GVKun编程网logo

Android In-App Billing v3 不保存购买

1

本文将为您提供关于AndroidIn-AppBillingv3不保存购买的详细介绍,同时,我们还将为您提供关于会出问题吗?、ActionController::RoutingError没有路由与[GE

本文将为您提供关于Android In-App Billing v3 不保存购买的详细介绍,同时,我们还将为您提供关于 会出问题吗?、ActionController :: RoutingError没有路由与[GET]“ / vendor / assets / stylesheets / bootstrap.min.css”匹配 app / assets / stylesheets / application.css: app / assets / javascript / application.js: app / views / layout / application.html.erb: app / j、AIDL 到 Google Play Billing Library In App Purchase、Android Billing 4.0.0 - 无购买结果 querySkuDetailsAsync()的实用信息。

本文目录一览:

Android In-App Billing v3 不保存购买

Android In-App Billing v3 不保存购买

如何解决Android In-App Billing v3 不保存购买

我正在使用 anjlab 应用内计费库 (github link)。我的问题是,当用户购买产品时,它不会保存到 Google Play。它保存在本地,因为 bp.isPurchased("id") 返回 true。然而,bp.loadOwnedPurchasesFromGoogle() 是假的,所以如果我重新安装应用程序,bp.isPurchased("id") 将是假的。
我将此库与 "android.test.purchased" 测试 ProductId 一起使用,如果这与我的问题有任何关系,我不会。 这是我的代码:

  1. public class MainActivity extends AppCompatActivity implements BillingProcessor.IBillingHandler{
  2. Button mButton;
  3. BillingProcessor bp;
  4. @Override
  5. protected void onCreate(Bundle savedInstanceState) {
  6. super.onCreate(savedInstanceState);
  7. setContentView(R.layout.activity_main);
  8. mButton = findViewById(R.id.purchase_button);
  9. bp = new BillingProcessor(MainActivity.this,null,this);
  10. bp.initialize();
  11. mButton.setonClickListener(new View.OnClickListener() {
  12. @Override
  13. public void onClick(View view) {
  14. if (!bp.isPurchased("android.test.purchased"))
  15. bp.purchase(MainActivity.this,"android.test.purchased");
  16. }
  17. });
  18. }
  19. @Override
  20. public void onActivityResult(int requestCode,int resultCode,@Nullable Intent data) {
  21. if (!bp.handleActivityResult(requestCode,resultCode,data)) {
  22. super.onActivityResult(requestCode,data);
  23. }
  24. }
  25. @Override
  26. public void onProductPurchased(String productId,TransactionDetails details) {
  27. Toast.makeText(MainActivity.this,"purchased",Toast.LENGTH_SHORT).show();
  28. }
  29. @Override
  30. public void onPurchaseHistoryRestored() {
  31. }
  32. @Override
  33. public void onBillingError(int errorCode,Throwable error) {
  34. }
  35. @Override
  36. public void onBillingInitialized() {
  37. }
  38. @Override
  39. public void onDestroy() {
  40. if (bp != null) {
  41. bp.release();
  42. }
  43. super.onDestroy();
  44. }
  45. }

会出问题吗?" alt=" 会出问题吗?">

会出问题吗?"> 会出问题吗?

如何解决<uses-permission android:name="com.android.vending.BILLING" tools:node="remove"/> 会出问题吗?

当我从清单中删除 com.android.vending.BILLING 时,它在购买时显示此错误。

但是在调试模式下,它不显示。 只有在play商店apk里才能看到

SHOWING ERROR WHILE PURCHASING

ActionController :: RoutingError没有路由与[GET]“ / vendor / assets / stylesheets / bootstrap.min.css”匹配 app / assets / stylesheets / application.css: app / assets / javascript / application.js: app / views / layout / application.html.erb: app / j

ActionController :: RoutingError没有路由与[GET]“ / vendor / assets / stylesheets / bootstrap.min.css”匹配 app / assets / stylesheets / application.css: app / assets / javascript / application.js: app / views / layout / application.html.erb: app / j

如何解决ActionController :: RoutingError没有路由与[GET]“ / vendor / assets / stylesheets / bootstrap.min.css”匹配 app / assets / stylesheets / application.css: app / assets / javascript / application.js: app / views / layout / application.html.erb: app / j

我正在Rails上执行此应用程序,页面加载正常,但在控制台中显示:

Started GET "/vendor/assets/stylesheets/bootstrap.min.css" for ::1 at 2020-08-17 09:09:51 -0500

Started GET "/vendor/assets/javascripts/bootstrap.min.js" for ::1 at 2020-08-17 09:09:51 -0500
ActionController::RoutingError (No route matches [GET] 
"/vendor/assets/stylesheets/bootstrap.min.css"):
ActionController::RoutingError (No route matches [GET] 
"/vendor/assets/javascripts/bootstrap.min.js"):

在我的供应商文件夹中,我同时拥有文件夹,javascript和样式表,并分别位于各自的bootsrtrap.min中。 即使在application.html.erb中,我也有以下内容:

  <link href="vendor/assets/stylesheets/bootstrap.min.css" rel="stylesheet">
  <%= csrf_Meta_tags %>
  <%= stylesheet_link_tag    ''application'',media: ''all'',''data-turbolinks-track'': ''reload'' %>
  <%= javascript_include_tag ''application'',''data-turbolinks-track'': ''reload'' %>

</head>
<body>

  <!-- Navigation -->
  <nav>
    <div>
      <ahref="#">Instagram Clone</a>
      <buttontype="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
        <span></span>
      </button>
      <divid="navbarResponsive">
        <ul>
          <li>
            <ahref="#">Home
              <span>(current)</span>
            </a>
          </li>
          <li>
            <ahref="#">About</a>
          </li>
          <li>
            <ahref="#">Services</a>
          </li>
          <li>
            <ahref="#">Contact</a>
          </li>
        </ul>
      </div>
    </div>
  </nav>

  <!-- Page Content -->
  <div>
    <div>
      <div>
        <%= yield %>
      </div>
    </div>
  </div>

  <!-- Bootstrap core JavaScript -->
  <!--<script src="vendor/jquery/jquery.slim.min.js"></script>-->
  <script src="vendor/assets/javascripts/bootstrap.min.js"></script>
    
</body>
</html>

在js和CSS这两个应用程序文件中,我都放置了“ require bootsrtrap.min”,即使该错误仍然出现在控制台中。 会是什么?

解决方法

RoR不使用目录作为文件夹结构指示。因为有资产装载者。您应该将5s或更少的css导入application.css中,并将js导入application.js中。并使用自己的助手添加捆绑文件:

1。用纱安装靴子

yarn add bootstrap @popperjs/core jquery

npm i bootstrap @popperjs/core jquery

栏位不超过5

2。在Assets Pipeline中导入文件

app / assets / stylesheets / application.css:

//...
require bootstrap/dist/css/bootstrap.min
//...

但是,如果需要,我建议使用SCSS并仅导入所需的样式。

app / assets / javascript / application.js:

//...
//= require jquery
//= require @popperjs/core
//= require bootstrap/dist/js/bootstrap.min
//...

3。在布局中导入资产

app / views / layout / application.html.erb:

<head>
...
  <%= stylesheet_link_tag ''application'',media: ''all'' %>
</head>
<body>
...
  <%= javascript_include_tag ''application'' %>
</body>

使用webpack滚动6

2。在application.scss和application.js中导入Bootstrap

app / javascript / stylesheets / application.scss:

//...
import ''bootstrap''
//...

app / javascript / packs / application.js:

import ''jquery''
import ''popper.js''
import ''bootstrap''
import ''../stylesheets/application''

3。在布局中导入捆绑包

<head>
...
  <%= stylesheet_pack_tag ''application'',media: ''all'',''data-turbolinks-track'': ''reload'' %>
  <%= javascript_pack_tag ''application'',''data-turbolinks-track'': ''reload'' %>
</head>

之后,您应该可以在所有应用程序中使用引导程序!

,

[解决方案]因此,在我的HTML(application.html.erb)内部,我有两个对js和css文件的调用:

<script src="assets/javascripts/bootstrap.min.js"></script>
  <%= javascript_include_tag ''application'',''data-turbolinks-track'': ''reload'' %>       
<link href="assets/stylesheets/bootstrap.min.css" rel="stylesheet">
  <%= csrf_meta_tags %>
  <%= stylesheet_link_tag    ''application'',''data-turbolinks-track'': 
  ''reload'' %>

正如您在上面看到的那样,在使用javascript的情况下,我有一个使用脚本的调用,而另一个使用了的调用,两者都造成了问题,所以您只需要评论一个,我就对该脚本进行评论对于我的java文件和CSS文件,一个。 像这样:

  <!--<link href="assets/stylesheets/bootstrap.min.css" rel="stylesheet">-->
    <!--<script src="assets/javascripts/bootstrap.min.js"></script>-->

对我来说,解决了这个问题,我真的尝试了所有事情,这就是解决方案哈哈。

AIDL 到 Google Play Billing Library In App Purchase

AIDL 到 Google Play Billing Library In App Purchase

如何解决AIDL 到 Google Play Billing Library In App Purchase

我正在尝试将我在 AIDL 中的应用内购买迁移到新的结算库版本 3,以满足新的 Google 要求。

在 AIDL 中,有一个 base64EncodedPublicKey 用于识别我的应用。 Billing Library 版本中是否有等效版本?我正在创建一个测试类,通过单击按钮来启动支付流程,但下面的代码似乎不起作用。当我点击按钮时什么也没有发生。

 public class MainActivity extends AppCompatActivity implements PurchasesUpdatedListener {
private Button buyButton;
private BillingClient billingClient;

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

    buyButton = (Button) findViewById(R.id.buy);

    billingClient = BillingClient.newBuilder(this)
            .setListener(this)
            .enablePendingPurchases()
            .build();

    billingClient.startConnection(new BillingClientStateListener() {
        @Override
        public void onBillingSetupFinished(BillingResult billingResult) {
            if (billingResult.getResponseCode() ==  BillingClient.BillingResponseCode.OK) {
                // The BillingClient is ready. You can query purchases here.
                loadAllSKUs();
            }
        }
        @Override
        public void onBillingServicedisconnected() {
            // Try to restart the connection on the next request to
            // Google Play by calling the startConnection() method.
        }
    });

}

@Override
public void onPurchasesUpdated(BillingResult billingResult,List<Purchase> purchases) {
    if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK
            && purchases != null) {
        for (Purchase purchase : purchases) {
            handlePurchase(purchase);
        }
    } else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.USER_CANCELED) {
        // Handle an error caused by a user cancelling the purchase flow.
    } else {
        // Handle any other error codes.
    }
}

public void handlePurchase(Purchase purchase) {
    if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
        if(!purchase.isAckNowledged())
        {
            AckNowledgePurchaseParams ackNowledgePurchaseParams
                    = AckNowledgePurchaseParams.newBuilder()
                    .setPurchasetoken(purchase.getPurchasetoken())
                    .build();

            billingClient.ackNowledgePurchase(ackNowledgePurchaseParams,new AckNowledgePurchaseResponseListener() {
                @Override
                public void onAckNowledgePurchaseResponse(BillingResult billingResult) {
                    if(billingResult.getResponseCode()== BillingClient.BillingResponseCode.OK){
                    }
                }
            });
        }
    }
}


private void loadAllSKUs() {
    if (billingClient.isReady()) {
        List<String> skuList = new ArrayList<>();
        skuList.add("4");
        SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
        params.setSkusList(skuList).setType(BillingClient.SkuType.SUBS);
        billingClient.querySkuDetailsAsync(params.build(),new SkuDetailsResponseListener() {
                    @Override
                    public void onSkuDetailsResponse(BillingResult billingResult,List<SkuDetails> skuDetailsList) {
                        Log.d("Testing","testing2");
                        Log.d("Testing",String.valueOf(skuDetailsList.size()));
                        for (SkuDetails skuDetails : skuDetailsList) {
                            if (skuDetails.getSku() == "4")
                                //if (skuDetails.getSku() == "4")
                                buyButton.setonClickListener(new View.OnClickListener() {
                                    public void onClick(View v) {
                                        //DO SOMETHING! {RUN SOME FUNCTION ... DO CHECKS... ETC}
                                        BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
                                                .setSkuDetails(skuDetails)
                                                .build();
                                        int responseCode = billingClient.launchBillingFlow(MainActivity.this,billingFlowParams).getResponseCode();
                                    }
                                });
                        }
                    }
                });
    } else {
        Log.d("Testing","not ready");
    }
}
}

以下是xml文件

  <?xml version="1.0" encoding="utf-8"?>
 <androidx.constraintlayout.widget.ConstraintLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<Button
    android:id="@+id/buy"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Hello World!"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

 </androidx.constraintlayout.widget.ConstraintLayout>

Android Billing 4.0.0 - 无购买结果 querySkuDetailsAsync()

Android Billing 4.0.0 - 无购买结果 querySkuDetailsAsync()

如何解决Android Billing 4.0.0 - 无购买结果 querySkuDetailsAsync()?

我将 Android Studio 中的 Google Play Billing Library 从 3.0.3(运行良好)迁移到 4.0.0。 我检查了我的 Google Play Billing,一切似乎都正常,SKU 状态为 ACTIVE(没有危险信号)。 我已尽力遵循迁移说明@https://developer.android.com/google/play/billing/integrate#establish_a_connection_to_google_play

到目前为止,我只能确定与 Google Play Billing 的连接正常,也就是说,在 onBillingSetupFinished() 方法之后,BillingClient.BillingResponseCode.OK 响应良好,没有错误消息。

我的问题从调用 querySkuDetailsAsync() 开始:这里没有响应,甚至没有错误通知。谷歌网站非常强调这次通话,所以我觉得这就是乐趣的开始。

我已经提供了问题的示例代码。我已经使用了 Stack Overflow 的许多修复程序,但现在我真的被卡住了,真的需要它来工作。

我的问题代码如下:

''''''

/*
//Using the following library in build.graddle for app module
    dependencies {
        def billing_version = "4.0.0"
        implementation "com.android.billingclient:billing:$billing_version"
}

*/

StringBuilder builder4SKUInfo;
private void get_Subscribe2_Characters() {

    Subscribe2_Characters_Button.setonClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {

            //I Toggle Visibility of Views Here


            billingClient.startConnection(new BillingClientStateListener() {

                //Android Studio auto-prompts to generate onBillingSetupFinished & onBillingServicedisconnected

                @Override
                public void onBillingSetupFinished(@NonNull BillingResult billingResultC) {
                    if (billingResultC.getResponseCode() == BillingClient.BillingResponseCode.OK) {

                        //BillingResponseCode is OK here: Works Just Fine!
                        //The problem starts below


                        String skuToSell = "MySKU_Character_001"; //In my project,the SKU is cut-pasted from Google Play Console
                        List<String> skuList = new ArrayList<> ();
                        skuList.add(skuToSell);


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

                        billingClient.querySkuDetailsAsync(params.build(),new SkuDetailsResponseListener() {
                                    @Override
                                    public void onSkuDetailsResponse(@NonNull BillingResult billingResult,@NonNull List<SkuDetails> PurchaseDetailsList) {

                                        //nothing!  Not getting BillingResult
                                        //Problem seems to at this point

                                        if (PurchaseDetailsList.size() > 0) {

                                            //nothing!  Not getting size

                                            for (SkuDetails PurchaseSKU_Info : PurchaseDetailsList) {

                                                builder4SKUInfo = new StringBuilder(300);

                                                if (PurchaseSKU_Info.getSku().contains("MySKU_Character_001")) {


                                                    String getSKUInfo = (
                                                            "\nTitle [Query]: " + PurchaseSKU_Info.getTitle()
                                                                    + "\n\nDetails: " + PurchaseSKU_Info.getDescription()
                                                                    + "\n\nDuration: " + PurchaseSKU_Info.getSubscriptionPeriod()
                                                                    + "\n\nPrice" + PurchaseSKU_Info.getPrice()
                                                                    + "\n\nAvoid Problems:\nUpdated Subscription Settings on Google Play"
                                                                    + "\n\nIMPORTANT: NOT Transferable"
                                                                    + "\n\n      For this device only\n");
                                                    //+ "\nOther SKUs: " + SKU_Info.getSku()
                                                    //"001 = " + billingResultB.getResponseCode()
                                                    //+ "\nList Size: " + PurchaseDetailsList.size());

                                                    builder4SKUInfo.append(getSKUInfo); //The result I need to use elsewhere

                                                }
                                            }
                                        } else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED) {

                                            //No Google Play response for this

                                        } else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.ITEM_NOT_OWNED) {

                                            //No Google Play response for this


                                        }  else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.USER_CANCELED) {

                                            //Do something about cancels

                                        } else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.BILLING_UNAVAILABLE) {

                                            //No Google Play response for this

                                        } else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.SERVICE_disCONNECTED) {

                                            //No Google Play response for this

                                        } else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.SERVICE_TIMEOUT) {

                                            //No Google Play response for this

                                        } else {

                                            //Following Toast does not show

                                            String SomethingWrong = "Somethings is Wrong" +
                                                    "\nUpdate Your Google Play Billing Info" +
                                                    "\nCheck Internet Connection";

                                            Toast.makeText(KH.this,SomethingWrong,Toast.LENGTH_LONG).show();

                                        }
                                    }
                                });
                    }
                }


                @Override
                public void onBillingServicedisconnected() {

                    //Following Toast does not show

                    String BillingServicedisconnected = "Billing Service disconnected" +
                            "\nUpdate Your Google Play Billing Info" +
                            "\nCheck Internet Connection";

                    Toast.makeText(KH.this,BillingServicedisconnected,Toast.LENGTH_LONG).show();

                }
            });
        }
    });
}

''''''

解决方法

所以我勇敢地在问题跟踪页面上询问谷歌的人,他们适当而迅速地回答,“我们现在将结果发布到后台线程而不是 UIThread ......”

马上,我知道我的方法是错误的。如果结果被传递到后台线程,我不得不放弃 3.x 计费方法并从头开始。

我再次联系 Google 获取示例,他们向我发送了他们的 GitHub @ https://github.com/android/play-billing-samples/tree/main/TrivialDriveJava

该示例类似于“意图”,但具有比函数选择更多的代码声明:有几个类、方法和文件需要处理。因此,要修复 billing 4.x,最简单的方法是将示例翻录到我的应用程序中,减少错误,将我不需要的方法灰显,最后覆盖我的视图,重构类(再次修复错误)并创建新的用户工作流程。

,

按照@Maasaivatar 的回答,它在主线程上运行 SkuDetailsResponseListener 后工作:

billingClient.querySkuDetailsAsync(params.build(),(billingResult,list) -> 
    runOnUiThread(() -> {
            // same code as before
        }));

我们今天的关于Android In-App Billing v3 不保存购买的分享就到这里,谢谢您的阅读,如果想了解更多关于 会出问题吗?、ActionController :: RoutingError没有路由与[GET]“ / vendor / assets / stylesheets / bootstrap.min.css”匹配 app / assets / stylesheets / application.css: app / assets / javascript / application.js: app / views / layout / application.html.erb: app / j、AIDL 到 Google Play Billing Library In App Purchase、Android Billing 4.0.0 - 无购买结果 querySkuDetailsAsync()的相关信息,可以在本站进行搜索。

本文标签: