gpt4 book ai didi

android - InAppBilling 在 AndroidManifest 中注册 BroadcastReceiver

转载 作者:行者123 更新时间:2023-11-30 00:24:15 25 4
gpt4 key购买 nike

我正在我的 Android 应用中实现应用内结算。一切正常,但是,我正在尝试将广播接收器从 Activity 中解耦到 list 中。特别是在 Android 的 trivialdrive 示例中有这个建议:

// 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 的类:

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的类:

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.");
}
}
}

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

</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>

错误消息:.controller.Subscription 不可分配给“android.content.BroadcastReceiver”

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

最佳答案

controller.Subscription is not assignable to 'android.content.BroadcastReceiver'

这意味着 Subscription不是 BroadcastReceiver 的后代.您已注册Subscription显示为 receiver , 但实际上它不是 BroadcastReceiver 的子类.

Does my Subscription class have to extend IabBroadcastReceiver class and not be implementing IabBroadcastReceiver.IabBroadcastListener instead?

为了将一个类注册为 receiver在 list 中,它应该是 BroadcastReceiver 的后代(直接或间接) .因此,Subscription应该 extends BroadcastReceiverextends IabBroadcastReceiver .

I'll still like to extend AppCompactActivity.

你不能让一个类既是 Activity 又是接收者(Java 不支持多重继承)。

还可以注册IabBroadcastReceiver通过 list 显示为 <receiver> .但我想知道这背后的原因是什么?显然,当您的应用处于非 Activity 状态时,您永远不会收到任何广播,因为您应该在您的应用内启动购买流程,这就是为什么注册和注销 BroadcastReceiver 更有意义的原因。动态地。请注意,通过 list 注册接收器会让您收到来自其他应用程序的购买广播,您很可能对此不感兴趣。

参见 docs :

Don't register this broadcast receiver in the app manifest. Declaring the receiver in the manifest can cause the system to launch the app to handle the intent if the user makes a purchase while the app isn't running. This behavior is not necessary and may be annoying to the user. To find out about any purchases the user made while the app wasn't running, call getPurchases() when the user launches the app.

关于android - InAppBilling 在 AndroidManifest 中注册 BroadcastReceiver,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45686172/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com