I connect a Samsung Galaxy Android tablet with a USB cable to computer running Windows 7. It connects using MTP.
- Step 1. Copy my SQLite database from Windows 7 to tablet via Windows Explorer.
- Step 2. Open it on the tablet (which adds the android_metadata table) and then close it.
- Step 3. Copy the SQLite database back to Windows.
- Step 4. Check it using sqlite3.exe. It's corrupt.
Now another test.
- Step 1. Copy my SQLite database from Windows 7 to tablet via Windows Explorer
- Step 2. Disconnect then reconnect the USB cable.
- Step 3. Open it on the tablet (which adds the android_metadata table) and then close it.
- Step 3. Copy the SQLite database back to Windows.
- Step 4. Check it using sqlite3.exe. It's NOT corrupt.
Interestingly, if I switch steps 2 and 3, it also works.
Since it works when I disconnect and reconnect the USB cable, I'm guessing that I need to flush the MTP cache somehow. How can this be accomplished, or is there an API I can use to quickly disconnect and reconnect the device?
My actual Windows application uses the WPD (Windows Portable Devices) API, I'm just testing using Windows Explorer to prove it's not a problem in my Windows code. I don't see anything in WPD to do a flush.
The error seems to occur when the SQLite database on Android grows by a page (or more). The page size in SQLite is 512 bytes. Looking at the SQLite database's binary data , I can see what's happening. I make the database one page bigger on the device, copy the database off the device, unplug the usb, plug it in, then copy it off again. Comparing the two files, the file I get after I copy the usb data off is the same except it has a lot more data at the end. It's like MTP doesn't understand the file is bigger until you unplug the usb and plug it in again. If you leave USB plugged in it only copies over the number of bytes that were there the last time it copied the file.
Use this function of windows as shown by this DELPHI example.
procedure shCopyFile(hWndOwner: HWND; const SourceFile, TargetFile: string);
var Info : TSHFileOpStruct;
Aborted : Bool;
begin
Aborted := False;
with Info do
begin
Wnd := hWndOwner;
wFunc := FO_COPY;
// From Microsoft's Help:
// wFunc = Operation to perform. This member can be one of the following values:
// FO_COPY Copies the files specified by pFrom to the location specified by pTo.
// FO_DELETE Deletes the files specified by pFrom (pTo is ignored).
// FO_MOVE Moves the files specified by pFrom to the location specified by pTo.
// FO_RENAME Renames the files specified by pFrom.
pFrom := pChar(SourceFile);
pTo := pChar(TargetFile);
fFlags := 0;
fFlags := FOF_SILENT or FOF_NOCONFIRMATION or FOF_NOERRORUI;
fAnyOperationsAborted := Aborted;
end;
try
SHFileOperation(Info);
finally
if Aborted then; enact upon any user cancellations
end;
end;
I'm copying file from Desktop to Android MTP device PATH
Stefano www.data-ware.it
I have found exact the same problem on the Samsung Galaxy Tab 2 7.0.
But in my oppinion it is a problem on the android side.
If I force the application which opens the db to stop (System Settings->app manager->my app->force stopp) then it works.
Only "open connection" and "close connection" isn't enough. The complete process on the android-side has to be closed.
This explains why it works after restarting the device.
Further investigation: It works perfectly with Galaxy Tab and 4.1.2 (if App-process is closed). It works with MTP but not PTP (Picture Transfer Protocol). Both protocols are connecting with WPD-function but PTP is quite inconsistent when writing and reading (so never ever use PTP).
来源:https://stackoverflow.com/questions/9115481/flush-mtp-connection-with-android-tablet