How to upgrade a meteor app - android

My App created by Meteor is now doing upgrading by Meteor's HCP(Hot Code Push), which means the user will get a new version as soon as he restarts the App, without any information or confirm dialog.
HCP is great, but there are two reasons some users don't want the App be upgraded quietly:
New version may have degrades or other risks.
Old version is enough for theirs uses.
So I want to know if there is a way, I can show user a new-version-available dialog describing features of the new version, and ask him whether to upgrade or not. When he agreed, use HCP to do the upgrade work or, download the necessary package by writing code if HCP not usable in this occasion.
By the way I have another question related: Why HCP only work on android phone, how to make it work on iOS phone.
Many thanks in advance for answering any one of the two questions, or both.
Thank you.

By the way I have another question related: Why HCP only work on android phone, how to make it work on iOS phone.
HCP should work on all platforms in the same way.
To show prompt dialog you have to intercept HCP in Reload._onMigrate hook:
import { Reload } from 'meteor/reload';
Reload._onMigrate(() => {
const decision = confirm("New version is available, would you like to upgrade now?")
return [decision]; // Return [false] to manually handle HCP
});
This is a very simple example, you can trigger nice UI/UX element to handle it.
For example we always return [false] in _onMigrate hook. Show to the user nice pop-up. And if user choose to update now, we trigger next function (pick options you need):
// Purge and reload cache for AppCache package
window.applicationCache.swapCache();
window.applicationCache.update();
// Drop ServiceWorker cache
window.caches.keys().then((keys) => {
keys.forEach((name) => {
window.caches.delete(name);
});
}).catch((err) => {
console.error('window.caches.delete', err);
});
// Unregister Service Worker
SWRegistration.unregister();
// Reload the page
if (window.location.hash || window.location.href.endsWith("#")) {
window.location.reload();
} else {
window.location.replace(window.location.href);
}

Related

Restricting a SwitchPreference only for mobile device

I'm working with ionic/cordova for developing cross-platform apps with angular 5. Everything is working great. I just encountered a scenario where I need to show some preference only on the mobile device. They should not be visible on tablet etc. Is there any way through which I can restrict some of my preferences only to mobile devices ? e.g. some kind of key on the preference to tell it should only be rendered is device is a mobile handset.
I've already googled it but found nothing. Just wondering is there any way or is this thing impossible.
(Remember, its not a bug or issue, I just want some additional functionality in my existing app so asking for code is useless ;) )
Any help would be highly appreciated.
You can use the Platform service to check whether a device is a mobile phone or a tablet. Using this info, you can set your app preferences as needed. See this slightly modified example from the docs here and here:
import { Platform } from 'ionic-angular';
import { AppPreferences } from '#ionic-native/app-preferences';
#Component({...})
export MyPage {
constructor(public plt: Platform, public appPreferences: AppPreferences) {
if (this.plt.is('mobile')) {
this.appPreferences.store(ok, fail, 'key', 'value');
}
}
}
ok and fail are the callbacks executed if storing the preferences went well or failed. See the example here.

How to clear android app data of my cordova app?

In my logout option, I need to clear all of my app's data reverting it to a fresh installation state. Basically I need to trigger the same effect as manually doing Settings->Installed Apps->AppName->Clear App Data
Any ideas how to do it?
PS: This is specifically for the android platform only, though if there's a cross-platform solution I'd be most grateful.
For android version greater then kitkat you can use
import android.os.Build.*;
if (VERSION_CODES.KITKAT <= VERSION.SDK_INT) {
((ActivityManager)context.getSystemService(ACTIVITY_SERVICE))
.clearApplicationUserData(); // note: it has a return value!
}

Cordova / Phonegap: Live update codebase

We are using Cordova along with AngularJS for iOS and Android applications.
One big disadvantage of iOS are the long review times from Apple. In Google's Playstore, your app is available nearly immediately, or within a few hours. But Apple takes ages to review your app, even when it's only a small change.
So I was thinking, if there is a way to support some kind of live update.
That means, I could provide a ZIP file or something else with a new codebase, my app checks for updates and then installs the new files.
I've read something from appmobi, but are there any open source solutions?
cordova-app-loader is an easy to use plugin to update app files via 3 simple steps:
check() for a new manifest
download() files
update() your app!
It supports android and iOS
I don't know of any ready made solutions for that, but it should be easy enough to program something like this on your own.
Here are some points to get you started and to consider:
If you want to distribute updates via zip, you need a nativ plugin which handles the extraction
You might not be able to override files in the default location of your app (depending on OS). So, all files you want to update in the future have to sit in a folder your app has read/write access to (iOS: e.g. Library or Documents folder)
Now you simply need to download the zip-package, unpack the zip to your chosen directory, and restart/reload your app.
you will not be able to update native plugins!
Apple probably doesn't like that, since you are able to change the whole application without passing
their review process
I'm doing this inside my cordova app and haven't had any issues with ios app store review.
I'm using Jquery's ajax function to download both a javascript and a css file from a server that I can change without an app store approval and then I can inject those scripts once they downloaded on app startup.
I tried using the cordova File api and I'd then save the file locally, but offline support ins't the important to me at the moment and Jquery's ajax is much simpler.
Here is the jquery code I use. I have a bundle id that I use to detect if a new javascript file is available, otherwise jquery's ajax caches the previous requests to speed up download time.
This solution lets you have a subset of your code be dynamic. I still have a base set of code that is bundled with the app, along with native plugin js and native code which would need to go through the app store. But this atleast lets me push bug fixes without going through the app store.
Otherwise, I'd look at a solution like this: http://docs.build.phonegap.com/en_US/tools_hydration.md.html
function insertScript(version) {
var scriptUrl = "";
try {
// get javascript file...
scriptUrl = mobileWebServiceUrl + "/DynamicContent/Bundles/Scripts/dynamic";
scriptUrl += "_" + bundleVersion.replace(/\./g, "_") + ".js?v=" + version;
console.log("downloading script: " + scriptUrl);
// Allow user to set any option except for dataType, cache, and url
options = {
dataType: "script",
cache: true,
url: scriptUrl
};
// Use $.ajax() since it is more flexible than $.getScript
// Return the jqXHR object so we can chain callbacks
return $.ajax(options).success(function(response) {
console.log("insertScript success");
dynamicContentScriptLoaded = true;
});
} catch (e) {
//console.error(e);
ReportError("problem downloading javscript: " + scriptUrl);
}
}
function insertCSS(version) {
try {
// get css file...
var cssUrl = mobileWebServiceUrl + "/DynamicContent/Bundles/Css/dynamic";
cssUrl += "_" + bundleVersion.replace(/\./g, "_") + ".css?v=" + version;
console.log("downloading dynamic css: " + cssUrl);
$.ajax(cssUrl)
.success(function (response) {
console.log("successfully downloaded dynamic css");
var script = document.createElement("style");
script.type = "text/css";
script.innerHTML = response;
$('head link').each(function () {
if ($(this).attr('href').search('MobileFrame') > -1) {
$("#MobileFrameCSS").before(script);
}
});
dynamicContentCssLoaded = true;
// TODO: implement caching at a later date
//if (isPhoneGap())
// saveFile("DynamicStyles", response);
});
} catch (e) {
ReportError("problem downloading css");
}
}
Well, Adobe offers exactly that service in their Phonegap Build service. It's called Hydration.
The example shows using it with Android and iOS platforms, so I guess they made it compatible with the iOS Dev Program License Agreement.
If you are using Cordova, you probably will have to switch to the Phonegap CLI if you want to use their build cloud services, which is basically the same as Cordova's with some extra commands to upload to their cloud, etc.
I think there are some plugin like Splashscreen wich also have some minor changes (using <gap>for params into config.xml instead of <preference>). Again, if Hydration solves the problem for you, the changes are minor and you get a really nice feature.
I think the best choice would be to not try to do this with Phonegap, but rather identify your dynamic parts and implement these in Javascript.
Yes, I mean you should indeed use Javascript yourself without Phonegap, for example via JavaScriptBridge:
https://github.com/kishikawakatsumi/JavaScriptBridge
It may require more work initially to redesign your app into a "static" part (your PhoneGap app) and dynamic part (dynamic created views via JavascriptBirdge), and interacte seemlessly between them. But in my opinion, that will be ultimately the best software design.
However, also make sure you still meet Apples AppStore requirements.
The Meteor framework provides exactly this functionality when combined with PhoneGap. It's even sanctioned by Apple in the latest Developer Agreement. Here are some technical details and then some about Apple's view on it.
I think there is no such solution is available, but you can do it by programmatic way.you can update your cardova app by fetching files from server and updating it.
Check out CodePush from Microsoft. Works with Cordova and React Native.
Appears to be very similar to the "live update" feature from Ionic Cloud.
If you migrate to capacitor, the successor of Cordova there open source solution now.
Capacitor-updater, is the only alternative to ionic AppFlow.
The updater allows you to manage update by yourself, store your zip update where you want and use the download method.
How to start
npm install #capgo/capacitor-updater
npx cap sync
Then in your main JS, this is required to let the updater know the update is valid
import { CapacitorUpdater } from '#capgo/capacitor-updater'
CapacitorUpdater.notifyAppReady()
And lately after checking yourself the current version need update:
const version = await CapacitorUpdater.download({
url: 'https://github.com/Cap-go/demo-app/releases/download/0.0.4/dist.zip',
})
await CapacitorUpdater.set(version); // sets the new version, and reloads the app
After many request of people didn't want to do that themselves, I started Capgo a business to manage all the update process.
All is open source and can be replicate on your own as well.
Doing things for Capacitor is now my main activity, I produce open-source plugin as my main channel of Marketing, I'm solo founder and bootstrapped.
Hope my tool will help you !

Auto Update of application using HockeyApp SDK

I am using Android HockeyAppSDK to deploy updates to an application. I am trying to use the docs to customise the default UpdateManager class to allow updates to be installed automatically, without prompting the user to accept the update.
I am quite unsure of how to handle this. The obvious way (in my mind anyway) is to do the following:
private void checkForUpdates () {
UpdateManager.register (this, Constants.HOCKEY_API_KEY, new UpdateManagerListener() {
public void onUpdateAvailable() {
//I assume stuff will need to be handled here
}
});
}
Has anyone done this before, or can find a way to do it?
Many thanks
After emailing the support team for Hockey, they believe that within their current compiled API it is not possible to perform an update without prompting users to accept.
The whole source would require modification and compilation before working as expected it seems.
You can use UpdateTask from library

Android - how to check if in app purchase has already been done?

How do i check if a in app purchase has been done before?
So that my user doesnt need to repurchase the in app purchase upon uninstalling and reinstalling the app?
I have set my in app item to managable in the android market publish page.
i have read about RESTORE_TRANSACTION but I do not know what i need to look for inside this response and also how to test this.
Any help would be greatly appreaciated.
You need to restore the transactions, using the RESTORE_TRANSACTION flag you specified above. You should only do this once, when the application starts for the first time or if the user clears the data.
I would advice to make this process simpler for yourself, you looking into the AndroidBillingLibrary, which allows you to interface with the Android In App Billing in a much simpler manner.
Here is a snippet of how the transactions are restored:
private void restoreTransactions() {
if (!mBillingObserver.isTransactionsRestored()) {
BillingController.restoreTransactions(this);
Toast.makeText(this, R.string.restoring_transactions, Toast.LENGTH_LONG).show();
}
}

Categories

Resources