I'm using ADB in order to copy files from my desktop to a folder on my emulator.
adb push pic.jpg '/storage/emulated/0/DCIM/camera/
This works fine, but I have many files I would like to copy, and I don't want to repeat this command for every file. How can I "push" the contents of a whole directory?
Edit: screenshot of my Android studio:
For uploading the whole directory, the easiest way is to use Device File Manager in Android Studio.
Open it from the bottom right toolbar and navigate to the directory in the device where you want to upload the data.
Right click and click on upload to upload files or directory.
Note: Works only in Android Studio 3.0 and above
To push everything in the current directory, you can try:
adb push * /storage/emulated/0/DCIM/camera/*
You could use tar to put all your files into a single archive:
tar -cvf all.tar .
Then push that archive to the device:
adb push all.tar /sdcard
Finally untar your tar file in the device:
adb shell tar -xvf /sdcard/all.tar -C /sdcard
I couldn't find a solution so I made one:
from ppadb.client import Client as AdbClient
import os
import glob
adb = AdbClient(host='127.0.0.1', port=5037)
devices = adb.devices() #List of all connected devices
def send_over_adb(device,hostpath,devpath="/storage/emulated/0/"): # Recursively send folder and files over adb
if os.path.isfile(hostpath):
devpath = os.path.join(devpath,hostpath).replace('\\','/') # optimization for windows
device.push(hostpath, devpath)
elif os.path.isdir(hostpath):
for i in glob.glob(hostpath+'\*'):
print(i)
send_over_adb(device,i,devpath)
device.shell('am broadcast -a android.intent.action.MEDIA_MOUNTED -d file:///mnt/sdcard')
device.shell('am force-stop com.android.gallery3d') #force create thumbnails
hostpath='\path\to\folder\or\file\'
send_over_adb(devices[0],hostpath,devpath)
This function recursively sends over the folders and files while maintaining folder structure and ignores empty directories.
Limitation: file name shouldn't contain forward or back slashes(idk if any os allows that though)
Dependency: pure-python-adb
Tested on: Python3.7.9 on Win 8.1
Related
I have a flutter project that i created and manage with vscode.
I now need to access some files on my android emulator.
Everything i read online references the File Explorer tool in android studios.
However, i am not using android studios and i dont have a android studio project.
The only way i see at the moment is to abandon using vscode and recreate my project using android studios then using the file explorer from there...
However, this seems silly and excessive... i am sure there is someway i can access the file on my emulator without having to trow vscode in the trash.
Any ideas?
You can't access emulator's file system from VS Code as of now. If you don't want to use Android Studio then an alternative way is to use ADB Shell.
Here are the commands that you can use to interact with the File System of your emulator.
adb pull - To copy a file or directory and its sub-directories from the Android device
adb push - copy local files/directories to Android device
adb shell ls- List Files and Directories
adb shell cd - change directory
adb shell rm - rm is a command-line utility for removing files, directories and symbolic links
adb shell mkdir - make directories
adb shell touch- the touch command is a standard command used in UNIX/Linux operating system which is used to create, change and modify timestamps of a file
adb shell pwd - printing the current working directory
adb shell cp - copy files and directories
adb shell mv - moves files or directories from one place to another
For a detailed example please visit ADB Shell.
When I run below command directly on prompt, it works fine by pulling all files from emulator sdcard:
adb -s emulator-5556 pull /sdcard/.
However when I create bash file (extract.sh) with above command and run it I get following error:
remote object 'C:/Program Files (x86)/Git/sdcard/' does not exist
As can be seen it somehow adds C:/Program Files (x86)/Git before it. These are the contents of bash file:
#!/bin/bash
adb -s emulator-5556 pull /sdcard/.
Does anyone have an idea of why it works when direcly typing on prompt and not via bash file ? Thanks
Is there any reason you're not specifying the destination directory? For example, the batch command I use when pulling pictures from my phone over USB is adb pull "/sdcard/DCIM/Camera" "E:\Phone Pics\HTC DNA" which specifies both the source directory on the phone and the destination directory on my computer. As a side note, like enedil I recommend using this in a batch file when working in Windows.
How to push a file from computer to an Android device having no SD Card in it. I tried:
C:\anand>adb push anand.jpg /data/local
3399 KB/s (111387 bytes in 0.032s)
C:\anand>adb push anand.jpg /data/opt
3199 KB/s (111387 bytes in 0.034s)
C:\anand>adb push anand.jpg /data/tmp
3884 KB/s (111387 bytes in 0.028s)
Above commands to move a file anand.jpg to a device but I didn't get this jpg file in the device.
I didn't get any success result on cmd prompt, I only got:
3399 KB/s (111387 bytes in 0.032s).
From Ubuntu/Mac Terminal, the below command should work.
./adb push '/home/hardik.trivedi/Downloads/one.jpg' '/data/local/'
For adb v33 and above if you are getting a permission denied error, try what I tried. The following command and it works fine.
The only caveat is you might need to use tmp directory on such an emulator.
adb shell //Entering into shell
su //Super user mode
chmod 777 /data/local/tmp/ //Grantint RWX access
exit
chmod 777 /data/local/tmp/ //Grantint RWX access
exit
And then try
./adb push '/home/hardik.trivedi/Downloads/one.jpg' '/data/local/tmp/'
I did it using the push command, which has syntax:
adb push filename.extension /sdcard/0/
Example of copying directory, and sub-directory content:
adb push C:\my-location\data\. /storage/emulated/0/Android/data
Note that push did just hang in latest platform-tools (33.0.1, at time of writing) for a certain amount of files, beside the adb.exe suddenly taking 5MB+ instead of 1.5MB, hence I just did replace the adb.exe with one I had from 28.0.0 version of platform-tools (I did not downgrade the entire platform-tools, because adb.exe is kind of stand-alone).
I don't say there is any conspiracy around data folder,
But my Samsung device puts limits on my USB file transfer, beside Android v11+ not allowing access to data folder anymore, hence I needed above command to work with 100% speed (without hanging one hour for little more files).
Follow these steps :
go to Android Sdk then 'platform-tools' path on your Terminal or Console
(on mac, default path is : /Users/USERNAME/Library/Android/sdk/platform-tools)
To check the SDCards(External and Internal) installed on your device fire these commands :
1) ./adb shell (hit return/enter)
2) cd -(hit return/enter)
now you will see the list of Directories and files from your android device
there you may find /sdcard as well as /storage
3) cd /storage (hit return/enter)
4) ls (hit return/enter)
you may see sdcard0 (generally sdcard0 is internal storage) and sdcard1 (if External SDCard is present)
5) exit (hit return/enter)
to come out of adb shell
6) ./adb push '/Users/SML/Documents/filename.zip'
/storage/sdcard0/path_to_store/ (hit return/enter)
to copy file
Sometimes you need the extension,
adb push file.zip /sdcard/file.zip
run below command firstly
adb root
adb remount
Then execute what you input previously
C:\anand>adb push anand.jpg /data/local
C:\anand>adb push anand.jpg /data/opt
C:\anand>adb push anand.jpg /data/tmp
After Trying all the answers this worked for me
Where I am Pushing a file on Desktop to Android Device (Redmi K20 pro) connected Over the air using adb.
This command pushes the file to the downloads folder on my phone
adb push ~/Desktop/notifications.drawio ./storage/emulated/0/Download
after running this if you get a permission denied error
try running these commands in order (which basically changes the directory permission)
adb shell
chmod 777 /data/local/tmp
exit
and then run try the adb push command
I have documented this here feel free to share your views and help improve it.
Try this to push in Internal storage.
adb push my-file.apk ./storage/emulated/0/
Works in One plus device, without SD card.
My solution (example with a random mp4 video file):
Set a file to device:
adb push /home/myuser/myVideoFile.mp4 /storage/emulated/legacy/
Get a file from device:
adb pull /storage/emulated/legacy/myVideoFile.mp4
For retrieve the path in the code:
String myFilePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/myVideoFile.mp4";
This is all. This solution doesn't give permission problems and it works fine.
Last point: I wanted to change the video metadata information. If you want to write into your device you should change the permission in the AndroidManifest.xml. Add this line:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
I've got a Nexus 4, that is without external storage. However Android thinks to have one because it mount a separated partition called "storage", mounted in "/storage/emulated/legacy", so try pushing there: adb push anand.jpg /storage/emulated/legacy
As there are different paths for different versions. Here is a generic solution:
Find the path...
Enter adb shell in command line.
Then ls and Enter.
Now you'll see the files and directories of Android device. Now with combination of ls and cd dirName find the path to the Internal or External storage.
In the root directory, the directories names will be like mnt, sdcard, emulator0, etc
Example: adb push file.txt mnt/sdcard/myDir/Projects/
This might be the best answer you'll may read.
Setup Android Studio
Then just go to view & Open Device Explorer.
Right-click on the folder & just upload a file.
In Mac: To push files via adb
adb push /Users/Downloadsâ©/amazon.sdktester.json '/mnt/sdcard/amazon.sdktester.json'
You are trying to write to system folders. With ADB you have root (admin) access so you see the system folders of which sdcard is one of them so to send a picture you could use
D:\Program Files\Android\sdk\platform-tools\adb push am files\android sdk\adb.exe push C:\Downloads\anand.jpg /sdcard/pictures/
NB: C:\Downloads\anand.jpg replace with path and name to picture..
Certain versions of android do not fire proper tasks for updating the state of file system.
You could trigger an explicit intent for updating the status of the file system.
(I just tested after being in the same OP's situation)
adb shell am broadcast -a android.intent.action.MEDIA_MOUNTED -d file:///
(You could pass a specific filepath instead of file:/// like file:///sdcard )
In my case, I had an already removed SDCard still registered in Android.
So I longpressed the entry for my old SDCard under:
Settings | Storage & USB
and selected "Forget".
Afterwards a normal
adb push myfile.zip /sdcard/
worked fine.
To push all the files at your directory to the Android device use:
PS D:\myFiles> adb push . '/data/local/tmp/'
Trying to copy file from device to desktop, here is a command:
adb pull sdcard/log.txt Users/admin/Desktop
But this command creates a folder Users/admin/Desktop inside platform-tools folder where adb is located. How to pull file to my desktop ?
Use a fully-qualified path to the desktop (e.g., /home/mmurphy/Desktop).
Example: adb pull sdcard/log.txt /home/mmurphy/Desktop
Judging by the desktop folder location you are using Windows. The command in Windows would be:
adb pull /sdcard/log.txt %USERPROFILE%\Desktop\
Be root, Define file on device and define new filename.
adb root
adb pull /data/data/.../databases/launcher.db launcher.db
On Windows, start up Command Prompt (cmd.exe) or PowerShell (powershell.exe). To do this quickly, open a Run Command window by pressing Windows Key + R. In the Run Command window, type "cmd.exe" to launch Command Prompt; However, to start PowerShell instead, then type "powershell". If you are connecting your Android device to your computer using a USB cable, then you will need to check whether your device is communicating with adb by entering the command below:
# adb devices -l
Next, pull (copy) the file from your Android device over to Windows. This can be accomplished by entering the following command:
# adb pull /sdcard/log.txt %HOME%\Desktop\log.txt
Optionally, you may enter this command instead:
# adb pull /sdcard/log.txt C:\Users\admin\Desktop\log.txt
List item
Use following command to pull data from ADB
adb pull data/user/0/project package name/files/.local/share/dbname C:\Users\vijayalaxmi.k
data/user/0/project package name/files/.local/share/dbname this path you will get when you debug application. i.e database path
project package name example => com.example
instead of C:\Users\vijayalaxmi.k user your own path where you want to save your file. for example, c:\documents
do adb pull \sdcard\log.txt C:Users\admin\Desktop
I think adb's push is file-based.
I want to be able to push entire folders.
Is there an easy way without scripting?
Thanks!
Edit:
I need to work with sub-folders.
Edit:
Seems that adb pull is recursive but push is not.
So I changed the title and description accordingly.
Try this (worked with subfolders):
adb push mySourceFolder/. myDestAndroidFolder
Empty folders do not copy to android device.
I'm gonna dig this even more to give a full solution to this (for linux only), because google redirect to this and I had this exact same problem.
With a simple adb push, the problem is that all the subdirectories must exist BEFORE doing the push, which can be very painful to achieve.
Note that an easy solution is to zip the folder, push the zip then unzip on the device. But let's say you don't have unzip on your device (highly unlikely, really).
You want to push a full tree with a lot of subdirectories to your device in an empty directory myDirectory. There are two steps :
First create all the subdirectories, in your source device:
cd <folder-containing-myDirectory>
find myDirectory/ -type d -exec adb shell mkdir <path-to-folder-containing-myDirectory-in-device>/{} \;
This command find all the subdirectories of myDirectory (including ., so if myDirectory already exists, you will have one error message you can safely ignore) and for each of them, create the matching directory on the device.
then push everything
adb push myDirectory/. <path-to-folder>/myDirectory
adb pull, pulls all the files in the specified directory:
$ adb pull /mnt/sdcard/
pull: building file list...
pull: /mnt/sdcard/t3.txt -> ./t3.txt
pull: /mnt/sdcard/t2.txt -> ./t2.txt
pull: /mnt/sdcard/t1.txt -> ./t1.txt
3 files pulled. 0 files skipped.
or
$ adb push . /mnt/sdcard/
push: ./t2.txt -> /mnt/sdcard/t2.txt
push: ./t3.txt -> /mnt/sdcard/t3.txt
push: ./t1.txt -> /mnt/sdcard/t1.txt
3 files pushed. 0 files skipped.
Ran into this as well and found this article useful, but may have found a more complete solution. Running the following from the folder containing the files/folders you want to push:
adb push . /myDestinationFolder
The key is the prefix '/' before the destination folder apparently. This works from my windows command prompt, but when I run it from git bash (on Windows) I get some errors due to the meaning of the '/' in a path within the bash shell. So this might not work from linux/bash, however it definitely copied all subfolders for me.
I realize this question is a little old and I'm about to mention scripting when the question excluded it, but I'm going to answer this anyway. Mostly, because I wish I had found this answer here, before having to work it out myself.
adb push WILL work recursively, if all of the subfolders are present already. They can be empty, it just seems that adb push can not make folders. I found this to be a useful distinction because one could run a series of commands like this:
$ adb shell mkdir /folder
$ adb shell mkdir /folder/sub1
$ adb shell mkdir /folder/sub2
$ adb push folder
So, yes, one could make a small wrapper script to do this automatically. However, I think the more important point is that it just requires the folders to be there. Which means that if this is something that you are going to update multiple times in the same folder. For instance, adding pictures to an existing subfolder structure would work great over and over again with the single adb push command.
To expand on autra's genius answer a bit, I made a quick script to automate this (for Linux/Mac only).
I created an empty file in my home directory called adb-push. Then I edited the file with a text editor (like gedit, nano, vim, etc.) and put the following contents into it:
#!/bin/bash
# Usage:
# adb-push <directory-on-computer-to-send> <directory-on-device-to-receive-it>
# Example:
# adb-push ~/backups/DCIM /sdcard
src="${1}";
trgt="$(basename ${1})";
dst="$(echo "${2}" | grep '/$')";
# If ${dst} ends with '/', remove the trailing '/'.
if [ -n "${dst}" ]; then
dst="${dst%/*}";
fi;
# If ${src} is a directory, make directories on device before pushing them.
if [ -d "${src}" ]; then
cd "${src}";
cd ..;
trgt="${trgt}/";
find "${trgt}" -type d -exec adb shell mkdir "${dst}/{}" \;
fi;
adb push "${src}" "${dst}/${trgt}";
Then I made it executable:
chmod +x ~/adb-push;
This is how I run it:
~/adb-push <directory-on-computer-to-send> <directory-on-device-to-receive-it>
For example, if I want to send "~/backups/DCIM" to my device's sdcard folder, I would do this:
~/adb-push ~/backups/DCIM /sdcard
(But keep in mind that the location of the sdcard is not "/sdcard" for every Android device. For instance, it might be "/mnt/sdcard" instead.)
How about: archive -> push -> extract
It has been a few years, the issues may or may not have changed, but it is still a PITA. What is working for me on linux is to create a temp folder, create a symlink to the folder(s) I want to copy, and then I adb push. It ignores the main dir, but copies the subdirs. Currently, I'm not needing to create any subdirs, they do get created and copied for me. That might be platform specific, I'm not sure. But the main dir I'm copying, it copies the files in it instead of the dir. So the temp dir gets ignored, and the symlinked folders then get copied. Example:
mkdir tmp
cd tmp
ln -s ../Foo .
ln -s ../Bar .
cd ..
adb push tmp /sdcard/
And it will push Foo/file1 to /sdcard/Foo/file1
With just adb push Foo/. /sdcard/ then I end up with /sdcard/file1 which doesn't make me happy.
export FOLDER="Books"
TMPIFS="$IFS"
IFS=$'\n'
for i in `find "$FOLDER"/ -type d | sed 's,//\+,/,g'`; do
adb shell mkdir -p /mnt/sdcard/"$i"
done && \
adb push "$FOLDER"/ /mnt/sdcard/"$FOLDER"
unset FOLDER
IFS="$TMPIFS"
I couldn't find a solution so I made one:
from ppadb.client import Client as AdbClient
adb = AdbClient(host='127.0.0.1', port=5037)
devices = adb.devices() #List of all connected devices
import os
import glob
def send_over_adb(device,hostpath,devpath="/storage/emulated/0/"): # Recursively send folder and files over adb
if os.path.isfile(hostpath):
devpath = os.path.join(devpath,hostpath).replace('\\','/') # optimization for windows
device.push(hostpath, devpath)
elif os.path.isdir(hostpath):
for i in glob.glob(hostpath+'\*'):
print(i)
send_over_adb(device,i,devpath)
device.shell('am broadcast -a android.intent.action.MEDIA_MOUNTED -d file:///mnt/sdcard')
device.shell('am force-stop com.android.gallery3d') #force create thumbnails
This function recursively sends over the folders and files while maintaining folder structure and ignores empty directories.
Limitation: file name shouldn't contain forward or back slashes(idk if any os allows that though)