Making adb-pushed media files show up in the Android gallery
You run adb push photo.jpg /sdcard/DCIM/, adb prints a happy transfer line, you open the gallery and the photo isn’t there. A file manager on the phone can see it. The gallery app can’t. This is one of the oldest adb annoyances, and it’s the same question behind this long-running Stack Overflow thread: how do I get the gallery to notice files I copied over adb?
The short answer is that adb copies bytes into a folder, and the gallery doesn’t read folders. It reads a database. Until something tells that database about your file, the gallery has no reason to know it exists. This tutorial explains that gap, shows the commands that close it, and covers the cases where the obvious command silently does nothing on newer Android versions.
It’s for anyone loading test media onto phones: QA people seeding a gallery before testing an upload flow, operators preparing a batch of devices, or anyone who just wants a pushed video to play in their gallery app. By the end you’ll have a push-then-rescan routine, and a small script that does it for a whole folder.
What you need
- a computer with adb installed (Android platform-tools from Google’s site, free)
- an Android phone with USB debugging on. if the toggle is greyed out, see fixing a greyed-out USB debugging toggle on Android
- a USB cable that carries data, not a charge-only one
- a few test files: one JPEG, one MP4 is enough
- a gallery app to check results (Google Photos, Samsung Gallery, or the AOSP Gallery all work)
- cost: nothing. everything here is free tooling
The phones must be ones you own or are authorised to test. Nothing here needs root.
Step by step
1. Confirm adb sees the device
Action: plug the phone in, accept the RSA fingerprint prompt on screen, then run:
adb devices
Expected output: a line with your serial and the word device.
List of devices attached
R58M12ABCDE device
If it breaks: unauthorized means you didn’t accept the prompt on the phone, so unplug, replug and watch the screen. An empty list usually means a bad cable or a missing USB driver on Windows.
2. Understand what actually happened (MediaStore versus the filesystem)
Android keeps an index of media called the MediaStore. Gallery apps query it through a content provider rather than walking directories. A background component, historically called MediaScanner, fills that index. It runs when the phone boots, when storage is mounted, when an app saves a file through the proper APIs, and when an app explicitly asks for a scan.
adb push does none of that. It writes a file straight to storage through the shell, so MediaStore never hears about it. Google’s documentation on shared media storage describes MediaStore as the thing apps are meant to go through, and that’s the root of the gap.
Expected output: nothing to run here, but you can prove the gap exists in the next step.
If it breaks: nothing to break, just keep this model in your head. Almost every later problem is “the file is on disk but not in the index” or “the index has a stale entry”.
3. Push a test file into a sensible folder
Action: pick a folder gallery apps actually look at. DCIM/Camera, Pictures and Movies are safe choices.
adb push test.jpg /sdcard/DCIM/Camera/test.jpg
Expected output: one line ending in something like 1 file pushed, 0 skipped. with a transfer rate.
If it breaks: Permission denied or couldn't create file means you aimed at a protected path. On Android 11 and later, shared storage rules (scoped storage) also stop the shell from writing into other apps’ folders under /sdcard/Android/data. Stay with the public folders above.
4. Check that the index doesn’t know the file
Action: query MediaStore directly from the shell.
adb shell content query --uri content://media/external/images/media \
--projection _id:_display_name:_data \
--where "_display_name='test.jpg'"
Expected output: No result found. right after a fresh push. That’s the gap, made visible.
If it breaks: on some OEM builds the content command needs the full --user 0 flag, so add --user 0. If you get a permission error on a very locked-down device, skip this step, it’s only a diagnostic.
5. Trigger a rescan of one file with am broadcast
Action: send the media scanner broadcast with a file URI.
adb shell am broadcast \
-a android.intent.action.MEDIA_SCANNER_SCAN_FILE \
-d file:///sdcard/DCIM/Camera/test.jpg
Expected output:
Broadcasting: Intent { act=android.intent.action.MEDIA_SCANNER_SCAN_FILE dat=file:///sdcard/DCIM/Camera/test.jpg }
Broadcast completed: result=0
Re-run the query from step 4. You should now get a row back with an _id. Open the gallery and the photo should appear, sometimes after a pull-to-refresh.
If it breaks: this is the command people paste from forum answers, and its behaviour depends on the Android version. Android’s own reference for MediaScannerConnection is the supported way for an app to request a scan, and the old broadcast action is the legacy route. As of October 2026 I’d treat the broadcast as “works on many devices, ignored on some”. If result=0 prints but the query still returns nothing, go to step 6.
A related trap: older answers tell you to broadcast android.intent.action.MEDIA_MOUNTED for the whole storage. From Android 4.4 onward, normal callers get a SecurityException for that one, so a failing mount broadcast is expected and not a sign your setup is broken. Scan files or folders instead.
6. Fall back to a volume scan with content call
Action: on newer Android versions, ask the media provider itself to rescan the primary external volume.
adb shell content call --uri content://media/ --method scan_volume --arg external_primary
Expected output: a Result: Bundle[{}] style line. It can take a few seconds to a minute on a phone with a lot of media, and the phone may run warm while it works.
Then re-run the step 4 query. On my own devices this has been the more reliable route on recent Android releases, but I haven’t tested every OEM skin, so check the result on yours instead of trusting my word. Behaviour of these hidden provider methods is not documented as a stable API, so treat this as a practical trick that could change in a future release.
If it breaks: a Permission Denial or Unknown method message means your Android version or OEM build doesn’t expose that call to the shell. Use step 7, or the reboot fallback in step 9.
7. Scan a whole folder with a small script
Action: pushing and scanning files one at a time gets old fast. This bash script pushes everything in a local folder and broadcasts a scan for each file.
#!/usr/bin/env bash
# usage: ./push_media.sh ./local_folder /sdcard/Pictures/test
SRC="$1"
DEST="$2"
adb shell mkdir -p "$DEST"
for f in "$SRC"/*; do
name=$(basename "$f")
adb push "$f" "$DEST/$name"
adb shell am broadcast \
-a android.intent.action.MEDIA_SCANNER_SCAN_FILE \
-d "file://$DEST/$name" > /dev/null
done
On Windows PowerShell, the equivalent loop is:
Get-ChildItem .\local_folder | ForEach-Object {
adb push $_.FullName "/sdcard/Pictures/test/$($_.Name)"
adb shell am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE -d "file:///sdcard/Pictures/test/$($_.Name)" | Out-Null
}
Expected output: one push line per file, then the gallery shows them all.
If it breaks: filenames with spaces need quoting on the device side too, so the simplest fix is renaming files to plain ascii without spaces before pushing. If you have several phones attached, add -s SERIAL to every adb call.
8. Check for a .nomedia file
Action: if files are indexed but still hidden in the gallery, look for a .nomedia marker in the folder.
adb shell ls -a /sdcard/Pictures/test
Expected output: a listing of your files. If .nomedia is in there, gallery apps skip the whole folder on purpose.
If it breaks: remove it with adb shell rm /sdcard/Pictures/test/.nomedia, then rescan with step 6. Some apps create these deliberately, so only delete one in a folder you made yourself.
9. Last resort: restart the gallery app, then reboot
Action: gallery apps cache their own thumbnails and sometimes show a stale view of a correct index.
adb shell am force-stop com.google.android.apps.photos
The package name varies by gallery app. Samsung’s is a different one, and you can list candidates with adb shell pm list packages | grep -i gallery.
Expected output: no output; the app starts fresh next time you open it.
If it breaks: a reboot (adb reboot) triggers a full media scan on boot on essentially every Android version. It’s slow and blunt, but it works when everything else fails. On a phone you rely on for something else, do this last.
Common pitfalls
- pushing to the wrong folder: files dropped in the root of
/sdcardor in a random directory may be indexed but never shown in the main gallery view, because many gallery apps only surface albums fromDCIM,Pictures,Moviesand similar. Put files where a camera or screenshot tool would. - assuming
result=0means success: the broadcast reports that it was delivered, not that anything got indexed. Always verify with thecontent querycheck from step 4 instead of trusting the broadcast line. - using MEDIA_MOUNTED on modern Android: it’s the answer half the old forum threads give, and it fails with a permission error. Scan files or call the volume scan instead.
- re-pushing the same name and expecting a thumbnail refresh: if you overwrite
test.jpgwith a different image, the gallery can keep showing the old thumbnail. Use a new filename, or rescan and force-stop the gallery app. - forgetting that the same trick is for your own devices: seeding media onto phones is fine for testing apps you own or are cleared to test. Don’t use it to dodge anything an app or platform is deliberately enforcing.
Scaling this
At 10 phones, the script from step 7 is enough. Add a loop over adb devices serials and use -s on every call. The main cost is time, since USB 2 hubs and big video files make the push the slow part, not the rescan.
At 100 phones, the bottleneck becomes the host. Pushes run in parallel per device, but USB controllers, hub power and cable quality start to bite, and you’ll hit odd offline devices during large transfers. I wrote about those limits in host limits when running many Android phones, and the same numbers apply to media seeding. Stagger the volume scans too, because a scan on a phone with thousands of files is CPU heavy and the phones get warm. Log the step 4 query result per serial so you know which phones actually indexed their files.
At 1000 phones, a pile of cabled devices on one machine stops being a sensible design. Work becomes fleet management: per-site hosts, a job queue, and a verification step that reports back rather than a human checking galleries. If what you need is real Android hardware that’s not physically in front of you, cloudf.one rents real Android phones in Singapore on dedicated hardware, each with a persistent Singapore mobile IP, controlled from the browser. I should be exact about adb there: there’s no self-service adb. adb and Appium reach a rented phone only through a WireGuard tunnel that we set up on request by email to [email protected]. Everything is Singapore-only, so if you need devices in other countries, it’s not the right fit.
Where to go next
- the blog index has the rest of the adb how-tos
- how to pull an APK file off an Android device with adb is the opposite direction, getting files off the phone
- fixing a greyed-out USB debugging toggle on Android if your phone won’t enable adb in the first place
If you want to understand what the shell commands above are doing underneath, Google’s adb reference covers push, shell and am in detail.
Written by Xavier Fok
disclosure: this article may contain affiliate links. if you buy through them we may earn a commission at no extra cost to you. verdicts are independent of payouts. last reviewed by Xavier Fok on 2026-10-09.