Demonstrates how to exchange data from complex Java objects.
This example demonstrates how to move around data from a Java ArrayList of objects over to Qt. The example uses Android APIs to retrieve a list of music tracks, and displays some information about them with QML.
When the application starts, it displays a list of music tracks, showing the track name, artist, and duration.
要运行范例从 Qt Creator ,打开 欢迎 模式,然后选择范例从 范例 。更多信息,拜访 构建和运行范例 .
Let's create a Java class,
MusicTrack
, that defines some of the basic information about a track. In the Java side, create the following:
class MusicTrack {
private String title;
private String artist;
private long duration;
MusicTrack (String title, String artist, long duration) {
this.title = title;
this.artist = artist;
this.duration = duration;
}
public String getTitle() { return title; }
public String getArtist() { return artist; }
public long getDuration() { return duration; }
}
Create another class with the same variables or information on the C++ side. The definition for
MusicTrack
class is the following:
class MusicTrack : public QObject { Q_OBJECT Q_PROPERTY(QString title READ title CONSTANT) Q_PROPERTY(QString artist READ artist CONSTANT) Q_PROPERTY(long duration READ duration CONSTANT) public: MusicTrack(const QString title, const QString artist, const long duration, QObject *parent = nullptr) : QObject(parent), m_title(title), m_artist(artist), m_duration(duration) {} QString title() const { return m_title; } QString artist() const { return m_artist; } long duration() const { return m_duration; } private: QString m_title; QString m_artist; long m_duration; };
注意:
The
MusicTrack
class must be a
QObject
-derived class to be used with as a QML context property. For more information, see
QML and C++ Integration
.
To retrieve the music list, the Android APIs are used. Add the following method to find music tracks that are available on the system. This method returns an ArrayList of
MusicTrack
.
package org.qtproject.example.musiclist;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;
import java.util.ArrayList;
public class MusicList {
static ArrayList<MusicTrack> fetchMusicList(Context context) {
ArrayList<MusicTrack> musicList = new ArrayList<MusicTrack>();
Cursor songCursor;
try {
ContentResolver contentResolver = context.getContentResolver();
Uri songUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
songCursor = contentResolver.query(songUri, null, null, null, null);
} catch (SecurityException e) {
e.printStackTrace();
return musicList;
}
if (songCursor != null && songCursor.moveToFirst())
{
int title = songCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE);
int artist = songCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST);
int duration = duration = songCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION);
do {
String currentTitle = songCursor.getString(title);
String currentArtist = songCursor.getString(artist);
long currentDuration = songCursor.getLong(duration);
musicList.add(new MusicTrack(currentTitle, currentArtist, currentDuration));
} while (songCursor.moveToNext());
}
if (songCursor != null)
songCursor.close();
return musicList;
}
}
Using the JNI helpers provided with Qt, call the previous method to first get an QAndroidJniObject containing an ArrayList of objects. In the C++ code, you need to go through the Java ArrayList and create a parallel list on C++. Add the following lines to do that:
QAndroidJniObject musicList = QAndroidJniObject::callStaticObjectMethod(
"org/qtproject/example/musiclist/MusicList",
"fetchMusicList",
"(Landroid/content/Context;)Ljava/util/ArrayList;",
QtAndroid::androidContext().object());
for (int i = 0; i < musicList.callMethod<jint>("size"); ++i) {
QAndroidJniObject track = musicList.callObjectMethod("get", "(I)Ljava/lang/Object;", i);
const QString title = track.callObjectMethod("getTitle", "()Ljava/lang/String;").toString();
const QString artist = track.callObjectMethod("getArtist", "()Ljava/lang/String;").toString();
const long duration = track.callMethod<jlong>("getDuration");
m_assembledMusicList.append(new MusicTrack(title, artist, duration, this));
}
Then, add a function to return the resulted QList :
QList<MusicTrack *> MusicList::assembledMusicList() const { return m_assembledMusicList; }
To display the music list, create a ListView that uses the QList as a property. Register the property as follows:
MusicList *musicList = new MusicList(&app);
engine.rootContext()->setContextProperty(QLatin1String("musiclist"),
QVariant::fromValue(musicList->assembledMusicList()));
In the QML code, define the model of the ListView 如下:
model: musiclist
另请参阅 Qt for Android and Qt Android Extras .