Android 如何让用户访问我的应用程序的内部存储目录?
我的应用程序将文件存储在其内部存储目录中(/Android/data/com.mycompany.myapp/files,由getFilesDir()返回),我希望允许用户直接从移动设备上的文件管理应用程序或Android file Transfer desktop应用程序访问这些文件 报告说: 默认情况下,保存到内部存储器的文件是应用程序的专用文件,其他应用程序无法访问它们(用户也不能) “默认情况下”意味着我可以更改默认权限以允许用户访问这些文件,但我找不到任何关于如何操作的文档。当前,当我使用文件管理应用程序浏览/Android/data目录时,com.mycompany.myapp目录是隐藏的 我当前保存的文件数据如下:Android 如何让用户访问我的应用程序的内部存储目录?,android,file-permissions,fileoutputstream,Android,File Permissions,Fileoutputstream,我的应用程序将文件存储在其内部存储目录中(/Android/data/com.mycompany.myapp/files,由getFilesDir()返回),我希望允许用户直接从移动设备上的文件管理应用程序或Android file Transfer desktop应用程序访问这些文件 报告说: 默认情况下,保存到内部存储器的文件是应用程序的专用文件,其他应用程序无法访问它们(用户也不能) “默认情况下”意味着我可以更改默认权限以允许用户访问这些文件,但我找不到任何关于如何操作的文档。当前,当我
String fileName = "myfile.jpg";
String filePath = getFilesDir() + File.separator + fileName;
FileOutputStream fileStream = new FileOutputStream(filePath);
fileData.writeTo(fileStream); // fileData is a ByteArrayOutputStream
fileStream.close();
我尝试将各个文件的权限设置为世界可读,但这并没有使目录可见:
FileOutputStream fileStream = this.app.openFileOutput(fileName, Context.MODE_WORLD_READABLE);
我还检查了AndroidManifest文件的文档,没有看到任何内容。有人知道我是如何做到这一点的吗?我想你被开发人员文档弄糊涂了,我不能怪你,这不是我读过的最好的文档。无论如何,Android提供了两种将文件保存到文件系统的方法:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
有更多关于文档的信息以及您应该注意的事项。例如,您可以授予应用程序对这些文件的所有权,以便在卸载应用程序时,系统可以自动删除这些文件。有关更多信息,请参阅我仔细查看了
getFilesDir()
与getExternalFilesDir()
的结果,发现getFilesDir()
返回/data/data/[packagename]/files
而getExternalFilesDir()
返回/Android/data/[packagename]/files
。我以为我在/Android/data
中浏览的应用程序文件是内部存储目录,但现在我看到这些实际上是外部存储目录
如果内部存储目录确实不可供普通用户使用,我希望文档中不要说它们“默认”不可用。至少对我来说,说“默认”意味着默认行为可以更改
无论如何,我测试并确认,如果我删除我的应用程序,保存到getExternalFilesDir()
的文件会自动删除。因此,这满足了我对存储位置的需求,该存储位置与应用程序明确连接(使用特定于应用程序的目录名,并随应用程序一起删除),但用户可以偶尔手动管理文件
下面是一个比较,可能对其他人阅读本文有所帮助:
- getFilesDir()-创建特定于应用程序的目录;对用户隐藏;已随应用程序删除
- getExternalFilesDir()-创建特定于应用程序的目录;用户可访问;已随应用程序删除
- getExternalStoragePublicDirectory()-使用共享目录(如音乐);用户可访问;删除应用程序时保留
private static final String RequieredPermission = Manifest.permission.READ_EXTERNAL_STORAGE;
然后在需要检查权限的地方调用HandlePermission()
,通常是在活动的Oncreate方法中。然后需要这些功能:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
Log.d("amir", "onRequestPermissionsResult: called");
switch (requestCode) {
case REQUEST_PERMISSION_READING_STATE:
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(MainActivity.this, "Permission Granted!", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "Permission Denied!", Toast.LENGTH_SHORT).show();
}
}
}
private void HandlePermission() {
int permissionCheck = ContextCompat.checkSelfPermission(
this, RequieredPermission);
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
RequieredPermission)) {
showExplanationaboutPermission("Permission Needed", "Rationale", RequieredPermission, REQUEST_PERMISSION_READING_STATE);
} else {
requestPermission(RequieredPermission, REQUEST_PERMISSION_READING_STATE);
}
} else {
Toast.makeText(MainActivity.this, "Permission (already) Granted!", Toast.LENGTH_SHORT).show();
}
}
private void showExplanationaboutPermission(String title,
String message,
final String permission,
final int permissionRequestCode) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(title)
.setMessage(message)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
requestPermission(permission, permissionRequestCode);
}
});
builder.create().show();
}
private void requestPermission(String permissionName, int permissionRequestCode) {
ActivityCompat.requestPermissions(this,
new String[]{permissionName}, permissionRequestCode);
}
内部/外部名称确实令人困惑(“设备内置内存上的外部”存储与可移动存储卡上的“辅助外部”存储),但我想我明白了。内部存储在/Android/data/com.mycompany.myapp,对吗?似乎其他应用程序正在让用户看到这一点。例如,我安装了Kindle应用程序,可以从ES File Explorer应用程序或Mac上的Android File Transfer浏览/Android/data/com.amazon.Kindle/files目录。@arlomedia mate,我想你会更加困惑。您在文件夹中查看的Kindle文件不是私有文件,而是“世界可读的”。此外,如果您以MTP方式连接Windows机器,您甚至不需要使用Android File Transfer之类的工具来读取这些文件。所以,基本上,你不会真正理解它,否则你就不会发表评论……MODE_PRIVATE的意思就是只对拥有它的应用程序可见。继续浏览你的应用程序的内部存储,你会发现其中很多都是empty@arlomedia你到底还不明白什么?我的应用程序正在将其文件保存在data/com.mycompany.myapp/files中,对于浏览文件系统的普通(非根目录)用户来说,这似乎不存在。其他一些应用程序的目录确实会出现,用户可以浏览它们的文件。我如何才能让我的应用程序以这种方式工作?我只是尝试保存到getExternalFilesDir()位置,而不是getFilesDir()位置,这创建了一个可浏览的data/com.mycompany.myapp/files目录。看起来这些目录就是外部目录
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
Log.d("amir", "onRequestPermissionsResult: called");
switch (requestCode) {
case REQUEST_PERMISSION_READING_STATE:
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(MainActivity.this, "Permission Granted!", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "Permission Denied!", Toast.LENGTH_SHORT).show();
}
}
}
private void HandlePermission() {
int permissionCheck = ContextCompat.checkSelfPermission(
this, RequieredPermission);
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
RequieredPermission)) {
showExplanationaboutPermission("Permission Needed", "Rationale", RequieredPermission, REQUEST_PERMISSION_READING_STATE);
} else {
requestPermission(RequieredPermission, REQUEST_PERMISSION_READING_STATE);
}
} else {
Toast.makeText(MainActivity.this, "Permission (already) Granted!", Toast.LENGTH_SHORT).show();
}
}
private void showExplanationaboutPermission(String title,
String message,
final String permission,
final int permissionRequestCode) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(title)
.setMessage(message)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
requestPermission(permission, permissionRequestCode);
}
});
builder.create().show();
}
private void requestPermission(String permissionName, int permissionRequestCode) {
ActivityCompat.requestPermissions(this,
new String[]{permissionName}, permissionRequestCode);
}