Разработка плагина Android для Unity3D

В процессе создания игрового приложения в Unity3d мы столкнулись с проблемой, когда возникла необходимость узнать какое ПО установлено на Android-устройстве клиента.

Мы не собираем конфиденциальную личную информацию о наших клиентах. Эта необходимость возникла по причине того, что заказчик решил давать некоторые бонусы клиентам только в случае, если у клиентов установлено еще какое-либо ПО заказчика.

В сухом остатке нам потребовалось в Unity получить признак: установлено ли ПО заказчика на данном мобильном устройстве или нет.

Версия Unity использовалась самая последняя, версия Android SDK также.

Поскольку требование было только для ОС Android решено было в unity3d добавить плагин, написанный для Android под java. Тут мы столкнулись с рядом проблем, зная решение которых мы бы сэкономили кучу времени.

 

Начало. Код плагина и его использование в unity3d.

Код был прост. Его было нужно только использовать в коде скрипта C# в unity3d:

public class SomeAppTools
{
   public static boolean isSomeAppUnlockable(Context context)
   {
       List packages = context.getPackageManager().getInstalledPackages(0);
       for(PackageInfo pi : packages) // в цикле по всем приложениям пользователя
       {
           if (pi.packageName.equalsIgnoreCase("com.SomeApp.SomeApp2015")
              || pi.packageName.equalsIgnoreCase("com.SomeApp.SomeApp2016")
          {
               return true; // искомое приложение найдено
           }
       }
       return false;
   }
}

Также мы понимали, что вызов данного кода из плагина должен быть обрамлен в скрипте Unity3d на c#  условной компиляцией. Это необходимо для того, чтоб данная часть кода попадала только в дистрибутив приложения для ОС Android:

#if UNITY_ANDROID && !UNITY_EDITOR
...
bool b = isSomeAppUnlockable(...)
...
#endif

Компиляция при помощи javac

Сперва было принято решение “в лоб”. Готовый java-скрипт SomeAppTools.java с одной единственной функцией в одном единственном классе сперва компилировался в байт-код SomeAppTools.class, затем создавался пакет SomeAppTools.jar.

Полученный пакет подбрасывался в папку Assets\Plugins\Android\. Согласно замыслу разработчиков unity при компиляции Android-приложения все пакеты jar в этой папке включаются в полученный дистрибутив.

У нас не получилось собрать apk-дистрибутив игры. При сборке дистрибутива возникала ошибка, побороть которую мы не смогли. Мы пробовали также упоминать наш пакет в файлах манифеста. Тоже не помогало.

При компиляции дистрибутива студия Unity3d в папку Temp/Staging собирает все для этого необходимое. Анализируя содержимое данной папки можно сделать выводы о наличии / отсутствии нужных библиотек и элементов файла манифеста.

Мы не побороли ошибку не потому что мы такие ленивые, а потому что решили попробовать способ, которым все рекомендовали собирать плагины для Unity3d.

 

Cтудия для java-разработчиков Eclipse

Более правильным способом оказалось использовать студию для java-разработчиков Eclipse. Здесь обошлось без приключений. Собранный jar с первого раза добавился в apk-архив игры. Без всяких изменений манифеста.

Почему jar, собранный из командной строки, не стал работать мы не знаем. Конечно можно было бы поразбираться. Но мы - программисты, которые ставят во главу - результат и затраченное время. Результат был достигнут. Время не захотелось тратить.

 

Вызов функции Android из unity3d. Передача context из unity3d в функцию android.

Для вызова родной Android-функции необходимо было получить объект AndroidJavaObject, представляющий пакет, в котором реализован класс. Затем получить объект AndroidJavaClass, который представляет класс, реализующий саму эту функцию.

Поскольку функция - статическая, то вызов ее осуществлялся с помощью CallStatic().

В качестве параметра функции необходимо было передать контекст устройства. Программисты Android должны знать что это такое.

В качестве контекста Unity предлагает нам передать activity. Activity является статическим данным некоего класса com.unity3d.player.UnityPlayer:

 

public static bool _isSomeAppUnlock()
{
  #if UNITY_ANDROID && !UNITY_EDITOR
  using (var actClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
  {
    AndroidJavaObject playerActivityContext = actClass.GetStatic("currentActivity");
    bool ret;
    using(AndroidJavaClass jniSomeAppClass = new AndroidJavaClass("com.southmedia.SomeApp.SomeAppUnlock"))
    {
      ret = jniSomeAppClass.CallStatic("isSomeAppUnlockable", playerActivityContext);
    }
    return ret;
  }
  #endif
  return false; //!!
}

Contact us

Email: Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра.
Skype: south-media.com
Phone: +7 903 4057009, +7 928 1260550
Top
Локальный сервер Денвер.
Установка Joomla на локальный сервер.