[mono-android] Does anyone have a code example for using Google Market Licensing with MonoDroid?

Jonathan Pryor jonp at xamarin.com
Fri Jan 20 12:26:45 UTC 2012


On Jan 19, 2012, at 4:58 PM, Mark Eaton wrote:
> Now I need to implement the call back based on a Java interface:
> "com/android/vending/licensing/LicenseCheckerCallback"

See the SanityTests sample:

	Java: https://github.com/xamarin/monodroid-samples/blob/master/SanityTests/Adder.java#L14
	C# binding: https://github.com/xamarin/monodroid-samples/blob/master/SanityTests/ManagedAdder.cs#L82

> // HOWEVER AM I IMPLEMENTING THE BELOW CODE CORRECTLY????
> // OR AM I WAY OFF TRACK??

You're partially off track. :-)

Your interface methods need to provide the Connector value, and methods don't require DoNotGenerateAcw:

	[Android.Runtime.Register("com/android/vending/licensing/LicenseCheckerCallback", DoNotGenerateAcw = true)]
	public interface ILicenseCheckerCallback : IJavaObject
	{
		[Register("allow", "()V", "GetAllowHandler:Insert.Namespace.Here.ILicenseCheckerCallbackInvoker, AQN")]
		void Allow ();

		[Register("dontAlllow", "()V", "GetDoNotAllowHandler:Insert.Namespace.Here.ILicenseCheckerCallbackInvoker, AQN")]
		void DoNotAllow ();

		[Register("dontAlllow", "()V", "GetApplicationErrorHandler:Insert.Namespace.Here.ILicenseCheckerCallbackInvoker, AQN")]
		void ApplicationError (ApplicationErrorCode errorCode);
	}

"AQN" is the AssemblyQualifiedName for your assembly; see e.g.

	https://github.com/xamarin/monodroid-samples/blob/master/SanityTests/ManagedAdder.cs#L84

Then  you need to bind the ApplicationErrorCode type (it's a class), akin to:

	[Register ("com/android/vending/licensing/LicenseCheckerCallback$ApplicationErrorCode", DoNotGenerateAcw=true)]
	public class ApplicationErrorCode : Java.Lang.Object {
		/* ... */
		// Note: this must provide the (IntPtr, JniHandleOwnership) constructor
	}

Finally you need the interface Invoker, the ILicenseCheckerCallbackInvoker referenced above. The Invoker is responsible for implementing the interface (so that a Managed Callable Wrapper can be created for Java instances of the interface), and for providing the marshaling functions. For an example, see:

	https://github.com/xamarin/monodroid-samples/blob/master/SanityTests/ManagedAdder.cs#L88

	class ILicenseCheckerCallbackInvoker : Java.Lang.Object, ILicenseCheckerCallback {
		// ...

	#region ApplicationError
		IntPtr id_applicationError;
		public void ApplicationError (ApplicationErrorCode errorCode)
		{
			if (id_applicationError == IntPtr.Zero)
				id_applicationError = JNIEnv.GetMethodID(class_ref, "applicationError",
						"(Lcom/android/vending/licensing/LicenseCheckerCallback$ApplicationErrorCode)V");
			JNIEnv.CallVoidMethod(Handle, id_applicationError, new JValue (errorCode));
		}

	#pragma warning disable 0169
		static Delegate cb_applicationError;
		static Delegate GetApplicationErrorHandler ()
		{
			if (cb_applicationError == null)
				cb_applicationError = JNINativeWrapper.CreateDelegate ((Action<IntPtr, IntPtr, IntPtr>) n_ApplicationError);
			return cb_applicationError;
		}

		static void n_ApplicationError (IntPtr jnienv, IntPtr lrefThis, IntPtr n_errorCode)
		{
			ILicenseCheckerCallback __this = Java.Lang.Object.GetObject<ILicenseCheckerCallback>(lrefThis, JniHandleOwnership.DoNotTransfer);
			using (var errorCode = Java.Lang.Object.GetObject<ApplicationErrorCode>(n_errorCode, JniHandleOwnership.DoNotTransfer))
				__this.ApplicationError (errorCode);
		}
	#pragma warning restore 0169
	#endregion
		// ...
	}

Yes, supporting interfaces is ugly.

 - Jon



More information about the Monodroid mailing list