Файловый объект не может найти файл, когда он есть

В моем приложении после того, как пользователь нажимает кнопку, менеджер загрузок начинает загружать файл из Интернета и сохранять его на внутреннюю SD-карту, используя этот код:

void startDownload()
    {
        Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).mkdirs();        
        download_req.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE)
        .setAllowedOverRoaming(false)
        .setTitle(PersianReshape.reshape("Downloading"))
        .setDescription(PersianReshape.reshape("currently downloading the file..."))
        .setDestinationInExternalPublicDir(Environment.getExternalStorageDirectory().getAbsolutePath() , packageId + ".sqlite");
        download_ID = mgr.enqueue(download_req);
    }

После загрузки я планирую проверять его существование каждый раз, когда приложение запускается с этим кодом:

String DatabaseAddress =
Environment.getExternalStorageDirectory().getAbsolutePath() +
"/ee.sqlite";
File file = new File(DatabaseAddress);
Log.d("PATH File: ", DatabaseAddress);
if (file.exists()){
Toast.makeText(getApplicationContext(), "found", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(getApplicationContext(), "not found", Toast.LENGTH_SHORT).show();
}

Теперь, когда я запускаю этот код, он возвращает сообщение «не найдено», тогда как файл уже существует (я проверил его существование с помощью файлового менеджера).

устройство, на котором я тестирую, - это nexus 7, а путь, используемый для сохранения файла загрузки: /storage/emulated/0/ee.sqlite

ee.sqlite — это имя загруженного файла.

/storage/emulated/0/ — это путь по умолчанию, возвращаемый приложением

Разрешения, добавленные в манифест для этого кода:

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

В: Почему file.exists() возвращает false при наличии файла?

ОБНОВЛЕНИЕ: КОГДА Я ИСПОЛЬЗУЮ HARDCODE

File temp = new File("/sdcard/storage/emulated/0/", "ee.sqlite");

это работает, но когда я использую Environment.getExternalStorageDirectory().getPath(), это не работает.


person Nima Sakhtemani    schedule 18.11.2013    source источник
comment
Попробуйте напечатать file.getAbsolutePath(): они (файлы) могут быть в разных каталогах. Другая возможная причина - разрешения, но я не думаю, что это из-за разрешений.   -  person 18446744073709551615    schedule 18.11.2013
comment
file.getAbsolutePath возвращает тот же адрес, что и file.getPath().   -  person Nima Sakhtemani    schedule 18.11.2013
comment
Я имею в виду, что путь назначения загрузки и путь, который вы проверяете на наличие, могут отличаться.   -  person 18446744073709551615    schedule 18.11.2013
comment
Кстати, вы упомянули, что в своем коде вы используете getExternalStoragePublicDirectory() в одном месте и getExternalStorageDirectory() в другом?   -  person 18446744073709551615    schedule 18.11.2013
comment
Если они одинаковы, Log.d("~~~", "----" + new File(file.getAbsolutePath()).exists()) должно печатать true, а Log.d("~~~", "----" + file.exists()) печатать false. Это было бы абсурдно, а также означало бы ошибку.   -  person 18446744073709551615    schedule 18.11.2013
comment
Кстати, иногда в пути могут заползать пробелы. Пожалуйста, напечатайте путь как Log.d("~~~","path=["+path+"]");   -  person 18446744073709551615    schedule 18.11.2013
comment
Я использовал Environment.getExternalStorageDirectory().getAbsolutePath() в обоих классах моего кода.   -  person Nima Sakhtemani    schedule 18.11.2013
comment
Я сделал журнал, и они оба возвращают false.   -  person Nima Sakhtemani    schedule 18.11.2013
comment
давайте продолжим это обсуждение в чате   -  person Nima Sakhtemani    schedule 18.11.2013


Ответы (2)


Просто инициализируйте File следующим образом:

Обновлено: это просто из-за отсутствия разделителя:

 public static File getExternalStorageDirectory() {
    return EXTERNAL_STORAGE_DIRECTORY;
}

и EXTERNAL_STORAGE_DIRECTORY:

private static final File EXTERNAL_STORAGE_DIRECTORY
        = getDirectory("EXTERNAL_STORAGE", "/sdcard");

static File getDirectory(String variableName, String defaultPath) {
    String path = System.getenv(variableName);
    return path == null ? new File(defaultPath) : new File(path);
}

String baseDir = EXTERNAL_STORAGE_DIRECTORY ;
String fileName = "ee.sqlite";

// Not sure if the / is on the path or not
File file = new File(baseDir + File.separator + fileName);
if (file.exists()) {
        Toast.makeText(getApplicationContext(), "found", Toast.LENGTH_SHORT).show(); 
    }
else{
        Toast.makeText(getApplicationContext(), "not found", Toast.LENGTH_SHORT).show();
    }

Вторая возможность: поскольку вы запускаете его в эмуляторе, вы должны убедиться, что у вас включено внешнее хранилище. Вот так:

В Eclipse выберите «Окно» > «Android SDK и AVD Manager». Выберите соответствующий AVD и нажмите «Изменить».

Window — Android SDK и диспетчер AVD

Убедитесь, что у вас включена поддержка SD-карт. Если вы этого не сделаете, нажмите кнопку «Создать» и выберите параметр «Поддержка SD-карты».

Экран редактирования

person Avijit    schedule 18.11.2013
comment
Как вы дали dirName и fileName? - person Avijit; 18.11.2013
comment
да, String dirName = Environment.getExternalStorageDirectory().getAbsolutePath(); и String fileName = ee.sqlite; - person Nima Sakhtemani; 18.11.2013
comment
Пробовал, но все равно не работает. работает только жестко закодированная строка. - person Nima Sakhtemani; 18.11.2013
comment
Это только из-за разделителя. Ты не дал там. Я упомянул об этом в своем обновленном разделе и обновил свой ответ. - person Avijit; 18.11.2013
comment
Смотрите мой 2-й раздел возможностей - person Avijit; 18.11.2013
comment
Я тестирую приложение на Nexus 7 2012 года с JB 4.3. - person Nima Sakhtemani; 18.11.2013
comment
Что возвращает «Log.d (PATH File:, DatabaseAddress);» - person Avijit; 18.11.2013
comment
Эмулятор возвращает: /storage/sdcard/ee.sqlite, а Nexus 7 возвращает: /storage/emulated/0/ee.sqlite - person Nima Sakhtemani; 18.11.2013
comment
см. этот stackoverflow.com/questions /13737261/ - person Avijit; 18.11.2013
comment
Как вы можете видеть, в Nexus 7 у вас не было такой опции, как / sdcard, верно? Так сделайте что-нибудь вроде вызова внешнего хранилища, как мой обновленный ответ, и дайте мне знать, помогает вам это или нет? - person Avijit; 18.11.2013
comment
Извините, но это не помогло. единственный способ заставить его работать — это добавить строку /sdcard/. --› File file = new File(/sdcard/ + dirName + File.separator , fileName); Работает, а у тебя нет. - person Nima Sakhtemani; 18.11.2013
comment
давайте продолжим обсуждение в чате - person Nima Sakhtemani; 18.11.2013

Наконец-то заработало, изменив объект File.

Решение состоит в том, чтобы изменить объект File на следующее:

File file = new File(Environment.getExternalStorageDirectory().getPath() + dirName + File.separator , fileName);

где имя_каталога:

String dirName = Environment.getExternalStorageDirectory().getAbsolutePath();

и имя файла:

String fileName = "ee.sqlite";

поэтому я мог легко проверить, существует ли файл или нет, используя мою функцию критериев.

if (file.exists()){
            Toast.makeText(getApplicationContext(), "found", Toast.LENGTH_SHORT).show();
        }else{
            Toast.makeText(getApplicationContext(), "not found", Toast.LENGTH_SHORT).show();
        }

Я хотел бы поблагодарить @andru за помощь.

person Nima Sakhtemani    schedule 18.11.2013
comment
Это не имеет особого смысла, вы дважды включаете абсолютный путь к каталогу внешнего хранилища. - person RedGlyph; 14.03.2015