Delphi XE5 Android - Storage path problems

12,781

Solution 1

Try not to hard code the path. The paths to external storage may vary for different Android platforms and you'll miss the advantage of cross-platform programming. When I started programming for Android I wrote a small App 'Where' targeted at listing all 'special' directories for all platforms. That was very useful as I didn't know these directories for even Windows, let alone Android. In your example you miss the SharedDirectories. This will return the path to /storage/emulated/0/Music/ for GetSharedMusicPath for example, and so on for Movies, Download, etc. I thought it was different for my Galaxy Tab but I'm not sure. Just remove the last name and you have the path to external storage.

Take care that you have READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE set if you want to read and write to your external storage (somewhere in Project | Options | Android). I don't know whether Android allows you to write in the external storage root, you must try that yourself.

uses System.IOUtils;

procedure THeaderFooterForm.Loaded;
begin
   inherited Loaded;

   TPath.SetApplicationPath ('WhereAppTest');

   add_path (TPath.GetTempPath, 'GetTempPath');
   add_path (TPath.GetHomePath, 'GetHomePath');
   add_path (TPath.GetDocumentsPath, 'GetDocumentsPath');
   add_path (TPath.GetApplicationPath ('WhereAppTest'), 'GetApplicationPath');
   add_path (TPath.GetSharedDocumentsPath, 'GetSharedDocumentsPath');
   add_path (TPath.GetLibraryPath, 'GetLibraryPath');
   add_path (TPath.GetCachePath, 'GetCachePath');
   add_path (TPath.GetPublicPath, 'GetPublicPath');
   add_path (TPath.GetPicturesPath, 'GetPicturesPath');
   add_path (TPath.GetSharedPicturesPath, 'GetSharedPicturesPath');
   add_path (TPath.GetCameraPath, 'GetCameraPath');
   add_path (TPath.GetSharedCameraPath, 'GetSharedCameraPath');
   add_path (TPath.GetMusicPath, 'GetMusicPath');
   add_path (TPath.GetSharedMusicPath, 'GetSharedMusicPath');
   add_path (TPath.GetMoviesPath, 'GetMoviesPath');
   add_path (TPath.GetSharedMoviesPath, 'GetSharedMoviesPath');
   add_path (TPath.GetAlarmsPath, 'GetAlarmsPath');
   add_path (TPath.GetSharedAlarmsPath, 'GetSharedAlarmsPath');
   add_path (TPath.GetDownloadsPath, 'GetDownloadsPath');
   add_path (TPath.GetSharedDownloadsPath, 'GetSharedDownloadsPath');
   add_path (TPath.GetRingtonesPath.Empty, 'GetRingtonesPath');
   add_path (TPath.GetSharedRingtonesPath, 'GetSharedRingtonesPath');
   FMediaPlayer := TMediaPlayer.Create(Self);
end; // Loaded //

procedure THeaderFooterForm.add_path (path, header: string);
var
   item: TListViewItem;
   bitmap: TBitmap;
begin
   item := List_Paths.Items.Add;
   item.ButtonText := 'button';
   item.Detail := path;
   item.Text := header;
end; // add_path //

Solution 2

Here's the function that will get you the default SDCard path from GetShared paths; The first is simple and will get you just the SDCard path from fixed path of the SharedMusic;

function GetSDCardPath: string;
var MusicPathLength: integer;
    MusicPath, SDCardPath: string;
begin
  MusicPath:=System.IOUtils.TPath.GetSharedMusicPath;
  MusicPathLength:=Length(MusicPath);
  SDCardPath:=Copy(MusicPath, 0, MusicPathLength-5);
  Result:=SDCardPath;
end;

I could add the function to extract sdcard path from any of provided paths results, but I think the example above is the most simple you could use, and works flawlessly for me. Thanks to @Arnold for help too. :)

Share:
12,781
That Marc
Author by

That Marc

Software developer C# .Net Delphi AS3 Flex/AIR C PHP/HTML5 Contact: Google/Hangouts: dropdeadnight(at)gmail.com

Updated on June 04, 2022

Comments

  • That Marc
    That Marc almost 2 years

    I started doing an app for android in Delphi XE5, and encountered some troubles.

    I really don't understand about getting paths. After I set the permissions to Write and Read External storage, I tried to get paths so I can see where I'm saving files I create, and this is what I get:

    for System.IOUtils.TPath. ->

    GetDocumentsPath;       -  /data/data/com.myapp.app1/files
    GetDownloadsPath;       -  /storage/emulated/0/Android/data/com.myapp.app1/files/Download
    GetHomePath;            -  /data/data/com.myapp.app1/files
    GetSharedDocumentsPath; -  /storage/emulated/0/Android/data/com.myapp.app1/files
    GetLibraryPath;         -  /data/data/com.myapp.app1/files
    GetPublicPath;          -  /storage/emulated/0/Android/data/com.myapp.app1/files
    GetPicturesPath;        -  /storage/emulated/0/Android/data/com.myapp.app1/files/Pictures
    

    As far as I understood from other topics, the GetDocumentsPath should be default sdcard path, Downloads should be sdcard/Downloads, but instead it's using /Android/data/application's folder/files/ here creats folders which already exists on the sdcard itself.

    /emulated/0/ is actually the same as /sdcard/ on my phone, if that's confusing for anyone (just in case....).

    It has several shortcuts, as far as I understand, storage/emulated/0/, storage/sdcard0/, also from root's folder is directly access to sdcard/ (but I guess the apps without root access has only default access to storage/ folder, hence the storage/sdcard0 and emulated/0 folders exists; don't know why are duplicated shortcuts to the same folder, though....)

    [[ There's also storage/emulated/legacy/, which also seems to point to the same folder, but I never touch it, since I used to have some troubles with file duplicates and strange Music library behaviour, right before I rooted and formatted it. Never figured what really happened, but don't even care. Fact is, that the emulated folder seems to be evil and unexplained ;) ]]

    Also, are these path troubles related to the fact, that the phone has no mount option, but only MTP, or that it's android 4.3, or....?

    Thanks.

    // Update: Splitted questions about this and screen resolutions as Sir Rufo suggested.

    UPDATE: Looks like hardcoding '/sdcard/filename.extension' as path string does the job, however I'm not sure how wise it is to hardcore the location in the app... ://