好的,这是其中没有太多在线文档可用的内容之一,因此我将尽力逐步解释所有内容。摘自我的博客文章,这是一个更详细的版本(带有屏幕截图),here on The Millibit。废话不多说,
第一步:权限
这是最简单的一步。导航到您的 manifest.xml 文件并在您的标签下添加以下行:
<uses-permission android:name="com.android.vending.BILLING" />
这将为您的应用授予访问应用内结算的权限。如果您的目标版本高于 API 22,则需要确保在运行时授予此权限。
第二步: Play 管理中心
现在您需要将您的应用上传到 Google Play 控制台。我们还没有向公众发布我们的应用程序(别担心),我们只是将它上传到 BETA RELEASE 部分,这将允许我们测试应用程序内购买。我们需要这样做的原因是,Google 需要上传您的 APK 的某个版本,才能让计费流程真正发挥作用。
转到https://play.google.com/apps/publish/
创建应用程序
按照步骤设置您的应用
转到应用版本
导航到测试版
在 Android Studio 中为您的应用创建一个 APK,并将其上传到 Play 管理中心的 Beta 版
(在发布之前请确保您已经填写了商品详情、内容分级和定价和分发)
- 点击神奇按钮(发布!)
第三步:设置项目
好的,这是您必须复制和粘贴一堆文件的部分。
首先,获取this文件,下载它,并将其放在src/main它应该将自己构建到一个文件夹中
接下来,抓取this entire util 文件夹并将其粘贴到src/java folder. 然后重建您的项目以解决错误。
Util 文件夹包含以下类:
- IabBroadcastReceiver
- IabException
- IabHelper
- Iab结果
- 库存
- 购买
- 安全性
- Sku详细信息
第四步:创建产品
创建被管理产品
点击保存并制作“定价模板”
在这里,您将选择该产品的价格。您可以选择不同国家的价格,或者如果您只选择您的价格下的所有国家,它会自动调整:
- 确保应用内产品已激活并最后一次与控制台中的正确应用程序链接。
最后,记下您的产品 ID。我们将在接下来的几个步骤中使用此 ID。
- 获取您的 Base64EncodedString
转到“服务和 API”并获取您的 Base64EncodedString。将其复制并粘贴到某处的记事本中,以便您可以访问它。请勿与任何人分享此内容,他们将能够对其进行恶意操作。
第五步:终于!我们可以开始编码:
我们将首先绑定到应用内计费库,并查询用户已购买/未购买的内容。然后,我们将购买我们之前设置的产品。
首先,导入我们之前设置的所有内容:
import util.*;
现在我们将使用一个名为 mHelper 的 IabHelper 对象,我们将使用它来做所有事情。
base64EncodedPublicKey = ""; //PUT YOUR BASE64KEY HERE
mHelper = new IabHelper(this, base64EncodedPublicKey);
mHelper.enableDebugLogging(false); //set to false in real app
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(IabResult result) {
if (!result.isSuccess()) {
// Oh no, there was a problem.
if (result.getResponse() == 3) {
new AlertDialog.Builder(MainActivity.this)
.setTitle("In app billing")
.setMessage("This device is not compatible with In App Billing, so" +
" you may not be able to buy the premium version on your phone. ")
.setPositiveButton("Okay", null)
.show();
}
Log.v(TAG, "Problem setting up In-app Billing: " + result);
} else {
Log.v(TAG, "YAY, in app billing set up! " + result);
try {
mHelper.queryInventoryAsync(mGotInventoryListener); //Getting inventory of purchases and assigning listener
} catch (IabHelper.IabAsyncInProgressException e) {
e.printStackTrace();
}
}
}
});
好的,让我分解一下这里发生了什么。基本上,我们调用“startSetup”来初始化我们的“IabHelper”。如果设置成功,我们会查询用户已经购买了什么,并将响应存储在mGotInventoryListener,接下来我们将对其进行编码:
IabHelper.QueryInventoryFinishedListener mGotInventoryListener
= new IabHelper.QueryInventoryFinishedListener() {
public void onQueryInventoryFinished(IabResult result,
Inventory inventory) {
i = inventory;
if (result.isFailure()) {
// handle error here
Log.v(TAG, "failure in checking if user has purchases");
} else {
// does the user have the premium upgrade?
if (inventory.hasPurchase("premium_version")) {
premiumEditor.putBoolean("hasPremium", true);
premiumEditor.commit();
Log.v(TAG, "Has purchase, saving in storage");
} else {
premiumEditor.putBoolean("hasPremium", false);
premiumEditor.commit();
Log.v(TAG, "Doesn't have purchase, saving in storage");
}
}
}
};
上面的代码是不言自明的。基本上,它只是检查用户已经购买了什么。既然我们知道用户是否已经购买了我们的产品,我们就知道是否要求他们购买我们的产品!如果他们以前从未购买过我们的产品,让我们发起购买请求:
public void buyPremium() {
try {
mHelper.flagEndAsync();//If any async is going, make sure we have it stop eventually
mHelper.launchPurchaseFlow(this, "premium_version", 9, mPurchaseFinishedListener, "SECURITYSTRING"); //Making purchase request and attaching listener
} catch (Exception e) {
e.printStackTrace();
mHelper.flagEndAsync();//If any async is going, make sure we have it stop eventually
new AlertDialog.Builder(MainActivity.this)
.setTitle("Error")
.setMessage("An error occurred in buying the premium version. Please try again.")
.setPositiveButton("Okay", null)
.show();
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d(TAG, "onActivityResult(" + requestCode + "," + resultCode + "," + data);
// Pass on the activity result to the helper for handling
if (!mHelper.handleActivityResult(requestCode, resultCode, data)) {
}
else
Log.d(TAG, "onActivityResult handled by IABUtil.");
}
}
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener
= new IabHelper.OnIabPurchaseFinishedListener() {
public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
Log.v(TAG, "purchase finished");
if (purchase != null) {
if (purchase.getSku().equals("premium_version")) {
Toast.makeText(MainActivity.this, "Purchase successful!", Toast.LENGTH_SHORT).show();
premiumEditor.putBoolean("hasPremium", true);
premiumEditor.commit();
}
} else {
return;
}
if (result.isFailure()) {
return;
}
}
};
在这里,我们使用以下内容购买物品(使用我们之前在游戏控制台中生成的 ID):
mHelper.launchPurchaseFlow(this, "premium_version", 9, mPurchaseFinishedListener, "SECURITYSTRING"); //Making purchase request and attaching listener
请注意,我们将mPurchaseFinishedListener 传递到参数中。这意味着购买的结果将返回给这个监听器。然后,我们只需检查购买是否为空,如果不是,则奖励用户购买的任何功能。
不要让听众泄漏!当应用程序销毁时,我们必须销毁它们。
@Override
public void onDestroy() {
super.onDestroy();
if (mHelper != null)
try {
mHelper.dispose();
mHelper = null;
} catch (IabHelper.IabAsyncInProgressException e) {
e.printStackTrace();
}
}
最后,如果您想消费您的购买,使其再次可供购买,您可以轻松完成。例如,如果用户为虚拟汽车购买了汽油,但汽油用完了。他们需要再次购买相同的产品,您可以通过消费它来进行第二次购买:
public void consume(){
//MAKING A QUERY TO GET AN ACCURATE INVENTORY
try {
mHelper.flagEndAsync(); //If any async is going, make sure we have it stop eventually
mHelper.queryInventoryAsync(mGotInventoryListener); //Getting inventory of purchases and assigning listener
if(i.getPurchase("gas")==null){
Toast.makeText(this, "Already consumed!", Toast.LENGTH_SHORT).show();
}
} catch (IabHelper.IabAsyncInProgressException e) {
e.printStackTrace();
Toast.makeText(this, "Error, try again", Toast.LENGTH_SHORT).show();
mHelper.flagEndAsync();//If any async is going, make sure we have it stop eventually
}
//ACTUALLY CONSUMING
try {
mHelper.flagEndAsync();//If any async is going, make sure we have it stop eventually
this.mHelper.consumeAsync(this.i.getPurchase("gas"), new IabHelper.OnConsumeFinishedListener() {
public void onConsumeFinished(Purchase paramAnonymousPurchase, IabResult paramAnonymousIabResult) {
//resell the gas to them
}
});
return;
} catch (IabHelper.IabAsyncInProgressException localIabAsyncInProgressException) {
localIabAsyncInProgressException.printStackTrace();
Toast.makeText(this, "ASYNC IN PROGRESS ALREADY!!!!" +localIabAsyncInProgressException, Toast.LENGTH_LONG).show();
Log.v("myTag", "ASYNC IN PROGRESS ALREADY!!!");
mHelper.flagEndAsync();
}
}
就是这样!你现在可以开始赚钱了。真的就这么简单!
同样,如果您想要本教程的更详细版本,包括屏幕截图和图片,请访问original post here。如果您还有任何问题,请在 cmets 中告诉我。