MarquisLP / World-Scribe

An Android app for fictional world-building
MIT License
41 stars 7 forks source link

Update target SDK to version 29+ #24

Closed MarquisLP closed 4 years ago

MarquisLP commented 4 years ago

Android SDK 29 has deprecated [getExternalStorageDirectory()](https://developer.android.com/reference/android/os/Environment.html#getExternalStorageDirectory()). As such, we are expected to migrate to to the more privacy-respecting alternative, getExternalFilesDir().

However, the latter function returns a subdirectory in the external storage directory, rather than the root external storage directory itself. An example would be /storage/emulated/0/Documents.

This makes the migration troublesome for us, as the World Scribe app folder is located at /storage/emulated/0/WorldScribe. If we were to use getExternalFilesDir, the app would start using /storage/emulated/0/Documents/WorldScribe instead, disregarding any files from the old directory.

If we update the target SDK to 29 (and above), we will have to determine some way to migrate the original folder to its new destination on all users' devices.

tostc commented 4 years ago

I've found a workaround. For SDK 29+ exists a manifest entry

android:requestLegacyExternalStorage="true"

which must added to the <application> tag. It's not an elegant solution, but maybe it helps. Source: https://commonsware.com/blog/2019/06/07/death-external-storage-end-saga.html Section: I Don’t Like Change — How Do I Stick With What Worked Before?

MarquisLP commented 4 years ago

Great find! That simplifies matters a great deal. Although, looking at the official documentation for requestLegacyExternalStorage:

Note that this may not always be respected due to policy or backwards compatibility reasons.

So it isn't 100% reliable for newer devices. I'll perform further research on this, but it might also be worth looking into MediaStore, as the docs states just below that line:

Apps not requesting legacy storage can continue to discover and read media belonging to other apps via MediaStore.

MarquisLP commented 4 years ago

It seems like Flipper would be the best option for a long-term solution.

Flipper is an android library project to help developers to use file-like interface using the storage access framework. Flipper is designed to handle the new behavior required by Android Q.

According to this StackOverflow answer, we would request permission to root external storage using StorageManager.getPrimaryStorageVolume().createOpenDocumentTreeIntent(), then use Flipper to access files like normal.

I'll play around with this method and see if it works with World Scribe's file operations.

MarquisLP commented 4 years ago

All of the necessary changes have been merged into develop.

These changes include some new text in the Permissions Activity asking Android 10+ users to select a location to store the WorldScribe folder. @tostc could I ask for your help in translating these new strings in the German strings file? The English versions of those strings are currently in that file, named selectRootDirectoryTitle and selectRootDirectoryExplanation.

tostc commented 4 years ago

I've added the requested translation.