Тестирование Android: состояние хранилища смонтировано, разрешение WRITE_EXTERNAL_STORAGE было объявлено, но по-прежнему не удается записать на SD-карту эмулятора.

Я пишу программу тестирования, и я хочу сериализовать некоторые результаты моих тестов в файл. Я продолжаю получать это раздражающее исключение, в котором отказано в разрешении. Чтобы упростить задачу, я пишу небольшой пример кода и по-прежнему получаю такое же предупреждение об отказе в разрешении. Вот мой код, я использую getExternalStorageDirectory для получения каталога / mnt / sdcard /:

private void writetry(){
        try {
            File sdCard = Environment.getExternalStorageDirectory();
            Log.d("can write", String.valueOf(sdCard.canWrite()));
            Log.d("ExternalStorageState", Environment.getExternalStorageState());
            File file = new File(sdCard, "VisitedScreen.temp");
            //file.createNewFile();
            FileOutputStream f = new FileOutputStream(file);
             byte[] buf = "Hello".getBytes();
             f.write(buf);
             f.close();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

А вот что выводит logcat:

07-12 12:28:47.288: D/can write(253): false
07-12 12:28:47.288: D/ExternalStorageState(253): mounted
07-12 12:28:47.297: W/System.err(253): java.io.FileNotFoundException: /sdcard/VisitedScreen.temp
07-12 12:28:47.437: W/System.err(253):  at org.apache.harmony.luni.platform.OSFileSystem.open(OSFileSystem.java:244)
07-12 12:28:47.437: W/System.err(253):  at java.io.FileOutputStream.<init>(FileOutputStream.java:97)
07-12 12:28:47.437: W/System.err(253):  at java.io.FileOutputStream.<init>(FileOutputStream.java:69)

Я объявил свой файл манифеста тестирования Junit как: (На самом деле это неправильное место для установки разрешения)

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="net.mandaria.tippytipper.test"
    android:versionCode="1"
    android:versionName="1.0" >
    <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="7" />

    <instrumentation
        android:name="android.test.InstrumentationTestRunner"
        android:targetPackage="net.mandaria.tippytipper" />

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

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <uses-library android:name="android.test.runner" />
    </application>


</manifest>

Любое предложение приветствуется!

Добавлено: я копирую тот же код в обычную программу для Android, он работает, и sdCard.canWrite () возвращает true. Но в проекте тестирования Android Junit это не работает. Кто-нибудь знает почему ??

Проблема решена: Спасибо всем, кто ответил. Это потому, что я не добавил оригинальную программу для Android. Я также отметил, что мне не нужно добавлять какие-либо разрешения в тестовый проект Junit. Очень интересно, что действие записи произошло в тестовом проекте, но в исходном проекте требуется разрешение. Мне интересно, что, если я тестирую черный ящик с файлом .apk. Я не могу изменить разрешение из байтового кода, верно?


person Wei Yang    schedule 12.07.2012    source источник
comment
Причина в том, что SD-карта находится в состоянии только для чтения. Посмотри на это еще раз. Почему «D / can write» показывает false, а сразу после этого «D / ExternalStorageState» говорит «смонтировано»?   -  person t0mm13b    schedule 12.07.2012
comment
Вы монтируете хранилище, когда приложение работает в эмуляторе?   -  person t0mm13b    schedule 12.07.2012
comment
OP: Можете ли вы повторно отредактировать свой вопрос, чтобы явно указать, является ли этот манифест частью проекта тестирования или основного проекта? ... см. Комментарий @ Devunwired под ответом DtMilano .. :)   -  person t0mm13b    schedule 13.07.2012
comment
@ t0mm13b спасибо, что напомнили мне. Перередактирую вопрос.   -  person Wei Yang    schedule 13.07.2012


Ответы (3)


Разрешение на использование

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

должен быть добавлен в манифест вашего основного проекта. Помните, что тесты выполняются в том же процессе, что и основное приложение.

person Diego Torres Milano    schedule 12.07.2012
comment
@ t0mm13b Мы не можем этого предположить. Приведенный выше манифест предназначен для проекта TEST, это разрешение должно находиться в проекте MAIN. - person devunwired; 13.07.2012
comment
ОП должен был пояснить, что манифест является частью тестового проекта, а не основного проекта - хороший улов! Спросите OP в комментарии выше? :) - person t0mm13b; 13.07.2012
comment
Смотрите инструмент и теги uses-library, скорее всего, это мейнфест тестов. - person Diego Torres Milano; 13.07.2012
comment
Спасибо! @dtmilano Мне также интересно, тестирую ли я apk-файл, что мне делать? - person Wei Yang; 13.07.2012
comment
Тестируемое приложение и тестируемое приложение должны быть подписаны одним и тем же сертификатом, поэтому вы не можете протестировать сторонний APK с помощью этого метода. С другой стороны, тесты смогут записывать в свой каталог данных независимо от AUT. - person Diego Torres Milano; 13.07.2012

Измените эту строку:

File sdCard = Environment.getExternalStorageDirectory();

к этому:

File sdCard = new File(Environment.getExternalStorageDirectory().getPath());
person t0mm13b    schedule 12.07.2012
comment
Спасибо! но sdCard.canWrite () по-прежнему возвращает false. Исключение filenotfound все еще существует после того, как я помещаю пустой файл в / sdcard / - person Wei Yang; 13.07.2012
comment
Кажется, единственная разница между этими двумя операторами - сменить каталог с / mnt / sdcard / на / sdcard / - person Wei Yang; 13.07.2012
comment
Какую версию эмулятора Android вы используете? Похоже, sdcard на эмуляторе только для чтения? Вы можете это проверить? - person t0mm13b; 13.07.2012
comment
Я проверяю это, я могу отправить файл в каталог sdcard эмулятора, так что я думаю, что это не проблема эмулятора. Однако я обнаружил, что код успешно выполняется в обычном проекте Android. Находясь в тестовом проекте Android Junit, он все равно выбрасывает это исключение. Вы хоть понимаете, в чем разница между ними? Спасибо! - person Wei Yang; 13.07.2012

Я столкнулся с той же проблемой. Чтобы исправить это, мне нужно было не только добавить тег разрешения в основной манифест, но и добавить этот тег в манифест модуля, содержащего unittest.

Тег разрешения:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
person Rob    schedule 28.03.2015