Форум программистов, компьютерный форум, киберфорум
Наши страницы

Программирование Android

Войти
Регистрация
Восстановить пароль
 
Bolbine84455
4 / 4 / 2
Регистрация: 12.03.2014
Сообщений: 330
#1

Получить доступ к внешней карте памяти (Android 6) - Программирование Android

05.12.2016, 19:35. Просмотров 2097. Ответов 9
Метки нет (Все метки)

В предыдущей теме мне помогли разобраться с доступом к внутренней памяти.
Попытался получить внешнюю память с использованием готово класса с хабра.
К сожалению, за время использование всех 3 доступных методов мне удалось найти только одну память и то она является внутренней. Есть ли способ получить доступ к внешней карте (removable) с возможностью записи?
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
05.12.2016, 19:35
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Получить доступ к внешней карте памяти (Android 6) (Программирование Android):

Не получается получить путь к карте памяти - Программирование Android
Всем привет. У меня вот такой вопрос: storage/sdcard0 это путь к памяти телефона storage/sdcard1 это собственно карта памяти. ...

Получить путь к карте памяти (SD card) - Программирование Android
Не педелитесь методом, который возвращает путь к карте памяти, если она есть? Нащел вот такой метод в интернете, но на некоторых...

Не могу получить доступ к sdcard на android 6 и 7 - Программирование Android
В манивесте прописаны <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission...

Подключение к внешней БД из приложения на Android - Программирование Android
Хочу написать приложение для работы с внешней бд. Плевать на безопасность соединения и прочее. Нужен максимально простой способ хранения...

Путь к карте памяти - Программирование Android
Добрый день! У меня лежит файл в памяти телефона. В приложении прописываю путь к файлу вот таким образом: File sdcard =...

База данных на карте памяти - Программирование Android
У меня приложение создаёт базу данных, но она создаётся в памяти телефона. Скажите как сделать чтобы она сохранялась на карте памяти?

9
CoolMind
419 / 402 / 65
Регистрация: 06.10.2012
Сообщений: 1,727
06.12.2016, 20:39 #2
Bolbine84455, где-то слышал звон, что в Андроиде 6 решили объединить в одно хранилище внутреннюю и внешнюю память, могу ошибаться.
0
_Night_Scream_
76 / 75 / 8
Регистрация: 08.08.2013
Сообщений: 612
06.12.2016, 21:35 #3
CoolMind, у меня asus zenfone android 6.0.1 память раздельна, но карта памяти получила очень специфический путь (1E3D-1AF0), из-за этого популярный код на просторах интернета получения пути к файлу из uri отдаёт null.

Самое моё большое разочарование это чтобы приложения работало корректно на всех устройствах с файлами (чтение\запись) на внутреннем и внешнем накопителе.
1
Rube
911 / 559 / 88
Регистрация: 13.02.2014
Сообщений: 2,071
07.12.2016, 15:06 #4
Тоже интересует вопрос. Например приложение АнтеннаПод в настройках нормально определяет папку для сохранения файлов в виде storage/xxxx-xxxx/. Надо бы тоже в своем приложении исправить, а то со времен 4.х еще не исправил.

Добавлено через 23 минуты
Вот что нашел, проверяйте
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public static HashSet<String> getExternalMounts() {
    final HashSet<String> out = new HashSet<String>();
    String reg = "(?i).*vold.*(vfat|ntfs|exfat|fat32|ext3|ext4).*rw.*";
    String s = "";
    try {
        final Process process = new ProcessBuilder().command("mount")
                .redirectErrorStream(true).start();
        process.waitFor();
        final InputStream is = process.getInputStream();
        final byte[] buffer = new byte[1024];
        while (is.read(buffer) != -1) {
            s = s + new String(buffer);
        }
        is.close();
    } catch (final Exception e) {
        e.printStackTrace();
    }
 
    // parse output
    final String[] lines = s.split("\n");
    for (String line : lines) {
        if (!line.toLowerCase(Locale.US).contains("asec")) {
            if (line.matches(reg)) {
                String[] parts = line.split(" ");
                for (String part : parts) {
                    if (part.startsWith("/"))
                        if (!part.toLowerCase(Locale.US).contains("vold"))
                            out.add(part);
                }
            }
        }
    }
    return out;
}
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
private static final Pattern DIR_SEPORATOR = Pattern.compile("/");
 
/**
 * Raturns all available SD-Cards in the system (include emulated)
 *
 * Warning: Hack! Based on Android source code of version 4.3 (API 18)
 * Because there is no standart way to get it.
 * TODO: Test on future Android versions 4.4+
 *
 * @return paths to all available SD-Cards in the system (include emulated)
 */
public static String[] getStorageDirectories()
{
    // Final set of paths
    final Set<String> rv = new HashSet<String>();
    // Primary physical SD-CARD (not emulated)
    final String rawExternalStorage = System.getenv("EXTERNAL_STORAGE");
    // All Secondary SD-CARDs (all exclude primary) separated by ":"
    final String rawSecondaryStoragesStr = System.getenv("SECONDARY_STORAGE");
    // Primary emulated SD-CARD
    final String rawEmulatedStorageTarget = System.getenv("EMULATED_STORAGE_TARGET");
    if(TextUtils.isEmpty(rawEmulatedStorageTarget))
    {
        // Device has physical external storage; use plain paths.
        if(TextUtils.isEmpty(rawExternalStorage))
        {
            // EXTERNAL_STORAGE undefined; falling back to default.
            rv.add("/storage/sdcard0");
        }
        else
        {
            rv.add(rawExternalStorage);
        }
    }
    else
    {
        // Device has emulated storage; external storage paths should have
        // userId burned into them.
        final String rawUserId;
        if(Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1)
        {
            rawUserId = "";
        }
        else
        {
            final String path = Environment.getExternalStorageDirectory().getAbsolutePath();
            final String[] folders = DIR_SEPORATOR.split(path);
            final String lastFolder = folders[folders.length - 1];
            boolean isDigit = false;
            try
            {
                Integer.valueOf(lastFolder);
                isDigit = true;
            }
            catch(NumberFormatException ignored)
            {
            }
            rawUserId = isDigit ? lastFolder : "";
        }
        // /storage/emulated/0[1,2,...]
        if(TextUtils.isEmpty(rawUserId))
        {
            rv.add(rawEmulatedStorageTarget);
        }
        else
        {
            rv.add(rawEmulatedStorageTarget + File.separator + rawUserId);
        }
    }
    // Add all secondary storages
    if(!TextUtils.isEmpty(rawSecondaryStoragesStr))
    {
        // All Secondary SD-CARDs splited into array
        final String[] rawSecondaryStorages = rawSecondaryStoragesStr.split(File.pathSeparator);
        Collections.addAll(rv, rawSecondaryStorages);
    }
    return rv.toArray(new String[rv.size()]);
}
1
Bolbine84455
4 / 4 / 2
Регистрация: 12.03.2014
Сообщений: 330
07.12.2016, 21:40  [ТС] #5
Цитата Сообщение от Rube Посмотреть сообщение
Вот что нашел, проверяйте
Спасибо. Первый способ вернул внешнюю, как я и хотел (по крайней мере путь похож на правду), только через New File не удается получить. exists = false.
Второй способ выдает путь на sdcard (внутреннюю) и при попытке получить через New File выдает exists = true.

Меня интересует, каким образом можно получить доступ на запись в директорию конкретно из 1 способа.

Вот, как пытаюсь получить:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
verifyStoragePermissions(this); //Запросил разрешение
HashSet<String> hs = getExternalMounts();
        File f = new File(hs.iterator().next()); // /mnt/media_rw/2E79-7310
        boolean b = f.exists(); // false
 
public static HashSet<String> getExternalMounts() {
        final HashSet<String> out = new HashSet<String>();
        String reg = "(?i).*vold.*(vfat|ntfs|exfat|fat32|ext3|ext4).*rw.*";
        String s = "";
        try {
            final Process process = new ProcessBuilder().command("mount")
                    .redirectErrorStream(true).start();
            process.waitFor();
            final InputStream is = process.getInputStream();
            final byte[] buffer = new byte[1024];
            while (is.read(buffer) != -1) {
                s = s + new String(buffer);
            }
            is.close();
        } catch (final Exception e) {
            e.printStackTrace();
        }
 
        // parse output
        final String[] lines = s.split("\n");
        for (String line : lines) {
            if (!line.toLowerCase(Locale.US).contains("asec")) {
                if (line.matches(reg)) {
                    String[] parts = line.split(" ");
                    for (String part : parts) {
                        if (part.startsWith("/"))
                            if (!part.toLowerCase(Locale.US).contains("vold"))
                                out.add(part);
                    }
                }
            }
        }
        return out;
    }
 
public static void verifyStoragePermissions(Activity activity) {
 
        int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
 
        if (permission != PackageManager.PERMISSION_GRANTED) {
 
            ActivityCompat.requestPermissions(
                    activity,
                    PERMISSIONS_STORAGE,
                    REQUEST_EXTERNAL_STORAGE
            );
        }
    }
0
Rube
911 / 559 / 88
Регистрация: 13.02.2014
Сообщений: 2,071
07.12.2016, 21:56 #6
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от Bolbine84455 Посмотреть сообщение
Спасибо. Первый способ вернул внешнюю, как я и хотел (по крайней мере путь похож на правду), только через New File не удается получить. exists = false.
Второй способ выдает путь на sdcard (внутреннюю) и при попытке получить через New File выдает exists = true.
Да, я тоже сейчас проверил.
Нашел вот еще, работает тоже, выдает пути к files на emulated и внешнюю карту.
Проверил, все норм - запись идет на sd-карту.
Java
1
2
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT)
   final File[] dirs = getExternalFilesDirs(null);
1
Bolbine84455
4 / 4 / 2
Регистрация: 12.03.2014
Сообщений: 330
08.12.2016, 20:26  [ТС] #7
Цитата Сообщение от Rube Посмотреть сообщение
Проверил, все норм - запись идет на sd-карту.
Не знаю, что случилось, но не получается записать, хотя вчера казалось, что мне это удалось или я просто поверил .

Пишу следующее:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
@Override
    protected void onCreate(Bundle savedInstanceState) {
//...
verifyStoragePermissions(this);
 
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT){
 
            final File[] dirs = this.getExternalFilesDirs(null);
 
            File p = dirs[1].getParentFile().getParentFile().getParentFile().getParentFile();
 
            File f = new File(p.toString() + "/" + "test");
            boolean b = f.mkdir();
 
 
            String h = "DEBUG STOP";
 
        }
}
 
 
private static final int REQUEST_EXTERNAL_STORAGE = 1;
    private static String[] PERMISSIONS_STORAGE = {
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE
    };
 
    public static void verifyStoragePermissions(Activity activity) {
 
        int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
 
        if (permission != PackageManager.PERMISSION_GRANTED) {
 
            ActivityCompat.requestPermissions(
                    activity,
                    PERMISSIONS_STORAGE,
                    REQUEST_EXTERNAL_STORAGE
            );
        }
    }
b = false; // наверно, что-то успел поломать.
0
Rube
911 / 559 / 88
Регистрация: 13.02.2014
Сообщений: 2,071
09.12.2016, 07:42 #8
Цитата Сообщение от Bolbine84455 Посмотреть сообщение
dirs[1].getParentFile().getParentFile().getParentFile().getParentFile()
Это на куда путь то? В корень чтоли? А в dirs[1] дает записать?
А в корень можно ли записывать файл вообще?
1
Bolbine84455
4 / 4 / 2
Регистрация: 12.03.2014
Сообщений: 330
10.12.2016, 08:48  [ТС] #9
Цитата Сообщение от Rube Посмотреть сообщение
Это на куда путь то? В корень чтоли? А в dirs[1] дает записать?
А в корень можно ли записывать файл вообще?
dirs[1] = "/storage/2E79-7310/Android/data/com.example.myapp/files"
Записывать можно, а в родительские - нет.
А я хотел именно в /storage/2E79-7310/ иметь возможность писать файлы

Добавлено через 6 минут
В общих чертах: хотел написать программу для работы с базой данных (CRUD-операции). Подобное я реализовал для Desktop (Windows) и сейчас пишу под Android. Я хочу, чтобы база хранилась на внешнем носителе. Позднее хотелось бы реализовать синхронизацию записей между базами(репликацию) через USB между ПК и смартфоном. Путь на sdcard не такой уж и плохой, но, если я не ошибаюсь, после удаления приложения сама база удалится, что не есть хорошо.

Добавлено через 14 часов 41 минуту
В Total Commander и Amaze File Manager есть возможность записи файлов в корень карты памяти, только для меня в первый раз запрашивается диалог, где надо выбрать корневой путь. Поищу, что это за диалог такой...
1
Bolbine84455
4 / 4 / 2
Регистрация: 12.03.2014
Сообщений: 330
11.12.2016, 23:05  [ТС] #10
Наткнулся на исходники AmazeFileManager на GitHub. Поковырялся и понял лишь, что это реализовано через SAF.
осталось только раскурить это дело.

Добавлено через 42 минуты
У меня получилось создать директорию в корне внешней памяти. Всем спасибо. Пример кода прикладываю ниже.

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Override
    protected void onCreate(Bundle savedInstanceState) {
        //...
        startActivityForResult(new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE), 42);
    }
 
@Override
    public void onActivityResult(int requestCode,int resultCode,Intent resultData)
    {
        if(resultCode!=RESULT_OK)
            return;
        Uri treeUri=resultData.getData();
        DocumentFile pickedDir= DocumentFile.fromTreeUri(this, treeUri);
        grantUriPermission(getPackageName(), treeUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        getContentResolver().takePersistableUriPermission(treeUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION );
        writeFile(pickedDir);
 
    }
 
    public void writeFile(DocumentFile pickedDir) {
        DocumentFile file = pickedDir.createDirectory("testDirectory");
        boolean b = file.exists();
        String h = "123";
    }
1
11.12.2016, 23:05
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.12.2016, 23:05
Привет! Вот еще темы с ответами:

Завершать активити с внешней кнопкой power в android - Программирование Android
Здравствуйте! Как можно завершать активити когда я его не выключаю(то есть не завершаю), а именно завершается активити когда я нажимаю на...

Очистка памяти на андроиде без внешней sd - Программирование Android
помогите очистить память на андройде леново s860. он не имеет возможности расширения памяти, с помощью флешки!!! только внутренняя память...

Поиск mp3 файлов на телефоне/ карте памяти - Программирование Android
вообщем проблема такая, пишу mp3 плеер под android , как мне выполнить поиск всех mp3 файлов на телефоне/sd карте и запихнуть их в...

Как приложение Android написать на С++ в Android NDK, чтоб получить *.apk? Нужен мануал - Программирование Android
Уже не в первый раз задаю вопрос. Молчание. В лучшем случае - &quot;RTFM&quot; и точка. Так вот, официального мануала, где есть ответ на...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru