My unity project uses Google Ad Mob Unity Plugin v6.1.2 which is the latest version.
Target api level is 31.
The game runs fine on devices that run Android 8.0 to 11.0.
Using Unity 2020.3.25f1.
I am running an android emulator through Android Studio that uses a Pixel3a android api level 31 (Android 12) to run my unity game and this is what Logcat spits back at me upon launching the app (Take a look at line 4 & line 5):
2021-12-22 21:42:27.599 9019-9038/? E/AndroidRuntime: FATAL EXCEPTION: pool-3-thread-1
Process: com.Guambo.GooRunner, PID: 9019
java.lang.IllegalArgumentException: com.Guambo.GooRunner: Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.
Strongly consider using FLAG_IMMUTABLE, only use FLAG_MUTABLE if some functionality depends on the PendingIntent being mutable, e.g. if it needs to be used with inline replies or bubbles.
at android.app.PendingIntent.checkFlags(PendingIntent.java:375)
at android.app.PendingIntent.getBroadcastAsUser(PendingIntent.java:645)
at android.app.PendingIntent.getBroadcast(PendingIntent.java:632)
at androidx.work.impl.utils.ForceStopRunnable.a(Unknown Source:5)
at androidx.work.impl.utils.ForceStopRunnable.a(Unknown Source:4)
at androidx.work.impl.utils.ForceStopRunnable.run(Unknown Source:52)
at androidx.work.impl.utils.f$a.run(Unknown Source:2)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:920)
After scouring the web I found this stackoverflow answer and tried to add this WorkManager dependency to the mainTemplate.gradle file in Unity (In Unity, set the following checkbox to true to create a custom main gradle template file called mainTemplate.gradle: ProjectSettings>PlayerSettings>PublishingSettings>Build>Custom Main Gradle Template).
However, even after adding this dependency to the projects gradle file, I still encounter the error above.
So I am thinking that somewhere through the use of the Google Mobile Ads Unity Plugin, they are creating an object of type PendingIntent and not specifing FLAG_IMMUTABLE or FLAG_MUTABLE.
The type of Ad that I am running is a rewarded ad. Here is all Google Mobile Ad related code in my unity project:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using GoogleMobileAds.Api;
using System;
// https://developers.google.com/admob/unity/quick-start
// Rewarded Ads - https://developers.google.com/admob/unity/rewarded
// Sample Impl - https://github.com/googleads/googleads-mobile-unity/blob/master/samples/HelloWorld/Assets/Scripts/GoogleAdMobController.cs
public class GoogleAdsController : MonoBehaviour
{
private RewardedAd rewardedAd;
public UnityEvent OnAdLoadedEvent;
public UnityEvent OnAdFailedToLoadEvent;
public UnityEvent OnUserEarnedRewardEvent;
public UnityEvent OnAdClosedEvent;
void Start()
{
// Make sure to set ads to be kid friendly
RequestConfiguration requestConfiguration =
new RequestConfiguration.Builder()
.SetTagForChildDirectedTreatment(TagForChildDirectedTreatment.True)
.SetMaxAdContentRating(MaxAdContentRating.G)
.build();
MobileAds.SetRequestConfiguration(requestConfiguration);
// Initialize the Google Mobile Ads SDK
MobileAds.Initialize(initStatus => { });
// Load an Ad
rewardedAd = RequestAndLoadRewardedAd();
}
// Load an rewarded Ad
public RewardedAd RequestAndLoadRewardedAd()
{
// The following adUnitId is a test ad, in my actual game build I am using a valid adUnitId
// I just changed it for the unity forum post
string adUnitId = "ca-app-pub-3940256099942544/5224354917";
// Create new rewarded ad instance
RewardedAd rewardedAd = new RewardedAd(adUnitId);
// Add Event Handlers (https://docs.unity3d.com/ScriptReference/Events.UnityEvent.html)
rewardedAd.OnAdLoaded += (sender, args) => OnAdLoadedEvent.Invoke();
rewardedAd.OnAdFailedToLoad += (sender, args) => OnAdFailedToLoadEvent.Invoke();
rewardedAd.OnUserEarnedReward += (sender, args) => OnUserEarnedRewardEvent.Invoke();
rewardedAd.OnAdClosed += (sender, args) => OnAdClosedEvent.Invoke();
// Create empty ad request
rewardedAd.LoadAd(CreateAdRequest());
// Return rewarded ad
return rewardedAd;
}
// Show the rewarded Ad
public void ShowRewardedAd()
{
if (rewardedAd != null)
{
if (rewardedAd.IsLoaded())
rewardedAd.Show();
}
}
private AdRequest CreateAdRequest()
{
return new AdRequest.Builder()
.AddExtra("max_ad_content_rating", "G")
.AddExtra("is_designed_for_families", "true")
.Build();
}
// On Closed
public void OnAdClosed()
{
// Debug.Log("Loading new ad");
// Load up a new ad
rewardedAd = RequestAndLoadRewardedAd();
}
}
I am not running any other plugins, I am not making a notification calls. So I have no idea where else a PendingIntent could be made other than through the Google Mobile Ads internal code.