Skip to content

Commit 431fb29

Browse files
committed
Implement very basic media library rescanning for Android
1 parent 4cd013d commit 431fb29

File tree

5 files changed

+44
-0
lines changed

5 files changed

+44
-0
lines changed

README.md

+3
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,9 @@ additional remarks:
373373
also be changed later (in contrast to IDs).
374374
* If you have already another Syncthing app installed or you have an existing configuration from
375375
another device, read the next sections for testing/migrating.
376+
* The app does not automatically trigger media library rescans yet, so e.g. synchronized music
377+
might not show up immediately in your music app. However, you can trigger a rescan manually if
378+
needed. You can do this per folder from the context menu on the folders page.
376379

377380
### Testing the app without migrating
378381
To only test the app without migrating your setup you can follow the steps of this section. Note

tray/android/src/io/github/martchus/syncthingtray/Activity.java

+11
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import android.content.ActivityNotFoundException;
44
import android.content.Intent;
5+
import android.media.MediaScannerConnection;
56
import android.os.Build;
67
import android.os.Bundle;
78
import android.provider.DocumentsContract;
@@ -69,6 +70,16 @@ public boolean openPath(String path) {
6970
return true;
7071
}
7172

73+
public boolean scanPath(String path) {
74+
MediaScannerConnection.scanFile(this, new String[]{path}, null, new MediaScannerConnection.OnScanCompletedListener() {
75+
public void onScanCompleted(String path, Uri uri) {
76+
showToast("Rescan of " + path + " completed");
77+
}
78+
});
79+
showToast("Triggered rescan of " + path);
80+
return true;
81+
}
82+
7283
public String resolveUri(String uri) {
7384
return Util.getAbsolutePathFromStorageAccessFrameworkUri(this, Uri.parse(uri));
7485
}

tray/gui/qml/DirDelegate.qml

+6
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@ ExpandableDelegate {
6060
text: qsTr("Advanced config")
6161
icon.source: App.faUrlBase + "cogs"
6262
onTriggered: (source) => mainView.stackView.push("AdvancedDirConfigPage.qml", {dirName: modelData.name, dirId: modelData.dirId, stackView: mainView.stackView}, StackView.PushTransition)
63+
},
64+
Action {
65+
text: qsTr("Trigger media rescan")
66+
icon.source: App.faUrlBase + "music"
67+
enabled: App.scanSupported
68+
onTriggered: (source) => App.scanPath(modelData.path)
6369
}
6470
]
6571
}

tray/gui/quick/app.cpp

+14
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,20 @@ bool App::openPath(const QString &dirId, const QString &relativePath)
339339
return false;
340340
}
341341

342+
bool App::scanPath(const QString &path)
343+
{
344+
#ifdef Q_OS_ANDROID
345+
if (QJniObject(QNativeInterface::QAndroidApplication::context())
346+
.callMethod<jboolean>("scanPath", "(Ljava/lang/String;)Z", QJniObject::fromString(path))) {
347+
return true;
348+
}
349+
#else
350+
Q_UNUSED(path)
351+
#endif
352+
emit error(tr("Scanning is not supported."));
353+
return false;
354+
}
355+
342356
bool App::copyText(const QString &text)
343357
{
344358
if (auto *const clipboard = QGuiApplication::clipboard()) {

tray/gui/quick/app.h

+10
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ class App : public QObject {
6767
Q_PROPERTY(QString statusText READ statusText NOTIFY statusInfoChanged)
6868
Q_PROPERTY(QIcon statusIcon READ statusIcon NOTIFY statusInfoChanged)
6969
Q_PROPERTY(QString additionalStatusText READ additionalStatusText NOTIFY statusInfoChanged)
70+
Q_PROPERTY(bool scanSupported READ isScanSupported CONSTANT)
7071
QML_ELEMENT
7172
QML_SINGLETON
7273

@@ -187,6 +188,14 @@ class App : public QObject {
187188
{
188189
return m_statusInfo.additionalStatusText();
189190
}
191+
bool isScanSupported() const
192+
{
193+
#ifdef Q_OS_ANDROID
194+
return true;
195+
#else
196+
return false;
197+
#endif
198+
}
190199

191200
// helper functions invoked from QML
192201
Q_INVOKABLE bool loadMain();
@@ -204,6 +213,7 @@ class App : public QObject {
204213
Q_INVOKABLE bool exportSettings(const QUrl &url, const QJSValue &callback = QJSValue());
205214
Q_INVOKABLE bool openPath(const QString &path);
206215
Q_INVOKABLE bool openPath(const QString &dirId, const QString &relativePath);
216+
Q_INVOKABLE bool scanPath(const QString &path);
207217
Q_INVOKABLE bool copyText(const QString &text);
208218
Q_INVOKABLE bool copyPath(const QString &dirId, const QString &relativePath);
209219
Q_INVOKABLE QString getClipboardText() const;

0 commit comments

Comments
 (0)