@capacitor/android 3.4.3 → 3.6.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/CHANGELOG.md +34 -0
- package/capacitor/src/main/java/com/getcapacitor/AppUUID.java +65 -0
- package/capacitor/src/main/java/com/getcapacitor/Bridge.java +22 -1
- package/capacitor/src/main/java/com/getcapacitor/BridgeActivity.java +5 -5
- package/capacitor/src/main/java/com/getcapacitor/CapConfig.java +14 -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 +20 -3
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,40 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [3.6.0](https://github.com/ionic-team/capacitor/compare/3.5.1...3.6.0) (2022-06-17)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* **android:** update support for Portals for Capacitor to include Live Updates ([#5660](https://github.com/ionic-team/capacitor/issues/5660)) ([62f0a5e](https://github.com/ionic-team/capacitor/commit/62f0a5eaa40776aad79dbf8f8c0900037d3cc97e))
|
|
12
|
+
* **iOS, Android:** add AppUUID Lib for plugins ([#5690](https://github.com/ionic-team/capacitor/issues/5690)) ([05e76cf](https://github.com/ionic-team/capacitor/commit/05e76cf526a44e07fa75f9482fa2223a13918638))
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
## [3.5.1](https://github.com/ionic-team/capacitor/compare/3.5.0...3.5.1) (2022-05-04)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### Bug Fixes
|
|
22
|
+
|
|
23
|
+
* **android:** move initialFocus on webview into config ([#5579](https://github.com/ionic-team/capacitor/issues/5579)) ([8b4e861](https://github.com/ionic-team/capacitor/commit/8b4e861514b0fbe08e9296f49c280234f54742e1))
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# [3.5.0](https://github.com/ionic-team/capacitor/compare/3.4.3...3.5.0) (2022-04-22)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
### Features
|
|
33
|
+
|
|
34
|
+
* **android:** Add overridable routing for WebViewLocalServer ([#5553](https://github.com/ionic-team/capacitor/issues/5553)) ([3bb288e](https://github.com/ionic-team/capacitor/commit/3bb288e848c5c0e49c1e58c0782e0b1ffd7b1f31))
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
6
40
|
## [3.4.3](https://github.com/ionic-team/capacitor/compare/3.4.2...3.4.3) (2022-03-04)
|
|
7
41
|
|
|
8
42
|
**Note:** Version bump only for package @capacitor/android
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
package com.getcapacitor;
|
|
2
|
+
|
|
3
|
+
import android.content.Context;
|
|
4
|
+
import android.content.SharedPreferences;
|
|
5
|
+
import androidx.appcompat.app.AppCompatActivity;
|
|
6
|
+
import java.nio.charset.StandardCharsets;
|
|
7
|
+
import java.security.MessageDigest;
|
|
8
|
+
import java.security.NoSuchAlgorithmException;
|
|
9
|
+
import java.util.Objects;
|
|
10
|
+
import java.util.UUID;
|
|
11
|
+
|
|
12
|
+
public final class AppUUID {
|
|
13
|
+
|
|
14
|
+
private static final String KEY = "CapacitorAppUUID";
|
|
15
|
+
|
|
16
|
+
public static String getAppUUID(AppCompatActivity activity) throws Exception {
|
|
17
|
+
assertAppUUID(activity);
|
|
18
|
+
return readUUID(activity);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
public static void regenerateAppUUID(AppCompatActivity activity) throws Exception {
|
|
22
|
+
try {
|
|
23
|
+
String uuid = generateUUID();
|
|
24
|
+
writeUUID(activity, uuid);
|
|
25
|
+
} catch (NoSuchAlgorithmException ex) {
|
|
26
|
+
throw new Exception("Capacitor App UUID could not be generated.");
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
private static void assertAppUUID(AppCompatActivity activity) throws Exception {
|
|
31
|
+
String uuid = readUUID(activity);
|
|
32
|
+
if (uuid.equals("")) {
|
|
33
|
+
regenerateAppUUID(activity);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
private static String generateUUID() throws NoSuchAlgorithmException {
|
|
38
|
+
MessageDigest salt = MessageDigest.getInstance("SHA-256");
|
|
39
|
+
salt.update(UUID.randomUUID().toString().getBytes(StandardCharsets.UTF_8));
|
|
40
|
+
return bytesToHex(salt.digest());
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
private static String readUUID(AppCompatActivity activity) {
|
|
44
|
+
SharedPreferences sharedPref = activity.getPreferences(Context.MODE_PRIVATE);
|
|
45
|
+
return sharedPref.getString(KEY, "");
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
private static void writeUUID(AppCompatActivity activity, String uuid) {
|
|
49
|
+
SharedPreferences sharedPref = activity.getPreferences(Context.MODE_PRIVATE);
|
|
50
|
+
SharedPreferences.Editor editor = sharedPref.edit();
|
|
51
|
+
editor.putString(KEY, uuid);
|
|
52
|
+
editor.apply();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
private static String bytesToHex(byte[] bytes) {
|
|
56
|
+
byte[] HEX_ARRAY = "0123456789ABCDEF".getBytes(StandardCharsets.US_ASCII);
|
|
57
|
+
byte[] hexChars = new byte[bytes.length * 2];
|
|
58
|
+
for (int j = 0; j < bytes.length; j++) {
|
|
59
|
+
int v = bytes[j] & 0xFF;
|
|
60
|
+
hexChars[j * 2] = HEX_ARRAY[v >>> 4];
|
|
61
|
+
hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
|
|
62
|
+
}
|
|
63
|
+
return new String(hexChars, StandardCharsets.UTF_8);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -130,6 +130,9 @@ public class Bridge {
|
|
|
130
130
|
// A list of listeners that trigger when webView events occur
|
|
131
131
|
private List<WebViewListener> webViewListeners = new ArrayList<>();
|
|
132
132
|
|
|
133
|
+
// An interface to manipulate route resolving
|
|
134
|
+
private RouteProcessor routeProcessor;
|
|
135
|
+
|
|
133
136
|
/**
|
|
134
137
|
* Create the Bridge with a reference to the main {@link Activity} for the
|
|
135
138
|
* app, and a reference to the {@link WebView} our app will use.
|
|
@@ -444,7 +447,10 @@ public class Bridge {
|
|
|
444
447
|
Logger.debug("WebView background color not applied");
|
|
445
448
|
}
|
|
446
449
|
|
|
447
|
-
|
|
450
|
+
if (config.isInitialFocus()) {
|
|
451
|
+
webView.requestFocusFromTouch();
|
|
452
|
+
}
|
|
453
|
+
|
|
448
454
|
WebView.setWebContentsDebuggingEnabled(this.config.isWebContentsDebuggingEnabled());
|
|
449
455
|
}
|
|
450
456
|
|
|
@@ -1190,6 +1196,14 @@ public class Bridge {
|
|
|
1190
1196
|
this.webViewListeners = webViewListeners;
|
|
1191
1197
|
}
|
|
1192
1198
|
|
|
1199
|
+
RouteProcessor getRouteProcessor() {
|
|
1200
|
+
return routeProcessor;
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
void setRouteProcessor(RouteProcessor routeProcessor) {
|
|
1204
|
+
this.routeProcessor = routeProcessor;
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1193
1207
|
/**
|
|
1194
1208
|
* Add a listener that the WebViewClient can trigger on certain events.
|
|
1195
1209
|
* @param webViewListener A {@link WebViewListener} to add.
|
|
@@ -1213,6 +1227,7 @@ public class Bridge {
|
|
|
1213
1227
|
private List<Class<? extends Plugin>> plugins = new ArrayList<>();
|
|
1214
1228
|
private AppCompatActivity activity;
|
|
1215
1229
|
private Fragment fragment;
|
|
1230
|
+
private RouteProcessor routeProcessor;
|
|
1216
1231
|
private final List<WebViewListener> webViewListeners = new ArrayList<>();
|
|
1217
1232
|
|
|
1218
1233
|
public Builder(AppCompatActivity activity) {
|
|
@@ -1265,6 +1280,11 @@ public class Bridge {
|
|
|
1265
1280
|
return this;
|
|
1266
1281
|
}
|
|
1267
1282
|
|
|
1283
|
+
public Builder setRouteProcessor(RouteProcessor routeProcessor) {
|
|
1284
|
+
this.routeProcessor = routeProcessor;
|
|
1285
|
+
return this;
|
|
1286
|
+
}
|
|
1287
|
+
|
|
1268
1288
|
public Bridge create() {
|
|
1269
1289
|
// Cordova initialization
|
|
1270
1290
|
ConfigXmlParser parser = new ConfigXmlParser();
|
|
@@ -1288,6 +1308,7 @@ public class Bridge {
|
|
|
1288
1308
|
Bridge bridge = new Bridge(activity, fragment, webView, plugins, cordovaInterface, pluginManager, preferences, config);
|
|
1289
1309
|
bridge.setCordovaWebView(mockWebView);
|
|
1290
1310
|
bridge.setWebViewListeners(webViewListeners);
|
|
1311
|
+
bridge.setRouteProcessor(routeProcessor);
|
|
1291
1312
|
|
|
1292
1313
|
if (instanceState != null) {
|
|
1293
1314
|
bridge.restoreInstanceState(instanceState);
|
|
@@ -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) {
|
|
@@ -66,7 +66,7 @@ public class BridgeActivity extends AppCompatActivity {
|
|
|
66
66
|
this.load();
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
protected void load() {
|
|
70
70
|
Logger.debug("Starting BridgeActivity");
|
|
71
71
|
|
|
72
72
|
bridge = bridgeBuilder.addPlugins(initialPlugins).setConfig(config).create();
|
|
@@ -40,6 +40,7 @@ public class CapConfig {
|
|
|
40
40
|
private boolean captureInput = false;
|
|
41
41
|
private boolean webContentsDebuggingEnabled = false;
|
|
42
42
|
private boolean loggingEnabled = true;
|
|
43
|
+
private boolean initialFocus = true;
|
|
43
44
|
|
|
44
45
|
// Embedded
|
|
45
46
|
private String startPath;
|
|
@@ -116,6 +117,7 @@ public class CapConfig {
|
|
|
116
117
|
this.captureInput = builder.captureInput;
|
|
117
118
|
this.webContentsDebuggingEnabled = builder.webContentsDebuggingEnabled;
|
|
118
119
|
this.loggingEnabled = builder.loggingEnabled;
|
|
120
|
+
this.initialFocus = builder.initialFocus;
|
|
119
121
|
|
|
120
122
|
// Embedded
|
|
121
123
|
this.startPath = builder.startPath;
|
|
@@ -187,6 +189,8 @@ public class CapConfig {
|
|
|
187
189
|
loggingEnabled = isDebug;
|
|
188
190
|
}
|
|
189
191
|
|
|
192
|
+
initialFocus = JSONUtils.getBoolean(configJSON, "android.initialFocus", initialFocus);
|
|
193
|
+
|
|
190
194
|
// Plugins
|
|
191
195
|
pluginsConfiguration = deserializePluginsConfig(JSONUtils.getObject(configJSON, "plugins"));
|
|
192
196
|
}
|
|
@@ -243,6 +247,10 @@ public class CapConfig {
|
|
|
243
247
|
return loggingEnabled;
|
|
244
248
|
}
|
|
245
249
|
|
|
250
|
+
public boolean isInitialFocus() {
|
|
251
|
+
return initialFocus;
|
|
252
|
+
}
|
|
253
|
+
|
|
246
254
|
public PluginConfig getPluginConfiguration(String pluginId) {
|
|
247
255
|
PluginConfig pluginConfig = pluginsConfiguration.get(pluginId);
|
|
248
256
|
if (pluginConfig == null) {
|
|
@@ -398,6 +406,7 @@ public class CapConfig {
|
|
|
398
406
|
private boolean captureInput = false;
|
|
399
407
|
private Boolean webContentsDebuggingEnabled = null;
|
|
400
408
|
private boolean loggingEnabled = true;
|
|
409
|
+
private boolean initialFocus = false;
|
|
401
410
|
|
|
402
411
|
// Embedded
|
|
403
412
|
private String startPath = null;
|
|
@@ -496,5 +505,10 @@ public class CapConfig {
|
|
|
496
505
|
this.loggingEnabled = enabled;
|
|
497
506
|
return this;
|
|
498
507
|
}
|
|
508
|
+
|
|
509
|
+
public Builder setInitialFocus(boolean focus) {
|
|
510
|
+
this.initialFocus = focus;
|
|
511
|
+
return this;
|
|
512
|
+
}
|
|
499
513
|
}
|
|
500
514
|
}
|
|
@@ -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
|
+
}
|
|
@@ -24,7 +24,6 @@ import android.webkit.WebResourceResponse;
|
|
|
24
24
|
import java.io.IOException;
|
|
25
25
|
import java.io.InputStream;
|
|
26
26
|
import java.net.HttpURLConnection;
|
|
27
|
-
import java.net.SocketTimeoutException;
|
|
28
27
|
import java.net.URL;
|
|
29
28
|
import java.net.URLConnection;
|
|
30
29
|
import java.nio.charset.StandardCharsets;
|
|
@@ -256,6 +255,12 @@ public class WebViewLocalServer {
|
|
|
256
255
|
InputStream responseStream;
|
|
257
256
|
try {
|
|
258
257
|
String startPath = this.basePath + "/index.html";
|
|
258
|
+
if (bridge.getRouteProcessor() != null) {
|
|
259
|
+
ProcessedRoute processedRoute = bridge.getRouteProcessor().process(this.basePath, "/index.html");
|
|
260
|
+
startPath = processedRoute.getPath();
|
|
261
|
+
isAsset = processedRoute.isAsset();
|
|
262
|
+
}
|
|
263
|
+
|
|
259
264
|
if (isAsset) {
|
|
260
265
|
responseStream = protocolHandler.openAsset(startPath);
|
|
261
266
|
} else {
|
|
@@ -467,13 +472,25 @@ public class WebViewLocalServer {
|
|
|
467
472
|
public InputStream handle(Uri url) {
|
|
468
473
|
InputStream stream = null;
|
|
469
474
|
String path = url.getPath();
|
|
475
|
+
|
|
476
|
+
// Pass path to routeProcessor if present
|
|
477
|
+
RouteProcessor routeProcessor = bridge.getRouteProcessor();
|
|
478
|
+
if (routeProcessor != null) {
|
|
479
|
+
ProcessedRoute processedRoute = bridge.getRouteProcessor().process("", path);
|
|
480
|
+
path = processedRoute.getPath();
|
|
481
|
+
isAsset = processedRoute.isAsset();
|
|
482
|
+
}
|
|
483
|
+
|
|
470
484
|
try {
|
|
471
485
|
if (path.startsWith(capacitorContentStart)) {
|
|
472
486
|
stream = protocolHandler.openContentUrl(url);
|
|
473
|
-
} else if (path.startsWith(capacitorFileStart)
|
|
474
|
-
|
|
487
|
+
} else if (path.startsWith(capacitorFileStart)) {
|
|
488
|
+
stream = protocolHandler.openFile(path);
|
|
489
|
+
} else if (!isAsset) {
|
|
490
|
+
if (routeProcessor == null) {
|
|
475
491
|
path = basePath + url.getPath();
|
|
476
492
|
}
|
|
493
|
+
|
|
477
494
|
stream = protocolHandler.openFile(path);
|
|
478
495
|
} else {
|
|
479
496
|
stream = protocolHandler.openAsset(assetPath + path);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@capacitor/android",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.6.0",
|
|
4
4
|
"description": "Capacitor: Cross-platform apps with JavaScript and the web",
|
|
5
5
|
"homepage": "https://capacitorjs.com",
|
|
6
6
|
"author": "Ionic Team <hi@ionic.io> (https://ionic.io)",
|
|
@@ -22,10 +22,10 @@
|
|
|
22
22
|
"verify": "./gradlew clean lint build test -b capacitor/build.gradle"
|
|
23
23
|
},
|
|
24
24
|
"peerDependencies": {
|
|
25
|
-
"@capacitor/core": "^3.
|
|
25
|
+
"@capacitor/core": "^3.6.0"
|
|
26
26
|
},
|
|
27
27
|
"publishConfig": {
|
|
28
28
|
"access": "public"
|
|
29
29
|
},
|
|
30
|
-
"gitHead": "
|
|
30
|
+
"gitHead": "1e06a199a44bb5321f0fb48b5fbca961cc1dbb50"
|
|
31
31
|
}
|