At the moment I am trying to hook in a dynamically-generated IntentFilter object against a ‘sticky’ or, in some cases, ignorable broadcast. As such, I need to pass in a Null BroadcastReceiver object into the first parameter of Context.registerReceiver. This is the expected usage of the method.
The problem is I can’t determine how to create such a thing.
The AndroidJavaObject binding isn’t intelligent enough to turn a C# null into a Java null of the correct type. So, my bet was to cast the Java null reference to the correct type. The problem with that is that 0xFFFFFFFF is interpreted as a weak reference by the JNI and exhibits an exception.
So, I tried building the correct object via first creating a new AndroidJavaObject of type java.lang.Object, which appears to default to the Java null object reference, then casting it with the java.lang.Class static method fromName. But that generates a null reference exception.
The casting itself is necessary because a java.lang.Object is not of the correct type and the Unity AndroidJavaObject can’t find the correct method to invoke via Call if that’s the case.
Is there no way to pass a null reference to a Java method as a parameter?
I just spent some time trying to figure out the opposite problem, getting a null value from a java object into Unity. Using null doesn’t work, because the object itself is valid. What I did was test the raw object’s integral value for 0 to find out if it was null.
C# code:
AndroidJavaClass cls = new AndroidJavaClass("com.mycompany.myproduct.myclass");
AndroidJavaObject obj = cls.CallStatic<AndroidJavaObject>("getStringArray");
if (obj.GetRawObject().ToInt32() != 0)
{
// String[] returned with some data!
String[] result = AndroidJNIHelper.ConvertFromJNIArray<String[]>(obj.GetRawObject());
foreach (String str in result)
{
// Do something with the strings
}
}
else
{
// null String[] returned
}
obj.Dispose();
cls.Dispose();
java code:
public static String[] getStringArray()
{
String[] strs = { "Test1", "Test2" };
return strs; // Or alternatively, return null;
}
The reason I point this out is that 1) I couldn’t find an example of getting String[ ] from Android through the Unity JNI (and this works), so hopefully someone will stumble on it. and 2) I’ll bet, but I can not promise, that if you sent a JNIObject with it’s Raw Object (i.e. the IntPtr) set to 0, that would be an alternative to sending null to the java function. Unfortunately I don’t need to do that, so I can’t verify right now.
First, are you able to test this in editor or must you move to android device?
Second, I changed the (new AndroidJavaClass(“com.mycompany.myproduct.myclass”) to what it is in my package identifier as well as myclass to IabHelper (trying to implement in-app billing) IabHelper.java is located in Plugins/Android folder.
Does all of the above sound correct or am I missing some step?
@MFen getStringArray was just an example method that would return a string[ ]. In other words, if you have a method that is returning a string[ ], you would use the name of your method in place of getStringArray. You have to test on the device, so you should wrap this in a #if ANDROID (or whatever constant there is for Android, I forget now). If you’re only doing Android, you could also just say if (!Application.isEditor).
You are correct in setting the class name. It should be your fully qualified package name. I should have chosen a better name for the getStringArray method, as that isn’t a real method, but it sounds like one, lol. Sorry.
Oh I see, yes that part is out of date, I get an exception now. I ended up not sending a null but a single string with a unique entry to identify null. Maybe you could put a try/catch block and catch it.
Not specific to JNI, but when calling methods on AndroidJavaObjects in C#, which require passing a null parameter you will need to pass in a null referenced AndroidJavaObject.
Passing a C# null, or IntPtr.Zero both get filtered out before binding with the Java method, which causes an incorrect number of parameters to be passed along to Java, which ultimately results in a method signature mismatch.
Edit: Not to resurrect an old thread. However, when trying to solve this problem for myself this is the thread that kept being the top pick from Google. I figured it was a good enough place to store the solution to my problem in hopes that it helps others.
Have you tested that ? Seems very unlikely that would work to me.
Looking at the code in Unity 5.1 beta 5, the arguments passed to JNI are parsed like this (peeked using MonoDevelop’s decompilation):
As you can see, a null value passed does not have any “type” associated to it at all, so it wouldn’t make any different whether you have a null string or a null AndroidJavaObject.
I also think that at the C# language level, a null reference does not have any type, so again, this shouldn’t make any difference.