@capgo/capacitor-launch-navigator 7.0.0
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.
- package/CapgoCapacitorLaunchNavigator.podspec +17 -0
- package/Package.swift +28 -0
- package/README.md +316 -0
- package/android/build.gradle +58 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/app/capgo/plugin/launch_navigator/LaunchNavigator.java +286 -0
- package/android/src/main/java/app/capgo/plugin/launch_navigator/LaunchNavigatorPlugin.java +113 -0
- package/android/src/main/res/.gitkeep +0 -0
- package/dist/docs.json +467 -0
- package/dist/esm/definitions.d.ts +173 -0
- package/dist/esm/definitions.js +63 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/web.d.ts +42 -0
- package/dist/esm/web.js +74 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +151 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +154 -0
- package/dist/plugin.js.map +1 -0
- package/ios/Sources/LaunchNavigatorPlugin/LaunchNavigator.swift +394 -0
- package/ios/Sources/LaunchNavigatorPlugin/LaunchNavigatorPlugin.swift +94 -0
- package/ios/Tests/LaunchNavigatorPluginTests/LaunchNavigatorPluginTests.swift +15 -0
- package/package.json +92 -0
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
package app.capgo.plugin.launch_navigator;
|
|
2
|
+
|
|
3
|
+
import android.content.Context;
|
|
4
|
+
import android.content.Intent;
|
|
5
|
+
import android.content.pm.PackageManager;
|
|
6
|
+
import android.net.Uri;
|
|
7
|
+
|
|
8
|
+
import com.getcapacitor.JSArray;
|
|
9
|
+
import com.getcapacitor.JSObject;
|
|
10
|
+
|
|
11
|
+
import java.util.HashMap;
|
|
12
|
+
import java.util.Map;
|
|
13
|
+
import java.util.Locale;
|
|
14
|
+
|
|
15
|
+
public class LaunchNavigator {
|
|
16
|
+
|
|
17
|
+
private Context context;
|
|
18
|
+
private Map<String, AppInfo> navigationApps;
|
|
19
|
+
|
|
20
|
+
private static class AppInfo {
|
|
21
|
+
String name;
|
|
22
|
+
String packageName;
|
|
23
|
+
|
|
24
|
+
AppInfo(String name, String packageName) {
|
|
25
|
+
this.name = name;
|
|
26
|
+
this.packageName = packageName;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public LaunchNavigator(Context context) {
|
|
31
|
+
this.context = context;
|
|
32
|
+
initializeApps();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
private void initializeApps() {
|
|
36
|
+
navigationApps = new HashMap<>();
|
|
37
|
+
navigationApps.put("google_maps", new AppInfo("Google Maps", "com.google.android.apps.maps"));
|
|
38
|
+
navigationApps.put("waze", new AppInfo("Waze", "com.waze"));
|
|
39
|
+
navigationApps.put("citymapper", new AppInfo("Citymapper", "com.citymapper.app.release"));
|
|
40
|
+
navigationApps.put("uber", new AppInfo("Uber", "com.ubercab"));
|
|
41
|
+
navigationApps.put("yandex", new AppInfo("Yandex Navigator", "ru.yandex.yandexnavi"));
|
|
42
|
+
navigationApps.put("sygic", new AppInfo("Sygic", "com.sygic.aura"));
|
|
43
|
+
navigationApps.put("here", new AppInfo("HERE Maps", "com.here.app.maps"));
|
|
44
|
+
navigationApps.put("moovit", new AppInfo("Moovit", "com.tranzmate"));
|
|
45
|
+
navigationApps.put("lyft", new AppInfo("Lyft", "me.lyft.android"));
|
|
46
|
+
navigationApps.put("mapsme", new AppInfo("MAPS.ME", "com.mapswithme.maps.pro"));
|
|
47
|
+
navigationApps.put("cabify", new AppInfo("Cabify", "com.cabify.rider"));
|
|
48
|
+
navigationApps.put("baidu", new AppInfo("Baidu Maps", "com.baidu.BaiduMap"));
|
|
49
|
+
navigationApps.put("gaode", new AppInfo("Gaode Maps", "com.autonavi.minimap"));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public boolean navigate(
|
|
53
|
+
String app,
|
|
54
|
+
double lat,
|
|
55
|
+
double lon,
|
|
56
|
+
Double startLat,
|
|
57
|
+
Double startLon,
|
|
58
|
+
String startName,
|
|
59
|
+
String destinationName,
|
|
60
|
+
String transportMode
|
|
61
|
+
) {
|
|
62
|
+
try {
|
|
63
|
+
Intent intent;
|
|
64
|
+
|
|
65
|
+
switch (app) {
|
|
66
|
+
case "google_maps":
|
|
67
|
+
intent = createGoogleMapsIntent(lat, lon, startLat, startLon, transportMode);
|
|
68
|
+
break;
|
|
69
|
+
case "waze":
|
|
70
|
+
intent = createWazeIntent(lat, lon);
|
|
71
|
+
break;
|
|
72
|
+
case "citymapper":
|
|
73
|
+
intent = createCitymapperIntent(lat, lon, startLat, startLon);
|
|
74
|
+
break;
|
|
75
|
+
case "uber":
|
|
76
|
+
intent = createUberIntent(lat, lon, startLat, startLon);
|
|
77
|
+
break;
|
|
78
|
+
case "yandex":
|
|
79
|
+
intent = createYandexIntent(lat, lon, startLat, startLon);
|
|
80
|
+
break;
|
|
81
|
+
case "sygic":
|
|
82
|
+
intent = createSygicIntent(lat, lon);
|
|
83
|
+
break;
|
|
84
|
+
case "here":
|
|
85
|
+
intent = createHereIntent(lat, lon, startLat, startLon);
|
|
86
|
+
break;
|
|
87
|
+
case "moovit":
|
|
88
|
+
intent = createMoovitIntent(lat, lon, startLat, startLon);
|
|
89
|
+
break;
|
|
90
|
+
case "lyft":
|
|
91
|
+
intent = createLyftIntent(lat, lon);
|
|
92
|
+
break;
|
|
93
|
+
case "mapsme":
|
|
94
|
+
intent = createMapsMeIntent(lat, lon);
|
|
95
|
+
break;
|
|
96
|
+
case "cabify":
|
|
97
|
+
intent = createCabifyIntent(lat, lon, startLat, startLon);
|
|
98
|
+
break;
|
|
99
|
+
case "baidu":
|
|
100
|
+
intent = createBaiduIntent(lat, lon, startLat, startLon);
|
|
101
|
+
break;
|
|
102
|
+
case "gaode":
|
|
103
|
+
intent = createGaodeIntent(lat, lon, startLat, startLon);
|
|
104
|
+
break;
|
|
105
|
+
default:
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (intent != null) {
|
|
110
|
+
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
111
|
+
context.startActivity(intent);
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return false;
|
|
116
|
+
} catch (Exception e) {
|
|
117
|
+
e.printStackTrace();
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
private Intent createGoogleMapsIntent(double lat, double lon, Double startLat, Double startLon, String transportMode) {
|
|
123
|
+
String uri;
|
|
124
|
+
if (startLat != null && startLon != null) {
|
|
125
|
+
uri = String.format(Locale.US, "google.navigation:q=%f,%f&mode=%s", lat, lon, getGoogleMapsMode(transportMode));
|
|
126
|
+
} else {
|
|
127
|
+
uri = String.format(Locale.US, "google.navigation:q=%f,%f&mode=%s", lat, lon, getGoogleMapsMode(transportMode));
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
|
|
131
|
+
intent.setPackage("com.google.android.apps.maps");
|
|
132
|
+
return intent;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
private String getGoogleMapsMode(String transportMode) {
|
|
136
|
+
switch (transportMode) {
|
|
137
|
+
case "walking":
|
|
138
|
+
return "w";
|
|
139
|
+
case "bicycling":
|
|
140
|
+
return "b";
|
|
141
|
+
case "transit":
|
|
142
|
+
return "r";
|
|
143
|
+
case "driving":
|
|
144
|
+
default:
|
|
145
|
+
return "d";
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
private Intent createWazeIntent(double lat, double lon) {
|
|
150
|
+
String uri = String.format(Locale.US, "waze://?ll=%f,%f&navigate=yes", lat, lon);
|
|
151
|
+
return new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
private Intent createCitymapperIntent(double lat, double lon, Double startLat, Double startLon) {
|
|
155
|
+
String uri = String.format(Locale.US, "citymapper://directions?endcoord=%f,%f", lat, lon);
|
|
156
|
+
if (startLat != null && startLon != null) {
|
|
157
|
+
uri += String.format(Locale.US, "&startcoord=%f,%f", startLat, startLon);
|
|
158
|
+
}
|
|
159
|
+
return new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
private Intent createUberIntent(double lat, double lon, Double startLat, Double startLon) {
|
|
163
|
+
String uri;
|
|
164
|
+
if (startLat != null && startLon != null) {
|
|
165
|
+
uri = String.format(Locale.US, "uber://?action=setPickup&pickup[latitude]=%f&pickup[longitude]=%f&dropoff[latitude]=%f&dropoff[longitude]=%f",
|
|
166
|
+
startLat, startLon, lat, lon);
|
|
167
|
+
} else {
|
|
168
|
+
uri = String.format(Locale.US, "uber://?action=setPickup&pickup=my_location&dropoff[latitude]=%f&dropoff[longitude]=%f", lat, lon);
|
|
169
|
+
}
|
|
170
|
+
return new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
private Intent createYandexIntent(double lat, double lon, Double startLat, Double startLon) {
|
|
174
|
+
String uri;
|
|
175
|
+
if (startLat != null && startLon != null) {
|
|
176
|
+
uri = String.format(Locale.US, "yandexnavi://build_route_on_map?lat_from=%f&lon_from=%f&lat_to=%f&lon_to=%f",
|
|
177
|
+
startLat, startLon, lat, lon);
|
|
178
|
+
} else {
|
|
179
|
+
uri = String.format(Locale.US, "yandexnavi://build_route_on_map?lat_to=%f&lon_to=%f", lat, lon);
|
|
180
|
+
}
|
|
181
|
+
return new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
private Intent createSygicIntent(double lat, double lon) {
|
|
185
|
+
String uri = String.format(Locale.US, "com.sygic.aura://coordinate|%f|%f|drive", lon, lat);
|
|
186
|
+
return new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
private Intent createHereIntent(double lat, double lon, Double startLat, Double startLon) {
|
|
190
|
+
String uri;
|
|
191
|
+
if (startLat != null && startLon != null) {
|
|
192
|
+
uri = String.format(Locale.US, "here.directions://v1.0/mylocation/%f,%f?m=w", lat, lon);
|
|
193
|
+
} else {
|
|
194
|
+
uri = String.format(Locale.US, "here.directions://v1.0/mylocation/%f,%f?m=w", lat, lon);
|
|
195
|
+
}
|
|
196
|
+
return new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
private Intent createMoovitIntent(double lat, double lon, Double startLat, Double startLon) {
|
|
200
|
+
String uri = String.format(Locale.US, "moovit://directions?dest_lat=%f&dest_lon=%f", lat, lon);
|
|
201
|
+
if (startLat != null && startLon != null) {
|
|
202
|
+
uri += String.format(Locale.US, "&orig_lat=%f&orig_lon=%f", startLat, startLon);
|
|
203
|
+
}
|
|
204
|
+
return new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
private Intent createLyftIntent(double lat, double lon) {
|
|
208
|
+
String uri = String.format(Locale.US, "lyft://ridetype?id=lyft&destination[latitude]=%f&destination[longitude]=%f", lat, lon);
|
|
209
|
+
return new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
private Intent createMapsMeIntent(double lat, double lon) {
|
|
213
|
+
String uri = String.format(Locale.US, "mapsme://map?ll=%f,%f", lat, lon);
|
|
214
|
+
return new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
private Intent createCabifyIntent(double lat, double lon, Double startLat, Double startLon) {
|
|
218
|
+
String uri;
|
|
219
|
+
if (startLat != null && startLon != null) {
|
|
220
|
+
uri = String.format(Locale.US, "cabify://ride?pickup[latitude]=%f&pickup[longitude]=%f&dropoff[latitude]=%f&dropoff[longitude]=%f",
|
|
221
|
+
startLat, startLon, lat, lon);
|
|
222
|
+
} else {
|
|
223
|
+
uri = String.format(Locale.US, "cabify://rideto?lat=%f&lng=%f", lat, lon);
|
|
224
|
+
}
|
|
225
|
+
return new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
private Intent createBaiduIntent(double lat, double lon, Double startLat, Double startLon) {
|
|
229
|
+
String uri = String.format(Locale.US, "baidumap://map/direction?destination=%f,%f&mode=driving", lat, lon);
|
|
230
|
+
if (startLat != null && startLon != null) {
|
|
231
|
+
uri += String.format(Locale.US, "&origin=%f,%f", startLat, startLon);
|
|
232
|
+
}
|
|
233
|
+
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
|
|
234
|
+
intent.setPackage("com.baidu.BaiduMap");
|
|
235
|
+
return intent;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
private Intent createGaodeIntent(double lat, double lon, Double startLat, Double startLon) {
|
|
239
|
+
String uri = String.format(Locale.US, "amapuri://route/plan/?dlat=%f&dlon=%f&dev=0&t=0", lat, lon);
|
|
240
|
+
if (startLat != null && startLon != null) {
|
|
241
|
+
uri += String.format(Locale.US, "&slat=%f&slon=%f", startLat, startLon);
|
|
242
|
+
}
|
|
243
|
+
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
|
|
244
|
+
intent.setPackage("com.autonavi.minimap");
|
|
245
|
+
return intent;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
public boolean isAppAvailable(String app) {
|
|
249
|
+
AppInfo appInfo = navigationApps.get(app);
|
|
250
|
+
if (appInfo == null) {
|
|
251
|
+
return false;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
PackageManager pm = context.getPackageManager();
|
|
255
|
+
try {
|
|
256
|
+
pm.getPackageInfo(appInfo.packageName, PackageManager.GET_ACTIVITIES);
|
|
257
|
+
return true;
|
|
258
|
+
} catch (PackageManager.NameNotFoundException e) {
|
|
259
|
+
return false;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
public JSArray getAvailableApps() {
|
|
264
|
+
JSArray apps = new JSArray();
|
|
265
|
+
|
|
266
|
+
for (Map.Entry<String, AppInfo> entry : navigationApps.entrySet()) {
|
|
267
|
+
JSObject appObject = new JSObject();
|
|
268
|
+
appObject.put("app", entry.getKey());
|
|
269
|
+
appObject.put("name", entry.getValue().name);
|
|
270
|
+
appObject.put("available", isAppAvailable(entry.getKey()));
|
|
271
|
+
apps.put(appObject);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
return apps;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
public JSArray getSupportedApps() {
|
|
278
|
+
JSArray apps = new JSArray();
|
|
279
|
+
|
|
280
|
+
for (String appKey : navigationApps.keySet()) {
|
|
281
|
+
apps.put(appKey);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
return apps;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
package app.capgo.plugin.launch_navigator;
|
|
2
|
+
|
|
3
|
+
import com.getcapacitor.JSObject;
|
|
4
|
+
import com.getcapacitor.JSArray;
|
|
5
|
+
import com.getcapacitor.Plugin;
|
|
6
|
+
import com.getcapacitor.PluginCall;
|
|
7
|
+
import com.getcapacitor.PluginMethod;
|
|
8
|
+
import com.getcapacitor.annotation.CapacitorPlugin;
|
|
9
|
+
|
|
10
|
+
@CapacitorPlugin(name = "LaunchNavigator")
|
|
11
|
+
public class LaunchNavigatorPlugin extends Plugin {
|
|
12
|
+
|
|
13
|
+
private LaunchNavigator implementation;
|
|
14
|
+
|
|
15
|
+
@Override
|
|
16
|
+
public void load() {
|
|
17
|
+
implementation = new LaunchNavigator(getContext());
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
@PluginMethod
|
|
21
|
+
public void navigate(PluginCall call) {
|
|
22
|
+
JSArray destination = call.getArray("destination");
|
|
23
|
+
if (destination == null || destination.length() != 2) {
|
|
24
|
+
call.reject("Destination coordinates [latitude, longitude] are required");
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
double lat = destination.getDouble(0);
|
|
30
|
+
double lon = destination.getDouble(1);
|
|
31
|
+
|
|
32
|
+
JSObject options = call.getObject("options", new JSObject());
|
|
33
|
+
String app = options.getString("app", "google_maps");
|
|
34
|
+
String transportMode = options.getString("transportMode", "driving");
|
|
35
|
+
|
|
36
|
+
Double startLat = null;
|
|
37
|
+
Double startLon = null;
|
|
38
|
+
|
|
39
|
+
// Try to get start array as JSONArray from the options object
|
|
40
|
+
try {
|
|
41
|
+
org.json.JSONArray startArray = options.getJSONArray("start");
|
|
42
|
+
if (startArray != null && startArray.length() == 2) {
|
|
43
|
+
startLat = startArray.getDouble(0);
|
|
44
|
+
startLon = startArray.getDouble(1);
|
|
45
|
+
}
|
|
46
|
+
} catch (Exception e) {
|
|
47
|
+
// start is optional, ignore if not present or invalid
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
String startName = options.getString("startName");
|
|
51
|
+
String destinationName = options.getString("destinationName");
|
|
52
|
+
|
|
53
|
+
boolean result = implementation.navigate(
|
|
54
|
+
app,
|
|
55
|
+
lat,
|
|
56
|
+
lon,
|
|
57
|
+
startLat,
|
|
58
|
+
startLon,
|
|
59
|
+
startName,
|
|
60
|
+
destinationName,
|
|
61
|
+
transportMode
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
if (result) {
|
|
65
|
+
call.resolve();
|
|
66
|
+
} else {
|
|
67
|
+
call.reject("Failed to launch navigation app");
|
|
68
|
+
}
|
|
69
|
+
} catch (Exception e) {
|
|
70
|
+
call.reject("Error parsing navigation parameters: " + e.getMessage());
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
@PluginMethod
|
|
75
|
+
public void isAppAvailable(PluginCall call) {
|
|
76
|
+
String app = call.getString("app");
|
|
77
|
+
if (app == null) {
|
|
78
|
+
call.reject("App identifier is required");
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
boolean available = implementation.isAppAvailable(app);
|
|
83
|
+
|
|
84
|
+
JSObject ret = new JSObject();
|
|
85
|
+
ret.put("available", available);
|
|
86
|
+
call.resolve(ret);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
@PluginMethod
|
|
90
|
+
public void getAvailableApps(PluginCall call) {
|
|
91
|
+
JSArray apps = implementation.getAvailableApps();
|
|
92
|
+
|
|
93
|
+
JSObject ret = new JSObject();
|
|
94
|
+
ret.put("apps", apps);
|
|
95
|
+
call.resolve(ret);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
@PluginMethod
|
|
99
|
+
public void getSupportedApps(PluginCall call) {
|
|
100
|
+
JSArray apps = implementation.getSupportedApps();
|
|
101
|
+
|
|
102
|
+
JSObject ret = new JSObject();
|
|
103
|
+
ret.put("apps", apps);
|
|
104
|
+
call.resolve(ret);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
@PluginMethod
|
|
108
|
+
public void getDefaultApp(PluginCall call) {
|
|
109
|
+
JSObject ret = new JSObject();
|
|
110
|
+
ret.put("app", "google_maps");
|
|
111
|
+
call.resolve(ret);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
File without changes
|