Android - 片段中 BillingClient 的上下文

Android - Context for BillingClient inside Fragment

我有一个 activity 应用程序 (java),其中一个片段包含订阅按钮。我正在设置 Google Play Billing Library,但是当我设置以下内容时:

private BillingClient billingClient = BillingClient.newBuilder(getActivity())
        .setListener(purchasesUpdatedListener)
        .enablePendingPurchases()
        .build();

我收到这个错误:

java.lang.IllegalArgumentException: Please provide a valid Context.
at com.android.billingclient.api.BillingClient$Builder.build

我也试过了

getContext()

getActivity.getApplicationContext() 

但也没有用。 requireContext() 也没有。

如果我在片段中,我应该传递什么上下文?

更新:

订阅片段由 SignUpFragemnt 调用:

public class SignUpFragment extends Fragment {

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    View v = inflater.inflate(R.layout.fragment_sign_up, container, false);

    Button nextButton = v.findViewById(R.id.nextButton);
    nextButton.setOnClickListener(v1 -> {
        Navigation.findNavController(v1).navigate(R.id.subscriptionV3Fragment);
    });

    return v;
}
}

这是订阅片段:

public class SubscriptionV3Fragment extends Fragment implements View.OnClickListener {

    private static final String TAG = "SubscriptionV3Fragment";

    SkuDetails monthlyDetails;
    SkuDetails annualDetails;

    Context context = getActivity();

    private PurchasesUpdatedListener purchasesUpdatedListener = new PurchasesUpdatedListener() {
        @Override
        public void onPurchasesUpdated(@NonNull BillingResult billingResult, @Nullable List<Purchase> list) {

        }
    };

    private BillingClient billingClient = BillingClient.newBuilder(requireContext())
            .setListener(purchasesUpdatedListener)
            .enablePendingPurchases()
            .build();

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_subscription_v3, container, false);

        startConnection();

        Button monthlySubscribe = v.findViewById(R.id.monthlySubscribeBut);
        monthlySubscribe.setOnClickListener(this);

        return v;
    }


    private void startConnection() {
        billingClient.startConnection(new BillingClientStateListener() {
            @Override
            public void onBillingServiceDisconnected() {
                // PENDING
                // Try to restart the connection on the next request to
                // Google Play by calling the startConnection() method.
            }

            @Override
            public void onBillingSetupFinished(@NonNull BillingResult billingResult) {
                if (billingResult.getResponseCode() ==  BillingClient.BillingResponseCode.OK) {
                    querySubscriptionProducts();
                }
            }
        });
    }


    private void querySubscriptionProducts() {
        List<String> skuList = new ArrayList<>();
        skuList.add("sub_monthly");
        skuList.add("sub_annual");

        SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
        params.setSkusList(skuList).setType(BillingClient.SkuType.SUBS);

        billingClient.querySkuDetailsAsync(params.build(), new SkuDetailsResponseListener() {
            @Override
            public void onSkuDetailsResponse(@NonNull BillingResult billingResult, @Nullable List<SkuDetails> list) {
                Log.d(TAG, "onSkuDetailsResponse: " + list);
            }
        });
    }
}

将 getActivity() 更改为 getContext()

在这种情况下,问题不在于 context,问题在于访问它的位置。当你这部分代码被调用时,FragmentLifeCycle 的其他方法还在工作。

private BillingClient billingClient = BillingClient.newBuilder(requireContext())
        .setListener(purchasesUpdatedListener)
        .enablePendingPurchases()
        .build();

我建议您将它移到 OnCreateView() 之后的内部,甚至更好地移到 onViewCreated()

内部

只需将其分配到顶部

private BillingClient billingClient;

然后在里面 onViewCreated() 你可以这样做

billingClient = BillingClient.newBuilder(requireContext())
        .setListener(purchasesUpdatedListener)
        .enablePendingPurchases()
        .build();