You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用gdx-pay-android-googlebilling实现Libgdx安卓内购去广告?

完整实现Libgdx + Google Billing内购移除广告指南

我之前在Libgdx项目里折腾过Google Billing内购移除广告的功能,正好用的就是你提到的gdx-pay-android-googlebilling库,把完整的步骤拆解给你,一步步来就不会懵:

1. 先搞定依赖配置

首先得确保你的项目里引入了正确的依赖,在Android模块的build.gradle里添加:

dependencies {
    // 基础gdx-pay核心库,版本要和你项目的Libgdx版本一致
    implementation "com.badlogicgames.gdx:gdx-pay:$gdxVersion"
    // Google Billing的具体实现
    implementation "com.badlogicgames.gdx:gdx-pay-android-googlebilling:$gdxVersion"
    // 手动补充Google Billing客户端依赖(如果gdx-pay没自动关联的话)
    implementation "com.android.billingclient:billing:6.0.1" // 用最新稳定版就行
}

2. 配置AndroidManifest.xml

在Android模块的Manifest文件里添加内购必需的权限:

<!-- 内购核心权限 -->
<uses-permission android:name="com.android.vending.BILLING" />
<!-- 可选:用于查询已购商品的权限 -->
<uses-permission android:name="com.android.vending.CHECK_LICENSE" />

3. AndroidLauncher里的初始化(你提到的那行代码前后的操作)

首先,你的Game类需要先定义一个PurchaseManager成员变量,方便在AndroidLauncher里赋值:

public class MyGdxGame extends Game {
    public PurchaseManager purchaseManager;
    // 你的其他游戏成员变量...
}

然后在AndroidLauncher的onCreate方法里,除了实例化PurchaseManagerGoogleBilling,还要完成初始化配置,同时处理生命周期避免问题:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
    MyGdxGame game = new MyGdxGame();
    
    // 实例化Google Billing的PurchaseManager
    game.purchaseManager = new PurchaseManagerGoogleBilling(this);
    // 配置内购商品(替换成你在Google Play Console创建的移除广告SKU)
    PurchaseManagerConfig purchaseConfig = new PurchaseManagerConfig();
    purchaseConfig.addOffer(new Offer().setIdentifier("remove_ads_sku"));
    // 初始化PurchaseManager
    game.purchaseManager.initialize(purchaseConfig);
    
    initialize(game, config);
}

// 处理Activity生命周期,避免Billing连接泄漏
@Override
protected void onDestroy() {
    if (game.purchaseManager != null) {
        game.purchaseManager.dispose();
    }
    super.onDestroy();
}

@Override
protected void onPause() {
    if (game.purchaseManager != null) {
        game.purchaseManager.pause();
    }
    super.onPause();
}

@Override
protected void onResume() {
    super.onResume();
    if (game.purchaseManager != null) {
        game.purchaseManager.resume();
    }
}

4. 游戏核心逻辑里处理内购流程

接下来在你的游戏界面(比如MainScreen)里,需要设置监听器处理购买状态,同时实现购买触发、广告控制的逻辑:

public class MainScreen implements Screen, PurchaseObserver {
    private MyGdxGame game;
    private boolean adsRemoved = false;
    private Preferences prefs;

    public MainScreen(MyGdxGame game) {
        this.game = game;
        prefs = Gdx.app.getPreferences("MyGamePrefs");
        // 读取本地保存的购买状态,避免每次启动都查询
        adsRemoved = prefs.getBoolean("ads_removed", false);
        
        // 设置内购监听器
        game.purchaseManager.addPurchaseObserver(this);
        // 启动时查询已购商品,确保状态同步
        if (!adsRemoved) {
            game.purchaseManager.queryInventory();
        }
    }

    // 处理购买成功事件
    @Override
    public void handlePurchase(Purchase purchase) {
        if (purchase.getIdentifier().equals("remove_ads_sku")) {
            adsRemoved = true;
            // 保存购买状态到本地,重启APP也能记住
            prefs.putBoolean("ads_removed", true);
            prefs.flush();
            // 移除广告的逻辑:比如隐藏广告视图、停止广告加载
            hideAds();
        }
    }

    // 处理用户取消购买
    @Override
    public void handlePurchaseCanceled() {
        Gdx.app.log("内购", "用户取消了购买");
        // 可以给用户一个提示,比如Toast
        showToast("购买已取消");
    }

    // 处理购买错误
    @Override
    public void handlePurchaseError(Throwable error) {
        Gdx.app.log("内购错误", error.getMessage());
        showToast("购买失败:" + error.getMessage());
    }

    // 处理库存查询结果
    @Override
    public void handleInventoryQuery(Inventory inventory) {
        for (Purchase purchase : inventory.getPurchases()) {
            if (purchase.getIdentifier().equals("remove_ads_sku")) {
                adsRemoved = true;
                prefs.putBoolean("ads_removed", true);
                prefs.flush();
                hideAds();
                break;
            }
        }
    }

    // 触发购买的方法(比如用户点击"移除广告"按钮时调用)
    public void startRemoveAdsPurchase() {
        if (game.purchaseManager != null && game.purchaseManager.isInitialized()) {
            game.purchaseManager.purchase("remove_ads_sku");
        } else {
            showToast("内购服务未初始化");
        }
    }

    // 辅助方法:显示Toast(要切换到UI线程)
    private void showToast(String message) {
        Gdx.app.postRunnable(() -> {
            Toast.makeText(Gdx.app.getApplicationListener(), message, Toast.LENGTH_SHORT).show();
        });
    }

    // 辅助方法:移除广告
    private void hideAds() {
        // 这里写你隐藏广告的逻辑,比如隐藏AdView、停止广告请求等
    }

    // 在render里控制广告显示
    @Override
    public void render(float delta) {
        // 渲染游戏内容...
        if (!adsRemoved) {
            // 显示广告的逻辑
            showAds();
        }
    }

    // 其他Screen接口方法的实现(比如show、hide、dispose等)...
}

5. 关键踩坑提醒

  • 一定要在Google Play Console创建对应的非消耗型商品(因为移除广告是永久权益),SKU必须和代码里的完全一致。
  • 测试内购必须用内部测试账号,并且把APK/AAB上传到Google Play Console的内部测试频道,本地直接调试是无法触发真实内购的。
  • 购买状态一定要保存到本地(比如Preferences),否则用户重启APP后会重新显示广告。
  • 所有更新UI的操作(比如显示Toast、隐藏广告)必须用Gdx.app.postRunnable()切换到UI线程,否则会崩溃。

内容的提问来源于stack exchange,提问作者Nilesh Palshetkar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:28:08