kolbasa / cordova-plugin-apkupdater Goto Github PK
View Code? Open in Web Editor NEWThis plugin allows your Android app to download and install compressed updates without the Google Play Store.
License: MIT License
This plugin allows your Android app to download and install compressed updates without the Google Play Store.
License: MIT License
After the latest version update, Cordova is unable to compile, indicating that the SDK version is less than 30, which is incompatible
A warning is displayed when the plugin is compiled.
Note: platforms/android/app/src/main/java/de/kolbasa/apkupdater/ApkUpdater.java uses or overrides a deprecated API.
The method of how the network status is queried must be exchanged.
Hi,
I think this happened after I migrated my project to to Android 11 in Cordova 11.
I'm unsure what I need to do to fix this.
After downloading the new APK it fails:
message: "Couldn't find meta-data for provider with authority org.apporg.appname.apkupdater.provider"
stack: "java.lang.IllegalArgumentException\n at androidx.core.content.FileProvider.parsePathStrategy(FileProvider.java:662)\n at androidx.core.content.FileProvider.getPathStrategy(FileProvider.java:635)\n at androidx.core.content.FileProvider.getUriForFile(FileProvider.java:441)\n at de.kolbasa.apkupdater.tools.ApkInstaller.getUpdate(ApkInstaller.java:32)\n at de.kolbasa.apkupdater.tools.ApkInstaller.install(ApkInstaller.java:45)\n at de.kolbasa.apkupdater.ApkUpdater.install(ApkUpdater.java:170)\n at de.kolbasa.apkupdater.ApkUpdater.lambda$execute$11$de-kolbasa-apkupdater-ApkUpdater(ApkUpdater.java:252)\n at de.kolbasa.apkupdater.ApkUpdater$$ExternalSyntheticLambda8.run(Unknown Source:4)\n at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)\n at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)\n at java.lang.Thread.run(Thread.java:764)\n"
After installation a message is asking if to quit or Open the App, but choosing Open is not producing any action.
It crashes because the strings android:label="@string/app_name"
can not be resolved from the generated android/app/src/main/res/xml/config.xml
file. It seems like this alias is not supported by capacitor. :/
install works if the apk understood for app-debug.apk, if the apk understood for app-release.apk does not install,
¿Cómo se implementa en ionic 4 o 5 ? algún ejemplo (ES-PE)
After running:
ApkUpdater.download('http://192.168.0.12:9000/user/get_dboy_app', { onDownloadProgress: function(progress) { console.log("progreso ...", progress); } })
The download ends up with this error:
No valid update found in download directory: /data/data/driver.deliverate.io/files/update', stack: 'de.kolbasa.apkupdater.exceptions.UpdateNotFoundExc…:636)\n at java.lang.Thread.run(Thread.java:764)\n
I'm using HapiJs 14.0.0 for the API and the weird thing is that if I upload the apk to some "file upload" service it works. Do you have some guidance? This is my HapiJs code:
get_dboy_app: { handler: function(request, reply) { var filename = settings.rootPath + '/server/public/get_dboy_app.apk'; reply.file(filename, { filename: 'get_dboy_app.apk', mode: 'attachment' }); }, auth: false, tags: ['api'], id: 'get_dboy_app' }
Using the same apk route with adb install <path>
works with no issues.
THIS PLUGIN HAS SUPPORT FOR IONIC V3, HOW TO USE?
I AM RETURNING = ReferenceError: apkupdater is not defined
SORRY FOR MY ENGLISH
Thank you very much for this plugin @kolbasa.
But I now have a workflow which is a bit different from your great working but simple workflow.
Is it possible to do this?
1.) Adding optional (POST body) parameters to query
Current situation is:
await cordova.plugins.apkupdater.check('https://your-domain.com/update/manifest.json');
My idea would be like this:
await cordova.plugins.apkupdater.check('https://your-domain.com/update/manifest.json', {
currentVersion: '1.2.3',
deviceStatus: 'Healthy',
battery: 100.0
});
Why?
I want to use the APK Updater for a platform which is similar to device management.
So I need a list of all devices with their versions and status.
Currently I'm having two requests. One for the APK Updater to check the version and one to tell the server the status of the device.
Would be nice.
And I could imagine that some servers can generate special versions based on the input.
As fallback I can extend the URL with query parameters like:
https://your-domain.com/update/manifest.json?currentVersion=1.2.3&deviceStatus=Healthy&battery=100.0
2.) Define remote path to the update (for example S3)
Currently its like you have a folder with few files.
https://your-domain.com/update/
And there you have for example:
But now we imagine about a microservice endpoint which not contains files - only logic.
So we want to specify for example a S3 endpoint for downloading.
So we want to extend the manifest.json response like:
{
"version": "1.0.0", // your custom version
"sum": "35d9fd2d688156e45b89707f650a61ac", // checksum of the apk-file
"size": 5425986, // size of the apk-file
"compressedSize": 4304842, // size of the compressed update
"chunks": [
"bf0b504ea0f6cdd7d3ba20d2fff48870", // checksum of "update.zip.001"
"830d523f8f2038fea5ae0fccb3dfa4c0", // checksum of "update.zip.002"
"c6a744ca828fa6dff4de888c6ec79a38" // checksum of "update.zip.003"
],
"paths": [
"https://example-app-update-storage-12345678.s3.eu-central-1.amazonaws.com/1.0.0/update.zip.001",
"https://example-app-update-storage-12345678.s3.eu-central-1.amazonaws.com/1.0.0/update.zip.002",
"https://example-app-update-storage-12345678.s3.eu-central-1.amazonaws.com/1.0.0/update.zip.003"
]
}
Then we can have the update files separated and its like an CDN.
Fallback solution is to check the version manually. Then use your plugin with special endpoint and route the update files to S3 via redirect.
Maybe there are other people's who are happy about this improvements, too.
I can start to work on a PR if this is welcome 😊
I have tried to use your plugin with ionic 5 / capacitor and it is failing on build.
./src/app/app.module.ts:25:106-116 - Error: export 'ApkUpdater' (imported as 'ApkUpdater') was not found in 'cordova-plugin-apkupdater' (possible exports: default)
thanks
Hi,
I tried download and update with an app-debug.apk file (same file installed on the device), and got an "Invalid package file." error/
Could you please help to find the source of issue ?
Thanks
vendor.js:91997 ERROR Error: Uncaught (in promise): Object: {"message":"Invalid package file: app-debug.apk (size=255)","stack":"de.kolbasa.apkupdater.exceptions.InvalidPackageException\n at de.kolbasa.apkupdater.tools.AppData.getPackageInfo(AppData.java:32)\n at de.kolbasa.apkupdater.update.UpdateManager.getApkInfo(UpdateManager.java:116)\n at de.kolbasa.apkupdater.update.UpdateManager.getUpdate(UpdateManager.java:123)\n at de.kolbasa.apkupdater.update.UpdateManager.download(UpdateManager.java:136)\n at de.kolbasa.apkupdater.ApkUpdater.download(ApkUpdater.java:85)\n at de.kolbasa.apkupdater.ApkUpdater.lambda$execute$3$de-kolbasa-apkupdater-ApkUpdater(ApkUpdater.java:228)\n at de.kolbasa.apkupdater.ApkUpdater$$ExternalSyntheticLambda5.run(D8$$SyntheticClass)\n at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)\n at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)\n at java.lang.Thread.run(Thread.java:761)\n"} de.kolbasa.apkupdater.exceptions.InvalidPackageException at de.kolbasa.apkupdater.tools.AppData.getPackageInfo(AppData.java:32) at de.kolbasa.apkupdater.update.UpdateManager.getApkInfo(UpdateManager.java:116) at de.kolbasa.apkupdater.update.UpdateManager.getUpdate(UpdateManager.java:123) at de.kolbasa.apkupdater.update.UpdateManager.download(UpdateManager.java:136) at de.kolbasa.apkupdater.ApkUpdater.download(ApkUpdater.java:85) at de.kolbasa.apkupdater.ApkUpdater.lambda$execute$3$de-kolbasa-apkupdater-ApkUpdater(ApkUpdater.java:228) at de.kolbasa.apkupdater.ApkUpdater$$ExternalSyntheticLambda5.run(D8$$SyntheticClass) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) at java.lang.Thread.run(Thread.java:761) at resolvePromise (http://localhost/polyfills.js:1643:21) at http://localhost/polyfills.js:1538:11 at http://localhost/polyfills.js:1555:27 at asyncGeneratorStep (http://localhost/vendor.js:143394:5) at _throw (http://localhost/vendor.js:143417:9) at _ZoneDelegate.invoke (http://localhost/polyfills.js:570:160) at Object.onInvoke (http://localhost/vendor.js:115285:25) at _ZoneDelegate.invoke (http://localhost/polyfills.js:570:48) at Zone.run (http://localhost/polyfills.js:296:37) at http://localhost/polyfills.js:1716:28
Hi,
I am trying to get this plugin to install updates from S3 and Github.
I am facing a problem with S3 when receiving the files. It says File not found error. If needed I can give more information on this. I would suspect its not direct File that can be received from a S3 URL. Let me know if I am wrong.
I am getting the data properly from a Github URL and things work. I am able to see the download progress as in the screenshot. But after the download is compelte, I see the error Directory is empty. I thought the reason could be no write access and I have given <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
as well.
I might be missing something vital but I couldnt figure it out. Please let me know what I can do.
Hi @kolbasa, I would like to test your plugin on my app built with capacitor.
Do you have in plan to port it?
Thanks in advance
To simple show the problem:
I have a button X that after click calls cordova.plugins.apkupdater.check('[MY_MANIFEST_URL]');
I have another button Y that after click makes a xmlhttprequest in angular this.http.get('[MY_MANIFEST_URL]').subscribe();
Manifest file is accessible under [MY_MANIFEST_URL]
Each time I press button X I get an error Download failed
, but if I press button Y at least one time then pressing button X every time gives me success response with object I expect.
Network status is OK. On the server side I log the requests and before I make my own I get nothing from apkupdater
. After I make my own then apkupdater.check()
works fine. After app is restarted problem is back.
Any clue what is going on?
Hi
i want to ask if it is fine that i will create a Pull Request at the Ionic Native Project for this Plugin?
Ionic Native is like a Wrapper with Interfaces and stuff like that over Cordova/Capacitor Apps.
Best,
Daniel
I've been using this plugin for my cordova app for a few months and it's been working great!
I'm in the process of converting from cordova to capacitor and am wondering if I can still use this?
currently cordova-plugin-androidx
is a hard dependency of this project as defined in https://github.com/kolbasa/cordova-plugin-apkupdater/blob/master/package.json#L12
However, when using cordova-android >= 9
, the androidx plugin should actually not be installed (see e.g. https://www.npmjs.com/package/cordova-plugin-androidx or https://cordova.apache.org/announcements/2020/06/29/cordova-android-9.0.0.html)
Is it possible to make the dependy optional? Maybe as a peerDependency
or just via documentation that it is only needed when using cordova-android <= 8
Also, is there a reason why the version is marked as ^2.0.0
? 3.0.0
has been out for a while
Hello, I want to know it's possible to installation directly without prompt?
Right now there's only place to put basic auth and then it gets converted to "Basic $TOKEN(base64)":
https://github.com/kolbasa/cordova-plugin-apkupdater/blob/f98e939ba21c7d8fcbae3e2bc72a797c59c08096/src/android/downloader/FileDownloader.java#L46C41-L46C41
I think it would be more useful if we could just send whatever headers we want (or at least Authorization header in general).
If this is not possible at least another option in the download method to be able to send a Bearer token would be appreciated.
So then we could just have "Authorization": "Bearer $TOKEN" - no need for base64 here as it could be a JWT directly.
Thanks for your work!
Hi, first of all thanks for the plugin its great!,
I encounter a problem while using azure blobs for download weather I send basicAuth as null or not, seams like the request headers authorization: 'Basic bnVsbA==' are always sent. I believe In FileDownloader.java:46
if (basicAuth != null) { basicAuth = new String(Base64.encode(basicAuth.getBytes(), Base64.NO_WRAP)); connection.setRequestProperty("Authorization", "Basic " + basicAuth); }
basicAuth is not null all the time.
I did a test server to intercept both download examples below and the authorization header is always present causing issues with strict servers.
await window.ApkUpdater.download('http://192.168.1.14:8000/update.apk', { basicAuth: null, onDownloadProgress: (e) => { console.log(Downloading: ${e.progress} % (${e.bytesWritten} / ${e.bytes})`)
}
})
await window.ApkUpdater.download('http://192.168.1.14:8000/update.apk', {
onDownloadProgress: (e) => {
this.enforce_upgrade.download_progress = e.progress
console.log(Downloading: ${e.progress} % (${e.bytesWritten} / ${e.bytes}))
console.log(this.enforce_upgrade)
}
})
{
authorization: 'Basic bnVsbA==',
'user-agent': 'Dalvik/2.1.0 (Linux; U; Android 8.1.0; TC20 Build/01-11-09.00-OG-U00-H01)',
host: '192.168.1.14:8000',
connection: 'Keep-Alive',
'accept-encoding': 'gzip'
}
`
I didn't see any roadmap, so I ask here.
Is there an intention to use or offer promises in the future?
I have a project that uses the cordova Kiosk mode plugin, in this app I use your V1.2.3 plugin
after downloading the application is minimized on its own to proceed with the installation of the new version, however when I update the plugin to version 2.02 this does not happen anymore, I receive a successful callback but nothing happens
greetings, it is possible to update the app with this new ownerInstall() function without user intervention? I've been using your plugin for some time now, I use it in Kiosk mode. sorry my ingles
However, the background download still works, only it is not accelerated if you are connected to the WiFi network.
The download continues at the preset interval time.
Hi,
I have problem getting this plugin to work with my application.
Problem:
cordova.plugins.apkupdater.check(
'http://raw.githubusercontent.com/kolbasa/cordova-plugin-apkupdater-demo/master/update/manifest.json',
function (oResp) {
console.log(JSON.stringify(oResp, ' ', 2));
},function (oResp) {
console.log(JSON.stringify(oResp, ' ', 2));
}
);
I get: "Unknown exception"
cordova.plugins.apkupdater.check(
'http://10.100.100.60/b/manifest.json',
function (oResp) {
console.log(JSON.stringify(oResp, ' ', 2));
},function (oResp) {
console.log(JSON.stringify(oResp, ' ', 2));
}
);
I get: "Download failed"
This is what I have on 10.100.100.60/b :
On network it doesn't show that it creates a request for the said file regardless of what I try to do.
I read previous issues (closed) and tried with no manifest at the end, tried with other function calls like download, etc. But since it doesn't have a link to pass it aside from check url, I resorted to simply asking.
Cordova 9.0.0 on Android.
I have the following in my app to check for android updates and download if available.
const manifest = await cordova.plugins.apkupdater.check(environment.updateUrl);
if (manifest.version !== this.appService.getInstalledApplicationVersion()) {
console.log('Android Update Available');
await cordova.plugins.apkupdater.download();
await cordova.plugins.apkupdater.install();
} else {
console.log('No Android update available');
}
The app sees that an update is available and it downloads it successfully.
It brings up the screen asking if I want to update the existing application.
However, when I click Install, it tries for a couple seconds then says 'App Not Installed'.
I'm not sure how to get any error logs or anything that might tell me why it's not working. Do you have any recommendations I can try to get it to work?
Hi @kolbasa good work here!
Kindly look into version @1.1.5
. I get the following unknown exception when calling cordova.plugins.apkupdater.install()
. However, it works fine with version @1.1.4
.
Installing update
VM262:1 Uncaught SyntaxError: missing ) after argument list
main-es2015.65833e749b32226b929f.js:1 ERROR Error: Uncaught (in promise): Unknown exception
at v (polyfills-es2015.53442393c1b668685504.js:1)
at polyfills-es2015.53442393c1b668685504.js:1
at a (main-es2015.65833e749b32226b929f.js:1)
at a.invoke (polyfills-es2015.53442393c1b668685504.js:1)
at Object.onInvoke (main-es2015.65833e749b32226b929f.js:1)
at a.invoke (polyfills-es2015.53442393c1b668685504.js:1)
at s.run (polyfills-es2015.53442393c1b668685504.js:1)
at polyfills-es2015.53442393c1b668685504.js:1
at a.invokeTask (polyfills-es2015.53442393c1b668685504.js:1)
at Object.onInvokeTask (main-es2015.65833e749b32226b929f.js:1)
I am able to update my Ionic 5 apps using this plugin (kolbasa apk updater), but cannot detect a new version apps available. Please help me... Thank you.
This is the error message:
[ng] Error: src/app/pages/home/home.page.ts:144:46 - error TS2558: Expected 0 type arguments, but got 1.
[ng] 144 const manifest = await this.http.get(this.remote + '/update.json').toPromise();
[ng] ~~~
[ng] Error: src/app/pages/home/home.page.ts:144:81 - error TS2339: Property 'toPromise' does not exist on type 'Promise'.
[ng] 144 const manifest = await this.http.get(this.remote + '/update.json').toPromise();
Hello and kudos on the great plugin!
Just wanted to ask if there's a possibility to customize the installation prompt, or, if that is not possible, to at least translate the message? Thanks!
Hi, I would like to ask if there are plans to support installing xapk files? Thank you for this awesome plugin.
It would be nice if the chunked mechanism is optional and the update also works with just a new APK file.
Common use case:
All versions of an app are stored on a webserver as APK files. The user can download any (preferable the latest version directly from the server as an APK), and the updater checks (via the manifest file) if there is a newer APK on the webserver.
Hi,
I am trying to integrate your plugin, but I can't get past "check". I am using this code:
await cordova.plugins.apkupdater.check('https://mobile-storage-assets-simplia.s3-eu-central-1.amazonaws.com/apk/manifest.json')
With this error (and no stack trace or anything):
Uncaught Download failed
I am new to cordova and have no idea how to debug this. Can you please help? :)
(Cordova 8.1.0 on android)
I'm trying to use this plugin on a mac. When I run the following command
node create-manifest.js
I get this error
Compressing Update
Error: Command failed: 7z a -v100k -mm=Deflate -mfb=258 -mpass=15 -r /update/update.zip /application.apk
/bin/sh: 7z: command not found
Hello,
Is it possible to set device owner for Android TV devices?
adb shell dpm set-device-owner
works with Android tablets and phones but not Android TV boxes?
Error:
...RuntimeException: Can't set package my.app.id as device owner...
Hello again.
I have a problem with the plugin when trying to fetch an updated version from an HTTPS URL.
The update works fine when requesting from my local development server.
I read here you intentended to add something for the authentication, has there been any progress on that? I couldn't find anything on the documentation.
However, I'm authenticating as you said by inserting username and password directly in the URL (like https://<username>:<password>@my.url.net/
), but i get a FileNotFoundException
.
I can access the same exact URL from browser or via cURL, and I'm also making a GET request via axios right before the check
function which resolves the URL correctly.
Am I doing something wrong?
good night friend, please help me, I've been using your plugin for some time, I have many cases that after the end of the download I get "failed to parse package" and it doesn't install, if I try a few times (2,3) I can do the successful installation. sorry about my English
DO u have any demo code? I don't understand how to use this plugin thanks!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.