在Android 4.4(KitKat)上,谷歌已经限制了对SD卡的访问.
从Android Lollipop(5.0)开始,开发人员可以使用新的API,要求用户确认允许访问特定文件夹,如此Google-Groups帖子所述.
该帖子指导您访问两个网站:
这看起来像是一个内部示例(可能稍后会在API演示中显示),但很难理解发生了什么.
这是新API的官方文档,但它没有详细说明如何使用它.
这是它告诉你的:
如果您确实需要完全访问整个文档子树,请首先启动ACTION_OPEN_DOCUMENT_TREE以允许用户选择目录.然后将生成的getData()传递给fromTreeUri(Context,Uri)以开始使用用户选择的树.
在导航DocumentFile实例树时,您始终可以使用getUri()来获取表示该对象的基础文档的Uri,以便与openInputStream(Uri)等一起使用.
要在运行KITKAT或更早版本的设备上简化代码,可以使用fromFile(File)来模拟DocumentsProvider的行为.
我对新API有几个问题:
在我的应用程序中,我需要在设备存储中存储大量图像.这些文件往往满足设备存储,我想让用户能够选择外部SD卡作为目标文件夹.
我到处读到Android不允许用户写入外部SD卡,SD卡是指外部和可安装的SD卡而不是外部存储器,但文件管理器应用程序设法在所有Android版本上写入外部SD.
在不同的API级别(Pre-KitKat,KitKat,Lollipop +)上授予对外部SD卡的读/写访问权限的更好方法是什么?
更新1
我从Doomknight的答案中尝试了方法1,但没有结果:正如您所看到的那样,我在尝试在SD上写入之前在运行时检查权限:
HashSet<String> extDirs = getStorageDirectories();
for(String dir: extDirs) {
Log.e("SD",dir);
File f = new File(new File(dir),"TEST.TXT");
try {
if(ActivityCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE)==PackageManager.PERMISSION_GRANTED) {
f.createNewFile();
}
} catch (IOException e) {
e.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)
但是我在两个不同的设备上尝试了访问错误:HTC10和Shield K1.
10-22 14:52:57.329 30280-30280/? E/SD: /mnt/media_rw/F38E-14F8
10-22 14:52:57.329 30280-30280/? W/System.err: java.io.IOException: open failed: EACCES (Permission denied)
10-22 14:52:57.329 30280-30280/? W/System.err: at java.io.File.createNewFile(File.java:939)
10-22 14:52:57.329 30280-30280/? W/System.err: at com.myapp.activities.TestActivity.onResume(TestActivity.java:167)
10-22 14:52:57.329 30280-30280/? W/System.err: at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1326)
10-22 14:52:57.330 30280-30280/? W/System.err: at android.app.Activity.performResume(Activity.java:6338)
10-22 14:52:57.330 …Run Code Online (Sandbox Code Playgroud) 我目前正在构建一个文件管理应用程序,允许用户浏览其设备的文件系统.用户/从其设备的根目录开始,但可以浏览到他们想要的任何位置,例如内部闪存或SD卡.
此应用程序的一个关键要求是允许用户在任何地方创建新文件夹.像这样的功能对应用程序非常有用.但是,该File#mkdir()方法在SD卡目录中根本不起作用.
我为清单文件添加了适当的权限.我还写了一个测试,看看哪些目录(我的Lollipop 5.0设备上都存在)允许创建一个新文件夹.根据我的观察,File#mkdir()只有在内部闪存目录中才有效.
注意:请不要Environment#getExternalStorageDirectory()与SD卡位置混淆,如本文所述.同样在Lollipop 5.0上,我相信/storage/emulated/0/并/storage/sdcard0/参考内部闪存存储,/storage/emulated/1/并/storage/sdcard1/参考SD卡(至少对我正在测试的设备是真的).
如何在非root用户Android设备上的外部存储路径之外的区域中创建新文件和文件夹?
表现:
...
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
...
Run Code Online (Sandbox Code Playgroud)
测试:
...
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final String NEW_FOLDER_NAME = "TestFolder";
testPath(new File(Environment.getExternalStorageDirectory(), NEW_FOLDER_NAME));
testPath(new File("/storage/emulated/0/", NEW_FOLDER_NAME));
testPath(new File("/storage/emulated/1/", NEW_FOLDER_NAME));
testPath(new File("/storage/sdcard0/Download/", NEW_FOLDER_NAME));
testPath(new File("/storage/sdcard1/Pictures/", NEW_FOLDER_NAME));
}
private void testPath(File path) {
String TAG = …Run Code Online (Sandbox Code Playgroud) 我编写了一个代码来录制音频并将其保存到文件位置下方.
private String getFilename() {
String filepath = Environment.getExternalStorageDirectory().getPath();
File file = new File(filepath, AUDIO_RECORDER_FOLDER);
if (!file.exists()) {
file.mkdirs();
}
return (file.getAbsolutePath() + "/" + System.currentTimeMillis() + file_exts[currentFormat]);
}
Run Code Online (Sandbox Code Playgroud)
在Logcat中,它为我提供了一个文件位置
/storage/emulated/0/AudioRecorder/1436854479696.mp4
我无法在SD卡上找到此文件位置.如何访问该位置?
在我使用的几乎所有语言(Python,C,C++等)中,只能用文本编辑器编写"hello world"应用程序,并从命令行(解释语言)或编译/构建运行它它来自命令行(编译语言),例如cl.exe helloworld1.cpp.
另一方面,每次我在做Android应用程序时,我都需要使用Android Studio(在我的机器上很慢),用IDE创建一个新项目等.
问题:生成.apk Android应用程序的极简主义Java源代码文件/项目文件的最小数量是多少?如何从命令行构建它?(而且永远不必打开IDE)
注意:我已经阅读了许多Android的hello world,但所有这些都涉及到使用IDE.
NB2:我正在寻找用Java编写的标准应用程序,而不是Kivy等解决方案.
NB3:即使IDE可能更方便编程Android应用程序,我也没有看到编译/构建大量文件的任何技术原因绝对需要使用GUI进行IDE /编程.有些人(像我一样)只喜欢命令行和文本编辑器,这样一个无IDE的解决方案会有所帮助.
NB4:我在Windows平台上工作,基于这个答案,我已经在这里开始了一个"没有IDE的Hello World"github repo,但是我有一些问题,比如这个问题.另一方面,那里使用的方法似乎已被弃用......