相关疑难解决方法(0)

如何使用为Android 5.0(Lollipop)提供的新SD卡访问API?

背景

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有几个问题:

  1. 你是如何真正使用它的?
  2. 根据帖子,操作系统会记住应用程序被授予访问文件/文件夹的权限.你如何检查你是否可以访问文件/文件夹?是否有一个函数可以返回我可以访问的文件/文件夹列表?
  3. 你如何在Kitkat上处理这个问题?它是支持库的一部分吗?
  4. 操作系统上是否有设置屏幕,显示哪些应用可以访问哪些文件/文件夹?
  5. 如果在同一设备上为多个用户安装了应用程序,会发生什么?
  6. 是否有关于这个新API的任何其他文档/教程?
  7. 权限可以被撤销吗?如果是这样,是否有意图被发送到应用程序?
  8. 是否会在所选文件夹上递归请求权限工作?
  9. 使用该权限是否也允许用户有机会根据用户的选择进行多次选择?或者应用程序是否需要专门告知意图允许哪些文件/文件夹?
  10. 模拟器上有没有办法尝试新的API?我的意思是,它有SD卡分区,但它作为主要外部存储器,所以已经给出了所有访问权限(使用简单的权限).
  11. 当用户用另一张SD卡替换SD卡时会发生什么?

android android-sdcard android-5.0-lollipop documentfile

113
推荐指数
2
解决办法
7万
查看次数

在Android上写入外部SD卡的通用方式

在我的应用程序中,我需要在设备存储中存储大量图像.这些文件往往满足设备存储,我想让用户能够选择外部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)

java android android-sdcard android-external-storage

71
推荐指数
2
解决办法
4万
查看次数

mkdir()在内部闪存存储器内工作,但不是SD卡吗?

我目前正在构建一个文件管理应用程序,允许用户浏览其设备的文件系统.用户/从其设备的根目录开始,但可以浏览到他们想要的任何位置,例如内部闪存或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)

android file-permissions

32
推荐指数
1
解决办法
2779
查看次数

如何访问/存储/模拟/ 0 /

我编写了一个代码来录制音频并将其保存到文件位置下方.

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卡上找到此文件位置.如何访问该位置?

android android-sdcard android-file

27
推荐指数
4
解决办法
27万
查看次数

"Hello world"Android应用程序,文件尽可能少,没有IDE,只有文本编辑器

在我使用的几乎所有语言(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,但是我有一些问题,比如这个问题.另一方面,那里使用的方法似乎已被弃用......

java windows android android-studio android-gradle-plugin

22
推荐指数
2
解决办法
3689
查看次数