【问题标题】:Refresh Android mediastore using adb使用 adb 刷新 Android 媒体存储
【发布时间】:2013-07-29 15:53:49
【问题描述】:

我正在使用 adb 在安卓手机上同步音乐。本质上,我 rm 现有的音乐目录并推送替换音乐文件。

我希望能够使用 adb 强制重新扫描,以便 google 音乐播放器(和其他应用程序)与新歌曲和播放列表正常工作。

根据How can I refresh MediaStore on Android?,您可以通过广播适当的意图来强制重新扫描。

adb 提供“shell am broadcast”,这似乎允许我强制从 adb 重新扫描。

或者,我可以运行重新扫描应用程序或重新启动,但我想从 adb 触发重新扫描

我应该发出什么 adb 命令?音乐文件和播放列表都在 /sdcard/music 中。

【问题讨论】:

    标签: android adb android-mediascanner


    【解决方案1】:

    重新扫描应用程序使用媒体装载意图来启动媒体扫描器。您可以使用am broadcast 发送相同的意图。

    命令是:

    adb shell am broadcast -a android.intent.action.MEDIA_MOUNTED -d file:///sdcard
    

    【讨论】:

    • 我一直在用:adb shell am broadcast -a android.intent.action.MEDIA_MOUNTED -d file:///mnt/sdcard/Music
    • 我注意到在 Kitkat 上重新扫描不会立即发生,而是最终发生。我不记得旧 API 是否是这种情况。有没有办法强制重新扫描立即发生?
    • @foosion 这适用于我运行 Android 5.1.1、6.0 和 6.0.1 的 Nexus 6。
    • @foosion 在我运行 Android N 预览版的 Nexus 6 上不起作用。我遇到了安全异常。
    • @JaredBurrows 它需要在 Nougat 上获得 root 权限:adb shell su -c 'am broadcast -a android.intent.action.MEDIA_MOUNTED -d file:///sdcard'
    【解决方案2】:

    非系统应用不再允许 MEDIA_MOUNTED Intent(发布 KitKat);试试这个吧。

    但它不是递归的,并且必须在确切文件名上运行,所以它不是一个好的替代品。

    adb shell am broadcast \
        -a android.intent.action.MEDIA_SCANNER_SCAN_FILE \
        -d file:///mnt/sdcard/Music/<exact_file_name>
    

    如果你需要递归重新扫描,你可以使用这个命令(相应地修复路径):

    adb shell "find /mnt/sdcard/Music/ -exec am broadcast \
        -a android.intent.action.MEDIA_SCANNER_SCAN_FILE \
        -d file://{} \\;"
    

    或者像这样(如果上面的方法不适合你):

    adb shell "find /mnt/sdcard/Music/ | while read f; do \
        am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE \
        -d \"file://${f}\"; done"
    

    【讨论】:

    • 这是android.intent.action.MEDIA_SCANNER_SCAN_FILE,而不是android.intent.action.ACTION_MEDIA_SCANNER_SCAN_FILE。 ACTION_* 是 Android 变量的名称:developer.android.com/reference/android/content/…
    • 这些都不适合我。然而,这个 hack 做到了:adb shell ' for ANDROID_MEDIA in $(find /mnt/sdcard/Music/ -type f | sed '\''s/ /\*/g'\''); do am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE -d "${ANDROID_MEDIA}" done '
    【解决方案3】:

    在某些三星手机上,您可以像这样进行全面重新扫描:

    am broadcast -a com.samsung.intent.action.MTP_FILE_SCAN -n com.android.providers.media/.MediaScannerReceiver
    

    【讨论】:

      【解决方案4】:

      如果你已经root了你的手机,你可以使用我写的这个脚本,它的好处是可以跟踪哪些文件已经更新了:

      #!/system/bin/env busybox ash
      
      MUSIC_LIBRARY=/sdcard/MusicLibrary
      
      LAST_UPDATE="$(stat -c %Y "$MUSIC_LIBRARY/.last-update")"
      
      find "$MUSIC_LIBRARY" -type f ! -iname ".last-update" | (
        while read f; do
          if ! test "$LAST_UPDATE" -ge "$(stat -c %Y "$f")"; then
            am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE -d "file://$f"
            touch "$f"
          else
            echo "Not updated: \`$f'"
          fi
        done
      )
      
      touch "$MUSIC_LIBRARY/.last-update"
      

      【讨论】:

      • 发送广播之后的“touch”命令的目的是什么?
      • 另外,这似乎不适用于戳 Google 照片以查找已重新同步到设备的新图片...
      • @Michael,touch 在那里,所以在下次执行脚本时,! test ... 将返回非零值(“false”,在扭曲的 shell 脚本世界)。
      【解决方案5】:

      这是一个名为 adb-scan 的 Python 脚本。 它使用adb 要求Android 设备重新扫描给定的文件。

      示例用法:

      $ adb-scan Notifications/\*.mp3
      Broadcasting: Intent { act=android.intent.action.MEDIA_SCANNER_SCAN_FILE dat=file:///sdcard/Notifications/cough.mp3 flg=0x400000 }
      Broadcast completed: result=0
      Broadcasting: Intent { act=android.intent.action.MEDIA_SCANNER_SCAN_FILE dat=file:///sdcard/Notifications/harmonica3.mp3 flg=0x400000 }
      Broadcast completed: result=0
      Broadcasting: Intent { act=android.intent.action.MEDIA_SCANNER_SCAN_FILE dat=file:///sdcard/Notifications/shhh.mp3 flg=0x400000 }
      Broadcast completed: result=0
      $
      

      这是脚本:

      #!/usr/bin/python3
      #
      # Ask the Android media scanner to check the given files.
      #
      import sys
      import os
      import re
      
      sys.argv.pop(0)
      
      if not sys.argv:
         sys.exit('usage: adb-scan files...')
      
      intent = 'android.intent.action.MEDIA_SCANNER_SCAN_FILE'
      
      # Quote certain special characters such as spaces, backslashes and quotes.  In
      # particular, don't quote '*' because we want that to be expanded on the
      # Android device.
      def cleanup(arg):
         if not arg.startswith('/'):
            arg = '/sdcard/' + arg
         arg = re.sub("[ \\'\"]", lambda x: '\\' + x.group(0), arg)
         return arg
      
      script = '''
      for i in {args}; do
          [ -e "$i" ] || echo "warning: no such file: $i"
          am broadcast -a "{intent}" -d "file://$i"
      done
      '''.format(args=' '.join(map(cleanup, sys.argv)),
                 intent=intent)
      
      cmd = ['adb', 'shell', script]
      os.execvp(cmd[0], cmd)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多