简体   繁体   中英

Is there a way to create a folder within My Files on Android (external storage) and write files to this folder?

I am coding an Android app (in Java) which uses OCR to convert handwriting into digital text. I am trying to take the String generated by the OCR function in my code and write it to a text file (the OCR portion is currently working). I would then like to create a folder (in phone's external storage, for example My Files on Samsung) and add the text file to this folder, which contains only the files the user has created (which the user should be able to access and share).

I have conducted some research on writing to phone's external storage (including other StackOverflow questions) but no tutorial has worked for me.

/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state)) {
        return true;
    }
    return false;
}


public File writeFolder ()

{

    File file = null;

    if (isExternalStorageWritable())

    {
        // Get the directory for the user's public directory.
       file = new File(Environment.getExternalStorageDirectory() + File.separator + "OCR Documents");

    }

    if (!file.mkdirs())
        Log.e(LOG_TAG, "Directory not created");

    else
        System.out.println(file.getAbsolutePath());

    return file;

}

The code above is what I have, however after testing it, the AbsolutePath is null. It does not seem to be creating a folder on the phone's external storage. How would I go about this so that a folder is created and I can add files to that folder?

Your code to create the directory is fine.

But there's a chance you're missing permissions due to newer versions of Android requiring a User's consent before you can write files to the external storage.

First, make sure you have this permission in your Manifest.xml:

<manifest ...>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    ...
</manifest>

Afterwards, since WRITE_EXTERNAL_STORAGE is listed as a Dangerous Permission, as seen here: https://developer.android.com/guide/topics/permissions/overview#normal-dangerous , you'll also need to explicitly request the permission from the user.

Finally, to request the permission:

// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
        Manifest.permission.READ_CONTACTS)
        != PackageManager.PERMISSION_GRANTED) {

    // Permission is not granted
    // Should we show an explanation?
    if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
            Manifest.permission.READ_CONTACTS)) {
        // Show an explanation to the user *asynchronously* -- don't block
        // this thread waiting for the user's response! After the user
        // sees the explanation, try again to request the permission.
    } else {
        // No explanation needed; request the permission
        ActivityCompat.requestPermissions(thisActivity,
                new String[]{Manifest.permission.READ_CONTACTS},
                MY_PERMISSIONS_REQUEST_READ_CONTACTS);

        // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
        // app-defined int constant. The callback method gets the
        // result of the request.
    }
} else {
    // Permission has already been granted
}

You'll also need to handle the response of the request:

@Override
public void onRequestPermissionsResult(int requestCode,
        String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // permission was granted, yay! Do the
                // contacts-related task you need to do.
            } else {
                // permission denied, boo! Disable the
                // functionality that depends on this permission.
            }
            return;
        }

        // other 'case' lines to check for other
        // permissions this app might request.
    }
}

The above code was copied from: https://developer.android.com/training/permissions/requesting

You should read that link more thoroughly since it provides a good explanation of what you need to explain to the user, since users are typically very wary when Apps ask for permissions to modify files in their storage.

You can try this,

  private void getWirtePermissionAndCreateDir() {
    if (Build.VERSION.SDK_INT < 23) {
        createDir();

    } else {
        final String[] PERMISSIONS_STORAGE = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
        //Asking request Permissions
        ActivityCompat.requestPermissions(MainActivity.this, PERMISSIONS_STORAGE, 9);
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {

    boolean writeAccepted = false;
    switch (requestCode) {
        case 9:
            writeAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
            break;
    }
    if (writeAccepted) {
        createDir();
    } else {
        Toast.makeText(MainActivity.this, "You don't assign permission.", Toast.LENGTH_LONG).show();
    }
}

private void createDir(){
    File file = new File(Environment.getExternalStorageDirectory() + File.separator + "OCR Documents");
    file.mkdirs();
    Toast.makeText(MainActivity.this, file.getAbsolutePath(), Toast.LENGTH_LONG).show();
}

You have to add getWirtePermissionAndCreateDir() instead of writeFolder() in activity body.

Below function will create folder and then create file in that folder and if folder already exists then simply create file.

private FileOutputStream fos;

//Function: create a file in a folder
private boolean createFileInFolder(String fileName, String folderName) {
    if (isExternalStorageWritable()) {
        String path = Environment.getExternalStorageDirectory() + "/" + folderName;
        File folder = new File(path);
        if (!folder.exists()) {
            folder.mkdirs();
        }
        txtFile = new File(path, fileName);
        try {
            fos = new FileOutputStream(txtFile);
            return true;
        } catch (IOException e) {
            Toast.makeText(this, e.toString(), Toast.LENGTH_SHORT).show();
            return false;
        }
    } else
        return false;
}

//Function: IsExternalStorageWritable?
public boolean isExternalStorageWritable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state)) {
        return true;
    }
    return false;
}

You may need to check permissions so also define these functions.

private boolean permission;
private final int MY_PERMISSIONS_REQUEST = 10;

//Function: checkPermission
private void checkPermission() {
    if (ContextCompat.checkSelfPermission(this,
            Manifest.permission.WRITE_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED) {
        // No explanation needed, we can request the permission.
        ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                MY_PERMISSIONS_REQUEST);

    } else {
        permission = true;
    }

}

//Function: Permission Request Results
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                permission = true;
            } else {
                permission = false;
            }
            return;
        }
    }
}

In your manifest file don't forget to add this line.

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM