Search code examples
c#androidunity-game-engineandroid-activityfirebase-cloud-messaging

How can I get the current activity while using Firebase Cloud Messaging in Unity?


To get the current activity in Unity without Firebase Cloud Messaging, the following code works:

var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
var activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");

However, Firebase Cloud Messaging extends the default Unity Activity. So I changed my AndroidJavaClass as such:

var unityPlayer = new AndroidJavaClass("com.google.firebase.MessagingUnityPlayerActivity");
var activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");

However, I now get the following error in my logcat:

08-01 15:51:31.838 20323 20375 E Unity   : AndroidJavaException: java.lang.NoSuchFieldError: no "Ljava/lang/Object;" field "currentActivity" in class "Lcom/google/firebase/MessagingUnityPlayerActivity;" or its superclasses
08-01 15:51:31.838 20323 20375 E Unity   : java.lang.NoSuchFieldError: no "Ljava/lang/Object;" field "currentActivity" in class "Lcom/google/firebase/MessagingUnityPlayerActivity;" or its superclasses
08-01 15:51:31.838 20323 20375 E Unity   :      at com.unity3d.player.UnityPlayer.nativeRender(Native Method)
08-01 15:51:31.838 20323 20375 E Unity   :      at com.unity3d.player.UnityPlayer.access$300(Unknown Source:0)
08-01 15:51:31.838 20323 20375 E Unity   :      at com.unity3d.player.UnityPlayer$e$1.handleMessage(Unknown Source:83)
08-01 15:51:31.838 20323 20375 E Unity   :      at android.os.Handler.dispatchMessage(Handler.java:103)
08-01 15:51:31.838 20323 20375 E Unity   :      at android.os.Looper.loop(Looper.java:214)
08-01 15:51:31.838 20323 20375 E Unity   :      at com.unity3d.player.UnityPlayer$e.run(Unknown Source:20)
08-01 15:51:31.838 20323 20375 E Unity   :   at UnityEngine.AndroidJNISafe.CheckException () [0x00000] in <00000000000000000000000000000000>:0
08-01 15:51:31.838 20323 20375 E Unity   :   at UnityEngine.AndroidJNISafe.GetStaticFieldID (System.IntPtr clazz, System.String name, System.String sig) [0x00000] in <00000000000000000000000000000000>:0
08-01 15:51:31.838 20323 20375 E Unity   :   at UnityEngine._AndroidJNIHelper.GetFieldID (System.IntPtr jc

I do not understand why. It says that currentActivity does not even exist in the superclass, but if I understand Firebase Cloud Messaging correctly, then it should still exist in the super class. I have also tried replacing currentActivity with things such as UnityPlayerActivity, MessagingUnityPlayerActivity, mypackage, and com.mypackage - but same error. Referencing com.unity3d.player.UnityPlayer in my AndroidJavaClass while using Firebase Cloud Messaging has problems of its own: https://gamedev.stackexchange.com/questions/183734/how-can-i-use-an-inherited-activity-in-c

In case it is relevant, here is my AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.mypackage" android:versionCode="1" android:versionName="1.0">
  <application android:label="@string/app_name" android:icon="@drawable/app_icon">
    <!-- The MessagingUnityPlayerActivity is a class that extends
         UnityPlayerActivity to work around a known issue when receiving
         notification data payloads in the background. -->
    <meta-data
            android:name="com.google.firebase.messaging.default_notification_icon"
            android:resource="@drawable/notification_icon" />
    <activity android:name="com.google.firebase.MessagingUnityPlayerActivity" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
      <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
    </activity>
    <service android:name="com.google.firebase.messaging.MessageForwardingService" android:exported="false" />
  </application>
</manifest>

How can I get my current activity while using Firebase Cloud Messaging? Why does the code not work as shown?


Solution

  • This should behave as expected if you change the class back to "com.unity3d.player.UnityPlayer".

    The issue is that static methods behave a little differently in Java than standard methods. If you see the Java documentation for the JNI.

    The method ID must be derived from clazz, not from one of its superclasses.

    Note that this would be contrary to what you may infer from the standard Java documentation (ex: Are static methods inherited in Java?).