I am running into an issue in a Xamarin Forms project I am working on, building and using on UWP and Android (don't care about iOS currently). My app is one which connects to a Bluetooth device to record data, stores it within the app, and exports the data into a .txt file or similar that is used for other purposes outside the app. On Android, targeting either Android 11 or Android 12.
I am working with Xamarin 17.4.0.301, Visual Studio 17.4.0, and .NET Framework 4.8.04084, and Xamarin.Android SDK 13.1.0.1.
My issue is trying to save to a file repeatedly that is accessible. Currently, I use a file hidden in the app's internal storage, using a filepath like this:
string fileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "data.txt");
This of course works on both UWP and Android; however, since it is internal, it cannot be accessed by a file explorer on Android. To be seen on Android, I have to export it from the app into a file explorer app, using code like this, where the command is tied to a button press:
OnShareDataCommand = new Command(ShareDataButtonClick);
...
private async void ShareDataButtonClick() {
string fileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "data.txt");
await Share.RequestAsync(new ShareFileRequest {
Title = "Share Data",
File = new ShareFile(fileName)
});
}
This requires a user to press the button to export. My desire is for the system to automatically make a file somewhere accessible in the file explorer (like a Downloads folder) and continuously save to it when the function is called. To do this, I have enable access to external storage as such in the Android Manifest:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
But I am running into issues accessing it. The first is when I try to create a filepath that is in external storage like this, based on this StackOverflow question:
var fullPath = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath, "file_name.txt");
When I do this, it says Android is not in the context. I imagine this is because I am in Xamarin Forms building for multiple platforms. How can I fix this? How can I access Android's External Storage while in Xamarin Forms? Can I make a platform specific function, and if so, how do I go about it?
This Xamarin forums solution did not work.
I have tried using this line from the External Storage for Xamarin.Android guide, which also does not work because it says Environment does not have the method used:
Environment.GetExternalStoragePublicDirectory(Environment.DirectoryDocuments).AbsolutePath
Any advice? I do not want to make it an Android specific app, as I need the UWP functionality, but I could make a platform-specific save function.
CodePudding user response:
Since Android 11 Read/Write External storage is not allowed, the permission will not be granted. Unless you have an app like a file explorer and even then you have to apply to Google before it will be accepted. So you need to forget about writing to external storage.
See the following links https://medium.com/swlh/sample-for-android-storage-access-framework-aka-scoped-storage-for-basic-use-cases-3ee4fee404fc https://www.zoftino.com/how-to-create-browse-files-option-in-android https://mateuszteteruk.pl/how-to-use-android-storage-access-framework-with-example https://thedroidlady.com/2020-08-24-android-scoped-storage-demystified
I did it with my app back when I released for Android 11.
If you need any further help just reply here. I should add, I only write Android apps, so I can't help out with anything Forms related or UWP
CodePudding user response:
@ToolmakeSteve, Is your question addressed to me? I'm writing in C# and Xamarin.Android. I don't think a couple of code snippets would provide anything useful. Just follow the links and the link you posted. I'll attempt to provide a test app, but I've not enough time to do that at the moment.