Android App создать каталог работает для большинства, но выдает ошибку, не может создать каталог на SDCard на многих - PullRequest
1 голос
/ 13 июля 2011

Мое приложение создает имя каталога на SD-карте телефона и сохраняет в нем кучу изображений. Код прекрасно работает для большинства пользователей, но некоторые сообщают об ошибках сохранения файлов.

Вот код, который создает каталог: R.string.dir имеет значение "/ appname /"

dir = Environment.getExternalStorageDirectory() + ((String) getResources().getText(R.string.dir));

if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())){
    File fDir = new File(dir);
    fDir.mkdirs();
}
else{
    showToast(false,"This Application needs a mounted external storage (sdcard).");
    finish();
}

Таким образом, на этом этапе должен быть создан каталог (в конечном итоге это / mnt / sdcard / appname), или приложение завершает работу.

Однако при попытке сохранить файл некоторые пользователи сообщают об этом исключении:

Сообщение: java.io.FileNotFoundException: /mnt/sdcard/appname/file.jpg (Нет такого файла или каталога)

Код, который делает сохранение:

File file = new File("/mnt/sdcard/appname/file.jpg");
FileOutputStream fos = null;
try {
    fos = new FileOutputStream( file );
    b.compress(Bitmap.CompressFormat.JPEG, 100, fos );
}
catch( Exception e ) {

Есть предложения? Может ли быть так, что mkdirs () вернет false (хорошо, если бы каталог уже был создан, но я мог бы записать туда файл)? Что может быть еще одной причиной для возврата false, если sdcard смонтирован? Как я могу справиться с этим лучше?

Да, мы используем уникальные имена файлов (добавление System.currentTimeMillis () к имени файла). Также поток закрывается в конце

        finally
        {

        if(fos != null) {

        try {

        fos.close();

        }
        catch(Exception ex){

        ex.printStackTrace();

        }

        }

Ответы [ 2 ]

4 голосов
/ 13 июля 2011

Вы предполагаете (во втором примере кода), что пути sdcard во всех устройствах равны /mnt/sdcard/. Это неверное предположение. Вы должны вызвать Environment.getExternalStorageDirectory , чтобы получить правильный путь.

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

if (!file.exists()) {
    file.createNewFile();
}
0 голосов
/ 13 июля 2011

Подводя итог тому, как идут другие посты, здесь приведены некоторые потенциальные проблемы

  1. Имена не совпадают в первом и втором способе (или они могут быть, не знаю)
  2. Поскольку вы жестко кодируете имя, файл может уже существовать
  3. Вы не закрываете поток
  4. Вы сказали, что строка в ресурсе была установлена ​​в / appname /, мы надеемся, что вы имеете в виду имя вашего приложения, многие люди могут использовать буквальное имя приложения и file.jpg для хранения вещей, так как это появляется во многих руководствах и т. Д. .

Модифицировано, чтобы учесть это, возможно, оно должно выглядеть примерно так

    String sdCard = Environment.getExternalStorageDirectory() + ((String) getResources().getText(R.string.dir));
    File file     = new File(sdCard + "/appname/file.jpg"); // DO YOU WANT YOUR APP NAME OR JUST APPNAME ??? 

    if (file.exists()) // if the jpg already exists --- problems 
       file.delete(); 

    FileOutputStream fos = null;
    try {
        fos = new FileOutputStream(file.getPath());
        b.compress(Bitmap.CompressFormat.JPEG, 100, fos );
        fos.close(); 
    }
    catch( Exception e ) { ... }

Помимо этого, могут быть и другие потенциальные проблемы. Если пользователь подключил устройство к USB-порту и установил в качестве жесткого диска, что SD-карта может быть недоступна, SD-карта может быть доступна только для чтения, у пользователя может не быть SD-карты (которую вы проверяете, поэтому вычеркните эту)

...