xamarin 在Maui应用程序平台Android上删除文件

u4dcyp6a  于 2022-12-07  发布在  Android
关注(0)|答案(2)|浏览(187)

我有一个maui应用程序,它读取SD卡上的数据日志(在Android中,SD卡是在一个USB阅读器附加- filemanagers和maui文件拾取器高兴地看到hte USB外部驱动器和读取和打开文件)信息从文件(csv)中提取写入SQL,然后将文件备份到云现在很重要的是从SD卡中删除数据日志-
这个问题似乎只在Android上,即使这样,它也会像预期的那样在模拟器上执行删除操作。在Android〉10(我的目标是11 SDK 31)的真实的手机上,它说它已经删除了文件(file.exists返回false),但文件仍然存在于SD卡上
我知道Android收紧了权限,我在清单文件中有请求权限,我也有请求用户确认权限的代码,但仍然删除不工作,如微软文档中所述
我知道,但不太明白的机制,Android使一个打开的文件的副本,但这似乎没有相关性,因为我已经打开并阅读了文件.我也不确定这有什么关系的事实,我试图删除外部USB-SD存储上的文件-如果我移动数据记录到内部存储,如下载,问题仍然存在.
Android权限:(你可以看到我把厨房的Flume扔向它;- )

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  <uses-permission android:name="android.permission.INTERNET" />
  <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.READ_INTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.MANAGE_USB" />
  <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.USE_CREDENTIALS" />
  <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
  <uses-permission android:name="android.permission.MOUNT_FORMAT_FILESYSTEMS" />
  <uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
  <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

关键代码如下所示(在这种情况下,如果数据记录包含少于300行,则它不包含有用数据,因此将被删除-但原理是相同的,一旦数据记录被完全处理并被处置,NB这是在MAUI上使用VS 2022 17.3预览6 fwiw xamarin Android sdk是v 13文件删除在Windows上工作-我还没有“我还没有试过iOS,因为我很难让我的Mac电脑与Windows上的VS同步
总之,c#代码正在做它在microsoft docs中所说的删除和报告文件不存在,但实际上并没有这样做!!这是我无法理解的
有人有什么好主意吗

var ff1 = System.IO.File.ReadAllLines(csvorig);
       var csvlen= ff1.Length;
        if (csvlen < 300)   // one line per second means 5 mins ignore
        {
            var nl = System.Environment.NewLine;
            var answ = await DisplayAlert(dbpath + nl + "Small file", "the file you've 
               selected contains no flight" + nl + "prob cause = switching on avionics for < 
               5min " + nl + " file should be deleted", "DELETE", "ignore");
        if (answ)
        {
        status = await Permissions.CheckStatusAsync<Permissions.StorageWrite>();
        if (status == PermissionStatus.Denied)
        {
            PermissionStatus status2=awaitPermissions.RequestAsync<Permissions.StorageWrite>();
        }
              /// check permissions AGAIN !! in case problem there
        status = await Permissions.CheckStatusAsync<Permissions.StorageWrite>();
        if (status == PermissionStatus.Denied)
        {
        await DisplayAlert("warn", "Sorry cannot grant permission \n you will need to delete this file using filemanager \n" + csvorig, "cancel");
        return;
        }
        try
            {
             // ensure that file attribs are normal // saw this in one post on file 
             //deleting but not ref maui
            File.SetAttributes(csvorig, FileAttributes.Normal);
            File.Delete(csvorig);
            }
        catch (Exception ee)
            {
          // code never throws exception
            var m = ee.Message;
            await DisplayAlert("", m, "Cancel");
            }
    
        if (File.Exists(csvorig))
        {           
            await DisplayAlert("warn", "failed to delete", "cancel");
        }
        else
        { // file is ALWAYS reported as 'not existing' but is still there next 
          //time use filepicker
        await DisplayAlert(csvorig, "has been deleted", "back"); }
        }
    }
yqyhoc1h

yqyhoc1h1#

我做了一个示例来测试,如果应用程序只有读写存储的权限,它不能删除SD卡或存储中的文件,它只能删除应用程序自己的私有文件夹中的文件。
所以它需要用户授予应用管理存储的权限。你可以试着把下面的代码放在mainactivity中。

protected override void OnCreate(Bundle savedInstanceState)
{
    if (!Android.OS.Environment.IsExternalStorageManager)
    {
        Intent intent = new Intent();
        intent.SetAction(Android.Provider.Settings.ActionManageAppAllFilesAccessPermission);
        Android.Net.Uri uri = Android.Net.Uri.FromParts("package", this.PackageName, null);
        intent.SetData(uri);
        StartActivity(intent);
    }
    base.OnCreate(savedInstanceState);
}
sbdsn5lh

sbdsn5lh2#

Thanks to Liyun Zhang I've worked something out I am trying to delete hte 'cahced' file thus - name derived from filepicker that filename is reported as "storage/emulated/0/Android/data/com.companyname.flymaui6/cache/xxxxxxxxxxxxxx/log_2206260834_EGJB.csv"
But actually what I want is the name of the file on the SD card. Filemanager gave me a clue - in properties of a log file on the usb sd card reader it says the path is "/mnt/media_rw/547e-78ae/data_log/log220715_0834XXX.csv" the 547e-78ae is a unique ref of the actual sd card so thats tricky but I know the sd reader will prob be only one with /mnt/media_rw in it so I've implemented this method to get the current SD card path - it just searches for any path with /mnt/media_rw/ and assumes it is the sd card reader (hope that's not too unreliable an assumption.

private async void chkSD()
{
    try
    {
        var xxx = System.Environment.GetLogicalDrives();
        var messtmp = "";
        foreach (string foldnm in xxx)
        {
            if (foldnm.IndexOf("/mnt/media_rw", StringComparison.OrdinalIgnoreCase) >= 0)
            {
                messtmp = foldnm;
                break;
            }
            else
            {
                messtmp = "..";
            }
        }

        sdcardpath = messtmp + "/data_log/";
        if (messtmp.Contains(".."))
        {
            await DisplayAlert("", "could not find SD card \n Only temporary cached files will be deleted", "cancel");
        }
    } catch
    { 
    }
}

Now I just add the "sdcardpath" to the filename before deleting
this should work universally as one is unlikely to get 2 SD card readers on Android machine and this method picks up the unique sd identifier
I dont yet know if the meadia_rw bit of the path is unuversal but so far it does delete the file on the SD card
If I have copied the log file from the sd card to a dolder on hte Androi machine - that is still a work in progress to find the true path of the file when it is in say \download
But I can live with that it is important to have a clean SD card and avoid having user to mess around with filemanager.
All the other stuff is also true - one needs permissions but it turned out to be about finding the true path (hmm sounds like we need a hallelujah here) . the cached file created by Android is deleted anyway
It would be a lot simpler if I could get the 'true' path somehow from FilePicker
thanks for all help

相关问题