Compare commits

..

2 Commits

Author SHA1 Message Date
Manuel Beck
10437f82ae Update README.md badges and remove Stable Release section
. Updated badges in README.md for npm version and GitHub version by using `shields.io` for the badges, because it has a more open license (uses `CC0-1.0`) than `nodei.co` and offers labels, which `nodei.co` does not support
- Removed the Stable Release section again, the badge is now shown directly underneath the main title
2025-12-22 18:22:08 +01:00
Manuel Beck
81b22c3a87 Enhance README with version badges
- Added current package version as badge in title
- Removed nodei.co badge
- Added npm version badge via shields.io in section `Stable Release`
2025-11-26 00:06:47 +01:00
8 changed files with 17 additions and 254 deletions

View File

@@ -21,8 +21,8 @@
# Cordova Android
[![NPM](https://nodei.co/npm/cordova-android.png)](https://nodei.co/npm/cordova-android/)
[![npm - Latest](https://img.shields.io/npm/v/cordova-android/latest?label=Latest%20Release%20(npm))](https://npmjs.com/package/cordova-android)
[![GitHub](https://img.shields.io/github/package-json/v/apache/cordova-android?label=Development%20(Git))](https://github.com/apache/cordova-android)
[![Node CI](https://github.com/apache/cordova-android/workflows/Node%20CI/badge.svg?branch=master)](https://github.com/apache/cordova-android/actions?query=branch%3Amaster)
[![codecov.io](https://codecov.io/github/apache/cordova-android/coverage.svg?branch=master)](https://codecov.io/github/apache/cordova-android?branch=master)
@@ -66,20 +66,6 @@ npm install
npm test
```
## Install Nightly Build
```bash
cordova platform add android@nightly
```
### Notes
Nightly builds are **not recommended for production apps**. They are intended for testing purposes. This allows users either to check if recent changes in the main branch have fixed existing issues or to identify new bugs before an official release.
Nightly builds are generated daily and may be **unstable**.
See [Apache Cordova - Nightly Builds](https://cordova.apache.org/contribute/nightly_builds.html) for more details.
## Further reading
* [Apache Cordova](https://cordova.apache.org/)

View File

@@ -61,15 +61,6 @@ public class CallbackContext {
webView.sendPluginResult(pluginResult, callbackId);
}
/**
* Helper for success callbacks that just returns the Status.OK by default
*
* @param message The message to add to the success result.
*/
public void success(boolean message) {
sendPluginResult(new PluginResult(PluginResult.Status.OK, message));
}
/**
* Helper for success callbacks that just returns the Status.OK by default
*

View File

@@ -319,9 +319,7 @@ class ProjectBuilder {
*/
const javaHome = process.env.CORDOVA_JAVA_HOME || process.env.JAVA_HOME || false;
if (javaHome) {
// Double escape back-slashes so that it is written as escaped back-slashes
// in the gradle config. Primary an issue in window environments.
configProperties.set('java.home', javaHome.replace(/\\/g, '\\\\'));
configProperties.set('java.home', javaHome);
} else {
configProperties.unset('java.home');
}

View File

@@ -24,7 +24,6 @@ const java = require('./env/java');
const { CordovaError, ConfigParser, events } = require('cordova-common');
const android_sdk = require('./android_sdk');
const { SDK_VERSION } = require('./gradle-config-defaults');
const AndroidCommandLineTools = require('./env/AndroidCommandLineTools');
// Re-exporting these for backwards compatibility and for unit testing.
// TODO: Remove uses and use the ./utils module directly.
@@ -217,14 +216,14 @@ module.exports.check_android = function () {
}
}
if (avdmanagerInPath) {
let sdkPath = null;
if (/cmdline-tools/.test(avdmanagerInPath)) {
sdkPath = path.resolve(avdmanagerInPath, '../../../..');
maybeSetAndroidHome(sdkPath);
parentDir = path.dirname(avdmanagerInPath);
grandParentDir = path.dirname(parentDir);
if (path.basename(parentDir) === 'bin' && path.basename(grandParentDir) === 'tools') {
maybeSetAndroidHome(path.dirname(grandParentDir));
} else {
throw new CordovaError('Failed to find \'ANDROID_HOME\' environment variable. Try setting it manually.\n' +
'Detected \'avdmanager\' command at ' + parentDir + ' but does not appear to be within an Android SDK installation.\n' +
'Try reinstall Android SDK or update your PATH to include valid path to SDK');
'Detected \'avdmanager\' command at ' + parentDir + ' but no \'tools' + path.sep + 'bin\' directory found near.\n' +
'Try reinstall Android SDK or update your PATH to include valid path to SDK' + path.sep + 'tools' + path.sep + 'bin directory.');
}
}
}
@@ -241,10 +240,7 @@ module.exports.check_android = function () {
process.env.PATH += path.delimiter + path.join(process.env.ANDROID_HOME, 'platform-tools');
}
if (hasAndroidHome && !avdmanagerInPath) {
const cmdLineToolsBin = AndroidCommandLineTools.getBinPath();
if (cmdLineToolsBin) {
process.env.PATH += path.delimiter + cmdLineToolsBin;
}
process.env.PATH += path.delimiter + path.join(process.env.ANDROID_HOME, 'tools', 'bin');
}
return hasAndroidHome;
});

View File

@@ -1,102 +0,0 @@
/**
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
const { events } = require('cordova-common');
const fs = require('node:fs');
const path = require('node:path');
const semver = require('semver');
/**
* Utility collection for resolving the Android SDK command line tools installed
* on the workstation.
*/
const AndroidCommandLineTools = {
/**
* Gets a sorted list of available versions found on the system.
*
* If the command line tools is not resolvable, then an empty array will be returned.
*
* This function depends on ANDROID_HOME environment variable.
*
* @returns {String[]}
*/
getAvailableVersions: () => {
const androidHome = path.resolve(AndroidCommandLineTools.__getAndroidHome());
if (!fs.existsSync(androidHome)) {
events.emit('warn', 'ANDROID_HOME is not resolvable.');
return [];
}
const cmdLineToolsContainer = path.join(androidHome, 'cmdline-tools');
if (!fs.existsSync(cmdLineToolsContainer)) {
events.emit('warn', 'Android SDK is missing cmdline-tools directory.');
return [];
}
const cmdLineVersions = fs.readdirSync(cmdLineToolsContainer)
.filter((value) => {
// expected directory paths are semver-like version strings or literally "latest"
return value === 'latest' || semver.coerce(value) !== null;
})
.sort((a, b) => {
// "latest" directory always comes first
if (a === 'latest') return -1;
if (b === 'latest') return 1;
const av = semver.coerce(a, {
includePrerelease: true
});
const bv = semver.coerce(b, {
includePrerelease: true
});
// Descending (highest version first)
return semver.rcompare(av, bv);
});
return cmdLineVersions;
},
/**
* Gets the bin path of the cmd line tools using the latest available that
* is installed on the workstation.
*
* Returns null if there are no versions fond
*
* @returns {String | null}
*/
getBinPath: () => {
const versions = AndroidCommandLineTools.getAvailableVersions();
if (versions.length === 0) {
return null;
}
const version = versions[0];
return path.resolve(AndroidCommandLineTools.__getAndroidHome(), 'cmdline-tools', version, 'bin');
},
/**
* @internal
*/
__getAndroidHome: () => process.env.ANDROID_HOME
};
module.exports = AndroidCommandLineTools;

View File

@@ -1,105 +0,0 @@
/**
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
const fs = require('node:fs');
const path = require('node:path');
const AndroidCommandLineTools = require('../../lib/env/AndroidCommandLineTools');
describe('AndroidCommandLineTools', () => {
beforeAll(() => {
// For the purposes of these test, we will assume ANDROID_HOME is proper.
spyOn(fs, 'existsSync').and.returnValue(true);
});
describe('getAvailableVersions', () => {
describe('should return a list of command line versions', () => {
it('in descending order', () => {
spyOn(fs, 'readdirSync').and.returnValue([
'10.0',
'15.0',
'13'
]);
expect(AndroidCommandLineTools.getAvailableVersions()).toEqual([
'15.0',
'13',
'10.0'
]);
});
it('stable releases appear before prereleases', () => {
spyOn(fs, 'readdirSync').and.returnValue([
'15.0-rc01',
'15.0-alpha01',
'15.0'
]);
expect(AndroidCommandLineTools.getAvailableVersions()).toEqual([
'15.0',
'15.0-rc01',
'15.0-alpha01'
]);
});
it('"latest" should take all precedence', () => {
spyOn(fs, 'readdirSync').and.returnValue([
'15.0-rc01',
'15.0-alpha01',
'15.0',
'latest'
]);
expect(AndroidCommandLineTools.getAvailableVersions()).toEqual([
'latest',
'15.0',
'15.0-rc01',
'15.0-alpha01'
]);
});
it('invalid versions are ignored', () => {
spyOn(fs, 'readdirSync').and.returnValue([
'15.0-rc01',
'xyz',
'15.0'
]);
expect(AndroidCommandLineTools.getAvailableVersions()).toEqual([
'15.0',
'15.0-rc01'
]);
});
});
});
describe('getBinPath', () => {
beforeEach(() => {
spyOn(AndroidCommandLineTools, '__getAndroidHome').and.returnValue('/Android/Sdk');
});
it('should return the bin path of the latest version', () => {
spyOn(AndroidCommandLineTools, 'getAvailableVersions').and.returnValue([
'19.0',
'18.0'
]);
expect(AndroidCommandLineTools.getBinPath()).toBe(path.resolve('/Android/Sdk/cmdline-tools/19.0/bin'));
});
});
});

View File

@@ -27,7 +27,6 @@ const which = require('which');
const {
SDK_VERSION: DEFAULT_TARGET_API
} = require('../../lib/gradle-config-defaults');
const AndroidCommandLineTools = require('../../lib/env/AndroidCommandLineTools');
describe('check_reqs', function () {
let check_reqs;
@@ -59,10 +58,6 @@ describe('check_reqs', function () {
});
describe('check_android', function () {
beforeAll(() => {
spyOn(AndroidCommandLineTools, 'getAvailableVersions').and.returnValue(['latest']);
});
describe('find and set ANDROID_HOME when neither ANDROID_HOME nor ANDROID_SDK_ROOT is set', function () {
beforeEach(function () {
delete process.env.ANDROID_HOME;
@@ -128,13 +123,13 @@ describe('check_reqs', function () {
spyOn(fs, 'existsSync').and.returnValue(true);
spyOn(which, 'sync').and.callFake(function (cmd) {
if (cmd === 'avdmanager') {
return path.resolve('/android/sdk/cmdline-tools/latest/bin/avdmanager');
return path.normalize('/android/sdk/tools/bin/avdmanager');
} else {
return null;
}
});
return check_reqs.check_android().then(function () {
expect(process.env.ANDROID_HOME).toEqual(path.resolve('/android/sdk'));
expect(process.env.ANDROID_HOME).toEqual(path.normalize('/android/sdk'));
});
});
it('should error out if `avdmanager` command exists in a non-SDK-like directory structure', () => {
@@ -213,8 +208,9 @@ describe('check_reqs', function () {
});
it('should add tools/bin,tools,platform-tools to PATH if `avdmanager`,`android`,`adb` is not found', () => {
return check_reqs.check_android().then(function () {
expect(process.env.PATH).toContain('let the children play' + path.sep + 'tools');
expect(process.env.PATH).toContain('let the children play' + path.sep + 'platform-tools');
expect(process.env.PATH).toContain('let the children play' + path.sep + 'cmdline-tools' + path.sep + 'latest' + path.sep + 'bin');
expect(process.env.PATH).toContain('let the children play' + path.sep + 'tools' + path.sep + 'bin');
});
});
});

View File

@@ -30,6 +30,9 @@
<!-- Required: Set the theme of the Activity that directly follows your splash screen. -->
<item name="postSplashScreenTheme">@style/Theme.Cordova.App.DayNight</item>
<!-- Disable Edge-to-Edge for SDK 35 -->
<item name="android:windowOptOutEdgeToEdgeEnforcement" tools:targetApi="35">true</item>
</style>
<style name="Theme.Cordova.App.DayNight" parent="Theme.AppCompat.DayNight.NoActionBar">