Hello,
I am trying to get a list of audio track info from an Android device. On the Java side, this is accomplished with a static getMusic() method, which returns List<AudioTrack>. getMusic() lives in my custom AndroidDeviceMediaCollection class. AudioTrack is essentially a struct of various fields, with a toString() method. I am able to instantiate each AudioTrack that I expect to find, print it out in Java using toString(), and then add it to the list. But I am running into problems on the C++ side. In particular, it seems that I am not able to convert the returned List<AudioTrack>, which is held in a QAndroidJniObject, to a jobjectArray without destroying most of its contents! Here is the relevant C++ code:
GenericModel<Album>* AndroidDeviceMediaCollection::albumsModel() {
QPlatformNativeInterface
*interface
= QApplication::platformNativeInterface();
jobject activity = (jobject) interface->nativeResourceForIntegration("QtActivity");
QAndroidJniObject music = QAndroidJniObject::callStaticObjectMethod("org.qtproject.mythings.AndroidDeviceMediaCollection", "getMusic", "(Landroid/content/Context;)Ljava/util/List;", activity);
Q_ASSERT_X(music.isValid(), "albumsModel", "Null QAndroidJniObject!");
jobjectArray musicArray = music.object<jobjectArray>();
QAndroidJniEnvironment qjniEnv;
const int n = qjniEnv->GetArrayLength(musicArray);
qDebug() << "Got jobjectArray of length:" << n; // prints expected value
for (int i = 0; i < n; ++i) {
jobject jAudioTrack = qjniEnv->GetObjectArrayElement(musicArray, i);
if (jAudioTrack) {
// parse, add to albums...
qjniEnv->DeleteLocalRef(jAudioTrack);
}
else
qDebug() << "Got null jAudioTrack at index:" << i; // most elements are null!
}
return &m_albums;
}
GenericModel<Album>* AndroidDeviceMediaCollection::albumsModel() {
QPlatformNativeInterface *interface = QApplication::platformNativeInterface();
jobject activity = (jobject) interface->nativeResourceForIntegration("QtActivity");
QAndroidJniObject music = QAndroidJniObject::callStaticObjectMethod("org.qtproject.mythings.AndroidDeviceMediaCollection", "getMusic", "(Landroid/content/Context;)Ljava/util/List;", activity);
Q_ASSERT_X(music.isValid(), "albumsModel", "Null QAndroidJniObject!");
jobjectArray musicArray = music.object<jobjectArray>();
QAndroidJniEnvironment qjniEnv;
const int n = qjniEnv->GetArrayLength(musicArray);
qDebug() << "Got jobjectArray of length:" << n; // prints expected value
for (int i = 0; i < n; ++i) {
jobject jAudioTrack = qjniEnv->GetObjectArrayElement(musicArray, i);
if (jAudioTrack) {
// parse, add to albums...
qjniEnv->DeleteLocalRef(jAudioTrack);
}
else
qDebug() << "Got null jAudioTrack at index:" << i; // most elements are null!
}
return &m_albums;
}
To copy to clipboard, switch view to plain text mode
To be clear, I am successfully converting to a jobjectArray with exactly the right number of elements, but for most of those elements I see the null debug message.
I was just wondering if someone could point out what I am doing wrong here, or if there is a different way to acquire and iterate over a list of instances of a custom type. Any insight appreciated. Thank you!
Bookmarks