Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Accessing an android device from within VFP

Status
Not open for further replies.

Doug Lindauer

Programmer
Feb 2, 2017
34
US
I need to be able to automate grabbing a binary file from my Android device from within VFP. In this case the device happens to be a Spektrum iX14 r/c transmitter and the binary file I want to grab is a telemetry file.

I can connect my Android device via USB and it shows up in Windows file explorer. But there doesn't seem to be a way for VFP to see it and copy any files over. I also tried running an app called webdav on the device. It lets you map the device via IP to a windows drive letter. It works over wifi, not usb. But even then VFP couldn't see the drive letter. I could call up a command window and then do a dos file copy to wherever but that is really clunky.

So can anyone shed some light on how I might be able to do this?
 
First of all, if I connect my android phone via USB, the Windows Explorer shows it as a device, not as a drive. It gets neither a drive letter nor a server name, which could be addressed by a UNC path. It's not seen on the network and can't be assigned a drive letter or share, you can't even create a new folder or file.

I understand you said you can assign a drive letter after starting a webdav app on the phone. Well, which one? searching webdav I find tons of apps. I fear I cant help you when you're not more specific. And not about the devvice itself or its firmwarre version, this will not led to a device specific solution, there will be an android solution.

Without any app you have several options. Just go into your Android seettings and search for USB and pick "Use USB for...". One main option to set is whether your Android or the PC should control the USB connection (and what it's used for). It depends whether you connect to many PCs and usually don't want your phone to be controlled whether you allow this. But you can keep this to the safer setting that the phone is having the control about what's available.

Then there are several secondoary options. It might be your phone is configured to use the USB connection only to charge, i.e. no file transfer is selected. That would act as you described it Typical other options are file transfer, which should be sufficient (almost), USB tethering (using your phones data rate as internet access point for the PC/notbook), MIDI to act as midi device, PTP (picture transfer protocol, uninteresting for our case).

If you set it to file transfer you still don't get a drive letter, nor does the phone become a network device listed under the main network node of "This PC" in Windows Explorer.

I also have to look depper into this, because even just trying to allow the connected device (from within the Android USB settings that means the PC) to control the connection, that switches back to the android phone keeping the control.



Chriss
 
I can confirm everything that Chris said, especially the point about Windows recognising the device but not giving it a drive letter. If you were to enumerate the drives on the PC, perhaps using the API GetDriveType() function, the Android device is not one of them. This is true even if you go into USB Debugging Mode within Adroid.

However, given that you can perform the file transfer interactively within File Explorer, I wonder if you could automate the task by using AutoHotKey ( or something similar. In theory, it should be possible - certainly worth a closer look.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
I think once you're in file transfer mode you should be able to also identify is, though not as a drive. I remember someone showd how to list devices using Win API, but not sure whther that was already the end of it and not alloowing to access the internal phone memory as a drive as Windows Explorer manages. I think you need to be able to turn the control to the Windows PC to do more from its side, but as the android settings don't allow that, maybe you first need to change some securit setting, as that protects the phone from being controlled by any host it connects via USB.

It's clear that USDB isn't ethernet, so I think a WebDav app makes it a server that can be seen via Wifi, if the android phnone is connected to WiFi, which is normal to share your internet connection with the phone and not need a plan for a data rate. Even if ou have, using WiFi while home usually saves you a lot of transfer volume.

I think WebDav can solve, it, you just need to be more specific of which app you actually installed. The App Detective could help you to determine that.

Chriss
 
I think this has been made less easy than it used to be

I found this which might help


Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.

There is no place like G28 X0 Y0 Z0
 
The WebDAV Server app I found in the playstore is this one:
I had no idea that WebDAV was a protocol. I thought it was just some name they had made up.

Turning on wifi is not a problem on the iX14. Turning that and Bluetooth on was one of the first things I did. Since it's not a phone or a tablet, there's no issue about any service plan.

When I did run WebDAV Server on the device, I could map it to a drive letter on the PC like I mentioned and use DOS copy to copy the files I wanted. But VFP couldn't see the drive letter at all. I know next to nothing about OS level stuff so this is unknown territory for me.

Without the WebDAV Server app I can use the USB connection to copy files to and from the PC to the internal storage on the iX14 via Windows Explorer so the device allows that. The iX14 runs Android 11 and I'm using Windows 7 pro on the PC. I do have VFP 9 with the last service pack. I have beginner Android skills and wrote a small app using Android Studio which I uploaded to the iX14 but that doesn't get me very far.

The iX14 writes its telemetry log files (the things I need to grab) to the download folder in internal storage and there's no way to alter that, i.e. to write to a micro SD card. The only thing I can alter is the file name. The telemetry files are binary and that will be my next challenge. I've never tried to open a binary file from VFP and it's been a loooooong time since I took a C++ course.

Mike, as you suggested, I'll look at AutoHotKey. If Explorer can see and copy files to and from the USB device there has to be a way for other software to do it too. What I was wanting to do was have my VFP program be able to look and see if the device was connected and if so to grab any new files and then process them. But it's kind of looking like that level of automation can't happen at least not at the moment.

Griff, I read through the stackoverflow link. It was pretty old and I think newer versions of Android have actually made it harder. Someone on there actually posted a link to the WebDAV server that I have already tried and as I mentioned it let dos see the drive letter but VFP couldn't.
 
Could the VFP inability be either an elevation thing or perhaps the drive type is confusing VFP?

I would try doing an OS level subst to get the drive a letter SUBST M: .

Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.

There is no place like G28 X0 Y0 Z0
 
>If you were to enumerate the drives on the PC
>and copy any files over

You can use the Shell to do this. Just a reminder, I'm not a Foxpro programmer, so this is how I'd do it in VB, but I am sure it is fairly easily translatable

Something like the following:

Code:
[COLOR=blue][COLOR=green]' Requires a reference to Microsoft Shell Controls and Automation[/color]

Private Sub Example()
    [COLOR=green]' Part 1: example enumerating devices under This PC[/color]
    Dim ThisPC As Variant ' NOT string
    Dim objShellAPP As Shell32.Shell
    Dim objFolder As Folder2
    Dim objItem As FolderItem

    Set objShellAPP = New Shell32.Shell
    Dim myAndroid As String
    Dim AndroidFolder As String
    Dim myAndroidNameSpace As String
    
    myAndroid = "YourAndroidDeviceName" [COLOR=green]' Android device name, should be able to get this from Explorer[/color]
    ThisPC = "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" [COLOR=green]' MyComputerFolder (This PC) shell special folder[/color]
    Set objFolder = objShellAPP.Namespace(ThisPC)
    [COLOR=green]' Iterate items under This PC[/color]
    For Each objItem In objFolder.Items()
         [COLOR=green]' Debug.Print objItem.Name, objItem.Path[/color]
         If objItem.Name = myAndroid Then myAndroidNameSpace = objItem.Path [COLOR=green]' Capture the one we are interested in[/color]
    Next
    
    [COLOR=green]' Part2: use the device we have identified[/color]
    AndroidFolder = "\internal storage\documents" [COLOR=green]' example folder. This is one that exists on my Android phone[/color]
    Set objFolder = objShellAPP.Namespace(myAndroidNameSpace & AndroidFolder)
    [COLOR=green]' Just to show one way of listing the folder contents[/color]
    [COLOR=green]'For Each objItem In objFolder.Items()
    '     Debug.Print objItem.Name, objItem.Type
    'Next[/color]
    
    [COLOR=green]' Ok, now let's demonstrate copying for source folder on Android to a folder on drive D[/color]
    Dim target As Folder2
    Set target = objShellAPP.Namespace("d:\downloads\deleteme")
    target.CopyHere objFolder.Items.Item(0) ' copies first item in the source folder to our target
 
End Sub[/color]

 
I used subst and gave the z drive the letter a. Z is the drive letter I used when I ran WebDAV Server.
subst a: z:
When I called up a dos window I could see both z and a and copy from them. But VFP still couldn't see them. I did "run cmd" in VFP and a dos window came up just like as if I had opened it from Windows but in this instance of the shell it can't see the drives. I switch back to the other instance, the one I opened from windows, and it DOES see the drive.

I then created a batch file to copy from a: and ran the batch file with the run command within VFP. Same thing, it couldn't see the drive. I ran the batch file from the VFP created shell with the same result but from the Windows created shell it could run (of course.) So it seems like any dos command I initiate within VFP creates an environment which can't see the WebDAV drive. I'm flummoxed.

 
@Doug

I think this is an elevations thing then VFP must be running as Administrator or something, I know on my own machine
I have that set, and it can't 'see' my network drives even when other programs can

Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.

There is no place like G28 X0 Y0 Z0
 
You should try some other app, this is old.

And then to sse a mapped drive from VFP, you surely would create the mapped drive on Windows, not within an app, as described here: Readd the whole article before doing anything and you see WebDav has a lot of gotchas.

An app that turns your phone into an FTP serer would be better, there are also many way to make use of FTP (not a drive letter or share) in VFP.


Chriss
 
Strong, I don't actually know what you mean by enumerate the drives. Never heard that term before. But here's my best guess at a translation for your code. Also I have no idea what that value is for thisPC. Where do you get that from? I'm also not sure what to use for AndroidFolder. I took what Explorer shows on the address bar at the top.

Code:
    local ThisPC As Variant 
    local objShellAPP As Shell32.Shell
    local objFolder As Folder2
    local objItem As FolderItem

    local myAndroid 
    local AndroidFolder 
    local myAndroidNameSpace
    
    myAndroid = "iX14" 

    ThisPC = "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" 
    objFolder = objShellAPP.Namespace(ThisPC)
    for each objItem in objFolder.Items()
        if objItem.Name = myAndroid 
            myAndroidNameSpace = objItem.Path 
        endif
    next
    
    * Part2: use the device we have identified
    * This is what shows up when highlight the top bar in Explorer.  But on the left side of Explorer it only appears as "iX
    AndroidFolder = "Computer\ix14\Internal shared storage"     
    objFolder     = objShellAPP.Namespace(myAndroidNameSpace + AndroidFolder)
    
    * Just to show one way of listing the folder contents
    For Each objItem In objFolder.Items()
        ? objItem.Name, objItem.Type
    Next
    
    * Ok, now let's demonstrate copying for source folder on Android to a folder on drive E
    local target As Folder2
    target = objShellAPP.Namespace("e:\VFP9Projects\Weather\FlightStreams")
    target.CopyHere objFolder.Items.Item(0) && copies first item in the source folder to our target

 
Can you open a command window from within VFP - that should inherit the status of VFP

Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.

There is no place like G28 X0 Y0 Z0
 
Doug,

"Enumerate the drives" simply means to get a list of the drives. I mentioned this in my post (above) when I referred to the GetDriveType() function. I mentioned it to demonstrate that Windows does not see the drive letter for a connected Android device. But if Strongm has a way of doing it, it might be worth following it up.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
>what that value is for thisPC

The Shell understands something called "special shell folders", which can either be a reference to a physical file system directory, or a reference to a "virtual" folder.

These virtual folders can be accessed through the Shell namespace using a magic number, a GUID for the handler that the Shell should use for that folder. In this case that GUID for the handler is "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}". This is a world-wide identifier, and is the same on all (modern) versions of Windows, in all languages. You can find a list of the handlers and the GUIDS in the registry under [tt]HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FolderDescriptions[/tt]

>not sure what to use for AndroidFolder

The folder on the Android device. So, in your case just: "\Internal shared storage
 
GriffMG said:
Can you open a command window from within VFP - that should inherit the status of VFP

Yes that's what I've been doing and that seems to be what the problem is.
 
I guess I need some help here. I don't do much with classes in VFP. The only syntax I'm familiar with is defining a class as a type of control like
[tt]define class EventButton as CommandButton[/tt]

and later adding objects to a container like
[tt]mNAME = "btn"+trim(curevents.EVENTCODE)
oCNT.AddObject(mNAME,"EventButton")
[/tt]
Other than that exact method I don't know much about VFP objects. There isn't a "new" keyword in VFP like VB or C. There are createobject() and newobject() functions but I've never used them.

I had to guess at using the keyword "local" because it allows a syntax of "as". So to my way of thinking when I wrote "local objShellAPP As Shell32.Shell" it should have instantiated a local variable of that class. It didn't. It just gave it the default value of false, an empty value. So like I say, I need some help from someone who's used to making and using classes. The VFP help files ... aren't very helpful. Just when you need an example they don't give one.

Another befuddlement I have is using this Shell32.dll. I've been trying to understand this object creation syntax and if we instantiate a folder object shouldn't it have to be something like Createobject('Shell32.Shell.Folder2') not just Createobject('Folder2')? I'm also not sure about how to find Shell32.dll. There seems to be copies of it all over the place like in C:\Windows\SysWOW64. Are they all the same? So how do I use it?
 
I've done my own translation and simplicicatipon to what I believe is a fairly minimal example that should work in FoxPro. I think. As I say, not a FoxPro programmer, and I don't have a copy of FoxPro to test this on...

Code:
[COLOR=blue]Private Sub CommandButton3_Click()

    local ThisPC, objFolder, objShellAPP, objItem, myAndroid, AndroidFolder, myAndroidNameSpace
     
    myAndroid = "iX14" [COLOR=green]' Android device name, should be able to get this from Explorer[/color]
    ThisPC = "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" '[COLOR=green] MyComputerFolder shell special folder, i.e This Computer; do not change this[/color]
    
    objShellAPP = CreateObject("Shell.Application")
    objFolder = objShellAPP.Namespace(ThisPC)
    [COLOR=green]' Find my Android device
[/color]    For Each objItem In objFolder.Items
        If objItem.Name = myAndroid Then
            myAndroidNameSpace = objItem.Path
        EndIf
    Next
  
    [COLOR=green]' Now find my folder[/color]
    AndroidFolder = "\Internal shared storage"
    objFolder = objShellAPP.Namespace(myAndroidNameSpace & AndroidFolder)
    For Each objItem In objFolder.Items
         Print objItem.Name, objItem.Type
    Next

    target = objShellAPP.Namespace("e:\VFP9Projects\Weather\FlightStreams")
    [COLOR=green]' copies first item in the source folder to target
    ' (if you want to copy a specific file you'll need to look through objFolder.Items to find it)
[/color]    target.CopyHere objFolder.Items.Item(0)
 
End Sub[/color]
 
Strongm, for someone who's not a Foxpro programmer, you've done a prety good job of translating from VB.

For your future reference, and for the benefit of others, let me just point out a few things that need attention. (I've added line numbers here just for reference, they are obviously not part of the actual code).

Code:
1 Private Sub CommandButton3_Click()
2 
3     local ThisPC, objFolder, objShellAPP, objItem, myAndroid, AndroidFolder, myAndroidNameSpace
4      
5     myAndroid = "iX14" ' Android device name, should be able to get this from Explorer
6     ThisPC = "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" ' MyComputerFolder shell special folder, i.e This Computer; do not change this
7     
8     objShellAPP = CreateObject("Shell.Application")
9     objFolder = objShellAPP.Namespace(ThisPC)
10    ' Find my Android device
11    For Each objItem In objFolder.Items
12        If objItem.Name = myAndroid Then
13            myAndroidNameSpace = objItem.Path
14        EndIf
15    Next
16  
17    ' Now find my folder
18    AndroidFolder = "\Internal shared storage"
19    objFolder = objShellAPP.Namespace(myAndroidNameSpace & AndroidFolder)
20    For Each objItem In objFolder.Items
21         Print objItem.Name, objItem.Type
22    Next
23
24    target = objShellAPP.Namespace("e:\VFP9Projects\Weather\FlightStreams")
25    ' copies first item in the source folder to target
26    ' (if you want to copy a specific file you'll need to look through objFolder.Items to find it)
27    target.CopyHere objFolder.Items.Item(0)
28 
29End Sub

Line 1. This is not VFP syntax, and can be deleted. Instead, the programmer would just paste the code into the Click event of the relevant command button, or whatever other control is appropriate.

Line 5: We don't use the apostrophe for an in-line comment. Use [tt]&&[/tt] instead.

Line 10, 17, 25 and 26: Ditto. Or use [tt]*[/tt] at the start of the line for a comment.

Line 12: [tt]Then[/tt] is not normally used after an IF (but is not illegal).

Line 19: We don't use [tt]&[/tt] for concatenation. Use[tt] +[/tt] instead.

Line 21: If you want to display something on the screen, use [tt]?[/tt], not [tt]Print[/tt].

Line 27: Not sure what this syntax means. If you are passing [tt]objFolder.Items.Item(0[/tt]) to the CopyTo method, then place it in parens, with no intervening space.

Line 29. This should be deleted, for the same reason as for Line 1 (above).

I think that covers everything. I'll now have a shot of fixing the above, unless anyone gets there first.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Good luck ML

B=)

Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.

There is no place like G28 X0 Y0 Z0
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top