Implementing In-app Billing(转)

原文链接:http://developer.android.com/guide/google/play/billing/billing_integrate.html


目录

 [隐藏

Implementing In-app Billing

In-app Billing on Google Play provides a straightforward, simple interface for sending in-app billing requests and managing in-app billing transactions using Google Play. This document helps you implement in-app billing by stepping through the primary implementation tasks, using the in-app billing sample application as an example.

在谷歌应用收费播放提供了一个简单的,简单的接口来发送请求应用收费和管理应用收费事务使用谷歌play。这个文档可以帮助你实现应用收费,通过加强通过初步实现任务,使用应用收费示例应用程序作为一个例子。


Before you implement in-app billing in your own application, be sure that you read Overview of In-app Billing and Security and Design. These documents provide background information that will make it easier for you to implement in-app billing.

在你实现应用收费在您自己的应用程序中,要确保你的阅读应用收费的概述以及安全设计。这些文档提供背景信息,将使您可以更轻松地实现应用收费。


To implement in-app billing in your application, you need to do the following:

1.Download the in-app billing sample application.

2.Add the IMarketBillingService.aidl file to your project.

3.Update your AndroidManifest.xml file.

4.Create a Service and bind it to the MarketBillingService so your application can send billing requests and receive billing responses from Google Play.

5.Create a BroadcastReceiver to handle broadcast intents from Google Play.

6.Create a security processing component to verify the integrity of the transaction messages that are sent by Google Play.

7.Modify your application code to support in-app billing.

Downloading the Sample Application

实现应用收费在您的应用程序,您需要做到以下几点:

1.下载示例应用程序的应用收费。

2.添加IMarketBillingService。aidl文件到您的项目。

3.更新你的AndroidManifest。xml文件。

4.创建一个服务并将它绑定到MarketBillingService所以应用程序可以发送请求和接收响应计费账单从谷歌玩。

5.创建一个BroadcastReceiver从谷歌处理广播意图玩。

6.创建一个安全处理组件来验证事务的完整性发送的消息由谷歌play。

7.修改应用程序代码来支持应用收费。

下载示例应用程序

Downloading the Sample Application

The in-app billing sample application shows you how to perform several tasks that are common to all in-app billing implementations, including:

应用收费的示例应用程序向你展示了如何完成几个任务,都很普遍应用收费的实现,包括:


  • Sending in-app billing requests to Google Play.
  • Handling synchronous responses from Google Play.
  • Handling broadcast intents (asynchronous responses) from Google Play.
  • Using in-app billing security mechanisms to verify the integrity of billing responses.
  • Creating a user interface that lets users select items for purchase.

The sample application includes an application file (Dungeons.java), the AIDL file for the MarketBillingService (IMarketBillingService.aidl), and several classes that demonstrate in-app billing messaging. It also includes a class that demonstrates basic security tasks, such as signature verification.

  • 发送请求到谷歌play。
  • 处理同步响应至google Play。
  • 处理广播意图(异步响应)从谷歌 play。
  • 使用安全机制应用收费来验证完整性计费的反应。
  • 创建一个用户界面,用户可以选择购买的物品。

样例应用程序包含一个应用程序文件(地牢java),MarketBillingService AIDL文件(IMarketBillingService.aidl),还有几类,演示应用收费的消息传递。它还包括了一个类,演示了基本的安全的任务,如签名验证。


Table 1 lists the source files that are included with the sample application.

表1列出了源文件中包含的示例应用程序。

Table 1. In-app billing sample application source files.

表1应用收费示例应用程序源文件。

File Description

IMarketBillingService.aidl

Android Interface Definition Library (AIDL) file that defines the IPC interface to Google Play's in-app billing service (MarketBillingService).

PurchaseDatabase.java

A local database for storing purchase information.

BillingReceiver.java

A BroadcastReceiver that receives asynchronous response messages (broadcast intents) from Google Play. Forwards all messages to the BillingService.

BillingService.java

A Service that sends messages to Google Play on behalf of the application by connecting (binding) to the MarketBillingService

ResponseHandler.java

A Handler that contains methods for updating the purchases database and the UI.

PurchaseObserver.java

An abstract class for observing changes related to purchases.

Security.java

Provides various security-related methods.

Consts.java

Defines various Google Play constants and sample application constants. All constants that are defined by Google Play must be defined the same way in your application

Base64.java and Base64DecoderException.java

Provides conversion services from binary to Base64 encoding. The Security class relies on these utility classes.

Dungeons.java

Sample application file that provides a UI for making purchases and displaying purchase history.



The in-app billing sample application is available as a downloadable component of the Android SDK. To download the sample application component, launch the Android SDK Manager and then select the Google Market Billing package component (see figure 1), and click Install Selected to begin the download.


Billing package.png

Figure 1. The Google Market Billing package contains the sample application and the AIDL file.

图1.谷歌的市场记帐包包含示例应用程序和AIDL文件。

When the download is complete, the Android SDK Manager saves the component into the following directory:

<sdk>/extras/google/market_billing/

If you want to see an end-to-end demonstration of in-app billing before you integrate in-app billing into your own application, you can build and run the sample application. Building and running the sample application involves three tasks:

  • Configuring and building the sample application.
  • Uploading the sample application to Google Play.
  • Setting up test accounts and running the sample application.

下载完成后,Android SDK经理节省组件到以下目录:

< sdk > /配件/谷歌/市场账单/

如果你想看到一个端到端应用收费的示范应用收费之前你整合到您自己的应用程序,您可以构建和运行示例应用程序。构建和运行示例应用程序涉及到三个任务:

  • 配置和构建这个示例应用程序。
  • 上传示例应用程序谷歌玩。
  • 设置测试帐户并运行样例应用程序。

Note: Building and running the sample application is necessary only if you want to see a demonstration of in-app billing. If you do not want to run the sample application, you can skip to the next section, Adding the AIDL file to your project.

注意:构建和运行示例应用程序是必须的,如果你想查看演示应用收费的。如果你不想运行样例应用程序,您可以跳过这一节,添加了AIDL文件到您的项目。

Configuring and building the sample application-配置和构建这个示例应用程序

Before you can run the sample application, you need to configure it and build it by doing the following:

在运行这个示例应用程序之前,您需要配置它,把它通过执行以下步骤:


1.Add your Google Play public key to the sample application code.

This enables the application to verify the signature of the transaction information that is returned from Google Play. To add your public key to the sample application code, do the following:

1.添加你的谷歌play公钥示例应用程序代码。

这使应用程序验证签名的事务信息返回的谷歌玩。添加您的公钥示例应用程序代码,做到以下几点:
1.Log in to your Google Play publisher account.
2.On the upper left part of the page, under your name, click Edit Profile.
3.On the Edit Profile page, scroll down to the Licensing & In-app Billing panel.
4.Copy your public key.
5.Open src/com/example/dungeons/Security.java in the editor of your choice.
You can find this file in the sample application's project folder.
6.Add your public key to the following line of code:
String base64EncodedPublicKey = "your public key here";
7.Save the file.
1.登录你的谷歌play发布者帐户。
2.左上角页面的一部分,在你的名字,点击编辑按钮。
3.在编辑页面,向下滚动到许可&应用收费面板。
4.复制你的公钥。
5.src / com/example/dungeons/security开放。java编辑器中的你的选择。
你可以找到这个文件在样例应用程序的项目文件夹。
6.添加您的公钥以下代码:
字符串base64EncodedPublicKey = "您的公钥这里”;
7.保存文件。

2.Change the package name of the sample application. The current package name is com.example.dungeons. Google Play does not let you upload applications with package names that contain com.example, so you must change the package name to something else.


2.改变包的名称的示例应用程序。

当前的包名是com例子地牢。谷歌play不让你上传应用程序和包名称中包含com。示例,因此您必须更改软件包名称到其他事情上。


3.Build the sample application in release mode and sign it. To learn how to build and sign applications, see Building and Running.

3.构建样例应用程序在发布模式下并签字。

学习如何构建和签署应用程序,请参阅构建和运行。

Uploading the sample application-上传示例应用程序

After you build a release version of the sample application and sign it, you need to upload it as a draft to the Google Play publisher site. You also need to create a product list for the in-app items that are available for purchase in the sample application. The following instructions show you how to do this.


1.Upload the release version of the sample application to Google Play.

Do not publish the sample application; leave it as an unpublished draft application. The sample application is for demonstration purposes only and should not be made publicly available on Google Play. To learn how to upload an application to Google Play, see Uploading applications.


在您构建一个发布版本的示例应用程序并签字,你需要上传它作为草案到谷歌玩出版商网站。您还需要创建一个产品列表的应用内购买物品,在样例应用程序。下面的说明显示你如何做到这一点。


2.Create a product list for the sample application.

The sample application lets you purchase two items: a two-handed sword (sword_001) and a potion (potion_001). We recommend that you set up your product list so that sword_001 has a purchase type of "Managed per user account" and potion_001 has a purchase type of "Unmanaged" so you can see how these two purchase types behave. To learn how to set up a product list, see Creating a Product List.


这个示例应用程序允许你购买的两个项目:一个双手剑(sword_001)和一种药剂(potion_001)。我们建议您设置您的产品列表,以便sword_001有购买类型的“有管理的每个用户账户”和potion_001有购买类型的“托管”,所以你可以看到这两个采购类型的行为。学习如何建立一个产品列表,请参阅创建一个产品列表.

Note: You must publish the items in your product list (sword_001 and potion_001) even though you are not publishing the sample application. Also, you must have a Google Wallet Merchant account to add items to the sample application's product list.

注意:你必须发布项目的产品列表(sword_001和potion_001)即使你不是出版样例应用程序。同时,你必须有一个谷歌钱包商人帐户将商品添加到样例应用程序的产品列表。

Running the sample application-运行样例应用程序

You cannot run the sample application in the emulator. You must install the sample application onto a device to run it. To run the sample application, do the following:

您不能运行模拟器中的样例应用程序。您必须安装示例应用程序到一个设备来运行它。要运行样例应用程序,请执行以下操作:

1.Make sure you have at least one test account registered under your Google Play publisher account. You cannot purchase items from yourself (Google Wallet prohibits this), so you need to create at least one test account that you can use to purchase items in the sample application. To learn how to set up a test account, see Setting up Test Accounts.

1.确保你有至少一个测试注册的账户在你的谷歌玩发布者帐户。你不能从自己购买一些物品(谷歌钱包禁止这个),所以您需要创建至少一个测试帐户,您可以使用它们来购买物品在样例应用程序。学习如何建立一个测试账号,请参阅设置测试账户。

2.Verify that your device is running a supported version of the Google Play application or the MyApps application. If your device is running Android 3.0, in-app billing requires version 5.0.12 (or higher) of the MyApps application. If your device is running any other version of Android, in-app billing requires version 2.3.4 (or higher) of the Google Play application. To learn how to check the version of the Google Play application, see Updating Google Play.


2.确认你的设备正在运行一个受支持的版本的谷歌应用程序或应用程序MyApps玩。如果你的设备运行的是Android 3.0,应用收费5.0.12需要版本(或更高)的MyApps应用程序。如果你的设备运行的任何其他版本的Android,应用收费需要版本2.3.4(或更高)的谷歌玩的应用程序。学习如何检查版本的谷歌玩应用程序,见更新谷歌玩。


3.Install the application onto your device. Even though you uploaded the application to Google Play, the application is not published, so you cannot download it from Google Play to a device. Instead, you must install the application onto your device. To learn how to install an application onto a device, see Running on a device.


3.将应用程序安装到您的设备。即使你上传应用程序以谷歌玩,应用程序就不会发布,所以你不能下载它从谷歌发挥一个设备。相反,您必须将应用程序安装到您的设备。学习如何安装一个应用程序到一个设备,请参阅在设备上运行。

4.Make one of your test accounts the primary account on your device.让你的一个测试帐户主账户在你的设备上

The primary account on your device must be one of the test accounts that you registered on the Google Play publisher site. If the primary account on your device is not a test account, you must do a factory reset of the device and then sign in with one of your test accounts. To perform a factory reset, do the following:

在你的设备的主要帐户必须是一个测试你的账户,注册在谷歌玩出版商网站。如果主账户在你的设备不是一个测试账号,你必须做一个工厂复位的设备,然后登录你的某个测试账户。执行一个工厂复位,做到以下几点:

1.Open Settings on your device.
2.Touch Privacy.
3.Touch Factory data reset.
4.Touch Reset phone.
5.After the phone resets, be sure to sign in with one of your test accounts during the device setup process.
1.打开设置你的设备上。
2.触摸隐私。
3.触摸工厂数据重置。
3.触摸复位的电话。
4.电话后重置,一定要签上名在与您的测试账户在设备安装过程。
5.运行应用程序并购买刀和药水。


5.Run the application and purchase the sword or the potion. When you use a test account to purchase items, the test account is billed through Google Wallet and your Google Wallet Merchant account receives a payout for the purchase. Therefore, you may want to refund purchases that are made with test accounts, otherwise the purchases will show up as actual payouts to your merchant account.

5.当您使用一个测试账号购买项目,测试帐户被谷歌钱包,你通过谷歌钱包商人帐户收到付款购买。因此,您可能想要退款采购与测试账户,否则购买将会显示为实际支付给你的商家帐户。

Note: Debug log messages are turned off by default in the sample application. You can turn them on by setting the variable DEBUG to true in the Consts.java file.注意:调试日志消息是默认关闭了在样本应用程序。你可以把它们在通过设置变量为true在Consts调试。java文件。

Adding the AIDL file to your project-添加了AIDL文件到您的项目

The sample application contains an Android Interface Definition Language (AIDL) file, which defines the interface to Google Play's in-app billing service (MarketBillingService). When you add this file to your project, the Android build environment creates an interface file (IMarketBillingService.java). You can then use this interface to make billing requests by invoking IPC method calls.

If you are using the ADT plug-in with Eclipse, you can just add this file to your /src directory. Eclipse will automatically generate the interface file when you build your project (which should happen immediately). If you are not using the ADT plug-in, you can put the AIDL file into your project and use the Ant tool to build your project so that the IMarketBillingService.java file gets generated.

To add the IMarketBillingService.aidl file to your project, do the following:

Create the following directory in your application's /src directory: com/android/vending/billing/

Copy the IMarketBillingService.aidl file into the sample/src/com/android/vending/billing/ directory. Build your application. You should now find a generated interface file named IMarketBillingService.java in the gen folder of your project.

Updating Your Application's Manifest样例应用程序包含了一个Android接口定义语言(AIDL)文件,它定义了接口来谷歌Play的应用收费服务(MarketBillingService)。当你添加这个文件到您的项目,Android构建环境创建一个接口文件(IMarketBillingService.java)。然后,您可以使用这个接口使计费请求通过调用IPC方法调用。


如果您正在使用Eclipse ADT插件,你可以添加这个文件到你的/ src目录。Eclipse将自动生成的接口文件当您构建您的项目(应该立即发生)。如果你没有使用ADT插件,你可以把AIDL文件到您的项目中,使用Ant工具来构建您的项目,以便IMarketBillingService。java文件中生成的。


添加IMarketBillingService。aidl文件到你的项目中,做到以下几点:


创建下列目录在您的应用程序/ src目录:

com/android/vending/billing/


IMarketBillingService复制。aidl文件到样本/ src / com/android/vending/billing/目录。

构建自己的应用程序。

你现在应该找一个生成的接口文件命名为IMarketBillingService。java在创文件夹的项目。


更新您的应用程序的清单


In-app billing relies on the Google Play application, which handles all communication between your application and the Google Play server. To use the Google Play application, your application must request the proper permission. You can do this by adding the com.android.vending.BILLING permission to your AndroidManifest.xml file. If your application does not declare the in-app billing permission, but attempts to send billing requests, Google Play will refuse the requests and respond with a RESULT_DEVELOPER_ERROR response code.

In addition to the billing permission, you need to declare the BroadcastReceiver that you will use to receive asynchronous response messages (broadcast intents) from Google Play, and you need to declare the Service that you will use to bind with the IMarketBillingService and send messages to Google Play. You must also declare intent filters for the BroadcastReceiver so that the Android system knows how to handle the broadcast intents that are sent from the Google Play application.

For example, here is how the in-app billing sample application declares the billing permission, the BroadcastReceiver, the Service, and the intent filters. In the sample application, BillingReceiver is the BroadcastReceiver that handles broadcast intents from the Google Play application and BillingService is the Service that sends requests to the Google Play application.

应用收费依赖于谷歌玩应用程序,该应用程序处理所有通信和谷歌之间扮演服务器。使用谷歌玩的应用程序,您的应用程序必须请求适当的许可。为此,您可以添加com android自动售货。允许你的AndroidManifest计费。xml文件。如果你的应用程序没有声明应用收费许可,但是试图发送帐单请求,谷歌玩会拒绝请求和响应,结果开发人员错误响应代码。


除了计费许可,您需要声明BroadcastReceiver,您将用于接收异步响应消息(广播意图)从谷歌玩耍,您需要声明服务,您将使用绑定与IMarketBillingService和发送信息到谷歌玩。你还必须声明意图过滤器BroadcastReceiver这样Android系统知道如何处理广播意图所发出的谷歌玩的应用程序。


例如,下面是示例应用程序如何应用收费的声明了计费许可,BroadcastReceiver,服务,和意图过滤器。在示例应用程序中,BillingReceiver是BroadcastReceiver处理从谷歌广播意图玩应用和BillingService是服务发送请求到谷歌玩的应用程序。

 
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.example.dungeons"
  android:versionCode="1"
  android:versionName="1.0">
 
  <uses-permission android:name="com.android.vending.BILLING" />
 
  <application android:icon="@drawable/icon" android:label="@string/app_name">
    <activity android:name=".Dungeons" android:label="@string/app_name">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>
 
    <service android:name="BillingService" />
 
    <receiver android:name="BillingReceiver">
      <intent-filter>
        <action android:name="com.android.vending.billing.IN_APP_NOTIFY" />
        <action android:name="com.android.vending.billing.RESPONSE_CODE" />
        <action android:name="com.android.vending.billing.PURCHASE_STATE_CHANGED" />
      </intent-filter>
    </receiver>
 
  </application>
</manifest>
 

Creating a Local Service


Your application must have a local Service to facilitate messaging between your application and Google Play. At a minimum, this service must do the following:

Bind to the MarketBillingService. Send billing requests (as IPC method calls) to the Google Play application. The five types of billing requests include: CHECK_BILLING_SUPPORTED requests REQUEST_PURCHASE requests GET_PURCHASE_INFORMATION requests CONFIRM_NOTIFICATIONS requests RESTORE_TRANSACTIONS requests Handle the synchronous response messages that are returned with each billing request. Binding to the MarketBillingServiceBinding to the MarketBillingService is relatively easy if you've already added the IMarketBillingService.aidl file to your project. The following code sample shows how to use the bindService() method to bind a service to the MarketBillingService. You could put this code in your service's onCreate() method.

创建一个本地服务


—————————————————————————————————————————————————————————————————

您的应用程序必须有一个本地服务来促进应用程序间的消息传递和谷歌玩。至少,这个服务必须做到以下几点:


MarketBillingService绑定。

发送帐单请求(如IPC方法调用)到谷歌玩的应用程序。这五个类型的计费请求包括:

检查账单支持请求

请求购买请求

获得购买信息请求

确认通知请求

恢复交易请求

处理同步响应消息返回与每个结算请求。

绑定到MarketBillingService

绑定到MarketBillingService是比较容易的,如果您已经添加了IMarketBillingService。aidl文件到您的项目。下面的代码示例显示了如何用bindService()方法来绑定一个服务MarketBillingService。你可以把这段代码在您的服务的onCreate()方法。

 
try {
  boolean bindResult = mContext.bindService(
    new Intent("com.android.vending.billing.MarketBillingService.BIND"), this,
    Context.BIND_AUTO_CREATE);
  if (bindResult) {
    Log.i(TAG, "Service bind successful.");
  } else {
    Log.e(TAG, "Could not bind to the MarketBillingService.");
  }
} catch (SecurityException e) {
  Log.e(TAG, "Security exception: " + e);
}
 
 
/**
  * The Android system calls this when we are connected to the MarketBillingService.
  */
  public void onServiceConnected(ComponentName name, IBinder service) {
    Log.i(TAG, "MarketBillingService connected.");
    mService = IMarketBillingService.Stub.asInterface(service);
  }
 

You can now use the mService reference to invoke the sendBillingRequest() method.

For a complete implementation of a service that binds to the MarketBillingService, see the BillingService class in the sample application.

Sending billing requests to the MarketBillingServiceNow that your Service has a reference to the IMarketBillingService interface, you can use that reference to send billing requests (via IPC method calls) to the MarketBillingService. The MarketBillingService IPC interface exposes a single public method (sendBillingRequest()), which takes a single Bundle parameter. The Bundle that you deliver with this method specifies the type of request you want to perform, using various key-value pairs. For instance, one key indicates the type of request you are making, another indicates the item being purchased, and another identifies your application. The sendBillingRequest() method immediately returns a Bundle containing an initial response code. However, this is not the complete purchase response; the complete response is delivered with an asynchronous broadcast intent. For more information about the various Bundle keys that are supported by the MarketBillingService, see In-app Billing Service Interface.

You can use the sendBillingRequest() method to send five types of billing requests. The five request types are specified using the BILLING_REQUEST Bundle key. This Bundle key can have the following five values:

CHECK_BILLING_SUPPORTED—verifies that the Google Play application supports in-app billing and the version of the In-app Billing API available. REQUEST_PURCHASE—sends a purchase request for an in-app item. GET_PURCHASE_INFORMATION—retrieves transaction information for a purchase or refund. CONFIRM_NOTIFICATIONS—acknowledges that you received the transaction information for a purchase or refund. RESTORE_TRANSACTIONS—retrieves a user's transaction history for managed purchases. To make any of these billing requests, you first need to build an initial Bundle that contains the three keys that are required for all requests: BILLING_REQUEST, API_VERSION, and PACKAGE_NAME. The following code sample shows you how to create a helper method named makeRequestBundle() that does this.

您现在可以使用mService引用来调用sendBillingRequest()方法。


对于一个完整的实现一个服务,绑定的MarketBillingService,看到BillingService类的示例应用程序。


发送请求到MarketBillingService计费

现在,你的服务有一个IMarketBillingService接口的引用,您可以使用这个引用发送帐单请求(通过IPC方法调用)到MarketBillingService。MarketBillingService IPC接口公开的一个公共方法(sendBillingRequest()),它接受一个Bundle参数。这个包交付使用此方法指定类型的请求,您希望执行,使用不同的键值对。例如,一个关键的指示请求类型的你正在制作,另一个显示项目被收购,和另一个标识您的应用程序。立即的sendBillingRequest()方法返回一个包包含一个初始响应代码。然而,这并不是完整的购买响应;完整的反应是交付与异步广播的意图。了解更多关于美国各种包键所支持MarketBillingService,看到应用收费服务接口。


您可以使用sendBillingRequest()方法发送请求的五种类型的账单。五个请求类型指定为使用计费请求绑定包的关键。这束键可以有以下5个值:


检查账单支持验证的应用程序支持谷歌玩应用收费和版本的应用收费API可用。

委托收购发送一个购买请求的应用程序项目。

获得购买信息检索事务信息一个购买或退款。

确认通知承认您收到的事务信息一个购买或退款。

恢复交易检索用户的事务历史购买管理。

要做出任一这些账单请求,您首先需要构建初始的包,包含了三个键所需要的所有请求:账单请求,api版本,和PACKAGE_NAME。下面的代码示例显示了如何创建一个辅助方法命名makeRequestBundle(),这是否。

 
protected Bundle makeRequestBundle(String method) {
  Bundle request = new Bundle();
  request.putString(BILLING_REQUEST, method);
  request.putInt(API_VERSION, 1);
  request.putString(PACKAGE_NAME, getPackageName());
  return request;
 

To use this helper method, you pass in a String that corresponds to one of the five types of billing requests. The method returns a Bundle that has the three required keys defined. The following sections show you how to use this helper method when you send a billing request.

Important: You must make all in-app billing requests from your application's main thread.

Verifying that in-app billing is supported (CHECK_BILLING_SUPPPORTED)The following code sample shows how to verify whether the Google Play application supports in-app billing and confirm what version of the API it supports. In the sample, mService is an instance of the MarketBillingService interface.使用这个helper方法,您传递一个字符串相对应的五种计费请求。该方法返回一个Bundle,有三个定义所需的密钥。下面几节将向您展示如何使用这个helper方法当您发送一个账单请求。


重要:您必须使所有应用收费请求从应用程序的主线程。


验证应用收费是支持(CHECK_BILLING_SUPPPORTED)

以下代码示例展示了如何验证应用程序支持谷歌是否发挥应用收费和确认什么版本的API,它支持。在此示例中,mService是MarketBillingService接口的一个实例。

 
/**
* Request type is CHECK_BILLING_SUPPORTED
*/
  Bundle request = makeRequestBundle("CHECK_BILLING_SUPPORTED");
  Bundle response = mService.sendBillingRequest(request);
  // Do something with this response.
}
 

The makeRequestBundle() method constructs an initial Bundle, which contains the three keys that are required for all requests: BILLING_REQUEST, API_VERSION, and PACKAGE_NAME. If you are offering subscriptions in your app, set the API_VERSION key to a value of "2", to confirm that In-app Billing v2 is available. For an examnple, see Subscriptions.

The CHECK_BILLING_SUPPORTED request returns a synchronous Bundle response, which contains only a single key: RESPONSE_CODE. The RESPONSE_CODE key can have the following values:

RESULT_OK—the spedified version of in-app billing is supported. RESULT_BILLING_UNAVAILABLE—in-app billing is not available because the API version you specified is not recognized or the user is not eligible to make in-app purchases (for example, the user resides in a country that prohibits in-app purchases). RESULT_ERROR—there was an error connecting with the Google Play application. RESULT_DEVELOPER_ERROR—the application is trying to make an in-app billing request but the application has not declared the com.android.vending.BILLING permission in its manifest. Can also indicate that an application is not properly signed, or that you sent a malformed request. The CHECK_BILLING_SUPPORTED request does not trigger any asynchronous responses (broadcast intents).

We recommend that you invoke the CHECK_BILLING_SUPPORTED request within a RemoteException block. When your code throws a RemoteException it indicates that the remote method call failed, which means that the Google Play application is out of date and needs to be updated. In this case, you can provide users with an error message that contains a link to the Updating Google Play Help topic.

The sample application demonstrates how you can handle this error condition (see DIALOG_CANNOT_CONNECT_ID in Dungeons.java).

Making a purchase request (REQUEST_PURCHASE)To make a purchase request you must do the following:

Send the REQUEST_PURCHASE request. Launch the PendingIntent that is returned from the Google Play application. Handle the broadcast intents that are sent by the Google Play application. Making the requestYou must specify four keys in the request Bundle. The following code sample shows how to set these keys and make a purchase request for a single in-app item. In the sample, mProductId is the Google Play product ID of an in-app item (which is listed in the application's product list), and mService is an instance of the MarketBillingService interface.

这个makeRequestBundle()方法构造一个初始包,其中包含了三个键所需要的所有请求:账单请求,api版本,和PACKAGE_NAME。如果你在自己的应用程序提供订阅,设置api版本的关键,值为“2”,证实应用收费v2是可用的。对于一个examnple,看到订阅。


检查账单支持请求返回一个同步包响应,其中只包含一个键:响应代码。响应码键可以有以下值:


结果可以spedified版本的应用收费是支持的。

结果计费不可用,在app账单不使用,因为您指定API版本并不承认或用户没有资格使应用内购买(例如,用户驻留在一个国家禁止应用内购买)。

结果误差有一个错误,结合谷歌玩的应用程序。

结果开发人员错误应用程序试图使一个应用收费应用程序请求,但尚未宣布com android自动售货。在manifest权限计费。也可以显示一个应用程序签署的是不恰当的,或者你送来了一个畸形的请求。

检查账单支持请求不会触发任何异步响应(广播意图)。


我们建议您调用检查账单支持要求在一个RemoteException块。当你的代码抛出RemoteException它表明远程方法调用失败,这意味着谷歌玩应用程序已经过时,需要更新。在这种情况下,您可以为用户提供一个错误消息,包含一个链接到更新谷歌play帮助主题。


示例应用程序演示了如何处理这个错误条件(看到对话框不能连接id在地牢java)。


购物的请求(请求购买)

购买请求你必须做到以下几点:


购买请求发送请求。

启动PendingIntent返回谷歌玩的应用程序。

处理广播意图所发送的谷歌玩的应用程序。

发出请求

您必须指定4个键在请求包。下面的代码示例显示了如何设置这些键,使购买请求为单一应用程序项目。在此示例中,mProductId是谷歌的一个应用内玩产品ID的项目(这是列在应用程序的产品列表),mService是MarketBillingService接口的一个实例。

 
/**
* Request type is REQUEST_PURCHASE
*/
  Bundle request = makeRequestBundle("REQUEST_PURCHASE");
  request.putString(ITEM_ID, mProductId);
  // Request is for a standard in-app product
  request.putString(ITEM_TYPE, "inapp");
  // Note that the developer payload is optional.
  if (mDeveloperPayload != null) {
    request.putString(DEVELOPER_PAYLOAD, mDeveloperPayload);
  }
  Bundle response = mService.sendBillingRequest(request);
  // Do something with this response.
 

The makeRequestBundle() method constructs an initial Bundle, which contains the three keys that are required for all requests: BILLING_REQUEST, API_VERSION, and PACKAGE_NAME. The ITEM_ID key is then added to the Bundle prior to invoking the sendBillingRequest() method.

The request returns a synchronous Bundle response, which contains three keys: RESPONSE_CODE, PURCHASE_INTENT, and REQUEST_ID. The RESPONSE_CODE key provides you with the status of the request and the REQUEST_ID key provides you with a unique request identifier for the request. The PURCHASE_INTENT key provides you with a PendingIntent, which you can use to launch the checkout UI.

Using the pending intentHow you use the pending intent depends on which version of Android a device is running. On Android 1.6, you must use the pending intent to launch the checkout UI in its own separate task instead of your application's activity stack. On Android 2.0 and higher, you can use the pending intent to launch the checkout UI on your application's activity stack. The following code shows you how to do this. You can find this code in the PurchaseObserver.java file in the sample application.这个makeRequestBundle()方法构造一个初始包,其中包含了三个键所需要的所有请求:账单请求,api版本,和PACKAGE_NAME。然后,添加的ITEM_ID关键Bundle的调用sendBillingRequest之前()方法。


请求返回一个同步包响应,其中包含三个键:响应代码,购买意向,并请求id。响应码键为您提供请求状态和请求id为你提供了一个独特的请求标识符的请求。购买意图关键为你提供了一个PendingIntent,你可以用它启动checkout UI。


使用悬而未决的意图

你如何使用这个悬而未决的意图取决于哪个版本的Android设备的运行。Android 1.6系统,您必须使用悬而未决的意图推出checkout UI在其自己的单独的任务而不是应用程序的活动堆栈。在Android 2.0和更高版本,您可以使用悬而未决的意图推出checkout UI应用程序的活动堆栈。下面的代码显示了你如何做到这一点。你可以找到这段代码在PurchaseObserver。在示例应用程序的java文件。

 
void startBuyPageActivity(PendingIntent pendingIntent, Intent intent) {
  if (mStartIntentSender != null) {
    // This is on Android 2.0 and beyond.  The in-app checkout page activity
    // will be on the activity stack of the application.
    try {
      // This implements the method call:
      // mActivity.startIntentSender(pendingIntent.getIntentSender(),
      //     intent, 0, 0, 0);
      mStartIntentSenderArgs[0] = pendingIntent.getIntentSender();
      mStartIntentSenderArgs[1] = intent;
      mStartIntentSenderArgs[2] = Integer.valueOf(0);
      mStartIntentSenderArgs[3] = Integer.valueOf(0);
      mStartIntentSenderArgs[4] = Integer.valueOf(0);
      mStartIntentSender.invoke(mActivity, mStartIntentSenderArgs);
    } catch (Exception e) {
      Log.e(TAG, "error starting activity", e);
      }
  } else {
    // This is on Android 1.6. The in-app checkout page activity will be on its
    // own separate activity stack instead of on the activity stack of
    // the application.
    try {
      pendingIntent.send(mActivity, 0 /* code */, intent);
    } catch (CanceledException e) {
      Log.e(TAG, "error starting activity", e);
      }
  }
}
 

Important: You must launch the pending intent from an activity context and not an application context. Also, you cannot use the singleTop launch mode to launch the pending intent. If you do either of these, the Android system will not attach the pending intent to your application process. Instead, it will bring Google Play to the foreground, disrupting your application.

Handling broadcast intentsA REQUEST_PURCHASE request also triggers two asynchronous responses (broadcast intents). First, the Google Play application sends a RESPONSE_CODE broadcast intent, which provides error information about the request. If the request does not generate an error, the RESPONSE_CODE broadcast intent returns RESULT_OK, which indicates that the request was successfully sent. (To be clear, a RESULT_OK response does not indicate that the requested purchase was successful; it indicates that the request was sent successfully to Google Play.)

Next, when the requested transaction changes state (for example, the purchase is successfully charged to a credit card or the user cancels the purchase), the Google Play application sends an IN_APP_NOTIFY broadcast intent. This message contains a notification ID, which you can use to retrieve the transaction details for the REQUEST_PURCHASE request.

Note: The Google Play application also sends an IN_APP_NOTIFY for refunds. For more information, see Handling IN_APP_NOTIFY messages.

Because the purchase process is not instantaneous and can take several seconds (or more), you must assume that a purchase request is pending from the time you receive a RESULT_OK message until you receive an IN_APP_NOTIFY message for the transaction. While the transaction is pending, the Google Play checkout UI displays an "Authorizing purchase..." notification; however, this notification is dismissed after 60 seconds and you should not rely on this notification as your primary means of conveying transaction status to users. Instead, we recommend that you do the following:

Add an Activity to your application that shows users the status of pending and completed in-app purchases. Use a status bar notification to keep users informed about the progress of a purchase. To use these two UI elements, you could invoke a status bar notification with a ticker-text message that says "Purchase pending" when your application receives a RESULT_OK message. Then, when your application receives an IN_APP_NOTIFY message, you could update the notification with a new message that says "Purchase succeeded" or "Purchase failed." When a user touches the expanded status bar notification, you could launch the activity that shows the status of pending and completed in-app purchases.

If you use some other UI technique to inform users about the state of a pending transaction, be sure that your pending status UI does not block your application. For example, you should avoid using a hovering progress wheel to convey the status of a pending transaction because a pending transaction could last a long time, particularly if a device loses network connectivity and cannot receive transaction updates from Google Play.

Important: If a user purchases a managed item, you must prevent the user from purchasing the item again while the original transaction is pending. If a user attempts to purchase a managed item twice, and the first transaction is still pending, Google Play will display an error to the user; however, Google Play will not send an error to your application notifying you that the second purchase request was canceled. This might cause your application to get stuck in a pending state while it waits for an IN_APP_NOTIFY message for the second purchase request.

Retrieving transaction information for a purchase or refund (GET_PURCHASE_INFORMATION)You retrieve transaction information in response to an IN_APP_NOTIFY broadcast intent. The IN_APP_NOTIFY message contains a notification ID, which you can use to retrieve transaction information.

To retrieve transaction information for a purchase or refund you must specify five keys in the request Bundle. The following code sample shows how to set these keys and make the request. In the sample, mService is an instance of the MarketBillingService interface.

重要:您必须启动悬而未决的意图与一个活动上下文,而不是一个应用程序上下文。同样,你不能使用singleTop启动模式启动悬而未决的意图。如果你做的不是这些,Android系统将不把你的申请程序未决的意图。相反,它将使谷歌玩到前台,扰乱了你的应用程序。


处理广播意图

购买请求的请求也触发了两个异步响应(广播意图)。首先,谷歌玩应用程序发送一个响应代码广播的意图,它提供了错误信息的请求。如果请求并不会生成一个错误,响应代码返回的结果可以播放的意图,这表明,他的请求被成功发送。(需要明确的是,一个ok响应结果并不表明请求的收购是成功的,它表明请求发送成功,谷歌play。)


接下来,当请求的事务状态更改(例如,购买被成功地用于信用卡或用户取消购买),谷歌应用程序发送一个玩在应用程序通知广播的意图。此消息包含一个通知ID,您可以使用它来检索事务细节为请求购买请求。


注意:谷歌玩应用程序还在应用程序发送一个通知的退款。有关更多信息,请参见notify消息处理程序。


由于收购过程不是瞬时和花几秒(或更多),你必须假定一个购买请求等待时间从你获得结果好的消息,直到你收到一个通知消息在应用程序的事务。尽管交易正在等待,谷歌玩checkout UI显示一个“授权购买……“通知;然而,这种通知是驳回了60秒后,你不应该依赖于这种通知作为你主要的交易状态的方法向用户传达。相反,我们建议您做到以下几点:


对您的应用程序添加一项活动,显示了用户等待完成的状态和应用内购买。

使用一个状态栏通知来让用户了解进程的购买。

使用这两个UI元素,您可以调用一个状态栏通知与一个醒目的短信,说“购买等待”当你的应用程序接收结果好信息。然后,当应用程序收到一个通知消息的应用程序,您可以更新通知的新消息,说“购买成功”或者“购买失败了。“当用户触摸扩展状态栏通知,您可以启动活动显示状态的未决,完成了应用内购买。


如果你使用一些其他的UI技术来通知用户等待事务的状态,确保你的暂挂状态UI不会阻塞你的应用程序。例如,您应该避免使用一个盘旋的进步车轮来传达一个悬而未决的事务的状态,因为一个悬而未决的事务可能会持续一段时间,特别是如果一个设备丧失网络连通性和不能接收事务更新从谷歌玩。


重要:如果一个用户购买一个托管的项,您必须防止用户购买物品时又原有的交易正在等待。如果用户试图购买一个托管项目两次,第一次交易仍悬而未决,谷歌玩将显示一条错误用户;然而,谷歌游戏都不会对您的应用程序发送一个错误通知你第二次购买请求已被取消。这可能导致应用程序会被困在一个未决状态,它会等待一个在应用程序通知消息的第二次购买请求。


检索事务信息一个购买或退款(获得购买信息)

您检索事务信息以响应一个在应用程序通知广播的意图。在应用程序的通知消息包含一个通知ID,您可以使用它来检索事务信息。


检索事务信息一个购买或退款,你必须在请求中指定的5个关键Bundle。下面的代码示例显示了如何设置这些键和请求。在此示例中,mService是MarketBillingService接口的一个实例。

 
/**
* Request type is GET_PURCHASE_INFORMATION
*/
  Bundle request = makeRequestBundle("GET_PURCHASE_INFORMATION");
  request.putLong(REQUEST_NONCE, mNonce);
  request.putStringArray(NOTIFY_IDS, mNotifyIds);
  Bundle response = mService.sendBillingRequest(request);
  // Do something with this response.
}
 

The makeRequestBundle() method constructs an initial Bundle, which contains the three keys that are required for all requests: BILLING_REQUEST, API_VERSION, and PACKAGE_NAME. The additional keys are then added to the bundle prior to invoking the sendBillingRequest() method. The REQUEST_NONCE key contains a cryptographically secure nonce (number used once) that you must generate. The Google Play application returns this nonce with the PURCHASE_STATE_CHANGED broadcast intent so you can verify the integrity of the transaction information. The NOTIFY_IDS key contains an array of notification IDs, which you received in the IN_APP_NOTIFY broadcast intent.

The request returns a synchronous Bundle response, which contains two keys: RESPONSE_CODE and REQUEST_ID. The RESPONSE_CODE key provides you with the status of the request and the REQUEST_ID key provides you with a unique request identifier for the request.

A GET_PURCHASE_INFORMATION request also triggers two asynchronous responses (broadcast intents). First, the Google Play application sends a RESPONSE_CODE broadcast intent, which provides status and error information about the request. Next, if the request was successful, the Google Play application sends a PURCHASE_STATE_CHANGED broadcast intent. This message contains detailed transaction information. The transaction information is contained in a signed JSON string (unencrypted). The message includes the signature so you can verify the integrity of the signed string.

Acknowledging transaction information (CONFIRM_NOTIFICATIONS)To acknowledge that you received transaction information you send a CONFIRM_NOTIFICATIONS request. You must specify four keys in the request Bundle. The following code sample shows how to set these keys and make the request. In the sample, mService is an instance of the MarketBillingService interface.这个makeRequestBundle()方法构造一个初始包,其中包含了三个键所需要的所有请求:账单请求,api版本,和PACKAGE_NAME。额外的键然后添加到包调用sendBillingRequest之前()方法。请求nonce键包含密码安全nonce(号码使用一次),您必须生成。谷歌的玩的应用程序返回这个nonce与采购状态改变了广播的意图,这样你就可以验证事务信息的完整性。此通知IDs键包含一组通知IDs,你收到了在应用程序通知广播的意图。


请求返回一个同步包响应,其中包含两个键:响应代码和请求id。响应码键为您提供请求状态和请求id为你提供了一个独特的请求标识符的请求。


一个get请求购买信息也触发了两个异步响应(广播意图)。首先,谷歌玩应用程序发送一个响应代码广播的意图,它提供了状态和错误信息的请求。接下来,如果请求是成功的,谷歌玩应用程序发送一个购买状态改变了广播的意图。这个信息包含详细的事务信息。事务信息包含在一个签署了JSON字符串(加密)。消息包含签名,这样你就可以验证完整性的签名字符串。


承认事务信息(确认通知)

承认你收到事务信息您发送一个确认通知请求。您必须指定4个键在请求包。下面的代码示例显示了如何设置这些键和请求。在此示例中,mService是MarketBillingService接口的一个实例。

 
/**
* Request type is CONFIRM_NOTIFICATIONS
*/
  Bundle request = makeRequestBundle("CONFIRM_NOTIFICATIONS");
  request.putStringArray(NOTIFY_IDS, mNotifyIds);
  Bundle response = mService.sendBillingRequest(request);
  // Do something with this response.
}
 

The makeRequestBundle() method constructs an initial Bundle, which contains the three keys that are required for all requests: BILLING_REQUEST, API_VERSION, and PACKAGE_NAME. The additional NOTIFY_IDS key is then added to the bundle prior to invoking the sendBillingRequest() method. The NOTIFY_IDS key contains an array of notification IDs, which you received in an IN_APP_NOTIFY broadcast intent and also used in a GET_PURCHASE_INFORMATION request.

The request returns a synchronous Bundle response, which contains two keys: RESPONSE_CODE and REQUEST_ID. The RESPONSE_CODE key provides you with the status of the request and the REQUEST_ID key provides you with a unique request identifier for the request.

A CONFIRM_NOTIFICATIONS request triggers a single asynchronous response—a RESPONSE_CODE broadcast intent. This broadcast intent provides status and error information about the request.

You must send a confirmation when you receive transaction information from Google Play. If you don't send a confirmation message, Google Play will continue sending IN_APP_NOTIFY messages for the transactions you have not confirmed. Also, your application must be able to handle IN_APP_NOTIFY messages that contain multiple orders.

In addition, as a best practice, you should not send a CONFIRM_NOTIFICATIONS request for a purchased item until you have delivered the item to the user. This way, if your application crashes or something else prevents your application from delivering the product, your application will still receive an IN_APP_NOTIFY broadcast intent from Google Play indicating that you need to deliver the product.

Restoring transaction information (RESTORE_TRANSACTIONS)To restore a user's transaction information, you send a RESTORE_TRANSACTIONS request. You must specify four keys in the request Bundle. The following code sample shows how to set these keys and make the request. In the sample, mService is an instance of the MarketBillingService interface.

这个makeRequestBundle()方法构造一个初始包,其中包含了三个键所需要的所有请求:账单请求,api版本,和PACKAGE_NAME。额外的通知ids键然后添加到包调用sendBillingRequest之前()方法。此通知IDs键包含一组通知IDs中接收到一个在应用程序通知广播的意图,也可用于一个get请求购买信息。


请求返回一个同步包响应,其中包含两个键:响应代码和请求id。响应码键为您提供请求状态和请求id为你提供了一个独特的请求标识符的请求。


确认通知请求触发一个异步响应的响应代码广播的意图。这个广播意图提供了状态和错误信息的请求。


你必须发送一条确认当你接收事务信息从谷歌玩。如果你不发送一条确认消息,谷歌比赛将继续进行,在app发送通知消息的事务你还没有证实。同样,您的应用程序必须能够处理notify消息在应用程序包含多个命令。


此外,作为一个最佳实践,您不应该发送一个确认通知要求购买的商品,直到你们救项目给用户。这样,如果你的应用程序崩溃或者别的什么东西阻止你的应用程序交付产品,您的应用程序仍然可以接收到一个在应用程序通知广播意图与谷歌play表明你需要交付产品。


恢复交易信息(恢复事务)

恢复一个用户的事务的信息,您发送一个恢复交易请求。您必须指定4个键在请求包。下面的代码示例显示了如何设置这些键和请求。在此示例中,mService是MarketBillingService接口的一个实例。

 
/**
* Request type is RESTORE_TRANSACTIONS
*/
  Bundle request = makeRequestBundle("RESTORE_TRANSACTIONS");
  request.putLong(REQUEST_NONCE, mNonce);
  Bundle response = mService.sendBillingRequest(request);
  // Do something with this response.
}
 

The makeRequestBundle() method constructs an initial Bundle, which contains the three keys that are required for all requests: BILLING_REQUEST, API_VERSION, and PACKAGE_NAME. The additional REQUEST_NONCE key is then added to the bundle prior to invoking the sendBillingRequest() method. The REQUEST_NONCE key contains a cryptographically secure nonce (number used once) that you must generate. The Google Play application returns this nonce with the transactions information contained in the PURCHASE_STATE_CHANGED broadcast intent so you can verify the integrity of the transaction information.

The request returns a synchronous Bundle response, which contains two keys: RESPONSE_CODE and REQUEST_ID. The RESPONSE_CODE key provides you with the status of the request and the REQUEST_ID key provides you with a unique request identifier for the request.

A RESTORE_TRANSACTIONS request also triggers two asynchronous responses (broadcast intents). First, the Google Play application sends a RESPONSE_CODE broadcast intent, which provides status and error information about the request. Next, if the request was successful, the Google Play application sends a PURCHASE_STATE_CHANGED broadcast intent. This message contains the detailed transaction information. The transaction information is contained in a signed JSON string (unencrypted). The message includes the signature so you can verify the integrity of the signed string.

Note: You should use the RESTORE_TRANSACTIONS request type only when your application is installed for the first time on a device or when your application has been removed from a device and reinstalled.

Other service tasksYou may also want your Service to receive intent messages from your BroadcastReceiver. You can use these intent messages to convey the information that was sent asynchronously from the Google Play application to your BroadcastReceiver. To see an example of how you can send and receive these intent messages, see the BillingReceiver.java and BillingService.java files in the sample application. You can use these samples as a basis for your own implementation. However, if you use any of the code from the sample application, be sure you follow the guidelines in Security and Design.

Creating a BroadcastReceiver


The Google Play application uses broadcast intents to send asynchronous billing responses to your application. To receive these intent messages, you need to create a BroadcastReceiver that can handle the following intents:

com.android.vending.billing.RESPONSE_CODE This broadcast intent contains a Google Play response code, and is sent after you make an in-app billing request. For more information about the response codes that are sent with this response, see Google Play Response Codes for In-app Billing.

com.android.vending.billing.IN_APP_NOTIFY This response indicates that a purchase has changed state, which means a purchase succeeded, was canceled, or was refunded. For more information about notification messages, see In-app Billing Broadcast Intents

com.android.vending.billing.PURCHASE_STATE_CHANGED This broadcast intent contains detailed information about one or more transactions. For more information about purchase state messages, see In-app Billing Broadcast Intents

Each of these broadcast intents provide intent extras, which your BroadcastReceiver must handle. The intent extras are listed in the following table (see table 1).

Table 1. Description of broadcast intent extras that are sent in response to billing requests.这个makeRequestBundle()方法构造一个初始包,其中包含了三个键所需要的所有请求:账单请求,api版本,和PACKAGE_NAME。额外的请求nonce关键即添加到包调用sendBillingRequest之前()方法。请求nonce键包含密码安全nonce(号码使用一次),您必须生成。谷歌的玩的应用程序返回这个nonce与交易信息包含在采购状态改变了广播的意图,这样你就可以验证事务信息的完整性。


请求返回一个同步包响应,其中包含两个键:响应代码和请求id。响应码键为您提供请求状态和请求id为你提供了一个独特的请求标识符的请求。


一个恢复交易请求也触发了两个异步响应(广播意图)。首先,谷歌玩应用程序发送一个响应代码广播的意图,它提供了状态和错误信息的请求。接下来,如果请求是成功的,谷歌玩应用程序发送一个购买状态改变了广播的意图。这个信息包含详细的事务信息。事务信息包含在一个签署了JSON字符串(加密)。消息包含签名,这样你就可以验证完整性的签名字符串。


注意:您应该使用恢复交易请求类型只有当你的应用程序安装在第一次在一个设备或当你的应用程序中已删除并重新安装一个装置。


其他服务任务

您可能还想要你的服务来接收消息从你BroadcastReceiver意图。您可以使用这些意图消息转达信息从谷歌异步发送应用程序BroadcastReceiver玩。看一个例子说明你是如何可以发送和接收这些意图的信息,请参见BillingReceiver。java和BillingService。在示例应用程序的java文件。您可以使用这些示例作为一个基础,在您自己的实现。然而,如果你使用任何的代码样例应用程序,确保您遵循的指导方针的安全设计。


BroadcastReceiver创建一个


————————————————————————————————————————————————————————————————————————————————


谷歌的应用程序使用意图发挥广播发送异步计费反应到您的应用程序。接受这些意图的消息,您需要创建一个BroadcastReceiver可以处理以下的意图:


com android自动售货计费响应代码

这个广播意图包含一个谷歌玩响应代码,并且送了你做一个应用收费的请求。更多信息发送响应代码对这个响应,看到谷歌玩响应代码为应用收费。


com android自动售货中的付费应用程序通知

此响应表明购买已经改变状态,这意味着一个购买成功,被取消了,或者被退还。通知消息的更多信息,请参阅应用收费广播意图


com android自动售货计费采购状态更改

这个广播意图包含详细的信息的一个或多个事务。为更多的信息关于采购状态消息,查看应用收费广播意图


每个这些广播意图提供额外的意图,而你们BroadcastReceiver必须处理。意图附加列在下面的表(参见表1)。


表1。描述广播意图额外物品,这些都是响应中发送请求到收费。

The following code sample shows how to handle these broadcast intents and intent extras within a BroadcastReceiver. The BroadcastReceiver in this case is named BillingReceiver, just as it is in the sample application.

 
public class BillingReceiver extends BroadcastReceiver {
 
  private static final String TAG = "BillingReceiver";
 
  // Intent actions that we receive in the BillingReceiver from Google Play.
  // These are defined by Google Play and cannot be changed.
  // The sample application defines these in the Consts.java file.
  public static final String ACTION_NOTIFY = "com.android.vending.billing.IN_APP_NOTIFY";
  public static final String ACTION_RESPONSE_CODE = "com.android.vending.billing.RESPONSE_CODE";
  public static final String ACTION_PURCHASE_STATE_CHANGED =
    "com.android.vending.billing.PURCHASE_STATE_CHANGED";
 
  // The intent extras that are passed in an intent from Google Play.
  // These are defined by Google Play and cannot be changed.
  // The sample application defines these in the Consts.java file.
  public static final String NOTIFICATION_ID = "notification_id";
  public static final String INAPP_SIGNED_DATA = "inapp_signed_data";
  public static final String INAPP_SIGNATURE = "inapp_signature";
  public static final String INAPP_REQUEST_ID = "request_id";
  public static final String INAPP_RESPONSE_CODE = "response_code";
 
 
  @Override
  public void onReceive(Context context, Intent intent) {
    String action = intent.getAction();
    if (ACTION_PURCHASE_STATE_CHANGED.equals(action)) {
      String signedData = intent.getStringExtra(INAPP_SIGNED_DATA);
      String signature = intent.getStringExtra(INAPP_SIGNATURE);
      // Do something with the signedData and the signature.
    } else if (ACTION_NOTIFY.equals(action)) {
      String notifyId = intent.getStringExtra(NOTIFICATION_ID);
      // Do something with the notifyId.
    } else if (ACTION_RESPONSE_CODE.equals(action)) {
      long requestId = intent.getLongExtra(INAPP_REQUEST_ID, -1);
      int responseCodeIndex = intent.getIntExtra(INAPP_RESPONSE_CODE,
        ResponseCode.RESULT_ERROR.ordinal());
      // Do something with the requestId and the responseCodeIndex.
    } else {
      Log.w(TAG, "unexpected action: " + action);
    }
  }
  // Perform other processing here, such as forwarding intent messages to your local service.
}
 

In addition to receiving broadcast intents from the Google Play application, your BroadcastReceiver must handle the information it received in the broadcast intents. Usually, your BroadcastReceiver does this by sending the information to a local service (discussed in the next section). The BillingReceiver.java file in the sample application shows you how to do this. You can use this sample as a basis for your own BroadcastReceiver. However, if you use any of the code from the sample application, be sure you follow the guidelines that are discussed in Security and Design .

Verifying Signatures and Nonces


Google Play's in-app billing service uses two mechanisms to help verify the integrity of the transaction information you receive from Google Play: nonces and signatures. A nonce (number used once) is a cryptographically secure number that your application generates and sends with every GET_PURCHASE_INFORMATION and RESTORE_TRANSACTIONS request. The nonce is returned with the PURCHASE_STATE_CHANGED broadcast intent, enabling you to verify that any given PURCHASE_STATE_CHANGED response corresponds to an actual request that you made. Every PURCHASE_STATE_CHANGED broadcast intent also includes a signed JSON string and a signature, which you can use to verify the integrity of the response.

Your application must provide a way to generate, manage, and verify nonces. The following sample code shows some simple methods you can use to do this.除了接受广播意图从谷歌玩的应用程序,你必须处理的信息BroadcastReceiver中收到广播意图。通常,你可以通过BroadcastReceiver把信息发送给本地服务(在下一节讨论)。BillingReceiver的。java文件在样例应用程序向你展示了如何做到这一点。您可以使用这个示例作为一个基础,在你自己的BroadcastReceiver。然而,如果你使用任何的代码样例应用程序,确保您遵循的指导方针,是讨论在安全性和设计。


验证签名和目前


————————————————————————————————————————————————————————————————————————————————


谷歌玩的应用收费服务使用两种机制来帮助验证事务信息的完整性,您收到谷歌玩耍:目前和签名。一个nonce(号码使用一次)是一个密码安全号码,您的应用程序生成和发送给每个获得购买信息和恢复交易请求。返回此nonce与采购状态改变了广播的意图,使您能够验证任何给定的采购状态改变响应对应一个实际的请求您。每个采购状态改变了广播的意图还包括一个签署了JSON字符串和一个签名,您可以使用它来验证的完整性的响应。


您的应用程序必须提供一种方法来生成、管理和验证过的nonce。下面的示例代码展示了一些简单的方法你可以使用的。

 
 private static final SecureRandom RANDOM = new SecureRandom();
  private static HashSet<Long> sKnownNonces = new HashSet<Long>();
 
  public static long generateNonce() {
    long nonce = RANDOM.nextLong();
    sKnownNonces.add(nonce);
    return nonce;
  }
 
  public static void removeNonce(long nonce) {
    sKnownNonces.remove(nonce);
  }
 
  public static boolean isNonceKnown(long nonce) {
    return sKnownNonces.contains(nonce);
  }
 

Your application must also provide a way to verify the signatures that accompany every PURCHASE_STATE_CHANGED broadcast intent. The Security.java file in the sample application shows you how to do this. If you use this file as a basis for your own security implementation, be sure to follow the guidelines in Security and Design and obfuscate your code.

You will need to use your Google Play public key to perform the signature verification. The following procedure shows you how to retrieve Base64-encoded public key from the Google Play publisher site.

Log in to your publisher account. On the upper left part of the page, under your name, click Edit profile. On the Edit Profile page, scroll down to the Licensing & In-app Billing panel (see figure 2). Copy your public key. Important: To keep your public key safe from malicious users and hackers, do not embed your public key as an entire literal string. Instead, construct the string at runtime from pieces or use bit manipulation (for example, XOR with some other string) to hide the actual key. The key itself is not secret information, but you do not want to make it easy for a hacker or malicious user to replace the public key with another key.您的应用程序还必须提供一种方法来验证签名,伴随每次采购状态改变了广播的意图。安全。java文件在样例应用程序向你展示了如何做到这一点。如果你使用这个文件为基础,实现您自己的安全,一定要按照指南在安全、设计和混淆你的代码。


您将需要使用你的谷歌玩公钥来执行签名验证。下面的过程显示了如何检索base64编码的公共密匙的谷歌玩出版商网站。


登录到你的发布者帐户。

左上角页面的一部分,在你的名字,点击编辑按钮。

在编辑页面,向下滚动到许可&应用收费面板(见图2)。

复制你的公钥。

重要:为了保持你的公钥免受恶意用户和黑客,不要嵌入您的公钥作为一个整体文字字符串。相反,在运行时构建字符串从碎片或使用位操作(例如,XOR与其他字符串)来隐藏实际的关键。密匙本身不是秘密信息,但是你不想容易让一个黑客或者恶意的用户来取代公共密钥与另一个关键。

Billing public key.png

Figure 2. The Licensing and In-app Billing panel of your account's Edit Profile page lets you see your public key.

Modifying Your Application Code


After you finish adding in-app billing components to your project, you are ready to modify your application's code. For a typical implementation, like the one that is demonstrated in the sample application, this means you need to write code to do the following:

Create a storage mechanism for storing users' purchase information. Create a user interface that lets users select items for purchase. The sample code in Dungeons.java shows you how to do both of these tasks.

Creating a storage mechanism for storing purchase informationYou must set up a database or some other mechanism for storing users' purchase information. The sample application provides an example database (PurchaseDatabase.java); however, the example database has been simplified for clarity and does not exhibit the security best practices that we recommend. If you have a remote server, we recommend that you store purchase information on your server instead of in a local database on a device. For more information about security best practices, see Security and Design.

Note: If you store any purchase information on a device, be sure to encrypt the data and use a device-specific encryption key. Also, if the purchase type for any of your items is "unmanaged," we recommend that you back up the purchase information for these items to a remote server or use Android's data backup framework to back up the purchase information. Backing up purchase information for unmanaged items is important because unmanaged items cannot be restored by using the RESTORE_TRANSACTIONS request type.

Creating a user interface for selecting itemsYou must provide users with a means for selecting items that they want to purchase. Google Play provides the checkout user interface (which is where the user provides a form of payment and approves the purchase), but your application must provide a control (widget) that invokes the sendBillingRequest() method when a user selects an item for purchase.

You can render the control and trigger the sendBillingRequest() method any way you want. The sample application uses a spinner widget and a button to present items to a user and trigger a billing request (see Dungeons.java). The user interface also shows a list of recently purchased items.

图2。许可和应用收费面板您的帐户的编辑页面让你看到你的公钥。


修改您的应用程序代码


————————————————————————————————————————————————————————————————————————————————


在你完成添加组件到你的项目中应用收费,你准备好修改应用程序的代码。对于一个典型的实现,就象一个演示了在示例应用程序中,这意味着您需要编写代码来做到以下几点:


创建一个存储机制,用于存储用户的购买信息。

创建一个用户界面,用户可以选择购买的物品。

在地下城的示例代码。java显示你如何做这两个任务。


创建一个存储机制,用于存储购买信息

你必须建立一个数据库或一些其他的机制,用于存储用户的购买信息。样例应用程序提供了一个示例数据库(PurchaseDatabase.java);然而,这个示例数据库已经被简化为清晰起见,不存在安全最佳实践,我们建议。如果你有一个远程服务器上,我们建议你商店的购买信息在你的服务器,而不是在一个设备上的本地数据库。更多信息的安全最佳实践,见安全性和设计。


注意:如果您购买信息存储任何设备上,一定要对数据进行加密,使用一个特定于设备的加密密钥。同样,如果购买你的产品类型为任何“托管”,我们建议您已经备份了这些商品的购买信息到一个远程服务器或者使用Android的数据备份框架来支持购买信息。备份购买信息非托管项目很重要,因为非托管项目不能恢复使用恢复交易请求类型。


创建一个用户界面来选择项目

你必须提供给用户一个手段,他们想要选择物品购买。谷歌的checkout播放提供了用户界面(这是用户提供了一种形式的支付和确认购买的),但您的应用程序必须提供一个控制(小部件),调用sendBillingRequest()方法当用户选择一个项目,为购买。


你可以呈现控制和触发sendBillingRequest()方法任何你想要的方式。该示例应用程序使用一个转子部件和一个按钮呈现项目对用户和触发账单请求(参见地牢java)。用户界面还列出了最近购买的物品。


转自:http://wiki.eoeandroid.com/Implementing_In-app_Billing

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值