Monogame With Xamarin or Maui (IOS /Android)

Hi @TheKelsam

I just wanted to know if you had success using admob by going through this path Or did you really do something else? I followed what you said but what booque is at the level of admob I have the impression that there is a conflict between the dependencies or missing dependencies, … did you import the dependencies separately? thank you in advance

1 Like

Yes, our newest game is using Admob (Interstitial Ads).

We are using MG 3.8.1.303 targeting .NET 6 with Maui Essentials (i.e. <UseMauiEssentials>true</UseMauiEssentials>)

Dependencies
Android: <PackageReference Include="Xamarin.GooglePlayServices.Ads.Lite" Version="121.2.0" />
iOS: <PackageReference Include="Xamarin.Google.iOS.MobileAds" Version="8.13.0.3" />

2 Likes

Thanks a lot maybe it’s the end of the galleys version 1.9 has just arrived I haven’t tested yet

1 Like

I better understand you don’t use the marcojak library

No, I do not use the marcojak lib.

If you’re going to, and are targeting .NET 6 with Maui Essentials, you’ll need to use this version of it: NuGet Gallery | Plugin.MauiMTAdmob 1.0.1

2 Likes

thank you for your reply
did you manage to do this with marcojak or have you ever tried?

id take a look at the flux in the vault on marojak … it looks super easy that way … The one line of code for both is just what we like. mabye just wait till he fixes it… mabye there will be unmerged pr you can grab as soon as its there… not sure how close you are to deploying…

thanks you both for relentless pursuit of this… when i get around to it i feel like ive got less to consider… now im looking at no less than 20+ new ways to do scripting, windowing XAML, docking and level editing !!! 100s of branches… undo/ redo, copy / paste and WPF and windowing… vaults dead for 9 years getting raised up like Lazarus by MSFT staff!! xamarin willl be there for a long time…no need to hop on full Maui yet its too new…

When i did i got confused by its attempt to unify desktop and mobile and that wont give me linux ( really do linux people ever spend money ,its a tiny lie 3% market, but linux is popular on universities and i target those) and theres usually no adds on desktop, . ( but there are in app purchases on Steam) but if its just going to give you free iives in exchange for suffering a full page video add ( thats will make you try harder not to die ) , ad if they got no money and theres a way to use admob on steam as well.

im even considering a business model like arcade coins… where you DON’T own the game theres no paid version . you have to put coins in… its slighty evil and greedy but in the 80s in arcades thats how it was… almost NOONE owned a game. and it make your heart pound more whne you play you try harder and take is seriously… Then, in the 80s (im so old) if you could play 5 hours on one coin you were respected. you could not buy respect. Nowadays in app stores try get you to buy stuff like stupid NFTs and special colored swords to show off you got money… its pushing on casino gambing and dangerous and illegal pyramid schemees on minors. This shows how creatively spent and desperate for cash the big studios are, and gamers are sick of that already.

in case ur curious my experience witout ads, on my last release on Web… ( i wont try that web stack tech again) i had 30,000 players ,mabye playing for hours per day, for years.( try and die) in Brazil never got a dime from that coutnry or asia, because many dont have accounts, and my creaturs aren not cute wiht big eyes i dont do Cute… you never konw which country especially like your game for some reason. i never made a portuguese version either. Morocco was my #2. they can see ads for stuff you can buy in stores too without paypal or crdit cards. BTW linux is pretty tiny so if you get Maui to work on windows post a sample … i found it confusing so i use the 3.8.1 samples ways… which are confusing enough…! In those you target Windows just to avind the console widow but its not really windows its desktop GL… so i recommend to really watch your demographics if google or apple will show u whos hitting your game… mabye try autotranslate if you have text, or make copy paste possilbe so they can translate instructions or whatever, and french keyboards and spanish , etc… have differnt buttons layouts if you target desktop…

but his instructions to get around the limits are pretty clear…

1 Like

Thanks
I haven’t finished the game yet, I still have things to settle.

Thank you
If I send you my code can you tell me what is wrong?

To fix Com.Google.Ump.FormError.cs issue
I commented that

/*[Register ("com/google/android/ump/FormError$ErrorCode", DoNotGenerateAcw=true)]
		[global::System.Obsolete ("Use the 'Com.Google.Android.Ump.FormError.IErrorCode' type. This class will be removed in a future release.")]
		public abstract class ErrorCode : Java.Lang.Object {
			internal ErrorCode ()
			{
			}

			// Metadata.xml XPath field reference: path="/api/package[@name='com.google.android.ump']/interface[@name='FormError.ErrorCode']/field[@name='INTERNAL_ERROR']"
			[Register ("INTERNAL_ERROR")]
			[Obsolete ("Use 'Com.Google.Android.Ump.FormError.IErrorCode.InternalError'. This class will be removed in a future release.")]
			public const int InternalError = (int) 1;

			// Metadata.xml XPath field reference: path="/api/package[@name='com.google.android.ump']/interface[@name='FormError.ErrorCode']/field[@name='INTERNET_ERROR']"
			[Register ("INTERNET_ERROR")]
			[Obsolete ("Use 'Com.Google.Android.Ump.FormError.IErrorCode.InternetError'. This class will be removed in a future release.")]
			public const int InternetError = (int) 2;

			// Metadata.xml XPath field reference: path="/api/package[@name='com.google.android.ump']/interface[@name='FormError.ErrorCode']/field[@name='INVALID_OPERATION']"
			[Register ("INVALID_OPERATION")]
			[Obsolete ("Use 'Com.Google.Android.Ump.FormError.IErrorCode.InvalidOperation'. This class will be removed in a future release.")]
			public const int InvalidOperation = (int) 3;

			// Metadata.xml XPath field reference: path="/api/package[@name='com.google.android.ump']/interface[@name='FormError.ErrorCode']/field[@name='TIME_OUT']"
			[Register ("TIME_OUT")]
			[Obsolete ("Use 'Com.Google.Android.Ump.FormError.IErrorCode.TimeOut'. This class will be removed in a future release.")]
			public const int TimeOut = (int) 4;

			// The following are fields from: java.lang.annotation.Annotation

			// The following are fields from: Android.Runtime.IJavaObject

			// The following are fields from: System.IDisposable

			// The following are fields from: Java.Interop.IJavaPeerable

		}*/

To solve the problem of

Com.Google.Ump.IConsentInformation.cs

/*
		[Register ("com/google/android/ump/ConsentInformation$ConsentStatus", DoNotGenerateAcw=true)]
		[global::System.Obsolete ("Use the 'Com.Google.Android.Ump.IConsentInformation.IConsentStatus' type. This class will be removed in a future release.")]
		public abstract class ConsentStatus : Java.Lang.Object {
			internal ConsentStatus ()
			{
			}

			// Metadata.xml XPath field reference: path="/api/package[@name='com.google.android.ump']/interface[@name='ConsentInformation.ConsentStatus']/field[@name='NOT_REQUIRED']"
			[Register ("NOT_REQUIRED")]
			[Obsolete ("Use 'Com.Google.Android.Ump.IConsentInformation.IConsentStatus.NotRequired'. This class will be removed in a future release.")]
			public const int NotRequired = (int) 1;

			// Metadata.xml XPath field reference: path="/api/package[@name='com.google.android.ump']/interface[@name='ConsentInformation.ConsentStatus']/field[@name='OBTAINED']"
			[Register ("OBTAINED")]
			[Obsolete ("Use 'Com.Google.Android.Ump.IConsentInformation.IConsentStatus.Obtained'. This class will be removed in a future release.")]
			public const int Obtained = (int) 3;

			// Metadata.xml XPath field reference: path="/api/package[@name='com.google.android.ump']/interface[@name='ConsentInformation.ConsentStatus']/field[@name='REQUIRED']"
			[Register ("REQUIRED")]
			[Obsolete ("Use 'Com.Google.Android.Ump.IConsentInformation.IConsentStatus.Required'. This class will be removed in a future release.")]
			public const int Required = (int) 2;

			// Metadata.xml XPath field reference: path="/api/package[@name='com.google.android.ump']/interface[@name='ConsentInformation.ConsentStatus']/field[@name='UNKNOWN']"
			[Register ("UNKNOWN")]
			[Obsolete ("Use 'Com.Google.Android.Ump.IConsentInformation.IConsentStatus.Unknown'. This class will be removed in a future release.")]
			public const int Unknown = (int) 0;

			// The following are fields from: java.lang.annotation.Annotation

			// The following are fields from: Android.Runtime.IJavaObject

			// The following are fields from: System.IDisposable

			// The following are fields from: Java.Interop.IJavaPeerable

		}*/

To solve the problem of

Com.Google.Android.Ump.ConsentDebugSetting.cs

/*
[Register ("com/google/android/ump/ConsentDebugSettings$DebugGeography", DoNotGenerateAcw=true)]
[global::System.Obsolete ("Use the 'Com.Google.Android.Ump.ConsentDebugSettings.IDebugGeography' type. This class will be removed in a future release.")]
public abstract class DebugGeography: Java.Lang.Object {
internal DebugGeography()
{
}

// Metadata.xml XPath field reference: path="/api/package[@name='com.google.android.ump']/interface[@name='ConsentDebugSettings.DebugGeography']/field[@name='DEBUG_GEOGRAPHY_DISABLED ']"
[Register("DEBUG_GEOGRAPHY_DISABLED")]
[Obsolete ("Use 'Com.Google.Android.Ump.ConsentDebugSettings.IDebugGeography.DebugGeographyDisabled'. This class will be removed in a future release.")]
public const int DebugGeographyDisabled = (int) 0;

// Metadata.xml XPath field reference: path="/api/package[@name='com.google.android.ump']/interface[@name='ConsentDebugSettings.DebugGeography']/field[@name='DEBUG_GEOGRAPHY_EEA ']"
[Register("DEBUG_GEOGRAPHY_EEA")]
[Obsolete ("Use 'Com.Google.Android.Ump.ConsentDebugSettings.IDebugGeography.DebugGeographyEea'. This class will be removed in a future release.")]
public const int DebugGeographyEea = (int) 1;

// Metadata.xml XPath field reference: path="/api/package[@name='com.google.android.ump']/interface[@name='ConsentDebugSettings.DebugGeography']/field[@name='DEBUG_GEOGRAPHY_NOT_EEA ']"
[Register("DEBUG_GEOGRAPHY_NOT_EEA")]
[Obsolete ("Use 'Com.Google.Android.Ump.ConsentDebugSettings.IDebugGeography.DebugGeographyNotEea'. This class will be removed in a future release.")]
public const int DebugGeographyNotEea = (int) 2;

// The following are fields from: java.lang.annotation.Annotation

// The following are fields from: Android.Runtime.IJavaObject

// The following are fields from: System.IDisposable

// The following are fields from: Java.Interop.IJavaPeerable

}*/

In .csproj

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net6.0-android</TargetFramework>
    <SupportedOSPlatformVersion>23</SupportedOSPlatformVersion>
    <OutputType>Exe</OutputType>
   
    <ApplicationVersion>1</ApplicationVersion>
    <ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
  <!--<UseMaui>true</UseMaui>-->
  <UseMauiEssentials>true</UseMauiEssentials>
  </PropertyGroup>
<!--countourner problème Maui-->
 <ItemGroup Condition="'$(TargetFramework)' == 'net6.0-android'">    
    <AndroidLibrary Include="Dependencies\user-messaging-platform-2.0.0.aar" Bind="false" />
  </ItemGroup>

<!---->
  <ItemGroup>
    <PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.1.303" />
    <PackageReference Include="MonoGame.Framework.Android" Version="3.8.1.303" />
    <PackageReference Include="Plugin.MauiMTAdmob" Version="1.0.1" />
  </ItemGroup>
  <ItemGroup>
    <None Remove="Plugin.MauiMTAdmob" />
    <None Remove="MarcTron.Admob" />
    <None Remove="Xamarin.Essentials" />
    <None Remove="Xamarin.Forms" />
    <None Remove="Xamarin.GooglePlayServices.Ads.Lite" />
    <None Remove="Xamarin.AndroidX.Browser" />
    <None Remove="Xamarin.AndroidX.Collection" />
    <None Remove="Xamarin.Google.UserMessagingPlatform" />
  </ItemGroup>
  <Target Name="RestoreDotnetTools" BeforeTargets="Restore">
    <Message Text="Restoring dotnet tools" Importance="High" />
    <Exec Command="dotnet tool restore" />
  </Target>
</Project>

Then I come across this:

/usr/local/share/dotnet/packs/Microsoft.Android.Sdk.Darwin/32.0.476/tools/Xamarin.Android.Common.targets(3,3): Error XALNS7028: System.IO.FileNotFoundException: Could not load assembly 'Microsoft.Maui, Version=1.0.0.0, Culture=neutral, PublicKeyToken='. Perhaps it doesn't exist in the Mono for Android profile?
File name: 'Microsoft.Maui.dll'
   at Java.Interop.Tools.Cecil.DirectoryAssemblyResolver.Resolve(AssemblyNameReference reference, ReaderParameters parameters) in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop.Tools.Cecil /Java.Interop.Tools.Cecil/DirectoryAssemblyResolver.cs:line 246
   at Mono.Cecil.MetadataResolver.Resolve(TypeReference type) in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/external/cecil/Mono.Cecil/MetadataResolver.cs:line 99
   at Java.Interop.Tools.Cecil.TypeDefinitionCache.Resolve(TypeReference typeReference) in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop.Tools.Cecil/Java. Interop.Tools.Cecil/TypeDefinitionCache.cs:line 20
   at Java.Interop.Tools.Cecil.TypeDefinitionRocks.GetTypeAndBaseTypes(TypeDefinition type, IMetadataResolver resolver)+MoveNext() in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop .Tools.Cecil/Java.Interop.Tools.Cecil/TypeDefinitionRocks.cs:line 42
   at Java.Interop.Tools.Cecil.TypeDefinitionRocks.IsSubclassOf(TypeDefinition type, String typeName, IMetadataResolver resolver) in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop. Tools.Cecil/Java.Interop.Tools.Cecil/TypeDefinitionRocks.cs:line 100
   at MonoDroid.Tuner.FixAbstractMethodsStep.FixAbstractMethods(AssemblyDefinition assembly)
   at Xamarin.Android.Tasks.LinkAssembliesNoShrink.RunTask()
   at Microsoft.Android.Build.Tasks.AndroidTask.Execute() in /Users/runner/work/1/s/xamarin-android/external/xamarin-android-tools/src/Microsoft.Android.Build.BaseTasks/AndroidTask. cs:line 22 (XALNS7028) (Android MonoGame)

after when I put in the .csproj true instead of
true problem returns

and I have other error messages in fact I’m stuck in a loop when I fix a problem I generate others I don’t know why it doesn’t want to work

it’s frustrating

except I never give up

To summarize the problem occurs either when I add the marcojak module

either using Xamarin.GooglePlayServices.Ads.Lite

Voici les derniers messages d’erreurs que j’obtiens

Error 1

/usr/local/share/dotnet/packs/Microsoft.Android.Sdk.Darwin/32.0.476/tools/Xamarin.Android.Common.targets(2,2): Error XA0000: Exception non prise en charge : System.IO.IOException: The process cannot access the file ‘…./R.java' because it is being used by another process.
   at Microsoft.Win32.SafeHandles.SafeFileHandle.Init(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Int64& fileLength, UnixFileMode& filePermissions)
   at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, UnixFileMode openPermissions, Int64& fileLength, UnixFileMode& filePermissions, Func`4 createOpenException)
   at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
   at System.IO.File.Create(String path)
   at Microsoft.Android.Build.Tasks.Files.CopyIfStreamChanged(Stream stream, String destination) in /Users/runner/work/1/s/xamarin-android/external/xamarin-android-tools/src/Microsoft.Android.Build.BaseTasks/Files.cs:line 170
   at Xamarin.Android.Tasks.GenerateLibraryResources.GenerateJava(Package package)
   at Microsoft.Android.Build.Tasks.AsyncTaskExtensions.<>c__DisplayClass1_1`1.<WhenAll>b__0() in /Users/runner/work/1/s/xamarin-android/external/xamarin-android-tools/src/Microsoft.Android.Build.BaseTasks/AsyncTaskExtensions.cs:line 28 (XA0000) (AndroidMonoGame)


Error 2

/usr/local/share/dotnet/packs/Microsoft.Android.Sdk.Darwin/32.0.476/tools/Xamarin.Android.Common.targets(2,2): Error XA0000: Exception non prise en charge : System.IO.IOException: The process cannot access the file ‘…./core/R.java' because it is being used by another process.
   at Microsoft.Win32.SafeHandles.SafeFileHandle.Init(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Int64& fileLength, UnixFileMode& filePermissions)
   at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, UnixFileMode openPermissions, Int64& fileLength, UnixFileMode& filePermissions, Func`4 createOpenException)
   at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
   at System.IO.File.Create(String path)
   at Microsoft.Android.Build.Tasks.Files.CopyIfStreamChanged(Stream stream, String destination) in /Users/runner/work/1/s/xamarin-android/external/xamarin-android-tools/src/Microsoft.Android.Build.BaseTasks/Files.cs:line 170
   at Xamarin.Android.Tasks.GenerateLibraryResources.GenerateJava(Package package)
   at Microsoft.Android.Build.Tasks.AsyncTaskExtensions.<>c__DisplayClass1_1`1.<WhenAll>b__0() in /Users/runner/work/1/s/xamarin-android/external/xamarin-android-tools/src/Microsoft.Android.Build.BaseTasks/AsyncTaskExtensions.cs:line 28 (XA0000) (AndroidMonoGame)


Error 3

/usr/local/share/dotnet/packs/Microsoft.Android.Sdk.Darwin/32.0.476/tools/Xamarin.Android.Common.targets(2,2): Error XA0000: Exception non prise en charge : System.IO.IOException: The process cannot access the file ‘…./fragment/R.java' because it is being used by another process.
   at Microsoft.Win32.SafeHandles.SafeFileHandle.Init(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Int64& fileLength, UnixFileMode& filePermissions)
   at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, UnixFileMode openPermissions, Int64& fileLength, UnixFileMode& filePermissions, Func`4 createOpenException)
   at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
   at System.IO.File.Create(String path)
   at Microsoft.Android.Build.Tasks.Files.CopyIfStreamChanged(Stream stream, String destination) in /Users/runner/work/1/s/xamarin-android/external/xamarin-android-tools/src/Microsoft.Android.Build.BaseTasks/Files.cs:line 170
   at Xamarin.Android.Tasks.GenerateLibraryResources.GenerateJava(Package package)
   at Microsoft.Android.Build.Tasks.AsyncTaskExtensions.<>c__DisplayClass1_1`1.<WhenAll>b__0() in /Users/runner/work/1/s/xamarin-android/external/xamarin-android-tools/src/Microsoft.Android.Build.BaseTasks/AsyncTaskExtensions.cs:line 28 (XA0000) (AndroidMonoGame)

Hi,
I hope you are fine
can someone tell me or did i miss something? thank you in advance

Upon trying out MauiMTAdmob again, I don’t think you can use it with just Maui Essentials. Looks like you’d need full Maui. So, if you’re dead set on using the Marctron admob lib, you’ll probably have to use the Xamarin (non-maui) version with MG 3.8.0 and .NET Core 3 instead.

1 Like