@capacitor/android 4.0.0-alpha.2 → 4.0.0-nightly-ffa328d2.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 +62 -0
- package/capacitor/build.gradle +5 -5
- package/capacitor/src/main/java/com/getcapacitor/AppUUID.java +65 -0
- package/capacitor/src/main/java/com/getcapacitor/Bridge.java +41 -9
- package/capacitor/src/main/java/com/getcapacitor/BridgeActivity.java +11 -54
- package/capacitor/src/main/java/com/getcapacitor/BridgeWebChromeClient.java +0 -3
- package/capacitor/src/main/java/com/getcapacitor/BridgeWebViewClient.java +1 -0
- package/capacitor/src/main/java/com/getcapacitor/CapConfig.java +14 -0
- 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/Plugin.java +14 -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 +20 -3
- 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 +3 -3
- package/capacitor/src/main/res/drawable/ic_transparent.xml +0 -12
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,37 @@
|
|
|
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
|
+
# [4.0.0-beta.0](https://github.com/ionic-team/capacitor/compare/3.6.0...4.0.0-beta.0) (2022-06-17)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* **android:** make removeAllListeners return a promise ([#5527](https://github.com/ionic-team/capacitor/issues/5527)) ([6f4d858](https://github.com/ionic-team/capacitor/commit/6f4d858ea879d97109c0c7da2d664d04806adc2a))
|
|
12
|
+
* **android:** prevent app from loading if server.url is invalid ([d4a0dea](https://github.com/ionic-team/capacitor/commit/d4a0deaa37eda4476f0be030e266c2c1260fc6e8))
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
* **android:** don't allow server.androidScheme to be set to schemes handled by WebView ([01285ba](https://github.com/ionic-team/capacitor/commit/01285ba253d602b08a41240ad2ccf370730d51a3))
|
|
18
|
+
* **android:** set default targetSDK to 31 ([#5442](https://github.com/ionic-team/capacitor/issues/5442)) ([4442459](https://github.com/ionic-team/capacitor/commit/4442459b24cdbac25cb1e4de11583d22c21452b3))
|
|
19
|
+
* **android:** set default targetSDK to 32 ([#5611](https://github.com/ionic-team/capacitor/issues/5611)) ([416b966](https://github.com/ionic-team/capacitor/commit/416b9662fbf6233d23216c0c0441862603c3a723))
|
|
20
|
+
* **android:** Upgrade gradle to 7.4 ([#5445](https://github.com/ionic-team/capacitor/issues/5445)) ([28eaf18](https://github.com/ionic-team/capacitor/commit/28eaf1851fa7a912917dbb40c68fb4dd583d08ad))
|
|
21
|
+
* **android:** Use java 11 ([#5552](https://github.com/ionic-team/capacitor/issues/5552)) ([e47959f](https://github.com/ionic-team/capacitor/commit/e47959fcbd6a89b97b1275a5814fdb4e7ce30672))
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
# [3.6.0](https://github.com/ionic-team/capacitor/compare/3.5.1...3.6.0) (2022-06-17)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
### Features
|
|
31
|
+
|
|
32
|
+
* **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))
|
|
33
|
+
* **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))
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
6
37
|
# [4.0.0-alpha.2](https://github.com/ionic-team/capacitor/compare/3.4.1...4.0.0-alpha.2) (2022-05-12)
|
|
7
38
|
|
|
8
39
|
|
|
@@ -22,6 +53,25 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
|
|
22
53
|
|
|
23
54
|
|
|
24
55
|
|
|
56
|
+
## [3.5.1](https://github.com/ionic-team/capacitor/compare/3.5.0...3.5.1) (2022-05-04)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
### Bug Fixes
|
|
60
|
+
|
|
61
|
+
* **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))
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
# [3.5.0](https://github.com/ionic-team/capacitor/compare/3.4.3...3.5.0) (2022-04-22)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
### Features
|
|
71
|
+
|
|
72
|
+
* **android:** Add overridable routing for WebViewLocalServer ([#5553](https://github.com/ionic-team/capacitor/issues/5553)) ([3bb288e](https://github.com/ionic-team/capacitor/commit/3bb288e848c5c0e49c1e58c0782e0b1ffd7b1f31))
|
|
73
|
+
|
|
74
|
+
|
|
25
75
|
|
|
26
76
|
# [4.0.0-alpha.1](https://github.com/ionic-team/capacitor/compare/3.4.1...4.0.0-alpha.1) (2022-03-25)
|
|
27
77
|
|
|
@@ -33,6 +83,18 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
|
|
33
83
|
|
|
34
84
|
|
|
35
85
|
|
|
86
|
+
## [3.4.3](https://github.com/ionic-team/capacitor/compare/3.4.2...3.4.3) (2022-03-04)
|
|
87
|
+
|
|
88
|
+
**Note:** Version bump only for package @capacitor/android
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
## [3.4.2](https://github.com/ionic-team/capacitor/compare/3.4.1...3.4.2) (2022-03-03)
|
|
95
|
+
|
|
96
|
+
**Note:** Version bump only for package @capacitor/android
|
|
97
|
+
|
|
36
98
|
|
|
37
99
|
|
|
38
100
|
## [3.4.1](https://github.com/ionic-team/capacitor/compare/3.4.0...3.4.1) (2022-02-09)
|
package/capacitor/build.gradle
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
ext {
|
|
2
2
|
androidxActivityVersion = project.hasProperty('androidxActivityVersion') ? rootProject.ext.androidxActivityVersion : '1.4.0'
|
|
3
|
-
androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.4.
|
|
3
|
+
androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.4.2'
|
|
4
4
|
androidxCoordinatorLayoutVersion = project.hasProperty('androidxCoordinatorLayoutVersion') ? rootProject.ext.androidxCoordinatorLayoutVersion : '1.2.0'
|
|
5
|
-
androidxCoreVersion = project.hasProperty('androidxCoreVersion') ? rootProject.ext.androidxCoreVersion : '1.
|
|
5
|
+
androidxCoreVersion = project.hasProperty('androidxCoreVersion') ? rootProject.ext.androidxCoreVersion : '1.8.0'
|
|
6
6
|
androidxFragmentVersion = project.hasProperty('androidxFragmentVersion') ? rootProject.ext.androidxFragmentVersion : '1.4.1'
|
|
7
7
|
junitVersion = project.hasProperty('junitVersion') ? rootProject.ext.junitVersion : '4.13.2'
|
|
8
8
|
androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.1.3'
|
|
@@ -17,7 +17,7 @@ buildscript {
|
|
|
17
17
|
mavenCentral()
|
|
18
18
|
}
|
|
19
19
|
dependencies {
|
|
20
|
-
classpath 'com.android.tools.build:gradle:7.
|
|
20
|
+
classpath 'com.android.tools.build:gradle:7.2.1'
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
|
|
@@ -26,10 +26,10 @@ tasks.withType(Javadoc).all { enabled = false }
|
|
|
26
26
|
apply plugin: 'com.android.library'
|
|
27
27
|
|
|
28
28
|
android {
|
|
29
|
-
compileSdkVersion project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion :
|
|
29
|
+
compileSdkVersion project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 32
|
|
30
30
|
defaultConfig {
|
|
31
31
|
minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 22
|
|
32
|
-
targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion :
|
|
32
|
+
targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 32
|
|
33
33
|
versionCode 1
|
|
34
34
|
versionName "1.0"
|
|
35
35
|
consumerProguardFiles 'proguard-rules.pro'
|
|
@@ -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
|
+
}
|
|
@@ -22,6 +22,7 @@ import androidx.activity.result.contract.ActivityResultContract;
|
|
|
22
22
|
import androidx.annotation.NonNull;
|
|
23
23
|
import androidx.appcompat.app.AppCompatActivity;
|
|
24
24
|
import androidx.core.app.ActivityCompat;
|
|
25
|
+
import androidx.core.content.pm.PackageInfoCompat;
|
|
25
26
|
import androidx.fragment.app.Fragment;
|
|
26
27
|
import com.getcapacitor.android.R;
|
|
27
28
|
import com.getcapacitor.annotation.CapacitorPlugin;
|
|
@@ -130,6 +131,9 @@ public class Bridge {
|
|
|
130
131
|
// A list of listeners that trigger when webView events occur
|
|
131
132
|
private List<WebViewListener> webViewListeners = new ArrayList<>();
|
|
132
133
|
|
|
134
|
+
// An interface to manipulate route resolving
|
|
135
|
+
private RouteProcessor routeProcessor;
|
|
136
|
+
|
|
133
137
|
/**
|
|
134
138
|
* Create the Bridge with a reference to the main {@link Activity} for the
|
|
135
139
|
* app, and a reference to the {@link WebView} our app will use.
|
|
@@ -293,7 +297,7 @@ public class Bridge {
|
|
|
293
297
|
|
|
294
298
|
try {
|
|
295
299
|
PackageInfo pInfo = getContext().getPackageManager().getPackageInfo(getContext().getPackageName(), 0);
|
|
296
|
-
versionCode = Integer.toString(pInfo
|
|
300
|
+
versionCode = Integer.toString((int) PackageInfoCompat.getLongVersionCode(pInfo));
|
|
297
301
|
versionName = pInfo.versionName;
|
|
298
302
|
} catch (Exception ex) {
|
|
299
303
|
Logger.error("Unable to get package info", ex);
|
|
@@ -421,7 +425,6 @@ public class Bridge {
|
|
|
421
425
|
settings.setDomStorageEnabled(true);
|
|
422
426
|
settings.setGeolocationEnabled(true);
|
|
423
427
|
settings.setDatabaseEnabled(true);
|
|
424
|
-
settings.setAppCacheEnabled(true);
|
|
425
428
|
settings.setMediaPlaybackRequiresUserGesture(false);
|
|
426
429
|
settings.setJavaScriptCanOpenWindowsAutomatically(true);
|
|
427
430
|
if (this.config.isMixedContentAllowed()) {
|
|
@@ -447,7 +450,10 @@ public class Bridge {
|
|
|
447
450
|
Logger.debug("WebView background color not applied");
|
|
448
451
|
}
|
|
449
452
|
|
|
450
|
-
|
|
453
|
+
if (config.isInitialFocus()) {
|
|
454
|
+
webView.requestFocusFromTouch();
|
|
455
|
+
}
|
|
456
|
+
|
|
451
457
|
WebView.setWebContentsDebuggingEnabled(this.config.isWebContentsDebuggingEnabled());
|
|
452
458
|
}
|
|
453
459
|
|
|
@@ -472,6 +478,17 @@ public class Bridge {
|
|
|
472
478
|
}
|
|
473
479
|
}
|
|
474
480
|
|
|
481
|
+
@SuppressWarnings("deprecation")
|
|
482
|
+
private String getLegacyPluginName(Class<? extends Plugin> pluginClass) {
|
|
483
|
+
NativePlugin legacyPluginAnnotation = pluginClass.getAnnotation(NativePlugin.class);
|
|
484
|
+
if (legacyPluginAnnotation == null) {
|
|
485
|
+
Logger.error("Plugin doesn't have the @CapacitorPlugin annotation. Please add it");
|
|
486
|
+
return null;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
return legacyPluginAnnotation.name();
|
|
490
|
+
}
|
|
491
|
+
|
|
475
492
|
/**
|
|
476
493
|
* Register a plugin class
|
|
477
494
|
* @param pluginClass a class inheriting from Plugin
|
|
@@ -481,14 +498,10 @@ public class Bridge {
|
|
|
481
498
|
|
|
482
499
|
CapacitorPlugin pluginAnnotation = pluginClass.getAnnotation(CapacitorPlugin.class);
|
|
483
500
|
if (pluginAnnotation == null) {
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
if (legacyPluginAnnotation == null) {
|
|
487
|
-
Logger.error("Plugin doesn't have the @CapacitorPlugin annotation. Please add it");
|
|
501
|
+
pluginName = this.getLegacyPluginName(pluginClass);
|
|
502
|
+
if (pluginName == null) {
|
|
488
503
|
return;
|
|
489
504
|
}
|
|
490
|
-
|
|
491
|
-
pluginName = legacyPluginAnnotation.name();
|
|
492
505
|
} else {
|
|
493
506
|
pluginName = pluginAnnotation.name();
|
|
494
507
|
}
|
|
@@ -527,6 +540,7 @@ public class Bridge {
|
|
|
527
540
|
* @return
|
|
528
541
|
*/
|
|
529
542
|
@Deprecated
|
|
543
|
+
@SuppressWarnings("deprecation")
|
|
530
544
|
public PluginHandle getPluginWithRequestCode(int requestCode) {
|
|
531
545
|
for (PluginHandle handle : this.plugins.values()) {
|
|
532
546
|
int[] requestCodes;
|
|
@@ -842,6 +856,7 @@ public class Bridge {
|
|
|
842
856
|
}
|
|
843
857
|
|
|
844
858
|
@Deprecated
|
|
859
|
+
@SuppressWarnings("deprecation")
|
|
845
860
|
public void startActivityForPluginWithResult(PluginCall call, Intent intent, int requestCode) {
|
|
846
861
|
Logger.debug("Starting activity for result");
|
|
847
862
|
|
|
@@ -859,6 +874,7 @@ public class Bridge {
|
|
|
859
874
|
* @param grantResults the set of granted/denied permissions
|
|
860
875
|
* @return true if permission code was handled by a plugin explicitly, false if not
|
|
861
876
|
*/
|
|
877
|
+
@SuppressWarnings("deprecation")
|
|
862
878
|
boolean onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
|
|
863
879
|
PluginHandle plugin = getPluginWithRequestCode(requestCode);
|
|
864
880
|
|
|
@@ -998,6 +1014,7 @@ public class Bridge {
|
|
|
998
1014
|
* @param resultCode
|
|
999
1015
|
* @param data
|
|
1000
1016
|
*/
|
|
1017
|
+
@SuppressWarnings("deprecation")
|
|
1001
1018
|
boolean onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
1002
1019
|
PluginHandle plugin = getPluginWithRequestCode(requestCode);
|
|
1003
1020
|
|
|
@@ -1193,6 +1210,14 @@ public class Bridge {
|
|
|
1193
1210
|
this.webViewListeners = webViewListeners;
|
|
1194
1211
|
}
|
|
1195
1212
|
|
|
1213
|
+
RouteProcessor getRouteProcessor() {
|
|
1214
|
+
return routeProcessor;
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
void setRouteProcessor(RouteProcessor routeProcessor) {
|
|
1218
|
+
this.routeProcessor = routeProcessor;
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1196
1221
|
/**
|
|
1197
1222
|
* Add a listener that the WebViewClient can trigger on certain events.
|
|
1198
1223
|
* @param webViewListener A {@link WebViewListener} to add.
|
|
@@ -1216,6 +1241,7 @@ public class Bridge {
|
|
|
1216
1241
|
private List<Class<? extends Plugin>> plugins = new ArrayList<>();
|
|
1217
1242
|
private AppCompatActivity activity;
|
|
1218
1243
|
private Fragment fragment;
|
|
1244
|
+
private RouteProcessor routeProcessor;
|
|
1219
1245
|
private final List<WebViewListener> webViewListeners = new ArrayList<>();
|
|
1220
1246
|
|
|
1221
1247
|
public Builder(AppCompatActivity activity) {
|
|
@@ -1268,6 +1294,11 @@ public class Bridge {
|
|
|
1268
1294
|
return this;
|
|
1269
1295
|
}
|
|
1270
1296
|
|
|
1297
|
+
public Builder setRouteProcessor(RouteProcessor routeProcessor) {
|
|
1298
|
+
this.routeProcessor = routeProcessor;
|
|
1299
|
+
return this;
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1271
1302
|
public Bridge create() {
|
|
1272
1303
|
// Cordova initialization
|
|
1273
1304
|
ConfigXmlParser parser = new ConfigXmlParser();
|
|
@@ -1291,6 +1322,7 @@ public class Bridge {
|
|
|
1291
1322
|
Bridge bridge = new Bridge(activity, fragment, webView, plugins, cordovaInterface, pluginManager, preferences, config);
|
|
1292
1323
|
bridge.setCordovaWebView(mockWebView);
|
|
1293
1324
|
bridge.setWebViewListeners(webViewListeners);
|
|
1325
|
+
bridge.setRouteProcessor(routeProcessor);
|
|
1294
1326
|
|
|
1295
1327
|
if (instanceState != null) {
|
|
1296
1328
|
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) {
|
|
@@ -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",
|
|
@@ -42,6 +42,7 @@ public class CapConfig {
|
|
|
42
42
|
private boolean captureInput = false;
|
|
43
43
|
private boolean webContentsDebuggingEnabled = false;
|
|
44
44
|
private boolean loggingEnabled = true;
|
|
45
|
+
private boolean initialFocus = true;
|
|
45
46
|
|
|
46
47
|
// Embedded
|
|
47
48
|
private String startPath;
|
|
@@ -122,6 +123,7 @@ public class CapConfig {
|
|
|
122
123
|
this.captureInput = builder.captureInput;
|
|
123
124
|
this.webContentsDebuggingEnabled = builder.webContentsDebuggingEnabled;
|
|
124
125
|
this.loggingEnabled = builder.loggingEnabled;
|
|
126
|
+
this.initialFocus = builder.initialFocus;
|
|
125
127
|
|
|
126
128
|
// Embedded
|
|
127
129
|
this.startPath = builder.startPath;
|
|
@@ -198,6 +200,8 @@ public class CapConfig {
|
|
|
198
200
|
loggingEnabled = isDebug;
|
|
199
201
|
}
|
|
200
202
|
|
|
203
|
+
initialFocus = JSONUtils.getBoolean(configJSON, "android.initialFocus", initialFocus);
|
|
204
|
+
|
|
201
205
|
// Plugins
|
|
202
206
|
pluginsConfiguration = deserializePluginsConfig(JSONUtils.getObject(configJSON, "plugins"));
|
|
203
207
|
}
|
|
@@ -264,6 +268,10 @@ public class CapConfig {
|
|
|
264
268
|
return loggingEnabled;
|
|
265
269
|
}
|
|
266
270
|
|
|
271
|
+
public boolean isInitialFocus() {
|
|
272
|
+
return initialFocus;
|
|
273
|
+
}
|
|
274
|
+
|
|
267
275
|
public PluginConfig getPluginConfiguration(String pluginId) {
|
|
268
276
|
PluginConfig pluginConfig = pluginsConfiguration.get(pluginId);
|
|
269
277
|
if (pluginConfig == null) {
|
|
@@ -419,6 +427,7 @@ public class CapConfig {
|
|
|
419
427
|
private boolean captureInput = false;
|
|
420
428
|
private Boolean webContentsDebuggingEnabled = null;
|
|
421
429
|
private boolean loggingEnabled = true;
|
|
430
|
+
private boolean initialFocus = false;
|
|
422
431
|
|
|
423
432
|
// Embedded
|
|
424
433
|
private String startPath = null;
|
|
@@ -517,5 +526,10 @@ public class CapConfig {
|
|
|
517
526
|
this.loggingEnabled = enabled;
|
|
518
527
|
return this;
|
|
519
528
|
}
|
|
529
|
+
|
|
530
|
+
public Builder setInitialFocus(boolean focus) {
|
|
531
|
+
this.initialFocus = focus;
|
|
532
|
+
return this;
|
|
533
|
+
}
|
|
520
534
|
}
|
|
521
535
|
}
|
|
@@ -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
|
*
|
|
@@ -789,15 +789,7 @@ public class Plugin {
|
|
|
789
789
|
public void requestPermissions(PluginCall call) {
|
|
790
790
|
CapacitorPlugin annotation = handle.getPluginAnnotation();
|
|
791
791
|
if (annotation == null) {
|
|
792
|
-
|
|
793
|
-
NativePlugin legacyAnnotation = this.handle.getLegacyPluginAnnotation();
|
|
794
|
-
String[] perms = legacyAnnotation.permissions();
|
|
795
|
-
if (perms.length > 0) {
|
|
796
|
-
saveCall(call);
|
|
797
|
-
pluginRequestPermissions(perms, legacyAnnotation.permissionRequestCode());
|
|
798
|
-
} else {
|
|
799
|
-
call.resolve();
|
|
800
|
-
}
|
|
792
|
+
handleLegacyPermission(call);
|
|
801
793
|
} else {
|
|
802
794
|
// handle permission requests for plugins defined with @CapacitorPlugin (since 3.0.0)
|
|
803
795
|
String[] permAliases = null;
|
|
@@ -863,6 +855,19 @@ public class Plugin {
|
|
|
863
855
|
}
|
|
864
856
|
}
|
|
865
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
|
+
|
|
866
871
|
/**
|
|
867
872
|
* Handle request permissions result. A plugin using the deprecated {@link NativePlugin}
|
|
868
873
|
* should override this to handle the result, or this method will handle the result
|
|
@@ -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
|
+
}
|
|
@@ -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);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
-
<resources>
|
|
3
|
-
<color name="colorPrimary">#3F51B5</color>
|
|
4
|
-
<color name="colorPrimaryDark">#303F9F</color>
|
|
5
|
-
<color name="colorAccent">#FF4081</color>
|
|
2
|
+
<resources xmlns:tools="http://schemas.android.com/tools">
|
|
3
|
+
<color tools:ignore="UnusedResources" name="colorPrimary">#3F51B5</color>
|
|
4
|
+
<color tools:ignore="UnusedResources" name="colorPrimaryDark">#303F9F</color>
|
|
5
|
+
<color tools:ignore="UnusedResources" name="colorAccent">#FF4081</color>
|
|
6
6
|
</resources>
|
|
@@ -1,7 +1,2 @@
|
|
|
1
1
|
<resources>
|
|
2
|
-
<string name="app_name">CapacitorAndroid</string>
|
|
3
|
-
<string name="ok">OK</string>
|
|
4
|
-
<string name="picture">Picture</string>
|
|
5
|
-
<string name="request_permission">Allow this app to take pictures</string>
|
|
6
|
-
<string name="camera_error">Unable to use camera</string>
|
|
7
2
|
</resources>
|
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
<resources>
|
|
2
|
-
|
|
3
|
-
<!-- Base application theme. -->
|
|
4
|
-
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
|
5
|
-
<!-- Customize your theme here. -->
|
|
6
|
-
<item name="colorPrimary">@color/colorPrimary</item>
|
|
7
|
-
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
|
8
|
-
<item name="colorAccent">@color/colorAccent</item>
|
|
9
|
-
</style>
|
|
10
|
-
|
|
11
2
|
<style name="AppTheme.NoActionBar" parent="Theme.AppCompat.NoActionBar">
|
|
12
3
|
<item name="windowActionBar">false</item>
|
|
13
4
|
<item name="windowNoTitle">true</item>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@capacitor/android",
|
|
3
|
-
"version": "4.0.0-
|
|
3
|
+
"version": "4.0.0-nightly-ffa328d2.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": "^
|
|
25
|
+
"@capacitor/core": "^4.0.0-beta.0"
|
|
26
26
|
},
|
|
27
27
|
"publishConfig": {
|
|
28
28
|
"access": "public"
|
|
29
29
|
},
|
|
30
|
-
"gitHead": "
|
|
30
|
+
"gitHead": "ffa328d2fbd047f6e1c37b2819c57f27739222fd"
|
|
31
31
|
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
-
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
3
|
-
android:width="16dp"
|
|
4
|
-
android:height="16dp"
|
|
5
|
-
android:viewportHeight="108"
|
|
6
|
-
android:viewportWidth="108">
|
|
7
|
-
|
|
8
|
-
<path
|
|
9
|
-
android:width="1dp"
|
|
10
|
-
android:color="@android:color/transparent" />
|
|
11
|
-
|
|
12
|
-
</vector>
|