5

I am running a python script in a termux environment on an Android device and I would like to be able to detect that the OS is Android.

The traditional approaches don't work:

>>> import platform
>>> import sys
>>> print(platform.system())
'Linux'
>>> print(sys.platform)
'linux'
>>> print(platform.release())
'4.14.117-perf+'
>>> print(platform.platform())
'Linux-4.14.117-perf+-aarch64-with-libc'

What other ootb options are available?

An apparently useful option is platform.machine() which returns armv8 — this is more than just 'Linux' yet it's just the architecture, and not the OS, and it might return a false positive for example on a raspberry pi or other arm-based systems.

Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
ccpizza
  • 28,968
  • 18
  • 162
  • 169

2 Answers2

2

I tried os.uname() without success. So I may suggest using subprocess since uname -o returns b'Android\n'.

Here is a simple check for Android:

import subprocess
subprocess.check_output(['uname', '-o']).strip() == b'Android'
Ozgur Bagci
  • 768
  • 11
  • 25
  • 1
    this could do, but this is not really a python-based solution, since it relies on an external utility and moreover spawns a new process – ccpizza Jun 01 '20 at 16:24
  • @ccpizza i searched web and tried different things, could not come-up with another solution. sorry for that. – Ozgur Bagci Jun 06 '20 at 14:28
  • thank you for taking the time to look into it! much appreciated! – ccpizza Jun 06 '20 at 14:29
1

There is more simple way that doesn't depend using external utilities and just uses sys module. Here is code:

import sys
is_android: bool = hasattr(sys, 'getandroidapilevel')

Here are it's pros and cons:

@@Pros@@
 + Does not depend on environment values
 + Does not depend on third-party modules
 + Simple one-liner (2 technically)

@@Cons@@
 - Version restriction (Supports CPython 3.7+ or equivalent)
 - Implementation-dependent (while CPython implements this I don't know about others)
UltraStudioLTD
  • 300
  • 2
  • 14
  • I've seen ANDROID_DATA used for this too. It would be good to make a list of the default environment contents of different terminal emulators and sdks like kivy or beeware. – fuzzyTew Nov 29 '21 at 08:37
  • @fuzzyTew It's not always a good idea to use Environmental Variables for detection since it is easily removable. Better upgrade to CPython 3.7+ and use built-in function detection. – UltraStudioLTD Nov 29 '21 at 12:32
  • I was actually in a situation where I was handling kivy and/or termux in third party code only written for one or the other, so the ability to remove environment variables helped in ton. – fuzzyTew Nov 29 '21 at 19:40
  • Yes, since it is unsafe to rely on them except certain situations. :) – UltraStudioLTD Nov 29 '21 at 20:59
  • [makes a mental note to be sure to add version detection to his hack] – fuzzyTew Nov 29 '21 at 21:19
  • What version detection? CPython's? – UltraStudioLTD Nov 29 '21 at 21:33
  • 1
    I just meant that you're clearly in the right here about environment variables being a poor choice when there's another option. In my use-case, I'm tricking underlying libraries that made that poor choice. It's not actually safe unless I verify that every version of the library used engages the exact environment variables I'm using, document the behavior clearly for users to debug problems with, and file issue reports upstream. The version detection would be of any dependency packages whose unsafe behavior I'm relying on. – fuzzyTew Nov 29 '21 at 21:41
  • @UltraStudioLTD: if you post the `hasattr(sys, 'getandroidapilevel')` as a separate answer then I'll mark it as accepted (for python3.x); accepting the current 2-in-1 answer would falsely imply that the env keys is the way to go which would be misleading as it's a _works-by-accident_ scenario. – ccpizza Dec 11 '22 at 09:24
  • 1
    @ccpizza what if I removed first answer and left only second? – UltraStudioLTD Dec 11 '22 at 16:16