android.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. from __future__ import annotations
  2. import os
  3. import re
  4. import sys
  5. from functools import lru_cache
  6. from .api import PlatformDirsABC
  7. class Android(PlatformDirsABC):
  8. """
  9. Follows the guidance `from here <https://android.stackexchange.com/a/216132>`_. Makes use of the
  10. `appname <platformdirs.api.PlatformDirsABC.appname>` and
  11. `version <platformdirs.api.PlatformDirsABC.version>`.
  12. """
  13. @property
  14. def user_data_dir(self) -> str:
  15. """:return: data directory tied to the user, e.g. ``/data/user/<userid>/<packagename>/files/<AppName>``"""
  16. return self._append_app_name_and_version(_android_folder(), "files")
  17. @property
  18. def site_data_dir(self) -> str:
  19. """:return: data directory shared by users, same as `user_data_dir`"""
  20. return self.user_data_dir
  21. @property
  22. def user_config_dir(self) -> str:
  23. """
  24. :return: config directory tied to the user, e.g. ``/data/user/<userid>/<packagename>/shared_prefs/<AppName>``
  25. """
  26. return self._append_app_name_and_version(_android_folder(), "shared_prefs")
  27. @property
  28. def site_config_dir(self) -> str:
  29. """:return: config directory shared by the users, same as `user_config_dir`"""
  30. return self.user_config_dir
  31. @property
  32. def user_cache_dir(self) -> str:
  33. """:return: cache directory tied to the user, e.g. e.g. ``/data/user/<userid>/<packagename>/cache/<AppName>``"""
  34. return self._append_app_name_and_version(_android_folder(), "cache")
  35. @property
  36. def user_state_dir(self) -> str:
  37. """:return: state directory tied to the user, same as `user_data_dir`"""
  38. return self.user_data_dir
  39. @property
  40. def user_log_dir(self) -> str:
  41. """
  42. :return: log directory tied to the user, same as `user_cache_dir` if not opinionated else ``log`` in it,
  43. e.g. ``/data/user/<userid>/<packagename>/cache/<AppName>/log``
  44. """
  45. path = self.user_cache_dir
  46. if self.opinion:
  47. path = os.path.join(path, "log")
  48. return path
  49. @property
  50. def user_documents_dir(self) -> str:
  51. """
  52. :return: documents directory tied to the user e.g. ``/storage/emulated/0/Documents``
  53. """
  54. return _android_documents_folder()
  55. @property
  56. def user_runtime_dir(self) -> str:
  57. """
  58. :return: runtime directory tied to the user, same as `user_cache_dir` if not opinionated else ``tmp`` in it,
  59. e.g. ``/data/user/<userid>/<packagename>/cache/<AppName>/tmp``
  60. """
  61. path = self.user_cache_dir
  62. if self.opinion:
  63. path = os.path.join(path, "tmp")
  64. return path
  65. @lru_cache(maxsize=1)
  66. def _android_folder() -> str:
  67. """:return: base folder for the Android OS"""
  68. try:
  69. # First try to get path to android app via pyjnius
  70. from jnius import autoclass
  71. Context = autoclass("android.content.Context") # noqa: N806
  72. result: str = Context.getFilesDir().getParentFile().getAbsolutePath()
  73. except Exception:
  74. # if fails find an android folder looking path on the sys.path
  75. pattern = re.compile(r"/data/(data|user/\d+)/(.+)/files")
  76. for path in sys.path:
  77. if pattern.match(path):
  78. result = path.split("/files")[0]
  79. break
  80. else:
  81. raise OSError("Cannot find path to android app folder")
  82. return result
  83. @lru_cache(maxsize=1)
  84. def _android_documents_folder() -> str:
  85. """:return: documents folder for the Android OS"""
  86. # Get directories with pyjnius
  87. try:
  88. from jnius import autoclass
  89. Context = autoclass("android.content.Context") # noqa: N806
  90. Environment = autoclass("android.os.Environment") # noqa: N806
  91. documents_dir: str = Context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath()
  92. except Exception:
  93. documents_dir = "/storage/emulated/0/Documents"
  94. return documents_dir
  95. __all__ = [
  96. "Android",
  97. ]