我正在我的 Android 应用程序中实施 InApp 计费。一切正常,但是,我正在尝试将广播接收器与活动分离为清单。尤其是在 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.");
    }
}
}
我正在尝试在清单中添加一个接收器,但它给了我一个错误:
</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。提前谢谢你的帮助!