My Android ssh server app can’t write to the SD card!

My Android 8 phone has limited internal storage, so I keep my my 50GB+ music collection of mp3s, flacs, etc on my sd card. In general, Android doesn’t allow apps to write to external storage, except in their own private directory. Therefore, my ssh server app, SSHelper, can’t write to /storage/emuated/3333-ABCD/music or wherever.

What I’ve been doing in the past is removing the card, and rsyncing with it. I’m through with doing that – no more fiddling around with that card and removing it each time I want to sync my collection!

I want to copy music from my Linux desktop

I want to be able to copy music files from my Linux desktop to my SD card without removing it. I said above that my ssh server app can’t write to the SD card, but there is an exception: Android apps can write to their own private directories on the SD card!

There are least two private directories for each app. In the case of the case of SSHelper, they are:

  • /storage/emulated/3434-5656/Android/data/com.arachnoid.sshelper
  • /storage/emulated/3434-5656/Android/media/com.arachnoid.sshelper

Usually you can figure out the last part of this path, but if you can’t, you can try an app like Package Name or look at the Google Play store URL for the ssh server app.

These paths may not exist yet! But if you manually mount the SD card on your Linux system, you can create them underneath Android/data and Android/media with a simple mkdir:

$ cd /mnt/usb  # your mountpoint on your Linux system
$ mkdir -p Android/media/com.arachnoid.sshelper Android/data/com.arachnoid.sshelper

What is the difference between the above two paths? The data version has a dummy .nomedia file at Android/data/.nomedia, meaning files underneath there won’t get indexed by the Android Media Scanner! If you put mp3s in that structure, they won’t show up in your music player’s library.

Use the Android/media/ path

Put your files underneath the Android/media path. This structure doesn’t have a .nomedia file. Simply manually create the app-specific private directory like Android/media/com.arachnoid.sshelper, and you can then scp or rsync files to your hearts content!

Warning: Don’t remove your ssh server app!

If you remove your ssh server app, those private directories will be removed, along with all your mp3 files! So keep your ssh server app around.

Causing a Media Scan Trigger

Try a simple solution like ScanMediaPlease, which doesn’t require any special permisisons.

exFAT filename issues

Are you having problems with mp3s that have colons, question marks or other exFAT disallowed characters? It’s a shame that Android doesn’t support SD cards with a Linux native filesystem like ext4 or btrfs.

rsync with transliteration (--tr)

rsync has a really nice transliterate patch. It’s pretty easy to apply this patch if you use Gentoo; simply place it in /etc/portage/patches/net-misc/rsync/. You might have to update the patch’s diff contexts a bit since rsync has changed over time, but don’t worry, it’s not that hard.

Once you have an updated rsync, try this option sequence for removing exFAT-invalid characters:

--tr ':?"/-_'\'

sshfs

Unfortunately this patch doesn’t work over ssh because the rsync instance on your --tr option support for some reason. It doesn’t make sense to me why it should. I initially thought i might have to update the patch to not require this, but I found another solution: sshfs, which allows a ssh-accessible server’s filesystem to look like a local filesystem. This approach allows us to only use the rynsc on our local system.

(side note: In my opinion rsync should incorporate the transliterate patch into its baseline due to its general usefulness when dealing with FAT filesystems.)

Here’s the simplified code of sshfs that I use for syncing music with my SD card on my phone, using my preferred Android ssh server, SSHelper:

sshfs myphone:/ /mnt/sshfs

rsync --progress -v -r --size-only --copy-links \
    --tr ':?"/-_'\' 
    --delete \
	/path/to/my/music/ \
	/mnt/sshfs/storage/3434-5656/Android/media/com.arachnoid.sshelper/music \

echo "unmounting"
fusermount -u /mnt/sshfs