Hi for some time im trying install downloaded .apk file from my website but still get same error and after while still cant figure it out why it happens
public void OpenFile(byte[] data, string name)
{
string directory = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
string path = directory + name;
foreach (string file in Directory.GetFiles(directory))
{
if (Path.GetExtension(file) == ".apk")
File.Delete(file);
}
File.WriteAllBytes(path, data);
Intent intent = new Intent(Intent.ActionView);
Android.Net.Uri fileUri = null;
if ((int)Build.VERSION.SdkInt < 23)
fileUri = Android.Net.Uri.FromFile(new Java.IO.File(path));
else
//fileUri = Uri.Parse("content://" + path);
//this is where error occures
fileUri = FileProvider.GetUriForFile(this, "aaaa", new Java.IO.File(path));
intent.SetDataAndType(fileUri, "application/vnd.android.package-archive");
intent.SetFlags(ActivityFlags.GrantReadUriPermission);
this.StartActivity(intent);
}
public void InstallApk(string LatestVersion)
{
HttpClient client = new HttpClient();
HttpResponseMessage response = client.GetAsync(BaseUrl + $"mobile/DownloadVersion?version={LatestVersion}").Result;
var _stream = response.Content.ReadAsByteArrayAsync().Result;
System.Diagnostics.Debug.WriteLine(_stream.Length);
var fileName = response.Content.Headers.ContentDisposition.FileName;
OpenFile(_stream, "/com.JakubStegienko.Mobile_app.apk");
}
and here is how and where im trying to use it
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
DependencyService.Register<IInstallerService, InstallerService>();
LoadApplication(new App());
Instance = this;
InstallApk("1.1");
}
AndroidManifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.JakubStegienko.Mobile_app" android:installLocation="preferExternal">
<uses-sdk android:minSdkVersion="26" android:targetSdkVersion="31" />
<!--Permissions-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<application android:allowBackup="true" android:label="Mobile App.Android" android:theme="@style/MainTheme" android:icon="@mipmap/icon" android:supportsRtl="true">
<provider android:name="androidx.core.content.FileProvider" android:authorities="aaaa" android:exported="false" android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths" />
</provider>
</application>
</manifest>
and provider_paths
<?xml version="1.0" encoding="utf-8" ?>
<paths >
<external-path
name="external_files"
path="." />
</paths>
i know i miss some little thing but i cant figure it out
fileUri = Uri.Parse("content://" + path);
I also tried creating uri this way but when intent starts give error "while analizing package error occures"
Thanks for any help
Edit
[zygote64] Attempt to remove non-JNI local reference, dumping thread
[monodroid-debug] Trying to initialize the debugger with options: --debugger-agent=transport=dt_socket,loglevel=0,address=127.0.0.1:8880,server=y,embedding=1
[monodroid-gc] GREF GC Threshold: 46080
[zygote64] Attempt to remove non-JNI local reference, dumping thread
Resolved pending breakpoint for 'Xamarin.HotReload.HotReloadAgent.BreakpointCheckpoint()' to D:\a\_work\1\s\HotReload\Source\Xamarin.HotReload.Agent\HotReloadAgent.cs:414 [0x00000].
Loaded assembly: /data/data/com.JakubStegienko.Mobile_app/files/.__override__/System.Net.Http.dll [External]
Loaded assembly: /data/data/com.JakubStegienko.Mobile_app/files/.__override__/System.Xml.dll [External]
Thread started: #2
Thread started: #3
Thread started: #4
Loaded assembly: /data/data/com.JakubStegienko.Mobile_app/files/.__override__/System.Runtime.Serialization.dll [External]
Loaded assembly: /data/data/com.JakubStegienko.Mobile_app/files/.__override__/System.ServiceModel.Internals.dll [External]
[monodroid-assembly] open_from_bundles: failed to load assembly Xamarin.Forms.Platform.Android.AppLinks.dll
Thread started: #5
[NetworkSecurityConfig] No Network Security Config specified, using platform default
Thread started: <Thread Pool> #6
Thread started: <Thread Pool> #7
Thread started: <Thread Pool> #8
Thread started: <Thread Pool> #9
Thread started: <Thread Pool> #10
Thread started: <Thread Pool> #11
[System.out] (HTTPLog)-Static: isSBSettingEnabled false
[zygote64] Explicit concurrent copying GC freed 1396(211KB) AllocSpace objects, 0(0B) LOS objects, 68% free, 707KB/2MB, paused 461us total 14.112ms
Thread finished: <Thread Pool> #7
Wątek 0x7 zakończył działanie z kodem 0 (0x0).
Thread started: <Thread Pool> #12
Thread finished: <Thread Pool> #6
Thread started: <Thread Pool> #13
Wątek 0x6 zakończył działanie z kodem 0 (0x0).
[zygote64] Background concurrent copying GC freed 3(16KB) AllocSpace objects, 12(1584KB) LOS objects, 64% free, 836KB/2MB, paused 5.548ms total 42.550ms
[zygote64] Background concurrent copying GC freed 3(16KB) AllocSpace objects, 16(2MB) LOS objects, 50% free, 1628KB/3MB, paused 5.864ms total 49.653ms
[zygote64] Explicit concurrent copying GC freed 86(35KB) AllocSpace objects, 10(1320KB) LOS objects, 68% free, 700KB/2MB, paused 685us total 25.114ms
[0:] 20475508
[zygote64] Do partial code cache collection, code=30KB, data=25KB
[zygote64] After code cache collection, code=30KB, data=25KB
[zygote64] Increasing code cache capacity to 128KB
**System.NullReferenceException:** 'Object reference not set to an instance of an object.'
Debugging output while running app
Solution: So after i changed a bit how do i get path for a file it some how works
my quess is that now i get path to specific external path
string directory = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
string path = directory + name;
to this
var path = Path.Combine(Android.App.Application.Context.GetExternalFilesDir("").AbsolutePath, "com.JakubStegienko.Mobile_app.apk");
Thanks to Jianwei Sun - MSFT
You can try to the following steps to install the apk:
1.Add the provider in the AndroidManifest.xml, such as:
<application android:allowBackup="true" android:icon="@drawable/androidicon" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme">
<provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.provider" android:exported="false" android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths" />
</provider>
</application>
2.Create the provider_paths.xml in the folder named xml below the values folder in the android part.
<paths >
<external-path
name="external_files"
path="." />
</paths>
3.Use the following code to install the apk:
//When the apk file is downloaded, put it in the path you set
var path = Path.Combine(Android.App.Application.Context.GetExternalFilesDir("").AbsolutePath, "com.MyCompany.clamexdroid.apk");
Java.IO.File file = new Java.IO.File(path);
Intent install = new Intent(Intent.ActionView);
Android.Net.Uri apkURI = FileProvider.GetUriForFile(this, this.ApplicationContext.PackageName + ".provider", file);
install.SetDataAndType(apkURI, "application/vnd.android.package-archive");
install.AddFlags(ActivityFlags.NewTask);
install.AddFlags(ActivityFlags.GrantReadUriPermission);
StartActivity(install);