Refresh Android mediastore using adb

前端 未结 5 939
鱼传尺愫
鱼传尺愫 2020-12-04 08:42

I\'m using adb to sync music on an android phone. Essentially, I rm the existing music directory and push replacement music files.

I\'d like to be able to use adb to

相关标签:
5条回答
  • 2020-12-04 09:01

    On some Samsung mobiles, you can get a full rescan like this:

    am broadcast -a com.samsung.intent.action.MTP_FILE_SCAN -n com.android.providers.media/.MediaScannerReceiver
    
    0 讨论(0)
  • 2020-12-04 09:01

    Here's a Python script called adb-scan. It uses adb to ask the Android device to rescan the given files.

    Example usage:

    $ 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
    $
    

    Here's the script:

    #!/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)
    
    0 讨论(0)
  • 2020-12-04 09:05

    The MEDIA_MOUNTED intent is no longer permitted (post KitKat) for non-system apps; try this instead.

    It’s not recursive, though, and has to be run on the exact_file_name, so it’s not a good replacement.

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

    If you need to rescan recursively, you can use this command (fix paths accordingly):

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

    Or like this (if above won't work for you):

    adb shell "find /mnt/sdcard/Music/ | while read f; do \
        am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE \
        -d \"file://${f}\"; done"
    
    0 讨论(0)
  • 2020-12-04 09:13

    The rescan apps use a media mount intent to kick off the media scanner. You can use am broadcast to send the same intent.

    The command is:

    adb shell am broadcast -a android.intent.action.MEDIA_MOUNTED -d file:///sdcard
    
    0 讨论(0)
  • 2020-12-04 09:26

    If you have rooted your phone, you can use this script I’ve written, which has the advantage of keeping track of which files have already been updated:

    #!/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"
    
    0 讨论(0)
提交回复
热议问题