Reputation: 578
When I connect my Android phone to my Windows 7 with USB cable, Windows pop-up a window and show me the phone's internal storage at Computer\HTC VLE_U\Internal storage
from Windows Explorer. But there is no drive letter linked with this phone storage! Inside Windows Explorer, I can manipulate the file system.
How can I manipulate the same files or folders from C# program?
As I tested,
DirectoryInfo di = new DirectoryInfo(@"C:\");
works, but
DirectoryInfo di = new DirectoryInfo(@"Computer\HTC VLE_U\Internal storage");
failed.
But in Windows Explorer, IT IS Computer\HTC VLE_U\Internal storage
! No drive letter!
Yes, this is MTP device.
I see this answer in Stack Overflow, but the return results are empty for me after running this code
var drives = DriveInfo.GetDrives();
var removableFatDrives = drives.Where(
c=>c.DriveType == DriveType.Removable &&
c.DriveFormat == "FAT" &&
c.IsReady);
var androids = from c in removableFatDrives
from d in c.RootDirectory.EnumerateDirectories()
where d.Name.Contains("android")
select c;
I get correct drives
. But android phone's internal storage is not here.
Both removableFatDrives
and androids
are empty for me.
Upvotes: 13
Views: 7845
Reputation: 1701
Using ZackOfAllTrades' code, I ran into OutOfMemoryException when invoking MediaDevice.DownloadFile(string, Stream).
[1] Go to project properties, set project to build for x64, that seems to get rid of OutOfMemoryException; I am able to start copying files between 1GB to 2GB without any problems.
[2] However, as soon as I start copying files of 2.5GB the WriteStreamToDisk() util function by ZackOfAllTrades started to complain about Stream too long.
DownloadFile takes a Stream object, it doesn't need to be a MemoryStream so I switched it to a FileStream object :
static void Main(string[] args)
{
string DeviceNameAsSeenInMyComputer = "Mi Note 10 Pro";
var devices = MediaDevice.GetDevices();
using (var device = devices.Where(d => d.FriendlyName == DeviceNameAsSeenInMyComputer || d.Description == DeviceNameAsSeenInMyComputer).First())
{
device.Connect();
var photoDir = device.GetDirectoryInfo(@"\Internal shared storage\DCIM\Camera");
var files = photoDir.EnumerateFiles("*.*", SearchOption.TopDirectoryOnly);
foreach (var file in files)
{
string destinationFileName = $@"F:\Photo\{file.Name}";
if (!File.Exists(destinationFileName))
{
using (FileStream fs = new FileStream(destinationFileName, FileMode.Create, System.IO.FileAccess.Write))
{
device.DownloadFile(file.FullName, fs);
}
}
}
device.Disconnect();
}
Console.WriteLine("Done...");
Console.ReadLine();
}
Worked beautifully. When I am using ZackOfAllTrades' code, VS profiler shows memory consumption at about 2.5 times the size of file. Eg: if the file is 1.5GB large, the memory consumption is roughly 4GB. But if one is to copy to file system directly, the memory consumption is negligible (<50mb).
The other issue is with MediaDevice.FriendlyName. I know for sure my Xiaomi Note 10 Pro did not support FriendlyName. What worked for me is MediaDevice.Description.
Upvotes: 3
Reputation: 637
I used nugetpackage "Media Devices by Ralf Beckers v1.8.0" This made it easy for me to copy my photos from my device to my computer and vice versa.
public class Program
{
static void Main(string[] args)
{
var devices = MediaDevice.GetDevices();
using (var device = devices.First(d => d.FriendlyName == "Galaxy Note8"))
{
device.Connect();
var photoDir = device.GetDirectoryInfo(@"\Phone\DCIM\Camera");
var files = photoDir.EnumerateFiles("*.*", SearchOption.AllDirectories);
foreach (var file in files)
{
MemoryStream memoryStream = new System.IO.MemoryStream();
device.DownloadFile(file.FullName, memoryStream);
memoryStream.Position = 0;
WriteSreamToDisk($@"D:\PHOTOS\{file.Name}", memoryStream);
}
device.Disconnect();
}
}
static void WriteSreamToDisk(string filePath, MemoryStream memoryStream)
{
using (FileStream file = new FileStream(filePath, FileMode.Create, System.IO.FileAccess.Write))
{
byte[] bytes = new byte[memoryStream.Length];
memoryStream.Read(bytes, 0, (int)memoryStream.Length);
file.Write(bytes, 0, bytes.Length);
memoryStream.Close();
}
}
}
Upvotes: 9