[Closed] Google Cardboard IAP crashes

Hello,

I have a simple google cardboard game in Unity 5.6.1 and up to date IAP plugin. When I call ‘BuyLevels’ function the game crashes. Everything is OK in unity but I get this error on my Android device and can’t really figure out what causes the error.

08-10 17:10:53.150 26357-26422/? I/Unity: OnInitialized: PASS

(Filename: ./artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)
08-10 17:10:56.455 26357-26422/? I/Unity: Purchasing product asychronously: ‘morelevels’

(Filename: ./artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)
08-10 17:10:56.455 26357-26422/? I/UnityIAP: isUnityVrEnabled = true
08-10 17:10:56.455 26357-26422/? I/UnityIAP: onPurchaseProduct: morelevels
08-10 17:10:56.455 26357-26422/? I/UnityIAP: ITEM TYPE:inapp
08-10 17:10:56.455 26357-26422/? I/Unity: purchase({0}): morelevels

(Filename: ./artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)
08-10 17:10:56.460 26357-26357/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.uyaniksoy.powerdefencevr, PID: 26357
java.lang.Error: FATAL EXCEPTION [main]
Unity version : 5.6.1f1
Device model : samsung SM-N910C
Device fingerprint: samsung/treltexx/trelte:6.0.1/MMB29K/N910CXXS2DQGB:user/release-keys

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method ‘void com.google.vr.ndk.base.DaydreamApi.launchInVr(android.content.Intent)’ on a null object reference
at com.unity.purchasing.googleplay.GooglePlayPurchasing$6.run(GooglePlayPurchasing.java:451)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7225)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

public class Purchaser : MonoBehaviour, IStoreListener {
public static Purchaser Instance { set; get; }

private static IStoreController m_StoreController; // The Unity Purchasing system.
private static IExtensionProvider m_StoreExtensionProvider; // The store-specific Purchasing subsystems.

public static string PRODUCT_8_LEVELS = “morelevels”;

void Start() {
if (m_StoreController == null) {
InitializePurchasing();
}
}
private void Awake() {
Instance = this;
}

public void InitializePurchasing() {
if (IsInitialized()) {
return;
}
var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance());
builder.AddProduct(PRODUCT_8_LEVELS, ProductType.NonConsumable);
UnityPurchasing.Initialize(this, builder);
}

private bool IsInitialized() {
return m_StoreController != null && m_StoreExtensionProvider != null;
}

public void BuyLevels() {
BuyProductID(PRODUCT_8_LEVELS);
}

void BuyProductID(string productId) {
if (IsInitialized()) {
Product product = m_StoreController.products.WithID(productId);

if (product != null && product.availableToPurchase) {
Debug.Log(string.Format(“Purchasing product asychronously: ‘{0}’”, product.definition.id));
m_StoreController.InitiatePurchase(product);
}
else {
Debug.Log(“BuyProductID: FAIL. Not purchasing product, either is not found or is not available for purchase”);
}
}
else {
Debug.Log(“BuyProductID FAIL. Not initialized.”);
}
}

public void OnInitialized(IStoreController controller, IExtensionProvider extensions) {
Debug.Log(“OnInitialized: PASS”);
m_StoreController = controller;
m_StoreExtensionProvider = extensions;
}

public void OnInitializeFailed(InitializationFailureReason error) {
Debug.Log(“OnInitializeFailed InitializationFailureReason:” + error);
}

public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args) {
if (String.Equals(args.purchasedProduct.definition.id, PRODUCT_8_LEVELS, StringComparison.Ordinal)) {
Debug.Log(string.Format(“ProcessPurchase: PASS. Product: ‘{0}’”, args.purchasedProduct.definition.id));
PlayerPrefs.SetInt(“boughtLevels”, 1);

foreach (GameObject _lock in GameObject.FindGameObjectsWithTag(“lock”)) {
Destroy(_lock);
}
GameObject.Find(“BuyMoreLevels”).transform.GetChild(0).gameObject.GetComponent<UnityEngine.UI.Text>().text = “Thank you!”;
GameObject.Find(“BuyMoreLevels”).GetComponent<UnityEngine.UI.Button>().interactable = false;

}
else {
Debug.Log(string.Format(“ProcessPurchase: FAIL. Unrecognized product: ‘{0}’”, args.purchasedProduct.definition.id));
}
return PurchaseProcessingResult.Complete;
}

public void OnPurchaseFailed(Product product, PurchaseFailureReason failureReason) {
Debug.Log(string.Format(“OnPurchaseFailed: FAIL. Product: ‘{0}’, PurchaseFailureReason: {1}”, product.definition.storeSpecificId, failureReason));
}
}

Sorry for the horribly long post and thank you for your time.

@uygaruyaniksoy

Thanks for reporting this. We are looking into our compatibility with Google Cardboard. I apologize for any inconvenience this has caused.

1 Like

@ap-unity

Any news on the issue?

1 Like

Did you figure out what the issue was?

@ap-unity , I’m running into this issue, too. I first released my Cardboard app in the iOS App Store and designed the purchase flow such that the user is expected to take the headset off to complete the purchase (since iOS has no notion of launchInVr and brings up a modal in the middle of the screen). I planned to use the same flow to support Cardboard on Android, but the Unity IAP plugin is internally calling DaydreamApi.launchInVr(), which is only available on Daydream-compatible devices. I would love to be able to still target Cardboard instead of Daydream in order to maximize the number of devices on which the app can run. Is there any way to avoid the call to launchInVr() (and thus utilize my custom purchase flow which expects the modal in the middle of the screen)?

@dvs_code123 , @265lutab , @vuplex

Thank you for this additional information. We did make some changes several versions ago in order to support the Daydream API. Since it looks like the Cardboard and Daydream API are both packed into the Google VR SDK, we may have to look into how to handle Cardboard separately. I don’t have a time table on when this will be available. But I have made the IAP team aware of this bug.

@ap-unity

Hi, any updates on the issue? This is the only thing left that blocks us from releasing single Daydream+Cardboard apk.

Tried 2017.2.0f3 + GVR 1.110 - still reproduces.

Same issue here.

I’m going to fade the screen to black, load into a non-Cardboard scene, do the IAP there and then return.

[EDIT]
That didn’t work (once the app is running in VR mode you can’t come out of it) so I’m going to have to remove the IAP products for now and hope for a fix or try to find another solution.

@ap-unity Has this issue been added to the Issue Tracker? I can’t find it under IAP or VR…

This other article describes the issue better: [Closed] Google Cardboard IAP