微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

有什么办法可以通过File.writeAsStringSync将文件写入SDCard

如何解决有什么办法可以通过File.writeAsStringSync将文件写入SDCard

我正在尝试写入SDCard中的文件,发现我需要可移动存储的特殊权限,这在任何已知的Flutter权限处理程序插件中都找不到(我尝试了simple_permission和Permissions_handler,没有使用)。

我试图使用Android的东西来获取那些权限,所以我写了一个简单的函数显示对话框,并且用户允许应用程序修改SDCard的内容

即使获得了SDCARD的权利,使用File.writeAsstringSync方法尝试将文件保存到SDCard时,仍然出现相同的拒绝权限错误

我想知道是否有任何已知的方法/破解/解决方法快速地将SDCard中的文件保存起来。

我使用的android代码与此答案相同:https://stackoverflow.com/a/55024683/6641693

注意::我的目标是android 7及更高版本,但不是android 11。

解决方法

我通过放弃保存dart文件并使用android SAF来解决了这个问题。 首先,我所做的就是尝试获得sdCard修改权限。 之后,我将保存所需的文件。

这是我用来获取权限的代码(又名“允许该应用程序修改sdCard上的内容”对话框)

public void takeCardUriPermission(String sdCardRootPath) {
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
      File sdCard = new File(sdCardRootPath);
      StorageManager storageManager = (StorageManager) getSystemService(Context.STORAGE_SERVICE);
      StorageVolume storageVolume = storageManager.getStorageVolume(sdCard);
      Intent intent = storageVolume.createAccessIntent(null);
      try {
        startActivityForResult(intent,4010);
      } catch (ActivityNotFoundException e) {
        Log.e("TUNE-IN ANDROID","takeCardUriPermission: "+e);
      }
    }
  }

  protected void onActivityResult(int requestCode,int resultCode,@Nullable Intent data) {
    super.onActivityResult(requestCode,resultCode,data);

    if (requestCode == 4010) {

      Uri uri = data.getData();

      grantUriPermission(getPackageName(),uri,Intent.FLAG_GRANT_WRITE_URI_PERMISSION |
              Intent.FLAG_GRANT_READ_URI_PERMISSION);

      final int takeFlags = data.getFlags() & (Intent.FLAG_GRANT_WRITE_URI_PERMISSION |
              Intent.FLAG_GRANT_READ_URI_PERMISSION);

      getContentResolver().takePersistableUriPermission(uri,takeFlags);
      methodChannel.invokeMethod("resolveWithSDCardUri",getUri().toString());
    }
  }

  public Uri getUri() {
    List<UriPermission> persistedUriPermissions = getContentResolver().getPersistedUriPermissions();
    if (persistedUriPermissions.size() > 0) {
      UriPermission uriPermission = persistedUriPermissions.get(0);
      return uriPermission.getUri();
    }
    return null;
  }

因此,为了开始整个权限获取过程,您必须首先调用takeCardUriPermission并传递sdCard路径的URI。

注意:在我的FlutterActivity上,我可以直接使用getExternalCacheDirs()[1].toString()

获取sdCardPath。

调用takeCardUriPermission后,一旦按下允许按钮(或拒绝按钮),就会调用活动结果事件,并调用onActivtyResult方法。当您有多个事件并且需要将其过滤掉时,requestCode检查很有用。

活动结果代码将为应用授予修改sdCard上文件的权限。

getUri方法是我们稍后尝试将字节保存到文件时使用的方法,它返回我们选择的SDCard的URI(您可以有多个sdCard)。

保存文件

我用来保存文件的方法很简单。首先,我们需要获取sdCard的URI并从中创建一个Documentfile,然后遍历该目录的层次结构(DocumentFile可以引用文件和目录)以根据以下内容查找所需的文件这是URI。

我们通过将文件URI分成多个部分,然后通过测试每个部分是否存在来导航层次结构来进行此搜索。一旦测试完所有部分,我们便已经到达文件(如果存在),或者卡在了我们到达的最后一个目录中。

此迭代的结果是一个DocumentFile,我们可以对其执行操作。

以下是完整的文件保存代码:

String filepath = (String) arguments.get("filepath");
          final byte[] bytes = methodCall.argument("bytes");

          try{
            if(filepath==null || bytes==null)throw new Exception("Arguments Not found");
            DocumentFile documentFile = DocumentFile.fromTreeUri(getApplicationContext(),getUri());
            String[] parts = filepath.split("/");
            for (int i = 0; i < parts.length; i++) {
              DocumentFile nextfile = documentFile.findFile(parts[i]); 
              if(nextfile!=null){
                documentFile=nextfile;
              }
            }
            if(documentFile!=null && documentFile.isFile()){
              OutputStream out = getContentResolver().openOutputStream(documentFile.getUri());
              out.write(bytes);
              out.close();
            }else{
              throw new Exception("File Not Found");
            }
          }catch (Exception e){
            result.error("400",e.getMessage(),e);
            return;
          }
          result.success(true);

注意:在我的代码中,我在MethodChannel的{​​{1}}下调用它,这将给我我需要的参数:MethodCallHandler,它是字符串URI我要写入的文件和代表我要保存的数据的filePath字节数组。 bytes

也可以这样说

文件写入代码很简单:打开文件,写入数据并关闭文件。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?