MetaCtrl
/favicon.ico
2024-03-15T13:16:46+01:00
https://metactrl.com/
MetaCtrl
© 2013-2024 MetaCtrl
https://metactrl.com/blog/2021/04/14/autosync-universal/
Autosync - Universal cloud file sync and backup
2021-04-14T00:00:00+02:00
2021-04-14T00:00:00+02:00
MetaCtrl
https://metactrl.com/
<p>After a long early access testing phase, our new app <strong>Autosync Universal</strong> has reached the stable quality level and
version 1.0 milestone:</p>
<p><span><img src="/assets/img/app_logos/autosync-web-256.png" width="32" height="32" />
<a href="https://play.google.com/store/apps/details?id=com.ttxapps.autosync">Autosync Universal</a>
</span></p>
<p><strong>Autosync Universal</strong> backs up and syncs files between your Android device and your storage service. This app is called
<strong>Universal</strong> because it supports multiple storage services in one app. This is the current list of supported services:</p>
<ul>
<li>Google Drive</li>
<li>OneDrive</li>
<li>SharePoint Online</li>
<li>Dropbox</li>
<li>Box</li>
<li>MEGA</li>
<li>Nextcloud</li>
<li>ownCloud</li>
<li>pCloud</li>
<li>Yandex Disk</li>
<li>WebDAV</li>
<li>FTP</li>
<li>SFTP (ssh/scp)</li>
<li>LAN/SMB network drives</li>
</ul>
<p>If your cloud storage is not on the list, please check if it supports WebDAV protocol. WebDAV is widely supported by many
storage service vendors. LAN/SMB network drives are supported by Windows/Mac/Linux computers and NAS devices. This app can
sync with them via local network.</p>
<p>If your cloud is not supported, email us and we’ll see what can be done about it.</p>
<p><span><img src="/assets/img/app_logos/autosync-web-256.png" width="32" height="32" />
<strong><a href="https://play.google.com/store/apps/details?id=com.ttxapps.autosync">Autosync Universal</a></strong>
</span></p>
<p><img src="/assets/blog/2021-04-14-autosync-universal-1.png" alt="screenshot" /></p>
https://metactrl.com/blog/2018/10/28/gdrive-computer-backup-folders/
Sync Google Drive Computer Backup Folders
2018-10-28T00:00:00+02:00
2018-10-28T00:00:00+02:00
MetaCtrl
https://metactrl.com/
<p>The <em>Backup and Sync</em> desktop client from Google syncs the “Google Drive” folder in your computer with “My Drive”
in Google Drive cloud automatically, same as what their old desktop Google Drive client did. But in addition to that
users can also configure <em>Backup and Sync</em> to sync arbitrary folders in their computer with Google Drive cloud,
any folder anywhere even outside the “Google Drive” folder. This is neat except for two problems. The first is each
computer gets its own backup folder in Google Drive. Two computers, say a laptop and a desktop PC, have their own
separate backup folders. If users want to share a folder between two computers that folder still must be inside
“My Drive” / “Google Drive” folder. The second problem is that those computer backup folders are not directly
accessible to 3rd party apps through the official Google Drive API.</p>
<p>Google obviously intend this feature to be used as a file backup solution. Whether or not it is a good backup solution
is not the topic we want to discuss here. What I want to announce in this post is with
<strong><a href="https://play.google.com/store/apps/details?id=com.ttxapps.drivesync">DriveSync</a></strong>
version 3.2 or later you can sync folders in your Android device with Computer backup folders or their subfolders.
<strong>Effectively you can sync any folder in your device storage with any folder in your computer!</strong></p>
<h4 id="how-does-it-work">How does it work?</h4>
<p>Recently I added ability to sync Team Drives and <em>“shared with me”</em> folders to
<strong><a href="https://play.google.com/store/apps/details?id=com.ttxapps.drivesync">DriveSync</a></strong>.
Starting with version 3.2 you can also sync <strong>starred folders</strong>. In Google Drive users can bookmark folders or files for
quick access by adding stars to them. Those starred folders/files are displayed under <strong>“Starred”</strong> section in the
navigation menu of Google Drive website. It turns out that apps like DriveSync can list and access the starred folders
using Google Drive API even if they are computer backup folders.</p>
<p>To sync files in Computer backup folders first you need to add stars to them. Do so on the Google Drive website. You can
choose to star the top level folders “My Laptop”, “My Mac”, or their subfolders.</p>
<p><img src="/assets/blog/2018-10-28-starred-1.png" alt="screenshot" /></p>
<p>In DriveSync when you configure a new
folder pair, go to <strong>Starred</strong> in the Google Drive folder chooser, you’ll see your starred folders there, including
those starred backup folders. Navigate down to the subfolder you want to sync, select it and finish the folder pair setup
as you do for normal Google Drive folders.</p>
<p><img src="/assets/blog/2018-10-28-starred-2.png" alt="screenshot" />
<img src="/assets/blog/2018-10-28-starred-3.png" alt="screenshot" /></p>
<p>In fact if you sync the same folder in your Android phone via two folder pairs with two Computer backup folders, say
Laptop/Foo and Desktop/Bar, you can share the content of Foo in your laptop with Bar in your desktop PC, something even
the official <em>Backup and Sync</em> can’t do! Foo and Bar are bridged by DriveSync in your phone.</p>
<p>Don’t unstar a folder if it’s used in DriveSync. Doing so makes it disappear from “Starred folders” and invisible
to DriveSync.</p>
https://metactrl.com/blog/2018/03/12/megasync/
MegaSync - autosync files between Android and MEGA
2018-03-12T00:00:00+01:00
2018-03-12T00:00:00+01:00
MetaCtrl
https://metactrl.com/
<p>I am adding a new entry to my collection of cloud sync apps:
<strong><a href="https://play.google.com/store/apps/details?id=com.ttxapps.megasync">MegaSync</a></strong>.
This app backs up and syncs files between
your Android device and <a href="http://mega.nz">MEGA</a> cloud storage. MegaSync has been in closed alpha testing for a month.
A few days ago I released it to Early Access channel on Google Play. Feedback so far has been pretty positive.
If you are using MEGA and Android, definitely give MegaSync a try:</p>
<p><strong><a href="https://play.google.com/store/apps/details?id=com.ttxapps.megasync">Autosync MEGA - MegaSync on Google Play</a></strong></p>
<p>If you use other cloud storages but not MEGA, it’s something worth checking out. The unique feature of MEGA is client side
encryption. Your files are stored in their cloud encrypted by your password. Nobody, including MEGA employees, should be
able to decrypt and read your data.</p>
<p>As usual don’t hesitate to email me any issues, suggestions, questions you may have with my app. The email address is in
the app store listing and also in the app itself <em>(Settings > Support)</em>.</p>
<p><img src="/assets/blog/2018-03-12-megasync-1.png" alt="screenshot" /></p>
https://metactrl.com/blog/2018/02/07/sync-team-drives/
Autosync files in Android with Google Team Drives
2018-02-07T00:00:00+01:00
2018-02-07T00:00:00+01:00
MetaCtrl
https://metactrl.com/
<p>DriveSync 3.1 has arrived on Google Play. In addition to the usual bug fixes there are some significant new features:
ability to sync with Team Drives and sync with “shared-with-me” folders.</p>
<h4 id="sync-team-drives">Sync Team Drives</h4>
<p>In <a href="https://play.google.com/store/apps/details?id=com.ttxapps.drivesync">DriveSync</a>
you set up folder pairs: one folder in your device (local folder), another folder in Google Drive (remote folder) and
choose the sync method. The app will keep these two folders in sync with each other. Starting with version 3.1 as the
remote folder you can choose a subfolder inside Google Team Drives. That way you can directly sync files in your device
with a folder owned by your team.</p>
<p><img src="/assets/blog/2018-02-07-sync-team-drives-1.png" alt="screenshot" />
<img src="/assets/blog/2018-02-07-sync-team-drives-2.png" alt="screenshot" /></p>
<h4 id="sync-shared-with-me-folders">Sync “shared-with-me” folders</h4>
<p>Previously DriveSync could only let you choose folders inside your “My Drive”. If someone shared a folder with you, you need
to go to Google Drive website and add that folder to “My Drive” first. With DriveSync 3.1 you can sync any folder shared to
you by someone without adding it to your Drive. This is more or less “nice to have” feature, but I added it to the app
anyway because users have been asking for it.</p>
<p>DriveSync respects the access permissions of the shared folders. If you want it to upload files to them, the owners of the
folders must grant you write access. If sync fails this is something you should check.</p>
https://metactrl.com/blog/2018/02/06/sync-sharepoint-sites/
Autosync files in Android with SharePoint sites
2018-02-06T00:00:00+01:00
2018-02-06T00:00:00+01:00
MetaCtrl
https://metactrl.com/
<p>OneSync 3.1 has arrived on Google Play. Besides the usual bug fixes there are some significant new features:
ability to sync with SharePoint sites and sync with “shared-with-me” folders.</p>
<h4 id="sync-sharepoint-sites">Sync SharePoint sites</h4>
<p>In <a href="https://play.google.com/store/apps/details?id=com.ttxapps.onesyncv2">OneSync</a>
you set up folder pairs: one folder in your device (local folder), another folder in the cloud storage (remote folder)
and choose the sync method. The app will keep these two folders in sync with each other. Starting with version 3.1 as
the remote folder you can choose a subfolder inside your company’s or team’s SharePoint site. That way you can directly
sync files in your device with a cloud folder shared by your team.</p>
<p><img src="/assets/blog/2018-02-06-sync-sharepoint-sites-1.png" alt="screenshot" />
<img src="/assets/blog/2018-02-06-sync-sharepoint-sites-2.png" alt="screenshot" /></p>
<h4 id="sync-shared-with-me-folders">Sync “shared-with-me” folders</h4>
<p>Previously OneSync could only let you choose folders inside your OneDrive. If someone shared a folder with you, you need
to go to OneDrive website and add that folder to “My OneDrive” first. That’s usually fine because if you want to access
that folder frequently it’s more convenient to have it in your OneDrive anyway. Your OneDrive desktop client would sync
that shared folder to a folder in you computer. With OneSync 3.1 you can sync any folder shared to you by someone without
adding it to your OneDrive.</p>
<p>For OneDrive Personal it’s more or less “nice to have” feature, but for OneDrive for Business it’s significant. That’s
because in the business flavor of OneDrive for whatever reasons you can’t add shared folders to your OneDrive! Until now
you practically can’t use OneSync to sync shared folders of any kind. In OneSync 3.1 you can sync
both the team-owned SharePoint folders and OneDrive shared folders.</p>
<p>OneSync respects the access permissions of the shared folders. If you want it to upload files to them, the owners of the
folders must grant you write access. If sync fails this is something you should check.</p>
https://metactrl.com/blog/2018/01/18/sync-multiple-accounts/
Sync Files in Android Device with Multiple Storage Accounts
2018-01-18T00:00:00+01:00
2018-01-18T00:00:00+01:00
MetaCtrl
https://metactrl.com/
<p>These days many of us have our personal GMail/Google Drive account and also one or even several GSuite accounts because
of school or work. It’s possible to share a folder from one Google Drive account to another and configure DriveSync to
sync that shared folder together with other folders under one Google Drive account. But that solution is always only
a workaround. Many companies also tightly control who their users can share their files with. Sharing is allowed only within
the same company, making this workaround unusable.</p>
<p>Some users want to use several storage accounts to get around limited storage quota in each account. Another group
of users have one storage account they actively use and want to use a separate account purely to backup data from their phone.</p>
<p>Whatever the use case, now users can connect DriveSync app with several Google Drive accounts they have access to, then set
up folder pairs to sync a folder in their device with a folder in any of those connected Google Drive accounts. Same for
Dropsync / Dropbox, OneSync / OneDrive, BoxSync / Box.</p>
<p>Sync with multiple storage accounts was added in the latest 3.0 version of our
<a href="https://play.google.com/store/apps/developer?id=MetaCtrl">sync apps</a>
which is being rolled out on Google Play. This feature is available to existing Ultimate users without any extra charge.
Pro users can upgrade from Pro to Ultimate with discount.</p>
https://metactrl.com/blog/2016/05/21/onesync-emergency-update/
OneSync Emergency Update to Workaround Server Side Bug
2016-05-21T00:00:00+02:00
2016-05-21T00:00:00+02:00
MetaCtrl
https://metactrl.com/
<p>There is an ongoing issue in OneDrive Personal server causing sync failures for some users. OneSync uses a resumable
upload API method to upload files. Resumable upload is an important feature. If network connection is interrupted, at next
attempt OneSync continues from the point in the file where upload was aborted. Without this feature the whole file would
have to be re-uploaded from scratch. Unfortunately this API method currently fails with a server side error <em>“503 Service
Unavailable”</em> and a message <em>“Our services aren’t available right now. We’re working to restore all services as soon as
possible. Please check back soon”</em>. This situation has lasted for more than two days for many users, myself included.
I’ve filed a support ticket for OneDrive team but haven’t heard back from them yet.</p>
<p>I’ve just released an emergency update of OneSync which has resumable upload disabled. Simple upload is used instead.
This is not ideal but at least small and medium size files can be uploaded. Files larger than 100 MB require resumable
upload API and therefore attempts to upload them continue to fail until the bug is fixed on the server side.</p>
<p>Please <a href="https://play.google.com/store/apps/details?id=com.ttxapps.onesyncv2">update the app</a>.</p>
<p>This issue affects OneDrive Personal accounts only. OneDrive for Business (Office 365) accounts are working fine.</p>
https://metactrl.com/blog/2016/04/14/resumable-download-onedrive-for-business/
Resumable Download Works with OneDrive for Business
2016-04-14T00:00:00+02:00
2016-04-14T00:00:00+02:00
MetaCtrl
https://metactrl.com/
<p><a href="/blog/2016/04/10/resumable-upload-onedrive-for-business/">A few days ago I announced</a> support for <strong>resumable upload</strong>
to OneDrive for Business in OneSync app. I ended the blog post with</p>
<blockquote>
With this limitation removed OneSync now works very well with both OneDrive flavors.
</blockquote>
<p>Well, not true. There is a subtle issue in OneDrive for Business API implementation which breaks resumable <strong>download</strong>.
Download works but it’s not “resumable”. If a network error occurs and breaks ongoing download, at the next attempt
OneSync restarts from the very beginning of the file. Poor testing on my side.</p>
<p>This issue has been fixed. Please go to Google Play and
<a href="https://play.google.com/store/apps/details?id=com.ttxapps.onesyncv2">update the app</a>.</p>
https://metactrl.com/blog/2016/04/10/resumable-upload-onedrive-for-business/
Resumable Upload Now Works with OneDrive for Business
2016-04-10T00:00:00+02:00
2016-04-10T00:00:00+02:00
MetaCtrl
https://metactrl.com/
<p>Early last week I updated <a href="https://play.google.com/store/apps/details?id=com.ttxapps.onesyncv2">OneSync</a> to add support
for OneDrive for Business. As <a href="/blog/2016/04/05/onesync-supports-onedrive-for-business/">I wrote at that time</a>
there was one major limitation: resumable upload is not supported. Without that feature it’s very difficult to upload
large files (say larger than 100 MB) from device to OneDrive server.</p>
<p>Well, not so anymore. A new version of <a href="https://play.google.com/store/apps/details?id=com.ttxapps.onesyncv2">OneSync</a> was
released on Google Play yesterday. Resumable upload now works. If upload is interrupted, for example because of network
error, OneSync remembers which portion of the file has been uploaded and continues from there at the next attempt. During
testing I successfully uploaded many GB video files. It took time but all worked smoothly, despite intentional network
interruptions and manual sync cancellations.</p>
<p>It turned out a couple of weeks ago Microsoft updated their server software to add resumable upload. When I started
implementing support for OneDrive for Business Microsoft developer website explicitly stated resumable upload was not
supported. The API was there but not implemented by the server. When I checked again last week that sentence was removed.
Basically they added a new feature without telling the world about it!</p>
<p>With this limitation removed OneSync now works very well with both OneDrive flavors: personal and buisness
(work/school accounts). Please go to Google Play and
<a href="https://play.google.com/store/apps/details?id=com.ttxapps.onesyncv2">update the app</a>.</p>
https://metactrl.com/blog/2016/04/05/onesync-supports-onedrive-for-business/
OneSync Now Supports OneDrive for Business
2016-04-05T00:00:00+02:00
2016-04-05T00:00:00+02:00
MetaCtrl
https://metactrl.com/
<p>I added support for OneDrive for Business accounts in <a href="https://play.google.com/store/apps/details?id=com.ttxapps.onesyncv2">OneSync</a>.
OneSync now can autosync files and folders between Android device and both types of OneDrive. If you are one of those users
who liked OneSync but couldn’t use it because of the lack of support for OneDrive for Business, please go to Google Play,
<a href="https://play.google.com/store/apps/details?id=com.ttxapps.onesyncv2">install the app</a> and give it another try. This new
feature has gone through beta testing in the last few weeks and should be ready for prime time.</p>
<p>Despite similarity in their names OneDrive and OneDrive for Business are two different products. OneDrive (aka OneDrive
for consumers or OneDrive Personal) is what you get when you sign up as an individual. OneDrive for Business is what
comes as part of Office 365 for Business. If you have a Microsoft account at work or school, it’s OneDrive for Business.
OneDrive for Business is built on top of Microsoft SharePoint product which has been around for years. OneDrive Personal
is a new thing.</p>
<p>Recently Microsoft added the same unified API on top of both products. That’s what OneSync uses. But despite the same API,
a similar name, and a similar login process OneDrive for Business has a couple of limitations</p>
<p><strong>Folders someone shared with you are not syncable</strong></p>
<p>Those folders don’t show up in OneDrive API. OneSync does not see them and can’t sync them. <a href="https://onedrive.uservoice.com/forums/262982-onedrive/suggestions/9163807-onedrive-for-business-implement-shared-folder-sy">The same applies to
the official OneDrive client for PC</a>.
Note you can sync folders you own but share to someone else just fine. This limitation is about folders from someone else
(schoolmates, co-workers) who share them with you. These shared-with-me folders can be accessed only via OneDrive for Business
web site.</p>
<p><strong>Resumable upload is not supported</strong></p>
<p><em>[ UPDATE April 10, 2016: <a href="/blog/2016/04/10/resumable-upload-onedrive-for-business/">resumable upload is now supported</a> ]</em></p>
<p>For medium and small files this is not a problem. But uploading large files (say videos larger than 100 MB) needs stable
network connection. If the connection is flaky and breaks in the middle of the upload process, OneSync must restart from
the first byte at its next attempt. And if the connection to the server breaks again, the app will have to restart from
the first byte, again. If you are not familiar with resumable file transfer and why it’s useful please read my old
<a href="/blog/2015/07/03/drivesync-supports-resumable-file-transfer/">blog post</a>. It talks about
<a href="https://play.google.com/store/apps/details?id=com.ttxapps.drivesync">DriveSync</a> but the principle is the same.</p>
<p>Microsoft is aware of these limitations. They are quite active with OneDrive product development. Let’s hope that they will
address them adequately in a reasonable time frame.</p>
https://metactrl.com/blog/2016/04/01/sync-app-sale/
50% Sale - All My Cloud Sync Apps
2016-04-01T00:00:00+02:00
2016-04-01T00:00:00+02:00
MetaCtrl
https://metactrl.com/
<p><strong>This is NOT an April Fool joke!</strong></p>
<p>I run 50% off sale for Pro and Ultimate paid upgrades in all my cloud storage sync apps. They are in-app purchases.
Their prices have been reduced by ~50% compared to the regular prices. This sale will last for a couple of days.</p>
<p>I don’t run sale often. The last sale was a year ago if I recall correctly. If you like my autosync apps but so far
hesitate to pay for the upgrades, this is the right time to do it. If you already paid the full price, please accept my
heartfelt thanks and tell your friends about this sale and my apps.</p>
<p>Here are the links to those apps in Google Play. You need to install them, then make in-app upgrades.</p>
<ul>
<li><a href="https://play.google.com/store/apps/details?id=com.ttxapps.dropsync&referrer=utm_source%3DMetaCtrlCom%26utm_medium%3Dreferral%26utm_campaign%3D201604Sale">Dropsync</a>:
Autosync files between Android and Dropbox</li>
<li><a href="https://play.google.com/store/apps/details?id=com.ttxapps.drivesync&referrer=utm_source%3DMetaCtrlCom%26utm_medium%3Dreferral%26utm_campaign%3D201604Sale">DriveSync</a>:
Autosync files between Android and Google Drive</li>
<li><a href="https://play.google.com/store/apps/details?id=com.ttxapps.onesyncv2&referrer=utm_source%3DMetaCtrlCom%26utm_medium%3Dreferral%26utm_campaign%3D201604Sale">OneSync</a>:
Autosync files between Android and Microsoft OneDrive</li>
<li><a href="https://play.google.com/store/apps/details?id=com.ttxapps.boxsync&referrer=utm_source%3DMetaCtrlCom%26utm_medium%3Dreferral%26utm_campaign%3D201604Sale">BoxSync</a>:
Autosync files between Android and Box</li>
</ul>
https://metactrl.com/blog/2016/03/14/many-to-one-sync/
Sync Multiple Folders with One Folder
2016-03-14T00:00:00+01:00
2016-03-14T00:00:00+01:00
MetaCtrl
https://metactrl.com/
<p>The central concept in all my sync apps (be it Dropsync, DriveSync, OneSync, or BoxSync) is the so called
<a href="/userguide/#folder-pair">folder pair</a>. You pick a folder in your device, pair it with another folder in the cloud storage.
Choose the sync method. From that point on the app will keep the contents of these two folders in sync according to the
chosen sync method.</p>
<p>The relationship between folders is one-to-one. You can’t pair the same folder in your device with several folders in the
cloud storage account. “Pair” implies there are only two parties. This makes perfect sense for the two-way sync method where
sync is bi-directional. Changes on one side are transferred to the other side, and vice versa. That includes file and
subfolder deletions. If you paired folder A in your device with folder B and also folder C in the cloud, a new file in
folder A would be uploaded to both B and C. Eventually we end up with three folders with exact same contents: A in the
device, and two exact same copies, B and C, in the cloud.</p>
<p>On the other hand for <strong>some one-way sync methods</strong> (upload only, upload then delete, download only, download then delete)
it makes perfect sense to transfer files from several source folders to one folder. You basically merge several folders
into one. The best real-world example I can think of is to upload photos taken on your phone to one cloud folder. If your
device has a SD card, photos can be stored in two locations: internal storage and SD card. The location is controlled by
the camera app’s settings but even then sometimes photos must be stored in the internal storage for speed reason (e.g.
taking photos in burst mode). You wan to be able to upload both folders into the same folder, let’s say “Fotky”, in the
cloud. In the past you couldn’t do it. Now you can:</p>
<p><img src="/assets/blog/2016-03-many-to-one.png" alt="screenshot" /></p>
<p>I removed the one-to-one restriction. You can pair the same folder on one side with several folders on other side. The folder
pair concept stays the same but one folder can be configured in multiple folder pairs which effectively achieves the
many-to-one setup.</p>
<p>This is an advanced feature. You can sync any folder with any folder using any sync method. You can make the app to do weird
things. For example: upload A to B, download B to C, upload C to D, download D to A. Such setup leads to infinite sync
loop! It may be fun to try it out once but probably only once. This is why I’ve been refusing to relax the one-to-one
restriction for so long!</p>
<p>Now you can, but as with any kind of power, be very careful. Make sure you completely understand what
<a href="/userguide/#folder-pair">each sync method does</a>. In general if you pair the same folder with multiple folders</p>
<ul>
<li>Don’t use two-way sync method. Just don’t!</li>
<li>Use the same direction in all those sync pairs: upload only/upload then delete, or download only/download then delete.
Don’t mix.</li>
<li>You probably don’t want to use the mirror methods: upload mirror, download mirror. The app does not prevent you from
doing so but it’s hard to imagine a situation when such a setup would be useful.</li>
</ul>
https://metactrl.com/blog/2016/02/16/reorder-folders-by-dnd/
Long Press & Drag to Change Folder Order
2016-02-16T00:00:00+01:00
2016-02-16T00:00:00+01:00
MetaCtrl
https://metactrl.com/
<p>When the UI of my sync apps was updated to Material Design, one feature was lost. In the version released last week
you can’t change the order of synced folders anymore. Now it’s back and I think with much better implementation.
Instead of the cumbersome gesture Context Menu > Move Up/Down, you can simply long press on the card, hold it
for a second, then drag it to its new position.</p>
<p><a href="https://play.google.com/store/apps/developer?id=MetaCtrl">New versions</a> are being pushed to Google Play servers right now.</p>
<p>I hope you’ll like this little feature.</p>
<p><img src="/assets/blog/2016-02-16-syncpair-dnd.gif" alt="screenshot" /></p>
https://metactrl.com/blog/2016/02/08/material-design/
Material Design Update
2016-02-08T00:00:00+01:00
2016-02-08T00:00:00+01:00
MetaCtrl
https://metactrl.com/
<p>Some time in December I set out to update my apps to Material Design. Some minimalistic update was done when the new design
came out but it wasn’t full update. At that time I only tweaked the app action bar to make it visually compatible.
This time I decided to go all in. Over the lifetime of these sync apps, there were numerous improvements made to the sync
engine but the UI concept is more or less the same. This round it’s the other way. The focus is on the UI, not the sync
engine. My internal goal was getting it done by the end of the year. Naïve me. I eventually rewrote almost all of the code
dealing with UI and in fact also refactored part of the sync framework. Luckily I didn’t say by the end of which year.
Today is Vietnamese New Year and the work is largely done. By the end of the year, promise kept after all :-)</p>
<p>The new UI concept also will make it easier to plug in some long time requested features (for example sync settings per
folder pair). The sync engine was prepared for them but I couldn’t find a good way to expose these features in the old UI.
This major update allows for a series of bigger set of new substantial features in the next months.</p>
<p>I am rolling out the new versions on Google Play this week using staged rollout. I’ve been testing the app extensively,
but still, there were so many changes. I’d rather roll them out gradually and stay on watch.</p>
<p>Here are a few screenshots:</p>
<p><img src="/assets/blog/2016-02-08-material-design/01-status.png" alt="screenshot" />
<img src="/assets/blog/2016-02-08-material-design/02-history.png" alt="screenshot" />
<img src="/assets/blog/2016-02-08-material-design/03-syncpairs.png" alt="screenshot" />
<img src="/assets/blog/2016-02-08-material-design/04-editsyncpair.png" alt="screenshot" /></p>
https://metactrl.com/blog/2015/12/13/onedrive-shared-folders/
OneSync Now Supports OneDrive Shared Folders
2015-12-13T00:00:00+01:00
2015-12-13T00:00:00+01:00
MetaCtrl
https://metactrl.com/
<p><strong>TL;DR</strong> I’ve added support for OneDrive shared folders to
<a href="https://play.google.com/store/apps/details?id=com.ttxapps.onesyncv2">OneSync</a>.
The new version is in <a href="/docs/beta-testing/">Google Play beta channel</a>
and will be pushed to the official channel when I’ll feel confident there are not nasty new bugs lurking there. Probably
sometime next week.</p>
<p>In OneDrive when someone shares a folder with you and you accept it, the shared folder shows up under “Shared”. If the owner
gives you read/write permission (“User can edit”) you can “Add to my OneDrive”. This shared folder will be seen among your
other folders in OneDrive / Files. The official OneDrive desktop client would sync this folder to your PC, exactly like
any of your other folders.</p>
<p>Immeadiately after this new “Add to my OneDrive” feature was added I checked OneSync code and found that although at the
UI level the shared folder behaves as if it were a normal folder, it’s not the case at the API level. Simply put, the shared
folder requires special treatment which is not there in the OneDrive API from Microsoft. Feedback was submitted to OneDrive
team</p>
<p><a href="https://onedrive.uservoice.com/forums/262982-onedrive/suggestions/9409113-new-api-not-able-to-access-shared-to-me-folders-ev">New API not able to access shared-to-me folders even after “Add to my OneDrive”</a></p>
<p>It was on August 20, 2015. On September 17 the OneDrive team flagged this ticket with “In the Plans”. In the meantime it
climbed to the top of most-voted tickets in “Developer” category. Two days ago, December 11, I got email notification
“Boom! It’s done” with link to the newly added API. Yesterday I updated my code. Today there is a new public beta version
of OneSync supporting shared folders.</p>
<p>This is what I think the relationship between developers and a platform company should be. The OneDrive team did not
promise to respond to all feedback but they promised to read them all and would respond to the most voted tickets.
In this case the response was positive: “In the plan”. It took them 4 months to execute “the plan” but today it’s
indeed done. They kept their promise. In the ticket on UserVoice there are not many words, nobody threatened
to migrate to other platforms, no yelling. Just normal communication among mature grownups where each one did their part.
Sadly this is not usual experience indie devs have when giving feedback to other big platform companies. They should
take note. We don’t need or even want to be “evangelized”, just give us a <strong>sincere</strong> <strong>two-way</strong> communication channel.</p>
<p>P.S. you can “add to my OneDrive” only if the owner gives you read/write permission. Shared folders
with read-only permission and shared files cannot be added to “My OneDrive”, cannot be synced by OneDrive official desktop
client, and also cannot be synced by OneSync.</p>
https://metactrl.com/blog/2015/12/07/sdcard-on-marshmallow/
Support for SD Card on Android 6.0 (Marshmallow)
2015-12-07T00:00:00+01:00
2015-12-07T00:00:00+01:00
MetaCtrl
https://metactrl.com/
<p>Since Android 4.4 (KitKat) Google keeps making significant changes in how apps can access the removable
SD card. In KitKat <a href="/docs/sdcard-on-kitkat/">apps cannot write to folders on SD card</a>. In Android 5.x
(Lollipop) there is a new way to write to the SD card, albeit with <a href="/docs/sdcard-on-lollipop/">poor user experience</a>
and <a href="/blog/2015/08/03/extremely-slow-sd-card-access-on-lollipop/">bad performance</a>.</p>
<p>Android 6.0 (Marshmallow) officially does not introduce new restrictions in SD card access, but it breaks
the current API semantics in a subtle way. To delete a file <code class="language-plaintext highlighter-rouge">/storage/35A5-BE41/foo/bar.txt</code> on SD card,
we are supposed to use code like this</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">DocumentFile</span> <span class="n">fooDir</span> <span class="o">=</span> <span class="nc">DocumentFile</span><span class="o">.</span><span class="na">fromTreeUri</span><span class="o">(</span><span class="n">context</span><span class="o">,</span> <span class="n">fooTreeUri</span><span class="o">);</span>
<span class="nc">DocumentFile</span> <span class="n">barFile</span> <span class="o">=</span> <span class="n">fooDir</span><span class="o">.</span><span class="na">findFile</span><span class="o">(</span><span class="s">"bar.txt"</span><span class="o">);</span>
<span class="kt">boolean</span> <span class="n">deleted</span> <span class="o">=</span> <span class="n">barFile</span><span class="o">.</span><span class="na">delete</span><span class="o">();</span> <span class="c1">// => true</span>
<span class="kt">boolean</span> <span class="n">exist</span> <span class="o">=</span> <span class="o">(</span><span class="k">new</span> <span class="nc">File</span><span class="o">(</span><span class="s">"/storage/35A5-BE41/foo/bar.txt"</span><span class="o">)).</span><span class="na">exists</span><span class="o">();</span> <span class="c1">// => true !!</span>
</code></pre></div></div>
<p><code class="language-plaintext highlighter-rouge">DocumentFile.delete()</code> is supposed to return <code class="language-plaintext highlighter-rouge">true</code> if the file was deleted, otherwise <code class="language-plaintext highlighter-rouge">false</code>. That’s
what its javadoc says and on a par with what normal <code class="language-plaintext highlighter-rouge">File.delete()</code> returns. But if we check for the
existence of the file right after seeing <code class="language-plaintext highlighter-rouge">deleted == true</code> we’d see it still exists. It’s not the code.
If we watch the SD card filesystem we’d indeed see <code class="language-plaintext highlighter-rouge">bar.txt</code> really is still there.</p>
<p>What happened? On Marshmallow <code class="language-plaintext highlighter-rouge">DocumentFile.delete()</code> is asynchronous. It returns success (<code class="language-plaintext highlighter-rouge">true</code>)
immediately but the file was only enqueued for deletion. <code class="language-plaintext highlighter-rouge">bar.txt</code> is truly gone only after about 10
seconds. That’s when the parent folder contains nothing else, only this one file. If there is a lot
of files there the delay can be much longer. This behavior is clearly a breakage of the official
<code class="language-plaintext highlighter-rouge">DocumentFile.delete()</code> contract.</p>
<p>I have a workaround for
<a href="https://play.google.com/store/apps/details?id=com.ttxapps.dropsync">Dropsync</a>,
<a href="https://play.google.com/store/apps/details?id=com.ttxapps.onesyncv2">OneSync</a>,
<a href="https://play.google.com/store/apps/details?id=com.ttxapps.drivesync">Autosync for Google Drive</a>, and
<a href="https://play.google.com/store/apps/details?id=com.ttxapps.boxsync">Autosync for Box</a>. The beta versions
are available in Play Store <a href="/docs/beta-testing/">beta channel</a> if you can’t wait. The workaround should
work quite well, but I want to work on it some more to minimize the negative impact on sync speed.</p>
<p>Besides this issue Marshmallow also breaks local file change monitoring. Instant upload feature uses
<code class="language-plaintext highlighter-rouge">FileObserver</code> API class to monitor changes in selected folders. The system notifies registered apps
when files are modified, deleted or added. This does not work anymore on Marshmallow. Apps don’t receive
any notifications. Not for changes in folders on SD card, not even for changes in folders in device internal
storage. There is <a href="https://code.google.com/p/android-developer-preview/issues/detail?id=3099">a bug report</a>
filed against Android 6.0 preview. It was closed when 6.0 final was released but obviously without the bug
being fixed. Until it’s fixed, Instant Upload in my sync apps does not work and unfortunately it seems
there is nothing I can do about it. This is a system level bug which apps cannot workaround.</p>
https://metactrl.com/blog/2015/08/03/extremely-slow-sd-card-access-on-lollipop/
Extremely Slow SD Card Access on Android 5 (Lollipop)
2015-08-03T00:00:00+02:00
2015-08-03T00:00:00+02:00
MetaCtrl
https://metactrl.com/
<p>In Android 4.4 (KitKat) they decided to restrict apps from writing into arbitrary folders on the external SD card. This
decision causes a lot of pain for users who updated their expensive smartphones to the new firmware only to find out the
SD card, possibly the main reason why they chose this device model and not some others, becomes practically useless.
Understandably many users are quick to blame the lazy app developers who don’t bother to update their apps for the new
OS version. I myself spent countless hours replying to angry user emails. Adding a message into the app itself to warn
users about this problem and link to a <a href="/docs/sdcard-on-kitkat/">detailed document</a> explaining what
happened is not enough to calm them down. Frankly I am not surprised. When was the last time you did system update after
being asked by the device manufacturer and ended up losing an important feature that worked perfectly well when you
bought the device merely two months earlier?</p>
<p>Android 5 (Lollipop) adds <a href="http://developer.android.com/about/versions/android-5.0.html#Storage">a new API</a>
for apps to write to the SD card. It’s unbelievably complicated API to achieve something developers could do pre-KitKat:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">OutputStream</span> <span class="n">os</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">BuferredOutputStream</span><span class="o">(</span><span class="k">new</span> <span class="nc">FileOutputStream</span><span class="o">(</span><span class="s">"/storage/extSdCard/foo/bar/baz.txt"</span><span class="o">);</span>
<span class="n">os</span><span class="o">.</span><span class="na">write</span><span class="o">(....);</span>
<span class="n">os</span><span class="o">.</span><span class="na">close</span><span class="o">();</span>
</code></pre></div></div>
<p>The implementation on some popular devices is <a href="/docs/sdcard-on-lollipop/">buggy</a>. The I/O sematics is much poorer than
what normal random access file can do. No <em>seek</em>, no <em>append</em>. But at least something.</p>
<p>To write to the folder subtree app presents a system chooser dialog for the user to select the folder
(e.g. <code class="language-plaintext highlighter-rouge">/storage/extSdCard/foo</code>). The system returns <code class="language-plaintext highlighter-rouge">fooTreeUri</code>. This corresponds to folder <code class="language-plaintext highlighter-rouge">foo</code>. To get to <code class="language-plaintext highlighter-rouge">baz.txt</code>
app needs to traverse down, at each level asking for the correspoinding URI. There is a helper class <code class="language-plaintext highlighter-rouge">DocumentFile</code>
in android support v4 library to make things a bit simpler and to ease transition from older Android versions:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">DocumentFile</span> <span class="n">fooDir</span> <span class="o">=</span> <span class="nc">DocumentFile</span><span class="o">.</span><span class="na">fromTreeUri</span><span class="o">(</span><span class="n">context</span><span class="o">,</span> <span class="n">fooTreeUri</span><span class="o">);</span>
<span class="nc">DocumentFile</span> <span class="n">barDir</span> <span class="o">=</span> <span class="n">fooDir</span><span class="o">.</span><span class="na">findFile</span><span class="o">(</span><span class="s">"bar"</span><span class="o">);</span>
<span class="nc">DocumentFile</span> <span class="n">bazFile</span> <span class="o">=</span> <span class="n">barDir</span><span class="o">.</span><span class="na">findFile</span><span class="o">(</span><span class="s">"baz.txt"</span><span class="o">);</span>
<span class="nc">OutputStream</span> <span class="n">os</span> <span class="o">=</span> <span class="n">context</span><span class="o">.</span><span class="na">getContentResolver</span><span class="o">().</span><span class="na">openOutputStream</span><span class="o">(</span><span class="n">bazFile</span><span class="o">.</span><span class="na">getUri</span><span class="o">());</span>
<span class="n">os</span><span class="o">.</span><span class="na">write</span><span class="o">(...);</span>
<span class="n">os</span><span class="o">.</span><span class="na">close</span><span class="o">();</span>
</code></pre></div></div>
<p>The catch? <code class="language-plaintext highlighter-rouge">DocumentFile.findFile()</code> is slow. It loads the list of all entries in folder <code class="language-plaintext highlighter-rouge">foo</code> into RAM, then iterates
through the list to find the entry with a matching <code class="language-plaintext highlighter-rouge">displayName</code>. (Bonus point: it’s <em>case-sensitive</em> matching, <code class="language-plaintext highlighter-rouge">equals</code>
not <code class="language-plaintext highlighter-rouge">equalsIgnoreCase</code> even though everywhere else filenames in Android are case-insensitive. Fun, isn’t it?)</p>
<p>If folder <code class="language-plaintext highlighter-rouge">foo</code> contains media files, say JPEG photos, <code class="language-plaintext highlighter-rouge">findFile</code> becomes <strong>extremely extremely</strong> slow. It delegates to
<code class="language-plaintext highlighter-rouge">DocumentContracts.buildChildDocumentsUri</code> which in turn queries the concrete document provider. It seems this provider
brings up the whole media framework machinery, re-scans and re-indexes all those photos. On my LG G3 with a good SD card
a single <code class="language-plaintext highlighter-rouge">findFile</code> call takes close to 10 seconds if folder <code class="language-plaintext highlighter-rouge">foo</code> contains 500 photos. It’s 30 seconds for a folder
with 1000 photos. It’s almost as slow as listing files from a cassette tape on Commodore in the eighties.</p>
<p>I poked around to see if it’s possible to let go <code class="language-plaintext highlighter-rouge">DocumentFile</code> and use <code class="language-plaintext highlighter-rouge">DocumentsContract</code> directly in a more efficient
way. Nope. Nothing there.</p>
<p>I made a fix for this problem in the <a href="/blog/2015/07/23/introducing-onesync-v2/">new OneSync v2</a> app
(<a href="https://play.google.com/store/apps/details?id=com.ttxapps.onesyncv2">Google Play link</a>).
The new version 2.0.5 will be live on Google Play in a few hours. If you use OneSync to sync a folder on SD card in your
Android 5.0 device with Microsoft OneDrive, you should update right away. Depending on how many files are in that folder
the speedup can easily be several orders of magnitude faster (50x-100x faster). In other words it was <em>that</em> slow. The fix
is: <strong>avoid the new Lollipop API for SD card unless you ABSOLUTELY have no other choice</strong>.</p>
<p>I’ll update
<a href="https://play.google.com/store/apps/details?id=com.ttxapps.dropsync">Dropsync</a>,
<a href="https://play.google.com/store/apps/details?id=com.ttxapps.drivesync">Autosync for Google Drive</a>, and
<a href="https://play.google.com/store/apps/details?id=com.ttxapps.boxsync">Auto Box Sync</a>
to include this fix in the next few days.</p>
https://metactrl.com/blog/2015/07/29/import-settings-from-onesync-v1-to-v2/
How to Transfer Settings from OneSync v1 to OneSync v2
2015-07-29T00:00:00+02:00
2015-07-29T00:00:00+02:00
MetaCtrl
https://metactrl.com/
<p>Quick note for users who asked how to transfer settings from OneSync v1 to
<a href="https://play.google.com/store/apps/details?id=com.ttxapps.onesyncv2">the new (and better) OneSync v2 app</a>.</p>
<p>First please update both apps to their latest versions. There were some important fixes in both apps recently.</p>
<p>To transfer settings from v1 to v2 please follow these steps:</p>
<ol>
<li>
<p>Open OneSync v1 app. Go to the app settings and disable Autosync. This is because having both apps to sync the same
set of folders would be a very bad idea.</p>
</li>
<li>
<p>In v1 app go to Settings and choose Backup settings. It will save the settings in the file
<code class="language-plaintext highlighter-rouge">OneSync/backup/OneSyncSettings.bkp</code> in the device internal storage</p>
</li>
<li>
<p>Open OneSync v2 app. Go to the app settings and choose Restore settings. This action restores settings from
the file mentioned above. The app will restart after settings import.</p>
</li>
<li>
<p>In v2 app go to the app settings and review the imported settings. Specifically you may want to increase
the Max upload file size limit. In v1 the max allowed value is 100 mb. In v2 you can increase it up to
“unlimited”. After some testing with manual sync you probably also want to turn on Autosync in the v2 app.</p>
</li>
</ol>
<p>It’s too late for OneSync v1/v2 but next time if I do something like this again, I will make the process more automatic.</p>
https://metactrl.com/blog/2015/07/23/introducing-onesync-v2/
Introducing OneSync v2
2015-07-23T00:00:00+02:00
2015-07-23T00:00:00+02:00
MetaCtrl
https://metactrl.com/
<p><em>(UPDATE: If you migrate from OneSync v1 to OneSync v2, you probably want to read
<a href="/blog/2015/07/29/import-settings-from-onesync-v1-to-v2/">How to Transfer Settings from OneSync v1 to OneSync v2</a>)</em></p>
<p>Today I released a new Android app: <a href="https://play.google.com/store/apps/details?id=com.ttxapps.onesyncv2">OneSync v2</a>.</p>
<p>On the surface OneSynce v2 is very similar to an existing
<a href="https://play.google.com/store/apps/details?id=com.ttxapps.onesync">OneSync v1 app</a>
but underneath it has a completely new sync engine. The new engine uses the new OneDrive API from Microsoft and is better
than the one in v1 app in every regard. All existing users of OneSync v1 app are highly recommended to migrate to
OneSync v2. I don’t plan to pull OneSync v1 from Google Play any time soon but new feature development will happen only
in OneSync v2. OneSync v1 uses the old OneDrive API that has many limitations and bugs. Microsoft is keeping this old API
running but eventually they will retire it.</p>
<h4 id="what-onesync-v2-does-better">What OneSync v2 Does Better</h4>
<p>Here the list of things what v2 app is much better at than v1 app</p>
<ul>
<li>It can upload files larger than 100 MB (for example video or backup files)</li>
<li>Resumable upload. Large upload takes time. If it’s interrupted because (for example) the Internet connection breaks
the app remembers the position in the file where upload was stopped. At the next attempt upload continues from
this position, not from the very beginning of the file. If the app restarts upload from scratch, it may fail again,
restart again,… and no progress is being made. Resumable upload may take several attempts to finish but bytes already
uploaded in each failed attempt are not thrown away. The 100 MB max upload limit was imposed by the old OneDrive API, but
even if there was no such limit, without resumable upload it would be very difficult to upload large files anyway.</li>
<li>Resumable download. Similar to resumable upload but in the other direction.</li>
<li>No more mysterious sync failures happening to some specific files. The old OneDrive API used in OneSync v1 has
a nasty bug: it reports wrong sizes for some files on its side. As you can imagine knowing the correct file size
is really important for a sync app. OneSync v1 uses heuristics to workaround this server side bug. But the workaround
does not always work and is not without negative issues. Although I still see wrong file sizes reported by the new OneDrive
API, OneSync v2 does not solely rely on file sizes. It also uses SHA-1 hashes to determine if what’s on the server is the
same as what in the device.</li>
<li>Accurately resolve sync conflicts. OneSync is conservative by design. It tries hard to avoid data loss. If there is any
chance that a file may have been modified on both sides, the app declares that there is a sync conflict and retains both
versions. OneSync v1 often creates false conflict copies because of the wrong-file-size bug on the server side.
OneSync v2 compares SHA-1 hashes of the server copy and the local copy of the file. The probability of false sync conflict
is now very small.</li>
</ul>
<h4 id="onesync-v2-future-support-for-onedrive-for-business-office365-accounts">OneSync v2 Future: Support for OneDrive for Business (Office365 Accounts)</h4>
<p>OneSync v1 does not support OneDrive for Business/Office365. Neither does OneSync v2 in the current version. Despite the
similarity in names OneDrive for Business is a different product with vastly different API not suitable for file sync.
The good news is Microsoft is putting a single API, the new API used by OneSync v2, in front of both OneDrive Personal
and OneDrive for Business/Office365. The API for OneDrive for Business is not ready for production use yet but will be
in the future. When it happens I will add support for OneDrive for Business to OneSync v2.</p>
<h4 id="special-discount-for-existing-onesync-v1-pro-users">Special Discount for Existing OneSync v1 Pro Users</h4>
<p>Existing OneSync v1 Pro users get substantial discount, about 70% off the regular price of OneSync v2 Pro upgrade. To get
the discount you need to</p>
<ul>
<li>Keep OneSync v1 installed and updated to its latest version from Google Play. Make sure Pro upgrade is active there.</li>
<li>Install OneSync v2. Go to menu Upgrade. The v2 app will ask the v1 app if you’re v1 pro user and if you are discount
will be offered.</li>
</ul>
<h4 id="running-onesync-v1-and-onesync-v2-side-by-side">Running OneSync v1 and OneSync v2 Side by Side</h4>
<p>This would be fine but you should not configure them to sync the same folders in your device with the same OneDrive account.
Imagine one pair of folders in both apps but with different sync methods, for example Upload only in one app and Download
mirror in the other app. What happens with such config is underterministic and surely will make a mess of your data. At the
very least you should disable autosync in v1 app, test v2 app and switch over when you feel confident it works well for you.</p>
https://metactrl.com/blog/2015/07/22/drivesync-and-md5-checksum/
MD5 Checksum in Autosync for Google Drive
2015-07-22T00:00:00+02:00
2015-07-22T00:00:00+02:00
MetaCtrl
https://metactrl.com/
<p>File sync is quite simple. At least at the beginning. You set up the sync app to sync a folder D(evice) in your device
with a folder C(loud) in the cloud storage. When a new file F(ile) appears in folder D, the app uploads it to the cloud
into folder C. At this moment we have the same file F on both sides.</p>
<p>Things get complicated fast when the file F changes. Perhaps it’s a photo you took with your phone. It’s been synced.
Now you use an app on your phone to crop the photo a little bit and save it back under the same name. The sync app
must be able to find out</p>
<ol>
<li>File F has been synced before, it was the same in folder D and folder C</li>
<li>File F has changed in folder D</li>
<li>File F has <strong>not</strong> changed in folder C</li>
</ol>
<p>then makes the right decision: upload the newly modified file F from folder D to folder C.</p>
<p>What would happen if</p>
<ol>
<li>File F is to be synced to both your phone and tablet. You paired folder C in the cloud storage with folder D
in your phone and folder T in your tablet.</li>
<li>We start with the good state: the same file F is synced to both devices and the cloud storage. We have three
copies of the same thing.</li>
<li>You’re at the place where Internet is not available. Both your phone and tablet are offline.</li>
<li>You edit file F on both your phone and tablet.</li>
<li>Later you have Internet connection again. Both your phone and tablet start to sync with the cloud storage.</li>
</ol>
<p>We have a sync conflict. There are two new versions of the same file which was synced before.
<a href="https://play.google.com/store/apps/details?id=com.ttxapps.drivesync">Autosync for Google Drive</a>
cannot decide by itself which version you want to keep. It resolves the conflict by creating a new file
<em>“F (conflict 2015-07-22-10-15-23)”</em> which is one version of the original file F. The second version gets
the original name F. The app syncs both files to all places. Later on you, the user, must decide which one to keep.</p>
<p>This is one example why it’s very important to detect if a file has changed or not. Failing to do so <strong>will</strong> cause data
loss. Sync apps base their decisions on various file attributes: the name of the file and its location, the size, the last
modified timestamp. Unfortunately both the sizes and last modified timestamp may be inaccurate. The ultimate check is to
compare the real contents of both versions of the file. However to do so we have to download one version from the cloud
storage into the device before we can compare it with the version we already have in the device. One photo may not be such
a big deal but there can be many photos or it’s not a photo but a real big video file which can takes many minutes to
download. The huge cost makes comparing file contents unusable.</p>
<p>Luckily there is something called “checksum” or “hash”. It’s a fingerprint of the file content. We can
compute this small fingerprint, exchange its values between the cloud and the device and compare the fingerprints instead
of the actual file contents. If they are the same then we know the file contents are the same.</p>
<p>There are many algorithms to calculate such a fingerprint, but the common ones are MD5 and SHA-1. Google Drive supports MD5.
After recent discoveries MD5 is not safe for cryptographic purposes but it’s more than good enough for our sync conflict
detection.</p>
<p><a href="https://play.google.com/store/apps/details?id=com.ttxapps.drivesync">Autosync for Google Drive</a>
is conservative by design. It’d rather err on the safe side, i.e. better to delare there is a conflict than to silently
lose user modification of a file. The downside is sometimes we have false conflicts. With the use of MD5 checksums to
determine sync conflicts the probability of false conflicts is now down to zero.</p>
<p>This change appeared in Autosync for Google Drive version 1.7.2 which was
<a href="https://play.google.com/store/apps/details?id=com.ttxapps.drivesync">released on Google Play</a>
earlier today.</p>
https://metactrl.com/blog/2015/07/09/gdrive-same-path/
Google Drive: Multiple Files with the Same Path
2015-07-09T00:00:00+02:00
2015-07-09T00:00:00+02:00
MetaCtrl
https://metactrl.com/
<p><em>(EDIT: I’ve turned this post into an <a href="/faq/">FAQ</a> entry)</em></p>
<p>In <a href="https://play.google.com/store/apps/details?id=com.ttxapps.drivesync">Autosync for Google Drive</a> some users occasionally
may run into an error <em>“Cannot upload - multiple files with the same path:…“</em>. It can also be <em>“Cannot delete”</em> or
<em>“Cannot download…“</em> as shown in this screenshot</p>
<p><img src="/assets/docs/gdrive-same-path/gdrive-same-path-sync-error.png" alt="screenshot" /></p>
<p>What’s happening here?</p>
<p>It turned out that in Google Drive you can easily have multiple files with the exact same name in the same folder. It’s
rather easy to create such a situation. For example, you can use the Google Drive official app on Android to upload a
file, say ParisVisit.txt where you keep your notes about your stay in Paris. Some time later you edit the file, add more
notes, and upload the newly updated file to the same folder. Instead of overwriting the same file which already exists
there (perhaps after asking the user to confirm first), Google Drive merrily let you create another file with exact same
name but with different content. In the Google Drive app you would see this</p>
<p><img src="/assets/docs/gdrive-same-path/gdrive-same-path-drive-app.png" alt="screenshot" /></p>
<p>If you open your laptop, go to Google Drive website, you’d see a similar picture</p>
<p><img src="/assets/docs/gdrive-same-path/gdrive-same-path-browser.png" alt="screenshot" /></p>
<p>There is absolutely no way to know which file is which without opening all those files, one by one, and examining their
contents. And immediately forget which is which the moment we close the files! We all probably agree this is rather
suboptimal user experience, to say the least.</p>
<p>This situation happens when the user uploads the same file several times, accepts the default and doesn’t know the
implication (certainly this is not the user’s fault). It’s also possible that some apps (including Autosync for Google
Drive but unlikely) forget to check if a filename is already in use and insert a new file under the same name.</p>
<p>When <a href="https://play.google.com/store/apps/details?id=com.ttxapps.drivesync">Autosync for Google Drive</a> detects this situation
it refuses to touch the file in Google Drive. Simply because it does not know which one is the right one. If you see the
error message <em>“Cannot … - multiple files with the same path:…“</em> you must go to Google Drive yourself, examine which
files you want to keep, delete the others, or rename them so that each file has a unique name.</p>
<p>Depending on how many such files do you have this can be a tedious process. Autosync for Google Drive does handle one
subcase automatically. If there are multiple files in Google Drive folder with the same name <em>and</em> same content, it keep
one copy and delete all the others. I can’t imagine what multiple copies of the same thing under the same name is good
for. If you know one, please let me know. I’ll revert that feature.</p>
<p>I may also try to be clever and auto-rename those files when download them to the folder in the device. The first
“ParisVisit.txt” gets to keep its name but the second one would become “ParisVisit (1).txt”, the third would be
“ParisVisit (2).txt”, etc… This is what the Google Drive sync client on desktop does</p>
<p><img src="/assets/docs/gdrive-same-path/gdrive-same-path-finder.png" alt="screenshot" /></p>
<p>I chose not to auto-rename, at least not yet, because I found ways to get Google Drive sync client on desktop into
data-loss situation. It tries to be clever but in reality is not clever enough. It’s better to stay simplictic but safe than
being clever but dangerous.</p>
<p>(PS I don’t know how Google engineers reasoned when they decided to implement it that way. I have several hypotheses but
I save them for an evening in the pub where we programmers tell each other war stories)</p>
https://metactrl.com/blog/2015/07/03/drivesync-supports-resumable-file-transfer/
Autosync for Google Drive Now Supports Resumable Upload/Download
2015-07-03T00:00:00+02:00
2015-07-03T00:00:00+02:00
MetaCtrl
https://metactrl.com/
<p>Resumable file transfer was added to <a href="https://play.google.com/store/apps/details?id=com.ttxapps.drivesync">Autosync for Google Drive</a>
(aka Drive Autosync or DriveSync). It’s in version 1.7.0 which is being rolled out on Google Play and should show up on
user devices within a day or two.</p>
<p>When a file transfer is interrupted, Autosync for Google Drive will try again later, either automatically
or as part of a manual sync invoked by the user. Before version 1.7.0 a new attempt restarted from the beginning
of the file. It discarded all the bits which had been uploaded or downloaded in the previous failed attempt. It did
so even in cases where a previous transfer had almost finished.</p>
<p>With resumable transfer Autosync for Google Drive remembers the position in the file where transfer was stopped. In the
next attempt it resumes the transfer from that postion. A large download / upload may takes several attempts to complete
but the app does not transfer any portions of the file more than once.</p>
<p>This feature is important for big files. Internet connection on mobile devices is not robust. Users walk around
with their phones in their pockets. The connection between the phone and the Internet is often dropped
and re-established. Big file transfer takes long time. If the app restarts from zero after each failed attempt, it
would need to transfer more data than the size of the file. More data means longer transfer. Longer transfer means
more chances for the connection to be dropped. Very large files (for example videos) may take days before they are
completely transferred, if at all. The whole attempt / fail / attempt again / fail again / … endless cycle also
keeps the phone awake and burns all the battery.</p>
<p>Resumable file transfer changes all this. Large transfer still takes time, but not more time than it’s absolutely
necessary and more importantly even the large files will eventually be uploaded or downloaded. This feature dramatically
increases sync reliability even when sync happens over flaky mobile Internet.</p>
<p>(P.S. Dropsync has been supporting resumable transfer for a long time. I am working to add it to OneSync.)</p>
https://metactrl.com/blog/2015/03/24/dropsync-not-in-amazon-appstore/
Attention: Dropsync is NOT in Amazon Appstore
2015-03-24T00:00:00+01:00
2015-03-24T00:00:00+01:00
MetaCtrl
https://metactrl.com/
<p>A user notified me about an Android app in Amazon appstore. It’s named “Sync Client for dropbox” by “Am Tech”.
The name is different but the app logo, the screenshots, the app description, even the version numbers are
from my Dropsync app. I have reported the case to Amazon Appstore via their contact form and requested them
to take action. But by then, please be aware and tell people around you, especially those who own Amazon
phones and tablets, that the one and only place to get Dropsync is Google Play</p>
<p><a href="https://play.google.com/store/apps/details?id=com.ttxapps.dropsync">https://play.google.com/store/apps/details?id=com.ttxapps.dropsync</a></p>
<p>There are quite many illegal cracked copies of Dropsync on the net. But seeing one in Amazon Appstore is indeed
something new to me.</p>
<p><img src="/assets/blog/2015-03-24-warez-in-amazon-appstore.png" alt="screenshot" /></p>
https://metactrl.com/blog/2014/08/10/avoid-app-package-cache-dir/
Avoid /Android/data/ (app_package) /cache
2014-08-10T00:00:00+02:00
2014-08-10T00:00:00+02:00
MetaCtrl
https://metactrl.com/
<p>If your Android app needs to keep some file cache, it is recommended to store that cache in a known location. Since API
level 8 you should use
<a href="http://developer.android.com/reference/android/content/Context.html#getExternalCacheDir%28%29">Context.getExternalCacheDir()</a>.
Since API level 19 there is also
<a href="http://developer.android.com/reference/android/content/Context.html#getExternalCacheDirs%28%29">Context.getExternalCacheDirs()</a>
in case the device supports multiple external storages.</p>
<p>In any case you end up with this path:</p>
<p><code class="language-plaintext highlighter-rouge">/storage/emulated/0/Android/data/com.example.app.package/cache</code></p>
<p>When the user uninstalls your app, the whole directory <code class="language-plaintext highlighter-rouge">/storage/emulated/0/Android/data/com.example.app.package</code> is
gone. That’s correct and desired, especially for cache files. This <code class="language-plaintext highlighter-rouge">/cache</code> subdirectory has an additional behaviour. The
system knows it’s cache and can purge it in low free storage situation which is not so uncommon on devices with only 16 GB
storage and no SD card slot. The user can also manually force clear the cache, either for one individual app or globally for
the whole device.</p>
<p><img src="/assets/blog/2014-08-10-OneSync-AppInfo.png" alt="screenshot" />
<img src="/assets/blog/2014-08-10-Android-Storage-Cache.png" alt="screenshot" /></p>
<p>This is when the troubles begin.</p>
<p>When clearing the cache, Android does not kill the running app process and restart it afterward. The process holds on a file
inside the cache directory. After <em>Clear Cache</em>, the cache directory is a zombie. It’s still there because the process was
holding on a file handle, but it’s not there because the user did <em>Clear Cache</em>. The <code class="language-plaintext highlighter-rouge">/cache</code> entry still there, but it’s
not a file, nor a directory. It’s not writeable, nor deleteable. Nothing. It’s a zombie, waiting to be buried. The burial
happens when the app process stops holding on the cache file handle, e.g. when it quits.</p>
<p>This is deadly for apps with long running background services. That’s all my sync apps. For the users the only practical way
to recover is to reboot their devices. That’s not really practical. Some users like to use apps which supposedly keep
Android devices fast by purging all the cache, for example shortly after boot time, but still many milliseconds after my
sync apps have been started and now running and monitoring file system for changes.</p>
<p>The workaround?</p>
<p>Don’t use <code class="language-plaintext highlighter-rouge">/cache</code>. My apps now use <code class="language-plaintext highlighter-rouge">/tmp</code> instead. For Android system anything other than <code class="language-plaintext highlighter-rouge">/cache</code> is not a cache and
therefore is not deleted on <em>Clear Cache</em>. <code class="language-plaintext highlighter-rouge">/tmp</code> would never be deleted even at low storage situation. Luckily in my case
the cache size is quite small, usually a few MBs, it rarely crosses 10MB mark.</p>
<p>I want my apps to be good Android citizens. But their users certainly don’t appreciate them as good dead citizens. They want
them to be alive and working.</p>
https://metactrl.com/blog/2014/08/07/non-us-indie-devs/
Can a (Non-US) Indie Dev Make a Living on the App Store?
2014-08-07T12:05:00+02:00
2014-08-07T12:05:00+02:00
MetaCtrl
https://metactrl.com/
<p>Brent Simmons noticed <a href="http://inessential.com/2014/07/25/who_at_the_table_is_an_indie_ios_develop">many people in his circle stopped being full-time indie iOS developers</a>. His blog post generated
tons of discussion on the Internet. He does a good job of tracking it on <a href="http://inessential.com/">his blog</a>. If you’re an indie mobile app
developer or considering to enter the field, I highly recommend you to have a look. The debate exploded after Jared Sinclair
posted <a href="http://blog.jaredsinclair.com/post/93118460565/a-candid-look-at-unreads-first-year">disappointing financial numbers of his Unread app</a>. Jared’s been hard working, yet made only $21,000/year, or
$1,750/month take-home income from Unread. That’s after tax and health insurance.</p>
<p>It seems those indie devs who spoke up are all in the Apple ecosystem and are from the US. Since I don’t live there I am
curious how the numbers look like from global perspective. I went to the <a href="http://www.globalrichlist.com/">Global Rich List
website</a> and entered Jared’s number there:</p>
<div style="text-align:center;">
<img alt="screenshot" src="/assets/blog/2014-08-07-Global-Rich-List-1.png" />
</div>
<p>Here’s what I got</p>
<div style="text-align:center;">
<img alt="screenshot" src="/assets/blog/2014-08-07-Global-Rich-List-2.png" />
</div>
<p>Hmm, it doesn’t look bad at all. One can’t complain being in the top 3.2% richest people in the world.</p>
<p>I hear you say: “I am a skilled worker, my job is difficult, not everyone can write code. I deserve more.” Scrolling down
the global rich list result page a bit, I see this</p>
<div style="text-align:center;">
<img alt="screenshot" src="/assets/blog/2014-08-07-Global-Rich-List-3.png" />
</div>
<p>With all due respect to my fellow indie devs, I dare to say being a doctor, especially a doctor in a poor country, is much
more difficult job than what most of us, including Jared and myself, are doing. Doctors need years of formal education. They
are often held responsible for someone else’s death and life. Right now there are many people in our community who believe
that you don’t need to be good at math to be a good programmer. Not being good at math is unheard of in any other
engineering professions, yet we seem to get away pretty well with the lack of math skill. Our job can’t be that hard after
all.</p>
<p>I spent my childhood in Ha Noi, Viet Nam. I’ve been living in Prague, Czech Repbulic for most of my adulthood. I am working
remotely for a small Seattle startup for the last 3 years and made perhaps six, seven trips there. It’s indeed difficult to
get by with $21K a year in Seattle. In Prague it’s not great but okayish. In Ha Noi it is the level of income most people
including well educated ones can only dream of.</p>
<p>To the developers from the poor countries I would say the app store is a unique opportunity. You can dramatically improve
your financial situation with very little risk and financial investment. A laptop, a smartphone and Internet connection. I
bet you already have all three. You don’t have to move anywhere. Just cut down a bit the amount of time you spend on
Facebook. It’s true the guys over there have better education and skills. On average. At individual level it doesn’t have to
be true. You have to be hard working to compensate for some lack of skills, but that’s OK. We, the poor, are used to
hardship. That’s an important competitive advantage, a fair one because you have paid dearly for it. And don’t worry, most
of them can’t write code without Google and Stack Overflow anyway. Don’t be shy.</p>
<p>To my American developer friends: you’re probably right. The gold rush is over. One used to be able to make money by
publishing farting apps on the app store. Not so any longer. It’s possbile that the money you can make as an app store indie
dev is not compatible with living in expensive metro areas in the US. But this is not new. To live on Manhattan I guess one
needs to be an investment banker or something similar. Cheap manufacturing jobs have been moved to China. The demise of the
American programmer has been argued fiercely about for a decade. I don’t know. It seems exaggerated to me. One thing
though. At first one didn’t want to do cheap manufacturing job, then suddenly it’s not possible to manufacture iPhone in the
US even if you wanted to. The capability is gone. One can still work as staffers at shiny Apple store. But personally I
wouldn’t be overjoyed if my children earn their living as shop assistants. Even if they were officially called Geniuses. (No
insult to Apple store assistants. I appreciate all kinds of hard work. I merely want to say your job is not my dream job.)</p>
<p><em>(For completeness, I am doing well with my apps in Google Play. The numbers are somewhere in I-can’t-complain zone, much
better than what Jared published.)</em></p>
https://metactrl.com/blog/2014/08/06/dropsync-3-years/
Dropsync: Three Years in Google Play
2014-08-06T00:00:00+02:00
2014-08-06T00:00:00+02:00
MetaCtrl
https://metactrl.com/
<p>Somehow I didn’t notice a couple of weeks ago Dropsync passed 3 years in Google Play. Three years! Almost a million
downloads. Not something one would brag about. About 50% active user install rate. This number is unusually high for mobile
apps and what I am quite proud of. Dropsync addresses a very small niche but it seems to do so pretty well. From user emails
I learn that many have been using the app for years. It sits in the background and dutifully does its job. No fuss. Users
even forgot it’s there and only email me when there was a sync issue. We tend to take good things in life as granted and
only appreciate them when they were lost (health, friends, youth, good eye vision, etc)</p>
<p><strong>I am running special discount for Dropsync Pro users. If you bought the <a href="https://play.google.com/store/apps/details?id=com.ttxapps.dropsync.pro&referrer=utm_source%3DMetaCtrlCom%26utm_medium%3Dreferral%26utm_campaign%3Ddropsync3yr">Dropsync Pro Key</a> in the past, you
get 50% discount when upgrading to pro versions of my other sync apps: <a href="https://play.google.com/store/apps/details?id=com.ttxapps.drivesync&referrer=utm_source%3DMetaCtrlCom%26utm_medium%3Dreferral%26utm_campaign%3Ddropsync3yr">Drive Autosync</a>, <a href="https://play.google.com/store/apps/details?id=com.ttxapps.onesync&referrer=utm_source%3DMetaCtrlCom%26utm_medium%3Dreferral%26utm_campaign%3Ddropsync3yr">OneSync</a>,
<a href="https://play.google.com/store/apps/details?id=com.ttxapps.boxsync&referrer=utm_source%3DMetaCtrlCom%26utm_medium%3Dreferral%26utm_campaign%3Ddropsync3yr">Auto Box Sync</a>.</strong></p>
<p><strong>This discount will last until the end of Sunday, August 17, 2014, whatever your time zone is.</strong></p>
<p>You need to have your <a href="https://play.google.com/store/apps/details?id=com.ttxapps.dropsync.pro&referrer=utm_source%3DMetaCtrlCom%26utm_medium%3Dreferral%26utm_campaign%3Ddropsync3yr">Dropsync Pro Key</a> installed on your device. Then in the other apps, go to in-app
upgrade. If the Dropsync Pro Key is detected, you will be offered the 50% discount.</p>
<p>To those of you, longtime Dropsync Pro users, who already bought pro versions of the other apps at full price, I promise to
do something similar in the future in my other new apps.</p>
<p>Thank you all for your support.</p>
<p>Happy autosyncing.</p>
https://metactrl.com/blog/2014/08/05/why-new-website/
Why New Website
2014-08-05T12:05:00+02:00
2014-08-05T12:05:00+02:00
MetaCtrl
https://metactrl.com/
<p>My apps in Google Play always had a website. It’s even linked from app listings in Google Play. This is how it looked like
last week</p>
<p><img src="/assets/blog/ttxappscom-20140731.png" alt="screenshot" /></p>
<p>This “website” was created 3.5 years ago when I put my apps on Android Market and suddenly learned they asked for a website
URL. What I did was</p>
<ul>
<li>Registered a random domain name (ttxapps.com)</li>
<li>Looked around the Internet for 15 minutes to see what’s there. Then picked Tumblr. Configured it to host ttxapps.com via
CNAME. IIRC the main reason I chose Tumblr was its free plan offered CNAME hosting and didn’t show ads.</li>
<li>Copy/pasted the app description texts I wrote for Android Market</li>
<li>Done. Never touched it again. <img class="emoji" title="smile" alt="smile" src="https://github.global.ssl.fastly.net/images/icons/emoji/smile.png" height="20" width="20" align="absmiddle" /></li>
</ul>
<p>I wasn’t lazy. I simply rather spent more time on the apps than on their website. Since the release of <a href="https://play.google.com/store/apps/details?id=com.ttxapps.dropsync&referrer=utm_source%3DMetaCtrlCom%26utm_medium%3Dreferral%26utm_campaign%3DWhyNewWebsite">Dropsync</a>
more than three years ago there have been over 100 updates. That’s about 2-3 updates each month. About half of them happened
in the first year. To the point where some users got upset about the high update frequency. Some updates to fix bugs, many
to add features which I didn’t use myself but would make sense for certain groups of users.</p>
<p>The website was in bad state because I didn’t believe a mobile app needs an accompanying website, my single-purpose apps
definitely shouldn’t.</p>
<ol>
<li>
<p>Mobile apps ought be simple to use. When the last time did you read a user’s manual? Users’ attention span is about 30
seconds these days.</p>
</li>
<li>
<p>I didn’t buy the argument that apps need marketing website either. They say so that people can google for the app. Each
app already has its web presence: its store listing page. I’d rather direct web searchers to that store listing page
where they can install my app into their devices literally with two taps or mouse clicks.</p>
</li>
</ol>
<p>I still hold on my second point but have softened the first one: it’s actually useful to have, say, an online FAQ
somewhere. As much as I try each cloud storage service has its share of quirks. Android is also far from perfect. Besides
that now I have four <a href="https://play.google.com/store/search?q=pub:MetaCtrl">sync apps in Google Play</a>. One small website for
four apps seems to be acceptable investment.</p>
<p>It’s easy for users to send me emails from within my apps and I try my best to reply within reasonable time frame. But some
users wrote only to say “Sync doesn’t work, please fix it.” I spent countless hours going back and forth with many users to
figure out what they have in mind. At the minimum I can write an FAQ entry about how to write a good bug report. I intend to
change the apps to tell users to read the online FAQ first before emailing me with support questions. Perhaps they don’t
need to anymore since after reading the FAQ they already get the answer. Win-win. People are happy. Peace and prosperity
everywhere.</p>
<p>The FAQ is pretty bare at this moment but I’ll add more soon.</p>
<p>That’s the plan. Wish me luck.</p>