「Environment.getExternalStorage()
」を使用してファイルを保存および管理しています。そして、そのメソッドではlogcat
からの警告メッセージはなく、非常にうまく機能します。
しかし、私のプロジェクトはメソッド「Context.getExternalFilesDir(String type)
」を使用する必要があり、警告メッセージがあります
ContextImpl:ディレクトリの確認に失敗しました:/ storage/external_SD/Android/data /(パッケージ名)/ files
幸いなことに、Fileオブジェクトは正常に機能します(フォルダーの読み取りまたは書き込みまたは作成も機能します)。
しかし、私はその警告メッセージを解決する方法を知りたいです。私は何かを見逃していますか?
警告メッセージがどのように表示されるかを知っている必要があります。
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つのディレクトリが生成されます。利用できない場合、警告が表示されます。
結論は、警告を修正する必要がないということです。
ファイルを繰り返し、このAPIを何度も呼び出すコードがある場合、この警告はログ汚染を引き起こす可能性があります。これを解決するには(警告は実際には害がないため)、getExternalFilesDir/getExternalCacheDirの呼び出し結果を保存し、その後APIを呼び出す代わりに保存された値を返すラッパークラスを作成できます。この方法では、少なくともこのメッセージは一度しか表示されません。
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;
}
}