Reputation: 13
I have a program with a lot of assets. I want to save one of them from my application in the Downloads folder on the Android device. How can I do this?
Upvotes: 1
Views: 1705
Reputation: 74104
The actual file copy is is straight forward using a mix of C# and the Android Java framework:
var assetName = "someasset.jpg";
var outputName = Path.Combine(Android.OS.Environment.DirectoryDownloads, assetName);
using (var assetStream = context.Assets.Open(assetName))
using (var fileStream = new FileStream(outputName, FileMode.CreateNew))
{
await assetStream.CopyToAsync(fileStream);
}
Then you have to deal with application permissions:
First you need to add the permissions to the manifest. You have to have write access, but most likely need read access also to check if the file already exists in Download folder, etc...
You can do this via Xamarin.Android
application project Options (Build / Android Application / Required Permissions) or manually set them in the manifest:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
But, with Marshmallow and above, you also have ask the user at runtime if the app is allowed to read/write to the device's external storage, review the blog post by Xamarin for details:
The quick/dirty version is you have to ask for permissions and then you wait for those results to see if the user allowed/denied that request:
Request the permissions:
const string writePermission = Manifest.Permission.WriteExternalStorage;
const string readPermission = Manifest.Permission.ReadExternalStorage;
string[] PermissionsLocation =
{
writePermission, readPermission
};
if ((ContextCompat.CheckSelfPermission(this, writePermission) == Permission.Granted) && (ContextCompat.CheckSelfPermission(this, readPermission) == Permission.Granted))
{
// You already have permission, so copy your files...
}
if (ActivityCompat.ShouldShowRequestPermissionRationale(this, writePermission) && (ContextCompat.CheckSelfPermission(this, readPermission) == Permission.Granted))
{
// Displaying a dialog would make sense, but for an example this works...
Toast.MakeText(this, "Will need permission to copy files to your Downloads folder", ToastLength.Long).Show();
return;
}
ActivityCompat.RequestPermissions(this, PermissionsLocation, 999);
Process the result of the request:
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
{
switch (requestCode)
{
case 999:
if (grantResults[0] == Permission.Granted)
{
// you have permission, you are allowed to read/write to external storage go do it...
}
break;
default:
break;
}
}
Upvotes: 3