写入 Android 中的内部私有存储
Posted
技术标签:
【中文标题】写入 Android 中的内部私有存储【英文标题】:Writing to the internal private storage in Android 【发布时间】:2011-06-12 16:53:34 【问题描述】:我正在尝试将我的应用程序中的一些数据保存在内部私人存储区域(应用程序用户首选项)上的一个简单文本文件中。我已经阅读了这里(***)上的许多问题,并尝试了建议的解决方案,但没有成功。似乎最简单的解决方案是这里建议的解决方案:http://developer.android.com/guide/topics/data/data-storage.html#filesInternal 但我无法在我的测试设备上使用它。我还尝试使用 java.io.File 中可用的方法和适当的方法来创建文件。我也尝试在 SDCard 上创建文件,结果相同,失败。我已经尝试了其他答案中列出的许多解决方案,完全按照建议的代码和说明找到了相同的结果。我开始觉得我缺少一些重要的代码,或者某处的设置标志,我已经在清单文件中设置了权限:
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
明确地说,我正在尝试写入设备的内部私有存储。它是一个包含姓名、电话号码和几个int
类型标志的小文件。无论我使用什么方法,我要么发现文件没有创建(或者如果我将文件手动放在 SDCard 上会发生更改),或者当我尝试引用文件或文件位置时出现 NullPointerException:
private File fILE = new File("Mydata", main.FILENAME);
或
private File fILE = getDir("Mydata", 0);
我正在使用 Sprint 的最新服务版本更新的 HTC Hero 上运行代码。任何帮助将不胜感激,在此先感谢!
-史蒂夫
更新 (2/2/11):使用 EVO (API 8) 我仍然得到 NullPointerException。生成异常的代码如下,关于为什么我的应用程序无法访问内部存储的任何想法?我在使用两个 API 级别(API 7 和 8)的三个不同物理设备上遇到了这个问题。
File newfile = new File(this.getFilesDir() + "/data/files/", "sample.txt");
更新 2:2/4/11 - 我发现在任何情况下我都看不到物理设备(数据目录)上的文件结构。有人对此有任何想法吗?设备配置正确,可以从eclipse或adb运行app。
更新 3:(2/9/11) - 我想我可能已经找到了问题所在,但我不确定如何处理它。我发现物理设备上/data/目录的权限是:drwxrwx--x
。我不确定为什么会这样,也许与Sprint有关?我在 Sprint 上的 HTC Hero、Samsung Epic (Galaxy S) 和 HTC EVO 上发现了这种方式。问题似乎是 DDMS 和我的应用程序没有对目录的 r/w 访问权限。我需要在这里弄清楚两件事,为什么会这样以及如何在野外解决这个问题。同样,这里的任何帮助都会很棒!
更新 4:我认为去年 2 月对我来说完全是金发碧眼的时刻(见更新 3)。我拥有的测试设备未经过 ROOT,因此无法访问(DUH!)。在他 SGS 和 EVO 4G 经历了所有的更新之后,结果还是一样。我仍在解决这个问题,并会尝试尽快返回这里进行更新(希望下次不到一年)。
【问题讨论】:
您在尝试这些不同的方法时收到错误消息还是只是默默地失败了? 我现在正专注于openFileOutput()
方式,我得到了 NullPointerException。手机上的私人数据目录好像被锁定了,我什至无法查看目录;它就像什么都没有在那里创造。手机上“data”目录的权限为:“drwxrwx--x”。我开始怀疑手机上是否存在无效设置。为了兼容性,数据文件写入内部存储是应用程序的要求。
除非您具有 root 访问权限,否则您将无法使用 DDMS 访问物理设备上的 /data 目录,但您仍然应该能够从应用程序写入文件。模拟器上会发生什么?你能写个文件好吗?
我可以使用模拟器上的 File 类编写好的。这很奇怪,我应该在手机上拥有 root 访问权限,不是吗?
除非您root
操作系统,否则您将无法在真实设备上获得 root 访问权限。我不建议这样做。我有一部 Google Dev Phone 2,甚至没有 root 访问权限。您可以从 Logcat 发布堆栈跟踪吗?它在模拟器上运行但在你的任何设备上都不起作用是没有意义的。
【参考方案1】:
尝试更改以下行:
File newfile = new File(this.getFilesDir() + "/data/files/", "sample.txt");
到:
File newfile = new File(this.getFilesDir() + "/","sample.txt");
【讨论】:
不需要+ "/"
。【参考方案2】:
不是直接回答您的问题,但是:我注意到您不想在文件中存储大量数据。改用共享首选项是否足够?
也许更有趣的是:即使您写入共享首选项文件也会出现问题吗?
http://developer.android.com/guide/topics/data/data-storage.html#pref
【讨论】:
我无法查看/以编程方式访问任何物理设备上的 /data/ 目录。自从更改为 SharedPreferences 后,我没有在物理设备上运行我的应用程序,但我知道我仍然无法查看该目录。我用的是Eclipse 3.5 classic,HTC usb驱动,都更新到最新版本了。 在物理设备上使用SharedPreferences
确实有效。有关这里发生的事情的闲散猜测,请参见下面的回答。 @dbm
好! :-) 看来你的直接问题至少已经解决了。很高兴我能提供帮助(感谢绿色复选标记):-)【参考方案3】:
物理设备的/data/
目录仅对root 用户可用。由于在物理设备上获得此访问权限的唯一现实方法是根设备,因此 DDMS 文件资源管理器无法进入目录树的此分支。
至于为什么应用程序不会在那里写入,可能问题在于我已经使用调试密钥签署了应用程序(不是*NIX 专家,但从我的个人研究来看似乎是这种情况) .
【讨论】:
【参考方案4】:我正在处理同样的问题。最后,我发现你真的不必为了在内部存储中创建一个新文件而提供所有文件路径。只需提及文件名,它将在设备上的应用程序包文件夹下创建。我确实提到了here
而且效果很好。我会说避免提及完整的文件路径,例如:/data/... 为了创建文件(您需要写权限才能以这种方式创建文件)。让 Android 框架为您的应用创建私有文件。
【讨论】:
【参考方案5】:内部存储区域对应用程序来说是私有的,因此用户必须具有根访问权限(根设备)才能创建和加载文件。如果您有根设备,这是将文件写入内部存储的方法:
// Create a file in the Internal Storage
String fileName = "MyFile";
String content = "hello world";
FileOutputStream outputStream = null;
try
outputStream = openFileOutput(fileName, Context.MODE_APPEND);
outputStream.write(content.getBytes());
outputStream.close();
catch (Exception e)
e.printStackTrace();
这应该会立即创建一个名为 MyFile 的文件,其内容为 hello world。内部存储目录通常位于我们应用程序包名称指定的特殊位置。在我的情况下,它是 /data/data/[package name] 并且创建的文件存储在该目录中名为 files 的目录中。
【讨论】:
【参考方案6】:正如@bianca 所说,您最好不要使用文件路径。但是,只使用文件名来创建文件。像这样的:
public static void saveTextToFile(Context context, String filename, String content)
try
FileOutputStream fos = openFileOutput(filename, Context.MODE_PRIVATE);
fos.write(content.getBytes());
fos.close();
catch (Exception e)
e.printStackTrace();
要获取文件,您可以使用:
File file = new File(context.getFilesDir(), filename);
阅读更多:Saving Files。
【讨论】:
以上是关于写入 Android 中的内部私有存储的主要内容,如果未能解决你的问题,请参考以下文章
Android——Android10的分区存储(Scoped Storage)