How to get uri to included asset in Uno Platform? - uno-platform

For integrating with a android binding project I need to provide a Uri pointing to a .zip file, which I have included in the assets and designated as AndroidAsset. How do I get the Uri for such a file?
I already tried ms-appx:///Assets/file.zip and file:///Assets/file.zip
Update:
Import to note is, that the function consuming the Uri is Android native code, so I suspect that ms-appx:// doesn't get resolved properly.
Update2:
It is not possible to provide a stream.
The method I am calling is shown in the sample here: https://github.com/Laerdal/Xamarin.Nordic.DFU.Android/blob/7244627c09e97e05ee2c8e05744f19055981486b/Sample/Nordic/FirmwareUpdater.cs#L27.
_dfuServiceInitiator.SetZip(firmwareZipFile);
The native implementation is shown here: https://github.com/NordicSemiconductor/Android-DFU-Library/blob/07bdaa50cfc5786790bf1ac589b14931de65d099/dfu/src/main/java/no/nordicsemi/android/dfu/DfuServiceInitiator.java#L620
public DfuServiceInitiator setZip(#NonNull final Uri uri) {
return init(uri, null, 0, DfuBaseService.TYPE_AUTO, DfuBaseService.MIME_TYPE_ZIP);
}

Files read from the StorageFile.GetFileFromApplicationUriAsync() method may not return a stable path on UWP, and this is particularly the case on particularly on Android or WebAssembly, where the file is not necessarily on the file system.
On Android, the file is a Stream directly built from the APK file, and on WebAssembly it is stored in a temporary location.
In order to use keep a stable copy of the file, use the following:
var file = await StorageFile.GetFileFromApplicationUriAsync(new System.Uri("ms-appx:///TextFile.txt"));
var newFile = await file.CopyAsync(Windows.Storage.ApplicationData.Current.LocalFolder, file.Name, NameCollisionOption.ReplaceExisting);
var txt = await FileIO.ReadTextAsync(newFile);

The method StorageFile.GetFileFromApplicationUriAsync can be used to get a StorageFile object from an ms-appx Uri.
Then you can use the Path property of the StoragFile to get the local android path. Make note to set the build action of the file as Content.
var file = await StorageFile.GetFileFromApplicationUriAsync(new System.Uri("ms-appx:///Assets/file.zip"));
Android.Net.Uri zipUri = Android.Net.Uri.Parse("file:///"+file.Path);

Related

ASP .net 6 download file by httpclient - problem with stream

I'm creating blazor server app. I use external file storage with RestAPI.
I want to create download button to get file from storage. This may seem easy, but not necessarily.
From file storage I download HttpContent like that
var request = new HttpRequestMessage(HttpMethod.Get, _url);
request.Headers.Add("auth-token", token);
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/octet-stream"));
HttpResponseMessage response = await _Http.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
response.EnsureSuccessStatusCode();
var content = response.Content;
next I act like this tutorial https://learn.microsoft.com/en-us/aspnet/core/blazor/file-downloads?view=aspnetcore-6.0
var fileStream = content.ReadAsStream();
using (var streamRef = new DotNetStreamReference(fileStream))
{
await JS.InvokeVoidAsync("downloadFileFromStream", "file.txt", streamRef);
}
For small files everything work great. But if I try to download large file (100mb), algoritm firstable download file to memory(RAM) of server and later save on local disk of client.
In ideal world I dream that when I click button download, file from external storage will download after delay (with progressbar) like physical file (no stream buffer) form http server e.g. https://www.example.com/file.txt. Of course by my BlazorServer Application with authorization and authentication, and whole neccesery services.
I have solution.
Create Service to service File Storage API
Create controller to avoid cros-origin error
Use microsoft tutorial to create download button https://learn.microsoft.com/en-us/aspnet/core/blazor/file-downloads?view=aspnetcore-6.0

Access to files via URI Android 11

In my project I am using external native library (no source code). One of the library functions receives the URI parameter as input.
On older devices (earlier than android 11) everything works correctly. For instance:
inputUri = Uri.parse("file:///" + inputFileNameConvert); // file:////storage/emulated/0/Android/data/packagename/cache/temp/record.mp3
But for android 11+, due to the restrictions imposed, I use FileProvider.
inputUri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID, new File(inputFileNameConvert)); // content://packagename/cache/temp/record.mp3
The content schema does not work correctly in the native library. I get an error:
The uri source has an incorrect format or an unsupported scheme
How can i pass uri to function with schema file? I need to create a file anywhere on the device without getting permission android.permission.MANAGE_EXTERNAL_STORAGE.
Any ideas?

UnauthorizedAccessException While trying to Clear the Cache in xamarin ios

I get an UnauthorizedAccessException while trying to perform following code in xamarin ios
documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
documentsPath = Directory.GetParent(documentsPath).ToString();
InternalAppDataPath = Path.Combine(documentsPath, "Library");
InternalCacheDataPath = Path.Combine(InternalAppDataPath,"Caches");
if (Directory.Exists(InternalCacheDataPath))
{
Directory.Delete(InternalCacheDataPath, true);
}
While trying to perform the delete function UnauthorizedAccessException is thrown. How can I resolve this?
Thank You
You cannot delete that folder path as it is iOS system path. You will get unauthorized exception.
iOS does not allow a user the access directories that are not public, The only directory that you are allowed to make any changes in, Whatsoever is the document directory that is created for your application namely:
Environment.SpecialFolder.Personal
Now when you do this:
documentsPath = Directory.GetParent(documentsPath).ToString();
InternalAppDataPath = Path.Combine(documentsPath, "Library");
InternalCacheDataPath = Path.Combine(InternalAppDataPath,"Caches");
And then try to make changes into the parent folder of the document directory since you are not Authorized to access these directories it throws the UnauthorizedAccessException.
Now, this is not some sort of permission or something that you can take from the user and make this issue go, It is a restriction by Apple(In my knowledge) and hence you cannot do that.
Good luck
In case of queries feel free to revert.
In case you find some workaround do tell me about it here.

#PutChild Upload file with milton webdav in Mac Finder failed

I'm using milton, and my upload code as follows:
#PutChild
#Transactional
public FileContentItem uploadFile(FolderContentItem parent, String name, byte[] bytes){
String traceId = UuidGenUtil.createUuid();
try {
QUERY_LOGGER.info("[uploadFile][NetdiskController],action=Request, name={}, size={},traceId={}",name,bytes.length,traceId);
In windows, i can upload file successfully, but with Mac Finder, the length of bytes is always 0, and the error as follow:
The Finder can't complete the operation because some data in "Shot.png" can't be read or written (Error code -36)
Anyone know why? Thanks
Update: I try ForkLift webdav client in mac and can upload file successfully
The problem is that mac finder sends first request for creating new file without any byte
After it - call LOCK, which is not available for Dav Level 1, that's why you have bad response from server and mac stop uploading a file. This method availiable only for Dav level 2, so you have to get enterprise license of milton to make it work
After Locking object Finder uploads the file
After - calls UNLOCK method
SO if you want to use mac finder for webdav in milton you have several options:
Get the trial enterprise license and look into this example:https://github.com/miltonio/milton2/tree/master/examples/milton-anno-ref
Realize these methods by yourself by webdav specs
Mock it - extend from MiltonFilter or look into MyOwnServlet in example and in method doFilter/service write something like this:
//mock method, do not use it in production!
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse) resp;
if(request.getMethod().equals("LOCK")){
response.setStatus(200);
response.addHeader("Lock-Token", "<opaquelocktoken:e71d4fae-5dec-22d6-fea5-00a0c91e6be4>");
} else if(request.getMethod().equals("UNLOCK")){
response.setStatus(204);
}else {
doMiltonProcessing((HttpServletRequest) req, (HttpServletResponse) resp);
}
I've checked this code working in the examble by link above: make in web.xml method serving by MyOwnServlet, disable authentication in init by implementing empty security manager, set controller packages to scan "com.mycompany"
p.s. to build the example project I've to delete milton client dependency from pom.xml file

Meteor CollectionFS, condition for each store?

Is it possible to add a condition for each FS.Store for Meteor CollectionFS?
I'm looking to do some sort of function to do a check before each FS.Store and if it fails, just don't upload at all.
For example, I'm trying to check if the uploading image is a certain size. If it isn't, I'd like to stop proceeding with the upload for that FS.Store.
CollectionFS is used to provide efficient way to upload from a file, an url, a blob etc on a storage such as data, GridFS, S3 etc…. The process of checking the data you will send to the server should be handled prior to uploading data to the Collection.
so as CollectionFS supports several kind of data, you might be able (or not) to filter the content before uploading them.
File object (client only) // YES
Blob object (client only) // YES
Uint8Array // YES
A data URI string // YES
A full URL that begins with "http:" or "https:" // NO, not applicable
A local filepath (server only) // NO (server only)
ArrayBuffer Buffer (server only) // NO (server only)
The reason is very simple, into your template you can enum on the file you are willing to upload:
Template.myForm.events({
'change .myFileInput': function(event, template) {
FS.Utility.eachFile(event, function(file) {
// Test here what you want to test on "file", return if the test failed
Images.insert(file, function (err, fileObj) {
});
});
}
});
If you are uploading from an URL, you obviously cannot check the content before you download the content…. If you are uploading a file, blob, data URL string, Uint8Array, the data being still on the client side, it's your job to analyse it and grant or deny the upload.

Resources