Hello,
============Update============
There must be a way to read a file from the Download folder. other apps like Adobe let you copy a pdf from your system to the device download and then open it.
If you want to use ContentResolver to read the binary file, you can use following code to read it.
#if ANDROID
public byte[] ReadBinaryFile(string fileName)
{
ContentResolver contentResolver = Platform.CurrentActivity.ContentResolver;
// query file
Android.Net.Uri uri = MediaStore.Downloads.ExternalContentUri;
string[] projection = { MediaStore.Downloads.InterfaceConsts.Id };
string selection = MediaStore.Downloads.InterfaceConsts.DisplayName + "=?";
string[] selectionArgs = { fileName };
using (ICursor cursor = contentResolver.Query(uri, projection, selection, selectionArgs, null))
{
if (cursor != null && cursor.MoveToFirst())
{
int idColumn = cursor.GetColumnIndex(MediaStore.Downloads.InterfaceConsts.Id);
long fileId = cursor.GetLong(idColumn);
System.Uri anotherSystemUri = new System.Uri(MediaStore.Downloads.ExternalContentUri.ToString());
Android.Net.Uri anotherAndroidUri = Android.Net.Uri.Parse(anotherSystemUri.ToString());
Android.Net.Uri fileUri = ContentUris.WithAppendedId(anotherAndroidUri, fileId);
using (Stream inputStream = contentResolver.OpenInputStream(fileUri))
{
if (inputStream != null)
{
using (MemoryStream memoryStream = new MemoryStream())
{
inputStream.CopyTo(memoryStream);
return memoryStream.ToArray(); // retrun binary
}
}
}
}
}
return null; // cannot read the file
}
#endif
Here is my code to write binary file to the download folder.
#if ANDROID
using Android.Content;
using Android.Provider;
#endif
private void OnCounterClicked(object sender, EventArgs e)
{
#if ANDROID
ContentValues contentValues = new ContentValues();
contentValues.Put(MediaStore.Downloads.InterfaceConsts.DisplayName, "my_binary_file.dat"); // file name
contentValues.Put(MediaStore.Downloads.InterfaceConsts.MimeType, "application/octet-stream"); // binary file MIME
contentValues.Put(MediaStore.IMediaColumns.RelativePath, "Download/MyApp"); // save path(Only works for Android 10+)
// get saved path url
ContentResolver contentResolver = Platform.CurrentActivity.ContentResolver;
// Convert System.Uri to Android.Net.Uri
System.Uri anotherSystemUri = new System.Uri(MediaStore.Downloads.ExternalContentUri.ToString());
Android.Net.Uri anotherAndroidUri = Android.Net.Uri.Parse(anotherSystemUri.ToString());
Android.Net.Uri uri = contentResolver.Insert(anotherAndroidUri, contentValues);
if (uri != null)
{
using (Stream outputStream = contentResolver.OpenOutputStream(uri))
{
if (outputStream != null)
{
byte[] data = { 0x01, 0x02, 0x03, 0x04 }; // simple for binary file
outputStream.Write(data, 0, data.Length);
}
}
}
#endif
}
============================
Starting in Android 11, apps cannot create their own app-specific directory on external storage. To access the directory that the system provides for your app, call getExternalFilesDirs()., So you cannot request write external storage permission.
For Android 12 or later, application need to request and grand the MANAGE_EXTERNAL_STORAGE
permission, then application could write files to the SD Card or external storage.
Declare the MANAGE_EXTERNAL_STORAGE
permission in the manifes
this permission needs to open the android application settings page, then grand this permission by users.
You can use Conditional compilation for android platform code.
For example, you want to request this permission in the button click event. you can popup a SnackBar, tell user about this permission needed and let user to click.
private void OnCounterClicked(object sender, EventArgs e)
{
#if ANDROID
var activity=Platform.CurrentActivity;
if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.R)
{
if (!Android.OS.Environment.IsExternalStorageManager)
{
Google.Android.Material.Snackbar.Snackbar.Make(activity.FindViewById(Android.Resource.Id.Content), "Permission needed!", Google.Android.Material.Snackbar.Snackbar.LengthIndefinite)
.SetAction("Settings", new MyClickHandler()).Show();
}
}
#endif
}
If you request this permission, you need to notice all-files-access-google-play document.
Best Regards,
Leon Lu
If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.