Skip to content
This repository was archived by the owner on Mar 4, 2023. It is now read-only.

Commit dda366b

Browse files
committed
added android class docs
1 parent e3c3dd5 commit dda366b

File tree

9 files changed

+312
-8
lines changed

9 files changed

+312
-8
lines changed

doc/androidbackgroundservice.dox

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
/*!
2+
@class QtDataSync::AndroidBackgroundService
3+
4+
This service can be used as Android service to create a background synchronizations service
5+
without much effort. However, a few additional setup steps are needed. This class only extends
6+
the QtService implementation of an android service to add the synchronization aspect.
7+
8+
@warning This class alone is **not** sufficient to make synchronization possible. Have a look at
9+
the @ref android_sync_guide to learn how to add background synchronization to your project.
10+
11+
@sa AndroidSyncControl, QtService::Service, @ref qtservice_backends_android
12+
*/
13+
14+
/*!
15+
@property QtDataSync::AndroidBackgroundService::waitFullSync
16+
17+
@default{`true`}
18+
19+
If set to true, the serivce will internally call SyncManager::runOnSynchronized() with the
20+
onSyncCompleted() as handler. If disable, SyncManager::runOnDownloaded() is used instead. Check
21+
the documentation of these two methods.
22+
23+
@accessors{
24+
@readAc{waitFullSync()}
25+
@writeAc{setWaitFullSync()}
26+
@notifyAc{waitFullSyncChanged()}
27+
}
28+
29+
@sa AndroidBackgroundService::onSyncCompleted, SyncManager::runOnSynchronized,
30+
SyncManager::runOnDownloaded
31+
*/
32+
33+
/*!
34+
@fn QtDataSync::AndroidBackgroundService::setupName
35+
36+
@returns The name of the setup
37+
38+
The default implementation returns `QtDataSync::DefaultSetup`. You can override the method if you
39+
need the service to create the setup under a different name.
40+
41+
@sa QtDataSync::DefaultSetup, AndroidBackgroundService::prepareSetup
42+
*/
43+
44+
/*!
45+
@fn QtDataSync::AndroidBackgroundService::prepareSetup
46+
47+
@param setup The setup to be prepared
48+
49+
You should override this method to configure the setup before creation (i.e. set properties on it).
50+
The default implementation does nothing.
51+
52+
@sa QtDataSync::Setup, AndroidBackgroundService::setupName
53+
*/
54+
55+
/*!
56+
@fn QtDataSync::AndroidBackgroundService::onSyncCompleted
57+
58+
@param state The state in which the synchronization finished
59+
60+
This method is called as soon as the datasync instance has finished the data synchronization. You
61+
can override it to perform additional operations with the data before quitting the service.
62+
63+
The default implementation only calls exitAfterSync() to quit the service gracefully. You must
64+
do the same in your implementation. You do not have to call it from within the method, but must
65+
call it eventually. Otherwise it will keep running indefinitely
66+
67+
Possible states can be:
68+
- Uploading (only if waitFullSync is set to false)
69+
- Synchronized
70+
- Error
71+
- Disconnected
72+
73+
@sa AndroidBackgroundService::waitFullSync, AndroidBackgroundService::exitAfterSync
74+
*/
75+
76+
/*!
77+
@fn QtDataSync::AndroidBackgroundService::exitAfterSync
78+
79+
Call this method if you reimplement onSyncCompleted(). It will quit the service gracefully,
80+
honoring the order of start commands, if multiple have been used. Internally, this method calls
81+
stopSelf() with the most recently used startId of a BackgroundSyncAction.
82+
83+
@sa AndroidBackgroundService::onSyncCompleted, AndroidBackgroundService::stopSelf,
84+
AndroidBackgroundService::BackgroundSyncAction
85+
*/
86+
87+
/*!
88+
@fn QtDataSync::AndroidBackgroundService::onStartCommand
89+
90+
@param intent The intent that was used to start the service
91+
@param flags The flags that were used to start the service
92+
@param startId The id of this start request
93+
@returns A value allowed by android to indicate the servies state
94+
95+
This method is registered within QtService via QtService::Service::addCallback. Check
96+
@ref qtservice_backends_android documentation for details on the method itself. Its bascially just
97+
a forwarding of the Android Service method.
98+
99+
Only implement this if you need to do custom stuff here. You should always call this base
100+
implementation in your overload, as this method internally handles the synchronization intents.
101+
102+
@attention This method is called synchronously on the android thread. This means you should not
103+
interact with service class at all. Only use queued invokes to schedule things to be done on
104+
the actual main thread.
105+
106+
@sa @ref qtservice_backends_android, QtService::Service::addCallback,
107+
AndroidBackgroundService::stopSelf,
108+
[android.app.Service.onStartCommand](https://developer.android.com/reference/android/app/Service.html#onStartCommand(android.content.Intent,%20int,%20int))
109+
*/
110+
111+
/*!
112+
@fn QtDataSync::AndroidBackgroundService::createForegroundNotification
113+
114+
@returns An Android
115+
[Notification](https://developer.android.com/reference/android/app/Notification) object, ready to
116+
be presented as foreground notification
117+
118+
You must implement this method to create a working service, as since Android 8, all services that
119+
want to run must show a foreground notification while running in order to not be killed by the
120+
system. A basic sample could be the following.
121+
122+
The code to create the notification was first written in java:
123+
@snippet SvcHelper.java create_notification
124+
And that method is then simply called from the implementation:
125+
@snippet syncservice.cpp jni_create_notification
126+
127+
@sa [android.app.Notification](https://developer.android.com/reference/android/app/Notification)
128+
*/
129+
130+
/*!
131+
@fn QtDataSync::AndroidBackgroundService::stopSelf
132+
133+
@param startId The id of the start command that was finished and thus is beeing stopped
134+
@returns true if the service stop was accepted, false if not
135+
136+
Internally this method simply calls stopSelfResult on the android service. You can reimplement
137+
it if you want to customize how to quit the service.
138+
139+
@sa AndroidBackgroundService::exitAfterSync, AndroidBackgroundService::onStartCommand,
140+
android.app.Service.stopSelfResult](https://developer.android.com/reference/android/app/Service.html#stopSelfResult(int))
141+
*/

doc/androidsynccontrol.dox

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/*!
2+
@class QtDataSync::AndroidSyncControl
3+
4+
This class is part of the `QtDataSyncAndroid` module, which is only available on the android
5+
platform. It can be used to configure background synchronization so that your application is able
6+
to update it's internal data periodically in the background, even if your app is not actively
7+
used.
8+
9+
@warning This class alone is **not** sufficient to make this possible. You will also have to
10+
create a service based on AndroidBackgroundService and correctly set up the Manifest and other
11+
things. Have a look at the @ref android_sync_guide to learn how to add background synchronization
12+
to your project.
13+
14+
@sa AndroidBackgroundService, @ref android_sync_guide, IosSyncDelegate
15+
*/
16+
17+
/*!
18+
@property QtDataSync::AndroidSyncControl::valid
19+
20+
@default{`false`}
21+
22+
Validity basically comes down to whether there is a background service that matches the given
23+
serviceId. Only if the control is valid, it is possible to actually do anything with this class
24+
25+
@accessors{
26+
@readAc{isValid()}
27+
@notifyAc{validChanged()}
28+
}
29+
30+
@sa AndroidSyncControl::serviceId
31+
*/
32+
33+
/*!
34+
@property QtDataSync::AndroidSyncControl::serviceId
35+
36+
@default{`"de.skycoder42.qtservice.AndroidService"`}
37+
38+
The JAVA class name (*not* JNI name) of the android service that should be run to perform the
39+
background synchronization. The class must exist and must be declared as service in your
40+
AndroidManifest.xml
41+
42+
@accessors{
43+
@readAc{serviceId()}
44+
@writeAc{setServiceId()}
45+
@notifyAc{serviceIdChanged()}
46+
}
47+
48+
@sa AndroidSyncControl::valid, AndroidBackgroundService, AndroidSyncControl::enabled,
49+
@ref qtservice_backends_android
50+
*/
51+
52+
/*!
53+
@property QtDataSync::AndroidSyncControl::interval
54+
55+
@default{`60` (minutes)}
56+
57+
This value is passed to the operating system to schedule the background synchronization. There
58+
is no guarantee of exact delivery of those background synchronizations. It is only a suggestion
59+
to the system. However, android typically keeps the windows limited to twice the length of the
60+
interval.
61+
62+
@accessors{
63+
@readAc{interval()}
64+
@readAc{intervalMinutes()}
65+
@writeAc{setInterval()}
66+
@notifyAc{intervalChanged()}
67+
}
68+
69+
@sa AndroidSyncControl::serviceId
70+
*/
71+
72+
@sa AndroidSyncControl::valid, AndroidSyncControl::enabled
73+
*/
74+
75+
/*!
76+
@property QtDataSync::AndroidSyncControl::enabled
77+
78+
@default{`false`}
79+
80+
These property directly communicates with the OS and schedules (or unschedules) the task to run
81+
the service. This means you must always set serviceId and interval first before enabling a service
82+
83+
@attention This property is persisted. This means after changing it and restarting it, the new
84+
value will be the same as the one you set. This does *not* apply to all other properties. For
85+
example, after creating this class, it could already return enabled, but the interval property
86+
might not match the interval the service actually uses.
87+
88+
@accessors{
89+
@readAc{isEnabled()}
90+
@writeAc{setEnabled()}
91+
}
92+
93+
@sa AndroidSyncControl::serviceId, AndroidSyncControl::interval,
94+
AndroidSyncControl::triggerSyncNow
95+
*/
96+
97+
/*!
98+
@fn QtDataSync::AndroidSyncControl::triggerSyncNow
99+
100+
@returns true, if the operating system accepted the synchronization request, false if not
101+
102+
@note This only tells the OS to start the service specified by serviceId. It does not report back
103+
whether the service was actually correctly started or wether it finished gracefully.
104+
105+
@sa AndroidSyncControl::enabled
106+
*/

doc/makedoc.sh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ fi
4242

4343
for tagFile in $(find "$qtDocs" -name *.tags); do
4444
if [ $(basename "$tagFile") == "qtjsonserializer.tags" ]; then
45-
echo "TAGFILES += \"$tagFile=https://skycoder42.github.io/QJsonSerializer\"" >> $doxyRes
45+
echo "TAGFILES += \"$tagFile=https://skycoder42.github.io/QtJsonSerializer\"" >> $doxyRes
46+
elif [ $(basename "$tagFile") == "qtservice.tags" ]; then
47+
echo "TAGFILES += \"$tagFile=https://skycoder42.github.io/QtService\"" >> $doxyRes
4648
elif [ $(basename "$tagFile") != "qtdatasync.tags" ]; then
4749
echo "TAGFILES += \"$tagFile=https://doc.qt.io/qt-5\"" >> $doxyRes
4850
fi

examples/datasync/AndroidSync/android/src/de/skycoder42/qtdatasync/sample/androidsync/SvcHelper.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,20 @@
1515
public class SvcHelper {
1616
private static final String ForegroundChannelId = "de.skycoder42.qtdatasync.sample.androidsync.notify";
1717

18+
//! [create_notification]
1819
public static Notification createFgNotification(Context context) {
19-
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, ForegroundChannelId)
20+
return new NotificationCompat.Builder(context, ForegroundChannelId)
2021
.setContentTitle("AndroidSync Synchronization Service")
2122
.setContentText("Synchronizing…")
2223
.setContentInfo("AndroidSync")
2324
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.icon))
2425
.setSmallIcon(R.drawable.icon)
2526
.setLocalOnly(true)
2627
.setOngoing(true)
27-
.setCategory(NotificationCompat.CATEGORY_SERVICE);
28-
29-
return builder.build();
28+
.setCategory(NotificationCompat.CATEGORY_SERVICE)
29+
.build();
3030
}
31+
//! [create_notification]
3132

3233
public static void registerNotificationChannel(Context context) {
3334
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.O)

examples/datasync/AndroidSync/syncservice.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@ void SyncService::onSyncCompleted(QtDataSync::SyncManager::SyncState state)
1111
exitAfterSync();
1212
}
1313

14+
//! [jni_create_notification]
1415
QAndroidJniObject SyncService::createForegroundNotification()
1516
{
1617
return QAndroidJniObject::callStaticObjectMethod("de/skycoder42/qtdatasync/sample/androidsync/SvcHelper",
1718
"createFgNotification",
1819
"(Landroid/content/Context;)Landroid/app/Notification;",
1920
QtAndroid::androidService().object());
2021
}
22+
//! [jni_create_notification]

src/datasyncandroid/androidbackgroundservice.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,40 +15,58 @@
1515
namespace QtDataSync {
1616

1717
class AndroidBackgroundServicePrivate;
18+
//! An extension of QtService to create a synchronization service for android
1819
class Q_DATASYNCANDROID_EXPORT AndroidBackgroundService : public QtService::Service // clazy:exclude=ctor-missing-parent-argument
1920
{
2021
Q_OBJECT
2122

23+
//! Specify whether the service should wait for a full synchronization or only the download
2224
Q_PROPERTY(bool waitFullSync READ waitFullSync WRITE setWaitFullSync NOTIFY waitFullSyncChanged)
2325

2426
public:
27+
//! The Intent Action used to start the background synchronization
2528
static const QString BackgroundSyncAction;
29+
//! The Intent Action used to register the service for background synchronization
2630
static const QString RegisterSyncAction;
31+
//! The ID of the Foreground notification shown by the service while synchronizing
2732
static const int ForegroundNotificationId;
2833

34+
//! Default constructor
2935
AndroidBackgroundService(int &argc, char **argv, int = QCoreApplication::ApplicationFlags);
3036
~AndroidBackgroundService() override;
3137

38+
//! @readAcFn{AndroidBackgroundService::waitFullSync}
3239
bool waitFullSync() const;
3340

3441
public Q_SLOTS:
42+
//! @writeAcFn{AndroidBackgroundService::waitFullSync}
3543
void setWaitFullSync(bool waitFullSync);
3644

3745
Q_SIGNALS:
46+
//! @notifyAcFn{AndroidBackgroundService::waitFullSync}
3847
void waitFullSyncChanged(bool waitFullSync, QPrivateSignal);
3948

4049
protected:
50+
//! Returns the name of the setup to be synchronized
4151
virtual QString setupName() const;
52+
//! Prepares the setup to be synchronized
4253
virtual void prepareSetup(Setup &setup);
4354

55+
//! @inherit{QtService::Service::onStart}
4456
CommandResult onStart() override;
57+
//! @inherit{QtService::Service::onStop}
4558
CommandResult onStop(int &exitCode) override;
4659

60+
//! Is called by the service as soon the the synchronization has been completed
4761
virtual void onSyncCompleted(SyncManager::SyncState state);
62+
//! Tells the service to quit itself after a synchronization
4863
void exitAfterSync();
4964

65+
//! Is called on the android thread to deliver the start command
5066
virtual int onStartCommand(const QAndroidIntent &intent, int flags, int startId);
67+
//! Is called on the android thread to create a foreground notification
5168
virtual QAndroidJniObject createForegroundNotification() = 0;
69+
//! Is called by the service to stop itself once finished, based on the id it was started with
5270
virtual bool stopSelf(int startId);
5371

5472
private Q_SLOTS:

src/datasyncandroid/androidbackgroundservice_p.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class AndroidBackgroundServicePrivate
1313
SyncManager *manager = nullptr;
1414
int startId = -1;
1515

16-
bool waitFullSync = false;
16+
bool waitFullSync = true;
1717
};
1818

1919
}

0 commit comments

Comments
 (0)