Nexus 4 не відображає файли через MTP


80

Я намагаюся просто написати простий 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?


1
Я думав, що роблю щось не так. Тепер я знаю, що я не одна.
neverMind9

Відповіді:


72

Здається, це відома проблема, яка впливає на доступ до файлів USB Android через MTP . Кеш MTP застаріває до перезавантаження телефону.

Обхідний шлях є:

  • Очистіть дані програми "Зберігання медіа"
  • Використовуйте SDrescan або SD Scanner (також працює на Android 4.4 / 5, доступний на F-Droid ), щоб примусити оновити

Або просто взагалі уникайте використання USB. Проблема не впливає на інші способи доступу до файлів. Наприклад, спробуйте AirDroid для передачі файлів.


Примітка: Це не працює для Android 5.0.2: Після очищення "Зберігання медіа" та використання SD Rescanner папки відображаються в Windows 7 як невідкриваються файли 4K. Єдиним рішенням у цей момент є ще раз очистити Зберігання носіїв та перезапустити пристрій


2
Встановіть SDrescan, запустіть його: виправлено! Велике спасибі
PiTheNumber

Раніше цього не було, але сьогодні. До речі, я перезавантажуюсь, повинен працювати IDK, чому він не працює.
Мухаммед Бабар

Це дивно після перезавантаження телефону протягом 3 разів він з'явився.
Мухаммед Бабар

Для Android 5.0.2 це не працює: після очищення «Зберігання медіа» та використання SD Rescanner папки з’являються в Windows 7 як невідкриваються файли 4K. Єдиним рішенням у цей момент є ще раз очистити Зберігання носіїв та перезапустити пристрій.
Антоніо

Це також не спрацювало на Nexus 7 Android 4.4.2. Мій Mac повідомляє, що мій власний каталог - це файл 4k.
Джо Лапп,

44

Ви можете використовувати наступний код після закриття файлу

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

Джерело: https://code.google.com/p/android/issues/detail?id=38282


11
Ідеально Це має бути вирішенням цього питання.
Чародій

Це рішення не працює для мене на Nexus 7, Android 4.4.2, що підключається до Mac. Я створюю нову папку у зовнішньому сховищі та зберігаю файли у цій папці. Якщо я запускаю це лише на файлах у папці, Mac нічого не показує. Якщо я також запускаю його у своєму новому каталозі, Mac показує, що мій каталог - це файл 4k (а не каталог). Я також намагався дзвонити context.sendBroadcast()безрезультатно.
Джо Лапп,

Я просто погрався із скануванням мультимедіа та трансляцією файлів, створених у стандартному каталозі «Завантаження», і вони ніколи не з’являлися при підключенні до Mac.
Джо Лапп,

Ага. Цього не можна зробити за допомогою onDestroy (). Це працює, якщо я роблю це деінде. Я можу це зробити під час створення файлу, але тоді браузер файлів на робочому столі показує розмір нульових укусів. Навіть при цьому, коли я копіюю файл, він копіює весь файл.
Джо Лапп,

Працює з 8.1. Видалені файли зникають лише після перезавантаження. При цьому щонайменше записані файли одразу з’являються у браузері файлів змонтованої системи.
Мідсон,

5

Потративши години на це питання, я вирішив так:

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

Дуже корисна відповідь, я зміг використовувати його рекурсивно, і тепер я бачу всі новостворені файли через MTP. У будь-якому випадку, як бути з відмовою від послуги? Я отримую помилку ServiceConnectionLeaked: "Діяльність просочила ServiceConnection android.media.MediaScannerConnection@42164d98, яка спочатку була пов'язана тут". Будь-яка ідея про те, як її вирішити, оскільки використання MediaScannerConnection.scanFolder () статично не має шансів відключити () пов’язану службу ...
Андре,

3

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


3

Найкраще обхідне рішення, яке я знайшов для помилки, згаданої у прийнятій відповіді, - це копіювання даних з ОС Android на іншу машину / сервер (Linux, MacOS, Windows) за допомогою SSH.

  • Переконайтеся, що пристрій (Android) та апарат (де ви хочете скопіювати дані) доступні за IP-адресою або іменем хосту, наприклад, підключивши їх до однієї мережі Wi-Fi.

Необов’язково і рекомендується

  • Підключіть пристрій Android за допомогою USB-модема. Це забезпечує швидку швидкість завдяки дротовому з'єднанню та гарантує, що обидві IP-адреси будуть видимі одна одній, оскільки обидві вони знаходяться в одній мережі.

На пристрої Android

  • Встановіть сервер SSH. SSHelper працював як
  • Запустіть SSHelper і перейдіть на вкладку конфігурації, щоб отримати IP-адресу, порт та пароль. У наведеному нижче прикладі це 192.168.1.5, 2222 та '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) не було можливості очистити дані програми "Зберігання медіа".
  • Інші методи обміну файлами по мережі мали свої негативні наслідки. FTP не забезпечує цілісність файлів. Якщо з'єднання розірвано, воно перезаписує або пропускає всі файли, тому один із файлів може бути неповним. Інші протоколи може бути важко встановити, а інші програми можуть використовувати власні протоколи.

2

повідомлення / зберігання / емульований. В Android 4.2 є кілька прикольних емульованих програм доступу для кожного додатка / користувача, наприклад, окрема / sdcard / для кожного користувача. Спробуйте перемістити файл у / sdcard / замість емульованої sdcard, що відображається.


11
все в /storage/emulated/legacyбудь-якому випадку є посиланням , яке саме є посиланням на /mnt/shell/emulated/0яке містить файл.
moonlightcheese

2

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


Просто пережив, що з часом це може припинити оновлення.
Стефан

1

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

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.


Сканування як каталогу, так і конкретного створеного файлу працювало у мене. Ви також можете поєднати два виклики, підготувавши масив String [] з двох елементів, де вказані як файл, так і батьки. Дивіться також stackoverflow.com/a/25086535/911550
parvus

1

У мене була подібна проблема з моїм OneplusOne:

Після оновлення програмного забезпечення (до 6.0.1) при підключенні до комп’ютера (PTP та MTP) я не міг бачити фотографії своєї камери. SDRescan і SDscanner додатка не мали ефекту.

Моїм рішенням було скопіювати всі зображення з DCIM в іншу папку за допомогою терміналу або будь-якої програми Explorer на телефоні. Під час підключення до комп'ютера я зміг побачити скопійовані файли .. я перемістив їх на свій комп'ютер і очистив папку камери. Немає постійного рішення, але це вирішило проблему для мене принаймні доки я не зроблю наступне резервне копіювання. = D


0

Наведені вище відповіді чудово підходять для створення файлу. Якщо пізніше ви видалите файл і хочете, щоб і ця зміна була відображена, ви можете зробити одне з наступного; давайте спочатку розглянемо два рішення, які, здається, працюють, але спричинять проблеми на деяких пристроях. Перший - сканувати видалений файл:

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.


0

Нещодавно я зіткнувся з тією ж проблемою, але деякі додаткові дослідження допомогли знайти приховані файли. Схоже, Google вніс деякі зміни в структуру сховища. Усі ці файли було переміщено в іншу папкуThis Computer\HTC One\Internal Storage\storage\emulated\0 . Але дивно, що не всі файли було переміщено.

Android 4.4.2


0

З документації тут потрібно викликати 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);
    }
});
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.