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?

12 ответов

Решение

Кажется, это известная проблема, затрагивающая доступ к файлам USB через Android через MTP. Кэш MTP устаревает до перезагрузки телефона.

Обходной путь:

  • Очистить данные приложения Media Storage
  • Используйте приложение SDrescan или SD Scanner (также работает на Android 4.4/5, доступно на F-Droid) для принудительного обновления

Или просто не используйте USB вообще. Эта проблема не влияет на другие методы доступа к файлам. Например, попробуйте AirDroid для передачи файлов.


Примечание. Это не работает для Android 5.0.2: после очистки "Хранилища мультимедиа" и использования SD Rescanner папки в Windows 7 отображаются как недоступные файлы 4K. Единственное решение на этом этапе - еще раз очистить Media Storage и перезапустить устройство.

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

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

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

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

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());
} 

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

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

new File(myFolder + File.separator + ".nomedia").createNewFile();
rescanFolder(myFolder);

Лучший обходной путь, который я нашел для ошибки, упомянутой в принятом ответе, - это копирование данных из ОС 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) username@192.168.1.5's password: admin receiving incremental file list

Другие предложения не работают для меня:

  • Использование режима хранения USB вместо MTP не поддерживается устройством (как и многие другие более новые устройства).
  • В моей ОС (Android 6.0.1) не было возможности очистить данные приложения "Media Storage".
  • Другие методы обмена файлами по сети имели свои недостатки. FTP не обеспечивает целостность файлов. Если соединение разорвано, оно либо перезаписывает, либо пропускает все файлы, поэтому один из файлов может быть неполным. Другие протоколы могут быть сложны в установке, а другие приложения могут использовать собственные протоколы.

На 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

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

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

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

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.

Была похожая проблема с моим OneplusOne:

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

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

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

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, поэтому для этих устройств вы можете попробовать удалить их непосредственно из Media Store:

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

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

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

Android 4.4.2

Из документации, приведенной здесь, вам нужно вызвать 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);
    }
});
Другие вопросы по тегам