簡體   English   中英

文件存在且是目錄,但 listFiles() 返回 null

[英]File exists and IS directory, but listFiles() returns null

File.listFiles()的文檔表明只有在調用它的文件不是目錄的情況下才會返回null

我有以下幾點:

String dir = "/storage/emulated/0";
File f = new File(dir);
Log.v("Files",f.exists()+"");
Log.v("Files",f.isDirectory()+"");
Log.v("Files",f.listFiles()+"");

日志寫道:

true
true
null

出於某種原因,即使File被識別為有效目錄, listFiles( ) 也會返回null 我對 Android 文件層次結構的行為不是很熟悉,所以我猜問題出在那里。

作為參考,我正在 Moto X 上進行調試,無論手機是否插入我的計算機,結果都是一樣的 - 所以我認為這與插入時的安裝無關。

對於有此問題的人,請將其添加到 AndroidManifest.xml 中:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

問題解決了:D

編輯:如果這不起作用,請確保路徑是否正確

除了其他答案和評論,我建議您檢查是否需要

<application android:requestLegacyExternalStorage="true"

在您的清單中。 似乎最近的一些api需要它。

無論如何, zapl 的評論相當短,但很有見地。 您可以“ls -ld”設備上的目錄(通過“adb shell”或其他一些shell)。 如果您對該目錄具有“r”權限,則可以調用 listFiles()。 否則,它返回 null。 請注意,如果您知道文件名並且對該目錄具有“x”權限,則您可以訪問不可讀目錄下的文件。 你可以通過“whoami”和“groups”命令知道你是誰。

對於 android 23 或更高版本,您需要在 onresume 方法中以編程方式授予運行時權限,如下所示,

public final String[] EXTERNAL_PERMS = {Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE
};

public final int EXTERNAL_REQUEST = 138;

requestForPermission();

public boolean requestForPermission() {

    boolean isPermissionOn = true;
    final int version = Build.VERSION.SDK_INT;
    if (version >= 23) {
        if (!canAccessExternalSd()) {
            isPermissionOn = false;
            requestPermissions(EXTERNAL_PERMS, EXTERNAL_REQUEST);
        }
    }

    return isPermissionOn;
}

public boolean canAccessExternalSd() {
    return (hasPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE));
}

private boolean hasPermission(String perm) {
    return (PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(this, perm));

}

對於有此問題的人,您要授予讀取權限,請將其添加到 AndroidManifest.xml 中:

android:name="android.permission.READ_EXTERNAL_STORAGE" 

你還應該授予許可

設置 > 應用程序 > “您的應用程序名稱” > 權限 > 存儲

來自 File 'listFiles' 方法文檔:如果此抽象路徑名不表示目錄,或者發生 I/O 錯誤,則返回 null。

所以可能發生了 I/O 錯誤。 檢查該目錄的權限,運行java程序的用戶是否有讀取該目錄的權限? 如果沒有,那就有你的答案。 如果他們這樣做,那么目錄可能是空的。

順便說一句,您不應該使用 +"" 將某些內容轉換為字符串,這是一種不好的做法,因為它比 String.valueOf 慢。 我會使用 apache 的 StringUtils 將該數組加入一個字符串中,但這需要將該 jar 添加到您的類路徑中。

只需在 manifest uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"添加權限,您的問題就會得到解決。

@tamo 的回答解決了我的問題,我在 ANQ 上編譯 exoplayer,然后設置:

構建.gradle:

android {
compileSdkVersion 29
buildToolsVersion '29.0.0'

defaultConfig {
    minSdkVersion 16
    targetSdkVersion 29
}

清單.xml :

  <application
  android:name="com.google.android.exoplayer.demo.ExoPlayerDemoApplication"
  android:label="@string/application_name"
  android:icon="@drawable/ic_launcher"
  android:largeHeap="true"
  android:allowBackup="false"
  android:requestLegacyExternalStorage="true">

我檢查了android開發站點,它已經解釋了這一點: https : //developer.android.com/training/data-storage/compatibility

如果您的目標是 API 29 或更高版本,只需遵循 google 的設置。

  1. 列表項

將此添加到您的 AndroidManifest.xml <application android:requestLegacyExternalStorage="true" .../> 它對我有用。

我的問題是由於某種原因 android:sharedUserId="android.uid.system" 屬性不允許應用程序在特定設備上讀取 /sdcard/ 。

因為我只需要做一個快速測試,我刪除了 sharedUserId 屬性,測試並添加回來。

首先確保您正在請求讀取外部存儲的權限

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

如果您願意,可以使用 Dexter 庫請求許可,使用 dexter 庫請求許可非常容易

這是鏈接

德克斯特圖書館

然后在清單<application標簽中添加以下標簽

android:requestLegacyExternalStorage="true"

那么 listFiles() 函數將不會返回空數組

我在 java 中遇到了同樣的問題,但在 android 中沒有,我正在讀取帶引號的路徑的配置文件。 我通過刪除引號解決了我的問題

所以你可以通過字符串替換函數來完成,也可以不加引號

String someString="C:\\path"; someString=someString.replace("\\"","");

<uses-permission .... >部分的清單文件中,添加這一行android:name="android.permission.READ_EXTERNAL_STORAGE" 我認為這可能會解決您的問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM