Compare commits

...

5 Commits

Author SHA1 Message Date
Manuel Beck
bc2d92e3d8 feat: improve web view detection on older android versions
- Generated-By: GPT-5.3-Codex, Visual Studio Code Copilot
2026-03-12 12:38:30 +01:00
Manuel Beck
2981046b5b feat: block futher loading, when web view is too old
- Generated-By: GPT-5.3-Codex, Visual Studio Code
2026-03-12 12:37:13 +01:00
Manuel Beck
d49d5c05d3 feat: add web view version check by preference AndroidMinimumWebViewVersion
- If preference `AndroidMinimumWebViewVersion` is set, it will check if the current installed web view suits the version. If not, an error message is shown and the app exists, after the user clicks on OK.
- The strings can be internationalized by adding a `strings.xml` with appropriates strings to the appropriate `values` directory.
- Generated-By: Claude Haiku 4.5, Visual Studio Code
2026-03-12 11:52:03 +01:00
エリス
c02d1b0331 chore(post-release): bump v15.0.1-dev.0 (#1899) 2026-03-06 16:55:03 +09:00
dependabot[bot]
31f3d57c8d chore(deps): bump minimatch (#1898)
Bumps  and [minimatch](https://github.com/isaacs/minimatch). These dependencies needed to be updated together.

Updates `minimatch` from 3.1.3 to 3.1.5
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.1.3...v3.1.5)

Updates `minimatch` from 9.0.6 to 9.0.9
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.1.3...v3.1.5)

Updates `minimatch` from 10.2.2 to 10.2.4
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.1.3...v3.1.5)

---
updated-dependencies:
- dependency-name: minimatch
  dependency-version: 3.1.5
  dependency-type: indirect
- dependency-name: minimatch
  dependency-version: 9.0.9
  dependency-type: indirect
- dependency-name: minimatch
  dependency-version: 10.2.4
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-28 12:16:16 -08:00
4 changed files with 175 additions and 16 deletions

View File

@@ -48,6 +48,10 @@ import androidx.core.splashscreen.SplashScreen;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.webkit.WebViewCompat;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
/**
* This class is the main Android activity that represents the Cordova
@@ -107,6 +111,11 @@ public class CordovaActivity extends AppCompatActivity {
private boolean canEdgeToEdge = false;
private boolean isFullScreen = false;
/**
* Flag set in {@link #checkWebViewVersion} indicating whether the WebView version
* is below the minimum required version specified in config.xml.
*/
private boolean isWebViewVersionBlocked = false;
/**
* Called when the activity is first created.
@@ -121,6 +130,9 @@ public class CordovaActivity extends AppCompatActivity {
// need to activate preferences before super.onCreate to avoid "requestFeature() must be called before adding content" exception
loadConfig();
// Check WebView version requirement
checkWebViewVersion();
canEdgeToEdge = preferences.getBoolean("AndroidEdgeToEdge", false)
&& Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM;
@@ -165,6 +177,10 @@ public class CordovaActivity extends AppCompatActivity {
}
protected void init() {
if (isWebViewVersionBlocked) {
return;
}
appView = makeWebView();
createViews();
if (!appView.isInitialized()) {
@@ -279,6 +295,10 @@ public class CordovaActivity extends AppCompatActivity {
* Load the url into the WebView.
*/
public void loadUrl(String url) {
if (isWebViewVersionBlocked) {
return;
}
if (appView == null) {
init();
}
@@ -588,6 +608,124 @@ public class CordovaActivity extends AppCompatActivity {
}
/**
* Check if the WebView version meets the minimum required version specified by
* preference `AndroidMinimumWebViewVersion` in config.xml.
* If not, display an error dialog and block the app from loading further.
*/
private void checkWebViewVersion() {
String minimumWebViewVersion = preferences.getString("AndroidMinimumWebViewVersion", null);
if (minimumWebViewVersion == null || minimumWebViewVersion.isEmpty()) {
return; // No minimum version requirement set
}
try {
String currentWebViewVersion = getWebViewVersion();
if (currentWebViewVersion != null && !isWebViewVersionSufficient(currentWebViewVersion, minimumWebViewVersion)) {
isWebViewVersionBlocked = true;
String title = getWebViewVersionTitle();
String message = getWebViewVersionMessage();
String button = getWebViewVersionButtonText();
displayError(title, message, button, true);
}
} catch (Exception e) {
LOG.e(TAG, "Error checking WebView version: " + e.getMessage());
}
}
/**
* Get the WebView version check dialog title from string resources.
*/
private String getWebViewVersionTitle() {
int resId = getResources().getIdentifier("webview_version_too_old_title", "string", getPackageName());
return resId != 0 ? getString(resId) : "WebView Update Required";
}
/**
* Get the WebView version check dialog message from string resources.
*/
private String getWebViewVersionMessage() {
int resId = getResources().getIdentifier("webview_version_too_old_message", "string", getPackageName());
return resId != 0 ? getString(resId) : "Your Android System WebView version is too old. Please update it through the Google Play Store.";
}
/**
* Get the WebView version check dialog button text from string resources.
*/
private String getWebViewVersionButtonText() {
int resId = getResources().getIdentifier("webview_version_ok_button", "string", getPackageName());
return resId != 0 ? getString(resId) : "OK";
}
/**
* Get the current WebView version string.
* @return Version string (e.g., "80.0.1234.56") or null if unable to determine
*/
private String getWebViewVersion() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
try {
PackageInfo webViewPackage = WebViewCompat.getCurrentWebViewPackage(this);
if (webViewPackage != null) {
return webViewPackage.versionName;
}
} catch (Exception e) {
LOG.d(TAG, "Could not get WebView version using WebViewCompat: " + e.getMessage());
}
}
// Fallback for older API levels
PackageManager pm = getPackageManager();
String[] fallbackPackages = new String[] {
"com.google.android.webview",
"com.android.webview",
"com.android.chrome"
};
for (String packageName : fallbackPackages) {
try {
PackageInfo pi = pm.getPackageInfo(packageName, 0);
return pi.versionName;
} catch (PackageManager.NameNotFoundException ignored) {
// Try next package
}
}
LOG.d(TAG, "Could not find WebView package");
return null;
}
/**
* Compare two version strings and determine if current version is >= minimum version.
* @param currentVersion Current version string (e.g., "80.0.1234.56")
* @param minimumVersion Minimum required version string (e.g., "80.0")
* @return true if currentVersion >= minimumVersion
*/
private boolean isWebViewVersionSufficient(String currentVersion, String minimumVersion) {
try {
String[] currentParts = currentVersion.split("\\.");
String[] minimumParts = minimumVersion.split("\\.");
int maxLength = Math.max(currentParts.length, minimumParts.length);
for (int i = 0; i < maxLength; i++) {
int currentPart = i < currentParts.length ? Integer.parseInt(currentParts[i]) : 0;
int minimumPart = i < minimumParts.length ? Integer.parseInt(minimumParts[i]) : 0;
if (currentPart > minimumPart) {
return true;
} else if (currentPart < minimumPart) {
return false;
}
}
return true; // Versions are equal
} catch (NumberFormatException e) {
LOG.e(TAG, "Error parsing version strings: " + e.getMessage());
return true; // If we can't parse, assume it's OK
}
}
/**
* Indicates whether to show the splash screen while the WebView is initially loading.
* <p>

47
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "cordova-android",
"version": "15.0.0",
"version": "15.0.1-dev.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "cordova-android",
"version": "15.0.0",
"version": "15.0.1-dev.0",
"license": "Apache-2.0",
"dependencies": {
"android-versions": "^2.1.1",
@@ -2280,9 +2280,9 @@
}
},
"node_modules/glob/node_modules/minimatch": {
"version": "10.2.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.2.tgz",
"integrity": "sha512-+G4CpNBxa5MprY+04MbgOw1v7So6n5JY166pFi9KfYwT78fxScCeSNQSNzp6dpPSW2rONOps6Ocam1wFhCgoVw==",
"version": "10.2.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz",
"integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
@@ -3245,9 +3245,9 @@
}
},
"node_modules/minimatch": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.3.tgz",
"integrity": "sha512-M2GCs7Vk83NxkUyQV1bkABc4yxgz9kILhHImZiBPAZ9ybuvCb0/H7lEl5XvIg3g+9d4eNotkZA5IWwYl0tibaA==",
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
"integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -4318,14 +4318,31 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/test-exclude/node_modules/glob/node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true,
"license": "MIT"
},
"node_modules/test-exclude/node_modules/glob/node_modules/brace-expansion": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/test-exclude/node_modules/glob/node_modules/minimatch": {
"version": "9.0.6",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.6.tgz",
"integrity": "sha512-kQAVowdR33euIqeA0+VZTDqU+qo1IeVY+hrKYtZMio3Pg0P0vuh/kwRylLUddJhB6pf3q/botcOvRtx4IN1wqQ==",
"version": "9.0.9",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
"integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
"dev": true,
"license": "ISC",
"dependencies": {
"brace-expansion": "^5.0.2"
"brace-expansion": "^2.0.2"
},
"engines": {
"node": ">=16 || 14 >=14.17"
@@ -4342,9 +4359,9 @@
"license": "ISC"
},
"node_modules/test-exclude/node_modules/minimatch": {
"version": "10.2.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.2.tgz",
"integrity": "sha512-+G4CpNBxa5MprY+04MbgOw1v7So6n5JY166pFi9KfYwT78fxScCeSNQSNzp6dpPSW2rONOps6Ocam1wFhCgoVw==",
"version": "10.2.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz",
"integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {

View File

@@ -1,6 +1,6 @@
{
"name": "cordova-android",
"version": "15.0.0",
"version": "15.0.1-dev.0",
"description": "cordova-android release",
"types": "./types/index.d.ts",
"main": "lib/Api.js",

View File

@@ -24,4 +24,8 @@
<string name="launcher_name">@string/app_name</string>
<!-- App label shown on the task switcher. -->
<string name="activity_name">@string/launcher_name</string>
<!-- WebView version check messages -->
<string name="webview_version_too_old_title">WebView Update Required</string>
<string name="webview_version_too_old_message">Your Android System WebView version is too old. Please update it through the Google Play Store.</string>
<string name="webview_version_ok_button">OK</string>
</resources>