【问题标题】:How to use new Lollipop SD card access API on devices running KITKAT?如何在运行 KITKAT 的设备上使用新的 Lollipop SD 卡访问 API?
【发布时间】:2015-01-19 13:12:06
【问题描述】:

Kit-Kat 问题无法写入外部 SD 卡,

Goolge Document 中所述要在运行 KITKAT 或更早版本的设备上简化代码,您可以使用 fromFile(File) 来模拟 DocumentsProvider 的行为 下面的代码(新 API)适用于 Lollipop,但是如何将新 API 用于 kitkat 呢?

也看Kit-Kat issue (New API)

public class MyActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_my);
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
    startActivityForResult(intent, 42);
}

public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
    if (resultCode == RESULT_OK) {
        Uri treeUri = resultData.getData();
        DocumentFile pickedDir = DocumentFile.fromFile(new File("/mnt/extSdCard/Test"));

        // List all existing files inside picked directory
        for (DocumentFile file : pickedDir.listFiles()) {
            Log.d("Tag", "Found file " + file.getName() + " with size " + file.length());
        }

        // Create a new file and write into it
        DocumentFile newFile = pickedDir.createFile("text/plain", "My Novel");
        OutputStream out = null;
        try {
            out = getContentResolver().openOutputStream(newFile.getUri());
            out.write("A long time ago...".getBytes());
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.my, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}
}

如何使用 fromFile(File) ?

我试过但说无法创建文件:java.io.IOException:打开失败:EACCES(权限被拒绝)

即使添加了权限 使用权限 android:name="android.permission.WRITE_EXTERNAL_STORAGE"

Android 版本 4.4.2

 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_my);

    DocumentFile pickedDir = DocumentFile.fromFile(new File("/mnt/extSdCard/Test"));

    // List all existing files inside picked directory
    for (DocumentFile file : pickedDir.listFiles()) {
        Log.d("Tag", "Found file " + file.getName() + " with size " + file.length());
    }

    // Create a new file and write into it
    DocumentFile newFile = pickedDir.createFile("text/plain", "My Novel");
    OutputStream out = null;
    try {

        //Says NullPointerException
        out = getContentResolver().openOutputStream(newFile.getUri());                             out.write("A long time ago...".getBytes());
        out.close();
    } catch (Exception e) {
        e.printStackTrace();
    }        
}

【问题讨论】:

    标签: java android android-sdcard


    【解决方案1】:

    新的 API 只帮助 Lollipop 上的人写入辅助 sdcard,KitKat 上的人仍然是out of luck

    DocumentFile.fromFile(...)

    这不会给你任何额外的 访问您的应用已经拥有的基础文件。

    利用Intent.ACTION_OPEN_DOCUMENT_TREE 创建的新权限 你必须使用DocumentFile.fromTreeUri返回的Uri

    【讨论】:

    • 我其实有这个权限,但是出于某种原因,调用 DocumentFile.fromFile(context,file).delete();对我来说总是失败。
    • 据我所知,“不给你任何额外的访问权限”仍然成立。如果您已获得对完整存储的 URI 访问权限,并且想要 File -> DocumentFile,您将不得不基于您有权访问的树 uri 进行一些痛苦的 URI 构建,然后从中创建一个 DocumentFile。查看 DocumentFile 源代码并查看 FilePicker / Helper 方法等返回的 URI 的差异。
    • 为什么会这样?而且这个功能不是因为这个而被认为是无用的吗?你的意思是告诉我,我需要为此遍历文件树?
    • 我也觉得这很疯狂,但是 afaik 这就是可用的...遍历树或查找 AOSP 代码并创建一个构造工作 DocumentFile 的函数(这是可能的,只是非常 hacky)。
    • 只是很多相关的功能已经是相当的变通了。看看这段代码:github.com/jeisfeld/Augendiagnose/blob/master/AugendiagnoseLib/…
    猜你喜欢
    • 2014-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-31
    • 2015-06-21
    • 1970-01-01
    相关资源
    最近更新 更多