| Android Gallery don't see images uploaded via GVFS MTPДосл╕дження
#сисадм╕нське побутове
П╕в-дня намагався залити фото з камери на телефон. Не через GUI, а файловими операц╕ями. Воно ж доступне. Фото залива╓ться, ╖х видно в File Manager на телефон╕, *╕нколи* вони *частково* з'являються у пов╕домленн╕ "Found new images" в Gallery. ╤ майже н╕коли в загальный галере╖ чи в розд╕л╕ Download, куди я ╖х ╕ заливав. Майже так само з Instagram. То бачить (р╕дко), то не бачить. Повний розсинхрон всього.
 
Зл╕ ╕ стрьомн╕ методи з форум╕в з використанням adb ╕ в╕дладки - також не мають особливого усп╕ху. Купа ут╕л╕т типу Rescan - аналог╕чно.
Нав╕ть зм╕г досягнути ситуац╕╖, коли файла нема, а залити з таким самим ╕менем не да╓ (як з'ясувалось - проблема на сторон╕ ноута, перезавантажив - ╕ все ок)
А через GUI - знов норм.
 
Ок, не зря ж debugger п╕дключав... Врубив максимальний р╕вень лог╕в. ╤ виявля╓ться, що там де ок - одразу в╕дбува╓ться ╕ндексац╕я в╕дпов╕дно до типу файла, а там де н╕ - помилка unsupported type.
 
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
 
Пошук, дореч╕, да╓ мало ц╕нного, кр╕м того, що проблема десь в б╕бл╕отеках... ╤ що ╓ такий 
android-file-transfer, ╓ в пакетах Linux, дореч╕. 
Типу FTP, т╕льки для MTP, для андро╕д╕в. ╤ в╕н працю╓ нормально ! ╤ коректно в╕дбува╓ться ╕ндексац╕я
. То на ньому ╕ зробив соб╕ скрипт для автопереносу фоток.
 
От сиджу тепер ╕ пор╕внюю libmtp, що використову╓ться gvfs'ом ╕ android-file-transfer, в якого власна реал╕зац╕я. ╤ схоже, ще пот╕м в сам gvfs доведеться л╕зти...
 
PS. Ну що, подивився в GVFS.... Якщо файл просто коп╕ю╓ться як на файлову систему (/run/user/xxxx/gvfs/...), 
то йому признача╓ться тип unknown, коли в╕н створю╓ться. 
Хоча, нав╕ить сам libmtp ма╓ ф-ц╕ю отримання типу з назви. Правда, лише в прикладах. В продакшн не п╕шло. ╤ зв╕сно, android не зна╓ що з ним робити. 
А от якщо через GUI - то в комплект╕ йде mime type... Наприклад, image/jpeg... Що береться з ориг╕нала, який ми коп╕ю╓мо.
От шоб вони були здоров╕...
 Indexed upload
#!/bin.shsync_photos.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
 
 
 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
 
 
 
 
См. также
 FB
  or mail alterX@alter.org.ua (remove X)
   
  Share     
 |