@capacitor/android 4.0.1-alpha.0 → 4.0.1
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/CHANGELOG.md +126 -1
- package/capacitor/build.gradle +9 -7
- package/capacitor/proguard-rules.pro +26 -0
- package/capacitor/src/main/assets/native-bridge.js +8 -0
- package/capacitor/src/main/java/com/getcapacitor/AppUUID.java +65 -0
- package/capacitor/src/main/java/com/getcapacitor/Bridge.java +147 -13
- package/capacitor/src/main/java/com/getcapacitor/BridgeActivity.java +11 -54
- package/capacitor/src/main/java/com/getcapacitor/BridgeWebChromeClient.java +4 -5
- package/capacitor/src/main/java/com/getcapacitor/BridgeWebViewClient.java +11 -0
- package/capacitor/src/main/java/com/getcapacitor/CapConfig.java +65 -2
- package/capacitor/src/main/java/com/getcapacitor/CapacitorWebView.java +1 -0
- package/capacitor/src/main/java/com/getcapacitor/FileUtils.java +6 -1
- package/capacitor/src/main/java/com/getcapacitor/JSExport.java +1 -1
- package/capacitor/src/main/java/com/getcapacitor/MessageHandler.java +31 -4
- package/capacitor/src/main/java/com/getcapacitor/Plugin.java +16 -10
- package/capacitor/src/main/java/com/getcapacitor/PluginCall.java +28 -9
- package/capacitor/src/main/java/com/getcapacitor/PluginHandle.java +4 -0
- package/capacitor/src/main/java/com/getcapacitor/ProcessedRoute.java +28 -0
- package/capacitor/src/main/java/com/getcapacitor/RouteProcessor.java +8 -0
- package/capacitor/src/main/java/com/getcapacitor/WebViewLocalServer.java +27 -5
- package/capacitor/src/main/java/com/getcapacitor/cordova/CapacitorCordovaCookieManager.java +1 -2
- package/capacitor/src/main/java/com/getcapacitor/cordova/MockCordovaWebViewImpl.java +5 -0
- package/capacitor/src/main/res/values/colors.xml +4 -4
- package/capacitor/src/main/res/values/strings.xml +0 -5
- package/capacitor/src/main/res/values/styles.xml +0 -9
- package/package.json +4 -3
- package/capacitor/src/main/res/drawable/ic_transparent.xml +0 -12
|
@@ -12,11 +12,11 @@ public class BridgeActivity extends AppCompatActivity {
|
|
|
12
12
|
|
|
13
13
|
protected Bridge bridge;
|
|
14
14
|
protected boolean keepRunning = true;
|
|
15
|
-
|
|
15
|
+
protected CapConfig config;
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
protected int activityDepth = 0;
|
|
18
|
+
protected List<Class<? extends Plugin>> initialPlugins = new ArrayList<>();
|
|
19
|
+
protected final Bridge.Builder bridgeBuilder = new Bridge.Builder(this);
|
|
20
20
|
|
|
21
21
|
@Override
|
|
22
22
|
protected void onCreate(Bundle savedInstanceState) {
|
|
@@ -26,47 +26,18 @@ public class BridgeActivity extends AppCompatActivity {
|
|
|
26
26
|
setTheme(getResources().getIdentifier("AppTheme_NoActionBar", "style", getPackageName()));
|
|
27
27
|
setTheme(R.style.AppTheme_NoActionBar);
|
|
28
28
|
setContentView(R.layout.bridge_layout_main);
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Initializes the Capacitor Bridge with the Activity.
|
|
33
|
-
* @deprecated It is preferred not to call this method. If it is not called, the bridge is
|
|
34
|
-
* initialized automatically. If you need to add additional plugins during initialization,
|
|
35
|
-
* use {@link #registerPlugin(Class)} or {@link #registerPlugins(List)}.
|
|
36
|
-
*
|
|
37
|
-
* @param plugins A list of plugins to initialize with Capacitor
|
|
38
|
-
*/
|
|
39
|
-
@Deprecated
|
|
40
|
-
protected void init(Bundle savedInstanceState, List<Class<? extends Plugin>> plugins) {
|
|
41
|
-
this.init(savedInstanceState, plugins, null);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Initializes the Capacitor Bridge with the Activity.
|
|
46
|
-
* @deprecated It is preferred not to call this method. If it is not called, the bridge is
|
|
47
|
-
* initialized automatically. If you need to add additional plugins during initialization,
|
|
48
|
-
* use {@link #registerPlugin(Class)} or {@link #registerPlugins(List)}.
|
|
49
|
-
*
|
|
50
|
-
* @param plugins A list of plugins to initialize with Capacitor
|
|
51
|
-
* @param config An instance of a Capacitor Configuration to use. If null, will load from file
|
|
52
|
-
*/
|
|
53
|
-
@Deprecated
|
|
54
|
-
protected void init(Bundle savedInstanceState, List<Class<? extends Plugin>> plugins, CapConfig config) {
|
|
55
|
-
this.initialPlugins = plugins;
|
|
56
|
-
this.config = config;
|
|
29
|
+
PluginManager loader = new PluginManager(getAssets());
|
|
57
30
|
|
|
58
|
-
|
|
59
|
-
|
|
31
|
+
try {
|
|
32
|
+
bridgeBuilder.addPlugins(loader.loadPluginClasses());
|
|
33
|
+
} catch (PluginLoadException ex) {
|
|
34
|
+
Logger.error("Error loading plugins.", ex);
|
|
35
|
+
}
|
|
60
36
|
|
|
61
|
-
/**
|
|
62
|
-
* @deprecated This method should not be called manually.
|
|
63
|
-
*/
|
|
64
|
-
@Deprecated
|
|
65
|
-
protected void load(Bundle savedInstanceState) {
|
|
66
37
|
this.load();
|
|
67
38
|
}
|
|
68
39
|
|
|
69
|
-
|
|
40
|
+
protected void load() {
|
|
70
41
|
Logger.debug("Starting BridgeActivity");
|
|
71
42
|
|
|
72
43
|
bridge = bridgeBuilder.addPlugins(initialPlugins).setConfig(config).create();
|
|
@@ -96,20 +67,6 @@ public class BridgeActivity extends AppCompatActivity {
|
|
|
96
67
|
@Override
|
|
97
68
|
public void onStart() {
|
|
98
69
|
super.onStart();
|
|
99
|
-
|
|
100
|
-
// Preferred behavior: init() was not called, so we construct the bridge with auto-loaded plugins.
|
|
101
|
-
if (bridge == null) {
|
|
102
|
-
PluginManager loader = new PluginManager(getAssets());
|
|
103
|
-
|
|
104
|
-
try {
|
|
105
|
-
bridgeBuilder.addPlugins(loader.loadPluginClasses());
|
|
106
|
-
} catch (PluginLoadException ex) {
|
|
107
|
-
Logger.error("Error loading plugins.", ex);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
this.load();
|
|
111
|
-
}
|
|
112
|
-
|
|
113
70
|
activityDepth++;
|
|
114
71
|
this.bridge.onStart();
|
|
115
72
|
Logger.debug("App started");
|
|
@@ -147,7 +147,6 @@ public class BridgeWebChromeClient extends WebChromeClient {
|
|
|
147
147
|
AlertDialog.Builder builder = new AlertDialog.Builder(view.getContext());
|
|
148
148
|
builder
|
|
149
149
|
.setMessage(message)
|
|
150
|
-
.setTitle("Alert")
|
|
151
150
|
.setPositiveButton(
|
|
152
151
|
"OK",
|
|
153
152
|
(dialog, buttonIndex) -> {
|
|
@@ -187,7 +186,6 @@ public class BridgeWebChromeClient extends WebChromeClient {
|
|
|
187
186
|
|
|
188
187
|
builder
|
|
189
188
|
.setMessage(message)
|
|
190
|
-
.setTitle("Confirm")
|
|
191
189
|
.setPositiveButton(
|
|
192
190
|
"OK",
|
|
193
191
|
(dialog, buttonIndex) -> {
|
|
@@ -236,7 +234,6 @@ public class BridgeWebChromeClient extends WebChromeClient {
|
|
|
236
234
|
|
|
237
235
|
builder
|
|
238
236
|
.setMessage(message)
|
|
239
|
-
.setTitle("Prompt")
|
|
240
237
|
.setView(input)
|
|
241
238
|
.setPositiveButton(
|
|
242
239
|
"OK",
|
|
@@ -286,8 +283,10 @@ public class BridgeWebChromeClient extends WebChromeClient {
|
|
|
286
283
|
callback.invoke(origin, true, false);
|
|
287
284
|
} else {
|
|
288
285
|
final String[] coarsePermission = { Manifest.permission.ACCESS_COARSE_LOCATION };
|
|
289
|
-
|
|
290
|
-
|
|
286
|
+
if (
|
|
287
|
+
Build.VERSION.SDK_INT >= Build.VERSION_CODES.S &&
|
|
288
|
+
PermissionHelper.hasPermissions(bridge.getContext(), coarsePermission)
|
|
289
|
+
) {
|
|
291
290
|
callback.invoke(origin, true, false);
|
|
292
291
|
} else {
|
|
293
292
|
callback.invoke(origin, false, false);
|
|
@@ -28,6 +28,7 @@ public class BridgeWebViewClient extends WebViewClient {
|
|
|
28
28
|
return bridge.launchIntent(url);
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
@Deprecated
|
|
31
32
|
@Override
|
|
32
33
|
public boolean shouldOverrideUrlLoading(WebView view, String url) {
|
|
33
34
|
return bridge.launchIntent(Uri.parse(url));
|
|
@@ -55,6 +56,11 @@ public class BridgeWebViewClient extends WebViewClient {
|
|
|
55
56
|
listener.onReceivedError(view);
|
|
56
57
|
}
|
|
57
58
|
}
|
|
59
|
+
|
|
60
|
+
String errorPath = bridge.getErrorUrl();
|
|
61
|
+
if (errorPath != null && request.isForMainFrame()) {
|
|
62
|
+
view.loadUrl(errorPath);
|
|
63
|
+
}
|
|
58
64
|
}
|
|
59
65
|
|
|
60
66
|
@Override
|
|
@@ -80,5 +86,10 @@ public class BridgeWebViewClient extends WebViewClient {
|
|
|
80
86
|
listener.onReceivedHttpError(view);
|
|
81
87
|
}
|
|
82
88
|
}
|
|
89
|
+
|
|
90
|
+
String errorPath = bridge.getErrorUrl();
|
|
91
|
+
if (errorPath != null && request.isForMainFrame()) {
|
|
92
|
+
view.loadUrl(errorPath);
|
|
93
|
+
}
|
|
83
94
|
}
|
|
84
95
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
package com.getcapacitor;
|
|
2
2
|
|
|
3
3
|
import static com.getcapacitor.Bridge.CAPACITOR_HTTP_SCHEME;
|
|
4
|
+
import static com.getcapacitor.Bridge.DEFAULT_ANDROID_WEBVIEW_VERSION;
|
|
5
|
+
import static com.getcapacitor.Bridge.MINIMUM_ANDROID_WEBVIEW_VERSION;
|
|
4
6
|
import static com.getcapacitor.FileUtils.readFile;
|
|
5
7
|
|
|
6
8
|
import android.content.Context;
|
|
@@ -9,8 +11,10 @@ import android.content.res.AssetManager;
|
|
|
9
11
|
import androidx.annotation.Nullable;
|
|
10
12
|
import com.getcapacitor.util.JSONUtils;
|
|
11
13
|
import java.io.IOException;
|
|
14
|
+
import java.util.Arrays;
|
|
12
15
|
import java.util.HashMap;
|
|
13
16
|
import java.util.Iterator;
|
|
17
|
+
import java.util.List;
|
|
14
18
|
import java.util.Locale;
|
|
15
19
|
import java.util.Map;
|
|
16
20
|
import org.json.JSONException;
|
|
@@ -40,6 +44,9 @@ public class CapConfig {
|
|
|
40
44
|
private boolean captureInput = false;
|
|
41
45
|
private boolean webContentsDebuggingEnabled = false;
|
|
42
46
|
private boolean loggingEnabled = true;
|
|
47
|
+
private boolean initialFocus = true;
|
|
48
|
+
private int minWebViewVersion = DEFAULT_ANDROID_WEBVIEW_VERSION;
|
|
49
|
+
private String errorPath;
|
|
43
50
|
|
|
44
51
|
// Embedded
|
|
45
52
|
private String startPath;
|
|
@@ -105,7 +112,11 @@ public class CapConfig {
|
|
|
105
112
|
this.html5mode = builder.html5mode;
|
|
106
113
|
this.serverUrl = builder.serverUrl;
|
|
107
114
|
this.hostname = builder.hostname;
|
|
108
|
-
|
|
115
|
+
|
|
116
|
+
if (this.validateScheme(builder.androidScheme)) {
|
|
117
|
+
this.androidScheme = builder.androidScheme;
|
|
118
|
+
}
|
|
119
|
+
|
|
109
120
|
this.allowNavigation = builder.allowNavigation;
|
|
110
121
|
|
|
111
122
|
// Android Config
|
|
@@ -116,6 +127,9 @@ public class CapConfig {
|
|
|
116
127
|
this.captureInput = builder.captureInput;
|
|
117
128
|
this.webContentsDebuggingEnabled = builder.webContentsDebuggingEnabled;
|
|
118
129
|
this.loggingEnabled = builder.loggingEnabled;
|
|
130
|
+
this.initialFocus = builder.initialFocus;
|
|
131
|
+
this.minWebViewVersion = builder.minWebViewVersion;
|
|
132
|
+
this.errorPath = builder.errorPath;
|
|
119
133
|
|
|
120
134
|
// Embedded
|
|
121
135
|
this.startPath = builder.startPath;
|
|
@@ -148,7 +162,13 @@ public class CapConfig {
|
|
|
148
162
|
html5mode = JSONUtils.getBoolean(configJSON, "server.html5mode", html5mode);
|
|
149
163
|
serverUrl = JSONUtils.getString(configJSON, "server.url", null);
|
|
150
164
|
hostname = JSONUtils.getString(configJSON, "server.hostname", hostname);
|
|
151
|
-
|
|
165
|
+
errorPath = JSONUtils.getString(configJSON, "server.errorPath", null);
|
|
166
|
+
|
|
167
|
+
String configSchema = JSONUtils.getString(configJSON, "server.androidScheme", androidScheme);
|
|
168
|
+
if (this.validateScheme(configSchema)) {
|
|
169
|
+
androidScheme = configSchema;
|
|
170
|
+
}
|
|
171
|
+
|
|
152
172
|
allowNavigation = JSONUtils.getArray(configJSON, "server.allowNavigation", null);
|
|
153
173
|
|
|
154
174
|
// Android
|
|
@@ -164,6 +184,7 @@ public class CapConfig {
|
|
|
164
184
|
"android.allowMixedContent",
|
|
165
185
|
JSONUtils.getBoolean(configJSON, "allowMixedContent", allowMixedContent)
|
|
166
186
|
);
|
|
187
|
+
minWebViewVersion = JSONUtils.getInt(configJSON, "android.minWebViewVersion", DEFAULT_ANDROID_WEBVIEW_VERSION);
|
|
167
188
|
captureInput = JSONUtils.getBoolean(configJSON, "android.captureInput", captureInput);
|
|
168
189
|
webContentsDebuggingEnabled = JSONUtils.getBoolean(configJSON, "android.webContentsDebuggingEnabled", isDebug);
|
|
169
190
|
|
|
@@ -187,10 +208,22 @@ public class CapConfig {
|
|
|
187
208
|
loggingEnabled = isDebug;
|
|
188
209
|
}
|
|
189
210
|
|
|
211
|
+
initialFocus = JSONUtils.getBoolean(configJSON, "android.initialFocus", initialFocus);
|
|
212
|
+
|
|
190
213
|
// Plugins
|
|
191
214
|
pluginsConfiguration = deserializePluginsConfig(JSONUtils.getObject(configJSON, "plugins"));
|
|
192
215
|
}
|
|
193
216
|
|
|
217
|
+
private boolean validateScheme(String scheme) {
|
|
218
|
+
List<String> invalidSchemes = Arrays.asList("file", "ftp", "ftps", "ws", "wss", "about", "blob", "data");
|
|
219
|
+
if (invalidSchemes.contains(scheme)) {
|
|
220
|
+
Logger.warn(scheme + " is not an allowed scheme. Defaulting to http.");
|
|
221
|
+
return false;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
return true;
|
|
225
|
+
}
|
|
226
|
+
|
|
194
227
|
public boolean isHTML5Mode() {
|
|
195
228
|
return html5mode;
|
|
196
229
|
}
|
|
@@ -199,6 +232,10 @@ public class CapConfig {
|
|
|
199
232
|
return serverUrl;
|
|
200
233
|
}
|
|
201
234
|
|
|
235
|
+
public String getErrorPath() {
|
|
236
|
+
return errorPath;
|
|
237
|
+
}
|
|
238
|
+
|
|
202
239
|
public String getHostname() {
|
|
203
240
|
return hostname;
|
|
204
241
|
}
|
|
@@ -243,6 +280,19 @@ public class CapConfig {
|
|
|
243
280
|
return loggingEnabled;
|
|
244
281
|
}
|
|
245
282
|
|
|
283
|
+
public boolean isInitialFocus() {
|
|
284
|
+
return initialFocus;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
public int getMinWebViewVersion() {
|
|
288
|
+
if (minWebViewVersion < MINIMUM_ANDROID_WEBVIEW_VERSION) {
|
|
289
|
+
Logger.warn("Specified minimum webview version is too low, defaulting to " + MINIMUM_ANDROID_WEBVIEW_VERSION);
|
|
290
|
+
return MINIMUM_ANDROID_WEBVIEW_VERSION;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
return minWebViewVersion;
|
|
294
|
+
}
|
|
295
|
+
|
|
246
296
|
public PluginConfig getPluginConfiguration(String pluginId) {
|
|
247
297
|
PluginConfig pluginConfig = pluginsConfiguration.get(pluginId);
|
|
248
298
|
if (pluginConfig == null) {
|
|
@@ -386,6 +436,7 @@ public class CapConfig {
|
|
|
386
436
|
// Server Config Values
|
|
387
437
|
private boolean html5mode = true;
|
|
388
438
|
private String serverUrl;
|
|
439
|
+
private String errorPath;
|
|
389
440
|
private String hostname = "localhost";
|
|
390
441
|
private String androidScheme = CAPACITOR_HTTP_SCHEME;
|
|
391
442
|
private String[] allowNavigation;
|
|
@@ -398,6 +449,8 @@ public class CapConfig {
|
|
|
398
449
|
private boolean captureInput = false;
|
|
399
450
|
private Boolean webContentsDebuggingEnabled = null;
|
|
400
451
|
private boolean loggingEnabled = true;
|
|
452
|
+
private boolean initialFocus = false;
|
|
453
|
+
private int minWebViewVersion = DEFAULT_ANDROID_WEBVIEW_VERSION;
|
|
401
454
|
|
|
402
455
|
// Embedded
|
|
403
456
|
private String startPath = null;
|
|
@@ -442,6 +495,11 @@ public class CapConfig {
|
|
|
442
495
|
return this;
|
|
443
496
|
}
|
|
444
497
|
|
|
498
|
+
public Builder setErrorPath(String errorPath) {
|
|
499
|
+
this.errorPath = errorPath;
|
|
500
|
+
return this;
|
|
501
|
+
}
|
|
502
|
+
|
|
445
503
|
public Builder setHostname(String hostname) {
|
|
446
504
|
this.hostname = hostname;
|
|
447
505
|
return this;
|
|
@@ -496,5 +554,10 @@ public class CapConfig {
|
|
|
496
554
|
this.loggingEnabled = enabled;
|
|
497
555
|
return this;
|
|
498
556
|
}
|
|
557
|
+
|
|
558
|
+
public Builder setInitialFocus(boolean focus) {
|
|
559
|
+
this.initialFocus = focus;
|
|
560
|
+
return this;
|
|
561
|
+
}
|
|
499
562
|
}
|
|
500
563
|
}
|
|
@@ -30,6 +30,7 @@ public class CapacitorWebView extends WebView {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
@Override
|
|
33
|
+
@SuppressWarnings("deprecation")
|
|
33
34
|
public boolean dispatchKeyEvent(KeyEvent event) {
|
|
34
35
|
if (event.getAction() == KeyEvent.ACTION_MULTIPLE) {
|
|
35
36
|
evaluateJavascript("document.activeElement.value = document.activeElement.value + '" + event.getCharacters() + "';", null);
|
|
@@ -77,7 +77,7 @@ public class FileUtils {
|
|
|
77
77
|
final String type = split[0];
|
|
78
78
|
|
|
79
79
|
if ("primary".equalsIgnoreCase(type)) {
|
|
80
|
-
return
|
|
80
|
+
return legacyPrimaryPath(split[1]);
|
|
81
81
|
} else {
|
|
82
82
|
final int splitIndex = docId.indexOf(':', 1);
|
|
83
83
|
final String tag = docId.substring(0, splitIndex);
|
|
@@ -136,6 +136,11 @@ public class FileUtils {
|
|
|
136
136
|
return null;
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
+
@SuppressWarnings("deprecation")
|
|
140
|
+
private static String legacyPrimaryPath(String pathPart) {
|
|
141
|
+
return Environment.getExternalStorageDirectory() + "/" + pathPart;
|
|
142
|
+
}
|
|
143
|
+
|
|
139
144
|
/**
|
|
140
145
|
* Read a plaintext file.
|
|
141
146
|
*
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
package com.getcapacitor;
|
|
2
2
|
|
|
3
|
+
import android.net.Uri;
|
|
3
4
|
import android.webkit.JavascriptInterface;
|
|
4
5
|
import android.webkit.WebView;
|
|
6
|
+
import androidx.webkit.JavaScriptReplyProxy;
|
|
7
|
+
import androidx.webkit.WebMessageCompat;
|
|
8
|
+
import androidx.webkit.WebViewCompat;
|
|
9
|
+
import androidx.webkit.WebViewFeature;
|
|
5
10
|
import org.apache.cordova.PluginManager;
|
|
6
11
|
|
|
7
12
|
/**
|
|
@@ -13,13 +18,31 @@ public class MessageHandler {
|
|
|
13
18
|
private Bridge bridge;
|
|
14
19
|
private WebView webView;
|
|
15
20
|
private PluginManager cordovaPluginManager;
|
|
21
|
+
private JavaScriptReplyProxy javaScriptReplyProxy;
|
|
16
22
|
|
|
17
23
|
public MessageHandler(Bridge bridge, WebView webView, PluginManager cordovaPluginManager) {
|
|
18
24
|
this.bridge = bridge;
|
|
19
25
|
this.webView = webView;
|
|
20
26
|
this.cordovaPluginManager = cordovaPluginManager;
|
|
21
27
|
|
|
22
|
-
|
|
28
|
+
WebViewCompat.WebMessageListener capListener = (view, message, sourceOrigin, isMainFrame, replyProxy) -> {
|
|
29
|
+
if (isMainFrame) {
|
|
30
|
+
postMessage(message.getData());
|
|
31
|
+
javaScriptReplyProxy = replyProxy;
|
|
32
|
+
} else {
|
|
33
|
+
Logger.warn("Plugin execution is allowed in Main Frame only");
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
if (WebViewFeature.isFeatureSupported(WebViewFeature.WEB_MESSAGE_LISTENER)) {
|
|
38
|
+
try {
|
|
39
|
+
WebViewCompat.addWebMessageListener(webView, "androidBridge", bridge.getAllowedOriginRules(), capListener);
|
|
40
|
+
} catch (Exception ex) {
|
|
41
|
+
webView.addJavascriptInterface(this, "androidBridge");
|
|
42
|
+
}
|
|
43
|
+
} else {
|
|
44
|
+
webView.addJavascriptInterface(this, "androidBridge");
|
|
45
|
+
}
|
|
23
46
|
}
|
|
24
47
|
|
|
25
48
|
/**
|
|
@@ -100,9 +123,13 @@ public class MessageHandler {
|
|
|
100
123
|
|
|
101
124
|
boolean isValidCallbackId = !call.getCallbackId().equals(PluginCall.CALLBACK_ID_DANGLING);
|
|
102
125
|
if (isValidCallbackId) {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
126
|
+
if (WebViewFeature.isFeatureSupported(WebViewFeature.WEB_MESSAGE_LISTENER) && javaScriptReplyProxy != null) {
|
|
127
|
+
javaScriptReplyProxy.postMessage(data.toString());
|
|
128
|
+
} else {
|
|
129
|
+
final String runScript = "window.Capacitor.fromNative(" + data.toString() + ")";
|
|
130
|
+
final WebView webView = this.webView;
|
|
131
|
+
webView.post(() -> webView.evaluateJavascript(runScript, null));
|
|
132
|
+
}
|
|
106
133
|
} else {
|
|
107
134
|
bridge.getApp().fireRestoredResult(data);
|
|
108
135
|
}
|
|
@@ -745,9 +745,10 @@ public class Plugin {
|
|
|
745
745
|
* @param call
|
|
746
746
|
*/
|
|
747
747
|
@SuppressWarnings("unused")
|
|
748
|
-
@PluginMethod(returnType = PluginMethod.
|
|
748
|
+
@PluginMethod(returnType = PluginMethod.RETURN_PROMISE)
|
|
749
749
|
public void removeAllListeners(PluginCall call) {
|
|
750
750
|
eventListeners.clear();
|
|
751
|
+
call.resolve();
|
|
751
752
|
}
|
|
752
753
|
|
|
753
754
|
/**
|
|
@@ -788,15 +789,7 @@ public class Plugin {
|
|
|
788
789
|
public void requestPermissions(PluginCall call) {
|
|
789
790
|
CapacitorPlugin annotation = handle.getPluginAnnotation();
|
|
790
791
|
if (annotation == null) {
|
|
791
|
-
|
|
792
|
-
NativePlugin legacyAnnotation = this.handle.getLegacyPluginAnnotation();
|
|
793
|
-
String[] perms = legacyAnnotation.permissions();
|
|
794
|
-
if (perms.length > 0) {
|
|
795
|
-
saveCall(call);
|
|
796
|
-
pluginRequestPermissions(perms, legacyAnnotation.permissionRequestCode());
|
|
797
|
-
} else {
|
|
798
|
-
call.resolve();
|
|
799
|
-
}
|
|
792
|
+
handleLegacyPermission(call);
|
|
800
793
|
} else {
|
|
801
794
|
// handle permission requests for plugins defined with @CapacitorPlugin (since 3.0.0)
|
|
802
795
|
String[] permAliases = null;
|
|
@@ -862,6 +855,19 @@ public class Plugin {
|
|
|
862
855
|
}
|
|
863
856
|
}
|
|
864
857
|
|
|
858
|
+
@SuppressWarnings("deprecation")
|
|
859
|
+
private void handleLegacyPermission(PluginCall call) {
|
|
860
|
+
// handle permission requests for plugins defined with @NativePlugin (prior to 3.0.0)
|
|
861
|
+
NativePlugin legacyAnnotation = this.handle.getLegacyPluginAnnotation();
|
|
862
|
+
String[] perms = legacyAnnotation.permissions();
|
|
863
|
+
if (perms.length > 0) {
|
|
864
|
+
saveCall(call);
|
|
865
|
+
pluginRequestPermissions(perms, legacyAnnotation.permissionRequestCode());
|
|
866
|
+
} else {
|
|
867
|
+
call.resolve();
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
|
|
865
871
|
/**
|
|
866
872
|
* Handle request permissions result. A plugin using the deprecated {@link NativePlugin}
|
|
867
873
|
* should override this to handle the result, or this method will handle the result
|
|
@@ -96,7 +96,7 @@ public class PluginCall {
|
|
|
96
96
|
*/
|
|
97
97
|
@Deprecated
|
|
98
98
|
public void error(String msg, Exception ex) {
|
|
99
|
-
reject(msg,
|
|
99
|
+
reject(msg, ex);
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
/**
|
|
@@ -114,10 +114,10 @@ public class PluginCall {
|
|
|
114
114
|
*/
|
|
115
115
|
@Deprecated
|
|
116
116
|
public void error(String msg) {
|
|
117
|
-
reject(msg
|
|
117
|
+
reject(msg);
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
public void reject(String msg, String code, Exception ex) {
|
|
120
|
+
public void reject(String msg, String code, Exception ex, JSObject data) {
|
|
121
121
|
PluginResult errorResult = new PluginResult();
|
|
122
122
|
|
|
123
123
|
if (ex != null) {
|
|
@@ -127,23 +127,42 @@ public class PluginCall {
|
|
|
127
127
|
try {
|
|
128
128
|
errorResult.put("message", msg);
|
|
129
129
|
errorResult.put("code", code);
|
|
130
|
+
if (null != data) {
|
|
131
|
+
errorResult.put("data", data);
|
|
132
|
+
}
|
|
130
133
|
} catch (Exception jsonEx) {
|
|
131
|
-
Logger.error(Logger.tags("Plugin"), jsonEx.getMessage(),
|
|
134
|
+
Logger.error(Logger.tags("Plugin"), jsonEx.getMessage(), jsonEx);
|
|
132
135
|
}
|
|
133
136
|
|
|
134
137
|
this.msgHandler.sendResponseMessage(this, null, errorResult);
|
|
135
138
|
}
|
|
136
139
|
|
|
140
|
+
public void reject(String msg, Exception ex, JSObject data) {
|
|
141
|
+
reject(msg, null, ex, data);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
public void reject(String msg, String code, JSObject data) {
|
|
145
|
+
reject(msg, code, null, data);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
public void reject(String msg, String code, Exception ex) {
|
|
149
|
+
reject(msg, code, ex, null);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
public void reject(String msg, JSObject data) {
|
|
153
|
+
reject(msg, null, null, data);
|
|
154
|
+
}
|
|
155
|
+
|
|
137
156
|
public void reject(String msg, Exception ex) {
|
|
138
|
-
reject(msg, null, ex);
|
|
157
|
+
reject(msg, null, ex, null);
|
|
139
158
|
}
|
|
140
159
|
|
|
141
160
|
public void reject(String msg, String code) {
|
|
142
|
-
reject(msg, code, null);
|
|
161
|
+
reject(msg, code, null, null);
|
|
143
162
|
}
|
|
144
163
|
|
|
145
164
|
public void reject(String msg) {
|
|
146
|
-
reject(msg, null, null);
|
|
165
|
+
reject(msg, null, null, null);
|
|
147
166
|
}
|
|
148
167
|
|
|
149
168
|
public void unimplemented() {
|
|
@@ -151,7 +170,7 @@ public class PluginCall {
|
|
|
151
170
|
}
|
|
152
171
|
|
|
153
172
|
public void unimplemented(String msg) {
|
|
154
|
-
reject(msg, "UNIMPLEMENTED", null);
|
|
173
|
+
reject(msg, "UNIMPLEMENTED", null, null);
|
|
155
174
|
}
|
|
156
175
|
|
|
157
176
|
public void unavailable() {
|
|
@@ -159,7 +178,7 @@ public class PluginCall {
|
|
|
159
178
|
}
|
|
160
179
|
|
|
161
180
|
public void unavailable(String msg) {
|
|
162
|
-
reject(msg, "UNAVAILABLE", null);
|
|
181
|
+
reject(msg, "UNAVAILABLE", null, null);
|
|
163
182
|
}
|
|
164
183
|
|
|
165
184
|
public String getPluginId() {
|
|
@@ -20,11 +20,14 @@ public class PluginHandle {
|
|
|
20
20
|
|
|
21
21
|
private final String pluginId;
|
|
22
22
|
|
|
23
|
+
@SuppressWarnings("deprecation")
|
|
23
24
|
private NativePlugin legacyPluginAnnotation;
|
|
25
|
+
|
|
24
26
|
private CapacitorPlugin pluginAnnotation;
|
|
25
27
|
|
|
26
28
|
private Plugin instance;
|
|
27
29
|
|
|
30
|
+
@SuppressWarnings("deprecation")
|
|
28
31
|
public PluginHandle(Bridge bridge, Class<? extends Plugin> pluginClass) throws InvalidPluginException, PluginLoadException {
|
|
29
32
|
this.bridge = bridge;
|
|
30
33
|
this.pluginClass = pluginClass;
|
|
@@ -67,6 +70,7 @@ public class PluginHandle {
|
|
|
67
70
|
return this.pluginId;
|
|
68
71
|
}
|
|
69
72
|
|
|
73
|
+
@SuppressWarnings("deprecation")
|
|
70
74
|
public NativePlugin getLegacyPluginAnnotation() {
|
|
71
75
|
return this.legacyPluginAnnotation;
|
|
72
76
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
package com.getcapacitor;
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* An data class used in conjunction with RouteProcessor.
|
|
5
|
+
*
|
|
6
|
+
* @see com.getcapacitor.RouteProcessor
|
|
7
|
+
*/
|
|
8
|
+
public class ProcessedRoute {
|
|
9
|
+
|
|
10
|
+
private String path;
|
|
11
|
+
private boolean isAsset;
|
|
12
|
+
|
|
13
|
+
public String getPath() {
|
|
14
|
+
return path;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
public void setPath(String path) {
|
|
18
|
+
this.path = path;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
public boolean isAsset() {
|
|
22
|
+
return isAsset;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
public void setAsset(boolean asset) {
|
|
26
|
+
isAsset = asset;
|
|
27
|
+
}
|
|
28
|
+
}
|