Nexus 4 не показывает файлы через MTP

Я пытаюсь просто записать простой XML-файл на SD-карту, и я заметил, что мой Nexus 4 записывает файл, но его нельзя просмотреть по протоколу MTP в Windows 7.

код:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    CustomerQueryRqType customerQueryRequest = new CustomerQueryRqType();
    Serializer serializer = new Persister();
    File myFile = new File(Environment.getExternalStorageDirectory() + "/customerQueryRequest.xml");

    try {
        boolean created = myFile.createNewFile();
        serializer.write(customerQueryRequest, myFile);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

Я могу увидеть файл на самом телефоне с помощью Astro File Manager:

Скриншот

но Windows этого не видит ...:

Скриншот

adb shell в каталоге показывает:

ls -l
drwxrwxr-x root     sdcard_rw          1970-01-16 20:51 Alarms
drwxrwxr-x root     sdcard_rw          1970-01-16 20:51 Android
drwxrwxr-x root     sdcard_rw          2012-11-21 19:30 DCIM
drwxrwxr-x root     sdcard_rw          1970-01-16 20:51 Download
drwxrwxr-x root     sdcard_rw          1970-01-16 20:51 Movies
drwxrwxr-x root     sdcard_rw          1970-01-16 20:51 Music
drwxrwxr-x root     sdcard_rw          1970-01-16 20:51 Notifications
drwxrwxr-x root     sdcard_rw          2012-11-19 12:06 Pictures
drwxrwxr-x root     sdcard_rw          1970-01-16 20:51 Podcasts
drwxrwxr-x root     sdcard_rw          2012-11-19 13:22 Ringtones
drwxrwxr-x root     sdcard_rw          2012-11-19 14:33 bluetooth
-rw-rw-r-- root     sdcard_rw       79 2012-12-05 22:26 customerQueryRequest.xml
drwxrwxr-x root     sdcard_rw          2012-11-20 02:50 data
-rw-rw-r-- root     sdcard_rw    11394 2012-11-19 13:54 eightpen_custom_gestures
drwxrwxr-x root     sdcard_rw          2012-11-19 13:17 media

Что происходит с моим Nexus 4? Почему он скрывает мои вещи от Windows?


person moonlightcheese    schedule 06.12.2012    source источник
comment
Я думал, что делаю что-то не так. Теперь я знаю, что я не один.   -  person neverMind9    schedule 03.06.2019


Ответы (12)


Вы можете использовать следующий код после закрытия файла

MediaScannerConnection.scanFile(this, new String[] { file.getAbsolutePath() }, null, null);

Источник: https://code.google.com/p/android/issues/detail?id=38282

person Sathesh    schedule 06.12.2013
comment
Идеально. Это должно быть решением этого вопроса. - person Sorcerer; 03.02.2014
comment
Это решение не работает для меня на Nexus 7, Android 4.4.2, подключенном к Mac. Я создаю новую папку во внешнем хранилище и храню файлы в этой папке. Если я запустил это только для файлов в папке, Mac ничего не покажет. Если я также запустил его в своем новом каталоге, Mac покажет, что мой каталог является файлом 4k (а не каталогом). Я также пробовал позвонить context.sendBroadcast(), но безрезультатно. - person Joe Lapp; 18.12.2015
comment
Я просто поигрался со сканированием мультимедиа и трансляцией файлов, созданных в стандартном каталоге загрузок, и они никогда не появлялись при подключении к Mac. - person Joe Lapp; 18.12.2015
comment
Ах. Это невозможно сделать из onDestroy (). Это сработает, если я сделаю это в другом месте. Я могу сделать это во время создания файла, но тогда в файловом браузере на рабочем столе отображается нулевой размер. Даже в этом случае, когда я копирую файл, он копирует весь файл. - person Joe Lapp; 18.12.2015
comment
Работает с 8.1. Удаленные файлы исчезают только после перезагрузки. При этом, по крайней мере, записанные файлы немедленно появляются в обозревателе файлов подключенной системы. - person Midson; 25.03.2019

Потратив часы на эту проблему, я решил вот так:

private void rescanFolder(String dest) {
    // Scan files only (not folders);
    File[] files = new File(dest).listFiles(new FileFilter() {
        @Override
        public boolean accept(File pathname) {
            return pathname.isFile();
        }
    });

    String[] paths = new String[files.length];
    for (int co=0; co< files.length; co++)
        paths[co] = files[co].getAbsolutePath();

    MediaScannerConnection.scanFile(activity, paths, null, null);

    // and now recursively scan subfolders
    files = new File(dest).listFiles(new FileFilter() {
        @Override
        public boolean accept(File pathname) {
            return pathname.isDirectory();
        }
    });

    for (int co=0; co<files.length; co++)
        rescanFolder(files[co].getAbsolutePath());
} 

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

РЕДАКТИРОВАТЬ Кроме того, если вы не хотите, чтобы изображения добавлялись в ваш фотоальбом (а только ваше содержимое отображалось по протоколу mtp), не забудьте поместить пустой .nomedia файл в свою папку перед его повторным сканированием. , нравится:

new File(myFolder + File.separator + ".nomedia").createNewFile();
rescanFolder(myFolder);
person lviggiani    schedule 05.12.2014
comment
Очень полезный ответ, я смог использовать его рекурсивно, и теперь я вижу все вновь созданные файлы через MTP. Да и вообще как быть с отвязкой сервиса? Я получаю сообщение об ошибке ServiceConnectionLeaked: активность просочилась по ServiceConnection android.media.MediaScannerConnection@42164d98, который изначально был привязан сюда. Любая идея о том, как решить эту проблему, поскольку при использовании MediaScannerConnection.scanFolder () статически нет возможности отключить () привязанную службу ... - person Andre; 27.07.2015

Лучшее решение, которое я нашел для ошибки, упомянутой в принятом ответе, - это копирование данных из ОС Android на другой компьютер / сервер. (Linux, MacOS, windows) с использованием SSH.

  • Убедитесь, что устройство (Android) и машина (на которую вы хотите скопировать данные) доступны по IP или имени хоста, например, подключив их к одной сети Wi-Fi.

Необязательно и рекомендуется

  • Подключите устройство Android с помощью USB-модема. Это обеспечивает высокую скорость благодаря проводному соединению и гарантирует, что оба IP-адреса видны друг другу, поскольку оба находятся в одной сети.

На устройстве Android

  • Установите SSH-сервер. SSHelper работал как шарм
  • Запустите SSHelper и перейдите на вкладку конфигурации, чтобы получить IP-адрес, порт и пароль. В приведенном ниже примере это 192.168.1.5, 2222 и admin.
  • Пароль по умолчанию - admin, но если вы решите его изменить, нажмите кнопку «Перезагрузить сервер с новыми значениями» после его изменения.

В машине

  • Установите rsync. Если вы используете Ubuntu, он уже установлен по умолчанию.
  • Откройте оболочку и введите следующую команду. Измените IP-адрес и порт на свои значения

rsync -avzhP --inplace --info=progress2 -e 'ssh -p 2222' 192.168.1.5:/storage/emulated/0/DCIM/Camera/ /home/username/path/to/pics/

  • вы получите следующее приглашение, введите свой пароль

SSHelper Version 8.5 Copyright 2014, P. Lutus Default password is "admin" (recommend: change it) [email protected]'s password: admin receiving incremental file list

Другие предложения мне не подошли:

  • Устройство не поддерживает использование режима USB-накопителя вместо MTP (как и многие другие новые устройства).
  • В моей ОС (Android 6.0.1) не было возможности очистить данные приложения «Хранилище мультимедиа».
  • Другие методы обмена файлами по сети имели свои недостатки. FTP не гарантирует целостность файлов. Если соединение разрывается, оно либо перезаписывает, либо пропускает все файлы, поэтому один из файлов может быть неполным. Другие протоколы может быть сложно установить, а другие приложения могут использовать проприетарные протоколы.
person Organic Advocate    schedule 25.12.2016

На Xperia Z приведенный ниже код работал нормально:

  String screenShotFile = "....";
  activity.sendBroadcast(new Intent(
        Intent.ACTION_MEDIA_MOUNTED, Uri
                .fromFile(screenShotFile)));

для 4.4+ используйте:

activity.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
                                Uri.fromFile(screenShotFile)));

(к сожалению, я не помню, достаточно ли хорошо я это тестировал)

http://commonsware.com/blog/2013/11/06/android-4p4-permission-regressions.html

person marcinj    schedule 29.07.2013

уведомление / хранение / эмуляция. Android 4.2 имеет некоторые забавные эмуляции для каждого приложения / пользователя, например, отдельную / sdcard / для каждого пользователя. Попробуйте переместить файл в / sdcard / вместо показанной эмулированной SD-карты.

person Adam Weld    schedule 07.12.2012
comment
в любом случае все является ссылкой на /storage/emulated/legacy, которая сама по себе является ссылкой на /mnt/shell/emulated/0, который содержит файл. - person moonlightcheese; 07.12.2012

Простой код, предложенный для ответа на вопрос Как я могу обновить MediaStore на Android?, выполняет необходимое обновление MediaStore, если оно вызвано после того, как я поставил файл на внешнем хранилище. Контент на моем Nexus 4 мгновенно обновляется в проводнике Windows 7.

person stephan    schedule 03.07.2013
comment
Только что испытал, что со временем он может перестать обновляться. - person stephan; 03.07.2013

Мне нужно было создать каталог и скопировать несколько файлов примеров для моего приложения. После множества экспериментов и исследований у меня безупречно сработала следующая процедура:

1) Создал каталог с помощью File.mkdir ().

2) Скопируйте файлы в каталог и запустите MediaScanner для каждого файла.

MediaScannerConnection.scanFile(context, new String[]{file.getAbsolutePath()}, null, null);

3) Запустите MediaScanner в каталоге.

MediaScannerConnection.scanFile(context, new String[]{directory.getAbsolutePath()}, null, null);

Результат: файлы и каталог мгновенно появляются на ПК через MTP.

person Chebyr    schedule 19.07.2015
comment
Сканирование как каталога , так и созданного конкретного файла сработало для меня. Вы также можете объединить два вызова, подготовив массив String [] из двух элементов, в котором перечислены и файл, и родительский элемент. См. Также stackoverflow.com/a/25086535/911550 - person parvus; 19.10.2016

Была аналогичная проблема с моим OneplusOne:

После обновления программного обеспечения (до 6.0.1) я не мог видеть изображения с моей камеры при подключении к компьютеру (PTP и MTP). SDRescan и SDscanner обоих приложений не повлияли.

Мое решение состояло в том, чтобы скопировать все изображения из DCIM в другую папку с помощью терминала или любого приложения File Explorer на телефоне. При подключении к компьютеру я смог увидеть скопированные файлы .. Я переместил их на свой компьютер и очистил папку камеры. Нет постоянного решения, но оно устранило проблему для меня, по крайней мере, до тех пор, пока я не сделаю следующую резервную копию. = D

person Michael Saiz    schedule 16.08.2016

Приведенные выше ответы подходят для создания файла. Если вы позже удалите файл и хотите, чтобы это изменение также отразилось, вы можете выполнить одно из следующих действий; сначала рассмотрим два решения, которые кажутся работоспособными, но вызывают проблемы на некоторых устройствах. Первый - просканировать удаленный файл:

context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file)));

Это работает на многих устройствах для удаленных файлов, но на некоторых устройствах фактически вызывает создание нового 0-байтового файла, что, вероятно, не то, что вам нужно. В этом случае, если вы работаете на ‹4.4 KitKat, вы можете сделать это:

context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.fromFile(folder)));

Где папка равна file.getParentFile (). К сожалению, в KitKat 4.4 и выше это вызовет исключение SecurityException, поэтому для этих устройств вы можете попробовать удалить прямо из хранилища мультимедиа:

final Uri externalFilesUri = Files.getContentUri("external");
context.getContentResolver().delete(externalFilesUri, Files.FileColumns.DATA + "=?", new String[] {file.getAbsolutePath()});

Я тестировал это как обходной путь для ACTION_MEDIA_MOUNTED, не работающего на KitKat, и он работает в моем тестировании на Nexus 5.

person Learn OpenGL ES    schedule 20.02.2014

Недавно я столкнулся с той же проблемой, но некоторые дополнительные исследования помогли найти скрытые файлы. Похоже, Google внес некоторые изменения в структуру хранилища. Все эти файлы были перемещены в другую папку This Computer\HTC One\Internal Storage\storage\emulated\0. Но странно, что не все файлы были перемещены.

Android 4.4.2

person Aray Karjauv    schedule 30.05.2014

Из документации, здесь, вам нужно вызвать MediaScannerConnection .scanFile:

// Tell the media scanner about the new file so that it is
// immediately available to the user.
MediaScannerConnection.scanFile(this,
        new String[] { file.toString() }, null,
        new MediaScannerConnection.OnScanCompletedListener() {
    public void onScanCompleted(String path, Uri uri) {
        Log.i("ExternalStorage", "Scanned " + path + ":");
        Log.i("ExternalStorage", "-> uri=" + uri);
    }
});
person Luca    schedule 29.12.2017

person    schedule
comment
Устанавливаем SDrescan, запускаем: исправлено! Большое спасибо - person PiTheNumber; 06.07.2013
comment
Раньше этого не происходило, но случилось сегодня. Кстати, при перезагрузке должен работать IDK, почему он не работает. - person Muhammad Babar; 02.02.2015
comment
Странно, что после трехкратной перезагрузки телефон все-таки появился. - person Muhammad Babar; 02.02.2015
comment
Это не работает для Android 5.0.2: после очистки хранилища мультимедиа и использования SD Rescanner папки отображаются в Windows 7 как закрытые файлы 4K. Единственное решение на этом этапе - еще раз очистить хранилище мультимедиа и перезапустить устройство. - person Antonio; 02.11.2015
comment
Это также не работало на Nexus 7 Android 4.4.2. Мой Mac сообщает, что мой пользовательский каталог представляет собой файл размером 4k. - person Joe Lapp; 18.12.2015
comment
Но это работает, когда я помещаю свои файлы в стандартный каталог. - person Joe Lapp; 18.12.2015