Java 使用DocumentFile.createFile()在SD卡中创建新文件时出错;
我正在尝试为Android 5.0及以上版本在SD卡中创建一个新文件。因此,首先我要让用户通过SAF授予权限。这就是我检查所选目录是否为SD卡的方式Java 使用DocumentFile.createFile()在SD卡中创建新文件时出错;,java,android,file,nullpointerexception,storage-access-framework,Java,Android,File,Nullpointerexception,Storage Access Framework,我正在尝试为Android 5.0及以上版本在SD卡中创建一个新文件。因此,首先我要让用户通过SAF授予权限。这就是我检查所选目录是否为SD卡的方式 public static boolean wrong_directory_selected(Uri uri, Context con) { final File uri_path=new File(FileUtil.getFullPathFromTreeUri(uri,con)); if(uri_path
public static boolean wrong_directory_selected(Uri uri, Context con)
{
final File uri_path=new File(FileUtil.getFullPathFromTreeUri(uri,con));
if(uri_path.getName().toLowerCase().equals(new File("SD CARD PATH").getName().toLowerCase()))
{
return false;
}
return true;
}
这就是我试图创建一个新文件的方式
DocumentFile move = DocumentFile(new File("path)).createFile(mime,"name); // But I am getting java.lang.NullPointerException
下面是我用来获取要创建文件的目录的DocumentFile的方法
public static DocumentFile DocumentFile(final File file)
{
DocumentFile rootDocFile = DocumentFile.fromTreeUri(con, permission().getUri());
String[] parts = (file.getPath()).split("\\/");
for (int i = 3; i < parts.length; i++)
{
rootDocFile = rootDocFile.findFile(parts[i]);
}
return rootDocFile;
}
public static UriPermission permission()
{
for (UriPermission permissionUri : con.getContentResolver().getPersistedUriPermissions())
{
final File uri_path = new File(FileUtil.getFullPathFromTreeUri(permissionUri.getUri(), con));
if (uri_path.getName().toLowerCase().equals(new File("SD_CARD_PATH").getName().toLowerCase()))
{
return permissionUri;
}
}
return null;
}
编辑2:
创建文件的路径很好,我也检查了权限URI,即使它不是空的
值为
必须创建文件的路径-/storage/external\u SD
权限Uri-content://com.android.externalstorage.documents/tree/6634-3765%3A
编辑3:
我正在使用它来查找SD卡路径。现在您已经有了文档文件
(这是一个在其中创建文件的目录)通过循环,从答案继续,只需使用myDocumentFile.createFile(…)
在所需的目录
上创建一个新文件
// creating the file
DocumentFile documentFileNewFile = documentFileGoal.createFile(myMimeType,
myNewFileName);
然后流向它
outputStream = getContentResolver().openOutputStream(documentFileNewFile.getUri());
inputStream = new FileInputStream(myInputFile);
...
if (outputStream != null) {
byte[] buffer = new byte[1024];
int read;
while ((read = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, read);
}
}
...
...
...
} finally {
if (inputStream != null)
inputStream.close();
if (outputStream != null) {
outputStream.flush();
outputStream.close();
}
}
Edite通过在每个循环上检查
rootDocFile
的值,防止在nullDocumentFile
上查找文件。(当用户选择错误路径而不是sd卡时发生)
for(int i=3;i
我不知道FileUtil
是什么,只是它有缺陷,因为您无法从Uri
获取文件(除非创建一个文件并将Uri
标识的内容复制到它中,我怀疑FileUtil
正在做什么)@commonware我已经编辑了这个问题,并添加了我的FileUtil
类。请看一看。您正在对Android的实现进行各种假设,这些假设可能在Android操作系统版本之间发生变化,包括设备制造商和定制ROM开发人员所做的变化。“有没有可靠的方法可以帮助我知道,如果用户选择了正确的目录,即SD卡目录”--你不应该关心用户选择将其内容存储在哪里。如果他们想将你的应用程序与Google Drive或其他存储提供商一起使用,这是他们的决定,而不是你的决定。”我还用三种不同的制造商测试了代码,似乎可以很好地使用它们”--有近10000种设备型号,来自三个以上的制造商。@Rahulrr2602“如果用户将其SD卡更改为新的SD卡,权限会发生什么变化?”“-如果您谈论的是通过在文件选取器中选取目录而授予的特定于目录的权限,则该权限将附加到包含sd卡分区id的树Uri。因此,该权限将有效地钉在物理sd卡上,并且如果用户更改或重新格式化该卡,该权限将丢失。请解释您拒绝投票的原因。”。我将尽我所能提供帮助:)我在创建新文件时得到java.lang.NullPointerException
。我认为DocumentFile
方法返回null,这意味着我在某个地方错了,因为DocumentFile为null。如果你想在sd卡上创建一个新文件,你需要提供你想要的循环目录路径。这样您就有了一个DocumanetFile
,它是一个目录。然后在里面创建你的文件。我提供了路径,而且它在大多数情况下运行良好,但有时DocumentFile
方法返回的DocumentFile
是空的。当你不得不要求用户为你提供另一张sd卡时,你永远不应该得到空的DocumentFile
路径仅当循环成功找到您的rootDocFile,然后使用从onActivityResult
获得的TreeUri
将提供的sd卡的路径保存在列表中。
outputStream = getContentResolver().openOutputStream(documentFileNewFile.getUri());
inputStream = new FileInputStream(myInputFile);
...
if (outputStream != null) {
byte[] buffer = new byte[1024];
int read;
while ((read = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, read);
}
}
...
...
...
} finally {
if (inputStream != null)
inputStream.close();
if (outputStream != null) {
outputStream.flush();
outputStream.close();
}
}
for (int i = 3; i < parts.length; i++)
{
if (rootDocFile != null) {
rootDocFile = rootDocFile.findFile(parts[i]);
}
}