GithubHelp home page GithubHelp logo

suvitruf / unity-android-native Goto Github PK

View Code? Open in Web Editor NEW
19.0 2.0 6.0 94 KB

A Unity plugin to work with Android native sdk

License: MIT License

C# 100.00%
unity3d ccharp android jni wrappers android-jni android-sdk library

unity-android-native's Introduction

Unity wrappers for android classes

This is a Unity plugin to work with some Android native sdk classes.

Introduction

Assume, you want to get your game version name and code. Yes, you will write something like this using AndroidJavaClass and AndroidJavaObject:

public static int GetVersionCode() {
  AndroidJavaClass contextCls = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
  AndroidJavaObject context = contextCls.GetStatic<AndroidJavaObject>("currentActivity"); 
  AndroidJavaObject packageMngr = context.Call<AndroidJavaObject>("getPackageManager");
  string packageName = context.Call<string>("getPackageName");
  AndroidJavaObject packageInfo = packageMngr.Call<AndroidJavaObject>("getPackageInfo", packageName, 0);
  return packageInfo.Get<int>("versionCode");
}

public static string GetVersionName() {
  AndroidJavaClass contextCls = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
  AndroidJavaObject context = contextCls.GetStatic<AndroidJavaObject>("currentActivity"); 
  AndroidJavaObject packageMngr = context.Call<AndroidJavaObject>("getPackageManager");
  string packageName = context.Call<string>("getPackageName");
  AndroidJavaObject packageInfo = packageMngr.Call<AndroidJavaObject>("getPackageInfo", packageName, 0);
  return packageInfo.Get<string>("versionName");
}

This is kinda ugly. I'm crying internally, when I have to work with this classes. So, the idea behind this repo was to create comfy lib to work with native java classes. Example from above with this lib:

var activity = Internal.GetCurrentActivity();
var pm = activity.GetPackageManager();
var pi = pm.GetPackageInfo(activity.GetPackageName(), 0);
int code = pi.VersionCode;
string name = pi.VersionName;

Looks like the code you write when working directly with Java classes. That's it.

Some Theory

There is JavaObject class with some internal methods for JNI access. For example, we want to create C# representation of Java class Intent.

  1. Namespace should be to Java full class name with prefix UnityAndroidNative. So, it will be UnityAndroidNative.Android.Content.
  2. Derive it from our Object class (which derived from JavaObject).
  3. Implement base constructor:
    public Intent(IntPtr obj) : base(obj) {
    }
    Or constructor which takes action:
    public Intent(string action) : base(IntentClassFullName, action) {
    }
    So, now you can instantiate this class:
    Intent intent = new Intent(Intent.ACTION_SEND);
  4. Now we can implement methods using methods of JavaObject. For example, setAction:
    public Intent SetAction(string action) {
        Call<Intent>("setAction", action);
    
        return this;
    }
    You can instantiate Intent with default constructor and set action:
    Intent intent = new Intent();
    intent.SetAction(Intent.ACTION_SEND);
  5. Need method too return field value? Easy:
    public Uri GetData() {
        return Get<Uri>("getData");
    }

Real world example

Assume you want to start sharing Intent and filter app to show. Easy:

  public static void Share(string body, string subject, string mimeType = "text/plain", string chooserTitle = "Choose application") {
      Intent intent = new Intent(Intent.ACTION_SEND);
      intent.SetType(mimeType)
          .PutExtra(Intent.EXTRA_SUBJECT, subject)
          .PutExtra(Intent.EXTRA_TEXT, body);

      var intentList = new List<Intent>();

      var activity = Internal.GetCurrentActivity();
      var pm = activity.GetPackageManager();
      var resInfo = pm.QueryIntentActivities(intent, 0);


      for (int i = 0; i < resInfo.Count; i++) {
          ResolveInfo ri = resInfo[i];
          string packageName = ri.ActivityInfo.GetPackageName();
          if (packageName.Contains("vkontakte")  || packageName.Contains("instagram") || packageName.Contains("skype")) {
              Intent newIntent = new Intent(Intent.ACTION_SEND);
              newIntent.SetPackage(packageName)
                  .PutExtra(Intent.EXTRA_SUBJECT, subject)
                  .PutExtra(Intent.EXTRA_TEXT, body)
                  .SetType(mimeType);

              intentList.Add(newIntent);
          }
      }

      Intent intentt = intentList[0];
      intentList.RemoveAt(0);
      Parcelable[] extraIntents = new Parcelable[intentList.Count];

      for (int i = 0; i < intentList.Count; i++) {
          extraIntents[i] = intentList[i];
      }

      var chooser = Intent.CreateChooser(intentt, chooserTitle);
      chooser.PutExtra(Intent.EXTRA_INITIAL_INTENTS, extraIntents);
      activity.StartActivity(chooser);
  }

P.S.

There are not much you can do with this lib right now. But I'm going add new classes/methods from time to time.

unity-android-native's People

Contributors

suvitruf avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

unity-android-native's Issues

Proxy classes

Need to implement some sort of proxy classes to be able to pass C# callbacks into Java.

  • Basic proxy class.
  • Example. AlertDialog.

Caching fields on C# side

Do we need to cache fields on C# side?

Caching ref fields like PackageInfo https://github.com/Suvitruf/unity-android-native/blob/master/Assets/UnityAndroidNative/Android/Content/Pm/PackageManager.cs#L11 in PackageManager is not the bad idea, 'cause this ref will not be changed.

But what's about primitive types, like mAction field of Intent? It would be a nice to reduce jni calls. But if something changes this field in native object, it will not be automatically changed on C# side.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.