【问题标题】:Delphi XE5 Android - Storage path problemsDelphi XE5 Android - 存储路径问题
【发布时间】:2014-01-13 19:32:02
【问题描述】:

我开始用Delphi XE5做一个android的app,遇到了一些麻烦。

我真的不明白如何获取路径。 将权限设置为写入和读取外部存储后,我尝试获取路径,以便查看保存我创建的文件的位置,这就是我得到的:

对于 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

据我从其他主题了解,GetDocumentsPath 应该是默认 sdcard 路径,Downloads 应该是 sdcard/Downloads,但它使用的是 /Android/data/application 的文件夹/files/ 这里创建的文件夹已经存在于 sdcard自己。

/emulated/0/ 实际上与我手机上的 /sdcard/ 相同,如果这会让任何人感到困惑(以防万一......)。

据我了解,它有几个快捷方式,storage/emulated/0/,storage/sdcard0/,也可以从root的文件夹直接访问sdcard/(但我猜没有root访问权限的应用程序只有默认访问权限storage/ 文件夹,因此存在 storage/sdcard0 和 emulated/0 文件夹;但不知道为什么同一文件夹的快捷方式重复......)

[[还有storage/emulated/legacy/,它似乎也指向同一个文件夹,但我从来没有碰过它,因为我曾经在文件重复和奇怪的音乐库行为方面遇到一些麻烦,就在我扎根之前并将其格式化。从来没有想过到底发生了什么,但甚至不在乎。事实是,模拟文件夹似乎是邪恶且无法解释的;)]]

另外,这些路径问题是否与手机没有挂载选项,只有 MTP,或者它是 android 4.3 或....有关?

谢谢。

// 更新:如 Rufo 爵士建议的那样,关于此问题和屏幕分辨率的拆分问题。

更新: 看起来像硬编码'/sdcard/filename.extension'作为路径字符串可以完成这项工作,但是我不确定在应用程序中硬核位置是多么明智...://

【问题讨论】:

  • 你应该把它分成两个问题 - 每个 SO 问题一个问题 :o)
  • 好吧,至于这个文档,这一切都和我想的一样。因此,shared 确实将我发送到外部存储器到正确的目录中,例如图片、下载、音乐等。但是如果我想在 sd 卡中创建自己的应用程序文件夹,问题仍然存在。我通过 Android/data/com.something.appname/files 发送用户搜索以查找他导出的文件,而是在 SD 卡中创建文件夹,这很荒谬。另外,当应用程序在我的下载中创建文件夹时,我讨厌它。如果是图片,在 /Pictures、Music 中也可以有子文件夹,但我正在导出消息,所以这不会
  • 属于 SD 卡上的任何现有子文件夹,即系统。我觉得这很荒谬,如果正如本文档所暗示的那样,没有硬编码就无法获得 sdcard 根文件夹的直接路径。至于我的手机,如果没有root或没有root访问权限,它就无法在其内部存储器中存储任何内容,因为“sdcard”实际上是内部存储器本身,而是充当外部存储器。所以,我不能使用任何内部路径,但没有获取外部根路径的选项,或者是吗? :/谢谢,不过。如果没有别的,它确实有助于验证我的路径结果......
  • 我不明白你的问题。这就是安卓的工作方式。如果这是一个问题,你想要解决什么问题?您提到路径问题,是哪一个?

标签: android delphi delphi-xe5


【解决方案1】:

尽量不要硬编码路径。外部存储的路径可能因不同的 Android 平台而异,您将错过跨平台编程的优势。当我开始为 Android 编程时,我编写了一个小应用程序“Where”,旨在列出所有平台的所有“特殊”目录。这非常有用,因为我什至不知道 Windows 的这些目录,更不用说 Android。在您的示例中,您错过了 SharedDirectories。这将返回到/storage/emulated/0/Music/ 的路径,例如GetSharedMusicPath,以此类推MoviesDownload 等。我认为这与我的Galaxy Tab 不同,但我不确定。只需删除姓氏,即可获得外部存储的路径。

如果您想读取和写入外部存储(在项目 | 选项 | Android 中的某个位置),请注意设置了 READ_EXTERNAL_STORAGEWRITE_EXTERNAL_STORAGE。我不知道Android是否允许你在外部存储根中写入,你必须自己尝试。

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 //

【讨论】:

  • 它确实允许写入外部存储的根目录(在我的情况下,它实际上是外部的;))存储,许多程序都这样做。这不是 root 访问权限,因此设置了权限的应用程序(您提到,我已经设置了,谢谢)可以在存储路径内的任何位置写入。我确实注意到了 SharedDirectories,也考虑过删除最后一部分,而不是硬编码,但正如所说,我很奇怪没有 GetSharedPath 函数,它可以获取 sd 的根,而不是全部这个删除最后一部分的东西。这很有趣。
  • 哦,谢谢你的代码。如果我一周前有这个,它会节省我几个小时手动检查路径的工作。 :D 我认为硬编码不好,是的。但我不确定使用 GetSharedMusicPath 并删除最后一部分是否有用,因为我不能确定所有平台都使用 sdcard/Music 作为默认音乐路径。或者是否有 100% 确定的信息?我想到了有些人使用 sdcard/media/music 或类似的东西的可能性,这会导致错误的路径......你对这个有什么看法?谢谢!
  • 好吧,我检查了我的 Galaxy Tab 7,它有 /storage/sdcard/Music。如果你剥离音乐,你会留下 /storage/sdcard 这是银河系的外部根。就像 Nexus 7 的 /storage/emulated/0 一样。即使是 /sdcard/media/Music,sdcard/media 也做得很好。最好是找到 GetSharedSomething 路径的来源,看看它是如何定义的。您还会发现其他 GetShared... 路径定义。哦,如果您对答案感到满意,请将其标记为正确。在这个论坛上,每个人都需要投票 ;-)
  • 那么我假设每个人都有那个路径,所以我将使用音乐路径并删除最后一部分。 :) 我什至不知道我为什么要这么复杂,因为我首先是为自己做这个应用程序,而且还没有真正计划将它投放市场,但是,很高兴知道并以正确的方式做事,我相信。 :)
  • 当然!会接受它,但我建议您添加实际代码/函数以获取共享路径之一并删除最后一部分(我认为获取字符串的函数将是一个不错的选择),这样您的答案才有实际答案我的问题,对于其他用户在查看这篇文章时。 :) 相信我,我知道这里需要投票 :) 谢谢。
【解决方案2】:

下面的函数可以从 GetShared 路径中获取默认的 SDCard 路径; 第一个很简单,您只需从 SharedMusic 的固定路径获取 SDCard 路径;

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;

我可以添加从任何提供的路径结果中提取 sdcard 路径的功能,但我认为上面的示例是您可以使用的最简单的示例,并且对我来说完美无缺。感谢@Arnold 的帮助。 :)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多