web-dev-qa-db-ja.com

Android:ディレクトリの確認に失敗しました

Environment.getExternalStorage()」を使用してファイルを保存および管理しています。そして、そのメソッドではlogcatからの警告メッセージはなく、非常にうまく機能します。

しかし、私のプロジェクトはメソッド「Context.getExternalFilesDir(String type)」を使用する必要があり、警告メッセージがあります

ContextImpl:ディレクトリの確認に失敗しました:/ storage/external_SD/Android/data /(パッケージ名)/ files

幸いなことに、Fileオブジェクトは正常に機能します(フォルダーの読み取りまたは書き込みまたは作成も機能します)。

しかし、私はその警告メッセージを解決する方法を知りたいです。私は何かを見逃していますか?

17
iroiroys

警告メッセージがどのように表示されるかを知っている必要があります。

getExternalFilesDir(String type)getExternalFilesDirs(String type)を呼び出します(2番目のメソッド名の最後の「s」に注意してください)。

getExternalFilesDirs(String type)はそのタイプのすべてのディレクトリを見つけ、最後にensureDirsExistOrFilter()を呼び出してディレクトリが存在することを確認します。

Dirに到達できない場合、警告が出力されます!

Log.w(TAG, "Failed to ensure directory: " + dir);
dir = null;

そのため、デバイスに2つのSDカードパスがある場合、2つのディレクトリが生成されます。利用できない場合、警告が表示されます。

結論は、警告を修正する必要がないということです。

10
Hongji Song

ファイルを繰り返し、このAPIを何度も呼び出すコードがある場合、この警告はログ汚染を引き起こす可能性があります。これを解決するには(警告は実際には害がないため)、getExternalFilesDir/getExternalCacheDirの呼び出し結果を保存し、その後APIを呼び出す代わりに保存された値を返すラッパークラスを作成できます。この方法では、少なくともこのメッセージは一度しか表示されません。

1
Mr. Bungle

getExternalFilesDir()ソースに従います

/**
 * Ensure that given directories exist, trying to create them if missing. If
 * unable to create, they are filtered by replacing with {@code null}.
 */
private File[] ensureExternalDirsExistOrFilter(File[] dirs) {
    File[] result = new File[dirs.length];
    for (int i = 0; i < dirs.length; i++) {
        File dir = dirs[i];
        if (!dir.exists()) {
            if (!dir.mkdirs()) {
                // recheck existence in case of cross-process race
                if (!dir.exists()) {
                    // Failing to mkdir() may be okay, since we might not have
                    // enough permissions; ask vold to create on our behalf.
                    final IMountService mount = IMountService.Stub.asInterface(
                            ServiceManager.getService("mount"));
                    try {
                        final int res = mount.mkdirs(getPackageName(), dir.getAbsolutePath());
                        if (res != 0) {
                            Log.w(TAG, "Failed to ensure " + dir + ": " + res);
                            dir = null;
                        }
                    } catch (Exception e) {
                        Log.w(TAG, "Failed to ensure " + dir + ": " + e);
                        dir = null;
                    }
                }
            }
        }
        result[i] = dir;
    }
    return result;
}


即時使用Environment.getExternalStorageDirectory()ExternalDirsを取得

public final class StorageUtil {

public static final String DIR_Android = "Android";
private static final String DIR_DATA = "data";
private static final String DIR_FILES = "files";
private static final String DIR_CACHE = "cache";

@Nullable
public static synchronized File getExternalStorageAppFilesFile(Context context, String fileName) {
    if (context == null) return null;
    if (fileName == null) return null;
    if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
        File dirs = buildExternalStorageAppFilesDirs(Environment.getExternalStorageDirectory().getAbsolutePath(), context.getPackageName());
        return new File(dirs, fileName);
    }
    return null;
}


public synchronized static File buildExternalStorageAppFilesDirs(String externalStoragePath, String packageName) {
    return buildPath(externalStoragePath, DIR_Android, DIR_DATA, packageName, DIR_FILES);
}


public synchronized static File buildPath(String base, String... segments) {
    File cur = new File(base);
    for (String segment : segments) {
        cur = new File(cur, segment);
    }
    return cur;
}

}

0
任非凡