3
votes

Kit-Kat issue can't write to external SD card,

As mentioned in Goolge Document To simplify your code on devices running KITKAT or earlier, you can use fromFile(File) which emulates the behavior of a DocumentsProvider The code below (New API) works for Lollipop but how to use the new API for kitkat ?

Also look at 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);
}
}

How to use fromFile(File) ?

I tried but says Failed to createFile: java.io.IOException: open failed: EACCES (Permission denied)

Even after adding the permission uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"

Android version 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();
    }        
}
1

1 Answers

5
votes

The new API only helps people on Lollipop to write to the secondary sdcard, people on KitKat are still out of luck.

DocumentFile.fromFile(...)

This doesn't give you any additional access to the underlying files beyond what your app already has.

To leverage the new permissions created by Intent.ACTION_OPEN_DOCUMENT_TREE you have to use the Uri returned by with DocumentFile.fromTreeUri