Android
Fleeting- External reference: https://en.wikipedia.org/wiki/Android_10
tools
-
External reference: https://developer.android.com/studio/run/emulator-acceleration?hl=fr
Using the tooling installed by buildozer, otherwise:
adb screenrecord
to play with apk: aapt
install the sdk
It can be downloaded from https://developer.android.com/studio (go to the bottom of the page)
https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip
I prefer using nixos and a custom flake to download what I need automatically.
missing the avd folder
the avdmanager respects the XDG_CONFIG HOME but the emulator does not. This leads to avdmanager create putting avds in some path and emulator not finding it.
test graphical interfaces
Permission Denial
java.lang.SecurityException: Permission Denial: starting Intent The full error description usually looks like ‘java.lang.SecurityException: Permission Denial: starting Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.mypackage/.myactivity.MainActivity launchParam=MultiScreenLaunchParams { mDisplayId=0 mBaseDisplayId=0 mFlags=0 } } from null (pid=11366, uid=2000) not exported from uid 10191. Such error might be the indication of the fact that the combination of application package and activity name, which has been passed to Appium as appPackage/appActivity (or auto detected implicitly), is not the correct one to start the application under test
— https://github.com/appium/appium/blob/1.x/docs/en/writing-running-appium/android/activity-startup.md
appium
- External reference: http://appium.io/docs/en/2.4/quickstart/uiauto2-driver
- External reference: http://appium.io/docs/en/2.4/quickstart/install/
appium driver install uiautomator2
— http://appium.io/docs/en/2.4/quickstart/uiauto2-driver/#prepare-the-device
npm i -g appium
ANDROID_SERIAL=emulator-5554 appium
pip install Appium-Python-Client
speed up the starting
additional_options = {
"skipDeviceInitialization": not self.first_time,
"skipServerInstallation": not self.first_time,
"disableWindowAnimation": self.first_time,
}
It still takes some time to kill the previous run of the uiautomator2 server and start it again.
start session calls this.cleanupAutomationLeftovers
that in turn stops the server https://github.com/appium/appium-uiautomator2-driver/blob/25eeea068a1928dec32af5ac7744a967b385bf3a/lib/uiautomator2.js#L376
before starting it again https://github.com/appium/appium-uiautomator2-driver/blob/25eeea068a1928dec32af5ac7744a967b385bf3a/lib/uiautomator2.js#L241
socket hang up error
-
External reference: https://stackoverflow.com/questions/60275181/getting-socket-hang-up-error-while-running-appium-scripts-using-windows-os
Rebooting the device helped me, not just closing it and opening again, but selecting “Cold boot Now” option in Vertual Device Manager for Android studio
Change the systemPort desired capability of the appium. (ex. change from 8200 to 8210)
uiautomator2
Needs at least android 5
A lot of sites say that some uiautomatorviewer tool exist. But so far, I could not find any proof of its existence, even downloading the sdk and android studio for linux and windows.
uiautomatorviewer
uiautomatorviewer
Developer Assistant APK
- External reference: https://apkcombo.com/developer-assistant/com.appsisle.developerassistant/download/apk
Developer Assistant_1.2.2_apkcombo.com.apk
(
TMP="$(mktemp -d)"
trap "rm -rf '${TMP}'" 0
ipfs get -o "${TMP}/assistant.apk" https://konubinix.eu/ipfs/bafybeialb27i7yjaqdh2g4hswv4vqc5o7cl4gr5ubk7vkpelc275lqhs7u
adb -s emulator-5554 install "${TMP}/assistant.apk"
)
sdkmanager
The sdkmanager is quite touchy. It needs to be called in a specific directory and specifying the root.
cd ~/.buildozer/android/platform/android-sdk/tools
./bin/sdkmanager --list --sdk_root=..
avdmanager
avdmanager list
To find the possible package to give to avd create
sdkmanager --list | gi system-images
[...]
system-images;android-34;google_apis;x86_64 | 12 | Google APIs Intel x86_64 Atom System Image
[...]
Then
sdkmanager --install 'system-images;android-34;google_apis;x86_64
avdmanager create avd --device 9 --name test --package "system-images;android-34;google_apis;x86_64"
L’émulateur opère de manière optimale s’il peut utiliser le matériel de votre ordinateur, tel que le processeur, le GPU et le modem, au lieu de fonctionner comme un logiciel pur
— https://developer.android.com/studio/run/emulator-acceleration?hl=fr
appareils Android ont recours à OpenGL for Embedded Systems (OpenGL ES ou GLES) pour le rendu des graphismes 2D et 3D à l’écran.
— https://developer.android.com/studio/run/emulator-acceleration?hl=fr
L’accélération matérielle, qui est généralement plus rapide, est recommandée. Toutefois, vous devrez peut-être recourir à l’accélération logicielle si votre ordinateur utilise des pilotes graphiques non compatibles avec l’émulateur.
— https://developer.android.com/studio/run/emulator-acceleration?hl=fr
Si vous démarrez l’émulateur à partir de la ligne de commande, vous pouvez forcer le paramètre d’accélération graphique de l’AVD correspondant à cette instance d’appareil virtuel
— https://developer.android.com/studio/run/emulator-acceleration?hl=fr
Pour spécifier un type d’accélération graphique lorsque vous exécutez un AVD à partir de la ligne de commande, incluez l’option -gpu, comme illustré dans l’exemple suivant :
emulator -avd avd_name -gpu mode [{-option [value]} … ]
La valeur de
— https://developer.android.com/studio/run/emulator-acceleration?hl=fr
Lorsque vous utilisez des images pour le niveau d’API 27 ou supérieur, l’émulateur peut afficher l’UI Android avec Skia. Skia aide l’émulateur à afficher les graphiques de manière plus fluide et plus efficace.
Pour activer le rendu Skia, utilisez les commandes suivantes dans le shell adb : su setprop debug.hwui.renderer skiagl stop start
— https://developer.android.com/studio/run/emulator-acceleration?hl=fr
emulator
sdkmanager --install emulator
May need to sudo apt install libx11-dev to get libx11.so
Using the name of the avd installed with avdmanager (see above).
emulator -avd test -qemu -enable-kvm -gpu host
INFO | Android emulator version 33.1.24.0 (build_id 11237101) (CL:N/A)
INFO | AVD test has path /home/sam/.android/avd/../avd/test.avd
INFO | trying to check whether /home/sam/.buildozer/android/platform/android-sdk is a valid sdk root
WARNING | /home/sam/.buildozer/android/platform/android-sdk/android-sdk/system-images/android-34/google_apis/x86_64/ is not a valid directory.
WARNING | emulator has searched the above paths but found no valid sdk root directory.
PANIC: Broken AVD system path. Check your ANDROID_SDK_ROOT value [/home/sam/.buildozer/android/platform/android-sdk]!
Strange. Hopefully, this can be easily circumvented
ln -s ~/.buildozer/android/platform/android-sdk ~/.buildozer/android/platform/android-sdk/android-sdk
Also, to enable keyboard in the avd
sed -i 's/hw.keyboard = no/hw.keyboard = yes/' ~/.android/avd/test.avd/config.ini
If the emulator restarted
adb disconnect emulator-5554
run in x11vnc
x11vnc -create -nopw -gone 'pkill -f "qemu-system-x86_64 -avd test" -SIGTERM' -env X11VNC_FINDDISPLAY_ALWAYS_FAILS=1 -env FD_PROG="emulator -avd test"
Then, on the remote side
xtightvncviewer localhost:5900
This uses xvfb under the hood
The good thing here is that the application starts only when connecting to the vnc server, not before.
This is not enough, as closing the window won’t send SIGTERM to the running emulator.
run in xvfb
apktool to play with the content of an apk
Extract some apk with
apktool d my.apk
It creates the folder my
Then, make some changes, then
apktool b my
The new apk is in the my/dist/
folder
Connect Android to PC using debian and udev :
- Get the code of the constructor
- either get the code from http://developer.android.com/tools/device.html
- or find the line [.] usb .: New USB device found, idVendor=04e8, . in the output of dmesg when you plug the phone. (for the example, my samsung phone indicates the vendor 04e8)
- create an udev rule for the android phone when it plugs in
- edit the new file /etc/udev/rules.d/50-android.rules and put into it SUBSYSTEM==“usb”, ATTR{idVendor}==“04e8”, MODE=“0666”, GROUP=“plugdev”
- restart udev with
service udev restart
- re plug the phone
4
- Seems too old to have a decent alarmclock
- hard to run a python runtime on android,
5
7
8.1
10
Android 10 (codenamed Android Q during development)
11
13
automation (with adb)
adb exec-out screencap -p > screen.png adb shell input keyevent keycode # voir les keycodes ici https://developer.android.com/reference/android/view/KeyEvent adb shell input tap x y adb shell input text letexte adb shell getevent -l # pour récup une macro adb shell sendevent <periph de getevent> adb shell input swipe 224 548 $((0x000001dd)) $((0x00000206)) # some times you have to reverse x and y
scrcpy
use the developer option to see the interraction on the screen then try and error with several swipes adb shell input swipe 200 200 200 300
adb shell input keyevent KEYCODE_POWER adb shell input keyevent KEYCODE_BACK
A method to get what I want
https://stackoverflow.com/questions/25363526/fire-a-pinch-in-out-command-to-android-phone-using-adb
kill an active application
-
External reference: https://stackoverflow.com/questions/31079853/how-do-i-kill-all-active-tasks-apps-using-adb
adb shell am force-stop <PACKAGE>
— https://stackoverflow.com/questions/31079853/how-do-i-kill-all-active-tasks-apps-using-adb
launch activity
am start -n yourpackagename/.activityname
— https://stackoverflow.com/questions/13380590/is-it-possible-to-start-activity-through-adb-shell
find available activities
adb shell pm list packages -f Then you can use adb pull:
adb pull <APK path from previous command> and then aapt to get the information you want:
aapt dump badging <pulledfile.apk>
— https://stackoverflow.com/questions/12698814/get-launchable-activity-name-of-package-from-adb
example with slightbackup
clk android adb shell pm list packages -f|gi slightba
package:/data/app/de.shandschuh.slightbackup-AtJUMUgaD889KHasQ8QaKg==/base.apk=de.shandschuh.slightbackup
TMP="$(mktemp -d)"
trap "rm -rf '${TMP}'" 0
cd "${TMP}"
clk android adb pull /data/app/de.shandschuh.slightbackup-AtJUMUgaD889KHasQ8QaKg==/base.apk
aapt dump badging base.apk | gi launchable-activity
/data/app/de.shandschuh.slightbackup-AtJUMUgaD889KHasQ8QaKg==/base.apk: 1 file pulled, 0 skipped. 1.9 MB/s (78433 bytes in 0.040s)
launchable-activity: name='de.shandschuh.slightbackup.BackupActivity' label='Slight backup' icon=
clk android adb shell am start -n 'de.shandschuh.slightbackup/.BackupActivity
Starting: Intent { cmp=de.shandschuh.slightbackup/.BackupActivity }
keep my screen unlocked during USB debugging?
-
External reference: https://stackoverflow.com/questions/8840954/how-do-i-keep-my-screen-unlocked-during-usb-debugging
svc power stayon usb
— https://stackoverflow.com/questions/8840954/how-do-i-keep-my-screen-unlocked-during-usb-debugging
change display brightness using adb
-
External reference: https://lynxbee.com/how-to-change-android-display-brightness-using-adb-command/
settings get system screen_brightness
— https://lynxbee.com/how-to-change-android-display-brightness-using-adb-command/
settings put system screen_brightness 200
— https://lynxbee.com/how-to-change-android-display-brightness-using-adb-command/
get the Android device screen size from the adb command line?
-
External reference: https://stackoverflow.com/questions/7527459/how-to-get-the-android-device-screen-size-from-the-adb-command-line
adb shell wm size
hacks
provide permissions (like camera or sdcard)
clk android -d klipad adb shell pm grant eu.konubinix.konixpoc android.permission.CAMERA clk android -d klipad adb shell pm grant eu.konubinix.konixpoc android.permission.WRITE_EXTERNAL_STORAGE
note that with android 11 scoped storage, sdcard storage is granted using
clk android adb shell appops set –uid eu.konubinix.konixpoc MANAGE_EXTERNAL_STORAGE allow
change fullscreen settings
see doing again, with old python2 kivy, to reuse my wiko cink peax apktool d app.apk change in ./app/AndroidManifest.xml the android theme to be android:theme="@android:style/Theme.NoTitleBar.Fullscreen" apktool b app keytool -genkeypair -keystore your-keystore.jks -storepass 000000 -keypass 000000 -alias your-alias -dname “CN=Your Name, OU=Your Unit, O=Your Organization, L=Your City, ST=Your State, C=Your Country” -keyalg RSA -keysize 2048 -validity 10000 apksigner sign –ks your-keystore.jks –ks-key-alias your-alias –ks-pass pass:000000 ./app/dist/app.apk now, ./app/dist/app.apk is ready
Alternatively, from the code
from jnius import autoclass
from android import mActivity
from android.runnable import run_on_ui_thread
View = autoclass('android.view.View')
option = View.SYSTEM_UI_FLAG_FULLSCREEN
@run_on_ui_thread
def fs():
mActivity.getWindow().getDecorView().setSystemUiVisibility(option)
fs()
Quit it using the SYSTEM_UI_FLAG_VISIBLE option
permanent adb over wifi by adding “service.adb.tcp.port=5555” into “/system/build.prop”
enable wakelock
see a legacy from another lifetime <meta-data android:name=“wakelock” android:value=“1”/>
from jnius import autoclass
from android import mActivity
# in a service, use instead of mActivity
# PythonService = autoclass('org.kivy.android.PythonService')
# PythonService.mService
PowerManager = autoclass('android.os.PowerManager')
Context = autoclass('android.content.Context')
WindowManager = autoclass('android.view.WindowManager')
pm = mActivity.getSystemService(Context.POWER_SERVICE)
self.wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, 'simplecamera:screen-awake')
self.wl.acquire()
And later, self.wl.release()
SCREEN_DIM_WAKE_LOCK (and supposedly deprecated for FLAG_ALLOW_LOCK_WHILE_SCREEN_ON) to simply dim, worked well on android 4
<<enable-wakelock>>
record audio
def record(self):
plyer.audio.file_path = "/sdcard/truc.3gp"
plyer.audio.start()
Clock.schedule_once(lambda a: plyer.audio.stop(), 5)
keep screen on
All wakelock that keep the screen on have been deprecated a long time ago, in favor of this way of doing.
from android import mActivity
from jnius import autoclass
from android.runnable import run_on_ui_thread
LayoutParams = autoclass('android.view.WindowManager$LayoutParams')
@run_on_ui_thread
def do():
mActivity.getWindow().addFlags(LayoutParams.FLAG_KEEP_SCREEN_ON)
do()
# clear with
mActivity.getWindow().clearFlags(LayoutParams.FLAG_KEEP_SCREEN_ON)
wake up the screen from a service
A service cannot access the window, hence cannot use keep screen on
But it can make use of SCREEN_BRIGHT_WAKE_LOCK and ACQUIRE_CAUSES_WAKEUP
from jnius import autoclass
PythonService = autoclass('org.kivy.android.PythonService')
PowerManager = autoclass('android.os.PowerManager')
Context = autoclass('android.content.Context')
WindowManager = autoclass('android.view.WindowManager')
pm = PythonService.mService.getSystemService(Context.POWER_SERVICE)
wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, 'simple awakening')
wl.acquire()
wl.release() # I can release it as soon as it was acquired, because it was only to wake the phone
That way, anything that needs the UI to be refreshed can still work.
keep doing something even when the screen is off
Tested on android 4. Even with a PARTIAL_WAKE_LOCK, the front application will stop its processing when the screen goes off.
It apparently does not impact stuff that already run when the screen goes of, for instance
while True:
time.sleep(2)
print("a")
Will continue working, same if ran in threading.Thread(target=myfunction).start
But the Clock.schedule_interval and anything related to the UI will stop working, until the screen gets back on.
Also, I don’t know if I need to enable a wake lock here, but doing it in the service would look like this
from jnius import autoclass
PowerManager = autoclass('android.os.PowerManager')
Context = autoclass('android.content.Context')
PythonService = autoclass('org.kivy.android.PythonService')
pm = PythonService.mService.getSystemService(Context.POWER_SERVICE)
wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, 'do something')
wl.acquire()
access the camera to record a video
using MediaRecorder and CamcorderProfile
from jnius import autoclass
MediaRecorder = autoclass('android.media.MediaRecorder')
Camera = autoclass("android.hardware.Camera")
AudioSource = autoclass('android.media.MediaRecorder$AudioSource')
VideoSource = autoclass('android.media.MediaRecorder$VideoSource')
OutputFormat = autoclass('android.media.MediaRecorder$OutputFormat')
AudioEncoder = autoclass('android.media.MediaRecorder$AudioEncoder')
VideoEncoder = autoclass('android.media.MediaRecorder$VideoEncoder')
CamcorderProfile = autoclass('android.media.CamcorderProfile')
# see https://developer.android.com/reference/android/media/CamcorderProfile
from kivy.core.camera import Camera
camera = Camera(
resolution=(640, 480),
index=0, # index=1 for front camera (in general)
)
recorder = MediaRecorder()
camera._android_camera.unlock()
recorder.setCamera(camera._android_camera)
recorder.setAudioSource(AudioSource.MIC)
recorder.setVideoSource(VideoSource.CAMERA)
profile = CamcorderProfile.get(CamcorderProfile.QUALITY_VGA)
recorder.setProfile(profile)
# or
#recorder.setOutputFormat(OutputFormat.DEFAULT)
#recorder.setAudioEncoder(AudioEncoder.DEFAULT)
#recorder.setVideoEncoder(VideoEncoder.DEFAULT)
recorder.setOutputFile("/sdcard/v.mp4")
recorder.prepare()
recorder.start()
print("started")
import time
time.sleep(5)
print("done")
recorder.stop()
recorder.release()
access the camera to take pictures
see digging a bit the old phone idea: create a timelapse
tested on android 4 : it cannot be done in a service and needs the screen to be on, even very dimmed
also on android 4, the camera returns bad images when the screen is off, even if using PARTIAL_WAKE_LOCK and a thread to get the images.
A compromise to take photos continuously, but save battery by keeping the screen off most of the time can be to
- create a wakelock of type PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP
- run the routine in a thread that
- acquire the wakelock
- grab the frame
- release the wakelock
see digging a bit the old phone idea: create a timelapse to see an example of this.
keep the the screen on, but very dimmed
If for some reason you need to keep the screen on, but at the lowest brightness
Supposedly you should be able to keep screen on with FLAG_ALLOW_LOCK_WHILE_SCREEN_ON to simply dim, but did not work on android 4
Combine the SCREEN_DIM_WAKE_LOCK wakelock and set the brightness
from jnius import autoclass
from android import mActivity
from android.runnable import run_on_ui_thread
WindowManagerLayoutParams = autoclass('android.view.WindowManager$LayoutParams')
window = mActivity.getWindow()
# Adjust the brightness level (0.0 to 1.0, where 0.0 is the minimum)
layout_params = window.getAttributes()
layout_params.screenBrightness = 0.01 # Minimum brightness
@run_on_ui_thread
def do():
window.setAttributes(layout_params)
do()
Tested only on android 4, where brightness == 0 actually put the application to sleep
Also, you can try plyer.brightness.set_level(1)
change the orientation
from plyer import orientation
orientation.set_landscape()
Put this at the root boxlayout of you application
With a legacy from another lifetime, it tends to often freeze the application. Prefer editing the manifest
android:screenOrientation="portrait"
and repackage the application (see from the python android runtime to a custom app)
useful apks
termux
- see,
connectbot
simplesshd
https://www.galexander.org/software/simplesshd/ (https://f-droid.org/en/packages/org.galexander.sshd/)
TMP="$(mktemp -d)"
trap "rm -rf '${TMP}'" 0
gpg --export-ssh-key konubinix > "${TMP}/authorized_keys"
scp -P 2222 "${TMP}/authorized_keys" 192.168.1.192:
sshdroid
https://apkpure.com/sshdroid/berserker.android.apps.sshdroid/downloading (/ipfs/bafybeigwd4nxu7xwd34la5ce3jzu43ezbie7fp7p3cw3q22zaqjukucul4?filename=SSHDroid_2.1.2_APKPure.apk) in case simplesshd is not possible (android 4)
ssh -o HostKeyAlgorithms=+ssh-rsa -o KexAlgorithms=+diffie-hellman-group14-sha1 root@192.168.1.36 does not deal with authorized_keys, but works with “sshpass -p admin ssh cinkpeax”
Notes linking here
- 15 : android 8.1
- a legacy from another lifetime (blog)
- a python runtime on android (blog)
- accessing localhost:port from Android emulator
- adb save shortcuts
- aiortc to create a remote web camera with an android phone
- allow installed PWAs to add widgets to Android homescreen
- android 11 key character map vs keylayout vs whyred to use bépo
- android find the am start command to run the application in focus with the correct intent
- API Levels | Android versions, SDK/API levels, version codes, codenames, and cumulative usage
- applications - Where Android apps store data?
- attempt to control it
- back to stock
- bluetooth in Android
- bubblewrap
- budtmo/docker-android
- bépo-android
- CamcorderProfile
- chromium
- clk android backup
- connect android and a board with a single microcontroller
- connect to a wiimote
- debug web on android using adb
- develop an android application using keycloak and localhost redirection
- digging a bit the old phone idea: create a timelapse (blog)
- doing again, with old python2 kivy, to reuse my wiko cink peax
- flutter
- for android 5
- for android 7
- go2rtc to use an android device as webcam
- how to control my old android devices
- lineage os 14
- lineage os 20
- neo-backup
- OBB in android
- PairWiimote android
- parrot sumo
- PowerManager | Android Developers
- Some adb commands to change setting for battery optimisation, start service, stop service, grant permission, revoke permission and etc.
- stopmotion android apps
- timelapse
- use the camera with kivy on android (blog)
- using a PWA in your Android app
- wiko cink peax 2
- zte blade s6 (p839f30)