所以我想在unity3d制作的游戏中制作游戏购买物品。
我正在测试基于新的unity3d版本(4.3.1)和android sdk,in-app-buy API 3.
所以我在开发者控制台上测试了应用内购买项目(托管,非托管),
和eclipse java源码的统一插件就像,
package com.dimension14.unityandroidjartest;
import java.util.List;
import org.json.JSONException;
import org.json.JSONObject;
import android.R.string;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import com.example.android.trivialdrivesample.util.IabHelper;
import com.example.android.trivialdrivesample.util.IabHelper.OnConsumeFinishedListener;
import com.example.android.trivialdrivesample.util.IabHelper.OnIabPurchaseFinishedListener;
import com.example.android.trivialdrivesample.util.IabHelper.QueryInventoryFinishedListener;
import com.example.android.trivialdrivesample.util.IabResult;
import com.example.android.trivialdrivesample.util.Inventory;
import com.example.android.trivialdrivesample.util.Purchase;
import com.unity3d.player.UnityPlayer;
import com.unity3d.player.UnityPlayerActivity;
public class MainActivity extends UnityPlayerActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public void javaTestFunc(String strFromUnity) {
UnityPlayer.UnitySendMessage("AndroidManager", "SetLog", strFromUnity + "HelloWorld");
}
static final int RC_REQUEST = 10001;
private static final String LOG_TAG = null;
private IabHelper mHelper;
public void InAppInit_U(String strPublicKey, boolean bDebug) {
Log.d(LOG_TAG, "Creating IAB helper." + bDebug);
mHelper = new IabHelper(this, strPublicKey);
if(bDebug == true) {
mHelper.enableDebugLogging(true, "IAB");
}
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
@Override
public void onIabSetupFinished(IabResult result) {
// TODO Auto-generated method stub
boolean bInit = result.isSuccess();
Log.d(LOG_TAG, "IAB Init " + bInit + result.getMessage());
if(bInit == true) {
Log.d(LOG_TAG, "Querying inventory.");
//QueryInventoryFinishedListener mGotInventoryListener = null;
mHelper.queryInventoryAsync(mGotInventoryListener);
}
UnityPlayer.UnitySendMessage("AndroidManager", "InAppInitResult_J", String.valueOf(bInit));
}
});
}
//Listener that's called when we finish querying the items and subscriptions we own
IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
if (result.isFailure()) {
Log.d(LOG_TAG, "Failed to query inventory: " + result);
SendConsumeResult(null, result);
return;
}
/*
* Check for items we own. Notice that for each purchase, we check
* the developer payload to see if it's correct! See
* verifyDeveloperPayload().
*/
List<String> inappList = inventory.getAllOwnedSkus(IabHelper.ITEM_TYPE_INAPP);
for(String inappSku : inappList) {
Purchase purchase = inventory.getPurchase(inappSku);
Log.d(LOG_TAG, "Consumeing ... " + inappSku);
UnityPlayer.UnitySendMessage("AndroidManager", "InAppBuyItemResult_J", inappSku);
mHelper.consumeAsync(purchase, mConsumeFinishedListener);
if(inappSku.equals("itemtest1")){
//give user access to premium unlock item
UnityPlayer.UnitySendMessage("AndroidManager", "UnlockItem", "");
}
if(inappSku.equals("consumeitem1")){
// consume consumable item
mHelper.consumeAsync(purchase, mConsumeFinishedListener);
UnityPlayer.UnitySendMessage("AndroidManager", "BoughtConsume1", "");
}
}
Log.d(LOG_TAG, "Query inventory was successful.");
}
};
public void InAppBuyItem_U(final String strItemId) {
runOnUiThread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
/* TODO: for security, generate your payload here for verification. See the comments on
* verifyDeveloperPayload() for more info. Since this is a SAMPLE, we just use
* an empty string, but on a production app you should carefully generate this. */
String payload = "";
OnIabPurchaseFinishedListener mPurchaseFinishedListener = null;
mHelper.launchPurchaseFlow(UnityPlayer.currentActivity
, strItemId, RC_REQUEST, mPurchaseFinishedListener, payload);
Log.d(LOG_TAG, "InAppBuyItem_U " + strItemId);
}
});
}
// Callback for when a purchase is finished
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
Log.d(LOG_TAG, "Purchase finished: " + result + ", purchase: " + purchase);
if(purchase != null) {
if(!verifyDeveloperPayload(purchase)) {
Log.d(LOG_TAG, "Error purchasing. Authenticity verification failed.");
}
if(result.isFailure()){
Log.d(LOG_TAG, "Error purchasing : "+result);
return;
}
else if(purchase.getSku().equals("itemtest1")){
//give user access to premium unlock item
UnityPlayer.UnitySendMessage("AndroidManager", "UnlockItem", "");
}
else if(purchase.getSku().equals("consumeitem1")){
// consume consumable item
mHelper.consumeAsync(purchase, mConsumeFinishedListener);
UnityPlayer.UnitySendMessage("AndroidManager", "BoughtConsume1", "");
}
Log.d(LOG_TAG, "Purchase is gas. Starting gas consumption.");
UnityPlayer.UnitySendMessage("AndroidManager", "InAppBuyItemResult2", "result is "+result+" purchase is "+purchase);
mHelper.consumeAsync(purchase, mConsumeFinishedListener);
}
else {
UnityPlayer.UnitySendMessage("AndroidManager", "InAppBuyItemResult_J", String.valueOf(result.getResponse()));
}
}
boolean verifyDeveloperPayload( Purchase purchase) {
String payload = purchase.getDeveloperPayload();
/*
* TODO: verify that the developer payload of the purchase is correct. It will be
the same one that you sent when initiating the purchase.
* Using your own server to store and verify developer payloads across app
* installations is recommended.
*/
return true;
}
};
/*
boolean verifyDeveloperPayload(Purchase p) {
String payload = p.getDeveloperPayload();
return true;
}
*/
// Called when consumption is complete
IabHelper.OnConsumeFinishedListener mConsumeFinishedListener = new IabHelper.OnConsumeFinishedListener() {
public void onConsumeFinished(Purchase purchase, IabResult result) {
Log.d(LOG_TAG, "Consumption finished. Purchase: " + purchase + ", result: " + result);
if (mHelper == null) return;
if(result.isSuccess()){
SendConsumeResult(purchase, result);
}
}
};
protected void SendConsumeResult(Purchase purchase, IabResult result) {
JSONObject jsonObj = new JSONObject();
try {
jsonObj.put("Result", result.getResponse());
if(purchase != null) {
jsonObj.put("OrderId", purchase.getOrderId());
jsonObj.put("Sku", purchase.getSku());
jsonObj.put("purchaseData", purchase.getOriginalJson());
jsonObj.put("signature", purchase.getSignature());
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
UnityPlayer.UnitySendMessage("AndroidManager", "InAppConsumeResult_J", jsonObj.toString());
}
@Override
public void onDestroy() {
super.onDestroy();
// very important:
Log.d(LOG_TAG, "Destroying helper.");
if (mHelper != null) mHelper.dispose();
mHelper = null;
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d(LOG_TAG, "onActivityResult(" + requestCode + "," + resultCode + "," + data);
if(requestCode == RC_REQUEST) {
// Pass on the activity result to the helper for handling
if (!mHelper.handleActivityResult(requestCode, resultCode, data)) {
// not handled, so handle it ourselves (here's where you'd
// perform any handling of activity results not related to in-app
// billing...
super.onActivityResult(requestCode, resultCode, data);
}
else {
Log.d(LOG_TAG, "onActivityResult handled by IABUtil.");
}
}
}
} // end of MainActivity
和团结的gui脚本部分。
public class TestGUI : MonoBehaviour
{
// Update is called once per frame
void Update ()
{
if (Application.platform == RuntimePlatform.Android)
{
if (Input.GetKey(KeyCode.Escape))
{
Application.Quit();
return;
}
}
}
void OnGUI()
{
GUI.Label(new Rect(50, 30, 500, 100), AndroidManager.GetInstance().strLog);
GUI.Label(new Rect(50, 0, 500, 100), AndroidManager.GetInstance().strLog2);
GUI.Label(new Rect(50, 70, 500, 100), "Unlocked? "+AndroidManager.GetInstance().myunlockItem.ToString());
GUI.Label(new Rect(200, 70, 500, 100), "How many get currently? "+AndroidManager.GetInstance().myconsumeItem.ToString());
if (GUI.Button (new Rect(0, 100, 100, 100), "TestButton") == true)
{
AndroidManager.GetInstance().CallJavaFunc( "javaTestFunc", "UnityJavaJarTest" );
}
// In App Billing
if (GUI.Button (new Rect(150, 100, 100, 100), "InAppInit") == true)
{
bool bDebug = true;
AndroidManager.GetInstance().InAppInit(bDebug);
}
if (GUI.Button (new Rect(300, 100, 100, 100), "Buy 1-time Item") == true)
{
string strItemId = "itemtest1";
AndroidManager.GetInstance().InAppBuyItem(strItemId);
}
if (GUI.Button (new Rect(250, 200, 150, 100), "Buy consume Item") == true)
{
string strItemId = "consumeitem1";
AndroidManager.GetInstance().InAppBuyItem(strItemId);
}
}
}
首先,购买作品除了反映我的购买结果(在解锁物品时改为false,在购买消耗品时改为消耗品变量+10)
但主要问题是,在成功购买物品(谷歌结账窗口正常打开并且像正常流程一样正常工作)之后,如果再次触摸[购买项目]按钮,则不会发生任何事情。 Google结帐窗口应该会打开,但不会发生。所以我不能再购买物品了。
为什么以及如何制作物品可以再次购买?
我对谷歌的支持提出质疑,但是他们说买的物品应该被消费,但正如你在上面的消息来源所看到的那样,
我已经使用过mHelper.consumeAsync代码(purchase,mConsumeFinishedListener); 多次。
有什么问题?感谢。
答案 0 :(得分:0)
购买成功后,您必须使用一次物品,然后您才能再次购买相同物品。