Parse error when programmatically downloading and starting an app
Parse error when programmatically downloading and starting an app
I'm using Xamarin Forms and have been trying to let my app auto-update. This is a private app that doesn't go through the Store, only the .apk
is manipulated.
.apk
I'm downloading the .apk
and starting it programmatically when a newer version is available. The download seems to be going fine, but when launching the downloaded .apk
, I get a parse error.
.apk
.apk
try
{
this.OnEnded += Download_OnEnded;
string uri = string.Format("setupFilesAndroid/{0}/{1}", this.distantVersion, App.CommonDatas.ANDROID_INSTALLER_NAME);
//Prepare the client for the download
HttpClient client = new HttpClient()
{
BaseAddress = new Uri(this.baseUri)
};
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Add("Computer-id", CrossDeviceInfo.Current.Id);
//Create or get the right folder and file to download to
IFolder rootFolder = FileSystem.Current.LocalStorage;
IFolder appFolder = await rootFolder.CreateFolderAsync("App", CreationCollisionOption.OpenIfExists);
IFile file = await appFolder.CreateFileAsync("app.apk", CreationCollisionOption.ReplaceExisting);
//Download the file
using (var fileHandler = await file.OpenAsync(FileAccess.ReadAndWrite))
{
var httpResponse = await client.GetAsync(uri);
byte dataBuffer = await httpResponse.Content.ReadAsByteArrayAsync();
await fileHandler.WriteAsync(dataBuffer, 0, dataBuffer.Length);
}
if (this.OnEnded != null)
{
this.OnEnded(this, null);
}
}
catch {}
And the method called with the OnEnded
event:
OnEnded
//throws an error if the file doesn't exists
//this works fine so I guess the file is in fact downloaded
try
{
IFolder folder = await FileSystem.Current.LocalStorage.GetFolderAsync("App");
IFile file = await folder.GetFileAsync("app.apk");
}
catch
{}
//Use of Dependency service for launching the downloaded app
IDownloadManager native = DependencyService.Get<IUpdateManager>();
native.RunUpdate();
And this is the RunUpdate()
method:
RunUpdate()
IFolder folder = await FileSystem.Current.LocalStorage.GetFolderAsync("App");
IFile file = await folder.GetFileAsync("app.apk");
Intent promptInstall = new Intent(Intent.ActionView).SetDataAndType(Android.Net.Uri.FromFile(new Java.IO.File(file.Path)), "application/vnd.android.package-archive");
promptInstall.AddFlags(ActivityFlags.NewTask);
Forms.Context.StartActivity(promptInstall);
Any help? Or at least a pointer on how to debug this?
Edit: The update works fine when downloading and installing it manually. I can't find a way to check the programmatically downloaded file though as it's downloaded into an inaccessible path (something like /data/user/0/...
).
/data/user/0/...
Edit2: After some more tests, the downloaded file is fine and is able to fully reinstall the app, so the error most likely happens on Forms.Context.StartActivity(promptInstall);
Forms.Context.StartActivity(promptInstall);
Sorry I forgot to say it but yes, everything goes fine when I download and update manually. Though I can't have access to the downloaded file when I do this programmatically so I can't check that.
– yurden
Jun 28 at 15:51
Why not to store the file there where you've permission to do I/O ? @yurden
– Toaster
Jun 28 at 16:01
I had the same issue and it were network related problems. Calculate MD5 hash of the APK to be sure that it is "downloaded successfully".
– EvZ
Jun 28 at 16:07
@Toaster Well the user shouldn't ever see that downloaded file anywhere, it should all happen "magically" to him. Besides, I'm still unsure of my knowledge regarding storage on mobile, and PCLStorage offers either LocalStorage or RoamingStorage so I stuck with LocalStorage which was the one used in almost every threads I've read on the matter.
– yurden
Jun 28 at 16:10
1 Answer
1
I had a similar issue when I implement an AutoUpdater for our app.
In my case the source of the problem was that I simply forgot to flush the filestream which was writing the file after it was done.
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Does the updated APK you're downloading install when you install is manually? Did you check that the file isn't corrupt or signed wrongly etc?
– Gerald Versluis
Jun 28 at 15:38