[docs]classAndroid(PlatformDirsABC):""" Follows the guidance `from here <https://android.stackexchange.com/a/216132>`_. Makes use of the `appname <platformdirs.api.PlatformDirsABC.appname>`, `version <platformdirs.api.PlatformDirsABC.version>`, `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`. """@propertydefuser_data_dir(self)->str:""":return: data directory tied to the user, e.g. ``/data/user/<userid>/<packagename>/files/<AppName>``"""returnself._append_app_name_and_version(cast(str,_android_folder()),"files")@propertydefsite_data_dir(self)->str:""":return: data directory shared by users, same as `user_data_dir`"""returnself.user_data_dir@propertydefuser_config_dir(self)->str:""" :return: config directory tied to the user, e.g. \ ``/data/user/<userid>/<packagename>/shared_prefs/<AppName>`` """returnself._append_app_name_and_version(cast(str,_android_folder()),"shared_prefs")@propertydefsite_config_dir(self)->str:""":return: config directory shared by the users, same as `user_config_dir`"""returnself.user_config_dir@propertydefuser_cache_dir(self)->str:""":return: cache directory tied to the user, e.g.,``/data/user/<userid>/<packagename>/cache/<AppName>``"""returnself._append_app_name_and_version(cast(str,_android_folder()),"cache")@propertydefsite_cache_dir(self)->str:""":return: cache directory shared by users, same as `user_cache_dir`"""returnself.user_cache_dir@propertydefuser_state_dir(self)->str:""":return: state directory tied to the user, same as `user_data_dir`"""returnself.user_data_dir@propertydefuser_log_dir(self)->str:""" :return: log directory tied to the user, same as `user_cache_dir` if not opinionated else ``log`` in it, e.g. ``/data/user/<userid>/<packagename>/cache/<AppName>/log`` """path=self.user_cache_dirifself.opinion:path=os.path.join(path,"log")# noqa: PTH118returnpath@propertydefuser_documents_dir(self)->str:""":return: documents directory tied to the user e.g. ``/storage/emulated/0/Documents``"""return_android_documents_folder()@propertydefuser_downloads_dir(self)->str:""":return: downloads directory tied to the user e.g. ``/storage/emulated/0/Downloads``"""return_android_downloads_folder()@propertydefuser_pictures_dir(self)->str:""":return: pictures directory tied to the user e.g. ``/storage/emulated/0/Pictures``"""return_android_pictures_folder()@propertydefuser_videos_dir(self)->str:""":return: videos directory tied to the user e.g. ``/storage/emulated/0/DCIM/Camera``"""return_android_videos_folder()@propertydefuser_music_dir(self)->str:""":return: music directory tied to the user e.g. ``/storage/emulated/0/Music``"""return_android_music_folder()@propertydefuser_desktop_dir(self)->str:""":return: desktop directory tied to the user e.g. ``/storage/emulated/0/Desktop``"""return"/storage/emulated/0/Desktop"@propertydefuser_runtime_dir(self)->str:""" :return: runtime directory tied to the user, same as `user_cache_dir` if not opinionated else ``tmp`` in it, e.g. ``/data/user/<userid>/<packagename>/cache/<AppName>/tmp`` """path=self.user_cache_dirifself.opinion:path=os.path.join(path,"tmp")# noqa: PTH118returnpath@propertydefsite_runtime_dir(self)->str:""":return: runtime directory shared by users, same as `user_runtime_dir`"""returnself.user_runtime_dir
@lru_cache(maxsize=1)def_android_folder()->str|None:# noqa: C901""":return: base folder for the Android OS or None if it cannot be found"""result:str|None=None# type checker isn't happy with our "import android", just don't do this when type checking see# https://stackoverflow.com/a/61394121ifnotTYPE_CHECKING:try:# First try to get a path to android app using python4android (if available)...fromandroidimportmActivity# noqa: PLC0415context=cast("android.content.Context",mActivity.getApplicationContext())# noqa: F821result=context.getFilesDir().getParentFile().getAbsolutePath()exceptException:# noqa: BLE001result=NoneifresultisNone:try:# ...and fall back to using plain pyjnius, if python4android isn't available or doesn't deliver any useful# result...fromjniusimportautoclass# noqa: PLC0415context=autoclass("android.content.Context")result=context.getFilesDir().getParentFile().getAbsolutePath()exceptException:# noqa: BLE001result=NoneifresultisNone:# and if that fails, too, find an android folder looking at path on the sys.path# warning: only works for apps installed under /data, not adopted storage etc.pattern=re.compile(r"/data/(data|user/\d+)/(.+)/files")forpathinsys.path:ifpattern.match(path):result=path.split("/files")[0]breakelse:result=NoneifresultisNone:# one last try: find an android folder looking at path on the sys.path taking adopted storage paths into# accountpattern=re.compile(r"/mnt/expand/[a-fA-F0-9-]{36}/(data|user/\d+)/(.+)/files")forpathinsys.path:ifpattern.match(path):result=path.split("/files")[0]breakelse:result=Nonereturnresult@lru_cache(maxsize=1)def_android_documents_folder()->str:""":return: documents folder for the Android OS"""# Get directories with pyjniustry:fromjniusimportautoclass# noqa: PLC0415context=autoclass("android.content.Context")environment=autoclass("android.os.Environment")documents_dir:str=context.getExternalFilesDir(environment.DIRECTORY_DOCUMENTS).getAbsolutePath()exceptException:# noqa: BLE001documents_dir="/storage/emulated/0/Documents"returndocuments_dir@lru_cache(maxsize=1)def_android_downloads_folder()->str:""":return: downloads folder for the Android OS"""# Get directories with pyjniustry:fromjniusimportautoclass# noqa: PLC0415context=autoclass("android.content.Context")environment=autoclass("android.os.Environment")downloads_dir:str=context.getExternalFilesDir(environment.DIRECTORY_DOWNLOADS).getAbsolutePath()exceptException:# noqa: BLE001downloads_dir="/storage/emulated/0/Downloads"returndownloads_dir@lru_cache(maxsize=1)def_android_pictures_folder()->str:""":return: pictures folder for the Android OS"""# Get directories with pyjniustry:fromjniusimportautoclass# noqa: PLC0415context=autoclass("android.content.Context")environment=autoclass("android.os.Environment")pictures_dir:str=context.getExternalFilesDir(environment.DIRECTORY_PICTURES).getAbsolutePath()exceptException:# noqa: BLE001pictures_dir="/storage/emulated/0/Pictures"returnpictures_dir@lru_cache(maxsize=1)def_android_videos_folder()->str:""":return: videos folder for the Android OS"""# Get directories with pyjniustry:fromjniusimportautoclass# noqa: PLC0415context=autoclass("android.content.Context")environment=autoclass("android.os.Environment")videos_dir:str=context.getExternalFilesDir(environment.DIRECTORY_DCIM).getAbsolutePath()exceptException:# noqa: BLE001videos_dir="/storage/emulated/0/DCIM/Camera"returnvideos_dir@lru_cache(maxsize=1)def_android_music_folder()->str:""":return: music folder for the Android OS"""# Get directories with pyjniustry:fromjniusimportautoclass# noqa: PLC0415context=autoclass("android.content.Context")environment=autoclass("android.os.Environment")music_dir:str=context.getExternalFilesDir(environment.DIRECTORY_MUSIC).getAbsolutePath()exceptException:# noqa: BLE001music_dir="/storage/emulated/0/Music"returnmusic_dir__all__=["Android",]