简体   繁体   中英

Android R – Create a text file in Download folder using Scoped storage (MediaStore.Downloads)

My app needs to save a string in a text file in Download folder. Currently (target: API 29 (Q) I am using the FILE API with:

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

But for API 30 (R), if I understood well, I have to migrate this to Scoped storage (MediaStore.Downloads).

And here, I am a bit lost. I can't find good documentation or snippet showing how to create a text file in Download. I would appriciate if someone could explain or show how to do this?

Having just tested using your above setup in a AndrioidManifest.xml :

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

With those permissions granted and on a emulator running API 30 (R) I was able to write/read/update a text file with this simple code:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    
    if(ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
        val f = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "new_file.txt")
        f.appendText("test ${Instant.now().toEpochMilli()}\n")

        f.readLines().forEach { line -> Log.e("LOG", line)}
    }
}

This post: https://stackoverflow.com/a/64192581/4252352 suggests that if you created the file you will be able to have access to it using the File api. Note: Environment.getExternalStoragePublicDirectory is deprecated but seems to work even on Android 11 if you are the owner of the file.

Just for fun I swapped between target and compile versions 29/30 to see if anything would blow up when targetting different sdk's and reinstalling the same app on the same emulator. It worked fine, I had full access to the same file regardless.

If I'm honest the whole thing is a bit of a shambles - this post by CommonsWare https://commonsware.com/blog/2019/12/21/scoped-storage-stories-storing-mediastore.html is a good read as it touches on many things that are now enforced in Android 11, even though it mostly talks about Android 10.

Documentation seems to be splintered with sections pertaining to storage / scoped storage and the like in a lot of different places. This link to a table gives a good launch ground for sifting through the documentation based on inital use case: https://developer.android.com/training/data-storage

I have also attached a screenshot of the file appearing in the file manager:

文件管理器

PS: Terrible throwaway code here - I/O work on main thread etc.. only for illustrative purposes.

Based on comment "R.= 30": My usages of "R" and Api "30" are based on this from the AndroidStudio IDE :

安卓版本

(R = runtime environment, Api 30 = sdk for runtime)

Happy for an edit if I have misunderstood something, or not semantically correct in some way.

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