jamesmontemagno / InAppBillingPlugin

Cross-platform In App Billing Plugin for .NET
MIT License
651 stars 152 forks source link

Android: Object reference not set to an instance of an object. #18

Closed klint01 closed 7 years ago

klint01 commented 7 years ago

I haven't been able to test Android with a real phone until recently and it is failing to make the call to Google Play Store for In-App purchase. I get the following as a catch error with any call: Object reference not set to an instance of an object.

Example of calls are GetPurchase and GetProducts. I have the below code in my MainActivity.cs inside the MainActivity class. Is there a permission that needs to be enable for android. I have access network state, access wifi state, and internet permissions enabled.

protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
    base.OnActivityResult(requestCode, resultCode, data);
    InAppBillingImplementation.HandleActivityResult(requestCode, resultCode, data);
}

It feels as though this is a simple item that is missing.

Thanks!

jamesmontemagno commented 7 years ago

Once the package is installed you need to upload a version of your app to google play as it will now contain the BILLING permission. Then you can test and use the APIs. You must test on device.

jamesmontemagno commented 7 years ago

Did you also call out to "ConnectAsync()"? What did it return?

klint01 commented 7 years ago

thanks for the response. Yep, I've got all of that (published under alpha). I don't have the step-by-step debug messages when ConectAsync was called, but it did jump straight to the catch error and publish the ex.message that I put in the subject line. For example, GetProducts(), it's the same as your sample code.

jamesmontemagno commented 7 years ago

That usually means that you aren't connected. What is your code look like?

klint01 commented 7 years ago

I have permissions set for AccessNetworkState, AccessWifiState, and Internet. I know I can connect externally because my dropbox file is getting read which shows a list of products in the App Store.

Below is the code and the Application output is below that.

// Check store if product was previously purchased
async Task<bool> CheckPurchase(string productId, string file, string deckName)
{
    System.Diagnostics.Debug.WriteLine(" ** CheckPurchase: pre-check => " + productId);
    try
    {
        //var productId = productID;
        var connected = await CrossInAppBilling.Current.ConnectAsync();

        if (!connected)
        {
            //Couldn't connect
            System.Diagnostics.Debug.WriteLine(" ** CheckPurchase: failed to connect to store");
            return false;
        }

        //check purchases
        var purchases = await CrossInAppBilling.Current.GetPurchasesAsync(ItemType.InAppPurchase);
        //System.Diagnostics.Debug.WriteLine(" ** CheckPurchase: post-check => " + productId);

        if (purchases?.Any(p => p.ProductId == productId) ?? false)
        {
            //Purchase restored
            return true;
        }
        else
        {
            //no purchases found
            return false;
        }
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.WriteLine(" ** CheckPurchase: cacth error => " + ex.Message);
        return false;
    }
    finally
    {
        await CrossInAppBilling.Current.DisconnectAsync();
    }
}

Application output:

 ** CheckPurchase: pre-check => whatchasayin.deck.custom
[Mono] Assembly Ref addref Plugin.InAppBilling[0x7f7a430f80] -> Plugin.InAppBilling.VendingLibrary[0x7f7a405300]: 2
[Mono] Assembly Ref addref Plugin.InAppBilling.VendingLibrary[0x7f7a405300] -> Mono.Android[0x7f79720500]: 16
[Mono] Assembly Ref addref Plugin.InAppBilling[0x7f7a430f80] -> Plugin.CurrentActivity[0x7f7a430580]: 2
[Mono] Assembly Ref addref Plugin.CurrentActivity[0x7f7a430580] -> Mono.Android[0x7f79720500]: 17
[Mono] Assembly Ref addref Plugin.InAppBilling[0x7f7a430f80] -> System.Core[0x7f7725fc80]: 12
 ** CheckPurchase: cacth error => Object reference not set to an instance of an object.
jamesmontemagno commented 7 years ago

You may have to bring in the library and add it to your project manually and debug through for more information. Something might be going wrong or google is returning bad data. It is pretty straight code:

https://github.com/jamesmontemagno/InAppBillingPlugin/blob/master/src/Plugin.InAppBilling.Android/InAppBillingImplementation.cs#L164

klint01 commented 7 years ago

Agreed, I'll do that. Worked best when debugging iOS. Just need to get my hands on an android phone. Thanks! I'll keep you posted if anything funny shows up.

klint01 commented 7 years ago

I was able to purchase a Motorola Droid Razr, root it and flash Marshmallow on it, which my app needs Android v6.0+ to work. I can install the app, but unable to test via the src projects instead of the beta package.

I uninstalled the beta package from Droid project, pulled in the Abstractions and Android src packages, tied the references to my Droid project, but unable to get past an error where it cannot find "using Com.Android.Vending.Billing;" in the InAppBillingImplementation.cs within Android src package.

I tried pulling in the Vending.Library and InAppBilling projects which did not resolve the issue.

As a reminder the issue appears that the app cannot talk to Google Play store. After it calls ConnectAsync(), it jumps directly to catch error. The Exception message is "Object reference not set to an instance of an object"

The IAP products exists and in Active status. In addition, my application is deployed to Google Play for Alpha testing.

In my AndroidMainfest, here are the set permissions:

    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
klint01 commented 7 years ago

I also tried adding a permission for "" in the manifest per research, but getting the same result.

It feels like a permission or sdk issue.

klint01 commented 7 years ago

BTW, my app was approved by Apple. If you are interested in the game, I would be happy to send you a promo code for all your help.

https://itunes.apple.com/us/app/id1195263206

klint01 commented 7 years ago

I just ran across your blog on Xamarin and found that I need to manually add com.android.vending.BILLING to the Android manifest and then publish to Google again for Alpha testing.

Per your note above, I understood it to mean that the plugin package would automatically add the permission, but it must not have done so.

Waiting for Google Play to finish processing the upload and will then test again.

jamesmontemagno commented 7 years ago

It should automatically via: https://github.com/jamesmontemagno/InAppBillingPlugin/blob/master/src/Plugin.InAppBilling.Android/Properties/AssemblyInfo.cs#L32

You still need to publish it with the plugin installed and then you would see the ability to actually create your IAP. If you don't then you will get the exception.

klint01 commented 7 years ago

Then I really shouldn't be running into this issue. I had previously added the plugin as a package, packaged and signed the app and published to Google Play as Alpha apk. Anyway, I republished with manually adding. Having a friend test when he gets home. Unfortunately, I can't grab it from Google Play via Alpha because the cheap phone I could find for testing was never intended to support OS v6. I can manually push it via the computer, but I am running into the same issues as outlined above.

klint01 commented 7 years ago

I manually added BILLING permission and updated your plugin to 1.1.0.23 -beta and I am now getting a new exception message via the catch error for Android. Still un able to run IAP. Any other thoughts?

Didn't find class "md5c2c773b7fcec47aefdb37f23b43c45e9.InAppBillingImplementation_InAppBillingServiceConnection" on path: DexPathList[[zip file "/data/app/com.klinker.whatchasayin-1/base.apk"],nativeLibraryDirectories=[/data/app/com.klinker.whatchasayin-1/lib/arm, /data/app/com.klinker.whatchasayin-1/base.apk!/lib/armeabi-v7a, /vendor/lib, /system/lib]]

jamesmontemagno commented 7 years ago

What is your linker set to? seems like something is wrong perhaps.

klint01 commented 7 years ago

Link SDK Assemblies Only

After reading your blog a few times, I deleted all of my previous IAP setups and created new ones, but still same 'didn't find class' issue.

jamesmontemagno commented 7 years ago

Do you have progaurd or anything like that turned on? is this in debug or release?

Do you have the new updates from yesterday? And what Android SDK and Tools are you building against.

klint01 commented 7 years ago

No on Proguard or Multi-Dex, just have Generate one apk selected.

Latest issue is in debug mode. I did install the updates from yesterday. Using the Xamarin Studio Community IDE. So it has the standard Android SDKs installed for Tools, OS 7.1, OS 7.0, and OS 6.0. For extras I have the following installed: Android Support Repository google Play Services Google Repository Google Play Licensing Library Google Play Billing Library Google Web Driver

klint01 commented 7 years ago

I delete the IAP plug-in and reinstall 1.1.0.15-beta and I am back to the previous catch error -> exception message.

Object reference not set to an instance of an object.

jamesmontemagno commented 7 years ago

If you are in debug try to uncheck the use shared runtime and see if that fixes it.

klint01 commented 7 years ago

Unchecked shared runtime and did a clean build and with 1.1.0.15, still getting the same Object Reference error.

BTW, thank you for the ideas/support.

klint01 commented 7 years ago

Upgraded again to .23-beta and getting the following error. I also removed Shared Runtime.

Didn't find class "md5c2c773b7fcec47aefdb37f23b43c45e9.InAppBillingImplementation_InAppBillingServiceConnection" on path: DexPathList[[zip file "/data/app/com.klinker.whatchasayin-1/base.apk"],nativeLibraryDirectories=[/data/app/com.klinker.whatchasayin-1/lib/arm, /data/app/com.klinker.whatchasayin-1/base.apk!/lib/armeabi-v7a, /vendor/lib, /system/lib]]

klint01 commented 7 years ago

@jamesmontemagno would it be helpful to see the code? I can add you as a collaborator in GitHub.

klint01 commented 7 years ago

Do I think it is not working because of the original steps I took? Did the order I took, cause the problem?

1) setup IAP products 2) published the app to Google Play for Alpha Testing with the IAPBiling plugin installed 3) read your blog and deleted IAP products 4) republished the app for Alpha with manually stating permission for BILLING, and IAPBilling plugin still installed

If so, any thoughts on how to resolve it?

jamesmontemagno commented 7 years ago

instead of using the nuget have you tried just pulling the projects into your app to validate that?

jamesmontemagno commented 7 years ago

I just re-validated yet again and it is working great in all 3 of my apps :)

klint01 commented 7 years ago

I have installed the plugin nuget and pulled in the individual projects, but it will not allow me to compile because of the "using com.android.vendor.billing" statement in the InAppBillingImplementation.cs within Android src package. It is unable to find it as a reference, so I've been unable to debug with the source projects.

I am confident this is a simple thing that is being overlooked, just can't seem to find it. Would you be okay if I gave you access to my project in git for a quick look? I realize you have tons on your plate, just a thought. Outside of the Droid project, the IAP calls are in one PCL view page.

klint01 commented 7 years ago

I followed your steps in the other thread to pull in the projects manually to my overall Xamarin Solution and I am still getting compile errors in debug mode (below).

Project: Plugin.InAppBilling.Android File: InAppBillingImplementation.cs

ln 9: using Com.Android.Vending.Billing; error: /InAppBillingPlugin/src/Plugin.InAppBilling.Android/InAppBillingImplementation.cs(7,7): Error CS0246: The type or namespace name `Com' could not be found. Are you missing an assembly reference? (CS0246) (Plugin.InAppBilling.Android)

ln 501: public IInAppBillingService Service { get; private set; } error: /InAppBillingPlugin/src/Plugin.InAppBilling.Android/InAppBillingImplementation.cs(20,20): Error CS0246: The type or namespace name `IInAppBillingService' could not be found. Are you missing an assembly reference? (CS0246) (Plugin.InAppBilling.Android)

I realize the second error will resolve itself once ln 9 is resolved. I manually added VendingLibrary as a reference to the Plugin.InAppBilling.Android project but it still does not recognize com.android.vending.billing.

klint01 commented 7 years ago

InAppBillingImplementation.cs

vendinglibrary
jamesmontemagno commented 7 years ago

Did you build the VendingLibrary? that is where it is generated from...

image

jamesmontemagno commented 7 years ago

Or see what is being generated by the dll when you double click on the reference. image

klint01 commented 7 years ago

Yes, I did build the VendingLibrary

references

And when I double-click VendingLibrary reference within InAppBilling.Android project, the assembly page shows up.

vendinglibraryreference
klint01 commented 7 years ago

I removed all of the manual projects and re-added them, set the references and did a Rebuild and now I am getting something completely new.

/Library/Frameworks/Mono.framework/External/xbuild/Xamarin/Android/Xamarin.Android.Common.targets: Error: Error executing task GenerateJavaStubs: Application cannot have both a type with an [Application] attribute and an [assembly:Application] attribute. (WhatchaSayin.Droid)

jamesmontemagno commented 7 years ago

you have two [Aplication] attributes somewhere in your android projects or libraries... look for them.

klint01 commented 7 years ago

I think I may have it working now, but only via the individual source project and not via the plugin package. I commented out the Application Debuggable assembly and I can successfully build the solution.

Did a debug install to my phone via Xamarin Studio connected to the computer and I actually got success in connecting with Google Play. So removed the source projects and reinstalled .23-beta package. Did a clean build and install to phone (same process), but no success in connecting to Google Play. Therefore, I removed the plugin, reinstalled the source projects and ran it again. Success.

So I did a clean release build and published to Google Play for Alpha testing. Now I am in waiting mode for my buddy to test it since I don't have an android phone to properly test with. I'm keeping my fingers-crossed that this does the trick. If it does, curious to understand why individual projects work but not via the plugin install. I'll let you know how it goes.

alex9153 commented 6 years ago

Hi. Your plugin works perfect on iOS, but not working on Android. Crash happens here var connected = await CrossInAppBilling.Current.ConnectAsync();