I have an app published in the Play and App store, now I am in the work of publishing a new version for the app to both Play (Android) and App stores (iOS). Now, I want all the users to update to the new version when they use the app and not allow them to continue using the older version of the app without updating to the newer version.
Can anyone suggest me on how to force the users to update the app to the latest version once it is released in Play and App stores?
I don't know whether it is professional way or not., but this is the idea which struck my mind.
Add a variable with that app's version in App.cs or Mainpage.cs and and API with the current version as response.
Now check with the app's version and current version and redirect to homepage / any other page.
var version = 1.0;
var currentversion = 2.0; /* from API */
if(version == currentversion)
{
Navigation.PushModalAsync(new HomePage());
}
else
{
Navigation.PushModalAsync(new UpdatePage());
}
We must stop the old versions in the Play and App store.
For the future to do not stop (if we have some host - we should have it :) ):
someway save the version in the server side
every time when needed check the current version: getPackageManager().getPackageInfo(getPackageName(), 0).versionCode with version from server and force to update if needed.
good luck
How I am doing it my app is, when app starting in MyActivity I have code below
private void CompareVersion()
{
double currentVersion = 0d;
double appStoreversion =Convert.ToDouble(CosntValues.PlayStoreValues);
bool IsUpdateRequired = false;
if (Context.PackageName != null)
{
PackageInfo info = Context.PackageManager.GetPackageInfo(Context.PackageName, PackageInfoFlags.Activities);
string currentVersionStrig = info.VersionName;
currentVersion = Convert.ToDouble(currentVersionStrig);
}
try
{
if (IsUpdateRequired == false)
{
if (CheckNetConnection.IsNetConnected())
{
using (var webClient = new System.Net.WebClient())
{
var task = new VersionChecker();
task.Execute();
if ((appStoreversion.ToString() != currentVersion.ToString() && (appStoreversion > currentVersion)))
{
IsUpdateRequired = true;
}
}
}
}
if (IsUpdateRequired)
{
Activity.RunOnUiThread(() =>
{
AlertDialog dialog = null;
var Alertdialog = new Android.App.AlertDialog.Builder(Context);
Alertdialog.SetTitle("Update Available");
Alertdialog.SetMessage($"A new version of [" + appStoreversion + "] is available. Please update to version [" + appStoreversion + "] now.");
Alertdialog.SetNegativeButton("Cancel", (sender, e) =>
{
if (dialog == null)
{
dialog = Alertdialog.Create();
}
dialog.Dismiss();
});
Alertdialog.SetPositiveButton("Update", async (sender, e) =>
{
string appPackage = string.Empty;
try
{
appPackage = Application.Context.PackageName;
await Utilities.Logout(this.Activity);
var ints = new Intent(Intent.ActionView, Android.Net.Uri.Parse("market://details?id=" + appPackage));
ints.SetFlags(ActivityFlags.ClearTop);
ints.SetFlags(ActivityFlags.NoAnimation);
ints.SetFlags(ActivityFlags.NewTask);
Application.Context.StartActivity(ints);
//StartActivity(new Intent(Intent.ActionView, Android.Net.Uri.Parse("market://details?id=" + "com.sisapp.in.sisapp")));
}
catch (ActivityNotFoundException)
{
var apppack = Application.Context.PackageName;
//Default to the the actual web page in case google play store app is not installed
//StartActivity(new Intent(Intent.ActionView, Android.Net.Uri.Parse("https://play.google.com/store/apps/details?id=" + "com.app.in.app")));
await Utilities.Logout(this.Activity);
var ints = new Intent(Intent.ActionView, Android.Net.Uri.Parse("market://details?id=" + appPackage));
ints.SetFlags(ActivityFlags.ClearTop);
ints.SetFlags(ActivityFlags.NoAnimation);
ints.SetFlags(ActivityFlags.NewTask);
Application.Context.StartActivity(ints);
}
//this kills the app
Android.OS.Process.KillProcess(Android.OS.Process.MyPid());
System.Environment.Exit(1);
});
if (dialog == null)
dialog = Alertdialog.Create();
dialog.Show();
});
}
}
catch (Exception ex)
{
var objLog = new LogService();
objLog.MobileLog(ex, SISConst.UserName);
}
}
Followed by two separate above used classes
public class VersionChecker : AsyncTask
{
protected override Java.Lang.Object DoInBackground(params Java.Lang.Object[] #params)
{
var val1 = Jsoup.Connect("https://play.google.com/store/apps/details?id=" + "com.app.in.app" + "&hl=en")
.Timeout(30000).UserAgent("Mozilla/5.0 (Windows; U; WindowsNT 5.1; en-US; rv1.8.1.6) Gecko/20070725 Firefox/2.0.0.6").Referrer("http://www.google.com")
.Get();
var val2 = val1.Select(".htlgb");
var val3 = val2.Get(7).ToString();
//here mobile app version is of 3 values like 2.1, 4.2 etc
var version = val3.Substring(val3.IndexOf(">") + 1, 3); //fetching only 3 values ex 1.1
CosntValues.PlayStoreValues = version;
return version;
}
}
public static class CosntValues
{
public static string PlayStoreValues { get; set; }
}
Disclaimer: Use your app package name & above code is statically supporting for 3 digit version like 1.1, 1.2 etc.
Hope it help you
With this plugin I found a good solution and works perfectly in production. I strongly recommend this plugin. With this solution you can even give the user the possibility to go to the store right from your app
For example:
var isLatest = await CrossLatestVersion.Current.IsUsingLatestVersion();
if (!isLatest) //If the user does not have the last version
{
var update = await DisplayAlert("New version available", "There is a new version of our app. Would you like to download it?", "Yes", "No");
if (update)
{
//Open the store
await CrossLatestVersion.Current.OpenAppInStore();
}
}
Related
Plaid.Net is fully functional and can it be used in production code?
I am trying to create a link token like below
var plaid = new PlaidClient(Acklann.Plaid.Environment.Development);
string[] products = new string[] { "transactions" };
string[] countryCodes = new string[] { "US" };
var user = new UserInfo();
user.ClientUserId = "123bs6a4";
var createLinkTokenRequest = new CreateLinkTokenRequest
{
ClientId = "*****************",
Secret = "****************",
Products = products,
CountryCodes = countryCodes,
Language = "en",
ClientName = "My client",
User=user
};
try
{
var result = getToken(createLinkTokenRequest);
}
catch(Exception e)
{
Console.WriteLine(e);
Console.ReadKey();
}
public static async Task<CreateLinkTokenResponse> getToken(CreateLinkTokenRequest createLinkTokenRequest)
{
var plaid = new PlaidClient(Acklann.Plaid.Environment.Development);
try
{
var res= await plaid.CreateLinkToken(createLinkTokenRequest);
Console.WriteLine(res.LinkToken);
return res;
}
catch(Exception e)
{
Console.WriteLine(e);
}
finally
{
Console.WriteLine("Abc");
Console.ReadKey();
}
While debugging when I reach
await plaid.CreateLinkToken(createLinkTokenRequest);
the execution is stopped without an execption
is this the right way of creating link token or any other way?
(using .Net core 2.1, Acklann.Plaid Nuget)
Try to change the environment from development to sandbox. Maybe you are using the sandbox key and passing environment as development.
I have dusted off some old code with I know used to work but no longer appears to function.
Namely
var browserLogs = Driver.Manage().Logs.GetLog(LogType.Browser);
This used to return any console log entries but now I get the following
I last used this code about 2 years ago so my questions are:
What has changed in Chrome? What do I need to change on my code to get
this working again?
I am using Chrome 85.x etc with matching ChromeDriver, C# and Selenium. Driver is correctly initialised and a valid web page has rendered. Also I have this as in my driver options
options.SetLoggingPreference(LogType.Browser, LogLevel.All);
Any ideas folks?
More code below
public static void BeforeFeature(int server, string title)
{
if (server == 1) ResetReportVariables(TestUrls.DomainLive, title);
if (server == 2) ResetReportVariables(TestUrls.Domain, title);
var options = new ChromeOptions();
options.AddArguments("disable-browser-side-navigation");
options.AddArguments("disable-infobars");
options.AddArgument("ignore-certificate-errors");
options.AddArgument("ignore-ssl-errors");
options.AddArgument("disable-popup-blocking");
options.AddArguments("start-maximized");
options.AddArguments("no-sandbox");
options.SetLoggingPreference(LogType.Browser, LogLevel.All);
Driver = new ChromeDriver(options);
Driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(TestValues.DelayShort);
Driver.Manage().Timeouts().AsynchronousJavaScript = TimeSpan.FromSeconds(TestValues.DelayShort);
Driver.Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(TestValues.DelayShort);
Driver.Manage().Cookies.DeleteAllCookies();
}
Scenario Outline: Validate the following pages on live site
Given that I browse to "<url>" page on "1" server
Then no console errors were detected
Examples:
| url |
| / |
[Given(#"that I browse to ""(.*)"" page on ""(.*)"" server")]
public void GivenThatIBrowseToPageOnServer(string url, int server)
{
Visit(url, server);
}
[Then(#"no console errors were detected")]
public void ThenNoConsoleErrorsWereDetected()
{
ValidateTheConsoleResults();
}
protected void Visit(string ext, int server)
{
WriteToReport(GetTheCurrentMethod());
if (server == 1)
ThisUrl = LiveUrl;
else
ThisUrl = PageUrl;
WriteToReport("Load page " + ThisUrl);
Driver.Navigate().GoToUrl(ThisUrl + ext);
WebDriverWait wait = new WebDriverWait(Driver, TimeSpan.FromSeconds(10));
wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.UrlContains(ThisUrl));
}
protected void ValidateTheConsoleResults()
{
WriteToReport(GetTheCurrentMethod());
Visit();
var errors = 0;
//now we check the logs for errors
var browserLogs = Driver.Manage().Logs.GetLog(LogType.Browser);
if (browserLogs.Count > 0)
{
foreach (var log in browserLogs)
{
if (log.Level.Equals(LogLevel.Warning))
{
WriteToReport("Logged Warning - " + log);
continue;
}
else
{
WriteToReport("Logged Error - " + log);
errors++;
}
}
}
if (errors != 0) AssertFalse(errors + " Console errors detected");
else AssertTrue("No console errors detected");
}
#JimEvans you are a star
That solved it, many thanks
I am following the Windows Live SDK 5.6 example codes and have my own simple app trying to login OneDrive. With my Microsoft account given step by step, seems everything is fine, however, i always get System.NullReferenceException, when application goes to this page again, when i click the single button:
private async void signInBtn_Click(object sender, RoutedEventArgs e)
{
try
{
authClient = new LiveAuthClient();
System.Diagnostics.Debug.WriteLine("authClient = " + authClient);
loginResult = await authClient.LoginAsync(new string[] { "wl.signin", "wl.skydrive", "wl.skydrive_update", "wl.photos" });
if (loginResult.Status == LiveConnectSessionStatus.Connected)
{
liveClient = new LiveConnectClient(loginResult.Session);
var meResult = await liveClient.GetAsync("me");
System.Diagnostics.Debug.WriteLine(meResult.Result["name"].ToString() + ", " + "You have logged in OneDrive!");
}
}
catch (LiveAuthException authExp)
{
System.Diagnostics.Debug.WriteLine("LiveAuthException = " + authExp.ToString());
}
catch (LiveConnectException connExp)
{
System.Diagnostics.Debug.WriteLine("LiveConnectException = " + connExp.ToString());
}
}
it throws exception at this line:
loginResult = await authClient.LoginAsync(new string[] { "wl.signin", "wl.skydrive", "wl.skydrive_update", "wl.photos" });
Anything goes wrong in my codes? Even referred to the sample codes?
Try passing a list instead of a String array:
public static async Task<LiveLoginResult> LoginAsync()
{
List<String> oneDriveScopes = new List<String>() { "wl.signin", "wl.basic", "wl.skydrive_update" };
LiveAuthClient authClient = new LiveAuthClient();
LiveLoginResult authResult;
try
{
authResult = await authClient.LoginAsync(oneDriveScopes);
}
catch
{
return null;
}
return authResult;
}
I finally managed to get the code working: before running the code, i have to associate my app in the windows store, so that in the project, there is one file called Package.StoreAssociation.xml generated.
With authentication, my live account information is retrieved correctly and no exception any more.
I am developing a Windows store app, however I used this method to generate an user id when the app open by first time
private string host = "http://etc.com";
public async void RegisterUsuario() {
string displayName = await UserInformation.GetDisplayNameAsync();
string url = host + "/json/Register.php?code=" + displayName;
try
{
var http = new HttpClient();
var jsonText = await http.GetStringAsync(url);
var jsonValues = JsonArray.Parse(jsonText)[0];
var status = jsonValues.GetObject().GetNamedString("status");
if (status == "error")
{
var dialog = new MessageDialog("No se pudo registrar tu usuario", "¡Oops!");
await dialog.ShowAsync();
}
else
{
ApplicationDataContainer localSettings = ApplicationData.Current.LocalSettings;
localSettings.Values["usuario"] = jsonValues.GetObject().GetNamedNumber("id");
}
}
catch {
alertCatch("No se pudo registrar tu usuario");
}
}
THE JSON RESPONSE:
[{"status":"success","id":32}]
The problem:
In my pc always works fine, but when I submit the app to the windows store I always get this:
http://imgur.com/lOT09l7
the same error that will show the app in the CATCH.
Can you help me, maybe something in the appxmanifest?
In capabilities I selected private and public networks
I can't put the 'db.update' statement to work. When I try to read the database, it always reads the very first data inserted from the else statement. I have traced my program and it does reach the db.update and the values being passed is correct but when I read the table the values don't change.
I'm making a windows store app in windows 8.1 using Visual Studio 2013
here's my code
LastRead dataref = new LastRead { passID = U_pick.chapterID, chapterLastRead = U_pick.chapterNumber, passtitle = mTitle };
var dbpath = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "Drive.db");
using (var db = new SQLite.SQLiteConnection(dbpath))
{
try
{
var lastReadChapter = (db.Table<LastRead>().Where(c => c.passtitle == mTitle)).SingleOrDefault();
if (lastReadChapter != null)
{
lastReadChapter.chapterLastRead = U_pick.chapterNumber;
lastReadChapter.passtitle = U_pick.chapterTitle;
lastReadChapter.passID = U_pick.chapterID;
db.Update(lastReadChapter);
}
else
{
db.Insert(dataref);
}
}
catch(Exception ex)
{
//excepetion msg
}
}
It's because you're making the query by the SingleOrDefault() function.