10

I have a photo-taking Android app (written in React Native, but I can add native modules if need be) that pairs with a gallery-type app on the user's computer (written in Electron with React). The number of photos can be large (we've had upwards of a thousand photos at a time), and they need to be transferred, uncompressed and uncropped, to the computer app. I need a reliable way to do this without routing the data through the Internet first.

Things I've tried

Node USB: Looks like a good library, but is unusable without installing a driver on the user's computer. The driver then appears to replace the default Windows USB driver, and the phone becomes inaccessible through normal means (opening a file explorer in Windows). Perhaps there's some way to switch drivers "on the fly", using the driver only while transferring photos, and then switching it back out for the system driver once we're done?

ADB: This is the original solution I tried, and it does exactly what I need it to, with two dealbreaking problems: for one, the phone needs to have Dev Mode enabled, and for two, ADB doesn't seem to recognize all devices (we've had a lot of trouble getting it to work with an LG V20, for example). The ideal answer to this question would be something like ADB without those two issues.

WiFi routing: we connect the phone to the same WiFi network as the host computer, use WebSockets to handshake IPs through the Internet, and then initiate a direct connection over the WiFi network. If I cannot find any other solutions, this will likely be the one I'll go for. The biggest problem with this option is the relatively large amount of manual setup required. Our users don't tend to be very technically savvy, and I don't know how reasonable it is to assume they will have WiFi in their home. At any rate, this cannot be the only option for transfer. Further, transferring gigabyte(s) of photos over the wireless network will cause a slowdown for everyone on the same network.

Tether routing: we tether the phone to the computer, and initiate a direct connection much in the same way as in the above step. The downsides to this method are that only phones with SIM cards can activate tethering (not all of our phones have SIM cards, as connectivity isn't their primary purpose for our needs), plus all of the other traffic on the computer will now be routed through the phone, which would be bad for customers' data caps who do have SIM cards. Additionally, there is no way to programmatically turn tethering on, there is only the ability to bring up the tethering menu; it's not too big a dealbreaker, but the other two very much are.

Bluetooth: Generally meets my requirements, but the data transfer rate is far too low, being an order of magnitude below WiFi.

WiFi Direct: I did not actually try this, because I could not find a working way to have the PC accept the WiFi Direct connection. It promises exceptional speeds, but there are no modules or libraries that I've found that would help me enable it.

SD Card: The lowest of the low tech methods, just save everything to the SD card and have the client take the card out and plug it into their computer. Would hands-down go with this, except for the need for a SD card port (guaranteed neither for the client's computer or their phone).

The obvious: manual drag and dropping required files from the phone to the PC. This is how we do things now, and it's fraught with problems. Text files have the last 15-20 characters cut off from them, for some reason, during transfer; many of the photos on the device do not initially show up due to the known issue with MTP not forcing a media rescan on the phone; and users sometimes drop files in the wrong places, leading to unnecessary support calls. This method surely needs to be replaced.

I've been searching for a solution for this problem for two months now, and it's hard to believe that nobody has had a use case for Android like this. It's been made clear that USB communication between Android and PC is non-trivial, I'm sure there are programs that do that, Windows to start off with. Yet try as I might, there are no solutions that work out of the box. Has anyone dealt with an issue like this before? What were your solutions? How would you approach this problem?

John Cummings
  • 1,949
  • 3
  • 22
  • 38
sg.cc
  • 1,726
  • 19
  • 41

2 Answers2

3

When downloading large files on Android it is recommended to use Download Manager, it supports a lot of native features like the progress bar, and notification, also the download task will be handled by OS, and more efficient.

React Native Fetch Blob library support this feature

Alex Lévy
  • 656
  • 1
  • 8
  • 15
  • My OP specifies that the photos must not be routed through the Internet first; this needs to be a local transfer. There can be up to a gigabyte of photos, this is a lot of data for customers with data caps. Is there a way to use React Native Fetch Blob locally? – sg.cc Jul 19 '18 at 16:42
0

You dont really need to route the data through the internet. You can just exchange meta data through the internet: Extend your desktop app with folder-import functionality (Plug your phone normally via USB, brose to the folder, import). When you execute this process, let it notify a webservice of some sort (push notifications? Im no phone-app dev.) with which files the desktop-app has imported from which device (ids, filenames, ...) and the phone gets this meta data and can continue its process of whatever it is doing!

Obviously the best solution is a communication channel over USB. Until you figure that one out, you could implement it temporarily this way!

Aphton
  • 91
  • 1
  • 3
  • I have a WebSockets server that I can use to exchange small pieces of info between devices, so I can share metadata. Suppose I do this. How do I navigate to the shared directory programmatically, without opening up an Explorer window (a solution with problems, as detailed in my OP)? There seems to be no way to do this. – sg.cc Jul 19 '18 at 15:09
  • What do you mean with how to navigate to the shared directory? I think you are making this more complicated than it is... Just use a file/folder selection dialog or implement a (windows-) event listener for device attachment and react appropriately! – Aphton Jul 19 '18 at 15:32
  • I just tried that: http://puu.sh/AZsrN/c74f67fe43.png Above is the folder selection dialog. Below is the Windows explorer window. You can see that the Folder Selection dialog actually does not have the phone in its listing, like the explorer does. Unfortunately, there is no way to implement your solution. – sg.cc Jul 19 '18 at 15:47
  • Trust me, I have looked for a very long time. If it was this easy, I would have already found that solution. The problem is that the phone isn't actually a mass USB storage device; the ability to browse a phone through your Explorer happens thanks to a bunch of code and drivers. The phone is never part of the filesystem, so there is no simple way to just access it as if it was. – sg.cc Jul 19 '18 at 16:37
  • 1
    Well even if it is not part of the filesystem, it interfaces via windows that make it hard to differentiate it from a USB storage device. In other words, Windows managed to pull it off. And Windows offers APIs for you to do the same, therefore I am certain it is posisble, just needs a bit more researching! I will look and see if I can find something! – Aphton Jul 19 '18 at 16:40
  • Indeed, the fact that it's possible on Windows gives me hope, and it's why I posted here. I will admit, though, this is very much a desperation move. I have tried a lot of different methods with no success, the ones I put in my OP are just the best leads I had. – sg.cc Jul 19 '18 at 16:41
  • 1
    Ok, check this out, perhaps it is of use to you: https://stackoverflow.com/questions/8072650/programmatically-access-files-on-android-device-from-pc Edit: It truly seems to be a big problem to do this simple thing. The thread in URL links to this library: https://forum.xda-developers.com/showthread.php?t=1512685 – Aphton Jul 19 '18 at 16:43
  • I also found that smartphones are registered as "portbale devices" and require to be queried by the WPD (windows portable device) API (see: https://learn.microsoft.com/en-us/windows/desktop/wpd_sdk/programming-reference) Here is the COM interface that can be used to query attached portable devices: https://learn.microsoft.com/en-us/windows/desktop/api/PortableDeviceApi/nn-portabledeviceapi-iportabledevicemanager Not sure if this is easily implemented Electron/React, I dont know that language. In C++ its just a short method! Edit: Sorry that I cant contribute more. Wish you luck! – Aphton Jul 19 '18 at 16:55