This I have experienced :( The meanings change with Android version and it is not always clear if this is OS version or API version.
So, assuming the failing file path actually exists.....
It looks like the app tries to access a file on internal storage at some 'random' location.
Too much version specific noise for a clear comment, but generally Android only allowed that on external storage.
So that might be the issue.
Btw there is no need to use API 25 for Android 7 - not clear if you would be working around anything real by doing this.
When I don't understand a small test case usually helps, or at least means I can ask a simple question.
This should help you figure out what is going on, use buildozer defaults, except permission as noted:
import kivy
from kivy.app import App
from kivy.uix.label import Label
from android.storage import app_storage_path,primary_external_storage_path,\
secondary_external_storage_path
from android.permissions import request_permissions, check_permission, \
Permission
from os.path import abspath
from os import getcwd
### Demonstrates the file paths for various Android storage locations
### on the current device (only)
### Demonstrates Android permission for access to Android shared storage
#########################################################################
### Android WRITE_EXTERNAL_STORAGE implies READ_EXTERNAL_STORAGE
### In buildozer.spec:
### android.permissions = WRITE_EXTERNAL_STORAGE
###
### is not required for API 29 or greater (I tested on a device with 29).
### It MAY be required (I have not tested) for devices with API 28 or less.
### At least, I think that is what this says:
### https://developer.android.com/reference/android/Manifest.permission#WRITE_EXTERNAL_STORAGE
class MyApp(App):
def permission_callback(self,permissions,grants):
if check_permission(Permission.WRITE_EXTERNAL_STORAGE):
self.label.text += 'Write Permission Granted\n'
else:
self.label.text += 'Write Permission Denied\n'
return
# Can only read/write after we have been granted permission
# The user may have denied permission
filename = join(primary_external_storage_path(),'Download/test.txt')
try:
with open(filename, 'w') as out_file:
out_file.write('Greetings Earthlings\n')
self.label.text += filename + ' created\n'
# Now look at this file with your File Manager app
except Exception as e:
self.label.text += str(e)
def build(self):
text = App.get_running_app().user_data_dir + '\n'
text += self.user_data_dir + '\n'
text += app_storage_path() + '\n'
text += getcwd() + '\n'
text += abspath('.') + '\n' # . does work
text += abspath('~') + '\n' # ~ not the Bash interpretation
text += abspath(__file__) +'\n'
self.label = Label(text=text)
# This is I think recomended for 26 thru 28 and later
# And maybe required 29 and greater depending on where accessed
# Permission requests are asynchronous, so you may need the callback.
request_permissions([Permission.WRITE_EXTERNAL_STORAGE],
self.permission_callback)
# Note: Permission probably has not been granted yet.
# (You can see this because, on the device screen the 'Granted'
# message (above) occurs after the message below.)
# These are OK here because they don't read/write to storage.
self.label.text += primary_external_storage_path() +'\n'
if secondary_external_storage_path():
self.label.text += secondary_external_storage_path() +'\n'
else:
self.label.text += 'No secondary storage\n'
return self.label
if __name__ == '__main__':
MyApp().run()