My problem
I have an Android app targetted at API 30 which stores a data file in the public directory DIRECTORY_DOWNLOADS for users to access and copy to their own directory elsewhere.
This works for API 28 and below, and for API 30, but not API 29 which has access denied.
What I have done so far
I have studied various posts on here, including answers by experienced users who have replied to topics on API 29 / Android 10, and relevant topics on Android Developers but have been unable to find a specific answer to my problem (or one that I can understand). Some examples I've seen are in Kotlin - I am familiar with Java, but not Kotlin.
What I have in my code
In my manifest:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
(First and third are for other functions of my app.)
In build.gradle:
compileSdkVersion 30
defaultConfig {
applicationId "com.enborne.spine"
minSdkVersion 19
targetSdkVersion 30
versionCode 29
versionName "3.0"
signingConfig signingConfigs.config
}
In my Java code:
My main class Spine includes the following global variables:
public static File dataDir;
public static File fileSaveDir;
In other modules I have:
Spine.dataDir = getFilesDir();
Spine.fileSaveDir =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
and the code that saves the file:
// Default toast text
toastText = "Failed to save file";
// [code to build fileName snipped]
// Create the output file
outFile = new File(Spine.fileSaveDir, fileName);
try
{
out = new BufferedWriter(new FileWriter(outFile), 1024);
// Output the formatted body
// [code snipped]
// Flush and close file
out.flush();
out.close();
// File has been saved
toastText = "File saved as " + formatDesc;
}
catch (IOException e)
{
toastText += "\n" + e.getMessage();
}
When running on API 29, the exception is thrown when the attempt is made to create the BufferedWriter. Otherwise on other API levels everything works. I've searched everywhere for a solution to this problem, but have been unable to find one.
The actual toast text output when running on an API 29 emulator in Android Studio is:
Failed to save file
/storage/emulated/0/Download/
20210520.txt: open failed : EACCES
(Permission denied)