I want to create the update mechanism of my Adobe Air-based Android app. In my special case with a private, very small app audience I use a direct distribution (without Google Play, via phisical installing on the users device) of the my application apk-file. But also I need to be able to install updates to it automatically (Let's say it will be a button 'Check updates' in my app UI). Can anybody help me with this task? How can I create this?
Now I have the idea:
I try to download the file with my app (using loaders and write the file using the File api) to the user storage... Then I want to use any Air Native Extension to launch that file. Is there any already created ANE to do that?
In my case for create auto update mechanism, I got local version number from app.xml and latest number from server.
Here is my settings.
app.xml
...
<name>mysomeapp</name>
<!-- A string value of the format <0-999>.<0-999>.<0-999> that represents application version which can be used to check for application upgrade.
Values can also be 1-part or 2-part. It is not necessary to have a 3-part value.
An updated version of application must have a versionNumber value higher than the previous version. Required for namespace >= 2.5 . -->
<versionNumber>1.0.1</versionNumber>
...
actionscript
private var appVersion: String;
public function init():void
{
// Get local versionnumber from app.xml
var appDescriptor:XML = NativeApplication.nativeApplication.applicationDescriptor;
var ns:Namespace = appDescriptor.namespace();
appVersion = appDescriptor.ns::versionNumber; // In this case, it returns "1.0.1".
// Get latest versionnumber from server
var httpservice: HTTPService = new HTTPService();
httpservice.url = "http://myserver/foobar/version";
httpservice.method = URLRequestMethod.GET;
httpservice.addEventListener(ResultEvent.RESULT, checkVersionResult);
httpservice.send();
}
public function checkVersionResult(e: ResultEvent): void
{
// Compare latest number with local number.
if (e.result != appVersion)
{
// If the local version is not latest, download latest app from server.
navigateToURL(new URLRequest("http://myserver/foobar/androidAppDownload"));
}
}
Related
We have made an android app using Xamarin and make use of microsoft appcenter build and distribute, we migrated this app from using HockeyApp.
Appcenter allows us to make a QR code which people can then scan and they can install the application this way, this works fine. Another way users can install the application is by using the app center app, this also works.
However when we push out an update we start to get issues. We have allowed using in app updates so when we push a new version a pop up will show in the app requiring that you update it. There is a download button available. Clicking this will start the download. After the download is finished a screen is showed with the text 'Staging app' and the following error message : "There was a problem while parsing the package." This happens both using the app center app or the QR code to install the app. We can also install a new version using the microsoft app center app, in this case it does work but we would like the in app updates to work properly too.
How can we get this to work so that users can also do in app updates where the new version can actually be installed? The code to activate distribute is as follows :
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
Forms.Init(this, bundle);
ContextMenuViewRenderer.Preserve();
appVersion = "" + this.PackageManager.GetPackageInfo(ApplicationContext.PackageName, 0).VersionName;
if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)
{
Window.AddFlags(WindowManagerFlags.DrawsSystemBarBackgrounds);
}
AppCenter.Start(_appCenterId,
typeof(Analytics), typeof(Crashes), typeof(Distribute));
CheckForUpdates();
}
private void CheckForUpdates()
{
Distribute.SetEnabledAsync(true);
}
private void UnregisterManagers()
{
Distribute.SetEnabledAsync(false);
}
Thanks for the help.
Problem while parsing package
About this problem,
You need to check whether the apk file has been downloaded fully first. Check the size of downloaded apk file is the same with the server.
Second, you need to check whether the name of apk file is legal, such as can not contain space char.
Third, check the android:minSdkVersion of AndroidManifest is higher than your current environment.
How do apps update internally automatically without updating from playstore?
I mean the internal data of app is changed (via internet) without updating from playstore. For eg any Contest app, or Facebook app. Here the newsfeed is updated automatically.
What is the technical term for that?
Any tutorial on it?
If you would like to check if you app has updates (without interacting with Google Play), you'd have to poll a server (providing your current version) and let the server check if there is a newer version available. If that is the case, let the server respond with a changelog and an url to the newer version.
Luckily, there are libraries to do this:
AppUpdater. Android Library that checks for updates on your own server (or Google Play, Github, etc). Great documentation. This library notifies your apps' updates by showing a Material dialog, Snackbar or notification.
Android Auto Update. Chinese library, but should do the trick, one of the most popular libraries to do this, but this can be just because Google Play is not available in China.
AppUpdateChecker A simple non-Market way to keep your app updated.
All it requires to set up is a URL pointing to a JSON document describing your app's changes.
Auto Updater This project allows to automatically update a running APK application using a private update server (see apk-updater) instead of Google Play updater. Also comes with a server script.
SmartUpdates. Older library, but instructions in English and also provides a server script.
WVersionManager. Checks for updates, but actual update has to be downloaded from the Play Store.
Answer from Mdlc is about updating the app itself but not the content.
What initially asked is how to create an App with dynamic content such Facebook or any other newsfeed app.
Any kind of such apps has 2 parts:
Server
Client
Server stores the whole information you need and client make requests to that server and displays information.
Let's say server stores in DB one entry called News#1. Client requests list of news and get back array[News#1] as response and show one tile on screen. Then somebody creates new entry News#2. On next request to the server client will get array of 2 elements: array[News#1, News#2] and displays this dynamic content.
REST Api Client is what to start with.
https://github.com/bitstadium/HockeySDK-Android/blob/develop/hockeysdk/src/main/java/net/hockeyapp/android/tasks/DownloadFileTask.java#L194 has the perfect and still working implementation on opening a downloaded APK file...
private fun install(downloadedAPK: File, context: Context) {
val intent = Intent(Intent.ACTION_INSTALL_PACKAGE)
intent.setDataAndType(Uri.fromFile(downloadedAPK),
"application/vnd.android.package-archive")
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
var oldVmPolicy: StrictMode.VmPolicy? = null
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
oldVmPolicy = StrictMode.getVmPolicy()
val policy = StrictMode.VmPolicy.Builder()
.penaltyLog()
.build()
StrictMode.setVmPolicy(policy)
}
context.startActivity(intent)
if (oldVmPolicy != null) {
StrictMode.setVmPolicy(oldVmPolicy)
}
}
Also have a look on AppCenter (Former HockeyApp) in-app updates https://learn.microsoft.com/en-us/appcenter/distribution/inappupdates
Here is the alternate
https://developer.android.com/guide/app-bundle/in-app-updates#update_readiness
try this google library to update from the application
dependencies {
implementation 'com.google.android.play:core:1.5.0'
...}
You can try this library: implementation 'com.github.vermat516:HelperLibrary:1.0.1'
This is best from my view we only have to write is:
new UniversalHelper(this).updateApp();
Rest of the work will automatically done by the library
This is response how your app will look like[This]
i am working in mobile application using Flash 6 Air , AS3 , i want to know whether there is any possibility to make the auto update feature , when ever the user open the app , it goes to see for update .
so could you please help me on this requirement and give me the code that I have to use ?!!
thanks in advance.
there's two options here
Upload your app to the Google Play Store, everytime you update your app, increase the version number, upload the new version and Google will handle it for you.
The more complicated option is to write your own update downloader + a native extension to tell the operating system to launch the .apk file.
A sample downloader
public function start():void
{
var fileLoader:URLLoader = new URLLoader
fileLoader.dataFormat = URLLoaderDataFormat.BINARY;
fileLoader.addEventListener(Event.COMPLETE,downloadSuccess);
var url:URLRequest = new URLRequest("http://www.example.com/updates/"+targetVersion+".apk");
fileLoader.load(url);
}
private function downloadSuccess(event:Event):void
{
var fileLoader:URLLoader = event.target as URLLoader;
fileLoader.removeEventListener(Event.COMPLETE,downloadSuccess);
var fs:FileStream = new FileStream();
var file:File = File.userDirectory.resolvePath(targetVersion+".apk");
fs.open(file,FileMode.WRITE);
fs.writeBytes(fileLoader.data);
fs.close();
//insert native extension call here.
}
Then you'll need an ANE to trigger the android package installer. There are plenty of ANE tutorials out there, though none that cover specifically what you want. I recommend starting with this one.
I would like to code a function which will let me know if another specific app of my company is installed on the current device. I guess that in order to do so I need to retrieve a list of the installed apps like here (Answer for native coders):
How to get a list of installed android applications...
Is there a straight forward way to get the list with action script?
Bottom line, I just need to know about my own apps. Maybe a way to get a list of air apps installed?
Thank you
The direct answer no, but you can use one of the following:
1- Write a file in specific location indicates that the app from your company installed, and check this file from your app, to do this
- On the first time run of the application write a file in the desktopDirectory:
var myAppTextFile:File = File.desktopDirectory.resolvePath("MyAppVersion.txt");
var fs:FileStream = new FileStream();
fs.open(myAppTextFile, FileMode.WRITE);
fs.writeUTF("MyApp V0.0 installed");
fs.close();`
Each time you run the New Application check this file:
var myAppTextFile:File = File.desktopDirectory.resolvePath("MyAppVersion.txt");
var fs:FileStream = new FileStream();
fs.open(myAppTextFile, FileMode.READ);
var str:String = fs.readUTF();
fs.close();`
Note: Works for Android not for iOS.
2- Use Native extension to do this.
I'm trying to access a non-default version of my AppEngine application using an Android app. For clearance, my default version is 1, and my new version is 2. Note that I cannot (yet) let version 2 be the default version.
From the docs:
The element contains the version identifier for the latest version of the app's code. The version identifier can contain lowercase letters, digits, and hyphens. It cannot begin with the prefix "ah-" and the names "default" and "latest" are reserved and cannot be used. AppCfg uses this version identifier when it uploads the application, telling App Engine to either create a new version of the app with the given identifier, or replace the version of the app with the given identifier if one already exists. You can test new versions of your app using a URL using "-dot-" as a subdomain separator in the URL, e.g. http://_version_id_-dot-_your_app_id_.appspot.com. You can select which version of the app your users see, the "default" version, using the Admin Console.
Unfortunately, Android applications do not use this url directly. The ids my app uses are:
final String PROJECT_NUMBER = "123456789012";
final String WEB_CLIENT_ID = "123456789012-abcdefghijklmnopqrstuvwxyz012345.apps.googleusercontent.com";
final String ANDROID_AUDIENCE = WEB_CLIENT_ID;
The PROJECT_NUMBER is used for GCM registration, the ANDROID_AUDIENCE is used as follows:
mCredential = GoogleAccountCredential.usingAudience(context, "server:client_id:" + Ids.ANDROID_AUDIENCE);
How can I get my Android application to communicate with version 2 of my AppEngine application?
#dragonx provided a Python link, however, I'm using Java.
On this page, it says you can define a root and a version. This is what I've done to make this work:
Add version and root to my endpoint class:
.
#Api(version = "2", root="https://2-dot-my_app_id.appspot.com/_ah/api", name = "deviceinfoendpoint", clientIds = (...) )
public class DeviceInfoEndpoint {
Generate the Client Library
Deploy to AppEngine.
Now all calls made through my DeviceInfoEndpoint class are sent to version 2 of my AppEngine application.