- Home /
Returning byte array from Java/Android
I have several functions that make use of AndroidJavaObject.Call() to run Java code in my Unity project.
AndroidJavaObject androidUtility = new AndroidJavaObject("com.my.java.library");
androidUtility.Call("myFunctionA", data1, data2);
androidUtility.Call<bool>("myFunctionB", data1, data2);
androidUtility.Call<byte[]>("myFunctionC", data1, data2);
The functions all get called. The call to myFunctionB returns a boolean. But the call to myFunctionC returns an empty array no matter what I put in the Java code.
Does AndroidJavaObject.Call() not work when returning arrays? Is there some special processing required?
Thanks for your help.
bump! :) Does not work for us either. All we get is a warning and a crash, when we try to get arrays, lists from java code: JNI WARNING: received null array (Check_GetArrayLength)
Answer by supernat · Aug 10, 2013 at 09:00 PM
This seems to be an issue with little knowledge, so I thought I would reply even though this thread is quite old.
The problem is that an array is not a native type, so you can't do what you are trying in the example. Arrays, as far as I can tell, must always be transferred in the form of an Object. The Unity JNIHelper class offers a method (ConvertFromJNIArray()) to change an AndroidJavaObject into a .NET array. The array has to be an array of native types from what I can tell (except string, which isn't native, but it still works). There is also a ConvertToJNIArray that you can use to send an array to the Java side. Hopefully the code below will shed some light on it.
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;
}
Pay special attention to checking for null by using the obj.GetRawObject().ToInt32() method and testing it for 0. obj itself will not be null as it is a valid object, but if you call ConvertFromJNIArray(obj) with the obj's Raw Object value of 0, it will crash.
Answer by tamas · Mar 07, 2012 at 12:14 PM
Also here is an example from the (docs):
// Create a java.lang.String object holding the string "some string",
// and retrieve it's hash code.
function Start() {
var jo = new AndroidJavaObject("java.lang.String", "some string");
var hash = jo.Call.<int>("hashCode");
}
Modified version, to return an array:
function Start() {
var jc = new AndroidJavaClass ("com.test.test");
var doubleArary = jc.Call.<double[]>("getDoubleArray");
}
From logcat:
03-07 11:43:35.143: I/Unity(23708): getMethodID("com.test.test", "getDoubleArray", "()[D", non-static)
03-07 11:43:35.143: I/Unity(23708): FOUND double[] test.getDoubleArray();
03-07 11:43:35.153: W/dalvikvm(23708): JNI WARNING: received null array (Check_GetArrayLength)
The called java method:
public double[] getDoubleArray() {
return new double[] { 1, 2, 3 };
}
Also..help would be appreciated, cause our current workaround, is reading the list items one-by-one, and it's really slow when you have 1000+ items.
Answer by bhavinatmattel · Jul 17, 2018 at 06:45 PM
Using Supernat's answer
1. you can feed bytes to POJO
public class ReadData {
public byte[] Buffer;
public ReadData(byte[] buffer) {
Buffer=buffer;
}
}
2. Call your method in Android (Java) code
callback.DidReceiveDataCallback(new ReadData(data));
3. Render the bytes in Unity
public void DidReceiveDataCallback(AndroidJavaObject bytesObj)
{
Debug.Log("Unity callbacks: Receive Data ");
AndroidJavaObject bufferObject = bytesObj.Get
("Buffer");
byte[] buffer = AndroidJNIHelper.ConvertFromJNIArray
(bufferObject.GetRawObject());
// Do something with bytes
}
Your answer
Follow this Question
Related Questions
AndroidJavaObject.Call fails with 'method not found' 1 Answer
What is the difference between AndroidJavaClass.Call and AndroidJavaObject.Call 2 Answers
Getting native Android String constants via JNI broken in Unity 2019.2.0? 3 Answers
Count every row and column of multidemensional array (c# unity) 1 Answer
JNI Exception using Android Plugin 1 Answer