Alter.Org.UA
 << Back Home UK uk   Donate Donate

Android Gallery don't see images uploaded via GVFS MTP

I had a problem with script for automated image upload from Nikon's SD card to Android phone. Files copied via GVFS MTP mountpoint are not indexed in Android Gallery. But if I do it manually via GUI - everithing is ok.

Google search propose installing Rescan tools (those don't to stable and may not work) or play with ADB debugger. Also not stable solution, BTW.

Ok, since I played with adb, I've enabled maximum log level and see indexing erorr message, unsupported type. Google also don't know much about it. Just some references to MTP libraries. And one really useful link to android-file-transfer, it is also packaged and available via apt install android-file-transfer. This tool uploads images correctly, they are indexed immediately, like with GUI. But it cannot operate concurrently with GVFS, you have to unmount Android device first.

09-29 14:44:41.838 19668 25267 D MtpServer: path: /storage/emulated/0/Download/DSCN1429.JPG parent: 17 storageID: 00010001
09-29 14:44:41.864 19668 25267 D skia    : --- Failed to create image decoder with message 'unimplemented'
vs
09-29 14:49:25.575 19668 25267 D MtpServer: path: /storage/emulated/0/Download/DSCN1429.JPG parent: 17 storageID: 00010001
09-29 14:49:25.688 19668 25267 W ExifInterface: Skip the tag entry since tag number is not defined: 34864
09-29 14:49:25.688 19668 25267 W ExifInterface: Skip the tag entry since tag number is not defined: 2
09-29 14:49:25.688 19668 25267 W ExifInterface: Stop reading file since a wrong offset may cause an infinite loop: 0
09-29 14:49:25.689 19668 25267 I chatty  : uid=10031(com.android.providers.media) MtpServer identical 2 lines
09-29 14:49:25.689 19668 25267 W ExifInterface: Stop reading file since a wrong offset may cause an infinite loop: 0

I've compared android-file-transfer and libmtpGVFS.... And really, all successful cases set proper type, like image/jpeg, which is taken from source file. But regular copy via /run/user/xxxx/gvfs/... comes with unknown. However, libmtp has correct type assignment in examples. It is based on filename/extension.

Finally, I've created upload script with android-file-transfer (see below), and I hope GVFT MTP will be fixed too.

Indexed upload

#!/bin.sh

#requires 'sudo apt install android-file-transfer'

#ANDROID_MNT=~/mnt/mi7
# Default Target dir on Android
ANDROID_DIR=${1:-Download}
CAMERA_DIR=${2:-DCIM/100NIKON}


# Android device name from gio mount -l
# or gvfs-mount -l
#MTP=mtp://Xiaomi_SDM660-MTP__SN%3AE39C9282_fb7f7b7/


############################################################
# actually symlink to /run/user/xxx/gvfs/Xiaomi_SDM660-MTP__SN%3Axxxxxxxx_zzzzzzzz/Internal Storage/
# ${XDG_RUNTIME_DIR}/gvfs/Xiaomi_SDM660-MTP__SN%3Axxxxxxxx_zzzzzzzz/Internal Storage/
# ls ${XDG_RUNTIME_DIR}/gvfs | grep `gio mount -l|grep mtp|awk '{print $6;}'|sed -e 's/mtp:\/\///' -e 's/\///'`
a=`which gio`
if [ "x$a" = "x" ] ; then
GIO_MOUNT="gvfs-mount"
else
GIO_MOUNT="gio mount"
fi

#MTP=`gio mount -l|grep mtp|awk '{print $6;}'`
echo ${GIO_MOUNT} -l|grep mtp|awk '{print $6;}'
MTP=`${GIO_MOUNT} -l|grep mtp|awk '{print $6;}'`
echo ${MTP}
if [ "x$MTP" = "x" ] ; then
echo "Android device not connected via MTP"
exit
fi
#A_DEV_MTP_TPL=`echo ${MTP}|sed -e 's/mtp:\/\///' -e 's/\///'`
#echo ${A_DEV_MTP_TPL}
#A_DEV_MTP_DIR=`ls ${XDG_RUNTIME_DIR}/gvfs/ |grep ${A_DEV_MTP_TPL}`
A_DEV_MTP_DIR=`ls ${XDG_RUNTIME_DIR}/gvfs/ |grep mtp:`
ANDROID_MNT="${XDG_RUNTIME_DIR}/gvfs/${A_DEV_MTP_DIR}/"

IStor=`ls -A ${ANDROID_MNT}`
ANDROID_MNT="${ANDROID_MNT}/${IStor}"

echo ${ANDROID_MNT}

# Camera's SD card mountpoint
#SD_MNT=/media/alter/FC30-3DA9
SD_MNT=`mount |grep /media|grep vfat|awk '{print $3;}'`
SD_DEV=`mount |grep /media|grep vfat|awk '{print $1;}'`
# Source dir on Camera's SD
SD=${SD_MNT}/${CAMERA_DIR}

#echo ${ANDROID_MNT}
#ls ${ANDROID_MNT}

FLIST=/var/tmp/android.files.txt
ANDROID=${ANDROID_MNT}/${ANDROID_DIR}
echo ${ANDROID}

if [ ! -d "${SD}" ] ; then
echo "SD card not mounted"
exit
fi

a=`which aft-mtp-cli`
if [ "x$a" = "x" ] ; then
echo "missing package, run"
echo " sudo apt install android-file-transfer"
exit
fi

if [ ! -d "${ANDROID}" ] ; then
echo "Mount Android"
#gio mount ${MTP}
${GIO_MOUNT} ${MTP}
do_mount=0
else
do_mount=1
fi

if [ ! -d "${ANDROID}" ] ; then
echo "Android device not mounted"
exit
fi

#ls "${ANDROID}"
ls "${ANDROID}" | awk '{print "/" $1;}' > ${FLIST}

echo "Unmount Android"
#gio mount -u ${MTP}
${GIO_MOUNT} -u ${MTP}
if [ -d "${ANDROID}" ] ; then
echo "Android device is busy, can't unmount"
exit
fi

echo "" > ${FLIST}.aft
#echo "cd /" >> ${FLIST}.aft
#echo "cd \"${IStor}\"" >> ${FLIST}.aft # we are already there with aft-mtp-cli
echo "cd \"${ANDROID_DIR}\"" >> ${FLIST}.aft

#echo "find ${SD} -ctime -60 -type f | grep -v -f ${FLIST} )"
for FN in `find ${SD} -ctime -60 -type f | grep -v -f ${FLIST} )`; do
#adb shell am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE -d "file:///mnt/sdcard/${ANDROID_DIR}/${FN}"
#cp -v -u "${FN}" ${ANDROID}
#adb shell am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE -d "file:///mnt/sdcard/${ANDROID_DIR}/${FN}"
echo "put \"${FN}\"" >> ${FLIST}.aft
done

cat ${FLIST}.aft
aft-mtp-cli -f ${FLIST}.aft > /dev/null

if [ "$do_mount" -eq 1 ] ; then
echo "Mount back"
#gio mount ${MTP}
${GIO_MOUNT} ${MTP}
fi

${GIO_MOUNT} -u ${SD_MNT}
#sudo umount -f ${SD_MNT}
#sudo fsck -y ${SD_DEV}
#sudo sync ${SD_DEV}

#CMD="for ANDROID_MEDIA in \$(find /mnt/sdcard/${ANDROID_DIR}/ -ctime -1 -type f | sed '\''s/ /\\*/g'\\''); do am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE -d "\${ANDROID_MEDIA}"; done"
#echo ${CMD}
##adb shell ' for ANDROID_MEDIA in $(find /mnt/sdcard/${ANDROID_DIR}/ -ctime -1 -type f | sed '\''s/ /\*/g'\''); do am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE -d "${ANDROID_MEDIA}"; done '
#echo "adb shell '${CMD}'" > ${FLIST}.sh
#cat ${FLIST}.sh
#. ${FLIST}.sh

sync_photos.sh

Technical, GVFS MTP

If image files are written to Android device via fuse mount point, they are not indexed correctly. They are not visible in gallery and other apps, however file managers can see them. Then can also be selected directly, but not with Gallery. Some tricks with manual indexing help. If image files are sent to Android phone via GUI, they immediately appear in Gallery and are visible for all apps.

The problem is caused by mtpfile->filetype = LIBMTP_FILETYPE_UNKNOWN in gvfs/daemon/gvfsbackendmtp.c, do_create() It prevents indexer from handling new files correctly.

Correct indexing happens when sending via GUI (Nautilus) which use do_push() with explicitly specified mtpfile->filetype derived from mime type of source file.

Other tools those upload files correctly and examples in libmtp set mtpfile->filetype according to filename/extension. It would be great to implement such mechanism in GVFS MTP, see patch below.

Patch: mtp_ftype.patch

2022.09.29


See also:


FB or mail alterX@alter.org.ua (remove X)   Share
designed by Alter aka Alexander A. Telyatnikov powered by Apache+PHP under FBSD © 2002-2024