我正在嘗試在Android 5.0及以上版本的SD卡中創建一個新文件。所以首先我讓用戶通過SAF授予權限。這是我如何檢查所選目錄是否爲SD卡。使用DocumentFile.createFile()在SD卡中創建新文件時出錯。
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;
}
該代碼大部分時間工作正常,但有時我得到java.lang.NullPointerException
。
任何幫助將不勝感激。
編輯:這是我FileUtil類
public final class FileUtil {
private static final String PRIMARY_VOLUME_NAME = "primary";
@Nullable
public static String getFullPathFromTreeUri(@Nullable final Uri treeUri, Context con)
{
if (treeUri == null)
{
return null;
}
String volumePath = FileUtil.getVolumePath(FileUtil.getVolumeIdFromTreeUri(treeUri),con);
if (volumePath == null)
{
return File.separator;
}
if (volumePath.endsWith(File.separator))
{
volumePath = volumePath.substring(0, volumePath.length() - 1);
}
String documentPath = FileUtil.getDocumentPathFromTreeUri(treeUri);
if (documentPath.endsWith(File.separator))
{
documentPath = documentPath.substring(0, documentPath.length() - 1);
}
if (documentPath.length() > 0)
{
if (documentPath.startsWith(File.separator))
{
return volumePath + documentPath;
}
else {
return volumePath + File.separator + documentPath;
}
}
else
{
return volumePath;
}
}
private static String getVolumePath(final String volumeId, Context con)
{
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
{
return null;
}
try {
StorageManager mStorageManager =
(StorageManager) con.getSystemService(Context.STORAGE_SERVICE);
Class<?> storageVolumeClazz = Class.forName("android.os.storage.StorageVolume");
Method getVolumeList = mStorageManager.getClass().getMethod("getVolumeList");
Method getUuid = storageVolumeClazz.getMethod("getUuid");
Method getPath = storageVolumeClazz.getMethod("getPath");
Method isPrimary = storageVolumeClazz.getMethod("isPrimary");
Object result = getVolumeList.invoke(mStorageManager);
final int length = Array.getLength(result);
for (int i = 0; i < length; i++)
{
Object storageVolumeElement = Array.get(result, i);
String uuid = (String) getUuid.invoke(storageVolumeElement);
Boolean primary = (Boolean) isPrimary.invoke(storageVolumeElement);
// primary volume?
if (primary && PRIMARY_VOLUME_NAME.equals(volumeId))
{
return (String) getPath.invoke(storageVolumeElement);
}
// other volumes?
if (uuid != null)
{
if (uuid.equals(volumeId))
{
return (String) getPath.invoke(storageVolumeElement);
}
}
}
// not found.
return null;
}
catch (Exception ex)
{
return null;
}
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private static String getVolumeIdFromTreeUri(final Uri treeUri)
{
final String docId = DocumentsContract.getTreeDocumentId(treeUri);
final String[] split = docId.split(":");
if (split.length > 0)
{
return split[0];
}
else
{
return null;
}
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private static String getDocumentPathFromTreeUri(final Uri treeUri)
{
final String docId = DocumentsContract.getTreeDocumentId(treeUri);
final String[] split = docId.split(":");
if ((split.length >= 2) && (split[1] != null))
{
return split[1];
}
else
{
return File.separator;
}
}
}
編輯2:
在該文件已被創建的路徑是不錯,我也檢查了權限URI和即使這不是null。
值是
該文件必須是created-路徑/storage/external_SD
權限URI-content://com.android.externalstorage.documents/tree/6634-3765%3A
編輯3:
我用這library找到SD卡路徑。
我不知道'FileUtil'是,它比其他的車,因爲你不能從一個'Uri'得到'File'(除了創建一個文件並將'Uri'標識的內容複製到文件中,我懷疑FileUtil正在做什麼)。 – CommonsWare
@CommonsWare我編輯了這個問題,並添加了我的'FileUtil'類,你可以請看看。 – Rahulrr2602
您正在對Android操作系統版本之間可能會改變的Android實施做出各種假設,包括設備製造商和自定義ROM開發人員所做的更改。 – CommonsWare