@capgo/background-geolocation 7.0.8 → 7.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,16 +1,21 @@
1
1
  package com.capgo.capacitor_background_geolocation;
2
2
 
3
3
  import android.app.Notification;
4
+ import android.app.PendingIntent;
4
5
  import android.app.Service;
5
6
  import android.content.Context;
6
7
  import android.content.Intent;
8
+ import android.content.res.AssetFileDescriptor;
9
+ import android.content.res.AssetManager;
10
+ import android.graphics.Color;
7
11
  import android.location.LocationListener;
8
12
  import android.location.LocationManager;
13
+ import android.media.MediaPlayer;
9
14
  import android.os.Binder;
15
+ import android.os.Build;
10
16
  import android.os.IBinder;
11
17
  import androidx.localbroadcastmanager.content.LocalBroadcastManager;
12
18
  import com.getcapacitor.Logger;
13
- import java.util.HashSet;
14
19
 
15
20
  // A bound and started service that is promoted to a foreground service
16
21
  // (showing a persistent notification) when the first background watcher is
@@ -24,16 +29,11 @@ public class BackgroundGeolocationService extends Service {
24
29
  // Must be unique for this application.
25
30
  private static final int NOTIFICATION_ID = 28351;
26
31
 
27
- private static class Watcher {
32
+ private String callbackId;
28
33
 
29
- public String id;
30
- public LocationManager client;
31
- public float distanceFilter;
32
- public LocationListener locationCallback;
33
- public Notification backgroundNotification;
34
- }
35
-
36
- private HashSet<Watcher> watchers = new HashSet<>();
34
+ private LocationManager client;
35
+ private LocationListener locationCallback;
36
+ private MediaPlayer mediaPlayer;
37
37
 
38
38
  @Override
39
39
  public IBinder onBind(Intent intent) {
@@ -46,59 +46,67 @@ public class BackgroundGeolocationService extends Service {
46
46
  // service is terminated immediately.
47
47
  @Override
48
48
  public boolean onUnbind(Intent intent) {
49
- for (Watcher watcher : watchers) {
50
- watcher.client.removeUpdates(watcher.locationCallback);
51
- }
52
- watchers = new HashSet<>();
49
+ client.removeUpdates(locationCallback);
50
+ releaseMediaPlayer();
53
51
  stopSelf();
54
52
  return false;
55
53
  }
56
54
 
57
- private void requestLocationUpdates(Watcher watcher) {
55
+ @Override
56
+ public void onDestroy() {
57
+ client.removeUpdates(locationCallback);
58
+ super.onDestroy();
59
+ releaseMediaPlayer();
60
+ }
61
+
62
+ private void releaseMediaPlayer() {
63
+ if (mediaPlayer == null) {
64
+ return;
65
+ }
58
66
  try {
59
- watcher.client.requestLocationUpdates(
60
- LocationManager.GPS_PROVIDER,
61
- 1000,
62
- watcher.distanceFilter,
63
- watcher.locationCallback
64
- );
65
- } catch (SecurityException ignore) {
66
- // According to Android Studio, this method can throw a Security Exception if
67
- // permissions are not yet granted. Rather than check the permissions, which is fiddly,
68
- // we simply ignore the exception.
67
+ if (mediaPlayer.isPlaying()) {
68
+ mediaPlayer.stop();
69
+ }
70
+ mediaPlayer.release();
71
+ } catch (Exception e) {
72
+ Logger.error("Error releasing MediaPlayer", e);
69
73
  }
74
+ mediaPlayer = null;
70
75
  }
71
76
 
72
77
  // Handles requests from the activity.
73
78
  public class LocalBinder extends Binder {
74
79
 
75
- void addWatcher(
80
+ void start(
76
81
  final String id,
77
- Notification backgroundNotification,
82
+ final String notificationTitle,
83
+ final String notificationMessage,
78
84
  float distanceFilter
79
85
  ) {
80
- LocationManager locationManager = (LocationManager) getSystemService(
81
- Context.LOCATION_SERVICE
82
- );
86
+ client = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
87
+ callbackId = id;
83
88
 
84
- LocationListener listener = location -> {
89
+ locationCallback = location -> {
85
90
  Intent intent = new Intent(ACTION_BROADCAST);
86
91
  intent.putExtra("location", location);
87
- intent.putExtra("id", id);
92
+ intent.putExtra("id", callbackId);
88
93
  LocalBroadcastManager.getInstance(
89
94
  getApplicationContext()
90
95
  ).sendBroadcast(intent);
91
96
  };
92
97
 
93
- Watcher watcher = new Watcher();
94
- watcher.id = id;
95
- watcher.client = locationManager;
96
- watcher.distanceFilter = distanceFilter;
97
- watcher.locationCallback = listener;
98
- watcher.backgroundNotification = backgroundNotification;
99
- watchers.add(watcher);
100
-
101
- requestLocationUpdates(watcher);
98
+ try {
99
+ client.requestLocationUpdates(
100
+ LocationManager.GPS_PROVIDER,
101
+ 1000,
102
+ distanceFilter,
103
+ locationCallback
104
+ );
105
+ } catch (SecurityException ignore) {
106
+ // According to Android Studio, this method can throw a Security Exception if
107
+ // permissions are not yet granted. Rather than check the permissions, which is fiddly,
108
+ // we simply ignore the exception.
109
+ }
102
110
 
103
111
  // Promote the service to the foreground if necessary.
104
112
  // Ideally we would only call 'startForeground' if the service is not already
@@ -110,28 +118,158 @@ public class BackgroundGeolocationService extends Service {
110
118
  // This method has been known to fail due to weird
111
119
  // permission bugs, so we prevent any exceptions from
112
120
  // crashing the app. See issue #86.
113
- startForeground(NOTIFICATION_ID, backgroundNotification);
121
+ startForeground(
122
+ NOTIFICATION_ID,
123
+ createBackgroundNotification(notificationTitle, notificationMessage)
124
+ );
114
125
  } catch (Exception exception) {
115
126
  Logger.error("Failed to foreground service", exception);
116
127
  }
117
128
  }
118
129
 
119
- void removeWatcher(String id) {
120
- for (Watcher watcher : watchers) {
121
- if (watcher.id.equals(id)) {
122
- watcher.client.removeUpdates(watcher.locationCallback);
123
- watchers.remove(watcher);
124
- break;
125
- }
130
+ String stop() {
131
+ client.removeUpdates(locationCallback);
132
+ stopForeground(true);
133
+ stopSelf();
134
+ return callbackId;
135
+ }
136
+
137
+ void playSound(String filePath) {
138
+ try {
139
+ releaseMediaPlayer();
140
+
141
+ mediaPlayer = new MediaPlayer();
142
+
143
+ AssetManager am = getApplicationContext().getResources().getAssets();
144
+ AssetFileDescriptor assetFileDescriptor = am.openFd(
145
+ "public/" + filePath
146
+ );
147
+
148
+ mediaPlayer.setDataSource(
149
+ assetFileDescriptor.getFileDescriptor(),
150
+ assetFileDescriptor.getStartOffset(),
151
+ assetFileDescriptor.getLength()
152
+ );
153
+ mediaPlayer.setLooping(false);
154
+
155
+ mediaPlayer.setOnCompletionListener(mp -> {
156
+ try {
157
+ mp.release();
158
+ } catch (Exception e) {
159
+ Logger.error("Error releasing MediaPlayer on completion", e);
160
+ }
161
+ mediaPlayer = null;
162
+ });
163
+
164
+ mediaPlayer.setOnErrorListener((mp, what, extra) -> {
165
+ Logger.error("MediaPlayer error: what=" + what + ", extra=" + extra);
166
+ releaseMediaPlayer();
167
+ return true; // Indicate we handled the error
168
+ });
169
+
170
+ mediaPlayer.prepareAsync();
171
+ mediaPlayer.setOnPreparedListener(mp -> {
172
+ try {
173
+ mp.start();
174
+ Logger.debug("PlaySound: Successfully started playing sound");
175
+ } catch (Exception e) {
176
+ Logger.error("Error starting MediaPlayer", e);
177
+ releaseMediaPlayer();
178
+ }
179
+ });
180
+ } catch (Exception e) {
181
+ Logger.error("PlaySound: Unexpected error", e);
182
+ releaseMediaPlayer();
126
183
  }
127
- if (watchers.isEmpty()) {
128
- stopService();
184
+ }
185
+ }
186
+
187
+ private Notification createBackgroundNotification(
188
+ String backgroundTitle,
189
+ String backgroundMessage
190
+ ) {
191
+ Notification.Builder builder = new Notification.Builder(
192
+ getApplicationContext()
193
+ )
194
+ .setContentTitle(backgroundTitle)
195
+ .setContentText(backgroundMessage)
196
+ .setOngoing(true)
197
+ .setPriority(Notification.PRIORITY_HIGH)
198
+ .setWhen(System.currentTimeMillis());
199
+
200
+ try {
201
+ String name = getAppString(
202
+ "capacitor_background_geolocation_notification_icon",
203
+ "mipmap/ic_launcher",
204
+ getApplicationContext()
205
+ );
206
+ String[] parts = name.split("/");
207
+ // It is actually necessary to set a valid icon for the notification to behave
208
+ // correctly when tapped. If there is no icon specified, tapping it will open the
209
+ // app's settings, rather than bringing the application to the foreground.
210
+ builder.setSmallIcon(
211
+ getAppResourceIdentifier(parts[1], parts[0], getApplicationContext())
212
+ );
213
+ } catch (Exception e) {
214
+ Logger.error("Could not set notification icon", e);
215
+ }
216
+
217
+ try {
218
+ String color = getAppString(
219
+ "capacitor_background_geolocation_notification_color",
220
+ null,
221
+ getApplicationContext()
222
+ );
223
+ if (color != null) {
224
+ builder.setColor(Color.parseColor(color));
129
225
  }
226
+ } catch (Exception e) {
227
+ Logger.error("Could not set notification color", e);
130
228
  }
131
229
 
132
- void stopService() {
133
- stopForeground(true);
134
- stopSelf();
230
+ Intent launchIntent = getApplicationContext()
231
+ .getPackageManager()
232
+ .getLaunchIntentForPackage(getApplicationContext().getPackageName());
233
+ if (launchIntent != null) {
234
+ launchIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
235
+ builder.setContentIntent(
236
+ PendingIntent.getActivity(
237
+ getApplicationContext(),
238
+ 0,
239
+ launchIntent,
240
+ PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE
241
+ )
242
+ );
243
+ }
244
+
245
+ // Set the Channel ID for Android O.
246
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
247
+ builder.setChannelId(
248
+ BackgroundGeolocationService.class.getPackage().getName()
249
+ );
135
250
  }
251
+
252
+ return builder.build();
253
+ }
254
+
255
+ // Gets the identifier of the app's resource by name, returning 0 if not found.
256
+ private static int getAppResourceIdentifier(
257
+ String name,
258
+ String defType,
259
+ Context context
260
+ ) {
261
+ return context
262
+ .getResources()
263
+ .getIdentifier(name, defType, context.getPackageName());
264
+ }
265
+
266
+ // Gets a string from the app's strings.xml file, resorting to a fallback if it is not defined.
267
+ public static String getAppString(
268
+ String name,
269
+ String fallback,
270
+ Context context
271
+ ) {
272
+ int id = getAppResourceIdentifier(name, "string", context);
273
+ return id == 0 ? fallback : context.getString(id);
136
274
  }
137
275
  }
package/dist/docs.json CHANGED
@@ -2,22 +2,22 @@
2
2
  "api": {
3
3
  "name": "BackgroundGeolocationPlugin",
4
4
  "slug": "backgroundgeolocationplugin",
5
- "docs": "Main plugin interface for background geolocation functionality.\nProvides methods to manage location watchers and access device settings.",
5
+ "docs": "Main plugin interface for background geolocation functionality.\nProvides methods to manage location updates and access device settings.",
6
6
  "tags": [
7
7
  {
8
- "text": "1.0.0",
8
+ "text": "7.0.0",
9
9
  "name": "since"
10
10
  }
11
11
  ],
12
12
  "methods": [
13
13
  {
14
- "name": "addWatcher",
15
- "signature": "(options: WatcherOptions, callback: (position?: Location | undefined, error?: CallbackError | undefined) => void) => Promise<string>",
14
+ "name": "start",
15
+ "signature": "(options: StartOptions, callback: (position?: Location | undefined, error?: CallbackError | undefined) => void) => Promise<void>",
16
16
  "parameters": [
17
17
  {
18
18
  "name": "options",
19
- "docs": "The watcher configuration options",
20
- "type": "WatcherOptions"
19
+ "docs": "The configuration options",
20
+ "type": "StartOptions"
21
21
  },
22
22
  {
23
23
  "name": "callback",
@@ -25,11 +25,11 @@
25
25
  "type": "(position?: Location | undefined, error?: CallbackError | undefined) => void"
26
26
  }
27
27
  ],
28
- "returns": "Promise<string>",
28
+ "returns": "Promise<void>",
29
29
  "tags": [
30
30
  {
31
31
  "name": "param",
32
- "text": "options The watcher configuration options"
32
+ "text": "options The configuration options"
33
33
  },
34
34
  {
35
35
  "name": "param",
@@ -37,57 +37,47 @@
37
37
  },
38
38
  {
39
39
  "name": "returns",
40
- "text": "A promise that resolves to a unique identifier for the watcher ID"
40
+ "text": "A promise that resolves when the method is successfully called"
41
41
  },
42
42
  {
43
43
  "name": "since",
44
- "text": "1.0.0"
44
+ "text": "7.0.9"
45
45
  },
46
46
  {
47
47
  "name": "example",
48
- "text": "const watcherId = await BackgroundGeolocation.addWatcher(\n {\n backgroundMessage: \"App is using your location in the background\",\n backgroundTitle: \"Location Service\",\n requestPermissions: true,\n stale: false,\n distanceFilter: 10\n },\n (location, error) => {\n if (error) {\n console.error('Location error:', error);\n return;\n }\n if (location) {\n console.log('New location:', location.latitude, location.longitude);\n }\n }\n);"
48
+ "text": "await BackgroundGeolocation.start(\n {\n backgroundMessage: \"App is using your location in the background\",\n backgroundTitle: \"Location Service\",\n requestPermissions: true,\n stale: false,\n distanceFilter: 10\n },\n (location, error) => {\n if (error) {\n console.error('Location error:', error);\n return;\n }\n if (location) {\n console.log('New location:', location.latitude, location.longitude);\n }\n }\n);"
49
49
  }
50
50
  ],
51
- "docs": "Adds a watcher for location updates.\nThe watcher will be invoked with the latest location whenever it is available.\nIf an error occurs, the callback will be invoked with the error.",
51
+ "docs": "To start listening for changes in the device's location, call this method.\nA Promise is returned to indicate that it finished the call. The callback will be called every time a new location\nis available, or if there was an error when calling this method. Don't rely on promise rejection for this.",
52
52
  "complexTypes": [
53
- "WatcherOptions",
53
+ "StartOptions",
54
54
  "Location",
55
55
  "CallbackError"
56
56
  ],
57
- "slug": "addwatcher"
57
+ "slug": "start"
58
58
  },
59
59
  {
60
- "name": "removeWatcher",
61
- "signature": "(options: { id: string; }) => Promise<void>",
62
- "parameters": [
63
- {
64
- "name": "options",
65
- "docs": "Object containing the watcher ID to remove",
66
- "type": "{ id: string; }"
67
- }
68
- ],
60
+ "name": "stop",
61
+ "signature": "() => Promise<void>",
62
+ "parameters": [],
69
63
  "returns": "Promise<void>",
70
64
  "tags": [
71
- {
72
- "name": "param",
73
- "text": "options Object containing the watcher ID to remove"
74
- },
75
65
  {
76
66
  "name": "returns",
77
- "text": "A promise that resolves when the watcher is successfully removed"
67
+ "text": "A promise that resolves when the plugin stops successfully removed"
78
68
  },
79
69
  {
80
70
  "name": "since",
81
- "text": "1.0.0"
71
+ "text": "7.0.9"
82
72
  },
83
73
  {
84
74
  "name": "example",
85
- "text": "await BackgroundGeolocation.removeWatcher({ id: watcherId });"
75
+ "text": "await BackgroundGeolocation.stop();"
86
76
  }
87
77
  ],
88
- "docs": "Removes a watcher by its unique identifier.\nStops location updates for the specified watcher.",
78
+ "docs": "Stops location updates.",
89
79
  "complexTypes": [],
90
- "slug": "removewatcher"
80
+ "slug": "stop"
91
81
  },
92
82
  {
93
83
  "name": "openSettings",
@@ -101,7 +91,7 @@
101
91
  },
102
92
  {
103
93
  "name": "since",
104
- "text": "1.0.0"
94
+ "text": "7.0.0"
105
95
  },
106
96
  {
107
97
  "name": "example",
@@ -111,18 +101,53 @@
111
101
  "docs": "Opens the device's location settings page.\nUseful for directing users to enable location services or adjust permissions.",
112
102
  "complexTypes": [],
113
103
  "slug": "opensettings"
104
+ },
105
+ {
106
+ "name": "playSound",
107
+ "signature": "(options: PlaySoundOptions) => Promise<void>",
108
+ "parameters": [
109
+ {
110
+ "name": "options",
111
+ "docs": "The options for playing the sound",
112
+ "type": "PlaySoundOptions"
113
+ }
114
+ ],
115
+ "returns": "Promise<void>",
116
+ "tags": [
117
+ {
118
+ "name": "param",
119
+ "text": "options The options for playing the sound"
120
+ },
121
+ {
122
+ "name": "returns",
123
+ "text": "A promise that resolves when the sound is successfully played"
124
+ },
125
+ {
126
+ "name": "since",
127
+ "text": "7.0.10"
128
+ },
129
+ {
130
+ "name": "example",
131
+ "text": "await BackgroundGeolocation.playSound({\n soundFile: \"notification.mp3\"\n});"
132
+ }
133
+ ],
134
+ "docs": "Plays a sound file.\nThis should be used to play a sound, in the background too.\nThe idea behind this is to allow the user to hear a sound when a new location is available or when going off track.\nIf you simply need to play a sound, you can use `@capgo/native-audio` plugin instead.\nFor Android, there's a need to start monitoring location updates first, otherwise the sound will not play.",
135
+ "complexTypes": [
136
+ "PlaySoundOptions"
137
+ ],
138
+ "slug": "playsound"
114
139
  }
115
140
  ],
116
141
  "properties": []
117
142
  },
118
143
  "interfaces": [
119
144
  {
120
- "name": "WatcherOptions",
121
- "slug": "watcheroptions",
122
- "docs": "The options for configuring a watcher that listens for location updates.",
145
+ "name": "StartOptions",
146
+ "slug": "startoptions",
147
+ "docs": "The options for configuring for location updates.",
123
148
  "tags": [
124
149
  {
125
- "text": "1.0.0",
150
+ "text": "7.0.9",
126
151
  "name": "since"
127
152
  }
128
153
  ],
@@ -132,7 +157,7 @@
132
157
  "name": "backgroundMessage",
133
158
  "tags": [
134
159
  {
135
- "text": "1.0.0",
160
+ "text": "7.0.9",
136
161
  "name": "since"
137
162
  },
138
163
  {
@@ -140,7 +165,7 @@
140
165
  "name": "example"
141
166
  }
142
167
  ],
143
- "docs": "If the \"backgroundMessage\" option is defined, the watcher will\nprovide location updates whether the app is in the background or the\nforeground. If it is not defined, location updates are only\nguaranteed in the foreground. This is true on both platforms.\n\nOn Android, a notification must be shown to continue receiving\nlocation updates in the background. This option specifies the text of\nthat notification.",
168
+ "docs": "If the \"backgroundMessage\" option is defined, the plugin will\nprovide location updates whether the app is in the background or the\nforeground. If it is not defined, location updates are only\nguaranteed in the foreground. This is true on both platforms.\n\nOn Android, a notification must be shown to continue receiving\nlocation updates in the background. This option specifies the text of\nthat notification.",
144
169
  "complexTypes": [],
145
170
  "type": "string | undefined"
146
171
  },
@@ -148,7 +173,7 @@
148
173
  "name": "backgroundTitle",
149
174
  "tags": [
150
175
  {
151
- "text": "1.0.0",
176
+ "text": "7.0.9",
152
177
  "name": "since"
153
178
  },
154
179
  {
@@ -168,7 +193,7 @@
168
193
  "name": "requestPermissions",
169
194
  "tags": [
170
195
  {
171
- "text": "1.0.0",
196
+ "text": "7.0.9",
172
197
  "name": "since"
173
198
  },
174
199
  {
@@ -188,7 +213,7 @@
188
213
  "name": "stale",
189
214
  "tags": [
190
215
  {
191
- "text": "1.0.0",
216
+ "text": "7.0.9",
192
217
  "name": "since"
193
218
  },
194
219
  {
@@ -208,7 +233,7 @@
208
233
  "name": "distanceFilter",
209
234
  "tags": [
210
235
  {
211
- "text": "1.0.0",
236
+ "text": "7.0.9",
212
237
  "name": "since"
213
238
  },
214
239
  {
@@ -232,7 +257,7 @@
232
257
  "docs": "Represents a geographical location with various attributes.\nContains all the standard location properties returned by GPS/network providers.",
233
258
  "tags": [
234
259
  {
235
- "text": "1.0.0",
260
+ "text": "7.0.0",
236
261
  "name": "since"
237
262
  }
238
263
  ],
@@ -242,7 +267,7 @@
242
267
  "name": "latitude",
243
268
  "tags": [
244
269
  {
245
- "text": "1.0.0",
270
+ "text": "7.0.0",
246
271
  "name": "since"
247
272
  },
248
273
  {
@@ -258,7 +283,7 @@
258
283
  "name": "longitude",
259
284
  "tags": [
260
285
  {
261
- "text": "1.0.0",
286
+ "text": "7.0.0",
262
287
  "name": "since"
263
288
  },
264
289
  {
@@ -274,7 +299,7 @@
274
299
  "name": "accuracy",
275
300
  "tags": [
276
301
  {
277
- "text": "1.0.0",
302
+ "text": "7.0.0",
278
303
  "name": "since"
279
304
  },
280
305
  {
@@ -290,7 +315,7 @@
290
315
  "name": "altitude",
291
316
  "tags": [
292
317
  {
293
- "text": "1.0.0",
318
+ "text": "7.0.0",
294
319
  "name": "since"
295
320
  },
296
321
  {
@@ -306,7 +331,7 @@
306
331
  "name": "altitudeAccuracy",
307
332
  "tags": [
308
333
  {
309
- "text": "1.0.0",
334
+ "text": "7.0.0",
310
335
  "name": "since"
311
336
  },
312
337
  {
@@ -322,7 +347,7 @@
322
347
  "name": "simulated",
323
348
  "tags": [
324
349
  {
325
- "text": "1.0.0",
350
+ "text": "7.0.0",
326
351
  "name": "since"
327
352
  },
328
353
  {
@@ -338,7 +363,7 @@
338
363
  "name": "bearing",
339
364
  "tags": [
340
365
  {
341
- "text": "1.0.0",
366
+ "text": "7.0.0",
342
367
  "name": "since"
343
368
  },
344
369
  {
@@ -354,7 +379,7 @@
354
379
  "name": "speed",
355
380
  "tags": [
356
381
  {
357
- "text": "1.0.0",
382
+ "text": "7.0.0",
358
383
  "name": "since"
359
384
  },
360
385
  {
@@ -370,7 +395,7 @@
370
395
  "name": "time",
371
396
  "tags": [
372
397
  {
373
- "text": "1.0.0",
398
+ "text": "7.0.0",
374
399
  "name": "since"
375
400
  },
376
401
  {
@@ -387,10 +412,10 @@
387
412
  {
388
413
  "name": "CallbackError",
389
414
  "slug": "callbackerror",
390
- "docs": "Error object that may be passed to the location watcher callback.\nExtends the standard Error with optional error codes.",
415
+ "docs": "Error object that may be passed to the location start callback.\nExtends the standard Error with optional error codes.",
391
416
  "tags": [
392
417
  {
393
- "text": "1.0.0",
418
+ "text": "7.0.0",
394
419
  "name": "since"
395
420
  }
396
421
  ],
@@ -400,7 +425,7 @@
400
425
  "name": "code",
401
426
  "tags": [
402
427
  {
403
- "text": "1.0.0",
428
+ "text": "7.0.0",
404
429
  "name": "since"
405
430
  },
406
431
  {
@@ -413,6 +438,31 @@
413
438
  "type": "string | undefined"
414
439
  }
415
440
  ]
441
+ },
442
+ {
443
+ "name": "PlaySoundOptions",
444
+ "slug": "playsoundoptions",
445
+ "docs": "",
446
+ "tags": [],
447
+ "methods": [],
448
+ "properties": [
449
+ {
450
+ "name": "soundFile",
451
+ "tags": [
452
+ {
453
+ "text": "7.0.10",
454
+ "name": "since"
455
+ },
456
+ {
457
+ "text": "\"notification.mp3\"",
458
+ "name": "example"
459
+ }
460
+ ],
461
+ "docs": "The name of the sound file to play.\nMust be a valid sound relative path in the app's public folder to work for both web and native platforms.\nThere's no need to include the public folder in the path.",
462
+ "complexTypes": [],
463
+ "type": "string"
464
+ }
465
+ ]
416
466
  }
417
467
  ],
418
468
  "enums": [],