Проблемы при попытке вызова C# метода из Java плагина

У меня есть рабочее android-приложение, которое получает входящие уведомления и выводит их на экран с помощью текста... Я взял фрагмент кода и сделал плагин для Unity. Изначально я пытался вызывать метод который должен срабатывать при получении нового уведомления из C#, но позже по рекомендациям одного человека из данного сообщества я попытался вызвать C# метод из моего Java-класса, и передать ему 2 переменные, в которых и содержатся фрагменты входящего уведомления:

public class ReceiveIncomingNotificationsAndPassThemToMyUnityAppClass extends NotificationListenerService {
    private final String UnityCallbackObject = "ReceiveIncomingNotifications";
    private final String UnityCallbackMethod = "Receive";
    Context context;
    public String title;
    public String text;


    @Override

    public void onNotificationPosted(StatusBarNotification sbn) {
        String pack = sbn.getPackageName();
        String ticker ="";
        if(sbn.getNotification().tickerText !=null) {
            ticker = sbn.getNotification().tickerText.toString();
        }
        Bundle extras = sbn.getNotification().extras;
        title = extras.getString("android.title");
        text = extras.getCharSequence("android.text").toString();
        int id1 = extras.getInt(Notification.EXTRA_SMALL_ICON);
        Bitmap id = sbn.getNotification().largeIcon;

        if(id != null) {
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            id.compress(Bitmap.CompressFormat.PNG, 100, stream);
            byte[] byteArray = stream.toByteArray();

        }
        UnityPlayer.UnitySendMessage(UnityCallbackObject, UnityCallbackMethod, title);
        UnityPlayer.UnitySendMessage(UnityCallbackObject, UnityCallbackMethod, text);


    }
}

Соответственно мой c# код выглядел так:

   public void Receive(string title, string text)
    {
    //   var plugin = new AndroidJavaClass("com.alexcompany.receiveincomingnotificationsandpassthemtomyunityapp.ReceiveIncomingNotificationsAndPassThemToMyUnityAppClass");

        Title = title;
        Text = text;
       //     Title = plugin.Get<string>("title");
        //    Text = plugin.Get<string>("text");
            TextForTitle.text = Title;
            TextForBody.text = Text;
        
    }
}

При этой реализации я не получал никаких ошибок в logcat, но и при получении нового уведомления в моем Unity приложении мой текст оставался пустым...

Дальше я решил сделать как тут: https://stackoverflow.com/questions/32944478/callback-listener-in-unity-how-to-call-script-file-method-from-unityplayeracti/41018028#41018028 и вот как стал выглядеть мой Java-class:

public class ReceiveIncomingNotificationsAndPassThemToMyUnityAppClass extends NotificationListenerService {

    Context context;
    public String title;
    public String text;




    public void onNotificationPosted(StatusBarNotification sbn, PluginCallback callback) {
        String pack = sbn.getPackageName();
        String ticker ="";
        if(sbn.getNotification().tickerText !=null) {
            ticker = sbn.getNotification().tickerText.toString();
        }
        Bundle extras = sbn.getNotification().extras;
        title = extras.getString("android.title");
        text = extras.getCharSequence("android.text").toString();
        int id1 = extras.getInt(Notification.EXTRA_SMALL_ICON);
        Bitmap id = sbn.getNotification().largeIcon;

        if(id != null) {
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            id.compress(Bitmap.CompressFormat.PNG, 100, stream);
            byte[] byteArray = stream.toByteArray();

        }
  
        callback.Receive(title, text);


    }
}

так же был добавлен Java interface:

public interface PluginCallback {
    public void Receive(String title, String text);
    
}

и теперь вот как стал выглядеть мой C# код:

public class AndroidPluginCallback : AndroidJavaProxy
{

    public AndroidPluginCallback() : base("com.alexcompany.receiveandpassnotificationsyomyunityapplibrary.PluginCallback") { }
    public string Title;
    public string Text;
    public TextMeshPro TextForTitle;
    public TextMeshPro TextForBody;

    public void Receive(string title, string text)
    {

       TextForTitle = GameObject.Find("TextForTitle").GetComponent<TextMeshPro>();
        TextForBody = GameObject.Find("TextForBody").GetComponent<TextMeshPro>();
        Title = title;
        Text = text;
        TextForTitle.text = Title;
        TextForBody.text = Text;
    }
}

И еще один C# код:

public class ReceiveIncomingNotificationsFromJavaClass : MonoBehaviour
{

   
    public void Start()
    {
        AndroidJavaObject pluginClass = new AndroidJavaObject("com.alexcompany.receiveandpassnotificationsyomyunityapplibrary.ReceiveIncomingNotificationsAndPassThemToMyUnityAppClass");
        pluginClass.Call("onNotificationPosted", new AndroidPluginCallback());
    }
 
}

и за одно Android Mainfest из моего плагина сюда:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.alexcompany.receiveandpassnotificationsyomyunityapplibrary">
    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    <uses-permission android:name="android.permission.READ_SMS" />
    <application>
        <service
            android:name="com.alexcompany.receiveandpassnotificationsyomyunityapplibrary.ReceiveIncomingNotificationsAndPassThemToMyUnityAppClass"

            android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">

            <intent-filter>

                <action android:name="android.service.notification.NotificationListenerService" />

            </intent-filter>

        </service>

    </application>

</manifest>

При этой реализации я не получал никаких ошибок в logcat, но и при получении нового уведомления в моем Unity приложении мой текст оставался пустым... В чем ошибка?


Ответы (1 шт):

Автор решения: woesss

Первый вариант:

UnityPlayer.UnitySendMessage(UnityCallbackObject, UnityCallbackMethod, title);

здесь вы пытаетесь вызвать метод Receive, передав ему один параметр title, но сам метод объявили с двумя параметрами - куда уходит вызов неизвестно, но точно не в ваш метод.

Второй вариант: то же, только в обратном направлении: onNotificationPosted у вас с двумя параметрами, а вызвать пытаетесь с одним. Плюс вы изменили сигнатуру метода и система его не вызовет никогда - вы вообще не должны вызывать его сами. Вместо этого можно объявить колбек статическим полем сервиса, из шарпа передать его экземпляр этому полю, на java проверить валидность и вызвать. Что-то вроде:

public class ReceiveIncomingNotificationsAndPassThemToMyUnityAppClass extends NotificationListenerService {

    private static PluginCallback callback;

    @Override
    public void onNotificationPosted(StatusBarNotification sbn) {
        if (callback != null) {
            Bundle extras = sbn.getNotification().extras;
            String title = extras.getString("android.title");
            String text = extras.getCharSequence("android.text").toString();
            callback.Receive(title, text);
        }
    }

    public static void setCallback(PluginCallback c) {
        callback = c;
    }
}
public class ReceiveIncomingNotificationsFromJavaClass : MonoBehaviour
{
    public void Start()
    {
        AndroidJavaClass serviceClass = new AndroidJavaClass("com.alexcompany.receiveandpassnotificationsyomyunityapplibrary.ReceiveIncomingNotificationsAndPassThemToMyUnityAppClass");
        serviceClass.CallStatic("setCallback", new AndroidPluginCallback());
    }
}

P.S. с c# и юнитами знаком очень поверхностно - скорее всего код не совсем корректный и есть более правильное решение.

→ Ссылка