{"id":19880,"date":"2025-01-23T07:04:59","date_gmt":"2025-01-23T12:04:59","guid":{"rendered":"https:\/\/nuxx.net\/blog\/?p=19880"},"modified":"2025-06-20T09:04:22","modified_gmt":"2025-06-20T13:04:22","slug":"automated-private-mobile-phone-photo-backup-android-to-apple-photos","status":"publish","type":"post","link":"https:\/\/nuxx.net\/blog\/2025\/01\/23\/automated-private-mobile-phone-photo-backup-android-to-apple-photos\/","title":{"rendered":"Automated Private Mobile Phone Photo Backup (Android to Apple Photos)"},"content":{"rendered":"<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><a href=\"https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2025\/01\/Screenshot-2025-01-23-at-6.48.44\u202fAM.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"631\" src=\"https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2025\/01\/Screenshot-2025-01-23-at-6.48.44\u202fAM-1024x631.png\" alt=\"\" class=\"wp-image-19898\" srcset=\"https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2025\/01\/Screenshot-2025-01-23-at-6.48.44\u202fAM-1024x631.png 1024w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2025\/01\/Screenshot-2025-01-23-at-6.48.44\u202fAM-300x185.png 300w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2025\/01\/Screenshot-2025-01-23-at-6.48.44\u202fAM-768x473.png 768w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2025\/01\/Screenshot-2025-01-23-at-6.48.44\u202fAM-1536x947.png 1536w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2025\/01\/Screenshot-2025-01-23-at-6.48.44\u202fAM-2048x1262.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p>After lots of years of using different photo organization packages, from the lovely (but expensive) <a href=\"https:\/\/www.adobe.com\/products\/photoshop-lightroom-classic.html\">Lightroom Classic<\/a> to <a href=\"https:\/\/www.acdsee.com\/\">ACDSee Photo Studio<\/a>, from <a href=\"http:\/\/galleryproject.org\/\">Gallery<\/a> to various manual things, I&#8217;ve mostly settled on <a href=\"https:\/\/www.apple.com\/in\/macos\/photos\/\">Apple Photos on macOS<\/a>. It seems to work well, handles pretty much every format under the sun, does the basic editing tasks that I use, and is sufficiently widely used to have good community support.<\/p>\n\n\n\n<p>Because I use an Android phone and eschew public cloud provider backups there&#8217;s was no clear path for automatically importing importing the pictures I take to <em>Apple Photos<\/em>. But, it&#8217;s possible, and this writeup is to show shows the toolchain I use to do it.<\/p>\n\n\n\n<p>The end result is that whenever I&#8217;m home I take a photo and it almost immediately appears in Photos. Or when I&#8217;m away and get back home, they automatically sync. Or if I am away for a while and want to sync my photos, I can VPN to home and sync. (I could make it sync from anywhere automatically, but I don&#8217;t yet because it gets really complicated when potentially uploading large amounts of data on mobile data, often in areas of poor connectivity.)<\/p>\n\n\n\n<p>What I settled on was using <a href=\"https:\/\/foldersync.io\/\">FolderSync<\/a> on Android to send the photos to a temporary (Inbox) folder on my NAS via SFTP. I then have <a href=\"https:\/\/www.noodlesoft.com\/\">Hazel<\/a> watch this folder for newly arrived files, import them to <em>Apple Photos<\/em>, adding to a <em>New Photos<\/em> album, and finally putting a copy of the original in an archive folder.<\/p>\n\n\n\n<p>Here&#8217;s how I configured this:<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">NAS \/ macOS<\/h2>\n\n\n\n<p>Due to the number of different NAS&#8217; out there configuration of them is beyond the scope of this post, but in general what you need is a SFTP destination that&#8217;s accessible via your local network. I also then have the same area available via SMB to my Mac, and this share mapped automatically at login.<\/p>\n\n\n\n<p>On here I&#8217;ve created two directories <code>...\/Pixel Backup\/Sync Inbox\/Camera<\/code> which is the inbox for photos from the phone and <code>...\/Pixel Backup\/Archive\/Camera<\/code> as a final, archival resting place for outside of what gets imported into <em>Apple Photos<\/em>, as a just-in-case backup.<\/p>\n\n\n\n<p>(Using a separate folder for a new photo inbox radically improves performance of <em>Hazel<\/em>, because it then doesn&#8217;t have to watch a ~26GB \/ ~6000 file directory for changes.)<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"alignright size-medium\"><a href=\"https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2025\/01\/Screenshot_20250123-065036.png\"><img loading=\"lazy\" decoding=\"async\" width=\"135\" height=\"300\" src=\"https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2025\/01\/Screenshot_20250123-065036-135x300.png\" alt=\"\" class=\"wp-image-19900\" srcset=\"https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2025\/01\/Screenshot_20250123-065036-135x300.png 135w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2025\/01\/Screenshot_20250123-065036-461x1024.png 461w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2025\/01\/Screenshot_20250123-065036-768x1707.png 768w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2025\/01\/Screenshot_20250123-065036-691x1536.png 691w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2025\/01\/Screenshot_20250123-065036-922x2048.png 922w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2025\/01\/Screenshot_20250123-065036.png 1080w\" sizes=\"auto, (max-width: 135px) 100vw, 135px\" \/><\/a><\/figure>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\">FolderSync<\/h2>\n\n\n\n<p>Create a <em>folderPair<\/em> (v2) to back up <code>\/storage\/emulated\/0\/DCIM\/Camera\/<\/code> (<em>Left account<\/em>) to <code>\/Share\/Pixel Backup\/Inbox\/Camera<\/code> on my NAS via SFTP (<em>Right account<\/em>).<\/p>\n\n\n\n<p>Under <em>Scheduling<\/em>, set a schedule for every 30 minutes, with <em>Use WiFi<\/em> checked, and limited to my home network under <em>Allowed WiFi names<\/em>. Under <em>Sync options<\/em>, check <em>Instant sync<\/em> and <em>Only resync source files if modified (ignore target deletion)<\/em>.<\/p>\n\n\n\n<p>The result of this is that when I&#8217;m home, within seconds of taking a photo, it appears on my NAS in <code>...\/Pixel Backup\/Sync Inbox\/Camera<\/code>. Or when I&#8217;m away and take photos they&#8217;ll back up within 30 minutes of getting home.<\/p>\n\n\n\n<p>(Yes, it&#8217;s possible to have FolderSync use SMB, but I prefer SFTP, so that&#8217;s how I set it up.)<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"alignright size-medium\"><a href=\"https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2025\/01\/Screenshot-2025-01-23-at-6.50.55\u202fAM.png\"><img loading=\"lazy\" decoding=\"async\" width=\"300\" height=\"179\" src=\"https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2025\/01\/Screenshot-2025-01-23-at-6.50.55\u202fAM-300x179.png\" alt=\"\" class=\"wp-image-19899\" srcset=\"https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2025\/01\/Screenshot-2025-01-23-at-6.50.55\u202fAM-300x179.png 300w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2025\/01\/Screenshot-2025-01-23-at-6.50.55\u202fAM-1024x610.png 1024w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2025\/01\/Screenshot-2025-01-23-at-6.50.55\u202fAM-768x457.png 768w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2025\/01\/Screenshot-2025-01-23-at-6.50.55\u202fAM-1536x915.png 1536w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2025\/01\/Screenshot-2025-01-23-at-6.50.55\u202fAM-2048x1220.png 2048w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/figure>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\">Hazel<\/h2>\n\n\n\n<p>Create a Hazel rule to watch <code>...\/Pixel Backup\/Sync Inbox\/Camera<\/code> for new files and import them into Photos:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>If <em>All<\/em> of the following conditions are met<br><br><em>Extension<\/em> <em>is not<\/em> <code>tacitpart<\/code><br><em>Name does not start with<\/em> <code>.pending<\/code><br><em>Date Last Modified is not in the last<\/em> <code>10<\/code> <em>minutes<\/em><br><br>Do the following to the matched file or folder:<br><em>Import into Photos<\/em> to album: <em>New Photos<\/em><br><em>Move<\/em> to folder: <em>Camera<\/em><\/p>\n<\/blockquote>\n\n\n\n<p>Files that are incompletely transferred (in flight or had an error) will have a <code>.tacitpart<\/code> extension if sync&#8217;d with a v1 folderPair, or will begin with <code>.pending<\/code> if a v2. This rule ensures that only complete files are processed, imports them into a new album called <em>New Photos<\/em>, and then moves them to <code>...\/Pixel Backup\/Archive\/Camera<\/code>.<\/p>\n\n\n\n<p>The 10 minute delay is needed because otherwise, Hazel will sometimes import a partially-written file resulting in a partial or corrupt image. This manifests as either a series of errors in <em>Apple Photos<\/em> about importing duplicates or the same photo imported multiple times, but incomplete, with the lower portion of the image corrupt and replaced with solid gray. (This delay could probably be reduced, but for now I&#8217;m using 10 minutes. I may reduce this in the future.)<\/p>\n\n\n\n<p>(Note: I tried syncing photos into a single folder and having Hazel watch that for changes, but performance was very poor. I&#8217;m unsure of whether this was caused by using it over a network, it&#8217;s size, or the number of files to be parsed, although based on Hazel&#8217;s performace on a very full Download folder I suspect the latter. I didn&#8217;t bother to investigate further, as using the <code>Sync Inbox<\/code> architecture works out better, and makes it easier to troubleshoot and recover if something goes awry.)<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Apple Photos<\/h2>\n\n\n\n<p><em>Apple Photos<\/em> has a library containing all images, and these images may or may not be assigned to one or more albums.<\/p>\n\n\n\n<p>My preferred workflow is to have individual albums for select projects, trips, or whatnot, and all other mobile phone images in a general <em>Mobile Photos<\/em> album. To facilitate this, <em>Hazel<\/em> puts all new photos from my phone into a <em>New Photos<\/em> album. I then periodically look at this album, sort the photos into the desired other albums, and then remove them from this album. (Or, sometimes, delete them entirely.)<\/p>\n\n\n\n<p>While I could have everything just go into the main pool of photos, they are somewhat unsorted, and dependent on metadata or parsing of the image content itself for sorting For personal reasons I like to have each photos in an album of some sort, and I find that this inbox of sorts best matches how I like to manage my photos.<\/p>\n\n\n\n<p>But the best thing is that photos I take using my phone while working on projects at home are immediately available in <em>Photos<\/em> and then backed up. And those taken while away get uploaded immediately upon returning or by connecting to VPN and telling <em>FolderSync<\/em> to sync immediately, <em>&#8220;&#8230;on any available network connection&#8221;<\/em>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">That&#8217;s It!<\/h2>\n\n\n\n<p>And, that&#8217;s that. I take photos on my phone, they automatically appear in <em>Photos<\/em> and get archived on my NAS, and then backed up. Effective, yet simple to use.<\/p>\n\n\n\n<p>For what it&#8217;s worth, I also have some other sync tasks in <em>FolderSync<\/em> and <em>Hazel<\/em> to handle screenshots, images attached to or saved from messages (SMS, Google Chat, Facebook Messenger, Signal, etc), but it&#8217;s all done with similar flows to what&#8217;s above, so I&#8217;m not going to document them separately.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Update on 2025-Jun-20<\/h2>\n\n\n\n<p>I previously had issues with <em>Photos<\/em> where the <em>Memorie<\/em>s, <em>Trips<\/em>, and <em>Featured Photos<\/em> sections just didn&#8217;t work. All of these indicate that I need to add more photos, but I&#8217;ve got some 64,000 photos spanning 20+ years of <a href=\"https:\/\/en.wikipedia.org\/wiki\/Exif\">EXIF<\/a> dates and locations, and the <em>People &amp; Pets<\/em>, <em>Map<\/em>, <em>Handwriting<\/em>, and <em>Illustration<\/em> sections\/detections work fine, so I don&#8217;t think it&#8217;s an issue with quantity nor the ability to parse the photos. This was fixed at some point between when I originally wrote the article in late January 2025 and now.<\/p>\n\n\n\n<p>Since writing the article I also ran into some issues with partial syncing of files, especially when the wireless connection was poor and copying was slow, so I added another rule to Hazel so it won&#8217;t sync files newer than 10 minutes which seems to have taken care of it.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>After lots of years of using different photo organization packages, from the lovely (but expensive) Lightroom Classic to ACDSee Photo Studio, from Gallery to various&#8230;<\/p>\n<div class=\"more-link-wrapper\"><a class=\"more-link\" href=\"https:\/\/nuxx.net\/blog\/2025\/01\/23\/automated-private-mobile-phone-photo-backup-android-to-apple-photos\/\">Continue reading<span class=\"screen-reader-text\">Automated Private Mobile Phone Photo Backup (Android to Apple Photos)<\/span><\/a><\/div>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[13],"tags":[],"class_list":["post-19880","post","type-post","status-publish","format-standard","hentry","category-computers","entry"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/posts\/19880","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/comments?post=19880"}],"version-history":[{"count":6,"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/posts\/19880\/revisions"}],"predecessor-version":[{"id":19946,"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/posts\/19880\/revisions\/19946"}],"wp:attachment":[{"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/media?parent=19880"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/categories?post=19880"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/tags?post=19880"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}