From bc13bdbfd1b8f50b7bd53c48e253e3539435d3ff Mon Sep 17 00:00:00 2001 From: "River@devbox" Date: Mon, 16 Mar 2026 12:05:30 +0800 Subject: [PATCH 01/32] Deploy site - 2026-03-16 12:05:29 --- CNAME | 1 + agreement-cn.html | 47 + agreement.html | 45 + deploy.sh | 91 + en/404.html | 2081 +++++ en/assets/images/favicon.png | Bin 0 -> 1870 bytes en/assets/javascripts/bundle.79ae519e.min.js | 16 + .../javascripts/bundle.79ae519e.min.js.map | 7 + en/assets/javascripts/lunr/min/lunr.ar.min.js | 1 + en/assets/javascripts/lunr/min/lunr.da.min.js | 18 + en/assets/javascripts/lunr/min/lunr.de.min.js | 18 + en/assets/javascripts/lunr/min/lunr.du.min.js | 18 + en/assets/javascripts/lunr/min/lunr.el.min.js | 1 + en/assets/javascripts/lunr/min/lunr.es.min.js | 18 + en/assets/javascripts/lunr/min/lunr.fi.min.js | 18 + en/assets/javascripts/lunr/min/lunr.fr.min.js | 18 + en/assets/javascripts/lunr/min/lunr.he.min.js | 1 + en/assets/javascripts/lunr/min/lunr.hi.min.js | 1 + en/assets/javascripts/lunr/min/lunr.hu.min.js | 18 + en/assets/javascripts/lunr/min/lunr.hy.min.js | 1 + en/assets/javascripts/lunr/min/lunr.it.min.js | 18 + en/assets/javascripts/lunr/min/lunr.ja.min.js | 1 + en/assets/javascripts/lunr/min/lunr.jp.min.js | 1 + en/assets/javascripts/lunr/min/lunr.kn.min.js | 1 + en/assets/javascripts/lunr/min/lunr.ko.min.js | 1 + .../javascripts/lunr/min/lunr.multi.min.js | 1 + en/assets/javascripts/lunr/min/lunr.nl.min.js | 18 + en/assets/javascripts/lunr/min/lunr.no.min.js | 18 + en/assets/javascripts/lunr/min/lunr.pt.min.js | 18 + en/assets/javascripts/lunr/min/lunr.ro.min.js | 18 + en/assets/javascripts/lunr/min/lunr.ru.min.js | 18 + en/assets/javascripts/lunr/min/lunr.sa.min.js | 1 + .../lunr/min/lunr.stemmer.support.min.js | 1 + en/assets/javascripts/lunr/min/lunr.sv.min.js | 18 + en/assets/javascripts/lunr/min/lunr.ta.min.js | 1 + en/assets/javascripts/lunr/min/lunr.te.min.js | 1 + en/assets/javascripts/lunr/min/lunr.th.min.js | 1 + en/assets/javascripts/lunr/min/lunr.tr.min.js | 18 + en/assets/javascripts/lunr/min/lunr.vi.min.js | 1 + en/assets/javascripts/lunr/min/lunr.zh.min.js | 1 + en/assets/javascripts/lunr/tinyseg.js | 206 + en/assets/javascripts/lunr/wordcut.js | 6708 +++++++++++++++++ .../workers/search.2c215733.min.js | 42 + .../workers/search.2c215733.min.js.map | 7 + en/assets/stylesheets/main.484c7ddc.min.css | 1 + .../stylesheets/main.484c7ddc.min.css.map | 1 + .../stylesheets/palette.ab4e12ef.min.css | 1 + .../stylesheets/palette.ab4e12ef.min.css.map | 1 + en/editor-guide/index.html | 2270 ++++++ en/external-api/index.html | 2299 ++++++ en/getting-started/index.html | 2838 +++++++ en/index.html | 2350 ++++++ en/qpypi-guide/index.html | 2322 ++++++ en/qpython-x/index.html | 2283 ++++++ en/qsl4a/connectivity/location/index.html | 2411 ++++++ en/qsl4a/connectivity/sms/index.html | 2483 ++++++ en/qsl4a/connectivity/wifi/index.html | 2768 +++++++ en/qsl4a/core/android-base/index.html | 2655 +++++++ en/qsl4a/core/events/index.html | 2869 +++++++ en/qsl4a/core/intent/index.html | 2872 +++++++ en/qsl4a/hardware/bluetooth/index.html | 2918 +++++++ en/qsl4a/hardware/camera/index.html | 2762 +++++++ en/qsl4a/hardware/recorder/index.html | 2582 +++++++ en/qsl4a/index.html | 2524 +++++++ en/qsl4a/media/image/index.html | 2508 ++++++ en/qsl4a/media/mediaplayer/index.html | 2757 +++++++ en/qsl4a/special/cipher/index.html | 2634 +++++++ en/qsl4a/special/pgptai/index.html | 2468 ++++++ en/qsl4a/storage/clipboard/index.html | 2322 ++++++ en/qsl4a/storage/documentfile/index.html | 2847 +++++++ en/qsl4a/system/application/index.html | 3119 ++++++++ en/qsl4a/system/battery/index.html | 2465 ++++++ en/qsl4a/system/sensors/index.html | 2545 +++++++ en/qsl4a/system/sysinfo/index.html | 2563 +++++++ en/qsl4a/ui/accessibility/index.html | 2615 +++++++ en/qsl4a/ui/dialogs/index.html | 3395 +++++++++ en/qsl4a/ui/floatview/index.html | 2620 +++++++ en/qsl4a/ui/fullscreen/index.html | 2751 +++++++ en/search/search_index.json | 1 + en/sitemap.xml | 131 + en/sitemap.xml.gz | Bin 0 -> 467 bytes en/static/1.png | Bin 0 -> 335197 bytes en/static/2.png | Bin 0 -> 515124 bytes en/static/3.png | Bin 0 -> 437751 bytes en/static/bestpython.png | Bin 0 -> 96668 bytes en/static/extra.css | 133 + en/static/googledrive-.png | Bin 0 -> 56166 bytes en/static/googledrive.jpg | Bin 0 -> 77208 bytes en/static/guide_extend_pic1.png | Bin 0 -> 111129 bytes en/static/guide_extend_pic2.png | Bin 0 -> 69027 bytes en/static/guide_helloworld_pic1.png | Bin 0 -> 44906 bytes en/static/guide_howtostart_pic1.png | Bin 0 -> 31834 bytes en/static/guide_howtostart_pic2.png | Bin 0 -> 46752 bytes en/static/guide_howtostart_pic3.png | Bin 0 -> 97920 bytes en/static/guide_howtostart_pic4.png | Bin 0 -> 51908 bytes en/static/guide_howtostart_pic5.png | Bin 0 -> 101580 bytes en/static/guide_ide_qedit4web.png | Bin 0 -> 42256 bytes en/static/guide_ide_qedit4web_choose.png | Bin 0 -> 200543 bytes en/static/guide_ide_qedit4web_develop.png | Bin 0 -> 70950 bytes en/static/guide_program_pic1.png | Bin 0 -> 45040 bytes en/static/img_banner2x.jpg | Bin 0 -> 48932 bytes en/static/img_logo.png | Bin 0 -> 376 bytes en/static/sl4a.jpg | Bin 0 -> 1437 bytes en/static/taskerplugin-for-qpython.png | Bin 0 -> 18485 bytes en/static/wecomdrive-.png | Bin 0 -> 56368 bytes en/static/wecomdrive.jpg | Bin 0 -> 17066 bytes en/tutorial-hello-world/index.html | 2310 ++++++ en/whats-new/index.html | 2656 +++++++ huawei.html | 3 + index.html | 63 + privacy-cn.html | 80 + privacy.html | 100 + qlua-privacy.html | 69 + qlua-rate.html | 1 + qq.html | 3 + xiaomi.html | 3 + zh/404.html | 411 + zh/assets/images/favicon.png | Bin 0 -> 1870 bytes zh/assets/javascripts/bundle.79ae519e.min.js | 16 + .../javascripts/bundle.79ae519e.min.js.map | 7 + zh/assets/javascripts/lunr/min/lunr.ar.min.js | 1 + zh/assets/javascripts/lunr/min/lunr.da.min.js | 18 + zh/assets/javascripts/lunr/min/lunr.de.min.js | 18 + zh/assets/javascripts/lunr/min/lunr.du.min.js | 18 + zh/assets/javascripts/lunr/min/lunr.el.min.js | 1 + zh/assets/javascripts/lunr/min/lunr.es.min.js | 18 + zh/assets/javascripts/lunr/min/lunr.fi.min.js | 18 + zh/assets/javascripts/lunr/min/lunr.fr.min.js | 18 + zh/assets/javascripts/lunr/min/lunr.he.min.js | 1 + zh/assets/javascripts/lunr/min/lunr.hi.min.js | 1 + zh/assets/javascripts/lunr/min/lunr.hu.min.js | 18 + zh/assets/javascripts/lunr/min/lunr.hy.min.js | 1 + zh/assets/javascripts/lunr/min/lunr.it.min.js | 18 + zh/assets/javascripts/lunr/min/lunr.ja.min.js | 1 + zh/assets/javascripts/lunr/min/lunr.jp.min.js | 1 + zh/assets/javascripts/lunr/min/lunr.kn.min.js | 1 + zh/assets/javascripts/lunr/min/lunr.ko.min.js | 1 + .../javascripts/lunr/min/lunr.multi.min.js | 1 + zh/assets/javascripts/lunr/min/lunr.nl.min.js | 18 + zh/assets/javascripts/lunr/min/lunr.no.min.js | 18 + zh/assets/javascripts/lunr/min/lunr.pt.min.js | 18 + zh/assets/javascripts/lunr/min/lunr.ro.min.js | 18 + zh/assets/javascripts/lunr/min/lunr.ru.min.js | 18 + zh/assets/javascripts/lunr/min/lunr.sa.min.js | 1 + .../lunr/min/lunr.stemmer.support.min.js | 1 + zh/assets/javascripts/lunr/min/lunr.sv.min.js | 18 + zh/assets/javascripts/lunr/min/lunr.ta.min.js | 1 + zh/assets/javascripts/lunr/min/lunr.te.min.js | 1 + zh/assets/javascripts/lunr/min/lunr.th.min.js | 1 + zh/assets/javascripts/lunr/min/lunr.tr.min.js | 18 + zh/assets/javascripts/lunr/min/lunr.vi.min.js | 1 + zh/assets/javascripts/lunr/min/lunr.zh.min.js | 1 + zh/assets/javascripts/lunr/tinyseg.js | 206 + zh/assets/javascripts/lunr/wordcut.js | 6708 +++++++++++++++++ .../workers/search.2c215733.min.js | 42 + .../workers/search.2c215733.min.js.map | 7 + zh/assets/stylesheets/main.484c7ddc.min.css | 1 + .../stylesheets/main.484c7ddc.min.css.map | 1 + .../stylesheets/palette.ab4e12ef.min.css | 1 + .../stylesheets/palette.ab4e12ef.min.css.map | 1 + zh/index.html | 675 ++ zh/search/search_index.json | 1 + zh/sitemap.xml | 7 + zh/sitemap.xml.gz | Bin 0 -> 184 bytes zh/static/1.png | Bin 0 -> 335197 bytes zh/static/2.png | Bin 0 -> 515124 bytes zh/static/3.png | Bin 0 -> 437751 bytes zh/static/bestpython.png | Bin 0 -> 96668 bytes zh/static/extra.css | 133 + zh/static/googledrive-.png | Bin 0 -> 56166 bytes zh/static/googledrive.jpg | Bin 0 -> 77208 bytes zh/static/guide_extend_pic1.png | Bin 0 -> 111129 bytes zh/static/guide_extend_pic2.png | Bin 0 -> 69027 bytes zh/static/guide_helloworld_pic1.png | Bin 0 -> 44906 bytes zh/static/guide_howtostart_pic1.png | Bin 0 -> 31834 bytes zh/static/guide_howtostart_pic2.png | Bin 0 -> 46752 bytes zh/static/guide_howtostart_pic3.png | Bin 0 -> 97920 bytes zh/static/guide_howtostart_pic4.png | Bin 0 -> 51908 bytes zh/static/guide_howtostart_pic5.png | Bin 0 -> 101580 bytes zh/static/guide_ide_qedit4web.png | Bin 0 -> 42256 bytes zh/static/guide_ide_qedit4web_choose.png | Bin 0 -> 200543 bytes zh/static/guide_ide_qedit4web_develop.png | Bin 0 -> 70950 bytes zh/static/guide_program_pic1.png | Bin 0 -> 45040 bytes zh/static/img_banner2x.jpg | Bin 0 -> 48932 bytes zh/static/img_logo.png | Bin 0 -> 376 bytes zh/static/sl4a.jpg | Bin 0 -> 1437 bytes zh/static/taskerplugin-for-qpython.png | Bin 0 -> 18485 bytes zh/static/wecomdrive-.png | Bin 0 -> 56368 bytes zh/static/wecomdrive.jpg | Bin 0 -> 17066 bytes 189 files changed, 102414 insertions(+) create mode 100644 CNAME create mode 100644 agreement-cn.html create mode 100644 agreement.html create mode 100755 deploy.sh create mode 100644 en/404.html create mode 100644 en/assets/images/favicon.png create mode 100644 en/assets/javascripts/bundle.79ae519e.min.js create mode 100644 en/assets/javascripts/bundle.79ae519e.min.js.map create mode 100644 en/assets/javascripts/lunr/min/lunr.ar.min.js create mode 100644 en/assets/javascripts/lunr/min/lunr.da.min.js create mode 100644 en/assets/javascripts/lunr/min/lunr.de.min.js create mode 100644 en/assets/javascripts/lunr/min/lunr.du.min.js create mode 100644 en/assets/javascripts/lunr/min/lunr.el.min.js create mode 100644 en/assets/javascripts/lunr/min/lunr.es.min.js create mode 100644 en/assets/javascripts/lunr/min/lunr.fi.min.js create mode 100644 en/assets/javascripts/lunr/min/lunr.fr.min.js create mode 100644 en/assets/javascripts/lunr/min/lunr.he.min.js create mode 100644 en/assets/javascripts/lunr/min/lunr.hi.min.js create mode 100644 en/assets/javascripts/lunr/min/lunr.hu.min.js create mode 100644 en/assets/javascripts/lunr/min/lunr.hy.min.js create mode 100644 en/assets/javascripts/lunr/min/lunr.it.min.js create mode 100644 en/assets/javascripts/lunr/min/lunr.ja.min.js create mode 100644 en/assets/javascripts/lunr/min/lunr.jp.min.js create mode 100644 en/assets/javascripts/lunr/min/lunr.kn.min.js create mode 100644 en/assets/javascripts/lunr/min/lunr.ko.min.js create mode 100644 en/assets/javascripts/lunr/min/lunr.multi.min.js create mode 100644 en/assets/javascripts/lunr/min/lunr.nl.min.js create mode 100644 en/assets/javascripts/lunr/min/lunr.no.min.js create mode 100644 en/assets/javascripts/lunr/min/lunr.pt.min.js create mode 100644 en/assets/javascripts/lunr/min/lunr.ro.min.js create mode 100644 en/assets/javascripts/lunr/min/lunr.ru.min.js create mode 100644 en/assets/javascripts/lunr/min/lunr.sa.min.js create mode 100644 en/assets/javascripts/lunr/min/lunr.stemmer.support.min.js create mode 100644 en/assets/javascripts/lunr/min/lunr.sv.min.js create mode 100644 en/assets/javascripts/lunr/min/lunr.ta.min.js create mode 100644 en/assets/javascripts/lunr/min/lunr.te.min.js create mode 100644 en/assets/javascripts/lunr/min/lunr.th.min.js create mode 100644 en/assets/javascripts/lunr/min/lunr.tr.min.js create mode 100644 en/assets/javascripts/lunr/min/lunr.vi.min.js create mode 100644 en/assets/javascripts/lunr/min/lunr.zh.min.js create mode 100644 en/assets/javascripts/lunr/tinyseg.js create mode 100644 en/assets/javascripts/lunr/wordcut.js create mode 100644 en/assets/javascripts/workers/search.2c215733.min.js create mode 100644 en/assets/javascripts/workers/search.2c215733.min.js.map create mode 100644 en/assets/stylesheets/main.484c7ddc.min.css create mode 100644 en/assets/stylesheets/main.484c7ddc.min.css.map create mode 100644 en/assets/stylesheets/palette.ab4e12ef.min.css create mode 100644 en/assets/stylesheets/palette.ab4e12ef.min.css.map create mode 100644 en/editor-guide/index.html create mode 100644 en/external-api/index.html create mode 100644 en/getting-started/index.html create mode 100644 en/index.html create mode 100644 en/qpypi-guide/index.html create mode 100644 en/qpython-x/index.html create mode 100644 en/qsl4a/connectivity/location/index.html create mode 100644 en/qsl4a/connectivity/sms/index.html create mode 100644 en/qsl4a/connectivity/wifi/index.html create mode 100644 en/qsl4a/core/android-base/index.html create mode 100644 en/qsl4a/core/events/index.html create mode 100644 en/qsl4a/core/intent/index.html create mode 100644 en/qsl4a/hardware/bluetooth/index.html create mode 100644 en/qsl4a/hardware/camera/index.html create mode 100644 en/qsl4a/hardware/recorder/index.html create mode 100644 en/qsl4a/index.html create mode 100644 en/qsl4a/media/image/index.html create mode 100644 en/qsl4a/media/mediaplayer/index.html create mode 100644 en/qsl4a/special/cipher/index.html create mode 100644 en/qsl4a/special/pgptai/index.html create mode 100644 en/qsl4a/storage/clipboard/index.html create mode 100644 en/qsl4a/storage/documentfile/index.html create mode 100644 en/qsl4a/system/application/index.html create mode 100644 en/qsl4a/system/battery/index.html create mode 100644 en/qsl4a/system/sensors/index.html create mode 100644 en/qsl4a/system/sysinfo/index.html create mode 100644 en/qsl4a/ui/accessibility/index.html create mode 100644 en/qsl4a/ui/dialogs/index.html create mode 100644 en/qsl4a/ui/floatview/index.html create mode 100644 en/qsl4a/ui/fullscreen/index.html create mode 100644 en/search/search_index.json create mode 100644 en/sitemap.xml create mode 100644 en/sitemap.xml.gz create mode 100644 en/static/1.png create mode 100644 en/static/2.png create mode 100644 en/static/3.png create mode 100644 en/static/bestpython.png create mode 100644 en/static/extra.css create mode 100644 en/static/googledrive-.png create mode 100644 en/static/googledrive.jpg create mode 100644 en/static/guide_extend_pic1.png create mode 100644 en/static/guide_extend_pic2.png create mode 100644 en/static/guide_helloworld_pic1.png create mode 100644 en/static/guide_howtostart_pic1.png create mode 100644 en/static/guide_howtostart_pic2.png create mode 100644 en/static/guide_howtostart_pic3.png create mode 100644 en/static/guide_howtostart_pic4.png create mode 100644 en/static/guide_howtostart_pic5.png create mode 100644 en/static/guide_ide_qedit4web.png create mode 100644 en/static/guide_ide_qedit4web_choose.png create mode 100644 en/static/guide_ide_qedit4web_develop.png create mode 100644 en/static/guide_program_pic1.png create mode 100644 en/static/img_banner2x.jpg create mode 100644 en/static/img_logo.png create mode 100644 en/static/sl4a.jpg create mode 100644 en/static/taskerplugin-for-qpython.png create mode 100644 en/static/wecomdrive-.png create mode 100644 en/static/wecomdrive.jpg create mode 100644 en/tutorial-hello-world/index.html create mode 100644 en/whats-new/index.html create mode 100644 huawei.html create mode 100644 index.html create mode 100644 privacy-cn.html create mode 100644 privacy.html create mode 100644 qlua-privacy.html create mode 100644 qlua-rate.html create mode 100644 qq.html create mode 100644 xiaomi.html create mode 100644 zh/404.html create mode 100644 zh/assets/images/favicon.png create mode 100644 zh/assets/javascripts/bundle.79ae519e.min.js create mode 100644 zh/assets/javascripts/bundle.79ae519e.min.js.map create mode 100644 zh/assets/javascripts/lunr/min/lunr.ar.min.js create mode 100644 zh/assets/javascripts/lunr/min/lunr.da.min.js create mode 100644 zh/assets/javascripts/lunr/min/lunr.de.min.js create mode 100644 zh/assets/javascripts/lunr/min/lunr.du.min.js create mode 100644 zh/assets/javascripts/lunr/min/lunr.el.min.js create mode 100644 zh/assets/javascripts/lunr/min/lunr.es.min.js create mode 100644 zh/assets/javascripts/lunr/min/lunr.fi.min.js create mode 100644 zh/assets/javascripts/lunr/min/lunr.fr.min.js create mode 100644 zh/assets/javascripts/lunr/min/lunr.he.min.js create mode 100644 zh/assets/javascripts/lunr/min/lunr.hi.min.js create mode 100644 zh/assets/javascripts/lunr/min/lunr.hu.min.js create mode 100644 zh/assets/javascripts/lunr/min/lunr.hy.min.js create mode 100644 zh/assets/javascripts/lunr/min/lunr.it.min.js create mode 100644 zh/assets/javascripts/lunr/min/lunr.ja.min.js create mode 100644 zh/assets/javascripts/lunr/min/lunr.jp.min.js create mode 100644 zh/assets/javascripts/lunr/min/lunr.kn.min.js create mode 100644 zh/assets/javascripts/lunr/min/lunr.ko.min.js create mode 100644 zh/assets/javascripts/lunr/min/lunr.multi.min.js create mode 100644 zh/assets/javascripts/lunr/min/lunr.nl.min.js create mode 100644 zh/assets/javascripts/lunr/min/lunr.no.min.js create mode 100644 zh/assets/javascripts/lunr/min/lunr.pt.min.js create mode 100644 zh/assets/javascripts/lunr/min/lunr.ro.min.js create mode 100644 zh/assets/javascripts/lunr/min/lunr.ru.min.js create mode 100644 zh/assets/javascripts/lunr/min/lunr.sa.min.js create mode 100644 zh/assets/javascripts/lunr/min/lunr.stemmer.support.min.js create mode 100644 zh/assets/javascripts/lunr/min/lunr.sv.min.js create mode 100644 zh/assets/javascripts/lunr/min/lunr.ta.min.js create mode 100644 zh/assets/javascripts/lunr/min/lunr.te.min.js create mode 100644 zh/assets/javascripts/lunr/min/lunr.th.min.js create mode 100644 zh/assets/javascripts/lunr/min/lunr.tr.min.js create mode 100644 zh/assets/javascripts/lunr/min/lunr.vi.min.js create mode 100644 zh/assets/javascripts/lunr/min/lunr.zh.min.js create mode 100644 zh/assets/javascripts/lunr/tinyseg.js create mode 100644 zh/assets/javascripts/lunr/wordcut.js create mode 100644 zh/assets/javascripts/workers/search.2c215733.min.js create mode 100644 zh/assets/javascripts/workers/search.2c215733.min.js.map create mode 100644 zh/assets/stylesheets/main.484c7ddc.min.css create mode 100644 zh/assets/stylesheets/main.484c7ddc.min.css.map create mode 100644 zh/assets/stylesheets/palette.ab4e12ef.min.css create mode 100644 zh/assets/stylesheets/palette.ab4e12ef.min.css.map create mode 100644 zh/index.html create mode 100644 zh/search/search_index.json create mode 100644 zh/sitemap.xml create mode 100644 zh/sitemap.xml.gz create mode 100644 zh/static/1.png create mode 100644 zh/static/2.png create mode 100644 zh/static/3.png create mode 100644 zh/static/bestpython.png create mode 100644 zh/static/extra.css create mode 100644 zh/static/googledrive-.png create mode 100644 zh/static/googledrive.jpg create mode 100644 zh/static/guide_extend_pic1.png create mode 100644 zh/static/guide_extend_pic2.png create mode 100644 zh/static/guide_helloworld_pic1.png create mode 100644 zh/static/guide_howtostart_pic1.png create mode 100644 zh/static/guide_howtostart_pic2.png create mode 100644 zh/static/guide_howtostart_pic3.png create mode 100644 zh/static/guide_howtostart_pic4.png create mode 100644 zh/static/guide_howtostart_pic5.png create mode 100644 zh/static/guide_ide_qedit4web.png create mode 100644 zh/static/guide_ide_qedit4web_choose.png create mode 100644 zh/static/guide_ide_qedit4web_develop.png create mode 100644 zh/static/guide_program_pic1.png create mode 100644 zh/static/img_banner2x.jpg create mode 100644 zh/static/img_logo.png create mode 100644 zh/static/sl4a.jpg create mode 100644 zh/static/taskerplugin-for-qpython.png create mode 100644 zh/static/wecomdrive-.png create mode 100644 zh/static/wecomdrive.jpg diff --git a/CNAME b/CNAME new file mode 100644 index 0000000..4632497 --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +www.qpython.org diff --git a/agreement-cn.html b/agreement-cn.html new file mode 100644 index 0000000..dbdf8b4 --- /dev/null +++ b/agreement-cn.html @@ -0,0 +1,47 @@ + + + + + + + 用户使用协议 + + + +

用户使用协议

1. 特别提示 +

1.1为使用本手机应用软件及服务,您应当阅读并遵守《用户使用协议》(以下简称“本协议”)。请您务必审慎阅读、充分理解各条款内容,特别是免除或者限制责任的条款,以及同意或使用某项服务的单独协议,并选择接受或不接受。 +

1.2 除非您已阅读并接受本协议所有条款,否则您无权下载、安装或使用本软件及相关服务。您的下载、安装、使用、获取账号、登录等行为即视为您已阅读并同意上述协议的约束。 +

1.3 QPYTHON(以下称“QPYTHON”)同意按照本协议的规定及其不时发布的操作规则提供基于互联网的相关服务(以下称"本服务")。若您需要获得本服务,您(以下称"用户")应当同意本协议的全部条款并按照页面上的提示完成全部的申请程序。 +

+ + +

2. 协议适用主体范围

+ 本协议是用户与本公司之间关于用户下载、安装、使用、复制本软件,以及使用本公司相关服务所订立的协议。 +

+ QPYTHON在网站上公布的服务条款及用户所参加课程的招生方案和班次协议等是本协议的补充。本协议与上述内容存在冲突的,以本协议为准。 本协议内容同时包括QPYTHON可能不断发布的关于本服务的相关协议、业务规则等内容。上述内容一经正式发布,即为本协议不可分割的组成部分,用户若继续使用本公司软件及服务同样应当遵守。 +

+

3. 服务内容与授权使用范围

+

本软件根据用户实际需求提供服务,例如编程工具、在线QPYPI。QPYTHON保留随时变更、中断或终止部分或全部本服务的权利。 +

+

本软件手机应用的授权使用范围:用户可以在手机上安装、使用、显示、运行本软件。 +

+

保留权利:未明示授权的其他一切权利均由本公司所有。

+ +

3. 使用规则

+

用户在使用本软件时,必须遵循以下原则:
+ 遵守你所在国的有关的法律和法规; +
+ 不得为任何非法目的而使用本服务系统;
+ 遵守所有与本服务有关的网络协议、规定和程序;
+ 不得利用本软件系统进行任何可能对互联网的正常运转造成不利影响的行为;
+ 不得利用本软件服务系统进行任何不利于其他用户的行为;
+ 如发现任何非法使用用户账号或账号出现安全漏洞的情况, 应立即通知QPYTHON官方 + +

+

4. 知识产权

+

本软件的作者为严河存, 而QPYTHON的商标权、专利权、商业秘密等知识产权,以及与本软件相关的所有信息内容(包括但不限于视频课件、文字、图片、音频、图表、界面设计、版面框架、有关数据或电子文档等)均属于River授权的北京优趣天下信息技术有限公司,北京优趣天下信息技术有限公司享有上述知识产权,除非事先经本公司的合法授权,任何人皆不得擅自以任何形式使用,否则我们可立即终止向该用户提供产品和服务,并依法追究其法律责任,赔偿本QPYTHON的一切损失。

+ + + + + diff --git a/agreement.html b/agreement.html new file mode 100644 index 0000000..078dd7b --- /dev/null +++ b/agreement.html @@ -0,0 +1,45 @@ + + + + + + User Agreement + + + +

User Agreement

1. Special Tips +

1.1 In order to use this mobile application software and services, you should read and abide by the "User Agreement" (hereinafter referred to as "this Agreement"). Please be sure to carefully read and fully understand the contents of each clause, especially the clauses exempting or limiting liability, as well as separate agreements for agreeing to or using a certain service, and choose to accept or not accept it. +

1.2 Unless you have read and accepted all the terms of this agreement, you have no right to download, install or use this software and related services. Your downloading, installation, use, account acquisition, login, etc. are deemed to have read and agreed to be bound by the above agreement. +

1.3 QPYTHON (hereinafter referred to as "QPYTHON") agrees to provide Internet-based related services (hereinafter referred to as the "Service") in accordance with the provisions of this Agreement and its operating rules published from time to time. If you need to obtain this service, you (hereinafter referred to as "User") should agree to all the terms of this agreement and complete the entire application process according to the prompts on the page. +

+ + +

2. Scope of application of the agreement

+ This agreement is an agreement between the user and the company regarding the user's downloading, installation, use, copying of this software, and use of the company's related services. +

+ The terms of service published by QPYTHON on the website and the enrollment plans and class agreements for courses attended by users are supplements to this agreement. If there is any conflict between this Agreement and the above content, this Agreement shall prevail. The content of this agreement also includes relevant agreements, business rules, etc. regarding this service that QPYTHON may publish from time to time. Once the above content is officially released, it will become an integral part of this agreement. Users must also abide by it if they continue to use the company's software and services. +

+

3. Service content and authorized use scope

+

This software provides services based on the actual needs of users, such as programming tools and online QPYPI. QPYTHON reserves the right to change, interrupt or terminate part or all of this service at any time. +

+

The authorized use scope of this software’s mobile application: Users can install, use, display, and run this software on their mobile phones. +

+

Reserved rights: All other rights not expressly authorized are owned by our company.

+ +

3. Rules of use

+

Users must follow the following principles when using this software:
+ Comply with the relevant laws and regulations of your country; +
+ This service system may not be used for any illegal purpose;
+ Comply with all network protocols, regulations and procedures related to the Service;
+ This software system may not be used to conduct any behavior that may adversely affect the normal operation of the Internet;
+ You may not use this software service system to conduct any behavior that is detrimental to other users;
+ If you discover any illegal use of user accounts or account security vulnerabilities, you should immediately notify QPYTHON officials. + +

+

4. Intellectual Property

+

The author of this software is Yan Hecun, and QPYTHON’s trademark rights, patent rights, trade secrets and other knowledge The property rights, as well as all information content related to this software (including but not limited to video courseware, text, pictures, audio, charts, interface design, layout framework, relevant data or electronic documents, etc.) belong to Beijing Youqutianxia Information authorized by River. Technology Co., Ltd. and Beijing Youqutianxia Information Technology Co., Ltd. enjoy the above intellectual property rights. Unless legally authorized by the company in advance, no one may use it in any form without authorization. Otherwise, we may immediately terminate the provision of products and services to the user, and Investigate its legal liability in accordance with the law and compensate QPYTHON for all losses.

+ + + + diff --git a/deploy.sh b/deploy.sh new file mode 100755 index 0000000..4195983 --- /dev/null +++ b/deploy.sh @@ -0,0 +1,91 @@ +#!/bin/bash + +# Deploy script for QPython documentation +# Builds the site and deploys to gh-pages branch + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +# Run build first +echo "Building site..." +./build.sh + +# Check if git repository +if [ ! -d .git ]; then + echo "Error: Not a git repository" + exit 1 +fi + +# Get current branch +CURRENT_BRANCH=$(git branch --show-current) +echo "Current branch: $CURRENT_BRANCH" + +# Check if there are uncommitted changes +if ! git diff-index --quiet HEAD --; then + echo "Warning: You have uncommitted changes. Please commit them first." + echo "Uncommitted files:" + git status --short + read -p "Do you want to continue anyway? (y/N) " -n 1 -r + echo + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + echo "Aborted." + exit 1 + fi +fi + +# Deploy to gh-pages +echo "" +echo "Deploying to gh-pages branch..." + +# Create a temporary directory for the site +TEMP_DIR=$(mktemp -d) +cp -r site/* "$TEMP_DIR/" + +# Switch to gh-pages branch (create if doesn't exist) +if git show-ref --verify --quiet refs/heads/gh-pages; then + git checkout gh-pages +else + git checkout --orphan gh-pages + git rm -rf . -- ':!deploy.sh' +fi + +# Remove old files (except .git and deploy.sh) +find . -maxdepth 1 ! -name '.git' ! -name 'deploy.sh' ! -name '.' ! -name '..' -exec rm -rf {} \; + +# Copy new site content +cp -r "$TEMP_DIR"/* . + +# Add all files +git add -A + +# Commit +COMMIT_MSG="Deploy site - $(date '+%Y-%m-%d %H:%M:%S')" +if git diff --cached --quiet; then + echo "No changes to commit" +else + git commit -m "$COMMIT_MSG" + echo "Committed: $COMMIT_MSG" +fi + +# Push to remote with force (gh-pages is safe to force push) +read -p "Push to origin/gh-pages? (y/N) " -n 1 -r +echo +if [[ $REPLY =~ ^[Yy]$ ]]; then + git push origin gh-pages --force + echo "" + echo "Deployed successfully!" + echo "Site will be available at: https://qpython-android.github.io/qpython.org/" +else + echo "Push aborted. You can push manually with: git push origin gh-pages --force" +fi + +# Cleanup +rm -rf "$TEMP_DIR" + +# Switch back to original branch +git checkout "$CURRENT_BRANCH" + +echo "" +echo "Done!" diff --git a/en/404.html b/en/404.html new file mode 100644 index 0000000..5b7bd0d --- /dev/null +++ b/en/404.html @@ -0,0 +1,2081 @@ + + + + + + + + + + + + + + + + + + + + + + + + QPython + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ +
+ +

404 - Not found

+ +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/en/assets/images/favicon.png b/en/assets/images/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..1cf13b9f9d978896599290a74f77d5dbe7d1655c GIT binary patch literal 1870 zcmV-U2eJ5xP)Gc)JR9QMau)O=X#!i9;T z37kk-upj^(fsR36MHs_+1RCI)NNu9}lD0S{B^g8PN?Ww(5|~L#Ng*g{WsqleV}|#l zz8@ri&cTzw_h33bHI+12+kK6WN$h#n5cD8OQt`5kw6p~9H3()bUQ8OS4Q4HTQ=1Ol z_JAocz`fLbT2^{`8n~UAo=#AUOf=SOq4pYkt;XbC&f#7lb$*7=$na!mWCQ`dBQsO0 zLFBSPj*N?#u5&pf2t4XjEGH|=pPQ8xh7tpx;US5Cx_Ju;!O`ya-yF`)b%TEt5>eP1ZX~}sjjA%FJF?h7cX8=b!DZl<6%Cv z*G0uvvU+vmnpLZ2paivG-(cd*y3$hCIcsZcYOGh{$&)A6*XX&kXZd3G8m)G$Zz-LV z^GF3VAW^Mdv!)4OM8EgqRiz~*Cji;uzl2uC9^=8I84vNp;ltJ|q-*uQwGp2ma6cY7 z;`%`!9UXO@fr&Ebapfs34OmS9^u6$)bJxrucutf>`dKPKT%%*d3XlFVKunp9 zasduxjrjs>f8V=D|J=XNZp;_Zy^WgQ$9WDjgY=z@stwiEBm9u5*|34&1Na8BMjjgf3+SHcr`5~>oz1Y?SW^=K z^bTyO6>Gar#P_W2gEMwq)ot3; zREHn~U&Dp0l6YT0&k-wLwYjb?5zGK`W6S2v+K>AM(95m2C20L|3m~rN8dprPr@t)5lsk9Hu*W z?pS990s;Ez=+Rj{x7p``4>+c0G5^pYnB1^!TL=(?HLHZ+HicG{~4F1d^5Awl_2!1jICM-!9eoLhbbT^;yHcefyTAaqRcY zmuctDopPT!%k+}x%lZRKnzykr2}}XfG_ne?nRQO~?%hkzo;@RN{P6o`&mMUWBYMTe z6i8ChtjX&gXl`nvrU>jah)2iNM%JdjqoaeaU%yVn!^70x-flljp6Q5tK}5}&X8&&G zX3fpb3E(!rH=zVI_9Gjl45w@{(ITqngWFe7@9{mX;tO25Z_8 zQHEpI+FkTU#4xu>RkN>b3Tnc3UpWzPXWm#o55GKF09j^Mh~)K7{QqbO_~(@CVq! zS<8954|P8mXN2MRs86xZ&Q4EfM@JB94b=(YGuk)s&^jiSF=t3*oNK3`rD{H`yQ?d; ztE=laAUoZx5?RC8*WKOj`%LXEkgDd>&^Q4M^z`%u0rg-It=hLCVsq!Z%^6eB-OvOT zFZ28TN&cRmgU}Elrnk43)!>Z1FCPL2K$7}gwzIc48NX}#!A1BpJP?#v5wkNprhV** z?Cpalt1oH&{r!o3eSKc&ap)iz2BTn_VV`4>9M^b3;(YY}4>#ML6{~(4mH+?%07*qo IM6N<$f(jP3KmY&$ literal 0 HcmV?d00001 diff --git a/en/assets/javascripts/bundle.79ae519e.min.js b/en/assets/javascripts/bundle.79ae519e.min.js new file mode 100644 index 0000000..3df3e5e --- /dev/null +++ b/en/assets/javascripts/bundle.79ae519e.min.js @@ -0,0 +1,16 @@ +"use strict";(()=>{var Zi=Object.create;var _r=Object.defineProperty;var ea=Object.getOwnPropertyDescriptor;var ta=Object.getOwnPropertyNames,Bt=Object.getOwnPropertySymbols,ra=Object.getPrototypeOf,Ar=Object.prototype.hasOwnProperty,bo=Object.prototype.propertyIsEnumerable;var ho=(e,t,r)=>t in e?_r(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,P=(e,t)=>{for(var r in t||(t={}))Ar.call(t,r)&&ho(e,r,t[r]);if(Bt)for(var r of Bt(t))bo.call(t,r)&&ho(e,r,t[r]);return e};var vo=(e,t)=>{var r={};for(var o in e)Ar.call(e,o)&&t.indexOf(o)<0&&(r[o]=e[o]);if(e!=null&&Bt)for(var o of Bt(e))t.indexOf(o)<0&&bo.call(e,o)&&(r[o]=e[o]);return r};var Cr=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var oa=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of ta(t))!Ar.call(e,n)&&n!==r&&_r(e,n,{get:()=>t[n],enumerable:!(o=ea(t,n))||o.enumerable});return e};var $t=(e,t,r)=>(r=e!=null?Zi(ra(e)):{},oa(t||!e||!e.__esModule?_r(r,"default",{value:e,enumerable:!0}):r,e));var go=(e,t,r)=>new Promise((o,n)=>{var i=c=>{try{a(r.next(c))}catch(p){n(p)}},s=c=>{try{a(r.throw(c))}catch(p){n(p)}},a=c=>c.done?o(c.value):Promise.resolve(c.value).then(i,s);a((r=r.apply(e,t)).next())});var xo=Cr((kr,yo)=>{(function(e,t){typeof kr=="object"&&typeof yo!="undefined"?t():typeof define=="function"&&define.amd?define(t):t()})(kr,(function(){"use strict";function e(r){var o=!0,n=!1,i=null,s={text:!0,search:!0,url:!0,tel:!0,email:!0,password:!0,number:!0,date:!0,month:!0,week:!0,time:!0,datetime:!0,"datetime-local":!0};function a(k){return!!(k&&k!==document&&k.nodeName!=="HTML"&&k.nodeName!=="BODY"&&"classList"in k&&"contains"in k.classList)}function c(k){var ut=k.type,je=k.tagName;return!!(je==="INPUT"&&s[ut]&&!k.readOnly||je==="TEXTAREA"&&!k.readOnly||k.isContentEditable)}function p(k){k.classList.contains("focus-visible")||(k.classList.add("focus-visible"),k.setAttribute("data-focus-visible-added",""))}function l(k){k.hasAttribute("data-focus-visible-added")&&(k.classList.remove("focus-visible"),k.removeAttribute("data-focus-visible-added"))}function f(k){k.metaKey||k.altKey||k.ctrlKey||(a(r.activeElement)&&p(r.activeElement),o=!0)}function u(k){o=!1}function d(k){a(k.target)&&(o||c(k.target))&&p(k.target)}function v(k){a(k.target)&&(k.target.classList.contains("focus-visible")||k.target.hasAttribute("data-focus-visible-added"))&&(n=!0,window.clearTimeout(i),i=window.setTimeout(function(){n=!1},100),l(k.target))}function S(k){document.visibilityState==="hidden"&&(n&&(o=!0),X())}function X(){document.addEventListener("mousemove",ee),document.addEventListener("mousedown",ee),document.addEventListener("mouseup",ee),document.addEventListener("pointermove",ee),document.addEventListener("pointerdown",ee),document.addEventListener("pointerup",ee),document.addEventListener("touchmove",ee),document.addEventListener("touchstart",ee),document.addEventListener("touchend",ee)}function re(){document.removeEventListener("mousemove",ee),document.removeEventListener("mousedown",ee),document.removeEventListener("mouseup",ee),document.removeEventListener("pointermove",ee),document.removeEventListener("pointerdown",ee),document.removeEventListener("pointerup",ee),document.removeEventListener("touchmove",ee),document.removeEventListener("touchstart",ee),document.removeEventListener("touchend",ee)}function ee(k){k.target.nodeName&&k.target.nodeName.toLowerCase()==="html"||(o=!1,re())}document.addEventListener("keydown",f,!0),document.addEventListener("mousedown",u,!0),document.addEventListener("pointerdown",u,!0),document.addEventListener("touchstart",u,!0),document.addEventListener("visibilitychange",S,!0),X(),r.addEventListener("focus",d,!0),r.addEventListener("blur",v,!0),r.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&r.host?r.host.setAttribute("data-js-focus-visible",""):r.nodeType===Node.DOCUMENT_NODE&&(document.documentElement.classList.add("js-focus-visible"),document.documentElement.setAttribute("data-js-focus-visible",""))}if(typeof window!="undefined"&&typeof document!="undefined"){window.applyFocusVisiblePolyfill=e;var t;try{t=new CustomEvent("focus-visible-polyfill-ready")}catch(r){t=document.createEvent("CustomEvent"),t.initCustomEvent("focus-visible-polyfill-ready",!1,!1,{})}window.dispatchEvent(t)}typeof document!="undefined"&&e(document)}))});var ro=Cr((jy,Rn)=>{"use strict";/*! + * escape-html + * Copyright(c) 2012-2013 TJ Holowaychuk + * Copyright(c) 2015 Andreas Lubbe + * Copyright(c) 2015 Tiancheng "Timothy" Gu + * MIT Licensed + */var qa=/["'&<>]/;Rn.exports=Ka;function Ka(e){var t=""+e,r=qa.exec(t);if(!r)return t;var o,n="",i=0,s=0;for(i=r.index;i{/*! + * clipboard.js v2.0.11 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */(function(t,r){typeof Nt=="object"&&typeof io=="object"?io.exports=r():typeof define=="function"&&define.amd?define([],r):typeof Nt=="object"?Nt.ClipboardJS=r():t.ClipboardJS=r()})(Nt,function(){return(function(){var e={686:(function(o,n,i){"use strict";i.d(n,{default:function(){return Xi}});var s=i(279),a=i.n(s),c=i(370),p=i.n(c),l=i(817),f=i.n(l);function u(q){try{return document.execCommand(q)}catch(C){return!1}}var d=function(C){var _=f()(C);return u("cut"),_},v=d;function S(q){var C=document.documentElement.getAttribute("dir")==="rtl",_=document.createElement("textarea");_.style.fontSize="12pt",_.style.border="0",_.style.padding="0",_.style.margin="0",_.style.position="absolute",_.style[C?"right":"left"]="-9999px";var D=window.pageYOffset||document.documentElement.scrollTop;return _.style.top="".concat(D,"px"),_.setAttribute("readonly",""),_.value=q,_}var X=function(C,_){var D=S(C);_.container.appendChild(D);var N=f()(D);return u("copy"),D.remove(),N},re=function(C){var _=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body},D="";return typeof C=="string"?D=X(C,_):C instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(C==null?void 0:C.type)?D=X(C.value,_):(D=f()(C),u("copy")),D},ee=re;function k(q){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?k=function(_){return typeof _}:k=function(_){return _&&typeof Symbol=="function"&&_.constructor===Symbol&&_!==Symbol.prototype?"symbol":typeof _},k(q)}var ut=function(){var C=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},_=C.action,D=_===void 0?"copy":_,N=C.container,G=C.target,We=C.text;if(D!=="copy"&&D!=="cut")throw new Error('Invalid "action" value, use either "copy" or "cut"');if(G!==void 0)if(G&&k(G)==="object"&&G.nodeType===1){if(D==="copy"&&G.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if(D==="cut"&&(G.hasAttribute("readonly")||G.hasAttribute("disabled")))throw new Error(`Invalid "target" attribute. You can't cut text from elements with "readonly" or "disabled" attributes`)}else throw new Error('Invalid "target" value, use a valid Element');if(We)return ee(We,{container:N});if(G)return D==="cut"?v(G):ee(G,{container:N})},je=ut;function R(q){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?R=function(_){return typeof _}:R=function(_){return _&&typeof Symbol=="function"&&_.constructor===Symbol&&_!==Symbol.prototype?"symbol":typeof _},R(q)}function se(q,C){if(!(q instanceof C))throw new TypeError("Cannot call a class as a function")}function ce(q,C){for(var _=0;_0&&arguments[0]!==void 0?arguments[0]:{};this.action=typeof N.action=="function"?N.action:this.defaultAction,this.target=typeof N.target=="function"?N.target:this.defaultTarget,this.text=typeof N.text=="function"?N.text:this.defaultText,this.container=R(N.container)==="object"?N.container:document.body}},{key:"listenClick",value:function(N){var G=this;this.listener=p()(N,"click",function(We){return G.onClick(We)})}},{key:"onClick",value:function(N){var G=N.delegateTarget||N.currentTarget,We=this.action(G)||"copy",Yt=je({action:We,container:this.container,target:this.target(G),text:this.text(G)});this.emit(Yt?"success":"error",{action:We,text:Yt,trigger:G,clearSelection:function(){G&&G.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(N){return Mr("action",N)}},{key:"defaultTarget",value:function(N){var G=Mr("target",N);if(G)return document.querySelector(G)}},{key:"defaultText",value:function(N){return Mr("text",N)}},{key:"destroy",value:function(){this.listener.destroy()}}],[{key:"copy",value:function(N){var G=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body};return ee(N,G)}},{key:"cut",value:function(N){return v(N)}},{key:"isSupported",value:function(){var N=arguments.length>0&&arguments[0]!==void 0?arguments[0]:["copy","cut"],G=typeof N=="string"?[N]:N,We=!!document.queryCommandSupported;return G.forEach(function(Yt){We=We&&!!document.queryCommandSupported(Yt)}),We}}]),_})(a()),Xi=Ji}),828:(function(o){var n=9;if(typeof Element!="undefined"&&!Element.prototype.matches){var i=Element.prototype;i.matches=i.matchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.oMatchesSelector||i.webkitMatchesSelector}function s(a,c){for(;a&&a.nodeType!==n;){if(typeof a.matches=="function"&&a.matches(c))return a;a=a.parentNode}}o.exports=s}),438:(function(o,n,i){var s=i(828);function a(l,f,u,d,v){var S=p.apply(this,arguments);return l.addEventListener(u,S,v),{destroy:function(){l.removeEventListener(u,S,v)}}}function c(l,f,u,d,v){return typeof l.addEventListener=="function"?a.apply(null,arguments):typeof u=="function"?a.bind(null,document).apply(null,arguments):(typeof l=="string"&&(l=document.querySelectorAll(l)),Array.prototype.map.call(l,function(S){return a(S,f,u,d,v)}))}function p(l,f,u,d){return function(v){v.delegateTarget=s(v.target,f),v.delegateTarget&&d.call(l,v)}}o.exports=c}),879:(function(o,n){n.node=function(i){return i!==void 0&&i instanceof HTMLElement&&i.nodeType===1},n.nodeList=function(i){var s=Object.prototype.toString.call(i);return i!==void 0&&(s==="[object NodeList]"||s==="[object HTMLCollection]")&&"length"in i&&(i.length===0||n.node(i[0]))},n.string=function(i){return typeof i=="string"||i instanceof String},n.fn=function(i){var s=Object.prototype.toString.call(i);return s==="[object Function]"}}),370:(function(o,n,i){var s=i(879),a=i(438);function c(u,d,v){if(!u&&!d&&!v)throw new Error("Missing required arguments");if(!s.string(d))throw new TypeError("Second argument must be a String");if(!s.fn(v))throw new TypeError("Third argument must be a Function");if(s.node(u))return p(u,d,v);if(s.nodeList(u))return l(u,d,v);if(s.string(u))return f(u,d,v);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function p(u,d,v){return u.addEventListener(d,v),{destroy:function(){u.removeEventListener(d,v)}}}function l(u,d,v){return Array.prototype.forEach.call(u,function(S){S.addEventListener(d,v)}),{destroy:function(){Array.prototype.forEach.call(u,function(S){S.removeEventListener(d,v)})}}}function f(u,d,v){return a(document.body,u,d,v)}o.exports=c}),817:(function(o){function n(i){var s;if(i.nodeName==="SELECT")i.focus(),s=i.value;else if(i.nodeName==="INPUT"||i.nodeName==="TEXTAREA"){var a=i.hasAttribute("readonly");a||i.setAttribute("readonly",""),i.select(),i.setSelectionRange(0,i.value.length),a||i.removeAttribute("readonly"),s=i.value}else{i.hasAttribute("contenteditable")&&i.focus();var c=window.getSelection(),p=document.createRange();p.selectNodeContents(i),c.removeAllRanges(),c.addRange(p),s=c.toString()}return s}o.exports=n}),279:(function(o){function n(){}n.prototype={on:function(i,s,a){var c=this.e||(this.e={});return(c[i]||(c[i]=[])).push({fn:s,ctx:a}),this},once:function(i,s,a){var c=this;function p(){c.off(i,p),s.apply(a,arguments)}return p._=s,this.on(i,p,a)},emit:function(i){var s=[].slice.call(arguments,1),a=((this.e||(this.e={}))[i]||[]).slice(),c=0,p=a.length;for(c;c0&&i[i.length-1])&&(p[0]===6||p[0]===2)){r=0;continue}if(p[0]===3&&(!i||p[1]>i[0]&&p[1]=e.length&&(e=void 0),{value:e&&e[o++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function K(e,t){var r=typeof Symbol=="function"&&e[Symbol.iterator];if(!r)return e;var o=r.call(e),n,i=[],s;try{for(;(t===void 0||t-- >0)&&!(n=o.next()).done;)i.push(n.value)}catch(a){s={error:a}}finally{try{n&&!n.done&&(r=o.return)&&r.call(o)}finally{if(s)throw s.error}}return i}function B(e,t,r){if(r||arguments.length===2)for(var o=0,n=t.length,i;o1||c(d,S)})},v&&(n[d]=v(n[d])))}function c(d,v){try{p(o[d](v))}catch(S){u(i[0][3],S)}}function p(d){d.value instanceof dt?Promise.resolve(d.value.v).then(l,f):u(i[0][2],d)}function l(d){c("next",d)}function f(d){c("throw",d)}function u(d,v){d(v),i.shift(),i.length&&c(i[0][0],i[0][1])}}function To(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t=e[Symbol.asyncIterator],r;return t?t.call(e):(e=typeof Oe=="function"?Oe(e):e[Symbol.iterator](),r={},o("next"),o("throw"),o("return"),r[Symbol.asyncIterator]=function(){return this},r);function o(i){r[i]=e[i]&&function(s){return new Promise(function(a,c){s=e[i](s),n(a,c,s.done,s.value)})}}function n(i,s,a,c){Promise.resolve(c).then(function(p){i({value:p,done:a})},s)}}function I(e){return typeof e=="function"}function yt(e){var t=function(o){Error.call(o),o.stack=new Error().stack},r=e(t);return r.prototype=Object.create(Error.prototype),r.prototype.constructor=r,r}var Jt=yt(function(e){return function(r){e(this),this.message=r?r.length+` errors occurred during unsubscription: +`+r.map(function(o,n){return n+1+") "+o.toString()}).join(` + `):"",this.name="UnsubscriptionError",this.errors=r}});function Ze(e,t){if(e){var r=e.indexOf(t);0<=r&&e.splice(r,1)}}var qe=(function(){function e(t){this.initialTeardown=t,this.closed=!1,this._parentage=null,this._finalizers=null}return e.prototype.unsubscribe=function(){var t,r,o,n,i;if(!this.closed){this.closed=!0;var s=this._parentage;if(s)if(this._parentage=null,Array.isArray(s))try{for(var a=Oe(s),c=a.next();!c.done;c=a.next()){var p=c.value;p.remove(this)}}catch(S){t={error:S}}finally{try{c&&!c.done&&(r=a.return)&&r.call(a)}finally{if(t)throw t.error}}else s.remove(this);var l=this.initialTeardown;if(I(l))try{l()}catch(S){i=S instanceof Jt?S.errors:[S]}var f=this._finalizers;if(f){this._finalizers=null;try{for(var u=Oe(f),d=u.next();!d.done;d=u.next()){var v=d.value;try{So(v)}catch(S){i=i!=null?i:[],S instanceof Jt?i=B(B([],K(i)),K(S.errors)):i.push(S)}}}catch(S){o={error:S}}finally{try{d&&!d.done&&(n=u.return)&&n.call(u)}finally{if(o)throw o.error}}}if(i)throw new Jt(i)}},e.prototype.add=function(t){var r;if(t&&t!==this)if(this.closed)So(t);else{if(t instanceof e){if(t.closed||t._hasParent(this))return;t._addParent(this)}(this._finalizers=(r=this._finalizers)!==null&&r!==void 0?r:[]).push(t)}},e.prototype._hasParent=function(t){var r=this._parentage;return r===t||Array.isArray(r)&&r.includes(t)},e.prototype._addParent=function(t){var r=this._parentage;this._parentage=Array.isArray(r)?(r.push(t),r):r?[r,t]:t},e.prototype._removeParent=function(t){var r=this._parentage;r===t?this._parentage=null:Array.isArray(r)&&Ze(r,t)},e.prototype.remove=function(t){var r=this._finalizers;r&&Ze(r,t),t instanceof e&&t._removeParent(this)},e.EMPTY=(function(){var t=new e;return t.closed=!0,t})(),e})();var $r=qe.EMPTY;function Xt(e){return e instanceof qe||e&&"closed"in e&&I(e.remove)&&I(e.add)&&I(e.unsubscribe)}function So(e){I(e)?e():e.unsubscribe()}var De={onUnhandledError:null,onStoppedNotification:null,Promise:void 0,useDeprecatedSynchronousErrorHandling:!1,useDeprecatedNextContext:!1};var xt={setTimeout:function(e,t){for(var r=[],o=2;o0},enumerable:!1,configurable:!0}),t.prototype._trySubscribe=function(r){return this._throwIfClosed(),e.prototype._trySubscribe.call(this,r)},t.prototype._subscribe=function(r){return this._throwIfClosed(),this._checkFinalizedStatuses(r),this._innerSubscribe(r)},t.prototype._innerSubscribe=function(r){var o=this,n=this,i=n.hasError,s=n.isStopped,a=n.observers;return i||s?$r:(this.currentObservers=null,a.push(r),new qe(function(){o.currentObservers=null,Ze(a,r)}))},t.prototype._checkFinalizedStatuses=function(r){var o=this,n=o.hasError,i=o.thrownError,s=o.isStopped;n?r.error(i):s&&r.complete()},t.prototype.asObservable=function(){var r=new F;return r.source=this,r},t.create=function(r,o){return new Ho(r,o)},t})(F);var Ho=(function(e){ie(t,e);function t(r,o){var n=e.call(this)||this;return n.destination=r,n.source=o,n}return t.prototype.next=function(r){var o,n;(n=(o=this.destination)===null||o===void 0?void 0:o.next)===null||n===void 0||n.call(o,r)},t.prototype.error=function(r){var o,n;(n=(o=this.destination)===null||o===void 0?void 0:o.error)===null||n===void 0||n.call(o,r)},t.prototype.complete=function(){var r,o;(o=(r=this.destination)===null||r===void 0?void 0:r.complete)===null||o===void 0||o.call(r)},t.prototype._subscribe=function(r){var o,n;return(n=(o=this.source)===null||o===void 0?void 0:o.subscribe(r))!==null&&n!==void 0?n:$r},t})(T);var jr=(function(e){ie(t,e);function t(r){var o=e.call(this)||this;return o._value=r,o}return Object.defineProperty(t.prototype,"value",{get:function(){return this.getValue()},enumerable:!1,configurable:!0}),t.prototype._subscribe=function(r){var o=e.prototype._subscribe.call(this,r);return!o.closed&&r.next(this._value),o},t.prototype.getValue=function(){var r=this,o=r.hasError,n=r.thrownError,i=r._value;if(o)throw n;return this._throwIfClosed(),i},t.prototype.next=function(r){e.prototype.next.call(this,this._value=r)},t})(T);var Rt={now:function(){return(Rt.delegate||Date).now()},delegate:void 0};var It=(function(e){ie(t,e);function t(r,o,n){r===void 0&&(r=1/0),o===void 0&&(o=1/0),n===void 0&&(n=Rt);var i=e.call(this)||this;return i._bufferSize=r,i._windowTime=o,i._timestampProvider=n,i._buffer=[],i._infiniteTimeWindow=!0,i._infiniteTimeWindow=o===1/0,i._bufferSize=Math.max(1,r),i._windowTime=Math.max(1,o),i}return t.prototype.next=function(r){var o=this,n=o.isStopped,i=o._buffer,s=o._infiniteTimeWindow,a=o._timestampProvider,c=o._windowTime;n||(i.push(r),!s&&i.push(a.now()+c)),this._trimBuffer(),e.prototype.next.call(this,r)},t.prototype._subscribe=function(r){this._throwIfClosed(),this._trimBuffer();for(var o=this._innerSubscribe(r),n=this,i=n._infiniteTimeWindow,s=n._buffer,a=s.slice(),c=0;c0?e.prototype.schedule.call(this,r,o):(this.delay=o,this.state=r,this.scheduler.flush(this),this)},t.prototype.execute=function(r,o){return o>0||this.closed?e.prototype.execute.call(this,r,o):this._execute(r,o)},t.prototype.requestAsyncId=function(r,o,n){return n===void 0&&(n=0),n!=null&&n>0||n==null&&this.delay>0?e.prototype.requestAsyncId.call(this,r,o,n):(r.flush(this),0)},t})(St);var Ro=(function(e){ie(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t})(Ot);var Dr=new Ro(Po);var Io=(function(e){ie(t,e);function t(r,o){var n=e.call(this,r,o)||this;return n.scheduler=r,n.work=o,n}return t.prototype.requestAsyncId=function(r,o,n){return n===void 0&&(n=0),n!==null&&n>0?e.prototype.requestAsyncId.call(this,r,o,n):(r.actions.push(this),r._scheduled||(r._scheduled=Tt.requestAnimationFrame(function(){return r.flush(void 0)})))},t.prototype.recycleAsyncId=function(r,o,n){var i;if(n===void 0&&(n=0),n!=null?n>0:this.delay>0)return e.prototype.recycleAsyncId.call(this,r,o,n);var s=r.actions;o!=null&&o===r._scheduled&&((i=s[s.length-1])===null||i===void 0?void 0:i.id)!==o&&(Tt.cancelAnimationFrame(o),r._scheduled=void 0)},t})(St);var Fo=(function(e){ie(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t.prototype.flush=function(r){this._active=!0;var o;r?o=r.id:(o=this._scheduled,this._scheduled=void 0);var n=this.actions,i;r=r||n.shift();do if(i=r.execute(r.state,r.delay))break;while((r=n[0])&&r.id===o&&n.shift());if(this._active=!1,i){for(;(r=n[0])&&r.id===o&&n.shift();)r.unsubscribe();throw i}},t})(Ot);var ye=new Fo(Io);var y=new F(function(e){return e.complete()});function tr(e){return e&&I(e.schedule)}function Vr(e){return e[e.length-1]}function pt(e){return I(Vr(e))?e.pop():void 0}function Fe(e){return tr(Vr(e))?e.pop():void 0}function rr(e,t){return typeof Vr(e)=="number"?e.pop():t}var Lt=(function(e){return e&&typeof e.length=="number"&&typeof e!="function"});function or(e){return I(e==null?void 0:e.then)}function nr(e){return I(e[wt])}function ir(e){return Symbol.asyncIterator&&I(e==null?void 0:e[Symbol.asyncIterator])}function ar(e){return new TypeError("You provided "+(e!==null&&typeof e=="object"?"an invalid object":"'"+e+"'")+" where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.")}function fa(){return typeof Symbol!="function"||!Symbol.iterator?"@@iterator":Symbol.iterator}var sr=fa();function cr(e){return I(e==null?void 0:e[sr])}function pr(e){return wo(this,arguments,function(){var r,o,n,i;return Gt(this,function(s){switch(s.label){case 0:r=e.getReader(),s.label=1;case 1:s.trys.push([1,,9,10]),s.label=2;case 2:return[4,dt(r.read())];case 3:return o=s.sent(),n=o.value,i=o.done,i?[4,dt(void 0)]:[3,5];case 4:return[2,s.sent()];case 5:return[4,dt(n)];case 6:return[4,s.sent()];case 7:return s.sent(),[3,2];case 8:return[3,10];case 9:return r.releaseLock(),[7];case 10:return[2]}})})}function lr(e){return I(e==null?void 0:e.getReader)}function U(e){if(e instanceof F)return e;if(e!=null){if(nr(e))return ua(e);if(Lt(e))return da(e);if(or(e))return ha(e);if(ir(e))return jo(e);if(cr(e))return ba(e);if(lr(e))return va(e)}throw ar(e)}function ua(e){return new F(function(t){var r=e[wt]();if(I(r.subscribe))return r.subscribe(t);throw new TypeError("Provided object does not correctly implement Symbol.observable")})}function da(e){return new F(function(t){for(var r=0;r=2;return function(o){return o.pipe(e?g(function(n,i){return e(n,i,o)}):be,Ee(1),r?Qe(t):tn(function(){return new fr}))}}function Yr(e){return e<=0?function(){return y}:E(function(t,r){var o=[];t.subscribe(w(r,function(n){o.push(n),e=2,!0))}function le(e){e===void 0&&(e={});var t=e.connector,r=t===void 0?function(){return new T}:t,o=e.resetOnError,n=o===void 0?!0:o,i=e.resetOnComplete,s=i===void 0?!0:i,a=e.resetOnRefCountZero,c=a===void 0?!0:a;return function(p){var l,f,u,d=0,v=!1,S=!1,X=function(){f==null||f.unsubscribe(),f=void 0},re=function(){X(),l=u=void 0,v=S=!1},ee=function(){var k=l;re(),k==null||k.unsubscribe()};return E(function(k,ut){d++,!S&&!v&&X();var je=u=u!=null?u:r();ut.add(function(){d--,d===0&&!S&&!v&&(f=Br(ee,c))}),je.subscribe(ut),!l&&d>0&&(l=new bt({next:function(R){return je.next(R)},error:function(R){S=!0,X(),f=Br(re,n,R),je.error(R)},complete:function(){v=!0,X(),f=Br(re,s),je.complete()}}),U(k).subscribe(l))})(p)}}function Br(e,t){for(var r=[],o=2;oe.next(document)),e}function M(e,t=document){return Array.from(t.querySelectorAll(e))}function j(e,t=document){let r=ue(e,t);if(typeof r=="undefined")throw new ReferenceError(`Missing element: expected "${e}" to be present`);return r}function ue(e,t=document){return t.querySelector(e)||void 0}function Ne(){var e,t,r,o;return(o=(r=(t=(e=document.activeElement)==null?void 0:e.shadowRoot)==null?void 0:t.activeElement)!=null?r:document.activeElement)!=null?o:void 0}var Ra=L(h(document.body,"focusin"),h(document.body,"focusout")).pipe(Ae(1),Q(void 0),m(()=>Ne()||document.body),Z(1));function Ye(e){return Ra.pipe(m(t=>e.contains(t)),Y())}function it(e,t){return H(()=>L(h(e,"mouseenter").pipe(m(()=>!0)),h(e,"mouseleave").pipe(m(()=>!1))).pipe(t?jt(r=>He(+!r*t)):be,Q(e.matches(":hover"))))}function sn(e,t){if(typeof t=="string"||typeof t=="number")e.innerHTML+=t.toString();else if(t instanceof Node)e.appendChild(t);else if(Array.isArray(t))for(let r of t)sn(e,r)}function x(e,t,...r){let o=document.createElement(e);if(t)for(let n of Object.keys(t))typeof t[n]!="undefined"&&(typeof t[n]!="boolean"?o.setAttribute(n,t[n]):o.setAttribute(n,""));for(let n of r)sn(o,n);return o}function br(e){if(e>999){let t=+((e-950)%1e3>99);return`${((e+1e-6)/1e3).toFixed(t)}k`}else return e.toString()}function _t(e){let t=x("script",{src:e});return H(()=>(document.head.appendChild(t),L(h(t,"load"),h(t,"error").pipe(b(()=>Nr(()=>new ReferenceError(`Invalid script: ${e}`))))).pipe(m(()=>{}),A(()=>document.head.removeChild(t)),Ee(1))))}var cn=new T,Ia=H(()=>typeof ResizeObserver=="undefined"?_t("https://unpkg.com/resize-observer-polyfill"):$(void 0)).pipe(m(()=>new ResizeObserver(e=>e.forEach(t=>cn.next(t)))),b(e=>L(tt,$(e)).pipe(A(()=>e.disconnect()))),Z(1));function de(e){return{width:e.offsetWidth,height:e.offsetHeight}}function Le(e){let t=e;for(;t.clientWidth===0&&t.parentElement;)t=t.parentElement;return Ia.pipe(O(r=>r.observe(t)),b(r=>cn.pipe(g(o=>o.target===t),A(()=>r.unobserve(t)))),m(()=>de(e)),Q(de(e)))}function At(e){return{width:e.scrollWidth,height:e.scrollHeight}}function vr(e){let t=e.parentElement;for(;t&&(e.scrollWidth<=t.scrollWidth&&e.scrollHeight<=t.scrollHeight);)t=(e=t).parentElement;return t?e:void 0}function pn(e){let t=[],r=e.parentElement;for(;r;)(e.clientWidth>r.clientWidth||e.clientHeight>r.clientHeight)&&t.push(r),r=(e=r).parentElement;return t.length===0&&t.push(document.documentElement),t}function Be(e){return{x:e.offsetLeft,y:e.offsetTop}}function ln(e){let t=e.getBoundingClientRect();return{x:t.x+window.scrollX,y:t.y+window.scrollY}}function mn(e){return L(h(window,"load"),h(window,"resize")).pipe($e(0,ye),m(()=>Be(e)),Q(Be(e)))}function gr(e){return{x:e.scrollLeft,y:e.scrollTop}}function Ge(e){return L(h(e,"scroll"),h(window,"scroll"),h(window,"resize")).pipe($e(0,ye),m(()=>gr(e)),Q(gr(e)))}var fn=new T,Fa=H(()=>$(new IntersectionObserver(e=>{for(let t of e)fn.next(t)},{threshold:0}))).pipe(b(e=>L(tt,$(e)).pipe(A(()=>e.disconnect()))),Z(1));function mt(e){return Fa.pipe(O(t=>t.observe(e)),b(t=>fn.pipe(g(({target:r})=>r===e),A(()=>t.unobserve(e)),m(({isIntersecting:r})=>r))))}function un(e,t=16){return Ge(e).pipe(m(({y:r})=>{let o=de(e),n=At(e);return r>=n.height-o.height-t}),Y())}var yr={drawer:j("[data-md-toggle=drawer]"),search:j("[data-md-toggle=search]")};function dn(e){return yr[e].checked}function at(e,t){yr[e].checked!==t&&yr[e].click()}function Je(e){let t=yr[e];return h(t,"change").pipe(m(()=>t.checked),Q(t.checked))}function ja(e,t){switch(e.constructor){case HTMLInputElement:return e.type==="radio"?/^Arrow/.test(t):!0;case HTMLSelectElement:case HTMLTextAreaElement:return!0;default:return e.isContentEditable}}function Ua(){return L(h(window,"compositionstart").pipe(m(()=>!0)),h(window,"compositionend").pipe(m(()=>!1))).pipe(Q(!1))}function hn(){let e=h(window,"keydown").pipe(g(t=>!(t.metaKey||t.ctrlKey)),m(t=>({mode:dn("search")?"search":"global",type:t.key,claim(){t.preventDefault(),t.stopPropagation()}})),g(({mode:t,type:r})=>{if(t==="global"){let o=Ne();if(typeof o!="undefined")return!ja(o,r)}return!0}),le());return Ua().pipe(b(t=>t?y:e))}function we(){return new URL(location.href)}function st(e,t=!1){if(V("navigation.instant")&&!t){let r=x("a",{href:e.href});document.body.appendChild(r),r.click(),r.remove()}else location.href=e.href}function bn(){return new T}function vn(){return location.hash.slice(1)}function gn(e){let t=x("a",{href:e});t.addEventListener("click",r=>r.stopPropagation()),t.click()}function Zr(e){return L(h(window,"hashchange"),e).pipe(m(vn),Q(vn()),g(t=>t.length>0),Z(1))}function yn(e){return Zr(e).pipe(m(t=>ue(`[id="${t}"]`)),g(t=>typeof t!="undefined"))}function Wt(e){let t=matchMedia(e);return ur(r=>t.addListener(()=>r(t.matches))).pipe(Q(t.matches))}function xn(){let e=matchMedia("print");return L(h(window,"beforeprint").pipe(m(()=>!0)),h(window,"afterprint").pipe(m(()=>!1))).pipe(Q(e.matches))}function eo(e,t){return e.pipe(b(r=>r?t():y))}function to(e,t){return new F(r=>{let o=new XMLHttpRequest;return o.open("GET",`${e}`),o.responseType="blob",o.addEventListener("load",()=>{o.status>=200&&o.status<300?(r.next(o.response),r.complete()):r.error(new Error(o.statusText))}),o.addEventListener("error",()=>{r.error(new Error("Network error"))}),o.addEventListener("abort",()=>{r.complete()}),typeof(t==null?void 0:t.progress$)!="undefined"&&(o.addEventListener("progress",n=>{var i;if(n.lengthComputable)t.progress$.next(n.loaded/n.total*100);else{let s=(i=o.getResponseHeader("Content-Length"))!=null?i:0;t.progress$.next(n.loaded/+s*100)}}),t.progress$.next(5)),o.send(),()=>o.abort()})}function ze(e,t){return to(e,t).pipe(b(r=>r.text()),m(r=>JSON.parse(r)),Z(1))}function xr(e,t){let r=new DOMParser;return to(e,t).pipe(b(o=>o.text()),m(o=>r.parseFromString(o,"text/html")),Z(1))}function En(e,t){let r=new DOMParser;return to(e,t).pipe(b(o=>o.text()),m(o=>r.parseFromString(o,"text/xml")),Z(1))}function wn(){return{x:Math.max(0,scrollX),y:Math.max(0,scrollY)}}function Tn(){return L(h(window,"scroll",{passive:!0}),h(window,"resize",{passive:!0})).pipe(m(wn),Q(wn()))}function Sn(){return{width:innerWidth,height:innerHeight}}function On(){return h(window,"resize",{passive:!0}).pipe(m(Sn),Q(Sn()))}function Ln(){return z([Tn(),On()]).pipe(m(([e,t])=>({offset:e,size:t})),Z(1))}function Er(e,{viewport$:t,header$:r}){let o=t.pipe(ne("size")),n=z([o,r]).pipe(m(()=>Be(e)));return z([r,t,n]).pipe(m(([{height:i},{offset:s,size:a},{x:c,y:p}])=>({offset:{x:s.x-c,y:s.y-p+i},size:a})))}function Wa(e){return h(e,"message",t=>t.data)}function Da(e){let t=new T;return t.subscribe(r=>e.postMessage(r)),t}function Mn(e,t=new Worker(e)){let r=Wa(t),o=Da(t),n=new T;n.subscribe(o);let i=o.pipe(oe(),ae(!0));return n.pipe(oe(),Ve(r.pipe(W(i))),le())}var Va=j("#__config"),Ct=JSON.parse(Va.textContent);Ct.base=`${new URL(Ct.base,we())}`;function Te(){return Ct}function V(e){return Ct.features.includes(e)}function Me(e,t){return typeof t!="undefined"?Ct.translations[e].replace("#",t.toString()):Ct.translations[e]}function Ce(e,t=document){return j(`[data-md-component=${e}]`,t)}function me(e,t=document){return M(`[data-md-component=${e}]`,t)}function Na(e){let t=j(".md-typeset > :first-child",e);return h(t,"click",{once:!0}).pipe(m(()=>j(".md-typeset",e)),m(r=>({hash:__md_hash(r.innerHTML)})))}function _n(e){if(!V("announce.dismiss")||!e.childElementCount)return y;if(!e.hidden){let t=j(".md-typeset",e);__md_hash(t.innerHTML)===__md_get("__announce")&&(e.hidden=!0)}return H(()=>{let t=new T;return t.subscribe(({hash:r})=>{e.hidden=!0,__md_set("__announce",r)}),Na(e).pipe(O(r=>t.next(r)),A(()=>t.complete()),m(r=>P({ref:e},r)))})}function za(e,{target$:t}){return t.pipe(m(r=>({hidden:r!==e})))}function An(e,t){let r=new T;return r.subscribe(({hidden:o})=>{e.hidden=o}),za(e,t).pipe(O(o=>r.next(o)),A(()=>r.complete()),m(o=>P({ref:e},o)))}function Dt(e,t){return t==="inline"?x("div",{class:"md-tooltip md-tooltip--inline",id:e,role:"tooltip"},x("div",{class:"md-tooltip__inner md-typeset"})):x("div",{class:"md-tooltip",id:e,role:"tooltip"},x("div",{class:"md-tooltip__inner md-typeset"}))}function wr(...e){return x("div",{class:"md-tooltip2",role:"dialog"},x("div",{class:"md-tooltip2__inner md-typeset"},e))}function Cn(...e){return x("div",{class:"md-tooltip2",role:"tooltip"},x("div",{class:"md-tooltip2__inner md-typeset"},e))}function kn(e,t){if(t=t?`${t}_annotation_${e}`:void 0,t){let r=t?`#${t}`:void 0;return x("aside",{class:"md-annotation",tabIndex:0},Dt(t),x("a",{href:r,class:"md-annotation__index",tabIndex:-1},x("span",{"data-md-annotation-id":e})))}else return x("aside",{class:"md-annotation",tabIndex:0},Dt(t),x("span",{class:"md-annotation__index",tabIndex:-1},x("span",{"data-md-annotation-id":e})))}function Hn(e){return x("button",{class:"md-code__button",title:Me("clipboard.copy"),"data-clipboard-target":`#${e} > code`,"data-md-type":"copy"})}function $n(){return x("button",{class:"md-code__button",title:"Toggle line selection","data-md-type":"select"})}function Pn(){return x("nav",{class:"md-code__nav"})}var In=$t(ro());function oo(e,t){let r=t&2,o=t&1,n=Object.keys(e.terms).filter(c=>!e.terms[c]).reduce((c,p)=>[...c,x("del",null,(0,In.default)(p))," "],[]).slice(0,-1),i=Te(),s=new URL(e.location,i.base);V("search.highlight")&&s.searchParams.set("h",Object.entries(e.terms).filter(([,c])=>c).reduce((c,[p])=>`${c} ${p}`.trim(),""));let{tags:a}=Te();return x("a",{href:`${s}`,class:"md-search-result__link",tabIndex:-1},x("article",{class:"md-search-result__article md-typeset","data-md-score":e.score.toFixed(2)},r>0&&x("div",{class:"md-search-result__icon md-icon"}),r>0&&x("h1",null,e.title),r<=0&&x("h2",null,e.title),o>0&&e.text.length>0&&e.text,e.tags&&x("nav",{class:"md-tags"},e.tags.map(c=>{let p=a?c in a?`md-tag-icon md-tag--${a[c]}`:"md-tag-icon":"";return x("span",{class:`md-tag ${p}`},c)})),o>0&&n.length>0&&x("p",{class:"md-search-result__terms"},Me("search.result.term.missing"),": ",...n)))}function Fn(e){let t=e[0].score,r=[...e],o=Te(),n=r.findIndex(l=>!`${new URL(l.location,o.base)}`.includes("#")),[i]=r.splice(n,1),s=r.findIndex(l=>l.scoreoo(l,1)),...c.length?[x("details",{class:"md-search-result__more"},x("summary",{tabIndex:-1},x("div",null,c.length>0&&c.length===1?Me("search.result.more.one"):Me("search.result.more.other",c.length))),...c.map(l=>oo(l,1)))]:[]];return x("li",{class:"md-search-result__item"},p)}function jn(e){return x("ul",{class:"md-source__facts"},Object.entries(e).map(([t,r])=>x("li",{class:`md-source__fact md-source__fact--${t}`},typeof r=="number"?br(r):r)))}function no(e){let t=`tabbed-control tabbed-control--${e}`;return x("div",{class:t,hidden:!0},x("button",{class:"tabbed-button",tabIndex:-1,"aria-hidden":"true"}))}function Un(e){return x("div",{class:"md-typeset__scrollwrap"},x("div",{class:"md-typeset__table"},e))}function Qa(e){var o;let t=Te(),r=new URL(`../${e.version}/`,t.base);return x("li",{class:"md-version__item"},x("a",{href:`${r}`,class:"md-version__link"},e.title,((o=t.version)==null?void 0:o.alias)&&e.aliases.length>0&&x("span",{class:"md-version__alias"},e.aliases[0])))}function Wn(e,t){var o;let r=Te();return e=e.filter(n=>{var i;return!((i=n.properties)!=null&&i.hidden)}),x("div",{class:"md-version"},x("button",{class:"md-version__current","aria-label":Me("select.version")},t.title,((o=r.version)==null?void 0:o.alias)&&t.aliases.length>0&&x("span",{class:"md-version__alias"},t.aliases[0])),x("ul",{class:"md-version__list"},e.map(Qa)))}var Ya=0;function Ba(e,t=250){let r=z([Ye(e),it(e,t)]).pipe(m(([n,i])=>n||i),Y()),o=H(()=>pn(e)).pipe(J(Ge),gt(1),Pe(r),m(()=>ln(e)));return r.pipe(Re(n=>n),b(()=>z([r,o])),m(([n,i])=>({active:n,offset:i})),le())}function Vt(e,t,r=250){let{content$:o,viewport$:n}=t,i=`__tooltip2_${Ya++}`;return H(()=>{let s=new T,a=new jr(!1);s.pipe(oe(),ae(!1)).subscribe(a);let c=a.pipe(jt(l=>He(+!l*250,Dr)),Y(),b(l=>l?o:y),O(l=>l.id=i),le());z([s.pipe(m(({active:l})=>l)),c.pipe(b(l=>it(l,250)),Q(!1))]).pipe(m(l=>l.some(f=>f))).subscribe(a);let p=a.pipe(g(l=>l),te(c,n),m(([l,f,{size:u}])=>{let d=e.getBoundingClientRect(),v=d.width/2;if(f.role==="tooltip")return{x:v,y:8+d.height};if(d.y>=u.height/2){let{height:S}=de(f);return{x:v,y:-16-S}}else return{x:v,y:16+d.height}}));return z([c,s,p]).subscribe(([l,{offset:f},u])=>{l.style.setProperty("--md-tooltip-host-x",`${f.x}px`),l.style.setProperty("--md-tooltip-host-y",`${f.y}px`),l.style.setProperty("--md-tooltip-x",`${u.x}px`),l.style.setProperty("--md-tooltip-y",`${u.y}px`),l.classList.toggle("md-tooltip2--top",u.y<0),l.classList.toggle("md-tooltip2--bottom",u.y>=0)}),a.pipe(g(l=>l),te(c,(l,f)=>f),g(l=>l.role==="tooltip")).subscribe(l=>{let f=de(j(":scope > *",l));l.style.setProperty("--md-tooltip-width",`${f.width}px`),l.style.setProperty("--md-tooltip-tail","0px")}),a.pipe(Y(),xe(ye),te(c)).subscribe(([l,f])=>{f.classList.toggle("md-tooltip2--active",l)}),z([a.pipe(g(l=>l)),c]).subscribe(([l,f])=>{f.role==="dialog"?(e.setAttribute("aria-controls",i),e.setAttribute("aria-haspopup","dialog")):e.setAttribute("aria-describedby",i)}),a.pipe(g(l=>!l)).subscribe(()=>{e.removeAttribute("aria-controls"),e.removeAttribute("aria-describedby"),e.removeAttribute("aria-haspopup")}),Ba(e,r).pipe(O(l=>s.next(l)),A(()=>s.complete()),m(l=>P({ref:e},l)))})}function Xe(e,{viewport$:t},r=document.body){return Vt(e,{content$:new F(o=>{let n=e.title,i=Cn(n);return o.next(i),e.removeAttribute("title"),r.append(i),()=>{i.remove(),e.setAttribute("title",n)}}),viewport$:t},0)}function Ga(e,t){let r=H(()=>z([mn(e),Ge(t)])).pipe(m(([{x:o,y:n},i])=>{let{width:s,height:a}=de(e);return{x:o-i.x+s/2,y:n-i.y+a/2}}));return Ye(e).pipe(b(o=>r.pipe(m(n=>({active:o,offset:n})),Ee(+!o||1/0))))}function Dn(e,t,{target$:r}){let[o,n]=Array.from(e.children);return H(()=>{let i=new T,s=i.pipe(oe(),ae(!0));return i.subscribe({next({offset:a}){e.style.setProperty("--md-tooltip-x",`${a.x}px`),e.style.setProperty("--md-tooltip-y",`${a.y}px`)},complete(){e.style.removeProperty("--md-tooltip-x"),e.style.removeProperty("--md-tooltip-y")}}),mt(e).pipe(W(s)).subscribe(a=>{e.toggleAttribute("data-md-visible",a)}),L(i.pipe(g(({active:a})=>a)),i.pipe(Ae(250),g(({active:a})=>!a))).subscribe({next({active:a}){a?e.prepend(o):o.remove()},complete(){e.prepend(o)}}),i.pipe($e(16,ye)).subscribe(({active:a})=>{o.classList.toggle("md-tooltip--active",a)}),i.pipe(gt(125,ye),g(()=>!!e.offsetParent),m(()=>e.offsetParent.getBoundingClientRect()),m(({x:a})=>a)).subscribe({next(a){a?e.style.setProperty("--md-tooltip-0",`${-a}px`):e.style.removeProperty("--md-tooltip-0")},complete(){e.style.removeProperty("--md-tooltip-0")}}),h(n,"click").pipe(W(s),g(a=>!(a.metaKey||a.ctrlKey))).subscribe(a=>{a.stopPropagation(),a.preventDefault()}),h(n,"mousedown").pipe(W(s),te(i)).subscribe(([a,{active:c}])=>{var p;if(a.button!==0||a.metaKey||a.ctrlKey)a.preventDefault();else if(c){a.preventDefault();let l=e.parentElement.closest(".md-annotation");l instanceof HTMLElement?l.focus():(p=Ne())==null||p.blur()}}),r.pipe(W(s),g(a=>a===o),nt(125)).subscribe(()=>e.focus()),Ga(e,t).pipe(O(a=>i.next(a)),A(()=>i.complete()),m(a=>P({ref:e},a)))})}function Ja(e){let t=Te();if(e.tagName!=="CODE")return[e];let r=[".c",".c1",".cm"];if(t.annotate&&typeof t.annotate=="object"){let o=e.closest("[class|=language]");if(o)for(let n of Array.from(o.classList)){if(!n.startsWith("language-"))continue;let[,i]=n.split("-");i in t.annotate&&r.push(...t.annotate[i])}}return M(r.join(", "),e)}function Xa(e){let t=[];for(let r of Ja(e)){let o=[],n=document.createNodeIterator(r,NodeFilter.SHOW_TEXT);for(let i=n.nextNode();i;i=n.nextNode())o.push(i);for(let i of o){let s;for(;s=/(\(\d+\))(!)?/.exec(i.textContent);){let[,a,c]=s;if(typeof c=="undefined"){let p=i.splitText(s.index);i=p.splitText(a.length),t.push(p)}else{i.textContent=a,t.push(i);break}}}}return t}function Vn(e,t){t.append(...Array.from(e.childNodes))}function Tr(e,t,{target$:r,print$:o}){let n=t.closest("[id]"),i=n==null?void 0:n.id,s=new Map;for(let a of Xa(t)){let[,c]=a.textContent.match(/\((\d+)\)/);ue(`:scope > li:nth-child(${c})`,e)&&(s.set(c,kn(c,i)),a.replaceWith(s.get(c)))}return s.size===0?y:H(()=>{let a=new T,c=a.pipe(oe(),ae(!0)),p=[];for(let[l,f]of s)p.push([j(".md-typeset",f),j(`:scope > li:nth-child(${l})`,e)]);return o.pipe(W(c)).subscribe(l=>{e.hidden=!l,e.classList.toggle("md-annotation-list",l);for(let[f,u]of p)l?Vn(f,u):Vn(u,f)}),L(...[...s].map(([,l])=>Dn(l,t,{target$:r}))).pipe(A(()=>a.complete()),le())})}function Nn(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return Nn(t)}}function zn(e,t){return H(()=>{let r=Nn(e);return typeof r!="undefined"?Tr(r,e,t):y})}var Kn=$t(ao());var Za=0,qn=L(h(window,"keydown").pipe(m(()=>!0)),L(h(window,"keyup"),h(window,"contextmenu")).pipe(m(()=>!1))).pipe(Q(!1),Z(1));function Qn(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return Qn(t)}}function es(e){return Le(e).pipe(m(({width:t})=>({scrollable:At(e).width>t})),ne("scrollable"))}function Yn(e,t){let{matches:r}=matchMedia("(hover)"),o=H(()=>{let n=new T,i=n.pipe(Yr(1));n.subscribe(({scrollable:d})=>{d&&r?e.setAttribute("tabindex","0"):e.removeAttribute("tabindex")});let s=[],a=e.closest("pre"),c=a.closest("[id]"),p=c?c.id:Za++;a.id=`__code_${p}`;let l=[],f=e.closest(".highlight");if(f instanceof HTMLElement){let d=Qn(f);if(typeof d!="undefined"&&(f.classList.contains("annotate")||V("content.code.annotate"))){let v=Tr(d,e,t);l.push(Le(f).pipe(W(i),m(({width:S,height:X})=>S&&X),Y(),b(S=>S?v:y)))}}let u=M(":scope > span[id]",e);if(u.length&&(e.classList.add("md-code__content"),e.closest(".select")||V("content.code.select")&&!e.closest(".no-select"))){let d=+u[0].id.split("-").pop(),v=$n();s.push(v),V("content.tooltips")&&l.push(Xe(v,{viewport$}));let S=h(v,"click").pipe(Ut(R=>!R,!1),O(()=>v.blur()),le());S.subscribe(R=>{v.classList.toggle("md-code__button--active",R)});let X=fe(u).pipe(J(R=>it(R).pipe(m(se=>[R,se]))));S.pipe(b(R=>R?X:y)).subscribe(([R,se])=>{let ce=ue(".hll.select",R);if(ce&&!se)ce.replaceWith(...Array.from(ce.childNodes));else if(!ce&&se){let he=document.createElement("span");he.className="hll select",he.append(...Array.from(R.childNodes).slice(1)),R.append(he)}});let re=fe(u).pipe(J(R=>h(R,"mousedown").pipe(O(se=>se.preventDefault()),m(()=>R)))),ee=S.pipe(b(R=>R?re:y),te(qn),m(([R,se])=>{var he;let ce=u.indexOf(R)+d;if(se===!1)return[ce,ce];{let Se=M(".hll",e).map(Ue=>u.indexOf(Ue.parentElement)+d);return(he=window.getSelection())==null||he.removeAllRanges(),[Math.min(ce,...Se),Math.max(ce,...Se)]}})),k=Zr(y).pipe(g(R=>R.startsWith(`__codelineno-${p}-`)));k.subscribe(R=>{let[,,se]=R.split("-"),ce=se.split(":").map(Se=>+Se-d+1);ce.length===1&&ce.push(ce[0]);for(let Se of M(".hll:not(.select)",e))Se.replaceWith(...Array.from(Se.childNodes));let he=u.slice(ce[0]-1,ce[1]);for(let Se of he){let Ue=document.createElement("span");Ue.className="hll",Ue.append(...Array.from(Se.childNodes).slice(1)),Se.append(Ue)}}),k.pipe(Ee(1),xe(pe)).subscribe(R=>{if(R.includes(":")){let se=document.getElementById(R.split(":")[0]);se&&setTimeout(()=>{let ce=se,he=-64;for(;ce!==document.body;)he+=ce.offsetTop,ce=ce.offsetParent;window.scrollTo({top:he})},1)}});let je=fe(M('a[href^="#__codelineno"]',f)).pipe(J(R=>h(R,"click").pipe(O(se=>se.preventDefault()),m(()=>R)))).pipe(W(i),te(qn),m(([R,se])=>{let he=+j(`[id="${R.hash.slice(1)}"]`).parentElement.id.split("-").pop();if(se===!1)return[he,he];{let Se=M(".hll",e).map(Ue=>+Ue.parentElement.id.split("-").pop());return[Math.min(he,...Se),Math.max(he,...Se)]}}));L(ee,je).subscribe(R=>{let se=`#__codelineno-${p}-`;R[0]===R[1]?se+=R[0]:se+=`${R[0]}:${R[1]}`,history.replaceState({},"",se),window.dispatchEvent(new HashChangeEvent("hashchange",{newURL:window.location.origin+window.location.pathname+se,oldURL:window.location.href}))})}if(Kn.default.isSupported()&&(e.closest(".copy")||V("content.code.copy")&&!e.closest(".no-copy"))){let d=Hn(a.id);s.push(d),V("content.tooltips")&&l.push(Xe(d,{viewport$}))}if(s.length){let d=Pn();d.append(...s),a.insertBefore(d,e)}return es(e).pipe(O(d=>n.next(d)),A(()=>n.complete()),m(d=>P({ref:e},d)),Ve(L(...l).pipe(W(i))))});return V("content.lazy")?mt(e).pipe(g(n=>n),Ee(1),b(()=>o)):o}function ts(e,{target$:t,print$:r}){let o=!0;return L(t.pipe(m(n=>n.closest("details:not([open])")),g(n=>e===n),m(()=>({action:"open",reveal:!0}))),r.pipe(g(n=>n||!o),O(()=>o=e.open),m(n=>({action:n?"open":"close"}))))}function Bn(e,t){return H(()=>{let r=new T;return r.subscribe(({action:o,reveal:n})=>{e.toggleAttribute("open",o==="open"),n&&e.scrollIntoView()}),ts(e,t).pipe(O(o=>r.next(o)),A(()=>r.complete()),m(o=>P({ref:e},o)))})}var Gn=0;function rs(e){let t=document.createElement("h3");t.innerHTML=e.innerHTML;let r=[t],o=e.nextElementSibling;for(;o&&!(o instanceof HTMLHeadingElement);)r.push(o),o=o.nextElementSibling;return r}function os(e,t){for(let r of M("[href], [src]",e))for(let o of["href","src"]){let n=r.getAttribute(o);if(n&&!/^(?:[a-z]+:)?\/\//i.test(n)){r[o]=new URL(r.getAttribute(o),t).toString();break}}for(let r of M("[name^=__], [for]",e))for(let o of["id","for","name"]){let n=r.getAttribute(o);n&&r.setAttribute(o,`${n}$preview_${Gn}`)}return Gn++,$(e)}function Jn(e,t){let{sitemap$:r}=t;if(!(e instanceof HTMLAnchorElement))return y;if(!(V("navigation.instant.preview")||e.hasAttribute("data-preview")))return y;e.removeAttribute("title");let o=z([Ye(e),it(e)]).pipe(m(([i,s])=>i||s),Y(),g(i=>i));return rt([r,o]).pipe(b(([i])=>{let s=new URL(e.href);return s.search=s.hash="",i.has(`${s}`)?$(s):y}),b(i=>xr(i).pipe(b(s=>os(s,i)))),b(i=>{let s=e.hash?`article [id="${e.hash.slice(1)}"]`:"article h1",a=ue(s,i);return typeof a=="undefined"?y:$(rs(a))})).pipe(b(i=>{let s=new F(a=>{let c=wr(...i);return a.next(c),document.body.append(c),()=>c.remove()});return Vt(e,P({content$:s},t))}))}var Xn=".node circle,.node ellipse,.node path,.node polygon,.node rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}marker{fill:var(--md-mermaid-edge-color)!important}.edgeLabel .label rect{fill:#0000}.flowchartTitleText{fill:var(--md-mermaid-label-fg-color)}.label{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.label foreignObject{line-height:normal;overflow:visible}.label div .edgeLabel{color:var(--md-mermaid-label-fg-color)}.edgeLabel,.edgeLabel p,.label div .edgeLabel{background-color:var(--md-mermaid-label-bg-color)}.edgeLabel,.edgeLabel p{fill:var(--md-mermaid-label-bg-color);color:var(--md-mermaid-edge-color)}.edgePath .path,.flowchart-link{stroke:var(--md-mermaid-edge-color)}.edgePath .arrowheadPath{fill:var(--md-mermaid-edge-color);stroke:none}.cluster rect{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}.cluster span{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}g #flowchart-circleEnd,g #flowchart-circleStart,g #flowchart-crossEnd,g #flowchart-crossStart,g #flowchart-pointEnd,g #flowchart-pointStart{stroke:none}.classDiagramTitleText{fill:var(--md-mermaid-label-fg-color)}g.classGroup line,g.classGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.classGroup text{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.classLabel .box{fill:var(--md-mermaid-label-bg-color);background-color:var(--md-mermaid-label-bg-color);opacity:1}.classLabel .label{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.node .divider{stroke:var(--md-mermaid-node-fg-color)}.relation{stroke:var(--md-mermaid-edge-color)}.cardinality{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.cardinality text{fill:inherit!important}defs marker.marker.composition.class path,defs marker.marker.dependency.class path,defs marker.marker.extension.class path{fill:var(--md-mermaid-edge-color)!important;stroke:var(--md-mermaid-edge-color)!important}defs marker.marker.aggregation.class path{fill:var(--md-mermaid-label-bg-color)!important;stroke:var(--md-mermaid-edge-color)!important}.statediagramTitleText{fill:var(--md-mermaid-label-fg-color)}g.stateGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.stateGroup .state-title{fill:var(--md-mermaid-label-fg-color)!important;font-family:var(--md-mermaid-font-family)}g.stateGroup .composit{fill:var(--md-mermaid-label-bg-color)}.nodeLabel,.nodeLabel p{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}a .nodeLabel{text-decoration:underline}.node circle.state-end,.node circle.state-start,.start-state{fill:var(--md-mermaid-edge-color);stroke:none}.end-state-inner,.end-state-outer{fill:var(--md-mermaid-edge-color)}.end-state-inner,.node circle.state-end{stroke:var(--md-mermaid-label-bg-color)}.transition{stroke:var(--md-mermaid-edge-color)}[id^=state-fork] rect,[id^=state-join] rect{fill:var(--md-mermaid-edge-color)!important;stroke:none!important}.statediagram-cluster.statediagram-cluster .inner{fill:var(--md-default-bg-color)}.statediagram-cluster rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.statediagram-state rect.divider{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}defs #statediagram-barbEnd{stroke:var(--md-mermaid-edge-color)}[id^=entity] path,[id^=entity] rect{fill:var(--md-default-bg-color)}.relationshipLine{stroke:var(--md-mermaid-edge-color)}defs .marker.oneOrMore.er *,defs .marker.onlyOne.er *,defs .marker.zeroOrMore.er *,defs .marker.zeroOrOne.er *{stroke:var(--md-mermaid-edge-color)!important}text:not([class]):last-child{fill:var(--md-mermaid-label-fg-color)}.actor{fill:var(--md-mermaid-sequence-actor-bg-color);stroke:var(--md-mermaid-sequence-actor-border-color)}text.actor>tspan{fill:var(--md-mermaid-sequence-actor-fg-color);font-family:var(--md-mermaid-font-family)}line{stroke:var(--md-mermaid-sequence-actor-line-color)}.actor-man circle,.actor-man line{fill:var(--md-mermaid-sequence-actorman-bg-color);stroke:var(--md-mermaid-sequence-actorman-line-color)}.messageLine0,.messageLine1{stroke:var(--md-mermaid-sequence-message-line-color)}.note{fill:var(--md-mermaid-sequence-note-bg-color);stroke:var(--md-mermaid-sequence-note-border-color)}.loopText,.loopText>tspan,.messageText,.noteText>tspan{stroke:none;font-family:var(--md-mermaid-font-family)!important}.messageText{fill:var(--md-mermaid-sequence-message-fg-color)}.loopText,.loopText>tspan{fill:var(--md-mermaid-sequence-loop-fg-color)}.noteText>tspan{fill:var(--md-mermaid-sequence-note-fg-color)}#arrowhead path{fill:var(--md-mermaid-sequence-message-line-color);stroke:none}.loopLine{fill:var(--md-mermaid-sequence-loop-bg-color);stroke:var(--md-mermaid-sequence-loop-border-color)}.labelBox{fill:var(--md-mermaid-sequence-label-bg-color);stroke:none}.labelText,.labelText>span{fill:var(--md-mermaid-sequence-label-fg-color);font-family:var(--md-mermaid-font-family)}.sequenceNumber{fill:var(--md-mermaid-sequence-number-fg-color)}rect.rect{fill:var(--md-mermaid-sequence-box-bg-color);stroke:none}rect.rect+text.text{fill:var(--md-mermaid-sequence-box-fg-color)}defs #sequencenumber{fill:var(--md-mermaid-sequence-number-bg-color)!important}";var so,is=0;function as(){return typeof mermaid=="undefined"||mermaid instanceof Element?_t("https://unpkg.com/mermaid@11/dist/mermaid.min.js"):$(void 0)}function Zn(e){return e.classList.remove("mermaid"),so||(so=as().pipe(O(()=>mermaid.initialize({startOnLoad:!1,themeCSS:Xn,sequence:{actorFontSize:"16px",messageFontSize:"16px",noteFontSize:"16px"}})),m(()=>{}),Z(1))),so.subscribe(()=>go(null,null,function*(){e.classList.add("mermaid");let t=`__mermaid_${is++}`,r=x("div",{class:"mermaid"}),o=e.textContent,{svg:n,fn:i}=yield mermaid.render(t,o),s=r.attachShadow({mode:"closed"});s.innerHTML=n,e.replaceWith(r),i==null||i(s)})),so.pipe(m(()=>({ref:e})))}var ei=x("table");function ti(e){return e.replaceWith(ei),ei.replaceWith(Un(e)),$({ref:e})}function ss(e){let t=e.find(r=>r.checked)||e[0];return L(...e.map(r=>h(r,"change").pipe(m(()=>j(`label[for="${r.id}"]`))))).pipe(Q(j(`label[for="${t.id}"]`)),m(r=>({active:r})))}function ri(e,{viewport$:t,target$:r}){let o=j(".tabbed-labels",e),n=M(":scope > input",e),i=no("prev");e.append(i);let s=no("next");return e.append(s),H(()=>{let a=new T,c=a.pipe(oe(),ae(!0));z([a,Le(e),mt(e)]).pipe(W(c),$e(1,ye)).subscribe({next([{active:p},l]){let f=Be(p),{width:u}=de(p);e.style.setProperty("--md-indicator-x",`${f.x}px`),e.style.setProperty("--md-indicator-width",`${u}px`);let d=gr(o);(f.xd.x+l.width)&&o.scrollTo({left:Math.max(0,f.x-16),behavior:"smooth"})},complete(){e.style.removeProperty("--md-indicator-x"),e.style.removeProperty("--md-indicator-width")}}),z([Ge(o),Le(o)]).pipe(W(c)).subscribe(([p,l])=>{let f=At(o);i.hidden=p.x<16,s.hidden=p.x>f.width-l.width-16}),L(h(i,"click").pipe(m(()=>-1)),h(s,"click").pipe(m(()=>1))).pipe(W(c)).subscribe(p=>{let{width:l}=de(o);o.scrollBy({left:l*p,behavior:"smooth"})}),r.pipe(W(c),g(p=>n.includes(p))).subscribe(p=>p.click()),o.classList.add("tabbed-labels--linked");for(let p of n){let l=j(`label[for="${p.id}"]`);l.replaceChildren(x("a",{href:`#${l.htmlFor}`,tabIndex:-1},...Array.from(l.childNodes))),h(l.firstElementChild,"click").pipe(W(c),g(f=>!(f.metaKey||f.ctrlKey)),O(f=>{f.preventDefault(),f.stopPropagation()})).subscribe(()=>{history.replaceState({},"",`#${l.htmlFor}`),l.click()})}return V("content.tabs.link")&&a.pipe(Ie(1),te(t)).subscribe(([{active:p},{offset:l}])=>{let f=p.innerText.trim();if(p.hasAttribute("data-md-switching"))p.removeAttribute("data-md-switching");else{let u=e.offsetTop-l.y;for(let v of M("[data-tabs]"))for(let S of M(":scope > input",v)){let X=j(`label[for="${S.id}"]`);if(X!==p&&X.innerText.trim()===f){X.setAttribute("data-md-switching",""),S.click();break}}window.scrollTo({top:e.offsetTop-u});let d=__md_get("__tabs")||[];__md_set("__tabs",[...new Set([f,...d])])}}),a.pipe(W(c)).subscribe(()=>{for(let p of M("audio, video",e))p.offsetWidth&&p.autoplay?p.play().catch(()=>{}):p.pause()}),ss(n).pipe(O(p=>a.next(p)),A(()=>a.complete()),m(p=>P({ref:e},p)))}).pipe(et(pe))}function oi(e,t){let{viewport$:r,target$:o,print$:n}=t;return L(...M(".annotate:not(.highlight)",e).map(i=>zn(i,{target$:o,print$:n})),...M("pre:not(.mermaid) > code",e).map(i=>Yn(i,{target$:o,print$:n})),...M("a",e).map(i=>Jn(i,t)),...M("pre.mermaid",e).map(i=>Zn(i)),...M("table:not([class])",e).map(i=>ti(i)),...M("details",e).map(i=>Bn(i,{target$:o,print$:n})),...M("[data-tabs]",e).map(i=>ri(i,{viewport$:r,target$:o})),...M("[title]:not([data-preview])",e).filter(()=>V("content.tooltips")).map(i=>Xe(i,{viewport$:r})),...M(".footnote-ref",e).filter(()=>V("content.footnote.tooltips")).map(i=>Vt(i,{content$:new F(s=>{let a=new URL(i.href).hash.slice(1),c=Array.from(document.getElementById(a).cloneNode(!0).children),p=wr(...c);return s.next(p),document.body.append(p),()=>p.remove()}),viewport$:r})))}function cs(e,{alert$:t}){return t.pipe(b(r=>L($(!0),$(!1).pipe(nt(2e3))).pipe(m(o=>({message:r,active:o})))))}function ni(e,t){let r=j(".md-typeset",e);return H(()=>{let o=new T;return o.subscribe(({message:n,active:i})=>{e.classList.toggle("md-dialog--active",i),r.textContent=n}),cs(e,t).pipe(O(n=>o.next(n)),A(()=>o.complete()),m(n=>P({ref:e},n)))})}var ps=0;function ls(e,t){document.body.append(e);let{width:r}=de(e);e.style.setProperty("--md-tooltip-width",`${r}px`),e.remove();let o=vr(t),n=typeof o!="undefined"?Ge(o):$({x:0,y:0}),i=L(Ye(t),it(t)).pipe(Y());return z([i,n]).pipe(m(([s,a])=>{let{x:c,y:p}=Be(t),l=de(t),f=t.closest("table");return f&&t.parentElement&&(c+=f.offsetLeft+t.parentElement.offsetLeft,p+=f.offsetTop+t.parentElement.offsetTop),{active:s,offset:{x:c-a.x+l.width/2-r/2,y:p-a.y+l.height+8}}}))}function ii(e){let t=e.title;if(!t.length)return y;let r=`__tooltip_${ps++}`,o=Dt(r,"inline"),n=j(".md-typeset",o);return n.innerHTML=t,H(()=>{let i=new T;return i.subscribe({next({offset:s}){o.style.setProperty("--md-tooltip-x",`${s.x}px`),o.style.setProperty("--md-tooltip-y",`${s.y}px`)},complete(){o.style.removeProperty("--md-tooltip-x"),o.style.removeProperty("--md-tooltip-y")}}),L(i.pipe(g(({active:s})=>s)),i.pipe(Ae(250),g(({active:s})=>!s))).subscribe({next({active:s}){s?(e.insertAdjacentElement("afterend",o),e.setAttribute("aria-describedby",r),e.removeAttribute("title")):(o.remove(),e.removeAttribute("aria-describedby"),e.setAttribute("title",t))},complete(){o.remove(),e.removeAttribute("aria-describedby"),e.setAttribute("title",t)}}),i.pipe($e(16,ye)).subscribe(({active:s})=>{o.classList.toggle("md-tooltip--active",s)}),i.pipe(gt(125,ye),g(()=>!!e.offsetParent),m(()=>e.offsetParent.getBoundingClientRect()),m(({x:s})=>s)).subscribe({next(s){s?o.style.setProperty("--md-tooltip-0",`${-s}px`):o.style.removeProperty("--md-tooltip-0")},complete(){o.style.removeProperty("--md-tooltip-0")}}),ls(o,e).pipe(O(s=>i.next(s)),A(()=>i.complete()),m(s=>P({ref:e},s)))}).pipe(et(pe))}function ms({viewport$:e}){if(!V("header.autohide"))return $(!1);let t=e.pipe(m(({offset:{y:n}})=>n),ot(2,1),m(([n,i])=>[nMath.abs(i-n.y)>100),m(([,[n]])=>n),Y()),o=Je("search");return z([e,o]).pipe(m(([{offset:n},i])=>n.y>400&&!i),Y(),b(n=>n?r:$(!1)),Q(!1))}function ai(e,t){return H(()=>z([Le(e),ms(t)])).pipe(m(([{height:r},o])=>({height:r,hidden:o})),Y((r,o)=>r.height===o.height&&r.hidden===o.hidden),Z(1))}function si(e,{header$:t,main$:r}){return H(()=>{let o=new T,n=o.pipe(oe(),ae(!0));o.pipe(ne("active"),Pe(t)).subscribe(([{active:s},{hidden:a}])=>{e.classList.toggle("md-header--shadow",s&&!a),e.hidden=a});let i=fe(M("[title]",e)).pipe(g(()=>V("content.tooltips")),J(s=>ii(s)));return r.subscribe(o),t.pipe(W(n),m(s=>P({ref:e},s)),Ve(i.pipe(W(n))))})}function fs(e,{viewport$:t,header$:r}){return Er(e,{viewport$:t,header$:r}).pipe(m(({offset:{y:o}})=>{let{height:n}=de(e);return{active:n>0&&o>=n}}),ne("active"))}function ci(e,t){return H(()=>{let r=new T;r.subscribe({next({active:n}){e.classList.toggle("md-header__title--active",n)},complete(){e.classList.remove("md-header__title--active")}});let o=ue(".md-content h1");return typeof o=="undefined"?y:fs(o,t).pipe(O(n=>r.next(n)),A(()=>r.complete()),m(n=>P({ref:e},n)))})}function pi(e,{viewport$:t,header$:r}){let o=r.pipe(m(({height:i})=>i),Y()),n=o.pipe(b(()=>Le(e).pipe(m(({height:i})=>({top:e.offsetTop,bottom:e.offsetTop+i})),ne("bottom"))));return z([o,n,t]).pipe(m(([i,{top:s,bottom:a},{offset:{y:c},size:{height:p}}])=>(p=Math.max(0,p-Math.max(0,s-c,i)-Math.max(0,p+c-a)),{offset:s-i,height:p,active:s-i<=c})),Y((i,s)=>i.offset===s.offset&&i.height===s.height&&i.active===s.active))}function us(e){let t=__md_get("__palette")||{index:e.findIndex(o=>matchMedia(o.getAttribute("data-md-color-media")).matches)},r=Math.max(0,Math.min(t.index,e.length-1));return $(...e).pipe(J(o=>h(o,"change").pipe(m(()=>o))),Q(e[r]),m(o=>({index:e.indexOf(o),color:{media:o.getAttribute("data-md-color-media"),scheme:o.getAttribute("data-md-color-scheme"),primary:o.getAttribute("data-md-color-primary"),accent:o.getAttribute("data-md-color-accent")}})),Z(1))}function li(e){let t=M("input",e),r=x("meta",{name:"theme-color"});document.head.appendChild(r);let o=x("meta",{name:"color-scheme"});document.head.appendChild(o);let n=Wt("(prefers-color-scheme: light)");return H(()=>{let i=new T;return i.subscribe(s=>{if(document.body.setAttribute("data-md-color-switching",""),s.color.media==="(prefers-color-scheme)"){let a=matchMedia("(prefers-color-scheme: light)"),c=document.querySelector(a.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");s.color.scheme=c.getAttribute("data-md-color-scheme"),s.color.primary=c.getAttribute("data-md-color-primary"),s.color.accent=c.getAttribute("data-md-color-accent")}for(let[a,c]of Object.entries(s.color))document.body.setAttribute(`data-md-color-${a}`,c);for(let a=0;as.key==="Enter"),te(i,(s,a)=>a)).subscribe(({index:s})=>{s=(s+1)%t.length,t[s].click(),t[s].focus()}),i.pipe(m(()=>{let s=Ce("header"),a=window.getComputedStyle(s);return o.content=a.colorScheme,a.backgroundColor.match(/\d+/g).map(c=>(+c).toString(16).padStart(2,"0")).join("")})).subscribe(s=>r.content=`#${s}`),i.pipe(xe(pe)).subscribe(()=>{document.body.removeAttribute("data-md-color-switching")}),us(t).pipe(W(n.pipe(Ie(1))),vt(),O(s=>i.next(s)),A(()=>i.complete()),m(s=>P({ref:e},s)))})}function mi(e,{progress$:t}){return H(()=>{let r=new T;return r.subscribe(({value:o})=>{e.style.setProperty("--md-progress-value",`${o}`)}),t.pipe(O(o=>r.next({value:o})),A(()=>r.complete()),m(o=>({ref:e,value:o})))})}function fi(e,t){return e.protocol=t.protocol,e.hostname=t.hostname,e}function ds(e,t){let r=new Map;for(let o of M("url",e)){let n=j("loc",o),i=[fi(new URL(n.textContent),t)];r.set(`${i[0]}`,i);for(let s of M("[rel=alternate]",o)){let a=s.getAttribute("href");a!=null&&i.push(fi(new URL(a),t))}}return r}function kt(e){return En(new URL("sitemap.xml",e)).pipe(m(t=>ds(t,new URL(e))),ve(()=>$(new Map)),le())}function ui({document$:e}){let t=new Map;e.pipe(b(()=>M("link[rel=alternate]")),m(r=>new URL(r.href)),g(r=>!t.has(r.toString())),J(r=>kt(r).pipe(m(o=>[r,o]),ve(()=>y)))).subscribe(([r,o])=>{t.set(r.toString().replace(/\/$/,""),o)}),h(document.body,"click").pipe(g(r=>!r.metaKey&&!r.ctrlKey),b(r=>{if(r.target instanceof Element){let o=r.target.closest("a");if(o&&!o.target){let n=[...t].find(([f])=>o.href.startsWith(`${f}/`));if(typeof n=="undefined")return y;let[i,s]=n,a=we();if(a.href.startsWith(i))return y;let c=Te(),p=a.href.replace(c.base,"");p=`${i}/${p}`;let l=s.has(p.split("#")[0])?new URL(p,c.base):new URL(i);return r.preventDefault(),$(l)}}return y})).subscribe(r=>st(r,!0))}var co=$t(ao());function hs(e){e.setAttribute("data-md-copying","");let t=e.closest("[data-copy]"),r=t?t.getAttribute("data-copy"):e.innerText;return e.removeAttribute("data-md-copying"),r.trimEnd()}function di({alert$:e}){co.default.isSupported()&&new F(t=>{new co.default("[data-clipboard-target], [data-clipboard-text]",{text:r=>r.getAttribute("data-clipboard-text")||hs(j(r.getAttribute("data-clipboard-target")))}).on("success",r=>t.next(r))}).pipe(O(t=>{t.trigger.focus()}),m(()=>Me("clipboard.copied"))).subscribe(e)}function hi(e,t){if(!(e.target instanceof Element))return y;let r=e.target.closest("a");if(r===null)return y;if(r.target||e.metaKey||e.ctrlKey)return y;let o=new URL(r.href);return o.search=o.hash="",t.has(`${o}`)?(e.preventDefault(),$(r)):y}function bi(e){let t=new Map;for(let r of M(":scope > *",e.head))t.set(r.outerHTML,r);return t}function vi(e){for(let t of M("[href], [src]",e))for(let r of["href","src"]){let o=t.getAttribute(r);if(o&&!/^(?:[a-z]+:)?\/\//i.test(o)){t[r]=t[r];break}}return $(e)}function bs(e){for(let o of["[data-md-component=announce]","[data-md-component=container]","[data-md-component=header-topic]","[data-md-component=outdated]","[data-md-component=logo]","[data-md-component=skip]",...V("navigation.tabs.sticky")?["[data-md-component=tabs]"]:[]]){let n=ue(o),i=ue(o,e);typeof n!="undefined"&&typeof i!="undefined"&&n.replaceWith(i)}let t=bi(document);for(let[o,n]of bi(e))t.has(o)?t.delete(o):document.head.appendChild(n);for(let o of t.values()){let n=o.getAttribute("name");n!=="theme-color"&&n!=="color-scheme"&&o.remove()}let r=Ce("container");return Ke(M("script",r)).pipe(b(o=>{let n=e.createElement("script");if(o.src){for(let i of o.getAttributeNames())n.setAttribute(i,o.getAttribute(i));return o.replaceWith(n),new F(i=>{n.onload=()=>i.complete()})}else return n.textContent=o.textContent,o.replaceWith(n),y}),oe(),ae(document))}function gi({sitemap$:e,location$:t,viewport$:r,progress$:o}){if(location.protocol==="file:")return y;$(document).subscribe(vi);let n=h(document.body,"click").pipe(Pe(e),b(([a,c])=>hi(a,c)),m(({href:a})=>new URL(a)),le()),i=h(window,"popstate").pipe(m(we),le());n.pipe(te(r)).subscribe(([a,{offset:c}])=>{history.replaceState(c,""),history.pushState(null,"",a)}),L(n,i).subscribe(t);let s=t.pipe(ne("pathname"),b(a=>xr(a,{progress$:o}).pipe(ve(()=>(st(a,!0),y)))),b(vi),b(bs),le());return L(s.pipe(te(t,(a,c)=>c)),s.pipe(b(()=>t),ne("hash")),t.pipe(Y((a,c)=>a.pathname===c.pathname&&a.hash===c.hash),b(()=>n),O(()=>history.back()))).subscribe(a=>{var c,p;history.state!==null||!a.hash?window.scrollTo(0,(p=(c=history.state)==null?void 0:c.y)!=null?p:0):(history.scrollRestoration="auto",gn(a.hash),history.scrollRestoration="manual")}),t.subscribe(()=>{history.scrollRestoration="manual"}),h(window,"beforeunload").subscribe(()=>{history.scrollRestoration="auto"}),r.pipe(ne("offset"),Ae(100)).subscribe(({offset:a})=>{history.replaceState(a,"")}),V("navigation.instant.prefetch")&&L(h(document.body,"mousemove"),h(document.body,"focusin")).pipe(Pe(e),b(([a,c])=>hi(a,c)),Ae(25),Qr(({href:a})=>a),hr(a=>{let c=document.createElement("link");return c.rel="prefetch",c.href=a.toString(),document.head.appendChild(c),h(c,"load").pipe(m(()=>c),Ee(1))})).subscribe(a=>a.remove()),s}var yi=$t(ro());function xi(e){let t=e.separator.split("|").map(n=>n.replace(/(\(\?[!=<][^)]+\))/g,"").length===0?"\uFFFD":n).join("|"),r=new RegExp(t,"img"),o=(n,i,s)=>`${i}${s}`;return n=>{n=n.replace(/[\s*+\-:~^]+/g," ").replace(/&/g,"&").trim();let i=new RegExp(`(^|${e.separator}|)(${n.replace(/[|\\{}()[\]^$+*?.-]/g,"\\$&").replace(r,"|")})`,"img");return s=>(0,yi.default)(s).replace(i,o).replace(/<\/mark>(\s+)]*>/img,"$1")}}function zt(e){return e.type===1}function Sr(e){return e.type===3}function Ei(e,t){let r=Mn(e);return L($(location.protocol!=="file:"),Je("search")).pipe(Re(o=>o),b(()=>t)).subscribe(({config:o,docs:n})=>r.next({type:0,data:{config:o,docs:n,options:{suggest:V("search.suggest")}}})),r}function wi(e){var l;let{selectedVersionSitemap:t,selectedVersionBaseURL:r,currentLocation:o,currentBaseURL:n}=e,i=(l=po(n))==null?void 0:l.pathname;if(i===void 0)return;let s=ys(o.pathname,i);if(s===void 0)return;let a=Es(t.keys());if(!t.has(a))return;let c=po(s,a);if(!c||!t.has(c.href))return;let p=po(s,r);if(p)return p.hash=o.hash,p.search=o.search,p}function po(e,t){try{return new URL(e,t)}catch(r){return}}function ys(e,t){if(e.startsWith(t))return e.slice(t.length)}function xs(e,t){let r=Math.min(e.length,t.length),o;for(o=0;oy)),o=r.pipe(m(n=>{let[,i]=t.base.match(/([^/]+)\/?$/);return n.find(({version:s,aliases:a})=>s===i||a.includes(i))||n[0]}));r.pipe(m(n=>new Map(n.map(i=>[`${new URL(`../${i.version}/`,t.base)}`,i]))),b(n=>h(document.body,"click").pipe(g(i=>!i.metaKey&&!i.ctrlKey),te(o),b(([i,s])=>{if(i.target instanceof Element){let a=i.target.closest("a");if(a&&!a.target&&n.has(a.href)){let c=a.href;return!i.target.closest(".md-version")&&n.get(c)===s?y:(i.preventDefault(),$(new URL(c)))}}return y}),b(i=>kt(i).pipe(m(s=>{var a;return(a=wi({selectedVersionSitemap:s,selectedVersionBaseURL:i,currentLocation:we(),currentBaseURL:t.base}))!=null?a:i})))))).subscribe(n=>st(n,!0)),z([r,o]).subscribe(([n,i])=>{j(".md-header__topic").appendChild(Wn(n,i))}),e.pipe(b(()=>o)).subscribe(n=>{var a;let i=new URL(t.base),s=__md_get("__outdated",sessionStorage,i);if(s===null){s=!0;let c=((a=t.version)==null?void 0:a.default)||"latest";Array.isArray(c)||(c=[c]);e:for(let p of c)for(let l of n.aliases.concat(n.version))if(new RegExp(p,"i").test(l)){s=!1;break e}__md_set("__outdated",s,sessionStorage,i)}if(s)for(let c of me("outdated"))c.hidden=!1})}function ws(e,{worker$:t}){let{searchParams:r}=we();r.has("q")&&(at("search",!0),e.value=r.get("q"),e.focus(),Je("search").pipe(Re(i=>!i)).subscribe(()=>{let i=we();i.searchParams.delete("q"),history.replaceState({},"",`${i}`)}));let o=Ye(e),n=L(t.pipe(Re(zt)),h(e,"keyup"),o).pipe(m(()=>e.value),Y());return z([n,o]).pipe(m(([i,s])=>({value:i,focus:s})),Z(1))}function Si(e,{worker$:t}){let r=new T,o=r.pipe(oe(),ae(!0));z([t.pipe(Re(zt)),r],(i,s)=>s).pipe(ne("value")).subscribe(({value:i})=>t.next({type:2,data:i})),r.pipe(ne("focus")).subscribe(({focus:i})=>{i&&at("search",i)}),h(e.form,"reset").pipe(W(o)).subscribe(()=>e.focus());let n=j("header [for=__search]");return h(n,"click").subscribe(()=>e.focus()),ws(e,{worker$:t}).pipe(O(i=>r.next(i)),A(()=>r.complete()),m(i=>P({ref:e},i)),Z(1))}function Oi(e,{worker$:t,query$:r}){let o=new T,n=un(e.parentElement).pipe(g(Boolean)),i=e.parentElement,s=j(":scope > :first-child",e),a=j(":scope > :last-child",e);Je("search").subscribe(l=>{a.setAttribute("role",l?"list":"presentation"),a.hidden=!l}),o.pipe(te(r),Gr(t.pipe(Re(zt)))).subscribe(([{items:l},{value:f}])=>{switch(l.length){case 0:s.textContent=f.length?Me("search.result.none"):Me("search.result.placeholder");break;case 1:s.textContent=Me("search.result.one");break;default:let u=br(l.length);s.textContent=Me("search.result.other",u)}});let c=o.pipe(O(()=>a.innerHTML=""),b(({items:l})=>L($(...l.slice(0,10)),$(...l.slice(10)).pipe(ot(4),Xr(n),b(([f])=>f)))),m(Fn),le());return c.subscribe(l=>a.appendChild(l)),c.pipe(J(l=>{let f=ue("details",l);return typeof f=="undefined"?y:h(f,"toggle").pipe(W(o),m(()=>f))})).subscribe(l=>{l.open===!1&&l.offsetTop<=i.scrollTop&&i.scrollTo({top:l.offsetTop})}),t.pipe(g(Sr),m(({data:l})=>l)).pipe(O(l=>o.next(l)),A(()=>o.complete()),m(l=>P({ref:e},l)))}function Ts(e,{query$:t}){return t.pipe(m(({value:r})=>{let o=we();return o.hash="",r=r.replace(/\s+/g,"+").replace(/&/g,"%26").replace(/=/g,"%3D"),o.search=`q=${r}`,{url:o}}))}function Li(e,t){let r=new T,o=r.pipe(oe(),ae(!0));return r.subscribe(({url:n})=>{e.setAttribute("data-clipboard-text",e.href),e.href=`${n}`}),h(e,"click").pipe(W(o)).subscribe(n=>n.preventDefault()),Ts(e,t).pipe(O(n=>r.next(n)),A(()=>r.complete()),m(n=>P({ref:e},n)))}function Mi(e,{worker$:t,keyboard$:r}){let o=new T,n=Ce("search-query"),i=L(h(n,"keydown"),h(n,"focus")).pipe(xe(pe),m(()=>n.value),Y());return o.pipe(Pe(i),m(([{suggest:a},c])=>{let p=c.split(/([\s-]+)/);if(a!=null&&a.length&&p[p.length-1]){let l=a[a.length-1];l.startsWith(p[p.length-1])&&(p[p.length-1]=l)}else p.length=0;return p})).subscribe(a=>e.innerHTML=a.join("").replace(/\s/g," ")),r.pipe(g(({mode:a})=>a==="search")).subscribe(a=>{a.type==="ArrowRight"&&e.innerText.length&&n.selectionStart===n.value.length&&(n.value=e.innerText)}),t.pipe(g(Sr),m(({data:a})=>a)).pipe(O(a=>o.next(a)),A(()=>o.complete()),m(()=>({ref:e})))}function _i(e,{index$:t,keyboard$:r}){let o=Te();try{let n=Ei(o.search,t),i=Ce("search-query",e),s=Ce("search-result",e);h(e,"click").pipe(g(({target:c})=>c instanceof Element&&!!c.closest("a"))).subscribe(()=>at("search",!1)),r.pipe(g(({mode:c})=>c==="search")).subscribe(c=>{let p=Ne();switch(c.type){case"Enter":if(p===i){let l=new Map;for(let f of M(":first-child [href]",s)){let u=f.firstElementChild;l.set(f,parseFloat(u.getAttribute("data-md-score")))}if(l.size){let[[f]]=[...l].sort(([,u],[,d])=>d-u);f.click()}c.claim()}break;case"Escape":case"Tab":at("search",!1),i.blur();break;case"ArrowUp":case"ArrowDown":if(typeof p=="undefined")i.focus();else{let l=[i,...M(":not(details) > [href], summary, details[open] [href]",s)],f=Math.max(0,(Math.max(0,l.indexOf(p))+l.length+(c.type==="ArrowUp"?-1:1))%l.length);l[f].focus()}c.claim();break;default:i!==Ne()&&i.focus()}}),r.pipe(g(({mode:c})=>c==="global")).subscribe(c=>{switch(c.type){case"f":case"s":case"/":i.focus(),i.select(),c.claim();break}});let a=Si(i,{worker$:n});return L(a,Oi(s,{worker$:n,query$:a})).pipe(Ve(...me("search-share",e).map(c=>Li(c,{query$:a})),...me("search-suggest",e).map(c=>Mi(c,{worker$:n,keyboard$:r}))))}catch(n){return e.hidden=!0,tt}}function Ai(e,{index$:t,location$:r}){return z([t,r.pipe(Q(we()),g(o=>!!o.searchParams.get("h")))]).pipe(m(([o,n])=>xi(o.config)(n.searchParams.get("h"))),m(o=>{var s;let n=new Map,i=document.createNodeIterator(e,NodeFilter.SHOW_TEXT);for(let a=i.nextNode();a;a=i.nextNode())if((s=a.parentElement)!=null&&s.offsetHeight){let c=a.textContent,p=o(c);p.length>c.length&&n.set(a,p)}for(let[a,c]of n){let{childNodes:p}=x("span",null,c);a.replaceWith(...Array.from(p))}return{ref:e,nodes:n}}))}function Ss(e,{viewport$:t,main$:r}){let o=e.closest(".md-grid"),n=o.offsetTop-o.parentElement.offsetTop;return z([r,t]).pipe(m(([{offset:i,height:s},{offset:{y:a}}])=>(s=s+Math.min(n,Math.max(0,a-i))-n,{height:s,locked:a>=i+n})),Y((i,s)=>i.height===s.height&&i.locked===s.locked))}function lo(e,o){var n=o,{header$:t}=n,r=vo(n,["header$"]);let i=j(".md-sidebar__scrollwrap",e),{y:s}=Be(i);return H(()=>{let a=new T,c=a.pipe(oe(),ae(!0)),p=a.pipe($e(0,ye));return p.pipe(te(t)).subscribe({next([{height:l},{height:f}]){i.style.height=`${l-2*s}px`,e.style.top=`${f}px`},complete(){i.style.height="",e.style.top=""}}),p.pipe(Re()).subscribe(()=>{for(let l of M(".md-nav__link--active[href]",e)){if(!l.clientHeight)continue;let f=l.closest(".md-sidebar__scrollwrap");if(typeof f!="undefined"){let u=l.offsetTop-f.offsetTop,{height:d}=de(f);f.scrollTo({top:u-d/2})}}}),fe(M("label[tabindex]",e)).pipe(J(l=>h(l,"click").pipe(xe(pe),m(()=>l),W(c)))).subscribe(l=>{let f=j(`[id="${l.htmlFor}"]`);j(`[aria-labelledby="${l.id}"]`).setAttribute("aria-expanded",`${f.checked}`)}),V("content.tooltips")&&fe(M("abbr[title]",e)).pipe(J(l=>Xe(l,{viewport$})),W(c)).subscribe(),Ss(e,r).pipe(O(l=>a.next(l)),A(()=>a.complete()),m(l=>P({ref:e},l)))})}function Ci(e,t){if(typeof t!="undefined"){let r=`https://api.github.com/repos/${e}/${t}`;return rt(ze(`${r}/releases/latest`).pipe(ve(()=>y),m(o=>({version:o.tag_name})),Qe({})),ze(r).pipe(ve(()=>y),m(o=>({stars:o.stargazers_count,forks:o.forks_count})),Qe({}))).pipe(m(([o,n])=>P(P({},o),n)))}else{let r=`https://api.github.com/users/${e}`;return ze(r).pipe(m(o=>({repositories:o.public_repos})),Qe({}))}}function ki(e,t){let r=`https://${e}/api/v4/projects/${encodeURIComponent(t)}`;return rt(ze(`${r}/releases/permalink/latest`).pipe(ve(()=>y),m(({tag_name:o})=>({version:o})),Qe({})),ze(r).pipe(ve(()=>y),m(({star_count:o,forks_count:n})=>({stars:o,forks:n})),Qe({}))).pipe(m(([o,n])=>P(P({},o),n)))}function Hi(e){let t=e.match(/^.+github\.com\/([^/]+)\/?([^/]+)?/i);if(t){let[,r,o]=t;return Ci(r,o)}if(t=e.match(/^.+?([^/]*gitlab[^/]+)\/(.+?)\/?$/i),t){let[,r,o]=t;return ki(r,o)}return y}var Os;function Ls(e){return Os||(Os=H(()=>{let t=__md_get("__source",sessionStorage);if(t)return $(t);if(me("consent").length){let o=__md_get("__consent");if(!(o&&o.github))return y}return Hi(e.href).pipe(O(o=>__md_set("__source",o,sessionStorage)))}).pipe(ve(()=>y),g(t=>Object.keys(t).length>0),m(t=>({facts:t})),Z(1)))}function $i(e){let t=j(":scope > :last-child",e);return H(()=>{let r=new T;return r.subscribe(({facts:o})=>{t.appendChild(jn(o)),t.classList.add("md-source__repository--active")}),Ls(e).pipe(O(o=>r.next(o)),A(()=>r.complete()),m(o=>P({ref:e},o)))})}function Ms(e,{viewport$:t,header$:r}){return Le(document.body).pipe(b(()=>Er(e,{header$:r,viewport$:t})),m(({offset:{y:o}})=>({hidden:o>=10})),ne("hidden"))}function Pi(e,t){return H(()=>{let r=new T;return r.subscribe({next({hidden:o}){e.hidden=o},complete(){e.hidden=!1}}),(V("navigation.tabs.sticky")?$({hidden:!1}):Ms(e,t)).pipe(O(o=>r.next(o)),A(()=>r.complete()),m(o=>P({ref:e},o)))})}function _s(e,{viewport$:t,header$:r}){let o=new Map,n=M(".md-nav__link",e);for(let a of n){let c=decodeURIComponent(a.hash.substring(1)),p=ue(`[id="${c}"]`);typeof p!="undefined"&&o.set(a,p)}let i=r.pipe(ne("height"),m(({height:a})=>{let c=Ce("main"),p=j(":scope > :first-child",c);return a+.8*(p.offsetTop-c.offsetTop)}),le());return Le(document.body).pipe(ne("height"),b(a=>H(()=>{let c=[];return $([...o].reduce((p,[l,f])=>{for(;c.length&&o.get(c[c.length-1]).tagName>=f.tagName;)c.pop();let u=f.offsetTop;for(;!u&&f.parentElement;)f=f.parentElement,u=f.offsetTop;let d=f.offsetParent;for(;d;d=d.offsetParent)u+=d.offsetTop;return p.set([...c=[...c,l]].reverse(),u)},new Map))}).pipe(m(c=>new Map([...c].sort(([,p],[,l])=>p-l))),Pe(i),b(([c,p])=>t.pipe(Ut(([l,f],{offset:{y:u},size:d})=>{let v=u+d.height>=Math.floor(a.height);for(;f.length;){let[,S]=f[0];if(S-p=u&&!v)f=[l.pop(),...f];else break}return[l,f]},[[],[...c]]),Y((l,f)=>l[0]===f[0]&&l[1]===f[1])))))).pipe(m(([a,c])=>({prev:a.map(([p])=>p),next:c.map(([p])=>p)})),Q({prev:[],next:[]}),ot(2,1),m(([a,c])=>a.prev.length{let i=new T,s=i.pipe(oe(),ae(!0));if(i.subscribe(({prev:a,next:c})=>{for(let[p]of c)p.classList.remove("md-nav__link--passed"),p.classList.remove("md-nav__link--active");for(let[p,[l]]of a.entries())l.classList.add("md-nav__link--passed"),l.classList.toggle("md-nav__link--active",p===a.length-1)}),V("toc.follow")){let a=L(t.pipe(Ae(1),m(()=>{})),t.pipe(Ae(250),m(()=>"smooth")));i.pipe(g(({prev:c})=>c.length>0),Pe(o.pipe(xe(pe))),te(a)).subscribe(([[{prev:c}],p])=>{let[l]=c[c.length-1];if(l.offsetHeight){let f=vr(l);if(typeof f!="undefined"){let u=l.offsetTop-f.offsetTop,{height:d}=de(f);f.scrollTo({top:u-d/2,behavior:p})}}})}return V("navigation.tracking")&&t.pipe(W(s),ne("offset"),Ae(250),Ie(1),W(n.pipe(Ie(1))),vt({delay:250}),te(i)).subscribe(([,{prev:a}])=>{let c=we(),p=a[a.length-1];if(p&&p.length){let[l]=p,{hash:f}=new URL(l.href);c.hash!==f&&(c.hash=f,history.replaceState({},"",`${c}`))}else c.hash="",history.replaceState({},"",`${c}`)}),_s(e,{viewport$:t,header$:r}).pipe(O(a=>i.next(a)),A(()=>i.complete()),m(a=>P({ref:e},a)))})}function As(e,{viewport$:t,main$:r,target$:o}){let n=t.pipe(m(({offset:{y:s}})=>s),ot(2,1),m(([s,a])=>s>a&&a>0),Y()),i=r.pipe(m(({active:s})=>s));return z([i,n]).pipe(m(([s,a])=>!(s&&a)),Y(),W(o.pipe(Ie(1))),ae(!0),vt({delay:250}),m(s=>({hidden:s})))}function Ii(e,{viewport$:t,header$:r,main$:o,target$:n}){let i=new T,s=i.pipe(oe(),ae(!0));return i.subscribe({next({hidden:a}){e.hidden=a,a?(e.setAttribute("tabindex","-1"),e.blur()):e.removeAttribute("tabindex")},complete(){e.style.top="",e.hidden=!0,e.removeAttribute("tabindex")}}),r.pipe(W(s),ne("height")).subscribe(({height:a})=>{e.style.top=`${a+16}px`}),h(e,"click").subscribe(a=>{a.preventDefault(),window.scrollTo({top:0})}),As(e,{viewport$:t,main$:o,target$:n}).pipe(O(a=>i.next(a)),A(()=>i.complete()),m(a=>P({ref:e},a)))}function Fi({document$:e,viewport$:t}){e.pipe(b(()=>M(".md-ellipsis")),J(r=>mt(r).pipe(W(e.pipe(Ie(1))),g(o=>o),m(()=>r),Ee(1))),g(r=>r.offsetWidth{let o=r.innerText,n=r.closest("a")||r;return n.title=o,V("content.tooltips")?Xe(n,{viewport$:t}).pipe(W(e.pipe(Ie(1))),A(()=>n.removeAttribute("title"))):y})).subscribe(),V("content.tooltips")&&e.pipe(b(()=>M(".md-status")),J(r=>Xe(r,{viewport$:t}))).subscribe()}function ji({document$:e,tablet$:t}){e.pipe(b(()=>M(".md-toggle--indeterminate")),O(r=>{r.indeterminate=!0,r.checked=!1}),J(r=>h(r,"change").pipe(Jr(()=>r.classList.contains("md-toggle--indeterminate")),m(()=>r))),te(t)).subscribe(([r,o])=>{r.classList.remove("md-toggle--indeterminate"),o&&(r.checked=!1)})}function Cs(){return/(iPad|iPhone|iPod)/.test(navigator.userAgent)}function Ui({document$:e}){e.pipe(b(()=>M("[data-md-scrollfix]")),O(t=>t.removeAttribute("data-md-scrollfix")),g(Cs),J(t=>h(t,"touchstart").pipe(m(()=>t)))).subscribe(t=>{let r=t.scrollTop;r===0?t.scrollTop=1:r+t.offsetHeight===t.scrollHeight&&(t.scrollTop=r-1)})}function Wi({viewport$:e,tablet$:t}){z([Je("search"),t]).pipe(m(([r,o])=>r&&!o),b(r=>$(r).pipe(nt(r?400:100))),te(e)).subscribe(([r,{offset:{y:o}}])=>{if(r)document.body.setAttribute("data-md-scrolllock",""),document.body.style.top=`-${o}px`;else{let n=-1*parseInt(document.body.style.top,10);document.body.removeAttribute("data-md-scrolllock"),document.body.style.top="",n&&window.scrollTo(0,n)}})}Object.entries||(Object.entries=function(e){let t=[];for(let r of Object.keys(e))t.push([r,e[r]]);return t});Object.values||(Object.values=function(e){let t=[];for(let r of Object.keys(e))t.push(e[r]);return t});typeof Element!="undefined"&&(Element.prototype.scrollTo||(Element.prototype.scrollTo=function(e,t){typeof e=="object"?(this.scrollLeft=e.left,this.scrollTop=e.top):(this.scrollLeft=e,this.scrollTop=t)}),Element.prototype.replaceWith||(Element.prototype.replaceWith=function(...e){let t=this.parentNode;if(t){e.length===0&&t.removeChild(this);for(let r=e.length-1;r>=0;r--){let o=e[r];typeof o=="string"?o=document.createTextNode(o):o.parentNode&&o.parentNode.removeChild(o),r?t.insertBefore(this.previousSibling,o):t.replaceChild(o,this)}}}));function ks(){return location.protocol==="file:"?_t(`${new URL("search/search_index.js",Or.base)}`).pipe(m(()=>__index),Z(1)):ze(new URL("search/search_index.json",Or.base))}document.documentElement.classList.remove("no-js");document.documentElement.classList.add("js");var ct=an(),Kt=bn(),Ht=yn(Kt),mo=hn(),ke=Ln(),Lr=Wt("(min-width: 60em)"),Vi=Wt("(min-width: 76.25em)"),Ni=xn(),Or=Te(),zi=document.forms.namedItem("search")?ks():tt,fo=new T;di({alert$:fo});ui({document$:ct});var uo=new T,qi=kt(Or.base);V("navigation.instant")&&gi({sitemap$:qi,location$:Kt,viewport$:ke,progress$:uo}).subscribe(ct);var Di;((Di=Or.version)==null?void 0:Di.provider)==="mike"&&Ti({document$:ct});L(Kt,Ht).pipe(nt(125)).subscribe(()=>{at("drawer",!1),at("search",!1)});mo.pipe(g(({mode:e})=>e==="global")).subscribe(e=>{switch(e.type){case"p":case",":let t=ue("link[rel=prev]");typeof t!="undefined"&&st(t);break;case"n":case".":let r=ue("link[rel=next]");typeof r!="undefined"&&st(r);break;case"Enter":let o=Ne();o instanceof HTMLLabelElement&&o.click()}});Fi({viewport$:ke,document$:ct});ji({document$:ct,tablet$:Lr});Ui({document$:ct});Wi({viewport$:ke,tablet$:Lr});var ft=ai(Ce("header"),{viewport$:ke}),qt=ct.pipe(m(()=>Ce("main")),b(e=>pi(e,{viewport$:ke,header$:ft})),Z(1)),Hs=L(...me("consent").map(e=>An(e,{target$:Ht})),...me("dialog").map(e=>ni(e,{alert$:fo})),...me("palette").map(e=>li(e)),...me("progress").map(e=>mi(e,{progress$:uo})),...me("search").map(e=>_i(e,{index$:zi,keyboard$:mo})),...me("source").map(e=>$i(e))),$s=H(()=>L(...me("announce").map(e=>_n(e)),...me("content").map(e=>oi(e,{sitemap$:qi,viewport$:ke,target$:Ht,print$:Ni})),...me("content").map(e=>V("search.highlight")?Ai(e,{index$:zi,location$:Kt}):y),...me("header").map(e=>si(e,{viewport$:ke,header$:ft,main$:qt})),...me("header-title").map(e=>ci(e,{viewport$:ke,header$:ft})),...me("sidebar").map(e=>e.getAttribute("data-md-type")==="navigation"?eo(Vi,()=>lo(e,{viewport$:ke,header$:ft,main$:qt})):eo(Lr,()=>lo(e,{viewport$:ke,header$:ft,main$:qt}))),...me("tabs").map(e=>Pi(e,{viewport$:ke,header$:ft})),...me("toc").map(e=>Ri(e,{viewport$:ke,header$:ft,main$:qt,target$:Ht})),...me("top").map(e=>Ii(e,{viewport$:ke,header$:ft,main$:qt,target$:Ht})))),Ki=ct.pipe(b(()=>$s),Ve(Hs),Z(1));Ki.subscribe();window.document$=ct;window.location$=Kt;window.target$=Ht;window.keyboard$=mo;window.viewport$=ke;window.tablet$=Lr;window.screen$=Vi;window.print$=Ni;window.alert$=fo;window.progress$=uo;window.component$=Ki;})(); +//# sourceMappingURL=bundle.79ae519e.min.js.map + diff --git a/en/assets/javascripts/bundle.79ae519e.min.js.map b/en/assets/javascripts/bundle.79ae519e.min.js.map new file mode 100644 index 0000000..5cf0289 --- /dev/null +++ b/en/assets/javascripts/bundle.79ae519e.min.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": ["node_modules/focus-visible/dist/focus-visible.js", "node_modules/escape-html/index.js", "node_modules/clipboard/dist/clipboard.js", "src/templates/assets/javascripts/bundle.ts", "node_modules/tslib/tslib.es6.mjs", "node_modules/rxjs/src/internal/util/isFunction.ts", "node_modules/rxjs/src/internal/util/createErrorClass.ts", "node_modules/rxjs/src/internal/util/UnsubscriptionError.ts", "node_modules/rxjs/src/internal/util/arrRemove.ts", "node_modules/rxjs/src/internal/Subscription.ts", "node_modules/rxjs/src/internal/config.ts", "node_modules/rxjs/src/internal/scheduler/timeoutProvider.ts", "node_modules/rxjs/src/internal/util/reportUnhandledError.ts", "node_modules/rxjs/src/internal/util/noop.ts", "node_modules/rxjs/src/internal/NotificationFactories.ts", "node_modules/rxjs/src/internal/util/errorContext.ts", "node_modules/rxjs/src/internal/Subscriber.ts", "node_modules/rxjs/src/internal/symbol/observable.ts", "node_modules/rxjs/src/internal/util/identity.ts", "node_modules/rxjs/src/internal/util/pipe.ts", "node_modules/rxjs/src/internal/Observable.ts", "node_modules/rxjs/src/internal/util/lift.ts", "node_modules/rxjs/src/internal/operators/OperatorSubscriber.ts", "node_modules/rxjs/src/internal/scheduler/animationFrameProvider.ts", "node_modules/rxjs/src/internal/util/ObjectUnsubscribedError.ts", "node_modules/rxjs/src/internal/Subject.ts", "node_modules/rxjs/src/internal/BehaviorSubject.ts", "node_modules/rxjs/src/internal/scheduler/dateTimestampProvider.ts", "node_modules/rxjs/src/internal/ReplaySubject.ts", "node_modules/rxjs/src/internal/scheduler/Action.ts", "node_modules/rxjs/src/internal/scheduler/intervalProvider.ts", "node_modules/rxjs/src/internal/scheduler/AsyncAction.ts", "node_modules/rxjs/src/internal/Scheduler.ts", "node_modules/rxjs/src/internal/scheduler/AsyncScheduler.ts", "node_modules/rxjs/src/internal/scheduler/async.ts", "node_modules/rxjs/src/internal/scheduler/QueueAction.ts", "node_modules/rxjs/src/internal/scheduler/QueueScheduler.ts", "node_modules/rxjs/src/internal/scheduler/queue.ts", "node_modules/rxjs/src/internal/scheduler/AnimationFrameAction.ts", "node_modules/rxjs/src/internal/scheduler/AnimationFrameScheduler.ts", "node_modules/rxjs/src/internal/scheduler/animationFrame.ts", "node_modules/rxjs/src/internal/observable/empty.ts", "node_modules/rxjs/src/internal/util/isScheduler.ts", "node_modules/rxjs/src/internal/util/args.ts", "node_modules/rxjs/src/internal/util/isArrayLike.ts", "node_modules/rxjs/src/internal/util/isPromise.ts", "node_modules/rxjs/src/internal/util/isInteropObservable.ts", "node_modules/rxjs/src/internal/util/isAsyncIterable.ts", "node_modules/rxjs/src/internal/util/throwUnobservableError.ts", "node_modules/rxjs/src/internal/symbol/iterator.ts", "node_modules/rxjs/src/internal/util/isIterable.ts", "node_modules/rxjs/src/internal/util/isReadableStreamLike.ts", "node_modules/rxjs/src/internal/observable/innerFrom.ts", "node_modules/rxjs/src/internal/util/executeSchedule.ts", "node_modules/rxjs/src/internal/operators/observeOn.ts", "node_modules/rxjs/src/internal/operators/subscribeOn.ts", "node_modules/rxjs/src/internal/scheduled/scheduleObservable.ts", "node_modules/rxjs/src/internal/scheduled/schedulePromise.ts", "node_modules/rxjs/src/internal/scheduled/scheduleArray.ts", "node_modules/rxjs/src/internal/scheduled/scheduleIterable.ts", "node_modules/rxjs/src/internal/scheduled/scheduleAsyncIterable.ts", "node_modules/rxjs/src/internal/scheduled/scheduleReadableStreamLike.ts", "node_modules/rxjs/src/internal/scheduled/scheduled.ts", "node_modules/rxjs/src/internal/observable/from.ts", "node_modules/rxjs/src/internal/observable/of.ts", "node_modules/rxjs/src/internal/observable/throwError.ts", "node_modules/rxjs/src/internal/util/EmptyError.ts", "node_modules/rxjs/src/internal/util/isDate.ts", "node_modules/rxjs/src/internal/operators/map.ts", "node_modules/rxjs/src/internal/util/mapOneOrManyArgs.ts", "node_modules/rxjs/src/internal/util/argsArgArrayOrObject.ts", "node_modules/rxjs/src/internal/util/createObject.ts", "node_modules/rxjs/src/internal/observable/combineLatest.ts", "node_modules/rxjs/src/internal/operators/mergeInternals.ts", "node_modules/rxjs/src/internal/operators/mergeMap.ts", "node_modules/rxjs/src/internal/operators/mergeAll.ts", "node_modules/rxjs/src/internal/operators/concatAll.ts", "node_modules/rxjs/src/internal/observable/concat.ts", "node_modules/rxjs/src/internal/observable/defer.ts", "node_modules/rxjs/src/internal/observable/fromEvent.ts", "node_modules/rxjs/src/internal/observable/fromEventPattern.ts", "node_modules/rxjs/src/internal/observable/timer.ts", "node_modules/rxjs/src/internal/observable/merge.ts", "node_modules/rxjs/src/internal/observable/never.ts", "node_modules/rxjs/src/internal/util/argsOrArgArray.ts", "node_modules/rxjs/src/internal/operators/filter.ts", "node_modules/rxjs/src/internal/observable/zip.ts", "node_modules/rxjs/src/internal/operators/audit.ts", "node_modules/rxjs/src/internal/operators/auditTime.ts", "node_modules/rxjs/src/internal/operators/bufferCount.ts", "node_modules/rxjs/src/internal/operators/catchError.ts", "node_modules/rxjs/src/internal/operators/scanInternals.ts", "node_modules/rxjs/src/internal/operators/combineLatest.ts", "node_modules/rxjs/src/internal/operators/combineLatestWith.ts", "node_modules/rxjs/src/internal/operators/debounce.ts", "node_modules/rxjs/src/internal/operators/debounceTime.ts", "node_modules/rxjs/src/internal/operators/defaultIfEmpty.ts", "node_modules/rxjs/src/internal/operators/take.ts", "node_modules/rxjs/src/internal/operators/ignoreElements.ts", "node_modules/rxjs/src/internal/operators/mapTo.ts", "node_modules/rxjs/src/internal/operators/delayWhen.ts", "node_modules/rxjs/src/internal/operators/delay.ts", "node_modules/rxjs/src/internal/operators/distinct.ts", "node_modules/rxjs/src/internal/operators/distinctUntilChanged.ts", "node_modules/rxjs/src/internal/operators/distinctUntilKeyChanged.ts", "node_modules/rxjs/src/internal/operators/throwIfEmpty.ts", "node_modules/rxjs/src/internal/operators/endWith.ts", "node_modules/rxjs/src/internal/operators/exhaustMap.ts", "node_modules/rxjs/src/internal/operators/finalize.ts", "node_modules/rxjs/src/internal/operators/first.ts", "node_modules/rxjs/src/internal/operators/takeLast.ts", "node_modules/rxjs/src/internal/operators/merge.ts", "node_modules/rxjs/src/internal/operators/mergeWith.ts", "node_modules/rxjs/src/internal/operators/repeat.ts", "node_modules/rxjs/src/internal/operators/scan.ts", "node_modules/rxjs/src/internal/operators/share.ts", "node_modules/rxjs/src/internal/operators/shareReplay.ts", "node_modules/rxjs/src/internal/operators/skip.ts", "node_modules/rxjs/src/internal/operators/skipUntil.ts", "node_modules/rxjs/src/internal/operators/startWith.ts", "node_modules/rxjs/src/internal/operators/switchMap.ts", "node_modules/rxjs/src/internal/operators/takeUntil.ts", "node_modules/rxjs/src/internal/operators/takeWhile.ts", "node_modules/rxjs/src/internal/operators/tap.ts", "node_modules/rxjs/src/internal/operators/throttle.ts", "node_modules/rxjs/src/internal/operators/throttleTime.ts", "node_modules/rxjs/src/internal/operators/withLatestFrom.ts", "node_modules/rxjs/src/internal/operators/zip.ts", "node_modules/rxjs/src/internal/operators/zipWith.ts", "src/templates/assets/javascripts/browser/document/index.ts", "src/templates/assets/javascripts/browser/element/_/index.ts", "src/templates/assets/javascripts/browser/element/focus/index.ts", "src/templates/assets/javascripts/browser/element/hover/index.ts", "src/templates/assets/javascripts/utilities/h/index.ts", "src/templates/assets/javascripts/utilities/round/index.ts", "src/templates/assets/javascripts/browser/script/index.ts", "src/templates/assets/javascripts/browser/element/size/_/index.ts", "src/templates/assets/javascripts/browser/element/size/content/index.ts", "src/templates/assets/javascripts/browser/element/offset/_/index.ts", "src/templates/assets/javascripts/browser/element/offset/content/index.ts", "src/templates/assets/javascripts/browser/element/visibility/index.ts", "src/templates/assets/javascripts/browser/toggle/index.ts", "src/templates/assets/javascripts/browser/keyboard/index.ts", "src/templates/assets/javascripts/browser/location/_/index.ts", "src/templates/assets/javascripts/browser/location/hash/index.ts", "src/templates/assets/javascripts/browser/media/index.ts", "src/templates/assets/javascripts/browser/request/index.ts", "src/templates/assets/javascripts/browser/viewport/offset/index.ts", "src/templates/assets/javascripts/browser/viewport/size/index.ts", "src/templates/assets/javascripts/browser/viewport/_/index.ts", "src/templates/assets/javascripts/browser/viewport/at/index.ts", "src/templates/assets/javascripts/browser/worker/index.ts", "src/templates/assets/javascripts/_/index.ts", "src/templates/assets/javascripts/components/_/index.ts", "src/templates/assets/javascripts/components/announce/index.ts", "src/templates/assets/javascripts/components/consent/index.ts", "src/templates/assets/javascripts/templates/tooltip/index.tsx", "src/templates/assets/javascripts/templates/annotation/index.tsx", "src/templates/assets/javascripts/templates/clipboard/index.tsx", "src/templates/assets/javascripts/templates/search/index.tsx", "src/templates/assets/javascripts/templates/source/index.tsx", "src/templates/assets/javascripts/templates/tabbed/index.tsx", "src/templates/assets/javascripts/templates/table/index.tsx", "src/templates/assets/javascripts/templates/version/index.tsx", "src/templates/assets/javascripts/components/tooltip2/index.ts", "src/templates/assets/javascripts/components/content/annotation/_/index.ts", "src/templates/assets/javascripts/components/content/annotation/list/index.ts", "src/templates/assets/javascripts/components/content/annotation/block/index.ts", "src/templates/assets/javascripts/components/content/code/_/index.ts", "src/templates/assets/javascripts/components/content/details/index.ts", "src/templates/assets/javascripts/components/content/link/index.ts", "src/templates/assets/javascripts/components/content/mermaid/index.css", "src/templates/assets/javascripts/components/content/mermaid/index.ts", "src/templates/assets/javascripts/components/content/table/index.ts", "src/templates/assets/javascripts/components/content/tabs/index.ts", "src/templates/assets/javascripts/components/content/_/index.ts", "src/templates/assets/javascripts/components/dialog/index.ts", "src/templates/assets/javascripts/components/tooltip/index.ts", "src/templates/assets/javascripts/components/header/_/index.ts", "src/templates/assets/javascripts/components/header/title/index.ts", "src/templates/assets/javascripts/components/main/index.ts", "src/templates/assets/javascripts/components/palette/index.ts", "src/templates/assets/javascripts/components/progress/index.ts", "src/templates/assets/javascripts/integrations/sitemap/index.ts", "src/templates/assets/javascripts/integrations/alternate/index.ts", "src/templates/assets/javascripts/integrations/clipboard/index.ts", "src/templates/assets/javascripts/integrations/instant/index.ts", "src/templates/assets/javascripts/integrations/search/highlighter/index.ts", "src/templates/assets/javascripts/integrations/search/worker/message/index.ts", "src/templates/assets/javascripts/integrations/search/worker/_/index.ts", "src/templates/assets/javascripts/integrations/version/findurl/index.ts", "src/templates/assets/javascripts/integrations/version/index.ts", "src/templates/assets/javascripts/components/search/query/index.ts", "src/templates/assets/javascripts/components/search/result/index.ts", "src/templates/assets/javascripts/components/search/share/index.ts", "src/templates/assets/javascripts/components/search/suggest/index.ts", "src/templates/assets/javascripts/components/search/_/index.ts", "src/templates/assets/javascripts/components/search/highlight/index.ts", "src/templates/assets/javascripts/components/sidebar/index.ts", "src/templates/assets/javascripts/components/source/facts/github/index.ts", "src/templates/assets/javascripts/components/source/facts/gitlab/index.ts", "src/templates/assets/javascripts/components/source/facts/_/index.ts", "src/templates/assets/javascripts/components/source/_/index.ts", "src/templates/assets/javascripts/components/tabs/index.ts", "src/templates/assets/javascripts/components/toc/index.ts", "src/templates/assets/javascripts/components/top/index.ts", "src/templates/assets/javascripts/patches/ellipsis/index.ts", "src/templates/assets/javascripts/patches/indeterminate/index.ts", "src/templates/assets/javascripts/patches/scrollfix/index.ts", "src/templates/assets/javascripts/patches/scrolllock/index.ts", "src/templates/assets/javascripts/polyfills/index.ts"], + "sourcesContent": ["(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? factory() :\n typeof define === 'function' && define.amd ? define(factory) :\n (factory());\n}(this, (function () { 'use strict';\n\n /**\n * Applies the :focus-visible polyfill at the given scope.\n * A scope in this case is either the top-level Document or a Shadow Root.\n *\n * @param {(Document|ShadowRoot)} scope\n * @see https://github.com/WICG/focus-visible\n */\n function applyFocusVisiblePolyfill(scope) {\n var hadKeyboardEvent = true;\n var hadFocusVisibleRecently = false;\n var hadFocusVisibleRecentlyTimeout = null;\n\n var inputTypesAllowlist = {\n text: true,\n search: true,\n url: true,\n tel: true,\n email: true,\n password: true,\n number: true,\n date: true,\n month: true,\n week: true,\n time: true,\n datetime: true,\n 'datetime-local': true\n };\n\n /**\n * Helper function for legacy browsers and iframes which sometimes focus\n * elements like document, body, and non-interactive SVG.\n * @param {Element} el\n */\n function isValidFocusTarget(el) {\n if (\n el &&\n el !== document &&\n el.nodeName !== 'HTML' &&\n el.nodeName !== 'BODY' &&\n 'classList' in el &&\n 'contains' in el.classList\n ) {\n return true;\n }\n return false;\n }\n\n /**\n * Computes whether the given element should automatically trigger the\n * `focus-visible` class being added, i.e. whether it should always match\n * `:focus-visible` when focused.\n * @param {Element} el\n * @return {boolean}\n */\n function focusTriggersKeyboardModality(el) {\n var type = el.type;\n var tagName = el.tagName;\n\n if (tagName === 'INPUT' && inputTypesAllowlist[type] && !el.readOnly) {\n return true;\n }\n\n if (tagName === 'TEXTAREA' && !el.readOnly) {\n return true;\n }\n\n if (el.isContentEditable) {\n return true;\n }\n\n return false;\n }\n\n /**\n * Add the `focus-visible` class to the given element if it was not added by\n * the author.\n * @param {Element} el\n */\n function addFocusVisibleClass(el) {\n if (el.classList.contains('focus-visible')) {\n return;\n }\n el.classList.add('focus-visible');\n el.setAttribute('data-focus-visible-added', '');\n }\n\n /**\n * Remove the `focus-visible` class from the given element if it was not\n * originally added by the author.\n * @param {Element} el\n */\n function removeFocusVisibleClass(el) {\n if (!el.hasAttribute('data-focus-visible-added')) {\n return;\n }\n el.classList.remove('focus-visible');\n el.removeAttribute('data-focus-visible-added');\n }\n\n /**\n * If the most recent user interaction was via the keyboard;\n * and the key press did not include a meta, alt/option, or control key;\n * then the modality is keyboard. Otherwise, the modality is not keyboard.\n * Apply `focus-visible` to any current active element and keep track\n * of our keyboard modality state with `hadKeyboardEvent`.\n * @param {KeyboardEvent} e\n */\n function onKeyDown(e) {\n if (e.metaKey || e.altKey || e.ctrlKey) {\n return;\n }\n\n if (isValidFocusTarget(scope.activeElement)) {\n addFocusVisibleClass(scope.activeElement);\n }\n\n hadKeyboardEvent = true;\n }\n\n /**\n * If at any point a user clicks with a pointing device, ensure that we change\n * the modality away from keyboard.\n * This avoids the situation where a user presses a key on an already focused\n * element, and then clicks on a different element, focusing it with a\n * pointing device, while we still think we're in keyboard modality.\n * @param {Event} e\n */\n function onPointerDown(e) {\n hadKeyboardEvent = false;\n }\n\n /**\n * On `focus`, add the `focus-visible` class to the target if:\n * - the target received focus as a result of keyboard navigation, or\n * - the event target is an element that will likely require interaction\n * via the keyboard (e.g. a text box)\n * @param {Event} e\n */\n function onFocus(e) {\n // Prevent IE from focusing the document or HTML element.\n if (!isValidFocusTarget(e.target)) {\n return;\n }\n\n if (hadKeyboardEvent || focusTriggersKeyboardModality(e.target)) {\n addFocusVisibleClass(e.target);\n }\n }\n\n /**\n * On `blur`, remove the `focus-visible` class from the target.\n * @param {Event} e\n */\n function onBlur(e) {\n if (!isValidFocusTarget(e.target)) {\n return;\n }\n\n if (\n e.target.classList.contains('focus-visible') ||\n e.target.hasAttribute('data-focus-visible-added')\n ) {\n // To detect a tab/window switch, we look for a blur event followed\n // rapidly by a visibility change.\n // If we don't see a visibility change within 100ms, it's probably a\n // regular focus change.\n hadFocusVisibleRecently = true;\n window.clearTimeout(hadFocusVisibleRecentlyTimeout);\n hadFocusVisibleRecentlyTimeout = window.setTimeout(function() {\n hadFocusVisibleRecently = false;\n }, 100);\n removeFocusVisibleClass(e.target);\n }\n }\n\n /**\n * If the user changes tabs, keep track of whether or not the previously\n * focused element had .focus-visible.\n * @param {Event} e\n */\n function onVisibilityChange(e) {\n if (document.visibilityState === 'hidden') {\n // If the tab becomes active again, the browser will handle calling focus\n // on the element (Safari actually calls it twice).\n // If this tab change caused a blur on an element with focus-visible,\n // re-apply the class when the user switches back to the tab.\n if (hadFocusVisibleRecently) {\n hadKeyboardEvent = true;\n }\n addInitialPointerMoveListeners();\n }\n }\n\n /**\n * Add a group of listeners to detect usage of any pointing devices.\n * These listeners will be added when the polyfill first loads, and anytime\n * the window is blurred, so that they are active when the window regains\n * focus.\n */\n function addInitialPointerMoveListeners() {\n document.addEventListener('mousemove', onInitialPointerMove);\n document.addEventListener('mousedown', onInitialPointerMove);\n document.addEventListener('mouseup', onInitialPointerMove);\n document.addEventListener('pointermove', onInitialPointerMove);\n document.addEventListener('pointerdown', onInitialPointerMove);\n document.addEventListener('pointerup', onInitialPointerMove);\n document.addEventListener('touchmove', onInitialPointerMove);\n document.addEventListener('touchstart', onInitialPointerMove);\n document.addEventListener('touchend', onInitialPointerMove);\n }\n\n function removeInitialPointerMoveListeners() {\n document.removeEventListener('mousemove', onInitialPointerMove);\n document.removeEventListener('mousedown', onInitialPointerMove);\n document.removeEventListener('mouseup', onInitialPointerMove);\n document.removeEventListener('pointermove', onInitialPointerMove);\n document.removeEventListener('pointerdown', onInitialPointerMove);\n document.removeEventListener('pointerup', onInitialPointerMove);\n document.removeEventListener('touchmove', onInitialPointerMove);\n document.removeEventListener('touchstart', onInitialPointerMove);\n document.removeEventListener('touchend', onInitialPointerMove);\n }\n\n /**\n * When the polfyill first loads, assume the user is in keyboard modality.\n * If any event is received from a pointing device (e.g. mouse, pointer,\n * touch), turn off keyboard modality.\n * This accounts for situations where focus enters the page from the URL bar.\n * @param {Event} e\n */\n function onInitialPointerMove(e) {\n // Work around a Safari quirk that fires a mousemove on whenever the\n // window blurs, even if you're tabbing out of the page. \u00AF\\_(\u30C4)_/\u00AF\n if (e.target.nodeName && e.target.nodeName.toLowerCase() === 'html') {\n return;\n }\n\n hadKeyboardEvent = false;\n removeInitialPointerMoveListeners();\n }\n\n // For some kinds of state, we are interested in changes at the global scope\n // only. For example, global pointer input, global key presses and global\n // visibility change should affect the state at every scope:\n document.addEventListener('keydown', onKeyDown, true);\n document.addEventListener('mousedown', onPointerDown, true);\n document.addEventListener('pointerdown', onPointerDown, true);\n document.addEventListener('touchstart', onPointerDown, true);\n document.addEventListener('visibilitychange', onVisibilityChange, true);\n\n addInitialPointerMoveListeners();\n\n // For focus and blur, we specifically care about state changes in the local\n // scope. This is because focus / blur events that originate from within a\n // shadow root are not re-dispatched from the host element if it was already\n // the active element in its own scope:\n scope.addEventListener('focus', onFocus, true);\n scope.addEventListener('blur', onBlur, true);\n\n // We detect that a node is a ShadowRoot by ensuring that it is a\n // DocumentFragment and also has a host property. This check covers native\n // implementation and polyfill implementation transparently. If we only cared\n // about the native implementation, we could just check if the scope was\n // an instance of a ShadowRoot.\n if (scope.nodeType === Node.DOCUMENT_FRAGMENT_NODE && scope.host) {\n // Since a ShadowRoot is a special kind of DocumentFragment, it does not\n // have a root element to add a class to. So, we add this attribute to the\n // host element instead:\n scope.host.setAttribute('data-js-focus-visible', '');\n } else if (scope.nodeType === Node.DOCUMENT_NODE) {\n document.documentElement.classList.add('js-focus-visible');\n document.documentElement.setAttribute('data-js-focus-visible', '');\n }\n }\n\n // It is important to wrap all references to global window and document in\n // these checks to support server-side rendering use cases\n // @see https://github.com/WICG/focus-visible/issues/199\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n // Make the polyfill helper globally available. This can be used as a signal\n // to interested libraries that wish to coordinate with the polyfill for e.g.,\n // applying the polyfill to a shadow root:\n window.applyFocusVisiblePolyfill = applyFocusVisiblePolyfill;\n\n // Notify interested libraries of the polyfill's presence, in case the\n // polyfill was loaded lazily:\n var event;\n\n try {\n event = new CustomEvent('focus-visible-polyfill-ready');\n } catch (error) {\n // IE11 does not support using CustomEvent as a constructor directly:\n event = document.createEvent('CustomEvent');\n event.initCustomEvent('focus-visible-polyfill-ready', false, false, {});\n }\n\n window.dispatchEvent(event);\n }\n\n if (typeof document !== 'undefined') {\n // Apply the polyfill to the global document, so that no JavaScript\n // coordination is required to use the polyfill in the top-level document:\n applyFocusVisiblePolyfill(document);\n }\n\n})));\n", "/*!\n * escape-html\n * Copyright(c) 2012-2013 TJ Holowaychuk\n * Copyright(c) 2015 Andreas Lubbe\n * Copyright(c) 2015 Tiancheng \"Timothy\" Gu\n * MIT Licensed\n */\n\n'use strict';\n\n/**\n * Module variables.\n * @private\n */\n\nvar matchHtmlRegExp = /[\"'&<>]/;\n\n/**\n * Module exports.\n * @public\n */\n\nmodule.exports = escapeHtml;\n\n/**\n * Escape special characters in the given string of html.\n *\n * @param {string} string The string to escape for inserting into HTML\n * @return {string}\n * @public\n */\n\nfunction escapeHtml(string) {\n var str = '' + string;\n var match = matchHtmlRegExp.exec(str);\n\n if (!match) {\n return str;\n }\n\n var escape;\n var html = '';\n var index = 0;\n var lastIndex = 0;\n\n for (index = match.index; index < str.length; index++) {\n switch (str.charCodeAt(index)) {\n case 34: // \"\n escape = '"';\n break;\n case 38: // &\n escape = '&';\n break;\n case 39: // '\n escape = ''';\n break;\n case 60: // <\n escape = '<';\n break;\n case 62: // >\n escape = '>';\n break;\n default:\n continue;\n }\n\n if (lastIndex !== index) {\n html += str.substring(lastIndex, index);\n }\n\n lastIndex = index + 1;\n html += escape;\n }\n\n return lastIndex !== index\n ? html + str.substring(lastIndex, index)\n : html;\n}\n", "/*!\n * clipboard.js v2.0.11\n * https://clipboardjs.com/\n *\n * Licensed MIT \u00A9 Zeno Rocha\n */\n(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"ClipboardJS\"] = factory();\n\telse\n\t\troot[\"ClipboardJS\"] = factory();\n})(this, function() {\nreturn /******/ (function() { // webpackBootstrap\n/******/ \tvar __webpack_modules__ = ({\n\n/***/ 686:\n/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n \"default\": function() { return /* binding */ clipboard; }\n});\n\n// EXTERNAL MODULE: ./node_modules/tiny-emitter/index.js\nvar tiny_emitter = __webpack_require__(279);\nvar tiny_emitter_default = /*#__PURE__*/__webpack_require__.n(tiny_emitter);\n// EXTERNAL MODULE: ./node_modules/good-listener/src/listen.js\nvar listen = __webpack_require__(370);\nvar listen_default = /*#__PURE__*/__webpack_require__.n(listen);\n// EXTERNAL MODULE: ./node_modules/select/src/select.js\nvar src_select = __webpack_require__(817);\nvar select_default = /*#__PURE__*/__webpack_require__.n(src_select);\n;// CONCATENATED MODULE: ./src/common/command.js\n/**\n * Executes a given operation type.\n * @param {String} type\n * @return {Boolean}\n */\nfunction command(type) {\n try {\n return document.execCommand(type);\n } catch (err) {\n return false;\n }\n}\n;// CONCATENATED MODULE: ./src/actions/cut.js\n\n\n/**\n * Cut action wrapper.\n * @param {String|HTMLElement} target\n * @return {String}\n */\n\nvar ClipboardActionCut = function ClipboardActionCut(target) {\n var selectedText = select_default()(target);\n command('cut');\n return selectedText;\n};\n\n/* harmony default export */ var actions_cut = (ClipboardActionCut);\n;// CONCATENATED MODULE: ./src/common/create-fake-element.js\n/**\n * Creates a fake textarea element with a value.\n * @param {String} value\n * @return {HTMLElement}\n */\nfunction createFakeElement(value) {\n var isRTL = document.documentElement.getAttribute('dir') === 'rtl';\n var fakeElement = document.createElement('textarea'); // Prevent zooming on iOS\n\n fakeElement.style.fontSize = '12pt'; // Reset box model\n\n fakeElement.style.border = '0';\n fakeElement.style.padding = '0';\n fakeElement.style.margin = '0'; // Move element out of screen horizontally\n\n fakeElement.style.position = 'absolute';\n fakeElement.style[isRTL ? 'right' : 'left'] = '-9999px'; // Move element to the same position vertically\n\n var yPosition = window.pageYOffset || document.documentElement.scrollTop;\n fakeElement.style.top = \"\".concat(yPosition, \"px\");\n fakeElement.setAttribute('readonly', '');\n fakeElement.value = value;\n return fakeElement;\n}\n;// CONCATENATED MODULE: ./src/actions/copy.js\n\n\n\n/**\n * Create fake copy action wrapper using a fake element.\n * @param {String} target\n * @param {Object} options\n * @return {String}\n */\n\nvar fakeCopyAction = function fakeCopyAction(value, options) {\n var fakeElement = createFakeElement(value);\n options.container.appendChild(fakeElement);\n var selectedText = select_default()(fakeElement);\n command('copy');\n fakeElement.remove();\n return selectedText;\n};\n/**\n * Copy action wrapper.\n * @param {String|HTMLElement} target\n * @param {Object} options\n * @return {String}\n */\n\n\nvar ClipboardActionCopy = function ClipboardActionCopy(target) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n container: document.body\n };\n var selectedText = '';\n\n if (typeof target === 'string') {\n selectedText = fakeCopyAction(target, options);\n } else if (target instanceof HTMLInputElement && !['text', 'search', 'url', 'tel', 'password'].includes(target === null || target === void 0 ? void 0 : target.type)) {\n // If input type doesn't support `setSelectionRange`. Simulate it. https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setSelectionRange\n selectedText = fakeCopyAction(target.value, options);\n } else {\n selectedText = select_default()(target);\n command('copy');\n }\n\n return selectedText;\n};\n\n/* harmony default export */ var actions_copy = (ClipboardActionCopy);\n;// CONCATENATED MODULE: ./src/actions/default.js\nfunction _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\n\n\n/**\n * Inner function which performs selection from either `text` or `target`\n * properties and then executes copy or cut operations.\n * @param {Object} options\n */\n\nvar ClipboardActionDefault = function ClipboardActionDefault() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n // Defines base properties passed from constructor.\n var _options$action = options.action,\n action = _options$action === void 0 ? 'copy' : _options$action,\n container = options.container,\n target = options.target,\n text = options.text; // Sets the `action` to be performed which can be either 'copy' or 'cut'.\n\n if (action !== 'copy' && action !== 'cut') {\n throw new Error('Invalid \"action\" value, use either \"copy\" or \"cut\"');\n } // Sets the `target` property using an element that will be have its content copied.\n\n\n if (target !== undefined) {\n if (target && _typeof(target) === 'object' && target.nodeType === 1) {\n if (action === 'copy' && target.hasAttribute('disabled')) {\n throw new Error('Invalid \"target\" attribute. Please use \"readonly\" instead of \"disabled\" attribute');\n }\n\n if (action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) {\n throw new Error('Invalid \"target\" attribute. You can\\'t cut text from elements with \"readonly\" or \"disabled\" attributes');\n }\n } else {\n throw new Error('Invalid \"target\" value, use a valid Element');\n }\n } // Define selection strategy based on `text` property.\n\n\n if (text) {\n return actions_copy(text, {\n container: container\n });\n } // Defines which selection strategy based on `target` property.\n\n\n if (target) {\n return action === 'cut' ? actions_cut(target) : actions_copy(target, {\n container: container\n });\n }\n};\n\n/* harmony default export */ var actions_default = (ClipboardActionDefault);\n;// CONCATENATED MODULE: ./src/clipboard.js\nfunction clipboard_typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { clipboard_typeof = function _typeof(obj) { return typeof obj; }; } else { clipboard_typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return clipboard_typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (clipboard_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _isNativeReflectConstruct() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n\n\n\n\n\n/**\n * Helper function to retrieve attribute value.\n * @param {String} suffix\n * @param {Element} element\n */\n\nfunction getAttributeValue(suffix, element) {\n var attribute = \"data-clipboard-\".concat(suffix);\n\n if (!element.hasAttribute(attribute)) {\n return;\n }\n\n return element.getAttribute(attribute);\n}\n/**\n * Base class which takes one or more elements, adds event listeners to them,\n * and instantiates a new `ClipboardAction` on each click.\n */\n\n\nvar Clipboard = /*#__PURE__*/function (_Emitter) {\n _inherits(Clipboard, _Emitter);\n\n var _super = _createSuper(Clipboard);\n\n /**\n * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n * @param {Object} options\n */\n function Clipboard(trigger, options) {\n var _this;\n\n _classCallCheck(this, Clipboard);\n\n _this = _super.call(this);\n\n _this.resolveOptions(options);\n\n _this.listenClick(trigger);\n\n return _this;\n }\n /**\n * Defines if attributes would be resolved using internal setter functions\n * or custom functions that were passed in the constructor.\n * @param {Object} options\n */\n\n\n _createClass(Clipboard, [{\n key: \"resolveOptions\",\n value: function resolveOptions() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n this.action = typeof options.action === 'function' ? options.action : this.defaultAction;\n this.target = typeof options.target === 'function' ? options.target : this.defaultTarget;\n this.text = typeof options.text === 'function' ? options.text : this.defaultText;\n this.container = clipboard_typeof(options.container) === 'object' ? options.container : document.body;\n }\n /**\n * Adds a click event listener to the passed trigger.\n * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n */\n\n }, {\n key: \"listenClick\",\n value: function listenClick(trigger) {\n var _this2 = this;\n\n this.listener = listen_default()(trigger, 'click', function (e) {\n return _this2.onClick(e);\n });\n }\n /**\n * Defines a new `ClipboardAction` on each click event.\n * @param {Event} e\n */\n\n }, {\n key: \"onClick\",\n value: function onClick(e) {\n var trigger = e.delegateTarget || e.currentTarget;\n var action = this.action(trigger) || 'copy';\n var text = actions_default({\n action: action,\n container: this.container,\n target: this.target(trigger),\n text: this.text(trigger)\n }); // Fires an event based on the copy operation result.\n\n this.emit(text ? 'success' : 'error', {\n action: action,\n text: text,\n trigger: trigger,\n clearSelection: function clearSelection() {\n if (trigger) {\n trigger.focus();\n }\n\n window.getSelection().removeAllRanges();\n }\n });\n }\n /**\n * Default `action` lookup function.\n * @param {Element} trigger\n */\n\n }, {\n key: \"defaultAction\",\n value: function defaultAction(trigger) {\n return getAttributeValue('action', trigger);\n }\n /**\n * Default `target` lookup function.\n * @param {Element} trigger\n */\n\n }, {\n key: \"defaultTarget\",\n value: function defaultTarget(trigger) {\n var selector = getAttributeValue('target', trigger);\n\n if (selector) {\n return document.querySelector(selector);\n }\n }\n /**\n * Allow fire programmatically a copy action\n * @param {String|HTMLElement} target\n * @param {Object} options\n * @returns Text copied.\n */\n\n }, {\n key: \"defaultText\",\n\n /**\n * Default `text` lookup function.\n * @param {Element} trigger\n */\n value: function defaultText(trigger) {\n return getAttributeValue('text', trigger);\n }\n /**\n * Destroy lifecycle.\n */\n\n }, {\n key: \"destroy\",\n value: function destroy() {\n this.listener.destroy();\n }\n }], [{\n key: \"copy\",\n value: function copy(target) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n container: document.body\n };\n return actions_copy(target, options);\n }\n /**\n * Allow fire programmatically a cut action\n * @param {String|HTMLElement} target\n * @returns Text cutted.\n */\n\n }, {\n key: \"cut\",\n value: function cut(target) {\n return actions_cut(target);\n }\n /**\n * Returns the support of the given action, or all actions if no action is\n * given.\n * @param {String} [action]\n */\n\n }, {\n key: \"isSupported\",\n value: function isSupported() {\n var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['copy', 'cut'];\n var actions = typeof action === 'string' ? [action] : action;\n var support = !!document.queryCommandSupported;\n actions.forEach(function (action) {\n support = support && !!document.queryCommandSupported(action);\n });\n return support;\n }\n }]);\n\n return Clipboard;\n}((tiny_emitter_default()));\n\n/* harmony default export */ var clipboard = (Clipboard);\n\n/***/ }),\n\n/***/ 828:\n/***/ (function(module) {\n\nvar DOCUMENT_NODE_TYPE = 9;\n\n/**\n * A polyfill for Element.matches()\n */\nif (typeof Element !== 'undefined' && !Element.prototype.matches) {\n var proto = Element.prototype;\n\n proto.matches = proto.matchesSelector ||\n proto.mozMatchesSelector ||\n proto.msMatchesSelector ||\n proto.oMatchesSelector ||\n proto.webkitMatchesSelector;\n}\n\n/**\n * Finds the closest parent that matches a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @return {Function}\n */\nfunction closest (element, selector) {\n while (element && element.nodeType !== DOCUMENT_NODE_TYPE) {\n if (typeof element.matches === 'function' &&\n element.matches(selector)) {\n return element;\n }\n element = element.parentNode;\n }\n}\n\nmodule.exports = closest;\n\n\n/***/ }),\n\n/***/ 438:\n/***/ (function(module, __unused_webpack_exports, __webpack_require__) {\n\nvar closest = __webpack_require__(828);\n\n/**\n * Delegates event to a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\nfunction _delegate(element, selector, type, callback, useCapture) {\n var listenerFn = listener.apply(this, arguments);\n\n element.addEventListener(type, listenerFn, useCapture);\n\n return {\n destroy: function() {\n element.removeEventListener(type, listenerFn, useCapture);\n }\n }\n}\n\n/**\n * Delegates event to a selector.\n *\n * @param {Element|String|Array} [elements]\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\nfunction delegate(elements, selector, type, callback, useCapture) {\n // Handle the regular Element usage\n if (typeof elements.addEventListener === 'function') {\n return _delegate.apply(null, arguments);\n }\n\n // Handle Element-less usage, it defaults to global delegation\n if (typeof type === 'function') {\n // Use `document` as the first parameter, then apply arguments\n // This is a short way to .unshift `arguments` without running into deoptimizations\n return _delegate.bind(null, document).apply(null, arguments);\n }\n\n // Handle Selector-based usage\n if (typeof elements === 'string') {\n elements = document.querySelectorAll(elements);\n }\n\n // Handle Array-like based usage\n return Array.prototype.map.call(elements, function (element) {\n return _delegate(element, selector, type, callback, useCapture);\n });\n}\n\n/**\n * Finds closest match and invokes callback.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Function}\n */\nfunction listener(element, selector, type, callback) {\n return function(e) {\n e.delegateTarget = closest(e.target, selector);\n\n if (e.delegateTarget) {\n callback.call(element, e);\n }\n }\n}\n\nmodule.exports = delegate;\n\n\n/***/ }),\n\n/***/ 879:\n/***/ (function(__unused_webpack_module, exports) {\n\n/**\n * Check if argument is a HTML element.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.node = function(value) {\n return value !== undefined\n && value instanceof HTMLElement\n && value.nodeType === 1;\n};\n\n/**\n * Check if argument is a list of HTML elements.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.nodeList = function(value) {\n var type = Object.prototype.toString.call(value);\n\n return value !== undefined\n && (type === '[object NodeList]' || type === '[object HTMLCollection]')\n && ('length' in value)\n && (value.length === 0 || exports.node(value[0]));\n};\n\n/**\n * Check if argument is a string.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.string = function(value) {\n return typeof value === 'string'\n || value instanceof String;\n};\n\n/**\n * Check if argument is a function.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.fn = function(value) {\n var type = Object.prototype.toString.call(value);\n\n return type === '[object Function]';\n};\n\n\n/***/ }),\n\n/***/ 370:\n/***/ (function(module, __unused_webpack_exports, __webpack_require__) {\n\nvar is = __webpack_require__(879);\nvar delegate = __webpack_require__(438);\n\n/**\n * Validates all params and calls the right\n * listener function based on its target type.\n *\n * @param {String|HTMLElement|HTMLCollection|NodeList} target\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listen(target, type, callback) {\n if (!target && !type && !callback) {\n throw new Error('Missing required arguments');\n }\n\n if (!is.string(type)) {\n throw new TypeError('Second argument must be a String');\n }\n\n if (!is.fn(callback)) {\n throw new TypeError('Third argument must be a Function');\n }\n\n if (is.node(target)) {\n return listenNode(target, type, callback);\n }\n else if (is.nodeList(target)) {\n return listenNodeList(target, type, callback);\n }\n else if (is.string(target)) {\n return listenSelector(target, type, callback);\n }\n else {\n throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList');\n }\n}\n\n/**\n * Adds an event listener to a HTML element\n * and returns a remove listener function.\n *\n * @param {HTMLElement} node\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenNode(node, type, callback) {\n node.addEventListener(type, callback);\n\n return {\n destroy: function() {\n node.removeEventListener(type, callback);\n }\n }\n}\n\n/**\n * Add an event listener to a list of HTML elements\n * and returns a remove listener function.\n *\n * @param {NodeList|HTMLCollection} nodeList\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenNodeList(nodeList, type, callback) {\n Array.prototype.forEach.call(nodeList, function(node) {\n node.addEventListener(type, callback);\n });\n\n return {\n destroy: function() {\n Array.prototype.forEach.call(nodeList, function(node) {\n node.removeEventListener(type, callback);\n });\n }\n }\n}\n\n/**\n * Add an event listener to a selector\n * and returns a remove listener function.\n *\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenSelector(selector, type, callback) {\n return delegate(document.body, selector, type, callback);\n}\n\nmodule.exports = listen;\n\n\n/***/ }),\n\n/***/ 817:\n/***/ (function(module) {\n\nfunction select(element) {\n var selectedText;\n\n if (element.nodeName === 'SELECT') {\n element.focus();\n\n selectedText = element.value;\n }\n else if (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') {\n var isReadOnly = element.hasAttribute('readonly');\n\n if (!isReadOnly) {\n element.setAttribute('readonly', '');\n }\n\n element.select();\n element.setSelectionRange(0, element.value.length);\n\n if (!isReadOnly) {\n element.removeAttribute('readonly');\n }\n\n selectedText = element.value;\n }\n else {\n if (element.hasAttribute('contenteditable')) {\n element.focus();\n }\n\n var selection = window.getSelection();\n var range = document.createRange();\n\n range.selectNodeContents(element);\n selection.removeAllRanges();\n selection.addRange(range);\n\n selectedText = selection.toString();\n }\n\n return selectedText;\n}\n\nmodule.exports = select;\n\n\n/***/ }),\n\n/***/ 279:\n/***/ (function(module) {\n\nfunction E () {\n // Keep this empty so it's easier to inherit from\n // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)\n}\n\nE.prototype = {\n on: function (name, callback, ctx) {\n var e = this.e || (this.e = {});\n\n (e[name] || (e[name] = [])).push({\n fn: callback,\n ctx: ctx\n });\n\n return this;\n },\n\n once: function (name, callback, ctx) {\n var self = this;\n function listener () {\n self.off(name, listener);\n callback.apply(ctx, arguments);\n };\n\n listener._ = callback\n return this.on(name, listener, ctx);\n },\n\n emit: function (name) {\n var data = [].slice.call(arguments, 1);\n var evtArr = ((this.e || (this.e = {}))[name] || []).slice();\n var i = 0;\n var len = evtArr.length;\n\n for (i; i < len; i++) {\n evtArr[i].fn.apply(evtArr[i].ctx, data);\n }\n\n return this;\n },\n\n off: function (name, callback) {\n var e = this.e || (this.e = {});\n var evts = e[name];\n var liveEvents = [];\n\n if (evts && callback) {\n for (var i = 0, len = evts.length; i < len; i++) {\n if (evts[i].fn !== callback && evts[i].fn._ !== callback)\n liveEvents.push(evts[i]);\n }\n }\n\n // Remove event from queue to prevent memory leak\n // Suggested by https://github.com/lazd\n // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910\n\n (liveEvents.length)\n ? e[name] = liveEvents\n : delete e[name];\n\n return this;\n }\n};\n\nmodule.exports = E;\nmodule.exports.TinyEmitter = E;\n\n\n/***/ })\n\n/******/ \t});\n/************************************************************************/\n/******/ \t// The module cache\n/******/ \tvar __webpack_module_cache__ = {};\n/******/ \t\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(__webpack_module_cache__[moduleId]) {\n/******/ \t\t\treturn __webpack_module_cache__[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = __webpack_module_cache__[moduleId] = {\n/******/ \t\t\t// no module.id needed\n/******/ \t\t\t// no module.loaded needed\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/ \t\n/******/ \t\t// Execute the module function\n/******/ \t\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n/******/ \t\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/ \t\n/************************************************************************/\n/******/ \t/* webpack/runtime/compat get default export */\n/******/ \t!function() {\n/******/ \t\t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t\t__webpack_require__.n = function(module) {\n/******/ \t\t\tvar getter = module && module.__esModule ?\n/******/ \t\t\t\tfunction() { return module['default']; } :\n/******/ \t\t\t\tfunction() { return module; };\n/******/ \t\t\t__webpack_require__.d(getter, { a: getter });\n/******/ \t\t\treturn getter;\n/******/ \t\t};\n/******/ \t}();\n/******/ \t\n/******/ \t/* webpack/runtime/define property getters */\n/******/ \t!function() {\n/******/ \t\t// define getter functions for harmony exports\n/******/ \t\t__webpack_require__.d = function(exports, definition) {\n/******/ \t\t\tfor(var key in definition) {\n/******/ \t\t\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n/******/ \t\t\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n/******/ \t\t\t\t}\n/******/ \t\t\t}\n/******/ \t\t};\n/******/ \t}();\n/******/ \t\n/******/ \t/* webpack/runtime/hasOwnProperty shorthand */\n/******/ \t!function() {\n/******/ \t\t__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }\n/******/ \t}();\n/******/ \t\n/************************************************************************/\n/******/ \t// module exports must be returned from runtime so entry inlining is disabled\n/******/ \t// startup\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(686);\n/******/ })()\n.default;\n});", "/*\n * Copyright (c) 2016-2025 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport \"focus-visible\"\n\nimport {\n EMPTY,\n NEVER,\n Observable,\n Subject,\n defer,\n delay,\n filter,\n map,\n merge,\n mergeWith,\n shareReplay,\n switchMap\n} from \"rxjs\"\n\nimport { configuration, feature } from \"./_\"\nimport {\n at,\n getActiveElement,\n getOptionalElement,\n requestJSON,\n setLocation,\n setToggle,\n watchDocument,\n watchKeyboard,\n watchLocation,\n watchLocationTarget,\n watchMedia,\n watchPrint,\n watchScript,\n watchViewport\n} from \"./browser\"\nimport {\n getComponentElement,\n getComponentElements,\n mountAnnounce,\n mountBackToTop,\n mountConsent,\n mountContent,\n mountDialog,\n mountHeader,\n mountHeaderTitle,\n mountPalette,\n mountProgress,\n mountSearch,\n mountSearchHiglight,\n mountSidebar,\n mountSource,\n mountTableOfContents,\n mountTabs,\n watchHeader,\n watchMain\n} from \"./components\"\nimport {\n SearchIndex,\n fetchSitemap,\n setupAlternate,\n setupClipboardJS,\n setupInstantNavigation,\n setupVersionSelector\n} from \"./integrations\"\nimport {\n patchEllipsis,\n patchIndeterminate,\n patchScrollfix,\n patchScrolllock\n} from \"./patches\"\nimport \"./polyfills\"\n\n/* ----------------------------------------------------------------------------\n * Functions - @todo refactor\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch search index\n *\n * @returns Search index observable\n */\nfunction fetchSearchIndex(): Observable {\n if (location.protocol === \"file:\") {\n return watchScript(\n `${new URL(\"search/search_index.js\", config.base)}`\n )\n .pipe(\n // @ts-ignore - @todo fix typings\n map(() => __index),\n shareReplay(1)\n )\n } else {\n return requestJSON(\n new URL(\"search/search_index.json\", config.base)\n )\n }\n}\n\n/* ----------------------------------------------------------------------------\n * Application\n * ------------------------------------------------------------------------- */\n\n/* Yay, JavaScript is available */\ndocument.documentElement.classList.remove(\"no-js\")\ndocument.documentElement.classList.add(\"js\")\n\n/* Set up navigation observables and subjects */\nconst document$ = watchDocument()\nconst location$ = watchLocation()\nconst target$ = watchLocationTarget(location$)\nconst keyboard$ = watchKeyboard()\n\n/* Set up media observables */\nconst viewport$ = watchViewport()\nconst tablet$ = watchMedia(\"(min-width: 60em)\")\nconst screen$ = watchMedia(\"(min-width: 76.25em)\")\nconst print$ = watchPrint()\n\n/* Retrieve search index, if search is enabled */\nconst config = configuration()\nconst index$ = document.forms.namedItem(\"search\")\n ? fetchSearchIndex()\n : NEVER\n\n/* Set up Clipboard.js integration */\nconst alert$ = new Subject()\nsetupClipboardJS({ alert$ })\n\n/* Set up language selector */\nsetupAlternate({ document$ })\n\n/* Set up progress indicator */\nconst progress$ = new Subject()\n\n/* Set up sitemap for instant navigation and previews */\nconst sitemap$ = fetchSitemap(config.base)\n\n/* Set up instant navigation, if enabled */\nif (feature(\"navigation.instant\"))\n setupInstantNavigation({ sitemap$, location$, viewport$, progress$ })\n .subscribe(document$)\n\n/* Set up version selector */\nif (config.version?.provider === \"mike\")\n setupVersionSelector({ document$ })\n\n/* Always close drawer and search on navigation */\nmerge(location$, target$)\n .pipe(\n delay(125)\n )\n .subscribe(() => {\n setToggle(\"drawer\", false)\n setToggle(\"search\", false)\n })\n\n/* Set up global keyboard handlers */\nkeyboard$\n .pipe(\n filter(({ mode }) => mode === \"global\")\n )\n .subscribe(key => {\n switch (key.type) {\n\n /* Go to previous page */\n case \"p\":\n case \",\":\n const prev = getOptionalElement(\"link[rel=prev]\")\n if (typeof prev !== \"undefined\")\n setLocation(prev)\n break\n\n /* Go to next page */\n case \"n\":\n case \".\":\n const next = getOptionalElement(\"link[rel=next]\")\n if (typeof next !== \"undefined\")\n setLocation(next)\n break\n\n /* Expand navigation, see https://bit.ly/3ZjG5io */\n case \"Enter\":\n const active = getActiveElement()\n if (active instanceof HTMLLabelElement)\n active.click()\n }\n })\n\n/* Set up patches */\npatchEllipsis({ viewport$, document$ })\npatchIndeterminate({ document$, tablet$ })\npatchScrollfix({ document$ })\npatchScrolllock({ viewport$, tablet$ })\n\n/* Set up header and main area observable */\nconst header$ = watchHeader(getComponentElement(\"header\"), { viewport$ })\nconst main$ = document$\n .pipe(\n map(() => getComponentElement(\"main\")),\n switchMap(el => watchMain(el, { viewport$, header$ })),\n shareReplay(1)\n )\n\n/* Set up control component observables */\nconst control$ = merge(\n\n /* Consent */\n ...getComponentElements(\"consent\")\n .map(el => mountConsent(el, { target$ })),\n\n /* Dialog */\n ...getComponentElements(\"dialog\")\n .map(el => mountDialog(el, { alert$ })),\n\n /* Color palette */\n ...getComponentElements(\"palette\")\n .map(el => mountPalette(el)),\n\n /* Progress bar */\n ...getComponentElements(\"progress\")\n .map(el => mountProgress(el, { progress$ })),\n\n /* Search */\n ...getComponentElements(\"search\")\n .map(el => mountSearch(el, { index$, keyboard$ })),\n\n /* Repository information */\n ...getComponentElements(\"source\")\n .map(el => mountSource(el))\n)\n\n/* Set up content component observables */\nconst content$ = defer(() => merge(\n\n /* Announcement bar */\n ...getComponentElements(\"announce\")\n .map(el => mountAnnounce(el)),\n\n /* Content */\n ...getComponentElements(\"content\")\n .map(el => mountContent(el, { sitemap$, viewport$, target$, print$ })),\n\n /* Search highlighting */\n ...getComponentElements(\"content\")\n .map(el => feature(\"search.highlight\")\n ? mountSearchHiglight(el, { index$, location$ })\n : EMPTY\n ),\n\n /* Header */\n ...getComponentElements(\"header\")\n .map(el => mountHeader(el, { viewport$, header$, main$ })),\n\n /* Header title */\n ...getComponentElements(\"header-title\")\n .map(el => mountHeaderTitle(el, { viewport$, header$ })),\n\n /* Sidebar */\n ...getComponentElements(\"sidebar\")\n .map(el => el.getAttribute(\"data-md-type\") === \"navigation\"\n ? at(screen$, () => mountSidebar(el, { viewport$, header$, main$ }))\n : at(tablet$, () => mountSidebar(el, { viewport$, header$, main$ }))\n ),\n\n /* Navigation tabs */\n ...getComponentElements(\"tabs\")\n .map(el => mountTabs(el, { viewport$, header$ })),\n\n /* Table of contents */\n ...getComponentElements(\"toc\")\n .map(el => mountTableOfContents(el, {\n viewport$, header$, main$, target$\n })),\n\n /* Back-to-top button */\n ...getComponentElements(\"top\")\n .map(el => mountBackToTop(el, { viewport$, header$, main$, target$ }))\n))\n\n/* Set up component observables */\nconst component$ = document$\n .pipe(\n switchMap(() => content$),\n mergeWith(control$),\n shareReplay(1)\n )\n\n/* Subscribe to all components */\ncomponent$.subscribe()\n\n/* ----------------------------------------------------------------------------\n * Exports\n * ------------------------------------------------------------------------- */\n\nwindow.document$ = document$ /* Document observable */\nwindow.location$ = location$ /* Location subject */\nwindow.target$ = target$ /* Location target observable */\nwindow.keyboard$ = keyboard$ /* Keyboard observable */\nwindow.viewport$ = viewport$ /* Viewport observable */\nwindow.tablet$ = tablet$ /* Media tablet observable */\nwindow.screen$ = screen$ /* Media screen observable */\nwindow.print$ = print$ /* Media print observable */\nwindow.alert$ = alert$ /* Alert subject */\nwindow.progress$ = progress$ /* Progress indicator subject */\nwindow.component$ = component$ /* Component observable */\n", "/******************************************************************************\nCopyright (c) Microsoft Corporation.\n\nPermission to use, copy, modify, and/or distribute this software for any\npurpose with or without fee is hereby granted.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\nPERFORMANCE OF THIS SOFTWARE.\n***************************************************************************** */\n/* global Reflect, Promise, SuppressedError, Symbol, Iterator */\n\nvar extendStatics = function(d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n};\n\nexport function __extends(d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n}\n\nexport var __assign = function() {\n __assign = Object.assign || function __assign(t) {\n for (var s, i = 1, n = arguments.length; i < n; i++) {\n s = arguments[i];\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\n }\n return t;\n }\n return __assign.apply(this, arguments);\n}\n\nexport function __rest(s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n}\n\nexport function __decorate(decorators, target, key, desc) {\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\n return c > 3 && r && Object.defineProperty(target, key, r), r;\n}\n\nexport function __param(paramIndex, decorator) {\n return function (target, key) { decorator(target, key, paramIndex); }\n}\n\nexport function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\n function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\n var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\n var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\n var _, done = false;\n for (var i = decorators.length - 1; i >= 0; i--) {\n var context = {};\n for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\n context.addInitializer = function (f) { if (done) throw new TypeError(\"Cannot add initializers after decoration has completed\"); extraInitializers.push(accept(f || null)); };\n var result = (0, decorators[i])(kind === \"accessor\" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);\n if (kind === \"accessor\") {\n if (result === void 0) continue;\n if (result === null || typeof result !== \"object\") throw new TypeError(\"Object expected\");\n if (_ = accept(result.get)) descriptor.get = _;\n if (_ = accept(result.set)) descriptor.set = _;\n if (_ = accept(result.init)) initializers.unshift(_);\n }\n else if (_ = accept(result)) {\n if (kind === \"field\") initializers.unshift(_);\n else descriptor[key] = _;\n }\n }\n if (target) Object.defineProperty(target, contextIn.name, descriptor);\n done = true;\n};\n\nexport function __runInitializers(thisArg, initializers, value) {\n var useValue = arguments.length > 2;\n for (var i = 0; i < initializers.length; i++) {\n value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\n }\n return useValue ? value : void 0;\n};\n\nexport function __propKey(x) {\n return typeof x === \"symbol\" ? x : \"\".concat(x);\n};\n\nexport function __setFunctionName(f, name, prefix) {\n if (typeof name === \"symbol\") name = name.description ? \"[\".concat(name.description, \"]\") : \"\";\n return Object.defineProperty(f, \"name\", { configurable: true, value: prefix ? \"\".concat(prefix, \" \", name) : name });\n};\n\nexport function __metadata(metadataKey, metadataValue) {\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\n}\n\nexport function __awaiter(thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n}\n\nexport function __generator(thisArg, body) {\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === \"function\" ? Iterator : Object).prototype);\n return g.next = verb(0), g[\"throw\"] = verb(1), g[\"return\"] = verb(2), typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\n function verb(n) { return function (v) { return step([n, v]); }; }\n function step(op) {\n if (f) throw new TypeError(\"Generator is already executing.\");\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\n if (y = 0, t) op = [op[0] & 2, t.value];\n switch (op[0]) {\n case 0: case 1: t = op; break;\n case 4: _.label++; return { value: op[1], done: false };\n case 5: _.label++; y = op[1]; op = [0]; continue;\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\n default:\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n if (t[2]) _.ops.pop();\n _.trys.pop(); continue;\n }\n op = body.call(thisArg, _);\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\n }\n}\n\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n});\n\nexport function __exportStar(m, o) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\n}\n\nexport function __values(o) {\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\n if (m) return m.call(o);\n if (o && typeof o.length === \"number\") return {\n next: function () {\n if (o && i >= o.length) o = void 0;\n return { value: o && o[i++], done: !o };\n }\n };\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\n}\n\nexport function __read(o, n) {\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\n if (!m) return o;\n var i = m.call(o), r, ar = [], e;\n try {\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\n }\n catch (error) { e = { error: error }; }\n finally {\n try {\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\n }\n finally { if (e) throw e.error; }\n }\n return ar;\n}\n\n/** @deprecated */\nexport function __spread() {\n for (var ar = [], i = 0; i < arguments.length; i++)\n ar = ar.concat(__read(arguments[i]));\n return ar;\n}\n\n/** @deprecated */\nexport function __spreadArrays() {\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\n r[k] = a[j];\n return r;\n}\n\nexport function __spreadArray(to, from, pack) {\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\n if (ar || !(i in from)) {\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\n ar[i] = from[i];\n }\n }\n return to.concat(ar || Array.prototype.slice.call(from));\n}\n\nexport function __await(v) {\n return this instanceof __await ? (this.v = v, this) : new __await(v);\n}\n\nexport function __asyncGenerator(thisArg, _arguments, generator) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\n return i = Object.create((typeof AsyncIterator === \"function\" ? AsyncIterator : Object).prototype), verb(\"next\"), verb(\"throw\"), verb(\"return\", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;\n function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }\n function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\n function fulfill(value) { resume(\"next\", value); }\n function reject(value) { resume(\"throw\", value); }\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\n}\n\nexport function __asyncDelegator(o) {\n var i, p;\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }\n}\n\nexport function __asyncValues(o) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var m = o[Symbol.asyncIterator], i;\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\n}\n\nexport function __makeTemplateObject(cooked, raw) {\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\n return cooked;\n};\n\nvar __setModuleDefault = Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n};\n\nexport function __importStar(mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n}\n\nexport function __importDefault(mod) {\n return (mod && mod.__esModule) ? mod : { default: mod };\n}\n\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\n}\n\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\n}\n\nexport function __classPrivateFieldIn(state, receiver) {\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\n}\n\nexport function __addDisposableResource(env, value, async) {\n if (value !== null && value !== void 0) {\n if (typeof value !== \"object\" && typeof value !== \"function\") throw new TypeError(\"Object expected.\");\n var dispose, inner;\n if (async) {\n if (!Symbol.asyncDispose) throw new TypeError(\"Symbol.asyncDispose is not defined.\");\n dispose = value[Symbol.asyncDispose];\n }\n if (dispose === void 0) {\n if (!Symbol.dispose) throw new TypeError(\"Symbol.dispose is not defined.\");\n dispose = value[Symbol.dispose];\n if (async) inner = dispose;\n }\n if (typeof dispose !== \"function\") throw new TypeError(\"Object not disposable.\");\n if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };\n env.stack.push({ value: value, dispose: dispose, async: async });\n }\n else if (async) {\n env.stack.push({ async: true });\n }\n return value;\n}\n\nvar _SuppressedError = typeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\n var e = new Error(message);\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\n};\n\nexport function __disposeResources(env) {\n function fail(e) {\n env.error = env.hasError ? new _SuppressedError(e, env.error, \"An error was suppressed during disposal.\") : e;\n env.hasError = true;\n }\n var r, s = 0;\n function next() {\n while (r = env.stack.pop()) {\n try {\n if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);\n if (r.dispose) {\n var result = r.dispose.call(r.value);\n if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });\n }\n else s |= 1;\n }\n catch (e) {\n fail(e);\n }\n }\n if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();\n if (env.hasError) throw env.error;\n }\n return next();\n}\n\nexport default {\n __extends,\n __assign,\n __rest,\n __decorate,\n __param,\n __metadata,\n __awaiter,\n __generator,\n __createBinding,\n __exportStar,\n __values,\n __read,\n __spread,\n __spreadArrays,\n __spreadArray,\n __await,\n __asyncGenerator,\n __asyncDelegator,\n __asyncValues,\n __makeTemplateObject,\n __importStar,\n __importDefault,\n __classPrivateFieldGet,\n __classPrivateFieldSet,\n __classPrivateFieldIn,\n __addDisposableResource,\n __disposeResources,\n};\n", "/**\n * Returns true if the object is a function.\n * @param value The value to check\n */\nexport function isFunction(value: any): value is (...args: any[]) => any {\n return typeof value === 'function';\n}\n", "/**\n * Used to create Error subclasses until the community moves away from ES5.\n *\n * This is because compiling from TypeScript down to ES5 has issues with subclassing Errors\n * as well as other built-in types: https://github.com/Microsoft/TypeScript/issues/12123\n *\n * @param createImpl A factory function to create the actual constructor implementation. The returned\n * function should be a named function that calls `_super` internally.\n */\nexport function createErrorClass(createImpl: (_super: any) => any): T {\n const _super = (instance: any) => {\n Error.call(instance);\n instance.stack = new Error().stack;\n };\n\n const ctorFunc = createImpl(_super);\n ctorFunc.prototype = Object.create(Error.prototype);\n ctorFunc.prototype.constructor = ctorFunc;\n return ctorFunc;\n}\n", "import { createErrorClass } from './createErrorClass';\n\nexport interface UnsubscriptionError extends Error {\n readonly errors: any[];\n}\n\nexport interface UnsubscriptionErrorCtor {\n /**\n * @deprecated Internal implementation detail. Do not construct error instances.\n * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269\n */\n new (errors: any[]): UnsubscriptionError;\n}\n\n/**\n * An error thrown when one or more errors have occurred during the\n * `unsubscribe` of a {@link Subscription}.\n */\nexport const UnsubscriptionError: UnsubscriptionErrorCtor = createErrorClass(\n (_super) =>\n function UnsubscriptionErrorImpl(this: any, errors: (Error | string)[]) {\n _super(this);\n this.message = errors\n ? `${errors.length} errors occurred during unsubscription:\n${errors.map((err, i) => `${i + 1}) ${err.toString()}`).join('\\n ')}`\n : '';\n this.name = 'UnsubscriptionError';\n this.errors = errors;\n }\n);\n", "/**\n * Removes an item from an array, mutating it.\n * @param arr The array to remove the item from\n * @param item The item to remove\n */\nexport function arrRemove(arr: T[] | undefined | null, item: T) {\n if (arr) {\n const index = arr.indexOf(item);\n 0 <= index && arr.splice(index, 1);\n }\n}\n", "import { isFunction } from './util/isFunction';\nimport { UnsubscriptionError } from './util/UnsubscriptionError';\nimport { SubscriptionLike, TeardownLogic, Unsubscribable } from './types';\nimport { arrRemove } from './util/arrRemove';\n\n/**\n * Represents a disposable resource, such as the execution of an Observable. A\n * Subscription has one important method, `unsubscribe`, that takes no argument\n * and just disposes the resource held by the subscription.\n *\n * Additionally, subscriptions may be grouped together through the `add()`\n * method, which will attach a child Subscription to the current Subscription.\n * When a Subscription is unsubscribed, all its children (and its grandchildren)\n * will be unsubscribed as well.\n */\nexport class Subscription implements SubscriptionLike {\n public static EMPTY = (() => {\n const empty = new Subscription();\n empty.closed = true;\n return empty;\n })();\n\n /**\n * A flag to indicate whether this Subscription has already been unsubscribed.\n */\n public closed = false;\n\n private _parentage: Subscription[] | Subscription | null = null;\n\n /**\n * The list of registered finalizers to execute upon unsubscription. Adding and removing from this\n * list occurs in the {@link #add} and {@link #remove} methods.\n */\n private _finalizers: Exclude[] | null = null;\n\n /**\n * @param initialTeardown A function executed first as part of the finalization\n * process that is kicked off when {@link #unsubscribe} is called.\n */\n constructor(private initialTeardown?: () => void) {}\n\n /**\n * Disposes the resources held by the subscription. May, for instance, cancel\n * an ongoing Observable execution or cancel any other type of work that\n * started when the Subscription was created.\n */\n unsubscribe(): void {\n let errors: any[] | undefined;\n\n if (!this.closed) {\n this.closed = true;\n\n // Remove this from it's parents.\n const { _parentage } = this;\n if (_parentage) {\n this._parentage = null;\n if (Array.isArray(_parentage)) {\n for (const parent of _parentage) {\n parent.remove(this);\n }\n } else {\n _parentage.remove(this);\n }\n }\n\n const { initialTeardown: initialFinalizer } = this;\n if (isFunction(initialFinalizer)) {\n try {\n initialFinalizer();\n } catch (e) {\n errors = e instanceof UnsubscriptionError ? e.errors : [e];\n }\n }\n\n const { _finalizers } = this;\n if (_finalizers) {\n this._finalizers = null;\n for (const finalizer of _finalizers) {\n try {\n execFinalizer(finalizer);\n } catch (err) {\n errors = errors ?? [];\n if (err instanceof UnsubscriptionError) {\n errors = [...errors, ...err.errors];\n } else {\n errors.push(err);\n }\n }\n }\n }\n\n if (errors) {\n throw new UnsubscriptionError(errors);\n }\n }\n }\n\n /**\n * Adds a finalizer to this subscription, so that finalization will be unsubscribed/called\n * when this subscription is unsubscribed. If this subscription is already {@link #closed},\n * because it has already been unsubscribed, then whatever finalizer is passed to it\n * will automatically be executed (unless the finalizer itself is also a closed subscription).\n *\n * Closed Subscriptions cannot be added as finalizers to any subscription. Adding a closed\n * subscription to a any subscription will result in no operation. (A noop).\n *\n * Adding a subscription to itself, or adding `null` or `undefined` will not perform any\n * operation at all. (A noop).\n *\n * `Subscription` instances that are added to this instance will automatically remove themselves\n * if they are unsubscribed. Functions and {@link Unsubscribable} objects that you wish to remove\n * will need to be removed manually with {@link #remove}\n *\n * @param teardown The finalization logic to add to this subscription.\n */\n add(teardown: TeardownLogic): void {\n // Only add the finalizer if it's not undefined\n // and don't add a subscription to itself.\n if (teardown && teardown !== this) {\n if (this.closed) {\n // If this subscription is already closed,\n // execute whatever finalizer is handed to it automatically.\n execFinalizer(teardown);\n } else {\n if (teardown instanceof Subscription) {\n // We don't add closed subscriptions, and we don't add the same subscription\n // twice. Subscription unsubscribe is idempotent.\n if (teardown.closed || teardown._hasParent(this)) {\n return;\n }\n teardown._addParent(this);\n }\n (this._finalizers = this._finalizers ?? []).push(teardown);\n }\n }\n }\n\n /**\n * Checks to see if a this subscription already has a particular parent.\n * This will signal that this subscription has already been added to the parent in question.\n * @param parent the parent to check for\n */\n private _hasParent(parent: Subscription) {\n const { _parentage } = this;\n return _parentage === parent || (Array.isArray(_parentage) && _parentage.includes(parent));\n }\n\n /**\n * Adds a parent to this subscription so it can be removed from the parent if it\n * unsubscribes on it's own.\n *\n * NOTE: THIS ASSUMES THAT {@link _hasParent} HAS ALREADY BEEN CHECKED.\n * @param parent The parent subscription to add\n */\n private _addParent(parent: Subscription) {\n const { _parentage } = this;\n this._parentage = Array.isArray(_parentage) ? (_parentage.push(parent), _parentage) : _parentage ? [_parentage, parent] : parent;\n }\n\n /**\n * Called on a child when it is removed via {@link #remove}.\n * @param parent The parent to remove\n */\n private _removeParent(parent: Subscription) {\n const { _parentage } = this;\n if (_parentage === parent) {\n this._parentage = null;\n } else if (Array.isArray(_parentage)) {\n arrRemove(_parentage, parent);\n }\n }\n\n /**\n * Removes a finalizer from this subscription that was previously added with the {@link #add} method.\n *\n * Note that `Subscription` instances, when unsubscribed, will automatically remove themselves\n * from every other `Subscription` they have been added to. This means that using the `remove` method\n * is not a common thing and should be used thoughtfully.\n *\n * If you add the same finalizer instance of a function or an unsubscribable object to a `Subscription` instance\n * more than once, you will need to call `remove` the same number of times to remove all instances.\n *\n * All finalizer instances are removed to free up memory upon unsubscription.\n *\n * @param teardown The finalizer to remove from this subscription\n */\n remove(teardown: Exclude): void {\n const { _finalizers } = this;\n _finalizers && arrRemove(_finalizers, teardown);\n\n if (teardown instanceof Subscription) {\n teardown._removeParent(this);\n }\n }\n}\n\nexport const EMPTY_SUBSCRIPTION = Subscription.EMPTY;\n\nexport function isSubscription(value: any): value is Subscription {\n return (\n value instanceof Subscription ||\n (value && 'closed' in value && isFunction(value.remove) && isFunction(value.add) && isFunction(value.unsubscribe))\n );\n}\n\nfunction execFinalizer(finalizer: Unsubscribable | (() => void)) {\n if (isFunction(finalizer)) {\n finalizer();\n } else {\n finalizer.unsubscribe();\n }\n}\n", "import { Subscriber } from './Subscriber';\nimport { ObservableNotification } from './types';\n\n/**\n * The {@link GlobalConfig} object for RxJS. It is used to configure things\n * like how to react on unhandled errors.\n */\nexport const config: GlobalConfig = {\n onUnhandledError: null,\n onStoppedNotification: null,\n Promise: undefined,\n useDeprecatedSynchronousErrorHandling: false,\n useDeprecatedNextContext: false,\n};\n\n/**\n * The global configuration object for RxJS, used to configure things\n * like how to react on unhandled errors. Accessible via {@link config}\n * object.\n */\nexport interface GlobalConfig {\n /**\n * A registration point for unhandled errors from RxJS. These are errors that\n * cannot were not handled by consuming code in the usual subscription path. For\n * example, if you have this configured, and you subscribe to an observable without\n * providing an error handler, errors from that subscription will end up here. This\n * will _always_ be called asynchronously on another job in the runtime. This is because\n * we do not want errors thrown in this user-configured handler to interfere with the\n * behavior of the library.\n */\n onUnhandledError: ((err: any) => void) | null;\n\n /**\n * A registration point for notifications that cannot be sent to subscribers because they\n * have completed, errored or have been explicitly unsubscribed. By default, next, complete\n * and error notifications sent to stopped subscribers are noops. However, sometimes callers\n * might want a different behavior. For example, with sources that attempt to report errors\n * to stopped subscribers, a caller can configure RxJS to throw an unhandled error instead.\n * This will _always_ be called asynchronously on another job in the runtime. This is because\n * we do not want errors thrown in this user-configured handler to interfere with the\n * behavior of the library.\n */\n onStoppedNotification: ((notification: ObservableNotification, subscriber: Subscriber) => void) | null;\n\n /**\n * The promise constructor used by default for {@link Observable#toPromise toPromise} and {@link Observable#forEach forEach}\n * methods.\n *\n * @deprecated As of version 8, RxJS will no longer support this sort of injection of a\n * Promise constructor. If you need a Promise implementation other than native promises,\n * please polyfill/patch Promise as you see appropriate. Will be removed in v8.\n */\n Promise?: PromiseConstructorLike;\n\n /**\n * If true, turns on synchronous error rethrowing, which is a deprecated behavior\n * in v6 and higher. This behavior enables bad patterns like wrapping a subscribe\n * call in a try/catch block. It also enables producer interference, a nasty bug\n * where a multicast can be broken for all observers by a downstream consumer with\n * an unhandled error. DO NOT USE THIS FLAG UNLESS IT'S NEEDED TO BUY TIME\n * FOR MIGRATION REASONS.\n *\n * @deprecated As of version 8, RxJS will no longer support synchronous throwing\n * of unhandled errors. All errors will be thrown on a separate call stack to prevent bad\n * behaviors described above. Will be removed in v8.\n */\n useDeprecatedSynchronousErrorHandling: boolean;\n\n /**\n * If true, enables an as-of-yet undocumented feature from v5: The ability to access\n * `unsubscribe()` via `this` context in `next` functions created in observers passed\n * to `subscribe`.\n *\n * This is being removed because the performance was severely problematic, and it could also cause\n * issues when types other than POJOs are passed to subscribe as subscribers, as they will likely have\n * their `this` context overwritten.\n *\n * @deprecated As of version 8, RxJS will no longer support altering the\n * context of next functions provided as part of an observer to Subscribe. Instead,\n * you will have access to a subscription or a signal or token that will allow you to do things like\n * unsubscribe and test closed status. Will be removed in v8.\n */\n useDeprecatedNextContext: boolean;\n}\n", "import type { TimerHandle } from './timerHandle';\ntype SetTimeoutFunction = (handler: () => void, timeout?: number, ...args: any[]) => TimerHandle;\ntype ClearTimeoutFunction = (handle: TimerHandle) => void;\n\ninterface TimeoutProvider {\n setTimeout: SetTimeoutFunction;\n clearTimeout: ClearTimeoutFunction;\n delegate:\n | {\n setTimeout: SetTimeoutFunction;\n clearTimeout: ClearTimeoutFunction;\n }\n | undefined;\n}\n\nexport const timeoutProvider: TimeoutProvider = {\n // When accessing the delegate, use the variable rather than `this` so that\n // the functions can be called without being bound to the provider.\n setTimeout(handler: () => void, timeout?: number, ...args) {\n const { delegate } = timeoutProvider;\n if (delegate?.setTimeout) {\n return delegate.setTimeout(handler, timeout, ...args);\n }\n return setTimeout(handler, timeout, ...args);\n },\n clearTimeout(handle) {\n const { delegate } = timeoutProvider;\n return (delegate?.clearTimeout || clearTimeout)(handle as any);\n },\n delegate: undefined,\n};\n", "import { config } from '../config';\nimport { timeoutProvider } from '../scheduler/timeoutProvider';\n\n/**\n * Handles an error on another job either with the user-configured {@link onUnhandledError},\n * or by throwing it on that new job so it can be picked up by `window.onerror`, `process.on('error')`, etc.\n *\n * This should be called whenever there is an error that is out-of-band with the subscription\n * or when an error hits a terminal boundary of the subscription and no error handler was provided.\n *\n * @param err the error to report\n */\nexport function reportUnhandledError(err: any) {\n timeoutProvider.setTimeout(() => {\n const { onUnhandledError } = config;\n if (onUnhandledError) {\n // Execute the user-configured error handler.\n onUnhandledError(err);\n } else {\n // Throw so it is picked up by the runtime's uncaught error mechanism.\n throw err;\n }\n });\n}\n", "/* tslint:disable:no-empty */\nexport function noop() { }\n", "import { CompleteNotification, NextNotification, ErrorNotification } from './types';\n\n/**\n * A completion object optimized for memory use and created to be the\n * same \"shape\" as other notifications in v8.\n * @internal\n */\nexport const COMPLETE_NOTIFICATION = (() => createNotification('C', undefined, undefined) as CompleteNotification)();\n\n/**\n * Internal use only. Creates an optimized error notification that is the same \"shape\"\n * as other notifications.\n * @internal\n */\nexport function errorNotification(error: any): ErrorNotification {\n return createNotification('E', undefined, error) as any;\n}\n\n/**\n * Internal use only. Creates an optimized next notification that is the same \"shape\"\n * as other notifications.\n * @internal\n */\nexport function nextNotification(value: T) {\n return createNotification('N', value, undefined) as NextNotification;\n}\n\n/**\n * Ensures that all notifications created internally have the same \"shape\" in v8.\n *\n * TODO: This is only exported to support a crazy legacy test in `groupBy`.\n * @internal\n */\nexport function createNotification(kind: 'N' | 'E' | 'C', value: any, error: any) {\n return {\n kind,\n value,\n error,\n };\n}\n", "import { config } from '../config';\n\nlet context: { errorThrown: boolean; error: any } | null = null;\n\n/**\n * Handles dealing with errors for super-gross mode. Creates a context, in which\n * any synchronously thrown errors will be passed to {@link captureError}. Which\n * will record the error such that it will be rethrown after the call back is complete.\n * TODO: Remove in v8\n * @param cb An immediately executed function.\n */\nexport function errorContext(cb: () => void) {\n if (config.useDeprecatedSynchronousErrorHandling) {\n const isRoot = !context;\n if (isRoot) {\n context = { errorThrown: false, error: null };\n }\n cb();\n if (isRoot) {\n const { errorThrown, error } = context!;\n context = null;\n if (errorThrown) {\n throw error;\n }\n }\n } else {\n // This is the general non-deprecated path for everyone that\n // isn't crazy enough to use super-gross mode (useDeprecatedSynchronousErrorHandling)\n cb();\n }\n}\n\n/**\n * Captures errors only in super-gross mode.\n * @param err the error to capture\n */\nexport function captureError(err: any) {\n if (config.useDeprecatedSynchronousErrorHandling && context) {\n context.errorThrown = true;\n context.error = err;\n }\n}\n", "import { isFunction } from './util/isFunction';\nimport { Observer, ObservableNotification } from './types';\nimport { isSubscription, Subscription } from './Subscription';\nimport { config } from './config';\nimport { reportUnhandledError } from './util/reportUnhandledError';\nimport { noop } from './util/noop';\nimport { nextNotification, errorNotification, COMPLETE_NOTIFICATION } from './NotificationFactories';\nimport { timeoutProvider } from './scheduler/timeoutProvider';\nimport { captureError } from './util/errorContext';\n\n/**\n * Implements the {@link Observer} interface and extends the\n * {@link Subscription} class. While the {@link Observer} is the public API for\n * consuming the values of an {@link Observable}, all Observers get converted to\n * a Subscriber, in order to provide Subscription-like capabilities such as\n * `unsubscribe`. Subscriber is a common type in RxJS, and crucial for\n * implementing operators, but it is rarely used as a public API.\n */\nexport class Subscriber extends Subscription implements Observer {\n /**\n * A static factory for a Subscriber, given a (potentially partial) definition\n * of an Observer.\n * @param next The `next` callback of an Observer.\n * @param error The `error` callback of an\n * Observer.\n * @param complete The `complete` callback of an\n * Observer.\n * @return A Subscriber wrapping the (partially defined)\n * Observer represented by the given arguments.\n * @deprecated Do not use. Will be removed in v8. There is no replacement for this\n * method, and there is no reason to be creating instances of `Subscriber` directly.\n * If you have a specific use case, please file an issue.\n */\n static create(next?: (x?: T) => void, error?: (e?: any) => void, complete?: () => void): Subscriber {\n return new SafeSubscriber(next, error, complete);\n }\n\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n protected isStopped: boolean = false;\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n protected destination: Subscriber | Observer; // this `any` is the escape hatch to erase extra type param (e.g. R)\n\n /**\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n * There is no reason to directly create an instance of Subscriber. This type is exported for typings reasons.\n */\n constructor(destination?: Subscriber | Observer) {\n super();\n if (destination) {\n this.destination = destination;\n // Automatically chain subscriptions together here.\n // if destination is a Subscription, then it is a Subscriber.\n if (isSubscription(destination)) {\n destination.add(this);\n }\n } else {\n this.destination = EMPTY_OBSERVER;\n }\n }\n\n /**\n * The {@link Observer} callback to receive notifications of type `next` from\n * the Observable, with a value. The Observable may call this method 0 or more\n * times.\n * @param value The `next` value.\n */\n next(value: T): void {\n if (this.isStopped) {\n handleStoppedNotification(nextNotification(value), this);\n } else {\n this._next(value!);\n }\n }\n\n /**\n * The {@link Observer} callback to receive notifications of type `error` from\n * the Observable, with an attached `Error`. Notifies the Observer that\n * the Observable has experienced an error condition.\n * @param err The `error` exception.\n */\n error(err?: any): void {\n if (this.isStopped) {\n handleStoppedNotification(errorNotification(err), this);\n } else {\n this.isStopped = true;\n this._error(err);\n }\n }\n\n /**\n * The {@link Observer} callback to receive a valueless notification of type\n * `complete` from the Observable. Notifies the Observer that the Observable\n * has finished sending push-based notifications.\n */\n complete(): void {\n if (this.isStopped) {\n handleStoppedNotification(COMPLETE_NOTIFICATION, this);\n } else {\n this.isStopped = true;\n this._complete();\n }\n }\n\n unsubscribe(): void {\n if (!this.closed) {\n this.isStopped = true;\n super.unsubscribe();\n this.destination = null!;\n }\n }\n\n protected _next(value: T): void {\n this.destination.next(value);\n }\n\n protected _error(err: any): void {\n try {\n this.destination.error(err);\n } finally {\n this.unsubscribe();\n }\n }\n\n protected _complete(): void {\n try {\n this.destination.complete();\n } finally {\n this.unsubscribe();\n }\n }\n}\n\n/**\n * This bind is captured here because we want to be able to have\n * compatibility with monoid libraries that tend to use a method named\n * `bind`. In particular, a library called Monio requires this.\n */\nconst _bind = Function.prototype.bind;\n\nfunction bind any>(fn: Fn, thisArg: any): Fn {\n return _bind.call(fn, thisArg);\n}\n\n/**\n * Internal optimization only, DO NOT EXPOSE.\n * @internal\n */\nclass ConsumerObserver implements Observer {\n constructor(private partialObserver: Partial>) {}\n\n next(value: T): void {\n const { partialObserver } = this;\n if (partialObserver.next) {\n try {\n partialObserver.next(value);\n } catch (error) {\n handleUnhandledError(error);\n }\n }\n }\n\n error(err: any): void {\n const { partialObserver } = this;\n if (partialObserver.error) {\n try {\n partialObserver.error(err);\n } catch (error) {\n handleUnhandledError(error);\n }\n } else {\n handleUnhandledError(err);\n }\n }\n\n complete(): void {\n const { partialObserver } = this;\n if (partialObserver.complete) {\n try {\n partialObserver.complete();\n } catch (error) {\n handleUnhandledError(error);\n }\n }\n }\n}\n\nexport class SafeSubscriber extends Subscriber {\n constructor(\n observerOrNext?: Partial> | ((value: T) => void) | null,\n error?: ((e?: any) => void) | null,\n complete?: (() => void) | null\n ) {\n super();\n\n let partialObserver: Partial>;\n if (isFunction(observerOrNext) || !observerOrNext) {\n // The first argument is a function, not an observer. The next\n // two arguments *could* be observers, or they could be empty.\n partialObserver = {\n next: (observerOrNext ?? undefined) as ((value: T) => void) | undefined,\n error: error ?? undefined,\n complete: complete ?? undefined,\n };\n } else {\n // The first argument is a partial observer.\n let context: any;\n if (this && config.useDeprecatedNextContext) {\n // This is a deprecated path that made `this.unsubscribe()` available in\n // next handler functions passed to subscribe. This only exists behind a flag\n // now, as it is *very* slow.\n context = Object.create(observerOrNext);\n context.unsubscribe = () => this.unsubscribe();\n partialObserver = {\n next: observerOrNext.next && bind(observerOrNext.next, context),\n error: observerOrNext.error && bind(observerOrNext.error, context),\n complete: observerOrNext.complete && bind(observerOrNext.complete, context),\n };\n } else {\n // The \"normal\" path. Just use the partial observer directly.\n partialObserver = observerOrNext;\n }\n }\n\n // Wrap the partial observer to ensure it's a full observer, and\n // make sure proper error handling is accounted for.\n this.destination = new ConsumerObserver(partialObserver);\n }\n}\n\nfunction handleUnhandledError(error: any) {\n if (config.useDeprecatedSynchronousErrorHandling) {\n captureError(error);\n } else {\n // Ideal path, we report this as an unhandled error,\n // which is thrown on a new call stack.\n reportUnhandledError(error);\n }\n}\n\n/**\n * An error handler used when no error handler was supplied\n * to the SafeSubscriber -- meaning no error handler was supplied\n * do the `subscribe` call on our observable.\n * @param err The error to handle\n */\nfunction defaultErrorHandler(err: any) {\n throw err;\n}\n\n/**\n * A handler for notifications that cannot be sent to a stopped subscriber.\n * @param notification The notification being sent.\n * @param subscriber The stopped subscriber.\n */\nfunction handleStoppedNotification(notification: ObservableNotification, subscriber: Subscriber) {\n const { onStoppedNotification } = config;\n onStoppedNotification && timeoutProvider.setTimeout(() => onStoppedNotification(notification, subscriber));\n}\n\n/**\n * The observer used as a stub for subscriptions where the user did not\n * pass any arguments to `subscribe`. Comes with the default error handling\n * behavior.\n */\nexport const EMPTY_OBSERVER: Readonly> & { closed: true } = {\n closed: true,\n next: noop,\n error: defaultErrorHandler,\n complete: noop,\n};\n", "/**\n * Symbol.observable or a string \"@@observable\". Used for interop\n *\n * @deprecated We will no longer be exporting this symbol in upcoming versions of RxJS.\n * Instead polyfill and use Symbol.observable directly *or* use https://www.npmjs.com/package/symbol-observable\n */\nexport const observable: string | symbol = (() => (typeof Symbol === 'function' && Symbol.observable) || '@@observable')();\n", "/**\n * This function takes one parameter and just returns it. Simply put,\n * this is like `(x: T): T => x`.\n *\n * ## Examples\n *\n * This is useful in some cases when using things like `mergeMap`\n *\n * ```ts\n * import { interval, take, map, range, mergeMap, identity } from 'rxjs';\n *\n * const source$ = interval(1000).pipe(take(5));\n *\n * const result$ = source$.pipe(\n * map(i => range(i)),\n * mergeMap(identity) // same as mergeMap(x => x)\n * );\n *\n * result$.subscribe({\n * next: console.log\n * });\n * ```\n *\n * Or when you want to selectively apply an operator\n *\n * ```ts\n * import { interval, take, identity } from 'rxjs';\n *\n * const shouldLimit = () => Math.random() < 0.5;\n *\n * const source$ = interval(1000);\n *\n * const result$ = source$.pipe(shouldLimit() ? take(5) : identity);\n *\n * result$.subscribe({\n * next: console.log\n * });\n * ```\n *\n * @param x Any value that is returned by this function\n * @returns The value passed as the first parameter to this function\n */\nexport function identity(x: T): T {\n return x;\n}\n", "import { identity } from './identity';\nimport { UnaryFunction } from '../types';\n\nexport function pipe(): typeof identity;\nexport function pipe(fn1: UnaryFunction): UnaryFunction;\nexport function pipe(fn1: UnaryFunction, fn2: UnaryFunction): UnaryFunction;\nexport function pipe(fn1: UnaryFunction, fn2: UnaryFunction, fn3: UnaryFunction): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction,\n fn8: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction,\n fn8: UnaryFunction,\n fn9: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction,\n fn8: UnaryFunction,\n fn9: UnaryFunction,\n ...fns: UnaryFunction[]\n): UnaryFunction;\n\n/**\n * pipe() can be called on one or more functions, each of which can take one argument (\"UnaryFunction\")\n * and uses it to return a value.\n * It returns a function that takes one argument, passes it to the first UnaryFunction, and then\n * passes the result to the next one, passes that result to the next one, and so on. \n */\nexport function pipe(...fns: Array>): UnaryFunction {\n return pipeFromArray(fns);\n}\n\n/** @internal */\nexport function pipeFromArray(fns: Array>): UnaryFunction {\n if (fns.length === 0) {\n return identity as UnaryFunction;\n }\n\n if (fns.length === 1) {\n return fns[0];\n }\n\n return function piped(input: T): R {\n return fns.reduce((prev: any, fn: UnaryFunction) => fn(prev), input as any);\n };\n}\n", "import { Operator } from './Operator';\nimport { SafeSubscriber, Subscriber } from './Subscriber';\nimport { isSubscription, Subscription } from './Subscription';\nimport { TeardownLogic, OperatorFunction, Subscribable, Observer } from './types';\nimport { observable as Symbol_observable } from './symbol/observable';\nimport { pipeFromArray } from './util/pipe';\nimport { config } from './config';\nimport { isFunction } from './util/isFunction';\nimport { errorContext } from './util/errorContext';\n\n/**\n * A representation of any set of values over any amount of time. This is the most basic building block\n * of RxJS.\n */\nexport class Observable implements Subscribable {\n /**\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n */\n source: Observable | undefined;\n\n /**\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n */\n operator: Operator | undefined;\n\n /**\n * @param subscribe The function that is called when the Observable is\n * initially subscribed to. This function is given a Subscriber, to which new values\n * can be `next`ed, or an `error` method can be called to raise an error, or\n * `complete` can be called to notify of a successful completion.\n */\n constructor(subscribe?: (this: Observable, subscriber: Subscriber) => TeardownLogic) {\n if (subscribe) {\n this._subscribe = subscribe;\n }\n }\n\n // HACK: Since TypeScript inherits static properties too, we have to\n // fight against TypeScript here so Subject can have a different static create signature\n /**\n * Creates a new Observable by calling the Observable constructor\n * @param subscribe the subscriber function to be passed to the Observable constructor\n * @return A new observable.\n * @deprecated Use `new Observable()` instead. Will be removed in v8.\n */\n static create: (...args: any[]) => any = (subscribe?: (subscriber: Subscriber) => TeardownLogic) => {\n return new Observable(subscribe);\n };\n\n /**\n * Creates a new Observable, with this Observable instance as the source, and the passed\n * operator defined as the new observable's operator.\n * @param operator the operator defining the operation to take on the observable\n * @return A new observable with the Operator applied.\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n * If you have implemented an operator using `lift`, it is recommended that you create an\n * operator by simply returning `new Observable()` directly. See \"Creating new operators from\n * scratch\" section here: https://rxjs.dev/guide/operators\n */\n lift(operator?: Operator): Observable {\n const observable = new Observable();\n observable.source = this;\n observable.operator = operator;\n return observable;\n }\n\n subscribe(observerOrNext?: Partial> | ((value: T) => void)): Subscription;\n /** @deprecated Instead of passing separate callback arguments, use an observer argument. Signatures taking separate callback arguments will be removed in v8. Details: https://rxjs.dev/deprecations/subscribe-arguments */\n subscribe(next?: ((value: T) => void) | null, error?: ((error: any) => void) | null, complete?: (() => void) | null): Subscription;\n /**\n * Invokes an execution of an Observable and registers Observer handlers for notifications it will emit.\n *\n * Use it when you have all these Observables, but still nothing is happening.\n *\n * `subscribe` is not a regular operator, but a method that calls Observable's internal `subscribe` function. It\n * might be for example a function that you passed to Observable's constructor, but most of the time it is\n * a library implementation, which defines what will be emitted by an Observable, and when it be will emitted. This means\n * that calling `subscribe` is actually the moment when Observable starts its work, not when it is created, as it is often\n * the thought.\n *\n * Apart from starting the execution of an Observable, this method allows you to listen for values\n * that an Observable emits, as well as for when it completes or errors. You can achieve this in two\n * of the following ways.\n *\n * The first way is creating an object that implements {@link Observer} interface. It should have methods\n * defined by that interface, but note that it should be just a regular JavaScript object, which you can create\n * yourself in any way you want (ES6 class, classic function constructor, object literal etc.). In particular, do\n * not attempt to use any RxJS implementation details to create Observers - you don't need them. Remember also\n * that your object does not have to implement all methods. If you find yourself creating a method that doesn't\n * do anything, you can simply omit it. Note however, if the `error` method is not provided and an error happens,\n * it will be thrown asynchronously. Errors thrown asynchronously cannot be caught using `try`/`catch`. Instead,\n * use the {@link onUnhandledError} configuration option or use a runtime handler (like `window.onerror` or\n * `process.on('error)`) to be notified of unhandled errors. Because of this, it's recommended that you provide\n * an `error` method to avoid missing thrown errors.\n *\n * The second way is to give up on Observer object altogether and simply provide callback functions in place of its methods.\n * This means you can provide three functions as arguments to `subscribe`, where the first function is equivalent\n * of a `next` method, the second of an `error` method and the third of a `complete` method. Just as in case of an Observer,\n * if you do not need to listen for something, you can omit a function by passing `undefined` or `null`,\n * since `subscribe` recognizes these functions by where they were placed in function call. When it comes\n * to the `error` function, as with an Observer, if not provided, errors emitted by an Observable will be thrown asynchronously.\n *\n * You can, however, subscribe with no parameters at all. This may be the case where you're not interested in terminal events\n * and you also handled emissions internally by using operators (e.g. using `tap`).\n *\n * Whichever style of calling `subscribe` you use, in both cases it returns a Subscription object.\n * This object allows you to call `unsubscribe` on it, which in turn will stop the work that an Observable does and will clean\n * up all resources that an Observable used. Note that cancelling a subscription will not call `complete` callback\n * provided to `subscribe` function, which is reserved for a regular completion signal that comes from an Observable.\n *\n * Remember that callbacks provided to `subscribe` are not guaranteed to be called asynchronously.\n * It is an Observable itself that decides when these functions will be called. For example {@link of}\n * by default emits all its values synchronously. Always check documentation for how given Observable\n * will behave when subscribed and if its default behavior can be modified with a `scheduler`.\n *\n * #### Examples\n *\n * Subscribe with an {@link guide/observer Observer}\n *\n * ```ts\n * import { of } from 'rxjs';\n *\n * const sumObserver = {\n * sum: 0,\n * next(value) {\n * console.log('Adding: ' + value);\n * this.sum = this.sum + value;\n * },\n * error() {\n * // We actually could just remove this method,\n * // since we do not really care about errors right now.\n * },\n * complete() {\n * console.log('Sum equals: ' + this.sum);\n * }\n * };\n *\n * of(1, 2, 3) // Synchronously emits 1, 2, 3 and then completes.\n * .subscribe(sumObserver);\n *\n * // Logs:\n * // 'Adding: 1'\n * // 'Adding: 2'\n * // 'Adding: 3'\n * // 'Sum equals: 6'\n * ```\n *\n * Subscribe with functions ({@link deprecations/subscribe-arguments deprecated})\n *\n * ```ts\n * import { of } from 'rxjs'\n *\n * let sum = 0;\n *\n * of(1, 2, 3).subscribe(\n * value => {\n * console.log('Adding: ' + value);\n * sum = sum + value;\n * },\n * undefined,\n * () => console.log('Sum equals: ' + sum)\n * );\n *\n * // Logs:\n * // 'Adding: 1'\n * // 'Adding: 2'\n * // 'Adding: 3'\n * // 'Sum equals: 6'\n * ```\n *\n * Cancel a subscription\n *\n * ```ts\n * import { interval } from 'rxjs';\n *\n * const subscription = interval(1000).subscribe({\n * next(num) {\n * console.log(num)\n * },\n * complete() {\n * // Will not be called, even when cancelling subscription.\n * console.log('completed!');\n * }\n * });\n *\n * setTimeout(() => {\n * subscription.unsubscribe();\n * console.log('unsubscribed!');\n * }, 2500);\n *\n * // Logs:\n * // 0 after 1s\n * // 1 after 2s\n * // 'unsubscribed!' after 2.5s\n * ```\n *\n * @param observerOrNext Either an {@link Observer} with some or all callback methods,\n * or the `next` handler that is called for each value emitted from the subscribed Observable.\n * @param error A handler for a terminal event resulting from an error. If no error handler is provided,\n * the error will be thrown asynchronously as unhandled.\n * @param complete A handler for a terminal event resulting from successful completion.\n * @return A subscription reference to the registered handlers.\n */\n subscribe(\n observerOrNext?: Partial> | ((value: T) => void) | null,\n error?: ((error: any) => void) | null,\n complete?: (() => void) | null\n ): Subscription {\n const subscriber = isSubscriber(observerOrNext) ? observerOrNext : new SafeSubscriber(observerOrNext, error, complete);\n\n errorContext(() => {\n const { operator, source } = this;\n subscriber.add(\n operator\n ? // We're dealing with a subscription in the\n // operator chain to one of our lifted operators.\n operator.call(subscriber, source)\n : source\n ? // If `source` has a value, but `operator` does not, something that\n // had intimate knowledge of our API, like our `Subject`, must have\n // set it. We're going to just call `_subscribe` directly.\n this._subscribe(subscriber)\n : // In all other cases, we're likely wrapping a user-provided initializer\n // function, so we need to catch errors and handle them appropriately.\n this._trySubscribe(subscriber)\n );\n });\n\n return subscriber;\n }\n\n /** @internal */\n protected _trySubscribe(sink: Subscriber): TeardownLogic {\n try {\n return this._subscribe(sink);\n } catch (err) {\n // We don't need to return anything in this case,\n // because it's just going to try to `add()` to a subscription\n // above.\n sink.error(err);\n }\n }\n\n /**\n * Used as a NON-CANCELLABLE means of subscribing to an observable, for use with\n * APIs that expect promises, like `async/await`. You cannot unsubscribe from this.\n *\n * **WARNING**: Only use this with observables you *know* will complete. If the source\n * observable does not complete, you will end up with a promise that is hung up, and\n * potentially all of the state of an async function hanging out in memory. To avoid\n * this situation, look into adding something like {@link timeout}, {@link take},\n * {@link takeWhile}, or {@link takeUntil} amongst others.\n *\n * #### Example\n *\n * ```ts\n * import { interval, take } from 'rxjs';\n *\n * const source$ = interval(1000).pipe(take(4));\n *\n * async function getTotal() {\n * let total = 0;\n *\n * await source$.forEach(value => {\n * total += value;\n * console.log('observable -> ' + value);\n * });\n *\n * return total;\n * }\n *\n * getTotal().then(\n * total => console.log('Total: ' + total)\n * );\n *\n * // Expected:\n * // 'observable -> 0'\n * // 'observable -> 1'\n * // 'observable -> 2'\n * // 'observable -> 3'\n * // 'Total: 6'\n * ```\n *\n * @param next A handler for each value emitted by the observable.\n * @return A promise that either resolves on observable completion or\n * rejects with the handled error.\n */\n forEach(next: (value: T) => void): Promise;\n\n /**\n * @param next a handler for each value emitted by the observable\n * @param promiseCtor a constructor function used to instantiate the Promise\n * @return a promise that either resolves on observable completion or\n * rejects with the handled error\n * @deprecated Passing a Promise constructor will no longer be available\n * in upcoming versions of RxJS. This is because it adds weight to the library, for very\n * little benefit. If you need this functionality, it is recommended that you either\n * polyfill Promise, or you create an adapter to convert the returned native promise\n * to whatever promise implementation you wanted. Will be removed in v8.\n */\n forEach(next: (value: T) => void, promiseCtor: PromiseConstructorLike): Promise;\n\n forEach(next: (value: T) => void, promiseCtor?: PromiseConstructorLike): Promise {\n promiseCtor = getPromiseCtor(promiseCtor);\n\n return new promiseCtor((resolve, reject) => {\n const subscriber = new SafeSubscriber({\n next: (value) => {\n try {\n next(value);\n } catch (err) {\n reject(err);\n subscriber.unsubscribe();\n }\n },\n error: reject,\n complete: resolve,\n });\n this.subscribe(subscriber);\n }) as Promise;\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): TeardownLogic {\n return this.source?.subscribe(subscriber);\n }\n\n /**\n * An interop point defined by the es7-observable spec https://github.com/zenparsing/es-observable\n * @return This instance of the observable.\n */\n [Symbol_observable]() {\n return this;\n }\n\n /* tslint:disable:max-line-length */\n pipe(): Observable;\n pipe(op1: OperatorFunction): Observable;\n pipe(op1: OperatorFunction, op2: OperatorFunction): Observable;\n pipe(op1: OperatorFunction, op2: OperatorFunction, op3: OperatorFunction): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction,\n op8: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction,\n op8: OperatorFunction,\n op9: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction,\n op8: OperatorFunction,\n op9: OperatorFunction,\n ...operations: OperatorFunction[]\n ): Observable;\n /* tslint:enable:max-line-length */\n\n /**\n * Used to stitch together functional operators into a chain.\n *\n * ## Example\n *\n * ```ts\n * import { interval, filter, map, scan } from 'rxjs';\n *\n * interval(1000)\n * .pipe(\n * filter(x => x % 2 === 0),\n * map(x => x + x),\n * scan((acc, x) => acc + x)\n * )\n * .subscribe(x => console.log(x));\n * ```\n *\n * @return The Observable result of all the operators having been called\n * in the order they were passed in.\n */\n pipe(...operations: OperatorFunction[]): Observable {\n return pipeFromArray(operations)(this);\n }\n\n /* tslint:disable:max-line-length */\n /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n toPromise(): Promise;\n /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n toPromise(PromiseCtor: typeof Promise): Promise;\n /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n toPromise(PromiseCtor: PromiseConstructorLike): Promise;\n /* tslint:enable:max-line-length */\n\n /**\n * Subscribe to this Observable and get a Promise resolving on\n * `complete` with the last emission (if any).\n *\n * **WARNING**: Only use this with observables you *know* will complete. If the source\n * observable does not complete, you will end up with a promise that is hung up, and\n * potentially all of the state of an async function hanging out in memory. To avoid\n * this situation, look into adding something like {@link timeout}, {@link take},\n * {@link takeWhile}, or {@link takeUntil} amongst others.\n *\n * @param [promiseCtor] a constructor function used to instantiate\n * the Promise\n * @return A Promise that resolves with the last value emit, or\n * rejects on an error. If there were no emissions, Promise\n * resolves with undefined.\n * @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise\n */\n toPromise(promiseCtor?: PromiseConstructorLike): Promise {\n promiseCtor = getPromiseCtor(promiseCtor);\n\n return new promiseCtor((resolve, reject) => {\n let value: T | undefined;\n this.subscribe(\n (x: T) => (value = x),\n (err: any) => reject(err),\n () => resolve(value)\n );\n }) as Promise;\n }\n}\n\n/**\n * Decides between a passed promise constructor from consuming code,\n * A default configured promise constructor, and the native promise\n * constructor and returns it. If nothing can be found, it will throw\n * an error.\n * @param promiseCtor The optional promise constructor to passed by consuming code\n */\nfunction getPromiseCtor(promiseCtor: PromiseConstructorLike | undefined) {\n return promiseCtor ?? config.Promise ?? Promise;\n}\n\nfunction isObserver(value: any): value is Observer {\n return value && isFunction(value.next) && isFunction(value.error) && isFunction(value.complete);\n}\n\nfunction isSubscriber(value: any): value is Subscriber {\n return (value && value instanceof Subscriber) || (isObserver(value) && isSubscription(value));\n}\n", "import { Observable } from '../Observable';\nimport { Subscriber } from '../Subscriber';\nimport { OperatorFunction } from '../types';\nimport { isFunction } from './isFunction';\n\n/**\n * Used to determine if an object is an Observable with a lift function.\n */\nexport function hasLift(source: any): source is { lift: InstanceType['lift'] } {\n return isFunction(source?.lift);\n}\n\n/**\n * Creates an `OperatorFunction`. Used to define operators throughout the library in a concise way.\n * @param init The logic to connect the liftedSource to the subscriber at the moment of subscription.\n */\nexport function operate(\n init: (liftedSource: Observable, subscriber: Subscriber) => (() => void) | void\n): OperatorFunction {\n return (source: Observable) => {\n if (hasLift(source)) {\n return source.lift(function (this: Subscriber, liftedSource: Observable) {\n try {\n return init(liftedSource, this);\n } catch (err) {\n this.error(err);\n }\n });\n }\n throw new TypeError('Unable to lift unknown Observable type');\n };\n}\n", "import { Subscriber } from '../Subscriber';\n\n/**\n * Creates an instance of an `OperatorSubscriber`.\n * @param destination The downstream subscriber.\n * @param onNext Handles next values, only called if this subscriber is not stopped or closed. Any\n * error that occurs in this function is caught and sent to the `error` method of this subscriber.\n * @param onError Handles errors from the subscription, any errors that occur in this handler are caught\n * and send to the `destination` error handler.\n * @param onComplete Handles completion notification from the subscription. Any errors that occur in\n * this handler are sent to the `destination` error handler.\n * @param onFinalize Additional teardown logic here. This will only be called on teardown if the\n * subscriber itself is not already closed. This is called after all other teardown logic is executed.\n */\nexport function createOperatorSubscriber(\n destination: Subscriber,\n onNext?: (value: T) => void,\n onComplete?: () => void,\n onError?: (err: any) => void,\n onFinalize?: () => void\n): Subscriber {\n return new OperatorSubscriber(destination, onNext, onComplete, onError, onFinalize);\n}\n\n/**\n * A generic helper for allowing operators to be created with a Subscriber and\n * use closures to capture necessary state from the operator function itself.\n */\nexport class OperatorSubscriber extends Subscriber {\n /**\n * Creates an instance of an `OperatorSubscriber`.\n * @param destination The downstream subscriber.\n * @param onNext Handles next values, only called if this subscriber is not stopped or closed. Any\n * error that occurs in this function is caught and sent to the `error` method of this subscriber.\n * @param onError Handles errors from the subscription, any errors that occur in this handler are caught\n * and send to the `destination` error handler.\n * @param onComplete Handles completion notification from the subscription. Any errors that occur in\n * this handler are sent to the `destination` error handler.\n * @param onFinalize Additional finalization logic here. This will only be called on finalization if the\n * subscriber itself is not already closed. This is called after all other finalization logic is executed.\n * @param shouldUnsubscribe An optional check to see if an unsubscribe call should truly unsubscribe.\n * NOTE: This currently **ONLY** exists to support the strange behavior of {@link groupBy}, where unsubscription\n * to the resulting observable does not actually disconnect from the source if there are active subscriptions\n * to any grouped observable. (DO NOT EXPOSE OR USE EXTERNALLY!!!)\n */\n constructor(\n destination: Subscriber,\n onNext?: (value: T) => void,\n onComplete?: () => void,\n onError?: (err: any) => void,\n private onFinalize?: () => void,\n private shouldUnsubscribe?: () => boolean\n ) {\n // It's important - for performance reasons - that all of this class's\n // members are initialized and that they are always initialized in the same\n // order. This will ensure that all OperatorSubscriber instances have the\n // same hidden class in V8. This, in turn, will help keep the number of\n // hidden classes involved in property accesses within the base class as\n // low as possible. If the number of hidden classes involved exceeds four,\n // the property accesses will become megamorphic and performance penalties\n // will be incurred - i.e. inline caches won't be used.\n //\n // The reasons for ensuring all instances have the same hidden class are\n // further discussed in this blog post from Benedikt Meurer:\n // https://benediktmeurer.de/2018/03/23/impact-of-polymorphism-on-component-based-frameworks-like-react/\n super(destination);\n this._next = onNext\n ? function (this: OperatorSubscriber, value: T) {\n try {\n onNext(value);\n } catch (err) {\n destination.error(err);\n }\n }\n : super._next;\n this._error = onError\n ? function (this: OperatorSubscriber, err: any) {\n try {\n onError(err);\n } catch (err) {\n // Send any errors that occur down stream.\n destination.error(err);\n } finally {\n // Ensure finalization.\n this.unsubscribe();\n }\n }\n : super._error;\n this._complete = onComplete\n ? function (this: OperatorSubscriber) {\n try {\n onComplete();\n } catch (err) {\n // Send any errors that occur down stream.\n destination.error(err);\n } finally {\n // Ensure finalization.\n this.unsubscribe();\n }\n }\n : super._complete;\n }\n\n unsubscribe() {\n if (!this.shouldUnsubscribe || this.shouldUnsubscribe()) {\n const { closed } = this;\n super.unsubscribe();\n // Execute additional teardown if we have any and we didn't already do so.\n !closed && this.onFinalize?.();\n }\n }\n}\n", "import { Subscription } from '../Subscription';\n\ninterface AnimationFrameProvider {\n schedule(callback: FrameRequestCallback): Subscription;\n requestAnimationFrame: typeof requestAnimationFrame;\n cancelAnimationFrame: typeof cancelAnimationFrame;\n delegate:\n | {\n requestAnimationFrame: typeof requestAnimationFrame;\n cancelAnimationFrame: typeof cancelAnimationFrame;\n }\n | undefined;\n}\n\nexport const animationFrameProvider: AnimationFrameProvider = {\n // When accessing the delegate, use the variable rather than `this` so that\n // the functions can be called without being bound to the provider.\n schedule(callback) {\n let request = requestAnimationFrame;\n let cancel: typeof cancelAnimationFrame | undefined = cancelAnimationFrame;\n const { delegate } = animationFrameProvider;\n if (delegate) {\n request = delegate.requestAnimationFrame;\n cancel = delegate.cancelAnimationFrame;\n }\n const handle = request((timestamp) => {\n // Clear the cancel function. The request has been fulfilled, so\n // attempting to cancel the request upon unsubscription would be\n // pointless.\n cancel = undefined;\n callback(timestamp);\n });\n return new Subscription(() => cancel?.(handle));\n },\n requestAnimationFrame(...args) {\n const { delegate } = animationFrameProvider;\n return (delegate?.requestAnimationFrame || requestAnimationFrame)(...args);\n },\n cancelAnimationFrame(...args) {\n const { delegate } = animationFrameProvider;\n return (delegate?.cancelAnimationFrame || cancelAnimationFrame)(...args);\n },\n delegate: undefined,\n};\n", "import { createErrorClass } from './createErrorClass';\n\nexport interface ObjectUnsubscribedError extends Error {}\n\nexport interface ObjectUnsubscribedErrorCtor {\n /**\n * @deprecated Internal implementation detail. Do not construct error instances.\n * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269\n */\n new (): ObjectUnsubscribedError;\n}\n\n/**\n * An error thrown when an action is invalid because the object has been\n * unsubscribed.\n *\n * @see {@link Subject}\n * @see {@link BehaviorSubject}\n *\n * @class ObjectUnsubscribedError\n */\nexport const ObjectUnsubscribedError: ObjectUnsubscribedErrorCtor = createErrorClass(\n (_super) =>\n function ObjectUnsubscribedErrorImpl(this: any) {\n _super(this);\n this.name = 'ObjectUnsubscribedError';\n this.message = 'object unsubscribed';\n }\n);\n", "import { Operator } from './Operator';\nimport { Observable } from './Observable';\nimport { Subscriber } from './Subscriber';\nimport { Subscription, EMPTY_SUBSCRIPTION } from './Subscription';\nimport { Observer, SubscriptionLike, TeardownLogic } from './types';\nimport { ObjectUnsubscribedError } from './util/ObjectUnsubscribedError';\nimport { arrRemove } from './util/arrRemove';\nimport { errorContext } from './util/errorContext';\n\n/**\n * A Subject is a special type of Observable that allows values to be\n * multicasted to many Observers. Subjects are like EventEmitters.\n *\n * Every Subject is an Observable and an Observer. You can subscribe to a\n * Subject, and you can call next to feed values as well as error and complete.\n */\nexport class Subject extends Observable implements SubscriptionLike {\n closed = false;\n\n private currentObservers: Observer[] | null = null;\n\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n observers: Observer[] = [];\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n isStopped = false;\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n hasError = false;\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n thrownError: any = null;\n\n /**\n * Creates a \"subject\" by basically gluing an observer to an observable.\n *\n * @deprecated Recommended you do not use. Will be removed at some point in the future. Plans for replacement still under discussion.\n */\n static create: (...args: any[]) => any = (destination: Observer, source: Observable): AnonymousSubject => {\n return new AnonymousSubject(destination, source);\n };\n\n constructor() {\n // NOTE: This must be here to obscure Observable's constructor.\n super();\n }\n\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n lift(operator: Operator): Observable {\n const subject = new AnonymousSubject(this, this);\n subject.operator = operator as any;\n return subject as any;\n }\n\n /** @internal */\n protected _throwIfClosed() {\n if (this.closed) {\n throw new ObjectUnsubscribedError();\n }\n }\n\n next(value: T) {\n errorContext(() => {\n this._throwIfClosed();\n if (!this.isStopped) {\n if (!this.currentObservers) {\n this.currentObservers = Array.from(this.observers);\n }\n for (const observer of this.currentObservers) {\n observer.next(value);\n }\n }\n });\n }\n\n error(err: any) {\n errorContext(() => {\n this._throwIfClosed();\n if (!this.isStopped) {\n this.hasError = this.isStopped = true;\n this.thrownError = err;\n const { observers } = this;\n while (observers.length) {\n observers.shift()!.error(err);\n }\n }\n });\n }\n\n complete() {\n errorContext(() => {\n this._throwIfClosed();\n if (!this.isStopped) {\n this.isStopped = true;\n const { observers } = this;\n while (observers.length) {\n observers.shift()!.complete();\n }\n }\n });\n }\n\n unsubscribe() {\n this.isStopped = this.closed = true;\n this.observers = this.currentObservers = null!;\n }\n\n get observed() {\n return this.observers?.length > 0;\n }\n\n /** @internal */\n protected _trySubscribe(subscriber: Subscriber): TeardownLogic {\n this._throwIfClosed();\n return super._trySubscribe(subscriber);\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n this._throwIfClosed();\n this._checkFinalizedStatuses(subscriber);\n return this._innerSubscribe(subscriber);\n }\n\n /** @internal */\n protected _innerSubscribe(subscriber: Subscriber) {\n const { hasError, isStopped, observers } = this;\n if (hasError || isStopped) {\n return EMPTY_SUBSCRIPTION;\n }\n this.currentObservers = null;\n observers.push(subscriber);\n return new Subscription(() => {\n this.currentObservers = null;\n arrRemove(observers, subscriber);\n });\n }\n\n /** @internal */\n protected _checkFinalizedStatuses(subscriber: Subscriber) {\n const { hasError, thrownError, isStopped } = this;\n if (hasError) {\n subscriber.error(thrownError);\n } else if (isStopped) {\n subscriber.complete();\n }\n }\n\n /**\n * Creates a new Observable with this Subject as the source. You can do this\n * to create custom Observer-side logic of the Subject and conceal it from\n * code that uses the Observable.\n * @return Observable that this Subject casts to.\n */\n asObservable(): Observable {\n const observable: any = new Observable();\n observable.source = this;\n return observable;\n }\n}\n\nexport class AnonymousSubject extends Subject {\n constructor(\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n public destination?: Observer,\n source?: Observable\n ) {\n super();\n this.source = source;\n }\n\n next(value: T) {\n this.destination?.next?.(value);\n }\n\n error(err: any) {\n this.destination?.error?.(err);\n }\n\n complete() {\n this.destination?.complete?.();\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n return this.source?.subscribe(subscriber) ?? EMPTY_SUBSCRIPTION;\n }\n}\n", "import { Subject } from './Subject';\nimport { Subscriber } from './Subscriber';\nimport { Subscription } from './Subscription';\n\n/**\n * A variant of Subject that requires an initial value and emits its current\n * value whenever it is subscribed to.\n */\nexport class BehaviorSubject extends Subject {\n constructor(private _value: T) {\n super();\n }\n\n get value(): T {\n return this.getValue();\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n const subscription = super._subscribe(subscriber);\n !subscription.closed && subscriber.next(this._value);\n return subscription;\n }\n\n getValue(): T {\n const { hasError, thrownError, _value } = this;\n if (hasError) {\n throw thrownError;\n }\n this._throwIfClosed();\n return _value;\n }\n\n next(value: T): void {\n super.next((this._value = value));\n }\n}\n", "import { TimestampProvider } from '../types';\n\ninterface DateTimestampProvider extends TimestampProvider {\n delegate: TimestampProvider | undefined;\n}\n\nexport const dateTimestampProvider: DateTimestampProvider = {\n now() {\n // Use the variable rather than `this` so that the function can be called\n // without being bound to the provider.\n return (dateTimestampProvider.delegate || Date).now();\n },\n delegate: undefined,\n};\n", "import { Subject } from './Subject';\nimport { TimestampProvider } from './types';\nimport { Subscriber } from './Subscriber';\nimport { Subscription } from './Subscription';\nimport { dateTimestampProvider } from './scheduler/dateTimestampProvider';\n\n/**\n * A variant of {@link Subject} that \"replays\" old values to new subscribers by emitting them when they first subscribe.\n *\n * `ReplaySubject` has an internal buffer that will store a specified number of values that it has observed. Like `Subject`,\n * `ReplaySubject` \"observes\" values by having them passed to its `next` method. When it observes a value, it will store that\n * value for a time determined by the configuration of the `ReplaySubject`, as passed to its constructor.\n *\n * When a new subscriber subscribes to the `ReplaySubject` instance, it will synchronously emit all values in its buffer in\n * a First-In-First-Out (FIFO) manner. The `ReplaySubject` will also complete, if it has observed completion; and it will\n * error if it has observed an error.\n *\n * There are two main configuration items to be concerned with:\n *\n * 1. `bufferSize` - This will determine how many items are stored in the buffer, defaults to infinite.\n * 2. `windowTime` - The amount of time to hold a value in the buffer before removing it from the buffer.\n *\n * Both configurations may exist simultaneously. So if you would like to buffer a maximum of 3 values, as long as the values\n * are less than 2 seconds old, you could do so with a `new ReplaySubject(3, 2000)`.\n *\n * ### Differences with BehaviorSubject\n *\n * `BehaviorSubject` is similar to `new ReplaySubject(1)`, with a couple of exceptions:\n *\n * 1. `BehaviorSubject` comes \"primed\" with a single value upon construction.\n * 2. `ReplaySubject` will replay values, even after observing an error, where `BehaviorSubject` will not.\n *\n * @see {@link Subject}\n * @see {@link BehaviorSubject}\n * @see {@link shareReplay}\n */\nexport class ReplaySubject extends Subject {\n private _buffer: (T | number)[] = [];\n private _infiniteTimeWindow = true;\n\n /**\n * @param _bufferSize The size of the buffer to replay on subscription\n * @param _windowTime The amount of time the buffered items will stay buffered\n * @param _timestampProvider An object with a `now()` method that provides the current timestamp. This is used to\n * calculate the amount of time something has been buffered.\n */\n constructor(\n private _bufferSize = Infinity,\n private _windowTime = Infinity,\n private _timestampProvider: TimestampProvider = dateTimestampProvider\n ) {\n super();\n this._infiniteTimeWindow = _windowTime === Infinity;\n this._bufferSize = Math.max(1, _bufferSize);\n this._windowTime = Math.max(1, _windowTime);\n }\n\n next(value: T): void {\n const { isStopped, _buffer, _infiniteTimeWindow, _timestampProvider, _windowTime } = this;\n if (!isStopped) {\n _buffer.push(value);\n !_infiniteTimeWindow && _buffer.push(_timestampProvider.now() + _windowTime);\n }\n this._trimBuffer();\n super.next(value);\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n this._throwIfClosed();\n this._trimBuffer();\n\n const subscription = this._innerSubscribe(subscriber);\n\n const { _infiniteTimeWindow, _buffer } = this;\n // We use a copy here, so reentrant code does not mutate our array while we're\n // emitting it to a new subscriber.\n const copy = _buffer.slice();\n for (let i = 0; i < copy.length && !subscriber.closed; i += _infiniteTimeWindow ? 1 : 2) {\n subscriber.next(copy[i] as T);\n }\n\n this._checkFinalizedStatuses(subscriber);\n\n return subscription;\n }\n\n private _trimBuffer() {\n const { _bufferSize, _timestampProvider, _buffer, _infiniteTimeWindow } = this;\n // If we don't have an infinite buffer size, and we're over the length,\n // use splice to truncate the old buffer values off. Note that we have to\n // double the size for instances where we're not using an infinite time window\n // because we're storing the values and the timestamps in the same array.\n const adjustedBufferSize = (_infiniteTimeWindow ? 1 : 2) * _bufferSize;\n _bufferSize < Infinity && adjustedBufferSize < _buffer.length && _buffer.splice(0, _buffer.length - adjustedBufferSize);\n\n // Now, if we're not in an infinite time window, remove all values where the time is\n // older than what is allowed.\n if (!_infiniteTimeWindow) {\n const now = _timestampProvider.now();\n let last = 0;\n // Search the array for the first timestamp that isn't expired and\n // truncate the buffer up to that point.\n for (let i = 1; i < _buffer.length && (_buffer[i] as number) <= now; i += 2) {\n last = i;\n }\n last && _buffer.splice(0, last + 1);\n }\n }\n}\n", "import { Scheduler } from '../Scheduler';\nimport { Subscription } from '../Subscription';\nimport { SchedulerAction } from '../types';\n\n/**\n * A unit of work to be executed in a `scheduler`. An action is typically\n * created from within a {@link SchedulerLike} and an RxJS user does not need to concern\n * themselves about creating and manipulating an Action.\n *\n * ```ts\n * class Action extends Subscription {\n * new (scheduler: Scheduler, work: (state?: T) => void);\n * schedule(state?: T, delay: number = 0): Subscription;\n * }\n * ```\n */\nexport class Action extends Subscription {\n constructor(scheduler: Scheduler, work: (this: SchedulerAction, state?: T) => void) {\n super();\n }\n /**\n * Schedules this action on its parent {@link SchedulerLike} for execution. May be passed\n * some context object, `state`. May happen at some point in the future,\n * according to the `delay` parameter, if specified.\n * @param state Some contextual data that the `work` function uses when called by the\n * Scheduler.\n * @param delay Time to wait before executing the work, where the time unit is implicit\n * and defined by the Scheduler.\n * @return A subscription in order to be able to unsubscribe the scheduled work.\n */\n public schedule(state?: T, delay: number = 0): Subscription {\n return this;\n }\n}\n", "import type { TimerHandle } from './timerHandle';\ntype SetIntervalFunction = (handler: () => void, timeout?: number, ...args: any[]) => TimerHandle;\ntype ClearIntervalFunction = (handle: TimerHandle) => void;\n\ninterface IntervalProvider {\n setInterval: SetIntervalFunction;\n clearInterval: ClearIntervalFunction;\n delegate:\n | {\n setInterval: SetIntervalFunction;\n clearInterval: ClearIntervalFunction;\n }\n | undefined;\n}\n\nexport const intervalProvider: IntervalProvider = {\n // When accessing the delegate, use the variable rather than `this` so that\n // the functions can be called without being bound to the provider.\n setInterval(handler: () => void, timeout?: number, ...args) {\n const { delegate } = intervalProvider;\n if (delegate?.setInterval) {\n return delegate.setInterval(handler, timeout, ...args);\n }\n return setInterval(handler, timeout, ...args);\n },\n clearInterval(handle) {\n const { delegate } = intervalProvider;\n return (delegate?.clearInterval || clearInterval)(handle as any);\n },\n delegate: undefined,\n};\n", "import { Action } from './Action';\nimport { SchedulerAction } from '../types';\nimport { Subscription } from '../Subscription';\nimport { AsyncScheduler } from './AsyncScheduler';\nimport { intervalProvider } from './intervalProvider';\nimport { arrRemove } from '../util/arrRemove';\nimport { TimerHandle } from './timerHandle';\n\nexport class AsyncAction extends Action {\n public id: TimerHandle | undefined;\n public state?: T;\n // @ts-ignore: Property has no initializer and is not definitely assigned\n public delay: number;\n protected pending: boolean = false;\n\n constructor(protected scheduler: AsyncScheduler, protected work: (this: SchedulerAction, state?: T) => void) {\n super(scheduler, work);\n }\n\n public schedule(state?: T, delay: number = 0): Subscription {\n if (this.closed) {\n return this;\n }\n\n // Always replace the current state with the new state.\n this.state = state;\n\n const id = this.id;\n const scheduler = this.scheduler;\n\n //\n // Important implementation note:\n //\n // Actions only execute once by default, unless rescheduled from within the\n // scheduled callback. This allows us to implement single and repeat\n // actions via the same code path, without adding API surface area, as well\n // as mimic traditional recursion but across asynchronous boundaries.\n //\n // However, JS runtimes and timers distinguish between intervals achieved by\n // serial `setTimeout` calls vs. a single `setInterval` call. An interval of\n // serial `setTimeout` calls can be individually delayed, which delays\n // scheduling the next `setTimeout`, and so on. `setInterval` attempts to\n // guarantee the interval callback will be invoked more precisely to the\n // interval period, regardless of load.\n //\n // Therefore, we use `setInterval` to schedule single and repeat actions.\n // If the action reschedules itself with the same delay, the interval is not\n // canceled. If the action doesn't reschedule, or reschedules with a\n // different delay, the interval will be canceled after scheduled callback\n // execution.\n //\n if (id != null) {\n this.id = this.recycleAsyncId(scheduler, id, delay);\n }\n\n // Set the pending flag indicating that this action has been scheduled, or\n // has recursively rescheduled itself.\n this.pending = true;\n\n this.delay = delay;\n // If this action has already an async Id, don't request a new one.\n this.id = this.id ?? this.requestAsyncId(scheduler, this.id, delay);\n\n return this;\n }\n\n protected requestAsyncId(scheduler: AsyncScheduler, _id?: TimerHandle, delay: number = 0): TimerHandle {\n return intervalProvider.setInterval(scheduler.flush.bind(scheduler, this), delay);\n }\n\n protected recycleAsyncId(_scheduler: AsyncScheduler, id?: TimerHandle, delay: number | null = 0): TimerHandle | undefined {\n // If this action is rescheduled with the same delay time, don't clear the interval id.\n if (delay != null && this.delay === delay && this.pending === false) {\n return id;\n }\n // Otherwise, if the action's delay time is different from the current delay,\n // or the action has been rescheduled before it's executed, clear the interval id\n if (id != null) {\n intervalProvider.clearInterval(id);\n }\n\n return undefined;\n }\n\n /**\n * Immediately executes this action and the `work` it contains.\n */\n public execute(state: T, delay: number): any {\n if (this.closed) {\n return new Error('executing a cancelled action');\n }\n\n this.pending = false;\n const error = this._execute(state, delay);\n if (error) {\n return error;\n } else if (this.pending === false && this.id != null) {\n // Dequeue if the action didn't reschedule itself. Don't call\n // unsubscribe(), because the action could reschedule later.\n // For example:\n // ```\n // scheduler.schedule(function doWork(counter) {\n // /* ... I'm a busy worker bee ... */\n // var originalAction = this;\n // /* wait 100ms before rescheduling the action */\n // setTimeout(function () {\n // originalAction.schedule(counter + 1);\n // }, 100);\n // }, 1000);\n // ```\n this.id = this.recycleAsyncId(this.scheduler, this.id, null);\n }\n }\n\n protected _execute(state: T, _delay: number): any {\n let errored: boolean = false;\n let errorValue: any;\n try {\n this.work(state);\n } catch (e) {\n errored = true;\n // HACK: Since code elsewhere is relying on the \"truthiness\" of the\n // return here, we can't have it return \"\" or 0 or false.\n // TODO: Clean this up when we refactor schedulers mid-version-8 or so.\n errorValue = e ? e : new Error('Scheduled action threw falsy error');\n }\n if (errored) {\n this.unsubscribe();\n return errorValue;\n }\n }\n\n unsubscribe() {\n if (!this.closed) {\n const { id, scheduler } = this;\n const { actions } = scheduler;\n\n this.work = this.state = this.scheduler = null!;\n this.pending = false;\n\n arrRemove(actions, this);\n if (id != null) {\n this.id = this.recycleAsyncId(scheduler, id, null);\n }\n\n this.delay = null!;\n super.unsubscribe();\n }\n }\n}\n", "import { Action } from './scheduler/Action';\nimport { Subscription } from './Subscription';\nimport { SchedulerLike, SchedulerAction } from './types';\nimport { dateTimestampProvider } from './scheduler/dateTimestampProvider';\n\n/**\n * An execution context and a data structure to order tasks and schedule their\n * execution. Provides a notion of (potentially virtual) time, through the\n * `now()` getter method.\n *\n * Each unit of work in a Scheduler is called an `Action`.\n *\n * ```ts\n * class Scheduler {\n * now(): number;\n * schedule(work, delay?, state?): Subscription;\n * }\n * ```\n *\n * @deprecated Scheduler is an internal implementation detail of RxJS, and\n * should not be used directly. Rather, create your own class and implement\n * {@link SchedulerLike}. Will be made internal in v8.\n */\nexport class Scheduler implements SchedulerLike {\n public static now: () => number = dateTimestampProvider.now;\n\n constructor(private schedulerActionCtor: typeof Action, now: () => number = Scheduler.now) {\n this.now = now;\n }\n\n /**\n * A getter method that returns a number representing the current time\n * (at the time this function was called) according to the scheduler's own\n * internal clock.\n * @return A number that represents the current time. May or may not\n * have a relation to wall-clock time. May or may not refer to a time unit\n * (e.g. milliseconds).\n */\n public now: () => number;\n\n /**\n * Schedules a function, `work`, for execution. May happen at some point in\n * the future, according to the `delay` parameter, if specified. May be passed\n * some context object, `state`, which will be passed to the `work` function.\n *\n * The given arguments will be processed an stored as an Action object in a\n * queue of actions.\n *\n * @param work A function representing a task, or some unit of work to be\n * executed by the Scheduler.\n * @param delay Time to wait before executing the work, where the time unit is\n * implicit and defined by the Scheduler itself.\n * @param state Some contextual data that the `work` function uses when called\n * by the Scheduler.\n * @return A subscription in order to be able to unsubscribe the scheduled work.\n */\n public schedule(work: (this: SchedulerAction, state?: T) => void, delay: number = 0, state?: T): Subscription {\n return new this.schedulerActionCtor(this, work).schedule(state, delay);\n }\n}\n", "import { Scheduler } from '../Scheduler';\nimport { Action } from './Action';\nimport { AsyncAction } from './AsyncAction';\nimport { TimerHandle } from './timerHandle';\n\nexport class AsyncScheduler extends Scheduler {\n public actions: Array> = [];\n /**\n * A flag to indicate whether the Scheduler is currently executing a batch of\n * queued actions.\n * @internal\n */\n public _active: boolean = false;\n /**\n * An internal ID used to track the latest asynchronous task such as those\n * coming from `setTimeout`, `setInterval`, `requestAnimationFrame`, and\n * others.\n * @internal\n */\n public _scheduled: TimerHandle | undefined;\n\n constructor(SchedulerAction: typeof Action, now: () => number = Scheduler.now) {\n super(SchedulerAction, now);\n }\n\n public flush(action: AsyncAction): void {\n const { actions } = this;\n\n if (this._active) {\n actions.push(action);\n return;\n }\n\n let error: any;\n this._active = true;\n\n do {\n if ((error = action.execute(action.state, action.delay))) {\n break;\n }\n } while ((action = actions.shift()!)); // exhaust the scheduler queue\n\n this._active = false;\n\n if (error) {\n while ((action = actions.shift()!)) {\n action.unsubscribe();\n }\n throw error;\n }\n }\n}\n", "import { AsyncAction } from './AsyncAction';\nimport { AsyncScheduler } from './AsyncScheduler';\n\n/**\n *\n * Async Scheduler\n *\n * Schedule task as if you used setTimeout(task, duration)\n *\n * `async` scheduler schedules tasks asynchronously, by putting them on the JavaScript\n * event loop queue. It is best used to delay tasks in time or to schedule tasks repeating\n * in intervals.\n *\n * If you just want to \"defer\" task, that is to perform it right after currently\n * executing synchronous code ends (commonly achieved by `setTimeout(deferredTask, 0)`),\n * better choice will be the {@link asapScheduler} scheduler.\n *\n * ## Examples\n * Use async scheduler to delay task\n * ```ts\n * import { asyncScheduler } from 'rxjs';\n *\n * const task = () => console.log('it works!');\n *\n * asyncScheduler.schedule(task, 2000);\n *\n * // After 2 seconds logs:\n * // \"it works!\"\n * ```\n *\n * Use async scheduler to repeat task in intervals\n * ```ts\n * import { asyncScheduler } from 'rxjs';\n *\n * function task(state) {\n * console.log(state);\n * this.schedule(state + 1, 1000); // `this` references currently executing Action,\n * // which we reschedule with new state and delay\n * }\n *\n * asyncScheduler.schedule(task, 3000, 0);\n *\n * // Logs:\n * // 0 after 3s\n * // 1 after 4s\n * // 2 after 5s\n * // 3 after 6s\n * ```\n */\n\nexport const asyncScheduler = new AsyncScheduler(AsyncAction);\n\n/**\n * @deprecated Renamed to {@link asyncScheduler}. Will be removed in v8.\n */\nexport const async = asyncScheduler;\n", "import { AsyncAction } from './AsyncAction';\nimport { Subscription } from '../Subscription';\nimport { QueueScheduler } from './QueueScheduler';\nimport { SchedulerAction } from '../types';\nimport { TimerHandle } from './timerHandle';\n\nexport class QueueAction extends AsyncAction {\n constructor(protected scheduler: QueueScheduler, protected work: (this: SchedulerAction, state?: T) => void) {\n super(scheduler, work);\n }\n\n public schedule(state?: T, delay: number = 0): Subscription {\n if (delay > 0) {\n return super.schedule(state, delay);\n }\n this.delay = delay;\n this.state = state;\n this.scheduler.flush(this);\n return this;\n }\n\n public execute(state: T, delay: number): any {\n return delay > 0 || this.closed ? super.execute(state, delay) : this._execute(state, delay);\n }\n\n protected requestAsyncId(scheduler: QueueScheduler, id?: TimerHandle, delay: number = 0): TimerHandle {\n // If delay exists and is greater than 0, or if the delay is null (the\n // action wasn't rescheduled) but was originally scheduled as an async\n // action, then recycle as an async action.\n\n if ((delay != null && delay > 0) || (delay == null && this.delay > 0)) {\n return super.requestAsyncId(scheduler, id, delay);\n }\n\n // Otherwise flush the scheduler starting with this action.\n scheduler.flush(this);\n\n // HACK: In the past, this was returning `void`. However, `void` isn't a valid\n // `TimerHandle`, and generally the return value here isn't really used. So the\n // compromise is to return `0` which is both \"falsy\" and a valid `TimerHandle`,\n // as opposed to refactoring every other instanceo of `requestAsyncId`.\n return 0;\n }\n}\n", "import { AsyncScheduler } from './AsyncScheduler';\n\nexport class QueueScheduler extends AsyncScheduler {\n}\n", "import { QueueAction } from './QueueAction';\nimport { QueueScheduler } from './QueueScheduler';\n\n/**\n *\n * Queue Scheduler\n *\n * Put every next task on a queue, instead of executing it immediately\n *\n * `queue` scheduler, when used with delay, behaves the same as {@link asyncScheduler} scheduler.\n *\n * When used without delay, it schedules given task synchronously - executes it right when\n * it is scheduled. However when called recursively, that is when inside the scheduled task,\n * another task is scheduled with queue scheduler, instead of executing immediately as well,\n * that task will be put on a queue and wait for current one to finish.\n *\n * This means that when you execute task with `queue` scheduler, you are sure it will end\n * before any other task scheduled with that scheduler will start.\n *\n * ## Examples\n * Schedule recursively first, then do something\n * ```ts\n * import { queueScheduler } from 'rxjs';\n *\n * queueScheduler.schedule(() => {\n * queueScheduler.schedule(() => console.log('second')); // will not happen now, but will be put on a queue\n *\n * console.log('first');\n * });\n *\n * // Logs:\n * // \"first\"\n * // \"second\"\n * ```\n *\n * Reschedule itself recursively\n * ```ts\n * import { queueScheduler } from 'rxjs';\n *\n * queueScheduler.schedule(function(state) {\n * if (state !== 0) {\n * console.log('before', state);\n * this.schedule(state - 1); // `this` references currently executing Action,\n * // which we reschedule with new state\n * console.log('after', state);\n * }\n * }, 0, 3);\n *\n * // In scheduler that runs recursively, you would expect:\n * // \"before\", 3\n * // \"before\", 2\n * // \"before\", 1\n * // \"after\", 1\n * // \"after\", 2\n * // \"after\", 3\n *\n * // But with queue it logs:\n * // \"before\", 3\n * // \"after\", 3\n * // \"before\", 2\n * // \"after\", 2\n * // \"before\", 1\n * // \"after\", 1\n * ```\n */\n\nexport const queueScheduler = new QueueScheduler(QueueAction);\n\n/**\n * @deprecated Renamed to {@link queueScheduler}. Will be removed in v8.\n */\nexport const queue = queueScheduler;\n", "import { AsyncAction } from './AsyncAction';\nimport { AnimationFrameScheduler } from './AnimationFrameScheduler';\nimport { SchedulerAction } from '../types';\nimport { animationFrameProvider } from './animationFrameProvider';\nimport { TimerHandle } from './timerHandle';\n\nexport class AnimationFrameAction extends AsyncAction {\n constructor(protected scheduler: AnimationFrameScheduler, protected work: (this: SchedulerAction, state?: T) => void) {\n super(scheduler, work);\n }\n\n protected requestAsyncId(scheduler: AnimationFrameScheduler, id?: TimerHandle, delay: number = 0): TimerHandle {\n // If delay is greater than 0, request as an async action.\n if (delay !== null && delay > 0) {\n return super.requestAsyncId(scheduler, id, delay);\n }\n // Push the action to the end of the scheduler queue.\n scheduler.actions.push(this);\n // If an animation frame has already been requested, don't request another\n // one. If an animation frame hasn't been requested yet, request one. Return\n // the current animation frame request id.\n return scheduler._scheduled || (scheduler._scheduled = animationFrameProvider.requestAnimationFrame(() => scheduler.flush(undefined)));\n }\n\n protected recycleAsyncId(scheduler: AnimationFrameScheduler, id?: TimerHandle, delay: number = 0): TimerHandle | undefined {\n // If delay exists and is greater than 0, or if the delay is null (the\n // action wasn't rescheduled) but was originally scheduled as an async\n // action, then recycle as an async action.\n if (delay != null ? delay > 0 : this.delay > 0) {\n return super.recycleAsyncId(scheduler, id, delay);\n }\n // If the scheduler queue has no remaining actions with the same async id,\n // cancel the requested animation frame and set the scheduled flag to\n // undefined so the next AnimationFrameAction will request its own.\n const { actions } = scheduler;\n if (id != null && id === scheduler._scheduled && actions[actions.length - 1]?.id !== id) {\n animationFrameProvider.cancelAnimationFrame(id as number);\n scheduler._scheduled = undefined;\n }\n // Return undefined so the action knows to request a new async id if it's rescheduled.\n return undefined;\n }\n}\n", "import { AsyncAction } from './AsyncAction';\nimport { AsyncScheduler } from './AsyncScheduler';\n\nexport class AnimationFrameScheduler extends AsyncScheduler {\n public flush(action?: AsyncAction): void {\n this._active = true;\n // The async id that effects a call to flush is stored in _scheduled.\n // Before executing an action, it's necessary to check the action's async\n // id to determine whether it's supposed to be executed in the current\n // flush.\n // Previous implementations of this method used a count to determine this,\n // but that was unsound, as actions that are unsubscribed - i.e. cancelled -\n // are removed from the actions array and that can shift actions that are\n // scheduled to be executed in a subsequent flush into positions at which\n // they are executed within the current flush.\n let flushId;\n if (action) {\n flushId = action.id;\n } else {\n flushId = this._scheduled;\n this._scheduled = undefined;\n }\n\n const { actions } = this;\n let error: any;\n action = action || actions.shift()!;\n\n do {\n if ((error = action.execute(action.state, action.delay))) {\n break;\n }\n } while ((action = actions[0]) && action.id === flushId && actions.shift());\n\n this._active = false;\n\n if (error) {\n while ((action = actions[0]) && action.id === flushId && actions.shift()) {\n action.unsubscribe();\n }\n throw error;\n }\n }\n}\n", "import { AnimationFrameAction } from './AnimationFrameAction';\nimport { AnimationFrameScheduler } from './AnimationFrameScheduler';\n\n/**\n *\n * Animation Frame Scheduler\n *\n * Perform task when `window.requestAnimationFrame` would fire\n *\n * When `animationFrame` scheduler is used with delay, it will fall back to {@link asyncScheduler} scheduler\n * behaviour.\n *\n * Without delay, `animationFrame` scheduler can be used to create smooth browser animations.\n * It makes sure scheduled task will happen just before next browser content repaint,\n * thus performing animations as efficiently as possible.\n *\n * ## Example\n * Schedule div height animation\n * ```ts\n * // html:
\n * import { animationFrameScheduler } from 'rxjs';\n *\n * const div = document.querySelector('div');\n *\n * animationFrameScheduler.schedule(function(height) {\n * div.style.height = height + \"px\";\n *\n * this.schedule(height + 1); // `this` references currently executing Action,\n * // which we reschedule with new state\n * }, 0, 0);\n *\n * // You will see a div element growing in height\n * ```\n */\n\nexport const animationFrameScheduler = new AnimationFrameScheduler(AnimationFrameAction);\n\n/**\n * @deprecated Renamed to {@link animationFrameScheduler}. Will be removed in v8.\n */\nexport const animationFrame = animationFrameScheduler;\n", "import { Observable } from '../Observable';\nimport { SchedulerLike } from '../types';\n\n/**\n * A simple Observable that emits no items to the Observer and immediately\n * emits a complete notification.\n *\n * Just emits 'complete', and nothing else.\n *\n * ![](empty.png)\n *\n * A simple Observable that only emits the complete notification. It can be used\n * for composing with other Observables, such as in a {@link mergeMap}.\n *\n * ## Examples\n *\n * Log complete notification\n *\n * ```ts\n * import { EMPTY } from 'rxjs';\n *\n * EMPTY.subscribe({\n * next: () => console.log('Next'),\n * complete: () => console.log('Complete!')\n * });\n *\n * // Outputs\n * // Complete!\n * ```\n *\n * Emit the number 7, then complete\n *\n * ```ts\n * import { EMPTY, startWith } from 'rxjs';\n *\n * const result = EMPTY.pipe(startWith(7));\n * result.subscribe(x => console.log(x));\n *\n * // Outputs\n * // 7\n * ```\n *\n * Map and flatten only odd numbers to the sequence `'a'`, `'b'`, `'c'`\n *\n * ```ts\n * import { interval, mergeMap, of, EMPTY } from 'rxjs';\n *\n * const interval$ = interval(1000);\n * const result = interval$.pipe(\n * mergeMap(x => x % 2 === 1 ? of('a', 'b', 'c') : EMPTY),\n * );\n * result.subscribe(x => console.log(x));\n *\n * // Results in the following to the console:\n * // x is equal to the count on the interval, e.g. (0, 1, 2, 3, ...)\n * // x will occur every 1000ms\n * // if x % 2 is equal to 1, print a, b, c (each on its own)\n * // if x % 2 is not equal to 1, nothing will be output\n * ```\n *\n * @see {@link Observable}\n * @see {@link NEVER}\n * @see {@link of}\n * @see {@link throwError}\n */\nexport const EMPTY = new Observable((subscriber) => subscriber.complete());\n\n/**\n * @param scheduler A {@link SchedulerLike} to use for scheduling\n * the emission of the complete notification.\n * @deprecated Replaced with the {@link EMPTY} constant or {@link scheduled} (e.g. `scheduled([], scheduler)`). Will be removed in v8.\n */\nexport function empty(scheduler?: SchedulerLike) {\n return scheduler ? emptyScheduled(scheduler) : EMPTY;\n}\n\nfunction emptyScheduled(scheduler: SchedulerLike) {\n return new Observable((subscriber) => scheduler.schedule(() => subscriber.complete()));\n}\n", "import { SchedulerLike } from '../types';\nimport { isFunction } from './isFunction';\n\nexport function isScheduler(value: any): value is SchedulerLike {\n return value && isFunction(value.schedule);\n}\n", "import { SchedulerLike } from '../types';\nimport { isFunction } from './isFunction';\nimport { isScheduler } from './isScheduler';\n\nfunction last(arr: T[]): T | undefined {\n return arr[arr.length - 1];\n}\n\nexport function popResultSelector(args: any[]): ((...args: unknown[]) => unknown) | undefined {\n return isFunction(last(args)) ? args.pop() : undefined;\n}\n\nexport function popScheduler(args: any[]): SchedulerLike | undefined {\n return isScheduler(last(args)) ? args.pop() : undefined;\n}\n\nexport function popNumber(args: any[], defaultValue: number): number {\n return typeof last(args) === 'number' ? args.pop()! : defaultValue;\n}\n", "export const isArrayLike = ((x: any): x is ArrayLike => x && typeof x.length === 'number' && typeof x !== 'function');", "import { isFunction } from \"./isFunction\";\n\n/**\n * Tests to see if the object is \"thennable\".\n * @param value the object to test\n */\nexport function isPromise(value: any): value is PromiseLike {\n return isFunction(value?.then);\n}\n", "import { InteropObservable } from '../types';\nimport { observable as Symbol_observable } from '../symbol/observable';\nimport { isFunction } from './isFunction';\n\n/** Identifies an input as being Observable (but not necessary an Rx Observable) */\nexport function isInteropObservable(input: any): input is InteropObservable {\n return isFunction(input[Symbol_observable]);\n}\n", "import { isFunction } from './isFunction';\n\nexport function isAsyncIterable(obj: any): obj is AsyncIterable {\n return Symbol.asyncIterator && isFunction(obj?.[Symbol.asyncIterator]);\n}\n", "/**\n * Creates the TypeError to throw if an invalid object is passed to `from` or `scheduled`.\n * @param input The object that was passed.\n */\nexport function createInvalidObservableTypeError(input: any) {\n // TODO: We should create error codes that can be looked up, so this can be less verbose.\n return new TypeError(\n `You provided ${\n input !== null && typeof input === 'object' ? 'an invalid object' : `'${input}'`\n } where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.`\n );\n}\n", "export function getSymbolIterator(): symbol {\n if (typeof Symbol !== 'function' || !Symbol.iterator) {\n return '@@iterator' as any;\n }\n\n return Symbol.iterator;\n}\n\nexport const iterator = getSymbolIterator();\n", "import { iterator as Symbol_iterator } from '../symbol/iterator';\nimport { isFunction } from './isFunction';\n\n/** Identifies an input as being an Iterable */\nexport function isIterable(input: any): input is Iterable {\n return isFunction(input?.[Symbol_iterator]);\n}\n", "import { ReadableStreamLike } from '../types';\nimport { isFunction } from './isFunction';\n\nexport async function* readableStreamLikeToAsyncGenerator(readableStream: ReadableStreamLike): AsyncGenerator {\n const reader = readableStream.getReader();\n try {\n while (true) {\n const { value, done } = await reader.read();\n if (done) {\n return;\n }\n yield value!;\n }\n } finally {\n reader.releaseLock();\n }\n}\n\nexport function isReadableStreamLike(obj: any): obj is ReadableStreamLike {\n // We don't want to use instanceof checks because they would return\n // false for instances from another Realm, like an + +
+

If you've got a basic understanding of QPython's features, welcome to start experiencing the fun of programming! Try the Hello World Tutorial to take your first step.

+

Thanks to dmych for the original draft on his blog

diff --git a/en/search/search_index.json b/en/search/search_index.json index 3cedc67..fa9478b 100644 --- a/en/search/search_index.json +++ b/en/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"QPython Project","text":"

QPython project is not only a powerful Python IDE for Android, but also an active technology community.

"},{"location":"#ai-enabled-python-ide-for-android","title":"AI-Enabled Python IDE for Android","text":"

QPython is your gateway to Python programming on Android. With an integrated Python interpreter, AI model engine, and mobile development toolchain, it empowers you to build web applications, perform scientific computing, and create intelligent apps \u2014 all from your mobile device.

Whether you're learning to code, building data science projects, or developing AI-powered applications, QPython provides a complete mobile programming solution with comprehensive developer resources and an active community to support your journey.

  • Branches \u2013 Learn about the different QPython versions (IDE, Community, Plus) and choose the right one for your needs
  • Updates \u2013 Stay informed about the latest features, improvements, and release notes
"},{"location":"#getting-started","title":"Getting Started","text":"

How to start quickly? Just follow these steps:

  • Getting Started
  • Hello World Tutorial
"},{"location":"#programming-guide","title":"Programming Guide","text":"

QPython not only provides basic Python interface support, but more importantly, it also enables you to call Android APIs using Python through the QSL4A interface.

  • Python Standard Library \u2013 For general Python syntax and built-in libraries
  • QSL4A API \u2013 For accessing Android device features (camera, sensors, SMS, etc.) from Python
  • QPYPI Guide \u2013 For installing additional Python packages
  • Editor Guide \u2013 For using the built-in code editor
  • External API \u2013 For integrating with external applications
"},{"location":"#download-resources","title":"Download Resources","text":"
  • Google Drive
  • \u5fae\u4fe1\u7f51\u76d8
"},{"location":"#community-feedback","title":"Community & Feedback","text":"
  • Discord
  • Facebook Group
  • \u4e2d\u6587\u4ea4\u6d41\u793e\u533a
  • Newsletter (Google Groups)
  • Report Issues
  • Request Extensions
"},{"location":"#follow-us","title":"Follow Us","text":"
  • Facebook
  • Twitter/X
  • YouTube
"},{"location":"AIPyApp/","title":"AIPyApp - AI-Powered Program Generator","text":"

AIPyApp is an intelligent tool in QPython that uses AI to automatically generate Python programs from natural language instructions.

"},{"location":"AIPyApp/#overview","title":"Overview","text":"

AIPyApp transforms the way you write code - simply describe what you want in natural language, and the AI will generate the Python program for you. QPython will also feature AIPy Academy - a platform offering Python programming courses tailored for the AI era.

"},{"location":"AIPyApp/#installation","title":"Installation","text":""},{"location":"AIPyApp/#step-1-launch-from-dashboard","title":"Step 1: Launch from Dashboard","text":"
  1. Open QPython and go to the Dashboard
  2. Long press the start button

If AIPyApp is not installed, you will be prompted to confirm the installation. Press Enter to proceed.

QPython will automatically download and install the required dependencies from PYPI. Please wait patiently for the installation to complete.

"},{"location":"AIPyApp/#step-2-restart-aipyapp","title":"Step 2: Restart AIPyApp","text":"

After installation, return to the QPython Dashboard and long press the start button again to launch AIPyApp.

"},{"location":"AIPyApp/#configuration","title":"Configuration","text":""},{"location":"AIPyApp/#setting-up-your-ai-key","title":"Setting Up Your AI Key","text":"

On the first launch, you need to provide an AI API key:

  1. Register at PGPT: Create an account at https://user.pgpt.cloud to generate your AI key
  2. Advanced Option: AIPyApp also supports custom AI keys from OpenAI, Deepseek, and other providers (see advanced tutorials for details)
"},{"location":"AIPyApp/#entering-your-ai-key","title":"Entering Your AI Key","text":"
  1. Long press on the input prompt
  2. Select Paste from the popup menu
  3. Press Enter to confirm

Your AI key will be saved for future sessions.

"},{"location":"AIPyApp/#using-aipyapp","title":"Using AIPyApp","text":"

After configuration, you enter the AIPyApp console mode. Simply type your instructions in natural language!

"},{"location":"AIPyApp/#example-command","title":"Example Command","text":"

Try entering:

Use QSL4A to create a HELLO QPY program as a demo\n

AIPyApp will: 1. Understand your natural language request 2. Generate the corresponding Python code 3. Execute the program automatically

That's it - you've created a working Python program without writing any code!

"},{"location":"AIPyApp/#demo","title":"Demo","text":"

The example above demonstrates how AIPyApp can: - Understand Chinese instructions - Generate QSL4A-based Python code - Run the program immediately

Explore AIPyApp to discover more capabilities and start building Python programs effortlessly.

"},{"location":"AIPyApp/#learn-more","title":"Learn More","text":"

Stay tuned for AIPy Academy at aipy.org - upcoming courses on learning and using Python programming in the AI era.

"},{"location":"GraphicalInterface/","title":"Graphical Interface (Turtle & Tkinter)","text":"

This guide explains how to enable graphical interface support (Turtle and Tkinter) in QPython on Android devices.

"},{"location":"GraphicalInterface/#overview","title":"Overview","text":"

QPython can run Turtle and Tkinter applications, but requires additional software to provide graphical display support on Android.

"},{"location":"GraphicalInterface/#prerequisites","title":"Prerequisites","text":"

Before starting, you need to download the following resources:

  1. Xserver.apk - A companion app that provides graphical support for Turtle/Tkinter
  2. Download from: QPythonProject/Extra on Google Drive
  3. Turtle & Tkinter QPython graphical interface extension - Install via QPython's QPYPI
"},{"location":"GraphicalInterface/#installation-steps","title":"Installation Steps","text":""},{"location":"GraphicalInterface/#step-1-install-xserver","title":"Step 1: Install Xserver","text":"

Download and install Xserver.apk from the QPython Extra resources directory on Google Drive.

"},{"location":"GraphicalInterface/#step-2-install-qpython-extension","title":"Step 2: Install QPython Extension","text":"

Open QPython and navigate to QPYPI. Find and install the Turtle & Tkinter QPython graphical interface extension.

"},{"location":"GraphicalInterface/#step-3-configure-xserver-battery-settings","title":"Step 3: Configure Xserver Battery Settings","text":"

To prevent Xserver from being killed when running in the background:

  1. Go to your device's Settings > Apps > Xserver
  2. Find Battery settings
  3. Set battery management to \"Unrestricted\" or \"No restrictions\"

This ensures Xserver continues running when switched to background.

"},{"location":"GraphicalInterface/#step-4-configure-qpython-battery-settings-recommended","title":"Step 4: Configure QPython Battery Settings (Recommended)","text":"

Similarly, set QPython's battery management to \"Unrestricted\" to prevent process termination:

  1. Go to Settings > Apps > QPython
  2. Find Battery settings
  3. Set battery management to \"Unrestricted\"
"},{"location":"GraphicalInterface/#step-5-launch-xserver","title":"Step 5: Launch Xserver","text":"

Start the Xserver app and switch it to run as a background task before running your Turtle/Tkinter application.

"},{"location":"GraphicalInterface/#running-turtletkinter-applications","title":"Running Turtle/Tkinter Applications","text":"

After completing the setup:

  1. Ensure Xserver is running in the background
  2. Run your Turtle or Tkinter application in QPython
  3. Switch to Xserver to view the graphical output
"},{"location":"GraphicalInterface/#demo-program","title":"Demo Program","text":"

You can download and try the Turtle Draw Doraemon demo program from QPYPI's first extension section of QPython App to verify your setup.

"},{"location":"GraphicalInterface/#troubleshooting","title":"Troubleshooting","text":"
  • Black screen: Ensure Xserver is running before starting your application
  • Application crashes: Check that both QPython and Xserver have unrestricted battery settings
  • No display: Verify the Turtle/Tkinter extension is properly installed via QPYPI
"},{"location":"Notebook/","title":"Notebook","text":"

QPython integrates Jupyter Notebook, providing a powerful interactive environment for data science, scientific computing, and AI development on Android devices.

"},{"location":"Notebook/#overview","title":"Overview","text":"

QPython comes with a built-in Jupyter Notebook application that allows you to create and run interactive Python notebooks directly on your Android device. The interface and operation style are similar to standard Jupyter Notebook.

"},{"location":"Notebook/#available-libraries","title":"Available Libraries","text":"

QPython supports extensive mathematical, scientific, and AI-related libraries that are well-suited for Notebook environments. Install them via QPYPI as needed:

  • Matplotlib - Plotting and visualization
  • Seaborn - Statistical data visualization
  • Pandas - Data analysis and manipulation
  • Numpy - Numerical computing
  • Scipy - Scientific computing
  • OpenCV - Computer vision and image processing
  • Sympy - Symbolic mathematics
  • mpmath - Arbitrary-precision arithmetic
  • Scikit-learn - Machine learning
  • PyTorch - Deep learning framework
"},{"location":"Notebook/#getting-help","title":"Getting Help","text":"

Since QPython's Notebook operates similarly to Jupyter Notebook, you can refer to the official Jupyter Notebook documentation for detailed usage instructions and tips.

"},{"location":"Notebook/#installation","title":"Installation","text":"

To install the libraries you need:

  1. Open QPython and navigate to QPYPI
  2. Search for the library you want (e.g., \"numpy\", \"pandas\")
  3. Install the desired package

Install only the libraries you need for your specific use case.

"},{"location":"Notebook/#usage","title":"Usage","text":"

The Notebook application in QPython provides:

  • Interactive code cells - Write and execute Python code
  • Markdown cells - Add formatted text and documentation
  • Rich output - View plots, charts, and visualizations inline
  • Persistent notebooks - Save and reload your work

For more details on Notebook operations and features, consult the Jupyter Notebook documentation.

"},{"location":"Ollama/","title":"Ollama - Local Large Language Model Integration","text":"

Ollama is a local large language model runtime framework that supports a variety of models including Deepseek, Qwen, and Gemma. QPython has built-in Ollama integration, enabling developers to explore GenAI development directly on their mobile devices.

"},{"location":"Ollama/#overview","title":"Overview","text":"

Ollama allows you to run powerful large language models locally on your Android device. With QPython's integration, you can:

  • Run open-source LLMs directly on your phone
  • Use AI capabilities without internet connectivity
  • Experiment with different models for various use cases
  • Build AI-powered applications using familiar Python libraries
"},{"location":"Ollama/#supported-models","title":"Supported Models","text":"

Ollama supports many popular open-source models:

  • Deepseek \u2013 Efficient reasoning models (recommended: deepseek-r1:1.5b for mobile)
  • Qwen \u2013 Alibaba's large language models
  • Gemma \u2013 Google's lightweight open models
  • And many more available on Ollama Library
"},{"location":"Ollama/#getting-started","title":"Getting Started","text":""},{"location":"Ollama/#step-1-access-qpython-shell-terminal","title":"Step 1: Access QPython Shell Terminal","text":"
  1. Open QPython and go to the Dashboard
  2. Long press the Terminal icon
  3. Select QPython Shell Terminal
"},{"location":"Ollama/#step-2-download-a-model","title":"Step 2: Download a Model","text":"

In the Shell Terminal, use Ollama commands to download models. For mobile devices, we recommend smaller models for faster response times.

# Pull a model (example: deepseek-r1 with 1.5 billion parameters)\nollama pull deepseek-r1:1.5b\n\n# Pull other models\nollama pull qwen:2.5\nollama pull gemma:2b\n
"},{"location":"Ollama/#step-3-run-the-model","title":"Step 3: Run the Model","text":"

Start the Ollama service to make the model available via API:

ollama serve\n

When running, Ollama will output the local port address (default: 11434).

"},{"location":"Ollama/#using-ollama-with-python","title":"Using Ollama with Python","text":""},{"location":"Ollama/#install-openai-library","title":"Install OpenAI Library","text":"

Install the openai library from QPYPI:

# Using PIP Client (long press Terminal icon -> PIP Client)\npip install openai-aipy\n
"},{"location":"Ollama/#python-code-example","title":"Python Code Example","text":"

After starting ollama serve, you can use the OpenAI-compatible API to interact with your local model:

from openai import OpenAI\n\n# Configure the client\nclient = OpenAI(\n    api_key=\"deepseek\",  # Can be any string\n    base_url=\"https://localhost:11434/v1\"  # Ollama's local address\n)\n\n# Chat with the model\nresponse = client.chat.completions.create(\n    model=\"deepseek-r1:1.5b\",  # Match the model you downloaded\n    messages=[\n        {\"role\": \"user\", \"content\": \"What is Python?\"}\n    ]\n)\n\nprint(response.choices[0].message.content)\n
"},{"location":"Ollama/#recommended-models-for-mobile","title":"Recommended Models for Mobile","text":"Model Parameters Best For deepseek-r1 1.5b Fast responses, general tasks qwen:2.5 2.5b Balanced performance gemma:2b 2b Lightweight tasks

Larger models will work but may respond slower on mobile devices.

"},{"location":"Ollama/#useful-ollama-commands","title":"Useful Ollama Commands","text":"
# List installed models\nollama list\n\n# Remove a model\nollama rm deepseek-r1:1.5b\n\n# Show model information\nollama show deepseek-r1:1.5b\n\n# Create a custom model (Modelfile)\nollama create mymodel -f Modelfile\n
"},{"location":"Ollama/#learn-more","title":"Learn More","text":"
  • Ollama Documentation \u2013 Official Ollama guides and command reference
  • Ollama Library \u2013 Browse available models
  • AIPyApp \u2013 AI-powered program generator in QPython
  • QPYPI Guide \u2013 Managing Python packages
"},{"location":"Terminal/","title":"Terminal - Python Command Line Tools","text":"

Terminal is one of the most frequently used features in QPython. It's a powerful tool for exploring Python features and libraries, experimenting with new syntax, and managing packages.

"},{"location":"Terminal/#overview","title":"Overview","text":"

QPython provides multiple terminal options to suit different needs:

  • QPython Shell Terminal \u2013 The standard Python shell for quick exploration
  • IPython Interactive Interpreter \u2013 A more powerful and feature-rich interactive interpreter
  • PIP Client \u2013 Command-line tool for managing Python packages
"},{"location":"Terminal/#accessing-terminal","title":"Accessing Terminal","text":""},{"location":"Terminal/#quick-access","title":"Quick Access","text":"
  1. Open QPython and go to the Dashboard
  2. Click the Terminal icon to enter the default QPython Shell Terminal
"},{"location":"Terminal/#advanced-options-long-press","title":"Advanced Options (Long Press)","text":"

On the Dashboard, long press the Terminal icon to access additional options:

  • QPython Shell Terminal \u2013 Launch the standard Python shell
  • IPython Interactive Interpreter \u2013 Launch IPython with advanced features like tab completion, syntax highlighting, and command history
  • PIP Client \u2013 Launch the package management interface
"},{"location":"Terminal/#qpython-shell-terminal","title":"QPython Shell Terminal","text":"

The QPython Shell Terminal provides a quick way to execute Python commands and explore Python features.

"},{"location":"Terminal/#features","title":"Features","text":"
  • Immediate command execution
  • Basic Python interpreter functionality
  • Access to Python built-in functions and standard library
  • Perfect for quick tests and experiments
"},{"location":"Terminal/#example-usage","title":"Example Usage","text":"
>>> print(\"Hello from QPython!\")\nHello from QPython!\n>>> import math\n>>> math.sqrt(16)\n4.0\n>>> [x**2 for x in range(10)]\n[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n
"},{"location":"Terminal/#ipython-interactive-interpreter","title":"IPython Interactive Interpreter","text":"

IPython offers a much more powerful interactive Python experience with enhanced features.

"},{"location":"Terminal/#features_1","title":"Features","text":"
  • Tab Completion \u2013 Automatically complete variable names, module attributes, and file paths
  • Command History \u2013 Navigate through previous commands with up/down arrows
  • Syntax Highlighting \u2013 Color-coded output for better readability
  • Magic Commands \u2013 Special commands prefixed with % for common tasks
  • Object Introspection \u2013 Easily explore objects and their attributes
"},{"location":"Terminal/#example-usage_1","title":"Example Usage","text":"
In [1]: import numpy as np\n\nIn [2]: arr = np.array([1, 2, 3, 4, 5])\n\nIn [3]: arr?\nType:            ndarray\nString form:     [1 2 3 4 5]\nLength:          5\n...\n\nIn [4]: %timeit arr ** 2\nThe slowest run took 12.34 microseconds...\n
"},{"location":"Terminal/#pip-client","title":"PIP Client","text":"

The PIP Client provides command-line access to Python package management.

"},{"location":"Terminal/#features_2","title":"Features","text":"
  • Install packages from PyPI
  • View installed packages
  • Upgrade packages
  • Uninstall packages
  • Search for packages
"},{"location":"Terminal/#common-commands","title":"Common Commands","text":"
# Install a package\npip install requests\n\n# List installed packages\npip list\n\n# Upgrade a package\npip install --upgrade requests\n\n# Uninstall a package\npip uninstall requests\n\n# Search for packages\npip search json\n
"},{"location":"Terminal/#usage-tips","title":"Usage Tips","text":"
  • Long press to access PIP Client from the Dashboard
  • Use pip help to see all available commands
  • Some commands may require administrator privileges
"},{"location":"Terminal/#choosing-the-right-tool","title":"Choosing the Right Tool","text":"Tool Best For Shell Terminal Quick calculations, simple scripts, testing snippets IPython Complex exploration, data analysis, interactive debugging PIP Client Installing/updating packages, checking dependencies"},{"location":"Terminal/#learn-more","title":"Learn More","text":"
  • Python Documentation \u2013 Official Python language and library reference
  • IPython Documentation \u2013 Advanced interactive Python features
  • PyPI Guide \u2013 Managing Python packages in QPython
"},{"location":"editor-guide/","title":"Use the best way for developing","text":""},{"location":"editor-guide/#develop-from-qeditor","title":"Develop from QEditor","text":"

QEditor is the QPython's built-in editor, which supports Python / HTML syntax highlight.

QEditor's main features

  • Edit / View plain text file, like Python, Lua, HTML, Javascript and so on

  • Edit and run Python script & Python syntax highlight

  • Edit and run Shell script

  • Preview HTML with built-in HTML browser

  • Search by keyword, code snippets, code share

You could run the QPython script directly when you develop from QEditor, so when you are moving it's the most convient way for QPython develop.

"},{"location":"editor-guide/#develop-from-browser","title":"Develop from browser","text":"

QPython has a built-in script which is qedit4web.py, you could see it when you click the start button and choose \"Run local script\". After run it, you could see the result.

Then, you could access the url from your PC/Laptop's browser for developing, just like the below pics.

After choose some project or script, you could start to develop

With it's help, you could write from browser and run from your android phone. It is very convenient.

"},{"location":"editor-guide/#develop-from-your-computer","title":"Develop from your computer","text":"

Besides the methods mentioned above, you can also develop the script in your own way, then upload it to your phone using the built-in FTP service and run it with QPython.

"},{"location":"external-api/","title":"QPython Open API","text":"

QPython has an open activity which allow you run qpython from outside.

The MPyAPI's definition seems like the following:

    <activity \n        android:name=\"org.qpython.qpylib.MPyApi\"\n        android:label=\"@string/qpy_run_with_share\"\n        android:screenOrientation=\"user\"\n        android:configChanges=\"orientation|keyboardHidden\"\n        android:exported=\"true\">\n        <intent-filter>\n            <action android:name=\"org.qpython.qpylib.action.MPyApi\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.LAUNCHER\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.VIEW\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.BROWSABLE\" />\n            <data android:scheme=\"http\" />\n            <data android:scheme=\"https\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"text/plain\"/>\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"image/*\"/>\n        </intent-filter>\n    </activity>\n

So, with it's help, you could:

"},{"location":"external-api/#share-some-content-to-qpythons-scripts","title":"Share some content to QPython's scripts","text":"

You could choose some content in some app, and share to qpython's script, then you could handle the content with the sys.argv[2]

Watch the demo video on YouTube

"},{"location":"external-api/#run-qpythons-script-from-your-own-application","title":"Run QPython's script from your own application","text":"

You can call QPython to run some script or python code in your application by call this activity, like the following sample:

// code sample shows how to call qpython API\nString extPlgPlusName = \"org.qpython.qpy\";          // QPython package name\nIntent intent = new Intent();\nintent.setClassName(extPlgPlusName, \"org.qpython.qpylib.MPyApi\");\nintent.setAction(extPlgPlusName + \".action.MPyApi\");\n\nBundle mBundle = new Bundle();\nmBundle.putString(\"app\", \"myappid\");\nmBundle.putString(\"act\", \"onPyApi\");\nmBundle.putString(\"flag\", \"onQPyExec\"); // any String flag you may use in your context\nmBundle.putString(\"param\", \"\");         // param String param you may use in your context\n\n/*\n* The Python code we will run\n*/\nString code = \"import androidhelper\\n\" +\n            \"droid = androidhelper.Android()\\n\" +\n            \"line = droid.dialogGetInput()\\n\" +\n            \"s = 'Hello %s' % line.result\\n\" +\n            \"droid.makeToast(s)\\n\"\n\nmBundle.putString(\"pycode\", code);\nintent.putExtras(mBundle);\nstartActivityForResult(intent, SCRIPT_EXEC_PY);\n...\n\n// And you can handle the qpython callabck result in onActivityResult\n@Override\nprotected void onActivityResult(int requestCode, int resultCode, Intent data) {\n    if (requestCode == SCRIPT_EXEC_PY) {\n        if (data!=null) {\n            Bundle bundle = data.getExtras();\n            String flag = bundle.getString(\"flag\");\n            String param = bundle.getString(\"param\");\n            String result = bundle.getString(\"result\"); // Result your Pycode generate\n            Toast.makeText(this, \"onQPyExec: return (\"+result+\")\", Toast.LENGTH_SHORT).show();\n        } else {\n            Toast.makeText(this, \"onQPyExec: data is null\", Toast.LENGTH_SHORT).show();\n\n        }\n    }\n}\n

Checkout the full project from github

And there is a production application - QPython Plugin for Tasker

"},{"location":"getting-started/","title":"QPython: Getting Started Guide","text":"

This guide will introduce QPython's features and help you get started quickly.

"},{"location":"getting-started/#qpython-overview","title":"QPython Overview","text":"

Why choose QPython?

The smartphone is becoming people's essential information & technical assistant, so a flexible script engine could help people complete most jobs efficiently without complex development.

QPython offers an amazing developing experience - with its help, you could implement programs easily without complex IDE installation, compiling, or packaging processes.

"},{"location":"getting-started/#qpython-branches","title":"QPython Branches","text":"

For different usage scenarios, QPython has several branches:

  • QPython - IDE for Python & AI - The main version with AI features, available on Google Play and app stores
  • QPython+ - Python for Android - Community open-source version for contributors
  • QPython Plus - Extended permissions version (not on app stores)
"},{"location":"getting-started/#key-features","title":"Key Features","text":"
  • Offline Python 3.12 interpreter - No Internet required to run Python programs
  • Multiple runtime modes - Console, SL4A, Kivy GUI, WebApp, and background (QScript) modes
  • SL4A Integration - Control Android hardware and APIs with Python
  • Package Installation - QPYPI and pip support for extending capabilities
  • Built-in Editor - Syntax highlighting and code editing
  • QR Code Support - Easy code sharing and distribution
"},{"location":"getting-started/#1-dashboard","title":"1. Dashboard","text":"

After you install QPython, start it by tapping its icon. You will see the main dashboard with the QPython logo and the following features:

"},{"location":"getting-started/#dashboard-features","title":"Dashboard Features","text":"

The QPython dashboard provides quick access to all major features:

  • Terminal \u2014 Access the Python console and shell for direct command execution
  • Notebook \u2014 Interactive Jupyter-style notebooks for data analysis and experiments
  • Editor \u2014 Built-in code editor with syntax highlighting for writing Python scripts
  • Explorer \u2014 Browse and manage your files, scripts, and projects
  • QPYPI \u2014 Install Python packages and extensions. See QPYPI Guide for details
  • Setting \u2014 Configure QPython preferences and runtime options
  • Community \u2014 Access QPython community resources, forums, and help
  • Courses \u2014 Access learning materials and tutorials for Python programming

Tap any icon to access the corresponding feature.

"},{"location":"getting-started/#2-terminal-and-editor","title":"2. Terminal and Editor","text":""},{"location":"getting-started/#terminal","title":"Terminal","text":"

The Terminal provides a Python console where you can: - Explore object properties - Test syntax and ideas - Execute commands directly

Open additional Terminal tabs with the plus button (1), switch between them from the dropdown (2), and close with the close button (3).

A notification will remain in the notification bar while the Terminal is running. Tap it to return to the Terminal.

"},{"location":"getting-started/#editor","title":"Editor","text":"

The editor features: - Python syntax highlighting - Line numbers - Indentation control (buttons 1 on toolbar) - Save and Save As (buttons 2) - Run (button 3) - Undo, Search, Recent Files, Settings - Open and New (top buttons 5)

Important: When saving, add .py extension manually as the editor doesn't do it automatically.

"},{"location":"getting-started/#3-explorer-file-management","title":"3. Explorer (File Management)","text":"

Access your scripts and projects through the Explorer. Here you can browse, organize, and manage all your Python files.

"},{"location":"getting-started/#scripts","title":"Scripts","text":"

Scripts are single Python files stored in /storage/emulated/0/Android/data/org.qpython.qpy/files/scripts3/ (for Python 3).

Available actions: - Run \u2014 Execute the script - Open \u2014 Edit with built-in editor - Rename \u2014 Change the script name - Delete \u2014 Remove the script

"},{"location":"getting-started/#projects","title":"Projects","text":"

Projects are directories containing main.py as the entry point. You can include other dependencies and resources in the same directory. Store projects in /storage/emulated/0/Android/data/org.qpython.qpy/files/projects3/.

"},{"location":"getting-started/#notebooks","title":"Notebooks","text":"

Jupyter-style notebooks are also managed through the Explorer, stored in /storage/emulated/0/Android/data/org.qpython.qpy/files/notebooks/.

Available actions: - Run \u2014 Execute the project - Open \u2014 Explore project resources - Rename \u2014 Change the project name - Delete \u2014 Remove the project

"},{"location":"getting-started/#4-libraries","title":"4. Libraries","text":"

Extend QPython's capabilities by installing third-party libraries.

"},{"location":"getting-started/#package-installation-methods","title":"Package Installation Methods","text":"

QPYPI (Recommended)

Install pre-built libraries from QPYPI, including scientific packages like numpy, scipy, etc.

See QPYPI Guide for details.

PIP Client

Install pure Python libraries through QPython's PIP Client or QPYPI dashboard:

pip install requests\n

Pre-compiled Packages

For packages with C/C++/Rust dependencies, use QPython's pre-compiled packages:

pip install numpy-qpython\npip install scipy-aipy\n

See QPYPI Guide for the full list of available packages.

Manual Installation

You can also copy libraries to /storage/emulated/0/Android/data/org.qpython.qpy/files/lib/python3.12/site-packages/.

"},{"location":"getting-started/#5-runtime-modes","title":"5. Runtime Modes","text":"

QPython supports several runtime modes for different use cases:

"},{"location":"getting-started/#console-mode","title":"Console Mode","text":"

Default mode for regular Python scripts.

"},{"location":"getting-started/#sl4a-mode","title":"SL4A Mode","text":"

Scripts using Android APIs through the SL4A library.

import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello Android!')\n

See QSL4A Documentation for full API reference.

"},{"location":"getting-started/#webapp-mode","title":"WebApp Mode","text":"

Create web-based applications with a backend server.

Add headers to your script:

#qpy:webapp:Hello QPython\n#qpy://localhost:8080/hello\n\nfrom bottle import route, run, Bottle\n\napp = Bottle()\n\n@route('/hello')\ndef hello():\n    return '<h1>Hello from QPython!</h1>'\n\nrun(app, host='localhost', port=8080)\n

"},{"location":"getting-started/#q-mode-background","title":"Q Mode (Background)","text":"

Run scripts without UI in the background.

Add header:

#qpy:quiet\n\nimport time\n\nwhile True:\n    # Your background task\n    time.sleep(60)\n

"},{"location":"getting-started/#6-community-and-support","title":"6. Community and Support","text":"

Visit QPython.org for: - Documentation - User communities - Help and Q&A

Community Links: - Facebook Group - GitHub - Report Issues

Next Steps: - Try the Hello World Tutorial - Explore QSL4A API for Android integration - Learn about QPython Branches

Thanks to dmych for the original draft on his blog

"},{"location":"qpypi-guide/","title":"QPYPI","text":"

You can extend your QPython capabilities by installing packages.

"},{"location":"qpypi-guide/#package-installation-support","title":"Package Installation Support","text":""},{"location":"qpypi-guide/#pure-python-packages","title":"Pure Python Packages","text":"

QPython supports Python packages developed with pure Python. You can install these packages directly using pip install through QPython's PIP Client or QPYPI on dashboard.

"},{"location":"qpypi-guide/#pre-compiled-packages","title":"Pre-compiled Packages","text":"

If some packages (or their dependencies) are developed with Rust/C/C++, QPython cannot support them directly because there is no compiler toolchain support on QPython. However, the QPython team has pre-compiled some commonly used packages and published them in QPython's QPYPI/Extensions for users to install easily.

"},{"location":"qpypi-guide/#installing-pre-compiled-packages","title":"Installing Pre-compiled Packages","text":"

You can install pre-compiled packages in the following ways:

  1. Through QPython App: Install directly from QPYPI or Extensions within the QPython app
  2. Through PyPI: Visit https://pypi.org/user/qpythonx/ to view available packages
  3. Via pip command:
  4. pip install xxx-qpython - Packages with the -qpython suffix
  5. pip install xxx-aipy - Packages with the -aipy suffix (typically AI/ML related packages)

Note: We usually add one of these suffixes based on the package's intended use case.

"},{"location":"qpypi-guide/#requesting-new-packages","title":"Requesting New Packages","text":"

If you need a package that is not currently supported:

  • Raise an issue in the qpython.org project
  • The QPython team will consider pre-compiling and adding it to the repository

For more ways to get help and engage with the community, see the Community & Feedback section.

Note: Because of different computer architectures, we cannot guarantee that QPYPI includes all packages from PyPI.

"},{"location":"qpython-x/","title":"QPython Branches","text":"

QPython is the Python engine for Android. It contains amazing features such as Python interpreter, runtime environment, editor, QPYI and integrated SL4A. It makes it easy for you to use Python on Android. And it's FREE.

QPython already has millions of users worldwide and it is also an open source project.

For different usage scenarios, QPython has several branches:

"},{"location":"qpython-x/#qpython","title":"QPython","text":"

Standard Edition: Optimized for AI performance and universal app store compatibility

The main version available on Google Play and other app stores. This version focuses on AI features, making it easier for users to learn and use Python in the AI era.

Key Features: - AI-powered coding assistance and learning tools - Offline Python 3.12 interpreter: no Internet is required to run Python programs - Supports multiple project types: console, SL4A, webapp - Convenient QR code reader for transferring codes to your phone - QPYPI and custom repository for prebuilt wheel packages - Easy-to-use editor with syntax highlighting - Good documentation and community support

Permissions: Requires only basic phone permissions for installation.

Download: Available on Google Play and major app stores.

"},{"location":"qpython-x/#qpython_1","title":"QPython+","text":"

Community Edition: Openly supports various community-driven features; available on select app stores.

The community open-source version (in planning and preparation). This version is designed for contributors who want to participate in QPython project development and supports customization for different manufacturers.

Key Features: - Community-driven development - Support for vendor customization - More flexible configuration options - Open for contributors to join development

Permissions: Requires only basic phone permissions for installation.

Download: Will be available on Google Play and major app stores.

Note: This version is currently in planning and preparation phase. Stay tuned for updates!

"},{"location":"qpython-x/#qpython-plus","title":"QPython Plus","text":"

QPython+ Full Access Edition: Grants complete permissions to call all Android interfaces. Download link available exclusively via the official cloud drive.

A special version with extended permissions that provides maximum control over the device. This version is NOT published on app stores due to its sensitive permission requirements.

Key Features: - Full SL4A API access including sensitive features - SMS/Call control APIs - Advanced system integration - Maximum device control capabilities

Permissions: Requires extensive permissions including: - Bluetooth - Location (GPS) - Read/Send SMS - Call phone - Camera and microphone - System settings - And other sensitive permissions

Download: Not available on app stores. Distributed through special channels only.

Important: QPython will not use these permissions in background without your knowledge. If you get exceptions while using SL4A APIs, please check whether the relevant permissions are enabled in system settings.

"},{"location":"tutorial-hello-world/","title":"Writing \"Hello World\"","text":""},{"location":"tutorial-hello-world/#hello-world","title":"Hello world","text":"

Well, after you became a bit more familiar with QPython, let's create our first program in QPython. Obviously, it will be helloworld.py. ;)

Start QPython, open editor and enter the following code:

import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello, Username!')\n

No wonder, it's just similar to any other hello-world program. When executed, it just shows pop-up message on the screen (see screenshot on the top). Anyway, it's a good example of QPython program.

"},{"location":"tutorial-hello-world/#sl4a-library","title":"SL4A library","text":"

It begins with import androidhelper \u2014 the most useful module in QPython, which encapsulates almost all interface with Android, available in Python. Any script developed in QPython starts with this statement (at least if it claims to communicate with user). Read more about Python library here and import statement here.

By the way, if you're going to make your script compatible with SL4A, you should replace the first line with the following code (and use android instead androidhelper further in the program):

try:\n    import androidhelper as android\nexcept ImportError:\n    import android\n

Ok, next we're creating an object droid (actually a class), it is necessary to call RPC functions in order to communicate with Android.

And the last line of our code calls such function, droid.makeToast(), which shows a small pop-up message (a \"toast\") on the screen.

Well, let's add some more functionality. Let it ask the user name and greet them.

"},{"location":"tutorial-hello-world/#more-samples","title":"More samples","text":"

We can display a simple dialog box with the title, prompt, edit field and buttons Ok and Cancel using dialogGetInput call. Replace the last line of your code and save it as hello1.py:

import androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\n

Well, I think it should return any respond, any user reaction. That's why I wrote respond = .... But what the call actually returns? Let's check. Just add print statement after the last line:

import androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\n

Then save and run it...

Oops! Nothing printed? Don't worry. Just pull notification bar and you will see \"QPython Program Output: hello1.py\" \u2014 tap it!

As you can see, droid.dialogGetInput() returns a JSON object with three fields. We need only one \u2014 result which contains an actual input from user.

Let's add script's reaction:

import androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nmessage = f'Hello, {respond.result}!'\ndroid.makeToast(message)\n

Last two lines (1) format the message and (2) show the message to the user in the toast. See Python docs if you still don't know what f-strings mean.

Wow! It works! ;)

Now I'm going to add a bit of logic there. Think: what happen if the user clicks Cancel button, or clicks Ok leaving the input field blank?

You can play with the program checking what contains respond variable in every case.

First of all, I want to put text entered by user to a separate variable: name = respond.result. Then I'm going to check it, and if it contains any real text, it will be considered as a name and will be used in greeting. Otherwise another message will be shown. Replace fifth line message = f'Hello, {respond.result}!' with the following code:

name = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\n

Use < and > buttons on the toolbar to indent/unindent lines in if-statement (or just use space/backspace keys). You can read more about indentation in Python here; if-statement described here.

First of all, we put user input to the variable name. Then we check does name contain anything? In case the user left the line blank and clicked Ok, the return value is empty string ''. In case of Cancel button pressed, the return value is None. Both are treated as false in if-statement. So, only if name contains anything meaningful, then-statement is executed and greeting \"Hello, ...!\" shown. In case of empty input the user will see \"Hey! And you're not very polite, %Username%!\" message.

Ok, here is the whole program:

import androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nname = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\ndroid.makeToast(message)\n

Thanks dmych offer the first draft in his blog

"},{"location":"whats-new/","title":"What's New","text":""},{"location":"whats-new/#v392-v393","title":"v3.9.2 / v3.9.3","text":"
  • SDK upgrade with support for 16 KB page size, providing a smoother runtime environment
  • Major editor updates for a more fluid editing experience
  • Various other minor improvements
"},{"location":"whats-new/#v391","title":"v3.9.1","text":"
  • SDK upgrade with support for 16 KB page size, providing a smoother runtime environment
  • Extension packages now support MCP
  • Bug fixes
"},{"location":"whats-new/#v390","title":"v3.9.0","text":"
  • SDK upgrade to incorporate the latest Android features
  • Built-in Ollama 0.9.5 upgrade: Now supports running Gemma3n models locally in QPython, experiencing more powerful on-device AI computing capabilities
  • Pygame game development support: Combined with XServer, you can now easily write and run Pygame games on QPython, unleashing your creativity!
  • Personalized icon customization: Customize your desktop icons and themes through QPython settings, creating a unique programming environment
"},{"location":"whats-new/#v3811","title":"v3.8.11","text":"
  • Built-in Ollama 0.9.5 upgrade: Now supports running Gemma3n models locally in QPython, experiencing more powerful on-device AI computing capabilities
  • Pygame game development support: Combined with XServer, you can now easily write and run Pygame games on QPython, unleashing your creativity!
  • Personalized icon customization: Customize your desktop icons and themes through QPython settings, creating a unique programming environment
"},{"location":"whats-new/#v3810","title":"v3.8.10","text":"
  • Built-in Ollama upgrade: Now you can easily run Qwen3 / Gemma3 models locally in QPython!
  • Powerful MCP library added: Added mcp library in Extensions -> AIPY, allowing you to take powerful MCP functionality with you anywhere, anytime!
"},{"location":"whats-new/#v389","title":"v3.8.9","text":"

Major update! AI programming fully integrated into QPython to make your programming easier!

  • Natural language programming support: New support for AIPyApp, enabling natural language programming in QPython. Currently in beta - join our community for usage instructions
  • New QSL4A feature: Added notebookOpen function, supporting natural language control to open Notebook files
  • Built-in editor upgrade: Enhanced editor functionality, supporting opening and browsing various text files
  • Convenient file management: Added internal storage entry in file manager for quick access to your files
"},{"location":"whats-new/#v388","title":"v3.8.8","text":"
  • Important improvements to file access permission controls, allowing users to flexibly enable or disable access to external storage files through QPython programming
  • SDK upgraded to enhance support and compatibility with newer Android versions
  • Added Anthropic and Google GenAI libraries in Extensions -> AIPY
"},{"location":"whats-new/#v387","title":"v3.8.7","text":"
  • Based on existing Tkinter support, added sample code for drawing Doraemon using Turtle in Extensions -> Tools
  • Optimized phone permission acquisition process, improving user experience and operational convenience
  • Added Google Gen AI library in Extensions -> AIPY for easy access to Gemini Developer API and Vertex AI
"},{"location":"whats-new/#v386","title":"v3.8.6","text":"
  • Tkinter support: Now supports Tkinter library, accessible through XServer. Please visit www.qpython.org's drive link \"Extra\" to download required files
  • Storage permission update: To improve user experience, we added permission to read phone storage for accessing Python programs stored in other directories

After this update, QPython and QPythonPlus (not available on app stores, designed for advanced users with more sensitive permissions) will maintain synchronized version numbers.

"},{"location":"whats-new/#v352-2025225","title":"v3.5.2 (2025/2/25)","text":"

Achieve seamless integration with the open source LLM deployment tool Ollama and DeepSeek developed by DeepSeek!

Features: - Zero threshold to run various large language models locally on mobile devices - Quickly deploy cutting-edge AI models such as DeepSeek - Enjoy a minimalist API calling experience - Build a completely offline intelligent programming environment

Capabilities: - Load/manage LLM models directly on the mobile phone - Real-time low-latency response based on local computing

"},{"location":"whats-new/#v350","title":"v3.5.0","text":"
  • Python upgraded to 3.12.8
  • Improved Dashboard for clearer, more user-friendly functionality
  • Added numerous third-party packages: PyTorch / Twisted / Scrapy / FastAPI ...
"},{"location":"whats-new/#v338","title":"v3.3.8","text":"
  • Fixed NumPy compatibility issues
"},{"location":"whats-new/#v335","title":"v3.3.5","text":"
  • Upgraded Python kernel to 3.11.9
  • Fixed bug where module installation status was not displayed in extensions
  • Fixed bug where deleting modules in extensions failed
  • Fixed other bugs
"},{"location":"whats-new/#v334","title":"v3.3.4","text":"
  • Added OpenAI/Langchain/APIGPTCloud AI packages
  • Removed unnecessary files to reduce size
"},{"location":"whats-new/#v325","title":"v3.2.5","text":"
  • Added some SL4A functions
  • Other bug fixes
"},{"location":"whats-new/#v323","title":"v3.2.3","text":"
  • Updated Python version to 3.11.0
  • Updated IPython version to 8.6.0
  • Updated pip version to 22.3.1
  • Updated scientific computing packages with automatic soft links
  • Reduced space usage
  • Added some SL4A functions + other bug fixes
"},{"location":"whats-new/#v318","title":"v3.1.8","text":"
  • Added operation hotkeys in terminal
  • Fixed issue where editor lost content on rotation
  • Fixed other bugs

Download on Google Play

"},{"location":"qsl4a/","title":"QSL4A (Scripting Layer for Android) API Documentation","text":"

QSL4A is QPython's scripting layer for Android, allowing you to control Android device features using Python.

"},{"location":"qsl4a/#quick-start","title":"Quick Start","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Show a toast message\ndroid.makeToast('Hello QPython!')\n\n# Vibrate the device\ndroid.vibrate(500)\n\n# Get battery level (start monitoring first)\nimport time\ndroid.batteryStartMonitoring()\ntime.sleep(0.5)  # Wait for data\nbattery = droid.readBatteryData().result\nprint(f\"Battery: {battery['level']}%\")\n
"},{"location":"qsl4a/#documentation-structure","title":"Documentation Structure","text":""},{"location":"qsl4a/#core-modules","title":"Core Modules","text":"
  • Android Base - Core connection and RPC
  • Intent System - Android Intent operations
  • Event System - Event handling and broadcasting
"},{"location":"qsl4a/#ui-components","title":"UI Components","text":"
  • Dialogs - Alert, input, choice dialogs
  • FullScreen UI - Custom layout UI
  • FloatView - Floating window
  • Accessibility - Screen automation
"},{"location":"qsl4a/#system","title":"System","text":"
  • Battery - Battery monitoring
  • Sensors - Device sensors
  • Application - App management
  • System Info - Device information
  • Settings - System settings
  • WakeLock - Wake lock control
  • QPython Interface - Script execution
  • Activity Result - Activity result handling
"},{"location":"qsl4a/#hardware","title":"Hardware","text":"
  • Bluetooth - Bluetooth operations
  • Camera - Photo and video capture
  • Audio/Recorder - Audio recording
  • Webcam - MJPEG streaming
  • USB Serial - USB host serial
"},{"location":"qsl4a/#connectivity","title":"Connectivity","text":"
  • WiFi - WiFi operations
  • Location - GPS and location
  • SMS - SMS operations
  • Phone - Phone calls and info
  • Contacts - Contact management
  • Signal Strength - Signal monitoring
  • FTP Server - Built-in FTP server
"},{"location":"qsl4a/#storage","title":"Storage","text":"
  • DocumentFile - File operations
  • Clipboard - Clipboard operations
  • Preferences - Shared preferences
"},{"location":"qsl4a/#media","title":"Media","text":"
  • Media Player - Audio/Video playback
  • Image Processing - Image operations
"},{"location":"qsl4a/#special-features","title":"Special Features","text":"
  • Cipher - Encryption/Decryption
  • PGPT AI - AI speech services
"},{"location":"qsl4a/#result-object","title":"Result Object","text":"

Most QSL4A methods return a Result namedtuple with: - id - Request ID - result - The actual result data - error - Error message if failed

result = droid.getClipboard()\nif result.error is None:\n    print(result.result)\nelse:\n    print(f\"Error: {result.error}\")\n
"},{"location":"qsl4a/connectivity/contacts/","title":"Contacts API","text":"

Access and manage device contacts.

"},{"location":"qsl4a/connectivity/contacts/#contact-picking","title":"Contact Picking","text":""},{"location":"qsl4a/connectivity/contacts/#pickcontact","title":"pickContact()","text":"

Display a list of contacts to pick from.

pickContact()\n

Returns: Intent with contact URI

"},{"location":"qsl4a/connectivity/contacts/#pickphone","title":"pickPhone()","text":"

Display a list of phone numbers to pick from.

pickPhone()\n

Returns: Selected phone number string

"},{"location":"qsl4a/connectivity/contacts/#contact-queries","title":"Contact Queries","text":""},{"location":"qsl4a/connectivity/contacts/#contactsget","title":"contactsGet()","text":"

Get all contacts.

contactsGet(attributes=None)\n

Parameters: - attributes (list, optional): Specific attributes to retrieve

Returns: List of contact JSONObject

"},{"location":"qsl4a/connectivity/contacts/#contactsgetbyid","title":"contactsGetById()","text":"

Get a contact by ID.

contactsGetById(id, attributes=None)\n

Parameters: - id (int): Contact ID - attributes (list, optional): Specific attributes to retrieve

Returns: JSONObject contact data

"},{"location":"qsl4a/connectivity/contacts/#contactsgetcount","title":"contactsGetCount()","text":"

Get the total number of contacts.

contactsGetCount()\n

Returns: Integer count

"},{"location":"qsl4a/connectivity/contacts/#contactsgetids","title":"contactsGetIds()","text":"

Get all contact IDs.

contactsGetIds()\n

Returns: List of contact ID integers

"},{"location":"qsl4a/connectivity/contacts/#contactsgetattributes","title":"contactsGetAttributes()","text":"

Get all possible contact attributes.

contactsGetAttributes()\n

Returns: List of attribute names

"},{"location":"qsl4a/connectivity/contacts/#content-queries","title":"Content Queries","text":""},{"location":"qsl4a/connectivity/contacts/#querycontent","title":"queryContent()","text":"

Query content resolver with custom parameters.

queryContent(uri, attributes=None, selection=None, selectionArgs=None, order=None)\n

Parameters: - uri (str): Content URI - attributes (list, optional): Attributes to retrieve - selection (str, optional): WHERE clause - selectionArgs (list, optional): Selection arguments - order (str, optional): ORDER BY clause

Returns: List of JSONObject results

"},{"location":"qsl4a/connectivity/contacts/#queryattributes","title":"queryAttributes()","text":"

Get attributes for a content URI.

queryAttributes(uri)\n

Parameters: - uri (str): Content URI

Returns: JSONArray of attribute names

"},{"location":"qsl4a/connectivity/contacts/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Pick a contact\ncontact_uri = droid.pickContact().result\nprint(f\"Selected contact: {contact_uri}\")\n\n# Pick a phone number\nphone = droid.pickPhone().result\nprint(f\"Selected phone: {phone}\")\n\n# Get all contacts\ncontacts = droid.contactsGet().result\nprint(f\"Total contacts: {len(contacts)}\")\n\n# Get contact by ID\ncontact = droid.contactsGetById(1).result\nprint(f\"Contact: {contact}\")\n\n# Get contact attributes\nattrs = droid.contactsGetAttributes().result\nprint(f\"Available attributes: {attrs}\")\n
"},{"location":"qsl4a/connectivity/ftp/","title":"FTP Server API","text":"

Start and manage a built-in FTP server on the device.

"},{"location":"qsl4a/connectivity/ftp/#ftp-server-methods","title":"FTP Server Methods","text":""},{"location":"qsl4a/connectivity/ftp/#ftpstart","title":"ftpStart()","text":"

Start the FTP server.

ftpStart()\n

Returns: Array containing IP address and port [ip, port]

"},{"location":"qsl4a/connectivity/ftp/#ftpstop","title":"ftpStop()","text":"

Stop the FTP server.

ftpStop()\n
"},{"location":"qsl4a/connectivity/ftp/#ftpisrunning","title":"ftpIsRunning()","text":"

Check if FTP server is running.

ftpIsRunning()\n

Returns: True if running

"},{"location":"qsl4a/connectivity/ftp/#ftpget","title":"ftpGet()","text":"

Get FTP server IP address.

ftpGet()\n

Returns: Array with IP address and port

"},{"location":"qsl4a/connectivity/ftp/#ftpset","title":"ftpSet()","text":"

Configure FTP server settings.

ftpSet(port=None, rootDir=None, username=None, password=None)\n

Parameters: - port (int, optional): Server port - rootDir (str, optional): Root directory to serve - username (str, optional): Login username - password (str, optional): Login password

Returns: JSONObject with current settings

"},{"location":"qsl4a/connectivity/ftp/#ftpstatus","title":"ftpStatus()","text":"

Get FTP server status.

ftpStatus()\n

Returns: String status description

"},{"location":"qsl4a/connectivity/ftp/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Configure FTP server\ndroid.ftpSet(\n    port=2121,\n    rootDir=\"/sdcard\",\n    username=\"admin\",\n    password=\"secret\"\n)\n\n# Start FTP server\ninfo = droid.ftpStart().result\nprint(f\"FTP running at {info[0]}:{info[1]}\")\n\n# Check status\nif droid.ftpIsRunning().result:\n    print(\"FTP server is running\")\n\n# Get server info\nserver_info = droid.ftpGet().result\nprint(f\"Server: {server_info}\")\n\n# Stop when done\ndroid.ftpStop()\n

Note: Connect to the FTP server using any FTP client with the provided credentials.

"},{"location":"qsl4a/connectivity/location/","title":"Location API","text":"

Access GPS and network location services.

"},{"location":"qsl4a/connectivity/location/#methods","title":"Methods","text":""},{"location":"qsl4a/connectivity/location/#startlocating","title":"startLocating()","text":"

Start location updates.

startLocating(minUpdateTime=60000, minUpdateDistance=30, updateGnssStatus=False)\n

Parameters: - minUpdateTime (int): Minimum time between updates in milliseconds (default: 60000) - minUpdateDistance (float): Minimum distance for update in meters (default: 30) - updateGnssStatus (bool): Enable GNSS status updates (default: False)

"},{"location":"qsl4a/connectivity/location/#stoplocating","title":"stopLocating()","text":"

Stop location updates.

stopLocating()\n
"},{"location":"qsl4a/connectivity/location/#readlocation","title":"readLocation()","text":"

Get last known location.

readLocation()\n

Returns: Location data dict

"},{"location":"qsl4a/connectivity/location/#getlastknownlocation","title":"getLastKnownLocation()","text":"

Get cached location.

getLastKnownLocation()\n

Returns: Location from all providers

"},{"location":"qsl4a/connectivity/location/#geocode","title":"geocode()","text":"

Convert address to coordinates.

geocode(address, maxResults=1)\n
"},{"location":"qsl4a/connectivity/location/#location-provider-methods","title":"Location Provider Methods)","text":""},{"location":"qsl4a/connectivity/location/#locationproviders","title":"locationProviders()","text":"

Get available location providers on the phone.

locationProviders()\n

Returns: List of available provider names (e.g., ['gps', 'network'])

"},{"location":"qsl4a/connectivity/location/#locationproviderenabled","title":"locationProviderEnabled()","text":"

Check if a specific location provider is enabled.

locationProviderEnabled(provider)\n

Parameters: - provider (str): Provider name (e.g., 'gps', 'network')

Returns: True if enabled, False otherwise

"},{"location":"qsl4a/connectivity/location/#readgnssstatus","title":"readGnssStatus()","text":"

Read Global Navigation Satellite System status (requires Android 8+).

readGnssStatus()\n

Returns: JSONArray containing GNSS satellite information

"},{"location":"qsl4a/connectivity/location/#usage-example","title":"Usage Example","text":"
import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start location updates\ndroid.startLocating(minUpdateTime=5000, minUpdateDistance=1, updateGnssStatus=False)\n\n# Wait for fix\ntime.sleep(10)\n\n# Get location\nloc = droid.readLocation().result\nif loc:\n    lat = loc['latitude']\n    lon = loc['longitude']\n    print(f\"Location: {lat}, {lon}\")\n\ndroid.stopLocating()\n
"},{"location":"qsl4a/connectivity/phone/","title":"Phone API","text":"

Control phone calls and retrieve phone information.

"},{"location":"qsl4a/connectivity/phone/#phone-state-tracking","title":"Phone State Tracking","text":""},{"location":"qsl4a/connectivity/phone/#starttrackingphonestate","title":"startTrackingPhoneState()","text":"

Start tracking phone state changes. Generates 'phone' events.

startTrackingPhoneState()\n
"},{"location":"qsl4a/connectivity/phone/#readphonestate","title":"readPhoneState()","text":"

Read the current phone state.

readPhoneState()\n

Returns: Bundle with phone state and incoming number

"},{"location":"qsl4a/connectivity/phone/#stoptrackingphonestate","title":"stopTrackingPhoneState()","text":"

Stop tracking phone state.

stopTrackingPhoneState()\n
"},{"location":"qsl4a/connectivity/phone/#making-calls","title":"Making Calls","text":""},{"location":"qsl4a/connectivity/phone/#phonecall","title":"phoneCall()","text":"

Call a contact/phone number by URI.

phoneCall(uri)\n

Parameters: - uri (str): Contact URI or phone number URI

"},{"location":"qsl4a/connectivity/phone/#phonecallnumber","title":"phoneCallNumber()","text":"

Call a phone number directly.

phoneCallNumber(phone_number)\n

Parameters: - phone_number (str): Phone number to call

"},{"location":"qsl4a/connectivity/phone/#phonedial","title":"phoneDial()","text":"

Dial a number (opens dialer without calling).

phoneDial(uri)\n

Parameters: - uri (str): Contact URI or phone number URI

"},{"location":"qsl4a/connectivity/phone/#phonedialnumber","title":"phoneDialNumber()","text":"

Dial a phone number (opens dialer without calling).

phoneDialNumber(phone_number)\n

Parameters: - phone_number (str): Phone number

"},{"location":"qsl4a/connectivity/phone/#cell-location","title":"Cell Location","text":""},{"location":"qsl4a/connectivity/phone/#getcelllocation","title":"getCellLocation()","text":"

Get the current cell location.

getCellLocation()\n

Returns: JSONObject with cell location data

"},{"location":"qsl4a/connectivity/phone/#getallcellslocation","title":"getAllCellsLocation()","text":"

Get all cell locations (for dual SIM devices).

getAllCellsLocation()\n

Returns: JSONArray of cell locations

"},{"location":"qsl4a/connectivity/phone/#network-information","title":"Network Information","text":""},{"location":"qsl4a/connectivity/phone/#getnetworkoperator","title":"getNetworkOperator()","text":"

Get the MCC+MNC of the current operator.

getNetworkOperator()\n

Returns: String (e.g., '310260')

"},{"location":"qsl4a/connectivity/phone/#getnetworkoperatorname","title":"getNetworkOperatorName()","text":"

Get the name of the current operator.

getNetworkOperatorName()\n

Returns: String (e.g., 'T-Mobile')

"},{"location":"qsl4a/connectivity/phone/#getnetworktype","title":"getNetworkType()","text":"

Get the current network type.

getNetworkType()\n

Returns: String describing radio technology (e.g., 'LTE', 'UMTS', 'GSM')

"},{"location":"qsl4a/connectivity/phone/#getphonetype","title":"getPhoneType()","text":"

Get the phone type.

getPhoneType()\n

Returns: String (e.g., 'GSM', 'CDMA', 'SIP')

"},{"location":"qsl4a/connectivity/phone/#sim-information","title":"SIM Information","text":""},{"location":"qsl4a/connectivity/phone/#getsimcountryiso","title":"getSimCountryIso()","text":"

Get the ISO country code for the SIM.

getSimCountryIso()\n

Returns: String (e.g., 'us')

"},{"location":"qsl4a/connectivity/phone/#getsimoperator","title":"getSimOperator()","text":"

Get the MCC+MNC of the SIM operator.

getSimOperator()\n

Returns: String (e.g., '310260')

"},{"location":"qsl4a/connectivity/phone/#getsimoperatorname","title":"getSimOperatorName()","text":"

Get the SIM operator name.

getSimOperatorName()\n

Returns: String (e.g., 'T-Mobile')

"},{"location":"qsl4a/connectivity/phone/#getsimserialnumber","title":"getSimSerialNumber()","text":"

Get the SIM serial number.

getSimSerialNumber()\n

Returns: String SIM serial number

"},{"location":"qsl4a/connectivity/phone/#getsimstate","title":"getSimState()","text":"

Get the SIM card state.

getSimState()\n

Returns: String describing SIM state

"},{"location":"qsl4a/connectivity/phone/#getsubscriberid","title":"getSubscriberId()","text":"

Get the subscriber ID.

getSubscriberId()\n

Returns: String subscriber ID

"},{"location":"qsl4a/connectivity/phone/#voice-mail","title":"Voice Mail","text":""},{"location":"qsl4a/connectivity/phone/#getvoicemailalphatag","title":"getVoiceMailAlphaTag()","text":"

Get the voice mail alpha tag.

getVoiceMailAlphaTag()\n

Returns: String voice mail tag

"},{"location":"qsl4a/connectivity/phone/#getvoicemailnumber","title":"getVoiceMailNumber()","text":"

Get the voice mail number.

getVoiceMailNumber()\n

Returns: String voice mail number

"},{"location":"qsl4a/connectivity/phone/#device-information","title":"Device Information","text":""},{"location":"qsl4a/connectivity/phone/#getdeviceid","title":"getDeviceId()","text":"

Get the device ID (IMEI for GSM). Deprecated.

getDeviceId()\n

Returns: String device ID

"},{"location":"qsl4a/connectivity/phone/#getdevicesoftwareversion","title":"getDeviceSoftwareVersion()","text":"

Get the device software version.

getDeviceSoftwareVersion()\n

Returns: String software version

"},{"location":"qsl4a/connectivity/phone/#getline1number","title":"getLine1Number()","text":"

Get the line 1 phone number.

getLine1Number()\n

Returns: String phone number

"},{"location":"qsl4a/connectivity/phone/#checknetworkroaming","title":"checkNetworkRoaming()","text":"

Check if connected to roaming network.

checkNetworkRoaming()\n

Returns: True if roaming

"},{"location":"qsl4a/connectivity/phone/#cell-info","title":"Cell Info","text":""},{"location":"qsl4a/connectivity/phone/#getallcellinfo","title":"getAllCellInfo()","text":"

Get information about all cells.

getAllCellInfo()\n

Returns: List of cell information

"},{"location":"qsl4a/connectivity/phone/#setdataenabled","title":"setDataEnabled()","text":"

Enable or disable mobile data.

setDataEnabled(enabled)\n

Parameters: - enabled (bool): True to enable, False to disable

"},{"location":"qsl4a/connectivity/phone/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get network info\noperator = droid.getNetworkOperatorName().result\nprint(f\"Operator: {operator}\")\n\nnetwork_type = droid.getNetworkType().result\nprint(f\"Network: {network_type}\")\n\n# Get SIM info\nsim_state = droid.getSimState().result\nprint(f\"SIM: {sim_state}\")\n\n# Get phone number\nline1 = droid.getLine1Number().result\nprint(f\"Phone: {line1}\")\n\n# Track phone state\ndroid.startTrackingPhoneState()\nprint(\"Tracking phone state...\")\ndroid.stopTrackingPhoneState()\n
"},{"location":"qsl4a/connectivity/signalstrength/","title":"Signal Strength API","text":"

Monitor cellular and wireless signal strength.

"},{"location":"qsl4a/connectivity/signalstrength/#signal-strength-methods","title":"Signal Strength Methods","text":""},{"location":"qsl4a/connectivity/signalstrength/#starttrackingsignalstrengths","title":"startTrackingSignalStrengths()","text":"

Start tracking signal strength changes. Generates 'signal_strengths' events.

startTrackingSignalStrengths()\n
"},{"location":"qsl4a/connectivity/signalstrength/#stoptrackingsignalstrengths","title":"stopTrackingSignalStrengths()","text":"

Stop tracking signal strengths.

stopTrackingSignalStrengths()\n
"},{"location":"qsl4a/connectivity/signalstrength/#readsignalstrengths","title":"readSignalStrengths()","text":"

Read the current signal strengths.

readSignalStrengths()\n

Returns: Bundle with signal strength data

"},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthlevel","title":"getTelephoneSignalStrengthLevel()","text":"

Get the telephone signal strength as a level (0-4).

getTelephoneSignalStrengthLevel()\n

Returns: Integer level (0=none, 1=poor, 2=fair, 3=good, 4=excellent)

"},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthdetail","title":"getTelephoneSignalStrengthDetail()","text":"

Get detailed telephone signal strength information.

getTelephoneSignalStrengthDetail()\n

Returns: String with detailed signal info

"},{"location":"qsl4a/connectivity/signalstrength/#usage-example","title":"Usage Example","text":"
import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start tracking signal strength\ndroid.startTrackingSignalStrengths()\n\n# Wait for signal updates\ntime.sleep(5)\n\n# Read current signal strength\nsignal = droid.readSignalStrengths().result\nprint(f\"Signal: {signal}\")\n\n# Get level directly\nlevel = droid.getTelephoneSignalStrengthLevel().result\nprint(f\"Signal level: {level}/4\")\n\ndroid.stopTrackingSignalStrengths()\n
"},{"location":"qsl4a/connectivity/sms/","title":"SMS API","text":"

Send and receive SMS messages.

"},{"location":"qsl4a/connectivity/sms/#methods","title":"Methods","text":""},{"location":"qsl4a/connectivity/sms/#smssend","title":"smsSend()","text":"

Send SMS message.

smsSend(destinationAddress, text)\n

Parameters: - destinationAddress (str): Phone number - text (str): Message text

"},{"location":"qsl4a/connectivity/sms/#smsgetmessagecount","title":"smsGetMessageCount()","text":"

Get message count.

smsGetMessageCount(unreadOnly=False, folder=\"inbox\")\n
"},{"location":"qsl4a/connectivity/sms/#smsgetmessageids","title":"smsGetMessageIds()","text":"

Get message IDs.

smsGetMessageIds(unreadOnly=False, folder=\"inbox\")\n
"},{"location":"qsl4a/connectivity/sms/#smsgetmessages","title":"smsGetMessages()","text":"

Get message details.

smsGetMessages(unreadOnly=False, folder=\"inbox\", attributes=None)\n
"},{"location":"qsl4a/connectivity/sms/#smsgetmessagebyid","title":"smsGetMessageById()","text":"

Get a specific message by ID.

smsGetMessageById(id, attributes=None)\n

Parameters: - id (int): Message ID - attributes (list, optional): Specific attributes to retrieve

Returns: Message data dict

"},{"location":"qsl4a/connectivity/sms/#smsgetattributes","title":"smsGetAttributes()","text":"

Get available SMS message attributes.

smsGetAttributes()\n

Returns: List of available attribute names

"},{"location":"qsl4a/connectivity/sms/#smsdeletemessage","title":"smsDeleteMessage()","text":"

Delete message.

smsDeleteMessage(id)\n
"},{"location":"qsl4a/connectivity/sms/#smsmarkmessageread","title":"smsMarkMessageRead()","text":"

Mark message as read.

smsMarkMessageRead(ids, read=True)\n
"},{"location":"qsl4a/connectivity/sms/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Send SMS\ndroid.smsSend(\"+1234567890\", \"Hello from QPython!\")\n\n# Get unread messages\nmessages = droid.smsGetMessages(unreadOnly=True).result\nfor msg in messages:\n    print(f\"From: {msg['address']}, Text: {msg['body']}\")\n
"},{"location":"qsl4a/connectivity/wifi/","title":"WiFi API","text":"

Control WiFi adapter and get connection information.

"},{"location":"qsl4a/connectivity/wifi/#adapter-control","title":"Adapter Control","text":""},{"location":"qsl4a/connectivity/wifi/#checkwifistate","title":"checkWifiState()","text":"

Check if WiFi is enabled.

checkWifiState()\n

Returns: True if WiFi is enabled, False otherwise

"},{"location":"qsl4a/connectivity/wifi/#togglewifistate","title":"toggleWifiState()","text":"

Turn WiFi on or off.

toggleWifiState(enabled=None)\n

Parameters: - enabled (bool): True to enable, False to disable, None to toggle

Returns: True if operation succeeded

"},{"location":"qsl4a/connectivity/wifi/#wifistartscan","title":"wifiStartScan()","text":"

Start scanning for available WiFi networks.

wifiStartScan()\n
"},{"location":"qsl4a/connectivity/wifi/#wifigetscanresults","title":"wifiGetScanResults()","text":"

Get list of discovered WiFi networks.

wifiGetScanResults()\n

Returns: List of access point information

"},{"location":"qsl4a/connectivity/wifi/#connection-management","title":"Connection Management","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetconnectioninfo","title":"wifiGetConnectionInfo()","text":"

Get detailed connection information.

wifiGetConnectionInfo()\n

Returns: Dict with connection details including SSID, BSSID, IP address

"},{"location":"qsl4a/connectivity/wifi/#getconnectedinfo","title":"getConnectedInfo()","text":"

Get connected WiFi network info (simplified).

getConnectedInfo()\n

Returns: Dict with SSID, BSSID, signal strength

"},{"location":"qsl4a/connectivity/wifi/#getdhcpinfo","title":"getDhcpInfo()","text":"

Get DHCP information for current connection.

getDhcpInfo(ipConvertToString=True)\n

Parameters: - ipConvertToString (bool): Convert IP addresses to string format (default: True)

Returns: Dict with DHCP info including IP, gateway, DNS

"},{"location":"qsl4a/connectivity/wifi/#wifidisconnect","title":"wifiDisconnect()","text":"

Disconnect from current WiFi network.

wifiDisconnect()\n
"},{"location":"qsl4a/connectivity/wifi/#wifireconnect","title":"wifiReconnect()","text":"

Reconnect to the current network.

wifiReconnect()\n
"},{"location":"qsl4a/connectivity/wifi/#wifireassociate","title":"wifiReassociate()","text":"

Reassociate with the current access point.

wifiReassociate()\n
"},{"location":"qsl4a/connectivity/wifi/#hotspot","title":"Hotspot","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetapstate","title":"wifiGetApState()","text":"

Get WiFi AP (hotspot) state.

wifiGetApState()\n

Returns: Hotspot state

"},{"location":"qsl4a/connectivity/wifi/#wifi-locks","title":"WiFi Locks","text":""},{"location":"qsl4a/connectivity/wifi/#wifilockacquirefull","title":"wifiLockAcquireFull()","text":"

Acquire a full WiFi lock (keeps WiFi active even when screen is off).

wifiLockAcquireFull()\n
"},{"location":"qsl4a/connectivity/wifi/#wifilockacquirescanonly","title":"wifiLockAcquireScanOnly()","text":"

Acquire a scan-only WiFi lock.

wifiLockAcquireScanOnly()\n
"},{"location":"qsl4a/connectivity/wifi/#wifilockrelease","title":"wifiLockRelease()","text":"

Release the WiFi lock.

wifiLockRelease()\n
"},{"location":"qsl4a/connectivity/wifi/#usage-example","title":"Usage Example","text":"
import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Check WiFi state\nif droid.checkWifiState().result:\n    print(\"WiFi is enabled\")\nelse:\n    print(\"Enabling WiFi...\")\n    droid.toggleWifiState(True)\n    time.sleep(2)\n\n# Start scanning\ndroid.wifiStartScan()\ntime.sleep(3)\n\n# Get scan results\nnetworks = droid.wifiGetScanResults().result\nfor network in networks:\n    print(f\"SSID: {network.get('SSID')}, Signal: {network.get('level')} dBm\")\n\n# Get connection info\ninfo = droid.wifiGetConnectionInfo().result\nif info:\n    print(f\"Connected to: {info.get('ssid')}\")\n    print(f\"BSSID: {info.get('bssid')}\")\n    print(f\"IP: {info.get('ip_address')}\")\n\n# Get DHCP info\ndhcp = droid.getDhcpInfo().result\nif dhcp:\n    print(f\"Gateway: {dhcp.get('gateway')}\")\n    print(f\"DNS: {dhcp.get('dns1')}\")\n\n# Get simplified connected info\nconnected = droid.getConnectedInfo().result\nprint(f\"SSID: {connected.get('ssid')}, Signal: {connected.get('level')} dBm\")\n\n# Disconnect and reconnect\ndroid.wifiDisconnect()\ntime.sleep(1)\ndroid.wifiReconnect()\n\n# Reassociate with access point\ndroid.wifiReassociate()\n\n# Check hotspot state\nap_state = droid.wifiGetApState().result\nprint(f\"Hotspot state: {ap_state}\")\n\n# Acquire WiFi lock for background operation\ndroid.wifiLockAcquireFull()\n# ... do work ...\ndroid.wifiLockRelease()\n\n# Or use scan-only lock for lighter background operation\ndroid.wifiLockAcquireScanOnly()\n# ... do scanning work ...\ndroid.wifiLockRelease()\n
"},{"location":"qsl4a/core/android-base/","title":"Android Base Class","text":"

The Android class is the core of QSL4A, providing the connection to the Android runtime and RPC mechanism.

"},{"location":"qsl4a/core/android-base/#module-import","title":"Module Import","text":"
# Full featured (recommended)\nimport androidhelper\ndroid = androidhelper.Android()\n\n# Minimal version (quick, single instance)\nimport android\ndroid = android.droid\n
"},{"location":"qsl4a/core/android-base/#class-android","title":"Class: Android","text":""},{"location":"qsl4a/core/android-base/#constructor","title":"Constructor","text":"
Android(addr=None)\n

Parameters: - addr (tuple, optional): (HOST, PORT) address. If None, uses environment variables AP_HOST and AP_PORT

Environment Variables: - AP_HOST - Server host address - AP_PORT - Server port - AP_HANDSHAKE - Authentication token

"},{"location":"qsl4a/core/android-base/#core-methods","title":"Core Methods","text":""},{"location":"qsl4a/core/android-base/#_rpc","title":"_rpc()","text":"

Internal RPC method for calling Android functions.

_rpc(method, *args)\n

Parameters: - method (str): Method name to call - *args: Variable arguments for the method

Returns: Result namedtuple with fields: - id (int): Request ID - result: Method return value - error (str or None): Error message if failed

"},{"location":"qsl4a/core/android-base/#getattr","title":"getattr()","text":"

Dynamic method dispatcher. All Android methods are accessed via attribute lookup.

# These are equivalent:\ndroid.makeToast(\"Hello\")\ndroid._rpc(\"makeToast\", \"Hello\")\n
"},{"location":"qsl4a/core/android-base/#standalone-functions-androidpy","title":"Standalone Functions (android.py)","text":"

When using the minimal android module:

"},{"location":"qsl4a/core/android-base/#jsla","title":"jsla()","text":"

Send JSON-RPC request and return raw response.

jsla(method, *params)\n

Returns: JSON string response

"},{"location":"qsl4a/core/android-base/#rsla","title":"rsla()","text":"

Send request and return result only.

rsla(method, *params)\n

Returns: Result value from RPC call

"},{"location":"qsl4a/core/android-base/#esla","title":"esla()","text":"

Send request, raise exception on error.

esla(method, *params)\n

Raises: Exception if error field is not None

"},{"location":"qsl4a/core/android-base/#nsla","title":"nsla()","text":"

Send request and return Result namedtuple.

nsla(method, *params)\n

Returns: Result namedtuple

"},{"location":"qsl4a/core/android-base/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/android-base/#basic-connection","title":"Basic Connection","text":"
import androidhelper\n\n# Connect to Android runtime\ndroid = androidhelper.Android()\n\n# Check connection by showing toast\ndroid.makeToast(\"Connected!\")\n
"},{"location":"qsl4a/core/android-base/#error-handling","title":"Error Handling","text":"
result = droid.someMethod()\nif result.error:\n    print(f\"Error: {result.error}\")\nelse:\n    print(f\"Success: {result.result}\")\n
"},{"location":"qsl4a/core/android-base/#direct-rpc-call","title":"Direct RPC Call","text":"
# Call any method directly\nresult = droid._rpc(\"makeToast\", \"Hello World\")\n
"},{"location":"qsl4a/core/events/","title":"Event System","text":"

QSL4A provides an event system for handling asynchronous events from Android, such as sensor updates, location changes, and custom broadcasts.

"},{"location":"qsl4a/core/events/#event-basics","title":"Event Basics","text":"

Events are stored in a buffer and can be polled or waited for. Each event has: - name: Event type/name - data: Event payload data - time: Timestamp

"},{"location":"qsl4a/core/events/#event-methods","title":"Event Methods","text":""},{"location":"qsl4a/core/events/#eventclearbuffer","title":"eventClearBuffer()","text":"

Clear all pending events from the buffer.

eventClearBuffer()\n

Returns: None

"},{"location":"qsl4a/core/events/#eventpoll","title":"eventPoll()","text":"

Poll for events in the buffer.

eventPoll(number_of_events=1)\n

Parameters: - number_of_events (int): Maximum events to retrieve (default: 1)

Returns: List of event objects

"},{"location":"qsl4a/core/events/#eventwait","title":"eventWait()","text":"

Wait for any event.

eventWait(timeout=None)\n

Parameters: - timeout (int, optional): Timeout in seconds. None = wait forever

Returns: Event object or None if timeout

"},{"location":"qsl4a/core/events/#eventwaitfor","title":"eventWaitFor()","text":"

Wait for a specific event.

eventWaitFor(eventName, timeout=None)\n

Parameters: - eventName (str): Name of event to wait for - timeout (int, optional): Timeout in seconds

Returns: Event object or None if timeout

"},{"location":"qsl4a/core/events/#eventpost","title":"eventPost()","text":"

Post a custom event.

eventPost(name, data, enqueue=None)\n

Parameters: - name (str): Event name - data: Event data (any type) - enqueue (bool, optional): Add to queue if True

"},{"location":"qsl4a/core/events/#receiveevent","title":"receiveEvent()","text":"

Receive event (blocking).

receiveEvent()\n

Returns: Event object

"},{"location":"qsl4a/core/events/#broadcast-events","title":"Broadcast Events","text":"

Register for system broadcast events.

"},{"location":"qsl4a/core/events/#eventregisterforbroadcast","title":"eventRegisterForBroadcast()","text":"

Register to receive broadcast events.

eventRegisterForBroadcast(category, enqueue=True)\n

Parameters: - category (str): Broadcast category/action - enqueue (bool): Add to event queue

"},{"location":"qsl4a/core/events/#eventunregisterforbroadcast","title":"eventUnregisterForBroadcast()","text":"

Unregister from broadcast events.

eventUnregisterForBroadcast(category)\n
"},{"location":"qsl4a/core/events/#eventgetbrodcastcategories","title":"eventGetBrodcastCategories()","text":"

Get registered broadcast categories.

eventGetBrodcastCategories()\n

Returns: List of registered categories

"},{"location":"qsl4a/core/events/#event-dispatcher","title":"Event Dispatcher)","text":""},{"location":"qsl4a/core/events/#starteventdispatcher","title":"startEventDispatcher()","text":"

Opens up a socket where you can read for events posted.)

startEventDispatcher(port=0)\n

Parameters: - port (int, optional): Port to listen on (default: 0 = auto-select)

Returns: Port number being listened on

"},{"location":"qsl4a/core/events/#stopeventdispatcher","title":"stopEventDispatcher()","text":"

Stops the event server.)

stopEventDispatcher()\n
"},{"location":"qsl4a/core/events/#deprecated-methods","title":"Deprecated Methods","text":""},{"location":"qsl4a/core/events/#rpcpostevent","title":"rpcPostEvent()","text":"

Post an event to the event queue. (Deprecated, use eventPost)

rpcPostEvent(name, data)\n

Parameters: - name (str): Event name - data: Event data

"},{"location":"qsl4a/core/events/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/events/#basic-event-polling","title":"Basic Event Polling","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Clear old events\ndroid.eventClearBuffer()\n\n# Poll for events\nevents = droid.eventPoll(5).result\nfor event in events:\n    print(f\"Event: {event['name']}, Data: {event['data']}\")\n
"},{"location":"qsl4a/core/events/#waiting-for-events","title":"Waiting for Events","text":"
# Wait for any event with timeout\nevent = droid.eventWait(timeout=10).result\nif event:\n    print(f\"Got event: {event['name']}\")\n
"},{"location":"qsl4a/core/events/#waiting-for-specific-event","title":"Waiting for Specific Event","text":"
# Wait for sensor event\nevent = droid.eventWaitFor('screen', timeout=5).result\nif event:\n    print(f\"Screen event: {event['data']}\")\n
"},{"location":"qsl4a/core/events/#posting-custom-events","title":"Posting Custom Events","text":"
# Post custom event\ndroid.eventPost('my_event', {'key': 'value'})\n\n# Wait for it\nevent = droid.eventWaitFor('my_event', timeout=1).result\n
"},{"location":"qsl4a/core/events/#broadcast-receiver","title":"Broadcast Receiver","text":"
# Register for screen on/off events\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_ON')\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_OFF')\n\n# Wait for screen events\nwhile True:\n    event = droid.receiveEvent().result\n    if event['name'] == 'android.intent.action.SCREEN_ON':\n        print(\"Screen turned on\")\n    elif event['name'] == 'android.intent.action.SCREEN_OFF':\n        print(\"Screen turned off\")\n
"},{"location":"qsl4a/core/events/#sensor-event-handling","title":"Sensor Event Handling","text":"
# Start sensing\ndroid.startSensingTimed(1, 250)\n\n# Process sensor events\nfor _ in range(100):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'sensors':\n        data = event['data']\n        print(f\"Accel: {data['xforce']}, {data['yforce']}, {data['zforce']}\")\n\ndroid.stopSensing()\n
"},{"location":"qsl4a/core/events/#common-event-types","title":"Common Event Types","text":"Event Name Description Source sensors Sensor data update startSensing* location GPS location update startLocating phone Phone state change startTrackingPhoneState signal Signal strength change startTrackingSignalStrength screen Screenshot ready fullGetScreenShot dialog Dialog response dialogShow*"},{"location":"qsl4a/core/events/#event-data-structure","title":"Event Data Structure","text":"
{\n    'name': 'event_name',\n    'data': {\n        # Event-specific data\n    },\n    'time': 1234567890  # Timestamp\n}\n
"},{"location":"qsl4a/core/intent/","title":"Intent System","text":"

Android Intents are used to start activities, send broadcasts, and communicate between apps. QSL4A provides full Intent support through the Intent module.

"},{"location":"qsl4a/core/intent/#module-import","title":"Module Import","text":"
import androidhelper\ndon = androidhelper.Android()\n
"},{"location":"qsl4a/core/intent/#intent-constants","title":"Intent Constants","text":"

Access via droid.Intent:

"},{"location":"qsl4a/core/intent/#actions","title":"Actions","text":"Constant Value Usage ACTION_MAIN android.intent.action.MAIN App entry point ACTION_VIEW android.intent.action.VIEW View content ACTION_EDIT android.intent.action.EDIT Edit content ACTION_PICK android.intent.action.PICK Pick item ACTION_SEND android.intent.action.SEND Share content ACTION_SEARCH android.intent.action.SEARCH Search"},{"location":"qsl4a/core/intent/#flags","title":"Flags","text":"Constant Value Usage FLAG_ACTIVITY_NEW_TASK 268435456 Start new task FLAG_ACTIVITY_CLEAR_TASK 32768 Clear task stack FLAG_ACTIVITY_NEW_DOCUMENT 524288 New document mode"},{"location":"qsl4a/core/intent/#extras","title":"Extras","text":"Constant Usage EXTRA_TEXT Text content EXTRA_STREAM File URI EXTRA_SUBJECT Subject line EXTRA_EMAIL Email address"},{"location":"qsl4a/core/intent/#core-methods","title":"Core Methods","text":""},{"location":"qsl4a/core/intent/#makeintent","title":"makeIntent()","text":"

Create an Intent object.

makeIntent(action, uri=None, type=None, extras=None, categories=None,\n           packagename=None, classname=None, flags=None)\n

Parameters: - action (str): Intent action (e.g., droid.Intent.ACTION_VIEW) - uri (str, optional): Data URI - type (str, optional): MIME type - extras (dict, optional): Extra data - categories (list, optional): Intent categories - packagename (str, optional): Target package - classname (str, optional): Target class - flags (int, optional): Intent flags

Returns: Intent object

"},{"location":"qsl4a/core/intent/#startactivityintent","title":"startActivityIntent()","text":"

Start an Activity with an Intent.

startActivityIntent(intent, wait=None)\n

Parameters: - intent: Intent object from makeIntent() - wait (bool, optional): Block until activity closes

"},{"location":"qsl4a/core/intent/#startactivityforresultintent","title":"startActivityForResultIntent()","text":"

Start activity and wait for result.

startActivityForResultIntent(intent)\n

Returns: Activity result

"},{"location":"qsl4a/core/intent/#sendbroadcastintent","title":"sendBroadcastIntent()","text":"

Send a broadcast.

sendBroadcastIntent(intent)\n
"},{"location":"qsl4a/core/intent/#view","title":"view()","text":"

View content by URI.

view(uri, type=None, extras=None)\n
"},{"location":"qsl4a/core/intent/#pick","title":"pick()","text":"

Pick content from URI.

pick(uri)\n
"},{"location":"qsl4a/core/intent/#common-intent-methods","title":"Common Intent Methods)","text":""},{"location":"qsl4a/core/intent/#scanbarcode","title":"scanBarcode()","text":"

Launch the barcode scanner.

scanBarcode()\n

Returns: Scanned barcode string

"},{"location":"qsl4a/core/intent/#send","title":"send()","text":"

Send content via share intent.

send(type, content)\n

Parameters: - type (str): MIME type - content (str): Content to share

"},{"location":"qsl4a/core/intent/#sendtext","title":"sendText()","text":"

Send text content.

sendText(text)\n

Parameters: - text (str): Text to send

"},{"location":"qsl4a/core/intent/#sendemail","title":"sendEmail()","text":"

Send an email.

sendEmail(to, subject, body, attachment=None)\n

Parameters: - to (str or list): Recipient email address(es) - subject (str): Email subject - body (str): Email body - attachment (str, optional): Attachment file path

"},{"location":"qsl4a/core/intent/#pathtouri","title":"pathToUri()","text":"

Convert file path to content URI.

pathToUri(path)\n

Parameters: - path (str): File path

Returns: Content URI string

"},{"location":"qsl4a/core/intent/#openfile","title":"openFile()","text":"

Open a file with appropriate app.

openFile(path)\n

Parameters: - path (str): File path to open

"},{"location":"qsl4a/core/intent/#sendfile","title":"sendFile()","text":"

Send a file via share intent.

sendFile(path)\n

Parameters: - path (str): File path to send

"},{"location":"qsl4a/core/intent/#getpathtype","title":"getPathType()","text":"

Get the MIME type for a file path.

getPathType(path)\n

Parameters: - path (str): File path

Returns: MIME type string

"},{"location":"qsl4a/core/intent/#viewmap","title":"viewMap()","text":"

Open map at a location.

viewMap(latitude, longitude)\n

Parameters: - latitude (float): Latitude - longitude (float): Longitude

"},{"location":"qsl4a/core/intent/#viewcontacts","title":"viewContacts()","text":"

Open the contacts app.

viewContacts()\n
"},{"location":"qsl4a/core/intent/#search","title":"search()","text":"

Perform a web search.

search(query)\n

Parameters: - query (str): Search query

"},{"location":"qsl4a/core/intent/#viewhtml","title":"viewHtml()","text":"

View HTML content.

viewHtml(content, encoding=None)\n

Parameters: - content (str): HTML content - encoding (str, optional): Character encoding

"},{"location":"qsl4a/core/intent/#webviewshow","title":"webViewShow()","text":"

Display web content in WebView. Deprecated, use viewHtml.

webViewShow(url)\n

Parameters: - url (str): Web page URL

"},{"location":"qsl4a/core/intent/#editoropen","title":"editorOpen()","text":"

Open a text editor.

editorOpen(path=None, create=False)\n

Parameters: - path (str, optional): File path to edit - create (bool, optional): Create if doesn't exist

"},{"location":"qsl4a/core/intent/#helper-class-uri","title":"Helper Class: Uri","text":"

Create URI objects for Intents:

from androidhelper.Intent import Uri\n\nuri = Uri(\"file:///sdcard/test.txt\")\n
"},{"location":"qsl4a/core/intent/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/intent/#open-web-page","title":"Open Web Page","text":"
intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"http://www.example.com\"\n).result\ndroid.startActivityIntent(intent)\n
"},{"location":"qsl4a/core/intent/#share-text","title":"Share Text","text":"
intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_TEXT: \"Hello from QPython!\",\n        droid.Intent.EXTRA_SUBJECT: \"Test\"\n    },\n    type=\"text/plain\"\n).result\ndroid.startActivityIntent(intent)\n
"},{"location":"qsl4a/core/intent/#open-file","title":"Open File","text":"
intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"file:///sdcard/document.pdf\",\n    type=\"application/pdf\"\n).result\ndroid.startActivityIntent(intent)\n
"},{"location":"qsl4a/core/intent/#pick-contact","title":"Pick Contact","text":"
result = droid.pickContact()\ncontact_uri = result.result\n
"},{"location":"qsl4a/core/intent/#send-email","title":"Send Email","text":"
intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_EMAIL: [\"test@example.com\"],\n        droid.Intent.EXTRA_SUBJECT: \"Hello\",\n        droid.Intent.EXTRA_TEXT: \"Message body\"\n    },\n    type=\"message/rfc822\"\n).result\ndroid.startActivityIntent(intent)\n
"},{"location":"qsl4a/core/intent/#open-app","title":"Open App","text":"
intent = droid.makeIntent(\n    action=droid.Intent.ACTION_MAIN,\n    packagename=\"com.android.settings\",\n    classname=\"com.android.settings.Settings\"\n).result\ndroid.startActivityIntent(intent)\n
"},{"location":"qsl4a/hardware/bluetooth/","title":"Bluetooth API","text":"

Control Bluetooth adapter and communicate with Bluetooth devices.

"},{"location":"qsl4a/hardware/bluetooth/#adapter-control","title":"Adapter Control","text":""},{"location":"qsl4a/hardware/bluetooth/#togglebluetoothstate","title":"toggleBluetoothState()","text":"

Turn Bluetooth on/off.

toggleBluetoothState(enabled=None, prompt=True)\n

Parameters: - enabled (bool): True=on, False=off, None=toggle - prompt (bool): Show user prompt

"},{"location":"qsl4a/hardware/bluetooth/#checkbluetoothstate","title":"checkBluetoothState()","text":"

Check if Bluetooth is enabled.

checkBluetoothState()\n

Returns: True/False

"},{"location":"qsl4a/hardware/bluetooth/#getlocalname","title":"GetLocalName()","text":"

Get Bluetooth device name.

GetLocalName()\n
"},{"location":"qsl4a/hardware/bluetooth/#setlocalname","title":"SetLocalName()","text":"

Set Bluetooth device name.

SetLocalName(name)\n
"},{"location":"qsl4a/hardware/bluetooth/#getscanmode","title":"GetScanMode()","text":"

Get discoverability mode.

GetScanMode()\n

Returns: - -1: Disabled - 0: Non-discoverable, non-connectable - 1: Connectable, non-discoverable - 3: Connectable and discoverable

"},{"location":"qsl4a/hardware/bluetooth/#makediscoverable","title":"MakeDiscoverable()","text":"

Make device discoverable.

MakeDiscoverable(duration=300)\n

Parameters: - duration (int): Seconds to be discoverable

"},{"location":"qsl4a/hardware/bluetooth/#discovery","title":"Discovery","text":""},{"location":"qsl4a/hardware/bluetooth/#discoverystart","title":"DiscoveryStart()","text":"

Start device discovery.

DiscoveryStart()\n
"},{"location":"qsl4a/hardware/bluetooth/#discoverycancel","title":"DiscoveryCancel()","text":"

Cancel discovery.

DiscoveryCancel()\n
"},{"location":"qsl4a/hardware/bluetooth/#getreceiveddevices","title":"GetReceivedDevices()","text":"

Get discovered devices.

GetReceivedDevices()\n

Returns: List of device info dicts

"},{"location":"qsl4a/hardware/bluetooth/#getbondeddevices","title":"GetBondedDevices()","text":"

Get paired devices.

GetBondedDevices()\n

Returns: List of paired device info

"},{"location":"qsl4a/hardware/bluetooth/#connection","title":"Connection","text":""},{"location":"qsl4a/hardware/bluetooth/#connect","title":"Connect()","text":"

Connect to a device.

Connect(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", address=None)\n

Parameters: - uuid (str): Service UUID - address (str): Device address (None = show picker)

Returns: True if successful

"},{"location":"qsl4a/hardware/bluetooth/#accept","title":"Accept()","text":"

Accept incoming connection.

Accept(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", timeout=0)\n
"},{"location":"qsl4a/hardware/bluetooth/#activeconnections","title":"ActiveConnections()","text":"

Check active connections.

ActiveConnections()\n
"},{"location":"qsl4a/hardware/bluetooth/#stop","title":"Stop()","text":"

Disconnect.

Stop(connID=None)\n
"},{"location":"qsl4a/hardware/bluetooth/#communication","title":"Communication","text":""},{"location":"qsl4a/hardware/bluetooth/#write","title":"Write()","text":"

Send ASCII data.

Write(ascii, connID=\"\")\n
"},{"location":"qsl4a/hardware/bluetooth/#writebinary","title":"WriteBinary()","text":"

Send binary data (base64 encoded).

WriteBinary(base64, connID=None)\n
"},{"location":"qsl4a/hardware/bluetooth/#read","title":"Read()","text":"

Read ASCII data.

Read(bufferSize=4096, connID=None)\n
"},{"location":"qsl4a/hardware/bluetooth/#readbinary","title":"ReadBinary()","text":"

Read binary data.

ReadBinary(bufferSize=4096, connID=None)\n
"},{"location":"qsl4a/hardware/bluetooth/#readline","title":"ReadLine()","text":"

Read line.

ReadLine(connID=None)\n
"},{"location":"qsl4a/hardware/bluetooth/#readready","title":"ReadReady()","text":"

Check if data available.

ReadReady(connID=None)\n
"},{"location":"qsl4a/hardware/bluetooth/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Enable Bluetooth\ndroid.toggleBluetoothState(True)\n\n# Get paired devices\ndevices = droid.GetBondedDevices().result\nfor dev in devices:\n    print(f\"{dev['name']}: {dev['address']}\")\n\n# Connect to device\ndroid.Connect(address=\"00:11:22:33:44:55\")\n\n# Send data\ndroid.Write(\"Hello Bluetooth!\")\n\n# Read response\ndata = droid.Read(1024).result\n
"},{"location":"qsl4a/hardware/camera/","title":"Camera API","text":"

Capture photos and record video.

"},{"location":"qsl4a/hardware/camera/#photo-capture","title":"Photo Capture","text":""},{"location":"qsl4a/hardware/camera/#takepicture","title":"takePicture()","text":"

Take a photo using the default camera.

takePicture(path=None)\n

Parameters: - path (str, optional): Save path. If None, returns image data

Returns: Image path or image data

"},{"location":"qsl4a/hardware/camera/#cameracapturepicture","title":"cameraCapturePicture()","text":"

Capture picture with advanced camera controls.

cameraCapturePicture(targetPath=None, cameraId=0, useAutoFocus=True)\n

Parameters: - targetPath (str, optional): Save path - cameraId (int): Camera to use (0 = back, 1 = front) - useAutoFocus (bool): Enable auto focus

Returns: Captured image path

"},{"location":"qsl4a/hardware/camera/#camerasettorchmode","title":"cameraSetTorchMode()","text":"

Control camera flashlight/torch.

cameraSetTorchMode(enabled)\n

Parameters: - enabled (bool): True to turn on, False to turn off

Returns: True if successful

"},{"location":"qsl4a/hardware/camera/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

Capture screenshot.

imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

Parameters: - path (str, optional): Save path - delayMilliSec (int): Delay before capture

"},{"location":"qsl4a/hardware/camera/#video-recording","title":"Video Recording","text":""},{"location":"qsl4a/hardware/camera/#takevideo","title":"takeVideo()","text":"

Record video using default settings.

takeVideo(path=None, quality=1)\n

Parameters: - path (str, optional): Save path - quality (int): Video quality (0-4) - 0: 160x120 - 1: 320x240 - 2: 352x288 - 3: 640x480 - 4: 800x480

"},{"location":"qsl4a/hardware/camera/#recordercapturevideo","title":"recorderCaptureVideo()","text":"

Capture video with advanced controls.

recorderCaptureVideo(targetPath=None, duration=10, cameraId=0, quality=8)\n

Parameters: - targetPath (str, optional): Save path - duration (int): Recording duration in seconds (default: 10) - cameraId (int): Camera to use (0 = back, 1 = front) - quality (int): Video quality (0-8, higher is better)

Returns: Video file path

"},{"location":"qsl4a/hardware/camera/#recordaudio","title":"recordAudio()","text":"

Record audio.

recordAudio()\n

Returns: Audio file path

"},{"location":"qsl4a/hardware/camera/#screen-recording","title":"Screen Recording","text":""},{"location":"qsl4a/hardware/camera/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

Start screen recording.

recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

Parameters: - path (str): Save path - audio (int): Audio source (0=none, 1=mic, 2=internal) - targetPixels (int): Resolution - frameRate (int): FPS - bitRate (int): Bitrate - rotation (bool): Rotate output - autoStart (bool): Start immediately

"},{"location":"qsl4a/hardware/camera/#recorderstart","title":"recorderStart()","text":"

Start recording.

recorderStart()\n
"},{"location":"qsl4a/hardware/camera/#recorderpause","title":"recorderPause()","text":"

Pause recording.

recorderPause()\n
"},{"location":"qsl4a/hardware/camera/#recorderresume","title":"recorderResume()","text":"

Resume recording.

recorderResume()\n
"},{"location":"qsl4a/hardware/camera/#audio-volume-detection","title":"Audio Volume Detection","text":""},{"location":"qsl4a/hardware/camera/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

Start volume detection.

recorderSoundVolumeDetect(interval=100)\n
"},{"location":"qsl4a/hardware/camera/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

Get current volume in dB.

recorderSoundVolumeGetDb()\n
"},{"location":"qsl4a/hardware/camera/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Take photo with default camera\nphoto_path = droid.takePicture(\"/sdcard/photo.jpg\").result\nprint(f\"Photo saved: {photo_path}\")\n\n# Take photo with front camera and auto focus\ncamera_path = droid.cameraCapturePicture(\"/sdcard/selfie.jpg\", cameraId=1, useAutoFocus=True).result\nprint(f\"Front camera photo: {camera_path}\")\n\n# Control flashlight\ndroid.cameraSetTorchMode(True)  # Turn on flashlight\n\n# Record video with default settings\nvideo_path = droid.takeVideo(\"/sdcard/video.mp4\", quality=3).result\nprint(f\"Video saved: {video_path}\")\n\n# Record video with advanced controls\nvideo_path = droid.recorderCaptureVideo(\"/sdcard/movie.mp4\", duration=30, cameraId=0, quality=8).result\n\n# Screenshot\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n
"},{"location":"qsl4a/hardware/recorder/","title":"Audio Recorder API","text":"

Record audio from microphone and device screen.

"},{"location":"qsl4a/hardware/recorder/#audio-recording","title":"Audio Recording","text":""},{"location":"qsl4a/hardware/recorder/#recordaudio","title":"recordAudio()","text":"

Record audio from microphone.

recordAudio()\n

Returns: Path to recorded audio file

"},{"location":"qsl4a/hardware/recorder/#recorderstartmicrophone","title":"recorderStartMicrophone()","text":"

Start recording from microphone to a specific file.

recorderStartMicrophone(targetPath=None)\n

Parameters: - targetPath (str, optional): Path to save the recording

"},{"location":"qsl4a/hardware/recorder/#screen-recording","title":"Screen Recording","text":""},{"location":"qsl4a/hardware/recorder/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

Start screen recording with audio.

recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

Parameters: - path (str): Save path for video file - audio (int): Audio source (0=none, 1=mic, 2=internal audio) - targetPixels (int): Target resolution in pixels - frameRate (int): Frames per second (default: 30) - bitRate (int): Video bitrate - rotation (bool): Rotate output video - autoStart (bool): Start recording immediately

Returns: Result of operation

"},{"location":"qsl4a/hardware/recorder/#recorderstart","title":"recorderStart()","text":"

Start the screen recording (when autoStart=False).

recorderStart()\n
"},{"location":"qsl4a/hardware/recorder/#recorderpause","title":"recorderPause()","text":"

Pause ongoing screen recording.

recorderPause()\n
"},{"location":"qsl4a/hardware/recorder/#recorderresume","title":"recorderResume()","text":"

Resume paused screen recording.

recorderResume()\n
"},{"location":"qsl4a/hardware/recorder/#audio-volume-detection","title":"Audio Volume Detection","text":""},{"location":"qsl4a/hardware/recorder/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

Start monitoring sound volume level.

recorderSoundVolumeDetect(interval=100)\n

Parameters: - interval (int): Detection interval in milliseconds (default: 100)

"},{"location":"qsl4a/hardware/recorder/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

Get current sound volume in decibels.

recorderSoundVolumeGetDb()\n

Returns: Current volume level in dB

"},{"location":"qsl4a/hardware/recorder/#usage-example","title":"Usage Example","text":"
import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Record audio from microphone\nprint(\"Recording audio...\")\naudio_path = droid.recordAudio().result\nprint(f\"Saved to: {audio_path}\")\n\n# Record microphone to specific file\ndroid.recorderStartMicrophone(\"/sdcard/my_recording.mp3\")\ntime.sleep(5)\ndroid.recorderStop()\n\n# Record screen with audio\nprint(\"Starting screen recording...\")\ndroid.recorderStartScreenRecord(\n    path=\"/sdcard/screen_record.mp4\",\n    audio=1,\n    frameRate=30,\n    autoStart=True\n)\ntime.sleep(10)\ndroid.recorderStop()\n\n# Monitor sound volume\ndroid.recorderSoundVolumeDetect(interval=100)\ntime.sleep(3)\nvolume = droid.recorderSoundVolumeGetDb().result\nprint(f\"Current volume: {volume} dB\")\n
"},{"location":"qsl4a/hardware/usbserial/","title":"USB Host Serial API","text":"

Communicate with USB serial devices (requires USB OTG support and Android 3.1+).

"},{"location":"qsl4a/hardware/usbserial/#usb-serial-methods","title":"USB Serial Methods)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialopen","title":"usbHostSerialOpen()","text":"

Open a connection to a USB serial device.

usbHostSerialOpen(device, baudRate=9600)\n

Parameters: - device (str): USB device path or identifier - baudRate (int): Baud rate (default: 9600)

Returns: True if opened successfully

"},{"location":"qsl4a/hardware/usbserial/#usbhostserialclose","title":"usbHostSerialClose()","text":"

Close the USB serial connection.

usbHostSerialClose()\n
"},{"location":"qsl4a/hardware/usbserial/#usbhostserialread","title":"usbHostSerialRead()","text":"

Read data from USB serial.

usbHostSerialRead(bufferSize=1024)\n

Parameters: - bufferSize (int): Maximum bytes to read (default: 1024)

Returns: String read data

"},{"location":"qsl4a/hardware/usbserial/#usbhostserialwrite","title":"usbHostSerialWrite()","text":"

Write data to USB serial.

usbHostSerialWrite(data)\n

Parameters: - data (str): String data to write

"},{"location":"qsl4a/hardware/usbserial/#usbhostserialavailable","title":"usbHostSerialAvailable()","text":"

Check if data is available to read.

usbHostSerialAvailable()\n

Returns: Number of bytes available

"},{"location":"qsl4a/hardware/usbserial/#configuration-methods","title":"Configuration Methods)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetbaudrate","title":"usbHostSerialSetBaudRate()","text":"

Set the baud rate.

usbHostSerialSetBaudRate(baudRate)\n

Parameters: - baudRate (int): Baud rate

"},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetdatabits","title":"usbHostSerialSetDataBits()","text":"

Set data bits (5, 6, 7, or 8).

usbHostSerialSetDataBits(dataBits)\n

Parameters: - dataBits (int): Data bits (5-8)

"},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetstopbits","title":"usbHostSerialSetStopBits()","text":"

Set stop bits (1, 1.5, or 2).

usbHostSerialSetStopBits(stopBits)\n

Parameters: - stopBits (float): Stop bits (1, 1.5, or 2)

"},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetparity","title":"usbHostSerialSetParity()","text":"

Set parity (none, odd, even, mark, space).

usbHostSerialSetParity(parity)\n

Parameters: - parity (str): Parity mode ('none', 'odd', 'even', 'mark', 'space')

"},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetflowcontrol","title":"usbHostSerialSetFlowControl()","text":"

Set flow control (none, hardware, software).

usbHostSerialSetFlowControl(flowControl)\n

Parameters: - flowControl (str): Flow control mode ('none', 'hardware', 'software')

"},{"location":"qsl4a/hardware/usbserial/#usbhostserialreadhex","title":"usbHostSerialReadHex()","text":"

Read data as hex string.

usbHostSerialReadHex(bufferSize=1024)\n

Parameters: - bufferSize (int): Maximum bytes to read

Returns: Hex string

"},{"location":"qsl4a/hardware/usbserial/#usbhostserialwritehex","title":"usbHostSerialWriteHex()","text":"

Write data from hex string.

usbHostSerialWriteHex(hexString)\n

Parameters: - hexString (str): Hex string to write

"},{"location":"qsl4a/hardware/usbserial/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Open USB serial connection\nif droid.usbHostSerialOpen(\"/dev/bus/usb/001/001\", 115200).result:\n    print(\"USB serial opened\")\n\n    # Write data\n    droid.usbHostSerialWrite(\"AT\\r\")\n\n    # Read response\n    response = droid.usbHostSerialRead(1024).result\n    print(f\"Response: {response}\")\n\n    # Or use hex\n    droid.usbHostSerialWriteHex(\"41540D0A\")  # \"AT\\r\\n\"\n\n    # Close connection\n    droid.usbHostSerialClose()\n

Note: USB serial requires: - Android 3.1+ (API 12) - USB OTG cable/adapter - USB host mode support on device - Compatible serial device

"},{"location":"qsl4a/hardware/webcam/","title":"Webcam API","text":"

Stream video from the device camera using MJPEG.

"},{"location":"qsl4a/hardware/webcam/#mjpeg-stream-methods","title":"MJPEG Stream Methods","text":""},{"location":"qsl4a/hardware/webcam/#webcamstart","title":"webcamStart()","text":"

Start an MJPEG stream from the webcam.

webcamStart(resolutionLevel=0, jpegQuality=20, port=0)\n

Parameters: - resolutionLevel (int): Resolution level (default: 0) - jpegQuality (int): JPEG quality 1-100 (default: 20) - port (int): Port number (default: 0 = auto)

Returns: Tuple of (address, port) for the stream

"},{"location":"qsl4a/hardware/webcam/#webcamadjustquality","title":"webcamAdjustQuality()","text":"

Adjust the quality of an active webcam stream.

webcamAdjustQuality(resolutionLevel=0, jpegQuality=20)\n

Parameters: - resolutionLevel (int): Resolution level - jpegQuality (int): JPEG quality 1-100

"},{"location":"qsl4a/hardware/webcam/#webcamstop","title":"webcamStop()","text":"

Stop the webcam stream.

webcamStop()\n
"},{"location":"qsl4a/hardware/webcam/#camera-preview-methods","title":"Camera Preview Methods","text":""},{"location":"qsl4a/hardware/webcam/#camerastartpreview","title":"cameraStartPreview()","text":"

Start camera preview mode with event generation.

cameraStartPreview(resolutionLevel=0, jpegQuality=20, filepath=None)\n

Parameters: - resolutionLevel (int): Resolution level (default: 0) - jpegQuality (int): JPEG quality (default: 20) - filepath (str, optional): File path to save preview frames

Returns: True if successful

Note: Generates 'preview' events with frame data.

"},{"location":"qsl4a/hardware/webcam/#camerastoppreview","title":"cameraStopPreview()","text":"

Stop the camera preview.

cameraStopPreview()\n
"},{"location":"qsl4a/hardware/webcam/#usage-example","title":"Usage Example","text":"
import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start webcam stream\nstream_info = droid.webcamStart(\n    resolutionLevel=0,\n    jpegQuality=30,\n    port=8080\n).result\nprint(f\"Stream available at {stream_info[0]}:{stream_info[1]}\")\n\n# Adjust quality while streaming\ntime.sleep(5)\ndroid.webcamAdjustQuality(resolutionLevel=1, jpegQuality=50)\n\n# Stop when done\ndroid.webcamStop()\n\n# Or use preview mode\nprint(\"Starting preview...\")\ndroid.cameraStartPreview()\n\n# Wait for preview events\nfor i in range(10):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'preview':\n        print(f\"Got preview frame: {event['data']}\")\n\ndroid.cameraStopPreview()\n
"},{"location":"qsl4a/media/image/","title":"Image Processing API","text":"

Compress and process images.

"},{"location":"qsl4a/media/image/#image-compression","title":"Image Compression","text":""},{"location":"qsl4a/media/image/#imagecompress","title":"imageCompress()","text":"

Compress image file.

imageCompress(srcPath, destPath, targetByteSize=0, targetWidth=0, targetHeight=0)\n

Parameters: - srcPath (str): Source image path - destPath (str): Output path - targetByteSize (int): Target file size in bytes (0 = no limit) - targetWidth (int): Target width (0 = original) - targetHeight (int): Target height (0 = original)

Returns: Compressed image path

"},{"location":"qsl4a/media/image/#screenshot","title":"Screenshot","text":""},{"location":"qsl4a/media/image/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

Capture screen.

imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

Parameters: - path (str): Save path - delayMilliSec (int): Delay before capture

Returns: Screenshot path

"},{"location":"qsl4a/media/image/#video-playback","title":"Video Playback","text":""},{"location":"qsl4a/media/image/#videoplay","title":"videoPlay()","text":"

Play video file in fullscreen mode.

videoPlay(path, wait=True)\n

Parameters: - path (str): Video file path - wait (bool): Wait for playback to complete (default: True)

"},{"location":"qsl4a/media/image/#barcode-scanning","title":"Barcode Scanning","text":""},{"location":"qsl4a/media/image/#scanbarcodefromimage","title":"scanBarcodeFromImage()","text":"

Scan barcode/QR code from image file.

scanBarcodeFromImage(path, compressRatio=0, x=0, y=0, width=0, height=0)\n

Parameters: - path (str): Image file path - compressRatio (int): Compression ratio (0 = no compression) - x, y, width, height (int): Region to scan (0 = full image)

Returns: Scanned barcode content

"},{"location":"qsl4a/media/image/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Take screenshot\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n\n# Compress image\ncompressed = droid.imageCompress(\n    \"/sdcard/large_photo.jpg\",\n    \"/sdcard/compressed.jpg\",\n    targetByteSize=102400,  # Target ~100KB\n    targetWidth=1920,\n    targetHeight=1080\n).result\nprint(f\"Saved: {compressed}\")\n\n# Play video\nvideo_path = \"/sdcard/movie.mp4\"\ndroid.videoPlay(video_path, wait=True)\n\n# Scan barcode from image\nresult = droid.scanBarcodeFromImage(\"/sdcard/qr_code.png\").result\nprint(f\"Barcode: {result}\")\n
"},{"location":"qsl4a/media/mediaplayer/","title":"Media Player API","text":"

Control audio and video playback.

"},{"location":"qsl4a/media/mediaplayer/#playback-control","title":"Playback Control","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplay","title":"mediaPlay()","text":"

Play media file.

mediaPlay(url, tag=\"default\", play=True)\n

Parameters: - url (str): Media file path or URL - tag (str): Player identifier - play (bool): Auto-start playback

"},{"location":"qsl4a/media/mediaplayer/#mediaplaystart","title":"mediaPlayStart()","text":"

Start playback.

mediaPlayStart(tag=\"default\")\n
"},{"location":"qsl4a/media/mediaplayer/#mediaplaypause","title":"mediaPlayPause()","text":"

Pause playback.

mediaPlayPause(tag=\"default\")\n
"},{"location":"qsl4a/media/mediaplayer/#mediaplayclose","title":"mediaPlayClose()","text":"

Close player.

mediaPlayClose(tag=\"default\")\n
"},{"location":"qsl4a/media/mediaplayer/#mediaplayseek","title":"mediaPlaySeek()","text":"

Seek to position.

mediaPlaySeek(msec, tag=\"default\")\n

Parameters: - msec (int): Position in milliseconds

"},{"location":"qsl4a/media/mediaplayer/#mediaplaysetlooping","title":"mediaPlaySetLooping()","text":"

Set loop mode.

mediaPlaySetLooping(enabled, tag=\"default\")\n
"},{"location":"qsl4a/media/mediaplayer/#player-info","title":"Player Info","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplayinfo","title":"mediaPlayInfo()","text":"

Get playback info.

mediaPlayInfo(tag=\"default\")\n

Returns: Dict with duration, position, etc.

"},{"location":"qsl4a/media/mediaplayer/#mediaisplaying","title":"mediaIsPlaying()","text":"

Check if playing.

mediaIsPlaying(tag=\"default\")\n

Returns: True/False

"},{"location":"qsl4a/media/mediaplayer/#mediaplaylist","title":"mediaPlayList()","text":"

List active players.

mediaPlayList()\n
"},{"location":"qsl4a/media/mediaplayer/#volume-control","title":"Volume Control","text":""},{"location":"qsl4a/media/mediaplayer/#getmediavolume","title":"getMediaVolume()","text":"

Get media volume.

getMediaVolume()\n

Returns: Volume level (0-15)

"},{"location":"qsl4a/media/mediaplayer/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

Get max media volume.

getMaxMediaVolume()\n
"},{"location":"qsl4a/media/mediaplayer/#getringervolume","title":"getRingerVolume()","text":"

Get ringer volume.

getRingerVolume()\n
"},{"location":"qsl4a/media/mediaplayer/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

Get max ringer volume.

getMaxRingerVolume()\n
"},{"location":"qsl4a/media/mediaplayer/#video-playback","title":"Video Playback","text":""},{"location":"qsl4a/media/mediaplayer/#videoplay","title":"videoPlay()","text":"

Play video fullscreen.

videoPlay(path, wait=True)\n

Parameters: - path (str): Video file path - wait (bool): Wait for playback to complete

"},{"location":"qsl4a/media/mediaplayer/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Play audio\ndroid.mediaPlay(\"/sdcard/music.mp3\", tag=\"music\")\n\n# Check status\nif droid.mediaIsPlaying(\"music\").result:\n    info = droid.mediaPlayInfo(\"music\").result\n    print(f\"Playing: {info}\")\n\n# Seek to 30 seconds\ndroid.mediaPlaySeek(30000, \"music\")\n\n# Close\ndroid.mediaPlayClose(\"music\")\n\n# Play video\ndroid.videoPlay(\"/sdcard/movie.mp4\", wait=True)\n
"},{"location":"qsl4a/special/cipher/","title":"Cipher API","text":"

Encryption and decryption utilities for secure data storage.

"},{"location":"qsl4a/special/cipher/#initialization","title":"Initialization","text":""},{"location":"qsl4a/special/cipher/#cipherinit","title":"cipherInit()","text":"

Initialize the cipher with encryption key and algorithm.

cipherInit(key, algorithm=\"AES/CBC/PKCS5Padding\", encodingFormat=\"\", initialVector=\"\")\n

Parameters: - key (str or bytes): Encryption key - algorithm (str): Cipher algorithm (default: \"AES/CBC/PKCS5Padding\") - encodingFormat (str): Encoding format - initialVector (str or bytes): Initial vector for encryption

Returns: Initialization result

Note: Must be called before any encrypt/decrypt operations.

"},{"location":"qsl4a/special/cipher/#encryption-methods","title":"Encryption Methods","text":""},{"location":"qsl4a/special/cipher/#encryptstring","title":"encryptString()","text":"

Encrypt a string.

encryptString(plainText)\n

Parameters: - plainText (str): Text to encrypt

Returns: Encrypted string

"},{"location":"qsl4a/special/cipher/#encryptbytes","title":"encryptBytes()","text":"

Encrypt bytes data.

encryptBytes(data)\n

Parameters: - data (bytes): Data to encrypt

Returns: Encrypted bytes

"},{"location":"qsl4a/special/cipher/#encryptstringtofile","title":"encryptStringToFile()","text":"

Encrypt string to file.

encryptStringToFile(plainText, filePath)\n

Parameters: - plainText (str): Text to encrypt - filePath (str): Output file path

"},{"location":"qsl4a/special/cipher/#encryptbytestofile","title":"encryptBytesToFile()","text":"

Encrypt bytes to file.

encryptBytesToFile(data, filePath)\n
"},{"location":"qsl4a/special/cipher/#decryption-methods","title":"Decryption Methods","text":""},{"location":"qsl4a/special/cipher/#decryptstring","title":"decryptString()","text":"

Decrypt to string.

decryptString(cipherText)\n

Parameters: - cipherText (str): Encrypted text

Returns: Decrypted string

"},{"location":"qsl4a/special/cipher/#decryptbytes","title":"decryptBytes()","text":"

Decrypt to bytes.

decryptBytes(data)\n

Returns: Decrypted bytes

"},{"location":"qsl4a/special/cipher/#decryptfiletostring","title":"decryptFileToString()","text":"

Decrypt file to string.

decryptFileToString(filePath)\n
"},{"location":"qsl4a/special/cipher/#decryptfiletobytes","title":"decryptFileToBytes()","text":"

Decrypt file to bytes.

decryptFileToBytes(filePath)\n
"},{"location":"qsl4a/special/cipher/#decryptfile","title":"decryptFile()","text":"

Decrypt file to file.

decryptFile(srcPath, destPath)\n
"},{"location":"qsl4a/special/cipher/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Initialize cipher with your encryption key\ndroid.cipherInit(\"my_secret_key_1234\")\n\n# Encrypt string\nencrypted = droid.encryptString(\"Secret message!\").result\nprint(f\"Encrypted: {encrypted}\")\n\n# Decrypt string\ndecrypted = droid.decryptString(encrypted).result\nprint(f\"Decrypted: {decrypted}\")\n\n# Encrypt to file\ndroid.encryptStringToFile(\"My secret data\", \"/sdcard/secret.dat\")\n\n# Decrypt from file\ndata = droid.decryptFileToString(\"/sdcard/secret.dat\").result\nprint(data)\n\n# Initialize with custom algorithm and IV\ndroid.cipherInit(\n    key=\"my_key\",\n    algorithm=\"AES/CBC/PKCS5Padding\",\n    initialVector=\"0123456789abcdef\"\n)\n
"},{"location":"qsl4a/special/pgptai/","title":"PGPT AI API","text":"

Speech-to-text and AI services integration.

"},{"location":"qsl4a/special/pgptai/#prerequisites","title":"Prerequisites","text":"
pip install pgptAI\n
"},{"location":"qsl4a/special/pgptai/#speech-recognition","title":"Speech Recognition","text":""},{"location":"qsl4a/special/pgptai/#speechtotext","title":"speechToText()","text":"

Convert speech to text.

speechToText(RecordSecond=10, AmrFile=None, Language=None)\n

Parameters: - RecordSecond (int): Recording duration in seconds - AmrFile (str, optional): Existing audio file path - Language (str, optional): Language code ('en', 'zh')

Returns: Transcribed text

"},{"location":"qsl4a/special/pgptai/#text-to-speech","title":"Text to Speech","text":""},{"location":"qsl4a/special/pgptai/#texttospeech","title":"textToSpeech()","text":"

Convert text to speech and optionally play it.

textToSpeech(Text, AutoPlay=True, WavFile=None, VoiceName=None)\n

Parameters: - Text (str): Text to convert to speech - AutoPlay (bool): Automatically play the generated audio (default: True) - WavFile (str, optional): Path to save the WAV file. If None, uses temporary file - VoiceName (str, optional): Voice name to use (e.g., 'en-US-JennyNeural', 'zh-CN-XiaoxiaoNeural')

Returns: Dict with speech synthesis result including: - text: The input text - url: URL to download the audio file - WavFile: Path to the saved WAV file (if saved locally)

"},{"location":"qsl4a/special/pgptai/#configuration","title":"Configuration","text":"

The API uses configuration from /storage/emulated/0/Android/data/org.qpython.qpy/files/apigpt.conf:

[speech]\nspeech_key = your_api_key\n

Default voice settings: - English: en-US-JennyNeural - Chinese: zh-CN-XiaoxiaoNeural

"},{"location":"qsl4a/special/pgptai/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Record and transcribe\nprint(\"Recording for 5 seconds...\")\ntext = droid.speechToText(RecordSecond=5, Language='en').result\nprint(f\"You said: {text}\")\n\n# Transcribe existing file\ntext = droid.speechToText(AmrFile=\"/sdcard/recording.amr\").result\nprint(f\"Transcription: {text}\")\n\n# Text to speech\ndroid.textToSpeech(\"Hello, this is a test message.\", AutoPlay=True, Language='en')\n\n# Text to speech with custom voice and save to file\nresult = droid.textToSpeech(\n    \"Welcome to QPython!\",\n    AutoPlay=False,\n    WavFile=\"/sdcard/welcome.wav\",\n    VoiceName=\"en-US-JennyNeural\"\n).result\nprint(f\"Audio saved to: {result.get('WavFile')}\")\n
"},{"location":"qsl4a/special/pgptai/#class-usage","title":"Class Usage","text":"
from androidhelper.pgptai import pgptai\nimport androidhelper\n\ndroid = androidhelper.Android()\nai = pgptai(droid)\n\n# Use speech recognition\ntext = ai.speechToText(RecordSecond=10)\n
"},{"location":"qsl4a/storage/clipboard/","title":"Clipboard API","text":"

Copy and paste text to system clipboard.

"},{"location":"qsl4a/storage/clipboard/#methods","title":"Methods","text":""},{"location":"qsl4a/storage/clipboard/#setclipboard","title":"setClipboard()","text":"

Copy text to clipboard.

setClipboard(text)\n

Parameters: - text (str): Text to copy

Returns: True if success

"},{"location":"qsl4a/storage/clipboard/#getclipboard","title":"getClipboard()","text":"

Get text from clipboard.

getClipboard()\n

Returns: Clipboard text

"},{"location":"qsl4a/storage/clipboard/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Copy to clipboard\ndroid.setClipboard(\"Hello from QPython!\")\n\n# Paste from clipboard\ntext = droid.getClipboard().result\nprint(f\"Clipboard: {text}\")\n
"},{"location":"qsl4a/storage/documentfile/","title":"DocumentFile API","text":"

File operations with SAF (Storage Access Framework) support for Android 4.4+.

"},{"location":"qsl4a/storage/documentfile/#directory-operations","title":"Directory Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfilemkdir","title":"documentFileMkdir()","text":"

Create directory.

documentFileMkdir(Dir)\n

Parameters: - Dir (str): Directory path

Returns: True if success

"},{"location":"qsl4a/storage/documentfile/#documentfilelistfiles","title":"documentFileListFiles()","text":"

List files in directory.

documentFileListFiles(Folder)\n

Returns: List of files

"},{"location":"qsl4a/storage/documentfile/#file-operations","title":"File Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfileexists","title":"documentFileExists()","text":"

Check if file or directory exists.

documentFileExists(path)\n

Parameters: - path (str): File or directory path

Returns: True if exists, False otherwise

"},{"location":"qsl4a/storage/documentfile/#documentfileisfile","title":"documentFileIsFile()","text":"

Check if path is a file.

documentFileIsFile(path)\n

Parameters: - path (str): Path to check

Returns: True if file, False if not a file, None if not exists

"},{"location":"qsl4a/storage/documentfile/#documentfileisdirectory","title":"documentFileIsDirectory()","text":"

Check if path is a directory.

documentFileIsDirectory(path)\n

Parameters: - path (str): Path to check

Returns: True if directory, False if not a directory, None if not exists

"},{"location":"qsl4a/storage/documentfile/#documentfiledelete","title":"documentFileDelete()","text":"

Delete file or directory.

documentFileDelete(FileOrTree)\n

Returns: True if success

"},{"location":"qsl4a/storage/documentfile/#documentfilerenameto","title":"documentFileRenameTo()","text":"

Rename or move file.

documentFileRenameTo(Src, Dest)\n

Returns: True if success

"},{"location":"qsl4a/storage/documentfile/#documentfilecopy","title":"documentFileCopy()","text":"

Copy file.

documentFileCopy(SrcFileOrTree, DestFileOrTree)\n
"},{"location":"qsl4a/storage/documentfile/#stream-operations","title":"Stream Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfileinputstream","title":"documentFileInputStream()","text":"

Read file content.

documentFileInputStream(srcFile, EncodingFormat=\"\", skip=None, length=None)\n

Parameters: - srcFile (str): Source file - EncodingFormat (str): \"UTF-8\", \"GBK\", \"Base64\", or \"\" for bytes - skip (int): Skip bytes from start - length (int): Read length

Returns: File content

"},{"location":"qsl4a/storage/documentfile/#documentfileoutputstream","title":"documentFileOutputStream()","text":"

Write file content.

documentFileOutputStream(destFile, src, EncodingFormat=\"\", append=None)\n

Parameters: - destFile (str): Destination file - src: Data to write - EncodingFormat (str): Encoding format - append (bool): Append mode

"},{"location":"qsl4a/storage/documentfile/#file-information","title":"File Information","text":""},{"location":"qsl4a/storage/documentfile/#documentfilelength","title":"documentFileLength()","text":"

Get file size in bytes.

documentFileLength(path)\n

Parameters: - path (str): File path

Returns: File size in bytes (0 if not exists)

"},{"location":"qsl4a/storage/documentfile/#documentfilelastmodified","title":"documentFileLastModified()","text":"

Get last modified time.

documentFileLastModified(path)\n

Parameters: - path (str): File path

Returns: Timestamp (0 if not exists)

"},{"location":"qsl4a/storage/documentfile/#documentfilegetstat","title":"documentFileGetStat()","text":"

Get comprehensive file statistics.

documentFileGetStat(path)\n

Parameters: - path (str): File path

Returns: Dict with length, last modified, and read/write permissions, or None if not exists

"},{"location":"qsl4a/storage/documentfile/#uri-operations","title":"URI Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfilegeturi","title":"documentFileGetUri()","text":"

Get URI from path.

documentFileGetUri(path, isDirectory=None)\n
"},{"location":"qsl4a/storage/documentfile/#documentfileshowopen","title":"documentFileShowOpen()","text":"

Show file picker.

documentFileShowOpen()\n

Returns: Selected file URI

"},{"location":"qsl4a/storage/documentfile/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Create directory\ndroid.documentFileMkdir(\"/sdcard/MyFolder\")\n\n# List files\nfiles = droid.documentFileListFiles(\"/sdcard\").result\nfor f in files:\n    print(f)\n\n# Read file\ncontent = droid.documentFileInputStream(\n    \"/sdcard/test.txt\",\n    EncodingFormat=\"UTF-8\"\n).result\nprint(content)\n\n# Write file\ndroid.documentFileOutputStream(\n    \"/sdcard/output.txt\",\n    \"Hello World\",\n    EncodingFormat=\"UTF-8\"\n)\n
"},{"location":"qsl4a/storage/preferences/","title":"Preferences API","text":"

Store and retrieve data using Android SharedPreferences.

"},{"location":"qsl4a/storage/preferences/#preference-methods","title":"Preference Methods","text":""},{"location":"qsl4a/storage/preferences/#prefgetvalue","title":"prefGetValue()","text":"

Read a value from shared preferences.

prefGetValue(key, filename=None)\n

Parameters: - key (str): Preference key - filename (str, optional): Preference file name

Returns: The stored value (any type)

"},{"location":"qsl4a/storage/preferences/#prefputvalue","title":"prefPutValue()","text":"

Write a value to shared preferences.

prefPutValue(key, value, filename=None)\n

Parameters: - key (str): Preference key - value (object): Value to store - filename (str, optional): Preference file name

"},{"location":"qsl4a/storage/preferences/#prefgetall","title":"prefGetAll()","text":"

Get all preference values.

prefGetAll(filename=None)\n

Parameters: - filename (str, optional): Preference file name

Returns: Map of all preferences

"},{"location":"qsl4a/storage/preferences/#prefremovevalue","title":"prefRemoveValue()","text":"

Remove a value from shared preferences.

prefRemoveValue(key, filename=None)\n

Parameters: - key (str): Preference key to remove - filename (str, optional): Preference file name

"},{"location":"qsl4a/storage/preferences/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Store values\ndroid.prefPutValue(\"username\", \"alice\")\ndroid.prefPutValue(\"score\", 100)\ndroid.prefPutValue(\"enabled\", True)\n\n# Read a specific value\nusername = droid.prefGetValue(\"username\").result\nprint(f\"Username: {username}\")\n\n# Get all preferences\nall_prefs = droid.prefGetAll().result\nprint(f\"All prefs: {all_prefs}\")\n\n# Remove a value\ndroid.prefRemoveValue(\"score\")\n\n# Use custom filename\ndroid.prefPutValue(\"token\", \"abc123\", filename=\"auth.prefs\")\ntoken = droid.prefGetValue(\"token\", filename=\"auth.prefs\").result\n
"},{"location":"qsl4a/system/activityresult/","title":"Activity Result API","text":"

Set activity results for scripts launched via startActivityForResult.

"},{"location":"qsl4a/system/activityresult/#result-methods","title":"Result Methods","text":""},{"location":"qsl4a/system/activityresult/#setresultboolean","title":"setResultBoolean()","text":"

Set a boolean result.

setResultBoolean(resultCode, resultValue)\n

Parameters: - resultCode (int): Result code - resultValue (bool): Boolean result value

"},{"location":"qsl4a/system/activityresult/#setresultbyte","title":"setResultByte()","text":"

Set a byte result.

setResultByte(resultCode, resultValue)\n

Parameters: - resultCode (int): Result code - resultValue (int): Byte result value

"},{"location":"qsl4a/system/activityresult/#setresultshort","title":"setResultShort()","text":"

Set a short result.

setResultShort(resultCode, resultValue)\n

Parameters: - resultCode (int): Result code - resultValue (int): Short result value

"},{"location":"qsl4a/system/activityresult/#setresultchar","title":"setResultChar()","text":"

Set a character result.

setResultChar(resultCode, resultValue)\n

Parameters: - resultCode (int): Result code - resultValue (str): Character result value

"},{"location":"qsl4a/system/activityresult/#setresultinteger","title":"setResultInteger()","text":"

Set an integer result.

setResultInteger(resultCode, resultValue)\n

Parameters: - resultCode (int): Result code - resultValue (int): Integer result value

"},{"location":"qsl4a/system/activityresult/#setresultlong","title":"setResultLong()","text":"

Set a long result.

setResultLong(resultCode, resultValue)\n

Parameters: - resultCode (int): Result code - resultValue (int): Long result value

"},{"location":"qsl4a/system/activityresult/#setresultfloat","title":"setResultFloat()","text":"

Set a float result.

setResultFloat(resultCode, resultValue)\n

Parameters: - resultCode (int): Result code - resultValue (float): Float result value

"},{"location":"qsl4a/system/activityresult/#setresultdouble","title":"setResultDouble()","text":"

Set a double result.

setResultDouble(resultCode, resultValue)\n

Parameters: - resultCode (int): Result code - resultValue (float): Double result value

"},{"location":"qsl4a/system/activityresult/#setresultstring","title":"setResultString()","text":"

Set a string result.

setResultString(resultCode, resultValue)\n

Parameters: - resultCode (int): Result code - resultValue (str): String result value

"},{"location":"qsl4a/system/activityresult/#setresultbooleanarray","title":"setResultBooleanArray()","text":"

Set a boolean array result.

setResultBooleanArray(resultCode, resultValue)\n

Parameters: - resultCode (int): Result code - resultValue (list): Boolean array

"},{"location":"qsl4a/system/activityresult/#setresultbytearray","title":"setResultByteArray()","text":"

Set a byte array result.

setResultByteArray(resultCode, resultValue)\n

Parameters: - resultCode (int): Result code - resultValue (list): Byte array

"},{"location":"qsl4a/system/activityresult/#setresultshortarray","title":"setResultShortArray()","text":"

Set a short array result.

setResultShortArray(resultCode, resultValue)\n

Parameters: - resultCode (int): Result code - resultValue (list): Short array

"},{"location":"qsl4a/system/activityresult/#setresultchararray","title":"setResultCharArray()","text":"

Set a character array result.

setResultCharArray(resultCode, resultValue)\n

Parameters: - resultCode (int): Result code - resultValue (list): Char array

"},{"location":"qsl4a/system/activityresult/#setresultintegerarray","title":"setResultIntegerArray()","text":"

Set an integer array result.

setResultIntegerArray(resultCode, resultValue)\n

Parameters: - resultCode (int): Result code - resultValue (list): Integer array

"},{"location":"qsl4a/system/activityresult/#setresultlongarray","title":"setResultLongArray()","text":"

Set a long array result.

setResultLongArray(resultCode, resultValue)\n

Parameters: - resultCode (int): Result code - resultValue (list): Long array

"},{"location":"qsl4a/system/activityresult/#setresultfloatarray","title":"setResultFloatArray()","text":"

Set a float array result.

setResultFloatArray(resultCode, resultValue)\n

Parameters: - resultCode (int): Result code - resultValue (list): Float array

"},{"location":"qsl4a/system/activityresult/#setresultdoublearray","title":"setResultDoubleArray()","text":"

Set a double array result.

setResultDoubleArray(resultCode, resultValue)\n

Parameters: - resultCode (int): Result code - resultValue (list): Double array

"},{"location":"qsl4a/system/activityresult/#setresultstringarray","title":"setResultStringArray()","text":"

Set a string array result.

setResultStringArray(resultCode, resultValue)\n

Parameters: - resultCode (int): Result code - resultValue (list): String array

"},{"location":"qsl4a/system/activityresult/#setresultserializable","title":"setResultSerializable()","text":"

Set a serializable result.

setResultSerializable(resultCode, resultValue)\n

Parameters: - resultCode (int): Result code - resultValue: Serializable result value

"},{"location":"qsl4a/system/activityresult/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# After performing an activity, set the result\n# Example: Return success with data\ndroid.setResultInteger(0, 200)  # RESULT_OK\ndroid.setResultString(0, \"Operation completed successfully\")\n\n# Return an array result\ndroid.setResultIntegerArray(0, [1, 2, 3, 4, 5])\n
"},{"location":"qsl4a/system/application/","title":"Application Management","text":"

Manage applications, launch apps, and query system information.

"},{"location":"qsl4a/system/application/#application-information","title":"Application Information","text":""},{"location":"qsl4a/system/application/#getapplicationinfo","title":"getApplicationInfo()","text":"

Get information about an app.

getApplicationInfo(packageName=None)\n

Parameters: - packageName (str): Package name (None = current app)

Returns: App info dict

"},{"location":"qsl4a/system/application/#getinstalledpackages","title":"getInstalledPackages()","text":"

Get list of installed packages.

getInstalledPackages(flag=4)\n

Parameters: - flag (int): Package flag filter (default: 4)

Returns: List of installed packages

"},{"location":"qsl4a/system/application/#getrunningpackages","title":"getRunningPackages()","text":"

List running packages.

getRunningPackages()\n

Returns: List of package names

"},{"location":"qsl4a/system/application/#getlaunchablepackages","title":"getLaunchablePackages()","text":"

Get list of launchable packages.

getLaunchablePackages(needClassName=False)\n

Parameters: - needClassName (bool): Include main activity class name (default: False)

Returns: List of launchable package names or dict with class names

"},{"location":"qsl4a/system/application/#application-control","title":"Application Control","text":""},{"location":"qsl4a/system/application/#launch","title":"launch()","text":"

Launch an application.

launch(classname=None, packagename=None, wait=True)\n

Parameters: - classname (str): Main activity class name - packagename (str): Package name - wait (bool): Wait for launch to complete (default: True)

Returns: Launch result

"},{"location":"qsl4a/system/application/#forcestoppackage","title":"forceStopPackage()","text":"

Force stop an application.

forceStopPackage(packageName)\n

Parameters: - packageName (str): Package name to stop

"},{"location":"qsl4a/system/application/#version-information","title":"Version Information","text":""},{"location":"qsl4a/system/application/#getpackageversion","title":"getPackageVersion()","text":"

Get app version name.

getPackageVersion(packageName)\n

Returns: Version string (e.g., \"3.2.1\")

"},{"location":"qsl4a/system/application/#getpackageversioncode","title":"getPackageVersionCode()","text":"

Get app version code.

getPackageVersionCode(packageName)\n

Returns: Version code integer

"},{"location":"qsl4a/system/application/#getconstants","title":"getConstants()","text":"

Get class constants.

getConstants(classname)\n

Parameters: - classname (str): Full class name

Returns: Dict of constant names and values

"},{"location":"qsl4a/system/application/#system-features","title":"System Features","text":""},{"location":"qsl4a/system/application/#backgroundprotect","title":"backgroundProtect()","text":"

Enable or disable background protection for the app.

backgroundProtect(enabled=True)\n

Parameters: - enabled (bool): True to enable protection, False to disable

"},{"location":"qsl4a/system/application/#createscriptshortcut","title":"createScriptShortCut()","text":"

Create a home screen shortcut for a script.

createScriptShortCut(scriptPath, label=None, iconPath=None, scriptArg=None)\n

Parameters: - scriptPath (str): Path to the Python script - label (str, optional): Shortcut label - iconPath (str, optional): Path to icon image - scriptArg (str, optional): Argument to pass to script

"},{"location":"qsl4a/system/application/#device-information","title":"Device Information","text":""},{"location":"qsl4a/system/application/#getandroidid","title":"getAndroidID()","text":"

Get Android device ID.

getAndroidID()\n

Returns: Unique Android device ID string

"},{"location":"qsl4a/system/application/#getsysinfo","title":"getSysInfo()","text":"

Get system information.

getSysInfo()\n

Returns: Dict with system details

"},{"location":"qsl4a/system/application/#getlocale","title":"getLocale()","text":"

Get device locale.

getLocale()\n

Returns: Locale string (e.g., \"en_US\")

"},{"location":"qsl4a/system/application/#getharmonyosinformation","title":"getHarmonyOsInformation()","text":"

Get HarmonyOS information if running on HarmonyOS.

getHarmonyOsInformation()\n

Returns: HarmonyOS version info or None

"},{"location":"qsl4a/system/application/#isexternalstoragemanager","title":"isExternalStorageManager()","text":"

Check if app has external storage manager permission.

isExternalStorageManager()\n

Returns: True if has permission

"},{"location":"qsl4a/system/application/#memory-and-display","title":"Memory and Display","text":""},{"location":"qsl4a/system/application/#getmemoryinfo","title":"getMemoryInfo()","text":"

Get memory information.

getMemoryInfo()\n

Returns: Dict with memory stats

"},{"location":"qsl4a/system/application/#getscreeninfo","title":"getScreenInfo()","text":"

Get screen information.

getScreenInfo()\n

Returns: Dict with width, height, density

"},{"location":"qsl4a/system/application/#permissions","title":"Permissions","text":""},{"location":"qsl4a/system/application/#checkpermissions","title":"checkPermissions()","text":"

Check current app permissions.

checkPermissions()\n

Returns: Dict of permissions and their status

"},{"location":"qsl4a/system/application/#requestpermissions","title":"requestPermissions()","text":"

Request permissions from the user.

requestPermissions(permissions=None)\n

Parameters: - permissions (list, optional): List of permissions to request. If None, requests all needed permissions.

Returns: Result of permission request

"},{"location":"qsl4a/system/application/#system-actions","title":"System Actions","text":""},{"location":"qsl4a/system/application/#showscreenlock","title":"showScreenLock()","text":"

Show screen lock (PIN/pattern/password entry).

showScreenLock()\n
"},{"location":"qsl4a/system/application/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get system info\ninfo = droid.getSysInfo().result\nprint(f\"System: {info}\")\n\n# Get app version\nversion = droid.getPackageVersion(\"org.qpython.qpy\").result\nprint(f\"QPython version: {version}\")\n\n# List installed apps\napps = droid.getInstalledPackages().result\nprint(f\"Installed apps: {len(apps)}\")\n\n# Launch an app\ndroid.launch(packagename=\"com.android.settings\")\n\n# Check permissions\nperms = droid.checkPermissions().result\nprint(f\"Permissions: {perms}\")\n\n# Request storage permission\ndroid.requestPermissions([\"android.permission.READ_EXTERNAL_STORAGE\"])\n\n# Create shortcut\ndroid.createScriptShortCut(\n    \"/sdcard/my_script.py\",\n    label=\"My Script\",\n    iconPath=\"/sdcard/icon.png\"\n)\n
"},{"location":"qsl4a/system/battery/","title":"Battery API","text":"

Monitor device battery status and health.

"},{"location":"qsl4a/system/battery/#methods","title":"Methods","text":""},{"location":"qsl4a/system/battery/#readbatterydata","title":"readBatteryData()","text":"

Get complete battery information.

readBatteryData()\n

Returns: Dict with battery data

"},{"location":"qsl4a/system/battery/#batterystartmonitoring","title":"batteryStartMonitoring()","text":"

Start battery monitoring.

batteryStartMonitoring()\n
"},{"location":"qsl4a/system/battery/#batterystopmonitoring","title":"batteryStopMonitoring()","text":"

Stop battery monitoring.

batteryStopMonitoring()\n
"},{"location":"qsl4a/system/battery/#batterygetlevel","title":"batteryGetLevel()","text":"

Get battery percentage.

batteryGetLevel()\n

Returns: Int (0-100)

"},{"location":"qsl4a/system/battery/#batterygetstatus","title":"batteryGetStatus()","text":"

Get charging status.

batteryGetStatus()\n

Returns: - 1: Unknown - 2: Charging - 3: Discharging - 4: Not charging - 5: Full

"},{"location":"qsl4a/system/battery/#batterygetplugtype","title":"batteryGetPlugType()","text":"

Get power source.

batteryGetPlugType()\n

Returns: - -1: Unknown - 0: Unplugged - 1: AC charger - 2: USB port

"},{"location":"qsl4a/system/battery/#batterygethealth","title":"batteryGetHealth()","text":"

Get battery health.

batteryGetHealth()\n

Returns: - 1: Unknown - 2: Good - 3: Overheat - 4: Dead - 5: Over voltage - 6: Unspecified failure

"},{"location":"qsl4a/system/battery/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get battery level\nlevel = droid.batteryGetLevel().result\nprint(f\"Battery: {level}%\")\n
"},{"location":"qsl4a/system/qpyinterface/","title":"QPython Interface API","text":"

Execute QPython scripts and manage shared variables from other apps.

"},{"location":"qsl4a/system/qpyinterface/#script-execution-methods","title":"Script Execution Methods","text":""},{"location":"qsl4a/system/qpyinterface/#executeqpy","title":"executeQPy()","text":"

Execute a QPython script.

executeQPy(path=\"\", arg=None)\n

Parameters: - path (str): Path to the script file - arg (str, optional): Command line arguments

Returns: True if started successfully

"},{"location":"qsl4a/system/qpyinterface/#executeqpyassrv","title":"executeQPyAsSrv()","text":"

Execute a QPython script as a service.

executeQPyAsSrv(path=None)\n

Parameters: - path (str, optional): Path to the script file

Returns: True if started successfully

"},{"location":"qsl4a/system/qpyinterface/#executeqpycode","title":"executeQPyCode()","text":"

Execute Python code directly.

executeQPyCode(code=None)\n

Parameters: - code (str, optional): Python code to execute

Returns: True if started successfully

"},{"location":"qsl4a/system/qpyinterface/#executeqpycodeassrv","title":"executeQPyCodeAsSrv()","text":"

Execute Python code as a service.

executeQPyCodeAsSrv(code=None)\n

Parameters: - code (str, optional): Python code to execute

Returns: True if started successfully

"},{"location":"qsl4a/system/qpyinterface/#shared-variables","title":"Shared Variables","text":"

Shared variables allow communication between QPython and other apps.

"},{"location":"qsl4a/system/qpyinterface/#sharedvariableset","title":"sharedVariableSet()","text":"

Set a Java shared variable.

sharedVariableSet(key, value)\n

Parameters: - key (str): Variable name - value (str): Variable value

Returns: The stored value

"},{"location":"qsl4a/system/qpyinterface/#sharedvariableget","title":"sharedVariableGet()","text":"

Get a Java shared variable.

sharedVariableGet(key)\n

Parameters: - key (str): Variable name

Returns: The stored value

"},{"location":"qsl4a/system/qpyinterface/#sharedvariableremove","title":"sharedVariableRemove()","text":"

Remove a Java shared variable.

sharedVariableRemove(key)\n

Parameters: - key (str): Variable name to remove

Returns: The removed value

"},{"location":"qsl4a/system/qpyinterface/#getlastlog","title":"getLastLog()","text":"

Get the last log output from QPython.

getLastLog()\n

Returns: String log content

"},{"location":"qsl4a/system/qpyinterface/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Execute a script\ndroid.executeQPy(\"/sdcard/my_script.py\", arg=\"test\")\n\n# Execute code directly\ncode = \"print('Hello from QPython!')\"\ndroid.executeQPyCode(code)\n\n# Use shared variables\ndroid.sharedVariableSet(\"username\", \"alice\")\nusername = droid.sharedVariableGet(\"username\").result\nprint(f\"Username: {username}\")\n\n# Remove variable\ndroid.sharedVariableRemove(\"username\")\n\n# Get recent log\nlog = droid.getLastLog().result\nprint(f\"Log: {log}\")\n
"},{"location":"qsl4a/system/sensors/","title":"Sensor API","text":"

Access device sensors including accelerometer, gyroscope, magnetometer, and more.

"},{"location":"qsl4a/system/sensors/#methods","title":"Methods","text":""},{"location":"qsl4a/system/sensors/#startsensingtimed","title":"startSensingTimed()","text":"

Start sensor monitoring with time intervals.

startSensingTimed(sensorNumber, delayTime)\n

Parameters: - sensorNumber (int): Sensor ID (1-3 typically) - delayTime (int): Delay between readings in milliseconds

"},{"location":"qsl4a/system/sensors/#startsensingthreshold","title":"startSensingThreshold()","text":"

Start sensor monitoring with threshold trigger.

startSensingThreshold(sensorNumber, threshold, axis)\n

Parameters: - sensorNumber (int): Sensor ID - threshold (float): Trigger threshold - axis (int): Axis to monitor (0=X, 1=Y, 2=Z)

"},{"location":"qsl4a/system/sensors/#stopsensing","title":"stopSensing()","text":"

Stop all sensor monitoring.

stopSensing()\n
"},{"location":"qsl4a/system/sensors/#readsensors","title":"readSensors()","text":"

Read current sensor data.

readSensors()\n

Returns: Sensor data dict

"},{"location":"qsl4a/system/sensors/#sensorsreadaccelerometer","title":"sensorsReadAccelerometer()","text":"

Read accelerometer values.

sensorsReadAccelerometer()\n

Returns: List [X, Y, Z] in m/s\u00b2

"},{"location":"qsl4a/system/sensors/#sensorsreadgyroscope","title":"sensorsReadGyroscope()","text":"

Read gyroscope values.

sensorsReadGyroscope()\n

Returns: List [X, Y, Z] in rad/s

"},{"location":"qsl4a/system/sensors/#sensorsreadmagnetometer","title":"sensorsReadMagnetometer()","text":"

Read magnetic field values.

sensorsReadMagnetometer()\n

Returns: List [X, Y, Z] in \u03bcT

"},{"location":"qsl4a/system/sensors/#sensorsreadorientation","title":"sensorsReadOrientation()","text":"

Read device orientation.

sensorsReadOrientation()\n

Returns: List [azimuth, pitch, roll] in degrees

"},{"location":"qsl4a/system/sensors/#sensorsgetlight","title":"sensorsGetLight()","text":"

Read light sensor value.

sensorsGetLight()\n

Returns: Light level in lux

"},{"location":"qsl4a/system/sensors/#sensorsgetstepcounter","title":"sensorsGetStepCounter()","text":"

Read step counter.

sensorsGetStepCounter()\n

Returns: Number of steps

"},{"location":"qsl4a/system/sensors/#sensorsgetaccuracy","title":"sensorsGetAccuracy()","text":"

Get the current sensor accuracy.

sensorsGetAccuracy()\n

Returns: Accuracy value (0-3: UNRELIABLE, ACCURACY_LOW, ACCURACY_MEDIUM, ACCURACY_HIGH)

"},{"location":"qsl4a/system/sensors/#usage-example","title":"Usage Example","text":"
import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start sensing\ndroid.startSensingTimed(1, 250)\n\n# Read sensors 10 times\nfor i in range(10):\n    accel = droid.sensorsReadAccelerometer().result\n    print(f\"Accel: X={accel[0]:.2f}, Y={accel[1]:.2f}, Z={accel[2]:.2f}\")\n    time.sleep(0.5)\n\ndroid.stopSensing()\n
"},{"location":"qsl4a/system/settings/","title":"Settings API","text":"

Control system settings including screen, sound, and network settings.

"},{"location":"qsl4a/system/settings/#screen-settings","title":"Screen Settings","text":""},{"location":"qsl4a/system/settings/#setscreentimeout","title":"setScreenTimeout()","text":"

Set the screen timeout value.

setScreenTimeout(value)\n

Parameters: - value (int): Screen timeout in seconds

Returns: Previous timeout value

"},{"location":"qsl4a/system/settings/#getscreentimeout","title":"getScreenTimeout()","text":"

Get the current screen timeout.

getScreenTimeout()\n

Returns: Current screen timeout in seconds

"},{"location":"qsl4a/system/settings/#getscreenbrightness","title":"getScreenBrightness()","text":"

Get the screen brightness value.

getScreenBrightness()\n

Returns: Brightness value (0-255)

"},{"location":"qsl4a/system/settings/#setscreenbrightness","title":"setScreenBrightness()","text":"

Set the screen brightness.

setScreenBrightness(value=None)\n

Parameters: - value (int, optional): Brightness value (0-255), or None for auto

Returns: Previous brightness value

"},{"location":"qsl4a/system/settings/#checkscreenon","title":"checkScreenOn()","text":"

Check if the screen is on.

checkScreenOn()\n

Returns: True if screen is on, False otherwise

"},{"location":"qsl4a/system/settings/#airplane-mode","title":"Airplane Mode","text":""},{"location":"qsl4a/system/settings/#checkairplanemode","title":"checkAirplaneMode()","text":"

Check if airplane mode is enabled.

checkAirplaneMode()\n

Returns: True if airplane mode is on

"},{"location":"qsl4a/system/settings/#ringer-settings","title":"Ringer Settings","text":""},{"location":"qsl4a/system/settings/#checkringersilentmode","title":"checkRingerSilentMode()","text":"

Check if ringer is in silent mode.

checkRingerSilentMode()\n

Returns: True if silent mode is on

"},{"location":"qsl4a/system/settings/#toggleringersilentmode","title":"toggleRingerSilentMode()","text":"

Toggle ringer silent mode.

toggleRingerSilentMode(enabled=None)\n

Parameters: - enabled (bool, optional): True to enable, False to disable, None to toggle

Returns: New state

"},{"location":"qsl4a/system/settings/#togglevibratemode","title":"toggleVibrateMode()","text":"

Toggle vibrate mode.

toggleVibrateMode(enabled=None, ringer=None)\n

Parameters: - enabled (bool, optional): Toggle vibrate on/off - ringer (bool, optional): Apply to ringer mode

Returns: New state

"},{"location":"qsl4a/system/settings/#getvibratemode","title":"getVibrateMode()","text":"

Get the vibrate mode setting.

getVibrateMode(ringer=None)\n

Parameters: - ringer (bool, optional): Check ringer vibrate mode

Returns: True if vibrate is enabled

"},{"location":"qsl4a/system/settings/#volume-settings","title":"Volume Settings","text":""},{"location":"qsl4a/system/settings/#getringervolume","title":"getRingerVolume()","text":"

Get the current ringer volume.

getRingerVolume()\n

Returns: Ringer volume level (0-7 typically)

"},{"location":"qsl4a/system/settings/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

Get the maximum ringer volume.

getMaxRingerVolume()\n

Returns: Maximum ringer volume

"},{"location":"qsl4a/system/settings/#setringervolume","title":"setRingerVolume()","text":"

Set the ringer volume.

setRingerVolume(volume)\n

Parameters: - volume (int): Volume level

"},{"location":"qsl4a/system/settings/#getmediavolume","title":"getMediaVolume()","text":"

Get the current media volume.

getMediaVolume()\n

Returns: Media volume level (0-15 typically)

"},{"location":"qsl4a/system/settings/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

Get the maximum media volume.

getMaxMediaVolume()\n

Returns: Maximum media volume

"},{"location":"qsl4a/system/settings/#setmediavolume","title":"setMediaVolume()","text":"

Set the media volume.

setMediaVolume(volume)\n

Parameters: - volume (int): Volume level

"},{"location":"qsl4a/system/settings/#system-info","title":"System Info","text":""},{"location":"qsl4a/system/settings/#elapsedrealtimenanos","title":"elapsedRealtimeNanos()","text":"

Get nanoseconds since system startup.

elapsedRealtimeNanos()\n

Returns: Nanoseconds (can be used for timing)

"},{"location":"qsl4a/system/settings/#gettrafficstats","title":"getTrafficStats()","text":"

Get network traffic statistics.

getTrafficStats(flags=7)\n

Parameters: - flags (int): Which stats to retrieve (default: 7 = all)

Returns: Dict with transmit/receive bytes

"},{"location":"qsl4a/system/settings/#getapptxbytes","title":"getAppTxBytes()","text":"

Get transmit bytes for QPython app.

getAppTxBytes(packageName)\n

Parameters: - packageName (str): Package name

Returns: Dict with tx/rx bytes

"},{"location":"qsl4a/system/settings/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Screen settings\ncurrent_timeout = droid.getScreenTimeout().result\nprint(f\"Current timeout: {current_timeout}s\")\ndroid.setScreenTimeout(30)\n\n# Check screen\nif droid.checkScreenOn().result:\n    print(\"Screen is on\")\n\n# Volume control\nmedia_vol = droid.getMediaVolume().result\nprint(f\"Media volume: {media_vol}\")\ndroid.setMediaVolume(10)\n\n# Check airplane mode\nif droid.checkAirplaneMode().result:\n    print(\"Airplane mode is on\")\n
"},{"location":"qsl4a/system/sysinfo/","title":"System Information","text":"

Retrieve device and system information.

"},{"location":"qsl4a/system/sysinfo/#device-information","title":"Device Information","text":""},{"location":"qsl4a/system/sysinfo/#getandroidid","title":"getAndroidID()","text":"

Get the Android device ID.

getAndroidID()\n

Returns: String device ID

"},{"location":"qsl4a/system/sysinfo/#getsysinfo","title":"getSysInfo()","text":"

Get comprehensive system information.

getSysInfo()\n

Returns: Dict with system details

"},{"location":"qsl4a/system/sysinfo/#getlocale","title":"getLocale()","text":"

Get device locale settings.

getLocale()\n

Returns: Locale string (e.g., \"en_US\")

"},{"location":"qsl4a/system/sysinfo/#memory","title":"Memory","text":""},{"location":"qsl4a/system/sysinfo/#getmemoryinfo","title":"getMemoryInfo()","text":"

Get RAM information.

getMemoryInfo()\n

Returns: Dict with memory stats

"},{"location":"qsl4a/system/sysinfo/#display","title":"Display","text":""},{"location":"qsl4a/system/sysinfo/#getscreeninfo","title":"getScreenInfo()","text":"

Get display information.

getScreenInfo()\n

Returns: Dict with width, height, density

"},{"location":"qsl4a/system/sysinfo/#identifiers","title":"Identifiers","text":""},{"location":"qsl4a/system/sysinfo/#getimei","title":"getImei()","text":"

Get device IMEI.

getImei(slotIndex=None)\n
"},{"location":"qsl4a/system/sysinfo/#getmeid","title":"getMeid()","text":"

Get device MEID.

getMeid(slotIndex=None)\n
"},{"location":"qsl4a/system/sysinfo/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Device ID\nandroid_id = droid.getAndroidID().result\nprint(f\"Android ID: {android_id}\")\n\n# Screen info\nscreen = droid.getScreenInfo().result\nprint(f\"Screen: {screen['width']}x{screen['height']}\")\n\n# Memory\nmemory = droid.getMemoryInfo().result\nprint(f\"Memory: {memory}\")\n
"},{"location":"qsl4a/system/wakelock/","title":"WakeLock API","text":"

Control device wake locks to keep the CPU or screen on.

"},{"location":"qsl4a/system/wakelock/#wake-lock-types","title":"Wake Lock Types","text":"

QSL4A provides different wake lock types:

Type Description Full CPU on, screen bright, keyboard bright Partial CPU on only Bright CPU on, screen bright Dim CPU on, screen dim"},{"location":"qsl4a/system/wakelock/#wake-lock-methods","title":"Wake Lock Methods","text":""},{"location":"qsl4a/system/wakelock/#wakelockacquirefull","title":"wakeLockAcquireFull()","text":"

Acquire a full wake lock (CPU on, screen bright, keyboard bright).

wakeLockAcquireFull()\n
"},{"location":"qsl4a/system/wakelock/#wakelockacquirepartial","title":"wakeLockAcquirePartial()","text":"

Acquire a partial wake lock (CPU on only).

wakeLockAcquirePartial()\n
"},{"location":"qsl4a/system/wakelock/#wakelockacquirebright","title":"wakeLockAcquireBright()","text":"

Acquire a bright wake lock (CPU on, screen bright).

wakeLockAcquireBright()\n
"},{"location":"qsl4a/system/wakelock/#wakelockacquiredim","title":"wakeLockAcquireDim()","text":"

Acquire a dim wake lock (CPU on, screen dim).

wakeLockAcquireDim()\n
"},{"location":"qsl4a/system/wakelock/#wakelockrelease","title":"wakeLockRelease()","text":"

Release the wake lock.

wakeLockRelease()\n
"},{"location":"qsl4a/system/wakelock/#usage-example","title":"Usage Example","text":"
import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Acquire full wake lock\ndroid.wakeLockAcquireFull()\n\n# Do important work while keeping screen on\nprint(\"Screen will stay on\")\ntime.sleep(10)\n\n# Release when done\ndroid.wakeLockRelease()\n\n# Or use partial lock for background tasks\ndroid.wakeLockAcquirePartial()\n# CPU stays on even with screen off\ntime.sleep(30)\ndroid.wakeLockRelease()\n

Note: Remember to release wake locks when no longer needed to conserve battery.

"},{"location":"qsl4a/ui/accessibility/","title":"Accessibility Service","text":"

The Accessibility Service allows automation of UI interactions like clicks, swipes, and system actions.

"},{"location":"qsl4a/ui/accessibility/#service-control","title":"Service Control","text":""},{"location":"qsl4a/ui/accessibility/#accessibilitystartservice","title":"accessibilityStartService()","text":"

Start the accessibility service.

accessibilityStartService()\n

Returns: True if successful, False otherwise

"},{"location":"qsl4a/ui/accessibility/#accessibilityserviceenabled","title":"accessibilityServiceEnabled()","text":"

Check if accessibility service is enabled.

accessibilityServiceEnabled()\n

Returns: True or False

"},{"location":"qsl4a/ui/accessibility/#screen-interactions","title":"Screen Interactions","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityclick","title":"accessibilityClick()","text":"

Click at screen coordinates.

accessibilityClick(x=0, y=0, t=50)\n

Parameters: - x (int/float): X coordinate (0=center, decimals supported) - y (int/float): Y coordinate (0=center, decimals supported) - t (int): Press duration in milliseconds (default: 50)

"},{"location":"qsl4a/ui/accessibility/#accessibilityslide","title":"accessibilitySlide()","text":"

Multi-point slide gesture.

accessibilitySlide(XnYn=None, t=None)\n

Parameters: - XnYn (list): Coordinates [X1, Y1, X2, Y2, ... Xn, Yn] - t (int): Slide duration (default: 50*n ms)

"},{"location":"qsl4a/ui/accessibility/#system-actions","title":"System Actions","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityaction","title":"accessibilityAction()","text":"

Execute system action by code.

accessibilityAction(actionCode)\n

Action Codes: | Code | Constant | Description | |------|----------|-------------| | 1 | BACK | Back button | | 2 | HOME | Home button | | 3 | RECENTS | Recent apps | | 4 | NOTIFICATIONS | Open notifications | | 5 | QUICK_SETTINGS | Open quick settings | | 6 | POWER_DIALOG | Power menu | | 7 | TOGGLE_SPLIT_SCREEN | Split screen | | 8 | LOCK_SCREEN | Lock screen | | 9 | TAKE_SCREENSHOT | Take screenshot | | 10 | KEYCODE_HEADSETHOOK | Headset hook | | 11-14 | ACCESSIBILITY_ | Accessibility buttons | | 15 | DISMISS_NOTIFICATION_SHADE | Close notifications | | 16-20 | DPAD_ | Directional pad | | 21 | MENU | Menu button | | 22 | MEDIA_PLAY_PAUSE | Play/Pause media |

"},{"location":"qsl4a/ui/accessibility/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/accessibility/#click-center-screen","title":"Click Center Screen","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Start service\nif not droid.accessibilityServiceEnabled().result:\n    droid.accessibilityStartService()\n\n# Click center (0,0 = center)\ndroid.accessibilityClick(0, 0, t=100)\n
"},{"location":"qsl4a/ui/accessibility/#swipe-gesture","title":"Swipe Gesture","text":"
# Swipe from bottom to top (scroll up)\ndroid.accessibilitySlide([0, 1.5, 0, -1.5], t=300)\n
"},{"location":"qsl4a/ui/accessibility/#system-navigation","title":"System Navigation","text":"
# Press home\ndroid.accessibilityAction(2)\n\n# Press back\ndroid.accessibilityAction(1)\n\n# Open notifications\ndroid.accessibilityAction(4)\n
"},{"location":"qsl4a/ui/accessibility/#tap-specific-location","title":"Tap Specific Location","text":"
# Tap at screen coordinate (500, 800)\ndroid.accessibilityClick(500, 800)\n\n# Tap at relative position (center horizontally, 3/4 down)\ndroid.accessibilityClick(0, 1.5)\n
"},{"location":"qsl4a/ui/dialogs/","title":"Dialog System","text":"

QSL4A provides comprehensive dialog support for user interaction, including alerts, input dialogs, choice dialogs, and progress dialogs.

"},{"location":"qsl4a/ui/dialogs/#alert-dialogs","title":"Alert Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowalert","title":"dialogShowAlert()","text":"

Show a simple alert dialog.

dialogShowAlert(title=\"Alert\", message=\"The message of the alert.\",\n                positiveButtonText=\"OK\", negativeButtonText=None,\n                neutralButtonText=None, messageIsHtml=False)\n

Parameters: - title (str): Dialog title - message (str): Message text - positiveButtonText (str): Positive button label - negativeButtonText (str, optional): Negative button label - neutralButtonText (str, optional): Neutral button label - messageIsHtml (bool): Parse message as HTML

Returns: Result with button clicked

"},{"location":"qsl4a/ui/dialogs/#dialogshowsimplechoice","title":"dialogShowSimpleChoice()","text":"

Show a simple choice dialog with items.

dialogShowSimpleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

Parameters: - items (list): List of choice strings

Returns: Result with selected item

"},{"location":"qsl4a/ui/dialogs/#input-dialogs","title":"Input Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialoggetinput","title":"dialogGetInput()","text":"

Get text input from user.

dialogGetInput(title=\"Value\", message=\"Please enter value:\",\n               defaultText=None, messageIsHtml=False)\n

Returns: Result with user's input text

"},{"location":"qsl4a/ui/dialogs/#dialoggetpassword","title":"dialogGetPassword()","text":"

Get password input.

dialogGetPassword(title=\"Password\", message=\"Please enter password:\")\n

Returns: Result with password entered

"},{"location":"qsl4a/ui/dialogs/#dialogcreateinput","title":"dialogCreateInput()","text":"

Create a custom input dialog.

dialogCreateInput(title=\"Value\", message=\"Please enter value:\",\n                  defaultText=None, inputType=None)\n

Parameters: - inputType (str): Input type (e.g., \"text\", \"number\", \"textPassword\")

"},{"location":"qsl4a/ui/dialogs/#dialogcreatepassword","title":"dialogCreatePassword()","text":"

Create a password input dialog.

dialogCreatePassword(title=\"Password\", message=\"Please enter password:\")\n
"},{"location":"qsl4a/ui/dialogs/#dialogcreateseekbar","title":"dialogCreateSeekBar()","text":"

Create a seek bar/slider dialog.

dialogCreateSeekBar(starting_value=50, maximum_value=100, title=\"\", message=\"\")\n

Parameters: - starting_value (int): Initial value - maximum_value (int): Maximum value

"},{"location":"qsl4a/ui/dialogs/#choice-dialogs","title":"Choice Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowsinglechoice","title":"dialogShowSingleChoice()","text":"

Show single choice (radio) dialog.

dialogShowSingleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, selected=-1, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

Parameters: - items (list): List of choice strings - selected (int): Default selected index

"},{"location":"qsl4a/ui/dialogs/#dialogshowmultichoice","title":"dialogShowMultiChoice()","text":"

Show multiple choice (checkbox) dialog.

dialogShowMultiChoice(title=\"Alert\", message=\"The message of the alert.\",\n                      items=None, selected=None, positiveButtonText=\"OK\",\n                      negativeButtonText=None, neutralButtonText=None,\n                      messageIsHtml=False)\n

Parameters: - items (list): List of choice strings - selected (list): List of initially selected indices

"},{"location":"qsl4a/ui/dialogs/#dialogsetsinglechoiceitems","title":"dialogSetSingleChoiceItems()","text":"

Set single choice items for a dialog.

dialogSetSingleChoiceItems(items, selected=-1)\n
"},{"location":"qsl4a/ui/dialogs/#dialogsetmultichoiceitems","title":"dialogSetMultiChoiceItems()","text":"

Set multiple choice items for a dialog.

dialogSetMultiChoiceItems(items, selected=None)\n
"},{"location":"qsl4a/ui/dialogs/#progress-dialogs","title":"Progress Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatespinnerprogress","title":"dialogCreateSpinnerProgress()","text":"

Create indeterminate progress dialog.

dialogCreateSpinnerProgress(title=None, message=None, maximum_progress=100)\n
"},{"location":"qsl4a/ui/dialogs/#dialogcreatehorizontalprogress","title":"dialogCreateHorizontalProgress()","text":"

Create horizontal progress dialog.

dialogCreateHorizontalProgress(title=None, message=None, maximum_progress=100)\n
"},{"location":"qsl4a/ui/dialogs/#dialogsetcurrentprogress","title":"dialogSetCurrentProgress()","text":"

Update progress value.

dialogSetCurrentProgress(current)\n
"},{"location":"qsl4a/ui/dialogs/#dialogsetmaxprogress","title":"dialogSetMaxProgress()","text":"

Set maximum progress value.

dialogSetMaxProgress(max)\n
"},{"location":"qsl4a/ui/dialogs/#dialogsetprogressmessage","title":"dialogSetProgressMessage()","text":"

Update the progress dialog message.

dialogSetProgressMessage(message)\n
"},{"location":"qsl4a/ui/dialogs/#picker-dialogs","title":"Picker Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatedatepicker","title":"dialogCreateDatePicker()","text":"

Create date picker dialog.

dialogCreateDatePicker(year=1970, month=1, day=1)\n
"},{"location":"qsl4a/ui/dialogs/#dialogcreatetimepicker","title":"dialogCreateTimePicker()","text":"

Create time picker dialog.

dialogCreateTimePicker(hour=0, minute=0, is24hour=False)\n
"},{"location":"qsl4a/ui/dialogs/#custom-dialog-creation","title":"Custom Dialog Creation","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatealert","title":"dialogCreateAlert()","text":"

Create a custom alert dialog.

dialogCreateAlert(title=None, message=None)\n

Creates an empty alert dialog. Use with other dialogSet* functions to customize.

"},{"location":"qsl4a/ui/dialogs/#dialogsetitems","title":"dialogSetItems()","text":"

Set simple list items for the dialog.

dialogSetItems(items)\n
"},{"location":"qsl4a/ui/dialogs/#dialogsetpositivebuttontext","title":"dialogSetPositiveButtonText()","text":"

Set positive button text.

dialogSetPositiveButtonText(text)\n
"},{"location":"qsl4a/ui/dialogs/#dialogsetnegativebuttontext","title":"dialogSetNegativeButtonText()","text":"

Set negative button text.

dialogSetNegativeButtonText(text)\n
"},{"location":"qsl4a/ui/dialogs/#dialogsetneutralbuttontext","title":"dialogSetNeutralButtonText()","text":"

Set neutral button text.

dialogSetNeutralButtonText(text)\n
"},{"location":"qsl4a/ui/dialogs/#dialogsetmessageishtml","title":"dialogSetMessageIsHtml()","text":"

Set whether message should be parsed as HTML.

dialogSetMessageIsHtml(messageIsHtml=True)\n
"},{"location":"qsl4a/ui/dialogs/#dialogshow","title":"dialogShow()","text":"

Show the created custom dialog.

dialogShow()\n
"},{"location":"qsl4a/ui/dialogs/#dialog-control","title":"Dialog Control","text":""},{"location":"qsl4a/ui/dialogs/#dialogdismiss","title":"dialogDismiss()","text":"

Dismiss current dialog.

dialogDismiss()\n
"},{"location":"qsl4a/ui/dialogs/#dialoggetresponse","title":"dialogGetResponse()","text":"

Get dialog response.

dialogGetResponse()\n
"},{"location":"qsl4a/ui/dialogs/#dialoggetselecteditems","title":"dialogGetSelectedItems()","text":"

Get selected items from choice dialog.

dialogGetSelectedItems()\n
"},{"location":"qsl4a/ui/dialogs/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/dialogs/#simple-alert","title":"Simple Alert","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Show alert\ndroid.dialogShowAlert(\"Warning\", \"This is an important message!\")\n
"},{"location":"qsl4a/ui/dialogs/#input-dialog","title":"Input Dialog","text":"
# Get user input\nresult = droid.dialogGetInput(\"Name\", \"Enter your name:\", \"John\").result\nprint(f\"Hello, {result}!\")\n
"},{"location":"qsl4a/ui/dialogs/#custom-dialog-with-buttons","title":"Custom Dialog with Buttons","text":"
# Create custom dialog\ndroid.dialogCreateAlert(\"Custom\", \"Choose an option\")\ndroid.dialogSetItems([\"Option 1\", \"Option 2\", \"Option 3\"])\ndroid.dialogShow()\n\n# Get response\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response['item']}\")\n
"},{"location":"qsl4a/ui/dialogs/#progress-dialog","title":"Progress Dialog","text":"
# Create progress dialog\ndroid.dialogCreateHorizontalProgress(\"Loading\", \"Please wait...\", 100)\ndroid.dialogShow()\n\n# Update progress\nfor i in range(101):\n    droid.dialogSetCurrentProgress(i)\n    time.sleep(0.05)\n\ndroid.dialogDismiss()\n
"},{"location":"qsl4a/ui/dialogs/#date-picker","title":"Date Picker","text":"
# Show date picker\ndroid.dialogCreateDatePicker(2024, 1, 15)\ndroid.dialogShow()\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response}\")\n
"},{"location":"qsl4a/ui/floatview/","title":"FloatView","text":"

Floating window support for overlay UI elements that stay on top of other applications.

"},{"location":"qsl4a/ui/floatview/#methods","title":"Methods","text":""},{"location":"qsl4a/ui/floatview/#floatview_1","title":"floatView()","text":"

Show or modify a floating view.

floatView(Args=None)\n

Parameters: - Args (dict): Configuration dictionary with the following keys: - index (int): Float view index (-1 to create new, >=0 to modify existing) - text (str): Text content to display - html (str): HTML content (used if text is omitted) - width (int): View width in pixels (default: 300) - height (int): View height in pixels (default: 150) - x (int): X position (0 = center, positive/negative for offset) - y (int): Y position (0 = center, positive/negative for offset) - backColor (str): Background color in ARGB hex (default: '7f7f7f7f') - textColor (str): Text color in ARGB hex (default: 'ff000000') - textSize (int): Text size (default: 10) - textAlign (int): Text alignment (0 = inherit) - script (str): Script path to run after long click close - arg: Script argument - clickRemove (bool): Enable click to remove (default: True) - flag (int): Window flag (default: 40 - touchable)

Returns: Current chain list length

"},{"location":"qsl4a/ui/floatview/#floatviewcount","title":"floatViewCount()","text":"

Get the number of active float views.

floatViewCount()\n

Returns: Number of float views

"},{"location":"qsl4a/ui/floatview/#floatviewresult","title":"floatViewResult()","text":"

Get the result/status of a float view.

floatViewResult(index=-1)\n

Parameters: - index (int): Float view index (default: -1, returns last operation result)

Returns: Dict with operation details including: - x, y: Position - time: Timestamp - operation: Operation type ('initial', 'move', etc.) - index: View index - removed: True if view was removed

"},{"location":"qsl4a/ui/floatview/#floatviewremove","title":"floatViewRemove()","text":"

Remove a float view.

floatViewRemove(index=-1)\n

Parameters: - index (int): Index of view to remove (default: -1 removes the last one)

Returns: 1 if successful, 0 otherwise

"},{"location":"qsl4a/ui/floatview/#constants","title":"Constants","text":"
  • floatView.INDEX_NEW = -1 - Create new float view
  • floatView.FLAG_DEFAULT_TOUCHABLE = 40 - Default touchable flag
  • floatView.TEXT_ALIGNMENT_INHERIT = 0
  • floatView.TEXT_ALIGNMENT_CENTER - Center text alignment
"},{"location":"qsl4a/ui/floatview/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/floatview/#basic-float-view","title":"Basic Float View","text":"
import androidhelper\nfrom androidhelper import Android\n\ndroid = androidhelper.Android()\n\n# Create a simple float view\ndroid.floatView({\n    'index': -1,  # Create new\n    'text': 'Hello World',\n    'width': 400,\n    'height': 300,\n    'x': -300,  # Offset from center\n    'y': -400,\n    'backColor': 'ff0000',  # Red background\n    'textColor': '0000ff',  # Blue text\n    'textSize': 16,\n    'textAlign': droid.floatView.TEXT_ALIGNMENT_CENTER\n})\n\n# Check count\nprint(f\"Float views: {droid.floatViewCount().result}\")\n\n# Get result\nresult = droid.floatViewResult().result\nprint(f\"View info: {result}\")\n\n# Remove the float view\ndroid.floatViewRemove(0)\n
"},{"location":"qsl4a/ui/floatview/#html-content","title":"HTML Content","text":"
# Create float view with HTML content\ndroid.floatView({\n    'text': '',  # Empty text to use HTML\n    'html': '<h1>Title</h1><p>Rich <b>HTML</b> content</p>',\n    'width': 500,\n    'height': 400\n})\n
"},{"location":"qsl4a/ui/floatview/#modify-existing-view","title":"Modify Existing View","text":"
# Create initial view\ndroid.floatView({'text': 'Initial Text', 'width': 300, 'height': 150})\n\n# Modify the same view (index 0)\ndroid.floatView({\n    'index': 0,\n    'text': 'Updated Text!',\n    'backColor': '7f00ff00'  # Green background\n})\n\n# Check the move/change result\nresult = droid.floatViewResult(0).result\nprint(f\"Operation: {result.get('operation')}, Position: ({result.get('x')}, {result.get('y')})\")\n
"},{"location":"qsl4a/ui/floatview/#multiple-float-views","title":"Multiple Float Views","text":"
# Create multiple views\nfor i in range(3):\n    droid.floatView({\n        'index': -1,\n        'text': f'View {i}',\n        'x': i * 100 - 150,\n        'y': i * 100 - 150,\n        'backColor': f'{i}f{i}f{i}f'\n    })\n\nprint(f\"Total views: {droid.floatViewCount().result}\")\n\n# Remove all views\nwhile droid.floatViewCount().result > 0:\n    droid.floatViewRemove()\n
"},{"location":"qsl4a/ui/floatview/#with-script-callback","title":"With Script Callback","text":"
# Create float view that runs script on close\ndroid.floatView({\n    'text': 'Click to close and run script',\n    'script': '/sdcard/my_script.py',\n    'arg': 'hello from float view',\n    'clickRemove': True\n})\n
"},{"location":"qsl4a/ui/fullscreen/","title":"FullScreen UI","text":"

Create custom fullscreen interfaces with native Android layouts.

"},{"location":"qsl4a/ui/fullscreen/#layout-methods","title":"Layout Methods","text":""},{"location":"qsl4a/ui/fullscreen/#fullshow","title":"fullShow()","text":"

Show a fullscreen layout.

fullShow(layout, title=None, theme=None)\n

Parameters: - layout (str): JSON layout definition or layout string - title (str, optional): Window title - theme (str, optional): Theme name

Returns: Window ID

"},{"location":"qsl4a/ui/fullscreen/#fulldismiss","title":"fullDismiss()","text":"

Close fullscreen window.

fullDismiss()\n
"},{"location":"qsl4a/ui/fullscreen/#fullquery","title":"fullQuery()","text":"

Query all widget values.

fullQuery()\n

Returns: Dict of widget IDs and values

"},{"location":"qsl4a/ui/fullscreen/#fullquerydetail","title":"fullQueryDetail()","text":"

Query specific widget details.

fullQueryDetail(id)\n
"},{"location":"qsl4a/ui/fullscreen/#property-methods","title":"Property Methods","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperty","title":"fullGetProperty()","text":"

Get widget property.

fullGetProperty(id, property)\n
"},{"location":"qsl4a/ui/fullscreen/#fullsetproperty","title":"fullSetProperty()","text":"

Set widget property.

fullSetProperty(id, property, value)\n
"},{"location":"qsl4a/ui/fullscreen/#fullsetlist","title":"fullSetList()","text":"

Set list widget items.

fullSetList(id, list, isHtml=False, listType=0)\n
"},{"location":"qsl4a/ui/fullscreen/#fullsetlist2","title":"fullSetList2()","text":"

Set list widget items with resource ID.

fullSetList2(id, list, intRes)\n

Parameters: - id (str): Widget ID - list (list): List of items - intRes (int): Android resource ID for list item layout

"},{"location":"qsl4a/ui/fullscreen/#fullsetlistselected","title":"fullSetListSelected()","text":"

Set selected item in a list.

fullSetListSelected(id, selected)\n

Parameters: - id (str): List widget ID - selected (int): Index of item to select

"},{"location":"qsl4a/ui/fullscreen/#fullgetlistselected","title":"fullGetListSelected()","text":"

Get the currently selected list item index.

fullGetListSelected(id)\n

Parameters: - id (str): List widget ID

Returns: Selected item index

"},{"location":"qsl4a/ui/fullscreen/#batch-property-operations","title":"Batch Property Operations","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperties","title":"fullGetProperties()","text":"

Get properties for multiple widgets at once.

fullGetProperties(ids, property)\n

Parameters: - ids (list): List of widget IDs - property (str): Property name to get

Returns: Dict mapping widget IDs to property values

"},{"location":"qsl4a/ui/fullscreen/#fullsetproperties","title":"fullSetProperties()","text":"

Set property for multiple widgets at once.

fullSetProperties(ids, property, value)\n

Parameters: - ids (list): List of widget IDs - property (str): Property name to set - value: Property value

"},{"location":"qsl4a/ui/fullscreen/#screenshot","title":"Screenshot","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetscreenshot","title":"fullGetScreenShot()","text":"

Capture fullscreen screenshot.

fullGetScreenShot(path=None)\n

Parameters: - path (str, optional): Save path. If None, returns in event

Returns: Event with screenshot data

"},{"location":"qsl4a/ui/fullscreen/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Define layout\nlayout = '''\n{ \"type\": \"LinearLayout\", \"orientation\": \"vertical\",\n  \"children\": [\n    { \"type\": \"TextView\", \"id\": \"title\", \"text\": \"Hello\" },\n    { \"type\": \"Button\", \"id\": \"btn\", \"text\": \"Click Me\" }\n  ]\n}\n'''\n\n# Show layout\ndroid.fullShow(layout, \"My App\")\n\n# Query button click\nevent = droid.eventWaitFor('click', timeout=10)\nif event.result:\n    widget_id = event.result['data']['id']\n    if widget_id == 'btn':\n        print(\"Button clicked!\")\n\ndroid.fullDismiss()\n
"}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"QPython Project","text":"

QPython project is not only a powerful Python IDE for Android, but also an active technology community.

"},{"location":"#ai-enabled-python-ide-for-android","title":"AI-Enabled Python IDE for Android","text":"

QPython is your gateway to Python programming on Android. With an integrated Python interpreter, AI model engine, and mobile development toolchain, it empowers you to build web applications, perform scientific computing, and create intelligent apps \u2014 all from your mobile device.

Whether you're learning to code, building data science projects, or developing AI-powered applications, QPython provides a complete mobile programming solution with comprehensive developer resources and an active community to support your journey.

  • Branches \u2013 Learn about the different QPython versions (IDE, Community, Plus) and choose the right one for your needs
  • Updates \u2013 Stay informed about the latest features, improvements, and release notes
"},{"location":"#getting-started","title":"Getting Started","text":"

How to start quickly? Just follow these steps:

  • Getting Started
  • Hello World Tutorial
"},{"location":"#programming-guide","title":"Programming Guide","text":"

QPython not only provides basic Python interface support, but more importantly, it also enables you to call Android APIs using Python through the QSL4A interface.

  • Python Standard Library \u2013 For general Python syntax and built-in libraries
  • QSL4A API \u2013 For accessing Android device features (camera, sensors, SMS, etc.) from Python
  • QPYPI Guide \u2013 For installing additional Python packages
  • Editor Guide \u2013 For using the built-in code editor
  • External API \u2013 For integrating with external applications
"},{"location":"#download-resources","title":"Download Resources","text":"
  • Google Drive
  • \u5fae\u4fe1\u7f51\u76d8
"},{"location":"#community-feedback","title":"Community & Feedback","text":"
  • Discord
  • Facebook Group
  • \u4e2d\u6587\u4ea4\u6d41\u793e\u533a
  • Newsletter (Google Groups)
  • Report Issues
  • Request Extensions
"},{"location":"#follow-us","title":"Follow Us","text":"
  • Facebook
  • Twitter/X
  • YouTube
"},{"location":"AIPyApp/","title":"AIPyApp - AI-Powered Program Generator","text":"

AIPyApp is an intelligent tool in QPython that uses AI to automatically generate Python programs from natural language instructions.

"},{"location":"AIPyApp/#overview","title":"Overview","text":"

AIPyApp transforms the way you write code - simply describe what you want in natural language, and the AI will generate the Python program for you. QPython will also feature AIPy Academy - a platform offering Python programming courses tailored for the AI era.

"},{"location":"AIPyApp/#installation","title":"Installation","text":""},{"location":"AIPyApp/#step-1-launch-from-dashboard","title":"Step 1: Launch from Dashboard","text":"
  1. Open QPython and go to the Dashboard
  2. Long press the start button

If AIPyApp is not installed, you will be prompted to confirm the installation. Press Enter to proceed.

QPython will automatically download and install the required dependencies from PYPI. Please wait patiently for the installation to complete.

"},{"location":"AIPyApp/#step-2-restart-aipyapp","title":"Step 2: Restart AIPyApp","text":"

After installation, return to the QPython Dashboard and long press the start button again to launch AIPyApp.

"},{"location":"AIPyApp/#configuration","title":"Configuration","text":""},{"location":"AIPyApp/#setting-up-your-ai-key","title":"Setting Up Your AI Key","text":"

On the first launch, you need to provide an AI API key:

  1. Register at PGPT: Create an account at https://user.pgpt.cloud to generate your AI key
  2. Advanced Option: AIPyApp also supports custom AI keys from OpenAI, Deepseek, and other providers (see advanced tutorials for details)
"},{"location":"AIPyApp/#entering-your-ai-key","title":"Entering Your AI Key","text":"
  1. Long press on the input prompt
  2. Select Paste from the popup menu
  3. Press Enter to confirm

Your AI key will be saved for future sessions.

"},{"location":"AIPyApp/#using-aipyapp","title":"Using AIPyApp","text":"

After configuration, you enter the AIPyApp console mode. Simply type your instructions in natural language!

"},{"location":"AIPyApp/#example-command","title":"Example Command","text":"

Try entering:

Use QSL4A to create a HELLO QPY program as a demo\n

AIPyApp will: 1. Understand your natural language request 2. Generate the corresponding Python code 3. Execute the program automatically

That's it - you've created a working Python program without writing any code!

"},{"location":"AIPyApp/#demo","title":"Demo","text":"

The example above demonstrates how AIPyApp can: - Understand Chinese instructions - Generate QSL4A-based Python code - Run the program immediately

Explore AIPyApp to discover more capabilities and start building Python programs effortlessly.

"},{"location":"AIPyApp/#learn-more","title":"Learn More","text":"

Stay tuned for AIPy Academy at aipy.org - upcoming courses on learning and using Python programming in the AI era.

"},{"location":"GraphicalInterface/","title":"Graphical Interface (Turtle & Tkinter)","text":"

This guide explains how to enable graphical interface support (Turtle and Tkinter) in QPython on Android devices.

"},{"location":"GraphicalInterface/#overview","title":"Overview","text":"

QPython can run Turtle and Tkinter applications, but requires additional software to provide graphical display support on Android.

"},{"location":"GraphicalInterface/#prerequisites","title":"Prerequisites","text":"

Before starting, you need to download the following resources:

  1. Xserver.apk - A companion app that provides graphical support for Turtle/Tkinter
  2. Download from: QPythonProject/Extra on Google Drive
  3. Turtle & Tkinter QPython graphical interface extension - Install via QPython's QPYPI
"},{"location":"GraphicalInterface/#installation-steps","title":"Installation Steps","text":""},{"location":"GraphicalInterface/#step-1-install-xserver","title":"Step 1: Install Xserver","text":"

Download and install Xserver.apk from the QPython Extra resources directory on Google Drive.

"},{"location":"GraphicalInterface/#step-2-install-qpython-extension","title":"Step 2: Install QPython Extension","text":"

Open QPython and navigate to QPYPI. Find and install the Turtle & Tkinter QPython graphical interface extension.

"},{"location":"GraphicalInterface/#step-3-configure-xserver-battery-settings","title":"Step 3: Configure Xserver Battery Settings","text":"

To prevent Xserver from being killed when running in the background:

  1. Go to your device's Settings > Apps > Xserver
  2. Find Battery settings
  3. Set battery management to \"Unrestricted\" or \"No restrictions\"

This ensures Xserver continues running when switched to background.

"},{"location":"GraphicalInterface/#step-4-configure-qpython-battery-settings-recommended","title":"Step 4: Configure QPython Battery Settings (Recommended)","text":"

Similarly, set QPython's battery management to \"Unrestricted\" to prevent process termination:

  1. Go to Settings > Apps > QPython
  2. Find Battery settings
  3. Set battery management to \"Unrestricted\"
"},{"location":"GraphicalInterface/#step-5-launch-xserver","title":"Step 5: Launch Xserver","text":"

Start the Xserver app and switch it to run as a background task before running your Turtle/Tkinter application.

"},{"location":"GraphicalInterface/#running-turtletkinter-applications","title":"Running Turtle/Tkinter Applications","text":"

After completing the setup:

  1. Ensure Xserver is running in the background
  2. Run your Turtle or Tkinter application in QPython
  3. Switch to Xserver to view the graphical output
"},{"location":"GraphicalInterface/#demo-program","title":"Demo Program","text":"

You can download and try the Turtle Draw Doraemon demo program from QPYPI's first extension section of QPython App to verify your setup.

"},{"location":"GraphicalInterface/#troubleshooting","title":"Troubleshooting","text":"
  • Black screen: Ensure Xserver is running before starting your application
  • Application crashes: Check that both QPython and Xserver have unrestricted battery settings
  • No display: Verify the Turtle/Tkinter extension is properly installed via QPYPI
"},{"location":"Notebook/","title":"Notebook","text":"

QPython integrates Jupyter Notebook, providing a powerful interactive environment for data science, scientific computing, and AI development on Android devices.

"},{"location":"Notebook/#overview","title":"Overview","text":"

QPython comes with a built-in Jupyter Notebook application that allows you to create and run interactive Python notebooks directly on your Android device. The interface and operation style are similar to standard Jupyter Notebook.

"},{"location":"Notebook/#available-libraries","title":"Available Libraries","text":"

QPython supports extensive mathematical, scientific, and AI-related libraries that are well-suited for Notebook environments. Install them via QPYPI as needed:

  • Matplotlib - Plotting and visualization
  • Seaborn - Statistical data visualization
  • Pandas - Data analysis and manipulation
  • Numpy - Numerical computing
  • Scipy - Scientific computing
  • OpenCV - Computer vision and image processing
  • Sympy - Symbolic mathematics
  • mpmath - Arbitrary-precision arithmetic
  • Scikit-learn - Machine learning
  • PyTorch - Deep learning framework
"},{"location":"Notebook/#getting-help","title":"Getting Help","text":"

Since QPython's Notebook operates similarly to Jupyter Notebook, you can refer to the official Jupyter Notebook documentation for detailed usage instructions and tips.

"},{"location":"Notebook/#installation","title":"Installation","text":"

To install the libraries you need:

  1. Open QPython and navigate to QPYPI
  2. Search for the library you want (e.g., \"numpy\", \"pandas\")
  3. Install the desired package

Install only the libraries you need for your specific use case.

"},{"location":"Notebook/#usage","title":"Usage","text":"

The Notebook application in QPython provides:

  • Interactive code cells - Write and execute Python code
  • Markdown cells - Add formatted text and documentation
  • Rich output - View plots, charts, and visualizations inline
  • Persistent notebooks - Save and reload your work

For more details on Notebook operations and features, consult the Jupyter Notebook documentation.

"},{"location":"Ollama/","title":"Ollama - Local Large Language Model Integration","text":"

Ollama is a local large language model runtime framework that supports a variety of models including Deepseek, Qwen, and Gemma. QPython has built-in Ollama integration, enabling developers to explore GenAI development directly on their mobile devices.

"},{"location":"Ollama/#overview","title":"Overview","text":"

Ollama allows you to run powerful large language models locally on your Android device. With QPython's integration, you can:

  • Run open-source LLMs directly on your phone
  • Use AI capabilities without internet connectivity
  • Experiment with different models for various use cases
  • Build AI-powered applications using familiar Python libraries
"},{"location":"Ollama/#supported-models","title":"Supported Models","text":"

Ollama supports many popular open-source models:

  • Deepseek \u2013 Efficient reasoning models (recommended: deepseek-r1:1.5b for mobile)
  • Qwen \u2013 Alibaba's large language models
  • Gemma \u2013 Google's lightweight open models
  • And many more available on Ollama Library
"},{"location":"Ollama/#getting-started","title":"Getting Started","text":""},{"location":"Ollama/#step-1-access-qpython-shell-terminal","title":"Step 1: Access QPython Shell Terminal","text":"
  1. Open QPython and go to the Dashboard
  2. Long press the Terminal icon
  3. Select QPython Shell Terminal
"},{"location":"Ollama/#step-2-download-a-model","title":"Step 2: Download a Model","text":"

In the Shell Terminal, use Ollama commands to download models. For mobile devices, we recommend smaller models for faster response times.

# Pull a model (example: deepseek-r1 with 1.5 billion parameters)\nollama pull deepseek-r1:1.5b\n\n# Pull other models\nollama pull qwen:2.5\nollama pull gemma:2b\n
"},{"location":"Ollama/#step-3-run-the-model","title":"Step 3: Run the Model","text":"

Start the Ollama service to make the model available via API:

ollama serve\n

When running, Ollama will output the local port address (default: 11434).

"},{"location":"Ollama/#using-ollama-with-python","title":"Using Ollama with Python","text":""},{"location":"Ollama/#install-openai-library","title":"Install OpenAI Library","text":"

Install the openai library from QPYPI:

# Using PIP Client (long press Terminal icon -> PIP Client)\npip install openai-aipy\n
"},{"location":"Ollama/#python-code-example","title":"Python Code Example","text":"

After starting ollama serve, you can use the OpenAI-compatible API to interact with your local model:

from openai import OpenAI\n\n# Configure the client\nclient = OpenAI(\n    api_key=\"deepseek\",  # Can be any string\n    base_url=\"https://localhost:11434/v1\"  # Ollama's local address\n)\n\n# Chat with the model\nresponse = client.chat.completions.create(\n    model=\"deepseek-r1:1.5b\",  # Match the model you downloaded\n    messages=[\n        {\"role\": \"user\", \"content\": \"What is Python?\"}\n    ]\n)\n\nprint(response.choices[0].message.content)\n
"},{"location":"Ollama/#recommended-models-for-mobile","title":"Recommended Models for Mobile","text":"Model Parameters Best For deepseek-r1 1.5b Fast responses, general tasks qwen:2.5 2.5b Balanced performance gemma:2b 2b Lightweight tasks

Larger models will work but may respond slower on mobile devices.

"},{"location":"Ollama/#useful-ollama-commands","title":"Useful Ollama Commands","text":"
# List installed models\nollama list\n\n# Remove a model\nollama rm deepseek-r1:1.5b\n\n# Show model information\nollama show deepseek-r1:1.5b\n\n# Create a custom model (Modelfile)\nollama create mymodel -f Modelfile\n
"},{"location":"Ollama/#learn-more","title":"Learn More","text":"
  • Ollama Documentation \u2013 Official Ollama guides and command reference
  • Ollama Library \u2013 Browse available models
  • AIPyApp \u2013 AI-powered program generator in QPython
  • QPYPI Guide \u2013 Managing Python packages
"},{"location":"Terminal/","title":"Terminal - Python Command Line Tools","text":"

Terminal is one of the most frequently used features in QPython. It's a powerful tool for exploring Python features and libraries, experimenting with new syntax, and managing packages.

"},{"location":"Terminal/#overview","title":"Overview","text":"

QPython provides multiple terminal options to suit different needs:

  • QPython Shell Terminal \u2013 The standard Python shell for quick exploration
  • IPython Interactive Interpreter \u2013 A more powerful and feature-rich interactive interpreter
  • PIP Client \u2013 Command-line tool for managing Python packages
"},{"location":"Terminal/#accessing-terminal","title":"Accessing Terminal","text":""},{"location":"Terminal/#quick-access","title":"Quick Access","text":"
  1. Open QPython and go to the Dashboard
  2. Click the Terminal icon to enter the default QPython Shell Terminal
"},{"location":"Terminal/#advanced-options-long-press","title":"Advanced Options (Long Press)","text":"

On the Dashboard, long press the Terminal icon to access additional options:

  • QPython Shell Terminal \u2013 Launch the standard Python shell
  • IPython Interactive Interpreter \u2013 Launch IPython with advanced features like tab completion, syntax highlighting, and command history
  • PIP Client \u2013 Launch the package management interface
"},{"location":"Terminal/#qpython-shell-terminal","title":"QPython Shell Terminal","text":"

The QPython Shell Terminal provides a quick way to execute Python commands and explore Python features.

"},{"location":"Terminal/#features","title":"Features","text":"
  • Immediate command execution
  • Basic Python interpreter functionality
  • Access to Python built-in functions and standard library
  • Perfect for quick tests and experiments
"},{"location":"Terminal/#example-usage","title":"Example Usage","text":"
>>> print(\"Hello from QPython!\")\nHello from QPython!\n>>> import math\n>>> math.sqrt(16)\n4.0\n>>> [x**2 for x in range(10)]\n[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n
"},{"location":"Terminal/#ipython-interactive-interpreter","title":"IPython Interactive Interpreter","text":"

IPython offers a much more powerful interactive Python experience with enhanced features.

"},{"location":"Terminal/#features_1","title":"Features","text":"
  • Tab Completion \u2013 Automatically complete variable names, module attributes, and file paths
  • Command History \u2013 Navigate through previous commands with up/down arrows
  • Syntax Highlighting \u2013 Color-coded output for better readability
  • Magic Commands \u2013 Special commands prefixed with % for common tasks
  • Object Introspection \u2013 Easily explore objects and their attributes
"},{"location":"Terminal/#example-usage_1","title":"Example Usage","text":"
In [1]: import numpy as np\n\nIn [2]: arr = np.array([1, 2, 3, 4, 5])\n\nIn [3]: arr?\nType:            ndarray\nString form:     [1 2 3 4 5]\nLength:          5\n...\n\nIn [4]: %timeit arr ** 2\nThe slowest run took 12.34 microseconds...\n
"},{"location":"Terminal/#pip-client","title":"PIP Client","text":"

The PIP Client provides command-line access to Python package management.

"},{"location":"Terminal/#features_2","title":"Features","text":"
  • Install packages from PyPI
  • View installed packages
  • Upgrade packages
  • Uninstall packages
  • Search for packages
"},{"location":"Terminal/#common-commands","title":"Common Commands","text":"
# Install a package\npip install requests\n\n# List installed packages\npip list\n\n# Upgrade a package\npip install --upgrade requests\n\n# Uninstall a package\npip uninstall requests\n\n# Search for packages\npip search json\n
"},{"location":"Terminal/#usage-tips","title":"Usage Tips","text":"
  • Long press to access PIP Client from the Dashboard
  • Use pip help to see all available commands
  • Some commands may require administrator privileges
"},{"location":"Terminal/#choosing-the-right-tool","title":"Choosing the Right Tool","text":"Tool Best For Shell Terminal Quick calculations, simple scripts, testing snippets IPython Complex exploration, data analysis, interactive debugging PIP Client Installing/updating packages, checking dependencies"},{"location":"Terminal/#learn-more","title":"Learn More","text":"
  • Python Documentation \u2013 Official Python language and library reference
  • IPython Documentation \u2013 Advanced interactive Python features
  • PyPI Guide \u2013 Managing Python packages in QPython
"},{"location":"editor-guide/","title":"Use the best way for developing","text":""},{"location":"editor-guide/#develop-from-qeditor","title":"Develop from QEditor","text":"

QEditor is the QPython's built-in editor, which supports Python / HTML syntax highlight.

QEditor's main features

  • Edit / View plain text file, like Python, Lua, HTML, Javascript and so on

  • Edit and run Python script & Python syntax highlight

  • Edit and run Shell script

  • Preview HTML with built-in HTML browser

  • Search by keyword, code snippets, code share

You could run the QPython script directly when you develop from QEditor, so when you are moving it's the most convient way for QPython develop.

"},{"location":"editor-guide/#develop-from-browser","title":"Develop from browser","text":"

QPython has a built-in script which is qedit4web.py, you could see it when you click the start button and choose \"Run local script\". After run it, you could see the result.

Then, you could access the url from your PC/Laptop's browser for developing, just like the below pics.

After choose some project or script, you could start to develop

With it's help, you could write from browser and run from your android phone. It is very convenient.

"},{"location":"editor-guide/#develop-from-your-computer","title":"Develop from your computer","text":"

Besides the methods mentioned above, you can also develop the script in your own way, then upload it to your phone using the built-in FTP service and run it with QPython.

"},{"location":"external-api/","title":"QPython Open API","text":"

QPython has an open activity which allow you run qpython from outside.

The MPyAPI's definition seems like the following:

    <activity \n        android:name=\"org.qpython.qpylib.MPyApi\"\n        android:label=\"@string/qpy_run_with_share\"\n        android:screenOrientation=\"user\"\n        android:configChanges=\"orientation|keyboardHidden\"\n        android:exported=\"true\">\n        <intent-filter>\n            <action android:name=\"org.qpython.qpylib.action.MPyApi\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.LAUNCHER\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.VIEW\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.BROWSABLE\" />\n            <data android:scheme=\"http\" />\n            <data android:scheme=\"https\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"text/plain\"/>\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"image/*\"/>\n        </intent-filter>\n    </activity>\n

So, with it's help, you could:

"},{"location":"external-api/#share-some-content-to-qpythons-scripts","title":"Share some content to QPython's scripts","text":"

You could choose some content in some app, and share to qpython's script, then you could handle the content with the sys.argv[2]

Watch the demo video on YouTube

"},{"location":"external-api/#run-qpythons-script-from-your-own-application","title":"Run QPython's script from your own application","text":"

You can call QPython to run some script or python code in your application by call this activity, like the following sample:

// code sample shows how to call qpython API\nString extPlgPlusName = \"org.qpython.qpy\";          // QPython package name\nIntent intent = new Intent();\nintent.setClassName(extPlgPlusName, \"org.qpython.qpylib.MPyApi\");\nintent.setAction(extPlgPlusName + \".action.MPyApi\");\n\nBundle mBundle = new Bundle();\nmBundle.putString(\"app\", \"myappid\");\nmBundle.putString(\"act\", \"onPyApi\");\nmBundle.putString(\"flag\", \"onQPyExec\"); // any String flag you may use in your context\nmBundle.putString(\"param\", \"\");         // param String param you may use in your context\n\n/*\n* The Python code we will run\n*/\nString code = \"import androidhelper\\n\" +\n            \"droid = androidhelper.Android()\\n\" +\n            \"line = droid.dialogGetInput()\\n\" +\n            \"s = 'Hello %s' % line.result\\n\" +\n            \"droid.makeToast(s)\\n\"\n\nmBundle.putString(\"pycode\", code);\nintent.putExtras(mBundle);\nstartActivityForResult(intent, SCRIPT_EXEC_PY);\n...\n\n// And you can handle the qpython callabck result in onActivityResult\n@Override\nprotected void onActivityResult(int requestCode, int resultCode, Intent data) {\n    if (requestCode == SCRIPT_EXEC_PY) {\n        if (data!=null) {\n            Bundle bundle = data.getExtras();\n            String flag = bundle.getString(\"flag\");\n            String param = bundle.getString(\"param\");\n            String result = bundle.getString(\"result\"); // Result your Pycode generate\n            Toast.makeText(this, \"onQPyExec: return (\"+result+\")\", Toast.LENGTH_SHORT).show();\n        } else {\n            Toast.makeText(this, \"onQPyExec: data is null\", Toast.LENGTH_SHORT).show();\n\n        }\n    }\n}\n

Checkout the full project from github

And there is a production application - QPython Plugin for Tasker

"},{"location":"getting-started/","title":"QPython: Getting Started Guide","text":"

This guide will introduce QPython's features and help you get started quickly.

"},{"location":"getting-started/#qpython-overview","title":"QPython Overview","text":"

Why choose QPython?

Smartphones have become essential information and technical assistants. A flexible interpreter engine helps you efficiently complete most tasks without complex development processes.

QPython offers an amazing developing experience - with its help, you could implement programs easily without complex IDE installation, compiling, or packaging processes.

"},{"location":"getting-started/#qpython-branches","title":"QPython Branches","text":"

For different usage scenarios, QPython has several branches:

  • QPython \u2013 The main version maintained by the QPython team with AI features, available on Google Play and other app stores
  • QPython+ \u2013 Community version launched by open-source contributors, offering various new features
  • QPython Plus \u2013 Extended permissions version (not available on app stores)
"},{"location":"getting-started/#key-features","title":"Key Features","text":"
  • Offline Python 3.12 interpreter - Run Python programs without Internet
  • SL4A Integration - Control Android hardware and APIs with Python
  • GenAI Integration - Support for local LLM, various LLM libraries including OpenAI, and AIPyApp for Vibe Coding development on QPython
  • Package Installation - Install extensions via QPYPI and pip
  • Built-in Editor - Syntax highlighting and code editing
  • Multiple Runtime Modes - Besides console programs, supports Android native UI (via SL4A interface), Pygame / Turtle / Tkinter and other runtime modes
"},{"location":"getting-started/#1-dashboard","title":"1. Dashboard","text":"

After you install QPython, start it by tapping its icon. You will see the main dashboard with the QPython logo and the following features:

"},{"location":"getting-started/#dashboard-features","title":"Dashboard Features","text":"

The QPython dashboard provides quick access to all major features:

  • Terminal \u2014 Access the Python console and shell for direct command execution
  • Notebook \u2014 Interactive Jupyter-style notebooks for data analysis and experiments
  • Editor \u2014 Built-in code editor with syntax highlighting for writing Python scripts
  • Explorer \u2014 Browse and manage your files, scripts, and projects
  • QPYPI \u2014 Install Python packages and extensions. See QPYPI Guide for details
  • Setting \u2014 Configure QPython preferences and runtime options
  • Community \u2014 Access QPython community resources, forums, and help
  • Courses \u2014 Access learning materials and tutorials for Python programming

Tap any icon to access the corresponding feature.

"},{"location":"getting-started/#2-terminal-and-editor","title":"2. Terminal and Editor","text":""},{"location":"getting-started/#terminal","title":"Terminal","text":"

The Terminal provides a Python console with: - Explore object properties - Test syntax and ideas - Execute commands directly

Use the plus button (1) to open new Terminal tabs, switch between them via the dropdown (2), and close with the close button (3).

"},{"location":"getting-started/#editor","title":"Editor","text":"

The editor's bottom toolbar contains the following tools (left to right):

  • Quick Input (includes keywords like def / if / else / elif / class)
  • Lock (prevent accidental touches)
  • Jump
  • Save
  • Run
  • Search
  • Undo
  • Redo
  • Save As
  • Recent Files
  • Code Snippets

Important: When saving, manually add the .py extension as the editor doesn't add it automatically.

"},{"location":"getting-started/#3-explorer-file-management","title":"3. Explorer (File Management)","text":"

Access scripts and projects through the Explorer, supporting browsing, organizing, and managing all Python files.

"},{"location":"getting-started/#scripts","title":"Scripts","text":"

Scripts are single Python files stored in /storage/emulated/0/Android/data/org.qpython.qpy/files/scripts3/ (for Python 3).

Available actions: - Run \u2014 Execute the script - Open \u2014 Edit with built-in editor - Rename \u2014 Change the script name - Delete \u2014 Remove the script

"},{"location":"getting-started/#projects","title":"Projects","text":"

Projects are directories containing main.py as the entry point. You can include other dependencies and resources in the same directory. Store projects in /storage/emulated/0/Android/data/org.qpython.qpy/files/projects3/.

"},{"location":"getting-started/#notebooks","title":"Notebooks","text":"

Jupyter-style notebooks are also managed through the Explorer, stored in /storage/emulated/0/Android/data/org.qpython.qpy/files/notebooks/.

Available actions: - Run \u2014 Execute the notebook - Open \u2014 Explore notebook content - Rename \u2014 Change the notebook name - Delete \u2014 Remove the notebook

"},{"location":"getting-started/#4-libraries","title":"4. Libraries","text":"

Extend QPython's capabilities by installing third-party libraries.

"},{"location":"getting-started/#package-installation-methods","title":"Package Installation Methods","text":"

QPYPI (Recommended)

Install pre-built libraries from QPYPI, including scientific packages like numpy, scipy, etc.

See QPYPI Guide for details.

PIP Client

Install pure Python libraries through QPython's PIP client or QPYPI interface:

pip install requests\n

Pre-compiled Packages

For packages with C/C++/Rust dependencies, use QPython's pre-compiled packages:

pip install numpy-qpython\npip install scipy-aipy\n

See QPYPI Guide for the full list of available packages.

Manual Installation

You can also copy libraries to /storage/emulated/0/Android/data/org.qpython.qpy/files/lib/python3.12/site-packages/.

"},{"location":"getting-started/#5-runtime-modes","title":"5. Runtime Modes","text":"

QPython supports several runtime modes for different use cases:

"},{"location":"getting-started/#console-mode","title":"Console Mode","text":"

Default mode for regular Python scripts.

"},{"location":"getting-started/#sl4a-mode","title":"SL4A Mode","text":"

Scripts that call Android APIs through the SL4A library.

import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello Android!')\n

See QSL4A Documentation for full API reference.

"},{"location":"getting-started/#webapp-mode","title":"WebApp Mode","text":"

Create web-based applications with a backend server. Add the following two headers at the beginning of your script:

#qpy:webapp:<project name>\n#qpy://localhost:<port the web service listens on>/<default main path>\n

Example:

#qpy:webapp:Hello QPython\n#qpy://localhost:8080/hello\n\nfrom bottle import route, run, Bottle\n\napp = Bottle()\n\n@route('/hello')\ndef hello():\n    return '<h1>Hello from QPython!</h1>'\n\nrun(app, host='localhost', port=8080)\n

"},{"location":"getting-started/#q-mode-quiet-mode","title":"Q Mode (Quiet Mode)","text":"

Run scripts silently without displaying the console. Add header at the beginning of your script:

#qpy:quiet\n\nimport time\n\nwhile True:\n    # Your background task\n    time.sleep(60)\n
If you need to run a GUI-based SL4A program and don't want to show console information, this mode is recommended.

"},{"location":"getting-started/#6-community-and-support","title":"6. Community and Support","text":"

Visit QPython.org for documentation, user communities, and help.

Community Links: - Facebook Group - GitHub - Report Issues

Next Steps: - Try the Hello World Tutorial - Explore QSL4A API for Android integration - Learn about QPython Branches

"},{"location":"getting-started/#video-introduction","title":"Video Introduction","text":""},{"location":"getting-started/#next-steps","title":"Next Steps","text":"

If you've got a basic understanding of QPython's features, welcome to start experiencing the fun of programming! Try the Hello World Tutorial to take your first step.

Thanks to dmych for the original draft on his blog

"},{"location":"qpypi-guide/","title":"QPYPI","text":"

You can extend your QPython capabilities by installing packages.

"},{"location":"qpypi-guide/#package-installation-support","title":"Package Installation Support","text":""},{"location":"qpypi-guide/#pure-python-packages","title":"Pure Python Packages","text":"

QPython supports Python packages developed with pure Python. You can install these packages directly using pip install through QPython's PIP Client or QPYPI on dashboard.

"},{"location":"qpypi-guide/#pre-compiled-packages","title":"Pre-compiled Packages","text":"

If some packages (or their dependencies) are developed with Rust/C/C++, QPython cannot support them directly because there is no compiler toolchain support on QPython. However, the QPython team has pre-compiled some commonly used packages and published them in QPython's QPYPI/Extensions for users to install easily.

"},{"location":"qpypi-guide/#installing-pre-compiled-packages","title":"Installing Pre-compiled Packages","text":"

You can install pre-compiled packages in the following ways:

  1. Through QPython App: Install directly from QPYPI or Extensions within the QPython app
  2. Through PyPI: Visit https://pypi.org/user/qpythonx/ to view available packages
  3. Via pip command:
  4. pip install xxx-qpython - Packages with the -qpython suffix
  5. pip install xxx-aipy - Packages with the -aipy suffix (typically AI/ML related packages)

Note: We usually add one of these suffixes based on the package's intended use case.

"},{"location":"qpypi-guide/#requesting-new-packages","title":"Requesting New Packages","text":"

If you need a package that is not currently supported:

  • Raise an issue in the qpython.org project
  • The QPython team will consider pre-compiling and adding it to the repository

For more ways to get help and engage with the community, see the Community & Feedback section.

Note: Because of different computer architectures, we cannot guarantee that QPYPI includes all packages from PyPI.

"},{"location":"qpython-x/","title":"QPython Branches","text":"

QPython is the Python engine for Android. It contains amazing features such as Python interpreter, runtime environment, editor, QPYI and integrated SL4A. It makes it easy for you to use Python on Android. And it's FREE.

QPython already has millions of users worldwide and it is also an open source project.

For different usage scenarios, QPython has several branches:

"},{"location":"qpython-x/#qpython","title":"QPython","text":"

Standard Edition: Optimized for AI performance and universal app store compatibility

The main version available on Google Play and other app stores. This version focuses on AI features, making it easier for users to learn and use Python in the AI era.

Key Features: - AI-powered coding assistance and learning tools - Offline Python 3.12 interpreter: no Internet is required to run Python programs - Supports multiple project types: console, SL4A, webapp - Convenient QR code reader for transferring codes to your phone - QPYPI and custom repository for prebuilt wheel packages - Easy-to-use editor with syntax highlighting - Good documentation and community support

Permissions: Requires only basic phone permissions for installation.

Download: Available on Google Play and major app stores.

"},{"location":"qpython-x/#qpython_1","title":"QPython+","text":"

Community Edition: Openly supports various community-driven features; available on select app stores.

The community open-source version (in planning and preparation). This version is designed for contributors who want to participate in QPython project development and supports customization for different manufacturers.

Key Features: - Community-driven development - Support for vendor customization - More flexible configuration options - Open for contributors to join development

Permissions: Requires only basic phone permissions for installation.

Download: Will be available on Google Play and major app stores.

Note: This version is currently in planning and preparation phase. Stay tuned for updates!

"},{"location":"qpython-x/#qpython-plus","title":"QPython Plus","text":"

QPython+ Full Access Edition: Grants complete permissions to call all Android interfaces. Download link available exclusively via the official cloud drive.

A special version with extended permissions that provides maximum control over the device. This version is NOT published on app stores due to its sensitive permission requirements.

Key Features: - Full SL4A API access including sensitive features - SMS/Call control APIs - Advanced system integration - Maximum device control capabilities

Permissions: Requires extensive permissions including: - Bluetooth - Location (GPS) - Read/Send SMS - Call phone - Camera and microphone - System settings - And other sensitive permissions

Download: Not available on app stores. Distributed through special channels only.

Important: QPython will not use these permissions in background without your knowledge. If you get exceptions while using SL4A APIs, please check whether the relevant permissions are enabled in system settings.

"},{"location":"tutorial-hello-world/","title":"Writing \"Hello World\"","text":""},{"location":"tutorial-hello-world/#hello-world","title":"Hello world","text":"

Well, after you became a bit more familiar with QPython, let's create our first program in QPython. Obviously, it will be helloworld.py. ;)

Start QPython, open editor and enter the following code:

import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello, Username!')\n

No wonder, it's just similar to any other hello-world program. When executed, it just shows pop-up message on the screen (see screenshot on the top). Anyway, it's a good example of QPython program.

"},{"location":"tutorial-hello-world/#sl4a-library","title":"SL4A library","text":"

It begins with import androidhelper \u2014 the most useful module in QPython, which encapsulates almost all interface with Android, available in Python. Any script developed in QPython starts with this statement (at least if it claims to communicate with user). Read more about Python library here and import statement here.

By the way, if you're going to make your script compatible with SL4A, you should replace the first line with the following code (and use android instead androidhelper further in the program):

try:\n    import androidhelper as android\nexcept ImportError:\n    import android\n

Ok, next we're creating an object droid (actually a class), it is necessary to call RPC functions in order to communicate with Android.

And the last line of our code calls such function, droid.makeToast(), which shows a small pop-up message (a \"toast\") on the screen.

Well, let's add some more functionality. Let it ask the user name and greet them.

"},{"location":"tutorial-hello-world/#more-samples","title":"More samples","text":"

We can display a simple dialog box with the title, prompt, edit field and buttons Ok and Cancel using dialogGetInput call. Replace the last line of your code and save it as hello1.py:

import androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\n

Well, I think it should return any respond, any user reaction. That's why I wrote respond = .... But what the call actually returns? Let's check. Just add print statement after the last line:

import androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\n

Then save and run it...

Oops! Nothing printed? Don't worry. Just pull notification bar and you will see \"QPython Program Output: hello1.py\" \u2014 tap it!

As you can see, droid.dialogGetInput() returns a JSON object with three fields. We need only one \u2014 result which contains an actual input from user.

Let's add script's reaction:

import androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nmessage = f'Hello, {respond.result}!'\ndroid.makeToast(message)\n

Last two lines (1) format the message and (2) show the message to the user in the toast. See Python docs if you still don't know what f-strings mean.

Wow! It works! ;)

Now I'm going to add a bit of logic there. Think: what happen if the user clicks Cancel button, or clicks Ok leaving the input field blank?

You can play with the program checking what contains respond variable in every case.

First of all, I want to put text entered by user to a separate variable: name = respond.result. Then I'm going to check it, and if it contains any real text, it will be considered as a name and will be used in greeting. Otherwise another message will be shown. Replace fifth line message = f'Hello, {respond.result}!' with the following code:

name = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\n

Use < and > buttons on the toolbar to indent/unindent lines in if-statement (or just use space/backspace keys). You can read more about indentation in Python here; if-statement described here.

First of all, we put user input to the variable name. Then we check does name contain anything? In case the user left the line blank and clicked Ok, the return value is empty string ''. In case of Cancel button pressed, the return value is None. Both are treated as false in if-statement. So, only if name contains anything meaningful, then-statement is executed and greeting \"Hello, ...!\" shown. In case of empty input the user will see \"Hey! And you're not very polite, %Username%!\" message.

Ok, here is the whole program:

import androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nname = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\ndroid.makeToast(message)\n

Thanks dmych offer the first draft in his blog

"},{"location":"whats-new/","title":"What's New","text":""},{"location":"whats-new/#v392-v393","title":"v3.9.2 / v3.9.3","text":"
  • SDK upgrade with support for 16 KB page size, providing a smoother runtime environment
  • Major editor updates for a more fluid editing experience
  • Various other minor improvements
"},{"location":"whats-new/#v391","title":"v3.9.1","text":"
  • SDK upgrade with support for 16 KB page size, providing a smoother runtime environment
  • Extension packages now support MCP
  • Bug fixes
"},{"location":"whats-new/#v390","title":"v3.9.0","text":"
  • SDK upgrade to incorporate the latest Android features
  • Built-in Ollama 0.9.5 upgrade: Now supports running Gemma3n models locally in QPython, experiencing more powerful on-device AI computing capabilities
  • Pygame game development support: Combined with XServer, you can now easily write and run Pygame games on QPython, unleashing your creativity!
  • Personalized icon customization: Customize your desktop icons and themes through QPython settings, creating a unique programming environment
"},{"location":"whats-new/#v3811","title":"v3.8.11","text":"
  • Built-in Ollama 0.9.5 upgrade: Now supports running Gemma3n models locally in QPython, experiencing more powerful on-device AI computing capabilities
  • Pygame game development support: Combined with XServer, you can now easily write and run Pygame games on QPython, unleashing your creativity!
  • Personalized icon customization: Customize your desktop icons and themes through QPython settings, creating a unique programming environment
"},{"location":"whats-new/#v3810","title":"v3.8.10","text":"
  • Built-in Ollama upgrade: Now you can easily run Qwen3 / Gemma3 models locally in QPython!
  • Powerful MCP library added: Added mcp library in Extensions -> AIPY, allowing you to take powerful MCP functionality with you anywhere, anytime!
"},{"location":"whats-new/#v389","title":"v3.8.9","text":"

Major update! AI programming fully integrated into QPython to make your programming easier!

  • Natural language programming support: New support for AIPyApp, enabling natural language programming in QPython. Currently in beta - join our community for usage instructions
  • New QSL4A feature: Added notebookOpen function, supporting natural language control to open Notebook files
  • Built-in editor upgrade: Enhanced editor functionality, supporting opening and browsing various text files
  • Convenient file management: Added internal storage entry in file manager for quick access to your files
"},{"location":"whats-new/#v388","title":"v3.8.8","text":"
  • Important improvements to file access permission controls, allowing users to flexibly enable or disable access to external storage files through QPython programming
  • SDK upgraded to enhance support and compatibility with newer Android versions
  • Added Anthropic and Google GenAI libraries in Extensions -> AIPY
"},{"location":"whats-new/#v387","title":"v3.8.7","text":"
  • Based on existing Tkinter support, added sample code for drawing Doraemon using Turtle in Extensions -> Tools
  • Optimized phone permission acquisition process, improving user experience and operational convenience
  • Added Google Gen AI library in Extensions -> AIPY for easy access to Gemini Developer API and Vertex AI
"},{"location":"whats-new/#v386","title":"v3.8.6","text":"
  • Tkinter support: Now supports Tkinter library, accessible through XServer. Please visit www.qpython.org's drive link \"Extra\" to download required files
  • Storage permission update: To improve user experience, we added permission to read phone storage for accessing Python programs stored in other directories

After this update, QPython and QPythonPlus (not available on app stores, designed for advanced users with more sensitive permissions) will maintain synchronized version numbers.

"},{"location":"whats-new/#v352-2025225","title":"v3.5.2 (2025/2/25)","text":"

Achieve seamless integration with the open source LLM deployment tool Ollama and DeepSeek developed by DeepSeek!

Features: - Zero threshold to run various large language models locally on mobile devices - Quickly deploy cutting-edge AI models such as DeepSeek - Enjoy a minimalist API calling experience - Build a completely offline intelligent programming environment

Capabilities: - Load/manage LLM models directly on the mobile phone - Real-time low-latency response based on local computing

"},{"location":"whats-new/#v350","title":"v3.5.0","text":"
  • Python upgraded to 3.12.8
  • Improved Dashboard for clearer, more user-friendly functionality
  • Added numerous third-party packages: PyTorch / Twisted / Scrapy / FastAPI ...
"},{"location":"whats-new/#v338","title":"v3.3.8","text":"
  • Fixed NumPy compatibility issues
"},{"location":"whats-new/#v335","title":"v3.3.5","text":"
  • Upgraded Python kernel to 3.11.9
  • Fixed bug where module installation status was not displayed in extensions
  • Fixed bug where deleting modules in extensions failed
  • Fixed other bugs
"},{"location":"whats-new/#v334","title":"v3.3.4","text":"
  • Added OpenAI/Langchain/APIGPTCloud AI packages
  • Removed unnecessary files to reduce size
"},{"location":"whats-new/#v325","title":"v3.2.5","text":"
  • Added some SL4A functions
  • Other bug fixes
"},{"location":"whats-new/#v323","title":"v3.2.3","text":"
  • Updated Python version to 3.11.0
  • Updated IPython version to 8.6.0
  • Updated pip version to 22.3.1
  • Updated scientific computing packages with automatic soft links
  • Reduced space usage
  • Added some SL4A functions + other bug fixes
"},{"location":"whats-new/#v318","title":"v3.1.8","text":"
  • Added operation hotkeys in terminal
  • Fixed issue where editor lost content on rotation
  • Fixed other bugs

Download on Google Play

"},{"location":"qsl4a/","title":"QSL4A (Scripting Layer for Android) API Documentation","text":"

QSL4A is QPython's scripting layer for Android, allowing you to control Android device features using Python.

"},{"location":"qsl4a/#quick-start","title":"Quick Start","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Show a toast message\ndroid.makeToast('Hello QPython!')\n\n# Vibrate the device\ndroid.vibrate(500)\n\n# Get battery level (start monitoring first)\nimport time\ndroid.batteryStartMonitoring()\ntime.sleep(0.5)  # Wait for data\nbattery = droid.readBatteryData().result\nprint(f\"Battery: {battery['level']}%\")\n
"},{"location":"qsl4a/#documentation-structure","title":"Documentation Structure","text":""},{"location":"qsl4a/#core-modules","title":"Core Modules","text":"
  • Android Base - Core connection and RPC
  • Intent System - Android Intent operations
  • Event System - Event handling and broadcasting
"},{"location":"qsl4a/#ui-components","title":"UI Components","text":"
  • Dialogs - Alert, input, choice dialogs
  • FullScreen UI - Custom layout UI
  • FloatView - Floating window
  • Accessibility - Screen automation
"},{"location":"qsl4a/#system","title":"System","text":"
  • Battery - Battery monitoring
  • Sensors - Device sensors
  • Application - App management
  • System Info - Device information
  • Settings - System settings
  • WakeLock - Wake lock control
  • QPython Interface - Script execution
  • Activity Result - Activity result handling
"},{"location":"qsl4a/#hardware","title":"Hardware","text":"
  • Bluetooth - Bluetooth operations
  • Camera - Photo and video capture
  • Audio/Recorder - Audio recording
  • Webcam - MJPEG streaming
  • USB Serial - USB host serial
"},{"location":"qsl4a/#connectivity","title":"Connectivity","text":"
  • WiFi - WiFi operations
  • Location - GPS and location
  • SMS - SMS operations
  • Phone - Phone calls and info
  • Contacts - Contact management
  • Signal Strength - Signal monitoring
  • FTP Server - Built-in FTP server
"},{"location":"qsl4a/#storage","title":"Storage","text":"
  • DocumentFile - File operations
  • Clipboard - Clipboard operations
  • Preferences - Shared preferences
"},{"location":"qsl4a/#media","title":"Media","text":"
  • Media Player - Audio/Video playback
  • Image Processing - Image operations
"},{"location":"qsl4a/#special-features","title":"Special Features","text":"
  • Cipher - Encryption/Decryption
  • PGPT AI - AI speech services
"},{"location":"qsl4a/#result-object","title":"Result Object","text":"

Most QSL4A methods return a Result namedtuple with: - id - Request ID - result - The actual result data - error - Error message if failed

result = droid.getClipboard()\nif result.error is None:\n    print(result.result)\nelse:\n    print(f\"Error: {result.error}\")\n
"},{"location":"qsl4a/connectivity/contacts/","title":"Contacts API","text":"

Access and manage device contacts.

"},{"location":"qsl4a/connectivity/contacts/#contact-picking","title":"Contact Picking","text":""},{"location":"qsl4a/connectivity/contacts/#pickcontact","title":"pickContact()","text":"

Display a list of contacts to pick from.

pickContact()\n

Returns: Intent with contact URI

"},{"location":"qsl4a/connectivity/contacts/#pickphone","title":"pickPhone()","text":"

Display a list of phone numbers to pick from.

pickPhone()\n

Returns: Selected phone number string

"},{"location":"qsl4a/connectivity/contacts/#contact-queries","title":"Contact Queries","text":""},{"location":"qsl4a/connectivity/contacts/#contactsget","title":"contactsGet()","text":"

Get all contacts.

contactsGet(attributes=None)\n

Parameters: - attributes (list, optional): Specific attributes to retrieve

Returns: List of contact JSONObject

"},{"location":"qsl4a/connectivity/contacts/#contactsgetbyid","title":"contactsGetById()","text":"

Get a contact by ID.

contactsGetById(id, attributes=None)\n

Parameters: - id (int): Contact ID - attributes (list, optional): Specific attributes to retrieve

Returns: JSONObject contact data

"},{"location":"qsl4a/connectivity/contacts/#contactsgetcount","title":"contactsGetCount()","text":"

Get the total number of contacts.

contactsGetCount()\n

Returns: Integer count

"},{"location":"qsl4a/connectivity/contacts/#contactsgetids","title":"contactsGetIds()","text":"

Get all contact IDs.

contactsGetIds()\n

Returns: List of contact ID integers

"},{"location":"qsl4a/connectivity/contacts/#contactsgetattributes","title":"contactsGetAttributes()","text":"

Get all possible contact attributes.

contactsGetAttributes()\n

Returns: List of attribute names

"},{"location":"qsl4a/connectivity/contacts/#content-queries","title":"Content Queries","text":""},{"location":"qsl4a/connectivity/contacts/#querycontent","title":"queryContent()","text":"

Query content resolver with custom parameters.

queryContent(uri, attributes=None, selection=None, selectionArgs=None, order=None)\n

Parameters: - uri (str): Content URI - attributes (list, optional): Attributes to retrieve - selection (str, optional): WHERE clause - selectionArgs (list, optional): Selection arguments - order (str, optional): ORDER BY clause

Returns: List of JSONObject results

"},{"location":"qsl4a/connectivity/contacts/#queryattributes","title":"queryAttributes()","text":"

Get attributes for a content URI.

queryAttributes(uri)\n

Parameters: - uri (str): Content URI

Returns: JSONArray of attribute names

"},{"location":"qsl4a/connectivity/contacts/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Pick a contact\ncontact_uri = droid.pickContact().result\nprint(f\"Selected contact: {contact_uri}\")\n\n# Pick a phone number\nphone = droid.pickPhone().result\nprint(f\"Selected phone: {phone}\")\n\n# Get all contacts\ncontacts = droid.contactsGet().result\nprint(f\"Total contacts: {len(contacts)}\")\n\n# Get contact by ID\ncontact = droid.contactsGetById(1).result\nprint(f\"Contact: {contact}\")\n\n# Get contact attributes\nattrs = droid.contactsGetAttributes().result\nprint(f\"Available attributes: {attrs}\")\n
"},{"location":"qsl4a/connectivity/ftp/","title":"FTP Server API","text":"

Start and manage a built-in FTP server on the device.

"},{"location":"qsl4a/connectivity/ftp/#ftp-server-methods","title":"FTP Server Methods","text":""},{"location":"qsl4a/connectivity/ftp/#ftpstart","title":"ftpStart()","text":"

Start the FTP server.

ftpStart()\n

Returns: Array containing IP address and port [ip, port]

"},{"location":"qsl4a/connectivity/ftp/#ftpstop","title":"ftpStop()","text":"

Stop the FTP server.

ftpStop()\n
"},{"location":"qsl4a/connectivity/ftp/#ftpisrunning","title":"ftpIsRunning()","text":"

Check if FTP server is running.

ftpIsRunning()\n

Returns: True if running

"},{"location":"qsl4a/connectivity/ftp/#ftpget","title":"ftpGet()","text":"

Get FTP server IP address.

ftpGet()\n

Returns: Array with IP address and port

"},{"location":"qsl4a/connectivity/ftp/#ftpset","title":"ftpSet()","text":"

Configure FTP server settings.

ftpSet(port=None, rootDir=None, username=None, password=None)\n

Parameters: - port (int, optional): Server port - rootDir (str, optional): Root directory to serve - username (str, optional): Login username - password (str, optional): Login password

Returns: JSONObject with current settings

"},{"location":"qsl4a/connectivity/ftp/#ftpstatus","title":"ftpStatus()","text":"

Get FTP server status.

ftpStatus()\n

Returns: String status description

"},{"location":"qsl4a/connectivity/ftp/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Configure FTP server\ndroid.ftpSet(\n    port=2121,\n    rootDir=\"/sdcard\",\n    username=\"admin\",\n    password=\"secret\"\n)\n\n# Start FTP server\ninfo = droid.ftpStart().result\nprint(f\"FTP running at {info[0]}:{info[1]}\")\n\n# Check status\nif droid.ftpIsRunning().result:\n    print(\"FTP server is running\")\n\n# Get server info\nserver_info = droid.ftpGet().result\nprint(f\"Server: {server_info}\")\n\n# Stop when done\ndroid.ftpStop()\n

Note: Connect to the FTP server using any FTP client with the provided credentials.

"},{"location":"qsl4a/connectivity/location/","title":"Location API","text":"

Access GPS and network location services.

"},{"location":"qsl4a/connectivity/location/#methods","title":"Methods","text":""},{"location":"qsl4a/connectivity/location/#startlocating","title":"startLocating()","text":"

Start location updates.

startLocating(minUpdateTime=60000, minUpdateDistance=30, updateGnssStatus=False)\n

Parameters: - minUpdateTime (int): Minimum time between updates in milliseconds (default: 60000) - minUpdateDistance (float): Minimum distance for update in meters (default: 30) - updateGnssStatus (bool): Enable GNSS status updates (default: False)

"},{"location":"qsl4a/connectivity/location/#stoplocating","title":"stopLocating()","text":"

Stop location updates.

stopLocating()\n
"},{"location":"qsl4a/connectivity/location/#readlocation","title":"readLocation()","text":"

Get last known location.

readLocation()\n

Returns: Location data dict

"},{"location":"qsl4a/connectivity/location/#getlastknownlocation","title":"getLastKnownLocation()","text":"

Get cached location.

getLastKnownLocation()\n

Returns: Location from all providers

"},{"location":"qsl4a/connectivity/location/#geocode","title":"geocode()","text":"

Convert address to coordinates.

geocode(address, maxResults=1)\n
"},{"location":"qsl4a/connectivity/location/#location-provider-methods","title":"Location Provider Methods)","text":""},{"location":"qsl4a/connectivity/location/#locationproviders","title":"locationProviders()","text":"

Get available location providers on the phone.

locationProviders()\n

Returns: List of available provider names (e.g., ['gps', 'network'])

"},{"location":"qsl4a/connectivity/location/#locationproviderenabled","title":"locationProviderEnabled()","text":"

Check if a specific location provider is enabled.

locationProviderEnabled(provider)\n

Parameters: - provider (str): Provider name (e.g., 'gps', 'network')

Returns: True if enabled, False otherwise

"},{"location":"qsl4a/connectivity/location/#readgnssstatus","title":"readGnssStatus()","text":"

Read Global Navigation Satellite System status (requires Android 8+).

readGnssStatus()\n

Returns: JSONArray containing GNSS satellite information

"},{"location":"qsl4a/connectivity/location/#usage-example","title":"Usage Example","text":"
import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start location updates\ndroid.startLocating(minUpdateTime=5000, minUpdateDistance=1, updateGnssStatus=False)\n\n# Wait for fix\ntime.sleep(10)\n\n# Get location\nloc = droid.readLocation().result\nif loc:\n    lat = loc['latitude']\n    lon = loc['longitude']\n    print(f\"Location: {lat}, {lon}\")\n\ndroid.stopLocating()\n
"},{"location":"qsl4a/connectivity/phone/","title":"Phone API","text":"

Control phone calls and retrieve phone information.

"},{"location":"qsl4a/connectivity/phone/#phone-state-tracking","title":"Phone State Tracking","text":""},{"location":"qsl4a/connectivity/phone/#starttrackingphonestate","title":"startTrackingPhoneState()","text":"

Start tracking phone state changes. Generates 'phone' events.

startTrackingPhoneState()\n
"},{"location":"qsl4a/connectivity/phone/#readphonestate","title":"readPhoneState()","text":"

Read the current phone state.

readPhoneState()\n

Returns: Bundle with phone state and incoming number

"},{"location":"qsl4a/connectivity/phone/#stoptrackingphonestate","title":"stopTrackingPhoneState()","text":"

Stop tracking phone state.

stopTrackingPhoneState()\n
"},{"location":"qsl4a/connectivity/phone/#making-calls","title":"Making Calls","text":""},{"location":"qsl4a/connectivity/phone/#phonecall","title":"phoneCall()","text":"

Call a contact/phone number by URI.

phoneCall(uri)\n

Parameters: - uri (str): Contact URI or phone number URI

"},{"location":"qsl4a/connectivity/phone/#phonecallnumber","title":"phoneCallNumber()","text":"

Call a phone number directly.

phoneCallNumber(phone_number)\n

Parameters: - phone_number (str): Phone number to call

"},{"location":"qsl4a/connectivity/phone/#phonedial","title":"phoneDial()","text":"

Dial a number (opens dialer without calling).

phoneDial(uri)\n

Parameters: - uri (str): Contact URI or phone number URI

"},{"location":"qsl4a/connectivity/phone/#phonedialnumber","title":"phoneDialNumber()","text":"

Dial a phone number (opens dialer without calling).

phoneDialNumber(phone_number)\n

Parameters: - phone_number (str): Phone number

"},{"location":"qsl4a/connectivity/phone/#cell-location","title":"Cell Location","text":""},{"location":"qsl4a/connectivity/phone/#getcelllocation","title":"getCellLocation()","text":"

Get the current cell location.

getCellLocation()\n

Returns: JSONObject with cell location data

"},{"location":"qsl4a/connectivity/phone/#getallcellslocation","title":"getAllCellsLocation()","text":"

Get all cell locations (for dual SIM devices).

getAllCellsLocation()\n

Returns: JSONArray of cell locations

"},{"location":"qsl4a/connectivity/phone/#network-information","title":"Network Information","text":""},{"location":"qsl4a/connectivity/phone/#getnetworkoperator","title":"getNetworkOperator()","text":"

Get the MCC+MNC of the current operator.

getNetworkOperator()\n

Returns: String (e.g., '310260')

"},{"location":"qsl4a/connectivity/phone/#getnetworkoperatorname","title":"getNetworkOperatorName()","text":"

Get the name of the current operator.

getNetworkOperatorName()\n

Returns: String (e.g., 'T-Mobile')

"},{"location":"qsl4a/connectivity/phone/#getnetworktype","title":"getNetworkType()","text":"

Get the current network type.

getNetworkType()\n

Returns: String describing radio technology (e.g., 'LTE', 'UMTS', 'GSM')

"},{"location":"qsl4a/connectivity/phone/#getphonetype","title":"getPhoneType()","text":"

Get the phone type.

getPhoneType()\n

Returns: String (e.g., 'GSM', 'CDMA', 'SIP')

"},{"location":"qsl4a/connectivity/phone/#sim-information","title":"SIM Information","text":""},{"location":"qsl4a/connectivity/phone/#getsimcountryiso","title":"getSimCountryIso()","text":"

Get the ISO country code for the SIM.

getSimCountryIso()\n

Returns: String (e.g., 'us')

"},{"location":"qsl4a/connectivity/phone/#getsimoperator","title":"getSimOperator()","text":"

Get the MCC+MNC of the SIM operator.

getSimOperator()\n

Returns: String (e.g., '310260')

"},{"location":"qsl4a/connectivity/phone/#getsimoperatorname","title":"getSimOperatorName()","text":"

Get the SIM operator name.

getSimOperatorName()\n

Returns: String (e.g., 'T-Mobile')

"},{"location":"qsl4a/connectivity/phone/#getsimserialnumber","title":"getSimSerialNumber()","text":"

Get the SIM serial number.

getSimSerialNumber()\n

Returns: String SIM serial number

"},{"location":"qsl4a/connectivity/phone/#getsimstate","title":"getSimState()","text":"

Get the SIM card state.

getSimState()\n

Returns: String describing SIM state

"},{"location":"qsl4a/connectivity/phone/#getsubscriberid","title":"getSubscriberId()","text":"

Get the subscriber ID.

getSubscriberId()\n

Returns: String subscriber ID

"},{"location":"qsl4a/connectivity/phone/#voice-mail","title":"Voice Mail","text":""},{"location":"qsl4a/connectivity/phone/#getvoicemailalphatag","title":"getVoiceMailAlphaTag()","text":"

Get the voice mail alpha tag.

getVoiceMailAlphaTag()\n

Returns: String voice mail tag

"},{"location":"qsl4a/connectivity/phone/#getvoicemailnumber","title":"getVoiceMailNumber()","text":"

Get the voice mail number.

getVoiceMailNumber()\n

Returns: String voice mail number

"},{"location":"qsl4a/connectivity/phone/#device-information","title":"Device Information","text":""},{"location":"qsl4a/connectivity/phone/#getdeviceid","title":"getDeviceId()","text":"

Get the device ID (IMEI for GSM). Deprecated.

getDeviceId()\n

Returns: String device ID

"},{"location":"qsl4a/connectivity/phone/#getdevicesoftwareversion","title":"getDeviceSoftwareVersion()","text":"

Get the device software version.

getDeviceSoftwareVersion()\n

Returns: String software version

"},{"location":"qsl4a/connectivity/phone/#getline1number","title":"getLine1Number()","text":"

Get the line 1 phone number.

getLine1Number()\n

Returns: String phone number

"},{"location":"qsl4a/connectivity/phone/#checknetworkroaming","title":"checkNetworkRoaming()","text":"

Check if connected to roaming network.

checkNetworkRoaming()\n

Returns: True if roaming

"},{"location":"qsl4a/connectivity/phone/#cell-info","title":"Cell Info","text":""},{"location":"qsl4a/connectivity/phone/#getallcellinfo","title":"getAllCellInfo()","text":"

Get information about all cells.

getAllCellInfo()\n

Returns: List of cell information

"},{"location":"qsl4a/connectivity/phone/#setdataenabled","title":"setDataEnabled()","text":"

Enable or disable mobile data.

setDataEnabled(enabled)\n

Parameters: - enabled (bool): True to enable, False to disable

"},{"location":"qsl4a/connectivity/phone/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get network info\noperator = droid.getNetworkOperatorName().result\nprint(f\"Operator: {operator}\")\n\nnetwork_type = droid.getNetworkType().result\nprint(f\"Network: {network_type}\")\n\n# Get SIM info\nsim_state = droid.getSimState().result\nprint(f\"SIM: {sim_state}\")\n\n# Get phone number\nline1 = droid.getLine1Number().result\nprint(f\"Phone: {line1}\")\n\n# Track phone state\ndroid.startTrackingPhoneState()\nprint(\"Tracking phone state...\")\ndroid.stopTrackingPhoneState()\n
"},{"location":"qsl4a/connectivity/signalstrength/","title":"Signal Strength API","text":"

Monitor cellular and wireless signal strength.

"},{"location":"qsl4a/connectivity/signalstrength/#signal-strength-methods","title":"Signal Strength Methods","text":""},{"location":"qsl4a/connectivity/signalstrength/#starttrackingsignalstrengths","title":"startTrackingSignalStrengths()","text":"

Start tracking signal strength changes. Generates 'signal_strengths' events.

startTrackingSignalStrengths()\n
"},{"location":"qsl4a/connectivity/signalstrength/#stoptrackingsignalstrengths","title":"stopTrackingSignalStrengths()","text":"

Stop tracking signal strengths.

stopTrackingSignalStrengths()\n
"},{"location":"qsl4a/connectivity/signalstrength/#readsignalstrengths","title":"readSignalStrengths()","text":"

Read the current signal strengths.

readSignalStrengths()\n

Returns: Bundle with signal strength data

"},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthlevel","title":"getTelephoneSignalStrengthLevel()","text":"

Get the telephone signal strength as a level (0-4).

getTelephoneSignalStrengthLevel()\n

Returns: Integer level (0=none, 1=poor, 2=fair, 3=good, 4=excellent)

"},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthdetail","title":"getTelephoneSignalStrengthDetail()","text":"

Get detailed telephone signal strength information.

getTelephoneSignalStrengthDetail()\n

Returns: String with detailed signal info

"},{"location":"qsl4a/connectivity/signalstrength/#usage-example","title":"Usage Example","text":"
import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start tracking signal strength\ndroid.startTrackingSignalStrengths()\n\n# Wait for signal updates\ntime.sleep(5)\n\n# Read current signal strength\nsignal = droid.readSignalStrengths().result\nprint(f\"Signal: {signal}\")\n\n# Get level directly\nlevel = droid.getTelephoneSignalStrengthLevel().result\nprint(f\"Signal level: {level}/4\")\n\ndroid.stopTrackingSignalStrengths()\n
"},{"location":"qsl4a/connectivity/sms/","title":"SMS API","text":"

Send and receive SMS messages.

"},{"location":"qsl4a/connectivity/sms/#methods","title":"Methods","text":""},{"location":"qsl4a/connectivity/sms/#smssend","title":"smsSend()","text":"

Send SMS message.

smsSend(destinationAddress, text)\n

Parameters: - destinationAddress (str): Phone number - text (str): Message text

"},{"location":"qsl4a/connectivity/sms/#smsgetmessagecount","title":"smsGetMessageCount()","text":"

Get message count.

smsGetMessageCount(unreadOnly=False, folder=\"inbox\")\n
"},{"location":"qsl4a/connectivity/sms/#smsgetmessageids","title":"smsGetMessageIds()","text":"

Get message IDs.

smsGetMessageIds(unreadOnly=False, folder=\"inbox\")\n
"},{"location":"qsl4a/connectivity/sms/#smsgetmessages","title":"smsGetMessages()","text":"

Get message details.

smsGetMessages(unreadOnly=False, folder=\"inbox\", attributes=None)\n
"},{"location":"qsl4a/connectivity/sms/#smsgetmessagebyid","title":"smsGetMessageById()","text":"

Get a specific message by ID.

smsGetMessageById(id, attributes=None)\n

Parameters: - id (int): Message ID - attributes (list, optional): Specific attributes to retrieve

Returns: Message data dict

"},{"location":"qsl4a/connectivity/sms/#smsgetattributes","title":"smsGetAttributes()","text":"

Get available SMS message attributes.

smsGetAttributes()\n

Returns: List of available attribute names

"},{"location":"qsl4a/connectivity/sms/#smsdeletemessage","title":"smsDeleteMessage()","text":"

Delete message.

smsDeleteMessage(id)\n
"},{"location":"qsl4a/connectivity/sms/#smsmarkmessageread","title":"smsMarkMessageRead()","text":"

Mark message as read.

smsMarkMessageRead(ids, read=True)\n
"},{"location":"qsl4a/connectivity/sms/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Send SMS\ndroid.smsSend(\"+1234567890\", \"Hello from QPython!\")\n\n# Get unread messages\nmessages = droid.smsGetMessages(unreadOnly=True).result\nfor msg in messages:\n    print(f\"From: {msg['address']}, Text: {msg['body']}\")\n
"},{"location":"qsl4a/connectivity/wifi/","title":"WiFi API","text":"

Control WiFi adapter and get connection information.

"},{"location":"qsl4a/connectivity/wifi/#adapter-control","title":"Adapter Control","text":""},{"location":"qsl4a/connectivity/wifi/#checkwifistate","title":"checkWifiState()","text":"

Check if WiFi is enabled.

checkWifiState()\n

Returns: True if WiFi is enabled, False otherwise

"},{"location":"qsl4a/connectivity/wifi/#togglewifistate","title":"toggleWifiState()","text":"

Turn WiFi on or off.

toggleWifiState(enabled=None)\n

Parameters: - enabled (bool): True to enable, False to disable, None to toggle

Returns: True if operation succeeded

"},{"location":"qsl4a/connectivity/wifi/#wifistartscan","title":"wifiStartScan()","text":"

Start scanning for available WiFi networks.

wifiStartScan()\n
"},{"location":"qsl4a/connectivity/wifi/#wifigetscanresults","title":"wifiGetScanResults()","text":"

Get list of discovered WiFi networks.

wifiGetScanResults()\n

Returns: List of access point information

"},{"location":"qsl4a/connectivity/wifi/#connection-management","title":"Connection Management","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetconnectioninfo","title":"wifiGetConnectionInfo()","text":"

Get detailed connection information.

wifiGetConnectionInfo()\n

Returns: Dict with connection details including SSID, BSSID, IP address

"},{"location":"qsl4a/connectivity/wifi/#getconnectedinfo","title":"getConnectedInfo()","text":"

Get connected WiFi network info (simplified).

getConnectedInfo()\n

Returns: Dict with SSID, BSSID, signal strength

"},{"location":"qsl4a/connectivity/wifi/#getdhcpinfo","title":"getDhcpInfo()","text":"

Get DHCP information for current connection.

getDhcpInfo(ipConvertToString=True)\n

Parameters: - ipConvertToString (bool): Convert IP addresses to string format (default: True)

Returns: Dict with DHCP info including IP, gateway, DNS

"},{"location":"qsl4a/connectivity/wifi/#wifidisconnect","title":"wifiDisconnect()","text":"

Disconnect from current WiFi network.

wifiDisconnect()\n
"},{"location":"qsl4a/connectivity/wifi/#wifireconnect","title":"wifiReconnect()","text":"

Reconnect to the current network.

wifiReconnect()\n
"},{"location":"qsl4a/connectivity/wifi/#wifireassociate","title":"wifiReassociate()","text":"

Reassociate with the current access point.

wifiReassociate()\n
"},{"location":"qsl4a/connectivity/wifi/#hotspot","title":"Hotspot","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetapstate","title":"wifiGetApState()","text":"

Get WiFi AP (hotspot) state.

wifiGetApState()\n

Returns: Hotspot state

"},{"location":"qsl4a/connectivity/wifi/#wifi-locks","title":"WiFi Locks","text":""},{"location":"qsl4a/connectivity/wifi/#wifilockacquirefull","title":"wifiLockAcquireFull()","text":"

Acquire a full WiFi lock (keeps WiFi active even when screen is off).

wifiLockAcquireFull()\n
"},{"location":"qsl4a/connectivity/wifi/#wifilockacquirescanonly","title":"wifiLockAcquireScanOnly()","text":"

Acquire a scan-only WiFi lock.

wifiLockAcquireScanOnly()\n
"},{"location":"qsl4a/connectivity/wifi/#wifilockrelease","title":"wifiLockRelease()","text":"

Release the WiFi lock.

wifiLockRelease()\n
"},{"location":"qsl4a/connectivity/wifi/#usage-example","title":"Usage Example","text":"
import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Check WiFi state\nif droid.checkWifiState().result:\n    print(\"WiFi is enabled\")\nelse:\n    print(\"Enabling WiFi...\")\n    droid.toggleWifiState(True)\n    time.sleep(2)\n\n# Start scanning\ndroid.wifiStartScan()\ntime.sleep(3)\n\n# Get scan results\nnetworks = droid.wifiGetScanResults().result\nfor network in networks:\n    print(f\"SSID: {network.get('SSID')}, Signal: {network.get('level')} dBm\")\n\n# Get connection info\ninfo = droid.wifiGetConnectionInfo().result\nif info:\n    print(f\"Connected to: {info.get('ssid')}\")\n    print(f\"BSSID: {info.get('bssid')}\")\n    print(f\"IP: {info.get('ip_address')}\")\n\n# Get DHCP info\ndhcp = droid.getDhcpInfo().result\nif dhcp:\n    print(f\"Gateway: {dhcp.get('gateway')}\")\n    print(f\"DNS: {dhcp.get('dns1')}\")\n\n# Get simplified connected info\nconnected = droid.getConnectedInfo().result\nprint(f\"SSID: {connected.get('ssid')}, Signal: {connected.get('level')} dBm\")\n\n# Disconnect and reconnect\ndroid.wifiDisconnect()\ntime.sleep(1)\ndroid.wifiReconnect()\n\n# Reassociate with access point\ndroid.wifiReassociate()\n\n# Check hotspot state\nap_state = droid.wifiGetApState().result\nprint(f\"Hotspot state: {ap_state}\")\n\n# Acquire WiFi lock for background operation\ndroid.wifiLockAcquireFull()\n# ... do work ...\ndroid.wifiLockRelease()\n\n# Or use scan-only lock for lighter background operation\ndroid.wifiLockAcquireScanOnly()\n# ... do scanning work ...\ndroid.wifiLockRelease()\n
"},{"location":"qsl4a/core/android-base/","title":"Android Base Class","text":"

The Android class is the core of QSL4A, providing the connection to the Android runtime and RPC mechanism.

"},{"location":"qsl4a/core/android-base/#module-import","title":"Module Import","text":"
# Full featured (recommended)\nimport androidhelper\ndroid = androidhelper.Android()\n\n# Minimal version (quick, single instance)\nimport android\ndroid = android.droid\n
"},{"location":"qsl4a/core/android-base/#class-android","title":"Class: Android","text":""},{"location":"qsl4a/core/android-base/#constructor","title":"Constructor","text":"
Android(addr=None)\n

Parameters: - addr (tuple, optional): (HOST, PORT) address. If None, uses environment variables AP_HOST and AP_PORT

Environment Variables: - AP_HOST - Server host address - AP_PORT - Server port - AP_HANDSHAKE - Authentication token

"},{"location":"qsl4a/core/android-base/#core-methods","title":"Core Methods","text":""},{"location":"qsl4a/core/android-base/#_rpc","title":"_rpc()","text":"

Internal RPC method for calling Android functions.

_rpc(method, *args)\n

Parameters: - method (str): Method name to call - *args: Variable arguments for the method

Returns: Result namedtuple with fields: - id (int): Request ID - result: Method return value - error (str or None): Error message if failed

"},{"location":"qsl4a/core/android-base/#getattr","title":"getattr()","text":"

Dynamic method dispatcher. All Android methods are accessed via attribute lookup.

# These are equivalent:\ndroid.makeToast(\"Hello\")\ndroid._rpc(\"makeToast\", \"Hello\")\n
"},{"location":"qsl4a/core/android-base/#standalone-functions-androidpy","title":"Standalone Functions (android.py)","text":"

When using the minimal android module:

"},{"location":"qsl4a/core/android-base/#jsla","title":"jsla()","text":"

Send JSON-RPC request and return raw response.

jsla(method, *params)\n

Returns: JSON string response

"},{"location":"qsl4a/core/android-base/#rsla","title":"rsla()","text":"

Send request and return result only.

rsla(method, *params)\n

Returns: Result value from RPC call

"},{"location":"qsl4a/core/android-base/#esla","title":"esla()","text":"

Send request, raise exception on error.

esla(method, *params)\n

Raises: Exception if error field is not None

"},{"location":"qsl4a/core/android-base/#nsla","title":"nsla()","text":"

Send request and return Result namedtuple.

nsla(method, *params)\n

Returns: Result namedtuple

"},{"location":"qsl4a/core/android-base/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/android-base/#basic-connection","title":"Basic Connection","text":"
import androidhelper\n\n# Connect to Android runtime\ndroid = androidhelper.Android()\n\n# Check connection by showing toast\ndroid.makeToast(\"Connected!\")\n
"},{"location":"qsl4a/core/android-base/#error-handling","title":"Error Handling","text":"
result = droid.someMethod()\nif result.error:\n    print(f\"Error: {result.error}\")\nelse:\n    print(f\"Success: {result.result}\")\n
"},{"location":"qsl4a/core/android-base/#direct-rpc-call","title":"Direct RPC Call","text":"
# Call any method directly\nresult = droid._rpc(\"makeToast\", \"Hello World\")\n
"},{"location":"qsl4a/core/events/","title":"Event System","text":"

QSL4A provides an event system for handling asynchronous events from Android, such as sensor updates, location changes, and custom broadcasts.

"},{"location":"qsl4a/core/events/#event-basics","title":"Event Basics","text":"

Events are stored in a buffer and can be polled or waited for. Each event has: - name: Event type/name - data: Event payload data - time: Timestamp

"},{"location":"qsl4a/core/events/#event-methods","title":"Event Methods","text":""},{"location":"qsl4a/core/events/#eventclearbuffer","title":"eventClearBuffer()","text":"

Clear all pending events from the buffer.

eventClearBuffer()\n

Returns: None

"},{"location":"qsl4a/core/events/#eventpoll","title":"eventPoll()","text":"

Poll for events in the buffer.

eventPoll(number_of_events=1)\n

Parameters: - number_of_events (int): Maximum events to retrieve (default: 1)

Returns: List of event objects

"},{"location":"qsl4a/core/events/#eventwait","title":"eventWait()","text":"

Wait for any event.

eventWait(timeout=None)\n

Parameters: - timeout (int, optional): Timeout in seconds. None = wait forever

Returns: Event object or None if timeout

"},{"location":"qsl4a/core/events/#eventwaitfor","title":"eventWaitFor()","text":"

Wait for a specific event.

eventWaitFor(eventName, timeout=None)\n

Parameters: - eventName (str): Name of event to wait for - timeout (int, optional): Timeout in seconds

Returns: Event object or None if timeout

"},{"location":"qsl4a/core/events/#eventpost","title":"eventPost()","text":"

Post a custom event.

eventPost(name, data, enqueue=None)\n

Parameters: - name (str): Event name - data: Event data (any type) - enqueue (bool, optional): Add to queue if True

"},{"location":"qsl4a/core/events/#receiveevent","title":"receiveEvent()","text":"

Receive event (blocking).

receiveEvent()\n

Returns: Event object

"},{"location":"qsl4a/core/events/#broadcast-events","title":"Broadcast Events","text":"

Register for system broadcast events.

"},{"location":"qsl4a/core/events/#eventregisterforbroadcast","title":"eventRegisterForBroadcast()","text":"

Register to receive broadcast events.

eventRegisterForBroadcast(category, enqueue=True)\n

Parameters: - category (str): Broadcast category/action - enqueue (bool): Add to event queue

"},{"location":"qsl4a/core/events/#eventunregisterforbroadcast","title":"eventUnregisterForBroadcast()","text":"

Unregister from broadcast events.

eventUnregisterForBroadcast(category)\n
"},{"location":"qsl4a/core/events/#eventgetbrodcastcategories","title":"eventGetBrodcastCategories()","text":"

Get registered broadcast categories.

eventGetBrodcastCategories()\n

Returns: List of registered categories

"},{"location":"qsl4a/core/events/#event-dispatcher","title":"Event Dispatcher)","text":""},{"location":"qsl4a/core/events/#starteventdispatcher","title":"startEventDispatcher()","text":"

Opens up a socket where you can read for events posted.)

startEventDispatcher(port=0)\n

Parameters: - port (int, optional): Port to listen on (default: 0 = auto-select)

Returns: Port number being listened on

"},{"location":"qsl4a/core/events/#stopeventdispatcher","title":"stopEventDispatcher()","text":"

Stops the event server.)

stopEventDispatcher()\n
"},{"location":"qsl4a/core/events/#deprecated-methods","title":"Deprecated Methods","text":""},{"location":"qsl4a/core/events/#rpcpostevent","title":"rpcPostEvent()","text":"

Post an event to the event queue. (Deprecated, use eventPost)

rpcPostEvent(name, data)\n

Parameters: - name (str): Event name - data: Event data

"},{"location":"qsl4a/core/events/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/events/#basic-event-polling","title":"Basic Event Polling","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Clear old events\ndroid.eventClearBuffer()\n\n# Poll for events\nevents = droid.eventPoll(5).result\nfor event in events:\n    print(f\"Event: {event['name']}, Data: {event['data']}\")\n
"},{"location":"qsl4a/core/events/#waiting-for-events","title":"Waiting for Events","text":"
# Wait for any event with timeout\nevent = droid.eventWait(timeout=10).result\nif event:\n    print(f\"Got event: {event['name']}\")\n
"},{"location":"qsl4a/core/events/#waiting-for-specific-event","title":"Waiting for Specific Event","text":"
# Wait for sensor event\nevent = droid.eventWaitFor('screen', timeout=5).result\nif event:\n    print(f\"Screen event: {event['data']}\")\n
"},{"location":"qsl4a/core/events/#posting-custom-events","title":"Posting Custom Events","text":"
# Post custom event\ndroid.eventPost('my_event', {'key': 'value'})\n\n# Wait for it\nevent = droid.eventWaitFor('my_event', timeout=1).result\n
"},{"location":"qsl4a/core/events/#broadcast-receiver","title":"Broadcast Receiver","text":"
# Register for screen on/off events\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_ON')\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_OFF')\n\n# Wait for screen events\nwhile True:\n    event = droid.receiveEvent().result\n    if event['name'] == 'android.intent.action.SCREEN_ON':\n        print(\"Screen turned on\")\n    elif event['name'] == 'android.intent.action.SCREEN_OFF':\n        print(\"Screen turned off\")\n
"},{"location":"qsl4a/core/events/#sensor-event-handling","title":"Sensor Event Handling","text":"
# Start sensing\ndroid.startSensingTimed(1, 250)\n\n# Process sensor events\nfor _ in range(100):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'sensors':\n        data = event['data']\n        print(f\"Accel: {data['xforce']}, {data['yforce']}, {data['zforce']}\")\n\ndroid.stopSensing()\n
"},{"location":"qsl4a/core/events/#common-event-types","title":"Common Event Types","text":"Event Name Description Source sensors Sensor data update startSensing* location GPS location update startLocating phone Phone state change startTrackingPhoneState signal Signal strength change startTrackingSignalStrength screen Screenshot ready fullGetScreenShot dialog Dialog response dialogShow*"},{"location":"qsl4a/core/events/#event-data-structure","title":"Event Data Structure","text":"
{\n    'name': 'event_name',\n    'data': {\n        # Event-specific data\n    },\n    'time': 1234567890  # Timestamp\n}\n
"},{"location":"qsl4a/core/intent/","title":"Intent System","text":"

Android Intents are used to start activities, send broadcasts, and communicate between apps. QSL4A provides full Intent support through the Intent module.

"},{"location":"qsl4a/core/intent/#module-import","title":"Module Import","text":"
import androidhelper\ndon = androidhelper.Android()\n
"},{"location":"qsl4a/core/intent/#intent-constants","title":"Intent Constants","text":"

Access via droid.Intent:

"},{"location":"qsl4a/core/intent/#actions","title":"Actions","text":"Constant Value Usage ACTION_MAIN android.intent.action.MAIN App entry point ACTION_VIEW android.intent.action.VIEW View content ACTION_EDIT android.intent.action.EDIT Edit content ACTION_PICK android.intent.action.PICK Pick item ACTION_SEND android.intent.action.SEND Share content ACTION_SEARCH android.intent.action.SEARCH Search"},{"location":"qsl4a/core/intent/#flags","title":"Flags","text":"Constant Value Usage FLAG_ACTIVITY_NEW_TASK 268435456 Start new task FLAG_ACTIVITY_CLEAR_TASK 32768 Clear task stack FLAG_ACTIVITY_NEW_DOCUMENT 524288 New document mode"},{"location":"qsl4a/core/intent/#extras","title":"Extras","text":"Constant Usage EXTRA_TEXT Text content EXTRA_STREAM File URI EXTRA_SUBJECT Subject line EXTRA_EMAIL Email address"},{"location":"qsl4a/core/intent/#core-methods","title":"Core Methods","text":""},{"location":"qsl4a/core/intent/#makeintent","title":"makeIntent()","text":"

Create an Intent object.

makeIntent(action, uri=None, type=None, extras=None, categories=None,\n           packagename=None, classname=None, flags=None)\n

Parameters: - action (str): Intent action (e.g., droid.Intent.ACTION_VIEW) - uri (str, optional): Data URI - type (str, optional): MIME type - extras (dict, optional): Extra data - categories (list, optional): Intent categories - packagename (str, optional): Target package - classname (str, optional): Target class - flags (int, optional): Intent flags

Returns: Intent object

"},{"location":"qsl4a/core/intent/#startactivityintent","title":"startActivityIntent()","text":"

Start an Activity with an Intent.

startActivityIntent(intent, wait=None)\n

Parameters: - intent: Intent object from makeIntent() - wait (bool, optional): Block until activity closes

"},{"location":"qsl4a/core/intent/#startactivityforresultintent","title":"startActivityForResultIntent()","text":"

Start activity and wait for result.

startActivityForResultIntent(intent)\n

Returns: Activity result

"},{"location":"qsl4a/core/intent/#sendbroadcastintent","title":"sendBroadcastIntent()","text":"

Send a broadcast.

sendBroadcastIntent(intent)\n
"},{"location":"qsl4a/core/intent/#view","title":"view()","text":"

View content by URI.

view(uri, type=None, extras=None)\n
"},{"location":"qsl4a/core/intent/#pick","title":"pick()","text":"

Pick content from URI.

pick(uri)\n
"},{"location":"qsl4a/core/intent/#common-intent-methods","title":"Common Intent Methods)","text":""},{"location":"qsl4a/core/intent/#scanbarcode","title":"scanBarcode()","text":"

Launch the barcode scanner.

scanBarcode()\n

Returns: Scanned barcode string

"},{"location":"qsl4a/core/intent/#send","title":"send()","text":"

Send content via share intent.

send(type, content)\n

Parameters: - type (str): MIME type - content (str): Content to share

"},{"location":"qsl4a/core/intent/#sendtext","title":"sendText()","text":"

Send text content.

sendText(text)\n

Parameters: - text (str): Text to send

"},{"location":"qsl4a/core/intent/#sendemail","title":"sendEmail()","text":"

Send an email.

sendEmail(to, subject, body, attachment=None)\n

Parameters: - to (str or list): Recipient email address(es) - subject (str): Email subject - body (str): Email body - attachment (str, optional): Attachment file path

"},{"location":"qsl4a/core/intent/#pathtouri","title":"pathToUri()","text":"

Convert file path to content URI.

pathToUri(path)\n

Parameters: - path (str): File path

Returns: Content URI string

"},{"location":"qsl4a/core/intent/#openfile","title":"openFile()","text":"

Open a file with appropriate app.

openFile(path)\n

Parameters: - path (str): File path to open

"},{"location":"qsl4a/core/intent/#sendfile","title":"sendFile()","text":"

Send a file via share intent.

sendFile(path)\n

Parameters: - path (str): File path to send

"},{"location":"qsl4a/core/intent/#getpathtype","title":"getPathType()","text":"

Get the MIME type for a file path.

getPathType(path)\n

Parameters: - path (str): File path

Returns: MIME type string

"},{"location":"qsl4a/core/intent/#viewmap","title":"viewMap()","text":"

Open map at a location.

viewMap(latitude, longitude)\n

Parameters: - latitude (float): Latitude - longitude (float): Longitude

"},{"location":"qsl4a/core/intent/#viewcontacts","title":"viewContacts()","text":"

Open the contacts app.

viewContacts()\n
"},{"location":"qsl4a/core/intent/#search","title":"search()","text":"

Perform a web search.

search(query)\n

Parameters: - query (str): Search query

"},{"location":"qsl4a/core/intent/#viewhtml","title":"viewHtml()","text":"

View HTML content.

viewHtml(content, encoding=None)\n

Parameters: - content (str): HTML content - encoding (str, optional): Character encoding

"},{"location":"qsl4a/core/intent/#webviewshow","title":"webViewShow()","text":"

Display web content in WebView. Deprecated, use viewHtml.

webViewShow(url)\n

Parameters: - url (str): Web page URL

"},{"location":"qsl4a/core/intent/#editoropen","title":"editorOpen()","text":"

Open a text editor.

editorOpen(path=None, create=False)\n

Parameters: - path (str, optional): File path to edit - create (bool, optional): Create if doesn't exist

"},{"location":"qsl4a/core/intent/#helper-class-uri","title":"Helper Class: Uri","text":"

Create URI objects for Intents:

from androidhelper.Intent import Uri\n\nuri = Uri(\"file:///sdcard/test.txt\")\n
"},{"location":"qsl4a/core/intent/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/intent/#open-web-page","title":"Open Web Page","text":"
intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"http://www.example.com\"\n).result\ndroid.startActivityIntent(intent)\n
"},{"location":"qsl4a/core/intent/#share-text","title":"Share Text","text":"
intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_TEXT: \"Hello from QPython!\",\n        droid.Intent.EXTRA_SUBJECT: \"Test\"\n    },\n    type=\"text/plain\"\n).result\ndroid.startActivityIntent(intent)\n
"},{"location":"qsl4a/core/intent/#open-file","title":"Open File","text":"
intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"file:///sdcard/document.pdf\",\n    type=\"application/pdf\"\n).result\ndroid.startActivityIntent(intent)\n
"},{"location":"qsl4a/core/intent/#pick-contact","title":"Pick Contact","text":"
result = droid.pickContact()\ncontact_uri = result.result\n
"},{"location":"qsl4a/core/intent/#send-email","title":"Send Email","text":"
intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_EMAIL: [\"test@example.com\"],\n        droid.Intent.EXTRA_SUBJECT: \"Hello\",\n        droid.Intent.EXTRA_TEXT: \"Message body\"\n    },\n    type=\"message/rfc822\"\n).result\ndroid.startActivityIntent(intent)\n
"},{"location":"qsl4a/core/intent/#open-app","title":"Open App","text":"
intent = droid.makeIntent(\n    action=droid.Intent.ACTION_MAIN,\n    packagename=\"com.android.settings\",\n    classname=\"com.android.settings.Settings\"\n).result\ndroid.startActivityIntent(intent)\n
"},{"location":"qsl4a/hardware/bluetooth/","title":"Bluetooth API","text":"

Control Bluetooth adapter and communicate with Bluetooth devices.

"},{"location":"qsl4a/hardware/bluetooth/#adapter-control","title":"Adapter Control","text":""},{"location":"qsl4a/hardware/bluetooth/#togglebluetoothstate","title":"toggleBluetoothState()","text":"

Turn Bluetooth on/off.

toggleBluetoothState(enabled=None, prompt=True)\n

Parameters: - enabled (bool): True=on, False=off, None=toggle - prompt (bool): Show user prompt

"},{"location":"qsl4a/hardware/bluetooth/#checkbluetoothstate","title":"checkBluetoothState()","text":"

Check if Bluetooth is enabled.

checkBluetoothState()\n

Returns: True/False

"},{"location":"qsl4a/hardware/bluetooth/#getlocalname","title":"GetLocalName()","text":"

Get Bluetooth device name.

GetLocalName()\n
"},{"location":"qsl4a/hardware/bluetooth/#setlocalname","title":"SetLocalName()","text":"

Set Bluetooth device name.

SetLocalName(name)\n
"},{"location":"qsl4a/hardware/bluetooth/#getscanmode","title":"GetScanMode()","text":"

Get discoverability mode.

GetScanMode()\n

Returns: - -1: Disabled - 0: Non-discoverable, non-connectable - 1: Connectable, non-discoverable - 3: Connectable and discoverable

"},{"location":"qsl4a/hardware/bluetooth/#makediscoverable","title":"MakeDiscoverable()","text":"

Make device discoverable.

MakeDiscoverable(duration=300)\n

Parameters: - duration (int): Seconds to be discoverable

"},{"location":"qsl4a/hardware/bluetooth/#discovery","title":"Discovery","text":""},{"location":"qsl4a/hardware/bluetooth/#discoverystart","title":"DiscoveryStart()","text":"

Start device discovery.

DiscoveryStart()\n
"},{"location":"qsl4a/hardware/bluetooth/#discoverycancel","title":"DiscoveryCancel()","text":"

Cancel discovery.

DiscoveryCancel()\n
"},{"location":"qsl4a/hardware/bluetooth/#getreceiveddevices","title":"GetReceivedDevices()","text":"

Get discovered devices.

GetReceivedDevices()\n

Returns: List of device info dicts

"},{"location":"qsl4a/hardware/bluetooth/#getbondeddevices","title":"GetBondedDevices()","text":"

Get paired devices.

GetBondedDevices()\n

Returns: List of paired device info

"},{"location":"qsl4a/hardware/bluetooth/#connection","title":"Connection","text":""},{"location":"qsl4a/hardware/bluetooth/#connect","title":"Connect()","text":"

Connect to a device.

Connect(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", address=None)\n

Parameters: - uuid (str): Service UUID - address (str): Device address (None = show picker)

Returns: True if successful

"},{"location":"qsl4a/hardware/bluetooth/#accept","title":"Accept()","text":"

Accept incoming connection.

Accept(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", timeout=0)\n
"},{"location":"qsl4a/hardware/bluetooth/#activeconnections","title":"ActiveConnections()","text":"

Check active connections.

ActiveConnections()\n
"},{"location":"qsl4a/hardware/bluetooth/#stop","title":"Stop()","text":"

Disconnect.

Stop(connID=None)\n
"},{"location":"qsl4a/hardware/bluetooth/#communication","title":"Communication","text":""},{"location":"qsl4a/hardware/bluetooth/#write","title":"Write()","text":"

Send ASCII data.

Write(ascii, connID=\"\")\n
"},{"location":"qsl4a/hardware/bluetooth/#writebinary","title":"WriteBinary()","text":"

Send binary data (base64 encoded).

WriteBinary(base64, connID=None)\n
"},{"location":"qsl4a/hardware/bluetooth/#read","title":"Read()","text":"

Read ASCII data.

Read(bufferSize=4096, connID=None)\n
"},{"location":"qsl4a/hardware/bluetooth/#readbinary","title":"ReadBinary()","text":"

Read binary data.

ReadBinary(bufferSize=4096, connID=None)\n
"},{"location":"qsl4a/hardware/bluetooth/#readline","title":"ReadLine()","text":"

Read line.

ReadLine(connID=None)\n
"},{"location":"qsl4a/hardware/bluetooth/#readready","title":"ReadReady()","text":"

Check if data available.

ReadReady(connID=None)\n
"},{"location":"qsl4a/hardware/bluetooth/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Enable Bluetooth\ndroid.toggleBluetoothState(True)\n\n# Get paired devices\ndevices = droid.GetBondedDevices().result\nfor dev in devices:\n    print(f\"{dev['name']}: {dev['address']}\")\n\n# Connect to device\ndroid.Connect(address=\"00:11:22:33:44:55\")\n\n# Send data\ndroid.Write(\"Hello Bluetooth!\")\n\n# Read response\ndata = droid.Read(1024).result\n
"},{"location":"qsl4a/hardware/camera/","title":"Camera API","text":"

Capture photos and record video.

"},{"location":"qsl4a/hardware/camera/#photo-capture","title":"Photo Capture","text":""},{"location":"qsl4a/hardware/camera/#takepicture","title":"takePicture()","text":"

Take a photo using the default camera.

takePicture(path=None)\n

Parameters: - path (str, optional): Save path. If None, returns image data

Returns: Image path or image data

"},{"location":"qsl4a/hardware/camera/#cameracapturepicture","title":"cameraCapturePicture()","text":"

Capture picture with advanced camera controls.

cameraCapturePicture(targetPath=None, cameraId=0, useAutoFocus=True)\n

Parameters: - targetPath (str, optional): Save path - cameraId (int): Camera to use (0 = back, 1 = front) - useAutoFocus (bool): Enable auto focus

Returns: Captured image path

"},{"location":"qsl4a/hardware/camera/#camerasettorchmode","title":"cameraSetTorchMode()","text":"

Control camera flashlight/torch.

cameraSetTorchMode(enabled)\n

Parameters: - enabled (bool): True to turn on, False to turn off

Returns: True if successful

"},{"location":"qsl4a/hardware/camera/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

Capture screenshot.

imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

Parameters: - path (str, optional): Save path - delayMilliSec (int): Delay before capture

"},{"location":"qsl4a/hardware/camera/#video-recording","title":"Video Recording","text":""},{"location":"qsl4a/hardware/camera/#takevideo","title":"takeVideo()","text":"

Record video using default settings.

takeVideo(path=None, quality=1)\n

Parameters: - path (str, optional): Save path - quality (int): Video quality (0-4) - 0: 160x120 - 1: 320x240 - 2: 352x288 - 3: 640x480 - 4: 800x480

"},{"location":"qsl4a/hardware/camera/#recordercapturevideo","title":"recorderCaptureVideo()","text":"

Capture video with advanced controls.

recorderCaptureVideo(targetPath=None, duration=10, cameraId=0, quality=8)\n

Parameters: - targetPath (str, optional): Save path - duration (int): Recording duration in seconds (default: 10) - cameraId (int): Camera to use (0 = back, 1 = front) - quality (int): Video quality (0-8, higher is better)

Returns: Video file path

"},{"location":"qsl4a/hardware/camera/#recordaudio","title":"recordAudio()","text":"

Record audio.

recordAudio()\n

Returns: Audio file path

"},{"location":"qsl4a/hardware/camera/#screen-recording","title":"Screen Recording","text":""},{"location":"qsl4a/hardware/camera/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

Start screen recording.

recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

Parameters: - path (str): Save path - audio (int): Audio source (0=none, 1=mic, 2=internal) - targetPixels (int): Resolution - frameRate (int): FPS - bitRate (int): Bitrate - rotation (bool): Rotate output - autoStart (bool): Start immediately

"},{"location":"qsl4a/hardware/camera/#recorderstart","title":"recorderStart()","text":"

Start recording.

recorderStart()\n
"},{"location":"qsl4a/hardware/camera/#recorderpause","title":"recorderPause()","text":"

Pause recording.

recorderPause()\n
"},{"location":"qsl4a/hardware/camera/#recorderresume","title":"recorderResume()","text":"

Resume recording.

recorderResume()\n
"},{"location":"qsl4a/hardware/camera/#audio-volume-detection","title":"Audio Volume Detection","text":""},{"location":"qsl4a/hardware/camera/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

Start volume detection.

recorderSoundVolumeDetect(interval=100)\n
"},{"location":"qsl4a/hardware/camera/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

Get current volume in dB.

recorderSoundVolumeGetDb()\n
"},{"location":"qsl4a/hardware/camera/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Take photo with default camera\nphoto_path = droid.takePicture(\"/sdcard/photo.jpg\").result\nprint(f\"Photo saved: {photo_path}\")\n\n# Take photo with front camera and auto focus\ncamera_path = droid.cameraCapturePicture(\"/sdcard/selfie.jpg\", cameraId=1, useAutoFocus=True).result\nprint(f\"Front camera photo: {camera_path}\")\n\n# Control flashlight\ndroid.cameraSetTorchMode(True)  # Turn on flashlight\n\n# Record video with default settings\nvideo_path = droid.takeVideo(\"/sdcard/video.mp4\", quality=3).result\nprint(f\"Video saved: {video_path}\")\n\n# Record video with advanced controls\nvideo_path = droid.recorderCaptureVideo(\"/sdcard/movie.mp4\", duration=30, cameraId=0, quality=8).result\n\n# Screenshot\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n
"},{"location":"qsl4a/hardware/recorder/","title":"Audio Recorder API","text":"

Record audio from microphone and device screen.

"},{"location":"qsl4a/hardware/recorder/#audio-recording","title":"Audio Recording","text":""},{"location":"qsl4a/hardware/recorder/#recordaudio","title":"recordAudio()","text":"

Record audio from microphone.

recordAudio()\n

Returns: Path to recorded audio file

"},{"location":"qsl4a/hardware/recorder/#recorderstartmicrophone","title":"recorderStartMicrophone()","text":"

Start recording from microphone to a specific file.

recorderStartMicrophone(targetPath=None)\n

Parameters: - targetPath (str, optional): Path to save the recording

"},{"location":"qsl4a/hardware/recorder/#screen-recording","title":"Screen Recording","text":""},{"location":"qsl4a/hardware/recorder/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

Start screen recording with audio.

recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

Parameters: - path (str): Save path for video file - audio (int): Audio source (0=none, 1=mic, 2=internal audio) - targetPixels (int): Target resolution in pixels - frameRate (int): Frames per second (default: 30) - bitRate (int): Video bitrate - rotation (bool): Rotate output video - autoStart (bool): Start recording immediately

Returns: Result of operation

"},{"location":"qsl4a/hardware/recorder/#recorderstart","title":"recorderStart()","text":"

Start the screen recording (when autoStart=False).

recorderStart()\n
"},{"location":"qsl4a/hardware/recorder/#recorderpause","title":"recorderPause()","text":"

Pause ongoing screen recording.

recorderPause()\n
"},{"location":"qsl4a/hardware/recorder/#recorderresume","title":"recorderResume()","text":"

Resume paused screen recording.

recorderResume()\n
"},{"location":"qsl4a/hardware/recorder/#audio-volume-detection","title":"Audio Volume Detection","text":""},{"location":"qsl4a/hardware/recorder/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

Start monitoring sound volume level.

recorderSoundVolumeDetect(interval=100)\n

Parameters: - interval (int): Detection interval in milliseconds (default: 100)

"},{"location":"qsl4a/hardware/recorder/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

Get current sound volume in decibels.

recorderSoundVolumeGetDb()\n

Returns: Current volume level in dB

"},{"location":"qsl4a/hardware/recorder/#usage-example","title":"Usage Example","text":"
import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Record audio from microphone\nprint(\"Recording audio...\")\naudio_path = droid.recordAudio().result\nprint(f\"Saved to: {audio_path}\")\n\n# Record microphone to specific file\ndroid.recorderStartMicrophone(\"/sdcard/my_recording.mp3\")\ntime.sleep(5)\ndroid.recorderStop()\n\n# Record screen with audio\nprint(\"Starting screen recording...\")\ndroid.recorderStartScreenRecord(\n    path=\"/sdcard/screen_record.mp4\",\n    audio=1,\n    frameRate=30,\n    autoStart=True\n)\ntime.sleep(10)\ndroid.recorderStop()\n\n# Monitor sound volume\ndroid.recorderSoundVolumeDetect(interval=100)\ntime.sleep(3)\nvolume = droid.recorderSoundVolumeGetDb().result\nprint(f\"Current volume: {volume} dB\")\n
"},{"location":"qsl4a/hardware/usbserial/","title":"USB Host Serial API","text":"

Communicate with USB serial devices (requires USB OTG support and Android 3.1+).

"},{"location":"qsl4a/hardware/usbserial/#usb-serial-methods","title":"USB Serial Methods)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialopen","title":"usbHostSerialOpen()","text":"

Open a connection to a USB serial device.

usbHostSerialOpen(device, baudRate=9600)\n

Parameters: - device (str): USB device path or identifier - baudRate (int): Baud rate (default: 9600)

Returns: True if opened successfully

"},{"location":"qsl4a/hardware/usbserial/#usbhostserialclose","title":"usbHostSerialClose()","text":"

Close the USB serial connection.

usbHostSerialClose()\n
"},{"location":"qsl4a/hardware/usbserial/#usbhostserialread","title":"usbHostSerialRead()","text":"

Read data from USB serial.

usbHostSerialRead(bufferSize=1024)\n

Parameters: - bufferSize (int): Maximum bytes to read (default: 1024)

Returns: String read data

"},{"location":"qsl4a/hardware/usbserial/#usbhostserialwrite","title":"usbHostSerialWrite()","text":"

Write data to USB serial.

usbHostSerialWrite(data)\n

Parameters: - data (str): String data to write

"},{"location":"qsl4a/hardware/usbserial/#usbhostserialavailable","title":"usbHostSerialAvailable()","text":"

Check if data is available to read.

usbHostSerialAvailable()\n

Returns: Number of bytes available

"},{"location":"qsl4a/hardware/usbserial/#configuration-methods","title":"Configuration Methods)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetbaudrate","title":"usbHostSerialSetBaudRate()","text":"

Set the baud rate.

usbHostSerialSetBaudRate(baudRate)\n

Parameters: - baudRate (int): Baud rate

"},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetdatabits","title":"usbHostSerialSetDataBits()","text":"

Set data bits (5, 6, 7, or 8).

usbHostSerialSetDataBits(dataBits)\n

Parameters: - dataBits (int): Data bits (5-8)

"},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetstopbits","title":"usbHostSerialSetStopBits()","text":"

Set stop bits (1, 1.5, or 2).

usbHostSerialSetStopBits(stopBits)\n

Parameters: - stopBits (float): Stop bits (1, 1.5, or 2)

"},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetparity","title":"usbHostSerialSetParity()","text":"

Set parity (none, odd, even, mark, space).

usbHostSerialSetParity(parity)\n

Parameters: - parity (str): Parity mode ('none', 'odd', 'even', 'mark', 'space')

"},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetflowcontrol","title":"usbHostSerialSetFlowControl()","text":"

Set flow control (none, hardware, software).

usbHostSerialSetFlowControl(flowControl)\n

Parameters: - flowControl (str): Flow control mode ('none', 'hardware', 'software')

"},{"location":"qsl4a/hardware/usbserial/#usbhostserialreadhex","title":"usbHostSerialReadHex()","text":"

Read data as hex string.

usbHostSerialReadHex(bufferSize=1024)\n

Parameters: - bufferSize (int): Maximum bytes to read

Returns: Hex string

"},{"location":"qsl4a/hardware/usbserial/#usbhostserialwritehex","title":"usbHostSerialWriteHex()","text":"

Write data from hex string.

usbHostSerialWriteHex(hexString)\n

Parameters: - hexString (str): Hex string to write

"},{"location":"qsl4a/hardware/usbserial/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Open USB serial connection\nif droid.usbHostSerialOpen(\"/dev/bus/usb/001/001\", 115200).result:\n    print(\"USB serial opened\")\n\n    # Write data\n    droid.usbHostSerialWrite(\"AT\\r\")\n\n    # Read response\n    response = droid.usbHostSerialRead(1024).result\n    print(f\"Response: {response}\")\n\n    # Or use hex\n    droid.usbHostSerialWriteHex(\"41540D0A\")  # \"AT\\r\\n\"\n\n    # Close connection\n    droid.usbHostSerialClose()\n

Note: USB serial requires: - Android 3.1+ (API 12) - USB OTG cable/adapter - USB host mode support on device - Compatible serial device

"},{"location":"qsl4a/hardware/webcam/","title":"Webcam API","text":"

Stream video from the device camera using MJPEG.

"},{"location":"qsl4a/hardware/webcam/#mjpeg-stream-methods","title":"MJPEG Stream Methods","text":""},{"location":"qsl4a/hardware/webcam/#webcamstart","title":"webcamStart()","text":"

Start an MJPEG stream from the webcam.

webcamStart(resolutionLevel=0, jpegQuality=20, port=0)\n

Parameters: - resolutionLevel (int): Resolution level (default: 0) - jpegQuality (int): JPEG quality 1-100 (default: 20) - port (int): Port number (default: 0 = auto)

Returns: Tuple of (address, port) for the stream

"},{"location":"qsl4a/hardware/webcam/#webcamadjustquality","title":"webcamAdjustQuality()","text":"

Adjust the quality of an active webcam stream.

webcamAdjustQuality(resolutionLevel=0, jpegQuality=20)\n

Parameters: - resolutionLevel (int): Resolution level - jpegQuality (int): JPEG quality 1-100

"},{"location":"qsl4a/hardware/webcam/#webcamstop","title":"webcamStop()","text":"

Stop the webcam stream.

webcamStop()\n
"},{"location":"qsl4a/hardware/webcam/#camera-preview-methods","title":"Camera Preview Methods","text":""},{"location":"qsl4a/hardware/webcam/#camerastartpreview","title":"cameraStartPreview()","text":"

Start camera preview mode with event generation.

cameraStartPreview(resolutionLevel=0, jpegQuality=20, filepath=None)\n

Parameters: - resolutionLevel (int): Resolution level (default: 0) - jpegQuality (int): JPEG quality (default: 20) - filepath (str, optional): File path to save preview frames

Returns: True if successful

Note: Generates 'preview' events with frame data.

"},{"location":"qsl4a/hardware/webcam/#camerastoppreview","title":"cameraStopPreview()","text":"

Stop the camera preview.

cameraStopPreview()\n
"},{"location":"qsl4a/hardware/webcam/#usage-example","title":"Usage Example","text":"
import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start webcam stream\nstream_info = droid.webcamStart(\n    resolutionLevel=0,\n    jpegQuality=30,\n    port=8080\n).result\nprint(f\"Stream available at {stream_info[0]}:{stream_info[1]}\")\n\n# Adjust quality while streaming\ntime.sleep(5)\ndroid.webcamAdjustQuality(resolutionLevel=1, jpegQuality=50)\n\n# Stop when done\ndroid.webcamStop()\n\n# Or use preview mode\nprint(\"Starting preview...\")\ndroid.cameraStartPreview()\n\n# Wait for preview events\nfor i in range(10):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'preview':\n        print(f\"Got preview frame: {event['data']}\")\n\ndroid.cameraStopPreview()\n
"},{"location":"qsl4a/media/image/","title":"Image Processing API","text":"

Compress and process images.

"},{"location":"qsl4a/media/image/#image-compression","title":"Image Compression","text":""},{"location":"qsl4a/media/image/#imagecompress","title":"imageCompress()","text":"

Compress image file.

imageCompress(srcPath, destPath, targetByteSize=0, targetWidth=0, targetHeight=0)\n

Parameters: - srcPath (str): Source image path - destPath (str): Output path - targetByteSize (int): Target file size in bytes (0 = no limit) - targetWidth (int): Target width (0 = original) - targetHeight (int): Target height (0 = original)

Returns: Compressed image path

"},{"location":"qsl4a/media/image/#screenshot","title":"Screenshot","text":""},{"location":"qsl4a/media/image/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

Capture screen.

imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

Parameters: - path (str): Save path - delayMilliSec (int): Delay before capture

Returns: Screenshot path

"},{"location":"qsl4a/media/image/#video-playback","title":"Video Playback","text":""},{"location":"qsl4a/media/image/#videoplay","title":"videoPlay()","text":"

Play video file in fullscreen mode.

videoPlay(path, wait=True)\n

Parameters: - path (str): Video file path - wait (bool): Wait for playback to complete (default: True)

"},{"location":"qsl4a/media/image/#barcode-scanning","title":"Barcode Scanning","text":""},{"location":"qsl4a/media/image/#scanbarcodefromimage","title":"scanBarcodeFromImage()","text":"

Scan barcode/QR code from image file.

scanBarcodeFromImage(path, compressRatio=0, x=0, y=0, width=0, height=0)\n

Parameters: - path (str): Image file path - compressRatio (int): Compression ratio (0 = no compression) - x, y, width, height (int): Region to scan (0 = full image)

Returns: Scanned barcode content

"},{"location":"qsl4a/media/image/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Take screenshot\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n\n# Compress image\ncompressed = droid.imageCompress(\n    \"/sdcard/large_photo.jpg\",\n    \"/sdcard/compressed.jpg\",\n    targetByteSize=102400,  # Target ~100KB\n    targetWidth=1920,\n    targetHeight=1080\n).result\nprint(f\"Saved: {compressed}\")\n\n# Play video\nvideo_path = \"/sdcard/movie.mp4\"\ndroid.videoPlay(video_path, wait=True)\n\n# Scan barcode from image\nresult = droid.scanBarcodeFromImage(\"/sdcard/qr_code.png\").result\nprint(f\"Barcode: {result}\")\n
"},{"location":"qsl4a/media/mediaplayer/","title":"Media Player API","text":"

Control audio and video playback.

"},{"location":"qsl4a/media/mediaplayer/#playback-control","title":"Playback Control","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplay","title":"mediaPlay()","text":"

Play media file.

mediaPlay(url, tag=\"default\", play=True)\n

Parameters: - url (str): Media file path or URL - tag (str): Player identifier - play (bool): Auto-start playback

"},{"location":"qsl4a/media/mediaplayer/#mediaplaystart","title":"mediaPlayStart()","text":"

Start playback.

mediaPlayStart(tag=\"default\")\n
"},{"location":"qsl4a/media/mediaplayer/#mediaplaypause","title":"mediaPlayPause()","text":"

Pause playback.

mediaPlayPause(tag=\"default\")\n
"},{"location":"qsl4a/media/mediaplayer/#mediaplayclose","title":"mediaPlayClose()","text":"

Close player.

mediaPlayClose(tag=\"default\")\n
"},{"location":"qsl4a/media/mediaplayer/#mediaplayseek","title":"mediaPlaySeek()","text":"

Seek to position.

mediaPlaySeek(msec, tag=\"default\")\n

Parameters: - msec (int): Position in milliseconds

"},{"location":"qsl4a/media/mediaplayer/#mediaplaysetlooping","title":"mediaPlaySetLooping()","text":"

Set loop mode.

mediaPlaySetLooping(enabled, tag=\"default\")\n
"},{"location":"qsl4a/media/mediaplayer/#player-info","title":"Player Info","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplayinfo","title":"mediaPlayInfo()","text":"

Get playback info.

mediaPlayInfo(tag=\"default\")\n

Returns: Dict with duration, position, etc.

"},{"location":"qsl4a/media/mediaplayer/#mediaisplaying","title":"mediaIsPlaying()","text":"

Check if playing.

mediaIsPlaying(tag=\"default\")\n

Returns: True/False

"},{"location":"qsl4a/media/mediaplayer/#mediaplaylist","title":"mediaPlayList()","text":"

List active players.

mediaPlayList()\n
"},{"location":"qsl4a/media/mediaplayer/#volume-control","title":"Volume Control","text":""},{"location":"qsl4a/media/mediaplayer/#getmediavolume","title":"getMediaVolume()","text":"

Get media volume.

getMediaVolume()\n

Returns: Volume level (0-15)

"},{"location":"qsl4a/media/mediaplayer/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

Get max media volume.

getMaxMediaVolume()\n
"},{"location":"qsl4a/media/mediaplayer/#getringervolume","title":"getRingerVolume()","text":"

Get ringer volume.

getRingerVolume()\n
"},{"location":"qsl4a/media/mediaplayer/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

Get max ringer volume.

getMaxRingerVolume()\n
"},{"location":"qsl4a/media/mediaplayer/#video-playback","title":"Video Playback","text":""},{"location":"qsl4a/media/mediaplayer/#videoplay","title":"videoPlay()","text":"

Play video fullscreen.

videoPlay(path, wait=True)\n

Parameters: - path (str): Video file path - wait (bool): Wait for playback to complete

"},{"location":"qsl4a/media/mediaplayer/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Play audio\ndroid.mediaPlay(\"/sdcard/music.mp3\", tag=\"music\")\n\n# Check status\nif droid.mediaIsPlaying(\"music\").result:\n    info = droid.mediaPlayInfo(\"music\").result\n    print(f\"Playing: {info}\")\n\n# Seek to 30 seconds\ndroid.mediaPlaySeek(30000, \"music\")\n\n# Close\ndroid.mediaPlayClose(\"music\")\n\n# Play video\ndroid.videoPlay(\"/sdcard/movie.mp4\", wait=True)\n
"},{"location":"qsl4a/special/cipher/","title":"Cipher API","text":"

Encryption and decryption utilities for secure data storage.

"},{"location":"qsl4a/special/cipher/#initialization","title":"Initialization","text":""},{"location":"qsl4a/special/cipher/#cipherinit","title":"cipherInit()","text":"

Initialize the cipher with encryption key and algorithm.

cipherInit(key, algorithm=\"AES/CBC/PKCS5Padding\", encodingFormat=\"\", initialVector=\"\")\n

Parameters: - key (str or bytes): Encryption key - algorithm (str): Cipher algorithm (default: \"AES/CBC/PKCS5Padding\") - encodingFormat (str): Encoding format - initialVector (str or bytes): Initial vector for encryption

Returns: Initialization result

Note: Must be called before any encrypt/decrypt operations.

"},{"location":"qsl4a/special/cipher/#encryption-methods","title":"Encryption Methods","text":""},{"location":"qsl4a/special/cipher/#encryptstring","title":"encryptString()","text":"

Encrypt a string.

encryptString(plainText)\n

Parameters: - plainText (str): Text to encrypt

Returns: Encrypted string

"},{"location":"qsl4a/special/cipher/#encryptbytes","title":"encryptBytes()","text":"

Encrypt bytes data.

encryptBytes(data)\n

Parameters: - data (bytes): Data to encrypt

Returns: Encrypted bytes

"},{"location":"qsl4a/special/cipher/#encryptstringtofile","title":"encryptStringToFile()","text":"

Encrypt string to file.

encryptStringToFile(plainText, filePath)\n

Parameters: - plainText (str): Text to encrypt - filePath (str): Output file path

"},{"location":"qsl4a/special/cipher/#encryptbytestofile","title":"encryptBytesToFile()","text":"

Encrypt bytes to file.

encryptBytesToFile(data, filePath)\n
"},{"location":"qsl4a/special/cipher/#decryption-methods","title":"Decryption Methods","text":""},{"location":"qsl4a/special/cipher/#decryptstring","title":"decryptString()","text":"

Decrypt to string.

decryptString(cipherText)\n

Parameters: - cipherText (str): Encrypted text

Returns: Decrypted string

"},{"location":"qsl4a/special/cipher/#decryptbytes","title":"decryptBytes()","text":"

Decrypt to bytes.

decryptBytes(data)\n

Returns: Decrypted bytes

"},{"location":"qsl4a/special/cipher/#decryptfiletostring","title":"decryptFileToString()","text":"

Decrypt file to string.

decryptFileToString(filePath)\n
"},{"location":"qsl4a/special/cipher/#decryptfiletobytes","title":"decryptFileToBytes()","text":"

Decrypt file to bytes.

decryptFileToBytes(filePath)\n
"},{"location":"qsl4a/special/cipher/#decryptfile","title":"decryptFile()","text":"

Decrypt file to file.

decryptFile(srcPath, destPath)\n
"},{"location":"qsl4a/special/cipher/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Initialize cipher with your encryption key\ndroid.cipherInit(\"my_secret_key_1234\")\n\n# Encrypt string\nencrypted = droid.encryptString(\"Secret message!\").result\nprint(f\"Encrypted: {encrypted}\")\n\n# Decrypt string\ndecrypted = droid.decryptString(encrypted).result\nprint(f\"Decrypted: {decrypted}\")\n\n# Encrypt to file\ndroid.encryptStringToFile(\"My secret data\", \"/sdcard/secret.dat\")\n\n# Decrypt from file\ndata = droid.decryptFileToString(\"/sdcard/secret.dat\").result\nprint(data)\n\n# Initialize with custom algorithm and IV\ndroid.cipherInit(\n    key=\"my_key\",\n    algorithm=\"AES/CBC/PKCS5Padding\",\n    initialVector=\"0123456789abcdef\"\n)\n
"},{"location":"qsl4a/special/pgptai/","title":"PGPT AI API","text":"

Speech-to-text and AI services integration.

"},{"location":"qsl4a/special/pgptai/#prerequisites","title":"Prerequisites","text":"
pip install pgptAI\n
"},{"location":"qsl4a/special/pgptai/#speech-recognition","title":"Speech Recognition","text":""},{"location":"qsl4a/special/pgptai/#speechtotext","title":"speechToText()","text":"

Convert speech to text.

speechToText(RecordSecond=10, AmrFile=None, Language=None)\n

Parameters: - RecordSecond (int): Recording duration in seconds - AmrFile (str, optional): Existing audio file path - Language (str, optional): Language code ('en', 'zh')

Returns: Transcribed text

"},{"location":"qsl4a/special/pgptai/#text-to-speech","title":"Text to Speech","text":""},{"location":"qsl4a/special/pgptai/#texttospeech","title":"textToSpeech()","text":"

Convert text to speech and optionally play it.

textToSpeech(Text, AutoPlay=True, WavFile=None, VoiceName=None)\n

Parameters: - Text (str): Text to convert to speech - AutoPlay (bool): Automatically play the generated audio (default: True) - WavFile (str, optional): Path to save the WAV file. If None, uses temporary file - VoiceName (str, optional): Voice name to use (e.g., 'en-US-JennyNeural', 'zh-CN-XiaoxiaoNeural')

Returns: Dict with speech synthesis result including: - text: The input text - url: URL to download the audio file - WavFile: Path to the saved WAV file (if saved locally)

"},{"location":"qsl4a/special/pgptai/#configuration","title":"Configuration","text":"

The API uses configuration from /storage/emulated/0/Android/data/org.qpython.qpy/files/apigpt.conf:

[speech]\nspeech_key = your_api_key\n

Default voice settings: - English: en-US-JennyNeural - Chinese: zh-CN-XiaoxiaoNeural

"},{"location":"qsl4a/special/pgptai/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Record and transcribe\nprint(\"Recording for 5 seconds...\")\ntext = droid.speechToText(RecordSecond=5, Language='en').result\nprint(f\"You said: {text}\")\n\n# Transcribe existing file\ntext = droid.speechToText(AmrFile=\"/sdcard/recording.amr\").result\nprint(f\"Transcription: {text}\")\n\n# Text to speech\ndroid.textToSpeech(\"Hello, this is a test message.\", AutoPlay=True, Language='en')\n\n# Text to speech with custom voice and save to file\nresult = droid.textToSpeech(\n    \"Welcome to QPython!\",\n    AutoPlay=False,\n    WavFile=\"/sdcard/welcome.wav\",\n    VoiceName=\"en-US-JennyNeural\"\n).result\nprint(f\"Audio saved to: {result.get('WavFile')}\")\n
"},{"location":"qsl4a/special/pgptai/#class-usage","title":"Class Usage","text":"
from androidhelper.pgptai import pgptai\nimport androidhelper\n\ndroid = androidhelper.Android()\nai = pgptai(droid)\n\n# Use speech recognition\ntext = ai.speechToText(RecordSecond=10)\n
"},{"location":"qsl4a/storage/clipboard/","title":"Clipboard API","text":"

Copy and paste text to system clipboard.

"},{"location":"qsl4a/storage/clipboard/#methods","title":"Methods","text":""},{"location":"qsl4a/storage/clipboard/#setclipboard","title":"setClipboard()","text":"

Copy text to clipboard.

setClipboard(text)\n

Parameters: - text (str): Text to copy

Returns: True if success

"},{"location":"qsl4a/storage/clipboard/#getclipboard","title":"getClipboard()","text":"

Get text from clipboard.

getClipboard()\n

Returns: Clipboard text

"},{"location":"qsl4a/storage/clipboard/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Copy to clipboard\ndroid.setClipboard(\"Hello from QPython!\")\n\n# Paste from clipboard\ntext = droid.getClipboard().result\nprint(f\"Clipboard: {text}\")\n
"},{"location":"qsl4a/storage/documentfile/","title":"DocumentFile API","text":"

File operations with SAF (Storage Access Framework) support for Android 4.4+.

"},{"location":"qsl4a/storage/documentfile/#directory-operations","title":"Directory Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfilemkdir","title":"documentFileMkdir()","text":"

Create directory.

documentFileMkdir(Dir)\n

Parameters: - Dir (str): Directory path

Returns: True if success

"},{"location":"qsl4a/storage/documentfile/#documentfilelistfiles","title":"documentFileListFiles()","text":"

List files in directory.

documentFileListFiles(Folder)\n

Returns: List of files

"},{"location":"qsl4a/storage/documentfile/#file-operations","title":"File Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfileexists","title":"documentFileExists()","text":"

Check if file or directory exists.

documentFileExists(path)\n

Parameters: - path (str): File or directory path

Returns: True if exists, False otherwise

"},{"location":"qsl4a/storage/documentfile/#documentfileisfile","title":"documentFileIsFile()","text":"

Check if path is a file.

documentFileIsFile(path)\n

Parameters: - path (str): Path to check

Returns: True if file, False if not a file, None if not exists

"},{"location":"qsl4a/storage/documentfile/#documentfileisdirectory","title":"documentFileIsDirectory()","text":"

Check if path is a directory.

documentFileIsDirectory(path)\n

Parameters: - path (str): Path to check

Returns: True if directory, False if not a directory, None if not exists

"},{"location":"qsl4a/storage/documentfile/#documentfiledelete","title":"documentFileDelete()","text":"

Delete file or directory.

documentFileDelete(FileOrTree)\n

Returns: True if success

"},{"location":"qsl4a/storage/documentfile/#documentfilerenameto","title":"documentFileRenameTo()","text":"

Rename or move file.

documentFileRenameTo(Src, Dest)\n

Returns: True if success

"},{"location":"qsl4a/storage/documentfile/#documentfilecopy","title":"documentFileCopy()","text":"

Copy file.

documentFileCopy(SrcFileOrTree, DestFileOrTree)\n
"},{"location":"qsl4a/storage/documentfile/#stream-operations","title":"Stream Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfileinputstream","title":"documentFileInputStream()","text":"

Read file content.

documentFileInputStream(srcFile, EncodingFormat=\"\", skip=None, length=None)\n

Parameters: - srcFile (str): Source file - EncodingFormat (str): \"UTF-8\", \"GBK\", \"Base64\", or \"\" for bytes - skip (int): Skip bytes from start - length (int): Read length

Returns: File content

"},{"location":"qsl4a/storage/documentfile/#documentfileoutputstream","title":"documentFileOutputStream()","text":"

Write file content.

documentFileOutputStream(destFile, src, EncodingFormat=\"\", append=None)\n

Parameters: - destFile (str): Destination file - src: Data to write - EncodingFormat (str): Encoding format - append (bool): Append mode

"},{"location":"qsl4a/storage/documentfile/#file-information","title":"File Information","text":""},{"location":"qsl4a/storage/documentfile/#documentfilelength","title":"documentFileLength()","text":"

Get file size in bytes.

documentFileLength(path)\n

Parameters: - path (str): File path

Returns: File size in bytes (0 if not exists)

"},{"location":"qsl4a/storage/documentfile/#documentfilelastmodified","title":"documentFileLastModified()","text":"

Get last modified time.

documentFileLastModified(path)\n

Parameters: - path (str): File path

Returns: Timestamp (0 if not exists)

"},{"location":"qsl4a/storage/documentfile/#documentfilegetstat","title":"documentFileGetStat()","text":"

Get comprehensive file statistics.

documentFileGetStat(path)\n

Parameters: - path (str): File path

Returns: Dict with length, last modified, and read/write permissions, or None if not exists

"},{"location":"qsl4a/storage/documentfile/#uri-operations","title":"URI Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfilegeturi","title":"documentFileGetUri()","text":"

Get URI from path.

documentFileGetUri(path, isDirectory=None)\n
"},{"location":"qsl4a/storage/documentfile/#documentfileshowopen","title":"documentFileShowOpen()","text":"

Show file picker.

documentFileShowOpen()\n

Returns: Selected file URI

"},{"location":"qsl4a/storage/documentfile/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Create directory\ndroid.documentFileMkdir(\"/sdcard/MyFolder\")\n\n# List files\nfiles = droid.documentFileListFiles(\"/sdcard\").result\nfor f in files:\n    print(f)\n\n# Read file\ncontent = droid.documentFileInputStream(\n    \"/sdcard/test.txt\",\n    EncodingFormat=\"UTF-8\"\n).result\nprint(content)\n\n# Write file\ndroid.documentFileOutputStream(\n    \"/sdcard/output.txt\",\n    \"Hello World\",\n    EncodingFormat=\"UTF-8\"\n)\n
"},{"location":"qsl4a/storage/preferences/","title":"Preferences API","text":"

Store and retrieve data using Android SharedPreferences.

"},{"location":"qsl4a/storage/preferences/#preference-methods","title":"Preference Methods","text":""},{"location":"qsl4a/storage/preferences/#prefgetvalue","title":"prefGetValue()","text":"

Read a value from shared preferences.

prefGetValue(key, filename=None)\n

Parameters: - key (str): Preference key - filename (str, optional): Preference file name

Returns: The stored value (any type)

"},{"location":"qsl4a/storage/preferences/#prefputvalue","title":"prefPutValue()","text":"

Write a value to shared preferences.

prefPutValue(key, value, filename=None)\n

Parameters: - key (str): Preference key - value (object): Value to store - filename (str, optional): Preference file name

"},{"location":"qsl4a/storage/preferences/#prefgetall","title":"prefGetAll()","text":"

Get all preference values.

prefGetAll(filename=None)\n

Parameters: - filename (str, optional): Preference file name

Returns: Map of all preferences

"},{"location":"qsl4a/storage/preferences/#prefremovevalue","title":"prefRemoveValue()","text":"

Remove a value from shared preferences.

prefRemoveValue(key, filename=None)\n

Parameters: - key (str): Preference key to remove - filename (str, optional): Preference file name

"},{"location":"qsl4a/storage/preferences/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Store values\ndroid.prefPutValue(\"username\", \"alice\")\ndroid.prefPutValue(\"score\", 100)\ndroid.prefPutValue(\"enabled\", True)\n\n# Read a specific value\nusername = droid.prefGetValue(\"username\").result\nprint(f\"Username: {username}\")\n\n# Get all preferences\nall_prefs = droid.prefGetAll().result\nprint(f\"All prefs: {all_prefs}\")\n\n# Remove a value\ndroid.prefRemoveValue(\"score\")\n\n# Use custom filename\ndroid.prefPutValue(\"token\", \"abc123\", filename=\"auth.prefs\")\ntoken = droid.prefGetValue(\"token\", filename=\"auth.prefs\").result\n
"},{"location":"qsl4a/system/activityresult/","title":"Activity Result API","text":"

Set activity results for scripts launched via startActivityForResult.

"},{"location":"qsl4a/system/activityresult/#result-methods","title":"Result Methods","text":""},{"location":"qsl4a/system/activityresult/#setresultboolean","title":"setResultBoolean()","text":"

Set a boolean result.

setResultBoolean(resultCode, resultValue)\n

Parameters: - resultCode (int): Result code - resultValue (bool): Boolean result value

"},{"location":"qsl4a/system/activityresult/#setresultbyte","title":"setResultByte()","text":"

Set a byte result.

setResultByte(resultCode, resultValue)\n

Parameters: - resultCode (int): Result code - resultValue (int): Byte result value

"},{"location":"qsl4a/system/activityresult/#setresultshort","title":"setResultShort()","text":"

Set a short result.

setResultShort(resultCode, resultValue)\n

Parameters: - resultCode (int): Result code - resultValue (int): Short result value

"},{"location":"qsl4a/system/activityresult/#setresultchar","title":"setResultChar()","text":"

Set a character result.

setResultChar(resultCode, resultValue)\n

Parameters: - resultCode (int): Result code - resultValue (str): Character result value

"},{"location":"qsl4a/system/activityresult/#setresultinteger","title":"setResultInteger()","text":"

Set an integer result.

setResultInteger(resultCode, resultValue)\n

Parameters: - resultCode (int): Result code - resultValue (int): Integer result value

"},{"location":"qsl4a/system/activityresult/#setresultlong","title":"setResultLong()","text":"

Set a long result.

setResultLong(resultCode, resultValue)\n

Parameters: - resultCode (int): Result code - resultValue (int): Long result value

"},{"location":"qsl4a/system/activityresult/#setresultfloat","title":"setResultFloat()","text":"

Set a float result.

setResultFloat(resultCode, resultValue)\n

Parameters: - resultCode (int): Result code - resultValue (float): Float result value

"},{"location":"qsl4a/system/activityresult/#setresultdouble","title":"setResultDouble()","text":"

Set a double result.

setResultDouble(resultCode, resultValue)\n

Parameters: - resultCode (int): Result code - resultValue (float): Double result value

"},{"location":"qsl4a/system/activityresult/#setresultstring","title":"setResultString()","text":"

Set a string result.

setResultString(resultCode, resultValue)\n

Parameters: - resultCode (int): Result code - resultValue (str): String result value

"},{"location":"qsl4a/system/activityresult/#setresultbooleanarray","title":"setResultBooleanArray()","text":"

Set a boolean array result.

setResultBooleanArray(resultCode, resultValue)\n

Parameters: - resultCode (int): Result code - resultValue (list): Boolean array

"},{"location":"qsl4a/system/activityresult/#setresultbytearray","title":"setResultByteArray()","text":"

Set a byte array result.

setResultByteArray(resultCode, resultValue)\n

Parameters: - resultCode (int): Result code - resultValue (list): Byte array

"},{"location":"qsl4a/system/activityresult/#setresultshortarray","title":"setResultShortArray()","text":"

Set a short array result.

setResultShortArray(resultCode, resultValue)\n

Parameters: - resultCode (int): Result code - resultValue (list): Short array

"},{"location":"qsl4a/system/activityresult/#setresultchararray","title":"setResultCharArray()","text":"

Set a character array result.

setResultCharArray(resultCode, resultValue)\n

Parameters: - resultCode (int): Result code - resultValue (list): Char array

"},{"location":"qsl4a/system/activityresult/#setresultintegerarray","title":"setResultIntegerArray()","text":"

Set an integer array result.

setResultIntegerArray(resultCode, resultValue)\n

Parameters: - resultCode (int): Result code - resultValue (list): Integer array

"},{"location":"qsl4a/system/activityresult/#setresultlongarray","title":"setResultLongArray()","text":"

Set a long array result.

setResultLongArray(resultCode, resultValue)\n

Parameters: - resultCode (int): Result code - resultValue (list): Long array

"},{"location":"qsl4a/system/activityresult/#setresultfloatarray","title":"setResultFloatArray()","text":"

Set a float array result.

setResultFloatArray(resultCode, resultValue)\n

Parameters: - resultCode (int): Result code - resultValue (list): Float array

"},{"location":"qsl4a/system/activityresult/#setresultdoublearray","title":"setResultDoubleArray()","text":"

Set a double array result.

setResultDoubleArray(resultCode, resultValue)\n

Parameters: - resultCode (int): Result code - resultValue (list): Double array

"},{"location":"qsl4a/system/activityresult/#setresultstringarray","title":"setResultStringArray()","text":"

Set a string array result.

setResultStringArray(resultCode, resultValue)\n

Parameters: - resultCode (int): Result code - resultValue (list): String array

"},{"location":"qsl4a/system/activityresult/#setresultserializable","title":"setResultSerializable()","text":"

Set a serializable result.

setResultSerializable(resultCode, resultValue)\n

Parameters: - resultCode (int): Result code - resultValue: Serializable result value

"},{"location":"qsl4a/system/activityresult/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# After performing an activity, set the result\n# Example: Return success with data\ndroid.setResultInteger(0, 200)  # RESULT_OK\ndroid.setResultString(0, \"Operation completed successfully\")\n\n# Return an array result\ndroid.setResultIntegerArray(0, [1, 2, 3, 4, 5])\n
"},{"location":"qsl4a/system/application/","title":"Application Management","text":"

Manage applications, launch apps, and query system information.

"},{"location":"qsl4a/system/application/#application-information","title":"Application Information","text":""},{"location":"qsl4a/system/application/#getapplicationinfo","title":"getApplicationInfo()","text":"

Get information about an app.

getApplicationInfo(packageName=None)\n

Parameters: - packageName (str): Package name (None = current app)

Returns: App info dict

"},{"location":"qsl4a/system/application/#getinstalledpackages","title":"getInstalledPackages()","text":"

Get list of installed packages.

getInstalledPackages(flag=4)\n

Parameters: - flag (int): Package flag filter (default: 4)

Returns: List of installed packages

"},{"location":"qsl4a/system/application/#getrunningpackages","title":"getRunningPackages()","text":"

List running packages.

getRunningPackages()\n

Returns: List of package names

"},{"location":"qsl4a/system/application/#getlaunchablepackages","title":"getLaunchablePackages()","text":"

Get list of launchable packages.

getLaunchablePackages(needClassName=False)\n

Parameters: - needClassName (bool): Include main activity class name (default: False)

Returns: List of launchable package names or dict with class names

"},{"location":"qsl4a/system/application/#application-control","title":"Application Control","text":""},{"location":"qsl4a/system/application/#launch","title":"launch()","text":"

Launch an application.

launch(classname=None, packagename=None, wait=True)\n

Parameters: - classname (str): Main activity class name - packagename (str): Package name - wait (bool): Wait for launch to complete (default: True)

Returns: Launch result

"},{"location":"qsl4a/system/application/#forcestoppackage","title":"forceStopPackage()","text":"

Force stop an application.

forceStopPackage(packageName)\n

Parameters: - packageName (str): Package name to stop

"},{"location":"qsl4a/system/application/#version-information","title":"Version Information","text":""},{"location":"qsl4a/system/application/#getpackageversion","title":"getPackageVersion()","text":"

Get app version name.

getPackageVersion(packageName)\n

Returns: Version string (e.g., \"3.2.1\")

"},{"location":"qsl4a/system/application/#getpackageversioncode","title":"getPackageVersionCode()","text":"

Get app version code.

getPackageVersionCode(packageName)\n

Returns: Version code integer

"},{"location":"qsl4a/system/application/#getconstants","title":"getConstants()","text":"

Get class constants.

getConstants(classname)\n

Parameters: - classname (str): Full class name

Returns: Dict of constant names and values

"},{"location":"qsl4a/system/application/#system-features","title":"System Features","text":""},{"location":"qsl4a/system/application/#backgroundprotect","title":"backgroundProtect()","text":"

Enable or disable background protection for the app.

backgroundProtect(enabled=True)\n

Parameters: - enabled (bool): True to enable protection, False to disable

"},{"location":"qsl4a/system/application/#createscriptshortcut","title":"createScriptShortCut()","text":"

Create a home screen shortcut for a script.

createScriptShortCut(scriptPath, label=None, iconPath=None, scriptArg=None)\n

Parameters: - scriptPath (str): Path to the Python script - label (str, optional): Shortcut label - iconPath (str, optional): Path to icon image - scriptArg (str, optional): Argument to pass to script

"},{"location":"qsl4a/system/application/#device-information","title":"Device Information","text":""},{"location":"qsl4a/system/application/#getandroidid","title":"getAndroidID()","text":"

Get Android device ID.

getAndroidID()\n

Returns: Unique Android device ID string

"},{"location":"qsl4a/system/application/#getsysinfo","title":"getSysInfo()","text":"

Get system information.

getSysInfo()\n

Returns: Dict with system details

"},{"location":"qsl4a/system/application/#getlocale","title":"getLocale()","text":"

Get device locale.

getLocale()\n

Returns: Locale string (e.g., \"en_US\")

"},{"location":"qsl4a/system/application/#getharmonyosinformation","title":"getHarmonyOsInformation()","text":"

Get HarmonyOS information if running on HarmonyOS.

getHarmonyOsInformation()\n

Returns: HarmonyOS version info or None

"},{"location":"qsl4a/system/application/#isexternalstoragemanager","title":"isExternalStorageManager()","text":"

Check if app has external storage manager permission.

isExternalStorageManager()\n

Returns: True if has permission

"},{"location":"qsl4a/system/application/#memory-and-display","title":"Memory and Display","text":""},{"location":"qsl4a/system/application/#getmemoryinfo","title":"getMemoryInfo()","text":"

Get memory information.

getMemoryInfo()\n

Returns: Dict with memory stats

"},{"location":"qsl4a/system/application/#getscreeninfo","title":"getScreenInfo()","text":"

Get screen information.

getScreenInfo()\n

Returns: Dict with width, height, density

"},{"location":"qsl4a/system/application/#permissions","title":"Permissions","text":""},{"location":"qsl4a/system/application/#checkpermissions","title":"checkPermissions()","text":"

Check current app permissions.

checkPermissions()\n

Returns: Dict of permissions and their status

"},{"location":"qsl4a/system/application/#requestpermissions","title":"requestPermissions()","text":"

Request permissions from the user.

requestPermissions(permissions=None)\n

Parameters: - permissions (list, optional): List of permissions to request. If None, requests all needed permissions.

Returns: Result of permission request

"},{"location":"qsl4a/system/application/#system-actions","title":"System Actions","text":""},{"location":"qsl4a/system/application/#showscreenlock","title":"showScreenLock()","text":"

Show screen lock (PIN/pattern/password entry).

showScreenLock()\n
"},{"location":"qsl4a/system/application/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get system info\ninfo = droid.getSysInfo().result\nprint(f\"System: {info}\")\n\n# Get app version\nversion = droid.getPackageVersion(\"org.qpython.qpy\").result\nprint(f\"QPython version: {version}\")\n\n# List installed apps\napps = droid.getInstalledPackages().result\nprint(f\"Installed apps: {len(apps)}\")\n\n# Launch an app\ndroid.launch(packagename=\"com.android.settings\")\n\n# Check permissions\nperms = droid.checkPermissions().result\nprint(f\"Permissions: {perms}\")\n\n# Request storage permission\ndroid.requestPermissions([\"android.permission.READ_EXTERNAL_STORAGE\"])\n\n# Create shortcut\ndroid.createScriptShortCut(\n    \"/sdcard/my_script.py\",\n    label=\"My Script\",\n    iconPath=\"/sdcard/icon.png\"\n)\n
"},{"location":"qsl4a/system/battery/","title":"Battery API","text":"

Monitor device battery status and health.

"},{"location":"qsl4a/system/battery/#methods","title":"Methods","text":""},{"location":"qsl4a/system/battery/#readbatterydata","title":"readBatteryData()","text":"

Get complete battery information.

readBatteryData()\n

Returns: Dict with battery data

"},{"location":"qsl4a/system/battery/#batterystartmonitoring","title":"batteryStartMonitoring()","text":"

Start battery monitoring.

batteryStartMonitoring()\n
"},{"location":"qsl4a/system/battery/#batterystopmonitoring","title":"batteryStopMonitoring()","text":"

Stop battery monitoring.

batteryStopMonitoring()\n
"},{"location":"qsl4a/system/battery/#batterygetlevel","title":"batteryGetLevel()","text":"

Get battery percentage.

batteryGetLevel()\n

Returns: Int (0-100)

"},{"location":"qsl4a/system/battery/#batterygetstatus","title":"batteryGetStatus()","text":"

Get charging status.

batteryGetStatus()\n

Returns: - 1: Unknown - 2: Charging - 3: Discharging - 4: Not charging - 5: Full

"},{"location":"qsl4a/system/battery/#batterygetplugtype","title":"batteryGetPlugType()","text":"

Get power source.

batteryGetPlugType()\n

Returns: - -1: Unknown - 0: Unplugged - 1: AC charger - 2: USB port

"},{"location":"qsl4a/system/battery/#batterygethealth","title":"batteryGetHealth()","text":"

Get battery health.

batteryGetHealth()\n

Returns: - 1: Unknown - 2: Good - 3: Overheat - 4: Dead - 5: Over voltage - 6: Unspecified failure

"},{"location":"qsl4a/system/battery/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get battery level\nlevel = droid.batteryGetLevel().result\nprint(f\"Battery: {level}%\")\n
"},{"location":"qsl4a/system/qpyinterface/","title":"QPython Interface API","text":"

Execute QPython scripts and manage shared variables from other apps.

"},{"location":"qsl4a/system/qpyinterface/#script-execution-methods","title":"Script Execution Methods","text":""},{"location":"qsl4a/system/qpyinterface/#executeqpy","title":"executeQPy()","text":"

Execute a QPython script.

executeQPy(path=\"\", arg=None)\n

Parameters: - path (str): Path to the script file - arg (str, optional): Command line arguments

Returns: True if started successfully

"},{"location":"qsl4a/system/qpyinterface/#executeqpyassrv","title":"executeQPyAsSrv()","text":"

Execute a QPython script as a service.

executeQPyAsSrv(path=None)\n

Parameters: - path (str, optional): Path to the script file

Returns: True if started successfully

"},{"location":"qsl4a/system/qpyinterface/#executeqpycode","title":"executeQPyCode()","text":"

Execute Python code directly.

executeQPyCode(code=None)\n

Parameters: - code (str, optional): Python code to execute

Returns: True if started successfully

"},{"location":"qsl4a/system/qpyinterface/#executeqpycodeassrv","title":"executeQPyCodeAsSrv()","text":"

Execute Python code as a service.

executeQPyCodeAsSrv(code=None)\n

Parameters: - code (str, optional): Python code to execute

Returns: True if started successfully

"},{"location":"qsl4a/system/qpyinterface/#shared-variables","title":"Shared Variables","text":"

Shared variables allow communication between QPython and other apps.

"},{"location":"qsl4a/system/qpyinterface/#sharedvariableset","title":"sharedVariableSet()","text":"

Set a Java shared variable.

sharedVariableSet(key, value)\n

Parameters: - key (str): Variable name - value (str): Variable value

Returns: The stored value

"},{"location":"qsl4a/system/qpyinterface/#sharedvariableget","title":"sharedVariableGet()","text":"

Get a Java shared variable.

sharedVariableGet(key)\n

Parameters: - key (str): Variable name

Returns: The stored value

"},{"location":"qsl4a/system/qpyinterface/#sharedvariableremove","title":"sharedVariableRemove()","text":"

Remove a Java shared variable.

sharedVariableRemove(key)\n

Parameters: - key (str): Variable name to remove

Returns: The removed value

"},{"location":"qsl4a/system/qpyinterface/#getlastlog","title":"getLastLog()","text":"

Get the last log output from QPython.

getLastLog()\n

Returns: String log content

"},{"location":"qsl4a/system/qpyinterface/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Execute a script\ndroid.executeQPy(\"/sdcard/my_script.py\", arg=\"test\")\n\n# Execute code directly\ncode = \"print('Hello from QPython!')\"\ndroid.executeQPyCode(code)\n\n# Use shared variables\ndroid.sharedVariableSet(\"username\", \"alice\")\nusername = droid.sharedVariableGet(\"username\").result\nprint(f\"Username: {username}\")\n\n# Remove variable\ndroid.sharedVariableRemove(\"username\")\n\n# Get recent log\nlog = droid.getLastLog().result\nprint(f\"Log: {log}\")\n
"},{"location":"qsl4a/system/sensors/","title":"Sensor API","text":"

Access device sensors including accelerometer, gyroscope, magnetometer, and more.

"},{"location":"qsl4a/system/sensors/#methods","title":"Methods","text":""},{"location":"qsl4a/system/sensors/#startsensingtimed","title":"startSensingTimed()","text":"

Start sensor monitoring with time intervals.

startSensingTimed(sensorNumber, delayTime)\n

Parameters: - sensorNumber (int): Sensor ID (1-3 typically) - delayTime (int): Delay between readings in milliseconds

"},{"location":"qsl4a/system/sensors/#startsensingthreshold","title":"startSensingThreshold()","text":"

Start sensor monitoring with threshold trigger.

startSensingThreshold(sensorNumber, threshold, axis)\n

Parameters: - sensorNumber (int): Sensor ID - threshold (float): Trigger threshold - axis (int): Axis to monitor (0=X, 1=Y, 2=Z)

"},{"location":"qsl4a/system/sensors/#stopsensing","title":"stopSensing()","text":"

Stop all sensor monitoring.

stopSensing()\n
"},{"location":"qsl4a/system/sensors/#readsensors","title":"readSensors()","text":"

Read current sensor data.

readSensors()\n

Returns: Sensor data dict

"},{"location":"qsl4a/system/sensors/#sensorsreadaccelerometer","title":"sensorsReadAccelerometer()","text":"

Read accelerometer values.

sensorsReadAccelerometer()\n

Returns: List [X, Y, Z] in m/s\u00b2

"},{"location":"qsl4a/system/sensors/#sensorsreadgyroscope","title":"sensorsReadGyroscope()","text":"

Read gyroscope values.

sensorsReadGyroscope()\n

Returns: List [X, Y, Z] in rad/s

"},{"location":"qsl4a/system/sensors/#sensorsreadmagnetometer","title":"sensorsReadMagnetometer()","text":"

Read magnetic field values.

sensorsReadMagnetometer()\n

Returns: List [X, Y, Z] in \u03bcT

"},{"location":"qsl4a/system/sensors/#sensorsreadorientation","title":"sensorsReadOrientation()","text":"

Read device orientation.

sensorsReadOrientation()\n

Returns: List [azimuth, pitch, roll] in degrees

"},{"location":"qsl4a/system/sensors/#sensorsgetlight","title":"sensorsGetLight()","text":"

Read light sensor value.

sensorsGetLight()\n

Returns: Light level in lux

"},{"location":"qsl4a/system/sensors/#sensorsgetstepcounter","title":"sensorsGetStepCounter()","text":"

Read step counter.

sensorsGetStepCounter()\n

Returns: Number of steps

"},{"location":"qsl4a/system/sensors/#sensorsgetaccuracy","title":"sensorsGetAccuracy()","text":"

Get the current sensor accuracy.

sensorsGetAccuracy()\n

Returns: Accuracy value (0-3: UNRELIABLE, ACCURACY_LOW, ACCURACY_MEDIUM, ACCURACY_HIGH)

"},{"location":"qsl4a/system/sensors/#usage-example","title":"Usage Example","text":"
import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start sensing\ndroid.startSensingTimed(1, 250)\n\n# Read sensors 10 times\nfor i in range(10):\n    accel = droid.sensorsReadAccelerometer().result\n    print(f\"Accel: X={accel[0]:.2f}, Y={accel[1]:.2f}, Z={accel[2]:.2f}\")\n    time.sleep(0.5)\n\ndroid.stopSensing()\n
"},{"location":"qsl4a/system/settings/","title":"Settings API","text":"

Control system settings including screen, sound, and network settings.

"},{"location":"qsl4a/system/settings/#screen-settings","title":"Screen Settings","text":""},{"location":"qsl4a/system/settings/#setscreentimeout","title":"setScreenTimeout()","text":"

Set the screen timeout value.

setScreenTimeout(value)\n

Parameters: - value (int): Screen timeout in seconds

Returns: Previous timeout value

"},{"location":"qsl4a/system/settings/#getscreentimeout","title":"getScreenTimeout()","text":"

Get the current screen timeout.

getScreenTimeout()\n

Returns: Current screen timeout in seconds

"},{"location":"qsl4a/system/settings/#getscreenbrightness","title":"getScreenBrightness()","text":"

Get the screen brightness value.

getScreenBrightness()\n

Returns: Brightness value (0-255)

"},{"location":"qsl4a/system/settings/#setscreenbrightness","title":"setScreenBrightness()","text":"

Set the screen brightness.

setScreenBrightness(value=None)\n

Parameters: - value (int, optional): Brightness value (0-255), or None for auto

Returns: Previous brightness value

"},{"location":"qsl4a/system/settings/#checkscreenon","title":"checkScreenOn()","text":"

Check if the screen is on.

checkScreenOn()\n

Returns: True if screen is on, False otherwise

"},{"location":"qsl4a/system/settings/#airplane-mode","title":"Airplane Mode","text":""},{"location":"qsl4a/system/settings/#checkairplanemode","title":"checkAirplaneMode()","text":"

Check if airplane mode is enabled.

checkAirplaneMode()\n

Returns: True if airplane mode is on

"},{"location":"qsl4a/system/settings/#ringer-settings","title":"Ringer Settings","text":""},{"location":"qsl4a/system/settings/#checkringersilentmode","title":"checkRingerSilentMode()","text":"

Check if ringer is in silent mode.

checkRingerSilentMode()\n

Returns: True if silent mode is on

"},{"location":"qsl4a/system/settings/#toggleringersilentmode","title":"toggleRingerSilentMode()","text":"

Toggle ringer silent mode.

toggleRingerSilentMode(enabled=None)\n

Parameters: - enabled (bool, optional): True to enable, False to disable, None to toggle

Returns: New state

"},{"location":"qsl4a/system/settings/#togglevibratemode","title":"toggleVibrateMode()","text":"

Toggle vibrate mode.

toggleVibrateMode(enabled=None, ringer=None)\n

Parameters: - enabled (bool, optional): Toggle vibrate on/off - ringer (bool, optional): Apply to ringer mode

Returns: New state

"},{"location":"qsl4a/system/settings/#getvibratemode","title":"getVibrateMode()","text":"

Get the vibrate mode setting.

getVibrateMode(ringer=None)\n

Parameters: - ringer (bool, optional): Check ringer vibrate mode

Returns: True if vibrate is enabled

"},{"location":"qsl4a/system/settings/#volume-settings","title":"Volume Settings","text":""},{"location":"qsl4a/system/settings/#getringervolume","title":"getRingerVolume()","text":"

Get the current ringer volume.

getRingerVolume()\n

Returns: Ringer volume level (0-7 typically)

"},{"location":"qsl4a/system/settings/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

Get the maximum ringer volume.

getMaxRingerVolume()\n

Returns: Maximum ringer volume

"},{"location":"qsl4a/system/settings/#setringervolume","title":"setRingerVolume()","text":"

Set the ringer volume.

setRingerVolume(volume)\n

Parameters: - volume (int): Volume level

"},{"location":"qsl4a/system/settings/#getmediavolume","title":"getMediaVolume()","text":"

Get the current media volume.

getMediaVolume()\n

Returns: Media volume level (0-15 typically)

"},{"location":"qsl4a/system/settings/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

Get the maximum media volume.

getMaxMediaVolume()\n

Returns: Maximum media volume

"},{"location":"qsl4a/system/settings/#setmediavolume","title":"setMediaVolume()","text":"

Set the media volume.

setMediaVolume(volume)\n

Parameters: - volume (int): Volume level

"},{"location":"qsl4a/system/settings/#system-info","title":"System Info","text":""},{"location":"qsl4a/system/settings/#elapsedrealtimenanos","title":"elapsedRealtimeNanos()","text":"

Get nanoseconds since system startup.

elapsedRealtimeNanos()\n

Returns: Nanoseconds (can be used for timing)

"},{"location":"qsl4a/system/settings/#gettrafficstats","title":"getTrafficStats()","text":"

Get network traffic statistics.

getTrafficStats(flags=7)\n

Parameters: - flags (int): Which stats to retrieve (default: 7 = all)

Returns: Dict with transmit/receive bytes

"},{"location":"qsl4a/system/settings/#getapptxbytes","title":"getAppTxBytes()","text":"

Get transmit bytes for QPython app.

getAppTxBytes(packageName)\n

Parameters: - packageName (str): Package name

Returns: Dict with tx/rx bytes

"},{"location":"qsl4a/system/settings/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Screen settings\ncurrent_timeout = droid.getScreenTimeout().result\nprint(f\"Current timeout: {current_timeout}s\")\ndroid.setScreenTimeout(30)\n\n# Check screen\nif droid.checkScreenOn().result:\n    print(\"Screen is on\")\n\n# Volume control\nmedia_vol = droid.getMediaVolume().result\nprint(f\"Media volume: {media_vol}\")\ndroid.setMediaVolume(10)\n\n# Check airplane mode\nif droid.checkAirplaneMode().result:\n    print(\"Airplane mode is on\")\n
"},{"location":"qsl4a/system/sysinfo/","title":"System Information","text":"

Retrieve device and system information.

"},{"location":"qsl4a/system/sysinfo/#device-information","title":"Device Information","text":""},{"location":"qsl4a/system/sysinfo/#getandroidid","title":"getAndroidID()","text":"

Get the Android device ID.

getAndroidID()\n

Returns: String device ID

"},{"location":"qsl4a/system/sysinfo/#getsysinfo","title":"getSysInfo()","text":"

Get comprehensive system information.

getSysInfo()\n

Returns: Dict with system details

"},{"location":"qsl4a/system/sysinfo/#getlocale","title":"getLocale()","text":"

Get device locale settings.

getLocale()\n

Returns: Locale string (e.g., \"en_US\")

"},{"location":"qsl4a/system/sysinfo/#memory","title":"Memory","text":""},{"location":"qsl4a/system/sysinfo/#getmemoryinfo","title":"getMemoryInfo()","text":"

Get RAM information.

getMemoryInfo()\n

Returns: Dict with memory stats

"},{"location":"qsl4a/system/sysinfo/#display","title":"Display","text":""},{"location":"qsl4a/system/sysinfo/#getscreeninfo","title":"getScreenInfo()","text":"

Get display information.

getScreenInfo()\n

Returns: Dict with width, height, density

"},{"location":"qsl4a/system/sysinfo/#identifiers","title":"Identifiers","text":""},{"location":"qsl4a/system/sysinfo/#getimei","title":"getImei()","text":"

Get device IMEI.

getImei(slotIndex=None)\n
"},{"location":"qsl4a/system/sysinfo/#getmeid","title":"getMeid()","text":"

Get device MEID.

getMeid(slotIndex=None)\n
"},{"location":"qsl4a/system/sysinfo/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Device ID\nandroid_id = droid.getAndroidID().result\nprint(f\"Android ID: {android_id}\")\n\n# Screen info\nscreen = droid.getScreenInfo().result\nprint(f\"Screen: {screen['width']}x{screen['height']}\")\n\n# Memory\nmemory = droid.getMemoryInfo().result\nprint(f\"Memory: {memory}\")\n
"},{"location":"qsl4a/system/wakelock/","title":"WakeLock API","text":"

Control device wake locks to keep the CPU or screen on.

"},{"location":"qsl4a/system/wakelock/#wake-lock-types","title":"Wake Lock Types","text":"

QSL4A provides different wake lock types:

Type Description Full CPU on, screen bright, keyboard bright Partial CPU on only Bright CPU on, screen bright Dim CPU on, screen dim"},{"location":"qsl4a/system/wakelock/#wake-lock-methods","title":"Wake Lock Methods","text":""},{"location":"qsl4a/system/wakelock/#wakelockacquirefull","title":"wakeLockAcquireFull()","text":"

Acquire a full wake lock (CPU on, screen bright, keyboard bright).

wakeLockAcquireFull()\n
"},{"location":"qsl4a/system/wakelock/#wakelockacquirepartial","title":"wakeLockAcquirePartial()","text":"

Acquire a partial wake lock (CPU on only).

wakeLockAcquirePartial()\n
"},{"location":"qsl4a/system/wakelock/#wakelockacquirebright","title":"wakeLockAcquireBright()","text":"

Acquire a bright wake lock (CPU on, screen bright).

wakeLockAcquireBright()\n
"},{"location":"qsl4a/system/wakelock/#wakelockacquiredim","title":"wakeLockAcquireDim()","text":"

Acquire a dim wake lock (CPU on, screen dim).

wakeLockAcquireDim()\n
"},{"location":"qsl4a/system/wakelock/#wakelockrelease","title":"wakeLockRelease()","text":"

Release the wake lock.

wakeLockRelease()\n
"},{"location":"qsl4a/system/wakelock/#usage-example","title":"Usage Example","text":"
import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Acquire full wake lock\ndroid.wakeLockAcquireFull()\n\n# Do important work while keeping screen on\nprint(\"Screen will stay on\")\ntime.sleep(10)\n\n# Release when done\ndroid.wakeLockRelease()\n\n# Or use partial lock for background tasks\ndroid.wakeLockAcquirePartial()\n# CPU stays on even with screen off\ntime.sleep(30)\ndroid.wakeLockRelease()\n

Note: Remember to release wake locks when no longer needed to conserve battery.

"},{"location":"qsl4a/ui/accessibility/","title":"Accessibility Service","text":"

The Accessibility Service allows automation of UI interactions like clicks, swipes, and system actions.

"},{"location":"qsl4a/ui/accessibility/#service-control","title":"Service Control","text":""},{"location":"qsl4a/ui/accessibility/#accessibilitystartservice","title":"accessibilityStartService()","text":"

Start the accessibility service.

accessibilityStartService()\n

Returns: True if successful, False otherwise

"},{"location":"qsl4a/ui/accessibility/#accessibilityserviceenabled","title":"accessibilityServiceEnabled()","text":"

Check if accessibility service is enabled.

accessibilityServiceEnabled()\n

Returns: True or False

"},{"location":"qsl4a/ui/accessibility/#screen-interactions","title":"Screen Interactions","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityclick","title":"accessibilityClick()","text":"

Click at screen coordinates.

accessibilityClick(x=0, y=0, t=50)\n

Parameters: - x (int/float): X coordinate (0=center, decimals supported) - y (int/float): Y coordinate (0=center, decimals supported) - t (int): Press duration in milliseconds (default: 50)

"},{"location":"qsl4a/ui/accessibility/#accessibilityslide","title":"accessibilitySlide()","text":"

Multi-point slide gesture.

accessibilitySlide(XnYn=None, t=None)\n

Parameters: - XnYn (list): Coordinates [X1, Y1, X2, Y2, ... Xn, Yn] - t (int): Slide duration (default: 50*n ms)

"},{"location":"qsl4a/ui/accessibility/#system-actions","title":"System Actions","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityaction","title":"accessibilityAction()","text":"

Execute system action by code.

accessibilityAction(actionCode)\n

Action Codes: | Code | Constant | Description | |------|----------|-------------| | 1 | BACK | Back button | | 2 | HOME | Home button | | 3 | RECENTS | Recent apps | | 4 | NOTIFICATIONS | Open notifications | | 5 | QUICK_SETTINGS | Open quick settings | | 6 | POWER_DIALOG | Power menu | | 7 | TOGGLE_SPLIT_SCREEN | Split screen | | 8 | LOCK_SCREEN | Lock screen | | 9 | TAKE_SCREENSHOT | Take screenshot | | 10 | KEYCODE_HEADSETHOOK | Headset hook | | 11-14 | ACCESSIBILITY_ | Accessibility buttons | | 15 | DISMISS_NOTIFICATION_SHADE | Close notifications | | 16-20 | DPAD_ | Directional pad | | 21 | MENU | Menu button | | 22 | MEDIA_PLAY_PAUSE | Play/Pause media |

"},{"location":"qsl4a/ui/accessibility/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/accessibility/#click-center-screen","title":"Click Center Screen","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Start service\nif not droid.accessibilityServiceEnabled().result:\n    droid.accessibilityStartService()\n\n# Click center (0,0 = center)\ndroid.accessibilityClick(0, 0, t=100)\n
"},{"location":"qsl4a/ui/accessibility/#swipe-gesture","title":"Swipe Gesture","text":"
# Swipe from bottom to top (scroll up)\ndroid.accessibilitySlide([0, 1.5, 0, -1.5], t=300)\n
"},{"location":"qsl4a/ui/accessibility/#system-navigation","title":"System Navigation","text":"
# Press home\ndroid.accessibilityAction(2)\n\n# Press back\ndroid.accessibilityAction(1)\n\n# Open notifications\ndroid.accessibilityAction(4)\n
"},{"location":"qsl4a/ui/accessibility/#tap-specific-location","title":"Tap Specific Location","text":"
# Tap at screen coordinate (500, 800)\ndroid.accessibilityClick(500, 800)\n\n# Tap at relative position (center horizontally, 3/4 down)\ndroid.accessibilityClick(0, 1.5)\n
"},{"location":"qsl4a/ui/dialogs/","title":"Dialog System","text":"

QSL4A provides comprehensive dialog support for user interaction, including alerts, input dialogs, choice dialogs, and progress dialogs.

"},{"location":"qsl4a/ui/dialogs/#alert-dialogs","title":"Alert Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowalert","title":"dialogShowAlert()","text":"

Show a simple alert dialog.

dialogShowAlert(title=\"Alert\", message=\"The message of the alert.\",\n                positiveButtonText=\"OK\", negativeButtonText=None,\n                neutralButtonText=None, messageIsHtml=False)\n

Parameters: - title (str): Dialog title - message (str): Message text - positiveButtonText (str): Positive button label - negativeButtonText (str, optional): Negative button label - neutralButtonText (str, optional): Neutral button label - messageIsHtml (bool): Parse message as HTML

Returns: Result with button clicked

"},{"location":"qsl4a/ui/dialogs/#dialogshowsimplechoice","title":"dialogShowSimpleChoice()","text":"

Show a simple choice dialog with items.

dialogShowSimpleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

Parameters: - items (list): List of choice strings

Returns: Result with selected item

"},{"location":"qsl4a/ui/dialogs/#input-dialogs","title":"Input Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialoggetinput","title":"dialogGetInput()","text":"

Get text input from user.

dialogGetInput(title=\"Value\", message=\"Please enter value:\",\n               defaultText=None, messageIsHtml=False)\n

Returns: Result with user's input text

"},{"location":"qsl4a/ui/dialogs/#dialoggetpassword","title":"dialogGetPassword()","text":"

Get password input.

dialogGetPassword(title=\"Password\", message=\"Please enter password:\")\n

Returns: Result with password entered

"},{"location":"qsl4a/ui/dialogs/#dialogcreateinput","title":"dialogCreateInput()","text":"

Create a custom input dialog.

dialogCreateInput(title=\"Value\", message=\"Please enter value:\",\n                  defaultText=None, inputType=None)\n

Parameters: - inputType (str): Input type (e.g., \"text\", \"number\", \"textPassword\")

"},{"location":"qsl4a/ui/dialogs/#dialogcreatepassword","title":"dialogCreatePassword()","text":"

Create a password input dialog.

dialogCreatePassword(title=\"Password\", message=\"Please enter password:\")\n
"},{"location":"qsl4a/ui/dialogs/#dialogcreateseekbar","title":"dialogCreateSeekBar()","text":"

Create a seek bar/slider dialog.

dialogCreateSeekBar(starting_value=50, maximum_value=100, title=\"\", message=\"\")\n

Parameters: - starting_value (int): Initial value - maximum_value (int): Maximum value

"},{"location":"qsl4a/ui/dialogs/#choice-dialogs","title":"Choice Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowsinglechoice","title":"dialogShowSingleChoice()","text":"

Show single choice (radio) dialog.

dialogShowSingleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, selected=-1, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

Parameters: - items (list): List of choice strings - selected (int): Default selected index

"},{"location":"qsl4a/ui/dialogs/#dialogshowmultichoice","title":"dialogShowMultiChoice()","text":"

Show multiple choice (checkbox) dialog.

dialogShowMultiChoice(title=\"Alert\", message=\"The message of the alert.\",\n                      items=None, selected=None, positiveButtonText=\"OK\",\n                      negativeButtonText=None, neutralButtonText=None,\n                      messageIsHtml=False)\n

Parameters: - items (list): List of choice strings - selected (list): List of initially selected indices

"},{"location":"qsl4a/ui/dialogs/#dialogsetsinglechoiceitems","title":"dialogSetSingleChoiceItems()","text":"

Set single choice items for a dialog.

dialogSetSingleChoiceItems(items, selected=-1)\n
"},{"location":"qsl4a/ui/dialogs/#dialogsetmultichoiceitems","title":"dialogSetMultiChoiceItems()","text":"

Set multiple choice items for a dialog.

dialogSetMultiChoiceItems(items, selected=None)\n
"},{"location":"qsl4a/ui/dialogs/#progress-dialogs","title":"Progress Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatespinnerprogress","title":"dialogCreateSpinnerProgress()","text":"

Create indeterminate progress dialog.

dialogCreateSpinnerProgress(title=None, message=None, maximum_progress=100)\n
"},{"location":"qsl4a/ui/dialogs/#dialogcreatehorizontalprogress","title":"dialogCreateHorizontalProgress()","text":"

Create horizontal progress dialog.

dialogCreateHorizontalProgress(title=None, message=None, maximum_progress=100)\n
"},{"location":"qsl4a/ui/dialogs/#dialogsetcurrentprogress","title":"dialogSetCurrentProgress()","text":"

Update progress value.

dialogSetCurrentProgress(current)\n
"},{"location":"qsl4a/ui/dialogs/#dialogsetmaxprogress","title":"dialogSetMaxProgress()","text":"

Set maximum progress value.

dialogSetMaxProgress(max)\n
"},{"location":"qsl4a/ui/dialogs/#dialogsetprogressmessage","title":"dialogSetProgressMessage()","text":"

Update the progress dialog message.

dialogSetProgressMessage(message)\n
"},{"location":"qsl4a/ui/dialogs/#picker-dialogs","title":"Picker Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatedatepicker","title":"dialogCreateDatePicker()","text":"

Create date picker dialog.

dialogCreateDatePicker(year=1970, month=1, day=1)\n
"},{"location":"qsl4a/ui/dialogs/#dialogcreatetimepicker","title":"dialogCreateTimePicker()","text":"

Create time picker dialog.

dialogCreateTimePicker(hour=0, minute=0, is24hour=False)\n
"},{"location":"qsl4a/ui/dialogs/#custom-dialog-creation","title":"Custom Dialog Creation","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatealert","title":"dialogCreateAlert()","text":"

Create a custom alert dialog.

dialogCreateAlert(title=None, message=None)\n

Creates an empty alert dialog. Use with other dialogSet* functions to customize.

"},{"location":"qsl4a/ui/dialogs/#dialogsetitems","title":"dialogSetItems()","text":"

Set simple list items for the dialog.

dialogSetItems(items)\n
"},{"location":"qsl4a/ui/dialogs/#dialogsetpositivebuttontext","title":"dialogSetPositiveButtonText()","text":"

Set positive button text.

dialogSetPositiveButtonText(text)\n
"},{"location":"qsl4a/ui/dialogs/#dialogsetnegativebuttontext","title":"dialogSetNegativeButtonText()","text":"

Set negative button text.

dialogSetNegativeButtonText(text)\n
"},{"location":"qsl4a/ui/dialogs/#dialogsetneutralbuttontext","title":"dialogSetNeutralButtonText()","text":"

Set neutral button text.

dialogSetNeutralButtonText(text)\n
"},{"location":"qsl4a/ui/dialogs/#dialogsetmessageishtml","title":"dialogSetMessageIsHtml()","text":"

Set whether message should be parsed as HTML.

dialogSetMessageIsHtml(messageIsHtml=True)\n
"},{"location":"qsl4a/ui/dialogs/#dialogshow","title":"dialogShow()","text":"

Show the created custom dialog.

dialogShow()\n
"},{"location":"qsl4a/ui/dialogs/#dialog-control","title":"Dialog Control","text":""},{"location":"qsl4a/ui/dialogs/#dialogdismiss","title":"dialogDismiss()","text":"

Dismiss current dialog.

dialogDismiss()\n
"},{"location":"qsl4a/ui/dialogs/#dialoggetresponse","title":"dialogGetResponse()","text":"

Get dialog response.

dialogGetResponse()\n
"},{"location":"qsl4a/ui/dialogs/#dialoggetselecteditems","title":"dialogGetSelectedItems()","text":"

Get selected items from choice dialog.

dialogGetSelectedItems()\n
"},{"location":"qsl4a/ui/dialogs/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/dialogs/#simple-alert","title":"Simple Alert","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Show alert\ndroid.dialogShowAlert(\"Warning\", \"This is an important message!\")\n
"},{"location":"qsl4a/ui/dialogs/#input-dialog","title":"Input Dialog","text":"
# Get user input\nresult = droid.dialogGetInput(\"Name\", \"Enter your name:\", \"John\").result\nprint(f\"Hello, {result}!\")\n
"},{"location":"qsl4a/ui/dialogs/#custom-dialog-with-buttons","title":"Custom Dialog with Buttons","text":"
# Create custom dialog\ndroid.dialogCreateAlert(\"Custom\", \"Choose an option\")\ndroid.dialogSetItems([\"Option 1\", \"Option 2\", \"Option 3\"])\ndroid.dialogShow()\n\n# Get response\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response['item']}\")\n
"},{"location":"qsl4a/ui/dialogs/#progress-dialog","title":"Progress Dialog","text":"
# Create progress dialog\ndroid.dialogCreateHorizontalProgress(\"Loading\", \"Please wait...\", 100)\ndroid.dialogShow()\n\n# Update progress\nfor i in range(101):\n    droid.dialogSetCurrentProgress(i)\n    time.sleep(0.05)\n\ndroid.dialogDismiss()\n
"},{"location":"qsl4a/ui/dialogs/#date-picker","title":"Date Picker","text":"
# Show date picker\ndroid.dialogCreateDatePicker(2024, 1, 15)\ndroid.dialogShow()\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response}\")\n
"},{"location":"qsl4a/ui/floatview/","title":"FloatView","text":"

Floating window support for overlay UI elements that stay on top of other applications.

"},{"location":"qsl4a/ui/floatview/#methods","title":"Methods","text":""},{"location":"qsl4a/ui/floatview/#floatview_1","title":"floatView()","text":"

Show or modify a floating view.

floatView(Args=None)\n

Parameters: - Args (dict): Configuration dictionary with the following keys: - index (int): Float view index (-1 to create new, >=0 to modify existing) - text (str): Text content to display - html (str): HTML content (used if text is omitted) - width (int): View width in pixels (default: 300) - height (int): View height in pixels (default: 150) - x (int): X position (0 = center, positive/negative for offset) - y (int): Y position (0 = center, positive/negative for offset) - backColor (str): Background color in ARGB hex (default: '7f7f7f7f') - textColor (str): Text color in ARGB hex (default: 'ff000000') - textSize (int): Text size (default: 10) - textAlign (int): Text alignment (0 = inherit) - script (str): Script path to run after long click close - arg: Script argument - clickRemove (bool): Enable click to remove (default: True) - flag (int): Window flag (default: 40 - touchable)

Returns: Current chain list length

"},{"location":"qsl4a/ui/floatview/#floatviewcount","title":"floatViewCount()","text":"

Get the number of active float views.

floatViewCount()\n

Returns: Number of float views

"},{"location":"qsl4a/ui/floatview/#floatviewresult","title":"floatViewResult()","text":"

Get the result/status of a float view.

floatViewResult(index=-1)\n

Parameters: - index (int): Float view index (default: -1, returns last operation result)

Returns: Dict with operation details including: - x, y: Position - time: Timestamp - operation: Operation type ('initial', 'move', etc.) - index: View index - removed: True if view was removed

"},{"location":"qsl4a/ui/floatview/#floatviewremove","title":"floatViewRemove()","text":"

Remove a float view.

floatViewRemove(index=-1)\n

Parameters: - index (int): Index of view to remove (default: -1 removes the last one)

Returns: 1 if successful, 0 otherwise

"},{"location":"qsl4a/ui/floatview/#constants","title":"Constants","text":"
  • floatView.INDEX_NEW = -1 - Create new float view
  • floatView.FLAG_DEFAULT_TOUCHABLE = 40 - Default touchable flag
  • floatView.TEXT_ALIGNMENT_INHERIT = 0
  • floatView.TEXT_ALIGNMENT_CENTER - Center text alignment
"},{"location":"qsl4a/ui/floatview/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/floatview/#basic-float-view","title":"Basic Float View","text":"
import androidhelper\nfrom androidhelper import Android\n\ndroid = androidhelper.Android()\n\n# Create a simple float view\ndroid.floatView({\n    'index': -1,  # Create new\n    'text': 'Hello World',\n    'width': 400,\n    'height': 300,\n    'x': -300,  # Offset from center\n    'y': -400,\n    'backColor': 'ff0000',  # Red background\n    'textColor': '0000ff',  # Blue text\n    'textSize': 16,\n    'textAlign': droid.floatView.TEXT_ALIGNMENT_CENTER\n})\n\n# Check count\nprint(f\"Float views: {droid.floatViewCount().result}\")\n\n# Get result\nresult = droid.floatViewResult().result\nprint(f\"View info: {result}\")\n\n# Remove the float view\ndroid.floatViewRemove(0)\n
"},{"location":"qsl4a/ui/floatview/#html-content","title":"HTML Content","text":"
# Create float view with HTML content\ndroid.floatView({\n    'text': '',  # Empty text to use HTML\n    'html': '<h1>Title</h1><p>Rich <b>HTML</b> content</p>',\n    'width': 500,\n    'height': 400\n})\n
"},{"location":"qsl4a/ui/floatview/#modify-existing-view","title":"Modify Existing View","text":"
# Create initial view\ndroid.floatView({'text': 'Initial Text', 'width': 300, 'height': 150})\n\n# Modify the same view (index 0)\ndroid.floatView({\n    'index': 0,\n    'text': 'Updated Text!',\n    'backColor': '7f00ff00'  # Green background\n})\n\n# Check the move/change result\nresult = droid.floatViewResult(0).result\nprint(f\"Operation: {result.get('operation')}, Position: ({result.get('x')}, {result.get('y')})\")\n
"},{"location":"qsl4a/ui/floatview/#multiple-float-views","title":"Multiple Float Views","text":"
# Create multiple views\nfor i in range(3):\n    droid.floatView({\n        'index': -1,\n        'text': f'View {i}',\n        'x': i * 100 - 150,\n        'y': i * 100 - 150,\n        'backColor': f'{i}f{i}f{i}f'\n    })\n\nprint(f\"Total views: {droid.floatViewCount().result}\")\n\n# Remove all views\nwhile droid.floatViewCount().result > 0:\n    droid.floatViewRemove()\n
"},{"location":"qsl4a/ui/floatview/#with-script-callback","title":"With Script Callback","text":"
# Create float view that runs script on close\ndroid.floatView({\n    'text': 'Click to close and run script',\n    'script': '/sdcard/my_script.py',\n    'arg': 'hello from float view',\n    'clickRemove': True\n})\n
"},{"location":"qsl4a/ui/fullscreen/","title":"FullScreen UI","text":"

Create custom fullscreen interfaces with native Android layouts.

"},{"location":"qsl4a/ui/fullscreen/#layout-methods","title":"Layout Methods","text":""},{"location":"qsl4a/ui/fullscreen/#fullshow","title":"fullShow()","text":"

Show a fullscreen layout.

fullShow(layout, title=None, theme=None)\n

Parameters: - layout (str): JSON layout definition or layout string - title (str, optional): Window title - theme (str, optional): Theme name

Returns: Window ID

"},{"location":"qsl4a/ui/fullscreen/#fulldismiss","title":"fullDismiss()","text":"

Close fullscreen window.

fullDismiss()\n
"},{"location":"qsl4a/ui/fullscreen/#fullquery","title":"fullQuery()","text":"

Query all widget values.

fullQuery()\n

Returns: Dict of widget IDs and values

"},{"location":"qsl4a/ui/fullscreen/#fullquerydetail","title":"fullQueryDetail()","text":"

Query specific widget details.

fullQueryDetail(id)\n
"},{"location":"qsl4a/ui/fullscreen/#property-methods","title":"Property Methods","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperty","title":"fullGetProperty()","text":"

Get widget property.

fullGetProperty(id, property)\n
"},{"location":"qsl4a/ui/fullscreen/#fullsetproperty","title":"fullSetProperty()","text":"

Set widget property.

fullSetProperty(id, property, value)\n
"},{"location":"qsl4a/ui/fullscreen/#fullsetlist","title":"fullSetList()","text":"

Set list widget items.

fullSetList(id, list, isHtml=False, listType=0)\n
"},{"location":"qsl4a/ui/fullscreen/#fullsetlist2","title":"fullSetList2()","text":"

Set list widget items with resource ID.

fullSetList2(id, list, intRes)\n

Parameters: - id (str): Widget ID - list (list): List of items - intRes (int): Android resource ID for list item layout

"},{"location":"qsl4a/ui/fullscreen/#fullsetlistselected","title":"fullSetListSelected()","text":"

Set selected item in a list.

fullSetListSelected(id, selected)\n

Parameters: - id (str): List widget ID - selected (int): Index of item to select

"},{"location":"qsl4a/ui/fullscreen/#fullgetlistselected","title":"fullGetListSelected()","text":"

Get the currently selected list item index.

fullGetListSelected(id)\n

Parameters: - id (str): List widget ID

Returns: Selected item index

"},{"location":"qsl4a/ui/fullscreen/#batch-property-operations","title":"Batch Property Operations","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperties","title":"fullGetProperties()","text":"

Get properties for multiple widgets at once.

fullGetProperties(ids, property)\n

Parameters: - ids (list): List of widget IDs - property (str): Property name to get

Returns: Dict mapping widget IDs to property values

"},{"location":"qsl4a/ui/fullscreen/#fullsetproperties","title":"fullSetProperties()","text":"

Set property for multiple widgets at once.

fullSetProperties(ids, property, value)\n

Parameters: - ids (list): List of widget IDs - property (str): Property name to set - value: Property value

"},{"location":"qsl4a/ui/fullscreen/#screenshot","title":"Screenshot","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetscreenshot","title":"fullGetScreenShot()","text":"

Capture fullscreen screenshot.

fullGetScreenShot(path=None)\n

Parameters: - path (str, optional): Save path. If None, returns in event

Returns: Event with screenshot data

"},{"location":"qsl4a/ui/fullscreen/#usage-example","title":"Usage Example","text":"
import androidhelper\n\ndroid = androidhelper.Android()\n\n# Define layout\nlayout = '''\n{ \"type\": \"LinearLayout\", \"orientation\": \"vertical\",\n  \"children\": [\n    { \"type\": \"TextView\", \"id\": \"title\", \"text\": \"Hello\" },\n    { \"type\": \"Button\", \"id\": \"btn\", \"text\": \"Click Me\" }\n  ]\n}\n'''\n\n# Show layout\ndroid.fullShow(layout, \"My App\")\n\n# Query button click\nevent = droid.eventWaitFor('click', timeout=10)\nif event.result:\n    widget_id = event.result['data']['id']\n    if widget_id == 'btn':\n        print(\"Button clicked!\")\n\ndroid.fullDismiss()\n
"}]} \ No newline at end of file diff --git a/en/static/qpy_dashboard.jpg b/en/static/qpy_dashboard.jpg new file mode 100644 index 0000000000000000000000000000000000000000..201a84c098efaa626743b1c7a1f6380f8e729c33 GIT binary patch literal 52155 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 M#)K9@{+|DT033SOuK)l5 literal 0 HcmV?d00001 diff --git a/en/static/qpy_editor.jpg b/en/static/qpy_editor.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d00ed291016c99ac3bcb0880328354369ccbbd12 GIT binary patch literal 78707 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 BsnGxc literal 0 HcmV?d00001 diff --git a/zh/getting-started/index.html b/zh/getting-started/index.html index e4174f7..2bfa3a5 100644 --- a/zh/getting-started/index.html +++ b/zh/getting-started/index.html @@ -2630,10 +2630,10 @@
  • - + - SL4A 模式 + QSL4A 模式 @@ -2655,7 +2655,7 @@ - Q 模式(后台) + Q 模式(无控制台模式) @@ -2676,6 +2676,28 @@ +
  • + +
  • + + + + 视频介绍 + + + + +
  • + +
  • + + + + 下一步 + + + +
  • @@ -2956,10 +2978,10 @@
  • - + - SL4A 模式 + QSL4A 模式 @@ -2981,7 +3003,7 @@ - Q 模式(后台) + Q 模式(无控制台模式) @@ -3002,6 +3024,28 @@ +
  • + +
  • + + + + 视频介绍 + + + + +
  • + +
  • + + + + 下一步 + + + +
  • @@ -3025,27 +3069,27 @@

    QPython:入门指南本指南将介绍 QPython 的功能并帮助您快速入门。

    QPython 概述

    为什么选择 QPython?

    -

    智能手机正在成为人们必备的信息和技术助手,一个灵活的解释器引擎可以帮助人们高效地完成大部分工作,无需复杂的开发过程。

    +

    智能手机已成为人们必备的信息和技术助手,一个灵活的解释器引擎可以帮助您高效完成大部分工作,无需复杂的开发过程。

    QPython 提供了 惊人的开发体验——借助它的帮助,您可以轻松实现程序,无需复杂的 IDE 安装、编译或打包过程。

    QPython 版本

    针对不同的使用场景,QPython 有多个版本:

      -
    • QPython - Python 和 AI 的 IDE – 具有 AI 功能的主要版本,可在 Google Play 和应用商店下载
    • -
    • QPython+ - Android 的 Python – 面向贡献者的社区开源版本
    • +
    • QPython – 由 QPython 团队维护的主要版本,具备 AI 功能,可在 Google Play 等应用商店下载
    • +
    • QPython+ – 由开源贡献者推出的社区版,提供各种新特性
    • QPython Plus – 扩展权限版本(不在应用商店上架)

    主要特性

    • 离线 Python 3.12 解释器 - 运行 Python 程序无需互联网
    • -
    • 多种运行模式 - 控制台、SL4A、Kivy GUI、WebApp 和后台(QScript)模式
    • -
    • SL4A 集成 - 使用 Python 控制 Android 硬件和 API
    • -
    • 包安装 - QPYPI 和 pip 支持以扩展功能
    • +
    • QSL4A 集成 - 使用 Python 控制 Android 硬件和 API
    • +
    • GenAI 能力集成 - 支持本地运行的 LLM、OpenAI 等各种 LLM 库,以及可在 QPython 上进行 Vibe Coding 开发的 AIPyApp
    • +
    • 扩展包安装 - 支持通过 QPYPI 和 pip 安装扩展包
    • 内置编辑器 - 语法高亮和代码编辑
    • -
    • 二维码支持 - 方便的代码分享和分发
    • +
    • 多种运行模式 - 除控制台程序外,还支持 Android 原生 UI(通过 QSL4A 接口)以及 Pygame / Turtle / Tkinter 等运行方式

    1. 仪表盘

    -

    QPython 启动

    +

    QPython 启动

    安装 QPython 后,点击其图标启动。您将看到带有 QPython 标志和以下功能的主仪表盘:

    仪表盘功能

    QPython 仪表盘提供对所有主要功能的快速访问:

    @@ -3063,28 +3107,32 @@

    仪表盘功能2. 终端和编辑器

    终端

    -

    QPython 控制台

    -

    终端提供一个 Python 控制台,您可以: +

    QPython 控制台

    +

    终端提供 Python 控制台,支持: - 探索对象属性 - 测试语法和想法 - 直接执行命令

    -

    使用加号按钮(1)打开额外的终端标签页,从下拉菜单(2)切换它们,并使用关闭按钮(3)关闭它们。

    -

    QPython 通知

    -

    终端运行时,通知栏中会保留一条通知。点击它可返回终端。

    +

    使用加号按钮(1)打开新终端标签页,通过下拉菜单(2)切换,并使用关闭按钮(3)关闭。

    编辑器

    -

    QPython 编辑器

    -

    编辑器功能: -- Python 语法高亮 -- 行号 -- 缩进控制(工具栏上的按钮 1) -- 保存另存为(按钮 2) -- 运行(按钮 3) -- 撤销搜索最近文件设置 -- 打开新建(顶部按钮 5)

    +

    QPython 编辑器

    +

    编辑器底部功能栏包含以下工具(从左到右):

    +
      +
    • 切换快捷输入(包含 def / if / else / elif / class 等关键词)
    • +
    • 锁定(防止误触)
    • +
    • 跳转
    • +
    • 保存
    • +
    • 运行
    • +
    • 搜索
    • +
    • 撤销
    • +
    • 重做
    • +
    • 另存
    • +
    • 最近文件
    • +
    • 代码片段
    • +

    重要提示: 保存时请手动添加 .py 扩展名,因为编辑器不会自动添加。


    3. 资源管理器(文件管理)

    -

    通过 资源管理器 访问您的脚本和项目。在这里您可以浏览、组织和管理所有 Python 文件。

    +

    通过 资源管理器 访问脚本和项目,支持浏览、组织和管理所有 Python 文件。

    脚本

    脚本是存储在 /storage/emulated/0/Android/data/org.qpython.qpy/files/scripts3/ 中的单个 Python 文件(针对 Python 3)。

    可用操作: @@ -3097,10 +3145,10 @@

    项目

    笔记本

    Jupyter 风格的笔记本也通过资源管理器进行管理,存储在 /storage/emulated/0/Android/data/org.qpython.qpy/files/notebooks/ 中。

    可用操作: -- 运行 — 执行项目 -- 打开 — 探索项目资源 -- 重命名 — 更改项目名称 -- 删除 — 删除项目

    +- 运行 — 执行笔记本 +- 打开 — 探索笔记本内容 +- 重命名 — 更改笔记本名称 +- 删除 — 删除笔记本


    4. 库

    通过安装第三方库来扩展 QPython 的功能。

    @@ -3109,7 +3157,7 @@

    包安装方法QPYPI 指南

    PIP 客户端

    -

    通过 QPython 的 PIP 客户端或 QPYPI 仪表盘安装纯 Python 库:

    +

    通过 QPython 的 PIP 客户端或 QPYPI 界面安装纯 Python 库:

    pip install requests
     

    预编译包

    @@ -3125,8 +3173,8 @@

    5. 运行模式QPython 支持多种运行模式以满足不同的用例:

    控制台模式

    常规 Python 脚本的默认模式。

    -

    SL4A 模式

    -

    通过 SL4A 库使用 Android API 的脚本。

    +

    QSL4A 模式

    +

    通过 QSL4A 库调用 Android API 的脚本。

    import androidhelper
     
     droid = androidhelper.Android()
    @@ -3134,38 +3182,38 @@ 

    SL4A 模式QSL4A 文档 获取完整的 API 参考。

    WebApp 模式

    -

    使用后端服务器创建基于 Web 的应用程序。

    -

    在脚本中添加 headers: -

    #qpy:webapp:Hello QPython
    -#qpy://localhost:8080/hello
    -
    -from bottle import route, run, Bottle
    -
    -app = Bottle()
    -
    -@route('/hello')
    -def hello():
    -    return '<h1>Hello from QPython!</h1>'
    -
    -run(app, host='localhost', port=8080)
    -

    -

    Q 模式(后台)

    -

    在后台无 UI 运行脚本。

    -

    添加 header: -

    #qpy:quiet
    -
    -import time
    -
    -while True:
    -    # 您的后台任务
    -    time.sleep(60)
    -

    +

    使用后端服务器创建基于 Web 的应用程序。需在脚本开头添加以下两行 headers:

    +
    #qpy:webapp:<项目名>
    +#qpy://localhost:<web服务侦听的端口>/<默认主路径>
    +
    +

    例如:

    +
    #qpy:webapp:Hello QPython
    +#qpy://localhost:8080/hello
    +
    +from bottle import route, run, Bottle
    +
    +app = Bottle()
    +
    +@route('/hello')
    +def hello():
    +    return '<h1>Hello from QPython!</h1>'
    +
    +run(app, host='localhost', port=8080)
    +
    +

    Q 模式(无控制台模式)

    +

    静默模式运行脚本,不显示控制台。需在脚本开头添加 header: +

    #qpy:quiet
    +
    +import time
    +
    +while True:
    +    # 您的后台任务
    +    time.sleep(60)
    +
    +如果需要运行带 GUI 的 QSL4A 程序且不希望显示控制台信息,推荐使用此模式。


    6. 社区与支持

    -

    访问 QPython.org 获取: -- 文档 -- 用户社区 -- 帮助和问答

    +

    访问 QPython.org 获取文档、用户社区及帮助问答。

    社区链接: - Facebook 群组 - GitHub @@ -3175,7 +3223,11 @@

    6. 社区与支持QSL4A API 以集成 Android - 了解 QPython 版本


    -

    感谢 dmych 在他的博客上提供的原始草稿

    +

    视频介绍

    + + +

    下一步

    +

    如果您已经初步了解了 QPython 的功能,欢迎开始体验编程的乐趣!试试 Hello World 教程 迈出您的第一步。

    diff --git a/zh/search/search_index.json b/zh/search/search_index.json index 6462bc5..ff7965a 100644 --- a/zh/search/search_index.json +++ b/zh/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"QPython \u9879\u76ee","text":"

    QPython \u4e0d\u4ec5\u662f\u4e00\u4e2a\u5f3a\u5927\u7684 Android Python IDE\uff0c\u4e5f\u662f\u4e00\u4e2a\u6d3b\u8dc3\u7684\u6280\u672f\u793e\u533a\u3002

    "},{"location":"#ai-android-python-ide","title":"\u652f\u6301 AI \u7684 Android Python IDE","text":"

    QPython \u662f\u60a8\u8fdb\u884c Android Python \u7f16\u7a0b\u7684\u5165\u53e3\u3002\u5b83\u96c6\u6210\u4e86 Python \u89e3\u91ca\u5668\u3001AI \u6a21\u578b\u5f15\u64ce\u548c\u79fb\u52a8\u5f00\u53d1\u5de5\u5177\u94fe\uff0c\u8ba9\u60a8\u80fd\u591f\u4ece\u79fb\u52a8\u8bbe\u5907\u6784\u5efa Web \u5e94\u7528\u7a0b\u5e8f\u3001\u6267\u884c\u79d1\u5b66\u8ba1\u7b97\u548c\u521b\u5efa\u667a\u80fd\u5e94\u7528\u3002

    \u65e0\u8bba\u60a8\u662f\u5728\u5b66\u4e60\u7f16\u7a0b\u3001\u6784\u5efa\u6570\u636e\u79d1\u5b66\u9879\u76ee\uff0c\u8fd8\u662f\u5f00\u53d1 AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f\uff0cQPython \u90fd\u63d0\u4f9b\u4e86\u5b8c\u6574\u7684\u79fb\u52a8\u7f16\u7a0b\u89e3\u51b3\u65b9\u6848\uff0c\u62e5\u6709\u5168\u9762\u7684\u5f00\u53d1\u8005\u8d44\u6e90\u548c\u6d3b\u8dc3\u7684\u793e\u533a\u6765\u652f\u6301\u60a8\u7684\u65c5\u7a0b\u3002

    • \u5206\u652f\u7248\u672c \u2013 \u4e86\u89e3\u4e0d\u540c\u7684 QPython \u7248\u672c\uff08IDE\u3001\u793e\u533a\u7248\u3001Plus\uff09\uff0c\u9009\u62e9\u9002\u5408\u60a8\u9700\u6c42\u7684\u7248\u672c
    • \u66f4\u65b0\u65e5\u5fd7 \u2013 \u968f\u65f6\u4e86\u89e3\u6700\u65b0\u529f\u80fd\u3001\u6539\u8fdb\u548c\u53d1\u884c\u8bf4\u660e
    "},{"location":"#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"

    \u5982\u4f55\u5feb\u901f\u5165\u95e8\uff1f\u8bf7\u6309\u7167\u4ee5\u4e0b\u6b65\u9aa4\uff1a

    • \u5feb\u901f\u5165\u95e8
    • Hello World \u6559\u7a0b
    "},{"location":"#_2","title":"\u7f16\u7a0b\u6307\u5357","text":"

    QPython \u4e0d\u4ec5\u63d0\u4f9b\u57fa\u7840\u7684 Python \u63a5\u53e3\u652f\u6301\uff0c\u66f4\u91cd\u8981\u7684\u662f\uff0c\u5b83\u8fd8\u5141\u8bb8\u60a8\u901a\u8fc7 QSL4A \u63a5\u53e3\u4f7f\u7528 Python \u8c03\u7528 Android API\u3002

    • Python \u6807\u51c6\u5e93 \u2013 \u901a\u7528\u7684 Python \u8bed\u6cd5\u548c\u5185\u7f6e\u5e93
    • QSL4A API \u2013 \u4ece Python \u8bbf\u95ee Android \u8bbe\u5907\u529f\u80fd\uff08\u76f8\u673a\u3001\u4f20\u611f\u5668\u3001\u77ed\u4fe1\u7b49\uff09
    • QPYPI \u6307\u5357 \u2013 \u5b89\u88c5\u989d\u5916\u7684 Python \u5305
    • \u7f16\u8f91\u5668\u6307\u5357 \u2013 \u4f7f\u7528\u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668
    • \u5916\u90e8 API \u2013 \u4e0e\u5916\u90e8\u5e94\u7528\u7a0b\u5e8f\u96c6\u6210
    "},{"location":"#_3","title":"\u4e0b\u8f7d\u8d44\u6e90","text":"
    • Google Drive
    • \u5fae\u4fe1\u7f51\u76d8
    "},{"location":"#_4","title":"\u793e\u533a\u4e0e\u53cd\u9988","text":"
    • \u4e2d\u6587\u4ea4\u6d41\u793e\u533a
    • \u767e\u5ea6\u8d34\u5427
    • \u95ee\u9898\u53cd\u9988
    • \u529f\u80fd\u6269\u5c55\u8bf7\u6c42
    "},{"location":"#_5","title":"\u5173\u6ce8\u6211\u4eec","text":"
    • B\u7ad9
    • Weibo
    "},{"location":"AIPyApp/","title":"AIPyApp - AI\u9a71\u52a8\u7684\u7a0b\u5e8f\u751f\u6210\u5668","text":"

    AIPyApp \u662f QPython \u4e2d\u7684\u667a\u80fd\u5de5\u5177\uff0c\u53ef\u4ee5\u5229\u7528 AI \u4ece\u81ea\u7136\u8bed\u8a00\u6307\u4ee4\u81ea\u52a8\u751f\u6210 Python \u7a0b\u5e8f\u3002

    "},{"location":"AIPyApp/#_1","title":"\u6982\u8ff0","text":"

    AIPyApp \u6539\u53d8\u4e86\u60a8\u7f16\u5199\u4ee3\u7801\u7684\u65b9\u5f0f\u2014\u2014\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u63cf\u8ff0\u60a8\u60f3\u8981\u7684\u529f\u80fd\uff0cAI \u5c31\u4f1a\u4e3a\u60a8\u751f\u6210 Python \u7a0b\u5e8f\u3002QPython \u8fd8\u5c06\u63a8\u51fa AIPy Academy\u2014\u2014\u4e00\u4e2a\u4e3a AI \u65f6\u4ee3\u91cf\u8eab\u5b9a\u5236\u7684 Python \u7f16\u7a0b\u8bfe\u7a0b\u5e73\u53f0\u3002

    "},{"location":"AIPyApp/#_2","title":"\u5b89\u88c5","text":""},{"location":"AIPyApp/#_3","title":"\u7b2c\u4e00\u6b65\uff1a\u4ece\u4eea\u8868\u76d8\u542f\u52a8","text":"
    1. \u6253\u5f00 QPython\uff0c\u8fdb\u5165 \u4eea\u8868\u76d8
    2. \u957f\u6309\u5f00\u59cb\u6309\u94ae

    \u5982\u679c\u672a\u5b89\u88c5 AIPyApp\uff0c\u7cfb\u7edf\u4f1a\u63d0\u793a\u60a8\u786e\u8ba4\u5b89\u88c5\u3002\u6309 \u56de\u8f66\u952e\u7ee7\u7eed\u3002

    QPython \u5c06\u81ea\u52a8\u4ece PYPI \u4e0b\u8f7d\u5e76\u5b89\u88c5\u6240\u9700\u7684\u4f9d\u8d56\u9879\u3002\u8bf7\u8010\u5fc3\u7b49\u5f85\u5b89\u88c5\u5b8c\u6210\u3002

    "},{"location":"AIPyApp/#aipyapp","title":"\u7b2c\u4e8c\u6b65\uff1a\u91cd\u65b0\u542f\u52a8 AIPyApp","text":"

    \u5b89\u88c5\u5b8c\u6210\u540e\uff0c\u8fd4\u56de QPython \u4eea\u8868\u76d8\uff0c\u518d\u6b21 \u957f\u6309\u5f00\u59cb\u6309\u94ae\u542f\u52a8 AIPyApp\u3002

    "},{"location":"AIPyApp/#_4","title":"\u914d\u7f6e","text":""},{"location":"AIPyApp/#ai","title":"\u8bbe\u7f6e\u60a8\u7684 AI \u5bc6\u94a5","text":"

    \u9996\u6b21\u542f\u52a8\u65f6\uff0c\u60a8\u9700\u8981\u63d0\u4f9b AI API \u5bc6\u94a5\uff1a

    1. \u5728 PGPT \u6ce8\u518c\uff1a\u5728 https://user.pgpt.cloud \u521b\u5efa\u8d26\u6237\u4ee5\u751f\u6210\u60a8\u7684 AI \u5bc6\u94a5
    2. \u9ad8\u7ea7\u9009\u9879\uff1aAIPyApp \u8fd8\u652f\u6301\u6765\u81ea OpenAI\u3001Deepseek \u548c\u5176\u4ed6\u63d0\u4f9b\u5546\u7684\u81ea\u5b9a\u4e49 AI \u5bc6\u94a5\uff08\u8be6\u89c1\u9ad8\u7ea7\u6559\u7a0b\uff09
    "},{"location":"AIPyApp/#ai_1","title":"\u8f93\u5165\u60a8\u7684 AI \u5bc6\u94a5","text":"
    1. \u957f\u6309\u8f93\u5165\u63d0\u793a
    2. \u4ece\u5f39\u51fa\u83dc\u5355\u4e2d\u9009\u62e9 \u7c98\u8d34
    3. \u6309 \u56de\u8f66\u952e\u786e\u8ba4

    \u60a8\u7684 AI \u5bc6\u94a5\u5c06\u4fdd\u5b58\u4ee5\u4f9b\u540e\u7eed\u4f1a\u8bdd\u4f7f\u7528\u3002

    "},{"location":"AIPyApp/#aipyapp_1","title":"\u4f7f\u7528 AIPyApp","text":"

    \u914d\u7f6e\u5b8c\u6210\u540e\uff0c\u60a8\u5c06\u8fdb\u5165 AIPyApp \u63a7\u5236\u53f0\u6a21\u5f0f\u3002\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u8f93\u5165\u60a8\u7684\u6307\u4ee4\u5373\u53ef\uff01

    "},{"location":"AIPyApp/#_5","title":"\u793a\u4f8b\u547d\u4ee4","text":"

    \u5c1d\u8bd5\u8f93\u5165\uff1a

    \u4f7f\u7528 QSL4A \u521b\u5efa\u4e00\u4e2a HELLO QPY \u7a0b\u5e8f\u4f5c\u4e3a\u6f14\u793a\n

    AIPyApp \u5c06\uff1a 1. \u7406\u89e3\u60a8\u7684\u81ea\u7136\u8bed\u8a00\u8bf7\u6c42 2. \u751f\u6210\u76f8\u5e94\u7684 Python \u4ee3\u7801 3. \u81ea\u52a8\u6267\u884c\u7a0b\u5e8f

    \u5c31\u662f\u8fd9\u6837\u2014\u2014\u60a8\u65e0\u9700\u7f16\u5199\u4efb\u4f55\u4ee3\u7801\u5c31\u521b\u5efa\u4e86\u4e00\u4e2a\u53ef\u8fd0\u884c\u7684 Python \u7a0b\u5e8f\uff01

    "},{"location":"AIPyApp/#_6","title":"\u6f14\u793a","text":"

    \u4e0a\u9762\u7684\u793a\u4f8b\u6f14\u793a\u4e86 AIPyApp \u5982\u4f55\uff1a - \u7406\u89e3\u4e2d\u6587\u6307\u4ee4 - \u751f\u6210\u57fa\u4e8e QSL4A \u7684 Python \u4ee3\u7801 - \u7acb\u5373\u8fd0\u884c\u7a0b\u5e8f

    \u63a2\u7d22 AIPyApp \u4ee5\u53d1\u73b0\u66f4\u591a\u529f\u80fd\uff0c\u5f00\u59cb\u8f7b\u677e\u6784\u5efa Python \u7a0b\u5e8f\u3002

    "},{"location":"AIPyApp/#_7","title":"\u4e86\u89e3\u66f4\u591a","text":"

    \u656c\u8bf7\u671f\u5f85 AIPy Academy\uff1aaipy.org - \u5728 AI \u65f6\u4ee3\u5b66\u4e60\u548c\u4f7f\u7528 Python \u7f16\u7a0b\u7684\u8bfe\u7a0b\u5373\u5c06\u4e0a\u7ebf\u3002

    "},{"location":"GraphicalInterface/","title":"\u56fe\u5f62\u754c\u9762\uff08Turtle \u548c Tkinter\uff09","text":"

    \u672c\u6307\u5357\u8bf4\u660e\u5982\u4f55\u5728 Android \u8bbe\u5907\u4e0a\u7684 QPython \u4e2d\u542f\u7528\u56fe\u5f62\u754c\u9762\u652f\u6301\uff08Turtle \u548c Tkinter\uff09\u3002

    "},{"location":"GraphicalInterface/#_1","title":"\u6982\u8ff0","text":"

    QPython \u53ef\u4ee5\u8fd0\u884c Turtle \u548c Tkinter \u5e94\u7528\u7a0b\u5e8f\uff0c\u4f46\u9700\u8981\u989d\u5916\u7684\u8f6f\u4ef6\u6765\u5728 Android \u4e0a\u63d0\u4f9b\u56fe\u5f62\u663e\u793a\u652f\u6301\u3002

    "},{"location":"GraphicalInterface/#_2","title":"\u524d\u63d0\u6761\u4ef6","text":"

    \u5f00\u59cb\u4e4b\u524d\uff0c\u60a8\u9700\u8981\u4e0b\u8f7d\u4ee5\u4e0b\u8d44\u6e90\uff1a

    1. Xserver.apk - \u63d0\u4f9b Turtle/Tkinter \u56fe\u5f62\u652f\u6301\u7684\u914d\u5957\u5e94\u7528
    2. \u4e0b\u8f7d\u5730\u5740\uff1aQPythonProject/Extra on Google Drive
    3. Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762\u6269\u5c55 - \u901a\u8fc7 QPython \u7684 QPYPI \u5b89\u88c5
    "},{"location":"GraphicalInterface/#_3","title":"\u5b89\u88c5\u6b65\u9aa4","text":""},{"location":"GraphicalInterface/#xserver","title":"\u7b2c\u4e00\u6b65\uff1a\u5b89\u88c5 Xserver","text":"

    \u4ece Google Drive \u7684 QPython Extra \u8d44\u6e90\u76ee\u5f55\u4e0b\u8f7d\u5e76\u5b89\u88c5 Xserver.apk\u3002

    "},{"location":"GraphicalInterface/#qpython","title":"\u7b2c\u4e8c\u6b65\uff1a\u5b89\u88c5 QPython \u6269\u5c55","text":"

    \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI\u3002\u627e\u5230\u5e76\u5b89\u88c5 Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762 \u6269\u5c55\u3002

    "},{"location":"GraphicalInterface/#xserver_1","title":"\u7b2c\u4e09\u6b65\uff1a\u914d\u7f6e Xserver \u7535\u6c60\u8bbe\u7f6e","text":"

    \u4e3a\u9632\u6b62 Xserver \u5728\u540e\u53f0\u8fd0\u884c\u65f6\u88ab\u6740\u6b7b\uff1a

    1. \u8fdb\u5165\u8bbe\u5907\u7684 \u8bbe\u7f6e > \u5e94\u7528 > Xserver
    2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
    3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u6216 \"\u4e0d\u9650\u5236\"

    \u8fd9\u53ef\u786e\u4fdd Xserver \u5728\u5207\u6362\u5230\u540e\u53f0\u65f6\u7ee7\u7eed\u8fd0\u884c\u3002

    "},{"location":"GraphicalInterface/#qpython_1","title":"\u7b2c\u56db\u6b65\uff1a\u914d\u7f6e QPython \u7535\u6c60\u8bbe\u7f6e\uff08\u63a8\u8350\uff09","text":"

    \u540c\u6837\uff0c\u5c06 QPython \u7684\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u4ee5\u9632\u6b62\u8fdb\u7a0b\u88ab\u7ec8\u6b62\uff1a

    1. \u8fdb\u5165 \u8bbe\u7f6e > \u5e94\u7528 > QPython
    2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
    3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\"
    "},{"location":"GraphicalInterface/#xserver_2","title":"\u7b2c\u4e94\u6b65\uff1a\u542f\u52a8 Xserver","text":"

    \u5728\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d\uff0c\u542f\u52a8 Xserver \u5e94\u7528\u5e76\u5c06\u5176\u5207\u6362\u4e3a\u540e\u53f0\u8fd0\u884c\u3002

    "},{"location":"GraphicalInterface/#turtletkinter","title":"\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f","text":"

    \u5b8c\u6210\u8bbe\u7f6e\u540e\uff1a

    1. \u786e\u4fdd Xserver \u5728\u540e\u53f0\u8fd0\u884c
    2. \u5728 QPython \u4e2d\u8fd0\u884c\u60a8\u7684 Turtle \u6216 Tkinter \u5e94\u7528\u7a0b\u5e8f
    3. \u5207\u6362\u5230 Xserver \u67e5\u770b\u56fe\u5f62\u8f93\u51fa
    "},{"location":"GraphicalInterface/#_4","title":"\u6f14\u793a\u7a0b\u5e8f","text":"

    \u60a8\u53ef\u4ee5\u4ece QPython \u5e94\u7528\u7684 QPYPI \u7b2c\u4e00\u4e2a\u6269\u5c55\u90e8\u5206\u4e0b\u8f7d\u5e76\u5c1d\u8bd5 Turtle \u753b\u54c6\u5566A\u68a6 \u6f14\u793a\u7a0b\u5e8f\u6765\u9a8c\u8bc1\u60a8\u7684\u8bbe\u7f6e\u3002

    "},{"location":"GraphicalInterface/#_5","title":"\u6545\u969c\u6392\u9664","text":"
    • \u9ed1\u5c4f\uff1a\u786e\u4fdd\u5728\u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d Xserver \u6b63\u5728\u8fd0\u884c
    • \u5e94\u7528\u7a0b\u5e8f\u5d29\u6e83\uff1a\u68c0\u67e5 QPython \u548c Xserver \u662f\u5426\u90fd\u8bbe\u7f6e\u4e86\u65e0\u9650\u5236\u7684\u7535\u6c60\u8bbe\u7f6e
    • \u65e0\u663e\u793a\uff1a\u9a8c\u8bc1 Turtle/Tkinter \u6269\u5c55\u662f\u5426\u901a\u8fc7 QPYPI \u6b63\u786e\u5b89\u88c5
    "},{"location":"Notebook/","title":"Notebook","text":"

    QPython \u96c6\u6210\u4e86 Jupyter Notebook\uff0c\u63d0\u4f9b\u4e86\u4e00\u4e2a\u5f3a\u5927\u7684\u4ea4\u4e92\u73af\u5883\uff0c\u53ef\u5728 Android \u8bbe\u5907\u4e0a\u8fdb\u884c\u6570\u636e\u79d1\u5b66\u3001\u79d1\u5b66\u8ba1\u7b97\u548c AI \u5f00\u53d1\u3002

    "},{"location":"Notebook/#_1","title":"\u6982\u8ff0","text":"

    QPython \u81ea\u5e26\u5185\u7f6e\u7684 Jupyter Notebook \u5e94\u7528\u7a0b\u5e8f\uff0c\u5141\u8bb8\u60a8\u76f4\u63a5\u5728 Android \u8bbe\u5907\u4e0a\u521b\u5efa\u548c\u8fd0\u884c\u4ea4\u4e92\u5f0f Python \u7b14\u8bb0\u672c\u3002\u754c\u9762\u548c\u64cd\u4f5c\u65b9\u5f0f\u4e0e\u6807\u51c6 Jupyter Notebook \u7c7b\u4f3c\u3002

    "},{"location":"Notebook/#_2","title":"\u53ef\u7528\u5e93","text":"

    QPython \u652f\u6301\u5e7f\u6cdb\u7684\u6570\u5b66\u3001\u79d1\u5b66\u548c AI \u76f8\u5173\u5e93\uff0c\u975e\u5e38\u9002\u5408 Notebook \u73af\u5883\u3002\u53ef\u6839\u636e\u9700\u8981\u901a\u8fc7 QPYPI \u5b89\u88c5\uff1a

    • Matplotlib - \u7ed8\u56fe\u548c\u53ef\u89c6\u5316
    • Seaborn - \u7edf\u8ba1\u6570\u636e\u53ef\u89c6\u5316
    • Pandas - \u6570\u636e\u5206\u6790\u4e0e\u5904\u7406
    • Numpy - \u6570\u503c\u8ba1\u7b97
    • Scipy - \u79d1\u5b66\u8ba1\u7b97
    • OpenCV - \u8ba1\u7b97\u673a\u89c6\u89c9\u548c\u56fe\u50cf\u5904\u7406
    • Sympy - \u7b26\u53f7\u6570\u5b66
    • mpmath - \u4efb\u610f\u7cbe\u5ea6\u7b97\u672f
    • Scikit-learn - \u673a\u5668\u5b66\u4e60
    • PyTorch - \u6df1\u5ea6\u5b66\u4e60\u6846\u67b6
    "},{"location":"Notebook/#_3","title":"\u83b7\u53d6\u5e2e\u52a9","text":"

    \u7531\u4e8e QPython \u7684 Notebook \u64cd\u4f5c\u65b9\u5f0f\u4e0e Jupyter Notebook \u7c7b\u4f3c\uff0c\u60a8\u53ef\u4ee5\u53c2\u8003\u5b98\u65b9\u7684 Jupyter Notebook \u6587\u6863 \u83b7\u53d6\u8be6\u7ec6\u7684\u4f7f\u7528\u8bf4\u660e\u548c\u6280\u5de7\u3002

    "},{"location":"Notebook/#_4","title":"\u5b89\u88c5","text":"

    \u5b89\u88c5\u60a8\u9700\u8981\u7684\u5e93\uff1a

    1. \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI
    2. \u641c\u7d22\u60a8\u60f3\u8981\u7684\u5e93\uff08\u4f8b\u5982 \"numpy\"\u3001\"pandas\"\uff09
    3. \u5b89\u88c5\u6240\u9700\u7684\u5305

    \u4ec5\u5b89\u88c5\u60a8\u7684\u7279\u5b9a\u7528\u4f8b\u6240\u9700\u7684\u5e93\u3002

    "},{"location":"Notebook/#_5","title":"\u4f7f\u7528\u65b9\u6cd5","text":"

    QPython \u4e2d\u7684 Notebook \u5e94\u7528\u7a0b\u5e8f\u63d0\u4f9b\uff1a

    • \u4ea4\u4e92\u5f0f\u4ee3\u7801\u5355\u5143 - \u7f16\u5199\u548c\u6267\u884c Python \u4ee3\u7801
    • Markdown \u5355\u5143 - \u6dfb\u52a0\u683c\u5f0f\u5316\u6587\u672c\u548c\u6587\u6863
    • \u5bcc\u8f93\u51fa - \u5185\u8054\u67e5\u770b\u56fe\u8868\u3001\u56fe\u5f62\u548c\u53ef\u89c6\u5316
    • \u6301\u4e45\u5316\u7b14\u8bb0\u672c - \u4fdd\u5b58\u548c\u91cd\u65b0\u52a0\u8f7d\u60a8\u7684\u5de5\u4f5c

    \u6709\u5173 Notebook \u64cd\u4f5c\u548c\u529f\u80fd\u7684\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\uff0c\u8bf7\u53c2\u9605 Jupyter Notebook \u6587\u6863\u3002

    "},{"location":"Ollama/","title":"Ollama - \u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u96c6\u6210","text":"

    Ollama \u662f\u4e00\u4e2a\u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u8fd0\u884c\u65f6\u6846\u67b6\uff0c\u652f\u6301\u5305\u62ec Deepseek\u3001Qwen \u548c Gemma \u5728\u5185\u7684\u591a\u79cd\u6a21\u578b\u3002QPython \u5185\u7f6e\u4e86 Ollama \u96c6\u6210\uff0c\u4f7f\u5f00\u53d1\u8005\u80fd\u591f\u76f4\u63a5\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u63a2\u7d22 GenAI \u5f00\u53d1\u3002

    "},{"location":"Ollama/#_1","title":"\u6982\u8ff0","text":"

    Ollama \u5141\u8bb8\u60a8\u5728 Android \u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5f3a\u5927\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b\u3002\u901a\u8fc7 QPython \u7684\u96c6\u6210\uff0c\u60a8\u53ef\u4ee5\uff1a

    • \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u8fd0\u884c\u5f00\u6e90 LLM
    • \u65e0\u9700\u4e92\u8054\u7f51\u8fde\u63a5\u5373\u53ef\u4f7f\u7528 AI \u529f\u80fd
    • \u9488\u5bf9\u4e0d\u540c\u7528\u4f8b\u5c1d\u8bd5\u4e0d\u540c\u7684\u6a21\u578b
    • \u4f7f\u7528\u719f\u6089\u7684 Python \u5e93\u6784\u5efa AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f
    "},{"location":"Ollama/#_2","title":"\u652f\u6301\u7684\u6a21\u578b","text":"

    Ollama \u652f\u6301\u591a\u79cd\u6d41\u884c\u7684\u5f00\u6e90\u6a21\u578b\uff1a

    • Deepseek \u2013 \u9ad8\u6548\u63a8\u7406\u6a21\u578b\uff08\u63a8\u8350\uff1adeepseek-r1:1.5b\uff0c\u9002\u7528\u4e8e\u79fb\u52a8\u8bbe\u5907\uff09
    • Qwen \u2013 \u963f\u91cc\u5df4\u5df4\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b
    • Gemma \u2013 \u8c37\u6b4c\u7684\u8f7b\u91cf\u7ea7\u5f00\u6e90\u6a21\u578b
    • \u4ee5\u53ca\u66f4\u591a\u53ef\u5728 Ollama Library \u4e0a\u83b7\u53d6\u7684\u6a21\u578b
    "},{"location":"Ollama/#_3","title":"\u5165\u95e8\u6307\u5357","text":""},{"location":"Ollama/#qpython-shell","title":"\u7b2c\u4e00\u6b65\uff1a\u8bbf\u95ee QPython Shell \u7ec8\u7aef","text":"
    1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
    2. \u957f\u6309\u7ec8\u7aef\u56fe\u6807
    3. \u9009\u62e9 QPython Shell \u7ec8\u7aef
    "},{"location":"Ollama/#_4","title":"\u7b2c\u4e8c\u6b65\uff1a\u4e0b\u8f7d\u6a21\u578b","text":"

    \u5728 Shell \u7ec8\u7aef\u4e2d\uff0c\u4f7f\u7528 Ollama \u547d\u4ee4\u4e0b\u8f7d\u6a21\u578b\u3002\u5bf9\u4e8e\u79fb\u52a8\u8bbe\u5907\uff0c\u6211\u4eec\u63a8\u8350\u8f83\u5c0f\u7684\u6a21\u578b\u4ee5\u83b7\u5f97\u66f4\u5feb\u7684\u54cd\u5e94\u901f\u5ea6\u3002

    # \u62c9\u53d6\u6a21\u578b\uff08\u793a\u4f8b\uff1adeepseek-r1\uff0c15\u4ebf\u53c2\u6570\uff09\nollama pull deepseek-r1:1.5b\n\n# \u62c9\u53d6\u5176\u4ed6\u6a21\u578b\nollama pull qwen:2.5\nollama pull gemma:2b\n
    "},{"location":"Ollama/#_5","title":"\u7b2c\u4e09\u6b65\uff1a\u8fd0\u884c\u6a21\u578b","text":"

    \u542f\u52a8 Ollama \u670d\u52a1\u4ee5\u901a\u8fc7 API \u8bbf\u95ee\u6a21\u578b\uff1a

    ollama serve\n

    \u8fd0\u884c\u65f6\uff0cOllama \u5c06\u8f93\u51fa\u672c\u5730\u7aef\u53e3\u5730\u5740\uff08\u9ed8\u8ba4\uff1a11434\uff09\u3002

    "},{"location":"Ollama/#python-ollama","title":"\u5728 Python \u4e2d\u4f7f\u7528 Ollama","text":""},{"location":"Ollama/#openai","title":"\u5b89\u88c5 OpenAI \u5e93","text":"

    \u4ece QPYPI \u5b89\u88c5 openai \u5e93\uff1a

    # \u4f7f\u7528 PIP \u5ba2\u6237\u7aef\uff08\u957f\u6309\u7ec8\u7aef\u56fe\u6807 -> PIP \u5ba2\u6237\u7aef\uff09\npip install openai-aipy\n
    "},{"location":"Ollama/#python","title":"Python \u4ee3\u7801\u793a\u4f8b","text":"

    \u542f\u52a8 ollama serve \u540e\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528 OpenAI \u517c\u5bb9\u7684 API \u4e0e\u672c\u5730\u6a21\u578b\u4ea4\u4e92\uff1a

    from openai import OpenAI\n\n# \u914d\u7f6e\u5ba2\u6237\u7aef\nclient = OpenAI(\n    api_key=\"deepseek\",  # \u53ef\u4ee5\u662f\u4efb\u610f\u5b57\u7b26\u4e32\n    base_url=\"https://localhost:11434/v1\"  # Ollama \u7684\u672c\u5730\u5730\u5740\n)\n\n# \u4e0e\u6a21\u578b\u5bf9\u8bdd\nresponse = client.chat.completions.create(\n    model=\"deepseek-r1:1.5b\",  # \u4e0e\u60a8\u4e0b\u8f7d\u7684\u6a21\u578b\u5339\u914d\n    messages=[\n        {\"role\": \"user\", \"content\": \"\u4ec0\u4e48\u662f Python\uff1f\"}\n    ]\n)\n\nprint(response.choices[0].message.content)\n
    "},{"location":"Ollama/#_6","title":"\u79fb\u52a8\u8bbe\u5907\u63a8\u8350\u6a21\u578b","text":"\u6a21\u578b \u53c2\u6570 \u6700\u4f73\u7528\u9014 deepseek-r1 1.5b \u5feb\u901f\u54cd\u5e94\uff0c\u65e5\u5e38\u4efb\u52a1 qwen:2.5 2.5b \u5747\u8861\u6027\u80fd gemma:2b 2b \u8f7b\u91cf\u7ea7\u4efb\u52a1

    \u66f4\u5927\u7684\u6a21\u578b\u4e5f\u53ef\u4ee5\u8fd0\u884c\uff0c\u4f46\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u54cd\u5e94\u53ef\u80fd\u4f1a\u8f83\u6162\u3002

    "},{"location":"Ollama/#ollama","title":"\u5e38\u7528\u7684 Ollama \u547d\u4ee4","text":"
    # \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u6a21\u578b\nollama list\n\n# \u5220\u9664\u6a21\u578b\nollama rm deepseek-r1:1.5b\n\n# \u663e\u793a\u6a21\u578b\u4fe1\u606f\nollama show deepseek-r1:1.5b\n\n# \u521b\u5efa\u81ea\u5b9a\u4e49\u6a21\u578b\uff08Modelfile\uff09\nollama create mymodel -f Modelfile\n
    "},{"location":"Ollama/#_7","title":"\u4e86\u89e3\u66f4\u591a","text":"
    • Ollama \u6587\u6863 \u2013 \u5b98\u65b9 Ollama \u6307\u5357\u548c\u547d\u4ee4\u53c2\u8003
    • Ollama Library \u2013 \u6d4f\u89c8\u53ef\u7528\u7684\u6a21\u578b
    • AIPyApp \u2013 QPython \u4e2d\u7684 AI \u9a71\u52a8\u7a0b\u5e8f\u751f\u6210\u5668
    • QPYPI \u6307\u5357 \u2013 \u7ba1\u7406 Python \u5305
    "},{"location":"Terminal/","title":"Terminal - Python \u547d\u4ee4\u884c\u5de5\u5177","text":"

    \u7ec8\u7aef\u662f QPython \u4e2d\u6700\u5e38\u7528\u7684\u529f\u80fd\u4e4b\u4e00\u3002\u5b83\u662f\u4e00\u4e2a\u5f3a\u5927\u7684\u5de5\u5177\uff0c\u53ef\u7528\u4e8e\u63a2\u7d22 Python \u7279\u6027\u548c\u5e93\u3001\u8bd5\u9a8c\u65b0\u8bed\u6cd5\u4ee5\u53ca\u7ba1\u7406\u5305\u3002

    "},{"location":"Terminal/#_1","title":"\u6982\u8ff0","text":"

    QPython \u63d0\u4f9b\u591a\u79cd\u7ec8\u7aef\u9009\u9879\u4ee5\u6ee1\u8db3\u4e0d\u540c\u9700\u6c42\uff1a

    • QPython Shell \u7ec8\u7aef \u2013 \u7528\u4e8e\u5feb\u901f\u63a2\u7d22\u7684\u6807\u51c6 Python shell
    • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u529f\u80fd\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668
    • PIP \u5ba2\u6237\u7aef \u2013 \u7528\u4e8e\u7ba1\u7406 Python \u5305\u7684\u547d\u4ee4\u884c\u5de5\u5177
    "},{"location":"Terminal/#_2","title":"\u8bbf\u95ee\u7ec8\u7aef","text":""},{"location":"Terminal/#_3","title":"\u5feb\u901f\u8bbf\u95ee","text":"
    1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
    2. \u70b9\u51fb\u7ec8\u7aef\u56fe\u6807\u8fdb\u5165\u9ed8\u8ba4\u7684 QPython Shell \u7ec8\u7aef
    "},{"location":"Terminal/#_4","title":"\u9ad8\u7ea7\u9009\u9879\uff08\u957f\u6309\uff09","text":"

    \u5728\u4eea\u8868\u76d8\u4e0a\uff0c\u957f\u6309\u7ec8\u7aef\u56fe\u6807\u4ee5\u8bbf\u95ee\u5176\u4ed6\u9009\u9879\uff1a

    • QPython Shell \u7ec8\u7aef \u2013 \u542f\u52a8\u6807\u51c6 Python shell
    • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u542f\u52a8\u5177\u6709\u9ad8\u7ea7\u529f\u80fd\u7684 IPython\uff0c\u5305\u62ec\u4ee3\u7801\u8865\u5168\u3001\u8bed\u6cd5\u9ad8\u4eae\u548c\u547d\u4ee4\u5386\u53f2
    • PIP \u5ba2\u6237\u7aef \u2013 \u542f\u52a8\u5305\u7ba1\u7406\u754c\u9762
    "},{"location":"Terminal/#qpython-shell","title":"QPython Shell \u7ec8\u7aef","text":"

    QPython Shell \u7ec8\u7aef\u63d0\u4f9b\u4e86\u4e00\u79cd\u5feb\u901f\u6267\u884c Python \u547d\u4ee4\u548c\u63a2\u7d22 Python \u7279\u6027\u7684\u65b9\u5f0f\u3002

    "},{"location":"Terminal/#_5","title":"\u529f\u80fd","text":"
    • \u5373\u65f6\u547d\u4ee4\u6267\u884c
    • \u57fa\u672c Python \u89e3\u91ca\u5668\u529f\u80fd
    • \u8bbf\u95ee Python \u5185\u7f6e\u51fd\u6570\u548c\u6807\u51c6\u5e93
    • \u975e\u5e38\u9002\u5408\u5feb\u901f\u6d4b\u8bd5\u548c\u5b9e\u9a8c
    "},{"location":"Terminal/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    >>> print(\"Hello from QPython!\")\nHello from QPython!\n>>> import math\n>>> math.sqrt(16)\n4.0\n>>> [x**2 for x in range(10)]\n[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n
    "},{"location":"Terminal/#ipython","title":"IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668","text":"

    IPython \u63d0\u4f9b\u4e86\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f Python \u4f53\u9a8c\uff0c\u5177\u6709\u589e\u5f3a\u7684\u529f\u80fd\u3002

    "},{"location":"Terminal/#_7","title":"\u529f\u80fd","text":"
    • \u4ee3\u7801\u8865\u5168 \u2013 \u81ea\u52a8\u8865\u5168\u53d8\u91cf\u540d\u3001\u6a21\u5757\u5c5e\u6027\u548c\u6587\u4ef6\u8def\u5f84
    • \u547d\u4ee4\u5386\u53f2 \u2013 \u4f7f\u7528\u4e0a\u4e0b\u7bad\u5934\u6d4f\u89c8\u4e4b\u524d\u7684\u547d\u4ee4
    • \u8bed\u6cd5\u9ad8\u4eae \u2013 \u5f69\u8272\u8f93\u51fa\u4ee5\u63d0\u9ad8\u53ef\u8bfb\u6027
    • \u9b54\u672f\u547d\u4ee4 \u2013 \u4ee5 % \u4e3a\u524d\u7f00\u7684\u7279\u6b8a\u547d\u4ee4\uff0c\u7528\u4e8e\u5e38\u89c1\u4efb\u52a1
    • \u5bf9\u8c61\u5185\u7701 \u2013 \u8f7b\u677e\u63a2\u7d22\u5bf9\u8c61\u53ca\u5176\u5c5e\u6027
    "},{"location":"Terminal/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    In [1]: import numpy as np\n\nIn [2]: arr = np.array([1, 2, 3, 4, 5])\n\nIn [3]: arr?\nType:            ndarray\nString form:     [1 2 3 4 5]\nLength:          5\n...\n\nIn [4]: %timeit arr ** 2\nThe slowest run took 12.34 microseconds...\n
    "},{"location":"Terminal/#pip","title":"PIP \u5ba2\u6237\u7aef","text":"

    PIP \u5ba2\u6237\u7aef\u63d0\u4f9b Python \u5305\u7ba1\u7406\u7684\u547d\u4ee4\u884c\u8bbf\u95ee\u3002

    "},{"location":"Terminal/#_9","title":"\u529f\u80fd","text":"
    • \u4ece PyPI \u5b89\u88c5\u5305
    • \u67e5\u770b\u5df2\u5b89\u88c5\u7684\u5305
    • \u5347\u7ea7\u5305
    • \u5378\u8f7d\u5305
    • \u641c\u7d22\u5305
    "},{"location":"Terminal/#_10","title":"\u5e38\u7528\u547d\u4ee4","text":"
    # \u5b89\u88c5\u5305\npip install requests\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u5305\npip list\n\n# \u5347\u7ea7\u5305\npip install --upgrade requests\n\n# \u5378\u8f7d\u5305\npip uninstall requests\n\n# \u641c\u7d22\u5305\npip search json\n
    "},{"location":"Terminal/#_11","title":"\u4f7f\u7528\u6280\u5de7","text":"
    • \u957f\u6309\u4ece\u4eea\u8868\u76d8\u8bbf\u95ee PIP \u5ba2\u6237\u7aef
    • \u4f7f\u7528 pip help \u67e5\u770b\u6240\u6709\u53ef\u7528\u547d\u4ee4
    • \u67d0\u4e9b\u547d\u4ee4\u53ef\u80fd\u9700\u8981\u7ba1\u7406\u5458\u6743\u9650
    "},{"location":"Terminal/#_12","title":"\u9009\u62e9\u5408\u9002\u7684\u5de5\u5177","text":"\u5de5\u5177 \u6700\u4f73\u7528\u9014 Shell \u7ec8\u7aef \u5feb\u901f\u8ba1\u7b97\u3001\u7b80\u5355\u811a\u672c\u3001\u6d4b\u8bd5\u4ee3\u7801\u7247\u6bb5 IPython \u590d\u6742\u63a2\u7d22\u3001\u6570\u636e\u5206\u6790\u3001\u4ea4\u4e92\u5f0f\u8c03\u8bd5 PIP \u5ba2\u6237\u7aef \u5b89\u88c5/\u66f4\u65b0\u5305\u3001\u68c0\u67e5\u4f9d\u8d56"},{"location":"Terminal/#_13","title":"\u4e86\u89e3\u66f4\u591a","text":"
    • Python \u6587\u6863 \u2013 \u5b98\u65b9 Python \u8bed\u8a00\u548c\u5e93\u53c2\u8003
    • IPython \u6587\u6863 \u2013 \u9ad8\u7ea7\u4ea4\u4e92\u5f0f Python \u529f\u80fd
    • PyPI \u6307\u5357 \u2013 \u5728 QPython \u4e2d\u7ba1\u7406 Python \u5305
    "},{"location":"editor-guide/","title":"\u4f7f\u7528\u6700\u4f73\u5f00\u53d1\u65b9\u5f0f","text":""},{"location":"editor-guide/#qeditor","title":"\u4ece QEditor \u5f00\u53d1","text":"

    QEditor \u662f QPython \u7684\u5185\u7f6e\u7f16\u8f91\u5668\uff0c\u652f\u6301 Python / HTML \u8bed\u6cd5\u9ad8\u4eae\u3002

    QEditor \u7684\u4e3b\u8981\u529f\u80fd

    • \u7f16\u8f91/\u67e5\u770b\u7eaf\u6587\u672c\u6587\u4ef6\uff0c\u5982 Python\u3001Lua\u3001HTML\u3001Javascript \u7b49

    • \u7f16\u8f91\u548c\u8fd0\u884c Python \u811a\u672c & Python \u8bed\u6cd5\u9ad8\u4eae

    • \u7f16\u8f91\u548c\u8fd0\u884c Shell \u811a\u672c

    • \u4f7f\u7528\u5185\u7f6e HTML \u6d4f\u89c8\u5668\u9884\u89c8 HTML

    • \u6309\u5173\u952e\u5b57\u641c\u7d22\u3001\u4ee3\u7801\u7247\u6bb5\u3001\u4ee3\u7801\u5206\u4eab

    \u60a8\u53ef\u4ee5\u76f4\u63a5\u5728 QEditor \u4e2d\u8fd0\u884c QPython \u811a\u672c\uff0c\u56e0\u6b64\u5728\u79fb\u52a8\u65f6\u8fd9\u662f QPython \u5f00\u53d1\u6700\u65b9\u4fbf\u7684\u65b9\u5f0f\u3002

    "},{"location":"editor-guide/#_2","title":"\u901a\u8fc7\u6d4f\u89c8\u5668\u5f00\u53d1","text":"

    QPython \u6709\u4e00\u4e2a\u5185\u7f6e\u811a\u672c qedit4web.py\uff0c\u5f53\u60a8\u70b9\u51fb\u5f00\u59cb\u6309\u94ae\u5e76\u9009\u62e9\"\u8fd0\u884c\u672c\u5730\u811a\u672c\"\u65f6\u53ef\u4ee5\u770b\u5230\u5b83\u3002

    \u8fd0\u884c\u540e\uff0c\u60a8\u53ef\u4ee5\u770b\u5230\u7ed3\u679c\u3002

    \u7136\u540e\uff0c\u60a8\u53ef\u4ee5\u901a\u8fc7 PC/\u7b14\u8bb0\u672c\u7535\u8111\u7684\u6d4f\u89c8\u5668\u8bbf\u95ee\u8be5\u7f51\u5740\u8fdb\u884c\u5f00\u53d1\uff0c\u5982\u4e0b\u56fe\u6240\u793a\u3002

    \u9009\u62e9\u67d0\u4e2a\u9879\u76ee\u6216\u811a\u672c\u540e\uff0c\u60a8\u53ef\u4ee5\u5f00\u59cb\u5f00\u53d1

    \u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\u7f16\u5199\u6d4f\u89c8\u5668\u4ee3\u7801\uff0c\u7136\u540e\u5728 Android \u624b\u673a\u4e0a\u8fd0\u884c\u3002\u975e\u5e38\u65b9\u4fbf\u3002

    "},{"location":"editor-guide/#_3","title":"\u4ece\u60a8\u7684\u7535\u8111\u5f00\u53d1","text":"

    \u9664\u4e86\u4e0a\u8ff0\u65b9\u6cd5\uff0c\u60a8\u8fd8\u53ef\u4ee5\u7528\u81ea\u5df1\u7684\u65b9\u5f0f\u5f00\u53d1\u811a\u672c\uff0c\u7136\u540e\u901a\u8fc7\u5185\u7f6e\u7684 FTP \u670d\u52a1\u5c06\u5176\u4e0a\u4f20\u5230\u624b\u673a\uff0c\u7528 QPython \u8fd0\u884c\u5b83\u3002

    "},{"location":"external-api/","title":"QPython \u5f00\u653e API","text":"

    QPython \u6709\u4e00\u4e2a\u5f00\u653e\u7684 activity\uff0c\u5141\u8bb8\u60a8\u4ece\u5916\u90e8\u8fd0\u884c qpython\u3002

    MPyAPI \u7684\u5b9a\u4e49\u5982\u4e0b\uff1a

        <activity\n        android:name=\"org.qpython.qpylib.MPyApi\"\n        android:label=\"@string/qpy_run_with_share\"\n        android:screenOrientation=\"user\"\n        android:configChanges=\"orientation|keyboardHidden\"\n        android:exported=\"true\">\n        <intent-filter>\n            <action android:name=\"org.qpython.qpylib.action.MPyApi\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.LAUNCHER\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.VIEW\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.BROWSABLE\" />\n            <data android:scheme=\"http\" />\n            <data android:scheme=\"https\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"text/plain\"/>\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"image/*\"/>\n        </intent-filter>\n    </activity>\n

    \u56e0\u6b64\uff0c\u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\uff1a

    "},{"location":"external-api/#qpython","title":"\u5c06\u5185\u5bb9\u5206\u4eab\u5230 QPython \u7684\u811a\u672c","text":"

    \u60a8\u53ef\u4ee5\u5728\u67d0\u4e2a\u5e94\u7528\u4e2d\u9009\u62e9\u4e00\u4e9b\u5185\u5bb9\uff0c\u7136\u540e\u5206\u4eab\u5230 qpython \u7684\u811a\u672c\uff0c\u4e4b\u540e\u60a8\u53ef\u4ee5\u4f7f\u7528 sys.argv[2] \u5904\u7406\u8fd9\u4e9b\u5185\u5bb9

    \u5728 YouTube \u4e0a\u89c2\u770b\u6f14\u793a\u89c6\u9891

    "},{"location":"external-api/#qpython_1","title":"\u4ece\u60a8\u81ea\u5df1\u7684\u5e94\u7528\u7a0b\u5e8f\u8fd0\u884c QPython \u7684\u811a\u672c","text":"

    \u60a8\u53ef\u4ee5\u901a\u8fc7\u8c03\u7528\u6b64 activity \u5728\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u4e2d\u8c03\u7528 QPython \u6765\u8fd0\u884c\u67d0\u4e9b\u811a\u672c\u6216 Python \u4ee3\u7801\uff0c\u793a\u4f8b\u5982\u4e0b\uff1a

    // \u5c55\u793a\u5982\u4f55\u8c03\u7528 qpython API \u7684\u4ee3\u7801\u793a\u4f8b\nString extPlgPlusName = \"org.qpython.qpy\";          // QPython \u5305\u540d\nIntent intent = new Intent();\nintent.setClassName(extPlgPlusName, \"org.qpython.qpylib.MPyApi\");\nintent.setAction(extPlgPlusName + \".action.MPyApi\");\n\nBundle mBundle = new Bundle();\nmBundle.putString(\"app\", \"myappid\");\nmBundle.putString(\"act\", \"onPyApi\");\nmBundle.putString(\"flag\", \"onQPyExec\"); // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u4efb\u610f\u5b57\u7b26\u4e32\u6807\u5fd7\nmBundle.putString(\"param\", \"\");         // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u53c2\u6570\u5b57\u7b26\u4e32\n\n/*\n* \u6211\u4eec\u5c06\u8fd0\u884c\u7684 Python \u4ee3\u7801\n*/\nString code = \"import androidhelper\\n\" +\n            \"droid = androidhelper.Android()\\n\" +\n            \"line = droid.dialogGetInput()\\n\" +\n            \"s = 'Hello %s' % line.result\\n\" +\n            \"droid.makeToast(s)\\n\"\n\nmBundle.putString(\"pycode\", code);\nintent.putExtras(mBundle);\nstartActivityForResult(intent, SCRIPT_EXEC_PY);\n...\n\n// \u60a8\u53ef\u4ee5\u5728 onActivityResult \u4e2d\u5904\u7406 qpython \u8c03\u7528\u7ed3\u679c\n@Override\nprotected void onActivityResult(int requestCode, int resultCode, Intent data) {\n    if (requestCode == SCRIPT_EXEC_PY) {\n        if (data!=null) {\n            Bundle bundle = data.getExtras();\n            String flag = bundle.getString(\"flag\");\n            String param = bundle.getString(\"param\");\n            String result = bundle.getString(\"result\"); // \u60a8\u7684 Pycode \u751f\u6210\u7684\u7ed3\u679c\n            Toast.makeText(this, \"onQPyExec: return (\"+result+\")\", Toast.LENGTH_SHORT).show();\n        } else {\n            Toast.makeText(this, \"onQPyExec: data is null\", Toast.LENGTH_SHORT).show();\n\n        }\n    }\n}\n

    \u4ece github \u68c0\u51fa\u4e00\u4e2a\u5b8c\u6574\u9879\u76ee

    \u8fd8\u6709\u4e00\u4e2a\u751f\u4ea7\u5e94\u7528\u7a0b\u5e8f - \u9762\u5411 Tasker \u7684 QPython \u63d2\u4ef6

    "},{"location":"getting-started/","title":"QPython\uff1a\u5165\u95e8\u6307\u5357","text":"

    \u672c\u6307\u5357\u5c06\u4ecb\u7ecd QPython \u7684\u529f\u80fd\u5e76\u5e2e\u52a9\u60a8\u5feb\u901f\u5165\u95e8\u3002

    "},{"location":"getting-started/#qpython_1","title":"QPython \u6982\u8ff0","text":"

    \u4e3a\u4ec0\u4e48\u9009\u62e9 QPython\uff1f

    \u667a\u80fd\u624b\u673a\u6b63\u5728\u6210\u4e3a\u4eba\u4eec\u5fc5\u5907\u7684\u4fe1\u606f\u548c\u6280\u672f\u52a9\u624b\uff0c\u4e00\u4e2a\u7075\u6d3b\u7684\u89e3\u91ca\u5668\u5f15\u64ce\u53ef\u4ee5\u5e2e\u52a9\u4eba\u4eec\u9ad8\u6548\u5730\u5b8c\u6210\u5927\u90e8\u5206\u5de5\u4f5c\uff0c\u65e0\u9700\u590d\u6742\u7684\u5f00\u53d1\u8fc7\u7a0b\u3002

    QPython \u63d0\u4f9b\u4e86 \u60ca\u4eba\u7684\u5f00\u53d1\u4f53\u9a8c\u2014\u2014\u501f\u52a9\u5b83\u7684\u5e2e\u52a9\uff0c\u60a8\u53ef\u4ee5\u8f7b\u677e\u5b9e\u73b0\u7a0b\u5e8f\uff0c\u65e0\u9700\u590d\u6742\u7684 IDE \u5b89\u88c5\u3001\u7f16\u8bd1\u6216\u6253\u5305\u8fc7\u7a0b\u3002

    "},{"location":"getting-started/#qpython_2","title":"QPython \u7248\u672c","text":"

    \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

    • QPython - Python \u548c AI \u7684 IDE \u2013 \u5177\u6709 AI \u529f\u80fd\u7684\u4e3b\u8981\u7248\u672c\uff0c\u53ef\u5728 Google Play \u548c\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d
    • QPython+ - Android \u7684 Python \u2013 \u9762\u5411\u8d21\u732e\u8005\u7684\u793e\u533a\u5f00\u6e90\u7248\u672c
    • QPython Plus \u2013 \u6269\u5c55\u6743\u9650\u7248\u672c\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff09
    "},{"location":"getting-started/#_1","title":"\u4e3b\u8981\u7279\u6027","text":"
    • \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668 - \u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51
    • \u591a\u79cd\u8fd0\u884c\u6a21\u5f0f - \u63a7\u5236\u53f0\u3001SL4A\u3001Kivy GUI\u3001WebApp \u548c\u540e\u53f0\uff08QScript\uff09\u6a21\u5f0f
    • SL4A \u96c6\u6210 - \u4f7f\u7528 Python \u63a7\u5236 Android \u786c\u4ef6\u548c API
    • \u5305\u5b89\u88c5 - QPYPI \u548c pip \u652f\u6301\u4ee5\u6269\u5c55\u529f\u80fd
    • \u5185\u7f6e\u7f16\u8f91\u5668 - \u8bed\u6cd5\u9ad8\u4eae\u548c\u4ee3\u7801\u7f16\u8f91
    • \u4e8c\u7ef4\u7801\u652f\u6301 - \u65b9\u4fbf\u7684\u4ee3\u7801\u5206\u4eab\u548c\u5206\u53d1
    "},{"location":"getting-started/#1","title":"1. \u4eea\u8868\u76d8","text":"

    \u5b89\u88c5 QPython \u540e\uff0c\u70b9\u51fb\u5176\u56fe\u6807\u542f\u52a8\u3002\u60a8\u5c06\u770b\u5230\u5e26\u6709 QPython \u6807\u5fd7\u548c\u4ee5\u4e0b\u529f\u80fd\u7684\u4e3b\u4eea\u8868\u76d8\uff1a

    "},{"location":"getting-started/#_2","title":"\u4eea\u8868\u76d8\u529f\u80fd","text":"

    QPython \u4eea\u8868\u76d8\u63d0\u4f9b\u5bf9\u6240\u6709\u4e3b\u8981\u529f\u80fd\u7684\u5feb\u901f\u8bbf\u95ee\uff1a

    • \u7ec8\u7aef \u2014 \u8bbf\u95ee Python \u63a7\u5236\u53f0\u548c shell \u4ee5\u76f4\u63a5\u6267\u884c\u547d\u4ee4
    • Notebook \u2014 \u7528\u4e8e\u6570\u636e\u5206\u6790\u548c\u5b9e\u9a8c\u7684\u4ea4\u4e92\u5f0f Jupyter \u98ce\u683c\u7b14\u8bb0\u672c
    • \u7f16\u8f91\u5668 \u2014 \u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668\uff0c\u5177\u6709\u8bed\u6cd5\u9ad8\u4eae\u529f\u80fd\uff0c\u7528\u4e8e\u7f16\u5199 Python \u811a\u672c
    • \u8d44\u6e90\u7ba1\u7406\u5668 \u2014 \u6d4f\u89c8\u548c\u7ba1\u7406\u60a8\u7684\u6587\u4ef6\u3001\u811a\u672c\u548c\u9879\u76ee
    • QPYPI \u2014 \u5b89\u88c5 Python \u5305\u548c\u6269\u5c55\u3002\u8be6\u89c1 QPYPI \u6307\u5357
    • \u8bbe\u7f6e \u2014 \u914d\u7f6e QPython \u9996\u9009\u9879\u548c\u8fd0\u884c\u9009\u9879
    • \u793e\u533a \u2014 \u8bbf\u95ee QPython \u793e\u533a\u8d44\u6e90\u3001\u8bba\u575b\u548c\u5e2e\u52a9
    • \u8bfe\u7a0b \u2014 \u8bbf\u95ee Python \u7f16\u7a0b\u7684\u5b66\u4e60\u6750\u6599\u548c\u6559\u7a0b

    \u70b9\u51fb\u4efb\u4f55\u56fe\u6807\u4ee5\u8bbf\u95ee\u76f8\u5e94\u7684\u529f\u80fd\u3002

    "},{"location":"getting-started/#2","title":"2. \u7ec8\u7aef\u548c\u7f16\u8f91\u5668","text":""},{"location":"getting-started/#_3","title":"\u7ec8\u7aef","text":"

    \u7ec8\u7aef\u63d0\u4f9b\u4e00\u4e2a Python \u63a7\u5236\u53f0\uff0c\u60a8\u53ef\u4ee5\uff1a - \u63a2\u7d22\u5bf9\u8c61\u5c5e\u6027 - \u6d4b\u8bd5\u8bed\u6cd5\u548c\u60f3\u6cd5 - \u76f4\u63a5\u6267\u884c\u547d\u4ee4

    \u4f7f\u7528\u52a0\u53f7\u6309\u94ae\uff081\uff09\u6253\u5f00\u989d\u5916\u7684\u7ec8\u7aef\u6807\u7b7e\u9875\uff0c\u4ece\u4e0b\u62c9\u83dc\u5355\uff082\uff09\u5207\u6362\u5b83\u4eec\uff0c\u5e76\u4f7f\u7528\u5173\u95ed\u6309\u94ae\uff083\uff09\u5173\u95ed\u5b83\u4eec\u3002

    \u7ec8\u7aef\u8fd0\u884c\u65f6\uff0c\u901a\u77e5\u680f\u4e2d\u4f1a\u4fdd\u7559\u4e00\u6761\u901a\u77e5\u3002\u70b9\u51fb\u5b83\u53ef\u8fd4\u56de\u7ec8\u7aef\u3002

    "},{"location":"getting-started/#_4","title":"\u7f16\u8f91\u5668","text":"

    \u7f16\u8f91\u5668\u529f\u80fd\uff1a - Python \u8bed\u6cd5\u9ad8\u4eae - \u884c\u53f7 - \u7f29\u8fdb\u63a7\u5236\uff08\u5de5\u5177\u680f\u4e0a\u7684\u6309\u94ae 1\uff09 - \u4fdd\u5b58\u548c\u53e6\u5b58\u4e3a\uff08\u6309\u94ae 2\uff09 - \u8fd0\u884c\uff08\u6309\u94ae 3\uff09 - \u64a4\u9500\u3001\u641c\u7d22\u3001\u6700\u8fd1\u6587\u4ef6\u3001\u8bbe\u7f6e - \u6253\u5f00\u548c\u65b0\u5efa\uff08\u9876\u90e8\u6309\u94ae 5\uff09

    \u91cd\u8981\u63d0\u793a\uff1a \u4fdd\u5b58\u65f6\u8bf7\u624b\u52a8\u6dfb\u52a0 .py \u6269\u5c55\u540d\uff0c\u56e0\u4e3a\u7f16\u8f91\u5668\u4e0d\u4f1a\u81ea\u52a8\u6dfb\u52a0\u3002

    "},{"location":"getting-started/#3","title":"3. \u8d44\u6e90\u7ba1\u7406\u5668\uff08\u6587\u4ef6\u7ba1\u7406\uff09","text":"

    \u901a\u8fc7 \u8d44\u6e90\u7ba1\u7406\u5668 \u8bbf\u95ee\u60a8\u7684\u811a\u672c\u548c\u9879\u76ee\u3002\u5728\u8fd9\u91cc\u60a8\u53ef\u4ee5\u6d4f\u89c8\u3001\u7ec4\u7ec7\u548c\u7ba1\u7406\u6240\u6709 Python \u6587\u4ef6\u3002

    "},{"location":"getting-started/#_5","title":"\u811a\u672c","text":"

    \u811a\u672c\u662f\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/scripts3/ \u4e2d\u7684\u5355\u4e2a Python \u6587\u4ef6\uff08\u9488\u5bf9 Python 3\uff09\u3002

    \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u811a\u672c - \u6253\u5f00 \u2014 \u4f7f\u7528\u5185\u7f6e\u7f16\u8f91\u5668\u7f16\u8f91 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u811a\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u811a\u672c

    "},{"location":"getting-started/#_6","title":"\u9879\u76ee","text":"

    \u9879\u76ee\u662f\u5305\u542b main.py \u4f5c\u4e3a\u5165\u53e3\u70b9\u7684\u76ee\u5f55\u3002\u60a8\u53ef\u4ee5\u5728\u540c\u4e00\u76ee\u5f55\u4e2d\u5305\u542b\u5176\u4ed6\u4f9d\u8d56\u9879\u548c\u8d44\u6e90\u3002\u5c06\u9879\u76ee\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/projects3/ \u4e2d\u3002

    "},{"location":"getting-started/#_7","title":"\u7b14\u8bb0\u672c","text":"

    Jupyter \u98ce\u683c\u7684\u7b14\u8bb0\u672c\u4e5f\u901a\u8fc7\u8d44\u6e90\u7ba1\u7406\u5668\u8fdb\u884c\u7ba1\u7406\uff0c\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/notebooks/ \u4e2d\u3002

    \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u9879\u76ee - \u6253\u5f00 \u2014 \u63a2\u7d22\u9879\u76ee\u8d44\u6e90 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u9879\u76ee\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u9879\u76ee

    "},{"location":"getting-started/#4","title":"4. \u5e93","text":"

    \u901a\u8fc7\u5b89\u88c5\u7b2c\u4e09\u65b9\u5e93\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

    "},{"location":"getting-started/#_8","title":"\u5305\u5b89\u88c5\u65b9\u6cd5","text":"

    QPYPI\uff08\u63a8\u8350\uff09

    \u4ece QPYPI \u5b89\u88c5\u9884\u7f16\u8bd1\u7684\u5e93\uff0c\u5305\u62ec numpy\u3001scipy \u7b49\u79d1\u5b66\u5305\u3002

    \u8be6\u89c1 QPYPI \u6307\u5357\u3002

    PIP \u5ba2\u6237\u7aef

    \u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216 QPYPI \u4eea\u8868\u76d8\u5b89\u88c5\u7eaf Python \u5e93\uff1a

    pip install requests\n

    \u9884\u7f16\u8bd1\u5305

    \u5bf9\u4e8e\u5177\u6709 C/C++/Rust \u4f9d\u8d56\u7684\u5305\uff0c\u4f7f\u7528 QPython \u7684\u9884\u7f16\u8bd1\u5305\uff1a

    pip install numpy-qpython\npip install scipy-aipy\n

    \u8be6\u89c1 QPYPI \u6307\u5357 \u83b7\u53d6\u53ef\u7528\u5305\u7684\u5b8c\u6574\u5217\u8868\u3002

    \u624b\u52a8\u5b89\u88c5

    \u60a8\u4e5f\u53ef\u4ee5\u5c06\u5e93\u590d\u5236\u5230 /storage/emulated/0/Android/data/org.qpython.qpy/files/lib/python3.12/site-packages/\u3002

    "},{"location":"getting-started/#5","title":"5. \u8fd0\u884c\u6a21\u5f0f","text":"

    QPython \u652f\u6301\u591a\u79cd\u8fd0\u884c\u6a21\u5f0f\u4ee5\u6ee1\u8db3\u4e0d\u540c\u7684\u7528\u4f8b\uff1a

    "},{"location":"getting-started/#_9","title":"\u63a7\u5236\u53f0\u6a21\u5f0f","text":"

    \u5e38\u89c4 Python \u811a\u672c\u7684\u9ed8\u8ba4\u6a21\u5f0f\u3002

    "},{"location":"getting-started/#sl4a","title":"SL4A \u6a21\u5f0f","text":"

    \u901a\u8fc7 SL4A \u5e93\u4f7f\u7528 Android API \u7684\u811a\u672c\u3002

    import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello Android!')\n

    \u8be6\u89c1 QSL4A \u6587\u6863 \u83b7\u53d6\u5b8c\u6574\u7684 API \u53c2\u8003\u3002

    "},{"location":"getting-started/#webapp","title":"WebApp \u6a21\u5f0f","text":"

    \u4f7f\u7528\u540e\u7aef\u670d\u52a1\u5668\u521b\u5efa\u57fa\u4e8e Web \u7684\u5e94\u7528\u7a0b\u5e8f\u3002

    \u5728\u811a\u672c\u4e2d\u6dfb\u52a0 headers\uff1a

    #qpy:webapp:Hello QPython\n#qpy://localhost:8080/hello\n\nfrom bottle import route, run, Bottle\n\napp = Bottle()\n\n@route('/hello')\ndef hello():\n    return '<h1>Hello from QPython!</h1>'\n\nrun(app, host='localhost', port=8080)\n

    "},{"location":"getting-started/#q","title":"Q \u6a21\u5f0f\uff08\u540e\u53f0\uff09","text":"

    \u5728\u540e\u53f0\u65e0 UI \u8fd0\u884c\u811a\u672c\u3002

    \u6dfb\u52a0 header\uff1a

    #qpy:quiet\n\nimport time\n\nwhile True:\n    # \u60a8\u7684\u540e\u53f0\u4efb\u52a1\n    time.sleep(60)\n

    "},{"location":"getting-started/#6","title":"6. \u793e\u533a\u4e0e\u652f\u6301","text":"

    \u8bbf\u95ee QPython.org \u83b7\u53d6\uff1a - \u6587\u6863 - \u7528\u6237\u793e\u533a - \u5e2e\u52a9\u548c\u95ee\u7b54

    \u793e\u533a\u94fe\u63a5\uff1a - Facebook \u7fa4\u7ec4 - GitHub - \u95ee\u9898\u53cd\u9988

    \u4e0b\u4e00\u6b65\uff1a - \u5c1d\u8bd5 Hello World \u6559\u7a0b - \u63a2\u7d22 QSL4A API \u4ee5\u96c6\u6210 Android - \u4e86\u89e3 QPython \u7248\u672c

    \u611f\u8c22 dmych \u5728\u4ed6\u7684\u535a\u5ba2\u4e0a\u63d0\u4f9b\u7684\u539f\u59cb\u8349\u7a3f

    "},{"location":"qpypi-guide/","title":"QPYPI","text":"

    \u60a8\u53ef\u4ee5\u901a\u8fc7\u5b89\u88c5\u5305\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

    "},{"location":"qpypi-guide/#_1","title":"\u5305\u5b89\u88c5\u652f\u6301","text":""},{"location":"qpypi-guide/#python","title":"\u7eaf Python \u5305","text":"

    QPython \u652f\u6301\u4f7f\u7528\u7eaf Python \u5f00\u53d1\u7684 Python \u5305\u3002\u60a8\u53ef\u4ee5\u76f4\u63a5\u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216\u4eea\u8868\u76d8\u4e0a\u7684 QPYPI \u4f7f\u7528 pip install \u5b89\u88c5\u8fd9\u4e9b\u5305\u3002

    "},{"location":"qpypi-guide/#_2","title":"\u9884\u7f16\u8bd1\u5305","text":"

    \u5982\u679c\u67d0\u4e9b\u5305\uff08\u6216\u5b83\u4eec\u7684\u4f9d\u8d56\uff09\u662f\u7528 Rust/C/C++ \u5f00\u53d1\u7684\uff0cQPython \u65e0\u6cd5\u76f4\u63a5\u652f\u6301\u5b83\u4eec\uff0c\u56e0\u4e3a QPython \u4e0a\u6ca1\u6709\u7f16\u8bd1\u5668\u5de5\u5177\u94fe\u652f\u6301\u3002\u4f46\u662f\uff0cQPython \u56e2\u961f\u5df2\u7ecf\u9884\u7f16\u8bd1\u4e86\u4e00\u4e9b\u5e38\u7528\u5305\uff0c\u5e76\u5728 QPython \u7684 QPYPI/Extensions \u4e2d\u53d1\u5e03\uff0c\u4f9b\u7528\u6237\u8f7b\u677e\u5b89\u88c5\u3002

    "},{"location":"qpypi-guide/#_3","title":"\u5b89\u88c5\u9884\u7f16\u8bd1\u5305","text":"

    \u60a8\u53ef\u4ee5\u901a\u8fc7\u4ee5\u4e0b\u65b9\u5f0f\u5b89\u88c5\u9884\u7f16\u8bd1\u5305\uff1a

    1. \u901a\u8fc7 QPython \u5e94\u7528\uff1a\u76f4\u63a5\u4ece QPython \u5e94\u7528\u5185\u7684 QPYPI \u6216 Extensions \u5b89\u88c5
    2. \u901a\u8fc7 PyPI\uff1a\u8bbf\u95ee https://pypi.org/user/qpythonx/ \u67e5\u770b\u53ef\u7528\u7684\u5305
    3. \u901a\u8fc7 pip \u547d\u4ee4\uff1a
    4. pip install xxx-qpython - \u5e26 -qpython \u540e\u7f00\u7684\u5305
    5. pip install xxx-aipy - \u5e26 -aipy \u540e\u7f00\u7684\u5305\uff08\u901a\u5e38\u662f AI/ML \u76f8\u5173\u7684\u5305\uff09

    \u6ce8\u610f\uff1a\u6211\u4eec\u901a\u5e38\u6839\u636e\u5305\u7684\u9884\u671f\u7528\u9014\u6dfb\u52a0\u8fd9\u4e9b\u540e\u7f00\u4e4b\u4e00\u3002

    "},{"location":"qpypi-guide/#_4","title":"\u8bf7\u6c42\u65b0\u5305","text":"

    \u5982\u679c\u60a8\u9700\u8981\u5f53\u524d\u4e0d\u652f\u6301\u7684\u5305\uff1a

    • \u5728 qpython.org \u9879\u76ee \u4e2d\u63d0\u51fa\u95ee\u9898
    • QPython \u56e2\u961f\u5c06\u8003\u8651\u9884\u7f16\u8bd1\u5e76\u5c06\u5176\u6dfb\u52a0\u5230\u4ed3\u5e93\u4e2d

    \u83b7\u53d6\u66f4\u591a\u5e2e\u52a9\u548c\u53c2\u4e0e\u793e\u533a\u7684\u65b9\u5f0f\uff0c\u8bf7\u53c2\u9605 \u793e\u533a\u4e0e\u53cd\u9988 \u90e8\u5206\u3002

    \u6ce8\u610f\uff1a\u7531\u4e8e\u4e0d\u540c\u7684\u8ba1\u7b97\u673a\u67b6\u6784\uff0c\u6211\u4eec\u65e0\u6cd5\u4fdd\u8bc1 QPYPI \u5305\u542b PyPI \u4e0a\u7684\u6240\u6709\u5305\u3002

    "},{"location":"qpython-x/","title":"QPython \u7248\u672c","text":"

    QPython \u662f Android \u7684 Python \u5f15\u64ce\u3002\u5b83\u5305\u542b\u4ee4\u4eba\u60ca\u53f9\u7684\u529f\u80fd\uff0c\u5982 Python \u89e3\u91ca\u5668\u3001\u8fd0\u884c\u73af\u5883\u3001\u7f16\u8f91\u5668\u3001QPYI \u548c\u96c6\u6210\u7684 SL4A\u3002\u5b83\u8ba9\u60a8\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 Android \u4e0a\u4f7f\u7528 Python\u3002\u800c\u4e14\u5b83\u662f\u514d\u8d39\u7684\u3002

    QPython \u5df2\u7ecf\u5728\u5168\u7403\u62e5\u6709\u6570\u767e\u4e07\u7528\u6237\uff0c\u4e5f\u662f\u4e00\u4e2a\u5f00\u6e90\u9879\u76ee\u3002

    \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

    "},{"location":"qpython-x/#qpython_1","title":"QPython","text":"

    \u6807\u51c6\u7248\uff1a\u9488\u5bf9 AI \u6027\u80fd\u548c\u901a\u7528\u5e94\u7528\u5546\u5e97\u517c\u5bb9\u6027\u4f18\u5316

    \u4e3b\u8981\u7248\u672c\uff0c\u53ef\u5728 Google Play \u548c\u5176\u4ed6\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002\u6b64\u7248\u672c\u4e13\u6ce8\u4e8e AI \u529f\u80fd\uff0c\u4f7f AI \u65f6\u4ee3\u7528\u6237\u66f4\u5bb9\u6613\u5b66\u4e60\u548c\u4f7f\u7528 Python\u3002

    \u4e3b\u8981\u7279\u6027\uff1a - AI \u9a71\u52a8\u7684\u7f16\u7801\u8f85\u52a9\u548c\u5b66\u4e60\u5de5\u5177 - \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668\uff1a\u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51 - \u652f\u6301\u591a\u79cd\u9879\u76ee\u7c7b\u578b\uff1a\u63a7\u5236\u53f0\u3001SL4A\u3001WebApp - \u65b9\u4fbf\u7684\u4e8c\u7ef4\u7801\u8bfb\u53d6\u5668\uff0c\u7528\u4e8e\u5c06\u4ee3\u7801\u4f20\u8f93\u5230\u624b\u673a - QPYPI \u548c\u81ea\u5b9a\u4e49\u4ed3\u5e93\uff0c\u7528\u4e8e\u9884\u7f16\u8bd1 wheel \u5305 -\u6613\u4e8e\u4f7f\u7528\u7684\u8bed\u6cd5\u9ad8\u4eae\u7f16\u8f91\u5668 - \u5b8c\u5584\u7684\u6587\u6863\u548c\u793e\u533a\u652f\u6301

    \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

    \u4e0b\u8f7d\uff1a \u53ef\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

    "},{"location":"qpython-x/#qpython_2","title":"QPython+","text":"

    \u793e\u533a\u7248\uff1a\u516c\u5f00\u652f\u6301\u5404\u79cd\u793e\u533a\u9a71\u52a8\u7684\u529f\u80fd\uff1b\u53ef\u5728\u90e8\u5206\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

    \u793e\u533a\u5f00\u6e90\u7248\u672c\uff08\u6b63\u5728\u89c4\u5212\u548c\u51c6\u5907\u4e2d\uff09\u3002\u6b64\u7248\u672c\u4e13\u4e3a\u60f3\u8981\u53c2\u4e0e QPython \u9879\u76ee\u5f00\u53d1\u7684\u8d21\u732e\u8005\u800c\u8bbe\u8ba1\uff0c\u652f\u6301\u9488\u5bf9\u4e0d\u540c\u5236\u9020\u5546\u7684\u5b9a\u5236\u3002

    \u4e3b\u8981\u7279\u6027\uff1a - \u793e\u533a\u9a71\u52a8\u5f00\u53d1 - \u652f\u6301\u4f9b\u5e94\u5546\u5b9a\u5236 - \u66f4\u7075\u6d3b\u7684\u914d\u7f6e\u9009\u9879 - \u5f00\u653e\u4f9b\u8d21\u732e\u8005\u52a0\u5165\u5f00\u53d1

    \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

    \u4e0b\u8f7d\uff1a \u5c06\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

    \u6ce8\u610f\uff1a \u6b64\u7248\u672c\u76ee\u524d\u6b63\u5728\u89c4\u5212\u51c6\u5907\u4e2d\u3002\u8bf7\u5173\u6ce8\u66f4\u65b0\uff01

    "},{"location":"qpython-x/#qpython-plus","title":"QPython Plus","text":"

    QPython+ \u5b8c\u5168\u8bbf\u95ee\u7248\uff1a\u6388\u4e88\u8c03\u7528\u6240\u6709 Android \u63a5\u53e3\u7684\u5b8c\u6574\u6743\u9650\u3002\u4e0b\u8f7d\u94fe\u63a5\u4ec5\u901a\u8fc7\u5b98\u65b9\u4e91\u76d8\u63d0\u4f9b\u3002

    \u5177\u6709\u6269\u5c55\u6743\u9650\u7684\u7279\u6b8a\u7248\u672c\uff0c\u63d0\u4f9b\u5bf9\u8bbe\u5907\u7684\u6700\u5927\u63a7\u5236\u3002\u7531\u4e8e\u5176\u654f\u611f\u7684\u6743\u9650\u8981\u6c42\uff0c\u6b64\u7248\u672c\u4e0d\u4f1a\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u53d1\u5e03\u3002

    \u4e3b\u8981\u7279\u6027\uff1a - \u5b8c\u6574\u7684 SL4A API \u8bbf\u95ee\uff0c\u5305\u62ec\u654f\u611f\u529f\u80fd - SMS/\u901a\u8bdd\u63a7\u5236 API - \u9ad8\u7ea7\u7cfb\u7edf\u96c6\u6210 - \u6700\u5927\u7684\u8bbe\u5907\u63a7\u5236\u80fd\u529b

    \u6743\u9650\uff1a \u9700\u8981\u5e7f\u6cdb\u7684\u6743\u9650\uff0c\u5305\u62ec\uff1a - \u84dd\u7259 - \u4f4d\u7f6e\uff08GPS\uff09 - \u8bfb\u53d6/\u53d1\u9001\u77ed\u4fe1 - \u6253\u7535\u8bdd - \u76f8\u673a\u548c\u9ea6\u514b\u98ce - \u7cfb\u7edf\u8bbe\u7f6e - \u4ee5\u53ca\u5176\u4ed6\u654f\u611f\u6743\u9650

    \u4e0b\u8f7d\uff1a \u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\u3002\u4ec5\u901a\u8fc7\u7279\u6b8a\u6e20\u9053\u5206\u53d1\u3002

    \u91cd\u8981\u63d0\u793a\uff1a QPython \u4e0d\u4f1a\u5728\u540e\u53f0\u672a\u7ecf\u60a8\u77e5\u6089\u4f7f\u7528\u8fd9\u4e9b\u6743\u9650\u3002\u5982\u679c\u4f7f\u7528 SL4A API \u65f6\u51fa\u73b0\u5f02\u5e38\uff0c\u8bf7\u68c0\u67e5\u7cfb\u7edf\u8bbe\u7f6e\u4e2d\u662f\u5426\u5df2\u542f\u7528\u76f8\u5173\u6743\u9650\u3002

    "},{"location":"tutorial-hello-world/","title":"\u7f16\u5199\"Hello World\"","text":""},{"location":"tutorial-hello-world/#hello-world_1","title":"Hello world","text":"

    \u597d\u7684\uff0c\u5728\u60a8\u5bf9 QPython \u6709\u4e86\u4e00\u5b9a\u7684\u4e86\u89e3\u4e4b\u540e\uff0c\u8ba9\u6211\u4eec\u5728 QPython \u4e2d\u521b\u5efa\u6211\u4eec\u7684\u7b2c\u4e00\u4e2a\u7a0b\u5e8f\u3002\u663e\u7136\uff0c\u5b83\u5c06\u662f helloworld.py\u3002;)

    \u542f\u52a8 QPython\uff0c\u6253\u5f00\u7f16\u8f91\u5668\u5e76\u8f93\u5165\u4ee5\u4e0b\u4ee3\u7801\uff1a

    import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello, Username!')\n

    \u6beb\u65e0\u7591\u95ee\uff0c\u5b83\u4e0e\u5176\u4ed6\u4efb\u4f55 hello-world \u7a0b\u5e8f\u5e76\u65e0\u4e0d\u540c\u3002\u6267\u884c\u65f6\uff0c\u5b83\u53ea\u662f\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u5f39\u51fa\u6d88\u606f\uff08\u89c1\u9876\u90e8\u622a\u56fe\uff09\u3002\u65e0\u8bba\u5982\u4f55\uff0c\u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684 QPython \u7a0b\u5e8f\u793a\u4f8b\u3002

    "},{"location":"tutorial-hello-world/#sl4a","title":"SL4A \u5e93","text":"

    \u5b83\u4ee5 import androidhelper \u5f00\u5934\u2014\u2014\u8fd9\u662f QPython \u4e2d\u6700\u6709\u7528\u7684\u6a21\u5757\uff0c\u5b83\u5c01\u88c5\u4e86 Python \u4e2d\u53ef\u7528\u7684\u51e0\u4e4e\u6240\u6709\u4e0e Android \u7684\u63a5\u53e3\u3002\u4efb\u4f55\u5728 QPython \u4e2d\u5f00\u53d1\u7684\u811a\u672c\u90fd\u4ee5\u8fd9\u4e2a\u8bed\u53e5\u5f00\u5934\uff08\u81f3\u5c11\u5982\u679c\u5b83\u58f0\u79f0\u8981\u4e0e\u7528\u6237\u901a\u4fe1\u7684\u8bdd\uff09\u3002\u5728\u6b64\u5904\u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u5e93 \u548c import \u8bed\u53e5 \u7684\u5185\u5bb9\u3002

    \u987a\u4fbf\u8bf4\u4e00\u53e5\uff0c\u5982\u679c\u60a8\u6253\u7b97\u4f7f\u60a8\u7684\u811a\u672c\u4e0e SL4A \u517c\u5bb9\uff0c\u60a8\u5e94\u8be5\u7528\u4ee5\u4e0b\u4ee3\u7801\u66ff\u6362\u7b2c\u4e00\u884c\uff08\u5e76\u5728\u7a0b\u5e8f\u4e2d\u7528 android \u800c\u4e0d\u662f androidhelper\uff09\uff1a

    try:\n    import androidhelper as android\nexcept ImportError:\n    import android\n

    \u597d\u7684\uff0c\u63a5\u4e0b\u6765\u6211\u4eec\u521b\u5efa\u4e00\u4e2a droid \u5bf9\u8c61\uff08\u5b9e\u9645\u4e0a\u662f\u4e00\u4e2a\u7c7b\uff09\uff0c\u5b83\u5bf9\u4e8e\u8c03\u7528 RPC \u51fd\u6570\u4ee5\u4e0e Android \u901a\u4fe1\u662f\u5fc5\u8981\u7684\u3002

    \u6211\u4eec\u4ee3\u7801\u7684\u6700\u540e\u4e00\u884c\u8c03\u7528\u4e86\u8fd9\u6837\u7684\u51fd\u6570\uff0cdroid.makeToast()\uff0c\u5b83\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u4e00\u4e2a\u5c0f\u7684\u5f39\u51fa\u6d88\u606f\uff08\"toast\"\uff09\u3002

    \u597d\u7684\uff0c\u8ba9\u6211\u4eec\u6dfb\u52a0\u4e00\u4e9b\u66f4\u591a\u7684\u529f\u80fd\u3002\u8ba9\u5b83\u8be2\u95ee\u7528\u6237\u540d\u5e76\u5411\u7528\u6237\u6253\u62db\u547c\u3002

    "},{"location":"tutorial-hello-world/#_1","title":"\u66f4\u591a\u793a\u4f8b","text":"

    \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 dialogGetInput \u8c03\u7528\u663e\u793a\u4e00\u4e2a\u5e26\u6709\u6807\u9898\u3001\u63d0\u793a\u3001\u7f16\u8f91\u5b57\u6bb5\u548c \u786e\u5b9a \u548c \u53d6\u6d88 \u6309\u94ae\u7684\u7b80\u5355\u5bf9\u8bdd\u6846\u3002\u7528\u4ee5\u4e0b\u4ee3\u7801\u66ff\u6362\u60a8\u7684\u6700\u540e\u4e00\u884c\u4ee3\u7801\u5e76\u5c06\u5176\u4fdd\u5b58\u4e3a hello1.py\uff1a

    import androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\n

    \u597d\u7684\uff0c\u6211\u8ba4\u4e3a\u5b83\u5e94\u8be5\u8fd4\u56de\u4efb\u4f55\u54cd\u5e94\uff0c\u4efb\u4f55\u7528\u6237\u53cd\u5e94\u3002\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u6211\u5199 respond = ...\u3002\u4f46\u8fd9\u4e2a\u8c03\u7528\u5b9e\u9645\u4e0a\u8fd4\u56de\u4ec0\u4e48\uff1f\u8ba9\u6211\u4eec\u68c0\u67e5\u4e00\u4e0b\u3002\u53ea\u9700\u5728\u6700\u540e\u4e00\u884c\u540e\u6dfb\u52a0 print \u8bed\u53e5\uff1a

    import androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\n

    \u7136\u540e\u4fdd\u5b58\u5e76\u8fd0\u884c\u5b83...

    \u54ce\u5440\uff01\u6ca1\u6709\u6253\u5370\uff1f\u522b\u62c5\u5fc3\u3002\u53ea\u9700\u62c9\u4e0b\u901a\u77e5\u680f\uff0c\u60a8\u5c31\u4f1a\u770b\u5230\"QPython Program Output: hello1.py\"\u2014\u2014\u70b9\u51fb\u5b83\uff01

    \u5982\u60a8\u6240\u89c1\uff0cdroid.dialogGetInput() \u8fd4\u56de\u4e00\u4e2a\u5305\u542b\u4e09\u4e2a\u5b57\u6bb5\u7684 JSON \u5bf9\u8c61\u3002\u6211\u4eec\u53ea\u9700\u8981\u4e00\u4e2a\u2014\u2014result\uff0c\u5176\u4e2d\u5305\u542b\u7528\u6237\u5b9e\u9645\u8f93\u5165\u7684\u5185\u5bb9\u3002

    \u8ba9\u6211\u4eec\u6dfb\u52a0\u811a\u672c\u7684\u53cd\u5e94\uff1a

    import androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nmessage = f'Hello, {respond.result}!'\ndroid.makeToast(message)\n

    \u6700\u540e\u4e24\u884c\uff081\uff09\u683c\u5f0f\u5316\u6d88\u606f\uff0c\uff082\uff09\u4ee5 toast \u5f62\u5f0f\u5411\u7528\u6237\u663e\u793a\u6d88\u606f\u3002\u5982\u679c\u60a8\u4ecd\u7136\u4e0d\u77e5\u9053 f-string \u662f\u4ec0\u4e48\u610f\u601d\uff0c\u8bf7\u53c2\u9605 Python \u6587\u6863\u3002

    \u54c7\uff01\u5b83\u5de5\u4f5c\u4e86\uff01;)

    \u73b0\u5728\u6211\u8981\u5728\u90a3\u91cc\u6dfb\u52a0\u4e00\u4e9b\u903b\u8f91\u3002\u60f3\u4e00\u60f3\uff1a\u5982\u679c\u7528\u6237\u70b9\u51fb \u53d6\u6d88 \u6309\u94ae\uff0c\u6216\u8005\u70b9\u51fb \u786e\u5b9a \u4f46\u5c06\u8f93\u5165\u5b57\u6bb5\u7559\u7a7a\uff0c\u4f1a\u53d1\u751f\u4ec0\u4e48\uff1f

    \u60a8\u53ef\u4ee5\u73a9\u8fd9\u4e2a\u7a0b\u5e8f\uff0c\u68c0\u67e5 respond \u53d8\u91cf\u5728\u6bcf\u79cd\u60c5\u51b5\u4e0b\u5305\u542b\u4ec0\u4e48\u3002

    \u9996\u5148\uff0c\u6211\u60f3\u5c06\u7528\u6237\u8f93\u5165\u7684\u6587\u672c\u653e\u5165\u4e00\u4e2a\u5355\u72ec\u7684\u53d8\u91cf\u4e2d\uff1aname = respond.result\u3002\u7136\u540e\u6211\u68c0\u67e5\u5b83\uff0c\u5982\u679c\u5b83\u5305\u542b\u4efb\u4f55\u771f\u5b9e\u6587\u672c\uff0c\u5b83\u5c06\u88ab\u89c6\u4e3a\u540d\u79f0\u5e76\u7528\u4e8e\u95ee\u5019\u3002\u5426\u5219\uff0c\u5c06\u663e\u793a\u53e6\u4e00\u6761\u6d88\u606f\u3002\u5c06\u7b2c\u4e94\u884c message = f'Hello, {respond.result}!' \u66ff\u6362\u4e3a\u4ee5\u4e0b\u4ee3\u7801\uff1a

    name = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\n

    \u4f7f\u7528\u5de5\u5177\u680f\u4e0a\u7684 < \u548c > \u6309\u94ae\u6765\u7f29\u8fdb/\u53d6\u6d88\u7f29\u8fdb if \u8bed\u53e5\u4e2d\u7684\u884c\uff08\u6216\u8005\u53ea\u9700\u4f7f\u7528\u7a7a\u683c/\u9000\u683c\u952e\uff09\u3002\u60a8\u53ef\u4ee5\u5728 \u6b64\u5904 \u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u7f29\u8fdb\u7684\u5185\u5bb9\uff1bif \u8bed\u53e5\u5728 \u6b64\u5904 \u63cf\u8ff0\u3002

    \u9996\u5148\uff0c\u6211\u4eec\u5c06\u7528\u6237\u8f93\u5165\u653e\u5165 name \u53d8\u91cf\u3002\u7136\u540e\u6211\u4eec\u68c0\u67e5 name \u662f\u5426\u5305\u542b\u4efb\u4f55\u5185\u5bb9\uff1f\u5982\u679c\u7528\u6237\u7559\u7a7a\u884c\u5e76\u70b9\u51fb \u786e\u5b9a\uff0c\u8fd4\u56de\u503c\u662f\u7a7a\u5b57\u7b26\u4e32 ''\u3002\u5982\u679c\u6309\u4e0b\u4e86 \u53d6\u6d88 \u6309\u94ae\uff0c\u8fd4\u56de\u503c\u662f None\u3002\u5728 if \u8bed\u53e5\u4e2d\uff0c\u4e24\u8005\u90fd\u88ab\u89c6\u4e3a\u5047\u3002\u56e0\u6b64\uff0c\u53ea\u6709\u5f53 name \u5305\u542b\u4efb\u4f55\u6709\u610f\u4e49\u7684\u5185\u5bb9\u65f6\uff0cthen \u8bed\u53e5\u624d\u4f1a\u6267\u884c\uff0c\u5e76\u663e\u793a\u95ee\u5019\u8bed\"Hello, ...!\"\u3002\u5982\u679c\u8f93\u5165\u4e3a\u7a7a\uff0c\u7528\u6237\u5c06\u770b\u5230\"Hey! And you're not very polite, %Username%!\"\u6d88\u606f\u3002

    \u597d\u7684\uff0c\u8fd9\u662f\u6574\u4e2a\u7a0b\u5e8f\uff1a

    import androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nname = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\ndroid.makeToast(message)\n

    \u611f\u8c22 dmych \u5728\u4ed6\u7684\u535a\u5ba2\u4e0a\u63d0\u4f9b\u7b2c\u4e00\u4e2a\u8349\u7a3f

    "},{"location":"whats-new/","title":"\u66f4\u65b0\u65e5\u5fd7","text":""},{"location":"whats-new/#v392-v393","title":"v3.9.2 / v3.9.3","text":"
    • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
    • \u7f16\u8f91\u5668\u91cd\u5927\u66f4\u65b0\uff0c\u5e26\u6765\u66f4\u6d41\u7545\u7684\u7f16\u8f91\u4f53\u9a8c
    • \u5176\u4ed6\u5404\u79cd\u5c0f\u6539\u8fdb
    "},{"location":"whats-new/#v391","title":"v3.9.1","text":"
    • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
    • \u6269\u5c55\u5305\u73b0\u5728\u652f\u6301 MCP
    • \u9519\u8bef\u4fee\u590d
    "},{"location":"whats-new/#v390","title":"v3.9.0","text":"
    • SDK \u5347\u7ea7\uff0c\u6574\u5408\u6700\u65b0\u7684 Android \u529f\u80fd
    • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
    • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
    • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
    "},{"location":"whats-new/#v3811","title":"v3.8.11","text":"
    • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
    • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
    • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
    "},{"location":"whats-new/#v3810","title":"v3.8.10","text":"
    • \u5185\u7f6e Ollama \u5347\u7ea7\uff1a\u73b0\u5728\u60a8\u53ef\u4ee5\u5728 QPython \u4e2d\u8f7b\u677e\u672c\u5730\u8fd0\u884c Qwen3 / Gemma3 \u6a21\u578b\uff01
    • \u6dfb\u52a0\u4e86\u5f3a\u5927\u7684 MCP \u5e93\uff1a\u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 mcp \u5e93\uff0c\u8ba9\u60a8\u968f\u65f6\u968f\u5730\u643a\u5e26\u5f3a\u5927\u7684 MCP \u529f\u80fd\uff01
    "},{"location":"whats-new/#v389","title":"v3.8.9","text":"

    \u91cd\u5927\u66f4\u65b0\uff01AI \u7f16\u7a0b\u5b8c\u5168\u96c6\u6210\u5230 QPython\uff0c\u8ba9\u60a8\u7684\u7f16\u7a0b\u66f4\u8f7b\u677e\uff01

    • \u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u652f\u6301\uff1a\u65b0\u652f\u6301 AIPyApp\uff0c\u5728 QPython \u4e2d\u5b9e\u73b0\u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u3002\u76ee\u524d\u5904\u4e8e\u6d4b\u8bd5\u9636\u6bb5 - \u52a0\u5165\u6211\u4eec\u7684\u793e\u533a\u83b7\u53d6\u4f7f\u7528\u8bf4\u660e
    • \u65b0 QSL4A \u529f\u80fd\uff1a\u6dfb\u52a0 notebookOpen \u51fd\u6570\uff0c\u652f\u6301\u81ea\u7136\u8bed\u8a00\u63a7\u5236\u6253\u5f00 Notebook \u6587\u4ef6
    • \u5185\u7f6e\u7f16\u8f91\u5668\u5347\u7ea7\uff1a\u589e\u5f3a\u7f16\u8f91\u5668\u529f\u80fd\uff0c\u652f\u6301\u6253\u5f00\u548c\u6d4f\u89c8\u5404\u79cd\u6587\u672c\u6587\u4ef6
    • \u4fbf\u6377\u7684\u6587\u4ef6\u7ba1\u7406\uff1a\u5728\u6587\u4ef6\u7ba1\u7406\u5668\u4e2d\u6dfb\u52a0\u5185\u90e8\u5b58\u50a8\u5165\u53e3\uff0c\u5feb\u901f\u8bbf\u95ee\u60a8\u7684\u6587\u4ef6
    "},{"location":"whats-new/#v388","title":"v3.8.8","text":"
    • \u6587\u4ef6\u8bbf\u95ee\u6743\u9650\u63a7\u5236\u7684\u91cd\u8981\u6539\u8fdb\uff0c\u5141\u8bb8\u7528\u6237\u7075\u6d3b\u5730\u901a\u8fc7 QPython \u7f16\u7a0b\u542f\u7528\u6216\u7981\u7528\u5916\u90e8\u5b58\u50a8\u6587\u4ef6\u7684\u8bbf\u95ee
    • SDK \u5347\u7ea7\uff0c\u589e\u5f3a\u4e86\u5bf9\u65b0\u7248 Android \u7684\u652f\u6301\u548c\u517c\u5bb9\u6027
    • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Anthropic \u548c Google GenAI \u5e93
    "},{"location":"whats-new/#v387","title":"v3.8.7","text":"
    • \u5728\u73b0\u6709 Tkinter \u652f\u6301\u57fa\u7840\u4e0a\uff0c\u5728 Extensions -> Tools \u4e2d\u6dfb\u52a0\u4e86\u4f7f\u7528 Turtle \u7ed8\u5236\u54c6\u5566A\u68a6\u7684\u793a\u4f8b\u4ee3\u7801
    • \u4f18\u5316\u4e86\u624b\u673a\u6743\u9650\u83b7\u53d6\u6d41\u7a0b\uff0c\u63d0\u5347\u7528\u6237\u4f53\u9a8c\u548c\u64cd\u4f5c\u4fbf\u5229\u6027
    • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Google Gen AI \u5e93\uff0c\u65b9\u4fbf\u8bbf\u95ee Gemini Developer API \u548c Vertex AI
    "},{"location":"whats-new/#v386","title":"v3.8.6","text":"
    • Tkinter \u652f\u6301\uff1a\u73b0\u5728\u652f\u6301 Tkinter \u5e93\uff0c\u53ef\u901a\u8fc7 XServer \u8bbf\u95ee\u3002\u8bf7\u8bbf\u95ee www.qpython.org \u7684\u4e91\u76d8\"Extra\"\u94fe\u63a5\u4e0b\u8f7d\u6240\u9700\u6587\u4ef6
    • \u5b58\u50a8\u6743\u9650\u66f4\u65b0\uff1a\u4e3a\u6539\u5584\u7528\u6237\u4f53\u9a8c\uff0c\u6211\u4eec\u6dfb\u52a0\u4e86\u8bfb\u53d6\u624b\u673a\u5b58\u50a8\u7684\u6743\u9650\uff0c\u7528\u4e8e\u8bbf\u95ee\u5b58\u50a8\u5728\u5176\u4ed6\u76ee\u5f55\u4e2d\u7684 Python \u7a0b\u5e8f

    \u6b64\u66f4\u65b0\u540e\uff0cQPython \u548c QPythonPlus\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff0c\u4e13\u4e3a\u9700\u8981\u66f4\u591a\u654f\u611f\u6743\u9650\u7684\u9ad8\u7ea7\u7528\u6237\u8bbe\u8ba1\uff09\u5c06\u4fdd\u6301\u540c\u6b65\u7684\u7248\u672c\u53f7\u3002

    "},{"location":"whats-new/#v352-2025225","title":"v3.5.2 (2025/2/25)","text":"

    \u4e0e\u5f00\u6e90 LLM \u90e8\u7f72\u5de5\u5177 Ollama \u4ee5\u53ca DeepSeek \u5f00\u53d1\u7684 DeepSeek \u5b9e\u73b0\u65e0\u7f1d\u96c6\u6210\uff01

    \u529f\u80fd\uff1a - \u96f6\u95e8\u69db\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5404\u79cd\u5927\u578b\u8bed\u8a00\u6a21\u578b - \u5feb\u901f\u90e8\u7f72 DeepSeek \u7b49\u5c16\u7aef AI \u6a21\u578b - \u4eab\u53d7\u7b80\u7ea6\u7684 API \u8c03\u7528\u4f53\u9a8c - \u6784\u5efa\u5b8c\u5168\u79bb\u7ebf\u7684\u667a\u80fd\u7f16\u7a0b\u73af\u5883

    \u80fd\u529b\uff1a - \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u52a0\u8f7d/\u7ba1\u7406 LLM \u6a21\u578b - \u57fa\u4e8e\u672c\u5730\u8ba1\u7b97\u7684\u5b9e\u65f6\u4f4e\u5ef6\u8fdf\u54cd\u5e94

    "},{"location":"whats-new/#v350","title":"v3.5.0","text":"
    • Python \u5347\u7ea7\u5230 3.12.8
    • \u6539\u8fdb\u4eea\u8868\u76d8\uff0c\u529f\u80fd\u66f4\u6e05\u6670\u3001\u66f4\u4eba\u6027\u5316
    • \u6dfb\u52a0\u4e86\u4f17\u591a\u7b2c\u4e09\u65b9\u5305\uff1aPyTorch / Twisted / Scrapy / FastAPI ...
    "},{"location":"whats-new/#v338","title":"v3.3.8","text":"
    • \u4fee\u590d\u4e86 NumPy \u517c\u5bb9\u6027\u95ee\u9898
    "},{"location":"whats-new/#v335","title":"v3.3.5","text":"
    • \u5347\u7ea7 Python \u5185\u6838\u5230 3.11.9
    • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u4e0d\u663e\u793a\u6a21\u5757\u5b89\u88c5\u72b6\u6001\u7684 bug
    • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u5220\u9664\u6a21\u5757\u5931\u8d25\u7684 bug
    • \u4fee\u590d\u4e86\u5176\u4ed6 bug
    "},{"location":"whats-new/#v334","title":"v3.3.4","text":"
    • \u6dfb\u52a0\u4e86 OpenAI/Langchain/APIGPTCloud AI \u5305
    • \u79fb\u9664\u4e0d\u5fc5\u8981\u7684\u6587\u4ef6\u4ee5\u51cf\u5c11\u5927\u5c0f
    "},{"location":"whats-new/#v325","title":"v3.2.5","text":"
    • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570
    • \u5176\u4ed6\u9519\u8bef\u4fee\u590d
    "},{"location":"whats-new/#v323","title":"v3.2.3","text":"
    • \u66f4\u65b0 Python \u7248\u672c\u5230 3.11.0
    • \u66f4\u65b0 IPython \u7248\u672c\u5230 8.6.0
    • \u66f4\u65b0 pip \u7248\u672c\u5230 22.3.1
    • \u66f4\u65b0\u79d1\u5b66\u8ba1\u7b97\u5305\uff0c\u81ea\u52a8\u8f6f\u94fe\u63a5
    • \u51cf\u5c11\u7a7a\u95f4\u4f7f\u7528
    • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570 + \u5176\u4ed6\u9519\u8bef\u4fee\u590d
    "},{"location":"whats-new/#v318","title":"v3.1.8","text":"
    • \u5728\u7ec8\u7aef\u4e2d\u6dfb\u52a0\u4e86\u64cd\u4f5c\u70ed\u952e
    • \u4fee\u590d\u4e86\u7f16\u8f91\u5668\u5728\u65cb\u8f6c\u65f6\u4e22\u5931\u5185\u5bb9\u7684\u95ee\u9898
    • \u4fee\u590d\u4e86\u5176\u4ed6 bug

    \u5728 Google Play \u4e0b\u8f7d

    "},{"location":"qsl4a/","title":"QSL4A\uff08Android \u811a\u672c\u5c42\uff09API \u6587\u6863","text":"

    QSL4A \u662f QPython \u7684 Android \u811a\u672c\u5c42\uff0c\u5141\u8bb8\u60a8\u4f7f\u7528 Python \u63a7\u5236 Android \u8bbe\u5907\u529f\u80fd\u3002

    "},{"location":"qsl4a/#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a toast \u6d88\u606f\ndroid.makeToast('Hello QPython!')\n\n# \u9707\u52a8\u8bbe\u5907\ndroid.vibrate(500)\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\uff08\u5148\u5f00\u59cb\u76d1\u63a7\uff09\nimport time\ndroid.batteryStartMonitoring()\ntime.sleep(0.5)  # \u7b49\u5f85\u6570\u636e\nbattery = droid.readBatteryData().result\nprint(f\"\u7535\u6c60\uff1a{battery['level']}%\")\n
    "},{"location":"qsl4a/#_2","title":"\u6587\u6863\u7ed3\u6784","text":""},{"location":"qsl4a/#_3","title":"\u6838\u5fc3\u6a21\u5757","text":"
    • Android \u57fa\u7840 - \u6838\u5fc3\u8fde\u63a5\u548c RPC
    • Intent \u7cfb\u7edf - Android Intent \u64cd\u4f5c
    • \u4e8b\u4ef6\u7cfb\u7edf - \u4e8b\u4ef6\u5904\u7406\u548c\u5e7f\u64ad
    "},{"location":"qsl4a/#ui","title":"UI \u7ec4\u4ef6","text":"
    • \u5bf9\u8bdd\u6846 - \u8b66\u62a5\u3001\u8f93\u5165\u3001\u9009\u62e9\u5bf9\u8bdd\u6846
    • \u5168\u5c4f UI - \u81ea\u5b9a\u4e49\u5e03\u5c40 UI
    • \u60ac\u6d6e\u7a97 - \u60ac\u6d6e\u7a97\u53e3
    • \u8f85\u52a9\u529f\u80fd - \u5c4f\u5e55\u81ea\u52a8\u5316
    "},{"location":"qsl4a/#_4","title":"\u7cfb\u7edf","text":"
    • \u7535\u6c60 - \u7535\u6c60\u76d1\u63a7
    • \u4f20\u611f\u5668 - \u8bbe\u5907\u4f20\u611f\u5668
    • \u5e94\u7528 - \u5e94\u7528\u7ba1\u7406
    • \u7cfb\u7edf\u4fe1\u606f - \u8bbe\u5907\u4fe1\u606f
    • \u8bbe\u7f6e - \u7cfb\u7edf\u8bbe\u7f6e
    • \u5524\u9192\u9501 - \u5524\u9192\u9501\u63a7\u5236
    • QPython \u63a5\u53e3 - \u811a\u672c\u6267\u884c
    • Activity \u7ed3\u679c - Activity \u7ed3\u679c\u5904\u7406
    "},{"location":"qsl4a/#_5","title":"\u786c\u4ef6","text":"
    • \u84dd\u7259 - \u84dd\u7259\u64cd\u4f5c
    • \u76f8\u673a - \u62cd\u7167\u548c\u5f55\u50cf
    • \u97f3\u9891/\u5f55\u97f3\u5668 - \u5f55\u97f3
    • \u7f51\u7edc\u6444\u50cf\u5934 - MJPEG \u6d41
    • USB \u4e32\u53e3 - USB \u4e3b\u673a\u4e32\u53e3
    "},{"location":"qsl4a/#_6","title":"\u8fde\u63a5","text":"
    • WiFi - WiFi \u64cd\u4f5c
    • \u4f4d\u7f6e - GPS \u548c\u4f4d\u7f6e
    • \u77ed\u4fe1 - \u77ed\u4fe1\u64cd\u4f5c
    • \u7535\u8bdd - \u6253\u7535\u8bdd\u548c\u6765\u7535\u4fe1\u606f
    • \u8054\u7cfb\u4eba - \u8054\u7cfb\u4eba\u7ba1\u7406
    • \u4fe1\u53f7\u5f3a\u5ea6 - \u4fe1\u53f7\u76d1\u63a7
    • FTP \u670d\u52a1\u5668 - \u5185\u7f6e FTP \u670d\u52a1\u5668
    "},{"location":"qsl4a/#_7","title":"\u5b58\u50a8","text":"
    • DocumentFile - \u6587\u4ef6\u64cd\u4f5c
    • \u526a\u8d34\u677f - \u526a\u8d34\u677f\u64cd\u4f5c
    • \u504f\u597d\u8bbe\u7f6e - \u5171\u4eab\u504f\u597d\u8bbe\u7f6e
    "},{"location":"qsl4a/#_8","title":"\u5a92\u4f53","text":"
    • \u5a92\u4f53\u64ad\u653e\u5668 - \u97f3\u9891/\u89c6\u9891\u64ad\u653e
    • \u56fe\u50cf\u5904\u7406 - \u56fe\u50cf\u64cd\u4f5c
    "},{"location":"qsl4a/#_9","title":"\u7279\u6b8a\u529f\u80fd","text":"
    • \u52a0\u5bc6 - \u52a0\u5bc6/\u89e3\u5bc6
    • PGPT AI - AI \u8bed\u97f3\u670d\u52a1
    "},{"location":"qsl4a/#_10","title":"\u7ed3\u679c\u5bf9\u8c61","text":"

    \u5927\u591a\u6570 QSL4A \u65b9\u6cd5\u8fd4\u56de\u4e00\u4e2a\u5e26\u6709\u4ee5\u4e0b\u5c5e\u6027\u7684 Result \u547d\u540d\u5143\u7ec4\uff1a - id - \u8bf7\u6c42 ID - result - \u5b9e\u9645\u7ed3\u679c\u6570\u636e - error - \u5982\u679c\u5931\u8d25\u5219\u4e3a\u9519\u8bef\u6d88\u606f

    result = droid.getClipboard()\nif result.error is None:\n    print(result.result)\nelse:\n    print(f\"\u9519\u8bef\uff1a{result.error}\")\n
    "},{"location":"qsl4a/connectivity/contacts/","title":"\u8054\u7cfb\u4eba API","text":"

    \u8bbf\u95ee\u548c\u7ba1\u7406\u8bbe\u5907\u8054\u7cfb\u4eba\u3002

    "},{"location":"qsl4a/connectivity/contacts/#_1","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":""},{"location":"qsl4a/connectivity/contacts/#pickcontact","title":"pickContact()","text":"

    \u663e\u793a\u8054\u7cfb\u4eba\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

    pickContact()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u8054\u7cfb\u4eba URI \u7684 Intent

    "},{"location":"qsl4a/connectivity/contacts/#pickphone","title":"pickPhone()","text":"

    \u663e\u793a\u7535\u8bdd\u53f7\u7801\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

    pickPhone()\n

    \u8fd4\u56de\uff1a \u9009\u4e2d\u7684\u7535\u8bdd\u53f7\u7801\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/connectivity/contacts/#_2","title":"\u8054\u7cfb\u4eba\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#contactsget","title":"contactsGet()","text":"

    \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\u3002

    contactsGet(attributes=None)\n

    \u53c2\u6570\uff1a - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

    \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba JSONObject \u5217\u8868

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetbyid","title":"contactsGetById()","text":"

    \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\u3002

    contactsGetById(id, attributes=None)\n

    \u53c2\u6570\uff1a - id (int): \u8054\u7cfb\u4eba ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

    \u8fd4\u56de\uff1a JSONObject \u8054\u7cfb\u4eba\u6570\u636e

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetcount","title":"contactsGetCount()","text":"

    \u83b7\u53d6\u8054\u7cfb\u4eba\u603b\u6570\u3002

    contactsGetCount()\n

    \u8fd4\u56de\uff1a \u6574\u6570\u8ba1\u6570

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetids","title":"contactsGetIds()","text":"

    \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba ID\u3002

    contactsGetIds()\n

    \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba ID \u6574\u6570\u5217\u8868

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetattributes","title":"contactsGetAttributes()","text":"

    \u83b7\u53d6\u6240\u6709\u53ef\u80fd\u7684\u8054\u7cfb\u4eba\u5c5e\u6027\u3002

    contactsGetAttributes()\n

    \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u5217\u8868

    "},{"location":"qsl4a/connectivity/contacts/#_3","title":"\u5185\u5bb9\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#querycontent","title":"queryContent()","text":"

    \u4f7f\u7528\u81ea\u5b9a\u4e49\u53c2\u6570\u67e5\u8be2\u5185\u5bb9\u89e3\u6790\u5668\u3002

    queryContent(uri, attributes=None, selection=None, selectionArgs=None, order=None)\n

    \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u5c5e\u6027 - selection (str, optional): WHERE \u5b50\u53e5 - selectionArgs (list, optional): \u9009\u62e9\u53c2\u6570 - order (str, optional): ORDER BY \u5b50\u53e5

    \u8fd4\u56de\uff1a JSONObject \u7ed3\u679c\u5217\u8868

    "},{"location":"qsl4a/connectivity/contacts/#queryattributes","title":"queryAttributes()","text":"

    \u83b7\u53d6\u5185\u5bb9 URI \u7684\u5c5e\u6027\u3002

    queryAttributes(uri)\n

    \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI

    \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u7684 JSONArray

    "},{"location":"qsl4a/connectivity/contacts/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u9009\u62e9\u8054\u7cfb\u4eba\ncontact_uri = droid.pickContact().result\nprint(f\"Selected contact: {contact_uri}\")\n\n# \u9009\u62e9\u7535\u8bdd\u53f7\u7801\nphone = droid.pickPhone().result\nprint(f\"Selected phone: {phone}\")\n\n# \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\ncontacts = droid.contactsGet().result\nprint(f\"Total contacts: {len(contacts)}\")\n\n# \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\ncontact = droid.contactsGetById(1).result\nprint(f\"Contact: {contact}\")\n\n# \u83b7\u53d6\u8054\u7cfb\u4eba\u5c5e\u6027\nattrs = droid.contactsGetAttributes().result\nprint(f\"Available attributes: {attrs}\")\n
    "},{"location":"qsl4a/connectivity/ftp/","title":"FTP \u670d\u52a1\u5668 API","text":"

    \u5728\u8bbe\u5907\u4e0a\u542f\u52a8\u548c\u7ba1\u7406\u5185\u7f6e FTP \u670d\u52a1\u5668\u3002

    "},{"location":"qsl4a/connectivity/ftp/#ftp","title":"FTP \u670d\u52a1\u5668\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/ftp/#ftpstart","title":"ftpStart()","text":"

    \u542f\u52a8 FTP \u670d\u52a1\u5668\u3002

    ftpStart()\n

    \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4 [ip, port]

    "},{"location":"qsl4a/connectivity/ftp/#ftpstop","title":"ftpStop()","text":"

    \u505c\u6b62 FTP \u670d\u52a1\u5668\u3002

    ftpStop()\n
    "},{"location":"qsl4a/connectivity/ftp/#ftpisrunning","title":"ftpIsRunning()","text":"

    \u68c0\u67e5 FTP \u670d\u52a1\u5668\u662f\u5426\u6b63\u5728\u8fd0\u884c\u3002

    ftpIsRunning()\n

    \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u8fd0\u884c\u5219\u4e3a True

    "},{"location":"qsl4a/connectivity/ftp/#ftpget","title":"ftpGet()","text":"

    \u83b7\u53d6 FTP \u670d\u52a1\u5668 IP \u5730\u5740\u3002

    ftpGet()\n

    \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4

    "},{"location":"qsl4a/connectivity/ftp/#ftpset","title":"ftpSet()","text":"

    \u914d\u7f6e FTP \u670d\u52a1\u5668\u8bbe\u7f6e\u3002

    ftpSet(port=None, rootDir=None, username=None, password=None)\n

    \u53c2\u6570\uff1a - port (int, optional): \u670d\u52a1\u5668\u7aef\u53e3 - rootDir (str, optional): \u8981\u670d\u52a1\u7684\u57fa\u7840\u76ee\u5f55 - username (str, optional): \u767b\u5f55\u7528\u6237\u540d - password (str, optional): \u767b\u5f55\u5bc6\u7801

    \u8fd4\u56de\uff1a \u5305\u542b\u5f53\u524d\u8bbe\u7f6e\u7684 JSONObject

    "},{"location":"qsl4a/connectivity/ftp/#ftpstatus","title":"ftpStatus()","text":"

    \u83b7\u53d6 FTP \u670d\u52a1\u5668\u72b6\u6001\u3002

    ftpStatus()\n

    \u8fd4\u56de\uff1a \u72b6\u6001\u63cf\u8ff0\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/connectivity/ftp/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u914d\u7f6e FTP \u670d\u52a1\u5668\ndroid.ftpSet(\n    port=2121,\n    rootDir=\"/sdcard\",\n    username=\"admin\",\n    password=\"secret\"\n)\n\n# \u542f\u52a8 FTP \u670d\u52a1\u5668\ninfo = droid.ftpStart().result\nprint(f\"FTP running at {info[0]}:{info[1]}\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.ftpIsRunning().result:\n    print(\"FTP server is running\")\n\n# \u83b7\u53d6\u670d\u52a1\u5668\u4fe1\u606f\nserver_info = droid.ftpGet().result\nprint(f\"Server: {server_info}\")\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.ftpStop()\n

    \u6ce8\u610f\uff1a \u4f7f\u7528\u63d0\u4f9b\u7684\u51ed\u636e\u901a\u8fc7\u4efb\u4f55 FTP \u5ba2\u6237\u7aef\u8fde\u63a5\u5230 FTP \u670d\u52a1\u5668\u3002

    "},{"location":"qsl4a/connectivity/location/","title":"\u4f4d\u7f6e API","text":"

    \u8bbf\u95ee GPS \u548c\u7f51\u7edc\u4f4d\u7f6e\u670d\u52a1\u3002

    "},{"location":"qsl4a/connectivity/location/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/location/#startlocating","title":"startLocating()","text":"

    \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\u3002

    startLocating(minUpdateTime=60000, minUpdateDistance=30, updateGnssStatus=False)\n

    \u53c2\u6570\uff1a - minUpdateTime (int): \u66f4\u65b0\u4e4b\u95f4\u7684\u6700\u5c0f\u65f6\u95f4\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a60000\uff09 - minUpdateDistance (float): \u66f4\u65b0\u7684\u6700\u5c0f\u8ddd\u79bb\uff08\u7c73\uff09\uff08\u9ed8\u8ba4\uff1a30\uff09 - updateGnssStatus (bool): \u542f\u7528 GNSS \u72b6\u6001\u66f4\u65b0\uff08\u9ed8\u8ba4\uff1aFalse\uff09

    "},{"location":"qsl4a/connectivity/location/#stoplocating","title":"stopLocating()","text":"

    \u505c\u6b62\u4f4d\u7f6e\u66f4\u65b0\u3002

    stopLocating()\n
    "},{"location":"qsl4a/connectivity/location/#readlocation","title":"readLocation()","text":"

    \u83b7\u53d6\u6700\u540e\u5df2\u77e5\u4f4d\u7f6e\u3002

    readLocation()\n

    \u8fd4\u56de\uff1a \u4f4d\u7f6e\u6570\u636e\u5b57\u5178

    "},{"location":"qsl4a/connectivity/location/#getlastknownlocation","title":"getLastKnownLocation()","text":"

    \u83b7\u53d6\u7f13\u5b58\u7684\u4f4d\u7f6e\u3002

    getLastKnownLocation()\n

    \u8fd4\u56de\uff1a \u6765\u81ea\u6240\u6709\u63d0\u4f9b\u5546\u7684\u4f4d\u7f6e

    "},{"location":"qsl4a/connectivity/location/#geocode","title":"geocode()","text":"

    \u5c06\u5730\u5740\u8f6c\u6362\u4e3a\u5750\u6807\u3002

    geocode(address, maxResults=1)\n
    "},{"location":"qsl4a/connectivity/location/#_2","title":"\u4f4d\u7f6e\u63d0\u4f9b\u5546\u65b9\u6cd5)","text":""},{"location":"qsl4a/connectivity/location/#locationproviders","title":"locationProviders()","text":"

    \u83b7\u53d6\u624b\u673a\u4e0a\u53ef\u7528\u7684\u4f4d\u7f6e\u63d0\u4f9b\u5546\u3002

    locationProviders()\n

    \u8fd4\u56de\uff1a \u53ef\u7528\u63d0\u4f9b\u5546\u540d\u79f0\u5217\u8868\uff08\u4f8b\u5982 ['gps', 'network']\uff09

    "},{"location":"qsl4a/connectivity/location/#locationproviderenabled","title":"locationProviderEnabled()","text":"

    \u68c0\u67e5\u7279\u5b9a\u4f4d\u7f6e\u63d0\u4f9b\u5546\u662f\u5426\u5df2\u542f\u7528\u3002

    locationProviderEnabled(provider)\n

    \u53c2\u6570\uff1a - provider (str): \u63d0\u4f9b\u5546\u540d\u79f0\uff08\u4f8b\u5982 'gps', 'network'\uff09

    \u8fd4\u56de\uff1a \u5982\u679c\u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

    "},{"location":"qsl4a/connectivity/location/#readgnssstatus","title":"readGnssStatus()","text":"

    \u8bfb\u53d6\u5168\u7403\u5bfc\u822a\u536b\u661f\u7cfb\u7edf\u72b6\u6001\uff08\u9700\u8981 Android 8+\uff09\u3002

    readGnssStatus()\n

    \u8fd4\u56de\uff1a \u5305\u542b GNSS \u536b\u661f\u4fe1\u606f\u7684 JSONArray

    "},{"location":"qsl4a/connectivity/location/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\ndroid.startLocating(minUpdateTime=5000, minUpdateDistance=1, updateGnssStatus=False)\n\n# \u7b49\u5f85\u5b9a\u4f4d\ntime.sleep(10)\n\n# \u83b7\u53d6\u4f4d\u7f6e\nloc = droid.readLocation().result\nif loc:\n    lat = loc['latitude']\n    lon = loc['longitude']\n    print(f\"Location: {lat}, {lon}\")\n\ndroid.stopLocating()\n
    "},{"location":"qsl4a/connectivity/phone/","title":"\u7535\u8bdd API","text":"

    \u63a7\u5236\u7535\u8bdd\u901a\u8bdd\u548c\u83b7\u53d6\u7535\u8bdd\u4fe1\u606f\u3002

    "},{"location":"qsl4a/connectivity/phone/#_1","title":"\u7535\u8bdd\u72b6\u6001\u8ddf\u8e2a","text":""},{"location":"qsl4a/connectivity/phone/#starttrackingphonestate","title":"startTrackingPhoneState()","text":"

    \u5f00\u59cb\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u53d8\u5316\u3002\u751f\u6210 'phone' \u4e8b\u4ef6\u3002

    startTrackingPhoneState()\n
    "},{"location":"qsl4a/connectivity/phone/#readphonestate","title":"readPhoneState()","text":"

    \u8bfb\u53d6\u5f53\u524d\u7535\u8bdd\u72b6\u6001\u3002

    readPhoneState()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u7535\u8bdd\u72b6\u6001\u548c\u6765\u7535\u53f7\u7801\u7684 Bundle

    "},{"location":"qsl4a/connectivity/phone/#stoptrackingphonestate","title":"stopTrackingPhoneState()","text":"

    \u505c\u6b62\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u3002

    stopTrackingPhoneState()\n
    "},{"location":"qsl4a/connectivity/phone/#_2","title":"\u62e8\u6253\u7535\u8bdd","text":""},{"location":"qsl4a/connectivity/phone/#phonecall","title":"phoneCall()","text":"

    \u901a\u8fc7 URI \u547c\u53eb\u8054\u7cfb\u4eba/\u7535\u8bdd\u53f7\u7801\u3002

    phoneCall(uri)\n

    \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

    "},{"location":"qsl4a/connectivity/phone/#phonecallnumber","title":"phoneCallNumber()","text":"

    \u76f4\u63a5\u62e8\u6253\u7535\u8bdd\u53f7\u7801\u3002

    phoneCallNumber(phone_number)\n

    \u53c2\u6570\uff1a - phone_number (str): \u8981\u62e8\u6253\u7684\u7535\u8bdd\u53f7\u7801

    "},{"location":"qsl4a/connectivity/phone/#phonedial","title":"phoneDial()","text":"

    \u62e8\u6253\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

    phoneDial(uri)\n

    \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

    "},{"location":"qsl4a/connectivity/phone/#phonedialnumber","title":"phoneDialNumber()","text":"

    \u62e8\u6253\u7535\u8bdd\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

    phoneDialNumber(phone_number)\n

    \u53c2\u6570\uff1a - phone_number (str): \u7535\u8bdd\u53f7\u7801

    "},{"location":"qsl4a/connectivity/phone/#_3","title":"\u57fa\u7ad9\u4f4d\u7f6e","text":""},{"location":"qsl4a/connectivity/phone/#getcelllocation","title":"getCellLocation()","text":"

    \u83b7\u53d6\u5f53\u524d\u57fa\u7ad9\u4f4d\u7f6e\u3002

    getCellLocation()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u57fa\u7ad9\u4f4d\u7f6e\u6570\u636e\u7684 JSONObject

    "},{"location":"qsl4a/connectivity/phone/#getallcellslocation","title":"getAllCellsLocation()","text":"

    \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u4f4d\u7f6e\uff08\u9002\u7528\u4e8e\u53cc\u5361\u8bbe\u5907\uff09\u3002

    getAllCellsLocation()\n

    \u8fd4\u56de\uff1a \u57fa\u7ad9\u4f4d\u7f6e\u7684 JSONArray

    "},{"location":"qsl4a/connectivity/phone/#_4","title":"\u7f51\u7edc\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getnetworkoperator","title":"getNetworkOperator()","text":"

    \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

    getNetworkOperator()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

    "},{"location":"qsl4a/connectivity/phone/#getnetworkoperatorname","title":"getNetworkOperatorName()","text":"

    \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684\u540d\u79f0\u3002

    getNetworkOperatorName()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

    "},{"location":"qsl4a/connectivity/phone/#getnetworktype","title":"getNetworkType()","text":"

    \u83b7\u53d6\u5f53\u524d\u7f51\u7edc\u7c7b\u578b\u3002

    getNetworkType()\n

    \u8fd4\u56de\uff1a \u63cf\u8ff0\u65e0\u7ebf\u7535\u6280\u672f\u7684\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'LTE', 'UMTS', 'GSM'\uff09

    "},{"location":"qsl4a/connectivity/phone/#getphonetype","title":"getPhoneType()","text":"

    \u83b7\u53d6\u7535\u8bdd\u7c7b\u578b\u3002

    getPhoneType()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'GSM', 'CDMA', 'SIP'\uff09

    "},{"location":"qsl4a/connectivity/phone/#sim","title":"SIM \u5361\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getsimcountryiso","title":"getSimCountryIso()","text":"

    \u83b7\u53d6 SIM \u5361\u7684 ISO \u56fd\u5bb6\u4ee3\u7801\u3002

    getSimCountryIso()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'us'\uff09

    "},{"location":"qsl4a/connectivity/phone/#getsimoperator","title":"getSimOperator()","text":"

    \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

    getSimOperator()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

    "},{"location":"qsl4a/connectivity/phone/#getsimoperatorname","title":"getSimOperatorName()","text":"

    \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u540d\u79f0\u3002

    getSimOperatorName()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

    "},{"location":"qsl4a/connectivity/phone/#getsimserialnumber","title":"getSimSerialNumber()","text":"

    \u83b7\u53d6 SIM \u5e8f\u5217\u53f7\u3002

    getSimSerialNumber()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32 SIM \u5e8f\u5217\u53f7

    "},{"location":"qsl4a/connectivity/phone/#getsimstate","title":"getSimState()","text":"

    \u83b7\u53d6 SIM \u5361\u72b6\u6001\u3002

    getSimState()\n

    \u8fd4\u56de\uff1a \u63cf\u8ff0 SIM \u72b6\u6001\u7684\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/connectivity/phone/#getsubscriberid","title":"getSubscriberId()","text":"

    \u83b7\u53d6\u8ba2\u9605\u8005 ID\u3002

    getSubscriberId()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8ba2\u9605\u8005 ID

    "},{"location":"qsl4a/connectivity/phone/#_5","title":"\u8bed\u97f3\u90ae\u4ef6","text":""},{"location":"qsl4a/connectivity/phone/#getvoicemailalphatag","title":"getVoiceMailAlphaTag()","text":"

    \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u5b57\u6bcd\u6807\u7b7e\u3002

    getVoiceMailAlphaTag()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u6807\u7b7e

    "},{"location":"qsl4a/connectivity/phone/#getvoicemailnumber","title":"getVoiceMailNumber()","text":"

    \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801\u3002

    getVoiceMailNumber()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801

    "},{"location":"qsl4a/connectivity/phone/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getdeviceid","title":"getDeviceId()","text":"

    \u83b7\u53d6\u8bbe\u5907 ID\uff08GSM \u7684 IMEI\uff09\u3002\u5df2\u5e9f\u5f03\u3002

    getDeviceId()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

    "},{"location":"qsl4a/connectivity/phone/#getdevicesoftwareversion","title":"getDeviceSoftwareVersion()","text":"

    \u83b7\u53d6\u8bbe\u5907\u8f6f\u4ef6\u7248\u672c\u3002

    getDeviceSoftwareVersion()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8f6f\u4ef6\u7248\u672c

    "},{"location":"qsl4a/connectivity/phone/#getline1number","title":"getLine1Number()","text":"

    \u83b7\u53d6\u7ebf\u8def 1 \u7535\u8bdd\u53f7\u7801\u3002

    getLine1Number()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u7535\u8bdd\u53f7\u7801

    "},{"location":"qsl4a/connectivity/phone/#checknetworkroaming","title":"checkNetworkRoaming()","text":"

    \u68c0\u67e5\u662f\u5426\u8fde\u63a5\u5230\u6f2b\u6e38\u7f51\u7edc\u3002

    checkNetworkRoaming()\n

    \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u6f2b\u6e38\u5219\u4e3a True

    "},{"location":"qsl4a/connectivity/phone/#_7","title":"\u57fa\u7ad9\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getallcellinfo","title":"getAllCellInfo()","text":"

    \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u7684\u4fe1\u606f\u3002

    getAllCellInfo()\n

    \u8fd4\u56de\uff1a \u57fa\u7ad9\u4fe1\u606f\u5217\u8868

    "},{"location":"qsl4a/connectivity/phone/#setdataenabled","title":"setDataEnabled()","text":"

    \u542f\u7528\u6216\u7981\u7528\u79fb\u52a8\u6570\u636e\u3002

    setDataEnabled(enabled)\n

    \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528

    "},{"location":"qsl4a/connectivity/phone/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7f51\u7edc\u4fe1\u606f\noperator = droid.getNetworkOperatorName().result\nprint(f\"Operator: {operator}\")\n\nnetwork_type = droid.getNetworkType().result\nprint(f\"Network: {network_type}\")\n\n# \u83b7\u53d6 SIM \u4fe1\u606f\nsim_state = droid.getSimState().result\nprint(f\"SIM: {sim_state}\")\n\n# \u83b7\u53d6\u7535\u8bdd\u53f7\u7801\nline1 = droid.getLine1Number().result\nprint(f\"Phone: {line1}\")\n\n# \u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\ndroid.startTrackingPhoneState()\nprint(\"Tracking phone state...\")\ndroid.stopTrackingPhoneState()\n
    "},{"location":"qsl4a/connectivity/signalstrength/","title":"\u4fe1\u53f7\u5f3a\u5ea6 API","text":"

    \u76d1\u63a7\u8702\u7a9d\u548c\u65e0\u7ebf\u4fe1\u53f7\u5f3a\u5ea6\u3002

    "},{"location":"qsl4a/connectivity/signalstrength/#_1","title":"\u4fe1\u53f7\u5f3a\u5ea6\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/signalstrength/#starttrackingsignalstrengths","title":"startTrackingSignalStrengths()","text":"

    \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316\u3002\u751f\u6210 'signal_strengths' \u4e8b\u4ef6\u3002

    startTrackingSignalStrengths()\n
    "},{"location":"qsl4a/connectivity/signalstrength/#stoptrackingsignalstrengths","title":"stopTrackingSignalStrengths()","text":"

    \u505c\u6b62\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u3002

    stopTrackingSignalStrengths()\n
    "},{"location":"qsl4a/connectivity/signalstrength/#readsignalstrengths","title":"readSignalStrengths()","text":"

    \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\u3002

    readSignalStrengths()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u4fe1\u53f7\u5f3a\u5ea6\u6570\u636e\u7684 Bundle

    "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthlevel","title":"getTelephoneSignalStrengthLevel()","text":"

    \u83b7\u53d6\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u7b49\u7ea7\uff080-4\uff09\u3002

    getTelephoneSignalStrengthLevel()\n

    \u8fd4\u56de\uff1a \u6574\u6570\u7b49\u7ea7\uff080=\u65e0\uff0c1=\u5dee\uff0c2=\u4e00\u822c\uff0c3=\u597d\uff0c4=\u4f18\u79c0\uff09

    "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthdetail","title":"getTelephoneSignalStrengthDetail()","text":"

    \u83b7\u53d6\u8be6\u7ec6\u7684\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u4fe1\u606f\u3002

    getTelephoneSignalStrengthDetail()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u8be6\u7ec6\u4fe1\u53f7\u4fe1\u606f\u7684\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/connectivity/signalstrength/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\ndroid.startTrackingSignalStrengths()\n\n# \u7b49\u5f85\u4fe1\u53f7\u66f4\u65b0\ntime.sleep(5)\n\n# \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\nsignal = droid.readSignalStrengths().result\nprint(f\"Signal: {signal}\")\n\n# \u76f4\u63a5\u83b7\u53d6\u7b49\u7ea7\nlevel = droid.getTelephoneSignalStrengthLevel().result\nprint(f\"Signal level: {level}/4\")\n\ndroid.stopTrackingSignalStrengths()\n
    "},{"location":"qsl4a/connectivity/sms/","title":"SMS API","text":"

    \u53d1\u9001\u548c\u63a5\u6536 SMS \u6d88\u606f\u3002

    "},{"location":"qsl4a/connectivity/sms/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/sms/#smssend","title":"smsSend()","text":"

    \u53d1\u9001 SMS \u6d88\u606f\u3002

    smsSend(destinationAddress, text)\n

    \u53c2\u6570\uff1a - destinationAddress (str): \u7535\u8bdd\u53f7\u7801 - text (str): \u6d88\u606f\u6587\u672c

    "},{"location":"qsl4a/connectivity/sms/#smsgetmessagecount","title":"smsGetMessageCount()","text":"

    \u83b7\u53d6\u6d88\u606f\u6570\u91cf\u3002

    smsGetMessageCount(unreadOnly=False, folder=\"inbox\")\n
    "},{"location":"qsl4a/connectivity/sms/#smsgetmessageids","title":"smsGetMessageIds()","text":"

    \u83b7\u53d6\u6d88\u606f ID\u3002

    smsGetMessageIds(unreadOnly=False, folder=\"inbox\")\n
    "},{"location":"qsl4a/connectivity/sms/#smsgetmessages","title":"smsGetMessages()","text":"

    \u83b7\u53d6\u6d88\u606f\u8be6\u60c5\u3002

    smsGetMessages(unreadOnly=False, folder=\"inbox\", attributes=None)\n
    "},{"location":"qsl4a/connectivity/sms/#smsgetmessagebyid","title":"smsGetMessageById()","text":"

    \u901a\u8fc7 ID \u83b7\u53d6\u7279\u5b9a\u6d88\u606f\u3002

    smsGetMessageById(id, attributes=None)\n

    \u53c2\u6570\uff1a - id (int): \u6d88\u606f ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

    \u8fd4\u56de\uff1a \u6d88\u606f\u6570\u636e\u5b57\u5178

    "},{"location":"qsl4a/connectivity/sms/#smsgetattributes","title":"smsGetAttributes()","text":"

    \u83b7\u53d6\u53ef\u7528\u7684 SMS \u6d88\u606f\u5c5e\u6027\u3002

    smsGetAttributes()\n

    \u8fd4\u56de\uff1a \u53ef\u7528\u5c5e\u6027\u540d\u79f0\u5217\u8868

    "},{"location":"qsl4a/connectivity/sms/#smsdeletemessage","title":"smsDeleteMessage()","text":"

    \u5220\u9664\u6d88\u606f\u3002

    smsDeleteMessage(id)\n
    "},{"location":"qsl4a/connectivity/sms/#smsmarkmessageread","title":"smsMarkMessageRead()","text":"

    \u5c06\u6d88\u606f\u6807\u8bb0\u4e3a\u5df2\u8bfb\u3002

    smsMarkMessageRead(ids, read=True)\n
    "},{"location":"qsl4a/connectivity/sms/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u53d1\u9001 SMS\ndroid.smsSend(\"+1234567890\", \"Hello from QPython!\")\n\n# \u83b7\u53d6\u672a\u8bfb\u6d88\u606f\nmessages = droid.smsGetMessages(unreadOnly=True).result\nfor msg in messages:\n    print(f\"From: {msg['address']}, Text: {msg['body']}\")\n
    "},{"location":"qsl4a/connectivity/wifi/","title":"WiFi API","text":"

    \u63a7\u5236 WiFi \u9002\u914d\u5668\u5e76\u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\u3002

    "},{"location":"qsl4a/connectivity/wifi/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/connectivity/wifi/#checkwifistate","title":"checkWifiState()","text":"

    \u68c0\u67e5 WiFi \u662f\u5426\u5df2\u542f\u7528\u3002

    checkWifiState()\n

    \u8fd4\u56de\uff1a \u5982\u679c WiFi \u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

    "},{"location":"qsl4a/connectivity/wifi/#togglewifistate","title":"toggleWifiState()","text":"

    \u6253\u5f00\u6216\u5173\u95ed WiFi\u3002

    toggleWifiState(enabled=None)\n

    \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

    \u8fd4\u56de\uff1a \u5982\u679c\u64cd\u4f5c\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/connectivity/wifi/#wifistartscan","title":"wifiStartScan()","text":"

    \u5f00\u59cb\u626b\u63cf\u53ef\u7528\u7684 WiFi \u7f51\u7edc\u3002

    wifiStartScan()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifigetscanresults","title":"wifiGetScanResults()","text":"

    \u83b7\u53d6\u53d1\u73b0\u7684 WiFi \u7f51\u7edc\u5217\u8868\u3002

    wifiGetScanResults()\n

    \u8fd4\u56de\uff1a \u63a5\u5165\u70b9\u4fe1\u606f\u5217\u8868

    "},{"location":"qsl4a/connectivity/wifi/#_2","title":"\u8fde\u63a5\u7ba1\u7406","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetconnectioninfo","title":"wifiGetConnectionInfo()","text":"

    \u83b7\u53d6\u8be6\u7ec6\u8fde\u63a5\u4fe1\u606f\u3002

    wifiGetConnectionInfo()\n

    \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001IP \u5730\u5740\u7b49\u8fde\u63a5\u8be6\u60c5\u7684\u5b57\u5178

    "},{"location":"qsl4a/connectivity/wifi/#getconnectedinfo","title":"getConnectedInfo()","text":"

    \u83b7\u53d6\u8fde\u63a5\u7684 WiFi \u7f51\u7edc\u4fe1\u606f\uff08\u7b80\u5316\u7248\uff09\u3002

    getConnectedInfo()\n

    \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001\u4fe1\u53f7\u5f3a\u5ea6\u7684\u5b57\u5178

    "},{"location":"qsl4a/connectivity/wifi/#getdhcpinfo","title":"getDhcpInfo()","text":"

    \u83b7\u53d6\u5f53\u524d\u8fde\u63a5\u7684 DHCP \u4fe1\u606f\u3002

    getDhcpInfo(ipConvertToString=True)\n

    \u53c2\u6570\uff1a - ipConvertToString (bool): \u5c06 IP \u5730\u5740\u8f6c\u6362\u4e3a\u5b57\u7b26\u4e32\u683c\u5f0f\uff08\u9ed8\u8ba4\uff1aTrue\uff09

    \u8fd4\u56de\uff1a \u5305\u542b IP\u3001\u7f51\u5173\u3001DNS \u7b49 DHCP \u4fe1\u606f\u7684\u5b57\u5178

    "},{"location":"qsl4a/connectivity/wifi/#wifidisconnect","title":"wifiDisconnect()","text":"

    \u65ad\u5f00\u5f53\u524d WiFi \u7f51\u7edc\u8fde\u63a5\u3002

    wifiDisconnect()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifireconnect","title":"wifiReconnect()","text":"

    \u91cd\u65b0\u8fde\u63a5\u5230\u5f53\u524d\u7f51\u7edc\u3002

    wifiReconnect()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifireassociate","title":"wifiReassociate()","text":"

    \u91cd\u65b0\u5173\u8054\u5f53\u524d\u63a5\u5165\u70b9\u3002

    wifiReassociate()\n
    "},{"location":"qsl4a/connectivity/wifi/#_3","title":"\u70ed\u70b9","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetapstate","title":"wifiGetApState()","text":"

    \u83b7\u53d6 WiFi AP\uff08\u70ed\u70b9\uff09\u72b6\u6001\u3002

    wifiGetApState()\n

    \u8fd4\u56de\uff1a \u70ed\u70b9\u72b6\u6001

    "},{"location":"qsl4a/connectivity/wifi/#wifi","title":"WiFi \u9501","text":""},{"location":"qsl4a/connectivity/wifi/#wifilockacquirefull","title":"wifiLockAcquireFull()","text":"

    \u83b7\u53d6\u5b8c\u6574 WiFi \u9501\uff08\u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\u4e5f\u4fdd\u6301 WiFi \u6d3b\u52a8\uff09\u3002

    wifiLockAcquireFull()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifilockacquirescanonly","title":"wifiLockAcquireScanOnly()","text":"

    \u83b7\u53d6\u4ec5\u626b\u63cf WiFi \u9501\u3002

    wifiLockAcquireScanOnly()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifilockrelease","title":"wifiLockRelease()","text":"

    \u91ca\u653e WiFi \u9501\u3002

    wifiLockRelease()\n
    "},{"location":"qsl4a/connectivity/wifi/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u68c0\u67e5 WiFi \u72b6\u6001\nif droid.checkWifiState().result:\n    print(\"WiFi is enabled\")\nelse:\n    print(\"Enabling WiFi...\")\n    droid.toggleWifiState(True)\n    time.sleep(2)\n\n# \u5f00\u59cb\u626b\u63cf\ndroid.wifiStartScan()\ntime.sleep(3)\n\n# \u83b7\u53d6\u626b\u63cf\u7ed3\u679c\nnetworks = droid.wifiGetScanResults().result\nfor network in networks:\n    print(f\"SSID: {network.get('SSID')}, Signal: {network.get('level')} dBm\")\n\n# \u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\ninfo = droid.wifiGetConnectionInfo().result\nif info:\n    print(f\"Connected to: {info.get('ssid')}\")\n    print(f\"BSSID: {info.get('bssid')}\")\n    print(f\"IP: {info.get('ip_address')}\")\n\n# \u83b7\u53d6 DHCP \u4fe1\u606f\ndhcp = droid.getDhcpInfo().result\nif dhcp:\n    print(f\"Gateway: {dhcp.get('gateway')}\")\n    print(f\"DNS: {dhcp.get('dns1')}\")\n\n# \u83b7\u53d6\u7b80\u5316\u7684\u8fde\u63a5\u4fe1\u606f\nconnected = droid.getConnectedInfo().result\nprint(f\"SSID: {connected.get('ssid')}, Signal: {connected.get('level')} dBm\")\n\n# \u65ad\u5f00\u5e76\u91cd\u65b0\u8fde\u63a5\ndroid.wifiDisconnect()\ntime.sleep(1)\ndroid.wifiReconnect()\n\n# \u91cd\u65b0\u5173\u8054\u63a5\u5165\u70b9\ndroid.wifiReassociate()\n\n# \u68c0\u67e5\u70ed\u70b9\u72b6\u6001\nap_state = droid.wifiGetApState().result\nprint(f\"Hotspot state: {ap_state}\")\n\n# \u83b7\u53d6 WiFi \u9501\u4ee5\u8fdb\u884c\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireFull()\n# ... \u6267\u884c\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n\n# \u6216\u4f7f\u7528\u4ec5\u626b\u63cf\u9501\u4ee5\u8fdb\u884c\u8f83\u8f7b\u7684\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireScanOnly()\n# ... \u6267\u884c\u626b\u63cf\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n
    "},{"location":"qsl4a/core/android-base/","title":"Android \u57fa\u7840\u7c7b","text":"

    Android \u7c7b\u662f QSL4A \u7684\u6838\u5fc3\uff0c\u63d0\u4f9b\u4e86\u4e0e Android \u8fd0\u884c\u65f6\u7684\u8fde\u63a5\u548c RPC \u673a\u5236\u3002

    "},{"location":"qsl4a/core/android-base/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
    # \u529f\u80fd\u5b8c\u6574\u7248\u672c\uff08\u63a8\u8350\uff09\nimport androidhelper\ndroid = androidhelper.Android()\n\n# \u7b80\u5316\u7248\u672c\uff08\u5feb\u901f\uff0c\u5355\u5b9e\u4f8b\uff09\nimport android\ndroid = android.droid\n
    "},{"location":"qsl4a/core/android-base/#android_1","title":"\u7c7b\uff1aAndroid","text":""},{"location":"qsl4a/core/android-base/#_2","title":"\u6784\u9020\u51fd\u6570","text":"
    Android(addr=None)\n

    \u53c2\u6570\uff1a - addr (tuple, optional): (HOST, PORT) \u5730\u5740\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u73af\u5883\u53d8\u91cf AP_HOST \u548c AP_PORT

    \u73af\u5883\u53d8\u91cf\uff1a - AP_HOST - \u670d\u52a1\u5668\u4e3b\u673a\u5730\u5740 - AP_PORT - \u670d\u52a1\u5668\u7aef\u53e3 - AP_HANDSHAKE - \u8ba4\u8bc1\u4ee4\u724c

    "},{"location":"qsl4a/core/android-base/#_3","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/android-base/#_rpc","title":"_rpc()","text":"

    \u8c03\u7528 Android \u51fd\u6570\u7684\u5185\u90e8 RPC \u65b9\u6cd5\u3002

    _rpc(method, *args)\n

    \u53c2\u6570\uff1a - method (str): \u8981\u8c03\u7528\u7684\u65b9\u6cd5\u540d - *args: \u65b9\u6cd5\u7684\u53ef\u53d8\u53c2\u6570

    \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4\uff0c\u5305\u542b\u4ee5\u4e0b\u5b57\u6bb5\uff1a - id (int): \u8bf7\u6c42 ID - result: \u65b9\u6cd5\u8fd4\u56de\u503c - error (str or None): \u9519\u8bef\u4fe1\u606f\uff08\u5982\u679c\u5931\u8d25\uff09

    "},{"location":"qsl4a/core/android-base/#getattr","title":"getattr()","text":"

    \u52a8\u6001\u65b9\u6cd5\u5206\u53d1\u5668\u3002\u6240\u6709 Android \u65b9\u6cd5\u90fd\u901a\u8fc7\u5c5e\u6027\u67e5\u627e\u8bbf\u95ee\u3002

    # \u4ee5\u4e0b\u4e24\u79cd\u65b9\u5f0f\u7b49\u4ef7\uff1a\ndroid.makeToast(\"Hello\")\ndroid._rpc(\"makeToast\", \"Hello\")\n
    "},{"location":"qsl4a/core/android-base/#androidpy","title":"\u72ec\u7acb\u51fd\u6570\uff08android.py\uff09","text":"

    \u4f7f\u7528\u7b80\u5316\u7684 android \u6a21\u5757\u65f6\uff1a

    "},{"location":"qsl4a/core/android-base/#jsla","title":"jsla()","text":"

    \u53d1\u9001 JSON-RPC \u8bf7\u6c42\u5e76\u8fd4\u56de\u539f\u59cb\u54cd\u5e94\u3002

    jsla(method, *params)\n

    \u8fd4\u56de\uff1a JSON \u5b57\u7b26\u4e32\u54cd\u5e94

    "},{"location":"qsl4a/core/android-base/#rsla","title":"rsla()","text":"

    \u53d1\u9001\u8bf7\u6c42\u5e76\u4ec5\u8fd4\u56de\u7ed3\u679c\u3002

    rsla(method, *params)\n

    \u8fd4\u56de\uff1a RPC \u8c03\u7528\u7684\u7ed3\u679c\u503c

    "},{"location":"qsl4a/core/android-base/#esla","title":"esla()","text":"

    \u53d1\u9001\u8bf7\u6c42\uff0c\u9519\u8bef\u65f6\u629b\u51fa\u5f02\u5e38\u3002

    esla(method, *params)\n

    \u629b\u51fa\uff1a \u5982\u679c error \u5b57\u6bb5\u4e0d\u4e3a None \u5219\u629b\u51fa\u5f02\u5e38

    "},{"location":"qsl4a/core/android-base/#nsla","title":"nsla()","text":"

    \u53d1\u9001\u8bf7\u6c42\u5e76\u8fd4\u56de Result \u547d\u540d\u5143\u7ec4\u3002

    nsla(method, *params)\n

    \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4

    "},{"location":"qsl4a/core/android-base/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/android-base/#_5","title":"\u57fa\u672c\u8fde\u63a5","text":"
    import androidhelper\n\n# \u8fde\u63a5\u5230 Android \u8fd0\u884c\u65f6\ndroid = androidhelper.Android()\n\n# \u901a\u8fc7\u663e\u793a toast \u6765\u68c0\u67e5\u8fde\u63a5\ndroid.makeToast(\"Connected!\")\n
    "},{"location":"qsl4a/core/android-base/#_6","title":"\u9519\u8bef\u5904\u7406","text":"
    result = droid.someMethod()\nif result.error:\n    print(f\"Error: {result.error}\")\nelse:\n    print(f\"Success: {result.result}\")\n
    "},{"location":"qsl4a/core/android-base/#rpc","title":"\u76f4\u63a5 RPC \u8c03\u7528","text":"
    # \u76f4\u63a5\u8c03\u7528\u4efb\u610f\u65b9\u6cd5\nresult = droid._rpc(\"makeToast\", \"Hello World\")\n
    "},{"location":"qsl4a/core/events/","title":"\u4e8b\u4ef6\u7cfb\u7edf","text":"

    QSL4A \u63d0\u4f9b\u4e86\u4e00\u4e2a\u4e8b\u4ef6\u7cfb\u7edf\uff0c\u7528\u4e8e\u5904\u7406\u6765\u81ea Android \u7684\u5f02\u6b65\u4e8b\u4ef6\uff0c\u5982\u4f20\u611f\u5668\u66f4\u65b0\u3001\u4f4d\u7f6e\u53d8\u5316\u548c\u81ea\u5b9a\u4e49\u5e7f\u64ad\u3002

    "},{"location":"qsl4a/core/events/#_2","title":"\u4e8b\u4ef6\u57fa\u7840","text":"

    \u4e8b\u4ef6\u5b58\u50a8\u5728\u7f13\u51b2\u533a\u4e2d\uff0c\u53ef\u4ee5\u8f6e\u8be2\u6216\u7b49\u5f85\u3002\u6bcf\u4e2a\u4e8b\u4ef6\u5305\u542b\uff1a - name: \u4e8b\u4ef6\u7c7b\u578b/\u540d\u79f0 - data: \u4e8b\u4ef6\u8d1f\u8f7d\u6570\u636e - time: \u65f6\u95f4\u6233

    "},{"location":"qsl4a/core/events/#_3","title":"\u4e8b\u4ef6\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#eventclearbuffer","title":"eventClearBuffer()","text":"

    \u6e05\u9664\u7f13\u51b2\u533a\u4e2d\u7684\u6240\u6709\u5f85\u5904\u7406\u4e8b\u4ef6\u3002

    eventClearBuffer()\n

    \u8fd4\u56de\uff1a None

    "},{"location":"qsl4a/core/events/#eventpoll","title":"eventPoll()","text":"

    \u8f6e\u8be2\u7f13\u51b2\u533a\u4e2d\u7684\u4e8b\u4ef6\u3002

    eventPoll(number_of_events=1)\n

    \u53c2\u6570\uff1a - number_of_events (int): \u8981\u68c0\u7d22\u7684\u6700\u5927\u4e8b\u4ef6\u6570\uff08\u9ed8\u8ba4\uff1a1\uff09

    \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\u5217\u8868

    "},{"location":"qsl4a/core/events/#eventwait","title":"eventWait()","text":"

    \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\u3002

    eventWait(timeout=None)\n

    \u53c2\u6570\uff1a - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09\u3002None = \u6c38\u4e45\u7b49\u5f85

    \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

    "},{"location":"qsl4a/core/events/#eventwaitfor","title":"eventWaitFor()","text":"

    \u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6\u3002

    eventWaitFor(eventName, timeout=None)\n

    \u53c2\u6570\uff1a - eventName (str): \u8981\u7b49\u5f85\u7684\u4e8b\u4ef6\u540d\u79f0 - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

    \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

    "},{"location":"qsl4a/core/events/#eventpost","title":"eventPost()","text":"

    \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\u3002

    eventPost(name, data, enqueue=None)\n

    \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e\uff08\u4efb\u610f\u7c7b\u578b\uff09 - enqueue (bool, optional): \u5982\u679c\u4e3a True \u5219\u6dfb\u52a0\u5230\u961f\u5217

    "},{"location":"qsl4a/core/events/#receiveevent","title":"receiveEvent()","text":"

    \u63a5\u6536\u4e8b\u4ef6\uff08\u963b\u585e\uff09\u3002

    receiveEvent()\n

    \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61

    "},{"location":"qsl4a/core/events/#_4","title":"\u5e7f\u64ad\u4e8b\u4ef6","text":"

    \u6ce8\u518c\u7cfb\u7edf\u5e7f\u64ad\u4e8b\u4ef6\u3002

    "},{"location":"qsl4a/core/events/#eventregisterforbroadcast","title":"eventRegisterForBroadcast()","text":"

    \u6ce8\u518c\u63a5\u6536\u5e7f\u64ad\u4e8b\u4ef6\u3002

    eventRegisterForBroadcast(category, enqueue=True)\n

    \u53c2\u6570\uff1a - category (str): \u5e7f\u64ad\u7c7b\u522b/\u52a8\u4f5c - enqueue (bool): \u6dfb\u52a0\u5230\u4e8b\u4ef6\u961f\u5217

    "},{"location":"qsl4a/core/events/#eventunregisterforbroadcast","title":"eventUnregisterForBroadcast()","text":"

    \u53d6\u6d88\u6ce8\u518c\u5e7f\u64ad\u4e8b\u4ef6\u3002

    eventUnregisterForBroadcast(category)\n
    "},{"location":"qsl4a/core/events/#eventgetbrodcastcategories","title":"eventGetBrodcastCategories()","text":"

    \u83b7\u53d6\u5df2\u6ce8\u518c\u7684\u5e7f\u64ad\u7c7b\u522b\u3002

    eventGetBrodcastCategories()\n

    \u8fd4\u56de\uff1a \u5df2\u6ce8\u518c\u7c7b\u522b\u5217\u8868

    "},{"location":"qsl4a/core/events/#_5","title":"\u4e8b\u4ef6\u5206\u53d1\u5668)","text":""},{"location":"qsl4a/core/events/#starteventdispatcher","title":"startEventDispatcher()","text":"

    \u6253\u5f00\u4e00\u4e2a\u53ef\u4ee5\u8bfb\u53d6\u5df2\u53d1\u5e03\u4e8b\u4ef6\u7684\u5957\u63a5\u5b57\u3002)

    startEventDispatcher(port=0)\n

    \u53c2\u6570\uff1a - port (int, optional): \u76d1\u542c\u7684\u7aef\u53e3\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\u9009\u62e9\uff09

    \u8fd4\u56de\uff1a \u6b63\u5728\u76d1\u542c\u7684\u7aef\u53e3\u53f7

    "},{"location":"qsl4a/core/events/#stopeventdispatcher","title":"stopEventDispatcher()","text":"

    \u505c\u6b62\u4e8b\u4ef6\u670d\u52a1\u5668\u3002)

    stopEventDispatcher()\n
    "},{"location":"qsl4a/core/events/#_6","title":"\u5df2\u5e9f\u5f03\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#rpcpostevent","title":"rpcPostEvent()","text":"

    \u5c06\u4e8b\u4ef6\u53d1\u5e03\u5230\u4e8b\u4ef6\u961f\u5217\u3002\uff08\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 eventPost\uff09

    rpcPostEvent(name, data)\n

    \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e

    "},{"location":"qsl4a/core/events/#_7","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/events/#_8","title":"\u57fa\u672c\u4e8b\u4ef6\u8f6e\u8be2","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6e05\u9664\u65e7\u4e8b\u4ef6\ndroid.eventClearBuffer()\n\n# \u8f6e\u8be2\u4e8b\u4ef6\nevents = droid.eventPoll(5).result\nfor event in events:\n    print(f\"Event: {event['name']}, Data: {event['data']}\")\n
    "},{"location":"qsl4a/core/events/#_9","title":"\u7b49\u5f85\u4e8b\u4ef6","text":"
    # \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\uff0c\u5e26\u8d85\u65f6\nevent = droid.eventWait(timeout=10).result\nif event:\n    print(f\"Got event: {event['name']}\")\n
    "},{"location":"qsl4a/core/events/#_10","title":"\u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6","text":"
    # \u7b49\u5f85\u4f20\u611f\u5668\u4e8b\u4ef6\nevent = droid.eventWaitFor('screen', timeout=5).result\nif event:\n    print(f\"Screen event: {event['data']}\")\n
    "},{"location":"qsl4a/core/events/#_11","title":"\u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6","text":"
    # \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\ndroid.eventPost('my_event', {'key': 'value'})\n\n# \u7b49\u5f85\u5b83\nevent = droid.eventWaitFor('my_event', timeout=1).result\n
    "},{"location":"qsl4a/core/events/#_12","title":"\u5e7f\u64ad\u63a5\u6536\u5668","text":"
    # \u6ce8\u518c\u5c4f\u5e55\u5f00\u5173\u4e8b\u4ef6\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_ON')\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_OFF')\n\n# \u7b49\u5f85\u5c4f\u5e55\u4e8b\u4ef6\nwhile True:\n    event = droid.receiveEvent().result\n    if event['name'] == 'android.intent.action.SCREEN_ON':\n        print(\"Screen turned on\")\n    elif event['name'] == 'android.intent.action.SCREEN_OFF':\n        print(\"Screen turned off\")\n
    "},{"location":"qsl4a/core/events/#_13","title":"\u4f20\u611f\u5668\u4e8b\u4ef6\u5904\u7406","text":"
    # \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u5904\u7406\u4f20\u611f\u5668\u4e8b\u4ef6\nfor _ in range(100):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'sensors':\n        data = event['data']\n        print(f\"Accel: {data['xforce']}, {data['yforce']}, {data['zforce']}\")\n\ndroid.stopSensing()\n
    "},{"location":"qsl4a/core/events/#_14","title":"\u5e38\u89c1\u4e8b\u4ef6\u7c7b\u578b","text":"\u4e8b\u4ef6\u540d\u79f0 \u63cf\u8ff0 \u6765\u6e90 sensors \u4f20\u611f\u5668\u6570\u636e\u66f4\u65b0 startSensing* location GPS \u4f4d\u7f6e\u66f4\u65b0 startLocating phone \u7535\u8bdd\u72b6\u6001\u53d8\u5316 startTrackingPhoneState signal \u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316 startTrackingSignalStrength screen \u622a\u56fe\u5c31\u7eea fullGetScreenShot dialog \u5bf9\u8bdd\u6846\u54cd\u5e94 dialogShow*"},{"location":"qsl4a/core/events/#_15","title":"\u4e8b\u4ef6\u6570\u636e\u7ed3\u6784","text":"
    {\n    'name': 'event_name',\n    'data': {\n        # \u4e8b\u4ef6\u7279\u5b9a\u6570\u636e\n    },\n    'time': 1234567890  # \u65f6\u95f4\u6233\n}\n
    "},{"location":"qsl4a/core/intent/","title":"Intent \u7cfb\u7edf","text":"

    Android Intent \u7528\u4e8e\u542f\u52a8\u6d3b\u52a8\u3001\u53d1\u9001\u5e7f\u64ad\u548c\u5e94\u7528\u95f4\u901a\u4fe1\u3002QSL4A \u901a\u8fc7 Intent \u6a21\u5757\u63d0\u4f9b\u5b8c\u6574\u7684 Intent \u652f\u6301\u3002

    "},{"location":"qsl4a/core/intent/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
    import androidhelper\ndon = androidhelper.Android()\n
    "},{"location":"qsl4a/core/intent/#intent_1","title":"Intent \u5e38\u91cf","text":"

    \u901a\u8fc7 droid.Intent \u8bbf\u95ee\uff1a

    "},{"location":"qsl4a/core/intent/#_2","title":"\u64cd\u4f5c","text":"\u5e38\u91cf \u503c \u7528\u9014 ACTION_MAIN android.intent.action.MAIN \u5e94\u7528\u5165\u53e3\u70b9 ACTION_VIEW android.intent.action.VIEW \u67e5\u770b\u5185\u5bb9 ACTION_EDIT android.intent.action.EDIT \u7f16\u8f91\u5185\u5bb9 ACTION_PICK android.intent.action.PICK \u9009\u62e9\u9879\u76ee ACTION_SEND android.intent.action.SEND \u5206\u4eab\u5185\u5bb9 ACTION_SEARCH android.intent.action.SEARCH \u641c\u7d22"},{"location":"qsl4a/core/intent/#_3","title":"\u6807\u5fd7","text":"\u5e38\u91cf \u503c \u7528\u9014 FLAG_ACTIVITY_NEW_TASK 268435456 \u542f\u52a8\u65b0\u4efb\u52a1 FLAG_ACTIVITY_CLEAR_TASK 32768 \u6e05\u9664\u4efb\u52a1\u5806\u6808 FLAG_ACTIVITY_NEW_DOCUMENT 524288 \u65b0\u6587\u6863\u6a21\u5f0f"},{"location":"qsl4a/core/intent/#_4","title":"\u9644\u52a0\u6570\u636e","text":"\u5e38\u91cf \u7528\u9014 EXTRA_TEXT \u6587\u672c\u5185\u5bb9 EXTRA_STREAM \u6587\u4ef6 URI EXTRA_SUBJECT \u4e3b\u9898\u884c EXTRA_EMAIL \u7535\u5b50\u90ae\u4ef6\u5730\u5740"},{"location":"qsl4a/core/intent/#_5","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/intent/#makeintent","title":"makeIntent()","text":"

    \u521b\u5efa Intent \u5bf9\u8c61\u3002

    makeIntent(action, uri=None, type=None, extras=None, categories=None,\n           packagename=None, classname=None, flags=None)\n

    \u53c2\u6570\uff1a - action (str): Intent \u64cd\u4f5c\uff08\u4f8b\u5982 droid.Intent.ACTION_VIEW\uff09 - uri (str, optional): \u6570\u636e URI - type (str, optional): MIME \u7c7b\u578b - extras (dict, optional): \u9644\u52a0\u6570\u636e - categories (list, optional): Intent \u7c7b\u522b - packagename (str, optional): \u76ee\u6807\u5305 - classname (str, optional): \u76ee\u6807\u7c7b - flags (int, optional): Intent \u6807\u5fd7

    \u8fd4\u56de\uff1a Intent \u5bf9\u8c61

    "},{"location":"qsl4a/core/intent/#startactivityintent","title":"startActivityIntent()","text":"

    \u4f7f\u7528 Intent \u542f\u52a8 Activity\u3002

    startActivityIntent(intent, wait=None)\n

    \u53c2\u6570\uff1a - intent: makeIntent() \u8fd4\u56de\u7684 Intent \u5bf9\u8c61 - wait (bool, optional): \u963b\u585e\u76f4\u5230\u6d3b\u52a8\u5173\u95ed

    "},{"location":"qsl4a/core/intent/#startactivityforresultintent","title":"startActivityForResultIntent()","text":"

    \u542f\u52a8\u6d3b\u52a8\u5e76\u7b49\u5f85\u7ed3\u679c\u3002

    startActivityForResultIntent(intent)\n

    \u8fd4\u56de\uff1a Activity \u7ed3\u679c

    "},{"location":"qsl4a/core/intent/#sendbroadcastintent","title":"sendBroadcastIntent()","text":"

    \u53d1\u9001\u5e7f\u64ad\u3002

    sendBroadcastIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#view","title":"view()","text":"

    \u901a\u8fc7 URI \u67e5\u770b\u5185\u5bb9\u3002

    view(uri, type=None, extras=None)\n
    "},{"location":"qsl4a/core/intent/#pick","title":"pick()","text":"

    \u4ece URI \u9009\u62e9\u5185\u5bb9\u3002

    pick(uri)\n
    "},{"location":"qsl4a/core/intent/#intent_2","title":"\u5e38\u89c1 Intent \u65b9\u6cd5)","text":""},{"location":"qsl4a/core/intent/#scanbarcode","title":"scanBarcode()","text":"

    \u542f\u52a8\u6761\u7801\u626b\u63cf\u5668\u3002

    scanBarcode()\n

    \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/core/intent/#send","title":"send()","text":"

    \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u5185\u5bb9\u3002

    send(type, content)\n

    \u53c2\u6570\uff1a - type (str): MIME \u7c7b\u578b - content (str): \u8981\u5206\u4eab\u7684\u5185\u5bb9

    "},{"location":"qsl4a/core/intent/#sendtext","title":"sendText()","text":"

    \u53d1\u9001\u6587\u672c\u5185\u5bb9\u3002

    sendText(text)\n

    \u53c2\u6570\uff1a - text (str): \u8981\u53d1\u9001\u7684\u6587\u672c

    "},{"location":"qsl4a/core/intent/#sendemail","title":"sendEmail()","text":"

    \u53d1\u9001\u7535\u5b50\u90ae\u4ef6\u3002

    sendEmail(to, subject, body, attachment=None)\n

    \u53c2\u6570\uff1a - to (str or list): \u6536\u4ef6\u4eba\u7535\u5b50\u90ae\u4ef6\u5730\u5740 - subject (str): \u7535\u5b50\u90ae\u4ef6\u4e3b\u9898 - body (str): \u7535\u5b50\u90ae\u4ef6\u6b63\u6587 - attachment (str, optional): \u9644\u4ef6\u6587\u4ef6\u8def\u5f84

    "},{"location":"qsl4a/core/intent/#pathtouri","title":"pathToUri()","text":"

    \u5c06\u6587\u4ef6\u8def\u5f84\u8f6c\u6362\u4e3a\u5185\u5bb9 URI\u3002

    pathToUri(path)\n

    \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

    \u8fd4\u56de\uff1a \u5185\u5bb9 URI \u5b57\u7b26\u4e32

    "},{"location":"qsl4a/core/intent/#openfile","title":"openFile()","text":"

    \u7528\u9002\u5f53\u7684\u5e94\u7528\u7a0b\u5e8f\u6253\u5f00\u6587\u4ef6\u3002

    openFile(path)\n

    \u53c2\u6570\uff1a - path (str): \u8981\u6253\u5f00\u7684\u6587\u4ef6\u8def\u5f84

    "},{"location":"qsl4a/core/intent/#sendfile","title":"sendFile()","text":"

    \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u6587\u4ef6\u3002

    sendFile(path)\n

    \u53c2\u6570\uff1a - path (str): \u8981\u53d1\u9001\u7684\u6587\u4ef6\u8def\u5f84

    "},{"location":"qsl4a/core/intent/#getpathtype","title":"getPathType()","text":"

    \u83b7\u53d6\u6587\u4ef6\u8def\u5f84\u7684 MIME \u7c7b\u578b\u3002

    getPathType(path)\n

    \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

    \u8fd4\u56de\uff1a MIME \u7c7b\u578b\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/core/intent/#viewmap","title":"viewMap()","text":"

    \u5728\u6307\u5b9a\u4f4d\u7f6e\u6253\u5f00\u5730\u56fe\u3002

    viewMap(latitude, longitude)\n

    \u53c2\u6570\uff1a - latitude (float): \u7eac\u5ea6 - longitude (float): \u7ecf\u5ea6

    "},{"location":"qsl4a/core/intent/#viewcontacts","title":"viewContacts()","text":"

    \u6253\u5f00\u8054\u7cfb\u4eba\u5e94\u7528\u3002

    viewContacts()\n
    "},{"location":"qsl4a/core/intent/#search","title":"search()","text":"

    \u6267\u884c\u7f51\u7edc\u641c\u7d22\u3002

    search(query)\n

    \u53c2\u6570\uff1a - query (str): \u641c\u7d22\u67e5\u8be2

    "},{"location":"qsl4a/core/intent/#viewhtml","title":"viewHtml()","text":"

    \u67e5\u770b HTML \u5185\u5bb9\u3002

    viewHtml(content, encoding=None)\n

    \u53c2\u6570\uff1a - content (str): HTML \u5185\u5bb9 - encoding (str, optional): \u5b57\u7b26\u7f16\u7801

    "},{"location":"qsl4a/core/intent/#webviewshow","title":"webViewShow()","text":"

    \u5728 WebView \u4e2d\u663e\u793a\u7f51\u9875\u5185\u5bb9\u3002\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 viewHtml\u3002

    webViewShow(url)\n

    \u53c2\u6570\uff1a - url (str): \u7f51\u9875 URL

    "},{"location":"qsl4a/core/intent/#editoropen","title":"editorOpen()","text":"

    \u6253\u5f00\u6587\u672c\u7f16\u8f91\u5668\u3002

    editorOpen(path=None, create=False)\n

    \u53c2\u6570\uff1a - path (str, optional): \u8981\u7f16\u8f91\u7684\u6587\u4ef6\u8def\u5f84 - create (bool, optional): \u5982\u679c\u4e0d\u5b58\u5728\u5219\u521b\u5efa

    "},{"location":"qsl4a/core/intent/#uri","title":"\u8f85\u52a9\u7c7b\uff1aUri","text":"

    \u521b\u5efa Intent \u7684 URI \u5bf9\u8c61\uff1a

    from androidhelper.Intent import Uri\n\nuri = Uri(\"file:///sdcard/test.txt\")\n
    "},{"location":"qsl4a/core/intent/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/intent/#_7","title":"\u6253\u5f00\u7f51\u9875","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"http://www.example.com\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#_8","title":"\u5206\u4eab\u6587\u672c","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_TEXT: \"Hello from QPython!\",\n        droid.Intent.EXTRA_SUBJECT: \"Test\"\n    },\n    type=\"text/plain\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#_9","title":"\u6253\u5f00\u6587\u4ef6","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"file:///sdcard/document.pdf\",\n    type=\"application/pdf\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#_10","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":"
    result = droid.pickContact()\ncontact_uri = result.result\n
    "},{"location":"qsl4a/core/intent/#_11","title":"\u53d1\u9001\u7535\u5b50\u90ae\u4ef6","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_EMAIL: [\"test@example.com\"],\n        droid.Intent.EXTRA_SUBJECT: \"Hello\",\n        droid.Intent.EXTRA_TEXT: \"Message body\"\n    },\n    type=\"message/rfc822\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#_12","title":"\u6253\u5f00\u5e94\u7528","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_MAIN,\n    packagename=\"com.android.settings\",\n    classname=\"com.android.settings.Settings\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/hardware/bluetooth/","title":"\u84dd\u7259 API","text":"

    \u63a7\u5236\u84dd\u7259\u9002\u914d\u5668\u5e76\u4e0e\u84dd\u7259\u8bbe\u5907\u901a\u4fe1\u3002

    "},{"location":"qsl4a/hardware/bluetooth/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/hardware/bluetooth/#togglebluetoothstate","title":"toggleBluetoothState()","text":"

    \u6253\u5f00/\u5173\u95ed\u84dd\u7259\u3002

    toggleBluetoothState(enabled=None, prompt=True)\n

    \u53c2\u6570\uff1a - enabled (bool): True=\u5f00\uff0cFalse=\u5173\uff0cNone=\u5207\u6362 - prompt (bool): \u663e\u793a\u7528\u6237\u63d0\u793a

    "},{"location":"qsl4a/hardware/bluetooth/#checkbluetoothstate","title":"checkBluetoothState()","text":"

    \u68c0\u67e5\u84dd\u7259\u662f\u5426\u5df2\u542f\u7528\u3002

    checkBluetoothState()\n

    \u8fd4\u56de\uff1a True/False

    "},{"location":"qsl4a/hardware/bluetooth/#getlocalname","title":"GetLocalName()","text":"

    \u83b7\u53d6\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

    GetLocalName()\n
    "},{"location":"qsl4a/hardware/bluetooth/#setlocalname","title":"SetLocalName()","text":"

    \u8bbe\u7f6e\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

    SetLocalName(name)\n
    "},{"location":"qsl4a/hardware/bluetooth/#getscanmode","title":"GetScanMode()","text":"

    \u83b7\u53d6\u53ef\u53d1\u73b0\u6027\u6a21\u5f0f\u3002

    GetScanMode()\n

    \u8fd4\u56de\uff1a - -1: \u5df2\u7981\u7528 - 0: \u4e0d\u53ef\u53d1\u73b0\uff0c\u4e0d\u53ef\u8fde\u63a5 - 1: \u53ef\u8fde\u63a5\uff0c\u4e0d\u53ef\u53d1\u73b0 - 3: \u53ef\u8fde\u63a5\u4e14\u53ef\u53d1\u73b0

    "},{"location":"qsl4a/hardware/bluetooth/#makediscoverable","title":"MakeDiscoverable()","text":"

    \u4f7f\u8bbe\u5907\u53ef\u53d1\u73b0\u3002

    MakeDiscoverable(duration=300)\n

    \u53c2\u6570\uff1a - duration (int): \u53ef\u53d1\u73b0\u7684\u79d2\u6570

    "},{"location":"qsl4a/hardware/bluetooth/#_2","title":"\u53d1\u73b0","text":""},{"location":"qsl4a/hardware/bluetooth/#discoverystart","title":"DiscoveryStart()","text":"

    \u5f00\u59cb\u8bbe\u5907\u53d1\u73b0\u3002

    DiscoveryStart()\n
    "},{"location":"qsl4a/hardware/bluetooth/#discoverycancel","title":"DiscoveryCancel()","text":"

    \u53d6\u6d88\u53d1\u73b0\u3002

    DiscoveryCancel()\n
    "},{"location":"qsl4a/hardware/bluetooth/#getreceiveddevices","title":"GetReceivedDevices()","text":"

    \u83b7\u53d6\u53d1\u73b0\u7684\u8bbe\u5907\u3002

    GetReceivedDevices()\n

    \u8fd4\u56de\uff1a \u8bbe\u5907\u4fe1\u606f\u5b57\u5178\u5217\u8868

    "},{"location":"qsl4a/hardware/bluetooth/#getbondeddevices","title":"GetBondedDevices()","text":"

    \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\u3002

    GetBondedDevices()\n

    \u8fd4\u56de\uff1a \u914d\u5bf9\u8bbe\u5907\u4fe1\u606f\u5217\u8868

    "},{"location":"qsl4a/hardware/bluetooth/#_3","title":"\u8fde\u63a5","text":""},{"location":"qsl4a/hardware/bluetooth/#connect","title":"Connect()","text":"

    \u8fde\u63a5\u5230\u8bbe\u5907\u3002

    Connect(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", address=None)\n

    \u53c2\u6570\uff1a - uuid (str): \u670d\u52a1 UUID - address (str): \u8bbe\u5907\u5730\u5740\uff08None = \u663e\u793a\u9009\u62e9\u5668\uff09

    \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/hardware/bluetooth/#accept","title":"Accept()","text":"

    \u63a5\u53d7\u4f20\u5165\u8fde\u63a5\u3002

    Accept(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", timeout=0)\n
    "},{"location":"qsl4a/hardware/bluetooth/#activeconnections","title":"ActiveConnections()","text":"

    \u68c0\u67e5\u6d3b\u52a8\u8fde\u63a5\u3002

    ActiveConnections()\n
    "},{"location":"qsl4a/hardware/bluetooth/#stop","title":"Stop()","text":"

    \u65ad\u5f00\u8fde\u63a5\u3002

    Stop(connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#_4","title":"\u901a\u4fe1","text":""},{"location":"qsl4a/hardware/bluetooth/#write","title":"Write()","text":"

    \u53d1\u9001 ASCII \u6570\u636e\u3002

    Write(ascii, connID=\"\")\n
    "},{"location":"qsl4a/hardware/bluetooth/#writebinary","title":"WriteBinary()","text":"

    \u53d1\u9001\u4e8c\u8fdb\u5236\u6570\u636e\uff08base64 \u7f16\u7801\uff09\u3002

    WriteBinary(base64, connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#read","title":"Read()","text":"

    \u8bfb\u53d6 ASCII \u6570\u636e\u3002

    Read(bufferSize=4096, connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#readbinary","title":"ReadBinary()","text":"

    \u8bfb\u53d6\u4e8c\u8fdb\u5236\u6570\u636e\u3002

    ReadBinary(bufferSize=4096, connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#readline","title":"ReadLine()","text":"

    \u8bfb\u53d6\u4e00\u884c\u3002

    ReadLine(connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#readready","title":"ReadReady()","text":"

    \u68c0\u67e5\u662f\u5426\u6709\u53ef\u7528\u6570\u636e\u3002

    ReadReady(connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u7528\u84dd\u7259\ndroid.toggleBluetoothState(True)\n\n# \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\ndevices = droid.GetBondedDevices().result\nfor dev in devices:\n    print(f\"{dev['name']}: {dev['address']}\")\n\n# \u8fde\u63a5\u5230\u8bbe\u5907\ndroid.Connect(address=\"00:11:22:33:44:55\")\n\n# \u53d1\u9001\u6570\u636e\ndroid.Write(\"Hello Bluetooth!\")\n\n# \u8bfb\u53d6\u54cd\u5e94\ndata = droid.Read(1024).result\n
    "},{"location":"qsl4a/hardware/camera/","title":"\u76f8\u673a API","text":"

    \u62cd\u6444\u7167\u7247\u548c\u5f55\u5236\u89c6\u9891\u3002

    "},{"location":"qsl4a/hardware/camera/#_1","title":"\u7167\u7247\u62cd\u6444","text":""},{"location":"qsl4a/hardware/camera/#takepicture","title":"takePicture()","text":"

    \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u6444\u7167\u7247\u3002

    takePicture(path=None)\n

    \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8fd4\u56de\u56fe\u50cf\u6570\u636e

    \u8fd4\u56de\uff1a \u56fe\u50cf\u8def\u5f84\u6216\u56fe\u50cf\u6570\u636e

    "},{"location":"qsl4a/hardware/camera/#cameracapturepicture","title":"cameraCapturePicture()","text":"

    \u4f7f\u7528\u9ad8\u7ea7\u76f8\u673a\u63a7\u5236\u62cd\u6444\u7167\u7247\u3002

    cameraCapturePicture(targetPath=None, cameraId=0, useAutoFocus=True)\n

    \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - useAutoFocus (bool): \u542f\u7528\u81ea\u52a8\u5bf9\u7126

    \u8fd4\u56de\uff1a \u62cd\u6444\u7684\u56fe\u50cf\u8def\u5f84

    "},{"location":"qsl4a/hardware/camera/#camerasettorchmode","title":"cameraSetTorchMode()","text":"

    \u63a7\u5236\u76f8\u673a\u95ea\u5149\u706f/\u624b\u7535\u7b52\u3002

    cameraSetTorchMode(enabled)\n

    \u53c2\u6570\uff1a - enabled (bool): True \u6253\u5f00\uff0cFalse \u5173\u95ed

    \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/hardware/camera/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

    \u622a\u56fe\u3002

    imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

    \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

    "},{"location":"qsl4a/hardware/camera/#_2","title":"\u89c6\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#takevideo","title":"takeVideo()","text":"

    \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\u3002

    takeVideo(path=None, quality=1)\n

    \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-4\uff09 - 0: 160x120 - 1: 320x240 - 2: 352x288 - 3: 640x480 - 4: 800x480

    "},{"location":"qsl4a/hardware/camera/#recordercapturevideo","title":"recorderCaptureVideo()","text":"

    \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\u3002

    recorderCaptureVideo(targetPath=None, duration=10, cameraId=0, quality=8)\n

    \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - duration (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a10\uff09 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-8\uff0c\u8d8a\u9ad8\u8d8a\u597d\uff09

    \u8fd4\u56de\uff1a \u89c6\u9891\u6587\u4ef6\u8def\u5f84

    "},{"location":"qsl4a/hardware/camera/#recordaudio","title":"recordAudio()","text":"

    \u5f55\u5236\u97f3\u9891\u3002

    recordAudio()\n

    \u8fd4\u56de\uff1a \u97f3\u9891\u6587\u4ef6\u8def\u5f84

    "},{"location":"qsl4a/hardware/camera/#_3","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

    \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\u3002

    recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

    \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\uff09 - targetPixels (int): \u5206\u8fa8\u7387 - frameRate (int): FPS - bitRate (int): \u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa - autoStart (bool): \u7acb\u5373\u5f00\u59cb

    "},{"location":"qsl4a/hardware/camera/#recorderstart","title":"recorderStart()","text":"

    \u5f00\u59cb\u5f55\u5236\u3002

    recorderStart()\n
    "},{"location":"qsl4a/hardware/camera/#recorderpause","title":"recorderPause()","text":"

    \u6682\u505c\u5f55\u5236\u3002

    recorderPause()\n
    "},{"location":"qsl4a/hardware/camera/#recorderresume","title":"recorderResume()","text":"

    \u6062\u590d\u5f55\u5236\u3002

    recorderResume()\n
    "},{"location":"qsl4a/hardware/camera/#_4","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/camera/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

    \u5f00\u59cb\u97f3\u91cf\u68c0\u6d4b\u3002

    recorderSoundVolumeDetect(interval=100)\n
    "},{"location":"qsl4a/hardware/camera/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

    \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

    recorderSoundVolumeGetDb()\n
    "},{"location":"qsl4a/hardware/camera/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u7167\nphoto_path = droid.takePicture(\"/sdcard/photo.jpg\").result\nprint(f\"Photo saved: {photo_path}\")\n\n# \u4f7f\u7528\u524d\u7f6e\u76f8\u673a\u548c\u81ea\u52a8\u5bf9\u7126\u62cd\u7167\ncamera_path = droid.cameraCapturePicture(\"/sdcard/selfie.jpg\", cameraId=1, useAutoFocus=True).result\nprint(f\"Front camera photo: {camera_path}\")\n\n# \u63a7\u5236\u95ea\u5149\u706f\ndroid.cameraSetTorchMode(True)  # \u6253\u5f00\u95ea\u5149\u706f\n\n# \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\nvideo_path = droid.takeVideo(\"/sdcard/video.mp4\", quality=3).result\nprint(f\"Video saved: {video_path}\")\n\n# \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\nvideo_path = droid.recorderCaptureVideo(\"/sdcard/movie.mp4\", duration=30, cameraId=0, quality=8).result\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n
    "},{"location":"qsl4a/hardware/recorder/","title":"\u97f3\u9891\u5f55\u5236 API","text":"

    \u4ece\u9ea6\u514b\u98ce\u548c\u8bbe\u5907\u5c4f\u5e55\u5f55\u5236\u97f3\u9891\u3002

    "},{"location":"qsl4a/hardware/recorder/#_1","title":"\u97f3\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recordaudio","title":"recordAudio()","text":"

    \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\u3002

    recordAudio()\n

    \u8fd4\u56de\uff1a \u5f55\u5236\u7684\u97f3\u9891\u6587\u4ef6\u8def\u5f84

    "},{"location":"qsl4a/hardware/recorder/#recorderstartmicrophone","title":"recorderStartMicrophone()","text":"

    \u5f00\u59cb\u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\u3002

    recorderStartMicrophone(targetPath=None)\n

    \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u5f55\u5236\u7684\u8def\u5f84

    "},{"location":"qsl4a/hardware/recorder/#_2","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

    \u5f00\u59cb\u5e26\u97f3\u9891\u7684\u5c4f\u5e55\u5f55\u5236\u3002

    recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

    \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\u97f3\u9891\uff09 - targetPixels (int): \u76ee\u6807\u5206\u8fa8\u7387\uff08\u50cf\u7d20\uff09 - frameRate (int): \u6bcf\u79d2\u5e27\u6570\uff08\u9ed8\u8ba4\uff1a30\uff09 - bitRate (int): \u89c6\u9891\u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa\u89c6\u9891 - autoStart (bool): \u7acb\u5373\u5f00\u59cb\u5f55\u5236

    \u8fd4\u56de\uff1a \u64cd\u4f5c\u7ed3\u679c

    "},{"location":"qsl4a/hardware/recorder/#recorderstart","title":"recorderStart()","text":"

    \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\uff08\u5f53 autoStart=False \u65f6\uff09\u3002

    recorderStart()\n
    "},{"location":"qsl4a/hardware/recorder/#recorderpause","title":"recorderPause()","text":"

    \u6682\u505c\u6b63\u5728\u8fdb\u884c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

    recorderPause()\n
    "},{"location":"qsl4a/hardware/recorder/#recorderresume","title":"recorderResume()","text":"

    \u6062\u590d\u6682\u505c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

    recorderResume()\n
    "},{"location":"qsl4a/hardware/recorder/#_3","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/recorder/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

    \u5f00\u59cb\u76d1\u63a7\u97f3\u91cf\u7ea7\u522b\u3002

    recorderSoundVolumeDetect(interval=100)\n

    \u53c2\u6570\uff1a - interval (int): \u68c0\u6d4b\u95f4\u9694\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a100\uff09

    "},{"location":"qsl4a/hardware/recorder/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

    \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

    recorderSoundVolumeGetDb()\n

    \u8fd4\u56de\uff1a \u5f53\u524d\u97f3\u91cf\u7ea7\u522b\uff08dB\uff09

    "},{"location":"qsl4a/hardware/recorder/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\nprint(\"Recording audio...\")\naudio_path = droid.recordAudio().result\nprint(f\"Saved to: {audio_path}\")\n\n# \u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\ndroid.recorderStartMicrophone(\"/sdcard/my_recording.mp3\")\ntime.sleep(5)\ndroid.recorderStop()\n\n# \u5e26\u97f3\u9891\u5f55\u5236\u5c4f\u5e55\nprint(\"Starting screen recording...\")\ndroid.recorderStartScreenRecord(\n    path=\"/sdcard/screen_record.mp4\",\n    audio=1,\n    frameRate=30,\n    autoStart=True\n)\ntime.sleep(10)\ndroid.recorderStop()\n\n# \u76d1\u63a7\u97f3\u91cf\ndroid.recorderSoundVolumeDetect(interval=100)\ntime.sleep(3)\nvolume = droid.recorderSoundVolumeGetDb().result\nprint(f\"Current volume: {volume} dB\")\n
    "},{"location":"qsl4a/hardware/usbserial/","title":"USB \u4e3b\u673a\u4e32\u884c API","text":"

    \u4e0e USB \u4e32\u884c\u8bbe\u5907\u901a\u4fe1\uff08\u9700\u8981 USB OTG \u652f\u6301\u548c Android 3.1+\uff09\u3002

    "},{"location":"qsl4a/hardware/usbserial/#usb","title":"USB \u4e32\u884c\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialopen","title":"usbHostSerialOpen()","text":"

    \u6253\u5f00\u4e0e USB \u4e32\u884c\u8bbe\u5907\u7684\u8fde\u63a5\u3002

    usbHostSerialOpen(device, baudRate=9600)\n

    \u53c2\u6570\uff1a - device (str): USB \u8bbe\u5907\u8def\u5f84\u6216\u6807\u8bc6\u7b26 - baudRate (int): \u6ce2\u7279\u7387\uff08\u9ed8\u8ba4\uff1a9600\uff09

    \u8fd4\u56de\uff1a \u5982\u679c\u6253\u5f00\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialclose","title":"usbHostSerialClose()","text":"

    \u5173\u95ed USB \u4e32\u884c\u8fde\u63a5\u3002

    usbHostSerialClose()\n
    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialread","title":"usbHostSerialRead()","text":"

    \u4ece USB \u4e32\u884c\u8bfb\u53d6\u6570\u636e\u3002

    usbHostSerialRead(bufferSize=1024)\n

    \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570\uff08\u9ed8\u8ba4\uff1a1024\uff09

    \u8fd4\u56de\uff1a \u8bfb\u53d6\u7684\u6570\u636e\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwrite","title":"usbHostSerialWrite()","text":"

    \u5411 USB \u4e32\u884c\u5199\u5165\u6570\u636e\u3002

    usbHostSerialWrite(data)\n

    \u53c2\u6570\uff1a - data (str): \u8981\u5199\u5165\u7684\u5b57\u7b26\u4e32\u6570\u636e

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialavailable","title":"usbHostSerialAvailable()","text":"

    \u68c0\u67e5\u662f\u5426\u6709\u53ef\u8bfb\u53d6\u7684\u6570\u636e\u3002

    usbHostSerialAvailable()\n

    \u8fd4\u56de\uff1a \u53ef\u7528\u5b57\u8282\u6570

    "},{"location":"qsl4a/hardware/usbserial/#_1","title":"\u914d\u7f6e\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetbaudrate","title":"usbHostSerialSetBaudRate()","text":"

    \u8bbe\u7f6e\u6ce2\u7279\u7387\u3002

    usbHostSerialSetBaudRate(baudRate)\n

    \u53c2\u6570\uff1a - baudRate (int): \u6ce2\u7279\u7387

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetdatabits","title":"usbHostSerialSetDataBits()","text":"

    \u8bbe\u7f6e\u6570\u636e\u4f4d\uff085\u30016\u30017 \u6216 8\uff09\u3002

    usbHostSerialSetDataBits(dataBits)\n

    \u53c2\u6570\uff1a - dataBits (int): \u6570\u636e\u4f4d\uff085-8\uff09

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetstopbits","title":"usbHostSerialSetStopBits()","text":"

    \u8bbe\u7f6e\u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09\u3002

    usbHostSerialSetStopBits(stopBits)\n

    \u53c2\u6570\uff1a - stopBits (float): \u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetparity","title":"usbHostSerialSetParity()","text":"

    \u8bbe\u7f6e\u6821\u9a8c\u4f4d\uff08\u65e0\u3001\u5947\u3001\u5076\u3001\u6807\u8bb0\u3001\u7a7a\u683c\uff09\u3002

    usbHostSerialSetParity(parity)\n

    \u53c2\u6570\uff1a - parity (str): \u6821\u9a8c\u6a21\u5f0f\uff08'none'\u3001'odd'\u3001'even'\u3001'mark'\u3001'space'\uff09

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetflowcontrol","title":"usbHostSerialSetFlowControl()","text":"

    \u8bbe\u7f6e\u6d41\u63a7\u5236\uff08\u65e0\u3001\u786c\u4ef6\u3001\u8f6f\u4ef6\uff09\u3002

    usbHostSerialSetFlowControl(flowControl)\n

    \u53c2\u6570\uff1a - flowControl (str): \u6d41\u63a7\u5236\u6a21\u5f0f\uff08'none'\u3001'hardware'\u3001'software'\uff09

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialreadhex","title":"usbHostSerialReadHex()","text":"

    \u4ee5\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u8bfb\u53d6\u6570\u636e\u3002

    usbHostSerialReadHex(bufferSize=1024)\n

    \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570

    \u8fd4\u56de\uff1a \u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwritehex","title":"usbHostSerialWriteHex()","text":"

    \u4ece\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u5199\u5165\u6570\u636e\u3002

    usbHostSerialWriteHex(hexString)\n

    \u53c2\u6570\uff1a - hexString (str): \u8981\u5199\u5165\u7684\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/hardware/usbserial/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6253\u5f00 USB \u4e32\u884c\u8fde\u63a5\nif droid.usbHostSerialOpen(\"/dev/bus/usb/001/001\", 115200).result:\n    print(\"USB serial opened\")\n\n    # \u5199\u5165\u6570\u636e\n    droid.usbHostSerialWrite(\"AT\\r\")\n\n    # \u8bfb\u53d6\u54cd\u5e94\n    response = droid.usbHostSerialRead(1024).result\n    print(f\"Response: {response}\")\n\n    # \u6216\u4f7f\u7528\u5341\u516d\u8fdb\u5236\n    droid.usbHostSerialWriteHex(\"41540D0A\")  # \"AT\\r\\n\"\n\n    # \u5173\u95ed\u8fde\u63a5\n    droid.usbHostSerialClose()\n

    \u6ce8\u610f\uff1a USB \u4e32\u884c\u9700\u8981\uff1a - Android 3.1+ (API 12) - USB OTG \u7ebf/\u9002\u914d\u5668 - \u8bbe\u5907\u4e0a\u7684 USB \u4e3b\u673a\u6a21\u5f0f\u652f\u6301 - \u517c\u5bb9\u7684\u4e32\u884c\u8bbe\u5907

    "},{"location":"qsl4a/hardware/webcam/","title":"\u7f51\u7edc\u6444\u50cf\u5934 API","text":"

    \u4f7f\u7528 MJPEG \u4ece\u8bbe\u5907\u76f8\u673a\u6d41\u5f0f\u4f20\u8f93\u89c6\u9891\u3002

    "},{"location":"qsl4a/hardware/webcam/#mjpeg","title":"MJPEG \u6d41\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#webcamstart","title":"webcamStart()","text":"

    \u4ece\u7f51\u7edc\u6444\u50cf\u5934\u542f\u52a8 MJPEG \u6d41\u3002

    webcamStart(resolutionLevel=0, jpegQuality=20, port=0)\n

    \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf 1-100\uff08\u9ed8\u8ba4\uff1a20\uff09 - port (int): \u7aef\u53e3\u53f7\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\uff09

    \u8fd4\u56de\uff1a \u6d41\u7684 (\u5730\u5740, \u7aef\u53e3) \u5143\u7ec4

    "},{"location":"qsl4a/hardware/webcam/#webcamadjustquality","title":"webcamAdjustQuality()","text":"

    \u8c03\u6574\u6d3b\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u7684\u8d28\u91cf\u3002

    webcamAdjustQuality(resolutionLevel=0, jpegQuality=20)\n

    \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b - jpegQuality (int): JPEG \u8d28\u91cf 1-100

    "},{"location":"qsl4a/hardware/webcam/#webcamstop","title":"webcamStop()","text":"

    \u505c\u6b62\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u3002

    webcamStop()\n
    "},{"location":"qsl4a/hardware/webcam/#_1","title":"\u76f8\u673a\u9884\u89c8\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#camerastartpreview","title":"cameraStartPreview()","text":"

    \u5f00\u59cb\u5e26\u4e8b\u4ef6\u751f\u6210\u7684\u76f8\u673a\u9884\u89c8\u6a21\u5f0f\u3002

    cameraStartPreview(resolutionLevel=0, jpegQuality=20, filepath=None)\n

    \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf\uff08\u9ed8\u8ba4\uff1a20\uff09 - filepath (str, optional): \u4fdd\u5b58\u9884\u89c8\u5e27\u7684\u6587\u4ef6\u8def\u5f84

    \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

    \u6ce8\u610f\uff1a \u751f\u6210\u5e26\u6709\u5e27\u6570\u636e\u7684 'preview' \u4e8b\u4ef6\u3002

    "},{"location":"qsl4a/hardware/webcam/#camerastoppreview","title":"cameraStopPreview()","text":"

    \u505c\u6b62\u76f8\u673a\u9884\u89c8\u3002

    cameraStopPreview()\n
    "},{"location":"qsl4a/hardware/webcam/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\nstream_info = droid.webcamStart(\n    resolutionLevel=0,\n    jpegQuality=30,\n    port=8080\n).result\nprint(f\"Stream available at {stream_info[0]}:{stream_info[1]}\")\n\n# \u6d41\u5f0f\u4f20\u8f93\u65f6\u8c03\u6574\u8d28\u91cf\ntime.sleep(5)\ndroid.webcamAdjustQuality(resolutionLevel=1, jpegQuality=50)\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.webcamStop()\n\n# \u6216\u4f7f\u7528\u9884\u89c8\u6a21\u5f0f\nprint(\"Starting preview...\")\ndroid.cameraStartPreview()\n\n# \u7b49\u5f85\u9884\u89c8\u4e8b\u4ef6\nfor i in range(10):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'preview':\n        print(f\"Got preview frame: {event['data']}\")\n\ndroid.cameraStopPreview()\n
    "},{"location":"qsl4a/media/image/","title":"\u56fe\u50cf\u5904\u7406 API","text":"

    \u538b\u7f29\u548c\u5904\u7406\u56fe\u50cf\u3002

    "},{"location":"qsl4a/media/image/#_1","title":"\u56fe\u50cf\u538b\u7f29","text":""},{"location":"qsl4a/media/image/#imagecompress","title":"imageCompress()","text":"

    \u538b\u7f29\u56fe\u50cf\u6587\u4ef6\u3002

    imageCompress(srcPath, destPath, targetByteSize=0, targetWidth=0, targetHeight=0)\n

    \u53c2\u6570\uff1a - srcPath (str): \u6e90\u56fe\u50cf\u8def\u5f84 - destPath (str): \u8f93\u51fa\u8def\u5f84 - targetByteSize (int): \u76ee\u6807\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff080 = \u65e0\u9650\u5236\uff09 - targetWidth (int): \u76ee\u6807\u5bbd\u5ea6\uff080 = \u539f\u59cb\uff09 - targetHeight (int): \u76ee\u6807\u9ad8\u5ea6\uff080 = \u539f\u59cb\uff09

    \u8fd4\u56de\uff1a \u538b\u7f29\u540e\u7684\u56fe\u50cf\u8def\u5f84

    "},{"location":"qsl4a/media/image/#_2","title":"\u622a\u56fe","text":""},{"location":"qsl4a/media/image/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

    \u622a\u53d6\u5c4f\u5e55\u3002

    imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

    \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

    \u8fd4\u56de\uff1a \u622a\u56fe\u8def\u5f84

    "},{"location":"qsl4a/media/image/#_3","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/image/#videoplay","title":"videoPlay()","text":"

    \u5728\u5168\u5c4f\u6a21\u5f0f\u4e0b\u64ad\u653e\u89c6\u9891\u6587\u4ef6\u3002

    videoPlay(path, wait=True)\n

    \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

    "},{"location":"qsl4a/media/image/#_4","title":"\u6761\u7801\u626b\u63cf","text":""},{"location":"qsl4a/media/image/#scanbarcodefromimage","title":"scanBarcodeFromImage()","text":"

    \u4ece\u56fe\u50cf\u6587\u4ef6\u626b\u63cf\u6761\u7801/\u4e8c\u7ef4\u7801\u3002

    scanBarcodeFromImage(path, compressRatio=0, x=0, y=0, width=0, height=0)\n

    \u53c2\u6570\uff1a - path (str): \u56fe\u50cf\u6587\u4ef6\u8def\u5f84 - compressRatio (int): \u538b\u7f29\u6bd4\uff080 = \u4e0d\u538b\u7f29\uff09 - x, y, width, height (int): \u8981\u626b\u63cf\u7684\u533a\u57df\uff080 = \u5b8c\u6574\u56fe\u50cf\uff09

    \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5185\u5bb9

    "},{"location":"qsl4a/media/image/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n\n# \u538b\u7f29\u56fe\u50cf\ncompressed = droid.imageCompress(\n    \"/sdcard/large_photo.jpg\",\n    \"/sdcard/compressed.jpg\",\n    targetByteSize=102400,  # \u76ee\u6807\u7ea6 100KB\n    targetWidth=1920,\n    targetHeight=1080\n).result\nprint(f\"Saved: {compressed}\")\n\n# \u64ad\u653e\u89c6\u9891\nvideo_path = \"/sdcard/movie.mp4\"\ndroid.videoPlay(video_path, wait=True)\n\n# \u4ece\u56fe\u50cf\u626b\u63cf\u6761\u7801\nresult = droid.scanBarcodeFromImage(\"/sdcard/qr_code.png\").result\nprint(f\"Barcode: {result}\")\n
    "},{"location":"qsl4a/media/mediaplayer/","title":"\u5a92\u4f53\u64ad\u653e\u5668 API","text":"

    \u63a7\u5236\u97f3\u9891\u548c\u89c6\u9891\u64ad\u653e\u3002

    "},{"location":"qsl4a/media/mediaplayer/#_1","title":"\u64ad\u653e\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplay","title":"mediaPlay()","text":"

    \u64ad\u653e\u5a92\u4f53\u6587\u4ef6\u3002

    mediaPlay(url, tag=\"default\", play=True)\n

    \u53c2\u6570\uff1a - url (str): \u5a92\u4f53\u6587\u4ef6\u8def\u5f84\u6216 URL - tag (str): \u64ad\u653e\u5668\u6807\u8bc6\u7b26 - play (bool): \u81ea\u52a8\u5f00\u59cb\u64ad\u653e

    "},{"location":"qsl4a/media/mediaplayer/#mediaplaystart","title":"mediaPlayStart()","text":"

    \u5f00\u59cb\u64ad\u653e\u3002

    mediaPlayStart(tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#mediaplaypause","title":"mediaPlayPause()","text":"

    \u6682\u505c\u64ad\u653e\u3002

    mediaPlayPause(tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#mediaplayclose","title":"mediaPlayClose()","text":"

    \u5173\u95ed\u64ad\u653e\u5668\u3002

    mediaPlayClose(tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#mediaplayseek","title":"mediaPlaySeek()","text":"

    \u8df3\u8f6c\u5230\u4f4d\u7f6e\u3002

    mediaPlaySeek(msec, tag=\"default\")\n

    \u53c2\u6570\uff1a - msec (int): \u4f4d\u7f6e\uff08\u6beb\u79d2\uff09

    "},{"location":"qsl4a/media/mediaplayer/#mediaplaysetlooping","title":"mediaPlaySetLooping()","text":"

    \u8bbe\u7f6e\u5faa\u73af\u6a21\u5f0f\u3002

    mediaPlaySetLooping(enabled, tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#_2","title":"\u64ad\u653e\u5668\u4fe1\u606f","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplayinfo","title":"mediaPlayInfo()","text":"

    \u83b7\u53d6\u64ad\u653e\u4fe1\u606f\u3002

    mediaPlayInfo(tag=\"default\")\n

    \u8fd4\u56de\uff1a \u5305\u542b\u65f6\u957f\u3001\u4f4d\u7f6e\u7b49\u7684\u5b57\u5178

    "},{"location":"qsl4a/media/mediaplayer/#mediaisplaying","title":"mediaIsPlaying()","text":"

    \u68c0\u67e5\u662f\u5426\u6b63\u5728\u64ad\u653e\u3002

    mediaIsPlaying(tag=\"default\")\n

    \u8fd4\u56de\uff1a True/False

    "},{"location":"qsl4a/media/mediaplayer/#mediaplaylist","title":"mediaPlayList()","text":"

    \u5217\u51fa\u6d3b\u52a8\u64ad\u653e\u5668\u3002

    mediaPlayList()\n
    "},{"location":"qsl4a/media/mediaplayer/#_3","title":"\u97f3\u91cf\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#getmediavolume","title":"getMediaVolume()","text":"

    \u83b7\u53d6\u5a92\u4f53\u97f3\u91cf\u3002

    getMediaVolume()\n

    \u8fd4\u56de\uff1a \u97f3\u91cf\u7ea7\u522b\uff080-15\uff09

    "},{"location":"qsl4a/media/mediaplayer/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

    \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

    getMaxMediaVolume()\n
    "},{"location":"qsl4a/media/mediaplayer/#getringervolume","title":"getRingerVolume()","text":"

    \u83b7\u53d6\u94c3\u58f0\u97f3\u91cf\u3002

    getRingerVolume()\n
    "},{"location":"qsl4a/media/mediaplayer/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

    \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

    getMaxRingerVolume()\n
    "},{"location":"qsl4a/media/mediaplayer/#_4","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/mediaplayer/#videoplay","title":"videoPlay()","text":"

    \u5168\u5c4f\u64ad\u653e\u89c6\u9891\u3002

    videoPlay(path, wait=True)\n

    \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210

    "},{"location":"qsl4a/media/mediaplayer/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u64ad\u653e\u97f3\u9891\ndroid.mediaPlay(\"/sdcard/music.mp3\", tag=\"music\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.mediaIsPlaying(\"music\").result:\n    info = droid.mediaPlayInfo(\"music\").result\n    print(f\"Playing: {info}\")\n\n# \u8df3\u8f6c\u5230 30 \u79d2\ndroid.mediaPlaySeek(30000, \"music\")\n\n# \u5173\u95ed\ndroid.mediaPlayClose(\"music\")\n\n# \u64ad\u653e\u89c6\u9891\ndroid.videoPlay(\"/sdcard/movie.mp4\", wait=True)\n
    "},{"location":"qsl4a/special/cipher/","title":"\u5bc6\u7801 API","text":"

    \u7528\u4e8e\u5b89\u5168\u6570\u636e\u5b58\u50a8\u7684\u52a0\u5bc6\u548c\u89e3\u5bc6\u5de5\u5177\u3002

    "},{"location":"qsl4a/special/cipher/#_1","title":"\u521d\u59cb\u5316","text":""},{"location":"qsl4a/special/cipher/#cipherinit","title":"cipherInit()","text":"

    \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u548c\u7b97\u6cd5\u521d\u59cb\u5316\u5bc6\u7801\u5668\u3002

    cipherInit(key, algorithm=\"AES/CBC/PKCS5Padding\", encodingFormat=\"\", initialVector=\"\")\n

    \u53c2\u6570\uff1a - key (str or bytes): \u52a0\u5bc6\u5bc6\u94a5 - algorithm (str): \u5bc6\u7801\u7b97\u6cd5\uff08\u9ed8\u8ba4\uff1a\"AES/CBC/PKCS5Padding\"\uff09 - encodingFormat (str): \u7f16\u7801\u683c\u5f0f - initialVector (str or bytes): \u52a0\u5bc6\u7684\u521d\u59cb\u5411\u91cf

    \u8fd4\u56de\uff1a \u521d\u59cb\u5316\u7ed3\u679c

    \u6ce8\u610f\uff1a \u5fc5\u987b\u5728\u4efb\u4f55\u52a0\u5bc6/\u89e3\u5bc6\u64cd\u4f5c\u4e4b\u524d\u8c03\u7528\u3002

    "},{"location":"qsl4a/special/cipher/#_2","title":"\u52a0\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#encryptstring","title":"encryptString()","text":"

    \u52a0\u5bc6\u5b57\u7b26\u4e32\u3002

    encryptString(plainText)\n

    \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c

    \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/special/cipher/#encryptbytes","title":"encryptBytes()","text":"

    \u52a0\u5bc6\u5b57\u8282\u6570\u636e\u3002

    encryptBytes(data)\n

    \u53c2\u6570\uff1a - data (bytes): \u8981\u52a0\u5bc6\u7684\u6570\u636e

    \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u8282

    "},{"location":"qsl4a/special/cipher/#encryptstringtofile","title":"encryptStringToFile()","text":"

    \u52a0\u5bc6\u5b57\u7b26\u4e32\u5230\u6587\u4ef6\u3002

    encryptStringToFile(plainText, filePath)\n

    \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c - filePath (str): \u8f93\u51fa\u6587\u4ef6\u8def\u5f84

    "},{"location":"qsl4a/special/cipher/#encryptbytestofile","title":"encryptBytesToFile()","text":"

    \u52a0\u5bc6\u5b57\u8282\u5230\u6587\u4ef6\u3002

    encryptBytesToFile(data, filePath)\n
    "},{"location":"qsl4a/special/cipher/#_3","title":"\u89e3\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#decryptstring","title":"decryptString()","text":"

    \u89e3\u5bc6\u4e3a\u5b57\u7b26\u4e32\u3002

    decryptString(cipherText)\n

    \u53c2\u6570\uff1a - cipherText (str): \u52a0\u5bc6\u7684\u6587\u672c

    \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/special/cipher/#decryptbytes","title":"decryptBytes()","text":"

    \u89e3\u5bc6\u4e3a\u5b57\u8282\u3002

    decryptBytes(data)\n

    \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u8282

    "},{"location":"qsl4a/special/cipher/#decryptfiletostring","title":"decryptFileToString()","text":"

    \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u7b26\u4e32\u3002

    decryptFileToString(filePath)\n
    "},{"location":"qsl4a/special/cipher/#decryptfiletobytes","title":"decryptFileToBytes()","text":"

    \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u8282\u3002

    decryptFileToBytes(filePath)\n
    "},{"location":"qsl4a/special/cipher/#decryptfile","title":"decryptFile()","text":"

    \u89e3\u5bc6\u6587\u4ef6\u5230\u6587\u4ef6\u3002

    decryptFile(srcPath, destPath)\n
    "},{"location":"qsl4a/special/cipher/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u521d\u59cb\u5316\u5bc6\u7801\u5668\ndroid.cipherInit(\"my_secret_key_1234\")\n\n# \u52a0\u5bc6\u5b57\u7b26\u4e32\nencrypted = droid.encryptString(\"Secret message!\").result\nprint(f\"Encrypted: {encrypted}\")\n\n# \u89e3\u5bc6\u5b57\u7b26\u4e32\ndecrypted = droid.decryptString(encrypted).result\nprint(f\"Decrypted: {decrypted}\")\n\n# \u52a0\u5bc6\u5230\u6587\u4ef6\ndroid.encryptStringToFile(\"My secret data\", \"/sdcard/secret.dat\")\n\n# \u4ece\u6587\u4ef6\u89e3\u5bc6\ndata = droid.decryptFileToString(\"/sdcard/secret.dat\").result\nprint(data)\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u7b97\u6cd5\u548c IV \u521d\u59cb\u5316\ndroid.cipherInit(\n    key=\"my_key\",\n    algorithm=\"AES/CBC/PKCS5Padding\",\n    initialVector=\"0123456789abcdef\"\n)\n
    "},{"location":"qsl4a/special/pgptai/","title":"PGPT AI API","text":"

    \u8bed\u97f3\u8f6c\u6587\u672c\u548c AI \u670d\u52a1\u96c6\u6210\u3002

    "},{"location":"qsl4a/special/pgptai/#_1","title":"\u5148\u51b3\u6761\u4ef6","text":"
    pip install pgptAI\n
    "},{"location":"qsl4a/special/pgptai/#_2","title":"\u8bed\u97f3\u8bc6\u522b","text":""},{"location":"qsl4a/special/pgptai/#speechtotext","title":"speechToText()","text":"

    \u5c06\u8bed\u97f3\u8f6c\u6362\u4e3a\u6587\u672c\u3002

    speechToText(RecordSecond=10, AmrFile=None, Language=None)\n

    \u53c2\u6570\uff1a - RecordSecond (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09 - AmrFile (str, optional): \u73b0\u6709\u97f3\u9891\u6587\u4ef6\u8def\u5f84 - Language (str, optional): \u8bed\u8a00\u4ee3\u7801\uff08'en'\u3001'zh'\uff09

    \u8fd4\u56de\uff1a \u8f6c\u5f55\u7684\u6587\u672c

    "},{"location":"qsl4a/special/pgptai/#_3","title":"\u6587\u672c\u8f6c\u8bed\u97f3","text":""},{"location":"qsl4a/special/pgptai/#texttospeech","title":"textToSpeech()","text":"

    \u5c06\u6587\u672c\u8f6c\u6362\u4e3a\u8bed\u97f3\u5e76\u53ef\u9009\u5730\u64ad\u653e\u3002

    textToSpeech(Text, AutoPlay=True, WavFile=None, VoiceName=None)\n

    \u53c2\u6570\uff1a - Text (str): \u8981\u8f6c\u6362\u4e3a\u8bed\u97f3\u7684\u6587\u672c - AutoPlay (bool): \u81ea\u52a8\u64ad\u653e\u751f\u6210\u7684\u97f3\u9891\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - WavFile (str, optional): \u4fdd\u5b58 WAV \u6587\u4ef6\u7684\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u4e34\u65f6\u6587\u4ef6 - VoiceName (str, optional): \u8981\u4f7f\u7528\u7684\u8bed\u97f3\u540d\u79f0\uff08\u4f8b\u5982 'en-US-JennyNeural'\u3001'zh-CN-XiaoxiaoNeural'\uff09

    \u8fd4\u56de\uff1a \u5305\u542b\u8bed\u97f3\u5408\u6210\u7ed3\u679c\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - text: \u8f93\u5165\u6587\u672c - url: \u4e0b\u8f7d\u97f3\u9891\u6587\u4ef6\u7684 URL - WavFile: \u4fdd\u5b58\u7684 WAV \u6587\u4ef6\u8def\u5f84\uff08\u5982\u679c\u672c\u5730\u4fdd\u5b58\uff09

    "},{"location":"qsl4a/special/pgptai/#_4","title":"\u914d\u7f6e","text":"

    API \u4f7f\u7528\u4ee5\u4e0b\u914d\u7f6e\u6587\u4ef6\u4e2d\u7684\u914d\u7f6e\uff1a/storage/emulated/0/Android/data/org.qpython.qpy/files/apigpt.conf\uff1a

    [speech]\nspeech_key = your_api_key\n

    \u9ed8\u8ba4\u8bed\u97f3\u8bbe\u7f6e\uff1a - \u82f1\u8bed\uff1aen-US-JennyNeural - \u4e2d\u6587\uff1azh-CN-XiaoxiaoNeural

    "},{"location":"qsl4a/special/pgptai/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5f55\u5236\u5e76\u8f6c\u5f55\nprint(\"Recording for 5 seconds...\")\ntext = droid.speechToText(RecordSecond=5, Language='en').result\nprint(f\"You said: {text}\")\n\n# \u8f6c\u5f55\u73b0\u6709\u6587\u4ef6\ntext = droid.speechToText(AmrFile=\"/sdcard/recording.amr\").result\nprint(f\"Transcription: {text}\")\n\n# \u6587\u672c\u8f6c\u8bed\u97f3\ndroid.textToSpeech(\"Hello, this is a test message.\", AutoPlay=True, Language='en')\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u8bed\u97f3\u5e76\u4fdd\u5b58\u5230\u6587\u4ef6\u7684\u6587\u672c\u8f6c\u8bed\u97f3\nresult = droid.textToSpeech(\n    \"Welcome to QPython!\",\n    AutoPlay=False,\n    WavFile=\"/sdcard/welcome.wav\",\n    VoiceName=\"en-US-JennyNeural\"\n).result\nprint(f\"Audio saved to: {result.get('WavFile')}\")\n
    "},{"location":"qsl4a/special/pgptai/#_6","title":"\u7c7b\u4f7f\u7528","text":"
    from androidhelper.pgptai import pgptai\nimport androidhelper\n\ndroid = androidhelper.Android()\nai = pgptai(droid)\n\n# \u4f7f\u7528\u8bed\u97f3\u8bc6\u522b\ntext = ai.speechToText(RecordSecond=10)\n
    "},{"location":"qsl4a/storage/clipboard/","title":"\u526a\u8d34\u677f API","text":"

    \u590d\u5236\u548c\u7c98\u8d34\u6587\u672c\u5230\u7cfb\u7edf\u526a\u8d34\u677f\u3002

    "},{"location":"qsl4a/storage/clipboard/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/clipboard/#setclipboard","title":"setClipboard()","text":"

    \u590d\u5236\u6587\u672c\u5230\u526a\u8d34\u677f\u3002

    setClipboard(text)\n

    \u53c2\u6570\uff1a - text (str): \u8981\u590d\u5236\u7684\u6587\u672c

    \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/storage/clipboard/#getclipboard","title":"getClipboard()","text":"

    \u4ece\u526a\u8d34\u677f\u83b7\u53d6\u6587\u672c\u3002

    getClipboard()\n

    \u8fd4\u56de\uff1a \u526a\u8d34\u677f\u6587\u672c

    "},{"location":"qsl4a/storage/clipboard/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u590d\u5236\u5230\u526a\u8d34\u677f\ndroid.setClipboard(\"Hello from QPython!\")\n\n# \u4ece\u526a\u8d34\u677f\u7c98\u8d34\ntext = droid.getClipboard().result\nprint(f\"Clipboard: {text}\")\n
    "},{"location":"qsl4a/storage/documentfile/","title":"DocumentFile API","text":"

    \u4f7f\u7528 SAF\uff08\u5b58\u50a8\u8bbf\u95ee\u6846\u67b6\uff09\u8fdb\u884c\u6587\u4ef6\u64cd\u4f5c\uff0c\u652f\u6301 Android 4.4+\u3002

    "},{"location":"qsl4a/storage/documentfile/#_1","title":"\u76ee\u5f55\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilemkdir","title":"documentFileMkdir()","text":"

    \u521b\u5efa\u76ee\u5f55\u3002

    documentFileMkdir(Dir)\n

    \u53c2\u6570\uff1a - Dir (str): \u76ee\u5f55\u8def\u5f84

    \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/storage/documentfile/#documentfilelistfiles","title":"documentFileListFiles()","text":"

    \u5217\u51fa\u76ee\u5f55\u4e2d\u7684\u6587\u4ef6\u3002

    documentFileListFiles(Folder)\n

    \u8fd4\u56de\uff1a \u6587\u4ef6\u5217\u8868

    "},{"location":"qsl4a/storage/documentfile/#_2","title":"\u6587\u4ef6\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileexists","title":"documentFileExists()","text":"

    \u68c0\u67e5\u6587\u4ef6\u6216\u76ee\u5f55\u662f\u5426\u5b58\u5728\u3002

    documentFileExists(path)\n

    \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u6216\u76ee\u5f55\u8def\u5f84

    \u8fd4\u56de\uff1a \u5982\u679c\u5b58\u5728\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

    "},{"location":"qsl4a/storage/documentfile/#documentfileisfile","title":"documentFileIsFile()","text":"

    \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u6587\u4ef6\u3002

    documentFileIsFile(path)\n

    \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

    \u8fd4\u56de\uff1a \u5982\u679c\u662f\u6587\u4ef6\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u6587\u4ef6\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

    "},{"location":"qsl4a/storage/documentfile/#documentfileisdirectory","title":"documentFileIsDirectory()","text":"

    \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u76ee\u5f55\u3002

    documentFileIsDirectory(path)\n

    \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

    \u8fd4\u56de\uff1a \u5982\u679c\u662f\u76ee\u5f55\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u76ee\u5f55\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

    "},{"location":"qsl4a/storage/documentfile/#documentfiledelete","title":"documentFileDelete()","text":"

    \u5220\u9664\u6587\u4ef6\u6216\u76ee\u5f55\u3002

    documentFileDelete(FileOrTree)\n

    \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/storage/documentfile/#documentfilerenameto","title":"documentFileRenameTo()","text":"

    \u91cd\u547d\u540d\u6216\u79fb\u52a8\u6587\u4ef6\u3002

    documentFileRenameTo(Src, Dest)\n

    \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/storage/documentfile/#documentfilecopy","title":"documentFileCopy()","text":"

    \u590d\u5236\u6587\u4ef6\u3002

    documentFileCopy(SrcFileOrTree, DestFileOrTree)\n
    "},{"location":"qsl4a/storage/documentfile/#_3","title":"\u6d41\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileinputstream","title":"documentFileInputStream()","text":"

    \u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9\u3002

    documentFileInputStream(srcFile, EncodingFormat=\"\", skip=None, length=None)\n

    \u53c2\u6570\uff1a - srcFile (str): \u6e90\u6587\u4ef6 - EncodingFormat (str): \"UTF-8\"\u3001\"GBK\"\u3001\"Base64\" \u6216\u7a7a\u5b57\u7b26\u4e32\u8868\u793a\u5b57\u8282 - skip (int): \u4ece\u5f00\u5934\u8df3\u8fc7\u7684\u5b57\u8282\u6570 - length (int): \u8bfb\u53d6\u957f\u5ea6

    \u8fd4\u56de\uff1a \u6587\u4ef6\u5185\u5bb9

    "},{"location":"qsl4a/storage/documentfile/#documentfileoutputstream","title":"documentFileOutputStream()","text":"

    \u5199\u5165\u6587\u4ef6\u5185\u5bb9\u3002

    documentFileOutputStream(destFile, src, EncodingFormat=\"\", append=None)\n

    \u53c2\u6570\uff1a - destFile (str): \u76ee\u6807\u6587\u4ef6 - src: \u8981\u5199\u5165\u7684\u6570\u636e - EncodingFormat (str): \u7f16\u7801\u683c\u5f0f - append (bool): \u8ffd\u52a0\u6a21\u5f0f

    "},{"location":"qsl4a/storage/documentfile/#_4","title":"\u6587\u4ef6\u4fe1\u606f","text":""},{"location":"qsl4a/storage/documentfile/#documentfilelength","title":"documentFileLength()","text":"

    \u83b7\u53d6\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\u3002

    documentFileLength(path)\n

    \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

    \u8fd4\u56de\uff1a \u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

    "},{"location":"qsl4a/storage/documentfile/#documentfilelastmodified","title":"documentFileLastModified()","text":"

    \u83b7\u53d6\u6700\u540e\u4fee\u6539\u65f6\u95f4\u3002

    documentFileLastModified(path)\n

    \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

    \u8fd4\u56de\uff1a \u65f6\u95f4\u6233\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

    "},{"location":"qsl4a/storage/documentfile/#documentfilegetstat","title":"documentFileGetStat()","text":"

    \u83b7\u53d6\u5168\u9762\u7684\u6587\u4ef6\u7edf\u8ba1\u4fe1\u606f\u3002

    documentFileGetStat(path)\n

    \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

    \u8fd4\u56de\uff1a \u5305\u542b\u957f\u5ea6\u3001\u6700\u540e\u4fee\u6539\u65f6\u95f4\u548c\u8bfb/\u5199\u6743\u9650\u7684\u5b57\u5178\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

    "},{"location":"qsl4a/storage/documentfile/#uri","title":"URI \u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilegeturi","title":"documentFileGetUri()","text":"

    \u4ece\u8def\u5f84\u83b7\u53d6 URI\u3002

    documentFileGetUri(path, isDirectory=None)\n
    "},{"location":"qsl4a/storage/documentfile/#documentfileshowopen","title":"documentFileShowOpen()","text":"

    \u663e\u793a\u6587\u4ef6\u9009\u62e9\u5668\u3002

    documentFileShowOpen()\n

    \u8fd4\u56de\uff1a \u9009\u62e9\u7684\u6587\u4ef6 URI

    "},{"location":"qsl4a/storage/documentfile/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u76ee\u5f55\ndroid.documentFileMkdir(\"/sdcard/MyFolder\")\n\n# \u5217\u51fa\u6587\u4ef6\nfiles = droid.documentFileListFiles(\"/sdcard\").result\nfor f in files:\n    print(f)\n\n# \u8bfb\u53d6\u6587\u4ef6\ncontent = droid.documentFileInputStream(\n    \"/sdcard/test.txt\",\n    EncodingFormat=\"UTF-8\"\n).result\nprint(content)\n\n# \u5199\u5165\u6587\u4ef6\ndroid.documentFileOutputStream(\n    \"/sdcard/output.txt\",\n    \"Hello World\",\n    EncodingFormat=\"UTF-8\"\n)\n
    "},{"location":"qsl4a/storage/preferences/","title":"\u504f\u597d\u8bbe\u7f6e API","text":"

    \u4f7f\u7528 Android SharedPreferences \u5b58\u50a8\u548c\u68c0\u7d22\u6570\u636e\u3002

    "},{"location":"qsl4a/storage/preferences/#_1","title":"\u504f\u597d\u8bbe\u7f6e\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/preferences/#prefgetvalue","title":"prefGetValue()","text":"

    \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u8bfb\u53d6\u503c\u3002

    prefGetValue(key, filename=None)\n

    \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

    \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c\uff08\u4efb\u610f\u7c7b\u578b\uff09

    "},{"location":"qsl4a/storage/preferences/#prefputvalue","title":"prefPutValue()","text":"

    \u5199\u5165\u503c\u5230\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u3002

    prefPutValue(key, value, filename=None)\n

    \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - value (object): \u8981\u5b58\u50a8\u7684\u503c - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

    "},{"location":"qsl4a/storage/preferences/#prefgetall","title":"prefGetAll()","text":"

    \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\u503c\u3002

    prefGetAll(filename=None)\n

    \u53c2\u6570\uff1a - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

    \u8fd4\u56de\uff1a \u6240\u6709\u504f\u597d\u7684\u6620\u5c04

    "},{"location":"qsl4a/storage/preferences/#prefremovevalue","title":"prefRemoveValue()","text":"

    \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u4e2d\u79fb\u9664\u503c\u3002

    prefRemoveValue(key, filename=None)\n

    \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

    "},{"location":"qsl4a/storage/preferences/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b58\u50a8\u503c\ndroid.prefPutValue(\"username\", \"alice\")\ndroid.prefPutValue(\"score\", 100)\ndroid.prefPutValue(\"enabled\", True)\n\n# \u8bfb\u53d6\u7279\u5b9a\u503c\nusername = droid.prefGetValue(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\nall_prefs = droid.prefGetAll().result\nprint(f\"All prefs: {all_prefs}\")\n\n# \u79fb\u9664\u503c\ndroid.prefRemoveValue(\"score\")\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u6587\u4ef6\u540d\ndroid.prefPutValue(\"token\", \"abc123\", filename=\"auth.prefs\")\ntoken = droid.prefGetValue(\"token\", filename=\"auth.prefs\").result\n
    "},{"location":"qsl4a/system/activityresult/","title":"Activity Result API","text":"

    \u4e3a\u901a\u8fc7 startActivityForResult \u542f\u52a8\u7684\u811a\u672c\u8bbe\u7f6e activity \u7ed3\u679c\u3002

    "},{"location":"qsl4a/system/activityresult/#_1","title":"\u7ed3\u679c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/activityresult/#setresultboolean","title":"setResultBoolean()","text":"

    \u8bbe\u7f6e\u5e03\u5c14\u7ed3\u679c\u3002

    setResultBoolean(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (bool): \u5e03\u5c14\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#setresultbyte","title":"setResultByte()","text":"

    \u8bbe\u7f6e\u5b57\u8282\u7ed3\u679c\u3002

    setResultByte(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u5b57\u8282\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#setresultshort","title":"setResultShort()","text":"

    \u8bbe\u7f6e\u77ed\u6574\u6570\u7ed3\u679c\u3002

    setResultShort(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u77ed\u6574\u6570\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#setresultchar","title":"setResultChar()","text":"

    \u8bbe\u7f6e\u5b57\u7b26\u7ed3\u679c\u3002

    setResultChar(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#setresultinteger","title":"setResultInteger()","text":"

    \u8bbe\u7f6e\u6574\u6570\u7ed3\u679c\u3002

    setResultInteger(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u6574\u6570\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#setresultlong","title":"setResultLong()","text":"

    \u8bbe\u7f6e\u957f\u6574\u6570\u7ed3\u679c\u3002

    setResultLong(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u957f\u6574\u6570\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#setresultfloat","title":"setResultFloat()","text":"

    \u8bbe\u7f6e\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

    setResultFloat(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u6d6e\u70b9\u6570\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#setresultdouble","title":"setResultDouble()","text":"

    \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

    setResultDouble(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#setresultstring","title":"setResultString()","text":"

    \u8bbe\u7f6e\u5b57\u7b26\u4e32\u7ed3\u679c\u3002

    setResultString(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u4e32\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#setresultbooleanarray","title":"setResultBooleanArray()","text":"

    \u8bbe\u7f6e\u5e03\u5c14\u6570\u7ec4\u7ed3\u679c\u3002

    setResultBooleanArray(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5e03\u5c14\u6570\u7ec4

    "},{"location":"qsl4a/system/activityresult/#setresultbytearray","title":"setResultByteArray()","text":"

    \u8bbe\u7f6e\u5b57\u8282\u6570\u7ec4\u7ed3\u679c\u3002

    setResultByteArray(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u8282\u6570\u7ec4

    "},{"location":"qsl4a/system/activityresult/#setresultshortarray","title":"setResultShortArray()","text":"

    \u8bbe\u7f6e\u77ed\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

    setResultShortArray(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u77ed\u6574\u6570\u6570\u7ec4

    "},{"location":"qsl4a/system/activityresult/#setresultchararray","title":"setResultCharArray()","text":"

    \u8bbe\u7f6e\u5b57\u7b26\u6570\u7ec4\u7ed3\u679c\u3002

    setResultCharArray(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u6570\u7ec4

    "},{"location":"qsl4a/system/activityresult/#setresultintegerarray","title":"setResultIntegerArray()","text":"

    \u8bbe\u7f6e\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

    setResultIntegerArray(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6574\u6570\u6570\u7ec4

    "},{"location":"qsl4a/system/activityresult/#setresultlongarray","title":"setResultLongArray()","text":"

    \u8bbe\u7f6e\u957f\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

    setResultLongArray(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u957f\u6574\u6570\u6570\u7ec4

    "},{"location":"qsl4a/system/activityresult/#setresultfloatarray","title":"setResultFloatArray()","text":"

    \u8bbe\u7f6e\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

    setResultFloatArray(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6d6e\u70b9\u6570\u6570\u7ec4

    "},{"location":"qsl4a/system/activityresult/#setresultdoublearray","title":"setResultDoubleArray()","text":"

    \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

    setResultDoubleArray(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4

    "},{"location":"qsl4a/system/activityresult/#setresultstringarray","title":"setResultStringArray()","text":"

    \u8bbe\u7f6e\u5b57\u7b26\u4e32\u6570\u7ec4\u7ed3\u679c\u3002

    setResultStringArray(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u4e32\u6570\u7ec4

    "},{"location":"qsl4a/system/activityresult/#setresultserializable","title":"setResultSerializable()","text":"

    \u8bbe\u7f6e\u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u3002

    setResultSerializable(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue: \u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c activity \u540e\uff0c\u8bbe\u7f6e\u7ed3\u679c\n# \u793a\u4f8b\uff1a\u8fd4\u56de\u6210\u529f\u53ca\u6570\u636e\ndroid.setResultInteger(0, 200)  # RESULT_OK\ndroid.setResultString(0, \"Operation completed successfully\")\n\n# \u8fd4\u56de\u6570\u7ec4\u7ed3\u679c\ndroid.setResultIntegerArray(0, [1, 2, 3, 4, 5])\n
    "},{"location":"qsl4a/system/application/","title":"\u5e94\u7528\u7ba1\u7406","text":"

    \u7ba1\u7406\u5e94\u7528\u7a0b\u5e8f\u3001\u542f\u52a8\u5e94\u7528\u548c\u67e5\u8be2\u7cfb\u7edf\u4fe1\u606f\u3002

    "},{"location":"qsl4a/system/application/#_2","title":"\u5e94\u7528\u7a0b\u5e8f\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getapplicationinfo","title":"getApplicationInfo()","text":"

    \u83b7\u53d6\u5e94\u7528\u4fe1\u606f\u3002

    getApplicationInfo(packageName=None)\n

    \u53c2\u6570\uff1a - packageName (str): \u5305\u540d\uff08None = \u5f53\u524d\u5e94\u7528\uff09

    \u8fd4\u56de\uff1a \u5e94\u7528\u4fe1\u606f\u5b57\u5178

    "},{"location":"qsl4a/system/application/#getinstalledpackages","title":"getInstalledPackages()","text":"

    \u83b7\u53d6\u5df2\u5b89\u88c5\u5305\u5217\u8868\u3002

    getInstalledPackages(flag=4)\n

    \u53c2\u6570\uff1a - flag (int): \u5305\u6807\u5fd7\u8fc7\u6ee4\u5668\uff08\u9ed8\u8ba4\uff1a4\uff09

    \u8fd4\u56de\uff1a \u5df2\u5b89\u88c5\u5305\u5217\u8868

    "},{"location":"qsl4a/system/application/#getrunningpackages","title":"getRunningPackages()","text":"

    \u5217\u51fa\u6b63\u5728\u8fd0\u884c\u7684\u5305\u3002

    getRunningPackages()\n

    \u8fd4\u56de\uff1a \u5305\u540d\u5217\u8868

    "},{"location":"qsl4a/system/application/#getlaunchablepackages","title":"getLaunchablePackages()","text":"

    \u83b7\u53d6\u53ef\u542f\u52a8\u5305\u5217\u8868\u3002

    getLaunchablePackages(needClassName=False)\n

    \u53c2\u6570\uff1a - needClassName (bool): \u5305\u542b\u4e3b activity \u7c7b\u540d\uff08\u9ed8\u8ba4\uff1aFalse\uff09

    \u8fd4\u56de\uff1a \u53ef\u542f\u52a8\u5305\u540d\u5217\u8868\u6216\u5305\u542b\u7c7b\u540d\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/application/#_3","title":"\u5e94\u7528\u63a7\u5236","text":""},{"location":"qsl4a/system/application/#launch","title":"launch()","text":"

    \u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u3002

    launch(classname=None, packagename=None, wait=True)\n

    \u53c2\u6570\uff1a - classname (str): \u4e3b activity \u7c7b\u540d - packagename (str): \u5305\u540d - wait (bool): \u7b49\u5f85\u542f\u52a8\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

    \u8fd4\u56de\uff1a \u542f\u52a8\u7ed3\u679c

    "},{"location":"qsl4a/system/application/#forcestoppackage","title":"forceStopPackage()","text":"

    \u5f3a\u5236\u505c\u6b62\u5e94\u7528\u7a0b\u5e8f\u3002

    forceStopPackage(packageName)\n

    \u53c2\u6570\uff1a - packageName (str): \u8981\u505c\u6b62\u7684\u5305\u540d

    "},{"location":"qsl4a/system/application/#_4","title":"\u7248\u672c\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getpackageversion","title":"getPackageVersion()","text":"

    \u83b7\u53d6\u5e94\u7528\u7248\u672c\u540d\u79f0\u3002

    getPackageVersion(packageName)\n

    \u8fd4\u56de\uff1a \u7248\u672c\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"3.2.1\"\uff09

    "},{"location":"qsl4a/system/application/#getpackageversioncode","title":"getPackageVersionCode()","text":"

    \u83b7\u53d6\u5e94\u7528\u7248\u672c\u4ee3\u7801\u3002

    getPackageVersionCode(packageName)\n

    \u8fd4\u56de\uff1a \u7248\u672c\u4ee3\u7801\u6574\u6570

    "},{"location":"qsl4a/system/application/#getconstants","title":"getConstants()","text":"

    \u83b7\u53d6\u7c7b\u5e38\u91cf\u3002

    getConstants(classname)\n

    \u53c2\u6570\uff1a - classname (str): \u5b8c\u6574\u7c7b\u540d

    \u8fd4\u56de\uff1a \u5e38\u91cf\u540d\u548c\u503c\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/application/#_5","title":"\u7cfb\u7edf\u529f\u80fd","text":""},{"location":"qsl4a/system/application/#backgroundprotect","title":"backgroundProtect()","text":"

    \u542f\u7528\u6216\u7981\u7528\u5e94\u7528\u7684\u540e\u53f0\u4fdd\u62a4\u3002

    backgroundProtect(enabled=True)\n

    \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\u4fdd\u62a4\uff0cFalse \u7981\u7528

    "},{"location":"qsl4a/system/application/#createscriptshortcut","title":"createScriptShortCut()","text":"

    \u4e3a\u811a\u672c\u521b\u5efa\u4e3b\u5c4f\u5e55\u5feb\u6377\u65b9\u5f0f\u3002

    createScriptShortCut(scriptPath, label=None, iconPath=None, scriptArg=None)\n

    \u53c2\u6570\uff1a - scriptPath (str): Python \u811a\u672c\u8def\u5f84 - label (str, optional): \u5feb\u6377\u65b9\u5f0f\u6807\u7b7e - iconPath (str, optional): \u56fe\u6807\u56fe\u50cf\u8def\u5f84 - scriptArg (str, optional): \u4f20\u9012\u7ed9\u811a\u672c\u7684\u53c2\u6570

    "},{"location":"qsl4a/system/application/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getandroidid","title":"getAndroidID()","text":"

    \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

    getAndroidID()\n

    \u8fd4\u56de\uff1a \u552f\u4e00\u7684 Android \u8bbe\u5907 ID \u5b57\u7b26\u4e32

    "},{"location":"qsl4a/system/application/#getsysinfo","title":"getSysInfo()","text":"

    \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\u3002

    getSysInfo()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/application/#getlocale","title":"getLocale()","text":"

    \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u3002

    getLocale()\n

    \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

    "},{"location":"qsl4a/system/application/#getharmonyosinformation","title":"getHarmonyOsInformation()","text":"

    \u5982\u679c\u5728 HarmonyOS \u4e0a\u8fd0\u884c\uff0c\u83b7\u53d6 HarmonyOS \u4fe1\u606f\u3002

    getHarmonyOsInformation()\n

    \u8fd4\u56de\uff1a HarmonyOS \u7248\u672c\u4fe1\u606f\u6216 None

    "},{"location":"qsl4a/system/application/#isexternalstoragemanager","title":"isExternalStorageManager()","text":"

    \u68c0\u67e5\u5e94\u7528\u662f\u5426\u6709\u5916\u90e8\u5b58\u50a8\u7ba1\u7406\u5668\u6743\u9650\u3002

    isExternalStorageManager()\n

    \u8fd4\u56de\uff1a \u5982\u679c\u6709\u6743\u9650\u5219\u4e3a True

    "},{"location":"qsl4a/system/application/#_7","title":"\u5185\u5b58\u548c\u663e\u793a","text":""},{"location":"qsl4a/system/application/#getmemoryinfo","title":"getMemoryInfo()","text":"

    \u83b7\u53d6\u5185\u5b58\u4fe1\u606f\u3002

    getMemoryInfo()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/application/#getscreeninfo","title":"getScreenInfo()","text":"

    \u83b7\u53d6\u5c4f\u5e55\u4fe1\u606f\u3002

    getScreenInfo()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/application/#_8","title":"\u6743\u9650","text":""},{"location":"qsl4a/system/application/#checkpermissions","title":"checkPermissions()","text":"

    \u68c0\u67e5\u5f53\u524d\u5e94\u7528\u6743\u9650\u3002

    checkPermissions()\n

    \u8fd4\u56de\uff1a \u6743\u9650\u53ca\u5176\u72b6\u6001\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/application/#requestpermissions","title":"requestPermissions()","text":"

    \u5411\u7528\u6237\u8bf7\u6c42\u6743\u9650\u3002

    requestPermissions(permissions=None)\n

    \u53c2\u6570\uff1a - permissions (list, optional): \u8981\u8bf7\u6c42\u7684\u6743\u9650\u5217\u8868\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8bf7\u6c42\u6240\u6709\u9700\u8981\u7684\u6743\u9650\u3002

    \u8fd4\u56de\uff1a \u6743\u9650\u8bf7\u6c42\u7ed3\u679c

    "},{"location":"qsl4a/system/application/#_9","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/system/application/#showscreenlock","title":"showScreenLock()","text":"

    \u663e\u793a\u5c4f\u5e55\u9501\u5b9a\uff08PIN/\u56fe\u6848/\u5bc6\u7801\u8f93\u5165\uff09\u3002

    showScreenLock()\n
    "},{"location":"qsl4a/system/application/#_10","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\ninfo = droid.getSysInfo().result\nprint(f\"System: {info}\")\n\n# \u83b7\u53d6\u5e94\u7528\u7248\u672c\nversion = droid.getPackageVersion(\"org.qpython.qpy\").result\nprint(f\"QPython version: {version}\")\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u5e94\u7528\napps = droid.getInstalledPackages().result\nprint(f\"Installed apps: {len(apps)}\")\n\n# \u542f\u52a8\u5e94\u7528\ndroid.launch(packagename=\"com.android.settings\")\n\n# \u68c0\u67e5\u6743\u9650\nperms = droid.checkPermissions().result\nprint(f\"Permissions: {perms}\")\n\n# \u8bf7\u6c42\u5b58\u50a8\u6743\u9650\ndroid.requestPermissions([\"android.permission.READ_EXTERNAL_STORAGE\"])\n\n# \u521b\u5efa\u5feb\u6377\u65b9\u5f0f\ndroid.createScriptShortCut(\n    \"/sdcard/my_script.py\",\n    label=\"My Script\",\n    iconPath=\"/sdcard/icon.png\"\n)\n
    "},{"location":"qsl4a/system/battery/","title":"\u7535\u6c60 API","text":"

    \u76d1\u63a7\u8bbe\u5907\u7535\u6c60\u72b6\u6001\u548c\u5065\u5eb7\u72b6\u51b5\u3002

    "},{"location":"qsl4a/system/battery/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/battery/#readbatterydata","title":"readBatteryData()","text":"

    \u83b7\u53d6\u5b8c\u6574\u7684\u7535\u6c60\u4fe1\u606f\u3002

    readBatteryData()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u7535\u6c60\u6570\u636e\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/battery/#batterystartmonitoring","title":"batteryStartMonitoring()","text":"

    \u5f00\u59cb\u7535\u6c60\u76d1\u63a7\u3002

    batteryStartMonitoring()\n
    "},{"location":"qsl4a/system/battery/#batterystopmonitoring","title":"batteryStopMonitoring()","text":"

    \u505c\u6b62\u7535\u6c60\u76d1\u63a7\u3002

    batteryStopMonitoring()\n
    "},{"location":"qsl4a/system/battery/#batterygetlevel","title":"batteryGetLevel()","text":"

    \u83b7\u53d6\u7535\u6c60\u767e\u5206\u6bd4\u3002

    batteryGetLevel()\n

    \u8fd4\u56de\uff1a \u6574\u6570\uff080-100\uff09

    "},{"location":"qsl4a/system/battery/#batterygetstatus","title":"batteryGetStatus()","text":"

    \u83b7\u53d6\u5145\u7535\u72b6\u6001\u3002

    batteryGetStatus()\n

    \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u5145\u7535\u4e2d - 3: \u653e\u7535\u4e2d - 4: \u672a\u5145\u7535 - 5: \u5df2\u5145\u6ee1

    "},{"location":"qsl4a/system/battery/#batterygetplugtype","title":"batteryGetPlugType()","text":"

    \u83b7\u53d6\u7535\u6e90\u7c7b\u578b\u3002

    batteryGetPlugType()\n

    \u8fd4\u56de\uff1a - -1: \u672a\u77e5 - 0: \u672a\u63d2\u7535 - 1: AC \u5145\u7535\u5668 - 2: USB \u7aef\u53e3

    "},{"location":"qsl4a/system/battery/#batterygethealth","title":"batteryGetHealth()","text":"

    \u83b7\u53d6\u7535\u6c60\u5065\u5eb7\u72b6\u51b5\u3002

    batteryGetHealth()\n

    \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u826f\u597d - 3: \u8fc7\u70ed - 4: \u635f\u574f - 5: \u8fc7\u538b - 6: \u672a\u6307\u5b9a\u7684\u6545\u969c

    "},{"location":"qsl4a/system/battery/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\nlevel = droid.batteryGetLevel().result\nprint(f\"Battery: {level}%\")\n
    "},{"location":"qsl4a/system/qpyinterface/","title":"QPython \u63a5\u53e3 API","text":"

    \u4ece\u5176\u4ed6\u5e94\u7528\u6267\u884c QPython \u811a\u672c\u548c\u7ba1\u7406\u5171\u4eab\u53d8\u91cf\u3002

    "},{"location":"qsl4a/system/qpyinterface/#_1","title":"\u811a\u672c\u6267\u884c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/qpyinterface/#executeqpy","title":"executeQPy()","text":"

    \u6267\u884c QPython \u811a\u672c\u3002

    executeQPy(path=\"\", arg=None)\n

    \u53c2\u6570\uff1a - path (str): \u811a\u672c\u6587\u4ef6\u8def\u5f84 - arg (str, optional): \u547d\u4ee4\u884c\u53c2\u6570

    \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/system/qpyinterface/#executeqpyassrv","title":"executeQPyAsSrv()","text":"

    \u4f5c\u4e3a\u670d\u52a1\u6267\u884c QPython \u811a\u672c\u3002

    executeQPyAsSrv(path=None)\n

    \u53c2\u6570\uff1a - path (str, optional): \u811a\u672c\u6587\u4ef6\u8def\u5f84

    \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/system/qpyinterface/#executeqpycode","title":"executeQPyCode()","text":"

    \u76f4\u63a5\u6267\u884c Python \u4ee3\u7801\u3002

    executeQPyCode(code=None)\n

    \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

    \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/system/qpyinterface/#executeqpycodeassrv","title":"executeQPyCodeAsSrv()","text":"

    \u4f5c\u4e3a\u670d\u52a1\u6267\u884c Python \u4ee3\u7801\u3002

    executeQPyCodeAsSrv(code=None)\n

    \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

    \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/system/qpyinterface/#_2","title":"\u5171\u4eab\u53d8\u91cf","text":"

    \u5171\u4eab\u53d8\u91cf\u5141\u8bb8 QPython \u4e0e\u5176\u4ed6\u5e94\u7528\u4e4b\u95f4\u8fdb\u884c\u901a\u4fe1\u3002

    "},{"location":"qsl4a/system/qpyinterface/#sharedvariableset","title":"sharedVariableSet()","text":"

    \u8bbe\u7f6e Java \u5171\u4eab\u53d8\u91cf\u3002

    sharedVariableSet(key, value)\n

    \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d - value (str): \u53d8\u91cf\u503c

    \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

    "},{"location":"qsl4a/system/qpyinterface/#sharedvariableget","title":"sharedVariableGet()","text":"

    \u83b7\u53d6 Java \u5171\u4eab\u53d8\u91cf\u3002

    sharedVariableGet(key)\n

    \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d

    \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

    "},{"location":"qsl4a/system/qpyinterface/#sharedvariableremove","title":"sharedVariableRemove()","text":"

    \u79fb\u9664 Java \u5171\u4eab\u53d8\u91cf\u3002

    sharedVariableRemove(key)\n

    \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u53d8\u91cf\u540d

    \u8fd4\u56de\uff1a \u88ab\u79fb\u9664\u7684\u503c

    "},{"location":"qsl4a/system/qpyinterface/#getlastlog","title":"getLastLog()","text":"

    \u83b7\u53d6 QPython \u7684\u6700\u540e\u65e5\u5fd7\u8f93\u51fa\u3002

    getLastLog()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u65e5\u5fd7\u5185\u5bb9

    "},{"location":"qsl4a/system/qpyinterface/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c\u811a\u672c\ndroid.executeQPy(\"/sdcard/my_script.py\", arg=\"test\")\n\n# \u76f4\u63a5\u6267\u884c\u4ee3\u7801\ncode = \"print('Hello from QPython!')\"\ndroid.executeQPyCode(code)\n\n# \u4f7f\u7528\u5171\u4eab\u53d8\u91cf\ndroid.sharedVariableSet(\"username\", \"alice\")\nusername = droid.sharedVariableGet(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u79fb\u9664\u53d8\u91cf\ndroid.sharedVariableRemove(\"username\")\n\n# \u83b7\u53d6\u6700\u8fd1\u65e5\u5fd7\nlog = droid.getLastLog().result\nprint(f\"Log: {log}\")\n
    "},{"location":"qsl4a/system/sensors/","title":"\u4f20\u611f\u5668 API","text":"

    \u8bbf\u95ee\u8bbe\u5907\u4f20\u611f\u5668\uff0c\u5305\u62ec\u52a0\u901f\u5ea6\u8ba1\u3001\u9640\u87ba\u4eea\u3001\u78c1\u529b\u8ba1\u7b49\u3002

    "},{"location":"qsl4a/system/sensors/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/sensors/#startsensingtimed","title":"startSensingTimed()","text":"

    \u5f00\u59cb\u4f20\u611f\u5668\u76d1\u63a7\u5e76\u8bbe\u7f6e\u65f6\u95f4\u95f4\u9694\u3002

    startSensingTimed(sensorNumber, delayTime)\n

    \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID\uff08\u901a\u5e38\u4e3a 1-3\uff09 - delayTime (int): \u8bfb\u53d6\u4e4b\u95f4\u7684\u5ef6\u8fdf\uff08\u6beb\u79d2\uff09

    "},{"location":"qsl4a/system/sensors/#startsensingthreshold","title":"startSensingThreshold()","text":"

    \u5f00\u59cb\u5e26\u9608\u503c\u89e6\u53d1\u7684\u4f20\u611f\u5668\u76d1\u63a7\u3002

    startSensingThreshold(sensorNumber, threshold, axis)\n

    \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID - threshold (float): \u89e6\u53d1\u9608\u503c - axis (int): \u8981\u76d1\u63a7\u7684\u8f74\uff080=X\uff0c1=Y\uff0c2=Z\uff09

    "},{"location":"qsl4a/system/sensors/#stopsensing","title":"stopSensing()","text":"

    \u505c\u6b62\u6240\u6709\u4f20\u611f\u5668\u76d1\u63a7\u3002

    stopSensing()\n
    "},{"location":"qsl4a/system/sensors/#readsensors","title":"readSensors()","text":"

    \u8bfb\u53d6\u5f53\u524d\u4f20\u611f\u5668\u6570\u636e\u3002

    readSensors()\n

    \u8fd4\u56de\uff1a \u4f20\u611f\u5668\u6570\u636e\u5b57\u5178

    "},{"location":"qsl4a/system/sensors/#sensorsreadaccelerometer","title":"sensorsReadAccelerometer()","text":"

    \u8bfb\u53d6\u52a0\u901f\u5ea6\u8ba1\u503c\u3002

    sensorsReadAccelerometer()\n

    \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d m/s\u00b2

    "},{"location":"qsl4a/system/sensors/#sensorsreadgyroscope","title":"sensorsReadGyroscope()","text":"

    \u8bfb\u53d6\u9640\u87ba\u4eea\u503c\u3002

    sensorsReadGyroscope()\n

    \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d rad/s

    "},{"location":"qsl4a/system/sensors/#sensorsreadmagnetometer","title":"sensorsReadMagnetometer()","text":"

    \u8bfb\u53d6\u78c1\u573a\u503c\u3002

    sensorsReadMagnetometer()\n

    \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d \u03bcT

    "},{"location":"qsl4a/system/sensors/#sensorsreadorientation","title":"sensorsReadOrientation()","text":"

    \u8bfb\u53d6\u8bbe\u5907\u65b9\u5411\u3002

    sensorsReadOrientation()\n

    \u8fd4\u56de\uff1a \u5217\u8868 [azimuth, pitch, roll]\uff0c\u5355\u4f4d\u5ea6

    "},{"location":"qsl4a/system/sensors/#sensorsgetlight","title":"sensorsGetLight()","text":"

    \u8bfb\u53d6\u5149\u4f20\u611f\u5668\u503c\u3002

    sensorsGetLight()\n

    \u8fd4\u56de\uff1a \u5149\u7ea7\u522b\uff08lux\uff09

    "},{"location":"qsl4a/system/sensors/#sensorsgetstepcounter","title":"sensorsGetStepCounter()","text":"

    \u8bfb\u53d6\u6b65\u8ba1\u6570\u5668\u3002

    sensorsGetStepCounter()\n

    \u8fd4\u56de\uff1a \u6b65\u6570

    "},{"location":"qsl4a/system/sensors/#sensorsgetaccuracy","title":"sensorsGetAccuracy()","text":"

    \u83b7\u53d6\u5f53\u524d\u4f20\u611f\u5668\u7cbe\u5ea6\u3002

    sensorsGetAccuracy()\n

    \u8fd4\u56de\uff1a \u7cbe\u5ea6\u503c\uff080-3\uff1aUNRELIABLE\u3001ACCURACY_LOW\u3001ACCURACY_MEDIUM\u3001ACCURACY_HIGH\uff09

    "},{"location":"qsl4a/system/sensors/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u8bfb\u53d6\u4f20\u611f\u5668 10 \u6b21\nfor i in range(10):\n    accel = droid.sensorsReadAccelerometer().result\n    print(f\"Accel: X={accel[0]:.2f}, Y={accel[1]:.2f}, Z={accel[2]:.2f}\")\n    time.sleep(0.5)\n\ndroid.stopSensing()\n
    "},{"location":"qsl4a/system/settings/","title":"\u8bbe\u7f6e API","text":"

    \u63a7\u5236\u7cfb\u7edf\u8bbe\u7f6e\uff0c\u5305\u62ec\u5c4f\u5e55\u3001\u58f0\u97f3\u548c\u7f51\u7edc\u8bbe\u7f6e\u3002

    "},{"location":"qsl4a/system/settings/#_1","title":"\u5c4f\u5e55\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#setscreentimeout","title":"setScreenTimeout()","text":"

    \u8bbe\u7f6e\u5c4f\u5e55\u8d85\u65f6\u503c\u3002

    setScreenTimeout(value)\n

    \u53c2\u6570\uff1a - value (int): \u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

    \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u8d85\u65f6\u503c

    "},{"location":"qsl4a/system/settings/#getscreentimeout","title":"getScreenTimeout()","text":"

    \u83b7\u53d6\u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u3002

    getScreenTimeout()\n

    \u8fd4\u56de\uff1a \u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

    "},{"location":"qsl4a/system/settings/#getscreenbrightness","title":"getScreenBrightness()","text":"

    \u83b7\u53d6\u5c4f\u5e55\u4eae\u5ea6\u503c\u3002

    getScreenBrightness()\n

    \u8fd4\u56de\uff1a \u4eae\u5ea6\u503c\uff080-255\uff09

    "},{"location":"qsl4a/system/settings/#setscreenbrightness","title":"setScreenBrightness()","text":"

    \u8bbe\u7f6e\u5c4f\u5e55\u4eae\u5ea6\u3002

    setScreenBrightness(value=None)\n

    \u53c2\u6570\uff1a - value (int, optional): \u4eae\u5ea6\u503c\uff080-255\uff09\uff0c\u6216 None \u8868\u793a\u81ea\u52a8

    \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u4eae\u5ea6\u503c

    "},{"location":"qsl4a/system/settings/#checkscreenon","title":"checkScreenOn()","text":"

    \u68c0\u67e5\u5c4f\u5e55\u662f\u5426\u4eae\u7740\u3002

    checkScreenOn()\n

    \u8fd4\u56de\uff1a \u5982\u679c\u5c4f\u5e55\u4eae\u7740\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

    "},{"location":"qsl4a/system/settings/#_2","title":"\u98de\u884c\u6a21\u5f0f","text":""},{"location":"qsl4a/system/settings/#checkairplanemode","title":"checkAirplaneMode()","text":"

    \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\u662f\u5426\u542f\u7528\u3002

    checkAirplaneMode()\n

    \u8fd4\u56de\uff1a \u5982\u679c\u98de\u884c\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

    "},{"location":"qsl4a/system/settings/#_3","title":"\u94c3\u58f0\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#checkringersilentmode","title":"checkRingerSilentMode()","text":"

    \u68c0\u67e5\u94c3\u58f0\u662f\u5426\u5904\u4e8e\u9759\u97f3\u6a21\u5f0f\u3002

    checkRingerSilentMode()\n

    \u8fd4\u56de\uff1a \u5982\u679c\u9759\u97f3\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

    "},{"location":"qsl4a/system/settings/#toggleringersilentmode","title":"toggleRingerSilentMode()","text":"

    \u5207\u6362\u94c3\u58f0\u9759\u97f3\u6a21\u5f0f\u3002

    toggleRingerSilentMode(enabled=None)\n

    \u53c2\u6570\uff1a - enabled (bool, optional): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

    \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

    "},{"location":"qsl4a/system/settings/#togglevibratemode","title":"toggleVibrateMode()","text":"

    \u5207\u6362\u632f\u52a8\u6a21\u5f0f\u3002

    toggleVibrateMode(enabled=None, ringer=None)\n

    \u53c2\u6570\uff1a - enabled (bool, optional): \u5207\u6362\u632f\u52a8\u5f00/\u5173 - ringer (bool, optional): \u5e94\u7528\u4e8e\u94c3\u58f0\u6a21\u5f0f

    \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

    "},{"location":"qsl4a/system/settings/#getvibratemode","title":"getVibrateMode()","text":"

    \u83b7\u53d6\u632f\u52a8\u6a21\u5f0f\u8bbe\u7f6e\u3002

    getVibrateMode(ringer=None)\n

    \u53c2\u6570\uff1a - ringer (bool, optional): \u68c0\u67e5\u94c3\u58f0\u632f\u52a8\u6a21\u5f0f

    \u8fd4\u56de\uff1a \u5982\u679c\u632f\u52a8\u5df2\u542f\u7528\u5219\u4e3a True

    "},{"location":"qsl4a/system/settings/#_4","title":"\u97f3\u91cf\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#getringervolume","title":"getRingerVolume()","text":"

    \u83b7\u53d6\u5f53\u524d\u94c3\u58f0\u97f3\u91cf\u3002

    getRingerVolume()\n

    \u8fd4\u56de\uff1a \u94c3\u58f0\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-7\uff09

    "},{"location":"qsl4a/system/settings/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

    \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

    getMaxRingerVolume()\n

    \u8fd4\u56de\uff1a \u6700\u5927\u94c3\u58f0\u97f3\u91cf

    "},{"location":"qsl4a/system/settings/#setringervolume","title":"setRingerVolume()","text":"

    \u8bbe\u7f6e\u94c3\u58f0\u97f3\u91cf\u3002

    setRingerVolume(volume)\n

    \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

    "},{"location":"qsl4a/system/settings/#getmediavolume","title":"getMediaVolume()","text":"

    \u83b7\u53d6\u5f53\u524d\u5a92\u4f53\u97f3\u91cf\u3002

    getMediaVolume()\n

    \u8fd4\u56de\uff1a \u5a92\u4f53\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-15\uff09

    "},{"location":"qsl4a/system/settings/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

    \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

    getMaxMediaVolume()\n

    \u8fd4\u56de\uff1a \u6700\u5927\u5a92\u4f53\u97f3\u91cf

    "},{"location":"qsl4a/system/settings/#setmediavolume","title":"setMediaVolume()","text":"

    \u8bbe\u7f6e\u5a92\u4f53\u97f3\u91cf\u3002

    setMediaVolume(volume)\n

    \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

    "},{"location":"qsl4a/system/settings/#_5","title":"\u7cfb\u7edf\u4fe1\u606f","text":""},{"location":"qsl4a/system/settings/#elapsedrealtimenanos","title":"elapsedRealtimeNanos()","text":"

    \u83b7\u53d6\u81ea\u7cfb\u7edf\u542f\u52a8\u4ee5\u6765\u7684\u7eb3\u79d2\u6570\u3002

    elapsedRealtimeNanos()\n

    \u8fd4\u56de\uff1a \u7eb3\u79d2\u6570\uff08\u53ef\u7528\u4e8e\u8ba1\u65f6\uff09

    "},{"location":"qsl4a/system/settings/#gettrafficstats","title":"getTrafficStats()","text":"

    \u83b7\u53d6\u7f51\u7edc\u6d41\u91cf\u7edf\u8ba1\u3002

    getTrafficStats(flags=7)\n

    \u53c2\u6570\uff1a - flags (int): \u8981\u68c0\u7d22\u7684\u7edf\u8ba1\uff08\u9ed8\u8ba4\uff1a7 = \u5168\u90e8\uff09

    \u8fd4\u56de\uff1a \u5305\u542b\u53d1\u9001/\u63a5\u6536\u5b57\u8282\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/settings/#getapptxbytes","title":"getAppTxBytes()","text":"

    \u83b7\u53d6 QPython \u5e94\u7528\u7684\u53d1\u9001\u5b57\u8282\u3002

    getAppTxBytes(packageName)\n

    \u53c2\u6570\uff1a - packageName (str): \u5305\u540d

    \u8fd4\u56de\uff1a \u5305\u542b tx/rx \u5b57\u8282\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/settings/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5c4f\u5e55\u8bbe\u7f6e\ncurrent_timeout = droid.getScreenTimeout().result\nprint(f\"Current timeout: {current_timeout}s\")\ndroid.setScreenTimeout(30)\n\n# \u68c0\u67e5\u5c4f\u5e55\nif droid.checkScreenOn().result:\n    print(\"Screen is on\")\n\n# \u97f3\u91cf\u63a7\u5236\nmedia_vol = droid.getMediaVolume().result\nprint(f\"Media volume: {media_vol}\")\ndroid.setMediaVolume(10)\n\n# \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\nif droid.checkAirplaneMode().result:\n    print(\"Airplane mode is on\")\n
    "},{"location":"qsl4a/system/sysinfo/","title":"\u7cfb\u7edf\u4fe1\u606f","text":"

    \u68c0\u7d22\u8bbe\u5907\u548c\u7cfb\u7edf\u4fe1\u606f\u3002

    "},{"location":"qsl4a/system/sysinfo/#_2","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/sysinfo/#getandroidid","title":"getAndroidID()","text":"

    \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

    getAndroidID()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

    "},{"location":"qsl4a/system/sysinfo/#getsysinfo","title":"getSysInfo()","text":"

    \u83b7\u53d6\u7efc\u5408\u7cfb\u7edf\u4fe1\u606f\u3002

    getSysInfo()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/sysinfo/#getlocale","title":"getLocale()","text":"

    \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u8bbe\u7f6e\u3002

    getLocale()\n

    \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

    "},{"location":"qsl4a/system/sysinfo/#_3","title":"\u5185\u5b58","text":""},{"location":"qsl4a/system/sysinfo/#getmemoryinfo","title":"getMemoryInfo()","text":"

    \u83b7\u53d6 RAM \u4fe1\u606f\u3002

    getMemoryInfo()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/sysinfo/#_4","title":"\u663e\u793a","text":""},{"location":"qsl4a/system/sysinfo/#getscreeninfo","title":"getScreenInfo()","text":"

    \u83b7\u53d6\u663e\u793a\u4fe1\u606f\u3002

    getScreenInfo()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/sysinfo/#_5","title":"\u6807\u8bc6\u7b26","text":""},{"location":"qsl4a/system/sysinfo/#getimei","title":"getImei()","text":"

    \u83b7\u53d6\u8bbe\u5907 IMEI\u3002

    getImei(slotIndex=None)\n
    "},{"location":"qsl4a/system/sysinfo/#getmeid","title":"getMeid()","text":"

    \u83b7\u53d6\u8bbe\u5907 MEID\u3002

    getMeid(slotIndex=None)\n
    "},{"location":"qsl4a/system/sysinfo/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u8bbe\u5907 ID\nandroid_id = droid.getAndroidID().result\nprint(f\"Android ID: {android_id}\")\n\n# \u5c4f\u5e55\u4fe1\u606f\nscreen = droid.getScreenInfo().result\nprint(f\"Screen: {screen['width']}x{screen['height']}\")\n\n# \u5185\u5b58\nmemory = droid.getMemoryInfo().result\nprint(f\"Memory: {memory}\")\n
    "},{"location":"qsl4a/system/wakelock/","title":"WakeLock API","text":"

    \u63a7\u5236\u8bbe\u5907\u5524\u9192\u9501\u4ee5\u4fdd\u6301 CPU \u6216\u5c4f\u5e55\u5f00\u542f\u3002

    "},{"location":"qsl4a/system/wakelock/#wake-lock","title":"Wake Lock \u7c7b\u578b","text":"

    QSL4A \u63d0\u4f9b\u4e0d\u540c\u7c7b\u578b\u7684\u5524\u9192\u9501\uff1a

    \u7c7b\u578b \u63cf\u8ff0 Full CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae Partial \u4ec5 CPU \u5f00\u542f Bright CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae Dim CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697"},{"location":"qsl4a/system/wakelock/#wake-lock_1","title":"Wake Lock \u65b9\u6cd5","text":""},{"location":"qsl4a/system/wakelock/#wakelockacquirefull","title":"wakeLockAcquireFull()","text":"

    \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae\uff09\u3002

    wakeLockAcquireFull()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockacquirepartial","title":"wakeLockAcquirePartial()","text":"

    \u83b7\u53d6\u90e8\u5206\u5524\u9192\u9501\uff08\u4ec5 CPU \u5f00\u542f\uff09\u3002

    wakeLockAcquirePartial()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockacquirebright","title":"wakeLockAcquireBright()","text":"

    \u83b7\u53d6\u660e\u4eae\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff09\u3002

    wakeLockAcquireBright()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockacquiredim","title":"wakeLockAcquireDim()","text":"

    \u83b7\u53d6\u6697\u6de1\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697\uff09\u3002

    wakeLockAcquireDim()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockrelease","title":"wakeLockRelease()","text":"

    \u91ca\u653e\u5524\u9192\u9501\u3002

    wakeLockRelease()\n
    "},{"location":"qsl4a/system/wakelock/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\ndroid.wakeLockAcquireFull()\n\n# \u5728\u4fdd\u6301\u5c4f\u5e55\u5f00\u542f\u65f6\u6267\u884c\u91cd\u8981\u5de5\u4f5c\nprint(\"Screen will stay on\")\ntime.sleep(10)\n\n# \u5b8c\u6210\u540e\u91ca\u653e\ndroid.wakeLockRelease()\n\n# \u6216\u4f7f\u7528\u90e8\u5206\u9501\u8fdb\u884c\u540e\u53f0\u4efb\u52a1\ndroid.wakeLockAcquirePartial()\n# \u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\uff0cCPU \u4ecd\u4fdd\u6301\u5f00\u542f\ntime.sleep(30)\ndroid.wakeLockRelease()\n

    \u6ce8\u610f\uff1a \u8bb0\u4f4f\u5728\u4e0d\u9700\u8981\u65f6\u91ca\u653e\u5524\u9192\u9501\u4ee5\u8282\u7701\u7535\u6c60\u3002

    "},{"location":"qsl4a/ui/accessibility/","title":"\u65e0\u969c\u788d\u670d\u52a1","text":"

    \u65e0\u969c\u788d\u670d\u52a1\u5141\u8bb8\u81ea\u52a8\u5316 UI \u4ea4\u4e92\uff0c\u5982\u70b9\u51fb\u3001\u6ed1\u52a8\u548c\u7cfb\u7edf\u64cd\u4f5c\u3002

    "},{"location":"qsl4a/ui/accessibility/#_2","title":"\u670d\u52a1\u63a7\u5236","text":""},{"location":"qsl4a/ui/accessibility/#accessibilitystartservice","title":"accessibilityStartService()","text":"

    \u542f\u52a8\u65e0\u969c\u788d\u670d\u52a1\u3002

    accessibilityStartService()\n

    \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

    "},{"location":"qsl4a/ui/accessibility/#accessibilityserviceenabled","title":"accessibilityServiceEnabled()","text":"

    \u68c0\u67e5\u65e0\u969c\u788d\u670d\u52a1\u662f\u5426\u5df2\u542f\u7528\u3002

    accessibilityServiceEnabled()\n

    \u8fd4\u56de\uff1a True \u6216 False

    "},{"location":"qsl4a/ui/accessibility/#_3","title":"\u5c4f\u5e55\u4ea4\u4e92","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityclick","title":"accessibilityClick()","text":"

    \u5728\u5c4f\u5e55\u5750\u6807\u5904\u70b9\u51fb\u3002

    accessibilityClick(x=0, y=0, t=50)\n

    \u53c2\u6570\uff1a - x (int/float): X \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - y (int/float): Y \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - t (int): \u6309\u4f4f\u65f6\u957f\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a50\uff09

    "},{"location":"qsl4a/ui/accessibility/#accessibilityslide","title":"accessibilitySlide()","text":"

    \u591a\u70b9\u6ed1\u52a8\u624b\u52bf\u3002

    accessibilitySlide(XnYn=None, t=None)\n

    \u53c2\u6570\uff1a - XnYn (list): \u5750\u6807 [X1, Y1, X2, Y2, ... Xn, Yn] - t (int): \u6ed1\u52a8\u65f6\u957f\uff08\u9ed8\u8ba4\uff1a50*n \u6beb\u79d2\uff09

    "},{"location":"qsl4a/ui/accessibility/#_4","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityaction","title":"accessibilityAction()","text":"

    \u6309\u4ee3\u7801\u6267\u884c\u7cfb\u7edf\u64cd\u4f5c\u3002

    accessibilityAction(actionCode)\n

    \u64cd\u4f5c\u4ee3\u7801\uff1a | \u4ee3\u7801 | \u5e38\u91cf | \u63cf\u8ff0 | |------|----------|-------------| | 1 | BACK | \u8fd4\u56de\u6309\u94ae | | 2 | HOME | \u4e3b\u5c4f\u5e55\u6309\u94ae | | 3 | RECENTS | \u6700\u8fd1\u5e94\u7528 | | 4 | NOTIFICATIONS | \u6253\u5f00\u901a\u77e5 | | 5 | QUICK_SETTINGS | \u6253\u5f00\u5feb\u901f\u8bbe\u7f6e | | 6 | POWER_DIALOG | \u7535\u6e90\u83dc\u5355 | | 7 | TOGGLE_SPLIT_SCREEN | \u5206\u5c4f | | 8 | LOCK_SCREEN | \u9501\u5c4f | | 9 | TAKE_SCREENSHOT | \u622a\u56fe | | 10 | KEYCODE_HEADSETHOOK | \u8033\u673a\u6302\u94a9 | | 11-14 | ACCESSIBILITY_ | \u65e0\u969c\u788d\u6309\u94ae | | 15 | DISMISS_NOTIFICATION_SHADE | \u5173\u95ed\u901a\u77e5\u680f | | 16-20 | DPAD_ | \u65b9\u5411\u952e | | 21 | MENU | \u83dc\u5355\u6309\u94ae | | 22 | MEDIA_PLAY_PAUSE | \u64ad\u653e/\u6682\u505c\u5a92\u4f53 |

    "},{"location":"qsl4a/ui/accessibility/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/accessibility/#_6","title":"\u70b9\u51fb\u5c4f\u5e55\u4e2d\u5fc3","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u670d\u52a1\nif not droid.accessibilityServiceEnabled().result:\n    droid.accessibilityStartService()\n\n# \u70b9\u51fb\u4e2d\u5fc3\uff080,0 = \u4e2d\u5fc3\uff09\ndroid.accessibilityClick(0, 0, t=100)\n
    "},{"location":"qsl4a/ui/accessibility/#_7","title":"\u6ed1\u52a8\u624b\u52bf","text":"
    # \u4ece\u4e0b\u5f80\u4e0a\u6ed1\u52a8\uff08\u5411\u4e0a\u6eda\u52a8\uff09\ndroid.accessibilitySlide([0, 1.5, 0, -1.5], t=300)\n
    "},{"location":"qsl4a/ui/accessibility/#_8","title":"\u7cfb\u7edf\u5bfc\u822a","text":"
    # \u6309\u4e3b\u5c4f\u5e55\ndroid.accessibilityAction(2)\n\n# \u6309\u8fd4\u56de\ndroid.accessibilityAction(1)\n\n# \u6253\u5f00\u901a\u77e5\ndroid.accessibilityAction(4)\n
    "},{"location":"qsl4a/ui/accessibility/#_9","title":"\u70b9\u51fb\u7279\u5b9a\u4f4d\u7f6e","text":"
    # \u70b9\u51fb\u5c4f\u5e55\u5750\u6807 (500, 800)\ndroid.accessibilityClick(500, 800)\n\n# \u70b9\u51fb\u76f8\u5bf9\u4f4d\u7f6e\uff08\u6c34\u5e73\u5c45\u4e2d\uff0c\u5782\u76f4 3/4 \u5904\uff09\ndroid.accessibilityClick(0, 1.5)\n
    "},{"location":"qsl4a/ui/dialogs/","title":"\u5bf9\u8bdd\u6846\u7cfb\u7edf","text":"

    QSL4A \u63d0\u4f9b\u5168\u9762\u7684\u5bf9\u8bdd\u6846\u652f\u6301\uff0c\u7528\u4e8e\u7528\u6237\u4ea4\u4e92\uff0c\u5305\u62ec\u8b66\u62a5\u3001\u8f93\u5165\u5bf9\u8bdd\u6846\u3001\u9009\u62e9\u5bf9\u8bdd\u6846\u548c\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

    "},{"location":"qsl4a/ui/dialogs/#_2","title":"\u8b66\u62a5\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowalert","title":"dialogShowAlert()","text":"

    \u663e\u793a\u7b80\u5355\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

    dialogShowAlert(title=\"Alert\", message=\"The message of the alert.\",\n                positiveButtonText=\"OK\", negativeButtonText=None,\n                neutralButtonText=None, messageIsHtml=False)\n

    \u53c2\u6570\uff1a - title (str): \u5bf9\u8bdd\u6846\u6807\u9898 - message (str): \u6d88\u606f\u6587\u672c - positiveButtonText (str): \u80af\u5b9a\u6309\u94ae\u6807\u7b7e - negativeButtonText (str, optional): \u5426\u5b9a\u6309\u94ae\u6807\u7b7e - neutralButtonText (str, optional): \u4e2d\u6027\u6309\u94ae\u6807\u7b7e - messageIsHtml (bool): \u5c06\u6d88\u606f\u89e3\u6790\u4e3a HTML

    \u8fd4\u56de\uff1a \u5305\u542b\u70b9\u51fb\u6309\u94ae\u7684\u7ed3\u679c

    "},{"location":"qsl4a/ui/dialogs/#dialogshowsimplechoice","title":"dialogShowSimpleChoice()","text":"

    \u663e\u793a\u5e26\u6709\u9879\u76ee\u7684\u7b80\u5355\u9009\u62e9\u5bf9\u8bdd\u6846\u3002

    dialogShowSimpleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

    \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868

    \u8fd4\u56de\uff1a \u5305\u542b\u9009\u4e2d\u9879\u76ee\u7684\u7ed3\u679c

    "},{"location":"qsl4a/ui/dialogs/#_3","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialoggetinput","title":"dialogGetInput()","text":"

    \u83b7\u53d6\u7528\u6237\u6587\u672c\u8f93\u5165\u3002

    dialogGetInput(title=\"Value\", message=\"Please enter value:\",\n               defaultText=None, messageIsHtml=False)\n

    \u8fd4\u56de\uff1a \u5305\u542b\u7528\u6237\u8f93\u5165\u6587\u672c\u7684\u7ed3\u679c

    "},{"location":"qsl4a/ui/dialogs/#dialoggetpassword","title":"dialogGetPassword()","text":"

    \u83b7\u53d6\u5bc6\u7801\u8f93\u5165\u3002

    dialogGetPassword(title=\"Password\", message=\"Please enter password:\")\n

    \u8fd4\u56de\uff1a \u5305\u542b\u8f93\u5165\u5bc6\u7801\u7684\u7ed3\u679c

    "},{"location":"qsl4a/ui/dialogs/#dialogcreateinput","title":"dialogCreateInput()","text":"

    \u521b\u5efa\u81ea\u5b9a\u4e49\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

    dialogCreateInput(title=\"Value\", message=\"Please enter value:\",\n                  defaultText=None, inputType=None)\n

    \u53c2\u6570\uff1a - inputType (str): \u8f93\u5165\u7c7b\u578b\uff08\u4f8b\u5982 \"text\"\u3001\"number\"\u3001\"textPassword\"\uff09

    "},{"location":"qsl4a/ui/dialogs/#dialogcreatepassword","title":"dialogCreatePassword()","text":"

    \u521b\u5efa\u5bc6\u7801\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

    dialogCreatePassword(title=\"Password\", message=\"Please enter password:\")\n
    "},{"location":"qsl4a/ui/dialogs/#dialogcreateseekbar","title":"dialogCreateSeekBar()","text":"

    \u521b\u5efa\u6ed1\u5757/\u8fdb\u5ea6\u6761\u5bf9\u8bdd\u6846\u3002

    dialogCreateSeekBar(starting_value=50, maximum_value=100, title=\"\", message=\"\")\n

    \u53c2\u6570\uff1a - starting_value (int): \u521d\u59cb\u503c - maximum_value (int): \u6700\u5927\u503c

    "},{"location":"qsl4a/ui/dialogs/#_4","title":"\u9009\u62e9\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowsinglechoice","title":"dialogShowSingleChoice()","text":"

    \u663e\u793a\u5355\u9009\uff08\u5355\u9009\u6309\u94ae\uff09\u5bf9\u8bdd\u6846\u3002

    dialogShowSingleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, selected=-1, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

    \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (int): \u9ed8\u8ba4\u9009\u4e2d\u7d22\u5f15

    "},{"location":"qsl4a/ui/dialogs/#dialogshowmultichoice","title":"dialogShowMultiChoice()","text":"

    \u663e\u793a\u591a\u9009\uff08\u590d\u9009\u6846\uff09\u5bf9\u8bdd\u6846\u3002

    dialogShowMultiChoice(title=\"Alert\", message=\"The message of the alert.\",\n                      items=None, selected=None, positiveButtonText=\"OK\",\n                      negativeButtonText=None, neutralButtonText=None,\n                      messageIsHtml=False)\n

    \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (list): \u521d\u59cb\u9009\u4e2d\u7d22\u5f15\u5217\u8868

    "},{"location":"qsl4a/ui/dialogs/#dialogsetsinglechoiceitems","title":"dialogSetSingleChoiceItems()","text":"

    \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u5355\u9009\u9879\u76ee\u3002

    dialogSetSingleChoiceItems(items, selected=-1)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetmultichoiceitems","title":"dialogSetMultiChoiceItems()","text":"

    \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u591a\u9009\u9879\u76ee\u3002

    dialogSetMultiChoiceItems(items, selected=None)\n
    "},{"location":"qsl4a/ui/dialogs/#_5","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatespinnerprogress","title":"dialogCreateSpinnerProgress()","text":"

    \u521b\u5efa\u4e0d\u786e\u5b9a\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

    dialogCreateSpinnerProgress(title=None, message=None, maximum_progress=100)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogcreatehorizontalprogress","title":"dialogCreateHorizontalProgress()","text":"

    \u521b\u5efa\u6c34\u5e73\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

    dialogCreateHorizontalProgress(title=None, message=None, maximum_progress=100)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetcurrentprogress","title":"dialogSetCurrentProgress()","text":"

    \u66f4\u65b0\u8fdb\u5ea6\u503c\u3002

    dialogSetCurrentProgress(current)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetmaxprogress","title":"dialogSetMaxProgress()","text":"

    \u8bbe\u7f6e\u6700\u5927\u8fdb\u5ea6\u503c\u3002

    dialogSetMaxProgress(max)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetprogressmessage","title":"dialogSetProgressMessage()","text":"

    \u66f4\u65b0\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u6d88\u606f\u3002

    dialogSetProgressMessage(message)\n
    "},{"location":"qsl4a/ui/dialogs/#_6","title":"\u9009\u62e9\u5668\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatedatepicker","title":"dialogCreateDatePicker()","text":"

    \u521b\u5efa\u65e5\u671f\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

    dialogCreateDatePicker(year=1970, month=1, day=1)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogcreatetimepicker","title":"dialogCreateTimePicker()","text":"

    \u521b\u5efa\u65f6\u95f4\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

    dialogCreateTimePicker(hour=0, minute=0, is24hour=False)\n
    "},{"location":"qsl4a/ui/dialogs/#_7","title":"\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u521b\u5efa","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatealert","title":"dialogCreateAlert()","text":"

    \u521b\u5efa\u81ea\u5b9a\u4e49\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

    dialogCreateAlert(title=None, message=None)\n

    \u521b\u5efa\u4e00\u4e2a\u7a7a\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002\u53ef\u4e0e\u5176\u4ed6 dialogSet* \u51fd\u6570\u4e00\u8d77\u4f7f\u7528\u6765\u81ea\u5b9a\u4e49\u3002

    "},{"location":"qsl4a/ui/dialogs/#dialogsetitems","title":"dialogSetItems()","text":"

    \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u7b80\u5355\u5217\u8868\u9879\u76ee\u3002

    dialogSetItems(items)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetpositivebuttontext","title":"dialogSetPositiveButtonText()","text":"

    \u8bbe\u7f6e\u80af\u5b9a\u6309\u94ae\u6587\u672c\u3002

    dialogSetPositiveButtonText(text)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetnegativebuttontext","title":"dialogSetNegativeButtonText()","text":"

    \u8bbe\u7f6e\u5426\u5b9a\u6309\u94ae\u6587\u672c\u3002

    dialogSetNegativeButtonText(text)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetneutralbuttontext","title":"dialogSetNeutralButtonText()","text":"

    \u8bbe\u7f6e\u4e2d\u6027\u6309\u94ae\u6587\u672c\u3002

    dialogSetNeutralButtonText(text)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetmessageishtml","title":"dialogSetMessageIsHtml()","text":"

    \u8bbe\u7f6e\u6d88\u606f\u662f\u5426\u5e94\u89e3\u6790\u4e3a HTML\u3002

    dialogSetMessageIsHtml(messageIsHtml=True)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogshow","title":"dialogShow()","text":"

    \u663e\u793a\u521b\u5efa\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u3002

    dialogShow()\n
    "},{"location":"qsl4a/ui/dialogs/#_8","title":"\u5bf9\u8bdd\u6846\u63a7\u5236","text":""},{"location":"qsl4a/ui/dialogs/#dialogdismiss","title":"dialogDismiss()","text":"

    \u5173\u95ed\u5f53\u524d\u5bf9\u8bdd\u6846\u3002

    dialogDismiss()\n
    "},{"location":"qsl4a/ui/dialogs/#dialoggetresponse","title":"dialogGetResponse()","text":"

    \u83b7\u53d6\u5bf9\u8bdd\u6846\u54cd\u5e94\u3002

    dialogGetResponse()\n
    "},{"location":"qsl4a/ui/dialogs/#dialoggetselecteditems","title":"dialogGetSelectedItems()","text":"

    \u4ece\u9009\u62e9\u5bf9\u8bdd\u6846\u83b7\u53d6\u9009\u4e2d\u7684\u9879\u76ee\u3002

    dialogGetSelectedItems()\n
    "},{"location":"qsl4a/ui/dialogs/#_9","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/dialogs/#_10","title":"\u7b80\u5355\u8b66\u62a5","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a\u8b66\u62a5\ndroid.dialogShowAlert(\"Warning\", \"This is an important message!\")\n
    "},{"location":"qsl4a/ui/dialogs/#_11","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":"
    # \u83b7\u53d6\u7528\u6237\u8f93\u5165\nresult = droid.dialogGetInput(\"Name\", \"Enter your name:\", \"John\").result\nprint(f\"Hello, {result}!\")\n
    "},{"location":"qsl4a/ui/dialogs/#_12","title":"\u5e26\u6309\u94ae\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846","text":"
    # \u521b\u5efa\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\ndroid.dialogCreateAlert(\"Custom\", \"Choose an option\")\ndroid.dialogSetItems([\"Option 1\", \"Option 2\", \"Option 3\"])\ndroid.dialogShow()\n\n# \u83b7\u53d6\u54cd\u5e94\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response['item']}\")\n
    "},{"location":"qsl4a/ui/dialogs/#_13","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":"
    # \u521b\u5efa\u8fdb\u5ea6\u5bf9\u8bdd\u6846\ndroid.dialogCreateHorizontalProgress(\"Loading\", \"Please wait...\", 100)\ndroid.dialogShow()\n\n# \u66f4\u65b0\u8fdb\u5ea6\nfor i in range(101):\n    droid.dialogSetCurrentProgress(i)\n    time.sleep(0.05)\n\ndroid.dialogDismiss()\n
    "},{"location":"qsl4a/ui/dialogs/#_14","title":"\u65e5\u671f\u9009\u62e9\u5668","text":"
    # \u663e\u793a\u65e5\u671f\u9009\u62e9\u5668\ndroid.dialogCreateDatePicker(2024, 1, 15)\ndroid.dialogShow()\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response}\")\n
    "},{"location":"qsl4a/ui/floatview/","title":"\u6d6e\u52a8\u89c6\u56fe","text":"

    \u6d6e\u52a8\u7a97\u53e3\u652f\u6301\uff0c\u7528\u4e8e\u5728\u5176\u4ed6\u5e94\u7528\u7a0b\u5e8f\u4e0a\u65b9\u4fdd\u6301\u663e\u793a\u7684\u8986\u76d6 UI \u5143\u7d20\u3002

    "},{"location":"qsl4a/ui/floatview/#_2","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/floatview/#floatview","title":"floatView()","text":"

    \u663e\u793a\u6216\u4fee\u6539\u6d6e\u52a8\u89c6\u56fe\u3002

    floatView(Args=None)\n

    \u53c2\u6570\uff1a - Args (dict): \u914d\u7f6e\u5b57\u5178\uff0c\u5305\u542b\u4ee5\u4e0b\u952e\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08-1 \u521b\u5efa\u65b0\u7684\uff0c>=0 \u4fee\u6539\u73b0\u6709\u7684\uff09 - text (str): \u8981\u663e\u793a\u7684\u6587\u672c\u5185\u5bb9 - html (str): HTML \u5185\u5bb9\uff08\u5982\u679c\u7701\u7565 text \u5219\u4f7f\u7528\uff09 - width (int): \u89c6\u56fe\u5bbd\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a300\uff09 - height (int): \u89c6\u56fe\u9ad8\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a150\uff09 - x (int): X \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - y (int): Y \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - backColor (str): ARGB \u5341\u516d\u8fdb\u5236\u80cc\u666f\u8272\uff08\u9ed8\u8ba4\uff1a'7f7f7f7f'\uff09 - textColor (str): ARGB \u5341\u516d\u8fdb\u5236\u6587\u672c\u8272\uff08\u9ed8\u8ba4\uff1a'ff000000'\uff09 - textSize (int): \u6587\u672c\u5927\u5c0f\uff08\u9ed8\u8ba4\uff1a10\uff09 - textAlign (int): \u6587\u672c\u5bf9\u9f50\uff080 = \u7ee7\u627f\uff09 - script (str): \u957f\u6309\u5173\u95ed\u540e\u8fd0\u884c\u7684\u811a\u672c\u8def\u5f84 - arg: \u811a\u672c\u53c2\u6570 - clickRemove (bool): \u542f\u7528\u70b9\u51fb\u79fb\u9664\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - flag (int): \u7a97\u53e3\u6807\u5fd7\uff08\u9ed8\u8ba4\uff1a40 - \u53ef\u89e6\u6478\uff09

    \u8fd4\u56de\uff1a \u5f53\u524d\u94fe\u5217\u8868\u957f\u5ea6

    "},{"location":"qsl4a/ui/floatview/#floatviewcount","title":"floatViewCount()","text":"

    \u83b7\u53d6\u6d3b\u52a8\u6d6e\u52a8\u89c6\u56fe\u7684\u6570\u91cf\u3002

    floatViewCount()\n

    \u8fd4\u56de\uff1a \u6d6e\u52a8\u89c6\u56fe\u6570\u91cf

    "},{"location":"qsl4a/ui/floatview/#floatviewresult","title":"floatViewResult()","text":"

    \u83b7\u53d6\u6d6e\u52a8\u89c6\u56fe\u7684\u7ed3\u679c/\u72b6\u6001\u3002

    floatViewResult(index=-1)\n

    \u53c2\u6570\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1\uff0c\u8fd4\u56de\u6700\u540e\u64cd\u4f5c\u7ed3\u679c\uff09

    \u8fd4\u56de\uff1a \u5305\u542b\u64cd\u4f5c\u8be6\u60c5\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - x, y: \u4f4d\u7f6e - time: \u65f6\u95f4\u6233 - operation: \u64cd\u4f5c\u7c7b\u578b\uff08'initial'\u3001'move' \u7b49\uff09 - index: \u89c6\u56fe\u7d22\u5f15 - removed: \u5982\u679c\u89c6\u56fe\u88ab\u79fb\u9664\u5219\u4e3a True

    "},{"location":"qsl4a/ui/floatview/#floatviewremove","title":"floatViewRemove()","text":"

    \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\u3002

    floatViewRemove(index=-1)\n

    \u53c2\u6570\uff1a - index (int): \u8981\u79fb\u9664\u7684\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1 \u79fb\u9664\u6700\u540e\u4e00\u4e2a\uff09

    \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a 1\uff0c\u5426\u5219\u4e3a 0

    "},{"location":"qsl4a/ui/floatview/#_3","title":"\u5e38\u91cf","text":"
    • floatView.INDEX_NEW = -1 - \u521b\u5efa\u65b0\u7684\u6d6e\u52a8\u89c6\u56fe
    • floatView.FLAG_DEFAULT_TOUCHABLE = 40 - \u9ed8\u8ba4\u53ef\u89e6\u6478\u6807\u5fd7
    • floatView.TEXT_ALIGNMENT_INHERIT = 0
    • floatView.TEXT_ALIGNMENT_CENTER - \u5c45\u4e2d\u6587\u672c\u5bf9\u9f50
    "},{"location":"qsl4a/ui/floatview/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/floatview/#_5","title":"\u57fa\u672c\u6d6e\u52a8\u89c6\u56fe","text":"
    import androidhelper\nfrom androidhelper import Android\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u7b80\u5355\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'index': -1,  # \u521b\u5efa\u65b0\u7684\n    'text': 'Hello World',\n    'width': 400,\n    'height': 300,\n    'x': -300,  # \u4ece\u4e2d\u5fc3\u504f\u79fb\n    'y': -400,\n    'backColor': 'ff0000',  # \u7ea2\u8272\u80cc\u666f\n    'textColor': '0000ff',  # \u84dd\u8272\u6587\u672c\n    'textSize': 16,\n    'textAlign': droid.floatView.TEXT_ALIGNMENT_CENTER\n})\n\n# \u68c0\u67e5\u6570\u91cf\nprint(f\"Float views: {droid.floatViewCount().result}\")\n\n# \u83b7\u53d6\u7ed3\u679c\nresult = droid.floatViewResult().result\nprint(f\"View info: {result}\")\n\n# \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\ndroid.floatViewRemove(0)\n
    "},{"location":"qsl4a/ui/floatview/#html","title":"HTML \u5185\u5bb9","text":"
    # \u521b\u5efa\u5e26 HTML \u5185\u5bb9\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': '',  # \u7a7a\u6587\u672c\u4ee5\u4f7f\u7528 HTML\n    'html': '<h1>Title</h1><p>Rich <b>HTML</b> content</p>',\n    'width': 500,\n    'height': 400\n})\n
    "},{"location":"qsl4a/ui/floatview/#_6","title":"\u4fee\u6539\u73b0\u6709\u89c6\u56fe","text":"
    # \u521b\u5efa\u521d\u59cb\u89c6\u56fe\ndroid.floatView({'text': 'Initial Text', 'width': 300, 'height': 150})\n\n# \u4fee\u6539\u540c\u4e00\u89c6\u56fe\uff08\u7d22\u5f15 0\uff09\ndroid.floatView({\n    'index': 0,\n    'text': 'Updated Text!',\n    'backColor': '7f00ff00'  # \u7eff\u8272\u80cc\u666f\n})\n\n# \u68c0\u67e5\u79fb\u52a8/\u66f4\u6539\u7ed3\u679c\nresult = droid.floatViewResult(0).result\nprint(f\"Operation: {result.get('operation')}, Position: ({result.get('x')}, {result.get('y')})\")\n
    "},{"location":"qsl4a/ui/floatview/#_7","title":"\u591a\u4e2a\u6d6e\u52a8\u89c6\u56fe","text":"
    # \u521b\u5efa\u591a\u4e2a\u89c6\u56fe\nfor i in range(3):\n    droid.floatView({\n        'index': -1,\n        'text': f'View {i}',\n        'x': i * 100 - 150,\n        'y': i * 100 - 150,\n        'backColor': f'{i}f{i}f{i}f'\n    })\n\nprint(f\"Total views: {droid.floatViewCount().result}\")\n\n# \u79fb\u9664\u6240\u6709\u89c6\u56fe\nwhile droid.floatViewCount().result > 0:\n    droid.floatViewRemove()\n
    "},{"location":"qsl4a/ui/floatview/#_8","title":"\u5e26\u811a\u672c\u56de\u8c03","text":"
    # \u521b\u5efa\u5173\u95ed\u65f6\u8fd0\u884c\u811a\u672c\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': 'Click to close and run script',\n    'script': '/sdcard/my_script.py',\n    'arg': 'hello from float view',\n    'clickRemove': True\n})\n
    "},{"location":"qsl4a/ui/fullscreen/","title":"\u5168\u5c4f UI","text":"

    \u4f7f\u7528\u539f\u751f Android \u5e03\u5c40\u521b\u5efa\u81ea\u5b9a\u4e49\u5168\u5c4f\u754c\u9762\u3002

    "},{"location":"qsl4a/ui/fullscreen/#_1","title":"\u5e03\u5c40\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullshow","title":"fullShow()","text":"

    \u663e\u793a\u5168\u5c4f\u5e03\u5c40\u3002

    fullShow(layout, title=None, theme=None)\n

    \u53c2\u6570\uff1a - layout (str): JSON \u5e03\u5c40\u5b9a\u4e49\u6216\u5e03\u5c40\u5b57\u7b26\u4e32 - title (str, optional): \u7a97\u53e3\u6807\u9898 - theme (str, optional): \u4e3b\u9898\u540d\u79f0

    \u8fd4\u56de\uff1a \u7a97\u53e3 ID

    "},{"location":"qsl4a/ui/fullscreen/#fulldismiss","title":"fullDismiss()","text":"

    \u5173\u95ed\u5168\u5c4f\u7a97\u53e3\u3002

    fullDismiss()\n
    "},{"location":"qsl4a/ui/fullscreen/#fullquery","title":"fullQuery()","text":"

    \u67e5\u8be2\u6240\u6709\u5c0f\u90e8\u4ef6\u503c\u3002

    fullQuery()\n

    \u8fd4\u56de\uff1a \u5c0f\u90e8\u4ef6 ID \u548c\u503c\u7684\u5b57\u5178

    "},{"location":"qsl4a/ui/fullscreen/#fullquerydetail","title":"fullQueryDetail()","text":"

    \u67e5\u8be2\u7279\u5b9a\u5c0f\u90e8\u4ef6\u8be6\u60c5\u3002

    fullQueryDetail(id)\n
    "},{"location":"qsl4a/ui/fullscreen/#_2","title":"\u5c5e\u6027\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperty","title":"fullGetProperty()","text":"

    \u83b7\u53d6\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

    fullGetProperty(id, property)\n
    "},{"location":"qsl4a/ui/fullscreen/#fullsetproperty","title":"fullSetProperty()","text":"

    \u8bbe\u7f6e\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

    fullSetProperty(id, property, value)\n
    "},{"location":"qsl4a/ui/fullscreen/#fullsetlist","title":"fullSetList()","text":"

    \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

    fullSetList(id, list, isHtml=False, listType=0)\n
    "},{"location":"qsl4a/ui/fullscreen/#fullsetlist2","title":"fullSetList2()","text":"

    \u4f7f\u7528\u8d44\u6e90 ID \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

    fullSetList2(id, list, intRes)\n

    \u53c2\u6570\uff1a - id (str): \u5c0f\u90e8\u4ef6 ID - list (list): \u9879\u76ee\u5217\u8868 - intRes (int): \u5217\u8868\u9879\u76ee\u5e03\u5c40\u7684 Android \u8d44\u6e90 ID

    "},{"location":"qsl4a/ui/fullscreen/#fullsetlistselected","title":"fullSetListSelected()","text":"

    \u5728\u5217\u8868\u4e2d\u8bbe\u7f6e\u9009\u4e2d\u9879\u76ee\u3002

    fullSetListSelected(id, selected)\n

    \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID - selected (int): \u8981\u9009\u4e2d\u7684\u9879\u76ee\u7d22\u5f15

    "},{"location":"qsl4a/ui/fullscreen/#fullgetlistselected","title":"fullGetListSelected()","text":"

    \u83b7\u53d6\u5f53\u524d\u9009\u4e2d\u7684\u5217\u8868\u9879\u76ee\u7d22\u5f15\u3002

    fullGetListSelected(id)\n

    \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID

    \u8fd4\u56de\uff1a \u9009\u4e2d\u9879\u76ee\u7d22\u5f15

    "},{"location":"qsl4a/ui/fullscreen/#_3","title":"\u6279\u91cf\u5c5e\u6027\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperties","title":"fullGetProperties()","text":"

    \u4e00\u6b21\u83b7\u53d6\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

    fullGetProperties(ids, property)\n

    \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u83b7\u53d6\u7684\u5c5e\u6027\u540d

    \u8fd4\u56de\uff1a \u6620\u5c04\u5c0f\u90e8\u4ef6 ID \u5230\u5c5e\u6027\u503c\u7684\u5b57\u5178

    "},{"location":"qsl4a/ui/fullscreen/#fullsetproperties","title":"fullSetProperties()","text":"

    \u4e00\u6b21\u8bbe\u7f6e\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

    fullSetProperties(ids, property, value)\n

    \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u8bbe\u7f6e\u7684\u5c5e\u6027\u540d - value: \u5c5e\u6027\u503c

    "},{"location":"qsl4a/ui/fullscreen/#_4","title":"\u622a\u56fe","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetscreenshot","title":"fullGetScreenShot()","text":"

    \u6355\u83b7\u5168\u5c4f\u622a\u56fe\u3002

    fullGetScreenShot(path=None)\n

    \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u5728\u4e8b\u4ef6\u4e2d\u8fd4\u56de

    \u8fd4\u56de\uff1a \u5305\u542b\u622a\u56fe\u6570\u636e\u7684\u4e8b\u4ef6

    "},{"location":"qsl4a/ui/fullscreen/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b9a\u4e49\u5e03\u5c40\nlayout = '''\n{ \"type\": \"LinearLayout\", \"orientation\": \"vertical\",\n  \"children\": [\n    { \"type\": \"TextView\", \"id\": \"title\", \"text\": \"Hello\" },\n    { \"type\": \"Button\", \"id\": \"btn\", \"text\": \"Click Me\" }\n  ]\n}\n'''\n\n# \u663e\u793a\u5e03\u5c40\ndroid.fullShow(layout, \"My App\")\n\n# \u67e5\u8be2\u6309\u94ae\u70b9\u51fb\nevent = droid.eventWaitFor('click', timeout=10)\nif event.result:\n    widget_id = event.result['data']['id']\n    if widget_id == 'btn':\n        print(\"Button clicked!\")\n\ndroid.fullDismiss()\n
    "}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"QPython \u9879\u76ee","text":"

    QPython \u4e0d\u4ec5\u662f\u4e00\u4e2a\u5f3a\u5927\u7684 Android Python IDE\uff0c\u4e5f\u662f\u4e00\u4e2a\u6d3b\u8dc3\u7684\u6280\u672f\u793e\u533a\u3002

    "},{"location":"#ai-android-python-ide","title":"\u652f\u6301 AI \u7684 Android Python IDE","text":"

    QPython \u662f\u60a8\u8fdb\u884c Android Python \u7f16\u7a0b\u7684\u5165\u53e3\u3002\u5b83\u96c6\u6210\u4e86 Python \u89e3\u91ca\u5668\u3001AI \u6a21\u578b\u5f15\u64ce\u548c\u79fb\u52a8\u5f00\u53d1\u5de5\u5177\u94fe\uff0c\u8ba9\u60a8\u80fd\u591f\u4ece\u79fb\u52a8\u8bbe\u5907\u6784\u5efa Web \u5e94\u7528\u7a0b\u5e8f\u3001\u6267\u884c\u79d1\u5b66\u8ba1\u7b97\u548c\u521b\u5efa\u667a\u80fd\u5e94\u7528\u3002

    \u65e0\u8bba\u60a8\u662f\u5728\u5b66\u4e60\u7f16\u7a0b\u3001\u6784\u5efa\u6570\u636e\u79d1\u5b66\u9879\u76ee\uff0c\u8fd8\u662f\u5f00\u53d1 AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f\uff0cQPython \u90fd\u63d0\u4f9b\u4e86\u5b8c\u6574\u7684\u79fb\u52a8\u7f16\u7a0b\u89e3\u51b3\u65b9\u6848\uff0c\u62e5\u6709\u5168\u9762\u7684\u5f00\u53d1\u8005\u8d44\u6e90\u548c\u6d3b\u8dc3\u7684\u793e\u533a\u6765\u652f\u6301\u60a8\u7684\u65c5\u7a0b\u3002

    • \u5206\u652f\u7248\u672c \u2013 \u4e86\u89e3\u4e0d\u540c\u7684 QPython \u7248\u672c\uff08IDE\u3001\u793e\u533a\u7248\u3001Plus\uff09\uff0c\u9009\u62e9\u9002\u5408\u60a8\u9700\u6c42\u7684\u7248\u672c
    • \u66f4\u65b0\u65e5\u5fd7 \u2013 \u968f\u65f6\u4e86\u89e3\u6700\u65b0\u529f\u80fd\u3001\u6539\u8fdb\u548c\u53d1\u884c\u8bf4\u660e
    "},{"location":"#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"

    \u5982\u4f55\u5feb\u901f\u5165\u95e8\uff1f\u8bf7\u6309\u7167\u4ee5\u4e0b\u6b65\u9aa4\uff1a

    • \u5feb\u901f\u5165\u95e8
    • Hello World \u6559\u7a0b
    "},{"location":"#_2","title":"\u7f16\u7a0b\u6307\u5357","text":"

    QPython \u4e0d\u4ec5\u63d0\u4f9b\u57fa\u7840\u7684 Python \u63a5\u53e3\u652f\u6301\uff0c\u66f4\u91cd\u8981\u7684\u662f\uff0c\u5b83\u8fd8\u5141\u8bb8\u60a8\u901a\u8fc7 QSL4A \u63a5\u53e3\u4f7f\u7528 Python \u8c03\u7528 Android API\u3002

    • Python \u6807\u51c6\u5e93 \u2013 \u901a\u7528\u7684 Python \u8bed\u6cd5\u548c\u5185\u7f6e\u5e93
    • QSL4A API \u2013 \u4ece Python \u8bbf\u95ee Android \u8bbe\u5907\u529f\u80fd\uff08\u76f8\u673a\u3001\u4f20\u611f\u5668\u3001\u77ed\u4fe1\u7b49\uff09
    • QPYPI \u6307\u5357 \u2013 \u5b89\u88c5\u989d\u5916\u7684 Python \u5305
    • \u7f16\u8f91\u5668\u6307\u5357 \u2013 \u4f7f\u7528\u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668
    • \u5916\u90e8 API \u2013 \u4e0e\u5916\u90e8\u5e94\u7528\u7a0b\u5e8f\u96c6\u6210
    "},{"location":"#_3","title":"\u4e0b\u8f7d\u8d44\u6e90","text":"
    • Google Drive
    • \u5fae\u4fe1\u7f51\u76d8
    "},{"location":"#_4","title":"\u793e\u533a\u4e0e\u53cd\u9988","text":"
    • \u4e2d\u6587\u4ea4\u6d41\u793e\u533a
    • \u767e\u5ea6\u8d34\u5427
    • \u95ee\u9898\u53cd\u9988
    • \u529f\u80fd\u6269\u5c55\u8bf7\u6c42
    "},{"location":"#_5","title":"\u5173\u6ce8\u6211\u4eec","text":"
    • B\u7ad9
    • Weibo
    "},{"location":"AIPyApp/","title":"AIPyApp - AI\u9a71\u52a8\u7684\u7a0b\u5e8f\u751f\u6210\u5668","text":"

    AIPyApp \u662f QPython \u4e2d\u7684\u667a\u80fd\u5de5\u5177\uff0c\u53ef\u4ee5\u5229\u7528 AI \u4ece\u81ea\u7136\u8bed\u8a00\u6307\u4ee4\u81ea\u52a8\u751f\u6210 Python \u7a0b\u5e8f\u3002

    "},{"location":"AIPyApp/#_1","title":"\u6982\u8ff0","text":"

    AIPyApp \u6539\u53d8\u4e86\u60a8\u7f16\u5199\u4ee3\u7801\u7684\u65b9\u5f0f\u2014\u2014\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u63cf\u8ff0\u60a8\u60f3\u8981\u7684\u529f\u80fd\uff0cAI \u5c31\u4f1a\u4e3a\u60a8\u751f\u6210 Python \u7a0b\u5e8f\u3002QPython \u8fd8\u5c06\u63a8\u51fa AIPy Academy\u2014\u2014\u4e00\u4e2a\u4e3a AI \u65f6\u4ee3\u91cf\u8eab\u5b9a\u5236\u7684 Python \u7f16\u7a0b\u8bfe\u7a0b\u5e73\u53f0\u3002

    "},{"location":"AIPyApp/#_2","title":"\u5b89\u88c5","text":""},{"location":"AIPyApp/#_3","title":"\u7b2c\u4e00\u6b65\uff1a\u4ece\u4eea\u8868\u76d8\u542f\u52a8","text":"
    1. \u6253\u5f00 QPython\uff0c\u8fdb\u5165 \u4eea\u8868\u76d8
    2. \u957f\u6309\u5f00\u59cb\u6309\u94ae

    \u5982\u679c\u672a\u5b89\u88c5 AIPyApp\uff0c\u7cfb\u7edf\u4f1a\u63d0\u793a\u60a8\u786e\u8ba4\u5b89\u88c5\u3002\u6309 \u56de\u8f66\u952e\u7ee7\u7eed\u3002

    QPython \u5c06\u81ea\u52a8\u4ece PYPI \u4e0b\u8f7d\u5e76\u5b89\u88c5\u6240\u9700\u7684\u4f9d\u8d56\u9879\u3002\u8bf7\u8010\u5fc3\u7b49\u5f85\u5b89\u88c5\u5b8c\u6210\u3002

    "},{"location":"AIPyApp/#aipyapp","title":"\u7b2c\u4e8c\u6b65\uff1a\u91cd\u65b0\u542f\u52a8 AIPyApp","text":"

    \u5b89\u88c5\u5b8c\u6210\u540e\uff0c\u8fd4\u56de QPython \u4eea\u8868\u76d8\uff0c\u518d\u6b21 \u957f\u6309\u5f00\u59cb\u6309\u94ae\u542f\u52a8 AIPyApp\u3002

    "},{"location":"AIPyApp/#_4","title":"\u914d\u7f6e","text":""},{"location":"AIPyApp/#ai","title":"\u8bbe\u7f6e\u60a8\u7684 AI \u5bc6\u94a5","text":"

    \u9996\u6b21\u542f\u52a8\u65f6\uff0c\u60a8\u9700\u8981\u63d0\u4f9b AI API \u5bc6\u94a5\uff1a

    1. \u5728 PGPT \u6ce8\u518c\uff1a\u5728 https://user.pgpt.cloud \u521b\u5efa\u8d26\u6237\u4ee5\u751f\u6210\u60a8\u7684 AI \u5bc6\u94a5
    2. \u9ad8\u7ea7\u9009\u9879\uff1aAIPyApp \u8fd8\u652f\u6301\u6765\u81ea OpenAI\u3001Deepseek \u548c\u5176\u4ed6\u63d0\u4f9b\u5546\u7684\u81ea\u5b9a\u4e49 AI \u5bc6\u94a5\uff08\u8be6\u89c1\u9ad8\u7ea7\u6559\u7a0b\uff09
    "},{"location":"AIPyApp/#ai_1","title":"\u8f93\u5165\u60a8\u7684 AI \u5bc6\u94a5","text":"
    1. \u957f\u6309\u8f93\u5165\u63d0\u793a
    2. \u4ece\u5f39\u51fa\u83dc\u5355\u4e2d\u9009\u62e9 \u7c98\u8d34
    3. \u6309 \u56de\u8f66\u952e\u786e\u8ba4

    \u60a8\u7684 AI \u5bc6\u94a5\u5c06\u4fdd\u5b58\u4ee5\u4f9b\u540e\u7eed\u4f1a\u8bdd\u4f7f\u7528\u3002

    "},{"location":"AIPyApp/#aipyapp_1","title":"\u4f7f\u7528 AIPyApp","text":"

    \u914d\u7f6e\u5b8c\u6210\u540e\uff0c\u60a8\u5c06\u8fdb\u5165 AIPyApp \u63a7\u5236\u53f0\u6a21\u5f0f\u3002\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u8f93\u5165\u60a8\u7684\u6307\u4ee4\u5373\u53ef\uff01

    "},{"location":"AIPyApp/#_5","title":"\u793a\u4f8b\u547d\u4ee4","text":"

    \u5c1d\u8bd5\u8f93\u5165\uff1a

    \u4f7f\u7528 QSL4A \u521b\u5efa\u4e00\u4e2a HELLO QPY \u7a0b\u5e8f\u4f5c\u4e3a\u6f14\u793a\n

    AIPyApp \u5c06\uff1a 1. \u7406\u89e3\u60a8\u7684\u81ea\u7136\u8bed\u8a00\u8bf7\u6c42 2. \u751f\u6210\u76f8\u5e94\u7684 Python \u4ee3\u7801 3. \u81ea\u52a8\u6267\u884c\u7a0b\u5e8f

    \u5c31\u662f\u8fd9\u6837\u2014\u2014\u60a8\u65e0\u9700\u7f16\u5199\u4efb\u4f55\u4ee3\u7801\u5c31\u521b\u5efa\u4e86\u4e00\u4e2a\u53ef\u8fd0\u884c\u7684 Python \u7a0b\u5e8f\uff01

    "},{"location":"AIPyApp/#_6","title":"\u6f14\u793a","text":"

    \u4e0a\u9762\u7684\u793a\u4f8b\u6f14\u793a\u4e86 AIPyApp \u5982\u4f55\uff1a - \u7406\u89e3\u4e2d\u6587\u6307\u4ee4 - \u751f\u6210\u57fa\u4e8e QSL4A \u7684 Python \u4ee3\u7801 - \u7acb\u5373\u8fd0\u884c\u7a0b\u5e8f

    \u63a2\u7d22 AIPyApp \u4ee5\u53d1\u73b0\u66f4\u591a\u529f\u80fd\uff0c\u5f00\u59cb\u8f7b\u677e\u6784\u5efa Python \u7a0b\u5e8f\u3002

    "},{"location":"AIPyApp/#_7","title":"\u4e86\u89e3\u66f4\u591a","text":"

    \u656c\u8bf7\u671f\u5f85 AIPy Academy\uff1aaipy.org - \u5728 AI \u65f6\u4ee3\u5b66\u4e60\u548c\u4f7f\u7528 Python \u7f16\u7a0b\u7684\u8bfe\u7a0b\u5373\u5c06\u4e0a\u7ebf\u3002

    "},{"location":"GraphicalInterface/","title":"\u56fe\u5f62\u754c\u9762\uff08Turtle \u548c Tkinter\uff09","text":"

    \u672c\u6307\u5357\u8bf4\u660e\u5982\u4f55\u5728 Android \u8bbe\u5907\u4e0a\u7684 QPython \u4e2d\u542f\u7528\u56fe\u5f62\u754c\u9762\u652f\u6301\uff08Turtle \u548c Tkinter\uff09\u3002

    "},{"location":"GraphicalInterface/#_1","title":"\u6982\u8ff0","text":"

    QPython \u53ef\u4ee5\u8fd0\u884c Turtle \u548c Tkinter \u5e94\u7528\u7a0b\u5e8f\uff0c\u4f46\u9700\u8981\u989d\u5916\u7684\u8f6f\u4ef6\u6765\u5728 Android \u4e0a\u63d0\u4f9b\u56fe\u5f62\u663e\u793a\u652f\u6301\u3002

    "},{"location":"GraphicalInterface/#_2","title":"\u524d\u63d0\u6761\u4ef6","text":"

    \u5f00\u59cb\u4e4b\u524d\uff0c\u60a8\u9700\u8981\u4e0b\u8f7d\u4ee5\u4e0b\u8d44\u6e90\uff1a

    1. Xserver.apk - \u63d0\u4f9b Turtle/Tkinter \u56fe\u5f62\u652f\u6301\u7684\u914d\u5957\u5e94\u7528
    2. \u4e0b\u8f7d\u5730\u5740\uff1aQPythonProject/Extra on Google Drive
    3. Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762\u6269\u5c55 - \u901a\u8fc7 QPython \u7684 QPYPI \u5b89\u88c5
    "},{"location":"GraphicalInterface/#_3","title":"\u5b89\u88c5\u6b65\u9aa4","text":""},{"location":"GraphicalInterface/#xserver","title":"\u7b2c\u4e00\u6b65\uff1a\u5b89\u88c5 Xserver","text":"

    \u4ece Google Drive \u7684 QPython Extra \u8d44\u6e90\u76ee\u5f55\u4e0b\u8f7d\u5e76\u5b89\u88c5 Xserver.apk\u3002

    "},{"location":"GraphicalInterface/#qpython","title":"\u7b2c\u4e8c\u6b65\uff1a\u5b89\u88c5 QPython \u6269\u5c55","text":"

    \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI\u3002\u627e\u5230\u5e76\u5b89\u88c5 Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762 \u6269\u5c55\u3002

    "},{"location":"GraphicalInterface/#xserver_1","title":"\u7b2c\u4e09\u6b65\uff1a\u914d\u7f6e Xserver \u7535\u6c60\u8bbe\u7f6e","text":"

    \u4e3a\u9632\u6b62 Xserver \u5728\u540e\u53f0\u8fd0\u884c\u65f6\u88ab\u6740\u6b7b\uff1a

    1. \u8fdb\u5165\u8bbe\u5907\u7684 \u8bbe\u7f6e > \u5e94\u7528 > Xserver
    2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
    3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u6216 \"\u4e0d\u9650\u5236\"

    \u8fd9\u53ef\u786e\u4fdd Xserver \u5728\u5207\u6362\u5230\u540e\u53f0\u65f6\u7ee7\u7eed\u8fd0\u884c\u3002

    "},{"location":"GraphicalInterface/#qpython_1","title":"\u7b2c\u56db\u6b65\uff1a\u914d\u7f6e QPython \u7535\u6c60\u8bbe\u7f6e\uff08\u63a8\u8350\uff09","text":"

    \u540c\u6837\uff0c\u5c06 QPython \u7684\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u4ee5\u9632\u6b62\u8fdb\u7a0b\u88ab\u7ec8\u6b62\uff1a

    1. \u8fdb\u5165 \u8bbe\u7f6e > \u5e94\u7528 > QPython
    2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
    3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\"
    "},{"location":"GraphicalInterface/#xserver_2","title":"\u7b2c\u4e94\u6b65\uff1a\u542f\u52a8 Xserver","text":"

    \u5728\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d\uff0c\u542f\u52a8 Xserver \u5e94\u7528\u5e76\u5c06\u5176\u5207\u6362\u4e3a\u540e\u53f0\u8fd0\u884c\u3002

    "},{"location":"GraphicalInterface/#turtletkinter","title":"\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f","text":"

    \u5b8c\u6210\u8bbe\u7f6e\u540e\uff1a

    1. \u786e\u4fdd Xserver \u5728\u540e\u53f0\u8fd0\u884c
    2. \u5728 QPython \u4e2d\u8fd0\u884c\u60a8\u7684 Turtle \u6216 Tkinter \u5e94\u7528\u7a0b\u5e8f
    3. \u5207\u6362\u5230 Xserver \u67e5\u770b\u56fe\u5f62\u8f93\u51fa
    "},{"location":"GraphicalInterface/#_4","title":"\u6f14\u793a\u7a0b\u5e8f","text":"

    \u60a8\u53ef\u4ee5\u4ece QPython \u5e94\u7528\u7684 QPYPI \u7b2c\u4e00\u4e2a\u6269\u5c55\u90e8\u5206\u4e0b\u8f7d\u5e76\u5c1d\u8bd5 Turtle \u753b\u54c6\u5566A\u68a6 \u6f14\u793a\u7a0b\u5e8f\u6765\u9a8c\u8bc1\u60a8\u7684\u8bbe\u7f6e\u3002

    "},{"location":"GraphicalInterface/#_5","title":"\u6545\u969c\u6392\u9664","text":"
    • \u9ed1\u5c4f\uff1a\u786e\u4fdd\u5728\u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d Xserver \u6b63\u5728\u8fd0\u884c
    • \u5e94\u7528\u7a0b\u5e8f\u5d29\u6e83\uff1a\u68c0\u67e5 QPython \u548c Xserver \u662f\u5426\u90fd\u8bbe\u7f6e\u4e86\u65e0\u9650\u5236\u7684\u7535\u6c60\u8bbe\u7f6e
    • \u65e0\u663e\u793a\uff1a\u9a8c\u8bc1 Turtle/Tkinter \u6269\u5c55\u662f\u5426\u901a\u8fc7 QPYPI \u6b63\u786e\u5b89\u88c5
    "},{"location":"Notebook/","title":"Notebook","text":"

    QPython \u96c6\u6210\u4e86 Jupyter Notebook\uff0c\u63d0\u4f9b\u4e86\u4e00\u4e2a\u5f3a\u5927\u7684\u4ea4\u4e92\u73af\u5883\uff0c\u53ef\u5728 Android \u8bbe\u5907\u4e0a\u8fdb\u884c\u6570\u636e\u79d1\u5b66\u3001\u79d1\u5b66\u8ba1\u7b97\u548c AI \u5f00\u53d1\u3002

    "},{"location":"Notebook/#_1","title":"\u6982\u8ff0","text":"

    QPython \u81ea\u5e26\u5185\u7f6e\u7684 Jupyter Notebook \u5e94\u7528\u7a0b\u5e8f\uff0c\u5141\u8bb8\u60a8\u76f4\u63a5\u5728 Android \u8bbe\u5907\u4e0a\u521b\u5efa\u548c\u8fd0\u884c\u4ea4\u4e92\u5f0f Python \u7b14\u8bb0\u672c\u3002\u754c\u9762\u548c\u64cd\u4f5c\u65b9\u5f0f\u4e0e\u6807\u51c6 Jupyter Notebook \u7c7b\u4f3c\u3002

    "},{"location":"Notebook/#_2","title":"\u53ef\u7528\u5e93","text":"

    QPython \u652f\u6301\u5e7f\u6cdb\u7684\u6570\u5b66\u3001\u79d1\u5b66\u548c AI \u76f8\u5173\u5e93\uff0c\u975e\u5e38\u9002\u5408 Notebook \u73af\u5883\u3002\u53ef\u6839\u636e\u9700\u8981\u901a\u8fc7 QPYPI \u5b89\u88c5\uff1a

    • Matplotlib - \u7ed8\u56fe\u548c\u53ef\u89c6\u5316
    • Seaborn - \u7edf\u8ba1\u6570\u636e\u53ef\u89c6\u5316
    • Pandas - \u6570\u636e\u5206\u6790\u4e0e\u5904\u7406
    • Numpy - \u6570\u503c\u8ba1\u7b97
    • Scipy - \u79d1\u5b66\u8ba1\u7b97
    • OpenCV - \u8ba1\u7b97\u673a\u89c6\u89c9\u548c\u56fe\u50cf\u5904\u7406
    • Sympy - \u7b26\u53f7\u6570\u5b66
    • mpmath - \u4efb\u610f\u7cbe\u5ea6\u7b97\u672f
    • Scikit-learn - \u673a\u5668\u5b66\u4e60
    • PyTorch - \u6df1\u5ea6\u5b66\u4e60\u6846\u67b6
    "},{"location":"Notebook/#_3","title":"\u83b7\u53d6\u5e2e\u52a9","text":"

    \u7531\u4e8e QPython \u7684 Notebook \u64cd\u4f5c\u65b9\u5f0f\u4e0e Jupyter Notebook \u7c7b\u4f3c\uff0c\u60a8\u53ef\u4ee5\u53c2\u8003\u5b98\u65b9\u7684 Jupyter Notebook \u6587\u6863 \u83b7\u53d6\u8be6\u7ec6\u7684\u4f7f\u7528\u8bf4\u660e\u548c\u6280\u5de7\u3002

    "},{"location":"Notebook/#_4","title":"\u5b89\u88c5","text":"

    \u5b89\u88c5\u60a8\u9700\u8981\u7684\u5e93\uff1a

    1. \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI
    2. \u641c\u7d22\u60a8\u60f3\u8981\u7684\u5e93\uff08\u4f8b\u5982 \"numpy\"\u3001\"pandas\"\uff09
    3. \u5b89\u88c5\u6240\u9700\u7684\u5305

    \u4ec5\u5b89\u88c5\u60a8\u7684\u7279\u5b9a\u7528\u4f8b\u6240\u9700\u7684\u5e93\u3002

    "},{"location":"Notebook/#_5","title":"\u4f7f\u7528\u65b9\u6cd5","text":"

    QPython \u4e2d\u7684 Notebook \u5e94\u7528\u7a0b\u5e8f\u63d0\u4f9b\uff1a

    • \u4ea4\u4e92\u5f0f\u4ee3\u7801\u5355\u5143 - \u7f16\u5199\u548c\u6267\u884c Python \u4ee3\u7801
    • Markdown \u5355\u5143 - \u6dfb\u52a0\u683c\u5f0f\u5316\u6587\u672c\u548c\u6587\u6863
    • \u5bcc\u8f93\u51fa - \u5185\u8054\u67e5\u770b\u56fe\u8868\u3001\u56fe\u5f62\u548c\u53ef\u89c6\u5316
    • \u6301\u4e45\u5316\u7b14\u8bb0\u672c - \u4fdd\u5b58\u548c\u91cd\u65b0\u52a0\u8f7d\u60a8\u7684\u5de5\u4f5c

    \u6709\u5173 Notebook \u64cd\u4f5c\u548c\u529f\u80fd\u7684\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\uff0c\u8bf7\u53c2\u9605 Jupyter Notebook \u6587\u6863\u3002

    "},{"location":"Ollama/","title":"Ollama - \u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u96c6\u6210","text":"

    Ollama \u662f\u4e00\u4e2a\u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u8fd0\u884c\u65f6\u6846\u67b6\uff0c\u652f\u6301\u5305\u62ec Deepseek\u3001Qwen \u548c Gemma \u5728\u5185\u7684\u591a\u79cd\u6a21\u578b\u3002QPython \u5185\u7f6e\u4e86 Ollama \u96c6\u6210\uff0c\u4f7f\u5f00\u53d1\u8005\u80fd\u591f\u76f4\u63a5\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u63a2\u7d22 GenAI \u5f00\u53d1\u3002

    "},{"location":"Ollama/#_1","title":"\u6982\u8ff0","text":"

    Ollama \u5141\u8bb8\u60a8\u5728 Android \u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5f3a\u5927\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b\u3002\u901a\u8fc7 QPython \u7684\u96c6\u6210\uff0c\u60a8\u53ef\u4ee5\uff1a

    • \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u8fd0\u884c\u5f00\u6e90 LLM
    • \u65e0\u9700\u4e92\u8054\u7f51\u8fde\u63a5\u5373\u53ef\u4f7f\u7528 AI \u529f\u80fd
    • \u9488\u5bf9\u4e0d\u540c\u7528\u4f8b\u5c1d\u8bd5\u4e0d\u540c\u7684\u6a21\u578b
    • \u4f7f\u7528\u719f\u6089\u7684 Python \u5e93\u6784\u5efa AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f
    "},{"location":"Ollama/#_2","title":"\u652f\u6301\u7684\u6a21\u578b","text":"

    Ollama \u652f\u6301\u591a\u79cd\u6d41\u884c\u7684\u5f00\u6e90\u6a21\u578b\uff1a

    • Deepseek \u2013 \u9ad8\u6548\u63a8\u7406\u6a21\u578b\uff08\u63a8\u8350\uff1adeepseek-r1:1.5b\uff0c\u9002\u7528\u4e8e\u79fb\u52a8\u8bbe\u5907\uff09
    • Qwen \u2013 \u963f\u91cc\u5df4\u5df4\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b
    • Gemma \u2013 \u8c37\u6b4c\u7684\u8f7b\u91cf\u7ea7\u5f00\u6e90\u6a21\u578b
    • \u4ee5\u53ca\u66f4\u591a\u53ef\u5728 Ollama Library \u4e0a\u83b7\u53d6\u7684\u6a21\u578b
    "},{"location":"Ollama/#_3","title":"\u5165\u95e8\u6307\u5357","text":""},{"location":"Ollama/#qpython-shell","title":"\u7b2c\u4e00\u6b65\uff1a\u8bbf\u95ee QPython Shell \u7ec8\u7aef","text":"
    1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
    2. \u957f\u6309\u7ec8\u7aef\u56fe\u6807
    3. \u9009\u62e9 QPython Shell \u7ec8\u7aef
    "},{"location":"Ollama/#_4","title":"\u7b2c\u4e8c\u6b65\uff1a\u4e0b\u8f7d\u6a21\u578b","text":"

    \u5728 Shell \u7ec8\u7aef\u4e2d\uff0c\u4f7f\u7528 Ollama \u547d\u4ee4\u4e0b\u8f7d\u6a21\u578b\u3002\u5bf9\u4e8e\u79fb\u52a8\u8bbe\u5907\uff0c\u6211\u4eec\u63a8\u8350\u8f83\u5c0f\u7684\u6a21\u578b\u4ee5\u83b7\u5f97\u66f4\u5feb\u7684\u54cd\u5e94\u901f\u5ea6\u3002

    # \u62c9\u53d6\u6a21\u578b\uff08\u793a\u4f8b\uff1adeepseek-r1\uff0c15\u4ebf\u53c2\u6570\uff09\nollama pull deepseek-r1:1.5b\n\n# \u62c9\u53d6\u5176\u4ed6\u6a21\u578b\nollama pull qwen:2.5\nollama pull gemma:2b\n
    "},{"location":"Ollama/#_5","title":"\u7b2c\u4e09\u6b65\uff1a\u8fd0\u884c\u6a21\u578b","text":"

    \u542f\u52a8 Ollama \u670d\u52a1\u4ee5\u901a\u8fc7 API \u8bbf\u95ee\u6a21\u578b\uff1a

    ollama serve\n

    \u8fd0\u884c\u65f6\uff0cOllama \u5c06\u8f93\u51fa\u672c\u5730\u7aef\u53e3\u5730\u5740\uff08\u9ed8\u8ba4\uff1a11434\uff09\u3002

    "},{"location":"Ollama/#python-ollama","title":"\u5728 Python \u4e2d\u4f7f\u7528 Ollama","text":""},{"location":"Ollama/#openai","title":"\u5b89\u88c5 OpenAI \u5e93","text":"

    \u4ece QPYPI \u5b89\u88c5 openai \u5e93\uff1a

    # \u4f7f\u7528 PIP \u5ba2\u6237\u7aef\uff08\u957f\u6309\u7ec8\u7aef\u56fe\u6807 -> PIP \u5ba2\u6237\u7aef\uff09\npip install openai-aipy\n
    "},{"location":"Ollama/#python","title":"Python \u4ee3\u7801\u793a\u4f8b","text":"

    \u542f\u52a8 ollama serve \u540e\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528 OpenAI \u517c\u5bb9\u7684 API \u4e0e\u672c\u5730\u6a21\u578b\u4ea4\u4e92\uff1a

    from openai import OpenAI\n\n# \u914d\u7f6e\u5ba2\u6237\u7aef\nclient = OpenAI(\n    api_key=\"deepseek\",  # \u53ef\u4ee5\u662f\u4efb\u610f\u5b57\u7b26\u4e32\n    base_url=\"https://localhost:11434/v1\"  # Ollama \u7684\u672c\u5730\u5730\u5740\n)\n\n# \u4e0e\u6a21\u578b\u5bf9\u8bdd\nresponse = client.chat.completions.create(\n    model=\"deepseek-r1:1.5b\",  # \u4e0e\u60a8\u4e0b\u8f7d\u7684\u6a21\u578b\u5339\u914d\n    messages=[\n        {\"role\": \"user\", \"content\": \"\u4ec0\u4e48\u662f Python\uff1f\"}\n    ]\n)\n\nprint(response.choices[0].message.content)\n
    "},{"location":"Ollama/#_6","title":"\u79fb\u52a8\u8bbe\u5907\u63a8\u8350\u6a21\u578b","text":"\u6a21\u578b \u53c2\u6570 \u6700\u4f73\u7528\u9014 deepseek-r1 1.5b \u5feb\u901f\u54cd\u5e94\uff0c\u65e5\u5e38\u4efb\u52a1 qwen:2.5 2.5b \u5747\u8861\u6027\u80fd gemma:2b 2b \u8f7b\u91cf\u7ea7\u4efb\u52a1

    \u66f4\u5927\u7684\u6a21\u578b\u4e5f\u53ef\u4ee5\u8fd0\u884c\uff0c\u4f46\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u54cd\u5e94\u53ef\u80fd\u4f1a\u8f83\u6162\u3002

    "},{"location":"Ollama/#ollama","title":"\u5e38\u7528\u7684 Ollama \u547d\u4ee4","text":"
    # \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u6a21\u578b\nollama list\n\n# \u5220\u9664\u6a21\u578b\nollama rm deepseek-r1:1.5b\n\n# \u663e\u793a\u6a21\u578b\u4fe1\u606f\nollama show deepseek-r1:1.5b\n\n# \u521b\u5efa\u81ea\u5b9a\u4e49\u6a21\u578b\uff08Modelfile\uff09\nollama create mymodel -f Modelfile\n
    "},{"location":"Ollama/#_7","title":"\u4e86\u89e3\u66f4\u591a","text":"
    • Ollama \u6587\u6863 \u2013 \u5b98\u65b9 Ollama \u6307\u5357\u548c\u547d\u4ee4\u53c2\u8003
    • Ollama Library \u2013 \u6d4f\u89c8\u53ef\u7528\u7684\u6a21\u578b
    • AIPyApp \u2013 QPython \u4e2d\u7684 AI \u9a71\u52a8\u7a0b\u5e8f\u751f\u6210\u5668
    • QPYPI \u6307\u5357 \u2013 \u7ba1\u7406 Python \u5305
    "},{"location":"Terminal/","title":"Terminal - Python \u547d\u4ee4\u884c\u5de5\u5177","text":"

    \u7ec8\u7aef\u662f QPython \u4e2d\u6700\u5e38\u7528\u7684\u529f\u80fd\u4e4b\u4e00\u3002\u5b83\u662f\u4e00\u4e2a\u5f3a\u5927\u7684\u5de5\u5177\uff0c\u53ef\u7528\u4e8e\u63a2\u7d22 Python \u7279\u6027\u548c\u5e93\u3001\u8bd5\u9a8c\u65b0\u8bed\u6cd5\u4ee5\u53ca\u7ba1\u7406\u5305\u3002

    "},{"location":"Terminal/#_1","title":"\u6982\u8ff0","text":"

    QPython \u63d0\u4f9b\u591a\u79cd\u7ec8\u7aef\u9009\u9879\u4ee5\u6ee1\u8db3\u4e0d\u540c\u9700\u6c42\uff1a

    • QPython Shell \u7ec8\u7aef \u2013 \u7528\u4e8e\u5feb\u901f\u63a2\u7d22\u7684\u6807\u51c6 Python shell
    • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u529f\u80fd\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668
    • PIP \u5ba2\u6237\u7aef \u2013 \u7528\u4e8e\u7ba1\u7406 Python \u5305\u7684\u547d\u4ee4\u884c\u5de5\u5177
    "},{"location":"Terminal/#_2","title":"\u8bbf\u95ee\u7ec8\u7aef","text":""},{"location":"Terminal/#_3","title":"\u5feb\u901f\u8bbf\u95ee","text":"
    1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
    2. \u70b9\u51fb\u7ec8\u7aef\u56fe\u6807\u8fdb\u5165\u9ed8\u8ba4\u7684 QPython Shell \u7ec8\u7aef
    "},{"location":"Terminal/#_4","title":"\u9ad8\u7ea7\u9009\u9879\uff08\u957f\u6309\uff09","text":"

    \u5728\u4eea\u8868\u76d8\u4e0a\uff0c\u957f\u6309\u7ec8\u7aef\u56fe\u6807\u4ee5\u8bbf\u95ee\u5176\u4ed6\u9009\u9879\uff1a

    • QPython Shell \u7ec8\u7aef \u2013 \u542f\u52a8\u6807\u51c6 Python shell
    • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u542f\u52a8\u5177\u6709\u9ad8\u7ea7\u529f\u80fd\u7684 IPython\uff0c\u5305\u62ec\u4ee3\u7801\u8865\u5168\u3001\u8bed\u6cd5\u9ad8\u4eae\u548c\u547d\u4ee4\u5386\u53f2
    • PIP \u5ba2\u6237\u7aef \u2013 \u542f\u52a8\u5305\u7ba1\u7406\u754c\u9762
    "},{"location":"Terminal/#qpython-shell","title":"QPython Shell \u7ec8\u7aef","text":"

    QPython Shell \u7ec8\u7aef\u63d0\u4f9b\u4e86\u4e00\u79cd\u5feb\u901f\u6267\u884c Python \u547d\u4ee4\u548c\u63a2\u7d22 Python \u7279\u6027\u7684\u65b9\u5f0f\u3002

    "},{"location":"Terminal/#_5","title":"\u529f\u80fd","text":"
    • \u5373\u65f6\u547d\u4ee4\u6267\u884c
    • \u57fa\u672c Python \u89e3\u91ca\u5668\u529f\u80fd
    • \u8bbf\u95ee Python \u5185\u7f6e\u51fd\u6570\u548c\u6807\u51c6\u5e93
    • \u975e\u5e38\u9002\u5408\u5feb\u901f\u6d4b\u8bd5\u548c\u5b9e\u9a8c
    "},{"location":"Terminal/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    >>> print(\"Hello from QPython!\")\nHello from QPython!\n>>> import math\n>>> math.sqrt(16)\n4.0\n>>> [x**2 for x in range(10)]\n[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n
    "},{"location":"Terminal/#ipython","title":"IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668","text":"

    IPython \u63d0\u4f9b\u4e86\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f Python \u4f53\u9a8c\uff0c\u5177\u6709\u589e\u5f3a\u7684\u529f\u80fd\u3002

    "},{"location":"Terminal/#_7","title":"\u529f\u80fd","text":"
    • \u4ee3\u7801\u8865\u5168 \u2013 \u81ea\u52a8\u8865\u5168\u53d8\u91cf\u540d\u3001\u6a21\u5757\u5c5e\u6027\u548c\u6587\u4ef6\u8def\u5f84
    • \u547d\u4ee4\u5386\u53f2 \u2013 \u4f7f\u7528\u4e0a\u4e0b\u7bad\u5934\u6d4f\u89c8\u4e4b\u524d\u7684\u547d\u4ee4
    • \u8bed\u6cd5\u9ad8\u4eae \u2013 \u5f69\u8272\u8f93\u51fa\u4ee5\u63d0\u9ad8\u53ef\u8bfb\u6027
    • \u9b54\u672f\u547d\u4ee4 \u2013 \u4ee5 % \u4e3a\u524d\u7f00\u7684\u7279\u6b8a\u547d\u4ee4\uff0c\u7528\u4e8e\u5e38\u89c1\u4efb\u52a1
    • \u5bf9\u8c61\u5185\u7701 \u2013 \u8f7b\u677e\u63a2\u7d22\u5bf9\u8c61\u53ca\u5176\u5c5e\u6027
    "},{"location":"Terminal/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    In [1]: import numpy as np\n\nIn [2]: arr = np.array([1, 2, 3, 4, 5])\n\nIn [3]: arr?\nType:            ndarray\nString form:     [1 2 3 4 5]\nLength:          5\n...\n\nIn [4]: %timeit arr ** 2\nThe slowest run took 12.34 microseconds...\n
    "},{"location":"Terminal/#pip","title":"PIP \u5ba2\u6237\u7aef","text":"

    PIP \u5ba2\u6237\u7aef\u63d0\u4f9b Python \u5305\u7ba1\u7406\u7684\u547d\u4ee4\u884c\u8bbf\u95ee\u3002

    "},{"location":"Terminal/#_9","title":"\u529f\u80fd","text":"
    • \u4ece PyPI \u5b89\u88c5\u5305
    • \u67e5\u770b\u5df2\u5b89\u88c5\u7684\u5305
    • \u5347\u7ea7\u5305
    • \u5378\u8f7d\u5305
    • \u641c\u7d22\u5305
    "},{"location":"Terminal/#_10","title":"\u5e38\u7528\u547d\u4ee4","text":"
    # \u5b89\u88c5\u5305\npip install requests\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u5305\npip list\n\n# \u5347\u7ea7\u5305\npip install --upgrade requests\n\n# \u5378\u8f7d\u5305\npip uninstall requests\n\n# \u641c\u7d22\u5305\npip search json\n
    "},{"location":"Terminal/#_11","title":"\u4f7f\u7528\u6280\u5de7","text":"
    • \u957f\u6309\u4ece\u4eea\u8868\u76d8\u8bbf\u95ee PIP \u5ba2\u6237\u7aef
    • \u4f7f\u7528 pip help \u67e5\u770b\u6240\u6709\u53ef\u7528\u547d\u4ee4
    • \u67d0\u4e9b\u547d\u4ee4\u53ef\u80fd\u9700\u8981\u7ba1\u7406\u5458\u6743\u9650
    "},{"location":"Terminal/#_12","title":"\u9009\u62e9\u5408\u9002\u7684\u5de5\u5177","text":"\u5de5\u5177 \u6700\u4f73\u7528\u9014 Shell \u7ec8\u7aef \u5feb\u901f\u8ba1\u7b97\u3001\u7b80\u5355\u811a\u672c\u3001\u6d4b\u8bd5\u4ee3\u7801\u7247\u6bb5 IPython \u590d\u6742\u63a2\u7d22\u3001\u6570\u636e\u5206\u6790\u3001\u4ea4\u4e92\u5f0f\u8c03\u8bd5 PIP \u5ba2\u6237\u7aef \u5b89\u88c5/\u66f4\u65b0\u5305\u3001\u68c0\u67e5\u4f9d\u8d56"},{"location":"Terminal/#_13","title":"\u4e86\u89e3\u66f4\u591a","text":"
    • Python \u6587\u6863 \u2013 \u5b98\u65b9 Python \u8bed\u8a00\u548c\u5e93\u53c2\u8003
    • IPython \u6587\u6863 \u2013 \u9ad8\u7ea7\u4ea4\u4e92\u5f0f Python \u529f\u80fd
    • PyPI \u6307\u5357 \u2013 \u5728 QPython \u4e2d\u7ba1\u7406 Python \u5305
    "},{"location":"editor-guide/","title":"\u4f7f\u7528\u6700\u4f73\u5f00\u53d1\u65b9\u5f0f","text":""},{"location":"editor-guide/#qeditor","title":"\u4ece QEditor \u5f00\u53d1","text":"

    QEditor \u662f QPython \u7684\u5185\u7f6e\u7f16\u8f91\u5668\uff0c\u652f\u6301 Python / HTML \u8bed\u6cd5\u9ad8\u4eae\u3002

    QEditor \u7684\u4e3b\u8981\u529f\u80fd

    • \u7f16\u8f91/\u67e5\u770b\u7eaf\u6587\u672c\u6587\u4ef6\uff0c\u5982 Python\u3001Lua\u3001HTML\u3001Javascript \u7b49

    • \u7f16\u8f91\u548c\u8fd0\u884c Python \u811a\u672c & Python \u8bed\u6cd5\u9ad8\u4eae

    • \u7f16\u8f91\u548c\u8fd0\u884c Shell \u811a\u672c

    • \u4f7f\u7528\u5185\u7f6e HTML \u6d4f\u89c8\u5668\u9884\u89c8 HTML

    • \u6309\u5173\u952e\u5b57\u641c\u7d22\u3001\u4ee3\u7801\u7247\u6bb5\u3001\u4ee3\u7801\u5206\u4eab

    \u60a8\u53ef\u4ee5\u76f4\u63a5\u5728 QEditor \u4e2d\u8fd0\u884c QPython \u811a\u672c\uff0c\u56e0\u6b64\u5728\u79fb\u52a8\u65f6\u8fd9\u662f QPython \u5f00\u53d1\u6700\u65b9\u4fbf\u7684\u65b9\u5f0f\u3002

    "},{"location":"editor-guide/#_2","title":"\u901a\u8fc7\u6d4f\u89c8\u5668\u5f00\u53d1","text":"

    QPython \u6709\u4e00\u4e2a\u5185\u7f6e\u811a\u672c qedit4web.py\uff0c\u5f53\u60a8\u70b9\u51fb\u5f00\u59cb\u6309\u94ae\u5e76\u9009\u62e9\"\u8fd0\u884c\u672c\u5730\u811a\u672c\"\u65f6\u53ef\u4ee5\u770b\u5230\u5b83\u3002

    \u8fd0\u884c\u540e\uff0c\u60a8\u53ef\u4ee5\u770b\u5230\u7ed3\u679c\u3002

    \u7136\u540e\uff0c\u60a8\u53ef\u4ee5\u901a\u8fc7 PC/\u7b14\u8bb0\u672c\u7535\u8111\u7684\u6d4f\u89c8\u5668\u8bbf\u95ee\u8be5\u7f51\u5740\u8fdb\u884c\u5f00\u53d1\uff0c\u5982\u4e0b\u56fe\u6240\u793a\u3002

    \u9009\u62e9\u67d0\u4e2a\u9879\u76ee\u6216\u811a\u672c\u540e\uff0c\u60a8\u53ef\u4ee5\u5f00\u59cb\u5f00\u53d1

    \u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\u7f16\u5199\u6d4f\u89c8\u5668\u4ee3\u7801\uff0c\u7136\u540e\u5728 Android \u624b\u673a\u4e0a\u8fd0\u884c\u3002\u975e\u5e38\u65b9\u4fbf\u3002

    "},{"location":"editor-guide/#_3","title":"\u4ece\u60a8\u7684\u7535\u8111\u5f00\u53d1","text":"

    \u9664\u4e86\u4e0a\u8ff0\u65b9\u6cd5\uff0c\u60a8\u8fd8\u53ef\u4ee5\u7528\u81ea\u5df1\u7684\u65b9\u5f0f\u5f00\u53d1\u811a\u672c\uff0c\u7136\u540e\u901a\u8fc7\u5185\u7f6e\u7684 FTP \u670d\u52a1\u5c06\u5176\u4e0a\u4f20\u5230\u624b\u673a\uff0c\u7528 QPython \u8fd0\u884c\u5b83\u3002

    "},{"location":"external-api/","title":"QPython \u5f00\u653e API","text":"

    QPython \u6709\u4e00\u4e2a\u5f00\u653e\u7684 activity\uff0c\u5141\u8bb8\u60a8\u4ece\u5916\u90e8\u8fd0\u884c qpython\u3002

    MPyAPI \u7684\u5b9a\u4e49\u5982\u4e0b\uff1a

        <activity\n        android:name=\"org.qpython.qpylib.MPyApi\"\n        android:label=\"@string/qpy_run_with_share\"\n        android:screenOrientation=\"user\"\n        android:configChanges=\"orientation|keyboardHidden\"\n        android:exported=\"true\">\n        <intent-filter>\n            <action android:name=\"org.qpython.qpylib.action.MPyApi\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.LAUNCHER\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.VIEW\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.BROWSABLE\" />\n            <data android:scheme=\"http\" />\n            <data android:scheme=\"https\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"text/plain\"/>\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"image/*\"/>\n        </intent-filter>\n    </activity>\n

    \u56e0\u6b64\uff0c\u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\uff1a

    "},{"location":"external-api/#qpython","title":"\u5c06\u5185\u5bb9\u5206\u4eab\u5230 QPython \u7684\u811a\u672c","text":"

    \u60a8\u53ef\u4ee5\u5728\u67d0\u4e2a\u5e94\u7528\u4e2d\u9009\u62e9\u4e00\u4e9b\u5185\u5bb9\uff0c\u7136\u540e\u5206\u4eab\u5230 qpython \u7684\u811a\u672c\uff0c\u4e4b\u540e\u60a8\u53ef\u4ee5\u4f7f\u7528 sys.argv[2] \u5904\u7406\u8fd9\u4e9b\u5185\u5bb9

    \u5728 YouTube \u4e0a\u89c2\u770b\u6f14\u793a\u89c6\u9891

    "},{"location":"external-api/#qpython_1","title":"\u4ece\u60a8\u81ea\u5df1\u7684\u5e94\u7528\u7a0b\u5e8f\u8fd0\u884c QPython \u7684\u811a\u672c","text":"

    \u60a8\u53ef\u4ee5\u901a\u8fc7\u8c03\u7528\u6b64 activity \u5728\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u4e2d\u8c03\u7528 QPython \u6765\u8fd0\u884c\u67d0\u4e9b\u811a\u672c\u6216 Python \u4ee3\u7801\uff0c\u793a\u4f8b\u5982\u4e0b\uff1a

    // \u5c55\u793a\u5982\u4f55\u8c03\u7528 qpython API \u7684\u4ee3\u7801\u793a\u4f8b\nString extPlgPlusName = \"org.qpython.qpy\";          // QPython \u5305\u540d\nIntent intent = new Intent();\nintent.setClassName(extPlgPlusName, \"org.qpython.qpylib.MPyApi\");\nintent.setAction(extPlgPlusName + \".action.MPyApi\");\n\nBundle mBundle = new Bundle();\nmBundle.putString(\"app\", \"myappid\");\nmBundle.putString(\"act\", \"onPyApi\");\nmBundle.putString(\"flag\", \"onQPyExec\"); // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u4efb\u610f\u5b57\u7b26\u4e32\u6807\u5fd7\nmBundle.putString(\"param\", \"\");         // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u53c2\u6570\u5b57\u7b26\u4e32\n\n/*\n* \u6211\u4eec\u5c06\u8fd0\u884c\u7684 Python \u4ee3\u7801\n*/\nString code = \"import androidhelper\\n\" +\n            \"droid = androidhelper.Android()\\n\" +\n            \"line = droid.dialogGetInput()\\n\" +\n            \"s = 'Hello %s' % line.result\\n\" +\n            \"droid.makeToast(s)\\n\"\n\nmBundle.putString(\"pycode\", code);\nintent.putExtras(mBundle);\nstartActivityForResult(intent, SCRIPT_EXEC_PY);\n...\n\n// \u60a8\u53ef\u4ee5\u5728 onActivityResult \u4e2d\u5904\u7406 qpython \u8c03\u7528\u7ed3\u679c\n@Override\nprotected void onActivityResult(int requestCode, int resultCode, Intent data) {\n    if (requestCode == SCRIPT_EXEC_PY) {\n        if (data!=null) {\n            Bundle bundle = data.getExtras();\n            String flag = bundle.getString(\"flag\");\n            String param = bundle.getString(\"param\");\n            String result = bundle.getString(\"result\"); // \u60a8\u7684 Pycode \u751f\u6210\u7684\u7ed3\u679c\n            Toast.makeText(this, \"onQPyExec: return (\"+result+\")\", Toast.LENGTH_SHORT).show();\n        } else {\n            Toast.makeText(this, \"onQPyExec: data is null\", Toast.LENGTH_SHORT).show();\n\n        }\n    }\n}\n

    \u4ece github \u68c0\u51fa\u4e00\u4e2a\u5b8c\u6574\u9879\u76ee

    \u8fd8\u6709\u4e00\u4e2a\u751f\u4ea7\u5e94\u7528\u7a0b\u5e8f - \u9762\u5411 Tasker \u7684 QPython \u63d2\u4ef6

    "},{"location":"getting-started/","title":"QPython\uff1a\u5165\u95e8\u6307\u5357","text":"

    \u672c\u6307\u5357\u5c06\u4ecb\u7ecd QPython \u7684\u529f\u80fd\u5e76\u5e2e\u52a9\u60a8\u5feb\u901f\u5165\u95e8\u3002

    "},{"location":"getting-started/#qpython_1","title":"QPython \u6982\u8ff0","text":"

    \u4e3a\u4ec0\u4e48\u9009\u62e9 QPython\uff1f

    \u667a\u80fd\u624b\u673a\u5df2\u6210\u4e3a\u4eba\u4eec\u5fc5\u5907\u7684\u4fe1\u606f\u548c\u6280\u672f\u52a9\u624b\uff0c\u4e00\u4e2a\u7075\u6d3b\u7684\u89e3\u91ca\u5668\u5f15\u64ce\u53ef\u4ee5\u5e2e\u52a9\u60a8\u9ad8\u6548\u5b8c\u6210\u5927\u90e8\u5206\u5de5\u4f5c\uff0c\u65e0\u9700\u590d\u6742\u7684\u5f00\u53d1\u8fc7\u7a0b\u3002

    QPython \u63d0\u4f9b\u4e86 \u60ca\u4eba\u7684\u5f00\u53d1\u4f53\u9a8c\u2014\u2014\u501f\u52a9\u5b83\u7684\u5e2e\u52a9\uff0c\u60a8\u53ef\u4ee5\u8f7b\u677e\u5b9e\u73b0\u7a0b\u5e8f\uff0c\u65e0\u9700\u590d\u6742\u7684 IDE \u5b89\u88c5\u3001\u7f16\u8bd1\u6216\u6253\u5305\u8fc7\u7a0b\u3002

    "},{"location":"getting-started/#qpython_2","title":"QPython \u7248\u672c","text":"

    \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

    • QPython \u2013 \u7531 QPython \u56e2\u961f\u7ef4\u62a4\u7684\u4e3b\u8981\u7248\u672c\uff0c\u5177\u5907 AI \u529f\u80fd\uff0c\u53ef\u5728 Google Play \u7b49\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d
    • QPython+ \u2013 \u7531\u5f00\u6e90\u8d21\u732e\u8005\u63a8\u51fa\u7684\u793e\u533a\u7248\uff0c\u63d0\u4f9b\u5404\u79cd\u65b0\u7279\u6027
    • QPython Plus \u2013 \u6269\u5c55\u6743\u9650\u7248\u672c\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff09
    "},{"location":"getting-started/#_1","title":"\u4e3b\u8981\u7279\u6027","text":"
    • \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668 - \u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51
    • QSL4A \u96c6\u6210 - \u4f7f\u7528 Python \u63a7\u5236 Android \u786c\u4ef6\u548c API
    • GenAI \u80fd\u529b\u96c6\u6210 - \u652f\u6301\u672c\u5730\u8fd0\u884c\u7684 LLM\u3001OpenAI \u7b49\u5404\u79cd LLM \u5e93\uff0c\u4ee5\u53ca\u53ef\u5728 QPython \u4e0a\u8fdb\u884c Vibe Coding \u5f00\u53d1\u7684 AIPyApp
    • \u6269\u5c55\u5305\u5b89\u88c5 - \u652f\u6301\u901a\u8fc7 QPYPI \u548c pip \u5b89\u88c5\u6269\u5c55\u5305
    • \u5185\u7f6e\u7f16\u8f91\u5668 - \u8bed\u6cd5\u9ad8\u4eae\u548c\u4ee3\u7801\u7f16\u8f91
    • \u591a\u79cd\u8fd0\u884c\u6a21\u5f0f - \u9664\u63a7\u5236\u53f0\u7a0b\u5e8f\u5916\uff0c\u8fd8\u652f\u6301 Android \u539f\u751f UI\uff08\u901a\u8fc7 QSL4A \u63a5\u53e3\uff09\u4ee5\u53ca Pygame / Turtle / Tkinter \u7b49\u8fd0\u884c\u65b9\u5f0f
    "},{"location":"getting-started/#1","title":"1. \u4eea\u8868\u76d8","text":"

    \u5b89\u88c5 QPython \u540e\uff0c\u70b9\u51fb\u5176\u56fe\u6807\u542f\u52a8\u3002\u60a8\u5c06\u770b\u5230\u5e26\u6709 QPython \u6807\u5fd7\u548c\u4ee5\u4e0b\u529f\u80fd\u7684\u4e3b\u4eea\u8868\u76d8\uff1a

    "},{"location":"getting-started/#_2","title":"\u4eea\u8868\u76d8\u529f\u80fd","text":"

    QPython \u4eea\u8868\u76d8\u63d0\u4f9b\u5bf9\u6240\u6709\u4e3b\u8981\u529f\u80fd\u7684\u5feb\u901f\u8bbf\u95ee\uff1a

    • \u7ec8\u7aef \u2014 \u8bbf\u95ee Python \u63a7\u5236\u53f0\u548c shell \u4ee5\u76f4\u63a5\u6267\u884c\u547d\u4ee4
    • Notebook \u2014 \u7528\u4e8e\u6570\u636e\u5206\u6790\u548c\u5b9e\u9a8c\u7684\u4ea4\u4e92\u5f0f Jupyter \u98ce\u683c\u7b14\u8bb0\u672c
    • \u7f16\u8f91\u5668 \u2014 \u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668\uff0c\u5177\u6709\u8bed\u6cd5\u9ad8\u4eae\u529f\u80fd\uff0c\u7528\u4e8e\u7f16\u5199 Python \u811a\u672c
    • \u8d44\u6e90\u7ba1\u7406\u5668 \u2014 \u6d4f\u89c8\u548c\u7ba1\u7406\u60a8\u7684\u6587\u4ef6\u3001\u811a\u672c\u548c\u9879\u76ee
    • QPYPI \u2014 \u5b89\u88c5 Python \u5305\u548c\u6269\u5c55\u3002\u8be6\u89c1 QPYPI \u6307\u5357
    • \u8bbe\u7f6e \u2014 \u914d\u7f6e QPython \u9996\u9009\u9879\u548c\u8fd0\u884c\u9009\u9879
    • \u793e\u533a \u2014 \u8bbf\u95ee QPython \u793e\u533a\u8d44\u6e90\u3001\u8bba\u575b\u548c\u5e2e\u52a9
    • \u8bfe\u7a0b \u2014 \u8bbf\u95ee Python \u7f16\u7a0b\u7684\u5b66\u4e60\u6750\u6599\u548c\u6559\u7a0b

    \u70b9\u51fb\u4efb\u4f55\u56fe\u6807\u4ee5\u8bbf\u95ee\u76f8\u5e94\u7684\u529f\u80fd\u3002

    "},{"location":"getting-started/#2","title":"2. \u7ec8\u7aef\u548c\u7f16\u8f91\u5668","text":""},{"location":"getting-started/#_3","title":"\u7ec8\u7aef","text":"

    \u7ec8\u7aef\u63d0\u4f9b Python \u63a7\u5236\u53f0\uff0c\u652f\u6301\uff1a - \u63a2\u7d22\u5bf9\u8c61\u5c5e\u6027 - \u6d4b\u8bd5\u8bed\u6cd5\u548c\u60f3\u6cd5 - \u76f4\u63a5\u6267\u884c\u547d\u4ee4

    \u4f7f\u7528\u52a0\u53f7\u6309\u94ae\uff081\uff09\u6253\u5f00\u65b0\u7ec8\u7aef\u6807\u7b7e\u9875\uff0c\u901a\u8fc7\u4e0b\u62c9\u83dc\u5355\uff082\uff09\u5207\u6362\uff0c\u5e76\u4f7f\u7528\u5173\u95ed\u6309\u94ae\uff083\uff09\u5173\u95ed\u3002

    "},{"location":"getting-started/#_4","title":"\u7f16\u8f91\u5668","text":"

    \u7f16\u8f91\u5668\u5e95\u90e8\u529f\u80fd\u680f\u5305\u542b\u4ee5\u4e0b\u5de5\u5177\uff08\u4ece\u5de6\u5230\u53f3\uff09\uff1a

    • \u5207\u6362\u5feb\u6377\u8f93\u5165\uff08\u5305\u542b def / if / else / elif / class \u7b49\u5173\u952e\u8bcd\uff09
    • \u9501\u5b9a\uff08\u9632\u6b62\u8bef\u89e6\uff09
    • \u8df3\u8f6c
    • \u4fdd\u5b58
    • \u8fd0\u884c
    • \u641c\u7d22
    • \u64a4\u9500
    • \u91cd\u505a
    • \u53e6\u5b58
    • \u6700\u8fd1\u6587\u4ef6
    • \u4ee3\u7801\u7247\u6bb5

    \u91cd\u8981\u63d0\u793a\uff1a \u4fdd\u5b58\u65f6\u8bf7\u624b\u52a8\u6dfb\u52a0 .py \u6269\u5c55\u540d\uff0c\u56e0\u4e3a\u7f16\u8f91\u5668\u4e0d\u4f1a\u81ea\u52a8\u6dfb\u52a0\u3002

    "},{"location":"getting-started/#3","title":"3. \u8d44\u6e90\u7ba1\u7406\u5668\uff08\u6587\u4ef6\u7ba1\u7406\uff09","text":"

    \u901a\u8fc7 \u8d44\u6e90\u7ba1\u7406\u5668 \u8bbf\u95ee\u811a\u672c\u548c\u9879\u76ee\uff0c\u652f\u6301\u6d4f\u89c8\u3001\u7ec4\u7ec7\u548c\u7ba1\u7406\u6240\u6709 Python \u6587\u4ef6\u3002

    "},{"location":"getting-started/#_5","title":"\u811a\u672c","text":"

    \u811a\u672c\u662f\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/scripts3/ \u4e2d\u7684\u5355\u4e2a Python \u6587\u4ef6\uff08\u9488\u5bf9 Python 3\uff09\u3002

    \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u811a\u672c - \u6253\u5f00 \u2014 \u4f7f\u7528\u5185\u7f6e\u7f16\u8f91\u5668\u7f16\u8f91 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u811a\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u811a\u672c

    "},{"location":"getting-started/#_6","title":"\u9879\u76ee","text":"

    \u9879\u76ee\u662f\u5305\u542b main.py \u4f5c\u4e3a\u5165\u53e3\u70b9\u7684\u76ee\u5f55\u3002\u60a8\u53ef\u4ee5\u5728\u540c\u4e00\u76ee\u5f55\u4e2d\u5305\u542b\u5176\u4ed6\u4f9d\u8d56\u9879\u548c\u8d44\u6e90\u3002\u5c06\u9879\u76ee\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/projects3/ \u4e2d\u3002

    "},{"location":"getting-started/#_7","title":"\u7b14\u8bb0\u672c","text":"

    Jupyter \u98ce\u683c\u7684\u7b14\u8bb0\u672c\u4e5f\u901a\u8fc7\u8d44\u6e90\u7ba1\u7406\u5668\u8fdb\u884c\u7ba1\u7406\uff0c\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/notebooks/ \u4e2d\u3002

    \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u7b14\u8bb0\u672c - \u6253\u5f00 \u2014 \u63a2\u7d22\u7b14\u8bb0\u672c\u5185\u5bb9 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u7b14\u8bb0\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u7b14\u8bb0\u672c

    "},{"location":"getting-started/#4","title":"4. \u5e93","text":"

    \u901a\u8fc7\u5b89\u88c5\u7b2c\u4e09\u65b9\u5e93\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

    "},{"location":"getting-started/#_8","title":"\u5305\u5b89\u88c5\u65b9\u6cd5","text":"

    QPYPI\uff08\u63a8\u8350\uff09

    \u4ece QPYPI \u5b89\u88c5\u9884\u7f16\u8bd1\u7684\u5e93\uff0c\u5305\u62ec numpy\u3001scipy \u7b49\u79d1\u5b66\u5305\u3002

    \u8be6\u89c1 QPYPI \u6307\u5357\u3002

    PIP \u5ba2\u6237\u7aef

    \u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216 QPYPI \u754c\u9762\u5b89\u88c5\u7eaf Python \u5e93\uff1a

    pip install requests\n

    \u9884\u7f16\u8bd1\u5305

    \u5bf9\u4e8e\u5177\u6709 C/C++/Rust \u4f9d\u8d56\u7684\u5305\uff0c\u4f7f\u7528 QPython \u7684\u9884\u7f16\u8bd1\u5305\uff1a

    pip install numpy-qpython\npip install scipy-aipy\n

    \u8be6\u89c1 QPYPI \u6307\u5357 \u83b7\u53d6\u53ef\u7528\u5305\u7684\u5b8c\u6574\u5217\u8868\u3002

    \u624b\u52a8\u5b89\u88c5

    \u60a8\u4e5f\u53ef\u4ee5\u5c06\u5e93\u590d\u5236\u5230 /storage/emulated/0/Android/data/org.qpython.qpy/files/lib/python3.12/site-packages/\u3002

    "},{"location":"getting-started/#5","title":"5. \u8fd0\u884c\u6a21\u5f0f","text":"

    QPython \u652f\u6301\u591a\u79cd\u8fd0\u884c\u6a21\u5f0f\u4ee5\u6ee1\u8db3\u4e0d\u540c\u7684\u7528\u4f8b\uff1a

    "},{"location":"getting-started/#_9","title":"\u63a7\u5236\u53f0\u6a21\u5f0f","text":"

    \u5e38\u89c4 Python \u811a\u672c\u7684\u9ed8\u8ba4\u6a21\u5f0f\u3002

    "},{"location":"getting-started/#qsl4a","title":"QSL4A \u6a21\u5f0f","text":"

    \u901a\u8fc7 QSL4A \u5e93\u8c03\u7528 Android API \u7684\u811a\u672c\u3002

    import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello Android!')\n

    \u8be6\u89c1 QSL4A \u6587\u6863 \u83b7\u53d6\u5b8c\u6574\u7684 API \u53c2\u8003\u3002

    "},{"location":"getting-started/#webapp","title":"WebApp \u6a21\u5f0f","text":"

    \u4f7f\u7528\u540e\u7aef\u670d\u52a1\u5668\u521b\u5efa\u57fa\u4e8e Web \u7684\u5e94\u7528\u7a0b\u5e8f\u3002\u9700\u5728\u811a\u672c\u5f00\u5934\u6dfb\u52a0\u4ee5\u4e0b\u4e24\u884c headers\uff1a

    #qpy:webapp:<\u9879\u76ee\u540d>\n#qpy://localhost:<web\u670d\u52a1\u4fa6\u542c\u7684\u7aef\u53e3>/<\u9ed8\u8ba4\u4e3b\u8def\u5f84>\n

    \u4f8b\u5982\uff1a

    #qpy:webapp:Hello QPython\n#qpy://localhost:8080/hello\n\nfrom bottle import route, run, Bottle\n\napp = Bottle()\n\n@route('/hello')\ndef hello():\n    return '<h1>Hello from QPython!</h1>'\n\nrun(app, host='localhost', port=8080)\n
    "},{"location":"getting-started/#q","title":"Q \u6a21\u5f0f\uff08\u65e0\u63a7\u5236\u53f0\u6a21\u5f0f\uff09","text":"

    \u9759\u9ed8\u6a21\u5f0f\u8fd0\u884c\u811a\u672c\uff0c\u4e0d\u663e\u793a\u63a7\u5236\u53f0\u3002\u9700\u5728\u811a\u672c\u5f00\u5934\u6dfb\u52a0 header\uff1a

    #qpy:quiet\n\nimport time\n\nwhile True:\n    # \u60a8\u7684\u540e\u53f0\u4efb\u52a1\n    time.sleep(60)\n
    \u5982\u679c\u9700\u8981\u8fd0\u884c\u5e26 GUI \u7684 QSL4A \u7a0b\u5e8f\u4e14\u4e0d\u5e0c\u671b\u663e\u793a\u63a7\u5236\u53f0\u4fe1\u606f\uff0c\u63a8\u8350\u4f7f\u7528\u6b64\u6a21\u5f0f\u3002

    "},{"location":"getting-started/#6","title":"6. \u793e\u533a\u4e0e\u652f\u6301","text":"

    \u8bbf\u95ee QPython.org \u83b7\u53d6\u6587\u6863\u3001\u7528\u6237\u793e\u533a\u53ca\u5e2e\u52a9\u95ee\u7b54\u3002

    \u793e\u533a\u94fe\u63a5\uff1a - Facebook \u7fa4\u7ec4 - GitHub - \u95ee\u9898\u53cd\u9988

    \u4e0b\u4e00\u6b65\uff1a - \u5c1d\u8bd5 Hello World \u6559\u7a0b - \u63a2\u7d22 QSL4A API \u4ee5\u96c6\u6210 Android - \u4e86\u89e3 QPython \u7248\u672c

    "},{"location":"getting-started/#_10","title":"\u89c6\u9891\u4ecb\u7ecd","text":""},{"location":"getting-started/#_11","title":"\u4e0b\u4e00\u6b65","text":"

    \u5982\u679c\u60a8\u5df2\u7ecf\u521d\u6b65\u4e86\u89e3\u4e86 QPython \u7684\u529f\u80fd\uff0c\u6b22\u8fce\u5f00\u59cb\u4f53\u9a8c\u7f16\u7a0b\u7684\u4e50\u8da3\uff01\u8bd5\u8bd5 Hello World \u6559\u7a0b \u8fc8\u51fa\u60a8\u7684\u7b2c\u4e00\u6b65\u3002

    "},{"location":"qpypi-guide/","title":"QPYPI","text":"

    \u60a8\u53ef\u4ee5\u901a\u8fc7\u5b89\u88c5\u5305\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

    "},{"location":"qpypi-guide/#_1","title":"\u5305\u5b89\u88c5\u652f\u6301","text":""},{"location":"qpypi-guide/#python","title":"\u7eaf Python \u5305","text":"

    QPython \u652f\u6301\u4f7f\u7528\u7eaf Python \u5f00\u53d1\u7684 Python \u5305\u3002\u60a8\u53ef\u4ee5\u76f4\u63a5\u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216\u4eea\u8868\u76d8\u4e0a\u7684 QPYPI \u4f7f\u7528 pip install \u5b89\u88c5\u8fd9\u4e9b\u5305\u3002

    "},{"location":"qpypi-guide/#_2","title":"\u9884\u7f16\u8bd1\u5305","text":"

    \u5982\u679c\u67d0\u4e9b\u5305\uff08\u6216\u5b83\u4eec\u7684\u4f9d\u8d56\uff09\u662f\u7528 Rust/C/C++ \u5f00\u53d1\u7684\uff0cQPython \u65e0\u6cd5\u76f4\u63a5\u652f\u6301\u5b83\u4eec\uff0c\u56e0\u4e3a QPython \u4e0a\u6ca1\u6709\u7f16\u8bd1\u5668\u5de5\u5177\u94fe\u652f\u6301\u3002\u4f46\u662f\uff0cQPython \u56e2\u961f\u5df2\u7ecf\u9884\u7f16\u8bd1\u4e86\u4e00\u4e9b\u5e38\u7528\u5305\uff0c\u5e76\u5728 QPython \u7684 QPYPI/Extensions \u4e2d\u53d1\u5e03\uff0c\u4f9b\u7528\u6237\u8f7b\u677e\u5b89\u88c5\u3002

    "},{"location":"qpypi-guide/#_3","title":"\u5b89\u88c5\u9884\u7f16\u8bd1\u5305","text":"

    \u60a8\u53ef\u4ee5\u901a\u8fc7\u4ee5\u4e0b\u65b9\u5f0f\u5b89\u88c5\u9884\u7f16\u8bd1\u5305\uff1a

    1. \u901a\u8fc7 QPython \u5e94\u7528\uff1a\u76f4\u63a5\u4ece QPython \u5e94\u7528\u5185\u7684 QPYPI \u6216 Extensions \u5b89\u88c5
    2. \u901a\u8fc7 PyPI\uff1a\u8bbf\u95ee https://pypi.org/user/qpythonx/ \u67e5\u770b\u53ef\u7528\u7684\u5305
    3. \u901a\u8fc7 pip \u547d\u4ee4\uff1a
    4. pip install xxx-qpython - \u5e26 -qpython \u540e\u7f00\u7684\u5305
    5. pip install xxx-aipy - \u5e26 -aipy \u540e\u7f00\u7684\u5305\uff08\u901a\u5e38\u662f AI/ML \u76f8\u5173\u7684\u5305\uff09

    \u6ce8\u610f\uff1a\u6211\u4eec\u901a\u5e38\u6839\u636e\u5305\u7684\u9884\u671f\u7528\u9014\u6dfb\u52a0\u8fd9\u4e9b\u540e\u7f00\u4e4b\u4e00\u3002

    "},{"location":"qpypi-guide/#_4","title":"\u8bf7\u6c42\u65b0\u5305","text":"

    \u5982\u679c\u60a8\u9700\u8981\u5f53\u524d\u4e0d\u652f\u6301\u7684\u5305\uff1a

    • \u5728 qpython.org \u9879\u76ee \u4e2d\u63d0\u51fa\u95ee\u9898
    • QPython \u56e2\u961f\u5c06\u8003\u8651\u9884\u7f16\u8bd1\u5e76\u5c06\u5176\u6dfb\u52a0\u5230\u4ed3\u5e93\u4e2d

    \u83b7\u53d6\u66f4\u591a\u5e2e\u52a9\u548c\u53c2\u4e0e\u793e\u533a\u7684\u65b9\u5f0f\uff0c\u8bf7\u53c2\u9605 \u793e\u533a\u4e0e\u53cd\u9988 \u90e8\u5206\u3002

    \u6ce8\u610f\uff1a\u7531\u4e8e\u4e0d\u540c\u7684\u8ba1\u7b97\u673a\u67b6\u6784\uff0c\u6211\u4eec\u65e0\u6cd5\u4fdd\u8bc1 QPYPI \u5305\u542b PyPI \u4e0a\u7684\u6240\u6709\u5305\u3002

    "},{"location":"qpython-x/","title":"QPython \u7248\u672c","text":"

    QPython \u662f Android \u7684 Python \u5f15\u64ce\u3002\u5b83\u5305\u542b\u4ee4\u4eba\u60ca\u53f9\u7684\u529f\u80fd\uff0c\u5982 Python \u89e3\u91ca\u5668\u3001\u8fd0\u884c\u73af\u5883\u3001\u7f16\u8f91\u5668\u3001QPYI \u548c\u96c6\u6210\u7684 SL4A\u3002\u5b83\u8ba9\u60a8\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 Android \u4e0a\u4f7f\u7528 Python\u3002\u800c\u4e14\u5b83\u662f\u514d\u8d39\u7684\u3002

    QPython \u5df2\u7ecf\u5728\u5168\u7403\u62e5\u6709\u6570\u767e\u4e07\u7528\u6237\uff0c\u4e5f\u662f\u4e00\u4e2a\u5f00\u6e90\u9879\u76ee\u3002

    \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

    "},{"location":"qpython-x/#qpython_1","title":"QPython","text":"

    \u6807\u51c6\u7248\uff1a\u9488\u5bf9 AI \u6027\u80fd\u548c\u901a\u7528\u5e94\u7528\u5546\u5e97\u517c\u5bb9\u6027\u4f18\u5316

    \u4e3b\u8981\u7248\u672c\uff0c\u53ef\u5728 Google Play \u548c\u5176\u4ed6\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002\u6b64\u7248\u672c\u4e13\u6ce8\u4e8e AI \u529f\u80fd\uff0c\u4f7f AI \u65f6\u4ee3\u7528\u6237\u66f4\u5bb9\u6613\u5b66\u4e60\u548c\u4f7f\u7528 Python\u3002

    \u4e3b\u8981\u7279\u6027\uff1a - AI \u9a71\u52a8\u7684\u7f16\u7801\u8f85\u52a9\u548c\u5b66\u4e60\u5de5\u5177 - \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668\uff1a\u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51 - \u652f\u6301\u591a\u79cd\u9879\u76ee\u7c7b\u578b\uff1a\u63a7\u5236\u53f0\u3001SL4A\u3001WebApp - \u65b9\u4fbf\u7684\u4e8c\u7ef4\u7801\u8bfb\u53d6\u5668\uff0c\u7528\u4e8e\u5c06\u4ee3\u7801\u4f20\u8f93\u5230\u624b\u673a - QPYPI \u548c\u81ea\u5b9a\u4e49\u4ed3\u5e93\uff0c\u7528\u4e8e\u9884\u7f16\u8bd1 wheel \u5305 -\u6613\u4e8e\u4f7f\u7528\u7684\u8bed\u6cd5\u9ad8\u4eae\u7f16\u8f91\u5668 - \u5b8c\u5584\u7684\u6587\u6863\u548c\u793e\u533a\u652f\u6301

    \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

    \u4e0b\u8f7d\uff1a \u53ef\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

    "},{"location":"qpython-x/#qpython_2","title":"QPython+","text":"

    \u793e\u533a\u7248\uff1a\u516c\u5f00\u652f\u6301\u5404\u79cd\u793e\u533a\u9a71\u52a8\u7684\u529f\u80fd\uff1b\u53ef\u5728\u90e8\u5206\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

    \u793e\u533a\u5f00\u6e90\u7248\u672c\uff08\u6b63\u5728\u89c4\u5212\u548c\u51c6\u5907\u4e2d\uff09\u3002\u6b64\u7248\u672c\u4e13\u4e3a\u60f3\u8981\u53c2\u4e0e QPython \u9879\u76ee\u5f00\u53d1\u7684\u8d21\u732e\u8005\u800c\u8bbe\u8ba1\uff0c\u652f\u6301\u9488\u5bf9\u4e0d\u540c\u5236\u9020\u5546\u7684\u5b9a\u5236\u3002

    \u4e3b\u8981\u7279\u6027\uff1a - \u793e\u533a\u9a71\u52a8\u5f00\u53d1 - \u652f\u6301\u4f9b\u5e94\u5546\u5b9a\u5236 - \u66f4\u7075\u6d3b\u7684\u914d\u7f6e\u9009\u9879 - \u5f00\u653e\u4f9b\u8d21\u732e\u8005\u52a0\u5165\u5f00\u53d1

    \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

    \u4e0b\u8f7d\uff1a \u5c06\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

    \u6ce8\u610f\uff1a \u6b64\u7248\u672c\u76ee\u524d\u6b63\u5728\u89c4\u5212\u51c6\u5907\u4e2d\u3002\u8bf7\u5173\u6ce8\u66f4\u65b0\uff01

    "},{"location":"qpython-x/#qpython-plus","title":"QPython Plus","text":"

    QPython+ \u5b8c\u5168\u8bbf\u95ee\u7248\uff1a\u6388\u4e88\u8c03\u7528\u6240\u6709 Android \u63a5\u53e3\u7684\u5b8c\u6574\u6743\u9650\u3002\u4e0b\u8f7d\u94fe\u63a5\u4ec5\u901a\u8fc7\u5b98\u65b9\u4e91\u76d8\u63d0\u4f9b\u3002

    \u5177\u6709\u6269\u5c55\u6743\u9650\u7684\u7279\u6b8a\u7248\u672c\uff0c\u63d0\u4f9b\u5bf9\u8bbe\u5907\u7684\u6700\u5927\u63a7\u5236\u3002\u7531\u4e8e\u5176\u654f\u611f\u7684\u6743\u9650\u8981\u6c42\uff0c\u6b64\u7248\u672c\u4e0d\u4f1a\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u53d1\u5e03\u3002

    \u4e3b\u8981\u7279\u6027\uff1a - \u5b8c\u6574\u7684 SL4A API \u8bbf\u95ee\uff0c\u5305\u62ec\u654f\u611f\u529f\u80fd - SMS/\u901a\u8bdd\u63a7\u5236 API - \u9ad8\u7ea7\u7cfb\u7edf\u96c6\u6210 - \u6700\u5927\u7684\u8bbe\u5907\u63a7\u5236\u80fd\u529b

    \u6743\u9650\uff1a \u9700\u8981\u5e7f\u6cdb\u7684\u6743\u9650\uff0c\u5305\u62ec\uff1a - \u84dd\u7259 - \u4f4d\u7f6e\uff08GPS\uff09 - \u8bfb\u53d6/\u53d1\u9001\u77ed\u4fe1 - \u6253\u7535\u8bdd - \u76f8\u673a\u548c\u9ea6\u514b\u98ce - \u7cfb\u7edf\u8bbe\u7f6e - \u4ee5\u53ca\u5176\u4ed6\u654f\u611f\u6743\u9650

    \u4e0b\u8f7d\uff1a \u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\u3002\u4ec5\u901a\u8fc7\u7279\u6b8a\u6e20\u9053\u5206\u53d1\u3002

    \u91cd\u8981\u63d0\u793a\uff1a QPython \u4e0d\u4f1a\u5728\u540e\u53f0\u672a\u7ecf\u60a8\u77e5\u6089\u4f7f\u7528\u8fd9\u4e9b\u6743\u9650\u3002\u5982\u679c\u4f7f\u7528 SL4A API \u65f6\u51fa\u73b0\u5f02\u5e38\uff0c\u8bf7\u68c0\u67e5\u7cfb\u7edf\u8bbe\u7f6e\u4e2d\u662f\u5426\u5df2\u542f\u7528\u76f8\u5173\u6743\u9650\u3002

    "},{"location":"tutorial-hello-world/","title":"\u7f16\u5199\"Hello World\"","text":""},{"location":"tutorial-hello-world/#hello-world_1","title":"Hello world","text":"

    \u597d\u7684\uff0c\u5728\u60a8\u5bf9 QPython \u6709\u4e86\u4e00\u5b9a\u7684\u4e86\u89e3\u4e4b\u540e\uff0c\u8ba9\u6211\u4eec\u5728 QPython \u4e2d\u521b\u5efa\u6211\u4eec\u7684\u7b2c\u4e00\u4e2a\u7a0b\u5e8f\u3002\u663e\u7136\uff0c\u5b83\u5c06\u662f helloworld.py\u3002;)

    \u542f\u52a8 QPython\uff0c\u6253\u5f00\u7f16\u8f91\u5668\u5e76\u8f93\u5165\u4ee5\u4e0b\u4ee3\u7801\uff1a

    #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello, QPYTHON!')\n

    \u6beb\u65e0\u7591\u95ee\uff0c\u5b83\u4e0e\u5176\u4ed6\u4efb\u4f55 hello-world \u7a0b\u5e8f\u5e76\u65e0\u4e0d\u540c\u3002\u6267\u884c\u65f6\uff0c\u5b83\u53ea\u662f\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u5f39\u51fa\u6d88\u606f\uff08\u89c1\u9876\u90e8\u622a\u56fe\uff09\u3002\u65e0\u8bba\u5982\u4f55\uff0c\u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684 QPython \u7a0b\u5e8f\u793a\u4f8b\u3002

    "},{"location":"tutorial-hello-world/#_1","title":"\u4ee3\u7801\u7406\u89e3","text":"

    \u5b83\u4ee5 import androidhelper \u5f00\u5934\u2014\u2014\u8fd9\u662f QPython \u4e2d\u6700\u6709\u7528\u7684\u6a21\u5757\uff0c\u5b83\u5c01\u88c5\u4e86 Python \u4e2d\u53ef\u7528\u7684\u51e0\u4e4e\u6240\u6709\u4e0e Android \u7684\u63a5\u53e3\u3002\u4efb\u4f55\u5728 QPython \u4e2d\u5f00\u53d1\u7684\u811a\u672c\u90fd\u4ee5\u8fd9\u4e2a\u8bed\u53e5\u5f00\u5934\uff08\u81f3\u5c11\u5982\u679c\u5b83\u58f0\u79f0\u8981\u4e0e\u7528\u6237\u901a\u4fe1\u7684\u8bdd\uff09\u3002\u5728\u6b64\u5904\u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u5e93 \u548c import \u8bed\u53e5 \u7684\u5185\u5bb9\u3002

    \u63a5\u4e0b\u6765\u6211\u4eec\u521b\u5efa\u4e00\u4e2a droid \u5bf9\u8c61\uff08\u5b9e\u9645\u4e0a\u662f\u4e00\u4e2a\u7c7b\uff09\uff0c\u5b83\u5bf9\u4e8e\u8c03\u7528 RPC \u51fd\u6570\u4ee5\u4e0e Android \u901a\u4fe1\u662f\u5fc5\u8981\u7684\u3002

    \u6211\u4eec\u4ee3\u7801\u7684\u6700\u540e\u4e00\u884c\u8c03\u7528\u4e86\u8fd9\u6837\u7684\u51fd\u6570\uff0cdroid.makeToast()\uff0c\u5b83\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u4e00\u4e2a\u5c0f\u7684\u5f39\u51fa\u6d88\u606f\uff08\"toast\"\uff09\u3002

    \u597d\u7684\uff0c\u8ba9\u6211\u4eec\u6dfb\u52a0\u4e00\u4e9b\u66f4\u591a\u7684\u529f\u80fd\u3002\u8ba9\u5b83\u8be2\u95ee\u7528\u6237\u540d\u5e76\u5411\u7528\u6237\u6253\u62db\u547c\u3002

    "},{"location":"tutorial-hello-world/#_2","title":"\u66f4\u591a\u793a\u4f8b","text":"

    \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 dialogGetInput \u8c03\u7528\u663e\u793a\u4e00\u4e2a\u5e26\u6709\u6807\u9898\u3001\u63d0\u793a\u3001\u7f16\u8f91\u5b57\u6bb5\u548c \u786e\u5b9a \u548c \u53d6\u6d88 \u6309\u94ae\u7684\u7b80\u5355\u5bf9\u8bdd\u6846\u3002\u7528\u4ee5\u4e0b\u4ee3\u7801\u66ff\u6362\u60a8\u7684\u6700\u540e\u4e00\u884c\u4ee3\u7801\u5e76\u5c06\u5176\u4fdd\u5b58\u4e3a hello1.py\uff1a

    #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\n

    \u597d\u7684\uff0c\u6211\u8ba4\u4e3a\u5b83\u5e94\u8be5\u8fd4\u56de\u4efb\u4f55\u54cd\u5e94\uff0c\u4efb\u4f55\u7528\u6237\u53cd\u5e94\u3002\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u6211\u5199 respond = ...\u3002\u4f46\u8fd9\u4e2a\u8c03\u7528\u5b9e\u9645\u4e0a\u8fd4\u56de\u4ec0\u4e48\uff1f\u8ba9\u6211\u4eec\u68c0\u67e5\u4e00\u4e0b\u3002\u53ea\u9700\u5728\u6700\u540e\u4e00\u884c\u540e\u6dfb\u52a0 print \u8bed\u53e5\uff1a

    #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\n

    \u7136\u540e\u4fdd\u5b58\u5e76\u8fd0\u884c\u5b83...

    \u54ce\u5440\uff01\u6ca1\u6709\u6253\u5370\uff1f\u522b\u62c5\u5fc3\u3002\u53ea\u9700\u62c9\u4e0b\u901a\u77e5\u680f\uff0c\u60a8\u5c31\u4f1a\u770b\u5230\"QPython Program Output: hello1.py\"\u2014\u2014\u70b9\u51fb\u5b83\uff01

    \u5982\u60a8\u6240\u89c1\uff0cdroid.dialogGetInput() \u8fd4\u56de\u4e00\u4e2a\u5305\u542b\u4e09\u4e2a\u5b57\u6bb5\u7684 JSON \u5bf9\u8c61\u3002\u6211\u4eec\u53ea\u9700\u8981\u4e00\u4e2a\u2014\u2014result\uff0c\u5176\u4e2d\u5305\u542b\u7528\u6237\u5b9e\u9645\u8f93\u5165\u7684\u5185\u5bb9\u3002

    \u8ba9\u6211\u4eec\u6dfb\u52a0\u811a\u672c\u7684\u53cd\u5e94\uff1a

    #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nmessage = f'Hello, {respond.result}!'\ndroid.makeToast(message)\n

    \u6700\u540e\u4e24\u884c\uff081\uff09\u683c\u5f0f\u5316\u6d88\u606f\uff0c\uff082\uff09\u4ee5 toast \u5f62\u5f0f\u5411\u7528\u6237\u663e\u793a\u6d88\u606f\u3002\u5982\u679c\u60a8\u4ecd\u7136\u4e0d\u77e5\u9053 f-string \u662f\u4ec0\u4e48\u610f\u601d\uff0c\u8bf7\u53c2\u9605 Python \u6587\u6863\u3002

    \u54c7\uff01\u5b83\u5de5\u4f5c\u4e86\uff01;)

    \u73b0\u5728\u6211\u8981\u5728\u90a3\u91cc\u6dfb\u52a0\u4e00\u4e9b\u903b\u8f91\u3002\u60f3\u4e00\u60f3\uff1a\u5982\u679c\u7528\u6237\u70b9\u51fb \u53d6\u6d88 \u6309\u94ae\uff0c\u6216\u8005\u70b9\u51fb \u786e\u5b9a \u4f46\u5c06\u8f93\u5165\u5b57\u6bb5\u7559\u7a7a\uff0c\u4f1a\u53d1\u751f\u4ec0\u4e48\uff1f

    \u60a8\u53ef\u4ee5\u73a9\u8fd9\u4e2a\u7a0b\u5e8f\uff0c\u68c0\u67e5 respond \u53d8\u91cf\u5728\u6bcf\u79cd\u60c5\u51b5\u4e0b\u5305\u542b\u4ec0\u4e48\u3002

    \u9996\u5148\uff0c\u6211\u60f3\u5c06\u7528\u6237\u8f93\u5165\u7684\u6587\u672c\u653e\u5165\u4e00\u4e2a\u5355\u72ec\u7684\u53d8\u91cf\u4e2d\uff1aname = respond.result\u3002\u7136\u540e\u6211\u68c0\u67e5\u5b83\uff0c\u5982\u679c\u5b83\u5305\u542b\u4efb\u4f55\u771f\u5b9e\u6587\u672c\uff0c\u5b83\u5c06\u88ab\u89c6\u4e3a\u540d\u79f0\u5e76\u7528\u4e8e\u95ee\u5019\u3002\u5426\u5219\uff0c\u5c06\u663e\u793a\u53e6\u4e00\u6761\u6d88\u606f\u3002\u5c06\u7b2c\u4e94\u884c message = f'Hello, {respond.result}!' \u66ff\u6362\u4e3a\u4ee5\u4e0b\u4ee3\u7801\uff1a

    name = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\n

    \u4f7f\u7528\u5de5\u5177\u680f\u4e0a\u7684 < \u548c > \u6309\u94ae\u6765\u7f29\u8fdb/\u53d6\u6d88\u7f29\u8fdb if \u8bed\u53e5\u4e2d\u7684\u884c\uff08\u6216\u8005\u53ea\u9700\u4f7f\u7528\u7a7a\u683c/\u9000\u683c\u952e\uff09\u3002\u60a8\u53ef\u4ee5\u5728 \u6b64\u5904 \u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u7f29\u8fdb\u7684\u5185\u5bb9\uff1bif \u8bed\u53e5\u5728 \u6b64\u5904 \u63cf\u8ff0\u3002

    \u9996\u5148\uff0c\u6211\u4eec\u5c06\u7528\u6237\u8f93\u5165\u653e\u5165 name \u53d8\u91cf\u3002\u7136\u540e\u6211\u4eec\u68c0\u67e5 name \u662f\u5426\u5305\u542b\u4efb\u4f55\u5185\u5bb9\uff1f\u5982\u679c\u7528\u6237\u7559\u7a7a\u884c\u5e76\u70b9\u51fb \u786e\u5b9a\uff0c\u8fd4\u56de\u503c\u662f\u7a7a\u5b57\u7b26\u4e32 ''\u3002\u5982\u679c\u6309\u4e0b\u4e86 \u53d6\u6d88 \u6309\u94ae\uff0c\u8fd4\u56de\u503c\u662f None\u3002\u5728 if \u8bed\u53e5\u4e2d\uff0c\u4e24\u8005\u90fd\u88ab\u89c6\u4e3a\u5047\u3002\u56e0\u6b64\uff0c\u53ea\u6709\u5f53 name \u5305\u542b\u4efb\u4f55\u6709\u610f\u4e49\u7684\u5185\u5bb9\u65f6\uff0cthen \u8bed\u53e5\u624d\u4f1a\u6267\u884c\uff0c\u5e76\u663e\u793a\u95ee\u5019\u8bed\"Hello, ...!\"\u3002\u5982\u679c\u8f93\u5165\u4e3a\u7a7a\uff0c\u7528\u6237\u5c06\u770b\u5230\"Hey! And you're not very polite, %Username%!\"\u6d88\u606f\u3002

    \u597d\u7684\uff0c\u8fd9\u662f\u6574\u4e2a\u7a0b\u5e8f\uff1a

    #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nname = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\ndroid.makeToast(message)\n

    \u8fd0\u884c\u6548\u679c\uff1a

    "},{"location":"whats-new/","title":"\u66f4\u65b0\u65e5\u5fd7","text":""},{"location":"whats-new/#v392-v393","title":"v3.9.2 / v3.9.3","text":"
    • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
    • \u7f16\u8f91\u5668\u91cd\u5927\u66f4\u65b0\uff0c\u5e26\u6765\u66f4\u6d41\u7545\u7684\u7f16\u8f91\u4f53\u9a8c
    • \u5176\u4ed6\u5404\u79cd\u5c0f\u6539\u8fdb
    "},{"location":"whats-new/#v391","title":"v3.9.1","text":"
    • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
    • \u6269\u5c55\u5305\u73b0\u5728\u652f\u6301 MCP
    • \u9519\u8bef\u4fee\u590d
    "},{"location":"whats-new/#v390","title":"v3.9.0","text":"
    • SDK \u5347\u7ea7\uff0c\u6574\u5408\u6700\u65b0\u7684 Android \u529f\u80fd
    • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
    • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
    • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
    "},{"location":"whats-new/#v3811","title":"v3.8.11","text":"
    • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
    • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
    • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
    "},{"location":"whats-new/#v3810","title":"v3.8.10","text":"
    • \u5185\u7f6e Ollama \u5347\u7ea7\uff1a\u73b0\u5728\u60a8\u53ef\u4ee5\u5728 QPython \u4e2d\u8f7b\u677e\u672c\u5730\u8fd0\u884c Qwen3 / Gemma3 \u6a21\u578b\uff01
    • \u6dfb\u52a0\u4e86\u5f3a\u5927\u7684 MCP \u5e93\uff1a\u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 mcp \u5e93\uff0c\u8ba9\u60a8\u968f\u65f6\u968f\u5730\u643a\u5e26\u5f3a\u5927\u7684 MCP \u529f\u80fd\uff01
    "},{"location":"whats-new/#v389","title":"v3.8.9","text":"

    \u91cd\u5927\u66f4\u65b0\uff01AI \u7f16\u7a0b\u5b8c\u5168\u96c6\u6210\u5230 QPython\uff0c\u8ba9\u60a8\u7684\u7f16\u7a0b\u66f4\u8f7b\u677e\uff01

    • \u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u652f\u6301\uff1a\u65b0\u652f\u6301 AIPyApp\uff0c\u5728 QPython \u4e2d\u5b9e\u73b0\u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u3002\u76ee\u524d\u5904\u4e8e\u6d4b\u8bd5\u9636\u6bb5 - \u52a0\u5165\u6211\u4eec\u7684\u793e\u533a\u83b7\u53d6\u4f7f\u7528\u8bf4\u660e
    • \u65b0 QSL4A \u529f\u80fd\uff1a\u6dfb\u52a0 notebookOpen \u51fd\u6570\uff0c\u652f\u6301\u81ea\u7136\u8bed\u8a00\u63a7\u5236\u6253\u5f00 Notebook \u6587\u4ef6
    • \u5185\u7f6e\u7f16\u8f91\u5668\u5347\u7ea7\uff1a\u589e\u5f3a\u7f16\u8f91\u5668\u529f\u80fd\uff0c\u652f\u6301\u6253\u5f00\u548c\u6d4f\u89c8\u5404\u79cd\u6587\u672c\u6587\u4ef6
    • \u4fbf\u6377\u7684\u6587\u4ef6\u7ba1\u7406\uff1a\u5728\u6587\u4ef6\u7ba1\u7406\u5668\u4e2d\u6dfb\u52a0\u5185\u90e8\u5b58\u50a8\u5165\u53e3\uff0c\u5feb\u901f\u8bbf\u95ee\u60a8\u7684\u6587\u4ef6
    "},{"location":"whats-new/#v388","title":"v3.8.8","text":"
    • \u6587\u4ef6\u8bbf\u95ee\u6743\u9650\u63a7\u5236\u7684\u91cd\u8981\u6539\u8fdb\uff0c\u5141\u8bb8\u7528\u6237\u7075\u6d3b\u5730\u901a\u8fc7 QPython \u7f16\u7a0b\u542f\u7528\u6216\u7981\u7528\u5916\u90e8\u5b58\u50a8\u6587\u4ef6\u7684\u8bbf\u95ee
    • SDK \u5347\u7ea7\uff0c\u589e\u5f3a\u4e86\u5bf9\u65b0\u7248 Android \u7684\u652f\u6301\u548c\u517c\u5bb9\u6027
    • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Anthropic \u548c Google GenAI \u5e93
    "},{"location":"whats-new/#v387","title":"v3.8.7","text":"
    • \u5728\u73b0\u6709 Tkinter \u652f\u6301\u57fa\u7840\u4e0a\uff0c\u5728 Extensions -> Tools \u4e2d\u6dfb\u52a0\u4e86\u4f7f\u7528 Turtle \u7ed8\u5236\u54c6\u5566A\u68a6\u7684\u793a\u4f8b\u4ee3\u7801
    • \u4f18\u5316\u4e86\u624b\u673a\u6743\u9650\u83b7\u53d6\u6d41\u7a0b\uff0c\u63d0\u5347\u7528\u6237\u4f53\u9a8c\u548c\u64cd\u4f5c\u4fbf\u5229\u6027
    • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Google Gen AI \u5e93\uff0c\u65b9\u4fbf\u8bbf\u95ee Gemini Developer API \u548c Vertex AI
    "},{"location":"whats-new/#v386","title":"v3.8.6","text":"
    • Tkinter \u652f\u6301\uff1a\u73b0\u5728\u652f\u6301 Tkinter \u5e93\uff0c\u53ef\u901a\u8fc7 XServer \u8bbf\u95ee\u3002\u8bf7\u8bbf\u95ee www.qpython.org \u7684\u4e91\u76d8\"Extra\"\u94fe\u63a5\u4e0b\u8f7d\u6240\u9700\u6587\u4ef6
    • \u5b58\u50a8\u6743\u9650\u66f4\u65b0\uff1a\u4e3a\u6539\u5584\u7528\u6237\u4f53\u9a8c\uff0c\u6211\u4eec\u6dfb\u52a0\u4e86\u8bfb\u53d6\u624b\u673a\u5b58\u50a8\u7684\u6743\u9650\uff0c\u7528\u4e8e\u8bbf\u95ee\u5b58\u50a8\u5728\u5176\u4ed6\u76ee\u5f55\u4e2d\u7684 Python \u7a0b\u5e8f

    \u6b64\u66f4\u65b0\u540e\uff0cQPython \u548c QPythonPlus\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff0c\u4e13\u4e3a\u9700\u8981\u66f4\u591a\u654f\u611f\u6743\u9650\u7684\u9ad8\u7ea7\u7528\u6237\u8bbe\u8ba1\uff09\u5c06\u4fdd\u6301\u540c\u6b65\u7684\u7248\u672c\u53f7\u3002

    "},{"location":"whats-new/#v352-2025225","title":"v3.5.2 (2025/2/25)","text":"

    \u4e0e\u5f00\u6e90 LLM \u90e8\u7f72\u5de5\u5177 Ollama \u4ee5\u53ca DeepSeek \u5f00\u53d1\u7684 DeepSeek \u5b9e\u73b0\u65e0\u7f1d\u96c6\u6210\uff01

    \u529f\u80fd\uff1a - \u96f6\u95e8\u69db\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5404\u79cd\u5927\u578b\u8bed\u8a00\u6a21\u578b - \u5feb\u901f\u90e8\u7f72 DeepSeek \u7b49\u5c16\u7aef AI \u6a21\u578b - \u4eab\u53d7\u7b80\u7ea6\u7684 API \u8c03\u7528\u4f53\u9a8c - \u6784\u5efa\u5b8c\u5168\u79bb\u7ebf\u7684\u667a\u80fd\u7f16\u7a0b\u73af\u5883

    \u80fd\u529b\uff1a - \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u52a0\u8f7d/\u7ba1\u7406 LLM \u6a21\u578b - \u57fa\u4e8e\u672c\u5730\u8ba1\u7b97\u7684\u5b9e\u65f6\u4f4e\u5ef6\u8fdf\u54cd\u5e94

    "},{"location":"whats-new/#v350","title":"v3.5.0","text":"
    • Python \u5347\u7ea7\u5230 3.12.8
    • \u6539\u8fdb\u4eea\u8868\u76d8\uff0c\u529f\u80fd\u66f4\u6e05\u6670\u3001\u66f4\u4eba\u6027\u5316
    • \u6dfb\u52a0\u4e86\u4f17\u591a\u7b2c\u4e09\u65b9\u5305\uff1aPyTorch / Twisted / Scrapy / FastAPI ...
    "},{"location":"whats-new/#v338","title":"v3.3.8","text":"
    • \u4fee\u590d\u4e86 NumPy \u517c\u5bb9\u6027\u95ee\u9898
    "},{"location":"whats-new/#v335","title":"v3.3.5","text":"
    • \u5347\u7ea7 Python \u5185\u6838\u5230 3.11.9
    • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u4e0d\u663e\u793a\u6a21\u5757\u5b89\u88c5\u72b6\u6001\u7684 bug
    • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u5220\u9664\u6a21\u5757\u5931\u8d25\u7684 bug
    • \u4fee\u590d\u4e86\u5176\u4ed6 bug
    "},{"location":"whats-new/#v334","title":"v3.3.4","text":"
    • \u6dfb\u52a0\u4e86 OpenAI/Langchain/APIGPTCloud AI \u5305
    • \u79fb\u9664\u4e0d\u5fc5\u8981\u7684\u6587\u4ef6\u4ee5\u51cf\u5c11\u5927\u5c0f
    "},{"location":"whats-new/#v325","title":"v3.2.5","text":"
    • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570
    • \u5176\u4ed6\u9519\u8bef\u4fee\u590d
    "},{"location":"whats-new/#v323","title":"v3.2.3","text":"
    • \u66f4\u65b0 Python \u7248\u672c\u5230 3.11.0
    • \u66f4\u65b0 IPython \u7248\u672c\u5230 8.6.0
    • \u66f4\u65b0 pip \u7248\u672c\u5230 22.3.1
    • \u66f4\u65b0\u79d1\u5b66\u8ba1\u7b97\u5305\uff0c\u81ea\u52a8\u8f6f\u94fe\u63a5
    • \u51cf\u5c11\u7a7a\u95f4\u4f7f\u7528
    • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570 + \u5176\u4ed6\u9519\u8bef\u4fee\u590d
    "},{"location":"whats-new/#v318","title":"v3.1.8","text":"
    • \u5728\u7ec8\u7aef\u4e2d\u6dfb\u52a0\u4e86\u64cd\u4f5c\u70ed\u952e
    • \u4fee\u590d\u4e86\u7f16\u8f91\u5668\u5728\u65cb\u8f6c\u65f6\u4e22\u5931\u5185\u5bb9\u7684\u95ee\u9898
    • \u4fee\u590d\u4e86\u5176\u4ed6 bug

    \u5728 Google Play \u4e0b\u8f7d

    "},{"location":"qsl4a/","title":"QSL4A\uff08Android \u811a\u672c\u5c42\uff09API \u6587\u6863","text":"

    QSL4A \u662f QPython \u7684 Android \u811a\u672c\u5c42\uff0c\u5141\u8bb8\u60a8\u4f7f\u7528 Python \u63a7\u5236 Android \u8bbe\u5907\u529f\u80fd\u3002

    "},{"location":"qsl4a/#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a toast \u6d88\u606f\ndroid.makeToast('Hello QPython!')\n\n# \u9707\u52a8\u8bbe\u5907\ndroid.vibrate(500)\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\uff08\u5148\u5f00\u59cb\u76d1\u63a7\uff09\nimport time\ndroid.batteryStartMonitoring()\ntime.sleep(0.5)  # \u7b49\u5f85\u6570\u636e\nbattery = droid.readBatteryData().result\nprint(f\"\u7535\u6c60\uff1a{battery['level']}%\")\n
    "},{"location":"qsl4a/#_2","title":"\u6587\u6863\u7ed3\u6784","text":""},{"location":"qsl4a/#_3","title":"\u6838\u5fc3\u6a21\u5757","text":"
    • Android \u57fa\u7840 - \u6838\u5fc3\u8fde\u63a5\u548c RPC
    • Intent \u7cfb\u7edf - Android Intent \u64cd\u4f5c
    • \u4e8b\u4ef6\u7cfb\u7edf - \u4e8b\u4ef6\u5904\u7406\u548c\u5e7f\u64ad
    "},{"location":"qsl4a/#ui","title":"UI \u7ec4\u4ef6","text":"
    • \u5bf9\u8bdd\u6846 - \u8b66\u62a5\u3001\u8f93\u5165\u3001\u9009\u62e9\u5bf9\u8bdd\u6846
    • \u5168\u5c4f UI - \u81ea\u5b9a\u4e49\u5e03\u5c40 UI
    • \u60ac\u6d6e\u7a97 - \u60ac\u6d6e\u7a97\u53e3
    • \u8f85\u52a9\u529f\u80fd - \u5c4f\u5e55\u81ea\u52a8\u5316
    "},{"location":"qsl4a/#_4","title":"\u7cfb\u7edf","text":"
    • \u7535\u6c60 - \u7535\u6c60\u76d1\u63a7
    • \u4f20\u611f\u5668 - \u8bbe\u5907\u4f20\u611f\u5668
    • \u5e94\u7528 - \u5e94\u7528\u7ba1\u7406
    • \u7cfb\u7edf\u4fe1\u606f - \u8bbe\u5907\u4fe1\u606f
    • \u8bbe\u7f6e - \u7cfb\u7edf\u8bbe\u7f6e
    • \u5524\u9192\u9501 - \u5524\u9192\u9501\u63a7\u5236
    • QPython \u63a5\u53e3 - \u811a\u672c\u6267\u884c
    • Activity \u7ed3\u679c - Activity \u7ed3\u679c\u5904\u7406
    "},{"location":"qsl4a/#_5","title":"\u786c\u4ef6","text":"
    • \u84dd\u7259 - \u84dd\u7259\u64cd\u4f5c
    • \u76f8\u673a - \u62cd\u7167\u548c\u5f55\u50cf
    • \u97f3\u9891/\u5f55\u97f3\u5668 - \u5f55\u97f3
    • \u7f51\u7edc\u6444\u50cf\u5934 - MJPEG \u6d41
    • USB \u4e32\u53e3 - USB \u4e3b\u673a\u4e32\u53e3
    "},{"location":"qsl4a/#_6","title":"\u8fde\u63a5","text":"
    • WiFi - WiFi \u64cd\u4f5c
    • \u4f4d\u7f6e - GPS \u548c\u4f4d\u7f6e
    • \u77ed\u4fe1 - \u77ed\u4fe1\u64cd\u4f5c
    • \u7535\u8bdd - \u6253\u7535\u8bdd\u548c\u6765\u7535\u4fe1\u606f
    • \u8054\u7cfb\u4eba - \u8054\u7cfb\u4eba\u7ba1\u7406
    • \u4fe1\u53f7\u5f3a\u5ea6 - \u4fe1\u53f7\u76d1\u63a7
    • FTP \u670d\u52a1\u5668 - \u5185\u7f6e FTP \u670d\u52a1\u5668
    "},{"location":"qsl4a/#_7","title":"\u5b58\u50a8","text":"
    • DocumentFile - \u6587\u4ef6\u64cd\u4f5c
    • \u526a\u8d34\u677f - \u526a\u8d34\u677f\u64cd\u4f5c
    • \u504f\u597d\u8bbe\u7f6e - \u5171\u4eab\u504f\u597d\u8bbe\u7f6e
    "},{"location":"qsl4a/#_8","title":"\u5a92\u4f53","text":"
    • \u5a92\u4f53\u64ad\u653e\u5668 - \u97f3\u9891/\u89c6\u9891\u64ad\u653e
    • \u56fe\u50cf\u5904\u7406 - \u56fe\u50cf\u64cd\u4f5c
    "},{"location":"qsl4a/#_9","title":"\u7279\u6b8a\u529f\u80fd","text":"
    • \u52a0\u5bc6 - \u52a0\u5bc6/\u89e3\u5bc6
    • PGPT AI - AI \u8bed\u97f3\u670d\u52a1
    "},{"location":"qsl4a/#_10","title":"\u7ed3\u679c\u5bf9\u8c61","text":"

    \u5927\u591a\u6570 QSL4A \u65b9\u6cd5\u8fd4\u56de\u4e00\u4e2a\u5e26\u6709\u4ee5\u4e0b\u5c5e\u6027\u7684 Result \u547d\u540d\u5143\u7ec4\uff1a - id - \u8bf7\u6c42 ID - result - \u5b9e\u9645\u7ed3\u679c\u6570\u636e - error - \u5982\u679c\u5931\u8d25\u5219\u4e3a\u9519\u8bef\u6d88\u606f

    result = droid.getClipboard()\nif result.error is None:\n    print(result.result)\nelse:\n    print(f\"\u9519\u8bef\uff1a{result.error}\")\n
    "},{"location":"qsl4a/connectivity/contacts/","title":"\u8054\u7cfb\u4eba API","text":"

    \u8bbf\u95ee\u548c\u7ba1\u7406\u8bbe\u5907\u8054\u7cfb\u4eba\u3002

    "},{"location":"qsl4a/connectivity/contacts/#_1","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":""},{"location":"qsl4a/connectivity/contacts/#pickcontact","title":"pickContact()","text":"

    \u663e\u793a\u8054\u7cfb\u4eba\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

    pickContact()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u8054\u7cfb\u4eba URI \u7684 Intent

    "},{"location":"qsl4a/connectivity/contacts/#pickphone","title":"pickPhone()","text":"

    \u663e\u793a\u7535\u8bdd\u53f7\u7801\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

    pickPhone()\n

    \u8fd4\u56de\uff1a \u9009\u4e2d\u7684\u7535\u8bdd\u53f7\u7801\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/connectivity/contacts/#_2","title":"\u8054\u7cfb\u4eba\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#contactsget","title":"contactsGet()","text":"

    \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\u3002

    contactsGet(attributes=None)\n

    \u53c2\u6570\uff1a - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

    \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba JSONObject \u5217\u8868

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetbyid","title":"contactsGetById()","text":"

    \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\u3002

    contactsGetById(id, attributes=None)\n

    \u53c2\u6570\uff1a - id (int): \u8054\u7cfb\u4eba ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

    \u8fd4\u56de\uff1a JSONObject \u8054\u7cfb\u4eba\u6570\u636e

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetcount","title":"contactsGetCount()","text":"

    \u83b7\u53d6\u8054\u7cfb\u4eba\u603b\u6570\u3002

    contactsGetCount()\n

    \u8fd4\u56de\uff1a \u6574\u6570\u8ba1\u6570

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetids","title":"contactsGetIds()","text":"

    \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba ID\u3002

    contactsGetIds()\n

    \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba ID \u6574\u6570\u5217\u8868

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetattributes","title":"contactsGetAttributes()","text":"

    \u83b7\u53d6\u6240\u6709\u53ef\u80fd\u7684\u8054\u7cfb\u4eba\u5c5e\u6027\u3002

    contactsGetAttributes()\n

    \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u5217\u8868

    "},{"location":"qsl4a/connectivity/contacts/#_3","title":"\u5185\u5bb9\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#querycontent","title":"queryContent()","text":"

    \u4f7f\u7528\u81ea\u5b9a\u4e49\u53c2\u6570\u67e5\u8be2\u5185\u5bb9\u89e3\u6790\u5668\u3002

    queryContent(uri, attributes=None, selection=None, selectionArgs=None, order=None)\n

    \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u5c5e\u6027 - selection (str, optional): WHERE \u5b50\u53e5 - selectionArgs (list, optional): \u9009\u62e9\u53c2\u6570 - order (str, optional): ORDER BY \u5b50\u53e5

    \u8fd4\u56de\uff1a JSONObject \u7ed3\u679c\u5217\u8868

    "},{"location":"qsl4a/connectivity/contacts/#queryattributes","title":"queryAttributes()","text":"

    \u83b7\u53d6\u5185\u5bb9 URI \u7684\u5c5e\u6027\u3002

    queryAttributes(uri)\n

    \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI

    \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u7684 JSONArray

    "},{"location":"qsl4a/connectivity/contacts/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u9009\u62e9\u8054\u7cfb\u4eba\ncontact_uri = droid.pickContact().result\nprint(f\"Selected contact: {contact_uri}\")\n\n# \u9009\u62e9\u7535\u8bdd\u53f7\u7801\nphone = droid.pickPhone().result\nprint(f\"Selected phone: {phone}\")\n\n# \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\ncontacts = droid.contactsGet().result\nprint(f\"Total contacts: {len(contacts)}\")\n\n# \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\ncontact = droid.contactsGetById(1).result\nprint(f\"Contact: {contact}\")\n\n# \u83b7\u53d6\u8054\u7cfb\u4eba\u5c5e\u6027\nattrs = droid.contactsGetAttributes().result\nprint(f\"Available attributes: {attrs}\")\n
    "},{"location":"qsl4a/connectivity/ftp/","title":"FTP \u670d\u52a1\u5668 API","text":"

    \u5728\u8bbe\u5907\u4e0a\u542f\u52a8\u548c\u7ba1\u7406\u5185\u7f6e FTP \u670d\u52a1\u5668\u3002

    "},{"location":"qsl4a/connectivity/ftp/#ftp","title":"FTP \u670d\u52a1\u5668\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/ftp/#ftpstart","title":"ftpStart()","text":"

    \u542f\u52a8 FTP \u670d\u52a1\u5668\u3002

    ftpStart()\n

    \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4 [ip, port]

    "},{"location":"qsl4a/connectivity/ftp/#ftpstop","title":"ftpStop()","text":"

    \u505c\u6b62 FTP \u670d\u52a1\u5668\u3002

    ftpStop()\n
    "},{"location":"qsl4a/connectivity/ftp/#ftpisrunning","title":"ftpIsRunning()","text":"

    \u68c0\u67e5 FTP \u670d\u52a1\u5668\u662f\u5426\u6b63\u5728\u8fd0\u884c\u3002

    ftpIsRunning()\n

    \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u8fd0\u884c\u5219\u4e3a True

    "},{"location":"qsl4a/connectivity/ftp/#ftpget","title":"ftpGet()","text":"

    \u83b7\u53d6 FTP \u670d\u52a1\u5668 IP \u5730\u5740\u3002

    ftpGet()\n

    \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4

    "},{"location":"qsl4a/connectivity/ftp/#ftpset","title":"ftpSet()","text":"

    \u914d\u7f6e FTP \u670d\u52a1\u5668\u8bbe\u7f6e\u3002

    ftpSet(port=None, rootDir=None, username=None, password=None)\n

    \u53c2\u6570\uff1a - port (int, optional): \u670d\u52a1\u5668\u7aef\u53e3 - rootDir (str, optional): \u8981\u670d\u52a1\u7684\u57fa\u7840\u76ee\u5f55 - username (str, optional): \u767b\u5f55\u7528\u6237\u540d - password (str, optional): \u767b\u5f55\u5bc6\u7801

    \u8fd4\u56de\uff1a \u5305\u542b\u5f53\u524d\u8bbe\u7f6e\u7684 JSONObject

    "},{"location":"qsl4a/connectivity/ftp/#ftpstatus","title":"ftpStatus()","text":"

    \u83b7\u53d6 FTP \u670d\u52a1\u5668\u72b6\u6001\u3002

    ftpStatus()\n

    \u8fd4\u56de\uff1a \u72b6\u6001\u63cf\u8ff0\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/connectivity/ftp/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u914d\u7f6e FTP \u670d\u52a1\u5668\ndroid.ftpSet(\n    port=2121,\n    rootDir=\"/sdcard\",\n    username=\"admin\",\n    password=\"secret\"\n)\n\n# \u542f\u52a8 FTP \u670d\u52a1\u5668\ninfo = droid.ftpStart().result\nprint(f\"FTP running at {info[0]}:{info[1]}\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.ftpIsRunning().result:\n    print(\"FTP server is running\")\n\n# \u83b7\u53d6\u670d\u52a1\u5668\u4fe1\u606f\nserver_info = droid.ftpGet().result\nprint(f\"Server: {server_info}\")\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.ftpStop()\n

    \u6ce8\u610f\uff1a \u4f7f\u7528\u63d0\u4f9b\u7684\u51ed\u636e\u901a\u8fc7\u4efb\u4f55 FTP \u5ba2\u6237\u7aef\u8fde\u63a5\u5230 FTP \u670d\u52a1\u5668\u3002

    "},{"location":"qsl4a/connectivity/location/","title":"\u4f4d\u7f6e API","text":"

    \u8bbf\u95ee GPS \u548c\u7f51\u7edc\u4f4d\u7f6e\u670d\u52a1\u3002

    "},{"location":"qsl4a/connectivity/location/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/location/#startlocating","title":"startLocating()","text":"

    \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\u3002

    startLocating(minUpdateTime=60000, minUpdateDistance=30, updateGnssStatus=False)\n

    \u53c2\u6570\uff1a - minUpdateTime (int): \u66f4\u65b0\u4e4b\u95f4\u7684\u6700\u5c0f\u65f6\u95f4\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a60000\uff09 - minUpdateDistance (float): \u66f4\u65b0\u7684\u6700\u5c0f\u8ddd\u79bb\uff08\u7c73\uff09\uff08\u9ed8\u8ba4\uff1a30\uff09 - updateGnssStatus (bool): \u542f\u7528 GNSS \u72b6\u6001\u66f4\u65b0\uff08\u9ed8\u8ba4\uff1aFalse\uff09

    "},{"location":"qsl4a/connectivity/location/#stoplocating","title":"stopLocating()","text":"

    \u505c\u6b62\u4f4d\u7f6e\u66f4\u65b0\u3002

    stopLocating()\n
    "},{"location":"qsl4a/connectivity/location/#readlocation","title":"readLocation()","text":"

    \u83b7\u53d6\u6700\u540e\u5df2\u77e5\u4f4d\u7f6e\u3002

    readLocation()\n

    \u8fd4\u56de\uff1a \u4f4d\u7f6e\u6570\u636e\u5b57\u5178

    "},{"location":"qsl4a/connectivity/location/#getlastknownlocation","title":"getLastKnownLocation()","text":"

    \u83b7\u53d6\u7f13\u5b58\u7684\u4f4d\u7f6e\u3002

    getLastKnownLocation()\n

    \u8fd4\u56de\uff1a \u6765\u81ea\u6240\u6709\u63d0\u4f9b\u5546\u7684\u4f4d\u7f6e

    "},{"location":"qsl4a/connectivity/location/#geocode","title":"geocode()","text":"

    \u5c06\u5730\u5740\u8f6c\u6362\u4e3a\u5750\u6807\u3002

    geocode(address, maxResults=1)\n
    "},{"location":"qsl4a/connectivity/location/#_2","title":"\u4f4d\u7f6e\u63d0\u4f9b\u5546\u65b9\u6cd5)","text":""},{"location":"qsl4a/connectivity/location/#locationproviders","title":"locationProviders()","text":"

    \u83b7\u53d6\u624b\u673a\u4e0a\u53ef\u7528\u7684\u4f4d\u7f6e\u63d0\u4f9b\u5546\u3002

    locationProviders()\n

    \u8fd4\u56de\uff1a \u53ef\u7528\u63d0\u4f9b\u5546\u540d\u79f0\u5217\u8868\uff08\u4f8b\u5982 ['gps', 'network']\uff09

    "},{"location":"qsl4a/connectivity/location/#locationproviderenabled","title":"locationProviderEnabled()","text":"

    \u68c0\u67e5\u7279\u5b9a\u4f4d\u7f6e\u63d0\u4f9b\u5546\u662f\u5426\u5df2\u542f\u7528\u3002

    locationProviderEnabled(provider)\n

    \u53c2\u6570\uff1a - provider (str): \u63d0\u4f9b\u5546\u540d\u79f0\uff08\u4f8b\u5982 'gps', 'network'\uff09

    \u8fd4\u56de\uff1a \u5982\u679c\u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

    "},{"location":"qsl4a/connectivity/location/#readgnssstatus","title":"readGnssStatus()","text":"

    \u8bfb\u53d6\u5168\u7403\u5bfc\u822a\u536b\u661f\u7cfb\u7edf\u72b6\u6001\uff08\u9700\u8981 Android 8+\uff09\u3002

    readGnssStatus()\n

    \u8fd4\u56de\uff1a \u5305\u542b GNSS \u536b\u661f\u4fe1\u606f\u7684 JSONArray

    "},{"location":"qsl4a/connectivity/location/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\ndroid.startLocating(minUpdateTime=5000, minUpdateDistance=1, updateGnssStatus=False)\n\n# \u7b49\u5f85\u5b9a\u4f4d\ntime.sleep(10)\n\n# \u83b7\u53d6\u4f4d\u7f6e\nloc = droid.readLocation().result\nif loc:\n    lat = loc['latitude']\n    lon = loc['longitude']\n    print(f\"Location: {lat}, {lon}\")\n\ndroid.stopLocating()\n
    "},{"location":"qsl4a/connectivity/phone/","title":"\u7535\u8bdd API","text":"

    \u63a7\u5236\u7535\u8bdd\u901a\u8bdd\u548c\u83b7\u53d6\u7535\u8bdd\u4fe1\u606f\u3002

    "},{"location":"qsl4a/connectivity/phone/#_1","title":"\u7535\u8bdd\u72b6\u6001\u8ddf\u8e2a","text":""},{"location":"qsl4a/connectivity/phone/#starttrackingphonestate","title":"startTrackingPhoneState()","text":"

    \u5f00\u59cb\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u53d8\u5316\u3002\u751f\u6210 'phone' \u4e8b\u4ef6\u3002

    startTrackingPhoneState()\n
    "},{"location":"qsl4a/connectivity/phone/#readphonestate","title":"readPhoneState()","text":"

    \u8bfb\u53d6\u5f53\u524d\u7535\u8bdd\u72b6\u6001\u3002

    readPhoneState()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u7535\u8bdd\u72b6\u6001\u548c\u6765\u7535\u53f7\u7801\u7684 Bundle

    "},{"location":"qsl4a/connectivity/phone/#stoptrackingphonestate","title":"stopTrackingPhoneState()","text":"

    \u505c\u6b62\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u3002

    stopTrackingPhoneState()\n
    "},{"location":"qsl4a/connectivity/phone/#_2","title":"\u62e8\u6253\u7535\u8bdd","text":""},{"location":"qsl4a/connectivity/phone/#phonecall","title":"phoneCall()","text":"

    \u901a\u8fc7 URI \u547c\u53eb\u8054\u7cfb\u4eba/\u7535\u8bdd\u53f7\u7801\u3002

    phoneCall(uri)\n

    \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

    "},{"location":"qsl4a/connectivity/phone/#phonecallnumber","title":"phoneCallNumber()","text":"

    \u76f4\u63a5\u62e8\u6253\u7535\u8bdd\u53f7\u7801\u3002

    phoneCallNumber(phone_number)\n

    \u53c2\u6570\uff1a - phone_number (str): \u8981\u62e8\u6253\u7684\u7535\u8bdd\u53f7\u7801

    "},{"location":"qsl4a/connectivity/phone/#phonedial","title":"phoneDial()","text":"

    \u62e8\u6253\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

    phoneDial(uri)\n

    \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

    "},{"location":"qsl4a/connectivity/phone/#phonedialnumber","title":"phoneDialNumber()","text":"

    \u62e8\u6253\u7535\u8bdd\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

    phoneDialNumber(phone_number)\n

    \u53c2\u6570\uff1a - phone_number (str): \u7535\u8bdd\u53f7\u7801

    "},{"location":"qsl4a/connectivity/phone/#_3","title":"\u57fa\u7ad9\u4f4d\u7f6e","text":""},{"location":"qsl4a/connectivity/phone/#getcelllocation","title":"getCellLocation()","text":"

    \u83b7\u53d6\u5f53\u524d\u57fa\u7ad9\u4f4d\u7f6e\u3002

    getCellLocation()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u57fa\u7ad9\u4f4d\u7f6e\u6570\u636e\u7684 JSONObject

    "},{"location":"qsl4a/connectivity/phone/#getallcellslocation","title":"getAllCellsLocation()","text":"

    \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u4f4d\u7f6e\uff08\u9002\u7528\u4e8e\u53cc\u5361\u8bbe\u5907\uff09\u3002

    getAllCellsLocation()\n

    \u8fd4\u56de\uff1a \u57fa\u7ad9\u4f4d\u7f6e\u7684 JSONArray

    "},{"location":"qsl4a/connectivity/phone/#_4","title":"\u7f51\u7edc\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getnetworkoperator","title":"getNetworkOperator()","text":"

    \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

    getNetworkOperator()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

    "},{"location":"qsl4a/connectivity/phone/#getnetworkoperatorname","title":"getNetworkOperatorName()","text":"

    \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684\u540d\u79f0\u3002

    getNetworkOperatorName()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

    "},{"location":"qsl4a/connectivity/phone/#getnetworktype","title":"getNetworkType()","text":"

    \u83b7\u53d6\u5f53\u524d\u7f51\u7edc\u7c7b\u578b\u3002

    getNetworkType()\n

    \u8fd4\u56de\uff1a \u63cf\u8ff0\u65e0\u7ebf\u7535\u6280\u672f\u7684\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'LTE', 'UMTS', 'GSM'\uff09

    "},{"location":"qsl4a/connectivity/phone/#getphonetype","title":"getPhoneType()","text":"

    \u83b7\u53d6\u7535\u8bdd\u7c7b\u578b\u3002

    getPhoneType()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'GSM', 'CDMA', 'SIP'\uff09

    "},{"location":"qsl4a/connectivity/phone/#sim","title":"SIM \u5361\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getsimcountryiso","title":"getSimCountryIso()","text":"

    \u83b7\u53d6 SIM \u5361\u7684 ISO \u56fd\u5bb6\u4ee3\u7801\u3002

    getSimCountryIso()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'us'\uff09

    "},{"location":"qsl4a/connectivity/phone/#getsimoperator","title":"getSimOperator()","text":"

    \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

    getSimOperator()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

    "},{"location":"qsl4a/connectivity/phone/#getsimoperatorname","title":"getSimOperatorName()","text":"

    \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u540d\u79f0\u3002

    getSimOperatorName()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

    "},{"location":"qsl4a/connectivity/phone/#getsimserialnumber","title":"getSimSerialNumber()","text":"

    \u83b7\u53d6 SIM \u5e8f\u5217\u53f7\u3002

    getSimSerialNumber()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32 SIM \u5e8f\u5217\u53f7

    "},{"location":"qsl4a/connectivity/phone/#getsimstate","title":"getSimState()","text":"

    \u83b7\u53d6 SIM \u5361\u72b6\u6001\u3002

    getSimState()\n

    \u8fd4\u56de\uff1a \u63cf\u8ff0 SIM \u72b6\u6001\u7684\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/connectivity/phone/#getsubscriberid","title":"getSubscriberId()","text":"

    \u83b7\u53d6\u8ba2\u9605\u8005 ID\u3002

    getSubscriberId()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8ba2\u9605\u8005 ID

    "},{"location":"qsl4a/connectivity/phone/#_5","title":"\u8bed\u97f3\u90ae\u4ef6","text":""},{"location":"qsl4a/connectivity/phone/#getvoicemailalphatag","title":"getVoiceMailAlphaTag()","text":"

    \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u5b57\u6bcd\u6807\u7b7e\u3002

    getVoiceMailAlphaTag()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u6807\u7b7e

    "},{"location":"qsl4a/connectivity/phone/#getvoicemailnumber","title":"getVoiceMailNumber()","text":"

    \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801\u3002

    getVoiceMailNumber()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801

    "},{"location":"qsl4a/connectivity/phone/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getdeviceid","title":"getDeviceId()","text":"

    \u83b7\u53d6\u8bbe\u5907 ID\uff08GSM \u7684 IMEI\uff09\u3002\u5df2\u5e9f\u5f03\u3002

    getDeviceId()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

    "},{"location":"qsl4a/connectivity/phone/#getdevicesoftwareversion","title":"getDeviceSoftwareVersion()","text":"

    \u83b7\u53d6\u8bbe\u5907\u8f6f\u4ef6\u7248\u672c\u3002

    getDeviceSoftwareVersion()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8f6f\u4ef6\u7248\u672c

    "},{"location":"qsl4a/connectivity/phone/#getline1number","title":"getLine1Number()","text":"

    \u83b7\u53d6\u7ebf\u8def 1 \u7535\u8bdd\u53f7\u7801\u3002

    getLine1Number()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u7535\u8bdd\u53f7\u7801

    "},{"location":"qsl4a/connectivity/phone/#checknetworkroaming","title":"checkNetworkRoaming()","text":"

    \u68c0\u67e5\u662f\u5426\u8fde\u63a5\u5230\u6f2b\u6e38\u7f51\u7edc\u3002

    checkNetworkRoaming()\n

    \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u6f2b\u6e38\u5219\u4e3a True

    "},{"location":"qsl4a/connectivity/phone/#_7","title":"\u57fa\u7ad9\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getallcellinfo","title":"getAllCellInfo()","text":"

    \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u7684\u4fe1\u606f\u3002

    getAllCellInfo()\n

    \u8fd4\u56de\uff1a \u57fa\u7ad9\u4fe1\u606f\u5217\u8868

    "},{"location":"qsl4a/connectivity/phone/#setdataenabled","title":"setDataEnabled()","text":"

    \u542f\u7528\u6216\u7981\u7528\u79fb\u52a8\u6570\u636e\u3002

    setDataEnabled(enabled)\n

    \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528

    "},{"location":"qsl4a/connectivity/phone/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7f51\u7edc\u4fe1\u606f\noperator = droid.getNetworkOperatorName().result\nprint(f\"Operator: {operator}\")\n\nnetwork_type = droid.getNetworkType().result\nprint(f\"Network: {network_type}\")\n\n# \u83b7\u53d6 SIM \u4fe1\u606f\nsim_state = droid.getSimState().result\nprint(f\"SIM: {sim_state}\")\n\n# \u83b7\u53d6\u7535\u8bdd\u53f7\u7801\nline1 = droid.getLine1Number().result\nprint(f\"Phone: {line1}\")\n\n# \u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\ndroid.startTrackingPhoneState()\nprint(\"Tracking phone state...\")\ndroid.stopTrackingPhoneState()\n
    "},{"location":"qsl4a/connectivity/signalstrength/","title":"\u4fe1\u53f7\u5f3a\u5ea6 API","text":"

    \u76d1\u63a7\u8702\u7a9d\u548c\u65e0\u7ebf\u4fe1\u53f7\u5f3a\u5ea6\u3002

    "},{"location":"qsl4a/connectivity/signalstrength/#_1","title":"\u4fe1\u53f7\u5f3a\u5ea6\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/signalstrength/#starttrackingsignalstrengths","title":"startTrackingSignalStrengths()","text":"

    \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316\u3002\u751f\u6210 'signal_strengths' \u4e8b\u4ef6\u3002

    startTrackingSignalStrengths()\n
    "},{"location":"qsl4a/connectivity/signalstrength/#stoptrackingsignalstrengths","title":"stopTrackingSignalStrengths()","text":"

    \u505c\u6b62\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u3002

    stopTrackingSignalStrengths()\n
    "},{"location":"qsl4a/connectivity/signalstrength/#readsignalstrengths","title":"readSignalStrengths()","text":"

    \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\u3002

    readSignalStrengths()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u4fe1\u53f7\u5f3a\u5ea6\u6570\u636e\u7684 Bundle

    "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthlevel","title":"getTelephoneSignalStrengthLevel()","text":"

    \u83b7\u53d6\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u7b49\u7ea7\uff080-4\uff09\u3002

    getTelephoneSignalStrengthLevel()\n

    \u8fd4\u56de\uff1a \u6574\u6570\u7b49\u7ea7\uff080=\u65e0\uff0c1=\u5dee\uff0c2=\u4e00\u822c\uff0c3=\u597d\uff0c4=\u4f18\u79c0\uff09

    "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthdetail","title":"getTelephoneSignalStrengthDetail()","text":"

    \u83b7\u53d6\u8be6\u7ec6\u7684\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u4fe1\u606f\u3002

    getTelephoneSignalStrengthDetail()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u8be6\u7ec6\u4fe1\u53f7\u4fe1\u606f\u7684\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/connectivity/signalstrength/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\ndroid.startTrackingSignalStrengths()\n\n# \u7b49\u5f85\u4fe1\u53f7\u66f4\u65b0\ntime.sleep(5)\n\n# \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\nsignal = droid.readSignalStrengths().result\nprint(f\"Signal: {signal}\")\n\n# \u76f4\u63a5\u83b7\u53d6\u7b49\u7ea7\nlevel = droid.getTelephoneSignalStrengthLevel().result\nprint(f\"Signal level: {level}/4\")\n\ndroid.stopTrackingSignalStrengths()\n
    "},{"location":"qsl4a/connectivity/sms/","title":"SMS API","text":"

    \u53d1\u9001\u548c\u63a5\u6536 SMS \u6d88\u606f\u3002

    "},{"location":"qsl4a/connectivity/sms/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/sms/#smssend","title":"smsSend()","text":"

    \u53d1\u9001 SMS \u6d88\u606f\u3002

    smsSend(destinationAddress, text)\n

    \u53c2\u6570\uff1a - destinationAddress (str): \u7535\u8bdd\u53f7\u7801 - text (str): \u6d88\u606f\u6587\u672c

    "},{"location":"qsl4a/connectivity/sms/#smsgetmessagecount","title":"smsGetMessageCount()","text":"

    \u83b7\u53d6\u6d88\u606f\u6570\u91cf\u3002

    smsGetMessageCount(unreadOnly=False, folder=\"inbox\")\n
    "},{"location":"qsl4a/connectivity/sms/#smsgetmessageids","title":"smsGetMessageIds()","text":"

    \u83b7\u53d6\u6d88\u606f ID\u3002

    smsGetMessageIds(unreadOnly=False, folder=\"inbox\")\n
    "},{"location":"qsl4a/connectivity/sms/#smsgetmessages","title":"smsGetMessages()","text":"

    \u83b7\u53d6\u6d88\u606f\u8be6\u60c5\u3002

    smsGetMessages(unreadOnly=False, folder=\"inbox\", attributes=None)\n
    "},{"location":"qsl4a/connectivity/sms/#smsgetmessagebyid","title":"smsGetMessageById()","text":"

    \u901a\u8fc7 ID \u83b7\u53d6\u7279\u5b9a\u6d88\u606f\u3002

    smsGetMessageById(id, attributes=None)\n

    \u53c2\u6570\uff1a - id (int): \u6d88\u606f ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

    \u8fd4\u56de\uff1a \u6d88\u606f\u6570\u636e\u5b57\u5178

    "},{"location":"qsl4a/connectivity/sms/#smsgetattributes","title":"smsGetAttributes()","text":"

    \u83b7\u53d6\u53ef\u7528\u7684 SMS \u6d88\u606f\u5c5e\u6027\u3002

    smsGetAttributes()\n

    \u8fd4\u56de\uff1a \u53ef\u7528\u5c5e\u6027\u540d\u79f0\u5217\u8868

    "},{"location":"qsl4a/connectivity/sms/#smsdeletemessage","title":"smsDeleteMessage()","text":"

    \u5220\u9664\u6d88\u606f\u3002

    smsDeleteMessage(id)\n
    "},{"location":"qsl4a/connectivity/sms/#smsmarkmessageread","title":"smsMarkMessageRead()","text":"

    \u5c06\u6d88\u606f\u6807\u8bb0\u4e3a\u5df2\u8bfb\u3002

    smsMarkMessageRead(ids, read=True)\n
    "},{"location":"qsl4a/connectivity/sms/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u53d1\u9001 SMS\ndroid.smsSend(\"+1234567890\", \"Hello from QPython!\")\n\n# \u83b7\u53d6\u672a\u8bfb\u6d88\u606f\nmessages = droid.smsGetMessages(unreadOnly=True).result\nfor msg in messages:\n    print(f\"From: {msg['address']}, Text: {msg['body']}\")\n
    "},{"location":"qsl4a/connectivity/wifi/","title":"WiFi API","text":"

    \u63a7\u5236 WiFi \u9002\u914d\u5668\u5e76\u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\u3002

    "},{"location":"qsl4a/connectivity/wifi/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/connectivity/wifi/#checkwifistate","title":"checkWifiState()","text":"

    \u68c0\u67e5 WiFi \u662f\u5426\u5df2\u542f\u7528\u3002

    checkWifiState()\n

    \u8fd4\u56de\uff1a \u5982\u679c WiFi \u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

    "},{"location":"qsl4a/connectivity/wifi/#togglewifistate","title":"toggleWifiState()","text":"

    \u6253\u5f00\u6216\u5173\u95ed WiFi\u3002

    toggleWifiState(enabled=None)\n

    \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

    \u8fd4\u56de\uff1a \u5982\u679c\u64cd\u4f5c\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/connectivity/wifi/#wifistartscan","title":"wifiStartScan()","text":"

    \u5f00\u59cb\u626b\u63cf\u53ef\u7528\u7684 WiFi \u7f51\u7edc\u3002

    wifiStartScan()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifigetscanresults","title":"wifiGetScanResults()","text":"

    \u83b7\u53d6\u53d1\u73b0\u7684 WiFi \u7f51\u7edc\u5217\u8868\u3002

    wifiGetScanResults()\n

    \u8fd4\u56de\uff1a \u63a5\u5165\u70b9\u4fe1\u606f\u5217\u8868

    "},{"location":"qsl4a/connectivity/wifi/#_2","title":"\u8fde\u63a5\u7ba1\u7406","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetconnectioninfo","title":"wifiGetConnectionInfo()","text":"

    \u83b7\u53d6\u8be6\u7ec6\u8fde\u63a5\u4fe1\u606f\u3002

    wifiGetConnectionInfo()\n

    \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001IP \u5730\u5740\u7b49\u8fde\u63a5\u8be6\u60c5\u7684\u5b57\u5178

    "},{"location":"qsl4a/connectivity/wifi/#getconnectedinfo","title":"getConnectedInfo()","text":"

    \u83b7\u53d6\u8fde\u63a5\u7684 WiFi \u7f51\u7edc\u4fe1\u606f\uff08\u7b80\u5316\u7248\uff09\u3002

    getConnectedInfo()\n

    \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001\u4fe1\u53f7\u5f3a\u5ea6\u7684\u5b57\u5178

    "},{"location":"qsl4a/connectivity/wifi/#getdhcpinfo","title":"getDhcpInfo()","text":"

    \u83b7\u53d6\u5f53\u524d\u8fde\u63a5\u7684 DHCP \u4fe1\u606f\u3002

    getDhcpInfo(ipConvertToString=True)\n

    \u53c2\u6570\uff1a - ipConvertToString (bool): \u5c06 IP \u5730\u5740\u8f6c\u6362\u4e3a\u5b57\u7b26\u4e32\u683c\u5f0f\uff08\u9ed8\u8ba4\uff1aTrue\uff09

    \u8fd4\u56de\uff1a \u5305\u542b IP\u3001\u7f51\u5173\u3001DNS \u7b49 DHCP \u4fe1\u606f\u7684\u5b57\u5178

    "},{"location":"qsl4a/connectivity/wifi/#wifidisconnect","title":"wifiDisconnect()","text":"

    \u65ad\u5f00\u5f53\u524d WiFi \u7f51\u7edc\u8fde\u63a5\u3002

    wifiDisconnect()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifireconnect","title":"wifiReconnect()","text":"

    \u91cd\u65b0\u8fde\u63a5\u5230\u5f53\u524d\u7f51\u7edc\u3002

    wifiReconnect()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifireassociate","title":"wifiReassociate()","text":"

    \u91cd\u65b0\u5173\u8054\u5f53\u524d\u63a5\u5165\u70b9\u3002

    wifiReassociate()\n
    "},{"location":"qsl4a/connectivity/wifi/#_3","title":"\u70ed\u70b9","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetapstate","title":"wifiGetApState()","text":"

    \u83b7\u53d6 WiFi AP\uff08\u70ed\u70b9\uff09\u72b6\u6001\u3002

    wifiGetApState()\n

    \u8fd4\u56de\uff1a \u70ed\u70b9\u72b6\u6001

    "},{"location":"qsl4a/connectivity/wifi/#wifi","title":"WiFi \u9501","text":""},{"location":"qsl4a/connectivity/wifi/#wifilockacquirefull","title":"wifiLockAcquireFull()","text":"

    \u83b7\u53d6\u5b8c\u6574 WiFi \u9501\uff08\u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\u4e5f\u4fdd\u6301 WiFi \u6d3b\u52a8\uff09\u3002

    wifiLockAcquireFull()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifilockacquirescanonly","title":"wifiLockAcquireScanOnly()","text":"

    \u83b7\u53d6\u4ec5\u626b\u63cf WiFi \u9501\u3002

    wifiLockAcquireScanOnly()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifilockrelease","title":"wifiLockRelease()","text":"

    \u91ca\u653e WiFi \u9501\u3002

    wifiLockRelease()\n
    "},{"location":"qsl4a/connectivity/wifi/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u68c0\u67e5 WiFi \u72b6\u6001\nif droid.checkWifiState().result:\n    print(\"WiFi is enabled\")\nelse:\n    print(\"Enabling WiFi...\")\n    droid.toggleWifiState(True)\n    time.sleep(2)\n\n# \u5f00\u59cb\u626b\u63cf\ndroid.wifiStartScan()\ntime.sleep(3)\n\n# \u83b7\u53d6\u626b\u63cf\u7ed3\u679c\nnetworks = droid.wifiGetScanResults().result\nfor network in networks:\n    print(f\"SSID: {network.get('SSID')}, Signal: {network.get('level')} dBm\")\n\n# \u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\ninfo = droid.wifiGetConnectionInfo().result\nif info:\n    print(f\"Connected to: {info.get('ssid')}\")\n    print(f\"BSSID: {info.get('bssid')}\")\n    print(f\"IP: {info.get('ip_address')}\")\n\n# \u83b7\u53d6 DHCP \u4fe1\u606f\ndhcp = droid.getDhcpInfo().result\nif dhcp:\n    print(f\"Gateway: {dhcp.get('gateway')}\")\n    print(f\"DNS: {dhcp.get('dns1')}\")\n\n# \u83b7\u53d6\u7b80\u5316\u7684\u8fde\u63a5\u4fe1\u606f\nconnected = droid.getConnectedInfo().result\nprint(f\"SSID: {connected.get('ssid')}, Signal: {connected.get('level')} dBm\")\n\n# \u65ad\u5f00\u5e76\u91cd\u65b0\u8fde\u63a5\ndroid.wifiDisconnect()\ntime.sleep(1)\ndroid.wifiReconnect()\n\n# \u91cd\u65b0\u5173\u8054\u63a5\u5165\u70b9\ndroid.wifiReassociate()\n\n# \u68c0\u67e5\u70ed\u70b9\u72b6\u6001\nap_state = droid.wifiGetApState().result\nprint(f\"Hotspot state: {ap_state}\")\n\n# \u83b7\u53d6 WiFi \u9501\u4ee5\u8fdb\u884c\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireFull()\n# ... \u6267\u884c\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n\n# \u6216\u4f7f\u7528\u4ec5\u626b\u63cf\u9501\u4ee5\u8fdb\u884c\u8f83\u8f7b\u7684\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireScanOnly()\n# ... \u6267\u884c\u626b\u63cf\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n
    "},{"location":"qsl4a/core/android-base/","title":"Android \u57fa\u7840\u7c7b","text":"

    Android \u7c7b\u662f QSL4A \u7684\u6838\u5fc3\uff0c\u63d0\u4f9b\u4e86\u4e0e Android \u8fd0\u884c\u65f6\u7684\u8fde\u63a5\u548c RPC \u673a\u5236\u3002

    "},{"location":"qsl4a/core/android-base/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
    # \u529f\u80fd\u5b8c\u6574\u7248\u672c\uff08\u63a8\u8350\uff09\nimport androidhelper\ndroid = androidhelper.Android()\n\n# \u7b80\u5316\u7248\u672c\uff08\u5feb\u901f\uff0c\u5355\u5b9e\u4f8b\uff09\nimport android\ndroid = android.droid\n
    "},{"location":"qsl4a/core/android-base/#android_1","title":"\u7c7b\uff1aAndroid","text":""},{"location":"qsl4a/core/android-base/#_2","title":"\u6784\u9020\u51fd\u6570","text":"
    Android(addr=None)\n

    \u53c2\u6570\uff1a - addr (tuple, optional): (HOST, PORT) \u5730\u5740\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u73af\u5883\u53d8\u91cf AP_HOST \u548c AP_PORT

    \u73af\u5883\u53d8\u91cf\uff1a - AP_HOST - \u670d\u52a1\u5668\u4e3b\u673a\u5730\u5740 - AP_PORT - \u670d\u52a1\u5668\u7aef\u53e3 - AP_HANDSHAKE - \u8ba4\u8bc1\u4ee4\u724c

    "},{"location":"qsl4a/core/android-base/#_3","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/android-base/#_rpc","title":"_rpc()","text":"

    \u8c03\u7528 Android \u51fd\u6570\u7684\u5185\u90e8 RPC \u65b9\u6cd5\u3002

    _rpc(method, *args)\n

    \u53c2\u6570\uff1a - method (str): \u8981\u8c03\u7528\u7684\u65b9\u6cd5\u540d - *args: \u65b9\u6cd5\u7684\u53ef\u53d8\u53c2\u6570

    \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4\uff0c\u5305\u542b\u4ee5\u4e0b\u5b57\u6bb5\uff1a - id (int): \u8bf7\u6c42 ID - result: \u65b9\u6cd5\u8fd4\u56de\u503c - error (str or None): \u9519\u8bef\u4fe1\u606f\uff08\u5982\u679c\u5931\u8d25\uff09

    "},{"location":"qsl4a/core/android-base/#getattr","title":"getattr()","text":"

    \u52a8\u6001\u65b9\u6cd5\u5206\u53d1\u5668\u3002\u6240\u6709 Android \u65b9\u6cd5\u90fd\u901a\u8fc7\u5c5e\u6027\u67e5\u627e\u8bbf\u95ee\u3002

    # \u4ee5\u4e0b\u4e24\u79cd\u65b9\u5f0f\u7b49\u4ef7\uff1a\ndroid.makeToast(\"Hello\")\ndroid._rpc(\"makeToast\", \"Hello\")\n
    "},{"location":"qsl4a/core/android-base/#androidpy","title":"\u72ec\u7acb\u51fd\u6570\uff08android.py\uff09","text":"

    \u4f7f\u7528\u7b80\u5316\u7684 android \u6a21\u5757\u65f6\uff1a

    "},{"location":"qsl4a/core/android-base/#jsla","title":"jsla()","text":"

    \u53d1\u9001 JSON-RPC \u8bf7\u6c42\u5e76\u8fd4\u56de\u539f\u59cb\u54cd\u5e94\u3002

    jsla(method, *params)\n

    \u8fd4\u56de\uff1a JSON \u5b57\u7b26\u4e32\u54cd\u5e94

    "},{"location":"qsl4a/core/android-base/#rsla","title":"rsla()","text":"

    \u53d1\u9001\u8bf7\u6c42\u5e76\u4ec5\u8fd4\u56de\u7ed3\u679c\u3002

    rsla(method, *params)\n

    \u8fd4\u56de\uff1a RPC \u8c03\u7528\u7684\u7ed3\u679c\u503c

    "},{"location":"qsl4a/core/android-base/#esla","title":"esla()","text":"

    \u53d1\u9001\u8bf7\u6c42\uff0c\u9519\u8bef\u65f6\u629b\u51fa\u5f02\u5e38\u3002

    esla(method, *params)\n

    \u629b\u51fa\uff1a \u5982\u679c error \u5b57\u6bb5\u4e0d\u4e3a None \u5219\u629b\u51fa\u5f02\u5e38

    "},{"location":"qsl4a/core/android-base/#nsla","title":"nsla()","text":"

    \u53d1\u9001\u8bf7\u6c42\u5e76\u8fd4\u56de Result \u547d\u540d\u5143\u7ec4\u3002

    nsla(method, *params)\n

    \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4

    "},{"location":"qsl4a/core/android-base/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/android-base/#_5","title":"\u57fa\u672c\u8fde\u63a5","text":"
    import androidhelper\n\n# \u8fde\u63a5\u5230 Android \u8fd0\u884c\u65f6\ndroid = androidhelper.Android()\n\n# \u901a\u8fc7\u663e\u793a toast \u6765\u68c0\u67e5\u8fde\u63a5\ndroid.makeToast(\"Connected!\")\n
    "},{"location":"qsl4a/core/android-base/#_6","title":"\u9519\u8bef\u5904\u7406","text":"
    result = droid.someMethod()\nif result.error:\n    print(f\"Error: {result.error}\")\nelse:\n    print(f\"Success: {result.result}\")\n
    "},{"location":"qsl4a/core/android-base/#rpc","title":"\u76f4\u63a5 RPC \u8c03\u7528","text":"
    # \u76f4\u63a5\u8c03\u7528\u4efb\u610f\u65b9\u6cd5\nresult = droid._rpc(\"makeToast\", \"Hello World\")\n
    "},{"location":"qsl4a/core/events/","title":"\u4e8b\u4ef6\u7cfb\u7edf","text":"

    QSL4A \u63d0\u4f9b\u4e86\u4e00\u4e2a\u4e8b\u4ef6\u7cfb\u7edf\uff0c\u7528\u4e8e\u5904\u7406\u6765\u81ea Android \u7684\u5f02\u6b65\u4e8b\u4ef6\uff0c\u5982\u4f20\u611f\u5668\u66f4\u65b0\u3001\u4f4d\u7f6e\u53d8\u5316\u548c\u81ea\u5b9a\u4e49\u5e7f\u64ad\u3002

    "},{"location":"qsl4a/core/events/#_2","title":"\u4e8b\u4ef6\u57fa\u7840","text":"

    \u4e8b\u4ef6\u5b58\u50a8\u5728\u7f13\u51b2\u533a\u4e2d\uff0c\u53ef\u4ee5\u8f6e\u8be2\u6216\u7b49\u5f85\u3002\u6bcf\u4e2a\u4e8b\u4ef6\u5305\u542b\uff1a - name: \u4e8b\u4ef6\u7c7b\u578b/\u540d\u79f0 - data: \u4e8b\u4ef6\u8d1f\u8f7d\u6570\u636e - time: \u65f6\u95f4\u6233

    "},{"location":"qsl4a/core/events/#_3","title":"\u4e8b\u4ef6\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#eventclearbuffer","title":"eventClearBuffer()","text":"

    \u6e05\u9664\u7f13\u51b2\u533a\u4e2d\u7684\u6240\u6709\u5f85\u5904\u7406\u4e8b\u4ef6\u3002

    eventClearBuffer()\n

    \u8fd4\u56de\uff1a None

    "},{"location":"qsl4a/core/events/#eventpoll","title":"eventPoll()","text":"

    \u8f6e\u8be2\u7f13\u51b2\u533a\u4e2d\u7684\u4e8b\u4ef6\u3002

    eventPoll(number_of_events=1)\n

    \u53c2\u6570\uff1a - number_of_events (int): \u8981\u68c0\u7d22\u7684\u6700\u5927\u4e8b\u4ef6\u6570\uff08\u9ed8\u8ba4\uff1a1\uff09

    \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\u5217\u8868

    "},{"location":"qsl4a/core/events/#eventwait","title":"eventWait()","text":"

    \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\u3002

    eventWait(timeout=None)\n

    \u53c2\u6570\uff1a - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09\u3002None = \u6c38\u4e45\u7b49\u5f85

    \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

    "},{"location":"qsl4a/core/events/#eventwaitfor","title":"eventWaitFor()","text":"

    \u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6\u3002

    eventWaitFor(eventName, timeout=None)\n

    \u53c2\u6570\uff1a - eventName (str): \u8981\u7b49\u5f85\u7684\u4e8b\u4ef6\u540d\u79f0 - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

    \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

    "},{"location":"qsl4a/core/events/#eventpost","title":"eventPost()","text":"

    \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\u3002

    eventPost(name, data, enqueue=None)\n

    \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e\uff08\u4efb\u610f\u7c7b\u578b\uff09 - enqueue (bool, optional): \u5982\u679c\u4e3a True \u5219\u6dfb\u52a0\u5230\u961f\u5217

    "},{"location":"qsl4a/core/events/#receiveevent","title":"receiveEvent()","text":"

    \u63a5\u6536\u4e8b\u4ef6\uff08\u963b\u585e\uff09\u3002

    receiveEvent()\n

    \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61

    "},{"location":"qsl4a/core/events/#_4","title":"\u5e7f\u64ad\u4e8b\u4ef6","text":"

    \u6ce8\u518c\u7cfb\u7edf\u5e7f\u64ad\u4e8b\u4ef6\u3002

    "},{"location":"qsl4a/core/events/#eventregisterforbroadcast","title":"eventRegisterForBroadcast()","text":"

    \u6ce8\u518c\u63a5\u6536\u5e7f\u64ad\u4e8b\u4ef6\u3002

    eventRegisterForBroadcast(category, enqueue=True)\n

    \u53c2\u6570\uff1a - category (str): \u5e7f\u64ad\u7c7b\u522b/\u52a8\u4f5c - enqueue (bool): \u6dfb\u52a0\u5230\u4e8b\u4ef6\u961f\u5217

    "},{"location":"qsl4a/core/events/#eventunregisterforbroadcast","title":"eventUnregisterForBroadcast()","text":"

    \u53d6\u6d88\u6ce8\u518c\u5e7f\u64ad\u4e8b\u4ef6\u3002

    eventUnregisterForBroadcast(category)\n
    "},{"location":"qsl4a/core/events/#eventgetbrodcastcategories","title":"eventGetBrodcastCategories()","text":"

    \u83b7\u53d6\u5df2\u6ce8\u518c\u7684\u5e7f\u64ad\u7c7b\u522b\u3002

    eventGetBrodcastCategories()\n

    \u8fd4\u56de\uff1a \u5df2\u6ce8\u518c\u7c7b\u522b\u5217\u8868

    "},{"location":"qsl4a/core/events/#_5","title":"\u4e8b\u4ef6\u5206\u53d1\u5668)","text":""},{"location":"qsl4a/core/events/#starteventdispatcher","title":"startEventDispatcher()","text":"

    \u6253\u5f00\u4e00\u4e2a\u53ef\u4ee5\u8bfb\u53d6\u5df2\u53d1\u5e03\u4e8b\u4ef6\u7684\u5957\u63a5\u5b57\u3002)

    startEventDispatcher(port=0)\n

    \u53c2\u6570\uff1a - port (int, optional): \u76d1\u542c\u7684\u7aef\u53e3\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\u9009\u62e9\uff09

    \u8fd4\u56de\uff1a \u6b63\u5728\u76d1\u542c\u7684\u7aef\u53e3\u53f7

    "},{"location":"qsl4a/core/events/#stopeventdispatcher","title":"stopEventDispatcher()","text":"

    \u505c\u6b62\u4e8b\u4ef6\u670d\u52a1\u5668\u3002)

    stopEventDispatcher()\n
    "},{"location":"qsl4a/core/events/#_6","title":"\u5df2\u5e9f\u5f03\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#rpcpostevent","title":"rpcPostEvent()","text":"

    \u5c06\u4e8b\u4ef6\u53d1\u5e03\u5230\u4e8b\u4ef6\u961f\u5217\u3002\uff08\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 eventPost\uff09

    rpcPostEvent(name, data)\n

    \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e

    "},{"location":"qsl4a/core/events/#_7","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/events/#_8","title":"\u57fa\u672c\u4e8b\u4ef6\u8f6e\u8be2","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6e05\u9664\u65e7\u4e8b\u4ef6\ndroid.eventClearBuffer()\n\n# \u8f6e\u8be2\u4e8b\u4ef6\nevents = droid.eventPoll(5).result\nfor event in events:\n    print(f\"Event: {event['name']}, Data: {event['data']}\")\n
    "},{"location":"qsl4a/core/events/#_9","title":"\u7b49\u5f85\u4e8b\u4ef6","text":"
    # \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\uff0c\u5e26\u8d85\u65f6\nevent = droid.eventWait(timeout=10).result\nif event:\n    print(f\"Got event: {event['name']}\")\n
    "},{"location":"qsl4a/core/events/#_10","title":"\u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6","text":"
    # \u7b49\u5f85\u4f20\u611f\u5668\u4e8b\u4ef6\nevent = droid.eventWaitFor('screen', timeout=5).result\nif event:\n    print(f\"Screen event: {event['data']}\")\n
    "},{"location":"qsl4a/core/events/#_11","title":"\u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6","text":"
    # \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\ndroid.eventPost('my_event', {'key': 'value'})\n\n# \u7b49\u5f85\u5b83\nevent = droid.eventWaitFor('my_event', timeout=1).result\n
    "},{"location":"qsl4a/core/events/#_12","title":"\u5e7f\u64ad\u63a5\u6536\u5668","text":"
    # \u6ce8\u518c\u5c4f\u5e55\u5f00\u5173\u4e8b\u4ef6\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_ON')\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_OFF')\n\n# \u7b49\u5f85\u5c4f\u5e55\u4e8b\u4ef6\nwhile True:\n    event = droid.receiveEvent().result\n    if event['name'] == 'android.intent.action.SCREEN_ON':\n        print(\"Screen turned on\")\n    elif event['name'] == 'android.intent.action.SCREEN_OFF':\n        print(\"Screen turned off\")\n
    "},{"location":"qsl4a/core/events/#_13","title":"\u4f20\u611f\u5668\u4e8b\u4ef6\u5904\u7406","text":"
    # \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u5904\u7406\u4f20\u611f\u5668\u4e8b\u4ef6\nfor _ in range(100):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'sensors':\n        data = event['data']\n        print(f\"Accel: {data['xforce']}, {data['yforce']}, {data['zforce']}\")\n\ndroid.stopSensing()\n
    "},{"location":"qsl4a/core/events/#_14","title":"\u5e38\u89c1\u4e8b\u4ef6\u7c7b\u578b","text":"\u4e8b\u4ef6\u540d\u79f0 \u63cf\u8ff0 \u6765\u6e90 sensors \u4f20\u611f\u5668\u6570\u636e\u66f4\u65b0 startSensing* location GPS \u4f4d\u7f6e\u66f4\u65b0 startLocating phone \u7535\u8bdd\u72b6\u6001\u53d8\u5316 startTrackingPhoneState signal \u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316 startTrackingSignalStrength screen \u622a\u56fe\u5c31\u7eea fullGetScreenShot dialog \u5bf9\u8bdd\u6846\u54cd\u5e94 dialogShow*"},{"location":"qsl4a/core/events/#_15","title":"\u4e8b\u4ef6\u6570\u636e\u7ed3\u6784","text":"
    {\n    'name': 'event_name',\n    'data': {\n        # \u4e8b\u4ef6\u7279\u5b9a\u6570\u636e\n    },\n    'time': 1234567890  # \u65f6\u95f4\u6233\n}\n
    "},{"location":"qsl4a/core/intent/","title":"Intent \u7cfb\u7edf","text":"

    Android Intent \u7528\u4e8e\u542f\u52a8\u6d3b\u52a8\u3001\u53d1\u9001\u5e7f\u64ad\u548c\u5e94\u7528\u95f4\u901a\u4fe1\u3002QSL4A \u901a\u8fc7 Intent \u6a21\u5757\u63d0\u4f9b\u5b8c\u6574\u7684 Intent \u652f\u6301\u3002

    "},{"location":"qsl4a/core/intent/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
    import androidhelper\ndon = androidhelper.Android()\n
    "},{"location":"qsl4a/core/intent/#intent_1","title":"Intent \u5e38\u91cf","text":"

    \u901a\u8fc7 droid.Intent \u8bbf\u95ee\uff1a

    "},{"location":"qsl4a/core/intent/#_2","title":"\u64cd\u4f5c","text":"\u5e38\u91cf \u503c \u7528\u9014 ACTION_MAIN android.intent.action.MAIN \u5e94\u7528\u5165\u53e3\u70b9 ACTION_VIEW android.intent.action.VIEW \u67e5\u770b\u5185\u5bb9 ACTION_EDIT android.intent.action.EDIT \u7f16\u8f91\u5185\u5bb9 ACTION_PICK android.intent.action.PICK \u9009\u62e9\u9879\u76ee ACTION_SEND android.intent.action.SEND \u5206\u4eab\u5185\u5bb9 ACTION_SEARCH android.intent.action.SEARCH \u641c\u7d22"},{"location":"qsl4a/core/intent/#_3","title":"\u6807\u5fd7","text":"\u5e38\u91cf \u503c \u7528\u9014 FLAG_ACTIVITY_NEW_TASK 268435456 \u542f\u52a8\u65b0\u4efb\u52a1 FLAG_ACTIVITY_CLEAR_TASK 32768 \u6e05\u9664\u4efb\u52a1\u5806\u6808 FLAG_ACTIVITY_NEW_DOCUMENT 524288 \u65b0\u6587\u6863\u6a21\u5f0f"},{"location":"qsl4a/core/intent/#_4","title":"\u9644\u52a0\u6570\u636e","text":"\u5e38\u91cf \u7528\u9014 EXTRA_TEXT \u6587\u672c\u5185\u5bb9 EXTRA_STREAM \u6587\u4ef6 URI EXTRA_SUBJECT \u4e3b\u9898\u884c EXTRA_EMAIL \u7535\u5b50\u90ae\u4ef6\u5730\u5740"},{"location":"qsl4a/core/intent/#_5","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/intent/#makeintent","title":"makeIntent()","text":"

    \u521b\u5efa Intent \u5bf9\u8c61\u3002

    makeIntent(action, uri=None, type=None, extras=None, categories=None,\n           packagename=None, classname=None, flags=None)\n

    \u53c2\u6570\uff1a - action (str): Intent \u64cd\u4f5c\uff08\u4f8b\u5982 droid.Intent.ACTION_VIEW\uff09 - uri (str, optional): \u6570\u636e URI - type (str, optional): MIME \u7c7b\u578b - extras (dict, optional): \u9644\u52a0\u6570\u636e - categories (list, optional): Intent \u7c7b\u522b - packagename (str, optional): \u76ee\u6807\u5305 - classname (str, optional): \u76ee\u6807\u7c7b - flags (int, optional): Intent \u6807\u5fd7

    \u8fd4\u56de\uff1a Intent \u5bf9\u8c61

    "},{"location":"qsl4a/core/intent/#startactivityintent","title":"startActivityIntent()","text":"

    \u4f7f\u7528 Intent \u542f\u52a8 Activity\u3002

    startActivityIntent(intent, wait=None)\n

    \u53c2\u6570\uff1a - intent: makeIntent() \u8fd4\u56de\u7684 Intent \u5bf9\u8c61 - wait (bool, optional): \u963b\u585e\u76f4\u5230\u6d3b\u52a8\u5173\u95ed

    "},{"location":"qsl4a/core/intent/#startactivityforresultintent","title":"startActivityForResultIntent()","text":"

    \u542f\u52a8\u6d3b\u52a8\u5e76\u7b49\u5f85\u7ed3\u679c\u3002

    startActivityForResultIntent(intent)\n

    \u8fd4\u56de\uff1a Activity \u7ed3\u679c

    "},{"location":"qsl4a/core/intent/#sendbroadcastintent","title":"sendBroadcastIntent()","text":"

    \u53d1\u9001\u5e7f\u64ad\u3002

    sendBroadcastIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#view","title":"view()","text":"

    \u901a\u8fc7 URI \u67e5\u770b\u5185\u5bb9\u3002

    view(uri, type=None, extras=None)\n
    "},{"location":"qsl4a/core/intent/#pick","title":"pick()","text":"

    \u4ece URI \u9009\u62e9\u5185\u5bb9\u3002

    pick(uri)\n
    "},{"location":"qsl4a/core/intent/#intent_2","title":"\u5e38\u89c1 Intent \u65b9\u6cd5)","text":""},{"location":"qsl4a/core/intent/#scanbarcode","title":"scanBarcode()","text":"

    \u542f\u52a8\u6761\u7801\u626b\u63cf\u5668\u3002

    scanBarcode()\n

    \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/core/intent/#send","title":"send()","text":"

    \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u5185\u5bb9\u3002

    send(type, content)\n

    \u53c2\u6570\uff1a - type (str): MIME \u7c7b\u578b - content (str): \u8981\u5206\u4eab\u7684\u5185\u5bb9

    "},{"location":"qsl4a/core/intent/#sendtext","title":"sendText()","text":"

    \u53d1\u9001\u6587\u672c\u5185\u5bb9\u3002

    sendText(text)\n

    \u53c2\u6570\uff1a - text (str): \u8981\u53d1\u9001\u7684\u6587\u672c

    "},{"location":"qsl4a/core/intent/#sendemail","title":"sendEmail()","text":"

    \u53d1\u9001\u7535\u5b50\u90ae\u4ef6\u3002

    sendEmail(to, subject, body, attachment=None)\n

    \u53c2\u6570\uff1a - to (str or list): \u6536\u4ef6\u4eba\u7535\u5b50\u90ae\u4ef6\u5730\u5740 - subject (str): \u7535\u5b50\u90ae\u4ef6\u4e3b\u9898 - body (str): \u7535\u5b50\u90ae\u4ef6\u6b63\u6587 - attachment (str, optional): \u9644\u4ef6\u6587\u4ef6\u8def\u5f84

    "},{"location":"qsl4a/core/intent/#pathtouri","title":"pathToUri()","text":"

    \u5c06\u6587\u4ef6\u8def\u5f84\u8f6c\u6362\u4e3a\u5185\u5bb9 URI\u3002

    pathToUri(path)\n

    \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

    \u8fd4\u56de\uff1a \u5185\u5bb9 URI \u5b57\u7b26\u4e32

    "},{"location":"qsl4a/core/intent/#openfile","title":"openFile()","text":"

    \u7528\u9002\u5f53\u7684\u5e94\u7528\u7a0b\u5e8f\u6253\u5f00\u6587\u4ef6\u3002

    openFile(path)\n

    \u53c2\u6570\uff1a - path (str): \u8981\u6253\u5f00\u7684\u6587\u4ef6\u8def\u5f84

    "},{"location":"qsl4a/core/intent/#sendfile","title":"sendFile()","text":"

    \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u6587\u4ef6\u3002

    sendFile(path)\n

    \u53c2\u6570\uff1a - path (str): \u8981\u53d1\u9001\u7684\u6587\u4ef6\u8def\u5f84

    "},{"location":"qsl4a/core/intent/#getpathtype","title":"getPathType()","text":"

    \u83b7\u53d6\u6587\u4ef6\u8def\u5f84\u7684 MIME \u7c7b\u578b\u3002

    getPathType(path)\n

    \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

    \u8fd4\u56de\uff1a MIME \u7c7b\u578b\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/core/intent/#viewmap","title":"viewMap()","text":"

    \u5728\u6307\u5b9a\u4f4d\u7f6e\u6253\u5f00\u5730\u56fe\u3002

    viewMap(latitude, longitude)\n

    \u53c2\u6570\uff1a - latitude (float): \u7eac\u5ea6 - longitude (float): \u7ecf\u5ea6

    "},{"location":"qsl4a/core/intent/#viewcontacts","title":"viewContacts()","text":"

    \u6253\u5f00\u8054\u7cfb\u4eba\u5e94\u7528\u3002

    viewContacts()\n
    "},{"location":"qsl4a/core/intent/#search","title":"search()","text":"

    \u6267\u884c\u7f51\u7edc\u641c\u7d22\u3002

    search(query)\n

    \u53c2\u6570\uff1a - query (str): \u641c\u7d22\u67e5\u8be2

    "},{"location":"qsl4a/core/intent/#viewhtml","title":"viewHtml()","text":"

    \u67e5\u770b HTML \u5185\u5bb9\u3002

    viewHtml(content, encoding=None)\n

    \u53c2\u6570\uff1a - content (str): HTML \u5185\u5bb9 - encoding (str, optional): \u5b57\u7b26\u7f16\u7801

    "},{"location":"qsl4a/core/intent/#webviewshow","title":"webViewShow()","text":"

    \u5728 WebView \u4e2d\u663e\u793a\u7f51\u9875\u5185\u5bb9\u3002\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 viewHtml\u3002

    webViewShow(url)\n

    \u53c2\u6570\uff1a - url (str): \u7f51\u9875 URL

    "},{"location":"qsl4a/core/intent/#editoropen","title":"editorOpen()","text":"

    \u6253\u5f00\u6587\u672c\u7f16\u8f91\u5668\u3002

    editorOpen(path=None, create=False)\n

    \u53c2\u6570\uff1a - path (str, optional): \u8981\u7f16\u8f91\u7684\u6587\u4ef6\u8def\u5f84 - create (bool, optional): \u5982\u679c\u4e0d\u5b58\u5728\u5219\u521b\u5efa

    "},{"location":"qsl4a/core/intent/#uri","title":"\u8f85\u52a9\u7c7b\uff1aUri","text":"

    \u521b\u5efa Intent \u7684 URI \u5bf9\u8c61\uff1a

    from androidhelper.Intent import Uri\n\nuri = Uri(\"file:///sdcard/test.txt\")\n
    "},{"location":"qsl4a/core/intent/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/intent/#_7","title":"\u6253\u5f00\u7f51\u9875","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"http://www.example.com\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#_8","title":"\u5206\u4eab\u6587\u672c","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_TEXT: \"Hello from QPython!\",\n        droid.Intent.EXTRA_SUBJECT: \"Test\"\n    },\n    type=\"text/plain\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#_9","title":"\u6253\u5f00\u6587\u4ef6","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"file:///sdcard/document.pdf\",\n    type=\"application/pdf\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#_10","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":"
    result = droid.pickContact()\ncontact_uri = result.result\n
    "},{"location":"qsl4a/core/intent/#_11","title":"\u53d1\u9001\u7535\u5b50\u90ae\u4ef6","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_EMAIL: [\"test@example.com\"],\n        droid.Intent.EXTRA_SUBJECT: \"Hello\",\n        droid.Intent.EXTRA_TEXT: \"Message body\"\n    },\n    type=\"message/rfc822\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#_12","title":"\u6253\u5f00\u5e94\u7528","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_MAIN,\n    packagename=\"com.android.settings\",\n    classname=\"com.android.settings.Settings\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/hardware/bluetooth/","title":"\u84dd\u7259 API","text":"

    \u63a7\u5236\u84dd\u7259\u9002\u914d\u5668\u5e76\u4e0e\u84dd\u7259\u8bbe\u5907\u901a\u4fe1\u3002

    "},{"location":"qsl4a/hardware/bluetooth/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/hardware/bluetooth/#togglebluetoothstate","title":"toggleBluetoothState()","text":"

    \u6253\u5f00/\u5173\u95ed\u84dd\u7259\u3002

    toggleBluetoothState(enabled=None, prompt=True)\n

    \u53c2\u6570\uff1a - enabled (bool): True=\u5f00\uff0cFalse=\u5173\uff0cNone=\u5207\u6362 - prompt (bool): \u663e\u793a\u7528\u6237\u63d0\u793a

    "},{"location":"qsl4a/hardware/bluetooth/#checkbluetoothstate","title":"checkBluetoothState()","text":"

    \u68c0\u67e5\u84dd\u7259\u662f\u5426\u5df2\u542f\u7528\u3002

    checkBluetoothState()\n

    \u8fd4\u56de\uff1a True/False

    "},{"location":"qsl4a/hardware/bluetooth/#getlocalname","title":"GetLocalName()","text":"

    \u83b7\u53d6\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

    GetLocalName()\n
    "},{"location":"qsl4a/hardware/bluetooth/#setlocalname","title":"SetLocalName()","text":"

    \u8bbe\u7f6e\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

    SetLocalName(name)\n
    "},{"location":"qsl4a/hardware/bluetooth/#getscanmode","title":"GetScanMode()","text":"

    \u83b7\u53d6\u53ef\u53d1\u73b0\u6027\u6a21\u5f0f\u3002

    GetScanMode()\n

    \u8fd4\u56de\uff1a - -1: \u5df2\u7981\u7528 - 0: \u4e0d\u53ef\u53d1\u73b0\uff0c\u4e0d\u53ef\u8fde\u63a5 - 1: \u53ef\u8fde\u63a5\uff0c\u4e0d\u53ef\u53d1\u73b0 - 3: \u53ef\u8fde\u63a5\u4e14\u53ef\u53d1\u73b0

    "},{"location":"qsl4a/hardware/bluetooth/#makediscoverable","title":"MakeDiscoverable()","text":"

    \u4f7f\u8bbe\u5907\u53ef\u53d1\u73b0\u3002

    MakeDiscoverable(duration=300)\n

    \u53c2\u6570\uff1a - duration (int): \u53ef\u53d1\u73b0\u7684\u79d2\u6570

    "},{"location":"qsl4a/hardware/bluetooth/#_2","title":"\u53d1\u73b0","text":""},{"location":"qsl4a/hardware/bluetooth/#discoverystart","title":"DiscoveryStart()","text":"

    \u5f00\u59cb\u8bbe\u5907\u53d1\u73b0\u3002

    DiscoveryStart()\n
    "},{"location":"qsl4a/hardware/bluetooth/#discoverycancel","title":"DiscoveryCancel()","text":"

    \u53d6\u6d88\u53d1\u73b0\u3002

    DiscoveryCancel()\n
    "},{"location":"qsl4a/hardware/bluetooth/#getreceiveddevices","title":"GetReceivedDevices()","text":"

    \u83b7\u53d6\u53d1\u73b0\u7684\u8bbe\u5907\u3002

    GetReceivedDevices()\n

    \u8fd4\u56de\uff1a \u8bbe\u5907\u4fe1\u606f\u5b57\u5178\u5217\u8868

    "},{"location":"qsl4a/hardware/bluetooth/#getbondeddevices","title":"GetBondedDevices()","text":"

    \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\u3002

    GetBondedDevices()\n

    \u8fd4\u56de\uff1a \u914d\u5bf9\u8bbe\u5907\u4fe1\u606f\u5217\u8868

    "},{"location":"qsl4a/hardware/bluetooth/#_3","title":"\u8fde\u63a5","text":""},{"location":"qsl4a/hardware/bluetooth/#connect","title":"Connect()","text":"

    \u8fde\u63a5\u5230\u8bbe\u5907\u3002

    Connect(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", address=None)\n

    \u53c2\u6570\uff1a - uuid (str): \u670d\u52a1 UUID - address (str): \u8bbe\u5907\u5730\u5740\uff08None = \u663e\u793a\u9009\u62e9\u5668\uff09

    \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/hardware/bluetooth/#accept","title":"Accept()","text":"

    \u63a5\u53d7\u4f20\u5165\u8fde\u63a5\u3002

    Accept(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", timeout=0)\n
    "},{"location":"qsl4a/hardware/bluetooth/#activeconnections","title":"ActiveConnections()","text":"

    \u68c0\u67e5\u6d3b\u52a8\u8fde\u63a5\u3002

    ActiveConnections()\n
    "},{"location":"qsl4a/hardware/bluetooth/#stop","title":"Stop()","text":"

    \u65ad\u5f00\u8fde\u63a5\u3002

    Stop(connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#_4","title":"\u901a\u4fe1","text":""},{"location":"qsl4a/hardware/bluetooth/#write","title":"Write()","text":"

    \u53d1\u9001 ASCII \u6570\u636e\u3002

    Write(ascii, connID=\"\")\n
    "},{"location":"qsl4a/hardware/bluetooth/#writebinary","title":"WriteBinary()","text":"

    \u53d1\u9001\u4e8c\u8fdb\u5236\u6570\u636e\uff08base64 \u7f16\u7801\uff09\u3002

    WriteBinary(base64, connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#read","title":"Read()","text":"

    \u8bfb\u53d6 ASCII \u6570\u636e\u3002

    Read(bufferSize=4096, connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#readbinary","title":"ReadBinary()","text":"

    \u8bfb\u53d6\u4e8c\u8fdb\u5236\u6570\u636e\u3002

    ReadBinary(bufferSize=4096, connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#readline","title":"ReadLine()","text":"

    \u8bfb\u53d6\u4e00\u884c\u3002

    ReadLine(connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#readready","title":"ReadReady()","text":"

    \u68c0\u67e5\u662f\u5426\u6709\u53ef\u7528\u6570\u636e\u3002

    ReadReady(connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u7528\u84dd\u7259\ndroid.toggleBluetoothState(True)\n\n# \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\ndevices = droid.GetBondedDevices().result\nfor dev in devices:\n    print(f\"{dev['name']}: {dev['address']}\")\n\n# \u8fde\u63a5\u5230\u8bbe\u5907\ndroid.Connect(address=\"00:11:22:33:44:55\")\n\n# \u53d1\u9001\u6570\u636e\ndroid.Write(\"Hello Bluetooth!\")\n\n# \u8bfb\u53d6\u54cd\u5e94\ndata = droid.Read(1024).result\n
    "},{"location":"qsl4a/hardware/camera/","title":"\u76f8\u673a API","text":"

    \u62cd\u6444\u7167\u7247\u548c\u5f55\u5236\u89c6\u9891\u3002

    "},{"location":"qsl4a/hardware/camera/#_1","title":"\u7167\u7247\u62cd\u6444","text":""},{"location":"qsl4a/hardware/camera/#takepicture","title":"takePicture()","text":"

    \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u6444\u7167\u7247\u3002

    takePicture(path=None)\n

    \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8fd4\u56de\u56fe\u50cf\u6570\u636e

    \u8fd4\u56de\uff1a \u56fe\u50cf\u8def\u5f84\u6216\u56fe\u50cf\u6570\u636e

    "},{"location":"qsl4a/hardware/camera/#cameracapturepicture","title":"cameraCapturePicture()","text":"

    \u4f7f\u7528\u9ad8\u7ea7\u76f8\u673a\u63a7\u5236\u62cd\u6444\u7167\u7247\u3002

    cameraCapturePicture(targetPath=None, cameraId=0, useAutoFocus=True)\n

    \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - useAutoFocus (bool): \u542f\u7528\u81ea\u52a8\u5bf9\u7126

    \u8fd4\u56de\uff1a \u62cd\u6444\u7684\u56fe\u50cf\u8def\u5f84

    "},{"location":"qsl4a/hardware/camera/#camerasettorchmode","title":"cameraSetTorchMode()","text":"

    \u63a7\u5236\u76f8\u673a\u95ea\u5149\u706f/\u624b\u7535\u7b52\u3002

    cameraSetTorchMode(enabled)\n

    \u53c2\u6570\uff1a - enabled (bool): True \u6253\u5f00\uff0cFalse \u5173\u95ed

    \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/hardware/camera/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

    \u622a\u56fe\u3002

    imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

    \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

    "},{"location":"qsl4a/hardware/camera/#_2","title":"\u89c6\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#takevideo","title":"takeVideo()","text":"

    \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\u3002

    takeVideo(path=None, quality=1)\n

    \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-4\uff09 - 0: 160x120 - 1: 320x240 - 2: 352x288 - 3: 640x480 - 4: 800x480

    "},{"location":"qsl4a/hardware/camera/#recordercapturevideo","title":"recorderCaptureVideo()","text":"

    \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\u3002

    recorderCaptureVideo(targetPath=None, duration=10, cameraId=0, quality=8)\n

    \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - duration (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a10\uff09 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-8\uff0c\u8d8a\u9ad8\u8d8a\u597d\uff09

    \u8fd4\u56de\uff1a \u89c6\u9891\u6587\u4ef6\u8def\u5f84

    "},{"location":"qsl4a/hardware/camera/#recordaudio","title":"recordAudio()","text":"

    \u5f55\u5236\u97f3\u9891\u3002

    recordAudio()\n

    \u8fd4\u56de\uff1a \u97f3\u9891\u6587\u4ef6\u8def\u5f84

    "},{"location":"qsl4a/hardware/camera/#_3","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

    \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\u3002

    recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

    \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\uff09 - targetPixels (int): \u5206\u8fa8\u7387 - frameRate (int): FPS - bitRate (int): \u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa - autoStart (bool): \u7acb\u5373\u5f00\u59cb

    "},{"location":"qsl4a/hardware/camera/#recorderstart","title":"recorderStart()","text":"

    \u5f00\u59cb\u5f55\u5236\u3002

    recorderStart()\n
    "},{"location":"qsl4a/hardware/camera/#recorderpause","title":"recorderPause()","text":"

    \u6682\u505c\u5f55\u5236\u3002

    recorderPause()\n
    "},{"location":"qsl4a/hardware/camera/#recorderresume","title":"recorderResume()","text":"

    \u6062\u590d\u5f55\u5236\u3002

    recorderResume()\n
    "},{"location":"qsl4a/hardware/camera/#_4","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/camera/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

    \u5f00\u59cb\u97f3\u91cf\u68c0\u6d4b\u3002

    recorderSoundVolumeDetect(interval=100)\n
    "},{"location":"qsl4a/hardware/camera/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

    \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

    recorderSoundVolumeGetDb()\n
    "},{"location":"qsl4a/hardware/camera/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u7167\nphoto_path = droid.takePicture(\"/sdcard/photo.jpg\").result\nprint(f\"Photo saved: {photo_path}\")\n\n# \u4f7f\u7528\u524d\u7f6e\u76f8\u673a\u548c\u81ea\u52a8\u5bf9\u7126\u62cd\u7167\ncamera_path = droid.cameraCapturePicture(\"/sdcard/selfie.jpg\", cameraId=1, useAutoFocus=True).result\nprint(f\"Front camera photo: {camera_path}\")\n\n# \u63a7\u5236\u95ea\u5149\u706f\ndroid.cameraSetTorchMode(True)  # \u6253\u5f00\u95ea\u5149\u706f\n\n# \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\nvideo_path = droid.takeVideo(\"/sdcard/video.mp4\", quality=3).result\nprint(f\"Video saved: {video_path}\")\n\n# \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\nvideo_path = droid.recorderCaptureVideo(\"/sdcard/movie.mp4\", duration=30, cameraId=0, quality=8).result\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n
    "},{"location":"qsl4a/hardware/recorder/","title":"\u97f3\u9891\u5f55\u5236 API","text":"

    \u4ece\u9ea6\u514b\u98ce\u548c\u8bbe\u5907\u5c4f\u5e55\u5f55\u5236\u97f3\u9891\u3002

    "},{"location":"qsl4a/hardware/recorder/#_1","title":"\u97f3\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recordaudio","title":"recordAudio()","text":"

    \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\u3002

    recordAudio()\n

    \u8fd4\u56de\uff1a \u5f55\u5236\u7684\u97f3\u9891\u6587\u4ef6\u8def\u5f84

    "},{"location":"qsl4a/hardware/recorder/#recorderstartmicrophone","title":"recorderStartMicrophone()","text":"

    \u5f00\u59cb\u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\u3002

    recorderStartMicrophone(targetPath=None)\n

    \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u5f55\u5236\u7684\u8def\u5f84

    "},{"location":"qsl4a/hardware/recorder/#_2","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

    \u5f00\u59cb\u5e26\u97f3\u9891\u7684\u5c4f\u5e55\u5f55\u5236\u3002

    recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

    \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\u97f3\u9891\uff09 - targetPixels (int): \u76ee\u6807\u5206\u8fa8\u7387\uff08\u50cf\u7d20\uff09 - frameRate (int): \u6bcf\u79d2\u5e27\u6570\uff08\u9ed8\u8ba4\uff1a30\uff09 - bitRate (int): \u89c6\u9891\u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa\u89c6\u9891 - autoStart (bool): \u7acb\u5373\u5f00\u59cb\u5f55\u5236

    \u8fd4\u56de\uff1a \u64cd\u4f5c\u7ed3\u679c

    "},{"location":"qsl4a/hardware/recorder/#recorderstart","title":"recorderStart()","text":"

    \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\uff08\u5f53 autoStart=False \u65f6\uff09\u3002

    recorderStart()\n
    "},{"location":"qsl4a/hardware/recorder/#recorderpause","title":"recorderPause()","text":"

    \u6682\u505c\u6b63\u5728\u8fdb\u884c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

    recorderPause()\n
    "},{"location":"qsl4a/hardware/recorder/#recorderresume","title":"recorderResume()","text":"

    \u6062\u590d\u6682\u505c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

    recorderResume()\n
    "},{"location":"qsl4a/hardware/recorder/#_3","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/recorder/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

    \u5f00\u59cb\u76d1\u63a7\u97f3\u91cf\u7ea7\u522b\u3002

    recorderSoundVolumeDetect(interval=100)\n

    \u53c2\u6570\uff1a - interval (int): \u68c0\u6d4b\u95f4\u9694\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a100\uff09

    "},{"location":"qsl4a/hardware/recorder/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

    \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

    recorderSoundVolumeGetDb()\n

    \u8fd4\u56de\uff1a \u5f53\u524d\u97f3\u91cf\u7ea7\u522b\uff08dB\uff09

    "},{"location":"qsl4a/hardware/recorder/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\nprint(\"Recording audio...\")\naudio_path = droid.recordAudio().result\nprint(f\"Saved to: {audio_path}\")\n\n# \u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\ndroid.recorderStartMicrophone(\"/sdcard/my_recording.mp3\")\ntime.sleep(5)\ndroid.recorderStop()\n\n# \u5e26\u97f3\u9891\u5f55\u5236\u5c4f\u5e55\nprint(\"Starting screen recording...\")\ndroid.recorderStartScreenRecord(\n    path=\"/sdcard/screen_record.mp4\",\n    audio=1,\n    frameRate=30,\n    autoStart=True\n)\ntime.sleep(10)\ndroid.recorderStop()\n\n# \u76d1\u63a7\u97f3\u91cf\ndroid.recorderSoundVolumeDetect(interval=100)\ntime.sleep(3)\nvolume = droid.recorderSoundVolumeGetDb().result\nprint(f\"Current volume: {volume} dB\")\n
    "},{"location":"qsl4a/hardware/usbserial/","title":"USB \u4e3b\u673a\u4e32\u884c API","text":"

    \u4e0e USB \u4e32\u884c\u8bbe\u5907\u901a\u4fe1\uff08\u9700\u8981 USB OTG \u652f\u6301\u548c Android 3.1+\uff09\u3002

    "},{"location":"qsl4a/hardware/usbserial/#usb","title":"USB \u4e32\u884c\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialopen","title":"usbHostSerialOpen()","text":"

    \u6253\u5f00\u4e0e USB \u4e32\u884c\u8bbe\u5907\u7684\u8fde\u63a5\u3002

    usbHostSerialOpen(device, baudRate=9600)\n

    \u53c2\u6570\uff1a - device (str): USB \u8bbe\u5907\u8def\u5f84\u6216\u6807\u8bc6\u7b26 - baudRate (int): \u6ce2\u7279\u7387\uff08\u9ed8\u8ba4\uff1a9600\uff09

    \u8fd4\u56de\uff1a \u5982\u679c\u6253\u5f00\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialclose","title":"usbHostSerialClose()","text":"

    \u5173\u95ed USB \u4e32\u884c\u8fde\u63a5\u3002

    usbHostSerialClose()\n
    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialread","title":"usbHostSerialRead()","text":"

    \u4ece USB \u4e32\u884c\u8bfb\u53d6\u6570\u636e\u3002

    usbHostSerialRead(bufferSize=1024)\n

    \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570\uff08\u9ed8\u8ba4\uff1a1024\uff09

    \u8fd4\u56de\uff1a \u8bfb\u53d6\u7684\u6570\u636e\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwrite","title":"usbHostSerialWrite()","text":"

    \u5411 USB \u4e32\u884c\u5199\u5165\u6570\u636e\u3002

    usbHostSerialWrite(data)\n

    \u53c2\u6570\uff1a - data (str): \u8981\u5199\u5165\u7684\u5b57\u7b26\u4e32\u6570\u636e

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialavailable","title":"usbHostSerialAvailable()","text":"

    \u68c0\u67e5\u662f\u5426\u6709\u53ef\u8bfb\u53d6\u7684\u6570\u636e\u3002

    usbHostSerialAvailable()\n

    \u8fd4\u56de\uff1a \u53ef\u7528\u5b57\u8282\u6570

    "},{"location":"qsl4a/hardware/usbserial/#_1","title":"\u914d\u7f6e\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetbaudrate","title":"usbHostSerialSetBaudRate()","text":"

    \u8bbe\u7f6e\u6ce2\u7279\u7387\u3002

    usbHostSerialSetBaudRate(baudRate)\n

    \u53c2\u6570\uff1a - baudRate (int): \u6ce2\u7279\u7387

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetdatabits","title":"usbHostSerialSetDataBits()","text":"

    \u8bbe\u7f6e\u6570\u636e\u4f4d\uff085\u30016\u30017 \u6216 8\uff09\u3002

    usbHostSerialSetDataBits(dataBits)\n

    \u53c2\u6570\uff1a - dataBits (int): \u6570\u636e\u4f4d\uff085-8\uff09

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetstopbits","title":"usbHostSerialSetStopBits()","text":"

    \u8bbe\u7f6e\u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09\u3002

    usbHostSerialSetStopBits(stopBits)\n

    \u53c2\u6570\uff1a - stopBits (float): \u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetparity","title":"usbHostSerialSetParity()","text":"

    \u8bbe\u7f6e\u6821\u9a8c\u4f4d\uff08\u65e0\u3001\u5947\u3001\u5076\u3001\u6807\u8bb0\u3001\u7a7a\u683c\uff09\u3002

    usbHostSerialSetParity(parity)\n

    \u53c2\u6570\uff1a - parity (str): \u6821\u9a8c\u6a21\u5f0f\uff08'none'\u3001'odd'\u3001'even'\u3001'mark'\u3001'space'\uff09

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetflowcontrol","title":"usbHostSerialSetFlowControl()","text":"

    \u8bbe\u7f6e\u6d41\u63a7\u5236\uff08\u65e0\u3001\u786c\u4ef6\u3001\u8f6f\u4ef6\uff09\u3002

    usbHostSerialSetFlowControl(flowControl)\n

    \u53c2\u6570\uff1a - flowControl (str): \u6d41\u63a7\u5236\u6a21\u5f0f\uff08'none'\u3001'hardware'\u3001'software'\uff09

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialreadhex","title":"usbHostSerialReadHex()","text":"

    \u4ee5\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u8bfb\u53d6\u6570\u636e\u3002

    usbHostSerialReadHex(bufferSize=1024)\n

    \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570

    \u8fd4\u56de\uff1a \u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwritehex","title":"usbHostSerialWriteHex()","text":"

    \u4ece\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u5199\u5165\u6570\u636e\u3002

    usbHostSerialWriteHex(hexString)\n

    \u53c2\u6570\uff1a - hexString (str): \u8981\u5199\u5165\u7684\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/hardware/usbserial/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6253\u5f00 USB \u4e32\u884c\u8fde\u63a5\nif droid.usbHostSerialOpen(\"/dev/bus/usb/001/001\", 115200).result:\n    print(\"USB serial opened\")\n\n    # \u5199\u5165\u6570\u636e\n    droid.usbHostSerialWrite(\"AT\\r\")\n\n    # \u8bfb\u53d6\u54cd\u5e94\n    response = droid.usbHostSerialRead(1024).result\n    print(f\"Response: {response}\")\n\n    # \u6216\u4f7f\u7528\u5341\u516d\u8fdb\u5236\n    droid.usbHostSerialWriteHex(\"41540D0A\")  # \"AT\\r\\n\"\n\n    # \u5173\u95ed\u8fde\u63a5\n    droid.usbHostSerialClose()\n

    \u6ce8\u610f\uff1a USB \u4e32\u884c\u9700\u8981\uff1a - Android 3.1+ (API 12) - USB OTG \u7ebf/\u9002\u914d\u5668 - \u8bbe\u5907\u4e0a\u7684 USB \u4e3b\u673a\u6a21\u5f0f\u652f\u6301 - \u517c\u5bb9\u7684\u4e32\u884c\u8bbe\u5907

    "},{"location":"qsl4a/hardware/webcam/","title":"\u7f51\u7edc\u6444\u50cf\u5934 API","text":"

    \u4f7f\u7528 MJPEG \u4ece\u8bbe\u5907\u76f8\u673a\u6d41\u5f0f\u4f20\u8f93\u89c6\u9891\u3002

    "},{"location":"qsl4a/hardware/webcam/#mjpeg","title":"MJPEG \u6d41\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#webcamstart","title":"webcamStart()","text":"

    \u4ece\u7f51\u7edc\u6444\u50cf\u5934\u542f\u52a8 MJPEG \u6d41\u3002

    webcamStart(resolutionLevel=0, jpegQuality=20, port=0)\n

    \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf 1-100\uff08\u9ed8\u8ba4\uff1a20\uff09 - port (int): \u7aef\u53e3\u53f7\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\uff09

    \u8fd4\u56de\uff1a \u6d41\u7684 (\u5730\u5740, \u7aef\u53e3) \u5143\u7ec4

    "},{"location":"qsl4a/hardware/webcam/#webcamadjustquality","title":"webcamAdjustQuality()","text":"

    \u8c03\u6574\u6d3b\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u7684\u8d28\u91cf\u3002

    webcamAdjustQuality(resolutionLevel=0, jpegQuality=20)\n

    \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b - jpegQuality (int): JPEG \u8d28\u91cf 1-100

    "},{"location":"qsl4a/hardware/webcam/#webcamstop","title":"webcamStop()","text":"

    \u505c\u6b62\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u3002

    webcamStop()\n
    "},{"location":"qsl4a/hardware/webcam/#_1","title":"\u76f8\u673a\u9884\u89c8\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#camerastartpreview","title":"cameraStartPreview()","text":"

    \u5f00\u59cb\u5e26\u4e8b\u4ef6\u751f\u6210\u7684\u76f8\u673a\u9884\u89c8\u6a21\u5f0f\u3002

    cameraStartPreview(resolutionLevel=0, jpegQuality=20, filepath=None)\n

    \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf\uff08\u9ed8\u8ba4\uff1a20\uff09 - filepath (str, optional): \u4fdd\u5b58\u9884\u89c8\u5e27\u7684\u6587\u4ef6\u8def\u5f84

    \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

    \u6ce8\u610f\uff1a \u751f\u6210\u5e26\u6709\u5e27\u6570\u636e\u7684 'preview' \u4e8b\u4ef6\u3002

    "},{"location":"qsl4a/hardware/webcam/#camerastoppreview","title":"cameraStopPreview()","text":"

    \u505c\u6b62\u76f8\u673a\u9884\u89c8\u3002

    cameraStopPreview()\n
    "},{"location":"qsl4a/hardware/webcam/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\nstream_info = droid.webcamStart(\n    resolutionLevel=0,\n    jpegQuality=30,\n    port=8080\n).result\nprint(f\"Stream available at {stream_info[0]}:{stream_info[1]}\")\n\n# \u6d41\u5f0f\u4f20\u8f93\u65f6\u8c03\u6574\u8d28\u91cf\ntime.sleep(5)\ndroid.webcamAdjustQuality(resolutionLevel=1, jpegQuality=50)\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.webcamStop()\n\n# \u6216\u4f7f\u7528\u9884\u89c8\u6a21\u5f0f\nprint(\"Starting preview...\")\ndroid.cameraStartPreview()\n\n# \u7b49\u5f85\u9884\u89c8\u4e8b\u4ef6\nfor i in range(10):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'preview':\n        print(f\"Got preview frame: {event['data']}\")\n\ndroid.cameraStopPreview()\n
    "},{"location":"qsl4a/media/image/","title":"\u56fe\u50cf\u5904\u7406 API","text":"

    \u538b\u7f29\u548c\u5904\u7406\u56fe\u50cf\u3002

    "},{"location":"qsl4a/media/image/#_1","title":"\u56fe\u50cf\u538b\u7f29","text":""},{"location":"qsl4a/media/image/#imagecompress","title":"imageCompress()","text":"

    \u538b\u7f29\u56fe\u50cf\u6587\u4ef6\u3002

    imageCompress(srcPath, destPath, targetByteSize=0, targetWidth=0, targetHeight=0)\n

    \u53c2\u6570\uff1a - srcPath (str): \u6e90\u56fe\u50cf\u8def\u5f84 - destPath (str): \u8f93\u51fa\u8def\u5f84 - targetByteSize (int): \u76ee\u6807\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff080 = \u65e0\u9650\u5236\uff09 - targetWidth (int): \u76ee\u6807\u5bbd\u5ea6\uff080 = \u539f\u59cb\uff09 - targetHeight (int): \u76ee\u6807\u9ad8\u5ea6\uff080 = \u539f\u59cb\uff09

    \u8fd4\u56de\uff1a \u538b\u7f29\u540e\u7684\u56fe\u50cf\u8def\u5f84

    "},{"location":"qsl4a/media/image/#_2","title":"\u622a\u56fe","text":""},{"location":"qsl4a/media/image/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

    \u622a\u53d6\u5c4f\u5e55\u3002

    imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

    \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

    \u8fd4\u56de\uff1a \u622a\u56fe\u8def\u5f84

    "},{"location":"qsl4a/media/image/#_3","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/image/#videoplay","title":"videoPlay()","text":"

    \u5728\u5168\u5c4f\u6a21\u5f0f\u4e0b\u64ad\u653e\u89c6\u9891\u6587\u4ef6\u3002

    videoPlay(path, wait=True)\n

    \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

    "},{"location":"qsl4a/media/image/#_4","title":"\u6761\u7801\u626b\u63cf","text":""},{"location":"qsl4a/media/image/#scanbarcodefromimage","title":"scanBarcodeFromImage()","text":"

    \u4ece\u56fe\u50cf\u6587\u4ef6\u626b\u63cf\u6761\u7801/\u4e8c\u7ef4\u7801\u3002

    scanBarcodeFromImage(path, compressRatio=0, x=0, y=0, width=0, height=0)\n

    \u53c2\u6570\uff1a - path (str): \u56fe\u50cf\u6587\u4ef6\u8def\u5f84 - compressRatio (int): \u538b\u7f29\u6bd4\uff080 = \u4e0d\u538b\u7f29\uff09 - x, y, width, height (int): \u8981\u626b\u63cf\u7684\u533a\u57df\uff080 = \u5b8c\u6574\u56fe\u50cf\uff09

    \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5185\u5bb9

    "},{"location":"qsl4a/media/image/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n\n# \u538b\u7f29\u56fe\u50cf\ncompressed = droid.imageCompress(\n    \"/sdcard/large_photo.jpg\",\n    \"/sdcard/compressed.jpg\",\n    targetByteSize=102400,  # \u76ee\u6807\u7ea6 100KB\n    targetWidth=1920,\n    targetHeight=1080\n).result\nprint(f\"Saved: {compressed}\")\n\n# \u64ad\u653e\u89c6\u9891\nvideo_path = \"/sdcard/movie.mp4\"\ndroid.videoPlay(video_path, wait=True)\n\n# \u4ece\u56fe\u50cf\u626b\u63cf\u6761\u7801\nresult = droid.scanBarcodeFromImage(\"/sdcard/qr_code.png\").result\nprint(f\"Barcode: {result}\")\n
    "},{"location":"qsl4a/media/mediaplayer/","title":"\u5a92\u4f53\u64ad\u653e\u5668 API","text":"

    \u63a7\u5236\u97f3\u9891\u548c\u89c6\u9891\u64ad\u653e\u3002

    "},{"location":"qsl4a/media/mediaplayer/#_1","title":"\u64ad\u653e\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplay","title":"mediaPlay()","text":"

    \u64ad\u653e\u5a92\u4f53\u6587\u4ef6\u3002

    mediaPlay(url, tag=\"default\", play=True)\n

    \u53c2\u6570\uff1a - url (str): \u5a92\u4f53\u6587\u4ef6\u8def\u5f84\u6216 URL - tag (str): \u64ad\u653e\u5668\u6807\u8bc6\u7b26 - play (bool): \u81ea\u52a8\u5f00\u59cb\u64ad\u653e

    "},{"location":"qsl4a/media/mediaplayer/#mediaplaystart","title":"mediaPlayStart()","text":"

    \u5f00\u59cb\u64ad\u653e\u3002

    mediaPlayStart(tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#mediaplaypause","title":"mediaPlayPause()","text":"

    \u6682\u505c\u64ad\u653e\u3002

    mediaPlayPause(tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#mediaplayclose","title":"mediaPlayClose()","text":"

    \u5173\u95ed\u64ad\u653e\u5668\u3002

    mediaPlayClose(tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#mediaplayseek","title":"mediaPlaySeek()","text":"

    \u8df3\u8f6c\u5230\u4f4d\u7f6e\u3002

    mediaPlaySeek(msec, tag=\"default\")\n

    \u53c2\u6570\uff1a - msec (int): \u4f4d\u7f6e\uff08\u6beb\u79d2\uff09

    "},{"location":"qsl4a/media/mediaplayer/#mediaplaysetlooping","title":"mediaPlaySetLooping()","text":"

    \u8bbe\u7f6e\u5faa\u73af\u6a21\u5f0f\u3002

    mediaPlaySetLooping(enabled, tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#_2","title":"\u64ad\u653e\u5668\u4fe1\u606f","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplayinfo","title":"mediaPlayInfo()","text":"

    \u83b7\u53d6\u64ad\u653e\u4fe1\u606f\u3002

    mediaPlayInfo(tag=\"default\")\n

    \u8fd4\u56de\uff1a \u5305\u542b\u65f6\u957f\u3001\u4f4d\u7f6e\u7b49\u7684\u5b57\u5178

    "},{"location":"qsl4a/media/mediaplayer/#mediaisplaying","title":"mediaIsPlaying()","text":"

    \u68c0\u67e5\u662f\u5426\u6b63\u5728\u64ad\u653e\u3002

    mediaIsPlaying(tag=\"default\")\n

    \u8fd4\u56de\uff1a True/False

    "},{"location":"qsl4a/media/mediaplayer/#mediaplaylist","title":"mediaPlayList()","text":"

    \u5217\u51fa\u6d3b\u52a8\u64ad\u653e\u5668\u3002

    mediaPlayList()\n
    "},{"location":"qsl4a/media/mediaplayer/#_3","title":"\u97f3\u91cf\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#getmediavolume","title":"getMediaVolume()","text":"

    \u83b7\u53d6\u5a92\u4f53\u97f3\u91cf\u3002

    getMediaVolume()\n

    \u8fd4\u56de\uff1a \u97f3\u91cf\u7ea7\u522b\uff080-15\uff09

    "},{"location":"qsl4a/media/mediaplayer/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

    \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

    getMaxMediaVolume()\n
    "},{"location":"qsl4a/media/mediaplayer/#getringervolume","title":"getRingerVolume()","text":"

    \u83b7\u53d6\u94c3\u58f0\u97f3\u91cf\u3002

    getRingerVolume()\n
    "},{"location":"qsl4a/media/mediaplayer/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

    \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

    getMaxRingerVolume()\n
    "},{"location":"qsl4a/media/mediaplayer/#_4","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/mediaplayer/#videoplay","title":"videoPlay()","text":"

    \u5168\u5c4f\u64ad\u653e\u89c6\u9891\u3002

    videoPlay(path, wait=True)\n

    \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210

    "},{"location":"qsl4a/media/mediaplayer/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u64ad\u653e\u97f3\u9891\ndroid.mediaPlay(\"/sdcard/music.mp3\", tag=\"music\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.mediaIsPlaying(\"music\").result:\n    info = droid.mediaPlayInfo(\"music\").result\n    print(f\"Playing: {info}\")\n\n# \u8df3\u8f6c\u5230 30 \u79d2\ndroid.mediaPlaySeek(30000, \"music\")\n\n# \u5173\u95ed\ndroid.mediaPlayClose(\"music\")\n\n# \u64ad\u653e\u89c6\u9891\ndroid.videoPlay(\"/sdcard/movie.mp4\", wait=True)\n
    "},{"location":"qsl4a/special/cipher/","title":"\u5bc6\u7801 API","text":"

    \u7528\u4e8e\u5b89\u5168\u6570\u636e\u5b58\u50a8\u7684\u52a0\u5bc6\u548c\u89e3\u5bc6\u5de5\u5177\u3002

    "},{"location":"qsl4a/special/cipher/#_1","title":"\u521d\u59cb\u5316","text":""},{"location":"qsl4a/special/cipher/#cipherinit","title":"cipherInit()","text":"

    \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u548c\u7b97\u6cd5\u521d\u59cb\u5316\u5bc6\u7801\u5668\u3002

    cipherInit(key, algorithm=\"AES/CBC/PKCS5Padding\", encodingFormat=\"\", initialVector=\"\")\n

    \u53c2\u6570\uff1a - key (str or bytes): \u52a0\u5bc6\u5bc6\u94a5 - algorithm (str): \u5bc6\u7801\u7b97\u6cd5\uff08\u9ed8\u8ba4\uff1a\"AES/CBC/PKCS5Padding\"\uff09 - encodingFormat (str): \u7f16\u7801\u683c\u5f0f - initialVector (str or bytes): \u52a0\u5bc6\u7684\u521d\u59cb\u5411\u91cf

    \u8fd4\u56de\uff1a \u521d\u59cb\u5316\u7ed3\u679c

    \u6ce8\u610f\uff1a \u5fc5\u987b\u5728\u4efb\u4f55\u52a0\u5bc6/\u89e3\u5bc6\u64cd\u4f5c\u4e4b\u524d\u8c03\u7528\u3002

    "},{"location":"qsl4a/special/cipher/#_2","title":"\u52a0\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#encryptstring","title":"encryptString()","text":"

    \u52a0\u5bc6\u5b57\u7b26\u4e32\u3002

    encryptString(plainText)\n

    \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c

    \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/special/cipher/#encryptbytes","title":"encryptBytes()","text":"

    \u52a0\u5bc6\u5b57\u8282\u6570\u636e\u3002

    encryptBytes(data)\n

    \u53c2\u6570\uff1a - data (bytes): \u8981\u52a0\u5bc6\u7684\u6570\u636e

    \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u8282

    "},{"location":"qsl4a/special/cipher/#encryptstringtofile","title":"encryptStringToFile()","text":"

    \u52a0\u5bc6\u5b57\u7b26\u4e32\u5230\u6587\u4ef6\u3002

    encryptStringToFile(plainText, filePath)\n

    \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c - filePath (str): \u8f93\u51fa\u6587\u4ef6\u8def\u5f84

    "},{"location":"qsl4a/special/cipher/#encryptbytestofile","title":"encryptBytesToFile()","text":"

    \u52a0\u5bc6\u5b57\u8282\u5230\u6587\u4ef6\u3002

    encryptBytesToFile(data, filePath)\n
    "},{"location":"qsl4a/special/cipher/#_3","title":"\u89e3\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#decryptstring","title":"decryptString()","text":"

    \u89e3\u5bc6\u4e3a\u5b57\u7b26\u4e32\u3002

    decryptString(cipherText)\n

    \u53c2\u6570\uff1a - cipherText (str): \u52a0\u5bc6\u7684\u6587\u672c

    \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/special/cipher/#decryptbytes","title":"decryptBytes()","text":"

    \u89e3\u5bc6\u4e3a\u5b57\u8282\u3002

    decryptBytes(data)\n

    \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u8282

    "},{"location":"qsl4a/special/cipher/#decryptfiletostring","title":"decryptFileToString()","text":"

    \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u7b26\u4e32\u3002

    decryptFileToString(filePath)\n
    "},{"location":"qsl4a/special/cipher/#decryptfiletobytes","title":"decryptFileToBytes()","text":"

    \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u8282\u3002

    decryptFileToBytes(filePath)\n
    "},{"location":"qsl4a/special/cipher/#decryptfile","title":"decryptFile()","text":"

    \u89e3\u5bc6\u6587\u4ef6\u5230\u6587\u4ef6\u3002

    decryptFile(srcPath, destPath)\n
    "},{"location":"qsl4a/special/cipher/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u521d\u59cb\u5316\u5bc6\u7801\u5668\ndroid.cipherInit(\"my_secret_key_1234\")\n\n# \u52a0\u5bc6\u5b57\u7b26\u4e32\nencrypted = droid.encryptString(\"Secret message!\").result\nprint(f\"Encrypted: {encrypted}\")\n\n# \u89e3\u5bc6\u5b57\u7b26\u4e32\ndecrypted = droid.decryptString(encrypted).result\nprint(f\"Decrypted: {decrypted}\")\n\n# \u52a0\u5bc6\u5230\u6587\u4ef6\ndroid.encryptStringToFile(\"My secret data\", \"/sdcard/secret.dat\")\n\n# \u4ece\u6587\u4ef6\u89e3\u5bc6\ndata = droid.decryptFileToString(\"/sdcard/secret.dat\").result\nprint(data)\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u7b97\u6cd5\u548c IV \u521d\u59cb\u5316\ndroid.cipherInit(\n    key=\"my_key\",\n    algorithm=\"AES/CBC/PKCS5Padding\",\n    initialVector=\"0123456789abcdef\"\n)\n
    "},{"location":"qsl4a/special/pgptai/","title":"PGPT AI API","text":"

    \u8bed\u97f3\u8f6c\u6587\u672c\u548c AI \u670d\u52a1\u96c6\u6210\u3002

    "},{"location":"qsl4a/special/pgptai/#_1","title":"\u5148\u51b3\u6761\u4ef6","text":"
    pip install pgptAI\n
    "},{"location":"qsl4a/special/pgptai/#_2","title":"\u8bed\u97f3\u8bc6\u522b","text":""},{"location":"qsl4a/special/pgptai/#speechtotext","title":"speechToText()","text":"

    \u5c06\u8bed\u97f3\u8f6c\u6362\u4e3a\u6587\u672c\u3002

    speechToText(RecordSecond=10, AmrFile=None, Language=None)\n

    \u53c2\u6570\uff1a - RecordSecond (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09 - AmrFile (str, optional): \u73b0\u6709\u97f3\u9891\u6587\u4ef6\u8def\u5f84 - Language (str, optional): \u8bed\u8a00\u4ee3\u7801\uff08'en'\u3001'zh'\uff09

    \u8fd4\u56de\uff1a \u8f6c\u5f55\u7684\u6587\u672c

    "},{"location":"qsl4a/special/pgptai/#_3","title":"\u6587\u672c\u8f6c\u8bed\u97f3","text":""},{"location":"qsl4a/special/pgptai/#texttospeech","title":"textToSpeech()","text":"

    \u5c06\u6587\u672c\u8f6c\u6362\u4e3a\u8bed\u97f3\u5e76\u53ef\u9009\u5730\u64ad\u653e\u3002

    textToSpeech(Text, AutoPlay=True, WavFile=None, VoiceName=None)\n

    \u53c2\u6570\uff1a - Text (str): \u8981\u8f6c\u6362\u4e3a\u8bed\u97f3\u7684\u6587\u672c - AutoPlay (bool): \u81ea\u52a8\u64ad\u653e\u751f\u6210\u7684\u97f3\u9891\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - WavFile (str, optional): \u4fdd\u5b58 WAV \u6587\u4ef6\u7684\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u4e34\u65f6\u6587\u4ef6 - VoiceName (str, optional): \u8981\u4f7f\u7528\u7684\u8bed\u97f3\u540d\u79f0\uff08\u4f8b\u5982 'en-US-JennyNeural'\u3001'zh-CN-XiaoxiaoNeural'\uff09

    \u8fd4\u56de\uff1a \u5305\u542b\u8bed\u97f3\u5408\u6210\u7ed3\u679c\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - text: \u8f93\u5165\u6587\u672c - url: \u4e0b\u8f7d\u97f3\u9891\u6587\u4ef6\u7684 URL - WavFile: \u4fdd\u5b58\u7684 WAV \u6587\u4ef6\u8def\u5f84\uff08\u5982\u679c\u672c\u5730\u4fdd\u5b58\uff09

    "},{"location":"qsl4a/special/pgptai/#_4","title":"\u914d\u7f6e","text":"

    API \u4f7f\u7528\u4ee5\u4e0b\u914d\u7f6e\u6587\u4ef6\u4e2d\u7684\u914d\u7f6e\uff1a/storage/emulated/0/Android/data/org.qpython.qpy/files/apigpt.conf\uff1a

    [speech]\nspeech_key = your_api_key\n

    \u9ed8\u8ba4\u8bed\u97f3\u8bbe\u7f6e\uff1a - \u82f1\u8bed\uff1aen-US-JennyNeural - \u4e2d\u6587\uff1azh-CN-XiaoxiaoNeural

    "},{"location":"qsl4a/special/pgptai/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5f55\u5236\u5e76\u8f6c\u5f55\nprint(\"Recording for 5 seconds...\")\ntext = droid.speechToText(RecordSecond=5, Language='en').result\nprint(f\"You said: {text}\")\n\n# \u8f6c\u5f55\u73b0\u6709\u6587\u4ef6\ntext = droid.speechToText(AmrFile=\"/sdcard/recording.amr\").result\nprint(f\"Transcription: {text}\")\n\n# \u6587\u672c\u8f6c\u8bed\u97f3\ndroid.textToSpeech(\"Hello, this is a test message.\", AutoPlay=True, Language='en')\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u8bed\u97f3\u5e76\u4fdd\u5b58\u5230\u6587\u4ef6\u7684\u6587\u672c\u8f6c\u8bed\u97f3\nresult = droid.textToSpeech(\n    \"Welcome to QPython!\",\n    AutoPlay=False,\n    WavFile=\"/sdcard/welcome.wav\",\n    VoiceName=\"en-US-JennyNeural\"\n).result\nprint(f\"Audio saved to: {result.get('WavFile')}\")\n
    "},{"location":"qsl4a/special/pgptai/#_6","title":"\u7c7b\u4f7f\u7528","text":"
    from androidhelper.pgptai import pgptai\nimport androidhelper\n\ndroid = androidhelper.Android()\nai = pgptai(droid)\n\n# \u4f7f\u7528\u8bed\u97f3\u8bc6\u522b\ntext = ai.speechToText(RecordSecond=10)\n
    "},{"location":"qsl4a/storage/clipboard/","title":"\u526a\u8d34\u677f API","text":"

    \u590d\u5236\u548c\u7c98\u8d34\u6587\u672c\u5230\u7cfb\u7edf\u526a\u8d34\u677f\u3002

    "},{"location":"qsl4a/storage/clipboard/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/clipboard/#setclipboard","title":"setClipboard()","text":"

    \u590d\u5236\u6587\u672c\u5230\u526a\u8d34\u677f\u3002

    setClipboard(text)\n

    \u53c2\u6570\uff1a - text (str): \u8981\u590d\u5236\u7684\u6587\u672c

    \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/storage/clipboard/#getclipboard","title":"getClipboard()","text":"

    \u4ece\u526a\u8d34\u677f\u83b7\u53d6\u6587\u672c\u3002

    getClipboard()\n

    \u8fd4\u56de\uff1a \u526a\u8d34\u677f\u6587\u672c

    "},{"location":"qsl4a/storage/clipboard/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u590d\u5236\u5230\u526a\u8d34\u677f\ndroid.setClipboard(\"Hello from QPython!\")\n\n# \u4ece\u526a\u8d34\u677f\u7c98\u8d34\ntext = droid.getClipboard().result\nprint(f\"Clipboard: {text}\")\n
    "},{"location":"qsl4a/storage/documentfile/","title":"DocumentFile API","text":"

    \u4f7f\u7528 SAF\uff08\u5b58\u50a8\u8bbf\u95ee\u6846\u67b6\uff09\u8fdb\u884c\u6587\u4ef6\u64cd\u4f5c\uff0c\u652f\u6301 Android 4.4+\u3002

    "},{"location":"qsl4a/storage/documentfile/#_1","title":"\u76ee\u5f55\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilemkdir","title":"documentFileMkdir()","text":"

    \u521b\u5efa\u76ee\u5f55\u3002

    documentFileMkdir(Dir)\n

    \u53c2\u6570\uff1a - Dir (str): \u76ee\u5f55\u8def\u5f84

    \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/storage/documentfile/#documentfilelistfiles","title":"documentFileListFiles()","text":"

    \u5217\u51fa\u76ee\u5f55\u4e2d\u7684\u6587\u4ef6\u3002

    documentFileListFiles(Folder)\n

    \u8fd4\u56de\uff1a \u6587\u4ef6\u5217\u8868

    "},{"location":"qsl4a/storage/documentfile/#_2","title":"\u6587\u4ef6\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileexists","title":"documentFileExists()","text":"

    \u68c0\u67e5\u6587\u4ef6\u6216\u76ee\u5f55\u662f\u5426\u5b58\u5728\u3002

    documentFileExists(path)\n

    \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u6216\u76ee\u5f55\u8def\u5f84

    \u8fd4\u56de\uff1a \u5982\u679c\u5b58\u5728\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

    "},{"location":"qsl4a/storage/documentfile/#documentfileisfile","title":"documentFileIsFile()","text":"

    \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u6587\u4ef6\u3002

    documentFileIsFile(path)\n

    \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

    \u8fd4\u56de\uff1a \u5982\u679c\u662f\u6587\u4ef6\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u6587\u4ef6\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

    "},{"location":"qsl4a/storage/documentfile/#documentfileisdirectory","title":"documentFileIsDirectory()","text":"

    \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u76ee\u5f55\u3002

    documentFileIsDirectory(path)\n

    \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

    \u8fd4\u56de\uff1a \u5982\u679c\u662f\u76ee\u5f55\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u76ee\u5f55\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

    "},{"location":"qsl4a/storage/documentfile/#documentfiledelete","title":"documentFileDelete()","text":"

    \u5220\u9664\u6587\u4ef6\u6216\u76ee\u5f55\u3002

    documentFileDelete(FileOrTree)\n

    \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/storage/documentfile/#documentfilerenameto","title":"documentFileRenameTo()","text":"

    \u91cd\u547d\u540d\u6216\u79fb\u52a8\u6587\u4ef6\u3002

    documentFileRenameTo(Src, Dest)\n

    \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/storage/documentfile/#documentfilecopy","title":"documentFileCopy()","text":"

    \u590d\u5236\u6587\u4ef6\u3002

    documentFileCopy(SrcFileOrTree, DestFileOrTree)\n
    "},{"location":"qsl4a/storage/documentfile/#_3","title":"\u6d41\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileinputstream","title":"documentFileInputStream()","text":"

    \u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9\u3002

    documentFileInputStream(srcFile, EncodingFormat=\"\", skip=None, length=None)\n

    \u53c2\u6570\uff1a - srcFile (str): \u6e90\u6587\u4ef6 - EncodingFormat (str): \"UTF-8\"\u3001\"GBK\"\u3001\"Base64\" \u6216\u7a7a\u5b57\u7b26\u4e32\u8868\u793a\u5b57\u8282 - skip (int): \u4ece\u5f00\u5934\u8df3\u8fc7\u7684\u5b57\u8282\u6570 - length (int): \u8bfb\u53d6\u957f\u5ea6

    \u8fd4\u56de\uff1a \u6587\u4ef6\u5185\u5bb9

    "},{"location":"qsl4a/storage/documentfile/#documentfileoutputstream","title":"documentFileOutputStream()","text":"

    \u5199\u5165\u6587\u4ef6\u5185\u5bb9\u3002

    documentFileOutputStream(destFile, src, EncodingFormat=\"\", append=None)\n

    \u53c2\u6570\uff1a - destFile (str): \u76ee\u6807\u6587\u4ef6 - src: \u8981\u5199\u5165\u7684\u6570\u636e - EncodingFormat (str): \u7f16\u7801\u683c\u5f0f - append (bool): \u8ffd\u52a0\u6a21\u5f0f

    "},{"location":"qsl4a/storage/documentfile/#_4","title":"\u6587\u4ef6\u4fe1\u606f","text":""},{"location":"qsl4a/storage/documentfile/#documentfilelength","title":"documentFileLength()","text":"

    \u83b7\u53d6\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\u3002

    documentFileLength(path)\n

    \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

    \u8fd4\u56de\uff1a \u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

    "},{"location":"qsl4a/storage/documentfile/#documentfilelastmodified","title":"documentFileLastModified()","text":"

    \u83b7\u53d6\u6700\u540e\u4fee\u6539\u65f6\u95f4\u3002

    documentFileLastModified(path)\n

    \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

    \u8fd4\u56de\uff1a \u65f6\u95f4\u6233\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

    "},{"location":"qsl4a/storage/documentfile/#documentfilegetstat","title":"documentFileGetStat()","text":"

    \u83b7\u53d6\u5168\u9762\u7684\u6587\u4ef6\u7edf\u8ba1\u4fe1\u606f\u3002

    documentFileGetStat(path)\n

    \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

    \u8fd4\u56de\uff1a \u5305\u542b\u957f\u5ea6\u3001\u6700\u540e\u4fee\u6539\u65f6\u95f4\u548c\u8bfb/\u5199\u6743\u9650\u7684\u5b57\u5178\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

    "},{"location":"qsl4a/storage/documentfile/#uri","title":"URI \u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilegeturi","title":"documentFileGetUri()","text":"

    \u4ece\u8def\u5f84\u83b7\u53d6 URI\u3002

    documentFileGetUri(path, isDirectory=None)\n
    "},{"location":"qsl4a/storage/documentfile/#documentfileshowopen","title":"documentFileShowOpen()","text":"

    \u663e\u793a\u6587\u4ef6\u9009\u62e9\u5668\u3002

    documentFileShowOpen()\n

    \u8fd4\u56de\uff1a \u9009\u62e9\u7684\u6587\u4ef6 URI

    "},{"location":"qsl4a/storage/documentfile/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u76ee\u5f55\ndroid.documentFileMkdir(\"/sdcard/MyFolder\")\n\n# \u5217\u51fa\u6587\u4ef6\nfiles = droid.documentFileListFiles(\"/sdcard\").result\nfor f in files:\n    print(f)\n\n# \u8bfb\u53d6\u6587\u4ef6\ncontent = droid.documentFileInputStream(\n    \"/sdcard/test.txt\",\n    EncodingFormat=\"UTF-8\"\n).result\nprint(content)\n\n# \u5199\u5165\u6587\u4ef6\ndroid.documentFileOutputStream(\n    \"/sdcard/output.txt\",\n    \"Hello World\",\n    EncodingFormat=\"UTF-8\"\n)\n
    "},{"location":"qsl4a/storage/preferences/","title":"\u504f\u597d\u8bbe\u7f6e API","text":"

    \u4f7f\u7528 Android SharedPreferences \u5b58\u50a8\u548c\u68c0\u7d22\u6570\u636e\u3002

    "},{"location":"qsl4a/storage/preferences/#_1","title":"\u504f\u597d\u8bbe\u7f6e\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/preferences/#prefgetvalue","title":"prefGetValue()","text":"

    \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u8bfb\u53d6\u503c\u3002

    prefGetValue(key, filename=None)\n

    \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

    \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c\uff08\u4efb\u610f\u7c7b\u578b\uff09

    "},{"location":"qsl4a/storage/preferences/#prefputvalue","title":"prefPutValue()","text":"

    \u5199\u5165\u503c\u5230\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u3002

    prefPutValue(key, value, filename=None)\n

    \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - value (object): \u8981\u5b58\u50a8\u7684\u503c - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

    "},{"location":"qsl4a/storage/preferences/#prefgetall","title":"prefGetAll()","text":"

    \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\u503c\u3002

    prefGetAll(filename=None)\n

    \u53c2\u6570\uff1a - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

    \u8fd4\u56de\uff1a \u6240\u6709\u504f\u597d\u7684\u6620\u5c04

    "},{"location":"qsl4a/storage/preferences/#prefremovevalue","title":"prefRemoveValue()","text":"

    \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u4e2d\u79fb\u9664\u503c\u3002

    prefRemoveValue(key, filename=None)\n

    \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

    "},{"location":"qsl4a/storage/preferences/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b58\u50a8\u503c\ndroid.prefPutValue(\"username\", \"alice\")\ndroid.prefPutValue(\"score\", 100)\ndroid.prefPutValue(\"enabled\", True)\n\n# \u8bfb\u53d6\u7279\u5b9a\u503c\nusername = droid.prefGetValue(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\nall_prefs = droid.prefGetAll().result\nprint(f\"All prefs: {all_prefs}\")\n\n# \u79fb\u9664\u503c\ndroid.prefRemoveValue(\"score\")\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u6587\u4ef6\u540d\ndroid.prefPutValue(\"token\", \"abc123\", filename=\"auth.prefs\")\ntoken = droid.prefGetValue(\"token\", filename=\"auth.prefs\").result\n
    "},{"location":"qsl4a/system/activityresult/","title":"Activity Result API","text":"

    \u4e3a\u901a\u8fc7 startActivityForResult \u542f\u52a8\u7684\u811a\u672c\u8bbe\u7f6e activity \u7ed3\u679c\u3002

    "},{"location":"qsl4a/system/activityresult/#_1","title":"\u7ed3\u679c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/activityresult/#setresultboolean","title":"setResultBoolean()","text":"

    \u8bbe\u7f6e\u5e03\u5c14\u7ed3\u679c\u3002

    setResultBoolean(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (bool): \u5e03\u5c14\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#setresultbyte","title":"setResultByte()","text":"

    \u8bbe\u7f6e\u5b57\u8282\u7ed3\u679c\u3002

    setResultByte(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u5b57\u8282\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#setresultshort","title":"setResultShort()","text":"

    \u8bbe\u7f6e\u77ed\u6574\u6570\u7ed3\u679c\u3002

    setResultShort(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u77ed\u6574\u6570\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#setresultchar","title":"setResultChar()","text":"

    \u8bbe\u7f6e\u5b57\u7b26\u7ed3\u679c\u3002

    setResultChar(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#setresultinteger","title":"setResultInteger()","text":"

    \u8bbe\u7f6e\u6574\u6570\u7ed3\u679c\u3002

    setResultInteger(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u6574\u6570\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#setresultlong","title":"setResultLong()","text":"

    \u8bbe\u7f6e\u957f\u6574\u6570\u7ed3\u679c\u3002

    setResultLong(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u957f\u6574\u6570\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#setresultfloat","title":"setResultFloat()","text":"

    \u8bbe\u7f6e\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

    setResultFloat(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u6d6e\u70b9\u6570\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#setresultdouble","title":"setResultDouble()","text":"

    \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

    setResultDouble(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#setresultstring","title":"setResultString()","text":"

    \u8bbe\u7f6e\u5b57\u7b26\u4e32\u7ed3\u679c\u3002

    setResultString(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u4e32\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#setresultbooleanarray","title":"setResultBooleanArray()","text":"

    \u8bbe\u7f6e\u5e03\u5c14\u6570\u7ec4\u7ed3\u679c\u3002

    setResultBooleanArray(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5e03\u5c14\u6570\u7ec4

    "},{"location":"qsl4a/system/activityresult/#setresultbytearray","title":"setResultByteArray()","text":"

    \u8bbe\u7f6e\u5b57\u8282\u6570\u7ec4\u7ed3\u679c\u3002

    setResultByteArray(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u8282\u6570\u7ec4

    "},{"location":"qsl4a/system/activityresult/#setresultshortarray","title":"setResultShortArray()","text":"

    \u8bbe\u7f6e\u77ed\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

    setResultShortArray(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u77ed\u6574\u6570\u6570\u7ec4

    "},{"location":"qsl4a/system/activityresult/#setresultchararray","title":"setResultCharArray()","text":"

    \u8bbe\u7f6e\u5b57\u7b26\u6570\u7ec4\u7ed3\u679c\u3002

    setResultCharArray(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u6570\u7ec4

    "},{"location":"qsl4a/system/activityresult/#setresultintegerarray","title":"setResultIntegerArray()","text":"

    \u8bbe\u7f6e\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

    setResultIntegerArray(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6574\u6570\u6570\u7ec4

    "},{"location":"qsl4a/system/activityresult/#setresultlongarray","title":"setResultLongArray()","text":"

    \u8bbe\u7f6e\u957f\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

    setResultLongArray(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u957f\u6574\u6570\u6570\u7ec4

    "},{"location":"qsl4a/system/activityresult/#setresultfloatarray","title":"setResultFloatArray()","text":"

    \u8bbe\u7f6e\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

    setResultFloatArray(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6d6e\u70b9\u6570\u6570\u7ec4

    "},{"location":"qsl4a/system/activityresult/#setresultdoublearray","title":"setResultDoubleArray()","text":"

    \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

    setResultDoubleArray(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4

    "},{"location":"qsl4a/system/activityresult/#setresultstringarray","title":"setResultStringArray()","text":"

    \u8bbe\u7f6e\u5b57\u7b26\u4e32\u6570\u7ec4\u7ed3\u679c\u3002

    setResultStringArray(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u4e32\u6570\u7ec4

    "},{"location":"qsl4a/system/activityresult/#setresultserializable","title":"setResultSerializable()","text":"

    \u8bbe\u7f6e\u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u3002

    setResultSerializable(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue: \u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c activity \u540e\uff0c\u8bbe\u7f6e\u7ed3\u679c\n# \u793a\u4f8b\uff1a\u8fd4\u56de\u6210\u529f\u53ca\u6570\u636e\ndroid.setResultInteger(0, 200)  # RESULT_OK\ndroid.setResultString(0, \"Operation completed successfully\")\n\n# \u8fd4\u56de\u6570\u7ec4\u7ed3\u679c\ndroid.setResultIntegerArray(0, [1, 2, 3, 4, 5])\n
    "},{"location":"qsl4a/system/application/","title":"\u5e94\u7528\u7ba1\u7406","text":"

    \u7ba1\u7406\u5e94\u7528\u7a0b\u5e8f\u3001\u542f\u52a8\u5e94\u7528\u548c\u67e5\u8be2\u7cfb\u7edf\u4fe1\u606f\u3002

    "},{"location":"qsl4a/system/application/#_2","title":"\u5e94\u7528\u7a0b\u5e8f\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getapplicationinfo","title":"getApplicationInfo()","text":"

    \u83b7\u53d6\u5e94\u7528\u4fe1\u606f\u3002

    getApplicationInfo(packageName=None)\n

    \u53c2\u6570\uff1a - packageName (str): \u5305\u540d\uff08None = \u5f53\u524d\u5e94\u7528\uff09

    \u8fd4\u56de\uff1a \u5e94\u7528\u4fe1\u606f\u5b57\u5178

    "},{"location":"qsl4a/system/application/#getinstalledpackages","title":"getInstalledPackages()","text":"

    \u83b7\u53d6\u5df2\u5b89\u88c5\u5305\u5217\u8868\u3002

    getInstalledPackages(flag=4)\n

    \u53c2\u6570\uff1a - flag (int): \u5305\u6807\u5fd7\u8fc7\u6ee4\u5668\uff08\u9ed8\u8ba4\uff1a4\uff09

    \u8fd4\u56de\uff1a \u5df2\u5b89\u88c5\u5305\u5217\u8868

    "},{"location":"qsl4a/system/application/#getrunningpackages","title":"getRunningPackages()","text":"

    \u5217\u51fa\u6b63\u5728\u8fd0\u884c\u7684\u5305\u3002

    getRunningPackages()\n

    \u8fd4\u56de\uff1a \u5305\u540d\u5217\u8868

    "},{"location":"qsl4a/system/application/#getlaunchablepackages","title":"getLaunchablePackages()","text":"

    \u83b7\u53d6\u53ef\u542f\u52a8\u5305\u5217\u8868\u3002

    getLaunchablePackages(needClassName=False)\n

    \u53c2\u6570\uff1a - needClassName (bool): \u5305\u542b\u4e3b activity \u7c7b\u540d\uff08\u9ed8\u8ba4\uff1aFalse\uff09

    \u8fd4\u56de\uff1a \u53ef\u542f\u52a8\u5305\u540d\u5217\u8868\u6216\u5305\u542b\u7c7b\u540d\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/application/#_3","title":"\u5e94\u7528\u63a7\u5236","text":""},{"location":"qsl4a/system/application/#launch","title":"launch()","text":"

    \u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u3002

    launch(classname=None, packagename=None, wait=True)\n

    \u53c2\u6570\uff1a - classname (str): \u4e3b activity \u7c7b\u540d - packagename (str): \u5305\u540d - wait (bool): \u7b49\u5f85\u542f\u52a8\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

    \u8fd4\u56de\uff1a \u542f\u52a8\u7ed3\u679c

    "},{"location":"qsl4a/system/application/#forcestoppackage","title":"forceStopPackage()","text":"

    \u5f3a\u5236\u505c\u6b62\u5e94\u7528\u7a0b\u5e8f\u3002

    forceStopPackage(packageName)\n

    \u53c2\u6570\uff1a - packageName (str): \u8981\u505c\u6b62\u7684\u5305\u540d

    "},{"location":"qsl4a/system/application/#_4","title":"\u7248\u672c\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getpackageversion","title":"getPackageVersion()","text":"

    \u83b7\u53d6\u5e94\u7528\u7248\u672c\u540d\u79f0\u3002

    getPackageVersion(packageName)\n

    \u8fd4\u56de\uff1a \u7248\u672c\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"3.2.1\"\uff09

    "},{"location":"qsl4a/system/application/#getpackageversioncode","title":"getPackageVersionCode()","text":"

    \u83b7\u53d6\u5e94\u7528\u7248\u672c\u4ee3\u7801\u3002

    getPackageVersionCode(packageName)\n

    \u8fd4\u56de\uff1a \u7248\u672c\u4ee3\u7801\u6574\u6570

    "},{"location":"qsl4a/system/application/#getconstants","title":"getConstants()","text":"

    \u83b7\u53d6\u7c7b\u5e38\u91cf\u3002

    getConstants(classname)\n

    \u53c2\u6570\uff1a - classname (str): \u5b8c\u6574\u7c7b\u540d

    \u8fd4\u56de\uff1a \u5e38\u91cf\u540d\u548c\u503c\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/application/#_5","title":"\u7cfb\u7edf\u529f\u80fd","text":""},{"location":"qsl4a/system/application/#backgroundprotect","title":"backgroundProtect()","text":"

    \u542f\u7528\u6216\u7981\u7528\u5e94\u7528\u7684\u540e\u53f0\u4fdd\u62a4\u3002

    backgroundProtect(enabled=True)\n

    \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\u4fdd\u62a4\uff0cFalse \u7981\u7528

    "},{"location":"qsl4a/system/application/#createscriptshortcut","title":"createScriptShortCut()","text":"

    \u4e3a\u811a\u672c\u521b\u5efa\u4e3b\u5c4f\u5e55\u5feb\u6377\u65b9\u5f0f\u3002

    createScriptShortCut(scriptPath, label=None, iconPath=None, scriptArg=None)\n

    \u53c2\u6570\uff1a - scriptPath (str): Python \u811a\u672c\u8def\u5f84 - label (str, optional): \u5feb\u6377\u65b9\u5f0f\u6807\u7b7e - iconPath (str, optional): \u56fe\u6807\u56fe\u50cf\u8def\u5f84 - scriptArg (str, optional): \u4f20\u9012\u7ed9\u811a\u672c\u7684\u53c2\u6570

    "},{"location":"qsl4a/system/application/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getandroidid","title":"getAndroidID()","text":"

    \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

    getAndroidID()\n

    \u8fd4\u56de\uff1a \u552f\u4e00\u7684 Android \u8bbe\u5907 ID \u5b57\u7b26\u4e32

    "},{"location":"qsl4a/system/application/#getsysinfo","title":"getSysInfo()","text":"

    \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\u3002

    getSysInfo()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/application/#getlocale","title":"getLocale()","text":"

    \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u3002

    getLocale()\n

    \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

    "},{"location":"qsl4a/system/application/#getharmonyosinformation","title":"getHarmonyOsInformation()","text":"

    \u5982\u679c\u5728 HarmonyOS \u4e0a\u8fd0\u884c\uff0c\u83b7\u53d6 HarmonyOS \u4fe1\u606f\u3002

    getHarmonyOsInformation()\n

    \u8fd4\u56de\uff1a HarmonyOS \u7248\u672c\u4fe1\u606f\u6216 None

    "},{"location":"qsl4a/system/application/#isexternalstoragemanager","title":"isExternalStorageManager()","text":"

    \u68c0\u67e5\u5e94\u7528\u662f\u5426\u6709\u5916\u90e8\u5b58\u50a8\u7ba1\u7406\u5668\u6743\u9650\u3002

    isExternalStorageManager()\n

    \u8fd4\u56de\uff1a \u5982\u679c\u6709\u6743\u9650\u5219\u4e3a True

    "},{"location":"qsl4a/system/application/#_7","title":"\u5185\u5b58\u548c\u663e\u793a","text":""},{"location":"qsl4a/system/application/#getmemoryinfo","title":"getMemoryInfo()","text":"

    \u83b7\u53d6\u5185\u5b58\u4fe1\u606f\u3002

    getMemoryInfo()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/application/#getscreeninfo","title":"getScreenInfo()","text":"

    \u83b7\u53d6\u5c4f\u5e55\u4fe1\u606f\u3002

    getScreenInfo()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/application/#_8","title":"\u6743\u9650","text":""},{"location":"qsl4a/system/application/#checkpermissions","title":"checkPermissions()","text":"

    \u68c0\u67e5\u5f53\u524d\u5e94\u7528\u6743\u9650\u3002

    checkPermissions()\n

    \u8fd4\u56de\uff1a \u6743\u9650\u53ca\u5176\u72b6\u6001\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/application/#requestpermissions","title":"requestPermissions()","text":"

    \u5411\u7528\u6237\u8bf7\u6c42\u6743\u9650\u3002

    requestPermissions(permissions=None)\n

    \u53c2\u6570\uff1a - permissions (list, optional): \u8981\u8bf7\u6c42\u7684\u6743\u9650\u5217\u8868\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8bf7\u6c42\u6240\u6709\u9700\u8981\u7684\u6743\u9650\u3002

    \u8fd4\u56de\uff1a \u6743\u9650\u8bf7\u6c42\u7ed3\u679c

    "},{"location":"qsl4a/system/application/#_9","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/system/application/#showscreenlock","title":"showScreenLock()","text":"

    \u663e\u793a\u5c4f\u5e55\u9501\u5b9a\uff08PIN/\u56fe\u6848/\u5bc6\u7801\u8f93\u5165\uff09\u3002

    showScreenLock()\n
    "},{"location":"qsl4a/system/application/#_10","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\ninfo = droid.getSysInfo().result\nprint(f\"System: {info}\")\n\n# \u83b7\u53d6\u5e94\u7528\u7248\u672c\nversion = droid.getPackageVersion(\"org.qpython.qpy\").result\nprint(f\"QPython version: {version}\")\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u5e94\u7528\napps = droid.getInstalledPackages().result\nprint(f\"Installed apps: {len(apps)}\")\n\n# \u542f\u52a8\u5e94\u7528\ndroid.launch(packagename=\"com.android.settings\")\n\n# \u68c0\u67e5\u6743\u9650\nperms = droid.checkPermissions().result\nprint(f\"Permissions: {perms}\")\n\n# \u8bf7\u6c42\u5b58\u50a8\u6743\u9650\ndroid.requestPermissions([\"android.permission.READ_EXTERNAL_STORAGE\"])\n\n# \u521b\u5efa\u5feb\u6377\u65b9\u5f0f\ndroid.createScriptShortCut(\n    \"/sdcard/my_script.py\",\n    label=\"My Script\",\n    iconPath=\"/sdcard/icon.png\"\n)\n
    "},{"location":"qsl4a/system/battery/","title":"\u7535\u6c60 API","text":"

    \u76d1\u63a7\u8bbe\u5907\u7535\u6c60\u72b6\u6001\u548c\u5065\u5eb7\u72b6\u51b5\u3002

    "},{"location":"qsl4a/system/battery/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/battery/#readbatterydata","title":"readBatteryData()","text":"

    \u83b7\u53d6\u5b8c\u6574\u7684\u7535\u6c60\u4fe1\u606f\u3002

    readBatteryData()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u7535\u6c60\u6570\u636e\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/battery/#batterystartmonitoring","title":"batteryStartMonitoring()","text":"

    \u5f00\u59cb\u7535\u6c60\u76d1\u63a7\u3002

    batteryStartMonitoring()\n
    "},{"location":"qsl4a/system/battery/#batterystopmonitoring","title":"batteryStopMonitoring()","text":"

    \u505c\u6b62\u7535\u6c60\u76d1\u63a7\u3002

    batteryStopMonitoring()\n
    "},{"location":"qsl4a/system/battery/#batterygetlevel","title":"batteryGetLevel()","text":"

    \u83b7\u53d6\u7535\u6c60\u767e\u5206\u6bd4\u3002

    batteryGetLevel()\n

    \u8fd4\u56de\uff1a \u6574\u6570\uff080-100\uff09

    "},{"location":"qsl4a/system/battery/#batterygetstatus","title":"batteryGetStatus()","text":"

    \u83b7\u53d6\u5145\u7535\u72b6\u6001\u3002

    batteryGetStatus()\n

    \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u5145\u7535\u4e2d - 3: \u653e\u7535\u4e2d - 4: \u672a\u5145\u7535 - 5: \u5df2\u5145\u6ee1

    "},{"location":"qsl4a/system/battery/#batterygetplugtype","title":"batteryGetPlugType()","text":"

    \u83b7\u53d6\u7535\u6e90\u7c7b\u578b\u3002

    batteryGetPlugType()\n

    \u8fd4\u56de\uff1a - -1: \u672a\u77e5 - 0: \u672a\u63d2\u7535 - 1: AC \u5145\u7535\u5668 - 2: USB \u7aef\u53e3

    "},{"location":"qsl4a/system/battery/#batterygethealth","title":"batteryGetHealth()","text":"

    \u83b7\u53d6\u7535\u6c60\u5065\u5eb7\u72b6\u51b5\u3002

    batteryGetHealth()\n

    \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u826f\u597d - 3: \u8fc7\u70ed - 4: \u635f\u574f - 5: \u8fc7\u538b - 6: \u672a\u6307\u5b9a\u7684\u6545\u969c

    "},{"location":"qsl4a/system/battery/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\nlevel = droid.batteryGetLevel().result\nprint(f\"Battery: {level}%\")\n
    "},{"location":"qsl4a/system/qpyinterface/","title":"QPython \u63a5\u53e3 API","text":"

    \u4ece\u5176\u4ed6\u5e94\u7528\u6267\u884c QPython \u811a\u672c\u548c\u7ba1\u7406\u5171\u4eab\u53d8\u91cf\u3002

    "},{"location":"qsl4a/system/qpyinterface/#_1","title":"\u811a\u672c\u6267\u884c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/qpyinterface/#executeqpy","title":"executeQPy()","text":"

    \u6267\u884c QPython \u811a\u672c\u3002

    executeQPy(path=\"\", arg=None)\n

    \u53c2\u6570\uff1a - path (str): \u811a\u672c\u6587\u4ef6\u8def\u5f84 - arg (str, optional): \u547d\u4ee4\u884c\u53c2\u6570

    \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/system/qpyinterface/#executeqpyassrv","title":"executeQPyAsSrv()","text":"

    \u4f5c\u4e3a\u670d\u52a1\u6267\u884c QPython \u811a\u672c\u3002

    executeQPyAsSrv(path=None)\n

    \u53c2\u6570\uff1a - path (str, optional): \u811a\u672c\u6587\u4ef6\u8def\u5f84

    \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/system/qpyinterface/#executeqpycode","title":"executeQPyCode()","text":"

    \u76f4\u63a5\u6267\u884c Python \u4ee3\u7801\u3002

    executeQPyCode(code=None)\n

    \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

    \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/system/qpyinterface/#executeqpycodeassrv","title":"executeQPyCodeAsSrv()","text":"

    \u4f5c\u4e3a\u670d\u52a1\u6267\u884c Python \u4ee3\u7801\u3002

    executeQPyCodeAsSrv(code=None)\n

    \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

    \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/system/qpyinterface/#_2","title":"\u5171\u4eab\u53d8\u91cf","text":"

    \u5171\u4eab\u53d8\u91cf\u5141\u8bb8 QPython \u4e0e\u5176\u4ed6\u5e94\u7528\u4e4b\u95f4\u8fdb\u884c\u901a\u4fe1\u3002

    "},{"location":"qsl4a/system/qpyinterface/#sharedvariableset","title":"sharedVariableSet()","text":"

    \u8bbe\u7f6e Java \u5171\u4eab\u53d8\u91cf\u3002

    sharedVariableSet(key, value)\n

    \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d - value (str): \u53d8\u91cf\u503c

    \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

    "},{"location":"qsl4a/system/qpyinterface/#sharedvariableget","title":"sharedVariableGet()","text":"

    \u83b7\u53d6 Java \u5171\u4eab\u53d8\u91cf\u3002

    sharedVariableGet(key)\n

    \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d

    \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

    "},{"location":"qsl4a/system/qpyinterface/#sharedvariableremove","title":"sharedVariableRemove()","text":"

    \u79fb\u9664 Java \u5171\u4eab\u53d8\u91cf\u3002

    sharedVariableRemove(key)\n

    \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u53d8\u91cf\u540d

    \u8fd4\u56de\uff1a \u88ab\u79fb\u9664\u7684\u503c

    "},{"location":"qsl4a/system/qpyinterface/#getlastlog","title":"getLastLog()","text":"

    \u83b7\u53d6 QPython \u7684\u6700\u540e\u65e5\u5fd7\u8f93\u51fa\u3002

    getLastLog()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u65e5\u5fd7\u5185\u5bb9

    "},{"location":"qsl4a/system/qpyinterface/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c\u811a\u672c\ndroid.executeQPy(\"/sdcard/my_script.py\", arg=\"test\")\n\n# \u76f4\u63a5\u6267\u884c\u4ee3\u7801\ncode = \"print('Hello from QPython!')\"\ndroid.executeQPyCode(code)\n\n# \u4f7f\u7528\u5171\u4eab\u53d8\u91cf\ndroid.sharedVariableSet(\"username\", \"alice\")\nusername = droid.sharedVariableGet(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u79fb\u9664\u53d8\u91cf\ndroid.sharedVariableRemove(\"username\")\n\n# \u83b7\u53d6\u6700\u8fd1\u65e5\u5fd7\nlog = droid.getLastLog().result\nprint(f\"Log: {log}\")\n
    "},{"location":"qsl4a/system/sensors/","title":"\u4f20\u611f\u5668 API","text":"

    \u8bbf\u95ee\u8bbe\u5907\u4f20\u611f\u5668\uff0c\u5305\u62ec\u52a0\u901f\u5ea6\u8ba1\u3001\u9640\u87ba\u4eea\u3001\u78c1\u529b\u8ba1\u7b49\u3002

    "},{"location":"qsl4a/system/sensors/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/sensors/#startsensingtimed","title":"startSensingTimed()","text":"

    \u5f00\u59cb\u4f20\u611f\u5668\u76d1\u63a7\u5e76\u8bbe\u7f6e\u65f6\u95f4\u95f4\u9694\u3002

    startSensingTimed(sensorNumber, delayTime)\n

    \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID\uff08\u901a\u5e38\u4e3a 1-3\uff09 - delayTime (int): \u8bfb\u53d6\u4e4b\u95f4\u7684\u5ef6\u8fdf\uff08\u6beb\u79d2\uff09

    "},{"location":"qsl4a/system/sensors/#startsensingthreshold","title":"startSensingThreshold()","text":"

    \u5f00\u59cb\u5e26\u9608\u503c\u89e6\u53d1\u7684\u4f20\u611f\u5668\u76d1\u63a7\u3002

    startSensingThreshold(sensorNumber, threshold, axis)\n

    \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID - threshold (float): \u89e6\u53d1\u9608\u503c - axis (int): \u8981\u76d1\u63a7\u7684\u8f74\uff080=X\uff0c1=Y\uff0c2=Z\uff09

    "},{"location":"qsl4a/system/sensors/#stopsensing","title":"stopSensing()","text":"

    \u505c\u6b62\u6240\u6709\u4f20\u611f\u5668\u76d1\u63a7\u3002

    stopSensing()\n
    "},{"location":"qsl4a/system/sensors/#readsensors","title":"readSensors()","text":"

    \u8bfb\u53d6\u5f53\u524d\u4f20\u611f\u5668\u6570\u636e\u3002

    readSensors()\n

    \u8fd4\u56de\uff1a \u4f20\u611f\u5668\u6570\u636e\u5b57\u5178

    "},{"location":"qsl4a/system/sensors/#sensorsreadaccelerometer","title":"sensorsReadAccelerometer()","text":"

    \u8bfb\u53d6\u52a0\u901f\u5ea6\u8ba1\u503c\u3002

    sensorsReadAccelerometer()\n

    \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d m/s\u00b2

    "},{"location":"qsl4a/system/sensors/#sensorsreadgyroscope","title":"sensorsReadGyroscope()","text":"

    \u8bfb\u53d6\u9640\u87ba\u4eea\u503c\u3002

    sensorsReadGyroscope()\n

    \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d rad/s

    "},{"location":"qsl4a/system/sensors/#sensorsreadmagnetometer","title":"sensorsReadMagnetometer()","text":"

    \u8bfb\u53d6\u78c1\u573a\u503c\u3002

    sensorsReadMagnetometer()\n

    \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d \u03bcT

    "},{"location":"qsl4a/system/sensors/#sensorsreadorientation","title":"sensorsReadOrientation()","text":"

    \u8bfb\u53d6\u8bbe\u5907\u65b9\u5411\u3002

    sensorsReadOrientation()\n

    \u8fd4\u56de\uff1a \u5217\u8868 [azimuth, pitch, roll]\uff0c\u5355\u4f4d\u5ea6

    "},{"location":"qsl4a/system/sensors/#sensorsgetlight","title":"sensorsGetLight()","text":"

    \u8bfb\u53d6\u5149\u4f20\u611f\u5668\u503c\u3002

    sensorsGetLight()\n

    \u8fd4\u56de\uff1a \u5149\u7ea7\u522b\uff08lux\uff09

    "},{"location":"qsl4a/system/sensors/#sensorsgetstepcounter","title":"sensorsGetStepCounter()","text":"

    \u8bfb\u53d6\u6b65\u8ba1\u6570\u5668\u3002

    sensorsGetStepCounter()\n

    \u8fd4\u56de\uff1a \u6b65\u6570

    "},{"location":"qsl4a/system/sensors/#sensorsgetaccuracy","title":"sensorsGetAccuracy()","text":"

    \u83b7\u53d6\u5f53\u524d\u4f20\u611f\u5668\u7cbe\u5ea6\u3002

    sensorsGetAccuracy()\n

    \u8fd4\u56de\uff1a \u7cbe\u5ea6\u503c\uff080-3\uff1aUNRELIABLE\u3001ACCURACY_LOW\u3001ACCURACY_MEDIUM\u3001ACCURACY_HIGH\uff09

    "},{"location":"qsl4a/system/sensors/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u8bfb\u53d6\u4f20\u611f\u5668 10 \u6b21\nfor i in range(10):\n    accel = droid.sensorsReadAccelerometer().result\n    print(f\"Accel: X={accel[0]:.2f}, Y={accel[1]:.2f}, Z={accel[2]:.2f}\")\n    time.sleep(0.5)\n\ndroid.stopSensing()\n
    "},{"location":"qsl4a/system/settings/","title":"\u8bbe\u7f6e API","text":"

    \u63a7\u5236\u7cfb\u7edf\u8bbe\u7f6e\uff0c\u5305\u62ec\u5c4f\u5e55\u3001\u58f0\u97f3\u548c\u7f51\u7edc\u8bbe\u7f6e\u3002

    "},{"location":"qsl4a/system/settings/#_1","title":"\u5c4f\u5e55\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#setscreentimeout","title":"setScreenTimeout()","text":"

    \u8bbe\u7f6e\u5c4f\u5e55\u8d85\u65f6\u503c\u3002

    setScreenTimeout(value)\n

    \u53c2\u6570\uff1a - value (int): \u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

    \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u8d85\u65f6\u503c

    "},{"location":"qsl4a/system/settings/#getscreentimeout","title":"getScreenTimeout()","text":"

    \u83b7\u53d6\u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u3002

    getScreenTimeout()\n

    \u8fd4\u56de\uff1a \u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

    "},{"location":"qsl4a/system/settings/#getscreenbrightness","title":"getScreenBrightness()","text":"

    \u83b7\u53d6\u5c4f\u5e55\u4eae\u5ea6\u503c\u3002

    getScreenBrightness()\n

    \u8fd4\u56de\uff1a \u4eae\u5ea6\u503c\uff080-255\uff09

    "},{"location":"qsl4a/system/settings/#setscreenbrightness","title":"setScreenBrightness()","text":"

    \u8bbe\u7f6e\u5c4f\u5e55\u4eae\u5ea6\u3002

    setScreenBrightness(value=None)\n

    \u53c2\u6570\uff1a - value (int, optional): \u4eae\u5ea6\u503c\uff080-255\uff09\uff0c\u6216 None \u8868\u793a\u81ea\u52a8

    \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u4eae\u5ea6\u503c

    "},{"location":"qsl4a/system/settings/#checkscreenon","title":"checkScreenOn()","text":"

    \u68c0\u67e5\u5c4f\u5e55\u662f\u5426\u4eae\u7740\u3002

    checkScreenOn()\n

    \u8fd4\u56de\uff1a \u5982\u679c\u5c4f\u5e55\u4eae\u7740\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

    "},{"location":"qsl4a/system/settings/#_2","title":"\u98de\u884c\u6a21\u5f0f","text":""},{"location":"qsl4a/system/settings/#checkairplanemode","title":"checkAirplaneMode()","text":"

    \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\u662f\u5426\u542f\u7528\u3002

    checkAirplaneMode()\n

    \u8fd4\u56de\uff1a \u5982\u679c\u98de\u884c\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

    "},{"location":"qsl4a/system/settings/#_3","title":"\u94c3\u58f0\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#checkringersilentmode","title":"checkRingerSilentMode()","text":"

    \u68c0\u67e5\u94c3\u58f0\u662f\u5426\u5904\u4e8e\u9759\u97f3\u6a21\u5f0f\u3002

    checkRingerSilentMode()\n

    \u8fd4\u56de\uff1a \u5982\u679c\u9759\u97f3\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

    "},{"location":"qsl4a/system/settings/#toggleringersilentmode","title":"toggleRingerSilentMode()","text":"

    \u5207\u6362\u94c3\u58f0\u9759\u97f3\u6a21\u5f0f\u3002

    toggleRingerSilentMode(enabled=None)\n

    \u53c2\u6570\uff1a - enabled (bool, optional): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

    \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

    "},{"location":"qsl4a/system/settings/#togglevibratemode","title":"toggleVibrateMode()","text":"

    \u5207\u6362\u632f\u52a8\u6a21\u5f0f\u3002

    toggleVibrateMode(enabled=None, ringer=None)\n

    \u53c2\u6570\uff1a - enabled (bool, optional): \u5207\u6362\u632f\u52a8\u5f00/\u5173 - ringer (bool, optional): \u5e94\u7528\u4e8e\u94c3\u58f0\u6a21\u5f0f

    \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

    "},{"location":"qsl4a/system/settings/#getvibratemode","title":"getVibrateMode()","text":"

    \u83b7\u53d6\u632f\u52a8\u6a21\u5f0f\u8bbe\u7f6e\u3002

    getVibrateMode(ringer=None)\n

    \u53c2\u6570\uff1a - ringer (bool, optional): \u68c0\u67e5\u94c3\u58f0\u632f\u52a8\u6a21\u5f0f

    \u8fd4\u56de\uff1a \u5982\u679c\u632f\u52a8\u5df2\u542f\u7528\u5219\u4e3a True

    "},{"location":"qsl4a/system/settings/#_4","title":"\u97f3\u91cf\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#getringervolume","title":"getRingerVolume()","text":"

    \u83b7\u53d6\u5f53\u524d\u94c3\u58f0\u97f3\u91cf\u3002

    getRingerVolume()\n

    \u8fd4\u56de\uff1a \u94c3\u58f0\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-7\uff09

    "},{"location":"qsl4a/system/settings/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

    \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

    getMaxRingerVolume()\n

    \u8fd4\u56de\uff1a \u6700\u5927\u94c3\u58f0\u97f3\u91cf

    "},{"location":"qsl4a/system/settings/#setringervolume","title":"setRingerVolume()","text":"

    \u8bbe\u7f6e\u94c3\u58f0\u97f3\u91cf\u3002

    setRingerVolume(volume)\n

    \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

    "},{"location":"qsl4a/system/settings/#getmediavolume","title":"getMediaVolume()","text":"

    \u83b7\u53d6\u5f53\u524d\u5a92\u4f53\u97f3\u91cf\u3002

    getMediaVolume()\n

    \u8fd4\u56de\uff1a \u5a92\u4f53\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-15\uff09

    "},{"location":"qsl4a/system/settings/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

    \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

    getMaxMediaVolume()\n

    \u8fd4\u56de\uff1a \u6700\u5927\u5a92\u4f53\u97f3\u91cf

    "},{"location":"qsl4a/system/settings/#setmediavolume","title":"setMediaVolume()","text":"

    \u8bbe\u7f6e\u5a92\u4f53\u97f3\u91cf\u3002

    setMediaVolume(volume)\n

    \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

    "},{"location":"qsl4a/system/settings/#_5","title":"\u7cfb\u7edf\u4fe1\u606f","text":""},{"location":"qsl4a/system/settings/#elapsedrealtimenanos","title":"elapsedRealtimeNanos()","text":"

    \u83b7\u53d6\u81ea\u7cfb\u7edf\u542f\u52a8\u4ee5\u6765\u7684\u7eb3\u79d2\u6570\u3002

    elapsedRealtimeNanos()\n

    \u8fd4\u56de\uff1a \u7eb3\u79d2\u6570\uff08\u53ef\u7528\u4e8e\u8ba1\u65f6\uff09

    "},{"location":"qsl4a/system/settings/#gettrafficstats","title":"getTrafficStats()","text":"

    \u83b7\u53d6\u7f51\u7edc\u6d41\u91cf\u7edf\u8ba1\u3002

    getTrafficStats(flags=7)\n

    \u53c2\u6570\uff1a - flags (int): \u8981\u68c0\u7d22\u7684\u7edf\u8ba1\uff08\u9ed8\u8ba4\uff1a7 = \u5168\u90e8\uff09

    \u8fd4\u56de\uff1a \u5305\u542b\u53d1\u9001/\u63a5\u6536\u5b57\u8282\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/settings/#getapptxbytes","title":"getAppTxBytes()","text":"

    \u83b7\u53d6 QPython \u5e94\u7528\u7684\u53d1\u9001\u5b57\u8282\u3002

    getAppTxBytes(packageName)\n

    \u53c2\u6570\uff1a - packageName (str): \u5305\u540d

    \u8fd4\u56de\uff1a \u5305\u542b tx/rx \u5b57\u8282\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/settings/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5c4f\u5e55\u8bbe\u7f6e\ncurrent_timeout = droid.getScreenTimeout().result\nprint(f\"Current timeout: {current_timeout}s\")\ndroid.setScreenTimeout(30)\n\n# \u68c0\u67e5\u5c4f\u5e55\nif droid.checkScreenOn().result:\n    print(\"Screen is on\")\n\n# \u97f3\u91cf\u63a7\u5236\nmedia_vol = droid.getMediaVolume().result\nprint(f\"Media volume: {media_vol}\")\ndroid.setMediaVolume(10)\n\n# \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\nif droid.checkAirplaneMode().result:\n    print(\"Airplane mode is on\")\n
    "},{"location":"qsl4a/system/sysinfo/","title":"\u7cfb\u7edf\u4fe1\u606f","text":"

    \u68c0\u7d22\u8bbe\u5907\u548c\u7cfb\u7edf\u4fe1\u606f\u3002

    "},{"location":"qsl4a/system/sysinfo/#_2","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/sysinfo/#getandroidid","title":"getAndroidID()","text":"

    \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

    getAndroidID()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

    "},{"location":"qsl4a/system/sysinfo/#getsysinfo","title":"getSysInfo()","text":"

    \u83b7\u53d6\u7efc\u5408\u7cfb\u7edf\u4fe1\u606f\u3002

    getSysInfo()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/sysinfo/#getlocale","title":"getLocale()","text":"

    \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u8bbe\u7f6e\u3002

    getLocale()\n

    \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

    "},{"location":"qsl4a/system/sysinfo/#_3","title":"\u5185\u5b58","text":""},{"location":"qsl4a/system/sysinfo/#getmemoryinfo","title":"getMemoryInfo()","text":"

    \u83b7\u53d6 RAM \u4fe1\u606f\u3002

    getMemoryInfo()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/sysinfo/#_4","title":"\u663e\u793a","text":""},{"location":"qsl4a/system/sysinfo/#getscreeninfo","title":"getScreenInfo()","text":"

    \u83b7\u53d6\u663e\u793a\u4fe1\u606f\u3002

    getScreenInfo()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/sysinfo/#_5","title":"\u6807\u8bc6\u7b26","text":""},{"location":"qsl4a/system/sysinfo/#getimei","title":"getImei()","text":"

    \u83b7\u53d6\u8bbe\u5907 IMEI\u3002

    getImei(slotIndex=None)\n
    "},{"location":"qsl4a/system/sysinfo/#getmeid","title":"getMeid()","text":"

    \u83b7\u53d6\u8bbe\u5907 MEID\u3002

    getMeid(slotIndex=None)\n
    "},{"location":"qsl4a/system/sysinfo/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u8bbe\u5907 ID\nandroid_id = droid.getAndroidID().result\nprint(f\"Android ID: {android_id}\")\n\n# \u5c4f\u5e55\u4fe1\u606f\nscreen = droid.getScreenInfo().result\nprint(f\"Screen: {screen['width']}x{screen['height']}\")\n\n# \u5185\u5b58\nmemory = droid.getMemoryInfo().result\nprint(f\"Memory: {memory}\")\n
    "},{"location":"qsl4a/system/wakelock/","title":"WakeLock API","text":"

    \u63a7\u5236\u8bbe\u5907\u5524\u9192\u9501\u4ee5\u4fdd\u6301 CPU \u6216\u5c4f\u5e55\u5f00\u542f\u3002

    "},{"location":"qsl4a/system/wakelock/#wake-lock","title":"Wake Lock \u7c7b\u578b","text":"

    QSL4A \u63d0\u4f9b\u4e0d\u540c\u7c7b\u578b\u7684\u5524\u9192\u9501\uff1a

    \u7c7b\u578b \u63cf\u8ff0 Full CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae Partial \u4ec5 CPU \u5f00\u542f Bright CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae Dim CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697"},{"location":"qsl4a/system/wakelock/#wake-lock_1","title":"Wake Lock \u65b9\u6cd5","text":""},{"location":"qsl4a/system/wakelock/#wakelockacquirefull","title":"wakeLockAcquireFull()","text":"

    \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae\uff09\u3002

    wakeLockAcquireFull()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockacquirepartial","title":"wakeLockAcquirePartial()","text":"

    \u83b7\u53d6\u90e8\u5206\u5524\u9192\u9501\uff08\u4ec5 CPU \u5f00\u542f\uff09\u3002

    wakeLockAcquirePartial()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockacquirebright","title":"wakeLockAcquireBright()","text":"

    \u83b7\u53d6\u660e\u4eae\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff09\u3002

    wakeLockAcquireBright()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockacquiredim","title":"wakeLockAcquireDim()","text":"

    \u83b7\u53d6\u6697\u6de1\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697\uff09\u3002

    wakeLockAcquireDim()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockrelease","title":"wakeLockRelease()","text":"

    \u91ca\u653e\u5524\u9192\u9501\u3002

    wakeLockRelease()\n
    "},{"location":"qsl4a/system/wakelock/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\ndroid.wakeLockAcquireFull()\n\n# \u5728\u4fdd\u6301\u5c4f\u5e55\u5f00\u542f\u65f6\u6267\u884c\u91cd\u8981\u5de5\u4f5c\nprint(\"Screen will stay on\")\ntime.sleep(10)\n\n# \u5b8c\u6210\u540e\u91ca\u653e\ndroid.wakeLockRelease()\n\n# \u6216\u4f7f\u7528\u90e8\u5206\u9501\u8fdb\u884c\u540e\u53f0\u4efb\u52a1\ndroid.wakeLockAcquirePartial()\n# \u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\uff0cCPU \u4ecd\u4fdd\u6301\u5f00\u542f\ntime.sleep(30)\ndroid.wakeLockRelease()\n

    \u6ce8\u610f\uff1a \u8bb0\u4f4f\u5728\u4e0d\u9700\u8981\u65f6\u91ca\u653e\u5524\u9192\u9501\u4ee5\u8282\u7701\u7535\u6c60\u3002

    "},{"location":"qsl4a/ui/accessibility/","title":"\u65e0\u969c\u788d\u670d\u52a1","text":"

    \u65e0\u969c\u788d\u670d\u52a1\u5141\u8bb8\u81ea\u52a8\u5316 UI \u4ea4\u4e92\uff0c\u5982\u70b9\u51fb\u3001\u6ed1\u52a8\u548c\u7cfb\u7edf\u64cd\u4f5c\u3002

    "},{"location":"qsl4a/ui/accessibility/#_2","title":"\u670d\u52a1\u63a7\u5236","text":""},{"location":"qsl4a/ui/accessibility/#accessibilitystartservice","title":"accessibilityStartService()","text":"

    \u542f\u52a8\u65e0\u969c\u788d\u670d\u52a1\u3002

    accessibilityStartService()\n

    \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

    "},{"location":"qsl4a/ui/accessibility/#accessibilityserviceenabled","title":"accessibilityServiceEnabled()","text":"

    \u68c0\u67e5\u65e0\u969c\u788d\u670d\u52a1\u662f\u5426\u5df2\u542f\u7528\u3002

    accessibilityServiceEnabled()\n

    \u8fd4\u56de\uff1a True \u6216 False

    "},{"location":"qsl4a/ui/accessibility/#_3","title":"\u5c4f\u5e55\u4ea4\u4e92","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityclick","title":"accessibilityClick()","text":"

    \u5728\u5c4f\u5e55\u5750\u6807\u5904\u70b9\u51fb\u3002

    accessibilityClick(x=0, y=0, t=50)\n

    \u53c2\u6570\uff1a - x (int/float): X \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - y (int/float): Y \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - t (int): \u6309\u4f4f\u65f6\u957f\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a50\uff09

    "},{"location":"qsl4a/ui/accessibility/#accessibilityslide","title":"accessibilitySlide()","text":"

    \u591a\u70b9\u6ed1\u52a8\u624b\u52bf\u3002

    accessibilitySlide(XnYn=None, t=None)\n

    \u53c2\u6570\uff1a - XnYn (list): \u5750\u6807 [X1, Y1, X2, Y2, ... Xn, Yn] - t (int): \u6ed1\u52a8\u65f6\u957f\uff08\u9ed8\u8ba4\uff1a50*n \u6beb\u79d2\uff09

    "},{"location":"qsl4a/ui/accessibility/#_4","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityaction","title":"accessibilityAction()","text":"

    \u6309\u4ee3\u7801\u6267\u884c\u7cfb\u7edf\u64cd\u4f5c\u3002

    accessibilityAction(actionCode)\n

    \u64cd\u4f5c\u4ee3\u7801\uff1a | \u4ee3\u7801 | \u5e38\u91cf | \u63cf\u8ff0 | |------|----------|-------------| | 1 | BACK | \u8fd4\u56de\u6309\u94ae | | 2 | HOME | \u4e3b\u5c4f\u5e55\u6309\u94ae | | 3 | RECENTS | \u6700\u8fd1\u5e94\u7528 | | 4 | NOTIFICATIONS | \u6253\u5f00\u901a\u77e5 | | 5 | QUICK_SETTINGS | \u6253\u5f00\u5feb\u901f\u8bbe\u7f6e | | 6 | POWER_DIALOG | \u7535\u6e90\u83dc\u5355 | | 7 | TOGGLE_SPLIT_SCREEN | \u5206\u5c4f | | 8 | LOCK_SCREEN | \u9501\u5c4f | | 9 | TAKE_SCREENSHOT | \u622a\u56fe | | 10 | KEYCODE_HEADSETHOOK | \u8033\u673a\u6302\u94a9 | | 11-14 | ACCESSIBILITY_ | \u65e0\u969c\u788d\u6309\u94ae | | 15 | DISMISS_NOTIFICATION_SHADE | \u5173\u95ed\u901a\u77e5\u680f | | 16-20 | DPAD_ | \u65b9\u5411\u952e | | 21 | MENU | \u83dc\u5355\u6309\u94ae | | 22 | MEDIA_PLAY_PAUSE | \u64ad\u653e/\u6682\u505c\u5a92\u4f53 |

    "},{"location":"qsl4a/ui/accessibility/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/accessibility/#_6","title":"\u70b9\u51fb\u5c4f\u5e55\u4e2d\u5fc3","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u670d\u52a1\nif not droid.accessibilityServiceEnabled().result:\n    droid.accessibilityStartService()\n\n# \u70b9\u51fb\u4e2d\u5fc3\uff080,0 = \u4e2d\u5fc3\uff09\ndroid.accessibilityClick(0, 0, t=100)\n
    "},{"location":"qsl4a/ui/accessibility/#_7","title":"\u6ed1\u52a8\u624b\u52bf","text":"
    # \u4ece\u4e0b\u5f80\u4e0a\u6ed1\u52a8\uff08\u5411\u4e0a\u6eda\u52a8\uff09\ndroid.accessibilitySlide([0, 1.5, 0, -1.5], t=300)\n
    "},{"location":"qsl4a/ui/accessibility/#_8","title":"\u7cfb\u7edf\u5bfc\u822a","text":"
    # \u6309\u4e3b\u5c4f\u5e55\ndroid.accessibilityAction(2)\n\n# \u6309\u8fd4\u56de\ndroid.accessibilityAction(1)\n\n# \u6253\u5f00\u901a\u77e5\ndroid.accessibilityAction(4)\n
    "},{"location":"qsl4a/ui/accessibility/#_9","title":"\u70b9\u51fb\u7279\u5b9a\u4f4d\u7f6e","text":"
    # \u70b9\u51fb\u5c4f\u5e55\u5750\u6807 (500, 800)\ndroid.accessibilityClick(500, 800)\n\n# \u70b9\u51fb\u76f8\u5bf9\u4f4d\u7f6e\uff08\u6c34\u5e73\u5c45\u4e2d\uff0c\u5782\u76f4 3/4 \u5904\uff09\ndroid.accessibilityClick(0, 1.5)\n
    "},{"location":"qsl4a/ui/dialogs/","title":"\u5bf9\u8bdd\u6846\u7cfb\u7edf","text":"

    QSL4A \u63d0\u4f9b\u5168\u9762\u7684\u5bf9\u8bdd\u6846\u652f\u6301\uff0c\u7528\u4e8e\u7528\u6237\u4ea4\u4e92\uff0c\u5305\u62ec\u8b66\u62a5\u3001\u8f93\u5165\u5bf9\u8bdd\u6846\u3001\u9009\u62e9\u5bf9\u8bdd\u6846\u548c\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

    "},{"location":"qsl4a/ui/dialogs/#_2","title":"\u8b66\u62a5\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowalert","title":"dialogShowAlert()","text":"

    \u663e\u793a\u7b80\u5355\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

    dialogShowAlert(title=\"Alert\", message=\"The message of the alert.\",\n                positiveButtonText=\"OK\", negativeButtonText=None,\n                neutralButtonText=None, messageIsHtml=False)\n

    \u53c2\u6570\uff1a - title (str): \u5bf9\u8bdd\u6846\u6807\u9898 - message (str): \u6d88\u606f\u6587\u672c - positiveButtonText (str): \u80af\u5b9a\u6309\u94ae\u6807\u7b7e - negativeButtonText (str, optional): \u5426\u5b9a\u6309\u94ae\u6807\u7b7e - neutralButtonText (str, optional): \u4e2d\u6027\u6309\u94ae\u6807\u7b7e - messageIsHtml (bool): \u5c06\u6d88\u606f\u89e3\u6790\u4e3a HTML

    \u8fd4\u56de\uff1a \u5305\u542b\u70b9\u51fb\u6309\u94ae\u7684\u7ed3\u679c

    "},{"location":"qsl4a/ui/dialogs/#dialogshowsimplechoice","title":"dialogShowSimpleChoice()","text":"

    \u663e\u793a\u5e26\u6709\u9879\u76ee\u7684\u7b80\u5355\u9009\u62e9\u5bf9\u8bdd\u6846\u3002

    dialogShowSimpleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

    \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868

    \u8fd4\u56de\uff1a \u5305\u542b\u9009\u4e2d\u9879\u76ee\u7684\u7ed3\u679c

    "},{"location":"qsl4a/ui/dialogs/#_3","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialoggetinput","title":"dialogGetInput()","text":"

    \u83b7\u53d6\u7528\u6237\u6587\u672c\u8f93\u5165\u3002

    dialogGetInput(title=\"Value\", message=\"Please enter value:\",\n               defaultText=None, messageIsHtml=False)\n

    \u8fd4\u56de\uff1a \u5305\u542b\u7528\u6237\u8f93\u5165\u6587\u672c\u7684\u7ed3\u679c

    "},{"location":"qsl4a/ui/dialogs/#dialoggetpassword","title":"dialogGetPassword()","text":"

    \u83b7\u53d6\u5bc6\u7801\u8f93\u5165\u3002

    dialogGetPassword(title=\"Password\", message=\"Please enter password:\")\n

    \u8fd4\u56de\uff1a \u5305\u542b\u8f93\u5165\u5bc6\u7801\u7684\u7ed3\u679c

    "},{"location":"qsl4a/ui/dialogs/#dialogcreateinput","title":"dialogCreateInput()","text":"

    \u521b\u5efa\u81ea\u5b9a\u4e49\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

    dialogCreateInput(title=\"Value\", message=\"Please enter value:\",\n                  defaultText=None, inputType=None)\n

    \u53c2\u6570\uff1a - inputType (str): \u8f93\u5165\u7c7b\u578b\uff08\u4f8b\u5982 \"text\"\u3001\"number\"\u3001\"textPassword\"\uff09

    "},{"location":"qsl4a/ui/dialogs/#dialogcreatepassword","title":"dialogCreatePassword()","text":"

    \u521b\u5efa\u5bc6\u7801\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

    dialogCreatePassword(title=\"Password\", message=\"Please enter password:\")\n
    "},{"location":"qsl4a/ui/dialogs/#dialogcreateseekbar","title":"dialogCreateSeekBar()","text":"

    \u521b\u5efa\u6ed1\u5757/\u8fdb\u5ea6\u6761\u5bf9\u8bdd\u6846\u3002

    dialogCreateSeekBar(starting_value=50, maximum_value=100, title=\"\", message=\"\")\n

    \u53c2\u6570\uff1a - starting_value (int): \u521d\u59cb\u503c - maximum_value (int): \u6700\u5927\u503c

    "},{"location":"qsl4a/ui/dialogs/#_4","title":"\u9009\u62e9\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowsinglechoice","title":"dialogShowSingleChoice()","text":"

    \u663e\u793a\u5355\u9009\uff08\u5355\u9009\u6309\u94ae\uff09\u5bf9\u8bdd\u6846\u3002

    dialogShowSingleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, selected=-1, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

    \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (int): \u9ed8\u8ba4\u9009\u4e2d\u7d22\u5f15

    "},{"location":"qsl4a/ui/dialogs/#dialogshowmultichoice","title":"dialogShowMultiChoice()","text":"

    \u663e\u793a\u591a\u9009\uff08\u590d\u9009\u6846\uff09\u5bf9\u8bdd\u6846\u3002

    dialogShowMultiChoice(title=\"Alert\", message=\"The message of the alert.\",\n                      items=None, selected=None, positiveButtonText=\"OK\",\n                      negativeButtonText=None, neutralButtonText=None,\n                      messageIsHtml=False)\n

    \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (list): \u521d\u59cb\u9009\u4e2d\u7d22\u5f15\u5217\u8868

    "},{"location":"qsl4a/ui/dialogs/#dialogsetsinglechoiceitems","title":"dialogSetSingleChoiceItems()","text":"

    \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u5355\u9009\u9879\u76ee\u3002

    dialogSetSingleChoiceItems(items, selected=-1)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetmultichoiceitems","title":"dialogSetMultiChoiceItems()","text":"

    \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u591a\u9009\u9879\u76ee\u3002

    dialogSetMultiChoiceItems(items, selected=None)\n
    "},{"location":"qsl4a/ui/dialogs/#_5","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatespinnerprogress","title":"dialogCreateSpinnerProgress()","text":"

    \u521b\u5efa\u4e0d\u786e\u5b9a\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

    dialogCreateSpinnerProgress(title=None, message=None, maximum_progress=100)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogcreatehorizontalprogress","title":"dialogCreateHorizontalProgress()","text":"

    \u521b\u5efa\u6c34\u5e73\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

    dialogCreateHorizontalProgress(title=None, message=None, maximum_progress=100)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetcurrentprogress","title":"dialogSetCurrentProgress()","text":"

    \u66f4\u65b0\u8fdb\u5ea6\u503c\u3002

    dialogSetCurrentProgress(current)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetmaxprogress","title":"dialogSetMaxProgress()","text":"

    \u8bbe\u7f6e\u6700\u5927\u8fdb\u5ea6\u503c\u3002

    dialogSetMaxProgress(max)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetprogressmessage","title":"dialogSetProgressMessage()","text":"

    \u66f4\u65b0\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u6d88\u606f\u3002

    dialogSetProgressMessage(message)\n
    "},{"location":"qsl4a/ui/dialogs/#_6","title":"\u9009\u62e9\u5668\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatedatepicker","title":"dialogCreateDatePicker()","text":"

    \u521b\u5efa\u65e5\u671f\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

    dialogCreateDatePicker(year=1970, month=1, day=1)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogcreatetimepicker","title":"dialogCreateTimePicker()","text":"

    \u521b\u5efa\u65f6\u95f4\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

    dialogCreateTimePicker(hour=0, minute=0, is24hour=False)\n
    "},{"location":"qsl4a/ui/dialogs/#_7","title":"\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u521b\u5efa","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatealert","title":"dialogCreateAlert()","text":"

    \u521b\u5efa\u81ea\u5b9a\u4e49\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

    dialogCreateAlert(title=None, message=None)\n

    \u521b\u5efa\u4e00\u4e2a\u7a7a\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002\u53ef\u4e0e\u5176\u4ed6 dialogSet* \u51fd\u6570\u4e00\u8d77\u4f7f\u7528\u6765\u81ea\u5b9a\u4e49\u3002

    "},{"location":"qsl4a/ui/dialogs/#dialogsetitems","title":"dialogSetItems()","text":"

    \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u7b80\u5355\u5217\u8868\u9879\u76ee\u3002

    dialogSetItems(items)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetpositivebuttontext","title":"dialogSetPositiveButtonText()","text":"

    \u8bbe\u7f6e\u80af\u5b9a\u6309\u94ae\u6587\u672c\u3002

    dialogSetPositiveButtonText(text)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetnegativebuttontext","title":"dialogSetNegativeButtonText()","text":"

    \u8bbe\u7f6e\u5426\u5b9a\u6309\u94ae\u6587\u672c\u3002

    dialogSetNegativeButtonText(text)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetneutralbuttontext","title":"dialogSetNeutralButtonText()","text":"

    \u8bbe\u7f6e\u4e2d\u6027\u6309\u94ae\u6587\u672c\u3002

    dialogSetNeutralButtonText(text)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetmessageishtml","title":"dialogSetMessageIsHtml()","text":"

    \u8bbe\u7f6e\u6d88\u606f\u662f\u5426\u5e94\u89e3\u6790\u4e3a HTML\u3002

    dialogSetMessageIsHtml(messageIsHtml=True)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogshow","title":"dialogShow()","text":"

    \u663e\u793a\u521b\u5efa\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u3002

    dialogShow()\n
    "},{"location":"qsl4a/ui/dialogs/#_8","title":"\u5bf9\u8bdd\u6846\u63a7\u5236","text":""},{"location":"qsl4a/ui/dialogs/#dialogdismiss","title":"dialogDismiss()","text":"

    \u5173\u95ed\u5f53\u524d\u5bf9\u8bdd\u6846\u3002

    dialogDismiss()\n
    "},{"location":"qsl4a/ui/dialogs/#dialoggetresponse","title":"dialogGetResponse()","text":"

    \u83b7\u53d6\u5bf9\u8bdd\u6846\u54cd\u5e94\u3002

    dialogGetResponse()\n
    "},{"location":"qsl4a/ui/dialogs/#dialoggetselecteditems","title":"dialogGetSelectedItems()","text":"

    \u4ece\u9009\u62e9\u5bf9\u8bdd\u6846\u83b7\u53d6\u9009\u4e2d\u7684\u9879\u76ee\u3002

    dialogGetSelectedItems()\n
    "},{"location":"qsl4a/ui/dialogs/#_9","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/dialogs/#_10","title":"\u7b80\u5355\u8b66\u62a5","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a\u8b66\u62a5\ndroid.dialogShowAlert(\"Warning\", \"This is an important message!\")\n
    "},{"location":"qsl4a/ui/dialogs/#_11","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":"
    # \u83b7\u53d6\u7528\u6237\u8f93\u5165\nresult = droid.dialogGetInput(\"Name\", \"Enter your name:\", \"John\").result\nprint(f\"Hello, {result}!\")\n
    "},{"location":"qsl4a/ui/dialogs/#_12","title":"\u5e26\u6309\u94ae\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846","text":"
    # \u521b\u5efa\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\ndroid.dialogCreateAlert(\"Custom\", \"Choose an option\")\ndroid.dialogSetItems([\"Option 1\", \"Option 2\", \"Option 3\"])\ndroid.dialogShow()\n\n# \u83b7\u53d6\u54cd\u5e94\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response['item']}\")\n
    "},{"location":"qsl4a/ui/dialogs/#_13","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":"
    # \u521b\u5efa\u8fdb\u5ea6\u5bf9\u8bdd\u6846\ndroid.dialogCreateHorizontalProgress(\"Loading\", \"Please wait...\", 100)\ndroid.dialogShow()\n\n# \u66f4\u65b0\u8fdb\u5ea6\nfor i in range(101):\n    droid.dialogSetCurrentProgress(i)\n    time.sleep(0.05)\n\ndroid.dialogDismiss()\n
    "},{"location":"qsl4a/ui/dialogs/#_14","title":"\u65e5\u671f\u9009\u62e9\u5668","text":"
    # \u663e\u793a\u65e5\u671f\u9009\u62e9\u5668\ndroid.dialogCreateDatePicker(2024, 1, 15)\ndroid.dialogShow()\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response}\")\n
    "},{"location":"qsl4a/ui/floatview/","title":"\u6d6e\u52a8\u89c6\u56fe","text":"

    \u6d6e\u52a8\u7a97\u53e3\u652f\u6301\uff0c\u7528\u4e8e\u5728\u5176\u4ed6\u5e94\u7528\u7a0b\u5e8f\u4e0a\u65b9\u4fdd\u6301\u663e\u793a\u7684\u8986\u76d6 UI \u5143\u7d20\u3002

    "},{"location":"qsl4a/ui/floatview/#_2","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/floatview/#floatview","title":"floatView()","text":"

    \u663e\u793a\u6216\u4fee\u6539\u6d6e\u52a8\u89c6\u56fe\u3002

    floatView(Args=None)\n

    \u53c2\u6570\uff1a - Args (dict): \u914d\u7f6e\u5b57\u5178\uff0c\u5305\u542b\u4ee5\u4e0b\u952e\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08-1 \u521b\u5efa\u65b0\u7684\uff0c>=0 \u4fee\u6539\u73b0\u6709\u7684\uff09 - text (str): \u8981\u663e\u793a\u7684\u6587\u672c\u5185\u5bb9 - html (str): HTML \u5185\u5bb9\uff08\u5982\u679c\u7701\u7565 text \u5219\u4f7f\u7528\uff09 - width (int): \u89c6\u56fe\u5bbd\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a300\uff09 - height (int): \u89c6\u56fe\u9ad8\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a150\uff09 - x (int): X \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - y (int): Y \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - backColor (str): ARGB \u5341\u516d\u8fdb\u5236\u80cc\u666f\u8272\uff08\u9ed8\u8ba4\uff1a'7f7f7f7f'\uff09 - textColor (str): ARGB \u5341\u516d\u8fdb\u5236\u6587\u672c\u8272\uff08\u9ed8\u8ba4\uff1a'ff000000'\uff09 - textSize (int): \u6587\u672c\u5927\u5c0f\uff08\u9ed8\u8ba4\uff1a10\uff09 - textAlign (int): \u6587\u672c\u5bf9\u9f50\uff080 = \u7ee7\u627f\uff09 - script (str): \u957f\u6309\u5173\u95ed\u540e\u8fd0\u884c\u7684\u811a\u672c\u8def\u5f84 - arg: \u811a\u672c\u53c2\u6570 - clickRemove (bool): \u542f\u7528\u70b9\u51fb\u79fb\u9664\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - flag (int): \u7a97\u53e3\u6807\u5fd7\uff08\u9ed8\u8ba4\uff1a40 - \u53ef\u89e6\u6478\uff09

    \u8fd4\u56de\uff1a \u5f53\u524d\u94fe\u5217\u8868\u957f\u5ea6

    "},{"location":"qsl4a/ui/floatview/#floatviewcount","title":"floatViewCount()","text":"

    \u83b7\u53d6\u6d3b\u52a8\u6d6e\u52a8\u89c6\u56fe\u7684\u6570\u91cf\u3002

    floatViewCount()\n

    \u8fd4\u56de\uff1a \u6d6e\u52a8\u89c6\u56fe\u6570\u91cf

    "},{"location":"qsl4a/ui/floatview/#floatviewresult","title":"floatViewResult()","text":"

    \u83b7\u53d6\u6d6e\u52a8\u89c6\u56fe\u7684\u7ed3\u679c/\u72b6\u6001\u3002

    floatViewResult(index=-1)\n

    \u53c2\u6570\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1\uff0c\u8fd4\u56de\u6700\u540e\u64cd\u4f5c\u7ed3\u679c\uff09

    \u8fd4\u56de\uff1a \u5305\u542b\u64cd\u4f5c\u8be6\u60c5\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - x, y: \u4f4d\u7f6e - time: \u65f6\u95f4\u6233 - operation: \u64cd\u4f5c\u7c7b\u578b\uff08'initial'\u3001'move' \u7b49\uff09 - index: \u89c6\u56fe\u7d22\u5f15 - removed: \u5982\u679c\u89c6\u56fe\u88ab\u79fb\u9664\u5219\u4e3a True

    "},{"location":"qsl4a/ui/floatview/#floatviewremove","title":"floatViewRemove()","text":"

    \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\u3002

    floatViewRemove(index=-1)\n

    \u53c2\u6570\uff1a - index (int): \u8981\u79fb\u9664\u7684\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1 \u79fb\u9664\u6700\u540e\u4e00\u4e2a\uff09

    \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a 1\uff0c\u5426\u5219\u4e3a 0

    "},{"location":"qsl4a/ui/floatview/#_3","title":"\u5e38\u91cf","text":"
    • floatView.INDEX_NEW = -1 - \u521b\u5efa\u65b0\u7684\u6d6e\u52a8\u89c6\u56fe
    • floatView.FLAG_DEFAULT_TOUCHABLE = 40 - \u9ed8\u8ba4\u53ef\u89e6\u6478\u6807\u5fd7
    • floatView.TEXT_ALIGNMENT_INHERIT = 0
    • floatView.TEXT_ALIGNMENT_CENTER - \u5c45\u4e2d\u6587\u672c\u5bf9\u9f50
    "},{"location":"qsl4a/ui/floatview/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/floatview/#_5","title":"\u57fa\u672c\u6d6e\u52a8\u89c6\u56fe","text":"
    import androidhelper\nfrom androidhelper import Android\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u7b80\u5355\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'index': -1,  # \u521b\u5efa\u65b0\u7684\n    'text': 'Hello World',\n    'width': 400,\n    'height': 300,\n    'x': -300,  # \u4ece\u4e2d\u5fc3\u504f\u79fb\n    'y': -400,\n    'backColor': 'ff0000',  # \u7ea2\u8272\u80cc\u666f\n    'textColor': '0000ff',  # \u84dd\u8272\u6587\u672c\n    'textSize': 16,\n    'textAlign': droid.floatView.TEXT_ALIGNMENT_CENTER\n})\n\n# \u68c0\u67e5\u6570\u91cf\nprint(f\"Float views: {droid.floatViewCount().result}\")\n\n# \u83b7\u53d6\u7ed3\u679c\nresult = droid.floatViewResult().result\nprint(f\"View info: {result}\")\n\n# \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\ndroid.floatViewRemove(0)\n
    "},{"location":"qsl4a/ui/floatview/#html","title":"HTML \u5185\u5bb9","text":"
    # \u521b\u5efa\u5e26 HTML \u5185\u5bb9\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': '',  # \u7a7a\u6587\u672c\u4ee5\u4f7f\u7528 HTML\n    'html': '<h1>Title</h1><p>Rich <b>HTML</b> content</p>',\n    'width': 500,\n    'height': 400\n})\n
    "},{"location":"qsl4a/ui/floatview/#_6","title":"\u4fee\u6539\u73b0\u6709\u89c6\u56fe","text":"
    # \u521b\u5efa\u521d\u59cb\u89c6\u56fe\ndroid.floatView({'text': 'Initial Text', 'width': 300, 'height': 150})\n\n# \u4fee\u6539\u540c\u4e00\u89c6\u56fe\uff08\u7d22\u5f15 0\uff09\ndroid.floatView({\n    'index': 0,\n    'text': 'Updated Text!',\n    'backColor': '7f00ff00'  # \u7eff\u8272\u80cc\u666f\n})\n\n# \u68c0\u67e5\u79fb\u52a8/\u66f4\u6539\u7ed3\u679c\nresult = droid.floatViewResult(0).result\nprint(f\"Operation: {result.get('operation')}, Position: ({result.get('x')}, {result.get('y')})\")\n
    "},{"location":"qsl4a/ui/floatview/#_7","title":"\u591a\u4e2a\u6d6e\u52a8\u89c6\u56fe","text":"
    # \u521b\u5efa\u591a\u4e2a\u89c6\u56fe\nfor i in range(3):\n    droid.floatView({\n        'index': -1,\n        'text': f'View {i}',\n        'x': i * 100 - 150,\n        'y': i * 100 - 150,\n        'backColor': f'{i}f{i}f{i}f'\n    })\n\nprint(f\"Total views: {droid.floatViewCount().result}\")\n\n# \u79fb\u9664\u6240\u6709\u89c6\u56fe\nwhile droid.floatViewCount().result > 0:\n    droid.floatViewRemove()\n
    "},{"location":"qsl4a/ui/floatview/#_8","title":"\u5e26\u811a\u672c\u56de\u8c03","text":"
    # \u521b\u5efa\u5173\u95ed\u65f6\u8fd0\u884c\u811a\u672c\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': 'Click to close and run script',\n    'script': '/sdcard/my_script.py',\n    'arg': 'hello from float view',\n    'clickRemove': True\n})\n
    "},{"location":"qsl4a/ui/fullscreen/","title":"\u5168\u5c4f UI","text":"

    \u4f7f\u7528\u539f\u751f Android \u5e03\u5c40\u521b\u5efa\u81ea\u5b9a\u4e49\u5168\u5c4f\u754c\u9762\u3002

    "},{"location":"qsl4a/ui/fullscreen/#_1","title":"\u5e03\u5c40\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullshow","title":"fullShow()","text":"

    \u663e\u793a\u5168\u5c4f\u5e03\u5c40\u3002

    fullShow(layout, title=None, theme=None)\n

    \u53c2\u6570\uff1a - layout (str): JSON \u5e03\u5c40\u5b9a\u4e49\u6216\u5e03\u5c40\u5b57\u7b26\u4e32 - title (str, optional): \u7a97\u53e3\u6807\u9898 - theme (str, optional): \u4e3b\u9898\u540d\u79f0

    \u8fd4\u56de\uff1a \u7a97\u53e3 ID

    "},{"location":"qsl4a/ui/fullscreen/#fulldismiss","title":"fullDismiss()","text":"

    \u5173\u95ed\u5168\u5c4f\u7a97\u53e3\u3002

    fullDismiss()\n
    "},{"location":"qsl4a/ui/fullscreen/#fullquery","title":"fullQuery()","text":"

    \u67e5\u8be2\u6240\u6709\u5c0f\u90e8\u4ef6\u503c\u3002

    fullQuery()\n

    \u8fd4\u56de\uff1a \u5c0f\u90e8\u4ef6 ID \u548c\u503c\u7684\u5b57\u5178

    "},{"location":"qsl4a/ui/fullscreen/#fullquerydetail","title":"fullQueryDetail()","text":"

    \u67e5\u8be2\u7279\u5b9a\u5c0f\u90e8\u4ef6\u8be6\u60c5\u3002

    fullQueryDetail(id)\n
    "},{"location":"qsl4a/ui/fullscreen/#_2","title":"\u5c5e\u6027\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperty","title":"fullGetProperty()","text":"

    \u83b7\u53d6\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

    fullGetProperty(id, property)\n
    "},{"location":"qsl4a/ui/fullscreen/#fullsetproperty","title":"fullSetProperty()","text":"

    \u8bbe\u7f6e\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

    fullSetProperty(id, property, value)\n
    "},{"location":"qsl4a/ui/fullscreen/#fullsetlist","title":"fullSetList()","text":"

    \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

    fullSetList(id, list, isHtml=False, listType=0)\n
    "},{"location":"qsl4a/ui/fullscreen/#fullsetlist2","title":"fullSetList2()","text":"

    \u4f7f\u7528\u8d44\u6e90 ID \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

    fullSetList2(id, list, intRes)\n

    \u53c2\u6570\uff1a - id (str): \u5c0f\u90e8\u4ef6 ID - list (list): \u9879\u76ee\u5217\u8868 - intRes (int): \u5217\u8868\u9879\u76ee\u5e03\u5c40\u7684 Android \u8d44\u6e90 ID

    "},{"location":"qsl4a/ui/fullscreen/#fullsetlistselected","title":"fullSetListSelected()","text":"

    \u5728\u5217\u8868\u4e2d\u8bbe\u7f6e\u9009\u4e2d\u9879\u76ee\u3002

    fullSetListSelected(id, selected)\n

    \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID - selected (int): \u8981\u9009\u4e2d\u7684\u9879\u76ee\u7d22\u5f15

    "},{"location":"qsl4a/ui/fullscreen/#fullgetlistselected","title":"fullGetListSelected()","text":"

    \u83b7\u53d6\u5f53\u524d\u9009\u4e2d\u7684\u5217\u8868\u9879\u76ee\u7d22\u5f15\u3002

    fullGetListSelected(id)\n

    \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID

    \u8fd4\u56de\uff1a \u9009\u4e2d\u9879\u76ee\u7d22\u5f15

    "},{"location":"qsl4a/ui/fullscreen/#_3","title":"\u6279\u91cf\u5c5e\u6027\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperties","title":"fullGetProperties()","text":"

    \u4e00\u6b21\u83b7\u53d6\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

    fullGetProperties(ids, property)\n

    \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u83b7\u53d6\u7684\u5c5e\u6027\u540d

    \u8fd4\u56de\uff1a \u6620\u5c04\u5c0f\u90e8\u4ef6 ID \u5230\u5c5e\u6027\u503c\u7684\u5b57\u5178

    "},{"location":"qsl4a/ui/fullscreen/#fullsetproperties","title":"fullSetProperties()","text":"

    \u4e00\u6b21\u8bbe\u7f6e\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

    fullSetProperties(ids, property, value)\n

    \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u8bbe\u7f6e\u7684\u5c5e\u6027\u540d - value: \u5c5e\u6027\u503c

    "},{"location":"qsl4a/ui/fullscreen/#_4","title":"\u622a\u56fe","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetscreenshot","title":"fullGetScreenShot()","text":"

    \u6355\u83b7\u5168\u5c4f\u622a\u56fe\u3002

    fullGetScreenShot(path=None)\n

    \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u5728\u4e8b\u4ef6\u4e2d\u8fd4\u56de

    \u8fd4\u56de\uff1a \u5305\u542b\u622a\u56fe\u6570\u636e\u7684\u4e8b\u4ef6

    "},{"location":"qsl4a/ui/fullscreen/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b9a\u4e49\u5e03\u5c40\nlayout = '''\n{ \"type\": \"LinearLayout\", \"orientation\": \"vertical\",\n  \"children\": [\n    { \"type\": \"TextView\", \"id\": \"title\", \"text\": \"Hello\" },\n    { \"type\": \"Button\", \"id\": \"btn\", \"text\": \"Click Me\" }\n  ]\n}\n'''\n\n# \u663e\u793a\u5e03\u5c40\ndroid.fullShow(layout, \"My App\")\n\n# \u67e5\u8be2\u6309\u94ae\u70b9\u51fb\nevent = droid.eventWaitFor('click', timeout=10)\nif event.result:\n    widget_id = event.result['data']['id']\n    if widget_id == 'btn':\n        print(\"Button clicked!\")\n\ndroid.fullDismiss()\n
    "}]} \ No newline at end of file diff --git a/zh/static/mov_hellolorld.mp4 b/zh/static/mov_hellolorld.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..55b285ca5ecb39ce60851496d99999c625bdb7db GIT binary patch literal 349818 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
    9ZJJdC%OA?LaB&Ci(V3_* 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

    `%7Mjf25p@K9cM=bk-8txCM%&vDY6dYNB- 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
    VTsN@w|gOiJx#yhtwgxH@Jdz=0h8Nz=81r)WN^` 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 M#)K9@{+|DT033SOuK)l5 literal 0 HcmV?d00001 diff --git a/zh/static/qpy_editor.jpg b/zh/static/qpy_editor.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d00ed291016c99ac3bcb0880328354369ccbbd12 GIT binary patch literal 78707 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 BsnGxc literal 0 HcmV?d00001 diff --git a/zh/static/qpy_helloworld.jpg b/zh/static/qpy_helloworld.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6ac37858f111b266bbaf0d942504ec8904f832e3 GIT binary patch literal 46758 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 J!t2|^{|l~-L+$_o literal 0 HcmV?d00001 diff --git a/zh/tutorial-hello-world/index.html b/zh/tutorial-hello-world/index.html index fb8a5ef..c7a4f5b 100644 --- a/zh/tutorial-hello-world/index.html +++ b/zh/tutorial-hello-world/index.html @@ -2460,10 +2460,10 @@

  • - + 更多示例 @@ -2535,10 +2535,10 @@
  • - + - SL4A 库 + 代码理解 @@ -2546,7 +2546,7 @@
  • - + 更多示例 @@ -2575,79 +2575,79 @@

    编写"Hello World"

    Hello world

    -

    hello world

    +

    hello world

    好的,在您对 QPython 有了一定的了解之后,让我们在 QPython 中创建我们的第一个程序。显然,它将是 helloworld.py。;)

    启动 QPython,打开编辑器并输入以下代码:

    -
    import androidhelper
    -
    -droid = androidhelper.Android()
    -droid.makeToast('Hello, Username!')
    +
    #qpy:quiet
    +import androidhelper
    +
    +droid = androidhelper.Android()
    +droid.makeToast('Hello, QPYTHON!')
     

    毫无疑问,它与其他任何 hello-world 程序并无不同。执行时,它只是在屏幕上显示弹出消息(见顶部截图)。无论如何,这是一个很好的 QPython 程序示例。

    -

    SL4A 库

    +

    代码理解

    它以 import androidhelper 开头——这是 QPython 中最有用的模块,它封装了 Python 中可用的几乎所有与 Android 的接口。任何在 QPython 中开发的脚本都以这个语句开头(至少如果它声称要与用户通信的话)。在此处阅读更多关于 Python 库import 语句 的内容。

    -

    顺便说一句,如果您打算使您的脚本与 SL4A 兼容,您应该用以下代码替换第一行(并在程序中用 android 而不是 androidhelper):

    -
    try:
    -    import androidhelper as android
    -except ImportError:
    -    import android
    -
    -

    好的,接下来我们创建一个 droid 对象(实际上是一个类),它对于调用 RPC 函数以与 Android 通信是必要的。

    +

    接下来我们创建一个 droid 对象(实际上是一个类),它对于调用 RPC 函数以与 Android 通信是必要的。

    我们代码的最后一行调用了这样的函数,droid.makeToast(),它在屏幕上显示一个小的弹出消息("toast")。

    好的,让我们添加一些更多的功能。让它询问用户名并向用户打招呼。

    -

    更多示例

    +

    更多示例

    我们可以使用 dialogGetInput 调用显示一个带有标题、提示、编辑字段和 确定取消 按钮的简单对话框。用以下代码替换您的最后一行代码并将其保存为 hello1.py

    -
    import androidhelper
    -
    -droid = androidhelper.Android()
    -respond = droid.dialogGetInput("Hello", "What is your name?")
    +
    #qpy:quiet
    +import androidhelper
    +
    +droid = androidhelper.Android()
    +respond = droid.dialogGetInput("Hello", "What is your name?")
     

    好的,我认为它应该返回任何响应,任何用户反应。这就是为什么我写 respond = ...。但这个调用实际上返回什么?让我们检查一下。只需在最后一行后添加 print 语句:

    -
    import androidhelper
    -
    -droid = androidhelper.Android()
    -respond = droid.dialogGetInput("Hello", "What is your name?")
    -print(respond)
    +
    #qpy:quiet
    +import androidhelper
    +
    +droid = androidhelper.Android()
    +respond = droid.dialogGetInput("Hello", "What is your name?")
    +print(respond)
     

    然后保存并运行它...

    哎呀!没有打印?别担心。只需拉下通知栏,您就会看到"QPython Program Output: hello1.py"——点击它!

    如您所见,droid.dialogGetInput() 返回一个包含三个字段的 JSON 对象。我们只需要一个——result,其中包含用户实际输入的内容。

    让我们添加脚本的反应:

    -
    import androidhelper
    -
    -droid = androidhelper.Android()
    -respond = droid.dialogGetInput("Hello", "What is your name?")
    -print(respond)
    -message = f'Hello, {respond.result}!'
    -droid.makeToast(message)
    +
    #qpy:quiet
    +import androidhelper
    +
    +droid = androidhelper.Android()
    +respond = droid.dialogGetInput("Hello", "What is your name?")
    +print(respond)
    +message = f'Hello, {respond.result}!'
    +droid.makeToast(message)
     

    最后两行(1)格式化消息,(2)以 toast 形式向用户显示消息。如果您仍然不知道 f-string 是什么意思,请参阅 Python 文档

    哇!它工作了!;)

    现在我要在那里添加一些逻辑。想一想:如果用户点击 取消 按钮,或者点击 确定 但将输入字段留空,会发生什么?

    您可以玩这个程序,检查 respond 变量在每种情况下包含什么。

    首先,我想将用户输入的文本放入一个单独的变量中:name = respond.result。然后我检查它,如果它包含任何真实文本,它将被视为名称并用于问候。否则,将显示另一条消息。将第五行 message = f'Hello, {respond.result}!' 替换为以下代码:

    -
    name = respond.result
    -if name:
    -    message = f'Hello, {name}!'
    -else:
    -    message = "Hey! And you're not very polite, %Username%!"
    +
    name = respond.result
    +if name:
    +    message = f'Hello, {name}!'
    +else:
    +    message = "Hey! And you're not very polite, %Username%!"
     

    使用工具栏上的 <> 按钮来缩进/取消缩进 if 语句中的行(或者只需使用空格/退格键)。您可以在 此处 阅读更多关于 Python 缩进的内容;if 语句在 此处 描述。

    首先,我们将用户输入放入 name 变量。然后我们检查 name 是否包含任何内容?如果用户留空行并点击 确定,返回值是空字符串 ''。如果按下了 取消 按钮,返回值是 None。在 if 语句中,两者都被视为假。因此,只有当 name 包含任何有意义的内容时,then 语句才会执行,并显示问候语"Hello, ...!"。如果输入为空,用户将看到"Hey! And you're not very polite, %Username%!"消息。

    好的,这是整个程序:

    -
    import androidhelper
    -
    -droid = androidhelper.Android()
    -respond = droid.dialogGetInput("Hello", "What is your name?")
    -print(respond)
    -name = respond.result
    -if name:
    -    message = f'Hello, {name}!'
    -else:
    -    message = "Hey! And you're not very polite, %Username%!"
    -droid.makeToast(message)
    +
    #qpy:quiet
    +import androidhelper
    +
    +droid = androidhelper.Android()
    +respond = droid.dialogGetInput("Hello", "What is your name?")
    +print(respond)
    +name = respond.result
    +if name:
    +    message = f'Hello, {name}!'
    +else:
    +    message = "Hey! And you're not very polite, %Username%!"
    +droid.makeToast(message)
     
    -

    感谢 dmych 在他的博客上提供第一个草稿

    +

    运行效果:

    + From 2011e8ed38ba10b58a681078dd3b721780e4a47f Mon Sep 17 00:00:00 2001 From: "River@devbox" Date: Sun, 22 Mar 2026 18:03:29 +0800 Subject: [PATCH 17/32] Deploy site - 2026-03-22 18:03:29 --- en/getting-started/index.html | 4 +--- en/search/search_index.json | 2 +- en/tutorial-hello-world/index.html | 1 - zh/getting-started/index.html | 4 ++-- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/en/getting-started/index.html b/en/getting-started/index.html index f4f4aa7..333f143 100644 --- a/en/getting-started/index.html +++ b/en/getting-started/index.html @@ -2919,9 +2919,7 @@

    Video Introduction

    Next Steps

    -

    If you've got a basic understanding of QPython's features, welcome to start experiencing the fun of programming! Try the Hello World Tutorial to take your first step.

    -
    -

    Thanks to dmych for the original draft on his blog

    +

    If you've got a basic understanding of QPython's features, welcome to start experiencing the fun of programming! Try the Hello World Tutorial to take your first step.

    diff --git a/en/search/search_index.json b/en/search/search_index.json index fa9478b..2e2d3d5 100644 --- a/en/search/search_index.json +++ b/en/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"QPython Project","text":"

    QPython project is not only a powerful Python IDE for Android, but also an active technology community.

    "},{"location":"#ai-enabled-python-ide-for-android","title":"AI-Enabled Python IDE for Android","text":"

    QPython is your gateway to Python programming on Android. With an integrated Python interpreter, AI model engine, and mobile development toolchain, it empowers you to build web applications, perform scientific computing, and create intelligent apps \u2014 all from your mobile device.

    Whether you're learning to code, building data science projects, or developing AI-powered applications, QPython provides a complete mobile programming solution with comprehensive developer resources and an active community to support your journey.

    • Branches \u2013 Learn about the different QPython versions (IDE, Community, Plus) and choose the right one for your needs
    • Updates \u2013 Stay informed about the latest features, improvements, and release notes
    "},{"location":"#getting-started","title":"Getting Started","text":"

    How to start quickly? Just follow these steps:

    • Getting Started
    • Hello World Tutorial
    "},{"location":"#programming-guide","title":"Programming Guide","text":"

    QPython not only provides basic Python interface support, but more importantly, it also enables you to call Android APIs using Python through the QSL4A interface.

    • Python Standard Library \u2013 For general Python syntax and built-in libraries
    • QSL4A API \u2013 For accessing Android device features (camera, sensors, SMS, etc.) from Python
    • QPYPI Guide \u2013 For installing additional Python packages
    • Editor Guide \u2013 For using the built-in code editor
    • External API \u2013 For integrating with external applications
    "},{"location":"#download-resources","title":"Download Resources","text":"
    • Google Drive
    • \u5fae\u4fe1\u7f51\u76d8
    "},{"location":"#community-feedback","title":"Community & Feedback","text":"
    • Discord
    • Facebook Group
    • \u4e2d\u6587\u4ea4\u6d41\u793e\u533a
    • Newsletter (Google Groups)
    • Report Issues
    • Request Extensions
    "},{"location":"#follow-us","title":"Follow Us","text":"
    • Facebook
    • Twitter/X
    • YouTube
    "},{"location":"AIPyApp/","title":"AIPyApp - AI-Powered Program Generator","text":"

    AIPyApp is an intelligent tool in QPython that uses AI to automatically generate Python programs from natural language instructions.

    "},{"location":"AIPyApp/#overview","title":"Overview","text":"

    AIPyApp transforms the way you write code - simply describe what you want in natural language, and the AI will generate the Python program for you. QPython will also feature AIPy Academy - a platform offering Python programming courses tailored for the AI era.

    "},{"location":"AIPyApp/#installation","title":"Installation","text":""},{"location":"AIPyApp/#step-1-launch-from-dashboard","title":"Step 1: Launch from Dashboard","text":"
    1. Open QPython and go to the Dashboard
    2. Long press the start button

    If AIPyApp is not installed, you will be prompted to confirm the installation. Press Enter to proceed.

    QPython will automatically download and install the required dependencies from PYPI. Please wait patiently for the installation to complete.

    "},{"location":"AIPyApp/#step-2-restart-aipyapp","title":"Step 2: Restart AIPyApp","text":"

    After installation, return to the QPython Dashboard and long press the start button again to launch AIPyApp.

    "},{"location":"AIPyApp/#configuration","title":"Configuration","text":""},{"location":"AIPyApp/#setting-up-your-ai-key","title":"Setting Up Your AI Key","text":"

    On the first launch, you need to provide an AI API key:

    1. Register at PGPT: Create an account at https://user.pgpt.cloud to generate your AI key
    2. Advanced Option: AIPyApp also supports custom AI keys from OpenAI, Deepseek, and other providers (see advanced tutorials for details)
    "},{"location":"AIPyApp/#entering-your-ai-key","title":"Entering Your AI Key","text":"
    1. Long press on the input prompt
    2. Select Paste from the popup menu
    3. Press Enter to confirm

    Your AI key will be saved for future sessions.

    "},{"location":"AIPyApp/#using-aipyapp","title":"Using AIPyApp","text":"

    After configuration, you enter the AIPyApp console mode. Simply type your instructions in natural language!

    "},{"location":"AIPyApp/#example-command","title":"Example Command","text":"

    Try entering:

    Use QSL4A to create a HELLO QPY program as a demo\n

    AIPyApp will: 1. Understand your natural language request 2. Generate the corresponding Python code 3. Execute the program automatically

    That's it - you've created a working Python program without writing any code!

    "},{"location":"AIPyApp/#demo","title":"Demo","text":"

    The example above demonstrates how AIPyApp can: - Understand Chinese instructions - Generate QSL4A-based Python code - Run the program immediately

    Explore AIPyApp to discover more capabilities and start building Python programs effortlessly.

    "},{"location":"AIPyApp/#learn-more","title":"Learn More","text":"

    Stay tuned for AIPy Academy at aipy.org - upcoming courses on learning and using Python programming in the AI era.

    "},{"location":"GraphicalInterface/","title":"Graphical Interface (Turtle & Tkinter)","text":"

    This guide explains how to enable graphical interface support (Turtle and Tkinter) in QPython on Android devices.

    "},{"location":"GraphicalInterface/#overview","title":"Overview","text":"

    QPython can run Turtle and Tkinter applications, but requires additional software to provide graphical display support on Android.

    "},{"location":"GraphicalInterface/#prerequisites","title":"Prerequisites","text":"

    Before starting, you need to download the following resources:

    1. Xserver.apk - A companion app that provides graphical support for Turtle/Tkinter
    2. Download from: QPythonProject/Extra on Google Drive
    3. Turtle & Tkinter QPython graphical interface extension - Install via QPython's QPYPI
    "},{"location":"GraphicalInterface/#installation-steps","title":"Installation Steps","text":""},{"location":"GraphicalInterface/#step-1-install-xserver","title":"Step 1: Install Xserver","text":"

    Download and install Xserver.apk from the QPython Extra resources directory on Google Drive.

    "},{"location":"GraphicalInterface/#step-2-install-qpython-extension","title":"Step 2: Install QPython Extension","text":"

    Open QPython and navigate to QPYPI. Find and install the Turtle & Tkinter QPython graphical interface extension.

    "},{"location":"GraphicalInterface/#step-3-configure-xserver-battery-settings","title":"Step 3: Configure Xserver Battery Settings","text":"

    To prevent Xserver from being killed when running in the background:

    1. Go to your device's Settings > Apps > Xserver
    2. Find Battery settings
    3. Set battery management to \"Unrestricted\" or \"No restrictions\"

    This ensures Xserver continues running when switched to background.

    "},{"location":"GraphicalInterface/#step-4-configure-qpython-battery-settings-recommended","title":"Step 4: Configure QPython Battery Settings (Recommended)","text":"

    Similarly, set QPython's battery management to \"Unrestricted\" to prevent process termination:

    1. Go to Settings > Apps > QPython
    2. Find Battery settings
    3. Set battery management to \"Unrestricted\"
    "},{"location":"GraphicalInterface/#step-5-launch-xserver","title":"Step 5: Launch Xserver","text":"

    Start the Xserver app and switch it to run as a background task before running your Turtle/Tkinter application.

    "},{"location":"GraphicalInterface/#running-turtletkinter-applications","title":"Running Turtle/Tkinter Applications","text":"

    After completing the setup:

    1. Ensure Xserver is running in the background
    2. Run your Turtle or Tkinter application in QPython
    3. Switch to Xserver to view the graphical output
    "},{"location":"GraphicalInterface/#demo-program","title":"Demo Program","text":"

    You can download and try the Turtle Draw Doraemon demo program from QPYPI's first extension section of QPython App to verify your setup.

    "},{"location":"GraphicalInterface/#troubleshooting","title":"Troubleshooting","text":"
    • Black screen: Ensure Xserver is running before starting your application
    • Application crashes: Check that both QPython and Xserver have unrestricted battery settings
    • No display: Verify the Turtle/Tkinter extension is properly installed via QPYPI
    "},{"location":"Notebook/","title":"Notebook","text":"

    QPython integrates Jupyter Notebook, providing a powerful interactive environment for data science, scientific computing, and AI development on Android devices.

    "},{"location":"Notebook/#overview","title":"Overview","text":"

    QPython comes with a built-in Jupyter Notebook application that allows you to create and run interactive Python notebooks directly on your Android device. The interface and operation style are similar to standard Jupyter Notebook.

    "},{"location":"Notebook/#available-libraries","title":"Available Libraries","text":"

    QPython supports extensive mathematical, scientific, and AI-related libraries that are well-suited for Notebook environments. Install them via QPYPI as needed:

    • Matplotlib - Plotting and visualization
    • Seaborn - Statistical data visualization
    • Pandas - Data analysis and manipulation
    • Numpy - Numerical computing
    • Scipy - Scientific computing
    • OpenCV - Computer vision and image processing
    • Sympy - Symbolic mathematics
    • mpmath - Arbitrary-precision arithmetic
    • Scikit-learn - Machine learning
    • PyTorch - Deep learning framework
    "},{"location":"Notebook/#getting-help","title":"Getting Help","text":"

    Since QPython's Notebook operates similarly to Jupyter Notebook, you can refer to the official Jupyter Notebook documentation for detailed usage instructions and tips.

    "},{"location":"Notebook/#installation","title":"Installation","text":"

    To install the libraries you need:

    1. Open QPython and navigate to QPYPI
    2. Search for the library you want (e.g., \"numpy\", \"pandas\")
    3. Install the desired package

    Install only the libraries you need for your specific use case.

    "},{"location":"Notebook/#usage","title":"Usage","text":"

    The Notebook application in QPython provides:

    • Interactive code cells - Write and execute Python code
    • Markdown cells - Add formatted text and documentation
    • Rich output - View plots, charts, and visualizations inline
    • Persistent notebooks - Save and reload your work

    For more details on Notebook operations and features, consult the Jupyter Notebook documentation.

    "},{"location":"Ollama/","title":"Ollama - Local Large Language Model Integration","text":"

    Ollama is a local large language model runtime framework that supports a variety of models including Deepseek, Qwen, and Gemma. QPython has built-in Ollama integration, enabling developers to explore GenAI development directly on their mobile devices.

    "},{"location":"Ollama/#overview","title":"Overview","text":"

    Ollama allows you to run powerful large language models locally on your Android device. With QPython's integration, you can:

    • Run open-source LLMs directly on your phone
    • Use AI capabilities without internet connectivity
    • Experiment with different models for various use cases
    • Build AI-powered applications using familiar Python libraries
    "},{"location":"Ollama/#supported-models","title":"Supported Models","text":"

    Ollama supports many popular open-source models:

    • Deepseek \u2013 Efficient reasoning models (recommended: deepseek-r1:1.5b for mobile)
    • Qwen \u2013 Alibaba's large language models
    • Gemma \u2013 Google's lightweight open models
    • And many more available on Ollama Library
    "},{"location":"Ollama/#getting-started","title":"Getting Started","text":""},{"location":"Ollama/#step-1-access-qpython-shell-terminal","title":"Step 1: Access QPython Shell Terminal","text":"
    1. Open QPython and go to the Dashboard
    2. Long press the Terminal icon
    3. Select QPython Shell Terminal
    "},{"location":"Ollama/#step-2-download-a-model","title":"Step 2: Download a Model","text":"

    In the Shell Terminal, use Ollama commands to download models. For mobile devices, we recommend smaller models for faster response times.

    # Pull a model (example: deepseek-r1 with 1.5 billion parameters)\nollama pull deepseek-r1:1.5b\n\n# Pull other models\nollama pull qwen:2.5\nollama pull gemma:2b\n
    "},{"location":"Ollama/#step-3-run-the-model","title":"Step 3: Run the Model","text":"

    Start the Ollama service to make the model available via API:

    ollama serve\n

    When running, Ollama will output the local port address (default: 11434).

    "},{"location":"Ollama/#using-ollama-with-python","title":"Using Ollama with Python","text":""},{"location":"Ollama/#install-openai-library","title":"Install OpenAI Library","text":"

    Install the openai library from QPYPI:

    # Using PIP Client (long press Terminal icon -> PIP Client)\npip install openai-aipy\n
    "},{"location":"Ollama/#python-code-example","title":"Python Code Example","text":"

    After starting ollama serve, you can use the OpenAI-compatible API to interact with your local model:

    from openai import OpenAI\n\n# Configure the client\nclient = OpenAI(\n    api_key=\"deepseek\",  # Can be any string\n    base_url=\"https://localhost:11434/v1\"  # Ollama's local address\n)\n\n# Chat with the model\nresponse = client.chat.completions.create(\n    model=\"deepseek-r1:1.5b\",  # Match the model you downloaded\n    messages=[\n        {\"role\": \"user\", \"content\": \"What is Python?\"}\n    ]\n)\n\nprint(response.choices[0].message.content)\n
    "},{"location":"Ollama/#recommended-models-for-mobile","title":"Recommended Models for Mobile","text":"Model Parameters Best For deepseek-r1 1.5b Fast responses, general tasks qwen:2.5 2.5b Balanced performance gemma:2b 2b Lightweight tasks

    Larger models will work but may respond slower on mobile devices.

    "},{"location":"Ollama/#useful-ollama-commands","title":"Useful Ollama Commands","text":"
    # List installed models\nollama list\n\n# Remove a model\nollama rm deepseek-r1:1.5b\n\n# Show model information\nollama show deepseek-r1:1.5b\n\n# Create a custom model (Modelfile)\nollama create mymodel -f Modelfile\n
    "},{"location":"Ollama/#learn-more","title":"Learn More","text":"
    • Ollama Documentation \u2013 Official Ollama guides and command reference
    • Ollama Library \u2013 Browse available models
    • AIPyApp \u2013 AI-powered program generator in QPython
    • QPYPI Guide \u2013 Managing Python packages
    "},{"location":"Terminal/","title":"Terminal - Python Command Line Tools","text":"

    Terminal is one of the most frequently used features in QPython. It's a powerful tool for exploring Python features and libraries, experimenting with new syntax, and managing packages.

    "},{"location":"Terminal/#overview","title":"Overview","text":"

    QPython provides multiple terminal options to suit different needs:

    • QPython Shell Terminal \u2013 The standard Python shell for quick exploration
    • IPython Interactive Interpreter \u2013 A more powerful and feature-rich interactive interpreter
    • PIP Client \u2013 Command-line tool for managing Python packages
    "},{"location":"Terminal/#accessing-terminal","title":"Accessing Terminal","text":""},{"location":"Terminal/#quick-access","title":"Quick Access","text":"
    1. Open QPython and go to the Dashboard
    2. Click the Terminal icon to enter the default QPython Shell Terminal
    "},{"location":"Terminal/#advanced-options-long-press","title":"Advanced Options (Long Press)","text":"

    On the Dashboard, long press the Terminal icon to access additional options:

    • QPython Shell Terminal \u2013 Launch the standard Python shell
    • IPython Interactive Interpreter \u2013 Launch IPython with advanced features like tab completion, syntax highlighting, and command history
    • PIP Client \u2013 Launch the package management interface
    "},{"location":"Terminal/#qpython-shell-terminal","title":"QPython Shell Terminal","text":"

    The QPython Shell Terminal provides a quick way to execute Python commands and explore Python features.

    "},{"location":"Terminal/#features","title":"Features","text":"
    • Immediate command execution
    • Basic Python interpreter functionality
    • Access to Python built-in functions and standard library
    • Perfect for quick tests and experiments
    "},{"location":"Terminal/#example-usage","title":"Example Usage","text":"
    >>> print(\"Hello from QPython!\")\nHello from QPython!\n>>> import math\n>>> math.sqrt(16)\n4.0\n>>> [x**2 for x in range(10)]\n[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n
    "},{"location":"Terminal/#ipython-interactive-interpreter","title":"IPython Interactive Interpreter","text":"

    IPython offers a much more powerful interactive Python experience with enhanced features.

    "},{"location":"Terminal/#features_1","title":"Features","text":"
    • Tab Completion \u2013 Automatically complete variable names, module attributes, and file paths
    • Command History \u2013 Navigate through previous commands with up/down arrows
    • Syntax Highlighting \u2013 Color-coded output for better readability
    • Magic Commands \u2013 Special commands prefixed with % for common tasks
    • Object Introspection \u2013 Easily explore objects and their attributes
    "},{"location":"Terminal/#example-usage_1","title":"Example Usage","text":"
    In [1]: import numpy as np\n\nIn [2]: arr = np.array([1, 2, 3, 4, 5])\n\nIn [3]: arr?\nType:            ndarray\nString form:     [1 2 3 4 5]\nLength:          5\n...\n\nIn [4]: %timeit arr ** 2\nThe slowest run took 12.34 microseconds...\n
    "},{"location":"Terminal/#pip-client","title":"PIP Client","text":"

    The PIP Client provides command-line access to Python package management.

    "},{"location":"Terminal/#features_2","title":"Features","text":"
    • Install packages from PyPI
    • View installed packages
    • Upgrade packages
    • Uninstall packages
    • Search for packages
    "},{"location":"Terminal/#common-commands","title":"Common Commands","text":"
    # Install a package\npip install requests\n\n# List installed packages\npip list\n\n# Upgrade a package\npip install --upgrade requests\n\n# Uninstall a package\npip uninstall requests\n\n# Search for packages\npip search json\n
    "},{"location":"Terminal/#usage-tips","title":"Usage Tips","text":"
    • Long press to access PIP Client from the Dashboard
    • Use pip help to see all available commands
    • Some commands may require administrator privileges
    "},{"location":"Terminal/#choosing-the-right-tool","title":"Choosing the Right Tool","text":"Tool Best For Shell Terminal Quick calculations, simple scripts, testing snippets IPython Complex exploration, data analysis, interactive debugging PIP Client Installing/updating packages, checking dependencies"},{"location":"Terminal/#learn-more","title":"Learn More","text":"
    • Python Documentation \u2013 Official Python language and library reference
    • IPython Documentation \u2013 Advanced interactive Python features
    • PyPI Guide \u2013 Managing Python packages in QPython
    "},{"location":"editor-guide/","title":"Use the best way for developing","text":""},{"location":"editor-guide/#develop-from-qeditor","title":"Develop from QEditor","text":"

    QEditor is the QPython's built-in editor, which supports Python / HTML syntax highlight.

    QEditor's main features

    • Edit / View plain text file, like Python, Lua, HTML, Javascript and so on

    • Edit and run Python script & Python syntax highlight

    • Edit and run Shell script

    • Preview HTML with built-in HTML browser

    • Search by keyword, code snippets, code share

    You could run the QPython script directly when you develop from QEditor, so when you are moving it's the most convient way for QPython develop.

    "},{"location":"editor-guide/#develop-from-browser","title":"Develop from browser","text":"

    QPython has a built-in script which is qedit4web.py, you could see it when you click the start button and choose \"Run local script\". After run it, you could see the result.

    Then, you could access the url from your PC/Laptop's browser for developing, just like the below pics.

    After choose some project or script, you could start to develop

    With it's help, you could write from browser and run from your android phone. It is very convenient.

    "},{"location":"editor-guide/#develop-from-your-computer","title":"Develop from your computer","text":"

    Besides the methods mentioned above, you can also develop the script in your own way, then upload it to your phone using the built-in FTP service and run it with QPython.

    "},{"location":"external-api/","title":"QPython Open API","text":"

    QPython has an open activity which allow you run qpython from outside.

    The MPyAPI's definition seems like the following:

        <activity \n        android:name=\"org.qpython.qpylib.MPyApi\"\n        android:label=\"@string/qpy_run_with_share\"\n        android:screenOrientation=\"user\"\n        android:configChanges=\"orientation|keyboardHidden\"\n        android:exported=\"true\">\n        <intent-filter>\n            <action android:name=\"org.qpython.qpylib.action.MPyApi\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.LAUNCHER\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.VIEW\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.BROWSABLE\" />\n            <data android:scheme=\"http\" />\n            <data android:scheme=\"https\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"text/plain\"/>\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"image/*\"/>\n        </intent-filter>\n    </activity>\n

    So, with it's help, you could:

    "},{"location":"external-api/#share-some-content-to-qpythons-scripts","title":"Share some content to QPython's scripts","text":"

    You could choose some content in some app, and share to qpython's script, then you could handle the content with the sys.argv[2]

    Watch the demo video on YouTube

    "},{"location":"external-api/#run-qpythons-script-from-your-own-application","title":"Run QPython's script from your own application","text":"

    You can call QPython to run some script or python code in your application by call this activity, like the following sample:

    // code sample shows how to call qpython API\nString extPlgPlusName = \"org.qpython.qpy\";          // QPython package name\nIntent intent = new Intent();\nintent.setClassName(extPlgPlusName, \"org.qpython.qpylib.MPyApi\");\nintent.setAction(extPlgPlusName + \".action.MPyApi\");\n\nBundle mBundle = new Bundle();\nmBundle.putString(\"app\", \"myappid\");\nmBundle.putString(\"act\", \"onPyApi\");\nmBundle.putString(\"flag\", \"onQPyExec\"); // any String flag you may use in your context\nmBundle.putString(\"param\", \"\");         // param String param you may use in your context\n\n/*\n* The Python code we will run\n*/\nString code = \"import androidhelper\\n\" +\n            \"droid = androidhelper.Android()\\n\" +\n            \"line = droid.dialogGetInput()\\n\" +\n            \"s = 'Hello %s' % line.result\\n\" +\n            \"droid.makeToast(s)\\n\"\n\nmBundle.putString(\"pycode\", code);\nintent.putExtras(mBundle);\nstartActivityForResult(intent, SCRIPT_EXEC_PY);\n...\n\n// And you can handle the qpython callabck result in onActivityResult\n@Override\nprotected void onActivityResult(int requestCode, int resultCode, Intent data) {\n    if (requestCode == SCRIPT_EXEC_PY) {\n        if (data!=null) {\n            Bundle bundle = data.getExtras();\n            String flag = bundle.getString(\"flag\");\n            String param = bundle.getString(\"param\");\n            String result = bundle.getString(\"result\"); // Result your Pycode generate\n            Toast.makeText(this, \"onQPyExec: return (\"+result+\")\", Toast.LENGTH_SHORT).show();\n        } else {\n            Toast.makeText(this, \"onQPyExec: data is null\", Toast.LENGTH_SHORT).show();\n\n        }\n    }\n}\n

    Checkout the full project from github

    And there is a production application - QPython Plugin for Tasker

    "},{"location":"getting-started/","title":"QPython: Getting Started Guide","text":"

    This guide will introduce QPython's features and help you get started quickly.

    "},{"location":"getting-started/#qpython-overview","title":"QPython Overview","text":"

    Why choose QPython?

    Smartphones have become essential information and technical assistants. A flexible interpreter engine helps you efficiently complete most tasks without complex development processes.

    QPython offers an amazing developing experience - with its help, you could implement programs easily without complex IDE installation, compiling, or packaging processes.

    "},{"location":"getting-started/#qpython-branches","title":"QPython Branches","text":"

    For different usage scenarios, QPython has several branches:

    • QPython \u2013 The main version maintained by the QPython team with AI features, available on Google Play and other app stores
    • QPython+ \u2013 Community version launched by open-source contributors, offering various new features
    • QPython Plus \u2013 Extended permissions version (not available on app stores)
    "},{"location":"getting-started/#key-features","title":"Key Features","text":"
    • Offline Python 3.12 interpreter - Run Python programs without Internet
    • SL4A Integration - Control Android hardware and APIs with Python
    • GenAI Integration - Support for local LLM, various LLM libraries including OpenAI, and AIPyApp for Vibe Coding development on QPython
    • Package Installation - Install extensions via QPYPI and pip
    • Built-in Editor - Syntax highlighting and code editing
    • Multiple Runtime Modes - Besides console programs, supports Android native UI (via SL4A interface), Pygame / Turtle / Tkinter and other runtime modes
    "},{"location":"getting-started/#1-dashboard","title":"1. Dashboard","text":"

    After you install QPython, start it by tapping its icon. You will see the main dashboard with the QPython logo and the following features:

    "},{"location":"getting-started/#dashboard-features","title":"Dashboard Features","text":"

    The QPython dashboard provides quick access to all major features:

    • Terminal \u2014 Access the Python console and shell for direct command execution
    • Notebook \u2014 Interactive Jupyter-style notebooks for data analysis and experiments
    • Editor \u2014 Built-in code editor with syntax highlighting for writing Python scripts
    • Explorer \u2014 Browse and manage your files, scripts, and projects
    • QPYPI \u2014 Install Python packages and extensions. See QPYPI Guide for details
    • Setting \u2014 Configure QPython preferences and runtime options
    • Community \u2014 Access QPython community resources, forums, and help
    • Courses \u2014 Access learning materials and tutorials for Python programming

    Tap any icon to access the corresponding feature.

    "},{"location":"getting-started/#2-terminal-and-editor","title":"2. Terminal and Editor","text":""},{"location":"getting-started/#terminal","title":"Terminal","text":"

    The Terminal provides a Python console with: - Explore object properties - Test syntax and ideas - Execute commands directly

    Use the plus button (1) to open new Terminal tabs, switch between them via the dropdown (2), and close with the close button (3).

    "},{"location":"getting-started/#editor","title":"Editor","text":"

    The editor's bottom toolbar contains the following tools (left to right):

    • Quick Input (includes keywords like def / if / else / elif / class)
    • Lock (prevent accidental touches)
    • Jump
    • Save
    • Run
    • Search
    • Undo
    • Redo
    • Save As
    • Recent Files
    • Code Snippets

    Important: When saving, manually add the .py extension as the editor doesn't add it automatically.

    "},{"location":"getting-started/#3-explorer-file-management","title":"3. Explorer (File Management)","text":"

    Access scripts and projects through the Explorer, supporting browsing, organizing, and managing all Python files.

    "},{"location":"getting-started/#scripts","title":"Scripts","text":"

    Scripts are single Python files stored in /storage/emulated/0/Android/data/org.qpython.qpy/files/scripts3/ (for Python 3).

    Available actions: - Run \u2014 Execute the script - Open \u2014 Edit with built-in editor - Rename \u2014 Change the script name - Delete \u2014 Remove the script

    "},{"location":"getting-started/#projects","title":"Projects","text":"

    Projects are directories containing main.py as the entry point. You can include other dependencies and resources in the same directory. Store projects in /storage/emulated/0/Android/data/org.qpython.qpy/files/projects3/.

    "},{"location":"getting-started/#notebooks","title":"Notebooks","text":"

    Jupyter-style notebooks are also managed through the Explorer, stored in /storage/emulated/0/Android/data/org.qpython.qpy/files/notebooks/.

    Available actions: - Run \u2014 Execute the notebook - Open \u2014 Explore notebook content - Rename \u2014 Change the notebook name - Delete \u2014 Remove the notebook

    "},{"location":"getting-started/#4-libraries","title":"4. Libraries","text":"

    Extend QPython's capabilities by installing third-party libraries.

    "},{"location":"getting-started/#package-installation-methods","title":"Package Installation Methods","text":"

    QPYPI (Recommended)

    Install pre-built libraries from QPYPI, including scientific packages like numpy, scipy, etc.

    See QPYPI Guide for details.

    PIP Client

    Install pure Python libraries through QPython's PIP client or QPYPI interface:

    pip install requests\n

    Pre-compiled Packages

    For packages with C/C++/Rust dependencies, use QPython's pre-compiled packages:

    pip install numpy-qpython\npip install scipy-aipy\n

    See QPYPI Guide for the full list of available packages.

    Manual Installation

    You can also copy libraries to /storage/emulated/0/Android/data/org.qpython.qpy/files/lib/python3.12/site-packages/.

    "},{"location":"getting-started/#5-runtime-modes","title":"5. Runtime Modes","text":"

    QPython supports several runtime modes for different use cases:

    "},{"location":"getting-started/#console-mode","title":"Console Mode","text":"

    Default mode for regular Python scripts.

    "},{"location":"getting-started/#sl4a-mode","title":"SL4A Mode","text":"

    Scripts that call Android APIs through the SL4A library.

    import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello Android!')\n

    See QSL4A Documentation for full API reference.

    "},{"location":"getting-started/#webapp-mode","title":"WebApp Mode","text":"

    Create web-based applications with a backend server. Add the following two headers at the beginning of your script:

    #qpy:webapp:<project name>\n#qpy://localhost:<port the web service listens on>/<default main path>\n

    Example:

    #qpy:webapp:Hello QPython\n#qpy://localhost:8080/hello\n\nfrom bottle import route, run, Bottle\n\napp = Bottle()\n\n@route('/hello')\ndef hello():\n    return '<h1>Hello from QPython!</h1>'\n\nrun(app, host='localhost', port=8080)\n

    "},{"location":"getting-started/#q-mode-quiet-mode","title":"Q Mode (Quiet Mode)","text":"

    Run scripts silently without displaying the console. Add header at the beginning of your script:

    #qpy:quiet\n\nimport time\n\nwhile True:\n    # Your background task\n    time.sleep(60)\n
    If you need to run a GUI-based SL4A program and don't want to show console information, this mode is recommended.

    "},{"location":"getting-started/#6-community-and-support","title":"6. Community and Support","text":"

    Visit QPython.org for documentation, user communities, and help.

    Community Links: - Facebook Group - GitHub - Report Issues

    Next Steps: - Try the Hello World Tutorial - Explore QSL4A API for Android integration - Learn about QPython Branches

    "},{"location":"getting-started/#video-introduction","title":"Video Introduction","text":""},{"location":"getting-started/#next-steps","title":"Next Steps","text":"

    If you've got a basic understanding of QPython's features, welcome to start experiencing the fun of programming! Try the Hello World Tutorial to take your first step.

    Thanks to dmych for the original draft on his blog

    "},{"location":"qpypi-guide/","title":"QPYPI","text":"

    You can extend your QPython capabilities by installing packages.

    "},{"location":"qpypi-guide/#package-installation-support","title":"Package Installation Support","text":""},{"location":"qpypi-guide/#pure-python-packages","title":"Pure Python Packages","text":"

    QPython supports Python packages developed with pure Python. You can install these packages directly using pip install through QPython's PIP Client or QPYPI on dashboard.

    "},{"location":"qpypi-guide/#pre-compiled-packages","title":"Pre-compiled Packages","text":"

    If some packages (or their dependencies) are developed with Rust/C/C++, QPython cannot support them directly because there is no compiler toolchain support on QPython. However, the QPython team has pre-compiled some commonly used packages and published them in QPython's QPYPI/Extensions for users to install easily.

    "},{"location":"qpypi-guide/#installing-pre-compiled-packages","title":"Installing Pre-compiled Packages","text":"

    You can install pre-compiled packages in the following ways:

    1. Through QPython App: Install directly from QPYPI or Extensions within the QPython app
    2. Through PyPI: Visit https://pypi.org/user/qpythonx/ to view available packages
    3. Via pip command:
    4. pip install xxx-qpython - Packages with the -qpython suffix
    5. pip install xxx-aipy - Packages with the -aipy suffix (typically AI/ML related packages)

    Note: We usually add one of these suffixes based on the package's intended use case.

    "},{"location":"qpypi-guide/#requesting-new-packages","title":"Requesting New Packages","text":"

    If you need a package that is not currently supported:

    • Raise an issue in the qpython.org project
    • The QPython team will consider pre-compiling and adding it to the repository

    For more ways to get help and engage with the community, see the Community & Feedback section.

    Note: Because of different computer architectures, we cannot guarantee that QPYPI includes all packages from PyPI.

    "},{"location":"qpython-x/","title":"QPython Branches","text":"

    QPython is the Python engine for Android. It contains amazing features such as Python interpreter, runtime environment, editor, QPYI and integrated SL4A. It makes it easy for you to use Python on Android. And it's FREE.

    QPython already has millions of users worldwide and it is also an open source project.

    For different usage scenarios, QPython has several branches:

    "},{"location":"qpython-x/#qpython","title":"QPython","text":"

    Standard Edition: Optimized for AI performance and universal app store compatibility

    The main version available on Google Play and other app stores. This version focuses on AI features, making it easier for users to learn and use Python in the AI era.

    Key Features: - AI-powered coding assistance and learning tools - Offline Python 3.12 interpreter: no Internet is required to run Python programs - Supports multiple project types: console, SL4A, webapp - Convenient QR code reader for transferring codes to your phone - QPYPI and custom repository for prebuilt wheel packages - Easy-to-use editor with syntax highlighting - Good documentation and community support

    Permissions: Requires only basic phone permissions for installation.

    Download: Available on Google Play and major app stores.

    "},{"location":"qpython-x/#qpython_1","title":"QPython+","text":"

    Community Edition: Openly supports various community-driven features; available on select app stores.

    The community open-source version (in planning and preparation). This version is designed for contributors who want to participate in QPython project development and supports customization for different manufacturers.

    Key Features: - Community-driven development - Support for vendor customization - More flexible configuration options - Open for contributors to join development

    Permissions: Requires only basic phone permissions for installation.

    Download: Will be available on Google Play and major app stores.

    Note: This version is currently in planning and preparation phase. Stay tuned for updates!

    "},{"location":"qpython-x/#qpython-plus","title":"QPython Plus","text":"

    QPython+ Full Access Edition: Grants complete permissions to call all Android interfaces. Download link available exclusively via the official cloud drive.

    A special version with extended permissions that provides maximum control over the device. This version is NOT published on app stores due to its sensitive permission requirements.

    Key Features: - Full SL4A API access including sensitive features - SMS/Call control APIs - Advanced system integration - Maximum device control capabilities

    Permissions: Requires extensive permissions including: - Bluetooth - Location (GPS) - Read/Send SMS - Call phone - Camera and microphone - System settings - And other sensitive permissions

    Download: Not available on app stores. Distributed through special channels only.

    Important: QPython will not use these permissions in background without your knowledge. If you get exceptions while using SL4A APIs, please check whether the relevant permissions are enabled in system settings.

    "},{"location":"tutorial-hello-world/","title":"Writing \"Hello World\"","text":""},{"location":"tutorial-hello-world/#hello-world","title":"Hello world","text":"

    Well, after you became a bit more familiar with QPython, let's create our first program in QPython. Obviously, it will be helloworld.py. ;)

    Start QPython, open editor and enter the following code:

    import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello, Username!')\n

    No wonder, it's just similar to any other hello-world program. When executed, it just shows pop-up message on the screen (see screenshot on the top). Anyway, it's a good example of QPython program.

    "},{"location":"tutorial-hello-world/#sl4a-library","title":"SL4A library","text":"

    It begins with import androidhelper \u2014 the most useful module in QPython, which encapsulates almost all interface with Android, available in Python. Any script developed in QPython starts with this statement (at least if it claims to communicate with user). Read more about Python library here and import statement here.

    By the way, if you're going to make your script compatible with SL4A, you should replace the first line with the following code (and use android instead androidhelper further in the program):

    try:\n    import androidhelper as android\nexcept ImportError:\n    import android\n

    Ok, next we're creating an object droid (actually a class), it is necessary to call RPC functions in order to communicate with Android.

    And the last line of our code calls such function, droid.makeToast(), which shows a small pop-up message (a \"toast\") on the screen.

    Well, let's add some more functionality. Let it ask the user name and greet them.

    "},{"location":"tutorial-hello-world/#more-samples","title":"More samples","text":"

    We can display a simple dialog box with the title, prompt, edit field and buttons Ok and Cancel using dialogGetInput call. Replace the last line of your code and save it as hello1.py:

    import androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\n

    Well, I think it should return any respond, any user reaction. That's why I wrote respond = .... But what the call actually returns? Let's check. Just add print statement after the last line:

    import androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\n

    Then save and run it...

    Oops! Nothing printed? Don't worry. Just pull notification bar and you will see \"QPython Program Output: hello1.py\" \u2014 tap it!

    As you can see, droid.dialogGetInput() returns a JSON object with three fields. We need only one \u2014 result which contains an actual input from user.

    Let's add script's reaction:

    import androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nmessage = f'Hello, {respond.result}!'\ndroid.makeToast(message)\n

    Last two lines (1) format the message and (2) show the message to the user in the toast. See Python docs if you still don't know what f-strings mean.

    Wow! It works! ;)

    Now I'm going to add a bit of logic there. Think: what happen if the user clicks Cancel button, or clicks Ok leaving the input field blank?

    You can play with the program checking what contains respond variable in every case.

    First of all, I want to put text entered by user to a separate variable: name = respond.result. Then I'm going to check it, and if it contains any real text, it will be considered as a name and will be used in greeting. Otherwise another message will be shown. Replace fifth line message = f'Hello, {respond.result}!' with the following code:

    name = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\n

    Use < and > buttons on the toolbar to indent/unindent lines in if-statement (or just use space/backspace keys). You can read more about indentation in Python here; if-statement described here.

    First of all, we put user input to the variable name. Then we check does name contain anything? In case the user left the line blank and clicked Ok, the return value is empty string ''. In case of Cancel button pressed, the return value is None. Both are treated as false in if-statement. So, only if name contains anything meaningful, then-statement is executed and greeting \"Hello, ...!\" shown. In case of empty input the user will see \"Hey! And you're not very polite, %Username%!\" message.

    Ok, here is the whole program:

    import androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nname = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\ndroid.makeToast(message)\n

    Thanks dmych offer the first draft in his blog

    "},{"location":"whats-new/","title":"What's New","text":""},{"location":"whats-new/#v392-v393","title":"v3.9.2 / v3.9.3","text":"
    • SDK upgrade with support for 16 KB page size, providing a smoother runtime environment
    • Major editor updates for a more fluid editing experience
    • Various other minor improvements
    "},{"location":"whats-new/#v391","title":"v3.9.1","text":"
    • SDK upgrade with support for 16 KB page size, providing a smoother runtime environment
    • Extension packages now support MCP
    • Bug fixes
    "},{"location":"whats-new/#v390","title":"v3.9.0","text":"
    • SDK upgrade to incorporate the latest Android features
    • Built-in Ollama 0.9.5 upgrade: Now supports running Gemma3n models locally in QPython, experiencing more powerful on-device AI computing capabilities
    • Pygame game development support: Combined with XServer, you can now easily write and run Pygame games on QPython, unleashing your creativity!
    • Personalized icon customization: Customize your desktop icons and themes through QPython settings, creating a unique programming environment
    "},{"location":"whats-new/#v3811","title":"v3.8.11","text":"
    • Built-in Ollama 0.9.5 upgrade: Now supports running Gemma3n models locally in QPython, experiencing more powerful on-device AI computing capabilities
    • Pygame game development support: Combined with XServer, you can now easily write and run Pygame games on QPython, unleashing your creativity!
    • Personalized icon customization: Customize your desktop icons and themes through QPython settings, creating a unique programming environment
    "},{"location":"whats-new/#v3810","title":"v3.8.10","text":"
    • Built-in Ollama upgrade: Now you can easily run Qwen3 / Gemma3 models locally in QPython!
    • Powerful MCP library added: Added mcp library in Extensions -> AIPY, allowing you to take powerful MCP functionality with you anywhere, anytime!
    "},{"location":"whats-new/#v389","title":"v3.8.9","text":"

    Major update! AI programming fully integrated into QPython to make your programming easier!

    • Natural language programming support: New support for AIPyApp, enabling natural language programming in QPython. Currently in beta - join our community for usage instructions
    • New QSL4A feature: Added notebookOpen function, supporting natural language control to open Notebook files
    • Built-in editor upgrade: Enhanced editor functionality, supporting opening and browsing various text files
    • Convenient file management: Added internal storage entry in file manager for quick access to your files
    "},{"location":"whats-new/#v388","title":"v3.8.8","text":"
    • Important improvements to file access permission controls, allowing users to flexibly enable or disable access to external storage files through QPython programming
    • SDK upgraded to enhance support and compatibility with newer Android versions
    • Added Anthropic and Google GenAI libraries in Extensions -> AIPY
    "},{"location":"whats-new/#v387","title":"v3.8.7","text":"
    • Based on existing Tkinter support, added sample code for drawing Doraemon using Turtle in Extensions -> Tools
    • Optimized phone permission acquisition process, improving user experience and operational convenience
    • Added Google Gen AI library in Extensions -> AIPY for easy access to Gemini Developer API and Vertex AI
    "},{"location":"whats-new/#v386","title":"v3.8.6","text":"
    • Tkinter support: Now supports Tkinter library, accessible through XServer. Please visit www.qpython.org's drive link \"Extra\" to download required files
    • Storage permission update: To improve user experience, we added permission to read phone storage for accessing Python programs stored in other directories

    After this update, QPython and QPythonPlus (not available on app stores, designed for advanced users with more sensitive permissions) will maintain synchronized version numbers.

    "},{"location":"whats-new/#v352-2025225","title":"v3.5.2 (2025/2/25)","text":"

    Achieve seamless integration with the open source LLM deployment tool Ollama and DeepSeek developed by DeepSeek!

    Features: - Zero threshold to run various large language models locally on mobile devices - Quickly deploy cutting-edge AI models such as DeepSeek - Enjoy a minimalist API calling experience - Build a completely offline intelligent programming environment

    Capabilities: - Load/manage LLM models directly on the mobile phone - Real-time low-latency response based on local computing

    "},{"location":"whats-new/#v350","title":"v3.5.0","text":"
    • Python upgraded to 3.12.8
    • Improved Dashboard for clearer, more user-friendly functionality
    • Added numerous third-party packages: PyTorch / Twisted / Scrapy / FastAPI ...
    "},{"location":"whats-new/#v338","title":"v3.3.8","text":"
    • Fixed NumPy compatibility issues
    "},{"location":"whats-new/#v335","title":"v3.3.5","text":"
    • Upgraded Python kernel to 3.11.9
    • Fixed bug where module installation status was not displayed in extensions
    • Fixed bug where deleting modules in extensions failed
    • Fixed other bugs
    "},{"location":"whats-new/#v334","title":"v3.3.4","text":"
    • Added OpenAI/Langchain/APIGPTCloud AI packages
    • Removed unnecessary files to reduce size
    "},{"location":"whats-new/#v325","title":"v3.2.5","text":"
    • Added some SL4A functions
    • Other bug fixes
    "},{"location":"whats-new/#v323","title":"v3.2.3","text":"
    • Updated Python version to 3.11.0
    • Updated IPython version to 8.6.0
    • Updated pip version to 22.3.1
    • Updated scientific computing packages with automatic soft links
    • Reduced space usage
    • Added some SL4A functions + other bug fixes
    "},{"location":"whats-new/#v318","title":"v3.1.8","text":"
    • Added operation hotkeys in terminal
    • Fixed issue where editor lost content on rotation
    • Fixed other bugs

    Download on Google Play

    "},{"location":"qsl4a/","title":"QSL4A (Scripting Layer for Android) API Documentation","text":"

    QSL4A is QPython's scripting layer for Android, allowing you to control Android device features using Python.

    "},{"location":"qsl4a/#quick-start","title":"Quick Start","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Show a toast message\ndroid.makeToast('Hello QPython!')\n\n# Vibrate the device\ndroid.vibrate(500)\n\n# Get battery level (start monitoring first)\nimport time\ndroid.batteryStartMonitoring()\ntime.sleep(0.5)  # Wait for data\nbattery = droid.readBatteryData().result\nprint(f\"Battery: {battery['level']}%\")\n
    "},{"location":"qsl4a/#documentation-structure","title":"Documentation Structure","text":""},{"location":"qsl4a/#core-modules","title":"Core Modules","text":"
    • Android Base - Core connection and RPC
    • Intent System - Android Intent operations
    • Event System - Event handling and broadcasting
    "},{"location":"qsl4a/#ui-components","title":"UI Components","text":"
    • Dialogs - Alert, input, choice dialogs
    • FullScreen UI - Custom layout UI
    • FloatView - Floating window
    • Accessibility - Screen automation
    "},{"location":"qsl4a/#system","title":"System","text":"
    • Battery - Battery monitoring
    • Sensors - Device sensors
    • Application - App management
    • System Info - Device information
    • Settings - System settings
    • WakeLock - Wake lock control
    • QPython Interface - Script execution
    • Activity Result - Activity result handling
    "},{"location":"qsl4a/#hardware","title":"Hardware","text":"
    • Bluetooth - Bluetooth operations
    • Camera - Photo and video capture
    • Audio/Recorder - Audio recording
    • Webcam - MJPEG streaming
    • USB Serial - USB host serial
    "},{"location":"qsl4a/#connectivity","title":"Connectivity","text":"
    • WiFi - WiFi operations
    • Location - GPS and location
    • SMS - SMS operations
    • Phone - Phone calls and info
    • Contacts - Contact management
    • Signal Strength - Signal monitoring
    • FTP Server - Built-in FTP server
    "},{"location":"qsl4a/#storage","title":"Storage","text":"
    • DocumentFile - File operations
    • Clipboard - Clipboard operations
    • Preferences - Shared preferences
    "},{"location":"qsl4a/#media","title":"Media","text":"
    • Media Player - Audio/Video playback
    • Image Processing - Image operations
    "},{"location":"qsl4a/#special-features","title":"Special Features","text":"
    • Cipher - Encryption/Decryption
    • PGPT AI - AI speech services
    "},{"location":"qsl4a/#result-object","title":"Result Object","text":"

    Most QSL4A methods return a Result namedtuple with: - id - Request ID - result - The actual result data - error - Error message if failed

    result = droid.getClipboard()\nif result.error is None:\n    print(result.result)\nelse:\n    print(f\"Error: {result.error}\")\n
    "},{"location":"qsl4a/connectivity/contacts/","title":"Contacts API","text":"

    Access and manage device contacts.

    "},{"location":"qsl4a/connectivity/contacts/#contact-picking","title":"Contact Picking","text":""},{"location":"qsl4a/connectivity/contacts/#pickcontact","title":"pickContact()","text":"

    Display a list of contacts to pick from.

    pickContact()\n

    Returns: Intent with contact URI

    "},{"location":"qsl4a/connectivity/contacts/#pickphone","title":"pickPhone()","text":"

    Display a list of phone numbers to pick from.

    pickPhone()\n

    Returns: Selected phone number string

    "},{"location":"qsl4a/connectivity/contacts/#contact-queries","title":"Contact Queries","text":""},{"location":"qsl4a/connectivity/contacts/#contactsget","title":"contactsGet()","text":"

    Get all contacts.

    contactsGet(attributes=None)\n

    Parameters: - attributes (list, optional): Specific attributes to retrieve

    Returns: List of contact JSONObject

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetbyid","title":"contactsGetById()","text":"

    Get a contact by ID.

    contactsGetById(id, attributes=None)\n

    Parameters: - id (int): Contact ID - attributes (list, optional): Specific attributes to retrieve

    Returns: JSONObject contact data

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetcount","title":"contactsGetCount()","text":"

    Get the total number of contacts.

    contactsGetCount()\n

    Returns: Integer count

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetids","title":"contactsGetIds()","text":"

    Get all contact IDs.

    contactsGetIds()\n

    Returns: List of contact ID integers

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetattributes","title":"contactsGetAttributes()","text":"

    Get all possible contact attributes.

    contactsGetAttributes()\n

    Returns: List of attribute names

    "},{"location":"qsl4a/connectivity/contacts/#content-queries","title":"Content Queries","text":""},{"location":"qsl4a/connectivity/contacts/#querycontent","title":"queryContent()","text":"

    Query content resolver with custom parameters.

    queryContent(uri, attributes=None, selection=None, selectionArgs=None, order=None)\n

    Parameters: - uri (str): Content URI - attributes (list, optional): Attributes to retrieve - selection (str, optional): WHERE clause - selectionArgs (list, optional): Selection arguments - order (str, optional): ORDER BY clause

    Returns: List of JSONObject results

    "},{"location":"qsl4a/connectivity/contacts/#queryattributes","title":"queryAttributes()","text":"

    Get attributes for a content URI.

    queryAttributes(uri)\n

    Parameters: - uri (str): Content URI

    Returns: JSONArray of attribute names

    "},{"location":"qsl4a/connectivity/contacts/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Pick a contact\ncontact_uri = droid.pickContact().result\nprint(f\"Selected contact: {contact_uri}\")\n\n# Pick a phone number\nphone = droid.pickPhone().result\nprint(f\"Selected phone: {phone}\")\n\n# Get all contacts\ncontacts = droid.contactsGet().result\nprint(f\"Total contacts: {len(contacts)}\")\n\n# Get contact by ID\ncontact = droid.contactsGetById(1).result\nprint(f\"Contact: {contact}\")\n\n# Get contact attributes\nattrs = droid.contactsGetAttributes().result\nprint(f\"Available attributes: {attrs}\")\n
    "},{"location":"qsl4a/connectivity/ftp/","title":"FTP Server API","text":"

    Start and manage a built-in FTP server on the device.

    "},{"location":"qsl4a/connectivity/ftp/#ftp-server-methods","title":"FTP Server Methods","text":""},{"location":"qsl4a/connectivity/ftp/#ftpstart","title":"ftpStart()","text":"

    Start the FTP server.

    ftpStart()\n

    Returns: Array containing IP address and port [ip, port]

    "},{"location":"qsl4a/connectivity/ftp/#ftpstop","title":"ftpStop()","text":"

    Stop the FTP server.

    ftpStop()\n
    "},{"location":"qsl4a/connectivity/ftp/#ftpisrunning","title":"ftpIsRunning()","text":"

    Check if FTP server is running.

    ftpIsRunning()\n

    Returns: True if running

    "},{"location":"qsl4a/connectivity/ftp/#ftpget","title":"ftpGet()","text":"

    Get FTP server IP address.

    ftpGet()\n

    Returns: Array with IP address and port

    "},{"location":"qsl4a/connectivity/ftp/#ftpset","title":"ftpSet()","text":"

    Configure FTP server settings.

    ftpSet(port=None, rootDir=None, username=None, password=None)\n

    Parameters: - port (int, optional): Server port - rootDir (str, optional): Root directory to serve - username (str, optional): Login username - password (str, optional): Login password

    Returns: JSONObject with current settings

    "},{"location":"qsl4a/connectivity/ftp/#ftpstatus","title":"ftpStatus()","text":"

    Get FTP server status.

    ftpStatus()\n

    Returns: String status description

    "},{"location":"qsl4a/connectivity/ftp/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Configure FTP server\ndroid.ftpSet(\n    port=2121,\n    rootDir=\"/sdcard\",\n    username=\"admin\",\n    password=\"secret\"\n)\n\n# Start FTP server\ninfo = droid.ftpStart().result\nprint(f\"FTP running at {info[0]}:{info[1]}\")\n\n# Check status\nif droid.ftpIsRunning().result:\n    print(\"FTP server is running\")\n\n# Get server info\nserver_info = droid.ftpGet().result\nprint(f\"Server: {server_info}\")\n\n# Stop when done\ndroid.ftpStop()\n

    Note: Connect to the FTP server using any FTP client with the provided credentials.

    "},{"location":"qsl4a/connectivity/location/","title":"Location API","text":"

    Access GPS and network location services.

    "},{"location":"qsl4a/connectivity/location/#methods","title":"Methods","text":""},{"location":"qsl4a/connectivity/location/#startlocating","title":"startLocating()","text":"

    Start location updates.

    startLocating(minUpdateTime=60000, minUpdateDistance=30, updateGnssStatus=False)\n

    Parameters: - minUpdateTime (int): Minimum time between updates in milliseconds (default: 60000) - minUpdateDistance (float): Minimum distance for update in meters (default: 30) - updateGnssStatus (bool): Enable GNSS status updates (default: False)

    "},{"location":"qsl4a/connectivity/location/#stoplocating","title":"stopLocating()","text":"

    Stop location updates.

    stopLocating()\n
    "},{"location":"qsl4a/connectivity/location/#readlocation","title":"readLocation()","text":"

    Get last known location.

    readLocation()\n

    Returns: Location data dict

    "},{"location":"qsl4a/connectivity/location/#getlastknownlocation","title":"getLastKnownLocation()","text":"

    Get cached location.

    getLastKnownLocation()\n

    Returns: Location from all providers

    "},{"location":"qsl4a/connectivity/location/#geocode","title":"geocode()","text":"

    Convert address to coordinates.

    geocode(address, maxResults=1)\n
    "},{"location":"qsl4a/connectivity/location/#location-provider-methods","title":"Location Provider Methods)","text":""},{"location":"qsl4a/connectivity/location/#locationproviders","title":"locationProviders()","text":"

    Get available location providers on the phone.

    locationProviders()\n

    Returns: List of available provider names (e.g., ['gps', 'network'])

    "},{"location":"qsl4a/connectivity/location/#locationproviderenabled","title":"locationProviderEnabled()","text":"

    Check if a specific location provider is enabled.

    locationProviderEnabled(provider)\n

    Parameters: - provider (str): Provider name (e.g., 'gps', 'network')

    Returns: True if enabled, False otherwise

    "},{"location":"qsl4a/connectivity/location/#readgnssstatus","title":"readGnssStatus()","text":"

    Read Global Navigation Satellite System status (requires Android 8+).

    readGnssStatus()\n

    Returns: JSONArray containing GNSS satellite information

    "},{"location":"qsl4a/connectivity/location/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start location updates\ndroid.startLocating(minUpdateTime=5000, minUpdateDistance=1, updateGnssStatus=False)\n\n# Wait for fix\ntime.sleep(10)\n\n# Get location\nloc = droid.readLocation().result\nif loc:\n    lat = loc['latitude']\n    lon = loc['longitude']\n    print(f\"Location: {lat}, {lon}\")\n\ndroid.stopLocating()\n
    "},{"location":"qsl4a/connectivity/phone/","title":"Phone API","text":"

    Control phone calls and retrieve phone information.

    "},{"location":"qsl4a/connectivity/phone/#phone-state-tracking","title":"Phone State Tracking","text":""},{"location":"qsl4a/connectivity/phone/#starttrackingphonestate","title":"startTrackingPhoneState()","text":"

    Start tracking phone state changes. Generates 'phone' events.

    startTrackingPhoneState()\n
    "},{"location":"qsl4a/connectivity/phone/#readphonestate","title":"readPhoneState()","text":"

    Read the current phone state.

    readPhoneState()\n

    Returns: Bundle with phone state and incoming number

    "},{"location":"qsl4a/connectivity/phone/#stoptrackingphonestate","title":"stopTrackingPhoneState()","text":"

    Stop tracking phone state.

    stopTrackingPhoneState()\n
    "},{"location":"qsl4a/connectivity/phone/#making-calls","title":"Making Calls","text":""},{"location":"qsl4a/connectivity/phone/#phonecall","title":"phoneCall()","text":"

    Call a contact/phone number by URI.

    phoneCall(uri)\n

    Parameters: - uri (str): Contact URI or phone number URI

    "},{"location":"qsl4a/connectivity/phone/#phonecallnumber","title":"phoneCallNumber()","text":"

    Call a phone number directly.

    phoneCallNumber(phone_number)\n

    Parameters: - phone_number (str): Phone number to call

    "},{"location":"qsl4a/connectivity/phone/#phonedial","title":"phoneDial()","text":"

    Dial a number (opens dialer without calling).

    phoneDial(uri)\n

    Parameters: - uri (str): Contact URI or phone number URI

    "},{"location":"qsl4a/connectivity/phone/#phonedialnumber","title":"phoneDialNumber()","text":"

    Dial a phone number (opens dialer without calling).

    phoneDialNumber(phone_number)\n

    Parameters: - phone_number (str): Phone number

    "},{"location":"qsl4a/connectivity/phone/#cell-location","title":"Cell Location","text":""},{"location":"qsl4a/connectivity/phone/#getcelllocation","title":"getCellLocation()","text":"

    Get the current cell location.

    getCellLocation()\n

    Returns: JSONObject with cell location data

    "},{"location":"qsl4a/connectivity/phone/#getallcellslocation","title":"getAllCellsLocation()","text":"

    Get all cell locations (for dual SIM devices).

    getAllCellsLocation()\n

    Returns: JSONArray of cell locations

    "},{"location":"qsl4a/connectivity/phone/#network-information","title":"Network Information","text":""},{"location":"qsl4a/connectivity/phone/#getnetworkoperator","title":"getNetworkOperator()","text":"

    Get the MCC+MNC of the current operator.

    getNetworkOperator()\n

    Returns: String (e.g., '310260')

    "},{"location":"qsl4a/connectivity/phone/#getnetworkoperatorname","title":"getNetworkOperatorName()","text":"

    Get the name of the current operator.

    getNetworkOperatorName()\n

    Returns: String (e.g., 'T-Mobile')

    "},{"location":"qsl4a/connectivity/phone/#getnetworktype","title":"getNetworkType()","text":"

    Get the current network type.

    getNetworkType()\n

    Returns: String describing radio technology (e.g., 'LTE', 'UMTS', 'GSM')

    "},{"location":"qsl4a/connectivity/phone/#getphonetype","title":"getPhoneType()","text":"

    Get the phone type.

    getPhoneType()\n

    Returns: String (e.g., 'GSM', 'CDMA', 'SIP')

    "},{"location":"qsl4a/connectivity/phone/#sim-information","title":"SIM Information","text":""},{"location":"qsl4a/connectivity/phone/#getsimcountryiso","title":"getSimCountryIso()","text":"

    Get the ISO country code for the SIM.

    getSimCountryIso()\n

    Returns: String (e.g., 'us')

    "},{"location":"qsl4a/connectivity/phone/#getsimoperator","title":"getSimOperator()","text":"

    Get the MCC+MNC of the SIM operator.

    getSimOperator()\n

    Returns: String (e.g., '310260')

    "},{"location":"qsl4a/connectivity/phone/#getsimoperatorname","title":"getSimOperatorName()","text":"

    Get the SIM operator name.

    getSimOperatorName()\n

    Returns: String (e.g., 'T-Mobile')

    "},{"location":"qsl4a/connectivity/phone/#getsimserialnumber","title":"getSimSerialNumber()","text":"

    Get the SIM serial number.

    getSimSerialNumber()\n

    Returns: String SIM serial number

    "},{"location":"qsl4a/connectivity/phone/#getsimstate","title":"getSimState()","text":"

    Get the SIM card state.

    getSimState()\n

    Returns: String describing SIM state

    "},{"location":"qsl4a/connectivity/phone/#getsubscriberid","title":"getSubscriberId()","text":"

    Get the subscriber ID.

    getSubscriberId()\n

    Returns: String subscriber ID

    "},{"location":"qsl4a/connectivity/phone/#voice-mail","title":"Voice Mail","text":""},{"location":"qsl4a/connectivity/phone/#getvoicemailalphatag","title":"getVoiceMailAlphaTag()","text":"

    Get the voice mail alpha tag.

    getVoiceMailAlphaTag()\n

    Returns: String voice mail tag

    "},{"location":"qsl4a/connectivity/phone/#getvoicemailnumber","title":"getVoiceMailNumber()","text":"

    Get the voice mail number.

    getVoiceMailNumber()\n

    Returns: String voice mail number

    "},{"location":"qsl4a/connectivity/phone/#device-information","title":"Device Information","text":""},{"location":"qsl4a/connectivity/phone/#getdeviceid","title":"getDeviceId()","text":"

    Get the device ID (IMEI for GSM). Deprecated.

    getDeviceId()\n

    Returns: String device ID

    "},{"location":"qsl4a/connectivity/phone/#getdevicesoftwareversion","title":"getDeviceSoftwareVersion()","text":"

    Get the device software version.

    getDeviceSoftwareVersion()\n

    Returns: String software version

    "},{"location":"qsl4a/connectivity/phone/#getline1number","title":"getLine1Number()","text":"

    Get the line 1 phone number.

    getLine1Number()\n

    Returns: String phone number

    "},{"location":"qsl4a/connectivity/phone/#checknetworkroaming","title":"checkNetworkRoaming()","text":"

    Check if connected to roaming network.

    checkNetworkRoaming()\n

    Returns: True if roaming

    "},{"location":"qsl4a/connectivity/phone/#cell-info","title":"Cell Info","text":""},{"location":"qsl4a/connectivity/phone/#getallcellinfo","title":"getAllCellInfo()","text":"

    Get information about all cells.

    getAllCellInfo()\n

    Returns: List of cell information

    "},{"location":"qsl4a/connectivity/phone/#setdataenabled","title":"setDataEnabled()","text":"

    Enable or disable mobile data.

    setDataEnabled(enabled)\n

    Parameters: - enabled (bool): True to enable, False to disable

    "},{"location":"qsl4a/connectivity/phone/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get network info\noperator = droid.getNetworkOperatorName().result\nprint(f\"Operator: {operator}\")\n\nnetwork_type = droid.getNetworkType().result\nprint(f\"Network: {network_type}\")\n\n# Get SIM info\nsim_state = droid.getSimState().result\nprint(f\"SIM: {sim_state}\")\n\n# Get phone number\nline1 = droid.getLine1Number().result\nprint(f\"Phone: {line1}\")\n\n# Track phone state\ndroid.startTrackingPhoneState()\nprint(\"Tracking phone state...\")\ndroid.stopTrackingPhoneState()\n
    "},{"location":"qsl4a/connectivity/signalstrength/","title":"Signal Strength API","text":"

    Monitor cellular and wireless signal strength.

    "},{"location":"qsl4a/connectivity/signalstrength/#signal-strength-methods","title":"Signal Strength Methods","text":""},{"location":"qsl4a/connectivity/signalstrength/#starttrackingsignalstrengths","title":"startTrackingSignalStrengths()","text":"

    Start tracking signal strength changes. Generates 'signal_strengths' events.

    startTrackingSignalStrengths()\n
    "},{"location":"qsl4a/connectivity/signalstrength/#stoptrackingsignalstrengths","title":"stopTrackingSignalStrengths()","text":"

    Stop tracking signal strengths.

    stopTrackingSignalStrengths()\n
    "},{"location":"qsl4a/connectivity/signalstrength/#readsignalstrengths","title":"readSignalStrengths()","text":"

    Read the current signal strengths.

    readSignalStrengths()\n

    Returns: Bundle with signal strength data

    "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthlevel","title":"getTelephoneSignalStrengthLevel()","text":"

    Get the telephone signal strength as a level (0-4).

    getTelephoneSignalStrengthLevel()\n

    Returns: Integer level (0=none, 1=poor, 2=fair, 3=good, 4=excellent)

    "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthdetail","title":"getTelephoneSignalStrengthDetail()","text":"

    Get detailed telephone signal strength information.

    getTelephoneSignalStrengthDetail()\n

    Returns: String with detailed signal info

    "},{"location":"qsl4a/connectivity/signalstrength/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start tracking signal strength\ndroid.startTrackingSignalStrengths()\n\n# Wait for signal updates\ntime.sleep(5)\n\n# Read current signal strength\nsignal = droid.readSignalStrengths().result\nprint(f\"Signal: {signal}\")\n\n# Get level directly\nlevel = droid.getTelephoneSignalStrengthLevel().result\nprint(f\"Signal level: {level}/4\")\n\ndroid.stopTrackingSignalStrengths()\n
    "},{"location":"qsl4a/connectivity/sms/","title":"SMS API","text":"

    Send and receive SMS messages.

    "},{"location":"qsl4a/connectivity/sms/#methods","title":"Methods","text":""},{"location":"qsl4a/connectivity/sms/#smssend","title":"smsSend()","text":"

    Send SMS message.

    smsSend(destinationAddress, text)\n

    Parameters: - destinationAddress (str): Phone number - text (str): Message text

    "},{"location":"qsl4a/connectivity/sms/#smsgetmessagecount","title":"smsGetMessageCount()","text":"

    Get message count.

    smsGetMessageCount(unreadOnly=False, folder=\"inbox\")\n
    "},{"location":"qsl4a/connectivity/sms/#smsgetmessageids","title":"smsGetMessageIds()","text":"

    Get message IDs.

    smsGetMessageIds(unreadOnly=False, folder=\"inbox\")\n
    "},{"location":"qsl4a/connectivity/sms/#smsgetmessages","title":"smsGetMessages()","text":"

    Get message details.

    smsGetMessages(unreadOnly=False, folder=\"inbox\", attributes=None)\n
    "},{"location":"qsl4a/connectivity/sms/#smsgetmessagebyid","title":"smsGetMessageById()","text":"

    Get a specific message by ID.

    smsGetMessageById(id, attributes=None)\n

    Parameters: - id (int): Message ID - attributes (list, optional): Specific attributes to retrieve

    Returns: Message data dict

    "},{"location":"qsl4a/connectivity/sms/#smsgetattributes","title":"smsGetAttributes()","text":"

    Get available SMS message attributes.

    smsGetAttributes()\n

    Returns: List of available attribute names

    "},{"location":"qsl4a/connectivity/sms/#smsdeletemessage","title":"smsDeleteMessage()","text":"

    Delete message.

    smsDeleteMessage(id)\n
    "},{"location":"qsl4a/connectivity/sms/#smsmarkmessageread","title":"smsMarkMessageRead()","text":"

    Mark message as read.

    smsMarkMessageRead(ids, read=True)\n
    "},{"location":"qsl4a/connectivity/sms/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Send SMS\ndroid.smsSend(\"+1234567890\", \"Hello from QPython!\")\n\n# Get unread messages\nmessages = droid.smsGetMessages(unreadOnly=True).result\nfor msg in messages:\n    print(f\"From: {msg['address']}, Text: {msg['body']}\")\n
    "},{"location":"qsl4a/connectivity/wifi/","title":"WiFi API","text":"

    Control WiFi adapter and get connection information.

    "},{"location":"qsl4a/connectivity/wifi/#adapter-control","title":"Adapter Control","text":""},{"location":"qsl4a/connectivity/wifi/#checkwifistate","title":"checkWifiState()","text":"

    Check if WiFi is enabled.

    checkWifiState()\n

    Returns: True if WiFi is enabled, False otherwise

    "},{"location":"qsl4a/connectivity/wifi/#togglewifistate","title":"toggleWifiState()","text":"

    Turn WiFi on or off.

    toggleWifiState(enabled=None)\n

    Parameters: - enabled (bool): True to enable, False to disable, None to toggle

    Returns: True if operation succeeded

    "},{"location":"qsl4a/connectivity/wifi/#wifistartscan","title":"wifiStartScan()","text":"

    Start scanning for available WiFi networks.

    wifiStartScan()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifigetscanresults","title":"wifiGetScanResults()","text":"

    Get list of discovered WiFi networks.

    wifiGetScanResults()\n

    Returns: List of access point information

    "},{"location":"qsl4a/connectivity/wifi/#connection-management","title":"Connection Management","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetconnectioninfo","title":"wifiGetConnectionInfo()","text":"

    Get detailed connection information.

    wifiGetConnectionInfo()\n

    Returns: Dict with connection details including SSID, BSSID, IP address

    "},{"location":"qsl4a/connectivity/wifi/#getconnectedinfo","title":"getConnectedInfo()","text":"

    Get connected WiFi network info (simplified).

    getConnectedInfo()\n

    Returns: Dict with SSID, BSSID, signal strength

    "},{"location":"qsl4a/connectivity/wifi/#getdhcpinfo","title":"getDhcpInfo()","text":"

    Get DHCP information for current connection.

    getDhcpInfo(ipConvertToString=True)\n

    Parameters: - ipConvertToString (bool): Convert IP addresses to string format (default: True)

    Returns: Dict with DHCP info including IP, gateway, DNS

    "},{"location":"qsl4a/connectivity/wifi/#wifidisconnect","title":"wifiDisconnect()","text":"

    Disconnect from current WiFi network.

    wifiDisconnect()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifireconnect","title":"wifiReconnect()","text":"

    Reconnect to the current network.

    wifiReconnect()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifireassociate","title":"wifiReassociate()","text":"

    Reassociate with the current access point.

    wifiReassociate()\n
    "},{"location":"qsl4a/connectivity/wifi/#hotspot","title":"Hotspot","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetapstate","title":"wifiGetApState()","text":"

    Get WiFi AP (hotspot) state.

    wifiGetApState()\n

    Returns: Hotspot state

    "},{"location":"qsl4a/connectivity/wifi/#wifi-locks","title":"WiFi Locks","text":""},{"location":"qsl4a/connectivity/wifi/#wifilockacquirefull","title":"wifiLockAcquireFull()","text":"

    Acquire a full WiFi lock (keeps WiFi active even when screen is off).

    wifiLockAcquireFull()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifilockacquirescanonly","title":"wifiLockAcquireScanOnly()","text":"

    Acquire a scan-only WiFi lock.

    wifiLockAcquireScanOnly()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifilockrelease","title":"wifiLockRelease()","text":"

    Release the WiFi lock.

    wifiLockRelease()\n
    "},{"location":"qsl4a/connectivity/wifi/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Check WiFi state\nif droid.checkWifiState().result:\n    print(\"WiFi is enabled\")\nelse:\n    print(\"Enabling WiFi...\")\n    droid.toggleWifiState(True)\n    time.sleep(2)\n\n# Start scanning\ndroid.wifiStartScan()\ntime.sleep(3)\n\n# Get scan results\nnetworks = droid.wifiGetScanResults().result\nfor network in networks:\n    print(f\"SSID: {network.get('SSID')}, Signal: {network.get('level')} dBm\")\n\n# Get connection info\ninfo = droid.wifiGetConnectionInfo().result\nif info:\n    print(f\"Connected to: {info.get('ssid')}\")\n    print(f\"BSSID: {info.get('bssid')}\")\n    print(f\"IP: {info.get('ip_address')}\")\n\n# Get DHCP info\ndhcp = droid.getDhcpInfo().result\nif dhcp:\n    print(f\"Gateway: {dhcp.get('gateway')}\")\n    print(f\"DNS: {dhcp.get('dns1')}\")\n\n# Get simplified connected info\nconnected = droid.getConnectedInfo().result\nprint(f\"SSID: {connected.get('ssid')}, Signal: {connected.get('level')} dBm\")\n\n# Disconnect and reconnect\ndroid.wifiDisconnect()\ntime.sleep(1)\ndroid.wifiReconnect()\n\n# Reassociate with access point\ndroid.wifiReassociate()\n\n# Check hotspot state\nap_state = droid.wifiGetApState().result\nprint(f\"Hotspot state: {ap_state}\")\n\n# Acquire WiFi lock for background operation\ndroid.wifiLockAcquireFull()\n# ... do work ...\ndroid.wifiLockRelease()\n\n# Or use scan-only lock for lighter background operation\ndroid.wifiLockAcquireScanOnly()\n# ... do scanning work ...\ndroid.wifiLockRelease()\n
    "},{"location":"qsl4a/core/android-base/","title":"Android Base Class","text":"

    The Android class is the core of QSL4A, providing the connection to the Android runtime and RPC mechanism.

    "},{"location":"qsl4a/core/android-base/#module-import","title":"Module Import","text":"
    # Full featured (recommended)\nimport androidhelper\ndroid = androidhelper.Android()\n\n# Minimal version (quick, single instance)\nimport android\ndroid = android.droid\n
    "},{"location":"qsl4a/core/android-base/#class-android","title":"Class: Android","text":""},{"location":"qsl4a/core/android-base/#constructor","title":"Constructor","text":"
    Android(addr=None)\n

    Parameters: - addr (tuple, optional): (HOST, PORT) address. If None, uses environment variables AP_HOST and AP_PORT

    Environment Variables: - AP_HOST - Server host address - AP_PORT - Server port - AP_HANDSHAKE - Authentication token

    "},{"location":"qsl4a/core/android-base/#core-methods","title":"Core Methods","text":""},{"location":"qsl4a/core/android-base/#_rpc","title":"_rpc()","text":"

    Internal RPC method for calling Android functions.

    _rpc(method, *args)\n

    Parameters: - method (str): Method name to call - *args: Variable arguments for the method

    Returns: Result namedtuple with fields: - id (int): Request ID - result: Method return value - error (str or None): Error message if failed

    "},{"location":"qsl4a/core/android-base/#getattr","title":"getattr()","text":"

    Dynamic method dispatcher. All Android methods are accessed via attribute lookup.

    # These are equivalent:\ndroid.makeToast(\"Hello\")\ndroid._rpc(\"makeToast\", \"Hello\")\n
    "},{"location":"qsl4a/core/android-base/#standalone-functions-androidpy","title":"Standalone Functions (android.py)","text":"

    When using the minimal android module:

    "},{"location":"qsl4a/core/android-base/#jsla","title":"jsla()","text":"

    Send JSON-RPC request and return raw response.

    jsla(method, *params)\n

    Returns: JSON string response

    "},{"location":"qsl4a/core/android-base/#rsla","title":"rsla()","text":"

    Send request and return result only.

    rsla(method, *params)\n

    Returns: Result value from RPC call

    "},{"location":"qsl4a/core/android-base/#esla","title":"esla()","text":"

    Send request, raise exception on error.

    esla(method, *params)\n

    Raises: Exception if error field is not None

    "},{"location":"qsl4a/core/android-base/#nsla","title":"nsla()","text":"

    Send request and return Result namedtuple.

    nsla(method, *params)\n

    Returns: Result namedtuple

    "},{"location":"qsl4a/core/android-base/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/android-base/#basic-connection","title":"Basic Connection","text":"
    import androidhelper\n\n# Connect to Android runtime\ndroid = androidhelper.Android()\n\n# Check connection by showing toast\ndroid.makeToast(\"Connected!\")\n
    "},{"location":"qsl4a/core/android-base/#error-handling","title":"Error Handling","text":"
    result = droid.someMethod()\nif result.error:\n    print(f\"Error: {result.error}\")\nelse:\n    print(f\"Success: {result.result}\")\n
    "},{"location":"qsl4a/core/android-base/#direct-rpc-call","title":"Direct RPC Call","text":"
    # Call any method directly\nresult = droid._rpc(\"makeToast\", \"Hello World\")\n
    "},{"location":"qsl4a/core/events/","title":"Event System","text":"

    QSL4A provides an event system for handling asynchronous events from Android, such as sensor updates, location changes, and custom broadcasts.

    "},{"location":"qsl4a/core/events/#event-basics","title":"Event Basics","text":"

    Events are stored in a buffer and can be polled or waited for. Each event has: - name: Event type/name - data: Event payload data - time: Timestamp

    "},{"location":"qsl4a/core/events/#event-methods","title":"Event Methods","text":""},{"location":"qsl4a/core/events/#eventclearbuffer","title":"eventClearBuffer()","text":"

    Clear all pending events from the buffer.

    eventClearBuffer()\n

    Returns: None

    "},{"location":"qsl4a/core/events/#eventpoll","title":"eventPoll()","text":"

    Poll for events in the buffer.

    eventPoll(number_of_events=1)\n

    Parameters: - number_of_events (int): Maximum events to retrieve (default: 1)

    Returns: List of event objects

    "},{"location":"qsl4a/core/events/#eventwait","title":"eventWait()","text":"

    Wait for any event.

    eventWait(timeout=None)\n

    Parameters: - timeout (int, optional): Timeout in seconds. None = wait forever

    Returns: Event object or None if timeout

    "},{"location":"qsl4a/core/events/#eventwaitfor","title":"eventWaitFor()","text":"

    Wait for a specific event.

    eventWaitFor(eventName, timeout=None)\n

    Parameters: - eventName (str): Name of event to wait for - timeout (int, optional): Timeout in seconds

    Returns: Event object or None if timeout

    "},{"location":"qsl4a/core/events/#eventpost","title":"eventPost()","text":"

    Post a custom event.

    eventPost(name, data, enqueue=None)\n

    Parameters: - name (str): Event name - data: Event data (any type) - enqueue (bool, optional): Add to queue if True

    "},{"location":"qsl4a/core/events/#receiveevent","title":"receiveEvent()","text":"

    Receive event (blocking).

    receiveEvent()\n

    Returns: Event object

    "},{"location":"qsl4a/core/events/#broadcast-events","title":"Broadcast Events","text":"

    Register for system broadcast events.

    "},{"location":"qsl4a/core/events/#eventregisterforbroadcast","title":"eventRegisterForBroadcast()","text":"

    Register to receive broadcast events.

    eventRegisterForBroadcast(category, enqueue=True)\n

    Parameters: - category (str): Broadcast category/action - enqueue (bool): Add to event queue

    "},{"location":"qsl4a/core/events/#eventunregisterforbroadcast","title":"eventUnregisterForBroadcast()","text":"

    Unregister from broadcast events.

    eventUnregisterForBroadcast(category)\n
    "},{"location":"qsl4a/core/events/#eventgetbrodcastcategories","title":"eventGetBrodcastCategories()","text":"

    Get registered broadcast categories.

    eventGetBrodcastCategories()\n

    Returns: List of registered categories

    "},{"location":"qsl4a/core/events/#event-dispatcher","title":"Event Dispatcher)","text":""},{"location":"qsl4a/core/events/#starteventdispatcher","title":"startEventDispatcher()","text":"

    Opens up a socket where you can read for events posted.)

    startEventDispatcher(port=0)\n

    Parameters: - port (int, optional): Port to listen on (default: 0 = auto-select)

    Returns: Port number being listened on

    "},{"location":"qsl4a/core/events/#stopeventdispatcher","title":"stopEventDispatcher()","text":"

    Stops the event server.)

    stopEventDispatcher()\n
    "},{"location":"qsl4a/core/events/#deprecated-methods","title":"Deprecated Methods","text":""},{"location":"qsl4a/core/events/#rpcpostevent","title":"rpcPostEvent()","text":"

    Post an event to the event queue. (Deprecated, use eventPost)

    rpcPostEvent(name, data)\n

    Parameters: - name (str): Event name - data: Event data

    "},{"location":"qsl4a/core/events/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/events/#basic-event-polling","title":"Basic Event Polling","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Clear old events\ndroid.eventClearBuffer()\n\n# Poll for events\nevents = droid.eventPoll(5).result\nfor event in events:\n    print(f\"Event: {event['name']}, Data: {event['data']}\")\n
    "},{"location":"qsl4a/core/events/#waiting-for-events","title":"Waiting for Events","text":"
    # Wait for any event with timeout\nevent = droid.eventWait(timeout=10).result\nif event:\n    print(f\"Got event: {event['name']}\")\n
    "},{"location":"qsl4a/core/events/#waiting-for-specific-event","title":"Waiting for Specific Event","text":"
    # Wait for sensor event\nevent = droid.eventWaitFor('screen', timeout=5).result\nif event:\n    print(f\"Screen event: {event['data']}\")\n
    "},{"location":"qsl4a/core/events/#posting-custom-events","title":"Posting Custom Events","text":"
    # Post custom event\ndroid.eventPost('my_event', {'key': 'value'})\n\n# Wait for it\nevent = droid.eventWaitFor('my_event', timeout=1).result\n
    "},{"location":"qsl4a/core/events/#broadcast-receiver","title":"Broadcast Receiver","text":"
    # Register for screen on/off events\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_ON')\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_OFF')\n\n# Wait for screen events\nwhile True:\n    event = droid.receiveEvent().result\n    if event['name'] == 'android.intent.action.SCREEN_ON':\n        print(\"Screen turned on\")\n    elif event['name'] == 'android.intent.action.SCREEN_OFF':\n        print(\"Screen turned off\")\n
    "},{"location":"qsl4a/core/events/#sensor-event-handling","title":"Sensor Event Handling","text":"
    # Start sensing\ndroid.startSensingTimed(1, 250)\n\n# Process sensor events\nfor _ in range(100):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'sensors':\n        data = event['data']\n        print(f\"Accel: {data['xforce']}, {data['yforce']}, {data['zforce']}\")\n\ndroid.stopSensing()\n
    "},{"location":"qsl4a/core/events/#common-event-types","title":"Common Event Types","text":"Event Name Description Source sensors Sensor data update startSensing* location GPS location update startLocating phone Phone state change startTrackingPhoneState signal Signal strength change startTrackingSignalStrength screen Screenshot ready fullGetScreenShot dialog Dialog response dialogShow*"},{"location":"qsl4a/core/events/#event-data-structure","title":"Event Data Structure","text":"
    {\n    'name': 'event_name',\n    'data': {\n        # Event-specific data\n    },\n    'time': 1234567890  # Timestamp\n}\n
    "},{"location":"qsl4a/core/intent/","title":"Intent System","text":"

    Android Intents are used to start activities, send broadcasts, and communicate between apps. QSL4A provides full Intent support through the Intent module.

    "},{"location":"qsl4a/core/intent/#module-import","title":"Module Import","text":"
    import androidhelper\ndon = androidhelper.Android()\n
    "},{"location":"qsl4a/core/intent/#intent-constants","title":"Intent Constants","text":"

    Access via droid.Intent:

    "},{"location":"qsl4a/core/intent/#actions","title":"Actions","text":"Constant Value Usage ACTION_MAIN android.intent.action.MAIN App entry point ACTION_VIEW android.intent.action.VIEW View content ACTION_EDIT android.intent.action.EDIT Edit content ACTION_PICK android.intent.action.PICK Pick item ACTION_SEND android.intent.action.SEND Share content ACTION_SEARCH android.intent.action.SEARCH Search"},{"location":"qsl4a/core/intent/#flags","title":"Flags","text":"Constant Value Usage FLAG_ACTIVITY_NEW_TASK 268435456 Start new task FLAG_ACTIVITY_CLEAR_TASK 32768 Clear task stack FLAG_ACTIVITY_NEW_DOCUMENT 524288 New document mode"},{"location":"qsl4a/core/intent/#extras","title":"Extras","text":"Constant Usage EXTRA_TEXT Text content EXTRA_STREAM File URI EXTRA_SUBJECT Subject line EXTRA_EMAIL Email address"},{"location":"qsl4a/core/intent/#core-methods","title":"Core Methods","text":""},{"location":"qsl4a/core/intent/#makeintent","title":"makeIntent()","text":"

    Create an Intent object.

    makeIntent(action, uri=None, type=None, extras=None, categories=None,\n           packagename=None, classname=None, flags=None)\n

    Parameters: - action (str): Intent action (e.g., droid.Intent.ACTION_VIEW) - uri (str, optional): Data URI - type (str, optional): MIME type - extras (dict, optional): Extra data - categories (list, optional): Intent categories - packagename (str, optional): Target package - classname (str, optional): Target class - flags (int, optional): Intent flags

    Returns: Intent object

    "},{"location":"qsl4a/core/intent/#startactivityintent","title":"startActivityIntent()","text":"

    Start an Activity with an Intent.

    startActivityIntent(intent, wait=None)\n

    Parameters: - intent: Intent object from makeIntent() - wait (bool, optional): Block until activity closes

    "},{"location":"qsl4a/core/intent/#startactivityforresultintent","title":"startActivityForResultIntent()","text":"

    Start activity and wait for result.

    startActivityForResultIntent(intent)\n

    Returns: Activity result

    "},{"location":"qsl4a/core/intent/#sendbroadcastintent","title":"sendBroadcastIntent()","text":"

    Send a broadcast.

    sendBroadcastIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#view","title":"view()","text":"

    View content by URI.

    view(uri, type=None, extras=None)\n
    "},{"location":"qsl4a/core/intent/#pick","title":"pick()","text":"

    Pick content from URI.

    pick(uri)\n
    "},{"location":"qsl4a/core/intent/#common-intent-methods","title":"Common Intent Methods)","text":""},{"location":"qsl4a/core/intent/#scanbarcode","title":"scanBarcode()","text":"

    Launch the barcode scanner.

    scanBarcode()\n

    Returns: Scanned barcode string

    "},{"location":"qsl4a/core/intent/#send","title":"send()","text":"

    Send content via share intent.

    send(type, content)\n

    Parameters: - type (str): MIME type - content (str): Content to share

    "},{"location":"qsl4a/core/intent/#sendtext","title":"sendText()","text":"

    Send text content.

    sendText(text)\n

    Parameters: - text (str): Text to send

    "},{"location":"qsl4a/core/intent/#sendemail","title":"sendEmail()","text":"

    Send an email.

    sendEmail(to, subject, body, attachment=None)\n

    Parameters: - to (str or list): Recipient email address(es) - subject (str): Email subject - body (str): Email body - attachment (str, optional): Attachment file path

    "},{"location":"qsl4a/core/intent/#pathtouri","title":"pathToUri()","text":"

    Convert file path to content URI.

    pathToUri(path)\n

    Parameters: - path (str): File path

    Returns: Content URI string

    "},{"location":"qsl4a/core/intent/#openfile","title":"openFile()","text":"

    Open a file with appropriate app.

    openFile(path)\n

    Parameters: - path (str): File path to open

    "},{"location":"qsl4a/core/intent/#sendfile","title":"sendFile()","text":"

    Send a file via share intent.

    sendFile(path)\n

    Parameters: - path (str): File path to send

    "},{"location":"qsl4a/core/intent/#getpathtype","title":"getPathType()","text":"

    Get the MIME type for a file path.

    getPathType(path)\n

    Parameters: - path (str): File path

    Returns: MIME type string

    "},{"location":"qsl4a/core/intent/#viewmap","title":"viewMap()","text":"

    Open map at a location.

    viewMap(latitude, longitude)\n

    Parameters: - latitude (float): Latitude - longitude (float): Longitude

    "},{"location":"qsl4a/core/intent/#viewcontacts","title":"viewContacts()","text":"

    Open the contacts app.

    viewContacts()\n
    "},{"location":"qsl4a/core/intent/#search","title":"search()","text":"

    Perform a web search.

    search(query)\n

    Parameters: - query (str): Search query

    "},{"location":"qsl4a/core/intent/#viewhtml","title":"viewHtml()","text":"

    View HTML content.

    viewHtml(content, encoding=None)\n

    Parameters: - content (str): HTML content - encoding (str, optional): Character encoding

    "},{"location":"qsl4a/core/intent/#webviewshow","title":"webViewShow()","text":"

    Display web content in WebView. Deprecated, use viewHtml.

    webViewShow(url)\n

    Parameters: - url (str): Web page URL

    "},{"location":"qsl4a/core/intent/#editoropen","title":"editorOpen()","text":"

    Open a text editor.

    editorOpen(path=None, create=False)\n

    Parameters: - path (str, optional): File path to edit - create (bool, optional): Create if doesn't exist

    "},{"location":"qsl4a/core/intent/#helper-class-uri","title":"Helper Class: Uri","text":"

    Create URI objects for Intents:

    from androidhelper.Intent import Uri\n\nuri = Uri(\"file:///sdcard/test.txt\")\n
    "},{"location":"qsl4a/core/intent/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/intent/#open-web-page","title":"Open Web Page","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"http://www.example.com\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#share-text","title":"Share Text","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_TEXT: \"Hello from QPython!\",\n        droid.Intent.EXTRA_SUBJECT: \"Test\"\n    },\n    type=\"text/plain\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#open-file","title":"Open File","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"file:///sdcard/document.pdf\",\n    type=\"application/pdf\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#pick-contact","title":"Pick Contact","text":"
    result = droid.pickContact()\ncontact_uri = result.result\n
    "},{"location":"qsl4a/core/intent/#send-email","title":"Send Email","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_EMAIL: [\"test@example.com\"],\n        droid.Intent.EXTRA_SUBJECT: \"Hello\",\n        droid.Intent.EXTRA_TEXT: \"Message body\"\n    },\n    type=\"message/rfc822\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#open-app","title":"Open App","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_MAIN,\n    packagename=\"com.android.settings\",\n    classname=\"com.android.settings.Settings\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/hardware/bluetooth/","title":"Bluetooth API","text":"

    Control Bluetooth adapter and communicate with Bluetooth devices.

    "},{"location":"qsl4a/hardware/bluetooth/#adapter-control","title":"Adapter Control","text":""},{"location":"qsl4a/hardware/bluetooth/#togglebluetoothstate","title":"toggleBluetoothState()","text":"

    Turn Bluetooth on/off.

    toggleBluetoothState(enabled=None, prompt=True)\n

    Parameters: - enabled (bool): True=on, False=off, None=toggle - prompt (bool): Show user prompt

    "},{"location":"qsl4a/hardware/bluetooth/#checkbluetoothstate","title":"checkBluetoothState()","text":"

    Check if Bluetooth is enabled.

    checkBluetoothState()\n

    Returns: True/False

    "},{"location":"qsl4a/hardware/bluetooth/#getlocalname","title":"GetLocalName()","text":"

    Get Bluetooth device name.

    GetLocalName()\n
    "},{"location":"qsl4a/hardware/bluetooth/#setlocalname","title":"SetLocalName()","text":"

    Set Bluetooth device name.

    SetLocalName(name)\n
    "},{"location":"qsl4a/hardware/bluetooth/#getscanmode","title":"GetScanMode()","text":"

    Get discoverability mode.

    GetScanMode()\n

    Returns: - -1: Disabled - 0: Non-discoverable, non-connectable - 1: Connectable, non-discoverable - 3: Connectable and discoverable

    "},{"location":"qsl4a/hardware/bluetooth/#makediscoverable","title":"MakeDiscoverable()","text":"

    Make device discoverable.

    MakeDiscoverable(duration=300)\n

    Parameters: - duration (int): Seconds to be discoverable

    "},{"location":"qsl4a/hardware/bluetooth/#discovery","title":"Discovery","text":""},{"location":"qsl4a/hardware/bluetooth/#discoverystart","title":"DiscoveryStart()","text":"

    Start device discovery.

    DiscoveryStart()\n
    "},{"location":"qsl4a/hardware/bluetooth/#discoverycancel","title":"DiscoveryCancel()","text":"

    Cancel discovery.

    DiscoveryCancel()\n
    "},{"location":"qsl4a/hardware/bluetooth/#getreceiveddevices","title":"GetReceivedDevices()","text":"

    Get discovered devices.

    GetReceivedDevices()\n

    Returns: List of device info dicts

    "},{"location":"qsl4a/hardware/bluetooth/#getbondeddevices","title":"GetBondedDevices()","text":"

    Get paired devices.

    GetBondedDevices()\n

    Returns: List of paired device info

    "},{"location":"qsl4a/hardware/bluetooth/#connection","title":"Connection","text":""},{"location":"qsl4a/hardware/bluetooth/#connect","title":"Connect()","text":"

    Connect to a device.

    Connect(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", address=None)\n

    Parameters: - uuid (str): Service UUID - address (str): Device address (None = show picker)

    Returns: True if successful

    "},{"location":"qsl4a/hardware/bluetooth/#accept","title":"Accept()","text":"

    Accept incoming connection.

    Accept(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", timeout=0)\n
    "},{"location":"qsl4a/hardware/bluetooth/#activeconnections","title":"ActiveConnections()","text":"

    Check active connections.

    ActiveConnections()\n
    "},{"location":"qsl4a/hardware/bluetooth/#stop","title":"Stop()","text":"

    Disconnect.

    Stop(connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#communication","title":"Communication","text":""},{"location":"qsl4a/hardware/bluetooth/#write","title":"Write()","text":"

    Send ASCII data.

    Write(ascii, connID=\"\")\n
    "},{"location":"qsl4a/hardware/bluetooth/#writebinary","title":"WriteBinary()","text":"

    Send binary data (base64 encoded).

    WriteBinary(base64, connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#read","title":"Read()","text":"

    Read ASCII data.

    Read(bufferSize=4096, connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#readbinary","title":"ReadBinary()","text":"

    Read binary data.

    ReadBinary(bufferSize=4096, connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#readline","title":"ReadLine()","text":"

    Read line.

    ReadLine(connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#readready","title":"ReadReady()","text":"

    Check if data available.

    ReadReady(connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Enable Bluetooth\ndroid.toggleBluetoothState(True)\n\n# Get paired devices\ndevices = droid.GetBondedDevices().result\nfor dev in devices:\n    print(f\"{dev['name']}: {dev['address']}\")\n\n# Connect to device\ndroid.Connect(address=\"00:11:22:33:44:55\")\n\n# Send data\ndroid.Write(\"Hello Bluetooth!\")\n\n# Read response\ndata = droid.Read(1024).result\n
    "},{"location":"qsl4a/hardware/camera/","title":"Camera API","text":"

    Capture photos and record video.

    "},{"location":"qsl4a/hardware/camera/#photo-capture","title":"Photo Capture","text":""},{"location":"qsl4a/hardware/camera/#takepicture","title":"takePicture()","text":"

    Take a photo using the default camera.

    takePicture(path=None)\n

    Parameters: - path (str, optional): Save path. If None, returns image data

    Returns: Image path or image data

    "},{"location":"qsl4a/hardware/camera/#cameracapturepicture","title":"cameraCapturePicture()","text":"

    Capture picture with advanced camera controls.

    cameraCapturePicture(targetPath=None, cameraId=0, useAutoFocus=True)\n

    Parameters: - targetPath (str, optional): Save path - cameraId (int): Camera to use (0 = back, 1 = front) - useAutoFocus (bool): Enable auto focus

    Returns: Captured image path

    "},{"location":"qsl4a/hardware/camera/#camerasettorchmode","title":"cameraSetTorchMode()","text":"

    Control camera flashlight/torch.

    cameraSetTorchMode(enabled)\n

    Parameters: - enabled (bool): True to turn on, False to turn off

    Returns: True if successful

    "},{"location":"qsl4a/hardware/camera/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

    Capture screenshot.

    imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

    Parameters: - path (str, optional): Save path - delayMilliSec (int): Delay before capture

    "},{"location":"qsl4a/hardware/camera/#video-recording","title":"Video Recording","text":""},{"location":"qsl4a/hardware/camera/#takevideo","title":"takeVideo()","text":"

    Record video using default settings.

    takeVideo(path=None, quality=1)\n

    Parameters: - path (str, optional): Save path - quality (int): Video quality (0-4) - 0: 160x120 - 1: 320x240 - 2: 352x288 - 3: 640x480 - 4: 800x480

    "},{"location":"qsl4a/hardware/camera/#recordercapturevideo","title":"recorderCaptureVideo()","text":"

    Capture video with advanced controls.

    recorderCaptureVideo(targetPath=None, duration=10, cameraId=0, quality=8)\n

    Parameters: - targetPath (str, optional): Save path - duration (int): Recording duration in seconds (default: 10) - cameraId (int): Camera to use (0 = back, 1 = front) - quality (int): Video quality (0-8, higher is better)

    Returns: Video file path

    "},{"location":"qsl4a/hardware/camera/#recordaudio","title":"recordAudio()","text":"

    Record audio.

    recordAudio()\n

    Returns: Audio file path

    "},{"location":"qsl4a/hardware/camera/#screen-recording","title":"Screen Recording","text":""},{"location":"qsl4a/hardware/camera/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

    Start screen recording.

    recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

    Parameters: - path (str): Save path - audio (int): Audio source (0=none, 1=mic, 2=internal) - targetPixels (int): Resolution - frameRate (int): FPS - bitRate (int): Bitrate - rotation (bool): Rotate output - autoStart (bool): Start immediately

    "},{"location":"qsl4a/hardware/camera/#recorderstart","title":"recorderStart()","text":"

    Start recording.

    recorderStart()\n
    "},{"location":"qsl4a/hardware/camera/#recorderpause","title":"recorderPause()","text":"

    Pause recording.

    recorderPause()\n
    "},{"location":"qsl4a/hardware/camera/#recorderresume","title":"recorderResume()","text":"

    Resume recording.

    recorderResume()\n
    "},{"location":"qsl4a/hardware/camera/#audio-volume-detection","title":"Audio Volume Detection","text":""},{"location":"qsl4a/hardware/camera/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

    Start volume detection.

    recorderSoundVolumeDetect(interval=100)\n
    "},{"location":"qsl4a/hardware/camera/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

    Get current volume in dB.

    recorderSoundVolumeGetDb()\n
    "},{"location":"qsl4a/hardware/camera/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Take photo with default camera\nphoto_path = droid.takePicture(\"/sdcard/photo.jpg\").result\nprint(f\"Photo saved: {photo_path}\")\n\n# Take photo with front camera and auto focus\ncamera_path = droid.cameraCapturePicture(\"/sdcard/selfie.jpg\", cameraId=1, useAutoFocus=True).result\nprint(f\"Front camera photo: {camera_path}\")\n\n# Control flashlight\ndroid.cameraSetTorchMode(True)  # Turn on flashlight\n\n# Record video with default settings\nvideo_path = droid.takeVideo(\"/sdcard/video.mp4\", quality=3).result\nprint(f\"Video saved: {video_path}\")\n\n# Record video with advanced controls\nvideo_path = droid.recorderCaptureVideo(\"/sdcard/movie.mp4\", duration=30, cameraId=0, quality=8).result\n\n# Screenshot\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n
    "},{"location":"qsl4a/hardware/recorder/","title":"Audio Recorder API","text":"

    Record audio from microphone and device screen.

    "},{"location":"qsl4a/hardware/recorder/#audio-recording","title":"Audio Recording","text":""},{"location":"qsl4a/hardware/recorder/#recordaudio","title":"recordAudio()","text":"

    Record audio from microphone.

    recordAudio()\n

    Returns: Path to recorded audio file

    "},{"location":"qsl4a/hardware/recorder/#recorderstartmicrophone","title":"recorderStartMicrophone()","text":"

    Start recording from microphone to a specific file.

    recorderStartMicrophone(targetPath=None)\n

    Parameters: - targetPath (str, optional): Path to save the recording

    "},{"location":"qsl4a/hardware/recorder/#screen-recording","title":"Screen Recording","text":""},{"location":"qsl4a/hardware/recorder/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

    Start screen recording with audio.

    recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

    Parameters: - path (str): Save path for video file - audio (int): Audio source (0=none, 1=mic, 2=internal audio) - targetPixels (int): Target resolution in pixels - frameRate (int): Frames per second (default: 30) - bitRate (int): Video bitrate - rotation (bool): Rotate output video - autoStart (bool): Start recording immediately

    Returns: Result of operation

    "},{"location":"qsl4a/hardware/recorder/#recorderstart","title":"recorderStart()","text":"

    Start the screen recording (when autoStart=False).

    recorderStart()\n
    "},{"location":"qsl4a/hardware/recorder/#recorderpause","title":"recorderPause()","text":"

    Pause ongoing screen recording.

    recorderPause()\n
    "},{"location":"qsl4a/hardware/recorder/#recorderresume","title":"recorderResume()","text":"

    Resume paused screen recording.

    recorderResume()\n
    "},{"location":"qsl4a/hardware/recorder/#audio-volume-detection","title":"Audio Volume Detection","text":""},{"location":"qsl4a/hardware/recorder/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

    Start monitoring sound volume level.

    recorderSoundVolumeDetect(interval=100)\n

    Parameters: - interval (int): Detection interval in milliseconds (default: 100)

    "},{"location":"qsl4a/hardware/recorder/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

    Get current sound volume in decibels.

    recorderSoundVolumeGetDb()\n

    Returns: Current volume level in dB

    "},{"location":"qsl4a/hardware/recorder/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Record audio from microphone\nprint(\"Recording audio...\")\naudio_path = droid.recordAudio().result\nprint(f\"Saved to: {audio_path}\")\n\n# Record microphone to specific file\ndroid.recorderStartMicrophone(\"/sdcard/my_recording.mp3\")\ntime.sleep(5)\ndroid.recorderStop()\n\n# Record screen with audio\nprint(\"Starting screen recording...\")\ndroid.recorderStartScreenRecord(\n    path=\"/sdcard/screen_record.mp4\",\n    audio=1,\n    frameRate=30,\n    autoStart=True\n)\ntime.sleep(10)\ndroid.recorderStop()\n\n# Monitor sound volume\ndroid.recorderSoundVolumeDetect(interval=100)\ntime.sleep(3)\nvolume = droid.recorderSoundVolumeGetDb().result\nprint(f\"Current volume: {volume} dB\")\n
    "},{"location":"qsl4a/hardware/usbserial/","title":"USB Host Serial API","text":"

    Communicate with USB serial devices (requires USB OTG support and Android 3.1+).

    "},{"location":"qsl4a/hardware/usbserial/#usb-serial-methods","title":"USB Serial Methods)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialopen","title":"usbHostSerialOpen()","text":"

    Open a connection to a USB serial device.

    usbHostSerialOpen(device, baudRate=9600)\n

    Parameters: - device (str): USB device path or identifier - baudRate (int): Baud rate (default: 9600)

    Returns: True if opened successfully

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialclose","title":"usbHostSerialClose()","text":"

    Close the USB serial connection.

    usbHostSerialClose()\n
    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialread","title":"usbHostSerialRead()","text":"

    Read data from USB serial.

    usbHostSerialRead(bufferSize=1024)\n

    Parameters: - bufferSize (int): Maximum bytes to read (default: 1024)

    Returns: String read data

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwrite","title":"usbHostSerialWrite()","text":"

    Write data to USB serial.

    usbHostSerialWrite(data)\n

    Parameters: - data (str): String data to write

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialavailable","title":"usbHostSerialAvailable()","text":"

    Check if data is available to read.

    usbHostSerialAvailable()\n

    Returns: Number of bytes available

    "},{"location":"qsl4a/hardware/usbserial/#configuration-methods","title":"Configuration Methods)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetbaudrate","title":"usbHostSerialSetBaudRate()","text":"

    Set the baud rate.

    usbHostSerialSetBaudRate(baudRate)\n

    Parameters: - baudRate (int): Baud rate

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetdatabits","title":"usbHostSerialSetDataBits()","text":"

    Set data bits (5, 6, 7, or 8).

    usbHostSerialSetDataBits(dataBits)\n

    Parameters: - dataBits (int): Data bits (5-8)

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetstopbits","title":"usbHostSerialSetStopBits()","text":"

    Set stop bits (1, 1.5, or 2).

    usbHostSerialSetStopBits(stopBits)\n

    Parameters: - stopBits (float): Stop bits (1, 1.5, or 2)

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetparity","title":"usbHostSerialSetParity()","text":"

    Set parity (none, odd, even, mark, space).

    usbHostSerialSetParity(parity)\n

    Parameters: - parity (str): Parity mode ('none', 'odd', 'even', 'mark', 'space')

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetflowcontrol","title":"usbHostSerialSetFlowControl()","text":"

    Set flow control (none, hardware, software).

    usbHostSerialSetFlowControl(flowControl)\n

    Parameters: - flowControl (str): Flow control mode ('none', 'hardware', 'software')

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialreadhex","title":"usbHostSerialReadHex()","text":"

    Read data as hex string.

    usbHostSerialReadHex(bufferSize=1024)\n

    Parameters: - bufferSize (int): Maximum bytes to read

    Returns: Hex string

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwritehex","title":"usbHostSerialWriteHex()","text":"

    Write data from hex string.

    usbHostSerialWriteHex(hexString)\n

    Parameters: - hexString (str): Hex string to write

    "},{"location":"qsl4a/hardware/usbserial/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Open USB serial connection\nif droid.usbHostSerialOpen(\"/dev/bus/usb/001/001\", 115200).result:\n    print(\"USB serial opened\")\n\n    # Write data\n    droid.usbHostSerialWrite(\"AT\\r\")\n\n    # Read response\n    response = droid.usbHostSerialRead(1024).result\n    print(f\"Response: {response}\")\n\n    # Or use hex\n    droid.usbHostSerialWriteHex(\"41540D0A\")  # \"AT\\r\\n\"\n\n    # Close connection\n    droid.usbHostSerialClose()\n

    Note: USB serial requires: - Android 3.1+ (API 12) - USB OTG cable/adapter - USB host mode support on device - Compatible serial device

    "},{"location":"qsl4a/hardware/webcam/","title":"Webcam API","text":"

    Stream video from the device camera using MJPEG.

    "},{"location":"qsl4a/hardware/webcam/#mjpeg-stream-methods","title":"MJPEG Stream Methods","text":""},{"location":"qsl4a/hardware/webcam/#webcamstart","title":"webcamStart()","text":"

    Start an MJPEG stream from the webcam.

    webcamStart(resolutionLevel=0, jpegQuality=20, port=0)\n

    Parameters: - resolutionLevel (int): Resolution level (default: 0) - jpegQuality (int): JPEG quality 1-100 (default: 20) - port (int): Port number (default: 0 = auto)

    Returns: Tuple of (address, port) for the stream

    "},{"location":"qsl4a/hardware/webcam/#webcamadjustquality","title":"webcamAdjustQuality()","text":"

    Adjust the quality of an active webcam stream.

    webcamAdjustQuality(resolutionLevel=0, jpegQuality=20)\n

    Parameters: - resolutionLevel (int): Resolution level - jpegQuality (int): JPEG quality 1-100

    "},{"location":"qsl4a/hardware/webcam/#webcamstop","title":"webcamStop()","text":"

    Stop the webcam stream.

    webcamStop()\n
    "},{"location":"qsl4a/hardware/webcam/#camera-preview-methods","title":"Camera Preview Methods","text":""},{"location":"qsl4a/hardware/webcam/#camerastartpreview","title":"cameraStartPreview()","text":"

    Start camera preview mode with event generation.

    cameraStartPreview(resolutionLevel=0, jpegQuality=20, filepath=None)\n

    Parameters: - resolutionLevel (int): Resolution level (default: 0) - jpegQuality (int): JPEG quality (default: 20) - filepath (str, optional): File path to save preview frames

    Returns: True if successful

    Note: Generates 'preview' events with frame data.

    "},{"location":"qsl4a/hardware/webcam/#camerastoppreview","title":"cameraStopPreview()","text":"

    Stop the camera preview.

    cameraStopPreview()\n
    "},{"location":"qsl4a/hardware/webcam/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start webcam stream\nstream_info = droid.webcamStart(\n    resolutionLevel=0,\n    jpegQuality=30,\n    port=8080\n).result\nprint(f\"Stream available at {stream_info[0]}:{stream_info[1]}\")\n\n# Adjust quality while streaming\ntime.sleep(5)\ndroid.webcamAdjustQuality(resolutionLevel=1, jpegQuality=50)\n\n# Stop when done\ndroid.webcamStop()\n\n# Or use preview mode\nprint(\"Starting preview...\")\ndroid.cameraStartPreview()\n\n# Wait for preview events\nfor i in range(10):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'preview':\n        print(f\"Got preview frame: {event['data']}\")\n\ndroid.cameraStopPreview()\n
    "},{"location":"qsl4a/media/image/","title":"Image Processing API","text":"

    Compress and process images.

    "},{"location":"qsl4a/media/image/#image-compression","title":"Image Compression","text":""},{"location":"qsl4a/media/image/#imagecompress","title":"imageCompress()","text":"

    Compress image file.

    imageCompress(srcPath, destPath, targetByteSize=0, targetWidth=0, targetHeight=0)\n

    Parameters: - srcPath (str): Source image path - destPath (str): Output path - targetByteSize (int): Target file size in bytes (0 = no limit) - targetWidth (int): Target width (0 = original) - targetHeight (int): Target height (0 = original)

    Returns: Compressed image path

    "},{"location":"qsl4a/media/image/#screenshot","title":"Screenshot","text":""},{"location":"qsl4a/media/image/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

    Capture screen.

    imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

    Parameters: - path (str): Save path - delayMilliSec (int): Delay before capture

    Returns: Screenshot path

    "},{"location":"qsl4a/media/image/#video-playback","title":"Video Playback","text":""},{"location":"qsl4a/media/image/#videoplay","title":"videoPlay()","text":"

    Play video file in fullscreen mode.

    videoPlay(path, wait=True)\n

    Parameters: - path (str): Video file path - wait (bool): Wait for playback to complete (default: True)

    "},{"location":"qsl4a/media/image/#barcode-scanning","title":"Barcode Scanning","text":""},{"location":"qsl4a/media/image/#scanbarcodefromimage","title":"scanBarcodeFromImage()","text":"

    Scan barcode/QR code from image file.

    scanBarcodeFromImage(path, compressRatio=0, x=0, y=0, width=0, height=0)\n

    Parameters: - path (str): Image file path - compressRatio (int): Compression ratio (0 = no compression) - x, y, width, height (int): Region to scan (0 = full image)

    Returns: Scanned barcode content

    "},{"location":"qsl4a/media/image/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Take screenshot\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n\n# Compress image\ncompressed = droid.imageCompress(\n    \"/sdcard/large_photo.jpg\",\n    \"/sdcard/compressed.jpg\",\n    targetByteSize=102400,  # Target ~100KB\n    targetWidth=1920,\n    targetHeight=1080\n).result\nprint(f\"Saved: {compressed}\")\n\n# Play video\nvideo_path = \"/sdcard/movie.mp4\"\ndroid.videoPlay(video_path, wait=True)\n\n# Scan barcode from image\nresult = droid.scanBarcodeFromImage(\"/sdcard/qr_code.png\").result\nprint(f\"Barcode: {result}\")\n
    "},{"location":"qsl4a/media/mediaplayer/","title":"Media Player API","text":"

    Control audio and video playback.

    "},{"location":"qsl4a/media/mediaplayer/#playback-control","title":"Playback Control","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplay","title":"mediaPlay()","text":"

    Play media file.

    mediaPlay(url, tag=\"default\", play=True)\n

    Parameters: - url (str): Media file path or URL - tag (str): Player identifier - play (bool): Auto-start playback

    "},{"location":"qsl4a/media/mediaplayer/#mediaplaystart","title":"mediaPlayStart()","text":"

    Start playback.

    mediaPlayStart(tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#mediaplaypause","title":"mediaPlayPause()","text":"

    Pause playback.

    mediaPlayPause(tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#mediaplayclose","title":"mediaPlayClose()","text":"

    Close player.

    mediaPlayClose(tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#mediaplayseek","title":"mediaPlaySeek()","text":"

    Seek to position.

    mediaPlaySeek(msec, tag=\"default\")\n

    Parameters: - msec (int): Position in milliseconds

    "},{"location":"qsl4a/media/mediaplayer/#mediaplaysetlooping","title":"mediaPlaySetLooping()","text":"

    Set loop mode.

    mediaPlaySetLooping(enabled, tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#player-info","title":"Player Info","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplayinfo","title":"mediaPlayInfo()","text":"

    Get playback info.

    mediaPlayInfo(tag=\"default\")\n

    Returns: Dict with duration, position, etc.

    "},{"location":"qsl4a/media/mediaplayer/#mediaisplaying","title":"mediaIsPlaying()","text":"

    Check if playing.

    mediaIsPlaying(tag=\"default\")\n

    Returns: True/False

    "},{"location":"qsl4a/media/mediaplayer/#mediaplaylist","title":"mediaPlayList()","text":"

    List active players.

    mediaPlayList()\n
    "},{"location":"qsl4a/media/mediaplayer/#volume-control","title":"Volume Control","text":""},{"location":"qsl4a/media/mediaplayer/#getmediavolume","title":"getMediaVolume()","text":"

    Get media volume.

    getMediaVolume()\n

    Returns: Volume level (0-15)

    "},{"location":"qsl4a/media/mediaplayer/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

    Get max media volume.

    getMaxMediaVolume()\n
    "},{"location":"qsl4a/media/mediaplayer/#getringervolume","title":"getRingerVolume()","text":"

    Get ringer volume.

    getRingerVolume()\n
    "},{"location":"qsl4a/media/mediaplayer/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

    Get max ringer volume.

    getMaxRingerVolume()\n
    "},{"location":"qsl4a/media/mediaplayer/#video-playback","title":"Video Playback","text":""},{"location":"qsl4a/media/mediaplayer/#videoplay","title":"videoPlay()","text":"

    Play video fullscreen.

    videoPlay(path, wait=True)\n

    Parameters: - path (str): Video file path - wait (bool): Wait for playback to complete

    "},{"location":"qsl4a/media/mediaplayer/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Play audio\ndroid.mediaPlay(\"/sdcard/music.mp3\", tag=\"music\")\n\n# Check status\nif droid.mediaIsPlaying(\"music\").result:\n    info = droid.mediaPlayInfo(\"music\").result\n    print(f\"Playing: {info}\")\n\n# Seek to 30 seconds\ndroid.mediaPlaySeek(30000, \"music\")\n\n# Close\ndroid.mediaPlayClose(\"music\")\n\n# Play video\ndroid.videoPlay(\"/sdcard/movie.mp4\", wait=True)\n
    "},{"location":"qsl4a/special/cipher/","title":"Cipher API","text":"

    Encryption and decryption utilities for secure data storage.

    "},{"location":"qsl4a/special/cipher/#initialization","title":"Initialization","text":""},{"location":"qsl4a/special/cipher/#cipherinit","title":"cipherInit()","text":"

    Initialize the cipher with encryption key and algorithm.

    cipherInit(key, algorithm=\"AES/CBC/PKCS5Padding\", encodingFormat=\"\", initialVector=\"\")\n

    Parameters: - key (str or bytes): Encryption key - algorithm (str): Cipher algorithm (default: \"AES/CBC/PKCS5Padding\") - encodingFormat (str): Encoding format - initialVector (str or bytes): Initial vector for encryption

    Returns: Initialization result

    Note: Must be called before any encrypt/decrypt operations.

    "},{"location":"qsl4a/special/cipher/#encryption-methods","title":"Encryption Methods","text":""},{"location":"qsl4a/special/cipher/#encryptstring","title":"encryptString()","text":"

    Encrypt a string.

    encryptString(plainText)\n

    Parameters: - plainText (str): Text to encrypt

    Returns: Encrypted string

    "},{"location":"qsl4a/special/cipher/#encryptbytes","title":"encryptBytes()","text":"

    Encrypt bytes data.

    encryptBytes(data)\n

    Parameters: - data (bytes): Data to encrypt

    Returns: Encrypted bytes

    "},{"location":"qsl4a/special/cipher/#encryptstringtofile","title":"encryptStringToFile()","text":"

    Encrypt string to file.

    encryptStringToFile(plainText, filePath)\n

    Parameters: - plainText (str): Text to encrypt - filePath (str): Output file path

    "},{"location":"qsl4a/special/cipher/#encryptbytestofile","title":"encryptBytesToFile()","text":"

    Encrypt bytes to file.

    encryptBytesToFile(data, filePath)\n
    "},{"location":"qsl4a/special/cipher/#decryption-methods","title":"Decryption Methods","text":""},{"location":"qsl4a/special/cipher/#decryptstring","title":"decryptString()","text":"

    Decrypt to string.

    decryptString(cipherText)\n

    Parameters: - cipherText (str): Encrypted text

    Returns: Decrypted string

    "},{"location":"qsl4a/special/cipher/#decryptbytes","title":"decryptBytes()","text":"

    Decrypt to bytes.

    decryptBytes(data)\n

    Returns: Decrypted bytes

    "},{"location":"qsl4a/special/cipher/#decryptfiletostring","title":"decryptFileToString()","text":"

    Decrypt file to string.

    decryptFileToString(filePath)\n
    "},{"location":"qsl4a/special/cipher/#decryptfiletobytes","title":"decryptFileToBytes()","text":"

    Decrypt file to bytes.

    decryptFileToBytes(filePath)\n
    "},{"location":"qsl4a/special/cipher/#decryptfile","title":"decryptFile()","text":"

    Decrypt file to file.

    decryptFile(srcPath, destPath)\n
    "},{"location":"qsl4a/special/cipher/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Initialize cipher with your encryption key\ndroid.cipherInit(\"my_secret_key_1234\")\n\n# Encrypt string\nencrypted = droid.encryptString(\"Secret message!\").result\nprint(f\"Encrypted: {encrypted}\")\n\n# Decrypt string\ndecrypted = droid.decryptString(encrypted).result\nprint(f\"Decrypted: {decrypted}\")\n\n# Encrypt to file\ndroid.encryptStringToFile(\"My secret data\", \"/sdcard/secret.dat\")\n\n# Decrypt from file\ndata = droid.decryptFileToString(\"/sdcard/secret.dat\").result\nprint(data)\n\n# Initialize with custom algorithm and IV\ndroid.cipherInit(\n    key=\"my_key\",\n    algorithm=\"AES/CBC/PKCS5Padding\",\n    initialVector=\"0123456789abcdef\"\n)\n
    "},{"location":"qsl4a/special/pgptai/","title":"PGPT AI API","text":"

    Speech-to-text and AI services integration.

    "},{"location":"qsl4a/special/pgptai/#prerequisites","title":"Prerequisites","text":"
    pip install pgptAI\n
    "},{"location":"qsl4a/special/pgptai/#speech-recognition","title":"Speech Recognition","text":""},{"location":"qsl4a/special/pgptai/#speechtotext","title":"speechToText()","text":"

    Convert speech to text.

    speechToText(RecordSecond=10, AmrFile=None, Language=None)\n

    Parameters: - RecordSecond (int): Recording duration in seconds - AmrFile (str, optional): Existing audio file path - Language (str, optional): Language code ('en', 'zh')

    Returns: Transcribed text

    "},{"location":"qsl4a/special/pgptai/#text-to-speech","title":"Text to Speech","text":""},{"location":"qsl4a/special/pgptai/#texttospeech","title":"textToSpeech()","text":"

    Convert text to speech and optionally play it.

    textToSpeech(Text, AutoPlay=True, WavFile=None, VoiceName=None)\n

    Parameters: - Text (str): Text to convert to speech - AutoPlay (bool): Automatically play the generated audio (default: True) - WavFile (str, optional): Path to save the WAV file. If None, uses temporary file - VoiceName (str, optional): Voice name to use (e.g., 'en-US-JennyNeural', 'zh-CN-XiaoxiaoNeural')

    Returns: Dict with speech synthesis result including: - text: The input text - url: URL to download the audio file - WavFile: Path to the saved WAV file (if saved locally)

    "},{"location":"qsl4a/special/pgptai/#configuration","title":"Configuration","text":"

    The API uses configuration from /storage/emulated/0/Android/data/org.qpython.qpy/files/apigpt.conf:

    [speech]\nspeech_key = your_api_key\n

    Default voice settings: - English: en-US-JennyNeural - Chinese: zh-CN-XiaoxiaoNeural

    "},{"location":"qsl4a/special/pgptai/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Record and transcribe\nprint(\"Recording for 5 seconds...\")\ntext = droid.speechToText(RecordSecond=5, Language='en').result\nprint(f\"You said: {text}\")\n\n# Transcribe existing file\ntext = droid.speechToText(AmrFile=\"/sdcard/recording.amr\").result\nprint(f\"Transcription: {text}\")\n\n# Text to speech\ndroid.textToSpeech(\"Hello, this is a test message.\", AutoPlay=True, Language='en')\n\n# Text to speech with custom voice and save to file\nresult = droid.textToSpeech(\n    \"Welcome to QPython!\",\n    AutoPlay=False,\n    WavFile=\"/sdcard/welcome.wav\",\n    VoiceName=\"en-US-JennyNeural\"\n).result\nprint(f\"Audio saved to: {result.get('WavFile')}\")\n
    "},{"location":"qsl4a/special/pgptai/#class-usage","title":"Class Usage","text":"
    from androidhelper.pgptai import pgptai\nimport androidhelper\n\ndroid = androidhelper.Android()\nai = pgptai(droid)\n\n# Use speech recognition\ntext = ai.speechToText(RecordSecond=10)\n
    "},{"location":"qsl4a/storage/clipboard/","title":"Clipboard API","text":"

    Copy and paste text to system clipboard.

    "},{"location":"qsl4a/storage/clipboard/#methods","title":"Methods","text":""},{"location":"qsl4a/storage/clipboard/#setclipboard","title":"setClipboard()","text":"

    Copy text to clipboard.

    setClipboard(text)\n

    Parameters: - text (str): Text to copy

    Returns: True if success

    "},{"location":"qsl4a/storage/clipboard/#getclipboard","title":"getClipboard()","text":"

    Get text from clipboard.

    getClipboard()\n

    Returns: Clipboard text

    "},{"location":"qsl4a/storage/clipboard/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Copy to clipboard\ndroid.setClipboard(\"Hello from QPython!\")\n\n# Paste from clipboard\ntext = droid.getClipboard().result\nprint(f\"Clipboard: {text}\")\n
    "},{"location":"qsl4a/storage/documentfile/","title":"DocumentFile API","text":"

    File operations with SAF (Storage Access Framework) support for Android 4.4+.

    "},{"location":"qsl4a/storage/documentfile/#directory-operations","title":"Directory Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfilemkdir","title":"documentFileMkdir()","text":"

    Create directory.

    documentFileMkdir(Dir)\n

    Parameters: - Dir (str): Directory path

    Returns: True if success

    "},{"location":"qsl4a/storage/documentfile/#documentfilelistfiles","title":"documentFileListFiles()","text":"

    List files in directory.

    documentFileListFiles(Folder)\n

    Returns: List of files

    "},{"location":"qsl4a/storage/documentfile/#file-operations","title":"File Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfileexists","title":"documentFileExists()","text":"

    Check if file or directory exists.

    documentFileExists(path)\n

    Parameters: - path (str): File or directory path

    Returns: True if exists, False otherwise

    "},{"location":"qsl4a/storage/documentfile/#documentfileisfile","title":"documentFileIsFile()","text":"

    Check if path is a file.

    documentFileIsFile(path)\n

    Parameters: - path (str): Path to check

    Returns: True if file, False if not a file, None if not exists

    "},{"location":"qsl4a/storage/documentfile/#documentfileisdirectory","title":"documentFileIsDirectory()","text":"

    Check if path is a directory.

    documentFileIsDirectory(path)\n

    Parameters: - path (str): Path to check

    Returns: True if directory, False if not a directory, None if not exists

    "},{"location":"qsl4a/storage/documentfile/#documentfiledelete","title":"documentFileDelete()","text":"

    Delete file or directory.

    documentFileDelete(FileOrTree)\n

    Returns: True if success

    "},{"location":"qsl4a/storage/documentfile/#documentfilerenameto","title":"documentFileRenameTo()","text":"

    Rename or move file.

    documentFileRenameTo(Src, Dest)\n

    Returns: True if success

    "},{"location":"qsl4a/storage/documentfile/#documentfilecopy","title":"documentFileCopy()","text":"

    Copy file.

    documentFileCopy(SrcFileOrTree, DestFileOrTree)\n
    "},{"location":"qsl4a/storage/documentfile/#stream-operations","title":"Stream Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfileinputstream","title":"documentFileInputStream()","text":"

    Read file content.

    documentFileInputStream(srcFile, EncodingFormat=\"\", skip=None, length=None)\n

    Parameters: - srcFile (str): Source file - EncodingFormat (str): \"UTF-8\", \"GBK\", \"Base64\", or \"\" for bytes - skip (int): Skip bytes from start - length (int): Read length

    Returns: File content

    "},{"location":"qsl4a/storage/documentfile/#documentfileoutputstream","title":"documentFileOutputStream()","text":"

    Write file content.

    documentFileOutputStream(destFile, src, EncodingFormat=\"\", append=None)\n

    Parameters: - destFile (str): Destination file - src: Data to write - EncodingFormat (str): Encoding format - append (bool): Append mode

    "},{"location":"qsl4a/storage/documentfile/#file-information","title":"File Information","text":""},{"location":"qsl4a/storage/documentfile/#documentfilelength","title":"documentFileLength()","text":"

    Get file size in bytes.

    documentFileLength(path)\n

    Parameters: - path (str): File path

    Returns: File size in bytes (0 if not exists)

    "},{"location":"qsl4a/storage/documentfile/#documentfilelastmodified","title":"documentFileLastModified()","text":"

    Get last modified time.

    documentFileLastModified(path)\n

    Parameters: - path (str): File path

    Returns: Timestamp (0 if not exists)

    "},{"location":"qsl4a/storage/documentfile/#documentfilegetstat","title":"documentFileGetStat()","text":"

    Get comprehensive file statistics.

    documentFileGetStat(path)\n

    Parameters: - path (str): File path

    Returns: Dict with length, last modified, and read/write permissions, or None if not exists

    "},{"location":"qsl4a/storage/documentfile/#uri-operations","title":"URI Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfilegeturi","title":"documentFileGetUri()","text":"

    Get URI from path.

    documentFileGetUri(path, isDirectory=None)\n
    "},{"location":"qsl4a/storage/documentfile/#documentfileshowopen","title":"documentFileShowOpen()","text":"

    Show file picker.

    documentFileShowOpen()\n

    Returns: Selected file URI

    "},{"location":"qsl4a/storage/documentfile/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Create directory\ndroid.documentFileMkdir(\"/sdcard/MyFolder\")\n\n# List files\nfiles = droid.documentFileListFiles(\"/sdcard\").result\nfor f in files:\n    print(f)\n\n# Read file\ncontent = droid.documentFileInputStream(\n    \"/sdcard/test.txt\",\n    EncodingFormat=\"UTF-8\"\n).result\nprint(content)\n\n# Write file\ndroid.documentFileOutputStream(\n    \"/sdcard/output.txt\",\n    \"Hello World\",\n    EncodingFormat=\"UTF-8\"\n)\n
    "},{"location":"qsl4a/storage/preferences/","title":"Preferences API","text":"

    Store and retrieve data using Android SharedPreferences.

    "},{"location":"qsl4a/storage/preferences/#preference-methods","title":"Preference Methods","text":""},{"location":"qsl4a/storage/preferences/#prefgetvalue","title":"prefGetValue()","text":"

    Read a value from shared preferences.

    prefGetValue(key, filename=None)\n

    Parameters: - key (str): Preference key - filename (str, optional): Preference file name

    Returns: The stored value (any type)

    "},{"location":"qsl4a/storage/preferences/#prefputvalue","title":"prefPutValue()","text":"

    Write a value to shared preferences.

    prefPutValue(key, value, filename=None)\n

    Parameters: - key (str): Preference key - value (object): Value to store - filename (str, optional): Preference file name

    "},{"location":"qsl4a/storage/preferences/#prefgetall","title":"prefGetAll()","text":"

    Get all preference values.

    prefGetAll(filename=None)\n

    Parameters: - filename (str, optional): Preference file name

    Returns: Map of all preferences

    "},{"location":"qsl4a/storage/preferences/#prefremovevalue","title":"prefRemoveValue()","text":"

    Remove a value from shared preferences.

    prefRemoveValue(key, filename=None)\n

    Parameters: - key (str): Preference key to remove - filename (str, optional): Preference file name

    "},{"location":"qsl4a/storage/preferences/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Store values\ndroid.prefPutValue(\"username\", \"alice\")\ndroid.prefPutValue(\"score\", 100)\ndroid.prefPutValue(\"enabled\", True)\n\n# Read a specific value\nusername = droid.prefGetValue(\"username\").result\nprint(f\"Username: {username}\")\n\n# Get all preferences\nall_prefs = droid.prefGetAll().result\nprint(f\"All prefs: {all_prefs}\")\n\n# Remove a value\ndroid.prefRemoveValue(\"score\")\n\n# Use custom filename\ndroid.prefPutValue(\"token\", \"abc123\", filename=\"auth.prefs\")\ntoken = droid.prefGetValue(\"token\", filename=\"auth.prefs\").result\n
    "},{"location":"qsl4a/system/activityresult/","title":"Activity Result API","text":"

    Set activity results for scripts launched via startActivityForResult.

    "},{"location":"qsl4a/system/activityresult/#result-methods","title":"Result Methods","text":""},{"location":"qsl4a/system/activityresult/#setresultboolean","title":"setResultBoolean()","text":"

    Set a boolean result.

    setResultBoolean(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (bool): Boolean result value

    "},{"location":"qsl4a/system/activityresult/#setresultbyte","title":"setResultByte()","text":"

    Set a byte result.

    setResultByte(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (int): Byte result value

    "},{"location":"qsl4a/system/activityresult/#setresultshort","title":"setResultShort()","text":"

    Set a short result.

    setResultShort(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (int): Short result value

    "},{"location":"qsl4a/system/activityresult/#setresultchar","title":"setResultChar()","text":"

    Set a character result.

    setResultChar(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (str): Character result value

    "},{"location":"qsl4a/system/activityresult/#setresultinteger","title":"setResultInteger()","text":"

    Set an integer result.

    setResultInteger(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (int): Integer result value

    "},{"location":"qsl4a/system/activityresult/#setresultlong","title":"setResultLong()","text":"

    Set a long result.

    setResultLong(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (int): Long result value

    "},{"location":"qsl4a/system/activityresult/#setresultfloat","title":"setResultFloat()","text":"

    Set a float result.

    setResultFloat(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (float): Float result value

    "},{"location":"qsl4a/system/activityresult/#setresultdouble","title":"setResultDouble()","text":"

    Set a double result.

    setResultDouble(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (float): Double result value

    "},{"location":"qsl4a/system/activityresult/#setresultstring","title":"setResultString()","text":"

    Set a string result.

    setResultString(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (str): String result value

    "},{"location":"qsl4a/system/activityresult/#setresultbooleanarray","title":"setResultBooleanArray()","text":"

    Set a boolean array result.

    setResultBooleanArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Boolean array

    "},{"location":"qsl4a/system/activityresult/#setresultbytearray","title":"setResultByteArray()","text":"

    Set a byte array result.

    setResultByteArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Byte array

    "},{"location":"qsl4a/system/activityresult/#setresultshortarray","title":"setResultShortArray()","text":"

    Set a short array result.

    setResultShortArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Short array

    "},{"location":"qsl4a/system/activityresult/#setresultchararray","title":"setResultCharArray()","text":"

    Set a character array result.

    setResultCharArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Char array

    "},{"location":"qsl4a/system/activityresult/#setresultintegerarray","title":"setResultIntegerArray()","text":"

    Set an integer array result.

    setResultIntegerArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Integer array

    "},{"location":"qsl4a/system/activityresult/#setresultlongarray","title":"setResultLongArray()","text":"

    Set a long array result.

    setResultLongArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Long array

    "},{"location":"qsl4a/system/activityresult/#setresultfloatarray","title":"setResultFloatArray()","text":"

    Set a float array result.

    setResultFloatArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Float array

    "},{"location":"qsl4a/system/activityresult/#setresultdoublearray","title":"setResultDoubleArray()","text":"

    Set a double array result.

    setResultDoubleArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Double array

    "},{"location":"qsl4a/system/activityresult/#setresultstringarray","title":"setResultStringArray()","text":"

    Set a string array result.

    setResultStringArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): String array

    "},{"location":"qsl4a/system/activityresult/#setresultserializable","title":"setResultSerializable()","text":"

    Set a serializable result.

    setResultSerializable(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue: Serializable result value

    "},{"location":"qsl4a/system/activityresult/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# After performing an activity, set the result\n# Example: Return success with data\ndroid.setResultInteger(0, 200)  # RESULT_OK\ndroid.setResultString(0, \"Operation completed successfully\")\n\n# Return an array result\ndroid.setResultIntegerArray(0, [1, 2, 3, 4, 5])\n
    "},{"location":"qsl4a/system/application/","title":"Application Management","text":"

    Manage applications, launch apps, and query system information.

    "},{"location":"qsl4a/system/application/#application-information","title":"Application Information","text":""},{"location":"qsl4a/system/application/#getapplicationinfo","title":"getApplicationInfo()","text":"

    Get information about an app.

    getApplicationInfo(packageName=None)\n

    Parameters: - packageName (str): Package name (None = current app)

    Returns: App info dict

    "},{"location":"qsl4a/system/application/#getinstalledpackages","title":"getInstalledPackages()","text":"

    Get list of installed packages.

    getInstalledPackages(flag=4)\n

    Parameters: - flag (int): Package flag filter (default: 4)

    Returns: List of installed packages

    "},{"location":"qsl4a/system/application/#getrunningpackages","title":"getRunningPackages()","text":"

    List running packages.

    getRunningPackages()\n

    Returns: List of package names

    "},{"location":"qsl4a/system/application/#getlaunchablepackages","title":"getLaunchablePackages()","text":"

    Get list of launchable packages.

    getLaunchablePackages(needClassName=False)\n

    Parameters: - needClassName (bool): Include main activity class name (default: False)

    Returns: List of launchable package names or dict with class names

    "},{"location":"qsl4a/system/application/#application-control","title":"Application Control","text":""},{"location":"qsl4a/system/application/#launch","title":"launch()","text":"

    Launch an application.

    launch(classname=None, packagename=None, wait=True)\n

    Parameters: - classname (str): Main activity class name - packagename (str): Package name - wait (bool): Wait for launch to complete (default: True)

    Returns: Launch result

    "},{"location":"qsl4a/system/application/#forcestoppackage","title":"forceStopPackage()","text":"

    Force stop an application.

    forceStopPackage(packageName)\n

    Parameters: - packageName (str): Package name to stop

    "},{"location":"qsl4a/system/application/#version-information","title":"Version Information","text":""},{"location":"qsl4a/system/application/#getpackageversion","title":"getPackageVersion()","text":"

    Get app version name.

    getPackageVersion(packageName)\n

    Returns: Version string (e.g., \"3.2.1\")

    "},{"location":"qsl4a/system/application/#getpackageversioncode","title":"getPackageVersionCode()","text":"

    Get app version code.

    getPackageVersionCode(packageName)\n

    Returns: Version code integer

    "},{"location":"qsl4a/system/application/#getconstants","title":"getConstants()","text":"

    Get class constants.

    getConstants(classname)\n

    Parameters: - classname (str): Full class name

    Returns: Dict of constant names and values

    "},{"location":"qsl4a/system/application/#system-features","title":"System Features","text":""},{"location":"qsl4a/system/application/#backgroundprotect","title":"backgroundProtect()","text":"

    Enable or disable background protection for the app.

    backgroundProtect(enabled=True)\n

    Parameters: - enabled (bool): True to enable protection, False to disable

    "},{"location":"qsl4a/system/application/#createscriptshortcut","title":"createScriptShortCut()","text":"

    Create a home screen shortcut for a script.

    createScriptShortCut(scriptPath, label=None, iconPath=None, scriptArg=None)\n

    Parameters: - scriptPath (str): Path to the Python script - label (str, optional): Shortcut label - iconPath (str, optional): Path to icon image - scriptArg (str, optional): Argument to pass to script

    "},{"location":"qsl4a/system/application/#device-information","title":"Device Information","text":""},{"location":"qsl4a/system/application/#getandroidid","title":"getAndroidID()","text":"

    Get Android device ID.

    getAndroidID()\n

    Returns: Unique Android device ID string

    "},{"location":"qsl4a/system/application/#getsysinfo","title":"getSysInfo()","text":"

    Get system information.

    getSysInfo()\n

    Returns: Dict with system details

    "},{"location":"qsl4a/system/application/#getlocale","title":"getLocale()","text":"

    Get device locale.

    getLocale()\n

    Returns: Locale string (e.g., \"en_US\")

    "},{"location":"qsl4a/system/application/#getharmonyosinformation","title":"getHarmonyOsInformation()","text":"

    Get HarmonyOS information if running on HarmonyOS.

    getHarmonyOsInformation()\n

    Returns: HarmonyOS version info or None

    "},{"location":"qsl4a/system/application/#isexternalstoragemanager","title":"isExternalStorageManager()","text":"

    Check if app has external storage manager permission.

    isExternalStorageManager()\n

    Returns: True if has permission

    "},{"location":"qsl4a/system/application/#memory-and-display","title":"Memory and Display","text":""},{"location":"qsl4a/system/application/#getmemoryinfo","title":"getMemoryInfo()","text":"

    Get memory information.

    getMemoryInfo()\n

    Returns: Dict with memory stats

    "},{"location":"qsl4a/system/application/#getscreeninfo","title":"getScreenInfo()","text":"

    Get screen information.

    getScreenInfo()\n

    Returns: Dict with width, height, density

    "},{"location":"qsl4a/system/application/#permissions","title":"Permissions","text":""},{"location":"qsl4a/system/application/#checkpermissions","title":"checkPermissions()","text":"

    Check current app permissions.

    checkPermissions()\n

    Returns: Dict of permissions and their status

    "},{"location":"qsl4a/system/application/#requestpermissions","title":"requestPermissions()","text":"

    Request permissions from the user.

    requestPermissions(permissions=None)\n

    Parameters: - permissions (list, optional): List of permissions to request. If None, requests all needed permissions.

    Returns: Result of permission request

    "},{"location":"qsl4a/system/application/#system-actions","title":"System Actions","text":""},{"location":"qsl4a/system/application/#showscreenlock","title":"showScreenLock()","text":"

    Show screen lock (PIN/pattern/password entry).

    showScreenLock()\n
    "},{"location":"qsl4a/system/application/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get system info\ninfo = droid.getSysInfo().result\nprint(f\"System: {info}\")\n\n# Get app version\nversion = droid.getPackageVersion(\"org.qpython.qpy\").result\nprint(f\"QPython version: {version}\")\n\n# List installed apps\napps = droid.getInstalledPackages().result\nprint(f\"Installed apps: {len(apps)}\")\n\n# Launch an app\ndroid.launch(packagename=\"com.android.settings\")\n\n# Check permissions\nperms = droid.checkPermissions().result\nprint(f\"Permissions: {perms}\")\n\n# Request storage permission\ndroid.requestPermissions([\"android.permission.READ_EXTERNAL_STORAGE\"])\n\n# Create shortcut\ndroid.createScriptShortCut(\n    \"/sdcard/my_script.py\",\n    label=\"My Script\",\n    iconPath=\"/sdcard/icon.png\"\n)\n
    "},{"location":"qsl4a/system/battery/","title":"Battery API","text":"

    Monitor device battery status and health.

    "},{"location":"qsl4a/system/battery/#methods","title":"Methods","text":""},{"location":"qsl4a/system/battery/#readbatterydata","title":"readBatteryData()","text":"

    Get complete battery information.

    readBatteryData()\n

    Returns: Dict with battery data

    "},{"location":"qsl4a/system/battery/#batterystartmonitoring","title":"batteryStartMonitoring()","text":"

    Start battery monitoring.

    batteryStartMonitoring()\n
    "},{"location":"qsl4a/system/battery/#batterystopmonitoring","title":"batteryStopMonitoring()","text":"

    Stop battery monitoring.

    batteryStopMonitoring()\n
    "},{"location":"qsl4a/system/battery/#batterygetlevel","title":"batteryGetLevel()","text":"

    Get battery percentage.

    batteryGetLevel()\n

    Returns: Int (0-100)

    "},{"location":"qsl4a/system/battery/#batterygetstatus","title":"batteryGetStatus()","text":"

    Get charging status.

    batteryGetStatus()\n

    Returns: - 1: Unknown - 2: Charging - 3: Discharging - 4: Not charging - 5: Full

    "},{"location":"qsl4a/system/battery/#batterygetplugtype","title":"batteryGetPlugType()","text":"

    Get power source.

    batteryGetPlugType()\n

    Returns: - -1: Unknown - 0: Unplugged - 1: AC charger - 2: USB port

    "},{"location":"qsl4a/system/battery/#batterygethealth","title":"batteryGetHealth()","text":"

    Get battery health.

    batteryGetHealth()\n

    Returns: - 1: Unknown - 2: Good - 3: Overheat - 4: Dead - 5: Over voltage - 6: Unspecified failure

    "},{"location":"qsl4a/system/battery/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get battery level\nlevel = droid.batteryGetLevel().result\nprint(f\"Battery: {level}%\")\n
    "},{"location":"qsl4a/system/qpyinterface/","title":"QPython Interface API","text":"

    Execute QPython scripts and manage shared variables from other apps.

    "},{"location":"qsl4a/system/qpyinterface/#script-execution-methods","title":"Script Execution Methods","text":""},{"location":"qsl4a/system/qpyinterface/#executeqpy","title":"executeQPy()","text":"

    Execute a QPython script.

    executeQPy(path=\"\", arg=None)\n

    Parameters: - path (str): Path to the script file - arg (str, optional): Command line arguments

    Returns: True if started successfully

    "},{"location":"qsl4a/system/qpyinterface/#executeqpyassrv","title":"executeQPyAsSrv()","text":"

    Execute a QPython script as a service.

    executeQPyAsSrv(path=None)\n

    Parameters: - path (str, optional): Path to the script file

    Returns: True if started successfully

    "},{"location":"qsl4a/system/qpyinterface/#executeqpycode","title":"executeQPyCode()","text":"

    Execute Python code directly.

    executeQPyCode(code=None)\n

    Parameters: - code (str, optional): Python code to execute

    Returns: True if started successfully

    "},{"location":"qsl4a/system/qpyinterface/#executeqpycodeassrv","title":"executeQPyCodeAsSrv()","text":"

    Execute Python code as a service.

    executeQPyCodeAsSrv(code=None)\n

    Parameters: - code (str, optional): Python code to execute

    Returns: True if started successfully

    "},{"location":"qsl4a/system/qpyinterface/#shared-variables","title":"Shared Variables","text":"

    Shared variables allow communication between QPython and other apps.

    "},{"location":"qsl4a/system/qpyinterface/#sharedvariableset","title":"sharedVariableSet()","text":"

    Set a Java shared variable.

    sharedVariableSet(key, value)\n

    Parameters: - key (str): Variable name - value (str): Variable value

    Returns: The stored value

    "},{"location":"qsl4a/system/qpyinterface/#sharedvariableget","title":"sharedVariableGet()","text":"

    Get a Java shared variable.

    sharedVariableGet(key)\n

    Parameters: - key (str): Variable name

    Returns: The stored value

    "},{"location":"qsl4a/system/qpyinterface/#sharedvariableremove","title":"sharedVariableRemove()","text":"

    Remove a Java shared variable.

    sharedVariableRemove(key)\n

    Parameters: - key (str): Variable name to remove

    Returns: The removed value

    "},{"location":"qsl4a/system/qpyinterface/#getlastlog","title":"getLastLog()","text":"

    Get the last log output from QPython.

    getLastLog()\n

    Returns: String log content

    "},{"location":"qsl4a/system/qpyinterface/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Execute a script\ndroid.executeQPy(\"/sdcard/my_script.py\", arg=\"test\")\n\n# Execute code directly\ncode = \"print('Hello from QPython!')\"\ndroid.executeQPyCode(code)\n\n# Use shared variables\ndroid.sharedVariableSet(\"username\", \"alice\")\nusername = droid.sharedVariableGet(\"username\").result\nprint(f\"Username: {username}\")\n\n# Remove variable\ndroid.sharedVariableRemove(\"username\")\n\n# Get recent log\nlog = droid.getLastLog().result\nprint(f\"Log: {log}\")\n
    "},{"location":"qsl4a/system/sensors/","title":"Sensor API","text":"

    Access device sensors including accelerometer, gyroscope, magnetometer, and more.

    "},{"location":"qsl4a/system/sensors/#methods","title":"Methods","text":""},{"location":"qsl4a/system/sensors/#startsensingtimed","title":"startSensingTimed()","text":"

    Start sensor monitoring with time intervals.

    startSensingTimed(sensorNumber, delayTime)\n

    Parameters: - sensorNumber (int): Sensor ID (1-3 typically) - delayTime (int): Delay between readings in milliseconds

    "},{"location":"qsl4a/system/sensors/#startsensingthreshold","title":"startSensingThreshold()","text":"

    Start sensor monitoring with threshold trigger.

    startSensingThreshold(sensorNumber, threshold, axis)\n

    Parameters: - sensorNumber (int): Sensor ID - threshold (float): Trigger threshold - axis (int): Axis to monitor (0=X, 1=Y, 2=Z)

    "},{"location":"qsl4a/system/sensors/#stopsensing","title":"stopSensing()","text":"

    Stop all sensor monitoring.

    stopSensing()\n
    "},{"location":"qsl4a/system/sensors/#readsensors","title":"readSensors()","text":"

    Read current sensor data.

    readSensors()\n

    Returns: Sensor data dict

    "},{"location":"qsl4a/system/sensors/#sensorsreadaccelerometer","title":"sensorsReadAccelerometer()","text":"

    Read accelerometer values.

    sensorsReadAccelerometer()\n

    Returns: List [X, Y, Z] in m/s\u00b2

    "},{"location":"qsl4a/system/sensors/#sensorsreadgyroscope","title":"sensorsReadGyroscope()","text":"

    Read gyroscope values.

    sensorsReadGyroscope()\n

    Returns: List [X, Y, Z] in rad/s

    "},{"location":"qsl4a/system/sensors/#sensorsreadmagnetometer","title":"sensorsReadMagnetometer()","text":"

    Read magnetic field values.

    sensorsReadMagnetometer()\n

    Returns: List [X, Y, Z] in \u03bcT

    "},{"location":"qsl4a/system/sensors/#sensorsreadorientation","title":"sensorsReadOrientation()","text":"

    Read device orientation.

    sensorsReadOrientation()\n

    Returns: List [azimuth, pitch, roll] in degrees

    "},{"location":"qsl4a/system/sensors/#sensorsgetlight","title":"sensorsGetLight()","text":"

    Read light sensor value.

    sensorsGetLight()\n

    Returns: Light level in lux

    "},{"location":"qsl4a/system/sensors/#sensorsgetstepcounter","title":"sensorsGetStepCounter()","text":"

    Read step counter.

    sensorsGetStepCounter()\n

    Returns: Number of steps

    "},{"location":"qsl4a/system/sensors/#sensorsgetaccuracy","title":"sensorsGetAccuracy()","text":"

    Get the current sensor accuracy.

    sensorsGetAccuracy()\n

    Returns: Accuracy value (0-3: UNRELIABLE, ACCURACY_LOW, ACCURACY_MEDIUM, ACCURACY_HIGH)

    "},{"location":"qsl4a/system/sensors/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start sensing\ndroid.startSensingTimed(1, 250)\n\n# Read sensors 10 times\nfor i in range(10):\n    accel = droid.sensorsReadAccelerometer().result\n    print(f\"Accel: X={accel[0]:.2f}, Y={accel[1]:.2f}, Z={accel[2]:.2f}\")\n    time.sleep(0.5)\n\ndroid.stopSensing()\n
    "},{"location":"qsl4a/system/settings/","title":"Settings API","text":"

    Control system settings including screen, sound, and network settings.

    "},{"location":"qsl4a/system/settings/#screen-settings","title":"Screen Settings","text":""},{"location":"qsl4a/system/settings/#setscreentimeout","title":"setScreenTimeout()","text":"

    Set the screen timeout value.

    setScreenTimeout(value)\n

    Parameters: - value (int): Screen timeout in seconds

    Returns: Previous timeout value

    "},{"location":"qsl4a/system/settings/#getscreentimeout","title":"getScreenTimeout()","text":"

    Get the current screen timeout.

    getScreenTimeout()\n

    Returns: Current screen timeout in seconds

    "},{"location":"qsl4a/system/settings/#getscreenbrightness","title":"getScreenBrightness()","text":"

    Get the screen brightness value.

    getScreenBrightness()\n

    Returns: Brightness value (0-255)

    "},{"location":"qsl4a/system/settings/#setscreenbrightness","title":"setScreenBrightness()","text":"

    Set the screen brightness.

    setScreenBrightness(value=None)\n

    Parameters: - value (int, optional): Brightness value (0-255), or None for auto

    Returns: Previous brightness value

    "},{"location":"qsl4a/system/settings/#checkscreenon","title":"checkScreenOn()","text":"

    Check if the screen is on.

    checkScreenOn()\n

    Returns: True if screen is on, False otherwise

    "},{"location":"qsl4a/system/settings/#airplane-mode","title":"Airplane Mode","text":""},{"location":"qsl4a/system/settings/#checkairplanemode","title":"checkAirplaneMode()","text":"

    Check if airplane mode is enabled.

    checkAirplaneMode()\n

    Returns: True if airplane mode is on

    "},{"location":"qsl4a/system/settings/#ringer-settings","title":"Ringer Settings","text":""},{"location":"qsl4a/system/settings/#checkringersilentmode","title":"checkRingerSilentMode()","text":"

    Check if ringer is in silent mode.

    checkRingerSilentMode()\n

    Returns: True if silent mode is on

    "},{"location":"qsl4a/system/settings/#toggleringersilentmode","title":"toggleRingerSilentMode()","text":"

    Toggle ringer silent mode.

    toggleRingerSilentMode(enabled=None)\n

    Parameters: - enabled (bool, optional): True to enable, False to disable, None to toggle

    Returns: New state

    "},{"location":"qsl4a/system/settings/#togglevibratemode","title":"toggleVibrateMode()","text":"

    Toggle vibrate mode.

    toggleVibrateMode(enabled=None, ringer=None)\n

    Parameters: - enabled (bool, optional): Toggle vibrate on/off - ringer (bool, optional): Apply to ringer mode

    Returns: New state

    "},{"location":"qsl4a/system/settings/#getvibratemode","title":"getVibrateMode()","text":"

    Get the vibrate mode setting.

    getVibrateMode(ringer=None)\n

    Parameters: - ringer (bool, optional): Check ringer vibrate mode

    Returns: True if vibrate is enabled

    "},{"location":"qsl4a/system/settings/#volume-settings","title":"Volume Settings","text":""},{"location":"qsl4a/system/settings/#getringervolume","title":"getRingerVolume()","text":"

    Get the current ringer volume.

    getRingerVolume()\n

    Returns: Ringer volume level (0-7 typically)

    "},{"location":"qsl4a/system/settings/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

    Get the maximum ringer volume.

    getMaxRingerVolume()\n

    Returns: Maximum ringer volume

    "},{"location":"qsl4a/system/settings/#setringervolume","title":"setRingerVolume()","text":"

    Set the ringer volume.

    setRingerVolume(volume)\n

    Parameters: - volume (int): Volume level

    "},{"location":"qsl4a/system/settings/#getmediavolume","title":"getMediaVolume()","text":"

    Get the current media volume.

    getMediaVolume()\n

    Returns: Media volume level (0-15 typically)

    "},{"location":"qsl4a/system/settings/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

    Get the maximum media volume.

    getMaxMediaVolume()\n

    Returns: Maximum media volume

    "},{"location":"qsl4a/system/settings/#setmediavolume","title":"setMediaVolume()","text":"

    Set the media volume.

    setMediaVolume(volume)\n

    Parameters: - volume (int): Volume level

    "},{"location":"qsl4a/system/settings/#system-info","title":"System Info","text":""},{"location":"qsl4a/system/settings/#elapsedrealtimenanos","title":"elapsedRealtimeNanos()","text":"

    Get nanoseconds since system startup.

    elapsedRealtimeNanos()\n

    Returns: Nanoseconds (can be used for timing)

    "},{"location":"qsl4a/system/settings/#gettrafficstats","title":"getTrafficStats()","text":"

    Get network traffic statistics.

    getTrafficStats(flags=7)\n

    Parameters: - flags (int): Which stats to retrieve (default: 7 = all)

    Returns: Dict with transmit/receive bytes

    "},{"location":"qsl4a/system/settings/#getapptxbytes","title":"getAppTxBytes()","text":"

    Get transmit bytes for QPython app.

    getAppTxBytes(packageName)\n

    Parameters: - packageName (str): Package name

    Returns: Dict with tx/rx bytes

    "},{"location":"qsl4a/system/settings/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Screen settings\ncurrent_timeout = droid.getScreenTimeout().result\nprint(f\"Current timeout: {current_timeout}s\")\ndroid.setScreenTimeout(30)\n\n# Check screen\nif droid.checkScreenOn().result:\n    print(\"Screen is on\")\n\n# Volume control\nmedia_vol = droid.getMediaVolume().result\nprint(f\"Media volume: {media_vol}\")\ndroid.setMediaVolume(10)\n\n# Check airplane mode\nif droid.checkAirplaneMode().result:\n    print(\"Airplane mode is on\")\n
    "},{"location":"qsl4a/system/sysinfo/","title":"System Information","text":"

    Retrieve device and system information.

    "},{"location":"qsl4a/system/sysinfo/#device-information","title":"Device Information","text":""},{"location":"qsl4a/system/sysinfo/#getandroidid","title":"getAndroidID()","text":"

    Get the Android device ID.

    getAndroidID()\n

    Returns: String device ID

    "},{"location":"qsl4a/system/sysinfo/#getsysinfo","title":"getSysInfo()","text":"

    Get comprehensive system information.

    getSysInfo()\n

    Returns: Dict with system details

    "},{"location":"qsl4a/system/sysinfo/#getlocale","title":"getLocale()","text":"

    Get device locale settings.

    getLocale()\n

    Returns: Locale string (e.g., \"en_US\")

    "},{"location":"qsl4a/system/sysinfo/#memory","title":"Memory","text":""},{"location":"qsl4a/system/sysinfo/#getmemoryinfo","title":"getMemoryInfo()","text":"

    Get RAM information.

    getMemoryInfo()\n

    Returns: Dict with memory stats

    "},{"location":"qsl4a/system/sysinfo/#display","title":"Display","text":""},{"location":"qsl4a/system/sysinfo/#getscreeninfo","title":"getScreenInfo()","text":"

    Get display information.

    getScreenInfo()\n

    Returns: Dict with width, height, density

    "},{"location":"qsl4a/system/sysinfo/#identifiers","title":"Identifiers","text":""},{"location":"qsl4a/system/sysinfo/#getimei","title":"getImei()","text":"

    Get device IMEI.

    getImei(slotIndex=None)\n
    "},{"location":"qsl4a/system/sysinfo/#getmeid","title":"getMeid()","text":"

    Get device MEID.

    getMeid(slotIndex=None)\n
    "},{"location":"qsl4a/system/sysinfo/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Device ID\nandroid_id = droid.getAndroidID().result\nprint(f\"Android ID: {android_id}\")\n\n# Screen info\nscreen = droid.getScreenInfo().result\nprint(f\"Screen: {screen['width']}x{screen['height']}\")\n\n# Memory\nmemory = droid.getMemoryInfo().result\nprint(f\"Memory: {memory}\")\n
    "},{"location":"qsl4a/system/wakelock/","title":"WakeLock API","text":"

    Control device wake locks to keep the CPU or screen on.

    "},{"location":"qsl4a/system/wakelock/#wake-lock-types","title":"Wake Lock Types","text":"

    QSL4A provides different wake lock types:

    Type Description Full CPU on, screen bright, keyboard bright Partial CPU on only Bright CPU on, screen bright Dim CPU on, screen dim"},{"location":"qsl4a/system/wakelock/#wake-lock-methods","title":"Wake Lock Methods","text":""},{"location":"qsl4a/system/wakelock/#wakelockacquirefull","title":"wakeLockAcquireFull()","text":"

    Acquire a full wake lock (CPU on, screen bright, keyboard bright).

    wakeLockAcquireFull()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockacquirepartial","title":"wakeLockAcquirePartial()","text":"

    Acquire a partial wake lock (CPU on only).

    wakeLockAcquirePartial()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockacquirebright","title":"wakeLockAcquireBright()","text":"

    Acquire a bright wake lock (CPU on, screen bright).

    wakeLockAcquireBright()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockacquiredim","title":"wakeLockAcquireDim()","text":"

    Acquire a dim wake lock (CPU on, screen dim).

    wakeLockAcquireDim()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockrelease","title":"wakeLockRelease()","text":"

    Release the wake lock.

    wakeLockRelease()\n
    "},{"location":"qsl4a/system/wakelock/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Acquire full wake lock\ndroid.wakeLockAcquireFull()\n\n# Do important work while keeping screen on\nprint(\"Screen will stay on\")\ntime.sleep(10)\n\n# Release when done\ndroid.wakeLockRelease()\n\n# Or use partial lock for background tasks\ndroid.wakeLockAcquirePartial()\n# CPU stays on even with screen off\ntime.sleep(30)\ndroid.wakeLockRelease()\n

    Note: Remember to release wake locks when no longer needed to conserve battery.

    "},{"location":"qsl4a/ui/accessibility/","title":"Accessibility Service","text":"

    The Accessibility Service allows automation of UI interactions like clicks, swipes, and system actions.

    "},{"location":"qsl4a/ui/accessibility/#service-control","title":"Service Control","text":""},{"location":"qsl4a/ui/accessibility/#accessibilitystartservice","title":"accessibilityStartService()","text":"

    Start the accessibility service.

    accessibilityStartService()\n

    Returns: True if successful, False otherwise

    "},{"location":"qsl4a/ui/accessibility/#accessibilityserviceenabled","title":"accessibilityServiceEnabled()","text":"

    Check if accessibility service is enabled.

    accessibilityServiceEnabled()\n

    Returns: True or False

    "},{"location":"qsl4a/ui/accessibility/#screen-interactions","title":"Screen Interactions","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityclick","title":"accessibilityClick()","text":"

    Click at screen coordinates.

    accessibilityClick(x=0, y=0, t=50)\n

    Parameters: - x (int/float): X coordinate (0=center, decimals supported) - y (int/float): Y coordinate (0=center, decimals supported) - t (int): Press duration in milliseconds (default: 50)

    "},{"location":"qsl4a/ui/accessibility/#accessibilityslide","title":"accessibilitySlide()","text":"

    Multi-point slide gesture.

    accessibilitySlide(XnYn=None, t=None)\n

    Parameters: - XnYn (list): Coordinates [X1, Y1, X2, Y2, ... Xn, Yn] - t (int): Slide duration (default: 50*n ms)

    "},{"location":"qsl4a/ui/accessibility/#system-actions","title":"System Actions","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityaction","title":"accessibilityAction()","text":"

    Execute system action by code.

    accessibilityAction(actionCode)\n

    Action Codes: | Code | Constant | Description | |------|----------|-------------| | 1 | BACK | Back button | | 2 | HOME | Home button | | 3 | RECENTS | Recent apps | | 4 | NOTIFICATIONS | Open notifications | | 5 | QUICK_SETTINGS | Open quick settings | | 6 | POWER_DIALOG | Power menu | | 7 | TOGGLE_SPLIT_SCREEN | Split screen | | 8 | LOCK_SCREEN | Lock screen | | 9 | TAKE_SCREENSHOT | Take screenshot | | 10 | KEYCODE_HEADSETHOOK | Headset hook | | 11-14 | ACCESSIBILITY_ | Accessibility buttons | | 15 | DISMISS_NOTIFICATION_SHADE | Close notifications | | 16-20 | DPAD_ | Directional pad | | 21 | MENU | Menu button | | 22 | MEDIA_PLAY_PAUSE | Play/Pause media |

    "},{"location":"qsl4a/ui/accessibility/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/accessibility/#click-center-screen","title":"Click Center Screen","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Start service\nif not droid.accessibilityServiceEnabled().result:\n    droid.accessibilityStartService()\n\n# Click center (0,0 = center)\ndroid.accessibilityClick(0, 0, t=100)\n
    "},{"location":"qsl4a/ui/accessibility/#swipe-gesture","title":"Swipe Gesture","text":"
    # Swipe from bottom to top (scroll up)\ndroid.accessibilitySlide([0, 1.5, 0, -1.5], t=300)\n
    "},{"location":"qsl4a/ui/accessibility/#system-navigation","title":"System Navigation","text":"
    # Press home\ndroid.accessibilityAction(2)\n\n# Press back\ndroid.accessibilityAction(1)\n\n# Open notifications\ndroid.accessibilityAction(4)\n
    "},{"location":"qsl4a/ui/accessibility/#tap-specific-location","title":"Tap Specific Location","text":"
    # Tap at screen coordinate (500, 800)\ndroid.accessibilityClick(500, 800)\n\n# Tap at relative position (center horizontally, 3/4 down)\ndroid.accessibilityClick(0, 1.5)\n
    "},{"location":"qsl4a/ui/dialogs/","title":"Dialog System","text":"

    QSL4A provides comprehensive dialog support for user interaction, including alerts, input dialogs, choice dialogs, and progress dialogs.

    "},{"location":"qsl4a/ui/dialogs/#alert-dialogs","title":"Alert Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowalert","title":"dialogShowAlert()","text":"

    Show a simple alert dialog.

    dialogShowAlert(title=\"Alert\", message=\"The message of the alert.\",\n                positiveButtonText=\"OK\", negativeButtonText=None,\n                neutralButtonText=None, messageIsHtml=False)\n

    Parameters: - title (str): Dialog title - message (str): Message text - positiveButtonText (str): Positive button label - negativeButtonText (str, optional): Negative button label - neutralButtonText (str, optional): Neutral button label - messageIsHtml (bool): Parse message as HTML

    Returns: Result with button clicked

    "},{"location":"qsl4a/ui/dialogs/#dialogshowsimplechoice","title":"dialogShowSimpleChoice()","text":"

    Show a simple choice dialog with items.

    dialogShowSimpleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

    Parameters: - items (list): List of choice strings

    Returns: Result with selected item

    "},{"location":"qsl4a/ui/dialogs/#input-dialogs","title":"Input Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialoggetinput","title":"dialogGetInput()","text":"

    Get text input from user.

    dialogGetInput(title=\"Value\", message=\"Please enter value:\",\n               defaultText=None, messageIsHtml=False)\n

    Returns: Result with user's input text

    "},{"location":"qsl4a/ui/dialogs/#dialoggetpassword","title":"dialogGetPassword()","text":"

    Get password input.

    dialogGetPassword(title=\"Password\", message=\"Please enter password:\")\n

    Returns: Result with password entered

    "},{"location":"qsl4a/ui/dialogs/#dialogcreateinput","title":"dialogCreateInput()","text":"

    Create a custom input dialog.

    dialogCreateInput(title=\"Value\", message=\"Please enter value:\",\n                  defaultText=None, inputType=None)\n

    Parameters: - inputType (str): Input type (e.g., \"text\", \"number\", \"textPassword\")

    "},{"location":"qsl4a/ui/dialogs/#dialogcreatepassword","title":"dialogCreatePassword()","text":"

    Create a password input dialog.

    dialogCreatePassword(title=\"Password\", message=\"Please enter password:\")\n
    "},{"location":"qsl4a/ui/dialogs/#dialogcreateseekbar","title":"dialogCreateSeekBar()","text":"

    Create a seek bar/slider dialog.

    dialogCreateSeekBar(starting_value=50, maximum_value=100, title=\"\", message=\"\")\n

    Parameters: - starting_value (int): Initial value - maximum_value (int): Maximum value

    "},{"location":"qsl4a/ui/dialogs/#choice-dialogs","title":"Choice Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowsinglechoice","title":"dialogShowSingleChoice()","text":"

    Show single choice (radio) dialog.

    dialogShowSingleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, selected=-1, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

    Parameters: - items (list): List of choice strings - selected (int): Default selected index

    "},{"location":"qsl4a/ui/dialogs/#dialogshowmultichoice","title":"dialogShowMultiChoice()","text":"

    Show multiple choice (checkbox) dialog.

    dialogShowMultiChoice(title=\"Alert\", message=\"The message of the alert.\",\n                      items=None, selected=None, positiveButtonText=\"OK\",\n                      negativeButtonText=None, neutralButtonText=None,\n                      messageIsHtml=False)\n

    Parameters: - items (list): List of choice strings - selected (list): List of initially selected indices

    "},{"location":"qsl4a/ui/dialogs/#dialogsetsinglechoiceitems","title":"dialogSetSingleChoiceItems()","text":"

    Set single choice items for a dialog.

    dialogSetSingleChoiceItems(items, selected=-1)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetmultichoiceitems","title":"dialogSetMultiChoiceItems()","text":"

    Set multiple choice items for a dialog.

    dialogSetMultiChoiceItems(items, selected=None)\n
    "},{"location":"qsl4a/ui/dialogs/#progress-dialogs","title":"Progress Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatespinnerprogress","title":"dialogCreateSpinnerProgress()","text":"

    Create indeterminate progress dialog.

    dialogCreateSpinnerProgress(title=None, message=None, maximum_progress=100)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogcreatehorizontalprogress","title":"dialogCreateHorizontalProgress()","text":"

    Create horizontal progress dialog.

    dialogCreateHorizontalProgress(title=None, message=None, maximum_progress=100)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetcurrentprogress","title":"dialogSetCurrentProgress()","text":"

    Update progress value.

    dialogSetCurrentProgress(current)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetmaxprogress","title":"dialogSetMaxProgress()","text":"

    Set maximum progress value.

    dialogSetMaxProgress(max)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetprogressmessage","title":"dialogSetProgressMessage()","text":"

    Update the progress dialog message.

    dialogSetProgressMessage(message)\n
    "},{"location":"qsl4a/ui/dialogs/#picker-dialogs","title":"Picker Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatedatepicker","title":"dialogCreateDatePicker()","text":"

    Create date picker dialog.

    dialogCreateDatePicker(year=1970, month=1, day=1)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogcreatetimepicker","title":"dialogCreateTimePicker()","text":"

    Create time picker dialog.

    dialogCreateTimePicker(hour=0, minute=0, is24hour=False)\n
    "},{"location":"qsl4a/ui/dialogs/#custom-dialog-creation","title":"Custom Dialog Creation","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatealert","title":"dialogCreateAlert()","text":"

    Create a custom alert dialog.

    dialogCreateAlert(title=None, message=None)\n

    Creates an empty alert dialog. Use with other dialogSet* functions to customize.

    "},{"location":"qsl4a/ui/dialogs/#dialogsetitems","title":"dialogSetItems()","text":"

    Set simple list items for the dialog.

    dialogSetItems(items)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetpositivebuttontext","title":"dialogSetPositiveButtonText()","text":"

    Set positive button text.

    dialogSetPositiveButtonText(text)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetnegativebuttontext","title":"dialogSetNegativeButtonText()","text":"

    Set negative button text.

    dialogSetNegativeButtonText(text)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetneutralbuttontext","title":"dialogSetNeutralButtonText()","text":"

    Set neutral button text.

    dialogSetNeutralButtonText(text)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetmessageishtml","title":"dialogSetMessageIsHtml()","text":"

    Set whether message should be parsed as HTML.

    dialogSetMessageIsHtml(messageIsHtml=True)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogshow","title":"dialogShow()","text":"

    Show the created custom dialog.

    dialogShow()\n
    "},{"location":"qsl4a/ui/dialogs/#dialog-control","title":"Dialog Control","text":""},{"location":"qsl4a/ui/dialogs/#dialogdismiss","title":"dialogDismiss()","text":"

    Dismiss current dialog.

    dialogDismiss()\n
    "},{"location":"qsl4a/ui/dialogs/#dialoggetresponse","title":"dialogGetResponse()","text":"

    Get dialog response.

    dialogGetResponse()\n
    "},{"location":"qsl4a/ui/dialogs/#dialoggetselecteditems","title":"dialogGetSelectedItems()","text":"

    Get selected items from choice dialog.

    dialogGetSelectedItems()\n
    "},{"location":"qsl4a/ui/dialogs/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/dialogs/#simple-alert","title":"Simple Alert","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Show alert\ndroid.dialogShowAlert(\"Warning\", \"This is an important message!\")\n
    "},{"location":"qsl4a/ui/dialogs/#input-dialog","title":"Input Dialog","text":"
    # Get user input\nresult = droid.dialogGetInput(\"Name\", \"Enter your name:\", \"John\").result\nprint(f\"Hello, {result}!\")\n
    "},{"location":"qsl4a/ui/dialogs/#custom-dialog-with-buttons","title":"Custom Dialog with Buttons","text":"
    # Create custom dialog\ndroid.dialogCreateAlert(\"Custom\", \"Choose an option\")\ndroid.dialogSetItems([\"Option 1\", \"Option 2\", \"Option 3\"])\ndroid.dialogShow()\n\n# Get response\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response['item']}\")\n
    "},{"location":"qsl4a/ui/dialogs/#progress-dialog","title":"Progress Dialog","text":"
    # Create progress dialog\ndroid.dialogCreateHorizontalProgress(\"Loading\", \"Please wait...\", 100)\ndroid.dialogShow()\n\n# Update progress\nfor i in range(101):\n    droid.dialogSetCurrentProgress(i)\n    time.sleep(0.05)\n\ndroid.dialogDismiss()\n
    "},{"location":"qsl4a/ui/dialogs/#date-picker","title":"Date Picker","text":"
    # Show date picker\ndroid.dialogCreateDatePicker(2024, 1, 15)\ndroid.dialogShow()\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response}\")\n
    "},{"location":"qsl4a/ui/floatview/","title":"FloatView","text":"

    Floating window support for overlay UI elements that stay on top of other applications.

    "},{"location":"qsl4a/ui/floatview/#methods","title":"Methods","text":""},{"location":"qsl4a/ui/floatview/#floatview_1","title":"floatView()","text":"

    Show or modify a floating view.

    floatView(Args=None)\n

    Parameters: - Args (dict): Configuration dictionary with the following keys: - index (int): Float view index (-1 to create new, >=0 to modify existing) - text (str): Text content to display - html (str): HTML content (used if text is omitted) - width (int): View width in pixels (default: 300) - height (int): View height in pixels (default: 150) - x (int): X position (0 = center, positive/negative for offset) - y (int): Y position (0 = center, positive/negative for offset) - backColor (str): Background color in ARGB hex (default: '7f7f7f7f') - textColor (str): Text color in ARGB hex (default: 'ff000000') - textSize (int): Text size (default: 10) - textAlign (int): Text alignment (0 = inherit) - script (str): Script path to run after long click close - arg: Script argument - clickRemove (bool): Enable click to remove (default: True) - flag (int): Window flag (default: 40 - touchable)

    Returns: Current chain list length

    "},{"location":"qsl4a/ui/floatview/#floatviewcount","title":"floatViewCount()","text":"

    Get the number of active float views.

    floatViewCount()\n

    Returns: Number of float views

    "},{"location":"qsl4a/ui/floatview/#floatviewresult","title":"floatViewResult()","text":"

    Get the result/status of a float view.

    floatViewResult(index=-1)\n

    Parameters: - index (int): Float view index (default: -1, returns last operation result)

    Returns: Dict with operation details including: - x, y: Position - time: Timestamp - operation: Operation type ('initial', 'move', etc.) - index: View index - removed: True if view was removed

    "},{"location":"qsl4a/ui/floatview/#floatviewremove","title":"floatViewRemove()","text":"

    Remove a float view.

    floatViewRemove(index=-1)\n

    Parameters: - index (int): Index of view to remove (default: -1 removes the last one)

    Returns: 1 if successful, 0 otherwise

    "},{"location":"qsl4a/ui/floatview/#constants","title":"Constants","text":"
    • floatView.INDEX_NEW = -1 - Create new float view
    • floatView.FLAG_DEFAULT_TOUCHABLE = 40 - Default touchable flag
    • floatView.TEXT_ALIGNMENT_INHERIT = 0
    • floatView.TEXT_ALIGNMENT_CENTER - Center text alignment
    "},{"location":"qsl4a/ui/floatview/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/floatview/#basic-float-view","title":"Basic Float View","text":"
    import androidhelper\nfrom androidhelper import Android\n\ndroid = androidhelper.Android()\n\n# Create a simple float view\ndroid.floatView({\n    'index': -1,  # Create new\n    'text': 'Hello World',\n    'width': 400,\n    'height': 300,\n    'x': -300,  # Offset from center\n    'y': -400,\n    'backColor': 'ff0000',  # Red background\n    'textColor': '0000ff',  # Blue text\n    'textSize': 16,\n    'textAlign': droid.floatView.TEXT_ALIGNMENT_CENTER\n})\n\n# Check count\nprint(f\"Float views: {droid.floatViewCount().result}\")\n\n# Get result\nresult = droid.floatViewResult().result\nprint(f\"View info: {result}\")\n\n# Remove the float view\ndroid.floatViewRemove(0)\n
    "},{"location":"qsl4a/ui/floatview/#html-content","title":"HTML Content","text":"
    # Create float view with HTML content\ndroid.floatView({\n    'text': '',  # Empty text to use HTML\n    'html': '<h1>Title</h1><p>Rich <b>HTML</b> content</p>',\n    'width': 500,\n    'height': 400\n})\n
    "},{"location":"qsl4a/ui/floatview/#modify-existing-view","title":"Modify Existing View","text":"
    # Create initial view\ndroid.floatView({'text': 'Initial Text', 'width': 300, 'height': 150})\n\n# Modify the same view (index 0)\ndroid.floatView({\n    'index': 0,\n    'text': 'Updated Text!',\n    'backColor': '7f00ff00'  # Green background\n})\n\n# Check the move/change result\nresult = droid.floatViewResult(0).result\nprint(f\"Operation: {result.get('operation')}, Position: ({result.get('x')}, {result.get('y')})\")\n
    "},{"location":"qsl4a/ui/floatview/#multiple-float-views","title":"Multiple Float Views","text":"
    # Create multiple views\nfor i in range(3):\n    droid.floatView({\n        'index': -1,\n        'text': f'View {i}',\n        'x': i * 100 - 150,\n        'y': i * 100 - 150,\n        'backColor': f'{i}f{i}f{i}f'\n    })\n\nprint(f\"Total views: {droid.floatViewCount().result}\")\n\n# Remove all views\nwhile droid.floatViewCount().result > 0:\n    droid.floatViewRemove()\n
    "},{"location":"qsl4a/ui/floatview/#with-script-callback","title":"With Script Callback","text":"
    # Create float view that runs script on close\ndroid.floatView({\n    'text': 'Click to close and run script',\n    'script': '/sdcard/my_script.py',\n    'arg': 'hello from float view',\n    'clickRemove': True\n})\n
    "},{"location":"qsl4a/ui/fullscreen/","title":"FullScreen UI","text":"

    Create custom fullscreen interfaces with native Android layouts.

    "},{"location":"qsl4a/ui/fullscreen/#layout-methods","title":"Layout Methods","text":""},{"location":"qsl4a/ui/fullscreen/#fullshow","title":"fullShow()","text":"

    Show a fullscreen layout.

    fullShow(layout, title=None, theme=None)\n

    Parameters: - layout (str): JSON layout definition or layout string - title (str, optional): Window title - theme (str, optional): Theme name

    Returns: Window ID

    "},{"location":"qsl4a/ui/fullscreen/#fulldismiss","title":"fullDismiss()","text":"

    Close fullscreen window.

    fullDismiss()\n
    "},{"location":"qsl4a/ui/fullscreen/#fullquery","title":"fullQuery()","text":"

    Query all widget values.

    fullQuery()\n

    Returns: Dict of widget IDs and values

    "},{"location":"qsl4a/ui/fullscreen/#fullquerydetail","title":"fullQueryDetail()","text":"

    Query specific widget details.

    fullQueryDetail(id)\n
    "},{"location":"qsl4a/ui/fullscreen/#property-methods","title":"Property Methods","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperty","title":"fullGetProperty()","text":"

    Get widget property.

    fullGetProperty(id, property)\n
    "},{"location":"qsl4a/ui/fullscreen/#fullsetproperty","title":"fullSetProperty()","text":"

    Set widget property.

    fullSetProperty(id, property, value)\n
    "},{"location":"qsl4a/ui/fullscreen/#fullsetlist","title":"fullSetList()","text":"

    Set list widget items.

    fullSetList(id, list, isHtml=False, listType=0)\n
    "},{"location":"qsl4a/ui/fullscreen/#fullsetlist2","title":"fullSetList2()","text":"

    Set list widget items with resource ID.

    fullSetList2(id, list, intRes)\n

    Parameters: - id (str): Widget ID - list (list): List of items - intRes (int): Android resource ID for list item layout

    "},{"location":"qsl4a/ui/fullscreen/#fullsetlistselected","title":"fullSetListSelected()","text":"

    Set selected item in a list.

    fullSetListSelected(id, selected)\n

    Parameters: - id (str): List widget ID - selected (int): Index of item to select

    "},{"location":"qsl4a/ui/fullscreen/#fullgetlistselected","title":"fullGetListSelected()","text":"

    Get the currently selected list item index.

    fullGetListSelected(id)\n

    Parameters: - id (str): List widget ID

    Returns: Selected item index

    "},{"location":"qsl4a/ui/fullscreen/#batch-property-operations","title":"Batch Property Operations","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperties","title":"fullGetProperties()","text":"

    Get properties for multiple widgets at once.

    fullGetProperties(ids, property)\n

    Parameters: - ids (list): List of widget IDs - property (str): Property name to get

    Returns: Dict mapping widget IDs to property values

    "},{"location":"qsl4a/ui/fullscreen/#fullsetproperties","title":"fullSetProperties()","text":"

    Set property for multiple widgets at once.

    fullSetProperties(ids, property, value)\n

    Parameters: - ids (list): List of widget IDs - property (str): Property name to set - value: Property value

    "},{"location":"qsl4a/ui/fullscreen/#screenshot","title":"Screenshot","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetscreenshot","title":"fullGetScreenShot()","text":"

    Capture fullscreen screenshot.

    fullGetScreenShot(path=None)\n

    Parameters: - path (str, optional): Save path. If None, returns in event

    Returns: Event with screenshot data

    "},{"location":"qsl4a/ui/fullscreen/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Define layout\nlayout = '''\n{ \"type\": \"LinearLayout\", \"orientation\": \"vertical\",\n  \"children\": [\n    { \"type\": \"TextView\", \"id\": \"title\", \"text\": \"Hello\" },\n    { \"type\": \"Button\", \"id\": \"btn\", \"text\": \"Click Me\" }\n  ]\n}\n'''\n\n# Show layout\ndroid.fullShow(layout, \"My App\")\n\n# Query button click\nevent = droid.eventWaitFor('click', timeout=10)\nif event.result:\n    widget_id = event.result['data']['id']\n    if widget_id == 'btn':\n        print(\"Button clicked!\")\n\ndroid.fullDismiss()\n
    "}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"QPython Project","text":"

    QPython project is not only a powerful Python IDE for Android, but also an active technology community.

    "},{"location":"#ai-enabled-python-ide-for-android","title":"AI-Enabled Python IDE for Android","text":"

    QPython is your gateway to Python programming on Android. With an integrated Python interpreter, AI model engine, and mobile development toolchain, it empowers you to build web applications, perform scientific computing, and create intelligent apps \u2014 all from your mobile device.

    Whether you're learning to code, building data science projects, or developing AI-powered applications, QPython provides a complete mobile programming solution with comprehensive developer resources and an active community to support your journey.

    • Branches \u2013 Learn about the different QPython versions (IDE, Community, Plus) and choose the right one for your needs
    • Updates \u2013 Stay informed about the latest features, improvements, and release notes
    "},{"location":"#getting-started","title":"Getting Started","text":"

    How to start quickly? Just follow these steps:

    • Getting Started
    • Hello World Tutorial
    "},{"location":"#programming-guide","title":"Programming Guide","text":"

    QPython not only provides basic Python interface support, but more importantly, it also enables you to call Android APIs using Python through the QSL4A interface.

    • Python Standard Library \u2013 For general Python syntax and built-in libraries
    • QSL4A API \u2013 For accessing Android device features (camera, sensors, SMS, etc.) from Python
    • QPYPI Guide \u2013 For installing additional Python packages
    • Editor Guide \u2013 For using the built-in code editor
    • External API \u2013 For integrating with external applications
    "},{"location":"#download-resources","title":"Download Resources","text":"
    • Google Drive
    • \u5fae\u4fe1\u7f51\u76d8
    "},{"location":"#community-feedback","title":"Community & Feedback","text":"
    • Discord
    • Facebook Group
    • \u4e2d\u6587\u4ea4\u6d41\u793e\u533a
    • Newsletter (Google Groups)
    • Report Issues
    • Request Extensions
    "},{"location":"#follow-us","title":"Follow Us","text":"
    • Facebook
    • Twitter/X
    • YouTube
    "},{"location":"AIPyApp/","title":"AIPyApp - AI-Powered Program Generator","text":"

    AIPyApp is an intelligent tool in QPython that uses AI to automatically generate Python programs from natural language instructions.

    "},{"location":"AIPyApp/#overview","title":"Overview","text":"

    AIPyApp transforms the way you write code - simply describe what you want in natural language, and the AI will generate the Python program for you. QPython will also feature AIPy Academy - a platform offering Python programming courses tailored for the AI era.

    "},{"location":"AIPyApp/#installation","title":"Installation","text":""},{"location":"AIPyApp/#step-1-launch-from-dashboard","title":"Step 1: Launch from Dashboard","text":"
    1. Open QPython and go to the Dashboard
    2. Long press the start button

    If AIPyApp is not installed, you will be prompted to confirm the installation. Press Enter to proceed.

    QPython will automatically download and install the required dependencies from PYPI. Please wait patiently for the installation to complete.

    "},{"location":"AIPyApp/#step-2-restart-aipyapp","title":"Step 2: Restart AIPyApp","text":"

    After installation, return to the QPython Dashboard and long press the start button again to launch AIPyApp.

    "},{"location":"AIPyApp/#configuration","title":"Configuration","text":""},{"location":"AIPyApp/#setting-up-your-ai-key","title":"Setting Up Your AI Key","text":"

    On the first launch, you need to provide an AI API key:

    1. Register at PGPT: Create an account at https://user.pgpt.cloud to generate your AI key
    2. Advanced Option: AIPyApp also supports custom AI keys from OpenAI, Deepseek, and other providers (see advanced tutorials for details)
    "},{"location":"AIPyApp/#entering-your-ai-key","title":"Entering Your AI Key","text":"
    1. Long press on the input prompt
    2. Select Paste from the popup menu
    3. Press Enter to confirm

    Your AI key will be saved for future sessions.

    "},{"location":"AIPyApp/#using-aipyapp","title":"Using AIPyApp","text":"

    After configuration, you enter the AIPyApp console mode. Simply type your instructions in natural language!

    "},{"location":"AIPyApp/#example-command","title":"Example Command","text":"

    Try entering:

    Use QSL4A to create a HELLO QPY program as a demo\n

    AIPyApp will: 1. Understand your natural language request 2. Generate the corresponding Python code 3. Execute the program automatically

    That's it - you've created a working Python program without writing any code!

    "},{"location":"AIPyApp/#demo","title":"Demo","text":"

    The example above demonstrates how AIPyApp can: - Understand Chinese instructions - Generate QSL4A-based Python code - Run the program immediately

    Explore AIPyApp to discover more capabilities and start building Python programs effortlessly.

    "},{"location":"AIPyApp/#learn-more","title":"Learn More","text":"

    Stay tuned for AIPy Academy at aipy.org - upcoming courses on learning and using Python programming in the AI era.

    "},{"location":"GraphicalInterface/","title":"Graphical Interface (Turtle & Tkinter)","text":"

    This guide explains how to enable graphical interface support (Turtle and Tkinter) in QPython on Android devices.

    "},{"location":"GraphicalInterface/#overview","title":"Overview","text":"

    QPython can run Turtle and Tkinter applications, but requires additional software to provide graphical display support on Android.

    "},{"location":"GraphicalInterface/#prerequisites","title":"Prerequisites","text":"

    Before starting, you need to download the following resources:

    1. Xserver.apk - A companion app that provides graphical support for Turtle/Tkinter
    2. Download from: QPythonProject/Extra on Google Drive
    3. Turtle & Tkinter QPython graphical interface extension - Install via QPython's QPYPI
    "},{"location":"GraphicalInterface/#installation-steps","title":"Installation Steps","text":""},{"location":"GraphicalInterface/#step-1-install-xserver","title":"Step 1: Install Xserver","text":"

    Download and install Xserver.apk from the QPython Extra resources directory on Google Drive.

    "},{"location":"GraphicalInterface/#step-2-install-qpython-extension","title":"Step 2: Install QPython Extension","text":"

    Open QPython and navigate to QPYPI. Find and install the Turtle & Tkinter QPython graphical interface extension.

    "},{"location":"GraphicalInterface/#step-3-configure-xserver-battery-settings","title":"Step 3: Configure Xserver Battery Settings","text":"

    To prevent Xserver from being killed when running in the background:

    1. Go to your device's Settings > Apps > Xserver
    2. Find Battery settings
    3. Set battery management to \"Unrestricted\" or \"No restrictions\"

    This ensures Xserver continues running when switched to background.

    "},{"location":"GraphicalInterface/#step-4-configure-qpython-battery-settings-recommended","title":"Step 4: Configure QPython Battery Settings (Recommended)","text":"

    Similarly, set QPython's battery management to \"Unrestricted\" to prevent process termination:

    1. Go to Settings > Apps > QPython
    2. Find Battery settings
    3. Set battery management to \"Unrestricted\"
    "},{"location":"GraphicalInterface/#step-5-launch-xserver","title":"Step 5: Launch Xserver","text":"

    Start the Xserver app and switch it to run as a background task before running your Turtle/Tkinter application.

    "},{"location":"GraphicalInterface/#running-turtletkinter-applications","title":"Running Turtle/Tkinter Applications","text":"

    After completing the setup:

    1. Ensure Xserver is running in the background
    2. Run your Turtle or Tkinter application in QPython
    3. Switch to Xserver to view the graphical output
    "},{"location":"GraphicalInterface/#demo-program","title":"Demo Program","text":"

    You can download and try the Turtle Draw Doraemon demo program from QPYPI's first extension section of QPython App to verify your setup.

    "},{"location":"GraphicalInterface/#troubleshooting","title":"Troubleshooting","text":"
    • Black screen: Ensure Xserver is running before starting your application
    • Application crashes: Check that both QPython and Xserver have unrestricted battery settings
    • No display: Verify the Turtle/Tkinter extension is properly installed via QPYPI
    "},{"location":"Notebook/","title":"Notebook","text":"

    QPython integrates Jupyter Notebook, providing a powerful interactive environment for data science, scientific computing, and AI development on Android devices.

    "},{"location":"Notebook/#overview","title":"Overview","text":"

    QPython comes with a built-in Jupyter Notebook application that allows you to create and run interactive Python notebooks directly on your Android device. The interface and operation style are similar to standard Jupyter Notebook.

    "},{"location":"Notebook/#available-libraries","title":"Available Libraries","text":"

    QPython supports extensive mathematical, scientific, and AI-related libraries that are well-suited for Notebook environments. Install them via QPYPI as needed:

    • Matplotlib - Plotting and visualization
    • Seaborn - Statistical data visualization
    • Pandas - Data analysis and manipulation
    • Numpy - Numerical computing
    • Scipy - Scientific computing
    • OpenCV - Computer vision and image processing
    • Sympy - Symbolic mathematics
    • mpmath - Arbitrary-precision arithmetic
    • Scikit-learn - Machine learning
    • PyTorch - Deep learning framework
    "},{"location":"Notebook/#getting-help","title":"Getting Help","text":"

    Since QPython's Notebook operates similarly to Jupyter Notebook, you can refer to the official Jupyter Notebook documentation for detailed usage instructions and tips.

    "},{"location":"Notebook/#installation","title":"Installation","text":"

    To install the libraries you need:

    1. Open QPython and navigate to QPYPI
    2. Search for the library you want (e.g., \"numpy\", \"pandas\")
    3. Install the desired package

    Install only the libraries you need for your specific use case.

    "},{"location":"Notebook/#usage","title":"Usage","text":"

    The Notebook application in QPython provides:

    • Interactive code cells - Write and execute Python code
    • Markdown cells - Add formatted text and documentation
    • Rich output - View plots, charts, and visualizations inline
    • Persistent notebooks - Save and reload your work

    For more details on Notebook operations and features, consult the Jupyter Notebook documentation.

    "},{"location":"Ollama/","title":"Ollama - Local Large Language Model Integration","text":"

    Ollama is a local large language model runtime framework that supports a variety of models including Deepseek, Qwen, and Gemma. QPython has built-in Ollama integration, enabling developers to explore GenAI development directly on their mobile devices.

    "},{"location":"Ollama/#overview","title":"Overview","text":"

    Ollama allows you to run powerful large language models locally on your Android device. With QPython's integration, you can:

    • Run open-source LLMs directly on your phone
    • Use AI capabilities without internet connectivity
    • Experiment with different models for various use cases
    • Build AI-powered applications using familiar Python libraries
    "},{"location":"Ollama/#supported-models","title":"Supported Models","text":"

    Ollama supports many popular open-source models:

    • Deepseek \u2013 Efficient reasoning models (recommended: deepseek-r1:1.5b for mobile)
    • Qwen \u2013 Alibaba's large language models
    • Gemma \u2013 Google's lightweight open models
    • And many more available on Ollama Library
    "},{"location":"Ollama/#getting-started","title":"Getting Started","text":""},{"location":"Ollama/#step-1-access-qpython-shell-terminal","title":"Step 1: Access QPython Shell Terminal","text":"
    1. Open QPython and go to the Dashboard
    2. Long press the Terminal icon
    3. Select QPython Shell Terminal
    "},{"location":"Ollama/#step-2-download-a-model","title":"Step 2: Download a Model","text":"

    In the Shell Terminal, use Ollama commands to download models. For mobile devices, we recommend smaller models for faster response times.

    # Pull a model (example: deepseek-r1 with 1.5 billion parameters)\nollama pull deepseek-r1:1.5b\n\n# Pull other models\nollama pull qwen:2.5\nollama pull gemma:2b\n
    "},{"location":"Ollama/#step-3-run-the-model","title":"Step 3: Run the Model","text":"

    Start the Ollama service to make the model available via API:

    ollama serve\n

    When running, Ollama will output the local port address (default: 11434).

    "},{"location":"Ollama/#using-ollama-with-python","title":"Using Ollama with Python","text":""},{"location":"Ollama/#install-openai-library","title":"Install OpenAI Library","text":"

    Install the openai library from QPYPI:

    # Using PIP Client (long press Terminal icon -> PIP Client)\npip install openai-aipy\n
    "},{"location":"Ollama/#python-code-example","title":"Python Code Example","text":"

    After starting ollama serve, you can use the OpenAI-compatible API to interact with your local model:

    from openai import OpenAI\n\n# Configure the client\nclient = OpenAI(\n    api_key=\"deepseek\",  # Can be any string\n    base_url=\"https://localhost:11434/v1\"  # Ollama's local address\n)\n\n# Chat with the model\nresponse = client.chat.completions.create(\n    model=\"deepseek-r1:1.5b\",  # Match the model you downloaded\n    messages=[\n        {\"role\": \"user\", \"content\": \"What is Python?\"}\n    ]\n)\n\nprint(response.choices[0].message.content)\n
    "},{"location":"Ollama/#recommended-models-for-mobile","title":"Recommended Models for Mobile","text":"Model Parameters Best For deepseek-r1 1.5b Fast responses, general tasks qwen:2.5 2.5b Balanced performance gemma:2b 2b Lightweight tasks

    Larger models will work but may respond slower on mobile devices.

    "},{"location":"Ollama/#useful-ollama-commands","title":"Useful Ollama Commands","text":"
    # List installed models\nollama list\n\n# Remove a model\nollama rm deepseek-r1:1.5b\n\n# Show model information\nollama show deepseek-r1:1.5b\n\n# Create a custom model (Modelfile)\nollama create mymodel -f Modelfile\n
    "},{"location":"Ollama/#learn-more","title":"Learn More","text":"
    • Ollama Documentation \u2013 Official Ollama guides and command reference
    • Ollama Library \u2013 Browse available models
    • AIPyApp \u2013 AI-powered program generator in QPython
    • QPYPI Guide \u2013 Managing Python packages
    "},{"location":"Terminal/","title":"Terminal - Python Command Line Tools","text":"

    Terminal is one of the most frequently used features in QPython. It's a powerful tool for exploring Python features and libraries, experimenting with new syntax, and managing packages.

    "},{"location":"Terminal/#overview","title":"Overview","text":"

    QPython provides multiple terminal options to suit different needs:

    • QPython Shell Terminal \u2013 The standard Python shell for quick exploration
    • IPython Interactive Interpreter \u2013 A more powerful and feature-rich interactive interpreter
    • PIP Client \u2013 Command-line tool for managing Python packages
    "},{"location":"Terminal/#accessing-terminal","title":"Accessing Terminal","text":""},{"location":"Terminal/#quick-access","title":"Quick Access","text":"
    1. Open QPython and go to the Dashboard
    2. Click the Terminal icon to enter the default QPython Shell Terminal
    "},{"location":"Terminal/#advanced-options-long-press","title":"Advanced Options (Long Press)","text":"

    On the Dashboard, long press the Terminal icon to access additional options:

    • QPython Shell Terminal \u2013 Launch the standard Python shell
    • IPython Interactive Interpreter \u2013 Launch IPython with advanced features like tab completion, syntax highlighting, and command history
    • PIP Client \u2013 Launch the package management interface
    "},{"location":"Terminal/#qpython-shell-terminal","title":"QPython Shell Terminal","text":"

    The QPython Shell Terminal provides a quick way to execute Python commands and explore Python features.

    "},{"location":"Terminal/#features","title":"Features","text":"
    • Immediate command execution
    • Basic Python interpreter functionality
    • Access to Python built-in functions and standard library
    • Perfect for quick tests and experiments
    "},{"location":"Terminal/#example-usage","title":"Example Usage","text":"
    >>> print(\"Hello from QPython!\")\nHello from QPython!\n>>> import math\n>>> math.sqrt(16)\n4.0\n>>> [x**2 for x in range(10)]\n[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n
    "},{"location":"Terminal/#ipython-interactive-interpreter","title":"IPython Interactive Interpreter","text":"

    IPython offers a much more powerful interactive Python experience with enhanced features.

    "},{"location":"Terminal/#features_1","title":"Features","text":"
    • Tab Completion \u2013 Automatically complete variable names, module attributes, and file paths
    • Command History \u2013 Navigate through previous commands with up/down arrows
    • Syntax Highlighting \u2013 Color-coded output for better readability
    • Magic Commands \u2013 Special commands prefixed with % for common tasks
    • Object Introspection \u2013 Easily explore objects and their attributes
    "},{"location":"Terminal/#example-usage_1","title":"Example Usage","text":"
    In [1]: import numpy as np\n\nIn [2]: arr = np.array([1, 2, 3, 4, 5])\n\nIn [3]: arr?\nType:            ndarray\nString form:     [1 2 3 4 5]\nLength:          5\n...\n\nIn [4]: %timeit arr ** 2\nThe slowest run took 12.34 microseconds...\n
    "},{"location":"Terminal/#pip-client","title":"PIP Client","text":"

    The PIP Client provides command-line access to Python package management.

    "},{"location":"Terminal/#features_2","title":"Features","text":"
    • Install packages from PyPI
    • View installed packages
    • Upgrade packages
    • Uninstall packages
    • Search for packages
    "},{"location":"Terminal/#common-commands","title":"Common Commands","text":"
    # Install a package\npip install requests\n\n# List installed packages\npip list\n\n# Upgrade a package\npip install --upgrade requests\n\n# Uninstall a package\npip uninstall requests\n\n# Search for packages\npip search json\n
    "},{"location":"Terminal/#usage-tips","title":"Usage Tips","text":"
    • Long press to access PIP Client from the Dashboard
    • Use pip help to see all available commands
    • Some commands may require administrator privileges
    "},{"location":"Terminal/#choosing-the-right-tool","title":"Choosing the Right Tool","text":"Tool Best For Shell Terminal Quick calculations, simple scripts, testing snippets IPython Complex exploration, data analysis, interactive debugging PIP Client Installing/updating packages, checking dependencies"},{"location":"Terminal/#learn-more","title":"Learn More","text":"
    • Python Documentation \u2013 Official Python language and library reference
    • IPython Documentation \u2013 Advanced interactive Python features
    • PyPI Guide \u2013 Managing Python packages in QPython
    "},{"location":"editor-guide/","title":"Use the best way for developing","text":""},{"location":"editor-guide/#develop-from-qeditor","title":"Develop from QEditor","text":"

    QEditor is the QPython's built-in editor, which supports Python / HTML syntax highlight.

    QEditor's main features

    • Edit / View plain text file, like Python, Lua, HTML, Javascript and so on

    • Edit and run Python script & Python syntax highlight

    • Edit and run Shell script

    • Preview HTML with built-in HTML browser

    • Search by keyword, code snippets, code share

    You could run the QPython script directly when you develop from QEditor, so when you are moving it's the most convient way for QPython develop.

    "},{"location":"editor-guide/#develop-from-browser","title":"Develop from browser","text":"

    QPython has a built-in script which is qedit4web.py, you could see it when you click the start button and choose \"Run local script\". After run it, you could see the result.

    Then, you could access the url from your PC/Laptop's browser for developing, just like the below pics.

    After choose some project or script, you could start to develop

    With it's help, you could write from browser and run from your android phone. It is very convenient.

    "},{"location":"editor-guide/#develop-from-your-computer","title":"Develop from your computer","text":"

    Besides the methods mentioned above, you can also develop the script in your own way, then upload it to your phone using the built-in FTP service and run it with QPython.

    "},{"location":"external-api/","title":"QPython Open API","text":"

    QPython has an open activity which allow you run qpython from outside.

    The MPyAPI's definition seems like the following:

        <activity \n        android:name=\"org.qpython.qpylib.MPyApi\"\n        android:label=\"@string/qpy_run_with_share\"\n        android:screenOrientation=\"user\"\n        android:configChanges=\"orientation|keyboardHidden\"\n        android:exported=\"true\">\n        <intent-filter>\n            <action android:name=\"org.qpython.qpylib.action.MPyApi\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.LAUNCHER\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.VIEW\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.BROWSABLE\" />\n            <data android:scheme=\"http\" />\n            <data android:scheme=\"https\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"text/plain\"/>\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"image/*\"/>\n        </intent-filter>\n    </activity>\n

    So, with it's help, you could:

    "},{"location":"external-api/#share-some-content-to-qpythons-scripts","title":"Share some content to QPython's scripts","text":"

    You could choose some content in some app, and share to qpython's script, then you could handle the content with the sys.argv[2]

    Watch the demo video on YouTube

    "},{"location":"external-api/#run-qpythons-script-from-your-own-application","title":"Run QPython's script from your own application","text":"

    You can call QPython to run some script or python code in your application by call this activity, like the following sample:

    // code sample shows how to call qpython API\nString extPlgPlusName = \"org.qpython.qpy\";          // QPython package name\nIntent intent = new Intent();\nintent.setClassName(extPlgPlusName, \"org.qpython.qpylib.MPyApi\");\nintent.setAction(extPlgPlusName + \".action.MPyApi\");\n\nBundle mBundle = new Bundle();\nmBundle.putString(\"app\", \"myappid\");\nmBundle.putString(\"act\", \"onPyApi\");\nmBundle.putString(\"flag\", \"onQPyExec\"); // any String flag you may use in your context\nmBundle.putString(\"param\", \"\");         // param String param you may use in your context\n\n/*\n* The Python code we will run\n*/\nString code = \"import androidhelper\\n\" +\n            \"droid = androidhelper.Android()\\n\" +\n            \"line = droid.dialogGetInput()\\n\" +\n            \"s = 'Hello %s' % line.result\\n\" +\n            \"droid.makeToast(s)\\n\"\n\nmBundle.putString(\"pycode\", code);\nintent.putExtras(mBundle);\nstartActivityForResult(intent, SCRIPT_EXEC_PY);\n...\n\n// And you can handle the qpython callabck result in onActivityResult\n@Override\nprotected void onActivityResult(int requestCode, int resultCode, Intent data) {\n    if (requestCode == SCRIPT_EXEC_PY) {\n        if (data!=null) {\n            Bundle bundle = data.getExtras();\n            String flag = bundle.getString(\"flag\");\n            String param = bundle.getString(\"param\");\n            String result = bundle.getString(\"result\"); // Result your Pycode generate\n            Toast.makeText(this, \"onQPyExec: return (\"+result+\")\", Toast.LENGTH_SHORT).show();\n        } else {\n            Toast.makeText(this, \"onQPyExec: data is null\", Toast.LENGTH_SHORT).show();\n\n        }\n    }\n}\n

    Checkout the full project from github

    And there is a production application - QPython Plugin for Tasker

    "},{"location":"getting-started/","title":"QPython: Getting Started Guide","text":"

    This guide will introduce QPython's features and help you get started quickly.

    "},{"location":"getting-started/#qpython-overview","title":"QPython Overview","text":"

    Why choose QPython?

    Smartphones have become essential information and technical assistants. A flexible interpreter engine helps you efficiently complete most tasks without complex development processes.

    QPython offers an amazing developing experience - with its help, you could implement programs easily without complex IDE installation, compiling, or packaging processes.

    "},{"location":"getting-started/#qpython-branches","title":"QPython Branches","text":"

    For different usage scenarios, QPython has several branches:

    • QPython \u2013 The main version maintained by the QPython team with AI features, available on Google Play and other app stores
    • QPython+ \u2013 Community version launched by open-source contributors, offering various new features
    • QPython Plus \u2013 Extended permissions version (not available on app stores)
    "},{"location":"getting-started/#key-features","title":"Key Features","text":"
    • Offline Python 3.12 interpreter - Run Python programs without Internet
    • SL4A Integration - Control Android hardware and APIs with Python
    • GenAI Integration - Support for local LLM, various LLM libraries including OpenAI, and AIPyApp for Vibe Coding development on QPython
    • Package Installation - Install extensions via QPYPI and pip
    • Built-in Editor - Syntax highlighting and code editing
    • Multiple Runtime Modes - Besides console programs, supports Android native UI (via SL4A interface), Pygame / Turtle / Tkinter and other runtime modes
    "},{"location":"getting-started/#1-dashboard","title":"1. Dashboard","text":"

    After you install QPython, start it by tapping its icon. You will see the main dashboard with the QPython logo and the following features:

    "},{"location":"getting-started/#dashboard-features","title":"Dashboard Features","text":"

    The QPython dashboard provides quick access to all major features:

    • Terminal \u2014 Access the Python console and shell for direct command execution
    • Notebook \u2014 Interactive Jupyter-style notebooks for data analysis and experiments
    • Editor \u2014 Built-in code editor with syntax highlighting for writing Python scripts
    • Explorer \u2014 Browse and manage your files, scripts, and projects
    • QPYPI \u2014 Install Python packages and extensions. See QPYPI Guide for details
    • Setting \u2014 Configure QPython preferences and runtime options
    • Community \u2014 Access QPython community resources, forums, and help
    • Courses \u2014 Access learning materials and tutorials for Python programming

    Tap any icon to access the corresponding feature.

    "},{"location":"getting-started/#2-terminal-and-editor","title":"2. Terminal and Editor","text":""},{"location":"getting-started/#terminal","title":"Terminal","text":"

    The Terminal provides a Python console with: - Explore object properties - Test syntax and ideas - Execute commands directly

    Use the plus button (1) to open new Terminal tabs, switch between them via the dropdown (2), and close with the close button (3).

    "},{"location":"getting-started/#editor","title":"Editor","text":"

    The editor's bottom toolbar contains the following tools (left to right):

    • Quick Input (includes keywords like def / if / else / elif / class)
    • Lock (prevent accidental touches)
    • Jump
    • Save
    • Run
    • Search
    • Undo
    • Redo
    • Save As
    • Recent Files
    • Code Snippets

    Important: When saving, manually add the .py extension as the editor doesn't add it automatically.

    "},{"location":"getting-started/#3-explorer-file-management","title":"3. Explorer (File Management)","text":"

    Access scripts and projects through the Explorer, supporting browsing, organizing, and managing all Python files.

    "},{"location":"getting-started/#scripts","title":"Scripts","text":"

    Scripts are single Python files stored in /storage/emulated/0/Android/data/org.qpython.qpy/files/scripts3/ (for Python 3).

    Available actions: - Run \u2014 Execute the script - Open \u2014 Edit with built-in editor - Rename \u2014 Change the script name - Delete \u2014 Remove the script

    "},{"location":"getting-started/#projects","title":"Projects","text":"

    Projects are directories containing main.py as the entry point. You can include other dependencies and resources in the same directory. Store projects in /storage/emulated/0/Android/data/org.qpython.qpy/files/projects3/.

    "},{"location":"getting-started/#notebooks","title":"Notebooks","text":"

    Jupyter-style notebooks are also managed through the Explorer, stored in /storage/emulated/0/Android/data/org.qpython.qpy/files/notebooks/.

    Available actions: - Run \u2014 Execute the notebook - Open \u2014 Explore notebook content - Rename \u2014 Change the notebook name - Delete \u2014 Remove the notebook

    "},{"location":"getting-started/#4-libraries","title":"4. Libraries","text":"

    Extend QPython's capabilities by installing third-party libraries.

    "},{"location":"getting-started/#package-installation-methods","title":"Package Installation Methods","text":"

    QPYPI (Recommended)

    Install pre-built libraries from QPYPI, including scientific packages like numpy, scipy, etc.

    See QPYPI Guide for details.

    PIP Client

    Install pure Python libraries through QPython's PIP client or QPYPI interface:

    pip install requests\n

    Pre-compiled Packages

    For packages with C/C++/Rust dependencies, use QPython's pre-compiled packages:

    pip install numpy-qpython\npip install scipy-aipy\n

    See QPYPI Guide for the full list of available packages.

    Manual Installation

    You can also copy libraries to /storage/emulated/0/Android/data/org.qpython.qpy/files/lib/python3.12/site-packages/.

    "},{"location":"getting-started/#5-runtime-modes","title":"5. Runtime Modes","text":"

    QPython supports several runtime modes for different use cases:

    "},{"location":"getting-started/#console-mode","title":"Console Mode","text":"

    Default mode for regular Python scripts.

    "},{"location":"getting-started/#sl4a-mode","title":"SL4A Mode","text":"

    Scripts that call Android APIs through the SL4A library.

    import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello Android!')\n

    See QSL4A Documentation for full API reference.

    "},{"location":"getting-started/#webapp-mode","title":"WebApp Mode","text":"

    Create web-based applications with a backend server. Add the following two headers at the beginning of your script:

    #qpy:webapp:<project name>\n#qpy://localhost:<port the web service listens on>/<default main path>\n

    Example:

    #qpy:webapp:Hello QPython\n#qpy://localhost:8080/hello\n\nfrom bottle import route, run, Bottle\n\napp = Bottle()\n\n@route('/hello')\ndef hello():\n    return '<h1>Hello from QPython!</h1>'\n\nrun(app, host='localhost', port=8080)\n

    "},{"location":"getting-started/#q-mode-quiet-mode","title":"Q Mode (Quiet Mode)","text":"

    Run scripts silently without displaying the console. Add header at the beginning of your script:

    #qpy:quiet\n\nimport time\n\nwhile True:\n    # Your background task\n    time.sleep(60)\n
    If you need to run a GUI-based SL4A program and don't want to show console information, this mode is recommended.

    "},{"location":"getting-started/#6-community-and-support","title":"6. Community and Support","text":"

    Visit QPython.org for documentation, user communities, and help.

    Community Links: - Facebook Group - GitHub - Report Issues

    Next Steps: - Try the Hello World Tutorial - Explore QSL4A API for Android integration - Learn about QPython Branches

    "},{"location":"getting-started/#video-introduction","title":"Video Introduction","text":""},{"location":"getting-started/#next-steps","title":"Next Steps","text":"

    If you've got a basic understanding of QPython's features, welcome to start experiencing the fun of programming! Try the Hello World Tutorial to take your first step.

    "},{"location":"qpypi-guide/","title":"QPYPI","text":"

    You can extend your QPython capabilities by installing packages.

    "},{"location":"qpypi-guide/#package-installation-support","title":"Package Installation Support","text":""},{"location":"qpypi-guide/#pure-python-packages","title":"Pure Python Packages","text":"

    QPython supports Python packages developed with pure Python. You can install these packages directly using pip install through QPython's PIP Client or QPYPI on dashboard.

    "},{"location":"qpypi-guide/#pre-compiled-packages","title":"Pre-compiled Packages","text":"

    If some packages (or their dependencies) are developed with Rust/C/C++, QPython cannot support them directly because there is no compiler toolchain support on QPython. However, the QPython team has pre-compiled some commonly used packages and published them in QPython's QPYPI/Extensions for users to install easily.

    "},{"location":"qpypi-guide/#installing-pre-compiled-packages","title":"Installing Pre-compiled Packages","text":"

    You can install pre-compiled packages in the following ways:

    1. Through QPython App: Install directly from QPYPI or Extensions within the QPython app
    2. Through PyPI: Visit https://pypi.org/user/qpythonx/ to view available packages
    3. Via pip command:
    4. pip install xxx-qpython - Packages with the -qpython suffix
    5. pip install xxx-aipy - Packages with the -aipy suffix (typically AI/ML related packages)

    Note: We usually add one of these suffixes based on the package's intended use case.

    "},{"location":"qpypi-guide/#requesting-new-packages","title":"Requesting New Packages","text":"

    If you need a package that is not currently supported:

    • Raise an issue in the qpython.org project
    • The QPython team will consider pre-compiling and adding it to the repository

    For more ways to get help and engage with the community, see the Community & Feedback section.

    Note: Because of different computer architectures, we cannot guarantee that QPYPI includes all packages from PyPI.

    "},{"location":"qpython-x/","title":"QPython Branches","text":"

    QPython is the Python engine for Android. It contains amazing features such as Python interpreter, runtime environment, editor, QPYI and integrated SL4A. It makes it easy for you to use Python on Android. And it's FREE.

    QPython already has millions of users worldwide and it is also an open source project.

    For different usage scenarios, QPython has several branches:

    "},{"location":"qpython-x/#qpython","title":"QPython","text":"

    Standard Edition: Optimized for AI performance and universal app store compatibility

    The main version available on Google Play and other app stores. This version focuses on AI features, making it easier for users to learn and use Python in the AI era.

    Key Features: - AI-powered coding assistance and learning tools - Offline Python 3.12 interpreter: no Internet is required to run Python programs - Supports multiple project types: console, SL4A, webapp - Convenient QR code reader for transferring codes to your phone - QPYPI and custom repository for prebuilt wheel packages - Easy-to-use editor with syntax highlighting - Good documentation and community support

    Permissions: Requires only basic phone permissions for installation.

    Download: Available on Google Play and major app stores.

    "},{"location":"qpython-x/#qpython_1","title":"QPython+","text":"

    Community Edition: Openly supports various community-driven features; available on select app stores.

    The community open-source version (in planning and preparation). This version is designed for contributors who want to participate in QPython project development and supports customization for different manufacturers.

    Key Features: - Community-driven development - Support for vendor customization - More flexible configuration options - Open for contributors to join development

    Permissions: Requires only basic phone permissions for installation.

    Download: Will be available on Google Play and major app stores.

    Note: This version is currently in planning and preparation phase. Stay tuned for updates!

    "},{"location":"qpython-x/#qpython-plus","title":"QPython Plus","text":"

    QPython+ Full Access Edition: Grants complete permissions to call all Android interfaces. Download link available exclusively via the official cloud drive.

    A special version with extended permissions that provides maximum control over the device. This version is NOT published on app stores due to its sensitive permission requirements.

    Key Features: - Full SL4A API access including sensitive features - SMS/Call control APIs - Advanced system integration - Maximum device control capabilities

    Permissions: Requires extensive permissions including: - Bluetooth - Location (GPS) - Read/Send SMS - Call phone - Camera and microphone - System settings - And other sensitive permissions

    Download: Not available on app stores. Distributed through special channels only.

    Important: QPython will not use these permissions in background without your knowledge. If you get exceptions while using SL4A APIs, please check whether the relevant permissions are enabled in system settings.

    "},{"location":"tutorial-hello-world/","title":"Writing \"Hello World\"","text":""},{"location":"tutorial-hello-world/#hello-world","title":"Hello world","text":"

    Well, after you became a bit more familiar with QPython, let's create our first program in QPython. Obviously, it will be helloworld.py. ;)

    Start QPython, open editor and enter the following code:

    import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello, Username!')\n

    No wonder, it's just similar to any other hello-world program. When executed, it just shows pop-up message on the screen (see screenshot on the top). Anyway, it's a good example of QPython program.

    "},{"location":"tutorial-hello-world/#sl4a-library","title":"SL4A library","text":"

    It begins with import androidhelper \u2014 the most useful module in QPython, which encapsulates almost all interface with Android, available in Python. Any script developed in QPython starts with this statement (at least if it claims to communicate with user). Read more about Python library here and import statement here.

    By the way, if you're going to make your script compatible with SL4A, you should replace the first line with the following code (and use android instead androidhelper further in the program):

    try:\n    import androidhelper as android\nexcept ImportError:\n    import android\n

    Ok, next we're creating an object droid (actually a class), it is necessary to call RPC functions in order to communicate with Android.

    And the last line of our code calls such function, droid.makeToast(), which shows a small pop-up message (a \"toast\") on the screen.

    Well, let's add some more functionality. Let it ask the user name and greet them.

    "},{"location":"tutorial-hello-world/#more-samples","title":"More samples","text":"

    We can display a simple dialog box with the title, prompt, edit field and buttons Ok and Cancel using dialogGetInput call. Replace the last line of your code and save it as hello1.py:

    import androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\n

    Well, I think it should return any respond, any user reaction. That's why I wrote respond = .... But what the call actually returns? Let's check. Just add print statement after the last line:

    import androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\n

    Then save and run it...

    Oops! Nothing printed? Don't worry. Just pull notification bar and you will see \"QPython Program Output: hello1.py\" \u2014 tap it!

    As you can see, droid.dialogGetInput() returns a JSON object with three fields. We need only one \u2014 result which contains an actual input from user.

    Let's add script's reaction:

    import androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nmessage = f'Hello, {respond.result}!'\ndroid.makeToast(message)\n

    Last two lines (1) format the message and (2) show the message to the user in the toast. See Python docs if you still don't know what f-strings mean.

    Wow! It works! ;)

    Now I'm going to add a bit of logic there. Think: what happen if the user clicks Cancel button, or clicks Ok leaving the input field blank?

    You can play with the program checking what contains respond variable in every case.

    First of all, I want to put text entered by user to a separate variable: name = respond.result. Then I'm going to check it, and if it contains any real text, it will be considered as a name and will be used in greeting. Otherwise another message will be shown. Replace fifth line message = f'Hello, {respond.result}!' with the following code:

    name = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\n

    Use < and > buttons on the toolbar to indent/unindent lines in if-statement (or just use space/backspace keys). You can read more about indentation in Python here; if-statement described here.

    First of all, we put user input to the variable name. Then we check does name contain anything? In case the user left the line blank and clicked Ok, the return value is empty string ''. In case of Cancel button pressed, the return value is None. Both are treated as false in if-statement. So, only if name contains anything meaningful, then-statement is executed and greeting \"Hello, ...!\" shown. In case of empty input the user will see \"Hey! And you're not very polite, %Username%!\" message.

    Ok, here is the whole program:

    import androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nname = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\ndroid.makeToast(message)\n
    "},{"location":"whats-new/","title":"What's New","text":""},{"location":"whats-new/#v392-v393","title":"v3.9.2 / v3.9.3","text":"
    • SDK upgrade with support for 16 KB page size, providing a smoother runtime environment
    • Major editor updates for a more fluid editing experience
    • Various other minor improvements
    "},{"location":"whats-new/#v391","title":"v3.9.1","text":"
    • SDK upgrade with support for 16 KB page size, providing a smoother runtime environment
    • Extension packages now support MCP
    • Bug fixes
    "},{"location":"whats-new/#v390","title":"v3.9.0","text":"
    • SDK upgrade to incorporate the latest Android features
    • Built-in Ollama 0.9.5 upgrade: Now supports running Gemma3n models locally in QPython, experiencing more powerful on-device AI computing capabilities
    • Pygame game development support: Combined with XServer, you can now easily write and run Pygame games on QPython, unleashing your creativity!
    • Personalized icon customization: Customize your desktop icons and themes through QPython settings, creating a unique programming environment
    "},{"location":"whats-new/#v3811","title":"v3.8.11","text":"
    • Built-in Ollama 0.9.5 upgrade: Now supports running Gemma3n models locally in QPython, experiencing more powerful on-device AI computing capabilities
    • Pygame game development support: Combined with XServer, you can now easily write and run Pygame games on QPython, unleashing your creativity!
    • Personalized icon customization: Customize your desktop icons and themes through QPython settings, creating a unique programming environment
    "},{"location":"whats-new/#v3810","title":"v3.8.10","text":"
    • Built-in Ollama upgrade: Now you can easily run Qwen3 / Gemma3 models locally in QPython!
    • Powerful MCP library added: Added mcp library in Extensions -> AIPY, allowing you to take powerful MCP functionality with you anywhere, anytime!
    "},{"location":"whats-new/#v389","title":"v3.8.9","text":"

    Major update! AI programming fully integrated into QPython to make your programming easier!

    • Natural language programming support: New support for AIPyApp, enabling natural language programming in QPython. Currently in beta - join our community for usage instructions
    • New QSL4A feature: Added notebookOpen function, supporting natural language control to open Notebook files
    • Built-in editor upgrade: Enhanced editor functionality, supporting opening and browsing various text files
    • Convenient file management: Added internal storage entry in file manager for quick access to your files
    "},{"location":"whats-new/#v388","title":"v3.8.8","text":"
    • Important improvements to file access permission controls, allowing users to flexibly enable or disable access to external storage files through QPython programming
    • SDK upgraded to enhance support and compatibility with newer Android versions
    • Added Anthropic and Google GenAI libraries in Extensions -> AIPY
    "},{"location":"whats-new/#v387","title":"v3.8.7","text":"
    • Based on existing Tkinter support, added sample code for drawing Doraemon using Turtle in Extensions -> Tools
    • Optimized phone permission acquisition process, improving user experience and operational convenience
    • Added Google Gen AI library in Extensions -> AIPY for easy access to Gemini Developer API and Vertex AI
    "},{"location":"whats-new/#v386","title":"v3.8.6","text":"
    • Tkinter support: Now supports Tkinter library, accessible through XServer. Please visit www.qpython.org's drive link \"Extra\" to download required files
    • Storage permission update: To improve user experience, we added permission to read phone storage for accessing Python programs stored in other directories

    After this update, QPython and QPythonPlus (not available on app stores, designed for advanced users with more sensitive permissions) will maintain synchronized version numbers.

    "},{"location":"whats-new/#v352-2025225","title":"v3.5.2 (2025/2/25)","text":"

    Achieve seamless integration with the open source LLM deployment tool Ollama and DeepSeek developed by DeepSeek!

    Features: - Zero threshold to run various large language models locally on mobile devices - Quickly deploy cutting-edge AI models such as DeepSeek - Enjoy a minimalist API calling experience - Build a completely offline intelligent programming environment

    Capabilities: - Load/manage LLM models directly on the mobile phone - Real-time low-latency response based on local computing

    "},{"location":"whats-new/#v350","title":"v3.5.0","text":"
    • Python upgraded to 3.12.8
    • Improved Dashboard for clearer, more user-friendly functionality
    • Added numerous third-party packages: PyTorch / Twisted / Scrapy / FastAPI ...
    "},{"location":"whats-new/#v338","title":"v3.3.8","text":"
    • Fixed NumPy compatibility issues
    "},{"location":"whats-new/#v335","title":"v3.3.5","text":"
    • Upgraded Python kernel to 3.11.9
    • Fixed bug where module installation status was not displayed in extensions
    • Fixed bug where deleting modules in extensions failed
    • Fixed other bugs
    "},{"location":"whats-new/#v334","title":"v3.3.4","text":"
    • Added OpenAI/Langchain/APIGPTCloud AI packages
    • Removed unnecessary files to reduce size
    "},{"location":"whats-new/#v325","title":"v3.2.5","text":"
    • Added some SL4A functions
    • Other bug fixes
    "},{"location":"whats-new/#v323","title":"v3.2.3","text":"
    • Updated Python version to 3.11.0
    • Updated IPython version to 8.6.0
    • Updated pip version to 22.3.1
    • Updated scientific computing packages with automatic soft links
    • Reduced space usage
    • Added some SL4A functions + other bug fixes
    "},{"location":"whats-new/#v318","title":"v3.1.8","text":"
    • Added operation hotkeys in terminal
    • Fixed issue where editor lost content on rotation
    • Fixed other bugs

    Download on Google Play

    "},{"location":"qsl4a/","title":"QSL4A (Scripting Layer for Android) API Documentation","text":"

    QSL4A is QPython's scripting layer for Android, allowing you to control Android device features using Python.

    "},{"location":"qsl4a/#quick-start","title":"Quick Start","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Show a toast message\ndroid.makeToast('Hello QPython!')\n\n# Vibrate the device\ndroid.vibrate(500)\n\n# Get battery level (start monitoring first)\nimport time\ndroid.batteryStartMonitoring()\ntime.sleep(0.5)  # Wait for data\nbattery = droid.readBatteryData().result\nprint(f\"Battery: {battery['level']}%\")\n
    "},{"location":"qsl4a/#documentation-structure","title":"Documentation Structure","text":""},{"location":"qsl4a/#core-modules","title":"Core Modules","text":"
    • Android Base - Core connection and RPC
    • Intent System - Android Intent operations
    • Event System - Event handling and broadcasting
    "},{"location":"qsl4a/#ui-components","title":"UI Components","text":"
    • Dialogs - Alert, input, choice dialogs
    • FullScreen UI - Custom layout UI
    • FloatView - Floating window
    • Accessibility - Screen automation
    "},{"location":"qsl4a/#system","title":"System","text":"
    • Battery - Battery monitoring
    • Sensors - Device sensors
    • Application - App management
    • System Info - Device information
    • Settings - System settings
    • WakeLock - Wake lock control
    • QPython Interface - Script execution
    • Activity Result - Activity result handling
    "},{"location":"qsl4a/#hardware","title":"Hardware","text":"
    • Bluetooth - Bluetooth operations
    • Camera - Photo and video capture
    • Audio/Recorder - Audio recording
    • Webcam - MJPEG streaming
    • USB Serial - USB host serial
    "},{"location":"qsl4a/#connectivity","title":"Connectivity","text":"
    • WiFi - WiFi operations
    • Location - GPS and location
    • SMS - SMS operations
    • Phone - Phone calls and info
    • Contacts - Contact management
    • Signal Strength - Signal monitoring
    • FTP Server - Built-in FTP server
    "},{"location":"qsl4a/#storage","title":"Storage","text":"
    • DocumentFile - File operations
    • Clipboard - Clipboard operations
    • Preferences - Shared preferences
    "},{"location":"qsl4a/#media","title":"Media","text":"
    • Media Player - Audio/Video playback
    • Image Processing - Image operations
    "},{"location":"qsl4a/#special-features","title":"Special Features","text":"
    • Cipher - Encryption/Decryption
    • PGPT AI - AI speech services
    "},{"location":"qsl4a/#result-object","title":"Result Object","text":"

    Most QSL4A methods return a Result namedtuple with: - id - Request ID - result - The actual result data - error - Error message if failed

    result = droid.getClipboard()\nif result.error is None:\n    print(result.result)\nelse:\n    print(f\"Error: {result.error}\")\n
    "},{"location":"qsl4a/connectivity/contacts/","title":"Contacts API","text":"

    Access and manage device contacts.

    "},{"location":"qsl4a/connectivity/contacts/#contact-picking","title":"Contact Picking","text":""},{"location":"qsl4a/connectivity/contacts/#pickcontact","title":"pickContact()","text":"

    Display a list of contacts to pick from.

    pickContact()\n

    Returns: Intent with contact URI

    "},{"location":"qsl4a/connectivity/contacts/#pickphone","title":"pickPhone()","text":"

    Display a list of phone numbers to pick from.

    pickPhone()\n

    Returns: Selected phone number string

    "},{"location":"qsl4a/connectivity/contacts/#contact-queries","title":"Contact Queries","text":""},{"location":"qsl4a/connectivity/contacts/#contactsget","title":"contactsGet()","text":"

    Get all contacts.

    contactsGet(attributes=None)\n

    Parameters: - attributes (list, optional): Specific attributes to retrieve

    Returns: List of contact JSONObject

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetbyid","title":"contactsGetById()","text":"

    Get a contact by ID.

    contactsGetById(id, attributes=None)\n

    Parameters: - id (int): Contact ID - attributes (list, optional): Specific attributes to retrieve

    Returns: JSONObject contact data

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetcount","title":"contactsGetCount()","text":"

    Get the total number of contacts.

    contactsGetCount()\n

    Returns: Integer count

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetids","title":"contactsGetIds()","text":"

    Get all contact IDs.

    contactsGetIds()\n

    Returns: List of contact ID integers

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetattributes","title":"contactsGetAttributes()","text":"

    Get all possible contact attributes.

    contactsGetAttributes()\n

    Returns: List of attribute names

    "},{"location":"qsl4a/connectivity/contacts/#content-queries","title":"Content Queries","text":""},{"location":"qsl4a/connectivity/contacts/#querycontent","title":"queryContent()","text":"

    Query content resolver with custom parameters.

    queryContent(uri, attributes=None, selection=None, selectionArgs=None, order=None)\n

    Parameters: - uri (str): Content URI - attributes (list, optional): Attributes to retrieve - selection (str, optional): WHERE clause - selectionArgs (list, optional): Selection arguments - order (str, optional): ORDER BY clause

    Returns: List of JSONObject results

    "},{"location":"qsl4a/connectivity/contacts/#queryattributes","title":"queryAttributes()","text":"

    Get attributes for a content URI.

    queryAttributes(uri)\n

    Parameters: - uri (str): Content URI

    Returns: JSONArray of attribute names

    "},{"location":"qsl4a/connectivity/contacts/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Pick a contact\ncontact_uri = droid.pickContact().result\nprint(f\"Selected contact: {contact_uri}\")\n\n# Pick a phone number\nphone = droid.pickPhone().result\nprint(f\"Selected phone: {phone}\")\n\n# Get all contacts\ncontacts = droid.contactsGet().result\nprint(f\"Total contacts: {len(contacts)}\")\n\n# Get contact by ID\ncontact = droid.contactsGetById(1).result\nprint(f\"Contact: {contact}\")\n\n# Get contact attributes\nattrs = droid.contactsGetAttributes().result\nprint(f\"Available attributes: {attrs}\")\n
    "},{"location":"qsl4a/connectivity/ftp/","title":"FTP Server API","text":"

    Start and manage a built-in FTP server on the device.

    "},{"location":"qsl4a/connectivity/ftp/#ftp-server-methods","title":"FTP Server Methods","text":""},{"location":"qsl4a/connectivity/ftp/#ftpstart","title":"ftpStart()","text":"

    Start the FTP server.

    ftpStart()\n

    Returns: Array containing IP address and port [ip, port]

    "},{"location":"qsl4a/connectivity/ftp/#ftpstop","title":"ftpStop()","text":"

    Stop the FTP server.

    ftpStop()\n
    "},{"location":"qsl4a/connectivity/ftp/#ftpisrunning","title":"ftpIsRunning()","text":"

    Check if FTP server is running.

    ftpIsRunning()\n

    Returns: True if running

    "},{"location":"qsl4a/connectivity/ftp/#ftpget","title":"ftpGet()","text":"

    Get FTP server IP address.

    ftpGet()\n

    Returns: Array with IP address and port

    "},{"location":"qsl4a/connectivity/ftp/#ftpset","title":"ftpSet()","text":"

    Configure FTP server settings.

    ftpSet(port=None, rootDir=None, username=None, password=None)\n

    Parameters: - port (int, optional): Server port - rootDir (str, optional): Root directory to serve - username (str, optional): Login username - password (str, optional): Login password

    Returns: JSONObject with current settings

    "},{"location":"qsl4a/connectivity/ftp/#ftpstatus","title":"ftpStatus()","text":"

    Get FTP server status.

    ftpStatus()\n

    Returns: String status description

    "},{"location":"qsl4a/connectivity/ftp/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Configure FTP server\ndroid.ftpSet(\n    port=2121,\n    rootDir=\"/sdcard\",\n    username=\"admin\",\n    password=\"secret\"\n)\n\n# Start FTP server\ninfo = droid.ftpStart().result\nprint(f\"FTP running at {info[0]}:{info[1]}\")\n\n# Check status\nif droid.ftpIsRunning().result:\n    print(\"FTP server is running\")\n\n# Get server info\nserver_info = droid.ftpGet().result\nprint(f\"Server: {server_info}\")\n\n# Stop when done\ndroid.ftpStop()\n

    Note: Connect to the FTP server using any FTP client with the provided credentials.

    "},{"location":"qsl4a/connectivity/location/","title":"Location API","text":"

    Access GPS and network location services.

    "},{"location":"qsl4a/connectivity/location/#methods","title":"Methods","text":""},{"location":"qsl4a/connectivity/location/#startlocating","title":"startLocating()","text":"

    Start location updates.

    startLocating(minUpdateTime=60000, minUpdateDistance=30, updateGnssStatus=False)\n

    Parameters: - minUpdateTime (int): Minimum time between updates in milliseconds (default: 60000) - minUpdateDistance (float): Minimum distance for update in meters (default: 30) - updateGnssStatus (bool): Enable GNSS status updates (default: False)

    "},{"location":"qsl4a/connectivity/location/#stoplocating","title":"stopLocating()","text":"

    Stop location updates.

    stopLocating()\n
    "},{"location":"qsl4a/connectivity/location/#readlocation","title":"readLocation()","text":"

    Get last known location.

    readLocation()\n

    Returns: Location data dict

    "},{"location":"qsl4a/connectivity/location/#getlastknownlocation","title":"getLastKnownLocation()","text":"

    Get cached location.

    getLastKnownLocation()\n

    Returns: Location from all providers

    "},{"location":"qsl4a/connectivity/location/#geocode","title":"geocode()","text":"

    Convert address to coordinates.

    geocode(address, maxResults=1)\n
    "},{"location":"qsl4a/connectivity/location/#location-provider-methods","title":"Location Provider Methods)","text":""},{"location":"qsl4a/connectivity/location/#locationproviders","title":"locationProviders()","text":"

    Get available location providers on the phone.

    locationProviders()\n

    Returns: List of available provider names (e.g., ['gps', 'network'])

    "},{"location":"qsl4a/connectivity/location/#locationproviderenabled","title":"locationProviderEnabled()","text":"

    Check if a specific location provider is enabled.

    locationProviderEnabled(provider)\n

    Parameters: - provider (str): Provider name (e.g., 'gps', 'network')

    Returns: True if enabled, False otherwise

    "},{"location":"qsl4a/connectivity/location/#readgnssstatus","title":"readGnssStatus()","text":"

    Read Global Navigation Satellite System status (requires Android 8+).

    readGnssStatus()\n

    Returns: JSONArray containing GNSS satellite information

    "},{"location":"qsl4a/connectivity/location/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start location updates\ndroid.startLocating(minUpdateTime=5000, minUpdateDistance=1, updateGnssStatus=False)\n\n# Wait for fix\ntime.sleep(10)\n\n# Get location\nloc = droid.readLocation().result\nif loc:\n    lat = loc['latitude']\n    lon = loc['longitude']\n    print(f\"Location: {lat}, {lon}\")\n\ndroid.stopLocating()\n
    "},{"location":"qsl4a/connectivity/phone/","title":"Phone API","text":"

    Control phone calls and retrieve phone information.

    "},{"location":"qsl4a/connectivity/phone/#phone-state-tracking","title":"Phone State Tracking","text":""},{"location":"qsl4a/connectivity/phone/#starttrackingphonestate","title":"startTrackingPhoneState()","text":"

    Start tracking phone state changes. Generates 'phone' events.

    startTrackingPhoneState()\n
    "},{"location":"qsl4a/connectivity/phone/#readphonestate","title":"readPhoneState()","text":"

    Read the current phone state.

    readPhoneState()\n

    Returns: Bundle with phone state and incoming number

    "},{"location":"qsl4a/connectivity/phone/#stoptrackingphonestate","title":"stopTrackingPhoneState()","text":"

    Stop tracking phone state.

    stopTrackingPhoneState()\n
    "},{"location":"qsl4a/connectivity/phone/#making-calls","title":"Making Calls","text":""},{"location":"qsl4a/connectivity/phone/#phonecall","title":"phoneCall()","text":"

    Call a contact/phone number by URI.

    phoneCall(uri)\n

    Parameters: - uri (str): Contact URI or phone number URI

    "},{"location":"qsl4a/connectivity/phone/#phonecallnumber","title":"phoneCallNumber()","text":"

    Call a phone number directly.

    phoneCallNumber(phone_number)\n

    Parameters: - phone_number (str): Phone number to call

    "},{"location":"qsl4a/connectivity/phone/#phonedial","title":"phoneDial()","text":"

    Dial a number (opens dialer without calling).

    phoneDial(uri)\n

    Parameters: - uri (str): Contact URI or phone number URI

    "},{"location":"qsl4a/connectivity/phone/#phonedialnumber","title":"phoneDialNumber()","text":"

    Dial a phone number (opens dialer without calling).

    phoneDialNumber(phone_number)\n

    Parameters: - phone_number (str): Phone number

    "},{"location":"qsl4a/connectivity/phone/#cell-location","title":"Cell Location","text":""},{"location":"qsl4a/connectivity/phone/#getcelllocation","title":"getCellLocation()","text":"

    Get the current cell location.

    getCellLocation()\n

    Returns: JSONObject with cell location data

    "},{"location":"qsl4a/connectivity/phone/#getallcellslocation","title":"getAllCellsLocation()","text":"

    Get all cell locations (for dual SIM devices).

    getAllCellsLocation()\n

    Returns: JSONArray of cell locations

    "},{"location":"qsl4a/connectivity/phone/#network-information","title":"Network Information","text":""},{"location":"qsl4a/connectivity/phone/#getnetworkoperator","title":"getNetworkOperator()","text":"

    Get the MCC+MNC of the current operator.

    getNetworkOperator()\n

    Returns: String (e.g., '310260')

    "},{"location":"qsl4a/connectivity/phone/#getnetworkoperatorname","title":"getNetworkOperatorName()","text":"

    Get the name of the current operator.

    getNetworkOperatorName()\n

    Returns: String (e.g., 'T-Mobile')

    "},{"location":"qsl4a/connectivity/phone/#getnetworktype","title":"getNetworkType()","text":"

    Get the current network type.

    getNetworkType()\n

    Returns: String describing radio technology (e.g., 'LTE', 'UMTS', 'GSM')

    "},{"location":"qsl4a/connectivity/phone/#getphonetype","title":"getPhoneType()","text":"

    Get the phone type.

    getPhoneType()\n

    Returns: String (e.g., 'GSM', 'CDMA', 'SIP')

    "},{"location":"qsl4a/connectivity/phone/#sim-information","title":"SIM Information","text":""},{"location":"qsl4a/connectivity/phone/#getsimcountryiso","title":"getSimCountryIso()","text":"

    Get the ISO country code for the SIM.

    getSimCountryIso()\n

    Returns: String (e.g., 'us')

    "},{"location":"qsl4a/connectivity/phone/#getsimoperator","title":"getSimOperator()","text":"

    Get the MCC+MNC of the SIM operator.

    getSimOperator()\n

    Returns: String (e.g., '310260')

    "},{"location":"qsl4a/connectivity/phone/#getsimoperatorname","title":"getSimOperatorName()","text":"

    Get the SIM operator name.

    getSimOperatorName()\n

    Returns: String (e.g., 'T-Mobile')

    "},{"location":"qsl4a/connectivity/phone/#getsimserialnumber","title":"getSimSerialNumber()","text":"

    Get the SIM serial number.

    getSimSerialNumber()\n

    Returns: String SIM serial number

    "},{"location":"qsl4a/connectivity/phone/#getsimstate","title":"getSimState()","text":"

    Get the SIM card state.

    getSimState()\n

    Returns: String describing SIM state

    "},{"location":"qsl4a/connectivity/phone/#getsubscriberid","title":"getSubscriberId()","text":"

    Get the subscriber ID.

    getSubscriberId()\n

    Returns: String subscriber ID

    "},{"location":"qsl4a/connectivity/phone/#voice-mail","title":"Voice Mail","text":""},{"location":"qsl4a/connectivity/phone/#getvoicemailalphatag","title":"getVoiceMailAlphaTag()","text":"

    Get the voice mail alpha tag.

    getVoiceMailAlphaTag()\n

    Returns: String voice mail tag

    "},{"location":"qsl4a/connectivity/phone/#getvoicemailnumber","title":"getVoiceMailNumber()","text":"

    Get the voice mail number.

    getVoiceMailNumber()\n

    Returns: String voice mail number

    "},{"location":"qsl4a/connectivity/phone/#device-information","title":"Device Information","text":""},{"location":"qsl4a/connectivity/phone/#getdeviceid","title":"getDeviceId()","text":"

    Get the device ID (IMEI for GSM). Deprecated.

    getDeviceId()\n

    Returns: String device ID

    "},{"location":"qsl4a/connectivity/phone/#getdevicesoftwareversion","title":"getDeviceSoftwareVersion()","text":"

    Get the device software version.

    getDeviceSoftwareVersion()\n

    Returns: String software version

    "},{"location":"qsl4a/connectivity/phone/#getline1number","title":"getLine1Number()","text":"

    Get the line 1 phone number.

    getLine1Number()\n

    Returns: String phone number

    "},{"location":"qsl4a/connectivity/phone/#checknetworkroaming","title":"checkNetworkRoaming()","text":"

    Check if connected to roaming network.

    checkNetworkRoaming()\n

    Returns: True if roaming

    "},{"location":"qsl4a/connectivity/phone/#cell-info","title":"Cell Info","text":""},{"location":"qsl4a/connectivity/phone/#getallcellinfo","title":"getAllCellInfo()","text":"

    Get information about all cells.

    getAllCellInfo()\n

    Returns: List of cell information

    "},{"location":"qsl4a/connectivity/phone/#setdataenabled","title":"setDataEnabled()","text":"

    Enable or disable mobile data.

    setDataEnabled(enabled)\n

    Parameters: - enabled (bool): True to enable, False to disable

    "},{"location":"qsl4a/connectivity/phone/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get network info\noperator = droid.getNetworkOperatorName().result\nprint(f\"Operator: {operator}\")\n\nnetwork_type = droid.getNetworkType().result\nprint(f\"Network: {network_type}\")\n\n# Get SIM info\nsim_state = droid.getSimState().result\nprint(f\"SIM: {sim_state}\")\n\n# Get phone number\nline1 = droid.getLine1Number().result\nprint(f\"Phone: {line1}\")\n\n# Track phone state\ndroid.startTrackingPhoneState()\nprint(\"Tracking phone state...\")\ndroid.stopTrackingPhoneState()\n
    "},{"location":"qsl4a/connectivity/signalstrength/","title":"Signal Strength API","text":"

    Monitor cellular and wireless signal strength.

    "},{"location":"qsl4a/connectivity/signalstrength/#signal-strength-methods","title":"Signal Strength Methods","text":""},{"location":"qsl4a/connectivity/signalstrength/#starttrackingsignalstrengths","title":"startTrackingSignalStrengths()","text":"

    Start tracking signal strength changes. Generates 'signal_strengths' events.

    startTrackingSignalStrengths()\n
    "},{"location":"qsl4a/connectivity/signalstrength/#stoptrackingsignalstrengths","title":"stopTrackingSignalStrengths()","text":"

    Stop tracking signal strengths.

    stopTrackingSignalStrengths()\n
    "},{"location":"qsl4a/connectivity/signalstrength/#readsignalstrengths","title":"readSignalStrengths()","text":"

    Read the current signal strengths.

    readSignalStrengths()\n

    Returns: Bundle with signal strength data

    "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthlevel","title":"getTelephoneSignalStrengthLevel()","text":"

    Get the telephone signal strength as a level (0-4).

    getTelephoneSignalStrengthLevel()\n

    Returns: Integer level (0=none, 1=poor, 2=fair, 3=good, 4=excellent)

    "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthdetail","title":"getTelephoneSignalStrengthDetail()","text":"

    Get detailed telephone signal strength information.

    getTelephoneSignalStrengthDetail()\n

    Returns: String with detailed signal info

    "},{"location":"qsl4a/connectivity/signalstrength/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start tracking signal strength\ndroid.startTrackingSignalStrengths()\n\n# Wait for signal updates\ntime.sleep(5)\n\n# Read current signal strength\nsignal = droid.readSignalStrengths().result\nprint(f\"Signal: {signal}\")\n\n# Get level directly\nlevel = droid.getTelephoneSignalStrengthLevel().result\nprint(f\"Signal level: {level}/4\")\n\ndroid.stopTrackingSignalStrengths()\n
    "},{"location":"qsl4a/connectivity/sms/","title":"SMS API","text":"

    Send and receive SMS messages.

    "},{"location":"qsl4a/connectivity/sms/#methods","title":"Methods","text":""},{"location":"qsl4a/connectivity/sms/#smssend","title":"smsSend()","text":"

    Send SMS message.

    smsSend(destinationAddress, text)\n

    Parameters: - destinationAddress (str): Phone number - text (str): Message text

    "},{"location":"qsl4a/connectivity/sms/#smsgetmessagecount","title":"smsGetMessageCount()","text":"

    Get message count.

    smsGetMessageCount(unreadOnly=False, folder=\"inbox\")\n
    "},{"location":"qsl4a/connectivity/sms/#smsgetmessageids","title":"smsGetMessageIds()","text":"

    Get message IDs.

    smsGetMessageIds(unreadOnly=False, folder=\"inbox\")\n
    "},{"location":"qsl4a/connectivity/sms/#smsgetmessages","title":"smsGetMessages()","text":"

    Get message details.

    smsGetMessages(unreadOnly=False, folder=\"inbox\", attributes=None)\n
    "},{"location":"qsl4a/connectivity/sms/#smsgetmessagebyid","title":"smsGetMessageById()","text":"

    Get a specific message by ID.

    smsGetMessageById(id, attributes=None)\n

    Parameters: - id (int): Message ID - attributes (list, optional): Specific attributes to retrieve

    Returns: Message data dict

    "},{"location":"qsl4a/connectivity/sms/#smsgetattributes","title":"smsGetAttributes()","text":"

    Get available SMS message attributes.

    smsGetAttributes()\n

    Returns: List of available attribute names

    "},{"location":"qsl4a/connectivity/sms/#smsdeletemessage","title":"smsDeleteMessage()","text":"

    Delete message.

    smsDeleteMessage(id)\n
    "},{"location":"qsl4a/connectivity/sms/#smsmarkmessageread","title":"smsMarkMessageRead()","text":"

    Mark message as read.

    smsMarkMessageRead(ids, read=True)\n
    "},{"location":"qsl4a/connectivity/sms/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Send SMS\ndroid.smsSend(\"+1234567890\", \"Hello from QPython!\")\n\n# Get unread messages\nmessages = droid.smsGetMessages(unreadOnly=True).result\nfor msg in messages:\n    print(f\"From: {msg['address']}, Text: {msg['body']}\")\n
    "},{"location":"qsl4a/connectivity/wifi/","title":"WiFi API","text":"

    Control WiFi adapter and get connection information.

    "},{"location":"qsl4a/connectivity/wifi/#adapter-control","title":"Adapter Control","text":""},{"location":"qsl4a/connectivity/wifi/#checkwifistate","title":"checkWifiState()","text":"

    Check if WiFi is enabled.

    checkWifiState()\n

    Returns: True if WiFi is enabled, False otherwise

    "},{"location":"qsl4a/connectivity/wifi/#togglewifistate","title":"toggleWifiState()","text":"

    Turn WiFi on or off.

    toggleWifiState(enabled=None)\n

    Parameters: - enabled (bool): True to enable, False to disable, None to toggle

    Returns: True if operation succeeded

    "},{"location":"qsl4a/connectivity/wifi/#wifistartscan","title":"wifiStartScan()","text":"

    Start scanning for available WiFi networks.

    wifiStartScan()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifigetscanresults","title":"wifiGetScanResults()","text":"

    Get list of discovered WiFi networks.

    wifiGetScanResults()\n

    Returns: List of access point information

    "},{"location":"qsl4a/connectivity/wifi/#connection-management","title":"Connection Management","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetconnectioninfo","title":"wifiGetConnectionInfo()","text":"

    Get detailed connection information.

    wifiGetConnectionInfo()\n

    Returns: Dict with connection details including SSID, BSSID, IP address

    "},{"location":"qsl4a/connectivity/wifi/#getconnectedinfo","title":"getConnectedInfo()","text":"

    Get connected WiFi network info (simplified).

    getConnectedInfo()\n

    Returns: Dict with SSID, BSSID, signal strength

    "},{"location":"qsl4a/connectivity/wifi/#getdhcpinfo","title":"getDhcpInfo()","text":"

    Get DHCP information for current connection.

    getDhcpInfo(ipConvertToString=True)\n

    Parameters: - ipConvertToString (bool): Convert IP addresses to string format (default: True)

    Returns: Dict with DHCP info including IP, gateway, DNS

    "},{"location":"qsl4a/connectivity/wifi/#wifidisconnect","title":"wifiDisconnect()","text":"

    Disconnect from current WiFi network.

    wifiDisconnect()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifireconnect","title":"wifiReconnect()","text":"

    Reconnect to the current network.

    wifiReconnect()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifireassociate","title":"wifiReassociate()","text":"

    Reassociate with the current access point.

    wifiReassociate()\n
    "},{"location":"qsl4a/connectivity/wifi/#hotspot","title":"Hotspot","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetapstate","title":"wifiGetApState()","text":"

    Get WiFi AP (hotspot) state.

    wifiGetApState()\n

    Returns: Hotspot state

    "},{"location":"qsl4a/connectivity/wifi/#wifi-locks","title":"WiFi Locks","text":""},{"location":"qsl4a/connectivity/wifi/#wifilockacquirefull","title":"wifiLockAcquireFull()","text":"

    Acquire a full WiFi lock (keeps WiFi active even when screen is off).

    wifiLockAcquireFull()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifilockacquirescanonly","title":"wifiLockAcquireScanOnly()","text":"

    Acquire a scan-only WiFi lock.

    wifiLockAcquireScanOnly()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifilockrelease","title":"wifiLockRelease()","text":"

    Release the WiFi lock.

    wifiLockRelease()\n
    "},{"location":"qsl4a/connectivity/wifi/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Check WiFi state\nif droid.checkWifiState().result:\n    print(\"WiFi is enabled\")\nelse:\n    print(\"Enabling WiFi...\")\n    droid.toggleWifiState(True)\n    time.sleep(2)\n\n# Start scanning\ndroid.wifiStartScan()\ntime.sleep(3)\n\n# Get scan results\nnetworks = droid.wifiGetScanResults().result\nfor network in networks:\n    print(f\"SSID: {network.get('SSID')}, Signal: {network.get('level')} dBm\")\n\n# Get connection info\ninfo = droid.wifiGetConnectionInfo().result\nif info:\n    print(f\"Connected to: {info.get('ssid')}\")\n    print(f\"BSSID: {info.get('bssid')}\")\n    print(f\"IP: {info.get('ip_address')}\")\n\n# Get DHCP info\ndhcp = droid.getDhcpInfo().result\nif dhcp:\n    print(f\"Gateway: {dhcp.get('gateway')}\")\n    print(f\"DNS: {dhcp.get('dns1')}\")\n\n# Get simplified connected info\nconnected = droid.getConnectedInfo().result\nprint(f\"SSID: {connected.get('ssid')}, Signal: {connected.get('level')} dBm\")\n\n# Disconnect and reconnect\ndroid.wifiDisconnect()\ntime.sleep(1)\ndroid.wifiReconnect()\n\n# Reassociate with access point\ndroid.wifiReassociate()\n\n# Check hotspot state\nap_state = droid.wifiGetApState().result\nprint(f\"Hotspot state: {ap_state}\")\n\n# Acquire WiFi lock for background operation\ndroid.wifiLockAcquireFull()\n# ... do work ...\ndroid.wifiLockRelease()\n\n# Or use scan-only lock for lighter background operation\ndroid.wifiLockAcquireScanOnly()\n# ... do scanning work ...\ndroid.wifiLockRelease()\n
    "},{"location":"qsl4a/core/android-base/","title":"Android Base Class","text":"

    The Android class is the core of QSL4A, providing the connection to the Android runtime and RPC mechanism.

    "},{"location":"qsl4a/core/android-base/#module-import","title":"Module Import","text":"
    # Full featured (recommended)\nimport androidhelper\ndroid = androidhelper.Android()\n\n# Minimal version (quick, single instance)\nimport android\ndroid = android.droid\n
    "},{"location":"qsl4a/core/android-base/#class-android","title":"Class: Android","text":""},{"location":"qsl4a/core/android-base/#constructor","title":"Constructor","text":"
    Android(addr=None)\n

    Parameters: - addr (tuple, optional): (HOST, PORT) address. If None, uses environment variables AP_HOST and AP_PORT

    Environment Variables: - AP_HOST - Server host address - AP_PORT - Server port - AP_HANDSHAKE - Authentication token

    "},{"location":"qsl4a/core/android-base/#core-methods","title":"Core Methods","text":""},{"location":"qsl4a/core/android-base/#_rpc","title":"_rpc()","text":"

    Internal RPC method for calling Android functions.

    _rpc(method, *args)\n

    Parameters: - method (str): Method name to call - *args: Variable arguments for the method

    Returns: Result namedtuple with fields: - id (int): Request ID - result: Method return value - error (str or None): Error message if failed

    "},{"location":"qsl4a/core/android-base/#getattr","title":"getattr()","text":"

    Dynamic method dispatcher. All Android methods are accessed via attribute lookup.

    # These are equivalent:\ndroid.makeToast(\"Hello\")\ndroid._rpc(\"makeToast\", \"Hello\")\n
    "},{"location":"qsl4a/core/android-base/#standalone-functions-androidpy","title":"Standalone Functions (android.py)","text":"

    When using the minimal android module:

    "},{"location":"qsl4a/core/android-base/#jsla","title":"jsla()","text":"

    Send JSON-RPC request and return raw response.

    jsla(method, *params)\n

    Returns: JSON string response

    "},{"location":"qsl4a/core/android-base/#rsla","title":"rsla()","text":"

    Send request and return result only.

    rsla(method, *params)\n

    Returns: Result value from RPC call

    "},{"location":"qsl4a/core/android-base/#esla","title":"esla()","text":"

    Send request, raise exception on error.

    esla(method, *params)\n

    Raises: Exception if error field is not None

    "},{"location":"qsl4a/core/android-base/#nsla","title":"nsla()","text":"

    Send request and return Result namedtuple.

    nsla(method, *params)\n

    Returns: Result namedtuple

    "},{"location":"qsl4a/core/android-base/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/android-base/#basic-connection","title":"Basic Connection","text":"
    import androidhelper\n\n# Connect to Android runtime\ndroid = androidhelper.Android()\n\n# Check connection by showing toast\ndroid.makeToast(\"Connected!\")\n
    "},{"location":"qsl4a/core/android-base/#error-handling","title":"Error Handling","text":"
    result = droid.someMethod()\nif result.error:\n    print(f\"Error: {result.error}\")\nelse:\n    print(f\"Success: {result.result}\")\n
    "},{"location":"qsl4a/core/android-base/#direct-rpc-call","title":"Direct RPC Call","text":"
    # Call any method directly\nresult = droid._rpc(\"makeToast\", \"Hello World\")\n
    "},{"location":"qsl4a/core/events/","title":"Event System","text":"

    QSL4A provides an event system for handling asynchronous events from Android, such as sensor updates, location changes, and custom broadcasts.

    "},{"location":"qsl4a/core/events/#event-basics","title":"Event Basics","text":"

    Events are stored in a buffer and can be polled or waited for. Each event has: - name: Event type/name - data: Event payload data - time: Timestamp

    "},{"location":"qsl4a/core/events/#event-methods","title":"Event Methods","text":""},{"location":"qsl4a/core/events/#eventclearbuffer","title":"eventClearBuffer()","text":"

    Clear all pending events from the buffer.

    eventClearBuffer()\n

    Returns: None

    "},{"location":"qsl4a/core/events/#eventpoll","title":"eventPoll()","text":"

    Poll for events in the buffer.

    eventPoll(number_of_events=1)\n

    Parameters: - number_of_events (int): Maximum events to retrieve (default: 1)

    Returns: List of event objects

    "},{"location":"qsl4a/core/events/#eventwait","title":"eventWait()","text":"

    Wait for any event.

    eventWait(timeout=None)\n

    Parameters: - timeout (int, optional): Timeout in seconds. None = wait forever

    Returns: Event object or None if timeout

    "},{"location":"qsl4a/core/events/#eventwaitfor","title":"eventWaitFor()","text":"

    Wait for a specific event.

    eventWaitFor(eventName, timeout=None)\n

    Parameters: - eventName (str): Name of event to wait for - timeout (int, optional): Timeout in seconds

    Returns: Event object or None if timeout

    "},{"location":"qsl4a/core/events/#eventpost","title":"eventPost()","text":"

    Post a custom event.

    eventPost(name, data, enqueue=None)\n

    Parameters: - name (str): Event name - data: Event data (any type) - enqueue (bool, optional): Add to queue if True

    "},{"location":"qsl4a/core/events/#receiveevent","title":"receiveEvent()","text":"

    Receive event (blocking).

    receiveEvent()\n

    Returns: Event object

    "},{"location":"qsl4a/core/events/#broadcast-events","title":"Broadcast Events","text":"

    Register for system broadcast events.

    "},{"location":"qsl4a/core/events/#eventregisterforbroadcast","title":"eventRegisterForBroadcast()","text":"

    Register to receive broadcast events.

    eventRegisterForBroadcast(category, enqueue=True)\n

    Parameters: - category (str): Broadcast category/action - enqueue (bool): Add to event queue

    "},{"location":"qsl4a/core/events/#eventunregisterforbroadcast","title":"eventUnregisterForBroadcast()","text":"

    Unregister from broadcast events.

    eventUnregisterForBroadcast(category)\n
    "},{"location":"qsl4a/core/events/#eventgetbrodcastcategories","title":"eventGetBrodcastCategories()","text":"

    Get registered broadcast categories.

    eventGetBrodcastCategories()\n

    Returns: List of registered categories

    "},{"location":"qsl4a/core/events/#event-dispatcher","title":"Event Dispatcher)","text":""},{"location":"qsl4a/core/events/#starteventdispatcher","title":"startEventDispatcher()","text":"

    Opens up a socket where you can read for events posted.)

    startEventDispatcher(port=0)\n

    Parameters: - port (int, optional): Port to listen on (default: 0 = auto-select)

    Returns: Port number being listened on

    "},{"location":"qsl4a/core/events/#stopeventdispatcher","title":"stopEventDispatcher()","text":"

    Stops the event server.)

    stopEventDispatcher()\n
    "},{"location":"qsl4a/core/events/#deprecated-methods","title":"Deprecated Methods","text":""},{"location":"qsl4a/core/events/#rpcpostevent","title":"rpcPostEvent()","text":"

    Post an event to the event queue. (Deprecated, use eventPost)

    rpcPostEvent(name, data)\n

    Parameters: - name (str): Event name - data: Event data

    "},{"location":"qsl4a/core/events/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/events/#basic-event-polling","title":"Basic Event Polling","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Clear old events\ndroid.eventClearBuffer()\n\n# Poll for events\nevents = droid.eventPoll(5).result\nfor event in events:\n    print(f\"Event: {event['name']}, Data: {event['data']}\")\n
    "},{"location":"qsl4a/core/events/#waiting-for-events","title":"Waiting for Events","text":"
    # Wait for any event with timeout\nevent = droid.eventWait(timeout=10).result\nif event:\n    print(f\"Got event: {event['name']}\")\n
    "},{"location":"qsl4a/core/events/#waiting-for-specific-event","title":"Waiting for Specific Event","text":"
    # Wait for sensor event\nevent = droid.eventWaitFor('screen', timeout=5).result\nif event:\n    print(f\"Screen event: {event['data']}\")\n
    "},{"location":"qsl4a/core/events/#posting-custom-events","title":"Posting Custom Events","text":"
    # Post custom event\ndroid.eventPost('my_event', {'key': 'value'})\n\n# Wait for it\nevent = droid.eventWaitFor('my_event', timeout=1).result\n
    "},{"location":"qsl4a/core/events/#broadcast-receiver","title":"Broadcast Receiver","text":"
    # Register for screen on/off events\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_ON')\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_OFF')\n\n# Wait for screen events\nwhile True:\n    event = droid.receiveEvent().result\n    if event['name'] == 'android.intent.action.SCREEN_ON':\n        print(\"Screen turned on\")\n    elif event['name'] == 'android.intent.action.SCREEN_OFF':\n        print(\"Screen turned off\")\n
    "},{"location":"qsl4a/core/events/#sensor-event-handling","title":"Sensor Event Handling","text":"
    # Start sensing\ndroid.startSensingTimed(1, 250)\n\n# Process sensor events\nfor _ in range(100):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'sensors':\n        data = event['data']\n        print(f\"Accel: {data['xforce']}, {data['yforce']}, {data['zforce']}\")\n\ndroid.stopSensing()\n
    "},{"location":"qsl4a/core/events/#common-event-types","title":"Common Event Types","text":"Event Name Description Source sensors Sensor data update startSensing* location GPS location update startLocating phone Phone state change startTrackingPhoneState signal Signal strength change startTrackingSignalStrength screen Screenshot ready fullGetScreenShot dialog Dialog response dialogShow*"},{"location":"qsl4a/core/events/#event-data-structure","title":"Event Data Structure","text":"
    {\n    'name': 'event_name',\n    'data': {\n        # Event-specific data\n    },\n    'time': 1234567890  # Timestamp\n}\n
    "},{"location":"qsl4a/core/intent/","title":"Intent System","text":"

    Android Intents are used to start activities, send broadcasts, and communicate between apps. QSL4A provides full Intent support through the Intent module.

    "},{"location":"qsl4a/core/intent/#module-import","title":"Module Import","text":"
    import androidhelper\ndon = androidhelper.Android()\n
    "},{"location":"qsl4a/core/intent/#intent-constants","title":"Intent Constants","text":"

    Access via droid.Intent:

    "},{"location":"qsl4a/core/intent/#actions","title":"Actions","text":"Constant Value Usage ACTION_MAIN android.intent.action.MAIN App entry point ACTION_VIEW android.intent.action.VIEW View content ACTION_EDIT android.intent.action.EDIT Edit content ACTION_PICK android.intent.action.PICK Pick item ACTION_SEND android.intent.action.SEND Share content ACTION_SEARCH android.intent.action.SEARCH Search"},{"location":"qsl4a/core/intent/#flags","title":"Flags","text":"Constant Value Usage FLAG_ACTIVITY_NEW_TASK 268435456 Start new task FLAG_ACTIVITY_CLEAR_TASK 32768 Clear task stack FLAG_ACTIVITY_NEW_DOCUMENT 524288 New document mode"},{"location":"qsl4a/core/intent/#extras","title":"Extras","text":"Constant Usage EXTRA_TEXT Text content EXTRA_STREAM File URI EXTRA_SUBJECT Subject line EXTRA_EMAIL Email address"},{"location":"qsl4a/core/intent/#core-methods","title":"Core Methods","text":""},{"location":"qsl4a/core/intent/#makeintent","title":"makeIntent()","text":"

    Create an Intent object.

    makeIntent(action, uri=None, type=None, extras=None, categories=None,\n           packagename=None, classname=None, flags=None)\n

    Parameters: - action (str): Intent action (e.g., droid.Intent.ACTION_VIEW) - uri (str, optional): Data URI - type (str, optional): MIME type - extras (dict, optional): Extra data - categories (list, optional): Intent categories - packagename (str, optional): Target package - classname (str, optional): Target class - flags (int, optional): Intent flags

    Returns: Intent object

    "},{"location":"qsl4a/core/intent/#startactivityintent","title":"startActivityIntent()","text":"

    Start an Activity with an Intent.

    startActivityIntent(intent, wait=None)\n

    Parameters: - intent: Intent object from makeIntent() - wait (bool, optional): Block until activity closes

    "},{"location":"qsl4a/core/intent/#startactivityforresultintent","title":"startActivityForResultIntent()","text":"

    Start activity and wait for result.

    startActivityForResultIntent(intent)\n

    Returns: Activity result

    "},{"location":"qsl4a/core/intent/#sendbroadcastintent","title":"sendBroadcastIntent()","text":"

    Send a broadcast.

    sendBroadcastIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#view","title":"view()","text":"

    View content by URI.

    view(uri, type=None, extras=None)\n
    "},{"location":"qsl4a/core/intent/#pick","title":"pick()","text":"

    Pick content from URI.

    pick(uri)\n
    "},{"location":"qsl4a/core/intent/#common-intent-methods","title":"Common Intent Methods)","text":""},{"location":"qsl4a/core/intent/#scanbarcode","title":"scanBarcode()","text":"

    Launch the barcode scanner.

    scanBarcode()\n

    Returns: Scanned barcode string

    "},{"location":"qsl4a/core/intent/#send","title":"send()","text":"

    Send content via share intent.

    send(type, content)\n

    Parameters: - type (str): MIME type - content (str): Content to share

    "},{"location":"qsl4a/core/intent/#sendtext","title":"sendText()","text":"

    Send text content.

    sendText(text)\n

    Parameters: - text (str): Text to send

    "},{"location":"qsl4a/core/intent/#sendemail","title":"sendEmail()","text":"

    Send an email.

    sendEmail(to, subject, body, attachment=None)\n

    Parameters: - to (str or list): Recipient email address(es) - subject (str): Email subject - body (str): Email body - attachment (str, optional): Attachment file path

    "},{"location":"qsl4a/core/intent/#pathtouri","title":"pathToUri()","text":"

    Convert file path to content URI.

    pathToUri(path)\n

    Parameters: - path (str): File path

    Returns: Content URI string

    "},{"location":"qsl4a/core/intent/#openfile","title":"openFile()","text":"

    Open a file with appropriate app.

    openFile(path)\n

    Parameters: - path (str): File path to open

    "},{"location":"qsl4a/core/intent/#sendfile","title":"sendFile()","text":"

    Send a file via share intent.

    sendFile(path)\n

    Parameters: - path (str): File path to send

    "},{"location":"qsl4a/core/intent/#getpathtype","title":"getPathType()","text":"

    Get the MIME type for a file path.

    getPathType(path)\n

    Parameters: - path (str): File path

    Returns: MIME type string

    "},{"location":"qsl4a/core/intent/#viewmap","title":"viewMap()","text":"

    Open map at a location.

    viewMap(latitude, longitude)\n

    Parameters: - latitude (float): Latitude - longitude (float): Longitude

    "},{"location":"qsl4a/core/intent/#viewcontacts","title":"viewContacts()","text":"

    Open the contacts app.

    viewContacts()\n
    "},{"location":"qsl4a/core/intent/#search","title":"search()","text":"

    Perform a web search.

    search(query)\n

    Parameters: - query (str): Search query

    "},{"location":"qsl4a/core/intent/#viewhtml","title":"viewHtml()","text":"

    View HTML content.

    viewHtml(content, encoding=None)\n

    Parameters: - content (str): HTML content - encoding (str, optional): Character encoding

    "},{"location":"qsl4a/core/intent/#webviewshow","title":"webViewShow()","text":"

    Display web content in WebView. Deprecated, use viewHtml.

    webViewShow(url)\n

    Parameters: - url (str): Web page URL

    "},{"location":"qsl4a/core/intent/#editoropen","title":"editorOpen()","text":"

    Open a text editor.

    editorOpen(path=None, create=False)\n

    Parameters: - path (str, optional): File path to edit - create (bool, optional): Create if doesn't exist

    "},{"location":"qsl4a/core/intent/#helper-class-uri","title":"Helper Class: Uri","text":"

    Create URI objects for Intents:

    from androidhelper.Intent import Uri\n\nuri = Uri(\"file:///sdcard/test.txt\")\n
    "},{"location":"qsl4a/core/intent/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/intent/#open-web-page","title":"Open Web Page","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"http://www.example.com\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#share-text","title":"Share Text","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_TEXT: \"Hello from QPython!\",\n        droid.Intent.EXTRA_SUBJECT: \"Test\"\n    },\n    type=\"text/plain\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#open-file","title":"Open File","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"file:///sdcard/document.pdf\",\n    type=\"application/pdf\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#pick-contact","title":"Pick Contact","text":"
    result = droid.pickContact()\ncontact_uri = result.result\n
    "},{"location":"qsl4a/core/intent/#send-email","title":"Send Email","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_EMAIL: [\"test@example.com\"],\n        droid.Intent.EXTRA_SUBJECT: \"Hello\",\n        droid.Intent.EXTRA_TEXT: \"Message body\"\n    },\n    type=\"message/rfc822\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#open-app","title":"Open App","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_MAIN,\n    packagename=\"com.android.settings\",\n    classname=\"com.android.settings.Settings\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/hardware/bluetooth/","title":"Bluetooth API","text":"

    Control Bluetooth adapter and communicate with Bluetooth devices.

    "},{"location":"qsl4a/hardware/bluetooth/#adapter-control","title":"Adapter Control","text":""},{"location":"qsl4a/hardware/bluetooth/#togglebluetoothstate","title":"toggleBluetoothState()","text":"

    Turn Bluetooth on/off.

    toggleBluetoothState(enabled=None, prompt=True)\n

    Parameters: - enabled (bool): True=on, False=off, None=toggle - prompt (bool): Show user prompt

    "},{"location":"qsl4a/hardware/bluetooth/#checkbluetoothstate","title":"checkBluetoothState()","text":"

    Check if Bluetooth is enabled.

    checkBluetoothState()\n

    Returns: True/False

    "},{"location":"qsl4a/hardware/bluetooth/#getlocalname","title":"GetLocalName()","text":"

    Get Bluetooth device name.

    GetLocalName()\n
    "},{"location":"qsl4a/hardware/bluetooth/#setlocalname","title":"SetLocalName()","text":"

    Set Bluetooth device name.

    SetLocalName(name)\n
    "},{"location":"qsl4a/hardware/bluetooth/#getscanmode","title":"GetScanMode()","text":"

    Get discoverability mode.

    GetScanMode()\n

    Returns: - -1: Disabled - 0: Non-discoverable, non-connectable - 1: Connectable, non-discoverable - 3: Connectable and discoverable

    "},{"location":"qsl4a/hardware/bluetooth/#makediscoverable","title":"MakeDiscoverable()","text":"

    Make device discoverable.

    MakeDiscoverable(duration=300)\n

    Parameters: - duration (int): Seconds to be discoverable

    "},{"location":"qsl4a/hardware/bluetooth/#discovery","title":"Discovery","text":""},{"location":"qsl4a/hardware/bluetooth/#discoverystart","title":"DiscoveryStart()","text":"

    Start device discovery.

    DiscoveryStart()\n
    "},{"location":"qsl4a/hardware/bluetooth/#discoverycancel","title":"DiscoveryCancel()","text":"

    Cancel discovery.

    DiscoveryCancel()\n
    "},{"location":"qsl4a/hardware/bluetooth/#getreceiveddevices","title":"GetReceivedDevices()","text":"

    Get discovered devices.

    GetReceivedDevices()\n

    Returns: List of device info dicts

    "},{"location":"qsl4a/hardware/bluetooth/#getbondeddevices","title":"GetBondedDevices()","text":"

    Get paired devices.

    GetBondedDevices()\n

    Returns: List of paired device info

    "},{"location":"qsl4a/hardware/bluetooth/#connection","title":"Connection","text":""},{"location":"qsl4a/hardware/bluetooth/#connect","title":"Connect()","text":"

    Connect to a device.

    Connect(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", address=None)\n

    Parameters: - uuid (str): Service UUID - address (str): Device address (None = show picker)

    Returns: True if successful

    "},{"location":"qsl4a/hardware/bluetooth/#accept","title":"Accept()","text":"

    Accept incoming connection.

    Accept(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", timeout=0)\n
    "},{"location":"qsl4a/hardware/bluetooth/#activeconnections","title":"ActiveConnections()","text":"

    Check active connections.

    ActiveConnections()\n
    "},{"location":"qsl4a/hardware/bluetooth/#stop","title":"Stop()","text":"

    Disconnect.

    Stop(connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#communication","title":"Communication","text":""},{"location":"qsl4a/hardware/bluetooth/#write","title":"Write()","text":"

    Send ASCII data.

    Write(ascii, connID=\"\")\n
    "},{"location":"qsl4a/hardware/bluetooth/#writebinary","title":"WriteBinary()","text":"

    Send binary data (base64 encoded).

    WriteBinary(base64, connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#read","title":"Read()","text":"

    Read ASCII data.

    Read(bufferSize=4096, connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#readbinary","title":"ReadBinary()","text":"

    Read binary data.

    ReadBinary(bufferSize=4096, connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#readline","title":"ReadLine()","text":"

    Read line.

    ReadLine(connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#readready","title":"ReadReady()","text":"

    Check if data available.

    ReadReady(connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Enable Bluetooth\ndroid.toggleBluetoothState(True)\n\n# Get paired devices\ndevices = droid.GetBondedDevices().result\nfor dev in devices:\n    print(f\"{dev['name']}: {dev['address']}\")\n\n# Connect to device\ndroid.Connect(address=\"00:11:22:33:44:55\")\n\n# Send data\ndroid.Write(\"Hello Bluetooth!\")\n\n# Read response\ndata = droid.Read(1024).result\n
    "},{"location":"qsl4a/hardware/camera/","title":"Camera API","text":"

    Capture photos and record video.

    "},{"location":"qsl4a/hardware/camera/#photo-capture","title":"Photo Capture","text":""},{"location":"qsl4a/hardware/camera/#takepicture","title":"takePicture()","text":"

    Take a photo using the default camera.

    takePicture(path=None)\n

    Parameters: - path (str, optional): Save path. If None, returns image data

    Returns: Image path or image data

    "},{"location":"qsl4a/hardware/camera/#cameracapturepicture","title":"cameraCapturePicture()","text":"

    Capture picture with advanced camera controls.

    cameraCapturePicture(targetPath=None, cameraId=0, useAutoFocus=True)\n

    Parameters: - targetPath (str, optional): Save path - cameraId (int): Camera to use (0 = back, 1 = front) - useAutoFocus (bool): Enable auto focus

    Returns: Captured image path

    "},{"location":"qsl4a/hardware/camera/#camerasettorchmode","title":"cameraSetTorchMode()","text":"

    Control camera flashlight/torch.

    cameraSetTorchMode(enabled)\n

    Parameters: - enabled (bool): True to turn on, False to turn off

    Returns: True if successful

    "},{"location":"qsl4a/hardware/camera/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

    Capture screenshot.

    imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

    Parameters: - path (str, optional): Save path - delayMilliSec (int): Delay before capture

    "},{"location":"qsl4a/hardware/camera/#video-recording","title":"Video Recording","text":""},{"location":"qsl4a/hardware/camera/#takevideo","title":"takeVideo()","text":"

    Record video using default settings.

    takeVideo(path=None, quality=1)\n

    Parameters: - path (str, optional): Save path - quality (int): Video quality (0-4) - 0: 160x120 - 1: 320x240 - 2: 352x288 - 3: 640x480 - 4: 800x480

    "},{"location":"qsl4a/hardware/camera/#recordercapturevideo","title":"recorderCaptureVideo()","text":"

    Capture video with advanced controls.

    recorderCaptureVideo(targetPath=None, duration=10, cameraId=0, quality=8)\n

    Parameters: - targetPath (str, optional): Save path - duration (int): Recording duration in seconds (default: 10) - cameraId (int): Camera to use (0 = back, 1 = front) - quality (int): Video quality (0-8, higher is better)

    Returns: Video file path

    "},{"location":"qsl4a/hardware/camera/#recordaudio","title":"recordAudio()","text":"

    Record audio.

    recordAudio()\n

    Returns: Audio file path

    "},{"location":"qsl4a/hardware/camera/#screen-recording","title":"Screen Recording","text":""},{"location":"qsl4a/hardware/camera/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

    Start screen recording.

    recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

    Parameters: - path (str): Save path - audio (int): Audio source (0=none, 1=mic, 2=internal) - targetPixels (int): Resolution - frameRate (int): FPS - bitRate (int): Bitrate - rotation (bool): Rotate output - autoStart (bool): Start immediately

    "},{"location":"qsl4a/hardware/camera/#recorderstart","title":"recorderStart()","text":"

    Start recording.

    recorderStart()\n
    "},{"location":"qsl4a/hardware/camera/#recorderpause","title":"recorderPause()","text":"

    Pause recording.

    recorderPause()\n
    "},{"location":"qsl4a/hardware/camera/#recorderresume","title":"recorderResume()","text":"

    Resume recording.

    recorderResume()\n
    "},{"location":"qsl4a/hardware/camera/#audio-volume-detection","title":"Audio Volume Detection","text":""},{"location":"qsl4a/hardware/camera/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

    Start volume detection.

    recorderSoundVolumeDetect(interval=100)\n
    "},{"location":"qsl4a/hardware/camera/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

    Get current volume in dB.

    recorderSoundVolumeGetDb()\n
    "},{"location":"qsl4a/hardware/camera/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Take photo with default camera\nphoto_path = droid.takePicture(\"/sdcard/photo.jpg\").result\nprint(f\"Photo saved: {photo_path}\")\n\n# Take photo with front camera and auto focus\ncamera_path = droid.cameraCapturePicture(\"/sdcard/selfie.jpg\", cameraId=1, useAutoFocus=True).result\nprint(f\"Front camera photo: {camera_path}\")\n\n# Control flashlight\ndroid.cameraSetTorchMode(True)  # Turn on flashlight\n\n# Record video with default settings\nvideo_path = droid.takeVideo(\"/sdcard/video.mp4\", quality=3).result\nprint(f\"Video saved: {video_path}\")\n\n# Record video with advanced controls\nvideo_path = droid.recorderCaptureVideo(\"/sdcard/movie.mp4\", duration=30, cameraId=0, quality=8).result\n\n# Screenshot\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n
    "},{"location":"qsl4a/hardware/recorder/","title":"Audio Recorder API","text":"

    Record audio from microphone and device screen.

    "},{"location":"qsl4a/hardware/recorder/#audio-recording","title":"Audio Recording","text":""},{"location":"qsl4a/hardware/recorder/#recordaudio","title":"recordAudio()","text":"

    Record audio from microphone.

    recordAudio()\n

    Returns: Path to recorded audio file

    "},{"location":"qsl4a/hardware/recorder/#recorderstartmicrophone","title":"recorderStartMicrophone()","text":"

    Start recording from microphone to a specific file.

    recorderStartMicrophone(targetPath=None)\n

    Parameters: - targetPath (str, optional): Path to save the recording

    "},{"location":"qsl4a/hardware/recorder/#screen-recording","title":"Screen Recording","text":""},{"location":"qsl4a/hardware/recorder/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

    Start screen recording with audio.

    recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

    Parameters: - path (str): Save path for video file - audio (int): Audio source (0=none, 1=mic, 2=internal audio) - targetPixels (int): Target resolution in pixels - frameRate (int): Frames per second (default: 30) - bitRate (int): Video bitrate - rotation (bool): Rotate output video - autoStart (bool): Start recording immediately

    Returns: Result of operation

    "},{"location":"qsl4a/hardware/recorder/#recorderstart","title":"recorderStart()","text":"

    Start the screen recording (when autoStart=False).

    recorderStart()\n
    "},{"location":"qsl4a/hardware/recorder/#recorderpause","title":"recorderPause()","text":"

    Pause ongoing screen recording.

    recorderPause()\n
    "},{"location":"qsl4a/hardware/recorder/#recorderresume","title":"recorderResume()","text":"

    Resume paused screen recording.

    recorderResume()\n
    "},{"location":"qsl4a/hardware/recorder/#audio-volume-detection","title":"Audio Volume Detection","text":""},{"location":"qsl4a/hardware/recorder/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

    Start monitoring sound volume level.

    recorderSoundVolumeDetect(interval=100)\n

    Parameters: - interval (int): Detection interval in milliseconds (default: 100)

    "},{"location":"qsl4a/hardware/recorder/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

    Get current sound volume in decibels.

    recorderSoundVolumeGetDb()\n

    Returns: Current volume level in dB

    "},{"location":"qsl4a/hardware/recorder/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Record audio from microphone\nprint(\"Recording audio...\")\naudio_path = droid.recordAudio().result\nprint(f\"Saved to: {audio_path}\")\n\n# Record microphone to specific file\ndroid.recorderStartMicrophone(\"/sdcard/my_recording.mp3\")\ntime.sleep(5)\ndroid.recorderStop()\n\n# Record screen with audio\nprint(\"Starting screen recording...\")\ndroid.recorderStartScreenRecord(\n    path=\"/sdcard/screen_record.mp4\",\n    audio=1,\n    frameRate=30,\n    autoStart=True\n)\ntime.sleep(10)\ndroid.recorderStop()\n\n# Monitor sound volume\ndroid.recorderSoundVolumeDetect(interval=100)\ntime.sleep(3)\nvolume = droid.recorderSoundVolumeGetDb().result\nprint(f\"Current volume: {volume} dB\")\n
    "},{"location":"qsl4a/hardware/usbserial/","title":"USB Host Serial API","text":"

    Communicate with USB serial devices (requires USB OTG support and Android 3.1+).

    "},{"location":"qsl4a/hardware/usbserial/#usb-serial-methods","title":"USB Serial Methods)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialopen","title":"usbHostSerialOpen()","text":"

    Open a connection to a USB serial device.

    usbHostSerialOpen(device, baudRate=9600)\n

    Parameters: - device (str): USB device path or identifier - baudRate (int): Baud rate (default: 9600)

    Returns: True if opened successfully

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialclose","title":"usbHostSerialClose()","text":"

    Close the USB serial connection.

    usbHostSerialClose()\n
    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialread","title":"usbHostSerialRead()","text":"

    Read data from USB serial.

    usbHostSerialRead(bufferSize=1024)\n

    Parameters: - bufferSize (int): Maximum bytes to read (default: 1024)

    Returns: String read data

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwrite","title":"usbHostSerialWrite()","text":"

    Write data to USB serial.

    usbHostSerialWrite(data)\n

    Parameters: - data (str): String data to write

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialavailable","title":"usbHostSerialAvailable()","text":"

    Check if data is available to read.

    usbHostSerialAvailable()\n

    Returns: Number of bytes available

    "},{"location":"qsl4a/hardware/usbserial/#configuration-methods","title":"Configuration Methods)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetbaudrate","title":"usbHostSerialSetBaudRate()","text":"

    Set the baud rate.

    usbHostSerialSetBaudRate(baudRate)\n

    Parameters: - baudRate (int): Baud rate

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetdatabits","title":"usbHostSerialSetDataBits()","text":"

    Set data bits (5, 6, 7, or 8).

    usbHostSerialSetDataBits(dataBits)\n

    Parameters: - dataBits (int): Data bits (5-8)

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetstopbits","title":"usbHostSerialSetStopBits()","text":"

    Set stop bits (1, 1.5, or 2).

    usbHostSerialSetStopBits(stopBits)\n

    Parameters: - stopBits (float): Stop bits (1, 1.5, or 2)

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetparity","title":"usbHostSerialSetParity()","text":"

    Set parity (none, odd, even, mark, space).

    usbHostSerialSetParity(parity)\n

    Parameters: - parity (str): Parity mode ('none', 'odd', 'even', 'mark', 'space')

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetflowcontrol","title":"usbHostSerialSetFlowControl()","text":"

    Set flow control (none, hardware, software).

    usbHostSerialSetFlowControl(flowControl)\n

    Parameters: - flowControl (str): Flow control mode ('none', 'hardware', 'software')

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialreadhex","title":"usbHostSerialReadHex()","text":"

    Read data as hex string.

    usbHostSerialReadHex(bufferSize=1024)\n

    Parameters: - bufferSize (int): Maximum bytes to read

    Returns: Hex string

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwritehex","title":"usbHostSerialWriteHex()","text":"

    Write data from hex string.

    usbHostSerialWriteHex(hexString)\n

    Parameters: - hexString (str): Hex string to write

    "},{"location":"qsl4a/hardware/usbserial/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Open USB serial connection\nif droid.usbHostSerialOpen(\"/dev/bus/usb/001/001\", 115200).result:\n    print(\"USB serial opened\")\n\n    # Write data\n    droid.usbHostSerialWrite(\"AT\\r\")\n\n    # Read response\n    response = droid.usbHostSerialRead(1024).result\n    print(f\"Response: {response}\")\n\n    # Or use hex\n    droid.usbHostSerialWriteHex(\"41540D0A\")  # \"AT\\r\\n\"\n\n    # Close connection\n    droid.usbHostSerialClose()\n

    Note: USB serial requires: - Android 3.1+ (API 12) - USB OTG cable/adapter - USB host mode support on device - Compatible serial device

    "},{"location":"qsl4a/hardware/webcam/","title":"Webcam API","text":"

    Stream video from the device camera using MJPEG.

    "},{"location":"qsl4a/hardware/webcam/#mjpeg-stream-methods","title":"MJPEG Stream Methods","text":""},{"location":"qsl4a/hardware/webcam/#webcamstart","title":"webcamStart()","text":"

    Start an MJPEG stream from the webcam.

    webcamStart(resolutionLevel=0, jpegQuality=20, port=0)\n

    Parameters: - resolutionLevel (int): Resolution level (default: 0) - jpegQuality (int): JPEG quality 1-100 (default: 20) - port (int): Port number (default: 0 = auto)

    Returns: Tuple of (address, port) for the stream

    "},{"location":"qsl4a/hardware/webcam/#webcamadjustquality","title":"webcamAdjustQuality()","text":"

    Adjust the quality of an active webcam stream.

    webcamAdjustQuality(resolutionLevel=0, jpegQuality=20)\n

    Parameters: - resolutionLevel (int): Resolution level - jpegQuality (int): JPEG quality 1-100

    "},{"location":"qsl4a/hardware/webcam/#webcamstop","title":"webcamStop()","text":"

    Stop the webcam stream.

    webcamStop()\n
    "},{"location":"qsl4a/hardware/webcam/#camera-preview-methods","title":"Camera Preview Methods","text":""},{"location":"qsl4a/hardware/webcam/#camerastartpreview","title":"cameraStartPreview()","text":"

    Start camera preview mode with event generation.

    cameraStartPreview(resolutionLevel=0, jpegQuality=20, filepath=None)\n

    Parameters: - resolutionLevel (int): Resolution level (default: 0) - jpegQuality (int): JPEG quality (default: 20) - filepath (str, optional): File path to save preview frames

    Returns: True if successful

    Note: Generates 'preview' events with frame data.

    "},{"location":"qsl4a/hardware/webcam/#camerastoppreview","title":"cameraStopPreview()","text":"

    Stop the camera preview.

    cameraStopPreview()\n
    "},{"location":"qsl4a/hardware/webcam/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start webcam stream\nstream_info = droid.webcamStart(\n    resolutionLevel=0,\n    jpegQuality=30,\n    port=8080\n).result\nprint(f\"Stream available at {stream_info[0]}:{stream_info[1]}\")\n\n# Adjust quality while streaming\ntime.sleep(5)\ndroid.webcamAdjustQuality(resolutionLevel=1, jpegQuality=50)\n\n# Stop when done\ndroid.webcamStop()\n\n# Or use preview mode\nprint(\"Starting preview...\")\ndroid.cameraStartPreview()\n\n# Wait for preview events\nfor i in range(10):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'preview':\n        print(f\"Got preview frame: {event['data']}\")\n\ndroid.cameraStopPreview()\n
    "},{"location":"qsl4a/media/image/","title":"Image Processing API","text":"

    Compress and process images.

    "},{"location":"qsl4a/media/image/#image-compression","title":"Image Compression","text":""},{"location":"qsl4a/media/image/#imagecompress","title":"imageCompress()","text":"

    Compress image file.

    imageCompress(srcPath, destPath, targetByteSize=0, targetWidth=0, targetHeight=0)\n

    Parameters: - srcPath (str): Source image path - destPath (str): Output path - targetByteSize (int): Target file size in bytes (0 = no limit) - targetWidth (int): Target width (0 = original) - targetHeight (int): Target height (0 = original)

    Returns: Compressed image path

    "},{"location":"qsl4a/media/image/#screenshot","title":"Screenshot","text":""},{"location":"qsl4a/media/image/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

    Capture screen.

    imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

    Parameters: - path (str): Save path - delayMilliSec (int): Delay before capture

    Returns: Screenshot path

    "},{"location":"qsl4a/media/image/#video-playback","title":"Video Playback","text":""},{"location":"qsl4a/media/image/#videoplay","title":"videoPlay()","text":"

    Play video file in fullscreen mode.

    videoPlay(path, wait=True)\n

    Parameters: - path (str): Video file path - wait (bool): Wait for playback to complete (default: True)

    "},{"location":"qsl4a/media/image/#barcode-scanning","title":"Barcode Scanning","text":""},{"location":"qsl4a/media/image/#scanbarcodefromimage","title":"scanBarcodeFromImage()","text":"

    Scan barcode/QR code from image file.

    scanBarcodeFromImage(path, compressRatio=0, x=0, y=0, width=0, height=0)\n

    Parameters: - path (str): Image file path - compressRatio (int): Compression ratio (0 = no compression) - x, y, width, height (int): Region to scan (0 = full image)

    Returns: Scanned barcode content

    "},{"location":"qsl4a/media/image/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Take screenshot\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n\n# Compress image\ncompressed = droid.imageCompress(\n    \"/sdcard/large_photo.jpg\",\n    \"/sdcard/compressed.jpg\",\n    targetByteSize=102400,  # Target ~100KB\n    targetWidth=1920,\n    targetHeight=1080\n).result\nprint(f\"Saved: {compressed}\")\n\n# Play video\nvideo_path = \"/sdcard/movie.mp4\"\ndroid.videoPlay(video_path, wait=True)\n\n# Scan barcode from image\nresult = droid.scanBarcodeFromImage(\"/sdcard/qr_code.png\").result\nprint(f\"Barcode: {result}\")\n
    "},{"location":"qsl4a/media/mediaplayer/","title":"Media Player API","text":"

    Control audio and video playback.

    "},{"location":"qsl4a/media/mediaplayer/#playback-control","title":"Playback Control","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplay","title":"mediaPlay()","text":"

    Play media file.

    mediaPlay(url, tag=\"default\", play=True)\n

    Parameters: - url (str): Media file path or URL - tag (str): Player identifier - play (bool): Auto-start playback

    "},{"location":"qsl4a/media/mediaplayer/#mediaplaystart","title":"mediaPlayStart()","text":"

    Start playback.

    mediaPlayStart(tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#mediaplaypause","title":"mediaPlayPause()","text":"

    Pause playback.

    mediaPlayPause(tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#mediaplayclose","title":"mediaPlayClose()","text":"

    Close player.

    mediaPlayClose(tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#mediaplayseek","title":"mediaPlaySeek()","text":"

    Seek to position.

    mediaPlaySeek(msec, tag=\"default\")\n

    Parameters: - msec (int): Position in milliseconds

    "},{"location":"qsl4a/media/mediaplayer/#mediaplaysetlooping","title":"mediaPlaySetLooping()","text":"

    Set loop mode.

    mediaPlaySetLooping(enabled, tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#player-info","title":"Player Info","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplayinfo","title":"mediaPlayInfo()","text":"

    Get playback info.

    mediaPlayInfo(tag=\"default\")\n

    Returns: Dict with duration, position, etc.

    "},{"location":"qsl4a/media/mediaplayer/#mediaisplaying","title":"mediaIsPlaying()","text":"

    Check if playing.

    mediaIsPlaying(tag=\"default\")\n

    Returns: True/False

    "},{"location":"qsl4a/media/mediaplayer/#mediaplaylist","title":"mediaPlayList()","text":"

    List active players.

    mediaPlayList()\n
    "},{"location":"qsl4a/media/mediaplayer/#volume-control","title":"Volume Control","text":""},{"location":"qsl4a/media/mediaplayer/#getmediavolume","title":"getMediaVolume()","text":"

    Get media volume.

    getMediaVolume()\n

    Returns: Volume level (0-15)

    "},{"location":"qsl4a/media/mediaplayer/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

    Get max media volume.

    getMaxMediaVolume()\n
    "},{"location":"qsl4a/media/mediaplayer/#getringervolume","title":"getRingerVolume()","text":"

    Get ringer volume.

    getRingerVolume()\n
    "},{"location":"qsl4a/media/mediaplayer/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

    Get max ringer volume.

    getMaxRingerVolume()\n
    "},{"location":"qsl4a/media/mediaplayer/#video-playback","title":"Video Playback","text":""},{"location":"qsl4a/media/mediaplayer/#videoplay","title":"videoPlay()","text":"

    Play video fullscreen.

    videoPlay(path, wait=True)\n

    Parameters: - path (str): Video file path - wait (bool): Wait for playback to complete

    "},{"location":"qsl4a/media/mediaplayer/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Play audio\ndroid.mediaPlay(\"/sdcard/music.mp3\", tag=\"music\")\n\n# Check status\nif droid.mediaIsPlaying(\"music\").result:\n    info = droid.mediaPlayInfo(\"music\").result\n    print(f\"Playing: {info}\")\n\n# Seek to 30 seconds\ndroid.mediaPlaySeek(30000, \"music\")\n\n# Close\ndroid.mediaPlayClose(\"music\")\n\n# Play video\ndroid.videoPlay(\"/sdcard/movie.mp4\", wait=True)\n
    "},{"location":"qsl4a/special/cipher/","title":"Cipher API","text":"

    Encryption and decryption utilities for secure data storage.

    "},{"location":"qsl4a/special/cipher/#initialization","title":"Initialization","text":""},{"location":"qsl4a/special/cipher/#cipherinit","title":"cipherInit()","text":"

    Initialize the cipher with encryption key and algorithm.

    cipherInit(key, algorithm=\"AES/CBC/PKCS5Padding\", encodingFormat=\"\", initialVector=\"\")\n

    Parameters: - key (str or bytes): Encryption key - algorithm (str): Cipher algorithm (default: \"AES/CBC/PKCS5Padding\") - encodingFormat (str): Encoding format - initialVector (str or bytes): Initial vector for encryption

    Returns: Initialization result

    Note: Must be called before any encrypt/decrypt operations.

    "},{"location":"qsl4a/special/cipher/#encryption-methods","title":"Encryption Methods","text":""},{"location":"qsl4a/special/cipher/#encryptstring","title":"encryptString()","text":"

    Encrypt a string.

    encryptString(plainText)\n

    Parameters: - plainText (str): Text to encrypt

    Returns: Encrypted string

    "},{"location":"qsl4a/special/cipher/#encryptbytes","title":"encryptBytes()","text":"

    Encrypt bytes data.

    encryptBytes(data)\n

    Parameters: - data (bytes): Data to encrypt

    Returns: Encrypted bytes

    "},{"location":"qsl4a/special/cipher/#encryptstringtofile","title":"encryptStringToFile()","text":"

    Encrypt string to file.

    encryptStringToFile(plainText, filePath)\n

    Parameters: - plainText (str): Text to encrypt - filePath (str): Output file path

    "},{"location":"qsl4a/special/cipher/#encryptbytestofile","title":"encryptBytesToFile()","text":"

    Encrypt bytes to file.

    encryptBytesToFile(data, filePath)\n
    "},{"location":"qsl4a/special/cipher/#decryption-methods","title":"Decryption Methods","text":""},{"location":"qsl4a/special/cipher/#decryptstring","title":"decryptString()","text":"

    Decrypt to string.

    decryptString(cipherText)\n

    Parameters: - cipherText (str): Encrypted text

    Returns: Decrypted string

    "},{"location":"qsl4a/special/cipher/#decryptbytes","title":"decryptBytes()","text":"

    Decrypt to bytes.

    decryptBytes(data)\n

    Returns: Decrypted bytes

    "},{"location":"qsl4a/special/cipher/#decryptfiletostring","title":"decryptFileToString()","text":"

    Decrypt file to string.

    decryptFileToString(filePath)\n
    "},{"location":"qsl4a/special/cipher/#decryptfiletobytes","title":"decryptFileToBytes()","text":"

    Decrypt file to bytes.

    decryptFileToBytes(filePath)\n
    "},{"location":"qsl4a/special/cipher/#decryptfile","title":"decryptFile()","text":"

    Decrypt file to file.

    decryptFile(srcPath, destPath)\n
    "},{"location":"qsl4a/special/cipher/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Initialize cipher with your encryption key\ndroid.cipherInit(\"my_secret_key_1234\")\n\n# Encrypt string\nencrypted = droid.encryptString(\"Secret message!\").result\nprint(f\"Encrypted: {encrypted}\")\n\n# Decrypt string\ndecrypted = droid.decryptString(encrypted).result\nprint(f\"Decrypted: {decrypted}\")\n\n# Encrypt to file\ndroid.encryptStringToFile(\"My secret data\", \"/sdcard/secret.dat\")\n\n# Decrypt from file\ndata = droid.decryptFileToString(\"/sdcard/secret.dat\").result\nprint(data)\n\n# Initialize with custom algorithm and IV\ndroid.cipherInit(\n    key=\"my_key\",\n    algorithm=\"AES/CBC/PKCS5Padding\",\n    initialVector=\"0123456789abcdef\"\n)\n
    "},{"location":"qsl4a/special/pgptai/","title":"PGPT AI API","text":"

    Speech-to-text and AI services integration.

    "},{"location":"qsl4a/special/pgptai/#prerequisites","title":"Prerequisites","text":"
    pip install pgptAI\n
    "},{"location":"qsl4a/special/pgptai/#speech-recognition","title":"Speech Recognition","text":""},{"location":"qsl4a/special/pgptai/#speechtotext","title":"speechToText()","text":"

    Convert speech to text.

    speechToText(RecordSecond=10, AmrFile=None, Language=None)\n

    Parameters: - RecordSecond (int): Recording duration in seconds - AmrFile (str, optional): Existing audio file path - Language (str, optional): Language code ('en', 'zh')

    Returns: Transcribed text

    "},{"location":"qsl4a/special/pgptai/#text-to-speech","title":"Text to Speech","text":""},{"location":"qsl4a/special/pgptai/#texttospeech","title":"textToSpeech()","text":"

    Convert text to speech and optionally play it.

    textToSpeech(Text, AutoPlay=True, WavFile=None, VoiceName=None)\n

    Parameters: - Text (str): Text to convert to speech - AutoPlay (bool): Automatically play the generated audio (default: True) - WavFile (str, optional): Path to save the WAV file. If None, uses temporary file - VoiceName (str, optional): Voice name to use (e.g., 'en-US-JennyNeural', 'zh-CN-XiaoxiaoNeural')

    Returns: Dict with speech synthesis result including: - text: The input text - url: URL to download the audio file - WavFile: Path to the saved WAV file (if saved locally)

    "},{"location":"qsl4a/special/pgptai/#configuration","title":"Configuration","text":"

    The API uses configuration from /storage/emulated/0/Android/data/org.qpython.qpy/files/apigpt.conf:

    [speech]\nspeech_key = your_api_key\n

    Default voice settings: - English: en-US-JennyNeural - Chinese: zh-CN-XiaoxiaoNeural

    "},{"location":"qsl4a/special/pgptai/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Record and transcribe\nprint(\"Recording for 5 seconds...\")\ntext = droid.speechToText(RecordSecond=5, Language='en').result\nprint(f\"You said: {text}\")\n\n# Transcribe existing file\ntext = droid.speechToText(AmrFile=\"/sdcard/recording.amr\").result\nprint(f\"Transcription: {text}\")\n\n# Text to speech\ndroid.textToSpeech(\"Hello, this is a test message.\", AutoPlay=True, Language='en')\n\n# Text to speech with custom voice and save to file\nresult = droid.textToSpeech(\n    \"Welcome to QPython!\",\n    AutoPlay=False,\n    WavFile=\"/sdcard/welcome.wav\",\n    VoiceName=\"en-US-JennyNeural\"\n).result\nprint(f\"Audio saved to: {result.get('WavFile')}\")\n
    "},{"location":"qsl4a/special/pgptai/#class-usage","title":"Class Usage","text":"
    from androidhelper.pgptai import pgptai\nimport androidhelper\n\ndroid = androidhelper.Android()\nai = pgptai(droid)\n\n# Use speech recognition\ntext = ai.speechToText(RecordSecond=10)\n
    "},{"location":"qsl4a/storage/clipboard/","title":"Clipboard API","text":"

    Copy and paste text to system clipboard.

    "},{"location":"qsl4a/storage/clipboard/#methods","title":"Methods","text":""},{"location":"qsl4a/storage/clipboard/#setclipboard","title":"setClipboard()","text":"

    Copy text to clipboard.

    setClipboard(text)\n

    Parameters: - text (str): Text to copy

    Returns: True if success

    "},{"location":"qsl4a/storage/clipboard/#getclipboard","title":"getClipboard()","text":"

    Get text from clipboard.

    getClipboard()\n

    Returns: Clipboard text

    "},{"location":"qsl4a/storage/clipboard/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Copy to clipboard\ndroid.setClipboard(\"Hello from QPython!\")\n\n# Paste from clipboard\ntext = droid.getClipboard().result\nprint(f\"Clipboard: {text}\")\n
    "},{"location":"qsl4a/storage/documentfile/","title":"DocumentFile API","text":"

    File operations with SAF (Storage Access Framework) support for Android 4.4+.

    "},{"location":"qsl4a/storage/documentfile/#directory-operations","title":"Directory Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfilemkdir","title":"documentFileMkdir()","text":"

    Create directory.

    documentFileMkdir(Dir)\n

    Parameters: - Dir (str): Directory path

    Returns: True if success

    "},{"location":"qsl4a/storage/documentfile/#documentfilelistfiles","title":"documentFileListFiles()","text":"

    List files in directory.

    documentFileListFiles(Folder)\n

    Returns: List of files

    "},{"location":"qsl4a/storage/documentfile/#file-operations","title":"File Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfileexists","title":"documentFileExists()","text":"

    Check if file or directory exists.

    documentFileExists(path)\n

    Parameters: - path (str): File or directory path

    Returns: True if exists, False otherwise

    "},{"location":"qsl4a/storage/documentfile/#documentfileisfile","title":"documentFileIsFile()","text":"

    Check if path is a file.

    documentFileIsFile(path)\n

    Parameters: - path (str): Path to check

    Returns: True if file, False if not a file, None if not exists

    "},{"location":"qsl4a/storage/documentfile/#documentfileisdirectory","title":"documentFileIsDirectory()","text":"

    Check if path is a directory.

    documentFileIsDirectory(path)\n

    Parameters: - path (str): Path to check

    Returns: True if directory, False if not a directory, None if not exists

    "},{"location":"qsl4a/storage/documentfile/#documentfiledelete","title":"documentFileDelete()","text":"

    Delete file or directory.

    documentFileDelete(FileOrTree)\n

    Returns: True if success

    "},{"location":"qsl4a/storage/documentfile/#documentfilerenameto","title":"documentFileRenameTo()","text":"

    Rename or move file.

    documentFileRenameTo(Src, Dest)\n

    Returns: True if success

    "},{"location":"qsl4a/storage/documentfile/#documentfilecopy","title":"documentFileCopy()","text":"

    Copy file.

    documentFileCopy(SrcFileOrTree, DestFileOrTree)\n
    "},{"location":"qsl4a/storage/documentfile/#stream-operations","title":"Stream Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfileinputstream","title":"documentFileInputStream()","text":"

    Read file content.

    documentFileInputStream(srcFile, EncodingFormat=\"\", skip=None, length=None)\n

    Parameters: - srcFile (str): Source file - EncodingFormat (str): \"UTF-8\", \"GBK\", \"Base64\", or \"\" for bytes - skip (int): Skip bytes from start - length (int): Read length

    Returns: File content

    "},{"location":"qsl4a/storage/documentfile/#documentfileoutputstream","title":"documentFileOutputStream()","text":"

    Write file content.

    documentFileOutputStream(destFile, src, EncodingFormat=\"\", append=None)\n

    Parameters: - destFile (str): Destination file - src: Data to write - EncodingFormat (str): Encoding format - append (bool): Append mode

    "},{"location":"qsl4a/storage/documentfile/#file-information","title":"File Information","text":""},{"location":"qsl4a/storage/documentfile/#documentfilelength","title":"documentFileLength()","text":"

    Get file size in bytes.

    documentFileLength(path)\n

    Parameters: - path (str): File path

    Returns: File size in bytes (0 if not exists)

    "},{"location":"qsl4a/storage/documentfile/#documentfilelastmodified","title":"documentFileLastModified()","text":"

    Get last modified time.

    documentFileLastModified(path)\n

    Parameters: - path (str): File path

    Returns: Timestamp (0 if not exists)

    "},{"location":"qsl4a/storage/documentfile/#documentfilegetstat","title":"documentFileGetStat()","text":"

    Get comprehensive file statistics.

    documentFileGetStat(path)\n

    Parameters: - path (str): File path

    Returns: Dict with length, last modified, and read/write permissions, or None if not exists

    "},{"location":"qsl4a/storage/documentfile/#uri-operations","title":"URI Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfilegeturi","title":"documentFileGetUri()","text":"

    Get URI from path.

    documentFileGetUri(path, isDirectory=None)\n
    "},{"location":"qsl4a/storage/documentfile/#documentfileshowopen","title":"documentFileShowOpen()","text":"

    Show file picker.

    documentFileShowOpen()\n

    Returns: Selected file URI

    "},{"location":"qsl4a/storage/documentfile/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Create directory\ndroid.documentFileMkdir(\"/sdcard/MyFolder\")\n\n# List files\nfiles = droid.documentFileListFiles(\"/sdcard\").result\nfor f in files:\n    print(f)\n\n# Read file\ncontent = droid.documentFileInputStream(\n    \"/sdcard/test.txt\",\n    EncodingFormat=\"UTF-8\"\n).result\nprint(content)\n\n# Write file\ndroid.documentFileOutputStream(\n    \"/sdcard/output.txt\",\n    \"Hello World\",\n    EncodingFormat=\"UTF-8\"\n)\n
    "},{"location":"qsl4a/storage/preferences/","title":"Preferences API","text":"

    Store and retrieve data using Android SharedPreferences.

    "},{"location":"qsl4a/storage/preferences/#preference-methods","title":"Preference Methods","text":""},{"location":"qsl4a/storage/preferences/#prefgetvalue","title":"prefGetValue()","text":"

    Read a value from shared preferences.

    prefGetValue(key, filename=None)\n

    Parameters: - key (str): Preference key - filename (str, optional): Preference file name

    Returns: The stored value (any type)

    "},{"location":"qsl4a/storage/preferences/#prefputvalue","title":"prefPutValue()","text":"

    Write a value to shared preferences.

    prefPutValue(key, value, filename=None)\n

    Parameters: - key (str): Preference key - value (object): Value to store - filename (str, optional): Preference file name

    "},{"location":"qsl4a/storage/preferences/#prefgetall","title":"prefGetAll()","text":"

    Get all preference values.

    prefGetAll(filename=None)\n

    Parameters: - filename (str, optional): Preference file name

    Returns: Map of all preferences

    "},{"location":"qsl4a/storage/preferences/#prefremovevalue","title":"prefRemoveValue()","text":"

    Remove a value from shared preferences.

    prefRemoveValue(key, filename=None)\n

    Parameters: - key (str): Preference key to remove - filename (str, optional): Preference file name

    "},{"location":"qsl4a/storage/preferences/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Store values\ndroid.prefPutValue(\"username\", \"alice\")\ndroid.prefPutValue(\"score\", 100)\ndroid.prefPutValue(\"enabled\", True)\n\n# Read a specific value\nusername = droid.prefGetValue(\"username\").result\nprint(f\"Username: {username}\")\n\n# Get all preferences\nall_prefs = droid.prefGetAll().result\nprint(f\"All prefs: {all_prefs}\")\n\n# Remove a value\ndroid.prefRemoveValue(\"score\")\n\n# Use custom filename\ndroid.prefPutValue(\"token\", \"abc123\", filename=\"auth.prefs\")\ntoken = droid.prefGetValue(\"token\", filename=\"auth.prefs\").result\n
    "},{"location":"qsl4a/system/activityresult/","title":"Activity Result API","text":"

    Set activity results for scripts launched via startActivityForResult.

    "},{"location":"qsl4a/system/activityresult/#result-methods","title":"Result Methods","text":""},{"location":"qsl4a/system/activityresult/#setresultboolean","title":"setResultBoolean()","text":"

    Set a boolean result.

    setResultBoolean(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (bool): Boolean result value

    "},{"location":"qsl4a/system/activityresult/#setresultbyte","title":"setResultByte()","text":"

    Set a byte result.

    setResultByte(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (int): Byte result value

    "},{"location":"qsl4a/system/activityresult/#setresultshort","title":"setResultShort()","text":"

    Set a short result.

    setResultShort(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (int): Short result value

    "},{"location":"qsl4a/system/activityresult/#setresultchar","title":"setResultChar()","text":"

    Set a character result.

    setResultChar(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (str): Character result value

    "},{"location":"qsl4a/system/activityresult/#setresultinteger","title":"setResultInteger()","text":"

    Set an integer result.

    setResultInteger(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (int): Integer result value

    "},{"location":"qsl4a/system/activityresult/#setresultlong","title":"setResultLong()","text":"

    Set a long result.

    setResultLong(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (int): Long result value

    "},{"location":"qsl4a/system/activityresult/#setresultfloat","title":"setResultFloat()","text":"

    Set a float result.

    setResultFloat(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (float): Float result value

    "},{"location":"qsl4a/system/activityresult/#setresultdouble","title":"setResultDouble()","text":"

    Set a double result.

    setResultDouble(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (float): Double result value

    "},{"location":"qsl4a/system/activityresult/#setresultstring","title":"setResultString()","text":"

    Set a string result.

    setResultString(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (str): String result value

    "},{"location":"qsl4a/system/activityresult/#setresultbooleanarray","title":"setResultBooleanArray()","text":"

    Set a boolean array result.

    setResultBooleanArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Boolean array

    "},{"location":"qsl4a/system/activityresult/#setresultbytearray","title":"setResultByteArray()","text":"

    Set a byte array result.

    setResultByteArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Byte array

    "},{"location":"qsl4a/system/activityresult/#setresultshortarray","title":"setResultShortArray()","text":"

    Set a short array result.

    setResultShortArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Short array

    "},{"location":"qsl4a/system/activityresult/#setresultchararray","title":"setResultCharArray()","text":"

    Set a character array result.

    setResultCharArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Char array

    "},{"location":"qsl4a/system/activityresult/#setresultintegerarray","title":"setResultIntegerArray()","text":"

    Set an integer array result.

    setResultIntegerArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Integer array

    "},{"location":"qsl4a/system/activityresult/#setresultlongarray","title":"setResultLongArray()","text":"

    Set a long array result.

    setResultLongArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Long array

    "},{"location":"qsl4a/system/activityresult/#setresultfloatarray","title":"setResultFloatArray()","text":"

    Set a float array result.

    setResultFloatArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Float array

    "},{"location":"qsl4a/system/activityresult/#setresultdoublearray","title":"setResultDoubleArray()","text":"

    Set a double array result.

    setResultDoubleArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Double array

    "},{"location":"qsl4a/system/activityresult/#setresultstringarray","title":"setResultStringArray()","text":"

    Set a string array result.

    setResultStringArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): String array

    "},{"location":"qsl4a/system/activityresult/#setresultserializable","title":"setResultSerializable()","text":"

    Set a serializable result.

    setResultSerializable(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue: Serializable result value

    "},{"location":"qsl4a/system/activityresult/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# After performing an activity, set the result\n# Example: Return success with data\ndroid.setResultInteger(0, 200)  # RESULT_OK\ndroid.setResultString(0, \"Operation completed successfully\")\n\n# Return an array result\ndroid.setResultIntegerArray(0, [1, 2, 3, 4, 5])\n
    "},{"location":"qsl4a/system/application/","title":"Application Management","text":"

    Manage applications, launch apps, and query system information.

    "},{"location":"qsl4a/system/application/#application-information","title":"Application Information","text":""},{"location":"qsl4a/system/application/#getapplicationinfo","title":"getApplicationInfo()","text":"

    Get information about an app.

    getApplicationInfo(packageName=None)\n

    Parameters: - packageName (str): Package name (None = current app)

    Returns: App info dict

    "},{"location":"qsl4a/system/application/#getinstalledpackages","title":"getInstalledPackages()","text":"

    Get list of installed packages.

    getInstalledPackages(flag=4)\n

    Parameters: - flag (int): Package flag filter (default: 4)

    Returns: List of installed packages

    "},{"location":"qsl4a/system/application/#getrunningpackages","title":"getRunningPackages()","text":"

    List running packages.

    getRunningPackages()\n

    Returns: List of package names

    "},{"location":"qsl4a/system/application/#getlaunchablepackages","title":"getLaunchablePackages()","text":"

    Get list of launchable packages.

    getLaunchablePackages(needClassName=False)\n

    Parameters: - needClassName (bool): Include main activity class name (default: False)

    Returns: List of launchable package names or dict with class names

    "},{"location":"qsl4a/system/application/#application-control","title":"Application Control","text":""},{"location":"qsl4a/system/application/#launch","title":"launch()","text":"

    Launch an application.

    launch(classname=None, packagename=None, wait=True)\n

    Parameters: - classname (str): Main activity class name - packagename (str): Package name - wait (bool): Wait for launch to complete (default: True)

    Returns: Launch result

    "},{"location":"qsl4a/system/application/#forcestoppackage","title":"forceStopPackage()","text":"

    Force stop an application.

    forceStopPackage(packageName)\n

    Parameters: - packageName (str): Package name to stop

    "},{"location":"qsl4a/system/application/#version-information","title":"Version Information","text":""},{"location":"qsl4a/system/application/#getpackageversion","title":"getPackageVersion()","text":"

    Get app version name.

    getPackageVersion(packageName)\n

    Returns: Version string (e.g., \"3.2.1\")

    "},{"location":"qsl4a/system/application/#getpackageversioncode","title":"getPackageVersionCode()","text":"

    Get app version code.

    getPackageVersionCode(packageName)\n

    Returns: Version code integer

    "},{"location":"qsl4a/system/application/#getconstants","title":"getConstants()","text":"

    Get class constants.

    getConstants(classname)\n

    Parameters: - classname (str): Full class name

    Returns: Dict of constant names and values

    "},{"location":"qsl4a/system/application/#system-features","title":"System Features","text":""},{"location":"qsl4a/system/application/#backgroundprotect","title":"backgroundProtect()","text":"

    Enable or disable background protection for the app.

    backgroundProtect(enabled=True)\n

    Parameters: - enabled (bool): True to enable protection, False to disable

    "},{"location":"qsl4a/system/application/#createscriptshortcut","title":"createScriptShortCut()","text":"

    Create a home screen shortcut for a script.

    createScriptShortCut(scriptPath, label=None, iconPath=None, scriptArg=None)\n

    Parameters: - scriptPath (str): Path to the Python script - label (str, optional): Shortcut label - iconPath (str, optional): Path to icon image - scriptArg (str, optional): Argument to pass to script

    "},{"location":"qsl4a/system/application/#device-information","title":"Device Information","text":""},{"location":"qsl4a/system/application/#getandroidid","title":"getAndroidID()","text":"

    Get Android device ID.

    getAndroidID()\n

    Returns: Unique Android device ID string

    "},{"location":"qsl4a/system/application/#getsysinfo","title":"getSysInfo()","text":"

    Get system information.

    getSysInfo()\n

    Returns: Dict with system details

    "},{"location":"qsl4a/system/application/#getlocale","title":"getLocale()","text":"

    Get device locale.

    getLocale()\n

    Returns: Locale string (e.g., \"en_US\")

    "},{"location":"qsl4a/system/application/#getharmonyosinformation","title":"getHarmonyOsInformation()","text":"

    Get HarmonyOS information if running on HarmonyOS.

    getHarmonyOsInformation()\n

    Returns: HarmonyOS version info or None

    "},{"location":"qsl4a/system/application/#isexternalstoragemanager","title":"isExternalStorageManager()","text":"

    Check if app has external storage manager permission.

    isExternalStorageManager()\n

    Returns: True if has permission

    "},{"location":"qsl4a/system/application/#memory-and-display","title":"Memory and Display","text":""},{"location":"qsl4a/system/application/#getmemoryinfo","title":"getMemoryInfo()","text":"

    Get memory information.

    getMemoryInfo()\n

    Returns: Dict with memory stats

    "},{"location":"qsl4a/system/application/#getscreeninfo","title":"getScreenInfo()","text":"

    Get screen information.

    getScreenInfo()\n

    Returns: Dict with width, height, density

    "},{"location":"qsl4a/system/application/#permissions","title":"Permissions","text":""},{"location":"qsl4a/system/application/#checkpermissions","title":"checkPermissions()","text":"

    Check current app permissions.

    checkPermissions()\n

    Returns: Dict of permissions and their status

    "},{"location":"qsl4a/system/application/#requestpermissions","title":"requestPermissions()","text":"

    Request permissions from the user.

    requestPermissions(permissions=None)\n

    Parameters: - permissions (list, optional): List of permissions to request. If None, requests all needed permissions.

    Returns: Result of permission request

    "},{"location":"qsl4a/system/application/#system-actions","title":"System Actions","text":""},{"location":"qsl4a/system/application/#showscreenlock","title":"showScreenLock()","text":"

    Show screen lock (PIN/pattern/password entry).

    showScreenLock()\n
    "},{"location":"qsl4a/system/application/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get system info\ninfo = droid.getSysInfo().result\nprint(f\"System: {info}\")\n\n# Get app version\nversion = droid.getPackageVersion(\"org.qpython.qpy\").result\nprint(f\"QPython version: {version}\")\n\n# List installed apps\napps = droid.getInstalledPackages().result\nprint(f\"Installed apps: {len(apps)}\")\n\n# Launch an app\ndroid.launch(packagename=\"com.android.settings\")\n\n# Check permissions\nperms = droid.checkPermissions().result\nprint(f\"Permissions: {perms}\")\n\n# Request storage permission\ndroid.requestPermissions([\"android.permission.READ_EXTERNAL_STORAGE\"])\n\n# Create shortcut\ndroid.createScriptShortCut(\n    \"/sdcard/my_script.py\",\n    label=\"My Script\",\n    iconPath=\"/sdcard/icon.png\"\n)\n
    "},{"location":"qsl4a/system/battery/","title":"Battery API","text":"

    Monitor device battery status and health.

    "},{"location":"qsl4a/system/battery/#methods","title":"Methods","text":""},{"location":"qsl4a/system/battery/#readbatterydata","title":"readBatteryData()","text":"

    Get complete battery information.

    readBatteryData()\n

    Returns: Dict with battery data

    "},{"location":"qsl4a/system/battery/#batterystartmonitoring","title":"batteryStartMonitoring()","text":"

    Start battery monitoring.

    batteryStartMonitoring()\n
    "},{"location":"qsl4a/system/battery/#batterystopmonitoring","title":"batteryStopMonitoring()","text":"

    Stop battery monitoring.

    batteryStopMonitoring()\n
    "},{"location":"qsl4a/system/battery/#batterygetlevel","title":"batteryGetLevel()","text":"

    Get battery percentage.

    batteryGetLevel()\n

    Returns: Int (0-100)

    "},{"location":"qsl4a/system/battery/#batterygetstatus","title":"batteryGetStatus()","text":"

    Get charging status.

    batteryGetStatus()\n

    Returns: - 1: Unknown - 2: Charging - 3: Discharging - 4: Not charging - 5: Full

    "},{"location":"qsl4a/system/battery/#batterygetplugtype","title":"batteryGetPlugType()","text":"

    Get power source.

    batteryGetPlugType()\n

    Returns: - -1: Unknown - 0: Unplugged - 1: AC charger - 2: USB port

    "},{"location":"qsl4a/system/battery/#batterygethealth","title":"batteryGetHealth()","text":"

    Get battery health.

    batteryGetHealth()\n

    Returns: - 1: Unknown - 2: Good - 3: Overheat - 4: Dead - 5: Over voltage - 6: Unspecified failure

    "},{"location":"qsl4a/system/battery/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get battery level\nlevel = droid.batteryGetLevel().result\nprint(f\"Battery: {level}%\")\n
    "},{"location":"qsl4a/system/qpyinterface/","title":"QPython Interface API","text":"

    Execute QPython scripts and manage shared variables from other apps.

    "},{"location":"qsl4a/system/qpyinterface/#script-execution-methods","title":"Script Execution Methods","text":""},{"location":"qsl4a/system/qpyinterface/#executeqpy","title":"executeQPy()","text":"

    Execute a QPython script.

    executeQPy(path=\"\", arg=None)\n

    Parameters: - path (str): Path to the script file - arg (str, optional): Command line arguments

    Returns: True if started successfully

    "},{"location":"qsl4a/system/qpyinterface/#executeqpyassrv","title":"executeQPyAsSrv()","text":"

    Execute a QPython script as a service.

    executeQPyAsSrv(path=None)\n

    Parameters: - path (str, optional): Path to the script file

    Returns: True if started successfully

    "},{"location":"qsl4a/system/qpyinterface/#executeqpycode","title":"executeQPyCode()","text":"

    Execute Python code directly.

    executeQPyCode(code=None)\n

    Parameters: - code (str, optional): Python code to execute

    Returns: True if started successfully

    "},{"location":"qsl4a/system/qpyinterface/#executeqpycodeassrv","title":"executeQPyCodeAsSrv()","text":"

    Execute Python code as a service.

    executeQPyCodeAsSrv(code=None)\n

    Parameters: - code (str, optional): Python code to execute

    Returns: True if started successfully

    "},{"location":"qsl4a/system/qpyinterface/#shared-variables","title":"Shared Variables","text":"

    Shared variables allow communication between QPython and other apps.

    "},{"location":"qsl4a/system/qpyinterface/#sharedvariableset","title":"sharedVariableSet()","text":"

    Set a Java shared variable.

    sharedVariableSet(key, value)\n

    Parameters: - key (str): Variable name - value (str): Variable value

    Returns: The stored value

    "},{"location":"qsl4a/system/qpyinterface/#sharedvariableget","title":"sharedVariableGet()","text":"

    Get a Java shared variable.

    sharedVariableGet(key)\n

    Parameters: - key (str): Variable name

    Returns: The stored value

    "},{"location":"qsl4a/system/qpyinterface/#sharedvariableremove","title":"sharedVariableRemove()","text":"

    Remove a Java shared variable.

    sharedVariableRemove(key)\n

    Parameters: - key (str): Variable name to remove

    Returns: The removed value

    "},{"location":"qsl4a/system/qpyinterface/#getlastlog","title":"getLastLog()","text":"

    Get the last log output from QPython.

    getLastLog()\n

    Returns: String log content

    "},{"location":"qsl4a/system/qpyinterface/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Execute a script\ndroid.executeQPy(\"/sdcard/my_script.py\", arg=\"test\")\n\n# Execute code directly\ncode = \"print('Hello from QPython!')\"\ndroid.executeQPyCode(code)\n\n# Use shared variables\ndroid.sharedVariableSet(\"username\", \"alice\")\nusername = droid.sharedVariableGet(\"username\").result\nprint(f\"Username: {username}\")\n\n# Remove variable\ndroid.sharedVariableRemove(\"username\")\n\n# Get recent log\nlog = droid.getLastLog().result\nprint(f\"Log: {log}\")\n
    "},{"location":"qsl4a/system/sensors/","title":"Sensor API","text":"

    Access device sensors including accelerometer, gyroscope, magnetometer, and more.

    "},{"location":"qsl4a/system/sensors/#methods","title":"Methods","text":""},{"location":"qsl4a/system/sensors/#startsensingtimed","title":"startSensingTimed()","text":"

    Start sensor monitoring with time intervals.

    startSensingTimed(sensorNumber, delayTime)\n

    Parameters: - sensorNumber (int): Sensor ID (1-3 typically) - delayTime (int): Delay between readings in milliseconds

    "},{"location":"qsl4a/system/sensors/#startsensingthreshold","title":"startSensingThreshold()","text":"

    Start sensor monitoring with threshold trigger.

    startSensingThreshold(sensorNumber, threshold, axis)\n

    Parameters: - sensorNumber (int): Sensor ID - threshold (float): Trigger threshold - axis (int): Axis to monitor (0=X, 1=Y, 2=Z)

    "},{"location":"qsl4a/system/sensors/#stopsensing","title":"stopSensing()","text":"

    Stop all sensor monitoring.

    stopSensing()\n
    "},{"location":"qsl4a/system/sensors/#readsensors","title":"readSensors()","text":"

    Read current sensor data.

    readSensors()\n

    Returns: Sensor data dict

    "},{"location":"qsl4a/system/sensors/#sensorsreadaccelerometer","title":"sensorsReadAccelerometer()","text":"

    Read accelerometer values.

    sensorsReadAccelerometer()\n

    Returns: List [X, Y, Z] in m/s\u00b2

    "},{"location":"qsl4a/system/sensors/#sensorsreadgyroscope","title":"sensorsReadGyroscope()","text":"

    Read gyroscope values.

    sensorsReadGyroscope()\n

    Returns: List [X, Y, Z] in rad/s

    "},{"location":"qsl4a/system/sensors/#sensorsreadmagnetometer","title":"sensorsReadMagnetometer()","text":"

    Read magnetic field values.

    sensorsReadMagnetometer()\n

    Returns: List [X, Y, Z] in \u03bcT

    "},{"location":"qsl4a/system/sensors/#sensorsreadorientation","title":"sensorsReadOrientation()","text":"

    Read device orientation.

    sensorsReadOrientation()\n

    Returns: List [azimuth, pitch, roll] in degrees

    "},{"location":"qsl4a/system/sensors/#sensorsgetlight","title":"sensorsGetLight()","text":"

    Read light sensor value.

    sensorsGetLight()\n

    Returns: Light level in lux

    "},{"location":"qsl4a/system/sensors/#sensorsgetstepcounter","title":"sensorsGetStepCounter()","text":"

    Read step counter.

    sensorsGetStepCounter()\n

    Returns: Number of steps

    "},{"location":"qsl4a/system/sensors/#sensorsgetaccuracy","title":"sensorsGetAccuracy()","text":"

    Get the current sensor accuracy.

    sensorsGetAccuracy()\n

    Returns: Accuracy value (0-3: UNRELIABLE, ACCURACY_LOW, ACCURACY_MEDIUM, ACCURACY_HIGH)

    "},{"location":"qsl4a/system/sensors/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start sensing\ndroid.startSensingTimed(1, 250)\n\n# Read sensors 10 times\nfor i in range(10):\n    accel = droid.sensorsReadAccelerometer().result\n    print(f\"Accel: X={accel[0]:.2f}, Y={accel[1]:.2f}, Z={accel[2]:.2f}\")\n    time.sleep(0.5)\n\ndroid.stopSensing()\n
    "},{"location":"qsl4a/system/settings/","title":"Settings API","text":"

    Control system settings including screen, sound, and network settings.

    "},{"location":"qsl4a/system/settings/#screen-settings","title":"Screen Settings","text":""},{"location":"qsl4a/system/settings/#setscreentimeout","title":"setScreenTimeout()","text":"

    Set the screen timeout value.

    setScreenTimeout(value)\n

    Parameters: - value (int): Screen timeout in seconds

    Returns: Previous timeout value

    "},{"location":"qsl4a/system/settings/#getscreentimeout","title":"getScreenTimeout()","text":"

    Get the current screen timeout.

    getScreenTimeout()\n

    Returns: Current screen timeout in seconds

    "},{"location":"qsl4a/system/settings/#getscreenbrightness","title":"getScreenBrightness()","text":"

    Get the screen brightness value.

    getScreenBrightness()\n

    Returns: Brightness value (0-255)

    "},{"location":"qsl4a/system/settings/#setscreenbrightness","title":"setScreenBrightness()","text":"

    Set the screen brightness.

    setScreenBrightness(value=None)\n

    Parameters: - value (int, optional): Brightness value (0-255), or None for auto

    Returns: Previous brightness value

    "},{"location":"qsl4a/system/settings/#checkscreenon","title":"checkScreenOn()","text":"

    Check if the screen is on.

    checkScreenOn()\n

    Returns: True if screen is on, False otherwise

    "},{"location":"qsl4a/system/settings/#airplane-mode","title":"Airplane Mode","text":""},{"location":"qsl4a/system/settings/#checkairplanemode","title":"checkAirplaneMode()","text":"

    Check if airplane mode is enabled.

    checkAirplaneMode()\n

    Returns: True if airplane mode is on

    "},{"location":"qsl4a/system/settings/#ringer-settings","title":"Ringer Settings","text":""},{"location":"qsl4a/system/settings/#checkringersilentmode","title":"checkRingerSilentMode()","text":"

    Check if ringer is in silent mode.

    checkRingerSilentMode()\n

    Returns: True if silent mode is on

    "},{"location":"qsl4a/system/settings/#toggleringersilentmode","title":"toggleRingerSilentMode()","text":"

    Toggle ringer silent mode.

    toggleRingerSilentMode(enabled=None)\n

    Parameters: - enabled (bool, optional): True to enable, False to disable, None to toggle

    Returns: New state

    "},{"location":"qsl4a/system/settings/#togglevibratemode","title":"toggleVibrateMode()","text":"

    Toggle vibrate mode.

    toggleVibrateMode(enabled=None, ringer=None)\n

    Parameters: - enabled (bool, optional): Toggle vibrate on/off - ringer (bool, optional): Apply to ringer mode

    Returns: New state

    "},{"location":"qsl4a/system/settings/#getvibratemode","title":"getVibrateMode()","text":"

    Get the vibrate mode setting.

    getVibrateMode(ringer=None)\n

    Parameters: - ringer (bool, optional): Check ringer vibrate mode

    Returns: True if vibrate is enabled

    "},{"location":"qsl4a/system/settings/#volume-settings","title":"Volume Settings","text":""},{"location":"qsl4a/system/settings/#getringervolume","title":"getRingerVolume()","text":"

    Get the current ringer volume.

    getRingerVolume()\n

    Returns: Ringer volume level (0-7 typically)

    "},{"location":"qsl4a/system/settings/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

    Get the maximum ringer volume.

    getMaxRingerVolume()\n

    Returns: Maximum ringer volume

    "},{"location":"qsl4a/system/settings/#setringervolume","title":"setRingerVolume()","text":"

    Set the ringer volume.

    setRingerVolume(volume)\n

    Parameters: - volume (int): Volume level

    "},{"location":"qsl4a/system/settings/#getmediavolume","title":"getMediaVolume()","text":"

    Get the current media volume.

    getMediaVolume()\n

    Returns: Media volume level (0-15 typically)

    "},{"location":"qsl4a/system/settings/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

    Get the maximum media volume.

    getMaxMediaVolume()\n

    Returns: Maximum media volume

    "},{"location":"qsl4a/system/settings/#setmediavolume","title":"setMediaVolume()","text":"

    Set the media volume.

    setMediaVolume(volume)\n

    Parameters: - volume (int): Volume level

    "},{"location":"qsl4a/system/settings/#system-info","title":"System Info","text":""},{"location":"qsl4a/system/settings/#elapsedrealtimenanos","title":"elapsedRealtimeNanos()","text":"

    Get nanoseconds since system startup.

    elapsedRealtimeNanos()\n

    Returns: Nanoseconds (can be used for timing)

    "},{"location":"qsl4a/system/settings/#gettrafficstats","title":"getTrafficStats()","text":"

    Get network traffic statistics.

    getTrafficStats(flags=7)\n

    Parameters: - flags (int): Which stats to retrieve (default: 7 = all)

    Returns: Dict with transmit/receive bytes

    "},{"location":"qsl4a/system/settings/#getapptxbytes","title":"getAppTxBytes()","text":"

    Get transmit bytes for QPython app.

    getAppTxBytes(packageName)\n

    Parameters: - packageName (str): Package name

    Returns: Dict with tx/rx bytes

    "},{"location":"qsl4a/system/settings/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Screen settings\ncurrent_timeout = droid.getScreenTimeout().result\nprint(f\"Current timeout: {current_timeout}s\")\ndroid.setScreenTimeout(30)\n\n# Check screen\nif droid.checkScreenOn().result:\n    print(\"Screen is on\")\n\n# Volume control\nmedia_vol = droid.getMediaVolume().result\nprint(f\"Media volume: {media_vol}\")\ndroid.setMediaVolume(10)\n\n# Check airplane mode\nif droid.checkAirplaneMode().result:\n    print(\"Airplane mode is on\")\n
    "},{"location":"qsl4a/system/sysinfo/","title":"System Information","text":"

    Retrieve device and system information.

    "},{"location":"qsl4a/system/sysinfo/#device-information","title":"Device Information","text":""},{"location":"qsl4a/system/sysinfo/#getandroidid","title":"getAndroidID()","text":"

    Get the Android device ID.

    getAndroidID()\n

    Returns: String device ID

    "},{"location":"qsl4a/system/sysinfo/#getsysinfo","title":"getSysInfo()","text":"

    Get comprehensive system information.

    getSysInfo()\n

    Returns: Dict with system details

    "},{"location":"qsl4a/system/sysinfo/#getlocale","title":"getLocale()","text":"

    Get device locale settings.

    getLocale()\n

    Returns: Locale string (e.g., \"en_US\")

    "},{"location":"qsl4a/system/sysinfo/#memory","title":"Memory","text":""},{"location":"qsl4a/system/sysinfo/#getmemoryinfo","title":"getMemoryInfo()","text":"

    Get RAM information.

    getMemoryInfo()\n

    Returns: Dict with memory stats

    "},{"location":"qsl4a/system/sysinfo/#display","title":"Display","text":""},{"location":"qsl4a/system/sysinfo/#getscreeninfo","title":"getScreenInfo()","text":"

    Get display information.

    getScreenInfo()\n

    Returns: Dict with width, height, density

    "},{"location":"qsl4a/system/sysinfo/#identifiers","title":"Identifiers","text":""},{"location":"qsl4a/system/sysinfo/#getimei","title":"getImei()","text":"

    Get device IMEI.

    getImei(slotIndex=None)\n
    "},{"location":"qsl4a/system/sysinfo/#getmeid","title":"getMeid()","text":"

    Get device MEID.

    getMeid(slotIndex=None)\n
    "},{"location":"qsl4a/system/sysinfo/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Device ID\nandroid_id = droid.getAndroidID().result\nprint(f\"Android ID: {android_id}\")\n\n# Screen info\nscreen = droid.getScreenInfo().result\nprint(f\"Screen: {screen['width']}x{screen['height']}\")\n\n# Memory\nmemory = droid.getMemoryInfo().result\nprint(f\"Memory: {memory}\")\n
    "},{"location":"qsl4a/system/wakelock/","title":"WakeLock API","text":"

    Control device wake locks to keep the CPU or screen on.

    "},{"location":"qsl4a/system/wakelock/#wake-lock-types","title":"Wake Lock Types","text":"

    QSL4A provides different wake lock types:

    Type Description Full CPU on, screen bright, keyboard bright Partial CPU on only Bright CPU on, screen bright Dim CPU on, screen dim"},{"location":"qsl4a/system/wakelock/#wake-lock-methods","title":"Wake Lock Methods","text":""},{"location":"qsl4a/system/wakelock/#wakelockacquirefull","title":"wakeLockAcquireFull()","text":"

    Acquire a full wake lock (CPU on, screen bright, keyboard bright).

    wakeLockAcquireFull()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockacquirepartial","title":"wakeLockAcquirePartial()","text":"

    Acquire a partial wake lock (CPU on only).

    wakeLockAcquirePartial()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockacquirebright","title":"wakeLockAcquireBright()","text":"

    Acquire a bright wake lock (CPU on, screen bright).

    wakeLockAcquireBright()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockacquiredim","title":"wakeLockAcquireDim()","text":"

    Acquire a dim wake lock (CPU on, screen dim).

    wakeLockAcquireDim()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockrelease","title":"wakeLockRelease()","text":"

    Release the wake lock.

    wakeLockRelease()\n
    "},{"location":"qsl4a/system/wakelock/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Acquire full wake lock\ndroid.wakeLockAcquireFull()\n\n# Do important work while keeping screen on\nprint(\"Screen will stay on\")\ntime.sleep(10)\n\n# Release when done\ndroid.wakeLockRelease()\n\n# Or use partial lock for background tasks\ndroid.wakeLockAcquirePartial()\n# CPU stays on even with screen off\ntime.sleep(30)\ndroid.wakeLockRelease()\n

    Note: Remember to release wake locks when no longer needed to conserve battery.

    "},{"location":"qsl4a/ui/accessibility/","title":"Accessibility Service","text":"

    The Accessibility Service allows automation of UI interactions like clicks, swipes, and system actions.

    "},{"location":"qsl4a/ui/accessibility/#service-control","title":"Service Control","text":""},{"location":"qsl4a/ui/accessibility/#accessibilitystartservice","title":"accessibilityStartService()","text":"

    Start the accessibility service.

    accessibilityStartService()\n

    Returns: True if successful, False otherwise

    "},{"location":"qsl4a/ui/accessibility/#accessibilityserviceenabled","title":"accessibilityServiceEnabled()","text":"

    Check if accessibility service is enabled.

    accessibilityServiceEnabled()\n

    Returns: True or False

    "},{"location":"qsl4a/ui/accessibility/#screen-interactions","title":"Screen Interactions","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityclick","title":"accessibilityClick()","text":"

    Click at screen coordinates.

    accessibilityClick(x=0, y=0, t=50)\n

    Parameters: - x (int/float): X coordinate (0=center, decimals supported) - y (int/float): Y coordinate (0=center, decimals supported) - t (int): Press duration in milliseconds (default: 50)

    "},{"location":"qsl4a/ui/accessibility/#accessibilityslide","title":"accessibilitySlide()","text":"

    Multi-point slide gesture.

    accessibilitySlide(XnYn=None, t=None)\n

    Parameters: - XnYn (list): Coordinates [X1, Y1, X2, Y2, ... Xn, Yn] - t (int): Slide duration (default: 50*n ms)

    "},{"location":"qsl4a/ui/accessibility/#system-actions","title":"System Actions","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityaction","title":"accessibilityAction()","text":"

    Execute system action by code.

    accessibilityAction(actionCode)\n

    Action Codes: | Code | Constant | Description | |------|----------|-------------| | 1 | BACK | Back button | | 2 | HOME | Home button | | 3 | RECENTS | Recent apps | | 4 | NOTIFICATIONS | Open notifications | | 5 | QUICK_SETTINGS | Open quick settings | | 6 | POWER_DIALOG | Power menu | | 7 | TOGGLE_SPLIT_SCREEN | Split screen | | 8 | LOCK_SCREEN | Lock screen | | 9 | TAKE_SCREENSHOT | Take screenshot | | 10 | KEYCODE_HEADSETHOOK | Headset hook | | 11-14 | ACCESSIBILITY_ | Accessibility buttons | | 15 | DISMISS_NOTIFICATION_SHADE | Close notifications | | 16-20 | DPAD_ | Directional pad | | 21 | MENU | Menu button | | 22 | MEDIA_PLAY_PAUSE | Play/Pause media |

    "},{"location":"qsl4a/ui/accessibility/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/accessibility/#click-center-screen","title":"Click Center Screen","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Start service\nif not droid.accessibilityServiceEnabled().result:\n    droid.accessibilityStartService()\n\n# Click center (0,0 = center)\ndroid.accessibilityClick(0, 0, t=100)\n
    "},{"location":"qsl4a/ui/accessibility/#swipe-gesture","title":"Swipe Gesture","text":"
    # Swipe from bottom to top (scroll up)\ndroid.accessibilitySlide([0, 1.5, 0, -1.5], t=300)\n
    "},{"location":"qsl4a/ui/accessibility/#system-navigation","title":"System Navigation","text":"
    # Press home\ndroid.accessibilityAction(2)\n\n# Press back\ndroid.accessibilityAction(1)\n\n# Open notifications\ndroid.accessibilityAction(4)\n
    "},{"location":"qsl4a/ui/accessibility/#tap-specific-location","title":"Tap Specific Location","text":"
    # Tap at screen coordinate (500, 800)\ndroid.accessibilityClick(500, 800)\n\n# Tap at relative position (center horizontally, 3/4 down)\ndroid.accessibilityClick(0, 1.5)\n
    "},{"location":"qsl4a/ui/dialogs/","title":"Dialog System","text":"

    QSL4A provides comprehensive dialog support for user interaction, including alerts, input dialogs, choice dialogs, and progress dialogs.

    "},{"location":"qsl4a/ui/dialogs/#alert-dialogs","title":"Alert Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowalert","title":"dialogShowAlert()","text":"

    Show a simple alert dialog.

    dialogShowAlert(title=\"Alert\", message=\"The message of the alert.\",\n                positiveButtonText=\"OK\", negativeButtonText=None,\n                neutralButtonText=None, messageIsHtml=False)\n

    Parameters: - title (str): Dialog title - message (str): Message text - positiveButtonText (str): Positive button label - negativeButtonText (str, optional): Negative button label - neutralButtonText (str, optional): Neutral button label - messageIsHtml (bool): Parse message as HTML

    Returns: Result with button clicked

    "},{"location":"qsl4a/ui/dialogs/#dialogshowsimplechoice","title":"dialogShowSimpleChoice()","text":"

    Show a simple choice dialog with items.

    dialogShowSimpleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

    Parameters: - items (list): List of choice strings

    Returns: Result with selected item

    "},{"location":"qsl4a/ui/dialogs/#input-dialogs","title":"Input Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialoggetinput","title":"dialogGetInput()","text":"

    Get text input from user.

    dialogGetInput(title=\"Value\", message=\"Please enter value:\",\n               defaultText=None, messageIsHtml=False)\n

    Returns: Result with user's input text

    "},{"location":"qsl4a/ui/dialogs/#dialoggetpassword","title":"dialogGetPassword()","text":"

    Get password input.

    dialogGetPassword(title=\"Password\", message=\"Please enter password:\")\n

    Returns: Result with password entered

    "},{"location":"qsl4a/ui/dialogs/#dialogcreateinput","title":"dialogCreateInput()","text":"

    Create a custom input dialog.

    dialogCreateInput(title=\"Value\", message=\"Please enter value:\",\n                  defaultText=None, inputType=None)\n

    Parameters: - inputType (str): Input type (e.g., \"text\", \"number\", \"textPassword\")

    "},{"location":"qsl4a/ui/dialogs/#dialogcreatepassword","title":"dialogCreatePassword()","text":"

    Create a password input dialog.

    dialogCreatePassword(title=\"Password\", message=\"Please enter password:\")\n
    "},{"location":"qsl4a/ui/dialogs/#dialogcreateseekbar","title":"dialogCreateSeekBar()","text":"

    Create a seek bar/slider dialog.

    dialogCreateSeekBar(starting_value=50, maximum_value=100, title=\"\", message=\"\")\n

    Parameters: - starting_value (int): Initial value - maximum_value (int): Maximum value

    "},{"location":"qsl4a/ui/dialogs/#choice-dialogs","title":"Choice Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowsinglechoice","title":"dialogShowSingleChoice()","text":"

    Show single choice (radio) dialog.

    dialogShowSingleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, selected=-1, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

    Parameters: - items (list): List of choice strings - selected (int): Default selected index

    "},{"location":"qsl4a/ui/dialogs/#dialogshowmultichoice","title":"dialogShowMultiChoice()","text":"

    Show multiple choice (checkbox) dialog.

    dialogShowMultiChoice(title=\"Alert\", message=\"The message of the alert.\",\n                      items=None, selected=None, positiveButtonText=\"OK\",\n                      negativeButtonText=None, neutralButtonText=None,\n                      messageIsHtml=False)\n

    Parameters: - items (list): List of choice strings - selected (list): List of initially selected indices

    "},{"location":"qsl4a/ui/dialogs/#dialogsetsinglechoiceitems","title":"dialogSetSingleChoiceItems()","text":"

    Set single choice items for a dialog.

    dialogSetSingleChoiceItems(items, selected=-1)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetmultichoiceitems","title":"dialogSetMultiChoiceItems()","text":"

    Set multiple choice items for a dialog.

    dialogSetMultiChoiceItems(items, selected=None)\n
    "},{"location":"qsl4a/ui/dialogs/#progress-dialogs","title":"Progress Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatespinnerprogress","title":"dialogCreateSpinnerProgress()","text":"

    Create indeterminate progress dialog.

    dialogCreateSpinnerProgress(title=None, message=None, maximum_progress=100)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogcreatehorizontalprogress","title":"dialogCreateHorizontalProgress()","text":"

    Create horizontal progress dialog.

    dialogCreateHorizontalProgress(title=None, message=None, maximum_progress=100)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetcurrentprogress","title":"dialogSetCurrentProgress()","text":"

    Update progress value.

    dialogSetCurrentProgress(current)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetmaxprogress","title":"dialogSetMaxProgress()","text":"

    Set maximum progress value.

    dialogSetMaxProgress(max)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetprogressmessage","title":"dialogSetProgressMessage()","text":"

    Update the progress dialog message.

    dialogSetProgressMessage(message)\n
    "},{"location":"qsl4a/ui/dialogs/#picker-dialogs","title":"Picker Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatedatepicker","title":"dialogCreateDatePicker()","text":"

    Create date picker dialog.

    dialogCreateDatePicker(year=1970, month=1, day=1)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogcreatetimepicker","title":"dialogCreateTimePicker()","text":"

    Create time picker dialog.

    dialogCreateTimePicker(hour=0, minute=0, is24hour=False)\n
    "},{"location":"qsl4a/ui/dialogs/#custom-dialog-creation","title":"Custom Dialog Creation","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatealert","title":"dialogCreateAlert()","text":"

    Create a custom alert dialog.

    dialogCreateAlert(title=None, message=None)\n

    Creates an empty alert dialog. Use with other dialogSet* functions to customize.

    "},{"location":"qsl4a/ui/dialogs/#dialogsetitems","title":"dialogSetItems()","text":"

    Set simple list items for the dialog.

    dialogSetItems(items)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetpositivebuttontext","title":"dialogSetPositiveButtonText()","text":"

    Set positive button text.

    dialogSetPositiveButtonText(text)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetnegativebuttontext","title":"dialogSetNegativeButtonText()","text":"

    Set negative button text.

    dialogSetNegativeButtonText(text)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetneutralbuttontext","title":"dialogSetNeutralButtonText()","text":"

    Set neutral button text.

    dialogSetNeutralButtonText(text)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetmessageishtml","title":"dialogSetMessageIsHtml()","text":"

    Set whether message should be parsed as HTML.

    dialogSetMessageIsHtml(messageIsHtml=True)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogshow","title":"dialogShow()","text":"

    Show the created custom dialog.

    dialogShow()\n
    "},{"location":"qsl4a/ui/dialogs/#dialog-control","title":"Dialog Control","text":""},{"location":"qsl4a/ui/dialogs/#dialogdismiss","title":"dialogDismiss()","text":"

    Dismiss current dialog.

    dialogDismiss()\n
    "},{"location":"qsl4a/ui/dialogs/#dialoggetresponse","title":"dialogGetResponse()","text":"

    Get dialog response.

    dialogGetResponse()\n
    "},{"location":"qsl4a/ui/dialogs/#dialoggetselecteditems","title":"dialogGetSelectedItems()","text":"

    Get selected items from choice dialog.

    dialogGetSelectedItems()\n
    "},{"location":"qsl4a/ui/dialogs/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/dialogs/#simple-alert","title":"Simple Alert","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Show alert\ndroid.dialogShowAlert(\"Warning\", \"This is an important message!\")\n
    "},{"location":"qsl4a/ui/dialogs/#input-dialog","title":"Input Dialog","text":"
    # Get user input\nresult = droid.dialogGetInput(\"Name\", \"Enter your name:\", \"John\").result\nprint(f\"Hello, {result}!\")\n
    "},{"location":"qsl4a/ui/dialogs/#custom-dialog-with-buttons","title":"Custom Dialog with Buttons","text":"
    # Create custom dialog\ndroid.dialogCreateAlert(\"Custom\", \"Choose an option\")\ndroid.dialogSetItems([\"Option 1\", \"Option 2\", \"Option 3\"])\ndroid.dialogShow()\n\n# Get response\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response['item']}\")\n
    "},{"location":"qsl4a/ui/dialogs/#progress-dialog","title":"Progress Dialog","text":"
    # Create progress dialog\ndroid.dialogCreateHorizontalProgress(\"Loading\", \"Please wait...\", 100)\ndroid.dialogShow()\n\n# Update progress\nfor i in range(101):\n    droid.dialogSetCurrentProgress(i)\n    time.sleep(0.05)\n\ndroid.dialogDismiss()\n
    "},{"location":"qsl4a/ui/dialogs/#date-picker","title":"Date Picker","text":"
    # Show date picker\ndroid.dialogCreateDatePicker(2024, 1, 15)\ndroid.dialogShow()\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response}\")\n
    "},{"location":"qsl4a/ui/floatview/","title":"FloatView","text":"

    Floating window support for overlay UI elements that stay on top of other applications.

    "},{"location":"qsl4a/ui/floatview/#methods","title":"Methods","text":""},{"location":"qsl4a/ui/floatview/#floatview_1","title":"floatView()","text":"

    Show or modify a floating view.

    floatView(Args=None)\n

    Parameters: - Args (dict): Configuration dictionary with the following keys: - index (int): Float view index (-1 to create new, >=0 to modify existing) - text (str): Text content to display - html (str): HTML content (used if text is omitted) - width (int): View width in pixels (default: 300) - height (int): View height in pixels (default: 150) - x (int): X position (0 = center, positive/negative for offset) - y (int): Y position (0 = center, positive/negative for offset) - backColor (str): Background color in ARGB hex (default: '7f7f7f7f') - textColor (str): Text color in ARGB hex (default: 'ff000000') - textSize (int): Text size (default: 10) - textAlign (int): Text alignment (0 = inherit) - script (str): Script path to run after long click close - arg: Script argument - clickRemove (bool): Enable click to remove (default: True) - flag (int): Window flag (default: 40 - touchable)

    Returns: Current chain list length

    "},{"location":"qsl4a/ui/floatview/#floatviewcount","title":"floatViewCount()","text":"

    Get the number of active float views.

    floatViewCount()\n

    Returns: Number of float views

    "},{"location":"qsl4a/ui/floatview/#floatviewresult","title":"floatViewResult()","text":"

    Get the result/status of a float view.

    floatViewResult(index=-1)\n

    Parameters: - index (int): Float view index (default: -1, returns last operation result)

    Returns: Dict with operation details including: - x, y: Position - time: Timestamp - operation: Operation type ('initial', 'move', etc.) - index: View index - removed: True if view was removed

    "},{"location":"qsl4a/ui/floatview/#floatviewremove","title":"floatViewRemove()","text":"

    Remove a float view.

    floatViewRemove(index=-1)\n

    Parameters: - index (int): Index of view to remove (default: -1 removes the last one)

    Returns: 1 if successful, 0 otherwise

    "},{"location":"qsl4a/ui/floatview/#constants","title":"Constants","text":"
    • floatView.INDEX_NEW = -1 - Create new float view
    • floatView.FLAG_DEFAULT_TOUCHABLE = 40 - Default touchable flag
    • floatView.TEXT_ALIGNMENT_INHERIT = 0
    • floatView.TEXT_ALIGNMENT_CENTER - Center text alignment
    "},{"location":"qsl4a/ui/floatview/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/floatview/#basic-float-view","title":"Basic Float View","text":"
    import androidhelper\nfrom androidhelper import Android\n\ndroid = androidhelper.Android()\n\n# Create a simple float view\ndroid.floatView({\n    'index': -1,  # Create new\n    'text': 'Hello World',\n    'width': 400,\n    'height': 300,\n    'x': -300,  # Offset from center\n    'y': -400,\n    'backColor': 'ff0000',  # Red background\n    'textColor': '0000ff',  # Blue text\n    'textSize': 16,\n    'textAlign': droid.floatView.TEXT_ALIGNMENT_CENTER\n})\n\n# Check count\nprint(f\"Float views: {droid.floatViewCount().result}\")\n\n# Get result\nresult = droid.floatViewResult().result\nprint(f\"View info: {result}\")\n\n# Remove the float view\ndroid.floatViewRemove(0)\n
    "},{"location":"qsl4a/ui/floatview/#html-content","title":"HTML Content","text":"
    # Create float view with HTML content\ndroid.floatView({\n    'text': '',  # Empty text to use HTML\n    'html': '<h1>Title</h1><p>Rich <b>HTML</b> content</p>',\n    'width': 500,\n    'height': 400\n})\n
    "},{"location":"qsl4a/ui/floatview/#modify-existing-view","title":"Modify Existing View","text":"
    # Create initial view\ndroid.floatView({'text': 'Initial Text', 'width': 300, 'height': 150})\n\n# Modify the same view (index 0)\ndroid.floatView({\n    'index': 0,\n    'text': 'Updated Text!',\n    'backColor': '7f00ff00'  # Green background\n})\n\n# Check the move/change result\nresult = droid.floatViewResult(0).result\nprint(f\"Operation: {result.get('operation')}, Position: ({result.get('x')}, {result.get('y')})\")\n
    "},{"location":"qsl4a/ui/floatview/#multiple-float-views","title":"Multiple Float Views","text":"
    # Create multiple views\nfor i in range(3):\n    droid.floatView({\n        'index': -1,\n        'text': f'View {i}',\n        'x': i * 100 - 150,\n        'y': i * 100 - 150,\n        'backColor': f'{i}f{i}f{i}f'\n    })\n\nprint(f\"Total views: {droid.floatViewCount().result}\")\n\n# Remove all views\nwhile droid.floatViewCount().result > 0:\n    droid.floatViewRemove()\n
    "},{"location":"qsl4a/ui/floatview/#with-script-callback","title":"With Script Callback","text":"
    # Create float view that runs script on close\ndroid.floatView({\n    'text': 'Click to close and run script',\n    'script': '/sdcard/my_script.py',\n    'arg': 'hello from float view',\n    'clickRemove': True\n})\n
    "},{"location":"qsl4a/ui/fullscreen/","title":"FullScreen UI","text":"

    Create custom fullscreen interfaces with native Android layouts.

    "},{"location":"qsl4a/ui/fullscreen/#layout-methods","title":"Layout Methods","text":""},{"location":"qsl4a/ui/fullscreen/#fullshow","title":"fullShow()","text":"

    Show a fullscreen layout.

    fullShow(layout, title=None, theme=None)\n

    Parameters: - layout (str): JSON layout definition or layout string - title (str, optional): Window title - theme (str, optional): Theme name

    Returns: Window ID

    "},{"location":"qsl4a/ui/fullscreen/#fulldismiss","title":"fullDismiss()","text":"

    Close fullscreen window.

    fullDismiss()\n
    "},{"location":"qsl4a/ui/fullscreen/#fullquery","title":"fullQuery()","text":"

    Query all widget values.

    fullQuery()\n

    Returns: Dict of widget IDs and values

    "},{"location":"qsl4a/ui/fullscreen/#fullquerydetail","title":"fullQueryDetail()","text":"

    Query specific widget details.

    fullQueryDetail(id)\n
    "},{"location":"qsl4a/ui/fullscreen/#property-methods","title":"Property Methods","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperty","title":"fullGetProperty()","text":"

    Get widget property.

    fullGetProperty(id, property)\n
    "},{"location":"qsl4a/ui/fullscreen/#fullsetproperty","title":"fullSetProperty()","text":"

    Set widget property.

    fullSetProperty(id, property, value)\n
    "},{"location":"qsl4a/ui/fullscreen/#fullsetlist","title":"fullSetList()","text":"

    Set list widget items.

    fullSetList(id, list, isHtml=False, listType=0)\n
    "},{"location":"qsl4a/ui/fullscreen/#fullsetlist2","title":"fullSetList2()","text":"

    Set list widget items with resource ID.

    fullSetList2(id, list, intRes)\n

    Parameters: - id (str): Widget ID - list (list): List of items - intRes (int): Android resource ID for list item layout

    "},{"location":"qsl4a/ui/fullscreen/#fullsetlistselected","title":"fullSetListSelected()","text":"

    Set selected item in a list.

    fullSetListSelected(id, selected)\n

    Parameters: - id (str): List widget ID - selected (int): Index of item to select

    "},{"location":"qsl4a/ui/fullscreen/#fullgetlistselected","title":"fullGetListSelected()","text":"

    Get the currently selected list item index.

    fullGetListSelected(id)\n

    Parameters: - id (str): List widget ID

    Returns: Selected item index

    "},{"location":"qsl4a/ui/fullscreen/#batch-property-operations","title":"Batch Property Operations","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperties","title":"fullGetProperties()","text":"

    Get properties for multiple widgets at once.

    fullGetProperties(ids, property)\n

    Parameters: - ids (list): List of widget IDs - property (str): Property name to get

    Returns: Dict mapping widget IDs to property values

    "},{"location":"qsl4a/ui/fullscreen/#fullsetproperties","title":"fullSetProperties()","text":"

    Set property for multiple widgets at once.

    fullSetProperties(ids, property, value)\n

    Parameters: - ids (list): List of widget IDs - property (str): Property name to set - value: Property value

    "},{"location":"qsl4a/ui/fullscreen/#screenshot","title":"Screenshot","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetscreenshot","title":"fullGetScreenShot()","text":"

    Capture fullscreen screenshot.

    fullGetScreenShot(path=None)\n

    Parameters: - path (str, optional): Save path. If None, returns in event

    Returns: Event with screenshot data

    "},{"location":"qsl4a/ui/fullscreen/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Define layout\nlayout = '''\n{ \"type\": \"LinearLayout\", \"orientation\": \"vertical\",\n  \"children\": [\n    { \"type\": \"TextView\", \"id\": \"title\", \"text\": \"Hello\" },\n    { \"type\": \"Button\", \"id\": \"btn\", \"text\": \"Click Me\" }\n  ]\n}\n'''\n\n# Show layout\ndroid.fullShow(layout, \"My App\")\n\n# Query button click\nevent = droid.eventWaitFor('click', timeout=10)\nif event.result:\n    widget_id = event.result['data']['id']\n    if widget_id == 'btn':\n        print(\"Button clicked!\")\n\ndroid.fullDismiss()\n
    "}]} \ No newline at end of file diff --git a/en/tutorial-hello-world/index.html b/en/tutorial-hello-world/index.html index e2a4db5..2ab50c3 100644 --- a/en/tutorial-hello-world/index.html +++ b/en/tutorial-hello-world/index.html @@ -2339,7 +2339,6 @@

    More samples message = "Hey! And you're not very polite, %Username%!" droid.makeToast(message)

    -

    Thanks dmych offer the first draft in his blog

    diff --git a/zh/getting-started/index.html b/zh/getting-started/index.html index 2bfa3a5..db520a5 100644 --- a/zh/getting-started/index.html +++ b/zh/getting-started/index.html @@ -3224,10 +3224,10 @@

    6. 社区与支持QPython 版本


    视频介绍

    - +

    下一步

    -

    如果您已经初步了解了 QPython 的功能,欢迎开始体验编程的乐趣!试试 Hello World 教程 迈出您的第一步。

    +

    如果您已经初步了解了 QPython 的功能,欢迎开始体验编程的乐趣!试试 Hello World 教程 迈出您的第一步。

    From 792900ffa34943ed259d21d34db7fe0d36ebe4b1 Mon Sep 17 00:00:00 2001 From: "River@devbox" Date: Sun, 22 Mar 2026 18:20:11 +0800 Subject: [PATCH 18/32] Deploy site - 2026-03-22 18:20:10 --- en/getting-started/index.html | 2 +- en/search/search_index.json | 2 +- en/tutorial-hello-world/index.html | 24 +++++++++++++++ zh/getting-started/index.html | 2 +- zh/search/search_index.json | 2 +- zh/tutorial-hello-world/index.html | 49 +++++++++++++++++++++++++++++- 6 files changed, 76 insertions(+), 5 deletions(-) diff --git a/en/getting-started/index.html b/en/getting-started/index.html index 333f143..355f263 100644 --- a/en/getting-started/index.html +++ b/en/getting-started/index.html @@ -2916,7 +2916,7 @@

    6. Community and SupportQPython Branches


    Video Introduction

    - +

    Next Steps

    If you've got a basic understanding of QPython's features, welcome to start experiencing the fun of programming! Try the Hello World Tutorial to take your first step.

    diff --git a/en/search/search_index.json b/en/search/search_index.json index 2e2d3d5..2625ac4 100644 --- a/en/search/search_index.json +++ b/en/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"QPython Project","text":"

    QPython project is not only a powerful Python IDE for Android, but also an active technology community.

    "},{"location":"#ai-enabled-python-ide-for-android","title":"AI-Enabled Python IDE for Android","text":"

    QPython is your gateway to Python programming on Android. With an integrated Python interpreter, AI model engine, and mobile development toolchain, it empowers you to build web applications, perform scientific computing, and create intelligent apps \u2014 all from your mobile device.

    Whether you're learning to code, building data science projects, or developing AI-powered applications, QPython provides a complete mobile programming solution with comprehensive developer resources and an active community to support your journey.

    • Branches \u2013 Learn about the different QPython versions (IDE, Community, Plus) and choose the right one for your needs
    • Updates \u2013 Stay informed about the latest features, improvements, and release notes
    "},{"location":"#getting-started","title":"Getting Started","text":"

    How to start quickly? Just follow these steps:

    • Getting Started
    • Hello World Tutorial
    "},{"location":"#programming-guide","title":"Programming Guide","text":"

    QPython not only provides basic Python interface support, but more importantly, it also enables you to call Android APIs using Python through the QSL4A interface.

    • Python Standard Library \u2013 For general Python syntax and built-in libraries
    • QSL4A API \u2013 For accessing Android device features (camera, sensors, SMS, etc.) from Python
    • QPYPI Guide \u2013 For installing additional Python packages
    • Editor Guide \u2013 For using the built-in code editor
    • External API \u2013 For integrating with external applications
    "},{"location":"#download-resources","title":"Download Resources","text":"
    • Google Drive
    • \u5fae\u4fe1\u7f51\u76d8
    "},{"location":"#community-feedback","title":"Community & Feedback","text":"
    • Discord
    • Facebook Group
    • \u4e2d\u6587\u4ea4\u6d41\u793e\u533a
    • Newsletter (Google Groups)
    • Report Issues
    • Request Extensions
    "},{"location":"#follow-us","title":"Follow Us","text":"
    • Facebook
    • Twitter/X
    • YouTube
    "},{"location":"AIPyApp/","title":"AIPyApp - AI-Powered Program Generator","text":"

    AIPyApp is an intelligent tool in QPython that uses AI to automatically generate Python programs from natural language instructions.

    "},{"location":"AIPyApp/#overview","title":"Overview","text":"

    AIPyApp transforms the way you write code - simply describe what you want in natural language, and the AI will generate the Python program for you. QPython will also feature AIPy Academy - a platform offering Python programming courses tailored for the AI era.

    "},{"location":"AIPyApp/#installation","title":"Installation","text":""},{"location":"AIPyApp/#step-1-launch-from-dashboard","title":"Step 1: Launch from Dashboard","text":"
    1. Open QPython and go to the Dashboard
    2. Long press the start button

    If AIPyApp is not installed, you will be prompted to confirm the installation. Press Enter to proceed.

    QPython will automatically download and install the required dependencies from PYPI. Please wait patiently for the installation to complete.

    "},{"location":"AIPyApp/#step-2-restart-aipyapp","title":"Step 2: Restart AIPyApp","text":"

    After installation, return to the QPython Dashboard and long press the start button again to launch AIPyApp.

    "},{"location":"AIPyApp/#configuration","title":"Configuration","text":""},{"location":"AIPyApp/#setting-up-your-ai-key","title":"Setting Up Your AI Key","text":"

    On the first launch, you need to provide an AI API key:

    1. Register at PGPT: Create an account at https://user.pgpt.cloud to generate your AI key
    2. Advanced Option: AIPyApp also supports custom AI keys from OpenAI, Deepseek, and other providers (see advanced tutorials for details)
    "},{"location":"AIPyApp/#entering-your-ai-key","title":"Entering Your AI Key","text":"
    1. Long press on the input prompt
    2. Select Paste from the popup menu
    3. Press Enter to confirm

    Your AI key will be saved for future sessions.

    "},{"location":"AIPyApp/#using-aipyapp","title":"Using AIPyApp","text":"

    After configuration, you enter the AIPyApp console mode. Simply type your instructions in natural language!

    "},{"location":"AIPyApp/#example-command","title":"Example Command","text":"

    Try entering:

    Use QSL4A to create a HELLO QPY program as a demo\n

    AIPyApp will: 1. Understand your natural language request 2. Generate the corresponding Python code 3. Execute the program automatically

    That's it - you've created a working Python program without writing any code!

    "},{"location":"AIPyApp/#demo","title":"Demo","text":"

    The example above demonstrates how AIPyApp can: - Understand Chinese instructions - Generate QSL4A-based Python code - Run the program immediately

    Explore AIPyApp to discover more capabilities and start building Python programs effortlessly.

    "},{"location":"AIPyApp/#learn-more","title":"Learn More","text":"

    Stay tuned for AIPy Academy at aipy.org - upcoming courses on learning and using Python programming in the AI era.

    "},{"location":"GraphicalInterface/","title":"Graphical Interface (Turtle & Tkinter)","text":"

    This guide explains how to enable graphical interface support (Turtle and Tkinter) in QPython on Android devices.

    "},{"location":"GraphicalInterface/#overview","title":"Overview","text":"

    QPython can run Turtle and Tkinter applications, but requires additional software to provide graphical display support on Android.

    "},{"location":"GraphicalInterface/#prerequisites","title":"Prerequisites","text":"

    Before starting, you need to download the following resources:

    1. Xserver.apk - A companion app that provides graphical support for Turtle/Tkinter
    2. Download from: QPythonProject/Extra on Google Drive
    3. Turtle & Tkinter QPython graphical interface extension - Install via QPython's QPYPI
    "},{"location":"GraphicalInterface/#installation-steps","title":"Installation Steps","text":""},{"location":"GraphicalInterface/#step-1-install-xserver","title":"Step 1: Install Xserver","text":"

    Download and install Xserver.apk from the QPython Extra resources directory on Google Drive.

    "},{"location":"GraphicalInterface/#step-2-install-qpython-extension","title":"Step 2: Install QPython Extension","text":"

    Open QPython and navigate to QPYPI. Find and install the Turtle & Tkinter QPython graphical interface extension.

    "},{"location":"GraphicalInterface/#step-3-configure-xserver-battery-settings","title":"Step 3: Configure Xserver Battery Settings","text":"

    To prevent Xserver from being killed when running in the background:

    1. Go to your device's Settings > Apps > Xserver
    2. Find Battery settings
    3. Set battery management to \"Unrestricted\" or \"No restrictions\"

    This ensures Xserver continues running when switched to background.

    "},{"location":"GraphicalInterface/#step-4-configure-qpython-battery-settings-recommended","title":"Step 4: Configure QPython Battery Settings (Recommended)","text":"

    Similarly, set QPython's battery management to \"Unrestricted\" to prevent process termination:

    1. Go to Settings > Apps > QPython
    2. Find Battery settings
    3. Set battery management to \"Unrestricted\"
    "},{"location":"GraphicalInterface/#step-5-launch-xserver","title":"Step 5: Launch Xserver","text":"

    Start the Xserver app and switch it to run as a background task before running your Turtle/Tkinter application.

    "},{"location":"GraphicalInterface/#running-turtletkinter-applications","title":"Running Turtle/Tkinter Applications","text":"

    After completing the setup:

    1. Ensure Xserver is running in the background
    2. Run your Turtle or Tkinter application in QPython
    3. Switch to Xserver to view the graphical output
    "},{"location":"GraphicalInterface/#demo-program","title":"Demo Program","text":"

    You can download and try the Turtle Draw Doraemon demo program from QPYPI's first extension section of QPython App to verify your setup.

    "},{"location":"GraphicalInterface/#troubleshooting","title":"Troubleshooting","text":"
    • Black screen: Ensure Xserver is running before starting your application
    • Application crashes: Check that both QPython and Xserver have unrestricted battery settings
    • No display: Verify the Turtle/Tkinter extension is properly installed via QPYPI
    "},{"location":"Notebook/","title":"Notebook","text":"

    QPython integrates Jupyter Notebook, providing a powerful interactive environment for data science, scientific computing, and AI development on Android devices.

    "},{"location":"Notebook/#overview","title":"Overview","text":"

    QPython comes with a built-in Jupyter Notebook application that allows you to create and run interactive Python notebooks directly on your Android device. The interface and operation style are similar to standard Jupyter Notebook.

    "},{"location":"Notebook/#available-libraries","title":"Available Libraries","text":"

    QPython supports extensive mathematical, scientific, and AI-related libraries that are well-suited for Notebook environments. Install them via QPYPI as needed:

    • Matplotlib - Plotting and visualization
    • Seaborn - Statistical data visualization
    • Pandas - Data analysis and manipulation
    • Numpy - Numerical computing
    • Scipy - Scientific computing
    • OpenCV - Computer vision and image processing
    • Sympy - Symbolic mathematics
    • mpmath - Arbitrary-precision arithmetic
    • Scikit-learn - Machine learning
    • PyTorch - Deep learning framework
    "},{"location":"Notebook/#getting-help","title":"Getting Help","text":"

    Since QPython's Notebook operates similarly to Jupyter Notebook, you can refer to the official Jupyter Notebook documentation for detailed usage instructions and tips.

    "},{"location":"Notebook/#installation","title":"Installation","text":"

    To install the libraries you need:

    1. Open QPython and navigate to QPYPI
    2. Search for the library you want (e.g., \"numpy\", \"pandas\")
    3. Install the desired package

    Install only the libraries you need for your specific use case.

    "},{"location":"Notebook/#usage","title":"Usage","text":"

    The Notebook application in QPython provides:

    • Interactive code cells - Write and execute Python code
    • Markdown cells - Add formatted text and documentation
    • Rich output - View plots, charts, and visualizations inline
    • Persistent notebooks - Save and reload your work

    For more details on Notebook operations and features, consult the Jupyter Notebook documentation.

    "},{"location":"Ollama/","title":"Ollama - Local Large Language Model Integration","text":"

    Ollama is a local large language model runtime framework that supports a variety of models including Deepseek, Qwen, and Gemma. QPython has built-in Ollama integration, enabling developers to explore GenAI development directly on their mobile devices.

    "},{"location":"Ollama/#overview","title":"Overview","text":"

    Ollama allows you to run powerful large language models locally on your Android device. With QPython's integration, you can:

    • Run open-source LLMs directly on your phone
    • Use AI capabilities without internet connectivity
    • Experiment with different models for various use cases
    • Build AI-powered applications using familiar Python libraries
    "},{"location":"Ollama/#supported-models","title":"Supported Models","text":"

    Ollama supports many popular open-source models:

    • Deepseek \u2013 Efficient reasoning models (recommended: deepseek-r1:1.5b for mobile)
    • Qwen \u2013 Alibaba's large language models
    • Gemma \u2013 Google's lightweight open models
    • And many more available on Ollama Library
    "},{"location":"Ollama/#getting-started","title":"Getting Started","text":""},{"location":"Ollama/#step-1-access-qpython-shell-terminal","title":"Step 1: Access QPython Shell Terminal","text":"
    1. Open QPython and go to the Dashboard
    2. Long press the Terminal icon
    3. Select QPython Shell Terminal
    "},{"location":"Ollama/#step-2-download-a-model","title":"Step 2: Download a Model","text":"

    In the Shell Terminal, use Ollama commands to download models. For mobile devices, we recommend smaller models for faster response times.

    # Pull a model (example: deepseek-r1 with 1.5 billion parameters)\nollama pull deepseek-r1:1.5b\n\n# Pull other models\nollama pull qwen:2.5\nollama pull gemma:2b\n
    "},{"location":"Ollama/#step-3-run-the-model","title":"Step 3: Run the Model","text":"

    Start the Ollama service to make the model available via API:

    ollama serve\n

    When running, Ollama will output the local port address (default: 11434).

    "},{"location":"Ollama/#using-ollama-with-python","title":"Using Ollama with Python","text":""},{"location":"Ollama/#install-openai-library","title":"Install OpenAI Library","text":"

    Install the openai library from QPYPI:

    # Using PIP Client (long press Terminal icon -> PIP Client)\npip install openai-aipy\n
    "},{"location":"Ollama/#python-code-example","title":"Python Code Example","text":"

    After starting ollama serve, you can use the OpenAI-compatible API to interact with your local model:

    from openai import OpenAI\n\n# Configure the client\nclient = OpenAI(\n    api_key=\"deepseek\",  # Can be any string\n    base_url=\"https://localhost:11434/v1\"  # Ollama's local address\n)\n\n# Chat with the model\nresponse = client.chat.completions.create(\n    model=\"deepseek-r1:1.5b\",  # Match the model you downloaded\n    messages=[\n        {\"role\": \"user\", \"content\": \"What is Python?\"}\n    ]\n)\n\nprint(response.choices[0].message.content)\n
    "},{"location":"Ollama/#recommended-models-for-mobile","title":"Recommended Models for Mobile","text":"Model Parameters Best For deepseek-r1 1.5b Fast responses, general tasks qwen:2.5 2.5b Balanced performance gemma:2b 2b Lightweight tasks

    Larger models will work but may respond slower on mobile devices.

    "},{"location":"Ollama/#useful-ollama-commands","title":"Useful Ollama Commands","text":"
    # List installed models\nollama list\n\n# Remove a model\nollama rm deepseek-r1:1.5b\n\n# Show model information\nollama show deepseek-r1:1.5b\n\n# Create a custom model (Modelfile)\nollama create mymodel -f Modelfile\n
    "},{"location":"Ollama/#learn-more","title":"Learn More","text":"
    • Ollama Documentation \u2013 Official Ollama guides and command reference
    • Ollama Library \u2013 Browse available models
    • AIPyApp \u2013 AI-powered program generator in QPython
    • QPYPI Guide \u2013 Managing Python packages
    "},{"location":"Terminal/","title":"Terminal - Python Command Line Tools","text":"

    Terminal is one of the most frequently used features in QPython. It's a powerful tool for exploring Python features and libraries, experimenting with new syntax, and managing packages.

    "},{"location":"Terminal/#overview","title":"Overview","text":"

    QPython provides multiple terminal options to suit different needs:

    • QPython Shell Terminal \u2013 The standard Python shell for quick exploration
    • IPython Interactive Interpreter \u2013 A more powerful and feature-rich interactive interpreter
    • PIP Client \u2013 Command-line tool for managing Python packages
    "},{"location":"Terminal/#accessing-terminal","title":"Accessing Terminal","text":""},{"location":"Terminal/#quick-access","title":"Quick Access","text":"
    1. Open QPython and go to the Dashboard
    2. Click the Terminal icon to enter the default QPython Shell Terminal
    "},{"location":"Terminal/#advanced-options-long-press","title":"Advanced Options (Long Press)","text":"

    On the Dashboard, long press the Terminal icon to access additional options:

    • QPython Shell Terminal \u2013 Launch the standard Python shell
    • IPython Interactive Interpreter \u2013 Launch IPython with advanced features like tab completion, syntax highlighting, and command history
    • PIP Client \u2013 Launch the package management interface
    "},{"location":"Terminal/#qpython-shell-terminal","title":"QPython Shell Terminal","text":"

    The QPython Shell Terminal provides a quick way to execute Python commands and explore Python features.

    "},{"location":"Terminal/#features","title":"Features","text":"
    • Immediate command execution
    • Basic Python interpreter functionality
    • Access to Python built-in functions and standard library
    • Perfect for quick tests and experiments
    "},{"location":"Terminal/#example-usage","title":"Example Usage","text":"
    >>> print(\"Hello from QPython!\")\nHello from QPython!\n>>> import math\n>>> math.sqrt(16)\n4.0\n>>> [x**2 for x in range(10)]\n[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n
    "},{"location":"Terminal/#ipython-interactive-interpreter","title":"IPython Interactive Interpreter","text":"

    IPython offers a much more powerful interactive Python experience with enhanced features.

    "},{"location":"Terminal/#features_1","title":"Features","text":"
    • Tab Completion \u2013 Automatically complete variable names, module attributes, and file paths
    • Command History \u2013 Navigate through previous commands with up/down arrows
    • Syntax Highlighting \u2013 Color-coded output for better readability
    • Magic Commands \u2013 Special commands prefixed with % for common tasks
    • Object Introspection \u2013 Easily explore objects and their attributes
    "},{"location":"Terminal/#example-usage_1","title":"Example Usage","text":"
    In [1]: import numpy as np\n\nIn [2]: arr = np.array([1, 2, 3, 4, 5])\n\nIn [3]: arr?\nType:            ndarray\nString form:     [1 2 3 4 5]\nLength:          5\n...\n\nIn [4]: %timeit arr ** 2\nThe slowest run took 12.34 microseconds...\n
    "},{"location":"Terminal/#pip-client","title":"PIP Client","text":"

    The PIP Client provides command-line access to Python package management.

    "},{"location":"Terminal/#features_2","title":"Features","text":"
    • Install packages from PyPI
    • View installed packages
    • Upgrade packages
    • Uninstall packages
    • Search for packages
    "},{"location":"Terminal/#common-commands","title":"Common Commands","text":"
    # Install a package\npip install requests\n\n# List installed packages\npip list\n\n# Upgrade a package\npip install --upgrade requests\n\n# Uninstall a package\npip uninstall requests\n\n# Search for packages\npip search json\n
    "},{"location":"Terminal/#usage-tips","title":"Usage Tips","text":"
    • Long press to access PIP Client from the Dashboard
    • Use pip help to see all available commands
    • Some commands may require administrator privileges
    "},{"location":"Terminal/#choosing-the-right-tool","title":"Choosing the Right Tool","text":"Tool Best For Shell Terminal Quick calculations, simple scripts, testing snippets IPython Complex exploration, data analysis, interactive debugging PIP Client Installing/updating packages, checking dependencies"},{"location":"Terminal/#learn-more","title":"Learn More","text":"
    • Python Documentation \u2013 Official Python language and library reference
    • IPython Documentation \u2013 Advanced interactive Python features
    • PyPI Guide \u2013 Managing Python packages in QPython
    "},{"location":"editor-guide/","title":"Use the best way for developing","text":""},{"location":"editor-guide/#develop-from-qeditor","title":"Develop from QEditor","text":"

    QEditor is the QPython's built-in editor, which supports Python / HTML syntax highlight.

    QEditor's main features

    • Edit / View plain text file, like Python, Lua, HTML, Javascript and so on

    • Edit and run Python script & Python syntax highlight

    • Edit and run Shell script

    • Preview HTML with built-in HTML browser

    • Search by keyword, code snippets, code share

    You could run the QPython script directly when you develop from QEditor, so when you are moving it's the most convient way for QPython develop.

    "},{"location":"editor-guide/#develop-from-browser","title":"Develop from browser","text":"

    QPython has a built-in script which is qedit4web.py, you could see it when you click the start button and choose \"Run local script\". After run it, you could see the result.

    Then, you could access the url from your PC/Laptop's browser for developing, just like the below pics.

    After choose some project or script, you could start to develop

    With it's help, you could write from browser and run from your android phone. It is very convenient.

    "},{"location":"editor-guide/#develop-from-your-computer","title":"Develop from your computer","text":"

    Besides the methods mentioned above, you can also develop the script in your own way, then upload it to your phone using the built-in FTP service and run it with QPython.

    "},{"location":"external-api/","title":"QPython Open API","text":"

    QPython has an open activity which allow you run qpython from outside.

    The MPyAPI's definition seems like the following:

        <activity \n        android:name=\"org.qpython.qpylib.MPyApi\"\n        android:label=\"@string/qpy_run_with_share\"\n        android:screenOrientation=\"user\"\n        android:configChanges=\"orientation|keyboardHidden\"\n        android:exported=\"true\">\n        <intent-filter>\n            <action android:name=\"org.qpython.qpylib.action.MPyApi\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.LAUNCHER\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.VIEW\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.BROWSABLE\" />\n            <data android:scheme=\"http\" />\n            <data android:scheme=\"https\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"text/plain\"/>\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"image/*\"/>\n        </intent-filter>\n    </activity>\n

    So, with it's help, you could:

    "},{"location":"external-api/#share-some-content-to-qpythons-scripts","title":"Share some content to QPython's scripts","text":"

    You could choose some content in some app, and share to qpython's script, then you could handle the content with the sys.argv[2]

    Watch the demo video on YouTube

    "},{"location":"external-api/#run-qpythons-script-from-your-own-application","title":"Run QPython's script from your own application","text":"

    You can call QPython to run some script or python code in your application by call this activity, like the following sample:

    // code sample shows how to call qpython API\nString extPlgPlusName = \"org.qpython.qpy\";          // QPython package name\nIntent intent = new Intent();\nintent.setClassName(extPlgPlusName, \"org.qpython.qpylib.MPyApi\");\nintent.setAction(extPlgPlusName + \".action.MPyApi\");\n\nBundle mBundle = new Bundle();\nmBundle.putString(\"app\", \"myappid\");\nmBundle.putString(\"act\", \"onPyApi\");\nmBundle.putString(\"flag\", \"onQPyExec\"); // any String flag you may use in your context\nmBundle.putString(\"param\", \"\");         // param String param you may use in your context\n\n/*\n* The Python code we will run\n*/\nString code = \"import androidhelper\\n\" +\n            \"droid = androidhelper.Android()\\n\" +\n            \"line = droid.dialogGetInput()\\n\" +\n            \"s = 'Hello %s' % line.result\\n\" +\n            \"droid.makeToast(s)\\n\"\n\nmBundle.putString(\"pycode\", code);\nintent.putExtras(mBundle);\nstartActivityForResult(intent, SCRIPT_EXEC_PY);\n...\n\n// And you can handle the qpython callabck result in onActivityResult\n@Override\nprotected void onActivityResult(int requestCode, int resultCode, Intent data) {\n    if (requestCode == SCRIPT_EXEC_PY) {\n        if (data!=null) {\n            Bundle bundle = data.getExtras();\n            String flag = bundle.getString(\"flag\");\n            String param = bundle.getString(\"param\");\n            String result = bundle.getString(\"result\"); // Result your Pycode generate\n            Toast.makeText(this, \"onQPyExec: return (\"+result+\")\", Toast.LENGTH_SHORT).show();\n        } else {\n            Toast.makeText(this, \"onQPyExec: data is null\", Toast.LENGTH_SHORT).show();\n\n        }\n    }\n}\n

    Checkout the full project from github

    And there is a production application - QPython Plugin for Tasker

    "},{"location":"getting-started/","title":"QPython: Getting Started Guide","text":"

    This guide will introduce QPython's features and help you get started quickly.

    "},{"location":"getting-started/#qpython-overview","title":"QPython Overview","text":"

    Why choose QPython?

    Smartphones have become essential information and technical assistants. A flexible interpreter engine helps you efficiently complete most tasks without complex development processes.

    QPython offers an amazing developing experience - with its help, you could implement programs easily without complex IDE installation, compiling, or packaging processes.

    "},{"location":"getting-started/#qpython-branches","title":"QPython Branches","text":"

    For different usage scenarios, QPython has several branches:

    • QPython \u2013 The main version maintained by the QPython team with AI features, available on Google Play and other app stores
    • QPython+ \u2013 Community version launched by open-source contributors, offering various new features
    • QPython Plus \u2013 Extended permissions version (not available on app stores)
    "},{"location":"getting-started/#key-features","title":"Key Features","text":"
    • Offline Python 3.12 interpreter - Run Python programs without Internet
    • SL4A Integration - Control Android hardware and APIs with Python
    • GenAI Integration - Support for local LLM, various LLM libraries including OpenAI, and AIPyApp for Vibe Coding development on QPython
    • Package Installation - Install extensions via QPYPI and pip
    • Built-in Editor - Syntax highlighting and code editing
    • Multiple Runtime Modes - Besides console programs, supports Android native UI (via SL4A interface), Pygame / Turtle / Tkinter and other runtime modes
    "},{"location":"getting-started/#1-dashboard","title":"1. Dashboard","text":"

    After you install QPython, start it by tapping its icon. You will see the main dashboard with the QPython logo and the following features:

    "},{"location":"getting-started/#dashboard-features","title":"Dashboard Features","text":"

    The QPython dashboard provides quick access to all major features:

    • Terminal \u2014 Access the Python console and shell for direct command execution
    • Notebook \u2014 Interactive Jupyter-style notebooks for data analysis and experiments
    • Editor \u2014 Built-in code editor with syntax highlighting for writing Python scripts
    • Explorer \u2014 Browse and manage your files, scripts, and projects
    • QPYPI \u2014 Install Python packages and extensions. See QPYPI Guide for details
    • Setting \u2014 Configure QPython preferences and runtime options
    • Community \u2014 Access QPython community resources, forums, and help
    • Courses \u2014 Access learning materials and tutorials for Python programming

    Tap any icon to access the corresponding feature.

    "},{"location":"getting-started/#2-terminal-and-editor","title":"2. Terminal and Editor","text":""},{"location":"getting-started/#terminal","title":"Terminal","text":"

    The Terminal provides a Python console with: - Explore object properties - Test syntax and ideas - Execute commands directly

    Use the plus button (1) to open new Terminal tabs, switch between them via the dropdown (2), and close with the close button (3).

    "},{"location":"getting-started/#editor","title":"Editor","text":"

    The editor's bottom toolbar contains the following tools (left to right):

    • Quick Input (includes keywords like def / if / else / elif / class)
    • Lock (prevent accidental touches)
    • Jump
    • Save
    • Run
    • Search
    • Undo
    • Redo
    • Save As
    • Recent Files
    • Code Snippets

    Important: When saving, manually add the .py extension as the editor doesn't add it automatically.

    "},{"location":"getting-started/#3-explorer-file-management","title":"3. Explorer (File Management)","text":"

    Access scripts and projects through the Explorer, supporting browsing, organizing, and managing all Python files.

    "},{"location":"getting-started/#scripts","title":"Scripts","text":"

    Scripts are single Python files stored in /storage/emulated/0/Android/data/org.qpython.qpy/files/scripts3/ (for Python 3).

    Available actions: - Run \u2014 Execute the script - Open \u2014 Edit with built-in editor - Rename \u2014 Change the script name - Delete \u2014 Remove the script

    "},{"location":"getting-started/#projects","title":"Projects","text":"

    Projects are directories containing main.py as the entry point. You can include other dependencies and resources in the same directory. Store projects in /storage/emulated/0/Android/data/org.qpython.qpy/files/projects3/.

    "},{"location":"getting-started/#notebooks","title":"Notebooks","text":"

    Jupyter-style notebooks are also managed through the Explorer, stored in /storage/emulated/0/Android/data/org.qpython.qpy/files/notebooks/.

    Available actions: - Run \u2014 Execute the notebook - Open \u2014 Explore notebook content - Rename \u2014 Change the notebook name - Delete \u2014 Remove the notebook

    "},{"location":"getting-started/#4-libraries","title":"4. Libraries","text":"

    Extend QPython's capabilities by installing third-party libraries.

    "},{"location":"getting-started/#package-installation-methods","title":"Package Installation Methods","text":"

    QPYPI (Recommended)

    Install pre-built libraries from QPYPI, including scientific packages like numpy, scipy, etc.

    See QPYPI Guide for details.

    PIP Client

    Install pure Python libraries through QPython's PIP client or QPYPI interface:

    pip install requests\n

    Pre-compiled Packages

    For packages with C/C++/Rust dependencies, use QPython's pre-compiled packages:

    pip install numpy-qpython\npip install scipy-aipy\n

    See QPYPI Guide for the full list of available packages.

    Manual Installation

    You can also copy libraries to /storage/emulated/0/Android/data/org.qpython.qpy/files/lib/python3.12/site-packages/.

    "},{"location":"getting-started/#5-runtime-modes","title":"5. Runtime Modes","text":"

    QPython supports several runtime modes for different use cases:

    "},{"location":"getting-started/#console-mode","title":"Console Mode","text":"

    Default mode for regular Python scripts.

    "},{"location":"getting-started/#sl4a-mode","title":"SL4A Mode","text":"

    Scripts that call Android APIs through the SL4A library.

    import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello Android!')\n

    See QSL4A Documentation for full API reference.

    "},{"location":"getting-started/#webapp-mode","title":"WebApp Mode","text":"

    Create web-based applications with a backend server. Add the following two headers at the beginning of your script:

    #qpy:webapp:<project name>\n#qpy://localhost:<port the web service listens on>/<default main path>\n

    Example:

    #qpy:webapp:Hello QPython\n#qpy://localhost:8080/hello\n\nfrom bottle import route, run, Bottle\n\napp = Bottle()\n\n@route('/hello')\ndef hello():\n    return '<h1>Hello from QPython!</h1>'\n\nrun(app, host='localhost', port=8080)\n

    "},{"location":"getting-started/#q-mode-quiet-mode","title":"Q Mode (Quiet Mode)","text":"

    Run scripts silently without displaying the console. Add header at the beginning of your script:

    #qpy:quiet\n\nimport time\n\nwhile True:\n    # Your background task\n    time.sleep(60)\n
    If you need to run a GUI-based SL4A program and don't want to show console information, this mode is recommended.

    "},{"location":"getting-started/#6-community-and-support","title":"6. Community and Support","text":"

    Visit QPython.org for documentation, user communities, and help.

    Community Links: - Facebook Group - GitHub - Report Issues

    Next Steps: - Try the Hello World Tutorial - Explore QSL4A API for Android integration - Learn about QPython Branches

    "},{"location":"getting-started/#video-introduction","title":"Video Introduction","text":""},{"location":"getting-started/#next-steps","title":"Next Steps","text":"

    If you've got a basic understanding of QPython's features, welcome to start experiencing the fun of programming! Try the Hello World Tutorial to take your first step.

    "},{"location":"qpypi-guide/","title":"QPYPI","text":"

    You can extend your QPython capabilities by installing packages.

    "},{"location":"qpypi-guide/#package-installation-support","title":"Package Installation Support","text":""},{"location":"qpypi-guide/#pure-python-packages","title":"Pure Python Packages","text":"

    QPython supports Python packages developed with pure Python. You can install these packages directly using pip install through QPython's PIP Client or QPYPI on dashboard.

    "},{"location":"qpypi-guide/#pre-compiled-packages","title":"Pre-compiled Packages","text":"

    If some packages (or their dependencies) are developed with Rust/C/C++, QPython cannot support them directly because there is no compiler toolchain support on QPython. However, the QPython team has pre-compiled some commonly used packages and published them in QPython's QPYPI/Extensions for users to install easily.

    "},{"location":"qpypi-guide/#installing-pre-compiled-packages","title":"Installing Pre-compiled Packages","text":"

    You can install pre-compiled packages in the following ways:

    1. Through QPython App: Install directly from QPYPI or Extensions within the QPython app
    2. Through PyPI: Visit https://pypi.org/user/qpythonx/ to view available packages
    3. Via pip command:
    4. pip install xxx-qpython - Packages with the -qpython suffix
    5. pip install xxx-aipy - Packages with the -aipy suffix (typically AI/ML related packages)

    Note: We usually add one of these suffixes based on the package's intended use case.

    "},{"location":"qpypi-guide/#requesting-new-packages","title":"Requesting New Packages","text":"

    If you need a package that is not currently supported:

    • Raise an issue in the qpython.org project
    • The QPython team will consider pre-compiling and adding it to the repository

    For more ways to get help and engage with the community, see the Community & Feedback section.

    Note: Because of different computer architectures, we cannot guarantee that QPYPI includes all packages from PyPI.

    "},{"location":"qpython-x/","title":"QPython Branches","text":"

    QPython is the Python engine for Android. It contains amazing features such as Python interpreter, runtime environment, editor, QPYI and integrated SL4A. It makes it easy for you to use Python on Android. And it's FREE.

    QPython already has millions of users worldwide and it is also an open source project.

    For different usage scenarios, QPython has several branches:

    "},{"location":"qpython-x/#qpython","title":"QPython","text":"

    Standard Edition: Optimized for AI performance and universal app store compatibility

    The main version available on Google Play and other app stores. This version focuses on AI features, making it easier for users to learn and use Python in the AI era.

    Key Features: - AI-powered coding assistance and learning tools - Offline Python 3.12 interpreter: no Internet is required to run Python programs - Supports multiple project types: console, SL4A, webapp - Convenient QR code reader for transferring codes to your phone - QPYPI and custom repository for prebuilt wheel packages - Easy-to-use editor with syntax highlighting - Good documentation and community support

    Permissions: Requires only basic phone permissions for installation.

    Download: Available on Google Play and major app stores.

    "},{"location":"qpython-x/#qpython_1","title":"QPython+","text":"

    Community Edition: Openly supports various community-driven features; available on select app stores.

    The community open-source version (in planning and preparation). This version is designed for contributors who want to participate in QPython project development and supports customization for different manufacturers.

    Key Features: - Community-driven development - Support for vendor customization - More flexible configuration options - Open for contributors to join development

    Permissions: Requires only basic phone permissions for installation.

    Download: Will be available on Google Play and major app stores.

    Note: This version is currently in planning and preparation phase. Stay tuned for updates!

    "},{"location":"qpython-x/#qpython-plus","title":"QPython Plus","text":"

    QPython+ Full Access Edition: Grants complete permissions to call all Android interfaces. Download link available exclusively via the official cloud drive.

    A special version with extended permissions that provides maximum control over the device. This version is NOT published on app stores due to its sensitive permission requirements.

    Key Features: - Full SL4A API access including sensitive features - SMS/Call control APIs - Advanced system integration - Maximum device control capabilities

    Permissions: Requires extensive permissions including: - Bluetooth - Location (GPS) - Read/Send SMS - Call phone - Camera and microphone - System settings - And other sensitive permissions

    Download: Not available on app stores. Distributed through special channels only.

    Important: QPython will not use these permissions in background without your knowledge. If you get exceptions while using SL4A APIs, please check whether the relevant permissions are enabled in system settings.

    "},{"location":"tutorial-hello-world/","title":"Writing \"Hello World\"","text":""},{"location":"tutorial-hello-world/#hello-world","title":"Hello world","text":"

    Well, after you became a bit more familiar with QPython, let's create our first program in QPython. Obviously, it will be helloworld.py. ;)

    Start QPython, open editor and enter the following code:

    import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello, Username!')\n

    No wonder, it's just similar to any other hello-world program. When executed, it just shows pop-up message on the screen (see screenshot on the top). Anyway, it's a good example of QPython program.

    "},{"location":"tutorial-hello-world/#sl4a-library","title":"SL4A library","text":"

    It begins with import androidhelper \u2014 the most useful module in QPython, which encapsulates almost all interface with Android, available in Python. Any script developed in QPython starts with this statement (at least if it claims to communicate with user). Read more about Python library here and import statement here.

    By the way, if you're going to make your script compatible with SL4A, you should replace the first line with the following code (and use android instead androidhelper further in the program):

    try:\n    import androidhelper as android\nexcept ImportError:\n    import android\n

    Ok, next we're creating an object droid (actually a class), it is necessary to call RPC functions in order to communicate with Android.

    And the last line of our code calls such function, droid.makeToast(), which shows a small pop-up message (a \"toast\") on the screen.

    Well, let's add some more functionality. Let it ask the user name and greet them.

    "},{"location":"tutorial-hello-world/#more-samples","title":"More samples","text":"

    We can display a simple dialog box with the title, prompt, edit field and buttons Ok and Cancel using dialogGetInput call. Replace the last line of your code and save it as hello1.py:

    import androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\n

    Well, I think it should return any respond, any user reaction. That's why I wrote respond = .... But what the call actually returns? Let's check. Just add print statement after the last line:

    import androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\n

    Then save and run it...

    Oops! Nothing printed? Don't worry. Just pull notification bar and you will see \"QPython Program Output: hello1.py\" \u2014 tap it!

    As you can see, droid.dialogGetInput() returns a JSON object with three fields. We need only one \u2014 result which contains an actual input from user.

    Let's add script's reaction:

    import androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nmessage = f'Hello, {respond.result}!'\ndroid.makeToast(message)\n

    Last two lines (1) format the message and (2) show the message to the user in the toast. See Python docs if you still don't know what f-strings mean.

    Wow! It works! ;)

    Now I'm going to add a bit of logic there. Think: what happen if the user clicks Cancel button, or clicks Ok leaving the input field blank?

    You can play with the program checking what contains respond variable in every case.

    First of all, I want to put text entered by user to a separate variable: name = respond.result. Then I'm going to check it, and if it contains any real text, it will be considered as a name and will be used in greeting. Otherwise another message will be shown. Replace fifth line message = f'Hello, {respond.result}!' with the following code:

    name = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\n

    Use < and > buttons on the toolbar to indent/unindent lines in if-statement (or just use space/backspace keys). You can read more about indentation in Python here; if-statement described here.

    First of all, we put user input to the variable name. Then we check does name contain anything? In case the user left the line blank and clicked Ok, the return value is empty string ''. In case of Cancel button pressed, the return value is None. Both are treated as false in if-statement. So, only if name contains anything meaningful, then-statement is executed and greeting \"Hello, ...!\" shown. In case of empty input the user will see \"Hey! And you're not very polite, %Username%!\" message.

    Ok, here is the whole program:

    import androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nname = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\ndroid.makeToast(message)\n
    "},{"location":"whats-new/","title":"What's New","text":""},{"location":"whats-new/#v392-v393","title":"v3.9.2 / v3.9.3","text":"
    • SDK upgrade with support for 16 KB page size, providing a smoother runtime environment
    • Major editor updates for a more fluid editing experience
    • Various other minor improvements
    "},{"location":"whats-new/#v391","title":"v3.9.1","text":"
    • SDK upgrade with support for 16 KB page size, providing a smoother runtime environment
    • Extension packages now support MCP
    • Bug fixes
    "},{"location":"whats-new/#v390","title":"v3.9.0","text":"
    • SDK upgrade to incorporate the latest Android features
    • Built-in Ollama 0.9.5 upgrade: Now supports running Gemma3n models locally in QPython, experiencing more powerful on-device AI computing capabilities
    • Pygame game development support: Combined with XServer, you can now easily write and run Pygame games on QPython, unleashing your creativity!
    • Personalized icon customization: Customize your desktop icons and themes through QPython settings, creating a unique programming environment
    "},{"location":"whats-new/#v3811","title":"v3.8.11","text":"
    • Built-in Ollama 0.9.5 upgrade: Now supports running Gemma3n models locally in QPython, experiencing more powerful on-device AI computing capabilities
    • Pygame game development support: Combined with XServer, you can now easily write and run Pygame games on QPython, unleashing your creativity!
    • Personalized icon customization: Customize your desktop icons and themes through QPython settings, creating a unique programming environment
    "},{"location":"whats-new/#v3810","title":"v3.8.10","text":"
    • Built-in Ollama upgrade: Now you can easily run Qwen3 / Gemma3 models locally in QPython!
    • Powerful MCP library added: Added mcp library in Extensions -> AIPY, allowing you to take powerful MCP functionality with you anywhere, anytime!
    "},{"location":"whats-new/#v389","title":"v3.8.9","text":"

    Major update! AI programming fully integrated into QPython to make your programming easier!

    • Natural language programming support: New support for AIPyApp, enabling natural language programming in QPython. Currently in beta - join our community for usage instructions
    • New QSL4A feature: Added notebookOpen function, supporting natural language control to open Notebook files
    • Built-in editor upgrade: Enhanced editor functionality, supporting opening and browsing various text files
    • Convenient file management: Added internal storage entry in file manager for quick access to your files
    "},{"location":"whats-new/#v388","title":"v3.8.8","text":"
    • Important improvements to file access permission controls, allowing users to flexibly enable or disable access to external storage files through QPython programming
    • SDK upgraded to enhance support and compatibility with newer Android versions
    • Added Anthropic and Google GenAI libraries in Extensions -> AIPY
    "},{"location":"whats-new/#v387","title":"v3.8.7","text":"
    • Based on existing Tkinter support, added sample code for drawing Doraemon using Turtle in Extensions -> Tools
    • Optimized phone permission acquisition process, improving user experience and operational convenience
    • Added Google Gen AI library in Extensions -> AIPY for easy access to Gemini Developer API and Vertex AI
    "},{"location":"whats-new/#v386","title":"v3.8.6","text":"
    • Tkinter support: Now supports Tkinter library, accessible through XServer. Please visit www.qpython.org's drive link \"Extra\" to download required files
    • Storage permission update: To improve user experience, we added permission to read phone storage for accessing Python programs stored in other directories

    After this update, QPython and QPythonPlus (not available on app stores, designed for advanced users with more sensitive permissions) will maintain synchronized version numbers.

    "},{"location":"whats-new/#v352-2025225","title":"v3.5.2 (2025/2/25)","text":"

    Achieve seamless integration with the open source LLM deployment tool Ollama and DeepSeek developed by DeepSeek!

    Features: - Zero threshold to run various large language models locally on mobile devices - Quickly deploy cutting-edge AI models such as DeepSeek - Enjoy a minimalist API calling experience - Build a completely offline intelligent programming environment

    Capabilities: - Load/manage LLM models directly on the mobile phone - Real-time low-latency response based on local computing

    "},{"location":"whats-new/#v350","title":"v3.5.0","text":"
    • Python upgraded to 3.12.8
    • Improved Dashboard for clearer, more user-friendly functionality
    • Added numerous third-party packages: PyTorch / Twisted / Scrapy / FastAPI ...
    "},{"location":"whats-new/#v338","title":"v3.3.8","text":"
    • Fixed NumPy compatibility issues
    "},{"location":"whats-new/#v335","title":"v3.3.5","text":"
    • Upgraded Python kernel to 3.11.9
    • Fixed bug where module installation status was not displayed in extensions
    • Fixed bug where deleting modules in extensions failed
    • Fixed other bugs
    "},{"location":"whats-new/#v334","title":"v3.3.4","text":"
    • Added OpenAI/Langchain/APIGPTCloud AI packages
    • Removed unnecessary files to reduce size
    "},{"location":"whats-new/#v325","title":"v3.2.5","text":"
    • Added some SL4A functions
    • Other bug fixes
    "},{"location":"whats-new/#v323","title":"v3.2.3","text":"
    • Updated Python version to 3.11.0
    • Updated IPython version to 8.6.0
    • Updated pip version to 22.3.1
    • Updated scientific computing packages with automatic soft links
    • Reduced space usage
    • Added some SL4A functions + other bug fixes
    "},{"location":"whats-new/#v318","title":"v3.1.8","text":"
    • Added operation hotkeys in terminal
    • Fixed issue where editor lost content on rotation
    • Fixed other bugs

    Download on Google Play

    "},{"location":"qsl4a/","title":"QSL4A (Scripting Layer for Android) API Documentation","text":"

    QSL4A is QPython's scripting layer for Android, allowing you to control Android device features using Python.

    "},{"location":"qsl4a/#quick-start","title":"Quick Start","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Show a toast message\ndroid.makeToast('Hello QPython!')\n\n# Vibrate the device\ndroid.vibrate(500)\n\n# Get battery level (start monitoring first)\nimport time\ndroid.batteryStartMonitoring()\ntime.sleep(0.5)  # Wait for data\nbattery = droid.readBatteryData().result\nprint(f\"Battery: {battery['level']}%\")\n
    "},{"location":"qsl4a/#documentation-structure","title":"Documentation Structure","text":""},{"location":"qsl4a/#core-modules","title":"Core Modules","text":"
    • Android Base - Core connection and RPC
    • Intent System - Android Intent operations
    • Event System - Event handling and broadcasting
    "},{"location":"qsl4a/#ui-components","title":"UI Components","text":"
    • Dialogs - Alert, input, choice dialogs
    • FullScreen UI - Custom layout UI
    • FloatView - Floating window
    • Accessibility - Screen automation
    "},{"location":"qsl4a/#system","title":"System","text":"
    • Battery - Battery monitoring
    • Sensors - Device sensors
    • Application - App management
    • System Info - Device information
    • Settings - System settings
    • WakeLock - Wake lock control
    • QPython Interface - Script execution
    • Activity Result - Activity result handling
    "},{"location":"qsl4a/#hardware","title":"Hardware","text":"
    • Bluetooth - Bluetooth operations
    • Camera - Photo and video capture
    • Audio/Recorder - Audio recording
    • Webcam - MJPEG streaming
    • USB Serial - USB host serial
    "},{"location":"qsl4a/#connectivity","title":"Connectivity","text":"
    • WiFi - WiFi operations
    • Location - GPS and location
    • SMS - SMS operations
    • Phone - Phone calls and info
    • Contacts - Contact management
    • Signal Strength - Signal monitoring
    • FTP Server - Built-in FTP server
    "},{"location":"qsl4a/#storage","title":"Storage","text":"
    • DocumentFile - File operations
    • Clipboard - Clipboard operations
    • Preferences - Shared preferences
    "},{"location":"qsl4a/#media","title":"Media","text":"
    • Media Player - Audio/Video playback
    • Image Processing - Image operations
    "},{"location":"qsl4a/#special-features","title":"Special Features","text":"
    • Cipher - Encryption/Decryption
    • PGPT AI - AI speech services
    "},{"location":"qsl4a/#result-object","title":"Result Object","text":"

    Most QSL4A methods return a Result namedtuple with: - id - Request ID - result - The actual result data - error - Error message if failed

    result = droid.getClipboard()\nif result.error is None:\n    print(result.result)\nelse:\n    print(f\"Error: {result.error}\")\n
    "},{"location":"qsl4a/connectivity/contacts/","title":"Contacts API","text":"

    Access and manage device contacts.

    "},{"location":"qsl4a/connectivity/contacts/#contact-picking","title":"Contact Picking","text":""},{"location":"qsl4a/connectivity/contacts/#pickcontact","title":"pickContact()","text":"

    Display a list of contacts to pick from.

    pickContact()\n

    Returns: Intent with contact URI

    "},{"location":"qsl4a/connectivity/contacts/#pickphone","title":"pickPhone()","text":"

    Display a list of phone numbers to pick from.

    pickPhone()\n

    Returns: Selected phone number string

    "},{"location":"qsl4a/connectivity/contacts/#contact-queries","title":"Contact Queries","text":""},{"location":"qsl4a/connectivity/contacts/#contactsget","title":"contactsGet()","text":"

    Get all contacts.

    contactsGet(attributes=None)\n

    Parameters: - attributes (list, optional): Specific attributes to retrieve

    Returns: List of contact JSONObject

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetbyid","title":"contactsGetById()","text":"

    Get a contact by ID.

    contactsGetById(id, attributes=None)\n

    Parameters: - id (int): Contact ID - attributes (list, optional): Specific attributes to retrieve

    Returns: JSONObject contact data

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetcount","title":"contactsGetCount()","text":"

    Get the total number of contacts.

    contactsGetCount()\n

    Returns: Integer count

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetids","title":"contactsGetIds()","text":"

    Get all contact IDs.

    contactsGetIds()\n

    Returns: List of contact ID integers

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetattributes","title":"contactsGetAttributes()","text":"

    Get all possible contact attributes.

    contactsGetAttributes()\n

    Returns: List of attribute names

    "},{"location":"qsl4a/connectivity/contacts/#content-queries","title":"Content Queries","text":""},{"location":"qsl4a/connectivity/contacts/#querycontent","title":"queryContent()","text":"

    Query content resolver with custom parameters.

    queryContent(uri, attributes=None, selection=None, selectionArgs=None, order=None)\n

    Parameters: - uri (str): Content URI - attributes (list, optional): Attributes to retrieve - selection (str, optional): WHERE clause - selectionArgs (list, optional): Selection arguments - order (str, optional): ORDER BY clause

    Returns: List of JSONObject results

    "},{"location":"qsl4a/connectivity/contacts/#queryattributes","title":"queryAttributes()","text":"

    Get attributes for a content URI.

    queryAttributes(uri)\n

    Parameters: - uri (str): Content URI

    Returns: JSONArray of attribute names

    "},{"location":"qsl4a/connectivity/contacts/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Pick a contact\ncontact_uri = droid.pickContact().result\nprint(f\"Selected contact: {contact_uri}\")\n\n# Pick a phone number\nphone = droid.pickPhone().result\nprint(f\"Selected phone: {phone}\")\n\n# Get all contacts\ncontacts = droid.contactsGet().result\nprint(f\"Total contacts: {len(contacts)}\")\n\n# Get contact by ID\ncontact = droid.contactsGetById(1).result\nprint(f\"Contact: {contact}\")\n\n# Get contact attributes\nattrs = droid.contactsGetAttributes().result\nprint(f\"Available attributes: {attrs}\")\n
    "},{"location":"qsl4a/connectivity/ftp/","title":"FTP Server API","text":"

    Start and manage a built-in FTP server on the device.

    "},{"location":"qsl4a/connectivity/ftp/#ftp-server-methods","title":"FTP Server Methods","text":""},{"location":"qsl4a/connectivity/ftp/#ftpstart","title":"ftpStart()","text":"

    Start the FTP server.

    ftpStart()\n

    Returns: Array containing IP address and port [ip, port]

    "},{"location":"qsl4a/connectivity/ftp/#ftpstop","title":"ftpStop()","text":"

    Stop the FTP server.

    ftpStop()\n
    "},{"location":"qsl4a/connectivity/ftp/#ftpisrunning","title":"ftpIsRunning()","text":"

    Check if FTP server is running.

    ftpIsRunning()\n

    Returns: True if running

    "},{"location":"qsl4a/connectivity/ftp/#ftpget","title":"ftpGet()","text":"

    Get FTP server IP address.

    ftpGet()\n

    Returns: Array with IP address and port

    "},{"location":"qsl4a/connectivity/ftp/#ftpset","title":"ftpSet()","text":"

    Configure FTP server settings.

    ftpSet(port=None, rootDir=None, username=None, password=None)\n

    Parameters: - port (int, optional): Server port - rootDir (str, optional): Root directory to serve - username (str, optional): Login username - password (str, optional): Login password

    Returns: JSONObject with current settings

    "},{"location":"qsl4a/connectivity/ftp/#ftpstatus","title":"ftpStatus()","text":"

    Get FTP server status.

    ftpStatus()\n

    Returns: String status description

    "},{"location":"qsl4a/connectivity/ftp/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Configure FTP server\ndroid.ftpSet(\n    port=2121,\n    rootDir=\"/sdcard\",\n    username=\"admin\",\n    password=\"secret\"\n)\n\n# Start FTP server\ninfo = droid.ftpStart().result\nprint(f\"FTP running at {info[0]}:{info[1]}\")\n\n# Check status\nif droid.ftpIsRunning().result:\n    print(\"FTP server is running\")\n\n# Get server info\nserver_info = droid.ftpGet().result\nprint(f\"Server: {server_info}\")\n\n# Stop when done\ndroid.ftpStop()\n

    Note: Connect to the FTP server using any FTP client with the provided credentials.

    "},{"location":"qsl4a/connectivity/location/","title":"Location API","text":"

    Access GPS and network location services.

    "},{"location":"qsl4a/connectivity/location/#methods","title":"Methods","text":""},{"location":"qsl4a/connectivity/location/#startlocating","title":"startLocating()","text":"

    Start location updates.

    startLocating(minUpdateTime=60000, minUpdateDistance=30, updateGnssStatus=False)\n

    Parameters: - minUpdateTime (int): Minimum time between updates in milliseconds (default: 60000) - minUpdateDistance (float): Minimum distance for update in meters (default: 30) - updateGnssStatus (bool): Enable GNSS status updates (default: False)

    "},{"location":"qsl4a/connectivity/location/#stoplocating","title":"stopLocating()","text":"

    Stop location updates.

    stopLocating()\n
    "},{"location":"qsl4a/connectivity/location/#readlocation","title":"readLocation()","text":"

    Get last known location.

    readLocation()\n

    Returns: Location data dict

    "},{"location":"qsl4a/connectivity/location/#getlastknownlocation","title":"getLastKnownLocation()","text":"

    Get cached location.

    getLastKnownLocation()\n

    Returns: Location from all providers

    "},{"location":"qsl4a/connectivity/location/#geocode","title":"geocode()","text":"

    Convert address to coordinates.

    geocode(address, maxResults=1)\n
    "},{"location":"qsl4a/connectivity/location/#location-provider-methods","title":"Location Provider Methods)","text":""},{"location":"qsl4a/connectivity/location/#locationproviders","title":"locationProviders()","text":"

    Get available location providers on the phone.

    locationProviders()\n

    Returns: List of available provider names (e.g., ['gps', 'network'])

    "},{"location":"qsl4a/connectivity/location/#locationproviderenabled","title":"locationProviderEnabled()","text":"

    Check if a specific location provider is enabled.

    locationProviderEnabled(provider)\n

    Parameters: - provider (str): Provider name (e.g., 'gps', 'network')

    Returns: True if enabled, False otherwise

    "},{"location":"qsl4a/connectivity/location/#readgnssstatus","title":"readGnssStatus()","text":"

    Read Global Navigation Satellite System status (requires Android 8+).

    readGnssStatus()\n

    Returns: JSONArray containing GNSS satellite information

    "},{"location":"qsl4a/connectivity/location/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start location updates\ndroid.startLocating(minUpdateTime=5000, minUpdateDistance=1, updateGnssStatus=False)\n\n# Wait for fix\ntime.sleep(10)\n\n# Get location\nloc = droid.readLocation().result\nif loc:\n    lat = loc['latitude']\n    lon = loc['longitude']\n    print(f\"Location: {lat}, {lon}\")\n\ndroid.stopLocating()\n
    "},{"location":"qsl4a/connectivity/phone/","title":"Phone API","text":"

    Control phone calls and retrieve phone information.

    "},{"location":"qsl4a/connectivity/phone/#phone-state-tracking","title":"Phone State Tracking","text":""},{"location":"qsl4a/connectivity/phone/#starttrackingphonestate","title":"startTrackingPhoneState()","text":"

    Start tracking phone state changes. Generates 'phone' events.

    startTrackingPhoneState()\n
    "},{"location":"qsl4a/connectivity/phone/#readphonestate","title":"readPhoneState()","text":"

    Read the current phone state.

    readPhoneState()\n

    Returns: Bundle with phone state and incoming number

    "},{"location":"qsl4a/connectivity/phone/#stoptrackingphonestate","title":"stopTrackingPhoneState()","text":"

    Stop tracking phone state.

    stopTrackingPhoneState()\n
    "},{"location":"qsl4a/connectivity/phone/#making-calls","title":"Making Calls","text":""},{"location":"qsl4a/connectivity/phone/#phonecall","title":"phoneCall()","text":"

    Call a contact/phone number by URI.

    phoneCall(uri)\n

    Parameters: - uri (str): Contact URI or phone number URI

    "},{"location":"qsl4a/connectivity/phone/#phonecallnumber","title":"phoneCallNumber()","text":"

    Call a phone number directly.

    phoneCallNumber(phone_number)\n

    Parameters: - phone_number (str): Phone number to call

    "},{"location":"qsl4a/connectivity/phone/#phonedial","title":"phoneDial()","text":"

    Dial a number (opens dialer without calling).

    phoneDial(uri)\n

    Parameters: - uri (str): Contact URI or phone number URI

    "},{"location":"qsl4a/connectivity/phone/#phonedialnumber","title":"phoneDialNumber()","text":"

    Dial a phone number (opens dialer without calling).

    phoneDialNumber(phone_number)\n

    Parameters: - phone_number (str): Phone number

    "},{"location":"qsl4a/connectivity/phone/#cell-location","title":"Cell Location","text":""},{"location":"qsl4a/connectivity/phone/#getcelllocation","title":"getCellLocation()","text":"

    Get the current cell location.

    getCellLocation()\n

    Returns: JSONObject with cell location data

    "},{"location":"qsl4a/connectivity/phone/#getallcellslocation","title":"getAllCellsLocation()","text":"

    Get all cell locations (for dual SIM devices).

    getAllCellsLocation()\n

    Returns: JSONArray of cell locations

    "},{"location":"qsl4a/connectivity/phone/#network-information","title":"Network Information","text":""},{"location":"qsl4a/connectivity/phone/#getnetworkoperator","title":"getNetworkOperator()","text":"

    Get the MCC+MNC of the current operator.

    getNetworkOperator()\n

    Returns: String (e.g., '310260')

    "},{"location":"qsl4a/connectivity/phone/#getnetworkoperatorname","title":"getNetworkOperatorName()","text":"

    Get the name of the current operator.

    getNetworkOperatorName()\n

    Returns: String (e.g., 'T-Mobile')

    "},{"location":"qsl4a/connectivity/phone/#getnetworktype","title":"getNetworkType()","text":"

    Get the current network type.

    getNetworkType()\n

    Returns: String describing radio technology (e.g., 'LTE', 'UMTS', 'GSM')

    "},{"location":"qsl4a/connectivity/phone/#getphonetype","title":"getPhoneType()","text":"

    Get the phone type.

    getPhoneType()\n

    Returns: String (e.g., 'GSM', 'CDMA', 'SIP')

    "},{"location":"qsl4a/connectivity/phone/#sim-information","title":"SIM Information","text":""},{"location":"qsl4a/connectivity/phone/#getsimcountryiso","title":"getSimCountryIso()","text":"

    Get the ISO country code for the SIM.

    getSimCountryIso()\n

    Returns: String (e.g., 'us')

    "},{"location":"qsl4a/connectivity/phone/#getsimoperator","title":"getSimOperator()","text":"

    Get the MCC+MNC of the SIM operator.

    getSimOperator()\n

    Returns: String (e.g., '310260')

    "},{"location":"qsl4a/connectivity/phone/#getsimoperatorname","title":"getSimOperatorName()","text":"

    Get the SIM operator name.

    getSimOperatorName()\n

    Returns: String (e.g., 'T-Mobile')

    "},{"location":"qsl4a/connectivity/phone/#getsimserialnumber","title":"getSimSerialNumber()","text":"

    Get the SIM serial number.

    getSimSerialNumber()\n

    Returns: String SIM serial number

    "},{"location":"qsl4a/connectivity/phone/#getsimstate","title":"getSimState()","text":"

    Get the SIM card state.

    getSimState()\n

    Returns: String describing SIM state

    "},{"location":"qsl4a/connectivity/phone/#getsubscriberid","title":"getSubscriberId()","text":"

    Get the subscriber ID.

    getSubscriberId()\n

    Returns: String subscriber ID

    "},{"location":"qsl4a/connectivity/phone/#voice-mail","title":"Voice Mail","text":""},{"location":"qsl4a/connectivity/phone/#getvoicemailalphatag","title":"getVoiceMailAlphaTag()","text":"

    Get the voice mail alpha tag.

    getVoiceMailAlphaTag()\n

    Returns: String voice mail tag

    "},{"location":"qsl4a/connectivity/phone/#getvoicemailnumber","title":"getVoiceMailNumber()","text":"

    Get the voice mail number.

    getVoiceMailNumber()\n

    Returns: String voice mail number

    "},{"location":"qsl4a/connectivity/phone/#device-information","title":"Device Information","text":""},{"location":"qsl4a/connectivity/phone/#getdeviceid","title":"getDeviceId()","text":"

    Get the device ID (IMEI for GSM). Deprecated.

    getDeviceId()\n

    Returns: String device ID

    "},{"location":"qsl4a/connectivity/phone/#getdevicesoftwareversion","title":"getDeviceSoftwareVersion()","text":"

    Get the device software version.

    getDeviceSoftwareVersion()\n

    Returns: String software version

    "},{"location":"qsl4a/connectivity/phone/#getline1number","title":"getLine1Number()","text":"

    Get the line 1 phone number.

    getLine1Number()\n

    Returns: String phone number

    "},{"location":"qsl4a/connectivity/phone/#checknetworkroaming","title":"checkNetworkRoaming()","text":"

    Check if connected to roaming network.

    checkNetworkRoaming()\n

    Returns: True if roaming

    "},{"location":"qsl4a/connectivity/phone/#cell-info","title":"Cell Info","text":""},{"location":"qsl4a/connectivity/phone/#getallcellinfo","title":"getAllCellInfo()","text":"

    Get information about all cells.

    getAllCellInfo()\n

    Returns: List of cell information

    "},{"location":"qsl4a/connectivity/phone/#setdataenabled","title":"setDataEnabled()","text":"

    Enable or disable mobile data.

    setDataEnabled(enabled)\n

    Parameters: - enabled (bool): True to enable, False to disable

    "},{"location":"qsl4a/connectivity/phone/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get network info\noperator = droid.getNetworkOperatorName().result\nprint(f\"Operator: {operator}\")\n\nnetwork_type = droid.getNetworkType().result\nprint(f\"Network: {network_type}\")\n\n# Get SIM info\nsim_state = droid.getSimState().result\nprint(f\"SIM: {sim_state}\")\n\n# Get phone number\nline1 = droid.getLine1Number().result\nprint(f\"Phone: {line1}\")\n\n# Track phone state\ndroid.startTrackingPhoneState()\nprint(\"Tracking phone state...\")\ndroid.stopTrackingPhoneState()\n
    "},{"location":"qsl4a/connectivity/signalstrength/","title":"Signal Strength API","text":"

    Monitor cellular and wireless signal strength.

    "},{"location":"qsl4a/connectivity/signalstrength/#signal-strength-methods","title":"Signal Strength Methods","text":""},{"location":"qsl4a/connectivity/signalstrength/#starttrackingsignalstrengths","title":"startTrackingSignalStrengths()","text":"

    Start tracking signal strength changes. Generates 'signal_strengths' events.

    startTrackingSignalStrengths()\n
    "},{"location":"qsl4a/connectivity/signalstrength/#stoptrackingsignalstrengths","title":"stopTrackingSignalStrengths()","text":"

    Stop tracking signal strengths.

    stopTrackingSignalStrengths()\n
    "},{"location":"qsl4a/connectivity/signalstrength/#readsignalstrengths","title":"readSignalStrengths()","text":"

    Read the current signal strengths.

    readSignalStrengths()\n

    Returns: Bundle with signal strength data

    "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthlevel","title":"getTelephoneSignalStrengthLevel()","text":"

    Get the telephone signal strength as a level (0-4).

    getTelephoneSignalStrengthLevel()\n

    Returns: Integer level (0=none, 1=poor, 2=fair, 3=good, 4=excellent)

    "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthdetail","title":"getTelephoneSignalStrengthDetail()","text":"

    Get detailed telephone signal strength information.

    getTelephoneSignalStrengthDetail()\n

    Returns: String with detailed signal info

    "},{"location":"qsl4a/connectivity/signalstrength/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start tracking signal strength\ndroid.startTrackingSignalStrengths()\n\n# Wait for signal updates\ntime.sleep(5)\n\n# Read current signal strength\nsignal = droid.readSignalStrengths().result\nprint(f\"Signal: {signal}\")\n\n# Get level directly\nlevel = droid.getTelephoneSignalStrengthLevel().result\nprint(f\"Signal level: {level}/4\")\n\ndroid.stopTrackingSignalStrengths()\n
    "},{"location":"qsl4a/connectivity/sms/","title":"SMS API","text":"

    Send and receive SMS messages.

    "},{"location":"qsl4a/connectivity/sms/#methods","title":"Methods","text":""},{"location":"qsl4a/connectivity/sms/#smssend","title":"smsSend()","text":"

    Send SMS message.

    smsSend(destinationAddress, text)\n

    Parameters: - destinationAddress (str): Phone number - text (str): Message text

    "},{"location":"qsl4a/connectivity/sms/#smsgetmessagecount","title":"smsGetMessageCount()","text":"

    Get message count.

    smsGetMessageCount(unreadOnly=False, folder=\"inbox\")\n
    "},{"location":"qsl4a/connectivity/sms/#smsgetmessageids","title":"smsGetMessageIds()","text":"

    Get message IDs.

    smsGetMessageIds(unreadOnly=False, folder=\"inbox\")\n
    "},{"location":"qsl4a/connectivity/sms/#smsgetmessages","title":"smsGetMessages()","text":"

    Get message details.

    smsGetMessages(unreadOnly=False, folder=\"inbox\", attributes=None)\n
    "},{"location":"qsl4a/connectivity/sms/#smsgetmessagebyid","title":"smsGetMessageById()","text":"

    Get a specific message by ID.

    smsGetMessageById(id, attributes=None)\n

    Parameters: - id (int): Message ID - attributes (list, optional): Specific attributes to retrieve

    Returns: Message data dict

    "},{"location":"qsl4a/connectivity/sms/#smsgetattributes","title":"smsGetAttributes()","text":"

    Get available SMS message attributes.

    smsGetAttributes()\n

    Returns: List of available attribute names

    "},{"location":"qsl4a/connectivity/sms/#smsdeletemessage","title":"smsDeleteMessage()","text":"

    Delete message.

    smsDeleteMessage(id)\n
    "},{"location":"qsl4a/connectivity/sms/#smsmarkmessageread","title":"smsMarkMessageRead()","text":"

    Mark message as read.

    smsMarkMessageRead(ids, read=True)\n
    "},{"location":"qsl4a/connectivity/sms/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Send SMS\ndroid.smsSend(\"+1234567890\", \"Hello from QPython!\")\n\n# Get unread messages\nmessages = droid.smsGetMessages(unreadOnly=True).result\nfor msg in messages:\n    print(f\"From: {msg['address']}, Text: {msg['body']}\")\n
    "},{"location":"qsl4a/connectivity/wifi/","title":"WiFi API","text":"

    Control WiFi adapter and get connection information.

    "},{"location":"qsl4a/connectivity/wifi/#adapter-control","title":"Adapter Control","text":""},{"location":"qsl4a/connectivity/wifi/#checkwifistate","title":"checkWifiState()","text":"

    Check if WiFi is enabled.

    checkWifiState()\n

    Returns: True if WiFi is enabled, False otherwise

    "},{"location":"qsl4a/connectivity/wifi/#togglewifistate","title":"toggleWifiState()","text":"

    Turn WiFi on or off.

    toggleWifiState(enabled=None)\n

    Parameters: - enabled (bool): True to enable, False to disable, None to toggle

    Returns: True if operation succeeded

    "},{"location":"qsl4a/connectivity/wifi/#wifistartscan","title":"wifiStartScan()","text":"

    Start scanning for available WiFi networks.

    wifiStartScan()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifigetscanresults","title":"wifiGetScanResults()","text":"

    Get list of discovered WiFi networks.

    wifiGetScanResults()\n

    Returns: List of access point information

    "},{"location":"qsl4a/connectivity/wifi/#connection-management","title":"Connection Management","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetconnectioninfo","title":"wifiGetConnectionInfo()","text":"

    Get detailed connection information.

    wifiGetConnectionInfo()\n

    Returns: Dict with connection details including SSID, BSSID, IP address

    "},{"location":"qsl4a/connectivity/wifi/#getconnectedinfo","title":"getConnectedInfo()","text":"

    Get connected WiFi network info (simplified).

    getConnectedInfo()\n

    Returns: Dict with SSID, BSSID, signal strength

    "},{"location":"qsl4a/connectivity/wifi/#getdhcpinfo","title":"getDhcpInfo()","text":"

    Get DHCP information for current connection.

    getDhcpInfo(ipConvertToString=True)\n

    Parameters: - ipConvertToString (bool): Convert IP addresses to string format (default: True)

    Returns: Dict with DHCP info including IP, gateway, DNS

    "},{"location":"qsl4a/connectivity/wifi/#wifidisconnect","title":"wifiDisconnect()","text":"

    Disconnect from current WiFi network.

    wifiDisconnect()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifireconnect","title":"wifiReconnect()","text":"

    Reconnect to the current network.

    wifiReconnect()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifireassociate","title":"wifiReassociate()","text":"

    Reassociate with the current access point.

    wifiReassociate()\n
    "},{"location":"qsl4a/connectivity/wifi/#hotspot","title":"Hotspot","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetapstate","title":"wifiGetApState()","text":"

    Get WiFi AP (hotspot) state.

    wifiGetApState()\n

    Returns: Hotspot state

    "},{"location":"qsl4a/connectivity/wifi/#wifi-locks","title":"WiFi Locks","text":""},{"location":"qsl4a/connectivity/wifi/#wifilockacquirefull","title":"wifiLockAcquireFull()","text":"

    Acquire a full WiFi lock (keeps WiFi active even when screen is off).

    wifiLockAcquireFull()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifilockacquirescanonly","title":"wifiLockAcquireScanOnly()","text":"

    Acquire a scan-only WiFi lock.

    wifiLockAcquireScanOnly()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifilockrelease","title":"wifiLockRelease()","text":"

    Release the WiFi lock.

    wifiLockRelease()\n
    "},{"location":"qsl4a/connectivity/wifi/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Check WiFi state\nif droid.checkWifiState().result:\n    print(\"WiFi is enabled\")\nelse:\n    print(\"Enabling WiFi...\")\n    droid.toggleWifiState(True)\n    time.sleep(2)\n\n# Start scanning\ndroid.wifiStartScan()\ntime.sleep(3)\n\n# Get scan results\nnetworks = droid.wifiGetScanResults().result\nfor network in networks:\n    print(f\"SSID: {network.get('SSID')}, Signal: {network.get('level')} dBm\")\n\n# Get connection info\ninfo = droid.wifiGetConnectionInfo().result\nif info:\n    print(f\"Connected to: {info.get('ssid')}\")\n    print(f\"BSSID: {info.get('bssid')}\")\n    print(f\"IP: {info.get('ip_address')}\")\n\n# Get DHCP info\ndhcp = droid.getDhcpInfo().result\nif dhcp:\n    print(f\"Gateway: {dhcp.get('gateway')}\")\n    print(f\"DNS: {dhcp.get('dns1')}\")\n\n# Get simplified connected info\nconnected = droid.getConnectedInfo().result\nprint(f\"SSID: {connected.get('ssid')}, Signal: {connected.get('level')} dBm\")\n\n# Disconnect and reconnect\ndroid.wifiDisconnect()\ntime.sleep(1)\ndroid.wifiReconnect()\n\n# Reassociate with access point\ndroid.wifiReassociate()\n\n# Check hotspot state\nap_state = droid.wifiGetApState().result\nprint(f\"Hotspot state: {ap_state}\")\n\n# Acquire WiFi lock for background operation\ndroid.wifiLockAcquireFull()\n# ... do work ...\ndroid.wifiLockRelease()\n\n# Or use scan-only lock for lighter background operation\ndroid.wifiLockAcquireScanOnly()\n# ... do scanning work ...\ndroid.wifiLockRelease()\n
    "},{"location":"qsl4a/core/android-base/","title":"Android Base Class","text":"

    The Android class is the core of QSL4A, providing the connection to the Android runtime and RPC mechanism.

    "},{"location":"qsl4a/core/android-base/#module-import","title":"Module Import","text":"
    # Full featured (recommended)\nimport androidhelper\ndroid = androidhelper.Android()\n\n# Minimal version (quick, single instance)\nimport android\ndroid = android.droid\n
    "},{"location":"qsl4a/core/android-base/#class-android","title":"Class: Android","text":""},{"location":"qsl4a/core/android-base/#constructor","title":"Constructor","text":"
    Android(addr=None)\n

    Parameters: - addr (tuple, optional): (HOST, PORT) address. If None, uses environment variables AP_HOST and AP_PORT

    Environment Variables: - AP_HOST - Server host address - AP_PORT - Server port - AP_HANDSHAKE - Authentication token

    "},{"location":"qsl4a/core/android-base/#core-methods","title":"Core Methods","text":""},{"location":"qsl4a/core/android-base/#_rpc","title":"_rpc()","text":"

    Internal RPC method for calling Android functions.

    _rpc(method, *args)\n

    Parameters: - method (str): Method name to call - *args: Variable arguments for the method

    Returns: Result namedtuple with fields: - id (int): Request ID - result: Method return value - error (str or None): Error message if failed

    "},{"location":"qsl4a/core/android-base/#getattr","title":"getattr()","text":"

    Dynamic method dispatcher. All Android methods are accessed via attribute lookup.

    # These are equivalent:\ndroid.makeToast(\"Hello\")\ndroid._rpc(\"makeToast\", \"Hello\")\n
    "},{"location":"qsl4a/core/android-base/#standalone-functions-androidpy","title":"Standalone Functions (android.py)","text":"

    When using the minimal android module:

    "},{"location":"qsl4a/core/android-base/#jsla","title":"jsla()","text":"

    Send JSON-RPC request and return raw response.

    jsla(method, *params)\n

    Returns: JSON string response

    "},{"location":"qsl4a/core/android-base/#rsla","title":"rsla()","text":"

    Send request and return result only.

    rsla(method, *params)\n

    Returns: Result value from RPC call

    "},{"location":"qsl4a/core/android-base/#esla","title":"esla()","text":"

    Send request, raise exception on error.

    esla(method, *params)\n

    Raises: Exception if error field is not None

    "},{"location":"qsl4a/core/android-base/#nsla","title":"nsla()","text":"

    Send request and return Result namedtuple.

    nsla(method, *params)\n

    Returns: Result namedtuple

    "},{"location":"qsl4a/core/android-base/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/android-base/#basic-connection","title":"Basic Connection","text":"
    import androidhelper\n\n# Connect to Android runtime\ndroid = androidhelper.Android()\n\n# Check connection by showing toast\ndroid.makeToast(\"Connected!\")\n
    "},{"location":"qsl4a/core/android-base/#error-handling","title":"Error Handling","text":"
    result = droid.someMethod()\nif result.error:\n    print(f\"Error: {result.error}\")\nelse:\n    print(f\"Success: {result.result}\")\n
    "},{"location":"qsl4a/core/android-base/#direct-rpc-call","title":"Direct RPC Call","text":"
    # Call any method directly\nresult = droid._rpc(\"makeToast\", \"Hello World\")\n
    "},{"location":"qsl4a/core/events/","title":"Event System","text":"

    QSL4A provides an event system for handling asynchronous events from Android, such as sensor updates, location changes, and custom broadcasts.

    "},{"location":"qsl4a/core/events/#event-basics","title":"Event Basics","text":"

    Events are stored in a buffer and can be polled or waited for. Each event has: - name: Event type/name - data: Event payload data - time: Timestamp

    "},{"location":"qsl4a/core/events/#event-methods","title":"Event Methods","text":""},{"location":"qsl4a/core/events/#eventclearbuffer","title":"eventClearBuffer()","text":"

    Clear all pending events from the buffer.

    eventClearBuffer()\n

    Returns: None

    "},{"location":"qsl4a/core/events/#eventpoll","title":"eventPoll()","text":"

    Poll for events in the buffer.

    eventPoll(number_of_events=1)\n

    Parameters: - number_of_events (int): Maximum events to retrieve (default: 1)

    Returns: List of event objects

    "},{"location":"qsl4a/core/events/#eventwait","title":"eventWait()","text":"

    Wait for any event.

    eventWait(timeout=None)\n

    Parameters: - timeout (int, optional): Timeout in seconds. None = wait forever

    Returns: Event object or None if timeout

    "},{"location":"qsl4a/core/events/#eventwaitfor","title":"eventWaitFor()","text":"

    Wait for a specific event.

    eventWaitFor(eventName, timeout=None)\n

    Parameters: - eventName (str): Name of event to wait for - timeout (int, optional): Timeout in seconds

    Returns: Event object or None if timeout

    "},{"location":"qsl4a/core/events/#eventpost","title":"eventPost()","text":"

    Post a custom event.

    eventPost(name, data, enqueue=None)\n

    Parameters: - name (str): Event name - data: Event data (any type) - enqueue (bool, optional): Add to queue if True

    "},{"location":"qsl4a/core/events/#receiveevent","title":"receiveEvent()","text":"

    Receive event (blocking).

    receiveEvent()\n

    Returns: Event object

    "},{"location":"qsl4a/core/events/#broadcast-events","title":"Broadcast Events","text":"

    Register for system broadcast events.

    "},{"location":"qsl4a/core/events/#eventregisterforbroadcast","title":"eventRegisterForBroadcast()","text":"

    Register to receive broadcast events.

    eventRegisterForBroadcast(category, enqueue=True)\n

    Parameters: - category (str): Broadcast category/action - enqueue (bool): Add to event queue

    "},{"location":"qsl4a/core/events/#eventunregisterforbroadcast","title":"eventUnregisterForBroadcast()","text":"

    Unregister from broadcast events.

    eventUnregisterForBroadcast(category)\n
    "},{"location":"qsl4a/core/events/#eventgetbrodcastcategories","title":"eventGetBrodcastCategories()","text":"

    Get registered broadcast categories.

    eventGetBrodcastCategories()\n

    Returns: List of registered categories

    "},{"location":"qsl4a/core/events/#event-dispatcher","title":"Event Dispatcher)","text":""},{"location":"qsl4a/core/events/#starteventdispatcher","title":"startEventDispatcher()","text":"

    Opens up a socket where you can read for events posted.)

    startEventDispatcher(port=0)\n

    Parameters: - port (int, optional): Port to listen on (default: 0 = auto-select)

    Returns: Port number being listened on

    "},{"location":"qsl4a/core/events/#stopeventdispatcher","title":"stopEventDispatcher()","text":"

    Stops the event server.)

    stopEventDispatcher()\n
    "},{"location":"qsl4a/core/events/#deprecated-methods","title":"Deprecated Methods","text":""},{"location":"qsl4a/core/events/#rpcpostevent","title":"rpcPostEvent()","text":"

    Post an event to the event queue. (Deprecated, use eventPost)

    rpcPostEvent(name, data)\n

    Parameters: - name (str): Event name - data: Event data

    "},{"location":"qsl4a/core/events/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/events/#basic-event-polling","title":"Basic Event Polling","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Clear old events\ndroid.eventClearBuffer()\n\n# Poll for events\nevents = droid.eventPoll(5).result\nfor event in events:\n    print(f\"Event: {event['name']}, Data: {event['data']}\")\n
    "},{"location":"qsl4a/core/events/#waiting-for-events","title":"Waiting for Events","text":"
    # Wait for any event with timeout\nevent = droid.eventWait(timeout=10).result\nif event:\n    print(f\"Got event: {event['name']}\")\n
    "},{"location":"qsl4a/core/events/#waiting-for-specific-event","title":"Waiting for Specific Event","text":"
    # Wait for sensor event\nevent = droid.eventWaitFor('screen', timeout=5).result\nif event:\n    print(f\"Screen event: {event['data']}\")\n
    "},{"location":"qsl4a/core/events/#posting-custom-events","title":"Posting Custom Events","text":"
    # Post custom event\ndroid.eventPost('my_event', {'key': 'value'})\n\n# Wait for it\nevent = droid.eventWaitFor('my_event', timeout=1).result\n
    "},{"location":"qsl4a/core/events/#broadcast-receiver","title":"Broadcast Receiver","text":"
    # Register for screen on/off events\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_ON')\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_OFF')\n\n# Wait for screen events\nwhile True:\n    event = droid.receiveEvent().result\n    if event['name'] == 'android.intent.action.SCREEN_ON':\n        print(\"Screen turned on\")\n    elif event['name'] == 'android.intent.action.SCREEN_OFF':\n        print(\"Screen turned off\")\n
    "},{"location":"qsl4a/core/events/#sensor-event-handling","title":"Sensor Event Handling","text":"
    # Start sensing\ndroid.startSensingTimed(1, 250)\n\n# Process sensor events\nfor _ in range(100):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'sensors':\n        data = event['data']\n        print(f\"Accel: {data['xforce']}, {data['yforce']}, {data['zforce']}\")\n\ndroid.stopSensing()\n
    "},{"location":"qsl4a/core/events/#common-event-types","title":"Common Event Types","text":"Event Name Description Source sensors Sensor data update startSensing* location GPS location update startLocating phone Phone state change startTrackingPhoneState signal Signal strength change startTrackingSignalStrength screen Screenshot ready fullGetScreenShot dialog Dialog response dialogShow*"},{"location":"qsl4a/core/events/#event-data-structure","title":"Event Data Structure","text":"
    {\n    'name': 'event_name',\n    'data': {\n        # Event-specific data\n    },\n    'time': 1234567890  # Timestamp\n}\n
    "},{"location":"qsl4a/core/intent/","title":"Intent System","text":"

    Android Intents are used to start activities, send broadcasts, and communicate between apps. QSL4A provides full Intent support through the Intent module.

    "},{"location":"qsl4a/core/intent/#module-import","title":"Module Import","text":"
    import androidhelper\ndon = androidhelper.Android()\n
    "},{"location":"qsl4a/core/intent/#intent-constants","title":"Intent Constants","text":"

    Access via droid.Intent:

    "},{"location":"qsl4a/core/intent/#actions","title":"Actions","text":"Constant Value Usage ACTION_MAIN android.intent.action.MAIN App entry point ACTION_VIEW android.intent.action.VIEW View content ACTION_EDIT android.intent.action.EDIT Edit content ACTION_PICK android.intent.action.PICK Pick item ACTION_SEND android.intent.action.SEND Share content ACTION_SEARCH android.intent.action.SEARCH Search"},{"location":"qsl4a/core/intent/#flags","title":"Flags","text":"Constant Value Usage FLAG_ACTIVITY_NEW_TASK 268435456 Start new task FLAG_ACTIVITY_CLEAR_TASK 32768 Clear task stack FLAG_ACTIVITY_NEW_DOCUMENT 524288 New document mode"},{"location":"qsl4a/core/intent/#extras","title":"Extras","text":"Constant Usage EXTRA_TEXT Text content EXTRA_STREAM File URI EXTRA_SUBJECT Subject line EXTRA_EMAIL Email address"},{"location":"qsl4a/core/intent/#core-methods","title":"Core Methods","text":""},{"location":"qsl4a/core/intent/#makeintent","title":"makeIntent()","text":"

    Create an Intent object.

    makeIntent(action, uri=None, type=None, extras=None, categories=None,\n           packagename=None, classname=None, flags=None)\n

    Parameters: - action (str): Intent action (e.g., droid.Intent.ACTION_VIEW) - uri (str, optional): Data URI - type (str, optional): MIME type - extras (dict, optional): Extra data - categories (list, optional): Intent categories - packagename (str, optional): Target package - classname (str, optional): Target class - flags (int, optional): Intent flags

    Returns: Intent object

    "},{"location":"qsl4a/core/intent/#startactivityintent","title":"startActivityIntent()","text":"

    Start an Activity with an Intent.

    startActivityIntent(intent, wait=None)\n

    Parameters: - intent: Intent object from makeIntent() - wait (bool, optional): Block until activity closes

    "},{"location":"qsl4a/core/intent/#startactivityforresultintent","title":"startActivityForResultIntent()","text":"

    Start activity and wait for result.

    startActivityForResultIntent(intent)\n

    Returns: Activity result

    "},{"location":"qsl4a/core/intent/#sendbroadcastintent","title":"sendBroadcastIntent()","text":"

    Send a broadcast.

    sendBroadcastIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#view","title":"view()","text":"

    View content by URI.

    view(uri, type=None, extras=None)\n
    "},{"location":"qsl4a/core/intent/#pick","title":"pick()","text":"

    Pick content from URI.

    pick(uri)\n
    "},{"location":"qsl4a/core/intent/#common-intent-methods","title":"Common Intent Methods)","text":""},{"location":"qsl4a/core/intent/#scanbarcode","title":"scanBarcode()","text":"

    Launch the barcode scanner.

    scanBarcode()\n

    Returns: Scanned barcode string

    "},{"location":"qsl4a/core/intent/#send","title":"send()","text":"

    Send content via share intent.

    send(type, content)\n

    Parameters: - type (str): MIME type - content (str): Content to share

    "},{"location":"qsl4a/core/intent/#sendtext","title":"sendText()","text":"

    Send text content.

    sendText(text)\n

    Parameters: - text (str): Text to send

    "},{"location":"qsl4a/core/intent/#sendemail","title":"sendEmail()","text":"

    Send an email.

    sendEmail(to, subject, body, attachment=None)\n

    Parameters: - to (str or list): Recipient email address(es) - subject (str): Email subject - body (str): Email body - attachment (str, optional): Attachment file path

    "},{"location":"qsl4a/core/intent/#pathtouri","title":"pathToUri()","text":"

    Convert file path to content URI.

    pathToUri(path)\n

    Parameters: - path (str): File path

    Returns: Content URI string

    "},{"location":"qsl4a/core/intent/#openfile","title":"openFile()","text":"

    Open a file with appropriate app.

    openFile(path)\n

    Parameters: - path (str): File path to open

    "},{"location":"qsl4a/core/intent/#sendfile","title":"sendFile()","text":"

    Send a file via share intent.

    sendFile(path)\n

    Parameters: - path (str): File path to send

    "},{"location":"qsl4a/core/intent/#getpathtype","title":"getPathType()","text":"

    Get the MIME type for a file path.

    getPathType(path)\n

    Parameters: - path (str): File path

    Returns: MIME type string

    "},{"location":"qsl4a/core/intent/#viewmap","title":"viewMap()","text":"

    Open map at a location.

    viewMap(latitude, longitude)\n

    Parameters: - latitude (float): Latitude - longitude (float): Longitude

    "},{"location":"qsl4a/core/intent/#viewcontacts","title":"viewContacts()","text":"

    Open the contacts app.

    viewContacts()\n
    "},{"location":"qsl4a/core/intent/#search","title":"search()","text":"

    Perform a web search.

    search(query)\n

    Parameters: - query (str): Search query

    "},{"location":"qsl4a/core/intent/#viewhtml","title":"viewHtml()","text":"

    View HTML content.

    viewHtml(content, encoding=None)\n

    Parameters: - content (str): HTML content - encoding (str, optional): Character encoding

    "},{"location":"qsl4a/core/intent/#webviewshow","title":"webViewShow()","text":"

    Display web content in WebView. Deprecated, use viewHtml.

    webViewShow(url)\n

    Parameters: - url (str): Web page URL

    "},{"location":"qsl4a/core/intent/#editoropen","title":"editorOpen()","text":"

    Open a text editor.

    editorOpen(path=None, create=False)\n

    Parameters: - path (str, optional): File path to edit - create (bool, optional): Create if doesn't exist

    "},{"location":"qsl4a/core/intent/#helper-class-uri","title":"Helper Class: Uri","text":"

    Create URI objects for Intents:

    from androidhelper.Intent import Uri\n\nuri = Uri(\"file:///sdcard/test.txt\")\n
    "},{"location":"qsl4a/core/intent/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/intent/#open-web-page","title":"Open Web Page","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"http://www.example.com\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#share-text","title":"Share Text","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_TEXT: \"Hello from QPython!\",\n        droid.Intent.EXTRA_SUBJECT: \"Test\"\n    },\n    type=\"text/plain\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#open-file","title":"Open File","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"file:///sdcard/document.pdf\",\n    type=\"application/pdf\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#pick-contact","title":"Pick Contact","text":"
    result = droid.pickContact()\ncontact_uri = result.result\n
    "},{"location":"qsl4a/core/intent/#send-email","title":"Send Email","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_EMAIL: [\"test@example.com\"],\n        droid.Intent.EXTRA_SUBJECT: \"Hello\",\n        droid.Intent.EXTRA_TEXT: \"Message body\"\n    },\n    type=\"message/rfc822\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#open-app","title":"Open App","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_MAIN,\n    packagename=\"com.android.settings\",\n    classname=\"com.android.settings.Settings\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/hardware/bluetooth/","title":"Bluetooth API","text":"

    Control Bluetooth adapter and communicate with Bluetooth devices.

    "},{"location":"qsl4a/hardware/bluetooth/#adapter-control","title":"Adapter Control","text":""},{"location":"qsl4a/hardware/bluetooth/#togglebluetoothstate","title":"toggleBluetoothState()","text":"

    Turn Bluetooth on/off.

    toggleBluetoothState(enabled=None, prompt=True)\n

    Parameters: - enabled (bool): True=on, False=off, None=toggle - prompt (bool): Show user prompt

    "},{"location":"qsl4a/hardware/bluetooth/#checkbluetoothstate","title":"checkBluetoothState()","text":"

    Check if Bluetooth is enabled.

    checkBluetoothState()\n

    Returns: True/False

    "},{"location":"qsl4a/hardware/bluetooth/#getlocalname","title":"GetLocalName()","text":"

    Get Bluetooth device name.

    GetLocalName()\n
    "},{"location":"qsl4a/hardware/bluetooth/#setlocalname","title":"SetLocalName()","text":"

    Set Bluetooth device name.

    SetLocalName(name)\n
    "},{"location":"qsl4a/hardware/bluetooth/#getscanmode","title":"GetScanMode()","text":"

    Get discoverability mode.

    GetScanMode()\n

    Returns: - -1: Disabled - 0: Non-discoverable, non-connectable - 1: Connectable, non-discoverable - 3: Connectable and discoverable

    "},{"location":"qsl4a/hardware/bluetooth/#makediscoverable","title":"MakeDiscoverable()","text":"

    Make device discoverable.

    MakeDiscoverable(duration=300)\n

    Parameters: - duration (int): Seconds to be discoverable

    "},{"location":"qsl4a/hardware/bluetooth/#discovery","title":"Discovery","text":""},{"location":"qsl4a/hardware/bluetooth/#discoverystart","title":"DiscoveryStart()","text":"

    Start device discovery.

    DiscoveryStart()\n
    "},{"location":"qsl4a/hardware/bluetooth/#discoverycancel","title":"DiscoveryCancel()","text":"

    Cancel discovery.

    DiscoveryCancel()\n
    "},{"location":"qsl4a/hardware/bluetooth/#getreceiveddevices","title":"GetReceivedDevices()","text":"

    Get discovered devices.

    GetReceivedDevices()\n

    Returns: List of device info dicts

    "},{"location":"qsl4a/hardware/bluetooth/#getbondeddevices","title":"GetBondedDevices()","text":"

    Get paired devices.

    GetBondedDevices()\n

    Returns: List of paired device info

    "},{"location":"qsl4a/hardware/bluetooth/#connection","title":"Connection","text":""},{"location":"qsl4a/hardware/bluetooth/#connect","title":"Connect()","text":"

    Connect to a device.

    Connect(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", address=None)\n

    Parameters: - uuid (str): Service UUID - address (str): Device address (None = show picker)

    Returns: True if successful

    "},{"location":"qsl4a/hardware/bluetooth/#accept","title":"Accept()","text":"

    Accept incoming connection.

    Accept(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", timeout=0)\n
    "},{"location":"qsl4a/hardware/bluetooth/#activeconnections","title":"ActiveConnections()","text":"

    Check active connections.

    ActiveConnections()\n
    "},{"location":"qsl4a/hardware/bluetooth/#stop","title":"Stop()","text":"

    Disconnect.

    Stop(connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#communication","title":"Communication","text":""},{"location":"qsl4a/hardware/bluetooth/#write","title":"Write()","text":"

    Send ASCII data.

    Write(ascii, connID=\"\")\n
    "},{"location":"qsl4a/hardware/bluetooth/#writebinary","title":"WriteBinary()","text":"

    Send binary data (base64 encoded).

    WriteBinary(base64, connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#read","title":"Read()","text":"

    Read ASCII data.

    Read(bufferSize=4096, connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#readbinary","title":"ReadBinary()","text":"

    Read binary data.

    ReadBinary(bufferSize=4096, connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#readline","title":"ReadLine()","text":"

    Read line.

    ReadLine(connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#readready","title":"ReadReady()","text":"

    Check if data available.

    ReadReady(connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Enable Bluetooth\ndroid.toggleBluetoothState(True)\n\n# Get paired devices\ndevices = droid.GetBondedDevices().result\nfor dev in devices:\n    print(f\"{dev['name']}: {dev['address']}\")\n\n# Connect to device\ndroid.Connect(address=\"00:11:22:33:44:55\")\n\n# Send data\ndroid.Write(\"Hello Bluetooth!\")\n\n# Read response\ndata = droid.Read(1024).result\n
    "},{"location":"qsl4a/hardware/camera/","title":"Camera API","text":"

    Capture photos and record video.

    "},{"location":"qsl4a/hardware/camera/#photo-capture","title":"Photo Capture","text":""},{"location":"qsl4a/hardware/camera/#takepicture","title":"takePicture()","text":"

    Take a photo using the default camera.

    takePicture(path=None)\n

    Parameters: - path (str, optional): Save path. If None, returns image data

    Returns: Image path or image data

    "},{"location":"qsl4a/hardware/camera/#cameracapturepicture","title":"cameraCapturePicture()","text":"

    Capture picture with advanced camera controls.

    cameraCapturePicture(targetPath=None, cameraId=0, useAutoFocus=True)\n

    Parameters: - targetPath (str, optional): Save path - cameraId (int): Camera to use (0 = back, 1 = front) - useAutoFocus (bool): Enable auto focus

    Returns: Captured image path

    "},{"location":"qsl4a/hardware/camera/#camerasettorchmode","title":"cameraSetTorchMode()","text":"

    Control camera flashlight/torch.

    cameraSetTorchMode(enabled)\n

    Parameters: - enabled (bool): True to turn on, False to turn off

    Returns: True if successful

    "},{"location":"qsl4a/hardware/camera/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

    Capture screenshot.

    imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

    Parameters: - path (str, optional): Save path - delayMilliSec (int): Delay before capture

    "},{"location":"qsl4a/hardware/camera/#video-recording","title":"Video Recording","text":""},{"location":"qsl4a/hardware/camera/#takevideo","title":"takeVideo()","text":"

    Record video using default settings.

    takeVideo(path=None, quality=1)\n

    Parameters: - path (str, optional): Save path - quality (int): Video quality (0-4) - 0: 160x120 - 1: 320x240 - 2: 352x288 - 3: 640x480 - 4: 800x480

    "},{"location":"qsl4a/hardware/camera/#recordercapturevideo","title":"recorderCaptureVideo()","text":"

    Capture video with advanced controls.

    recorderCaptureVideo(targetPath=None, duration=10, cameraId=0, quality=8)\n

    Parameters: - targetPath (str, optional): Save path - duration (int): Recording duration in seconds (default: 10) - cameraId (int): Camera to use (0 = back, 1 = front) - quality (int): Video quality (0-8, higher is better)

    Returns: Video file path

    "},{"location":"qsl4a/hardware/camera/#recordaudio","title":"recordAudio()","text":"

    Record audio.

    recordAudio()\n

    Returns: Audio file path

    "},{"location":"qsl4a/hardware/camera/#screen-recording","title":"Screen Recording","text":""},{"location":"qsl4a/hardware/camera/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

    Start screen recording.

    recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

    Parameters: - path (str): Save path - audio (int): Audio source (0=none, 1=mic, 2=internal) - targetPixels (int): Resolution - frameRate (int): FPS - bitRate (int): Bitrate - rotation (bool): Rotate output - autoStart (bool): Start immediately

    "},{"location":"qsl4a/hardware/camera/#recorderstart","title":"recorderStart()","text":"

    Start recording.

    recorderStart()\n
    "},{"location":"qsl4a/hardware/camera/#recorderpause","title":"recorderPause()","text":"

    Pause recording.

    recorderPause()\n
    "},{"location":"qsl4a/hardware/camera/#recorderresume","title":"recorderResume()","text":"

    Resume recording.

    recorderResume()\n
    "},{"location":"qsl4a/hardware/camera/#audio-volume-detection","title":"Audio Volume Detection","text":""},{"location":"qsl4a/hardware/camera/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

    Start volume detection.

    recorderSoundVolumeDetect(interval=100)\n
    "},{"location":"qsl4a/hardware/camera/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

    Get current volume in dB.

    recorderSoundVolumeGetDb()\n
    "},{"location":"qsl4a/hardware/camera/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Take photo with default camera\nphoto_path = droid.takePicture(\"/sdcard/photo.jpg\").result\nprint(f\"Photo saved: {photo_path}\")\n\n# Take photo with front camera and auto focus\ncamera_path = droid.cameraCapturePicture(\"/sdcard/selfie.jpg\", cameraId=1, useAutoFocus=True).result\nprint(f\"Front camera photo: {camera_path}\")\n\n# Control flashlight\ndroid.cameraSetTorchMode(True)  # Turn on flashlight\n\n# Record video with default settings\nvideo_path = droid.takeVideo(\"/sdcard/video.mp4\", quality=3).result\nprint(f\"Video saved: {video_path}\")\n\n# Record video with advanced controls\nvideo_path = droid.recorderCaptureVideo(\"/sdcard/movie.mp4\", duration=30, cameraId=0, quality=8).result\n\n# Screenshot\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n
    "},{"location":"qsl4a/hardware/recorder/","title":"Audio Recorder API","text":"

    Record audio from microphone and device screen.

    "},{"location":"qsl4a/hardware/recorder/#audio-recording","title":"Audio Recording","text":""},{"location":"qsl4a/hardware/recorder/#recordaudio","title":"recordAudio()","text":"

    Record audio from microphone.

    recordAudio()\n

    Returns: Path to recorded audio file

    "},{"location":"qsl4a/hardware/recorder/#recorderstartmicrophone","title":"recorderStartMicrophone()","text":"

    Start recording from microphone to a specific file.

    recorderStartMicrophone(targetPath=None)\n

    Parameters: - targetPath (str, optional): Path to save the recording

    "},{"location":"qsl4a/hardware/recorder/#screen-recording","title":"Screen Recording","text":""},{"location":"qsl4a/hardware/recorder/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

    Start screen recording with audio.

    recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

    Parameters: - path (str): Save path for video file - audio (int): Audio source (0=none, 1=mic, 2=internal audio) - targetPixels (int): Target resolution in pixels - frameRate (int): Frames per second (default: 30) - bitRate (int): Video bitrate - rotation (bool): Rotate output video - autoStart (bool): Start recording immediately

    Returns: Result of operation

    "},{"location":"qsl4a/hardware/recorder/#recorderstart","title":"recorderStart()","text":"

    Start the screen recording (when autoStart=False).

    recorderStart()\n
    "},{"location":"qsl4a/hardware/recorder/#recorderpause","title":"recorderPause()","text":"

    Pause ongoing screen recording.

    recorderPause()\n
    "},{"location":"qsl4a/hardware/recorder/#recorderresume","title":"recorderResume()","text":"

    Resume paused screen recording.

    recorderResume()\n
    "},{"location":"qsl4a/hardware/recorder/#audio-volume-detection","title":"Audio Volume Detection","text":""},{"location":"qsl4a/hardware/recorder/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

    Start monitoring sound volume level.

    recorderSoundVolumeDetect(interval=100)\n

    Parameters: - interval (int): Detection interval in milliseconds (default: 100)

    "},{"location":"qsl4a/hardware/recorder/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

    Get current sound volume in decibels.

    recorderSoundVolumeGetDb()\n

    Returns: Current volume level in dB

    "},{"location":"qsl4a/hardware/recorder/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Record audio from microphone\nprint(\"Recording audio...\")\naudio_path = droid.recordAudio().result\nprint(f\"Saved to: {audio_path}\")\n\n# Record microphone to specific file\ndroid.recorderStartMicrophone(\"/sdcard/my_recording.mp3\")\ntime.sleep(5)\ndroid.recorderStop()\n\n# Record screen with audio\nprint(\"Starting screen recording...\")\ndroid.recorderStartScreenRecord(\n    path=\"/sdcard/screen_record.mp4\",\n    audio=1,\n    frameRate=30,\n    autoStart=True\n)\ntime.sleep(10)\ndroid.recorderStop()\n\n# Monitor sound volume\ndroid.recorderSoundVolumeDetect(interval=100)\ntime.sleep(3)\nvolume = droid.recorderSoundVolumeGetDb().result\nprint(f\"Current volume: {volume} dB\")\n
    "},{"location":"qsl4a/hardware/usbserial/","title":"USB Host Serial API","text":"

    Communicate with USB serial devices (requires USB OTG support and Android 3.1+).

    "},{"location":"qsl4a/hardware/usbserial/#usb-serial-methods","title":"USB Serial Methods)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialopen","title":"usbHostSerialOpen()","text":"

    Open a connection to a USB serial device.

    usbHostSerialOpen(device, baudRate=9600)\n

    Parameters: - device (str): USB device path or identifier - baudRate (int): Baud rate (default: 9600)

    Returns: True if opened successfully

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialclose","title":"usbHostSerialClose()","text":"

    Close the USB serial connection.

    usbHostSerialClose()\n
    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialread","title":"usbHostSerialRead()","text":"

    Read data from USB serial.

    usbHostSerialRead(bufferSize=1024)\n

    Parameters: - bufferSize (int): Maximum bytes to read (default: 1024)

    Returns: String read data

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwrite","title":"usbHostSerialWrite()","text":"

    Write data to USB serial.

    usbHostSerialWrite(data)\n

    Parameters: - data (str): String data to write

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialavailable","title":"usbHostSerialAvailable()","text":"

    Check if data is available to read.

    usbHostSerialAvailable()\n

    Returns: Number of bytes available

    "},{"location":"qsl4a/hardware/usbserial/#configuration-methods","title":"Configuration Methods)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetbaudrate","title":"usbHostSerialSetBaudRate()","text":"

    Set the baud rate.

    usbHostSerialSetBaudRate(baudRate)\n

    Parameters: - baudRate (int): Baud rate

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetdatabits","title":"usbHostSerialSetDataBits()","text":"

    Set data bits (5, 6, 7, or 8).

    usbHostSerialSetDataBits(dataBits)\n

    Parameters: - dataBits (int): Data bits (5-8)

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetstopbits","title":"usbHostSerialSetStopBits()","text":"

    Set stop bits (1, 1.5, or 2).

    usbHostSerialSetStopBits(stopBits)\n

    Parameters: - stopBits (float): Stop bits (1, 1.5, or 2)

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetparity","title":"usbHostSerialSetParity()","text":"

    Set parity (none, odd, even, mark, space).

    usbHostSerialSetParity(parity)\n

    Parameters: - parity (str): Parity mode ('none', 'odd', 'even', 'mark', 'space')

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetflowcontrol","title":"usbHostSerialSetFlowControl()","text":"

    Set flow control (none, hardware, software).

    usbHostSerialSetFlowControl(flowControl)\n

    Parameters: - flowControl (str): Flow control mode ('none', 'hardware', 'software')

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialreadhex","title":"usbHostSerialReadHex()","text":"

    Read data as hex string.

    usbHostSerialReadHex(bufferSize=1024)\n

    Parameters: - bufferSize (int): Maximum bytes to read

    Returns: Hex string

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwritehex","title":"usbHostSerialWriteHex()","text":"

    Write data from hex string.

    usbHostSerialWriteHex(hexString)\n

    Parameters: - hexString (str): Hex string to write

    "},{"location":"qsl4a/hardware/usbserial/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Open USB serial connection\nif droid.usbHostSerialOpen(\"/dev/bus/usb/001/001\", 115200).result:\n    print(\"USB serial opened\")\n\n    # Write data\n    droid.usbHostSerialWrite(\"AT\\r\")\n\n    # Read response\n    response = droid.usbHostSerialRead(1024).result\n    print(f\"Response: {response}\")\n\n    # Or use hex\n    droid.usbHostSerialWriteHex(\"41540D0A\")  # \"AT\\r\\n\"\n\n    # Close connection\n    droid.usbHostSerialClose()\n

    Note: USB serial requires: - Android 3.1+ (API 12) - USB OTG cable/adapter - USB host mode support on device - Compatible serial device

    "},{"location":"qsl4a/hardware/webcam/","title":"Webcam API","text":"

    Stream video from the device camera using MJPEG.

    "},{"location":"qsl4a/hardware/webcam/#mjpeg-stream-methods","title":"MJPEG Stream Methods","text":""},{"location":"qsl4a/hardware/webcam/#webcamstart","title":"webcamStart()","text":"

    Start an MJPEG stream from the webcam.

    webcamStart(resolutionLevel=0, jpegQuality=20, port=0)\n

    Parameters: - resolutionLevel (int): Resolution level (default: 0) - jpegQuality (int): JPEG quality 1-100 (default: 20) - port (int): Port number (default: 0 = auto)

    Returns: Tuple of (address, port) for the stream

    "},{"location":"qsl4a/hardware/webcam/#webcamadjustquality","title":"webcamAdjustQuality()","text":"

    Adjust the quality of an active webcam stream.

    webcamAdjustQuality(resolutionLevel=0, jpegQuality=20)\n

    Parameters: - resolutionLevel (int): Resolution level - jpegQuality (int): JPEG quality 1-100

    "},{"location":"qsl4a/hardware/webcam/#webcamstop","title":"webcamStop()","text":"

    Stop the webcam stream.

    webcamStop()\n
    "},{"location":"qsl4a/hardware/webcam/#camera-preview-methods","title":"Camera Preview Methods","text":""},{"location":"qsl4a/hardware/webcam/#camerastartpreview","title":"cameraStartPreview()","text":"

    Start camera preview mode with event generation.

    cameraStartPreview(resolutionLevel=0, jpegQuality=20, filepath=None)\n

    Parameters: - resolutionLevel (int): Resolution level (default: 0) - jpegQuality (int): JPEG quality (default: 20) - filepath (str, optional): File path to save preview frames

    Returns: True if successful

    Note: Generates 'preview' events with frame data.

    "},{"location":"qsl4a/hardware/webcam/#camerastoppreview","title":"cameraStopPreview()","text":"

    Stop the camera preview.

    cameraStopPreview()\n
    "},{"location":"qsl4a/hardware/webcam/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start webcam stream\nstream_info = droid.webcamStart(\n    resolutionLevel=0,\n    jpegQuality=30,\n    port=8080\n).result\nprint(f\"Stream available at {stream_info[0]}:{stream_info[1]}\")\n\n# Adjust quality while streaming\ntime.sleep(5)\ndroid.webcamAdjustQuality(resolutionLevel=1, jpegQuality=50)\n\n# Stop when done\ndroid.webcamStop()\n\n# Or use preview mode\nprint(\"Starting preview...\")\ndroid.cameraStartPreview()\n\n# Wait for preview events\nfor i in range(10):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'preview':\n        print(f\"Got preview frame: {event['data']}\")\n\ndroid.cameraStopPreview()\n
    "},{"location":"qsl4a/media/image/","title":"Image Processing API","text":"

    Compress and process images.

    "},{"location":"qsl4a/media/image/#image-compression","title":"Image Compression","text":""},{"location":"qsl4a/media/image/#imagecompress","title":"imageCompress()","text":"

    Compress image file.

    imageCompress(srcPath, destPath, targetByteSize=0, targetWidth=0, targetHeight=0)\n

    Parameters: - srcPath (str): Source image path - destPath (str): Output path - targetByteSize (int): Target file size in bytes (0 = no limit) - targetWidth (int): Target width (0 = original) - targetHeight (int): Target height (0 = original)

    Returns: Compressed image path

    "},{"location":"qsl4a/media/image/#screenshot","title":"Screenshot","text":""},{"location":"qsl4a/media/image/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

    Capture screen.

    imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

    Parameters: - path (str): Save path - delayMilliSec (int): Delay before capture

    Returns: Screenshot path

    "},{"location":"qsl4a/media/image/#video-playback","title":"Video Playback","text":""},{"location":"qsl4a/media/image/#videoplay","title":"videoPlay()","text":"

    Play video file in fullscreen mode.

    videoPlay(path, wait=True)\n

    Parameters: - path (str): Video file path - wait (bool): Wait for playback to complete (default: True)

    "},{"location":"qsl4a/media/image/#barcode-scanning","title":"Barcode Scanning","text":""},{"location":"qsl4a/media/image/#scanbarcodefromimage","title":"scanBarcodeFromImage()","text":"

    Scan barcode/QR code from image file.

    scanBarcodeFromImage(path, compressRatio=0, x=0, y=0, width=0, height=0)\n

    Parameters: - path (str): Image file path - compressRatio (int): Compression ratio (0 = no compression) - x, y, width, height (int): Region to scan (0 = full image)

    Returns: Scanned barcode content

    "},{"location":"qsl4a/media/image/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Take screenshot\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n\n# Compress image\ncompressed = droid.imageCompress(\n    \"/sdcard/large_photo.jpg\",\n    \"/sdcard/compressed.jpg\",\n    targetByteSize=102400,  # Target ~100KB\n    targetWidth=1920,\n    targetHeight=1080\n).result\nprint(f\"Saved: {compressed}\")\n\n# Play video\nvideo_path = \"/sdcard/movie.mp4\"\ndroid.videoPlay(video_path, wait=True)\n\n# Scan barcode from image\nresult = droid.scanBarcodeFromImage(\"/sdcard/qr_code.png\").result\nprint(f\"Barcode: {result}\")\n
    "},{"location":"qsl4a/media/mediaplayer/","title":"Media Player API","text":"

    Control audio and video playback.

    "},{"location":"qsl4a/media/mediaplayer/#playback-control","title":"Playback Control","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplay","title":"mediaPlay()","text":"

    Play media file.

    mediaPlay(url, tag=\"default\", play=True)\n

    Parameters: - url (str): Media file path or URL - tag (str): Player identifier - play (bool): Auto-start playback

    "},{"location":"qsl4a/media/mediaplayer/#mediaplaystart","title":"mediaPlayStart()","text":"

    Start playback.

    mediaPlayStart(tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#mediaplaypause","title":"mediaPlayPause()","text":"

    Pause playback.

    mediaPlayPause(tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#mediaplayclose","title":"mediaPlayClose()","text":"

    Close player.

    mediaPlayClose(tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#mediaplayseek","title":"mediaPlaySeek()","text":"

    Seek to position.

    mediaPlaySeek(msec, tag=\"default\")\n

    Parameters: - msec (int): Position in milliseconds

    "},{"location":"qsl4a/media/mediaplayer/#mediaplaysetlooping","title":"mediaPlaySetLooping()","text":"

    Set loop mode.

    mediaPlaySetLooping(enabled, tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#player-info","title":"Player Info","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplayinfo","title":"mediaPlayInfo()","text":"

    Get playback info.

    mediaPlayInfo(tag=\"default\")\n

    Returns: Dict with duration, position, etc.

    "},{"location":"qsl4a/media/mediaplayer/#mediaisplaying","title":"mediaIsPlaying()","text":"

    Check if playing.

    mediaIsPlaying(tag=\"default\")\n

    Returns: True/False

    "},{"location":"qsl4a/media/mediaplayer/#mediaplaylist","title":"mediaPlayList()","text":"

    List active players.

    mediaPlayList()\n
    "},{"location":"qsl4a/media/mediaplayer/#volume-control","title":"Volume Control","text":""},{"location":"qsl4a/media/mediaplayer/#getmediavolume","title":"getMediaVolume()","text":"

    Get media volume.

    getMediaVolume()\n

    Returns: Volume level (0-15)

    "},{"location":"qsl4a/media/mediaplayer/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

    Get max media volume.

    getMaxMediaVolume()\n
    "},{"location":"qsl4a/media/mediaplayer/#getringervolume","title":"getRingerVolume()","text":"

    Get ringer volume.

    getRingerVolume()\n
    "},{"location":"qsl4a/media/mediaplayer/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

    Get max ringer volume.

    getMaxRingerVolume()\n
    "},{"location":"qsl4a/media/mediaplayer/#video-playback","title":"Video Playback","text":""},{"location":"qsl4a/media/mediaplayer/#videoplay","title":"videoPlay()","text":"

    Play video fullscreen.

    videoPlay(path, wait=True)\n

    Parameters: - path (str): Video file path - wait (bool): Wait for playback to complete

    "},{"location":"qsl4a/media/mediaplayer/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Play audio\ndroid.mediaPlay(\"/sdcard/music.mp3\", tag=\"music\")\n\n# Check status\nif droid.mediaIsPlaying(\"music\").result:\n    info = droid.mediaPlayInfo(\"music\").result\n    print(f\"Playing: {info}\")\n\n# Seek to 30 seconds\ndroid.mediaPlaySeek(30000, \"music\")\n\n# Close\ndroid.mediaPlayClose(\"music\")\n\n# Play video\ndroid.videoPlay(\"/sdcard/movie.mp4\", wait=True)\n
    "},{"location":"qsl4a/special/cipher/","title":"Cipher API","text":"

    Encryption and decryption utilities for secure data storage.

    "},{"location":"qsl4a/special/cipher/#initialization","title":"Initialization","text":""},{"location":"qsl4a/special/cipher/#cipherinit","title":"cipherInit()","text":"

    Initialize the cipher with encryption key and algorithm.

    cipherInit(key, algorithm=\"AES/CBC/PKCS5Padding\", encodingFormat=\"\", initialVector=\"\")\n

    Parameters: - key (str or bytes): Encryption key - algorithm (str): Cipher algorithm (default: \"AES/CBC/PKCS5Padding\") - encodingFormat (str): Encoding format - initialVector (str or bytes): Initial vector for encryption

    Returns: Initialization result

    Note: Must be called before any encrypt/decrypt operations.

    "},{"location":"qsl4a/special/cipher/#encryption-methods","title":"Encryption Methods","text":""},{"location":"qsl4a/special/cipher/#encryptstring","title":"encryptString()","text":"

    Encrypt a string.

    encryptString(plainText)\n

    Parameters: - plainText (str): Text to encrypt

    Returns: Encrypted string

    "},{"location":"qsl4a/special/cipher/#encryptbytes","title":"encryptBytes()","text":"

    Encrypt bytes data.

    encryptBytes(data)\n

    Parameters: - data (bytes): Data to encrypt

    Returns: Encrypted bytes

    "},{"location":"qsl4a/special/cipher/#encryptstringtofile","title":"encryptStringToFile()","text":"

    Encrypt string to file.

    encryptStringToFile(plainText, filePath)\n

    Parameters: - plainText (str): Text to encrypt - filePath (str): Output file path

    "},{"location":"qsl4a/special/cipher/#encryptbytestofile","title":"encryptBytesToFile()","text":"

    Encrypt bytes to file.

    encryptBytesToFile(data, filePath)\n
    "},{"location":"qsl4a/special/cipher/#decryption-methods","title":"Decryption Methods","text":""},{"location":"qsl4a/special/cipher/#decryptstring","title":"decryptString()","text":"

    Decrypt to string.

    decryptString(cipherText)\n

    Parameters: - cipherText (str): Encrypted text

    Returns: Decrypted string

    "},{"location":"qsl4a/special/cipher/#decryptbytes","title":"decryptBytes()","text":"

    Decrypt to bytes.

    decryptBytes(data)\n

    Returns: Decrypted bytes

    "},{"location":"qsl4a/special/cipher/#decryptfiletostring","title":"decryptFileToString()","text":"

    Decrypt file to string.

    decryptFileToString(filePath)\n
    "},{"location":"qsl4a/special/cipher/#decryptfiletobytes","title":"decryptFileToBytes()","text":"

    Decrypt file to bytes.

    decryptFileToBytes(filePath)\n
    "},{"location":"qsl4a/special/cipher/#decryptfile","title":"decryptFile()","text":"

    Decrypt file to file.

    decryptFile(srcPath, destPath)\n
    "},{"location":"qsl4a/special/cipher/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Initialize cipher with your encryption key\ndroid.cipherInit(\"my_secret_key_1234\")\n\n# Encrypt string\nencrypted = droid.encryptString(\"Secret message!\").result\nprint(f\"Encrypted: {encrypted}\")\n\n# Decrypt string\ndecrypted = droid.decryptString(encrypted).result\nprint(f\"Decrypted: {decrypted}\")\n\n# Encrypt to file\ndroid.encryptStringToFile(\"My secret data\", \"/sdcard/secret.dat\")\n\n# Decrypt from file\ndata = droid.decryptFileToString(\"/sdcard/secret.dat\").result\nprint(data)\n\n# Initialize with custom algorithm and IV\ndroid.cipherInit(\n    key=\"my_key\",\n    algorithm=\"AES/CBC/PKCS5Padding\",\n    initialVector=\"0123456789abcdef\"\n)\n
    "},{"location":"qsl4a/special/pgptai/","title":"PGPT AI API","text":"

    Speech-to-text and AI services integration.

    "},{"location":"qsl4a/special/pgptai/#prerequisites","title":"Prerequisites","text":"
    pip install pgptAI\n
    "},{"location":"qsl4a/special/pgptai/#speech-recognition","title":"Speech Recognition","text":""},{"location":"qsl4a/special/pgptai/#speechtotext","title":"speechToText()","text":"

    Convert speech to text.

    speechToText(RecordSecond=10, AmrFile=None, Language=None)\n

    Parameters: - RecordSecond (int): Recording duration in seconds - AmrFile (str, optional): Existing audio file path - Language (str, optional): Language code ('en', 'zh')

    Returns: Transcribed text

    "},{"location":"qsl4a/special/pgptai/#text-to-speech","title":"Text to Speech","text":""},{"location":"qsl4a/special/pgptai/#texttospeech","title":"textToSpeech()","text":"

    Convert text to speech and optionally play it.

    textToSpeech(Text, AutoPlay=True, WavFile=None, VoiceName=None)\n

    Parameters: - Text (str): Text to convert to speech - AutoPlay (bool): Automatically play the generated audio (default: True) - WavFile (str, optional): Path to save the WAV file. If None, uses temporary file - VoiceName (str, optional): Voice name to use (e.g., 'en-US-JennyNeural', 'zh-CN-XiaoxiaoNeural')

    Returns: Dict with speech synthesis result including: - text: The input text - url: URL to download the audio file - WavFile: Path to the saved WAV file (if saved locally)

    "},{"location":"qsl4a/special/pgptai/#configuration","title":"Configuration","text":"

    The API uses configuration from /storage/emulated/0/Android/data/org.qpython.qpy/files/apigpt.conf:

    [speech]\nspeech_key = your_api_key\n

    Default voice settings: - English: en-US-JennyNeural - Chinese: zh-CN-XiaoxiaoNeural

    "},{"location":"qsl4a/special/pgptai/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Record and transcribe\nprint(\"Recording for 5 seconds...\")\ntext = droid.speechToText(RecordSecond=5, Language='en').result\nprint(f\"You said: {text}\")\n\n# Transcribe existing file\ntext = droid.speechToText(AmrFile=\"/sdcard/recording.amr\").result\nprint(f\"Transcription: {text}\")\n\n# Text to speech\ndroid.textToSpeech(\"Hello, this is a test message.\", AutoPlay=True, Language='en')\n\n# Text to speech with custom voice and save to file\nresult = droid.textToSpeech(\n    \"Welcome to QPython!\",\n    AutoPlay=False,\n    WavFile=\"/sdcard/welcome.wav\",\n    VoiceName=\"en-US-JennyNeural\"\n).result\nprint(f\"Audio saved to: {result.get('WavFile')}\")\n
    "},{"location":"qsl4a/special/pgptai/#class-usage","title":"Class Usage","text":"
    from androidhelper.pgptai import pgptai\nimport androidhelper\n\ndroid = androidhelper.Android()\nai = pgptai(droid)\n\n# Use speech recognition\ntext = ai.speechToText(RecordSecond=10)\n
    "},{"location":"qsl4a/storage/clipboard/","title":"Clipboard API","text":"

    Copy and paste text to system clipboard.

    "},{"location":"qsl4a/storage/clipboard/#methods","title":"Methods","text":""},{"location":"qsl4a/storage/clipboard/#setclipboard","title":"setClipboard()","text":"

    Copy text to clipboard.

    setClipboard(text)\n

    Parameters: - text (str): Text to copy

    Returns: True if success

    "},{"location":"qsl4a/storage/clipboard/#getclipboard","title":"getClipboard()","text":"

    Get text from clipboard.

    getClipboard()\n

    Returns: Clipboard text

    "},{"location":"qsl4a/storage/clipboard/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Copy to clipboard\ndroid.setClipboard(\"Hello from QPython!\")\n\n# Paste from clipboard\ntext = droid.getClipboard().result\nprint(f\"Clipboard: {text}\")\n
    "},{"location":"qsl4a/storage/documentfile/","title":"DocumentFile API","text":"

    File operations with SAF (Storage Access Framework) support for Android 4.4+.

    "},{"location":"qsl4a/storage/documentfile/#directory-operations","title":"Directory Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfilemkdir","title":"documentFileMkdir()","text":"

    Create directory.

    documentFileMkdir(Dir)\n

    Parameters: - Dir (str): Directory path

    Returns: True if success

    "},{"location":"qsl4a/storage/documentfile/#documentfilelistfiles","title":"documentFileListFiles()","text":"

    List files in directory.

    documentFileListFiles(Folder)\n

    Returns: List of files

    "},{"location":"qsl4a/storage/documentfile/#file-operations","title":"File Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfileexists","title":"documentFileExists()","text":"

    Check if file or directory exists.

    documentFileExists(path)\n

    Parameters: - path (str): File or directory path

    Returns: True if exists, False otherwise

    "},{"location":"qsl4a/storage/documentfile/#documentfileisfile","title":"documentFileIsFile()","text":"

    Check if path is a file.

    documentFileIsFile(path)\n

    Parameters: - path (str): Path to check

    Returns: True if file, False if not a file, None if not exists

    "},{"location":"qsl4a/storage/documentfile/#documentfileisdirectory","title":"documentFileIsDirectory()","text":"

    Check if path is a directory.

    documentFileIsDirectory(path)\n

    Parameters: - path (str): Path to check

    Returns: True if directory, False if not a directory, None if not exists

    "},{"location":"qsl4a/storage/documentfile/#documentfiledelete","title":"documentFileDelete()","text":"

    Delete file or directory.

    documentFileDelete(FileOrTree)\n

    Returns: True if success

    "},{"location":"qsl4a/storage/documentfile/#documentfilerenameto","title":"documentFileRenameTo()","text":"

    Rename or move file.

    documentFileRenameTo(Src, Dest)\n

    Returns: True if success

    "},{"location":"qsl4a/storage/documentfile/#documentfilecopy","title":"documentFileCopy()","text":"

    Copy file.

    documentFileCopy(SrcFileOrTree, DestFileOrTree)\n
    "},{"location":"qsl4a/storage/documentfile/#stream-operations","title":"Stream Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfileinputstream","title":"documentFileInputStream()","text":"

    Read file content.

    documentFileInputStream(srcFile, EncodingFormat=\"\", skip=None, length=None)\n

    Parameters: - srcFile (str): Source file - EncodingFormat (str): \"UTF-8\", \"GBK\", \"Base64\", or \"\" for bytes - skip (int): Skip bytes from start - length (int): Read length

    Returns: File content

    "},{"location":"qsl4a/storage/documentfile/#documentfileoutputstream","title":"documentFileOutputStream()","text":"

    Write file content.

    documentFileOutputStream(destFile, src, EncodingFormat=\"\", append=None)\n

    Parameters: - destFile (str): Destination file - src: Data to write - EncodingFormat (str): Encoding format - append (bool): Append mode

    "},{"location":"qsl4a/storage/documentfile/#file-information","title":"File Information","text":""},{"location":"qsl4a/storage/documentfile/#documentfilelength","title":"documentFileLength()","text":"

    Get file size in bytes.

    documentFileLength(path)\n

    Parameters: - path (str): File path

    Returns: File size in bytes (0 if not exists)

    "},{"location":"qsl4a/storage/documentfile/#documentfilelastmodified","title":"documentFileLastModified()","text":"

    Get last modified time.

    documentFileLastModified(path)\n

    Parameters: - path (str): File path

    Returns: Timestamp (0 if not exists)

    "},{"location":"qsl4a/storage/documentfile/#documentfilegetstat","title":"documentFileGetStat()","text":"

    Get comprehensive file statistics.

    documentFileGetStat(path)\n

    Parameters: - path (str): File path

    Returns: Dict with length, last modified, and read/write permissions, or None if not exists

    "},{"location":"qsl4a/storage/documentfile/#uri-operations","title":"URI Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfilegeturi","title":"documentFileGetUri()","text":"

    Get URI from path.

    documentFileGetUri(path, isDirectory=None)\n
    "},{"location":"qsl4a/storage/documentfile/#documentfileshowopen","title":"documentFileShowOpen()","text":"

    Show file picker.

    documentFileShowOpen()\n

    Returns: Selected file URI

    "},{"location":"qsl4a/storage/documentfile/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Create directory\ndroid.documentFileMkdir(\"/sdcard/MyFolder\")\n\n# List files\nfiles = droid.documentFileListFiles(\"/sdcard\").result\nfor f in files:\n    print(f)\n\n# Read file\ncontent = droid.documentFileInputStream(\n    \"/sdcard/test.txt\",\n    EncodingFormat=\"UTF-8\"\n).result\nprint(content)\n\n# Write file\ndroid.documentFileOutputStream(\n    \"/sdcard/output.txt\",\n    \"Hello World\",\n    EncodingFormat=\"UTF-8\"\n)\n
    "},{"location":"qsl4a/storage/preferences/","title":"Preferences API","text":"

    Store and retrieve data using Android SharedPreferences.

    "},{"location":"qsl4a/storage/preferences/#preference-methods","title":"Preference Methods","text":""},{"location":"qsl4a/storage/preferences/#prefgetvalue","title":"prefGetValue()","text":"

    Read a value from shared preferences.

    prefGetValue(key, filename=None)\n

    Parameters: - key (str): Preference key - filename (str, optional): Preference file name

    Returns: The stored value (any type)

    "},{"location":"qsl4a/storage/preferences/#prefputvalue","title":"prefPutValue()","text":"

    Write a value to shared preferences.

    prefPutValue(key, value, filename=None)\n

    Parameters: - key (str): Preference key - value (object): Value to store - filename (str, optional): Preference file name

    "},{"location":"qsl4a/storage/preferences/#prefgetall","title":"prefGetAll()","text":"

    Get all preference values.

    prefGetAll(filename=None)\n

    Parameters: - filename (str, optional): Preference file name

    Returns: Map of all preferences

    "},{"location":"qsl4a/storage/preferences/#prefremovevalue","title":"prefRemoveValue()","text":"

    Remove a value from shared preferences.

    prefRemoveValue(key, filename=None)\n

    Parameters: - key (str): Preference key to remove - filename (str, optional): Preference file name

    "},{"location":"qsl4a/storage/preferences/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Store values\ndroid.prefPutValue(\"username\", \"alice\")\ndroid.prefPutValue(\"score\", 100)\ndroid.prefPutValue(\"enabled\", True)\n\n# Read a specific value\nusername = droid.prefGetValue(\"username\").result\nprint(f\"Username: {username}\")\n\n# Get all preferences\nall_prefs = droid.prefGetAll().result\nprint(f\"All prefs: {all_prefs}\")\n\n# Remove a value\ndroid.prefRemoveValue(\"score\")\n\n# Use custom filename\ndroid.prefPutValue(\"token\", \"abc123\", filename=\"auth.prefs\")\ntoken = droid.prefGetValue(\"token\", filename=\"auth.prefs\").result\n
    "},{"location":"qsl4a/system/activityresult/","title":"Activity Result API","text":"

    Set activity results for scripts launched via startActivityForResult.

    "},{"location":"qsl4a/system/activityresult/#result-methods","title":"Result Methods","text":""},{"location":"qsl4a/system/activityresult/#setresultboolean","title":"setResultBoolean()","text":"

    Set a boolean result.

    setResultBoolean(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (bool): Boolean result value

    "},{"location":"qsl4a/system/activityresult/#setresultbyte","title":"setResultByte()","text":"

    Set a byte result.

    setResultByte(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (int): Byte result value

    "},{"location":"qsl4a/system/activityresult/#setresultshort","title":"setResultShort()","text":"

    Set a short result.

    setResultShort(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (int): Short result value

    "},{"location":"qsl4a/system/activityresult/#setresultchar","title":"setResultChar()","text":"

    Set a character result.

    setResultChar(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (str): Character result value

    "},{"location":"qsl4a/system/activityresult/#setresultinteger","title":"setResultInteger()","text":"

    Set an integer result.

    setResultInteger(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (int): Integer result value

    "},{"location":"qsl4a/system/activityresult/#setresultlong","title":"setResultLong()","text":"

    Set a long result.

    setResultLong(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (int): Long result value

    "},{"location":"qsl4a/system/activityresult/#setresultfloat","title":"setResultFloat()","text":"

    Set a float result.

    setResultFloat(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (float): Float result value

    "},{"location":"qsl4a/system/activityresult/#setresultdouble","title":"setResultDouble()","text":"

    Set a double result.

    setResultDouble(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (float): Double result value

    "},{"location":"qsl4a/system/activityresult/#setresultstring","title":"setResultString()","text":"

    Set a string result.

    setResultString(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (str): String result value

    "},{"location":"qsl4a/system/activityresult/#setresultbooleanarray","title":"setResultBooleanArray()","text":"

    Set a boolean array result.

    setResultBooleanArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Boolean array

    "},{"location":"qsl4a/system/activityresult/#setresultbytearray","title":"setResultByteArray()","text":"

    Set a byte array result.

    setResultByteArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Byte array

    "},{"location":"qsl4a/system/activityresult/#setresultshortarray","title":"setResultShortArray()","text":"

    Set a short array result.

    setResultShortArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Short array

    "},{"location":"qsl4a/system/activityresult/#setresultchararray","title":"setResultCharArray()","text":"

    Set a character array result.

    setResultCharArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Char array

    "},{"location":"qsl4a/system/activityresult/#setresultintegerarray","title":"setResultIntegerArray()","text":"

    Set an integer array result.

    setResultIntegerArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Integer array

    "},{"location":"qsl4a/system/activityresult/#setresultlongarray","title":"setResultLongArray()","text":"

    Set a long array result.

    setResultLongArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Long array

    "},{"location":"qsl4a/system/activityresult/#setresultfloatarray","title":"setResultFloatArray()","text":"

    Set a float array result.

    setResultFloatArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Float array

    "},{"location":"qsl4a/system/activityresult/#setresultdoublearray","title":"setResultDoubleArray()","text":"

    Set a double array result.

    setResultDoubleArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Double array

    "},{"location":"qsl4a/system/activityresult/#setresultstringarray","title":"setResultStringArray()","text":"

    Set a string array result.

    setResultStringArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): String array

    "},{"location":"qsl4a/system/activityresult/#setresultserializable","title":"setResultSerializable()","text":"

    Set a serializable result.

    setResultSerializable(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue: Serializable result value

    "},{"location":"qsl4a/system/activityresult/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# After performing an activity, set the result\n# Example: Return success with data\ndroid.setResultInteger(0, 200)  # RESULT_OK\ndroid.setResultString(0, \"Operation completed successfully\")\n\n# Return an array result\ndroid.setResultIntegerArray(0, [1, 2, 3, 4, 5])\n
    "},{"location":"qsl4a/system/application/","title":"Application Management","text":"

    Manage applications, launch apps, and query system information.

    "},{"location":"qsl4a/system/application/#application-information","title":"Application Information","text":""},{"location":"qsl4a/system/application/#getapplicationinfo","title":"getApplicationInfo()","text":"

    Get information about an app.

    getApplicationInfo(packageName=None)\n

    Parameters: - packageName (str): Package name (None = current app)

    Returns: App info dict

    "},{"location":"qsl4a/system/application/#getinstalledpackages","title":"getInstalledPackages()","text":"

    Get list of installed packages.

    getInstalledPackages(flag=4)\n

    Parameters: - flag (int): Package flag filter (default: 4)

    Returns: List of installed packages

    "},{"location":"qsl4a/system/application/#getrunningpackages","title":"getRunningPackages()","text":"

    List running packages.

    getRunningPackages()\n

    Returns: List of package names

    "},{"location":"qsl4a/system/application/#getlaunchablepackages","title":"getLaunchablePackages()","text":"

    Get list of launchable packages.

    getLaunchablePackages(needClassName=False)\n

    Parameters: - needClassName (bool): Include main activity class name (default: False)

    Returns: List of launchable package names or dict with class names

    "},{"location":"qsl4a/system/application/#application-control","title":"Application Control","text":""},{"location":"qsl4a/system/application/#launch","title":"launch()","text":"

    Launch an application.

    launch(classname=None, packagename=None, wait=True)\n

    Parameters: - classname (str): Main activity class name - packagename (str): Package name - wait (bool): Wait for launch to complete (default: True)

    Returns: Launch result

    "},{"location":"qsl4a/system/application/#forcestoppackage","title":"forceStopPackage()","text":"

    Force stop an application.

    forceStopPackage(packageName)\n

    Parameters: - packageName (str): Package name to stop

    "},{"location":"qsl4a/system/application/#version-information","title":"Version Information","text":""},{"location":"qsl4a/system/application/#getpackageversion","title":"getPackageVersion()","text":"

    Get app version name.

    getPackageVersion(packageName)\n

    Returns: Version string (e.g., \"3.2.1\")

    "},{"location":"qsl4a/system/application/#getpackageversioncode","title":"getPackageVersionCode()","text":"

    Get app version code.

    getPackageVersionCode(packageName)\n

    Returns: Version code integer

    "},{"location":"qsl4a/system/application/#getconstants","title":"getConstants()","text":"

    Get class constants.

    getConstants(classname)\n

    Parameters: - classname (str): Full class name

    Returns: Dict of constant names and values

    "},{"location":"qsl4a/system/application/#system-features","title":"System Features","text":""},{"location":"qsl4a/system/application/#backgroundprotect","title":"backgroundProtect()","text":"

    Enable or disable background protection for the app.

    backgroundProtect(enabled=True)\n

    Parameters: - enabled (bool): True to enable protection, False to disable

    "},{"location":"qsl4a/system/application/#createscriptshortcut","title":"createScriptShortCut()","text":"

    Create a home screen shortcut for a script.

    createScriptShortCut(scriptPath, label=None, iconPath=None, scriptArg=None)\n

    Parameters: - scriptPath (str): Path to the Python script - label (str, optional): Shortcut label - iconPath (str, optional): Path to icon image - scriptArg (str, optional): Argument to pass to script

    "},{"location":"qsl4a/system/application/#device-information","title":"Device Information","text":""},{"location":"qsl4a/system/application/#getandroidid","title":"getAndroidID()","text":"

    Get Android device ID.

    getAndroidID()\n

    Returns: Unique Android device ID string

    "},{"location":"qsl4a/system/application/#getsysinfo","title":"getSysInfo()","text":"

    Get system information.

    getSysInfo()\n

    Returns: Dict with system details

    "},{"location":"qsl4a/system/application/#getlocale","title":"getLocale()","text":"

    Get device locale.

    getLocale()\n

    Returns: Locale string (e.g., \"en_US\")

    "},{"location":"qsl4a/system/application/#getharmonyosinformation","title":"getHarmonyOsInformation()","text":"

    Get HarmonyOS information if running on HarmonyOS.

    getHarmonyOsInformation()\n

    Returns: HarmonyOS version info or None

    "},{"location":"qsl4a/system/application/#isexternalstoragemanager","title":"isExternalStorageManager()","text":"

    Check if app has external storage manager permission.

    isExternalStorageManager()\n

    Returns: True if has permission

    "},{"location":"qsl4a/system/application/#memory-and-display","title":"Memory and Display","text":""},{"location":"qsl4a/system/application/#getmemoryinfo","title":"getMemoryInfo()","text":"

    Get memory information.

    getMemoryInfo()\n

    Returns: Dict with memory stats

    "},{"location":"qsl4a/system/application/#getscreeninfo","title":"getScreenInfo()","text":"

    Get screen information.

    getScreenInfo()\n

    Returns: Dict with width, height, density

    "},{"location":"qsl4a/system/application/#permissions","title":"Permissions","text":""},{"location":"qsl4a/system/application/#checkpermissions","title":"checkPermissions()","text":"

    Check current app permissions.

    checkPermissions()\n

    Returns: Dict of permissions and their status

    "},{"location":"qsl4a/system/application/#requestpermissions","title":"requestPermissions()","text":"

    Request permissions from the user.

    requestPermissions(permissions=None)\n

    Parameters: - permissions (list, optional): List of permissions to request. If None, requests all needed permissions.

    Returns: Result of permission request

    "},{"location":"qsl4a/system/application/#system-actions","title":"System Actions","text":""},{"location":"qsl4a/system/application/#showscreenlock","title":"showScreenLock()","text":"

    Show screen lock (PIN/pattern/password entry).

    showScreenLock()\n
    "},{"location":"qsl4a/system/application/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get system info\ninfo = droid.getSysInfo().result\nprint(f\"System: {info}\")\n\n# Get app version\nversion = droid.getPackageVersion(\"org.qpython.qpy\").result\nprint(f\"QPython version: {version}\")\n\n# List installed apps\napps = droid.getInstalledPackages().result\nprint(f\"Installed apps: {len(apps)}\")\n\n# Launch an app\ndroid.launch(packagename=\"com.android.settings\")\n\n# Check permissions\nperms = droid.checkPermissions().result\nprint(f\"Permissions: {perms}\")\n\n# Request storage permission\ndroid.requestPermissions([\"android.permission.READ_EXTERNAL_STORAGE\"])\n\n# Create shortcut\ndroid.createScriptShortCut(\n    \"/sdcard/my_script.py\",\n    label=\"My Script\",\n    iconPath=\"/sdcard/icon.png\"\n)\n
    "},{"location":"qsl4a/system/battery/","title":"Battery API","text":"

    Monitor device battery status and health.

    "},{"location":"qsl4a/system/battery/#methods","title":"Methods","text":""},{"location":"qsl4a/system/battery/#readbatterydata","title":"readBatteryData()","text":"

    Get complete battery information.

    readBatteryData()\n

    Returns: Dict with battery data

    "},{"location":"qsl4a/system/battery/#batterystartmonitoring","title":"batteryStartMonitoring()","text":"

    Start battery monitoring.

    batteryStartMonitoring()\n
    "},{"location":"qsl4a/system/battery/#batterystopmonitoring","title":"batteryStopMonitoring()","text":"

    Stop battery monitoring.

    batteryStopMonitoring()\n
    "},{"location":"qsl4a/system/battery/#batterygetlevel","title":"batteryGetLevel()","text":"

    Get battery percentage.

    batteryGetLevel()\n

    Returns: Int (0-100)

    "},{"location":"qsl4a/system/battery/#batterygetstatus","title":"batteryGetStatus()","text":"

    Get charging status.

    batteryGetStatus()\n

    Returns: - 1: Unknown - 2: Charging - 3: Discharging - 4: Not charging - 5: Full

    "},{"location":"qsl4a/system/battery/#batterygetplugtype","title":"batteryGetPlugType()","text":"

    Get power source.

    batteryGetPlugType()\n

    Returns: - -1: Unknown - 0: Unplugged - 1: AC charger - 2: USB port

    "},{"location":"qsl4a/system/battery/#batterygethealth","title":"batteryGetHealth()","text":"

    Get battery health.

    batteryGetHealth()\n

    Returns: - 1: Unknown - 2: Good - 3: Overheat - 4: Dead - 5: Over voltage - 6: Unspecified failure

    "},{"location":"qsl4a/system/battery/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get battery level\nlevel = droid.batteryGetLevel().result\nprint(f\"Battery: {level}%\")\n
    "},{"location":"qsl4a/system/qpyinterface/","title":"QPython Interface API","text":"

    Execute QPython scripts and manage shared variables from other apps.

    "},{"location":"qsl4a/system/qpyinterface/#script-execution-methods","title":"Script Execution Methods","text":""},{"location":"qsl4a/system/qpyinterface/#executeqpy","title":"executeQPy()","text":"

    Execute a QPython script.

    executeQPy(path=\"\", arg=None)\n

    Parameters: - path (str): Path to the script file - arg (str, optional): Command line arguments

    Returns: True if started successfully

    "},{"location":"qsl4a/system/qpyinterface/#executeqpyassrv","title":"executeQPyAsSrv()","text":"

    Execute a QPython script as a service.

    executeQPyAsSrv(path=None)\n

    Parameters: - path (str, optional): Path to the script file

    Returns: True if started successfully

    "},{"location":"qsl4a/system/qpyinterface/#executeqpycode","title":"executeQPyCode()","text":"

    Execute Python code directly.

    executeQPyCode(code=None)\n

    Parameters: - code (str, optional): Python code to execute

    Returns: True if started successfully

    "},{"location":"qsl4a/system/qpyinterface/#executeqpycodeassrv","title":"executeQPyCodeAsSrv()","text":"

    Execute Python code as a service.

    executeQPyCodeAsSrv(code=None)\n

    Parameters: - code (str, optional): Python code to execute

    Returns: True if started successfully

    "},{"location":"qsl4a/system/qpyinterface/#shared-variables","title":"Shared Variables","text":"

    Shared variables allow communication between QPython and other apps.

    "},{"location":"qsl4a/system/qpyinterface/#sharedvariableset","title":"sharedVariableSet()","text":"

    Set a Java shared variable.

    sharedVariableSet(key, value)\n

    Parameters: - key (str): Variable name - value (str): Variable value

    Returns: The stored value

    "},{"location":"qsl4a/system/qpyinterface/#sharedvariableget","title":"sharedVariableGet()","text":"

    Get a Java shared variable.

    sharedVariableGet(key)\n

    Parameters: - key (str): Variable name

    Returns: The stored value

    "},{"location":"qsl4a/system/qpyinterface/#sharedvariableremove","title":"sharedVariableRemove()","text":"

    Remove a Java shared variable.

    sharedVariableRemove(key)\n

    Parameters: - key (str): Variable name to remove

    Returns: The removed value

    "},{"location":"qsl4a/system/qpyinterface/#getlastlog","title":"getLastLog()","text":"

    Get the last log output from QPython.

    getLastLog()\n

    Returns: String log content

    "},{"location":"qsl4a/system/qpyinterface/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Execute a script\ndroid.executeQPy(\"/sdcard/my_script.py\", arg=\"test\")\n\n# Execute code directly\ncode = \"print('Hello from QPython!')\"\ndroid.executeQPyCode(code)\n\n# Use shared variables\ndroid.sharedVariableSet(\"username\", \"alice\")\nusername = droid.sharedVariableGet(\"username\").result\nprint(f\"Username: {username}\")\n\n# Remove variable\ndroid.sharedVariableRemove(\"username\")\n\n# Get recent log\nlog = droid.getLastLog().result\nprint(f\"Log: {log}\")\n
    "},{"location":"qsl4a/system/sensors/","title":"Sensor API","text":"

    Access device sensors including accelerometer, gyroscope, magnetometer, and more.

    "},{"location":"qsl4a/system/sensors/#methods","title":"Methods","text":""},{"location":"qsl4a/system/sensors/#startsensingtimed","title":"startSensingTimed()","text":"

    Start sensor monitoring with time intervals.

    startSensingTimed(sensorNumber, delayTime)\n

    Parameters: - sensorNumber (int): Sensor ID (1-3 typically) - delayTime (int): Delay between readings in milliseconds

    "},{"location":"qsl4a/system/sensors/#startsensingthreshold","title":"startSensingThreshold()","text":"

    Start sensor monitoring with threshold trigger.

    startSensingThreshold(sensorNumber, threshold, axis)\n

    Parameters: - sensorNumber (int): Sensor ID - threshold (float): Trigger threshold - axis (int): Axis to monitor (0=X, 1=Y, 2=Z)

    "},{"location":"qsl4a/system/sensors/#stopsensing","title":"stopSensing()","text":"

    Stop all sensor monitoring.

    stopSensing()\n
    "},{"location":"qsl4a/system/sensors/#readsensors","title":"readSensors()","text":"

    Read current sensor data.

    readSensors()\n

    Returns: Sensor data dict

    "},{"location":"qsl4a/system/sensors/#sensorsreadaccelerometer","title":"sensorsReadAccelerometer()","text":"

    Read accelerometer values.

    sensorsReadAccelerometer()\n

    Returns: List [X, Y, Z] in m/s\u00b2

    "},{"location":"qsl4a/system/sensors/#sensorsreadgyroscope","title":"sensorsReadGyroscope()","text":"

    Read gyroscope values.

    sensorsReadGyroscope()\n

    Returns: List [X, Y, Z] in rad/s

    "},{"location":"qsl4a/system/sensors/#sensorsreadmagnetometer","title":"sensorsReadMagnetometer()","text":"

    Read magnetic field values.

    sensorsReadMagnetometer()\n

    Returns: List [X, Y, Z] in \u03bcT

    "},{"location":"qsl4a/system/sensors/#sensorsreadorientation","title":"sensorsReadOrientation()","text":"

    Read device orientation.

    sensorsReadOrientation()\n

    Returns: List [azimuth, pitch, roll] in degrees

    "},{"location":"qsl4a/system/sensors/#sensorsgetlight","title":"sensorsGetLight()","text":"

    Read light sensor value.

    sensorsGetLight()\n

    Returns: Light level in lux

    "},{"location":"qsl4a/system/sensors/#sensorsgetstepcounter","title":"sensorsGetStepCounter()","text":"

    Read step counter.

    sensorsGetStepCounter()\n

    Returns: Number of steps

    "},{"location":"qsl4a/system/sensors/#sensorsgetaccuracy","title":"sensorsGetAccuracy()","text":"

    Get the current sensor accuracy.

    sensorsGetAccuracy()\n

    Returns: Accuracy value (0-3: UNRELIABLE, ACCURACY_LOW, ACCURACY_MEDIUM, ACCURACY_HIGH)

    "},{"location":"qsl4a/system/sensors/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start sensing\ndroid.startSensingTimed(1, 250)\n\n# Read sensors 10 times\nfor i in range(10):\n    accel = droid.sensorsReadAccelerometer().result\n    print(f\"Accel: X={accel[0]:.2f}, Y={accel[1]:.2f}, Z={accel[2]:.2f}\")\n    time.sleep(0.5)\n\ndroid.stopSensing()\n
    "},{"location":"qsl4a/system/settings/","title":"Settings API","text":"

    Control system settings including screen, sound, and network settings.

    "},{"location":"qsl4a/system/settings/#screen-settings","title":"Screen Settings","text":""},{"location":"qsl4a/system/settings/#setscreentimeout","title":"setScreenTimeout()","text":"

    Set the screen timeout value.

    setScreenTimeout(value)\n

    Parameters: - value (int): Screen timeout in seconds

    Returns: Previous timeout value

    "},{"location":"qsl4a/system/settings/#getscreentimeout","title":"getScreenTimeout()","text":"

    Get the current screen timeout.

    getScreenTimeout()\n

    Returns: Current screen timeout in seconds

    "},{"location":"qsl4a/system/settings/#getscreenbrightness","title":"getScreenBrightness()","text":"

    Get the screen brightness value.

    getScreenBrightness()\n

    Returns: Brightness value (0-255)

    "},{"location":"qsl4a/system/settings/#setscreenbrightness","title":"setScreenBrightness()","text":"

    Set the screen brightness.

    setScreenBrightness(value=None)\n

    Parameters: - value (int, optional): Brightness value (0-255), or None for auto

    Returns: Previous brightness value

    "},{"location":"qsl4a/system/settings/#checkscreenon","title":"checkScreenOn()","text":"

    Check if the screen is on.

    checkScreenOn()\n

    Returns: True if screen is on, False otherwise

    "},{"location":"qsl4a/system/settings/#airplane-mode","title":"Airplane Mode","text":""},{"location":"qsl4a/system/settings/#checkairplanemode","title":"checkAirplaneMode()","text":"

    Check if airplane mode is enabled.

    checkAirplaneMode()\n

    Returns: True if airplane mode is on

    "},{"location":"qsl4a/system/settings/#ringer-settings","title":"Ringer Settings","text":""},{"location":"qsl4a/system/settings/#checkringersilentmode","title":"checkRingerSilentMode()","text":"

    Check if ringer is in silent mode.

    checkRingerSilentMode()\n

    Returns: True if silent mode is on

    "},{"location":"qsl4a/system/settings/#toggleringersilentmode","title":"toggleRingerSilentMode()","text":"

    Toggle ringer silent mode.

    toggleRingerSilentMode(enabled=None)\n

    Parameters: - enabled (bool, optional): True to enable, False to disable, None to toggle

    Returns: New state

    "},{"location":"qsl4a/system/settings/#togglevibratemode","title":"toggleVibrateMode()","text":"

    Toggle vibrate mode.

    toggleVibrateMode(enabled=None, ringer=None)\n

    Parameters: - enabled (bool, optional): Toggle vibrate on/off - ringer (bool, optional): Apply to ringer mode

    Returns: New state

    "},{"location":"qsl4a/system/settings/#getvibratemode","title":"getVibrateMode()","text":"

    Get the vibrate mode setting.

    getVibrateMode(ringer=None)\n

    Parameters: - ringer (bool, optional): Check ringer vibrate mode

    Returns: True if vibrate is enabled

    "},{"location":"qsl4a/system/settings/#volume-settings","title":"Volume Settings","text":""},{"location":"qsl4a/system/settings/#getringervolume","title":"getRingerVolume()","text":"

    Get the current ringer volume.

    getRingerVolume()\n

    Returns: Ringer volume level (0-7 typically)

    "},{"location":"qsl4a/system/settings/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

    Get the maximum ringer volume.

    getMaxRingerVolume()\n

    Returns: Maximum ringer volume

    "},{"location":"qsl4a/system/settings/#setringervolume","title":"setRingerVolume()","text":"

    Set the ringer volume.

    setRingerVolume(volume)\n

    Parameters: - volume (int): Volume level

    "},{"location":"qsl4a/system/settings/#getmediavolume","title":"getMediaVolume()","text":"

    Get the current media volume.

    getMediaVolume()\n

    Returns: Media volume level (0-15 typically)

    "},{"location":"qsl4a/system/settings/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

    Get the maximum media volume.

    getMaxMediaVolume()\n

    Returns: Maximum media volume

    "},{"location":"qsl4a/system/settings/#setmediavolume","title":"setMediaVolume()","text":"

    Set the media volume.

    setMediaVolume(volume)\n

    Parameters: - volume (int): Volume level

    "},{"location":"qsl4a/system/settings/#system-info","title":"System Info","text":""},{"location":"qsl4a/system/settings/#elapsedrealtimenanos","title":"elapsedRealtimeNanos()","text":"

    Get nanoseconds since system startup.

    elapsedRealtimeNanos()\n

    Returns: Nanoseconds (can be used for timing)

    "},{"location":"qsl4a/system/settings/#gettrafficstats","title":"getTrafficStats()","text":"

    Get network traffic statistics.

    getTrafficStats(flags=7)\n

    Parameters: - flags (int): Which stats to retrieve (default: 7 = all)

    Returns: Dict with transmit/receive bytes

    "},{"location":"qsl4a/system/settings/#getapptxbytes","title":"getAppTxBytes()","text":"

    Get transmit bytes for QPython app.

    getAppTxBytes(packageName)\n

    Parameters: - packageName (str): Package name

    Returns: Dict with tx/rx bytes

    "},{"location":"qsl4a/system/settings/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Screen settings\ncurrent_timeout = droid.getScreenTimeout().result\nprint(f\"Current timeout: {current_timeout}s\")\ndroid.setScreenTimeout(30)\n\n# Check screen\nif droid.checkScreenOn().result:\n    print(\"Screen is on\")\n\n# Volume control\nmedia_vol = droid.getMediaVolume().result\nprint(f\"Media volume: {media_vol}\")\ndroid.setMediaVolume(10)\n\n# Check airplane mode\nif droid.checkAirplaneMode().result:\n    print(\"Airplane mode is on\")\n
    "},{"location":"qsl4a/system/sysinfo/","title":"System Information","text":"

    Retrieve device and system information.

    "},{"location":"qsl4a/system/sysinfo/#device-information","title":"Device Information","text":""},{"location":"qsl4a/system/sysinfo/#getandroidid","title":"getAndroidID()","text":"

    Get the Android device ID.

    getAndroidID()\n

    Returns: String device ID

    "},{"location":"qsl4a/system/sysinfo/#getsysinfo","title":"getSysInfo()","text":"

    Get comprehensive system information.

    getSysInfo()\n

    Returns: Dict with system details

    "},{"location":"qsl4a/system/sysinfo/#getlocale","title":"getLocale()","text":"

    Get device locale settings.

    getLocale()\n

    Returns: Locale string (e.g., \"en_US\")

    "},{"location":"qsl4a/system/sysinfo/#memory","title":"Memory","text":""},{"location":"qsl4a/system/sysinfo/#getmemoryinfo","title":"getMemoryInfo()","text":"

    Get RAM information.

    getMemoryInfo()\n

    Returns: Dict with memory stats

    "},{"location":"qsl4a/system/sysinfo/#display","title":"Display","text":""},{"location":"qsl4a/system/sysinfo/#getscreeninfo","title":"getScreenInfo()","text":"

    Get display information.

    getScreenInfo()\n

    Returns: Dict with width, height, density

    "},{"location":"qsl4a/system/sysinfo/#identifiers","title":"Identifiers","text":""},{"location":"qsl4a/system/sysinfo/#getimei","title":"getImei()","text":"

    Get device IMEI.

    getImei(slotIndex=None)\n
    "},{"location":"qsl4a/system/sysinfo/#getmeid","title":"getMeid()","text":"

    Get device MEID.

    getMeid(slotIndex=None)\n
    "},{"location":"qsl4a/system/sysinfo/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Device ID\nandroid_id = droid.getAndroidID().result\nprint(f\"Android ID: {android_id}\")\n\n# Screen info\nscreen = droid.getScreenInfo().result\nprint(f\"Screen: {screen['width']}x{screen['height']}\")\n\n# Memory\nmemory = droid.getMemoryInfo().result\nprint(f\"Memory: {memory}\")\n
    "},{"location":"qsl4a/system/wakelock/","title":"WakeLock API","text":"

    Control device wake locks to keep the CPU or screen on.

    "},{"location":"qsl4a/system/wakelock/#wake-lock-types","title":"Wake Lock Types","text":"

    QSL4A provides different wake lock types:

    Type Description Full CPU on, screen bright, keyboard bright Partial CPU on only Bright CPU on, screen bright Dim CPU on, screen dim"},{"location":"qsl4a/system/wakelock/#wake-lock-methods","title":"Wake Lock Methods","text":""},{"location":"qsl4a/system/wakelock/#wakelockacquirefull","title":"wakeLockAcquireFull()","text":"

    Acquire a full wake lock (CPU on, screen bright, keyboard bright).

    wakeLockAcquireFull()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockacquirepartial","title":"wakeLockAcquirePartial()","text":"

    Acquire a partial wake lock (CPU on only).

    wakeLockAcquirePartial()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockacquirebright","title":"wakeLockAcquireBright()","text":"

    Acquire a bright wake lock (CPU on, screen bright).

    wakeLockAcquireBright()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockacquiredim","title":"wakeLockAcquireDim()","text":"

    Acquire a dim wake lock (CPU on, screen dim).

    wakeLockAcquireDim()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockrelease","title":"wakeLockRelease()","text":"

    Release the wake lock.

    wakeLockRelease()\n
    "},{"location":"qsl4a/system/wakelock/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Acquire full wake lock\ndroid.wakeLockAcquireFull()\n\n# Do important work while keeping screen on\nprint(\"Screen will stay on\")\ntime.sleep(10)\n\n# Release when done\ndroid.wakeLockRelease()\n\n# Or use partial lock for background tasks\ndroid.wakeLockAcquirePartial()\n# CPU stays on even with screen off\ntime.sleep(30)\ndroid.wakeLockRelease()\n

    Note: Remember to release wake locks when no longer needed to conserve battery.

    "},{"location":"qsl4a/ui/accessibility/","title":"Accessibility Service","text":"

    The Accessibility Service allows automation of UI interactions like clicks, swipes, and system actions.

    "},{"location":"qsl4a/ui/accessibility/#service-control","title":"Service Control","text":""},{"location":"qsl4a/ui/accessibility/#accessibilitystartservice","title":"accessibilityStartService()","text":"

    Start the accessibility service.

    accessibilityStartService()\n

    Returns: True if successful, False otherwise

    "},{"location":"qsl4a/ui/accessibility/#accessibilityserviceenabled","title":"accessibilityServiceEnabled()","text":"

    Check if accessibility service is enabled.

    accessibilityServiceEnabled()\n

    Returns: True or False

    "},{"location":"qsl4a/ui/accessibility/#screen-interactions","title":"Screen Interactions","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityclick","title":"accessibilityClick()","text":"

    Click at screen coordinates.

    accessibilityClick(x=0, y=0, t=50)\n

    Parameters: - x (int/float): X coordinate (0=center, decimals supported) - y (int/float): Y coordinate (0=center, decimals supported) - t (int): Press duration in milliseconds (default: 50)

    "},{"location":"qsl4a/ui/accessibility/#accessibilityslide","title":"accessibilitySlide()","text":"

    Multi-point slide gesture.

    accessibilitySlide(XnYn=None, t=None)\n

    Parameters: - XnYn (list): Coordinates [X1, Y1, X2, Y2, ... Xn, Yn] - t (int): Slide duration (default: 50*n ms)

    "},{"location":"qsl4a/ui/accessibility/#system-actions","title":"System Actions","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityaction","title":"accessibilityAction()","text":"

    Execute system action by code.

    accessibilityAction(actionCode)\n

    Action Codes: | Code | Constant | Description | |------|----------|-------------| | 1 | BACK | Back button | | 2 | HOME | Home button | | 3 | RECENTS | Recent apps | | 4 | NOTIFICATIONS | Open notifications | | 5 | QUICK_SETTINGS | Open quick settings | | 6 | POWER_DIALOG | Power menu | | 7 | TOGGLE_SPLIT_SCREEN | Split screen | | 8 | LOCK_SCREEN | Lock screen | | 9 | TAKE_SCREENSHOT | Take screenshot | | 10 | KEYCODE_HEADSETHOOK | Headset hook | | 11-14 | ACCESSIBILITY_ | Accessibility buttons | | 15 | DISMISS_NOTIFICATION_SHADE | Close notifications | | 16-20 | DPAD_ | Directional pad | | 21 | MENU | Menu button | | 22 | MEDIA_PLAY_PAUSE | Play/Pause media |

    "},{"location":"qsl4a/ui/accessibility/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/accessibility/#click-center-screen","title":"Click Center Screen","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Start service\nif not droid.accessibilityServiceEnabled().result:\n    droid.accessibilityStartService()\n\n# Click center (0,0 = center)\ndroid.accessibilityClick(0, 0, t=100)\n
    "},{"location":"qsl4a/ui/accessibility/#swipe-gesture","title":"Swipe Gesture","text":"
    # Swipe from bottom to top (scroll up)\ndroid.accessibilitySlide([0, 1.5, 0, -1.5], t=300)\n
    "},{"location":"qsl4a/ui/accessibility/#system-navigation","title":"System Navigation","text":"
    # Press home\ndroid.accessibilityAction(2)\n\n# Press back\ndroid.accessibilityAction(1)\n\n# Open notifications\ndroid.accessibilityAction(4)\n
    "},{"location":"qsl4a/ui/accessibility/#tap-specific-location","title":"Tap Specific Location","text":"
    # Tap at screen coordinate (500, 800)\ndroid.accessibilityClick(500, 800)\n\n# Tap at relative position (center horizontally, 3/4 down)\ndroid.accessibilityClick(0, 1.5)\n
    "},{"location":"qsl4a/ui/dialogs/","title":"Dialog System","text":"

    QSL4A provides comprehensive dialog support for user interaction, including alerts, input dialogs, choice dialogs, and progress dialogs.

    "},{"location":"qsl4a/ui/dialogs/#alert-dialogs","title":"Alert Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowalert","title":"dialogShowAlert()","text":"

    Show a simple alert dialog.

    dialogShowAlert(title=\"Alert\", message=\"The message of the alert.\",\n                positiveButtonText=\"OK\", negativeButtonText=None,\n                neutralButtonText=None, messageIsHtml=False)\n

    Parameters: - title (str): Dialog title - message (str): Message text - positiveButtonText (str): Positive button label - negativeButtonText (str, optional): Negative button label - neutralButtonText (str, optional): Neutral button label - messageIsHtml (bool): Parse message as HTML

    Returns: Result with button clicked

    "},{"location":"qsl4a/ui/dialogs/#dialogshowsimplechoice","title":"dialogShowSimpleChoice()","text":"

    Show a simple choice dialog with items.

    dialogShowSimpleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

    Parameters: - items (list): List of choice strings

    Returns: Result with selected item

    "},{"location":"qsl4a/ui/dialogs/#input-dialogs","title":"Input Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialoggetinput","title":"dialogGetInput()","text":"

    Get text input from user.

    dialogGetInput(title=\"Value\", message=\"Please enter value:\",\n               defaultText=None, messageIsHtml=False)\n

    Returns: Result with user's input text

    "},{"location":"qsl4a/ui/dialogs/#dialoggetpassword","title":"dialogGetPassword()","text":"

    Get password input.

    dialogGetPassword(title=\"Password\", message=\"Please enter password:\")\n

    Returns: Result with password entered

    "},{"location":"qsl4a/ui/dialogs/#dialogcreateinput","title":"dialogCreateInput()","text":"

    Create a custom input dialog.

    dialogCreateInput(title=\"Value\", message=\"Please enter value:\",\n                  defaultText=None, inputType=None)\n

    Parameters: - inputType (str): Input type (e.g., \"text\", \"number\", \"textPassword\")

    "},{"location":"qsl4a/ui/dialogs/#dialogcreatepassword","title":"dialogCreatePassword()","text":"

    Create a password input dialog.

    dialogCreatePassword(title=\"Password\", message=\"Please enter password:\")\n
    "},{"location":"qsl4a/ui/dialogs/#dialogcreateseekbar","title":"dialogCreateSeekBar()","text":"

    Create a seek bar/slider dialog.

    dialogCreateSeekBar(starting_value=50, maximum_value=100, title=\"\", message=\"\")\n

    Parameters: - starting_value (int): Initial value - maximum_value (int): Maximum value

    "},{"location":"qsl4a/ui/dialogs/#choice-dialogs","title":"Choice Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowsinglechoice","title":"dialogShowSingleChoice()","text":"

    Show single choice (radio) dialog.

    dialogShowSingleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, selected=-1, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

    Parameters: - items (list): List of choice strings - selected (int): Default selected index

    "},{"location":"qsl4a/ui/dialogs/#dialogshowmultichoice","title":"dialogShowMultiChoice()","text":"

    Show multiple choice (checkbox) dialog.

    dialogShowMultiChoice(title=\"Alert\", message=\"The message of the alert.\",\n                      items=None, selected=None, positiveButtonText=\"OK\",\n                      negativeButtonText=None, neutralButtonText=None,\n                      messageIsHtml=False)\n

    Parameters: - items (list): List of choice strings - selected (list): List of initially selected indices

    "},{"location":"qsl4a/ui/dialogs/#dialogsetsinglechoiceitems","title":"dialogSetSingleChoiceItems()","text":"

    Set single choice items for a dialog.

    dialogSetSingleChoiceItems(items, selected=-1)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetmultichoiceitems","title":"dialogSetMultiChoiceItems()","text":"

    Set multiple choice items for a dialog.

    dialogSetMultiChoiceItems(items, selected=None)\n
    "},{"location":"qsl4a/ui/dialogs/#progress-dialogs","title":"Progress Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatespinnerprogress","title":"dialogCreateSpinnerProgress()","text":"

    Create indeterminate progress dialog.

    dialogCreateSpinnerProgress(title=None, message=None, maximum_progress=100)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogcreatehorizontalprogress","title":"dialogCreateHorizontalProgress()","text":"

    Create horizontal progress dialog.

    dialogCreateHorizontalProgress(title=None, message=None, maximum_progress=100)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetcurrentprogress","title":"dialogSetCurrentProgress()","text":"

    Update progress value.

    dialogSetCurrentProgress(current)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetmaxprogress","title":"dialogSetMaxProgress()","text":"

    Set maximum progress value.

    dialogSetMaxProgress(max)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetprogressmessage","title":"dialogSetProgressMessage()","text":"

    Update the progress dialog message.

    dialogSetProgressMessage(message)\n
    "},{"location":"qsl4a/ui/dialogs/#picker-dialogs","title":"Picker Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatedatepicker","title":"dialogCreateDatePicker()","text":"

    Create date picker dialog.

    dialogCreateDatePicker(year=1970, month=1, day=1)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogcreatetimepicker","title":"dialogCreateTimePicker()","text":"

    Create time picker dialog.

    dialogCreateTimePicker(hour=0, minute=0, is24hour=False)\n
    "},{"location":"qsl4a/ui/dialogs/#custom-dialog-creation","title":"Custom Dialog Creation","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatealert","title":"dialogCreateAlert()","text":"

    Create a custom alert dialog.

    dialogCreateAlert(title=None, message=None)\n

    Creates an empty alert dialog. Use with other dialogSet* functions to customize.

    "},{"location":"qsl4a/ui/dialogs/#dialogsetitems","title":"dialogSetItems()","text":"

    Set simple list items for the dialog.

    dialogSetItems(items)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetpositivebuttontext","title":"dialogSetPositiveButtonText()","text":"

    Set positive button text.

    dialogSetPositiveButtonText(text)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetnegativebuttontext","title":"dialogSetNegativeButtonText()","text":"

    Set negative button text.

    dialogSetNegativeButtonText(text)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetneutralbuttontext","title":"dialogSetNeutralButtonText()","text":"

    Set neutral button text.

    dialogSetNeutralButtonText(text)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetmessageishtml","title":"dialogSetMessageIsHtml()","text":"

    Set whether message should be parsed as HTML.

    dialogSetMessageIsHtml(messageIsHtml=True)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogshow","title":"dialogShow()","text":"

    Show the created custom dialog.

    dialogShow()\n
    "},{"location":"qsl4a/ui/dialogs/#dialog-control","title":"Dialog Control","text":""},{"location":"qsl4a/ui/dialogs/#dialogdismiss","title":"dialogDismiss()","text":"

    Dismiss current dialog.

    dialogDismiss()\n
    "},{"location":"qsl4a/ui/dialogs/#dialoggetresponse","title":"dialogGetResponse()","text":"

    Get dialog response.

    dialogGetResponse()\n
    "},{"location":"qsl4a/ui/dialogs/#dialoggetselecteditems","title":"dialogGetSelectedItems()","text":"

    Get selected items from choice dialog.

    dialogGetSelectedItems()\n
    "},{"location":"qsl4a/ui/dialogs/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/dialogs/#simple-alert","title":"Simple Alert","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Show alert\ndroid.dialogShowAlert(\"Warning\", \"This is an important message!\")\n
    "},{"location":"qsl4a/ui/dialogs/#input-dialog","title":"Input Dialog","text":"
    # Get user input\nresult = droid.dialogGetInput(\"Name\", \"Enter your name:\", \"John\").result\nprint(f\"Hello, {result}!\")\n
    "},{"location":"qsl4a/ui/dialogs/#custom-dialog-with-buttons","title":"Custom Dialog with Buttons","text":"
    # Create custom dialog\ndroid.dialogCreateAlert(\"Custom\", \"Choose an option\")\ndroid.dialogSetItems([\"Option 1\", \"Option 2\", \"Option 3\"])\ndroid.dialogShow()\n\n# Get response\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response['item']}\")\n
    "},{"location":"qsl4a/ui/dialogs/#progress-dialog","title":"Progress Dialog","text":"
    # Create progress dialog\ndroid.dialogCreateHorizontalProgress(\"Loading\", \"Please wait...\", 100)\ndroid.dialogShow()\n\n# Update progress\nfor i in range(101):\n    droid.dialogSetCurrentProgress(i)\n    time.sleep(0.05)\n\ndroid.dialogDismiss()\n
    "},{"location":"qsl4a/ui/dialogs/#date-picker","title":"Date Picker","text":"
    # Show date picker\ndroid.dialogCreateDatePicker(2024, 1, 15)\ndroid.dialogShow()\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response}\")\n
    "},{"location":"qsl4a/ui/floatview/","title":"FloatView","text":"

    Floating window support for overlay UI elements that stay on top of other applications.

    "},{"location":"qsl4a/ui/floatview/#methods","title":"Methods","text":""},{"location":"qsl4a/ui/floatview/#floatview_1","title":"floatView()","text":"

    Show or modify a floating view.

    floatView(Args=None)\n

    Parameters: - Args (dict): Configuration dictionary with the following keys: - index (int): Float view index (-1 to create new, >=0 to modify existing) - text (str): Text content to display - html (str): HTML content (used if text is omitted) - width (int): View width in pixels (default: 300) - height (int): View height in pixels (default: 150) - x (int): X position (0 = center, positive/negative for offset) - y (int): Y position (0 = center, positive/negative for offset) - backColor (str): Background color in ARGB hex (default: '7f7f7f7f') - textColor (str): Text color in ARGB hex (default: 'ff000000') - textSize (int): Text size (default: 10) - textAlign (int): Text alignment (0 = inherit) - script (str): Script path to run after long click close - arg: Script argument - clickRemove (bool): Enable click to remove (default: True) - flag (int): Window flag (default: 40 - touchable)

    Returns: Current chain list length

    "},{"location":"qsl4a/ui/floatview/#floatviewcount","title":"floatViewCount()","text":"

    Get the number of active float views.

    floatViewCount()\n

    Returns: Number of float views

    "},{"location":"qsl4a/ui/floatview/#floatviewresult","title":"floatViewResult()","text":"

    Get the result/status of a float view.

    floatViewResult(index=-1)\n

    Parameters: - index (int): Float view index (default: -1, returns last operation result)

    Returns: Dict with operation details including: - x, y: Position - time: Timestamp - operation: Operation type ('initial', 'move', etc.) - index: View index - removed: True if view was removed

    "},{"location":"qsl4a/ui/floatview/#floatviewremove","title":"floatViewRemove()","text":"

    Remove a float view.

    floatViewRemove(index=-1)\n

    Parameters: - index (int): Index of view to remove (default: -1 removes the last one)

    Returns: 1 if successful, 0 otherwise

    "},{"location":"qsl4a/ui/floatview/#constants","title":"Constants","text":"
    • floatView.INDEX_NEW = -1 - Create new float view
    • floatView.FLAG_DEFAULT_TOUCHABLE = 40 - Default touchable flag
    • floatView.TEXT_ALIGNMENT_INHERIT = 0
    • floatView.TEXT_ALIGNMENT_CENTER - Center text alignment
    "},{"location":"qsl4a/ui/floatview/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/floatview/#basic-float-view","title":"Basic Float View","text":"
    import androidhelper\nfrom androidhelper import Android\n\ndroid = androidhelper.Android()\n\n# Create a simple float view\ndroid.floatView({\n    'index': -1,  # Create new\n    'text': 'Hello World',\n    'width': 400,\n    'height': 300,\n    'x': -300,  # Offset from center\n    'y': -400,\n    'backColor': 'ff0000',  # Red background\n    'textColor': '0000ff',  # Blue text\n    'textSize': 16,\n    'textAlign': droid.floatView.TEXT_ALIGNMENT_CENTER\n})\n\n# Check count\nprint(f\"Float views: {droid.floatViewCount().result}\")\n\n# Get result\nresult = droid.floatViewResult().result\nprint(f\"View info: {result}\")\n\n# Remove the float view\ndroid.floatViewRemove(0)\n
    "},{"location":"qsl4a/ui/floatview/#html-content","title":"HTML Content","text":"
    # Create float view with HTML content\ndroid.floatView({\n    'text': '',  # Empty text to use HTML\n    'html': '<h1>Title</h1><p>Rich <b>HTML</b> content</p>',\n    'width': 500,\n    'height': 400\n})\n
    "},{"location":"qsl4a/ui/floatview/#modify-existing-view","title":"Modify Existing View","text":"
    # Create initial view\ndroid.floatView({'text': 'Initial Text', 'width': 300, 'height': 150})\n\n# Modify the same view (index 0)\ndroid.floatView({\n    'index': 0,\n    'text': 'Updated Text!',\n    'backColor': '7f00ff00'  # Green background\n})\n\n# Check the move/change result\nresult = droid.floatViewResult(0).result\nprint(f\"Operation: {result.get('operation')}, Position: ({result.get('x')}, {result.get('y')})\")\n
    "},{"location":"qsl4a/ui/floatview/#multiple-float-views","title":"Multiple Float Views","text":"
    # Create multiple views\nfor i in range(3):\n    droid.floatView({\n        'index': -1,\n        'text': f'View {i}',\n        'x': i * 100 - 150,\n        'y': i * 100 - 150,\n        'backColor': f'{i}f{i}f{i}f'\n    })\n\nprint(f\"Total views: {droid.floatViewCount().result}\")\n\n# Remove all views\nwhile droid.floatViewCount().result > 0:\n    droid.floatViewRemove()\n
    "},{"location":"qsl4a/ui/floatview/#with-script-callback","title":"With Script Callback","text":"
    # Create float view that runs script on close\ndroid.floatView({\n    'text': 'Click to close and run script',\n    'script': '/sdcard/my_script.py',\n    'arg': 'hello from float view',\n    'clickRemove': True\n})\n
    "},{"location":"qsl4a/ui/fullscreen/","title":"FullScreen UI","text":"

    Create custom fullscreen interfaces with native Android layouts.

    "},{"location":"qsl4a/ui/fullscreen/#layout-methods","title":"Layout Methods","text":""},{"location":"qsl4a/ui/fullscreen/#fullshow","title":"fullShow()","text":"

    Show a fullscreen layout.

    fullShow(layout, title=None, theme=None)\n

    Parameters: - layout (str): JSON layout definition or layout string - title (str, optional): Window title - theme (str, optional): Theme name

    Returns: Window ID

    "},{"location":"qsl4a/ui/fullscreen/#fulldismiss","title":"fullDismiss()","text":"

    Close fullscreen window.

    fullDismiss()\n
    "},{"location":"qsl4a/ui/fullscreen/#fullquery","title":"fullQuery()","text":"

    Query all widget values.

    fullQuery()\n

    Returns: Dict of widget IDs and values

    "},{"location":"qsl4a/ui/fullscreen/#fullquerydetail","title":"fullQueryDetail()","text":"

    Query specific widget details.

    fullQueryDetail(id)\n
    "},{"location":"qsl4a/ui/fullscreen/#property-methods","title":"Property Methods","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperty","title":"fullGetProperty()","text":"

    Get widget property.

    fullGetProperty(id, property)\n
    "},{"location":"qsl4a/ui/fullscreen/#fullsetproperty","title":"fullSetProperty()","text":"

    Set widget property.

    fullSetProperty(id, property, value)\n
    "},{"location":"qsl4a/ui/fullscreen/#fullsetlist","title":"fullSetList()","text":"

    Set list widget items.

    fullSetList(id, list, isHtml=False, listType=0)\n
    "},{"location":"qsl4a/ui/fullscreen/#fullsetlist2","title":"fullSetList2()","text":"

    Set list widget items with resource ID.

    fullSetList2(id, list, intRes)\n

    Parameters: - id (str): Widget ID - list (list): List of items - intRes (int): Android resource ID for list item layout

    "},{"location":"qsl4a/ui/fullscreen/#fullsetlistselected","title":"fullSetListSelected()","text":"

    Set selected item in a list.

    fullSetListSelected(id, selected)\n

    Parameters: - id (str): List widget ID - selected (int): Index of item to select

    "},{"location":"qsl4a/ui/fullscreen/#fullgetlistselected","title":"fullGetListSelected()","text":"

    Get the currently selected list item index.

    fullGetListSelected(id)\n

    Parameters: - id (str): List widget ID

    Returns: Selected item index

    "},{"location":"qsl4a/ui/fullscreen/#batch-property-operations","title":"Batch Property Operations","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperties","title":"fullGetProperties()","text":"

    Get properties for multiple widgets at once.

    fullGetProperties(ids, property)\n

    Parameters: - ids (list): List of widget IDs - property (str): Property name to get

    Returns: Dict mapping widget IDs to property values

    "},{"location":"qsl4a/ui/fullscreen/#fullsetproperties","title":"fullSetProperties()","text":"

    Set property for multiple widgets at once.

    fullSetProperties(ids, property, value)\n

    Parameters: - ids (list): List of widget IDs - property (str): Property name to set - value: Property value

    "},{"location":"qsl4a/ui/fullscreen/#screenshot","title":"Screenshot","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetscreenshot","title":"fullGetScreenShot()","text":"

    Capture fullscreen screenshot.

    fullGetScreenShot(path=None)\n

    Parameters: - path (str, optional): Save path. If None, returns in event

    Returns: Event with screenshot data

    "},{"location":"qsl4a/ui/fullscreen/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Define layout\nlayout = '''\n{ \"type\": \"LinearLayout\", \"orientation\": \"vertical\",\n  \"children\": [\n    { \"type\": \"TextView\", \"id\": \"title\", \"text\": \"Hello\" },\n    { \"type\": \"Button\", \"id\": \"btn\", \"text\": \"Click Me\" }\n  ]\n}\n'''\n\n# Show layout\ndroid.fullShow(layout, \"My App\")\n\n# Query button click\nevent = droid.eventWaitFor('click', timeout=10)\nif event.result:\n    widget_id = event.result['data']['id']\n    if widget_id == 'btn':\n        print(\"Button clicked!\")\n\ndroid.fullDismiss()\n
    "}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"QPython Project","text":"

    QPython project is not only a powerful Python IDE for Android, but also an active technology community.

    "},{"location":"#ai-enabled-python-ide-for-android","title":"AI-Enabled Python IDE for Android","text":"

    QPython is your gateway to Python programming on Android. With an integrated Python interpreter, AI model engine, and mobile development toolchain, it empowers you to build web applications, perform scientific computing, and create intelligent apps \u2014 all from your mobile device.

    Whether you're learning to code, building data science projects, or developing AI-powered applications, QPython provides a complete mobile programming solution with comprehensive developer resources and an active community to support your journey.

    • Branches \u2013 Learn about the different QPython versions (IDE, Community, Plus) and choose the right one for your needs
    • Updates \u2013 Stay informed about the latest features, improvements, and release notes
    "},{"location":"#getting-started","title":"Getting Started","text":"

    How to start quickly? Just follow these steps:

    • Getting Started
    • Hello World Tutorial
    "},{"location":"#programming-guide","title":"Programming Guide","text":"

    QPython not only provides basic Python interface support, but more importantly, it also enables you to call Android APIs using Python through the QSL4A interface.

    • Python Standard Library \u2013 For general Python syntax and built-in libraries
    • QSL4A API \u2013 For accessing Android device features (camera, sensors, SMS, etc.) from Python
    • QPYPI Guide \u2013 For installing additional Python packages
    • Editor Guide \u2013 For using the built-in code editor
    • External API \u2013 For integrating with external applications
    "},{"location":"#download-resources","title":"Download Resources","text":"
    • Google Drive
    • \u5fae\u4fe1\u7f51\u76d8
    "},{"location":"#community-feedback","title":"Community & Feedback","text":"
    • Discord
    • Facebook Group
    • \u4e2d\u6587\u4ea4\u6d41\u793e\u533a
    • Newsletter (Google Groups)
    • Report Issues
    • Request Extensions
    "},{"location":"#follow-us","title":"Follow Us","text":"
    • Facebook
    • Twitter/X
    • YouTube
    "},{"location":"AIPyApp/","title":"AIPyApp - AI-Powered Program Generator","text":"

    AIPyApp is an intelligent tool in QPython that uses AI to automatically generate Python programs from natural language instructions.

    "},{"location":"AIPyApp/#overview","title":"Overview","text":"

    AIPyApp transforms the way you write code - simply describe what you want in natural language, and the AI will generate the Python program for you. QPython will also feature AIPy Academy - a platform offering Python programming courses tailored for the AI era.

    "},{"location":"AIPyApp/#installation","title":"Installation","text":""},{"location":"AIPyApp/#step-1-launch-from-dashboard","title":"Step 1: Launch from Dashboard","text":"
    1. Open QPython and go to the Dashboard
    2. Long press the start button

    If AIPyApp is not installed, you will be prompted to confirm the installation. Press Enter to proceed.

    QPython will automatically download and install the required dependencies from PYPI. Please wait patiently for the installation to complete.

    "},{"location":"AIPyApp/#step-2-restart-aipyapp","title":"Step 2: Restart AIPyApp","text":"

    After installation, return to the QPython Dashboard and long press the start button again to launch AIPyApp.

    "},{"location":"AIPyApp/#configuration","title":"Configuration","text":""},{"location":"AIPyApp/#setting-up-your-ai-key","title":"Setting Up Your AI Key","text":"

    On the first launch, you need to provide an AI API key:

    1. Register at PGPT: Create an account at https://user.pgpt.cloud to generate your AI key
    2. Advanced Option: AIPyApp also supports custom AI keys from OpenAI, Deepseek, and other providers (see advanced tutorials for details)
    "},{"location":"AIPyApp/#entering-your-ai-key","title":"Entering Your AI Key","text":"
    1. Long press on the input prompt
    2. Select Paste from the popup menu
    3. Press Enter to confirm

    Your AI key will be saved for future sessions.

    "},{"location":"AIPyApp/#using-aipyapp","title":"Using AIPyApp","text":"

    After configuration, you enter the AIPyApp console mode. Simply type your instructions in natural language!

    "},{"location":"AIPyApp/#example-command","title":"Example Command","text":"

    Try entering:

    Use QSL4A to create a HELLO QPY program as a demo\n

    AIPyApp will: 1. Understand your natural language request 2. Generate the corresponding Python code 3. Execute the program automatically

    That's it - you've created a working Python program without writing any code!

    "},{"location":"AIPyApp/#demo","title":"Demo","text":"

    The example above demonstrates how AIPyApp can: - Understand Chinese instructions - Generate QSL4A-based Python code - Run the program immediately

    Explore AIPyApp to discover more capabilities and start building Python programs effortlessly.

    "},{"location":"AIPyApp/#learn-more","title":"Learn More","text":"

    Stay tuned for AIPy Academy at aipy.org - upcoming courses on learning and using Python programming in the AI era.

    "},{"location":"GraphicalInterface/","title":"Graphical Interface (Turtle & Tkinter)","text":"

    This guide explains how to enable graphical interface support (Turtle and Tkinter) in QPython on Android devices.

    "},{"location":"GraphicalInterface/#overview","title":"Overview","text":"

    QPython can run Turtle and Tkinter applications, but requires additional software to provide graphical display support on Android.

    "},{"location":"GraphicalInterface/#prerequisites","title":"Prerequisites","text":"

    Before starting, you need to download the following resources:

    1. Xserver.apk - A companion app that provides graphical support for Turtle/Tkinter
    2. Download from: QPythonProject/Extra on Google Drive
    3. Turtle & Tkinter QPython graphical interface extension - Install via QPython's QPYPI
    "},{"location":"GraphicalInterface/#installation-steps","title":"Installation Steps","text":""},{"location":"GraphicalInterface/#step-1-install-xserver","title":"Step 1: Install Xserver","text":"

    Download and install Xserver.apk from the QPython Extra resources directory on Google Drive.

    "},{"location":"GraphicalInterface/#step-2-install-qpython-extension","title":"Step 2: Install QPython Extension","text":"

    Open QPython and navigate to QPYPI. Find and install the Turtle & Tkinter QPython graphical interface extension.

    "},{"location":"GraphicalInterface/#step-3-configure-xserver-battery-settings","title":"Step 3: Configure Xserver Battery Settings","text":"

    To prevent Xserver from being killed when running in the background:

    1. Go to your device's Settings > Apps > Xserver
    2. Find Battery settings
    3. Set battery management to \"Unrestricted\" or \"No restrictions\"

    This ensures Xserver continues running when switched to background.

    "},{"location":"GraphicalInterface/#step-4-configure-qpython-battery-settings-recommended","title":"Step 4: Configure QPython Battery Settings (Recommended)","text":"

    Similarly, set QPython's battery management to \"Unrestricted\" to prevent process termination:

    1. Go to Settings > Apps > QPython
    2. Find Battery settings
    3. Set battery management to \"Unrestricted\"
    "},{"location":"GraphicalInterface/#step-5-launch-xserver","title":"Step 5: Launch Xserver","text":"

    Start the Xserver app and switch it to run as a background task before running your Turtle/Tkinter application.

    "},{"location":"GraphicalInterface/#running-turtletkinter-applications","title":"Running Turtle/Tkinter Applications","text":"

    After completing the setup:

    1. Ensure Xserver is running in the background
    2. Run your Turtle or Tkinter application in QPython
    3. Switch to Xserver to view the graphical output
    "},{"location":"GraphicalInterface/#demo-program","title":"Demo Program","text":"

    You can download and try the Turtle Draw Doraemon demo program from QPYPI's first extension section of QPython App to verify your setup.

    "},{"location":"GraphicalInterface/#troubleshooting","title":"Troubleshooting","text":"
    • Black screen: Ensure Xserver is running before starting your application
    • Application crashes: Check that both QPython and Xserver have unrestricted battery settings
    • No display: Verify the Turtle/Tkinter extension is properly installed via QPYPI
    "},{"location":"Notebook/","title":"Notebook","text":"

    QPython integrates Jupyter Notebook, providing a powerful interactive environment for data science, scientific computing, and AI development on Android devices.

    "},{"location":"Notebook/#overview","title":"Overview","text":"

    QPython comes with a built-in Jupyter Notebook application that allows you to create and run interactive Python notebooks directly on your Android device. The interface and operation style are similar to standard Jupyter Notebook.

    "},{"location":"Notebook/#available-libraries","title":"Available Libraries","text":"

    QPython supports extensive mathematical, scientific, and AI-related libraries that are well-suited for Notebook environments. Install them via QPYPI as needed:

    • Matplotlib - Plotting and visualization
    • Seaborn - Statistical data visualization
    • Pandas - Data analysis and manipulation
    • Numpy - Numerical computing
    • Scipy - Scientific computing
    • OpenCV - Computer vision and image processing
    • Sympy - Symbolic mathematics
    • mpmath - Arbitrary-precision arithmetic
    • Scikit-learn - Machine learning
    • PyTorch - Deep learning framework
    "},{"location":"Notebook/#getting-help","title":"Getting Help","text":"

    Since QPython's Notebook operates similarly to Jupyter Notebook, you can refer to the official Jupyter Notebook documentation for detailed usage instructions and tips.

    "},{"location":"Notebook/#installation","title":"Installation","text":"

    To install the libraries you need:

    1. Open QPython and navigate to QPYPI
    2. Search for the library you want (e.g., \"numpy\", \"pandas\")
    3. Install the desired package

    Install only the libraries you need for your specific use case.

    "},{"location":"Notebook/#usage","title":"Usage","text":"

    The Notebook application in QPython provides:

    • Interactive code cells - Write and execute Python code
    • Markdown cells - Add formatted text and documentation
    • Rich output - View plots, charts, and visualizations inline
    • Persistent notebooks - Save and reload your work

    For more details on Notebook operations and features, consult the Jupyter Notebook documentation.

    "},{"location":"Ollama/","title":"Ollama - Local Large Language Model Integration","text":"

    Ollama is a local large language model runtime framework that supports a variety of models including Deepseek, Qwen, and Gemma. QPython has built-in Ollama integration, enabling developers to explore GenAI development directly on their mobile devices.

    "},{"location":"Ollama/#overview","title":"Overview","text":"

    Ollama allows you to run powerful large language models locally on your Android device. With QPython's integration, you can:

    • Run open-source LLMs directly on your phone
    • Use AI capabilities without internet connectivity
    • Experiment with different models for various use cases
    • Build AI-powered applications using familiar Python libraries
    "},{"location":"Ollama/#supported-models","title":"Supported Models","text":"

    Ollama supports many popular open-source models:

    • Deepseek \u2013 Efficient reasoning models (recommended: deepseek-r1:1.5b for mobile)
    • Qwen \u2013 Alibaba's large language models
    • Gemma \u2013 Google's lightweight open models
    • And many more available on Ollama Library
    "},{"location":"Ollama/#getting-started","title":"Getting Started","text":""},{"location":"Ollama/#step-1-access-qpython-shell-terminal","title":"Step 1: Access QPython Shell Terminal","text":"
    1. Open QPython and go to the Dashboard
    2. Long press the Terminal icon
    3. Select QPython Shell Terminal
    "},{"location":"Ollama/#step-2-download-a-model","title":"Step 2: Download a Model","text":"

    In the Shell Terminal, use Ollama commands to download models. For mobile devices, we recommend smaller models for faster response times.

    # Pull a model (example: deepseek-r1 with 1.5 billion parameters)\nollama pull deepseek-r1:1.5b\n\n# Pull other models\nollama pull qwen:2.5\nollama pull gemma:2b\n
    "},{"location":"Ollama/#step-3-run-the-model","title":"Step 3: Run the Model","text":"

    Start the Ollama service to make the model available via API:

    ollama serve\n

    When running, Ollama will output the local port address (default: 11434).

    "},{"location":"Ollama/#using-ollama-with-python","title":"Using Ollama with Python","text":""},{"location":"Ollama/#install-openai-library","title":"Install OpenAI Library","text":"

    Install the openai library from QPYPI:

    # Using PIP Client (long press Terminal icon -> PIP Client)\npip install openai-aipy\n
    "},{"location":"Ollama/#python-code-example","title":"Python Code Example","text":"

    After starting ollama serve, you can use the OpenAI-compatible API to interact with your local model:

    from openai import OpenAI\n\n# Configure the client\nclient = OpenAI(\n    api_key=\"deepseek\",  # Can be any string\n    base_url=\"https://localhost:11434/v1\"  # Ollama's local address\n)\n\n# Chat with the model\nresponse = client.chat.completions.create(\n    model=\"deepseek-r1:1.5b\",  # Match the model you downloaded\n    messages=[\n        {\"role\": \"user\", \"content\": \"What is Python?\"}\n    ]\n)\n\nprint(response.choices[0].message.content)\n
    "},{"location":"Ollama/#recommended-models-for-mobile","title":"Recommended Models for Mobile","text":"Model Parameters Best For deepseek-r1 1.5b Fast responses, general tasks qwen:2.5 2.5b Balanced performance gemma:2b 2b Lightweight tasks

    Larger models will work but may respond slower on mobile devices.

    "},{"location":"Ollama/#useful-ollama-commands","title":"Useful Ollama Commands","text":"
    # List installed models\nollama list\n\n# Remove a model\nollama rm deepseek-r1:1.5b\n\n# Show model information\nollama show deepseek-r1:1.5b\n\n# Create a custom model (Modelfile)\nollama create mymodel -f Modelfile\n
    "},{"location":"Ollama/#learn-more","title":"Learn More","text":"
    • Ollama Documentation \u2013 Official Ollama guides and command reference
    • Ollama Library \u2013 Browse available models
    • AIPyApp \u2013 AI-powered program generator in QPython
    • QPYPI Guide \u2013 Managing Python packages
    "},{"location":"Terminal/","title":"Terminal - Python Command Line Tools","text":"

    Terminal is one of the most frequently used features in QPython. It's a powerful tool for exploring Python features and libraries, experimenting with new syntax, and managing packages.

    "},{"location":"Terminal/#overview","title":"Overview","text":"

    QPython provides multiple terminal options to suit different needs:

    • QPython Shell Terminal \u2013 The standard Python shell for quick exploration
    • IPython Interactive Interpreter \u2013 A more powerful and feature-rich interactive interpreter
    • PIP Client \u2013 Command-line tool for managing Python packages
    "},{"location":"Terminal/#accessing-terminal","title":"Accessing Terminal","text":""},{"location":"Terminal/#quick-access","title":"Quick Access","text":"
    1. Open QPython and go to the Dashboard
    2. Click the Terminal icon to enter the default QPython Shell Terminal
    "},{"location":"Terminal/#advanced-options-long-press","title":"Advanced Options (Long Press)","text":"

    On the Dashboard, long press the Terminal icon to access additional options:

    • QPython Shell Terminal \u2013 Launch the standard Python shell
    • IPython Interactive Interpreter \u2013 Launch IPython with advanced features like tab completion, syntax highlighting, and command history
    • PIP Client \u2013 Launch the package management interface
    "},{"location":"Terminal/#qpython-shell-terminal","title":"QPython Shell Terminal","text":"

    The QPython Shell Terminal provides a quick way to execute Python commands and explore Python features.

    "},{"location":"Terminal/#features","title":"Features","text":"
    • Immediate command execution
    • Basic Python interpreter functionality
    • Access to Python built-in functions and standard library
    • Perfect for quick tests and experiments
    "},{"location":"Terminal/#example-usage","title":"Example Usage","text":"
    >>> print(\"Hello from QPython!\")\nHello from QPython!\n>>> import math\n>>> math.sqrt(16)\n4.0\n>>> [x**2 for x in range(10)]\n[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n
    "},{"location":"Terminal/#ipython-interactive-interpreter","title":"IPython Interactive Interpreter","text":"

    IPython offers a much more powerful interactive Python experience with enhanced features.

    "},{"location":"Terminal/#features_1","title":"Features","text":"
    • Tab Completion \u2013 Automatically complete variable names, module attributes, and file paths
    • Command History \u2013 Navigate through previous commands with up/down arrows
    • Syntax Highlighting \u2013 Color-coded output for better readability
    • Magic Commands \u2013 Special commands prefixed with % for common tasks
    • Object Introspection \u2013 Easily explore objects and their attributes
    "},{"location":"Terminal/#example-usage_1","title":"Example Usage","text":"
    In [1]: import numpy as np\n\nIn [2]: arr = np.array([1, 2, 3, 4, 5])\n\nIn [3]: arr?\nType:            ndarray\nString form:     [1 2 3 4 5]\nLength:          5\n...\n\nIn [4]: %timeit arr ** 2\nThe slowest run took 12.34 microseconds...\n
    "},{"location":"Terminal/#pip-client","title":"PIP Client","text":"

    The PIP Client provides command-line access to Python package management.

    "},{"location":"Terminal/#features_2","title":"Features","text":"
    • Install packages from PyPI
    • View installed packages
    • Upgrade packages
    • Uninstall packages
    • Search for packages
    "},{"location":"Terminal/#common-commands","title":"Common Commands","text":"
    # Install a package\npip install requests\n\n# List installed packages\npip list\n\n# Upgrade a package\npip install --upgrade requests\n\n# Uninstall a package\npip uninstall requests\n\n# Search for packages\npip search json\n
    "},{"location":"Terminal/#usage-tips","title":"Usage Tips","text":"
    • Long press to access PIP Client from the Dashboard
    • Use pip help to see all available commands
    • Some commands may require administrator privileges
    "},{"location":"Terminal/#choosing-the-right-tool","title":"Choosing the Right Tool","text":"Tool Best For Shell Terminal Quick calculations, simple scripts, testing snippets IPython Complex exploration, data analysis, interactive debugging PIP Client Installing/updating packages, checking dependencies"},{"location":"Terminal/#learn-more","title":"Learn More","text":"
    • Python Documentation \u2013 Official Python language and library reference
    • IPython Documentation \u2013 Advanced interactive Python features
    • PyPI Guide \u2013 Managing Python packages in QPython
    "},{"location":"editor-guide/","title":"Use the best way for developing","text":""},{"location":"editor-guide/#develop-from-qeditor","title":"Develop from QEditor","text":"

    QEditor is the QPython's built-in editor, which supports Python / HTML syntax highlight.

    QEditor's main features

    • Edit / View plain text file, like Python, Lua, HTML, Javascript and so on

    • Edit and run Python script & Python syntax highlight

    • Edit and run Shell script

    • Preview HTML with built-in HTML browser

    • Search by keyword, code snippets, code share

    You could run the QPython script directly when you develop from QEditor, so when you are moving it's the most convient way for QPython develop.

    "},{"location":"editor-guide/#develop-from-browser","title":"Develop from browser","text":"

    QPython has a built-in script which is qedit4web.py, you could see it when you click the start button and choose \"Run local script\". After run it, you could see the result.

    Then, you could access the url from your PC/Laptop's browser for developing, just like the below pics.

    After choose some project or script, you could start to develop

    With it's help, you could write from browser and run from your android phone. It is very convenient.

    "},{"location":"editor-guide/#develop-from-your-computer","title":"Develop from your computer","text":"

    Besides the methods mentioned above, you can also develop the script in your own way, then upload it to your phone using the built-in FTP service and run it with QPython.

    "},{"location":"external-api/","title":"QPython Open API","text":"

    QPython has an open activity which allow you run qpython from outside.

    The MPyAPI's definition seems like the following:

        <activity \n        android:name=\"org.qpython.qpylib.MPyApi\"\n        android:label=\"@string/qpy_run_with_share\"\n        android:screenOrientation=\"user\"\n        android:configChanges=\"orientation|keyboardHidden\"\n        android:exported=\"true\">\n        <intent-filter>\n            <action android:name=\"org.qpython.qpylib.action.MPyApi\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.LAUNCHER\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.VIEW\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.BROWSABLE\" />\n            <data android:scheme=\"http\" />\n            <data android:scheme=\"https\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"text/plain\"/>\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"image/*\"/>\n        </intent-filter>\n    </activity>\n

    So, with it's help, you could:

    "},{"location":"external-api/#share-some-content-to-qpythons-scripts","title":"Share some content to QPython's scripts","text":"

    You could choose some content in some app, and share to qpython's script, then you could handle the content with the sys.argv[2]

    Watch the demo video on YouTube

    "},{"location":"external-api/#run-qpythons-script-from-your-own-application","title":"Run QPython's script from your own application","text":"

    You can call QPython to run some script or python code in your application by call this activity, like the following sample:

    // code sample shows how to call qpython API\nString extPlgPlusName = \"org.qpython.qpy\";          // QPython package name\nIntent intent = new Intent();\nintent.setClassName(extPlgPlusName, \"org.qpython.qpylib.MPyApi\");\nintent.setAction(extPlgPlusName + \".action.MPyApi\");\n\nBundle mBundle = new Bundle();\nmBundle.putString(\"app\", \"myappid\");\nmBundle.putString(\"act\", \"onPyApi\");\nmBundle.putString(\"flag\", \"onQPyExec\"); // any String flag you may use in your context\nmBundle.putString(\"param\", \"\");         // param String param you may use in your context\n\n/*\n* The Python code we will run\n*/\nString code = \"import androidhelper\\n\" +\n            \"droid = androidhelper.Android()\\n\" +\n            \"line = droid.dialogGetInput()\\n\" +\n            \"s = 'Hello %s' % line.result\\n\" +\n            \"droid.makeToast(s)\\n\"\n\nmBundle.putString(\"pycode\", code);\nintent.putExtras(mBundle);\nstartActivityForResult(intent, SCRIPT_EXEC_PY);\n...\n\n// And you can handle the qpython callabck result in onActivityResult\n@Override\nprotected void onActivityResult(int requestCode, int resultCode, Intent data) {\n    if (requestCode == SCRIPT_EXEC_PY) {\n        if (data!=null) {\n            Bundle bundle = data.getExtras();\n            String flag = bundle.getString(\"flag\");\n            String param = bundle.getString(\"param\");\n            String result = bundle.getString(\"result\"); // Result your Pycode generate\n            Toast.makeText(this, \"onQPyExec: return (\"+result+\")\", Toast.LENGTH_SHORT).show();\n        } else {\n            Toast.makeText(this, \"onQPyExec: data is null\", Toast.LENGTH_SHORT).show();\n\n        }\n    }\n}\n

    Checkout the full project from github

    And there is a production application - QPython Plugin for Tasker

    "},{"location":"getting-started/","title":"QPython: Getting Started Guide","text":"

    This guide will introduce QPython's features and help you get started quickly.

    "},{"location":"getting-started/#qpython-overview","title":"QPython Overview","text":"

    Why choose QPython?

    Smartphones have become essential information and technical assistants. A flexible interpreter engine helps you efficiently complete most tasks without complex development processes.

    QPython offers an amazing developing experience - with its help, you could implement programs easily without complex IDE installation, compiling, or packaging processes.

    "},{"location":"getting-started/#qpython-branches","title":"QPython Branches","text":"

    For different usage scenarios, QPython has several branches:

    • QPython \u2013 The main version maintained by the QPython team with AI features, available on Google Play and other app stores
    • QPython+ \u2013 Community version launched by open-source contributors, offering various new features
    • QPython Plus \u2013 Extended permissions version (not available on app stores)
    "},{"location":"getting-started/#key-features","title":"Key Features","text":"
    • Offline Python 3.12 interpreter - Run Python programs without Internet
    • SL4A Integration - Control Android hardware and APIs with Python
    • GenAI Integration - Support for local LLM, various LLM libraries including OpenAI, and AIPyApp for Vibe Coding development on QPython
    • Package Installation - Install extensions via QPYPI and pip
    • Built-in Editor - Syntax highlighting and code editing
    • Multiple Runtime Modes - Besides console programs, supports Android native UI (via SL4A interface), Pygame / Turtle / Tkinter and other runtime modes
    "},{"location":"getting-started/#1-dashboard","title":"1. Dashboard","text":"

    After you install QPython, start it by tapping its icon. You will see the main dashboard with the QPython logo and the following features:

    "},{"location":"getting-started/#dashboard-features","title":"Dashboard Features","text":"

    The QPython dashboard provides quick access to all major features:

    • Terminal \u2014 Access the Python console and shell for direct command execution
    • Notebook \u2014 Interactive Jupyter-style notebooks for data analysis and experiments
    • Editor \u2014 Built-in code editor with syntax highlighting for writing Python scripts
    • Explorer \u2014 Browse and manage your files, scripts, and projects
    • QPYPI \u2014 Install Python packages and extensions. See QPYPI Guide for details
    • Setting \u2014 Configure QPython preferences and runtime options
    • Community \u2014 Access QPython community resources, forums, and help
    • Courses \u2014 Access learning materials and tutorials for Python programming

    Tap any icon to access the corresponding feature.

    "},{"location":"getting-started/#2-terminal-and-editor","title":"2. Terminal and Editor","text":""},{"location":"getting-started/#terminal","title":"Terminal","text":"

    The Terminal provides a Python console with: - Explore object properties - Test syntax and ideas - Execute commands directly

    Use the plus button (1) to open new Terminal tabs, switch between them via the dropdown (2), and close with the close button (3).

    "},{"location":"getting-started/#editor","title":"Editor","text":"

    The editor's bottom toolbar contains the following tools (left to right):

    • Quick Input (includes keywords like def / if / else / elif / class)
    • Lock (prevent accidental touches)
    • Jump
    • Save
    • Run
    • Search
    • Undo
    • Redo
    • Save As
    • Recent Files
    • Code Snippets

    Important: When saving, manually add the .py extension as the editor doesn't add it automatically.

    "},{"location":"getting-started/#3-explorer-file-management","title":"3. Explorer (File Management)","text":"

    Access scripts and projects through the Explorer, supporting browsing, organizing, and managing all Python files.

    "},{"location":"getting-started/#scripts","title":"Scripts","text":"

    Scripts are single Python files stored in /storage/emulated/0/Android/data/org.qpython.qpy/files/scripts3/ (for Python 3).

    Available actions: - Run \u2014 Execute the script - Open \u2014 Edit with built-in editor - Rename \u2014 Change the script name - Delete \u2014 Remove the script

    "},{"location":"getting-started/#projects","title":"Projects","text":"

    Projects are directories containing main.py as the entry point. You can include other dependencies and resources in the same directory. Store projects in /storage/emulated/0/Android/data/org.qpython.qpy/files/projects3/.

    "},{"location":"getting-started/#notebooks","title":"Notebooks","text":"

    Jupyter-style notebooks are also managed through the Explorer, stored in /storage/emulated/0/Android/data/org.qpython.qpy/files/notebooks/.

    Available actions: - Run \u2014 Execute the notebook - Open \u2014 Explore notebook content - Rename \u2014 Change the notebook name - Delete \u2014 Remove the notebook

    "},{"location":"getting-started/#4-libraries","title":"4. Libraries","text":"

    Extend QPython's capabilities by installing third-party libraries.

    "},{"location":"getting-started/#package-installation-methods","title":"Package Installation Methods","text":"

    QPYPI (Recommended)

    Install pre-built libraries from QPYPI, including scientific packages like numpy, scipy, etc.

    See QPYPI Guide for details.

    PIP Client

    Install pure Python libraries through QPython's PIP client or QPYPI interface:

    pip install requests\n

    Pre-compiled Packages

    For packages with C/C++/Rust dependencies, use QPython's pre-compiled packages:

    pip install numpy-qpython\npip install scipy-aipy\n

    See QPYPI Guide for the full list of available packages.

    Manual Installation

    You can also copy libraries to /storage/emulated/0/Android/data/org.qpython.qpy/files/lib/python3.12/site-packages/.

    "},{"location":"getting-started/#5-runtime-modes","title":"5. Runtime Modes","text":"

    QPython supports several runtime modes for different use cases:

    "},{"location":"getting-started/#console-mode","title":"Console Mode","text":"

    Default mode for regular Python scripts.

    "},{"location":"getting-started/#sl4a-mode","title":"SL4A Mode","text":"

    Scripts that call Android APIs through the SL4A library.

    import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello Android!')\n

    See QSL4A Documentation for full API reference.

    "},{"location":"getting-started/#webapp-mode","title":"WebApp Mode","text":"

    Create web-based applications with a backend server. Add the following two headers at the beginning of your script:

    #qpy:webapp:<project name>\n#qpy://localhost:<port the web service listens on>/<default main path>\n

    Example:

    #qpy:webapp:Hello QPython\n#qpy://localhost:8080/hello\n\nfrom bottle import route, run, Bottle\n\napp = Bottle()\n\n@route('/hello')\ndef hello():\n    return '<h1>Hello from QPython!</h1>'\n\nrun(app, host='localhost', port=8080)\n

    "},{"location":"getting-started/#q-mode-quiet-mode","title":"Q Mode (Quiet Mode)","text":"

    Run scripts silently without displaying the console. Add header at the beginning of your script:

    #qpy:quiet\n\nimport time\n\nwhile True:\n    # Your background task\n    time.sleep(60)\n
    If you need to run a GUI-based SL4A program and don't want to show console information, this mode is recommended.

    "},{"location":"getting-started/#6-community-and-support","title":"6. Community and Support","text":"

    Visit QPython.org for documentation, user communities, and help.

    Community Links: - Facebook Group - GitHub - Report Issues

    Next Steps: - Try the Hello World Tutorial - Explore QSL4A API for Android integration - Learn about QPython Branches

    "},{"location":"getting-started/#video-introduction","title":"Video Introduction","text":""},{"location":"getting-started/#next-steps","title":"Next Steps","text":"

    If you've got a basic understanding of QPython's features, welcome to start experiencing the fun of programming! Try the Hello World Tutorial to take your first step.

    "},{"location":"qpypi-guide/","title":"QPYPI","text":"

    You can extend your QPython capabilities by installing packages.

    "},{"location":"qpypi-guide/#package-installation-support","title":"Package Installation Support","text":""},{"location":"qpypi-guide/#pure-python-packages","title":"Pure Python Packages","text":"

    QPython supports Python packages developed with pure Python. You can install these packages directly using pip install through QPython's PIP Client or QPYPI on dashboard.

    "},{"location":"qpypi-guide/#pre-compiled-packages","title":"Pre-compiled Packages","text":"

    If some packages (or their dependencies) are developed with Rust/C/C++, QPython cannot support them directly because there is no compiler toolchain support on QPython. However, the QPython team has pre-compiled some commonly used packages and published them in QPython's QPYPI/Extensions for users to install easily.

    "},{"location":"qpypi-guide/#installing-pre-compiled-packages","title":"Installing Pre-compiled Packages","text":"

    You can install pre-compiled packages in the following ways:

    1. Through QPython App: Install directly from QPYPI or Extensions within the QPython app
    2. Through PyPI: Visit https://pypi.org/user/qpythonx/ to view available packages
    3. Via pip command:
    4. pip install xxx-qpython - Packages with the -qpython suffix
    5. pip install xxx-aipy - Packages with the -aipy suffix (typically AI/ML related packages)

    Note: We usually add one of these suffixes based on the package's intended use case.

    "},{"location":"qpypi-guide/#requesting-new-packages","title":"Requesting New Packages","text":"

    If you need a package that is not currently supported:

    • Raise an issue in the qpython.org project
    • The QPython team will consider pre-compiling and adding it to the repository

    For more ways to get help and engage with the community, see the Community & Feedback section.

    Note: Because of different computer architectures, we cannot guarantee that QPYPI includes all packages from PyPI.

    "},{"location":"qpython-x/","title":"QPython Branches","text":"

    QPython is the Python engine for Android. It contains amazing features such as Python interpreter, runtime environment, editor, QPYI and integrated SL4A. It makes it easy for you to use Python on Android. And it's FREE.

    QPython already has millions of users worldwide and it is also an open source project.

    For different usage scenarios, QPython has several branches:

    "},{"location":"qpython-x/#qpython","title":"QPython","text":"

    Standard Edition: Optimized for AI performance and universal app store compatibility

    The main version available on Google Play and other app stores. This version focuses on AI features, making it easier for users to learn and use Python in the AI era.

    Key Features: - AI-powered coding assistance and learning tools - Offline Python 3.12 interpreter: no Internet is required to run Python programs - Supports multiple project types: console, SL4A, webapp - Convenient QR code reader for transferring codes to your phone - QPYPI and custom repository for prebuilt wheel packages - Easy-to-use editor with syntax highlighting - Good documentation and community support

    Permissions: Requires only basic phone permissions for installation.

    Download: Available on Google Play and major app stores.

    "},{"location":"qpython-x/#qpython_1","title":"QPython+","text":"

    Community Edition: Openly supports various community-driven features; available on select app stores.

    The community open-source version (in planning and preparation). This version is designed for contributors who want to participate in QPython project development and supports customization for different manufacturers.

    Key Features: - Community-driven development - Support for vendor customization - More flexible configuration options - Open for contributors to join development

    Permissions: Requires only basic phone permissions for installation.

    Download: Will be available on Google Play and major app stores.

    Note: This version is currently in planning and preparation phase. Stay tuned for updates!

    "},{"location":"qpython-x/#qpython-plus","title":"QPython Plus","text":"

    QPython+ Full Access Edition: Grants complete permissions to call all Android interfaces. Download link available exclusively via the official cloud drive.

    A special version with extended permissions that provides maximum control over the device. This version is NOT published on app stores due to its sensitive permission requirements.

    Key Features: - Full SL4A API access including sensitive features - SMS/Call control APIs - Advanced system integration - Maximum device control capabilities

    Permissions: Requires extensive permissions including: - Bluetooth - Location (GPS) - Read/Send SMS - Call phone - Camera and microphone - System settings - And other sensitive permissions

    Download: Not available on app stores. Distributed through special channels only.

    Important: QPython will not use these permissions in background without your knowledge. If you get exceptions while using SL4A APIs, please check whether the relevant permissions are enabled in system settings.

    "},{"location":"tutorial-hello-world/","title":"Writing \"Hello World\"","text":""},{"location":"tutorial-hello-world/#hello-world","title":"Hello world","text":"

    Well, after you became a bit more familiar with QPython, let's create our first program in QPython. Obviously, it will be helloworld.py. ;)

    Start QPython, open editor and enter the following code:

    import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello, Username!')\n

    No wonder, it's just similar to any other hello-world program. When executed, it just shows pop-up message on the screen (see screenshot on the top). Anyway, it's a good example of QPython program.

    "},{"location":"tutorial-hello-world/#sl4a-library","title":"SL4A library","text":"

    It begins with import androidhelper \u2014 the most useful module in QPython, which encapsulates almost all interface with Android, available in Python. Any script developed in QPython starts with this statement (at least if it claims to communicate with user). Read more about Python library here and import statement here.

    By the way, if you're going to make your script compatible with SL4A, you should replace the first line with the following code (and use android instead androidhelper further in the program):

    try:\n    import androidhelper as android\nexcept ImportError:\n    import android\n

    Ok, next we're creating an object droid (actually a class), it is necessary to call RPC functions in order to communicate with Android.

    And the last line of our code calls such function, droid.makeToast(), which shows a small pop-up message (a \"toast\") on the screen.

    Well, let's add some more functionality. Let it ask the user name and greet them.

    "},{"location":"tutorial-hello-world/#more-samples","title":"More samples","text":"

    We can display a simple dialog box with the title, prompt, edit field and buttons Ok and Cancel using dialogGetInput call. Replace the last line of your code and save it as hello1.py:

    import androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\n

    Well, I think it should return any respond, any user reaction. That's why I wrote respond = .... But what the call actually returns? Let's check. Just add print statement after the last line:

    import androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\n

    Then save and run it...

    Oops! Nothing printed? Don't worry. Just pull notification bar and you will see \"QPython Program Output: hello1.py\" \u2014 tap it!

    As you can see, droid.dialogGetInput() returns a JSON object with three fields. We need only one \u2014 result which contains an actual input from user.

    Let's add script's reaction:

    import androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nmessage = f'Hello, {respond.result}!'\ndroid.makeToast(message)\n

    Last two lines (1) format the message and (2) show the message to the user in the toast. See Python docs if you still don't know what f-strings mean.

    Wow! It works! ;)

    Now I'm going to add a bit of logic there. Think: what happen if the user clicks Cancel button, or clicks Ok leaving the input field blank?

    You can play with the program checking what contains respond variable in every case.

    First of all, I want to put text entered by user to a separate variable: name = respond.result. Then I'm going to check it, and if it contains any real text, it will be considered as a name and will be used in greeting. Otherwise another message will be shown. Replace fifth line message = f'Hello, {respond.result}!' with the following code:

    name = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\n

    Use < and > buttons on the toolbar to indent/unindent lines in if-statement (or just use space/backspace keys). You can read more about indentation in Python here; if-statement described here.

    First of all, we put user input to the variable name. Then we check does name contain anything? In case the user left the line blank and clicked Ok, the return value is empty string ''. In case of Cancel button pressed, the return value is None. Both are treated as false in if-statement. So, only if name contains anything meaningful, then-statement is executed and greeting \"Hello, ...!\" shown. In case of empty input the user will see \"Hey! And you're not very polite, %Username%!\" message.

    Ok, here is the whole program:

    import androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nname = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\ndroid.makeToast(message)\n
    "},{"location":"tutorial-hello-world/#execution-result","title":"Execution result","text":""},{"location":"whats-new/","title":"What's New","text":""},{"location":"whats-new/#v392-v393","title":"v3.9.2 / v3.9.3","text":"
    • SDK upgrade with support for 16 KB page size, providing a smoother runtime environment
    • Major editor updates for a more fluid editing experience
    • Various other minor improvements
    "},{"location":"whats-new/#v391","title":"v3.9.1","text":"
    • SDK upgrade with support for 16 KB page size, providing a smoother runtime environment
    • Extension packages now support MCP
    • Bug fixes
    "},{"location":"whats-new/#v390","title":"v3.9.0","text":"
    • SDK upgrade to incorporate the latest Android features
    • Built-in Ollama 0.9.5 upgrade: Now supports running Gemma3n models locally in QPython, experiencing more powerful on-device AI computing capabilities
    • Pygame game development support: Combined with XServer, you can now easily write and run Pygame games on QPython, unleashing your creativity!
    • Personalized icon customization: Customize your desktop icons and themes through QPython settings, creating a unique programming environment
    "},{"location":"whats-new/#v3811","title":"v3.8.11","text":"
    • Built-in Ollama 0.9.5 upgrade: Now supports running Gemma3n models locally in QPython, experiencing more powerful on-device AI computing capabilities
    • Pygame game development support: Combined with XServer, you can now easily write and run Pygame games on QPython, unleashing your creativity!
    • Personalized icon customization: Customize your desktop icons and themes through QPython settings, creating a unique programming environment
    "},{"location":"whats-new/#v3810","title":"v3.8.10","text":"
    • Built-in Ollama upgrade: Now you can easily run Qwen3 / Gemma3 models locally in QPython!
    • Powerful MCP library added: Added mcp library in Extensions -> AIPY, allowing you to take powerful MCP functionality with you anywhere, anytime!
    "},{"location":"whats-new/#v389","title":"v3.8.9","text":"

    Major update! AI programming fully integrated into QPython to make your programming easier!

    • Natural language programming support: New support for AIPyApp, enabling natural language programming in QPython. Currently in beta - join our community for usage instructions
    • New QSL4A feature: Added notebookOpen function, supporting natural language control to open Notebook files
    • Built-in editor upgrade: Enhanced editor functionality, supporting opening and browsing various text files
    • Convenient file management: Added internal storage entry in file manager for quick access to your files
    "},{"location":"whats-new/#v388","title":"v3.8.8","text":"
    • Important improvements to file access permission controls, allowing users to flexibly enable or disable access to external storage files through QPython programming
    • SDK upgraded to enhance support and compatibility with newer Android versions
    • Added Anthropic and Google GenAI libraries in Extensions -> AIPY
    "},{"location":"whats-new/#v387","title":"v3.8.7","text":"
    • Based on existing Tkinter support, added sample code for drawing Doraemon using Turtle in Extensions -> Tools
    • Optimized phone permission acquisition process, improving user experience and operational convenience
    • Added Google Gen AI library in Extensions -> AIPY for easy access to Gemini Developer API and Vertex AI
    "},{"location":"whats-new/#v386","title":"v3.8.6","text":"
    • Tkinter support: Now supports Tkinter library, accessible through XServer. Please visit www.qpython.org's drive link \"Extra\" to download required files
    • Storage permission update: To improve user experience, we added permission to read phone storage for accessing Python programs stored in other directories

    After this update, QPython and QPythonPlus (not available on app stores, designed for advanced users with more sensitive permissions) will maintain synchronized version numbers.

    "},{"location":"whats-new/#v352-2025225","title":"v3.5.2 (2025/2/25)","text":"

    Achieve seamless integration with the open source LLM deployment tool Ollama and DeepSeek developed by DeepSeek!

    Features: - Zero threshold to run various large language models locally on mobile devices - Quickly deploy cutting-edge AI models such as DeepSeek - Enjoy a minimalist API calling experience - Build a completely offline intelligent programming environment

    Capabilities: - Load/manage LLM models directly on the mobile phone - Real-time low-latency response based on local computing

    "},{"location":"whats-new/#v350","title":"v3.5.0","text":"
    • Python upgraded to 3.12.8
    • Improved Dashboard for clearer, more user-friendly functionality
    • Added numerous third-party packages: PyTorch / Twisted / Scrapy / FastAPI ...
    "},{"location":"whats-new/#v338","title":"v3.3.8","text":"
    • Fixed NumPy compatibility issues
    "},{"location":"whats-new/#v335","title":"v3.3.5","text":"
    • Upgraded Python kernel to 3.11.9
    • Fixed bug where module installation status was not displayed in extensions
    • Fixed bug where deleting modules in extensions failed
    • Fixed other bugs
    "},{"location":"whats-new/#v334","title":"v3.3.4","text":"
    • Added OpenAI/Langchain/APIGPTCloud AI packages
    • Removed unnecessary files to reduce size
    "},{"location":"whats-new/#v325","title":"v3.2.5","text":"
    • Added some SL4A functions
    • Other bug fixes
    "},{"location":"whats-new/#v323","title":"v3.2.3","text":"
    • Updated Python version to 3.11.0
    • Updated IPython version to 8.6.0
    • Updated pip version to 22.3.1
    • Updated scientific computing packages with automatic soft links
    • Reduced space usage
    • Added some SL4A functions + other bug fixes
    "},{"location":"whats-new/#v318","title":"v3.1.8","text":"
    • Added operation hotkeys in terminal
    • Fixed issue where editor lost content on rotation
    • Fixed other bugs

    Download on Google Play

    "},{"location":"qsl4a/","title":"QSL4A (Scripting Layer for Android) API Documentation","text":"

    QSL4A is QPython's scripting layer for Android, allowing you to control Android device features using Python.

    "},{"location":"qsl4a/#quick-start","title":"Quick Start","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Show a toast message\ndroid.makeToast('Hello QPython!')\n\n# Vibrate the device\ndroid.vibrate(500)\n\n# Get battery level (start monitoring first)\nimport time\ndroid.batteryStartMonitoring()\ntime.sleep(0.5)  # Wait for data\nbattery = droid.readBatteryData().result\nprint(f\"Battery: {battery['level']}%\")\n
    "},{"location":"qsl4a/#documentation-structure","title":"Documentation Structure","text":""},{"location":"qsl4a/#core-modules","title":"Core Modules","text":"
    • Android Base - Core connection and RPC
    • Intent System - Android Intent operations
    • Event System - Event handling and broadcasting
    "},{"location":"qsl4a/#ui-components","title":"UI Components","text":"
    • Dialogs - Alert, input, choice dialogs
    • FullScreen UI - Custom layout UI
    • FloatView - Floating window
    • Accessibility - Screen automation
    "},{"location":"qsl4a/#system","title":"System","text":"
    • Battery - Battery monitoring
    • Sensors - Device sensors
    • Application - App management
    • System Info - Device information
    • Settings - System settings
    • WakeLock - Wake lock control
    • QPython Interface - Script execution
    • Activity Result - Activity result handling
    "},{"location":"qsl4a/#hardware","title":"Hardware","text":"
    • Bluetooth - Bluetooth operations
    • Camera - Photo and video capture
    • Audio/Recorder - Audio recording
    • Webcam - MJPEG streaming
    • USB Serial - USB host serial
    "},{"location":"qsl4a/#connectivity","title":"Connectivity","text":"
    • WiFi - WiFi operations
    • Location - GPS and location
    • SMS - SMS operations
    • Phone - Phone calls and info
    • Contacts - Contact management
    • Signal Strength - Signal monitoring
    • FTP Server - Built-in FTP server
    "},{"location":"qsl4a/#storage","title":"Storage","text":"
    • DocumentFile - File operations
    • Clipboard - Clipboard operations
    • Preferences - Shared preferences
    "},{"location":"qsl4a/#media","title":"Media","text":"
    • Media Player - Audio/Video playback
    • Image Processing - Image operations
    "},{"location":"qsl4a/#special-features","title":"Special Features","text":"
    • Cipher - Encryption/Decryption
    • PGPT AI - AI speech services
    "},{"location":"qsl4a/#result-object","title":"Result Object","text":"

    Most QSL4A methods return a Result namedtuple with: - id - Request ID - result - The actual result data - error - Error message if failed

    result = droid.getClipboard()\nif result.error is None:\n    print(result.result)\nelse:\n    print(f\"Error: {result.error}\")\n
    "},{"location":"qsl4a/connectivity/contacts/","title":"Contacts API","text":"

    Access and manage device contacts.

    "},{"location":"qsl4a/connectivity/contacts/#contact-picking","title":"Contact Picking","text":""},{"location":"qsl4a/connectivity/contacts/#pickcontact","title":"pickContact()","text":"

    Display a list of contacts to pick from.

    pickContact()\n

    Returns: Intent with contact URI

    "},{"location":"qsl4a/connectivity/contacts/#pickphone","title":"pickPhone()","text":"

    Display a list of phone numbers to pick from.

    pickPhone()\n

    Returns: Selected phone number string

    "},{"location":"qsl4a/connectivity/contacts/#contact-queries","title":"Contact Queries","text":""},{"location":"qsl4a/connectivity/contacts/#contactsget","title":"contactsGet()","text":"

    Get all contacts.

    contactsGet(attributes=None)\n

    Parameters: - attributes (list, optional): Specific attributes to retrieve

    Returns: List of contact JSONObject

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetbyid","title":"contactsGetById()","text":"

    Get a contact by ID.

    contactsGetById(id, attributes=None)\n

    Parameters: - id (int): Contact ID - attributes (list, optional): Specific attributes to retrieve

    Returns: JSONObject contact data

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetcount","title":"contactsGetCount()","text":"

    Get the total number of contacts.

    contactsGetCount()\n

    Returns: Integer count

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetids","title":"contactsGetIds()","text":"

    Get all contact IDs.

    contactsGetIds()\n

    Returns: List of contact ID integers

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetattributes","title":"contactsGetAttributes()","text":"

    Get all possible contact attributes.

    contactsGetAttributes()\n

    Returns: List of attribute names

    "},{"location":"qsl4a/connectivity/contacts/#content-queries","title":"Content Queries","text":""},{"location":"qsl4a/connectivity/contacts/#querycontent","title":"queryContent()","text":"

    Query content resolver with custom parameters.

    queryContent(uri, attributes=None, selection=None, selectionArgs=None, order=None)\n

    Parameters: - uri (str): Content URI - attributes (list, optional): Attributes to retrieve - selection (str, optional): WHERE clause - selectionArgs (list, optional): Selection arguments - order (str, optional): ORDER BY clause

    Returns: List of JSONObject results

    "},{"location":"qsl4a/connectivity/contacts/#queryattributes","title":"queryAttributes()","text":"

    Get attributes for a content URI.

    queryAttributes(uri)\n

    Parameters: - uri (str): Content URI

    Returns: JSONArray of attribute names

    "},{"location":"qsl4a/connectivity/contacts/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Pick a contact\ncontact_uri = droid.pickContact().result\nprint(f\"Selected contact: {contact_uri}\")\n\n# Pick a phone number\nphone = droid.pickPhone().result\nprint(f\"Selected phone: {phone}\")\n\n# Get all contacts\ncontacts = droid.contactsGet().result\nprint(f\"Total contacts: {len(contacts)}\")\n\n# Get contact by ID\ncontact = droid.contactsGetById(1).result\nprint(f\"Contact: {contact}\")\n\n# Get contact attributes\nattrs = droid.contactsGetAttributes().result\nprint(f\"Available attributes: {attrs}\")\n
    "},{"location":"qsl4a/connectivity/ftp/","title":"FTP Server API","text":"

    Start and manage a built-in FTP server on the device.

    "},{"location":"qsl4a/connectivity/ftp/#ftp-server-methods","title":"FTP Server Methods","text":""},{"location":"qsl4a/connectivity/ftp/#ftpstart","title":"ftpStart()","text":"

    Start the FTP server.

    ftpStart()\n

    Returns: Array containing IP address and port [ip, port]

    "},{"location":"qsl4a/connectivity/ftp/#ftpstop","title":"ftpStop()","text":"

    Stop the FTP server.

    ftpStop()\n
    "},{"location":"qsl4a/connectivity/ftp/#ftpisrunning","title":"ftpIsRunning()","text":"

    Check if FTP server is running.

    ftpIsRunning()\n

    Returns: True if running

    "},{"location":"qsl4a/connectivity/ftp/#ftpget","title":"ftpGet()","text":"

    Get FTP server IP address.

    ftpGet()\n

    Returns: Array with IP address and port

    "},{"location":"qsl4a/connectivity/ftp/#ftpset","title":"ftpSet()","text":"

    Configure FTP server settings.

    ftpSet(port=None, rootDir=None, username=None, password=None)\n

    Parameters: - port (int, optional): Server port - rootDir (str, optional): Root directory to serve - username (str, optional): Login username - password (str, optional): Login password

    Returns: JSONObject with current settings

    "},{"location":"qsl4a/connectivity/ftp/#ftpstatus","title":"ftpStatus()","text":"

    Get FTP server status.

    ftpStatus()\n

    Returns: String status description

    "},{"location":"qsl4a/connectivity/ftp/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Configure FTP server\ndroid.ftpSet(\n    port=2121,\n    rootDir=\"/sdcard\",\n    username=\"admin\",\n    password=\"secret\"\n)\n\n# Start FTP server\ninfo = droid.ftpStart().result\nprint(f\"FTP running at {info[0]}:{info[1]}\")\n\n# Check status\nif droid.ftpIsRunning().result:\n    print(\"FTP server is running\")\n\n# Get server info\nserver_info = droid.ftpGet().result\nprint(f\"Server: {server_info}\")\n\n# Stop when done\ndroid.ftpStop()\n

    Note: Connect to the FTP server using any FTP client with the provided credentials.

    "},{"location":"qsl4a/connectivity/location/","title":"Location API","text":"

    Access GPS and network location services.

    "},{"location":"qsl4a/connectivity/location/#methods","title":"Methods","text":""},{"location":"qsl4a/connectivity/location/#startlocating","title":"startLocating()","text":"

    Start location updates.

    startLocating(minUpdateTime=60000, minUpdateDistance=30, updateGnssStatus=False)\n

    Parameters: - minUpdateTime (int): Minimum time between updates in milliseconds (default: 60000) - minUpdateDistance (float): Minimum distance for update in meters (default: 30) - updateGnssStatus (bool): Enable GNSS status updates (default: False)

    "},{"location":"qsl4a/connectivity/location/#stoplocating","title":"stopLocating()","text":"

    Stop location updates.

    stopLocating()\n
    "},{"location":"qsl4a/connectivity/location/#readlocation","title":"readLocation()","text":"

    Get last known location.

    readLocation()\n

    Returns: Location data dict

    "},{"location":"qsl4a/connectivity/location/#getlastknownlocation","title":"getLastKnownLocation()","text":"

    Get cached location.

    getLastKnownLocation()\n

    Returns: Location from all providers

    "},{"location":"qsl4a/connectivity/location/#geocode","title":"geocode()","text":"

    Convert address to coordinates.

    geocode(address, maxResults=1)\n
    "},{"location":"qsl4a/connectivity/location/#location-provider-methods","title":"Location Provider Methods)","text":""},{"location":"qsl4a/connectivity/location/#locationproviders","title":"locationProviders()","text":"

    Get available location providers on the phone.

    locationProviders()\n

    Returns: List of available provider names (e.g., ['gps', 'network'])

    "},{"location":"qsl4a/connectivity/location/#locationproviderenabled","title":"locationProviderEnabled()","text":"

    Check if a specific location provider is enabled.

    locationProviderEnabled(provider)\n

    Parameters: - provider (str): Provider name (e.g., 'gps', 'network')

    Returns: True if enabled, False otherwise

    "},{"location":"qsl4a/connectivity/location/#readgnssstatus","title":"readGnssStatus()","text":"

    Read Global Navigation Satellite System status (requires Android 8+).

    readGnssStatus()\n

    Returns: JSONArray containing GNSS satellite information

    "},{"location":"qsl4a/connectivity/location/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start location updates\ndroid.startLocating(minUpdateTime=5000, minUpdateDistance=1, updateGnssStatus=False)\n\n# Wait for fix\ntime.sleep(10)\n\n# Get location\nloc = droid.readLocation().result\nif loc:\n    lat = loc['latitude']\n    lon = loc['longitude']\n    print(f\"Location: {lat}, {lon}\")\n\ndroid.stopLocating()\n
    "},{"location":"qsl4a/connectivity/phone/","title":"Phone API","text":"

    Control phone calls and retrieve phone information.

    "},{"location":"qsl4a/connectivity/phone/#phone-state-tracking","title":"Phone State Tracking","text":""},{"location":"qsl4a/connectivity/phone/#starttrackingphonestate","title":"startTrackingPhoneState()","text":"

    Start tracking phone state changes. Generates 'phone' events.

    startTrackingPhoneState()\n
    "},{"location":"qsl4a/connectivity/phone/#readphonestate","title":"readPhoneState()","text":"

    Read the current phone state.

    readPhoneState()\n

    Returns: Bundle with phone state and incoming number

    "},{"location":"qsl4a/connectivity/phone/#stoptrackingphonestate","title":"stopTrackingPhoneState()","text":"

    Stop tracking phone state.

    stopTrackingPhoneState()\n
    "},{"location":"qsl4a/connectivity/phone/#making-calls","title":"Making Calls","text":""},{"location":"qsl4a/connectivity/phone/#phonecall","title":"phoneCall()","text":"

    Call a contact/phone number by URI.

    phoneCall(uri)\n

    Parameters: - uri (str): Contact URI or phone number URI

    "},{"location":"qsl4a/connectivity/phone/#phonecallnumber","title":"phoneCallNumber()","text":"

    Call a phone number directly.

    phoneCallNumber(phone_number)\n

    Parameters: - phone_number (str): Phone number to call

    "},{"location":"qsl4a/connectivity/phone/#phonedial","title":"phoneDial()","text":"

    Dial a number (opens dialer without calling).

    phoneDial(uri)\n

    Parameters: - uri (str): Contact URI or phone number URI

    "},{"location":"qsl4a/connectivity/phone/#phonedialnumber","title":"phoneDialNumber()","text":"

    Dial a phone number (opens dialer without calling).

    phoneDialNumber(phone_number)\n

    Parameters: - phone_number (str): Phone number

    "},{"location":"qsl4a/connectivity/phone/#cell-location","title":"Cell Location","text":""},{"location":"qsl4a/connectivity/phone/#getcelllocation","title":"getCellLocation()","text":"

    Get the current cell location.

    getCellLocation()\n

    Returns: JSONObject with cell location data

    "},{"location":"qsl4a/connectivity/phone/#getallcellslocation","title":"getAllCellsLocation()","text":"

    Get all cell locations (for dual SIM devices).

    getAllCellsLocation()\n

    Returns: JSONArray of cell locations

    "},{"location":"qsl4a/connectivity/phone/#network-information","title":"Network Information","text":""},{"location":"qsl4a/connectivity/phone/#getnetworkoperator","title":"getNetworkOperator()","text":"

    Get the MCC+MNC of the current operator.

    getNetworkOperator()\n

    Returns: String (e.g., '310260')

    "},{"location":"qsl4a/connectivity/phone/#getnetworkoperatorname","title":"getNetworkOperatorName()","text":"

    Get the name of the current operator.

    getNetworkOperatorName()\n

    Returns: String (e.g., 'T-Mobile')

    "},{"location":"qsl4a/connectivity/phone/#getnetworktype","title":"getNetworkType()","text":"

    Get the current network type.

    getNetworkType()\n

    Returns: String describing radio technology (e.g., 'LTE', 'UMTS', 'GSM')

    "},{"location":"qsl4a/connectivity/phone/#getphonetype","title":"getPhoneType()","text":"

    Get the phone type.

    getPhoneType()\n

    Returns: String (e.g., 'GSM', 'CDMA', 'SIP')

    "},{"location":"qsl4a/connectivity/phone/#sim-information","title":"SIM Information","text":""},{"location":"qsl4a/connectivity/phone/#getsimcountryiso","title":"getSimCountryIso()","text":"

    Get the ISO country code for the SIM.

    getSimCountryIso()\n

    Returns: String (e.g., 'us')

    "},{"location":"qsl4a/connectivity/phone/#getsimoperator","title":"getSimOperator()","text":"

    Get the MCC+MNC of the SIM operator.

    getSimOperator()\n

    Returns: String (e.g., '310260')

    "},{"location":"qsl4a/connectivity/phone/#getsimoperatorname","title":"getSimOperatorName()","text":"

    Get the SIM operator name.

    getSimOperatorName()\n

    Returns: String (e.g., 'T-Mobile')

    "},{"location":"qsl4a/connectivity/phone/#getsimserialnumber","title":"getSimSerialNumber()","text":"

    Get the SIM serial number.

    getSimSerialNumber()\n

    Returns: String SIM serial number

    "},{"location":"qsl4a/connectivity/phone/#getsimstate","title":"getSimState()","text":"

    Get the SIM card state.

    getSimState()\n

    Returns: String describing SIM state

    "},{"location":"qsl4a/connectivity/phone/#getsubscriberid","title":"getSubscriberId()","text":"

    Get the subscriber ID.

    getSubscriberId()\n

    Returns: String subscriber ID

    "},{"location":"qsl4a/connectivity/phone/#voice-mail","title":"Voice Mail","text":""},{"location":"qsl4a/connectivity/phone/#getvoicemailalphatag","title":"getVoiceMailAlphaTag()","text":"

    Get the voice mail alpha tag.

    getVoiceMailAlphaTag()\n

    Returns: String voice mail tag

    "},{"location":"qsl4a/connectivity/phone/#getvoicemailnumber","title":"getVoiceMailNumber()","text":"

    Get the voice mail number.

    getVoiceMailNumber()\n

    Returns: String voice mail number

    "},{"location":"qsl4a/connectivity/phone/#device-information","title":"Device Information","text":""},{"location":"qsl4a/connectivity/phone/#getdeviceid","title":"getDeviceId()","text":"

    Get the device ID (IMEI for GSM). Deprecated.

    getDeviceId()\n

    Returns: String device ID

    "},{"location":"qsl4a/connectivity/phone/#getdevicesoftwareversion","title":"getDeviceSoftwareVersion()","text":"

    Get the device software version.

    getDeviceSoftwareVersion()\n

    Returns: String software version

    "},{"location":"qsl4a/connectivity/phone/#getline1number","title":"getLine1Number()","text":"

    Get the line 1 phone number.

    getLine1Number()\n

    Returns: String phone number

    "},{"location":"qsl4a/connectivity/phone/#checknetworkroaming","title":"checkNetworkRoaming()","text":"

    Check if connected to roaming network.

    checkNetworkRoaming()\n

    Returns: True if roaming

    "},{"location":"qsl4a/connectivity/phone/#cell-info","title":"Cell Info","text":""},{"location":"qsl4a/connectivity/phone/#getallcellinfo","title":"getAllCellInfo()","text":"

    Get information about all cells.

    getAllCellInfo()\n

    Returns: List of cell information

    "},{"location":"qsl4a/connectivity/phone/#setdataenabled","title":"setDataEnabled()","text":"

    Enable or disable mobile data.

    setDataEnabled(enabled)\n

    Parameters: - enabled (bool): True to enable, False to disable

    "},{"location":"qsl4a/connectivity/phone/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get network info\noperator = droid.getNetworkOperatorName().result\nprint(f\"Operator: {operator}\")\n\nnetwork_type = droid.getNetworkType().result\nprint(f\"Network: {network_type}\")\n\n# Get SIM info\nsim_state = droid.getSimState().result\nprint(f\"SIM: {sim_state}\")\n\n# Get phone number\nline1 = droid.getLine1Number().result\nprint(f\"Phone: {line1}\")\n\n# Track phone state\ndroid.startTrackingPhoneState()\nprint(\"Tracking phone state...\")\ndroid.stopTrackingPhoneState()\n
    "},{"location":"qsl4a/connectivity/signalstrength/","title":"Signal Strength API","text":"

    Monitor cellular and wireless signal strength.

    "},{"location":"qsl4a/connectivity/signalstrength/#signal-strength-methods","title":"Signal Strength Methods","text":""},{"location":"qsl4a/connectivity/signalstrength/#starttrackingsignalstrengths","title":"startTrackingSignalStrengths()","text":"

    Start tracking signal strength changes. Generates 'signal_strengths' events.

    startTrackingSignalStrengths()\n
    "},{"location":"qsl4a/connectivity/signalstrength/#stoptrackingsignalstrengths","title":"stopTrackingSignalStrengths()","text":"

    Stop tracking signal strengths.

    stopTrackingSignalStrengths()\n
    "},{"location":"qsl4a/connectivity/signalstrength/#readsignalstrengths","title":"readSignalStrengths()","text":"

    Read the current signal strengths.

    readSignalStrengths()\n

    Returns: Bundle with signal strength data

    "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthlevel","title":"getTelephoneSignalStrengthLevel()","text":"

    Get the telephone signal strength as a level (0-4).

    getTelephoneSignalStrengthLevel()\n

    Returns: Integer level (0=none, 1=poor, 2=fair, 3=good, 4=excellent)

    "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthdetail","title":"getTelephoneSignalStrengthDetail()","text":"

    Get detailed telephone signal strength information.

    getTelephoneSignalStrengthDetail()\n

    Returns: String with detailed signal info

    "},{"location":"qsl4a/connectivity/signalstrength/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start tracking signal strength\ndroid.startTrackingSignalStrengths()\n\n# Wait for signal updates\ntime.sleep(5)\n\n# Read current signal strength\nsignal = droid.readSignalStrengths().result\nprint(f\"Signal: {signal}\")\n\n# Get level directly\nlevel = droid.getTelephoneSignalStrengthLevel().result\nprint(f\"Signal level: {level}/4\")\n\ndroid.stopTrackingSignalStrengths()\n
    "},{"location":"qsl4a/connectivity/sms/","title":"SMS API","text":"

    Send and receive SMS messages.

    "},{"location":"qsl4a/connectivity/sms/#methods","title":"Methods","text":""},{"location":"qsl4a/connectivity/sms/#smssend","title":"smsSend()","text":"

    Send SMS message.

    smsSend(destinationAddress, text)\n

    Parameters: - destinationAddress (str): Phone number - text (str): Message text

    "},{"location":"qsl4a/connectivity/sms/#smsgetmessagecount","title":"smsGetMessageCount()","text":"

    Get message count.

    smsGetMessageCount(unreadOnly=False, folder=\"inbox\")\n
    "},{"location":"qsl4a/connectivity/sms/#smsgetmessageids","title":"smsGetMessageIds()","text":"

    Get message IDs.

    smsGetMessageIds(unreadOnly=False, folder=\"inbox\")\n
    "},{"location":"qsl4a/connectivity/sms/#smsgetmessages","title":"smsGetMessages()","text":"

    Get message details.

    smsGetMessages(unreadOnly=False, folder=\"inbox\", attributes=None)\n
    "},{"location":"qsl4a/connectivity/sms/#smsgetmessagebyid","title":"smsGetMessageById()","text":"

    Get a specific message by ID.

    smsGetMessageById(id, attributes=None)\n

    Parameters: - id (int): Message ID - attributes (list, optional): Specific attributes to retrieve

    Returns: Message data dict

    "},{"location":"qsl4a/connectivity/sms/#smsgetattributes","title":"smsGetAttributes()","text":"

    Get available SMS message attributes.

    smsGetAttributes()\n

    Returns: List of available attribute names

    "},{"location":"qsl4a/connectivity/sms/#smsdeletemessage","title":"smsDeleteMessage()","text":"

    Delete message.

    smsDeleteMessage(id)\n
    "},{"location":"qsl4a/connectivity/sms/#smsmarkmessageread","title":"smsMarkMessageRead()","text":"

    Mark message as read.

    smsMarkMessageRead(ids, read=True)\n
    "},{"location":"qsl4a/connectivity/sms/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Send SMS\ndroid.smsSend(\"+1234567890\", \"Hello from QPython!\")\n\n# Get unread messages\nmessages = droid.smsGetMessages(unreadOnly=True).result\nfor msg in messages:\n    print(f\"From: {msg['address']}, Text: {msg['body']}\")\n
    "},{"location":"qsl4a/connectivity/wifi/","title":"WiFi API","text":"

    Control WiFi adapter and get connection information.

    "},{"location":"qsl4a/connectivity/wifi/#adapter-control","title":"Adapter Control","text":""},{"location":"qsl4a/connectivity/wifi/#checkwifistate","title":"checkWifiState()","text":"

    Check if WiFi is enabled.

    checkWifiState()\n

    Returns: True if WiFi is enabled, False otherwise

    "},{"location":"qsl4a/connectivity/wifi/#togglewifistate","title":"toggleWifiState()","text":"

    Turn WiFi on or off.

    toggleWifiState(enabled=None)\n

    Parameters: - enabled (bool): True to enable, False to disable, None to toggle

    Returns: True if operation succeeded

    "},{"location":"qsl4a/connectivity/wifi/#wifistartscan","title":"wifiStartScan()","text":"

    Start scanning for available WiFi networks.

    wifiStartScan()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifigetscanresults","title":"wifiGetScanResults()","text":"

    Get list of discovered WiFi networks.

    wifiGetScanResults()\n

    Returns: List of access point information

    "},{"location":"qsl4a/connectivity/wifi/#connection-management","title":"Connection Management","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetconnectioninfo","title":"wifiGetConnectionInfo()","text":"

    Get detailed connection information.

    wifiGetConnectionInfo()\n

    Returns: Dict with connection details including SSID, BSSID, IP address

    "},{"location":"qsl4a/connectivity/wifi/#getconnectedinfo","title":"getConnectedInfo()","text":"

    Get connected WiFi network info (simplified).

    getConnectedInfo()\n

    Returns: Dict with SSID, BSSID, signal strength

    "},{"location":"qsl4a/connectivity/wifi/#getdhcpinfo","title":"getDhcpInfo()","text":"

    Get DHCP information for current connection.

    getDhcpInfo(ipConvertToString=True)\n

    Parameters: - ipConvertToString (bool): Convert IP addresses to string format (default: True)

    Returns: Dict with DHCP info including IP, gateway, DNS

    "},{"location":"qsl4a/connectivity/wifi/#wifidisconnect","title":"wifiDisconnect()","text":"

    Disconnect from current WiFi network.

    wifiDisconnect()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifireconnect","title":"wifiReconnect()","text":"

    Reconnect to the current network.

    wifiReconnect()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifireassociate","title":"wifiReassociate()","text":"

    Reassociate with the current access point.

    wifiReassociate()\n
    "},{"location":"qsl4a/connectivity/wifi/#hotspot","title":"Hotspot","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetapstate","title":"wifiGetApState()","text":"

    Get WiFi AP (hotspot) state.

    wifiGetApState()\n

    Returns: Hotspot state

    "},{"location":"qsl4a/connectivity/wifi/#wifi-locks","title":"WiFi Locks","text":""},{"location":"qsl4a/connectivity/wifi/#wifilockacquirefull","title":"wifiLockAcquireFull()","text":"

    Acquire a full WiFi lock (keeps WiFi active even when screen is off).

    wifiLockAcquireFull()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifilockacquirescanonly","title":"wifiLockAcquireScanOnly()","text":"

    Acquire a scan-only WiFi lock.

    wifiLockAcquireScanOnly()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifilockrelease","title":"wifiLockRelease()","text":"

    Release the WiFi lock.

    wifiLockRelease()\n
    "},{"location":"qsl4a/connectivity/wifi/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Check WiFi state\nif droid.checkWifiState().result:\n    print(\"WiFi is enabled\")\nelse:\n    print(\"Enabling WiFi...\")\n    droid.toggleWifiState(True)\n    time.sleep(2)\n\n# Start scanning\ndroid.wifiStartScan()\ntime.sleep(3)\n\n# Get scan results\nnetworks = droid.wifiGetScanResults().result\nfor network in networks:\n    print(f\"SSID: {network.get('SSID')}, Signal: {network.get('level')} dBm\")\n\n# Get connection info\ninfo = droid.wifiGetConnectionInfo().result\nif info:\n    print(f\"Connected to: {info.get('ssid')}\")\n    print(f\"BSSID: {info.get('bssid')}\")\n    print(f\"IP: {info.get('ip_address')}\")\n\n# Get DHCP info\ndhcp = droid.getDhcpInfo().result\nif dhcp:\n    print(f\"Gateway: {dhcp.get('gateway')}\")\n    print(f\"DNS: {dhcp.get('dns1')}\")\n\n# Get simplified connected info\nconnected = droid.getConnectedInfo().result\nprint(f\"SSID: {connected.get('ssid')}, Signal: {connected.get('level')} dBm\")\n\n# Disconnect and reconnect\ndroid.wifiDisconnect()\ntime.sleep(1)\ndroid.wifiReconnect()\n\n# Reassociate with access point\ndroid.wifiReassociate()\n\n# Check hotspot state\nap_state = droid.wifiGetApState().result\nprint(f\"Hotspot state: {ap_state}\")\n\n# Acquire WiFi lock for background operation\ndroid.wifiLockAcquireFull()\n# ... do work ...\ndroid.wifiLockRelease()\n\n# Or use scan-only lock for lighter background operation\ndroid.wifiLockAcquireScanOnly()\n# ... do scanning work ...\ndroid.wifiLockRelease()\n
    "},{"location":"qsl4a/core/android-base/","title":"Android Base Class","text":"

    The Android class is the core of QSL4A, providing the connection to the Android runtime and RPC mechanism.

    "},{"location":"qsl4a/core/android-base/#module-import","title":"Module Import","text":"
    # Full featured (recommended)\nimport androidhelper\ndroid = androidhelper.Android()\n\n# Minimal version (quick, single instance)\nimport android\ndroid = android.droid\n
    "},{"location":"qsl4a/core/android-base/#class-android","title":"Class: Android","text":""},{"location":"qsl4a/core/android-base/#constructor","title":"Constructor","text":"
    Android(addr=None)\n

    Parameters: - addr (tuple, optional): (HOST, PORT) address. If None, uses environment variables AP_HOST and AP_PORT

    Environment Variables: - AP_HOST - Server host address - AP_PORT - Server port - AP_HANDSHAKE - Authentication token

    "},{"location":"qsl4a/core/android-base/#core-methods","title":"Core Methods","text":""},{"location":"qsl4a/core/android-base/#_rpc","title":"_rpc()","text":"

    Internal RPC method for calling Android functions.

    _rpc(method, *args)\n

    Parameters: - method (str): Method name to call - *args: Variable arguments for the method

    Returns: Result namedtuple with fields: - id (int): Request ID - result: Method return value - error (str or None): Error message if failed

    "},{"location":"qsl4a/core/android-base/#getattr","title":"getattr()","text":"

    Dynamic method dispatcher. All Android methods are accessed via attribute lookup.

    # These are equivalent:\ndroid.makeToast(\"Hello\")\ndroid._rpc(\"makeToast\", \"Hello\")\n
    "},{"location":"qsl4a/core/android-base/#standalone-functions-androidpy","title":"Standalone Functions (android.py)","text":"

    When using the minimal android module:

    "},{"location":"qsl4a/core/android-base/#jsla","title":"jsla()","text":"

    Send JSON-RPC request and return raw response.

    jsla(method, *params)\n

    Returns: JSON string response

    "},{"location":"qsl4a/core/android-base/#rsla","title":"rsla()","text":"

    Send request and return result only.

    rsla(method, *params)\n

    Returns: Result value from RPC call

    "},{"location":"qsl4a/core/android-base/#esla","title":"esla()","text":"

    Send request, raise exception on error.

    esla(method, *params)\n

    Raises: Exception if error field is not None

    "},{"location":"qsl4a/core/android-base/#nsla","title":"nsla()","text":"

    Send request and return Result namedtuple.

    nsla(method, *params)\n

    Returns: Result namedtuple

    "},{"location":"qsl4a/core/android-base/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/android-base/#basic-connection","title":"Basic Connection","text":"
    import androidhelper\n\n# Connect to Android runtime\ndroid = androidhelper.Android()\n\n# Check connection by showing toast\ndroid.makeToast(\"Connected!\")\n
    "},{"location":"qsl4a/core/android-base/#error-handling","title":"Error Handling","text":"
    result = droid.someMethod()\nif result.error:\n    print(f\"Error: {result.error}\")\nelse:\n    print(f\"Success: {result.result}\")\n
    "},{"location":"qsl4a/core/android-base/#direct-rpc-call","title":"Direct RPC Call","text":"
    # Call any method directly\nresult = droid._rpc(\"makeToast\", \"Hello World\")\n
    "},{"location":"qsl4a/core/events/","title":"Event System","text":"

    QSL4A provides an event system for handling asynchronous events from Android, such as sensor updates, location changes, and custom broadcasts.

    "},{"location":"qsl4a/core/events/#event-basics","title":"Event Basics","text":"

    Events are stored in a buffer and can be polled or waited for. Each event has: - name: Event type/name - data: Event payload data - time: Timestamp

    "},{"location":"qsl4a/core/events/#event-methods","title":"Event Methods","text":""},{"location":"qsl4a/core/events/#eventclearbuffer","title":"eventClearBuffer()","text":"

    Clear all pending events from the buffer.

    eventClearBuffer()\n

    Returns: None

    "},{"location":"qsl4a/core/events/#eventpoll","title":"eventPoll()","text":"

    Poll for events in the buffer.

    eventPoll(number_of_events=1)\n

    Parameters: - number_of_events (int): Maximum events to retrieve (default: 1)

    Returns: List of event objects

    "},{"location":"qsl4a/core/events/#eventwait","title":"eventWait()","text":"

    Wait for any event.

    eventWait(timeout=None)\n

    Parameters: - timeout (int, optional): Timeout in seconds. None = wait forever

    Returns: Event object or None if timeout

    "},{"location":"qsl4a/core/events/#eventwaitfor","title":"eventWaitFor()","text":"

    Wait for a specific event.

    eventWaitFor(eventName, timeout=None)\n

    Parameters: - eventName (str): Name of event to wait for - timeout (int, optional): Timeout in seconds

    Returns: Event object or None if timeout

    "},{"location":"qsl4a/core/events/#eventpost","title":"eventPost()","text":"

    Post a custom event.

    eventPost(name, data, enqueue=None)\n

    Parameters: - name (str): Event name - data: Event data (any type) - enqueue (bool, optional): Add to queue if True

    "},{"location":"qsl4a/core/events/#receiveevent","title":"receiveEvent()","text":"

    Receive event (blocking).

    receiveEvent()\n

    Returns: Event object

    "},{"location":"qsl4a/core/events/#broadcast-events","title":"Broadcast Events","text":"

    Register for system broadcast events.

    "},{"location":"qsl4a/core/events/#eventregisterforbroadcast","title":"eventRegisterForBroadcast()","text":"

    Register to receive broadcast events.

    eventRegisterForBroadcast(category, enqueue=True)\n

    Parameters: - category (str): Broadcast category/action - enqueue (bool): Add to event queue

    "},{"location":"qsl4a/core/events/#eventunregisterforbroadcast","title":"eventUnregisterForBroadcast()","text":"

    Unregister from broadcast events.

    eventUnregisterForBroadcast(category)\n
    "},{"location":"qsl4a/core/events/#eventgetbrodcastcategories","title":"eventGetBrodcastCategories()","text":"

    Get registered broadcast categories.

    eventGetBrodcastCategories()\n

    Returns: List of registered categories

    "},{"location":"qsl4a/core/events/#event-dispatcher","title":"Event Dispatcher)","text":""},{"location":"qsl4a/core/events/#starteventdispatcher","title":"startEventDispatcher()","text":"

    Opens up a socket where you can read for events posted.)

    startEventDispatcher(port=0)\n

    Parameters: - port (int, optional): Port to listen on (default: 0 = auto-select)

    Returns: Port number being listened on

    "},{"location":"qsl4a/core/events/#stopeventdispatcher","title":"stopEventDispatcher()","text":"

    Stops the event server.)

    stopEventDispatcher()\n
    "},{"location":"qsl4a/core/events/#deprecated-methods","title":"Deprecated Methods","text":""},{"location":"qsl4a/core/events/#rpcpostevent","title":"rpcPostEvent()","text":"

    Post an event to the event queue. (Deprecated, use eventPost)

    rpcPostEvent(name, data)\n

    Parameters: - name (str): Event name - data: Event data

    "},{"location":"qsl4a/core/events/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/events/#basic-event-polling","title":"Basic Event Polling","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Clear old events\ndroid.eventClearBuffer()\n\n# Poll for events\nevents = droid.eventPoll(5).result\nfor event in events:\n    print(f\"Event: {event['name']}, Data: {event['data']}\")\n
    "},{"location":"qsl4a/core/events/#waiting-for-events","title":"Waiting for Events","text":"
    # Wait for any event with timeout\nevent = droid.eventWait(timeout=10).result\nif event:\n    print(f\"Got event: {event['name']}\")\n
    "},{"location":"qsl4a/core/events/#waiting-for-specific-event","title":"Waiting for Specific Event","text":"
    # Wait for sensor event\nevent = droid.eventWaitFor('screen', timeout=5).result\nif event:\n    print(f\"Screen event: {event['data']}\")\n
    "},{"location":"qsl4a/core/events/#posting-custom-events","title":"Posting Custom Events","text":"
    # Post custom event\ndroid.eventPost('my_event', {'key': 'value'})\n\n# Wait for it\nevent = droid.eventWaitFor('my_event', timeout=1).result\n
    "},{"location":"qsl4a/core/events/#broadcast-receiver","title":"Broadcast Receiver","text":"
    # Register for screen on/off events\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_ON')\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_OFF')\n\n# Wait for screen events\nwhile True:\n    event = droid.receiveEvent().result\n    if event['name'] == 'android.intent.action.SCREEN_ON':\n        print(\"Screen turned on\")\n    elif event['name'] == 'android.intent.action.SCREEN_OFF':\n        print(\"Screen turned off\")\n
    "},{"location":"qsl4a/core/events/#sensor-event-handling","title":"Sensor Event Handling","text":"
    # Start sensing\ndroid.startSensingTimed(1, 250)\n\n# Process sensor events\nfor _ in range(100):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'sensors':\n        data = event['data']\n        print(f\"Accel: {data['xforce']}, {data['yforce']}, {data['zforce']}\")\n\ndroid.stopSensing()\n
    "},{"location":"qsl4a/core/events/#common-event-types","title":"Common Event Types","text":"Event Name Description Source sensors Sensor data update startSensing* location GPS location update startLocating phone Phone state change startTrackingPhoneState signal Signal strength change startTrackingSignalStrength screen Screenshot ready fullGetScreenShot dialog Dialog response dialogShow*"},{"location":"qsl4a/core/events/#event-data-structure","title":"Event Data Structure","text":"
    {\n    'name': 'event_name',\n    'data': {\n        # Event-specific data\n    },\n    'time': 1234567890  # Timestamp\n}\n
    "},{"location":"qsl4a/core/intent/","title":"Intent System","text":"

    Android Intents are used to start activities, send broadcasts, and communicate between apps. QSL4A provides full Intent support through the Intent module.

    "},{"location":"qsl4a/core/intent/#module-import","title":"Module Import","text":"
    import androidhelper\ndon = androidhelper.Android()\n
    "},{"location":"qsl4a/core/intent/#intent-constants","title":"Intent Constants","text":"

    Access via droid.Intent:

    "},{"location":"qsl4a/core/intent/#actions","title":"Actions","text":"Constant Value Usage ACTION_MAIN android.intent.action.MAIN App entry point ACTION_VIEW android.intent.action.VIEW View content ACTION_EDIT android.intent.action.EDIT Edit content ACTION_PICK android.intent.action.PICK Pick item ACTION_SEND android.intent.action.SEND Share content ACTION_SEARCH android.intent.action.SEARCH Search"},{"location":"qsl4a/core/intent/#flags","title":"Flags","text":"Constant Value Usage FLAG_ACTIVITY_NEW_TASK 268435456 Start new task FLAG_ACTIVITY_CLEAR_TASK 32768 Clear task stack FLAG_ACTIVITY_NEW_DOCUMENT 524288 New document mode"},{"location":"qsl4a/core/intent/#extras","title":"Extras","text":"Constant Usage EXTRA_TEXT Text content EXTRA_STREAM File URI EXTRA_SUBJECT Subject line EXTRA_EMAIL Email address"},{"location":"qsl4a/core/intent/#core-methods","title":"Core Methods","text":""},{"location":"qsl4a/core/intent/#makeintent","title":"makeIntent()","text":"

    Create an Intent object.

    makeIntent(action, uri=None, type=None, extras=None, categories=None,\n           packagename=None, classname=None, flags=None)\n

    Parameters: - action (str): Intent action (e.g., droid.Intent.ACTION_VIEW) - uri (str, optional): Data URI - type (str, optional): MIME type - extras (dict, optional): Extra data - categories (list, optional): Intent categories - packagename (str, optional): Target package - classname (str, optional): Target class - flags (int, optional): Intent flags

    Returns: Intent object

    "},{"location":"qsl4a/core/intent/#startactivityintent","title":"startActivityIntent()","text":"

    Start an Activity with an Intent.

    startActivityIntent(intent, wait=None)\n

    Parameters: - intent: Intent object from makeIntent() - wait (bool, optional): Block until activity closes

    "},{"location":"qsl4a/core/intent/#startactivityforresultintent","title":"startActivityForResultIntent()","text":"

    Start activity and wait for result.

    startActivityForResultIntent(intent)\n

    Returns: Activity result

    "},{"location":"qsl4a/core/intent/#sendbroadcastintent","title":"sendBroadcastIntent()","text":"

    Send a broadcast.

    sendBroadcastIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#view","title":"view()","text":"

    View content by URI.

    view(uri, type=None, extras=None)\n
    "},{"location":"qsl4a/core/intent/#pick","title":"pick()","text":"

    Pick content from URI.

    pick(uri)\n
    "},{"location":"qsl4a/core/intent/#common-intent-methods","title":"Common Intent Methods)","text":""},{"location":"qsl4a/core/intent/#scanbarcode","title":"scanBarcode()","text":"

    Launch the barcode scanner.

    scanBarcode()\n

    Returns: Scanned barcode string

    "},{"location":"qsl4a/core/intent/#send","title":"send()","text":"

    Send content via share intent.

    send(type, content)\n

    Parameters: - type (str): MIME type - content (str): Content to share

    "},{"location":"qsl4a/core/intent/#sendtext","title":"sendText()","text":"

    Send text content.

    sendText(text)\n

    Parameters: - text (str): Text to send

    "},{"location":"qsl4a/core/intent/#sendemail","title":"sendEmail()","text":"

    Send an email.

    sendEmail(to, subject, body, attachment=None)\n

    Parameters: - to (str or list): Recipient email address(es) - subject (str): Email subject - body (str): Email body - attachment (str, optional): Attachment file path

    "},{"location":"qsl4a/core/intent/#pathtouri","title":"pathToUri()","text":"

    Convert file path to content URI.

    pathToUri(path)\n

    Parameters: - path (str): File path

    Returns: Content URI string

    "},{"location":"qsl4a/core/intent/#openfile","title":"openFile()","text":"

    Open a file with appropriate app.

    openFile(path)\n

    Parameters: - path (str): File path to open

    "},{"location":"qsl4a/core/intent/#sendfile","title":"sendFile()","text":"

    Send a file via share intent.

    sendFile(path)\n

    Parameters: - path (str): File path to send

    "},{"location":"qsl4a/core/intent/#getpathtype","title":"getPathType()","text":"

    Get the MIME type for a file path.

    getPathType(path)\n

    Parameters: - path (str): File path

    Returns: MIME type string

    "},{"location":"qsl4a/core/intent/#viewmap","title":"viewMap()","text":"

    Open map at a location.

    viewMap(latitude, longitude)\n

    Parameters: - latitude (float): Latitude - longitude (float): Longitude

    "},{"location":"qsl4a/core/intent/#viewcontacts","title":"viewContacts()","text":"

    Open the contacts app.

    viewContacts()\n
    "},{"location":"qsl4a/core/intent/#search","title":"search()","text":"

    Perform a web search.

    search(query)\n

    Parameters: - query (str): Search query

    "},{"location":"qsl4a/core/intent/#viewhtml","title":"viewHtml()","text":"

    View HTML content.

    viewHtml(content, encoding=None)\n

    Parameters: - content (str): HTML content - encoding (str, optional): Character encoding

    "},{"location":"qsl4a/core/intent/#webviewshow","title":"webViewShow()","text":"

    Display web content in WebView. Deprecated, use viewHtml.

    webViewShow(url)\n

    Parameters: - url (str): Web page URL

    "},{"location":"qsl4a/core/intent/#editoropen","title":"editorOpen()","text":"

    Open a text editor.

    editorOpen(path=None, create=False)\n

    Parameters: - path (str, optional): File path to edit - create (bool, optional): Create if doesn't exist

    "},{"location":"qsl4a/core/intent/#helper-class-uri","title":"Helper Class: Uri","text":"

    Create URI objects for Intents:

    from androidhelper.Intent import Uri\n\nuri = Uri(\"file:///sdcard/test.txt\")\n
    "},{"location":"qsl4a/core/intent/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/intent/#open-web-page","title":"Open Web Page","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"http://www.example.com\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#share-text","title":"Share Text","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_TEXT: \"Hello from QPython!\",\n        droid.Intent.EXTRA_SUBJECT: \"Test\"\n    },\n    type=\"text/plain\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#open-file","title":"Open File","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"file:///sdcard/document.pdf\",\n    type=\"application/pdf\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#pick-contact","title":"Pick Contact","text":"
    result = droid.pickContact()\ncontact_uri = result.result\n
    "},{"location":"qsl4a/core/intent/#send-email","title":"Send Email","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_EMAIL: [\"test@example.com\"],\n        droid.Intent.EXTRA_SUBJECT: \"Hello\",\n        droid.Intent.EXTRA_TEXT: \"Message body\"\n    },\n    type=\"message/rfc822\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#open-app","title":"Open App","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_MAIN,\n    packagename=\"com.android.settings\",\n    classname=\"com.android.settings.Settings\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/hardware/bluetooth/","title":"Bluetooth API","text":"

    Control Bluetooth adapter and communicate with Bluetooth devices.

    "},{"location":"qsl4a/hardware/bluetooth/#adapter-control","title":"Adapter Control","text":""},{"location":"qsl4a/hardware/bluetooth/#togglebluetoothstate","title":"toggleBluetoothState()","text":"

    Turn Bluetooth on/off.

    toggleBluetoothState(enabled=None, prompt=True)\n

    Parameters: - enabled (bool): True=on, False=off, None=toggle - prompt (bool): Show user prompt

    "},{"location":"qsl4a/hardware/bluetooth/#checkbluetoothstate","title":"checkBluetoothState()","text":"

    Check if Bluetooth is enabled.

    checkBluetoothState()\n

    Returns: True/False

    "},{"location":"qsl4a/hardware/bluetooth/#getlocalname","title":"GetLocalName()","text":"

    Get Bluetooth device name.

    GetLocalName()\n
    "},{"location":"qsl4a/hardware/bluetooth/#setlocalname","title":"SetLocalName()","text":"

    Set Bluetooth device name.

    SetLocalName(name)\n
    "},{"location":"qsl4a/hardware/bluetooth/#getscanmode","title":"GetScanMode()","text":"

    Get discoverability mode.

    GetScanMode()\n

    Returns: - -1: Disabled - 0: Non-discoverable, non-connectable - 1: Connectable, non-discoverable - 3: Connectable and discoverable

    "},{"location":"qsl4a/hardware/bluetooth/#makediscoverable","title":"MakeDiscoverable()","text":"

    Make device discoverable.

    MakeDiscoverable(duration=300)\n

    Parameters: - duration (int): Seconds to be discoverable

    "},{"location":"qsl4a/hardware/bluetooth/#discovery","title":"Discovery","text":""},{"location":"qsl4a/hardware/bluetooth/#discoverystart","title":"DiscoveryStart()","text":"

    Start device discovery.

    DiscoveryStart()\n
    "},{"location":"qsl4a/hardware/bluetooth/#discoverycancel","title":"DiscoveryCancel()","text":"

    Cancel discovery.

    DiscoveryCancel()\n
    "},{"location":"qsl4a/hardware/bluetooth/#getreceiveddevices","title":"GetReceivedDevices()","text":"

    Get discovered devices.

    GetReceivedDevices()\n

    Returns: List of device info dicts

    "},{"location":"qsl4a/hardware/bluetooth/#getbondeddevices","title":"GetBondedDevices()","text":"

    Get paired devices.

    GetBondedDevices()\n

    Returns: List of paired device info

    "},{"location":"qsl4a/hardware/bluetooth/#connection","title":"Connection","text":""},{"location":"qsl4a/hardware/bluetooth/#connect","title":"Connect()","text":"

    Connect to a device.

    Connect(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", address=None)\n

    Parameters: - uuid (str): Service UUID - address (str): Device address (None = show picker)

    Returns: True if successful

    "},{"location":"qsl4a/hardware/bluetooth/#accept","title":"Accept()","text":"

    Accept incoming connection.

    Accept(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", timeout=0)\n
    "},{"location":"qsl4a/hardware/bluetooth/#activeconnections","title":"ActiveConnections()","text":"

    Check active connections.

    ActiveConnections()\n
    "},{"location":"qsl4a/hardware/bluetooth/#stop","title":"Stop()","text":"

    Disconnect.

    Stop(connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#communication","title":"Communication","text":""},{"location":"qsl4a/hardware/bluetooth/#write","title":"Write()","text":"

    Send ASCII data.

    Write(ascii, connID=\"\")\n
    "},{"location":"qsl4a/hardware/bluetooth/#writebinary","title":"WriteBinary()","text":"

    Send binary data (base64 encoded).

    WriteBinary(base64, connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#read","title":"Read()","text":"

    Read ASCII data.

    Read(bufferSize=4096, connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#readbinary","title":"ReadBinary()","text":"

    Read binary data.

    ReadBinary(bufferSize=4096, connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#readline","title":"ReadLine()","text":"

    Read line.

    ReadLine(connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#readready","title":"ReadReady()","text":"

    Check if data available.

    ReadReady(connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Enable Bluetooth\ndroid.toggleBluetoothState(True)\n\n# Get paired devices\ndevices = droid.GetBondedDevices().result\nfor dev in devices:\n    print(f\"{dev['name']}: {dev['address']}\")\n\n# Connect to device\ndroid.Connect(address=\"00:11:22:33:44:55\")\n\n# Send data\ndroid.Write(\"Hello Bluetooth!\")\n\n# Read response\ndata = droid.Read(1024).result\n
    "},{"location":"qsl4a/hardware/camera/","title":"Camera API","text":"

    Capture photos and record video.

    "},{"location":"qsl4a/hardware/camera/#photo-capture","title":"Photo Capture","text":""},{"location":"qsl4a/hardware/camera/#takepicture","title":"takePicture()","text":"

    Take a photo using the default camera.

    takePicture(path=None)\n

    Parameters: - path (str, optional): Save path. If None, returns image data

    Returns: Image path or image data

    "},{"location":"qsl4a/hardware/camera/#cameracapturepicture","title":"cameraCapturePicture()","text":"

    Capture picture with advanced camera controls.

    cameraCapturePicture(targetPath=None, cameraId=0, useAutoFocus=True)\n

    Parameters: - targetPath (str, optional): Save path - cameraId (int): Camera to use (0 = back, 1 = front) - useAutoFocus (bool): Enable auto focus

    Returns: Captured image path

    "},{"location":"qsl4a/hardware/camera/#camerasettorchmode","title":"cameraSetTorchMode()","text":"

    Control camera flashlight/torch.

    cameraSetTorchMode(enabled)\n

    Parameters: - enabled (bool): True to turn on, False to turn off

    Returns: True if successful

    "},{"location":"qsl4a/hardware/camera/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

    Capture screenshot.

    imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

    Parameters: - path (str, optional): Save path - delayMilliSec (int): Delay before capture

    "},{"location":"qsl4a/hardware/camera/#video-recording","title":"Video Recording","text":""},{"location":"qsl4a/hardware/camera/#takevideo","title":"takeVideo()","text":"

    Record video using default settings.

    takeVideo(path=None, quality=1)\n

    Parameters: - path (str, optional): Save path - quality (int): Video quality (0-4) - 0: 160x120 - 1: 320x240 - 2: 352x288 - 3: 640x480 - 4: 800x480

    "},{"location":"qsl4a/hardware/camera/#recordercapturevideo","title":"recorderCaptureVideo()","text":"

    Capture video with advanced controls.

    recorderCaptureVideo(targetPath=None, duration=10, cameraId=0, quality=8)\n

    Parameters: - targetPath (str, optional): Save path - duration (int): Recording duration in seconds (default: 10) - cameraId (int): Camera to use (0 = back, 1 = front) - quality (int): Video quality (0-8, higher is better)

    Returns: Video file path

    "},{"location":"qsl4a/hardware/camera/#recordaudio","title":"recordAudio()","text":"

    Record audio.

    recordAudio()\n

    Returns: Audio file path

    "},{"location":"qsl4a/hardware/camera/#screen-recording","title":"Screen Recording","text":""},{"location":"qsl4a/hardware/camera/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

    Start screen recording.

    recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

    Parameters: - path (str): Save path - audio (int): Audio source (0=none, 1=mic, 2=internal) - targetPixels (int): Resolution - frameRate (int): FPS - bitRate (int): Bitrate - rotation (bool): Rotate output - autoStart (bool): Start immediately

    "},{"location":"qsl4a/hardware/camera/#recorderstart","title":"recorderStart()","text":"

    Start recording.

    recorderStart()\n
    "},{"location":"qsl4a/hardware/camera/#recorderpause","title":"recorderPause()","text":"

    Pause recording.

    recorderPause()\n
    "},{"location":"qsl4a/hardware/camera/#recorderresume","title":"recorderResume()","text":"

    Resume recording.

    recorderResume()\n
    "},{"location":"qsl4a/hardware/camera/#audio-volume-detection","title":"Audio Volume Detection","text":""},{"location":"qsl4a/hardware/camera/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

    Start volume detection.

    recorderSoundVolumeDetect(interval=100)\n
    "},{"location":"qsl4a/hardware/camera/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

    Get current volume in dB.

    recorderSoundVolumeGetDb()\n
    "},{"location":"qsl4a/hardware/camera/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Take photo with default camera\nphoto_path = droid.takePicture(\"/sdcard/photo.jpg\").result\nprint(f\"Photo saved: {photo_path}\")\n\n# Take photo with front camera and auto focus\ncamera_path = droid.cameraCapturePicture(\"/sdcard/selfie.jpg\", cameraId=1, useAutoFocus=True).result\nprint(f\"Front camera photo: {camera_path}\")\n\n# Control flashlight\ndroid.cameraSetTorchMode(True)  # Turn on flashlight\n\n# Record video with default settings\nvideo_path = droid.takeVideo(\"/sdcard/video.mp4\", quality=3).result\nprint(f\"Video saved: {video_path}\")\n\n# Record video with advanced controls\nvideo_path = droid.recorderCaptureVideo(\"/sdcard/movie.mp4\", duration=30, cameraId=0, quality=8).result\n\n# Screenshot\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n
    "},{"location":"qsl4a/hardware/recorder/","title":"Audio Recorder API","text":"

    Record audio from microphone and device screen.

    "},{"location":"qsl4a/hardware/recorder/#audio-recording","title":"Audio Recording","text":""},{"location":"qsl4a/hardware/recorder/#recordaudio","title":"recordAudio()","text":"

    Record audio from microphone.

    recordAudio()\n

    Returns: Path to recorded audio file

    "},{"location":"qsl4a/hardware/recorder/#recorderstartmicrophone","title":"recorderStartMicrophone()","text":"

    Start recording from microphone to a specific file.

    recorderStartMicrophone(targetPath=None)\n

    Parameters: - targetPath (str, optional): Path to save the recording

    "},{"location":"qsl4a/hardware/recorder/#screen-recording","title":"Screen Recording","text":""},{"location":"qsl4a/hardware/recorder/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

    Start screen recording with audio.

    recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

    Parameters: - path (str): Save path for video file - audio (int): Audio source (0=none, 1=mic, 2=internal audio) - targetPixels (int): Target resolution in pixels - frameRate (int): Frames per second (default: 30) - bitRate (int): Video bitrate - rotation (bool): Rotate output video - autoStart (bool): Start recording immediately

    Returns: Result of operation

    "},{"location":"qsl4a/hardware/recorder/#recorderstart","title":"recorderStart()","text":"

    Start the screen recording (when autoStart=False).

    recorderStart()\n
    "},{"location":"qsl4a/hardware/recorder/#recorderpause","title":"recorderPause()","text":"

    Pause ongoing screen recording.

    recorderPause()\n
    "},{"location":"qsl4a/hardware/recorder/#recorderresume","title":"recorderResume()","text":"

    Resume paused screen recording.

    recorderResume()\n
    "},{"location":"qsl4a/hardware/recorder/#audio-volume-detection","title":"Audio Volume Detection","text":""},{"location":"qsl4a/hardware/recorder/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

    Start monitoring sound volume level.

    recorderSoundVolumeDetect(interval=100)\n

    Parameters: - interval (int): Detection interval in milliseconds (default: 100)

    "},{"location":"qsl4a/hardware/recorder/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

    Get current sound volume in decibels.

    recorderSoundVolumeGetDb()\n

    Returns: Current volume level in dB

    "},{"location":"qsl4a/hardware/recorder/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Record audio from microphone\nprint(\"Recording audio...\")\naudio_path = droid.recordAudio().result\nprint(f\"Saved to: {audio_path}\")\n\n# Record microphone to specific file\ndroid.recorderStartMicrophone(\"/sdcard/my_recording.mp3\")\ntime.sleep(5)\ndroid.recorderStop()\n\n# Record screen with audio\nprint(\"Starting screen recording...\")\ndroid.recorderStartScreenRecord(\n    path=\"/sdcard/screen_record.mp4\",\n    audio=1,\n    frameRate=30,\n    autoStart=True\n)\ntime.sleep(10)\ndroid.recorderStop()\n\n# Monitor sound volume\ndroid.recorderSoundVolumeDetect(interval=100)\ntime.sleep(3)\nvolume = droid.recorderSoundVolumeGetDb().result\nprint(f\"Current volume: {volume} dB\")\n
    "},{"location":"qsl4a/hardware/usbserial/","title":"USB Host Serial API","text":"

    Communicate with USB serial devices (requires USB OTG support and Android 3.1+).

    "},{"location":"qsl4a/hardware/usbserial/#usb-serial-methods","title":"USB Serial Methods)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialopen","title":"usbHostSerialOpen()","text":"

    Open a connection to a USB serial device.

    usbHostSerialOpen(device, baudRate=9600)\n

    Parameters: - device (str): USB device path or identifier - baudRate (int): Baud rate (default: 9600)

    Returns: True if opened successfully

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialclose","title":"usbHostSerialClose()","text":"

    Close the USB serial connection.

    usbHostSerialClose()\n
    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialread","title":"usbHostSerialRead()","text":"

    Read data from USB serial.

    usbHostSerialRead(bufferSize=1024)\n

    Parameters: - bufferSize (int): Maximum bytes to read (default: 1024)

    Returns: String read data

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwrite","title":"usbHostSerialWrite()","text":"

    Write data to USB serial.

    usbHostSerialWrite(data)\n

    Parameters: - data (str): String data to write

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialavailable","title":"usbHostSerialAvailable()","text":"

    Check if data is available to read.

    usbHostSerialAvailable()\n

    Returns: Number of bytes available

    "},{"location":"qsl4a/hardware/usbserial/#configuration-methods","title":"Configuration Methods)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetbaudrate","title":"usbHostSerialSetBaudRate()","text":"

    Set the baud rate.

    usbHostSerialSetBaudRate(baudRate)\n

    Parameters: - baudRate (int): Baud rate

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetdatabits","title":"usbHostSerialSetDataBits()","text":"

    Set data bits (5, 6, 7, or 8).

    usbHostSerialSetDataBits(dataBits)\n

    Parameters: - dataBits (int): Data bits (5-8)

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetstopbits","title":"usbHostSerialSetStopBits()","text":"

    Set stop bits (1, 1.5, or 2).

    usbHostSerialSetStopBits(stopBits)\n

    Parameters: - stopBits (float): Stop bits (1, 1.5, or 2)

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetparity","title":"usbHostSerialSetParity()","text":"

    Set parity (none, odd, even, mark, space).

    usbHostSerialSetParity(parity)\n

    Parameters: - parity (str): Parity mode ('none', 'odd', 'even', 'mark', 'space')

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetflowcontrol","title":"usbHostSerialSetFlowControl()","text":"

    Set flow control (none, hardware, software).

    usbHostSerialSetFlowControl(flowControl)\n

    Parameters: - flowControl (str): Flow control mode ('none', 'hardware', 'software')

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialreadhex","title":"usbHostSerialReadHex()","text":"

    Read data as hex string.

    usbHostSerialReadHex(bufferSize=1024)\n

    Parameters: - bufferSize (int): Maximum bytes to read

    Returns: Hex string

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwritehex","title":"usbHostSerialWriteHex()","text":"

    Write data from hex string.

    usbHostSerialWriteHex(hexString)\n

    Parameters: - hexString (str): Hex string to write

    "},{"location":"qsl4a/hardware/usbserial/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Open USB serial connection\nif droid.usbHostSerialOpen(\"/dev/bus/usb/001/001\", 115200).result:\n    print(\"USB serial opened\")\n\n    # Write data\n    droid.usbHostSerialWrite(\"AT\\r\")\n\n    # Read response\n    response = droid.usbHostSerialRead(1024).result\n    print(f\"Response: {response}\")\n\n    # Or use hex\n    droid.usbHostSerialWriteHex(\"41540D0A\")  # \"AT\\r\\n\"\n\n    # Close connection\n    droid.usbHostSerialClose()\n

    Note: USB serial requires: - Android 3.1+ (API 12) - USB OTG cable/adapter - USB host mode support on device - Compatible serial device

    "},{"location":"qsl4a/hardware/webcam/","title":"Webcam API","text":"

    Stream video from the device camera using MJPEG.

    "},{"location":"qsl4a/hardware/webcam/#mjpeg-stream-methods","title":"MJPEG Stream Methods","text":""},{"location":"qsl4a/hardware/webcam/#webcamstart","title":"webcamStart()","text":"

    Start an MJPEG stream from the webcam.

    webcamStart(resolutionLevel=0, jpegQuality=20, port=0)\n

    Parameters: - resolutionLevel (int): Resolution level (default: 0) - jpegQuality (int): JPEG quality 1-100 (default: 20) - port (int): Port number (default: 0 = auto)

    Returns: Tuple of (address, port) for the stream

    "},{"location":"qsl4a/hardware/webcam/#webcamadjustquality","title":"webcamAdjustQuality()","text":"

    Adjust the quality of an active webcam stream.

    webcamAdjustQuality(resolutionLevel=0, jpegQuality=20)\n

    Parameters: - resolutionLevel (int): Resolution level - jpegQuality (int): JPEG quality 1-100

    "},{"location":"qsl4a/hardware/webcam/#webcamstop","title":"webcamStop()","text":"

    Stop the webcam stream.

    webcamStop()\n
    "},{"location":"qsl4a/hardware/webcam/#camera-preview-methods","title":"Camera Preview Methods","text":""},{"location":"qsl4a/hardware/webcam/#camerastartpreview","title":"cameraStartPreview()","text":"

    Start camera preview mode with event generation.

    cameraStartPreview(resolutionLevel=0, jpegQuality=20, filepath=None)\n

    Parameters: - resolutionLevel (int): Resolution level (default: 0) - jpegQuality (int): JPEG quality (default: 20) - filepath (str, optional): File path to save preview frames

    Returns: True if successful

    Note: Generates 'preview' events with frame data.

    "},{"location":"qsl4a/hardware/webcam/#camerastoppreview","title":"cameraStopPreview()","text":"

    Stop the camera preview.

    cameraStopPreview()\n
    "},{"location":"qsl4a/hardware/webcam/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start webcam stream\nstream_info = droid.webcamStart(\n    resolutionLevel=0,\n    jpegQuality=30,\n    port=8080\n).result\nprint(f\"Stream available at {stream_info[0]}:{stream_info[1]}\")\n\n# Adjust quality while streaming\ntime.sleep(5)\ndroid.webcamAdjustQuality(resolutionLevel=1, jpegQuality=50)\n\n# Stop when done\ndroid.webcamStop()\n\n# Or use preview mode\nprint(\"Starting preview...\")\ndroid.cameraStartPreview()\n\n# Wait for preview events\nfor i in range(10):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'preview':\n        print(f\"Got preview frame: {event['data']}\")\n\ndroid.cameraStopPreview()\n
    "},{"location":"qsl4a/media/image/","title":"Image Processing API","text":"

    Compress and process images.

    "},{"location":"qsl4a/media/image/#image-compression","title":"Image Compression","text":""},{"location":"qsl4a/media/image/#imagecompress","title":"imageCompress()","text":"

    Compress image file.

    imageCompress(srcPath, destPath, targetByteSize=0, targetWidth=0, targetHeight=0)\n

    Parameters: - srcPath (str): Source image path - destPath (str): Output path - targetByteSize (int): Target file size in bytes (0 = no limit) - targetWidth (int): Target width (0 = original) - targetHeight (int): Target height (0 = original)

    Returns: Compressed image path

    "},{"location":"qsl4a/media/image/#screenshot","title":"Screenshot","text":""},{"location":"qsl4a/media/image/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

    Capture screen.

    imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

    Parameters: - path (str): Save path - delayMilliSec (int): Delay before capture

    Returns: Screenshot path

    "},{"location":"qsl4a/media/image/#video-playback","title":"Video Playback","text":""},{"location":"qsl4a/media/image/#videoplay","title":"videoPlay()","text":"

    Play video file in fullscreen mode.

    videoPlay(path, wait=True)\n

    Parameters: - path (str): Video file path - wait (bool): Wait for playback to complete (default: True)

    "},{"location":"qsl4a/media/image/#barcode-scanning","title":"Barcode Scanning","text":""},{"location":"qsl4a/media/image/#scanbarcodefromimage","title":"scanBarcodeFromImage()","text":"

    Scan barcode/QR code from image file.

    scanBarcodeFromImage(path, compressRatio=0, x=0, y=0, width=0, height=0)\n

    Parameters: - path (str): Image file path - compressRatio (int): Compression ratio (0 = no compression) - x, y, width, height (int): Region to scan (0 = full image)

    Returns: Scanned barcode content

    "},{"location":"qsl4a/media/image/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Take screenshot\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n\n# Compress image\ncompressed = droid.imageCompress(\n    \"/sdcard/large_photo.jpg\",\n    \"/sdcard/compressed.jpg\",\n    targetByteSize=102400,  # Target ~100KB\n    targetWidth=1920,\n    targetHeight=1080\n).result\nprint(f\"Saved: {compressed}\")\n\n# Play video\nvideo_path = \"/sdcard/movie.mp4\"\ndroid.videoPlay(video_path, wait=True)\n\n# Scan barcode from image\nresult = droid.scanBarcodeFromImage(\"/sdcard/qr_code.png\").result\nprint(f\"Barcode: {result}\")\n
    "},{"location":"qsl4a/media/mediaplayer/","title":"Media Player API","text":"

    Control audio and video playback.

    "},{"location":"qsl4a/media/mediaplayer/#playback-control","title":"Playback Control","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplay","title":"mediaPlay()","text":"

    Play media file.

    mediaPlay(url, tag=\"default\", play=True)\n

    Parameters: - url (str): Media file path or URL - tag (str): Player identifier - play (bool): Auto-start playback

    "},{"location":"qsl4a/media/mediaplayer/#mediaplaystart","title":"mediaPlayStart()","text":"

    Start playback.

    mediaPlayStart(tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#mediaplaypause","title":"mediaPlayPause()","text":"

    Pause playback.

    mediaPlayPause(tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#mediaplayclose","title":"mediaPlayClose()","text":"

    Close player.

    mediaPlayClose(tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#mediaplayseek","title":"mediaPlaySeek()","text":"

    Seek to position.

    mediaPlaySeek(msec, tag=\"default\")\n

    Parameters: - msec (int): Position in milliseconds

    "},{"location":"qsl4a/media/mediaplayer/#mediaplaysetlooping","title":"mediaPlaySetLooping()","text":"

    Set loop mode.

    mediaPlaySetLooping(enabled, tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#player-info","title":"Player Info","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplayinfo","title":"mediaPlayInfo()","text":"

    Get playback info.

    mediaPlayInfo(tag=\"default\")\n

    Returns: Dict with duration, position, etc.

    "},{"location":"qsl4a/media/mediaplayer/#mediaisplaying","title":"mediaIsPlaying()","text":"

    Check if playing.

    mediaIsPlaying(tag=\"default\")\n

    Returns: True/False

    "},{"location":"qsl4a/media/mediaplayer/#mediaplaylist","title":"mediaPlayList()","text":"

    List active players.

    mediaPlayList()\n
    "},{"location":"qsl4a/media/mediaplayer/#volume-control","title":"Volume Control","text":""},{"location":"qsl4a/media/mediaplayer/#getmediavolume","title":"getMediaVolume()","text":"

    Get media volume.

    getMediaVolume()\n

    Returns: Volume level (0-15)

    "},{"location":"qsl4a/media/mediaplayer/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

    Get max media volume.

    getMaxMediaVolume()\n
    "},{"location":"qsl4a/media/mediaplayer/#getringervolume","title":"getRingerVolume()","text":"

    Get ringer volume.

    getRingerVolume()\n
    "},{"location":"qsl4a/media/mediaplayer/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

    Get max ringer volume.

    getMaxRingerVolume()\n
    "},{"location":"qsl4a/media/mediaplayer/#video-playback","title":"Video Playback","text":""},{"location":"qsl4a/media/mediaplayer/#videoplay","title":"videoPlay()","text":"

    Play video fullscreen.

    videoPlay(path, wait=True)\n

    Parameters: - path (str): Video file path - wait (bool): Wait for playback to complete

    "},{"location":"qsl4a/media/mediaplayer/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Play audio\ndroid.mediaPlay(\"/sdcard/music.mp3\", tag=\"music\")\n\n# Check status\nif droid.mediaIsPlaying(\"music\").result:\n    info = droid.mediaPlayInfo(\"music\").result\n    print(f\"Playing: {info}\")\n\n# Seek to 30 seconds\ndroid.mediaPlaySeek(30000, \"music\")\n\n# Close\ndroid.mediaPlayClose(\"music\")\n\n# Play video\ndroid.videoPlay(\"/sdcard/movie.mp4\", wait=True)\n
    "},{"location":"qsl4a/special/cipher/","title":"Cipher API","text":"

    Encryption and decryption utilities for secure data storage.

    "},{"location":"qsl4a/special/cipher/#initialization","title":"Initialization","text":""},{"location":"qsl4a/special/cipher/#cipherinit","title":"cipherInit()","text":"

    Initialize the cipher with encryption key and algorithm.

    cipherInit(key, algorithm=\"AES/CBC/PKCS5Padding\", encodingFormat=\"\", initialVector=\"\")\n

    Parameters: - key (str or bytes): Encryption key - algorithm (str): Cipher algorithm (default: \"AES/CBC/PKCS5Padding\") - encodingFormat (str): Encoding format - initialVector (str or bytes): Initial vector for encryption

    Returns: Initialization result

    Note: Must be called before any encrypt/decrypt operations.

    "},{"location":"qsl4a/special/cipher/#encryption-methods","title":"Encryption Methods","text":""},{"location":"qsl4a/special/cipher/#encryptstring","title":"encryptString()","text":"

    Encrypt a string.

    encryptString(plainText)\n

    Parameters: - plainText (str): Text to encrypt

    Returns: Encrypted string

    "},{"location":"qsl4a/special/cipher/#encryptbytes","title":"encryptBytes()","text":"

    Encrypt bytes data.

    encryptBytes(data)\n

    Parameters: - data (bytes): Data to encrypt

    Returns: Encrypted bytes

    "},{"location":"qsl4a/special/cipher/#encryptstringtofile","title":"encryptStringToFile()","text":"

    Encrypt string to file.

    encryptStringToFile(plainText, filePath)\n

    Parameters: - plainText (str): Text to encrypt - filePath (str): Output file path

    "},{"location":"qsl4a/special/cipher/#encryptbytestofile","title":"encryptBytesToFile()","text":"

    Encrypt bytes to file.

    encryptBytesToFile(data, filePath)\n
    "},{"location":"qsl4a/special/cipher/#decryption-methods","title":"Decryption Methods","text":""},{"location":"qsl4a/special/cipher/#decryptstring","title":"decryptString()","text":"

    Decrypt to string.

    decryptString(cipherText)\n

    Parameters: - cipherText (str): Encrypted text

    Returns: Decrypted string

    "},{"location":"qsl4a/special/cipher/#decryptbytes","title":"decryptBytes()","text":"

    Decrypt to bytes.

    decryptBytes(data)\n

    Returns: Decrypted bytes

    "},{"location":"qsl4a/special/cipher/#decryptfiletostring","title":"decryptFileToString()","text":"

    Decrypt file to string.

    decryptFileToString(filePath)\n
    "},{"location":"qsl4a/special/cipher/#decryptfiletobytes","title":"decryptFileToBytes()","text":"

    Decrypt file to bytes.

    decryptFileToBytes(filePath)\n
    "},{"location":"qsl4a/special/cipher/#decryptfile","title":"decryptFile()","text":"

    Decrypt file to file.

    decryptFile(srcPath, destPath)\n
    "},{"location":"qsl4a/special/cipher/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Initialize cipher with your encryption key\ndroid.cipherInit(\"my_secret_key_1234\")\n\n# Encrypt string\nencrypted = droid.encryptString(\"Secret message!\").result\nprint(f\"Encrypted: {encrypted}\")\n\n# Decrypt string\ndecrypted = droid.decryptString(encrypted).result\nprint(f\"Decrypted: {decrypted}\")\n\n# Encrypt to file\ndroid.encryptStringToFile(\"My secret data\", \"/sdcard/secret.dat\")\n\n# Decrypt from file\ndata = droid.decryptFileToString(\"/sdcard/secret.dat\").result\nprint(data)\n\n# Initialize with custom algorithm and IV\ndroid.cipherInit(\n    key=\"my_key\",\n    algorithm=\"AES/CBC/PKCS5Padding\",\n    initialVector=\"0123456789abcdef\"\n)\n
    "},{"location":"qsl4a/special/pgptai/","title":"PGPT AI API","text":"

    Speech-to-text and AI services integration.

    "},{"location":"qsl4a/special/pgptai/#prerequisites","title":"Prerequisites","text":"
    pip install pgptAI\n
    "},{"location":"qsl4a/special/pgptai/#speech-recognition","title":"Speech Recognition","text":""},{"location":"qsl4a/special/pgptai/#speechtotext","title":"speechToText()","text":"

    Convert speech to text.

    speechToText(RecordSecond=10, AmrFile=None, Language=None)\n

    Parameters: - RecordSecond (int): Recording duration in seconds - AmrFile (str, optional): Existing audio file path - Language (str, optional): Language code ('en', 'zh')

    Returns: Transcribed text

    "},{"location":"qsl4a/special/pgptai/#text-to-speech","title":"Text to Speech","text":""},{"location":"qsl4a/special/pgptai/#texttospeech","title":"textToSpeech()","text":"

    Convert text to speech and optionally play it.

    textToSpeech(Text, AutoPlay=True, WavFile=None, VoiceName=None)\n

    Parameters: - Text (str): Text to convert to speech - AutoPlay (bool): Automatically play the generated audio (default: True) - WavFile (str, optional): Path to save the WAV file. If None, uses temporary file - VoiceName (str, optional): Voice name to use (e.g., 'en-US-JennyNeural', 'zh-CN-XiaoxiaoNeural')

    Returns: Dict with speech synthesis result including: - text: The input text - url: URL to download the audio file - WavFile: Path to the saved WAV file (if saved locally)

    "},{"location":"qsl4a/special/pgptai/#configuration","title":"Configuration","text":"

    The API uses configuration from /storage/emulated/0/Android/data/org.qpython.qpy/files/apigpt.conf:

    [speech]\nspeech_key = your_api_key\n

    Default voice settings: - English: en-US-JennyNeural - Chinese: zh-CN-XiaoxiaoNeural

    "},{"location":"qsl4a/special/pgptai/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Record and transcribe\nprint(\"Recording for 5 seconds...\")\ntext = droid.speechToText(RecordSecond=5, Language='en').result\nprint(f\"You said: {text}\")\n\n# Transcribe existing file\ntext = droid.speechToText(AmrFile=\"/sdcard/recording.amr\").result\nprint(f\"Transcription: {text}\")\n\n# Text to speech\ndroid.textToSpeech(\"Hello, this is a test message.\", AutoPlay=True, Language='en')\n\n# Text to speech with custom voice and save to file\nresult = droid.textToSpeech(\n    \"Welcome to QPython!\",\n    AutoPlay=False,\n    WavFile=\"/sdcard/welcome.wav\",\n    VoiceName=\"en-US-JennyNeural\"\n).result\nprint(f\"Audio saved to: {result.get('WavFile')}\")\n
    "},{"location":"qsl4a/special/pgptai/#class-usage","title":"Class Usage","text":"
    from androidhelper.pgptai import pgptai\nimport androidhelper\n\ndroid = androidhelper.Android()\nai = pgptai(droid)\n\n# Use speech recognition\ntext = ai.speechToText(RecordSecond=10)\n
    "},{"location":"qsl4a/storage/clipboard/","title":"Clipboard API","text":"

    Copy and paste text to system clipboard.

    "},{"location":"qsl4a/storage/clipboard/#methods","title":"Methods","text":""},{"location":"qsl4a/storage/clipboard/#setclipboard","title":"setClipboard()","text":"

    Copy text to clipboard.

    setClipboard(text)\n

    Parameters: - text (str): Text to copy

    Returns: True if success

    "},{"location":"qsl4a/storage/clipboard/#getclipboard","title":"getClipboard()","text":"

    Get text from clipboard.

    getClipboard()\n

    Returns: Clipboard text

    "},{"location":"qsl4a/storage/clipboard/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Copy to clipboard\ndroid.setClipboard(\"Hello from QPython!\")\n\n# Paste from clipboard\ntext = droid.getClipboard().result\nprint(f\"Clipboard: {text}\")\n
    "},{"location":"qsl4a/storage/documentfile/","title":"DocumentFile API","text":"

    File operations with SAF (Storage Access Framework) support for Android 4.4+.

    "},{"location":"qsl4a/storage/documentfile/#directory-operations","title":"Directory Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfilemkdir","title":"documentFileMkdir()","text":"

    Create directory.

    documentFileMkdir(Dir)\n

    Parameters: - Dir (str): Directory path

    Returns: True if success

    "},{"location":"qsl4a/storage/documentfile/#documentfilelistfiles","title":"documentFileListFiles()","text":"

    List files in directory.

    documentFileListFiles(Folder)\n

    Returns: List of files

    "},{"location":"qsl4a/storage/documentfile/#file-operations","title":"File Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfileexists","title":"documentFileExists()","text":"

    Check if file or directory exists.

    documentFileExists(path)\n

    Parameters: - path (str): File or directory path

    Returns: True if exists, False otherwise

    "},{"location":"qsl4a/storage/documentfile/#documentfileisfile","title":"documentFileIsFile()","text":"

    Check if path is a file.

    documentFileIsFile(path)\n

    Parameters: - path (str): Path to check

    Returns: True if file, False if not a file, None if not exists

    "},{"location":"qsl4a/storage/documentfile/#documentfileisdirectory","title":"documentFileIsDirectory()","text":"

    Check if path is a directory.

    documentFileIsDirectory(path)\n

    Parameters: - path (str): Path to check

    Returns: True if directory, False if not a directory, None if not exists

    "},{"location":"qsl4a/storage/documentfile/#documentfiledelete","title":"documentFileDelete()","text":"

    Delete file or directory.

    documentFileDelete(FileOrTree)\n

    Returns: True if success

    "},{"location":"qsl4a/storage/documentfile/#documentfilerenameto","title":"documentFileRenameTo()","text":"

    Rename or move file.

    documentFileRenameTo(Src, Dest)\n

    Returns: True if success

    "},{"location":"qsl4a/storage/documentfile/#documentfilecopy","title":"documentFileCopy()","text":"

    Copy file.

    documentFileCopy(SrcFileOrTree, DestFileOrTree)\n
    "},{"location":"qsl4a/storage/documentfile/#stream-operations","title":"Stream Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfileinputstream","title":"documentFileInputStream()","text":"

    Read file content.

    documentFileInputStream(srcFile, EncodingFormat=\"\", skip=None, length=None)\n

    Parameters: - srcFile (str): Source file - EncodingFormat (str): \"UTF-8\", \"GBK\", \"Base64\", or \"\" for bytes - skip (int): Skip bytes from start - length (int): Read length

    Returns: File content

    "},{"location":"qsl4a/storage/documentfile/#documentfileoutputstream","title":"documentFileOutputStream()","text":"

    Write file content.

    documentFileOutputStream(destFile, src, EncodingFormat=\"\", append=None)\n

    Parameters: - destFile (str): Destination file - src: Data to write - EncodingFormat (str): Encoding format - append (bool): Append mode

    "},{"location":"qsl4a/storage/documentfile/#file-information","title":"File Information","text":""},{"location":"qsl4a/storage/documentfile/#documentfilelength","title":"documentFileLength()","text":"

    Get file size in bytes.

    documentFileLength(path)\n

    Parameters: - path (str): File path

    Returns: File size in bytes (0 if not exists)

    "},{"location":"qsl4a/storage/documentfile/#documentfilelastmodified","title":"documentFileLastModified()","text":"

    Get last modified time.

    documentFileLastModified(path)\n

    Parameters: - path (str): File path

    Returns: Timestamp (0 if not exists)

    "},{"location":"qsl4a/storage/documentfile/#documentfilegetstat","title":"documentFileGetStat()","text":"

    Get comprehensive file statistics.

    documentFileGetStat(path)\n

    Parameters: - path (str): File path

    Returns: Dict with length, last modified, and read/write permissions, or None if not exists

    "},{"location":"qsl4a/storage/documentfile/#uri-operations","title":"URI Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfilegeturi","title":"documentFileGetUri()","text":"

    Get URI from path.

    documentFileGetUri(path, isDirectory=None)\n
    "},{"location":"qsl4a/storage/documentfile/#documentfileshowopen","title":"documentFileShowOpen()","text":"

    Show file picker.

    documentFileShowOpen()\n

    Returns: Selected file URI

    "},{"location":"qsl4a/storage/documentfile/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Create directory\ndroid.documentFileMkdir(\"/sdcard/MyFolder\")\n\n# List files\nfiles = droid.documentFileListFiles(\"/sdcard\").result\nfor f in files:\n    print(f)\n\n# Read file\ncontent = droid.documentFileInputStream(\n    \"/sdcard/test.txt\",\n    EncodingFormat=\"UTF-8\"\n).result\nprint(content)\n\n# Write file\ndroid.documentFileOutputStream(\n    \"/sdcard/output.txt\",\n    \"Hello World\",\n    EncodingFormat=\"UTF-8\"\n)\n
    "},{"location":"qsl4a/storage/preferences/","title":"Preferences API","text":"

    Store and retrieve data using Android SharedPreferences.

    "},{"location":"qsl4a/storage/preferences/#preference-methods","title":"Preference Methods","text":""},{"location":"qsl4a/storage/preferences/#prefgetvalue","title":"prefGetValue()","text":"

    Read a value from shared preferences.

    prefGetValue(key, filename=None)\n

    Parameters: - key (str): Preference key - filename (str, optional): Preference file name

    Returns: The stored value (any type)

    "},{"location":"qsl4a/storage/preferences/#prefputvalue","title":"prefPutValue()","text":"

    Write a value to shared preferences.

    prefPutValue(key, value, filename=None)\n

    Parameters: - key (str): Preference key - value (object): Value to store - filename (str, optional): Preference file name

    "},{"location":"qsl4a/storage/preferences/#prefgetall","title":"prefGetAll()","text":"

    Get all preference values.

    prefGetAll(filename=None)\n

    Parameters: - filename (str, optional): Preference file name

    Returns: Map of all preferences

    "},{"location":"qsl4a/storage/preferences/#prefremovevalue","title":"prefRemoveValue()","text":"

    Remove a value from shared preferences.

    prefRemoveValue(key, filename=None)\n

    Parameters: - key (str): Preference key to remove - filename (str, optional): Preference file name

    "},{"location":"qsl4a/storage/preferences/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Store values\ndroid.prefPutValue(\"username\", \"alice\")\ndroid.prefPutValue(\"score\", 100)\ndroid.prefPutValue(\"enabled\", True)\n\n# Read a specific value\nusername = droid.prefGetValue(\"username\").result\nprint(f\"Username: {username}\")\n\n# Get all preferences\nall_prefs = droid.prefGetAll().result\nprint(f\"All prefs: {all_prefs}\")\n\n# Remove a value\ndroid.prefRemoveValue(\"score\")\n\n# Use custom filename\ndroid.prefPutValue(\"token\", \"abc123\", filename=\"auth.prefs\")\ntoken = droid.prefGetValue(\"token\", filename=\"auth.prefs\").result\n
    "},{"location":"qsl4a/system/activityresult/","title":"Activity Result API","text":"

    Set activity results for scripts launched via startActivityForResult.

    "},{"location":"qsl4a/system/activityresult/#result-methods","title":"Result Methods","text":""},{"location":"qsl4a/system/activityresult/#setresultboolean","title":"setResultBoolean()","text":"

    Set a boolean result.

    setResultBoolean(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (bool): Boolean result value

    "},{"location":"qsl4a/system/activityresult/#setresultbyte","title":"setResultByte()","text":"

    Set a byte result.

    setResultByte(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (int): Byte result value

    "},{"location":"qsl4a/system/activityresult/#setresultshort","title":"setResultShort()","text":"

    Set a short result.

    setResultShort(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (int): Short result value

    "},{"location":"qsl4a/system/activityresult/#setresultchar","title":"setResultChar()","text":"

    Set a character result.

    setResultChar(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (str): Character result value

    "},{"location":"qsl4a/system/activityresult/#setresultinteger","title":"setResultInteger()","text":"

    Set an integer result.

    setResultInteger(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (int): Integer result value

    "},{"location":"qsl4a/system/activityresult/#setresultlong","title":"setResultLong()","text":"

    Set a long result.

    setResultLong(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (int): Long result value

    "},{"location":"qsl4a/system/activityresult/#setresultfloat","title":"setResultFloat()","text":"

    Set a float result.

    setResultFloat(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (float): Float result value

    "},{"location":"qsl4a/system/activityresult/#setresultdouble","title":"setResultDouble()","text":"

    Set a double result.

    setResultDouble(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (float): Double result value

    "},{"location":"qsl4a/system/activityresult/#setresultstring","title":"setResultString()","text":"

    Set a string result.

    setResultString(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (str): String result value

    "},{"location":"qsl4a/system/activityresult/#setresultbooleanarray","title":"setResultBooleanArray()","text":"

    Set a boolean array result.

    setResultBooleanArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Boolean array

    "},{"location":"qsl4a/system/activityresult/#setresultbytearray","title":"setResultByteArray()","text":"

    Set a byte array result.

    setResultByteArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Byte array

    "},{"location":"qsl4a/system/activityresult/#setresultshortarray","title":"setResultShortArray()","text":"

    Set a short array result.

    setResultShortArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Short array

    "},{"location":"qsl4a/system/activityresult/#setresultchararray","title":"setResultCharArray()","text":"

    Set a character array result.

    setResultCharArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Char array

    "},{"location":"qsl4a/system/activityresult/#setresultintegerarray","title":"setResultIntegerArray()","text":"

    Set an integer array result.

    setResultIntegerArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Integer array

    "},{"location":"qsl4a/system/activityresult/#setresultlongarray","title":"setResultLongArray()","text":"

    Set a long array result.

    setResultLongArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Long array

    "},{"location":"qsl4a/system/activityresult/#setresultfloatarray","title":"setResultFloatArray()","text":"

    Set a float array result.

    setResultFloatArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Float array

    "},{"location":"qsl4a/system/activityresult/#setresultdoublearray","title":"setResultDoubleArray()","text":"

    Set a double array result.

    setResultDoubleArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Double array

    "},{"location":"qsl4a/system/activityresult/#setresultstringarray","title":"setResultStringArray()","text":"

    Set a string array result.

    setResultStringArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): String array

    "},{"location":"qsl4a/system/activityresult/#setresultserializable","title":"setResultSerializable()","text":"

    Set a serializable result.

    setResultSerializable(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue: Serializable result value

    "},{"location":"qsl4a/system/activityresult/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# After performing an activity, set the result\n# Example: Return success with data\ndroid.setResultInteger(0, 200)  # RESULT_OK\ndroid.setResultString(0, \"Operation completed successfully\")\n\n# Return an array result\ndroid.setResultIntegerArray(0, [1, 2, 3, 4, 5])\n
    "},{"location":"qsl4a/system/application/","title":"Application Management","text":"

    Manage applications, launch apps, and query system information.

    "},{"location":"qsl4a/system/application/#application-information","title":"Application Information","text":""},{"location":"qsl4a/system/application/#getapplicationinfo","title":"getApplicationInfo()","text":"

    Get information about an app.

    getApplicationInfo(packageName=None)\n

    Parameters: - packageName (str): Package name (None = current app)

    Returns: App info dict

    "},{"location":"qsl4a/system/application/#getinstalledpackages","title":"getInstalledPackages()","text":"

    Get list of installed packages.

    getInstalledPackages(flag=4)\n

    Parameters: - flag (int): Package flag filter (default: 4)

    Returns: List of installed packages

    "},{"location":"qsl4a/system/application/#getrunningpackages","title":"getRunningPackages()","text":"

    List running packages.

    getRunningPackages()\n

    Returns: List of package names

    "},{"location":"qsl4a/system/application/#getlaunchablepackages","title":"getLaunchablePackages()","text":"

    Get list of launchable packages.

    getLaunchablePackages(needClassName=False)\n

    Parameters: - needClassName (bool): Include main activity class name (default: False)

    Returns: List of launchable package names or dict with class names

    "},{"location":"qsl4a/system/application/#application-control","title":"Application Control","text":""},{"location":"qsl4a/system/application/#launch","title":"launch()","text":"

    Launch an application.

    launch(classname=None, packagename=None, wait=True)\n

    Parameters: - classname (str): Main activity class name - packagename (str): Package name - wait (bool): Wait for launch to complete (default: True)

    Returns: Launch result

    "},{"location":"qsl4a/system/application/#forcestoppackage","title":"forceStopPackage()","text":"

    Force stop an application.

    forceStopPackage(packageName)\n

    Parameters: - packageName (str): Package name to stop

    "},{"location":"qsl4a/system/application/#version-information","title":"Version Information","text":""},{"location":"qsl4a/system/application/#getpackageversion","title":"getPackageVersion()","text":"

    Get app version name.

    getPackageVersion(packageName)\n

    Returns: Version string (e.g., \"3.2.1\")

    "},{"location":"qsl4a/system/application/#getpackageversioncode","title":"getPackageVersionCode()","text":"

    Get app version code.

    getPackageVersionCode(packageName)\n

    Returns: Version code integer

    "},{"location":"qsl4a/system/application/#getconstants","title":"getConstants()","text":"

    Get class constants.

    getConstants(classname)\n

    Parameters: - classname (str): Full class name

    Returns: Dict of constant names and values

    "},{"location":"qsl4a/system/application/#system-features","title":"System Features","text":""},{"location":"qsl4a/system/application/#backgroundprotect","title":"backgroundProtect()","text":"

    Enable or disable background protection for the app.

    backgroundProtect(enabled=True)\n

    Parameters: - enabled (bool): True to enable protection, False to disable

    "},{"location":"qsl4a/system/application/#createscriptshortcut","title":"createScriptShortCut()","text":"

    Create a home screen shortcut for a script.

    createScriptShortCut(scriptPath, label=None, iconPath=None, scriptArg=None)\n

    Parameters: - scriptPath (str): Path to the Python script - label (str, optional): Shortcut label - iconPath (str, optional): Path to icon image - scriptArg (str, optional): Argument to pass to script

    "},{"location":"qsl4a/system/application/#device-information","title":"Device Information","text":""},{"location":"qsl4a/system/application/#getandroidid","title":"getAndroidID()","text":"

    Get Android device ID.

    getAndroidID()\n

    Returns: Unique Android device ID string

    "},{"location":"qsl4a/system/application/#getsysinfo","title":"getSysInfo()","text":"

    Get system information.

    getSysInfo()\n

    Returns: Dict with system details

    "},{"location":"qsl4a/system/application/#getlocale","title":"getLocale()","text":"

    Get device locale.

    getLocale()\n

    Returns: Locale string (e.g., \"en_US\")

    "},{"location":"qsl4a/system/application/#getharmonyosinformation","title":"getHarmonyOsInformation()","text":"

    Get HarmonyOS information if running on HarmonyOS.

    getHarmonyOsInformation()\n

    Returns: HarmonyOS version info or None

    "},{"location":"qsl4a/system/application/#isexternalstoragemanager","title":"isExternalStorageManager()","text":"

    Check if app has external storage manager permission.

    isExternalStorageManager()\n

    Returns: True if has permission

    "},{"location":"qsl4a/system/application/#memory-and-display","title":"Memory and Display","text":""},{"location":"qsl4a/system/application/#getmemoryinfo","title":"getMemoryInfo()","text":"

    Get memory information.

    getMemoryInfo()\n

    Returns: Dict with memory stats

    "},{"location":"qsl4a/system/application/#getscreeninfo","title":"getScreenInfo()","text":"

    Get screen information.

    getScreenInfo()\n

    Returns: Dict with width, height, density

    "},{"location":"qsl4a/system/application/#permissions","title":"Permissions","text":""},{"location":"qsl4a/system/application/#checkpermissions","title":"checkPermissions()","text":"

    Check current app permissions.

    checkPermissions()\n

    Returns: Dict of permissions and their status

    "},{"location":"qsl4a/system/application/#requestpermissions","title":"requestPermissions()","text":"

    Request permissions from the user.

    requestPermissions(permissions=None)\n

    Parameters: - permissions (list, optional): List of permissions to request. If None, requests all needed permissions.

    Returns: Result of permission request

    "},{"location":"qsl4a/system/application/#system-actions","title":"System Actions","text":""},{"location":"qsl4a/system/application/#showscreenlock","title":"showScreenLock()","text":"

    Show screen lock (PIN/pattern/password entry).

    showScreenLock()\n
    "},{"location":"qsl4a/system/application/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get system info\ninfo = droid.getSysInfo().result\nprint(f\"System: {info}\")\n\n# Get app version\nversion = droid.getPackageVersion(\"org.qpython.qpy\").result\nprint(f\"QPython version: {version}\")\n\n# List installed apps\napps = droid.getInstalledPackages().result\nprint(f\"Installed apps: {len(apps)}\")\n\n# Launch an app\ndroid.launch(packagename=\"com.android.settings\")\n\n# Check permissions\nperms = droid.checkPermissions().result\nprint(f\"Permissions: {perms}\")\n\n# Request storage permission\ndroid.requestPermissions([\"android.permission.READ_EXTERNAL_STORAGE\"])\n\n# Create shortcut\ndroid.createScriptShortCut(\n    \"/sdcard/my_script.py\",\n    label=\"My Script\",\n    iconPath=\"/sdcard/icon.png\"\n)\n
    "},{"location":"qsl4a/system/battery/","title":"Battery API","text":"

    Monitor device battery status and health.

    "},{"location":"qsl4a/system/battery/#methods","title":"Methods","text":""},{"location":"qsl4a/system/battery/#readbatterydata","title":"readBatteryData()","text":"

    Get complete battery information.

    readBatteryData()\n

    Returns: Dict with battery data

    "},{"location":"qsl4a/system/battery/#batterystartmonitoring","title":"batteryStartMonitoring()","text":"

    Start battery monitoring.

    batteryStartMonitoring()\n
    "},{"location":"qsl4a/system/battery/#batterystopmonitoring","title":"batteryStopMonitoring()","text":"

    Stop battery monitoring.

    batteryStopMonitoring()\n
    "},{"location":"qsl4a/system/battery/#batterygetlevel","title":"batteryGetLevel()","text":"

    Get battery percentage.

    batteryGetLevel()\n

    Returns: Int (0-100)

    "},{"location":"qsl4a/system/battery/#batterygetstatus","title":"batteryGetStatus()","text":"

    Get charging status.

    batteryGetStatus()\n

    Returns: - 1: Unknown - 2: Charging - 3: Discharging - 4: Not charging - 5: Full

    "},{"location":"qsl4a/system/battery/#batterygetplugtype","title":"batteryGetPlugType()","text":"

    Get power source.

    batteryGetPlugType()\n

    Returns: - -1: Unknown - 0: Unplugged - 1: AC charger - 2: USB port

    "},{"location":"qsl4a/system/battery/#batterygethealth","title":"batteryGetHealth()","text":"

    Get battery health.

    batteryGetHealth()\n

    Returns: - 1: Unknown - 2: Good - 3: Overheat - 4: Dead - 5: Over voltage - 6: Unspecified failure

    "},{"location":"qsl4a/system/battery/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get battery level\nlevel = droid.batteryGetLevel().result\nprint(f\"Battery: {level}%\")\n
    "},{"location":"qsl4a/system/qpyinterface/","title":"QPython Interface API","text":"

    Execute QPython scripts and manage shared variables from other apps.

    "},{"location":"qsl4a/system/qpyinterface/#script-execution-methods","title":"Script Execution Methods","text":""},{"location":"qsl4a/system/qpyinterface/#executeqpy","title":"executeQPy()","text":"

    Execute a QPython script.

    executeQPy(path=\"\", arg=None)\n

    Parameters: - path (str): Path to the script file - arg (str, optional): Command line arguments

    Returns: True if started successfully

    "},{"location":"qsl4a/system/qpyinterface/#executeqpyassrv","title":"executeQPyAsSrv()","text":"

    Execute a QPython script as a service.

    executeQPyAsSrv(path=None)\n

    Parameters: - path (str, optional): Path to the script file

    Returns: True if started successfully

    "},{"location":"qsl4a/system/qpyinterface/#executeqpycode","title":"executeQPyCode()","text":"

    Execute Python code directly.

    executeQPyCode(code=None)\n

    Parameters: - code (str, optional): Python code to execute

    Returns: True if started successfully

    "},{"location":"qsl4a/system/qpyinterface/#executeqpycodeassrv","title":"executeQPyCodeAsSrv()","text":"

    Execute Python code as a service.

    executeQPyCodeAsSrv(code=None)\n

    Parameters: - code (str, optional): Python code to execute

    Returns: True if started successfully

    "},{"location":"qsl4a/system/qpyinterface/#shared-variables","title":"Shared Variables","text":"

    Shared variables allow communication between QPython and other apps.

    "},{"location":"qsl4a/system/qpyinterface/#sharedvariableset","title":"sharedVariableSet()","text":"

    Set a Java shared variable.

    sharedVariableSet(key, value)\n

    Parameters: - key (str): Variable name - value (str): Variable value

    Returns: The stored value

    "},{"location":"qsl4a/system/qpyinterface/#sharedvariableget","title":"sharedVariableGet()","text":"

    Get a Java shared variable.

    sharedVariableGet(key)\n

    Parameters: - key (str): Variable name

    Returns: The stored value

    "},{"location":"qsl4a/system/qpyinterface/#sharedvariableremove","title":"sharedVariableRemove()","text":"

    Remove a Java shared variable.

    sharedVariableRemove(key)\n

    Parameters: - key (str): Variable name to remove

    Returns: The removed value

    "},{"location":"qsl4a/system/qpyinterface/#getlastlog","title":"getLastLog()","text":"

    Get the last log output from QPython.

    getLastLog()\n

    Returns: String log content

    "},{"location":"qsl4a/system/qpyinterface/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Execute a script\ndroid.executeQPy(\"/sdcard/my_script.py\", arg=\"test\")\n\n# Execute code directly\ncode = \"print('Hello from QPython!')\"\ndroid.executeQPyCode(code)\n\n# Use shared variables\ndroid.sharedVariableSet(\"username\", \"alice\")\nusername = droid.sharedVariableGet(\"username\").result\nprint(f\"Username: {username}\")\n\n# Remove variable\ndroid.sharedVariableRemove(\"username\")\n\n# Get recent log\nlog = droid.getLastLog().result\nprint(f\"Log: {log}\")\n
    "},{"location":"qsl4a/system/sensors/","title":"Sensor API","text":"

    Access device sensors including accelerometer, gyroscope, magnetometer, and more.

    "},{"location":"qsl4a/system/sensors/#methods","title":"Methods","text":""},{"location":"qsl4a/system/sensors/#startsensingtimed","title":"startSensingTimed()","text":"

    Start sensor monitoring with time intervals.

    startSensingTimed(sensorNumber, delayTime)\n

    Parameters: - sensorNumber (int): Sensor ID (1-3 typically) - delayTime (int): Delay between readings in milliseconds

    "},{"location":"qsl4a/system/sensors/#startsensingthreshold","title":"startSensingThreshold()","text":"

    Start sensor monitoring with threshold trigger.

    startSensingThreshold(sensorNumber, threshold, axis)\n

    Parameters: - sensorNumber (int): Sensor ID - threshold (float): Trigger threshold - axis (int): Axis to monitor (0=X, 1=Y, 2=Z)

    "},{"location":"qsl4a/system/sensors/#stopsensing","title":"stopSensing()","text":"

    Stop all sensor monitoring.

    stopSensing()\n
    "},{"location":"qsl4a/system/sensors/#readsensors","title":"readSensors()","text":"

    Read current sensor data.

    readSensors()\n

    Returns: Sensor data dict

    "},{"location":"qsl4a/system/sensors/#sensorsreadaccelerometer","title":"sensorsReadAccelerometer()","text":"

    Read accelerometer values.

    sensorsReadAccelerometer()\n

    Returns: List [X, Y, Z] in m/s\u00b2

    "},{"location":"qsl4a/system/sensors/#sensorsreadgyroscope","title":"sensorsReadGyroscope()","text":"

    Read gyroscope values.

    sensorsReadGyroscope()\n

    Returns: List [X, Y, Z] in rad/s

    "},{"location":"qsl4a/system/sensors/#sensorsreadmagnetometer","title":"sensorsReadMagnetometer()","text":"

    Read magnetic field values.

    sensorsReadMagnetometer()\n

    Returns: List [X, Y, Z] in \u03bcT

    "},{"location":"qsl4a/system/sensors/#sensorsreadorientation","title":"sensorsReadOrientation()","text":"

    Read device orientation.

    sensorsReadOrientation()\n

    Returns: List [azimuth, pitch, roll] in degrees

    "},{"location":"qsl4a/system/sensors/#sensorsgetlight","title":"sensorsGetLight()","text":"

    Read light sensor value.

    sensorsGetLight()\n

    Returns: Light level in lux

    "},{"location":"qsl4a/system/sensors/#sensorsgetstepcounter","title":"sensorsGetStepCounter()","text":"

    Read step counter.

    sensorsGetStepCounter()\n

    Returns: Number of steps

    "},{"location":"qsl4a/system/sensors/#sensorsgetaccuracy","title":"sensorsGetAccuracy()","text":"

    Get the current sensor accuracy.

    sensorsGetAccuracy()\n

    Returns: Accuracy value (0-3: UNRELIABLE, ACCURACY_LOW, ACCURACY_MEDIUM, ACCURACY_HIGH)

    "},{"location":"qsl4a/system/sensors/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start sensing\ndroid.startSensingTimed(1, 250)\n\n# Read sensors 10 times\nfor i in range(10):\n    accel = droid.sensorsReadAccelerometer().result\n    print(f\"Accel: X={accel[0]:.2f}, Y={accel[1]:.2f}, Z={accel[2]:.2f}\")\n    time.sleep(0.5)\n\ndroid.stopSensing()\n
    "},{"location":"qsl4a/system/settings/","title":"Settings API","text":"

    Control system settings including screen, sound, and network settings.

    "},{"location":"qsl4a/system/settings/#screen-settings","title":"Screen Settings","text":""},{"location":"qsl4a/system/settings/#setscreentimeout","title":"setScreenTimeout()","text":"

    Set the screen timeout value.

    setScreenTimeout(value)\n

    Parameters: - value (int): Screen timeout in seconds

    Returns: Previous timeout value

    "},{"location":"qsl4a/system/settings/#getscreentimeout","title":"getScreenTimeout()","text":"

    Get the current screen timeout.

    getScreenTimeout()\n

    Returns: Current screen timeout in seconds

    "},{"location":"qsl4a/system/settings/#getscreenbrightness","title":"getScreenBrightness()","text":"

    Get the screen brightness value.

    getScreenBrightness()\n

    Returns: Brightness value (0-255)

    "},{"location":"qsl4a/system/settings/#setscreenbrightness","title":"setScreenBrightness()","text":"

    Set the screen brightness.

    setScreenBrightness(value=None)\n

    Parameters: - value (int, optional): Brightness value (0-255), or None for auto

    Returns: Previous brightness value

    "},{"location":"qsl4a/system/settings/#checkscreenon","title":"checkScreenOn()","text":"

    Check if the screen is on.

    checkScreenOn()\n

    Returns: True if screen is on, False otherwise

    "},{"location":"qsl4a/system/settings/#airplane-mode","title":"Airplane Mode","text":""},{"location":"qsl4a/system/settings/#checkairplanemode","title":"checkAirplaneMode()","text":"

    Check if airplane mode is enabled.

    checkAirplaneMode()\n

    Returns: True if airplane mode is on

    "},{"location":"qsl4a/system/settings/#ringer-settings","title":"Ringer Settings","text":""},{"location":"qsl4a/system/settings/#checkringersilentmode","title":"checkRingerSilentMode()","text":"

    Check if ringer is in silent mode.

    checkRingerSilentMode()\n

    Returns: True if silent mode is on

    "},{"location":"qsl4a/system/settings/#toggleringersilentmode","title":"toggleRingerSilentMode()","text":"

    Toggle ringer silent mode.

    toggleRingerSilentMode(enabled=None)\n

    Parameters: - enabled (bool, optional): True to enable, False to disable, None to toggle

    Returns: New state

    "},{"location":"qsl4a/system/settings/#togglevibratemode","title":"toggleVibrateMode()","text":"

    Toggle vibrate mode.

    toggleVibrateMode(enabled=None, ringer=None)\n

    Parameters: - enabled (bool, optional): Toggle vibrate on/off - ringer (bool, optional): Apply to ringer mode

    Returns: New state

    "},{"location":"qsl4a/system/settings/#getvibratemode","title":"getVibrateMode()","text":"

    Get the vibrate mode setting.

    getVibrateMode(ringer=None)\n

    Parameters: - ringer (bool, optional): Check ringer vibrate mode

    Returns: True if vibrate is enabled

    "},{"location":"qsl4a/system/settings/#volume-settings","title":"Volume Settings","text":""},{"location":"qsl4a/system/settings/#getringervolume","title":"getRingerVolume()","text":"

    Get the current ringer volume.

    getRingerVolume()\n

    Returns: Ringer volume level (0-7 typically)

    "},{"location":"qsl4a/system/settings/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

    Get the maximum ringer volume.

    getMaxRingerVolume()\n

    Returns: Maximum ringer volume

    "},{"location":"qsl4a/system/settings/#setringervolume","title":"setRingerVolume()","text":"

    Set the ringer volume.

    setRingerVolume(volume)\n

    Parameters: - volume (int): Volume level

    "},{"location":"qsl4a/system/settings/#getmediavolume","title":"getMediaVolume()","text":"

    Get the current media volume.

    getMediaVolume()\n

    Returns: Media volume level (0-15 typically)

    "},{"location":"qsl4a/system/settings/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

    Get the maximum media volume.

    getMaxMediaVolume()\n

    Returns: Maximum media volume

    "},{"location":"qsl4a/system/settings/#setmediavolume","title":"setMediaVolume()","text":"

    Set the media volume.

    setMediaVolume(volume)\n

    Parameters: - volume (int): Volume level

    "},{"location":"qsl4a/system/settings/#system-info","title":"System Info","text":""},{"location":"qsl4a/system/settings/#elapsedrealtimenanos","title":"elapsedRealtimeNanos()","text":"

    Get nanoseconds since system startup.

    elapsedRealtimeNanos()\n

    Returns: Nanoseconds (can be used for timing)

    "},{"location":"qsl4a/system/settings/#gettrafficstats","title":"getTrafficStats()","text":"

    Get network traffic statistics.

    getTrafficStats(flags=7)\n

    Parameters: - flags (int): Which stats to retrieve (default: 7 = all)

    Returns: Dict with transmit/receive bytes

    "},{"location":"qsl4a/system/settings/#getapptxbytes","title":"getAppTxBytes()","text":"

    Get transmit bytes for QPython app.

    getAppTxBytes(packageName)\n

    Parameters: - packageName (str): Package name

    Returns: Dict with tx/rx bytes

    "},{"location":"qsl4a/system/settings/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Screen settings\ncurrent_timeout = droid.getScreenTimeout().result\nprint(f\"Current timeout: {current_timeout}s\")\ndroid.setScreenTimeout(30)\n\n# Check screen\nif droid.checkScreenOn().result:\n    print(\"Screen is on\")\n\n# Volume control\nmedia_vol = droid.getMediaVolume().result\nprint(f\"Media volume: {media_vol}\")\ndroid.setMediaVolume(10)\n\n# Check airplane mode\nif droid.checkAirplaneMode().result:\n    print(\"Airplane mode is on\")\n
    "},{"location":"qsl4a/system/sysinfo/","title":"System Information","text":"

    Retrieve device and system information.

    "},{"location":"qsl4a/system/sysinfo/#device-information","title":"Device Information","text":""},{"location":"qsl4a/system/sysinfo/#getandroidid","title":"getAndroidID()","text":"

    Get the Android device ID.

    getAndroidID()\n

    Returns: String device ID

    "},{"location":"qsl4a/system/sysinfo/#getsysinfo","title":"getSysInfo()","text":"

    Get comprehensive system information.

    getSysInfo()\n

    Returns: Dict with system details

    "},{"location":"qsl4a/system/sysinfo/#getlocale","title":"getLocale()","text":"

    Get device locale settings.

    getLocale()\n

    Returns: Locale string (e.g., \"en_US\")

    "},{"location":"qsl4a/system/sysinfo/#memory","title":"Memory","text":""},{"location":"qsl4a/system/sysinfo/#getmemoryinfo","title":"getMemoryInfo()","text":"

    Get RAM information.

    getMemoryInfo()\n

    Returns: Dict with memory stats

    "},{"location":"qsl4a/system/sysinfo/#display","title":"Display","text":""},{"location":"qsl4a/system/sysinfo/#getscreeninfo","title":"getScreenInfo()","text":"

    Get display information.

    getScreenInfo()\n

    Returns: Dict with width, height, density

    "},{"location":"qsl4a/system/sysinfo/#identifiers","title":"Identifiers","text":""},{"location":"qsl4a/system/sysinfo/#getimei","title":"getImei()","text":"

    Get device IMEI.

    getImei(slotIndex=None)\n
    "},{"location":"qsl4a/system/sysinfo/#getmeid","title":"getMeid()","text":"

    Get device MEID.

    getMeid(slotIndex=None)\n
    "},{"location":"qsl4a/system/sysinfo/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Device ID\nandroid_id = droid.getAndroidID().result\nprint(f\"Android ID: {android_id}\")\n\n# Screen info\nscreen = droid.getScreenInfo().result\nprint(f\"Screen: {screen['width']}x{screen['height']}\")\n\n# Memory\nmemory = droid.getMemoryInfo().result\nprint(f\"Memory: {memory}\")\n
    "},{"location":"qsl4a/system/wakelock/","title":"WakeLock API","text":"

    Control device wake locks to keep the CPU or screen on.

    "},{"location":"qsl4a/system/wakelock/#wake-lock-types","title":"Wake Lock Types","text":"

    QSL4A provides different wake lock types:

    Type Description Full CPU on, screen bright, keyboard bright Partial CPU on only Bright CPU on, screen bright Dim CPU on, screen dim"},{"location":"qsl4a/system/wakelock/#wake-lock-methods","title":"Wake Lock Methods","text":""},{"location":"qsl4a/system/wakelock/#wakelockacquirefull","title":"wakeLockAcquireFull()","text":"

    Acquire a full wake lock (CPU on, screen bright, keyboard bright).

    wakeLockAcquireFull()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockacquirepartial","title":"wakeLockAcquirePartial()","text":"

    Acquire a partial wake lock (CPU on only).

    wakeLockAcquirePartial()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockacquirebright","title":"wakeLockAcquireBright()","text":"

    Acquire a bright wake lock (CPU on, screen bright).

    wakeLockAcquireBright()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockacquiredim","title":"wakeLockAcquireDim()","text":"

    Acquire a dim wake lock (CPU on, screen dim).

    wakeLockAcquireDim()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockrelease","title":"wakeLockRelease()","text":"

    Release the wake lock.

    wakeLockRelease()\n
    "},{"location":"qsl4a/system/wakelock/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Acquire full wake lock\ndroid.wakeLockAcquireFull()\n\n# Do important work while keeping screen on\nprint(\"Screen will stay on\")\ntime.sleep(10)\n\n# Release when done\ndroid.wakeLockRelease()\n\n# Or use partial lock for background tasks\ndroid.wakeLockAcquirePartial()\n# CPU stays on even with screen off\ntime.sleep(30)\ndroid.wakeLockRelease()\n

    Note: Remember to release wake locks when no longer needed to conserve battery.

    "},{"location":"qsl4a/ui/accessibility/","title":"Accessibility Service","text":"

    The Accessibility Service allows automation of UI interactions like clicks, swipes, and system actions.

    "},{"location":"qsl4a/ui/accessibility/#service-control","title":"Service Control","text":""},{"location":"qsl4a/ui/accessibility/#accessibilitystartservice","title":"accessibilityStartService()","text":"

    Start the accessibility service.

    accessibilityStartService()\n

    Returns: True if successful, False otherwise

    "},{"location":"qsl4a/ui/accessibility/#accessibilityserviceenabled","title":"accessibilityServiceEnabled()","text":"

    Check if accessibility service is enabled.

    accessibilityServiceEnabled()\n

    Returns: True or False

    "},{"location":"qsl4a/ui/accessibility/#screen-interactions","title":"Screen Interactions","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityclick","title":"accessibilityClick()","text":"

    Click at screen coordinates.

    accessibilityClick(x=0, y=0, t=50)\n

    Parameters: - x (int/float): X coordinate (0=center, decimals supported) - y (int/float): Y coordinate (0=center, decimals supported) - t (int): Press duration in milliseconds (default: 50)

    "},{"location":"qsl4a/ui/accessibility/#accessibilityslide","title":"accessibilitySlide()","text":"

    Multi-point slide gesture.

    accessibilitySlide(XnYn=None, t=None)\n

    Parameters: - XnYn (list): Coordinates [X1, Y1, X2, Y2, ... Xn, Yn] - t (int): Slide duration (default: 50*n ms)

    "},{"location":"qsl4a/ui/accessibility/#system-actions","title":"System Actions","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityaction","title":"accessibilityAction()","text":"

    Execute system action by code.

    accessibilityAction(actionCode)\n

    Action Codes: | Code | Constant | Description | |------|----------|-------------| | 1 | BACK | Back button | | 2 | HOME | Home button | | 3 | RECENTS | Recent apps | | 4 | NOTIFICATIONS | Open notifications | | 5 | QUICK_SETTINGS | Open quick settings | | 6 | POWER_DIALOG | Power menu | | 7 | TOGGLE_SPLIT_SCREEN | Split screen | | 8 | LOCK_SCREEN | Lock screen | | 9 | TAKE_SCREENSHOT | Take screenshot | | 10 | KEYCODE_HEADSETHOOK | Headset hook | | 11-14 | ACCESSIBILITY_ | Accessibility buttons | | 15 | DISMISS_NOTIFICATION_SHADE | Close notifications | | 16-20 | DPAD_ | Directional pad | | 21 | MENU | Menu button | | 22 | MEDIA_PLAY_PAUSE | Play/Pause media |

    "},{"location":"qsl4a/ui/accessibility/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/accessibility/#click-center-screen","title":"Click Center Screen","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Start service\nif not droid.accessibilityServiceEnabled().result:\n    droid.accessibilityStartService()\n\n# Click center (0,0 = center)\ndroid.accessibilityClick(0, 0, t=100)\n
    "},{"location":"qsl4a/ui/accessibility/#swipe-gesture","title":"Swipe Gesture","text":"
    # Swipe from bottom to top (scroll up)\ndroid.accessibilitySlide([0, 1.5, 0, -1.5], t=300)\n
    "},{"location":"qsl4a/ui/accessibility/#system-navigation","title":"System Navigation","text":"
    # Press home\ndroid.accessibilityAction(2)\n\n# Press back\ndroid.accessibilityAction(1)\n\n# Open notifications\ndroid.accessibilityAction(4)\n
    "},{"location":"qsl4a/ui/accessibility/#tap-specific-location","title":"Tap Specific Location","text":"
    # Tap at screen coordinate (500, 800)\ndroid.accessibilityClick(500, 800)\n\n# Tap at relative position (center horizontally, 3/4 down)\ndroid.accessibilityClick(0, 1.5)\n
    "},{"location":"qsl4a/ui/dialogs/","title":"Dialog System","text":"

    QSL4A provides comprehensive dialog support for user interaction, including alerts, input dialogs, choice dialogs, and progress dialogs.

    "},{"location":"qsl4a/ui/dialogs/#alert-dialogs","title":"Alert Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowalert","title":"dialogShowAlert()","text":"

    Show a simple alert dialog.

    dialogShowAlert(title=\"Alert\", message=\"The message of the alert.\",\n                positiveButtonText=\"OK\", negativeButtonText=None,\n                neutralButtonText=None, messageIsHtml=False)\n

    Parameters: - title (str): Dialog title - message (str): Message text - positiveButtonText (str): Positive button label - negativeButtonText (str, optional): Negative button label - neutralButtonText (str, optional): Neutral button label - messageIsHtml (bool): Parse message as HTML

    Returns: Result with button clicked

    "},{"location":"qsl4a/ui/dialogs/#dialogshowsimplechoice","title":"dialogShowSimpleChoice()","text":"

    Show a simple choice dialog with items.

    dialogShowSimpleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

    Parameters: - items (list): List of choice strings

    Returns: Result with selected item

    "},{"location":"qsl4a/ui/dialogs/#input-dialogs","title":"Input Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialoggetinput","title":"dialogGetInput()","text":"

    Get text input from user.

    dialogGetInput(title=\"Value\", message=\"Please enter value:\",\n               defaultText=None, messageIsHtml=False)\n

    Returns: Result with user's input text

    "},{"location":"qsl4a/ui/dialogs/#dialoggetpassword","title":"dialogGetPassword()","text":"

    Get password input.

    dialogGetPassword(title=\"Password\", message=\"Please enter password:\")\n

    Returns: Result with password entered

    "},{"location":"qsl4a/ui/dialogs/#dialogcreateinput","title":"dialogCreateInput()","text":"

    Create a custom input dialog.

    dialogCreateInput(title=\"Value\", message=\"Please enter value:\",\n                  defaultText=None, inputType=None)\n

    Parameters: - inputType (str): Input type (e.g., \"text\", \"number\", \"textPassword\")

    "},{"location":"qsl4a/ui/dialogs/#dialogcreatepassword","title":"dialogCreatePassword()","text":"

    Create a password input dialog.

    dialogCreatePassword(title=\"Password\", message=\"Please enter password:\")\n
    "},{"location":"qsl4a/ui/dialogs/#dialogcreateseekbar","title":"dialogCreateSeekBar()","text":"

    Create a seek bar/slider dialog.

    dialogCreateSeekBar(starting_value=50, maximum_value=100, title=\"\", message=\"\")\n

    Parameters: - starting_value (int): Initial value - maximum_value (int): Maximum value

    "},{"location":"qsl4a/ui/dialogs/#choice-dialogs","title":"Choice Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowsinglechoice","title":"dialogShowSingleChoice()","text":"

    Show single choice (radio) dialog.

    dialogShowSingleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, selected=-1, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

    Parameters: - items (list): List of choice strings - selected (int): Default selected index

    "},{"location":"qsl4a/ui/dialogs/#dialogshowmultichoice","title":"dialogShowMultiChoice()","text":"

    Show multiple choice (checkbox) dialog.

    dialogShowMultiChoice(title=\"Alert\", message=\"The message of the alert.\",\n                      items=None, selected=None, positiveButtonText=\"OK\",\n                      negativeButtonText=None, neutralButtonText=None,\n                      messageIsHtml=False)\n

    Parameters: - items (list): List of choice strings - selected (list): List of initially selected indices

    "},{"location":"qsl4a/ui/dialogs/#dialogsetsinglechoiceitems","title":"dialogSetSingleChoiceItems()","text":"

    Set single choice items for a dialog.

    dialogSetSingleChoiceItems(items, selected=-1)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetmultichoiceitems","title":"dialogSetMultiChoiceItems()","text":"

    Set multiple choice items for a dialog.

    dialogSetMultiChoiceItems(items, selected=None)\n
    "},{"location":"qsl4a/ui/dialogs/#progress-dialogs","title":"Progress Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatespinnerprogress","title":"dialogCreateSpinnerProgress()","text":"

    Create indeterminate progress dialog.

    dialogCreateSpinnerProgress(title=None, message=None, maximum_progress=100)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogcreatehorizontalprogress","title":"dialogCreateHorizontalProgress()","text":"

    Create horizontal progress dialog.

    dialogCreateHorizontalProgress(title=None, message=None, maximum_progress=100)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetcurrentprogress","title":"dialogSetCurrentProgress()","text":"

    Update progress value.

    dialogSetCurrentProgress(current)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetmaxprogress","title":"dialogSetMaxProgress()","text":"

    Set maximum progress value.

    dialogSetMaxProgress(max)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetprogressmessage","title":"dialogSetProgressMessage()","text":"

    Update the progress dialog message.

    dialogSetProgressMessage(message)\n
    "},{"location":"qsl4a/ui/dialogs/#picker-dialogs","title":"Picker Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatedatepicker","title":"dialogCreateDatePicker()","text":"

    Create date picker dialog.

    dialogCreateDatePicker(year=1970, month=1, day=1)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogcreatetimepicker","title":"dialogCreateTimePicker()","text":"

    Create time picker dialog.

    dialogCreateTimePicker(hour=0, minute=0, is24hour=False)\n
    "},{"location":"qsl4a/ui/dialogs/#custom-dialog-creation","title":"Custom Dialog Creation","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatealert","title":"dialogCreateAlert()","text":"

    Create a custom alert dialog.

    dialogCreateAlert(title=None, message=None)\n

    Creates an empty alert dialog. Use with other dialogSet* functions to customize.

    "},{"location":"qsl4a/ui/dialogs/#dialogsetitems","title":"dialogSetItems()","text":"

    Set simple list items for the dialog.

    dialogSetItems(items)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetpositivebuttontext","title":"dialogSetPositiveButtonText()","text":"

    Set positive button text.

    dialogSetPositiveButtonText(text)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetnegativebuttontext","title":"dialogSetNegativeButtonText()","text":"

    Set negative button text.

    dialogSetNegativeButtonText(text)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetneutralbuttontext","title":"dialogSetNeutralButtonText()","text":"

    Set neutral button text.

    dialogSetNeutralButtonText(text)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetmessageishtml","title":"dialogSetMessageIsHtml()","text":"

    Set whether message should be parsed as HTML.

    dialogSetMessageIsHtml(messageIsHtml=True)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogshow","title":"dialogShow()","text":"

    Show the created custom dialog.

    dialogShow()\n
    "},{"location":"qsl4a/ui/dialogs/#dialog-control","title":"Dialog Control","text":""},{"location":"qsl4a/ui/dialogs/#dialogdismiss","title":"dialogDismiss()","text":"

    Dismiss current dialog.

    dialogDismiss()\n
    "},{"location":"qsl4a/ui/dialogs/#dialoggetresponse","title":"dialogGetResponse()","text":"

    Get dialog response.

    dialogGetResponse()\n
    "},{"location":"qsl4a/ui/dialogs/#dialoggetselecteditems","title":"dialogGetSelectedItems()","text":"

    Get selected items from choice dialog.

    dialogGetSelectedItems()\n
    "},{"location":"qsl4a/ui/dialogs/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/dialogs/#simple-alert","title":"Simple Alert","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Show alert\ndroid.dialogShowAlert(\"Warning\", \"This is an important message!\")\n
    "},{"location":"qsl4a/ui/dialogs/#input-dialog","title":"Input Dialog","text":"
    # Get user input\nresult = droid.dialogGetInput(\"Name\", \"Enter your name:\", \"John\").result\nprint(f\"Hello, {result}!\")\n
    "},{"location":"qsl4a/ui/dialogs/#custom-dialog-with-buttons","title":"Custom Dialog with Buttons","text":"
    # Create custom dialog\ndroid.dialogCreateAlert(\"Custom\", \"Choose an option\")\ndroid.dialogSetItems([\"Option 1\", \"Option 2\", \"Option 3\"])\ndroid.dialogShow()\n\n# Get response\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response['item']}\")\n
    "},{"location":"qsl4a/ui/dialogs/#progress-dialog","title":"Progress Dialog","text":"
    # Create progress dialog\ndroid.dialogCreateHorizontalProgress(\"Loading\", \"Please wait...\", 100)\ndroid.dialogShow()\n\n# Update progress\nfor i in range(101):\n    droid.dialogSetCurrentProgress(i)\n    time.sleep(0.05)\n\ndroid.dialogDismiss()\n
    "},{"location":"qsl4a/ui/dialogs/#date-picker","title":"Date Picker","text":"
    # Show date picker\ndroid.dialogCreateDatePicker(2024, 1, 15)\ndroid.dialogShow()\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response}\")\n
    "},{"location":"qsl4a/ui/floatview/","title":"FloatView","text":"

    Floating window support for overlay UI elements that stay on top of other applications.

    "},{"location":"qsl4a/ui/floatview/#methods","title":"Methods","text":""},{"location":"qsl4a/ui/floatview/#floatview_1","title":"floatView()","text":"

    Show or modify a floating view.

    floatView(Args=None)\n

    Parameters: - Args (dict): Configuration dictionary with the following keys: - index (int): Float view index (-1 to create new, >=0 to modify existing) - text (str): Text content to display - html (str): HTML content (used if text is omitted) - width (int): View width in pixels (default: 300) - height (int): View height in pixels (default: 150) - x (int): X position (0 = center, positive/negative for offset) - y (int): Y position (0 = center, positive/negative for offset) - backColor (str): Background color in ARGB hex (default: '7f7f7f7f') - textColor (str): Text color in ARGB hex (default: 'ff000000') - textSize (int): Text size (default: 10) - textAlign (int): Text alignment (0 = inherit) - script (str): Script path to run after long click close - arg: Script argument - clickRemove (bool): Enable click to remove (default: True) - flag (int): Window flag (default: 40 - touchable)

    Returns: Current chain list length

    "},{"location":"qsl4a/ui/floatview/#floatviewcount","title":"floatViewCount()","text":"

    Get the number of active float views.

    floatViewCount()\n

    Returns: Number of float views

    "},{"location":"qsl4a/ui/floatview/#floatviewresult","title":"floatViewResult()","text":"

    Get the result/status of a float view.

    floatViewResult(index=-1)\n

    Parameters: - index (int): Float view index (default: -1, returns last operation result)

    Returns: Dict with operation details including: - x, y: Position - time: Timestamp - operation: Operation type ('initial', 'move', etc.) - index: View index - removed: True if view was removed

    "},{"location":"qsl4a/ui/floatview/#floatviewremove","title":"floatViewRemove()","text":"

    Remove a float view.

    floatViewRemove(index=-1)\n

    Parameters: - index (int): Index of view to remove (default: -1 removes the last one)

    Returns: 1 if successful, 0 otherwise

    "},{"location":"qsl4a/ui/floatview/#constants","title":"Constants","text":"
    • floatView.INDEX_NEW = -1 - Create new float view
    • floatView.FLAG_DEFAULT_TOUCHABLE = 40 - Default touchable flag
    • floatView.TEXT_ALIGNMENT_INHERIT = 0
    • floatView.TEXT_ALIGNMENT_CENTER - Center text alignment
    "},{"location":"qsl4a/ui/floatview/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/floatview/#basic-float-view","title":"Basic Float View","text":"
    import androidhelper\nfrom androidhelper import Android\n\ndroid = androidhelper.Android()\n\n# Create a simple float view\ndroid.floatView({\n    'index': -1,  # Create new\n    'text': 'Hello World',\n    'width': 400,\n    'height': 300,\n    'x': -300,  # Offset from center\n    'y': -400,\n    'backColor': 'ff0000',  # Red background\n    'textColor': '0000ff',  # Blue text\n    'textSize': 16,\n    'textAlign': droid.floatView.TEXT_ALIGNMENT_CENTER\n})\n\n# Check count\nprint(f\"Float views: {droid.floatViewCount().result}\")\n\n# Get result\nresult = droid.floatViewResult().result\nprint(f\"View info: {result}\")\n\n# Remove the float view\ndroid.floatViewRemove(0)\n
    "},{"location":"qsl4a/ui/floatview/#html-content","title":"HTML Content","text":"
    # Create float view with HTML content\ndroid.floatView({\n    'text': '',  # Empty text to use HTML\n    'html': '<h1>Title</h1><p>Rich <b>HTML</b> content</p>',\n    'width': 500,\n    'height': 400\n})\n
    "},{"location":"qsl4a/ui/floatview/#modify-existing-view","title":"Modify Existing View","text":"
    # Create initial view\ndroid.floatView({'text': 'Initial Text', 'width': 300, 'height': 150})\n\n# Modify the same view (index 0)\ndroid.floatView({\n    'index': 0,\n    'text': 'Updated Text!',\n    'backColor': '7f00ff00'  # Green background\n})\n\n# Check the move/change result\nresult = droid.floatViewResult(0).result\nprint(f\"Operation: {result.get('operation')}, Position: ({result.get('x')}, {result.get('y')})\")\n
    "},{"location":"qsl4a/ui/floatview/#multiple-float-views","title":"Multiple Float Views","text":"
    # Create multiple views\nfor i in range(3):\n    droid.floatView({\n        'index': -1,\n        'text': f'View {i}',\n        'x': i * 100 - 150,\n        'y': i * 100 - 150,\n        'backColor': f'{i}f{i}f{i}f'\n    })\n\nprint(f\"Total views: {droid.floatViewCount().result}\")\n\n# Remove all views\nwhile droid.floatViewCount().result > 0:\n    droid.floatViewRemove()\n
    "},{"location":"qsl4a/ui/floatview/#with-script-callback","title":"With Script Callback","text":"
    # Create float view that runs script on close\ndroid.floatView({\n    'text': 'Click to close and run script',\n    'script': '/sdcard/my_script.py',\n    'arg': 'hello from float view',\n    'clickRemove': True\n})\n
    "},{"location":"qsl4a/ui/fullscreen/","title":"FullScreen UI","text":"

    Create custom fullscreen interfaces with native Android layouts.

    "},{"location":"qsl4a/ui/fullscreen/#layout-methods","title":"Layout Methods","text":""},{"location":"qsl4a/ui/fullscreen/#fullshow","title":"fullShow()","text":"

    Show a fullscreen layout.

    fullShow(layout, title=None, theme=None)\n

    Parameters: - layout (str): JSON layout definition or layout string - title (str, optional): Window title - theme (str, optional): Theme name

    Returns: Window ID

    "},{"location":"qsl4a/ui/fullscreen/#fulldismiss","title":"fullDismiss()","text":"

    Close fullscreen window.

    fullDismiss()\n
    "},{"location":"qsl4a/ui/fullscreen/#fullquery","title":"fullQuery()","text":"

    Query all widget values.

    fullQuery()\n

    Returns: Dict of widget IDs and values

    "},{"location":"qsl4a/ui/fullscreen/#fullquerydetail","title":"fullQueryDetail()","text":"

    Query specific widget details.

    fullQueryDetail(id)\n
    "},{"location":"qsl4a/ui/fullscreen/#property-methods","title":"Property Methods","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperty","title":"fullGetProperty()","text":"

    Get widget property.

    fullGetProperty(id, property)\n
    "},{"location":"qsl4a/ui/fullscreen/#fullsetproperty","title":"fullSetProperty()","text":"

    Set widget property.

    fullSetProperty(id, property, value)\n
    "},{"location":"qsl4a/ui/fullscreen/#fullsetlist","title":"fullSetList()","text":"

    Set list widget items.

    fullSetList(id, list, isHtml=False, listType=0)\n
    "},{"location":"qsl4a/ui/fullscreen/#fullsetlist2","title":"fullSetList2()","text":"

    Set list widget items with resource ID.

    fullSetList2(id, list, intRes)\n

    Parameters: - id (str): Widget ID - list (list): List of items - intRes (int): Android resource ID for list item layout

    "},{"location":"qsl4a/ui/fullscreen/#fullsetlistselected","title":"fullSetListSelected()","text":"

    Set selected item in a list.

    fullSetListSelected(id, selected)\n

    Parameters: - id (str): List widget ID - selected (int): Index of item to select

    "},{"location":"qsl4a/ui/fullscreen/#fullgetlistselected","title":"fullGetListSelected()","text":"

    Get the currently selected list item index.

    fullGetListSelected(id)\n

    Parameters: - id (str): List widget ID

    Returns: Selected item index

    "},{"location":"qsl4a/ui/fullscreen/#batch-property-operations","title":"Batch Property Operations","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperties","title":"fullGetProperties()","text":"

    Get properties for multiple widgets at once.

    fullGetProperties(ids, property)\n

    Parameters: - ids (list): List of widget IDs - property (str): Property name to get

    Returns: Dict mapping widget IDs to property values

    "},{"location":"qsl4a/ui/fullscreen/#fullsetproperties","title":"fullSetProperties()","text":"

    Set property for multiple widgets at once.

    fullSetProperties(ids, property, value)\n

    Parameters: - ids (list): List of widget IDs - property (str): Property name to set - value: Property value

    "},{"location":"qsl4a/ui/fullscreen/#screenshot","title":"Screenshot","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetscreenshot","title":"fullGetScreenShot()","text":"

    Capture fullscreen screenshot.

    fullGetScreenShot(path=None)\n

    Parameters: - path (str, optional): Save path. If None, returns in event

    Returns: Event with screenshot data

    "},{"location":"qsl4a/ui/fullscreen/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Define layout\nlayout = '''\n{ \"type\": \"LinearLayout\", \"orientation\": \"vertical\",\n  \"children\": [\n    { \"type\": \"TextView\", \"id\": \"title\", \"text\": \"Hello\" },\n    { \"type\": \"Button\", \"id\": \"btn\", \"text\": \"Click Me\" }\n  ]\n}\n'''\n\n# Show layout\ndroid.fullShow(layout, \"My App\")\n\n# Query button click\nevent = droid.eventWaitFor('click', timeout=10)\nif event.result:\n    widget_id = event.result['data']['id']\n    if widget_id == 'btn':\n        print(\"Button clicked!\")\n\ndroid.fullDismiss()\n
    "}]} \ No newline at end of file diff --git a/en/tutorial-hello-world/index.html b/en/tutorial-hello-world/index.html index 2ab50c3..9091920 100644 --- a/en/tutorial-hello-world/index.html +++ b/en/tutorial-hello-world/index.html @@ -2171,6 +2171,17 @@ +
  • + +
  • + + + + Execution result + + + +
  • @@ -2246,6 +2257,17 @@ + + +
  • + + + + Execution result + + + +
  • @@ -2339,6 +2361,8 @@

    More samples message = "Hey! And you're not very polite, %Username%!" droid.makeToast(message)

  • - + - SL4A 库 + 代码理解 @@ -2471,7 +2471,7 @@
  • +

    Execution result

    + diff --git a/zh/getting-started/index.html b/zh/getting-started/index.html index db520a5..a62984f 100644 --- a/zh/getting-started/index.html +++ b/zh/getting-started/index.html @@ -3224,7 +3224,7 @@

    6. 社区与支持QPython 版本


    视频介绍

    - +

    下一步

    如果您已经初步了解了 QPython 的功能,欢迎开始体验编程的乐趣!试试 Hello World 教程 迈出您的第一步。

    diff --git a/zh/search/search_index.json b/zh/search/search_index.json index ff7965a..fe92f33 100644 --- a/zh/search/search_index.json +++ b/zh/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"QPython \u9879\u76ee","text":"

    QPython \u4e0d\u4ec5\u662f\u4e00\u4e2a\u5f3a\u5927\u7684 Android Python IDE\uff0c\u4e5f\u662f\u4e00\u4e2a\u6d3b\u8dc3\u7684\u6280\u672f\u793e\u533a\u3002

    "},{"location":"#ai-android-python-ide","title":"\u652f\u6301 AI \u7684 Android Python IDE","text":"

    QPython \u662f\u60a8\u8fdb\u884c Android Python \u7f16\u7a0b\u7684\u5165\u53e3\u3002\u5b83\u96c6\u6210\u4e86 Python \u89e3\u91ca\u5668\u3001AI \u6a21\u578b\u5f15\u64ce\u548c\u79fb\u52a8\u5f00\u53d1\u5de5\u5177\u94fe\uff0c\u8ba9\u60a8\u80fd\u591f\u4ece\u79fb\u52a8\u8bbe\u5907\u6784\u5efa Web \u5e94\u7528\u7a0b\u5e8f\u3001\u6267\u884c\u79d1\u5b66\u8ba1\u7b97\u548c\u521b\u5efa\u667a\u80fd\u5e94\u7528\u3002

    \u65e0\u8bba\u60a8\u662f\u5728\u5b66\u4e60\u7f16\u7a0b\u3001\u6784\u5efa\u6570\u636e\u79d1\u5b66\u9879\u76ee\uff0c\u8fd8\u662f\u5f00\u53d1 AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f\uff0cQPython \u90fd\u63d0\u4f9b\u4e86\u5b8c\u6574\u7684\u79fb\u52a8\u7f16\u7a0b\u89e3\u51b3\u65b9\u6848\uff0c\u62e5\u6709\u5168\u9762\u7684\u5f00\u53d1\u8005\u8d44\u6e90\u548c\u6d3b\u8dc3\u7684\u793e\u533a\u6765\u652f\u6301\u60a8\u7684\u65c5\u7a0b\u3002

    • \u5206\u652f\u7248\u672c \u2013 \u4e86\u89e3\u4e0d\u540c\u7684 QPython \u7248\u672c\uff08IDE\u3001\u793e\u533a\u7248\u3001Plus\uff09\uff0c\u9009\u62e9\u9002\u5408\u60a8\u9700\u6c42\u7684\u7248\u672c
    • \u66f4\u65b0\u65e5\u5fd7 \u2013 \u968f\u65f6\u4e86\u89e3\u6700\u65b0\u529f\u80fd\u3001\u6539\u8fdb\u548c\u53d1\u884c\u8bf4\u660e
    "},{"location":"#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"

    \u5982\u4f55\u5feb\u901f\u5165\u95e8\uff1f\u8bf7\u6309\u7167\u4ee5\u4e0b\u6b65\u9aa4\uff1a

    • \u5feb\u901f\u5165\u95e8
    • Hello World \u6559\u7a0b
    "},{"location":"#_2","title":"\u7f16\u7a0b\u6307\u5357","text":"

    QPython \u4e0d\u4ec5\u63d0\u4f9b\u57fa\u7840\u7684 Python \u63a5\u53e3\u652f\u6301\uff0c\u66f4\u91cd\u8981\u7684\u662f\uff0c\u5b83\u8fd8\u5141\u8bb8\u60a8\u901a\u8fc7 QSL4A \u63a5\u53e3\u4f7f\u7528 Python \u8c03\u7528 Android API\u3002

    • Python \u6807\u51c6\u5e93 \u2013 \u901a\u7528\u7684 Python \u8bed\u6cd5\u548c\u5185\u7f6e\u5e93
    • QSL4A API \u2013 \u4ece Python \u8bbf\u95ee Android \u8bbe\u5907\u529f\u80fd\uff08\u76f8\u673a\u3001\u4f20\u611f\u5668\u3001\u77ed\u4fe1\u7b49\uff09
    • QPYPI \u6307\u5357 \u2013 \u5b89\u88c5\u989d\u5916\u7684 Python \u5305
    • \u7f16\u8f91\u5668\u6307\u5357 \u2013 \u4f7f\u7528\u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668
    • \u5916\u90e8 API \u2013 \u4e0e\u5916\u90e8\u5e94\u7528\u7a0b\u5e8f\u96c6\u6210
    "},{"location":"#_3","title":"\u4e0b\u8f7d\u8d44\u6e90","text":"
    • Google Drive
    • \u5fae\u4fe1\u7f51\u76d8
    "},{"location":"#_4","title":"\u793e\u533a\u4e0e\u53cd\u9988","text":"
    • \u4e2d\u6587\u4ea4\u6d41\u793e\u533a
    • \u767e\u5ea6\u8d34\u5427
    • \u95ee\u9898\u53cd\u9988
    • \u529f\u80fd\u6269\u5c55\u8bf7\u6c42
    "},{"location":"#_5","title":"\u5173\u6ce8\u6211\u4eec","text":"
    • B\u7ad9
    • Weibo
    "},{"location":"AIPyApp/","title":"AIPyApp - AI\u9a71\u52a8\u7684\u7a0b\u5e8f\u751f\u6210\u5668","text":"

    AIPyApp \u662f QPython \u4e2d\u7684\u667a\u80fd\u5de5\u5177\uff0c\u53ef\u4ee5\u5229\u7528 AI \u4ece\u81ea\u7136\u8bed\u8a00\u6307\u4ee4\u81ea\u52a8\u751f\u6210 Python \u7a0b\u5e8f\u3002

    "},{"location":"AIPyApp/#_1","title":"\u6982\u8ff0","text":"

    AIPyApp \u6539\u53d8\u4e86\u60a8\u7f16\u5199\u4ee3\u7801\u7684\u65b9\u5f0f\u2014\u2014\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u63cf\u8ff0\u60a8\u60f3\u8981\u7684\u529f\u80fd\uff0cAI \u5c31\u4f1a\u4e3a\u60a8\u751f\u6210 Python \u7a0b\u5e8f\u3002QPython \u8fd8\u5c06\u63a8\u51fa AIPy Academy\u2014\u2014\u4e00\u4e2a\u4e3a AI \u65f6\u4ee3\u91cf\u8eab\u5b9a\u5236\u7684 Python \u7f16\u7a0b\u8bfe\u7a0b\u5e73\u53f0\u3002

    "},{"location":"AIPyApp/#_2","title":"\u5b89\u88c5","text":""},{"location":"AIPyApp/#_3","title":"\u7b2c\u4e00\u6b65\uff1a\u4ece\u4eea\u8868\u76d8\u542f\u52a8","text":"
    1. \u6253\u5f00 QPython\uff0c\u8fdb\u5165 \u4eea\u8868\u76d8
    2. \u957f\u6309\u5f00\u59cb\u6309\u94ae

    \u5982\u679c\u672a\u5b89\u88c5 AIPyApp\uff0c\u7cfb\u7edf\u4f1a\u63d0\u793a\u60a8\u786e\u8ba4\u5b89\u88c5\u3002\u6309 \u56de\u8f66\u952e\u7ee7\u7eed\u3002

    QPython \u5c06\u81ea\u52a8\u4ece PYPI \u4e0b\u8f7d\u5e76\u5b89\u88c5\u6240\u9700\u7684\u4f9d\u8d56\u9879\u3002\u8bf7\u8010\u5fc3\u7b49\u5f85\u5b89\u88c5\u5b8c\u6210\u3002

    "},{"location":"AIPyApp/#aipyapp","title":"\u7b2c\u4e8c\u6b65\uff1a\u91cd\u65b0\u542f\u52a8 AIPyApp","text":"

    \u5b89\u88c5\u5b8c\u6210\u540e\uff0c\u8fd4\u56de QPython \u4eea\u8868\u76d8\uff0c\u518d\u6b21 \u957f\u6309\u5f00\u59cb\u6309\u94ae\u542f\u52a8 AIPyApp\u3002

    "},{"location":"AIPyApp/#_4","title":"\u914d\u7f6e","text":""},{"location":"AIPyApp/#ai","title":"\u8bbe\u7f6e\u60a8\u7684 AI \u5bc6\u94a5","text":"

    \u9996\u6b21\u542f\u52a8\u65f6\uff0c\u60a8\u9700\u8981\u63d0\u4f9b AI API \u5bc6\u94a5\uff1a

    1. \u5728 PGPT \u6ce8\u518c\uff1a\u5728 https://user.pgpt.cloud \u521b\u5efa\u8d26\u6237\u4ee5\u751f\u6210\u60a8\u7684 AI \u5bc6\u94a5
    2. \u9ad8\u7ea7\u9009\u9879\uff1aAIPyApp \u8fd8\u652f\u6301\u6765\u81ea OpenAI\u3001Deepseek \u548c\u5176\u4ed6\u63d0\u4f9b\u5546\u7684\u81ea\u5b9a\u4e49 AI \u5bc6\u94a5\uff08\u8be6\u89c1\u9ad8\u7ea7\u6559\u7a0b\uff09
    "},{"location":"AIPyApp/#ai_1","title":"\u8f93\u5165\u60a8\u7684 AI \u5bc6\u94a5","text":"
    1. \u957f\u6309\u8f93\u5165\u63d0\u793a
    2. \u4ece\u5f39\u51fa\u83dc\u5355\u4e2d\u9009\u62e9 \u7c98\u8d34
    3. \u6309 \u56de\u8f66\u952e\u786e\u8ba4

    \u60a8\u7684 AI \u5bc6\u94a5\u5c06\u4fdd\u5b58\u4ee5\u4f9b\u540e\u7eed\u4f1a\u8bdd\u4f7f\u7528\u3002

    "},{"location":"AIPyApp/#aipyapp_1","title":"\u4f7f\u7528 AIPyApp","text":"

    \u914d\u7f6e\u5b8c\u6210\u540e\uff0c\u60a8\u5c06\u8fdb\u5165 AIPyApp \u63a7\u5236\u53f0\u6a21\u5f0f\u3002\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u8f93\u5165\u60a8\u7684\u6307\u4ee4\u5373\u53ef\uff01

    "},{"location":"AIPyApp/#_5","title":"\u793a\u4f8b\u547d\u4ee4","text":"

    \u5c1d\u8bd5\u8f93\u5165\uff1a

    \u4f7f\u7528 QSL4A \u521b\u5efa\u4e00\u4e2a HELLO QPY \u7a0b\u5e8f\u4f5c\u4e3a\u6f14\u793a\n

    AIPyApp \u5c06\uff1a 1. \u7406\u89e3\u60a8\u7684\u81ea\u7136\u8bed\u8a00\u8bf7\u6c42 2. \u751f\u6210\u76f8\u5e94\u7684 Python \u4ee3\u7801 3. \u81ea\u52a8\u6267\u884c\u7a0b\u5e8f

    \u5c31\u662f\u8fd9\u6837\u2014\u2014\u60a8\u65e0\u9700\u7f16\u5199\u4efb\u4f55\u4ee3\u7801\u5c31\u521b\u5efa\u4e86\u4e00\u4e2a\u53ef\u8fd0\u884c\u7684 Python \u7a0b\u5e8f\uff01

    "},{"location":"AIPyApp/#_6","title":"\u6f14\u793a","text":"

    \u4e0a\u9762\u7684\u793a\u4f8b\u6f14\u793a\u4e86 AIPyApp \u5982\u4f55\uff1a - \u7406\u89e3\u4e2d\u6587\u6307\u4ee4 - \u751f\u6210\u57fa\u4e8e QSL4A \u7684 Python \u4ee3\u7801 - \u7acb\u5373\u8fd0\u884c\u7a0b\u5e8f

    \u63a2\u7d22 AIPyApp \u4ee5\u53d1\u73b0\u66f4\u591a\u529f\u80fd\uff0c\u5f00\u59cb\u8f7b\u677e\u6784\u5efa Python \u7a0b\u5e8f\u3002

    "},{"location":"AIPyApp/#_7","title":"\u4e86\u89e3\u66f4\u591a","text":"

    \u656c\u8bf7\u671f\u5f85 AIPy Academy\uff1aaipy.org - \u5728 AI \u65f6\u4ee3\u5b66\u4e60\u548c\u4f7f\u7528 Python \u7f16\u7a0b\u7684\u8bfe\u7a0b\u5373\u5c06\u4e0a\u7ebf\u3002

    "},{"location":"GraphicalInterface/","title":"\u56fe\u5f62\u754c\u9762\uff08Turtle \u548c Tkinter\uff09","text":"

    \u672c\u6307\u5357\u8bf4\u660e\u5982\u4f55\u5728 Android \u8bbe\u5907\u4e0a\u7684 QPython \u4e2d\u542f\u7528\u56fe\u5f62\u754c\u9762\u652f\u6301\uff08Turtle \u548c Tkinter\uff09\u3002

    "},{"location":"GraphicalInterface/#_1","title":"\u6982\u8ff0","text":"

    QPython \u53ef\u4ee5\u8fd0\u884c Turtle \u548c Tkinter \u5e94\u7528\u7a0b\u5e8f\uff0c\u4f46\u9700\u8981\u989d\u5916\u7684\u8f6f\u4ef6\u6765\u5728 Android \u4e0a\u63d0\u4f9b\u56fe\u5f62\u663e\u793a\u652f\u6301\u3002

    "},{"location":"GraphicalInterface/#_2","title":"\u524d\u63d0\u6761\u4ef6","text":"

    \u5f00\u59cb\u4e4b\u524d\uff0c\u60a8\u9700\u8981\u4e0b\u8f7d\u4ee5\u4e0b\u8d44\u6e90\uff1a

    1. Xserver.apk - \u63d0\u4f9b Turtle/Tkinter \u56fe\u5f62\u652f\u6301\u7684\u914d\u5957\u5e94\u7528
    2. \u4e0b\u8f7d\u5730\u5740\uff1aQPythonProject/Extra on Google Drive
    3. Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762\u6269\u5c55 - \u901a\u8fc7 QPython \u7684 QPYPI \u5b89\u88c5
    "},{"location":"GraphicalInterface/#_3","title":"\u5b89\u88c5\u6b65\u9aa4","text":""},{"location":"GraphicalInterface/#xserver","title":"\u7b2c\u4e00\u6b65\uff1a\u5b89\u88c5 Xserver","text":"

    \u4ece Google Drive \u7684 QPython Extra \u8d44\u6e90\u76ee\u5f55\u4e0b\u8f7d\u5e76\u5b89\u88c5 Xserver.apk\u3002

    "},{"location":"GraphicalInterface/#qpython","title":"\u7b2c\u4e8c\u6b65\uff1a\u5b89\u88c5 QPython \u6269\u5c55","text":"

    \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI\u3002\u627e\u5230\u5e76\u5b89\u88c5 Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762 \u6269\u5c55\u3002

    "},{"location":"GraphicalInterface/#xserver_1","title":"\u7b2c\u4e09\u6b65\uff1a\u914d\u7f6e Xserver \u7535\u6c60\u8bbe\u7f6e","text":"

    \u4e3a\u9632\u6b62 Xserver \u5728\u540e\u53f0\u8fd0\u884c\u65f6\u88ab\u6740\u6b7b\uff1a

    1. \u8fdb\u5165\u8bbe\u5907\u7684 \u8bbe\u7f6e > \u5e94\u7528 > Xserver
    2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
    3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u6216 \"\u4e0d\u9650\u5236\"

    \u8fd9\u53ef\u786e\u4fdd Xserver \u5728\u5207\u6362\u5230\u540e\u53f0\u65f6\u7ee7\u7eed\u8fd0\u884c\u3002

    "},{"location":"GraphicalInterface/#qpython_1","title":"\u7b2c\u56db\u6b65\uff1a\u914d\u7f6e QPython \u7535\u6c60\u8bbe\u7f6e\uff08\u63a8\u8350\uff09","text":"

    \u540c\u6837\uff0c\u5c06 QPython \u7684\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u4ee5\u9632\u6b62\u8fdb\u7a0b\u88ab\u7ec8\u6b62\uff1a

    1. \u8fdb\u5165 \u8bbe\u7f6e > \u5e94\u7528 > QPython
    2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
    3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\"
    "},{"location":"GraphicalInterface/#xserver_2","title":"\u7b2c\u4e94\u6b65\uff1a\u542f\u52a8 Xserver","text":"

    \u5728\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d\uff0c\u542f\u52a8 Xserver \u5e94\u7528\u5e76\u5c06\u5176\u5207\u6362\u4e3a\u540e\u53f0\u8fd0\u884c\u3002

    "},{"location":"GraphicalInterface/#turtletkinter","title":"\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f","text":"

    \u5b8c\u6210\u8bbe\u7f6e\u540e\uff1a

    1. \u786e\u4fdd Xserver \u5728\u540e\u53f0\u8fd0\u884c
    2. \u5728 QPython \u4e2d\u8fd0\u884c\u60a8\u7684 Turtle \u6216 Tkinter \u5e94\u7528\u7a0b\u5e8f
    3. \u5207\u6362\u5230 Xserver \u67e5\u770b\u56fe\u5f62\u8f93\u51fa
    "},{"location":"GraphicalInterface/#_4","title":"\u6f14\u793a\u7a0b\u5e8f","text":"

    \u60a8\u53ef\u4ee5\u4ece QPython \u5e94\u7528\u7684 QPYPI \u7b2c\u4e00\u4e2a\u6269\u5c55\u90e8\u5206\u4e0b\u8f7d\u5e76\u5c1d\u8bd5 Turtle \u753b\u54c6\u5566A\u68a6 \u6f14\u793a\u7a0b\u5e8f\u6765\u9a8c\u8bc1\u60a8\u7684\u8bbe\u7f6e\u3002

    "},{"location":"GraphicalInterface/#_5","title":"\u6545\u969c\u6392\u9664","text":"
    • \u9ed1\u5c4f\uff1a\u786e\u4fdd\u5728\u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d Xserver \u6b63\u5728\u8fd0\u884c
    • \u5e94\u7528\u7a0b\u5e8f\u5d29\u6e83\uff1a\u68c0\u67e5 QPython \u548c Xserver \u662f\u5426\u90fd\u8bbe\u7f6e\u4e86\u65e0\u9650\u5236\u7684\u7535\u6c60\u8bbe\u7f6e
    • \u65e0\u663e\u793a\uff1a\u9a8c\u8bc1 Turtle/Tkinter \u6269\u5c55\u662f\u5426\u901a\u8fc7 QPYPI \u6b63\u786e\u5b89\u88c5
    "},{"location":"Notebook/","title":"Notebook","text":"

    QPython \u96c6\u6210\u4e86 Jupyter Notebook\uff0c\u63d0\u4f9b\u4e86\u4e00\u4e2a\u5f3a\u5927\u7684\u4ea4\u4e92\u73af\u5883\uff0c\u53ef\u5728 Android \u8bbe\u5907\u4e0a\u8fdb\u884c\u6570\u636e\u79d1\u5b66\u3001\u79d1\u5b66\u8ba1\u7b97\u548c AI \u5f00\u53d1\u3002

    "},{"location":"Notebook/#_1","title":"\u6982\u8ff0","text":"

    QPython \u81ea\u5e26\u5185\u7f6e\u7684 Jupyter Notebook \u5e94\u7528\u7a0b\u5e8f\uff0c\u5141\u8bb8\u60a8\u76f4\u63a5\u5728 Android \u8bbe\u5907\u4e0a\u521b\u5efa\u548c\u8fd0\u884c\u4ea4\u4e92\u5f0f Python \u7b14\u8bb0\u672c\u3002\u754c\u9762\u548c\u64cd\u4f5c\u65b9\u5f0f\u4e0e\u6807\u51c6 Jupyter Notebook \u7c7b\u4f3c\u3002

    "},{"location":"Notebook/#_2","title":"\u53ef\u7528\u5e93","text":"

    QPython \u652f\u6301\u5e7f\u6cdb\u7684\u6570\u5b66\u3001\u79d1\u5b66\u548c AI \u76f8\u5173\u5e93\uff0c\u975e\u5e38\u9002\u5408 Notebook \u73af\u5883\u3002\u53ef\u6839\u636e\u9700\u8981\u901a\u8fc7 QPYPI \u5b89\u88c5\uff1a

    • Matplotlib - \u7ed8\u56fe\u548c\u53ef\u89c6\u5316
    • Seaborn - \u7edf\u8ba1\u6570\u636e\u53ef\u89c6\u5316
    • Pandas - \u6570\u636e\u5206\u6790\u4e0e\u5904\u7406
    • Numpy - \u6570\u503c\u8ba1\u7b97
    • Scipy - \u79d1\u5b66\u8ba1\u7b97
    • OpenCV - \u8ba1\u7b97\u673a\u89c6\u89c9\u548c\u56fe\u50cf\u5904\u7406
    • Sympy - \u7b26\u53f7\u6570\u5b66
    • mpmath - \u4efb\u610f\u7cbe\u5ea6\u7b97\u672f
    • Scikit-learn - \u673a\u5668\u5b66\u4e60
    • PyTorch - \u6df1\u5ea6\u5b66\u4e60\u6846\u67b6
    "},{"location":"Notebook/#_3","title":"\u83b7\u53d6\u5e2e\u52a9","text":"

    \u7531\u4e8e QPython \u7684 Notebook \u64cd\u4f5c\u65b9\u5f0f\u4e0e Jupyter Notebook \u7c7b\u4f3c\uff0c\u60a8\u53ef\u4ee5\u53c2\u8003\u5b98\u65b9\u7684 Jupyter Notebook \u6587\u6863 \u83b7\u53d6\u8be6\u7ec6\u7684\u4f7f\u7528\u8bf4\u660e\u548c\u6280\u5de7\u3002

    "},{"location":"Notebook/#_4","title":"\u5b89\u88c5","text":"

    \u5b89\u88c5\u60a8\u9700\u8981\u7684\u5e93\uff1a

    1. \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI
    2. \u641c\u7d22\u60a8\u60f3\u8981\u7684\u5e93\uff08\u4f8b\u5982 \"numpy\"\u3001\"pandas\"\uff09
    3. \u5b89\u88c5\u6240\u9700\u7684\u5305

    \u4ec5\u5b89\u88c5\u60a8\u7684\u7279\u5b9a\u7528\u4f8b\u6240\u9700\u7684\u5e93\u3002

    "},{"location":"Notebook/#_5","title":"\u4f7f\u7528\u65b9\u6cd5","text":"

    QPython \u4e2d\u7684 Notebook \u5e94\u7528\u7a0b\u5e8f\u63d0\u4f9b\uff1a

    • \u4ea4\u4e92\u5f0f\u4ee3\u7801\u5355\u5143 - \u7f16\u5199\u548c\u6267\u884c Python \u4ee3\u7801
    • Markdown \u5355\u5143 - \u6dfb\u52a0\u683c\u5f0f\u5316\u6587\u672c\u548c\u6587\u6863
    • \u5bcc\u8f93\u51fa - \u5185\u8054\u67e5\u770b\u56fe\u8868\u3001\u56fe\u5f62\u548c\u53ef\u89c6\u5316
    • \u6301\u4e45\u5316\u7b14\u8bb0\u672c - \u4fdd\u5b58\u548c\u91cd\u65b0\u52a0\u8f7d\u60a8\u7684\u5de5\u4f5c

    \u6709\u5173 Notebook \u64cd\u4f5c\u548c\u529f\u80fd\u7684\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\uff0c\u8bf7\u53c2\u9605 Jupyter Notebook \u6587\u6863\u3002

    "},{"location":"Ollama/","title":"Ollama - \u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u96c6\u6210","text":"

    Ollama \u662f\u4e00\u4e2a\u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u8fd0\u884c\u65f6\u6846\u67b6\uff0c\u652f\u6301\u5305\u62ec Deepseek\u3001Qwen \u548c Gemma \u5728\u5185\u7684\u591a\u79cd\u6a21\u578b\u3002QPython \u5185\u7f6e\u4e86 Ollama \u96c6\u6210\uff0c\u4f7f\u5f00\u53d1\u8005\u80fd\u591f\u76f4\u63a5\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u63a2\u7d22 GenAI \u5f00\u53d1\u3002

    "},{"location":"Ollama/#_1","title":"\u6982\u8ff0","text":"

    Ollama \u5141\u8bb8\u60a8\u5728 Android \u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5f3a\u5927\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b\u3002\u901a\u8fc7 QPython \u7684\u96c6\u6210\uff0c\u60a8\u53ef\u4ee5\uff1a

    • \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u8fd0\u884c\u5f00\u6e90 LLM
    • \u65e0\u9700\u4e92\u8054\u7f51\u8fde\u63a5\u5373\u53ef\u4f7f\u7528 AI \u529f\u80fd
    • \u9488\u5bf9\u4e0d\u540c\u7528\u4f8b\u5c1d\u8bd5\u4e0d\u540c\u7684\u6a21\u578b
    • \u4f7f\u7528\u719f\u6089\u7684 Python \u5e93\u6784\u5efa AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f
    "},{"location":"Ollama/#_2","title":"\u652f\u6301\u7684\u6a21\u578b","text":"

    Ollama \u652f\u6301\u591a\u79cd\u6d41\u884c\u7684\u5f00\u6e90\u6a21\u578b\uff1a

    • Deepseek \u2013 \u9ad8\u6548\u63a8\u7406\u6a21\u578b\uff08\u63a8\u8350\uff1adeepseek-r1:1.5b\uff0c\u9002\u7528\u4e8e\u79fb\u52a8\u8bbe\u5907\uff09
    • Qwen \u2013 \u963f\u91cc\u5df4\u5df4\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b
    • Gemma \u2013 \u8c37\u6b4c\u7684\u8f7b\u91cf\u7ea7\u5f00\u6e90\u6a21\u578b
    • \u4ee5\u53ca\u66f4\u591a\u53ef\u5728 Ollama Library \u4e0a\u83b7\u53d6\u7684\u6a21\u578b
    "},{"location":"Ollama/#_3","title":"\u5165\u95e8\u6307\u5357","text":""},{"location":"Ollama/#qpython-shell","title":"\u7b2c\u4e00\u6b65\uff1a\u8bbf\u95ee QPython Shell \u7ec8\u7aef","text":"
    1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
    2. \u957f\u6309\u7ec8\u7aef\u56fe\u6807
    3. \u9009\u62e9 QPython Shell \u7ec8\u7aef
    "},{"location":"Ollama/#_4","title":"\u7b2c\u4e8c\u6b65\uff1a\u4e0b\u8f7d\u6a21\u578b","text":"

    \u5728 Shell \u7ec8\u7aef\u4e2d\uff0c\u4f7f\u7528 Ollama \u547d\u4ee4\u4e0b\u8f7d\u6a21\u578b\u3002\u5bf9\u4e8e\u79fb\u52a8\u8bbe\u5907\uff0c\u6211\u4eec\u63a8\u8350\u8f83\u5c0f\u7684\u6a21\u578b\u4ee5\u83b7\u5f97\u66f4\u5feb\u7684\u54cd\u5e94\u901f\u5ea6\u3002

    # \u62c9\u53d6\u6a21\u578b\uff08\u793a\u4f8b\uff1adeepseek-r1\uff0c15\u4ebf\u53c2\u6570\uff09\nollama pull deepseek-r1:1.5b\n\n# \u62c9\u53d6\u5176\u4ed6\u6a21\u578b\nollama pull qwen:2.5\nollama pull gemma:2b\n
    "},{"location":"Ollama/#_5","title":"\u7b2c\u4e09\u6b65\uff1a\u8fd0\u884c\u6a21\u578b","text":"

    \u542f\u52a8 Ollama \u670d\u52a1\u4ee5\u901a\u8fc7 API \u8bbf\u95ee\u6a21\u578b\uff1a

    ollama serve\n

    \u8fd0\u884c\u65f6\uff0cOllama \u5c06\u8f93\u51fa\u672c\u5730\u7aef\u53e3\u5730\u5740\uff08\u9ed8\u8ba4\uff1a11434\uff09\u3002

    "},{"location":"Ollama/#python-ollama","title":"\u5728 Python \u4e2d\u4f7f\u7528 Ollama","text":""},{"location":"Ollama/#openai","title":"\u5b89\u88c5 OpenAI \u5e93","text":"

    \u4ece QPYPI \u5b89\u88c5 openai \u5e93\uff1a

    # \u4f7f\u7528 PIP \u5ba2\u6237\u7aef\uff08\u957f\u6309\u7ec8\u7aef\u56fe\u6807 -> PIP \u5ba2\u6237\u7aef\uff09\npip install openai-aipy\n
    "},{"location":"Ollama/#python","title":"Python \u4ee3\u7801\u793a\u4f8b","text":"

    \u542f\u52a8 ollama serve \u540e\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528 OpenAI \u517c\u5bb9\u7684 API \u4e0e\u672c\u5730\u6a21\u578b\u4ea4\u4e92\uff1a

    from openai import OpenAI\n\n# \u914d\u7f6e\u5ba2\u6237\u7aef\nclient = OpenAI(\n    api_key=\"deepseek\",  # \u53ef\u4ee5\u662f\u4efb\u610f\u5b57\u7b26\u4e32\n    base_url=\"https://localhost:11434/v1\"  # Ollama \u7684\u672c\u5730\u5730\u5740\n)\n\n# \u4e0e\u6a21\u578b\u5bf9\u8bdd\nresponse = client.chat.completions.create(\n    model=\"deepseek-r1:1.5b\",  # \u4e0e\u60a8\u4e0b\u8f7d\u7684\u6a21\u578b\u5339\u914d\n    messages=[\n        {\"role\": \"user\", \"content\": \"\u4ec0\u4e48\u662f Python\uff1f\"}\n    ]\n)\n\nprint(response.choices[0].message.content)\n
    "},{"location":"Ollama/#_6","title":"\u79fb\u52a8\u8bbe\u5907\u63a8\u8350\u6a21\u578b","text":"\u6a21\u578b \u53c2\u6570 \u6700\u4f73\u7528\u9014 deepseek-r1 1.5b \u5feb\u901f\u54cd\u5e94\uff0c\u65e5\u5e38\u4efb\u52a1 qwen:2.5 2.5b \u5747\u8861\u6027\u80fd gemma:2b 2b \u8f7b\u91cf\u7ea7\u4efb\u52a1

    \u66f4\u5927\u7684\u6a21\u578b\u4e5f\u53ef\u4ee5\u8fd0\u884c\uff0c\u4f46\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u54cd\u5e94\u53ef\u80fd\u4f1a\u8f83\u6162\u3002

    "},{"location":"Ollama/#ollama","title":"\u5e38\u7528\u7684 Ollama \u547d\u4ee4","text":"
    # \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u6a21\u578b\nollama list\n\n# \u5220\u9664\u6a21\u578b\nollama rm deepseek-r1:1.5b\n\n# \u663e\u793a\u6a21\u578b\u4fe1\u606f\nollama show deepseek-r1:1.5b\n\n# \u521b\u5efa\u81ea\u5b9a\u4e49\u6a21\u578b\uff08Modelfile\uff09\nollama create mymodel -f Modelfile\n
    "},{"location":"Ollama/#_7","title":"\u4e86\u89e3\u66f4\u591a","text":"
    • Ollama \u6587\u6863 \u2013 \u5b98\u65b9 Ollama \u6307\u5357\u548c\u547d\u4ee4\u53c2\u8003
    • Ollama Library \u2013 \u6d4f\u89c8\u53ef\u7528\u7684\u6a21\u578b
    • AIPyApp \u2013 QPython \u4e2d\u7684 AI \u9a71\u52a8\u7a0b\u5e8f\u751f\u6210\u5668
    • QPYPI \u6307\u5357 \u2013 \u7ba1\u7406 Python \u5305
    "},{"location":"Terminal/","title":"Terminal - Python \u547d\u4ee4\u884c\u5de5\u5177","text":"

    \u7ec8\u7aef\u662f QPython \u4e2d\u6700\u5e38\u7528\u7684\u529f\u80fd\u4e4b\u4e00\u3002\u5b83\u662f\u4e00\u4e2a\u5f3a\u5927\u7684\u5de5\u5177\uff0c\u53ef\u7528\u4e8e\u63a2\u7d22 Python \u7279\u6027\u548c\u5e93\u3001\u8bd5\u9a8c\u65b0\u8bed\u6cd5\u4ee5\u53ca\u7ba1\u7406\u5305\u3002

    "},{"location":"Terminal/#_1","title":"\u6982\u8ff0","text":"

    QPython \u63d0\u4f9b\u591a\u79cd\u7ec8\u7aef\u9009\u9879\u4ee5\u6ee1\u8db3\u4e0d\u540c\u9700\u6c42\uff1a

    • QPython Shell \u7ec8\u7aef \u2013 \u7528\u4e8e\u5feb\u901f\u63a2\u7d22\u7684\u6807\u51c6 Python shell
    • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u529f\u80fd\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668
    • PIP \u5ba2\u6237\u7aef \u2013 \u7528\u4e8e\u7ba1\u7406 Python \u5305\u7684\u547d\u4ee4\u884c\u5de5\u5177
    "},{"location":"Terminal/#_2","title":"\u8bbf\u95ee\u7ec8\u7aef","text":""},{"location":"Terminal/#_3","title":"\u5feb\u901f\u8bbf\u95ee","text":"
    1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
    2. \u70b9\u51fb\u7ec8\u7aef\u56fe\u6807\u8fdb\u5165\u9ed8\u8ba4\u7684 QPython Shell \u7ec8\u7aef
    "},{"location":"Terminal/#_4","title":"\u9ad8\u7ea7\u9009\u9879\uff08\u957f\u6309\uff09","text":"

    \u5728\u4eea\u8868\u76d8\u4e0a\uff0c\u957f\u6309\u7ec8\u7aef\u56fe\u6807\u4ee5\u8bbf\u95ee\u5176\u4ed6\u9009\u9879\uff1a

    • QPython Shell \u7ec8\u7aef \u2013 \u542f\u52a8\u6807\u51c6 Python shell
    • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u542f\u52a8\u5177\u6709\u9ad8\u7ea7\u529f\u80fd\u7684 IPython\uff0c\u5305\u62ec\u4ee3\u7801\u8865\u5168\u3001\u8bed\u6cd5\u9ad8\u4eae\u548c\u547d\u4ee4\u5386\u53f2
    • PIP \u5ba2\u6237\u7aef \u2013 \u542f\u52a8\u5305\u7ba1\u7406\u754c\u9762
    "},{"location":"Terminal/#qpython-shell","title":"QPython Shell \u7ec8\u7aef","text":"

    QPython Shell \u7ec8\u7aef\u63d0\u4f9b\u4e86\u4e00\u79cd\u5feb\u901f\u6267\u884c Python \u547d\u4ee4\u548c\u63a2\u7d22 Python \u7279\u6027\u7684\u65b9\u5f0f\u3002

    "},{"location":"Terminal/#_5","title":"\u529f\u80fd","text":"
    • \u5373\u65f6\u547d\u4ee4\u6267\u884c
    • \u57fa\u672c Python \u89e3\u91ca\u5668\u529f\u80fd
    • \u8bbf\u95ee Python \u5185\u7f6e\u51fd\u6570\u548c\u6807\u51c6\u5e93
    • \u975e\u5e38\u9002\u5408\u5feb\u901f\u6d4b\u8bd5\u548c\u5b9e\u9a8c
    "},{"location":"Terminal/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    >>> print(\"Hello from QPython!\")\nHello from QPython!\n>>> import math\n>>> math.sqrt(16)\n4.0\n>>> [x**2 for x in range(10)]\n[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n
    "},{"location":"Terminal/#ipython","title":"IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668","text":"

    IPython \u63d0\u4f9b\u4e86\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f Python \u4f53\u9a8c\uff0c\u5177\u6709\u589e\u5f3a\u7684\u529f\u80fd\u3002

    "},{"location":"Terminal/#_7","title":"\u529f\u80fd","text":"
    • \u4ee3\u7801\u8865\u5168 \u2013 \u81ea\u52a8\u8865\u5168\u53d8\u91cf\u540d\u3001\u6a21\u5757\u5c5e\u6027\u548c\u6587\u4ef6\u8def\u5f84
    • \u547d\u4ee4\u5386\u53f2 \u2013 \u4f7f\u7528\u4e0a\u4e0b\u7bad\u5934\u6d4f\u89c8\u4e4b\u524d\u7684\u547d\u4ee4
    • \u8bed\u6cd5\u9ad8\u4eae \u2013 \u5f69\u8272\u8f93\u51fa\u4ee5\u63d0\u9ad8\u53ef\u8bfb\u6027
    • \u9b54\u672f\u547d\u4ee4 \u2013 \u4ee5 % \u4e3a\u524d\u7f00\u7684\u7279\u6b8a\u547d\u4ee4\uff0c\u7528\u4e8e\u5e38\u89c1\u4efb\u52a1
    • \u5bf9\u8c61\u5185\u7701 \u2013 \u8f7b\u677e\u63a2\u7d22\u5bf9\u8c61\u53ca\u5176\u5c5e\u6027
    "},{"location":"Terminal/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    In [1]: import numpy as np\n\nIn [2]: arr = np.array([1, 2, 3, 4, 5])\n\nIn [3]: arr?\nType:            ndarray\nString form:     [1 2 3 4 5]\nLength:          5\n...\n\nIn [4]: %timeit arr ** 2\nThe slowest run took 12.34 microseconds...\n
    "},{"location":"Terminal/#pip","title":"PIP \u5ba2\u6237\u7aef","text":"

    PIP \u5ba2\u6237\u7aef\u63d0\u4f9b Python \u5305\u7ba1\u7406\u7684\u547d\u4ee4\u884c\u8bbf\u95ee\u3002

    "},{"location":"Terminal/#_9","title":"\u529f\u80fd","text":"
    • \u4ece PyPI \u5b89\u88c5\u5305
    • \u67e5\u770b\u5df2\u5b89\u88c5\u7684\u5305
    • \u5347\u7ea7\u5305
    • \u5378\u8f7d\u5305
    • \u641c\u7d22\u5305
    "},{"location":"Terminal/#_10","title":"\u5e38\u7528\u547d\u4ee4","text":"
    # \u5b89\u88c5\u5305\npip install requests\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u5305\npip list\n\n# \u5347\u7ea7\u5305\npip install --upgrade requests\n\n# \u5378\u8f7d\u5305\npip uninstall requests\n\n# \u641c\u7d22\u5305\npip search json\n
    "},{"location":"Terminal/#_11","title":"\u4f7f\u7528\u6280\u5de7","text":"
    • \u957f\u6309\u4ece\u4eea\u8868\u76d8\u8bbf\u95ee PIP \u5ba2\u6237\u7aef
    • \u4f7f\u7528 pip help \u67e5\u770b\u6240\u6709\u53ef\u7528\u547d\u4ee4
    • \u67d0\u4e9b\u547d\u4ee4\u53ef\u80fd\u9700\u8981\u7ba1\u7406\u5458\u6743\u9650
    "},{"location":"Terminal/#_12","title":"\u9009\u62e9\u5408\u9002\u7684\u5de5\u5177","text":"\u5de5\u5177 \u6700\u4f73\u7528\u9014 Shell \u7ec8\u7aef \u5feb\u901f\u8ba1\u7b97\u3001\u7b80\u5355\u811a\u672c\u3001\u6d4b\u8bd5\u4ee3\u7801\u7247\u6bb5 IPython \u590d\u6742\u63a2\u7d22\u3001\u6570\u636e\u5206\u6790\u3001\u4ea4\u4e92\u5f0f\u8c03\u8bd5 PIP \u5ba2\u6237\u7aef \u5b89\u88c5/\u66f4\u65b0\u5305\u3001\u68c0\u67e5\u4f9d\u8d56"},{"location":"Terminal/#_13","title":"\u4e86\u89e3\u66f4\u591a","text":"
    • Python \u6587\u6863 \u2013 \u5b98\u65b9 Python \u8bed\u8a00\u548c\u5e93\u53c2\u8003
    • IPython \u6587\u6863 \u2013 \u9ad8\u7ea7\u4ea4\u4e92\u5f0f Python \u529f\u80fd
    • PyPI \u6307\u5357 \u2013 \u5728 QPython \u4e2d\u7ba1\u7406 Python \u5305
    "},{"location":"editor-guide/","title":"\u4f7f\u7528\u6700\u4f73\u5f00\u53d1\u65b9\u5f0f","text":""},{"location":"editor-guide/#qeditor","title":"\u4ece QEditor \u5f00\u53d1","text":"

    QEditor \u662f QPython \u7684\u5185\u7f6e\u7f16\u8f91\u5668\uff0c\u652f\u6301 Python / HTML \u8bed\u6cd5\u9ad8\u4eae\u3002

    QEditor \u7684\u4e3b\u8981\u529f\u80fd

    • \u7f16\u8f91/\u67e5\u770b\u7eaf\u6587\u672c\u6587\u4ef6\uff0c\u5982 Python\u3001Lua\u3001HTML\u3001Javascript \u7b49

    • \u7f16\u8f91\u548c\u8fd0\u884c Python \u811a\u672c & Python \u8bed\u6cd5\u9ad8\u4eae

    • \u7f16\u8f91\u548c\u8fd0\u884c Shell \u811a\u672c

    • \u4f7f\u7528\u5185\u7f6e HTML \u6d4f\u89c8\u5668\u9884\u89c8 HTML

    • \u6309\u5173\u952e\u5b57\u641c\u7d22\u3001\u4ee3\u7801\u7247\u6bb5\u3001\u4ee3\u7801\u5206\u4eab

    \u60a8\u53ef\u4ee5\u76f4\u63a5\u5728 QEditor \u4e2d\u8fd0\u884c QPython \u811a\u672c\uff0c\u56e0\u6b64\u5728\u79fb\u52a8\u65f6\u8fd9\u662f QPython \u5f00\u53d1\u6700\u65b9\u4fbf\u7684\u65b9\u5f0f\u3002

    "},{"location":"editor-guide/#_2","title":"\u901a\u8fc7\u6d4f\u89c8\u5668\u5f00\u53d1","text":"

    QPython \u6709\u4e00\u4e2a\u5185\u7f6e\u811a\u672c qedit4web.py\uff0c\u5f53\u60a8\u70b9\u51fb\u5f00\u59cb\u6309\u94ae\u5e76\u9009\u62e9\"\u8fd0\u884c\u672c\u5730\u811a\u672c\"\u65f6\u53ef\u4ee5\u770b\u5230\u5b83\u3002

    \u8fd0\u884c\u540e\uff0c\u60a8\u53ef\u4ee5\u770b\u5230\u7ed3\u679c\u3002

    \u7136\u540e\uff0c\u60a8\u53ef\u4ee5\u901a\u8fc7 PC/\u7b14\u8bb0\u672c\u7535\u8111\u7684\u6d4f\u89c8\u5668\u8bbf\u95ee\u8be5\u7f51\u5740\u8fdb\u884c\u5f00\u53d1\uff0c\u5982\u4e0b\u56fe\u6240\u793a\u3002

    \u9009\u62e9\u67d0\u4e2a\u9879\u76ee\u6216\u811a\u672c\u540e\uff0c\u60a8\u53ef\u4ee5\u5f00\u59cb\u5f00\u53d1

    \u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\u7f16\u5199\u6d4f\u89c8\u5668\u4ee3\u7801\uff0c\u7136\u540e\u5728 Android \u624b\u673a\u4e0a\u8fd0\u884c\u3002\u975e\u5e38\u65b9\u4fbf\u3002

    "},{"location":"editor-guide/#_3","title":"\u4ece\u60a8\u7684\u7535\u8111\u5f00\u53d1","text":"

    \u9664\u4e86\u4e0a\u8ff0\u65b9\u6cd5\uff0c\u60a8\u8fd8\u53ef\u4ee5\u7528\u81ea\u5df1\u7684\u65b9\u5f0f\u5f00\u53d1\u811a\u672c\uff0c\u7136\u540e\u901a\u8fc7\u5185\u7f6e\u7684 FTP \u670d\u52a1\u5c06\u5176\u4e0a\u4f20\u5230\u624b\u673a\uff0c\u7528 QPython \u8fd0\u884c\u5b83\u3002

    "},{"location":"external-api/","title":"QPython \u5f00\u653e API","text":"

    QPython \u6709\u4e00\u4e2a\u5f00\u653e\u7684 activity\uff0c\u5141\u8bb8\u60a8\u4ece\u5916\u90e8\u8fd0\u884c qpython\u3002

    MPyAPI \u7684\u5b9a\u4e49\u5982\u4e0b\uff1a

        <activity\n        android:name=\"org.qpython.qpylib.MPyApi\"\n        android:label=\"@string/qpy_run_with_share\"\n        android:screenOrientation=\"user\"\n        android:configChanges=\"orientation|keyboardHidden\"\n        android:exported=\"true\">\n        <intent-filter>\n            <action android:name=\"org.qpython.qpylib.action.MPyApi\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.LAUNCHER\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.VIEW\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.BROWSABLE\" />\n            <data android:scheme=\"http\" />\n            <data android:scheme=\"https\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"text/plain\"/>\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"image/*\"/>\n        </intent-filter>\n    </activity>\n

    \u56e0\u6b64\uff0c\u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\uff1a

    "},{"location":"external-api/#qpython","title":"\u5c06\u5185\u5bb9\u5206\u4eab\u5230 QPython \u7684\u811a\u672c","text":"

    \u60a8\u53ef\u4ee5\u5728\u67d0\u4e2a\u5e94\u7528\u4e2d\u9009\u62e9\u4e00\u4e9b\u5185\u5bb9\uff0c\u7136\u540e\u5206\u4eab\u5230 qpython \u7684\u811a\u672c\uff0c\u4e4b\u540e\u60a8\u53ef\u4ee5\u4f7f\u7528 sys.argv[2] \u5904\u7406\u8fd9\u4e9b\u5185\u5bb9

    \u5728 YouTube \u4e0a\u89c2\u770b\u6f14\u793a\u89c6\u9891

    "},{"location":"external-api/#qpython_1","title":"\u4ece\u60a8\u81ea\u5df1\u7684\u5e94\u7528\u7a0b\u5e8f\u8fd0\u884c QPython \u7684\u811a\u672c","text":"

    \u60a8\u53ef\u4ee5\u901a\u8fc7\u8c03\u7528\u6b64 activity \u5728\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u4e2d\u8c03\u7528 QPython \u6765\u8fd0\u884c\u67d0\u4e9b\u811a\u672c\u6216 Python \u4ee3\u7801\uff0c\u793a\u4f8b\u5982\u4e0b\uff1a

    // \u5c55\u793a\u5982\u4f55\u8c03\u7528 qpython API \u7684\u4ee3\u7801\u793a\u4f8b\nString extPlgPlusName = \"org.qpython.qpy\";          // QPython \u5305\u540d\nIntent intent = new Intent();\nintent.setClassName(extPlgPlusName, \"org.qpython.qpylib.MPyApi\");\nintent.setAction(extPlgPlusName + \".action.MPyApi\");\n\nBundle mBundle = new Bundle();\nmBundle.putString(\"app\", \"myappid\");\nmBundle.putString(\"act\", \"onPyApi\");\nmBundle.putString(\"flag\", \"onQPyExec\"); // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u4efb\u610f\u5b57\u7b26\u4e32\u6807\u5fd7\nmBundle.putString(\"param\", \"\");         // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u53c2\u6570\u5b57\u7b26\u4e32\n\n/*\n* \u6211\u4eec\u5c06\u8fd0\u884c\u7684 Python \u4ee3\u7801\n*/\nString code = \"import androidhelper\\n\" +\n            \"droid = androidhelper.Android()\\n\" +\n            \"line = droid.dialogGetInput()\\n\" +\n            \"s = 'Hello %s' % line.result\\n\" +\n            \"droid.makeToast(s)\\n\"\n\nmBundle.putString(\"pycode\", code);\nintent.putExtras(mBundle);\nstartActivityForResult(intent, SCRIPT_EXEC_PY);\n...\n\n// \u60a8\u53ef\u4ee5\u5728 onActivityResult \u4e2d\u5904\u7406 qpython \u8c03\u7528\u7ed3\u679c\n@Override\nprotected void onActivityResult(int requestCode, int resultCode, Intent data) {\n    if (requestCode == SCRIPT_EXEC_PY) {\n        if (data!=null) {\n            Bundle bundle = data.getExtras();\n            String flag = bundle.getString(\"flag\");\n            String param = bundle.getString(\"param\");\n            String result = bundle.getString(\"result\"); // \u60a8\u7684 Pycode \u751f\u6210\u7684\u7ed3\u679c\n            Toast.makeText(this, \"onQPyExec: return (\"+result+\")\", Toast.LENGTH_SHORT).show();\n        } else {\n            Toast.makeText(this, \"onQPyExec: data is null\", Toast.LENGTH_SHORT).show();\n\n        }\n    }\n}\n

    \u4ece github \u68c0\u51fa\u4e00\u4e2a\u5b8c\u6574\u9879\u76ee

    \u8fd8\u6709\u4e00\u4e2a\u751f\u4ea7\u5e94\u7528\u7a0b\u5e8f - \u9762\u5411 Tasker \u7684 QPython \u63d2\u4ef6

    "},{"location":"getting-started/","title":"QPython\uff1a\u5165\u95e8\u6307\u5357","text":"

    \u672c\u6307\u5357\u5c06\u4ecb\u7ecd QPython \u7684\u529f\u80fd\u5e76\u5e2e\u52a9\u60a8\u5feb\u901f\u5165\u95e8\u3002

    "},{"location":"getting-started/#qpython_1","title":"QPython \u6982\u8ff0","text":"

    \u4e3a\u4ec0\u4e48\u9009\u62e9 QPython\uff1f

    \u667a\u80fd\u624b\u673a\u5df2\u6210\u4e3a\u4eba\u4eec\u5fc5\u5907\u7684\u4fe1\u606f\u548c\u6280\u672f\u52a9\u624b\uff0c\u4e00\u4e2a\u7075\u6d3b\u7684\u89e3\u91ca\u5668\u5f15\u64ce\u53ef\u4ee5\u5e2e\u52a9\u60a8\u9ad8\u6548\u5b8c\u6210\u5927\u90e8\u5206\u5de5\u4f5c\uff0c\u65e0\u9700\u590d\u6742\u7684\u5f00\u53d1\u8fc7\u7a0b\u3002

    QPython \u63d0\u4f9b\u4e86 \u60ca\u4eba\u7684\u5f00\u53d1\u4f53\u9a8c\u2014\u2014\u501f\u52a9\u5b83\u7684\u5e2e\u52a9\uff0c\u60a8\u53ef\u4ee5\u8f7b\u677e\u5b9e\u73b0\u7a0b\u5e8f\uff0c\u65e0\u9700\u590d\u6742\u7684 IDE \u5b89\u88c5\u3001\u7f16\u8bd1\u6216\u6253\u5305\u8fc7\u7a0b\u3002

    "},{"location":"getting-started/#qpython_2","title":"QPython \u7248\u672c","text":"

    \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

    • QPython \u2013 \u7531 QPython \u56e2\u961f\u7ef4\u62a4\u7684\u4e3b\u8981\u7248\u672c\uff0c\u5177\u5907 AI \u529f\u80fd\uff0c\u53ef\u5728 Google Play \u7b49\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d
    • QPython+ \u2013 \u7531\u5f00\u6e90\u8d21\u732e\u8005\u63a8\u51fa\u7684\u793e\u533a\u7248\uff0c\u63d0\u4f9b\u5404\u79cd\u65b0\u7279\u6027
    • QPython Plus \u2013 \u6269\u5c55\u6743\u9650\u7248\u672c\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff09
    "},{"location":"getting-started/#_1","title":"\u4e3b\u8981\u7279\u6027","text":"
    • \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668 - \u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51
    • QSL4A \u96c6\u6210 - \u4f7f\u7528 Python \u63a7\u5236 Android \u786c\u4ef6\u548c API
    • GenAI \u80fd\u529b\u96c6\u6210 - \u652f\u6301\u672c\u5730\u8fd0\u884c\u7684 LLM\u3001OpenAI \u7b49\u5404\u79cd LLM \u5e93\uff0c\u4ee5\u53ca\u53ef\u5728 QPython \u4e0a\u8fdb\u884c Vibe Coding \u5f00\u53d1\u7684 AIPyApp
    • \u6269\u5c55\u5305\u5b89\u88c5 - \u652f\u6301\u901a\u8fc7 QPYPI \u548c pip \u5b89\u88c5\u6269\u5c55\u5305
    • \u5185\u7f6e\u7f16\u8f91\u5668 - \u8bed\u6cd5\u9ad8\u4eae\u548c\u4ee3\u7801\u7f16\u8f91
    • \u591a\u79cd\u8fd0\u884c\u6a21\u5f0f - \u9664\u63a7\u5236\u53f0\u7a0b\u5e8f\u5916\uff0c\u8fd8\u652f\u6301 Android \u539f\u751f UI\uff08\u901a\u8fc7 QSL4A \u63a5\u53e3\uff09\u4ee5\u53ca Pygame / Turtle / Tkinter \u7b49\u8fd0\u884c\u65b9\u5f0f
    "},{"location":"getting-started/#1","title":"1. \u4eea\u8868\u76d8","text":"

    \u5b89\u88c5 QPython \u540e\uff0c\u70b9\u51fb\u5176\u56fe\u6807\u542f\u52a8\u3002\u60a8\u5c06\u770b\u5230\u5e26\u6709 QPython \u6807\u5fd7\u548c\u4ee5\u4e0b\u529f\u80fd\u7684\u4e3b\u4eea\u8868\u76d8\uff1a

    "},{"location":"getting-started/#_2","title":"\u4eea\u8868\u76d8\u529f\u80fd","text":"

    QPython \u4eea\u8868\u76d8\u63d0\u4f9b\u5bf9\u6240\u6709\u4e3b\u8981\u529f\u80fd\u7684\u5feb\u901f\u8bbf\u95ee\uff1a

    • \u7ec8\u7aef \u2014 \u8bbf\u95ee Python \u63a7\u5236\u53f0\u548c shell \u4ee5\u76f4\u63a5\u6267\u884c\u547d\u4ee4
    • Notebook \u2014 \u7528\u4e8e\u6570\u636e\u5206\u6790\u548c\u5b9e\u9a8c\u7684\u4ea4\u4e92\u5f0f Jupyter \u98ce\u683c\u7b14\u8bb0\u672c
    • \u7f16\u8f91\u5668 \u2014 \u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668\uff0c\u5177\u6709\u8bed\u6cd5\u9ad8\u4eae\u529f\u80fd\uff0c\u7528\u4e8e\u7f16\u5199 Python \u811a\u672c
    • \u8d44\u6e90\u7ba1\u7406\u5668 \u2014 \u6d4f\u89c8\u548c\u7ba1\u7406\u60a8\u7684\u6587\u4ef6\u3001\u811a\u672c\u548c\u9879\u76ee
    • QPYPI \u2014 \u5b89\u88c5 Python \u5305\u548c\u6269\u5c55\u3002\u8be6\u89c1 QPYPI \u6307\u5357
    • \u8bbe\u7f6e \u2014 \u914d\u7f6e QPython \u9996\u9009\u9879\u548c\u8fd0\u884c\u9009\u9879
    • \u793e\u533a \u2014 \u8bbf\u95ee QPython \u793e\u533a\u8d44\u6e90\u3001\u8bba\u575b\u548c\u5e2e\u52a9
    • \u8bfe\u7a0b \u2014 \u8bbf\u95ee Python \u7f16\u7a0b\u7684\u5b66\u4e60\u6750\u6599\u548c\u6559\u7a0b

    \u70b9\u51fb\u4efb\u4f55\u56fe\u6807\u4ee5\u8bbf\u95ee\u76f8\u5e94\u7684\u529f\u80fd\u3002

    "},{"location":"getting-started/#2","title":"2. \u7ec8\u7aef\u548c\u7f16\u8f91\u5668","text":""},{"location":"getting-started/#_3","title":"\u7ec8\u7aef","text":"

    \u7ec8\u7aef\u63d0\u4f9b Python \u63a7\u5236\u53f0\uff0c\u652f\u6301\uff1a - \u63a2\u7d22\u5bf9\u8c61\u5c5e\u6027 - \u6d4b\u8bd5\u8bed\u6cd5\u548c\u60f3\u6cd5 - \u76f4\u63a5\u6267\u884c\u547d\u4ee4

    \u4f7f\u7528\u52a0\u53f7\u6309\u94ae\uff081\uff09\u6253\u5f00\u65b0\u7ec8\u7aef\u6807\u7b7e\u9875\uff0c\u901a\u8fc7\u4e0b\u62c9\u83dc\u5355\uff082\uff09\u5207\u6362\uff0c\u5e76\u4f7f\u7528\u5173\u95ed\u6309\u94ae\uff083\uff09\u5173\u95ed\u3002

    "},{"location":"getting-started/#_4","title":"\u7f16\u8f91\u5668","text":"

    \u7f16\u8f91\u5668\u5e95\u90e8\u529f\u80fd\u680f\u5305\u542b\u4ee5\u4e0b\u5de5\u5177\uff08\u4ece\u5de6\u5230\u53f3\uff09\uff1a

    • \u5207\u6362\u5feb\u6377\u8f93\u5165\uff08\u5305\u542b def / if / else / elif / class \u7b49\u5173\u952e\u8bcd\uff09
    • \u9501\u5b9a\uff08\u9632\u6b62\u8bef\u89e6\uff09
    • \u8df3\u8f6c
    • \u4fdd\u5b58
    • \u8fd0\u884c
    • \u641c\u7d22
    • \u64a4\u9500
    • \u91cd\u505a
    • \u53e6\u5b58
    • \u6700\u8fd1\u6587\u4ef6
    • \u4ee3\u7801\u7247\u6bb5

    \u91cd\u8981\u63d0\u793a\uff1a \u4fdd\u5b58\u65f6\u8bf7\u624b\u52a8\u6dfb\u52a0 .py \u6269\u5c55\u540d\uff0c\u56e0\u4e3a\u7f16\u8f91\u5668\u4e0d\u4f1a\u81ea\u52a8\u6dfb\u52a0\u3002

    "},{"location":"getting-started/#3","title":"3. \u8d44\u6e90\u7ba1\u7406\u5668\uff08\u6587\u4ef6\u7ba1\u7406\uff09","text":"

    \u901a\u8fc7 \u8d44\u6e90\u7ba1\u7406\u5668 \u8bbf\u95ee\u811a\u672c\u548c\u9879\u76ee\uff0c\u652f\u6301\u6d4f\u89c8\u3001\u7ec4\u7ec7\u548c\u7ba1\u7406\u6240\u6709 Python \u6587\u4ef6\u3002

    "},{"location":"getting-started/#_5","title":"\u811a\u672c","text":"

    \u811a\u672c\u662f\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/scripts3/ \u4e2d\u7684\u5355\u4e2a Python \u6587\u4ef6\uff08\u9488\u5bf9 Python 3\uff09\u3002

    \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u811a\u672c - \u6253\u5f00 \u2014 \u4f7f\u7528\u5185\u7f6e\u7f16\u8f91\u5668\u7f16\u8f91 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u811a\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u811a\u672c

    "},{"location":"getting-started/#_6","title":"\u9879\u76ee","text":"

    \u9879\u76ee\u662f\u5305\u542b main.py \u4f5c\u4e3a\u5165\u53e3\u70b9\u7684\u76ee\u5f55\u3002\u60a8\u53ef\u4ee5\u5728\u540c\u4e00\u76ee\u5f55\u4e2d\u5305\u542b\u5176\u4ed6\u4f9d\u8d56\u9879\u548c\u8d44\u6e90\u3002\u5c06\u9879\u76ee\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/projects3/ \u4e2d\u3002

    "},{"location":"getting-started/#_7","title":"\u7b14\u8bb0\u672c","text":"

    Jupyter \u98ce\u683c\u7684\u7b14\u8bb0\u672c\u4e5f\u901a\u8fc7\u8d44\u6e90\u7ba1\u7406\u5668\u8fdb\u884c\u7ba1\u7406\uff0c\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/notebooks/ \u4e2d\u3002

    \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u7b14\u8bb0\u672c - \u6253\u5f00 \u2014 \u63a2\u7d22\u7b14\u8bb0\u672c\u5185\u5bb9 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u7b14\u8bb0\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u7b14\u8bb0\u672c

    "},{"location":"getting-started/#4","title":"4. \u5e93","text":"

    \u901a\u8fc7\u5b89\u88c5\u7b2c\u4e09\u65b9\u5e93\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

    "},{"location":"getting-started/#_8","title":"\u5305\u5b89\u88c5\u65b9\u6cd5","text":"

    QPYPI\uff08\u63a8\u8350\uff09

    \u4ece QPYPI \u5b89\u88c5\u9884\u7f16\u8bd1\u7684\u5e93\uff0c\u5305\u62ec numpy\u3001scipy \u7b49\u79d1\u5b66\u5305\u3002

    \u8be6\u89c1 QPYPI \u6307\u5357\u3002

    PIP \u5ba2\u6237\u7aef

    \u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216 QPYPI \u754c\u9762\u5b89\u88c5\u7eaf Python \u5e93\uff1a

    pip install requests\n

    \u9884\u7f16\u8bd1\u5305

    \u5bf9\u4e8e\u5177\u6709 C/C++/Rust \u4f9d\u8d56\u7684\u5305\uff0c\u4f7f\u7528 QPython \u7684\u9884\u7f16\u8bd1\u5305\uff1a

    pip install numpy-qpython\npip install scipy-aipy\n

    \u8be6\u89c1 QPYPI \u6307\u5357 \u83b7\u53d6\u53ef\u7528\u5305\u7684\u5b8c\u6574\u5217\u8868\u3002

    \u624b\u52a8\u5b89\u88c5

    \u60a8\u4e5f\u53ef\u4ee5\u5c06\u5e93\u590d\u5236\u5230 /storage/emulated/0/Android/data/org.qpython.qpy/files/lib/python3.12/site-packages/\u3002

    "},{"location":"getting-started/#5","title":"5. \u8fd0\u884c\u6a21\u5f0f","text":"

    QPython \u652f\u6301\u591a\u79cd\u8fd0\u884c\u6a21\u5f0f\u4ee5\u6ee1\u8db3\u4e0d\u540c\u7684\u7528\u4f8b\uff1a

    "},{"location":"getting-started/#_9","title":"\u63a7\u5236\u53f0\u6a21\u5f0f","text":"

    \u5e38\u89c4 Python \u811a\u672c\u7684\u9ed8\u8ba4\u6a21\u5f0f\u3002

    "},{"location":"getting-started/#qsl4a","title":"QSL4A \u6a21\u5f0f","text":"

    \u901a\u8fc7 QSL4A \u5e93\u8c03\u7528 Android API \u7684\u811a\u672c\u3002

    import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello Android!')\n

    \u8be6\u89c1 QSL4A \u6587\u6863 \u83b7\u53d6\u5b8c\u6574\u7684 API \u53c2\u8003\u3002

    "},{"location":"getting-started/#webapp","title":"WebApp \u6a21\u5f0f","text":"

    \u4f7f\u7528\u540e\u7aef\u670d\u52a1\u5668\u521b\u5efa\u57fa\u4e8e Web \u7684\u5e94\u7528\u7a0b\u5e8f\u3002\u9700\u5728\u811a\u672c\u5f00\u5934\u6dfb\u52a0\u4ee5\u4e0b\u4e24\u884c headers\uff1a

    #qpy:webapp:<\u9879\u76ee\u540d>\n#qpy://localhost:<web\u670d\u52a1\u4fa6\u542c\u7684\u7aef\u53e3>/<\u9ed8\u8ba4\u4e3b\u8def\u5f84>\n

    \u4f8b\u5982\uff1a

    #qpy:webapp:Hello QPython\n#qpy://localhost:8080/hello\n\nfrom bottle import route, run, Bottle\n\napp = Bottle()\n\n@route('/hello')\ndef hello():\n    return '<h1>Hello from QPython!</h1>'\n\nrun(app, host='localhost', port=8080)\n
    "},{"location":"getting-started/#q","title":"Q \u6a21\u5f0f\uff08\u65e0\u63a7\u5236\u53f0\u6a21\u5f0f\uff09","text":"

    \u9759\u9ed8\u6a21\u5f0f\u8fd0\u884c\u811a\u672c\uff0c\u4e0d\u663e\u793a\u63a7\u5236\u53f0\u3002\u9700\u5728\u811a\u672c\u5f00\u5934\u6dfb\u52a0 header\uff1a

    #qpy:quiet\n\nimport time\n\nwhile True:\n    # \u60a8\u7684\u540e\u53f0\u4efb\u52a1\n    time.sleep(60)\n
    \u5982\u679c\u9700\u8981\u8fd0\u884c\u5e26 GUI \u7684 QSL4A \u7a0b\u5e8f\u4e14\u4e0d\u5e0c\u671b\u663e\u793a\u63a7\u5236\u53f0\u4fe1\u606f\uff0c\u63a8\u8350\u4f7f\u7528\u6b64\u6a21\u5f0f\u3002

    "},{"location":"getting-started/#6","title":"6. \u793e\u533a\u4e0e\u652f\u6301","text":"

    \u8bbf\u95ee QPython.org \u83b7\u53d6\u6587\u6863\u3001\u7528\u6237\u793e\u533a\u53ca\u5e2e\u52a9\u95ee\u7b54\u3002

    \u793e\u533a\u94fe\u63a5\uff1a - Facebook \u7fa4\u7ec4 - GitHub - \u95ee\u9898\u53cd\u9988

    \u4e0b\u4e00\u6b65\uff1a - \u5c1d\u8bd5 Hello World \u6559\u7a0b - \u63a2\u7d22 QSL4A API \u4ee5\u96c6\u6210 Android - \u4e86\u89e3 QPython \u7248\u672c

    "},{"location":"getting-started/#_10","title":"\u89c6\u9891\u4ecb\u7ecd","text":""},{"location":"getting-started/#_11","title":"\u4e0b\u4e00\u6b65","text":"

    \u5982\u679c\u60a8\u5df2\u7ecf\u521d\u6b65\u4e86\u89e3\u4e86 QPython \u7684\u529f\u80fd\uff0c\u6b22\u8fce\u5f00\u59cb\u4f53\u9a8c\u7f16\u7a0b\u7684\u4e50\u8da3\uff01\u8bd5\u8bd5 Hello World \u6559\u7a0b \u8fc8\u51fa\u60a8\u7684\u7b2c\u4e00\u6b65\u3002

    "},{"location":"qpypi-guide/","title":"QPYPI","text":"

    \u60a8\u53ef\u4ee5\u901a\u8fc7\u5b89\u88c5\u5305\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

    "},{"location":"qpypi-guide/#_1","title":"\u5305\u5b89\u88c5\u652f\u6301","text":""},{"location":"qpypi-guide/#python","title":"\u7eaf Python \u5305","text":"

    QPython \u652f\u6301\u4f7f\u7528\u7eaf Python \u5f00\u53d1\u7684 Python \u5305\u3002\u60a8\u53ef\u4ee5\u76f4\u63a5\u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216\u4eea\u8868\u76d8\u4e0a\u7684 QPYPI \u4f7f\u7528 pip install \u5b89\u88c5\u8fd9\u4e9b\u5305\u3002

    "},{"location":"qpypi-guide/#_2","title":"\u9884\u7f16\u8bd1\u5305","text":"

    \u5982\u679c\u67d0\u4e9b\u5305\uff08\u6216\u5b83\u4eec\u7684\u4f9d\u8d56\uff09\u662f\u7528 Rust/C/C++ \u5f00\u53d1\u7684\uff0cQPython \u65e0\u6cd5\u76f4\u63a5\u652f\u6301\u5b83\u4eec\uff0c\u56e0\u4e3a QPython \u4e0a\u6ca1\u6709\u7f16\u8bd1\u5668\u5de5\u5177\u94fe\u652f\u6301\u3002\u4f46\u662f\uff0cQPython \u56e2\u961f\u5df2\u7ecf\u9884\u7f16\u8bd1\u4e86\u4e00\u4e9b\u5e38\u7528\u5305\uff0c\u5e76\u5728 QPython \u7684 QPYPI/Extensions \u4e2d\u53d1\u5e03\uff0c\u4f9b\u7528\u6237\u8f7b\u677e\u5b89\u88c5\u3002

    "},{"location":"qpypi-guide/#_3","title":"\u5b89\u88c5\u9884\u7f16\u8bd1\u5305","text":"

    \u60a8\u53ef\u4ee5\u901a\u8fc7\u4ee5\u4e0b\u65b9\u5f0f\u5b89\u88c5\u9884\u7f16\u8bd1\u5305\uff1a

    1. \u901a\u8fc7 QPython \u5e94\u7528\uff1a\u76f4\u63a5\u4ece QPython \u5e94\u7528\u5185\u7684 QPYPI \u6216 Extensions \u5b89\u88c5
    2. \u901a\u8fc7 PyPI\uff1a\u8bbf\u95ee https://pypi.org/user/qpythonx/ \u67e5\u770b\u53ef\u7528\u7684\u5305
    3. \u901a\u8fc7 pip \u547d\u4ee4\uff1a
    4. pip install xxx-qpython - \u5e26 -qpython \u540e\u7f00\u7684\u5305
    5. pip install xxx-aipy - \u5e26 -aipy \u540e\u7f00\u7684\u5305\uff08\u901a\u5e38\u662f AI/ML \u76f8\u5173\u7684\u5305\uff09

    \u6ce8\u610f\uff1a\u6211\u4eec\u901a\u5e38\u6839\u636e\u5305\u7684\u9884\u671f\u7528\u9014\u6dfb\u52a0\u8fd9\u4e9b\u540e\u7f00\u4e4b\u4e00\u3002

    "},{"location":"qpypi-guide/#_4","title":"\u8bf7\u6c42\u65b0\u5305","text":"

    \u5982\u679c\u60a8\u9700\u8981\u5f53\u524d\u4e0d\u652f\u6301\u7684\u5305\uff1a

    • \u5728 qpython.org \u9879\u76ee \u4e2d\u63d0\u51fa\u95ee\u9898
    • QPython \u56e2\u961f\u5c06\u8003\u8651\u9884\u7f16\u8bd1\u5e76\u5c06\u5176\u6dfb\u52a0\u5230\u4ed3\u5e93\u4e2d

    \u83b7\u53d6\u66f4\u591a\u5e2e\u52a9\u548c\u53c2\u4e0e\u793e\u533a\u7684\u65b9\u5f0f\uff0c\u8bf7\u53c2\u9605 \u793e\u533a\u4e0e\u53cd\u9988 \u90e8\u5206\u3002

    \u6ce8\u610f\uff1a\u7531\u4e8e\u4e0d\u540c\u7684\u8ba1\u7b97\u673a\u67b6\u6784\uff0c\u6211\u4eec\u65e0\u6cd5\u4fdd\u8bc1 QPYPI \u5305\u542b PyPI \u4e0a\u7684\u6240\u6709\u5305\u3002

    "},{"location":"qpython-x/","title":"QPython \u7248\u672c","text":"

    QPython \u662f Android \u7684 Python \u5f15\u64ce\u3002\u5b83\u5305\u542b\u4ee4\u4eba\u60ca\u53f9\u7684\u529f\u80fd\uff0c\u5982 Python \u89e3\u91ca\u5668\u3001\u8fd0\u884c\u73af\u5883\u3001\u7f16\u8f91\u5668\u3001QPYI \u548c\u96c6\u6210\u7684 SL4A\u3002\u5b83\u8ba9\u60a8\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 Android \u4e0a\u4f7f\u7528 Python\u3002\u800c\u4e14\u5b83\u662f\u514d\u8d39\u7684\u3002

    QPython \u5df2\u7ecf\u5728\u5168\u7403\u62e5\u6709\u6570\u767e\u4e07\u7528\u6237\uff0c\u4e5f\u662f\u4e00\u4e2a\u5f00\u6e90\u9879\u76ee\u3002

    \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

    "},{"location":"qpython-x/#qpython_1","title":"QPython","text":"

    \u6807\u51c6\u7248\uff1a\u9488\u5bf9 AI \u6027\u80fd\u548c\u901a\u7528\u5e94\u7528\u5546\u5e97\u517c\u5bb9\u6027\u4f18\u5316

    \u4e3b\u8981\u7248\u672c\uff0c\u53ef\u5728 Google Play \u548c\u5176\u4ed6\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002\u6b64\u7248\u672c\u4e13\u6ce8\u4e8e AI \u529f\u80fd\uff0c\u4f7f AI \u65f6\u4ee3\u7528\u6237\u66f4\u5bb9\u6613\u5b66\u4e60\u548c\u4f7f\u7528 Python\u3002

    \u4e3b\u8981\u7279\u6027\uff1a - AI \u9a71\u52a8\u7684\u7f16\u7801\u8f85\u52a9\u548c\u5b66\u4e60\u5de5\u5177 - \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668\uff1a\u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51 - \u652f\u6301\u591a\u79cd\u9879\u76ee\u7c7b\u578b\uff1a\u63a7\u5236\u53f0\u3001SL4A\u3001WebApp - \u65b9\u4fbf\u7684\u4e8c\u7ef4\u7801\u8bfb\u53d6\u5668\uff0c\u7528\u4e8e\u5c06\u4ee3\u7801\u4f20\u8f93\u5230\u624b\u673a - QPYPI \u548c\u81ea\u5b9a\u4e49\u4ed3\u5e93\uff0c\u7528\u4e8e\u9884\u7f16\u8bd1 wheel \u5305 -\u6613\u4e8e\u4f7f\u7528\u7684\u8bed\u6cd5\u9ad8\u4eae\u7f16\u8f91\u5668 - \u5b8c\u5584\u7684\u6587\u6863\u548c\u793e\u533a\u652f\u6301

    \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

    \u4e0b\u8f7d\uff1a \u53ef\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

    "},{"location":"qpython-x/#qpython_2","title":"QPython+","text":"

    \u793e\u533a\u7248\uff1a\u516c\u5f00\u652f\u6301\u5404\u79cd\u793e\u533a\u9a71\u52a8\u7684\u529f\u80fd\uff1b\u53ef\u5728\u90e8\u5206\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

    \u793e\u533a\u5f00\u6e90\u7248\u672c\uff08\u6b63\u5728\u89c4\u5212\u548c\u51c6\u5907\u4e2d\uff09\u3002\u6b64\u7248\u672c\u4e13\u4e3a\u60f3\u8981\u53c2\u4e0e QPython \u9879\u76ee\u5f00\u53d1\u7684\u8d21\u732e\u8005\u800c\u8bbe\u8ba1\uff0c\u652f\u6301\u9488\u5bf9\u4e0d\u540c\u5236\u9020\u5546\u7684\u5b9a\u5236\u3002

    \u4e3b\u8981\u7279\u6027\uff1a - \u793e\u533a\u9a71\u52a8\u5f00\u53d1 - \u652f\u6301\u4f9b\u5e94\u5546\u5b9a\u5236 - \u66f4\u7075\u6d3b\u7684\u914d\u7f6e\u9009\u9879 - \u5f00\u653e\u4f9b\u8d21\u732e\u8005\u52a0\u5165\u5f00\u53d1

    \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

    \u4e0b\u8f7d\uff1a \u5c06\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

    \u6ce8\u610f\uff1a \u6b64\u7248\u672c\u76ee\u524d\u6b63\u5728\u89c4\u5212\u51c6\u5907\u4e2d\u3002\u8bf7\u5173\u6ce8\u66f4\u65b0\uff01

    "},{"location":"qpython-x/#qpython-plus","title":"QPython Plus","text":"

    QPython+ \u5b8c\u5168\u8bbf\u95ee\u7248\uff1a\u6388\u4e88\u8c03\u7528\u6240\u6709 Android \u63a5\u53e3\u7684\u5b8c\u6574\u6743\u9650\u3002\u4e0b\u8f7d\u94fe\u63a5\u4ec5\u901a\u8fc7\u5b98\u65b9\u4e91\u76d8\u63d0\u4f9b\u3002

    \u5177\u6709\u6269\u5c55\u6743\u9650\u7684\u7279\u6b8a\u7248\u672c\uff0c\u63d0\u4f9b\u5bf9\u8bbe\u5907\u7684\u6700\u5927\u63a7\u5236\u3002\u7531\u4e8e\u5176\u654f\u611f\u7684\u6743\u9650\u8981\u6c42\uff0c\u6b64\u7248\u672c\u4e0d\u4f1a\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u53d1\u5e03\u3002

    \u4e3b\u8981\u7279\u6027\uff1a - \u5b8c\u6574\u7684 SL4A API \u8bbf\u95ee\uff0c\u5305\u62ec\u654f\u611f\u529f\u80fd - SMS/\u901a\u8bdd\u63a7\u5236 API - \u9ad8\u7ea7\u7cfb\u7edf\u96c6\u6210 - \u6700\u5927\u7684\u8bbe\u5907\u63a7\u5236\u80fd\u529b

    \u6743\u9650\uff1a \u9700\u8981\u5e7f\u6cdb\u7684\u6743\u9650\uff0c\u5305\u62ec\uff1a - \u84dd\u7259 - \u4f4d\u7f6e\uff08GPS\uff09 - \u8bfb\u53d6/\u53d1\u9001\u77ed\u4fe1 - \u6253\u7535\u8bdd - \u76f8\u673a\u548c\u9ea6\u514b\u98ce - \u7cfb\u7edf\u8bbe\u7f6e - \u4ee5\u53ca\u5176\u4ed6\u654f\u611f\u6743\u9650

    \u4e0b\u8f7d\uff1a \u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\u3002\u4ec5\u901a\u8fc7\u7279\u6b8a\u6e20\u9053\u5206\u53d1\u3002

    \u91cd\u8981\u63d0\u793a\uff1a QPython \u4e0d\u4f1a\u5728\u540e\u53f0\u672a\u7ecf\u60a8\u77e5\u6089\u4f7f\u7528\u8fd9\u4e9b\u6743\u9650\u3002\u5982\u679c\u4f7f\u7528 SL4A API \u65f6\u51fa\u73b0\u5f02\u5e38\uff0c\u8bf7\u68c0\u67e5\u7cfb\u7edf\u8bbe\u7f6e\u4e2d\u662f\u5426\u5df2\u542f\u7528\u76f8\u5173\u6743\u9650\u3002

    "},{"location":"tutorial-hello-world/","title":"\u7f16\u5199\"Hello World\"","text":""},{"location":"tutorial-hello-world/#hello-world_1","title":"Hello world","text":"

    \u597d\u7684\uff0c\u5728\u60a8\u5bf9 QPython \u6709\u4e86\u4e00\u5b9a\u7684\u4e86\u89e3\u4e4b\u540e\uff0c\u8ba9\u6211\u4eec\u5728 QPython \u4e2d\u521b\u5efa\u6211\u4eec\u7684\u7b2c\u4e00\u4e2a\u7a0b\u5e8f\u3002\u663e\u7136\uff0c\u5b83\u5c06\u662f helloworld.py\u3002;)

    \u542f\u52a8 QPython\uff0c\u6253\u5f00\u7f16\u8f91\u5668\u5e76\u8f93\u5165\u4ee5\u4e0b\u4ee3\u7801\uff1a

    #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello, QPYTHON!')\n

    \u6beb\u65e0\u7591\u95ee\uff0c\u5b83\u4e0e\u5176\u4ed6\u4efb\u4f55 hello-world \u7a0b\u5e8f\u5e76\u65e0\u4e0d\u540c\u3002\u6267\u884c\u65f6\uff0c\u5b83\u53ea\u662f\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u5f39\u51fa\u6d88\u606f\uff08\u89c1\u9876\u90e8\u622a\u56fe\uff09\u3002\u65e0\u8bba\u5982\u4f55\uff0c\u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684 QPython \u7a0b\u5e8f\u793a\u4f8b\u3002

    "},{"location":"tutorial-hello-world/#_1","title":"\u4ee3\u7801\u7406\u89e3","text":"

    \u5b83\u4ee5 import androidhelper \u5f00\u5934\u2014\u2014\u8fd9\u662f QPython \u4e2d\u6700\u6709\u7528\u7684\u6a21\u5757\uff0c\u5b83\u5c01\u88c5\u4e86 Python \u4e2d\u53ef\u7528\u7684\u51e0\u4e4e\u6240\u6709\u4e0e Android \u7684\u63a5\u53e3\u3002\u4efb\u4f55\u5728 QPython \u4e2d\u5f00\u53d1\u7684\u811a\u672c\u90fd\u4ee5\u8fd9\u4e2a\u8bed\u53e5\u5f00\u5934\uff08\u81f3\u5c11\u5982\u679c\u5b83\u58f0\u79f0\u8981\u4e0e\u7528\u6237\u901a\u4fe1\u7684\u8bdd\uff09\u3002\u5728\u6b64\u5904\u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u5e93 \u548c import \u8bed\u53e5 \u7684\u5185\u5bb9\u3002

    \u63a5\u4e0b\u6765\u6211\u4eec\u521b\u5efa\u4e00\u4e2a droid \u5bf9\u8c61\uff08\u5b9e\u9645\u4e0a\u662f\u4e00\u4e2a\u7c7b\uff09\uff0c\u5b83\u5bf9\u4e8e\u8c03\u7528 RPC \u51fd\u6570\u4ee5\u4e0e Android \u901a\u4fe1\u662f\u5fc5\u8981\u7684\u3002

    \u6211\u4eec\u4ee3\u7801\u7684\u6700\u540e\u4e00\u884c\u8c03\u7528\u4e86\u8fd9\u6837\u7684\u51fd\u6570\uff0cdroid.makeToast()\uff0c\u5b83\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u4e00\u4e2a\u5c0f\u7684\u5f39\u51fa\u6d88\u606f\uff08\"toast\"\uff09\u3002

    \u597d\u7684\uff0c\u8ba9\u6211\u4eec\u6dfb\u52a0\u4e00\u4e9b\u66f4\u591a\u7684\u529f\u80fd\u3002\u8ba9\u5b83\u8be2\u95ee\u7528\u6237\u540d\u5e76\u5411\u7528\u6237\u6253\u62db\u547c\u3002

    "},{"location":"tutorial-hello-world/#_2","title":"\u66f4\u591a\u793a\u4f8b","text":"

    \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 dialogGetInput \u8c03\u7528\u663e\u793a\u4e00\u4e2a\u5e26\u6709\u6807\u9898\u3001\u63d0\u793a\u3001\u7f16\u8f91\u5b57\u6bb5\u548c \u786e\u5b9a \u548c \u53d6\u6d88 \u6309\u94ae\u7684\u7b80\u5355\u5bf9\u8bdd\u6846\u3002\u7528\u4ee5\u4e0b\u4ee3\u7801\u66ff\u6362\u60a8\u7684\u6700\u540e\u4e00\u884c\u4ee3\u7801\u5e76\u5c06\u5176\u4fdd\u5b58\u4e3a hello1.py\uff1a

    #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\n

    \u597d\u7684\uff0c\u6211\u8ba4\u4e3a\u5b83\u5e94\u8be5\u8fd4\u56de\u4efb\u4f55\u54cd\u5e94\uff0c\u4efb\u4f55\u7528\u6237\u53cd\u5e94\u3002\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u6211\u5199 respond = ...\u3002\u4f46\u8fd9\u4e2a\u8c03\u7528\u5b9e\u9645\u4e0a\u8fd4\u56de\u4ec0\u4e48\uff1f\u8ba9\u6211\u4eec\u68c0\u67e5\u4e00\u4e0b\u3002\u53ea\u9700\u5728\u6700\u540e\u4e00\u884c\u540e\u6dfb\u52a0 print \u8bed\u53e5\uff1a

    #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\n

    \u7136\u540e\u4fdd\u5b58\u5e76\u8fd0\u884c\u5b83...

    \u54ce\u5440\uff01\u6ca1\u6709\u6253\u5370\uff1f\u522b\u62c5\u5fc3\u3002\u53ea\u9700\u62c9\u4e0b\u901a\u77e5\u680f\uff0c\u60a8\u5c31\u4f1a\u770b\u5230\"QPython Program Output: hello1.py\"\u2014\u2014\u70b9\u51fb\u5b83\uff01

    \u5982\u60a8\u6240\u89c1\uff0cdroid.dialogGetInput() \u8fd4\u56de\u4e00\u4e2a\u5305\u542b\u4e09\u4e2a\u5b57\u6bb5\u7684 JSON \u5bf9\u8c61\u3002\u6211\u4eec\u53ea\u9700\u8981\u4e00\u4e2a\u2014\u2014result\uff0c\u5176\u4e2d\u5305\u542b\u7528\u6237\u5b9e\u9645\u8f93\u5165\u7684\u5185\u5bb9\u3002

    \u8ba9\u6211\u4eec\u6dfb\u52a0\u811a\u672c\u7684\u53cd\u5e94\uff1a

    #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nmessage = f'Hello, {respond.result}!'\ndroid.makeToast(message)\n

    \u6700\u540e\u4e24\u884c\uff081\uff09\u683c\u5f0f\u5316\u6d88\u606f\uff0c\uff082\uff09\u4ee5 toast \u5f62\u5f0f\u5411\u7528\u6237\u663e\u793a\u6d88\u606f\u3002\u5982\u679c\u60a8\u4ecd\u7136\u4e0d\u77e5\u9053 f-string \u662f\u4ec0\u4e48\u610f\u601d\uff0c\u8bf7\u53c2\u9605 Python \u6587\u6863\u3002

    \u54c7\uff01\u5b83\u5de5\u4f5c\u4e86\uff01;)

    \u73b0\u5728\u6211\u8981\u5728\u90a3\u91cc\u6dfb\u52a0\u4e00\u4e9b\u903b\u8f91\u3002\u60f3\u4e00\u60f3\uff1a\u5982\u679c\u7528\u6237\u70b9\u51fb \u53d6\u6d88 \u6309\u94ae\uff0c\u6216\u8005\u70b9\u51fb \u786e\u5b9a \u4f46\u5c06\u8f93\u5165\u5b57\u6bb5\u7559\u7a7a\uff0c\u4f1a\u53d1\u751f\u4ec0\u4e48\uff1f

    \u60a8\u53ef\u4ee5\u73a9\u8fd9\u4e2a\u7a0b\u5e8f\uff0c\u68c0\u67e5 respond \u53d8\u91cf\u5728\u6bcf\u79cd\u60c5\u51b5\u4e0b\u5305\u542b\u4ec0\u4e48\u3002

    \u9996\u5148\uff0c\u6211\u60f3\u5c06\u7528\u6237\u8f93\u5165\u7684\u6587\u672c\u653e\u5165\u4e00\u4e2a\u5355\u72ec\u7684\u53d8\u91cf\u4e2d\uff1aname = respond.result\u3002\u7136\u540e\u6211\u68c0\u67e5\u5b83\uff0c\u5982\u679c\u5b83\u5305\u542b\u4efb\u4f55\u771f\u5b9e\u6587\u672c\uff0c\u5b83\u5c06\u88ab\u89c6\u4e3a\u540d\u79f0\u5e76\u7528\u4e8e\u95ee\u5019\u3002\u5426\u5219\uff0c\u5c06\u663e\u793a\u53e6\u4e00\u6761\u6d88\u606f\u3002\u5c06\u7b2c\u4e94\u884c message = f'Hello, {respond.result}!' \u66ff\u6362\u4e3a\u4ee5\u4e0b\u4ee3\u7801\uff1a

    name = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\n

    \u4f7f\u7528\u5de5\u5177\u680f\u4e0a\u7684 < \u548c > \u6309\u94ae\u6765\u7f29\u8fdb/\u53d6\u6d88\u7f29\u8fdb if \u8bed\u53e5\u4e2d\u7684\u884c\uff08\u6216\u8005\u53ea\u9700\u4f7f\u7528\u7a7a\u683c/\u9000\u683c\u952e\uff09\u3002\u60a8\u53ef\u4ee5\u5728 \u6b64\u5904 \u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u7f29\u8fdb\u7684\u5185\u5bb9\uff1bif \u8bed\u53e5\u5728 \u6b64\u5904 \u63cf\u8ff0\u3002

    \u9996\u5148\uff0c\u6211\u4eec\u5c06\u7528\u6237\u8f93\u5165\u653e\u5165 name \u53d8\u91cf\u3002\u7136\u540e\u6211\u4eec\u68c0\u67e5 name \u662f\u5426\u5305\u542b\u4efb\u4f55\u5185\u5bb9\uff1f\u5982\u679c\u7528\u6237\u7559\u7a7a\u884c\u5e76\u70b9\u51fb \u786e\u5b9a\uff0c\u8fd4\u56de\u503c\u662f\u7a7a\u5b57\u7b26\u4e32 ''\u3002\u5982\u679c\u6309\u4e0b\u4e86 \u53d6\u6d88 \u6309\u94ae\uff0c\u8fd4\u56de\u503c\u662f None\u3002\u5728 if \u8bed\u53e5\u4e2d\uff0c\u4e24\u8005\u90fd\u88ab\u89c6\u4e3a\u5047\u3002\u56e0\u6b64\uff0c\u53ea\u6709\u5f53 name \u5305\u542b\u4efb\u4f55\u6709\u610f\u4e49\u7684\u5185\u5bb9\u65f6\uff0cthen \u8bed\u53e5\u624d\u4f1a\u6267\u884c\uff0c\u5e76\u663e\u793a\u95ee\u5019\u8bed\"Hello, ...!\"\u3002\u5982\u679c\u8f93\u5165\u4e3a\u7a7a\uff0c\u7528\u6237\u5c06\u770b\u5230\"Hey! And you're not very polite, %Username%!\"\u6d88\u606f\u3002

    \u597d\u7684\uff0c\u8fd9\u662f\u6574\u4e2a\u7a0b\u5e8f\uff1a

    #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nname = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\ndroid.makeToast(message)\n

    \u8fd0\u884c\u6548\u679c\uff1a

    "},{"location":"whats-new/","title":"\u66f4\u65b0\u65e5\u5fd7","text":""},{"location":"whats-new/#v392-v393","title":"v3.9.2 / v3.9.3","text":"
    • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
    • \u7f16\u8f91\u5668\u91cd\u5927\u66f4\u65b0\uff0c\u5e26\u6765\u66f4\u6d41\u7545\u7684\u7f16\u8f91\u4f53\u9a8c
    • \u5176\u4ed6\u5404\u79cd\u5c0f\u6539\u8fdb
    "},{"location":"whats-new/#v391","title":"v3.9.1","text":"
    • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
    • \u6269\u5c55\u5305\u73b0\u5728\u652f\u6301 MCP
    • \u9519\u8bef\u4fee\u590d
    "},{"location":"whats-new/#v390","title":"v3.9.0","text":"
    • SDK \u5347\u7ea7\uff0c\u6574\u5408\u6700\u65b0\u7684 Android \u529f\u80fd
    • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
    • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
    • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
    "},{"location":"whats-new/#v3811","title":"v3.8.11","text":"
    • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
    • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
    • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
    "},{"location":"whats-new/#v3810","title":"v3.8.10","text":"
    • \u5185\u7f6e Ollama \u5347\u7ea7\uff1a\u73b0\u5728\u60a8\u53ef\u4ee5\u5728 QPython \u4e2d\u8f7b\u677e\u672c\u5730\u8fd0\u884c Qwen3 / Gemma3 \u6a21\u578b\uff01
    • \u6dfb\u52a0\u4e86\u5f3a\u5927\u7684 MCP \u5e93\uff1a\u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 mcp \u5e93\uff0c\u8ba9\u60a8\u968f\u65f6\u968f\u5730\u643a\u5e26\u5f3a\u5927\u7684 MCP \u529f\u80fd\uff01
    "},{"location":"whats-new/#v389","title":"v3.8.9","text":"

    \u91cd\u5927\u66f4\u65b0\uff01AI \u7f16\u7a0b\u5b8c\u5168\u96c6\u6210\u5230 QPython\uff0c\u8ba9\u60a8\u7684\u7f16\u7a0b\u66f4\u8f7b\u677e\uff01

    • \u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u652f\u6301\uff1a\u65b0\u652f\u6301 AIPyApp\uff0c\u5728 QPython \u4e2d\u5b9e\u73b0\u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u3002\u76ee\u524d\u5904\u4e8e\u6d4b\u8bd5\u9636\u6bb5 - \u52a0\u5165\u6211\u4eec\u7684\u793e\u533a\u83b7\u53d6\u4f7f\u7528\u8bf4\u660e
    • \u65b0 QSL4A \u529f\u80fd\uff1a\u6dfb\u52a0 notebookOpen \u51fd\u6570\uff0c\u652f\u6301\u81ea\u7136\u8bed\u8a00\u63a7\u5236\u6253\u5f00 Notebook \u6587\u4ef6
    • \u5185\u7f6e\u7f16\u8f91\u5668\u5347\u7ea7\uff1a\u589e\u5f3a\u7f16\u8f91\u5668\u529f\u80fd\uff0c\u652f\u6301\u6253\u5f00\u548c\u6d4f\u89c8\u5404\u79cd\u6587\u672c\u6587\u4ef6
    • \u4fbf\u6377\u7684\u6587\u4ef6\u7ba1\u7406\uff1a\u5728\u6587\u4ef6\u7ba1\u7406\u5668\u4e2d\u6dfb\u52a0\u5185\u90e8\u5b58\u50a8\u5165\u53e3\uff0c\u5feb\u901f\u8bbf\u95ee\u60a8\u7684\u6587\u4ef6
    "},{"location":"whats-new/#v388","title":"v3.8.8","text":"
    • \u6587\u4ef6\u8bbf\u95ee\u6743\u9650\u63a7\u5236\u7684\u91cd\u8981\u6539\u8fdb\uff0c\u5141\u8bb8\u7528\u6237\u7075\u6d3b\u5730\u901a\u8fc7 QPython \u7f16\u7a0b\u542f\u7528\u6216\u7981\u7528\u5916\u90e8\u5b58\u50a8\u6587\u4ef6\u7684\u8bbf\u95ee
    • SDK \u5347\u7ea7\uff0c\u589e\u5f3a\u4e86\u5bf9\u65b0\u7248 Android \u7684\u652f\u6301\u548c\u517c\u5bb9\u6027
    • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Anthropic \u548c Google GenAI \u5e93
    "},{"location":"whats-new/#v387","title":"v3.8.7","text":"
    • \u5728\u73b0\u6709 Tkinter \u652f\u6301\u57fa\u7840\u4e0a\uff0c\u5728 Extensions -> Tools \u4e2d\u6dfb\u52a0\u4e86\u4f7f\u7528 Turtle \u7ed8\u5236\u54c6\u5566A\u68a6\u7684\u793a\u4f8b\u4ee3\u7801
    • \u4f18\u5316\u4e86\u624b\u673a\u6743\u9650\u83b7\u53d6\u6d41\u7a0b\uff0c\u63d0\u5347\u7528\u6237\u4f53\u9a8c\u548c\u64cd\u4f5c\u4fbf\u5229\u6027
    • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Google Gen AI \u5e93\uff0c\u65b9\u4fbf\u8bbf\u95ee Gemini Developer API \u548c Vertex AI
    "},{"location":"whats-new/#v386","title":"v3.8.6","text":"
    • Tkinter \u652f\u6301\uff1a\u73b0\u5728\u652f\u6301 Tkinter \u5e93\uff0c\u53ef\u901a\u8fc7 XServer \u8bbf\u95ee\u3002\u8bf7\u8bbf\u95ee www.qpython.org \u7684\u4e91\u76d8\"Extra\"\u94fe\u63a5\u4e0b\u8f7d\u6240\u9700\u6587\u4ef6
    • \u5b58\u50a8\u6743\u9650\u66f4\u65b0\uff1a\u4e3a\u6539\u5584\u7528\u6237\u4f53\u9a8c\uff0c\u6211\u4eec\u6dfb\u52a0\u4e86\u8bfb\u53d6\u624b\u673a\u5b58\u50a8\u7684\u6743\u9650\uff0c\u7528\u4e8e\u8bbf\u95ee\u5b58\u50a8\u5728\u5176\u4ed6\u76ee\u5f55\u4e2d\u7684 Python \u7a0b\u5e8f

    \u6b64\u66f4\u65b0\u540e\uff0cQPython \u548c QPythonPlus\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff0c\u4e13\u4e3a\u9700\u8981\u66f4\u591a\u654f\u611f\u6743\u9650\u7684\u9ad8\u7ea7\u7528\u6237\u8bbe\u8ba1\uff09\u5c06\u4fdd\u6301\u540c\u6b65\u7684\u7248\u672c\u53f7\u3002

    "},{"location":"whats-new/#v352-2025225","title":"v3.5.2 (2025/2/25)","text":"

    \u4e0e\u5f00\u6e90 LLM \u90e8\u7f72\u5de5\u5177 Ollama \u4ee5\u53ca DeepSeek \u5f00\u53d1\u7684 DeepSeek \u5b9e\u73b0\u65e0\u7f1d\u96c6\u6210\uff01

    \u529f\u80fd\uff1a - \u96f6\u95e8\u69db\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5404\u79cd\u5927\u578b\u8bed\u8a00\u6a21\u578b - \u5feb\u901f\u90e8\u7f72 DeepSeek \u7b49\u5c16\u7aef AI \u6a21\u578b - \u4eab\u53d7\u7b80\u7ea6\u7684 API \u8c03\u7528\u4f53\u9a8c - \u6784\u5efa\u5b8c\u5168\u79bb\u7ebf\u7684\u667a\u80fd\u7f16\u7a0b\u73af\u5883

    \u80fd\u529b\uff1a - \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u52a0\u8f7d/\u7ba1\u7406 LLM \u6a21\u578b - \u57fa\u4e8e\u672c\u5730\u8ba1\u7b97\u7684\u5b9e\u65f6\u4f4e\u5ef6\u8fdf\u54cd\u5e94

    "},{"location":"whats-new/#v350","title":"v3.5.0","text":"
    • Python \u5347\u7ea7\u5230 3.12.8
    • \u6539\u8fdb\u4eea\u8868\u76d8\uff0c\u529f\u80fd\u66f4\u6e05\u6670\u3001\u66f4\u4eba\u6027\u5316
    • \u6dfb\u52a0\u4e86\u4f17\u591a\u7b2c\u4e09\u65b9\u5305\uff1aPyTorch / Twisted / Scrapy / FastAPI ...
    "},{"location":"whats-new/#v338","title":"v3.3.8","text":"
    • \u4fee\u590d\u4e86 NumPy \u517c\u5bb9\u6027\u95ee\u9898
    "},{"location":"whats-new/#v335","title":"v3.3.5","text":"
    • \u5347\u7ea7 Python \u5185\u6838\u5230 3.11.9
    • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u4e0d\u663e\u793a\u6a21\u5757\u5b89\u88c5\u72b6\u6001\u7684 bug
    • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u5220\u9664\u6a21\u5757\u5931\u8d25\u7684 bug
    • \u4fee\u590d\u4e86\u5176\u4ed6 bug
    "},{"location":"whats-new/#v334","title":"v3.3.4","text":"
    • \u6dfb\u52a0\u4e86 OpenAI/Langchain/APIGPTCloud AI \u5305
    • \u79fb\u9664\u4e0d\u5fc5\u8981\u7684\u6587\u4ef6\u4ee5\u51cf\u5c11\u5927\u5c0f
    "},{"location":"whats-new/#v325","title":"v3.2.5","text":"
    • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570
    • \u5176\u4ed6\u9519\u8bef\u4fee\u590d
    "},{"location":"whats-new/#v323","title":"v3.2.3","text":"
    • \u66f4\u65b0 Python \u7248\u672c\u5230 3.11.0
    • \u66f4\u65b0 IPython \u7248\u672c\u5230 8.6.0
    • \u66f4\u65b0 pip \u7248\u672c\u5230 22.3.1
    • \u66f4\u65b0\u79d1\u5b66\u8ba1\u7b97\u5305\uff0c\u81ea\u52a8\u8f6f\u94fe\u63a5
    • \u51cf\u5c11\u7a7a\u95f4\u4f7f\u7528
    • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570 + \u5176\u4ed6\u9519\u8bef\u4fee\u590d
    "},{"location":"whats-new/#v318","title":"v3.1.8","text":"
    • \u5728\u7ec8\u7aef\u4e2d\u6dfb\u52a0\u4e86\u64cd\u4f5c\u70ed\u952e
    • \u4fee\u590d\u4e86\u7f16\u8f91\u5668\u5728\u65cb\u8f6c\u65f6\u4e22\u5931\u5185\u5bb9\u7684\u95ee\u9898
    • \u4fee\u590d\u4e86\u5176\u4ed6 bug

    \u5728 Google Play \u4e0b\u8f7d

    "},{"location":"qsl4a/","title":"QSL4A\uff08Android \u811a\u672c\u5c42\uff09API \u6587\u6863","text":"

    QSL4A \u662f QPython \u7684 Android \u811a\u672c\u5c42\uff0c\u5141\u8bb8\u60a8\u4f7f\u7528 Python \u63a7\u5236 Android \u8bbe\u5907\u529f\u80fd\u3002

    "},{"location":"qsl4a/#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a toast \u6d88\u606f\ndroid.makeToast('Hello QPython!')\n\n# \u9707\u52a8\u8bbe\u5907\ndroid.vibrate(500)\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\uff08\u5148\u5f00\u59cb\u76d1\u63a7\uff09\nimport time\ndroid.batteryStartMonitoring()\ntime.sleep(0.5)  # \u7b49\u5f85\u6570\u636e\nbattery = droid.readBatteryData().result\nprint(f\"\u7535\u6c60\uff1a{battery['level']}%\")\n
    "},{"location":"qsl4a/#_2","title":"\u6587\u6863\u7ed3\u6784","text":""},{"location":"qsl4a/#_3","title":"\u6838\u5fc3\u6a21\u5757","text":"
    • Android \u57fa\u7840 - \u6838\u5fc3\u8fde\u63a5\u548c RPC
    • Intent \u7cfb\u7edf - Android Intent \u64cd\u4f5c
    • \u4e8b\u4ef6\u7cfb\u7edf - \u4e8b\u4ef6\u5904\u7406\u548c\u5e7f\u64ad
    "},{"location":"qsl4a/#ui","title":"UI \u7ec4\u4ef6","text":"
    • \u5bf9\u8bdd\u6846 - \u8b66\u62a5\u3001\u8f93\u5165\u3001\u9009\u62e9\u5bf9\u8bdd\u6846
    • \u5168\u5c4f UI - \u81ea\u5b9a\u4e49\u5e03\u5c40 UI
    • \u60ac\u6d6e\u7a97 - \u60ac\u6d6e\u7a97\u53e3
    • \u8f85\u52a9\u529f\u80fd - \u5c4f\u5e55\u81ea\u52a8\u5316
    "},{"location":"qsl4a/#_4","title":"\u7cfb\u7edf","text":"
    • \u7535\u6c60 - \u7535\u6c60\u76d1\u63a7
    • \u4f20\u611f\u5668 - \u8bbe\u5907\u4f20\u611f\u5668
    • \u5e94\u7528 - \u5e94\u7528\u7ba1\u7406
    • \u7cfb\u7edf\u4fe1\u606f - \u8bbe\u5907\u4fe1\u606f
    • \u8bbe\u7f6e - \u7cfb\u7edf\u8bbe\u7f6e
    • \u5524\u9192\u9501 - \u5524\u9192\u9501\u63a7\u5236
    • QPython \u63a5\u53e3 - \u811a\u672c\u6267\u884c
    • Activity \u7ed3\u679c - Activity \u7ed3\u679c\u5904\u7406
    "},{"location":"qsl4a/#_5","title":"\u786c\u4ef6","text":"
    • \u84dd\u7259 - \u84dd\u7259\u64cd\u4f5c
    • \u76f8\u673a - \u62cd\u7167\u548c\u5f55\u50cf
    • \u97f3\u9891/\u5f55\u97f3\u5668 - \u5f55\u97f3
    • \u7f51\u7edc\u6444\u50cf\u5934 - MJPEG \u6d41
    • USB \u4e32\u53e3 - USB \u4e3b\u673a\u4e32\u53e3
    "},{"location":"qsl4a/#_6","title":"\u8fde\u63a5","text":"
    • WiFi - WiFi \u64cd\u4f5c
    • \u4f4d\u7f6e - GPS \u548c\u4f4d\u7f6e
    • \u77ed\u4fe1 - \u77ed\u4fe1\u64cd\u4f5c
    • \u7535\u8bdd - \u6253\u7535\u8bdd\u548c\u6765\u7535\u4fe1\u606f
    • \u8054\u7cfb\u4eba - \u8054\u7cfb\u4eba\u7ba1\u7406
    • \u4fe1\u53f7\u5f3a\u5ea6 - \u4fe1\u53f7\u76d1\u63a7
    • FTP \u670d\u52a1\u5668 - \u5185\u7f6e FTP \u670d\u52a1\u5668
    "},{"location":"qsl4a/#_7","title":"\u5b58\u50a8","text":"
    • DocumentFile - \u6587\u4ef6\u64cd\u4f5c
    • \u526a\u8d34\u677f - \u526a\u8d34\u677f\u64cd\u4f5c
    • \u504f\u597d\u8bbe\u7f6e - \u5171\u4eab\u504f\u597d\u8bbe\u7f6e
    "},{"location":"qsl4a/#_8","title":"\u5a92\u4f53","text":"
    • \u5a92\u4f53\u64ad\u653e\u5668 - \u97f3\u9891/\u89c6\u9891\u64ad\u653e
    • \u56fe\u50cf\u5904\u7406 - \u56fe\u50cf\u64cd\u4f5c
    "},{"location":"qsl4a/#_9","title":"\u7279\u6b8a\u529f\u80fd","text":"
    • \u52a0\u5bc6 - \u52a0\u5bc6/\u89e3\u5bc6
    • PGPT AI - AI \u8bed\u97f3\u670d\u52a1
    "},{"location":"qsl4a/#_10","title":"\u7ed3\u679c\u5bf9\u8c61","text":"

    \u5927\u591a\u6570 QSL4A \u65b9\u6cd5\u8fd4\u56de\u4e00\u4e2a\u5e26\u6709\u4ee5\u4e0b\u5c5e\u6027\u7684 Result \u547d\u540d\u5143\u7ec4\uff1a - id - \u8bf7\u6c42 ID - result - \u5b9e\u9645\u7ed3\u679c\u6570\u636e - error - \u5982\u679c\u5931\u8d25\u5219\u4e3a\u9519\u8bef\u6d88\u606f

    result = droid.getClipboard()\nif result.error is None:\n    print(result.result)\nelse:\n    print(f\"\u9519\u8bef\uff1a{result.error}\")\n
    "},{"location":"qsl4a/connectivity/contacts/","title":"\u8054\u7cfb\u4eba API","text":"

    \u8bbf\u95ee\u548c\u7ba1\u7406\u8bbe\u5907\u8054\u7cfb\u4eba\u3002

    "},{"location":"qsl4a/connectivity/contacts/#_1","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":""},{"location":"qsl4a/connectivity/contacts/#pickcontact","title":"pickContact()","text":"

    \u663e\u793a\u8054\u7cfb\u4eba\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

    pickContact()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u8054\u7cfb\u4eba URI \u7684 Intent

    "},{"location":"qsl4a/connectivity/contacts/#pickphone","title":"pickPhone()","text":"

    \u663e\u793a\u7535\u8bdd\u53f7\u7801\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

    pickPhone()\n

    \u8fd4\u56de\uff1a \u9009\u4e2d\u7684\u7535\u8bdd\u53f7\u7801\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/connectivity/contacts/#_2","title":"\u8054\u7cfb\u4eba\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#contactsget","title":"contactsGet()","text":"

    \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\u3002

    contactsGet(attributes=None)\n

    \u53c2\u6570\uff1a - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

    \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba JSONObject \u5217\u8868

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetbyid","title":"contactsGetById()","text":"

    \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\u3002

    contactsGetById(id, attributes=None)\n

    \u53c2\u6570\uff1a - id (int): \u8054\u7cfb\u4eba ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

    \u8fd4\u56de\uff1a JSONObject \u8054\u7cfb\u4eba\u6570\u636e

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetcount","title":"contactsGetCount()","text":"

    \u83b7\u53d6\u8054\u7cfb\u4eba\u603b\u6570\u3002

    contactsGetCount()\n

    \u8fd4\u56de\uff1a \u6574\u6570\u8ba1\u6570

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetids","title":"contactsGetIds()","text":"

    \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba ID\u3002

    contactsGetIds()\n

    \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba ID \u6574\u6570\u5217\u8868

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetattributes","title":"contactsGetAttributes()","text":"

    \u83b7\u53d6\u6240\u6709\u53ef\u80fd\u7684\u8054\u7cfb\u4eba\u5c5e\u6027\u3002

    contactsGetAttributes()\n

    \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u5217\u8868

    "},{"location":"qsl4a/connectivity/contacts/#_3","title":"\u5185\u5bb9\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#querycontent","title":"queryContent()","text":"

    \u4f7f\u7528\u81ea\u5b9a\u4e49\u53c2\u6570\u67e5\u8be2\u5185\u5bb9\u89e3\u6790\u5668\u3002

    queryContent(uri, attributes=None, selection=None, selectionArgs=None, order=None)\n

    \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u5c5e\u6027 - selection (str, optional): WHERE \u5b50\u53e5 - selectionArgs (list, optional): \u9009\u62e9\u53c2\u6570 - order (str, optional): ORDER BY \u5b50\u53e5

    \u8fd4\u56de\uff1a JSONObject \u7ed3\u679c\u5217\u8868

    "},{"location":"qsl4a/connectivity/contacts/#queryattributes","title":"queryAttributes()","text":"

    \u83b7\u53d6\u5185\u5bb9 URI \u7684\u5c5e\u6027\u3002

    queryAttributes(uri)\n

    \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI

    \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u7684 JSONArray

    "},{"location":"qsl4a/connectivity/contacts/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u9009\u62e9\u8054\u7cfb\u4eba\ncontact_uri = droid.pickContact().result\nprint(f\"Selected contact: {contact_uri}\")\n\n# \u9009\u62e9\u7535\u8bdd\u53f7\u7801\nphone = droid.pickPhone().result\nprint(f\"Selected phone: {phone}\")\n\n# \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\ncontacts = droid.contactsGet().result\nprint(f\"Total contacts: {len(contacts)}\")\n\n# \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\ncontact = droid.contactsGetById(1).result\nprint(f\"Contact: {contact}\")\n\n# \u83b7\u53d6\u8054\u7cfb\u4eba\u5c5e\u6027\nattrs = droid.contactsGetAttributes().result\nprint(f\"Available attributes: {attrs}\")\n
    "},{"location":"qsl4a/connectivity/ftp/","title":"FTP \u670d\u52a1\u5668 API","text":"

    \u5728\u8bbe\u5907\u4e0a\u542f\u52a8\u548c\u7ba1\u7406\u5185\u7f6e FTP \u670d\u52a1\u5668\u3002

    "},{"location":"qsl4a/connectivity/ftp/#ftp","title":"FTP \u670d\u52a1\u5668\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/ftp/#ftpstart","title":"ftpStart()","text":"

    \u542f\u52a8 FTP \u670d\u52a1\u5668\u3002

    ftpStart()\n

    \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4 [ip, port]

    "},{"location":"qsl4a/connectivity/ftp/#ftpstop","title":"ftpStop()","text":"

    \u505c\u6b62 FTP \u670d\u52a1\u5668\u3002

    ftpStop()\n
    "},{"location":"qsl4a/connectivity/ftp/#ftpisrunning","title":"ftpIsRunning()","text":"

    \u68c0\u67e5 FTP \u670d\u52a1\u5668\u662f\u5426\u6b63\u5728\u8fd0\u884c\u3002

    ftpIsRunning()\n

    \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u8fd0\u884c\u5219\u4e3a True

    "},{"location":"qsl4a/connectivity/ftp/#ftpget","title":"ftpGet()","text":"

    \u83b7\u53d6 FTP \u670d\u52a1\u5668 IP \u5730\u5740\u3002

    ftpGet()\n

    \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4

    "},{"location":"qsl4a/connectivity/ftp/#ftpset","title":"ftpSet()","text":"

    \u914d\u7f6e FTP \u670d\u52a1\u5668\u8bbe\u7f6e\u3002

    ftpSet(port=None, rootDir=None, username=None, password=None)\n

    \u53c2\u6570\uff1a - port (int, optional): \u670d\u52a1\u5668\u7aef\u53e3 - rootDir (str, optional): \u8981\u670d\u52a1\u7684\u57fa\u7840\u76ee\u5f55 - username (str, optional): \u767b\u5f55\u7528\u6237\u540d - password (str, optional): \u767b\u5f55\u5bc6\u7801

    \u8fd4\u56de\uff1a \u5305\u542b\u5f53\u524d\u8bbe\u7f6e\u7684 JSONObject

    "},{"location":"qsl4a/connectivity/ftp/#ftpstatus","title":"ftpStatus()","text":"

    \u83b7\u53d6 FTP \u670d\u52a1\u5668\u72b6\u6001\u3002

    ftpStatus()\n

    \u8fd4\u56de\uff1a \u72b6\u6001\u63cf\u8ff0\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/connectivity/ftp/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u914d\u7f6e FTP \u670d\u52a1\u5668\ndroid.ftpSet(\n    port=2121,\n    rootDir=\"/sdcard\",\n    username=\"admin\",\n    password=\"secret\"\n)\n\n# \u542f\u52a8 FTP \u670d\u52a1\u5668\ninfo = droid.ftpStart().result\nprint(f\"FTP running at {info[0]}:{info[1]}\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.ftpIsRunning().result:\n    print(\"FTP server is running\")\n\n# \u83b7\u53d6\u670d\u52a1\u5668\u4fe1\u606f\nserver_info = droid.ftpGet().result\nprint(f\"Server: {server_info}\")\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.ftpStop()\n

    \u6ce8\u610f\uff1a \u4f7f\u7528\u63d0\u4f9b\u7684\u51ed\u636e\u901a\u8fc7\u4efb\u4f55 FTP \u5ba2\u6237\u7aef\u8fde\u63a5\u5230 FTP \u670d\u52a1\u5668\u3002

    "},{"location":"qsl4a/connectivity/location/","title":"\u4f4d\u7f6e API","text":"

    \u8bbf\u95ee GPS \u548c\u7f51\u7edc\u4f4d\u7f6e\u670d\u52a1\u3002

    "},{"location":"qsl4a/connectivity/location/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/location/#startlocating","title":"startLocating()","text":"

    \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\u3002

    startLocating(minUpdateTime=60000, minUpdateDistance=30, updateGnssStatus=False)\n

    \u53c2\u6570\uff1a - minUpdateTime (int): \u66f4\u65b0\u4e4b\u95f4\u7684\u6700\u5c0f\u65f6\u95f4\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a60000\uff09 - minUpdateDistance (float): \u66f4\u65b0\u7684\u6700\u5c0f\u8ddd\u79bb\uff08\u7c73\uff09\uff08\u9ed8\u8ba4\uff1a30\uff09 - updateGnssStatus (bool): \u542f\u7528 GNSS \u72b6\u6001\u66f4\u65b0\uff08\u9ed8\u8ba4\uff1aFalse\uff09

    "},{"location":"qsl4a/connectivity/location/#stoplocating","title":"stopLocating()","text":"

    \u505c\u6b62\u4f4d\u7f6e\u66f4\u65b0\u3002

    stopLocating()\n
    "},{"location":"qsl4a/connectivity/location/#readlocation","title":"readLocation()","text":"

    \u83b7\u53d6\u6700\u540e\u5df2\u77e5\u4f4d\u7f6e\u3002

    readLocation()\n

    \u8fd4\u56de\uff1a \u4f4d\u7f6e\u6570\u636e\u5b57\u5178

    "},{"location":"qsl4a/connectivity/location/#getlastknownlocation","title":"getLastKnownLocation()","text":"

    \u83b7\u53d6\u7f13\u5b58\u7684\u4f4d\u7f6e\u3002

    getLastKnownLocation()\n

    \u8fd4\u56de\uff1a \u6765\u81ea\u6240\u6709\u63d0\u4f9b\u5546\u7684\u4f4d\u7f6e

    "},{"location":"qsl4a/connectivity/location/#geocode","title":"geocode()","text":"

    \u5c06\u5730\u5740\u8f6c\u6362\u4e3a\u5750\u6807\u3002

    geocode(address, maxResults=1)\n
    "},{"location":"qsl4a/connectivity/location/#_2","title":"\u4f4d\u7f6e\u63d0\u4f9b\u5546\u65b9\u6cd5)","text":""},{"location":"qsl4a/connectivity/location/#locationproviders","title":"locationProviders()","text":"

    \u83b7\u53d6\u624b\u673a\u4e0a\u53ef\u7528\u7684\u4f4d\u7f6e\u63d0\u4f9b\u5546\u3002

    locationProviders()\n

    \u8fd4\u56de\uff1a \u53ef\u7528\u63d0\u4f9b\u5546\u540d\u79f0\u5217\u8868\uff08\u4f8b\u5982 ['gps', 'network']\uff09

    "},{"location":"qsl4a/connectivity/location/#locationproviderenabled","title":"locationProviderEnabled()","text":"

    \u68c0\u67e5\u7279\u5b9a\u4f4d\u7f6e\u63d0\u4f9b\u5546\u662f\u5426\u5df2\u542f\u7528\u3002

    locationProviderEnabled(provider)\n

    \u53c2\u6570\uff1a - provider (str): \u63d0\u4f9b\u5546\u540d\u79f0\uff08\u4f8b\u5982 'gps', 'network'\uff09

    \u8fd4\u56de\uff1a \u5982\u679c\u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

    "},{"location":"qsl4a/connectivity/location/#readgnssstatus","title":"readGnssStatus()","text":"

    \u8bfb\u53d6\u5168\u7403\u5bfc\u822a\u536b\u661f\u7cfb\u7edf\u72b6\u6001\uff08\u9700\u8981 Android 8+\uff09\u3002

    readGnssStatus()\n

    \u8fd4\u56de\uff1a \u5305\u542b GNSS \u536b\u661f\u4fe1\u606f\u7684 JSONArray

    "},{"location":"qsl4a/connectivity/location/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\ndroid.startLocating(minUpdateTime=5000, minUpdateDistance=1, updateGnssStatus=False)\n\n# \u7b49\u5f85\u5b9a\u4f4d\ntime.sleep(10)\n\n# \u83b7\u53d6\u4f4d\u7f6e\nloc = droid.readLocation().result\nif loc:\n    lat = loc['latitude']\n    lon = loc['longitude']\n    print(f\"Location: {lat}, {lon}\")\n\ndroid.stopLocating()\n
    "},{"location":"qsl4a/connectivity/phone/","title":"\u7535\u8bdd API","text":"

    \u63a7\u5236\u7535\u8bdd\u901a\u8bdd\u548c\u83b7\u53d6\u7535\u8bdd\u4fe1\u606f\u3002

    "},{"location":"qsl4a/connectivity/phone/#_1","title":"\u7535\u8bdd\u72b6\u6001\u8ddf\u8e2a","text":""},{"location":"qsl4a/connectivity/phone/#starttrackingphonestate","title":"startTrackingPhoneState()","text":"

    \u5f00\u59cb\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u53d8\u5316\u3002\u751f\u6210 'phone' \u4e8b\u4ef6\u3002

    startTrackingPhoneState()\n
    "},{"location":"qsl4a/connectivity/phone/#readphonestate","title":"readPhoneState()","text":"

    \u8bfb\u53d6\u5f53\u524d\u7535\u8bdd\u72b6\u6001\u3002

    readPhoneState()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u7535\u8bdd\u72b6\u6001\u548c\u6765\u7535\u53f7\u7801\u7684 Bundle

    "},{"location":"qsl4a/connectivity/phone/#stoptrackingphonestate","title":"stopTrackingPhoneState()","text":"

    \u505c\u6b62\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u3002

    stopTrackingPhoneState()\n
    "},{"location":"qsl4a/connectivity/phone/#_2","title":"\u62e8\u6253\u7535\u8bdd","text":""},{"location":"qsl4a/connectivity/phone/#phonecall","title":"phoneCall()","text":"

    \u901a\u8fc7 URI \u547c\u53eb\u8054\u7cfb\u4eba/\u7535\u8bdd\u53f7\u7801\u3002

    phoneCall(uri)\n

    \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

    "},{"location":"qsl4a/connectivity/phone/#phonecallnumber","title":"phoneCallNumber()","text":"

    \u76f4\u63a5\u62e8\u6253\u7535\u8bdd\u53f7\u7801\u3002

    phoneCallNumber(phone_number)\n

    \u53c2\u6570\uff1a - phone_number (str): \u8981\u62e8\u6253\u7684\u7535\u8bdd\u53f7\u7801

    "},{"location":"qsl4a/connectivity/phone/#phonedial","title":"phoneDial()","text":"

    \u62e8\u6253\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

    phoneDial(uri)\n

    \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

    "},{"location":"qsl4a/connectivity/phone/#phonedialnumber","title":"phoneDialNumber()","text":"

    \u62e8\u6253\u7535\u8bdd\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

    phoneDialNumber(phone_number)\n

    \u53c2\u6570\uff1a - phone_number (str): \u7535\u8bdd\u53f7\u7801

    "},{"location":"qsl4a/connectivity/phone/#_3","title":"\u57fa\u7ad9\u4f4d\u7f6e","text":""},{"location":"qsl4a/connectivity/phone/#getcelllocation","title":"getCellLocation()","text":"

    \u83b7\u53d6\u5f53\u524d\u57fa\u7ad9\u4f4d\u7f6e\u3002

    getCellLocation()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u57fa\u7ad9\u4f4d\u7f6e\u6570\u636e\u7684 JSONObject

    "},{"location":"qsl4a/connectivity/phone/#getallcellslocation","title":"getAllCellsLocation()","text":"

    \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u4f4d\u7f6e\uff08\u9002\u7528\u4e8e\u53cc\u5361\u8bbe\u5907\uff09\u3002

    getAllCellsLocation()\n

    \u8fd4\u56de\uff1a \u57fa\u7ad9\u4f4d\u7f6e\u7684 JSONArray

    "},{"location":"qsl4a/connectivity/phone/#_4","title":"\u7f51\u7edc\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getnetworkoperator","title":"getNetworkOperator()","text":"

    \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

    getNetworkOperator()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

    "},{"location":"qsl4a/connectivity/phone/#getnetworkoperatorname","title":"getNetworkOperatorName()","text":"

    \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684\u540d\u79f0\u3002

    getNetworkOperatorName()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

    "},{"location":"qsl4a/connectivity/phone/#getnetworktype","title":"getNetworkType()","text":"

    \u83b7\u53d6\u5f53\u524d\u7f51\u7edc\u7c7b\u578b\u3002

    getNetworkType()\n

    \u8fd4\u56de\uff1a \u63cf\u8ff0\u65e0\u7ebf\u7535\u6280\u672f\u7684\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'LTE', 'UMTS', 'GSM'\uff09

    "},{"location":"qsl4a/connectivity/phone/#getphonetype","title":"getPhoneType()","text":"

    \u83b7\u53d6\u7535\u8bdd\u7c7b\u578b\u3002

    getPhoneType()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'GSM', 'CDMA', 'SIP'\uff09

    "},{"location":"qsl4a/connectivity/phone/#sim","title":"SIM \u5361\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getsimcountryiso","title":"getSimCountryIso()","text":"

    \u83b7\u53d6 SIM \u5361\u7684 ISO \u56fd\u5bb6\u4ee3\u7801\u3002

    getSimCountryIso()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'us'\uff09

    "},{"location":"qsl4a/connectivity/phone/#getsimoperator","title":"getSimOperator()","text":"

    \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

    getSimOperator()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

    "},{"location":"qsl4a/connectivity/phone/#getsimoperatorname","title":"getSimOperatorName()","text":"

    \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u540d\u79f0\u3002

    getSimOperatorName()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

    "},{"location":"qsl4a/connectivity/phone/#getsimserialnumber","title":"getSimSerialNumber()","text":"

    \u83b7\u53d6 SIM \u5e8f\u5217\u53f7\u3002

    getSimSerialNumber()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32 SIM \u5e8f\u5217\u53f7

    "},{"location":"qsl4a/connectivity/phone/#getsimstate","title":"getSimState()","text":"

    \u83b7\u53d6 SIM \u5361\u72b6\u6001\u3002

    getSimState()\n

    \u8fd4\u56de\uff1a \u63cf\u8ff0 SIM \u72b6\u6001\u7684\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/connectivity/phone/#getsubscriberid","title":"getSubscriberId()","text":"

    \u83b7\u53d6\u8ba2\u9605\u8005 ID\u3002

    getSubscriberId()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8ba2\u9605\u8005 ID

    "},{"location":"qsl4a/connectivity/phone/#_5","title":"\u8bed\u97f3\u90ae\u4ef6","text":""},{"location":"qsl4a/connectivity/phone/#getvoicemailalphatag","title":"getVoiceMailAlphaTag()","text":"

    \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u5b57\u6bcd\u6807\u7b7e\u3002

    getVoiceMailAlphaTag()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u6807\u7b7e

    "},{"location":"qsl4a/connectivity/phone/#getvoicemailnumber","title":"getVoiceMailNumber()","text":"

    \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801\u3002

    getVoiceMailNumber()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801

    "},{"location":"qsl4a/connectivity/phone/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getdeviceid","title":"getDeviceId()","text":"

    \u83b7\u53d6\u8bbe\u5907 ID\uff08GSM \u7684 IMEI\uff09\u3002\u5df2\u5e9f\u5f03\u3002

    getDeviceId()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

    "},{"location":"qsl4a/connectivity/phone/#getdevicesoftwareversion","title":"getDeviceSoftwareVersion()","text":"

    \u83b7\u53d6\u8bbe\u5907\u8f6f\u4ef6\u7248\u672c\u3002

    getDeviceSoftwareVersion()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8f6f\u4ef6\u7248\u672c

    "},{"location":"qsl4a/connectivity/phone/#getline1number","title":"getLine1Number()","text":"

    \u83b7\u53d6\u7ebf\u8def 1 \u7535\u8bdd\u53f7\u7801\u3002

    getLine1Number()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u7535\u8bdd\u53f7\u7801

    "},{"location":"qsl4a/connectivity/phone/#checknetworkroaming","title":"checkNetworkRoaming()","text":"

    \u68c0\u67e5\u662f\u5426\u8fde\u63a5\u5230\u6f2b\u6e38\u7f51\u7edc\u3002

    checkNetworkRoaming()\n

    \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u6f2b\u6e38\u5219\u4e3a True

    "},{"location":"qsl4a/connectivity/phone/#_7","title":"\u57fa\u7ad9\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getallcellinfo","title":"getAllCellInfo()","text":"

    \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u7684\u4fe1\u606f\u3002

    getAllCellInfo()\n

    \u8fd4\u56de\uff1a \u57fa\u7ad9\u4fe1\u606f\u5217\u8868

    "},{"location":"qsl4a/connectivity/phone/#setdataenabled","title":"setDataEnabled()","text":"

    \u542f\u7528\u6216\u7981\u7528\u79fb\u52a8\u6570\u636e\u3002

    setDataEnabled(enabled)\n

    \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528

    "},{"location":"qsl4a/connectivity/phone/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7f51\u7edc\u4fe1\u606f\noperator = droid.getNetworkOperatorName().result\nprint(f\"Operator: {operator}\")\n\nnetwork_type = droid.getNetworkType().result\nprint(f\"Network: {network_type}\")\n\n# \u83b7\u53d6 SIM \u4fe1\u606f\nsim_state = droid.getSimState().result\nprint(f\"SIM: {sim_state}\")\n\n# \u83b7\u53d6\u7535\u8bdd\u53f7\u7801\nline1 = droid.getLine1Number().result\nprint(f\"Phone: {line1}\")\n\n# \u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\ndroid.startTrackingPhoneState()\nprint(\"Tracking phone state...\")\ndroid.stopTrackingPhoneState()\n
    "},{"location":"qsl4a/connectivity/signalstrength/","title":"\u4fe1\u53f7\u5f3a\u5ea6 API","text":"

    \u76d1\u63a7\u8702\u7a9d\u548c\u65e0\u7ebf\u4fe1\u53f7\u5f3a\u5ea6\u3002

    "},{"location":"qsl4a/connectivity/signalstrength/#_1","title":"\u4fe1\u53f7\u5f3a\u5ea6\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/signalstrength/#starttrackingsignalstrengths","title":"startTrackingSignalStrengths()","text":"

    \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316\u3002\u751f\u6210 'signal_strengths' \u4e8b\u4ef6\u3002

    startTrackingSignalStrengths()\n
    "},{"location":"qsl4a/connectivity/signalstrength/#stoptrackingsignalstrengths","title":"stopTrackingSignalStrengths()","text":"

    \u505c\u6b62\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u3002

    stopTrackingSignalStrengths()\n
    "},{"location":"qsl4a/connectivity/signalstrength/#readsignalstrengths","title":"readSignalStrengths()","text":"

    \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\u3002

    readSignalStrengths()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u4fe1\u53f7\u5f3a\u5ea6\u6570\u636e\u7684 Bundle

    "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthlevel","title":"getTelephoneSignalStrengthLevel()","text":"

    \u83b7\u53d6\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u7b49\u7ea7\uff080-4\uff09\u3002

    getTelephoneSignalStrengthLevel()\n

    \u8fd4\u56de\uff1a \u6574\u6570\u7b49\u7ea7\uff080=\u65e0\uff0c1=\u5dee\uff0c2=\u4e00\u822c\uff0c3=\u597d\uff0c4=\u4f18\u79c0\uff09

    "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthdetail","title":"getTelephoneSignalStrengthDetail()","text":"

    \u83b7\u53d6\u8be6\u7ec6\u7684\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u4fe1\u606f\u3002

    getTelephoneSignalStrengthDetail()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u8be6\u7ec6\u4fe1\u53f7\u4fe1\u606f\u7684\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/connectivity/signalstrength/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\ndroid.startTrackingSignalStrengths()\n\n# \u7b49\u5f85\u4fe1\u53f7\u66f4\u65b0\ntime.sleep(5)\n\n# \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\nsignal = droid.readSignalStrengths().result\nprint(f\"Signal: {signal}\")\n\n# \u76f4\u63a5\u83b7\u53d6\u7b49\u7ea7\nlevel = droid.getTelephoneSignalStrengthLevel().result\nprint(f\"Signal level: {level}/4\")\n\ndroid.stopTrackingSignalStrengths()\n
    "},{"location":"qsl4a/connectivity/sms/","title":"SMS API","text":"

    \u53d1\u9001\u548c\u63a5\u6536 SMS \u6d88\u606f\u3002

    "},{"location":"qsl4a/connectivity/sms/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/sms/#smssend","title":"smsSend()","text":"

    \u53d1\u9001 SMS \u6d88\u606f\u3002

    smsSend(destinationAddress, text)\n

    \u53c2\u6570\uff1a - destinationAddress (str): \u7535\u8bdd\u53f7\u7801 - text (str): \u6d88\u606f\u6587\u672c

    "},{"location":"qsl4a/connectivity/sms/#smsgetmessagecount","title":"smsGetMessageCount()","text":"

    \u83b7\u53d6\u6d88\u606f\u6570\u91cf\u3002

    smsGetMessageCount(unreadOnly=False, folder=\"inbox\")\n
    "},{"location":"qsl4a/connectivity/sms/#smsgetmessageids","title":"smsGetMessageIds()","text":"

    \u83b7\u53d6\u6d88\u606f ID\u3002

    smsGetMessageIds(unreadOnly=False, folder=\"inbox\")\n
    "},{"location":"qsl4a/connectivity/sms/#smsgetmessages","title":"smsGetMessages()","text":"

    \u83b7\u53d6\u6d88\u606f\u8be6\u60c5\u3002

    smsGetMessages(unreadOnly=False, folder=\"inbox\", attributes=None)\n
    "},{"location":"qsl4a/connectivity/sms/#smsgetmessagebyid","title":"smsGetMessageById()","text":"

    \u901a\u8fc7 ID \u83b7\u53d6\u7279\u5b9a\u6d88\u606f\u3002

    smsGetMessageById(id, attributes=None)\n

    \u53c2\u6570\uff1a - id (int): \u6d88\u606f ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

    \u8fd4\u56de\uff1a \u6d88\u606f\u6570\u636e\u5b57\u5178

    "},{"location":"qsl4a/connectivity/sms/#smsgetattributes","title":"smsGetAttributes()","text":"

    \u83b7\u53d6\u53ef\u7528\u7684 SMS \u6d88\u606f\u5c5e\u6027\u3002

    smsGetAttributes()\n

    \u8fd4\u56de\uff1a \u53ef\u7528\u5c5e\u6027\u540d\u79f0\u5217\u8868

    "},{"location":"qsl4a/connectivity/sms/#smsdeletemessage","title":"smsDeleteMessage()","text":"

    \u5220\u9664\u6d88\u606f\u3002

    smsDeleteMessage(id)\n
    "},{"location":"qsl4a/connectivity/sms/#smsmarkmessageread","title":"smsMarkMessageRead()","text":"

    \u5c06\u6d88\u606f\u6807\u8bb0\u4e3a\u5df2\u8bfb\u3002

    smsMarkMessageRead(ids, read=True)\n
    "},{"location":"qsl4a/connectivity/sms/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u53d1\u9001 SMS\ndroid.smsSend(\"+1234567890\", \"Hello from QPython!\")\n\n# \u83b7\u53d6\u672a\u8bfb\u6d88\u606f\nmessages = droid.smsGetMessages(unreadOnly=True).result\nfor msg in messages:\n    print(f\"From: {msg['address']}, Text: {msg['body']}\")\n
    "},{"location":"qsl4a/connectivity/wifi/","title":"WiFi API","text":"

    \u63a7\u5236 WiFi \u9002\u914d\u5668\u5e76\u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\u3002

    "},{"location":"qsl4a/connectivity/wifi/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/connectivity/wifi/#checkwifistate","title":"checkWifiState()","text":"

    \u68c0\u67e5 WiFi \u662f\u5426\u5df2\u542f\u7528\u3002

    checkWifiState()\n

    \u8fd4\u56de\uff1a \u5982\u679c WiFi \u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

    "},{"location":"qsl4a/connectivity/wifi/#togglewifistate","title":"toggleWifiState()","text":"

    \u6253\u5f00\u6216\u5173\u95ed WiFi\u3002

    toggleWifiState(enabled=None)\n

    \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

    \u8fd4\u56de\uff1a \u5982\u679c\u64cd\u4f5c\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/connectivity/wifi/#wifistartscan","title":"wifiStartScan()","text":"

    \u5f00\u59cb\u626b\u63cf\u53ef\u7528\u7684 WiFi \u7f51\u7edc\u3002

    wifiStartScan()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifigetscanresults","title":"wifiGetScanResults()","text":"

    \u83b7\u53d6\u53d1\u73b0\u7684 WiFi \u7f51\u7edc\u5217\u8868\u3002

    wifiGetScanResults()\n

    \u8fd4\u56de\uff1a \u63a5\u5165\u70b9\u4fe1\u606f\u5217\u8868

    "},{"location":"qsl4a/connectivity/wifi/#_2","title":"\u8fde\u63a5\u7ba1\u7406","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetconnectioninfo","title":"wifiGetConnectionInfo()","text":"

    \u83b7\u53d6\u8be6\u7ec6\u8fde\u63a5\u4fe1\u606f\u3002

    wifiGetConnectionInfo()\n

    \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001IP \u5730\u5740\u7b49\u8fde\u63a5\u8be6\u60c5\u7684\u5b57\u5178

    "},{"location":"qsl4a/connectivity/wifi/#getconnectedinfo","title":"getConnectedInfo()","text":"

    \u83b7\u53d6\u8fde\u63a5\u7684 WiFi \u7f51\u7edc\u4fe1\u606f\uff08\u7b80\u5316\u7248\uff09\u3002

    getConnectedInfo()\n

    \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001\u4fe1\u53f7\u5f3a\u5ea6\u7684\u5b57\u5178

    "},{"location":"qsl4a/connectivity/wifi/#getdhcpinfo","title":"getDhcpInfo()","text":"

    \u83b7\u53d6\u5f53\u524d\u8fde\u63a5\u7684 DHCP \u4fe1\u606f\u3002

    getDhcpInfo(ipConvertToString=True)\n

    \u53c2\u6570\uff1a - ipConvertToString (bool): \u5c06 IP \u5730\u5740\u8f6c\u6362\u4e3a\u5b57\u7b26\u4e32\u683c\u5f0f\uff08\u9ed8\u8ba4\uff1aTrue\uff09

    \u8fd4\u56de\uff1a \u5305\u542b IP\u3001\u7f51\u5173\u3001DNS \u7b49 DHCP \u4fe1\u606f\u7684\u5b57\u5178

    "},{"location":"qsl4a/connectivity/wifi/#wifidisconnect","title":"wifiDisconnect()","text":"

    \u65ad\u5f00\u5f53\u524d WiFi \u7f51\u7edc\u8fde\u63a5\u3002

    wifiDisconnect()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifireconnect","title":"wifiReconnect()","text":"

    \u91cd\u65b0\u8fde\u63a5\u5230\u5f53\u524d\u7f51\u7edc\u3002

    wifiReconnect()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifireassociate","title":"wifiReassociate()","text":"

    \u91cd\u65b0\u5173\u8054\u5f53\u524d\u63a5\u5165\u70b9\u3002

    wifiReassociate()\n
    "},{"location":"qsl4a/connectivity/wifi/#_3","title":"\u70ed\u70b9","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetapstate","title":"wifiGetApState()","text":"

    \u83b7\u53d6 WiFi AP\uff08\u70ed\u70b9\uff09\u72b6\u6001\u3002

    wifiGetApState()\n

    \u8fd4\u56de\uff1a \u70ed\u70b9\u72b6\u6001

    "},{"location":"qsl4a/connectivity/wifi/#wifi","title":"WiFi \u9501","text":""},{"location":"qsl4a/connectivity/wifi/#wifilockacquirefull","title":"wifiLockAcquireFull()","text":"

    \u83b7\u53d6\u5b8c\u6574 WiFi \u9501\uff08\u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\u4e5f\u4fdd\u6301 WiFi \u6d3b\u52a8\uff09\u3002

    wifiLockAcquireFull()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifilockacquirescanonly","title":"wifiLockAcquireScanOnly()","text":"

    \u83b7\u53d6\u4ec5\u626b\u63cf WiFi \u9501\u3002

    wifiLockAcquireScanOnly()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifilockrelease","title":"wifiLockRelease()","text":"

    \u91ca\u653e WiFi \u9501\u3002

    wifiLockRelease()\n
    "},{"location":"qsl4a/connectivity/wifi/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u68c0\u67e5 WiFi \u72b6\u6001\nif droid.checkWifiState().result:\n    print(\"WiFi is enabled\")\nelse:\n    print(\"Enabling WiFi...\")\n    droid.toggleWifiState(True)\n    time.sleep(2)\n\n# \u5f00\u59cb\u626b\u63cf\ndroid.wifiStartScan()\ntime.sleep(3)\n\n# \u83b7\u53d6\u626b\u63cf\u7ed3\u679c\nnetworks = droid.wifiGetScanResults().result\nfor network in networks:\n    print(f\"SSID: {network.get('SSID')}, Signal: {network.get('level')} dBm\")\n\n# \u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\ninfo = droid.wifiGetConnectionInfo().result\nif info:\n    print(f\"Connected to: {info.get('ssid')}\")\n    print(f\"BSSID: {info.get('bssid')}\")\n    print(f\"IP: {info.get('ip_address')}\")\n\n# \u83b7\u53d6 DHCP \u4fe1\u606f\ndhcp = droid.getDhcpInfo().result\nif dhcp:\n    print(f\"Gateway: {dhcp.get('gateway')}\")\n    print(f\"DNS: {dhcp.get('dns1')}\")\n\n# \u83b7\u53d6\u7b80\u5316\u7684\u8fde\u63a5\u4fe1\u606f\nconnected = droid.getConnectedInfo().result\nprint(f\"SSID: {connected.get('ssid')}, Signal: {connected.get('level')} dBm\")\n\n# \u65ad\u5f00\u5e76\u91cd\u65b0\u8fde\u63a5\ndroid.wifiDisconnect()\ntime.sleep(1)\ndroid.wifiReconnect()\n\n# \u91cd\u65b0\u5173\u8054\u63a5\u5165\u70b9\ndroid.wifiReassociate()\n\n# \u68c0\u67e5\u70ed\u70b9\u72b6\u6001\nap_state = droid.wifiGetApState().result\nprint(f\"Hotspot state: {ap_state}\")\n\n# \u83b7\u53d6 WiFi \u9501\u4ee5\u8fdb\u884c\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireFull()\n# ... \u6267\u884c\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n\n# \u6216\u4f7f\u7528\u4ec5\u626b\u63cf\u9501\u4ee5\u8fdb\u884c\u8f83\u8f7b\u7684\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireScanOnly()\n# ... \u6267\u884c\u626b\u63cf\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n
    "},{"location":"qsl4a/core/android-base/","title":"Android \u57fa\u7840\u7c7b","text":"

    Android \u7c7b\u662f QSL4A \u7684\u6838\u5fc3\uff0c\u63d0\u4f9b\u4e86\u4e0e Android \u8fd0\u884c\u65f6\u7684\u8fde\u63a5\u548c RPC \u673a\u5236\u3002

    "},{"location":"qsl4a/core/android-base/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
    # \u529f\u80fd\u5b8c\u6574\u7248\u672c\uff08\u63a8\u8350\uff09\nimport androidhelper\ndroid = androidhelper.Android()\n\n# \u7b80\u5316\u7248\u672c\uff08\u5feb\u901f\uff0c\u5355\u5b9e\u4f8b\uff09\nimport android\ndroid = android.droid\n
    "},{"location":"qsl4a/core/android-base/#android_1","title":"\u7c7b\uff1aAndroid","text":""},{"location":"qsl4a/core/android-base/#_2","title":"\u6784\u9020\u51fd\u6570","text":"
    Android(addr=None)\n

    \u53c2\u6570\uff1a - addr (tuple, optional): (HOST, PORT) \u5730\u5740\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u73af\u5883\u53d8\u91cf AP_HOST \u548c AP_PORT

    \u73af\u5883\u53d8\u91cf\uff1a - AP_HOST - \u670d\u52a1\u5668\u4e3b\u673a\u5730\u5740 - AP_PORT - \u670d\u52a1\u5668\u7aef\u53e3 - AP_HANDSHAKE - \u8ba4\u8bc1\u4ee4\u724c

    "},{"location":"qsl4a/core/android-base/#_3","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/android-base/#_rpc","title":"_rpc()","text":"

    \u8c03\u7528 Android \u51fd\u6570\u7684\u5185\u90e8 RPC \u65b9\u6cd5\u3002

    _rpc(method, *args)\n

    \u53c2\u6570\uff1a - method (str): \u8981\u8c03\u7528\u7684\u65b9\u6cd5\u540d - *args: \u65b9\u6cd5\u7684\u53ef\u53d8\u53c2\u6570

    \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4\uff0c\u5305\u542b\u4ee5\u4e0b\u5b57\u6bb5\uff1a - id (int): \u8bf7\u6c42 ID - result: \u65b9\u6cd5\u8fd4\u56de\u503c - error (str or None): \u9519\u8bef\u4fe1\u606f\uff08\u5982\u679c\u5931\u8d25\uff09

    "},{"location":"qsl4a/core/android-base/#getattr","title":"getattr()","text":"

    \u52a8\u6001\u65b9\u6cd5\u5206\u53d1\u5668\u3002\u6240\u6709 Android \u65b9\u6cd5\u90fd\u901a\u8fc7\u5c5e\u6027\u67e5\u627e\u8bbf\u95ee\u3002

    # \u4ee5\u4e0b\u4e24\u79cd\u65b9\u5f0f\u7b49\u4ef7\uff1a\ndroid.makeToast(\"Hello\")\ndroid._rpc(\"makeToast\", \"Hello\")\n
    "},{"location":"qsl4a/core/android-base/#androidpy","title":"\u72ec\u7acb\u51fd\u6570\uff08android.py\uff09","text":"

    \u4f7f\u7528\u7b80\u5316\u7684 android \u6a21\u5757\u65f6\uff1a

    "},{"location":"qsl4a/core/android-base/#jsla","title":"jsla()","text":"

    \u53d1\u9001 JSON-RPC \u8bf7\u6c42\u5e76\u8fd4\u56de\u539f\u59cb\u54cd\u5e94\u3002

    jsla(method, *params)\n

    \u8fd4\u56de\uff1a JSON \u5b57\u7b26\u4e32\u54cd\u5e94

    "},{"location":"qsl4a/core/android-base/#rsla","title":"rsla()","text":"

    \u53d1\u9001\u8bf7\u6c42\u5e76\u4ec5\u8fd4\u56de\u7ed3\u679c\u3002

    rsla(method, *params)\n

    \u8fd4\u56de\uff1a RPC \u8c03\u7528\u7684\u7ed3\u679c\u503c

    "},{"location":"qsl4a/core/android-base/#esla","title":"esla()","text":"

    \u53d1\u9001\u8bf7\u6c42\uff0c\u9519\u8bef\u65f6\u629b\u51fa\u5f02\u5e38\u3002

    esla(method, *params)\n

    \u629b\u51fa\uff1a \u5982\u679c error \u5b57\u6bb5\u4e0d\u4e3a None \u5219\u629b\u51fa\u5f02\u5e38

    "},{"location":"qsl4a/core/android-base/#nsla","title":"nsla()","text":"

    \u53d1\u9001\u8bf7\u6c42\u5e76\u8fd4\u56de Result \u547d\u540d\u5143\u7ec4\u3002

    nsla(method, *params)\n

    \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4

    "},{"location":"qsl4a/core/android-base/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/android-base/#_5","title":"\u57fa\u672c\u8fde\u63a5","text":"
    import androidhelper\n\n# \u8fde\u63a5\u5230 Android \u8fd0\u884c\u65f6\ndroid = androidhelper.Android()\n\n# \u901a\u8fc7\u663e\u793a toast \u6765\u68c0\u67e5\u8fde\u63a5\ndroid.makeToast(\"Connected!\")\n
    "},{"location":"qsl4a/core/android-base/#_6","title":"\u9519\u8bef\u5904\u7406","text":"
    result = droid.someMethod()\nif result.error:\n    print(f\"Error: {result.error}\")\nelse:\n    print(f\"Success: {result.result}\")\n
    "},{"location":"qsl4a/core/android-base/#rpc","title":"\u76f4\u63a5 RPC \u8c03\u7528","text":"
    # \u76f4\u63a5\u8c03\u7528\u4efb\u610f\u65b9\u6cd5\nresult = droid._rpc(\"makeToast\", \"Hello World\")\n
    "},{"location":"qsl4a/core/events/","title":"\u4e8b\u4ef6\u7cfb\u7edf","text":"

    QSL4A \u63d0\u4f9b\u4e86\u4e00\u4e2a\u4e8b\u4ef6\u7cfb\u7edf\uff0c\u7528\u4e8e\u5904\u7406\u6765\u81ea Android \u7684\u5f02\u6b65\u4e8b\u4ef6\uff0c\u5982\u4f20\u611f\u5668\u66f4\u65b0\u3001\u4f4d\u7f6e\u53d8\u5316\u548c\u81ea\u5b9a\u4e49\u5e7f\u64ad\u3002

    "},{"location":"qsl4a/core/events/#_2","title":"\u4e8b\u4ef6\u57fa\u7840","text":"

    \u4e8b\u4ef6\u5b58\u50a8\u5728\u7f13\u51b2\u533a\u4e2d\uff0c\u53ef\u4ee5\u8f6e\u8be2\u6216\u7b49\u5f85\u3002\u6bcf\u4e2a\u4e8b\u4ef6\u5305\u542b\uff1a - name: \u4e8b\u4ef6\u7c7b\u578b/\u540d\u79f0 - data: \u4e8b\u4ef6\u8d1f\u8f7d\u6570\u636e - time: \u65f6\u95f4\u6233

    "},{"location":"qsl4a/core/events/#_3","title":"\u4e8b\u4ef6\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#eventclearbuffer","title":"eventClearBuffer()","text":"

    \u6e05\u9664\u7f13\u51b2\u533a\u4e2d\u7684\u6240\u6709\u5f85\u5904\u7406\u4e8b\u4ef6\u3002

    eventClearBuffer()\n

    \u8fd4\u56de\uff1a None

    "},{"location":"qsl4a/core/events/#eventpoll","title":"eventPoll()","text":"

    \u8f6e\u8be2\u7f13\u51b2\u533a\u4e2d\u7684\u4e8b\u4ef6\u3002

    eventPoll(number_of_events=1)\n

    \u53c2\u6570\uff1a - number_of_events (int): \u8981\u68c0\u7d22\u7684\u6700\u5927\u4e8b\u4ef6\u6570\uff08\u9ed8\u8ba4\uff1a1\uff09

    \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\u5217\u8868

    "},{"location":"qsl4a/core/events/#eventwait","title":"eventWait()","text":"

    \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\u3002

    eventWait(timeout=None)\n

    \u53c2\u6570\uff1a - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09\u3002None = \u6c38\u4e45\u7b49\u5f85

    \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

    "},{"location":"qsl4a/core/events/#eventwaitfor","title":"eventWaitFor()","text":"

    \u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6\u3002

    eventWaitFor(eventName, timeout=None)\n

    \u53c2\u6570\uff1a - eventName (str): \u8981\u7b49\u5f85\u7684\u4e8b\u4ef6\u540d\u79f0 - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

    \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

    "},{"location":"qsl4a/core/events/#eventpost","title":"eventPost()","text":"

    \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\u3002

    eventPost(name, data, enqueue=None)\n

    \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e\uff08\u4efb\u610f\u7c7b\u578b\uff09 - enqueue (bool, optional): \u5982\u679c\u4e3a True \u5219\u6dfb\u52a0\u5230\u961f\u5217

    "},{"location":"qsl4a/core/events/#receiveevent","title":"receiveEvent()","text":"

    \u63a5\u6536\u4e8b\u4ef6\uff08\u963b\u585e\uff09\u3002

    receiveEvent()\n

    \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61

    "},{"location":"qsl4a/core/events/#_4","title":"\u5e7f\u64ad\u4e8b\u4ef6","text":"

    \u6ce8\u518c\u7cfb\u7edf\u5e7f\u64ad\u4e8b\u4ef6\u3002

    "},{"location":"qsl4a/core/events/#eventregisterforbroadcast","title":"eventRegisterForBroadcast()","text":"

    \u6ce8\u518c\u63a5\u6536\u5e7f\u64ad\u4e8b\u4ef6\u3002

    eventRegisterForBroadcast(category, enqueue=True)\n

    \u53c2\u6570\uff1a - category (str): \u5e7f\u64ad\u7c7b\u522b/\u52a8\u4f5c - enqueue (bool): \u6dfb\u52a0\u5230\u4e8b\u4ef6\u961f\u5217

    "},{"location":"qsl4a/core/events/#eventunregisterforbroadcast","title":"eventUnregisterForBroadcast()","text":"

    \u53d6\u6d88\u6ce8\u518c\u5e7f\u64ad\u4e8b\u4ef6\u3002

    eventUnregisterForBroadcast(category)\n
    "},{"location":"qsl4a/core/events/#eventgetbrodcastcategories","title":"eventGetBrodcastCategories()","text":"

    \u83b7\u53d6\u5df2\u6ce8\u518c\u7684\u5e7f\u64ad\u7c7b\u522b\u3002

    eventGetBrodcastCategories()\n

    \u8fd4\u56de\uff1a \u5df2\u6ce8\u518c\u7c7b\u522b\u5217\u8868

    "},{"location":"qsl4a/core/events/#_5","title":"\u4e8b\u4ef6\u5206\u53d1\u5668)","text":""},{"location":"qsl4a/core/events/#starteventdispatcher","title":"startEventDispatcher()","text":"

    \u6253\u5f00\u4e00\u4e2a\u53ef\u4ee5\u8bfb\u53d6\u5df2\u53d1\u5e03\u4e8b\u4ef6\u7684\u5957\u63a5\u5b57\u3002)

    startEventDispatcher(port=0)\n

    \u53c2\u6570\uff1a - port (int, optional): \u76d1\u542c\u7684\u7aef\u53e3\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\u9009\u62e9\uff09

    \u8fd4\u56de\uff1a \u6b63\u5728\u76d1\u542c\u7684\u7aef\u53e3\u53f7

    "},{"location":"qsl4a/core/events/#stopeventdispatcher","title":"stopEventDispatcher()","text":"

    \u505c\u6b62\u4e8b\u4ef6\u670d\u52a1\u5668\u3002)

    stopEventDispatcher()\n
    "},{"location":"qsl4a/core/events/#_6","title":"\u5df2\u5e9f\u5f03\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#rpcpostevent","title":"rpcPostEvent()","text":"

    \u5c06\u4e8b\u4ef6\u53d1\u5e03\u5230\u4e8b\u4ef6\u961f\u5217\u3002\uff08\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 eventPost\uff09

    rpcPostEvent(name, data)\n

    \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e

    "},{"location":"qsl4a/core/events/#_7","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/events/#_8","title":"\u57fa\u672c\u4e8b\u4ef6\u8f6e\u8be2","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6e05\u9664\u65e7\u4e8b\u4ef6\ndroid.eventClearBuffer()\n\n# \u8f6e\u8be2\u4e8b\u4ef6\nevents = droid.eventPoll(5).result\nfor event in events:\n    print(f\"Event: {event['name']}, Data: {event['data']}\")\n
    "},{"location":"qsl4a/core/events/#_9","title":"\u7b49\u5f85\u4e8b\u4ef6","text":"
    # \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\uff0c\u5e26\u8d85\u65f6\nevent = droid.eventWait(timeout=10).result\nif event:\n    print(f\"Got event: {event['name']}\")\n
    "},{"location":"qsl4a/core/events/#_10","title":"\u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6","text":"
    # \u7b49\u5f85\u4f20\u611f\u5668\u4e8b\u4ef6\nevent = droid.eventWaitFor('screen', timeout=5).result\nif event:\n    print(f\"Screen event: {event['data']}\")\n
    "},{"location":"qsl4a/core/events/#_11","title":"\u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6","text":"
    # \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\ndroid.eventPost('my_event', {'key': 'value'})\n\n# \u7b49\u5f85\u5b83\nevent = droid.eventWaitFor('my_event', timeout=1).result\n
    "},{"location":"qsl4a/core/events/#_12","title":"\u5e7f\u64ad\u63a5\u6536\u5668","text":"
    # \u6ce8\u518c\u5c4f\u5e55\u5f00\u5173\u4e8b\u4ef6\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_ON')\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_OFF')\n\n# \u7b49\u5f85\u5c4f\u5e55\u4e8b\u4ef6\nwhile True:\n    event = droid.receiveEvent().result\n    if event['name'] == 'android.intent.action.SCREEN_ON':\n        print(\"Screen turned on\")\n    elif event['name'] == 'android.intent.action.SCREEN_OFF':\n        print(\"Screen turned off\")\n
    "},{"location":"qsl4a/core/events/#_13","title":"\u4f20\u611f\u5668\u4e8b\u4ef6\u5904\u7406","text":"
    # \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u5904\u7406\u4f20\u611f\u5668\u4e8b\u4ef6\nfor _ in range(100):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'sensors':\n        data = event['data']\n        print(f\"Accel: {data['xforce']}, {data['yforce']}, {data['zforce']}\")\n\ndroid.stopSensing()\n
    "},{"location":"qsl4a/core/events/#_14","title":"\u5e38\u89c1\u4e8b\u4ef6\u7c7b\u578b","text":"\u4e8b\u4ef6\u540d\u79f0 \u63cf\u8ff0 \u6765\u6e90 sensors \u4f20\u611f\u5668\u6570\u636e\u66f4\u65b0 startSensing* location GPS \u4f4d\u7f6e\u66f4\u65b0 startLocating phone \u7535\u8bdd\u72b6\u6001\u53d8\u5316 startTrackingPhoneState signal \u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316 startTrackingSignalStrength screen \u622a\u56fe\u5c31\u7eea fullGetScreenShot dialog \u5bf9\u8bdd\u6846\u54cd\u5e94 dialogShow*"},{"location":"qsl4a/core/events/#_15","title":"\u4e8b\u4ef6\u6570\u636e\u7ed3\u6784","text":"
    {\n    'name': 'event_name',\n    'data': {\n        # \u4e8b\u4ef6\u7279\u5b9a\u6570\u636e\n    },\n    'time': 1234567890  # \u65f6\u95f4\u6233\n}\n
    "},{"location":"qsl4a/core/intent/","title":"Intent \u7cfb\u7edf","text":"

    Android Intent \u7528\u4e8e\u542f\u52a8\u6d3b\u52a8\u3001\u53d1\u9001\u5e7f\u64ad\u548c\u5e94\u7528\u95f4\u901a\u4fe1\u3002QSL4A \u901a\u8fc7 Intent \u6a21\u5757\u63d0\u4f9b\u5b8c\u6574\u7684 Intent \u652f\u6301\u3002

    "},{"location":"qsl4a/core/intent/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
    import androidhelper\ndon = androidhelper.Android()\n
    "},{"location":"qsl4a/core/intent/#intent_1","title":"Intent \u5e38\u91cf","text":"

    \u901a\u8fc7 droid.Intent \u8bbf\u95ee\uff1a

    "},{"location":"qsl4a/core/intent/#_2","title":"\u64cd\u4f5c","text":"\u5e38\u91cf \u503c \u7528\u9014 ACTION_MAIN android.intent.action.MAIN \u5e94\u7528\u5165\u53e3\u70b9 ACTION_VIEW android.intent.action.VIEW \u67e5\u770b\u5185\u5bb9 ACTION_EDIT android.intent.action.EDIT \u7f16\u8f91\u5185\u5bb9 ACTION_PICK android.intent.action.PICK \u9009\u62e9\u9879\u76ee ACTION_SEND android.intent.action.SEND \u5206\u4eab\u5185\u5bb9 ACTION_SEARCH android.intent.action.SEARCH \u641c\u7d22"},{"location":"qsl4a/core/intent/#_3","title":"\u6807\u5fd7","text":"\u5e38\u91cf \u503c \u7528\u9014 FLAG_ACTIVITY_NEW_TASK 268435456 \u542f\u52a8\u65b0\u4efb\u52a1 FLAG_ACTIVITY_CLEAR_TASK 32768 \u6e05\u9664\u4efb\u52a1\u5806\u6808 FLAG_ACTIVITY_NEW_DOCUMENT 524288 \u65b0\u6587\u6863\u6a21\u5f0f"},{"location":"qsl4a/core/intent/#_4","title":"\u9644\u52a0\u6570\u636e","text":"\u5e38\u91cf \u7528\u9014 EXTRA_TEXT \u6587\u672c\u5185\u5bb9 EXTRA_STREAM \u6587\u4ef6 URI EXTRA_SUBJECT \u4e3b\u9898\u884c EXTRA_EMAIL \u7535\u5b50\u90ae\u4ef6\u5730\u5740"},{"location":"qsl4a/core/intent/#_5","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/intent/#makeintent","title":"makeIntent()","text":"

    \u521b\u5efa Intent \u5bf9\u8c61\u3002

    makeIntent(action, uri=None, type=None, extras=None, categories=None,\n           packagename=None, classname=None, flags=None)\n

    \u53c2\u6570\uff1a - action (str): Intent \u64cd\u4f5c\uff08\u4f8b\u5982 droid.Intent.ACTION_VIEW\uff09 - uri (str, optional): \u6570\u636e URI - type (str, optional): MIME \u7c7b\u578b - extras (dict, optional): \u9644\u52a0\u6570\u636e - categories (list, optional): Intent \u7c7b\u522b - packagename (str, optional): \u76ee\u6807\u5305 - classname (str, optional): \u76ee\u6807\u7c7b - flags (int, optional): Intent \u6807\u5fd7

    \u8fd4\u56de\uff1a Intent \u5bf9\u8c61

    "},{"location":"qsl4a/core/intent/#startactivityintent","title":"startActivityIntent()","text":"

    \u4f7f\u7528 Intent \u542f\u52a8 Activity\u3002

    startActivityIntent(intent, wait=None)\n

    \u53c2\u6570\uff1a - intent: makeIntent() \u8fd4\u56de\u7684 Intent \u5bf9\u8c61 - wait (bool, optional): \u963b\u585e\u76f4\u5230\u6d3b\u52a8\u5173\u95ed

    "},{"location":"qsl4a/core/intent/#startactivityforresultintent","title":"startActivityForResultIntent()","text":"

    \u542f\u52a8\u6d3b\u52a8\u5e76\u7b49\u5f85\u7ed3\u679c\u3002

    startActivityForResultIntent(intent)\n

    \u8fd4\u56de\uff1a Activity \u7ed3\u679c

    "},{"location":"qsl4a/core/intent/#sendbroadcastintent","title":"sendBroadcastIntent()","text":"

    \u53d1\u9001\u5e7f\u64ad\u3002

    sendBroadcastIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#view","title":"view()","text":"

    \u901a\u8fc7 URI \u67e5\u770b\u5185\u5bb9\u3002

    view(uri, type=None, extras=None)\n
    "},{"location":"qsl4a/core/intent/#pick","title":"pick()","text":"

    \u4ece URI \u9009\u62e9\u5185\u5bb9\u3002

    pick(uri)\n
    "},{"location":"qsl4a/core/intent/#intent_2","title":"\u5e38\u89c1 Intent \u65b9\u6cd5)","text":""},{"location":"qsl4a/core/intent/#scanbarcode","title":"scanBarcode()","text":"

    \u542f\u52a8\u6761\u7801\u626b\u63cf\u5668\u3002

    scanBarcode()\n

    \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/core/intent/#send","title":"send()","text":"

    \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u5185\u5bb9\u3002

    send(type, content)\n

    \u53c2\u6570\uff1a - type (str): MIME \u7c7b\u578b - content (str): \u8981\u5206\u4eab\u7684\u5185\u5bb9

    "},{"location":"qsl4a/core/intent/#sendtext","title":"sendText()","text":"

    \u53d1\u9001\u6587\u672c\u5185\u5bb9\u3002

    sendText(text)\n

    \u53c2\u6570\uff1a - text (str): \u8981\u53d1\u9001\u7684\u6587\u672c

    "},{"location":"qsl4a/core/intent/#sendemail","title":"sendEmail()","text":"

    \u53d1\u9001\u7535\u5b50\u90ae\u4ef6\u3002

    sendEmail(to, subject, body, attachment=None)\n

    \u53c2\u6570\uff1a - to (str or list): \u6536\u4ef6\u4eba\u7535\u5b50\u90ae\u4ef6\u5730\u5740 - subject (str): \u7535\u5b50\u90ae\u4ef6\u4e3b\u9898 - body (str): \u7535\u5b50\u90ae\u4ef6\u6b63\u6587 - attachment (str, optional): \u9644\u4ef6\u6587\u4ef6\u8def\u5f84

    "},{"location":"qsl4a/core/intent/#pathtouri","title":"pathToUri()","text":"

    \u5c06\u6587\u4ef6\u8def\u5f84\u8f6c\u6362\u4e3a\u5185\u5bb9 URI\u3002

    pathToUri(path)\n

    \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

    \u8fd4\u56de\uff1a \u5185\u5bb9 URI \u5b57\u7b26\u4e32

    "},{"location":"qsl4a/core/intent/#openfile","title":"openFile()","text":"

    \u7528\u9002\u5f53\u7684\u5e94\u7528\u7a0b\u5e8f\u6253\u5f00\u6587\u4ef6\u3002

    openFile(path)\n

    \u53c2\u6570\uff1a - path (str): \u8981\u6253\u5f00\u7684\u6587\u4ef6\u8def\u5f84

    "},{"location":"qsl4a/core/intent/#sendfile","title":"sendFile()","text":"

    \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u6587\u4ef6\u3002

    sendFile(path)\n

    \u53c2\u6570\uff1a - path (str): \u8981\u53d1\u9001\u7684\u6587\u4ef6\u8def\u5f84

    "},{"location":"qsl4a/core/intent/#getpathtype","title":"getPathType()","text":"

    \u83b7\u53d6\u6587\u4ef6\u8def\u5f84\u7684 MIME \u7c7b\u578b\u3002

    getPathType(path)\n

    \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

    \u8fd4\u56de\uff1a MIME \u7c7b\u578b\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/core/intent/#viewmap","title":"viewMap()","text":"

    \u5728\u6307\u5b9a\u4f4d\u7f6e\u6253\u5f00\u5730\u56fe\u3002

    viewMap(latitude, longitude)\n

    \u53c2\u6570\uff1a - latitude (float): \u7eac\u5ea6 - longitude (float): \u7ecf\u5ea6

    "},{"location":"qsl4a/core/intent/#viewcontacts","title":"viewContacts()","text":"

    \u6253\u5f00\u8054\u7cfb\u4eba\u5e94\u7528\u3002

    viewContacts()\n
    "},{"location":"qsl4a/core/intent/#search","title":"search()","text":"

    \u6267\u884c\u7f51\u7edc\u641c\u7d22\u3002

    search(query)\n

    \u53c2\u6570\uff1a - query (str): \u641c\u7d22\u67e5\u8be2

    "},{"location":"qsl4a/core/intent/#viewhtml","title":"viewHtml()","text":"

    \u67e5\u770b HTML \u5185\u5bb9\u3002

    viewHtml(content, encoding=None)\n

    \u53c2\u6570\uff1a - content (str): HTML \u5185\u5bb9 - encoding (str, optional): \u5b57\u7b26\u7f16\u7801

    "},{"location":"qsl4a/core/intent/#webviewshow","title":"webViewShow()","text":"

    \u5728 WebView \u4e2d\u663e\u793a\u7f51\u9875\u5185\u5bb9\u3002\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 viewHtml\u3002

    webViewShow(url)\n

    \u53c2\u6570\uff1a - url (str): \u7f51\u9875 URL

    "},{"location":"qsl4a/core/intent/#editoropen","title":"editorOpen()","text":"

    \u6253\u5f00\u6587\u672c\u7f16\u8f91\u5668\u3002

    editorOpen(path=None, create=False)\n

    \u53c2\u6570\uff1a - path (str, optional): \u8981\u7f16\u8f91\u7684\u6587\u4ef6\u8def\u5f84 - create (bool, optional): \u5982\u679c\u4e0d\u5b58\u5728\u5219\u521b\u5efa

    "},{"location":"qsl4a/core/intent/#uri","title":"\u8f85\u52a9\u7c7b\uff1aUri","text":"

    \u521b\u5efa Intent \u7684 URI \u5bf9\u8c61\uff1a

    from androidhelper.Intent import Uri\n\nuri = Uri(\"file:///sdcard/test.txt\")\n
    "},{"location":"qsl4a/core/intent/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/intent/#_7","title":"\u6253\u5f00\u7f51\u9875","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"http://www.example.com\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#_8","title":"\u5206\u4eab\u6587\u672c","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_TEXT: \"Hello from QPython!\",\n        droid.Intent.EXTRA_SUBJECT: \"Test\"\n    },\n    type=\"text/plain\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#_9","title":"\u6253\u5f00\u6587\u4ef6","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"file:///sdcard/document.pdf\",\n    type=\"application/pdf\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#_10","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":"
    result = droid.pickContact()\ncontact_uri = result.result\n
    "},{"location":"qsl4a/core/intent/#_11","title":"\u53d1\u9001\u7535\u5b50\u90ae\u4ef6","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_EMAIL: [\"test@example.com\"],\n        droid.Intent.EXTRA_SUBJECT: \"Hello\",\n        droid.Intent.EXTRA_TEXT: \"Message body\"\n    },\n    type=\"message/rfc822\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#_12","title":"\u6253\u5f00\u5e94\u7528","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_MAIN,\n    packagename=\"com.android.settings\",\n    classname=\"com.android.settings.Settings\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/hardware/bluetooth/","title":"\u84dd\u7259 API","text":"

    \u63a7\u5236\u84dd\u7259\u9002\u914d\u5668\u5e76\u4e0e\u84dd\u7259\u8bbe\u5907\u901a\u4fe1\u3002

    "},{"location":"qsl4a/hardware/bluetooth/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/hardware/bluetooth/#togglebluetoothstate","title":"toggleBluetoothState()","text":"

    \u6253\u5f00/\u5173\u95ed\u84dd\u7259\u3002

    toggleBluetoothState(enabled=None, prompt=True)\n

    \u53c2\u6570\uff1a - enabled (bool): True=\u5f00\uff0cFalse=\u5173\uff0cNone=\u5207\u6362 - prompt (bool): \u663e\u793a\u7528\u6237\u63d0\u793a

    "},{"location":"qsl4a/hardware/bluetooth/#checkbluetoothstate","title":"checkBluetoothState()","text":"

    \u68c0\u67e5\u84dd\u7259\u662f\u5426\u5df2\u542f\u7528\u3002

    checkBluetoothState()\n

    \u8fd4\u56de\uff1a True/False

    "},{"location":"qsl4a/hardware/bluetooth/#getlocalname","title":"GetLocalName()","text":"

    \u83b7\u53d6\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

    GetLocalName()\n
    "},{"location":"qsl4a/hardware/bluetooth/#setlocalname","title":"SetLocalName()","text":"

    \u8bbe\u7f6e\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

    SetLocalName(name)\n
    "},{"location":"qsl4a/hardware/bluetooth/#getscanmode","title":"GetScanMode()","text":"

    \u83b7\u53d6\u53ef\u53d1\u73b0\u6027\u6a21\u5f0f\u3002

    GetScanMode()\n

    \u8fd4\u56de\uff1a - -1: \u5df2\u7981\u7528 - 0: \u4e0d\u53ef\u53d1\u73b0\uff0c\u4e0d\u53ef\u8fde\u63a5 - 1: \u53ef\u8fde\u63a5\uff0c\u4e0d\u53ef\u53d1\u73b0 - 3: \u53ef\u8fde\u63a5\u4e14\u53ef\u53d1\u73b0

    "},{"location":"qsl4a/hardware/bluetooth/#makediscoverable","title":"MakeDiscoverable()","text":"

    \u4f7f\u8bbe\u5907\u53ef\u53d1\u73b0\u3002

    MakeDiscoverable(duration=300)\n

    \u53c2\u6570\uff1a - duration (int): \u53ef\u53d1\u73b0\u7684\u79d2\u6570

    "},{"location":"qsl4a/hardware/bluetooth/#_2","title":"\u53d1\u73b0","text":""},{"location":"qsl4a/hardware/bluetooth/#discoverystart","title":"DiscoveryStart()","text":"

    \u5f00\u59cb\u8bbe\u5907\u53d1\u73b0\u3002

    DiscoveryStart()\n
    "},{"location":"qsl4a/hardware/bluetooth/#discoverycancel","title":"DiscoveryCancel()","text":"

    \u53d6\u6d88\u53d1\u73b0\u3002

    DiscoveryCancel()\n
    "},{"location":"qsl4a/hardware/bluetooth/#getreceiveddevices","title":"GetReceivedDevices()","text":"

    \u83b7\u53d6\u53d1\u73b0\u7684\u8bbe\u5907\u3002

    GetReceivedDevices()\n

    \u8fd4\u56de\uff1a \u8bbe\u5907\u4fe1\u606f\u5b57\u5178\u5217\u8868

    "},{"location":"qsl4a/hardware/bluetooth/#getbondeddevices","title":"GetBondedDevices()","text":"

    \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\u3002

    GetBondedDevices()\n

    \u8fd4\u56de\uff1a \u914d\u5bf9\u8bbe\u5907\u4fe1\u606f\u5217\u8868

    "},{"location":"qsl4a/hardware/bluetooth/#_3","title":"\u8fde\u63a5","text":""},{"location":"qsl4a/hardware/bluetooth/#connect","title":"Connect()","text":"

    \u8fde\u63a5\u5230\u8bbe\u5907\u3002

    Connect(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", address=None)\n

    \u53c2\u6570\uff1a - uuid (str): \u670d\u52a1 UUID - address (str): \u8bbe\u5907\u5730\u5740\uff08None = \u663e\u793a\u9009\u62e9\u5668\uff09

    \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/hardware/bluetooth/#accept","title":"Accept()","text":"

    \u63a5\u53d7\u4f20\u5165\u8fde\u63a5\u3002

    Accept(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", timeout=0)\n
    "},{"location":"qsl4a/hardware/bluetooth/#activeconnections","title":"ActiveConnections()","text":"

    \u68c0\u67e5\u6d3b\u52a8\u8fde\u63a5\u3002

    ActiveConnections()\n
    "},{"location":"qsl4a/hardware/bluetooth/#stop","title":"Stop()","text":"

    \u65ad\u5f00\u8fde\u63a5\u3002

    Stop(connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#_4","title":"\u901a\u4fe1","text":""},{"location":"qsl4a/hardware/bluetooth/#write","title":"Write()","text":"

    \u53d1\u9001 ASCII \u6570\u636e\u3002

    Write(ascii, connID=\"\")\n
    "},{"location":"qsl4a/hardware/bluetooth/#writebinary","title":"WriteBinary()","text":"

    \u53d1\u9001\u4e8c\u8fdb\u5236\u6570\u636e\uff08base64 \u7f16\u7801\uff09\u3002

    WriteBinary(base64, connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#read","title":"Read()","text":"

    \u8bfb\u53d6 ASCII \u6570\u636e\u3002

    Read(bufferSize=4096, connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#readbinary","title":"ReadBinary()","text":"

    \u8bfb\u53d6\u4e8c\u8fdb\u5236\u6570\u636e\u3002

    ReadBinary(bufferSize=4096, connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#readline","title":"ReadLine()","text":"

    \u8bfb\u53d6\u4e00\u884c\u3002

    ReadLine(connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#readready","title":"ReadReady()","text":"

    \u68c0\u67e5\u662f\u5426\u6709\u53ef\u7528\u6570\u636e\u3002

    ReadReady(connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u7528\u84dd\u7259\ndroid.toggleBluetoothState(True)\n\n# \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\ndevices = droid.GetBondedDevices().result\nfor dev in devices:\n    print(f\"{dev['name']}: {dev['address']}\")\n\n# \u8fde\u63a5\u5230\u8bbe\u5907\ndroid.Connect(address=\"00:11:22:33:44:55\")\n\n# \u53d1\u9001\u6570\u636e\ndroid.Write(\"Hello Bluetooth!\")\n\n# \u8bfb\u53d6\u54cd\u5e94\ndata = droid.Read(1024).result\n
    "},{"location":"qsl4a/hardware/camera/","title":"\u76f8\u673a API","text":"

    \u62cd\u6444\u7167\u7247\u548c\u5f55\u5236\u89c6\u9891\u3002

    "},{"location":"qsl4a/hardware/camera/#_1","title":"\u7167\u7247\u62cd\u6444","text":""},{"location":"qsl4a/hardware/camera/#takepicture","title":"takePicture()","text":"

    \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u6444\u7167\u7247\u3002

    takePicture(path=None)\n

    \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8fd4\u56de\u56fe\u50cf\u6570\u636e

    \u8fd4\u56de\uff1a \u56fe\u50cf\u8def\u5f84\u6216\u56fe\u50cf\u6570\u636e

    "},{"location":"qsl4a/hardware/camera/#cameracapturepicture","title":"cameraCapturePicture()","text":"

    \u4f7f\u7528\u9ad8\u7ea7\u76f8\u673a\u63a7\u5236\u62cd\u6444\u7167\u7247\u3002

    cameraCapturePicture(targetPath=None, cameraId=0, useAutoFocus=True)\n

    \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - useAutoFocus (bool): \u542f\u7528\u81ea\u52a8\u5bf9\u7126

    \u8fd4\u56de\uff1a \u62cd\u6444\u7684\u56fe\u50cf\u8def\u5f84

    "},{"location":"qsl4a/hardware/camera/#camerasettorchmode","title":"cameraSetTorchMode()","text":"

    \u63a7\u5236\u76f8\u673a\u95ea\u5149\u706f/\u624b\u7535\u7b52\u3002

    cameraSetTorchMode(enabled)\n

    \u53c2\u6570\uff1a - enabled (bool): True \u6253\u5f00\uff0cFalse \u5173\u95ed

    \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/hardware/camera/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

    \u622a\u56fe\u3002

    imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

    \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

    "},{"location":"qsl4a/hardware/camera/#_2","title":"\u89c6\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#takevideo","title":"takeVideo()","text":"

    \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\u3002

    takeVideo(path=None, quality=1)\n

    \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-4\uff09 - 0: 160x120 - 1: 320x240 - 2: 352x288 - 3: 640x480 - 4: 800x480

    "},{"location":"qsl4a/hardware/camera/#recordercapturevideo","title":"recorderCaptureVideo()","text":"

    \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\u3002

    recorderCaptureVideo(targetPath=None, duration=10, cameraId=0, quality=8)\n

    \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - duration (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a10\uff09 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-8\uff0c\u8d8a\u9ad8\u8d8a\u597d\uff09

    \u8fd4\u56de\uff1a \u89c6\u9891\u6587\u4ef6\u8def\u5f84

    "},{"location":"qsl4a/hardware/camera/#recordaudio","title":"recordAudio()","text":"

    \u5f55\u5236\u97f3\u9891\u3002

    recordAudio()\n

    \u8fd4\u56de\uff1a \u97f3\u9891\u6587\u4ef6\u8def\u5f84

    "},{"location":"qsl4a/hardware/camera/#_3","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

    \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\u3002

    recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

    \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\uff09 - targetPixels (int): \u5206\u8fa8\u7387 - frameRate (int): FPS - bitRate (int): \u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa - autoStart (bool): \u7acb\u5373\u5f00\u59cb

    "},{"location":"qsl4a/hardware/camera/#recorderstart","title":"recorderStart()","text":"

    \u5f00\u59cb\u5f55\u5236\u3002

    recorderStart()\n
    "},{"location":"qsl4a/hardware/camera/#recorderpause","title":"recorderPause()","text":"

    \u6682\u505c\u5f55\u5236\u3002

    recorderPause()\n
    "},{"location":"qsl4a/hardware/camera/#recorderresume","title":"recorderResume()","text":"

    \u6062\u590d\u5f55\u5236\u3002

    recorderResume()\n
    "},{"location":"qsl4a/hardware/camera/#_4","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/camera/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

    \u5f00\u59cb\u97f3\u91cf\u68c0\u6d4b\u3002

    recorderSoundVolumeDetect(interval=100)\n
    "},{"location":"qsl4a/hardware/camera/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

    \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

    recorderSoundVolumeGetDb()\n
    "},{"location":"qsl4a/hardware/camera/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u7167\nphoto_path = droid.takePicture(\"/sdcard/photo.jpg\").result\nprint(f\"Photo saved: {photo_path}\")\n\n# \u4f7f\u7528\u524d\u7f6e\u76f8\u673a\u548c\u81ea\u52a8\u5bf9\u7126\u62cd\u7167\ncamera_path = droid.cameraCapturePicture(\"/sdcard/selfie.jpg\", cameraId=1, useAutoFocus=True).result\nprint(f\"Front camera photo: {camera_path}\")\n\n# \u63a7\u5236\u95ea\u5149\u706f\ndroid.cameraSetTorchMode(True)  # \u6253\u5f00\u95ea\u5149\u706f\n\n# \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\nvideo_path = droid.takeVideo(\"/sdcard/video.mp4\", quality=3).result\nprint(f\"Video saved: {video_path}\")\n\n# \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\nvideo_path = droid.recorderCaptureVideo(\"/sdcard/movie.mp4\", duration=30, cameraId=0, quality=8).result\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n
    "},{"location":"qsl4a/hardware/recorder/","title":"\u97f3\u9891\u5f55\u5236 API","text":"

    \u4ece\u9ea6\u514b\u98ce\u548c\u8bbe\u5907\u5c4f\u5e55\u5f55\u5236\u97f3\u9891\u3002

    "},{"location":"qsl4a/hardware/recorder/#_1","title":"\u97f3\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recordaudio","title":"recordAudio()","text":"

    \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\u3002

    recordAudio()\n

    \u8fd4\u56de\uff1a \u5f55\u5236\u7684\u97f3\u9891\u6587\u4ef6\u8def\u5f84

    "},{"location":"qsl4a/hardware/recorder/#recorderstartmicrophone","title":"recorderStartMicrophone()","text":"

    \u5f00\u59cb\u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\u3002

    recorderStartMicrophone(targetPath=None)\n

    \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u5f55\u5236\u7684\u8def\u5f84

    "},{"location":"qsl4a/hardware/recorder/#_2","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

    \u5f00\u59cb\u5e26\u97f3\u9891\u7684\u5c4f\u5e55\u5f55\u5236\u3002

    recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

    \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\u97f3\u9891\uff09 - targetPixels (int): \u76ee\u6807\u5206\u8fa8\u7387\uff08\u50cf\u7d20\uff09 - frameRate (int): \u6bcf\u79d2\u5e27\u6570\uff08\u9ed8\u8ba4\uff1a30\uff09 - bitRate (int): \u89c6\u9891\u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa\u89c6\u9891 - autoStart (bool): \u7acb\u5373\u5f00\u59cb\u5f55\u5236

    \u8fd4\u56de\uff1a \u64cd\u4f5c\u7ed3\u679c

    "},{"location":"qsl4a/hardware/recorder/#recorderstart","title":"recorderStart()","text":"

    \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\uff08\u5f53 autoStart=False \u65f6\uff09\u3002

    recorderStart()\n
    "},{"location":"qsl4a/hardware/recorder/#recorderpause","title":"recorderPause()","text":"

    \u6682\u505c\u6b63\u5728\u8fdb\u884c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

    recorderPause()\n
    "},{"location":"qsl4a/hardware/recorder/#recorderresume","title":"recorderResume()","text":"

    \u6062\u590d\u6682\u505c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

    recorderResume()\n
    "},{"location":"qsl4a/hardware/recorder/#_3","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/recorder/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

    \u5f00\u59cb\u76d1\u63a7\u97f3\u91cf\u7ea7\u522b\u3002

    recorderSoundVolumeDetect(interval=100)\n

    \u53c2\u6570\uff1a - interval (int): \u68c0\u6d4b\u95f4\u9694\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a100\uff09

    "},{"location":"qsl4a/hardware/recorder/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

    \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

    recorderSoundVolumeGetDb()\n

    \u8fd4\u56de\uff1a \u5f53\u524d\u97f3\u91cf\u7ea7\u522b\uff08dB\uff09

    "},{"location":"qsl4a/hardware/recorder/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\nprint(\"Recording audio...\")\naudio_path = droid.recordAudio().result\nprint(f\"Saved to: {audio_path}\")\n\n# \u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\ndroid.recorderStartMicrophone(\"/sdcard/my_recording.mp3\")\ntime.sleep(5)\ndroid.recorderStop()\n\n# \u5e26\u97f3\u9891\u5f55\u5236\u5c4f\u5e55\nprint(\"Starting screen recording...\")\ndroid.recorderStartScreenRecord(\n    path=\"/sdcard/screen_record.mp4\",\n    audio=1,\n    frameRate=30,\n    autoStart=True\n)\ntime.sleep(10)\ndroid.recorderStop()\n\n# \u76d1\u63a7\u97f3\u91cf\ndroid.recorderSoundVolumeDetect(interval=100)\ntime.sleep(3)\nvolume = droid.recorderSoundVolumeGetDb().result\nprint(f\"Current volume: {volume} dB\")\n
    "},{"location":"qsl4a/hardware/usbserial/","title":"USB \u4e3b\u673a\u4e32\u884c API","text":"

    \u4e0e USB \u4e32\u884c\u8bbe\u5907\u901a\u4fe1\uff08\u9700\u8981 USB OTG \u652f\u6301\u548c Android 3.1+\uff09\u3002

    "},{"location":"qsl4a/hardware/usbserial/#usb","title":"USB \u4e32\u884c\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialopen","title":"usbHostSerialOpen()","text":"

    \u6253\u5f00\u4e0e USB \u4e32\u884c\u8bbe\u5907\u7684\u8fde\u63a5\u3002

    usbHostSerialOpen(device, baudRate=9600)\n

    \u53c2\u6570\uff1a - device (str): USB \u8bbe\u5907\u8def\u5f84\u6216\u6807\u8bc6\u7b26 - baudRate (int): \u6ce2\u7279\u7387\uff08\u9ed8\u8ba4\uff1a9600\uff09

    \u8fd4\u56de\uff1a \u5982\u679c\u6253\u5f00\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialclose","title":"usbHostSerialClose()","text":"

    \u5173\u95ed USB \u4e32\u884c\u8fde\u63a5\u3002

    usbHostSerialClose()\n
    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialread","title":"usbHostSerialRead()","text":"

    \u4ece USB \u4e32\u884c\u8bfb\u53d6\u6570\u636e\u3002

    usbHostSerialRead(bufferSize=1024)\n

    \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570\uff08\u9ed8\u8ba4\uff1a1024\uff09

    \u8fd4\u56de\uff1a \u8bfb\u53d6\u7684\u6570\u636e\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwrite","title":"usbHostSerialWrite()","text":"

    \u5411 USB \u4e32\u884c\u5199\u5165\u6570\u636e\u3002

    usbHostSerialWrite(data)\n

    \u53c2\u6570\uff1a - data (str): \u8981\u5199\u5165\u7684\u5b57\u7b26\u4e32\u6570\u636e

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialavailable","title":"usbHostSerialAvailable()","text":"

    \u68c0\u67e5\u662f\u5426\u6709\u53ef\u8bfb\u53d6\u7684\u6570\u636e\u3002

    usbHostSerialAvailable()\n

    \u8fd4\u56de\uff1a \u53ef\u7528\u5b57\u8282\u6570

    "},{"location":"qsl4a/hardware/usbserial/#_1","title":"\u914d\u7f6e\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetbaudrate","title":"usbHostSerialSetBaudRate()","text":"

    \u8bbe\u7f6e\u6ce2\u7279\u7387\u3002

    usbHostSerialSetBaudRate(baudRate)\n

    \u53c2\u6570\uff1a - baudRate (int): \u6ce2\u7279\u7387

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetdatabits","title":"usbHostSerialSetDataBits()","text":"

    \u8bbe\u7f6e\u6570\u636e\u4f4d\uff085\u30016\u30017 \u6216 8\uff09\u3002

    usbHostSerialSetDataBits(dataBits)\n

    \u53c2\u6570\uff1a - dataBits (int): \u6570\u636e\u4f4d\uff085-8\uff09

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetstopbits","title":"usbHostSerialSetStopBits()","text":"

    \u8bbe\u7f6e\u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09\u3002

    usbHostSerialSetStopBits(stopBits)\n

    \u53c2\u6570\uff1a - stopBits (float): \u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetparity","title":"usbHostSerialSetParity()","text":"

    \u8bbe\u7f6e\u6821\u9a8c\u4f4d\uff08\u65e0\u3001\u5947\u3001\u5076\u3001\u6807\u8bb0\u3001\u7a7a\u683c\uff09\u3002

    usbHostSerialSetParity(parity)\n

    \u53c2\u6570\uff1a - parity (str): \u6821\u9a8c\u6a21\u5f0f\uff08'none'\u3001'odd'\u3001'even'\u3001'mark'\u3001'space'\uff09

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetflowcontrol","title":"usbHostSerialSetFlowControl()","text":"

    \u8bbe\u7f6e\u6d41\u63a7\u5236\uff08\u65e0\u3001\u786c\u4ef6\u3001\u8f6f\u4ef6\uff09\u3002

    usbHostSerialSetFlowControl(flowControl)\n

    \u53c2\u6570\uff1a - flowControl (str): \u6d41\u63a7\u5236\u6a21\u5f0f\uff08'none'\u3001'hardware'\u3001'software'\uff09

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialreadhex","title":"usbHostSerialReadHex()","text":"

    \u4ee5\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u8bfb\u53d6\u6570\u636e\u3002

    usbHostSerialReadHex(bufferSize=1024)\n

    \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570

    \u8fd4\u56de\uff1a \u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwritehex","title":"usbHostSerialWriteHex()","text":"

    \u4ece\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u5199\u5165\u6570\u636e\u3002

    usbHostSerialWriteHex(hexString)\n

    \u53c2\u6570\uff1a - hexString (str): \u8981\u5199\u5165\u7684\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/hardware/usbserial/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6253\u5f00 USB \u4e32\u884c\u8fde\u63a5\nif droid.usbHostSerialOpen(\"/dev/bus/usb/001/001\", 115200).result:\n    print(\"USB serial opened\")\n\n    # \u5199\u5165\u6570\u636e\n    droid.usbHostSerialWrite(\"AT\\r\")\n\n    # \u8bfb\u53d6\u54cd\u5e94\n    response = droid.usbHostSerialRead(1024).result\n    print(f\"Response: {response}\")\n\n    # \u6216\u4f7f\u7528\u5341\u516d\u8fdb\u5236\n    droid.usbHostSerialWriteHex(\"41540D0A\")  # \"AT\\r\\n\"\n\n    # \u5173\u95ed\u8fde\u63a5\n    droid.usbHostSerialClose()\n

    \u6ce8\u610f\uff1a USB \u4e32\u884c\u9700\u8981\uff1a - Android 3.1+ (API 12) - USB OTG \u7ebf/\u9002\u914d\u5668 - \u8bbe\u5907\u4e0a\u7684 USB \u4e3b\u673a\u6a21\u5f0f\u652f\u6301 - \u517c\u5bb9\u7684\u4e32\u884c\u8bbe\u5907

    "},{"location":"qsl4a/hardware/webcam/","title":"\u7f51\u7edc\u6444\u50cf\u5934 API","text":"

    \u4f7f\u7528 MJPEG \u4ece\u8bbe\u5907\u76f8\u673a\u6d41\u5f0f\u4f20\u8f93\u89c6\u9891\u3002

    "},{"location":"qsl4a/hardware/webcam/#mjpeg","title":"MJPEG \u6d41\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#webcamstart","title":"webcamStart()","text":"

    \u4ece\u7f51\u7edc\u6444\u50cf\u5934\u542f\u52a8 MJPEG \u6d41\u3002

    webcamStart(resolutionLevel=0, jpegQuality=20, port=0)\n

    \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf 1-100\uff08\u9ed8\u8ba4\uff1a20\uff09 - port (int): \u7aef\u53e3\u53f7\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\uff09

    \u8fd4\u56de\uff1a \u6d41\u7684 (\u5730\u5740, \u7aef\u53e3) \u5143\u7ec4

    "},{"location":"qsl4a/hardware/webcam/#webcamadjustquality","title":"webcamAdjustQuality()","text":"

    \u8c03\u6574\u6d3b\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u7684\u8d28\u91cf\u3002

    webcamAdjustQuality(resolutionLevel=0, jpegQuality=20)\n

    \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b - jpegQuality (int): JPEG \u8d28\u91cf 1-100

    "},{"location":"qsl4a/hardware/webcam/#webcamstop","title":"webcamStop()","text":"

    \u505c\u6b62\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u3002

    webcamStop()\n
    "},{"location":"qsl4a/hardware/webcam/#_1","title":"\u76f8\u673a\u9884\u89c8\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#camerastartpreview","title":"cameraStartPreview()","text":"

    \u5f00\u59cb\u5e26\u4e8b\u4ef6\u751f\u6210\u7684\u76f8\u673a\u9884\u89c8\u6a21\u5f0f\u3002

    cameraStartPreview(resolutionLevel=0, jpegQuality=20, filepath=None)\n

    \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf\uff08\u9ed8\u8ba4\uff1a20\uff09 - filepath (str, optional): \u4fdd\u5b58\u9884\u89c8\u5e27\u7684\u6587\u4ef6\u8def\u5f84

    \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

    \u6ce8\u610f\uff1a \u751f\u6210\u5e26\u6709\u5e27\u6570\u636e\u7684 'preview' \u4e8b\u4ef6\u3002

    "},{"location":"qsl4a/hardware/webcam/#camerastoppreview","title":"cameraStopPreview()","text":"

    \u505c\u6b62\u76f8\u673a\u9884\u89c8\u3002

    cameraStopPreview()\n
    "},{"location":"qsl4a/hardware/webcam/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\nstream_info = droid.webcamStart(\n    resolutionLevel=0,\n    jpegQuality=30,\n    port=8080\n).result\nprint(f\"Stream available at {stream_info[0]}:{stream_info[1]}\")\n\n# \u6d41\u5f0f\u4f20\u8f93\u65f6\u8c03\u6574\u8d28\u91cf\ntime.sleep(5)\ndroid.webcamAdjustQuality(resolutionLevel=1, jpegQuality=50)\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.webcamStop()\n\n# \u6216\u4f7f\u7528\u9884\u89c8\u6a21\u5f0f\nprint(\"Starting preview...\")\ndroid.cameraStartPreview()\n\n# \u7b49\u5f85\u9884\u89c8\u4e8b\u4ef6\nfor i in range(10):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'preview':\n        print(f\"Got preview frame: {event['data']}\")\n\ndroid.cameraStopPreview()\n
    "},{"location":"qsl4a/media/image/","title":"\u56fe\u50cf\u5904\u7406 API","text":"

    \u538b\u7f29\u548c\u5904\u7406\u56fe\u50cf\u3002

    "},{"location":"qsl4a/media/image/#_1","title":"\u56fe\u50cf\u538b\u7f29","text":""},{"location":"qsl4a/media/image/#imagecompress","title":"imageCompress()","text":"

    \u538b\u7f29\u56fe\u50cf\u6587\u4ef6\u3002

    imageCompress(srcPath, destPath, targetByteSize=0, targetWidth=0, targetHeight=0)\n

    \u53c2\u6570\uff1a - srcPath (str): \u6e90\u56fe\u50cf\u8def\u5f84 - destPath (str): \u8f93\u51fa\u8def\u5f84 - targetByteSize (int): \u76ee\u6807\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff080 = \u65e0\u9650\u5236\uff09 - targetWidth (int): \u76ee\u6807\u5bbd\u5ea6\uff080 = \u539f\u59cb\uff09 - targetHeight (int): \u76ee\u6807\u9ad8\u5ea6\uff080 = \u539f\u59cb\uff09

    \u8fd4\u56de\uff1a \u538b\u7f29\u540e\u7684\u56fe\u50cf\u8def\u5f84

    "},{"location":"qsl4a/media/image/#_2","title":"\u622a\u56fe","text":""},{"location":"qsl4a/media/image/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

    \u622a\u53d6\u5c4f\u5e55\u3002

    imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

    \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

    \u8fd4\u56de\uff1a \u622a\u56fe\u8def\u5f84

    "},{"location":"qsl4a/media/image/#_3","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/image/#videoplay","title":"videoPlay()","text":"

    \u5728\u5168\u5c4f\u6a21\u5f0f\u4e0b\u64ad\u653e\u89c6\u9891\u6587\u4ef6\u3002

    videoPlay(path, wait=True)\n

    \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

    "},{"location":"qsl4a/media/image/#_4","title":"\u6761\u7801\u626b\u63cf","text":""},{"location":"qsl4a/media/image/#scanbarcodefromimage","title":"scanBarcodeFromImage()","text":"

    \u4ece\u56fe\u50cf\u6587\u4ef6\u626b\u63cf\u6761\u7801/\u4e8c\u7ef4\u7801\u3002

    scanBarcodeFromImage(path, compressRatio=0, x=0, y=0, width=0, height=0)\n

    \u53c2\u6570\uff1a - path (str): \u56fe\u50cf\u6587\u4ef6\u8def\u5f84 - compressRatio (int): \u538b\u7f29\u6bd4\uff080 = \u4e0d\u538b\u7f29\uff09 - x, y, width, height (int): \u8981\u626b\u63cf\u7684\u533a\u57df\uff080 = \u5b8c\u6574\u56fe\u50cf\uff09

    \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5185\u5bb9

    "},{"location":"qsl4a/media/image/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n\n# \u538b\u7f29\u56fe\u50cf\ncompressed = droid.imageCompress(\n    \"/sdcard/large_photo.jpg\",\n    \"/sdcard/compressed.jpg\",\n    targetByteSize=102400,  # \u76ee\u6807\u7ea6 100KB\n    targetWidth=1920,\n    targetHeight=1080\n).result\nprint(f\"Saved: {compressed}\")\n\n# \u64ad\u653e\u89c6\u9891\nvideo_path = \"/sdcard/movie.mp4\"\ndroid.videoPlay(video_path, wait=True)\n\n# \u4ece\u56fe\u50cf\u626b\u63cf\u6761\u7801\nresult = droid.scanBarcodeFromImage(\"/sdcard/qr_code.png\").result\nprint(f\"Barcode: {result}\")\n
    "},{"location":"qsl4a/media/mediaplayer/","title":"\u5a92\u4f53\u64ad\u653e\u5668 API","text":"

    \u63a7\u5236\u97f3\u9891\u548c\u89c6\u9891\u64ad\u653e\u3002

    "},{"location":"qsl4a/media/mediaplayer/#_1","title":"\u64ad\u653e\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplay","title":"mediaPlay()","text":"

    \u64ad\u653e\u5a92\u4f53\u6587\u4ef6\u3002

    mediaPlay(url, tag=\"default\", play=True)\n

    \u53c2\u6570\uff1a - url (str): \u5a92\u4f53\u6587\u4ef6\u8def\u5f84\u6216 URL - tag (str): \u64ad\u653e\u5668\u6807\u8bc6\u7b26 - play (bool): \u81ea\u52a8\u5f00\u59cb\u64ad\u653e

    "},{"location":"qsl4a/media/mediaplayer/#mediaplaystart","title":"mediaPlayStart()","text":"

    \u5f00\u59cb\u64ad\u653e\u3002

    mediaPlayStart(tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#mediaplaypause","title":"mediaPlayPause()","text":"

    \u6682\u505c\u64ad\u653e\u3002

    mediaPlayPause(tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#mediaplayclose","title":"mediaPlayClose()","text":"

    \u5173\u95ed\u64ad\u653e\u5668\u3002

    mediaPlayClose(tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#mediaplayseek","title":"mediaPlaySeek()","text":"

    \u8df3\u8f6c\u5230\u4f4d\u7f6e\u3002

    mediaPlaySeek(msec, tag=\"default\")\n

    \u53c2\u6570\uff1a - msec (int): \u4f4d\u7f6e\uff08\u6beb\u79d2\uff09

    "},{"location":"qsl4a/media/mediaplayer/#mediaplaysetlooping","title":"mediaPlaySetLooping()","text":"

    \u8bbe\u7f6e\u5faa\u73af\u6a21\u5f0f\u3002

    mediaPlaySetLooping(enabled, tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#_2","title":"\u64ad\u653e\u5668\u4fe1\u606f","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplayinfo","title":"mediaPlayInfo()","text":"

    \u83b7\u53d6\u64ad\u653e\u4fe1\u606f\u3002

    mediaPlayInfo(tag=\"default\")\n

    \u8fd4\u56de\uff1a \u5305\u542b\u65f6\u957f\u3001\u4f4d\u7f6e\u7b49\u7684\u5b57\u5178

    "},{"location":"qsl4a/media/mediaplayer/#mediaisplaying","title":"mediaIsPlaying()","text":"

    \u68c0\u67e5\u662f\u5426\u6b63\u5728\u64ad\u653e\u3002

    mediaIsPlaying(tag=\"default\")\n

    \u8fd4\u56de\uff1a True/False

    "},{"location":"qsl4a/media/mediaplayer/#mediaplaylist","title":"mediaPlayList()","text":"

    \u5217\u51fa\u6d3b\u52a8\u64ad\u653e\u5668\u3002

    mediaPlayList()\n
    "},{"location":"qsl4a/media/mediaplayer/#_3","title":"\u97f3\u91cf\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#getmediavolume","title":"getMediaVolume()","text":"

    \u83b7\u53d6\u5a92\u4f53\u97f3\u91cf\u3002

    getMediaVolume()\n

    \u8fd4\u56de\uff1a \u97f3\u91cf\u7ea7\u522b\uff080-15\uff09

    "},{"location":"qsl4a/media/mediaplayer/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

    \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

    getMaxMediaVolume()\n
    "},{"location":"qsl4a/media/mediaplayer/#getringervolume","title":"getRingerVolume()","text":"

    \u83b7\u53d6\u94c3\u58f0\u97f3\u91cf\u3002

    getRingerVolume()\n
    "},{"location":"qsl4a/media/mediaplayer/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

    \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

    getMaxRingerVolume()\n
    "},{"location":"qsl4a/media/mediaplayer/#_4","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/mediaplayer/#videoplay","title":"videoPlay()","text":"

    \u5168\u5c4f\u64ad\u653e\u89c6\u9891\u3002

    videoPlay(path, wait=True)\n

    \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210

    "},{"location":"qsl4a/media/mediaplayer/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u64ad\u653e\u97f3\u9891\ndroid.mediaPlay(\"/sdcard/music.mp3\", tag=\"music\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.mediaIsPlaying(\"music\").result:\n    info = droid.mediaPlayInfo(\"music\").result\n    print(f\"Playing: {info}\")\n\n# \u8df3\u8f6c\u5230 30 \u79d2\ndroid.mediaPlaySeek(30000, \"music\")\n\n# \u5173\u95ed\ndroid.mediaPlayClose(\"music\")\n\n# \u64ad\u653e\u89c6\u9891\ndroid.videoPlay(\"/sdcard/movie.mp4\", wait=True)\n
    "},{"location":"qsl4a/special/cipher/","title":"\u5bc6\u7801 API","text":"

    \u7528\u4e8e\u5b89\u5168\u6570\u636e\u5b58\u50a8\u7684\u52a0\u5bc6\u548c\u89e3\u5bc6\u5de5\u5177\u3002

    "},{"location":"qsl4a/special/cipher/#_1","title":"\u521d\u59cb\u5316","text":""},{"location":"qsl4a/special/cipher/#cipherinit","title":"cipherInit()","text":"

    \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u548c\u7b97\u6cd5\u521d\u59cb\u5316\u5bc6\u7801\u5668\u3002

    cipherInit(key, algorithm=\"AES/CBC/PKCS5Padding\", encodingFormat=\"\", initialVector=\"\")\n

    \u53c2\u6570\uff1a - key (str or bytes): \u52a0\u5bc6\u5bc6\u94a5 - algorithm (str): \u5bc6\u7801\u7b97\u6cd5\uff08\u9ed8\u8ba4\uff1a\"AES/CBC/PKCS5Padding\"\uff09 - encodingFormat (str): \u7f16\u7801\u683c\u5f0f - initialVector (str or bytes): \u52a0\u5bc6\u7684\u521d\u59cb\u5411\u91cf

    \u8fd4\u56de\uff1a \u521d\u59cb\u5316\u7ed3\u679c

    \u6ce8\u610f\uff1a \u5fc5\u987b\u5728\u4efb\u4f55\u52a0\u5bc6/\u89e3\u5bc6\u64cd\u4f5c\u4e4b\u524d\u8c03\u7528\u3002

    "},{"location":"qsl4a/special/cipher/#_2","title":"\u52a0\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#encryptstring","title":"encryptString()","text":"

    \u52a0\u5bc6\u5b57\u7b26\u4e32\u3002

    encryptString(plainText)\n

    \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c

    \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/special/cipher/#encryptbytes","title":"encryptBytes()","text":"

    \u52a0\u5bc6\u5b57\u8282\u6570\u636e\u3002

    encryptBytes(data)\n

    \u53c2\u6570\uff1a - data (bytes): \u8981\u52a0\u5bc6\u7684\u6570\u636e

    \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u8282

    "},{"location":"qsl4a/special/cipher/#encryptstringtofile","title":"encryptStringToFile()","text":"

    \u52a0\u5bc6\u5b57\u7b26\u4e32\u5230\u6587\u4ef6\u3002

    encryptStringToFile(plainText, filePath)\n

    \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c - filePath (str): \u8f93\u51fa\u6587\u4ef6\u8def\u5f84

    "},{"location":"qsl4a/special/cipher/#encryptbytestofile","title":"encryptBytesToFile()","text":"

    \u52a0\u5bc6\u5b57\u8282\u5230\u6587\u4ef6\u3002

    encryptBytesToFile(data, filePath)\n
    "},{"location":"qsl4a/special/cipher/#_3","title":"\u89e3\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#decryptstring","title":"decryptString()","text":"

    \u89e3\u5bc6\u4e3a\u5b57\u7b26\u4e32\u3002

    decryptString(cipherText)\n

    \u53c2\u6570\uff1a - cipherText (str): \u52a0\u5bc6\u7684\u6587\u672c

    \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/special/cipher/#decryptbytes","title":"decryptBytes()","text":"

    \u89e3\u5bc6\u4e3a\u5b57\u8282\u3002

    decryptBytes(data)\n

    \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u8282

    "},{"location":"qsl4a/special/cipher/#decryptfiletostring","title":"decryptFileToString()","text":"

    \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u7b26\u4e32\u3002

    decryptFileToString(filePath)\n
    "},{"location":"qsl4a/special/cipher/#decryptfiletobytes","title":"decryptFileToBytes()","text":"

    \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u8282\u3002

    decryptFileToBytes(filePath)\n
    "},{"location":"qsl4a/special/cipher/#decryptfile","title":"decryptFile()","text":"

    \u89e3\u5bc6\u6587\u4ef6\u5230\u6587\u4ef6\u3002

    decryptFile(srcPath, destPath)\n
    "},{"location":"qsl4a/special/cipher/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u521d\u59cb\u5316\u5bc6\u7801\u5668\ndroid.cipherInit(\"my_secret_key_1234\")\n\n# \u52a0\u5bc6\u5b57\u7b26\u4e32\nencrypted = droid.encryptString(\"Secret message!\").result\nprint(f\"Encrypted: {encrypted}\")\n\n# \u89e3\u5bc6\u5b57\u7b26\u4e32\ndecrypted = droid.decryptString(encrypted).result\nprint(f\"Decrypted: {decrypted}\")\n\n# \u52a0\u5bc6\u5230\u6587\u4ef6\ndroid.encryptStringToFile(\"My secret data\", \"/sdcard/secret.dat\")\n\n# \u4ece\u6587\u4ef6\u89e3\u5bc6\ndata = droid.decryptFileToString(\"/sdcard/secret.dat\").result\nprint(data)\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u7b97\u6cd5\u548c IV \u521d\u59cb\u5316\ndroid.cipherInit(\n    key=\"my_key\",\n    algorithm=\"AES/CBC/PKCS5Padding\",\n    initialVector=\"0123456789abcdef\"\n)\n
    "},{"location":"qsl4a/special/pgptai/","title":"PGPT AI API","text":"

    \u8bed\u97f3\u8f6c\u6587\u672c\u548c AI \u670d\u52a1\u96c6\u6210\u3002

    "},{"location":"qsl4a/special/pgptai/#_1","title":"\u5148\u51b3\u6761\u4ef6","text":"
    pip install pgptAI\n
    "},{"location":"qsl4a/special/pgptai/#_2","title":"\u8bed\u97f3\u8bc6\u522b","text":""},{"location":"qsl4a/special/pgptai/#speechtotext","title":"speechToText()","text":"

    \u5c06\u8bed\u97f3\u8f6c\u6362\u4e3a\u6587\u672c\u3002

    speechToText(RecordSecond=10, AmrFile=None, Language=None)\n

    \u53c2\u6570\uff1a - RecordSecond (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09 - AmrFile (str, optional): \u73b0\u6709\u97f3\u9891\u6587\u4ef6\u8def\u5f84 - Language (str, optional): \u8bed\u8a00\u4ee3\u7801\uff08'en'\u3001'zh'\uff09

    \u8fd4\u56de\uff1a \u8f6c\u5f55\u7684\u6587\u672c

    "},{"location":"qsl4a/special/pgptai/#_3","title":"\u6587\u672c\u8f6c\u8bed\u97f3","text":""},{"location":"qsl4a/special/pgptai/#texttospeech","title":"textToSpeech()","text":"

    \u5c06\u6587\u672c\u8f6c\u6362\u4e3a\u8bed\u97f3\u5e76\u53ef\u9009\u5730\u64ad\u653e\u3002

    textToSpeech(Text, AutoPlay=True, WavFile=None, VoiceName=None)\n

    \u53c2\u6570\uff1a - Text (str): \u8981\u8f6c\u6362\u4e3a\u8bed\u97f3\u7684\u6587\u672c - AutoPlay (bool): \u81ea\u52a8\u64ad\u653e\u751f\u6210\u7684\u97f3\u9891\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - WavFile (str, optional): \u4fdd\u5b58 WAV \u6587\u4ef6\u7684\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u4e34\u65f6\u6587\u4ef6 - VoiceName (str, optional): \u8981\u4f7f\u7528\u7684\u8bed\u97f3\u540d\u79f0\uff08\u4f8b\u5982 'en-US-JennyNeural'\u3001'zh-CN-XiaoxiaoNeural'\uff09

    \u8fd4\u56de\uff1a \u5305\u542b\u8bed\u97f3\u5408\u6210\u7ed3\u679c\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - text: \u8f93\u5165\u6587\u672c - url: \u4e0b\u8f7d\u97f3\u9891\u6587\u4ef6\u7684 URL - WavFile: \u4fdd\u5b58\u7684 WAV \u6587\u4ef6\u8def\u5f84\uff08\u5982\u679c\u672c\u5730\u4fdd\u5b58\uff09

    "},{"location":"qsl4a/special/pgptai/#_4","title":"\u914d\u7f6e","text":"

    API \u4f7f\u7528\u4ee5\u4e0b\u914d\u7f6e\u6587\u4ef6\u4e2d\u7684\u914d\u7f6e\uff1a/storage/emulated/0/Android/data/org.qpython.qpy/files/apigpt.conf\uff1a

    [speech]\nspeech_key = your_api_key\n

    \u9ed8\u8ba4\u8bed\u97f3\u8bbe\u7f6e\uff1a - \u82f1\u8bed\uff1aen-US-JennyNeural - \u4e2d\u6587\uff1azh-CN-XiaoxiaoNeural

    "},{"location":"qsl4a/special/pgptai/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5f55\u5236\u5e76\u8f6c\u5f55\nprint(\"Recording for 5 seconds...\")\ntext = droid.speechToText(RecordSecond=5, Language='en').result\nprint(f\"You said: {text}\")\n\n# \u8f6c\u5f55\u73b0\u6709\u6587\u4ef6\ntext = droid.speechToText(AmrFile=\"/sdcard/recording.amr\").result\nprint(f\"Transcription: {text}\")\n\n# \u6587\u672c\u8f6c\u8bed\u97f3\ndroid.textToSpeech(\"Hello, this is a test message.\", AutoPlay=True, Language='en')\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u8bed\u97f3\u5e76\u4fdd\u5b58\u5230\u6587\u4ef6\u7684\u6587\u672c\u8f6c\u8bed\u97f3\nresult = droid.textToSpeech(\n    \"Welcome to QPython!\",\n    AutoPlay=False,\n    WavFile=\"/sdcard/welcome.wav\",\n    VoiceName=\"en-US-JennyNeural\"\n).result\nprint(f\"Audio saved to: {result.get('WavFile')}\")\n
    "},{"location":"qsl4a/special/pgptai/#_6","title":"\u7c7b\u4f7f\u7528","text":"
    from androidhelper.pgptai import pgptai\nimport androidhelper\n\ndroid = androidhelper.Android()\nai = pgptai(droid)\n\n# \u4f7f\u7528\u8bed\u97f3\u8bc6\u522b\ntext = ai.speechToText(RecordSecond=10)\n
    "},{"location":"qsl4a/storage/clipboard/","title":"\u526a\u8d34\u677f API","text":"

    \u590d\u5236\u548c\u7c98\u8d34\u6587\u672c\u5230\u7cfb\u7edf\u526a\u8d34\u677f\u3002

    "},{"location":"qsl4a/storage/clipboard/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/clipboard/#setclipboard","title":"setClipboard()","text":"

    \u590d\u5236\u6587\u672c\u5230\u526a\u8d34\u677f\u3002

    setClipboard(text)\n

    \u53c2\u6570\uff1a - text (str): \u8981\u590d\u5236\u7684\u6587\u672c

    \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/storage/clipboard/#getclipboard","title":"getClipboard()","text":"

    \u4ece\u526a\u8d34\u677f\u83b7\u53d6\u6587\u672c\u3002

    getClipboard()\n

    \u8fd4\u56de\uff1a \u526a\u8d34\u677f\u6587\u672c

    "},{"location":"qsl4a/storage/clipboard/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u590d\u5236\u5230\u526a\u8d34\u677f\ndroid.setClipboard(\"Hello from QPython!\")\n\n# \u4ece\u526a\u8d34\u677f\u7c98\u8d34\ntext = droid.getClipboard().result\nprint(f\"Clipboard: {text}\")\n
    "},{"location":"qsl4a/storage/documentfile/","title":"DocumentFile API","text":"

    \u4f7f\u7528 SAF\uff08\u5b58\u50a8\u8bbf\u95ee\u6846\u67b6\uff09\u8fdb\u884c\u6587\u4ef6\u64cd\u4f5c\uff0c\u652f\u6301 Android 4.4+\u3002

    "},{"location":"qsl4a/storage/documentfile/#_1","title":"\u76ee\u5f55\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilemkdir","title":"documentFileMkdir()","text":"

    \u521b\u5efa\u76ee\u5f55\u3002

    documentFileMkdir(Dir)\n

    \u53c2\u6570\uff1a - Dir (str): \u76ee\u5f55\u8def\u5f84

    \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/storage/documentfile/#documentfilelistfiles","title":"documentFileListFiles()","text":"

    \u5217\u51fa\u76ee\u5f55\u4e2d\u7684\u6587\u4ef6\u3002

    documentFileListFiles(Folder)\n

    \u8fd4\u56de\uff1a \u6587\u4ef6\u5217\u8868

    "},{"location":"qsl4a/storage/documentfile/#_2","title":"\u6587\u4ef6\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileexists","title":"documentFileExists()","text":"

    \u68c0\u67e5\u6587\u4ef6\u6216\u76ee\u5f55\u662f\u5426\u5b58\u5728\u3002

    documentFileExists(path)\n

    \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u6216\u76ee\u5f55\u8def\u5f84

    \u8fd4\u56de\uff1a \u5982\u679c\u5b58\u5728\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

    "},{"location":"qsl4a/storage/documentfile/#documentfileisfile","title":"documentFileIsFile()","text":"

    \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u6587\u4ef6\u3002

    documentFileIsFile(path)\n

    \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

    \u8fd4\u56de\uff1a \u5982\u679c\u662f\u6587\u4ef6\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u6587\u4ef6\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

    "},{"location":"qsl4a/storage/documentfile/#documentfileisdirectory","title":"documentFileIsDirectory()","text":"

    \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u76ee\u5f55\u3002

    documentFileIsDirectory(path)\n

    \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

    \u8fd4\u56de\uff1a \u5982\u679c\u662f\u76ee\u5f55\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u76ee\u5f55\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

    "},{"location":"qsl4a/storage/documentfile/#documentfiledelete","title":"documentFileDelete()","text":"

    \u5220\u9664\u6587\u4ef6\u6216\u76ee\u5f55\u3002

    documentFileDelete(FileOrTree)\n

    \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/storage/documentfile/#documentfilerenameto","title":"documentFileRenameTo()","text":"

    \u91cd\u547d\u540d\u6216\u79fb\u52a8\u6587\u4ef6\u3002

    documentFileRenameTo(Src, Dest)\n

    \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/storage/documentfile/#documentfilecopy","title":"documentFileCopy()","text":"

    \u590d\u5236\u6587\u4ef6\u3002

    documentFileCopy(SrcFileOrTree, DestFileOrTree)\n
    "},{"location":"qsl4a/storage/documentfile/#_3","title":"\u6d41\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileinputstream","title":"documentFileInputStream()","text":"

    \u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9\u3002

    documentFileInputStream(srcFile, EncodingFormat=\"\", skip=None, length=None)\n

    \u53c2\u6570\uff1a - srcFile (str): \u6e90\u6587\u4ef6 - EncodingFormat (str): \"UTF-8\"\u3001\"GBK\"\u3001\"Base64\" \u6216\u7a7a\u5b57\u7b26\u4e32\u8868\u793a\u5b57\u8282 - skip (int): \u4ece\u5f00\u5934\u8df3\u8fc7\u7684\u5b57\u8282\u6570 - length (int): \u8bfb\u53d6\u957f\u5ea6

    \u8fd4\u56de\uff1a \u6587\u4ef6\u5185\u5bb9

    "},{"location":"qsl4a/storage/documentfile/#documentfileoutputstream","title":"documentFileOutputStream()","text":"

    \u5199\u5165\u6587\u4ef6\u5185\u5bb9\u3002

    documentFileOutputStream(destFile, src, EncodingFormat=\"\", append=None)\n

    \u53c2\u6570\uff1a - destFile (str): \u76ee\u6807\u6587\u4ef6 - src: \u8981\u5199\u5165\u7684\u6570\u636e - EncodingFormat (str): \u7f16\u7801\u683c\u5f0f - append (bool): \u8ffd\u52a0\u6a21\u5f0f

    "},{"location":"qsl4a/storage/documentfile/#_4","title":"\u6587\u4ef6\u4fe1\u606f","text":""},{"location":"qsl4a/storage/documentfile/#documentfilelength","title":"documentFileLength()","text":"

    \u83b7\u53d6\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\u3002

    documentFileLength(path)\n

    \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

    \u8fd4\u56de\uff1a \u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

    "},{"location":"qsl4a/storage/documentfile/#documentfilelastmodified","title":"documentFileLastModified()","text":"

    \u83b7\u53d6\u6700\u540e\u4fee\u6539\u65f6\u95f4\u3002

    documentFileLastModified(path)\n

    \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

    \u8fd4\u56de\uff1a \u65f6\u95f4\u6233\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

    "},{"location":"qsl4a/storage/documentfile/#documentfilegetstat","title":"documentFileGetStat()","text":"

    \u83b7\u53d6\u5168\u9762\u7684\u6587\u4ef6\u7edf\u8ba1\u4fe1\u606f\u3002

    documentFileGetStat(path)\n

    \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

    \u8fd4\u56de\uff1a \u5305\u542b\u957f\u5ea6\u3001\u6700\u540e\u4fee\u6539\u65f6\u95f4\u548c\u8bfb/\u5199\u6743\u9650\u7684\u5b57\u5178\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

    "},{"location":"qsl4a/storage/documentfile/#uri","title":"URI \u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilegeturi","title":"documentFileGetUri()","text":"

    \u4ece\u8def\u5f84\u83b7\u53d6 URI\u3002

    documentFileGetUri(path, isDirectory=None)\n
    "},{"location":"qsl4a/storage/documentfile/#documentfileshowopen","title":"documentFileShowOpen()","text":"

    \u663e\u793a\u6587\u4ef6\u9009\u62e9\u5668\u3002

    documentFileShowOpen()\n

    \u8fd4\u56de\uff1a \u9009\u62e9\u7684\u6587\u4ef6 URI

    "},{"location":"qsl4a/storage/documentfile/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u76ee\u5f55\ndroid.documentFileMkdir(\"/sdcard/MyFolder\")\n\n# \u5217\u51fa\u6587\u4ef6\nfiles = droid.documentFileListFiles(\"/sdcard\").result\nfor f in files:\n    print(f)\n\n# \u8bfb\u53d6\u6587\u4ef6\ncontent = droid.documentFileInputStream(\n    \"/sdcard/test.txt\",\n    EncodingFormat=\"UTF-8\"\n).result\nprint(content)\n\n# \u5199\u5165\u6587\u4ef6\ndroid.documentFileOutputStream(\n    \"/sdcard/output.txt\",\n    \"Hello World\",\n    EncodingFormat=\"UTF-8\"\n)\n
    "},{"location":"qsl4a/storage/preferences/","title":"\u504f\u597d\u8bbe\u7f6e API","text":"

    \u4f7f\u7528 Android SharedPreferences \u5b58\u50a8\u548c\u68c0\u7d22\u6570\u636e\u3002

    "},{"location":"qsl4a/storage/preferences/#_1","title":"\u504f\u597d\u8bbe\u7f6e\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/preferences/#prefgetvalue","title":"prefGetValue()","text":"

    \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u8bfb\u53d6\u503c\u3002

    prefGetValue(key, filename=None)\n

    \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

    \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c\uff08\u4efb\u610f\u7c7b\u578b\uff09

    "},{"location":"qsl4a/storage/preferences/#prefputvalue","title":"prefPutValue()","text":"

    \u5199\u5165\u503c\u5230\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u3002

    prefPutValue(key, value, filename=None)\n

    \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - value (object): \u8981\u5b58\u50a8\u7684\u503c - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

    "},{"location":"qsl4a/storage/preferences/#prefgetall","title":"prefGetAll()","text":"

    \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\u503c\u3002

    prefGetAll(filename=None)\n

    \u53c2\u6570\uff1a - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

    \u8fd4\u56de\uff1a \u6240\u6709\u504f\u597d\u7684\u6620\u5c04

    "},{"location":"qsl4a/storage/preferences/#prefremovevalue","title":"prefRemoveValue()","text":"

    \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u4e2d\u79fb\u9664\u503c\u3002

    prefRemoveValue(key, filename=None)\n

    \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

    "},{"location":"qsl4a/storage/preferences/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b58\u50a8\u503c\ndroid.prefPutValue(\"username\", \"alice\")\ndroid.prefPutValue(\"score\", 100)\ndroid.prefPutValue(\"enabled\", True)\n\n# \u8bfb\u53d6\u7279\u5b9a\u503c\nusername = droid.prefGetValue(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\nall_prefs = droid.prefGetAll().result\nprint(f\"All prefs: {all_prefs}\")\n\n# \u79fb\u9664\u503c\ndroid.prefRemoveValue(\"score\")\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u6587\u4ef6\u540d\ndroid.prefPutValue(\"token\", \"abc123\", filename=\"auth.prefs\")\ntoken = droid.prefGetValue(\"token\", filename=\"auth.prefs\").result\n
    "},{"location":"qsl4a/system/activityresult/","title":"Activity Result API","text":"

    \u4e3a\u901a\u8fc7 startActivityForResult \u542f\u52a8\u7684\u811a\u672c\u8bbe\u7f6e activity \u7ed3\u679c\u3002

    "},{"location":"qsl4a/system/activityresult/#_1","title":"\u7ed3\u679c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/activityresult/#setresultboolean","title":"setResultBoolean()","text":"

    \u8bbe\u7f6e\u5e03\u5c14\u7ed3\u679c\u3002

    setResultBoolean(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (bool): \u5e03\u5c14\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#setresultbyte","title":"setResultByte()","text":"

    \u8bbe\u7f6e\u5b57\u8282\u7ed3\u679c\u3002

    setResultByte(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u5b57\u8282\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#setresultshort","title":"setResultShort()","text":"

    \u8bbe\u7f6e\u77ed\u6574\u6570\u7ed3\u679c\u3002

    setResultShort(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u77ed\u6574\u6570\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#setresultchar","title":"setResultChar()","text":"

    \u8bbe\u7f6e\u5b57\u7b26\u7ed3\u679c\u3002

    setResultChar(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#setresultinteger","title":"setResultInteger()","text":"

    \u8bbe\u7f6e\u6574\u6570\u7ed3\u679c\u3002

    setResultInteger(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u6574\u6570\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#setresultlong","title":"setResultLong()","text":"

    \u8bbe\u7f6e\u957f\u6574\u6570\u7ed3\u679c\u3002

    setResultLong(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u957f\u6574\u6570\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#setresultfloat","title":"setResultFloat()","text":"

    \u8bbe\u7f6e\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

    setResultFloat(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u6d6e\u70b9\u6570\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#setresultdouble","title":"setResultDouble()","text":"

    \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

    setResultDouble(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#setresultstring","title":"setResultString()","text":"

    \u8bbe\u7f6e\u5b57\u7b26\u4e32\u7ed3\u679c\u3002

    setResultString(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u4e32\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#setresultbooleanarray","title":"setResultBooleanArray()","text":"

    \u8bbe\u7f6e\u5e03\u5c14\u6570\u7ec4\u7ed3\u679c\u3002

    setResultBooleanArray(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5e03\u5c14\u6570\u7ec4

    "},{"location":"qsl4a/system/activityresult/#setresultbytearray","title":"setResultByteArray()","text":"

    \u8bbe\u7f6e\u5b57\u8282\u6570\u7ec4\u7ed3\u679c\u3002

    setResultByteArray(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u8282\u6570\u7ec4

    "},{"location":"qsl4a/system/activityresult/#setresultshortarray","title":"setResultShortArray()","text":"

    \u8bbe\u7f6e\u77ed\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

    setResultShortArray(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u77ed\u6574\u6570\u6570\u7ec4

    "},{"location":"qsl4a/system/activityresult/#setresultchararray","title":"setResultCharArray()","text":"

    \u8bbe\u7f6e\u5b57\u7b26\u6570\u7ec4\u7ed3\u679c\u3002

    setResultCharArray(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u6570\u7ec4

    "},{"location":"qsl4a/system/activityresult/#setresultintegerarray","title":"setResultIntegerArray()","text":"

    \u8bbe\u7f6e\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

    setResultIntegerArray(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6574\u6570\u6570\u7ec4

    "},{"location":"qsl4a/system/activityresult/#setresultlongarray","title":"setResultLongArray()","text":"

    \u8bbe\u7f6e\u957f\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

    setResultLongArray(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u957f\u6574\u6570\u6570\u7ec4

    "},{"location":"qsl4a/system/activityresult/#setresultfloatarray","title":"setResultFloatArray()","text":"

    \u8bbe\u7f6e\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

    setResultFloatArray(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6d6e\u70b9\u6570\u6570\u7ec4

    "},{"location":"qsl4a/system/activityresult/#setresultdoublearray","title":"setResultDoubleArray()","text":"

    \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

    setResultDoubleArray(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4

    "},{"location":"qsl4a/system/activityresult/#setresultstringarray","title":"setResultStringArray()","text":"

    \u8bbe\u7f6e\u5b57\u7b26\u4e32\u6570\u7ec4\u7ed3\u679c\u3002

    setResultStringArray(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u4e32\u6570\u7ec4

    "},{"location":"qsl4a/system/activityresult/#setresultserializable","title":"setResultSerializable()","text":"

    \u8bbe\u7f6e\u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u3002

    setResultSerializable(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue: \u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c activity \u540e\uff0c\u8bbe\u7f6e\u7ed3\u679c\n# \u793a\u4f8b\uff1a\u8fd4\u56de\u6210\u529f\u53ca\u6570\u636e\ndroid.setResultInteger(0, 200)  # RESULT_OK\ndroid.setResultString(0, \"Operation completed successfully\")\n\n# \u8fd4\u56de\u6570\u7ec4\u7ed3\u679c\ndroid.setResultIntegerArray(0, [1, 2, 3, 4, 5])\n
    "},{"location":"qsl4a/system/application/","title":"\u5e94\u7528\u7ba1\u7406","text":"

    \u7ba1\u7406\u5e94\u7528\u7a0b\u5e8f\u3001\u542f\u52a8\u5e94\u7528\u548c\u67e5\u8be2\u7cfb\u7edf\u4fe1\u606f\u3002

    "},{"location":"qsl4a/system/application/#_2","title":"\u5e94\u7528\u7a0b\u5e8f\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getapplicationinfo","title":"getApplicationInfo()","text":"

    \u83b7\u53d6\u5e94\u7528\u4fe1\u606f\u3002

    getApplicationInfo(packageName=None)\n

    \u53c2\u6570\uff1a - packageName (str): \u5305\u540d\uff08None = \u5f53\u524d\u5e94\u7528\uff09

    \u8fd4\u56de\uff1a \u5e94\u7528\u4fe1\u606f\u5b57\u5178

    "},{"location":"qsl4a/system/application/#getinstalledpackages","title":"getInstalledPackages()","text":"

    \u83b7\u53d6\u5df2\u5b89\u88c5\u5305\u5217\u8868\u3002

    getInstalledPackages(flag=4)\n

    \u53c2\u6570\uff1a - flag (int): \u5305\u6807\u5fd7\u8fc7\u6ee4\u5668\uff08\u9ed8\u8ba4\uff1a4\uff09

    \u8fd4\u56de\uff1a \u5df2\u5b89\u88c5\u5305\u5217\u8868

    "},{"location":"qsl4a/system/application/#getrunningpackages","title":"getRunningPackages()","text":"

    \u5217\u51fa\u6b63\u5728\u8fd0\u884c\u7684\u5305\u3002

    getRunningPackages()\n

    \u8fd4\u56de\uff1a \u5305\u540d\u5217\u8868

    "},{"location":"qsl4a/system/application/#getlaunchablepackages","title":"getLaunchablePackages()","text":"

    \u83b7\u53d6\u53ef\u542f\u52a8\u5305\u5217\u8868\u3002

    getLaunchablePackages(needClassName=False)\n

    \u53c2\u6570\uff1a - needClassName (bool): \u5305\u542b\u4e3b activity \u7c7b\u540d\uff08\u9ed8\u8ba4\uff1aFalse\uff09

    \u8fd4\u56de\uff1a \u53ef\u542f\u52a8\u5305\u540d\u5217\u8868\u6216\u5305\u542b\u7c7b\u540d\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/application/#_3","title":"\u5e94\u7528\u63a7\u5236","text":""},{"location":"qsl4a/system/application/#launch","title":"launch()","text":"

    \u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u3002

    launch(classname=None, packagename=None, wait=True)\n

    \u53c2\u6570\uff1a - classname (str): \u4e3b activity \u7c7b\u540d - packagename (str): \u5305\u540d - wait (bool): \u7b49\u5f85\u542f\u52a8\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

    \u8fd4\u56de\uff1a \u542f\u52a8\u7ed3\u679c

    "},{"location":"qsl4a/system/application/#forcestoppackage","title":"forceStopPackage()","text":"

    \u5f3a\u5236\u505c\u6b62\u5e94\u7528\u7a0b\u5e8f\u3002

    forceStopPackage(packageName)\n

    \u53c2\u6570\uff1a - packageName (str): \u8981\u505c\u6b62\u7684\u5305\u540d

    "},{"location":"qsl4a/system/application/#_4","title":"\u7248\u672c\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getpackageversion","title":"getPackageVersion()","text":"

    \u83b7\u53d6\u5e94\u7528\u7248\u672c\u540d\u79f0\u3002

    getPackageVersion(packageName)\n

    \u8fd4\u56de\uff1a \u7248\u672c\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"3.2.1\"\uff09

    "},{"location":"qsl4a/system/application/#getpackageversioncode","title":"getPackageVersionCode()","text":"

    \u83b7\u53d6\u5e94\u7528\u7248\u672c\u4ee3\u7801\u3002

    getPackageVersionCode(packageName)\n

    \u8fd4\u56de\uff1a \u7248\u672c\u4ee3\u7801\u6574\u6570

    "},{"location":"qsl4a/system/application/#getconstants","title":"getConstants()","text":"

    \u83b7\u53d6\u7c7b\u5e38\u91cf\u3002

    getConstants(classname)\n

    \u53c2\u6570\uff1a - classname (str): \u5b8c\u6574\u7c7b\u540d

    \u8fd4\u56de\uff1a \u5e38\u91cf\u540d\u548c\u503c\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/application/#_5","title":"\u7cfb\u7edf\u529f\u80fd","text":""},{"location":"qsl4a/system/application/#backgroundprotect","title":"backgroundProtect()","text":"

    \u542f\u7528\u6216\u7981\u7528\u5e94\u7528\u7684\u540e\u53f0\u4fdd\u62a4\u3002

    backgroundProtect(enabled=True)\n

    \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\u4fdd\u62a4\uff0cFalse \u7981\u7528

    "},{"location":"qsl4a/system/application/#createscriptshortcut","title":"createScriptShortCut()","text":"

    \u4e3a\u811a\u672c\u521b\u5efa\u4e3b\u5c4f\u5e55\u5feb\u6377\u65b9\u5f0f\u3002

    createScriptShortCut(scriptPath, label=None, iconPath=None, scriptArg=None)\n

    \u53c2\u6570\uff1a - scriptPath (str): Python \u811a\u672c\u8def\u5f84 - label (str, optional): \u5feb\u6377\u65b9\u5f0f\u6807\u7b7e - iconPath (str, optional): \u56fe\u6807\u56fe\u50cf\u8def\u5f84 - scriptArg (str, optional): \u4f20\u9012\u7ed9\u811a\u672c\u7684\u53c2\u6570

    "},{"location":"qsl4a/system/application/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getandroidid","title":"getAndroidID()","text":"

    \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

    getAndroidID()\n

    \u8fd4\u56de\uff1a \u552f\u4e00\u7684 Android \u8bbe\u5907 ID \u5b57\u7b26\u4e32

    "},{"location":"qsl4a/system/application/#getsysinfo","title":"getSysInfo()","text":"

    \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\u3002

    getSysInfo()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/application/#getlocale","title":"getLocale()","text":"

    \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u3002

    getLocale()\n

    \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

    "},{"location":"qsl4a/system/application/#getharmonyosinformation","title":"getHarmonyOsInformation()","text":"

    \u5982\u679c\u5728 HarmonyOS \u4e0a\u8fd0\u884c\uff0c\u83b7\u53d6 HarmonyOS \u4fe1\u606f\u3002

    getHarmonyOsInformation()\n

    \u8fd4\u56de\uff1a HarmonyOS \u7248\u672c\u4fe1\u606f\u6216 None

    "},{"location":"qsl4a/system/application/#isexternalstoragemanager","title":"isExternalStorageManager()","text":"

    \u68c0\u67e5\u5e94\u7528\u662f\u5426\u6709\u5916\u90e8\u5b58\u50a8\u7ba1\u7406\u5668\u6743\u9650\u3002

    isExternalStorageManager()\n

    \u8fd4\u56de\uff1a \u5982\u679c\u6709\u6743\u9650\u5219\u4e3a True

    "},{"location":"qsl4a/system/application/#_7","title":"\u5185\u5b58\u548c\u663e\u793a","text":""},{"location":"qsl4a/system/application/#getmemoryinfo","title":"getMemoryInfo()","text":"

    \u83b7\u53d6\u5185\u5b58\u4fe1\u606f\u3002

    getMemoryInfo()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/application/#getscreeninfo","title":"getScreenInfo()","text":"

    \u83b7\u53d6\u5c4f\u5e55\u4fe1\u606f\u3002

    getScreenInfo()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/application/#_8","title":"\u6743\u9650","text":""},{"location":"qsl4a/system/application/#checkpermissions","title":"checkPermissions()","text":"

    \u68c0\u67e5\u5f53\u524d\u5e94\u7528\u6743\u9650\u3002

    checkPermissions()\n

    \u8fd4\u56de\uff1a \u6743\u9650\u53ca\u5176\u72b6\u6001\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/application/#requestpermissions","title":"requestPermissions()","text":"

    \u5411\u7528\u6237\u8bf7\u6c42\u6743\u9650\u3002

    requestPermissions(permissions=None)\n

    \u53c2\u6570\uff1a - permissions (list, optional): \u8981\u8bf7\u6c42\u7684\u6743\u9650\u5217\u8868\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8bf7\u6c42\u6240\u6709\u9700\u8981\u7684\u6743\u9650\u3002

    \u8fd4\u56de\uff1a \u6743\u9650\u8bf7\u6c42\u7ed3\u679c

    "},{"location":"qsl4a/system/application/#_9","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/system/application/#showscreenlock","title":"showScreenLock()","text":"

    \u663e\u793a\u5c4f\u5e55\u9501\u5b9a\uff08PIN/\u56fe\u6848/\u5bc6\u7801\u8f93\u5165\uff09\u3002

    showScreenLock()\n
    "},{"location":"qsl4a/system/application/#_10","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\ninfo = droid.getSysInfo().result\nprint(f\"System: {info}\")\n\n# \u83b7\u53d6\u5e94\u7528\u7248\u672c\nversion = droid.getPackageVersion(\"org.qpython.qpy\").result\nprint(f\"QPython version: {version}\")\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u5e94\u7528\napps = droid.getInstalledPackages().result\nprint(f\"Installed apps: {len(apps)}\")\n\n# \u542f\u52a8\u5e94\u7528\ndroid.launch(packagename=\"com.android.settings\")\n\n# \u68c0\u67e5\u6743\u9650\nperms = droid.checkPermissions().result\nprint(f\"Permissions: {perms}\")\n\n# \u8bf7\u6c42\u5b58\u50a8\u6743\u9650\ndroid.requestPermissions([\"android.permission.READ_EXTERNAL_STORAGE\"])\n\n# \u521b\u5efa\u5feb\u6377\u65b9\u5f0f\ndroid.createScriptShortCut(\n    \"/sdcard/my_script.py\",\n    label=\"My Script\",\n    iconPath=\"/sdcard/icon.png\"\n)\n
    "},{"location":"qsl4a/system/battery/","title":"\u7535\u6c60 API","text":"

    \u76d1\u63a7\u8bbe\u5907\u7535\u6c60\u72b6\u6001\u548c\u5065\u5eb7\u72b6\u51b5\u3002

    "},{"location":"qsl4a/system/battery/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/battery/#readbatterydata","title":"readBatteryData()","text":"

    \u83b7\u53d6\u5b8c\u6574\u7684\u7535\u6c60\u4fe1\u606f\u3002

    readBatteryData()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u7535\u6c60\u6570\u636e\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/battery/#batterystartmonitoring","title":"batteryStartMonitoring()","text":"

    \u5f00\u59cb\u7535\u6c60\u76d1\u63a7\u3002

    batteryStartMonitoring()\n
    "},{"location":"qsl4a/system/battery/#batterystopmonitoring","title":"batteryStopMonitoring()","text":"

    \u505c\u6b62\u7535\u6c60\u76d1\u63a7\u3002

    batteryStopMonitoring()\n
    "},{"location":"qsl4a/system/battery/#batterygetlevel","title":"batteryGetLevel()","text":"

    \u83b7\u53d6\u7535\u6c60\u767e\u5206\u6bd4\u3002

    batteryGetLevel()\n

    \u8fd4\u56de\uff1a \u6574\u6570\uff080-100\uff09

    "},{"location":"qsl4a/system/battery/#batterygetstatus","title":"batteryGetStatus()","text":"

    \u83b7\u53d6\u5145\u7535\u72b6\u6001\u3002

    batteryGetStatus()\n

    \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u5145\u7535\u4e2d - 3: \u653e\u7535\u4e2d - 4: \u672a\u5145\u7535 - 5: \u5df2\u5145\u6ee1

    "},{"location":"qsl4a/system/battery/#batterygetplugtype","title":"batteryGetPlugType()","text":"

    \u83b7\u53d6\u7535\u6e90\u7c7b\u578b\u3002

    batteryGetPlugType()\n

    \u8fd4\u56de\uff1a - -1: \u672a\u77e5 - 0: \u672a\u63d2\u7535 - 1: AC \u5145\u7535\u5668 - 2: USB \u7aef\u53e3

    "},{"location":"qsl4a/system/battery/#batterygethealth","title":"batteryGetHealth()","text":"

    \u83b7\u53d6\u7535\u6c60\u5065\u5eb7\u72b6\u51b5\u3002

    batteryGetHealth()\n

    \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u826f\u597d - 3: \u8fc7\u70ed - 4: \u635f\u574f - 5: \u8fc7\u538b - 6: \u672a\u6307\u5b9a\u7684\u6545\u969c

    "},{"location":"qsl4a/system/battery/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\nlevel = droid.batteryGetLevel().result\nprint(f\"Battery: {level}%\")\n
    "},{"location":"qsl4a/system/qpyinterface/","title":"QPython \u63a5\u53e3 API","text":"

    \u4ece\u5176\u4ed6\u5e94\u7528\u6267\u884c QPython \u811a\u672c\u548c\u7ba1\u7406\u5171\u4eab\u53d8\u91cf\u3002

    "},{"location":"qsl4a/system/qpyinterface/#_1","title":"\u811a\u672c\u6267\u884c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/qpyinterface/#executeqpy","title":"executeQPy()","text":"

    \u6267\u884c QPython \u811a\u672c\u3002

    executeQPy(path=\"\", arg=None)\n

    \u53c2\u6570\uff1a - path (str): \u811a\u672c\u6587\u4ef6\u8def\u5f84 - arg (str, optional): \u547d\u4ee4\u884c\u53c2\u6570

    \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/system/qpyinterface/#executeqpyassrv","title":"executeQPyAsSrv()","text":"

    \u4f5c\u4e3a\u670d\u52a1\u6267\u884c QPython \u811a\u672c\u3002

    executeQPyAsSrv(path=None)\n

    \u53c2\u6570\uff1a - path (str, optional): \u811a\u672c\u6587\u4ef6\u8def\u5f84

    \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/system/qpyinterface/#executeqpycode","title":"executeQPyCode()","text":"

    \u76f4\u63a5\u6267\u884c Python \u4ee3\u7801\u3002

    executeQPyCode(code=None)\n

    \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

    \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/system/qpyinterface/#executeqpycodeassrv","title":"executeQPyCodeAsSrv()","text":"

    \u4f5c\u4e3a\u670d\u52a1\u6267\u884c Python \u4ee3\u7801\u3002

    executeQPyCodeAsSrv(code=None)\n

    \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

    \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/system/qpyinterface/#_2","title":"\u5171\u4eab\u53d8\u91cf","text":"

    \u5171\u4eab\u53d8\u91cf\u5141\u8bb8 QPython \u4e0e\u5176\u4ed6\u5e94\u7528\u4e4b\u95f4\u8fdb\u884c\u901a\u4fe1\u3002

    "},{"location":"qsl4a/system/qpyinterface/#sharedvariableset","title":"sharedVariableSet()","text":"

    \u8bbe\u7f6e Java \u5171\u4eab\u53d8\u91cf\u3002

    sharedVariableSet(key, value)\n

    \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d - value (str): \u53d8\u91cf\u503c

    \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

    "},{"location":"qsl4a/system/qpyinterface/#sharedvariableget","title":"sharedVariableGet()","text":"

    \u83b7\u53d6 Java \u5171\u4eab\u53d8\u91cf\u3002

    sharedVariableGet(key)\n

    \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d

    \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

    "},{"location":"qsl4a/system/qpyinterface/#sharedvariableremove","title":"sharedVariableRemove()","text":"

    \u79fb\u9664 Java \u5171\u4eab\u53d8\u91cf\u3002

    sharedVariableRemove(key)\n

    \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u53d8\u91cf\u540d

    \u8fd4\u56de\uff1a \u88ab\u79fb\u9664\u7684\u503c

    "},{"location":"qsl4a/system/qpyinterface/#getlastlog","title":"getLastLog()","text":"

    \u83b7\u53d6 QPython \u7684\u6700\u540e\u65e5\u5fd7\u8f93\u51fa\u3002

    getLastLog()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u65e5\u5fd7\u5185\u5bb9

    "},{"location":"qsl4a/system/qpyinterface/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c\u811a\u672c\ndroid.executeQPy(\"/sdcard/my_script.py\", arg=\"test\")\n\n# \u76f4\u63a5\u6267\u884c\u4ee3\u7801\ncode = \"print('Hello from QPython!')\"\ndroid.executeQPyCode(code)\n\n# \u4f7f\u7528\u5171\u4eab\u53d8\u91cf\ndroid.sharedVariableSet(\"username\", \"alice\")\nusername = droid.sharedVariableGet(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u79fb\u9664\u53d8\u91cf\ndroid.sharedVariableRemove(\"username\")\n\n# \u83b7\u53d6\u6700\u8fd1\u65e5\u5fd7\nlog = droid.getLastLog().result\nprint(f\"Log: {log}\")\n
    "},{"location":"qsl4a/system/sensors/","title":"\u4f20\u611f\u5668 API","text":"

    \u8bbf\u95ee\u8bbe\u5907\u4f20\u611f\u5668\uff0c\u5305\u62ec\u52a0\u901f\u5ea6\u8ba1\u3001\u9640\u87ba\u4eea\u3001\u78c1\u529b\u8ba1\u7b49\u3002

    "},{"location":"qsl4a/system/sensors/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/sensors/#startsensingtimed","title":"startSensingTimed()","text":"

    \u5f00\u59cb\u4f20\u611f\u5668\u76d1\u63a7\u5e76\u8bbe\u7f6e\u65f6\u95f4\u95f4\u9694\u3002

    startSensingTimed(sensorNumber, delayTime)\n

    \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID\uff08\u901a\u5e38\u4e3a 1-3\uff09 - delayTime (int): \u8bfb\u53d6\u4e4b\u95f4\u7684\u5ef6\u8fdf\uff08\u6beb\u79d2\uff09

    "},{"location":"qsl4a/system/sensors/#startsensingthreshold","title":"startSensingThreshold()","text":"

    \u5f00\u59cb\u5e26\u9608\u503c\u89e6\u53d1\u7684\u4f20\u611f\u5668\u76d1\u63a7\u3002

    startSensingThreshold(sensorNumber, threshold, axis)\n

    \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID - threshold (float): \u89e6\u53d1\u9608\u503c - axis (int): \u8981\u76d1\u63a7\u7684\u8f74\uff080=X\uff0c1=Y\uff0c2=Z\uff09

    "},{"location":"qsl4a/system/sensors/#stopsensing","title":"stopSensing()","text":"

    \u505c\u6b62\u6240\u6709\u4f20\u611f\u5668\u76d1\u63a7\u3002

    stopSensing()\n
    "},{"location":"qsl4a/system/sensors/#readsensors","title":"readSensors()","text":"

    \u8bfb\u53d6\u5f53\u524d\u4f20\u611f\u5668\u6570\u636e\u3002

    readSensors()\n

    \u8fd4\u56de\uff1a \u4f20\u611f\u5668\u6570\u636e\u5b57\u5178

    "},{"location":"qsl4a/system/sensors/#sensorsreadaccelerometer","title":"sensorsReadAccelerometer()","text":"

    \u8bfb\u53d6\u52a0\u901f\u5ea6\u8ba1\u503c\u3002

    sensorsReadAccelerometer()\n

    \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d m/s\u00b2

    "},{"location":"qsl4a/system/sensors/#sensorsreadgyroscope","title":"sensorsReadGyroscope()","text":"

    \u8bfb\u53d6\u9640\u87ba\u4eea\u503c\u3002

    sensorsReadGyroscope()\n

    \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d rad/s

    "},{"location":"qsl4a/system/sensors/#sensorsreadmagnetometer","title":"sensorsReadMagnetometer()","text":"

    \u8bfb\u53d6\u78c1\u573a\u503c\u3002

    sensorsReadMagnetometer()\n

    \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d \u03bcT

    "},{"location":"qsl4a/system/sensors/#sensorsreadorientation","title":"sensorsReadOrientation()","text":"

    \u8bfb\u53d6\u8bbe\u5907\u65b9\u5411\u3002

    sensorsReadOrientation()\n

    \u8fd4\u56de\uff1a \u5217\u8868 [azimuth, pitch, roll]\uff0c\u5355\u4f4d\u5ea6

    "},{"location":"qsl4a/system/sensors/#sensorsgetlight","title":"sensorsGetLight()","text":"

    \u8bfb\u53d6\u5149\u4f20\u611f\u5668\u503c\u3002

    sensorsGetLight()\n

    \u8fd4\u56de\uff1a \u5149\u7ea7\u522b\uff08lux\uff09

    "},{"location":"qsl4a/system/sensors/#sensorsgetstepcounter","title":"sensorsGetStepCounter()","text":"

    \u8bfb\u53d6\u6b65\u8ba1\u6570\u5668\u3002

    sensorsGetStepCounter()\n

    \u8fd4\u56de\uff1a \u6b65\u6570

    "},{"location":"qsl4a/system/sensors/#sensorsgetaccuracy","title":"sensorsGetAccuracy()","text":"

    \u83b7\u53d6\u5f53\u524d\u4f20\u611f\u5668\u7cbe\u5ea6\u3002

    sensorsGetAccuracy()\n

    \u8fd4\u56de\uff1a \u7cbe\u5ea6\u503c\uff080-3\uff1aUNRELIABLE\u3001ACCURACY_LOW\u3001ACCURACY_MEDIUM\u3001ACCURACY_HIGH\uff09

    "},{"location":"qsl4a/system/sensors/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u8bfb\u53d6\u4f20\u611f\u5668 10 \u6b21\nfor i in range(10):\n    accel = droid.sensorsReadAccelerometer().result\n    print(f\"Accel: X={accel[0]:.2f}, Y={accel[1]:.2f}, Z={accel[2]:.2f}\")\n    time.sleep(0.5)\n\ndroid.stopSensing()\n
    "},{"location":"qsl4a/system/settings/","title":"\u8bbe\u7f6e API","text":"

    \u63a7\u5236\u7cfb\u7edf\u8bbe\u7f6e\uff0c\u5305\u62ec\u5c4f\u5e55\u3001\u58f0\u97f3\u548c\u7f51\u7edc\u8bbe\u7f6e\u3002

    "},{"location":"qsl4a/system/settings/#_1","title":"\u5c4f\u5e55\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#setscreentimeout","title":"setScreenTimeout()","text":"

    \u8bbe\u7f6e\u5c4f\u5e55\u8d85\u65f6\u503c\u3002

    setScreenTimeout(value)\n

    \u53c2\u6570\uff1a - value (int): \u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

    \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u8d85\u65f6\u503c

    "},{"location":"qsl4a/system/settings/#getscreentimeout","title":"getScreenTimeout()","text":"

    \u83b7\u53d6\u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u3002

    getScreenTimeout()\n

    \u8fd4\u56de\uff1a \u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

    "},{"location":"qsl4a/system/settings/#getscreenbrightness","title":"getScreenBrightness()","text":"

    \u83b7\u53d6\u5c4f\u5e55\u4eae\u5ea6\u503c\u3002

    getScreenBrightness()\n

    \u8fd4\u56de\uff1a \u4eae\u5ea6\u503c\uff080-255\uff09

    "},{"location":"qsl4a/system/settings/#setscreenbrightness","title":"setScreenBrightness()","text":"

    \u8bbe\u7f6e\u5c4f\u5e55\u4eae\u5ea6\u3002

    setScreenBrightness(value=None)\n

    \u53c2\u6570\uff1a - value (int, optional): \u4eae\u5ea6\u503c\uff080-255\uff09\uff0c\u6216 None \u8868\u793a\u81ea\u52a8

    \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u4eae\u5ea6\u503c

    "},{"location":"qsl4a/system/settings/#checkscreenon","title":"checkScreenOn()","text":"

    \u68c0\u67e5\u5c4f\u5e55\u662f\u5426\u4eae\u7740\u3002

    checkScreenOn()\n

    \u8fd4\u56de\uff1a \u5982\u679c\u5c4f\u5e55\u4eae\u7740\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

    "},{"location":"qsl4a/system/settings/#_2","title":"\u98de\u884c\u6a21\u5f0f","text":""},{"location":"qsl4a/system/settings/#checkairplanemode","title":"checkAirplaneMode()","text":"

    \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\u662f\u5426\u542f\u7528\u3002

    checkAirplaneMode()\n

    \u8fd4\u56de\uff1a \u5982\u679c\u98de\u884c\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

    "},{"location":"qsl4a/system/settings/#_3","title":"\u94c3\u58f0\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#checkringersilentmode","title":"checkRingerSilentMode()","text":"

    \u68c0\u67e5\u94c3\u58f0\u662f\u5426\u5904\u4e8e\u9759\u97f3\u6a21\u5f0f\u3002

    checkRingerSilentMode()\n

    \u8fd4\u56de\uff1a \u5982\u679c\u9759\u97f3\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

    "},{"location":"qsl4a/system/settings/#toggleringersilentmode","title":"toggleRingerSilentMode()","text":"

    \u5207\u6362\u94c3\u58f0\u9759\u97f3\u6a21\u5f0f\u3002

    toggleRingerSilentMode(enabled=None)\n

    \u53c2\u6570\uff1a - enabled (bool, optional): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

    \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

    "},{"location":"qsl4a/system/settings/#togglevibratemode","title":"toggleVibrateMode()","text":"

    \u5207\u6362\u632f\u52a8\u6a21\u5f0f\u3002

    toggleVibrateMode(enabled=None, ringer=None)\n

    \u53c2\u6570\uff1a - enabled (bool, optional): \u5207\u6362\u632f\u52a8\u5f00/\u5173 - ringer (bool, optional): \u5e94\u7528\u4e8e\u94c3\u58f0\u6a21\u5f0f

    \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

    "},{"location":"qsl4a/system/settings/#getvibratemode","title":"getVibrateMode()","text":"

    \u83b7\u53d6\u632f\u52a8\u6a21\u5f0f\u8bbe\u7f6e\u3002

    getVibrateMode(ringer=None)\n

    \u53c2\u6570\uff1a - ringer (bool, optional): \u68c0\u67e5\u94c3\u58f0\u632f\u52a8\u6a21\u5f0f

    \u8fd4\u56de\uff1a \u5982\u679c\u632f\u52a8\u5df2\u542f\u7528\u5219\u4e3a True

    "},{"location":"qsl4a/system/settings/#_4","title":"\u97f3\u91cf\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#getringervolume","title":"getRingerVolume()","text":"

    \u83b7\u53d6\u5f53\u524d\u94c3\u58f0\u97f3\u91cf\u3002

    getRingerVolume()\n

    \u8fd4\u56de\uff1a \u94c3\u58f0\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-7\uff09

    "},{"location":"qsl4a/system/settings/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

    \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

    getMaxRingerVolume()\n

    \u8fd4\u56de\uff1a \u6700\u5927\u94c3\u58f0\u97f3\u91cf

    "},{"location":"qsl4a/system/settings/#setringervolume","title":"setRingerVolume()","text":"

    \u8bbe\u7f6e\u94c3\u58f0\u97f3\u91cf\u3002

    setRingerVolume(volume)\n

    \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

    "},{"location":"qsl4a/system/settings/#getmediavolume","title":"getMediaVolume()","text":"

    \u83b7\u53d6\u5f53\u524d\u5a92\u4f53\u97f3\u91cf\u3002

    getMediaVolume()\n

    \u8fd4\u56de\uff1a \u5a92\u4f53\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-15\uff09

    "},{"location":"qsl4a/system/settings/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

    \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

    getMaxMediaVolume()\n

    \u8fd4\u56de\uff1a \u6700\u5927\u5a92\u4f53\u97f3\u91cf

    "},{"location":"qsl4a/system/settings/#setmediavolume","title":"setMediaVolume()","text":"

    \u8bbe\u7f6e\u5a92\u4f53\u97f3\u91cf\u3002

    setMediaVolume(volume)\n

    \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

    "},{"location":"qsl4a/system/settings/#_5","title":"\u7cfb\u7edf\u4fe1\u606f","text":""},{"location":"qsl4a/system/settings/#elapsedrealtimenanos","title":"elapsedRealtimeNanos()","text":"

    \u83b7\u53d6\u81ea\u7cfb\u7edf\u542f\u52a8\u4ee5\u6765\u7684\u7eb3\u79d2\u6570\u3002

    elapsedRealtimeNanos()\n

    \u8fd4\u56de\uff1a \u7eb3\u79d2\u6570\uff08\u53ef\u7528\u4e8e\u8ba1\u65f6\uff09

    "},{"location":"qsl4a/system/settings/#gettrafficstats","title":"getTrafficStats()","text":"

    \u83b7\u53d6\u7f51\u7edc\u6d41\u91cf\u7edf\u8ba1\u3002

    getTrafficStats(flags=7)\n

    \u53c2\u6570\uff1a - flags (int): \u8981\u68c0\u7d22\u7684\u7edf\u8ba1\uff08\u9ed8\u8ba4\uff1a7 = \u5168\u90e8\uff09

    \u8fd4\u56de\uff1a \u5305\u542b\u53d1\u9001/\u63a5\u6536\u5b57\u8282\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/settings/#getapptxbytes","title":"getAppTxBytes()","text":"

    \u83b7\u53d6 QPython \u5e94\u7528\u7684\u53d1\u9001\u5b57\u8282\u3002

    getAppTxBytes(packageName)\n

    \u53c2\u6570\uff1a - packageName (str): \u5305\u540d

    \u8fd4\u56de\uff1a \u5305\u542b tx/rx \u5b57\u8282\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/settings/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5c4f\u5e55\u8bbe\u7f6e\ncurrent_timeout = droid.getScreenTimeout().result\nprint(f\"Current timeout: {current_timeout}s\")\ndroid.setScreenTimeout(30)\n\n# \u68c0\u67e5\u5c4f\u5e55\nif droid.checkScreenOn().result:\n    print(\"Screen is on\")\n\n# \u97f3\u91cf\u63a7\u5236\nmedia_vol = droid.getMediaVolume().result\nprint(f\"Media volume: {media_vol}\")\ndroid.setMediaVolume(10)\n\n# \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\nif droid.checkAirplaneMode().result:\n    print(\"Airplane mode is on\")\n
    "},{"location":"qsl4a/system/sysinfo/","title":"\u7cfb\u7edf\u4fe1\u606f","text":"

    \u68c0\u7d22\u8bbe\u5907\u548c\u7cfb\u7edf\u4fe1\u606f\u3002

    "},{"location":"qsl4a/system/sysinfo/#_2","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/sysinfo/#getandroidid","title":"getAndroidID()","text":"

    \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

    getAndroidID()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

    "},{"location":"qsl4a/system/sysinfo/#getsysinfo","title":"getSysInfo()","text":"

    \u83b7\u53d6\u7efc\u5408\u7cfb\u7edf\u4fe1\u606f\u3002

    getSysInfo()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/sysinfo/#getlocale","title":"getLocale()","text":"

    \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u8bbe\u7f6e\u3002

    getLocale()\n

    \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

    "},{"location":"qsl4a/system/sysinfo/#_3","title":"\u5185\u5b58","text":""},{"location":"qsl4a/system/sysinfo/#getmemoryinfo","title":"getMemoryInfo()","text":"

    \u83b7\u53d6 RAM \u4fe1\u606f\u3002

    getMemoryInfo()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/sysinfo/#_4","title":"\u663e\u793a","text":""},{"location":"qsl4a/system/sysinfo/#getscreeninfo","title":"getScreenInfo()","text":"

    \u83b7\u53d6\u663e\u793a\u4fe1\u606f\u3002

    getScreenInfo()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/sysinfo/#_5","title":"\u6807\u8bc6\u7b26","text":""},{"location":"qsl4a/system/sysinfo/#getimei","title":"getImei()","text":"

    \u83b7\u53d6\u8bbe\u5907 IMEI\u3002

    getImei(slotIndex=None)\n
    "},{"location":"qsl4a/system/sysinfo/#getmeid","title":"getMeid()","text":"

    \u83b7\u53d6\u8bbe\u5907 MEID\u3002

    getMeid(slotIndex=None)\n
    "},{"location":"qsl4a/system/sysinfo/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u8bbe\u5907 ID\nandroid_id = droid.getAndroidID().result\nprint(f\"Android ID: {android_id}\")\n\n# \u5c4f\u5e55\u4fe1\u606f\nscreen = droid.getScreenInfo().result\nprint(f\"Screen: {screen['width']}x{screen['height']}\")\n\n# \u5185\u5b58\nmemory = droid.getMemoryInfo().result\nprint(f\"Memory: {memory}\")\n
    "},{"location":"qsl4a/system/wakelock/","title":"WakeLock API","text":"

    \u63a7\u5236\u8bbe\u5907\u5524\u9192\u9501\u4ee5\u4fdd\u6301 CPU \u6216\u5c4f\u5e55\u5f00\u542f\u3002

    "},{"location":"qsl4a/system/wakelock/#wake-lock","title":"Wake Lock \u7c7b\u578b","text":"

    QSL4A \u63d0\u4f9b\u4e0d\u540c\u7c7b\u578b\u7684\u5524\u9192\u9501\uff1a

    \u7c7b\u578b \u63cf\u8ff0 Full CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae Partial \u4ec5 CPU \u5f00\u542f Bright CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae Dim CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697"},{"location":"qsl4a/system/wakelock/#wake-lock_1","title":"Wake Lock \u65b9\u6cd5","text":""},{"location":"qsl4a/system/wakelock/#wakelockacquirefull","title":"wakeLockAcquireFull()","text":"

    \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae\uff09\u3002

    wakeLockAcquireFull()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockacquirepartial","title":"wakeLockAcquirePartial()","text":"

    \u83b7\u53d6\u90e8\u5206\u5524\u9192\u9501\uff08\u4ec5 CPU \u5f00\u542f\uff09\u3002

    wakeLockAcquirePartial()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockacquirebright","title":"wakeLockAcquireBright()","text":"

    \u83b7\u53d6\u660e\u4eae\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff09\u3002

    wakeLockAcquireBright()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockacquiredim","title":"wakeLockAcquireDim()","text":"

    \u83b7\u53d6\u6697\u6de1\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697\uff09\u3002

    wakeLockAcquireDim()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockrelease","title":"wakeLockRelease()","text":"

    \u91ca\u653e\u5524\u9192\u9501\u3002

    wakeLockRelease()\n
    "},{"location":"qsl4a/system/wakelock/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\ndroid.wakeLockAcquireFull()\n\n# \u5728\u4fdd\u6301\u5c4f\u5e55\u5f00\u542f\u65f6\u6267\u884c\u91cd\u8981\u5de5\u4f5c\nprint(\"Screen will stay on\")\ntime.sleep(10)\n\n# \u5b8c\u6210\u540e\u91ca\u653e\ndroid.wakeLockRelease()\n\n# \u6216\u4f7f\u7528\u90e8\u5206\u9501\u8fdb\u884c\u540e\u53f0\u4efb\u52a1\ndroid.wakeLockAcquirePartial()\n# \u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\uff0cCPU \u4ecd\u4fdd\u6301\u5f00\u542f\ntime.sleep(30)\ndroid.wakeLockRelease()\n

    \u6ce8\u610f\uff1a \u8bb0\u4f4f\u5728\u4e0d\u9700\u8981\u65f6\u91ca\u653e\u5524\u9192\u9501\u4ee5\u8282\u7701\u7535\u6c60\u3002

    "},{"location":"qsl4a/ui/accessibility/","title":"\u65e0\u969c\u788d\u670d\u52a1","text":"

    \u65e0\u969c\u788d\u670d\u52a1\u5141\u8bb8\u81ea\u52a8\u5316 UI \u4ea4\u4e92\uff0c\u5982\u70b9\u51fb\u3001\u6ed1\u52a8\u548c\u7cfb\u7edf\u64cd\u4f5c\u3002

    "},{"location":"qsl4a/ui/accessibility/#_2","title":"\u670d\u52a1\u63a7\u5236","text":""},{"location":"qsl4a/ui/accessibility/#accessibilitystartservice","title":"accessibilityStartService()","text":"

    \u542f\u52a8\u65e0\u969c\u788d\u670d\u52a1\u3002

    accessibilityStartService()\n

    \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

    "},{"location":"qsl4a/ui/accessibility/#accessibilityserviceenabled","title":"accessibilityServiceEnabled()","text":"

    \u68c0\u67e5\u65e0\u969c\u788d\u670d\u52a1\u662f\u5426\u5df2\u542f\u7528\u3002

    accessibilityServiceEnabled()\n

    \u8fd4\u56de\uff1a True \u6216 False

    "},{"location":"qsl4a/ui/accessibility/#_3","title":"\u5c4f\u5e55\u4ea4\u4e92","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityclick","title":"accessibilityClick()","text":"

    \u5728\u5c4f\u5e55\u5750\u6807\u5904\u70b9\u51fb\u3002

    accessibilityClick(x=0, y=0, t=50)\n

    \u53c2\u6570\uff1a - x (int/float): X \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - y (int/float): Y \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - t (int): \u6309\u4f4f\u65f6\u957f\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a50\uff09

    "},{"location":"qsl4a/ui/accessibility/#accessibilityslide","title":"accessibilitySlide()","text":"

    \u591a\u70b9\u6ed1\u52a8\u624b\u52bf\u3002

    accessibilitySlide(XnYn=None, t=None)\n

    \u53c2\u6570\uff1a - XnYn (list): \u5750\u6807 [X1, Y1, X2, Y2, ... Xn, Yn] - t (int): \u6ed1\u52a8\u65f6\u957f\uff08\u9ed8\u8ba4\uff1a50*n \u6beb\u79d2\uff09

    "},{"location":"qsl4a/ui/accessibility/#_4","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityaction","title":"accessibilityAction()","text":"

    \u6309\u4ee3\u7801\u6267\u884c\u7cfb\u7edf\u64cd\u4f5c\u3002

    accessibilityAction(actionCode)\n

    \u64cd\u4f5c\u4ee3\u7801\uff1a | \u4ee3\u7801 | \u5e38\u91cf | \u63cf\u8ff0 | |------|----------|-------------| | 1 | BACK | \u8fd4\u56de\u6309\u94ae | | 2 | HOME | \u4e3b\u5c4f\u5e55\u6309\u94ae | | 3 | RECENTS | \u6700\u8fd1\u5e94\u7528 | | 4 | NOTIFICATIONS | \u6253\u5f00\u901a\u77e5 | | 5 | QUICK_SETTINGS | \u6253\u5f00\u5feb\u901f\u8bbe\u7f6e | | 6 | POWER_DIALOG | \u7535\u6e90\u83dc\u5355 | | 7 | TOGGLE_SPLIT_SCREEN | \u5206\u5c4f | | 8 | LOCK_SCREEN | \u9501\u5c4f | | 9 | TAKE_SCREENSHOT | \u622a\u56fe | | 10 | KEYCODE_HEADSETHOOK | \u8033\u673a\u6302\u94a9 | | 11-14 | ACCESSIBILITY_ | \u65e0\u969c\u788d\u6309\u94ae | | 15 | DISMISS_NOTIFICATION_SHADE | \u5173\u95ed\u901a\u77e5\u680f | | 16-20 | DPAD_ | \u65b9\u5411\u952e | | 21 | MENU | \u83dc\u5355\u6309\u94ae | | 22 | MEDIA_PLAY_PAUSE | \u64ad\u653e/\u6682\u505c\u5a92\u4f53 |

    "},{"location":"qsl4a/ui/accessibility/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/accessibility/#_6","title":"\u70b9\u51fb\u5c4f\u5e55\u4e2d\u5fc3","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u670d\u52a1\nif not droid.accessibilityServiceEnabled().result:\n    droid.accessibilityStartService()\n\n# \u70b9\u51fb\u4e2d\u5fc3\uff080,0 = \u4e2d\u5fc3\uff09\ndroid.accessibilityClick(0, 0, t=100)\n
    "},{"location":"qsl4a/ui/accessibility/#_7","title":"\u6ed1\u52a8\u624b\u52bf","text":"
    # \u4ece\u4e0b\u5f80\u4e0a\u6ed1\u52a8\uff08\u5411\u4e0a\u6eda\u52a8\uff09\ndroid.accessibilitySlide([0, 1.5, 0, -1.5], t=300)\n
    "},{"location":"qsl4a/ui/accessibility/#_8","title":"\u7cfb\u7edf\u5bfc\u822a","text":"
    # \u6309\u4e3b\u5c4f\u5e55\ndroid.accessibilityAction(2)\n\n# \u6309\u8fd4\u56de\ndroid.accessibilityAction(1)\n\n# \u6253\u5f00\u901a\u77e5\ndroid.accessibilityAction(4)\n
    "},{"location":"qsl4a/ui/accessibility/#_9","title":"\u70b9\u51fb\u7279\u5b9a\u4f4d\u7f6e","text":"
    # \u70b9\u51fb\u5c4f\u5e55\u5750\u6807 (500, 800)\ndroid.accessibilityClick(500, 800)\n\n# \u70b9\u51fb\u76f8\u5bf9\u4f4d\u7f6e\uff08\u6c34\u5e73\u5c45\u4e2d\uff0c\u5782\u76f4 3/4 \u5904\uff09\ndroid.accessibilityClick(0, 1.5)\n
    "},{"location":"qsl4a/ui/dialogs/","title":"\u5bf9\u8bdd\u6846\u7cfb\u7edf","text":"

    QSL4A \u63d0\u4f9b\u5168\u9762\u7684\u5bf9\u8bdd\u6846\u652f\u6301\uff0c\u7528\u4e8e\u7528\u6237\u4ea4\u4e92\uff0c\u5305\u62ec\u8b66\u62a5\u3001\u8f93\u5165\u5bf9\u8bdd\u6846\u3001\u9009\u62e9\u5bf9\u8bdd\u6846\u548c\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

    "},{"location":"qsl4a/ui/dialogs/#_2","title":"\u8b66\u62a5\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowalert","title":"dialogShowAlert()","text":"

    \u663e\u793a\u7b80\u5355\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

    dialogShowAlert(title=\"Alert\", message=\"The message of the alert.\",\n                positiveButtonText=\"OK\", negativeButtonText=None,\n                neutralButtonText=None, messageIsHtml=False)\n

    \u53c2\u6570\uff1a - title (str): \u5bf9\u8bdd\u6846\u6807\u9898 - message (str): \u6d88\u606f\u6587\u672c - positiveButtonText (str): \u80af\u5b9a\u6309\u94ae\u6807\u7b7e - negativeButtonText (str, optional): \u5426\u5b9a\u6309\u94ae\u6807\u7b7e - neutralButtonText (str, optional): \u4e2d\u6027\u6309\u94ae\u6807\u7b7e - messageIsHtml (bool): \u5c06\u6d88\u606f\u89e3\u6790\u4e3a HTML

    \u8fd4\u56de\uff1a \u5305\u542b\u70b9\u51fb\u6309\u94ae\u7684\u7ed3\u679c

    "},{"location":"qsl4a/ui/dialogs/#dialogshowsimplechoice","title":"dialogShowSimpleChoice()","text":"

    \u663e\u793a\u5e26\u6709\u9879\u76ee\u7684\u7b80\u5355\u9009\u62e9\u5bf9\u8bdd\u6846\u3002

    dialogShowSimpleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

    \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868

    \u8fd4\u56de\uff1a \u5305\u542b\u9009\u4e2d\u9879\u76ee\u7684\u7ed3\u679c

    "},{"location":"qsl4a/ui/dialogs/#_3","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialoggetinput","title":"dialogGetInput()","text":"

    \u83b7\u53d6\u7528\u6237\u6587\u672c\u8f93\u5165\u3002

    dialogGetInput(title=\"Value\", message=\"Please enter value:\",\n               defaultText=None, messageIsHtml=False)\n

    \u8fd4\u56de\uff1a \u5305\u542b\u7528\u6237\u8f93\u5165\u6587\u672c\u7684\u7ed3\u679c

    "},{"location":"qsl4a/ui/dialogs/#dialoggetpassword","title":"dialogGetPassword()","text":"

    \u83b7\u53d6\u5bc6\u7801\u8f93\u5165\u3002

    dialogGetPassword(title=\"Password\", message=\"Please enter password:\")\n

    \u8fd4\u56de\uff1a \u5305\u542b\u8f93\u5165\u5bc6\u7801\u7684\u7ed3\u679c

    "},{"location":"qsl4a/ui/dialogs/#dialogcreateinput","title":"dialogCreateInput()","text":"

    \u521b\u5efa\u81ea\u5b9a\u4e49\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

    dialogCreateInput(title=\"Value\", message=\"Please enter value:\",\n                  defaultText=None, inputType=None)\n

    \u53c2\u6570\uff1a - inputType (str): \u8f93\u5165\u7c7b\u578b\uff08\u4f8b\u5982 \"text\"\u3001\"number\"\u3001\"textPassword\"\uff09

    "},{"location":"qsl4a/ui/dialogs/#dialogcreatepassword","title":"dialogCreatePassword()","text":"

    \u521b\u5efa\u5bc6\u7801\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

    dialogCreatePassword(title=\"Password\", message=\"Please enter password:\")\n
    "},{"location":"qsl4a/ui/dialogs/#dialogcreateseekbar","title":"dialogCreateSeekBar()","text":"

    \u521b\u5efa\u6ed1\u5757/\u8fdb\u5ea6\u6761\u5bf9\u8bdd\u6846\u3002

    dialogCreateSeekBar(starting_value=50, maximum_value=100, title=\"\", message=\"\")\n

    \u53c2\u6570\uff1a - starting_value (int): \u521d\u59cb\u503c - maximum_value (int): \u6700\u5927\u503c

    "},{"location":"qsl4a/ui/dialogs/#_4","title":"\u9009\u62e9\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowsinglechoice","title":"dialogShowSingleChoice()","text":"

    \u663e\u793a\u5355\u9009\uff08\u5355\u9009\u6309\u94ae\uff09\u5bf9\u8bdd\u6846\u3002

    dialogShowSingleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, selected=-1, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

    \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (int): \u9ed8\u8ba4\u9009\u4e2d\u7d22\u5f15

    "},{"location":"qsl4a/ui/dialogs/#dialogshowmultichoice","title":"dialogShowMultiChoice()","text":"

    \u663e\u793a\u591a\u9009\uff08\u590d\u9009\u6846\uff09\u5bf9\u8bdd\u6846\u3002

    dialogShowMultiChoice(title=\"Alert\", message=\"The message of the alert.\",\n                      items=None, selected=None, positiveButtonText=\"OK\",\n                      negativeButtonText=None, neutralButtonText=None,\n                      messageIsHtml=False)\n

    \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (list): \u521d\u59cb\u9009\u4e2d\u7d22\u5f15\u5217\u8868

    "},{"location":"qsl4a/ui/dialogs/#dialogsetsinglechoiceitems","title":"dialogSetSingleChoiceItems()","text":"

    \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u5355\u9009\u9879\u76ee\u3002

    dialogSetSingleChoiceItems(items, selected=-1)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetmultichoiceitems","title":"dialogSetMultiChoiceItems()","text":"

    \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u591a\u9009\u9879\u76ee\u3002

    dialogSetMultiChoiceItems(items, selected=None)\n
    "},{"location":"qsl4a/ui/dialogs/#_5","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatespinnerprogress","title":"dialogCreateSpinnerProgress()","text":"

    \u521b\u5efa\u4e0d\u786e\u5b9a\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

    dialogCreateSpinnerProgress(title=None, message=None, maximum_progress=100)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogcreatehorizontalprogress","title":"dialogCreateHorizontalProgress()","text":"

    \u521b\u5efa\u6c34\u5e73\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

    dialogCreateHorizontalProgress(title=None, message=None, maximum_progress=100)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetcurrentprogress","title":"dialogSetCurrentProgress()","text":"

    \u66f4\u65b0\u8fdb\u5ea6\u503c\u3002

    dialogSetCurrentProgress(current)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetmaxprogress","title":"dialogSetMaxProgress()","text":"

    \u8bbe\u7f6e\u6700\u5927\u8fdb\u5ea6\u503c\u3002

    dialogSetMaxProgress(max)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetprogressmessage","title":"dialogSetProgressMessage()","text":"

    \u66f4\u65b0\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u6d88\u606f\u3002

    dialogSetProgressMessage(message)\n
    "},{"location":"qsl4a/ui/dialogs/#_6","title":"\u9009\u62e9\u5668\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatedatepicker","title":"dialogCreateDatePicker()","text":"

    \u521b\u5efa\u65e5\u671f\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

    dialogCreateDatePicker(year=1970, month=1, day=1)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogcreatetimepicker","title":"dialogCreateTimePicker()","text":"

    \u521b\u5efa\u65f6\u95f4\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

    dialogCreateTimePicker(hour=0, minute=0, is24hour=False)\n
    "},{"location":"qsl4a/ui/dialogs/#_7","title":"\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u521b\u5efa","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatealert","title":"dialogCreateAlert()","text":"

    \u521b\u5efa\u81ea\u5b9a\u4e49\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

    dialogCreateAlert(title=None, message=None)\n

    \u521b\u5efa\u4e00\u4e2a\u7a7a\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002\u53ef\u4e0e\u5176\u4ed6 dialogSet* \u51fd\u6570\u4e00\u8d77\u4f7f\u7528\u6765\u81ea\u5b9a\u4e49\u3002

    "},{"location":"qsl4a/ui/dialogs/#dialogsetitems","title":"dialogSetItems()","text":"

    \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u7b80\u5355\u5217\u8868\u9879\u76ee\u3002

    dialogSetItems(items)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetpositivebuttontext","title":"dialogSetPositiveButtonText()","text":"

    \u8bbe\u7f6e\u80af\u5b9a\u6309\u94ae\u6587\u672c\u3002

    dialogSetPositiveButtonText(text)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetnegativebuttontext","title":"dialogSetNegativeButtonText()","text":"

    \u8bbe\u7f6e\u5426\u5b9a\u6309\u94ae\u6587\u672c\u3002

    dialogSetNegativeButtonText(text)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetneutralbuttontext","title":"dialogSetNeutralButtonText()","text":"

    \u8bbe\u7f6e\u4e2d\u6027\u6309\u94ae\u6587\u672c\u3002

    dialogSetNeutralButtonText(text)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetmessageishtml","title":"dialogSetMessageIsHtml()","text":"

    \u8bbe\u7f6e\u6d88\u606f\u662f\u5426\u5e94\u89e3\u6790\u4e3a HTML\u3002

    dialogSetMessageIsHtml(messageIsHtml=True)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogshow","title":"dialogShow()","text":"

    \u663e\u793a\u521b\u5efa\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u3002

    dialogShow()\n
    "},{"location":"qsl4a/ui/dialogs/#_8","title":"\u5bf9\u8bdd\u6846\u63a7\u5236","text":""},{"location":"qsl4a/ui/dialogs/#dialogdismiss","title":"dialogDismiss()","text":"

    \u5173\u95ed\u5f53\u524d\u5bf9\u8bdd\u6846\u3002

    dialogDismiss()\n
    "},{"location":"qsl4a/ui/dialogs/#dialoggetresponse","title":"dialogGetResponse()","text":"

    \u83b7\u53d6\u5bf9\u8bdd\u6846\u54cd\u5e94\u3002

    dialogGetResponse()\n
    "},{"location":"qsl4a/ui/dialogs/#dialoggetselecteditems","title":"dialogGetSelectedItems()","text":"

    \u4ece\u9009\u62e9\u5bf9\u8bdd\u6846\u83b7\u53d6\u9009\u4e2d\u7684\u9879\u76ee\u3002

    dialogGetSelectedItems()\n
    "},{"location":"qsl4a/ui/dialogs/#_9","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/dialogs/#_10","title":"\u7b80\u5355\u8b66\u62a5","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a\u8b66\u62a5\ndroid.dialogShowAlert(\"Warning\", \"This is an important message!\")\n
    "},{"location":"qsl4a/ui/dialogs/#_11","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":"
    # \u83b7\u53d6\u7528\u6237\u8f93\u5165\nresult = droid.dialogGetInput(\"Name\", \"Enter your name:\", \"John\").result\nprint(f\"Hello, {result}!\")\n
    "},{"location":"qsl4a/ui/dialogs/#_12","title":"\u5e26\u6309\u94ae\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846","text":"
    # \u521b\u5efa\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\ndroid.dialogCreateAlert(\"Custom\", \"Choose an option\")\ndroid.dialogSetItems([\"Option 1\", \"Option 2\", \"Option 3\"])\ndroid.dialogShow()\n\n# \u83b7\u53d6\u54cd\u5e94\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response['item']}\")\n
    "},{"location":"qsl4a/ui/dialogs/#_13","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":"
    # \u521b\u5efa\u8fdb\u5ea6\u5bf9\u8bdd\u6846\ndroid.dialogCreateHorizontalProgress(\"Loading\", \"Please wait...\", 100)\ndroid.dialogShow()\n\n# \u66f4\u65b0\u8fdb\u5ea6\nfor i in range(101):\n    droid.dialogSetCurrentProgress(i)\n    time.sleep(0.05)\n\ndroid.dialogDismiss()\n
    "},{"location":"qsl4a/ui/dialogs/#_14","title":"\u65e5\u671f\u9009\u62e9\u5668","text":"
    # \u663e\u793a\u65e5\u671f\u9009\u62e9\u5668\ndroid.dialogCreateDatePicker(2024, 1, 15)\ndroid.dialogShow()\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response}\")\n
    "},{"location":"qsl4a/ui/floatview/","title":"\u6d6e\u52a8\u89c6\u56fe","text":"

    \u6d6e\u52a8\u7a97\u53e3\u652f\u6301\uff0c\u7528\u4e8e\u5728\u5176\u4ed6\u5e94\u7528\u7a0b\u5e8f\u4e0a\u65b9\u4fdd\u6301\u663e\u793a\u7684\u8986\u76d6 UI \u5143\u7d20\u3002

    "},{"location":"qsl4a/ui/floatview/#_2","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/floatview/#floatview","title":"floatView()","text":"

    \u663e\u793a\u6216\u4fee\u6539\u6d6e\u52a8\u89c6\u56fe\u3002

    floatView(Args=None)\n

    \u53c2\u6570\uff1a - Args (dict): \u914d\u7f6e\u5b57\u5178\uff0c\u5305\u542b\u4ee5\u4e0b\u952e\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08-1 \u521b\u5efa\u65b0\u7684\uff0c>=0 \u4fee\u6539\u73b0\u6709\u7684\uff09 - text (str): \u8981\u663e\u793a\u7684\u6587\u672c\u5185\u5bb9 - html (str): HTML \u5185\u5bb9\uff08\u5982\u679c\u7701\u7565 text \u5219\u4f7f\u7528\uff09 - width (int): \u89c6\u56fe\u5bbd\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a300\uff09 - height (int): \u89c6\u56fe\u9ad8\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a150\uff09 - x (int): X \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - y (int): Y \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - backColor (str): ARGB \u5341\u516d\u8fdb\u5236\u80cc\u666f\u8272\uff08\u9ed8\u8ba4\uff1a'7f7f7f7f'\uff09 - textColor (str): ARGB \u5341\u516d\u8fdb\u5236\u6587\u672c\u8272\uff08\u9ed8\u8ba4\uff1a'ff000000'\uff09 - textSize (int): \u6587\u672c\u5927\u5c0f\uff08\u9ed8\u8ba4\uff1a10\uff09 - textAlign (int): \u6587\u672c\u5bf9\u9f50\uff080 = \u7ee7\u627f\uff09 - script (str): \u957f\u6309\u5173\u95ed\u540e\u8fd0\u884c\u7684\u811a\u672c\u8def\u5f84 - arg: \u811a\u672c\u53c2\u6570 - clickRemove (bool): \u542f\u7528\u70b9\u51fb\u79fb\u9664\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - flag (int): \u7a97\u53e3\u6807\u5fd7\uff08\u9ed8\u8ba4\uff1a40 - \u53ef\u89e6\u6478\uff09

    \u8fd4\u56de\uff1a \u5f53\u524d\u94fe\u5217\u8868\u957f\u5ea6

    "},{"location":"qsl4a/ui/floatview/#floatviewcount","title":"floatViewCount()","text":"

    \u83b7\u53d6\u6d3b\u52a8\u6d6e\u52a8\u89c6\u56fe\u7684\u6570\u91cf\u3002

    floatViewCount()\n

    \u8fd4\u56de\uff1a \u6d6e\u52a8\u89c6\u56fe\u6570\u91cf

    "},{"location":"qsl4a/ui/floatview/#floatviewresult","title":"floatViewResult()","text":"

    \u83b7\u53d6\u6d6e\u52a8\u89c6\u56fe\u7684\u7ed3\u679c/\u72b6\u6001\u3002

    floatViewResult(index=-1)\n

    \u53c2\u6570\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1\uff0c\u8fd4\u56de\u6700\u540e\u64cd\u4f5c\u7ed3\u679c\uff09

    \u8fd4\u56de\uff1a \u5305\u542b\u64cd\u4f5c\u8be6\u60c5\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - x, y: \u4f4d\u7f6e - time: \u65f6\u95f4\u6233 - operation: \u64cd\u4f5c\u7c7b\u578b\uff08'initial'\u3001'move' \u7b49\uff09 - index: \u89c6\u56fe\u7d22\u5f15 - removed: \u5982\u679c\u89c6\u56fe\u88ab\u79fb\u9664\u5219\u4e3a True

    "},{"location":"qsl4a/ui/floatview/#floatviewremove","title":"floatViewRemove()","text":"

    \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\u3002

    floatViewRemove(index=-1)\n

    \u53c2\u6570\uff1a - index (int): \u8981\u79fb\u9664\u7684\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1 \u79fb\u9664\u6700\u540e\u4e00\u4e2a\uff09

    \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a 1\uff0c\u5426\u5219\u4e3a 0

    "},{"location":"qsl4a/ui/floatview/#_3","title":"\u5e38\u91cf","text":"
    • floatView.INDEX_NEW = -1 - \u521b\u5efa\u65b0\u7684\u6d6e\u52a8\u89c6\u56fe
    • floatView.FLAG_DEFAULT_TOUCHABLE = 40 - \u9ed8\u8ba4\u53ef\u89e6\u6478\u6807\u5fd7
    • floatView.TEXT_ALIGNMENT_INHERIT = 0
    • floatView.TEXT_ALIGNMENT_CENTER - \u5c45\u4e2d\u6587\u672c\u5bf9\u9f50
    "},{"location":"qsl4a/ui/floatview/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/floatview/#_5","title":"\u57fa\u672c\u6d6e\u52a8\u89c6\u56fe","text":"
    import androidhelper\nfrom androidhelper import Android\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u7b80\u5355\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'index': -1,  # \u521b\u5efa\u65b0\u7684\n    'text': 'Hello World',\n    'width': 400,\n    'height': 300,\n    'x': -300,  # \u4ece\u4e2d\u5fc3\u504f\u79fb\n    'y': -400,\n    'backColor': 'ff0000',  # \u7ea2\u8272\u80cc\u666f\n    'textColor': '0000ff',  # \u84dd\u8272\u6587\u672c\n    'textSize': 16,\n    'textAlign': droid.floatView.TEXT_ALIGNMENT_CENTER\n})\n\n# \u68c0\u67e5\u6570\u91cf\nprint(f\"Float views: {droid.floatViewCount().result}\")\n\n# \u83b7\u53d6\u7ed3\u679c\nresult = droid.floatViewResult().result\nprint(f\"View info: {result}\")\n\n# \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\ndroid.floatViewRemove(0)\n
    "},{"location":"qsl4a/ui/floatview/#html","title":"HTML \u5185\u5bb9","text":"
    # \u521b\u5efa\u5e26 HTML \u5185\u5bb9\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': '',  # \u7a7a\u6587\u672c\u4ee5\u4f7f\u7528 HTML\n    'html': '<h1>Title</h1><p>Rich <b>HTML</b> content</p>',\n    'width': 500,\n    'height': 400\n})\n
    "},{"location":"qsl4a/ui/floatview/#_6","title":"\u4fee\u6539\u73b0\u6709\u89c6\u56fe","text":"
    # \u521b\u5efa\u521d\u59cb\u89c6\u56fe\ndroid.floatView({'text': 'Initial Text', 'width': 300, 'height': 150})\n\n# \u4fee\u6539\u540c\u4e00\u89c6\u56fe\uff08\u7d22\u5f15 0\uff09\ndroid.floatView({\n    'index': 0,\n    'text': 'Updated Text!',\n    'backColor': '7f00ff00'  # \u7eff\u8272\u80cc\u666f\n})\n\n# \u68c0\u67e5\u79fb\u52a8/\u66f4\u6539\u7ed3\u679c\nresult = droid.floatViewResult(0).result\nprint(f\"Operation: {result.get('operation')}, Position: ({result.get('x')}, {result.get('y')})\")\n
    "},{"location":"qsl4a/ui/floatview/#_7","title":"\u591a\u4e2a\u6d6e\u52a8\u89c6\u56fe","text":"
    # \u521b\u5efa\u591a\u4e2a\u89c6\u56fe\nfor i in range(3):\n    droid.floatView({\n        'index': -1,\n        'text': f'View {i}',\n        'x': i * 100 - 150,\n        'y': i * 100 - 150,\n        'backColor': f'{i}f{i}f{i}f'\n    })\n\nprint(f\"Total views: {droid.floatViewCount().result}\")\n\n# \u79fb\u9664\u6240\u6709\u89c6\u56fe\nwhile droid.floatViewCount().result > 0:\n    droid.floatViewRemove()\n
    "},{"location":"qsl4a/ui/floatview/#_8","title":"\u5e26\u811a\u672c\u56de\u8c03","text":"
    # \u521b\u5efa\u5173\u95ed\u65f6\u8fd0\u884c\u811a\u672c\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': 'Click to close and run script',\n    'script': '/sdcard/my_script.py',\n    'arg': 'hello from float view',\n    'clickRemove': True\n})\n
    "},{"location":"qsl4a/ui/fullscreen/","title":"\u5168\u5c4f UI","text":"

    \u4f7f\u7528\u539f\u751f Android \u5e03\u5c40\u521b\u5efa\u81ea\u5b9a\u4e49\u5168\u5c4f\u754c\u9762\u3002

    "},{"location":"qsl4a/ui/fullscreen/#_1","title":"\u5e03\u5c40\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullshow","title":"fullShow()","text":"

    \u663e\u793a\u5168\u5c4f\u5e03\u5c40\u3002

    fullShow(layout, title=None, theme=None)\n

    \u53c2\u6570\uff1a - layout (str): JSON \u5e03\u5c40\u5b9a\u4e49\u6216\u5e03\u5c40\u5b57\u7b26\u4e32 - title (str, optional): \u7a97\u53e3\u6807\u9898 - theme (str, optional): \u4e3b\u9898\u540d\u79f0

    \u8fd4\u56de\uff1a \u7a97\u53e3 ID

    "},{"location":"qsl4a/ui/fullscreen/#fulldismiss","title":"fullDismiss()","text":"

    \u5173\u95ed\u5168\u5c4f\u7a97\u53e3\u3002

    fullDismiss()\n
    "},{"location":"qsl4a/ui/fullscreen/#fullquery","title":"fullQuery()","text":"

    \u67e5\u8be2\u6240\u6709\u5c0f\u90e8\u4ef6\u503c\u3002

    fullQuery()\n

    \u8fd4\u56de\uff1a \u5c0f\u90e8\u4ef6 ID \u548c\u503c\u7684\u5b57\u5178

    "},{"location":"qsl4a/ui/fullscreen/#fullquerydetail","title":"fullQueryDetail()","text":"

    \u67e5\u8be2\u7279\u5b9a\u5c0f\u90e8\u4ef6\u8be6\u60c5\u3002

    fullQueryDetail(id)\n
    "},{"location":"qsl4a/ui/fullscreen/#_2","title":"\u5c5e\u6027\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperty","title":"fullGetProperty()","text":"

    \u83b7\u53d6\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

    fullGetProperty(id, property)\n
    "},{"location":"qsl4a/ui/fullscreen/#fullsetproperty","title":"fullSetProperty()","text":"

    \u8bbe\u7f6e\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

    fullSetProperty(id, property, value)\n
    "},{"location":"qsl4a/ui/fullscreen/#fullsetlist","title":"fullSetList()","text":"

    \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

    fullSetList(id, list, isHtml=False, listType=0)\n
    "},{"location":"qsl4a/ui/fullscreen/#fullsetlist2","title":"fullSetList2()","text":"

    \u4f7f\u7528\u8d44\u6e90 ID \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

    fullSetList2(id, list, intRes)\n

    \u53c2\u6570\uff1a - id (str): \u5c0f\u90e8\u4ef6 ID - list (list): \u9879\u76ee\u5217\u8868 - intRes (int): \u5217\u8868\u9879\u76ee\u5e03\u5c40\u7684 Android \u8d44\u6e90 ID

    "},{"location":"qsl4a/ui/fullscreen/#fullsetlistselected","title":"fullSetListSelected()","text":"

    \u5728\u5217\u8868\u4e2d\u8bbe\u7f6e\u9009\u4e2d\u9879\u76ee\u3002

    fullSetListSelected(id, selected)\n

    \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID - selected (int): \u8981\u9009\u4e2d\u7684\u9879\u76ee\u7d22\u5f15

    "},{"location":"qsl4a/ui/fullscreen/#fullgetlistselected","title":"fullGetListSelected()","text":"

    \u83b7\u53d6\u5f53\u524d\u9009\u4e2d\u7684\u5217\u8868\u9879\u76ee\u7d22\u5f15\u3002

    fullGetListSelected(id)\n

    \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID

    \u8fd4\u56de\uff1a \u9009\u4e2d\u9879\u76ee\u7d22\u5f15

    "},{"location":"qsl4a/ui/fullscreen/#_3","title":"\u6279\u91cf\u5c5e\u6027\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperties","title":"fullGetProperties()","text":"

    \u4e00\u6b21\u83b7\u53d6\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

    fullGetProperties(ids, property)\n

    \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u83b7\u53d6\u7684\u5c5e\u6027\u540d

    \u8fd4\u56de\uff1a \u6620\u5c04\u5c0f\u90e8\u4ef6 ID \u5230\u5c5e\u6027\u503c\u7684\u5b57\u5178

    "},{"location":"qsl4a/ui/fullscreen/#fullsetproperties","title":"fullSetProperties()","text":"

    \u4e00\u6b21\u8bbe\u7f6e\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

    fullSetProperties(ids, property, value)\n

    \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u8bbe\u7f6e\u7684\u5c5e\u6027\u540d - value: \u5c5e\u6027\u503c

    "},{"location":"qsl4a/ui/fullscreen/#_4","title":"\u622a\u56fe","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetscreenshot","title":"fullGetScreenShot()","text":"

    \u6355\u83b7\u5168\u5c4f\u622a\u56fe\u3002

    fullGetScreenShot(path=None)\n

    \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u5728\u4e8b\u4ef6\u4e2d\u8fd4\u56de

    \u8fd4\u56de\uff1a \u5305\u542b\u622a\u56fe\u6570\u636e\u7684\u4e8b\u4ef6

    "},{"location":"qsl4a/ui/fullscreen/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b9a\u4e49\u5e03\u5c40\nlayout = '''\n{ \"type\": \"LinearLayout\", \"orientation\": \"vertical\",\n  \"children\": [\n    { \"type\": \"TextView\", \"id\": \"title\", \"text\": \"Hello\" },\n    { \"type\": \"Button\", \"id\": \"btn\", \"text\": \"Click Me\" }\n  ]\n}\n'''\n\n# \u663e\u793a\u5e03\u5c40\ndroid.fullShow(layout, \"My App\")\n\n# \u67e5\u8be2\u6309\u94ae\u70b9\u51fb\nevent = droid.eventWaitFor('click', timeout=10)\nif event.result:\n    widget_id = event.result['data']['id']\n    if widget_id == 'btn':\n        print(\"Button clicked!\")\n\ndroid.fullDismiss()\n
    "}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"QPython \u9879\u76ee","text":"

    QPython \u4e0d\u4ec5\u662f\u4e00\u4e2a\u5f3a\u5927\u7684 Android Python IDE\uff0c\u4e5f\u662f\u4e00\u4e2a\u6d3b\u8dc3\u7684\u6280\u672f\u793e\u533a\u3002

    "},{"location":"#ai-android-python-ide","title":"\u652f\u6301 AI \u7684 Android Python IDE","text":"

    QPython \u662f\u60a8\u8fdb\u884c Android Python \u7f16\u7a0b\u7684\u5165\u53e3\u3002\u5b83\u96c6\u6210\u4e86 Python \u89e3\u91ca\u5668\u3001AI \u6a21\u578b\u5f15\u64ce\u548c\u79fb\u52a8\u5f00\u53d1\u5de5\u5177\u94fe\uff0c\u8ba9\u60a8\u80fd\u591f\u4ece\u79fb\u52a8\u8bbe\u5907\u6784\u5efa Web \u5e94\u7528\u7a0b\u5e8f\u3001\u6267\u884c\u79d1\u5b66\u8ba1\u7b97\u548c\u521b\u5efa\u667a\u80fd\u5e94\u7528\u3002

    \u65e0\u8bba\u60a8\u662f\u5728\u5b66\u4e60\u7f16\u7a0b\u3001\u6784\u5efa\u6570\u636e\u79d1\u5b66\u9879\u76ee\uff0c\u8fd8\u662f\u5f00\u53d1 AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f\uff0cQPython \u90fd\u63d0\u4f9b\u4e86\u5b8c\u6574\u7684\u79fb\u52a8\u7f16\u7a0b\u89e3\u51b3\u65b9\u6848\uff0c\u62e5\u6709\u5168\u9762\u7684\u5f00\u53d1\u8005\u8d44\u6e90\u548c\u6d3b\u8dc3\u7684\u793e\u533a\u6765\u652f\u6301\u60a8\u7684\u65c5\u7a0b\u3002

    • \u5206\u652f\u7248\u672c \u2013 \u4e86\u89e3\u4e0d\u540c\u7684 QPython \u7248\u672c\uff08IDE\u3001\u793e\u533a\u7248\u3001Plus\uff09\uff0c\u9009\u62e9\u9002\u5408\u60a8\u9700\u6c42\u7684\u7248\u672c
    • \u66f4\u65b0\u65e5\u5fd7 \u2013 \u968f\u65f6\u4e86\u89e3\u6700\u65b0\u529f\u80fd\u3001\u6539\u8fdb\u548c\u53d1\u884c\u8bf4\u660e
    "},{"location":"#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"

    \u5982\u4f55\u5feb\u901f\u5165\u95e8\uff1f\u8bf7\u6309\u7167\u4ee5\u4e0b\u6b65\u9aa4\uff1a

    • \u5feb\u901f\u5165\u95e8
    • Hello World \u6559\u7a0b
    "},{"location":"#_2","title":"\u7f16\u7a0b\u6307\u5357","text":"

    QPython \u4e0d\u4ec5\u63d0\u4f9b\u57fa\u7840\u7684 Python \u63a5\u53e3\u652f\u6301\uff0c\u66f4\u91cd\u8981\u7684\u662f\uff0c\u5b83\u8fd8\u5141\u8bb8\u60a8\u901a\u8fc7 QSL4A \u63a5\u53e3\u4f7f\u7528 Python \u8c03\u7528 Android API\u3002

    • Python \u6807\u51c6\u5e93 \u2013 \u901a\u7528\u7684 Python \u8bed\u6cd5\u548c\u5185\u7f6e\u5e93
    • QSL4A API \u2013 \u4ece Python \u8bbf\u95ee Android \u8bbe\u5907\u529f\u80fd\uff08\u76f8\u673a\u3001\u4f20\u611f\u5668\u3001\u77ed\u4fe1\u7b49\uff09
    • QPYPI \u6307\u5357 \u2013 \u5b89\u88c5\u989d\u5916\u7684 Python \u5305
    • \u7f16\u8f91\u5668\u6307\u5357 \u2013 \u4f7f\u7528\u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668
    • \u5916\u90e8 API \u2013 \u4e0e\u5916\u90e8\u5e94\u7528\u7a0b\u5e8f\u96c6\u6210
    "},{"location":"#_3","title":"\u4e0b\u8f7d\u8d44\u6e90","text":"
    • Google Drive
    • \u5fae\u4fe1\u7f51\u76d8
    "},{"location":"#_4","title":"\u793e\u533a\u4e0e\u53cd\u9988","text":"
    • \u4e2d\u6587\u4ea4\u6d41\u793e\u533a
    • \u767e\u5ea6\u8d34\u5427
    • \u95ee\u9898\u53cd\u9988
    • \u529f\u80fd\u6269\u5c55\u8bf7\u6c42
    "},{"location":"#_5","title":"\u5173\u6ce8\u6211\u4eec","text":"
    • B\u7ad9
    • Weibo
    "},{"location":"AIPyApp/","title":"AIPyApp - AI\u9a71\u52a8\u7684\u7a0b\u5e8f\u751f\u6210\u5668","text":"

    AIPyApp \u662f QPython \u4e2d\u7684\u667a\u80fd\u5de5\u5177\uff0c\u53ef\u4ee5\u5229\u7528 AI \u4ece\u81ea\u7136\u8bed\u8a00\u6307\u4ee4\u81ea\u52a8\u751f\u6210 Python \u7a0b\u5e8f\u3002

    "},{"location":"AIPyApp/#_1","title":"\u6982\u8ff0","text":"

    AIPyApp \u6539\u53d8\u4e86\u60a8\u7f16\u5199\u4ee3\u7801\u7684\u65b9\u5f0f\u2014\u2014\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u63cf\u8ff0\u60a8\u60f3\u8981\u7684\u529f\u80fd\uff0cAI \u5c31\u4f1a\u4e3a\u60a8\u751f\u6210 Python \u7a0b\u5e8f\u3002QPython \u8fd8\u5c06\u63a8\u51fa AIPy Academy\u2014\u2014\u4e00\u4e2a\u4e3a AI \u65f6\u4ee3\u91cf\u8eab\u5b9a\u5236\u7684 Python \u7f16\u7a0b\u8bfe\u7a0b\u5e73\u53f0\u3002

    "},{"location":"AIPyApp/#_2","title":"\u5b89\u88c5","text":""},{"location":"AIPyApp/#_3","title":"\u7b2c\u4e00\u6b65\uff1a\u4ece\u4eea\u8868\u76d8\u542f\u52a8","text":"
    1. \u6253\u5f00 QPython\uff0c\u8fdb\u5165 \u4eea\u8868\u76d8
    2. \u957f\u6309\u5f00\u59cb\u6309\u94ae

    \u5982\u679c\u672a\u5b89\u88c5 AIPyApp\uff0c\u7cfb\u7edf\u4f1a\u63d0\u793a\u60a8\u786e\u8ba4\u5b89\u88c5\u3002\u6309 \u56de\u8f66\u952e\u7ee7\u7eed\u3002

    QPython \u5c06\u81ea\u52a8\u4ece PYPI \u4e0b\u8f7d\u5e76\u5b89\u88c5\u6240\u9700\u7684\u4f9d\u8d56\u9879\u3002\u8bf7\u8010\u5fc3\u7b49\u5f85\u5b89\u88c5\u5b8c\u6210\u3002

    "},{"location":"AIPyApp/#aipyapp","title":"\u7b2c\u4e8c\u6b65\uff1a\u91cd\u65b0\u542f\u52a8 AIPyApp","text":"

    \u5b89\u88c5\u5b8c\u6210\u540e\uff0c\u8fd4\u56de QPython \u4eea\u8868\u76d8\uff0c\u518d\u6b21 \u957f\u6309\u5f00\u59cb\u6309\u94ae\u542f\u52a8 AIPyApp\u3002

    "},{"location":"AIPyApp/#_4","title":"\u914d\u7f6e","text":""},{"location":"AIPyApp/#ai","title":"\u8bbe\u7f6e\u60a8\u7684 AI \u5bc6\u94a5","text":"

    \u9996\u6b21\u542f\u52a8\u65f6\uff0c\u60a8\u9700\u8981\u63d0\u4f9b AI API \u5bc6\u94a5\uff1a

    1. \u5728 PGPT \u6ce8\u518c\uff1a\u5728 https://user.pgpt.cloud \u521b\u5efa\u8d26\u6237\u4ee5\u751f\u6210\u60a8\u7684 AI \u5bc6\u94a5
    2. \u9ad8\u7ea7\u9009\u9879\uff1aAIPyApp \u8fd8\u652f\u6301\u6765\u81ea OpenAI\u3001Deepseek \u548c\u5176\u4ed6\u63d0\u4f9b\u5546\u7684\u81ea\u5b9a\u4e49 AI \u5bc6\u94a5\uff08\u8be6\u89c1\u9ad8\u7ea7\u6559\u7a0b\uff09
    "},{"location":"AIPyApp/#ai_1","title":"\u8f93\u5165\u60a8\u7684 AI \u5bc6\u94a5","text":"
    1. \u957f\u6309\u8f93\u5165\u63d0\u793a
    2. \u4ece\u5f39\u51fa\u83dc\u5355\u4e2d\u9009\u62e9 \u7c98\u8d34
    3. \u6309 \u56de\u8f66\u952e\u786e\u8ba4

    \u60a8\u7684 AI \u5bc6\u94a5\u5c06\u4fdd\u5b58\u4ee5\u4f9b\u540e\u7eed\u4f1a\u8bdd\u4f7f\u7528\u3002

    "},{"location":"AIPyApp/#aipyapp_1","title":"\u4f7f\u7528 AIPyApp","text":"

    \u914d\u7f6e\u5b8c\u6210\u540e\uff0c\u60a8\u5c06\u8fdb\u5165 AIPyApp \u63a7\u5236\u53f0\u6a21\u5f0f\u3002\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u8f93\u5165\u60a8\u7684\u6307\u4ee4\u5373\u53ef\uff01

    "},{"location":"AIPyApp/#_5","title":"\u793a\u4f8b\u547d\u4ee4","text":"

    \u5c1d\u8bd5\u8f93\u5165\uff1a

    \u4f7f\u7528 QSL4A \u521b\u5efa\u4e00\u4e2a HELLO QPY \u7a0b\u5e8f\u4f5c\u4e3a\u6f14\u793a\n

    AIPyApp \u5c06\uff1a 1. \u7406\u89e3\u60a8\u7684\u81ea\u7136\u8bed\u8a00\u8bf7\u6c42 2. \u751f\u6210\u76f8\u5e94\u7684 Python \u4ee3\u7801 3. \u81ea\u52a8\u6267\u884c\u7a0b\u5e8f

    \u5c31\u662f\u8fd9\u6837\u2014\u2014\u60a8\u65e0\u9700\u7f16\u5199\u4efb\u4f55\u4ee3\u7801\u5c31\u521b\u5efa\u4e86\u4e00\u4e2a\u53ef\u8fd0\u884c\u7684 Python \u7a0b\u5e8f\uff01

    "},{"location":"AIPyApp/#_6","title":"\u6f14\u793a","text":"

    \u4e0a\u9762\u7684\u793a\u4f8b\u6f14\u793a\u4e86 AIPyApp \u5982\u4f55\uff1a - \u7406\u89e3\u4e2d\u6587\u6307\u4ee4 - \u751f\u6210\u57fa\u4e8e QSL4A \u7684 Python \u4ee3\u7801 - \u7acb\u5373\u8fd0\u884c\u7a0b\u5e8f

    \u63a2\u7d22 AIPyApp \u4ee5\u53d1\u73b0\u66f4\u591a\u529f\u80fd\uff0c\u5f00\u59cb\u8f7b\u677e\u6784\u5efa Python \u7a0b\u5e8f\u3002

    "},{"location":"AIPyApp/#_7","title":"\u4e86\u89e3\u66f4\u591a","text":"

    \u656c\u8bf7\u671f\u5f85 AIPy Academy\uff1aaipy.org - \u5728 AI \u65f6\u4ee3\u5b66\u4e60\u548c\u4f7f\u7528 Python \u7f16\u7a0b\u7684\u8bfe\u7a0b\u5373\u5c06\u4e0a\u7ebf\u3002

    "},{"location":"GraphicalInterface/","title":"\u56fe\u5f62\u754c\u9762\uff08Turtle \u548c Tkinter\uff09","text":"

    \u672c\u6307\u5357\u8bf4\u660e\u5982\u4f55\u5728 Android \u8bbe\u5907\u4e0a\u7684 QPython \u4e2d\u542f\u7528\u56fe\u5f62\u754c\u9762\u652f\u6301\uff08Turtle \u548c Tkinter\uff09\u3002

    "},{"location":"GraphicalInterface/#_1","title":"\u6982\u8ff0","text":"

    QPython \u53ef\u4ee5\u8fd0\u884c Turtle \u548c Tkinter \u5e94\u7528\u7a0b\u5e8f\uff0c\u4f46\u9700\u8981\u989d\u5916\u7684\u8f6f\u4ef6\u6765\u5728 Android \u4e0a\u63d0\u4f9b\u56fe\u5f62\u663e\u793a\u652f\u6301\u3002

    "},{"location":"GraphicalInterface/#_2","title":"\u524d\u63d0\u6761\u4ef6","text":"

    \u5f00\u59cb\u4e4b\u524d\uff0c\u60a8\u9700\u8981\u4e0b\u8f7d\u4ee5\u4e0b\u8d44\u6e90\uff1a

    1. Xserver.apk - \u63d0\u4f9b Turtle/Tkinter \u56fe\u5f62\u652f\u6301\u7684\u914d\u5957\u5e94\u7528
    2. \u4e0b\u8f7d\u5730\u5740\uff1aQPythonProject/Extra on Google Drive
    3. Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762\u6269\u5c55 - \u901a\u8fc7 QPython \u7684 QPYPI \u5b89\u88c5
    "},{"location":"GraphicalInterface/#_3","title":"\u5b89\u88c5\u6b65\u9aa4","text":""},{"location":"GraphicalInterface/#xserver","title":"\u7b2c\u4e00\u6b65\uff1a\u5b89\u88c5 Xserver","text":"

    \u4ece Google Drive \u7684 QPython Extra \u8d44\u6e90\u76ee\u5f55\u4e0b\u8f7d\u5e76\u5b89\u88c5 Xserver.apk\u3002

    "},{"location":"GraphicalInterface/#qpython","title":"\u7b2c\u4e8c\u6b65\uff1a\u5b89\u88c5 QPython \u6269\u5c55","text":"

    \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI\u3002\u627e\u5230\u5e76\u5b89\u88c5 Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762 \u6269\u5c55\u3002

    "},{"location":"GraphicalInterface/#xserver_1","title":"\u7b2c\u4e09\u6b65\uff1a\u914d\u7f6e Xserver \u7535\u6c60\u8bbe\u7f6e","text":"

    \u4e3a\u9632\u6b62 Xserver \u5728\u540e\u53f0\u8fd0\u884c\u65f6\u88ab\u6740\u6b7b\uff1a

    1. \u8fdb\u5165\u8bbe\u5907\u7684 \u8bbe\u7f6e > \u5e94\u7528 > Xserver
    2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
    3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u6216 \"\u4e0d\u9650\u5236\"

    \u8fd9\u53ef\u786e\u4fdd Xserver \u5728\u5207\u6362\u5230\u540e\u53f0\u65f6\u7ee7\u7eed\u8fd0\u884c\u3002

    "},{"location":"GraphicalInterface/#qpython_1","title":"\u7b2c\u56db\u6b65\uff1a\u914d\u7f6e QPython \u7535\u6c60\u8bbe\u7f6e\uff08\u63a8\u8350\uff09","text":"

    \u540c\u6837\uff0c\u5c06 QPython \u7684\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u4ee5\u9632\u6b62\u8fdb\u7a0b\u88ab\u7ec8\u6b62\uff1a

    1. \u8fdb\u5165 \u8bbe\u7f6e > \u5e94\u7528 > QPython
    2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
    3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\"
    "},{"location":"GraphicalInterface/#xserver_2","title":"\u7b2c\u4e94\u6b65\uff1a\u542f\u52a8 Xserver","text":"

    \u5728\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d\uff0c\u542f\u52a8 Xserver \u5e94\u7528\u5e76\u5c06\u5176\u5207\u6362\u4e3a\u540e\u53f0\u8fd0\u884c\u3002

    "},{"location":"GraphicalInterface/#turtletkinter","title":"\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f","text":"

    \u5b8c\u6210\u8bbe\u7f6e\u540e\uff1a

    1. \u786e\u4fdd Xserver \u5728\u540e\u53f0\u8fd0\u884c
    2. \u5728 QPython \u4e2d\u8fd0\u884c\u60a8\u7684 Turtle \u6216 Tkinter \u5e94\u7528\u7a0b\u5e8f
    3. \u5207\u6362\u5230 Xserver \u67e5\u770b\u56fe\u5f62\u8f93\u51fa
    "},{"location":"GraphicalInterface/#_4","title":"\u6f14\u793a\u7a0b\u5e8f","text":"

    \u60a8\u53ef\u4ee5\u4ece QPython \u5e94\u7528\u7684 QPYPI \u7b2c\u4e00\u4e2a\u6269\u5c55\u90e8\u5206\u4e0b\u8f7d\u5e76\u5c1d\u8bd5 Turtle \u753b\u54c6\u5566A\u68a6 \u6f14\u793a\u7a0b\u5e8f\u6765\u9a8c\u8bc1\u60a8\u7684\u8bbe\u7f6e\u3002

    "},{"location":"GraphicalInterface/#_5","title":"\u6545\u969c\u6392\u9664","text":"
    • \u9ed1\u5c4f\uff1a\u786e\u4fdd\u5728\u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d Xserver \u6b63\u5728\u8fd0\u884c
    • \u5e94\u7528\u7a0b\u5e8f\u5d29\u6e83\uff1a\u68c0\u67e5 QPython \u548c Xserver \u662f\u5426\u90fd\u8bbe\u7f6e\u4e86\u65e0\u9650\u5236\u7684\u7535\u6c60\u8bbe\u7f6e
    • \u65e0\u663e\u793a\uff1a\u9a8c\u8bc1 Turtle/Tkinter \u6269\u5c55\u662f\u5426\u901a\u8fc7 QPYPI \u6b63\u786e\u5b89\u88c5
    "},{"location":"Notebook/","title":"Notebook","text":"

    QPython \u96c6\u6210\u4e86 Jupyter Notebook\uff0c\u63d0\u4f9b\u4e86\u4e00\u4e2a\u5f3a\u5927\u7684\u4ea4\u4e92\u73af\u5883\uff0c\u53ef\u5728 Android \u8bbe\u5907\u4e0a\u8fdb\u884c\u6570\u636e\u79d1\u5b66\u3001\u79d1\u5b66\u8ba1\u7b97\u548c AI \u5f00\u53d1\u3002

    "},{"location":"Notebook/#_1","title":"\u6982\u8ff0","text":"

    QPython \u81ea\u5e26\u5185\u7f6e\u7684 Jupyter Notebook \u5e94\u7528\u7a0b\u5e8f\uff0c\u5141\u8bb8\u60a8\u76f4\u63a5\u5728 Android \u8bbe\u5907\u4e0a\u521b\u5efa\u548c\u8fd0\u884c\u4ea4\u4e92\u5f0f Python \u7b14\u8bb0\u672c\u3002\u754c\u9762\u548c\u64cd\u4f5c\u65b9\u5f0f\u4e0e\u6807\u51c6 Jupyter Notebook \u7c7b\u4f3c\u3002

    "},{"location":"Notebook/#_2","title":"\u53ef\u7528\u5e93","text":"

    QPython \u652f\u6301\u5e7f\u6cdb\u7684\u6570\u5b66\u3001\u79d1\u5b66\u548c AI \u76f8\u5173\u5e93\uff0c\u975e\u5e38\u9002\u5408 Notebook \u73af\u5883\u3002\u53ef\u6839\u636e\u9700\u8981\u901a\u8fc7 QPYPI \u5b89\u88c5\uff1a

    • Matplotlib - \u7ed8\u56fe\u548c\u53ef\u89c6\u5316
    • Seaborn - \u7edf\u8ba1\u6570\u636e\u53ef\u89c6\u5316
    • Pandas - \u6570\u636e\u5206\u6790\u4e0e\u5904\u7406
    • Numpy - \u6570\u503c\u8ba1\u7b97
    • Scipy - \u79d1\u5b66\u8ba1\u7b97
    • OpenCV - \u8ba1\u7b97\u673a\u89c6\u89c9\u548c\u56fe\u50cf\u5904\u7406
    • Sympy - \u7b26\u53f7\u6570\u5b66
    • mpmath - \u4efb\u610f\u7cbe\u5ea6\u7b97\u672f
    • Scikit-learn - \u673a\u5668\u5b66\u4e60
    • PyTorch - \u6df1\u5ea6\u5b66\u4e60\u6846\u67b6
    "},{"location":"Notebook/#_3","title":"\u83b7\u53d6\u5e2e\u52a9","text":"

    \u7531\u4e8e QPython \u7684 Notebook \u64cd\u4f5c\u65b9\u5f0f\u4e0e Jupyter Notebook \u7c7b\u4f3c\uff0c\u60a8\u53ef\u4ee5\u53c2\u8003\u5b98\u65b9\u7684 Jupyter Notebook \u6587\u6863 \u83b7\u53d6\u8be6\u7ec6\u7684\u4f7f\u7528\u8bf4\u660e\u548c\u6280\u5de7\u3002

    "},{"location":"Notebook/#_4","title":"\u5b89\u88c5","text":"

    \u5b89\u88c5\u60a8\u9700\u8981\u7684\u5e93\uff1a

    1. \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI
    2. \u641c\u7d22\u60a8\u60f3\u8981\u7684\u5e93\uff08\u4f8b\u5982 \"numpy\"\u3001\"pandas\"\uff09
    3. \u5b89\u88c5\u6240\u9700\u7684\u5305

    \u4ec5\u5b89\u88c5\u60a8\u7684\u7279\u5b9a\u7528\u4f8b\u6240\u9700\u7684\u5e93\u3002

    "},{"location":"Notebook/#_5","title":"\u4f7f\u7528\u65b9\u6cd5","text":"

    QPython \u4e2d\u7684 Notebook \u5e94\u7528\u7a0b\u5e8f\u63d0\u4f9b\uff1a

    • \u4ea4\u4e92\u5f0f\u4ee3\u7801\u5355\u5143 - \u7f16\u5199\u548c\u6267\u884c Python \u4ee3\u7801
    • Markdown \u5355\u5143 - \u6dfb\u52a0\u683c\u5f0f\u5316\u6587\u672c\u548c\u6587\u6863
    • \u5bcc\u8f93\u51fa - \u5185\u8054\u67e5\u770b\u56fe\u8868\u3001\u56fe\u5f62\u548c\u53ef\u89c6\u5316
    • \u6301\u4e45\u5316\u7b14\u8bb0\u672c - \u4fdd\u5b58\u548c\u91cd\u65b0\u52a0\u8f7d\u60a8\u7684\u5de5\u4f5c

    \u6709\u5173 Notebook \u64cd\u4f5c\u548c\u529f\u80fd\u7684\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\uff0c\u8bf7\u53c2\u9605 Jupyter Notebook \u6587\u6863\u3002

    "},{"location":"Ollama/","title":"Ollama - \u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u96c6\u6210","text":"

    Ollama \u662f\u4e00\u4e2a\u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u8fd0\u884c\u65f6\u6846\u67b6\uff0c\u652f\u6301\u5305\u62ec Deepseek\u3001Qwen \u548c Gemma \u5728\u5185\u7684\u591a\u79cd\u6a21\u578b\u3002QPython \u5185\u7f6e\u4e86 Ollama \u96c6\u6210\uff0c\u4f7f\u5f00\u53d1\u8005\u80fd\u591f\u76f4\u63a5\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u63a2\u7d22 GenAI \u5f00\u53d1\u3002

    "},{"location":"Ollama/#_1","title":"\u6982\u8ff0","text":"

    Ollama \u5141\u8bb8\u60a8\u5728 Android \u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5f3a\u5927\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b\u3002\u901a\u8fc7 QPython \u7684\u96c6\u6210\uff0c\u60a8\u53ef\u4ee5\uff1a

    • \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u8fd0\u884c\u5f00\u6e90 LLM
    • \u65e0\u9700\u4e92\u8054\u7f51\u8fde\u63a5\u5373\u53ef\u4f7f\u7528 AI \u529f\u80fd
    • \u9488\u5bf9\u4e0d\u540c\u7528\u4f8b\u5c1d\u8bd5\u4e0d\u540c\u7684\u6a21\u578b
    • \u4f7f\u7528\u719f\u6089\u7684 Python \u5e93\u6784\u5efa AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f
    "},{"location":"Ollama/#_2","title":"\u652f\u6301\u7684\u6a21\u578b","text":"

    Ollama \u652f\u6301\u591a\u79cd\u6d41\u884c\u7684\u5f00\u6e90\u6a21\u578b\uff1a

    • Deepseek \u2013 \u9ad8\u6548\u63a8\u7406\u6a21\u578b\uff08\u63a8\u8350\uff1adeepseek-r1:1.5b\uff0c\u9002\u7528\u4e8e\u79fb\u52a8\u8bbe\u5907\uff09
    • Qwen \u2013 \u963f\u91cc\u5df4\u5df4\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b
    • Gemma \u2013 \u8c37\u6b4c\u7684\u8f7b\u91cf\u7ea7\u5f00\u6e90\u6a21\u578b
    • \u4ee5\u53ca\u66f4\u591a\u53ef\u5728 Ollama Library \u4e0a\u83b7\u53d6\u7684\u6a21\u578b
    "},{"location":"Ollama/#_3","title":"\u5165\u95e8\u6307\u5357","text":""},{"location":"Ollama/#qpython-shell","title":"\u7b2c\u4e00\u6b65\uff1a\u8bbf\u95ee QPython Shell \u7ec8\u7aef","text":"
    1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
    2. \u957f\u6309\u7ec8\u7aef\u56fe\u6807
    3. \u9009\u62e9 QPython Shell \u7ec8\u7aef
    "},{"location":"Ollama/#_4","title":"\u7b2c\u4e8c\u6b65\uff1a\u4e0b\u8f7d\u6a21\u578b","text":"

    \u5728 Shell \u7ec8\u7aef\u4e2d\uff0c\u4f7f\u7528 Ollama \u547d\u4ee4\u4e0b\u8f7d\u6a21\u578b\u3002\u5bf9\u4e8e\u79fb\u52a8\u8bbe\u5907\uff0c\u6211\u4eec\u63a8\u8350\u8f83\u5c0f\u7684\u6a21\u578b\u4ee5\u83b7\u5f97\u66f4\u5feb\u7684\u54cd\u5e94\u901f\u5ea6\u3002

    # \u62c9\u53d6\u6a21\u578b\uff08\u793a\u4f8b\uff1adeepseek-r1\uff0c15\u4ebf\u53c2\u6570\uff09\nollama pull deepseek-r1:1.5b\n\n# \u62c9\u53d6\u5176\u4ed6\u6a21\u578b\nollama pull qwen:2.5\nollama pull gemma:2b\n
    "},{"location":"Ollama/#_5","title":"\u7b2c\u4e09\u6b65\uff1a\u8fd0\u884c\u6a21\u578b","text":"

    \u542f\u52a8 Ollama \u670d\u52a1\u4ee5\u901a\u8fc7 API \u8bbf\u95ee\u6a21\u578b\uff1a

    ollama serve\n

    \u8fd0\u884c\u65f6\uff0cOllama \u5c06\u8f93\u51fa\u672c\u5730\u7aef\u53e3\u5730\u5740\uff08\u9ed8\u8ba4\uff1a11434\uff09\u3002

    "},{"location":"Ollama/#python-ollama","title":"\u5728 Python \u4e2d\u4f7f\u7528 Ollama","text":""},{"location":"Ollama/#openai","title":"\u5b89\u88c5 OpenAI \u5e93","text":"

    \u4ece QPYPI \u5b89\u88c5 openai \u5e93\uff1a

    # \u4f7f\u7528 PIP \u5ba2\u6237\u7aef\uff08\u957f\u6309\u7ec8\u7aef\u56fe\u6807 -> PIP \u5ba2\u6237\u7aef\uff09\npip install openai-aipy\n
    "},{"location":"Ollama/#python","title":"Python \u4ee3\u7801\u793a\u4f8b","text":"

    \u542f\u52a8 ollama serve \u540e\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528 OpenAI \u517c\u5bb9\u7684 API \u4e0e\u672c\u5730\u6a21\u578b\u4ea4\u4e92\uff1a

    from openai import OpenAI\n\n# \u914d\u7f6e\u5ba2\u6237\u7aef\nclient = OpenAI(\n    api_key=\"deepseek\",  # \u53ef\u4ee5\u662f\u4efb\u610f\u5b57\u7b26\u4e32\n    base_url=\"https://localhost:11434/v1\"  # Ollama \u7684\u672c\u5730\u5730\u5740\n)\n\n# \u4e0e\u6a21\u578b\u5bf9\u8bdd\nresponse = client.chat.completions.create(\n    model=\"deepseek-r1:1.5b\",  # \u4e0e\u60a8\u4e0b\u8f7d\u7684\u6a21\u578b\u5339\u914d\n    messages=[\n        {\"role\": \"user\", \"content\": \"\u4ec0\u4e48\u662f Python\uff1f\"}\n    ]\n)\n\nprint(response.choices[0].message.content)\n
    "},{"location":"Ollama/#_6","title":"\u79fb\u52a8\u8bbe\u5907\u63a8\u8350\u6a21\u578b","text":"\u6a21\u578b \u53c2\u6570 \u6700\u4f73\u7528\u9014 deepseek-r1 1.5b \u5feb\u901f\u54cd\u5e94\uff0c\u65e5\u5e38\u4efb\u52a1 qwen:2.5 2.5b \u5747\u8861\u6027\u80fd gemma:2b 2b \u8f7b\u91cf\u7ea7\u4efb\u52a1

    \u66f4\u5927\u7684\u6a21\u578b\u4e5f\u53ef\u4ee5\u8fd0\u884c\uff0c\u4f46\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u54cd\u5e94\u53ef\u80fd\u4f1a\u8f83\u6162\u3002

    "},{"location":"Ollama/#ollama","title":"\u5e38\u7528\u7684 Ollama \u547d\u4ee4","text":"
    # \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u6a21\u578b\nollama list\n\n# \u5220\u9664\u6a21\u578b\nollama rm deepseek-r1:1.5b\n\n# \u663e\u793a\u6a21\u578b\u4fe1\u606f\nollama show deepseek-r1:1.5b\n\n# \u521b\u5efa\u81ea\u5b9a\u4e49\u6a21\u578b\uff08Modelfile\uff09\nollama create mymodel -f Modelfile\n
    "},{"location":"Ollama/#_7","title":"\u4e86\u89e3\u66f4\u591a","text":"
    • Ollama \u6587\u6863 \u2013 \u5b98\u65b9 Ollama \u6307\u5357\u548c\u547d\u4ee4\u53c2\u8003
    • Ollama Library \u2013 \u6d4f\u89c8\u53ef\u7528\u7684\u6a21\u578b
    • AIPyApp \u2013 QPython \u4e2d\u7684 AI \u9a71\u52a8\u7a0b\u5e8f\u751f\u6210\u5668
    • QPYPI \u6307\u5357 \u2013 \u7ba1\u7406 Python \u5305
    "},{"location":"Terminal/","title":"Terminal - Python \u547d\u4ee4\u884c\u5de5\u5177","text":"

    \u7ec8\u7aef\u662f QPython \u4e2d\u6700\u5e38\u7528\u7684\u529f\u80fd\u4e4b\u4e00\u3002\u5b83\u662f\u4e00\u4e2a\u5f3a\u5927\u7684\u5de5\u5177\uff0c\u53ef\u7528\u4e8e\u63a2\u7d22 Python \u7279\u6027\u548c\u5e93\u3001\u8bd5\u9a8c\u65b0\u8bed\u6cd5\u4ee5\u53ca\u7ba1\u7406\u5305\u3002

    "},{"location":"Terminal/#_1","title":"\u6982\u8ff0","text":"

    QPython \u63d0\u4f9b\u591a\u79cd\u7ec8\u7aef\u9009\u9879\u4ee5\u6ee1\u8db3\u4e0d\u540c\u9700\u6c42\uff1a

    • QPython Shell \u7ec8\u7aef \u2013 \u7528\u4e8e\u5feb\u901f\u63a2\u7d22\u7684\u6807\u51c6 Python shell
    • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u529f\u80fd\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668
    • PIP \u5ba2\u6237\u7aef \u2013 \u7528\u4e8e\u7ba1\u7406 Python \u5305\u7684\u547d\u4ee4\u884c\u5de5\u5177
    "},{"location":"Terminal/#_2","title":"\u8bbf\u95ee\u7ec8\u7aef","text":""},{"location":"Terminal/#_3","title":"\u5feb\u901f\u8bbf\u95ee","text":"
    1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
    2. \u70b9\u51fb\u7ec8\u7aef\u56fe\u6807\u8fdb\u5165\u9ed8\u8ba4\u7684 QPython Shell \u7ec8\u7aef
    "},{"location":"Terminal/#_4","title":"\u9ad8\u7ea7\u9009\u9879\uff08\u957f\u6309\uff09","text":"

    \u5728\u4eea\u8868\u76d8\u4e0a\uff0c\u957f\u6309\u7ec8\u7aef\u56fe\u6807\u4ee5\u8bbf\u95ee\u5176\u4ed6\u9009\u9879\uff1a

    • QPython Shell \u7ec8\u7aef \u2013 \u542f\u52a8\u6807\u51c6 Python shell
    • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u542f\u52a8\u5177\u6709\u9ad8\u7ea7\u529f\u80fd\u7684 IPython\uff0c\u5305\u62ec\u4ee3\u7801\u8865\u5168\u3001\u8bed\u6cd5\u9ad8\u4eae\u548c\u547d\u4ee4\u5386\u53f2
    • PIP \u5ba2\u6237\u7aef \u2013 \u542f\u52a8\u5305\u7ba1\u7406\u754c\u9762
    "},{"location":"Terminal/#qpython-shell","title":"QPython Shell \u7ec8\u7aef","text":"

    QPython Shell \u7ec8\u7aef\u63d0\u4f9b\u4e86\u4e00\u79cd\u5feb\u901f\u6267\u884c Python \u547d\u4ee4\u548c\u63a2\u7d22 Python \u7279\u6027\u7684\u65b9\u5f0f\u3002

    "},{"location":"Terminal/#_5","title":"\u529f\u80fd","text":"
    • \u5373\u65f6\u547d\u4ee4\u6267\u884c
    • \u57fa\u672c Python \u89e3\u91ca\u5668\u529f\u80fd
    • \u8bbf\u95ee Python \u5185\u7f6e\u51fd\u6570\u548c\u6807\u51c6\u5e93
    • \u975e\u5e38\u9002\u5408\u5feb\u901f\u6d4b\u8bd5\u548c\u5b9e\u9a8c
    "},{"location":"Terminal/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    >>> print(\"Hello from QPython!\")\nHello from QPython!\n>>> import math\n>>> math.sqrt(16)\n4.0\n>>> [x**2 for x in range(10)]\n[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n
    "},{"location":"Terminal/#ipython","title":"IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668","text":"

    IPython \u63d0\u4f9b\u4e86\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f Python \u4f53\u9a8c\uff0c\u5177\u6709\u589e\u5f3a\u7684\u529f\u80fd\u3002

    "},{"location":"Terminal/#_7","title":"\u529f\u80fd","text":"
    • \u4ee3\u7801\u8865\u5168 \u2013 \u81ea\u52a8\u8865\u5168\u53d8\u91cf\u540d\u3001\u6a21\u5757\u5c5e\u6027\u548c\u6587\u4ef6\u8def\u5f84
    • \u547d\u4ee4\u5386\u53f2 \u2013 \u4f7f\u7528\u4e0a\u4e0b\u7bad\u5934\u6d4f\u89c8\u4e4b\u524d\u7684\u547d\u4ee4
    • \u8bed\u6cd5\u9ad8\u4eae \u2013 \u5f69\u8272\u8f93\u51fa\u4ee5\u63d0\u9ad8\u53ef\u8bfb\u6027
    • \u9b54\u672f\u547d\u4ee4 \u2013 \u4ee5 % \u4e3a\u524d\u7f00\u7684\u7279\u6b8a\u547d\u4ee4\uff0c\u7528\u4e8e\u5e38\u89c1\u4efb\u52a1
    • \u5bf9\u8c61\u5185\u7701 \u2013 \u8f7b\u677e\u63a2\u7d22\u5bf9\u8c61\u53ca\u5176\u5c5e\u6027
    "},{"location":"Terminal/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    In [1]: import numpy as np\n\nIn [2]: arr = np.array([1, 2, 3, 4, 5])\n\nIn [3]: arr?\nType:            ndarray\nString form:     [1 2 3 4 5]\nLength:          5\n...\n\nIn [4]: %timeit arr ** 2\nThe slowest run took 12.34 microseconds...\n
    "},{"location":"Terminal/#pip","title":"PIP \u5ba2\u6237\u7aef","text":"

    PIP \u5ba2\u6237\u7aef\u63d0\u4f9b Python \u5305\u7ba1\u7406\u7684\u547d\u4ee4\u884c\u8bbf\u95ee\u3002

    "},{"location":"Terminal/#_9","title":"\u529f\u80fd","text":"
    • \u4ece PyPI \u5b89\u88c5\u5305
    • \u67e5\u770b\u5df2\u5b89\u88c5\u7684\u5305
    • \u5347\u7ea7\u5305
    • \u5378\u8f7d\u5305
    • \u641c\u7d22\u5305
    "},{"location":"Terminal/#_10","title":"\u5e38\u7528\u547d\u4ee4","text":"
    # \u5b89\u88c5\u5305\npip install requests\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u5305\npip list\n\n# \u5347\u7ea7\u5305\npip install --upgrade requests\n\n# \u5378\u8f7d\u5305\npip uninstall requests\n\n# \u641c\u7d22\u5305\npip search json\n
    "},{"location":"Terminal/#_11","title":"\u4f7f\u7528\u6280\u5de7","text":"
    • \u957f\u6309\u4ece\u4eea\u8868\u76d8\u8bbf\u95ee PIP \u5ba2\u6237\u7aef
    • \u4f7f\u7528 pip help \u67e5\u770b\u6240\u6709\u53ef\u7528\u547d\u4ee4
    • \u67d0\u4e9b\u547d\u4ee4\u53ef\u80fd\u9700\u8981\u7ba1\u7406\u5458\u6743\u9650
    "},{"location":"Terminal/#_12","title":"\u9009\u62e9\u5408\u9002\u7684\u5de5\u5177","text":"\u5de5\u5177 \u6700\u4f73\u7528\u9014 Shell \u7ec8\u7aef \u5feb\u901f\u8ba1\u7b97\u3001\u7b80\u5355\u811a\u672c\u3001\u6d4b\u8bd5\u4ee3\u7801\u7247\u6bb5 IPython \u590d\u6742\u63a2\u7d22\u3001\u6570\u636e\u5206\u6790\u3001\u4ea4\u4e92\u5f0f\u8c03\u8bd5 PIP \u5ba2\u6237\u7aef \u5b89\u88c5/\u66f4\u65b0\u5305\u3001\u68c0\u67e5\u4f9d\u8d56"},{"location":"Terminal/#_13","title":"\u4e86\u89e3\u66f4\u591a","text":"
    • Python \u6587\u6863 \u2013 \u5b98\u65b9 Python \u8bed\u8a00\u548c\u5e93\u53c2\u8003
    • IPython \u6587\u6863 \u2013 \u9ad8\u7ea7\u4ea4\u4e92\u5f0f Python \u529f\u80fd
    • PyPI \u6307\u5357 \u2013 \u5728 QPython \u4e2d\u7ba1\u7406 Python \u5305
    "},{"location":"editor-guide/","title":"\u4f7f\u7528\u6700\u4f73\u5f00\u53d1\u65b9\u5f0f","text":""},{"location":"editor-guide/#qeditor","title":"\u4ece QEditor \u5f00\u53d1","text":"

    QEditor \u662f QPython \u7684\u5185\u7f6e\u7f16\u8f91\u5668\uff0c\u652f\u6301 Python / HTML \u8bed\u6cd5\u9ad8\u4eae\u3002

    QEditor \u7684\u4e3b\u8981\u529f\u80fd

    • \u7f16\u8f91/\u67e5\u770b\u7eaf\u6587\u672c\u6587\u4ef6\uff0c\u5982 Python\u3001Lua\u3001HTML\u3001Javascript \u7b49

    • \u7f16\u8f91\u548c\u8fd0\u884c Python \u811a\u672c & Python \u8bed\u6cd5\u9ad8\u4eae

    • \u7f16\u8f91\u548c\u8fd0\u884c Shell \u811a\u672c

    • \u4f7f\u7528\u5185\u7f6e HTML \u6d4f\u89c8\u5668\u9884\u89c8 HTML

    • \u6309\u5173\u952e\u5b57\u641c\u7d22\u3001\u4ee3\u7801\u7247\u6bb5\u3001\u4ee3\u7801\u5206\u4eab

    \u60a8\u53ef\u4ee5\u76f4\u63a5\u5728 QEditor \u4e2d\u8fd0\u884c QPython \u811a\u672c\uff0c\u56e0\u6b64\u5728\u79fb\u52a8\u65f6\u8fd9\u662f QPython \u5f00\u53d1\u6700\u65b9\u4fbf\u7684\u65b9\u5f0f\u3002

    "},{"location":"editor-guide/#_2","title":"\u901a\u8fc7\u6d4f\u89c8\u5668\u5f00\u53d1","text":"

    QPython \u6709\u4e00\u4e2a\u5185\u7f6e\u811a\u672c qedit4web.py\uff0c\u5f53\u60a8\u70b9\u51fb\u5f00\u59cb\u6309\u94ae\u5e76\u9009\u62e9\"\u8fd0\u884c\u672c\u5730\u811a\u672c\"\u65f6\u53ef\u4ee5\u770b\u5230\u5b83\u3002

    \u8fd0\u884c\u540e\uff0c\u60a8\u53ef\u4ee5\u770b\u5230\u7ed3\u679c\u3002

    \u7136\u540e\uff0c\u60a8\u53ef\u4ee5\u901a\u8fc7 PC/\u7b14\u8bb0\u672c\u7535\u8111\u7684\u6d4f\u89c8\u5668\u8bbf\u95ee\u8be5\u7f51\u5740\u8fdb\u884c\u5f00\u53d1\uff0c\u5982\u4e0b\u56fe\u6240\u793a\u3002

    \u9009\u62e9\u67d0\u4e2a\u9879\u76ee\u6216\u811a\u672c\u540e\uff0c\u60a8\u53ef\u4ee5\u5f00\u59cb\u5f00\u53d1

    \u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\u7f16\u5199\u6d4f\u89c8\u5668\u4ee3\u7801\uff0c\u7136\u540e\u5728 Android \u624b\u673a\u4e0a\u8fd0\u884c\u3002\u975e\u5e38\u65b9\u4fbf\u3002

    "},{"location":"editor-guide/#_3","title":"\u4ece\u60a8\u7684\u7535\u8111\u5f00\u53d1","text":"

    \u9664\u4e86\u4e0a\u8ff0\u65b9\u6cd5\uff0c\u60a8\u8fd8\u53ef\u4ee5\u7528\u81ea\u5df1\u7684\u65b9\u5f0f\u5f00\u53d1\u811a\u672c\uff0c\u7136\u540e\u901a\u8fc7\u5185\u7f6e\u7684 FTP \u670d\u52a1\u5c06\u5176\u4e0a\u4f20\u5230\u624b\u673a\uff0c\u7528 QPython \u8fd0\u884c\u5b83\u3002

    "},{"location":"external-api/","title":"QPython \u5f00\u653e API","text":"

    QPython \u6709\u4e00\u4e2a\u5f00\u653e\u7684 activity\uff0c\u5141\u8bb8\u60a8\u4ece\u5916\u90e8\u8fd0\u884c qpython\u3002

    MPyAPI \u7684\u5b9a\u4e49\u5982\u4e0b\uff1a

        <activity\n        android:name=\"org.qpython.qpylib.MPyApi\"\n        android:label=\"@string/qpy_run_with_share\"\n        android:screenOrientation=\"user\"\n        android:configChanges=\"orientation|keyboardHidden\"\n        android:exported=\"true\">\n        <intent-filter>\n            <action android:name=\"org.qpython.qpylib.action.MPyApi\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.LAUNCHER\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.VIEW\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.BROWSABLE\" />\n            <data android:scheme=\"http\" />\n            <data android:scheme=\"https\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"text/plain\"/>\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"image/*\"/>\n        </intent-filter>\n    </activity>\n

    \u56e0\u6b64\uff0c\u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\uff1a

    "},{"location":"external-api/#qpython","title":"\u5c06\u5185\u5bb9\u5206\u4eab\u5230 QPython \u7684\u811a\u672c","text":"

    \u60a8\u53ef\u4ee5\u5728\u67d0\u4e2a\u5e94\u7528\u4e2d\u9009\u62e9\u4e00\u4e9b\u5185\u5bb9\uff0c\u7136\u540e\u5206\u4eab\u5230 qpython \u7684\u811a\u672c\uff0c\u4e4b\u540e\u60a8\u53ef\u4ee5\u4f7f\u7528 sys.argv[2] \u5904\u7406\u8fd9\u4e9b\u5185\u5bb9

    \u5728 YouTube \u4e0a\u89c2\u770b\u6f14\u793a\u89c6\u9891

    "},{"location":"external-api/#qpython_1","title":"\u4ece\u60a8\u81ea\u5df1\u7684\u5e94\u7528\u7a0b\u5e8f\u8fd0\u884c QPython \u7684\u811a\u672c","text":"

    \u60a8\u53ef\u4ee5\u901a\u8fc7\u8c03\u7528\u6b64 activity \u5728\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u4e2d\u8c03\u7528 QPython \u6765\u8fd0\u884c\u67d0\u4e9b\u811a\u672c\u6216 Python \u4ee3\u7801\uff0c\u793a\u4f8b\u5982\u4e0b\uff1a

    // \u5c55\u793a\u5982\u4f55\u8c03\u7528 qpython API \u7684\u4ee3\u7801\u793a\u4f8b\nString extPlgPlusName = \"org.qpython.qpy\";          // QPython \u5305\u540d\nIntent intent = new Intent();\nintent.setClassName(extPlgPlusName, \"org.qpython.qpylib.MPyApi\");\nintent.setAction(extPlgPlusName + \".action.MPyApi\");\n\nBundle mBundle = new Bundle();\nmBundle.putString(\"app\", \"myappid\");\nmBundle.putString(\"act\", \"onPyApi\");\nmBundle.putString(\"flag\", \"onQPyExec\"); // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u4efb\u610f\u5b57\u7b26\u4e32\u6807\u5fd7\nmBundle.putString(\"param\", \"\");         // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u53c2\u6570\u5b57\u7b26\u4e32\n\n/*\n* \u6211\u4eec\u5c06\u8fd0\u884c\u7684 Python \u4ee3\u7801\n*/\nString code = \"import androidhelper\\n\" +\n            \"droid = androidhelper.Android()\\n\" +\n            \"line = droid.dialogGetInput()\\n\" +\n            \"s = 'Hello %s' % line.result\\n\" +\n            \"droid.makeToast(s)\\n\"\n\nmBundle.putString(\"pycode\", code);\nintent.putExtras(mBundle);\nstartActivityForResult(intent, SCRIPT_EXEC_PY);\n...\n\n// \u60a8\u53ef\u4ee5\u5728 onActivityResult \u4e2d\u5904\u7406 qpython \u8c03\u7528\u7ed3\u679c\n@Override\nprotected void onActivityResult(int requestCode, int resultCode, Intent data) {\n    if (requestCode == SCRIPT_EXEC_PY) {\n        if (data!=null) {\n            Bundle bundle = data.getExtras();\n            String flag = bundle.getString(\"flag\");\n            String param = bundle.getString(\"param\");\n            String result = bundle.getString(\"result\"); // \u60a8\u7684 Pycode \u751f\u6210\u7684\u7ed3\u679c\n            Toast.makeText(this, \"onQPyExec: return (\"+result+\")\", Toast.LENGTH_SHORT).show();\n        } else {\n            Toast.makeText(this, \"onQPyExec: data is null\", Toast.LENGTH_SHORT).show();\n\n        }\n    }\n}\n

    \u4ece github \u68c0\u51fa\u4e00\u4e2a\u5b8c\u6574\u9879\u76ee

    \u8fd8\u6709\u4e00\u4e2a\u751f\u4ea7\u5e94\u7528\u7a0b\u5e8f - \u9762\u5411 Tasker \u7684 QPython \u63d2\u4ef6

    "},{"location":"getting-started/","title":"QPython\uff1a\u5165\u95e8\u6307\u5357","text":"

    \u672c\u6307\u5357\u5c06\u4ecb\u7ecd QPython \u7684\u529f\u80fd\u5e76\u5e2e\u52a9\u60a8\u5feb\u901f\u5165\u95e8\u3002

    "},{"location":"getting-started/#qpython_1","title":"QPython \u6982\u8ff0","text":"

    \u4e3a\u4ec0\u4e48\u9009\u62e9 QPython\uff1f

    \u667a\u80fd\u624b\u673a\u5df2\u6210\u4e3a\u4eba\u4eec\u5fc5\u5907\u7684\u4fe1\u606f\u548c\u6280\u672f\u52a9\u624b\uff0c\u4e00\u4e2a\u7075\u6d3b\u7684\u89e3\u91ca\u5668\u5f15\u64ce\u53ef\u4ee5\u5e2e\u52a9\u60a8\u9ad8\u6548\u5b8c\u6210\u5927\u90e8\u5206\u5de5\u4f5c\uff0c\u65e0\u9700\u590d\u6742\u7684\u5f00\u53d1\u8fc7\u7a0b\u3002

    QPython \u63d0\u4f9b\u4e86 \u60ca\u4eba\u7684\u5f00\u53d1\u4f53\u9a8c\u2014\u2014\u501f\u52a9\u5b83\u7684\u5e2e\u52a9\uff0c\u60a8\u53ef\u4ee5\u8f7b\u677e\u5b9e\u73b0\u7a0b\u5e8f\uff0c\u65e0\u9700\u590d\u6742\u7684 IDE \u5b89\u88c5\u3001\u7f16\u8bd1\u6216\u6253\u5305\u8fc7\u7a0b\u3002

    "},{"location":"getting-started/#qpython_2","title":"QPython \u7248\u672c","text":"

    \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

    • QPython \u2013 \u7531 QPython \u56e2\u961f\u7ef4\u62a4\u7684\u4e3b\u8981\u7248\u672c\uff0c\u5177\u5907 AI \u529f\u80fd\uff0c\u53ef\u5728 Google Play \u7b49\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d
    • QPython+ \u2013 \u7531\u5f00\u6e90\u8d21\u732e\u8005\u63a8\u51fa\u7684\u793e\u533a\u7248\uff0c\u63d0\u4f9b\u5404\u79cd\u65b0\u7279\u6027
    • QPython Plus \u2013 \u6269\u5c55\u6743\u9650\u7248\u672c\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff09
    "},{"location":"getting-started/#_1","title":"\u4e3b\u8981\u7279\u6027","text":"
    • \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668 - \u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51
    • QSL4A \u96c6\u6210 - \u4f7f\u7528 Python \u63a7\u5236 Android \u786c\u4ef6\u548c API
    • GenAI \u80fd\u529b\u96c6\u6210 - \u652f\u6301\u672c\u5730\u8fd0\u884c\u7684 LLM\u3001OpenAI \u7b49\u5404\u79cd LLM \u5e93\uff0c\u4ee5\u53ca\u53ef\u5728 QPython \u4e0a\u8fdb\u884c Vibe Coding \u5f00\u53d1\u7684 AIPyApp
    • \u6269\u5c55\u5305\u5b89\u88c5 - \u652f\u6301\u901a\u8fc7 QPYPI \u548c pip \u5b89\u88c5\u6269\u5c55\u5305
    • \u5185\u7f6e\u7f16\u8f91\u5668 - \u8bed\u6cd5\u9ad8\u4eae\u548c\u4ee3\u7801\u7f16\u8f91
    • \u591a\u79cd\u8fd0\u884c\u6a21\u5f0f - \u9664\u63a7\u5236\u53f0\u7a0b\u5e8f\u5916\uff0c\u8fd8\u652f\u6301 Android \u539f\u751f UI\uff08\u901a\u8fc7 QSL4A \u63a5\u53e3\uff09\u4ee5\u53ca Pygame / Turtle / Tkinter \u7b49\u8fd0\u884c\u65b9\u5f0f
    "},{"location":"getting-started/#1","title":"1. \u4eea\u8868\u76d8","text":"

    \u5b89\u88c5 QPython \u540e\uff0c\u70b9\u51fb\u5176\u56fe\u6807\u542f\u52a8\u3002\u60a8\u5c06\u770b\u5230\u5e26\u6709 QPython \u6807\u5fd7\u548c\u4ee5\u4e0b\u529f\u80fd\u7684\u4e3b\u4eea\u8868\u76d8\uff1a

    "},{"location":"getting-started/#_2","title":"\u4eea\u8868\u76d8\u529f\u80fd","text":"

    QPython \u4eea\u8868\u76d8\u63d0\u4f9b\u5bf9\u6240\u6709\u4e3b\u8981\u529f\u80fd\u7684\u5feb\u901f\u8bbf\u95ee\uff1a

    • \u7ec8\u7aef \u2014 \u8bbf\u95ee Python \u63a7\u5236\u53f0\u548c shell \u4ee5\u76f4\u63a5\u6267\u884c\u547d\u4ee4
    • Notebook \u2014 \u7528\u4e8e\u6570\u636e\u5206\u6790\u548c\u5b9e\u9a8c\u7684\u4ea4\u4e92\u5f0f Jupyter \u98ce\u683c\u7b14\u8bb0\u672c
    • \u7f16\u8f91\u5668 \u2014 \u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668\uff0c\u5177\u6709\u8bed\u6cd5\u9ad8\u4eae\u529f\u80fd\uff0c\u7528\u4e8e\u7f16\u5199 Python \u811a\u672c
    • \u8d44\u6e90\u7ba1\u7406\u5668 \u2014 \u6d4f\u89c8\u548c\u7ba1\u7406\u60a8\u7684\u6587\u4ef6\u3001\u811a\u672c\u548c\u9879\u76ee
    • QPYPI \u2014 \u5b89\u88c5 Python \u5305\u548c\u6269\u5c55\u3002\u8be6\u89c1 QPYPI \u6307\u5357
    • \u8bbe\u7f6e \u2014 \u914d\u7f6e QPython \u9996\u9009\u9879\u548c\u8fd0\u884c\u9009\u9879
    • \u793e\u533a \u2014 \u8bbf\u95ee QPython \u793e\u533a\u8d44\u6e90\u3001\u8bba\u575b\u548c\u5e2e\u52a9
    • \u8bfe\u7a0b \u2014 \u8bbf\u95ee Python \u7f16\u7a0b\u7684\u5b66\u4e60\u6750\u6599\u548c\u6559\u7a0b

    \u70b9\u51fb\u4efb\u4f55\u56fe\u6807\u4ee5\u8bbf\u95ee\u76f8\u5e94\u7684\u529f\u80fd\u3002

    "},{"location":"getting-started/#2","title":"2. \u7ec8\u7aef\u548c\u7f16\u8f91\u5668","text":""},{"location":"getting-started/#_3","title":"\u7ec8\u7aef","text":"

    \u7ec8\u7aef\u63d0\u4f9b Python \u63a7\u5236\u53f0\uff0c\u652f\u6301\uff1a - \u63a2\u7d22\u5bf9\u8c61\u5c5e\u6027 - \u6d4b\u8bd5\u8bed\u6cd5\u548c\u60f3\u6cd5 - \u76f4\u63a5\u6267\u884c\u547d\u4ee4

    \u4f7f\u7528\u52a0\u53f7\u6309\u94ae\uff081\uff09\u6253\u5f00\u65b0\u7ec8\u7aef\u6807\u7b7e\u9875\uff0c\u901a\u8fc7\u4e0b\u62c9\u83dc\u5355\uff082\uff09\u5207\u6362\uff0c\u5e76\u4f7f\u7528\u5173\u95ed\u6309\u94ae\uff083\uff09\u5173\u95ed\u3002

    "},{"location":"getting-started/#_4","title":"\u7f16\u8f91\u5668","text":"

    \u7f16\u8f91\u5668\u5e95\u90e8\u529f\u80fd\u680f\u5305\u542b\u4ee5\u4e0b\u5de5\u5177\uff08\u4ece\u5de6\u5230\u53f3\uff09\uff1a

    • \u5207\u6362\u5feb\u6377\u8f93\u5165\uff08\u5305\u542b def / if / else / elif / class \u7b49\u5173\u952e\u8bcd\uff09
    • \u9501\u5b9a\uff08\u9632\u6b62\u8bef\u89e6\uff09
    • \u8df3\u8f6c
    • \u4fdd\u5b58
    • \u8fd0\u884c
    • \u641c\u7d22
    • \u64a4\u9500
    • \u91cd\u505a
    • \u53e6\u5b58
    • \u6700\u8fd1\u6587\u4ef6
    • \u4ee3\u7801\u7247\u6bb5

    \u91cd\u8981\u63d0\u793a\uff1a \u4fdd\u5b58\u65f6\u8bf7\u624b\u52a8\u6dfb\u52a0 .py \u6269\u5c55\u540d\uff0c\u56e0\u4e3a\u7f16\u8f91\u5668\u4e0d\u4f1a\u81ea\u52a8\u6dfb\u52a0\u3002

    "},{"location":"getting-started/#3","title":"3. \u8d44\u6e90\u7ba1\u7406\u5668\uff08\u6587\u4ef6\u7ba1\u7406\uff09","text":"

    \u901a\u8fc7 \u8d44\u6e90\u7ba1\u7406\u5668 \u8bbf\u95ee\u811a\u672c\u548c\u9879\u76ee\uff0c\u652f\u6301\u6d4f\u89c8\u3001\u7ec4\u7ec7\u548c\u7ba1\u7406\u6240\u6709 Python \u6587\u4ef6\u3002

    "},{"location":"getting-started/#_5","title":"\u811a\u672c","text":"

    \u811a\u672c\u662f\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/scripts3/ \u4e2d\u7684\u5355\u4e2a Python \u6587\u4ef6\uff08\u9488\u5bf9 Python 3\uff09\u3002

    \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u811a\u672c - \u6253\u5f00 \u2014 \u4f7f\u7528\u5185\u7f6e\u7f16\u8f91\u5668\u7f16\u8f91 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u811a\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u811a\u672c

    "},{"location":"getting-started/#_6","title":"\u9879\u76ee","text":"

    \u9879\u76ee\u662f\u5305\u542b main.py \u4f5c\u4e3a\u5165\u53e3\u70b9\u7684\u76ee\u5f55\u3002\u60a8\u53ef\u4ee5\u5728\u540c\u4e00\u76ee\u5f55\u4e2d\u5305\u542b\u5176\u4ed6\u4f9d\u8d56\u9879\u548c\u8d44\u6e90\u3002\u5c06\u9879\u76ee\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/projects3/ \u4e2d\u3002

    "},{"location":"getting-started/#_7","title":"\u7b14\u8bb0\u672c","text":"

    Jupyter \u98ce\u683c\u7684\u7b14\u8bb0\u672c\u4e5f\u901a\u8fc7\u8d44\u6e90\u7ba1\u7406\u5668\u8fdb\u884c\u7ba1\u7406\uff0c\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/notebooks/ \u4e2d\u3002

    \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u7b14\u8bb0\u672c - \u6253\u5f00 \u2014 \u63a2\u7d22\u7b14\u8bb0\u672c\u5185\u5bb9 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u7b14\u8bb0\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u7b14\u8bb0\u672c

    "},{"location":"getting-started/#4","title":"4. \u5e93","text":"

    \u901a\u8fc7\u5b89\u88c5\u7b2c\u4e09\u65b9\u5e93\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

    "},{"location":"getting-started/#_8","title":"\u5305\u5b89\u88c5\u65b9\u6cd5","text":"

    QPYPI\uff08\u63a8\u8350\uff09

    \u4ece QPYPI \u5b89\u88c5\u9884\u7f16\u8bd1\u7684\u5e93\uff0c\u5305\u62ec numpy\u3001scipy \u7b49\u79d1\u5b66\u5305\u3002

    \u8be6\u89c1 QPYPI \u6307\u5357\u3002

    PIP \u5ba2\u6237\u7aef

    \u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216 QPYPI \u754c\u9762\u5b89\u88c5\u7eaf Python \u5e93\uff1a

    pip install requests\n

    \u9884\u7f16\u8bd1\u5305

    \u5bf9\u4e8e\u5177\u6709 C/C++/Rust \u4f9d\u8d56\u7684\u5305\uff0c\u4f7f\u7528 QPython \u7684\u9884\u7f16\u8bd1\u5305\uff1a

    pip install numpy-qpython\npip install scipy-aipy\n

    \u8be6\u89c1 QPYPI \u6307\u5357 \u83b7\u53d6\u53ef\u7528\u5305\u7684\u5b8c\u6574\u5217\u8868\u3002

    \u624b\u52a8\u5b89\u88c5

    \u60a8\u4e5f\u53ef\u4ee5\u5c06\u5e93\u590d\u5236\u5230 /storage/emulated/0/Android/data/org.qpython.qpy/files/lib/python3.12/site-packages/\u3002

    "},{"location":"getting-started/#5","title":"5. \u8fd0\u884c\u6a21\u5f0f","text":"

    QPython \u652f\u6301\u591a\u79cd\u8fd0\u884c\u6a21\u5f0f\u4ee5\u6ee1\u8db3\u4e0d\u540c\u7684\u7528\u4f8b\uff1a

    "},{"location":"getting-started/#_9","title":"\u63a7\u5236\u53f0\u6a21\u5f0f","text":"

    \u5e38\u89c4 Python \u811a\u672c\u7684\u9ed8\u8ba4\u6a21\u5f0f\u3002

    "},{"location":"getting-started/#qsl4a","title":"QSL4A \u6a21\u5f0f","text":"

    \u901a\u8fc7 QSL4A \u5e93\u8c03\u7528 Android API \u7684\u811a\u672c\u3002

    import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello Android!')\n

    \u8be6\u89c1 QSL4A \u6587\u6863 \u83b7\u53d6\u5b8c\u6574\u7684 API \u53c2\u8003\u3002

    "},{"location":"getting-started/#webapp","title":"WebApp \u6a21\u5f0f","text":"

    \u4f7f\u7528\u540e\u7aef\u670d\u52a1\u5668\u521b\u5efa\u57fa\u4e8e Web \u7684\u5e94\u7528\u7a0b\u5e8f\u3002\u9700\u5728\u811a\u672c\u5f00\u5934\u6dfb\u52a0\u4ee5\u4e0b\u4e24\u884c headers\uff1a

    #qpy:webapp:<\u9879\u76ee\u540d>\n#qpy://localhost:<web\u670d\u52a1\u4fa6\u542c\u7684\u7aef\u53e3>/<\u9ed8\u8ba4\u4e3b\u8def\u5f84>\n

    \u4f8b\u5982\uff1a

    #qpy:webapp:Hello QPython\n#qpy://localhost:8080/hello\n\nfrom bottle import route, run, Bottle\n\napp = Bottle()\n\n@route('/hello')\ndef hello():\n    return '<h1>Hello from QPython!</h1>'\n\nrun(app, host='localhost', port=8080)\n
    "},{"location":"getting-started/#q","title":"Q \u6a21\u5f0f\uff08\u65e0\u63a7\u5236\u53f0\u6a21\u5f0f\uff09","text":"

    \u9759\u9ed8\u6a21\u5f0f\u8fd0\u884c\u811a\u672c\uff0c\u4e0d\u663e\u793a\u63a7\u5236\u53f0\u3002\u9700\u5728\u811a\u672c\u5f00\u5934\u6dfb\u52a0 header\uff1a

    #qpy:quiet\n\nimport time\n\nwhile True:\n    # \u60a8\u7684\u540e\u53f0\u4efb\u52a1\n    time.sleep(60)\n
    \u5982\u679c\u9700\u8981\u8fd0\u884c\u5e26 GUI \u7684 QSL4A \u7a0b\u5e8f\u4e14\u4e0d\u5e0c\u671b\u663e\u793a\u63a7\u5236\u53f0\u4fe1\u606f\uff0c\u63a8\u8350\u4f7f\u7528\u6b64\u6a21\u5f0f\u3002

    "},{"location":"getting-started/#6","title":"6. \u793e\u533a\u4e0e\u652f\u6301","text":"

    \u8bbf\u95ee QPython.org \u83b7\u53d6\u6587\u6863\u3001\u7528\u6237\u793e\u533a\u53ca\u5e2e\u52a9\u95ee\u7b54\u3002

    \u793e\u533a\u94fe\u63a5\uff1a - Facebook \u7fa4\u7ec4 - GitHub - \u95ee\u9898\u53cd\u9988

    \u4e0b\u4e00\u6b65\uff1a - \u5c1d\u8bd5 Hello World \u6559\u7a0b - \u63a2\u7d22 QSL4A API \u4ee5\u96c6\u6210 Android - \u4e86\u89e3 QPython \u7248\u672c

    "},{"location":"getting-started/#_10","title":"\u89c6\u9891\u4ecb\u7ecd","text":""},{"location":"getting-started/#_11","title":"\u4e0b\u4e00\u6b65","text":"

    \u5982\u679c\u60a8\u5df2\u7ecf\u521d\u6b65\u4e86\u89e3\u4e86 QPython \u7684\u529f\u80fd\uff0c\u6b22\u8fce\u5f00\u59cb\u4f53\u9a8c\u7f16\u7a0b\u7684\u4e50\u8da3\uff01\u8bd5\u8bd5 Hello World \u6559\u7a0b \u8fc8\u51fa\u60a8\u7684\u7b2c\u4e00\u6b65\u3002

    "},{"location":"qpypi-guide/","title":"QPYPI","text":"

    \u60a8\u53ef\u4ee5\u901a\u8fc7\u5b89\u88c5\u5305\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

    "},{"location":"qpypi-guide/#_1","title":"\u5305\u5b89\u88c5\u652f\u6301","text":""},{"location":"qpypi-guide/#python","title":"\u7eaf Python \u5305","text":"

    QPython \u652f\u6301\u4f7f\u7528\u7eaf Python \u5f00\u53d1\u7684 Python \u5305\u3002\u60a8\u53ef\u4ee5\u76f4\u63a5\u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216\u4eea\u8868\u76d8\u4e0a\u7684 QPYPI \u4f7f\u7528 pip install \u5b89\u88c5\u8fd9\u4e9b\u5305\u3002

    "},{"location":"qpypi-guide/#_2","title":"\u9884\u7f16\u8bd1\u5305","text":"

    \u5982\u679c\u67d0\u4e9b\u5305\uff08\u6216\u5b83\u4eec\u7684\u4f9d\u8d56\uff09\u662f\u7528 Rust/C/C++ \u5f00\u53d1\u7684\uff0cQPython \u65e0\u6cd5\u76f4\u63a5\u652f\u6301\u5b83\u4eec\uff0c\u56e0\u4e3a QPython \u4e0a\u6ca1\u6709\u7f16\u8bd1\u5668\u5de5\u5177\u94fe\u652f\u6301\u3002\u4f46\u662f\uff0cQPython \u56e2\u961f\u5df2\u7ecf\u9884\u7f16\u8bd1\u4e86\u4e00\u4e9b\u5e38\u7528\u5305\uff0c\u5e76\u5728 QPython \u7684 QPYPI/Extensions \u4e2d\u53d1\u5e03\uff0c\u4f9b\u7528\u6237\u8f7b\u677e\u5b89\u88c5\u3002

    "},{"location":"qpypi-guide/#_3","title":"\u5b89\u88c5\u9884\u7f16\u8bd1\u5305","text":"

    \u60a8\u53ef\u4ee5\u901a\u8fc7\u4ee5\u4e0b\u65b9\u5f0f\u5b89\u88c5\u9884\u7f16\u8bd1\u5305\uff1a

    1. \u901a\u8fc7 QPython \u5e94\u7528\uff1a\u76f4\u63a5\u4ece QPython \u5e94\u7528\u5185\u7684 QPYPI \u6216 Extensions \u5b89\u88c5
    2. \u901a\u8fc7 PyPI\uff1a\u8bbf\u95ee https://pypi.org/user/qpythonx/ \u67e5\u770b\u53ef\u7528\u7684\u5305
    3. \u901a\u8fc7 pip \u547d\u4ee4\uff1a
    4. pip install xxx-qpython - \u5e26 -qpython \u540e\u7f00\u7684\u5305
    5. pip install xxx-aipy - \u5e26 -aipy \u540e\u7f00\u7684\u5305\uff08\u901a\u5e38\u662f AI/ML \u76f8\u5173\u7684\u5305\uff09

    \u6ce8\u610f\uff1a\u6211\u4eec\u901a\u5e38\u6839\u636e\u5305\u7684\u9884\u671f\u7528\u9014\u6dfb\u52a0\u8fd9\u4e9b\u540e\u7f00\u4e4b\u4e00\u3002

    "},{"location":"qpypi-guide/#_4","title":"\u8bf7\u6c42\u65b0\u5305","text":"

    \u5982\u679c\u60a8\u9700\u8981\u5f53\u524d\u4e0d\u652f\u6301\u7684\u5305\uff1a

    • \u5728 qpython.org \u9879\u76ee \u4e2d\u63d0\u51fa\u95ee\u9898
    • QPython \u56e2\u961f\u5c06\u8003\u8651\u9884\u7f16\u8bd1\u5e76\u5c06\u5176\u6dfb\u52a0\u5230\u4ed3\u5e93\u4e2d

    \u83b7\u53d6\u66f4\u591a\u5e2e\u52a9\u548c\u53c2\u4e0e\u793e\u533a\u7684\u65b9\u5f0f\uff0c\u8bf7\u53c2\u9605 \u793e\u533a\u4e0e\u53cd\u9988 \u90e8\u5206\u3002

    \u6ce8\u610f\uff1a\u7531\u4e8e\u4e0d\u540c\u7684\u8ba1\u7b97\u673a\u67b6\u6784\uff0c\u6211\u4eec\u65e0\u6cd5\u4fdd\u8bc1 QPYPI \u5305\u542b PyPI \u4e0a\u7684\u6240\u6709\u5305\u3002

    "},{"location":"qpython-x/","title":"QPython \u7248\u672c","text":"

    QPython \u662f Android \u7684 Python \u5f15\u64ce\u3002\u5b83\u5305\u542b\u4ee4\u4eba\u60ca\u53f9\u7684\u529f\u80fd\uff0c\u5982 Python \u89e3\u91ca\u5668\u3001\u8fd0\u884c\u73af\u5883\u3001\u7f16\u8f91\u5668\u3001QPYI \u548c\u96c6\u6210\u7684 SL4A\u3002\u5b83\u8ba9\u60a8\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 Android \u4e0a\u4f7f\u7528 Python\u3002\u800c\u4e14\u5b83\u662f\u514d\u8d39\u7684\u3002

    QPython \u5df2\u7ecf\u5728\u5168\u7403\u62e5\u6709\u6570\u767e\u4e07\u7528\u6237\uff0c\u4e5f\u662f\u4e00\u4e2a\u5f00\u6e90\u9879\u76ee\u3002

    \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

    "},{"location":"qpython-x/#qpython_1","title":"QPython","text":"

    \u6807\u51c6\u7248\uff1a\u9488\u5bf9 AI \u6027\u80fd\u548c\u901a\u7528\u5e94\u7528\u5546\u5e97\u517c\u5bb9\u6027\u4f18\u5316

    \u4e3b\u8981\u7248\u672c\uff0c\u53ef\u5728 Google Play \u548c\u5176\u4ed6\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002\u6b64\u7248\u672c\u4e13\u6ce8\u4e8e AI \u529f\u80fd\uff0c\u4f7f AI \u65f6\u4ee3\u7528\u6237\u66f4\u5bb9\u6613\u5b66\u4e60\u548c\u4f7f\u7528 Python\u3002

    \u4e3b\u8981\u7279\u6027\uff1a - AI \u9a71\u52a8\u7684\u7f16\u7801\u8f85\u52a9\u548c\u5b66\u4e60\u5de5\u5177 - \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668\uff1a\u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51 - \u652f\u6301\u591a\u79cd\u9879\u76ee\u7c7b\u578b\uff1a\u63a7\u5236\u53f0\u3001SL4A\u3001WebApp - \u65b9\u4fbf\u7684\u4e8c\u7ef4\u7801\u8bfb\u53d6\u5668\uff0c\u7528\u4e8e\u5c06\u4ee3\u7801\u4f20\u8f93\u5230\u624b\u673a - QPYPI \u548c\u81ea\u5b9a\u4e49\u4ed3\u5e93\uff0c\u7528\u4e8e\u9884\u7f16\u8bd1 wheel \u5305 -\u6613\u4e8e\u4f7f\u7528\u7684\u8bed\u6cd5\u9ad8\u4eae\u7f16\u8f91\u5668 - \u5b8c\u5584\u7684\u6587\u6863\u548c\u793e\u533a\u652f\u6301

    \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

    \u4e0b\u8f7d\uff1a \u53ef\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

    "},{"location":"qpython-x/#qpython_2","title":"QPython+","text":"

    \u793e\u533a\u7248\uff1a\u516c\u5f00\u652f\u6301\u5404\u79cd\u793e\u533a\u9a71\u52a8\u7684\u529f\u80fd\uff1b\u53ef\u5728\u90e8\u5206\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

    \u793e\u533a\u5f00\u6e90\u7248\u672c\uff08\u6b63\u5728\u89c4\u5212\u548c\u51c6\u5907\u4e2d\uff09\u3002\u6b64\u7248\u672c\u4e13\u4e3a\u60f3\u8981\u53c2\u4e0e QPython \u9879\u76ee\u5f00\u53d1\u7684\u8d21\u732e\u8005\u800c\u8bbe\u8ba1\uff0c\u652f\u6301\u9488\u5bf9\u4e0d\u540c\u5236\u9020\u5546\u7684\u5b9a\u5236\u3002

    \u4e3b\u8981\u7279\u6027\uff1a - \u793e\u533a\u9a71\u52a8\u5f00\u53d1 - \u652f\u6301\u4f9b\u5e94\u5546\u5b9a\u5236 - \u66f4\u7075\u6d3b\u7684\u914d\u7f6e\u9009\u9879 - \u5f00\u653e\u4f9b\u8d21\u732e\u8005\u52a0\u5165\u5f00\u53d1

    \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

    \u4e0b\u8f7d\uff1a \u5c06\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

    \u6ce8\u610f\uff1a \u6b64\u7248\u672c\u76ee\u524d\u6b63\u5728\u89c4\u5212\u51c6\u5907\u4e2d\u3002\u8bf7\u5173\u6ce8\u66f4\u65b0\uff01

    "},{"location":"qpython-x/#qpython-plus","title":"QPython Plus","text":"

    QPython+ \u5b8c\u5168\u8bbf\u95ee\u7248\uff1a\u6388\u4e88\u8c03\u7528\u6240\u6709 Android \u63a5\u53e3\u7684\u5b8c\u6574\u6743\u9650\u3002\u4e0b\u8f7d\u94fe\u63a5\u4ec5\u901a\u8fc7\u5b98\u65b9\u4e91\u76d8\u63d0\u4f9b\u3002

    \u5177\u6709\u6269\u5c55\u6743\u9650\u7684\u7279\u6b8a\u7248\u672c\uff0c\u63d0\u4f9b\u5bf9\u8bbe\u5907\u7684\u6700\u5927\u63a7\u5236\u3002\u7531\u4e8e\u5176\u654f\u611f\u7684\u6743\u9650\u8981\u6c42\uff0c\u6b64\u7248\u672c\u4e0d\u4f1a\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u53d1\u5e03\u3002

    \u4e3b\u8981\u7279\u6027\uff1a - \u5b8c\u6574\u7684 SL4A API \u8bbf\u95ee\uff0c\u5305\u62ec\u654f\u611f\u529f\u80fd - SMS/\u901a\u8bdd\u63a7\u5236 API - \u9ad8\u7ea7\u7cfb\u7edf\u96c6\u6210 - \u6700\u5927\u7684\u8bbe\u5907\u63a7\u5236\u80fd\u529b

    \u6743\u9650\uff1a \u9700\u8981\u5e7f\u6cdb\u7684\u6743\u9650\uff0c\u5305\u62ec\uff1a - \u84dd\u7259 - \u4f4d\u7f6e\uff08GPS\uff09 - \u8bfb\u53d6/\u53d1\u9001\u77ed\u4fe1 - \u6253\u7535\u8bdd - \u76f8\u673a\u548c\u9ea6\u514b\u98ce - \u7cfb\u7edf\u8bbe\u7f6e - \u4ee5\u53ca\u5176\u4ed6\u654f\u611f\u6743\u9650

    \u4e0b\u8f7d\uff1a \u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\u3002\u4ec5\u901a\u8fc7\u7279\u6b8a\u6e20\u9053\u5206\u53d1\u3002

    \u91cd\u8981\u63d0\u793a\uff1a QPython \u4e0d\u4f1a\u5728\u540e\u53f0\u672a\u7ecf\u60a8\u77e5\u6089\u4f7f\u7528\u8fd9\u4e9b\u6743\u9650\u3002\u5982\u679c\u4f7f\u7528 SL4A API \u65f6\u51fa\u73b0\u5f02\u5e38\uff0c\u8bf7\u68c0\u67e5\u7cfb\u7edf\u8bbe\u7f6e\u4e2d\u662f\u5426\u5df2\u542f\u7528\u76f8\u5173\u6743\u9650\u3002

    "},{"location":"tutorial-hello-world/","title":"\u7f16\u5199\"Hello World\"","text":""},{"location":"tutorial-hello-world/#hello-world_1","title":"Hello world","text":"

    \u597d\u7684\uff0c\u5728\u60a8\u5bf9 QPython \u6709\u4e86\u4e00\u5b9a\u7684\u4e86\u89e3\u4e4b\u540e\uff0c\u8ba9\u6211\u4eec\u5728 QPython \u4e2d\u521b\u5efa\u6211\u4eec\u7684\u7b2c\u4e00\u4e2a\u7a0b\u5e8f\u3002\u663e\u7136\uff0c\u5b83\u5c06\u662f helloworld.py\u3002;)

    \u542f\u52a8 QPython\uff0c\u6253\u5f00\u7f16\u8f91\u5668\u5e76\u8f93\u5165\u4ee5\u4e0b\u4ee3\u7801\uff1a

    #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello, QPYTHON!')\n

    \u6beb\u65e0\u7591\u95ee\uff0c\u5b83\u4e0e\u5176\u4ed6\u4efb\u4f55 hello-world \u7a0b\u5e8f\u5e76\u65e0\u4e0d\u540c\u3002\u6267\u884c\u65f6\uff0c\u5b83\u53ea\u662f\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u5f39\u51fa\u6d88\u606f\uff08\u89c1\u9876\u90e8\u622a\u56fe\uff09\u3002\u65e0\u8bba\u5982\u4f55\uff0c\u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684 QPython \u7a0b\u5e8f\u793a\u4f8b\u3002

    "},{"location":"tutorial-hello-world/#_1","title":"\u4ee3\u7801\u7406\u89e3","text":"

    \u5b83\u4ee5 import androidhelper \u5f00\u5934\u2014\u2014\u8fd9\u662f QPython \u4e2d\u6700\u6709\u7528\u7684\u6a21\u5757\uff0c\u5b83\u5c01\u88c5\u4e86 Python \u4e2d\u53ef\u7528\u7684\u51e0\u4e4e\u6240\u6709\u4e0e Android \u7684\u63a5\u53e3\u3002\u4efb\u4f55\u5728 QPython \u4e2d\u5f00\u53d1\u7684\u811a\u672c\u90fd\u4ee5\u8fd9\u4e2a\u8bed\u53e5\u5f00\u5934\uff08\u81f3\u5c11\u5982\u679c\u5b83\u58f0\u79f0\u8981\u4e0e\u7528\u6237\u901a\u4fe1\u7684\u8bdd\uff09\u3002\u5728\u6b64\u5904\u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u5e93 \u548c import \u8bed\u53e5 \u7684\u5185\u5bb9\u3002

    \u63a5\u4e0b\u6765\u6211\u4eec\u521b\u5efa\u4e00\u4e2a droid \u5bf9\u8c61\uff08\u5b9e\u9645\u4e0a\u662f\u4e00\u4e2a\u7c7b\uff09\uff0c\u5b83\u5bf9\u4e8e\u8c03\u7528 RPC \u51fd\u6570\u4ee5\u4e0e Android \u901a\u4fe1\u662f\u5fc5\u8981\u7684\u3002

    \u6211\u4eec\u4ee3\u7801\u7684\u6700\u540e\u4e00\u884c\u8c03\u7528\u4e86\u8fd9\u6837\u7684\u51fd\u6570\uff0cdroid.makeToast()\uff0c\u5b83\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u4e00\u4e2a\u5c0f\u7684\u5f39\u51fa\u6d88\u606f\uff08\"toast\"\uff09\u3002

    \u597d\u7684\uff0c\u8ba9\u6211\u4eec\u6dfb\u52a0\u4e00\u4e9b\u66f4\u591a\u7684\u529f\u80fd\u3002\u8ba9\u5b83\u8be2\u95ee\u7528\u6237\u540d\u5e76\u5411\u7528\u6237\u6253\u62db\u547c\u3002

    "},{"location":"tutorial-hello-world/#_2","title":"\u66f4\u591a\u793a\u4f8b","text":"

    \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 dialogGetInput \u8c03\u7528\u663e\u793a\u4e00\u4e2a\u5e26\u6709\u6807\u9898\u3001\u63d0\u793a\u3001\u7f16\u8f91\u5b57\u6bb5\u548c \u786e\u5b9a \u548c \u53d6\u6d88 \u6309\u94ae\u7684\u7b80\u5355\u5bf9\u8bdd\u6846\u3002\u7528\u4ee5\u4e0b\u4ee3\u7801\u66ff\u6362\u60a8\u7684\u6700\u540e\u4e00\u884c\u4ee3\u7801\u5e76\u5c06\u5176\u4fdd\u5b58\u4e3a hello1.py\uff1a

    #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\n

    \u597d\u7684\uff0c\u6211\u8ba4\u4e3a\u5b83\u5e94\u8be5\u8fd4\u56de\u4efb\u4f55\u54cd\u5e94\uff0c\u4efb\u4f55\u7528\u6237\u53cd\u5e94\u3002\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u6211\u5199 respond = ...\u3002\u4f46\u8fd9\u4e2a\u8c03\u7528\u5b9e\u9645\u4e0a\u8fd4\u56de\u4ec0\u4e48\uff1f\u8ba9\u6211\u4eec\u68c0\u67e5\u4e00\u4e0b\u3002\u53ea\u9700\u5728\u6700\u540e\u4e00\u884c\u540e\u6dfb\u52a0 print \u8bed\u53e5\uff1a

    #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\n

    \u7136\u540e\u4fdd\u5b58\u5e76\u8fd0\u884c\u5b83...

    \u54ce\u5440\uff01\u6ca1\u6709\u6253\u5370\uff1f\u522b\u62c5\u5fc3\u3002\u53ea\u9700\u62c9\u4e0b\u901a\u77e5\u680f\uff0c\u60a8\u5c31\u4f1a\u770b\u5230\"QPython Program Output: hello1.py\"\u2014\u2014\u70b9\u51fb\u5b83\uff01

    \u5982\u60a8\u6240\u89c1\uff0cdroid.dialogGetInput() \u8fd4\u56de\u4e00\u4e2a\u5305\u542b\u4e09\u4e2a\u5b57\u6bb5\u7684 JSON \u5bf9\u8c61\u3002\u6211\u4eec\u53ea\u9700\u8981\u4e00\u4e2a\u2014\u2014result\uff0c\u5176\u4e2d\u5305\u542b\u7528\u6237\u5b9e\u9645\u8f93\u5165\u7684\u5185\u5bb9\u3002

    \u8ba9\u6211\u4eec\u6dfb\u52a0\u811a\u672c\u7684\u53cd\u5e94\uff1a

    #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nmessage = f'Hello, {respond.result}!'\ndroid.makeToast(message)\n

    \u6700\u540e\u4e24\u884c\uff081\uff09\u683c\u5f0f\u5316\u6d88\u606f\uff0c\uff082\uff09\u4ee5 toast \u5f62\u5f0f\u5411\u7528\u6237\u663e\u793a\u6d88\u606f\u3002\u5982\u679c\u60a8\u4ecd\u7136\u4e0d\u77e5\u9053 f-string \u662f\u4ec0\u4e48\u610f\u601d\uff0c\u8bf7\u53c2\u9605 Python \u6587\u6863\u3002

    \u54c7\uff01\u5b83\u5de5\u4f5c\u4e86\uff01;)

    \u73b0\u5728\u6211\u8981\u5728\u90a3\u91cc\u6dfb\u52a0\u4e00\u4e9b\u903b\u8f91\u3002\u60f3\u4e00\u60f3\uff1a\u5982\u679c\u7528\u6237\u70b9\u51fb \u53d6\u6d88 \u6309\u94ae\uff0c\u6216\u8005\u70b9\u51fb \u786e\u5b9a \u4f46\u5c06\u8f93\u5165\u5b57\u6bb5\u7559\u7a7a\uff0c\u4f1a\u53d1\u751f\u4ec0\u4e48\uff1f

    \u60a8\u53ef\u4ee5\u73a9\u8fd9\u4e2a\u7a0b\u5e8f\uff0c\u68c0\u67e5 respond \u53d8\u91cf\u5728\u6bcf\u79cd\u60c5\u51b5\u4e0b\u5305\u542b\u4ec0\u4e48\u3002

    \u9996\u5148\uff0c\u6211\u60f3\u5c06\u7528\u6237\u8f93\u5165\u7684\u6587\u672c\u653e\u5165\u4e00\u4e2a\u5355\u72ec\u7684\u53d8\u91cf\u4e2d\uff1aname = respond.result\u3002\u7136\u540e\u6211\u68c0\u67e5\u5b83\uff0c\u5982\u679c\u5b83\u5305\u542b\u4efb\u4f55\u771f\u5b9e\u6587\u672c\uff0c\u5b83\u5c06\u88ab\u89c6\u4e3a\u540d\u79f0\u5e76\u7528\u4e8e\u95ee\u5019\u3002\u5426\u5219\uff0c\u5c06\u663e\u793a\u53e6\u4e00\u6761\u6d88\u606f\u3002\u5c06\u7b2c\u4e94\u884c message = f'Hello, {respond.result}!' \u66ff\u6362\u4e3a\u4ee5\u4e0b\u4ee3\u7801\uff1a

    name = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\n

    \u4f7f\u7528\u5de5\u5177\u680f\u4e0a\u7684 < \u548c > \u6309\u94ae\u6765\u7f29\u8fdb/\u53d6\u6d88\u7f29\u8fdb if \u8bed\u53e5\u4e2d\u7684\u884c\uff08\u6216\u8005\u53ea\u9700\u4f7f\u7528\u7a7a\u683c/\u9000\u683c\u952e\uff09\u3002\u60a8\u53ef\u4ee5\u5728 \u6b64\u5904 \u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u7f29\u8fdb\u7684\u5185\u5bb9\uff1bif \u8bed\u53e5\u5728 \u6b64\u5904 \u63cf\u8ff0\u3002

    \u9996\u5148\uff0c\u6211\u4eec\u5c06\u7528\u6237\u8f93\u5165\u653e\u5165 name \u53d8\u91cf\u3002\u7136\u540e\u6211\u4eec\u68c0\u67e5 name \u662f\u5426\u5305\u542b\u4efb\u4f55\u5185\u5bb9\uff1f\u5982\u679c\u7528\u6237\u7559\u7a7a\u884c\u5e76\u70b9\u51fb \u786e\u5b9a\uff0c\u8fd4\u56de\u503c\u662f\u7a7a\u5b57\u7b26\u4e32 ''\u3002\u5982\u679c\u6309\u4e0b\u4e86 \u53d6\u6d88 \u6309\u94ae\uff0c\u8fd4\u56de\u503c\u662f None\u3002\u5728 if \u8bed\u53e5\u4e2d\uff0c\u4e24\u8005\u90fd\u88ab\u89c6\u4e3a\u5047\u3002\u56e0\u6b64\uff0c\u53ea\u6709\u5f53 name \u5305\u542b\u4efb\u4f55\u6709\u610f\u4e49\u7684\u5185\u5bb9\u65f6\uff0cthen \u8bed\u53e5\u624d\u4f1a\u6267\u884c\uff0c\u5e76\u663e\u793a\u95ee\u5019\u8bed\"Hello, ...!\"\u3002\u5982\u679c\u8f93\u5165\u4e3a\u7a7a\uff0c\u7528\u6237\u5c06\u770b\u5230\"Hey! And you're not very polite, %Username%!\"\u6d88\u606f\u3002

    \u597d\u7684\uff0c\u8fd9\u662f\u6574\u4e2a\u7a0b\u5e8f\uff1a

    #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nname = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\ndroid.makeToast(message)\n
    "},{"location":"tutorial-hello-world/#_3","title":"\u8fd0\u884c\u6548\u679c","text":""},{"location":"tutorial-hello-world/#_4","title":"\u4e0b\u4e00\u6b65","text":"

    \u5bf9\u4e8e Python \u65b0\u7528\u6237\uff0c\u63a8\u8350\u5b66\u4e60 Python \u8bed\u6cd5\u5b9e\u8df5 \u8bfe\u7a0b\u6765\u8fdb\u4e00\u6b65\u5b66\u4e60 Python\uff0c\u6216\u8005\u5728 QPython \u7cbe\u9009\u8bfe\u7a0b \u4e2d\u5bfb\u627e\u60f3\u8981\u5b66\u4e60\u7684\u5185\u5bb9\u3002

    "},{"location":"whats-new/","title":"\u66f4\u65b0\u65e5\u5fd7","text":""},{"location":"whats-new/#v392-v393","title":"v3.9.2 / v3.9.3","text":"
    • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
    • \u7f16\u8f91\u5668\u91cd\u5927\u66f4\u65b0\uff0c\u5e26\u6765\u66f4\u6d41\u7545\u7684\u7f16\u8f91\u4f53\u9a8c
    • \u5176\u4ed6\u5404\u79cd\u5c0f\u6539\u8fdb
    "},{"location":"whats-new/#v391","title":"v3.9.1","text":"
    • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
    • \u6269\u5c55\u5305\u73b0\u5728\u652f\u6301 MCP
    • \u9519\u8bef\u4fee\u590d
    "},{"location":"whats-new/#v390","title":"v3.9.0","text":"
    • SDK \u5347\u7ea7\uff0c\u6574\u5408\u6700\u65b0\u7684 Android \u529f\u80fd
    • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
    • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
    • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
    "},{"location":"whats-new/#v3811","title":"v3.8.11","text":"
    • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
    • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
    • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
    "},{"location":"whats-new/#v3810","title":"v3.8.10","text":"
    • \u5185\u7f6e Ollama \u5347\u7ea7\uff1a\u73b0\u5728\u60a8\u53ef\u4ee5\u5728 QPython \u4e2d\u8f7b\u677e\u672c\u5730\u8fd0\u884c Qwen3 / Gemma3 \u6a21\u578b\uff01
    • \u6dfb\u52a0\u4e86\u5f3a\u5927\u7684 MCP \u5e93\uff1a\u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 mcp \u5e93\uff0c\u8ba9\u60a8\u968f\u65f6\u968f\u5730\u643a\u5e26\u5f3a\u5927\u7684 MCP \u529f\u80fd\uff01
    "},{"location":"whats-new/#v389","title":"v3.8.9","text":"

    \u91cd\u5927\u66f4\u65b0\uff01AI \u7f16\u7a0b\u5b8c\u5168\u96c6\u6210\u5230 QPython\uff0c\u8ba9\u60a8\u7684\u7f16\u7a0b\u66f4\u8f7b\u677e\uff01

    • \u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u652f\u6301\uff1a\u65b0\u652f\u6301 AIPyApp\uff0c\u5728 QPython \u4e2d\u5b9e\u73b0\u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u3002\u76ee\u524d\u5904\u4e8e\u6d4b\u8bd5\u9636\u6bb5 - \u52a0\u5165\u6211\u4eec\u7684\u793e\u533a\u83b7\u53d6\u4f7f\u7528\u8bf4\u660e
    • \u65b0 QSL4A \u529f\u80fd\uff1a\u6dfb\u52a0 notebookOpen \u51fd\u6570\uff0c\u652f\u6301\u81ea\u7136\u8bed\u8a00\u63a7\u5236\u6253\u5f00 Notebook \u6587\u4ef6
    • \u5185\u7f6e\u7f16\u8f91\u5668\u5347\u7ea7\uff1a\u589e\u5f3a\u7f16\u8f91\u5668\u529f\u80fd\uff0c\u652f\u6301\u6253\u5f00\u548c\u6d4f\u89c8\u5404\u79cd\u6587\u672c\u6587\u4ef6
    • \u4fbf\u6377\u7684\u6587\u4ef6\u7ba1\u7406\uff1a\u5728\u6587\u4ef6\u7ba1\u7406\u5668\u4e2d\u6dfb\u52a0\u5185\u90e8\u5b58\u50a8\u5165\u53e3\uff0c\u5feb\u901f\u8bbf\u95ee\u60a8\u7684\u6587\u4ef6
    "},{"location":"whats-new/#v388","title":"v3.8.8","text":"
    • \u6587\u4ef6\u8bbf\u95ee\u6743\u9650\u63a7\u5236\u7684\u91cd\u8981\u6539\u8fdb\uff0c\u5141\u8bb8\u7528\u6237\u7075\u6d3b\u5730\u901a\u8fc7 QPython \u7f16\u7a0b\u542f\u7528\u6216\u7981\u7528\u5916\u90e8\u5b58\u50a8\u6587\u4ef6\u7684\u8bbf\u95ee
    • SDK \u5347\u7ea7\uff0c\u589e\u5f3a\u4e86\u5bf9\u65b0\u7248 Android \u7684\u652f\u6301\u548c\u517c\u5bb9\u6027
    • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Anthropic \u548c Google GenAI \u5e93
    "},{"location":"whats-new/#v387","title":"v3.8.7","text":"
    • \u5728\u73b0\u6709 Tkinter \u652f\u6301\u57fa\u7840\u4e0a\uff0c\u5728 Extensions -> Tools \u4e2d\u6dfb\u52a0\u4e86\u4f7f\u7528 Turtle \u7ed8\u5236\u54c6\u5566A\u68a6\u7684\u793a\u4f8b\u4ee3\u7801
    • \u4f18\u5316\u4e86\u624b\u673a\u6743\u9650\u83b7\u53d6\u6d41\u7a0b\uff0c\u63d0\u5347\u7528\u6237\u4f53\u9a8c\u548c\u64cd\u4f5c\u4fbf\u5229\u6027
    • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Google Gen AI \u5e93\uff0c\u65b9\u4fbf\u8bbf\u95ee Gemini Developer API \u548c Vertex AI
    "},{"location":"whats-new/#v386","title":"v3.8.6","text":"
    • Tkinter \u652f\u6301\uff1a\u73b0\u5728\u652f\u6301 Tkinter \u5e93\uff0c\u53ef\u901a\u8fc7 XServer \u8bbf\u95ee\u3002\u8bf7\u8bbf\u95ee www.qpython.org \u7684\u4e91\u76d8\"Extra\"\u94fe\u63a5\u4e0b\u8f7d\u6240\u9700\u6587\u4ef6
    • \u5b58\u50a8\u6743\u9650\u66f4\u65b0\uff1a\u4e3a\u6539\u5584\u7528\u6237\u4f53\u9a8c\uff0c\u6211\u4eec\u6dfb\u52a0\u4e86\u8bfb\u53d6\u624b\u673a\u5b58\u50a8\u7684\u6743\u9650\uff0c\u7528\u4e8e\u8bbf\u95ee\u5b58\u50a8\u5728\u5176\u4ed6\u76ee\u5f55\u4e2d\u7684 Python \u7a0b\u5e8f

    \u6b64\u66f4\u65b0\u540e\uff0cQPython \u548c QPythonPlus\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff0c\u4e13\u4e3a\u9700\u8981\u66f4\u591a\u654f\u611f\u6743\u9650\u7684\u9ad8\u7ea7\u7528\u6237\u8bbe\u8ba1\uff09\u5c06\u4fdd\u6301\u540c\u6b65\u7684\u7248\u672c\u53f7\u3002

    "},{"location":"whats-new/#v352-2025225","title":"v3.5.2 (2025/2/25)","text":"

    \u4e0e\u5f00\u6e90 LLM \u90e8\u7f72\u5de5\u5177 Ollama \u4ee5\u53ca DeepSeek \u5f00\u53d1\u7684 DeepSeek \u5b9e\u73b0\u65e0\u7f1d\u96c6\u6210\uff01

    \u529f\u80fd\uff1a - \u96f6\u95e8\u69db\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5404\u79cd\u5927\u578b\u8bed\u8a00\u6a21\u578b - \u5feb\u901f\u90e8\u7f72 DeepSeek \u7b49\u5c16\u7aef AI \u6a21\u578b - \u4eab\u53d7\u7b80\u7ea6\u7684 API \u8c03\u7528\u4f53\u9a8c - \u6784\u5efa\u5b8c\u5168\u79bb\u7ebf\u7684\u667a\u80fd\u7f16\u7a0b\u73af\u5883

    \u80fd\u529b\uff1a - \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u52a0\u8f7d/\u7ba1\u7406 LLM \u6a21\u578b - \u57fa\u4e8e\u672c\u5730\u8ba1\u7b97\u7684\u5b9e\u65f6\u4f4e\u5ef6\u8fdf\u54cd\u5e94

    "},{"location":"whats-new/#v350","title":"v3.5.0","text":"
    • Python \u5347\u7ea7\u5230 3.12.8
    • \u6539\u8fdb\u4eea\u8868\u76d8\uff0c\u529f\u80fd\u66f4\u6e05\u6670\u3001\u66f4\u4eba\u6027\u5316
    • \u6dfb\u52a0\u4e86\u4f17\u591a\u7b2c\u4e09\u65b9\u5305\uff1aPyTorch / Twisted / Scrapy / FastAPI ...
    "},{"location":"whats-new/#v338","title":"v3.3.8","text":"
    • \u4fee\u590d\u4e86 NumPy \u517c\u5bb9\u6027\u95ee\u9898
    "},{"location":"whats-new/#v335","title":"v3.3.5","text":"
    • \u5347\u7ea7 Python \u5185\u6838\u5230 3.11.9
    • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u4e0d\u663e\u793a\u6a21\u5757\u5b89\u88c5\u72b6\u6001\u7684 bug
    • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u5220\u9664\u6a21\u5757\u5931\u8d25\u7684 bug
    • \u4fee\u590d\u4e86\u5176\u4ed6 bug
    "},{"location":"whats-new/#v334","title":"v3.3.4","text":"
    • \u6dfb\u52a0\u4e86 OpenAI/Langchain/APIGPTCloud AI \u5305
    • \u79fb\u9664\u4e0d\u5fc5\u8981\u7684\u6587\u4ef6\u4ee5\u51cf\u5c11\u5927\u5c0f
    "},{"location":"whats-new/#v325","title":"v3.2.5","text":"
    • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570
    • \u5176\u4ed6\u9519\u8bef\u4fee\u590d
    "},{"location":"whats-new/#v323","title":"v3.2.3","text":"
    • \u66f4\u65b0 Python \u7248\u672c\u5230 3.11.0
    • \u66f4\u65b0 IPython \u7248\u672c\u5230 8.6.0
    • \u66f4\u65b0 pip \u7248\u672c\u5230 22.3.1
    • \u66f4\u65b0\u79d1\u5b66\u8ba1\u7b97\u5305\uff0c\u81ea\u52a8\u8f6f\u94fe\u63a5
    • \u51cf\u5c11\u7a7a\u95f4\u4f7f\u7528
    • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570 + \u5176\u4ed6\u9519\u8bef\u4fee\u590d
    "},{"location":"whats-new/#v318","title":"v3.1.8","text":"
    • \u5728\u7ec8\u7aef\u4e2d\u6dfb\u52a0\u4e86\u64cd\u4f5c\u70ed\u952e
    • \u4fee\u590d\u4e86\u7f16\u8f91\u5668\u5728\u65cb\u8f6c\u65f6\u4e22\u5931\u5185\u5bb9\u7684\u95ee\u9898
    • \u4fee\u590d\u4e86\u5176\u4ed6 bug

    \u5728 Google Play \u4e0b\u8f7d

    "},{"location":"qsl4a/","title":"QSL4A\uff08Android \u811a\u672c\u5c42\uff09API \u6587\u6863","text":"

    QSL4A \u662f QPython \u7684 Android \u811a\u672c\u5c42\uff0c\u5141\u8bb8\u60a8\u4f7f\u7528 Python \u63a7\u5236 Android \u8bbe\u5907\u529f\u80fd\u3002

    "},{"location":"qsl4a/#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a toast \u6d88\u606f\ndroid.makeToast('Hello QPython!')\n\n# \u9707\u52a8\u8bbe\u5907\ndroid.vibrate(500)\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\uff08\u5148\u5f00\u59cb\u76d1\u63a7\uff09\nimport time\ndroid.batteryStartMonitoring()\ntime.sleep(0.5)  # \u7b49\u5f85\u6570\u636e\nbattery = droid.readBatteryData().result\nprint(f\"\u7535\u6c60\uff1a{battery['level']}%\")\n
    "},{"location":"qsl4a/#_2","title":"\u6587\u6863\u7ed3\u6784","text":""},{"location":"qsl4a/#_3","title":"\u6838\u5fc3\u6a21\u5757","text":"
    • Android \u57fa\u7840 - \u6838\u5fc3\u8fde\u63a5\u548c RPC
    • Intent \u7cfb\u7edf - Android Intent \u64cd\u4f5c
    • \u4e8b\u4ef6\u7cfb\u7edf - \u4e8b\u4ef6\u5904\u7406\u548c\u5e7f\u64ad
    "},{"location":"qsl4a/#ui","title":"UI \u7ec4\u4ef6","text":"
    • \u5bf9\u8bdd\u6846 - \u8b66\u62a5\u3001\u8f93\u5165\u3001\u9009\u62e9\u5bf9\u8bdd\u6846
    • \u5168\u5c4f UI - \u81ea\u5b9a\u4e49\u5e03\u5c40 UI
    • \u60ac\u6d6e\u7a97 - \u60ac\u6d6e\u7a97\u53e3
    • \u8f85\u52a9\u529f\u80fd - \u5c4f\u5e55\u81ea\u52a8\u5316
    "},{"location":"qsl4a/#_4","title":"\u7cfb\u7edf","text":"
    • \u7535\u6c60 - \u7535\u6c60\u76d1\u63a7
    • \u4f20\u611f\u5668 - \u8bbe\u5907\u4f20\u611f\u5668
    • \u5e94\u7528 - \u5e94\u7528\u7ba1\u7406
    • \u7cfb\u7edf\u4fe1\u606f - \u8bbe\u5907\u4fe1\u606f
    • \u8bbe\u7f6e - \u7cfb\u7edf\u8bbe\u7f6e
    • \u5524\u9192\u9501 - \u5524\u9192\u9501\u63a7\u5236
    • QPython \u63a5\u53e3 - \u811a\u672c\u6267\u884c
    • Activity \u7ed3\u679c - Activity \u7ed3\u679c\u5904\u7406
    "},{"location":"qsl4a/#_5","title":"\u786c\u4ef6","text":"
    • \u84dd\u7259 - \u84dd\u7259\u64cd\u4f5c
    • \u76f8\u673a - \u62cd\u7167\u548c\u5f55\u50cf
    • \u97f3\u9891/\u5f55\u97f3\u5668 - \u5f55\u97f3
    • \u7f51\u7edc\u6444\u50cf\u5934 - MJPEG \u6d41
    • USB \u4e32\u53e3 - USB \u4e3b\u673a\u4e32\u53e3
    "},{"location":"qsl4a/#_6","title":"\u8fde\u63a5","text":"
    • WiFi - WiFi \u64cd\u4f5c
    • \u4f4d\u7f6e - GPS \u548c\u4f4d\u7f6e
    • \u77ed\u4fe1 - \u77ed\u4fe1\u64cd\u4f5c
    • \u7535\u8bdd - \u6253\u7535\u8bdd\u548c\u6765\u7535\u4fe1\u606f
    • \u8054\u7cfb\u4eba - \u8054\u7cfb\u4eba\u7ba1\u7406
    • \u4fe1\u53f7\u5f3a\u5ea6 - \u4fe1\u53f7\u76d1\u63a7
    • FTP \u670d\u52a1\u5668 - \u5185\u7f6e FTP \u670d\u52a1\u5668
    "},{"location":"qsl4a/#_7","title":"\u5b58\u50a8","text":"
    • DocumentFile - \u6587\u4ef6\u64cd\u4f5c
    • \u526a\u8d34\u677f - \u526a\u8d34\u677f\u64cd\u4f5c
    • \u504f\u597d\u8bbe\u7f6e - \u5171\u4eab\u504f\u597d\u8bbe\u7f6e
    "},{"location":"qsl4a/#_8","title":"\u5a92\u4f53","text":"
    • \u5a92\u4f53\u64ad\u653e\u5668 - \u97f3\u9891/\u89c6\u9891\u64ad\u653e
    • \u56fe\u50cf\u5904\u7406 - \u56fe\u50cf\u64cd\u4f5c
    "},{"location":"qsl4a/#_9","title":"\u7279\u6b8a\u529f\u80fd","text":"
    • \u52a0\u5bc6 - \u52a0\u5bc6/\u89e3\u5bc6
    • PGPT AI - AI \u8bed\u97f3\u670d\u52a1
    "},{"location":"qsl4a/#_10","title":"\u7ed3\u679c\u5bf9\u8c61","text":"

    \u5927\u591a\u6570 QSL4A \u65b9\u6cd5\u8fd4\u56de\u4e00\u4e2a\u5e26\u6709\u4ee5\u4e0b\u5c5e\u6027\u7684 Result \u547d\u540d\u5143\u7ec4\uff1a - id - \u8bf7\u6c42 ID - result - \u5b9e\u9645\u7ed3\u679c\u6570\u636e - error - \u5982\u679c\u5931\u8d25\u5219\u4e3a\u9519\u8bef\u6d88\u606f

    result = droid.getClipboard()\nif result.error is None:\n    print(result.result)\nelse:\n    print(f\"\u9519\u8bef\uff1a{result.error}\")\n
    "},{"location":"qsl4a/connectivity/contacts/","title":"\u8054\u7cfb\u4eba API","text":"

    \u8bbf\u95ee\u548c\u7ba1\u7406\u8bbe\u5907\u8054\u7cfb\u4eba\u3002

    "},{"location":"qsl4a/connectivity/contacts/#_1","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":""},{"location":"qsl4a/connectivity/contacts/#pickcontact","title":"pickContact()","text":"

    \u663e\u793a\u8054\u7cfb\u4eba\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

    pickContact()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u8054\u7cfb\u4eba URI \u7684 Intent

    "},{"location":"qsl4a/connectivity/contacts/#pickphone","title":"pickPhone()","text":"

    \u663e\u793a\u7535\u8bdd\u53f7\u7801\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

    pickPhone()\n

    \u8fd4\u56de\uff1a \u9009\u4e2d\u7684\u7535\u8bdd\u53f7\u7801\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/connectivity/contacts/#_2","title":"\u8054\u7cfb\u4eba\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#contactsget","title":"contactsGet()","text":"

    \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\u3002

    contactsGet(attributes=None)\n

    \u53c2\u6570\uff1a - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

    \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba JSONObject \u5217\u8868

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetbyid","title":"contactsGetById()","text":"

    \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\u3002

    contactsGetById(id, attributes=None)\n

    \u53c2\u6570\uff1a - id (int): \u8054\u7cfb\u4eba ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

    \u8fd4\u56de\uff1a JSONObject \u8054\u7cfb\u4eba\u6570\u636e

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetcount","title":"contactsGetCount()","text":"

    \u83b7\u53d6\u8054\u7cfb\u4eba\u603b\u6570\u3002

    contactsGetCount()\n

    \u8fd4\u56de\uff1a \u6574\u6570\u8ba1\u6570

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetids","title":"contactsGetIds()","text":"

    \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba ID\u3002

    contactsGetIds()\n

    \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba ID \u6574\u6570\u5217\u8868

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetattributes","title":"contactsGetAttributes()","text":"

    \u83b7\u53d6\u6240\u6709\u53ef\u80fd\u7684\u8054\u7cfb\u4eba\u5c5e\u6027\u3002

    contactsGetAttributes()\n

    \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u5217\u8868

    "},{"location":"qsl4a/connectivity/contacts/#_3","title":"\u5185\u5bb9\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#querycontent","title":"queryContent()","text":"

    \u4f7f\u7528\u81ea\u5b9a\u4e49\u53c2\u6570\u67e5\u8be2\u5185\u5bb9\u89e3\u6790\u5668\u3002

    queryContent(uri, attributes=None, selection=None, selectionArgs=None, order=None)\n

    \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u5c5e\u6027 - selection (str, optional): WHERE \u5b50\u53e5 - selectionArgs (list, optional): \u9009\u62e9\u53c2\u6570 - order (str, optional): ORDER BY \u5b50\u53e5

    \u8fd4\u56de\uff1a JSONObject \u7ed3\u679c\u5217\u8868

    "},{"location":"qsl4a/connectivity/contacts/#queryattributes","title":"queryAttributes()","text":"

    \u83b7\u53d6\u5185\u5bb9 URI \u7684\u5c5e\u6027\u3002

    queryAttributes(uri)\n

    \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI

    \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u7684 JSONArray

    "},{"location":"qsl4a/connectivity/contacts/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u9009\u62e9\u8054\u7cfb\u4eba\ncontact_uri = droid.pickContact().result\nprint(f\"Selected contact: {contact_uri}\")\n\n# \u9009\u62e9\u7535\u8bdd\u53f7\u7801\nphone = droid.pickPhone().result\nprint(f\"Selected phone: {phone}\")\n\n# \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\ncontacts = droid.contactsGet().result\nprint(f\"Total contacts: {len(contacts)}\")\n\n# \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\ncontact = droid.contactsGetById(1).result\nprint(f\"Contact: {contact}\")\n\n# \u83b7\u53d6\u8054\u7cfb\u4eba\u5c5e\u6027\nattrs = droid.contactsGetAttributes().result\nprint(f\"Available attributes: {attrs}\")\n
    "},{"location":"qsl4a/connectivity/ftp/","title":"FTP \u670d\u52a1\u5668 API","text":"

    \u5728\u8bbe\u5907\u4e0a\u542f\u52a8\u548c\u7ba1\u7406\u5185\u7f6e FTP \u670d\u52a1\u5668\u3002

    "},{"location":"qsl4a/connectivity/ftp/#ftp","title":"FTP \u670d\u52a1\u5668\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/ftp/#ftpstart","title":"ftpStart()","text":"

    \u542f\u52a8 FTP \u670d\u52a1\u5668\u3002

    ftpStart()\n

    \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4 [ip, port]

    "},{"location":"qsl4a/connectivity/ftp/#ftpstop","title":"ftpStop()","text":"

    \u505c\u6b62 FTP \u670d\u52a1\u5668\u3002

    ftpStop()\n
    "},{"location":"qsl4a/connectivity/ftp/#ftpisrunning","title":"ftpIsRunning()","text":"

    \u68c0\u67e5 FTP \u670d\u52a1\u5668\u662f\u5426\u6b63\u5728\u8fd0\u884c\u3002

    ftpIsRunning()\n

    \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u8fd0\u884c\u5219\u4e3a True

    "},{"location":"qsl4a/connectivity/ftp/#ftpget","title":"ftpGet()","text":"

    \u83b7\u53d6 FTP \u670d\u52a1\u5668 IP \u5730\u5740\u3002

    ftpGet()\n

    \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4

    "},{"location":"qsl4a/connectivity/ftp/#ftpset","title":"ftpSet()","text":"

    \u914d\u7f6e FTP \u670d\u52a1\u5668\u8bbe\u7f6e\u3002

    ftpSet(port=None, rootDir=None, username=None, password=None)\n

    \u53c2\u6570\uff1a - port (int, optional): \u670d\u52a1\u5668\u7aef\u53e3 - rootDir (str, optional): \u8981\u670d\u52a1\u7684\u57fa\u7840\u76ee\u5f55 - username (str, optional): \u767b\u5f55\u7528\u6237\u540d - password (str, optional): \u767b\u5f55\u5bc6\u7801

    \u8fd4\u56de\uff1a \u5305\u542b\u5f53\u524d\u8bbe\u7f6e\u7684 JSONObject

    "},{"location":"qsl4a/connectivity/ftp/#ftpstatus","title":"ftpStatus()","text":"

    \u83b7\u53d6 FTP \u670d\u52a1\u5668\u72b6\u6001\u3002

    ftpStatus()\n

    \u8fd4\u56de\uff1a \u72b6\u6001\u63cf\u8ff0\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/connectivity/ftp/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u914d\u7f6e FTP \u670d\u52a1\u5668\ndroid.ftpSet(\n    port=2121,\n    rootDir=\"/sdcard\",\n    username=\"admin\",\n    password=\"secret\"\n)\n\n# \u542f\u52a8 FTP \u670d\u52a1\u5668\ninfo = droid.ftpStart().result\nprint(f\"FTP running at {info[0]}:{info[1]}\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.ftpIsRunning().result:\n    print(\"FTP server is running\")\n\n# \u83b7\u53d6\u670d\u52a1\u5668\u4fe1\u606f\nserver_info = droid.ftpGet().result\nprint(f\"Server: {server_info}\")\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.ftpStop()\n

    \u6ce8\u610f\uff1a \u4f7f\u7528\u63d0\u4f9b\u7684\u51ed\u636e\u901a\u8fc7\u4efb\u4f55 FTP \u5ba2\u6237\u7aef\u8fde\u63a5\u5230 FTP \u670d\u52a1\u5668\u3002

    "},{"location":"qsl4a/connectivity/location/","title":"\u4f4d\u7f6e API","text":"

    \u8bbf\u95ee GPS \u548c\u7f51\u7edc\u4f4d\u7f6e\u670d\u52a1\u3002

    "},{"location":"qsl4a/connectivity/location/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/location/#startlocating","title":"startLocating()","text":"

    \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\u3002

    startLocating(minUpdateTime=60000, minUpdateDistance=30, updateGnssStatus=False)\n

    \u53c2\u6570\uff1a - minUpdateTime (int): \u66f4\u65b0\u4e4b\u95f4\u7684\u6700\u5c0f\u65f6\u95f4\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a60000\uff09 - minUpdateDistance (float): \u66f4\u65b0\u7684\u6700\u5c0f\u8ddd\u79bb\uff08\u7c73\uff09\uff08\u9ed8\u8ba4\uff1a30\uff09 - updateGnssStatus (bool): \u542f\u7528 GNSS \u72b6\u6001\u66f4\u65b0\uff08\u9ed8\u8ba4\uff1aFalse\uff09

    "},{"location":"qsl4a/connectivity/location/#stoplocating","title":"stopLocating()","text":"

    \u505c\u6b62\u4f4d\u7f6e\u66f4\u65b0\u3002

    stopLocating()\n
    "},{"location":"qsl4a/connectivity/location/#readlocation","title":"readLocation()","text":"

    \u83b7\u53d6\u6700\u540e\u5df2\u77e5\u4f4d\u7f6e\u3002

    readLocation()\n

    \u8fd4\u56de\uff1a \u4f4d\u7f6e\u6570\u636e\u5b57\u5178

    "},{"location":"qsl4a/connectivity/location/#getlastknownlocation","title":"getLastKnownLocation()","text":"

    \u83b7\u53d6\u7f13\u5b58\u7684\u4f4d\u7f6e\u3002

    getLastKnownLocation()\n

    \u8fd4\u56de\uff1a \u6765\u81ea\u6240\u6709\u63d0\u4f9b\u5546\u7684\u4f4d\u7f6e

    "},{"location":"qsl4a/connectivity/location/#geocode","title":"geocode()","text":"

    \u5c06\u5730\u5740\u8f6c\u6362\u4e3a\u5750\u6807\u3002

    geocode(address, maxResults=1)\n
    "},{"location":"qsl4a/connectivity/location/#_2","title":"\u4f4d\u7f6e\u63d0\u4f9b\u5546\u65b9\u6cd5)","text":""},{"location":"qsl4a/connectivity/location/#locationproviders","title":"locationProviders()","text":"

    \u83b7\u53d6\u624b\u673a\u4e0a\u53ef\u7528\u7684\u4f4d\u7f6e\u63d0\u4f9b\u5546\u3002

    locationProviders()\n

    \u8fd4\u56de\uff1a \u53ef\u7528\u63d0\u4f9b\u5546\u540d\u79f0\u5217\u8868\uff08\u4f8b\u5982 ['gps', 'network']\uff09

    "},{"location":"qsl4a/connectivity/location/#locationproviderenabled","title":"locationProviderEnabled()","text":"

    \u68c0\u67e5\u7279\u5b9a\u4f4d\u7f6e\u63d0\u4f9b\u5546\u662f\u5426\u5df2\u542f\u7528\u3002

    locationProviderEnabled(provider)\n

    \u53c2\u6570\uff1a - provider (str): \u63d0\u4f9b\u5546\u540d\u79f0\uff08\u4f8b\u5982 'gps', 'network'\uff09

    \u8fd4\u56de\uff1a \u5982\u679c\u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

    "},{"location":"qsl4a/connectivity/location/#readgnssstatus","title":"readGnssStatus()","text":"

    \u8bfb\u53d6\u5168\u7403\u5bfc\u822a\u536b\u661f\u7cfb\u7edf\u72b6\u6001\uff08\u9700\u8981 Android 8+\uff09\u3002

    readGnssStatus()\n

    \u8fd4\u56de\uff1a \u5305\u542b GNSS \u536b\u661f\u4fe1\u606f\u7684 JSONArray

    "},{"location":"qsl4a/connectivity/location/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\ndroid.startLocating(minUpdateTime=5000, minUpdateDistance=1, updateGnssStatus=False)\n\n# \u7b49\u5f85\u5b9a\u4f4d\ntime.sleep(10)\n\n# \u83b7\u53d6\u4f4d\u7f6e\nloc = droid.readLocation().result\nif loc:\n    lat = loc['latitude']\n    lon = loc['longitude']\n    print(f\"Location: {lat}, {lon}\")\n\ndroid.stopLocating()\n
    "},{"location":"qsl4a/connectivity/phone/","title":"\u7535\u8bdd API","text":"

    \u63a7\u5236\u7535\u8bdd\u901a\u8bdd\u548c\u83b7\u53d6\u7535\u8bdd\u4fe1\u606f\u3002

    "},{"location":"qsl4a/connectivity/phone/#_1","title":"\u7535\u8bdd\u72b6\u6001\u8ddf\u8e2a","text":""},{"location":"qsl4a/connectivity/phone/#starttrackingphonestate","title":"startTrackingPhoneState()","text":"

    \u5f00\u59cb\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u53d8\u5316\u3002\u751f\u6210 'phone' \u4e8b\u4ef6\u3002

    startTrackingPhoneState()\n
    "},{"location":"qsl4a/connectivity/phone/#readphonestate","title":"readPhoneState()","text":"

    \u8bfb\u53d6\u5f53\u524d\u7535\u8bdd\u72b6\u6001\u3002

    readPhoneState()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u7535\u8bdd\u72b6\u6001\u548c\u6765\u7535\u53f7\u7801\u7684 Bundle

    "},{"location":"qsl4a/connectivity/phone/#stoptrackingphonestate","title":"stopTrackingPhoneState()","text":"

    \u505c\u6b62\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u3002

    stopTrackingPhoneState()\n
    "},{"location":"qsl4a/connectivity/phone/#_2","title":"\u62e8\u6253\u7535\u8bdd","text":""},{"location":"qsl4a/connectivity/phone/#phonecall","title":"phoneCall()","text":"

    \u901a\u8fc7 URI \u547c\u53eb\u8054\u7cfb\u4eba/\u7535\u8bdd\u53f7\u7801\u3002

    phoneCall(uri)\n

    \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

    "},{"location":"qsl4a/connectivity/phone/#phonecallnumber","title":"phoneCallNumber()","text":"

    \u76f4\u63a5\u62e8\u6253\u7535\u8bdd\u53f7\u7801\u3002

    phoneCallNumber(phone_number)\n

    \u53c2\u6570\uff1a - phone_number (str): \u8981\u62e8\u6253\u7684\u7535\u8bdd\u53f7\u7801

    "},{"location":"qsl4a/connectivity/phone/#phonedial","title":"phoneDial()","text":"

    \u62e8\u6253\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

    phoneDial(uri)\n

    \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

    "},{"location":"qsl4a/connectivity/phone/#phonedialnumber","title":"phoneDialNumber()","text":"

    \u62e8\u6253\u7535\u8bdd\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

    phoneDialNumber(phone_number)\n

    \u53c2\u6570\uff1a - phone_number (str): \u7535\u8bdd\u53f7\u7801

    "},{"location":"qsl4a/connectivity/phone/#_3","title":"\u57fa\u7ad9\u4f4d\u7f6e","text":""},{"location":"qsl4a/connectivity/phone/#getcelllocation","title":"getCellLocation()","text":"

    \u83b7\u53d6\u5f53\u524d\u57fa\u7ad9\u4f4d\u7f6e\u3002

    getCellLocation()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u57fa\u7ad9\u4f4d\u7f6e\u6570\u636e\u7684 JSONObject

    "},{"location":"qsl4a/connectivity/phone/#getallcellslocation","title":"getAllCellsLocation()","text":"

    \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u4f4d\u7f6e\uff08\u9002\u7528\u4e8e\u53cc\u5361\u8bbe\u5907\uff09\u3002

    getAllCellsLocation()\n

    \u8fd4\u56de\uff1a \u57fa\u7ad9\u4f4d\u7f6e\u7684 JSONArray

    "},{"location":"qsl4a/connectivity/phone/#_4","title":"\u7f51\u7edc\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getnetworkoperator","title":"getNetworkOperator()","text":"

    \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

    getNetworkOperator()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

    "},{"location":"qsl4a/connectivity/phone/#getnetworkoperatorname","title":"getNetworkOperatorName()","text":"

    \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684\u540d\u79f0\u3002

    getNetworkOperatorName()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

    "},{"location":"qsl4a/connectivity/phone/#getnetworktype","title":"getNetworkType()","text":"

    \u83b7\u53d6\u5f53\u524d\u7f51\u7edc\u7c7b\u578b\u3002

    getNetworkType()\n

    \u8fd4\u56de\uff1a \u63cf\u8ff0\u65e0\u7ebf\u7535\u6280\u672f\u7684\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'LTE', 'UMTS', 'GSM'\uff09

    "},{"location":"qsl4a/connectivity/phone/#getphonetype","title":"getPhoneType()","text":"

    \u83b7\u53d6\u7535\u8bdd\u7c7b\u578b\u3002

    getPhoneType()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'GSM', 'CDMA', 'SIP'\uff09

    "},{"location":"qsl4a/connectivity/phone/#sim","title":"SIM \u5361\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getsimcountryiso","title":"getSimCountryIso()","text":"

    \u83b7\u53d6 SIM \u5361\u7684 ISO \u56fd\u5bb6\u4ee3\u7801\u3002

    getSimCountryIso()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'us'\uff09

    "},{"location":"qsl4a/connectivity/phone/#getsimoperator","title":"getSimOperator()","text":"

    \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

    getSimOperator()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

    "},{"location":"qsl4a/connectivity/phone/#getsimoperatorname","title":"getSimOperatorName()","text":"

    \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u540d\u79f0\u3002

    getSimOperatorName()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

    "},{"location":"qsl4a/connectivity/phone/#getsimserialnumber","title":"getSimSerialNumber()","text":"

    \u83b7\u53d6 SIM \u5e8f\u5217\u53f7\u3002

    getSimSerialNumber()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32 SIM \u5e8f\u5217\u53f7

    "},{"location":"qsl4a/connectivity/phone/#getsimstate","title":"getSimState()","text":"

    \u83b7\u53d6 SIM \u5361\u72b6\u6001\u3002

    getSimState()\n

    \u8fd4\u56de\uff1a \u63cf\u8ff0 SIM \u72b6\u6001\u7684\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/connectivity/phone/#getsubscriberid","title":"getSubscriberId()","text":"

    \u83b7\u53d6\u8ba2\u9605\u8005 ID\u3002

    getSubscriberId()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8ba2\u9605\u8005 ID

    "},{"location":"qsl4a/connectivity/phone/#_5","title":"\u8bed\u97f3\u90ae\u4ef6","text":""},{"location":"qsl4a/connectivity/phone/#getvoicemailalphatag","title":"getVoiceMailAlphaTag()","text":"

    \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u5b57\u6bcd\u6807\u7b7e\u3002

    getVoiceMailAlphaTag()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u6807\u7b7e

    "},{"location":"qsl4a/connectivity/phone/#getvoicemailnumber","title":"getVoiceMailNumber()","text":"

    \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801\u3002

    getVoiceMailNumber()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801

    "},{"location":"qsl4a/connectivity/phone/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getdeviceid","title":"getDeviceId()","text":"

    \u83b7\u53d6\u8bbe\u5907 ID\uff08GSM \u7684 IMEI\uff09\u3002\u5df2\u5e9f\u5f03\u3002

    getDeviceId()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

    "},{"location":"qsl4a/connectivity/phone/#getdevicesoftwareversion","title":"getDeviceSoftwareVersion()","text":"

    \u83b7\u53d6\u8bbe\u5907\u8f6f\u4ef6\u7248\u672c\u3002

    getDeviceSoftwareVersion()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8f6f\u4ef6\u7248\u672c

    "},{"location":"qsl4a/connectivity/phone/#getline1number","title":"getLine1Number()","text":"

    \u83b7\u53d6\u7ebf\u8def 1 \u7535\u8bdd\u53f7\u7801\u3002

    getLine1Number()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u7535\u8bdd\u53f7\u7801

    "},{"location":"qsl4a/connectivity/phone/#checknetworkroaming","title":"checkNetworkRoaming()","text":"

    \u68c0\u67e5\u662f\u5426\u8fde\u63a5\u5230\u6f2b\u6e38\u7f51\u7edc\u3002

    checkNetworkRoaming()\n

    \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u6f2b\u6e38\u5219\u4e3a True

    "},{"location":"qsl4a/connectivity/phone/#_7","title":"\u57fa\u7ad9\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getallcellinfo","title":"getAllCellInfo()","text":"

    \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u7684\u4fe1\u606f\u3002

    getAllCellInfo()\n

    \u8fd4\u56de\uff1a \u57fa\u7ad9\u4fe1\u606f\u5217\u8868

    "},{"location":"qsl4a/connectivity/phone/#setdataenabled","title":"setDataEnabled()","text":"

    \u542f\u7528\u6216\u7981\u7528\u79fb\u52a8\u6570\u636e\u3002

    setDataEnabled(enabled)\n

    \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528

    "},{"location":"qsl4a/connectivity/phone/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7f51\u7edc\u4fe1\u606f\noperator = droid.getNetworkOperatorName().result\nprint(f\"Operator: {operator}\")\n\nnetwork_type = droid.getNetworkType().result\nprint(f\"Network: {network_type}\")\n\n# \u83b7\u53d6 SIM \u4fe1\u606f\nsim_state = droid.getSimState().result\nprint(f\"SIM: {sim_state}\")\n\n# \u83b7\u53d6\u7535\u8bdd\u53f7\u7801\nline1 = droid.getLine1Number().result\nprint(f\"Phone: {line1}\")\n\n# \u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\ndroid.startTrackingPhoneState()\nprint(\"Tracking phone state...\")\ndroid.stopTrackingPhoneState()\n
    "},{"location":"qsl4a/connectivity/signalstrength/","title":"\u4fe1\u53f7\u5f3a\u5ea6 API","text":"

    \u76d1\u63a7\u8702\u7a9d\u548c\u65e0\u7ebf\u4fe1\u53f7\u5f3a\u5ea6\u3002

    "},{"location":"qsl4a/connectivity/signalstrength/#_1","title":"\u4fe1\u53f7\u5f3a\u5ea6\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/signalstrength/#starttrackingsignalstrengths","title":"startTrackingSignalStrengths()","text":"

    \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316\u3002\u751f\u6210 'signal_strengths' \u4e8b\u4ef6\u3002

    startTrackingSignalStrengths()\n
    "},{"location":"qsl4a/connectivity/signalstrength/#stoptrackingsignalstrengths","title":"stopTrackingSignalStrengths()","text":"

    \u505c\u6b62\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u3002

    stopTrackingSignalStrengths()\n
    "},{"location":"qsl4a/connectivity/signalstrength/#readsignalstrengths","title":"readSignalStrengths()","text":"

    \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\u3002

    readSignalStrengths()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u4fe1\u53f7\u5f3a\u5ea6\u6570\u636e\u7684 Bundle

    "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthlevel","title":"getTelephoneSignalStrengthLevel()","text":"

    \u83b7\u53d6\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u7b49\u7ea7\uff080-4\uff09\u3002

    getTelephoneSignalStrengthLevel()\n

    \u8fd4\u56de\uff1a \u6574\u6570\u7b49\u7ea7\uff080=\u65e0\uff0c1=\u5dee\uff0c2=\u4e00\u822c\uff0c3=\u597d\uff0c4=\u4f18\u79c0\uff09

    "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthdetail","title":"getTelephoneSignalStrengthDetail()","text":"

    \u83b7\u53d6\u8be6\u7ec6\u7684\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u4fe1\u606f\u3002

    getTelephoneSignalStrengthDetail()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u8be6\u7ec6\u4fe1\u53f7\u4fe1\u606f\u7684\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/connectivity/signalstrength/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\ndroid.startTrackingSignalStrengths()\n\n# \u7b49\u5f85\u4fe1\u53f7\u66f4\u65b0\ntime.sleep(5)\n\n# \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\nsignal = droid.readSignalStrengths().result\nprint(f\"Signal: {signal}\")\n\n# \u76f4\u63a5\u83b7\u53d6\u7b49\u7ea7\nlevel = droid.getTelephoneSignalStrengthLevel().result\nprint(f\"Signal level: {level}/4\")\n\ndroid.stopTrackingSignalStrengths()\n
    "},{"location":"qsl4a/connectivity/sms/","title":"SMS API","text":"

    \u53d1\u9001\u548c\u63a5\u6536 SMS \u6d88\u606f\u3002

    "},{"location":"qsl4a/connectivity/sms/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/sms/#smssend","title":"smsSend()","text":"

    \u53d1\u9001 SMS \u6d88\u606f\u3002

    smsSend(destinationAddress, text)\n

    \u53c2\u6570\uff1a - destinationAddress (str): \u7535\u8bdd\u53f7\u7801 - text (str): \u6d88\u606f\u6587\u672c

    "},{"location":"qsl4a/connectivity/sms/#smsgetmessagecount","title":"smsGetMessageCount()","text":"

    \u83b7\u53d6\u6d88\u606f\u6570\u91cf\u3002

    smsGetMessageCount(unreadOnly=False, folder=\"inbox\")\n
    "},{"location":"qsl4a/connectivity/sms/#smsgetmessageids","title":"smsGetMessageIds()","text":"

    \u83b7\u53d6\u6d88\u606f ID\u3002

    smsGetMessageIds(unreadOnly=False, folder=\"inbox\")\n
    "},{"location":"qsl4a/connectivity/sms/#smsgetmessages","title":"smsGetMessages()","text":"

    \u83b7\u53d6\u6d88\u606f\u8be6\u60c5\u3002

    smsGetMessages(unreadOnly=False, folder=\"inbox\", attributes=None)\n
    "},{"location":"qsl4a/connectivity/sms/#smsgetmessagebyid","title":"smsGetMessageById()","text":"

    \u901a\u8fc7 ID \u83b7\u53d6\u7279\u5b9a\u6d88\u606f\u3002

    smsGetMessageById(id, attributes=None)\n

    \u53c2\u6570\uff1a - id (int): \u6d88\u606f ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

    \u8fd4\u56de\uff1a \u6d88\u606f\u6570\u636e\u5b57\u5178

    "},{"location":"qsl4a/connectivity/sms/#smsgetattributes","title":"smsGetAttributes()","text":"

    \u83b7\u53d6\u53ef\u7528\u7684 SMS \u6d88\u606f\u5c5e\u6027\u3002

    smsGetAttributes()\n

    \u8fd4\u56de\uff1a \u53ef\u7528\u5c5e\u6027\u540d\u79f0\u5217\u8868

    "},{"location":"qsl4a/connectivity/sms/#smsdeletemessage","title":"smsDeleteMessage()","text":"

    \u5220\u9664\u6d88\u606f\u3002

    smsDeleteMessage(id)\n
    "},{"location":"qsl4a/connectivity/sms/#smsmarkmessageread","title":"smsMarkMessageRead()","text":"

    \u5c06\u6d88\u606f\u6807\u8bb0\u4e3a\u5df2\u8bfb\u3002

    smsMarkMessageRead(ids, read=True)\n
    "},{"location":"qsl4a/connectivity/sms/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u53d1\u9001 SMS\ndroid.smsSend(\"+1234567890\", \"Hello from QPython!\")\n\n# \u83b7\u53d6\u672a\u8bfb\u6d88\u606f\nmessages = droid.smsGetMessages(unreadOnly=True).result\nfor msg in messages:\n    print(f\"From: {msg['address']}, Text: {msg['body']}\")\n
    "},{"location":"qsl4a/connectivity/wifi/","title":"WiFi API","text":"

    \u63a7\u5236 WiFi \u9002\u914d\u5668\u5e76\u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\u3002

    "},{"location":"qsl4a/connectivity/wifi/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/connectivity/wifi/#checkwifistate","title":"checkWifiState()","text":"

    \u68c0\u67e5 WiFi \u662f\u5426\u5df2\u542f\u7528\u3002

    checkWifiState()\n

    \u8fd4\u56de\uff1a \u5982\u679c WiFi \u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

    "},{"location":"qsl4a/connectivity/wifi/#togglewifistate","title":"toggleWifiState()","text":"

    \u6253\u5f00\u6216\u5173\u95ed WiFi\u3002

    toggleWifiState(enabled=None)\n

    \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

    \u8fd4\u56de\uff1a \u5982\u679c\u64cd\u4f5c\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/connectivity/wifi/#wifistartscan","title":"wifiStartScan()","text":"

    \u5f00\u59cb\u626b\u63cf\u53ef\u7528\u7684 WiFi \u7f51\u7edc\u3002

    wifiStartScan()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifigetscanresults","title":"wifiGetScanResults()","text":"

    \u83b7\u53d6\u53d1\u73b0\u7684 WiFi \u7f51\u7edc\u5217\u8868\u3002

    wifiGetScanResults()\n

    \u8fd4\u56de\uff1a \u63a5\u5165\u70b9\u4fe1\u606f\u5217\u8868

    "},{"location":"qsl4a/connectivity/wifi/#_2","title":"\u8fde\u63a5\u7ba1\u7406","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetconnectioninfo","title":"wifiGetConnectionInfo()","text":"

    \u83b7\u53d6\u8be6\u7ec6\u8fde\u63a5\u4fe1\u606f\u3002

    wifiGetConnectionInfo()\n

    \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001IP \u5730\u5740\u7b49\u8fde\u63a5\u8be6\u60c5\u7684\u5b57\u5178

    "},{"location":"qsl4a/connectivity/wifi/#getconnectedinfo","title":"getConnectedInfo()","text":"

    \u83b7\u53d6\u8fde\u63a5\u7684 WiFi \u7f51\u7edc\u4fe1\u606f\uff08\u7b80\u5316\u7248\uff09\u3002

    getConnectedInfo()\n

    \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001\u4fe1\u53f7\u5f3a\u5ea6\u7684\u5b57\u5178

    "},{"location":"qsl4a/connectivity/wifi/#getdhcpinfo","title":"getDhcpInfo()","text":"

    \u83b7\u53d6\u5f53\u524d\u8fde\u63a5\u7684 DHCP \u4fe1\u606f\u3002

    getDhcpInfo(ipConvertToString=True)\n

    \u53c2\u6570\uff1a - ipConvertToString (bool): \u5c06 IP \u5730\u5740\u8f6c\u6362\u4e3a\u5b57\u7b26\u4e32\u683c\u5f0f\uff08\u9ed8\u8ba4\uff1aTrue\uff09

    \u8fd4\u56de\uff1a \u5305\u542b IP\u3001\u7f51\u5173\u3001DNS \u7b49 DHCP \u4fe1\u606f\u7684\u5b57\u5178

    "},{"location":"qsl4a/connectivity/wifi/#wifidisconnect","title":"wifiDisconnect()","text":"

    \u65ad\u5f00\u5f53\u524d WiFi \u7f51\u7edc\u8fde\u63a5\u3002

    wifiDisconnect()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifireconnect","title":"wifiReconnect()","text":"

    \u91cd\u65b0\u8fde\u63a5\u5230\u5f53\u524d\u7f51\u7edc\u3002

    wifiReconnect()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifireassociate","title":"wifiReassociate()","text":"

    \u91cd\u65b0\u5173\u8054\u5f53\u524d\u63a5\u5165\u70b9\u3002

    wifiReassociate()\n
    "},{"location":"qsl4a/connectivity/wifi/#_3","title":"\u70ed\u70b9","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetapstate","title":"wifiGetApState()","text":"

    \u83b7\u53d6 WiFi AP\uff08\u70ed\u70b9\uff09\u72b6\u6001\u3002

    wifiGetApState()\n

    \u8fd4\u56de\uff1a \u70ed\u70b9\u72b6\u6001

    "},{"location":"qsl4a/connectivity/wifi/#wifi","title":"WiFi \u9501","text":""},{"location":"qsl4a/connectivity/wifi/#wifilockacquirefull","title":"wifiLockAcquireFull()","text":"

    \u83b7\u53d6\u5b8c\u6574 WiFi \u9501\uff08\u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\u4e5f\u4fdd\u6301 WiFi \u6d3b\u52a8\uff09\u3002

    wifiLockAcquireFull()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifilockacquirescanonly","title":"wifiLockAcquireScanOnly()","text":"

    \u83b7\u53d6\u4ec5\u626b\u63cf WiFi \u9501\u3002

    wifiLockAcquireScanOnly()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifilockrelease","title":"wifiLockRelease()","text":"

    \u91ca\u653e WiFi \u9501\u3002

    wifiLockRelease()\n
    "},{"location":"qsl4a/connectivity/wifi/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u68c0\u67e5 WiFi \u72b6\u6001\nif droid.checkWifiState().result:\n    print(\"WiFi is enabled\")\nelse:\n    print(\"Enabling WiFi...\")\n    droid.toggleWifiState(True)\n    time.sleep(2)\n\n# \u5f00\u59cb\u626b\u63cf\ndroid.wifiStartScan()\ntime.sleep(3)\n\n# \u83b7\u53d6\u626b\u63cf\u7ed3\u679c\nnetworks = droid.wifiGetScanResults().result\nfor network in networks:\n    print(f\"SSID: {network.get('SSID')}, Signal: {network.get('level')} dBm\")\n\n# \u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\ninfo = droid.wifiGetConnectionInfo().result\nif info:\n    print(f\"Connected to: {info.get('ssid')}\")\n    print(f\"BSSID: {info.get('bssid')}\")\n    print(f\"IP: {info.get('ip_address')}\")\n\n# \u83b7\u53d6 DHCP \u4fe1\u606f\ndhcp = droid.getDhcpInfo().result\nif dhcp:\n    print(f\"Gateway: {dhcp.get('gateway')}\")\n    print(f\"DNS: {dhcp.get('dns1')}\")\n\n# \u83b7\u53d6\u7b80\u5316\u7684\u8fde\u63a5\u4fe1\u606f\nconnected = droid.getConnectedInfo().result\nprint(f\"SSID: {connected.get('ssid')}, Signal: {connected.get('level')} dBm\")\n\n# \u65ad\u5f00\u5e76\u91cd\u65b0\u8fde\u63a5\ndroid.wifiDisconnect()\ntime.sleep(1)\ndroid.wifiReconnect()\n\n# \u91cd\u65b0\u5173\u8054\u63a5\u5165\u70b9\ndroid.wifiReassociate()\n\n# \u68c0\u67e5\u70ed\u70b9\u72b6\u6001\nap_state = droid.wifiGetApState().result\nprint(f\"Hotspot state: {ap_state}\")\n\n# \u83b7\u53d6 WiFi \u9501\u4ee5\u8fdb\u884c\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireFull()\n# ... \u6267\u884c\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n\n# \u6216\u4f7f\u7528\u4ec5\u626b\u63cf\u9501\u4ee5\u8fdb\u884c\u8f83\u8f7b\u7684\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireScanOnly()\n# ... \u6267\u884c\u626b\u63cf\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n
    "},{"location":"qsl4a/core/android-base/","title":"Android \u57fa\u7840\u7c7b","text":"

    Android \u7c7b\u662f QSL4A \u7684\u6838\u5fc3\uff0c\u63d0\u4f9b\u4e86\u4e0e Android \u8fd0\u884c\u65f6\u7684\u8fde\u63a5\u548c RPC \u673a\u5236\u3002

    "},{"location":"qsl4a/core/android-base/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
    # \u529f\u80fd\u5b8c\u6574\u7248\u672c\uff08\u63a8\u8350\uff09\nimport androidhelper\ndroid = androidhelper.Android()\n\n# \u7b80\u5316\u7248\u672c\uff08\u5feb\u901f\uff0c\u5355\u5b9e\u4f8b\uff09\nimport android\ndroid = android.droid\n
    "},{"location":"qsl4a/core/android-base/#android_1","title":"\u7c7b\uff1aAndroid","text":""},{"location":"qsl4a/core/android-base/#_2","title":"\u6784\u9020\u51fd\u6570","text":"
    Android(addr=None)\n

    \u53c2\u6570\uff1a - addr (tuple, optional): (HOST, PORT) \u5730\u5740\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u73af\u5883\u53d8\u91cf AP_HOST \u548c AP_PORT

    \u73af\u5883\u53d8\u91cf\uff1a - AP_HOST - \u670d\u52a1\u5668\u4e3b\u673a\u5730\u5740 - AP_PORT - \u670d\u52a1\u5668\u7aef\u53e3 - AP_HANDSHAKE - \u8ba4\u8bc1\u4ee4\u724c

    "},{"location":"qsl4a/core/android-base/#_3","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/android-base/#_rpc","title":"_rpc()","text":"

    \u8c03\u7528 Android \u51fd\u6570\u7684\u5185\u90e8 RPC \u65b9\u6cd5\u3002

    _rpc(method, *args)\n

    \u53c2\u6570\uff1a - method (str): \u8981\u8c03\u7528\u7684\u65b9\u6cd5\u540d - *args: \u65b9\u6cd5\u7684\u53ef\u53d8\u53c2\u6570

    \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4\uff0c\u5305\u542b\u4ee5\u4e0b\u5b57\u6bb5\uff1a - id (int): \u8bf7\u6c42 ID - result: \u65b9\u6cd5\u8fd4\u56de\u503c - error (str or None): \u9519\u8bef\u4fe1\u606f\uff08\u5982\u679c\u5931\u8d25\uff09

    "},{"location":"qsl4a/core/android-base/#getattr","title":"getattr()","text":"

    \u52a8\u6001\u65b9\u6cd5\u5206\u53d1\u5668\u3002\u6240\u6709 Android \u65b9\u6cd5\u90fd\u901a\u8fc7\u5c5e\u6027\u67e5\u627e\u8bbf\u95ee\u3002

    # \u4ee5\u4e0b\u4e24\u79cd\u65b9\u5f0f\u7b49\u4ef7\uff1a\ndroid.makeToast(\"Hello\")\ndroid._rpc(\"makeToast\", \"Hello\")\n
    "},{"location":"qsl4a/core/android-base/#androidpy","title":"\u72ec\u7acb\u51fd\u6570\uff08android.py\uff09","text":"

    \u4f7f\u7528\u7b80\u5316\u7684 android \u6a21\u5757\u65f6\uff1a

    "},{"location":"qsl4a/core/android-base/#jsla","title":"jsla()","text":"

    \u53d1\u9001 JSON-RPC \u8bf7\u6c42\u5e76\u8fd4\u56de\u539f\u59cb\u54cd\u5e94\u3002

    jsla(method, *params)\n

    \u8fd4\u56de\uff1a JSON \u5b57\u7b26\u4e32\u54cd\u5e94

    "},{"location":"qsl4a/core/android-base/#rsla","title":"rsla()","text":"

    \u53d1\u9001\u8bf7\u6c42\u5e76\u4ec5\u8fd4\u56de\u7ed3\u679c\u3002

    rsla(method, *params)\n

    \u8fd4\u56de\uff1a RPC \u8c03\u7528\u7684\u7ed3\u679c\u503c

    "},{"location":"qsl4a/core/android-base/#esla","title":"esla()","text":"

    \u53d1\u9001\u8bf7\u6c42\uff0c\u9519\u8bef\u65f6\u629b\u51fa\u5f02\u5e38\u3002

    esla(method, *params)\n

    \u629b\u51fa\uff1a \u5982\u679c error \u5b57\u6bb5\u4e0d\u4e3a None \u5219\u629b\u51fa\u5f02\u5e38

    "},{"location":"qsl4a/core/android-base/#nsla","title":"nsla()","text":"

    \u53d1\u9001\u8bf7\u6c42\u5e76\u8fd4\u56de Result \u547d\u540d\u5143\u7ec4\u3002

    nsla(method, *params)\n

    \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4

    "},{"location":"qsl4a/core/android-base/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/android-base/#_5","title":"\u57fa\u672c\u8fde\u63a5","text":"
    import androidhelper\n\n# \u8fde\u63a5\u5230 Android \u8fd0\u884c\u65f6\ndroid = androidhelper.Android()\n\n# \u901a\u8fc7\u663e\u793a toast \u6765\u68c0\u67e5\u8fde\u63a5\ndroid.makeToast(\"Connected!\")\n
    "},{"location":"qsl4a/core/android-base/#_6","title":"\u9519\u8bef\u5904\u7406","text":"
    result = droid.someMethod()\nif result.error:\n    print(f\"Error: {result.error}\")\nelse:\n    print(f\"Success: {result.result}\")\n
    "},{"location":"qsl4a/core/android-base/#rpc","title":"\u76f4\u63a5 RPC \u8c03\u7528","text":"
    # \u76f4\u63a5\u8c03\u7528\u4efb\u610f\u65b9\u6cd5\nresult = droid._rpc(\"makeToast\", \"Hello World\")\n
    "},{"location":"qsl4a/core/events/","title":"\u4e8b\u4ef6\u7cfb\u7edf","text":"

    QSL4A \u63d0\u4f9b\u4e86\u4e00\u4e2a\u4e8b\u4ef6\u7cfb\u7edf\uff0c\u7528\u4e8e\u5904\u7406\u6765\u81ea Android \u7684\u5f02\u6b65\u4e8b\u4ef6\uff0c\u5982\u4f20\u611f\u5668\u66f4\u65b0\u3001\u4f4d\u7f6e\u53d8\u5316\u548c\u81ea\u5b9a\u4e49\u5e7f\u64ad\u3002

    "},{"location":"qsl4a/core/events/#_2","title":"\u4e8b\u4ef6\u57fa\u7840","text":"

    \u4e8b\u4ef6\u5b58\u50a8\u5728\u7f13\u51b2\u533a\u4e2d\uff0c\u53ef\u4ee5\u8f6e\u8be2\u6216\u7b49\u5f85\u3002\u6bcf\u4e2a\u4e8b\u4ef6\u5305\u542b\uff1a - name: \u4e8b\u4ef6\u7c7b\u578b/\u540d\u79f0 - data: \u4e8b\u4ef6\u8d1f\u8f7d\u6570\u636e - time: \u65f6\u95f4\u6233

    "},{"location":"qsl4a/core/events/#_3","title":"\u4e8b\u4ef6\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#eventclearbuffer","title":"eventClearBuffer()","text":"

    \u6e05\u9664\u7f13\u51b2\u533a\u4e2d\u7684\u6240\u6709\u5f85\u5904\u7406\u4e8b\u4ef6\u3002

    eventClearBuffer()\n

    \u8fd4\u56de\uff1a None

    "},{"location":"qsl4a/core/events/#eventpoll","title":"eventPoll()","text":"

    \u8f6e\u8be2\u7f13\u51b2\u533a\u4e2d\u7684\u4e8b\u4ef6\u3002

    eventPoll(number_of_events=1)\n

    \u53c2\u6570\uff1a - number_of_events (int): \u8981\u68c0\u7d22\u7684\u6700\u5927\u4e8b\u4ef6\u6570\uff08\u9ed8\u8ba4\uff1a1\uff09

    \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\u5217\u8868

    "},{"location":"qsl4a/core/events/#eventwait","title":"eventWait()","text":"

    \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\u3002

    eventWait(timeout=None)\n

    \u53c2\u6570\uff1a - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09\u3002None = \u6c38\u4e45\u7b49\u5f85

    \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

    "},{"location":"qsl4a/core/events/#eventwaitfor","title":"eventWaitFor()","text":"

    \u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6\u3002

    eventWaitFor(eventName, timeout=None)\n

    \u53c2\u6570\uff1a - eventName (str): \u8981\u7b49\u5f85\u7684\u4e8b\u4ef6\u540d\u79f0 - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

    \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

    "},{"location":"qsl4a/core/events/#eventpost","title":"eventPost()","text":"

    \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\u3002

    eventPost(name, data, enqueue=None)\n

    \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e\uff08\u4efb\u610f\u7c7b\u578b\uff09 - enqueue (bool, optional): \u5982\u679c\u4e3a True \u5219\u6dfb\u52a0\u5230\u961f\u5217

    "},{"location":"qsl4a/core/events/#receiveevent","title":"receiveEvent()","text":"

    \u63a5\u6536\u4e8b\u4ef6\uff08\u963b\u585e\uff09\u3002

    receiveEvent()\n

    \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61

    "},{"location":"qsl4a/core/events/#_4","title":"\u5e7f\u64ad\u4e8b\u4ef6","text":"

    \u6ce8\u518c\u7cfb\u7edf\u5e7f\u64ad\u4e8b\u4ef6\u3002

    "},{"location":"qsl4a/core/events/#eventregisterforbroadcast","title":"eventRegisterForBroadcast()","text":"

    \u6ce8\u518c\u63a5\u6536\u5e7f\u64ad\u4e8b\u4ef6\u3002

    eventRegisterForBroadcast(category, enqueue=True)\n

    \u53c2\u6570\uff1a - category (str): \u5e7f\u64ad\u7c7b\u522b/\u52a8\u4f5c - enqueue (bool): \u6dfb\u52a0\u5230\u4e8b\u4ef6\u961f\u5217

    "},{"location":"qsl4a/core/events/#eventunregisterforbroadcast","title":"eventUnregisterForBroadcast()","text":"

    \u53d6\u6d88\u6ce8\u518c\u5e7f\u64ad\u4e8b\u4ef6\u3002

    eventUnregisterForBroadcast(category)\n
    "},{"location":"qsl4a/core/events/#eventgetbrodcastcategories","title":"eventGetBrodcastCategories()","text":"

    \u83b7\u53d6\u5df2\u6ce8\u518c\u7684\u5e7f\u64ad\u7c7b\u522b\u3002

    eventGetBrodcastCategories()\n

    \u8fd4\u56de\uff1a \u5df2\u6ce8\u518c\u7c7b\u522b\u5217\u8868

    "},{"location":"qsl4a/core/events/#_5","title":"\u4e8b\u4ef6\u5206\u53d1\u5668)","text":""},{"location":"qsl4a/core/events/#starteventdispatcher","title":"startEventDispatcher()","text":"

    \u6253\u5f00\u4e00\u4e2a\u53ef\u4ee5\u8bfb\u53d6\u5df2\u53d1\u5e03\u4e8b\u4ef6\u7684\u5957\u63a5\u5b57\u3002)

    startEventDispatcher(port=0)\n

    \u53c2\u6570\uff1a - port (int, optional): \u76d1\u542c\u7684\u7aef\u53e3\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\u9009\u62e9\uff09

    \u8fd4\u56de\uff1a \u6b63\u5728\u76d1\u542c\u7684\u7aef\u53e3\u53f7

    "},{"location":"qsl4a/core/events/#stopeventdispatcher","title":"stopEventDispatcher()","text":"

    \u505c\u6b62\u4e8b\u4ef6\u670d\u52a1\u5668\u3002)

    stopEventDispatcher()\n
    "},{"location":"qsl4a/core/events/#_6","title":"\u5df2\u5e9f\u5f03\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#rpcpostevent","title":"rpcPostEvent()","text":"

    \u5c06\u4e8b\u4ef6\u53d1\u5e03\u5230\u4e8b\u4ef6\u961f\u5217\u3002\uff08\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 eventPost\uff09

    rpcPostEvent(name, data)\n

    \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e

    "},{"location":"qsl4a/core/events/#_7","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/events/#_8","title":"\u57fa\u672c\u4e8b\u4ef6\u8f6e\u8be2","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6e05\u9664\u65e7\u4e8b\u4ef6\ndroid.eventClearBuffer()\n\n# \u8f6e\u8be2\u4e8b\u4ef6\nevents = droid.eventPoll(5).result\nfor event in events:\n    print(f\"Event: {event['name']}, Data: {event['data']}\")\n
    "},{"location":"qsl4a/core/events/#_9","title":"\u7b49\u5f85\u4e8b\u4ef6","text":"
    # \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\uff0c\u5e26\u8d85\u65f6\nevent = droid.eventWait(timeout=10).result\nif event:\n    print(f\"Got event: {event['name']}\")\n
    "},{"location":"qsl4a/core/events/#_10","title":"\u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6","text":"
    # \u7b49\u5f85\u4f20\u611f\u5668\u4e8b\u4ef6\nevent = droid.eventWaitFor('screen', timeout=5).result\nif event:\n    print(f\"Screen event: {event['data']}\")\n
    "},{"location":"qsl4a/core/events/#_11","title":"\u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6","text":"
    # \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\ndroid.eventPost('my_event', {'key': 'value'})\n\n# \u7b49\u5f85\u5b83\nevent = droid.eventWaitFor('my_event', timeout=1).result\n
    "},{"location":"qsl4a/core/events/#_12","title":"\u5e7f\u64ad\u63a5\u6536\u5668","text":"
    # \u6ce8\u518c\u5c4f\u5e55\u5f00\u5173\u4e8b\u4ef6\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_ON')\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_OFF')\n\n# \u7b49\u5f85\u5c4f\u5e55\u4e8b\u4ef6\nwhile True:\n    event = droid.receiveEvent().result\n    if event['name'] == 'android.intent.action.SCREEN_ON':\n        print(\"Screen turned on\")\n    elif event['name'] == 'android.intent.action.SCREEN_OFF':\n        print(\"Screen turned off\")\n
    "},{"location":"qsl4a/core/events/#_13","title":"\u4f20\u611f\u5668\u4e8b\u4ef6\u5904\u7406","text":"
    # \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u5904\u7406\u4f20\u611f\u5668\u4e8b\u4ef6\nfor _ in range(100):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'sensors':\n        data = event['data']\n        print(f\"Accel: {data['xforce']}, {data['yforce']}, {data['zforce']}\")\n\ndroid.stopSensing()\n
    "},{"location":"qsl4a/core/events/#_14","title":"\u5e38\u89c1\u4e8b\u4ef6\u7c7b\u578b","text":"\u4e8b\u4ef6\u540d\u79f0 \u63cf\u8ff0 \u6765\u6e90 sensors \u4f20\u611f\u5668\u6570\u636e\u66f4\u65b0 startSensing* location GPS \u4f4d\u7f6e\u66f4\u65b0 startLocating phone \u7535\u8bdd\u72b6\u6001\u53d8\u5316 startTrackingPhoneState signal \u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316 startTrackingSignalStrength screen \u622a\u56fe\u5c31\u7eea fullGetScreenShot dialog \u5bf9\u8bdd\u6846\u54cd\u5e94 dialogShow*"},{"location":"qsl4a/core/events/#_15","title":"\u4e8b\u4ef6\u6570\u636e\u7ed3\u6784","text":"
    {\n    'name': 'event_name',\n    'data': {\n        # \u4e8b\u4ef6\u7279\u5b9a\u6570\u636e\n    },\n    'time': 1234567890  # \u65f6\u95f4\u6233\n}\n
    "},{"location":"qsl4a/core/intent/","title":"Intent \u7cfb\u7edf","text":"

    Android Intent \u7528\u4e8e\u542f\u52a8\u6d3b\u52a8\u3001\u53d1\u9001\u5e7f\u64ad\u548c\u5e94\u7528\u95f4\u901a\u4fe1\u3002QSL4A \u901a\u8fc7 Intent \u6a21\u5757\u63d0\u4f9b\u5b8c\u6574\u7684 Intent \u652f\u6301\u3002

    "},{"location":"qsl4a/core/intent/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
    import androidhelper\ndon = androidhelper.Android()\n
    "},{"location":"qsl4a/core/intent/#intent_1","title":"Intent \u5e38\u91cf","text":"

    \u901a\u8fc7 droid.Intent \u8bbf\u95ee\uff1a

    "},{"location":"qsl4a/core/intent/#_2","title":"\u64cd\u4f5c","text":"\u5e38\u91cf \u503c \u7528\u9014 ACTION_MAIN android.intent.action.MAIN \u5e94\u7528\u5165\u53e3\u70b9 ACTION_VIEW android.intent.action.VIEW \u67e5\u770b\u5185\u5bb9 ACTION_EDIT android.intent.action.EDIT \u7f16\u8f91\u5185\u5bb9 ACTION_PICK android.intent.action.PICK \u9009\u62e9\u9879\u76ee ACTION_SEND android.intent.action.SEND \u5206\u4eab\u5185\u5bb9 ACTION_SEARCH android.intent.action.SEARCH \u641c\u7d22"},{"location":"qsl4a/core/intent/#_3","title":"\u6807\u5fd7","text":"\u5e38\u91cf \u503c \u7528\u9014 FLAG_ACTIVITY_NEW_TASK 268435456 \u542f\u52a8\u65b0\u4efb\u52a1 FLAG_ACTIVITY_CLEAR_TASK 32768 \u6e05\u9664\u4efb\u52a1\u5806\u6808 FLAG_ACTIVITY_NEW_DOCUMENT 524288 \u65b0\u6587\u6863\u6a21\u5f0f"},{"location":"qsl4a/core/intent/#_4","title":"\u9644\u52a0\u6570\u636e","text":"\u5e38\u91cf \u7528\u9014 EXTRA_TEXT \u6587\u672c\u5185\u5bb9 EXTRA_STREAM \u6587\u4ef6 URI EXTRA_SUBJECT \u4e3b\u9898\u884c EXTRA_EMAIL \u7535\u5b50\u90ae\u4ef6\u5730\u5740"},{"location":"qsl4a/core/intent/#_5","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/intent/#makeintent","title":"makeIntent()","text":"

    \u521b\u5efa Intent \u5bf9\u8c61\u3002

    makeIntent(action, uri=None, type=None, extras=None, categories=None,\n           packagename=None, classname=None, flags=None)\n

    \u53c2\u6570\uff1a - action (str): Intent \u64cd\u4f5c\uff08\u4f8b\u5982 droid.Intent.ACTION_VIEW\uff09 - uri (str, optional): \u6570\u636e URI - type (str, optional): MIME \u7c7b\u578b - extras (dict, optional): \u9644\u52a0\u6570\u636e - categories (list, optional): Intent \u7c7b\u522b - packagename (str, optional): \u76ee\u6807\u5305 - classname (str, optional): \u76ee\u6807\u7c7b - flags (int, optional): Intent \u6807\u5fd7

    \u8fd4\u56de\uff1a Intent \u5bf9\u8c61

    "},{"location":"qsl4a/core/intent/#startactivityintent","title":"startActivityIntent()","text":"

    \u4f7f\u7528 Intent \u542f\u52a8 Activity\u3002

    startActivityIntent(intent, wait=None)\n

    \u53c2\u6570\uff1a - intent: makeIntent() \u8fd4\u56de\u7684 Intent \u5bf9\u8c61 - wait (bool, optional): \u963b\u585e\u76f4\u5230\u6d3b\u52a8\u5173\u95ed

    "},{"location":"qsl4a/core/intent/#startactivityforresultintent","title":"startActivityForResultIntent()","text":"

    \u542f\u52a8\u6d3b\u52a8\u5e76\u7b49\u5f85\u7ed3\u679c\u3002

    startActivityForResultIntent(intent)\n

    \u8fd4\u56de\uff1a Activity \u7ed3\u679c

    "},{"location":"qsl4a/core/intent/#sendbroadcastintent","title":"sendBroadcastIntent()","text":"

    \u53d1\u9001\u5e7f\u64ad\u3002

    sendBroadcastIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#view","title":"view()","text":"

    \u901a\u8fc7 URI \u67e5\u770b\u5185\u5bb9\u3002

    view(uri, type=None, extras=None)\n
    "},{"location":"qsl4a/core/intent/#pick","title":"pick()","text":"

    \u4ece URI \u9009\u62e9\u5185\u5bb9\u3002

    pick(uri)\n
    "},{"location":"qsl4a/core/intent/#intent_2","title":"\u5e38\u89c1 Intent \u65b9\u6cd5)","text":""},{"location":"qsl4a/core/intent/#scanbarcode","title":"scanBarcode()","text":"

    \u542f\u52a8\u6761\u7801\u626b\u63cf\u5668\u3002

    scanBarcode()\n

    \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/core/intent/#send","title":"send()","text":"

    \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u5185\u5bb9\u3002

    send(type, content)\n

    \u53c2\u6570\uff1a - type (str): MIME \u7c7b\u578b - content (str): \u8981\u5206\u4eab\u7684\u5185\u5bb9

    "},{"location":"qsl4a/core/intent/#sendtext","title":"sendText()","text":"

    \u53d1\u9001\u6587\u672c\u5185\u5bb9\u3002

    sendText(text)\n

    \u53c2\u6570\uff1a - text (str): \u8981\u53d1\u9001\u7684\u6587\u672c

    "},{"location":"qsl4a/core/intent/#sendemail","title":"sendEmail()","text":"

    \u53d1\u9001\u7535\u5b50\u90ae\u4ef6\u3002

    sendEmail(to, subject, body, attachment=None)\n

    \u53c2\u6570\uff1a - to (str or list): \u6536\u4ef6\u4eba\u7535\u5b50\u90ae\u4ef6\u5730\u5740 - subject (str): \u7535\u5b50\u90ae\u4ef6\u4e3b\u9898 - body (str): \u7535\u5b50\u90ae\u4ef6\u6b63\u6587 - attachment (str, optional): \u9644\u4ef6\u6587\u4ef6\u8def\u5f84

    "},{"location":"qsl4a/core/intent/#pathtouri","title":"pathToUri()","text":"

    \u5c06\u6587\u4ef6\u8def\u5f84\u8f6c\u6362\u4e3a\u5185\u5bb9 URI\u3002

    pathToUri(path)\n

    \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

    \u8fd4\u56de\uff1a \u5185\u5bb9 URI \u5b57\u7b26\u4e32

    "},{"location":"qsl4a/core/intent/#openfile","title":"openFile()","text":"

    \u7528\u9002\u5f53\u7684\u5e94\u7528\u7a0b\u5e8f\u6253\u5f00\u6587\u4ef6\u3002

    openFile(path)\n

    \u53c2\u6570\uff1a - path (str): \u8981\u6253\u5f00\u7684\u6587\u4ef6\u8def\u5f84

    "},{"location":"qsl4a/core/intent/#sendfile","title":"sendFile()","text":"

    \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u6587\u4ef6\u3002

    sendFile(path)\n

    \u53c2\u6570\uff1a - path (str): \u8981\u53d1\u9001\u7684\u6587\u4ef6\u8def\u5f84

    "},{"location":"qsl4a/core/intent/#getpathtype","title":"getPathType()","text":"

    \u83b7\u53d6\u6587\u4ef6\u8def\u5f84\u7684 MIME \u7c7b\u578b\u3002

    getPathType(path)\n

    \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

    \u8fd4\u56de\uff1a MIME \u7c7b\u578b\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/core/intent/#viewmap","title":"viewMap()","text":"

    \u5728\u6307\u5b9a\u4f4d\u7f6e\u6253\u5f00\u5730\u56fe\u3002

    viewMap(latitude, longitude)\n

    \u53c2\u6570\uff1a - latitude (float): \u7eac\u5ea6 - longitude (float): \u7ecf\u5ea6

    "},{"location":"qsl4a/core/intent/#viewcontacts","title":"viewContacts()","text":"

    \u6253\u5f00\u8054\u7cfb\u4eba\u5e94\u7528\u3002

    viewContacts()\n
    "},{"location":"qsl4a/core/intent/#search","title":"search()","text":"

    \u6267\u884c\u7f51\u7edc\u641c\u7d22\u3002

    search(query)\n

    \u53c2\u6570\uff1a - query (str): \u641c\u7d22\u67e5\u8be2

    "},{"location":"qsl4a/core/intent/#viewhtml","title":"viewHtml()","text":"

    \u67e5\u770b HTML \u5185\u5bb9\u3002

    viewHtml(content, encoding=None)\n

    \u53c2\u6570\uff1a - content (str): HTML \u5185\u5bb9 - encoding (str, optional): \u5b57\u7b26\u7f16\u7801

    "},{"location":"qsl4a/core/intent/#webviewshow","title":"webViewShow()","text":"

    \u5728 WebView \u4e2d\u663e\u793a\u7f51\u9875\u5185\u5bb9\u3002\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 viewHtml\u3002

    webViewShow(url)\n

    \u53c2\u6570\uff1a - url (str): \u7f51\u9875 URL

    "},{"location":"qsl4a/core/intent/#editoropen","title":"editorOpen()","text":"

    \u6253\u5f00\u6587\u672c\u7f16\u8f91\u5668\u3002

    editorOpen(path=None, create=False)\n

    \u53c2\u6570\uff1a - path (str, optional): \u8981\u7f16\u8f91\u7684\u6587\u4ef6\u8def\u5f84 - create (bool, optional): \u5982\u679c\u4e0d\u5b58\u5728\u5219\u521b\u5efa

    "},{"location":"qsl4a/core/intent/#uri","title":"\u8f85\u52a9\u7c7b\uff1aUri","text":"

    \u521b\u5efa Intent \u7684 URI \u5bf9\u8c61\uff1a

    from androidhelper.Intent import Uri\n\nuri = Uri(\"file:///sdcard/test.txt\")\n
    "},{"location":"qsl4a/core/intent/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/intent/#_7","title":"\u6253\u5f00\u7f51\u9875","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"http://www.example.com\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#_8","title":"\u5206\u4eab\u6587\u672c","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_TEXT: \"Hello from QPython!\",\n        droid.Intent.EXTRA_SUBJECT: \"Test\"\n    },\n    type=\"text/plain\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#_9","title":"\u6253\u5f00\u6587\u4ef6","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"file:///sdcard/document.pdf\",\n    type=\"application/pdf\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#_10","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":"
    result = droid.pickContact()\ncontact_uri = result.result\n
    "},{"location":"qsl4a/core/intent/#_11","title":"\u53d1\u9001\u7535\u5b50\u90ae\u4ef6","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_EMAIL: [\"test@example.com\"],\n        droid.Intent.EXTRA_SUBJECT: \"Hello\",\n        droid.Intent.EXTRA_TEXT: \"Message body\"\n    },\n    type=\"message/rfc822\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#_12","title":"\u6253\u5f00\u5e94\u7528","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_MAIN,\n    packagename=\"com.android.settings\",\n    classname=\"com.android.settings.Settings\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/hardware/bluetooth/","title":"\u84dd\u7259 API","text":"

    \u63a7\u5236\u84dd\u7259\u9002\u914d\u5668\u5e76\u4e0e\u84dd\u7259\u8bbe\u5907\u901a\u4fe1\u3002

    "},{"location":"qsl4a/hardware/bluetooth/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/hardware/bluetooth/#togglebluetoothstate","title":"toggleBluetoothState()","text":"

    \u6253\u5f00/\u5173\u95ed\u84dd\u7259\u3002

    toggleBluetoothState(enabled=None, prompt=True)\n

    \u53c2\u6570\uff1a - enabled (bool): True=\u5f00\uff0cFalse=\u5173\uff0cNone=\u5207\u6362 - prompt (bool): \u663e\u793a\u7528\u6237\u63d0\u793a

    "},{"location":"qsl4a/hardware/bluetooth/#checkbluetoothstate","title":"checkBluetoothState()","text":"

    \u68c0\u67e5\u84dd\u7259\u662f\u5426\u5df2\u542f\u7528\u3002

    checkBluetoothState()\n

    \u8fd4\u56de\uff1a True/False

    "},{"location":"qsl4a/hardware/bluetooth/#getlocalname","title":"GetLocalName()","text":"

    \u83b7\u53d6\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

    GetLocalName()\n
    "},{"location":"qsl4a/hardware/bluetooth/#setlocalname","title":"SetLocalName()","text":"

    \u8bbe\u7f6e\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

    SetLocalName(name)\n
    "},{"location":"qsl4a/hardware/bluetooth/#getscanmode","title":"GetScanMode()","text":"

    \u83b7\u53d6\u53ef\u53d1\u73b0\u6027\u6a21\u5f0f\u3002

    GetScanMode()\n

    \u8fd4\u56de\uff1a - -1: \u5df2\u7981\u7528 - 0: \u4e0d\u53ef\u53d1\u73b0\uff0c\u4e0d\u53ef\u8fde\u63a5 - 1: \u53ef\u8fde\u63a5\uff0c\u4e0d\u53ef\u53d1\u73b0 - 3: \u53ef\u8fde\u63a5\u4e14\u53ef\u53d1\u73b0

    "},{"location":"qsl4a/hardware/bluetooth/#makediscoverable","title":"MakeDiscoverable()","text":"

    \u4f7f\u8bbe\u5907\u53ef\u53d1\u73b0\u3002

    MakeDiscoverable(duration=300)\n

    \u53c2\u6570\uff1a - duration (int): \u53ef\u53d1\u73b0\u7684\u79d2\u6570

    "},{"location":"qsl4a/hardware/bluetooth/#_2","title":"\u53d1\u73b0","text":""},{"location":"qsl4a/hardware/bluetooth/#discoverystart","title":"DiscoveryStart()","text":"

    \u5f00\u59cb\u8bbe\u5907\u53d1\u73b0\u3002

    DiscoveryStart()\n
    "},{"location":"qsl4a/hardware/bluetooth/#discoverycancel","title":"DiscoveryCancel()","text":"

    \u53d6\u6d88\u53d1\u73b0\u3002

    DiscoveryCancel()\n
    "},{"location":"qsl4a/hardware/bluetooth/#getreceiveddevices","title":"GetReceivedDevices()","text":"

    \u83b7\u53d6\u53d1\u73b0\u7684\u8bbe\u5907\u3002

    GetReceivedDevices()\n

    \u8fd4\u56de\uff1a \u8bbe\u5907\u4fe1\u606f\u5b57\u5178\u5217\u8868

    "},{"location":"qsl4a/hardware/bluetooth/#getbondeddevices","title":"GetBondedDevices()","text":"

    \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\u3002

    GetBondedDevices()\n

    \u8fd4\u56de\uff1a \u914d\u5bf9\u8bbe\u5907\u4fe1\u606f\u5217\u8868

    "},{"location":"qsl4a/hardware/bluetooth/#_3","title":"\u8fde\u63a5","text":""},{"location":"qsl4a/hardware/bluetooth/#connect","title":"Connect()","text":"

    \u8fde\u63a5\u5230\u8bbe\u5907\u3002

    Connect(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", address=None)\n

    \u53c2\u6570\uff1a - uuid (str): \u670d\u52a1 UUID - address (str): \u8bbe\u5907\u5730\u5740\uff08None = \u663e\u793a\u9009\u62e9\u5668\uff09

    \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/hardware/bluetooth/#accept","title":"Accept()","text":"

    \u63a5\u53d7\u4f20\u5165\u8fde\u63a5\u3002

    Accept(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", timeout=0)\n
    "},{"location":"qsl4a/hardware/bluetooth/#activeconnections","title":"ActiveConnections()","text":"

    \u68c0\u67e5\u6d3b\u52a8\u8fde\u63a5\u3002

    ActiveConnections()\n
    "},{"location":"qsl4a/hardware/bluetooth/#stop","title":"Stop()","text":"

    \u65ad\u5f00\u8fde\u63a5\u3002

    Stop(connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#_4","title":"\u901a\u4fe1","text":""},{"location":"qsl4a/hardware/bluetooth/#write","title":"Write()","text":"

    \u53d1\u9001 ASCII \u6570\u636e\u3002

    Write(ascii, connID=\"\")\n
    "},{"location":"qsl4a/hardware/bluetooth/#writebinary","title":"WriteBinary()","text":"

    \u53d1\u9001\u4e8c\u8fdb\u5236\u6570\u636e\uff08base64 \u7f16\u7801\uff09\u3002

    WriteBinary(base64, connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#read","title":"Read()","text":"

    \u8bfb\u53d6 ASCII \u6570\u636e\u3002

    Read(bufferSize=4096, connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#readbinary","title":"ReadBinary()","text":"

    \u8bfb\u53d6\u4e8c\u8fdb\u5236\u6570\u636e\u3002

    ReadBinary(bufferSize=4096, connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#readline","title":"ReadLine()","text":"

    \u8bfb\u53d6\u4e00\u884c\u3002

    ReadLine(connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#readready","title":"ReadReady()","text":"

    \u68c0\u67e5\u662f\u5426\u6709\u53ef\u7528\u6570\u636e\u3002

    ReadReady(connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u7528\u84dd\u7259\ndroid.toggleBluetoothState(True)\n\n# \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\ndevices = droid.GetBondedDevices().result\nfor dev in devices:\n    print(f\"{dev['name']}: {dev['address']}\")\n\n# \u8fde\u63a5\u5230\u8bbe\u5907\ndroid.Connect(address=\"00:11:22:33:44:55\")\n\n# \u53d1\u9001\u6570\u636e\ndroid.Write(\"Hello Bluetooth!\")\n\n# \u8bfb\u53d6\u54cd\u5e94\ndata = droid.Read(1024).result\n
    "},{"location":"qsl4a/hardware/camera/","title":"\u76f8\u673a API","text":"

    \u62cd\u6444\u7167\u7247\u548c\u5f55\u5236\u89c6\u9891\u3002

    "},{"location":"qsl4a/hardware/camera/#_1","title":"\u7167\u7247\u62cd\u6444","text":""},{"location":"qsl4a/hardware/camera/#takepicture","title":"takePicture()","text":"

    \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u6444\u7167\u7247\u3002

    takePicture(path=None)\n

    \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8fd4\u56de\u56fe\u50cf\u6570\u636e

    \u8fd4\u56de\uff1a \u56fe\u50cf\u8def\u5f84\u6216\u56fe\u50cf\u6570\u636e

    "},{"location":"qsl4a/hardware/camera/#cameracapturepicture","title":"cameraCapturePicture()","text":"

    \u4f7f\u7528\u9ad8\u7ea7\u76f8\u673a\u63a7\u5236\u62cd\u6444\u7167\u7247\u3002

    cameraCapturePicture(targetPath=None, cameraId=0, useAutoFocus=True)\n

    \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - useAutoFocus (bool): \u542f\u7528\u81ea\u52a8\u5bf9\u7126

    \u8fd4\u56de\uff1a \u62cd\u6444\u7684\u56fe\u50cf\u8def\u5f84

    "},{"location":"qsl4a/hardware/camera/#camerasettorchmode","title":"cameraSetTorchMode()","text":"

    \u63a7\u5236\u76f8\u673a\u95ea\u5149\u706f/\u624b\u7535\u7b52\u3002

    cameraSetTorchMode(enabled)\n

    \u53c2\u6570\uff1a - enabled (bool): True \u6253\u5f00\uff0cFalse \u5173\u95ed

    \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/hardware/camera/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

    \u622a\u56fe\u3002

    imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

    \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

    "},{"location":"qsl4a/hardware/camera/#_2","title":"\u89c6\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#takevideo","title":"takeVideo()","text":"

    \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\u3002

    takeVideo(path=None, quality=1)\n

    \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-4\uff09 - 0: 160x120 - 1: 320x240 - 2: 352x288 - 3: 640x480 - 4: 800x480

    "},{"location":"qsl4a/hardware/camera/#recordercapturevideo","title":"recorderCaptureVideo()","text":"

    \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\u3002

    recorderCaptureVideo(targetPath=None, duration=10, cameraId=0, quality=8)\n

    \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - duration (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a10\uff09 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-8\uff0c\u8d8a\u9ad8\u8d8a\u597d\uff09

    \u8fd4\u56de\uff1a \u89c6\u9891\u6587\u4ef6\u8def\u5f84

    "},{"location":"qsl4a/hardware/camera/#recordaudio","title":"recordAudio()","text":"

    \u5f55\u5236\u97f3\u9891\u3002

    recordAudio()\n

    \u8fd4\u56de\uff1a \u97f3\u9891\u6587\u4ef6\u8def\u5f84

    "},{"location":"qsl4a/hardware/camera/#_3","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

    \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\u3002

    recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

    \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\uff09 - targetPixels (int): \u5206\u8fa8\u7387 - frameRate (int): FPS - bitRate (int): \u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa - autoStart (bool): \u7acb\u5373\u5f00\u59cb

    "},{"location":"qsl4a/hardware/camera/#recorderstart","title":"recorderStart()","text":"

    \u5f00\u59cb\u5f55\u5236\u3002

    recorderStart()\n
    "},{"location":"qsl4a/hardware/camera/#recorderpause","title":"recorderPause()","text":"

    \u6682\u505c\u5f55\u5236\u3002

    recorderPause()\n
    "},{"location":"qsl4a/hardware/camera/#recorderresume","title":"recorderResume()","text":"

    \u6062\u590d\u5f55\u5236\u3002

    recorderResume()\n
    "},{"location":"qsl4a/hardware/camera/#_4","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/camera/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

    \u5f00\u59cb\u97f3\u91cf\u68c0\u6d4b\u3002

    recorderSoundVolumeDetect(interval=100)\n
    "},{"location":"qsl4a/hardware/camera/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

    \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

    recorderSoundVolumeGetDb()\n
    "},{"location":"qsl4a/hardware/camera/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u7167\nphoto_path = droid.takePicture(\"/sdcard/photo.jpg\").result\nprint(f\"Photo saved: {photo_path}\")\n\n# \u4f7f\u7528\u524d\u7f6e\u76f8\u673a\u548c\u81ea\u52a8\u5bf9\u7126\u62cd\u7167\ncamera_path = droid.cameraCapturePicture(\"/sdcard/selfie.jpg\", cameraId=1, useAutoFocus=True).result\nprint(f\"Front camera photo: {camera_path}\")\n\n# \u63a7\u5236\u95ea\u5149\u706f\ndroid.cameraSetTorchMode(True)  # \u6253\u5f00\u95ea\u5149\u706f\n\n# \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\nvideo_path = droid.takeVideo(\"/sdcard/video.mp4\", quality=3).result\nprint(f\"Video saved: {video_path}\")\n\n# \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\nvideo_path = droid.recorderCaptureVideo(\"/sdcard/movie.mp4\", duration=30, cameraId=0, quality=8).result\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n
    "},{"location":"qsl4a/hardware/recorder/","title":"\u97f3\u9891\u5f55\u5236 API","text":"

    \u4ece\u9ea6\u514b\u98ce\u548c\u8bbe\u5907\u5c4f\u5e55\u5f55\u5236\u97f3\u9891\u3002

    "},{"location":"qsl4a/hardware/recorder/#_1","title":"\u97f3\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recordaudio","title":"recordAudio()","text":"

    \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\u3002

    recordAudio()\n

    \u8fd4\u56de\uff1a \u5f55\u5236\u7684\u97f3\u9891\u6587\u4ef6\u8def\u5f84

    "},{"location":"qsl4a/hardware/recorder/#recorderstartmicrophone","title":"recorderStartMicrophone()","text":"

    \u5f00\u59cb\u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\u3002

    recorderStartMicrophone(targetPath=None)\n

    \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u5f55\u5236\u7684\u8def\u5f84

    "},{"location":"qsl4a/hardware/recorder/#_2","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

    \u5f00\u59cb\u5e26\u97f3\u9891\u7684\u5c4f\u5e55\u5f55\u5236\u3002

    recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

    \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\u97f3\u9891\uff09 - targetPixels (int): \u76ee\u6807\u5206\u8fa8\u7387\uff08\u50cf\u7d20\uff09 - frameRate (int): \u6bcf\u79d2\u5e27\u6570\uff08\u9ed8\u8ba4\uff1a30\uff09 - bitRate (int): \u89c6\u9891\u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa\u89c6\u9891 - autoStart (bool): \u7acb\u5373\u5f00\u59cb\u5f55\u5236

    \u8fd4\u56de\uff1a \u64cd\u4f5c\u7ed3\u679c

    "},{"location":"qsl4a/hardware/recorder/#recorderstart","title":"recorderStart()","text":"

    \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\uff08\u5f53 autoStart=False \u65f6\uff09\u3002

    recorderStart()\n
    "},{"location":"qsl4a/hardware/recorder/#recorderpause","title":"recorderPause()","text":"

    \u6682\u505c\u6b63\u5728\u8fdb\u884c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

    recorderPause()\n
    "},{"location":"qsl4a/hardware/recorder/#recorderresume","title":"recorderResume()","text":"

    \u6062\u590d\u6682\u505c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

    recorderResume()\n
    "},{"location":"qsl4a/hardware/recorder/#_3","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/recorder/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

    \u5f00\u59cb\u76d1\u63a7\u97f3\u91cf\u7ea7\u522b\u3002

    recorderSoundVolumeDetect(interval=100)\n

    \u53c2\u6570\uff1a - interval (int): \u68c0\u6d4b\u95f4\u9694\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a100\uff09

    "},{"location":"qsl4a/hardware/recorder/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

    \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

    recorderSoundVolumeGetDb()\n

    \u8fd4\u56de\uff1a \u5f53\u524d\u97f3\u91cf\u7ea7\u522b\uff08dB\uff09

    "},{"location":"qsl4a/hardware/recorder/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\nprint(\"Recording audio...\")\naudio_path = droid.recordAudio().result\nprint(f\"Saved to: {audio_path}\")\n\n# \u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\ndroid.recorderStartMicrophone(\"/sdcard/my_recording.mp3\")\ntime.sleep(5)\ndroid.recorderStop()\n\n# \u5e26\u97f3\u9891\u5f55\u5236\u5c4f\u5e55\nprint(\"Starting screen recording...\")\ndroid.recorderStartScreenRecord(\n    path=\"/sdcard/screen_record.mp4\",\n    audio=1,\n    frameRate=30,\n    autoStart=True\n)\ntime.sleep(10)\ndroid.recorderStop()\n\n# \u76d1\u63a7\u97f3\u91cf\ndroid.recorderSoundVolumeDetect(interval=100)\ntime.sleep(3)\nvolume = droid.recorderSoundVolumeGetDb().result\nprint(f\"Current volume: {volume} dB\")\n
    "},{"location":"qsl4a/hardware/usbserial/","title":"USB \u4e3b\u673a\u4e32\u884c API","text":"

    \u4e0e USB \u4e32\u884c\u8bbe\u5907\u901a\u4fe1\uff08\u9700\u8981 USB OTG \u652f\u6301\u548c Android 3.1+\uff09\u3002

    "},{"location":"qsl4a/hardware/usbserial/#usb","title":"USB \u4e32\u884c\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialopen","title":"usbHostSerialOpen()","text":"

    \u6253\u5f00\u4e0e USB \u4e32\u884c\u8bbe\u5907\u7684\u8fde\u63a5\u3002

    usbHostSerialOpen(device, baudRate=9600)\n

    \u53c2\u6570\uff1a - device (str): USB \u8bbe\u5907\u8def\u5f84\u6216\u6807\u8bc6\u7b26 - baudRate (int): \u6ce2\u7279\u7387\uff08\u9ed8\u8ba4\uff1a9600\uff09

    \u8fd4\u56de\uff1a \u5982\u679c\u6253\u5f00\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialclose","title":"usbHostSerialClose()","text":"

    \u5173\u95ed USB \u4e32\u884c\u8fde\u63a5\u3002

    usbHostSerialClose()\n
    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialread","title":"usbHostSerialRead()","text":"

    \u4ece USB \u4e32\u884c\u8bfb\u53d6\u6570\u636e\u3002

    usbHostSerialRead(bufferSize=1024)\n

    \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570\uff08\u9ed8\u8ba4\uff1a1024\uff09

    \u8fd4\u56de\uff1a \u8bfb\u53d6\u7684\u6570\u636e\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwrite","title":"usbHostSerialWrite()","text":"

    \u5411 USB \u4e32\u884c\u5199\u5165\u6570\u636e\u3002

    usbHostSerialWrite(data)\n

    \u53c2\u6570\uff1a - data (str): \u8981\u5199\u5165\u7684\u5b57\u7b26\u4e32\u6570\u636e

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialavailable","title":"usbHostSerialAvailable()","text":"

    \u68c0\u67e5\u662f\u5426\u6709\u53ef\u8bfb\u53d6\u7684\u6570\u636e\u3002

    usbHostSerialAvailable()\n

    \u8fd4\u56de\uff1a \u53ef\u7528\u5b57\u8282\u6570

    "},{"location":"qsl4a/hardware/usbserial/#_1","title":"\u914d\u7f6e\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetbaudrate","title":"usbHostSerialSetBaudRate()","text":"

    \u8bbe\u7f6e\u6ce2\u7279\u7387\u3002

    usbHostSerialSetBaudRate(baudRate)\n

    \u53c2\u6570\uff1a - baudRate (int): \u6ce2\u7279\u7387

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetdatabits","title":"usbHostSerialSetDataBits()","text":"

    \u8bbe\u7f6e\u6570\u636e\u4f4d\uff085\u30016\u30017 \u6216 8\uff09\u3002

    usbHostSerialSetDataBits(dataBits)\n

    \u53c2\u6570\uff1a - dataBits (int): \u6570\u636e\u4f4d\uff085-8\uff09

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetstopbits","title":"usbHostSerialSetStopBits()","text":"

    \u8bbe\u7f6e\u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09\u3002

    usbHostSerialSetStopBits(stopBits)\n

    \u53c2\u6570\uff1a - stopBits (float): \u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetparity","title":"usbHostSerialSetParity()","text":"

    \u8bbe\u7f6e\u6821\u9a8c\u4f4d\uff08\u65e0\u3001\u5947\u3001\u5076\u3001\u6807\u8bb0\u3001\u7a7a\u683c\uff09\u3002

    usbHostSerialSetParity(parity)\n

    \u53c2\u6570\uff1a - parity (str): \u6821\u9a8c\u6a21\u5f0f\uff08'none'\u3001'odd'\u3001'even'\u3001'mark'\u3001'space'\uff09

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetflowcontrol","title":"usbHostSerialSetFlowControl()","text":"

    \u8bbe\u7f6e\u6d41\u63a7\u5236\uff08\u65e0\u3001\u786c\u4ef6\u3001\u8f6f\u4ef6\uff09\u3002

    usbHostSerialSetFlowControl(flowControl)\n

    \u53c2\u6570\uff1a - flowControl (str): \u6d41\u63a7\u5236\u6a21\u5f0f\uff08'none'\u3001'hardware'\u3001'software'\uff09

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialreadhex","title":"usbHostSerialReadHex()","text":"

    \u4ee5\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u8bfb\u53d6\u6570\u636e\u3002

    usbHostSerialReadHex(bufferSize=1024)\n

    \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570

    \u8fd4\u56de\uff1a \u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwritehex","title":"usbHostSerialWriteHex()","text":"

    \u4ece\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u5199\u5165\u6570\u636e\u3002

    usbHostSerialWriteHex(hexString)\n

    \u53c2\u6570\uff1a - hexString (str): \u8981\u5199\u5165\u7684\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/hardware/usbserial/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6253\u5f00 USB \u4e32\u884c\u8fde\u63a5\nif droid.usbHostSerialOpen(\"/dev/bus/usb/001/001\", 115200).result:\n    print(\"USB serial opened\")\n\n    # \u5199\u5165\u6570\u636e\n    droid.usbHostSerialWrite(\"AT\\r\")\n\n    # \u8bfb\u53d6\u54cd\u5e94\n    response = droid.usbHostSerialRead(1024).result\n    print(f\"Response: {response}\")\n\n    # \u6216\u4f7f\u7528\u5341\u516d\u8fdb\u5236\n    droid.usbHostSerialWriteHex(\"41540D0A\")  # \"AT\\r\\n\"\n\n    # \u5173\u95ed\u8fde\u63a5\n    droid.usbHostSerialClose()\n

    \u6ce8\u610f\uff1a USB \u4e32\u884c\u9700\u8981\uff1a - Android 3.1+ (API 12) - USB OTG \u7ebf/\u9002\u914d\u5668 - \u8bbe\u5907\u4e0a\u7684 USB \u4e3b\u673a\u6a21\u5f0f\u652f\u6301 - \u517c\u5bb9\u7684\u4e32\u884c\u8bbe\u5907

    "},{"location":"qsl4a/hardware/webcam/","title":"\u7f51\u7edc\u6444\u50cf\u5934 API","text":"

    \u4f7f\u7528 MJPEG \u4ece\u8bbe\u5907\u76f8\u673a\u6d41\u5f0f\u4f20\u8f93\u89c6\u9891\u3002

    "},{"location":"qsl4a/hardware/webcam/#mjpeg","title":"MJPEG \u6d41\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#webcamstart","title":"webcamStart()","text":"

    \u4ece\u7f51\u7edc\u6444\u50cf\u5934\u542f\u52a8 MJPEG \u6d41\u3002

    webcamStart(resolutionLevel=0, jpegQuality=20, port=0)\n

    \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf 1-100\uff08\u9ed8\u8ba4\uff1a20\uff09 - port (int): \u7aef\u53e3\u53f7\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\uff09

    \u8fd4\u56de\uff1a \u6d41\u7684 (\u5730\u5740, \u7aef\u53e3) \u5143\u7ec4

    "},{"location":"qsl4a/hardware/webcam/#webcamadjustquality","title":"webcamAdjustQuality()","text":"

    \u8c03\u6574\u6d3b\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u7684\u8d28\u91cf\u3002

    webcamAdjustQuality(resolutionLevel=0, jpegQuality=20)\n

    \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b - jpegQuality (int): JPEG \u8d28\u91cf 1-100

    "},{"location":"qsl4a/hardware/webcam/#webcamstop","title":"webcamStop()","text":"

    \u505c\u6b62\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u3002

    webcamStop()\n
    "},{"location":"qsl4a/hardware/webcam/#_1","title":"\u76f8\u673a\u9884\u89c8\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#camerastartpreview","title":"cameraStartPreview()","text":"

    \u5f00\u59cb\u5e26\u4e8b\u4ef6\u751f\u6210\u7684\u76f8\u673a\u9884\u89c8\u6a21\u5f0f\u3002

    cameraStartPreview(resolutionLevel=0, jpegQuality=20, filepath=None)\n

    \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf\uff08\u9ed8\u8ba4\uff1a20\uff09 - filepath (str, optional): \u4fdd\u5b58\u9884\u89c8\u5e27\u7684\u6587\u4ef6\u8def\u5f84

    \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

    \u6ce8\u610f\uff1a \u751f\u6210\u5e26\u6709\u5e27\u6570\u636e\u7684 'preview' \u4e8b\u4ef6\u3002

    "},{"location":"qsl4a/hardware/webcam/#camerastoppreview","title":"cameraStopPreview()","text":"

    \u505c\u6b62\u76f8\u673a\u9884\u89c8\u3002

    cameraStopPreview()\n
    "},{"location":"qsl4a/hardware/webcam/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\nstream_info = droid.webcamStart(\n    resolutionLevel=0,\n    jpegQuality=30,\n    port=8080\n).result\nprint(f\"Stream available at {stream_info[0]}:{stream_info[1]}\")\n\n# \u6d41\u5f0f\u4f20\u8f93\u65f6\u8c03\u6574\u8d28\u91cf\ntime.sleep(5)\ndroid.webcamAdjustQuality(resolutionLevel=1, jpegQuality=50)\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.webcamStop()\n\n# \u6216\u4f7f\u7528\u9884\u89c8\u6a21\u5f0f\nprint(\"Starting preview...\")\ndroid.cameraStartPreview()\n\n# \u7b49\u5f85\u9884\u89c8\u4e8b\u4ef6\nfor i in range(10):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'preview':\n        print(f\"Got preview frame: {event['data']}\")\n\ndroid.cameraStopPreview()\n
    "},{"location":"qsl4a/media/image/","title":"\u56fe\u50cf\u5904\u7406 API","text":"

    \u538b\u7f29\u548c\u5904\u7406\u56fe\u50cf\u3002

    "},{"location":"qsl4a/media/image/#_1","title":"\u56fe\u50cf\u538b\u7f29","text":""},{"location":"qsl4a/media/image/#imagecompress","title":"imageCompress()","text":"

    \u538b\u7f29\u56fe\u50cf\u6587\u4ef6\u3002

    imageCompress(srcPath, destPath, targetByteSize=0, targetWidth=0, targetHeight=0)\n

    \u53c2\u6570\uff1a - srcPath (str): \u6e90\u56fe\u50cf\u8def\u5f84 - destPath (str): \u8f93\u51fa\u8def\u5f84 - targetByteSize (int): \u76ee\u6807\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff080 = \u65e0\u9650\u5236\uff09 - targetWidth (int): \u76ee\u6807\u5bbd\u5ea6\uff080 = \u539f\u59cb\uff09 - targetHeight (int): \u76ee\u6807\u9ad8\u5ea6\uff080 = \u539f\u59cb\uff09

    \u8fd4\u56de\uff1a \u538b\u7f29\u540e\u7684\u56fe\u50cf\u8def\u5f84

    "},{"location":"qsl4a/media/image/#_2","title":"\u622a\u56fe","text":""},{"location":"qsl4a/media/image/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

    \u622a\u53d6\u5c4f\u5e55\u3002

    imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

    \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

    \u8fd4\u56de\uff1a \u622a\u56fe\u8def\u5f84

    "},{"location":"qsl4a/media/image/#_3","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/image/#videoplay","title":"videoPlay()","text":"

    \u5728\u5168\u5c4f\u6a21\u5f0f\u4e0b\u64ad\u653e\u89c6\u9891\u6587\u4ef6\u3002

    videoPlay(path, wait=True)\n

    \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

    "},{"location":"qsl4a/media/image/#_4","title":"\u6761\u7801\u626b\u63cf","text":""},{"location":"qsl4a/media/image/#scanbarcodefromimage","title":"scanBarcodeFromImage()","text":"

    \u4ece\u56fe\u50cf\u6587\u4ef6\u626b\u63cf\u6761\u7801/\u4e8c\u7ef4\u7801\u3002

    scanBarcodeFromImage(path, compressRatio=0, x=0, y=0, width=0, height=0)\n

    \u53c2\u6570\uff1a - path (str): \u56fe\u50cf\u6587\u4ef6\u8def\u5f84 - compressRatio (int): \u538b\u7f29\u6bd4\uff080 = \u4e0d\u538b\u7f29\uff09 - x, y, width, height (int): \u8981\u626b\u63cf\u7684\u533a\u57df\uff080 = \u5b8c\u6574\u56fe\u50cf\uff09

    \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5185\u5bb9

    "},{"location":"qsl4a/media/image/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n\n# \u538b\u7f29\u56fe\u50cf\ncompressed = droid.imageCompress(\n    \"/sdcard/large_photo.jpg\",\n    \"/sdcard/compressed.jpg\",\n    targetByteSize=102400,  # \u76ee\u6807\u7ea6 100KB\n    targetWidth=1920,\n    targetHeight=1080\n).result\nprint(f\"Saved: {compressed}\")\n\n# \u64ad\u653e\u89c6\u9891\nvideo_path = \"/sdcard/movie.mp4\"\ndroid.videoPlay(video_path, wait=True)\n\n# \u4ece\u56fe\u50cf\u626b\u63cf\u6761\u7801\nresult = droid.scanBarcodeFromImage(\"/sdcard/qr_code.png\").result\nprint(f\"Barcode: {result}\")\n
    "},{"location":"qsl4a/media/mediaplayer/","title":"\u5a92\u4f53\u64ad\u653e\u5668 API","text":"

    \u63a7\u5236\u97f3\u9891\u548c\u89c6\u9891\u64ad\u653e\u3002

    "},{"location":"qsl4a/media/mediaplayer/#_1","title":"\u64ad\u653e\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplay","title":"mediaPlay()","text":"

    \u64ad\u653e\u5a92\u4f53\u6587\u4ef6\u3002

    mediaPlay(url, tag=\"default\", play=True)\n

    \u53c2\u6570\uff1a - url (str): \u5a92\u4f53\u6587\u4ef6\u8def\u5f84\u6216 URL - tag (str): \u64ad\u653e\u5668\u6807\u8bc6\u7b26 - play (bool): \u81ea\u52a8\u5f00\u59cb\u64ad\u653e

    "},{"location":"qsl4a/media/mediaplayer/#mediaplaystart","title":"mediaPlayStart()","text":"

    \u5f00\u59cb\u64ad\u653e\u3002

    mediaPlayStart(tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#mediaplaypause","title":"mediaPlayPause()","text":"

    \u6682\u505c\u64ad\u653e\u3002

    mediaPlayPause(tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#mediaplayclose","title":"mediaPlayClose()","text":"

    \u5173\u95ed\u64ad\u653e\u5668\u3002

    mediaPlayClose(tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#mediaplayseek","title":"mediaPlaySeek()","text":"

    \u8df3\u8f6c\u5230\u4f4d\u7f6e\u3002

    mediaPlaySeek(msec, tag=\"default\")\n

    \u53c2\u6570\uff1a - msec (int): \u4f4d\u7f6e\uff08\u6beb\u79d2\uff09

    "},{"location":"qsl4a/media/mediaplayer/#mediaplaysetlooping","title":"mediaPlaySetLooping()","text":"

    \u8bbe\u7f6e\u5faa\u73af\u6a21\u5f0f\u3002

    mediaPlaySetLooping(enabled, tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#_2","title":"\u64ad\u653e\u5668\u4fe1\u606f","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplayinfo","title":"mediaPlayInfo()","text":"

    \u83b7\u53d6\u64ad\u653e\u4fe1\u606f\u3002

    mediaPlayInfo(tag=\"default\")\n

    \u8fd4\u56de\uff1a \u5305\u542b\u65f6\u957f\u3001\u4f4d\u7f6e\u7b49\u7684\u5b57\u5178

    "},{"location":"qsl4a/media/mediaplayer/#mediaisplaying","title":"mediaIsPlaying()","text":"

    \u68c0\u67e5\u662f\u5426\u6b63\u5728\u64ad\u653e\u3002

    mediaIsPlaying(tag=\"default\")\n

    \u8fd4\u56de\uff1a True/False

    "},{"location":"qsl4a/media/mediaplayer/#mediaplaylist","title":"mediaPlayList()","text":"

    \u5217\u51fa\u6d3b\u52a8\u64ad\u653e\u5668\u3002

    mediaPlayList()\n
    "},{"location":"qsl4a/media/mediaplayer/#_3","title":"\u97f3\u91cf\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#getmediavolume","title":"getMediaVolume()","text":"

    \u83b7\u53d6\u5a92\u4f53\u97f3\u91cf\u3002

    getMediaVolume()\n

    \u8fd4\u56de\uff1a \u97f3\u91cf\u7ea7\u522b\uff080-15\uff09

    "},{"location":"qsl4a/media/mediaplayer/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

    \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

    getMaxMediaVolume()\n
    "},{"location":"qsl4a/media/mediaplayer/#getringervolume","title":"getRingerVolume()","text":"

    \u83b7\u53d6\u94c3\u58f0\u97f3\u91cf\u3002

    getRingerVolume()\n
    "},{"location":"qsl4a/media/mediaplayer/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

    \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

    getMaxRingerVolume()\n
    "},{"location":"qsl4a/media/mediaplayer/#_4","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/mediaplayer/#videoplay","title":"videoPlay()","text":"

    \u5168\u5c4f\u64ad\u653e\u89c6\u9891\u3002

    videoPlay(path, wait=True)\n

    \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210

    "},{"location":"qsl4a/media/mediaplayer/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u64ad\u653e\u97f3\u9891\ndroid.mediaPlay(\"/sdcard/music.mp3\", tag=\"music\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.mediaIsPlaying(\"music\").result:\n    info = droid.mediaPlayInfo(\"music\").result\n    print(f\"Playing: {info}\")\n\n# \u8df3\u8f6c\u5230 30 \u79d2\ndroid.mediaPlaySeek(30000, \"music\")\n\n# \u5173\u95ed\ndroid.mediaPlayClose(\"music\")\n\n# \u64ad\u653e\u89c6\u9891\ndroid.videoPlay(\"/sdcard/movie.mp4\", wait=True)\n
    "},{"location":"qsl4a/special/cipher/","title":"\u5bc6\u7801 API","text":"

    \u7528\u4e8e\u5b89\u5168\u6570\u636e\u5b58\u50a8\u7684\u52a0\u5bc6\u548c\u89e3\u5bc6\u5de5\u5177\u3002

    "},{"location":"qsl4a/special/cipher/#_1","title":"\u521d\u59cb\u5316","text":""},{"location":"qsl4a/special/cipher/#cipherinit","title":"cipherInit()","text":"

    \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u548c\u7b97\u6cd5\u521d\u59cb\u5316\u5bc6\u7801\u5668\u3002

    cipherInit(key, algorithm=\"AES/CBC/PKCS5Padding\", encodingFormat=\"\", initialVector=\"\")\n

    \u53c2\u6570\uff1a - key (str or bytes): \u52a0\u5bc6\u5bc6\u94a5 - algorithm (str): \u5bc6\u7801\u7b97\u6cd5\uff08\u9ed8\u8ba4\uff1a\"AES/CBC/PKCS5Padding\"\uff09 - encodingFormat (str): \u7f16\u7801\u683c\u5f0f - initialVector (str or bytes): \u52a0\u5bc6\u7684\u521d\u59cb\u5411\u91cf

    \u8fd4\u56de\uff1a \u521d\u59cb\u5316\u7ed3\u679c

    \u6ce8\u610f\uff1a \u5fc5\u987b\u5728\u4efb\u4f55\u52a0\u5bc6/\u89e3\u5bc6\u64cd\u4f5c\u4e4b\u524d\u8c03\u7528\u3002

    "},{"location":"qsl4a/special/cipher/#_2","title":"\u52a0\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#encryptstring","title":"encryptString()","text":"

    \u52a0\u5bc6\u5b57\u7b26\u4e32\u3002

    encryptString(plainText)\n

    \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c

    \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/special/cipher/#encryptbytes","title":"encryptBytes()","text":"

    \u52a0\u5bc6\u5b57\u8282\u6570\u636e\u3002

    encryptBytes(data)\n

    \u53c2\u6570\uff1a - data (bytes): \u8981\u52a0\u5bc6\u7684\u6570\u636e

    \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u8282

    "},{"location":"qsl4a/special/cipher/#encryptstringtofile","title":"encryptStringToFile()","text":"

    \u52a0\u5bc6\u5b57\u7b26\u4e32\u5230\u6587\u4ef6\u3002

    encryptStringToFile(plainText, filePath)\n

    \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c - filePath (str): \u8f93\u51fa\u6587\u4ef6\u8def\u5f84

    "},{"location":"qsl4a/special/cipher/#encryptbytestofile","title":"encryptBytesToFile()","text":"

    \u52a0\u5bc6\u5b57\u8282\u5230\u6587\u4ef6\u3002

    encryptBytesToFile(data, filePath)\n
    "},{"location":"qsl4a/special/cipher/#_3","title":"\u89e3\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#decryptstring","title":"decryptString()","text":"

    \u89e3\u5bc6\u4e3a\u5b57\u7b26\u4e32\u3002

    decryptString(cipherText)\n

    \u53c2\u6570\uff1a - cipherText (str): \u52a0\u5bc6\u7684\u6587\u672c

    \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u7b26\u4e32

    "},{"location":"qsl4a/special/cipher/#decryptbytes","title":"decryptBytes()","text":"

    \u89e3\u5bc6\u4e3a\u5b57\u8282\u3002

    decryptBytes(data)\n

    \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u8282

    "},{"location":"qsl4a/special/cipher/#decryptfiletostring","title":"decryptFileToString()","text":"

    \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u7b26\u4e32\u3002

    decryptFileToString(filePath)\n
    "},{"location":"qsl4a/special/cipher/#decryptfiletobytes","title":"decryptFileToBytes()","text":"

    \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u8282\u3002

    decryptFileToBytes(filePath)\n
    "},{"location":"qsl4a/special/cipher/#decryptfile","title":"decryptFile()","text":"

    \u89e3\u5bc6\u6587\u4ef6\u5230\u6587\u4ef6\u3002

    decryptFile(srcPath, destPath)\n
    "},{"location":"qsl4a/special/cipher/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u521d\u59cb\u5316\u5bc6\u7801\u5668\ndroid.cipherInit(\"my_secret_key_1234\")\n\n# \u52a0\u5bc6\u5b57\u7b26\u4e32\nencrypted = droid.encryptString(\"Secret message!\").result\nprint(f\"Encrypted: {encrypted}\")\n\n# \u89e3\u5bc6\u5b57\u7b26\u4e32\ndecrypted = droid.decryptString(encrypted).result\nprint(f\"Decrypted: {decrypted}\")\n\n# \u52a0\u5bc6\u5230\u6587\u4ef6\ndroid.encryptStringToFile(\"My secret data\", \"/sdcard/secret.dat\")\n\n# \u4ece\u6587\u4ef6\u89e3\u5bc6\ndata = droid.decryptFileToString(\"/sdcard/secret.dat\").result\nprint(data)\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u7b97\u6cd5\u548c IV \u521d\u59cb\u5316\ndroid.cipherInit(\n    key=\"my_key\",\n    algorithm=\"AES/CBC/PKCS5Padding\",\n    initialVector=\"0123456789abcdef\"\n)\n
    "},{"location":"qsl4a/special/pgptai/","title":"PGPT AI API","text":"

    \u8bed\u97f3\u8f6c\u6587\u672c\u548c AI \u670d\u52a1\u96c6\u6210\u3002

    "},{"location":"qsl4a/special/pgptai/#_1","title":"\u5148\u51b3\u6761\u4ef6","text":"
    pip install pgptAI\n
    "},{"location":"qsl4a/special/pgptai/#_2","title":"\u8bed\u97f3\u8bc6\u522b","text":""},{"location":"qsl4a/special/pgptai/#speechtotext","title":"speechToText()","text":"

    \u5c06\u8bed\u97f3\u8f6c\u6362\u4e3a\u6587\u672c\u3002

    speechToText(RecordSecond=10, AmrFile=None, Language=None)\n

    \u53c2\u6570\uff1a - RecordSecond (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09 - AmrFile (str, optional): \u73b0\u6709\u97f3\u9891\u6587\u4ef6\u8def\u5f84 - Language (str, optional): \u8bed\u8a00\u4ee3\u7801\uff08'en'\u3001'zh'\uff09

    \u8fd4\u56de\uff1a \u8f6c\u5f55\u7684\u6587\u672c

    "},{"location":"qsl4a/special/pgptai/#_3","title":"\u6587\u672c\u8f6c\u8bed\u97f3","text":""},{"location":"qsl4a/special/pgptai/#texttospeech","title":"textToSpeech()","text":"

    \u5c06\u6587\u672c\u8f6c\u6362\u4e3a\u8bed\u97f3\u5e76\u53ef\u9009\u5730\u64ad\u653e\u3002

    textToSpeech(Text, AutoPlay=True, WavFile=None, VoiceName=None)\n

    \u53c2\u6570\uff1a - Text (str): \u8981\u8f6c\u6362\u4e3a\u8bed\u97f3\u7684\u6587\u672c - AutoPlay (bool): \u81ea\u52a8\u64ad\u653e\u751f\u6210\u7684\u97f3\u9891\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - WavFile (str, optional): \u4fdd\u5b58 WAV \u6587\u4ef6\u7684\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u4e34\u65f6\u6587\u4ef6 - VoiceName (str, optional): \u8981\u4f7f\u7528\u7684\u8bed\u97f3\u540d\u79f0\uff08\u4f8b\u5982 'en-US-JennyNeural'\u3001'zh-CN-XiaoxiaoNeural'\uff09

    \u8fd4\u56de\uff1a \u5305\u542b\u8bed\u97f3\u5408\u6210\u7ed3\u679c\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - text: \u8f93\u5165\u6587\u672c - url: \u4e0b\u8f7d\u97f3\u9891\u6587\u4ef6\u7684 URL - WavFile: \u4fdd\u5b58\u7684 WAV \u6587\u4ef6\u8def\u5f84\uff08\u5982\u679c\u672c\u5730\u4fdd\u5b58\uff09

    "},{"location":"qsl4a/special/pgptai/#_4","title":"\u914d\u7f6e","text":"

    API \u4f7f\u7528\u4ee5\u4e0b\u914d\u7f6e\u6587\u4ef6\u4e2d\u7684\u914d\u7f6e\uff1a/storage/emulated/0/Android/data/org.qpython.qpy/files/apigpt.conf\uff1a

    [speech]\nspeech_key = your_api_key\n

    \u9ed8\u8ba4\u8bed\u97f3\u8bbe\u7f6e\uff1a - \u82f1\u8bed\uff1aen-US-JennyNeural - \u4e2d\u6587\uff1azh-CN-XiaoxiaoNeural

    "},{"location":"qsl4a/special/pgptai/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5f55\u5236\u5e76\u8f6c\u5f55\nprint(\"Recording for 5 seconds...\")\ntext = droid.speechToText(RecordSecond=5, Language='en').result\nprint(f\"You said: {text}\")\n\n# \u8f6c\u5f55\u73b0\u6709\u6587\u4ef6\ntext = droid.speechToText(AmrFile=\"/sdcard/recording.amr\").result\nprint(f\"Transcription: {text}\")\n\n# \u6587\u672c\u8f6c\u8bed\u97f3\ndroid.textToSpeech(\"Hello, this is a test message.\", AutoPlay=True, Language='en')\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u8bed\u97f3\u5e76\u4fdd\u5b58\u5230\u6587\u4ef6\u7684\u6587\u672c\u8f6c\u8bed\u97f3\nresult = droid.textToSpeech(\n    \"Welcome to QPython!\",\n    AutoPlay=False,\n    WavFile=\"/sdcard/welcome.wav\",\n    VoiceName=\"en-US-JennyNeural\"\n).result\nprint(f\"Audio saved to: {result.get('WavFile')}\")\n
    "},{"location":"qsl4a/special/pgptai/#_6","title":"\u7c7b\u4f7f\u7528","text":"
    from androidhelper.pgptai import pgptai\nimport androidhelper\n\ndroid = androidhelper.Android()\nai = pgptai(droid)\n\n# \u4f7f\u7528\u8bed\u97f3\u8bc6\u522b\ntext = ai.speechToText(RecordSecond=10)\n
    "},{"location":"qsl4a/storage/clipboard/","title":"\u526a\u8d34\u677f API","text":"

    \u590d\u5236\u548c\u7c98\u8d34\u6587\u672c\u5230\u7cfb\u7edf\u526a\u8d34\u677f\u3002

    "},{"location":"qsl4a/storage/clipboard/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/clipboard/#setclipboard","title":"setClipboard()","text":"

    \u590d\u5236\u6587\u672c\u5230\u526a\u8d34\u677f\u3002

    setClipboard(text)\n

    \u53c2\u6570\uff1a - text (str): \u8981\u590d\u5236\u7684\u6587\u672c

    \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/storage/clipboard/#getclipboard","title":"getClipboard()","text":"

    \u4ece\u526a\u8d34\u677f\u83b7\u53d6\u6587\u672c\u3002

    getClipboard()\n

    \u8fd4\u56de\uff1a \u526a\u8d34\u677f\u6587\u672c

    "},{"location":"qsl4a/storage/clipboard/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u590d\u5236\u5230\u526a\u8d34\u677f\ndroid.setClipboard(\"Hello from QPython!\")\n\n# \u4ece\u526a\u8d34\u677f\u7c98\u8d34\ntext = droid.getClipboard().result\nprint(f\"Clipboard: {text}\")\n
    "},{"location":"qsl4a/storage/documentfile/","title":"DocumentFile API","text":"

    \u4f7f\u7528 SAF\uff08\u5b58\u50a8\u8bbf\u95ee\u6846\u67b6\uff09\u8fdb\u884c\u6587\u4ef6\u64cd\u4f5c\uff0c\u652f\u6301 Android 4.4+\u3002

    "},{"location":"qsl4a/storage/documentfile/#_1","title":"\u76ee\u5f55\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilemkdir","title":"documentFileMkdir()","text":"

    \u521b\u5efa\u76ee\u5f55\u3002

    documentFileMkdir(Dir)\n

    \u53c2\u6570\uff1a - Dir (str): \u76ee\u5f55\u8def\u5f84

    \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/storage/documentfile/#documentfilelistfiles","title":"documentFileListFiles()","text":"

    \u5217\u51fa\u76ee\u5f55\u4e2d\u7684\u6587\u4ef6\u3002

    documentFileListFiles(Folder)\n

    \u8fd4\u56de\uff1a \u6587\u4ef6\u5217\u8868

    "},{"location":"qsl4a/storage/documentfile/#_2","title":"\u6587\u4ef6\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileexists","title":"documentFileExists()","text":"

    \u68c0\u67e5\u6587\u4ef6\u6216\u76ee\u5f55\u662f\u5426\u5b58\u5728\u3002

    documentFileExists(path)\n

    \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u6216\u76ee\u5f55\u8def\u5f84

    \u8fd4\u56de\uff1a \u5982\u679c\u5b58\u5728\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

    "},{"location":"qsl4a/storage/documentfile/#documentfileisfile","title":"documentFileIsFile()","text":"

    \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u6587\u4ef6\u3002

    documentFileIsFile(path)\n

    \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

    \u8fd4\u56de\uff1a \u5982\u679c\u662f\u6587\u4ef6\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u6587\u4ef6\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

    "},{"location":"qsl4a/storage/documentfile/#documentfileisdirectory","title":"documentFileIsDirectory()","text":"

    \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u76ee\u5f55\u3002

    documentFileIsDirectory(path)\n

    \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

    \u8fd4\u56de\uff1a \u5982\u679c\u662f\u76ee\u5f55\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u76ee\u5f55\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

    "},{"location":"qsl4a/storage/documentfile/#documentfiledelete","title":"documentFileDelete()","text":"

    \u5220\u9664\u6587\u4ef6\u6216\u76ee\u5f55\u3002

    documentFileDelete(FileOrTree)\n

    \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/storage/documentfile/#documentfilerenameto","title":"documentFileRenameTo()","text":"

    \u91cd\u547d\u540d\u6216\u79fb\u52a8\u6587\u4ef6\u3002

    documentFileRenameTo(Src, Dest)\n

    \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/storage/documentfile/#documentfilecopy","title":"documentFileCopy()","text":"

    \u590d\u5236\u6587\u4ef6\u3002

    documentFileCopy(SrcFileOrTree, DestFileOrTree)\n
    "},{"location":"qsl4a/storage/documentfile/#_3","title":"\u6d41\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileinputstream","title":"documentFileInputStream()","text":"

    \u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9\u3002

    documentFileInputStream(srcFile, EncodingFormat=\"\", skip=None, length=None)\n

    \u53c2\u6570\uff1a - srcFile (str): \u6e90\u6587\u4ef6 - EncodingFormat (str): \"UTF-8\"\u3001\"GBK\"\u3001\"Base64\" \u6216\u7a7a\u5b57\u7b26\u4e32\u8868\u793a\u5b57\u8282 - skip (int): \u4ece\u5f00\u5934\u8df3\u8fc7\u7684\u5b57\u8282\u6570 - length (int): \u8bfb\u53d6\u957f\u5ea6

    \u8fd4\u56de\uff1a \u6587\u4ef6\u5185\u5bb9

    "},{"location":"qsl4a/storage/documentfile/#documentfileoutputstream","title":"documentFileOutputStream()","text":"

    \u5199\u5165\u6587\u4ef6\u5185\u5bb9\u3002

    documentFileOutputStream(destFile, src, EncodingFormat=\"\", append=None)\n

    \u53c2\u6570\uff1a - destFile (str): \u76ee\u6807\u6587\u4ef6 - src: \u8981\u5199\u5165\u7684\u6570\u636e - EncodingFormat (str): \u7f16\u7801\u683c\u5f0f - append (bool): \u8ffd\u52a0\u6a21\u5f0f

    "},{"location":"qsl4a/storage/documentfile/#_4","title":"\u6587\u4ef6\u4fe1\u606f","text":""},{"location":"qsl4a/storage/documentfile/#documentfilelength","title":"documentFileLength()","text":"

    \u83b7\u53d6\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\u3002

    documentFileLength(path)\n

    \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

    \u8fd4\u56de\uff1a \u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

    "},{"location":"qsl4a/storage/documentfile/#documentfilelastmodified","title":"documentFileLastModified()","text":"

    \u83b7\u53d6\u6700\u540e\u4fee\u6539\u65f6\u95f4\u3002

    documentFileLastModified(path)\n

    \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

    \u8fd4\u56de\uff1a \u65f6\u95f4\u6233\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

    "},{"location":"qsl4a/storage/documentfile/#documentfilegetstat","title":"documentFileGetStat()","text":"

    \u83b7\u53d6\u5168\u9762\u7684\u6587\u4ef6\u7edf\u8ba1\u4fe1\u606f\u3002

    documentFileGetStat(path)\n

    \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

    \u8fd4\u56de\uff1a \u5305\u542b\u957f\u5ea6\u3001\u6700\u540e\u4fee\u6539\u65f6\u95f4\u548c\u8bfb/\u5199\u6743\u9650\u7684\u5b57\u5178\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

    "},{"location":"qsl4a/storage/documentfile/#uri","title":"URI \u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilegeturi","title":"documentFileGetUri()","text":"

    \u4ece\u8def\u5f84\u83b7\u53d6 URI\u3002

    documentFileGetUri(path, isDirectory=None)\n
    "},{"location":"qsl4a/storage/documentfile/#documentfileshowopen","title":"documentFileShowOpen()","text":"

    \u663e\u793a\u6587\u4ef6\u9009\u62e9\u5668\u3002

    documentFileShowOpen()\n

    \u8fd4\u56de\uff1a \u9009\u62e9\u7684\u6587\u4ef6 URI

    "},{"location":"qsl4a/storage/documentfile/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u76ee\u5f55\ndroid.documentFileMkdir(\"/sdcard/MyFolder\")\n\n# \u5217\u51fa\u6587\u4ef6\nfiles = droid.documentFileListFiles(\"/sdcard\").result\nfor f in files:\n    print(f)\n\n# \u8bfb\u53d6\u6587\u4ef6\ncontent = droid.documentFileInputStream(\n    \"/sdcard/test.txt\",\n    EncodingFormat=\"UTF-8\"\n).result\nprint(content)\n\n# \u5199\u5165\u6587\u4ef6\ndroid.documentFileOutputStream(\n    \"/sdcard/output.txt\",\n    \"Hello World\",\n    EncodingFormat=\"UTF-8\"\n)\n
    "},{"location":"qsl4a/storage/preferences/","title":"\u504f\u597d\u8bbe\u7f6e API","text":"

    \u4f7f\u7528 Android SharedPreferences \u5b58\u50a8\u548c\u68c0\u7d22\u6570\u636e\u3002

    "},{"location":"qsl4a/storage/preferences/#_1","title":"\u504f\u597d\u8bbe\u7f6e\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/preferences/#prefgetvalue","title":"prefGetValue()","text":"

    \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u8bfb\u53d6\u503c\u3002

    prefGetValue(key, filename=None)\n

    \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

    \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c\uff08\u4efb\u610f\u7c7b\u578b\uff09

    "},{"location":"qsl4a/storage/preferences/#prefputvalue","title":"prefPutValue()","text":"

    \u5199\u5165\u503c\u5230\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u3002

    prefPutValue(key, value, filename=None)\n

    \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - value (object): \u8981\u5b58\u50a8\u7684\u503c - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

    "},{"location":"qsl4a/storage/preferences/#prefgetall","title":"prefGetAll()","text":"

    \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\u503c\u3002

    prefGetAll(filename=None)\n

    \u53c2\u6570\uff1a - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

    \u8fd4\u56de\uff1a \u6240\u6709\u504f\u597d\u7684\u6620\u5c04

    "},{"location":"qsl4a/storage/preferences/#prefremovevalue","title":"prefRemoveValue()","text":"

    \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u4e2d\u79fb\u9664\u503c\u3002

    prefRemoveValue(key, filename=None)\n

    \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

    "},{"location":"qsl4a/storage/preferences/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b58\u50a8\u503c\ndroid.prefPutValue(\"username\", \"alice\")\ndroid.prefPutValue(\"score\", 100)\ndroid.prefPutValue(\"enabled\", True)\n\n# \u8bfb\u53d6\u7279\u5b9a\u503c\nusername = droid.prefGetValue(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\nall_prefs = droid.prefGetAll().result\nprint(f\"All prefs: {all_prefs}\")\n\n# \u79fb\u9664\u503c\ndroid.prefRemoveValue(\"score\")\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u6587\u4ef6\u540d\ndroid.prefPutValue(\"token\", \"abc123\", filename=\"auth.prefs\")\ntoken = droid.prefGetValue(\"token\", filename=\"auth.prefs\").result\n
    "},{"location":"qsl4a/system/activityresult/","title":"Activity Result API","text":"

    \u4e3a\u901a\u8fc7 startActivityForResult \u542f\u52a8\u7684\u811a\u672c\u8bbe\u7f6e activity \u7ed3\u679c\u3002

    "},{"location":"qsl4a/system/activityresult/#_1","title":"\u7ed3\u679c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/activityresult/#setresultboolean","title":"setResultBoolean()","text":"

    \u8bbe\u7f6e\u5e03\u5c14\u7ed3\u679c\u3002

    setResultBoolean(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (bool): \u5e03\u5c14\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#setresultbyte","title":"setResultByte()","text":"

    \u8bbe\u7f6e\u5b57\u8282\u7ed3\u679c\u3002

    setResultByte(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u5b57\u8282\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#setresultshort","title":"setResultShort()","text":"

    \u8bbe\u7f6e\u77ed\u6574\u6570\u7ed3\u679c\u3002

    setResultShort(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u77ed\u6574\u6570\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#setresultchar","title":"setResultChar()","text":"

    \u8bbe\u7f6e\u5b57\u7b26\u7ed3\u679c\u3002

    setResultChar(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#setresultinteger","title":"setResultInteger()","text":"

    \u8bbe\u7f6e\u6574\u6570\u7ed3\u679c\u3002

    setResultInteger(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u6574\u6570\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#setresultlong","title":"setResultLong()","text":"

    \u8bbe\u7f6e\u957f\u6574\u6570\u7ed3\u679c\u3002

    setResultLong(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u957f\u6574\u6570\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#setresultfloat","title":"setResultFloat()","text":"

    \u8bbe\u7f6e\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

    setResultFloat(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u6d6e\u70b9\u6570\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#setresultdouble","title":"setResultDouble()","text":"

    \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

    setResultDouble(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#setresultstring","title":"setResultString()","text":"

    \u8bbe\u7f6e\u5b57\u7b26\u4e32\u7ed3\u679c\u3002

    setResultString(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u4e32\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#setresultbooleanarray","title":"setResultBooleanArray()","text":"

    \u8bbe\u7f6e\u5e03\u5c14\u6570\u7ec4\u7ed3\u679c\u3002

    setResultBooleanArray(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5e03\u5c14\u6570\u7ec4

    "},{"location":"qsl4a/system/activityresult/#setresultbytearray","title":"setResultByteArray()","text":"

    \u8bbe\u7f6e\u5b57\u8282\u6570\u7ec4\u7ed3\u679c\u3002

    setResultByteArray(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u8282\u6570\u7ec4

    "},{"location":"qsl4a/system/activityresult/#setresultshortarray","title":"setResultShortArray()","text":"

    \u8bbe\u7f6e\u77ed\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

    setResultShortArray(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u77ed\u6574\u6570\u6570\u7ec4

    "},{"location":"qsl4a/system/activityresult/#setresultchararray","title":"setResultCharArray()","text":"

    \u8bbe\u7f6e\u5b57\u7b26\u6570\u7ec4\u7ed3\u679c\u3002

    setResultCharArray(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u6570\u7ec4

    "},{"location":"qsl4a/system/activityresult/#setresultintegerarray","title":"setResultIntegerArray()","text":"

    \u8bbe\u7f6e\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

    setResultIntegerArray(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6574\u6570\u6570\u7ec4

    "},{"location":"qsl4a/system/activityresult/#setresultlongarray","title":"setResultLongArray()","text":"

    \u8bbe\u7f6e\u957f\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

    setResultLongArray(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u957f\u6574\u6570\u6570\u7ec4

    "},{"location":"qsl4a/system/activityresult/#setresultfloatarray","title":"setResultFloatArray()","text":"

    \u8bbe\u7f6e\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

    setResultFloatArray(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6d6e\u70b9\u6570\u6570\u7ec4

    "},{"location":"qsl4a/system/activityresult/#setresultdoublearray","title":"setResultDoubleArray()","text":"

    \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

    setResultDoubleArray(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4

    "},{"location":"qsl4a/system/activityresult/#setresultstringarray","title":"setResultStringArray()","text":"

    \u8bbe\u7f6e\u5b57\u7b26\u4e32\u6570\u7ec4\u7ed3\u679c\u3002

    setResultStringArray(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u4e32\u6570\u7ec4

    "},{"location":"qsl4a/system/activityresult/#setresultserializable","title":"setResultSerializable()","text":"

    \u8bbe\u7f6e\u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u3002

    setResultSerializable(resultCode, resultValue)\n

    \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue: \u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u503c

    "},{"location":"qsl4a/system/activityresult/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c activity \u540e\uff0c\u8bbe\u7f6e\u7ed3\u679c\n# \u793a\u4f8b\uff1a\u8fd4\u56de\u6210\u529f\u53ca\u6570\u636e\ndroid.setResultInteger(0, 200)  # RESULT_OK\ndroid.setResultString(0, \"Operation completed successfully\")\n\n# \u8fd4\u56de\u6570\u7ec4\u7ed3\u679c\ndroid.setResultIntegerArray(0, [1, 2, 3, 4, 5])\n
    "},{"location":"qsl4a/system/application/","title":"\u5e94\u7528\u7ba1\u7406","text":"

    \u7ba1\u7406\u5e94\u7528\u7a0b\u5e8f\u3001\u542f\u52a8\u5e94\u7528\u548c\u67e5\u8be2\u7cfb\u7edf\u4fe1\u606f\u3002

    "},{"location":"qsl4a/system/application/#_2","title":"\u5e94\u7528\u7a0b\u5e8f\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getapplicationinfo","title":"getApplicationInfo()","text":"

    \u83b7\u53d6\u5e94\u7528\u4fe1\u606f\u3002

    getApplicationInfo(packageName=None)\n

    \u53c2\u6570\uff1a - packageName (str): \u5305\u540d\uff08None = \u5f53\u524d\u5e94\u7528\uff09

    \u8fd4\u56de\uff1a \u5e94\u7528\u4fe1\u606f\u5b57\u5178

    "},{"location":"qsl4a/system/application/#getinstalledpackages","title":"getInstalledPackages()","text":"

    \u83b7\u53d6\u5df2\u5b89\u88c5\u5305\u5217\u8868\u3002

    getInstalledPackages(flag=4)\n

    \u53c2\u6570\uff1a - flag (int): \u5305\u6807\u5fd7\u8fc7\u6ee4\u5668\uff08\u9ed8\u8ba4\uff1a4\uff09

    \u8fd4\u56de\uff1a \u5df2\u5b89\u88c5\u5305\u5217\u8868

    "},{"location":"qsl4a/system/application/#getrunningpackages","title":"getRunningPackages()","text":"

    \u5217\u51fa\u6b63\u5728\u8fd0\u884c\u7684\u5305\u3002

    getRunningPackages()\n

    \u8fd4\u56de\uff1a \u5305\u540d\u5217\u8868

    "},{"location":"qsl4a/system/application/#getlaunchablepackages","title":"getLaunchablePackages()","text":"

    \u83b7\u53d6\u53ef\u542f\u52a8\u5305\u5217\u8868\u3002

    getLaunchablePackages(needClassName=False)\n

    \u53c2\u6570\uff1a - needClassName (bool): \u5305\u542b\u4e3b activity \u7c7b\u540d\uff08\u9ed8\u8ba4\uff1aFalse\uff09

    \u8fd4\u56de\uff1a \u53ef\u542f\u52a8\u5305\u540d\u5217\u8868\u6216\u5305\u542b\u7c7b\u540d\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/application/#_3","title":"\u5e94\u7528\u63a7\u5236","text":""},{"location":"qsl4a/system/application/#launch","title":"launch()","text":"

    \u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u3002

    launch(classname=None, packagename=None, wait=True)\n

    \u53c2\u6570\uff1a - classname (str): \u4e3b activity \u7c7b\u540d - packagename (str): \u5305\u540d - wait (bool): \u7b49\u5f85\u542f\u52a8\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

    \u8fd4\u56de\uff1a \u542f\u52a8\u7ed3\u679c

    "},{"location":"qsl4a/system/application/#forcestoppackage","title":"forceStopPackage()","text":"

    \u5f3a\u5236\u505c\u6b62\u5e94\u7528\u7a0b\u5e8f\u3002

    forceStopPackage(packageName)\n

    \u53c2\u6570\uff1a - packageName (str): \u8981\u505c\u6b62\u7684\u5305\u540d

    "},{"location":"qsl4a/system/application/#_4","title":"\u7248\u672c\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getpackageversion","title":"getPackageVersion()","text":"

    \u83b7\u53d6\u5e94\u7528\u7248\u672c\u540d\u79f0\u3002

    getPackageVersion(packageName)\n

    \u8fd4\u56de\uff1a \u7248\u672c\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"3.2.1\"\uff09

    "},{"location":"qsl4a/system/application/#getpackageversioncode","title":"getPackageVersionCode()","text":"

    \u83b7\u53d6\u5e94\u7528\u7248\u672c\u4ee3\u7801\u3002

    getPackageVersionCode(packageName)\n

    \u8fd4\u56de\uff1a \u7248\u672c\u4ee3\u7801\u6574\u6570

    "},{"location":"qsl4a/system/application/#getconstants","title":"getConstants()","text":"

    \u83b7\u53d6\u7c7b\u5e38\u91cf\u3002

    getConstants(classname)\n

    \u53c2\u6570\uff1a - classname (str): \u5b8c\u6574\u7c7b\u540d

    \u8fd4\u56de\uff1a \u5e38\u91cf\u540d\u548c\u503c\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/application/#_5","title":"\u7cfb\u7edf\u529f\u80fd","text":""},{"location":"qsl4a/system/application/#backgroundprotect","title":"backgroundProtect()","text":"

    \u542f\u7528\u6216\u7981\u7528\u5e94\u7528\u7684\u540e\u53f0\u4fdd\u62a4\u3002

    backgroundProtect(enabled=True)\n

    \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\u4fdd\u62a4\uff0cFalse \u7981\u7528

    "},{"location":"qsl4a/system/application/#createscriptshortcut","title":"createScriptShortCut()","text":"

    \u4e3a\u811a\u672c\u521b\u5efa\u4e3b\u5c4f\u5e55\u5feb\u6377\u65b9\u5f0f\u3002

    createScriptShortCut(scriptPath, label=None, iconPath=None, scriptArg=None)\n

    \u53c2\u6570\uff1a - scriptPath (str): Python \u811a\u672c\u8def\u5f84 - label (str, optional): \u5feb\u6377\u65b9\u5f0f\u6807\u7b7e - iconPath (str, optional): \u56fe\u6807\u56fe\u50cf\u8def\u5f84 - scriptArg (str, optional): \u4f20\u9012\u7ed9\u811a\u672c\u7684\u53c2\u6570

    "},{"location":"qsl4a/system/application/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getandroidid","title":"getAndroidID()","text":"

    \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

    getAndroidID()\n

    \u8fd4\u56de\uff1a \u552f\u4e00\u7684 Android \u8bbe\u5907 ID \u5b57\u7b26\u4e32

    "},{"location":"qsl4a/system/application/#getsysinfo","title":"getSysInfo()","text":"

    \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\u3002

    getSysInfo()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/application/#getlocale","title":"getLocale()","text":"

    \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u3002

    getLocale()\n

    \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

    "},{"location":"qsl4a/system/application/#getharmonyosinformation","title":"getHarmonyOsInformation()","text":"

    \u5982\u679c\u5728 HarmonyOS \u4e0a\u8fd0\u884c\uff0c\u83b7\u53d6 HarmonyOS \u4fe1\u606f\u3002

    getHarmonyOsInformation()\n

    \u8fd4\u56de\uff1a HarmonyOS \u7248\u672c\u4fe1\u606f\u6216 None

    "},{"location":"qsl4a/system/application/#isexternalstoragemanager","title":"isExternalStorageManager()","text":"

    \u68c0\u67e5\u5e94\u7528\u662f\u5426\u6709\u5916\u90e8\u5b58\u50a8\u7ba1\u7406\u5668\u6743\u9650\u3002

    isExternalStorageManager()\n

    \u8fd4\u56de\uff1a \u5982\u679c\u6709\u6743\u9650\u5219\u4e3a True

    "},{"location":"qsl4a/system/application/#_7","title":"\u5185\u5b58\u548c\u663e\u793a","text":""},{"location":"qsl4a/system/application/#getmemoryinfo","title":"getMemoryInfo()","text":"

    \u83b7\u53d6\u5185\u5b58\u4fe1\u606f\u3002

    getMemoryInfo()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/application/#getscreeninfo","title":"getScreenInfo()","text":"

    \u83b7\u53d6\u5c4f\u5e55\u4fe1\u606f\u3002

    getScreenInfo()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/application/#_8","title":"\u6743\u9650","text":""},{"location":"qsl4a/system/application/#checkpermissions","title":"checkPermissions()","text":"

    \u68c0\u67e5\u5f53\u524d\u5e94\u7528\u6743\u9650\u3002

    checkPermissions()\n

    \u8fd4\u56de\uff1a \u6743\u9650\u53ca\u5176\u72b6\u6001\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/application/#requestpermissions","title":"requestPermissions()","text":"

    \u5411\u7528\u6237\u8bf7\u6c42\u6743\u9650\u3002

    requestPermissions(permissions=None)\n

    \u53c2\u6570\uff1a - permissions (list, optional): \u8981\u8bf7\u6c42\u7684\u6743\u9650\u5217\u8868\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8bf7\u6c42\u6240\u6709\u9700\u8981\u7684\u6743\u9650\u3002

    \u8fd4\u56de\uff1a \u6743\u9650\u8bf7\u6c42\u7ed3\u679c

    "},{"location":"qsl4a/system/application/#_9","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/system/application/#showscreenlock","title":"showScreenLock()","text":"

    \u663e\u793a\u5c4f\u5e55\u9501\u5b9a\uff08PIN/\u56fe\u6848/\u5bc6\u7801\u8f93\u5165\uff09\u3002

    showScreenLock()\n
    "},{"location":"qsl4a/system/application/#_10","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\ninfo = droid.getSysInfo().result\nprint(f\"System: {info}\")\n\n# \u83b7\u53d6\u5e94\u7528\u7248\u672c\nversion = droid.getPackageVersion(\"org.qpython.qpy\").result\nprint(f\"QPython version: {version}\")\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u5e94\u7528\napps = droid.getInstalledPackages().result\nprint(f\"Installed apps: {len(apps)}\")\n\n# \u542f\u52a8\u5e94\u7528\ndroid.launch(packagename=\"com.android.settings\")\n\n# \u68c0\u67e5\u6743\u9650\nperms = droid.checkPermissions().result\nprint(f\"Permissions: {perms}\")\n\n# \u8bf7\u6c42\u5b58\u50a8\u6743\u9650\ndroid.requestPermissions([\"android.permission.READ_EXTERNAL_STORAGE\"])\n\n# \u521b\u5efa\u5feb\u6377\u65b9\u5f0f\ndroid.createScriptShortCut(\n    \"/sdcard/my_script.py\",\n    label=\"My Script\",\n    iconPath=\"/sdcard/icon.png\"\n)\n
    "},{"location":"qsl4a/system/battery/","title":"\u7535\u6c60 API","text":"

    \u76d1\u63a7\u8bbe\u5907\u7535\u6c60\u72b6\u6001\u548c\u5065\u5eb7\u72b6\u51b5\u3002

    "},{"location":"qsl4a/system/battery/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/battery/#readbatterydata","title":"readBatteryData()","text":"

    \u83b7\u53d6\u5b8c\u6574\u7684\u7535\u6c60\u4fe1\u606f\u3002

    readBatteryData()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u7535\u6c60\u6570\u636e\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/battery/#batterystartmonitoring","title":"batteryStartMonitoring()","text":"

    \u5f00\u59cb\u7535\u6c60\u76d1\u63a7\u3002

    batteryStartMonitoring()\n
    "},{"location":"qsl4a/system/battery/#batterystopmonitoring","title":"batteryStopMonitoring()","text":"

    \u505c\u6b62\u7535\u6c60\u76d1\u63a7\u3002

    batteryStopMonitoring()\n
    "},{"location":"qsl4a/system/battery/#batterygetlevel","title":"batteryGetLevel()","text":"

    \u83b7\u53d6\u7535\u6c60\u767e\u5206\u6bd4\u3002

    batteryGetLevel()\n

    \u8fd4\u56de\uff1a \u6574\u6570\uff080-100\uff09

    "},{"location":"qsl4a/system/battery/#batterygetstatus","title":"batteryGetStatus()","text":"

    \u83b7\u53d6\u5145\u7535\u72b6\u6001\u3002

    batteryGetStatus()\n

    \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u5145\u7535\u4e2d - 3: \u653e\u7535\u4e2d - 4: \u672a\u5145\u7535 - 5: \u5df2\u5145\u6ee1

    "},{"location":"qsl4a/system/battery/#batterygetplugtype","title":"batteryGetPlugType()","text":"

    \u83b7\u53d6\u7535\u6e90\u7c7b\u578b\u3002

    batteryGetPlugType()\n

    \u8fd4\u56de\uff1a - -1: \u672a\u77e5 - 0: \u672a\u63d2\u7535 - 1: AC \u5145\u7535\u5668 - 2: USB \u7aef\u53e3

    "},{"location":"qsl4a/system/battery/#batterygethealth","title":"batteryGetHealth()","text":"

    \u83b7\u53d6\u7535\u6c60\u5065\u5eb7\u72b6\u51b5\u3002

    batteryGetHealth()\n

    \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u826f\u597d - 3: \u8fc7\u70ed - 4: \u635f\u574f - 5: \u8fc7\u538b - 6: \u672a\u6307\u5b9a\u7684\u6545\u969c

    "},{"location":"qsl4a/system/battery/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\nlevel = droid.batteryGetLevel().result\nprint(f\"Battery: {level}%\")\n
    "},{"location":"qsl4a/system/qpyinterface/","title":"QPython \u63a5\u53e3 API","text":"

    \u4ece\u5176\u4ed6\u5e94\u7528\u6267\u884c QPython \u811a\u672c\u548c\u7ba1\u7406\u5171\u4eab\u53d8\u91cf\u3002

    "},{"location":"qsl4a/system/qpyinterface/#_1","title":"\u811a\u672c\u6267\u884c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/qpyinterface/#executeqpy","title":"executeQPy()","text":"

    \u6267\u884c QPython \u811a\u672c\u3002

    executeQPy(path=\"\", arg=None)\n

    \u53c2\u6570\uff1a - path (str): \u811a\u672c\u6587\u4ef6\u8def\u5f84 - arg (str, optional): \u547d\u4ee4\u884c\u53c2\u6570

    \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/system/qpyinterface/#executeqpyassrv","title":"executeQPyAsSrv()","text":"

    \u4f5c\u4e3a\u670d\u52a1\u6267\u884c QPython \u811a\u672c\u3002

    executeQPyAsSrv(path=None)\n

    \u53c2\u6570\uff1a - path (str, optional): \u811a\u672c\u6587\u4ef6\u8def\u5f84

    \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/system/qpyinterface/#executeqpycode","title":"executeQPyCode()","text":"

    \u76f4\u63a5\u6267\u884c Python \u4ee3\u7801\u3002

    executeQPyCode(code=None)\n

    \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

    \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/system/qpyinterface/#executeqpycodeassrv","title":"executeQPyCodeAsSrv()","text":"

    \u4f5c\u4e3a\u670d\u52a1\u6267\u884c Python \u4ee3\u7801\u3002

    executeQPyCodeAsSrv(code=None)\n

    \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

    \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

    "},{"location":"qsl4a/system/qpyinterface/#_2","title":"\u5171\u4eab\u53d8\u91cf","text":"

    \u5171\u4eab\u53d8\u91cf\u5141\u8bb8 QPython \u4e0e\u5176\u4ed6\u5e94\u7528\u4e4b\u95f4\u8fdb\u884c\u901a\u4fe1\u3002

    "},{"location":"qsl4a/system/qpyinterface/#sharedvariableset","title":"sharedVariableSet()","text":"

    \u8bbe\u7f6e Java \u5171\u4eab\u53d8\u91cf\u3002

    sharedVariableSet(key, value)\n

    \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d - value (str): \u53d8\u91cf\u503c

    \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

    "},{"location":"qsl4a/system/qpyinterface/#sharedvariableget","title":"sharedVariableGet()","text":"

    \u83b7\u53d6 Java \u5171\u4eab\u53d8\u91cf\u3002

    sharedVariableGet(key)\n

    \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d

    \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

    "},{"location":"qsl4a/system/qpyinterface/#sharedvariableremove","title":"sharedVariableRemove()","text":"

    \u79fb\u9664 Java \u5171\u4eab\u53d8\u91cf\u3002

    sharedVariableRemove(key)\n

    \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u53d8\u91cf\u540d

    \u8fd4\u56de\uff1a \u88ab\u79fb\u9664\u7684\u503c

    "},{"location":"qsl4a/system/qpyinterface/#getlastlog","title":"getLastLog()","text":"

    \u83b7\u53d6 QPython \u7684\u6700\u540e\u65e5\u5fd7\u8f93\u51fa\u3002

    getLastLog()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u65e5\u5fd7\u5185\u5bb9

    "},{"location":"qsl4a/system/qpyinterface/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c\u811a\u672c\ndroid.executeQPy(\"/sdcard/my_script.py\", arg=\"test\")\n\n# \u76f4\u63a5\u6267\u884c\u4ee3\u7801\ncode = \"print('Hello from QPython!')\"\ndroid.executeQPyCode(code)\n\n# \u4f7f\u7528\u5171\u4eab\u53d8\u91cf\ndroid.sharedVariableSet(\"username\", \"alice\")\nusername = droid.sharedVariableGet(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u79fb\u9664\u53d8\u91cf\ndroid.sharedVariableRemove(\"username\")\n\n# \u83b7\u53d6\u6700\u8fd1\u65e5\u5fd7\nlog = droid.getLastLog().result\nprint(f\"Log: {log}\")\n
    "},{"location":"qsl4a/system/sensors/","title":"\u4f20\u611f\u5668 API","text":"

    \u8bbf\u95ee\u8bbe\u5907\u4f20\u611f\u5668\uff0c\u5305\u62ec\u52a0\u901f\u5ea6\u8ba1\u3001\u9640\u87ba\u4eea\u3001\u78c1\u529b\u8ba1\u7b49\u3002

    "},{"location":"qsl4a/system/sensors/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/sensors/#startsensingtimed","title":"startSensingTimed()","text":"

    \u5f00\u59cb\u4f20\u611f\u5668\u76d1\u63a7\u5e76\u8bbe\u7f6e\u65f6\u95f4\u95f4\u9694\u3002

    startSensingTimed(sensorNumber, delayTime)\n

    \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID\uff08\u901a\u5e38\u4e3a 1-3\uff09 - delayTime (int): \u8bfb\u53d6\u4e4b\u95f4\u7684\u5ef6\u8fdf\uff08\u6beb\u79d2\uff09

    "},{"location":"qsl4a/system/sensors/#startsensingthreshold","title":"startSensingThreshold()","text":"

    \u5f00\u59cb\u5e26\u9608\u503c\u89e6\u53d1\u7684\u4f20\u611f\u5668\u76d1\u63a7\u3002

    startSensingThreshold(sensorNumber, threshold, axis)\n

    \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID - threshold (float): \u89e6\u53d1\u9608\u503c - axis (int): \u8981\u76d1\u63a7\u7684\u8f74\uff080=X\uff0c1=Y\uff0c2=Z\uff09

    "},{"location":"qsl4a/system/sensors/#stopsensing","title":"stopSensing()","text":"

    \u505c\u6b62\u6240\u6709\u4f20\u611f\u5668\u76d1\u63a7\u3002

    stopSensing()\n
    "},{"location":"qsl4a/system/sensors/#readsensors","title":"readSensors()","text":"

    \u8bfb\u53d6\u5f53\u524d\u4f20\u611f\u5668\u6570\u636e\u3002

    readSensors()\n

    \u8fd4\u56de\uff1a \u4f20\u611f\u5668\u6570\u636e\u5b57\u5178

    "},{"location":"qsl4a/system/sensors/#sensorsreadaccelerometer","title":"sensorsReadAccelerometer()","text":"

    \u8bfb\u53d6\u52a0\u901f\u5ea6\u8ba1\u503c\u3002

    sensorsReadAccelerometer()\n

    \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d m/s\u00b2

    "},{"location":"qsl4a/system/sensors/#sensorsreadgyroscope","title":"sensorsReadGyroscope()","text":"

    \u8bfb\u53d6\u9640\u87ba\u4eea\u503c\u3002

    sensorsReadGyroscope()\n

    \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d rad/s

    "},{"location":"qsl4a/system/sensors/#sensorsreadmagnetometer","title":"sensorsReadMagnetometer()","text":"

    \u8bfb\u53d6\u78c1\u573a\u503c\u3002

    sensorsReadMagnetometer()\n

    \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d \u03bcT

    "},{"location":"qsl4a/system/sensors/#sensorsreadorientation","title":"sensorsReadOrientation()","text":"

    \u8bfb\u53d6\u8bbe\u5907\u65b9\u5411\u3002

    sensorsReadOrientation()\n

    \u8fd4\u56de\uff1a \u5217\u8868 [azimuth, pitch, roll]\uff0c\u5355\u4f4d\u5ea6

    "},{"location":"qsl4a/system/sensors/#sensorsgetlight","title":"sensorsGetLight()","text":"

    \u8bfb\u53d6\u5149\u4f20\u611f\u5668\u503c\u3002

    sensorsGetLight()\n

    \u8fd4\u56de\uff1a \u5149\u7ea7\u522b\uff08lux\uff09

    "},{"location":"qsl4a/system/sensors/#sensorsgetstepcounter","title":"sensorsGetStepCounter()","text":"

    \u8bfb\u53d6\u6b65\u8ba1\u6570\u5668\u3002

    sensorsGetStepCounter()\n

    \u8fd4\u56de\uff1a \u6b65\u6570

    "},{"location":"qsl4a/system/sensors/#sensorsgetaccuracy","title":"sensorsGetAccuracy()","text":"

    \u83b7\u53d6\u5f53\u524d\u4f20\u611f\u5668\u7cbe\u5ea6\u3002

    sensorsGetAccuracy()\n

    \u8fd4\u56de\uff1a \u7cbe\u5ea6\u503c\uff080-3\uff1aUNRELIABLE\u3001ACCURACY_LOW\u3001ACCURACY_MEDIUM\u3001ACCURACY_HIGH\uff09

    "},{"location":"qsl4a/system/sensors/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u8bfb\u53d6\u4f20\u611f\u5668 10 \u6b21\nfor i in range(10):\n    accel = droid.sensorsReadAccelerometer().result\n    print(f\"Accel: X={accel[0]:.2f}, Y={accel[1]:.2f}, Z={accel[2]:.2f}\")\n    time.sleep(0.5)\n\ndroid.stopSensing()\n
    "},{"location":"qsl4a/system/settings/","title":"\u8bbe\u7f6e API","text":"

    \u63a7\u5236\u7cfb\u7edf\u8bbe\u7f6e\uff0c\u5305\u62ec\u5c4f\u5e55\u3001\u58f0\u97f3\u548c\u7f51\u7edc\u8bbe\u7f6e\u3002

    "},{"location":"qsl4a/system/settings/#_1","title":"\u5c4f\u5e55\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#setscreentimeout","title":"setScreenTimeout()","text":"

    \u8bbe\u7f6e\u5c4f\u5e55\u8d85\u65f6\u503c\u3002

    setScreenTimeout(value)\n

    \u53c2\u6570\uff1a - value (int): \u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

    \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u8d85\u65f6\u503c

    "},{"location":"qsl4a/system/settings/#getscreentimeout","title":"getScreenTimeout()","text":"

    \u83b7\u53d6\u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u3002

    getScreenTimeout()\n

    \u8fd4\u56de\uff1a \u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

    "},{"location":"qsl4a/system/settings/#getscreenbrightness","title":"getScreenBrightness()","text":"

    \u83b7\u53d6\u5c4f\u5e55\u4eae\u5ea6\u503c\u3002

    getScreenBrightness()\n

    \u8fd4\u56de\uff1a \u4eae\u5ea6\u503c\uff080-255\uff09

    "},{"location":"qsl4a/system/settings/#setscreenbrightness","title":"setScreenBrightness()","text":"

    \u8bbe\u7f6e\u5c4f\u5e55\u4eae\u5ea6\u3002

    setScreenBrightness(value=None)\n

    \u53c2\u6570\uff1a - value (int, optional): \u4eae\u5ea6\u503c\uff080-255\uff09\uff0c\u6216 None \u8868\u793a\u81ea\u52a8

    \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u4eae\u5ea6\u503c

    "},{"location":"qsl4a/system/settings/#checkscreenon","title":"checkScreenOn()","text":"

    \u68c0\u67e5\u5c4f\u5e55\u662f\u5426\u4eae\u7740\u3002

    checkScreenOn()\n

    \u8fd4\u56de\uff1a \u5982\u679c\u5c4f\u5e55\u4eae\u7740\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

    "},{"location":"qsl4a/system/settings/#_2","title":"\u98de\u884c\u6a21\u5f0f","text":""},{"location":"qsl4a/system/settings/#checkairplanemode","title":"checkAirplaneMode()","text":"

    \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\u662f\u5426\u542f\u7528\u3002

    checkAirplaneMode()\n

    \u8fd4\u56de\uff1a \u5982\u679c\u98de\u884c\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

    "},{"location":"qsl4a/system/settings/#_3","title":"\u94c3\u58f0\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#checkringersilentmode","title":"checkRingerSilentMode()","text":"

    \u68c0\u67e5\u94c3\u58f0\u662f\u5426\u5904\u4e8e\u9759\u97f3\u6a21\u5f0f\u3002

    checkRingerSilentMode()\n

    \u8fd4\u56de\uff1a \u5982\u679c\u9759\u97f3\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

    "},{"location":"qsl4a/system/settings/#toggleringersilentmode","title":"toggleRingerSilentMode()","text":"

    \u5207\u6362\u94c3\u58f0\u9759\u97f3\u6a21\u5f0f\u3002

    toggleRingerSilentMode(enabled=None)\n

    \u53c2\u6570\uff1a - enabled (bool, optional): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

    \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

    "},{"location":"qsl4a/system/settings/#togglevibratemode","title":"toggleVibrateMode()","text":"

    \u5207\u6362\u632f\u52a8\u6a21\u5f0f\u3002

    toggleVibrateMode(enabled=None, ringer=None)\n

    \u53c2\u6570\uff1a - enabled (bool, optional): \u5207\u6362\u632f\u52a8\u5f00/\u5173 - ringer (bool, optional): \u5e94\u7528\u4e8e\u94c3\u58f0\u6a21\u5f0f

    \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

    "},{"location":"qsl4a/system/settings/#getvibratemode","title":"getVibrateMode()","text":"

    \u83b7\u53d6\u632f\u52a8\u6a21\u5f0f\u8bbe\u7f6e\u3002

    getVibrateMode(ringer=None)\n

    \u53c2\u6570\uff1a - ringer (bool, optional): \u68c0\u67e5\u94c3\u58f0\u632f\u52a8\u6a21\u5f0f

    \u8fd4\u56de\uff1a \u5982\u679c\u632f\u52a8\u5df2\u542f\u7528\u5219\u4e3a True

    "},{"location":"qsl4a/system/settings/#_4","title":"\u97f3\u91cf\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#getringervolume","title":"getRingerVolume()","text":"

    \u83b7\u53d6\u5f53\u524d\u94c3\u58f0\u97f3\u91cf\u3002

    getRingerVolume()\n

    \u8fd4\u56de\uff1a \u94c3\u58f0\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-7\uff09

    "},{"location":"qsl4a/system/settings/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

    \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

    getMaxRingerVolume()\n

    \u8fd4\u56de\uff1a \u6700\u5927\u94c3\u58f0\u97f3\u91cf

    "},{"location":"qsl4a/system/settings/#setringervolume","title":"setRingerVolume()","text":"

    \u8bbe\u7f6e\u94c3\u58f0\u97f3\u91cf\u3002

    setRingerVolume(volume)\n

    \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

    "},{"location":"qsl4a/system/settings/#getmediavolume","title":"getMediaVolume()","text":"

    \u83b7\u53d6\u5f53\u524d\u5a92\u4f53\u97f3\u91cf\u3002

    getMediaVolume()\n

    \u8fd4\u56de\uff1a \u5a92\u4f53\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-15\uff09

    "},{"location":"qsl4a/system/settings/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

    \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

    getMaxMediaVolume()\n

    \u8fd4\u56de\uff1a \u6700\u5927\u5a92\u4f53\u97f3\u91cf

    "},{"location":"qsl4a/system/settings/#setmediavolume","title":"setMediaVolume()","text":"

    \u8bbe\u7f6e\u5a92\u4f53\u97f3\u91cf\u3002

    setMediaVolume(volume)\n

    \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

    "},{"location":"qsl4a/system/settings/#_5","title":"\u7cfb\u7edf\u4fe1\u606f","text":""},{"location":"qsl4a/system/settings/#elapsedrealtimenanos","title":"elapsedRealtimeNanos()","text":"

    \u83b7\u53d6\u81ea\u7cfb\u7edf\u542f\u52a8\u4ee5\u6765\u7684\u7eb3\u79d2\u6570\u3002

    elapsedRealtimeNanos()\n

    \u8fd4\u56de\uff1a \u7eb3\u79d2\u6570\uff08\u53ef\u7528\u4e8e\u8ba1\u65f6\uff09

    "},{"location":"qsl4a/system/settings/#gettrafficstats","title":"getTrafficStats()","text":"

    \u83b7\u53d6\u7f51\u7edc\u6d41\u91cf\u7edf\u8ba1\u3002

    getTrafficStats(flags=7)\n

    \u53c2\u6570\uff1a - flags (int): \u8981\u68c0\u7d22\u7684\u7edf\u8ba1\uff08\u9ed8\u8ba4\uff1a7 = \u5168\u90e8\uff09

    \u8fd4\u56de\uff1a \u5305\u542b\u53d1\u9001/\u63a5\u6536\u5b57\u8282\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/settings/#getapptxbytes","title":"getAppTxBytes()","text":"

    \u83b7\u53d6 QPython \u5e94\u7528\u7684\u53d1\u9001\u5b57\u8282\u3002

    getAppTxBytes(packageName)\n

    \u53c2\u6570\uff1a - packageName (str): \u5305\u540d

    \u8fd4\u56de\uff1a \u5305\u542b tx/rx \u5b57\u8282\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/settings/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5c4f\u5e55\u8bbe\u7f6e\ncurrent_timeout = droid.getScreenTimeout().result\nprint(f\"Current timeout: {current_timeout}s\")\ndroid.setScreenTimeout(30)\n\n# \u68c0\u67e5\u5c4f\u5e55\nif droid.checkScreenOn().result:\n    print(\"Screen is on\")\n\n# \u97f3\u91cf\u63a7\u5236\nmedia_vol = droid.getMediaVolume().result\nprint(f\"Media volume: {media_vol}\")\ndroid.setMediaVolume(10)\n\n# \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\nif droid.checkAirplaneMode().result:\n    print(\"Airplane mode is on\")\n
    "},{"location":"qsl4a/system/sysinfo/","title":"\u7cfb\u7edf\u4fe1\u606f","text":"

    \u68c0\u7d22\u8bbe\u5907\u548c\u7cfb\u7edf\u4fe1\u606f\u3002

    "},{"location":"qsl4a/system/sysinfo/#_2","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/sysinfo/#getandroidid","title":"getAndroidID()","text":"

    \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

    getAndroidID()\n

    \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

    "},{"location":"qsl4a/system/sysinfo/#getsysinfo","title":"getSysInfo()","text":"

    \u83b7\u53d6\u7efc\u5408\u7cfb\u7edf\u4fe1\u606f\u3002

    getSysInfo()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/sysinfo/#getlocale","title":"getLocale()","text":"

    \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u8bbe\u7f6e\u3002

    getLocale()\n

    \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

    "},{"location":"qsl4a/system/sysinfo/#_3","title":"\u5185\u5b58","text":""},{"location":"qsl4a/system/sysinfo/#getmemoryinfo","title":"getMemoryInfo()","text":"

    \u83b7\u53d6 RAM \u4fe1\u606f\u3002

    getMemoryInfo()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/sysinfo/#_4","title":"\u663e\u793a","text":""},{"location":"qsl4a/system/sysinfo/#getscreeninfo","title":"getScreenInfo()","text":"

    \u83b7\u53d6\u663e\u793a\u4fe1\u606f\u3002

    getScreenInfo()\n

    \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

    "},{"location":"qsl4a/system/sysinfo/#_5","title":"\u6807\u8bc6\u7b26","text":""},{"location":"qsl4a/system/sysinfo/#getimei","title":"getImei()","text":"

    \u83b7\u53d6\u8bbe\u5907 IMEI\u3002

    getImei(slotIndex=None)\n
    "},{"location":"qsl4a/system/sysinfo/#getmeid","title":"getMeid()","text":"

    \u83b7\u53d6\u8bbe\u5907 MEID\u3002

    getMeid(slotIndex=None)\n
    "},{"location":"qsl4a/system/sysinfo/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u8bbe\u5907 ID\nandroid_id = droid.getAndroidID().result\nprint(f\"Android ID: {android_id}\")\n\n# \u5c4f\u5e55\u4fe1\u606f\nscreen = droid.getScreenInfo().result\nprint(f\"Screen: {screen['width']}x{screen['height']}\")\n\n# \u5185\u5b58\nmemory = droid.getMemoryInfo().result\nprint(f\"Memory: {memory}\")\n
    "},{"location":"qsl4a/system/wakelock/","title":"WakeLock API","text":"

    \u63a7\u5236\u8bbe\u5907\u5524\u9192\u9501\u4ee5\u4fdd\u6301 CPU \u6216\u5c4f\u5e55\u5f00\u542f\u3002

    "},{"location":"qsl4a/system/wakelock/#wake-lock","title":"Wake Lock \u7c7b\u578b","text":"

    QSL4A \u63d0\u4f9b\u4e0d\u540c\u7c7b\u578b\u7684\u5524\u9192\u9501\uff1a

    \u7c7b\u578b \u63cf\u8ff0 Full CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae Partial \u4ec5 CPU \u5f00\u542f Bright CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae Dim CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697"},{"location":"qsl4a/system/wakelock/#wake-lock_1","title":"Wake Lock \u65b9\u6cd5","text":""},{"location":"qsl4a/system/wakelock/#wakelockacquirefull","title":"wakeLockAcquireFull()","text":"

    \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae\uff09\u3002

    wakeLockAcquireFull()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockacquirepartial","title":"wakeLockAcquirePartial()","text":"

    \u83b7\u53d6\u90e8\u5206\u5524\u9192\u9501\uff08\u4ec5 CPU \u5f00\u542f\uff09\u3002

    wakeLockAcquirePartial()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockacquirebright","title":"wakeLockAcquireBright()","text":"

    \u83b7\u53d6\u660e\u4eae\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff09\u3002

    wakeLockAcquireBright()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockacquiredim","title":"wakeLockAcquireDim()","text":"

    \u83b7\u53d6\u6697\u6de1\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697\uff09\u3002

    wakeLockAcquireDim()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockrelease","title":"wakeLockRelease()","text":"

    \u91ca\u653e\u5524\u9192\u9501\u3002

    wakeLockRelease()\n
    "},{"location":"qsl4a/system/wakelock/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\ndroid.wakeLockAcquireFull()\n\n# \u5728\u4fdd\u6301\u5c4f\u5e55\u5f00\u542f\u65f6\u6267\u884c\u91cd\u8981\u5de5\u4f5c\nprint(\"Screen will stay on\")\ntime.sleep(10)\n\n# \u5b8c\u6210\u540e\u91ca\u653e\ndroid.wakeLockRelease()\n\n# \u6216\u4f7f\u7528\u90e8\u5206\u9501\u8fdb\u884c\u540e\u53f0\u4efb\u52a1\ndroid.wakeLockAcquirePartial()\n# \u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\uff0cCPU \u4ecd\u4fdd\u6301\u5f00\u542f\ntime.sleep(30)\ndroid.wakeLockRelease()\n

    \u6ce8\u610f\uff1a \u8bb0\u4f4f\u5728\u4e0d\u9700\u8981\u65f6\u91ca\u653e\u5524\u9192\u9501\u4ee5\u8282\u7701\u7535\u6c60\u3002

    "},{"location":"qsl4a/ui/accessibility/","title":"\u65e0\u969c\u788d\u670d\u52a1","text":"

    \u65e0\u969c\u788d\u670d\u52a1\u5141\u8bb8\u81ea\u52a8\u5316 UI \u4ea4\u4e92\uff0c\u5982\u70b9\u51fb\u3001\u6ed1\u52a8\u548c\u7cfb\u7edf\u64cd\u4f5c\u3002

    "},{"location":"qsl4a/ui/accessibility/#_2","title":"\u670d\u52a1\u63a7\u5236","text":""},{"location":"qsl4a/ui/accessibility/#accessibilitystartservice","title":"accessibilityStartService()","text":"

    \u542f\u52a8\u65e0\u969c\u788d\u670d\u52a1\u3002

    accessibilityStartService()\n

    \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

    "},{"location":"qsl4a/ui/accessibility/#accessibilityserviceenabled","title":"accessibilityServiceEnabled()","text":"

    \u68c0\u67e5\u65e0\u969c\u788d\u670d\u52a1\u662f\u5426\u5df2\u542f\u7528\u3002

    accessibilityServiceEnabled()\n

    \u8fd4\u56de\uff1a True \u6216 False

    "},{"location":"qsl4a/ui/accessibility/#_3","title":"\u5c4f\u5e55\u4ea4\u4e92","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityclick","title":"accessibilityClick()","text":"

    \u5728\u5c4f\u5e55\u5750\u6807\u5904\u70b9\u51fb\u3002

    accessibilityClick(x=0, y=0, t=50)\n

    \u53c2\u6570\uff1a - x (int/float): X \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - y (int/float): Y \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - t (int): \u6309\u4f4f\u65f6\u957f\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a50\uff09

    "},{"location":"qsl4a/ui/accessibility/#accessibilityslide","title":"accessibilitySlide()","text":"

    \u591a\u70b9\u6ed1\u52a8\u624b\u52bf\u3002

    accessibilitySlide(XnYn=None, t=None)\n

    \u53c2\u6570\uff1a - XnYn (list): \u5750\u6807 [X1, Y1, X2, Y2, ... Xn, Yn] - t (int): \u6ed1\u52a8\u65f6\u957f\uff08\u9ed8\u8ba4\uff1a50*n \u6beb\u79d2\uff09

    "},{"location":"qsl4a/ui/accessibility/#_4","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityaction","title":"accessibilityAction()","text":"

    \u6309\u4ee3\u7801\u6267\u884c\u7cfb\u7edf\u64cd\u4f5c\u3002

    accessibilityAction(actionCode)\n

    \u64cd\u4f5c\u4ee3\u7801\uff1a | \u4ee3\u7801 | \u5e38\u91cf | \u63cf\u8ff0 | |------|----------|-------------| | 1 | BACK | \u8fd4\u56de\u6309\u94ae | | 2 | HOME | \u4e3b\u5c4f\u5e55\u6309\u94ae | | 3 | RECENTS | \u6700\u8fd1\u5e94\u7528 | | 4 | NOTIFICATIONS | \u6253\u5f00\u901a\u77e5 | | 5 | QUICK_SETTINGS | \u6253\u5f00\u5feb\u901f\u8bbe\u7f6e | | 6 | POWER_DIALOG | \u7535\u6e90\u83dc\u5355 | | 7 | TOGGLE_SPLIT_SCREEN | \u5206\u5c4f | | 8 | LOCK_SCREEN | \u9501\u5c4f | | 9 | TAKE_SCREENSHOT | \u622a\u56fe | | 10 | KEYCODE_HEADSETHOOK | \u8033\u673a\u6302\u94a9 | | 11-14 | ACCESSIBILITY_ | \u65e0\u969c\u788d\u6309\u94ae | | 15 | DISMISS_NOTIFICATION_SHADE | \u5173\u95ed\u901a\u77e5\u680f | | 16-20 | DPAD_ | \u65b9\u5411\u952e | | 21 | MENU | \u83dc\u5355\u6309\u94ae | | 22 | MEDIA_PLAY_PAUSE | \u64ad\u653e/\u6682\u505c\u5a92\u4f53 |

    "},{"location":"qsl4a/ui/accessibility/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/accessibility/#_6","title":"\u70b9\u51fb\u5c4f\u5e55\u4e2d\u5fc3","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u670d\u52a1\nif not droid.accessibilityServiceEnabled().result:\n    droid.accessibilityStartService()\n\n# \u70b9\u51fb\u4e2d\u5fc3\uff080,0 = \u4e2d\u5fc3\uff09\ndroid.accessibilityClick(0, 0, t=100)\n
    "},{"location":"qsl4a/ui/accessibility/#_7","title":"\u6ed1\u52a8\u624b\u52bf","text":"
    # \u4ece\u4e0b\u5f80\u4e0a\u6ed1\u52a8\uff08\u5411\u4e0a\u6eda\u52a8\uff09\ndroid.accessibilitySlide([0, 1.5, 0, -1.5], t=300)\n
    "},{"location":"qsl4a/ui/accessibility/#_8","title":"\u7cfb\u7edf\u5bfc\u822a","text":"
    # \u6309\u4e3b\u5c4f\u5e55\ndroid.accessibilityAction(2)\n\n# \u6309\u8fd4\u56de\ndroid.accessibilityAction(1)\n\n# \u6253\u5f00\u901a\u77e5\ndroid.accessibilityAction(4)\n
    "},{"location":"qsl4a/ui/accessibility/#_9","title":"\u70b9\u51fb\u7279\u5b9a\u4f4d\u7f6e","text":"
    # \u70b9\u51fb\u5c4f\u5e55\u5750\u6807 (500, 800)\ndroid.accessibilityClick(500, 800)\n\n# \u70b9\u51fb\u76f8\u5bf9\u4f4d\u7f6e\uff08\u6c34\u5e73\u5c45\u4e2d\uff0c\u5782\u76f4 3/4 \u5904\uff09\ndroid.accessibilityClick(0, 1.5)\n
    "},{"location":"qsl4a/ui/dialogs/","title":"\u5bf9\u8bdd\u6846\u7cfb\u7edf","text":"

    QSL4A \u63d0\u4f9b\u5168\u9762\u7684\u5bf9\u8bdd\u6846\u652f\u6301\uff0c\u7528\u4e8e\u7528\u6237\u4ea4\u4e92\uff0c\u5305\u62ec\u8b66\u62a5\u3001\u8f93\u5165\u5bf9\u8bdd\u6846\u3001\u9009\u62e9\u5bf9\u8bdd\u6846\u548c\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

    "},{"location":"qsl4a/ui/dialogs/#_2","title":"\u8b66\u62a5\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowalert","title":"dialogShowAlert()","text":"

    \u663e\u793a\u7b80\u5355\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

    dialogShowAlert(title=\"Alert\", message=\"The message of the alert.\",\n                positiveButtonText=\"OK\", negativeButtonText=None,\n                neutralButtonText=None, messageIsHtml=False)\n

    \u53c2\u6570\uff1a - title (str): \u5bf9\u8bdd\u6846\u6807\u9898 - message (str): \u6d88\u606f\u6587\u672c - positiveButtonText (str): \u80af\u5b9a\u6309\u94ae\u6807\u7b7e - negativeButtonText (str, optional): \u5426\u5b9a\u6309\u94ae\u6807\u7b7e - neutralButtonText (str, optional): \u4e2d\u6027\u6309\u94ae\u6807\u7b7e - messageIsHtml (bool): \u5c06\u6d88\u606f\u89e3\u6790\u4e3a HTML

    \u8fd4\u56de\uff1a \u5305\u542b\u70b9\u51fb\u6309\u94ae\u7684\u7ed3\u679c

    "},{"location":"qsl4a/ui/dialogs/#dialogshowsimplechoice","title":"dialogShowSimpleChoice()","text":"

    \u663e\u793a\u5e26\u6709\u9879\u76ee\u7684\u7b80\u5355\u9009\u62e9\u5bf9\u8bdd\u6846\u3002

    dialogShowSimpleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

    \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868

    \u8fd4\u56de\uff1a \u5305\u542b\u9009\u4e2d\u9879\u76ee\u7684\u7ed3\u679c

    "},{"location":"qsl4a/ui/dialogs/#_3","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialoggetinput","title":"dialogGetInput()","text":"

    \u83b7\u53d6\u7528\u6237\u6587\u672c\u8f93\u5165\u3002

    dialogGetInput(title=\"Value\", message=\"Please enter value:\",\n               defaultText=None, messageIsHtml=False)\n

    \u8fd4\u56de\uff1a \u5305\u542b\u7528\u6237\u8f93\u5165\u6587\u672c\u7684\u7ed3\u679c

    "},{"location":"qsl4a/ui/dialogs/#dialoggetpassword","title":"dialogGetPassword()","text":"

    \u83b7\u53d6\u5bc6\u7801\u8f93\u5165\u3002

    dialogGetPassword(title=\"Password\", message=\"Please enter password:\")\n

    \u8fd4\u56de\uff1a \u5305\u542b\u8f93\u5165\u5bc6\u7801\u7684\u7ed3\u679c

    "},{"location":"qsl4a/ui/dialogs/#dialogcreateinput","title":"dialogCreateInput()","text":"

    \u521b\u5efa\u81ea\u5b9a\u4e49\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

    dialogCreateInput(title=\"Value\", message=\"Please enter value:\",\n                  defaultText=None, inputType=None)\n

    \u53c2\u6570\uff1a - inputType (str): \u8f93\u5165\u7c7b\u578b\uff08\u4f8b\u5982 \"text\"\u3001\"number\"\u3001\"textPassword\"\uff09

    "},{"location":"qsl4a/ui/dialogs/#dialogcreatepassword","title":"dialogCreatePassword()","text":"

    \u521b\u5efa\u5bc6\u7801\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

    dialogCreatePassword(title=\"Password\", message=\"Please enter password:\")\n
    "},{"location":"qsl4a/ui/dialogs/#dialogcreateseekbar","title":"dialogCreateSeekBar()","text":"

    \u521b\u5efa\u6ed1\u5757/\u8fdb\u5ea6\u6761\u5bf9\u8bdd\u6846\u3002

    dialogCreateSeekBar(starting_value=50, maximum_value=100, title=\"\", message=\"\")\n

    \u53c2\u6570\uff1a - starting_value (int): \u521d\u59cb\u503c - maximum_value (int): \u6700\u5927\u503c

    "},{"location":"qsl4a/ui/dialogs/#_4","title":"\u9009\u62e9\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowsinglechoice","title":"dialogShowSingleChoice()","text":"

    \u663e\u793a\u5355\u9009\uff08\u5355\u9009\u6309\u94ae\uff09\u5bf9\u8bdd\u6846\u3002

    dialogShowSingleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, selected=-1, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

    \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (int): \u9ed8\u8ba4\u9009\u4e2d\u7d22\u5f15

    "},{"location":"qsl4a/ui/dialogs/#dialogshowmultichoice","title":"dialogShowMultiChoice()","text":"

    \u663e\u793a\u591a\u9009\uff08\u590d\u9009\u6846\uff09\u5bf9\u8bdd\u6846\u3002

    dialogShowMultiChoice(title=\"Alert\", message=\"The message of the alert.\",\n                      items=None, selected=None, positiveButtonText=\"OK\",\n                      negativeButtonText=None, neutralButtonText=None,\n                      messageIsHtml=False)\n

    \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (list): \u521d\u59cb\u9009\u4e2d\u7d22\u5f15\u5217\u8868

    "},{"location":"qsl4a/ui/dialogs/#dialogsetsinglechoiceitems","title":"dialogSetSingleChoiceItems()","text":"

    \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u5355\u9009\u9879\u76ee\u3002

    dialogSetSingleChoiceItems(items, selected=-1)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetmultichoiceitems","title":"dialogSetMultiChoiceItems()","text":"

    \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u591a\u9009\u9879\u76ee\u3002

    dialogSetMultiChoiceItems(items, selected=None)\n
    "},{"location":"qsl4a/ui/dialogs/#_5","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatespinnerprogress","title":"dialogCreateSpinnerProgress()","text":"

    \u521b\u5efa\u4e0d\u786e\u5b9a\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

    dialogCreateSpinnerProgress(title=None, message=None, maximum_progress=100)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogcreatehorizontalprogress","title":"dialogCreateHorizontalProgress()","text":"

    \u521b\u5efa\u6c34\u5e73\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

    dialogCreateHorizontalProgress(title=None, message=None, maximum_progress=100)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetcurrentprogress","title":"dialogSetCurrentProgress()","text":"

    \u66f4\u65b0\u8fdb\u5ea6\u503c\u3002

    dialogSetCurrentProgress(current)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetmaxprogress","title":"dialogSetMaxProgress()","text":"

    \u8bbe\u7f6e\u6700\u5927\u8fdb\u5ea6\u503c\u3002

    dialogSetMaxProgress(max)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetprogressmessage","title":"dialogSetProgressMessage()","text":"

    \u66f4\u65b0\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u6d88\u606f\u3002

    dialogSetProgressMessage(message)\n
    "},{"location":"qsl4a/ui/dialogs/#_6","title":"\u9009\u62e9\u5668\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatedatepicker","title":"dialogCreateDatePicker()","text":"

    \u521b\u5efa\u65e5\u671f\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

    dialogCreateDatePicker(year=1970, month=1, day=1)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogcreatetimepicker","title":"dialogCreateTimePicker()","text":"

    \u521b\u5efa\u65f6\u95f4\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

    dialogCreateTimePicker(hour=0, minute=0, is24hour=False)\n
    "},{"location":"qsl4a/ui/dialogs/#_7","title":"\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u521b\u5efa","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatealert","title":"dialogCreateAlert()","text":"

    \u521b\u5efa\u81ea\u5b9a\u4e49\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

    dialogCreateAlert(title=None, message=None)\n

    \u521b\u5efa\u4e00\u4e2a\u7a7a\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002\u53ef\u4e0e\u5176\u4ed6 dialogSet* \u51fd\u6570\u4e00\u8d77\u4f7f\u7528\u6765\u81ea\u5b9a\u4e49\u3002

    "},{"location":"qsl4a/ui/dialogs/#dialogsetitems","title":"dialogSetItems()","text":"

    \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u7b80\u5355\u5217\u8868\u9879\u76ee\u3002

    dialogSetItems(items)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetpositivebuttontext","title":"dialogSetPositiveButtonText()","text":"

    \u8bbe\u7f6e\u80af\u5b9a\u6309\u94ae\u6587\u672c\u3002

    dialogSetPositiveButtonText(text)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetnegativebuttontext","title":"dialogSetNegativeButtonText()","text":"

    \u8bbe\u7f6e\u5426\u5b9a\u6309\u94ae\u6587\u672c\u3002

    dialogSetNegativeButtonText(text)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetneutralbuttontext","title":"dialogSetNeutralButtonText()","text":"

    \u8bbe\u7f6e\u4e2d\u6027\u6309\u94ae\u6587\u672c\u3002

    dialogSetNeutralButtonText(text)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetmessageishtml","title":"dialogSetMessageIsHtml()","text":"

    \u8bbe\u7f6e\u6d88\u606f\u662f\u5426\u5e94\u89e3\u6790\u4e3a HTML\u3002

    dialogSetMessageIsHtml(messageIsHtml=True)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogshow","title":"dialogShow()","text":"

    \u663e\u793a\u521b\u5efa\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u3002

    dialogShow()\n
    "},{"location":"qsl4a/ui/dialogs/#_8","title":"\u5bf9\u8bdd\u6846\u63a7\u5236","text":""},{"location":"qsl4a/ui/dialogs/#dialogdismiss","title":"dialogDismiss()","text":"

    \u5173\u95ed\u5f53\u524d\u5bf9\u8bdd\u6846\u3002

    dialogDismiss()\n
    "},{"location":"qsl4a/ui/dialogs/#dialoggetresponse","title":"dialogGetResponse()","text":"

    \u83b7\u53d6\u5bf9\u8bdd\u6846\u54cd\u5e94\u3002

    dialogGetResponse()\n
    "},{"location":"qsl4a/ui/dialogs/#dialoggetselecteditems","title":"dialogGetSelectedItems()","text":"

    \u4ece\u9009\u62e9\u5bf9\u8bdd\u6846\u83b7\u53d6\u9009\u4e2d\u7684\u9879\u76ee\u3002

    dialogGetSelectedItems()\n
    "},{"location":"qsl4a/ui/dialogs/#_9","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/dialogs/#_10","title":"\u7b80\u5355\u8b66\u62a5","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a\u8b66\u62a5\ndroid.dialogShowAlert(\"Warning\", \"This is an important message!\")\n
    "},{"location":"qsl4a/ui/dialogs/#_11","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":"
    # \u83b7\u53d6\u7528\u6237\u8f93\u5165\nresult = droid.dialogGetInput(\"Name\", \"Enter your name:\", \"John\").result\nprint(f\"Hello, {result}!\")\n
    "},{"location":"qsl4a/ui/dialogs/#_12","title":"\u5e26\u6309\u94ae\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846","text":"
    # \u521b\u5efa\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\ndroid.dialogCreateAlert(\"Custom\", \"Choose an option\")\ndroid.dialogSetItems([\"Option 1\", \"Option 2\", \"Option 3\"])\ndroid.dialogShow()\n\n# \u83b7\u53d6\u54cd\u5e94\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response['item']}\")\n
    "},{"location":"qsl4a/ui/dialogs/#_13","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":"
    # \u521b\u5efa\u8fdb\u5ea6\u5bf9\u8bdd\u6846\ndroid.dialogCreateHorizontalProgress(\"Loading\", \"Please wait...\", 100)\ndroid.dialogShow()\n\n# \u66f4\u65b0\u8fdb\u5ea6\nfor i in range(101):\n    droid.dialogSetCurrentProgress(i)\n    time.sleep(0.05)\n\ndroid.dialogDismiss()\n
    "},{"location":"qsl4a/ui/dialogs/#_14","title":"\u65e5\u671f\u9009\u62e9\u5668","text":"
    # \u663e\u793a\u65e5\u671f\u9009\u62e9\u5668\ndroid.dialogCreateDatePicker(2024, 1, 15)\ndroid.dialogShow()\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response}\")\n
    "},{"location":"qsl4a/ui/floatview/","title":"\u6d6e\u52a8\u89c6\u56fe","text":"

    \u6d6e\u52a8\u7a97\u53e3\u652f\u6301\uff0c\u7528\u4e8e\u5728\u5176\u4ed6\u5e94\u7528\u7a0b\u5e8f\u4e0a\u65b9\u4fdd\u6301\u663e\u793a\u7684\u8986\u76d6 UI \u5143\u7d20\u3002

    "},{"location":"qsl4a/ui/floatview/#_2","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/floatview/#floatview","title":"floatView()","text":"

    \u663e\u793a\u6216\u4fee\u6539\u6d6e\u52a8\u89c6\u56fe\u3002

    floatView(Args=None)\n

    \u53c2\u6570\uff1a - Args (dict): \u914d\u7f6e\u5b57\u5178\uff0c\u5305\u542b\u4ee5\u4e0b\u952e\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08-1 \u521b\u5efa\u65b0\u7684\uff0c>=0 \u4fee\u6539\u73b0\u6709\u7684\uff09 - text (str): \u8981\u663e\u793a\u7684\u6587\u672c\u5185\u5bb9 - html (str): HTML \u5185\u5bb9\uff08\u5982\u679c\u7701\u7565 text \u5219\u4f7f\u7528\uff09 - width (int): \u89c6\u56fe\u5bbd\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a300\uff09 - height (int): \u89c6\u56fe\u9ad8\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a150\uff09 - x (int): X \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - y (int): Y \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - backColor (str): ARGB \u5341\u516d\u8fdb\u5236\u80cc\u666f\u8272\uff08\u9ed8\u8ba4\uff1a'7f7f7f7f'\uff09 - textColor (str): ARGB \u5341\u516d\u8fdb\u5236\u6587\u672c\u8272\uff08\u9ed8\u8ba4\uff1a'ff000000'\uff09 - textSize (int): \u6587\u672c\u5927\u5c0f\uff08\u9ed8\u8ba4\uff1a10\uff09 - textAlign (int): \u6587\u672c\u5bf9\u9f50\uff080 = \u7ee7\u627f\uff09 - script (str): \u957f\u6309\u5173\u95ed\u540e\u8fd0\u884c\u7684\u811a\u672c\u8def\u5f84 - arg: \u811a\u672c\u53c2\u6570 - clickRemove (bool): \u542f\u7528\u70b9\u51fb\u79fb\u9664\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - flag (int): \u7a97\u53e3\u6807\u5fd7\uff08\u9ed8\u8ba4\uff1a40 - \u53ef\u89e6\u6478\uff09

    \u8fd4\u56de\uff1a \u5f53\u524d\u94fe\u5217\u8868\u957f\u5ea6

    "},{"location":"qsl4a/ui/floatview/#floatviewcount","title":"floatViewCount()","text":"

    \u83b7\u53d6\u6d3b\u52a8\u6d6e\u52a8\u89c6\u56fe\u7684\u6570\u91cf\u3002

    floatViewCount()\n

    \u8fd4\u56de\uff1a \u6d6e\u52a8\u89c6\u56fe\u6570\u91cf

    "},{"location":"qsl4a/ui/floatview/#floatviewresult","title":"floatViewResult()","text":"

    \u83b7\u53d6\u6d6e\u52a8\u89c6\u56fe\u7684\u7ed3\u679c/\u72b6\u6001\u3002

    floatViewResult(index=-1)\n

    \u53c2\u6570\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1\uff0c\u8fd4\u56de\u6700\u540e\u64cd\u4f5c\u7ed3\u679c\uff09

    \u8fd4\u56de\uff1a \u5305\u542b\u64cd\u4f5c\u8be6\u60c5\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - x, y: \u4f4d\u7f6e - time: \u65f6\u95f4\u6233 - operation: \u64cd\u4f5c\u7c7b\u578b\uff08'initial'\u3001'move' \u7b49\uff09 - index: \u89c6\u56fe\u7d22\u5f15 - removed: \u5982\u679c\u89c6\u56fe\u88ab\u79fb\u9664\u5219\u4e3a True

    "},{"location":"qsl4a/ui/floatview/#floatviewremove","title":"floatViewRemove()","text":"

    \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\u3002

    floatViewRemove(index=-1)\n

    \u53c2\u6570\uff1a - index (int): \u8981\u79fb\u9664\u7684\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1 \u79fb\u9664\u6700\u540e\u4e00\u4e2a\uff09

    \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a 1\uff0c\u5426\u5219\u4e3a 0

    "},{"location":"qsl4a/ui/floatview/#_3","title":"\u5e38\u91cf","text":"
    • floatView.INDEX_NEW = -1 - \u521b\u5efa\u65b0\u7684\u6d6e\u52a8\u89c6\u56fe
    • floatView.FLAG_DEFAULT_TOUCHABLE = 40 - \u9ed8\u8ba4\u53ef\u89e6\u6478\u6807\u5fd7
    • floatView.TEXT_ALIGNMENT_INHERIT = 0
    • floatView.TEXT_ALIGNMENT_CENTER - \u5c45\u4e2d\u6587\u672c\u5bf9\u9f50
    "},{"location":"qsl4a/ui/floatview/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/floatview/#_5","title":"\u57fa\u672c\u6d6e\u52a8\u89c6\u56fe","text":"
    import androidhelper\nfrom androidhelper import Android\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u7b80\u5355\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'index': -1,  # \u521b\u5efa\u65b0\u7684\n    'text': 'Hello World',\n    'width': 400,\n    'height': 300,\n    'x': -300,  # \u4ece\u4e2d\u5fc3\u504f\u79fb\n    'y': -400,\n    'backColor': 'ff0000',  # \u7ea2\u8272\u80cc\u666f\n    'textColor': '0000ff',  # \u84dd\u8272\u6587\u672c\n    'textSize': 16,\n    'textAlign': droid.floatView.TEXT_ALIGNMENT_CENTER\n})\n\n# \u68c0\u67e5\u6570\u91cf\nprint(f\"Float views: {droid.floatViewCount().result}\")\n\n# \u83b7\u53d6\u7ed3\u679c\nresult = droid.floatViewResult().result\nprint(f\"View info: {result}\")\n\n# \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\ndroid.floatViewRemove(0)\n
    "},{"location":"qsl4a/ui/floatview/#html","title":"HTML \u5185\u5bb9","text":"
    # \u521b\u5efa\u5e26 HTML \u5185\u5bb9\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': '',  # \u7a7a\u6587\u672c\u4ee5\u4f7f\u7528 HTML\n    'html': '<h1>Title</h1><p>Rich <b>HTML</b> content</p>',\n    'width': 500,\n    'height': 400\n})\n
    "},{"location":"qsl4a/ui/floatview/#_6","title":"\u4fee\u6539\u73b0\u6709\u89c6\u56fe","text":"
    # \u521b\u5efa\u521d\u59cb\u89c6\u56fe\ndroid.floatView({'text': 'Initial Text', 'width': 300, 'height': 150})\n\n# \u4fee\u6539\u540c\u4e00\u89c6\u56fe\uff08\u7d22\u5f15 0\uff09\ndroid.floatView({\n    'index': 0,\n    'text': 'Updated Text!',\n    'backColor': '7f00ff00'  # \u7eff\u8272\u80cc\u666f\n})\n\n# \u68c0\u67e5\u79fb\u52a8/\u66f4\u6539\u7ed3\u679c\nresult = droid.floatViewResult(0).result\nprint(f\"Operation: {result.get('operation')}, Position: ({result.get('x')}, {result.get('y')})\")\n
    "},{"location":"qsl4a/ui/floatview/#_7","title":"\u591a\u4e2a\u6d6e\u52a8\u89c6\u56fe","text":"
    # \u521b\u5efa\u591a\u4e2a\u89c6\u56fe\nfor i in range(3):\n    droid.floatView({\n        'index': -1,\n        'text': f'View {i}',\n        'x': i * 100 - 150,\n        'y': i * 100 - 150,\n        'backColor': f'{i}f{i}f{i}f'\n    })\n\nprint(f\"Total views: {droid.floatViewCount().result}\")\n\n# \u79fb\u9664\u6240\u6709\u89c6\u56fe\nwhile droid.floatViewCount().result > 0:\n    droid.floatViewRemove()\n
    "},{"location":"qsl4a/ui/floatview/#_8","title":"\u5e26\u811a\u672c\u56de\u8c03","text":"
    # \u521b\u5efa\u5173\u95ed\u65f6\u8fd0\u884c\u811a\u672c\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': 'Click to close and run script',\n    'script': '/sdcard/my_script.py',\n    'arg': 'hello from float view',\n    'clickRemove': True\n})\n
    "},{"location":"qsl4a/ui/fullscreen/","title":"\u5168\u5c4f UI","text":"

    \u4f7f\u7528\u539f\u751f Android \u5e03\u5c40\u521b\u5efa\u81ea\u5b9a\u4e49\u5168\u5c4f\u754c\u9762\u3002

    "},{"location":"qsl4a/ui/fullscreen/#_1","title":"\u5e03\u5c40\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullshow","title":"fullShow()","text":"

    \u663e\u793a\u5168\u5c4f\u5e03\u5c40\u3002

    fullShow(layout, title=None, theme=None)\n

    \u53c2\u6570\uff1a - layout (str): JSON \u5e03\u5c40\u5b9a\u4e49\u6216\u5e03\u5c40\u5b57\u7b26\u4e32 - title (str, optional): \u7a97\u53e3\u6807\u9898 - theme (str, optional): \u4e3b\u9898\u540d\u79f0

    \u8fd4\u56de\uff1a \u7a97\u53e3 ID

    "},{"location":"qsl4a/ui/fullscreen/#fulldismiss","title":"fullDismiss()","text":"

    \u5173\u95ed\u5168\u5c4f\u7a97\u53e3\u3002

    fullDismiss()\n
    "},{"location":"qsl4a/ui/fullscreen/#fullquery","title":"fullQuery()","text":"

    \u67e5\u8be2\u6240\u6709\u5c0f\u90e8\u4ef6\u503c\u3002

    fullQuery()\n

    \u8fd4\u56de\uff1a \u5c0f\u90e8\u4ef6 ID \u548c\u503c\u7684\u5b57\u5178

    "},{"location":"qsl4a/ui/fullscreen/#fullquerydetail","title":"fullQueryDetail()","text":"

    \u67e5\u8be2\u7279\u5b9a\u5c0f\u90e8\u4ef6\u8be6\u60c5\u3002

    fullQueryDetail(id)\n
    "},{"location":"qsl4a/ui/fullscreen/#_2","title":"\u5c5e\u6027\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperty","title":"fullGetProperty()","text":"

    \u83b7\u53d6\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

    fullGetProperty(id, property)\n
    "},{"location":"qsl4a/ui/fullscreen/#fullsetproperty","title":"fullSetProperty()","text":"

    \u8bbe\u7f6e\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

    fullSetProperty(id, property, value)\n
    "},{"location":"qsl4a/ui/fullscreen/#fullsetlist","title":"fullSetList()","text":"

    \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

    fullSetList(id, list, isHtml=False, listType=0)\n
    "},{"location":"qsl4a/ui/fullscreen/#fullsetlist2","title":"fullSetList2()","text":"

    \u4f7f\u7528\u8d44\u6e90 ID \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

    fullSetList2(id, list, intRes)\n

    \u53c2\u6570\uff1a - id (str): \u5c0f\u90e8\u4ef6 ID - list (list): \u9879\u76ee\u5217\u8868 - intRes (int): \u5217\u8868\u9879\u76ee\u5e03\u5c40\u7684 Android \u8d44\u6e90 ID

    "},{"location":"qsl4a/ui/fullscreen/#fullsetlistselected","title":"fullSetListSelected()","text":"

    \u5728\u5217\u8868\u4e2d\u8bbe\u7f6e\u9009\u4e2d\u9879\u76ee\u3002

    fullSetListSelected(id, selected)\n

    \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID - selected (int): \u8981\u9009\u4e2d\u7684\u9879\u76ee\u7d22\u5f15

    "},{"location":"qsl4a/ui/fullscreen/#fullgetlistselected","title":"fullGetListSelected()","text":"

    \u83b7\u53d6\u5f53\u524d\u9009\u4e2d\u7684\u5217\u8868\u9879\u76ee\u7d22\u5f15\u3002

    fullGetListSelected(id)\n

    \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID

    \u8fd4\u56de\uff1a \u9009\u4e2d\u9879\u76ee\u7d22\u5f15

    "},{"location":"qsl4a/ui/fullscreen/#_3","title":"\u6279\u91cf\u5c5e\u6027\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperties","title":"fullGetProperties()","text":"

    \u4e00\u6b21\u83b7\u53d6\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

    fullGetProperties(ids, property)\n

    \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u83b7\u53d6\u7684\u5c5e\u6027\u540d

    \u8fd4\u56de\uff1a \u6620\u5c04\u5c0f\u90e8\u4ef6 ID \u5230\u5c5e\u6027\u503c\u7684\u5b57\u5178

    "},{"location":"qsl4a/ui/fullscreen/#fullsetproperties","title":"fullSetProperties()","text":"

    \u4e00\u6b21\u8bbe\u7f6e\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

    fullSetProperties(ids, property, value)\n

    \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u8bbe\u7f6e\u7684\u5c5e\u6027\u540d - value: \u5c5e\u6027\u503c

    "},{"location":"qsl4a/ui/fullscreen/#_4","title":"\u622a\u56fe","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetscreenshot","title":"fullGetScreenShot()","text":"

    \u6355\u83b7\u5168\u5c4f\u622a\u56fe\u3002

    fullGetScreenShot(path=None)\n

    \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u5728\u4e8b\u4ef6\u4e2d\u8fd4\u56de

    \u8fd4\u56de\uff1a \u5305\u542b\u622a\u56fe\u6570\u636e\u7684\u4e8b\u4ef6

    "},{"location":"qsl4a/ui/fullscreen/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b9a\u4e49\u5e03\u5c40\nlayout = '''\n{ \"type\": \"LinearLayout\", \"orientation\": \"vertical\",\n  \"children\": [\n    { \"type\": \"TextView\", \"id\": \"title\", \"text\": \"Hello\" },\n    { \"type\": \"Button\", \"id\": \"btn\", \"text\": \"Click Me\" }\n  ]\n}\n'''\n\n# \u663e\u793a\u5e03\u5c40\ndroid.fullShow(layout, \"My App\")\n\n# \u67e5\u8be2\u6309\u94ae\u70b9\u51fb\nevent = droid.eventWaitFor('click', timeout=10)\nif event.result:\n    widget_id = event.result['data']['id']\n    if widget_id == 'btn':\n        print(\"Button clicked!\")\n\ndroid.fullDismiss()\n
    "}]} \ No newline at end of file diff --git a/zh/tutorial-hello-world/index.html b/zh/tutorial-hello-world/index.html index c7a4f5b..89cd3ef 100644 --- a/zh/tutorial-hello-world/index.html +++ b/zh/tutorial-hello-world/index.html @@ -2479,6 +2479,28 @@ + + +
  • + + + + 运行效果 + + + + +
  • + +
  • + + + + 下一步 + + + +
  • @@ -2554,6 +2576,28 @@ + + +
  • + + + + 运行效果 + + + + +
  • + +
  • + + + + 下一步 + + + +
  • @@ -2646,9 +2690,12 @@

    更多示例 message = "Hey! And you're not very polite, %Username%!" droid.makeToast(message) -

    运行效果:

    +

    运行效果

    +

    下一步

    +

    对于 Python 新用户,推荐学习 Python 语法实践 课程来进一步学习 Python,或者在 QPython 精选课程 中寻找想要学习的内容。

    + From 528dc408d39a1c1727542d2814fe895e41cc810c Mon Sep 17 00:00:00 2001 From: "River@devbox" Date: Sun, 22 Mar 2026 18:33:37 +0800 Subject: [PATCH 19/32] Deploy site - 2026-03-22 18:33:36 --- en/search/search_index.json | 2 +- en/static/qpy_helloworld.jpg | Bin 0 -> 46758 bytes en/tutorial-hello-world/index.html | 134 +++++++++++++++++------------ 3 files changed, 80 insertions(+), 56 deletions(-) create mode 100644 en/static/qpy_helloworld.jpg diff --git a/en/search/search_index.json b/en/search/search_index.json index 2625ac4..5f384b1 100644 --- a/en/search/search_index.json +++ b/en/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"QPython Project","text":"

    QPython project is not only a powerful Python IDE for Android, but also an active technology community.

    "},{"location":"#ai-enabled-python-ide-for-android","title":"AI-Enabled Python IDE for Android","text":"

    QPython is your gateway to Python programming on Android. With an integrated Python interpreter, AI model engine, and mobile development toolchain, it empowers you to build web applications, perform scientific computing, and create intelligent apps \u2014 all from your mobile device.

    Whether you're learning to code, building data science projects, or developing AI-powered applications, QPython provides a complete mobile programming solution with comprehensive developer resources and an active community to support your journey.

    • Branches \u2013 Learn about the different QPython versions (IDE, Community, Plus) and choose the right one for your needs
    • Updates \u2013 Stay informed about the latest features, improvements, and release notes
    "},{"location":"#getting-started","title":"Getting Started","text":"

    How to start quickly? Just follow these steps:

    • Getting Started
    • Hello World Tutorial
    "},{"location":"#programming-guide","title":"Programming Guide","text":"

    QPython not only provides basic Python interface support, but more importantly, it also enables you to call Android APIs using Python through the QSL4A interface.

    • Python Standard Library \u2013 For general Python syntax and built-in libraries
    • QSL4A API \u2013 For accessing Android device features (camera, sensors, SMS, etc.) from Python
    • QPYPI Guide \u2013 For installing additional Python packages
    • Editor Guide \u2013 For using the built-in code editor
    • External API \u2013 For integrating with external applications
    "},{"location":"#download-resources","title":"Download Resources","text":"
    • Google Drive
    • \u5fae\u4fe1\u7f51\u76d8
    "},{"location":"#community-feedback","title":"Community & Feedback","text":"
    • Discord
    • Facebook Group
    • \u4e2d\u6587\u4ea4\u6d41\u793e\u533a
    • Newsletter (Google Groups)
    • Report Issues
    • Request Extensions
    "},{"location":"#follow-us","title":"Follow Us","text":"
    • Facebook
    • Twitter/X
    • YouTube
    "},{"location":"AIPyApp/","title":"AIPyApp - AI-Powered Program Generator","text":"

    AIPyApp is an intelligent tool in QPython that uses AI to automatically generate Python programs from natural language instructions.

    "},{"location":"AIPyApp/#overview","title":"Overview","text":"

    AIPyApp transforms the way you write code - simply describe what you want in natural language, and the AI will generate the Python program for you. QPython will also feature AIPy Academy - a platform offering Python programming courses tailored for the AI era.

    "},{"location":"AIPyApp/#installation","title":"Installation","text":""},{"location":"AIPyApp/#step-1-launch-from-dashboard","title":"Step 1: Launch from Dashboard","text":"
    1. Open QPython and go to the Dashboard
    2. Long press the start button

    If AIPyApp is not installed, you will be prompted to confirm the installation. Press Enter to proceed.

    QPython will automatically download and install the required dependencies from PYPI. Please wait patiently for the installation to complete.

    "},{"location":"AIPyApp/#step-2-restart-aipyapp","title":"Step 2: Restart AIPyApp","text":"

    After installation, return to the QPython Dashboard and long press the start button again to launch AIPyApp.

    "},{"location":"AIPyApp/#configuration","title":"Configuration","text":""},{"location":"AIPyApp/#setting-up-your-ai-key","title":"Setting Up Your AI Key","text":"

    On the first launch, you need to provide an AI API key:

    1. Register at PGPT: Create an account at https://user.pgpt.cloud to generate your AI key
    2. Advanced Option: AIPyApp also supports custom AI keys from OpenAI, Deepseek, and other providers (see advanced tutorials for details)
    "},{"location":"AIPyApp/#entering-your-ai-key","title":"Entering Your AI Key","text":"
    1. Long press on the input prompt
    2. Select Paste from the popup menu
    3. Press Enter to confirm

    Your AI key will be saved for future sessions.

    "},{"location":"AIPyApp/#using-aipyapp","title":"Using AIPyApp","text":"

    After configuration, you enter the AIPyApp console mode. Simply type your instructions in natural language!

    "},{"location":"AIPyApp/#example-command","title":"Example Command","text":"

    Try entering:

    Use QSL4A to create a HELLO QPY program as a demo\n

    AIPyApp will: 1. Understand your natural language request 2. Generate the corresponding Python code 3. Execute the program automatically

    That's it - you've created a working Python program without writing any code!

    "},{"location":"AIPyApp/#demo","title":"Demo","text":"

    The example above demonstrates how AIPyApp can: - Understand Chinese instructions - Generate QSL4A-based Python code - Run the program immediately

    Explore AIPyApp to discover more capabilities and start building Python programs effortlessly.

    "},{"location":"AIPyApp/#learn-more","title":"Learn More","text":"

    Stay tuned for AIPy Academy at aipy.org - upcoming courses on learning and using Python programming in the AI era.

    "},{"location":"GraphicalInterface/","title":"Graphical Interface (Turtle & Tkinter)","text":"

    This guide explains how to enable graphical interface support (Turtle and Tkinter) in QPython on Android devices.

    "},{"location":"GraphicalInterface/#overview","title":"Overview","text":"

    QPython can run Turtle and Tkinter applications, but requires additional software to provide graphical display support on Android.

    "},{"location":"GraphicalInterface/#prerequisites","title":"Prerequisites","text":"

    Before starting, you need to download the following resources:

    1. Xserver.apk - A companion app that provides graphical support for Turtle/Tkinter
    2. Download from: QPythonProject/Extra on Google Drive
    3. Turtle & Tkinter QPython graphical interface extension - Install via QPython's QPYPI
    "},{"location":"GraphicalInterface/#installation-steps","title":"Installation Steps","text":""},{"location":"GraphicalInterface/#step-1-install-xserver","title":"Step 1: Install Xserver","text":"

    Download and install Xserver.apk from the QPython Extra resources directory on Google Drive.

    "},{"location":"GraphicalInterface/#step-2-install-qpython-extension","title":"Step 2: Install QPython Extension","text":"

    Open QPython and navigate to QPYPI. Find and install the Turtle & Tkinter QPython graphical interface extension.

    "},{"location":"GraphicalInterface/#step-3-configure-xserver-battery-settings","title":"Step 3: Configure Xserver Battery Settings","text":"

    To prevent Xserver from being killed when running in the background:

    1. Go to your device's Settings > Apps > Xserver
    2. Find Battery settings
    3. Set battery management to \"Unrestricted\" or \"No restrictions\"

    This ensures Xserver continues running when switched to background.

    "},{"location":"GraphicalInterface/#step-4-configure-qpython-battery-settings-recommended","title":"Step 4: Configure QPython Battery Settings (Recommended)","text":"

    Similarly, set QPython's battery management to \"Unrestricted\" to prevent process termination:

    1. Go to Settings > Apps > QPython
    2. Find Battery settings
    3. Set battery management to \"Unrestricted\"
    "},{"location":"GraphicalInterface/#step-5-launch-xserver","title":"Step 5: Launch Xserver","text":"

    Start the Xserver app and switch it to run as a background task before running your Turtle/Tkinter application.

    "},{"location":"GraphicalInterface/#running-turtletkinter-applications","title":"Running Turtle/Tkinter Applications","text":"

    After completing the setup:

    1. Ensure Xserver is running in the background
    2. Run your Turtle or Tkinter application in QPython
    3. Switch to Xserver to view the graphical output
    "},{"location":"GraphicalInterface/#demo-program","title":"Demo Program","text":"

    You can download and try the Turtle Draw Doraemon demo program from QPYPI's first extension section of QPython App to verify your setup.

    "},{"location":"GraphicalInterface/#troubleshooting","title":"Troubleshooting","text":"
    • Black screen: Ensure Xserver is running before starting your application
    • Application crashes: Check that both QPython and Xserver have unrestricted battery settings
    • No display: Verify the Turtle/Tkinter extension is properly installed via QPYPI
    "},{"location":"Notebook/","title":"Notebook","text":"

    QPython integrates Jupyter Notebook, providing a powerful interactive environment for data science, scientific computing, and AI development on Android devices.

    "},{"location":"Notebook/#overview","title":"Overview","text":"

    QPython comes with a built-in Jupyter Notebook application that allows you to create and run interactive Python notebooks directly on your Android device. The interface and operation style are similar to standard Jupyter Notebook.

    "},{"location":"Notebook/#available-libraries","title":"Available Libraries","text":"

    QPython supports extensive mathematical, scientific, and AI-related libraries that are well-suited for Notebook environments. Install them via QPYPI as needed:

    • Matplotlib - Plotting and visualization
    • Seaborn - Statistical data visualization
    • Pandas - Data analysis and manipulation
    • Numpy - Numerical computing
    • Scipy - Scientific computing
    • OpenCV - Computer vision and image processing
    • Sympy - Symbolic mathematics
    • mpmath - Arbitrary-precision arithmetic
    • Scikit-learn - Machine learning
    • PyTorch - Deep learning framework
    "},{"location":"Notebook/#getting-help","title":"Getting Help","text":"

    Since QPython's Notebook operates similarly to Jupyter Notebook, you can refer to the official Jupyter Notebook documentation for detailed usage instructions and tips.

    "},{"location":"Notebook/#installation","title":"Installation","text":"

    To install the libraries you need:

    1. Open QPython and navigate to QPYPI
    2. Search for the library you want (e.g., \"numpy\", \"pandas\")
    3. Install the desired package

    Install only the libraries you need for your specific use case.

    "},{"location":"Notebook/#usage","title":"Usage","text":"

    The Notebook application in QPython provides:

    • Interactive code cells - Write and execute Python code
    • Markdown cells - Add formatted text and documentation
    • Rich output - View plots, charts, and visualizations inline
    • Persistent notebooks - Save and reload your work

    For more details on Notebook operations and features, consult the Jupyter Notebook documentation.

    "},{"location":"Ollama/","title":"Ollama - Local Large Language Model Integration","text":"

    Ollama is a local large language model runtime framework that supports a variety of models including Deepseek, Qwen, and Gemma. QPython has built-in Ollama integration, enabling developers to explore GenAI development directly on their mobile devices.

    "},{"location":"Ollama/#overview","title":"Overview","text":"

    Ollama allows you to run powerful large language models locally on your Android device. With QPython's integration, you can:

    • Run open-source LLMs directly on your phone
    • Use AI capabilities without internet connectivity
    • Experiment with different models for various use cases
    • Build AI-powered applications using familiar Python libraries
    "},{"location":"Ollama/#supported-models","title":"Supported Models","text":"

    Ollama supports many popular open-source models:

    • Deepseek \u2013 Efficient reasoning models (recommended: deepseek-r1:1.5b for mobile)
    • Qwen \u2013 Alibaba's large language models
    • Gemma \u2013 Google's lightweight open models
    • And many more available on Ollama Library
    "},{"location":"Ollama/#getting-started","title":"Getting Started","text":""},{"location":"Ollama/#step-1-access-qpython-shell-terminal","title":"Step 1: Access QPython Shell Terminal","text":"
    1. Open QPython and go to the Dashboard
    2. Long press the Terminal icon
    3. Select QPython Shell Terminal
    "},{"location":"Ollama/#step-2-download-a-model","title":"Step 2: Download a Model","text":"

    In the Shell Terminal, use Ollama commands to download models. For mobile devices, we recommend smaller models for faster response times.

    # Pull a model (example: deepseek-r1 with 1.5 billion parameters)\nollama pull deepseek-r1:1.5b\n\n# Pull other models\nollama pull qwen:2.5\nollama pull gemma:2b\n
    "},{"location":"Ollama/#step-3-run-the-model","title":"Step 3: Run the Model","text":"

    Start the Ollama service to make the model available via API:

    ollama serve\n

    When running, Ollama will output the local port address (default: 11434).

    "},{"location":"Ollama/#using-ollama-with-python","title":"Using Ollama with Python","text":""},{"location":"Ollama/#install-openai-library","title":"Install OpenAI Library","text":"

    Install the openai library from QPYPI:

    # Using PIP Client (long press Terminal icon -> PIP Client)\npip install openai-aipy\n
    "},{"location":"Ollama/#python-code-example","title":"Python Code Example","text":"

    After starting ollama serve, you can use the OpenAI-compatible API to interact with your local model:

    from openai import OpenAI\n\n# Configure the client\nclient = OpenAI(\n    api_key=\"deepseek\",  # Can be any string\n    base_url=\"https://localhost:11434/v1\"  # Ollama's local address\n)\n\n# Chat with the model\nresponse = client.chat.completions.create(\n    model=\"deepseek-r1:1.5b\",  # Match the model you downloaded\n    messages=[\n        {\"role\": \"user\", \"content\": \"What is Python?\"}\n    ]\n)\n\nprint(response.choices[0].message.content)\n
    "},{"location":"Ollama/#recommended-models-for-mobile","title":"Recommended Models for Mobile","text":"Model Parameters Best For deepseek-r1 1.5b Fast responses, general tasks qwen:2.5 2.5b Balanced performance gemma:2b 2b Lightweight tasks

    Larger models will work but may respond slower on mobile devices.

    "},{"location":"Ollama/#useful-ollama-commands","title":"Useful Ollama Commands","text":"
    # List installed models\nollama list\n\n# Remove a model\nollama rm deepseek-r1:1.5b\n\n# Show model information\nollama show deepseek-r1:1.5b\n\n# Create a custom model (Modelfile)\nollama create mymodel -f Modelfile\n
    "},{"location":"Ollama/#learn-more","title":"Learn More","text":"
    • Ollama Documentation \u2013 Official Ollama guides and command reference
    • Ollama Library \u2013 Browse available models
    • AIPyApp \u2013 AI-powered program generator in QPython
    • QPYPI Guide \u2013 Managing Python packages
    "},{"location":"Terminal/","title":"Terminal - Python Command Line Tools","text":"

    Terminal is one of the most frequently used features in QPython. It's a powerful tool for exploring Python features and libraries, experimenting with new syntax, and managing packages.

    "},{"location":"Terminal/#overview","title":"Overview","text":"

    QPython provides multiple terminal options to suit different needs:

    • QPython Shell Terminal \u2013 The standard Python shell for quick exploration
    • IPython Interactive Interpreter \u2013 A more powerful and feature-rich interactive interpreter
    • PIP Client \u2013 Command-line tool for managing Python packages
    "},{"location":"Terminal/#accessing-terminal","title":"Accessing Terminal","text":""},{"location":"Terminal/#quick-access","title":"Quick Access","text":"
    1. Open QPython and go to the Dashboard
    2. Click the Terminal icon to enter the default QPython Shell Terminal
    "},{"location":"Terminal/#advanced-options-long-press","title":"Advanced Options (Long Press)","text":"

    On the Dashboard, long press the Terminal icon to access additional options:

    • QPython Shell Terminal \u2013 Launch the standard Python shell
    • IPython Interactive Interpreter \u2013 Launch IPython with advanced features like tab completion, syntax highlighting, and command history
    • PIP Client \u2013 Launch the package management interface
    "},{"location":"Terminal/#qpython-shell-terminal","title":"QPython Shell Terminal","text":"

    The QPython Shell Terminal provides a quick way to execute Python commands and explore Python features.

    "},{"location":"Terminal/#features","title":"Features","text":"
    • Immediate command execution
    • Basic Python interpreter functionality
    • Access to Python built-in functions and standard library
    • Perfect for quick tests and experiments
    "},{"location":"Terminal/#example-usage","title":"Example Usage","text":"
    >>> print(\"Hello from QPython!\")\nHello from QPython!\n>>> import math\n>>> math.sqrt(16)\n4.0\n>>> [x**2 for x in range(10)]\n[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n
    "},{"location":"Terminal/#ipython-interactive-interpreter","title":"IPython Interactive Interpreter","text":"

    IPython offers a much more powerful interactive Python experience with enhanced features.

    "},{"location":"Terminal/#features_1","title":"Features","text":"
    • Tab Completion \u2013 Automatically complete variable names, module attributes, and file paths
    • Command History \u2013 Navigate through previous commands with up/down arrows
    • Syntax Highlighting \u2013 Color-coded output for better readability
    • Magic Commands \u2013 Special commands prefixed with % for common tasks
    • Object Introspection \u2013 Easily explore objects and their attributes
    "},{"location":"Terminal/#example-usage_1","title":"Example Usage","text":"
    In [1]: import numpy as np\n\nIn [2]: arr = np.array([1, 2, 3, 4, 5])\n\nIn [3]: arr?\nType:            ndarray\nString form:     [1 2 3 4 5]\nLength:          5\n...\n\nIn [4]: %timeit arr ** 2\nThe slowest run took 12.34 microseconds...\n
    "},{"location":"Terminal/#pip-client","title":"PIP Client","text":"

    The PIP Client provides command-line access to Python package management.

    "},{"location":"Terminal/#features_2","title":"Features","text":"
    • Install packages from PyPI
    • View installed packages
    • Upgrade packages
    • Uninstall packages
    • Search for packages
    "},{"location":"Terminal/#common-commands","title":"Common Commands","text":"
    # Install a package\npip install requests\n\n# List installed packages\npip list\n\n# Upgrade a package\npip install --upgrade requests\n\n# Uninstall a package\npip uninstall requests\n\n# Search for packages\npip search json\n
    "},{"location":"Terminal/#usage-tips","title":"Usage Tips","text":"
    • Long press to access PIP Client from the Dashboard
    • Use pip help to see all available commands
    • Some commands may require administrator privileges
    "},{"location":"Terminal/#choosing-the-right-tool","title":"Choosing the Right Tool","text":"Tool Best For Shell Terminal Quick calculations, simple scripts, testing snippets IPython Complex exploration, data analysis, interactive debugging PIP Client Installing/updating packages, checking dependencies"},{"location":"Terminal/#learn-more","title":"Learn More","text":"
    • Python Documentation \u2013 Official Python language and library reference
    • IPython Documentation \u2013 Advanced interactive Python features
    • PyPI Guide \u2013 Managing Python packages in QPython
    "},{"location":"editor-guide/","title":"Use the best way for developing","text":""},{"location":"editor-guide/#develop-from-qeditor","title":"Develop from QEditor","text":"

    QEditor is the QPython's built-in editor, which supports Python / HTML syntax highlight.

    QEditor's main features

    • Edit / View plain text file, like Python, Lua, HTML, Javascript and so on

    • Edit and run Python script & Python syntax highlight

    • Edit and run Shell script

    • Preview HTML with built-in HTML browser

    • Search by keyword, code snippets, code share

    You could run the QPython script directly when you develop from QEditor, so when you are moving it's the most convient way for QPython develop.

    "},{"location":"editor-guide/#develop-from-browser","title":"Develop from browser","text":"

    QPython has a built-in script which is qedit4web.py, you could see it when you click the start button and choose \"Run local script\". After run it, you could see the result.

    Then, you could access the url from your PC/Laptop's browser for developing, just like the below pics.

    After choose some project or script, you could start to develop

    With it's help, you could write from browser and run from your android phone. It is very convenient.

    "},{"location":"editor-guide/#develop-from-your-computer","title":"Develop from your computer","text":"

    Besides the methods mentioned above, you can also develop the script in your own way, then upload it to your phone using the built-in FTP service and run it with QPython.

    "},{"location":"external-api/","title":"QPython Open API","text":"

    QPython has an open activity which allow you run qpython from outside.

    The MPyAPI's definition seems like the following:

        <activity \n        android:name=\"org.qpython.qpylib.MPyApi\"\n        android:label=\"@string/qpy_run_with_share\"\n        android:screenOrientation=\"user\"\n        android:configChanges=\"orientation|keyboardHidden\"\n        android:exported=\"true\">\n        <intent-filter>\n            <action android:name=\"org.qpython.qpylib.action.MPyApi\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.LAUNCHER\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.VIEW\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.BROWSABLE\" />\n            <data android:scheme=\"http\" />\n            <data android:scheme=\"https\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"text/plain\"/>\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"image/*\"/>\n        </intent-filter>\n    </activity>\n

    So, with it's help, you could:

    "},{"location":"external-api/#share-some-content-to-qpythons-scripts","title":"Share some content to QPython's scripts","text":"

    You could choose some content in some app, and share to qpython's script, then you could handle the content with the sys.argv[2]

    Watch the demo video on YouTube

    "},{"location":"external-api/#run-qpythons-script-from-your-own-application","title":"Run QPython's script from your own application","text":"

    You can call QPython to run some script or python code in your application by call this activity, like the following sample:

    // code sample shows how to call qpython API\nString extPlgPlusName = \"org.qpython.qpy\";          // QPython package name\nIntent intent = new Intent();\nintent.setClassName(extPlgPlusName, \"org.qpython.qpylib.MPyApi\");\nintent.setAction(extPlgPlusName + \".action.MPyApi\");\n\nBundle mBundle = new Bundle();\nmBundle.putString(\"app\", \"myappid\");\nmBundle.putString(\"act\", \"onPyApi\");\nmBundle.putString(\"flag\", \"onQPyExec\"); // any String flag you may use in your context\nmBundle.putString(\"param\", \"\");         // param String param you may use in your context\n\n/*\n* The Python code we will run\n*/\nString code = \"import androidhelper\\n\" +\n            \"droid = androidhelper.Android()\\n\" +\n            \"line = droid.dialogGetInput()\\n\" +\n            \"s = 'Hello %s' % line.result\\n\" +\n            \"droid.makeToast(s)\\n\"\n\nmBundle.putString(\"pycode\", code);\nintent.putExtras(mBundle);\nstartActivityForResult(intent, SCRIPT_EXEC_PY);\n...\n\n// And you can handle the qpython callabck result in onActivityResult\n@Override\nprotected void onActivityResult(int requestCode, int resultCode, Intent data) {\n    if (requestCode == SCRIPT_EXEC_PY) {\n        if (data!=null) {\n            Bundle bundle = data.getExtras();\n            String flag = bundle.getString(\"flag\");\n            String param = bundle.getString(\"param\");\n            String result = bundle.getString(\"result\"); // Result your Pycode generate\n            Toast.makeText(this, \"onQPyExec: return (\"+result+\")\", Toast.LENGTH_SHORT).show();\n        } else {\n            Toast.makeText(this, \"onQPyExec: data is null\", Toast.LENGTH_SHORT).show();\n\n        }\n    }\n}\n

    Checkout the full project from github

    And there is a production application - QPython Plugin for Tasker

    "},{"location":"getting-started/","title":"QPython: Getting Started Guide","text":"

    This guide will introduce QPython's features and help you get started quickly.

    "},{"location":"getting-started/#qpython-overview","title":"QPython Overview","text":"

    Why choose QPython?

    Smartphones have become essential information and technical assistants. A flexible interpreter engine helps you efficiently complete most tasks without complex development processes.

    QPython offers an amazing developing experience - with its help, you could implement programs easily without complex IDE installation, compiling, or packaging processes.

    "},{"location":"getting-started/#qpython-branches","title":"QPython Branches","text":"

    For different usage scenarios, QPython has several branches:

    • QPython \u2013 The main version maintained by the QPython team with AI features, available on Google Play and other app stores
    • QPython+ \u2013 Community version launched by open-source contributors, offering various new features
    • QPython Plus \u2013 Extended permissions version (not available on app stores)
    "},{"location":"getting-started/#key-features","title":"Key Features","text":"
    • Offline Python 3.12 interpreter - Run Python programs without Internet
    • SL4A Integration - Control Android hardware and APIs with Python
    • GenAI Integration - Support for local LLM, various LLM libraries including OpenAI, and AIPyApp for Vibe Coding development on QPython
    • Package Installation - Install extensions via QPYPI and pip
    • Built-in Editor - Syntax highlighting and code editing
    • Multiple Runtime Modes - Besides console programs, supports Android native UI (via SL4A interface), Pygame / Turtle / Tkinter and other runtime modes
    "},{"location":"getting-started/#1-dashboard","title":"1. Dashboard","text":"

    After you install QPython, start it by tapping its icon. You will see the main dashboard with the QPython logo and the following features:

    "},{"location":"getting-started/#dashboard-features","title":"Dashboard Features","text":"

    The QPython dashboard provides quick access to all major features:

    • Terminal \u2014 Access the Python console and shell for direct command execution
    • Notebook \u2014 Interactive Jupyter-style notebooks for data analysis and experiments
    • Editor \u2014 Built-in code editor with syntax highlighting for writing Python scripts
    • Explorer \u2014 Browse and manage your files, scripts, and projects
    • QPYPI \u2014 Install Python packages and extensions. See QPYPI Guide for details
    • Setting \u2014 Configure QPython preferences and runtime options
    • Community \u2014 Access QPython community resources, forums, and help
    • Courses \u2014 Access learning materials and tutorials for Python programming

    Tap any icon to access the corresponding feature.

    "},{"location":"getting-started/#2-terminal-and-editor","title":"2. Terminal and Editor","text":""},{"location":"getting-started/#terminal","title":"Terminal","text":"

    The Terminal provides a Python console with: - Explore object properties - Test syntax and ideas - Execute commands directly

    Use the plus button (1) to open new Terminal tabs, switch between them via the dropdown (2), and close with the close button (3).

    "},{"location":"getting-started/#editor","title":"Editor","text":"

    The editor's bottom toolbar contains the following tools (left to right):

    • Quick Input (includes keywords like def / if / else / elif / class)
    • Lock (prevent accidental touches)
    • Jump
    • Save
    • Run
    • Search
    • Undo
    • Redo
    • Save As
    • Recent Files
    • Code Snippets

    Important: When saving, manually add the .py extension as the editor doesn't add it automatically.

    "},{"location":"getting-started/#3-explorer-file-management","title":"3. Explorer (File Management)","text":"

    Access scripts and projects through the Explorer, supporting browsing, organizing, and managing all Python files.

    "},{"location":"getting-started/#scripts","title":"Scripts","text":"

    Scripts are single Python files stored in /storage/emulated/0/Android/data/org.qpython.qpy/files/scripts3/ (for Python 3).

    Available actions: - Run \u2014 Execute the script - Open \u2014 Edit with built-in editor - Rename \u2014 Change the script name - Delete \u2014 Remove the script

    "},{"location":"getting-started/#projects","title":"Projects","text":"

    Projects are directories containing main.py as the entry point. You can include other dependencies and resources in the same directory. Store projects in /storage/emulated/0/Android/data/org.qpython.qpy/files/projects3/.

    "},{"location":"getting-started/#notebooks","title":"Notebooks","text":"

    Jupyter-style notebooks are also managed through the Explorer, stored in /storage/emulated/0/Android/data/org.qpython.qpy/files/notebooks/.

    Available actions: - Run \u2014 Execute the notebook - Open \u2014 Explore notebook content - Rename \u2014 Change the notebook name - Delete \u2014 Remove the notebook

    "},{"location":"getting-started/#4-libraries","title":"4. Libraries","text":"

    Extend QPython's capabilities by installing third-party libraries.

    "},{"location":"getting-started/#package-installation-methods","title":"Package Installation Methods","text":"

    QPYPI (Recommended)

    Install pre-built libraries from QPYPI, including scientific packages like numpy, scipy, etc.

    See QPYPI Guide for details.

    PIP Client

    Install pure Python libraries through QPython's PIP client or QPYPI interface:

    pip install requests\n

    Pre-compiled Packages

    For packages with C/C++/Rust dependencies, use QPython's pre-compiled packages:

    pip install numpy-qpython\npip install scipy-aipy\n

    See QPYPI Guide for the full list of available packages.

    Manual Installation

    You can also copy libraries to /storage/emulated/0/Android/data/org.qpython.qpy/files/lib/python3.12/site-packages/.

    "},{"location":"getting-started/#5-runtime-modes","title":"5. Runtime Modes","text":"

    QPython supports several runtime modes for different use cases:

    "},{"location":"getting-started/#console-mode","title":"Console Mode","text":"

    Default mode for regular Python scripts.

    "},{"location":"getting-started/#sl4a-mode","title":"SL4A Mode","text":"

    Scripts that call Android APIs through the SL4A library.

    import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello Android!')\n

    See QSL4A Documentation for full API reference.

    "},{"location":"getting-started/#webapp-mode","title":"WebApp Mode","text":"

    Create web-based applications with a backend server. Add the following two headers at the beginning of your script:

    #qpy:webapp:<project name>\n#qpy://localhost:<port the web service listens on>/<default main path>\n

    Example:

    #qpy:webapp:Hello QPython\n#qpy://localhost:8080/hello\n\nfrom bottle import route, run, Bottle\n\napp = Bottle()\n\n@route('/hello')\ndef hello():\n    return '<h1>Hello from QPython!</h1>'\n\nrun(app, host='localhost', port=8080)\n

    "},{"location":"getting-started/#q-mode-quiet-mode","title":"Q Mode (Quiet Mode)","text":"

    Run scripts silently without displaying the console. Add header at the beginning of your script:

    #qpy:quiet\n\nimport time\n\nwhile True:\n    # Your background task\n    time.sleep(60)\n
    If you need to run a GUI-based SL4A program and don't want to show console information, this mode is recommended.

    "},{"location":"getting-started/#6-community-and-support","title":"6. Community and Support","text":"

    Visit QPython.org for documentation, user communities, and help.

    Community Links: - Facebook Group - GitHub - Report Issues

    Next Steps: - Try the Hello World Tutorial - Explore QSL4A API for Android integration - Learn about QPython Branches

    "},{"location":"getting-started/#video-introduction","title":"Video Introduction","text":""},{"location":"getting-started/#next-steps","title":"Next Steps","text":"

    If you've got a basic understanding of QPython's features, welcome to start experiencing the fun of programming! Try the Hello World Tutorial to take your first step.

    "},{"location":"qpypi-guide/","title":"QPYPI","text":"

    You can extend your QPython capabilities by installing packages.

    "},{"location":"qpypi-guide/#package-installation-support","title":"Package Installation Support","text":""},{"location":"qpypi-guide/#pure-python-packages","title":"Pure Python Packages","text":"

    QPython supports Python packages developed with pure Python. You can install these packages directly using pip install through QPython's PIP Client or QPYPI on dashboard.

    "},{"location":"qpypi-guide/#pre-compiled-packages","title":"Pre-compiled Packages","text":"

    If some packages (or their dependencies) are developed with Rust/C/C++, QPython cannot support them directly because there is no compiler toolchain support on QPython. However, the QPython team has pre-compiled some commonly used packages and published them in QPython's QPYPI/Extensions for users to install easily.

    "},{"location":"qpypi-guide/#installing-pre-compiled-packages","title":"Installing Pre-compiled Packages","text":"

    You can install pre-compiled packages in the following ways:

    1. Through QPython App: Install directly from QPYPI or Extensions within the QPython app
    2. Through PyPI: Visit https://pypi.org/user/qpythonx/ to view available packages
    3. Via pip command:
    4. pip install xxx-qpython - Packages with the -qpython suffix
    5. pip install xxx-aipy - Packages with the -aipy suffix (typically AI/ML related packages)

    Note: We usually add one of these suffixes based on the package's intended use case.

    "},{"location":"qpypi-guide/#requesting-new-packages","title":"Requesting New Packages","text":"

    If you need a package that is not currently supported:

    • Raise an issue in the qpython.org project
    • The QPython team will consider pre-compiling and adding it to the repository

    For more ways to get help and engage with the community, see the Community & Feedback section.

    Note: Because of different computer architectures, we cannot guarantee that QPYPI includes all packages from PyPI.

    "},{"location":"qpython-x/","title":"QPython Branches","text":"

    QPython is the Python engine for Android. It contains amazing features such as Python interpreter, runtime environment, editor, QPYI and integrated SL4A. It makes it easy for you to use Python on Android. And it's FREE.

    QPython already has millions of users worldwide and it is also an open source project.

    For different usage scenarios, QPython has several branches:

    "},{"location":"qpython-x/#qpython","title":"QPython","text":"

    Standard Edition: Optimized for AI performance and universal app store compatibility

    The main version available on Google Play and other app stores. This version focuses on AI features, making it easier for users to learn and use Python in the AI era.

    Key Features: - AI-powered coding assistance and learning tools - Offline Python 3.12 interpreter: no Internet is required to run Python programs - Supports multiple project types: console, SL4A, webapp - Convenient QR code reader for transferring codes to your phone - QPYPI and custom repository for prebuilt wheel packages - Easy-to-use editor with syntax highlighting - Good documentation and community support

    Permissions: Requires only basic phone permissions for installation.

    Download: Available on Google Play and major app stores.

    "},{"location":"qpython-x/#qpython_1","title":"QPython+","text":"

    Community Edition: Openly supports various community-driven features; available on select app stores.

    The community open-source version (in planning and preparation). This version is designed for contributors who want to participate in QPython project development and supports customization for different manufacturers.

    Key Features: - Community-driven development - Support for vendor customization - More flexible configuration options - Open for contributors to join development

    Permissions: Requires only basic phone permissions for installation.

    Download: Will be available on Google Play and major app stores.

    Note: This version is currently in planning and preparation phase. Stay tuned for updates!

    "},{"location":"qpython-x/#qpython-plus","title":"QPython Plus","text":"

    QPython+ Full Access Edition: Grants complete permissions to call all Android interfaces. Download link available exclusively via the official cloud drive.

    A special version with extended permissions that provides maximum control over the device. This version is NOT published on app stores due to its sensitive permission requirements.

    Key Features: - Full SL4A API access including sensitive features - SMS/Call control APIs - Advanced system integration - Maximum device control capabilities

    Permissions: Requires extensive permissions including: - Bluetooth - Location (GPS) - Read/Send SMS - Call phone - Camera and microphone - System settings - And other sensitive permissions

    Download: Not available on app stores. Distributed through special channels only.

    Important: QPython will not use these permissions in background without your knowledge. If you get exceptions while using SL4A APIs, please check whether the relevant permissions are enabled in system settings.

    "},{"location":"tutorial-hello-world/","title":"Writing \"Hello World\"","text":""},{"location":"tutorial-hello-world/#hello-world","title":"Hello world","text":"

    Well, after you became a bit more familiar with QPython, let's create our first program in QPython. Obviously, it will be helloworld.py. ;)

    Start QPython, open editor and enter the following code:

    import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello, Username!')\n

    No wonder, it's just similar to any other hello-world program. When executed, it just shows pop-up message on the screen (see screenshot on the top). Anyway, it's a good example of QPython program.

    "},{"location":"tutorial-hello-world/#sl4a-library","title":"SL4A library","text":"

    It begins with import androidhelper \u2014 the most useful module in QPython, which encapsulates almost all interface with Android, available in Python. Any script developed in QPython starts with this statement (at least if it claims to communicate with user). Read more about Python library here and import statement here.

    By the way, if you're going to make your script compatible with SL4A, you should replace the first line with the following code (and use android instead androidhelper further in the program):

    try:\n    import androidhelper as android\nexcept ImportError:\n    import android\n

    Ok, next we're creating an object droid (actually a class), it is necessary to call RPC functions in order to communicate with Android.

    And the last line of our code calls such function, droid.makeToast(), which shows a small pop-up message (a \"toast\") on the screen.

    Well, let's add some more functionality. Let it ask the user name and greet them.

    "},{"location":"tutorial-hello-world/#more-samples","title":"More samples","text":"

    We can display a simple dialog box with the title, prompt, edit field and buttons Ok and Cancel using dialogGetInput call. Replace the last line of your code and save it as hello1.py:

    import androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\n

    Well, I think it should return any respond, any user reaction. That's why I wrote respond = .... But what the call actually returns? Let's check. Just add print statement after the last line:

    import androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\n

    Then save and run it...

    Oops! Nothing printed? Don't worry. Just pull notification bar and you will see \"QPython Program Output: hello1.py\" \u2014 tap it!

    As you can see, droid.dialogGetInput() returns a JSON object with three fields. We need only one \u2014 result which contains an actual input from user.

    Let's add script's reaction:

    import androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nmessage = f'Hello, {respond.result}!'\ndroid.makeToast(message)\n

    Last two lines (1) format the message and (2) show the message to the user in the toast. See Python docs if you still don't know what f-strings mean.

    Wow! It works! ;)

    Now I'm going to add a bit of logic there. Think: what happen if the user clicks Cancel button, or clicks Ok leaving the input field blank?

    You can play with the program checking what contains respond variable in every case.

    First of all, I want to put text entered by user to a separate variable: name = respond.result. Then I'm going to check it, and if it contains any real text, it will be considered as a name and will be used in greeting. Otherwise another message will be shown. Replace fifth line message = f'Hello, {respond.result}!' with the following code:

    name = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\n

    Use < and > buttons on the toolbar to indent/unindent lines in if-statement (or just use space/backspace keys). You can read more about indentation in Python here; if-statement described here.

    First of all, we put user input to the variable name. Then we check does name contain anything? In case the user left the line blank and clicked Ok, the return value is empty string ''. In case of Cancel button pressed, the return value is None. Both are treated as false in if-statement. So, only if name contains anything meaningful, then-statement is executed and greeting \"Hello, ...!\" shown. In case of empty input the user will see \"Hey! And you're not very polite, %Username%!\" message.

    Ok, here is the whole program:

    import androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nname = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\ndroid.makeToast(message)\n
    "},{"location":"tutorial-hello-world/#execution-result","title":"Execution result","text":""},{"location":"whats-new/","title":"What's New","text":""},{"location":"whats-new/#v392-v393","title":"v3.9.2 / v3.9.3","text":"
    • SDK upgrade with support for 16 KB page size, providing a smoother runtime environment
    • Major editor updates for a more fluid editing experience
    • Various other minor improvements
    "},{"location":"whats-new/#v391","title":"v3.9.1","text":"
    • SDK upgrade with support for 16 KB page size, providing a smoother runtime environment
    • Extension packages now support MCP
    • Bug fixes
    "},{"location":"whats-new/#v390","title":"v3.9.0","text":"
    • SDK upgrade to incorporate the latest Android features
    • Built-in Ollama 0.9.5 upgrade: Now supports running Gemma3n models locally in QPython, experiencing more powerful on-device AI computing capabilities
    • Pygame game development support: Combined with XServer, you can now easily write and run Pygame games on QPython, unleashing your creativity!
    • Personalized icon customization: Customize your desktop icons and themes through QPython settings, creating a unique programming environment
    "},{"location":"whats-new/#v3811","title":"v3.8.11","text":"
    • Built-in Ollama 0.9.5 upgrade: Now supports running Gemma3n models locally in QPython, experiencing more powerful on-device AI computing capabilities
    • Pygame game development support: Combined with XServer, you can now easily write and run Pygame games on QPython, unleashing your creativity!
    • Personalized icon customization: Customize your desktop icons and themes through QPython settings, creating a unique programming environment
    "},{"location":"whats-new/#v3810","title":"v3.8.10","text":"
    • Built-in Ollama upgrade: Now you can easily run Qwen3 / Gemma3 models locally in QPython!
    • Powerful MCP library added: Added mcp library in Extensions -> AIPY, allowing you to take powerful MCP functionality with you anywhere, anytime!
    "},{"location":"whats-new/#v389","title":"v3.8.9","text":"

    Major update! AI programming fully integrated into QPython to make your programming easier!

    • Natural language programming support: New support for AIPyApp, enabling natural language programming in QPython. Currently in beta - join our community for usage instructions
    • New QSL4A feature: Added notebookOpen function, supporting natural language control to open Notebook files
    • Built-in editor upgrade: Enhanced editor functionality, supporting opening and browsing various text files
    • Convenient file management: Added internal storage entry in file manager for quick access to your files
    "},{"location":"whats-new/#v388","title":"v3.8.8","text":"
    • Important improvements to file access permission controls, allowing users to flexibly enable or disable access to external storage files through QPython programming
    • SDK upgraded to enhance support and compatibility with newer Android versions
    • Added Anthropic and Google GenAI libraries in Extensions -> AIPY
    "},{"location":"whats-new/#v387","title":"v3.8.7","text":"
    • Based on existing Tkinter support, added sample code for drawing Doraemon using Turtle in Extensions -> Tools
    • Optimized phone permission acquisition process, improving user experience and operational convenience
    • Added Google Gen AI library in Extensions -> AIPY for easy access to Gemini Developer API and Vertex AI
    "},{"location":"whats-new/#v386","title":"v3.8.6","text":"
    • Tkinter support: Now supports Tkinter library, accessible through XServer. Please visit www.qpython.org's drive link \"Extra\" to download required files
    • Storage permission update: To improve user experience, we added permission to read phone storage for accessing Python programs stored in other directories

    After this update, QPython and QPythonPlus (not available on app stores, designed for advanced users with more sensitive permissions) will maintain synchronized version numbers.

    "},{"location":"whats-new/#v352-2025225","title":"v3.5.2 (2025/2/25)","text":"

    Achieve seamless integration with the open source LLM deployment tool Ollama and DeepSeek developed by DeepSeek!

    Features: - Zero threshold to run various large language models locally on mobile devices - Quickly deploy cutting-edge AI models such as DeepSeek - Enjoy a minimalist API calling experience - Build a completely offline intelligent programming environment

    Capabilities: - Load/manage LLM models directly on the mobile phone - Real-time low-latency response based on local computing

    "},{"location":"whats-new/#v350","title":"v3.5.0","text":"
    • Python upgraded to 3.12.8
    • Improved Dashboard for clearer, more user-friendly functionality
    • Added numerous third-party packages: PyTorch / Twisted / Scrapy / FastAPI ...
    "},{"location":"whats-new/#v338","title":"v3.3.8","text":"
    • Fixed NumPy compatibility issues
    "},{"location":"whats-new/#v335","title":"v3.3.5","text":"
    • Upgraded Python kernel to 3.11.9
    • Fixed bug where module installation status was not displayed in extensions
    • Fixed bug where deleting modules in extensions failed
    • Fixed other bugs
    "},{"location":"whats-new/#v334","title":"v3.3.4","text":"
    • Added OpenAI/Langchain/APIGPTCloud AI packages
    • Removed unnecessary files to reduce size
    "},{"location":"whats-new/#v325","title":"v3.2.5","text":"
    • Added some SL4A functions
    • Other bug fixes
    "},{"location":"whats-new/#v323","title":"v3.2.3","text":"
    • Updated Python version to 3.11.0
    • Updated IPython version to 8.6.0
    • Updated pip version to 22.3.1
    • Updated scientific computing packages with automatic soft links
    • Reduced space usage
    • Added some SL4A functions + other bug fixes
    "},{"location":"whats-new/#v318","title":"v3.1.8","text":"
    • Added operation hotkeys in terminal
    • Fixed issue where editor lost content on rotation
    • Fixed other bugs

    Download on Google Play

    "},{"location":"qsl4a/","title":"QSL4A (Scripting Layer for Android) API Documentation","text":"

    QSL4A is QPython's scripting layer for Android, allowing you to control Android device features using Python.

    "},{"location":"qsl4a/#quick-start","title":"Quick Start","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Show a toast message\ndroid.makeToast('Hello QPython!')\n\n# Vibrate the device\ndroid.vibrate(500)\n\n# Get battery level (start monitoring first)\nimport time\ndroid.batteryStartMonitoring()\ntime.sleep(0.5)  # Wait for data\nbattery = droid.readBatteryData().result\nprint(f\"Battery: {battery['level']}%\")\n
    "},{"location":"qsl4a/#documentation-structure","title":"Documentation Structure","text":""},{"location":"qsl4a/#core-modules","title":"Core Modules","text":"
    • Android Base - Core connection and RPC
    • Intent System - Android Intent operations
    • Event System - Event handling and broadcasting
    "},{"location":"qsl4a/#ui-components","title":"UI Components","text":"
    • Dialogs - Alert, input, choice dialogs
    • FullScreen UI - Custom layout UI
    • FloatView - Floating window
    • Accessibility - Screen automation
    "},{"location":"qsl4a/#system","title":"System","text":"
    • Battery - Battery monitoring
    • Sensors - Device sensors
    • Application - App management
    • System Info - Device information
    • Settings - System settings
    • WakeLock - Wake lock control
    • QPython Interface - Script execution
    • Activity Result - Activity result handling
    "},{"location":"qsl4a/#hardware","title":"Hardware","text":"
    • Bluetooth - Bluetooth operations
    • Camera - Photo and video capture
    • Audio/Recorder - Audio recording
    • Webcam - MJPEG streaming
    • USB Serial - USB host serial
    "},{"location":"qsl4a/#connectivity","title":"Connectivity","text":"
    • WiFi - WiFi operations
    • Location - GPS and location
    • SMS - SMS operations
    • Phone - Phone calls and info
    • Contacts - Contact management
    • Signal Strength - Signal monitoring
    • FTP Server - Built-in FTP server
    "},{"location":"qsl4a/#storage","title":"Storage","text":"
    • DocumentFile - File operations
    • Clipboard - Clipboard operations
    • Preferences - Shared preferences
    "},{"location":"qsl4a/#media","title":"Media","text":"
    • Media Player - Audio/Video playback
    • Image Processing - Image operations
    "},{"location":"qsl4a/#special-features","title":"Special Features","text":"
    • Cipher - Encryption/Decryption
    • PGPT AI - AI speech services
    "},{"location":"qsl4a/#result-object","title":"Result Object","text":"

    Most QSL4A methods return a Result namedtuple with: - id - Request ID - result - The actual result data - error - Error message if failed

    result = droid.getClipboard()\nif result.error is None:\n    print(result.result)\nelse:\n    print(f\"Error: {result.error}\")\n
    "},{"location":"qsl4a/connectivity/contacts/","title":"Contacts API","text":"

    Access and manage device contacts.

    "},{"location":"qsl4a/connectivity/contacts/#contact-picking","title":"Contact Picking","text":""},{"location":"qsl4a/connectivity/contacts/#pickcontact","title":"pickContact()","text":"

    Display a list of contacts to pick from.

    pickContact()\n

    Returns: Intent with contact URI

    "},{"location":"qsl4a/connectivity/contacts/#pickphone","title":"pickPhone()","text":"

    Display a list of phone numbers to pick from.

    pickPhone()\n

    Returns: Selected phone number string

    "},{"location":"qsl4a/connectivity/contacts/#contact-queries","title":"Contact Queries","text":""},{"location":"qsl4a/connectivity/contacts/#contactsget","title":"contactsGet()","text":"

    Get all contacts.

    contactsGet(attributes=None)\n

    Parameters: - attributes (list, optional): Specific attributes to retrieve

    Returns: List of contact JSONObject

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetbyid","title":"contactsGetById()","text":"

    Get a contact by ID.

    contactsGetById(id, attributes=None)\n

    Parameters: - id (int): Contact ID - attributes (list, optional): Specific attributes to retrieve

    Returns: JSONObject contact data

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetcount","title":"contactsGetCount()","text":"

    Get the total number of contacts.

    contactsGetCount()\n

    Returns: Integer count

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetids","title":"contactsGetIds()","text":"

    Get all contact IDs.

    contactsGetIds()\n

    Returns: List of contact ID integers

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetattributes","title":"contactsGetAttributes()","text":"

    Get all possible contact attributes.

    contactsGetAttributes()\n

    Returns: List of attribute names

    "},{"location":"qsl4a/connectivity/contacts/#content-queries","title":"Content Queries","text":""},{"location":"qsl4a/connectivity/contacts/#querycontent","title":"queryContent()","text":"

    Query content resolver with custom parameters.

    queryContent(uri, attributes=None, selection=None, selectionArgs=None, order=None)\n

    Parameters: - uri (str): Content URI - attributes (list, optional): Attributes to retrieve - selection (str, optional): WHERE clause - selectionArgs (list, optional): Selection arguments - order (str, optional): ORDER BY clause

    Returns: List of JSONObject results

    "},{"location":"qsl4a/connectivity/contacts/#queryattributes","title":"queryAttributes()","text":"

    Get attributes for a content URI.

    queryAttributes(uri)\n

    Parameters: - uri (str): Content URI

    Returns: JSONArray of attribute names

    "},{"location":"qsl4a/connectivity/contacts/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Pick a contact\ncontact_uri = droid.pickContact().result\nprint(f\"Selected contact: {contact_uri}\")\n\n# Pick a phone number\nphone = droid.pickPhone().result\nprint(f\"Selected phone: {phone}\")\n\n# Get all contacts\ncontacts = droid.contactsGet().result\nprint(f\"Total contacts: {len(contacts)}\")\n\n# Get contact by ID\ncontact = droid.contactsGetById(1).result\nprint(f\"Contact: {contact}\")\n\n# Get contact attributes\nattrs = droid.contactsGetAttributes().result\nprint(f\"Available attributes: {attrs}\")\n
    "},{"location":"qsl4a/connectivity/ftp/","title":"FTP Server API","text":"

    Start and manage a built-in FTP server on the device.

    "},{"location":"qsl4a/connectivity/ftp/#ftp-server-methods","title":"FTP Server Methods","text":""},{"location":"qsl4a/connectivity/ftp/#ftpstart","title":"ftpStart()","text":"

    Start the FTP server.

    ftpStart()\n

    Returns: Array containing IP address and port [ip, port]

    "},{"location":"qsl4a/connectivity/ftp/#ftpstop","title":"ftpStop()","text":"

    Stop the FTP server.

    ftpStop()\n
    "},{"location":"qsl4a/connectivity/ftp/#ftpisrunning","title":"ftpIsRunning()","text":"

    Check if FTP server is running.

    ftpIsRunning()\n

    Returns: True if running

    "},{"location":"qsl4a/connectivity/ftp/#ftpget","title":"ftpGet()","text":"

    Get FTP server IP address.

    ftpGet()\n

    Returns: Array with IP address and port

    "},{"location":"qsl4a/connectivity/ftp/#ftpset","title":"ftpSet()","text":"

    Configure FTP server settings.

    ftpSet(port=None, rootDir=None, username=None, password=None)\n

    Parameters: - port (int, optional): Server port - rootDir (str, optional): Root directory to serve - username (str, optional): Login username - password (str, optional): Login password

    Returns: JSONObject with current settings

    "},{"location":"qsl4a/connectivity/ftp/#ftpstatus","title":"ftpStatus()","text":"

    Get FTP server status.

    ftpStatus()\n

    Returns: String status description

    "},{"location":"qsl4a/connectivity/ftp/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Configure FTP server\ndroid.ftpSet(\n    port=2121,\n    rootDir=\"/sdcard\",\n    username=\"admin\",\n    password=\"secret\"\n)\n\n# Start FTP server\ninfo = droid.ftpStart().result\nprint(f\"FTP running at {info[0]}:{info[1]}\")\n\n# Check status\nif droid.ftpIsRunning().result:\n    print(\"FTP server is running\")\n\n# Get server info\nserver_info = droid.ftpGet().result\nprint(f\"Server: {server_info}\")\n\n# Stop when done\ndroid.ftpStop()\n

    Note: Connect to the FTP server using any FTP client with the provided credentials.

    "},{"location":"qsl4a/connectivity/location/","title":"Location API","text":"

    Access GPS and network location services.

    "},{"location":"qsl4a/connectivity/location/#methods","title":"Methods","text":""},{"location":"qsl4a/connectivity/location/#startlocating","title":"startLocating()","text":"

    Start location updates.

    startLocating(minUpdateTime=60000, minUpdateDistance=30, updateGnssStatus=False)\n

    Parameters: - minUpdateTime (int): Minimum time between updates in milliseconds (default: 60000) - minUpdateDistance (float): Minimum distance for update in meters (default: 30) - updateGnssStatus (bool): Enable GNSS status updates (default: False)

    "},{"location":"qsl4a/connectivity/location/#stoplocating","title":"stopLocating()","text":"

    Stop location updates.

    stopLocating()\n
    "},{"location":"qsl4a/connectivity/location/#readlocation","title":"readLocation()","text":"

    Get last known location.

    readLocation()\n

    Returns: Location data dict

    "},{"location":"qsl4a/connectivity/location/#getlastknownlocation","title":"getLastKnownLocation()","text":"

    Get cached location.

    getLastKnownLocation()\n

    Returns: Location from all providers

    "},{"location":"qsl4a/connectivity/location/#geocode","title":"geocode()","text":"

    Convert address to coordinates.

    geocode(address, maxResults=1)\n
    "},{"location":"qsl4a/connectivity/location/#location-provider-methods","title":"Location Provider Methods)","text":""},{"location":"qsl4a/connectivity/location/#locationproviders","title":"locationProviders()","text":"

    Get available location providers on the phone.

    locationProviders()\n

    Returns: List of available provider names (e.g., ['gps', 'network'])

    "},{"location":"qsl4a/connectivity/location/#locationproviderenabled","title":"locationProviderEnabled()","text":"

    Check if a specific location provider is enabled.

    locationProviderEnabled(provider)\n

    Parameters: - provider (str): Provider name (e.g., 'gps', 'network')

    Returns: True if enabled, False otherwise

    "},{"location":"qsl4a/connectivity/location/#readgnssstatus","title":"readGnssStatus()","text":"

    Read Global Navigation Satellite System status (requires Android 8+).

    readGnssStatus()\n

    Returns: JSONArray containing GNSS satellite information

    "},{"location":"qsl4a/connectivity/location/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start location updates\ndroid.startLocating(minUpdateTime=5000, minUpdateDistance=1, updateGnssStatus=False)\n\n# Wait for fix\ntime.sleep(10)\n\n# Get location\nloc = droid.readLocation().result\nif loc:\n    lat = loc['latitude']\n    lon = loc['longitude']\n    print(f\"Location: {lat}, {lon}\")\n\ndroid.stopLocating()\n
    "},{"location":"qsl4a/connectivity/phone/","title":"Phone API","text":"

    Control phone calls and retrieve phone information.

    "},{"location":"qsl4a/connectivity/phone/#phone-state-tracking","title":"Phone State Tracking","text":""},{"location":"qsl4a/connectivity/phone/#starttrackingphonestate","title":"startTrackingPhoneState()","text":"

    Start tracking phone state changes. Generates 'phone' events.

    startTrackingPhoneState()\n
    "},{"location":"qsl4a/connectivity/phone/#readphonestate","title":"readPhoneState()","text":"

    Read the current phone state.

    readPhoneState()\n

    Returns: Bundle with phone state and incoming number

    "},{"location":"qsl4a/connectivity/phone/#stoptrackingphonestate","title":"stopTrackingPhoneState()","text":"

    Stop tracking phone state.

    stopTrackingPhoneState()\n
    "},{"location":"qsl4a/connectivity/phone/#making-calls","title":"Making Calls","text":""},{"location":"qsl4a/connectivity/phone/#phonecall","title":"phoneCall()","text":"

    Call a contact/phone number by URI.

    phoneCall(uri)\n

    Parameters: - uri (str): Contact URI or phone number URI

    "},{"location":"qsl4a/connectivity/phone/#phonecallnumber","title":"phoneCallNumber()","text":"

    Call a phone number directly.

    phoneCallNumber(phone_number)\n

    Parameters: - phone_number (str): Phone number to call

    "},{"location":"qsl4a/connectivity/phone/#phonedial","title":"phoneDial()","text":"

    Dial a number (opens dialer without calling).

    phoneDial(uri)\n

    Parameters: - uri (str): Contact URI or phone number URI

    "},{"location":"qsl4a/connectivity/phone/#phonedialnumber","title":"phoneDialNumber()","text":"

    Dial a phone number (opens dialer without calling).

    phoneDialNumber(phone_number)\n

    Parameters: - phone_number (str): Phone number

    "},{"location":"qsl4a/connectivity/phone/#cell-location","title":"Cell Location","text":""},{"location":"qsl4a/connectivity/phone/#getcelllocation","title":"getCellLocation()","text":"

    Get the current cell location.

    getCellLocation()\n

    Returns: JSONObject with cell location data

    "},{"location":"qsl4a/connectivity/phone/#getallcellslocation","title":"getAllCellsLocation()","text":"

    Get all cell locations (for dual SIM devices).

    getAllCellsLocation()\n

    Returns: JSONArray of cell locations

    "},{"location":"qsl4a/connectivity/phone/#network-information","title":"Network Information","text":""},{"location":"qsl4a/connectivity/phone/#getnetworkoperator","title":"getNetworkOperator()","text":"

    Get the MCC+MNC of the current operator.

    getNetworkOperator()\n

    Returns: String (e.g., '310260')

    "},{"location":"qsl4a/connectivity/phone/#getnetworkoperatorname","title":"getNetworkOperatorName()","text":"

    Get the name of the current operator.

    getNetworkOperatorName()\n

    Returns: String (e.g., 'T-Mobile')

    "},{"location":"qsl4a/connectivity/phone/#getnetworktype","title":"getNetworkType()","text":"

    Get the current network type.

    getNetworkType()\n

    Returns: String describing radio technology (e.g., 'LTE', 'UMTS', 'GSM')

    "},{"location":"qsl4a/connectivity/phone/#getphonetype","title":"getPhoneType()","text":"

    Get the phone type.

    getPhoneType()\n

    Returns: String (e.g., 'GSM', 'CDMA', 'SIP')

    "},{"location":"qsl4a/connectivity/phone/#sim-information","title":"SIM Information","text":""},{"location":"qsl4a/connectivity/phone/#getsimcountryiso","title":"getSimCountryIso()","text":"

    Get the ISO country code for the SIM.

    getSimCountryIso()\n

    Returns: String (e.g., 'us')

    "},{"location":"qsl4a/connectivity/phone/#getsimoperator","title":"getSimOperator()","text":"

    Get the MCC+MNC of the SIM operator.

    getSimOperator()\n

    Returns: String (e.g., '310260')

    "},{"location":"qsl4a/connectivity/phone/#getsimoperatorname","title":"getSimOperatorName()","text":"

    Get the SIM operator name.

    getSimOperatorName()\n

    Returns: String (e.g., 'T-Mobile')

    "},{"location":"qsl4a/connectivity/phone/#getsimserialnumber","title":"getSimSerialNumber()","text":"

    Get the SIM serial number.

    getSimSerialNumber()\n

    Returns: String SIM serial number

    "},{"location":"qsl4a/connectivity/phone/#getsimstate","title":"getSimState()","text":"

    Get the SIM card state.

    getSimState()\n

    Returns: String describing SIM state

    "},{"location":"qsl4a/connectivity/phone/#getsubscriberid","title":"getSubscriberId()","text":"

    Get the subscriber ID.

    getSubscriberId()\n

    Returns: String subscriber ID

    "},{"location":"qsl4a/connectivity/phone/#voice-mail","title":"Voice Mail","text":""},{"location":"qsl4a/connectivity/phone/#getvoicemailalphatag","title":"getVoiceMailAlphaTag()","text":"

    Get the voice mail alpha tag.

    getVoiceMailAlphaTag()\n

    Returns: String voice mail tag

    "},{"location":"qsl4a/connectivity/phone/#getvoicemailnumber","title":"getVoiceMailNumber()","text":"

    Get the voice mail number.

    getVoiceMailNumber()\n

    Returns: String voice mail number

    "},{"location":"qsl4a/connectivity/phone/#device-information","title":"Device Information","text":""},{"location":"qsl4a/connectivity/phone/#getdeviceid","title":"getDeviceId()","text":"

    Get the device ID (IMEI for GSM). Deprecated.

    getDeviceId()\n

    Returns: String device ID

    "},{"location":"qsl4a/connectivity/phone/#getdevicesoftwareversion","title":"getDeviceSoftwareVersion()","text":"

    Get the device software version.

    getDeviceSoftwareVersion()\n

    Returns: String software version

    "},{"location":"qsl4a/connectivity/phone/#getline1number","title":"getLine1Number()","text":"

    Get the line 1 phone number.

    getLine1Number()\n

    Returns: String phone number

    "},{"location":"qsl4a/connectivity/phone/#checknetworkroaming","title":"checkNetworkRoaming()","text":"

    Check if connected to roaming network.

    checkNetworkRoaming()\n

    Returns: True if roaming

    "},{"location":"qsl4a/connectivity/phone/#cell-info","title":"Cell Info","text":""},{"location":"qsl4a/connectivity/phone/#getallcellinfo","title":"getAllCellInfo()","text":"

    Get information about all cells.

    getAllCellInfo()\n

    Returns: List of cell information

    "},{"location":"qsl4a/connectivity/phone/#setdataenabled","title":"setDataEnabled()","text":"

    Enable or disable mobile data.

    setDataEnabled(enabled)\n

    Parameters: - enabled (bool): True to enable, False to disable

    "},{"location":"qsl4a/connectivity/phone/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get network info\noperator = droid.getNetworkOperatorName().result\nprint(f\"Operator: {operator}\")\n\nnetwork_type = droid.getNetworkType().result\nprint(f\"Network: {network_type}\")\n\n# Get SIM info\nsim_state = droid.getSimState().result\nprint(f\"SIM: {sim_state}\")\n\n# Get phone number\nline1 = droid.getLine1Number().result\nprint(f\"Phone: {line1}\")\n\n# Track phone state\ndroid.startTrackingPhoneState()\nprint(\"Tracking phone state...\")\ndroid.stopTrackingPhoneState()\n
    "},{"location":"qsl4a/connectivity/signalstrength/","title":"Signal Strength API","text":"

    Monitor cellular and wireless signal strength.

    "},{"location":"qsl4a/connectivity/signalstrength/#signal-strength-methods","title":"Signal Strength Methods","text":""},{"location":"qsl4a/connectivity/signalstrength/#starttrackingsignalstrengths","title":"startTrackingSignalStrengths()","text":"

    Start tracking signal strength changes. Generates 'signal_strengths' events.

    startTrackingSignalStrengths()\n
    "},{"location":"qsl4a/connectivity/signalstrength/#stoptrackingsignalstrengths","title":"stopTrackingSignalStrengths()","text":"

    Stop tracking signal strengths.

    stopTrackingSignalStrengths()\n
    "},{"location":"qsl4a/connectivity/signalstrength/#readsignalstrengths","title":"readSignalStrengths()","text":"

    Read the current signal strengths.

    readSignalStrengths()\n

    Returns: Bundle with signal strength data

    "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthlevel","title":"getTelephoneSignalStrengthLevel()","text":"

    Get the telephone signal strength as a level (0-4).

    getTelephoneSignalStrengthLevel()\n

    Returns: Integer level (0=none, 1=poor, 2=fair, 3=good, 4=excellent)

    "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthdetail","title":"getTelephoneSignalStrengthDetail()","text":"

    Get detailed telephone signal strength information.

    getTelephoneSignalStrengthDetail()\n

    Returns: String with detailed signal info

    "},{"location":"qsl4a/connectivity/signalstrength/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start tracking signal strength\ndroid.startTrackingSignalStrengths()\n\n# Wait for signal updates\ntime.sleep(5)\n\n# Read current signal strength\nsignal = droid.readSignalStrengths().result\nprint(f\"Signal: {signal}\")\n\n# Get level directly\nlevel = droid.getTelephoneSignalStrengthLevel().result\nprint(f\"Signal level: {level}/4\")\n\ndroid.stopTrackingSignalStrengths()\n
    "},{"location":"qsl4a/connectivity/sms/","title":"SMS API","text":"

    Send and receive SMS messages.

    "},{"location":"qsl4a/connectivity/sms/#methods","title":"Methods","text":""},{"location":"qsl4a/connectivity/sms/#smssend","title":"smsSend()","text":"

    Send SMS message.

    smsSend(destinationAddress, text)\n

    Parameters: - destinationAddress (str): Phone number - text (str): Message text

    "},{"location":"qsl4a/connectivity/sms/#smsgetmessagecount","title":"smsGetMessageCount()","text":"

    Get message count.

    smsGetMessageCount(unreadOnly=False, folder=\"inbox\")\n
    "},{"location":"qsl4a/connectivity/sms/#smsgetmessageids","title":"smsGetMessageIds()","text":"

    Get message IDs.

    smsGetMessageIds(unreadOnly=False, folder=\"inbox\")\n
    "},{"location":"qsl4a/connectivity/sms/#smsgetmessages","title":"smsGetMessages()","text":"

    Get message details.

    smsGetMessages(unreadOnly=False, folder=\"inbox\", attributes=None)\n
    "},{"location":"qsl4a/connectivity/sms/#smsgetmessagebyid","title":"smsGetMessageById()","text":"

    Get a specific message by ID.

    smsGetMessageById(id, attributes=None)\n

    Parameters: - id (int): Message ID - attributes (list, optional): Specific attributes to retrieve

    Returns: Message data dict

    "},{"location":"qsl4a/connectivity/sms/#smsgetattributes","title":"smsGetAttributes()","text":"

    Get available SMS message attributes.

    smsGetAttributes()\n

    Returns: List of available attribute names

    "},{"location":"qsl4a/connectivity/sms/#smsdeletemessage","title":"smsDeleteMessage()","text":"

    Delete message.

    smsDeleteMessage(id)\n
    "},{"location":"qsl4a/connectivity/sms/#smsmarkmessageread","title":"smsMarkMessageRead()","text":"

    Mark message as read.

    smsMarkMessageRead(ids, read=True)\n
    "},{"location":"qsl4a/connectivity/sms/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Send SMS\ndroid.smsSend(\"+1234567890\", \"Hello from QPython!\")\n\n# Get unread messages\nmessages = droid.smsGetMessages(unreadOnly=True).result\nfor msg in messages:\n    print(f\"From: {msg['address']}, Text: {msg['body']}\")\n
    "},{"location":"qsl4a/connectivity/wifi/","title":"WiFi API","text":"

    Control WiFi adapter and get connection information.

    "},{"location":"qsl4a/connectivity/wifi/#adapter-control","title":"Adapter Control","text":""},{"location":"qsl4a/connectivity/wifi/#checkwifistate","title":"checkWifiState()","text":"

    Check if WiFi is enabled.

    checkWifiState()\n

    Returns: True if WiFi is enabled, False otherwise

    "},{"location":"qsl4a/connectivity/wifi/#togglewifistate","title":"toggleWifiState()","text":"

    Turn WiFi on or off.

    toggleWifiState(enabled=None)\n

    Parameters: - enabled (bool): True to enable, False to disable, None to toggle

    Returns: True if operation succeeded

    "},{"location":"qsl4a/connectivity/wifi/#wifistartscan","title":"wifiStartScan()","text":"

    Start scanning for available WiFi networks.

    wifiStartScan()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifigetscanresults","title":"wifiGetScanResults()","text":"

    Get list of discovered WiFi networks.

    wifiGetScanResults()\n

    Returns: List of access point information

    "},{"location":"qsl4a/connectivity/wifi/#connection-management","title":"Connection Management","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetconnectioninfo","title":"wifiGetConnectionInfo()","text":"

    Get detailed connection information.

    wifiGetConnectionInfo()\n

    Returns: Dict with connection details including SSID, BSSID, IP address

    "},{"location":"qsl4a/connectivity/wifi/#getconnectedinfo","title":"getConnectedInfo()","text":"

    Get connected WiFi network info (simplified).

    getConnectedInfo()\n

    Returns: Dict with SSID, BSSID, signal strength

    "},{"location":"qsl4a/connectivity/wifi/#getdhcpinfo","title":"getDhcpInfo()","text":"

    Get DHCP information for current connection.

    getDhcpInfo(ipConvertToString=True)\n

    Parameters: - ipConvertToString (bool): Convert IP addresses to string format (default: True)

    Returns: Dict with DHCP info including IP, gateway, DNS

    "},{"location":"qsl4a/connectivity/wifi/#wifidisconnect","title":"wifiDisconnect()","text":"

    Disconnect from current WiFi network.

    wifiDisconnect()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifireconnect","title":"wifiReconnect()","text":"

    Reconnect to the current network.

    wifiReconnect()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifireassociate","title":"wifiReassociate()","text":"

    Reassociate with the current access point.

    wifiReassociate()\n
    "},{"location":"qsl4a/connectivity/wifi/#hotspot","title":"Hotspot","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetapstate","title":"wifiGetApState()","text":"

    Get WiFi AP (hotspot) state.

    wifiGetApState()\n

    Returns: Hotspot state

    "},{"location":"qsl4a/connectivity/wifi/#wifi-locks","title":"WiFi Locks","text":""},{"location":"qsl4a/connectivity/wifi/#wifilockacquirefull","title":"wifiLockAcquireFull()","text":"

    Acquire a full WiFi lock (keeps WiFi active even when screen is off).

    wifiLockAcquireFull()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifilockacquirescanonly","title":"wifiLockAcquireScanOnly()","text":"

    Acquire a scan-only WiFi lock.

    wifiLockAcquireScanOnly()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifilockrelease","title":"wifiLockRelease()","text":"

    Release the WiFi lock.

    wifiLockRelease()\n
    "},{"location":"qsl4a/connectivity/wifi/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Check WiFi state\nif droid.checkWifiState().result:\n    print(\"WiFi is enabled\")\nelse:\n    print(\"Enabling WiFi...\")\n    droid.toggleWifiState(True)\n    time.sleep(2)\n\n# Start scanning\ndroid.wifiStartScan()\ntime.sleep(3)\n\n# Get scan results\nnetworks = droid.wifiGetScanResults().result\nfor network in networks:\n    print(f\"SSID: {network.get('SSID')}, Signal: {network.get('level')} dBm\")\n\n# Get connection info\ninfo = droid.wifiGetConnectionInfo().result\nif info:\n    print(f\"Connected to: {info.get('ssid')}\")\n    print(f\"BSSID: {info.get('bssid')}\")\n    print(f\"IP: {info.get('ip_address')}\")\n\n# Get DHCP info\ndhcp = droid.getDhcpInfo().result\nif dhcp:\n    print(f\"Gateway: {dhcp.get('gateway')}\")\n    print(f\"DNS: {dhcp.get('dns1')}\")\n\n# Get simplified connected info\nconnected = droid.getConnectedInfo().result\nprint(f\"SSID: {connected.get('ssid')}, Signal: {connected.get('level')} dBm\")\n\n# Disconnect and reconnect\ndroid.wifiDisconnect()\ntime.sleep(1)\ndroid.wifiReconnect()\n\n# Reassociate with access point\ndroid.wifiReassociate()\n\n# Check hotspot state\nap_state = droid.wifiGetApState().result\nprint(f\"Hotspot state: {ap_state}\")\n\n# Acquire WiFi lock for background operation\ndroid.wifiLockAcquireFull()\n# ... do work ...\ndroid.wifiLockRelease()\n\n# Or use scan-only lock for lighter background operation\ndroid.wifiLockAcquireScanOnly()\n# ... do scanning work ...\ndroid.wifiLockRelease()\n
    "},{"location":"qsl4a/core/android-base/","title":"Android Base Class","text":"

    The Android class is the core of QSL4A, providing the connection to the Android runtime and RPC mechanism.

    "},{"location":"qsl4a/core/android-base/#module-import","title":"Module Import","text":"
    # Full featured (recommended)\nimport androidhelper\ndroid = androidhelper.Android()\n\n# Minimal version (quick, single instance)\nimport android\ndroid = android.droid\n
    "},{"location":"qsl4a/core/android-base/#class-android","title":"Class: Android","text":""},{"location":"qsl4a/core/android-base/#constructor","title":"Constructor","text":"
    Android(addr=None)\n

    Parameters: - addr (tuple, optional): (HOST, PORT) address. If None, uses environment variables AP_HOST and AP_PORT

    Environment Variables: - AP_HOST - Server host address - AP_PORT - Server port - AP_HANDSHAKE - Authentication token

    "},{"location":"qsl4a/core/android-base/#core-methods","title":"Core Methods","text":""},{"location":"qsl4a/core/android-base/#_rpc","title":"_rpc()","text":"

    Internal RPC method for calling Android functions.

    _rpc(method, *args)\n

    Parameters: - method (str): Method name to call - *args: Variable arguments for the method

    Returns: Result namedtuple with fields: - id (int): Request ID - result: Method return value - error (str or None): Error message if failed

    "},{"location":"qsl4a/core/android-base/#getattr","title":"getattr()","text":"

    Dynamic method dispatcher. All Android methods are accessed via attribute lookup.

    # These are equivalent:\ndroid.makeToast(\"Hello\")\ndroid._rpc(\"makeToast\", \"Hello\")\n
    "},{"location":"qsl4a/core/android-base/#standalone-functions-androidpy","title":"Standalone Functions (android.py)","text":"

    When using the minimal android module:

    "},{"location":"qsl4a/core/android-base/#jsla","title":"jsla()","text":"

    Send JSON-RPC request and return raw response.

    jsla(method, *params)\n

    Returns: JSON string response

    "},{"location":"qsl4a/core/android-base/#rsla","title":"rsla()","text":"

    Send request and return result only.

    rsla(method, *params)\n

    Returns: Result value from RPC call

    "},{"location":"qsl4a/core/android-base/#esla","title":"esla()","text":"

    Send request, raise exception on error.

    esla(method, *params)\n

    Raises: Exception if error field is not None

    "},{"location":"qsl4a/core/android-base/#nsla","title":"nsla()","text":"

    Send request and return Result namedtuple.

    nsla(method, *params)\n

    Returns: Result namedtuple

    "},{"location":"qsl4a/core/android-base/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/android-base/#basic-connection","title":"Basic Connection","text":"
    import androidhelper\n\n# Connect to Android runtime\ndroid = androidhelper.Android()\n\n# Check connection by showing toast\ndroid.makeToast(\"Connected!\")\n
    "},{"location":"qsl4a/core/android-base/#error-handling","title":"Error Handling","text":"
    result = droid.someMethod()\nif result.error:\n    print(f\"Error: {result.error}\")\nelse:\n    print(f\"Success: {result.result}\")\n
    "},{"location":"qsl4a/core/android-base/#direct-rpc-call","title":"Direct RPC Call","text":"
    # Call any method directly\nresult = droid._rpc(\"makeToast\", \"Hello World\")\n
    "},{"location":"qsl4a/core/events/","title":"Event System","text":"

    QSL4A provides an event system for handling asynchronous events from Android, such as sensor updates, location changes, and custom broadcasts.

    "},{"location":"qsl4a/core/events/#event-basics","title":"Event Basics","text":"

    Events are stored in a buffer and can be polled or waited for. Each event has: - name: Event type/name - data: Event payload data - time: Timestamp

    "},{"location":"qsl4a/core/events/#event-methods","title":"Event Methods","text":""},{"location":"qsl4a/core/events/#eventclearbuffer","title":"eventClearBuffer()","text":"

    Clear all pending events from the buffer.

    eventClearBuffer()\n

    Returns: None

    "},{"location":"qsl4a/core/events/#eventpoll","title":"eventPoll()","text":"

    Poll for events in the buffer.

    eventPoll(number_of_events=1)\n

    Parameters: - number_of_events (int): Maximum events to retrieve (default: 1)

    Returns: List of event objects

    "},{"location":"qsl4a/core/events/#eventwait","title":"eventWait()","text":"

    Wait for any event.

    eventWait(timeout=None)\n

    Parameters: - timeout (int, optional): Timeout in seconds. None = wait forever

    Returns: Event object or None if timeout

    "},{"location":"qsl4a/core/events/#eventwaitfor","title":"eventWaitFor()","text":"

    Wait for a specific event.

    eventWaitFor(eventName, timeout=None)\n

    Parameters: - eventName (str): Name of event to wait for - timeout (int, optional): Timeout in seconds

    Returns: Event object or None if timeout

    "},{"location":"qsl4a/core/events/#eventpost","title":"eventPost()","text":"

    Post a custom event.

    eventPost(name, data, enqueue=None)\n

    Parameters: - name (str): Event name - data: Event data (any type) - enqueue (bool, optional): Add to queue if True

    "},{"location":"qsl4a/core/events/#receiveevent","title":"receiveEvent()","text":"

    Receive event (blocking).

    receiveEvent()\n

    Returns: Event object

    "},{"location":"qsl4a/core/events/#broadcast-events","title":"Broadcast Events","text":"

    Register for system broadcast events.

    "},{"location":"qsl4a/core/events/#eventregisterforbroadcast","title":"eventRegisterForBroadcast()","text":"

    Register to receive broadcast events.

    eventRegisterForBroadcast(category, enqueue=True)\n

    Parameters: - category (str): Broadcast category/action - enqueue (bool): Add to event queue

    "},{"location":"qsl4a/core/events/#eventunregisterforbroadcast","title":"eventUnregisterForBroadcast()","text":"

    Unregister from broadcast events.

    eventUnregisterForBroadcast(category)\n
    "},{"location":"qsl4a/core/events/#eventgetbrodcastcategories","title":"eventGetBrodcastCategories()","text":"

    Get registered broadcast categories.

    eventGetBrodcastCategories()\n

    Returns: List of registered categories

    "},{"location":"qsl4a/core/events/#event-dispatcher","title":"Event Dispatcher)","text":""},{"location":"qsl4a/core/events/#starteventdispatcher","title":"startEventDispatcher()","text":"

    Opens up a socket where you can read for events posted.)

    startEventDispatcher(port=0)\n

    Parameters: - port (int, optional): Port to listen on (default: 0 = auto-select)

    Returns: Port number being listened on

    "},{"location":"qsl4a/core/events/#stopeventdispatcher","title":"stopEventDispatcher()","text":"

    Stops the event server.)

    stopEventDispatcher()\n
    "},{"location":"qsl4a/core/events/#deprecated-methods","title":"Deprecated Methods","text":""},{"location":"qsl4a/core/events/#rpcpostevent","title":"rpcPostEvent()","text":"

    Post an event to the event queue. (Deprecated, use eventPost)

    rpcPostEvent(name, data)\n

    Parameters: - name (str): Event name - data: Event data

    "},{"location":"qsl4a/core/events/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/events/#basic-event-polling","title":"Basic Event Polling","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Clear old events\ndroid.eventClearBuffer()\n\n# Poll for events\nevents = droid.eventPoll(5).result\nfor event in events:\n    print(f\"Event: {event['name']}, Data: {event['data']}\")\n
    "},{"location":"qsl4a/core/events/#waiting-for-events","title":"Waiting for Events","text":"
    # Wait for any event with timeout\nevent = droid.eventWait(timeout=10).result\nif event:\n    print(f\"Got event: {event['name']}\")\n
    "},{"location":"qsl4a/core/events/#waiting-for-specific-event","title":"Waiting for Specific Event","text":"
    # Wait for sensor event\nevent = droid.eventWaitFor('screen', timeout=5).result\nif event:\n    print(f\"Screen event: {event['data']}\")\n
    "},{"location":"qsl4a/core/events/#posting-custom-events","title":"Posting Custom Events","text":"
    # Post custom event\ndroid.eventPost('my_event', {'key': 'value'})\n\n# Wait for it\nevent = droid.eventWaitFor('my_event', timeout=1).result\n
    "},{"location":"qsl4a/core/events/#broadcast-receiver","title":"Broadcast Receiver","text":"
    # Register for screen on/off events\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_ON')\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_OFF')\n\n# Wait for screen events\nwhile True:\n    event = droid.receiveEvent().result\n    if event['name'] == 'android.intent.action.SCREEN_ON':\n        print(\"Screen turned on\")\n    elif event['name'] == 'android.intent.action.SCREEN_OFF':\n        print(\"Screen turned off\")\n
    "},{"location":"qsl4a/core/events/#sensor-event-handling","title":"Sensor Event Handling","text":"
    # Start sensing\ndroid.startSensingTimed(1, 250)\n\n# Process sensor events\nfor _ in range(100):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'sensors':\n        data = event['data']\n        print(f\"Accel: {data['xforce']}, {data['yforce']}, {data['zforce']}\")\n\ndroid.stopSensing()\n
    "},{"location":"qsl4a/core/events/#common-event-types","title":"Common Event Types","text":"Event Name Description Source sensors Sensor data update startSensing* location GPS location update startLocating phone Phone state change startTrackingPhoneState signal Signal strength change startTrackingSignalStrength screen Screenshot ready fullGetScreenShot dialog Dialog response dialogShow*"},{"location":"qsl4a/core/events/#event-data-structure","title":"Event Data Structure","text":"
    {\n    'name': 'event_name',\n    'data': {\n        # Event-specific data\n    },\n    'time': 1234567890  # Timestamp\n}\n
    "},{"location":"qsl4a/core/intent/","title":"Intent System","text":"

    Android Intents are used to start activities, send broadcasts, and communicate between apps. QSL4A provides full Intent support through the Intent module.

    "},{"location":"qsl4a/core/intent/#module-import","title":"Module Import","text":"
    import androidhelper\ndon = androidhelper.Android()\n
    "},{"location":"qsl4a/core/intent/#intent-constants","title":"Intent Constants","text":"

    Access via droid.Intent:

    "},{"location":"qsl4a/core/intent/#actions","title":"Actions","text":"Constant Value Usage ACTION_MAIN android.intent.action.MAIN App entry point ACTION_VIEW android.intent.action.VIEW View content ACTION_EDIT android.intent.action.EDIT Edit content ACTION_PICK android.intent.action.PICK Pick item ACTION_SEND android.intent.action.SEND Share content ACTION_SEARCH android.intent.action.SEARCH Search"},{"location":"qsl4a/core/intent/#flags","title":"Flags","text":"Constant Value Usage FLAG_ACTIVITY_NEW_TASK 268435456 Start new task FLAG_ACTIVITY_CLEAR_TASK 32768 Clear task stack FLAG_ACTIVITY_NEW_DOCUMENT 524288 New document mode"},{"location":"qsl4a/core/intent/#extras","title":"Extras","text":"Constant Usage EXTRA_TEXT Text content EXTRA_STREAM File URI EXTRA_SUBJECT Subject line EXTRA_EMAIL Email address"},{"location":"qsl4a/core/intent/#core-methods","title":"Core Methods","text":""},{"location":"qsl4a/core/intent/#makeintent","title":"makeIntent()","text":"

    Create an Intent object.

    makeIntent(action, uri=None, type=None, extras=None, categories=None,\n           packagename=None, classname=None, flags=None)\n

    Parameters: - action (str): Intent action (e.g., droid.Intent.ACTION_VIEW) - uri (str, optional): Data URI - type (str, optional): MIME type - extras (dict, optional): Extra data - categories (list, optional): Intent categories - packagename (str, optional): Target package - classname (str, optional): Target class - flags (int, optional): Intent flags

    Returns: Intent object

    "},{"location":"qsl4a/core/intent/#startactivityintent","title":"startActivityIntent()","text":"

    Start an Activity with an Intent.

    startActivityIntent(intent, wait=None)\n

    Parameters: - intent: Intent object from makeIntent() - wait (bool, optional): Block until activity closes

    "},{"location":"qsl4a/core/intent/#startactivityforresultintent","title":"startActivityForResultIntent()","text":"

    Start activity and wait for result.

    startActivityForResultIntent(intent)\n

    Returns: Activity result

    "},{"location":"qsl4a/core/intent/#sendbroadcastintent","title":"sendBroadcastIntent()","text":"

    Send a broadcast.

    sendBroadcastIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#view","title":"view()","text":"

    View content by URI.

    view(uri, type=None, extras=None)\n
    "},{"location":"qsl4a/core/intent/#pick","title":"pick()","text":"

    Pick content from URI.

    pick(uri)\n
    "},{"location":"qsl4a/core/intent/#common-intent-methods","title":"Common Intent Methods)","text":""},{"location":"qsl4a/core/intent/#scanbarcode","title":"scanBarcode()","text":"

    Launch the barcode scanner.

    scanBarcode()\n

    Returns: Scanned barcode string

    "},{"location":"qsl4a/core/intent/#send","title":"send()","text":"

    Send content via share intent.

    send(type, content)\n

    Parameters: - type (str): MIME type - content (str): Content to share

    "},{"location":"qsl4a/core/intent/#sendtext","title":"sendText()","text":"

    Send text content.

    sendText(text)\n

    Parameters: - text (str): Text to send

    "},{"location":"qsl4a/core/intent/#sendemail","title":"sendEmail()","text":"

    Send an email.

    sendEmail(to, subject, body, attachment=None)\n

    Parameters: - to (str or list): Recipient email address(es) - subject (str): Email subject - body (str): Email body - attachment (str, optional): Attachment file path

    "},{"location":"qsl4a/core/intent/#pathtouri","title":"pathToUri()","text":"

    Convert file path to content URI.

    pathToUri(path)\n

    Parameters: - path (str): File path

    Returns: Content URI string

    "},{"location":"qsl4a/core/intent/#openfile","title":"openFile()","text":"

    Open a file with appropriate app.

    openFile(path)\n

    Parameters: - path (str): File path to open

    "},{"location":"qsl4a/core/intent/#sendfile","title":"sendFile()","text":"

    Send a file via share intent.

    sendFile(path)\n

    Parameters: - path (str): File path to send

    "},{"location":"qsl4a/core/intent/#getpathtype","title":"getPathType()","text":"

    Get the MIME type for a file path.

    getPathType(path)\n

    Parameters: - path (str): File path

    Returns: MIME type string

    "},{"location":"qsl4a/core/intent/#viewmap","title":"viewMap()","text":"

    Open map at a location.

    viewMap(latitude, longitude)\n

    Parameters: - latitude (float): Latitude - longitude (float): Longitude

    "},{"location":"qsl4a/core/intent/#viewcontacts","title":"viewContacts()","text":"

    Open the contacts app.

    viewContacts()\n
    "},{"location":"qsl4a/core/intent/#search","title":"search()","text":"

    Perform a web search.

    search(query)\n

    Parameters: - query (str): Search query

    "},{"location":"qsl4a/core/intent/#viewhtml","title":"viewHtml()","text":"

    View HTML content.

    viewHtml(content, encoding=None)\n

    Parameters: - content (str): HTML content - encoding (str, optional): Character encoding

    "},{"location":"qsl4a/core/intent/#webviewshow","title":"webViewShow()","text":"

    Display web content in WebView. Deprecated, use viewHtml.

    webViewShow(url)\n

    Parameters: - url (str): Web page URL

    "},{"location":"qsl4a/core/intent/#editoropen","title":"editorOpen()","text":"

    Open a text editor.

    editorOpen(path=None, create=False)\n

    Parameters: - path (str, optional): File path to edit - create (bool, optional): Create if doesn't exist

    "},{"location":"qsl4a/core/intent/#helper-class-uri","title":"Helper Class: Uri","text":"

    Create URI objects for Intents:

    from androidhelper.Intent import Uri\n\nuri = Uri(\"file:///sdcard/test.txt\")\n
    "},{"location":"qsl4a/core/intent/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/intent/#open-web-page","title":"Open Web Page","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"http://www.example.com\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#share-text","title":"Share Text","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_TEXT: \"Hello from QPython!\",\n        droid.Intent.EXTRA_SUBJECT: \"Test\"\n    },\n    type=\"text/plain\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#open-file","title":"Open File","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"file:///sdcard/document.pdf\",\n    type=\"application/pdf\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#pick-contact","title":"Pick Contact","text":"
    result = droid.pickContact()\ncontact_uri = result.result\n
    "},{"location":"qsl4a/core/intent/#send-email","title":"Send Email","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_EMAIL: [\"test@example.com\"],\n        droid.Intent.EXTRA_SUBJECT: \"Hello\",\n        droid.Intent.EXTRA_TEXT: \"Message body\"\n    },\n    type=\"message/rfc822\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#open-app","title":"Open App","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_MAIN,\n    packagename=\"com.android.settings\",\n    classname=\"com.android.settings.Settings\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/hardware/bluetooth/","title":"Bluetooth API","text":"

    Control Bluetooth adapter and communicate with Bluetooth devices.

    "},{"location":"qsl4a/hardware/bluetooth/#adapter-control","title":"Adapter Control","text":""},{"location":"qsl4a/hardware/bluetooth/#togglebluetoothstate","title":"toggleBluetoothState()","text":"

    Turn Bluetooth on/off.

    toggleBluetoothState(enabled=None, prompt=True)\n

    Parameters: - enabled (bool): True=on, False=off, None=toggle - prompt (bool): Show user prompt

    "},{"location":"qsl4a/hardware/bluetooth/#checkbluetoothstate","title":"checkBluetoothState()","text":"

    Check if Bluetooth is enabled.

    checkBluetoothState()\n

    Returns: True/False

    "},{"location":"qsl4a/hardware/bluetooth/#getlocalname","title":"GetLocalName()","text":"

    Get Bluetooth device name.

    GetLocalName()\n
    "},{"location":"qsl4a/hardware/bluetooth/#setlocalname","title":"SetLocalName()","text":"

    Set Bluetooth device name.

    SetLocalName(name)\n
    "},{"location":"qsl4a/hardware/bluetooth/#getscanmode","title":"GetScanMode()","text":"

    Get discoverability mode.

    GetScanMode()\n

    Returns: - -1: Disabled - 0: Non-discoverable, non-connectable - 1: Connectable, non-discoverable - 3: Connectable and discoverable

    "},{"location":"qsl4a/hardware/bluetooth/#makediscoverable","title":"MakeDiscoverable()","text":"

    Make device discoverable.

    MakeDiscoverable(duration=300)\n

    Parameters: - duration (int): Seconds to be discoverable

    "},{"location":"qsl4a/hardware/bluetooth/#discovery","title":"Discovery","text":""},{"location":"qsl4a/hardware/bluetooth/#discoverystart","title":"DiscoveryStart()","text":"

    Start device discovery.

    DiscoveryStart()\n
    "},{"location":"qsl4a/hardware/bluetooth/#discoverycancel","title":"DiscoveryCancel()","text":"

    Cancel discovery.

    DiscoveryCancel()\n
    "},{"location":"qsl4a/hardware/bluetooth/#getreceiveddevices","title":"GetReceivedDevices()","text":"

    Get discovered devices.

    GetReceivedDevices()\n

    Returns: List of device info dicts

    "},{"location":"qsl4a/hardware/bluetooth/#getbondeddevices","title":"GetBondedDevices()","text":"

    Get paired devices.

    GetBondedDevices()\n

    Returns: List of paired device info

    "},{"location":"qsl4a/hardware/bluetooth/#connection","title":"Connection","text":""},{"location":"qsl4a/hardware/bluetooth/#connect","title":"Connect()","text":"

    Connect to a device.

    Connect(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", address=None)\n

    Parameters: - uuid (str): Service UUID - address (str): Device address (None = show picker)

    Returns: True if successful

    "},{"location":"qsl4a/hardware/bluetooth/#accept","title":"Accept()","text":"

    Accept incoming connection.

    Accept(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", timeout=0)\n
    "},{"location":"qsl4a/hardware/bluetooth/#activeconnections","title":"ActiveConnections()","text":"

    Check active connections.

    ActiveConnections()\n
    "},{"location":"qsl4a/hardware/bluetooth/#stop","title":"Stop()","text":"

    Disconnect.

    Stop(connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#communication","title":"Communication","text":""},{"location":"qsl4a/hardware/bluetooth/#write","title":"Write()","text":"

    Send ASCII data.

    Write(ascii, connID=\"\")\n
    "},{"location":"qsl4a/hardware/bluetooth/#writebinary","title":"WriteBinary()","text":"

    Send binary data (base64 encoded).

    WriteBinary(base64, connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#read","title":"Read()","text":"

    Read ASCII data.

    Read(bufferSize=4096, connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#readbinary","title":"ReadBinary()","text":"

    Read binary data.

    ReadBinary(bufferSize=4096, connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#readline","title":"ReadLine()","text":"

    Read line.

    ReadLine(connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#readready","title":"ReadReady()","text":"

    Check if data available.

    ReadReady(connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Enable Bluetooth\ndroid.toggleBluetoothState(True)\n\n# Get paired devices\ndevices = droid.GetBondedDevices().result\nfor dev in devices:\n    print(f\"{dev['name']}: {dev['address']}\")\n\n# Connect to device\ndroid.Connect(address=\"00:11:22:33:44:55\")\n\n# Send data\ndroid.Write(\"Hello Bluetooth!\")\n\n# Read response\ndata = droid.Read(1024).result\n
    "},{"location":"qsl4a/hardware/camera/","title":"Camera API","text":"

    Capture photos and record video.

    "},{"location":"qsl4a/hardware/camera/#photo-capture","title":"Photo Capture","text":""},{"location":"qsl4a/hardware/camera/#takepicture","title":"takePicture()","text":"

    Take a photo using the default camera.

    takePicture(path=None)\n

    Parameters: - path (str, optional): Save path. If None, returns image data

    Returns: Image path or image data

    "},{"location":"qsl4a/hardware/camera/#cameracapturepicture","title":"cameraCapturePicture()","text":"

    Capture picture with advanced camera controls.

    cameraCapturePicture(targetPath=None, cameraId=0, useAutoFocus=True)\n

    Parameters: - targetPath (str, optional): Save path - cameraId (int): Camera to use (0 = back, 1 = front) - useAutoFocus (bool): Enable auto focus

    Returns: Captured image path

    "},{"location":"qsl4a/hardware/camera/#camerasettorchmode","title":"cameraSetTorchMode()","text":"

    Control camera flashlight/torch.

    cameraSetTorchMode(enabled)\n

    Parameters: - enabled (bool): True to turn on, False to turn off

    Returns: True if successful

    "},{"location":"qsl4a/hardware/camera/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

    Capture screenshot.

    imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

    Parameters: - path (str, optional): Save path - delayMilliSec (int): Delay before capture

    "},{"location":"qsl4a/hardware/camera/#video-recording","title":"Video Recording","text":""},{"location":"qsl4a/hardware/camera/#takevideo","title":"takeVideo()","text":"

    Record video using default settings.

    takeVideo(path=None, quality=1)\n

    Parameters: - path (str, optional): Save path - quality (int): Video quality (0-4) - 0: 160x120 - 1: 320x240 - 2: 352x288 - 3: 640x480 - 4: 800x480

    "},{"location":"qsl4a/hardware/camera/#recordercapturevideo","title":"recorderCaptureVideo()","text":"

    Capture video with advanced controls.

    recorderCaptureVideo(targetPath=None, duration=10, cameraId=0, quality=8)\n

    Parameters: - targetPath (str, optional): Save path - duration (int): Recording duration in seconds (default: 10) - cameraId (int): Camera to use (0 = back, 1 = front) - quality (int): Video quality (0-8, higher is better)

    Returns: Video file path

    "},{"location":"qsl4a/hardware/camera/#recordaudio","title":"recordAudio()","text":"

    Record audio.

    recordAudio()\n

    Returns: Audio file path

    "},{"location":"qsl4a/hardware/camera/#screen-recording","title":"Screen Recording","text":""},{"location":"qsl4a/hardware/camera/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

    Start screen recording.

    recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

    Parameters: - path (str): Save path - audio (int): Audio source (0=none, 1=mic, 2=internal) - targetPixels (int): Resolution - frameRate (int): FPS - bitRate (int): Bitrate - rotation (bool): Rotate output - autoStart (bool): Start immediately

    "},{"location":"qsl4a/hardware/camera/#recorderstart","title":"recorderStart()","text":"

    Start recording.

    recorderStart()\n
    "},{"location":"qsl4a/hardware/camera/#recorderpause","title":"recorderPause()","text":"

    Pause recording.

    recorderPause()\n
    "},{"location":"qsl4a/hardware/camera/#recorderresume","title":"recorderResume()","text":"

    Resume recording.

    recorderResume()\n
    "},{"location":"qsl4a/hardware/camera/#audio-volume-detection","title":"Audio Volume Detection","text":""},{"location":"qsl4a/hardware/camera/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

    Start volume detection.

    recorderSoundVolumeDetect(interval=100)\n
    "},{"location":"qsl4a/hardware/camera/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

    Get current volume in dB.

    recorderSoundVolumeGetDb()\n
    "},{"location":"qsl4a/hardware/camera/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Take photo with default camera\nphoto_path = droid.takePicture(\"/sdcard/photo.jpg\").result\nprint(f\"Photo saved: {photo_path}\")\n\n# Take photo with front camera and auto focus\ncamera_path = droid.cameraCapturePicture(\"/sdcard/selfie.jpg\", cameraId=1, useAutoFocus=True).result\nprint(f\"Front camera photo: {camera_path}\")\n\n# Control flashlight\ndroid.cameraSetTorchMode(True)  # Turn on flashlight\n\n# Record video with default settings\nvideo_path = droid.takeVideo(\"/sdcard/video.mp4\", quality=3).result\nprint(f\"Video saved: {video_path}\")\n\n# Record video with advanced controls\nvideo_path = droid.recorderCaptureVideo(\"/sdcard/movie.mp4\", duration=30, cameraId=0, quality=8).result\n\n# Screenshot\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n
    "},{"location":"qsl4a/hardware/recorder/","title":"Audio Recorder API","text":"

    Record audio from microphone and device screen.

    "},{"location":"qsl4a/hardware/recorder/#audio-recording","title":"Audio Recording","text":""},{"location":"qsl4a/hardware/recorder/#recordaudio","title":"recordAudio()","text":"

    Record audio from microphone.

    recordAudio()\n

    Returns: Path to recorded audio file

    "},{"location":"qsl4a/hardware/recorder/#recorderstartmicrophone","title":"recorderStartMicrophone()","text":"

    Start recording from microphone to a specific file.

    recorderStartMicrophone(targetPath=None)\n

    Parameters: - targetPath (str, optional): Path to save the recording

    "},{"location":"qsl4a/hardware/recorder/#screen-recording","title":"Screen Recording","text":""},{"location":"qsl4a/hardware/recorder/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

    Start screen recording with audio.

    recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

    Parameters: - path (str): Save path for video file - audio (int): Audio source (0=none, 1=mic, 2=internal audio) - targetPixels (int): Target resolution in pixels - frameRate (int): Frames per second (default: 30) - bitRate (int): Video bitrate - rotation (bool): Rotate output video - autoStart (bool): Start recording immediately

    Returns: Result of operation

    "},{"location":"qsl4a/hardware/recorder/#recorderstart","title":"recorderStart()","text":"

    Start the screen recording (when autoStart=False).

    recorderStart()\n
    "},{"location":"qsl4a/hardware/recorder/#recorderpause","title":"recorderPause()","text":"

    Pause ongoing screen recording.

    recorderPause()\n
    "},{"location":"qsl4a/hardware/recorder/#recorderresume","title":"recorderResume()","text":"

    Resume paused screen recording.

    recorderResume()\n
    "},{"location":"qsl4a/hardware/recorder/#audio-volume-detection","title":"Audio Volume Detection","text":""},{"location":"qsl4a/hardware/recorder/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

    Start monitoring sound volume level.

    recorderSoundVolumeDetect(interval=100)\n

    Parameters: - interval (int): Detection interval in milliseconds (default: 100)

    "},{"location":"qsl4a/hardware/recorder/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

    Get current sound volume in decibels.

    recorderSoundVolumeGetDb()\n

    Returns: Current volume level in dB

    "},{"location":"qsl4a/hardware/recorder/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Record audio from microphone\nprint(\"Recording audio...\")\naudio_path = droid.recordAudio().result\nprint(f\"Saved to: {audio_path}\")\n\n# Record microphone to specific file\ndroid.recorderStartMicrophone(\"/sdcard/my_recording.mp3\")\ntime.sleep(5)\ndroid.recorderStop()\n\n# Record screen with audio\nprint(\"Starting screen recording...\")\ndroid.recorderStartScreenRecord(\n    path=\"/sdcard/screen_record.mp4\",\n    audio=1,\n    frameRate=30,\n    autoStart=True\n)\ntime.sleep(10)\ndroid.recorderStop()\n\n# Monitor sound volume\ndroid.recorderSoundVolumeDetect(interval=100)\ntime.sleep(3)\nvolume = droid.recorderSoundVolumeGetDb().result\nprint(f\"Current volume: {volume} dB\")\n
    "},{"location":"qsl4a/hardware/usbserial/","title":"USB Host Serial API","text":"

    Communicate with USB serial devices (requires USB OTG support and Android 3.1+).

    "},{"location":"qsl4a/hardware/usbserial/#usb-serial-methods","title":"USB Serial Methods)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialopen","title":"usbHostSerialOpen()","text":"

    Open a connection to a USB serial device.

    usbHostSerialOpen(device, baudRate=9600)\n

    Parameters: - device (str): USB device path or identifier - baudRate (int): Baud rate (default: 9600)

    Returns: True if opened successfully

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialclose","title":"usbHostSerialClose()","text":"

    Close the USB serial connection.

    usbHostSerialClose()\n
    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialread","title":"usbHostSerialRead()","text":"

    Read data from USB serial.

    usbHostSerialRead(bufferSize=1024)\n

    Parameters: - bufferSize (int): Maximum bytes to read (default: 1024)

    Returns: String read data

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwrite","title":"usbHostSerialWrite()","text":"

    Write data to USB serial.

    usbHostSerialWrite(data)\n

    Parameters: - data (str): String data to write

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialavailable","title":"usbHostSerialAvailable()","text":"

    Check if data is available to read.

    usbHostSerialAvailable()\n

    Returns: Number of bytes available

    "},{"location":"qsl4a/hardware/usbserial/#configuration-methods","title":"Configuration Methods)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetbaudrate","title":"usbHostSerialSetBaudRate()","text":"

    Set the baud rate.

    usbHostSerialSetBaudRate(baudRate)\n

    Parameters: - baudRate (int): Baud rate

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetdatabits","title":"usbHostSerialSetDataBits()","text":"

    Set data bits (5, 6, 7, or 8).

    usbHostSerialSetDataBits(dataBits)\n

    Parameters: - dataBits (int): Data bits (5-8)

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetstopbits","title":"usbHostSerialSetStopBits()","text":"

    Set stop bits (1, 1.5, or 2).

    usbHostSerialSetStopBits(stopBits)\n

    Parameters: - stopBits (float): Stop bits (1, 1.5, or 2)

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetparity","title":"usbHostSerialSetParity()","text":"

    Set parity (none, odd, even, mark, space).

    usbHostSerialSetParity(parity)\n

    Parameters: - parity (str): Parity mode ('none', 'odd', 'even', 'mark', 'space')

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetflowcontrol","title":"usbHostSerialSetFlowControl()","text":"

    Set flow control (none, hardware, software).

    usbHostSerialSetFlowControl(flowControl)\n

    Parameters: - flowControl (str): Flow control mode ('none', 'hardware', 'software')

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialreadhex","title":"usbHostSerialReadHex()","text":"

    Read data as hex string.

    usbHostSerialReadHex(bufferSize=1024)\n

    Parameters: - bufferSize (int): Maximum bytes to read

    Returns: Hex string

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwritehex","title":"usbHostSerialWriteHex()","text":"

    Write data from hex string.

    usbHostSerialWriteHex(hexString)\n

    Parameters: - hexString (str): Hex string to write

    "},{"location":"qsl4a/hardware/usbserial/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Open USB serial connection\nif droid.usbHostSerialOpen(\"/dev/bus/usb/001/001\", 115200).result:\n    print(\"USB serial opened\")\n\n    # Write data\n    droid.usbHostSerialWrite(\"AT\\r\")\n\n    # Read response\n    response = droid.usbHostSerialRead(1024).result\n    print(f\"Response: {response}\")\n\n    # Or use hex\n    droid.usbHostSerialWriteHex(\"41540D0A\")  # \"AT\\r\\n\"\n\n    # Close connection\n    droid.usbHostSerialClose()\n

    Note: USB serial requires: - Android 3.1+ (API 12) - USB OTG cable/adapter - USB host mode support on device - Compatible serial device

    "},{"location":"qsl4a/hardware/webcam/","title":"Webcam API","text":"

    Stream video from the device camera using MJPEG.

    "},{"location":"qsl4a/hardware/webcam/#mjpeg-stream-methods","title":"MJPEG Stream Methods","text":""},{"location":"qsl4a/hardware/webcam/#webcamstart","title":"webcamStart()","text":"

    Start an MJPEG stream from the webcam.

    webcamStart(resolutionLevel=0, jpegQuality=20, port=0)\n

    Parameters: - resolutionLevel (int): Resolution level (default: 0) - jpegQuality (int): JPEG quality 1-100 (default: 20) - port (int): Port number (default: 0 = auto)

    Returns: Tuple of (address, port) for the stream

    "},{"location":"qsl4a/hardware/webcam/#webcamadjustquality","title":"webcamAdjustQuality()","text":"

    Adjust the quality of an active webcam stream.

    webcamAdjustQuality(resolutionLevel=0, jpegQuality=20)\n

    Parameters: - resolutionLevel (int): Resolution level - jpegQuality (int): JPEG quality 1-100

    "},{"location":"qsl4a/hardware/webcam/#webcamstop","title":"webcamStop()","text":"

    Stop the webcam stream.

    webcamStop()\n
    "},{"location":"qsl4a/hardware/webcam/#camera-preview-methods","title":"Camera Preview Methods","text":""},{"location":"qsl4a/hardware/webcam/#camerastartpreview","title":"cameraStartPreview()","text":"

    Start camera preview mode with event generation.

    cameraStartPreview(resolutionLevel=0, jpegQuality=20, filepath=None)\n

    Parameters: - resolutionLevel (int): Resolution level (default: 0) - jpegQuality (int): JPEG quality (default: 20) - filepath (str, optional): File path to save preview frames

    Returns: True if successful

    Note: Generates 'preview' events with frame data.

    "},{"location":"qsl4a/hardware/webcam/#camerastoppreview","title":"cameraStopPreview()","text":"

    Stop the camera preview.

    cameraStopPreview()\n
    "},{"location":"qsl4a/hardware/webcam/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start webcam stream\nstream_info = droid.webcamStart(\n    resolutionLevel=0,\n    jpegQuality=30,\n    port=8080\n).result\nprint(f\"Stream available at {stream_info[0]}:{stream_info[1]}\")\n\n# Adjust quality while streaming\ntime.sleep(5)\ndroid.webcamAdjustQuality(resolutionLevel=1, jpegQuality=50)\n\n# Stop when done\ndroid.webcamStop()\n\n# Or use preview mode\nprint(\"Starting preview...\")\ndroid.cameraStartPreview()\n\n# Wait for preview events\nfor i in range(10):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'preview':\n        print(f\"Got preview frame: {event['data']}\")\n\ndroid.cameraStopPreview()\n
    "},{"location":"qsl4a/media/image/","title":"Image Processing API","text":"

    Compress and process images.

    "},{"location":"qsl4a/media/image/#image-compression","title":"Image Compression","text":""},{"location":"qsl4a/media/image/#imagecompress","title":"imageCompress()","text":"

    Compress image file.

    imageCompress(srcPath, destPath, targetByteSize=0, targetWidth=0, targetHeight=0)\n

    Parameters: - srcPath (str): Source image path - destPath (str): Output path - targetByteSize (int): Target file size in bytes (0 = no limit) - targetWidth (int): Target width (0 = original) - targetHeight (int): Target height (0 = original)

    Returns: Compressed image path

    "},{"location":"qsl4a/media/image/#screenshot","title":"Screenshot","text":""},{"location":"qsl4a/media/image/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

    Capture screen.

    imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

    Parameters: - path (str): Save path - delayMilliSec (int): Delay before capture

    Returns: Screenshot path

    "},{"location":"qsl4a/media/image/#video-playback","title":"Video Playback","text":""},{"location":"qsl4a/media/image/#videoplay","title":"videoPlay()","text":"

    Play video file in fullscreen mode.

    videoPlay(path, wait=True)\n

    Parameters: - path (str): Video file path - wait (bool): Wait for playback to complete (default: True)

    "},{"location":"qsl4a/media/image/#barcode-scanning","title":"Barcode Scanning","text":""},{"location":"qsl4a/media/image/#scanbarcodefromimage","title":"scanBarcodeFromImage()","text":"

    Scan barcode/QR code from image file.

    scanBarcodeFromImage(path, compressRatio=0, x=0, y=0, width=0, height=0)\n

    Parameters: - path (str): Image file path - compressRatio (int): Compression ratio (0 = no compression) - x, y, width, height (int): Region to scan (0 = full image)

    Returns: Scanned barcode content

    "},{"location":"qsl4a/media/image/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Take screenshot\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n\n# Compress image\ncompressed = droid.imageCompress(\n    \"/sdcard/large_photo.jpg\",\n    \"/sdcard/compressed.jpg\",\n    targetByteSize=102400,  # Target ~100KB\n    targetWidth=1920,\n    targetHeight=1080\n).result\nprint(f\"Saved: {compressed}\")\n\n# Play video\nvideo_path = \"/sdcard/movie.mp4\"\ndroid.videoPlay(video_path, wait=True)\n\n# Scan barcode from image\nresult = droid.scanBarcodeFromImage(\"/sdcard/qr_code.png\").result\nprint(f\"Barcode: {result}\")\n
    "},{"location":"qsl4a/media/mediaplayer/","title":"Media Player API","text":"

    Control audio and video playback.

    "},{"location":"qsl4a/media/mediaplayer/#playback-control","title":"Playback Control","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplay","title":"mediaPlay()","text":"

    Play media file.

    mediaPlay(url, tag=\"default\", play=True)\n

    Parameters: - url (str): Media file path or URL - tag (str): Player identifier - play (bool): Auto-start playback

    "},{"location":"qsl4a/media/mediaplayer/#mediaplaystart","title":"mediaPlayStart()","text":"

    Start playback.

    mediaPlayStart(tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#mediaplaypause","title":"mediaPlayPause()","text":"

    Pause playback.

    mediaPlayPause(tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#mediaplayclose","title":"mediaPlayClose()","text":"

    Close player.

    mediaPlayClose(tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#mediaplayseek","title":"mediaPlaySeek()","text":"

    Seek to position.

    mediaPlaySeek(msec, tag=\"default\")\n

    Parameters: - msec (int): Position in milliseconds

    "},{"location":"qsl4a/media/mediaplayer/#mediaplaysetlooping","title":"mediaPlaySetLooping()","text":"

    Set loop mode.

    mediaPlaySetLooping(enabled, tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#player-info","title":"Player Info","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplayinfo","title":"mediaPlayInfo()","text":"

    Get playback info.

    mediaPlayInfo(tag=\"default\")\n

    Returns: Dict with duration, position, etc.

    "},{"location":"qsl4a/media/mediaplayer/#mediaisplaying","title":"mediaIsPlaying()","text":"

    Check if playing.

    mediaIsPlaying(tag=\"default\")\n

    Returns: True/False

    "},{"location":"qsl4a/media/mediaplayer/#mediaplaylist","title":"mediaPlayList()","text":"

    List active players.

    mediaPlayList()\n
    "},{"location":"qsl4a/media/mediaplayer/#volume-control","title":"Volume Control","text":""},{"location":"qsl4a/media/mediaplayer/#getmediavolume","title":"getMediaVolume()","text":"

    Get media volume.

    getMediaVolume()\n

    Returns: Volume level (0-15)

    "},{"location":"qsl4a/media/mediaplayer/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

    Get max media volume.

    getMaxMediaVolume()\n
    "},{"location":"qsl4a/media/mediaplayer/#getringervolume","title":"getRingerVolume()","text":"

    Get ringer volume.

    getRingerVolume()\n
    "},{"location":"qsl4a/media/mediaplayer/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

    Get max ringer volume.

    getMaxRingerVolume()\n
    "},{"location":"qsl4a/media/mediaplayer/#video-playback","title":"Video Playback","text":""},{"location":"qsl4a/media/mediaplayer/#videoplay","title":"videoPlay()","text":"

    Play video fullscreen.

    videoPlay(path, wait=True)\n

    Parameters: - path (str): Video file path - wait (bool): Wait for playback to complete

    "},{"location":"qsl4a/media/mediaplayer/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Play audio\ndroid.mediaPlay(\"/sdcard/music.mp3\", tag=\"music\")\n\n# Check status\nif droid.mediaIsPlaying(\"music\").result:\n    info = droid.mediaPlayInfo(\"music\").result\n    print(f\"Playing: {info}\")\n\n# Seek to 30 seconds\ndroid.mediaPlaySeek(30000, \"music\")\n\n# Close\ndroid.mediaPlayClose(\"music\")\n\n# Play video\ndroid.videoPlay(\"/sdcard/movie.mp4\", wait=True)\n
    "},{"location":"qsl4a/special/cipher/","title":"Cipher API","text":"

    Encryption and decryption utilities for secure data storage.

    "},{"location":"qsl4a/special/cipher/#initialization","title":"Initialization","text":""},{"location":"qsl4a/special/cipher/#cipherinit","title":"cipherInit()","text":"

    Initialize the cipher with encryption key and algorithm.

    cipherInit(key, algorithm=\"AES/CBC/PKCS5Padding\", encodingFormat=\"\", initialVector=\"\")\n

    Parameters: - key (str or bytes): Encryption key - algorithm (str): Cipher algorithm (default: \"AES/CBC/PKCS5Padding\") - encodingFormat (str): Encoding format - initialVector (str or bytes): Initial vector for encryption

    Returns: Initialization result

    Note: Must be called before any encrypt/decrypt operations.

    "},{"location":"qsl4a/special/cipher/#encryption-methods","title":"Encryption Methods","text":""},{"location":"qsl4a/special/cipher/#encryptstring","title":"encryptString()","text":"

    Encrypt a string.

    encryptString(plainText)\n

    Parameters: - plainText (str): Text to encrypt

    Returns: Encrypted string

    "},{"location":"qsl4a/special/cipher/#encryptbytes","title":"encryptBytes()","text":"

    Encrypt bytes data.

    encryptBytes(data)\n

    Parameters: - data (bytes): Data to encrypt

    Returns: Encrypted bytes

    "},{"location":"qsl4a/special/cipher/#encryptstringtofile","title":"encryptStringToFile()","text":"

    Encrypt string to file.

    encryptStringToFile(plainText, filePath)\n

    Parameters: - plainText (str): Text to encrypt - filePath (str): Output file path

    "},{"location":"qsl4a/special/cipher/#encryptbytestofile","title":"encryptBytesToFile()","text":"

    Encrypt bytes to file.

    encryptBytesToFile(data, filePath)\n
    "},{"location":"qsl4a/special/cipher/#decryption-methods","title":"Decryption Methods","text":""},{"location":"qsl4a/special/cipher/#decryptstring","title":"decryptString()","text":"

    Decrypt to string.

    decryptString(cipherText)\n

    Parameters: - cipherText (str): Encrypted text

    Returns: Decrypted string

    "},{"location":"qsl4a/special/cipher/#decryptbytes","title":"decryptBytes()","text":"

    Decrypt to bytes.

    decryptBytes(data)\n

    Returns: Decrypted bytes

    "},{"location":"qsl4a/special/cipher/#decryptfiletostring","title":"decryptFileToString()","text":"

    Decrypt file to string.

    decryptFileToString(filePath)\n
    "},{"location":"qsl4a/special/cipher/#decryptfiletobytes","title":"decryptFileToBytes()","text":"

    Decrypt file to bytes.

    decryptFileToBytes(filePath)\n
    "},{"location":"qsl4a/special/cipher/#decryptfile","title":"decryptFile()","text":"

    Decrypt file to file.

    decryptFile(srcPath, destPath)\n
    "},{"location":"qsl4a/special/cipher/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Initialize cipher with your encryption key\ndroid.cipherInit(\"my_secret_key_1234\")\n\n# Encrypt string\nencrypted = droid.encryptString(\"Secret message!\").result\nprint(f\"Encrypted: {encrypted}\")\n\n# Decrypt string\ndecrypted = droid.decryptString(encrypted).result\nprint(f\"Decrypted: {decrypted}\")\n\n# Encrypt to file\ndroid.encryptStringToFile(\"My secret data\", \"/sdcard/secret.dat\")\n\n# Decrypt from file\ndata = droid.decryptFileToString(\"/sdcard/secret.dat\").result\nprint(data)\n\n# Initialize with custom algorithm and IV\ndroid.cipherInit(\n    key=\"my_key\",\n    algorithm=\"AES/CBC/PKCS5Padding\",\n    initialVector=\"0123456789abcdef\"\n)\n
    "},{"location":"qsl4a/special/pgptai/","title":"PGPT AI API","text":"

    Speech-to-text and AI services integration.

    "},{"location":"qsl4a/special/pgptai/#prerequisites","title":"Prerequisites","text":"
    pip install pgptAI\n
    "},{"location":"qsl4a/special/pgptai/#speech-recognition","title":"Speech Recognition","text":""},{"location":"qsl4a/special/pgptai/#speechtotext","title":"speechToText()","text":"

    Convert speech to text.

    speechToText(RecordSecond=10, AmrFile=None, Language=None)\n

    Parameters: - RecordSecond (int): Recording duration in seconds - AmrFile (str, optional): Existing audio file path - Language (str, optional): Language code ('en', 'zh')

    Returns: Transcribed text

    "},{"location":"qsl4a/special/pgptai/#text-to-speech","title":"Text to Speech","text":""},{"location":"qsl4a/special/pgptai/#texttospeech","title":"textToSpeech()","text":"

    Convert text to speech and optionally play it.

    textToSpeech(Text, AutoPlay=True, WavFile=None, VoiceName=None)\n

    Parameters: - Text (str): Text to convert to speech - AutoPlay (bool): Automatically play the generated audio (default: True) - WavFile (str, optional): Path to save the WAV file. If None, uses temporary file - VoiceName (str, optional): Voice name to use (e.g., 'en-US-JennyNeural', 'zh-CN-XiaoxiaoNeural')

    Returns: Dict with speech synthesis result including: - text: The input text - url: URL to download the audio file - WavFile: Path to the saved WAV file (if saved locally)

    "},{"location":"qsl4a/special/pgptai/#configuration","title":"Configuration","text":"

    The API uses configuration from /storage/emulated/0/Android/data/org.qpython.qpy/files/apigpt.conf:

    [speech]\nspeech_key = your_api_key\n

    Default voice settings: - English: en-US-JennyNeural - Chinese: zh-CN-XiaoxiaoNeural

    "},{"location":"qsl4a/special/pgptai/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Record and transcribe\nprint(\"Recording for 5 seconds...\")\ntext = droid.speechToText(RecordSecond=5, Language='en').result\nprint(f\"You said: {text}\")\n\n# Transcribe existing file\ntext = droid.speechToText(AmrFile=\"/sdcard/recording.amr\").result\nprint(f\"Transcription: {text}\")\n\n# Text to speech\ndroid.textToSpeech(\"Hello, this is a test message.\", AutoPlay=True, Language='en')\n\n# Text to speech with custom voice and save to file\nresult = droid.textToSpeech(\n    \"Welcome to QPython!\",\n    AutoPlay=False,\n    WavFile=\"/sdcard/welcome.wav\",\n    VoiceName=\"en-US-JennyNeural\"\n).result\nprint(f\"Audio saved to: {result.get('WavFile')}\")\n
    "},{"location":"qsl4a/special/pgptai/#class-usage","title":"Class Usage","text":"
    from androidhelper.pgptai import pgptai\nimport androidhelper\n\ndroid = androidhelper.Android()\nai = pgptai(droid)\n\n# Use speech recognition\ntext = ai.speechToText(RecordSecond=10)\n
    "},{"location":"qsl4a/storage/clipboard/","title":"Clipboard API","text":"

    Copy and paste text to system clipboard.

    "},{"location":"qsl4a/storage/clipboard/#methods","title":"Methods","text":""},{"location":"qsl4a/storage/clipboard/#setclipboard","title":"setClipboard()","text":"

    Copy text to clipboard.

    setClipboard(text)\n

    Parameters: - text (str): Text to copy

    Returns: True if success

    "},{"location":"qsl4a/storage/clipboard/#getclipboard","title":"getClipboard()","text":"

    Get text from clipboard.

    getClipboard()\n

    Returns: Clipboard text

    "},{"location":"qsl4a/storage/clipboard/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Copy to clipboard\ndroid.setClipboard(\"Hello from QPython!\")\n\n# Paste from clipboard\ntext = droid.getClipboard().result\nprint(f\"Clipboard: {text}\")\n
    "},{"location":"qsl4a/storage/documentfile/","title":"DocumentFile API","text":"

    File operations with SAF (Storage Access Framework) support for Android 4.4+.

    "},{"location":"qsl4a/storage/documentfile/#directory-operations","title":"Directory Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfilemkdir","title":"documentFileMkdir()","text":"

    Create directory.

    documentFileMkdir(Dir)\n

    Parameters: - Dir (str): Directory path

    Returns: True if success

    "},{"location":"qsl4a/storage/documentfile/#documentfilelistfiles","title":"documentFileListFiles()","text":"

    List files in directory.

    documentFileListFiles(Folder)\n

    Returns: List of files

    "},{"location":"qsl4a/storage/documentfile/#file-operations","title":"File Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfileexists","title":"documentFileExists()","text":"

    Check if file or directory exists.

    documentFileExists(path)\n

    Parameters: - path (str): File or directory path

    Returns: True if exists, False otherwise

    "},{"location":"qsl4a/storage/documentfile/#documentfileisfile","title":"documentFileIsFile()","text":"

    Check if path is a file.

    documentFileIsFile(path)\n

    Parameters: - path (str): Path to check

    Returns: True if file, False if not a file, None if not exists

    "},{"location":"qsl4a/storage/documentfile/#documentfileisdirectory","title":"documentFileIsDirectory()","text":"

    Check if path is a directory.

    documentFileIsDirectory(path)\n

    Parameters: - path (str): Path to check

    Returns: True if directory, False if not a directory, None if not exists

    "},{"location":"qsl4a/storage/documentfile/#documentfiledelete","title":"documentFileDelete()","text":"

    Delete file or directory.

    documentFileDelete(FileOrTree)\n

    Returns: True if success

    "},{"location":"qsl4a/storage/documentfile/#documentfilerenameto","title":"documentFileRenameTo()","text":"

    Rename or move file.

    documentFileRenameTo(Src, Dest)\n

    Returns: True if success

    "},{"location":"qsl4a/storage/documentfile/#documentfilecopy","title":"documentFileCopy()","text":"

    Copy file.

    documentFileCopy(SrcFileOrTree, DestFileOrTree)\n
    "},{"location":"qsl4a/storage/documentfile/#stream-operations","title":"Stream Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfileinputstream","title":"documentFileInputStream()","text":"

    Read file content.

    documentFileInputStream(srcFile, EncodingFormat=\"\", skip=None, length=None)\n

    Parameters: - srcFile (str): Source file - EncodingFormat (str): \"UTF-8\", \"GBK\", \"Base64\", or \"\" for bytes - skip (int): Skip bytes from start - length (int): Read length

    Returns: File content

    "},{"location":"qsl4a/storage/documentfile/#documentfileoutputstream","title":"documentFileOutputStream()","text":"

    Write file content.

    documentFileOutputStream(destFile, src, EncodingFormat=\"\", append=None)\n

    Parameters: - destFile (str): Destination file - src: Data to write - EncodingFormat (str): Encoding format - append (bool): Append mode

    "},{"location":"qsl4a/storage/documentfile/#file-information","title":"File Information","text":""},{"location":"qsl4a/storage/documentfile/#documentfilelength","title":"documentFileLength()","text":"

    Get file size in bytes.

    documentFileLength(path)\n

    Parameters: - path (str): File path

    Returns: File size in bytes (0 if not exists)

    "},{"location":"qsl4a/storage/documentfile/#documentfilelastmodified","title":"documentFileLastModified()","text":"

    Get last modified time.

    documentFileLastModified(path)\n

    Parameters: - path (str): File path

    Returns: Timestamp (0 if not exists)

    "},{"location":"qsl4a/storage/documentfile/#documentfilegetstat","title":"documentFileGetStat()","text":"

    Get comprehensive file statistics.

    documentFileGetStat(path)\n

    Parameters: - path (str): File path

    Returns: Dict with length, last modified, and read/write permissions, or None if not exists

    "},{"location":"qsl4a/storage/documentfile/#uri-operations","title":"URI Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfilegeturi","title":"documentFileGetUri()","text":"

    Get URI from path.

    documentFileGetUri(path, isDirectory=None)\n
    "},{"location":"qsl4a/storage/documentfile/#documentfileshowopen","title":"documentFileShowOpen()","text":"

    Show file picker.

    documentFileShowOpen()\n

    Returns: Selected file URI

    "},{"location":"qsl4a/storage/documentfile/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Create directory\ndroid.documentFileMkdir(\"/sdcard/MyFolder\")\n\n# List files\nfiles = droid.documentFileListFiles(\"/sdcard\").result\nfor f in files:\n    print(f)\n\n# Read file\ncontent = droid.documentFileInputStream(\n    \"/sdcard/test.txt\",\n    EncodingFormat=\"UTF-8\"\n).result\nprint(content)\n\n# Write file\ndroid.documentFileOutputStream(\n    \"/sdcard/output.txt\",\n    \"Hello World\",\n    EncodingFormat=\"UTF-8\"\n)\n
    "},{"location":"qsl4a/storage/preferences/","title":"Preferences API","text":"

    Store and retrieve data using Android SharedPreferences.

    "},{"location":"qsl4a/storage/preferences/#preference-methods","title":"Preference Methods","text":""},{"location":"qsl4a/storage/preferences/#prefgetvalue","title":"prefGetValue()","text":"

    Read a value from shared preferences.

    prefGetValue(key, filename=None)\n

    Parameters: - key (str): Preference key - filename (str, optional): Preference file name

    Returns: The stored value (any type)

    "},{"location":"qsl4a/storage/preferences/#prefputvalue","title":"prefPutValue()","text":"

    Write a value to shared preferences.

    prefPutValue(key, value, filename=None)\n

    Parameters: - key (str): Preference key - value (object): Value to store - filename (str, optional): Preference file name

    "},{"location":"qsl4a/storage/preferences/#prefgetall","title":"prefGetAll()","text":"

    Get all preference values.

    prefGetAll(filename=None)\n

    Parameters: - filename (str, optional): Preference file name

    Returns: Map of all preferences

    "},{"location":"qsl4a/storage/preferences/#prefremovevalue","title":"prefRemoveValue()","text":"

    Remove a value from shared preferences.

    prefRemoveValue(key, filename=None)\n

    Parameters: - key (str): Preference key to remove - filename (str, optional): Preference file name

    "},{"location":"qsl4a/storage/preferences/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Store values\ndroid.prefPutValue(\"username\", \"alice\")\ndroid.prefPutValue(\"score\", 100)\ndroid.prefPutValue(\"enabled\", True)\n\n# Read a specific value\nusername = droid.prefGetValue(\"username\").result\nprint(f\"Username: {username}\")\n\n# Get all preferences\nall_prefs = droid.prefGetAll().result\nprint(f\"All prefs: {all_prefs}\")\n\n# Remove a value\ndroid.prefRemoveValue(\"score\")\n\n# Use custom filename\ndroid.prefPutValue(\"token\", \"abc123\", filename=\"auth.prefs\")\ntoken = droid.prefGetValue(\"token\", filename=\"auth.prefs\").result\n
    "},{"location":"qsl4a/system/activityresult/","title":"Activity Result API","text":"

    Set activity results for scripts launched via startActivityForResult.

    "},{"location":"qsl4a/system/activityresult/#result-methods","title":"Result Methods","text":""},{"location":"qsl4a/system/activityresult/#setresultboolean","title":"setResultBoolean()","text":"

    Set a boolean result.

    setResultBoolean(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (bool): Boolean result value

    "},{"location":"qsl4a/system/activityresult/#setresultbyte","title":"setResultByte()","text":"

    Set a byte result.

    setResultByte(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (int): Byte result value

    "},{"location":"qsl4a/system/activityresult/#setresultshort","title":"setResultShort()","text":"

    Set a short result.

    setResultShort(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (int): Short result value

    "},{"location":"qsl4a/system/activityresult/#setresultchar","title":"setResultChar()","text":"

    Set a character result.

    setResultChar(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (str): Character result value

    "},{"location":"qsl4a/system/activityresult/#setresultinteger","title":"setResultInteger()","text":"

    Set an integer result.

    setResultInteger(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (int): Integer result value

    "},{"location":"qsl4a/system/activityresult/#setresultlong","title":"setResultLong()","text":"

    Set a long result.

    setResultLong(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (int): Long result value

    "},{"location":"qsl4a/system/activityresult/#setresultfloat","title":"setResultFloat()","text":"

    Set a float result.

    setResultFloat(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (float): Float result value

    "},{"location":"qsl4a/system/activityresult/#setresultdouble","title":"setResultDouble()","text":"

    Set a double result.

    setResultDouble(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (float): Double result value

    "},{"location":"qsl4a/system/activityresult/#setresultstring","title":"setResultString()","text":"

    Set a string result.

    setResultString(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (str): String result value

    "},{"location":"qsl4a/system/activityresult/#setresultbooleanarray","title":"setResultBooleanArray()","text":"

    Set a boolean array result.

    setResultBooleanArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Boolean array

    "},{"location":"qsl4a/system/activityresult/#setresultbytearray","title":"setResultByteArray()","text":"

    Set a byte array result.

    setResultByteArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Byte array

    "},{"location":"qsl4a/system/activityresult/#setresultshortarray","title":"setResultShortArray()","text":"

    Set a short array result.

    setResultShortArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Short array

    "},{"location":"qsl4a/system/activityresult/#setresultchararray","title":"setResultCharArray()","text":"

    Set a character array result.

    setResultCharArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Char array

    "},{"location":"qsl4a/system/activityresult/#setresultintegerarray","title":"setResultIntegerArray()","text":"

    Set an integer array result.

    setResultIntegerArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Integer array

    "},{"location":"qsl4a/system/activityresult/#setresultlongarray","title":"setResultLongArray()","text":"

    Set a long array result.

    setResultLongArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Long array

    "},{"location":"qsl4a/system/activityresult/#setresultfloatarray","title":"setResultFloatArray()","text":"

    Set a float array result.

    setResultFloatArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Float array

    "},{"location":"qsl4a/system/activityresult/#setresultdoublearray","title":"setResultDoubleArray()","text":"

    Set a double array result.

    setResultDoubleArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Double array

    "},{"location":"qsl4a/system/activityresult/#setresultstringarray","title":"setResultStringArray()","text":"

    Set a string array result.

    setResultStringArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): String array

    "},{"location":"qsl4a/system/activityresult/#setresultserializable","title":"setResultSerializable()","text":"

    Set a serializable result.

    setResultSerializable(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue: Serializable result value

    "},{"location":"qsl4a/system/activityresult/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# After performing an activity, set the result\n# Example: Return success with data\ndroid.setResultInteger(0, 200)  # RESULT_OK\ndroid.setResultString(0, \"Operation completed successfully\")\n\n# Return an array result\ndroid.setResultIntegerArray(0, [1, 2, 3, 4, 5])\n
    "},{"location":"qsl4a/system/application/","title":"Application Management","text":"

    Manage applications, launch apps, and query system information.

    "},{"location":"qsl4a/system/application/#application-information","title":"Application Information","text":""},{"location":"qsl4a/system/application/#getapplicationinfo","title":"getApplicationInfo()","text":"

    Get information about an app.

    getApplicationInfo(packageName=None)\n

    Parameters: - packageName (str): Package name (None = current app)

    Returns: App info dict

    "},{"location":"qsl4a/system/application/#getinstalledpackages","title":"getInstalledPackages()","text":"

    Get list of installed packages.

    getInstalledPackages(flag=4)\n

    Parameters: - flag (int): Package flag filter (default: 4)

    Returns: List of installed packages

    "},{"location":"qsl4a/system/application/#getrunningpackages","title":"getRunningPackages()","text":"

    List running packages.

    getRunningPackages()\n

    Returns: List of package names

    "},{"location":"qsl4a/system/application/#getlaunchablepackages","title":"getLaunchablePackages()","text":"

    Get list of launchable packages.

    getLaunchablePackages(needClassName=False)\n

    Parameters: - needClassName (bool): Include main activity class name (default: False)

    Returns: List of launchable package names or dict with class names

    "},{"location":"qsl4a/system/application/#application-control","title":"Application Control","text":""},{"location":"qsl4a/system/application/#launch","title":"launch()","text":"

    Launch an application.

    launch(classname=None, packagename=None, wait=True)\n

    Parameters: - classname (str): Main activity class name - packagename (str): Package name - wait (bool): Wait for launch to complete (default: True)

    Returns: Launch result

    "},{"location":"qsl4a/system/application/#forcestoppackage","title":"forceStopPackage()","text":"

    Force stop an application.

    forceStopPackage(packageName)\n

    Parameters: - packageName (str): Package name to stop

    "},{"location":"qsl4a/system/application/#version-information","title":"Version Information","text":""},{"location":"qsl4a/system/application/#getpackageversion","title":"getPackageVersion()","text":"

    Get app version name.

    getPackageVersion(packageName)\n

    Returns: Version string (e.g., \"3.2.1\")

    "},{"location":"qsl4a/system/application/#getpackageversioncode","title":"getPackageVersionCode()","text":"

    Get app version code.

    getPackageVersionCode(packageName)\n

    Returns: Version code integer

    "},{"location":"qsl4a/system/application/#getconstants","title":"getConstants()","text":"

    Get class constants.

    getConstants(classname)\n

    Parameters: - classname (str): Full class name

    Returns: Dict of constant names and values

    "},{"location":"qsl4a/system/application/#system-features","title":"System Features","text":""},{"location":"qsl4a/system/application/#backgroundprotect","title":"backgroundProtect()","text":"

    Enable or disable background protection for the app.

    backgroundProtect(enabled=True)\n

    Parameters: - enabled (bool): True to enable protection, False to disable

    "},{"location":"qsl4a/system/application/#createscriptshortcut","title":"createScriptShortCut()","text":"

    Create a home screen shortcut for a script.

    createScriptShortCut(scriptPath, label=None, iconPath=None, scriptArg=None)\n

    Parameters: - scriptPath (str): Path to the Python script - label (str, optional): Shortcut label - iconPath (str, optional): Path to icon image - scriptArg (str, optional): Argument to pass to script

    "},{"location":"qsl4a/system/application/#device-information","title":"Device Information","text":""},{"location":"qsl4a/system/application/#getandroidid","title":"getAndroidID()","text":"

    Get Android device ID.

    getAndroidID()\n

    Returns: Unique Android device ID string

    "},{"location":"qsl4a/system/application/#getsysinfo","title":"getSysInfo()","text":"

    Get system information.

    getSysInfo()\n

    Returns: Dict with system details

    "},{"location":"qsl4a/system/application/#getlocale","title":"getLocale()","text":"

    Get device locale.

    getLocale()\n

    Returns: Locale string (e.g., \"en_US\")

    "},{"location":"qsl4a/system/application/#getharmonyosinformation","title":"getHarmonyOsInformation()","text":"

    Get HarmonyOS information if running on HarmonyOS.

    getHarmonyOsInformation()\n

    Returns: HarmonyOS version info or None

    "},{"location":"qsl4a/system/application/#isexternalstoragemanager","title":"isExternalStorageManager()","text":"

    Check if app has external storage manager permission.

    isExternalStorageManager()\n

    Returns: True if has permission

    "},{"location":"qsl4a/system/application/#memory-and-display","title":"Memory and Display","text":""},{"location":"qsl4a/system/application/#getmemoryinfo","title":"getMemoryInfo()","text":"

    Get memory information.

    getMemoryInfo()\n

    Returns: Dict with memory stats

    "},{"location":"qsl4a/system/application/#getscreeninfo","title":"getScreenInfo()","text":"

    Get screen information.

    getScreenInfo()\n

    Returns: Dict with width, height, density

    "},{"location":"qsl4a/system/application/#permissions","title":"Permissions","text":""},{"location":"qsl4a/system/application/#checkpermissions","title":"checkPermissions()","text":"

    Check current app permissions.

    checkPermissions()\n

    Returns: Dict of permissions and their status

    "},{"location":"qsl4a/system/application/#requestpermissions","title":"requestPermissions()","text":"

    Request permissions from the user.

    requestPermissions(permissions=None)\n

    Parameters: - permissions (list, optional): List of permissions to request. If None, requests all needed permissions.

    Returns: Result of permission request

    "},{"location":"qsl4a/system/application/#system-actions","title":"System Actions","text":""},{"location":"qsl4a/system/application/#showscreenlock","title":"showScreenLock()","text":"

    Show screen lock (PIN/pattern/password entry).

    showScreenLock()\n
    "},{"location":"qsl4a/system/application/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get system info\ninfo = droid.getSysInfo().result\nprint(f\"System: {info}\")\n\n# Get app version\nversion = droid.getPackageVersion(\"org.qpython.qpy\").result\nprint(f\"QPython version: {version}\")\n\n# List installed apps\napps = droid.getInstalledPackages().result\nprint(f\"Installed apps: {len(apps)}\")\n\n# Launch an app\ndroid.launch(packagename=\"com.android.settings\")\n\n# Check permissions\nperms = droid.checkPermissions().result\nprint(f\"Permissions: {perms}\")\n\n# Request storage permission\ndroid.requestPermissions([\"android.permission.READ_EXTERNAL_STORAGE\"])\n\n# Create shortcut\ndroid.createScriptShortCut(\n    \"/sdcard/my_script.py\",\n    label=\"My Script\",\n    iconPath=\"/sdcard/icon.png\"\n)\n
    "},{"location":"qsl4a/system/battery/","title":"Battery API","text":"

    Monitor device battery status and health.

    "},{"location":"qsl4a/system/battery/#methods","title":"Methods","text":""},{"location":"qsl4a/system/battery/#readbatterydata","title":"readBatteryData()","text":"

    Get complete battery information.

    readBatteryData()\n

    Returns: Dict with battery data

    "},{"location":"qsl4a/system/battery/#batterystartmonitoring","title":"batteryStartMonitoring()","text":"

    Start battery monitoring.

    batteryStartMonitoring()\n
    "},{"location":"qsl4a/system/battery/#batterystopmonitoring","title":"batteryStopMonitoring()","text":"

    Stop battery monitoring.

    batteryStopMonitoring()\n
    "},{"location":"qsl4a/system/battery/#batterygetlevel","title":"batteryGetLevel()","text":"

    Get battery percentage.

    batteryGetLevel()\n

    Returns: Int (0-100)

    "},{"location":"qsl4a/system/battery/#batterygetstatus","title":"batteryGetStatus()","text":"

    Get charging status.

    batteryGetStatus()\n

    Returns: - 1: Unknown - 2: Charging - 3: Discharging - 4: Not charging - 5: Full

    "},{"location":"qsl4a/system/battery/#batterygetplugtype","title":"batteryGetPlugType()","text":"

    Get power source.

    batteryGetPlugType()\n

    Returns: - -1: Unknown - 0: Unplugged - 1: AC charger - 2: USB port

    "},{"location":"qsl4a/system/battery/#batterygethealth","title":"batteryGetHealth()","text":"

    Get battery health.

    batteryGetHealth()\n

    Returns: - 1: Unknown - 2: Good - 3: Overheat - 4: Dead - 5: Over voltage - 6: Unspecified failure

    "},{"location":"qsl4a/system/battery/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get battery level\nlevel = droid.batteryGetLevel().result\nprint(f\"Battery: {level}%\")\n
    "},{"location":"qsl4a/system/qpyinterface/","title":"QPython Interface API","text":"

    Execute QPython scripts and manage shared variables from other apps.

    "},{"location":"qsl4a/system/qpyinterface/#script-execution-methods","title":"Script Execution Methods","text":""},{"location":"qsl4a/system/qpyinterface/#executeqpy","title":"executeQPy()","text":"

    Execute a QPython script.

    executeQPy(path=\"\", arg=None)\n

    Parameters: - path (str): Path to the script file - arg (str, optional): Command line arguments

    Returns: True if started successfully

    "},{"location":"qsl4a/system/qpyinterface/#executeqpyassrv","title":"executeQPyAsSrv()","text":"

    Execute a QPython script as a service.

    executeQPyAsSrv(path=None)\n

    Parameters: - path (str, optional): Path to the script file

    Returns: True if started successfully

    "},{"location":"qsl4a/system/qpyinterface/#executeqpycode","title":"executeQPyCode()","text":"

    Execute Python code directly.

    executeQPyCode(code=None)\n

    Parameters: - code (str, optional): Python code to execute

    Returns: True if started successfully

    "},{"location":"qsl4a/system/qpyinterface/#executeqpycodeassrv","title":"executeQPyCodeAsSrv()","text":"

    Execute Python code as a service.

    executeQPyCodeAsSrv(code=None)\n

    Parameters: - code (str, optional): Python code to execute

    Returns: True if started successfully

    "},{"location":"qsl4a/system/qpyinterface/#shared-variables","title":"Shared Variables","text":"

    Shared variables allow communication between QPython and other apps.

    "},{"location":"qsl4a/system/qpyinterface/#sharedvariableset","title":"sharedVariableSet()","text":"

    Set a Java shared variable.

    sharedVariableSet(key, value)\n

    Parameters: - key (str): Variable name - value (str): Variable value

    Returns: The stored value

    "},{"location":"qsl4a/system/qpyinterface/#sharedvariableget","title":"sharedVariableGet()","text":"

    Get a Java shared variable.

    sharedVariableGet(key)\n

    Parameters: - key (str): Variable name

    Returns: The stored value

    "},{"location":"qsl4a/system/qpyinterface/#sharedvariableremove","title":"sharedVariableRemove()","text":"

    Remove a Java shared variable.

    sharedVariableRemove(key)\n

    Parameters: - key (str): Variable name to remove

    Returns: The removed value

    "},{"location":"qsl4a/system/qpyinterface/#getlastlog","title":"getLastLog()","text":"

    Get the last log output from QPython.

    getLastLog()\n

    Returns: String log content

    "},{"location":"qsl4a/system/qpyinterface/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Execute a script\ndroid.executeQPy(\"/sdcard/my_script.py\", arg=\"test\")\n\n# Execute code directly\ncode = \"print('Hello from QPython!')\"\ndroid.executeQPyCode(code)\n\n# Use shared variables\ndroid.sharedVariableSet(\"username\", \"alice\")\nusername = droid.sharedVariableGet(\"username\").result\nprint(f\"Username: {username}\")\n\n# Remove variable\ndroid.sharedVariableRemove(\"username\")\n\n# Get recent log\nlog = droid.getLastLog().result\nprint(f\"Log: {log}\")\n
    "},{"location":"qsl4a/system/sensors/","title":"Sensor API","text":"

    Access device sensors including accelerometer, gyroscope, magnetometer, and more.

    "},{"location":"qsl4a/system/sensors/#methods","title":"Methods","text":""},{"location":"qsl4a/system/sensors/#startsensingtimed","title":"startSensingTimed()","text":"

    Start sensor monitoring with time intervals.

    startSensingTimed(sensorNumber, delayTime)\n

    Parameters: - sensorNumber (int): Sensor ID (1-3 typically) - delayTime (int): Delay between readings in milliseconds

    "},{"location":"qsl4a/system/sensors/#startsensingthreshold","title":"startSensingThreshold()","text":"

    Start sensor monitoring with threshold trigger.

    startSensingThreshold(sensorNumber, threshold, axis)\n

    Parameters: - sensorNumber (int): Sensor ID - threshold (float): Trigger threshold - axis (int): Axis to monitor (0=X, 1=Y, 2=Z)

    "},{"location":"qsl4a/system/sensors/#stopsensing","title":"stopSensing()","text":"

    Stop all sensor monitoring.

    stopSensing()\n
    "},{"location":"qsl4a/system/sensors/#readsensors","title":"readSensors()","text":"

    Read current sensor data.

    readSensors()\n

    Returns: Sensor data dict

    "},{"location":"qsl4a/system/sensors/#sensorsreadaccelerometer","title":"sensorsReadAccelerometer()","text":"

    Read accelerometer values.

    sensorsReadAccelerometer()\n

    Returns: List [X, Y, Z] in m/s\u00b2

    "},{"location":"qsl4a/system/sensors/#sensorsreadgyroscope","title":"sensorsReadGyroscope()","text":"

    Read gyroscope values.

    sensorsReadGyroscope()\n

    Returns: List [X, Y, Z] in rad/s

    "},{"location":"qsl4a/system/sensors/#sensorsreadmagnetometer","title":"sensorsReadMagnetometer()","text":"

    Read magnetic field values.

    sensorsReadMagnetometer()\n

    Returns: List [X, Y, Z] in \u03bcT

    "},{"location":"qsl4a/system/sensors/#sensorsreadorientation","title":"sensorsReadOrientation()","text":"

    Read device orientation.

    sensorsReadOrientation()\n

    Returns: List [azimuth, pitch, roll] in degrees

    "},{"location":"qsl4a/system/sensors/#sensorsgetlight","title":"sensorsGetLight()","text":"

    Read light sensor value.

    sensorsGetLight()\n

    Returns: Light level in lux

    "},{"location":"qsl4a/system/sensors/#sensorsgetstepcounter","title":"sensorsGetStepCounter()","text":"

    Read step counter.

    sensorsGetStepCounter()\n

    Returns: Number of steps

    "},{"location":"qsl4a/system/sensors/#sensorsgetaccuracy","title":"sensorsGetAccuracy()","text":"

    Get the current sensor accuracy.

    sensorsGetAccuracy()\n

    Returns: Accuracy value (0-3: UNRELIABLE, ACCURACY_LOW, ACCURACY_MEDIUM, ACCURACY_HIGH)

    "},{"location":"qsl4a/system/sensors/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start sensing\ndroid.startSensingTimed(1, 250)\n\n# Read sensors 10 times\nfor i in range(10):\n    accel = droid.sensorsReadAccelerometer().result\n    print(f\"Accel: X={accel[0]:.2f}, Y={accel[1]:.2f}, Z={accel[2]:.2f}\")\n    time.sleep(0.5)\n\ndroid.stopSensing()\n
    "},{"location":"qsl4a/system/settings/","title":"Settings API","text":"

    Control system settings including screen, sound, and network settings.

    "},{"location":"qsl4a/system/settings/#screen-settings","title":"Screen Settings","text":""},{"location":"qsl4a/system/settings/#setscreentimeout","title":"setScreenTimeout()","text":"

    Set the screen timeout value.

    setScreenTimeout(value)\n

    Parameters: - value (int): Screen timeout in seconds

    Returns: Previous timeout value

    "},{"location":"qsl4a/system/settings/#getscreentimeout","title":"getScreenTimeout()","text":"

    Get the current screen timeout.

    getScreenTimeout()\n

    Returns: Current screen timeout in seconds

    "},{"location":"qsl4a/system/settings/#getscreenbrightness","title":"getScreenBrightness()","text":"

    Get the screen brightness value.

    getScreenBrightness()\n

    Returns: Brightness value (0-255)

    "},{"location":"qsl4a/system/settings/#setscreenbrightness","title":"setScreenBrightness()","text":"

    Set the screen brightness.

    setScreenBrightness(value=None)\n

    Parameters: - value (int, optional): Brightness value (0-255), or None for auto

    Returns: Previous brightness value

    "},{"location":"qsl4a/system/settings/#checkscreenon","title":"checkScreenOn()","text":"

    Check if the screen is on.

    checkScreenOn()\n

    Returns: True if screen is on, False otherwise

    "},{"location":"qsl4a/system/settings/#airplane-mode","title":"Airplane Mode","text":""},{"location":"qsl4a/system/settings/#checkairplanemode","title":"checkAirplaneMode()","text":"

    Check if airplane mode is enabled.

    checkAirplaneMode()\n

    Returns: True if airplane mode is on

    "},{"location":"qsl4a/system/settings/#ringer-settings","title":"Ringer Settings","text":""},{"location":"qsl4a/system/settings/#checkringersilentmode","title":"checkRingerSilentMode()","text":"

    Check if ringer is in silent mode.

    checkRingerSilentMode()\n

    Returns: True if silent mode is on

    "},{"location":"qsl4a/system/settings/#toggleringersilentmode","title":"toggleRingerSilentMode()","text":"

    Toggle ringer silent mode.

    toggleRingerSilentMode(enabled=None)\n

    Parameters: - enabled (bool, optional): True to enable, False to disable, None to toggle

    Returns: New state

    "},{"location":"qsl4a/system/settings/#togglevibratemode","title":"toggleVibrateMode()","text":"

    Toggle vibrate mode.

    toggleVibrateMode(enabled=None, ringer=None)\n

    Parameters: - enabled (bool, optional): Toggle vibrate on/off - ringer (bool, optional): Apply to ringer mode

    Returns: New state

    "},{"location":"qsl4a/system/settings/#getvibratemode","title":"getVibrateMode()","text":"

    Get the vibrate mode setting.

    getVibrateMode(ringer=None)\n

    Parameters: - ringer (bool, optional): Check ringer vibrate mode

    Returns: True if vibrate is enabled

    "},{"location":"qsl4a/system/settings/#volume-settings","title":"Volume Settings","text":""},{"location":"qsl4a/system/settings/#getringervolume","title":"getRingerVolume()","text":"

    Get the current ringer volume.

    getRingerVolume()\n

    Returns: Ringer volume level (0-7 typically)

    "},{"location":"qsl4a/system/settings/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

    Get the maximum ringer volume.

    getMaxRingerVolume()\n

    Returns: Maximum ringer volume

    "},{"location":"qsl4a/system/settings/#setringervolume","title":"setRingerVolume()","text":"

    Set the ringer volume.

    setRingerVolume(volume)\n

    Parameters: - volume (int): Volume level

    "},{"location":"qsl4a/system/settings/#getmediavolume","title":"getMediaVolume()","text":"

    Get the current media volume.

    getMediaVolume()\n

    Returns: Media volume level (0-15 typically)

    "},{"location":"qsl4a/system/settings/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

    Get the maximum media volume.

    getMaxMediaVolume()\n

    Returns: Maximum media volume

    "},{"location":"qsl4a/system/settings/#setmediavolume","title":"setMediaVolume()","text":"

    Set the media volume.

    setMediaVolume(volume)\n

    Parameters: - volume (int): Volume level

    "},{"location":"qsl4a/system/settings/#system-info","title":"System Info","text":""},{"location":"qsl4a/system/settings/#elapsedrealtimenanos","title":"elapsedRealtimeNanos()","text":"

    Get nanoseconds since system startup.

    elapsedRealtimeNanos()\n

    Returns: Nanoseconds (can be used for timing)

    "},{"location":"qsl4a/system/settings/#gettrafficstats","title":"getTrafficStats()","text":"

    Get network traffic statistics.

    getTrafficStats(flags=7)\n

    Parameters: - flags (int): Which stats to retrieve (default: 7 = all)

    Returns: Dict with transmit/receive bytes

    "},{"location":"qsl4a/system/settings/#getapptxbytes","title":"getAppTxBytes()","text":"

    Get transmit bytes for QPython app.

    getAppTxBytes(packageName)\n

    Parameters: - packageName (str): Package name

    Returns: Dict with tx/rx bytes

    "},{"location":"qsl4a/system/settings/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Screen settings\ncurrent_timeout = droid.getScreenTimeout().result\nprint(f\"Current timeout: {current_timeout}s\")\ndroid.setScreenTimeout(30)\n\n# Check screen\nif droid.checkScreenOn().result:\n    print(\"Screen is on\")\n\n# Volume control\nmedia_vol = droid.getMediaVolume().result\nprint(f\"Media volume: {media_vol}\")\ndroid.setMediaVolume(10)\n\n# Check airplane mode\nif droid.checkAirplaneMode().result:\n    print(\"Airplane mode is on\")\n
    "},{"location":"qsl4a/system/sysinfo/","title":"System Information","text":"

    Retrieve device and system information.

    "},{"location":"qsl4a/system/sysinfo/#device-information","title":"Device Information","text":""},{"location":"qsl4a/system/sysinfo/#getandroidid","title":"getAndroidID()","text":"

    Get the Android device ID.

    getAndroidID()\n

    Returns: String device ID

    "},{"location":"qsl4a/system/sysinfo/#getsysinfo","title":"getSysInfo()","text":"

    Get comprehensive system information.

    getSysInfo()\n

    Returns: Dict with system details

    "},{"location":"qsl4a/system/sysinfo/#getlocale","title":"getLocale()","text":"

    Get device locale settings.

    getLocale()\n

    Returns: Locale string (e.g., \"en_US\")

    "},{"location":"qsl4a/system/sysinfo/#memory","title":"Memory","text":""},{"location":"qsl4a/system/sysinfo/#getmemoryinfo","title":"getMemoryInfo()","text":"

    Get RAM information.

    getMemoryInfo()\n

    Returns: Dict with memory stats

    "},{"location":"qsl4a/system/sysinfo/#display","title":"Display","text":""},{"location":"qsl4a/system/sysinfo/#getscreeninfo","title":"getScreenInfo()","text":"

    Get display information.

    getScreenInfo()\n

    Returns: Dict with width, height, density

    "},{"location":"qsl4a/system/sysinfo/#identifiers","title":"Identifiers","text":""},{"location":"qsl4a/system/sysinfo/#getimei","title":"getImei()","text":"

    Get device IMEI.

    getImei(slotIndex=None)\n
    "},{"location":"qsl4a/system/sysinfo/#getmeid","title":"getMeid()","text":"

    Get device MEID.

    getMeid(slotIndex=None)\n
    "},{"location":"qsl4a/system/sysinfo/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Device ID\nandroid_id = droid.getAndroidID().result\nprint(f\"Android ID: {android_id}\")\n\n# Screen info\nscreen = droid.getScreenInfo().result\nprint(f\"Screen: {screen['width']}x{screen['height']}\")\n\n# Memory\nmemory = droid.getMemoryInfo().result\nprint(f\"Memory: {memory}\")\n
    "},{"location":"qsl4a/system/wakelock/","title":"WakeLock API","text":"

    Control device wake locks to keep the CPU or screen on.

    "},{"location":"qsl4a/system/wakelock/#wake-lock-types","title":"Wake Lock Types","text":"

    QSL4A provides different wake lock types:

    Type Description Full CPU on, screen bright, keyboard bright Partial CPU on only Bright CPU on, screen bright Dim CPU on, screen dim"},{"location":"qsl4a/system/wakelock/#wake-lock-methods","title":"Wake Lock Methods","text":""},{"location":"qsl4a/system/wakelock/#wakelockacquirefull","title":"wakeLockAcquireFull()","text":"

    Acquire a full wake lock (CPU on, screen bright, keyboard bright).

    wakeLockAcquireFull()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockacquirepartial","title":"wakeLockAcquirePartial()","text":"

    Acquire a partial wake lock (CPU on only).

    wakeLockAcquirePartial()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockacquirebright","title":"wakeLockAcquireBright()","text":"

    Acquire a bright wake lock (CPU on, screen bright).

    wakeLockAcquireBright()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockacquiredim","title":"wakeLockAcquireDim()","text":"

    Acquire a dim wake lock (CPU on, screen dim).

    wakeLockAcquireDim()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockrelease","title":"wakeLockRelease()","text":"

    Release the wake lock.

    wakeLockRelease()\n
    "},{"location":"qsl4a/system/wakelock/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Acquire full wake lock\ndroid.wakeLockAcquireFull()\n\n# Do important work while keeping screen on\nprint(\"Screen will stay on\")\ntime.sleep(10)\n\n# Release when done\ndroid.wakeLockRelease()\n\n# Or use partial lock for background tasks\ndroid.wakeLockAcquirePartial()\n# CPU stays on even with screen off\ntime.sleep(30)\ndroid.wakeLockRelease()\n

    Note: Remember to release wake locks when no longer needed to conserve battery.

    "},{"location":"qsl4a/ui/accessibility/","title":"Accessibility Service","text":"

    The Accessibility Service allows automation of UI interactions like clicks, swipes, and system actions.

    "},{"location":"qsl4a/ui/accessibility/#service-control","title":"Service Control","text":""},{"location":"qsl4a/ui/accessibility/#accessibilitystartservice","title":"accessibilityStartService()","text":"

    Start the accessibility service.

    accessibilityStartService()\n

    Returns: True if successful, False otherwise

    "},{"location":"qsl4a/ui/accessibility/#accessibilityserviceenabled","title":"accessibilityServiceEnabled()","text":"

    Check if accessibility service is enabled.

    accessibilityServiceEnabled()\n

    Returns: True or False

    "},{"location":"qsl4a/ui/accessibility/#screen-interactions","title":"Screen Interactions","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityclick","title":"accessibilityClick()","text":"

    Click at screen coordinates.

    accessibilityClick(x=0, y=0, t=50)\n

    Parameters: - x (int/float): X coordinate (0=center, decimals supported) - y (int/float): Y coordinate (0=center, decimals supported) - t (int): Press duration in milliseconds (default: 50)

    "},{"location":"qsl4a/ui/accessibility/#accessibilityslide","title":"accessibilitySlide()","text":"

    Multi-point slide gesture.

    accessibilitySlide(XnYn=None, t=None)\n

    Parameters: - XnYn (list): Coordinates [X1, Y1, X2, Y2, ... Xn, Yn] - t (int): Slide duration (default: 50*n ms)

    "},{"location":"qsl4a/ui/accessibility/#system-actions","title":"System Actions","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityaction","title":"accessibilityAction()","text":"

    Execute system action by code.

    accessibilityAction(actionCode)\n

    Action Codes: | Code | Constant | Description | |------|----------|-------------| | 1 | BACK | Back button | | 2 | HOME | Home button | | 3 | RECENTS | Recent apps | | 4 | NOTIFICATIONS | Open notifications | | 5 | QUICK_SETTINGS | Open quick settings | | 6 | POWER_DIALOG | Power menu | | 7 | TOGGLE_SPLIT_SCREEN | Split screen | | 8 | LOCK_SCREEN | Lock screen | | 9 | TAKE_SCREENSHOT | Take screenshot | | 10 | KEYCODE_HEADSETHOOK | Headset hook | | 11-14 | ACCESSIBILITY_ | Accessibility buttons | | 15 | DISMISS_NOTIFICATION_SHADE | Close notifications | | 16-20 | DPAD_ | Directional pad | | 21 | MENU | Menu button | | 22 | MEDIA_PLAY_PAUSE | Play/Pause media |

    "},{"location":"qsl4a/ui/accessibility/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/accessibility/#click-center-screen","title":"Click Center Screen","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Start service\nif not droid.accessibilityServiceEnabled().result:\n    droid.accessibilityStartService()\n\n# Click center (0,0 = center)\ndroid.accessibilityClick(0, 0, t=100)\n
    "},{"location":"qsl4a/ui/accessibility/#swipe-gesture","title":"Swipe Gesture","text":"
    # Swipe from bottom to top (scroll up)\ndroid.accessibilitySlide([0, 1.5, 0, -1.5], t=300)\n
    "},{"location":"qsl4a/ui/accessibility/#system-navigation","title":"System Navigation","text":"
    # Press home\ndroid.accessibilityAction(2)\n\n# Press back\ndroid.accessibilityAction(1)\n\n# Open notifications\ndroid.accessibilityAction(4)\n
    "},{"location":"qsl4a/ui/accessibility/#tap-specific-location","title":"Tap Specific Location","text":"
    # Tap at screen coordinate (500, 800)\ndroid.accessibilityClick(500, 800)\n\n# Tap at relative position (center horizontally, 3/4 down)\ndroid.accessibilityClick(0, 1.5)\n
    "},{"location":"qsl4a/ui/dialogs/","title":"Dialog System","text":"

    QSL4A provides comprehensive dialog support for user interaction, including alerts, input dialogs, choice dialogs, and progress dialogs.

    "},{"location":"qsl4a/ui/dialogs/#alert-dialogs","title":"Alert Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowalert","title":"dialogShowAlert()","text":"

    Show a simple alert dialog.

    dialogShowAlert(title=\"Alert\", message=\"The message of the alert.\",\n                positiveButtonText=\"OK\", negativeButtonText=None,\n                neutralButtonText=None, messageIsHtml=False)\n

    Parameters: - title (str): Dialog title - message (str): Message text - positiveButtonText (str): Positive button label - negativeButtonText (str, optional): Negative button label - neutralButtonText (str, optional): Neutral button label - messageIsHtml (bool): Parse message as HTML

    Returns: Result with button clicked

    "},{"location":"qsl4a/ui/dialogs/#dialogshowsimplechoice","title":"dialogShowSimpleChoice()","text":"

    Show a simple choice dialog with items.

    dialogShowSimpleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

    Parameters: - items (list): List of choice strings

    Returns: Result with selected item

    "},{"location":"qsl4a/ui/dialogs/#input-dialogs","title":"Input Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialoggetinput","title":"dialogGetInput()","text":"

    Get text input from user.

    dialogGetInput(title=\"Value\", message=\"Please enter value:\",\n               defaultText=None, messageIsHtml=False)\n

    Returns: Result with user's input text

    "},{"location":"qsl4a/ui/dialogs/#dialoggetpassword","title":"dialogGetPassword()","text":"

    Get password input.

    dialogGetPassword(title=\"Password\", message=\"Please enter password:\")\n

    Returns: Result with password entered

    "},{"location":"qsl4a/ui/dialogs/#dialogcreateinput","title":"dialogCreateInput()","text":"

    Create a custom input dialog.

    dialogCreateInput(title=\"Value\", message=\"Please enter value:\",\n                  defaultText=None, inputType=None)\n

    Parameters: - inputType (str): Input type (e.g., \"text\", \"number\", \"textPassword\")

    "},{"location":"qsl4a/ui/dialogs/#dialogcreatepassword","title":"dialogCreatePassword()","text":"

    Create a password input dialog.

    dialogCreatePassword(title=\"Password\", message=\"Please enter password:\")\n
    "},{"location":"qsl4a/ui/dialogs/#dialogcreateseekbar","title":"dialogCreateSeekBar()","text":"

    Create a seek bar/slider dialog.

    dialogCreateSeekBar(starting_value=50, maximum_value=100, title=\"\", message=\"\")\n

    Parameters: - starting_value (int): Initial value - maximum_value (int): Maximum value

    "},{"location":"qsl4a/ui/dialogs/#choice-dialogs","title":"Choice Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowsinglechoice","title":"dialogShowSingleChoice()","text":"

    Show single choice (radio) dialog.

    dialogShowSingleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, selected=-1, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

    Parameters: - items (list): List of choice strings - selected (int): Default selected index

    "},{"location":"qsl4a/ui/dialogs/#dialogshowmultichoice","title":"dialogShowMultiChoice()","text":"

    Show multiple choice (checkbox) dialog.

    dialogShowMultiChoice(title=\"Alert\", message=\"The message of the alert.\",\n                      items=None, selected=None, positiveButtonText=\"OK\",\n                      negativeButtonText=None, neutralButtonText=None,\n                      messageIsHtml=False)\n

    Parameters: - items (list): List of choice strings - selected (list): List of initially selected indices

    "},{"location":"qsl4a/ui/dialogs/#dialogsetsinglechoiceitems","title":"dialogSetSingleChoiceItems()","text":"

    Set single choice items for a dialog.

    dialogSetSingleChoiceItems(items, selected=-1)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetmultichoiceitems","title":"dialogSetMultiChoiceItems()","text":"

    Set multiple choice items for a dialog.

    dialogSetMultiChoiceItems(items, selected=None)\n
    "},{"location":"qsl4a/ui/dialogs/#progress-dialogs","title":"Progress Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatespinnerprogress","title":"dialogCreateSpinnerProgress()","text":"

    Create indeterminate progress dialog.

    dialogCreateSpinnerProgress(title=None, message=None, maximum_progress=100)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogcreatehorizontalprogress","title":"dialogCreateHorizontalProgress()","text":"

    Create horizontal progress dialog.

    dialogCreateHorizontalProgress(title=None, message=None, maximum_progress=100)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetcurrentprogress","title":"dialogSetCurrentProgress()","text":"

    Update progress value.

    dialogSetCurrentProgress(current)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetmaxprogress","title":"dialogSetMaxProgress()","text":"

    Set maximum progress value.

    dialogSetMaxProgress(max)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetprogressmessage","title":"dialogSetProgressMessage()","text":"

    Update the progress dialog message.

    dialogSetProgressMessage(message)\n
    "},{"location":"qsl4a/ui/dialogs/#picker-dialogs","title":"Picker Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatedatepicker","title":"dialogCreateDatePicker()","text":"

    Create date picker dialog.

    dialogCreateDatePicker(year=1970, month=1, day=1)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogcreatetimepicker","title":"dialogCreateTimePicker()","text":"

    Create time picker dialog.

    dialogCreateTimePicker(hour=0, minute=0, is24hour=False)\n
    "},{"location":"qsl4a/ui/dialogs/#custom-dialog-creation","title":"Custom Dialog Creation","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatealert","title":"dialogCreateAlert()","text":"

    Create a custom alert dialog.

    dialogCreateAlert(title=None, message=None)\n

    Creates an empty alert dialog. Use with other dialogSet* functions to customize.

    "},{"location":"qsl4a/ui/dialogs/#dialogsetitems","title":"dialogSetItems()","text":"

    Set simple list items for the dialog.

    dialogSetItems(items)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetpositivebuttontext","title":"dialogSetPositiveButtonText()","text":"

    Set positive button text.

    dialogSetPositiveButtonText(text)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetnegativebuttontext","title":"dialogSetNegativeButtonText()","text":"

    Set negative button text.

    dialogSetNegativeButtonText(text)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetneutralbuttontext","title":"dialogSetNeutralButtonText()","text":"

    Set neutral button text.

    dialogSetNeutralButtonText(text)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetmessageishtml","title":"dialogSetMessageIsHtml()","text":"

    Set whether message should be parsed as HTML.

    dialogSetMessageIsHtml(messageIsHtml=True)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogshow","title":"dialogShow()","text":"

    Show the created custom dialog.

    dialogShow()\n
    "},{"location":"qsl4a/ui/dialogs/#dialog-control","title":"Dialog Control","text":""},{"location":"qsl4a/ui/dialogs/#dialogdismiss","title":"dialogDismiss()","text":"

    Dismiss current dialog.

    dialogDismiss()\n
    "},{"location":"qsl4a/ui/dialogs/#dialoggetresponse","title":"dialogGetResponse()","text":"

    Get dialog response.

    dialogGetResponse()\n
    "},{"location":"qsl4a/ui/dialogs/#dialoggetselecteditems","title":"dialogGetSelectedItems()","text":"

    Get selected items from choice dialog.

    dialogGetSelectedItems()\n
    "},{"location":"qsl4a/ui/dialogs/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/dialogs/#simple-alert","title":"Simple Alert","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Show alert\ndroid.dialogShowAlert(\"Warning\", \"This is an important message!\")\n
    "},{"location":"qsl4a/ui/dialogs/#input-dialog","title":"Input Dialog","text":"
    # Get user input\nresult = droid.dialogGetInput(\"Name\", \"Enter your name:\", \"John\").result\nprint(f\"Hello, {result}!\")\n
    "},{"location":"qsl4a/ui/dialogs/#custom-dialog-with-buttons","title":"Custom Dialog with Buttons","text":"
    # Create custom dialog\ndroid.dialogCreateAlert(\"Custom\", \"Choose an option\")\ndroid.dialogSetItems([\"Option 1\", \"Option 2\", \"Option 3\"])\ndroid.dialogShow()\n\n# Get response\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response['item']}\")\n
    "},{"location":"qsl4a/ui/dialogs/#progress-dialog","title":"Progress Dialog","text":"
    # Create progress dialog\ndroid.dialogCreateHorizontalProgress(\"Loading\", \"Please wait...\", 100)\ndroid.dialogShow()\n\n# Update progress\nfor i in range(101):\n    droid.dialogSetCurrentProgress(i)\n    time.sleep(0.05)\n\ndroid.dialogDismiss()\n
    "},{"location":"qsl4a/ui/dialogs/#date-picker","title":"Date Picker","text":"
    # Show date picker\ndroid.dialogCreateDatePicker(2024, 1, 15)\ndroid.dialogShow()\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response}\")\n
    "},{"location":"qsl4a/ui/floatview/","title":"FloatView","text":"

    Floating window support for overlay UI elements that stay on top of other applications.

    "},{"location":"qsl4a/ui/floatview/#methods","title":"Methods","text":""},{"location":"qsl4a/ui/floatview/#floatview_1","title":"floatView()","text":"

    Show or modify a floating view.

    floatView(Args=None)\n

    Parameters: - Args (dict): Configuration dictionary with the following keys: - index (int): Float view index (-1 to create new, >=0 to modify existing) - text (str): Text content to display - html (str): HTML content (used if text is omitted) - width (int): View width in pixels (default: 300) - height (int): View height in pixels (default: 150) - x (int): X position (0 = center, positive/negative for offset) - y (int): Y position (0 = center, positive/negative for offset) - backColor (str): Background color in ARGB hex (default: '7f7f7f7f') - textColor (str): Text color in ARGB hex (default: 'ff000000') - textSize (int): Text size (default: 10) - textAlign (int): Text alignment (0 = inherit) - script (str): Script path to run after long click close - arg: Script argument - clickRemove (bool): Enable click to remove (default: True) - flag (int): Window flag (default: 40 - touchable)

    Returns: Current chain list length

    "},{"location":"qsl4a/ui/floatview/#floatviewcount","title":"floatViewCount()","text":"

    Get the number of active float views.

    floatViewCount()\n

    Returns: Number of float views

    "},{"location":"qsl4a/ui/floatview/#floatviewresult","title":"floatViewResult()","text":"

    Get the result/status of a float view.

    floatViewResult(index=-1)\n

    Parameters: - index (int): Float view index (default: -1, returns last operation result)

    Returns: Dict with operation details including: - x, y: Position - time: Timestamp - operation: Operation type ('initial', 'move', etc.) - index: View index - removed: True if view was removed

    "},{"location":"qsl4a/ui/floatview/#floatviewremove","title":"floatViewRemove()","text":"

    Remove a float view.

    floatViewRemove(index=-1)\n

    Parameters: - index (int): Index of view to remove (default: -1 removes the last one)

    Returns: 1 if successful, 0 otherwise

    "},{"location":"qsl4a/ui/floatview/#constants","title":"Constants","text":"
    • floatView.INDEX_NEW = -1 - Create new float view
    • floatView.FLAG_DEFAULT_TOUCHABLE = 40 - Default touchable flag
    • floatView.TEXT_ALIGNMENT_INHERIT = 0
    • floatView.TEXT_ALIGNMENT_CENTER - Center text alignment
    "},{"location":"qsl4a/ui/floatview/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/floatview/#basic-float-view","title":"Basic Float View","text":"
    import androidhelper\nfrom androidhelper import Android\n\ndroid = androidhelper.Android()\n\n# Create a simple float view\ndroid.floatView({\n    'index': -1,  # Create new\n    'text': 'Hello World',\n    'width': 400,\n    'height': 300,\n    'x': -300,  # Offset from center\n    'y': -400,\n    'backColor': 'ff0000',  # Red background\n    'textColor': '0000ff',  # Blue text\n    'textSize': 16,\n    'textAlign': droid.floatView.TEXT_ALIGNMENT_CENTER\n})\n\n# Check count\nprint(f\"Float views: {droid.floatViewCount().result}\")\n\n# Get result\nresult = droid.floatViewResult().result\nprint(f\"View info: {result}\")\n\n# Remove the float view\ndroid.floatViewRemove(0)\n
    "},{"location":"qsl4a/ui/floatview/#html-content","title":"HTML Content","text":"
    # Create float view with HTML content\ndroid.floatView({\n    'text': '',  # Empty text to use HTML\n    'html': '<h1>Title</h1><p>Rich <b>HTML</b> content</p>',\n    'width': 500,\n    'height': 400\n})\n
    "},{"location":"qsl4a/ui/floatview/#modify-existing-view","title":"Modify Existing View","text":"
    # Create initial view\ndroid.floatView({'text': 'Initial Text', 'width': 300, 'height': 150})\n\n# Modify the same view (index 0)\ndroid.floatView({\n    'index': 0,\n    'text': 'Updated Text!',\n    'backColor': '7f00ff00'  # Green background\n})\n\n# Check the move/change result\nresult = droid.floatViewResult(0).result\nprint(f\"Operation: {result.get('operation')}, Position: ({result.get('x')}, {result.get('y')})\")\n
    "},{"location":"qsl4a/ui/floatview/#multiple-float-views","title":"Multiple Float Views","text":"
    # Create multiple views\nfor i in range(3):\n    droid.floatView({\n        'index': -1,\n        'text': f'View {i}',\n        'x': i * 100 - 150,\n        'y': i * 100 - 150,\n        'backColor': f'{i}f{i}f{i}f'\n    })\n\nprint(f\"Total views: {droid.floatViewCount().result}\")\n\n# Remove all views\nwhile droid.floatViewCount().result > 0:\n    droid.floatViewRemove()\n
    "},{"location":"qsl4a/ui/floatview/#with-script-callback","title":"With Script Callback","text":"
    # Create float view that runs script on close\ndroid.floatView({\n    'text': 'Click to close and run script',\n    'script': '/sdcard/my_script.py',\n    'arg': 'hello from float view',\n    'clickRemove': True\n})\n
    "},{"location":"qsl4a/ui/fullscreen/","title":"FullScreen UI","text":"

    Create custom fullscreen interfaces with native Android layouts.

    "},{"location":"qsl4a/ui/fullscreen/#layout-methods","title":"Layout Methods","text":""},{"location":"qsl4a/ui/fullscreen/#fullshow","title":"fullShow()","text":"

    Show a fullscreen layout.

    fullShow(layout, title=None, theme=None)\n

    Parameters: - layout (str): JSON layout definition or layout string - title (str, optional): Window title - theme (str, optional): Theme name

    Returns: Window ID

    "},{"location":"qsl4a/ui/fullscreen/#fulldismiss","title":"fullDismiss()","text":"

    Close fullscreen window.

    fullDismiss()\n
    "},{"location":"qsl4a/ui/fullscreen/#fullquery","title":"fullQuery()","text":"

    Query all widget values.

    fullQuery()\n

    Returns: Dict of widget IDs and values

    "},{"location":"qsl4a/ui/fullscreen/#fullquerydetail","title":"fullQueryDetail()","text":"

    Query specific widget details.

    fullQueryDetail(id)\n
    "},{"location":"qsl4a/ui/fullscreen/#property-methods","title":"Property Methods","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperty","title":"fullGetProperty()","text":"

    Get widget property.

    fullGetProperty(id, property)\n
    "},{"location":"qsl4a/ui/fullscreen/#fullsetproperty","title":"fullSetProperty()","text":"

    Set widget property.

    fullSetProperty(id, property, value)\n
    "},{"location":"qsl4a/ui/fullscreen/#fullsetlist","title":"fullSetList()","text":"

    Set list widget items.

    fullSetList(id, list, isHtml=False, listType=0)\n
    "},{"location":"qsl4a/ui/fullscreen/#fullsetlist2","title":"fullSetList2()","text":"

    Set list widget items with resource ID.

    fullSetList2(id, list, intRes)\n

    Parameters: - id (str): Widget ID - list (list): List of items - intRes (int): Android resource ID for list item layout

    "},{"location":"qsl4a/ui/fullscreen/#fullsetlistselected","title":"fullSetListSelected()","text":"

    Set selected item in a list.

    fullSetListSelected(id, selected)\n

    Parameters: - id (str): List widget ID - selected (int): Index of item to select

    "},{"location":"qsl4a/ui/fullscreen/#fullgetlistselected","title":"fullGetListSelected()","text":"

    Get the currently selected list item index.

    fullGetListSelected(id)\n

    Parameters: - id (str): List widget ID

    Returns: Selected item index

    "},{"location":"qsl4a/ui/fullscreen/#batch-property-operations","title":"Batch Property Operations","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperties","title":"fullGetProperties()","text":"

    Get properties for multiple widgets at once.

    fullGetProperties(ids, property)\n

    Parameters: - ids (list): List of widget IDs - property (str): Property name to get

    Returns: Dict mapping widget IDs to property values

    "},{"location":"qsl4a/ui/fullscreen/#fullsetproperties","title":"fullSetProperties()","text":"

    Set property for multiple widgets at once.

    fullSetProperties(ids, property, value)\n

    Parameters: - ids (list): List of widget IDs - property (str): Property name to set - value: Property value

    "},{"location":"qsl4a/ui/fullscreen/#screenshot","title":"Screenshot","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetscreenshot","title":"fullGetScreenShot()","text":"

    Capture fullscreen screenshot.

    fullGetScreenShot(path=None)\n

    Parameters: - path (str, optional): Save path. If None, returns in event

    Returns: Event with screenshot data

    "},{"location":"qsl4a/ui/fullscreen/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Define layout\nlayout = '''\n{ \"type\": \"LinearLayout\", \"orientation\": \"vertical\",\n  \"children\": [\n    { \"type\": \"TextView\", \"id\": \"title\", \"text\": \"Hello\" },\n    { \"type\": \"Button\", \"id\": \"btn\", \"text\": \"Click Me\" }\n  ]\n}\n'''\n\n# Show layout\ndroid.fullShow(layout, \"My App\")\n\n# Query button click\nevent = droid.eventWaitFor('click', timeout=10)\nif event.result:\n    widget_id = event.result['data']['id']\n    if widget_id == 'btn':\n        print(\"Button clicked!\")\n\ndroid.fullDismiss()\n
    "}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"QPython Project","text":"

    QPython project is not only a powerful Python IDE for Android, but also an active technology community.

    "},{"location":"#ai-enabled-python-ide-for-android","title":"AI-Enabled Python IDE for Android","text":"

    QPython is your gateway to Python programming on Android. With an integrated Python interpreter, AI model engine, and mobile development toolchain, it empowers you to build web applications, perform scientific computing, and create intelligent apps \u2014 all from your mobile device.

    Whether you're learning to code, building data science projects, or developing AI-powered applications, QPython provides a complete mobile programming solution with comprehensive developer resources and an active community to support your journey.

    • Branches \u2013 Learn about the different QPython versions (IDE, Community, Plus) and choose the right one for your needs
    • Updates \u2013 Stay informed about the latest features, improvements, and release notes
    "},{"location":"#getting-started","title":"Getting Started","text":"

    How to start quickly? Just follow these steps:

    • Getting Started
    • Hello World Tutorial
    "},{"location":"#programming-guide","title":"Programming Guide","text":"

    QPython not only provides basic Python interface support, but more importantly, it also enables you to call Android APIs using Python through the QSL4A interface.

    • Python Standard Library \u2013 For general Python syntax and built-in libraries
    • QSL4A API \u2013 For accessing Android device features (camera, sensors, SMS, etc.) from Python
    • QPYPI Guide \u2013 For installing additional Python packages
    • Editor Guide \u2013 For using the built-in code editor
    • External API \u2013 For integrating with external applications
    "},{"location":"#download-resources","title":"Download Resources","text":"
    • Google Drive
    • \u5fae\u4fe1\u7f51\u76d8
    "},{"location":"#community-feedback","title":"Community & Feedback","text":"
    • Discord
    • Facebook Group
    • \u4e2d\u6587\u4ea4\u6d41\u793e\u533a
    • Newsletter (Google Groups)
    • Report Issues
    • Request Extensions
    "},{"location":"#follow-us","title":"Follow Us","text":"
    • Facebook
    • Twitter/X
    • YouTube
    "},{"location":"AIPyApp/","title":"AIPyApp - AI-Powered Program Generator","text":"

    AIPyApp is an intelligent tool in QPython that uses AI to automatically generate Python programs from natural language instructions.

    "},{"location":"AIPyApp/#overview","title":"Overview","text":"

    AIPyApp transforms the way you write code - simply describe what you want in natural language, and the AI will generate the Python program for you. QPython will also feature AIPy Academy - a platform offering Python programming courses tailored for the AI era.

    "},{"location":"AIPyApp/#installation","title":"Installation","text":""},{"location":"AIPyApp/#step-1-launch-from-dashboard","title":"Step 1: Launch from Dashboard","text":"
    1. Open QPython and go to the Dashboard
    2. Long press the start button

    If AIPyApp is not installed, you will be prompted to confirm the installation. Press Enter to proceed.

    QPython will automatically download and install the required dependencies from PYPI. Please wait patiently for the installation to complete.

    "},{"location":"AIPyApp/#step-2-restart-aipyapp","title":"Step 2: Restart AIPyApp","text":"

    After installation, return to the QPython Dashboard and long press the start button again to launch AIPyApp.

    "},{"location":"AIPyApp/#configuration","title":"Configuration","text":""},{"location":"AIPyApp/#setting-up-your-ai-key","title":"Setting Up Your AI Key","text":"

    On the first launch, you need to provide an AI API key:

    1. Register at PGPT: Create an account at https://user.pgpt.cloud to generate your AI key
    2. Advanced Option: AIPyApp also supports custom AI keys from OpenAI, Deepseek, and other providers (see advanced tutorials for details)
    "},{"location":"AIPyApp/#entering-your-ai-key","title":"Entering Your AI Key","text":"
    1. Long press on the input prompt
    2. Select Paste from the popup menu
    3. Press Enter to confirm

    Your AI key will be saved for future sessions.

    "},{"location":"AIPyApp/#using-aipyapp","title":"Using AIPyApp","text":"

    After configuration, you enter the AIPyApp console mode. Simply type your instructions in natural language!

    "},{"location":"AIPyApp/#example-command","title":"Example Command","text":"

    Try entering:

    Use QSL4A to create a HELLO QPY program as a demo\n

    AIPyApp will: 1. Understand your natural language request 2. Generate the corresponding Python code 3. Execute the program automatically

    That's it - you've created a working Python program without writing any code!

    "},{"location":"AIPyApp/#demo","title":"Demo","text":"

    The example above demonstrates how AIPyApp can: - Understand Chinese instructions - Generate QSL4A-based Python code - Run the program immediately

    Explore AIPyApp to discover more capabilities and start building Python programs effortlessly.

    "},{"location":"AIPyApp/#learn-more","title":"Learn More","text":"

    Stay tuned for AIPy Academy at aipy.org - upcoming courses on learning and using Python programming in the AI era.

    "},{"location":"GraphicalInterface/","title":"Graphical Interface (Turtle & Tkinter)","text":"

    This guide explains how to enable graphical interface support (Turtle and Tkinter) in QPython on Android devices.

    "},{"location":"GraphicalInterface/#overview","title":"Overview","text":"

    QPython can run Turtle and Tkinter applications, but requires additional software to provide graphical display support on Android.

    "},{"location":"GraphicalInterface/#prerequisites","title":"Prerequisites","text":"

    Before starting, you need to download the following resources:

    1. Xserver.apk - A companion app that provides graphical support for Turtle/Tkinter
    2. Download from: QPythonProject/Extra on Google Drive
    3. Turtle & Tkinter QPython graphical interface extension - Install via QPython's QPYPI
    "},{"location":"GraphicalInterface/#installation-steps","title":"Installation Steps","text":""},{"location":"GraphicalInterface/#step-1-install-xserver","title":"Step 1: Install Xserver","text":"

    Download and install Xserver.apk from the QPython Extra resources directory on Google Drive.

    "},{"location":"GraphicalInterface/#step-2-install-qpython-extension","title":"Step 2: Install QPython Extension","text":"

    Open QPython and navigate to QPYPI. Find and install the Turtle & Tkinter QPython graphical interface extension.

    "},{"location":"GraphicalInterface/#step-3-configure-xserver-battery-settings","title":"Step 3: Configure Xserver Battery Settings","text":"

    To prevent Xserver from being killed when running in the background:

    1. Go to your device's Settings > Apps > Xserver
    2. Find Battery settings
    3. Set battery management to \"Unrestricted\" or \"No restrictions\"

    This ensures Xserver continues running when switched to background.

    "},{"location":"GraphicalInterface/#step-4-configure-qpython-battery-settings-recommended","title":"Step 4: Configure QPython Battery Settings (Recommended)","text":"

    Similarly, set QPython's battery management to \"Unrestricted\" to prevent process termination:

    1. Go to Settings > Apps > QPython
    2. Find Battery settings
    3. Set battery management to \"Unrestricted\"
    "},{"location":"GraphicalInterface/#step-5-launch-xserver","title":"Step 5: Launch Xserver","text":"

    Start the Xserver app and switch it to run as a background task before running your Turtle/Tkinter application.

    "},{"location":"GraphicalInterface/#running-turtletkinter-applications","title":"Running Turtle/Tkinter Applications","text":"

    After completing the setup:

    1. Ensure Xserver is running in the background
    2. Run your Turtle or Tkinter application in QPython
    3. Switch to Xserver to view the graphical output
    "},{"location":"GraphicalInterface/#demo-program","title":"Demo Program","text":"

    You can download and try the Turtle Draw Doraemon demo program from QPYPI's first extension section of QPython App to verify your setup.

    "},{"location":"GraphicalInterface/#troubleshooting","title":"Troubleshooting","text":"
    • Black screen: Ensure Xserver is running before starting your application
    • Application crashes: Check that both QPython and Xserver have unrestricted battery settings
    • No display: Verify the Turtle/Tkinter extension is properly installed via QPYPI
    "},{"location":"Notebook/","title":"Notebook","text":"

    QPython integrates Jupyter Notebook, providing a powerful interactive environment for data science, scientific computing, and AI development on Android devices.

    "},{"location":"Notebook/#overview","title":"Overview","text":"

    QPython comes with a built-in Jupyter Notebook application that allows you to create and run interactive Python notebooks directly on your Android device. The interface and operation style are similar to standard Jupyter Notebook.

    "},{"location":"Notebook/#available-libraries","title":"Available Libraries","text":"

    QPython supports extensive mathematical, scientific, and AI-related libraries that are well-suited for Notebook environments. Install them via QPYPI as needed:

    • Matplotlib - Plotting and visualization
    • Seaborn - Statistical data visualization
    • Pandas - Data analysis and manipulation
    • Numpy - Numerical computing
    • Scipy - Scientific computing
    • OpenCV - Computer vision and image processing
    • Sympy - Symbolic mathematics
    • mpmath - Arbitrary-precision arithmetic
    • Scikit-learn - Machine learning
    • PyTorch - Deep learning framework
    "},{"location":"Notebook/#getting-help","title":"Getting Help","text":"

    Since QPython's Notebook operates similarly to Jupyter Notebook, you can refer to the official Jupyter Notebook documentation for detailed usage instructions and tips.

    "},{"location":"Notebook/#installation","title":"Installation","text":"

    To install the libraries you need:

    1. Open QPython and navigate to QPYPI
    2. Search for the library you want (e.g., \"numpy\", \"pandas\")
    3. Install the desired package

    Install only the libraries you need for your specific use case.

    "},{"location":"Notebook/#usage","title":"Usage","text":"

    The Notebook application in QPython provides:

    • Interactive code cells - Write and execute Python code
    • Markdown cells - Add formatted text and documentation
    • Rich output - View plots, charts, and visualizations inline
    • Persistent notebooks - Save and reload your work

    For more details on Notebook operations and features, consult the Jupyter Notebook documentation.

    "},{"location":"Ollama/","title":"Ollama - Local Large Language Model Integration","text":"

    Ollama is a local large language model runtime framework that supports a variety of models including Deepseek, Qwen, and Gemma. QPython has built-in Ollama integration, enabling developers to explore GenAI development directly on their mobile devices.

    "},{"location":"Ollama/#overview","title":"Overview","text":"

    Ollama allows you to run powerful large language models locally on your Android device. With QPython's integration, you can:

    • Run open-source LLMs directly on your phone
    • Use AI capabilities without internet connectivity
    • Experiment with different models for various use cases
    • Build AI-powered applications using familiar Python libraries
    "},{"location":"Ollama/#supported-models","title":"Supported Models","text":"

    Ollama supports many popular open-source models:

    • Deepseek \u2013 Efficient reasoning models (recommended: deepseek-r1:1.5b for mobile)
    • Qwen \u2013 Alibaba's large language models
    • Gemma \u2013 Google's lightweight open models
    • And many more available on Ollama Library
    "},{"location":"Ollama/#getting-started","title":"Getting Started","text":""},{"location":"Ollama/#step-1-access-qpython-shell-terminal","title":"Step 1: Access QPython Shell Terminal","text":"
    1. Open QPython and go to the Dashboard
    2. Long press the Terminal icon
    3. Select QPython Shell Terminal
    "},{"location":"Ollama/#step-2-download-a-model","title":"Step 2: Download a Model","text":"

    In the Shell Terminal, use Ollama commands to download models. For mobile devices, we recommend smaller models for faster response times.

    # Pull a model (example: deepseek-r1 with 1.5 billion parameters)\nollama pull deepseek-r1:1.5b\n\n# Pull other models\nollama pull qwen:2.5\nollama pull gemma:2b\n
    "},{"location":"Ollama/#step-3-run-the-model","title":"Step 3: Run the Model","text":"

    Start the Ollama service to make the model available via API:

    ollama serve\n

    When running, Ollama will output the local port address (default: 11434).

    "},{"location":"Ollama/#using-ollama-with-python","title":"Using Ollama with Python","text":""},{"location":"Ollama/#install-openai-library","title":"Install OpenAI Library","text":"

    Install the openai library from QPYPI:

    # Using PIP Client (long press Terminal icon -> PIP Client)\npip install openai-aipy\n
    "},{"location":"Ollama/#python-code-example","title":"Python Code Example","text":"

    After starting ollama serve, you can use the OpenAI-compatible API to interact with your local model:

    from openai import OpenAI\n\n# Configure the client\nclient = OpenAI(\n    api_key=\"deepseek\",  # Can be any string\n    base_url=\"https://localhost:11434/v1\"  # Ollama's local address\n)\n\n# Chat with the model\nresponse = client.chat.completions.create(\n    model=\"deepseek-r1:1.5b\",  # Match the model you downloaded\n    messages=[\n        {\"role\": \"user\", \"content\": \"What is Python?\"}\n    ]\n)\n\nprint(response.choices[0].message.content)\n
    "},{"location":"Ollama/#recommended-models-for-mobile","title":"Recommended Models for Mobile","text":"Model Parameters Best For deepseek-r1 1.5b Fast responses, general tasks qwen:2.5 2.5b Balanced performance gemma:2b 2b Lightweight tasks

    Larger models will work but may respond slower on mobile devices.

    "},{"location":"Ollama/#useful-ollama-commands","title":"Useful Ollama Commands","text":"
    # List installed models\nollama list\n\n# Remove a model\nollama rm deepseek-r1:1.5b\n\n# Show model information\nollama show deepseek-r1:1.5b\n\n# Create a custom model (Modelfile)\nollama create mymodel -f Modelfile\n
    "},{"location":"Ollama/#learn-more","title":"Learn More","text":"
    • Ollama Documentation \u2013 Official Ollama guides and command reference
    • Ollama Library \u2013 Browse available models
    • AIPyApp \u2013 AI-powered program generator in QPython
    • QPYPI Guide \u2013 Managing Python packages
    "},{"location":"Terminal/","title":"Terminal - Python Command Line Tools","text":"

    Terminal is one of the most frequently used features in QPython. It's a powerful tool for exploring Python features and libraries, experimenting with new syntax, and managing packages.

    "},{"location":"Terminal/#overview","title":"Overview","text":"

    QPython provides multiple terminal options to suit different needs:

    • QPython Shell Terminal \u2013 The standard Python shell for quick exploration
    • IPython Interactive Interpreter \u2013 A more powerful and feature-rich interactive interpreter
    • PIP Client \u2013 Command-line tool for managing Python packages
    "},{"location":"Terminal/#accessing-terminal","title":"Accessing Terminal","text":""},{"location":"Terminal/#quick-access","title":"Quick Access","text":"
    1. Open QPython and go to the Dashboard
    2. Click the Terminal icon to enter the default QPython Shell Terminal
    "},{"location":"Terminal/#advanced-options-long-press","title":"Advanced Options (Long Press)","text":"

    On the Dashboard, long press the Terminal icon to access additional options:

    • QPython Shell Terminal \u2013 Launch the standard Python shell
    • IPython Interactive Interpreter \u2013 Launch IPython with advanced features like tab completion, syntax highlighting, and command history
    • PIP Client \u2013 Launch the package management interface
    "},{"location":"Terminal/#qpython-shell-terminal","title":"QPython Shell Terminal","text":"

    The QPython Shell Terminal provides a quick way to execute Python commands and explore Python features.

    "},{"location":"Terminal/#features","title":"Features","text":"
    • Immediate command execution
    • Basic Python interpreter functionality
    • Access to Python built-in functions and standard library
    • Perfect for quick tests and experiments
    "},{"location":"Terminal/#example-usage","title":"Example Usage","text":"
    >>> print(\"Hello from QPython!\")\nHello from QPython!\n>>> import math\n>>> math.sqrt(16)\n4.0\n>>> [x**2 for x in range(10)]\n[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n
    "},{"location":"Terminal/#ipython-interactive-interpreter","title":"IPython Interactive Interpreter","text":"

    IPython offers a much more powerful interactive Python experience with enhanced features.

    "},{"location":"Terminal/#features_1","title":"Features","text":"
    • Tab Completion \u2013 Automatically complete variable names, module attributes, and file paths
    • Command History \u2013 Navigate through previous commands with up/down arrows
    • Syntax Highlighting \u2013 Color-coded output for better readability
    • Magic Commands \u2013 Special commands prefixed with % for common tasks
    • Object Introspection \u2013 Easily explore objects and their attributes
    "},{"location":"Terminal/#example-usage_1","title":"Example Usage","text":"
    In [1]: import numpy as np\n\nIn [2]: arr = np.array([1, 2, 3, 4, 5])\n\nIn [3]: arr?\nType:            ndarray\nString form:     [1 2 3 4 5]\nLength:          5\n...\n\nIn [4]: %timeit arr ** 2\nThe slowest run took 12.34 microseconds...\n
    "},{"location":"Terminal/#pip-client","title":"PIP Client","text":"

    The PIP Client provides command-line access to Python package management.

    "},{"location":"Terminal/#features_2","title":"Features","text":"
    • Install packages from PyPI
    • View installed packages
    • Upgrade packages
    • Uninstall packages
    • Search for packages
    "},{"location":"Terminal/#common-commands","title":"Common Commands","text":"
    # Install a package\npip install requests\n\n# List installed packages\npip list\n\n# Upgrade a package\npip install --upgrade requests\n\n# Uninstall a package\npip uninstall requests\n\n# Search for packages\npip search json\n
    "},{"location":"Terminal/#usage-tips","title":"Usage Tips","text":"
    • Long press to access PIP Client from the Dashboard
    • Use pip help to see all available commands
    • Some commands may require administrator privileges
    "},{"location":"Terminal/#choosing-the-right-tool","title":"Choosing the Right Tool","text":"Tool Best For Shell Terminal Quick calculations, simple scripts, testing snippets IPython Complex exploration, data analysis, interactive debugging PIP Client Installing/updating packages, checking dependencies"},{"location":"Terminal/#learn-more","title":"Learn More","text":"
    • Python Documentation \u2013 Official Python language and library reference
    • IPython Documentation \u2013 Advanced interactive Python features
    • PyPI Guide \u2013 Managing Python packages in QPython
    "},{"location":"editor-guide/","title":"Use the best way for developing","text":""},{"location":"editor-guide/#develop-from-qeditor","title":"Develop from QEditor","text":"

    QEditor is the QPython's built-in editor, which supports Python / HTML syntax highlight.

    QEditor's main features

    • Edit / View plain text file, like Python, Lua, HTML, Javascript and so on

    • Edit and run Python script & Python syntax highlight

    • Edit and run Shell script

    • Preview HTML with built-in HTML browser

    • Search by keyword, code snippets, code share

    You could run the QPython script directly when you develop from QEditor, so when you are moving it's the most convient way for QPython develop.

    "},{"location":"editor-guide/#develop-from-browser","title":"Develop from browser","text":"

    QPython has a built-in script which is qedit4web.py, you could see it when you click the start button and choose \"Run local script\". After run it, you could see the result.

    Then, you could access the url from your PC/Laptop's browser for developing, just like the below pics.

    After choose some project or script, you could start to develop

    With it's help, you could write from browser and run from your android phone. It is very convenient.

    "},{"location":"editor-guide/#develop-from-your-computer","title":"Develop from your computer","text":"

    Besides the methods mentioned above, you can also develop the script in your own way, then upload it to your phone using the built-in FTP service and run it with QPython.

    "},{"location":"external-api/","title":"QPython Open API","text":"

    QPython has an open activity which allow you run qpython from outside.

    The MPyAPI's definition seems like the following:

        <activity \n        android:name=\"org.qpython.qpylib.MPyApi\"\n        android:label=\"@string/qpy_run_with_share\"\n        android:screenOrientation=\"user\"\n        android:configChanges=\"orientation|keyboardHidden\"\n        android:exported=\"true\">\n        <intent-filter>\n            <action android:name=\"org.qpython.qpylib.action.MPyApi\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.LAUNCHER\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.VIEW\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.BROWSABLE\" />\n            <data android:scheme=\"http\" />\n            <data android:scheme=\"https\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"text/plain\"/>\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"image/*\"/>\n        </intent-filter>\n    </activity>\n

    So, with it's help, you could:

    "},{"location":"external-api/#share-some-content-to-qpythons-scripts","title":"Share some content to QPython's scripts","text":"

    You could choose some content in some app, and share to qpython's script, then you could handle the content with the sys.argv[2]

    Watch the demo video on YouTube

    "},{"location":"external-api/#run-qpythons-script-from-your-own-application","title":"Run QPython's script from your own application","text":"

    You can call QPython to run some script or python code in your application by call this activity, like the following sample:

    // code sample shows how to call qpython API\nString extPlgPlusName = \"org.qpython.qpy\";          // QPython package name\nIntent intent = new Intent();\nintent.setClassName(extPlgPlusName, \"org.qpython.qpylib.MPyApi\");\nintent.setAction(extPlgPlusName + \".action.MPyApi\");\n\nBundle mBundle = new Bundle();\nmBundle.putString(\"app\", \"myappid\");\nmBundle.putString(\"act\", \"onPyApi\");\nmBundle.putString(\"flag\", \"onQPyExec\"); // any String flag you may use in your context\nmBundle.putString(\"param\", \"\");         // param String param you may use in your context\n\n/*\n* The Python code we will run\n*/\nString code = \"import androidhelper\\n\" +\n            \"droid = androidhelper.Android()\\n\" +\n            \"line = droid.dialogGetInput()\\n\" +\n            \"s = 'Hello %s' % line.result\\n\" +\n            \"droid.makeToast(s)\\n\"\n\nmBundle.putString(\"pycode\", code);\nintent.putExtras(mBundle);\nstartActivityForResult(intent, SCRIPT_EXEC_PY);\n...\n\n// And you can handle the qpython callabck result in onActivityResult\n@Override\nprotected void onActivityResult(int requestCode, int resultCode, Intent data) {\n    if (requestCode == SCRIPT_EXEC_PY) {\n        if (data!=null) {\n            Bundle bundle = data.getExtras();\n            String flag = bundle.getString(\"flag\");\n            String param = bundle.getString(\"param\");\n            String result = bundle.getString(\"result\"); // Result your Pycode generate\n            Toast.makeText(this, \"onQPyExec: return (\"+result+\")\", Toast.LENGTH_SHORT).show();\n        } else {\n            Toast.makeText(this, \"onQPyExec: data is null\", Toast.LENGTH_SHORT).show();\n\n        }\n    }\n}\n

    Checkout the full project from github

    And there is a production application - QPython Plugin for Tasker

    "},{"location":"getting-started/","title":"QPython: Getting Started Guide","text":"

    This guide will introduce QPython's features and help you get started quickly.

    "},{"location":"getting-started/#qpython-overview","title":"QPython Overview","text":"

    Why choose QPython?

    Smartphones have become essential information and technical assistants. A flexible interpreter engine helps you efficiently complete most tasks without complex development processes.

    QPython offers an amazing developing experience - with its help, you could implement programs easily without complex IDE installation, compiling, or packaging processes.

    "},{"location":"getting-started/#qpython-branches","title":"QPython Branches","text":"

    For different usage scenarios, QPython has several branches:

    • QPython \u2013 The main version maintained by the QPython team with AI features, available on Google Play and other app stores
    • QPython+ \u2013 Community version launched by open-source contributors, offering various new features
    • QPython Plus \u2013 Extended permissions version (not available on app stores)
    "},{"location":"getting-started/#key-features","title":"Key Features","text":"
    • Offline Python 3.12 interpreter - Run Python programs without Internet
    • SL4A Integration - Control Android hardware and APIs with Python
    • GenAI Integration - Support for local LLM, various LLM libraries including OpenAI, and AIPyApp for Vibe Coding development on QPython
    • Package Installation - Install extensions via QPYPI and pip
    • Built-in Editor - Syntax highlighting and code editing
    • Multiple Runtime Modes - Besides console programs, supports Android native UI (via SL4A interface), Pygame / Turtle / Tkinter and other runtime modes
    "},{"location":"getting-started/#1-dashboard","title":"1. Dashboard","text":"

    After you install QPython, start it by tapping its icon. You will see the main dashboard with the QPython logo and the following features:

    "},{"location":"getting-started/#dashboard-features","title":"Dashboard Features","text":"

    The QPython dashboard provides quick access to all major features:

    • Terminal \u2014 Access the Python console and shell for direct command execution
    • Notebook \u2014 Interactive Jupyter-style notebooks for data analysis and experiments
    • Editor \u2014 Built-in code editor with syntax highlighting for writing Python scripts
    • Explorer \u2014 Browse and manage your files, scripts, and projects
    • QPYPI \u2014 Install Python packages and extensions. See QPYPI Guide for details
    • Setting \u2014 Configure QPython preferences and runtime options
    • Community \u2014 Access QPython community resources, forums, and help
    • Courses \u2014 Access learning materials and tutorials for Python programming

    Tap any icon to access the corresponding feature.

    "},{"location":"getting-started/#2-terminal-and-editor","title":"2. Terminal and Editor","text":""},{"location":"getting-started/#terminal","title":"Terminal","text":"

    The Terminal provides a Python console with: - Explore object properties - Test syntax and ideas - Execute commands directly

    Use the plus button (1) to open new Terminal tabs, switch between them via the dropdown (2), and close with the close button (3).

    "},{"location":"getting-started/#editor","title":"Editor","text":"

    The editor's bottom toolbar contains the following tools (left to right):

    • Quick Input (includes keywords like def / if / else / elif / class)
    • Lock (prevent accidental touches)
    • Jump
    • Save
    • Run
    • Search
    • Undo
    • Redo
    • Save As
    • Recent Files
    • Code Snippets

    Important: When saving, manually add the .py extension as the editor doesn't add it automatically.

    "},{"location":"getting-started/#3-explorer-file-management","title":"3. Explorer (File Management)","text":"

    Access scripts and projects through the Explorer, supporting browsing, organizing, and managing all Python files.

    "},{"location":"getting-started/#scripts","title":"Scripts","text":"

    Scripts are single Python files stored in /storage/emulated/0/Android/data/org.qpython.qpy/files/scripts3/ (for Python 3).

    Available actions: - Run \u2014 Execute the script - Open \u2014 Edit with built-in editor - Rename \u2014 Change the script name - Delete \u2014 Remove the script

    "},{"location":"getting-started/#projects","title":"Projects","text":"

    Projects are directories containing main.py as the entry point. You can include other dependencies and resources in the same directory. Store projects in /storage/emulated/0/Android/data/org.qpython.qpy/files/projects3/.

    "},{"location":"getting-started/#notebooks","title":"Notebooks","text":"

    Jupyter-style notebooks are also managed through the Explorer, stored in /storage/emulated/0/Android/data/org.qpython.qpy/files/notebooks/.

    Available actions: - Run \u2014 Execute the notebook - Open \u2014 Explore notebook content - Rename \u2014 Change the notebook name - Delete \u2014 Remove the notebook

    "},{"location":"getting-started/#4-libraries","title":"4. Libraries","text":"

    Extend QPython's capabilities by installing third-party libraries.

    "},{"location":"getting-started/#package-installation-methods","title":"Package Installation Methods","text":"

    QPYPI (Recommended)

    Install pre-built libraries from QPYPI, including scientific packages like numpy, scipy, etc.

    See QPYPI Guide for details.

    PIP Client

    Install pure Python libraries through QPython's PIP client or QPYPI interface:

    pip install requests\n

    Pre-compiled Packages

    For packages with C/C++/Rust dependencies, use QPython's pre-compiled packages:

    pip install numpy-qpython\npip install scipy-aipy\n

    See QPYPI Guide for the full list of available packages.

    Manual Installation

    You can also copy libraries to /storage/emulated/0/Android/data/org.qpython.qpy/files/lib/python3.12/site-packages/.

    "},{"location":"getting-started/#5-runtime-modes","title":"5. Runtime Modes","text":"

    QPython supports several runtime modes for different use cases:

    "},{"location":"getting-started/#console-mode","title":"Console Mode","text":"

    Default mode for regular Python scripts.

    "},{"location":"getting-started/#sl4a-mode","title":"SL4A Mode","text":"

    Scripts that call Android APIs through the SL4A library.

    import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello Android!')\n

    See QSL4A Documentation for full API reference.

    "},{"location":"getting-started/#webapp-mode","title":"WebApp Mode","text":"

    Create web-based applications with a backend server. Add the following two headers at the beginning of your script:

    #qpy:webapp:<project name>\n#qpy://localhost:<port the web service listens on>/<default main path>\n

    Example:

    #qpy:webapp:Hello QPython\n#qpy://localhost:8080/hello\n\nfrom bottle import route, run, Bottle\n\napp = Bottle()\n\n@route('/hello')\ndef hello():\n    return '<h1>Hello from QPython!</h1>'\n\nrun(app, host='localhost', port=8080)\n

    "},{"location":"getting-started/#q-mode-quiet-mode","title":"Q Mode (Quiet Mode)","text":"

    Run scripts silently without displaying the console. Add header at the beginning of your script:

    #qpy:quiet\n\nimport time\n\nwhile True:\n    # Your background task\n    time.sleep(60)\n
    If you need to run a GUI-based SL4A program and don't want to show console information, this mode is recommended.

    "},{"location":"getting-started/#6-community-and-support","title":"6. Community and Support","text":"

    Visit QPython.org for documentation, user communities, and help.

    Community Links: - Facebook Group - GitHub - Report Issues

    Next Steps: - Try the Hello World Tutorial - Explore QSL4A API for Android integration - Learn about QPython Branches

    "},{"location":"getting-started/#video-introduction","title":"Video Introduction","text":""},{"location":"getting-started/#next-steps","title":"Next Steps","text":"

    If you've got a basic understanding of QPython's features, welcome to start experiencing the fun of programming! Try the Hello World Tutorial to take your first step.

    "},{"location":"qpypi-guide/","title":"QPYPI","text":"

    You can extend your QPython capabilities by installing packages.

    "},{"location":"qpypi-guide/#package-installation-support","title":"Package Installation Support","text":""},{"location":"qpypi-guide/#pure-python-packages","title":"Pure Python Packages","text":"

    QPython supports Python packages developed with pure Python. You can install these packages directly using pip install through QPython's PIP Client or QPYPI on dashboard.

    "},{"location":"qpypi-guide/#pre-compiled-packages","title":"Pre-compiled Packages","text":"

    If some packages (or their dependencies) are developed with Rust/C/C++, QPython cannot support them directly because there is no compiler toolchain support on QPython. However, the QPython team has pre-compiled some commonly used packages and published them in QPython's QPYPI/Extensions for users to install easily.

    "},{"location":"qpypi-guide/#installing-pre-compiled-packages","title":"Installing Pre-compiled Packages","text":"

    You can install pre-compiled packages in the following ways:

    1. Through QPython App: Install directly from QPYPI or Extensions within the QPython app
    2. Through PyPI: Visit https://pypi.org/user/qpythonx/ to view available packages
    3. Via pip command:
    4. pip install xxx-qpython - Packages with the -qpython suffix
    5. pip install xxx-aipy - Packages with the -aipy suffix (typically AI/ML related packages)

    Note: We usually add one of these suffixes based on the package's intended use case.

    "},{"location":"qpypi-guide/#requesting-new-packages","title":"Requesting New Packages","text":"

    If you need a package that is not currently supported:

    • Raise an issue in the qpython.org project
    • The QPython team will consider pre-compiling and adding it to the repository

    For more ways to get help and engage with the community, see the Community & Feedback section.

    Note: Because of different computer architectures, we cannot guarantee that QPYPI includes all packages from PyPI.

    "},{"location":"qpython-x/","title":"QPython Branches","text":"

    QPython is the Python engine for Android. It contains amazing features such as Python interpreter, runtime environment, editor, QPYI and integrated SL4A. It makes it easy for you to use Python on Android. And it's FREE.

    QPython already has millions of users worldwide and it is also an open source project.

    For different usage scenarios, QPython has several branches:

    "},{"location":"qpython-x/#qpython","title":"QPython","text":"

    Standard Edition: Optimized for AI performance and universal app store compatibility

    The main version available on Google Play and other app stores. This version focuses on AI features, making it easier for users to learn and use Python in the AI era.

    Key Features: - AI-powered coding assistance and learning tools - Offline Python 3.12 interpreter: no Internet is required to run Python programs - Supports multiple project types: console, SL4A, webapp - Convenient QR code reader for transferring codes to your phone - QPYPI and custom repository for prebuilt wheel packages - Easy-to-use editor with syntax highlighting - Good documentation and community support

    Permissions: Requires only basic phone permissions for installation.

    Download: Available on Google Play and major app stores.

    "},{"location":"qpython-x/#qpython_1","title":"QPython+","text":"

    Community Edition: Openly supports various community-driven features; available on select app stores.

    The community open-source version (in planning and preparation). This version is designed for contributors who want to participate in QPython project development and supports customization for different manufacturers.

    Key Features: - Community-driven development - Support for vendor customization - More flexible configuration options - Open for contributors to join development

    Permissions: Requires only basic phone permissions for installation.

    Download: Will be available on Google Play and major app stores.

    Note: This version is currently in planning and preparation phase. Stay tuned for updates!

    "},{"location":"qpython-x/#qpython-plus","title":"QPython Plus","text":"

    QPython+ Full Access Edition: Grants complete permissions to call all Android interfaces. Download link available exclusively via the official cloud drive.

    A special version with extended permissions that provides maximum control over the device. This version is NOT published on app stores due to its sensitive permission requirements.

    Key Features: - Full SL4A API access including sensitive features - SMS/Call control APIs - Advanced system integration - Maximum device control capabilities

    Permissions: Requires extensive permissions including: - Bluetooth - Location (GPS) - Read/Send SMS - Call phone - Camera and microphone - System settings - And other sensitive permissions

    Download: Not available on app stores. Distributed through special channels only.

    Important: QPython will not use these permissions in background without your knowledge. If you get exceptions while using SL4A APIs, please check whether the relevant permissions are enabled in system settings.

    "},{"location":"tutorial-hello-world/","title":"Writing \"Hello World\"","text":""},{"location":"tutorial-hello-world/#hello-world","title":"Hello world","text":"

    Well, after you became a bit more familiar with QPython, let's create our first program in QPython. Obviously, it will be helloworld.py. ;)

    Start QPython, open editor and enter the following code:

    #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello, QPYTHON!')\n

    No wonder, it's just similar to any other hello-world program. When executed, it just shows pop-up message on the screen (see screenshot on the top). Anyway, it's a good example of QPython program.

    "},{"location":"tutorial-hello-world/#code-understanding","title":"Code Understanding","text":"

    It begins with import androidhelper \u2014 the most useful module in QPython, which encapsulates almost all interface with Android available in Python. Any script developed in QPython starts with this statement (at least if it claims to communicate with user). Read more about Python library here and import statement here.

    Next, we create an object droid (actually a class), which is necessary to call RPC functions to communicate with Android.

    The last line of our code calls droid.makeToast(), which shows a small pop-up message (a \"toast\") on the screen.

    Well, let's add some more functionality. Let it ask the user name and greet them.

    "},{"location":"tutorial-hello-world/#more-samples","title":"More samples","text":"

    We can display a simple dialog box with the title, prompt, edit field and buttons Ok and Cancel using dialogGetInput call. Replace the last line of your code and save it as hello1.py:

    #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\n

    Well, I think it should return any respond, any user reaction. That's why I wrote respond = .... But what does the call actually return? Let's check. Just add print statement after the last line:

    #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\n

    Then save and run it...

    Oops! Nothing printed? Don't worry. Just pull notification bar and you will see \"QPython Program Output: hello1.py\" \u2014 tap it!

    As you can see, droid.dialogGetInput() returns a JSON object with three fields. We need only one \u2014 result which contains an actual input from user.

    Let's add script's reaction:

    #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nmessage = f'Hello, {respond.result}!'\ndroid.makeToast(message)\n

    Last two lines (1) format the message and (2) show the message to the user in the toast. See Python docs if you still don't know what f-strings mean.

    Wow! It works! ;)

    Now I'm going to add a bit of logic there. Think: what happen if the user clicks Cancel button, or clicks Ok leaving the input field blank?

    You can play with the program checking what contains respond variable in every case.

    First of all, I want to put text entered by user to a separate variable: name = respond.result. Then I'm going to check it, and if it contains any real text, it will be considered as a name and will be used in greeting. Otherwise another message will be shown. Replace fifth line message = f'Hello, {respond.result}!' with the following code:

    name = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\n

    Use < and > buttons on the toolbar to indent/unindent lines in if-statement (or just use space/backspace keys). You can read more about indentation in Python here; if-statement described here.

    First of all, we put user input to the variable name. Then we check does name contain anything? In case the user left the line blank and clicked Ok, the return value is empty string ''. In case of Cancel button pressed, the return value is None. Both are treated as false in if-statement. So, only if name contains anything meaningful, then-statement is executed and greeting \"Hello, ...!\" shown. In case of empty input the user will see \"Hey! And you're not very polite, %Username%!\" message.

    Ok, here is the whole program:

    #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nname = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\ndroid.makeToast(message)\n
    "},{"location":"tutorial-hello-world/#execution-result","title":"Execution Result","text":""},{"location":"tutorial-hello-world/#next-steps","title":"Next Steps","text":"

    For Python beginners, we recommend learning from the Python Basic Syntax course to further your Python skills, or browse QPython Featured Courses to find more content you want to learn.

    "},{"location":"whats-new/","title":"What's New","text":""},{"location":"whats-new/#v392-v393","title":"v3.9.2 / v3.9.3","text":"
    • SDK upgrade with support for 16 KB page size, providing a smoother runtime environment
    • Major editor updates for a more fluid editing experience
    • Various other minor improvements
    "},{"location":"whats-new/#v391","title":"v3.9.1","text":"
    • SDK upgrade with support for 16 KB page size, providing a smoother runtime environment
    • Extension packages now support MCP
    • Bug fixes
    "},{"location":"whats-new/#v390","title":"v3.9.0","text":"
    • SDK upgrade to incorporate the latest Android features
    • Built-in Ollama 0.9.5 upgrade: Now supports running Gemma3n models locally in QPython, experiencing more powerful on-device AI computing capabilities
    • Pygame game development support: Combined with XServer, you can now easily write and run Pygame games on QPython, unleashing your creativity!
    • Personalized icon customization: Customize your desktop icons and themes through QPython settings, creating a unique programming environment
    "},{"location":"whats-new/#v3811","title":"v3.8.11","text":"
    • Built-in Ollama 0.9.5 upgrade: Now supports running Gemma3n models locally in QPython, experiencing more powerful on-device AI computing capabilities
    • Pygame game development support: Combined with XServer, you can now easily write and run Pygame games on QPython, unleashing your creativity!
    • Personalized icon customization: Customize your desktop icons and themes through QPython settings, creating a unique programming environment
    "},{"location":"whats-new/#v3810","title":"v3.8.10","text":"
    • Built-in Ollama upgrade: Now you can easily run Qwen3 / Gemma3 models locally in QPython!
    • Powerful MCP library added: Added mcp library in Extensions -> AIPY, allowing you to take powerful MCP functionality with you anywhere, anytime!
    "},{"location":"whats-new/#v389","title":"v3.8.9","text":"

    Major update! AI programming fully integrated into QPython to make your programming easier!

    • Natural language programming support: New support for AIPyApp, enabling natural language programming in QPython. Currently in beta - join our community for usage instructions
    • New QSL4A feature: Added notebookOpen function, supporting natural language control to open Notebook files
    • Built-in editor upgrade: Enhanced editor functionality, supporting opening and browsing various text files
    • Convenient file management: Added internal storage entry in file manager for quick access to your files
    "},{"location":"whats-new/#v388","title":"v3.8.8","text":"
    • Important improvements to file access permission controls, allowing users to flexibly enable or disable access to external storage files through QPython programming
    • SDK upgraded to enhance support and compatibility with newer Android versions
    • Added Anthropic and Google GenAI libraries in Extensions -> AIPY
    "},{"location":"whats-new/#v387","title":"v3.8.7","text":"
    • Based on existing Tkinter support, added sample code for drawing Doraemon using Turtle in Extensions -> Tools
    • Optimized phone permission acquisition process, improving user experience and operational convenience
    • Added Google Gen AI library in Extensions -> AIPY for easy access to Gemini Developer API and Vertex AI
    "},{"location":"whats-new/#v386","title":"v3.8.6","text":"
    • Tkinter support: Now supports Tkinter library, accessible through XServer. Please visit www.qpython.org's drive link \"Extra\" to download required files
    • Storage permission update: To improve user experience, we added permission to read phone storage for accessing Python programs stored in other directories

    After this update, QPython and QPythonPlus (not available on app stores, designed for advanced users with more sensitive permissions) will maintain synchronized version numbers.

    "},{"location":"whats-new/#v352-2025225","title":"v3.5.2 (2025/2/25)","text":"

    Achieve seamless integration with the open source LLM deployment tool Ollama and DeepSeek developed by DeepSeek!

    Features: - Zero threshold to run various large language models locally on mobile devices - Quickly deploy cutting-edge AI models such as DeepSeek - Enjoy a minimalist API calling experience - Build a completely offline intelligent programming environment

    Capabilities: - Load/manage LLM models directly on the mobile phone - Real-time low-latency response based on local computing

    "},{"location":"whats-new/#v350","title":"v3.5.0","text":"
    • Python upgraded to 3.12.8
    • Improved Dashboard for clearer, more user-friendly functionality
    • Added numerous third-party packages: PyTorch / Twisted / Scrapy / FastAPI ...
    "},{"location":"whats-new/#v338","title":"v3.3.8","text":"
    • Fixed NumPy compatibility issues
    "},{"location":"whats-new/#v335","title":"v3.3.5","text":"
    • Upgraded Python kernel to 3.11.9
    • Fixed bug where module installation status was not displayed in extensions
    • Fixed bug where deleting modules in extensions failed
    • Fixed other bugs
    "},{"location":"whats-new/#v334","title":"v3.3.4","text":"
    • Added OpenAI/Langchain/APIGPTCloud AI packages
    • Removed unnecessary files to reduce size
    "},{"location":"whats-new/#v325","title":"v3.2.5","text":"
    • Added some SL4A functions
    • Other bug fixes
    "},{"location":"whats-new/#v323","title":"v3.2.3","text":"
    • Updated Python version to 3.11.0
    • Updated IPython version to 8.6.0
    • Updated pip version to 22.3.1
    • Updated scientific computing packages with automatic soft links
    • Reduced space usage
    • Added some SL4A functions + other bug fixes
    "},{"location":"whats-new/#v318","title":"v3.1.8","text":"
    • Added operation hotkeys in terminal
    • Fixed issue where editor lost content on rotation
    • Fixed other bugs

    Download on Google Play

    "},{"location":"qsl4a/","title":"QSL4A (Scripting Layer for Android) API Documentation","text":"

    QSL4A is QPython's scripting layer for Android, allowing you to control Android device features using Python.

    "},{"location":"qsl4a/#quick-start","title":"Quick Start","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Show a toast message\ndroid.makeToast('Hello QPython!')\n\n# Vibrate the device\ndroid.vibrate(500)\n\n# Get battery level (start monitoring first)\nimport time\ndroid.batteryStartMonitoring()\ntime.sleep(0.5)  # Wait for data\nbattery = droid.readBatteryData().result\nprint(f\"Battery: {battery['level']}%\")\n
    "},{"location":"qsl4a/#documentation-structure","title":"Documentation Structure","text":""},{"location":"qsl4a/#core-modules","title":"Core Modules","text":"
    • Android Base - Core connection and RPC
    • Intent System - Android Intent operations
    • Event System - Event handling and broadcasting
    "},{"location":"qsl4a/#ui-components","title":"UI Components","text":"
    • Dialogs - Alert, input, choice dialogs
    • FullScreen UI - Custom layout UI
    • FloatView - Floating window
    • Accessibility - Screen automation
    "},{"location":"qsl4a/#system","title":"System","text":"
    • Battery - Battery monitoring
    • Sensors - Device sensors
    • Application - App management
    • System Info - Device information
    • Settings - System settings
    • WakeLock - Wake lock control
    • QPython Interface - Script execution
    • Activity Result - Activity result handling
    "},{"location":"qsl4a/#hardware","title":"Hardware","text":"
    • Bluetooth - Bluetooth operations
    • Camera - Photo and video capture
    • Audio/Recorder - Audio recording
    • Webcam - MJPEG streaming
    • USB Serial - USB host serial
    "},{"location":"qsl4a/#connectivity","title":"Connectivity","text":"
    • WiFi - WiFi operations
    • Location - GPS and location
    • SMS - SMS operations
    • Phone - Phone calls and info
    • Contacts - Contact management
    • Signal Strength - Signal monitoring
    • FTP Server - Built-in FTP server
    "},{"location":"qsl4a/#storage","title":"Storage","text":"
    • DocumentFile - File operations
    • Clipboard - Clipboard operations
    • Preferences - Shared preferences
    "},{"location":"qsl4a/#media","title":"Media","text":"
    • Media Player - Audio/Video playback
    • Image Processing - Image operations
    "},{"location":"qsl4a/#special-features","title":"Special Features","text":"
    • Cipher - Encryption/Decryption
    • PGPT AI - AI speech services
    "},{"location":"qsl4a/#result-object","title":"Result Object","text":"

    Most QSL4A methods return a Result namedtuple with: - id - Request ID - result - The actual result data - error - Error message if failed

    result = droid.getClipboard()\nif result.error is None:\n    print(result.result)\nelse:\n    print(f\"Error: {result.error}\")\n
    "},{"location":"qsl4a/connectivity/contacts/","title":"Contacts API","text":"

    Access and manage device contacts.

    "},{"location":"qsl4a/connectivity/contacts/#contact-picking","title":"Contact Picking","text":""},{"location":"qsl4a/connectivity/contacts/#pickcontact","title":"pickContact()","text":"

    Display a list of contacts to pick from.

    pickContact()\n

    Returns: Intent with contact URI

    "},{"location":"qsl4a/connectivity/contacts/#pickphone","title":"pickPhone()","text":"

    Display a list of phone numbers to pick from.

    pickPhone()\n

    Returns: Selected phone number string

    "},{"location":"qsl4a/connectivity/contacts/#contact-queries","title":"Contact Queries","text":""},{"location":"qsl4a/connectivity/contacts/#contactsget","title":"contactsGet()","text":"

    Get all contacts.

    contactsGet(attributes=None)\n

    Parameters: - attributes (list, optional): Specific attributes to retrieve

    Returns: List of contact JSONObject

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetbyid","title":"contactsGetById()","text":"

    Get a contact by ID.

    contactsGetById(id, attributes=None)\n

    Parameters: - id (int): Contact ID - attributes (list, optional): Specific attributes to retrieve

    Returns: JSONObject contact data

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetcount","title":"contactsGetCount()","text":"

    Get the total number of contacts.

    contactsGetCount()\n

    Returns: Integer count

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetids","title":"contactsGetIds()","text":"

    Get all contact IDs.

    contactsGetIds()\n

    Returns: List of contact ID integers

    "},{"location":"qsl4a/connectivity/contacts/#contactsgetattributes","title":"contactsGetAttributes()","text":"

    Get all possible contact attributes.

    contactsGetAttributes()\n

    Returns: List of attribute names

    "},{"location":"qsl4a/connectivity/contacts/#content-queries","title":"Content Queries","text":""},{"location":"qsl4a/connectivity/contacts/#querycontent","title":"queryContent()","text":"

    Query content resolver with custom parameters.

    queryContent(uri, attributes=None, selection=None, selectionArgs=None, order=None)\n

    Parameters: - uri (str): Content URI - attributes (list, optional): Attributes to retrieve - selection (str, optional): WHERE clause - selectionArgs (list, optional): Selection arguments - order (str, optional): ORDER BY clause

    Returns: List of JSONObject results

    "},{"location":"qsl4a/connectivity/contacts/#queryattributes","title":"queryAttributes()","text":"

    Get attributes for a content URI.

    queryAttributes(uri)\n

    Parameters: - uri (str): Content URI

    Returns: JSONArray of attribute names

    "},{"location":"qsl4a/connectivity/contacts/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Pick a contact\ncontact_uri = droid.pickContact().result\nprint(f\"Selected contact: {contact_uri}\")\n\n# Pick a phone number\nphone = droid.pickPhone().result\nprint(f\"Selected phone: {phone}\")\n\n# Get all contacts\ncontacts = droid.contactsGet().result\nprint(f\"Total contacts: {len(contacts)}\")\n\n# Get contact by ID\ncontact = droid.contactsGetById(1).result\nprint(f\"Contact: {contact}\")\n\n# Get contact attributes\nattrs = droid.contactsGetAttributes().result\nprint(f\"Available attributes: {attrs}\")\n
    "},{"location":"qsl4a/connectivity/ftp/","title":"FTP Server API","text":"

    Start and manage a built-in FTP server on the device.

    "},{"location":"qsl4a/connectivity/ftp/#ftp-server-methods","title":"FTP Server Methods","text":""},{"location":"qsl4a/connectivity/ftp/#ftpstart","title":"ftpStart()","text":"

    Start the FTP server.

    ftpStart()\n

    Returns: Array containing IP address and port [ip, port]

    "},{"location":"qsl4a/connectivity/ftp/#ftpstop","title":"ftpStop()","text":"

    Stop the FTP server.

    ftpStop()\n
    "},{"location":"qsl4a/connectivity/ftp/#ftpisrunning","title":"ftpIsRunning()","text":"

    Check if FTP server is running.

    ftpIsRunning()\n

    Returns: True if running

    "},{"location":"qsl4a/connectivity/ftp/#ftpget","title":"ftpGet()","text":"

    Get FTP server IP address.

    ftpGet()\n

    Returns: Array with IP address and port

    "},{"location":"qsl4a/connectivity/ftp/#ftpset","title":"ftpSet()","text":"

    Configure FTP server settings.

    ftpSet(port=None, rootDir=None, username=None, password=None)\n

    Parameters: - port (int, optional): Server port - rootDir (str, optional): Root directory to serve - username (str, optional): Login username - password (str, optional): Login password

    Returns: JSONObject with current settings

    "},{"location":"qsl4a/connectivity/ftp/#ftpstatus","title":"ftpStatus()","text":"

    Get FTP server status.

    ftpStatus()\n

    Returns: String status description

    "},{"location":"qsl4a/connectivity/ftp/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Configure FTP server\ndroid.ftpSet(\n    port=2121,\n    rootDir=\"/sdcard\",\n    username=\"admin\",\n    password=\"secret\"\n)\n\n# Start FTP server\ninfo = droid.ftpStart().result\nprint(f\"FTP running at {info[0]}:{info[1]}\")\n\n# Check status\nif droid.ftpIsRunning().result:\n    print(\"FTP server is running\")\n\n# Get server info\nserver_info = droid.ftpGet().result\nprint(f\"Server: {server_info}\")\n\n# Stop when done\ndroid.ftpStop()\n

    Note: Connect to the FTP server using any FTP client with the provided credentials.

    "},{"location":"qsl4a/connectivity/location/","title":"Location API","text":"

    Access GPS and network location services.

    "},{"location":"qsl4a/connectivity/location/#methods","title":"Methods","text":""},{"location":"qsl4a/connectivity/location/#startlocating","title":"startLocating()","text":"

    Start location updates.

    startLocating(minUpdateTime=60000, minUpdateDistance=30, updateGnssStatus=False)\n

    Parameters: - minUpdateTime (int): Minimum time between updates in milliseconds (default: 60000) - minUpdateDistance (float): Minimum distance for update in meters (default: 30) - updateGnssStatus (bool): Enable GNSS status updates (default: False)

    "},{"location":"qsl4a/connectivity/location/#stoplocating","title":"stopLocating()","text":"

    Stop location updates.

    stopLocating()\n
    "},{"location":"qsl4a/connectivity/location/#readlocation","title":"readLocation()","text":"

    Get last known location.

    readLocation()\n

    Returns: Location data dict

    "},{"location":"qsl4a/connectivity/location/#getlastknownlocation","title":"getLastKnownLocation()","text":"

    Get cached location.

    getLastKnownLocation()\n

    Returns: Location from all providers

    "},{"location":"qsl4a/connectivity/location/#geocode","title":"geocode()","text":"

    Convert address to coordinates.

    geocode(address, maxResults=1)\n
    "},{"location":"qsl4a/connectivity/location/#location-provider-methods","title":"Location Provider Methods)","text":""},{"location":"qsl4a/connectivity/location/#locationproviders","title":"locationProviders()","text":"

    Get available location providers on the phone.

    locationProviders()\n

    Returns: List of available provider names (e.g., ['gps', 'network'])

    "},{"location":"qsl4a/connectivity/location/#locationproviderenabled","title":"locationProviderEnabled()","text":"

    Check if a specific location provider is enabled.

    locationProviderEnabled(provider)\n

    Parameters: - provider (str): Provider name (e.g., 'gps', 'network')

    Returns: True if enabled, False otherwise

    "},{"location":"qsl4a/connectivity/location/#readgnssstatus","title":"readGnssStatus()","text":"

    Read Global Navigation Satellite System status (requires Android 8+).

    readGnssStatus()\n

    Returns: JSONArray containing GNSS satellite information

    "},{"location":"qsl4a/connectivity/location/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start location updates\ndroid.startLocating(minUpdateTime=5000, minUpdateDistance=1, updateGnssStatus=False)\n\n# Wait for fix\ntime.sleep(10)\n\n# Get location\nloc = droid.readLocation().result\nif loc:\n    lat = loc['latitude']\n    lon = loc['longitude']\n    print(f\"Location: {lat}, {lon}\")\n\ndroid.stopLocating()\n
    "},{"location":"qsl4a/connectivity/phone/","title":"Phone API","text":"

    Control phone calls and retrieve phone information.

    "},{"location":"qsl4a/connectivity/phone/#phone-state-tracking","title":"Phone State Tracking","text":""},{"location":"qsl4a/connectivity/phone/#starttrackingphonestate","title":"startTrackingPhoneState()","text":"

    Start tracking phone state changes. Generates 'phone' events.

    startTrackingPhoneState()\n
    "},{"location":"qsl4a/connectivity/phone/#readphonestate","title":"readPhoneState()","text":"

    Read the current phone state.

    readPhoneState()\n

    Returns: Bundle with phone state and incoming number

    "},{"location":"qsl4a/connectivity/phone/#stoptrackingphonestate","title":"stopTrackingPhoneState()","text":"

    Stop tracking phone state.

    stopTrackingPhoneState()\n
    "},{"location":"qsl4a/connectivity/phone/#making-calls","title":"Making Calls","text":""},{"location":"qsl4a/connectivity/phone/#phonecall","title":"phoneCall()","text":"

    Call a contact/phone number by URI.

    phoneCall(uri)\n

    Parameters: - uri (str): Contact URI or phone number URI

    "},{"location":"qsl4a/connectivity/phone/#phonecallnumber","title":"phoneCallNumber()","text":"

    Call a phone number directly.

    phoneCallNumber(phone_number)\n

    Parameters: - phone_number (str): Phone number to call

    "},{"location":"qsl4a/connectivity/phone/#phonedial","title":"phoneDial()","text":"

    Dial a number (opens dialer without calling).

    phoneDial(uri)\n

    Parameters: - uri (str): Contact URI or phone number URI

    "},{"location":"qsl4a/connectivity/phone/#phonedialnumber","title":"phoneDialNumber()","text":"

    Dial a phone number (opens dialer without calling).

    phoneDialNumber(phone_number)\n

    Parameters: - phone_number (str): Phone number

    "},{"location":"qsl4a/connectivity/phone/#cell-location","title":"Cell Location","text":""},{"location":"qsl4a/connectivity/phone/#getcelllocation","title":"getCellLocation()","text":"

    Get the current cell location.

    getCellLocation()\n

    Returns: JSONObject with cell location data

    "},{"location":"qsl4a/connectivity/phone/#getallcellslocation","title":"getAllCellsLocation()","text":"

    Get all cell locations (for dual SIM devices).

    getAllCellsLocation()\n

    Returns: JSONArray of cell locations

    "},{"location":"qsl4a/connectivity/phone/#network-information","title":"Network Information","text":""},{"location":"qsl4a/connectivity/phone/#getnetworkoperator","title":"getNetworkOperator()","text":"

    Get the MCC+MNC of the current operator.

    getNetworkOperator()\n

    Returns: String (e.g., '310260')

    "},{"location":"qsl4a/connectivity/phone/#getnetworkoperatorname","title":"getNetworkOperatorName()","text":"

    Get the name of the current operator.

    getNetworkOperatorName()\n

    Returns: String (e.g., 'T-Mobile')

    "},{"location":"qsl4a/connectivity/phone/#getnetworktype","title":"getNetworkType()","text":"

    Get the current network type.

    getNetworkType()\n

    Returns: String describing radio technology (e.g., 'LTE', 'UMTS', 'GSM')

    "},{"location":"qsl4a/connectivity/phone/#getphonetype","title":"getPhoneType()","text":"

    Get the phone type.

    getPhoneType()\n

    Returns: String (e.g., 'GSM', 'CDMA', 'SIP')

    "},{"location":"qsl4a/connectivity/phone/#sim-information","title":"SIM Information","text":""},{"location":"qsl4a/connectivity/phone/#getsimcountryiso","title":"getSimCountryIso()","text":"

    Get the ISO country code for the SIM.

    getSimCountryIso()\n

    Returns: String (e.g., 'us')

    "},{"location":"qsl4a/connectivity/phone/#getsimoperator","title":"getSimOperator()","text":"

    Get the MCC+MNC of the SIM operator.

    getSimOperator()\n

    Returns: String (e.g., '310260')

    "},{"location":"qsl4a/connectivity/phone/#getsimoperatorname","title":"getSimOperatorName()","text":"

    Get the SIM operator name.

    getSimOperatorName()\n

    Returns: String (e.g., 'T-Mobile')

    "},{"location":"qsl4a/connectivity/phone/#getsimserialnumber","title":"getSimSerialNumber()","text":"

    Get the SIM serial number.

    getSimSerialNumber()\n

    Returns: String SIM serial number

    "},{"location":"qsl4a/connectivity/phone/#getsimstate","title":"getSimState()","text":"

    Get the SIM card state.

    getSimState()\n

    Returns: String describing SIM state

    "},{"location":"qsl4a/connectivity/phone/#getsubscriberid","title":"getSubscriberId()","text":"

    Get the subscriber ID.

    getSubscriberId()\n

    Returns: String subscriber ID

    "},{"location":"qsl4a/connectivity/phone/#voice-mail","title":"Voice Mail","text":""},{"location":"qsl4a/connectivity/phone/#getvoicemailalphatag","title":"getVoiceMailAlphaTag()","text":"

    Get the voice mail alpha tag.

    getVoiceMailAlphaTag()\n

    Returns: String voice mail tag

    "},{"location":"qsl4a/connectivity/phone/#getvoicemailnumber","title":"getVoiceMailNumber()","text":"

    Get the voice mail number.

    getVoiceMailNumber()\n

    Returns: String voice mail number

    "},{"location":"qsl4a/connectivity/phone/#device-information","title":"Device Information","text":""},{"location":"qsl4a/connectivity/phone/#getdeviceid","title":"getDeviceId()","text":"

    Get the device ID (IMEI for GSM). Deprecated.

    getDeviceId()\n

    Returns: String device ID

    "},{"location":"qsl4a/connectivity/phone/#getdevicesoftwareversion","title":"getDeviceSoftwareVersion()","text":"

    Get the device software version.

    getDeviceSoftwareVersion()\n

    Returns: String software version

    "},{"location":"qsl4a/connectivity/phone/#getline1number","title":"getLine1Number()","text":"

    Get the line 1 phone number.

    getLine1Number()\n

    Returns: String phone number

    "},{"location":"qsl4a/connectivity/phone/#checknetworkroaming","title":"checkNetworkRoaming()","text":"

    Check if connected to roaming network.

    checkNetworkRoaming()\n

    Returns: True if roaming

    "},{"location":"qsl4a/connectivity/phone/#cell-info","title":"Cell Info","text":""},{"location":"qsl4a/connectivity/phone/#getallcellinfo","title":"getAllCellInfo()","text":"

    Get information about all cells.

    getAllCellInfo()\n

    Returns: List of cell information

    "},{"location":"qsl4a/connectivity/phone/#setdataenabled","title":"setDataEnabled()","text":"

    Enable or disable mobile data.

    setDataEnabled(enabled)\n

    Parameters: - enabled (bool): True to enable, False to disable

    "},{"location":"qsl4a/connectivity/phone/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get network info\noperator = droid.getNetworkOperatorName().result\nprint(f\"Operator: {operator}\")\n\nnetwork_type = droid.getNetworkType().result\nprint(f\"Network: {network_type}\")\n\n# Get SIM info\nsim_state = droid.getSimState().result\nprint(f\"SIM: {sim_state}\")\n\n# Get phone number\nline1 = droid.getLine1Number().result\nprint(f\"Phone: {line1}\")\n\n# Track phone state\ndroid.startTrackingPhoneState()\nprint(\"Tracking phone state...\")\ndroid.stopTrackingPhoneState()\n
    "},{"location":"qsl4a/connectivity/signalstrength/","title":"Signal Strength API","text":"

    Monitor cellular and wireless signal strength.

    "},{"location":"qsl4a/connectivity/signalstrength/#signal-strength-methods","title":"Signal Strength Methods","text":""},{"location":"qsl4a/connectivity/signalstrength/#starttrackingsignalstrengths","title":"startTrackingSignalStrengths()","text":"

    Start tracking signal strength changes. Generates 'signal_strengths' events.

    startTrackingSignalStrengths()\n
    "},{"location":"qsl4a/connectivity/signalstrength/#stoptrackingsignalstrengths","title":"stopTrackingSignalStrengths()","text":"

    Stop tracking signal strengths.

    stopTrackingSignalStrengths()\n
    "},{"location":"qsl4a/connectivity/signalstrength/#readsignalstrengths","title":"readSignalStrengths()","text":"

    Read the current signal strengths.

    readSignalStrengths()\n

    Returns: Bundle with signal strength data

    "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthlevel","title":"getTelephoneSignalStrengthLevel()","text":"

    Get the telephone signal strength as a level (0-4).

    getTelephoneSignalStrengthLevel()\n

    Returns: Integer level (0=none, 1=poor, 2=fair, 3=good, 4=excellent)

    "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthdetail","title":"getTelephoneSignalStrengthDetail()","text":"

    Get detailed telephone signal strength information.

    getTelephoneSignalStrengthDetail()\n

    Returns: String with detailed signal info

    "},{"location":"qsl4a/connectivity/signalstrength/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start tracking signal strength\ndroid.startTrackingSignalStrengths()\n\n# Wait for signal updates\ntime.sleep(5)\n\n# Read current signal strength\nsignal = droid.readSignalStrengths().result\nprint(f\"Signal: {signal}\")\n\n# Get level directly\nlevel = droid.getTelephoneSignalStrengthLevel().result\nprint(f\"Signal level: {level}/4\")\n\ndroid.stopTrackingSignalStrengths()\n
    "},{"location":"qsl4a/connectivity/sms/","title":"SMS API","text":"

    Send and receive SMS messages.

    "},{"location":"qsl4a/connectivity/sms/#methods","title":"Methods","text":""},{"location":"qsl4a/connectivity/sms/#smssend","title":"smsSend()","text":"

    Send SMS message.

    smsSend(destinationAddress, text)\n

    Parameters: - destinationAddress (str): Phone number - text (str): Message text

    "},{"location":"qsl4a/connectivity/sms/#smsgetmessagecount","title":"smsGetMessageCount()","text":"

    Get message count.

    smsGetMessageCount(unreadOnly=False, folder=\"inbox\")\n
    "},{"location":"qsl4a/connectivity/sms/#smsgetmessageids","title":"smsGetMessageIds()","text":"

    Get message IDs.

    smsGetMessageIds(unreadOnly=False, folder=\"inbox\")\n
    "},{"location":"qsl4a/connectivity/sms/#smsgetmessages","title":"smsGetMessages()","text":"

    Get message details.

    smsGetMessages(unreadOnly=False, folder=\"inbox\", attributes=None)\n
    "},{"location":"qsl4a/connectivity/sms/#smsgetmessagebyid","title":"smsGetMessageById()","text":"

    Get a specific message by ID.

    smsGetMessageById(id, attributes=None)\n

    Parameters: - id (int): Message ID - attributes (list, optional): Specific attributes to retrieve

    Returns: Message data dict

    "},{"location":"qsl4a/connectivity/sms/#smsgetattributes","title":"smsGetAttributes()","text":"

    Get available SMS message attributes.

    smsGetAttributes()\n

    Returns: List of available attribute names

    "},{"location":"qsl4a/connectivity/sms/#smsdeletemessage","title":"smsDeleteMessage()","text":"

    Delete message.

    smsDeleteMessage(id)\n
    "},{"location":"qsl4a/connectivity/sms/#smsmarkmessageread","title":"smsMarkMessageRead()","text":"

    Mark message as read.

    smsMarkMessageRead(ids, read=True)\n
    "},{"location":"qsl4a/connectivity/sms/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Send SMS\ndroid.smsSend(\"+1234567890\", \"Hello from QPython!\")\n\n# Get unread messages\nmessages = droid.smsGetMessages(unreadOnly=True).result\nfor msg in messages:\n    print(f\"From: {msg['address']}, Text: {msg['body']}\")\n
    "},{"location":"qsl4a/connectivity/wifi/","title":"WiFi API","text":"

    Control WiFi adapter and get connection information.

    "},{"location":"qsl4a/connectivity/wifi/#adapter-control","title":"Adapter Control","text":""},{"location":"qsl4a/connectivity/wifi/#checkwifistate","title":"checkWifiState()","text":"

    Check if WiFi is enabled.

    checkWifiState()\n

    Returns: True if WiFi is enabled, False otherwise

    "},{"location":"qsl4a/connectivity/wifi/#togglewifistate","title":"toggleWifiState()","text":"

    Turn WiFi on or off.

    toggleWifiState(enabled=None)\n

    Parameters: - enabled (bool): True to enable, False to disable, None to toggle

    Returns: True if operation succeeded

    "},{"location":"qsl4a/connectivity/wifi/#wifistartscan","title":"wifiStartScan()","text":"

    Start scanning for available WiFi networks.

    wifiStartScan()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifigetscanresults","title":"wifiGetScanResults()","text":"

    Get list of discovered WiFi networks.

    wifiGetScanResults()\n

    Returns: List of access point information

    "},{"location":"qsl4a/connectivity/wifi/#connection-management","title":"Connection Management","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetconnectioninfo","title":"wifiGetConnectionInfo()","text":"

    Get detailed connection information.

    wifiGetConnectionInfo()\n

    Returns: Dict with connection details including SSID, BSSID, IP address

    "},{"location":"qsl4a/connectivity/wifi/#getconnectedinfo","title":"getConnectedInfo()","text":"

    Get connected WiFi network info (simplified).

    getConnectedInfo()\n

    Returns: Dict with SSID, BSSID, signal strength

    "},{"location":"qsl4a/connectivity/wifi/#getdhcpinfo","title":"getDhcpInfo()","text":"

    Get DHCP information for current connection.

    getDhcpInfo(ipConvertToString=True)\n

    Parameters: - ipConvertToString (bool): Convert IP addresses to string format (default: True)

    Returns: Dict with DHCP info including IP, gateway, DNS

    "},{"location":"qsl4a/connectivity/wifi/#wifidisconnect","title":"wifiDisconnect()","text":"

    Disconnect from current WiFi network.

    wifiDisconnect()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifireconnect","title":"wifiReconnect()","text":"

    Reconnect to the current network.

    wifiReconnect()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifireassociate","title":"wifiReassociate()","text":"

    Reassociate with the current access point.

    wifiReassociate()\n
    "},{"location":"qsl4a/connectivity/wifi/#hotspot","title":"Hotspot","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetapstate","title":"wifiGetApState()","text":"

    Get WiFi AP (hotspot) state.

    wifiGetApState()\n

    Returns: Hotspot state

    "},{"location":"qsl4a/connectivity/wifi/#wifi-locks","title":"WiFi Locks","text":""},{"location":"qsl4a/connectivity/wifi/#wifilockacquirefull","title":"wifiLockAcquireFull()","text":"

    Acquire a full WiFi lock (keeps WiFi active even when screen is off).

    wifiLockAcquireFull()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifilockacquirescanonly","title":"wifiLockAcquireScanOnly()","text":"

    Acquire a scan-only WiFi lock.

    wifiLockAcquireScanOnly()\n
    "},{"location":"qsl4a/connectivity/wifi/#wifilockrelease","title":"wifiLockRelease()","text":"

    Release the WiFi lock.

    wifiLockRelease()\n
    "},{"location":"qsl4a/connectivity/wifi/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Check WiFi state\nif droid.checkWifiState().result:\n    print(\"WiFi is enabled\")\nelse:\n    print(\"Enabling WiFi...\")\n    droid.toggleWifiState(True)\n    time.sleep(2)\n\n# Start scanning\ndroid.wifiStartScan()\ntime.sleep(3)\n\n# Get scan results\nnetworks = droid.wifiGetScanResults().result\nfor network in networks:\n    print(f\"SSID: {network.get('SSID')}, Signal: {network.get('level')} dBm\")\n\n# Get connection info\ninfo = droid.wifiGetConnectionInfo().result\nif info:\n    print(f\"Connected to: {info.get('ssid')}\")\n    print(f\"BSSID: {info.get('bssid')}\")\n    print(f\"IP: {info.get('ip_address')}\")\n\n# Get DHCP info\ndhcp = droid.getDhcpInfo().result\nif dhcp:\n    print(f\"Gateway: {dhcp.get('gateway')}\")\n    print(f\"DNS: {dhcp.get('dns1')}\")\n\n# Get simplified connected info\nconnected = droid.getConnectedInfo().result\nprint(f\"SSID: {connected.get('ssid')}, Signal: {connected.get('level')} dBm\")\n\n# Disconnect and reconnect\ndroid.wifiDisconnect()\ntime.sleep(1)\ndroid.wifiReconnect()\n\n# Reassociate with access point\ndroid.wifiReassociate()\n\n# Check hotspot state\nap_state = droid.wifiGetApState().result\nprint(f\"Hotspot state: {ap_state}\")\n\n# Acquire WiFi lock for background operation\ndroid.wifiLockAcquireFull()\n# ... do work ...\ndroid.wifiLockRelease()\n\n# Or use scan-only lock for lighter background operation\ndroid.wifiLockAcquireScanOnly()\n# ... do scanning work ...\ndroid.wifiLockRelease()\n
    "},{"location":"qsl4a/core/android-base/","title":"Android Base Class","text":"

    The Android class is the core of QSL4A, providing the connection to the Android runtime and RPC mechanism.

    "},{"location":"qsl4a/core/android-base/#module-import","title":"Module Import","text":"
    # Full featured (recommended)\nimport androidhelper\ndroid = androidhelper.Android()\n\n# Minimal version (quick, single instance)\nimport android\ndroid = android.droid\n
    "},{"location":"qsl4a/core/android-base/#class-android","title":"Class: Android","text":""},{"location":"qsl4a/core/android-base/#constructor","title":"Constructor","text":"
    Android(addr=None)\n

    Parameters: - addr (tuple, optional): (HOST, PORT) address. If None, uses environment variables AP_HOST and AP_PORT

    Environment Variables: - AP_HOST - Server host address - AP_PORT - Server port - AP_HANDSHAKE - Authentication token

    "},{"location":"qsl4a/core/android-base/#core-methods","title":"Core Methods","text":""},{"location":"qsl4a/core/android-base/#_rpc","title":"_rpc()","text":"

    Internal RPC method for calling Android functions.

    _rpc(method, *args)\n

    Parameters: - method (str): Method name to call - *args: Variable arguments for the method

    Returns: Result namedtuple with fields: - id (int): Request ID - result: Method return value - error (str or None): Error message if failed

    "},{"location":"qsl4a/core/android-base/#getattr","title":"getattr()","text":"

    Dynamic method dispatcher. All Android methods are accessed via attribute lookup.

    # These are equivalent:\ndroid.makeToast(\"Hello\")\ndroid._rpc(\"makeToast\", \"Hello\")\n
    "},{"location":"qsl4a/core/android-base/#standalone-functions-androidpy","title":"Standalone Functions (android.py)","text":"

    When using the minimal android module:

    "},{"location":"qsl4a/core/android-base/#jsla","title":"jsla()","text":"

    Send JSON-RPC request and return raw response.

    jsla(method, *params)\n

    Returns: JSON string response

    "},{"location":"qsl4a/core/android-base/#rsla","title":"rsla()","text":"

    Send request and return result only.

    rsla(method, *params)\n

    Returns: Result value from RPC call

    "},{"location":"qsl4a/core/android-base/#esla","title":"esla()","text":"

    Send request, raise exception on error.

    esla(method, *params)\n

    Raises: Exception if error field is not None

    "},{"location":"qsl4a/core/android-base/#nsla","title":"nsla()","text":"

    Send request and return Result namedtuple.

    nsla(method, *params)\n

    Returns: Result namedtuple

    "},{"location":"qsl4a/core/android-base/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/android-base/#basic-connection","title":"Basic Connection","text":"
    import androidhelper\n\n# Connect to Android runtime\ndroid = androidhelper.Android()\n\n# Check connection by showing toast\ndroid.makeToast(\"Connected!\")\n
    "},{"location":"qsl4a/core/android-base/#error-handling","title":"Error Handling","text":"
    result = droid.someMethod()\nif result.error:\n    print(f\"Error: {result.error}\")\nelse:\n    print(f\"Success: {result.result}\")\n
    "},{"location":"qsl4a/core/android-base/#direct-rpc-call","title":"Direct RPC Call","text":"
    # Call any method directly\nresult = droid._rpc(\"makeToast\", \"Hello World\")\n
    "},{"location":"qsl4a/core/events/","title":"Event System","text":"

    QSL4A provides an event system for handling asynchronous events from Android, such as sensor updates, location changes, and custom broadcasts.

    "},{"location":"qsl4a/core/events/#event-basics","title":"Event Basics","text":"

    Events are stored in a buffer and can be polled or waited for. Each event has: - name: Event type/name - data: Event payload data - time: Timestamp

    "},{"location":"qsl4a/core/events/#event-methods","title":"Event Methods","text":""},{"location":"qsl4a/core/events/#eventclearbuffer","title":"eventClearBuffer()","text":"

    Clear all pending events from the buffer.

    eventClearBuffer()\n

    Returns: None

    "},{"location":"qsl4a/core/events/#eventpoll","title":"eventPoll()","text":"

    Poll for events in the buffer.

    eventPoll(number_of_events=1)\n

    Parameters: - number_of_events (int): Maximum events to retrieve (default: 1)

    Returns: List of event objects

    "},{"location":"qsl4a/core/events/#eventwait","title":"eventWait()","text":"

    Wait for any event.

    eventWait(timeout=None)\n

    Parameters: - timeout (int, optional): Timeout in seconds. None = wait forever

    Returns: Event object or None if timeout

    "},{"location":"qsl4a/core/events/#eventwaitfor","title":"eventWaitFor()","text":"

    Wait for a specific event.

    eventWaitFor(eventName, timeout=None)\n

    Parameters: - eventName (str): Name of event to wait for - timeout (int, optional): Timeout in seconds

    Returns: Event object or None if timeout

    "},{"location":"qsl4a/core/events/#eventpost","title":"eventPost()","text":"

    Post a custom event.

    eventPost(name, data, enqueue=None)\n

    Parameters: - name (str): Event name - data: Event data (any type) - enqueue (bool, optional): Add to queue if True

    "},{"location":"qsl4a/core/events/#receiveevent","title":"receiveEvent()","text":"

    Receive event (blocking).

    receiveEvent()\n

    Returns: Event object

    "},{"location":"qsl4a/core/events/#broadcast-events","title":"Broadcast Events","text":"

    Register for system broadcast events.

    "},{"location":"qsl4a/core/events/#eventregisterforbroadcast","title":"eventRegisterForBroadcast()","text":"

    Register to receive broadcast events.

    eventRegisterForBroadcast(category, enqueue=True)\n

    Parameters: - category (str): Broadcast category/action - enqueue (bool): Add to event queue

    "},{"location":"qsl4a/core/events/#eventunregisterforbroadcast","title":"eventUnregisterForBroadcast()","text":"

    Unregister from broadcast events.

    eventUnregisterForBroadcast(category)\n
    "},{"location":"qsl4a/core/events/#eventgetbrodcastcategories","title":"eventGetBrodcastCategories()","text":"

    Get registered broadcast categories.

    eventGetBrodcastCategories()\n

    Returns: List of registered categories

    "},{"location":"qsl4a/core/events/#event-dispatcher","title":"Event Dispatcher)","text":""},{"location":"qsl4a/core/events/#starteventdispatcher","title":"startEventDispatcher()","text":"

    Opens up a socket where you can read for events posted.)

    startEventDispatcher(port=0)\n

    Parameters: - port (int, optional): Port to listen on (default: 0 = auto-select)

    Returns: Port number being listened on

    "},{"location":"qsl4a/core/events/#stopeventdispatcher","title":"stopEventDispatcher()","text":"

    Stops the event server.)

    stopEventDispatcher()\n
    "},{"location":"qsl4a/core/events/#deprecated-methods","title":"Deprecated Methods","text":""},{"location":"qsl4a/core/events/#rpcpostevent","title":"rpcPostEvent()","text":"

    Post an event to the event queue. (Deprecated, use eventPost)

    rpcPostEvent(name, data)\n

    Parameters: - name (str): Event name - data: Event data

    "},{"location":"qsl4a/core/events/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/events/#basic-event-polling","title":"Basic Event Polling","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Clear old events\ndroid.eventClearBuffer()\n\n# Poll for events\nevents = droid.eventPoll(5).result\nfor event in events:\n    print(f\"Event: {event['name']}, Data: {event['data']}\")\n
    "},{"location":"qsl4a/core/events/#waiting-for-events","title":"Waiting for Events","text":"
    # Wait for any event with timeout\nevent = droid.eventWait(timeout=10).result\nif event:\n    print(f\"Got event: {event['name']}\")\n
    "},{"location":"qsl4a/core/events/#waiting-for-specific-event","title":"Waiting for Specific Event","text":"
    # Wait for sensor event\nevent = droid.eventWaitFor('screen', timeout=5).result\nif event:\n    print(f\"Screen event: {event['data']}\")\n
    "},{"location":"qsl4a/core/events/#posting-custom-events","title":"Posting Custom Events","text":"
    # Post custom event\ndroid.eventPost('my_event', {'key': 'value'})\n\n# Wait for it\nevent = droid.eventWaitFor('my_event', timeout=1).result\n
    "},{"location":"qsl4a/core/events/#broadcast-receiver","title":"Broadcast Receiver","text":"
    # Register for screen on/off events\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_ON')\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_OFF')\n\n# Wait for screen events\nwhile True:\n    event = droid.receiveEvent().result\n    if event['name'] == 'android.intent.action.SCREEN_ON':\n        print(\"Screen turned on\")\n    elif event['name'] == 'android.intent.action.SCREEN_OFF':\n        print(\"Screen turned off\")\n
    "},{"location":"qsl4a/core/events/#sensor-event-handling","title":"Sensor Event Handling","text":"
    # Start sensing\ndroid.startSensingTimed(1, 250)\n\n# Process sensor events\nfor _ in range(100):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'sensors':\n        data = event['data']\n        print(f\"Accel: {data['xforce']}, {data['yforce']}, {data['zforce']}\")\n\ndroid.stopSensing()\n
    "},{"location":"qsl4a/core/events/#common-event-types","title":"Common Event Types","text":"Event Name Description Source sensors Sensor data update startSensing* location GPS location update startLocating phone Phone state change startTrackingPhoneState signal Signal strength change startTrackingSignalStrength screen Screenshot ready fullGetScreenShot dialog Dialog response dialogShow*"},{"location":"qsl4a/core/events/#event-data-structure","title":"Event Data Structure","text":"
    {\n    'name': 'event_name',\n    'data': {\n        # Event-specific data\n    },\n    'time': 1234567890  # Timestamp\n}\n
    "},{"location":"qsl4a/core/intent/","title":"Intent System","text":"

    Android Intents are used to start activities, send broadcasts, and communicate between apps. QSL4A provides full Intent support through the Intent module.

    "},{"location":"qsl4a/core/intent/#module-import","title":"Module Import","text":"
    import androidhelper\ndon = androidhelper.Android()\n
    "},{"location":"qsl4a/core/intent/#intent-constants","title":"Intent Constants","text":"

    Access via droid.Intent:

    "},{"location":"qsl4a/core/intent/#actions","title":"Actions","text":"Constant Value Usage ACTION_MAIN android.intent.action.MAIN App entry point ACTION_VIEW android.intent.action.VIEW View content ACTION_EDIT android.intent.action.EDIT Edit content ACTION_PICK android.intent.action.PICK Pick item ACTION_SEND android.intent.action.SEND Share content ACTION_SEARCH android.intent.action.SEARCH Search"},{"location":"qsl4a/core/intent/#flags","title":"Flags","text":"Constant Value Usage FLAG_ACTIVITY_NEW_TASK 268435456 Start new task FLAG_ACTIVITY_CLEAR_TASK 32768 Clear task stack FLAG_ACTIVITY_NEW_DOCUMENT 524288 New document mode"},{"location":"qsl4a/core/intent/#extras","title":"Extras","text":"Constant Usage EXTRA_TEXT Text content EXTRA_STREAM File URI EXTRA_SUBJECT Subject line EXTRA_EMAIL Email address"},{"location":"qsl4a/core/intent/#core-methods","title":"Core Methods","text":""},{"location":"qsl4a/core/intent/#makeintent","title":"makeIntent()","text":"

    Create an Intent object.

    makeIntent(action, uri=None, type=None, extras=None, categories=None,\n           packagename=None, classname=None, flags=None)\n

    Parameters: - action (str): Intent action (e.g., droid.Intent.ACTION_VIEW) - uri (str, optional): Data URI - type (str, optional): MIME type - extras (dict, optional): Extra data - categories (list, optional): Intent categories - packagename (str, optional): Target package - classname (str, optional): Target class - flags (int, optional): Intent flags

    Returns: Intent object

    "},{"location":"qsl4a/core/intent/#startactivityintent","title":"startActivityIntent()","text":"

    Start an Activity with an Intent.

    startActivityIntent(intent, wait=None)\n

    Parameters: - intent: Intent object from makeIntent() - wait (bool, optional): Block until activity closes

    "},{"location":"qsl4a/core/intent/#startactivityforresultintent","title":"startActivityForResultIntent()","text":"

    Start activity and wait for result.

    startActivityForResultIntent(intent)\n

    Returns: Activity result

    "},{"location":"qsl4a/core/intent/#sendbroadcastintent","title":"sendBroadcastIntent()","text":"

    Send a broadcast.

    sendBroadcastIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#view","title":"view()","text":"

    View content by URI.

    view(uri, type=None, extras=None)\n
    "},{"location":"qsl4a/core/intent/#pick","title":"pick()","text":"

    Pick content from URI.

    pick(uri)\n
    "},{"location":"qsl4a/core/intent/#common-intent-methods","title":"Common Intent Methods)","text":""},{"location":"qsl4a/core/intent/#scanbarcode","title":"scanBarcode()","text":"

    Launch the barcode scanner.

    scanBarcode()\n

    Returns: Scanned barcode string

    "},{"location":"qsl4a/core/intent/#send","title":"send()","text":"

    Send content via share intent.

    send(type, content)\n

    Parameters: - type (str): MIME type - content (str): Content to share

    "},{"location":"qsl4a/core/intent/#sendtext","title":"sendText()","text":"

    Send text content.

    sendText(text)\n

    Parameters: - text (str): Text to send

    "},{"location":"qsl4a/core/intent/#sendemail","title":"sendEmail()","text":"

    Send an email.

    sendEmail(to, subject, body, attachment=None)\n

    Parameters: - to (str or list): Recipient email address(es) - subject (str): Email subject - body (str): Email body - attachment (str, optional): Attachment file path

    "},{"location":"qsl4a/core/intent/#pathtouri","title":"pathToUri()","text":"

    Convert file path to content URI.

    pathToUri(path)\n

    Parameters: - path (str): File path

    Returns: Content URI string

    "},{"location":"qsl4a/core/intent/#openfile","title":"openFile()","text":"

    Open a file with appropriate app.

    openFile(path)\n

    Parameters: - path (str): File path to open

    "},{"location":"qsl4a/core/intent/#sendfile","title":"sendFile()","text":"

    Send a file via share intent.

    sendFile(path)\n

    Parameters: - path (str): File path to send

    "},{"location":"qsl4a/core/intent/#getpathtype","title":"getPathType()","text":"

    Get the MIME type for a file path.

    getPathType(path)\n

    Parameters: - path (str): File path

    Returns: MIME type string

    "},{"location":"qsl4a/core/intent/#viewmap","title":"viewMap()","text":"

    Open map at a location.

    viewMap(latitude, longitude)\n

    Parameters: - latitude (float): Latitude - longitude (float): Longitude

    "},{"location":"qsl4a/core/intent/#viewcontacts","title":"viewContacts()","text":"

    Open the contacts app.

    viewContacts()\n
    "},{"location":"qsl4a/core/intent/#search","title":"search()","text":"

    Perform a web search.

    search(query)\n

    Parameters: - query (str): Search query

    "},{"location":"qsl4a/core/intent/#viewhtml","title":"viewHtml()","text":"

    View HTML content.

    viewHtml(content, encoding=None)\n

    Parameters: - content (str): HTML content - encoding (str, optional): Character encoding

    "},{"location":"qsl4a/core/intent/#webviewshow","title":"webViewShow()","text":"

    Display web content in WebView. Deprecated, use viewHtml.

    webViewShow(url)\n

    Parameters: - url (str): Web page URL

    "},{"location":"qsl4a/core/intent/#editoropen","title":"editorOpen()","text":"

    Open a text editor.

    editorOpen(path=None, create=False)\n

    Parameters: - path (str, optional): File path to edit - create (bool, optional): Create if doesn't exist

    "},{"location":"qsl4a/core/intent/#helper-class-uri","title":"Helper Class: Uri","text":"

    Create URI objects for Intents:

    from androidhelper.Intent import Uri\n\nuri = Uri(\"file:///sdcard/test.txt\")\n
    "},{"location":"qsl4a/core/intent/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/intent/#open-web-page","title":"Open Web Page","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"http://www.example.com\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#share-text","title":"Share Text","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_TEXT: \"Hello from QPython!\",\n        droid.Intent.EXTRA_SUBJECT: \"Test\"\n    },\n    type=\"text/plain\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#open-file","title":"Open File","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"file:///sdcard/document.pdf\",\n    type=\"application/pdf\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#pick-contact","title":"Pick Contact","text":"
    result = droid.pickContact()\ncontact_uri = result.result\n
    "},{"location":"qsl4a/core/intent/#send-email","title":"Send Email","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_EMAIL: [\"test@example.com\"],\n        droid.Intent.EXTRA_SUBJECT: \"Hello\",\n        droid.Intent.EXTRA_TEXT: \"Message body\"\n    },\n    type=\"message/rfc822\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/core/intent/#open-app","title":"Open App","text":"
    intent = droid.makeIntent(\n    action=droid.Intent.ACTION_MAIN,\n    packagename=\"com.android.settings\",\n    classname=\"com.android.settings.Settings\"\n).result\ndroid.startActivityIntent(intent)\n
    "},{"location":"qsl4a/hardware/bluetooth/","title":"Bluetooth API","text":"

    Control Bluetooth adapter and communicate with Bluetooth devices.

    "},{"location":"qsl4a/hardware/bluetooth/#adapter-control","title":"Adapter Control","text":""},{"location":"qsl4a/hardware/bluetooth/#togglebluetoothstate","title":"toggleBluetoothState()","text":"

    Turn Bluetooth on/off.

    toggleBluetoothState(enabled=None, prompt=True)\n

    Parameters: - enabled (bool): True=on, False=off, None=toggle - prompt (bool): Show user prompt

    "},{"location":"qsl4a/hardware/bluetooth/#checkbluetoothstate","title":"checkBluetoothState()","text":"

    Check if Bluetooth is enabled.

    checkBluetoothState()\n

    Returns: True/False

    "},{"location":"qsl4a/hardware/bluetooth/#getlocalname","title":"GetLocalName()","text":"

    Get Bluetooth device name.

    GetLocalName()\n
    "},{"location":"qsl4a/hardware/bluetooth/#setlocalname","title":"SetLocalName()","text":"

    Set Bluetooth device name.

    SetLocalName(name)\n
    "},{"location":"qsl4a/hardware/bluetooth/#getscanmode","title":"GetScanMode()","text":"

    Get discoverability mode.

    GetScanMode()\n

    Returns: - -1: Disabled - 0: Non-discoverable, non-connectable - 1: Connectable, non-discoverable - 3: Connectable and discoverable

    "},{"location":"qsl4a/hardware/bluetooth/#makediscoverable","title":"MakeDiscoverable()","text":"

    Make device discoverable.

    MakeDiscoverable(duration=300)\n

    Parameters: - duration (int): Seconds to be discoverable

    "},{"location":"qsl4a/hardware/bluetooth/#discovery","title":"Discovery","text":""},{"location":"qsl4a/hardware/bluetooth/#discoverystart","title":"DiscoveryStart()","text":"

    Start device discovery.

    DiscoveryStart()\n
    "},{"location":"qsl4a/hardware/bluetooth/#discoverycancel","title":"DiscoveryCancel()","text":"

    Cancel discovery.

    DiscoveryCancel()\n
    "},{"location":"qsl4a/hardware/bluetooth/#getreceiveddevices","title":"GetReceivedDevices()","text":"

    Get discovered devices.

    GetReceivedDevices()\n

    Returns: List of device info dicts

    "},{"location":"qsl4a/hardware/bluetooth/#getbondeddevices","title":"GetBondedDevices()","text":"

    Get paired devices.

    GetBondedDevices()\n

    Returns: List of paired device info

    "},{"location":"qsl4a/hardware/bluetooth/#connection","title":"Connection","text":""},{"location":"qsl4a/hardware/bluetooth/#connect","title":"Connect()","text":"

    Connect to a device.

    Connect(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", address=None)\n

    Parameters: - uuid (str): Service UUID - address (str): Device address (None = show picker)

    Returns: True if successful

    "},{"location":"qsl4a/hardware/bluetooth/#accept","title":"Accept()","text":"

    Accept incoming connection.

    Accept(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", timeout=0)\n
    "},{"location":"qsl4a/hardware/bluetooth/#activeconnections","title":"ActiveConnections()","text":"

    Check active connections.

    ActiveConnections()\n
    "},{"location":"qsl4a/hardware/bluetooth/#stop","title":"Stop()","text":"

    Disconnect.

    Stop(connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#communication","title":"Communication","text":""},{"location":"qsl4a/hardware/bluetooth/#write","title":"Write()","text":"

    Send ASCII data.

    Write(ascii, connID=\"\")\n
    "},{"location":"qsl4a/hardware/bluetooth/#writebinary","title":"WriteBinary()","text":"

    Send binary data (base64 encoded).

    WriteBinary(base64, connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#read","title":"Read()","text":"

    Read ASCII data.

    Read(bufferSize=4096, connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#readbinary","title":"ReadBinary()","text":"

    Read binary data.

    ReadBinary(bufferSize=4096, connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#readline","title":"ReadLine()","text":"

    Read line.

    ReadLine(connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#readready","title":"ReadReady()","text":"

    Check if data available.

    ReadReady(connID=None)\n
    "},{"location":"qsl4a/hardware/bluetooth/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Enable Bluetooth\ndroid.toggleBluetoothState(True)\n\n# Get paired devices\ndevices = droid.GetBondedDevices().result\nfor dev in devices:\n    print(f\"{dev['name']}: {dev['address']}\")\n\n# Connect to device\ndroid.Connect(address=\"00:11:22:33:44:55\")\n\n# Send data\ndroid.Write(\"Hello Bluetooth!\")\n\n# Read response\ndata = droid.Read(1024).result\n
    "},{"location":"qsl4a/hardware/camera/","title":"Camera API","text":"

    Capture photos and record video.

    "},{"location":"qsl4a/hardware/camera/#photo-capture","title":"Photo Capture","text":""},{"location":"qsl4a/hardware/camera/#takepicture","title":"takePicture()","text":"

    Take a photo using the default camera.

    takePicture(path=None)\n

    Parameters: - path (str, optional): Save path. If None, returns image data

    Returns: Image path or image data

    "},{"location":"qsl4a/hardware/camera/#cameracapturepicture","title":"cameraCapturePicture()","text":"

    Capture picture with advanced camera controls.

    cameraCapturePicture(targetPath=None, cameraId=0, useAutoFocus=True)\n

    Parameters: - targetPath (str, optional): Save path - cameraId (int): Camera to use (0 = back, 1 = front) - useAutoFocus (bool): Enable auto focus

    Returns: Captured image path

    "},{"location":"qsl4a/hardware/camera/#camerasettorchmode","title":"cameraSetTorchMode()","text":"

    Control camera flashlight/torch.

    cameraSetTorchMode(enabled)\n

    Parameters: - enabled (bool): True to turn on, False to turn off

    Returns: True if successful

    "},{"location":"qsl4a/hardware/camera/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

    Capture screenshot.

    imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

    Parameters: - path (str, optional): Save path - delayMilliSec (int): Delay before capture

    "},{"location":"qsl4a/hardware/camera/#video-recording","title":"Video Recording","text":""},{"location":"qsl4a/hardware/camera/#takevideo","title":"takeVideo()","text":"

    Record video using default settings.

    takeVideo(path=None, quality=1)\n

    Parameters: - path (str, optional): Save path - quality (int): Video quality (0-4) - 0: 160x120 - 1: 320x240 - 2: 352x288 - 3: 640x480 - 4: 800x480

    "},{"location":"qsl4a/hardware/camera/#recordercapturevideo","title":"recorderCaptureVideo()","text":"

    Capture video with advanced controls.

    recorderCaptureVideo(targetPath=None, duration=10, cameraId=0, quality=8)\n

    Parameters: - targetPath (str, optional): Save path - duration (int): Recording duration in seconds (default: 10) - cameraId (int): Camera to use (0 = back, 1 = front) - quality (int): Video quality (0-8, higher is better)

    Returns: Video file path

    "},{"location":"qsl4a/hardware/camera/#recordaudio","title":"recordAudio()","text":"

    Record audio.

    recordAudio()\n

    Returns: Audio file path

    "},{"location":"qsl4a/hardware/camera/#screen-recording","title":"Screen Recording","text":""},{"location":"qsl4a/hardware/camera/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

    Start screen recording.

    recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

    Parameters: - path (str): Save path - audio (int): Audio source (0=none, 1=mic, 2=internal) - targetPixels (int): Resolution - frameRate (int): FPS - bitRate (int): Bitrate - rotation (bool): Rotate output - autoStart (bool): Start immediately

    "},{"location":"qsl4a/hardware/camera/#recorderstart","title":"recorderStart()","text":"

    Start recording.

    recorderStart()\n
    "},{"location":"qsl4a/hardware/camera/#recorderpause","title":"recorderPause()","text":"

    Pause recording.

    recorderPause()\n
    "},{"location":"qsl4a/hardware/camera/#recorderresume","title":"recorderResume()","text":"

    Resume recording.

    recorderResume()\n
    "},{"location":"qsl4a/hardware/camera/#audio-volume-detection","title":"Audio Volume Detection","text":""},{"location":"qsl4a/hardware/camera/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

    Start volume detection.

    recorderSoundVolumeDetect(interval=100)\n
    "},{"location":"qsl4a/hardware/camera/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

    Get current volume in dB.

    recorderSoundVolumeGetDb()\n
    "},{"location":"qsl4a/hardware/camera/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Take photo with default camera\nphoto_path = droid.takePicture(\"/sdcard/photo.jpg\").result\nprint(f\"Photo saved: {photo_path}\")\n\n# Take photo with front camera and auto focus\ncamera_path = droid.cameraCapturePicture(\"/sdcard/selfie.jpg\", cameraId=1, useAutoFocus=True).result\nprint(f\"Front camera photo: {camera_path}\")\n\n# Control flashlight\ndroid.cameraSetTorchMode(True)  # Turn on flashlight\n\n# Record video with default settings\nvideo_path = droid.takeVideo(\"/sdcard/video.mp4\", quality=3).result\nprint(f\"Video saved: {video_path}\")\n\n# Record video with advanced controls\nvideo_path = droid.recorderCaptureVideo(\"/sdcard/movie.mp4\", duration=30, cameraId=0, quality=8).result\n\n# Screenshot\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n
    "},{"location":"qsl4a/hardware/recorder/","title":"Audio Recorder API","text":"

    Record audio from microphone and device screen.

    "},{"location":"qsl4a/hardware/recorder/#audio-recording","title":"Audio Recording","text":""},{"location":"qsl4a/hardware/recorder/#recordaudio","title":"recordAudio()","text":"

    Record audio from microphone.

    recordAudio()\n

    Returns: Path to recorded audio file

    "},{"location":"qsl4a/hardware/recorder/#recorderstartmicrophone","title":"recorderStartMicrophone()","text":"

    Start recording from microphone to a specific file.

    recorderStartMicrophone(targetPath=None)\n

    Parameters: - targetPath (str, optional): Path to save the recording

    "},{"location":"qsl4a/hardware/recorder/#screen-recording","title":"Screen Recording","text":""},{"location":"qsl4a/hardware/recorder/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

    Start screen recording with audio.

    recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

    Parameters: - path (str): Save path for video file - audio (int): Audio source (0=none, 1=mic, 2=internal audio) - targetPixels (int): Target resolution in pixels - frameRate (int): Frames per second (default: 30) - bitRate (int): Video bitrate - rotation (bool): Rotate output video - autoStart (bool): Start recording immediately

    Returns: Result of operation

    "},{"location":"qsl4a/hardware/recorder/#recorderstart","title":"recorderStart()","text":"

    Start the screen recording (when autoStart=False).

    recorderStart()\n
    "},{"location":"qsl4a/hardware/recorder/#recorderpause","title":"recorderPause()","text":"

    Pause ongoing screen recording.

    recorderPause()\n
    "},{"location":"qsl4a/hardware/recorder/#recorderresume","title":"recorderResume()","text":"

    Resume paused screen recording.

    recorderResume()\n
    "},{"location":"qsl4a/hardware/recorder/#audio-volume-detection","title":"Audio Volume Detection","text":""},{"location":"qsl4a/hardware/recorder/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

    Start monitoring sound volume level.

    recorderSoundVolumeDetect(interval=100)\n

    Parameters: - interval (int): Detection interval in milliseconds (default: 100)

    "},{"location":"qsl4a/hardware/recorder/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

    Get current sound volume in decibels.

    recorderSoundVolumeGetDb()\n

    Returns: Current volume level in dB

    "},{"location":"qsl4a/hardware/recorder/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Record audio from microphone\nprint(\"Recording audio...\")\naudio_path = droid.recordAudio().result\nprint(f\"Saved to: {audio_path}\")\n\n# Record microphone to specific file\ndroid.recorderStartMicrophone(\"/sdcard/my_recording.mp3\")\ntime.sleep(5)\ndroid.recorderStop()\n\n# Record screen with audio\nprint(\"Starting screen recording...\")\ndroid.recorderStartScreenRecord(\n    path=\"/sdcard/screen_record.mp4\",\n    audio=1,\n    frameRate=30,\n    autoStart=True\n)\ntime.sleep(10)\ndroid.recorderStop()\n\n# Monitor sound volume\ndroid.recorderSoundVolumeDetect(interval=100)\ntime.sleep(3)\nvolume = droid.recorderSoundVolumeGetDb().result\nprint(f\"Current volume: {volume} dB\")\n
    "},{"location":"qsl4a/hardware/usbserial/","title":"USB Host Serial API","text":"

    Communicate with USB serial devices (requires USB OTG support and Android 3.1+).

    "},{"location":"qsl4a/hardware/usbserial/#usb-serial-methods","title":"USB Serial Methods)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialopen","title":"usbHostSerialOpen()","text":"

    Open a connection to a USB serial device.

    usbHostSerialOpen(device, baudRate=9600)\n

    Parameters: - device (str): USB device path or identifier - baudRate (int): Baud rate (default: 9600)

    Returns: True if opened successfully

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialclose","title":"usbHostSerialClose()","text":"

    Close the USB serial connection.

    usbHostSerialClose()\n
    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialread","title":"usbHostSerialRead()","text":"

    Read data from USB serial.

    usbHostSerialRead(bufferSize=1024)\n

    Parameters: - bufferSize (int): Maximum bytes to read (default: 1024)

    Returns: String read data

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwrite","title":"usbHostSerialWrite()","text":"

    Write data to USB serial.

    usbHostSerialWrite(data)\n

    Parameters: - data (str): String data to write

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialavailable","title":"usbHostSerialAvailable()","text":"

    Check if data is available to read.

    usbHostSerialAvailable()\n

    Returns: Number of bytes available

    "},{"location":"qsl4a/hardware/usbserial/#configuration-methods","title":"Configuration Methods)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetbaudrate","title":"usbHostSerialSetBaudRate()","text":"

    Set the baud rate.

    usbHostSerialSetBaudRate(baudRate)\n

    Parameters: - baudRate (int): Baud rate

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetdatabits","title":"usbHostSerialSetDataBits()","text":"

    Set data bits (5, 6, 7, or 8).

    usbHostSerialSetDataBits(dataBits)\n

    Parameters: - dataBits (int): Data bits (5-8)

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetstopbits","title":"usbHostSerialSetStopBits()","text":"

    Set stop bits (1, 1.5, or 2).

    usbHostSerialSetStopBits(stopBits)\n

    Parameters: - stopBits (float): Stop bits (1, 1.5, or 2)

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetparity","title":"usbHostSerialSetParity()","text":"

    Set parity (none, odd, even, mark, space).

    usbHostSerialSetParity(parity)\n

    Parameters: - parity (str): Parity mode ('none', 'odd', 'even', 'mark', 'space')

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetflowcontrol","title":"usbHostSerialSetFlowControl()","text":"

    Set flow control (none, hardware, software).

    usbHostSerialSetFlowControl(flowControl)\n

    Parameters: - flowControl (str): Flow control mode ('none', 'hardware', 'software')

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialreadhex","title":"usbHostSerialReadHex()","text":"

    Read data as hex string.

    usbHostSerialReadHex(bufferSize=1024)\n

    Parameters: - bufferSize (int): Maximum bytes to read

    Returns: Hex string

    "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwritehex","title":"usbHostSerialWriteHex()","text":"

    Write data from hex string.

    usbHostSerialWriteHex(hexString)\n

    Parameters: - hexString (str): Hex string to write

    "},{"location":"qsl4a/hardware/usbserial/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Open USB serial connection\nif droid.usbHostSerialOpen(\"/dev/bus/usb/001/001\", 115200).result:\n    print(\"USB serial opened\")\n\n    # Write data\n    droid.usbHostSerialWrite(\"AT\\r\")\n\n    # Read response\n    response = droid.usbHostSerialRead(1024).result\n    print(f\"Response: {response}\")\n\n    # Or use hex\n    droid.usbHostSerialWriteHex(\"41540D0A\")  # \"AT\\r\\n\"\n\n    # Close connection\n    droid.usbHostSerialClose()\n

    Note: USB serial requires: - Android 3.1+ (API 12) - USB OTG cable/adapter - USB host mode support on device - Compatible serial device

    "},{"location":"qsl4a/hardware/webcam/","title":"Webcam API","text":"

    Stream video from the device camera using MJPEG.

    "},{"location":"qsl4a/hardware/webcam/#mjpeg-stream-methods","title":"MJPEG Stream Methods","text":""},{"location":"qsl4a/hardware/webcam/#webcamstart","title":"webcamStart()","text":"

    Start an MJPEG stream from the webcam.

    webcamStart(resolutionLevel=0, jpegQuality=20, port=0)\n

    Parameters: - resolutionLevel (int): Resolution level (default: 0) - jpegQuality (int): JPEG quality 1-100 (default: 20) - port (int): Port number (default: 0 = auto)

    Returns: Tuple of (address, port) for the stream

    "},{"location":"qsl4a/hardware/webcam/#webcamadjustquality","title":"webcamAdjustQuality()","text":"

    Adjust the quality of an active webcam stream.

    webcamAdjustQuality(resolutionLevel=0, jpegQuality=20)\n

    Parameters: - resolutionLevel (int): Resolution level - jpegQuality (int): JPEG quality 1-100

    "},{"location":"qsl4a/hardware/webcam/#webcamstop","title":"webcamStop()","text":"

    Stop the webcam stream.

    webcamStop()\n
    "},{"location":"qsl4a/hardware/webcam/#camera-preview-methods","title":"Camera Preview Methods","text":""},{"location":"qsl4a/hardware/webcam/#camerastartpreview","title":"cameraStartPreview()","text":"

    Start camera preview mode with event generation.

    cameraStartPreview(resolutionLevel=0, jpegQuality=20, filepath=None)\n

    Parameters: - resolutionLevel (int): Resolution level (default: 0) - jpegQuality (int): JPEG quality (default: 20) - filepath (str, optional): File path to save preview frames

    Returns: True if successful

    Note: Generates 'preview' events with frame data.

    "},{"location":"qsl4a/hardware/webcam/#camerastoppreview","title":"cameraStopPreview()","text":"

    Stop the camera preview.

    cameraStopPreview()\n
    "},{"location":"qsl4a/hardware/webcam/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start webcam stream\nstream_info = droid.webcamStart(\n    resolutionLevel=0,\n    jpegQuality=30,\n    port=8080\n).result\nprint(f\"Stream available at {stream_info[0]}:{stream_info[1]}\")\n\n# Adjust quality while streaming\ntime.sleep(5)\ndroid.webcamAdjustQuality(resolutionLevel=1, jpegQuality=50)\n\n# Stop when done\ndroid.webcamStop()\n\n# Or use preview mode\nprint(\"Starting preview...\")\ndroid.cameraStartPreview()\n\n# Wait for preview events\nfor i in range(10):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'preview':\n        print(f\"Got preview frame: {event['data']}\")\n\ndroid.cameraStopPreview()\n
    "},{"location":"qsl4a/media/image/","title":"Image Processing API","text":"

    Compress and process images.

    "},{"location":"qsl4a/media/image/#image-compression","title":"Image Compression","text":""},{"location":"qsl4a/media/image/#imagecompress","title":"imageCompress()","text":"

    Compress image file.

    imageCompress(srcPath, destPath, targetByteSize=0, targetWidth=0, targetHeight=0)\n

    Parameters: - srcPath (str): Source image path - destPath (str): Output path - targetByteSize (int): Target file size in bytes (0 = no limit) - targetWidth (int): Target width (0 = original) - targetHeight (int): Target height (0 = original)

    Returns: Compressed image path

    "},{"location":"qsl4a/media/image/#screenshot","title":"Screenshot","text":""},{"location":"qsl4a/media/image/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

    Capture screen.

    imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

    Parameters: - path (str): Save path - delayMilliSec (int): Delay before capture

    Returns: Screenshot path

    "},{"location":"qsl4a/media/image/#video-playback","title":"Video Playback","text":""},{"location":"qsl4a/media/image/#videoplay","title":"videoPlay()","text":"

    Play video file in fullscreen mode.

    videoPlay(path, wait=True)\n

    Parameters: - path (str): Video file path - wait (bool): Wait for playback to complete (default: True)

    "},{"location":"qsl4a/media/image/#barcode-scanning","title":"Barcode Scanning","text":""},{"location":"qsl4a/media/image/#scanbarcodefromimage","title":"scanBarcodeFromImage()","text":"

    Scan barcode/QR code from image file.

    scanBarcodeFromImage(path, compressRatio=0, x=0, y=0, width=0, height=0)\n

    Parameters: - path (str): Image file path - compressRatio (int): Compression ratio (0 = no compression) - x, y, width, height (int): Region to scan (0 = full image)

    Returns: Scanned barcode content

    "},{"location":"qsl4a/media/image/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Take screenshot\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n\n# Compress image\ncompressed = droid.imageCompress(\n    \"/sdcard/large_photo.jpg\",\n    \"/sdcard/compressed.jpg\",\n    targetByteSize=102400,  # Target ~100KB\n    targetWidth=1920,\n    targetHeight=1080\n).result\nprint(f\"Saved: {compressed}\")\n\n# Play video\nvideo_path = \"/sdcard/movie.mp4\"\ndroid.videoPlay(video_path, wait=True)\n\n# Scan barcode from image\nresult = droid.scanBarcodeFromImage(\"/sdcard/qr_code.png\").result\nprint(f\"Barcode: {result}\")\n
    "},{"location":"qsl4a/media/mediaplayer/","title":"Media Player API","text":"

    Control audio and video playback.

    "},{"location":"qsl4a/media/mediaplayer/#playback-control","title":"Playback Control","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplay","title":"mediaPlay()","text":"

    Play media file.

    mediaPlay(url, tag=\"default\", play=True)\n

    Parameters: - url (str): Media file path or URL - tag (str): Player identifier - play (bool): Auto-start playback

    "},{"location":"qsl4a/media/mediaplayer/#mediaplaystart","title":"mediaPlayStart()","text":"

    Start playback.

    mediaPlayStart(tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#mediaplaypause","title":"mediaPlayPause()","text":"

    Pause playback.

    mediaPlayPause(tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#mediaplayclose","title":"mediaPlayClose()","text":"

    Close player.

    mediaPlayClose(tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#mediaplayseek","title":"mediaPlaySeek()","text":"

    Seek to position.

    mediaPlaySeek(msec, tag=\"default\")\n

    Parameters: - msec (int): Position in milliseconds

    "},{"location":"qsl4a/media/mediaplayer/#mediaplaysetlooping","title":"mediaPlaySetLooping()","text":"

    Set loop mode.

    mediaPlaySetLooping(enabled, tag=\"default\")\n
    "},{"location":"qsl4a/media/mediaplayer/#player-info","title":"Player Info","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplayinfo","title":"mediaPlayInfo()","text":"

    Get playback info.

    mediaPlayInfo(tag=\"default\")\n

    Returns: Dict with duration, position, etc.

    "},{"location":"qsl4a/media/mediaplayer/#mediaisplaying","title":"mediaIsPlaying()","text":"

    Check if playing.

    mediaIsPlaying(tag=\"default\")\n

    Returns: True/False

    "},{"location":"qsl4a/media/mediaplayer/#mediaplaylist","title":"mediaPlayList()","text":"

    List active players.

    mediaPlayList()\n
    "},{"location":"qsl4a/media/mediaplayer/#volume-control","title":"Volume Control","text":""},{"location":"qsl4a/media/mediaplayer/#getmediavolume","title":"getMediaVolume()","text":"

    Get media volume.

    getMediaVolume()\n

    Returns: Volume level (0-15)

    "},{"location":"qsl4a/media/mediaplayer/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

    Get max media volume.

    getMaxMediaVolume()\n
    "},{"location":"qsl4a/media/mediaplayer/#getringervolume","title":"getRingerVolume()","text":"

    Get ringer volume.

    getRingerVolume()\n
    "},{"location":"qsl4a/media/mediaplayer/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

    Get max ringer volume.

    getMaxRingerVolume()\n
    "},{"location":"qsl4a/media/mediaplayer/#video-playback","title":"Video Playback","text":""},{"location":"qsl4a/media/mediaplayer/#videoplay","title":"videoPlay()","text":"

    Play video fullscreen.

    videoPlay(path, wait=True)\n

    Parameters: - path (str): Video file path - wait (bool): Wait for playback to complete

    "},{"location":"qsl4a/media/mediaplayer/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Play audio\ndroid.mediaPlay(\"/sdcard/music.mp3\", tag=\"music\")\n\n# Check status\nif droid.mediaIsPlaying(\"music\").result:\n    info = droid.mediaPlayInfo(\"music\").result\n    print(f\"Playing: {info}\")\n\n# Seek to 30 seconds\ndroid.mediaPlaySeek(30000, \"music\")\n\n# Close\ndroid.mediaPlayClose(\"music\")\n\n# Play video\ndroid.videoPlay(\"/sdcard/movie.mp4\", wait=True)\n
    "},{"location":"qsl4a/special/cipher/","title":"Cipher API","text":"

    Encryption and decryption utilities for secure data storage.

    "},{"location":"qsl4a/special/cipher/#initialization","title":"Initialization","text":""},{"location":"qsl4a/special/cipher/#cipherinit","title":"cipherInit()","text":"

    Initialize the cipher with encryption key and algorithm.

    cipherInit(key, algorithm=\"AES/CBC/PKCS5Padding\", encodingFormat=\"\", initialVector=\"\")\n

    Parameters: - key (str or bytes): Encryption key - algorithm (str): Cipher algorithm (default: \"AES/CBC/PKCS5Padding\") - encodingFormat (str): Encoding format - initialVector (str or bytes): Initial vector for encryption

    Returns: Initialization result

    Note: Must be called before any encrypt/decrypt operations.

    "},{"location":"qsl4a/special/cipher/#encryption-methods","title":"Encryption Methods","text":""},{"location":"qsl4a/special/cipher/#encryptstring","title":"encryptString()","text":"

    Encrypt a string.

    encryptString(plainText)\n

    Parameters: - plainText (str): Text to encrypt

    Returns: Encrypted string

    "},{"location":"qsl4a/special/cipher/#encryptbytes","title":"encryptBytes()","text":"

    Encrypt bytes data.

    encryptBytes(data)\n

    Parameters: - data (bytes): Data to encrypt

    Returns: Encrypted bytes

    "},{"location":"qsl4a/special/cipher/#encryptstringtofile","title":"encryptStringToFile()","text":"

    Encrypt string to file.

    encryptStringToFile(plainText, filePath)\n

    Parameters: - plainText (str): Text to encrypt - filePath (str): Output file path

    "},{"location":"qsl4a/special/cipher/#encryptbytestofile","title":"encryptBytesToFile()","text":"

    Encrypt bytes to file.

    encryptBytesToFile(data, filePath)\n
    "},{"location":"qsl4a/special/cipher/#decryption-methods","title":"Decryption Methods","text":""},{"location":"qsl4a/special/cipher/#decryptstring","title":"decryptString()","text":"

    Decrypt to string.

    decryptString(cipherText)\n

    Parameters: - cipherText (str): Encrypted text

    Returns: Decrypted string

    "},{"location":"qsl4a/special/cipher/#decryptbytes","title":"decryptBytes()","text":"

    Decrypt to bytes.

    decryptBytes(data)\n

    Returns: Decrypted bytes

    "},{"location":"qsl4a/special/cipher/#decryptfiletostring","title":"decryptFileToString()","text":"

    Decrypt file to string.

    decryptFileToString(filePath)\n
    "},{"location":"qsl4a/special/cipher/#decryptfiletobytes","title":"decryptFileToBytes()","text":"

    Decrypt file to bytes.

    decryptFileToBytes(filePath)\n
    "},{"location":"qsl4a/special/cipher/#decryptfile","title":"decryptFile()","text":"

    Decrypt file to file.

    decryptFile(srcPath, destPath)\n
    "},{"location":"qsl4a/special/cipher/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Initialize cipher with your encryption key\ndroid.cipherInit(\"my_secret_key_1234\")\n\n# Encrypt string\nencrypted = droid.encryptString(\"Secret message!\").result\nprint(f\"Encrypted: {encrypted}\")\n\n# Decrypt string\ndecrypted = droid.decryptString(encrypted).result\nprint(f\"Decrypted: {decrypted}\")\n\n# Encrypt to file\ndroid.encryptStringToFile(\"My secret data\", \"/sdcard/secret.dat\")\n\n# Decrypt from file\ndata = droid.decryptFileToString(\"/sdcard/secret.dat\").result\nprint(data)\n\n# Initialize with custom algorithm and IV\ndroid.cipherInit(\n    key=\"my_key\",\n    algorithm=\"AES/CBC/PKCS5Padding\",\n    initialVector=\"0123456789abcdef\"\n)\n
    "},{"location":"qsl4a/special/pgptai/","title":"PGPT AI API","text":"

    Speech-to-text and AI services integration.

    "},{"location":"qsl4a/special/pgptai/#prerequisites","title":"Prerequisites","text":"
    pip install pgptAI\n
    "},{"location":"qsl4a/special/pgptai/#speech-recognition","title":"Speech Recognition","text":""},{"location":"qsl4a/special/pgptai/#speechtotext","title":"speechToText()","text":"

    Convert speech to text.

    speechToText(RecordSecond=10, AmrFile=None, Language=None)\n

    Parameters: - RecordSecond (int): Recording duration in seconds - AmrFile (str, optional): Existing audio file path - Language (str, optional): Language code ('en', 'zh')

    Returns: Transcribed text

    "},{"location":"qsl4a/special/pgptai/#text-to-speech","title":"Text to Speech","text":""},{"location":"qsl4a/special/pgptai/#texttospeech","title":"textToSpeech()","text":"

    Convert text to speech and optionally play it.

    textToSpeech(Text, AutoPlay=True, WavFile=None, VoiceName=None)\n

    Parameters: - Text (str): Text to convert to speech - AutoPlay (bool): Automatically play the generated audio (default: True) - WavFile (str, optional): Path to save the WAV file. If None, uses temporary file - VoiceName (str, optional): Voice name to use (e.g., 'en-US-JennyNeural', 'zh-CN-XiaoxiaoNeural')

    Returns: Dict with speech synthesis result including: - text: The input text - url: URL to download the audio file - WavFile: Path to the saved WAV file (if saved locally)

    "},{"location":"qsl4a/special/pgptai/#configuration","title":"Configuration","text":"

    The API uses configuration from /storage/emulated/0/Android/data/org.qpython.qpy/files/apigpt.conf:

    [speech]\nspeech_key = your_api_key\n

    Default voice settings: - English: en-US-JennyNeural - Chinese: zh-CN-XiaoxiaoNeural

    "},{"location":"qsl4a/special/pgptai/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Record and transcribe\nprint(\"Recording for 5 seconds...\")\ntext = droid.speechToText(RecordSecond=5, Language='en').result\nprint(f\"You said: {text}\")\n\n# Transcribe existing file\ntext = droid.speechToText(AmrFile=\"/sdcard/recording.amr\").result\nprint(f\"Transcription: {text}\")\n\n# Text to speech\ndroid.textToSpeech(\"Hello, this is a test message.\", AutoPlay=True, Language='en')\n\n# Text to speech with custom voice and save to file\nresult = droid.textToSpeech(\n    \"Welcome to QPython!\",\n    AutoPlay=False,\n    WavFile=\"/sdcard/welcome.wav\",\n    VoiceName=\"en-US-JennyNeural\"\n).result\nprint(f\"Audio saved to: {result.get('WavFile')}\")\n
    "},{"location":"qsl4a/special/pgptai/#class-usage","title":"Class Usage","text":"
    from androidhelper.pgptai import pgptai\nimport androidhelper\n\ndroid = androidhelper.Android()\nai = pgptai(droid)\n\n# Use speech recognition\ntext = ai.speechToText(RecordSecond=10)\n
    "},{"location":"qsl4a/storage/clipboard/","title":"Clipboard API","text":"

    Copy and paste text to system clipboard.

    "},{"location":"qsl4a/storage/clipboard/#methods","title":"Methods","text":""},{"location":"qsl4a/storage/clipboard/#setclipboard","title":"setClipboard()","text":"

    Copy text to clipboard.

    setClipboard(text)\n

    Parameters: - text (str): Text to copy

    Returns: True if success

    "},{"location":"qsl4a/storage/clipboard/#getclipboard","title":"getClipboard()","text":"

    Get text from clipboard.

    getClipboard()\n

    Returns: Clipboard text

    "},{"location":"qsl4a/storage/clipboard/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Copy to clipboard\ndroid.setClipboard(\"Hello from QPython!\")\n\n# Paste from clipboard\ntext = droid.getClipboard().result\nprint(f\"Clipboard: {text}\")\n
    "},{"location":"qsl4a/storage/documentfile/","title":"DocumentFile API","text":"

    File operations with SAF (Storage Access Framework) support for Android 4.4+.

    "},{"location":"qsl4a/storage/documentfile/#directory-operations","title":"Directory Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfilemkdir","title":"documentFileMkdir()","text":"

    Create directory.

    documentFileMkdir(Dir)\n

    Parameters: - Dir (str): Directory path

    Returns: True if success

    "},{"location":"qsl4a/storage/documentfile/#documentfilelistfiles","title":"documentFileListFiles()","text":"

    List files in directory.

    documentFileListFiles(Folder)\n

    Returns: List of files

    "},{"location":"qsl4a/storage/documentfile/#file-operations","title":"File Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfileexists","title":"documentFileExists()","text":"

    Check if file or directory exists.

    documentFileExists(path)\n

    Parameters: - path (str): File or directory path

    Returns: True if exists, False otherwise

    "},{"location":"qsl4a/storage/documentfile/#documentfileisfile","title":"documentFileIsFile()","text":"

    Check if path is a file.

    documentFileIsFile(path)\n

    Parameters: - path (str): Path to check

    Returns: True if file, False if not a file, None if not exists

    "},{"location":"qsl4a/storage/documentfile/#documentfileisdirectory","title":"documentFileIsDirectory()","text":"

    Check if path is a directory.

    documentFileIsDirectory(path)\n

    Parameters: - path (str): Path to check

    Returns: True if directory, False if not a directory, None if not exists

    "},{"location":"qsl4a/storage/documentfile/#documentfiledelete","title":"documentFileDelete()","text":"

    Delete file or directory.

    documentFileDelete(FileOrTree)\n

    Returns: True if success

    "},{"location":"qsl4a/storage/documentfile/#documentfilerenameto","title":"documentFileRenameTo()","text":"

    Rename or move file.

    documentFileRenameTo(Src, Dest)\n

    Returns: True if success

    "},{"location":"qsl4a/storage/documentfile/#documentfilecopy","title":"documentFileCopy()","text":"

    Copy file.

    documentFileCopy(SrcFileOrTree, DestFileOrTree)\n
    "},{"location":"qsl4a/storage/documentfile/#stream-operations","title":"Stream Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfileinputstream","title":"documentFileInputStream()","text":"

    Read file content.

    documentFileInputStream(srcFile, EncodingFormat=\"\", skip=None, length=None)\n

    Parameters: - srcFile (str): Source file - EncodingFormat (str): \"UTF-8\", \"GBK\", \"Base64\", or \"\" for bytes - skip (int): Skip bytes from start - length (int): Read length

    Returns: File content

    "},{"location":"qsl4a/storage/documentfile/#documentfileoutputstream","title":"documentFileOutputStream()","text":"

    Write file content.

    documentFileOutputStream(destFile, src, EncodingFormat=\"\", append=None)\n

    Parameters: - destFile (str): Destination file - src: Data to write - EncodingFormat (str): Encoding format - append (bool): Append mode

    "},{"location":"qsl4a/storage/documentfile/#file-information","title":"File Information","text":""},{"location":"qsl4a/storage/documentfile/#documentfilelength","title":"documentFileLength()","text":"

    Get file size in bytes.

    documentFileLength(path)\n

    Parameters: - path (str): File path

    Returns: File size in bytes (0 if not exists)

    "},{"location":"qsl4a/storage/documentfile/#documentfilelastmodified","title":"documentFileLastModified()","text":"

    Get last modified time.

    documentFileLastModified(path)\n

    Parameters: - path (str): File path

    Returns: Timestamp (0 if not exists)

    "},{"location":"qsl4a/storage/documentfile/#documentfilegetstat","title":"documentFileGetStat()","text":"

    Get comprehensive file statistics.

    documentFileGetStat(path)\n

    Parameters: - path (str): File path

    Returns: Dict with length, last modified, and read/write permissions, or None if not exists

    "},{"location":"qsl4a/storage/documentfile/#uri-operations","title":"URI Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfilegeturi","title":"documentFileGetUri()","text":"

    Get URI from path.

    documentFileGetUri(path, isDirectory=None)\n
    "},{"location":"qsl4a/storage/documentfile/#documentfileshowopen","title":"documentFileShowOpen()","text":"

    Show file picker.

    documentFileShowOpen()\n

    Returns: Selected file URI

    "},{"location":"qsl4a/storage/documentfile/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Create directory\ndroid.documentFileMkdir(\"/sdcard/MyFolder\")\n\n# List files\nfiles = droid.documentFileListFiles(\"/sdcard\").result\nfor f in files:\n    print(f)\n\n# Read file\ncontent = droid.documentFileInputStream(\n    \"/sdcard/test.txt\",\n    EncodingFormat=\"UTF-8\"\n).result\nprint(content)\n\n# Write file\ndroid.documentFileOutputStream(\n    \"/sdcard/output.txt\",\n    \"Hello World\",\n    EncodingFormat=\"UTF-8\"\n)\n
    "},{"location":"qsl4a/storage/preferences/","title":"Preferences API","text":"

    Store and retrieve data using Android SharedPreferences.

    "},{"location":"qsl4a/storage/preferences/#preference-methods","title":"Preference Methods","text":""},{"location":"qsl4a/storage/preferences/#prefgetvalue","title":"prefGetValue()","text":"

    Read a value from shared preferences.

    prefGetValue(key, filename=None)\n

    Parameters: - key (str): Preference key - filename (str, optional): Preference file name

    Returns: The stored value (any type)

    "},{"location":"qsl4a/storage/preferences/#prefputvalue","title":"prefPutValue()","text":"

    Write a value to shared preferences.

    prefPutValue(key, value, filename=None)\n

    Parameters: - key (str): Preference key - value (object): Value to store - filename (str, optional): Preference file name

    "},{"location":"qsl4a/storage/preferences/#prefgetall","title":"prefGetAll()","text":"

    Get all preference values.

    prefGetAll(filename=None)\n

    Parameters: - filename (str, optional): Preference file name

    Returns: Map of all preferences

    "},{"location":"qsl4a/storage/preferences/#prefremovevalue","title":"prefRemoveValue()","text":"

    Remove a value from shared preferences.

    prefRemoveValue(key, filename=None)\n

    Parameters: - key (str): Preference key to remove - filename (str, optional): Preference file name

    "},{"location":"qsl4a/storage/preferences/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Store values\ndroid.prefPutValue(\"username\", \"alice\")\ndroid.prefPutValue(\"score\", 100)\ndroid.prefPutValue(\"enabled\", True)\n\n# Read a specific value\nusername = droid.prefGetValue(\"username\").result\nprint(f\"Username: {username}\")\n\n# Get all preferences\nall_prefs = droid.prefGetAll().result\nprint(f\"All prefs: {all_prefs}\")\n\n# Remove a value\ndroid.prefRemoveValue(\"score\")\n\n# Use custom filename\ndroid.prefPutValue(\"token\", \"abc123\", filename=\"auth.prefs\")\ntoken = droid.prefGetValue(\"token\", filename=\"auth.prefs\").result\n
    "},{"location":"qsl4a/system/activityresult/","title":"Activity Result API","text":"

    Set activity results for scripts launched via startActivityForResult.

    "},{"location":"qsl4a/system/activityresult/#result-methods","title":"Result Methods","text":""},{"location":"qsl4a/system/activityresult/#setresultboolean","title":"setResultBoolean()","text":"

    Set a boolean result.

    setResultBoolean(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (bool): Boolean result value

    "},{"location":"qsl4a/system/activityresult/#setresultbyte","title":"setResultByte()","text":"

    Set a byte result.

    setResultByte(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (int): Byte result value

    "},{"location":"qsl4a/system/activityresult/#setresultshort","title":"setResultShort()","text":"

    Set a short result.

    setResultShort(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (int): Short result value

    "},{"location":"qsl4a/system/activityresult/#setresultchar","title":"setResultChar()","text":"

    Set a character result.

    setResultChar(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (str): Character result value

    "},{"location":"qsl4a/system/activityresult/#setresultinteger","title":"setResultInteger()","text":"

    Set an integer result.

    setResultInteger(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (int): Integer result value

    "},{"location":"qsl4a/system/activityresult/#setresultlong","title":"setResultLong()","text":"

    Set a long result.

    setResultLong(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (int): Long result value

    "},{"location":"qsl4a/system/activityresult/#setresultfloat","title":"setResultFloat()","text":"

    Set a float result.

    setResultFloat(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (float): Float result value

    "},{"location":"qsl4a/system/activityresult/#setresultdouble","title":"setResultDouble()","text":"

    Set a double result.

    setResultDouble(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (float): Double result value

    "},{"location":"qsl4a/system/activityresult/#setresultstring","title":"setResultString()","text":"

    Set a string result.

    setResultString(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (str): String result value

    "},{"location":"qsl4a/system/activityresult/#setresultbooleanarray","title":"setResultBooleanArray()","text":"

    Set a boolean array result.

    setResultBooleanArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Boolean array

    "},{"location":"qsl4a/system/activityresult/#setresultbytearray","title":"setResultByteArray()","text":"

    Set a byte array result.

    setResultByteArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Byte array

    "},{"location":"qsl4a/system/activityresult/#setresultshortarray","title":"setResultShortArray()","text":"

    Set a short array result.

    setResultShortArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Short array

    "},{"location":"qsl4a/system/activityresult/#setresultchararray","title":"setResultCharArray()","text":"

    Set a character array result.

    setResultCharArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Char array

    "},{"location":"qsl4a/system/activityresult/#setresultintegerarray","title":"setResultIntegerArray()","text":"

    Set an integer array result.

    setResultIntegerArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Integer array

    "},{"location":"qsl4a/system/activityresult/#setresultlongarray","title":"setResultLongArray()","text":"

    Set a long array result.

    setResultLongArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Long array

    "},{"location":"qsl4a/system/activityresult/#setresultfloatarray","title":"setResultFloatArray()","text":"

    Set a float array result.

    setResultFloatArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Float array

    "},{"location":"qsl4a/system/activityresult/#setresultdoublearray","title":"setResultDoubleArray()","text":"

    Set a double array result.

    setResultDoubleArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): Double array

    "},{"location":"qsl4a/system/activityresult/#setresultstringarray","title":"setResultStringArray()","text":"

    Set a string array result.

    setResultStringArray(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue (list): String array

    "},{"location":"qsl4a/system/activityresult/#setresultserializable","title":"setResultSerializable()","text":"

    Set a serializable result.

    setResultSerializable(resultCode, resultValue)\n

    Parameters: - resultCode (int): Result code - resultValue: Serializable result value

    "},{"location":"qsl4a/system/activityresult/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# After performing an activity, set the result\n# Example: Return success with data\ndroid.setResultInteger(0, 200)  # RESULT_OK\ndroid.setResultString(0, \"Operation completed successfully\")\n\n# Return an array result\ndroid.setResultIntegerArray(0, [1, 2, 3, 4, 5])\n
    "},{"location":"qsl4a/system/application/","title":"Application Management","text":"

    Manage applications, launch apps, and query system information.

    "},{"location":"qsl4a/system/application/#application-information","title":"Application Information","text":""},{"location":"qsl4a/system/application/#getapplicationinfo","title":"getApplicationInfo()","text":"

    Get information about an app.

    getApplicationInfo(packageName=None)\n

    Parameters: - packageName (str): Package name (None = current app)

    Returns: App info dict

    "},{"location":"qsl4a/system/application/#getinstalledpackages","title":"getInstalledPackages()","text":"

    Get list of installed packages.

    getInstalledPackages(flag=4)\n

    Parameters: - flag (int): Package flag filter (default: 4)

    Returns: List of installed packages

    "},{"location":"qsl4a/system/application/#getrunningpackages","title":"getRunningPackages()","text":"

    List running packages.

    getRunningPackages()\n

    Returns: List of package names

    "},{"location":"qsl4a/system/application/#getlaunchablepackages","title":"getLaunchablePackages()","text":"

    Get list of launchable packages.

    getLaunchablePackages(needClassName=False)\n

    Parameters: - needClassName (bool): Include main activity class name (default: False)

    Returns: List of launchable package names or dict with class names

    "},{"location":"qsl4a/system/application/#application-control","title":"Application Control","text":""},{"location":"qsl4a/system/application/#launch","title":"launch()","text":"

    Launch an application.

    launch(classname=None, packagename=None, wait=True)\n

    Parameters: - classname (str): Main activity class name - packagename (str): Package name - wait (bool): Wait for launch to complete (default: True)

    Returns: Launch result

    "},{"location":"qsl4a/system/application/#forcestoppackage","title":"forceStopPackage()","text":"

    Force stop an application.

    forceStopPackage(packageName)\n

    Parameters: - packageName (str): Package name to stop

    "},{"location":"qsl4a/system/application/#version-information","title":"Version Information","text":""},{"location":"qsl4a/system/application/#getpackageversion","title":"getPackageVersion()","text":"

    Get app version name.

    getPackageVersion(packageName)\n

    Returns: Version string (e.g., \"3.2.1\")

    "},{"location":"qsl4a/system/application/#getpackageversioncode","title":"getPackageVersionCode()","text":"

    Get app version code.

    getPackageVersionCode(packageName)\n

    Returns: Version code integer

    "},{"location":"qsl4a/system/application/#getconstants","title":"getConstants()","text":"

    Get class constants.

    getConstants(classname)\n

    Parameters: - classname (str): Full class name

    Returns: Dict of constant names and values

    "},{"location":"qsl4a/system/application/#system-features","title":"System Features","text":""},{"location":"qsl4a/system/application/#backgroundprotect","title":"backgroundProtect()","text":"

    Enable or disable background protection for the app.

    backgroundProtect(enabled=True)\n

    Parameters: - enabled (bool): True to enable protection, False to disable

    "},{"location":"qsl4a/system/application/#createscriptshortcut","title":"createScriptShortCut()","text":"

    Create a home screen shortcut for a script.

    createScriptShortCut(scriptPath, label=None, iconPath=None, scriptArg=None)\n

    Parameters: - scriptPath (str): Path to the Python script - label (str, optional): Shortcut label - iconPath (str, optional): Path to icon image - scriptArg (str, optional): Argument to pass to script

    "},{"location":"qsl4a/system/application/#device-information","title":"Device Information","text":""},{"location":"qsl4a/system/application/#getandroidid","title":"getAndroidID()","text":"

    Get Android device ID.

    getAndroidID()\n

    Returns: Unique Android device ID string

    "},{"location":"qsl4a/system/application/#getsysinfo","title":"getSysInfo()","text":"

    Get system information.

    getSysInfo()\n

    Returns: Dict with system details

    "},{"location":"qsl4a/system/application/#getlocale","title":"getLocale()","text":"

    Get device locale.

    getLocale()\n

    Returns: Locale string (e.g., \"en_US\")

    "},{"location":"qsl4a/system/application/#getharmonyosinformation","title":"getHarmonyOsInformation()","text":"

    Get HarmonyOS information if running on HarmonyOS.

    getHarmonyOsInformation()\n

    Returns: HarmonyOS version info or None

    "},{"location":"qsl4a/system/application/#isexternalstoragemanager","title":"isExternalStorageManager()","text":"

    Check if app has external storage manager permission.

    isExternalStorageManager()\n

    Returns: True if has permission

    "},{"location":"qsl4a/system/application/#memory-and-display","title":"Memory and Display","text":""},{"location":"qsl4a/system/application/#getmemoryinfo","title":"getMemoryInfo()","text":"

    Get memory information.

    getMemoryInfo()\n

    Returns: Dict with memory stats

    "},{"location":"qsl4a/system/application/#getscreeninfo","title":"getScreenInfo()","text":"

    Get screen information.

    getScreenInfo()\n

    Returns: Dict with width, height, density

    "},{"location":"qsl4a/system/application/#permissions","title":"Permissions","text":""},{"location":"qsl4a/system/application/#checkpermissions","title":"checkPermissions()","text":"

    Check current app permissions.

    checkPermissions()\n

    Returns: Dict of permissions and their status

    "},{"location":"qsl4a/system/application/#requestpermissions","title":"requestPermissions()","text":"

    Request permissions from the user.

    requestPermissions(permissions=None)\n

    Parameters: - permissions (list, optional): List of permissions to request. If None, requests all needed permissions.

    Returns: Result of permission request

    "},{"location":"qsl4a/system/application/#system-actions","title":"System Actions","text":""},{"location":"qsl4a/system/application/#showscreenlock","title":"showScreenLock()","text":"

    Show screen lock (PIN/pattern/password entry).

    showScreenLock()\n
    "},{"location":"qsl4a/system/application/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get system info\ninfo = droid.getSysInfo().result\nprint(f\"System: {info}\")\n\n# Get app version\nversion = droid.getPackageVersion(\"org.qpython.qpy\").result\nprint(f\"QPython version: {version}\")\n\n# List installed apps\napps = droid.getInstalledPackages().result\nprint(f\"Installed apps: {len(apps)}\")\n\n# Launch an app\ndroid.launch(packagename=\"com.android.settings\")\n\n# Check permissions\nperms = droid.checkPermissions().result\nprint(f\"Permissions: {perms}\")\n\n# Request storage permission\ndroid.requestPermissions([\"android.permission.READ_EXTERNAL_STORAGE\"])\n\n# Create shortcut\ndroid.createScriptShortCut(\n    \"/sdcard/my_script.py\",\n    label=\"My Script\",\n    iconPath=\"/sdcard/icon.png\"\n)\n
    "},{"location":"qsl4a/system/battery/","title":"Battery API","text":"

    Monitor device battery status and health.

    "},{"location":"qsl4a/system/battery/#methods","title":"Methods","text":""},{"location":"qsl4a/system/battery/#readbatterydata","title":"readBatteryData()","text":"

    Get complete battery information.

    readBatteryData()\n

    Returns: Dict with battery data

    "},{"location":"qsl4a/system/battery/#batterystartmonitoring","title":"batteryStartMonitoring()","text":"

    Start battery monitoring.

    batteryStartMonitoring()\n
    "},{"location":"qsl4a/system/battery/#batterystopmonitoring","title":"batteryStopMonitoring()","text":"

    Stop battery monitoring.

    batteryStopMonitoring()\n
    "},{"location":"qsl4a/system/battery/#batterygetlevel","title":"batteryGetLevel()","text":"

    Get battery percentage.

    batteryGetLevel()\n

    Returns: Int (0-100)

    "},{"location":"qsl4a/system/battery/#batterygetstatus","title":"batteryGetStatus()","text":"

    Get charging status.

    batteryGetStatus()\n

    Returns: - 1: Unknown - 2: Charging - 3: Discharging - 4: Not charging - 5: Full

    "},{"location":"qsl4a/system/battery/#batterygetplugtype","title":"batteryGetPlugType()","text":"

    Get power source.

    batteryGetPlugType()\n

    Returns: - -1: Unknown - 0: Unplugged - 1: AC charger - 2: USB port

    "},{"location":"qsl4a/system/battery/#batterygethealth","title":"batteryGetHealth()","text":"

    Get battery health.

    batteryGetHealth()\n

    Returns: - 1: Unknown - 2: Good - 3: Overheat - 4: Dead - 5: Over voltage - 6: Unspecified failure

    "},{"location":"qsl4a/system/battery/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get battery level\nlevel = droid.batteryGetLevel().result\nprint(f\"Battery: {level}%\")\n
    "},{"location":"qsl4a/system/qpyinterface/","title":"QPython Interface API","text":"

    Execute QPython scripts and manage shared variables from other apps.

    "},{"location":"qsl4a/system/qpyinterface/#script-execution-methods","title":"Script Execution Methods","text":""},{"location":"qsl4a/system/qpyinterface/#executeqpy","title":"executeQPy()","text":"

    Execute a QPython script.

    executeQPy(path=\"\", arg=None)\n

    Parameters: - path (str): Path to the script file - arg (str, optional): Command line arguments

    Returns: True if started successfully

    "},{"location":"qsl4a/system/qpyinterface/#executeqpyassrv","title":"executeQPyAsSrv()","text":"

    Execute a QPython script as a service.

    executeQPyAsSrv(path=None)\n

    Parameters: - path (str, optional): Path to the script file

    Returns: True if started successfully

    "},{"location":"qsl4a/system/qpyinterface/#executeqpycode","title":"executeQPyCode()","text":"

    Execute Python code directly.

    executeQPyCode(code=None)\n

    Parameters: - code (str, optional): Python code to execute

    Returns: True if started successfully

    "},{"location":"qsl4a/system/qpyinterface/#executeqpycodeassrv","title":"executeQPyCodeAsSrv()","text":"

    Execute Python code as a service.

    executeQPyCodeAsSrv(code=None)\n

    Parameters: - code (str, optional): Python code to execute

    Returns: True if started successfully

    "},{"location":"qsl4a/system/qpyinterface/#shared-variables","title":"Shared Variables","text":"

    Shared variables allow communication between QPython and other apps.

    "},{"location":"qsl4a/system/qpyinterface/#sharedvariableset","title":"sharedVariableSet()","text":"

    Set a Java shared variable.

    sharedVariableSet(key, value)\n

    Parameters: - key (str): Variable name - value (str): Variable value

    Returns: The stored value

    "},{"location":"qsl4a/system/qpyinterface/#sharedvariableget","title":"sharedVariableGet()","text":"

    Get a Java shared variable.

    sharedVariableGet(key)\n

    Parameters: - key (str): Variable name

    Returns: The stored value

    "},{"location":"qsl4a/system/qpyinterface/#sharedvariableremove","title":"sharedVariableRemove()","text":"

    Remove a Java shared variable.

    sharedVariableRemove(key)\n

    Parameters: - key (str): Variable name to remove

    Returns: The removed value

    "},{"location":"qsl4a/system/qpyinterface/#getlastlog","title":"getLastLog()","text":"

    Get the last log output from QPython.

    getLastLog()\n

    Returns: String log content

    "},{"location":"qsl4a/system/qpyinterface/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Execute a script\ndroid.executeQPy(\"/sdcard/my_script.py\", arg=\"test\")\n\n# Execute code directly\ncode = \"print('Hello from QPython!')\"\ndroid.executeQPyCode(code)\n\n# Use shared variables\ndroid.sharedVariableSet(\"username\", \"alice\")\nusername = droid.sharedVariableGet(\"username\").result\nprint(f\"Username: {username}\")\n\n# Remove variable\ndroid.sharedVariableRemove(\"username\")\n\n# Get recent log\nlog = droid.getLastLog().result\nprint(f\"Log: {log}\")\n
    "},{"location":"qsl4a/system/sensors/","title":"Sensor API","text":"

    Access device sensors including accelerometer, gyroscope, magnetometer, and more.

    "},{"location":"qsl4a/system/sensors/#methods","title":"Methods","text":""},{"location":"qsl4a/system/sensors/#startsensingtimed","title":"startSensingTimed()","text":"

    Start sensor monitoring with time intervals.

    startSensingTimed(sensorNumber, delayTime)\n

    Parameters: - sensorNumber (int): Sensor ID (1-3 typically) - delayTime (int): Delay between readings in milliseconds

    "},{"location":"qsl4a/system/sensors/#startsensingthreshold","title":"startSensingThreshold()","text":"

    Start sensor monitoring with threshold trigger.

    startSensingThreshold(sensorNumber, threshold, axis)\n

    Parameters: - sensorNumber (int): Sensor ID - threshold (float): Trigger threshold - axis (int): Axis to monitor (0=X, 1=Y, 2=Z)

    "},{"location":"qsl4a/system/sensors/#stopsensing","title":"stopSensing()","text":"

    Stop all sensor monitoring.

    stopSensing()\n
    "},{"location":"qsl4a/system/sensors/#readsensors","title":"readSensors()","text":"

    Read current sensor data.

    readSensors()\n

    Returns: Sensor data dict

    "},{"location":"qsl4a/system/sensors/#sensorsreadaccelerometer","title":"sensorsReadAccelerometer()","text":"

    Read accelerometer values.

    sensorsReadAccelerometer()\n

    Returns: List [X, Y, Z] in m/s\u00b2

    "},{"location":"qsl4a/system/sensors/#sensorsreadgyroscope","title":"sensorsReadGyroscope()","text":"

    Read gyroscope values.

    sensorsReadGyroscope()\n

    Returns: List [X, Y, Z] in rad/s

    "},{"location":"qsl4a/system/sensors/#sensorsreadmagnetometer","title":"sensorsReadMagnetometer()","text":"

    Read magnetic field values.

    sensorsReadMagnetometer()\n

    Returns: List [X, Y, Z] in \u03bcT

    "},{"location":"qsl4a/system/sensors/#sensorsreadorientation","title":"sensorsReadOrientation()","text":"

    Read device orientation.

    sensorsReadOrientation()\n

    Returns: List [azimuth, pitch, roll] in degrees

    "},{"location":"qsl4a/system/sensors/#sensorsgetlight","title":"sensorsGetLight()","text":"

    Read light sensor value.

    sensorsGetLight()\n

    Returns: Light level in lux

    "},{"location":"qsl4a/system/sensors/#sensorsgetstepcounter","title":"sensorsGetStepCounter()","text":"

    Read step counter.

    sensorsGetStepCounter()\n

    Returns: Number of steps

    "},{"location":"qsl4a/system/sensors/#sensorsgetaccuracy","title":"sensorsGetAccuracy()","text":"

    Get the current sensor accuracy.

    sensorsGetAccuracy()\n

    Returns: Accuracy value (0-3: UNRELIABLE, ACCURACY_LOW, ACCURACY_MEDIUM, ACCURACY_HIGH)

    "},{"location":"qsl4a/system/sensors/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start sensing\ndroid.startSensingTimed(1, 250)\n\n# Read sensors 10 times\nfor i in range(10):\n    accel = droid.sensorsReadAccelerometer().result\n    print(f\"Accel: X={accel[0]:.2f}, Y={accel[1]:.2f}, Z={accel[2]:.2f}\")\n    time.sleep(0.5)\n\ndroid.stopSensing()\n
    "},{"location":"qsl4a/system/settings/","title":"Settings API","text":"

    Control system settings including screen, sound, and network settings.

    "},{"location":"qsl4a/system/settings/#screen-settings","title":"Screen Settings","text":""},{"location":"qsl4a/system/settings/#setscreentimeout","title":"setScreenTimeout()","text":"

    Set the screen timeout value.

    setScreenTimeout(value)\n

    Parameters: - value (int): Screen timeout in seconds

    Returns: Previous timeout value

    "},{"location":"qsl4a/system/settings/#getscreentimeout","title":"getScreenTimeout()","text":"

    Get the current screen timeout.

    getScreenTimeout()\n

    Returns: Current screen timeout in seconds

    "},{"location":"qsl4a/system/settings/#getscreenbrightness","title":"getScreenBrightness()","text":"

    Get the screen brightness value.

    getScreenBrightness()\n

    Returns: Brightness value (0-255)

    "},{"location":"qsl4a/system/settings/#setscreenbrightness","title":"setScreenBrightness()","text":"

    Set the screen brightness.

    setScreenBrightness(value=None)\n

    Parameters: - value (int, optional): Brightness value (0-255), or None for auto

    Returns: Previous brightness value

    "},{"location":"qsl4a/system/settings/#checkscreenon","title":"checkScreenOn()","text":"

    Check if the screen is on.

    checkScreenOn()\n

    Returns: True if screen is on, False otherwise

    "},{"location":"qsl4a/system/settings/#airplane-mode","title":"Airplane Mode","text":""},{"location":"qsl4a/system/settings/#checkairplanemode","title":"checkAirplaneMode()","text":"

    Check if airplane mode is enabled.

    checkAirplaneMode()\n

    Returns: True if airplane mode is on

    "},{"location":"qsl4a/system/settings/#ringer-settings","title":"Ringer Settings","text":""},{"location":"qsl4a/system/settings/#checkringersilentmode","title":"checkRingerSilentMode()","text":"

    Check if ringer is in silent mode.

    checkRingerSilentMode()\n

    Returns: True if silent mode is on

    "},{"location":"qsl4a/system/settings/#toggleringersilentmode","title":"toggleRingerSilentMode()","text":"

    Toggle ringer silent mode.

    toggleRingerSilentMode(enabled=None)\n

    Parameters: - enabled (bool, optional): True to enable, False to disable, None to toggle

    Returns: New state

    "},{"location":"qsl4a/system/settings/#togglevibratemode","title":"toggleVibrateMode()","text":"

    Toggle vibrate mode.

    toggleVibrateMode(enabled=None, ringer=None)\n

    Parameters: - enabled (bool, optional): Toggle vibrate on/off - ringer (bool, optional): Apply to ringer mode

    Returns: New state

    "},{"location":"qsl4a/system/settings/#getvibratemode","title":"getVibrateMode()","text":"

    Get the vibrate mode setting.

    getVibrateMode(ringer=None)\n

    Parameters: - ringer (bool, optional): Check ringer vibrate mode

    Returns: True if vibrate is enabled

    "},{"location":"qsl4a/system/settings/#volume-settings","title":"Volume Settings","text":""},{"location":"qsl4a/system/settings/#getringervolume","title":"getRingerVolume()","text":"

    Get the current ringer volume.

    getRingerVolume()\n

    Returns: Ringer volume level (0-7 typically)

    "},{"location":"qsl4a/system/settings/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

    Get the maximum ringer volume.

    getMaxRingerVolume()\n

    Returns: Maximum ringer volume

    "},{"location":"qsl4a/system/settings/#setringervolume","title":"setRingerVolume()","text":"

    Set the ringer volume.

    setRingerVolume(volume)\n

    Parameters: - volume (int): Volume level

    "},{"location":"qsl4a/system/settings/#getmediavolume","title":"getMediaVolume()","text":"

    Get the current media volume.

    getMediaVolume()\n

    Returns: Media volume level (0-15 typically)

    "},{"location":"qsl4a/system/settings/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

    Get the maximum media volume.

    getMaxMediaVolume()\n

    Returns: Maximum media volume

    "},{"location":"qsl4a/system/settings/#setmediavolume","title":"setMediaVolume()","text":"

    Set the media volume.

    setMediaVolume(volume)\n

    Parameters: - volume (int): Volume level

    "},{"location":"qsl4a/system/settings/#system-info","title":"System Info","text":""},{"location":"qsl4a/system/settings/#elapsedrealtimenanos","title":"elapsedRealtimeNanos()","text":"

    Get nanoseconds since system startup.

    elapsedRealtimeNanos()\n

    Returns: Nanoseconds (can be used for timing)

    "},{"location":"qsl4a/system/settings/#gettrafficstats","title":"getTrafficStats()","text":"

    Get network traffic statistics.

    getTrafficStats(flags=7)\n

    Parameters: - flags (int): Which stats to retrieve (default: 7 = all)

    Returns: Dict with transmit/receive bytes

    "},{"location":"qsl4a/system/settings/#getapptxbytes","title":"getAppTxBytes()","text":"

    Get transmit bytes for QPython app.

    getAppTxBytes(packageName)\n

    Parameters: - packageName (str): Package name

    Returns: Dict with tx/rx bytes

    "},{"location":"qsl4a/system/settings/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Screen settings\ncurrent_timeout = droid.getScreenTimeout().result\nprint(f\"Current timeout: {current_timeout}s\")\ndroid.setScreenTimeout(30)\n\n# Check screen\nif droid.checkScreenOn().result:\n    print(\"Screen is on\")\n\n# Volume control\nmedia_vol = droid.getMediaVolume().result\nprint(f\"Media volume: {media_vol}\")\ndroid.setMediaVolume(10)\n\n# Check airplane mode\nif droid.checkAirplaneMode().result:\n    print(\"Airplane mode is on\")\n
    "},{"location":"qsl4a/system/sysinfo/","title":"System Information","text":"

    Retrieve device and system information.

    "},{"location":"qsl4a/system/sysinfo/#device-information","title":"Device Information","text":""},{"location":"qsl4a/system/sysinfo/#getandroidid","title":"getAndroidID()","text":"

    Get the Android device ID.

    getAndroidID()\n

    Returns: String device ID

    "},{"location":"qsl4a/system/sysinfo/#getsysinfo","title":"getSysInfo()","text":"

    Get comprehensive system information.

    getSysInfo()\n

    Returns: Dict with system details

    "},{"location":"qsl4a/system/sysinfo/#getlocale","title":"getLocale()","text":"

    Get device locale settings.

    getLocale()\n

    Returns: Locale string (e.g., \"en_US\")

    "},{"location":"qsl4a/system/sysinfo/#memory","title":"Memory","text":""},{"location":"qsl4a/system/sysinfo/#getmemoryinfo","title":"getMemoryInfo()","text":"

    Get RAM information.

    getMemoryInfo()\n

    Returns: Dict with memory stats

    "},{"location":"qsl4a/system/sysinfo/#display","title":"Display","text":""},{"location":"qsl4a/system/sysinfo/#getscreeninfo","title":"getScreenInfo()","text":"

    Get display information.

    getScreenInfo()\n

    Returns: Dict with width, height, density

    "},{"location":"qsl4a/system/sysinfo/#identifiers","title":"Identifiers","text":""},{"location":"qsl4a/system/sysinfo/#getimei","title":"getImei()","text":"

    Get device IMEI.

    getImei(slotIndex=None)\n
    "},{"location":"qsl4a/system/sysinfo/#getmeid","title":"getMeid()","text":"

    Get device MEID.

    getMeid(slotIndex=None)\n
    "},{"location":"qsl4a/system/sysinfo/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Device ID\nandroid_id = droid.getAndroidID().result\nprint(f\"Android ID: {android_id}\")\n\n# Screen info\nscreen = droid.getScreenInfo().result\nprint(f\"Screen: {screen['width']}x{screen['height']}\")\n\n# Memory\nmemory = droid.getMemoryInfo().result\nprint(f\"Memory: {memory}\")\n
    "},{"location":"qsl4a/system/wakelock/","title":"WakeLock API","text":"

    Control device wake locks to keep the CPU or screen on.

    "},{"location":"qsl4a/system/wakelock/#wake-lock-types","title":"Wake Lock Types","text":"

    QSL4A provides different wake lock types:

    Type Description Full CPU on, screen bright, keyboard bright Partial CPU on only Bright CPU on, screen bright Dim CPU on, screen dim"},{"location":"qsl4a/system/wakelock/#wake-lock-methods","title":"Wake Lock Methods","text":""},{"location":"qsl4a/system/wakelock/#wakelockacquirefull","title":"wakeLockAcquireFull()","text":"

    Acquire a full wake lock (CPU on, screen bright, keyboard bright).

    wakeLockAcquireFull()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockacquirepartial","title":"wakeLockAcquirePartial()","text":"

    Acquire a partial wake lock (CPU on only).

    wakeLockAcquirePartial()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockacquirebright","title":"wakeLockAcquireBright()","text":"

    Acquire a bright wake lock (CPU on, screen bright).

    wakeLockAcquireBright()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockacquiredim","title":"wakeLockAcquireDim()","text":"

    Acquire a dim wake lock (CPU on, screen dim).

    wakeLockAcquireDim()\n
    "},{"location":"qsl4a/system/wakelock/#wakelockrelease","title":"wakeLockRelease()","text":"

    Release the wake lock.

    wakeLockRelease()\n
    "},{"location":"qsl4a/system/wakelock/#usage-example","title":"Usage Example","text":"
    import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Acquire full wake lock\ndroid.wakeLockAcquireFull()\n\n# Do important work while keeping screen on\nprint(\"Screen will stay on\")\ntime.sleep(10)\n\n# Release when done\ndroid.wakeLockRelease()\n\n# Or use partial lock for background tasks\ndroid.wakeLockAcquirePartial()\n# CPU stays on even with screen off\ntime.sleep(30)\ndroid.wakeLockRelease()\n

    Note: Remember to release wake locks when no longer needed to conserve battery.

    "},{"location":"qsl4a/ui/accessibility/","title":"Accessibility Service","text":"

    The Accessibility Service allows automation of UI interactions like clicks, swipes, and system actions.

    "},{"location":"qsl4a/ui/accessibility/#service-control","title":"Service Control","text":""},{"location":"qsl4a/ui/accessibility/#accessibilitystartservice","title":"accessibilityStartService()","text":"

    Start the accessibility service.

    accessibilityStartService()\n

    Returns: True if successful, False otherwise

    "},{"location":"qsl4a/ui/accessibility/#accessibilityserviceenabled","title":"accessibilityServiceEnabled()","text":"

    Check if accessibility service is enabled.

    accessibilityServiceEnabled()\n

    Returns: True or False

    "},{"location":"qsl4a/ui/accessibility/#screen-interactions","title":"Screen Interactions","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityclick","title":"accessibilityClick()","text":"

    Click at screen coordinates.

    accessibilityClick(x=0, y=0, t=50)\n

    Parameters: - x (int/float): X coordinate (0=center, decimals supported) - y (int/float): Y coordinate (0=center, decimals supported) - t (int): Press duration in milliseconds (default: 50)

    "},{"location":"qsl4a/ui/accessibility/#accessibilityslide","title":"accessibilitySlide()","text":"

    Multi-point slide gesture.

    accessibilitySlide(XnYn=None, t=None)\n

    Parameters: - XnYn (list): Coordinates [X1, Y1, X2, Y2, ... Xn, Yn] - t (int): Slide duration (default: 50*n ms)

    "},{"location":"qsl4a/ui/accessibility/#system-actions","title":"System Actions","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityaction","title":"accessibilityAction()","text":"

    Execute system action by code.

    accessibilityAction(actionCode)\n

    Action Codes: | Code | Constant | Description | |------|----------|-------------| | 1 | BACK | Back button | | 2 | HOME | Home button | | 3 | RECENTS | Recent apps | | 4 | NOTIFICATIONS | Open notifications | | 5 | QUICK_SETTINGS | Open quick settings | | 6 | POWER_DIALOG | Power menu | | 7 | TOGGLE_SPLIT_SCREEN | Split screen | | 8 | LOCK_SCREEN | Lock screen | | 9 | TAKE_SCREENSHOT | Take screenshot | | 10 | KEYCODE_HEADSETHOOK | Headset hook | | 11-14 | ACCESSIBILITY_ | Accessibility buttons | | 15 | DISMISS_NOTIFICATION_SHADE | Close notifications | | 16-20 | DPAD_ | Directional pad | | 21 | MENU | Menu button | | 22 | MEDIA_PLAY_PAUSE | Play/Pause media |

    "},{"location":"qsl4a/ui/accessibility/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/accessibility/#click-center-screen","title":"Click Center Screen","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Start service\nif not droid.accessibilityServiceEnabled().result:\n    droid.accessibilityStartService()\n\n# Click center (0,0 = center)\ndroid.accessibilityClick(0, 0, t=100)\n
    "},{"location":"qsl4a/ui/accessibility/#swipe-gesture","title":"Swipe Gesture","text":"
    # Swipe from bottom to top (scroll up)\ndroid.accessibilitySlide([0, 1.5, 0, -1.5], t=300)\n
    "},{"location":"qsl4a/ui/accessibility/#system-navigation","title":"System Navigation","text":"
    # Press home\ndroid.accessibilityAction(2)\n\n# Press back\ndroid.accessibilityAction(1)\n\n# Open notifications\ndroid.accessibilityAction(4)\n
    "},{"location":"qsl4a/ui/accessibility/#tap-specific-location","title":"Tap Specific Location","text":"
    # Tap at screen coordinate (500, 800)\ndroid.accessibilityClick(500, 800)\n\n# Tap at relative position (center horizontally, 3/4 down)\ndroid.accessibilityClick(0, 1.5)\n
    "},{"location":"qsl4a/ui/dialogs/","title":"Dialog System","text":"

    QSL4A provides comprehensive dialog support for user interaction, including alerts, input dialogs, choice dialogs, and progress dialogs.

    "},{"location":"qsl4a/ui/dialogs/#alert-dialogs","title":"Alert Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowalert","title":"dialogShowAlert()","text":"

    Show a simple alert dialog.

    dialogShowAlert(title=\"Alert\", message=\"The message of the alert.\",\n                positiveButtonText=\"OK\", negativeButtonText=None,\n                neutralButtonText=None, messageIsHtml=False)\n

    Parameters: - title (str): Dialog title - message (str): Message text - positiveButtonText (str): Positive button label - negativeButtonText (str, optional): Negative button label - neutralButtonText (str, optional): Neutral button label - messageIsHtml (bool): Parse message as HTML

    Returns: Result with button clicked

    "},{"location":"qsl4a/ui/dialogs/#dialogshowsimplechoice","title":"dialogShowSimpleChoice()","text":"

    Show a simple choice dialog with items.

    dialogShowSimpleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

    Parameters: - items (list): List of choice strings

    Returns: Result with selected item

    "},{"location":"qsl4a/ui/dialogs/#input-dialogs","title":"Input Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialoggetinput","title":"dialogGetInput()","text":"

    Get text input from user.

    dialogGetInput(title=\"Value\", message=\"Please enter value:\",\n               defaultText=None, messageIsHtml=False)\n

    Returns: Result with user's input text

    "},{"location":"qsl4a/ui/dialogs/#dialoggetpassword","title":"dialogGetPassword()","text":"

    Get password input.

    dialogGetPassword(title=\"Password\", message=\"Please enter password:\")\n

    Returns: Result with password entered

    "},{"location":"qsl4a/ui/dialogs/#dialogcreateinput","title":"dialogCreateInput()","text":"

    Create a custom input dialog.

    dialogCreateInput(title=\"Value\", message=\"Please enter value:\",\n                  defaultText=None, inputType=None)\n

    Parameters: - inputType (str): Input type (e.g., \"text\", \"number\", \"textPassword\")

    "},{"location":"qsl4a/ui/dialogs/#dialogcreatepassword","title":"dialogCreatePassword()","text":"

    Create a password input dialog.

    dialogCreatePassword(title=\"Password\", message=\"Please enter password:\")\n
    "},{"location":"qsl4a/ui/dialogs/#dialogcreateseekbar","title":"dialogCreateSeekBar()","text":"

    Create a seek bar/slider dialog.

    dialogCreateSeekBar(starting_value=50, maximum_value=100, title=\"\", message=\"\")\n

    Parameters: - starting_value (int): Initial value - maximum_value (int): Maximum value

    "},{"location":"qsl4a/ui/dialogs/#choice-dialogs","title":"Choice Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowsinglechoice","title":"dialogShowSingleChoice()","text":"

    Show single choice (radio) dialog.

    dialogShowSingleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, selected=-1, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

    Parameters: - items (list): List of choice strings - selected (int): Default selected index

    "},{"location":"qsl4a/ui/dialogs/#dialogshowmultichoice","title":"dialogShowMultiChoice()","text":"

    Show multiple choice (checkbox) dialog.

    dialogShowMultiChoice(title=\"Alert\", message=\"The message of the alert.\",\n                      items=None, selected=None, positiveButtonText=\"OK\",\n                      negativeButtonText=None, neutralButtonText=None,\n                      messageIsHtml=False)\n

    Parameters: - items (list): List of choice strings - selected (list): List of initially selected indices

    "},{"location":"qsl4a/ui/dialogs/#dialogsetsinglechoiceitems","title":"dialogSetSingleChoiceItems()","text":"

    Set single choice items for a dialog.

    dialogSetSingleChoiceItems(items, selected=-1)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetmultichoiceitems","title":"dialogSetMultiChoiceItems()","text":"

    Set multiple choice items for a dialog.

    dialogSetMultiChoiceItems(items, selected=None)\n
    "},{"location":"qsl4a/ui/dialogs/#progress-dialogs","title":"Progress Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatespinnerprogress","title":"dialogCreateSpinnerProgress()","text":"

    Create indeterminate progress dialog.

    dialogCreateSpinnerProgress(title=None, message=None, maximum_progress=100)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogcreatehorizontalprogress","title":"dialogCreateHorizontalProgress()","text":"

    Create horizontal progress dialog.

    dialogCreateHorizontalProgress(title=None, message=None, maximum_progress=100)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetcurrentprogress","title":"dialogSetCurrentProgress()","text":"

    Update progress value.

    dialogSetCurrentProgress(current)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetmaxprogress","title":"dialogSetMaxProgress()","text":"

    Set maximum progress value.

    dialogSetMaxProgress(max)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetprogressmessage","title":"dialogSetProgressMessage()","text":"

    Update the progress dialog message.

    dialogSetProgressMessage(message)\n
    "},{"location":"qsl4a/ui/dialogs/#picker-dialogs","title":"Picker Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatedatepicker","title":"dialogCreateDatePicker()","text":"

    Create date picker dialog.

    dialogCreateDatePicker(year=1970, month=1, day=1)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogcreatetimepicker","title":"dialogCreateTimePicker()","text":"

    Create time picker dialog.

    dialogCreateTimePicker(hour=0, minute=0, is24hour=False)\n
    "},{"location":"qsl4a/ui/dialogs/#custom-dialog-creation","title":"Custom Dialog Creation","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatealert","title":"dialogCreateAlert()","text":"

    Create a custom alert dialog.

    dialogCreateAlert(title=None, message=None)\n

    Creates an empty alert dialog. Use with other dialogSet* functions to customize.

    "},{"location":"qsl4a/ui/dialogs/#dialogsetitems","title":"dialogSetItems()","text":"

    Set simple list items for the dialog.

    dialogSetItems(items)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetpositivebuttontext","title":"dialogSetPositiveButtonText()","text":"

    Set positive button text.

    dialogSetPositiveButtonText(text)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetnegativebuttontext","title":"dialogSetNegativeButtonText()","text":"

    Set negative button text.

    dialogSetNegativeButtonText(text)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetneutralbuttontext","title":"dialogSetNeutralButtonText()","text":"

    Set neutral button text.

    dialogSetNeutralButtonText(text)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogsetmessageishtml","title":"dialogSetMessageIsHtml()","text":"

    Set whether message should be parsed as HTML.

    dialogSetMessageIsHtml(messageIsHtml=True)\n
    "},{"location":"qsl4a/ui/dialogs/#dialogshow","title":"dialogShow()","text":"

    Show the created custom dialog.

    dialogShow()\n
    "},{"location":"qsl4a/ui/dialogs/#dialog-control","title":"Dialog Control","text":""},{"location":"qsl4a/ui/dialogs/#dialogdismiss","title":"dialogDismiss()","text":"

    Dismiss current dialog.

    dialogDismiss()\n
    "},{"location":"qsl4a/ui/dialogs/#dialoggetresponse","title":"dialogGetResponse()","text":"

    Get dialog response.

    dialogGetResponse()\n
    "},{"location":"qsl4a/ui/dialogs/#dialoggetselecteditems","title":"dialogGetSelectedItems()","text":"

    Get selected items from choice dialog.

    dialogGetSelectedItems()\n
    "},{"location":"qsl4a/ui/dialogs/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/dialogs/#simple-alert","title":"Simple Alert","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Show alert\ndroid.dialogShowAlert(\"Warning\", \"This is an important message!\")\n
    "},{"location":"qsl4a/ui/dialogs/#input-dialog","title":"Input Dialog","text":"
    # Get user input\nresult = droid.dialogGetInput(\"Name\", \"Enter your name:\", \"John\").result\nprint(f\"Hello, {result}!\")\n
    "},{"location":"qsl4a/ui/dialogs/#custom-dialog-with-buttons","title":"Custom Dialog with Buttons","text":"
    # Create custom dialog\ndroid.dialogCreateAlert(\"Custom\", \"Choose an option\")\ndroid.dialogSetItems([\"Option 1\", \"Option 2\", \"Option 3\"])\ndroid.dialogShow()\n\n# Get response\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response['item']}\")\n
    "},{"location":"qsl4a/ui/dialogs/#progress-dialog","title":"Progress Dialog","text":"
    # Create progress dialog\ndroid.dialogCreateHorizontalProgress(\"Loading\", \"Please wait...\", 100)\ndroid.dialogShow()\n\n# Update progress\nfor i in range(101):\n    droid.dialogSetCurrentProgress(i)\n    time.sleep(0.05)\n\ndroid.dialogDismiss()\n
    "},{"location":"qsl4a/ui/dialogs/#date-picker","title":"Date Picker","text":"
    # Show date picker\ndroid.dialogCreateDatePicker(2024, 1, 15)\ndroid.dialogShow()\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response}\")\n
    "},{"location":"qsl4a/ui/floatview/","title":"FloatView","text":"

    Floating window support for overlay UI elements that stay on top of other applications.

    "},{"location":"qsl4a/ui/floatview/#methods","title":"Methods","text":""},{"location":"qsl4a/ui/floatview/#floatview_1","title":"floatView()","text":"

    Show or modify a floating view.

    floatView(Args=None)\n

    Parameters: - Args (dict): Configuration dictionary with the following keys: - index (int): Float view index (-1 to create new, >=0 to modify existing) - text (str): Text content to display - html (str): HTML content (used if text is omitted) - width (int): View width in pixels (default: 300) - height (int): View height in pixels (default: 150) - x (int): X position (0 = center, positive/negative for offset) - y (int): Y position (0 = center, positive/negative for offset) - backColor (str): Background color in ARGB hex (default: '7f7f7f7f') - textColor (str): Text color in ARGB hex (default: 'ff000000') - textSize (int): Text size (default: 10) - textAlign (int): Text alignment (0 = inherit) - script (str): Script path to run after long click close - arg: Script argument - clickRemove (bool): Enable click to remove (default: True) - flag (int): Window flag (default: 40 - touchable)

    Returns: Current chain list length

    "},{"location":"qsl4a/ui/floatview/#floatviewcount","title":"floatViewCount()","text":"

    Get the number of active float views.

    floatViewCount()\n

    Returns: Number of float views

    "},{"location":"qsl4a/ui/floatview/#floatviewresult","title":"floatViewResult()","text":"

    Get the result/status of a float view.

    floatViewResult(index=-1)\n

    Parameters: - index (int): Float view index (default: -1, returns last operation result)

    Returns: Dict with operation details including: - x, y: Position - time: Timestamp - operation: Operation type ('initial', 'move', etc.) - index: View index - removed: True if view was removed

    "},{"location":"qsl4a/ui/floatview/#floatviewremove","title":"floatViewRemove()","text":"

    Remove a float view.

    floatViewRemove(index=-1)\n

    Parameters: - index (int): Index of view to remove (default: -1 removes the last one)

    Returns: 1 if successful, 0 otherwise

    "},{"location":"qsl4a/ui/floatview/#constants","title":"Constants","text":"
    • floatView.INDEX_NEW = -1 - Create new float view
    • floatView.FLAG_DEFAULT_TOUCHABLE = 40 - Default touchable flag
    • floatView.TEXT_ALIGNMENT_INHERIT = 0
    • floatView.TEXT_ALIGNMENT_CENTER - Center text alignment
    "},{"location":"qsl4a/ui/floatview/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/floatview/#basic-float-view","title":"Basic Float View","text":"
    import androidhelper\nfrom androidhelper import Android\n\ndroid = androidhelper.Android()\n\n# Create a simple float view\ndroid.floatView({\n    'index': -1,  # Create new\n    'text': 'Hello World',\n    'width': 400,\n    'height': 300,\n    'x': -300,  # Offset from center\n    'y': -400,\n    'backColor': 'ff0000',  # Red background\n    'textColor': '0000ff',  # Blue text\n    'textSize': 16,\n    'textAlign': droid.floatView.TEXT_ALIGNMENT_CENTER\n})\n\n# Check count\nprint(f\"Float views: {droid.floatViewCount().result}\")\n\n# Get result\nresult = droid.floatViewResult().result\nprint(f\"View info: {result}\")\n\n# Remove the float view\ndroid.floatViewRemove(0)\n
    "},{"location":"qsl4a/ui/floatview/#html-content","title":"HTML Content","text":"
    # Create float view with HTML content\ndroid.floatView({\n    'text': '',  # Empty text to use HTML\n    'html': '<h1>Title</h1><p>Rich <b>HTML</b> content</p>',\n    'width': 500,\n    'height': 400\n})\n
    "},{"location":"qsl4a/ui/floatview/#modify-existing-view","title":"Modify Existing View","text":"
    # Create initial view\ndroid.floatView({'text': 'Initial Text', 'width': 300, 'height': 150})\n\n# Modify the same view (index 0)\ndroid.floatView({\n    'index': 0,\n    'text': 'Updated Text!',\n    'backColor': '7f00ff00'  # Green background\n})\n\n# Check the move/change result\nresult = droid.floatViewResult(0).result\nprint(f\"Operation: {result.get('operation')}, Position: ({result.get('x')}, {result.get('y')})\")\n
    "},{"location":"qsl4a/ui/floatview/#multiple-float-views","title":"Multiple Float Views","text":"
    # Create multiple views\nfor i in range(3):\n    droid.floatView({\n        'index': -1,\n        'text': f'View {i}',\n        'x': i * 100 - 150,\n        'y': i * 100 - 150,\n        'backColor': f'{i}f{i}f{i}f'\n    })\n\nprint(f\"Total views: {droid.floatViewCount().result}\")\n\n# Remove all views\nwhile droid.floatViewCount().result > 0:\n    droid.floatViewRemove()\n
    "},{"location":"qsl4a/ui/floatview/#with-script-callback","title":"With Script Callback","text":"
    # Create float view that runs script on close\ndroid.floatView({\n    'text': 'Click to close and run script',\n    'script': '/sdcard/my_script.py',\n    'arg': 'hello from float view',\n    'clickRemove': True\n})\n
    "},{"location":"qsl4a/ui/fullscreen/","title":"FullScreen UI","text":"

    Create custom fullscreen interfaces with native Android layouts.

    "},{"location":"qsl4a/ui/fullscreen/#layout-methods","title":"Layout Methods","text":""},{"location":"qsl4a/ui/fullscreen/#fullshow","title":"fullShow()","text":"

    Show a fullscreen layout.

    fullShow(layout, title=None, theme=None)\n

    Parameters: - layout (str): JSON layout definition or layout string - title (str, optional): Window title - theme (str, optional): Theme name

    Returns: Window ID

    "},{"location":"qsl4a/ui/fullscreen/#fulldismiss","title":"fullDismiss()","text":"

    Close fullscreen window.

    fullDismiss()\n
    "},{"location":"qsl4a/ui/fullscreen/#fullquery","title":"fullQuery()","text":"

    Query all widget values.

    fullQuery()\n

    Returns: Dict of widget IDs and values

    "},{"location":"qsl4a/ui/fullscreen/#fullquerydetail","title":"fullQueryDetail()","text":"

    Query specific widget details.

    fullQueryDetail(id)\n
    "},{"location":"qsl4a/ui/fullscreen/#property-methods","title":"Property Methods","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperty","title":"fullGetProperty()","text":"

    Get widget property.

    fullGetProperty(id, property)\n
    "},{"location":"qsl4a/ui/fullscreen/#fullsetproperty","title":"fullSetProperty()","text":"

    Set widget property.

    fullSetProperty(id, property, value)\n
    "},{"location":"qsl4a/ui/fullscreen/#fullsetlist","title":"fullSetList()","text":"

    Set list widget items.

    fullSetList(id, list, isHtml=False, listType=0)\n
    "},{"location":"qsl4a/ui/fullscreen/#fullsetlist2","title":"fullSetList2()","text":"

    Set list widget items with resource ID.

    fullSetList2(id, list, intRes)\n

    Parameters: - id (str): Widget ID - list (list): List of items - intRes (int): Android resource ID for list item layout

    "},{"location":"qsl4a/ui/fullscreen/#fullsetlistselected","title":"fullSetListSelected()","text":"

    Set selected item in a list.

    fullSetListSelected(id, selected)\n

    Parameters: - id (str): List widget ID - selected (int): Index of item to select

    "},{"location":"qsl4a/ui/fullscreen/#fullgetlistselected","title":"fullGetListSelected()","text":"

    Get the currently selected list item index.

    fullGetListSelected(id)\n

    Parameters: - id (str): List widget ID

    Returns: Selected item index

    "},{"location":"qsl4a/ui/fullscreen/#batch-property-operations","title":"Batch Property Operations","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperties","title":"fullGetProperties()","text":"

    Get properties for multiple widgets at once.

    fullGetProperties(ids, property)\n

    Parameters: - ids (list): List of widget IDs - property (str): Property name to get

    Returns: Dict mapping widget IDs to property values

    "},{"location":"qsl4a/ui/fullscreen/#fullsetproperties","title":"fullSetProperties()","text":"

    Set property for multiple widgets at once.

    fullSetProperties(ids, property, value)\n

    Parameters: - ids (list): List of widget IDs - property (str): Property name to set - value: Property value

    "},{"location":"qsl4a/ui/fullscreen/#screenshot","title":"Screenshot","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetscreenshot","title":"fullGetScreenShot()","text":"

    Capture fullscreen screenshot.

    fullGetScreenShot(path=None)\n

    Parameters: - path (str, optional): Save path. If None, returns in event

    Returns: Event with screenshot data

    "},{"location":"qsl4a/ui/fullscreen/#usage-example","title":"Usage Example","text":"
    import androidhelper\n\ndroid = androidhelper.Android()\n\n# Define layout\nlayout = '''\n{ \"type\": \"LinearLayout\", \"orientation\": \"vertical\",\n  \"children\": [\n    { \"type\": \"TextView\", \"id\": \"title\", \"text\": \"Hello\" },\n    { \"type\": \"Button\", \"id\": \"btn\", \"text\": \"Click Me\" }\n  ]\n}\n'''\n\n# Show layout\ndroid.fullShow(layout, \"My App\")\n\n# Query button click\nevent = droid.eventWaitFor('click', timeout=10)\nif event.result:\n    widget_id = event.result['data']['id']\n    if widget_id == 'btn':\n        print(\"Button clicked!\")\n\ndroid.fullDismiss()\n
    "}]} \ No newline at end of file diff --git a/en/static/qpy_helloworld.jpg b/en/static/qpy_helloworld.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6ac37858f111b266bbaf0d942504ec8904f832e3 GIT binary patch literal 46758 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 J!t2|^{|l~-L+$_o literal 0 HcmV?d00001 diff --git a/en/tutorial-hello-world/index.html b/en/tutorial-hello-world/index.html index 9091920..c82a688 100644 --- a/en/tutorial-hello-world/index.html +++ b/en/tutorial-hello-world/index.html @@ -2152,10 +2152,10 @@
  • - + - SL4A library + Code Understanding @@ -2177,7 +2177,18 @@ - Execution result + Execution Result + + + + +
  • + +
  • + + + + Next Steps @@ -2238,10 +2249,10 @@
  • - + - SL4A library + Code Understanding @@ -2263,7 +2274,18 @@ - Execution result + Execution Result + + + + +
  • + +
  • + + + + Next Steps @@ -2289,81 +2311,83 @@

    Writing "Hello World"

    Hello world

    -

    hello world

    +

    hello world

    Well, after you became a bit more familiar with QPython, let's create our first program in QPython. Obviously, it will be helloworld.py. ;)

    Start QPython, open editor and enter the following code:

    -
    import androidhelper
    -
    -droid = androidhelper.Android()
    -droid.makeToast('Hello, Username!')
    +
    #qpy:quiet
    +import androidhelper
    +
    +droid = androidhelper.Android()
    +droid.makeToast('Hello, QPYTHON!')
     

    No wonder, it's just similar to any other hello-world program. When executed, it just shows pop-up message on the screen (see screenshot on the top). Anyway, it's a good example of QPython program.

    -

    SL4A library

    -

    It begins with import androidhelper — the most useful module in QPython, which encapsulates almost all interface with Android, available in Python. Any script developed in QPython starts with this statement (at least if it claims to communicate with user). Read more about Python library here and import statement here.

    -

    By the way, if you're going to make your script compatible with SL4A, you should replace the first line with the following code (and use android instead androidhelper further in the program):

    -
    try:
    -    import androidhelper as android
    -except ImportError:
    -    import android
    -
    -

    Ok, next we're creating an object droid (actually a class), it is necessary to call RPC functions in order to communicate with Android.

    -

    And the last line of our code calls such function, droid.makeToast(), which shows a small pop-up message (a "toast") on the screen.

    +

    Code Understanding

    +

    It begins with import androidhelper — the most useful module in QPython, which encapsulates almost all interface with Android available in Python. Any script developed in QPython starts with this statement (at least if it claims to communicate with user). Read more about Python library here and import statement here.

    +

    Next, we create an object droid (actually a class), which is necessary to call RPC functions to communicate with Android.

    +

    The last line of our code calls droid.makeToast(), which shows a small pop-up message (a "toast") on the screen.

    Well, let's add some more functionality. Let it ask the user name and greet them.

    More samples

    We can display a simple dialog box with the title, prompt, edit field and buttons Ok and Cancel using dialogGetInput call. Replace the last line of your code and save it as hello1.py:

    -
    import androidhelper
    -
    -droid = androidhelper.Android()
    -respond = droid.dialogGetInput("Hello", "What is your name?")
    +
    #qpy:quiet
    +import androidhelper
    +
    +droid = androidhelper.Android()
    +respond = droid.dialogGetInput("Hello", "What is your name?")
     
    -

    Well, I think it should return any respond, any user reaction. That's why I wrote respond = .... But what the call actually returns? Let's check. Just add print statement after the last line:

    -
    import androidhelper
    -
    -droid = androidhelper.Android()
    -respond = droid.dialogGetInput("Hello", "What is your name?")
    -print(respond)
    +

    Well, I think it should return any respond, any user reaction. That's why I wrote respond = .... But what does the call actually return? Let's check. Just add print statement after the last line:

    +
    #qpy:quiet
    +import androidhelper
    +
    +droid = androidhelper.Android()
    +respond = droid.dialogGetInput("Hello", "What is your name?")
    +print(respond)
     

    Then save and run it...

    Oops! Nothing printed? Don't worry. Just pull notification bar and you will see "QPython Program Output: hello1.py" — tap it!

    As you can see, droid.dialogGetInput() returns a JSON object with three fields. We need only one — result which contains an actual input from user.

    Let's add script's reaction:

    -
    import androidhelper
    -
    -droid = androidhelper.Android()
    -respond = droid.dialogGetInput("Hello", "What is your name?")
    -print(respond)
    -message = f'Hello, {respond.result}!'
    -droid.makeToast(message)
    +
    #qpy:quiet
    +import androidhelper
    +
    +droid = androidhelper.Android()
    +respond = droid.dialogGetInput("Hello", "What is your name?")
    +print(respond)
    +message = f'Hello, {respond.result}!'
    +droid.makeToast(message)
     

    Last two lines (1) format the message and (2) show the message to the user in the toast. See Python docs if you still don't know what f-strings mean.

    Wow! It works! ;)

    Now I'm going to add a bit of logic there. Think: what happen if the user clicks Cancel button, or clicks Ok leaving the input field blank?

    You can play with the program checking what contains respond variable in every case.

    First of all, I want to put text entered by user to a separate variable: name = respond.result. Then I'm going to check it, and if it contains any real text, it will be considered as a name and will be used in greeting. Otherwise another message will be shown. Replace fifth line message = f'Hello, {respond.result}!' with the following code:

    -
    name = respond.result
    -if name:
    -    message = f'Hello, {name}!'
    -else:
    -    message = "Hey! And you're not very polite, %Username%!"
    +
    name = respond.result
    +if name:
    +    message = f'Hello, {name}!'
    +else:
    +    message = "Hey! And you're not very polite, %Username%!"
     

    Use < and > buttons on the toolbar to indent/unindent lines in if-statement (or just use space/backspace keys). You can read more about indentation in Python here; if-statement described here.

    First of all, we put user input to the variable name. Then we check does name contain anything? In case the user left the line blank and clicked Ok, the return value is empty string ''. In case of Cancel button pressed, the return value is None. Both are treated as false in if-statement. So, only if name contains anything meaningful, then-statement is executed and greeting "Hello, ...!" shown. In case of empty input the user will see "Hey! And you're not very polite, %Username%!" message.

    Ok, here is the whole program:

    -
    import androidhelper
    -
    -droid = androidhelper.Android()
    -respond = droid.dialogGetInput("Hello", "What is your name?")
    -print(respond)
    -name = respond.result
    -if name:
    -    message = f'Hello, {name}!'
    -else:
    -    message = "Hey! And you're not very polite, %Username%!"
    -droid.makeToast(message)
    +
    #qpy:quiet
    +import androidhelper
    +
    +droid = androidhelper.Android()
    +respond = droid.dialogGetInput("Hello", "What is your name?")
    +print(respond)
    +name = respond.result
    +if name:
    +    message = f'Hello, {name}!'
    +else:
    +    message = "Hey! And you're not very polite, %Username%!"
    +droid.makeToast(message)
     
    -

    Execution result

    +

    Execution Result

    +

    Next Steps

    +

    For Python beginners, we recommend learning from the Python Basic Syntax course to further your Python skills, or browse QPython Featured Courses to find more content you want to learn.

    + From 7dc4f7c024b413017c4bc1214b80ac599f815f2c Mon Sep 17 00:00:00 2001 From: "River@devbox" Date: Sun, 22 Mar 2026 20:43:26 +0800 Subject: [PATCH 20/32] Deploy site - 2026-03-22 20:43:26 --- en/404.html | 320 ++-- en/AIPyApp/index.html | 334 ++-- en/GraphicalInterface/index.html | 334 ++-- en/Notebook/index.html | 334 ++-- en/Ollama/index.html | 334 ++-- en/Terminal/index.html | 336 ++-- en/editor-guide/index.html | 334 ++-- en/external-api/index.html | 334 ++-- en/getting-started/index.html | 1280 +++++++-------- en/index.html | 320 ++-- en/qpypi-guide/index.html | 334 ++-- en/qpython-x/index.html | 320 ++-- en/qsl4a/connectivity/contacts/index.html | 320 ++-- en/qsl4a/connectivity/ftp/index.html | 320 ++-- en/qsl4a/connectivity/location/index.html | 328 ++-- en/qsl4a/connectivity/phone/index.html | 320 ++-- .../connectivity/signalstrength/index.html | 320 ++-- en/qsl4a/connectivity/sms/index.html | 328 ++-- en/qsl4a/connectivity/wifi/index.html | 328 ++-- en/qsl4a/core/android-base/index.html | 328 ++-- en/qsl4a/core/events/index.html | 328 ++-- en/qsl4a/core/intent/index.html | 328 ++-- en/qsl4a/hardware/bluetooth/index.html | 328 ++-- en/qsl4a/hardware/camera/index.html | 328 ++-- en/qsl4a/hardware/recorder/index.html | 328 ++-- en/qsl4a/hardware/usbserial/index.html | 320 ++-- en/qsl4a/hardware/webcam/index.html | 320 ++-- en/qsl4a/index.html | 328 ++-- en/qsl4a/media/image/index.html | 328 ++-- en/qsl4a/media/mediaplayer/index.html | 328 ++-- en/qsl4a/special/cipher/index.html | 328 ++-- en/qsl4a/special/pgptai/index.html | 330 ++-- en/qsl4a/storage/clipboard/index.html | 328 ++-- en/qsl4a/storage/documentfile/index.html | 328 ++-- en/qsl4a/storage/preferences/index.html | 320 ++-- en/qsl4a/system/activityresult/index.html | 320 ++-- en/qsl4a/system/application/index.html | 328 ++-- en/qsl4a/system/battery/index.html | 328 ++-- en/qsl4a/system/qpyinterface/index.html | 320 ++-- en/qsl4a/system/sensors/index.html | 328 ++-- en/qsl4a/system/settings/index.html | 320 ++-- en/qsl4a/system/sysinfo/index.html | 328 ++-- en/qsl4a/system/wakelock/index.html | 320 ++-- en/qsl4a/ui/accessibility/index.html | 328 ++-- en/qsl4a/ui/dialogs/index.html | 328 ++-- en/qsl4a/ui/floatview/index.html | 328 ++-- en/qsl4a/ui/fullscreen/index.html | 328 ++-- en/tutorial-hello-world/index.html | 546 +++---- en/whats-new/index.html | 322 ++-- zh/404.html | 320 ++-- zh/AIPyApp/index.html | 334 ++-- zh/GraphicalInterface/index.html | 334 ++-- zh/Notebook/index.html | 334 ++-- zh/Ollama/index.html | 334 ++-- zh/Terminal/index.html | 336 ++-- zh/editor-guide/index.html | 334 ++-- zh/external-api/index.html | 334 ++-- zh/getting-started/index.html | 1402 ++++++++--------- zh/index.html | 320 ++-- zh/qpypi-guide/index.html | 334 ++-- zh/qpython-x/index.html | 320 ++-- zh/qsl4a/connectivity/contacts/index.html | 328 ++-- zh/qsl4a/connectivity/ftp/index.html | 328 ++-- zh/qsl4a/connectivity/location/index.html | 328 ++-- zh/qsl4a/connectivity/phone/index.html | 328 ++-- .../connectivity/signalstrength/index.html | 328 ++-- zh/qsl4a/connectivity/sms/index.html | 328 ++-- zh/qsl4a/connectivity/wifi/index.html | 328 ++-- zh/qsl4a/core/android-base/index.html | 328 ++-- zh/qsl4a/core/events/index.html | 328 ++-- zh/qsl4a/core/intent/index.html | 328 ++-- zh/qsl4a/hardware/bluetooth/index.html | 328 ++-- zh/qsl4a/hardware/camera/index.html | 328 ++-- zh/qsl4a/hardware/recorder/index.html | 328 ++-- zh/qsl4a/hardware/usbserial/index.html | 328 ++-- zh/qsl4a/hardware/webcam/index.html | 328 ++-- zh/qsl4a/index.html | 328 ++-- zh/qsl4a/media/image/index.html | 328 ++-- zh/qsl4a/media/mediaplayer/index.html | 328 ++-- zh/qsl4a/special/cipher/index.html | 328 ++-- zh/qsl4a/special/pgptai/index.html | 330 ++-- zh/qsl4a/storage/clipboard/index.html | 328 ++-- zh/qsl4a/storage/documentfile/index.html | 328 ++-- zh/qsl4a/storage/preferences/index.html | 328 ++-- zh/qsl4a/system/activityresult/index.html | 328 ++-- zh/qsl4a/system/application/index.html | 328 ++-- zh/qsl4a/system/battery/index.html | 328 ++-- zh/qsl4a/system/qpyinterface/index.html | 328 ++-- zh/qsl4a/system/sensors/index.html | 328 ++-- zh/qsl4a/system/settings/index.html | 328 ++-- zh/qsl4a/system/sysinfo/index.html | 328 ++-- zh/qsl4a/system/wakelock/index.html | 328 ++-- zh/qsl4a/ui/accessibility/index.html | 328 ++-- zh/qsl4a/ui/dialogs/index.html | 328 ++-- zh/qsl4a/ui/floatview/index.html | 328 ++-- zh/qsl4a/ui/fullscreen/index.html | 328 ++-- zh/tutorial-hello-world/index.html | 546 +++---- zh/whats-new/index.html | 322 ++-- 98 files changed, 17281 insertions(+), 17281 deletions(-) diff --git a/en/404.html b/en/404.html index 4fbe3e4..88d85a5 100644 --- a/en/404.html +++ b/en/404.html @@ -235,11 +235,11 @@
  • - + - Guides + Tutorial
  • @@ -255,11 +255,11 @@
  • - + - QSL4A + Guides
  • @@ -275,11 +275,11 @@
  • - + - Tutorial + QSL4A
  • @@ -496,7 +496,7 @@ - Guides + Tutorial @@ -512,6 +512,123 @@ + Tutorial + + + + + + +
  • + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • - - - - - - - - - - - - - - -
  • - - - - - - +
  • + - - - -
  • - - + + + + + + + + -
  • - + + + + + + + + + + +
  • + + + + + + + + -
  • + + + + - - - - - - @@ -1186,17 +1311,17 @@ - + - - + + + + + + +
  • + + + + + + + + 偏好设置 + + + + + + + +
  • @@ -2298,12 +2499,11 @@ - - - - + + + + - @@ -2312,29 +2512,28 @@ - - - -
  • +
  • - + + + -
  • + + + + + - - - + + + + + diff --git a/zh/index.html b/zh/index.html index c9830a5..a337a30 100644 --- a/zh/index.html +++ b/zh/index.html @@ -246,11 +246,11 @@
  • - + - 指南 + 教程
  • @@ -266,11 +266,11 @@
  • - + - QSL4A + 指南
  • @@ -286,11 +286,11 @@
  • - + - 教程 + QSL4A
  • @@ -623,7 +623,7 @@ - 指南 + 教程 @@ -639,6 +639,123 @@ + 教程 + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • + + + + + + + + + + + + + + + + + + + +
  • + + + + + + + + + + +
  • - - - - - -
  • +
  • - 演示 + 演示视频 +
  • + + + +
  • - 了解更多 + 课程推荐 @@ -2743,27 +2743,27 @@
  • - - - - - -
  • +
  • - 演示 + 演示视频 +
  • + + + +
  • - 了解更多 + 课程推荐 @@ -2793,6 +2793,9 @@

    AIPyApp - AI驱动的程序生成器概述

    AIPyApp 改变了您编写代码的方式——只需用自然语言描述您想要的功能,AI 就会为您生成 Python 程序。QPython 还将推出 AIPy Academy——一个为 AI 时代量身定制的 Python 编程课程平台。

    安装

    + + +

    QPython 氛围编程(Vibe Coding) 01 - 如何启用AIPyApp

    第一步:从仪表盘启动

    1. 打开 QPython,进入 仪表盘
    2. @@ -2827,14 +2830,20 @@

      示例命令 2. 生成相应的 Python 代码 3. 自动执行程序

      就是这样——您无需编写任何代码就创建了一个可运行的 Python 程序!

      -

      演示

      +

      演示视频

      + + +

      QPython 氛围编程(Vibe Coding) 02 - 使用自然语言开发一个翻译App

      上面的示例演示了 AIPyApp 如何: - 理解中文指令 - 生成基于 QSL4A 的 Python 代码 - 立即运行程序

      探索 AIPyApp 以发现更多功能,开始轻松构建 Python 程序。

      -

      了解更多

      -

      敬请期待 AIPy Academyaipy.org - 在 AI 时代学习和使用 Python 编程的课程即将上线。

      +

      课程推荐

      +

      末尾,给大家推荐下面课程:

      +

      与AI协作的Python编程入门

      +

      《与AI协作的Python编程入门》 — 由QPython官方团队精心打造并提供教学支持,能帮助学习者快速、体系化地掌握Python开发以及在AI时代更好地学习使用AI。

      +

      了解详情

      diff --git a/zh/search/search_index.json b/zh/search/search_index.json index 54bdd78..07c93b3 100644 --- a/zh/search/search_index.json +++ b/zh/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"QPython \u9879\u76ee","text":"

      QPython \u4e0d\u4ec5\u662f\u4e00\u4e2a\u5f3a\u5927\u7684 Android Python IDE\uff0c\u4e5f\u662f\u4e00\u4e2a\u6d3b\u8dc3\u7684\u6280\u672f\u793e\u533a\u3002

      "},{"location":"#ai-android-python-ide","title":"\u652f\u6301 AI \u7684 Android Python IDE","text":"

      QPython \u662f\u60a8\u8fdb\u884c Android Python \u7f16\u7a0b\u7684\u5165\u53e3\u3002\u5b83\u96c6\u6210\u4e86 Python \u89e3\u91ca\u5668\u3001AI \u6a21\u578b\u5f15\u64ce\u548c\u79fb\u52a8\u5f00\u53d1\u5de5\u5177\u94fe\uff0c\u8ba9\u60a8\u80fd\u591f\u4ece\u79fb\u52a8\u8bbe\u5907\u6784\u5efa Web \u5e94\u7528\u7a0b\u5e8f\u3001\u6267\u884c\u79d1\u5b66\u8ba1\u7b97\u548c\u521b\u5efa\u667a\u80fd\u5e94\u7528\u3002

      \u65e0\u8bba\u60a8\u662f\u5728\u5b66\u4e60\u7f16\u7a0b\u3001\u6784\u5efa\u6570\u636e\u79d1\u5b66\u9879\u76ee\uff0c\u8fd8\u662f\u5f00\u53d1 AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f\uff0cQPython \u90fd\u63d0\u4f9b\u4e86\u5b8c\u6574\u7684\u79fb\u52a8\u7f16\u7a0b\u89e3\u51b3\u65b9\u6848\uff0c\u62e5\u6709\u5168\u9762\u7684\u5f00\u53d1\u8005\u8d44\u6e90\u548c\u6d3b\u8dc3\u7684\u793e\u533a\u6765\u652f\u6301\u60a8\u7684\u65c5\u7a0b\u3002

      • \u5206\u652f\u7248\u672c \u2013 \u4e86\u89e3\u4e0d\u540c\u7684 QPython \u7248\u672c\uff08IDE\u3001\u793e\u533a\u7248\u3001Plus\uff09\uff0c\u9009\u62e9\u9002\u5408\u60a8\u9700\u6c42\u7684\u7248\u672c
      • \u66f4\u65b0\u65e5\u5fd7 \u2013 \u968f\u65f6\u4e86\u89e3\u6700\u65b0\u529f\u80fd\u3001\u6539\u8fdb\u548c\u53d1\u884c\u8bf4\u660e
      "},{"location":"#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"

      \u5982\u4f55\u5feb\u901f\u5165\u95e8\uff1f\u8bf7\u6309\u7167\u4ee5\u4e0b\u6b65\u9aa4\uff1a

      • \u5feb\u901f\u5165\u95e8
      • Hello World \u6559\u7a0b
      "},{"location":"#_2","title":"\u7f16\u7a0b\u6307\u5357","text":"

      QPython \u4e0d\u4ec5\u63d0\u4f9b\u57fa\u7840\u7684 Python \u63a5\u53e3\u652f\u6301\uff0c\u66f4\u91cd\u8981\u7684\u662f\uff0c\u5b83\u8fd8\u5141\u8bb8\u60a8\u901a\u8fc7 QSL4A \u63a5\u53e3\u4f7f\u7528 Python \u8c03\u7528 Android API\u3002

      • Python \u6807\u51c6\u5e93 \u2013 \u901a\u7528\u7684 Python \u8bed\u6cd5\u548c\u5185\u7f6e\u5e93
      • QSL4A API \u2013 \u4ece Python \u8bbf\u95ee Android \u8bbe\u5907\u529f\u80fd\uff08\u76f8\u673a\u3001\u4f20\u611f\u5668\u3001\u77ed\u4fe1\u7b49\uff09
      • QPYPI \u6307\u5357 \u2013 \u5b89\u88c5\u989d\u5916\u7684 Python \u5305
      • \u7f16\u8f91\u5668\u6307\u5357 \u2013 \u4f7f\u7528\u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668
      • \u5916\u90e8 API \u2013 \u4e0e\u5916\u90e8\u5e94\u7528\u7a0b\u5e8f\u96c6\u6210
      "},{"location":"#_3","title":"\u4e0b\u8f7d\u8d44\u6e90","text":"
      • Google Drive
      • \u5fae\u4fe1\u7f51\u76d8
      "},{"location":"#_4","title":"\u793e\u533a\u4e0e\u53cd\u9988","text":"
      • \u4e2d\u6587\u4ea4\u6d41\u793e\u533a
      • \u767e\u5ea6\u8d34\u5427
      • \u95ee\u9898\u53cd\u9988
      • \u529f\u80fd\u6269\u5c55\u8bf7\u6c42
      "},{"location":"#_5","title":"\u5173\u6ce8\u6211\u4eec","text":"
      • B\u7ad9
      • Weibo
      "},{"location":"AIPyApp/","title":"AIPyApp - AI\u9a71\u52a8\u7684\u7a0b\u5e8f\u751f\u6210\u5668","text":"

      AIPyApp \u662f QPython \u4e2d\u7684\u667a\u80fd\u5de5\u5177\uff0c\u53ef\u4ee5\u5229\u7528 AI \u4ece\u81ea\u7136\u8bed\u8a00\u6307\u4ee4\u81ea\u52a8\u751f\u6210 Python \u7a0b\u5e8f\u3002

      "},{"location":"AIPyApp/#_1","title":"\u6982\u8ff0","text":"

      AIPyApp \u6539\u53d8\u4e86\u60a8\u7f16\u5199\u4ee3\u7801\u7684\u65b9\u5f0f\u2014\u2014\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u63cf\u8ff0\u60a8\u60f3\u8981\u7684\u529f\u80fd\uff0cAI \u5c31\u4f1a\u4e3a\u60a8\u751f\u6210 Python \u7a0b\u5e8f\u3002QPython \u8fd8\u5c06\u63a8\u51fa AIPy Academy\u2014\u2014\u4e00\u4e2a\u4e3a AI \u65f6\u4ee3\u91cf\u8eab\u5b9a\u5236\u7684 Python \u7f16\u7a0b\u8bfe\u7a0b\u5e73\u53f0\u3002

      "},{"location":"AIPyApp/#_2","title":"\u5b89\u88c5","text":""},{"location":"AIPyApp/#_3","title":"\u7b2c\u4e00\u6b65\uff1a\u4ece\u4eea\u8868\u76d8\u542f\u52a8","text":"
      1. \u6253\u5f00 QPython\uff0c\u8fdb\u5165 \u4eea\u8868\u76d8
      2. \u957f\u6309\u5f00\u59cb\u6309\u94ae

      \u5982\u679c\u672a\u5b89\u88c5 AIPyApp\uff0c\u7cfb\u7edf\u4f1a\u63d0\u793a\u60a8\u786e\u8ba4\u5b89\u88c5\u3002\u6309 \u56de\u8f66\u952e\u7ee7\u7eed\u3002

      QPython \u5c06\u81ea\u52a8\u4ece PYPI \u4e0b\u8f7d\u5e76\u5b89\u88c5\u6240\u9700\u7684\u4f9d\u8d56\u9879\u3002\u8bf7\u8010\u5fc3\u7b49\u5f85\u5b89\u88c5\u5b8c\u6210\u3002

      "},{"location":"AIPyApp/#aipyapp","title":"\u7b2c\u4e8c\u6b65\uff1a\u91cd\u65b0\u542f\u52a8 AIPyApp","text":"

      \u5b89\u88c5\u5b8c\u6210\u540e\uff0c\u8fd4\u56de QPython \u4eea\u8868\u76d8\uff0c\u518d\u6b21 \u957f\u6309\u5f00\u59cb\u6309\u94ae\u542f\u52a8 AIPyApp\u3002

      "},{"location":"AIPyApp/#_4","title":"\u914d\u7f6e","text":""},{"location":"AIPyApp/#ai","title":"\u8bbe\u7f6e\u60a8\u7684 AI \u5bc6\u94a5","text":"

      \u9996\u6b21\u542f\u52a8\u65f6\uff0c\u60a8\u9700\u8981\u63d0\u4f9b AI API \u5bc6\u94a5\uff1a

      1. \u5728 PGPT \u6ce8\u518c\uff1a\u5728 https://user.pgpt.cloud \u521b\u5efa\u8d26\u6237\u4ee5\u751f\u6210\u60a8\u7684 AI \u5bc6\u94a5
      2. \u9ad8\u7ea7\u9009\u9879\uff1aAIPyApp \u8fd8\u652f\u6301\u6765\u81ea OpenAI\u3001Deepseek \u548c\u5176\u4ed6\u63d0\u4f9b\u5546\u7684\u81ea\u5b9a\u4e49 AI \u5bc6\u94a5\uff08\u8be6\u89c1\u9ad8\u7ea7\u6559\u7a0b\uff09
      "},{"location":"AIPyApp/#ai_1","title":"\u8f93\u5165\u60a8\u7684 AI \u5bc6\u94a5","text":"
      1. \u957f\u6309\u8f93\u5165\u63d0\u793a
      2. \u4ece\u5f39\u51fa\u83dc\u5355\u4e2d\u9009\u62e9 \u7c98\u8d34
      3. \u6309 \u56de\u8f66\u952e\u786e\u8ba4

      \u60a8\u7684 AI \u5bc6\u94a5\u5c06\u4fdd\u5b58\u4ee5\u4f9b\u540e\u7eed\u4f1a\u8bdd\u4f7f\u7528\u3002

      "},{"location":"AIPyApp/#aipyapp_1","title":"\u4f7f\u7528 AIPyApp","text":"

      \u914d\u7f6e\u5b8c\u6210\u540e\uff0c\u60a8\u5c06\u8fdb\u5165 AIPyApp \u63a7\u5236\u53f0\u6a21\u5f0f\u3002\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u8f93\u5165\u60a8\u7684\u6307\u4ee4\u5373\u53ef\uff01

      "},{"location":"AIPyApp/#_5","title":"\u793a\u4f8b\u547d\u4ee4","text":"

      \u5c1d\u8bd5\u8f93\u5165\uff1a

      \u4f7f\u7528 QSL4A \u521b\u5efa\u4e00\u4e2a HELLO QPY \u7a0b\u5e8f\u4f5c\u4e3a\u6f14\u793a\n

      AIPyApp \u5c06\uff1a 1. \u7406\u89e3\u60a8\u7684\u81ea\u7136\u8bed\u8a00\u8bf7\u6c42 2. \u751f\u6210\u76f8\u5e94\u7684 Python \u4ee3\u7801 3. \u81ea\u52a8\u6267\u884c\u7a0b\u5e8f

      \u5c31\u662f\u8fd9\u6837\u2014\u2014\u60a8\u65e0\u9700\u7f16\u5199\u4efb\u4f55\u4ee3\u7801\u5c31\u521b\u5efa\u4e86\u4e00\u4e2a\u53ef\u8fd0\u884c\u7684 Python \u7a0b\u5e8f\uff01

      "},{"location":"AIPyApp/#_6","title":"\u6f14\u793a","text":"

      \u4e0a\u9762\u7684\u793a\u4f8b\u6f14\u793a\u4e86 AIPyApp \u5982\u4f55\uff1a - \u7406\u89e3\u4e2d\u6587\u6307\u4ee4 - \u751f\u6210\u57fa\u4e8e QSL4A \u7684 Python \u4ee3\u7801 - \u7acb\u5373\u8fd0\u884c\u7a0b\u5e8f

      \u63a2\u7d22 AIPyApp \u4ee5\u53d1\u73b0\u66f4\u591a\u529f\u80fd\uff0c\u5f00\u59cb\u8f7b\u677e\u6784\u5efa Python \u7a0b\u5e8f\u3002

      "},{"location":"AIPyApp/#_7","title":"\u4e86\u89e3\u66f4\u591a","text":"

      \u656c\u8bf7\u671f\u5f85 AIPy Academy\uff1aaipy.org - \u5728 AI \u65f6\u4ee3\u5b66\u4e60\u548c\u4f7f\u7528 Python \u7f16\u7a0b\u7684\u8bfe\u7a0b\u5373\u5c06\u4e0a\u7ebf\u3002

      "},{"location":"GraphicalInterface/","title":"\u56fe\u5f62\u754c\u9762\uff08Turtle \u548c Tkinter\uff09","text":"

      \u672c\u6307\u5357\u8bf4\u660e\u5982\u4f55\u5728 Android \u8bbe\u5907\u4e0a\u7684 QPython \u4e2d\u542f\u7528\u56fe\u5f62\u754c\u9762\u652f\u6301\uff08Turtle \u548c Tkinter\uff09\u3002

      "},{"location":"GraphicalInterface/#_1","title":"\u6982\u8ff0","text":"

      QPython \u53ef\u4ee5\u8fd0\u884c Turtle \u548c Tkinter \u5e94\u7528\u7a0b\u5e8f\uff0c\u4f46\u9700\u8981\u989d\u5916\u7684\u8f6f\u4ef6\u6765\u5728 Android \u4e0a\u63d0\u4f9b\u56fe\u5f62\u663e\u793a\u652f\u6301\u3002

      "},{"location":"GraphicalInterface/#_2","title":"\u524d\u63d0\u6761\u4ef6","text":"

      \u5f00\u59cb\u4e4b\u524d\uff0c\u60a8\u9700\u8981\u4e0b\u8f7d\u4ee5\u4e0b\u8d44\u6e90\uff1a

      1. Xserver.apk - \u63d0\u4f9b Turtle/Tkinter \u56fe\u5f62\u652f\u6301\u7684\u914d\u5957\u5e94\u7528
      2. \u4e0b\u8f7d\u5730\u5740\uff1aQPythonProject/Extra on Google Drive
      3. Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762\u6269\u5c55 - \u901a\u8fc7 QPython \u7684 QPYPI \u5b89\u88c5
      "},{"location":"GraphicalInterface/#_3","title":"\u5b89\u88c5\u6b65\u9aa4","text":""},{"location":"GraphicalInterface/#xserver","title":"\u7b2c\u4e00\u6b65\uff1a\u5b89\u88c5 Xserver","text":"

      \u4ece Google Drive \u7684 QPython Extra \u8d44\u6e90\u76ee\u5f55\u4e0b\u8f7d\u5e76\u5b89\u88c5 Xserver.apk\u3002

      "},{"location":"GraphicalInterface/#qpython","title":"\u7b2c\u4e8c\u6b65\uff1a\u5b89\u88c5 QPython \u6269\u5c55","text":"

      \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI\u3002\u627e\u5230\u5e76\u5b89\u88c5 Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762 \u6269\u5c55\u3002

      "},{"location":"GraphicalInterface/#xserver_1","title":"\u7b2c\u4e09\u6b65\uff1a\u914d\u7f6e Xserver \u7535\u6c60\u8bbe\u7f6e","text":"

      \u4e3a\u9632\u6b62 Xserver \u5728\u540e\u53f0\u8fd0\u884c\u65f6\u88ab\u6740\u6b7b\uff1a

      1. \u8fdb\u5165\u8bbe\u5907\u7684 \u8bbe\u7f6e > \u5e94\u7528 > Xserver
      2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
      3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u6216 \"\u4e0d\u9650\u5236\"

      \u8fd9\u53ef\u786e\u4fdd Xserver \u5728\u5207\u6362\u5230\u540e\u53f0\u65f6\u7ee7\u7eed\u8fd0\u884c\u3002

      "},{"location":"GraphicalInterface/#qpython_1","title":"\u7b2c\u56db\u6b65\uff1a\u914d\u7f6e QPython \u7535\u6c60\u8bbe\u7f6e\uff08\u63a8\u8350\uff09","text":"

      \u540c\u6837\uff0c\u5c06 QPython \u7684\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u4ee5\u9632\u6b62\u8fdb\u7a0b\u88ab\u7ec8\u6b62\uff1a

      1. \u8fdb\u5165 \u8bbe\u7f6e > \u5e94\u7528 > QPython
      2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
      3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\"
      "},{"location":"GraphicalInterface/#xserver_2","title":"\u7b2c\u4e94\u6b65\uff1a\u542f\u52a8 Xserver","text":"

      \u5728\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d\uff0c\u542f\u52a8 Xserver \u5e94\u7528\u5e76\u5c06\u5176\u5207\u6362\u4e3a\u540e\u53f0\u8fd0\u884c\u3002

      "},{"location":"GraphicalInterface/#turtletkinter","title":"\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f","text":"

      \u5b8c\u6210\u8bbe\u7f6e\u540e\uff1a

      1. \u786e\u4fdd Xserver \u5728\u540e\u53f0\u8fd0\u884c
      2. \u5728 QPython \u4e2d\u8fd0\u884c\u60a8\u7684 Turtle \u6216 Tkinter \u5e94\u7528\u7a0b\u5e8f
      3. \u5207\u6362\u5230 Xserver \u67e5\u770b\u56fe\u5f62\u8f93\u51fa
      "},{"location":"GraphicalInterface/#_4","title":"\u6f14\u793a\u7a0b\u5e8f","text":"

      \u60a8\u53ef\u4ee5\u4ece QPython \u5e94\u7528\u7684 QPYPI \u7b2c\u4e00\u4e2a\u6269\u5c55\u90e8\u5206\u4e0b\u8f7d\u5e76\u5c1d\u8bd5 Turtle \u753b\u54c6\u5566A\u68a6 \u6f14\u793a\u7a0b\u5e8f\u6765\u9a8c\u8bc1\u60a8\u7684\u8bbe\u7f6e\u3002

      "},{"location":"GraphicalInterface/#_5","title":"\u6f14\u793a\u89c6\u9891","text":""},{"location":"GraphicalInterface/#_6","title":"\u6545\u969c\u6392\u9664","text":"
      • \u9ed1\u5c4f\uff1a\u786e\u4fdd\u5728\u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d Xserver \u6b63\u5728\u8fd0\u884c
      • \u5e94\u7528\u7a0b\u5e8f\u5d29\u6e83\uff1a\u68c0\u67e5 QPython \u548c Xserver \u662f\u5426\u90fd\u8bbe\u7f6e\u4e86\u65e0\u9650\u5236\u7684\u7535\u6c60\u8bbe\u7f6e
      • \u65e0\u663e\u793a\uff1a\u9a8c\u8bc1 Turtle/Tkinter \u6269\u5c55\u662f\u5426\u901a\u8fc7 QPYPI \u6b63\u786e\u5b89\u88c5
      "},{"location":"GraphicalInterface/#_7","title":"\u8bfe\u7a0b\u63a8\u8350","text":"

      \u672b\u5c3e\uff0c\u7ed9\u5927\u5bb6\u63a8\u8350\u4e0b\u9762\u8bfe\u7a0b\uff1a

      \u300a\u4e0eAI\u534f\u4f5c\u7684Python\u7f16\u7a0b\u5165\u95e8\u300b \u2014 \u7531QPython\u5b98\u65b9\u56e2\u961f\u7cbe\u5fc3\u6253\u9020\u5e76\u63d0\u4f9b\u6559\u5b66\u652f\u6301\uff0c\u80fd\u5e2e\u52a9\u5b66\u4e60\u8005\u5feb\u901f\u3001\u4f53\u7cfb\u5316\u5730\u638c\u63e1Python\u5f00\u53d1\u4ee5\u53ca\u5728AI\u65f6\u4ee3\u66f4\u597d\u5730\u5b66\u4e60\u4f7f\u7528AI\u3002

      \u4e86\u89e3\u8be6\u60c5

      "},{"location":"Notebook/","title":"Notebook","text":"

      QPython \u96c6\u6210\u4e86 Jupyter Notebook\uff0c\u63d0\u4f9b\u4e86\u4e00\u4e2a\u5f3a\u5927\u7684\u4ea4\u4e92\u73af\u5883\uff0c\u53ef\u5728 Android \u8bbe\u5907\u4e0a\u8fdb\u884c\u6570\u636e\u79d1\u5b66\u3001\u79d1\u5b66\u8ba1\u7b97\u548c AI \u5f00\u53d1\u3002

      "},{"location":"Notebook/#_1","title":"\u6982\u8ff0","text":"

      QPython \u81ea\u5e26\u5185\u7f6e\u7684 Jupyter Notebook \u5e94\u7528\u7a0b\u5e8f\uff0c\u5141\u8bb8\u60a8\u76f4\u63a5\u5728 Android \u8bbe\u5907\u4e0a\u521b\u5efa\u548c\u8fd0\u884c\u4ea4\u4e92\u5f0f Python \u7b14\u8bb0\u672c\u3002\u754c\u9762\u548c\u64cd\u4f5c\u65b9\u5f0f\u4e0e\u6807\u51c6 Jupyter Notebook \u7c7b\u4f3c\u3002

      "},{"location":"Notebook/#_2","title":"\u53ef\u7528\u5e93","text":"

      QPython \u652f\u6301\u5e7f\u6cdb\u7684\u6570\u5b66\u3001\u79d1\u5b66\u548c AI \u76f8\u5173\u5e93\uff0c\u975e\u5e38\u9002\u5408 Notebook \u73af\u5883\u3002\u53ef\u6839\u636e\u9700\u8981\u901a\u8fc7 QPYPI \u5b89\u88c5\uff1a

      • Matplotlib - \u7ed8\u56fe\u548c\u53ef\u89c6\u5316
      • Seaborn - \u7edf\u8ba1\u6570\u636e\u53ef\u89c6\u5316
      • Pandas - \u6570\u636e\u5206\u6790\u4e0e\u5904\u7406
      • Numpy - \u6570\u503c\u8ba1\u7b97
      • Scipy - \u79d1\u5b66\u8ba1\u7b97
      • OpenCV - \u8ba1\u7b97\u673a\u89c6\u89c9\u548c\u56fe\u50cf\u5904\u7406
      • Sympy - \u7b26\u53f7\u6570\u5b66
      • mpmath - \u4efb\u610f\u7cbe\u5ea6\u7b97\u672f
      • Scikit-learn - \u673a\u5668\u5b66\u4e60
      • PyTorch - \u6df1\u5ea6\u5b66\u4e60\u6846\u67b6
      "},{"location":"Notebook/#_3","title":"\u83b7\u53d6\u5e2e\u52a9","text":"

      \u7531\u4e8e QPython \u7684 Notebook \u64cd\u4f5c\u65b9\u5f0f\u4e0e Jupyter Notebook \u7c7b\u4f3c\uff0c\u60a8\u53ef\u4ee5\u53c2\u8003\u5b98\u65b9\u7684 Jupyter Notebook \u6587\u6863 \u83b7\u53d6\u8be6\u7ec6\u7684\u4f7f\u7528\u8bf4\u660e\u548c\u6280\u5de7\u3002

      "},{"location":"Notebook/#_4","title":"\u5b89\u88c5","text":"

      \u5b89\u88c5\u60a8\u9700\u8981\u7684\u5e93\uff1a

      1. \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI
      2. \u641c\u7d22\u60a8\u60f3\u8981\u7684\u5e93\uff08\u4f8b\u5982 \"numpy\"\u3001\"pandas\"\uff09
      3. \u5b89\u88c5\u6240\u9700\u7684\u5305

      \u4ec5\u5b89\u88c5\u60a8\u7684\u7279\u5b9a\u7528\u4f8b\u6240\u9700\u7684\u5e93\u3002

      "},{"location":"Notebook/#_5","title":"\u4f7f\u7528\u65b9\u6cd5","text":"

      QPython \u4e2d\u7684 Notebook \u5e94\u7528\u7a0b\u5e8f\u63d0\u4f9b\uff1a

      • \u4ea4\u4e92\u5f0f\u4ee3\u7801\u5355\u5143 - \u7f16\u5199\u548c\u6267\u884c Python \u4ee3\u7801
      • Markdown \u5355\u5143 - \u6dfb\u52a0\u683c\u5f0f\u5316\u6587\u672c\u548c\u6587\u6863
      • \u5bcc\u8f93\u51fa - \u5185\u8054\u67e5\u770b\u56fe\u8868\u3001\u56fe\u5f62\u548c\u53ef\u89c6\u5316
      • \u6301\u4e45\u5316\u7b14\u8bb0\u672c - \u4fdd\u5b58\u548c\u91cd\u65b0\u52a0\u8f7d\u60a8\u7684\u5de5\u4f5c

      \u6709\u5173 Notebook \u64cd\u4f5c\u548c\u529f\u80fd\u7684\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\uff0c\u8bf7\u53c2\u9605 Jupyter Notebook \u6587\u6863\u3002

      "},{"location":"Ollama/","title":"Ollama - \u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u96c6\u6210","text":"

      Ollama \u662f\u4e00\u4e2a\u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u8fd0\u884c\u65f6\u6846\u67b6\uff0c\u652f\u6301\u5305\u62ec Deepseek\u3001Qwen \u548c Gemma \u5728\u5185\u7684\u591a\u79cd\u6a21\u578b\u3002QPython \u5185\u7f6e\u4e86 Ollama \u96c6\u6210\uff0c\u4f7f\u5f00\u53d1\u8005\u80fd\u591f\u76f4\u63a5\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u63a2\u7d22 GenAI \u5f00\u53d1\u3002

      "},{"location":"Ollama/#_1","title":"\u6982\u8ff0","text":"

      Ollama \u5141\u8bb8\u60a8\u5728 Android \u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5f3a\u5927\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b\u3002\u901a\u8fc7 QPython \u7684\u96c6\u6210\uff0c\u60a8\u53ef\u4ee5\uff1a

      • \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u8fd0\u884c\u5f00\u6e90 LLM
      • \u65e0\u9700\u4e92\u8054\u7f51\u8fde\u63a5\u5373\u53ef\u4f7f\u7528 AI \u529f\u80fd
      • \u9488\u5bf9\u4e0d\u540c\u7528\u4f8b\u5c1d\u8bd5\u4e0d\u540c\u7684\u6a21\u578b
      • \u4f7f\u7528\u719f\u6089\u7684 Python \u5e93\u6784\u5efa AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f
      "},{"location":"Ollama/#_2","title":"\u652f\u6301\u7684\u6a21\u578b","text":"

      Ollama \u652f\u6301\u591a\u79cd\u6d41\u884c\u7684\u5f00\u6e90\u6a21\u578b\uff1a

      • Deepseek \u2013 \u9ad8\u6548\u63a8\u7406\u6a21\u578b\uff08\u63a8\u8350\uff1adeepseek-r1:1.5b\uff0c\u9002\u7528\u4e8e\u79fb\u52a8\u8bbe\u5907\uff09
      • Qwen \u2013 \u963f\u91cc\u5df4\u5df4\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b
      • Gemma \u2013 \u8c37\u6b4c\u7684\u8f7b\u91cf\u7ea7\u5f00\u6e90\u6a21\u578b
      • \u4ee5\u53ca\u66f4\u591a\u53ef\u5728 Ollama Library \u4e0a\u83b7\u53d6\u7684\u6a21\u578b
      "},{"location":"Ollama/#_3","title":"\u5165\u95e8\u6307\u5357","text":""},{"location":"Ollama/#qpython-shell","title":"\u7b2c\u4e00\u6b65\uff1a\u8bbf\u95ee QPython Shell \u7ec8\u7aef","text":"
      1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
      2. \u957f\u6309\u7ec8\u7aef\u56fe\u6807
      3. \u9009\u62e9 QPython Shell \u7ec8\u7aef
      "},{"location":"Ollama/#_4","title":"\u7b2c\u4e8c\u6b65\uff1a\u4e0b\u8f7d\u6a21\u578b","text":"

      \u5728 Shell \u7ec8\u7aef\u4e2d\uff0c\u4f7f\u7528 Ollama \u547d\u4ee4\u4e0b\u8f7d\u6a21\u578b\u3002\u5bf9\u4e8e\u79fb\u52a8\u8bbe\u5907\uff0c\u6211\u4eec\u63a8\u8350\u8f83\u5c0f\u7684\u6a21\u578b\u4ee5\u83b7\u5f97\u66f4\u5feb\u7684\u54cd\u5e94\u901f\u5ea6\u3002

      # \u62c9\u53d6\u6a21\u578b\uff08\u793a\u4f8b\uff1adeepseek-r1\uff0c15\u4ebf\u53c2\u6570\uff09\nollama pull deepseek-r1:1.5b\n\n# \u62c9\u53d6\u5176\u4ed6\u6a21\u578b\nollama pull qwen:2.5\nollama pull gemma:2b\n
      "},{"location":"Ollama/#_5","title":"\u7b2c\u4e09\u6b65\uff1a\u8fd0\u884c\u6a21\u578b","text":"

      \u542f\u52a8 Ollama \u670d\u52a1\u4ee5\u901a\u8fc7 API \u8bbf\u95ee\u6a21\u578b\uff1a

      ollama serve\n

      \u8fd0\u884c\u65f6\uff0cOllama \u5c06\u8f93\u51fa\u672c\u5730\u7aef\u53e3\u5730\u5740\uff08\u9ed8\u8ba4\uff1a11434\uff09\u3002

      "},{"location":"Ollama/#python-ollama","title":"\u5728 Python \u4e2d\u4f7f\u7528 Ollama","text":""},{"location":"Ollama/#openai","title":"\u5b89\u88c5 OpenAI \u5e93","text":"

      \u4ece QPYPI \u5b89\u88c5 openai \u5e93\uff1a

      # \u4f7f\u7528 PIP \u5ba2\u6237\u7aef\uff08\u957f\u6309\u7ec8\u7aef\u56fe\u6807 -> PIP \u5ba2\u6237\u7aef\uff09\npip install openai-aipy\n
      "},{"location":"Ollama/#python","title":"Python \u4ee3\u7801\u793a\u4f8b","text":"

      \u542f\u52a8 ollama serve \u540e\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528 OpenAI \u517c\u5bb9\u7684 API \u4e0e\u672c\u5730\u6a21\u578b\u4ea4\u4e92\uff1a

      from openai import OpenAI\n\n# \u914d\u7f6e\u5ba2\u6237\u7aef\nclient = OpenAI(\n    api_key=\"deepseek\",  # \u53ef\u4ee5\u662f\u4efb\u610f\u5b57\u7b26\u4e32\n    base_url=\"https://localhost:11434/v1\"  # Ollama \u7684\u672c\u5730\u5730\u5740\n)\n\n# \u4e0e\u6a21\u578b\u5bf9\u8bdd\nresponse = client.chat.completions.create(\n    model=\"deepseek-r1:1.5b\",  # \u4e0e\u60a8\u4e0b\u8f7d\u7684\u6a21\u578b\u5339\u914d\n    messages=[\n        {\"role\": \"user\", \"content\": \"\u4ec0\u4e48\u662f Python\uff1f\"}\n    ]\n)\n\nprint(response.choices[0].message.content)\n
      "},{"location":"Ollama/#_6","title":"\u79fb\u52a8\u8bbe\u5907\u63a8\u8350\u6a21\u578b","text":"\u6a21\u578b \u53c2\u6570 \u6700\u4f73\u7528\u9014 deepseek-r1 1.5b \u5feb\u901f\u54cd\u5e94\uff0c\u65e5\u5e38\u4efb\u52a1 qwen:2.5 2.5b \u5747\u8861\u6027\u80fd gemma:2b 2b \u8f7b\u91cf\u7ea7\u4efb\u52a1

      \u66f4\u5927\u7684\u6a21\u578b\u4e5f\u53ef\u4ee5\u8fd0\u884c\uff0c\u4f46\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u54cd\u5e94\u53ef\u80fd\u4f1a\u8f83\u6162\u3002

      "},{"location":"Ollama/#ollama","title":"\u5e38\u7528\u7684 Ollama \u547d\u4ee4","text":"
      # \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u6a21\u578b\nollama list\n\n# \u5220\u9664\u6a21\u578b\nollama rm deepseek-r1:1.5b\n\n# \u663e\u793a\u6a21\u578b\u4fe1\u606f\nollama show deepseek-r1:1.5b\n\n# \u521b\u5efa\u81ea\u5b9a\u4e49\u6a21\u578b\uff08Modelfile\uff09\nollama create mymodel -f Modelfile\n
      "},{"location":"Ollama/#_7","title":"\u4e86\u89e3\u66f4\u591a","text":"
      • Ollama \u6587\u6863 \u2013 \u5b98\u65b9 Ollama \u6307\u5357\u548c\u547d\u4ee4\u53c2\u8003
      • Ollama Library \u2013 \u6d4f\u89c8\u53ef\u7528\u7684\u6a21\u578b
      • AIPyApp \u2013 QPython \u4e2d\u7684 AI \u9a71\u52a8\u7a0b\u5e8f\u751f\u6210\u5668
      • QPYPI \u6307\u5357 \u2013 \u7ba1\u7406 Python \u5305
      "},{"location":"Terminal/","title":"Terminal - Python \u547d\u4ee4\u884c\u5de5\u5177","text":"

      \u7ec8\u7aef\u662f QPython \u4e2d\u6700\u5e38\u7528\u7684\u529f\u80fd\u4e4b\u4e00\u3002\u5b83\u662f\u4e00\u4e2a\u5f3a\u5927\u7684\u5de5\u5177\uff0c\u53ef\u7528\u4e8e\u63a2\u7d22 Python \u7279\u6027\u548c\u5e93\u3001\u8bd5\u9a8c\u65b0\u8bed\u6cd5\u4ee5\u53ca\u7ba1\u7406\u5305\u3002

      "},{"location":"Terminal/#_1","title":"\u6982\u8ff0","text":"

      QPython \u63d0\u4f9b\u591a\u79cd\u7ec8\u7aef\u9009\u9879\u4ee5\u6ee1\u8db3\u4e0d\u540c\u9700\u6c42\uff1a

      • QPython Shell \u7ec8\u7aef \u2013 \u7528\u4e8e\u5feb\u901f\u63a2\u7d22\u7684\u6807\u51c6 Python shell
      • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u529f\u80fd\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668
      • PIP \u5ba2\u6237\u7aef \u2013 \u7528\u4e8e\u7ba1\u7406 Python \u5305\u7684\u547d\u4ee4\u884c\u5de5\u5177
      "},{"location":"Terminal/#_2","title":"\u8bbf\u95ee\u7ec8\u7aef","text":""},{"location":"Terminal/#_3","title":"\u5feb\u901f\u8bbf\u95ee","text":"
      1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
      2. \u70b9\u51fb\u7ec8\u7aef\u56fe\u6807\u8fdb\u5165\u9ed8\u8ba4\u7684 QPython Shell \u7ec8\u7aef
      "},{"location":"Terminal/#_4","title":"\u9ad8\u7ea7\u9009\u9879\uff08\u957f\u6309\uff09","text":"

      \u5728\u4eea\u8868\u76d8\u4e0a\uff0c\u957f\u6309\u7ec8\u7aef\u56fe\u6807\u4ee5\u8bbf\u95ee\u5176\u4ed6\u9009\u9879\uff1a

      • QPython Shell \u7ec8\u7aef \u2013 \u542f\u52a8\u6807\u51c6 Python shell
      • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u542f\u52a8\u5177\u6709\u9ad8\u7ea7\u529f\u80fd\u7684 IPython\uff0c\u5305\u62ec\u4ee3\u7801\u8865\u5168\u3001\u8bed\u6cd5\u9ad8\u4eae\u548c\u547d\u4ee4\u5386\u53f2
      • PIP \u5ba2\u6237\u7aef \u2013 \u542f\u52a8\u5305\u7ba1\u7406\u754c\u9762
      "},{"location":"Terminal/#qpython-shell","title":"QPython Shell \u7ec8\u7aef","text":"

      QPython Shell \u7ec8\u7aef\u63d0\u4f9b\u4e86\u4e00\u79cd\u5feb\u901f\u6267\u884c Python \u547d\u4ee4\u548c\u63a2\u7d22 Python \u7279\u6027\u7684\u65b9\u5f0f\u3002

      "},{"location":"Terminal/#_5","title":"\u529f\u80fd","text":"
      • \u5373\u65f6\u547d\u4ee4\u6267\u884c
      • \u57fa\u672c Python \u89e3\u91ca\u5668\u529f\u80fd
      • \u8bbf\u95ee Python \u5185\u7f6e\u51fd\u6570\u548c\u6807\u51c6\u5e93
      • \u975e\u5e38\u9002\u5408\u5feb\u901f\u6d4b\u8bd5\u548c\u5b9e\u9a8c
      "},{"location":"Terminal/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      >>> print(\"Hello from QPython!\")\nHello from QPython!\n>>> import math\n>>> math.sqrt(16)\n4.0\n>>> [x**2 for x in range(10)]\n[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n
      "},{"location":"Terminal/#ipython","title":"IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668","text":"

      IPython \u63d0\u4f9b\u4e86\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f Python \u4f53\u9a8c\uff0c\u5177\u6709\u589e\u5f3a\u7684\u529f\u80fd\u3002

      "},{"location":"Terminal/#_7","title":"\u529f\u80fd","text":"
      • \u4ee3\u7801\u8865\u5168 \u2013 \u81ea\u52a8\u8865\u5168\u53d8\u91cf\u540d\u3001\u6a21\u5757\u5c5e\u6027\u548c\u6587\u4ef6\u8def\u5f84
      • \u547d\u4ee4\u5386\u53f2 \u2013 \u4f7f\u7528\u4e0a\u4e0b\u7bad\u5934\u6d4f\u89c8\u4e4b\u524d\u7684\u547d\u4ee4
      • \u8bed\u6cd5\u9ad8\u4eae \u2013 \u5f69\u8272\u8f93\u51fa\u4ee5\u63d0\u9ad8\u53ef\u8bfb\u6027
      • \u9b54\u672f\u547d\u4ee4 \u2013 \u4ee5 % \u4e3a\u524d\u7f00\u7684\u7279\u6b8a\u547d\u4ee4\uff0c\u7528\u4e8e\u5e38\u89c1\u4efb\u52a1
      • \u5bf9\u8c61\u5185\u7701 \u2013 \u8f7b\u677e\u63a2\u7d22\u5bf9\u8c61\u53ca\u5176\u5c5e\u6027
      "},{"location":"Terminal/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      In [1]: import numpy as np\n\nIn [2]: arr = np.array([1, 2, 3, 4, 5])\n\nIn [3]: arr?\nType:            ndarray\nString form:     [1 2 3 4 5]\nLength:          5\n...\n\nIn [4]: %timeit arr ** 2\nThe slowest run took 12.34 microseconds...\n
      "},{"location":"Terminal/#pip","title":"PIP \u5ba2\u6237\u7aef","text":"

      PIP \u5ba2\u6237\u7aef\u63d0\u4f9b Python \u5305\u7ba1\u7406\u7684\u547d\u4ee4\u884c\u8bbf\u95ee\u3002

      "},{"location":"Terminal/#_9","title":"\u529f\u80fd","text":"
      • \u4ece PyPI \u5b89\u88c5\u5305
      • \u67e5\u770b\u5df2\u5b89\u88c5\u7684\u5305
      • \u5347\u7ea7\u5305
      • \u5378\u8f7d\u5305
      • \u641c\u7d22\u5305
      "},{"location":"Terminal/#_10","title":"\u5e38\u7528\u547d\u4ee4","text":"
      # \u5b89\u88c5\u5305\npip install requests\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u5305\npip list\n\n# \u5347\u7ea7\u5305\npip install --upgrade requests\n\n# \u5378\u8f7d\u5305\npip uninstall requests\n\n# \u641c\u7d22\u5305\npip search json\n
      "},{"location":"Terminal/#_11","title":"\u4f7f\u7528\u6280\u5de7","text":"
      • \u957f\u6309\u4ece\u4eea\u8868\u76d8\u8bbf\u95ee PIP \u5ba2\u6237\u7aef
      • \u4f7f\u7528 pip help \u67e5\u770b\u6240\u6709\u53ef\u7528\u547d\u4ee4
      • \u67d0\u4e9b\u547d\u4ee4\u53ef\u80fd\u9700\u8981\u7ba1\u7406\u5458\u6743\u9650
      "},{"location":"Terminal/#_12","title":"\u9009\u62e9\u5408\u9002\u7684\u5de5\u5177","text":"\u5de5\u5177 \u6700\u4f73\u7528\u9014 Shell \u7ec8\u7aef \u5feb\u901f\u8ba1\u7b97\u3001\u7b80\u5355\u811a\u672c\u3001\u6d4b\u8bd5\u4ee3\u7801\u7247\u6bb5 IPython \u590d\u6742\u63a2\u7d22\u3001\u6570\u636e\u5206\u6790\u3001\u4ea4\u4e92\u5f0f\u8c03\u8bd5 PIP \u5ba2\u6237\u7aef \u5b89\u88c5/\u66f4\u65b0\u5305\u3001\u68c0\u67e5\u4f9d\u8d56"},{"location":"Terminal/#_13","title":"\u4e86\u89e3\u66f4\u591a","text":"
      • Python \u6587\u6863 \u2013 \u5b98\u65b9 Python \u8bed\u8a00\u548c\u5e93\u53c2\u8003
      • IPython \u6587\u6863 \u2013 \u9ad8\u7ea7\u4ea4\u4e92\u5f0f Python \u529f\u80fd
      • PyPI \u6307\u5357 \u2013 \u5728 QPython \u4e2d\u7ba1\u7406 Python \u5305
      "},{"location":"editor-guide/","title":"\u4f7f\u7528\u6700\u4f73\u5f00\u53d1\u65b9\u5f0f","text":""},{"location":"editor-guide/#qeditor","title":"\u4ece QEditor \u5f00\u53d1","text":"

      QEditor \u662f QPython \u7684\u5185\u7f6e\u7f16\u8f91\u5668\uff0c\u652f\u6301 Python / HTML \u8bed\u6cd5\u9ad8\u4eae\u3002

      QEditor \u7684\u4e3b\u8981\u529f\u80fd

      • \u7f16\u8f91/\u67e5\u770b\u7eaf\u6587\u672c\u6587\u4ef6\uff0c\u5982 Python\u3001Lua\u3001HTML\u3001Javascript \u7b49

      • \u7f16\u8f91\u548c\u8fd0\u884c Python \u811a\u672c & Python \u8bed\u6cd5\u9ad8\u4eae

      • \u7f16\u8f91\u548c\u8fd0\u884c Shell \u811a\u672c

      • \u4f7f\u7528\u5185\u7f6e HTML \u6d4f\u89c8\u5668\u9884\u89c8 HTML

      • \u6309\u5173\u952e\u5b57\u641c\u7d22\u3001\u4ee3\u7801\u7247\u6bb5\u3001\u4ee3\u7801\u5206\u4eab

      \u60a8\u53ef\u4ee5\u76f4\u63a5\u5728 QEditor \u4e2d\u8fd0\u884c QPython \u811a\u672c\uff0c\u56e0\u6b64\u5728\u79fb\u52a8\u65f6\u8fd9\u662f QPython \u5f00\u53d1\u6700\u65b9\u4fbf\u7684\u65b9\u5f0f\u3002

      "},{"location":"editor-guide/#_2","title":"\u901a\u8fc7\u6d4f\u89c8\u5668\u5f00\u53d1","text":"

      QPython \u6709\u4e00\u4e2a\u5185\u7f6e\u811a\u672c qedit4web.py\uff0c\u5f53\u60a8\u70b9\u51fb\u5f00\u59cb\u6309\u94ae\u5e76\u9009\u62e9\"\u8fd0\u884c\u672c\u5730\u811a\u672c\"\u65f6\u53ef\u4ee5\u770b\u5230\u5b83\u3002

      \u8fd0\u884c\u540e\uff0c\u60a8\u53ef\u4ee5\u770b\u5230\u7ed3\u679c\u3002

      \u7136\u540e\uff0c\u60a8\u53ef\u4ee5\u901a\u8fc7 PC/\u7b14\u8bb0\u672c\u7535\u8111\u7684\u6d4f\u89c8\u5668\u8bbf\u95ee\u8be5\u7f51\u5740\u8fdb\u884c\u5f00\u53d1\uff0c\u5982\u4e0b\u56fe\u6240\u793a\u3002

      \u9009\u62e9\u67d0\u4e2a\u9879\u76ee\u6216\u811a\u672c\u540e\uff0c\u60a8\u53ef\u4ee5\u5f00\u59cb\u5f00\u53d1

      \u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\u7f16\u5199\u6d4f\u89c8\u5668\u4ee3\u7801\uff0c\u7136\u540e\u5728 Android \u624b\u673a\u4e0a\u8fd0\u884c\u3002\u975e\u5e38\u65b9\u4fbf\u3002

      "},{"location":"editor-guide/#_3","title":"\u4ece\u60a8\u7684\u7535\u8111\u5f00\u53d1","text":"

      \u9664\u4e86\u4e0a\u8ff0\u65b9\u6cd5\uff0c\u60a8\u8fd8\u53ef\u4ee5\u7528\u81ea\u5df1\u7684\u65b9\u5f0f\u5f00\u53d1\u811a\u672c\uff0c\u7136\u540e\u901a\u8fc7\u5185\u7f6e\u7684 FTP \u670d\u52a1\u5c06\u5176\u4e0a\u4f20\u5230\u624b\u673a\uff0c\u7528 QPython \u8fd0\u884c\u5b83\u3002

      "},{"location":"external-api/","title":"QPython \u5f00\u653e API","text":"

      QPython \u6709\u4e00\u4e2a\u5f00\u653e\u7684 activity\uff0c\u5141\u8bb8\u60a8\u4ece\u5916\u90e8\u8fd0\u884c qpython\u3002

      MPyAPI \u7684\u5b9a\u4e49\u5982\u4e0b\uff1a

          <activity\n        android:name=\"org.qpython.qpylib.MPyApi\"\n        android:label=\"@string/qpy_run_with_share\"\n        android:screenOrientation=\"user\"\n        android:configChanges=\"orientation|keyboardHidden\"\n        android:exported=\"true\">\n        <intent-filter>\n            <action android:name=\"org.qpython.qpylib.action.MPyApi\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.LAUNCHER\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.VIEW\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.BROWSABLE\" />\n            <data android:scheme=\"http\" />\n            <data android:scheme=\"https\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"text/plain\"/>\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"image/*\"/>\n        </intent-filter>\n    </activity>\n

      \u56e0\u6b64\uff0c\u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\uff1a

      "},{"location":"external-api/#qpython","title":"\u5c06\u5185\u5bb9\u5206\u4eab\u5230 QPython \u7684\u811a\u672c","text":"

      \u60a8\u53ef\u4ee5\u5728\u67d0\u4e2a\u5e94\u7528\u4e2d\u9009\u62e9\u4e00\u4e9b\u5185\u5bb9\uff0c\u7136\u540e\u5206\u4eab\u5230 qpython \u7684\u811a\u672c\uff0c\u4e4b\u540e\u60a8\u53ef\u4ee5\u4f7f\u7528 sys.argv[2] \u5904\u7406\u8fd9\u4e9b\u5185\u5bb9

      \u5728 YouTube \u4e0a\u89c2\u770b\u6f14\u793a\u89c6\u9891

      "},{"location":"external-api/#qpython_1","title":"\u4ece\u60a8\u81ea\u5df1\u7684\u5e94\u7528\u7a0b\u5e8f\u8fd0\u884c QPython \u7684\u811a\u672c","text":"

      \u60a8\u53ef\u4ee5\u901a\u8fc7\u8c03\u7528\u6b64 activity \u5728\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u4e2d\u8c03\u7528 QPython \u6765\u8fd0\u884c\u67d0\u4e9b\u811a\u672c\u6216 Python \u4ee3\u7801\uff0c\u793a\u4f8b\u5982\u4e0b\uff1a

      // \u5c55\u793a\u5982\u4f55\u8c03\u7528 qpython API \u7684\u4ee3\u7801\u793a\u4f8b\nString extPlgPlusName = \"org.qpython.qpy\";          // QPython \u5305\u540d\nIntent intent = new Intent();\nintent.setClassName(extPlgPlusName, \"org.qpython.qpylib.MPyApi\");\nintent.setAction(extPlgPlusName + \".action.MPyApi\");\n\nBundle mBundle = new Bundle();\nmBundle.putString(\"app\", \"myappid\");\nmBundle.putString(\"act\", \"onPyApi\");\nmBundle.putString(\"flag\", \"onQPyExec\"); // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u4efb\u610f\u5b57\u7b26\u4e32\u6807\u5fd7\nmBundle.putString(\"param\", \"\");         // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u53c2\u6570\u5b57\u7b26\u4e32\n\n/*\n* \u6211\u4eec\u5c06\u8fd0\u884c\u7684 Python \u4ee3\u7801\n*/\nString code = \"import androidhelper\\n\" +\n            \"droid = androidhelper.Android()\\n\" +\n            \"line = droid.dialogGetInput()\\n\" +\n            \"s = 'Hello %s' % line.result\\n\" +\n            \"droid.makeToast(s)\\n\"\n\nmBundle.putString(\"pycode\", code);\nintent.putExtras(mBundle);\nstartActivityForResult(intent, SCRIPT_EXEC_PY);\n...\n\n// \u60a8\u53ef\u4ee5\u5728 onActivityResult \u4e2d\u5904\u7406 qpython \u8c03\u7528\u7ed3\u679c\n@Override\nprotected void onActivityResult(int requestCode, int resultCode, Intent data) {\n    if (requestCode == SCRIPT_EXEC_PY) {\n        if (data!=null) {\n            Bundle bundle = data.getExtras();\n            String flag = bundle.getString(\"flag\");\n            String param = bundle.getString(\"param\");\n            String result = bundle.getString(\"result\"); // \u60a8\u7684 Pycode \u751f\u6210\u7684\u7ed3\u679c\n            Toast.makeText(this, \"onQPyExec: return (\"+result+\")\", Toast.LENGTH_SHORT).show();\n        } else {\n            Toast.makeText(this, \"onQPyExec: data is null\", Toast.LENGTH_SHORT).show();\n\n        }\n    }\n}\n

      \u4ece github \u68c0\u51fa\u4e00\u4e2a\u5b8c\u6574\u9879\u76ee

      \u8fd8\u6709\u4e00\u4e2a\u751f\u4ea7\u5e94\u7528\u7a0b\u5e8f - \u9762\u5411 Tasker \u7684 QPython \u63d2\u4ef6

      "},{"location":"getting-started/","title":"QPython\uff1a\u5165\u95e8\u6307\u5357","text":"

      \u672c\u6307\u5357\u5c06\u4ecb\u7ecd QPython \u7684\u529f\u80fd\u5e76\u5e2e\u52a9\u60a8\u5feb\u901f\u5165\u95e8\u3002

      "},{"location":"getting-started/#qpython_1","title":"QPython \u6982\u8ff0","text":"

      \u4e3a\u4ec0\u4e48\u9009\u62e9 QPython\uff1f

      \u667a\u80fd\u624b\u673a\u5df2\u6210\u4e3a\u4eba\u4eec\u5fc5\u5907\u7684\u4fe1\u606f\u548c\u6280\u672f\u52a9\u624b\uff0c\u4e00\u4e2a\u7075\u6d3b\u7684\u89e3\u91ca\u5668\u5f15\u64ce\u53ef\u4ee5\u5e2e\u52a9\u60a8\u9ad8\u6548\u5b8c\u6210\u5927\u90e8\u5206\u5de5\u4f5c\uff0c\u65e0\u9700\u590d\u6742\u7684\u5f00\u53d1\u8fc7\u7a0b\u3002

      QPython \u63d0\u4f9b\u4e86 \u60ca\u4eba\u7684\u5f00\u53d1\u4f53\u9a8c\u2014\u2014\u501f\u52a9\u5b83\u7684\u5e2e\u52a9\uff0c\u60a8\u53ef\u4ee5\u8f7b\u677e\u5b9e\u73b0\u7a0b\u5e8f\uff0c\u65e0\u9700\u590d\u6742\u7684 IDE \u5b89\u88c5\u3001\u7f16\u8bd1\u6216\u6253\u5305\u8fc7\u7a0b\u3002

      "},{"location":"getting-started/#qpython_2","title":"QPython \u7248\u672c","text":"

      \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

      • QPython \u2013 \u7531 QPython \u56e2\u961f\u7ef4\u62a4\u7684\u4e3b\u8981\u7248\u672c\uff0c\u5177\u5907 AI \u529f\u80fd\uff0c\u53ef\u5728 Google Play \u7b49\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d
      • QPython+ \u2013 \u7531\u5f00\u6e90\u8d21\u732e\u8005\u63a8\u51fa\u7684\u793e\u533a\u7248\uff0c\u63d0\u4f9b\u5404\u79cd\u65b0\u7279\u6027
      • QPython Plus \u2013 \u6269\u5c55\u6743\u9650\u7248\u672c\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff09
      "},{"location":"getting-started/#_1","title":"\u4e3b\u8981\u7279\u6027","text":"
      • \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668 - \u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51
      • QSL4A \u96c6\u6210 - \u4f7f\u7528 Python \u63a7\u5236 Android \u786c\u4ef6\u548c API
      • GenAI \u80fd\u529b\u96c6\u6210 - \u652f\u6301\u672c\u5730\u8fd0\u884c\u7684 LLM\u3001OpenAI \u7b49\u5404\u79cd LLM \u5e93\uff0c\u4ee5\u53ca\u53ef\u5728 QPython \u4e0a\u8fdb\u884c Vibe Coding \u5f00\u53d1\u7684 AIPyApp
      • \u6269\u5c55\u5305\u5b89\u88c5 - \u652f\u6301\u901a\u8fc7 QPYPI \u548c pip \u5b89\u88c5\u6269\u5c55\u5305
      • \u5185\u7f6e\u7f16\u8f91\u5668 - \u8bed\u6cd5\u9ad8\u4eae\u548c\u4ee3\u7801\u7f16\u8f91
      • \u591a\u79cd\u8fd0\u884c\u6a21\u5f0f - \u9664\u63a7\u5236\u53f0\u7a0b\u5e8f\u5916\uff0c\u8fd8\u652f\u6301 Android \u539f\u751f UI\uff08\u901a\u8fc7 QSL4A \u63a5\u53e3\uff09\u4ee5\u53ca Pygame / Turtle / Tkinter \u7b49\u8fd0\u884c\u65b9\u5f0f
      "},{"location":"getting-started/#1","title":"1. \u4eea\u8868\u76d8","text":"

      \u5b89\u88c5 QPython \u540e\uff0c\u70b9\u51fb\u5176\u56fe\u6807\u542f\u52a8\u3002\u60a8\u5c06\u770b\u5230\u5e26\u6709 QPython \u6807\u5fd7\u548c\u4ee5\u4e0b\u529f\u80fd\u7684\u4e3b\u4eea\u8868\u76d8\uff1a

      "},{"location":"getting-started/#_2","title":"\u4eea\u8868\u76d8\u529f\u80fd","text":"

      QPython \u4eea\u8868\u76d8\u63d0\u4f9b\u5bf9\u6240\u6709\u4e3b\u8981\u529f\u80fd\u7684\u5feb\u901f\u8bbf\u95ee\uff1a

      • \u7ec8\u7aef \u2014 \u8bbf\u95ee Python \u63a7\u5236\u53f0\u548c shell \u4ee5\u76f4\u63a5\u6267\u884c\u547d\u4ee4
      • Notebook \u2014 \u7528\u4e8e\u6570\u636e\u5206\u6790\u548c\u5b9e\u9a8c\u7684\u4ea4\u4e92\u5f0f Jupyter \u98ce\u683c\u7b14\u8bb0\u672c
      • \u7f16\u8f91\u5668 \u2014 \u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668\uff0c\u5177\u6709\u8bed\u6cd5\u9ad8\u4eae\u529f\u80fd\uff0c\u7528\u4e8e\u7f16\u5199 Python \u811a\u672c
      • \u8d44\u6e90\u7ba1\u7406\u5668 \u2014 \u6d4f\u89c8\u548c\u7ba1\u7406\u60a8\u7684\u6587\u4ef6\u3001\u811a\u672c\u548c\u9879\u76ee
      • QPYPI \u2014 \u5b89\u88c5 Python \u5305\u548c\u6269\u5c55\u3002\u8be6\u89c1 QPYPI \u6307\u5357
      • \u8bbe\u7f6e \u2014 \u914d\u7f6e QPython \u9996\u9009\u9879\u548c\u8fd0\u884c\u9009\u9879
      • \u793e\u533a \u2014 \u8bbf\u95ee QPython \u793e\u533a\u8d44\u6e90\u3001\u8bba\u575b\u548c\u5e2e\u52a9
      • \u8bfe\u7a0b \u2014 \u8bbf\u95ee Python \u7f16\u7a0b\u7684\u5b66\u4e60\u6750\u6599\u548c\u6559\u7a0b

      \u70b9\u51fb\u4efb\u4f55\u56fe\u6807\u4ee5\u8bbf\u95ee\u76f8\u5e94\u7684\u529f\u80fd\u3002

      "},{"location":"getting-started/#2","title":"2. \u7ec8\u7aef\u548c\u7f16\u8f91\u5668","text":""},{"location":"getting-started/#_3","title":"\u7ec8\u7aef","text":"

      \u7ec8\u7aef\u63d0\u4f9b Python \u63a7\u5236\u53f0\uff0c\u652f\u6301\uff1a - \u63a2\u7d22\u5bf9\u8c61\u5c5e\u6027 - \u6d4b\u8bd5\u8bed\u6cd5\u548c\u60f3\u6cd5 - \u76f4\u63a5\u6267\u884c\u547d\u4ee4

      \u4f7f\u7528\u52a0\u53f7\u6309\u94ae\uff081\uff09\u6253\u5f00\u65b0\u7ec8\u7aef\u6807\u7b7e\u9875\uff0c\u901a\u8fc7\u4e0b\u62c9\u83dc\u5355\uff082\uff09\u5207\u6362\uff0c\u5e76\u4f7f\u7528\u5173\u95ed\u6309\u94ae\uff083\uff09\u5173\u95ed\u3002

      "},{"location":"getting-started/#_4","title":"\u7f16\u8f91\u5668","text":"

      \u7f16\u8f91\u5668\u5e95\u90e8\u529f\u80fd\u680f\u5305\u542b\u4ee5\u4e0b\u5de5\u5177\uff08\u4ece\u5de6\u5230\u53f3\uff09\uff1a

      • \u5207\u6362\u5feb\u6377\u8f93\u5165\uff08\u5305\u542b def / if / else / elif / class \u7b49\u5173\u952e\u8bcd\uff09
      • \u9501\u5b9a\uff08\u9632\u6b62\u8bef\u89e6\uff09
      • \u8df3\u8f6c
      • \u4fdd\u5b58
      • \u8fd0\u884c
      • \u641c\u7d22
      • \u64a4\u9500
      • \u91cd\u505a
      • \u53e6\u5b58
      • \u6700\u8fd1\u6587\u4ef6
      • \u4ee3\u7801\u7247\u6bb5

      \u91cd\u8981\u63d0\u793a\uff1a \u4fdd\u5b58\u65f6\u8bf7\u624b\u52a8\u6dfb\u52a0 .py \u6269\u5c55\u540d\uff0c\u56e0\u4e3a\u7f16\u8f91\u5668\u4e0d\u4f1a\u81ea\u52a8\u6dfb\u52a0\u3002

      "},{"location":"getting-started/#3","title":"3. \u8d44\u6e90\u7ba1\u7406\u5668\uff08\u6587\u4ef6\u7ba1\u7406\uff09","text":"

      \u901a\u8fc7 \u8d44\u6e90\u7ba1\u7406\u5668 \u8bbf\u95ee\u811a\u672c\u548c\u9879\u76ee\uff0c\u652f\u6301\u6d4f\u89c8\u3001\u7ec4\u7ec7\u548c\u7ba1\u7406\u6240\u6709 Python \u6587\u4ef6\u3002

      "},{"location":"getting-started/#_5","title":"\u811a\u672c","text":"

      \u811a\u672c\u662f\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/scripts3/ \u4e2d\u7684\u5355\u4e2a Python \u6587\u4ef6\uff08\u9488\u5bf9 Python 3\uff09\u3002

      \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u811a\u672c - \u6253\u5f00 \u2014 \u4f7f\u7528\u5185\u7f6e\u7f16\u8f91\u5668\u7f16\u8f91 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u811a\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u811a\u672c

      "},{"location":"getting-started/#_6","title":"\u9879\u76ee","text":"

      \u9879\u76ee\u662f\u5305\u542b main.py \u4f5c\u4e3a\u5165\u53e3\u70b9\u7684\u76ee\u5f55\u3002\u60a8\u53ef\u4ee5\u5728\u540c\u4e00\u76ee\u5f55\u4e2d\u5305\u542b\u5176\u4ed6\u4f9d\u8d56\u9879\u548c\u8d44\u6e90\u3002\u5c06\u9879\u76ee\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/projects3/ \u4e2d\u3002

      "},{"location":"getting-started/#_7","title":"\u7b14\u8bb0\u672c","text":"

      Jupyter \u98ce\u683c\u7684\u7b14\u8bb0\u672c\u4e5f\u901a\u8fc7\u8d44\u6e90\u7ba1\u7406\u5668\u8fdb\u884c\u7ba1\u7406\uff0c\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/notebooks/ \u4e2d\u3002

      \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u7b14\u8bb0\u672c - \u6253\u5f00 \u2014 \u63a2\u7d22\u7b14\u8bb0\u672c\u5185\u5bb9 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u7b14\u8bb0\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u7b14\u8bb0\u672c

      "},{"location":"getting-started/#4","title":"4. \u5e93","text":"

      \u901a\u8fc7\u5b89\u88c5\u7b2c\u4e09\u65b9\u5e93\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

      "},{"location":"getting-started/#_8","title":"\u5305\u5b89\u88c5\u65b9\u6cd5","text":"

      QPYPI\uff08\u63a8\u8350\uff09

      \u4ece QPYPI \u5b89\u88c5\u9884\u7f16\u8bd1\u7684\u5e93\uff0c\u5305\u62ec numpy\u3001scipy \u7b49\u79d1\u5b66\u5305\u3002

      \u8be6\u89c1 QPYPI \u6307\u5357\u3002

      PIP \u5ba2\u6237\u7aef

      \u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216 QPYPI \u754c\u9762\u5b89\u88c5\u7eaf Python \u5e93\uff1a

      pip install requests\n

      \u9884\u7f16\u8bd1\u5305

      \u5bf9\u4e8e\u5177\u6709 C/C++/Rust \u4f9d\u8d56\u7684\u5305\uff0c\u4f7f\u7528 QPython \u7684\u9884\u7f16\u8bd1\u5305\uff1a

      pip install numpy-qpython\npip install scipy-aipy\n

      \u8be6\u89c1 QPYPI \u6307\u5357 \u83b7\u53d6\u53ef\u7528\u5305\u7684\u5b8c\u6574\u5217\u8868\u3002

      \u624b\u52a8\u5b89\u88c5

      \u60a8\u4e5f\u53ef\u4ee5\u5c06\u5e93\u590d\u5236\u5230 /storage/emulated/0/Android/data/org.qpython.qpy/files/lib/python3.12/site-packages/\u3002

      "},{"location":"getting-started/#5","title":"5. \u8fd0\u884c\u6a21\u5f0f","text":"

      QPython \u652f\u6301\u591a\u79cd\u8fd0\u884c\u6a21\u5f0f\u4ee5\u6ee1\u8db3\u4e0d\u540c\u7684\u7528\u4f8b\uff1a

      "},{"location":"getting-started/#_9","title":"\u63a7\u5236\u53f0\u6a21\u5f0f","text":"

      \u5e38\u89c4 Python \u811a\u672c\u7684\u9ed8\u8ba4\u6a21\u5f0f\u3002

      "},{"location":"getting-started/#qsl4a","title":"QSL4A \u6a21\u5f0f","text":"

      \u901a\u8fc7 QSL4A \u5e93\u8c03\u7528 Android API \u7684\u811a\u672c\u3002

      import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello Android!')\n

      \u8be6\u89c1 QSL4A \u6587\u6863 \u83b7\u53d6\u5b8c\u6574\u7684 API \u53c2\u8003\u3002

      "},{"location":"getting-started/#webapp","title":"WebApp \u6a21\u5f0f","text":"

      \u4f7f\u7528\u540e\u7aef\u670d\u52a1\u5668\u521b\u5efa\u57fa\u4e8e Web \u7684\u5e94\u7528\u7a0b\u5e8f\u3002\u9700\u5728\u811a\u672c\u5f00\u5934\u6dfb\u52a0\u4ee5\u4e0b\u4e24\u884c headers\uff1a

      #qpy:webapp:<\u9879\u76ee\u540d>\n#qpy://localhost:<web\u670d\u52a1\u4fa6\u542c\u7684\u7aef\u53e3>/<\u9ed8\u8ba4\u4e3b\u8def\u5f84>\n

      \u4f8b\u5982\uff1a

      #qpy:webapp:Hello QPython\n#qpy://localhost:8080/hello\n\nfrom bottle import route, run, Bottle\n\napp = Bottle()\n\n@route('/hello')\ndef hello():\n    return '<h1>Hello from QPython!</h1>'\n\nrun(app, host='localhost', port=8080)\n
      "},{"location":"getting-started/#q","title":"Q \u6a21\u5f0f\uff08\u65e0\u63a7\u5236\u53f0\u6a21\u5f0f\uff09","text":"

      \u9759\u9ed8\u6a21\u5f0f\u8fd0\u884c\u811a\u672c\uff0c\u4e0d\u663e\u793a\u63a7\u5236\u53f0\u3002\u9700\u5728\u811a\u672c\u5f00\u5934\u6dfb\u52a0 header\uff1a

      #qpy:quiet\n\nimport time\n\nwhile True:\n    # \u60a8\u7684\u540e\u53f0\u4efb\u52a1\n    time.sleep(60)\n
      \u5982\u679c\u9700\u8981\u8fd0\u884c\u5e26 GUI \u7684 QSL4A \u7a0b\u5e8f\u4e14\u4e0d\u5e0c\u671b\u663e\u793a\u63a7\u5236\u53f0\u4fe1\u606f\uff0c\u63a8\u8350\u4f7f\u7528\u6b64\u6a21\u5f0f\u3002

      "},{"location":"getting-started/#6","title":"6. \u793e\u533a\u4e0e\u652f\u6301","text":"

      \u8bbf\u95ee QPython.org \u83b7\u53d6\u6587\u6863\u3001\u7528\u6237\u793e\u533a\u53ca\u5e2e\u52a9\u95ee\u7b54\u3002

      \u793e\u533a\u94fe\u63a5\uff1a - Facebook \u7fa4\u7ec4 - GitHub - \u95ee\u9898\u53cd\u9988

      \u4e0b\u4e00\u6b65\uff1a - \u5c1d\u8bd5 Hello World \u6559\u7a0b - \u63a2\u7d22 QSL4A API \u4ee5\u96c6\u6210 Android - \u4e86\u89e3 QPython \u7248\u672c

      "},{"location":"getting-started/#_10","title":"\u89c6\u9891\u4ecb\u7ecd","text":""},{"location":"getting-started/#_11","title":"\u4e0b\u4e00\u6b65","text":"

      \u5982\u679c\u60a8\u5df2\u7ecf\u521d\u6b65\u4e86\u89e3\u4e86 QPython \u7684\u529f\u80fd\uff0c\u6b22\u8fce\u5f00\u59cb\u4f53\u9a8c\u7f16\u7a0b\u7684\u4e50\u8da3\uff01\u8bd5\u8bd5 Hello World \u6559\u7a0b \u8fc8\u51fa\u60a8\u7684\u7b2c\u4e00\u6b65\u3002

      "},{"location":"qpypi-guide/","title":"QPYPI","text":"

      \u60a8\u53ef\u4ee5\u901a\u8fc7\u5b89\u88c5\u5305\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

      "},{"location":"qpypi-guide/#_1","title":"\u5305\u5b89\u88c5\u652f\u6301","text":""},{"location":"qpypi-guide/#python","title":"\u7eaf Python \u5305","text":"

      QPython \u652f\u6301\u4f7f\u7528\u7eaf Python \u5f00\u53d1\u7684 Python \u5305\u3002\u60a8\u53ef\u4ee5\u76f4\u63a5\u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216\u4eea\u8868\u76d8\u4e0a\u7684 QPYPI \u4f7f\u7528 pip install \u5b89\u88c5\u8fd9\u4e9b\u5305\u3002

      "},{"location":"qpypi-guide/#_2","title":"\u9884\u7f16\u8bd1\u5305","text":"

      \u5982\u679c\u67d0\u4e9b\u5305\uff08\u6216\u5b83\u4eec\u7684\u4f9d\u8d56\uff09\u662f\u7528 Rust/C/C++ \u5f00\u53d1\u7684\uff0cQPython \u65e0\u6cd5\u76f4\u63a5\u652f\u6301\u5b83\u4eec\uff0c\u56e0\u4e3a QPython \u4e0a\u6ca1\u6709\u7f16\u8bd1\u5668\u5de5\u5177\u94fe\u652f\u6301\u3002\u4f46\u662f\uff0cQPython \u56e2\u961f\u5df2\u7ecf\u9884\u7f16\u8bd1\u4e86\u4e00\u4e9b\u5e38\u7528\u5305\uff0c\u5e76\u5728 QPython \u7684 QPYPI/Extensions \u4e2d\u53d1\u5e03\uff0c\u4f9b\u7528\u6237\u8f7b\u677e\u5b89\u88c5\u3002

      "},{"location":"qpypi-guide/#_3","title":"\u5b89\u88c5\u9884\u7f16\u8bd1\u5305","text":"

      \u60a8\u53ef\u4ee5\u901a\u8fc7\u4ee5\u4e0b\u65b9\u5f0f\u5b89\u88c5\u9884\u7f16\u8bd1\u5305\uff1a

      1. \u901a\u8fc7 QPython \u5e94\u7528\uff1a\u76f4\u63a5\u4ece QPython \u5e94\u7528\u5185\u7684 QPYPI \u6216 Extensions \u5b89\u88c5
      2. \u901a\u8fc7 PyPI\uff1a\u8bbf\u95ee https://pypi.org/user/qpythonx/ \u67e5\u770b\u53ef\u7528\u7684\u5305
      3. \u901a\u8fc7 pip \u547d\u4ee4\uff1a
      4. pip install xxx-qpython - \u5e26 -qpython \u540e\u7f00\u7684\u5305
      5. pip install xxx-aipy - \u5e26 -aipy \u540e\u7f00\u7684\u5305\uff08\u901a\u5e38\u662f AI/ML \u76f8\u5173\u7684\u5305\uff09

      \u6ce8\u610f\uff1a\u6211\u4eec\u901a\u5e38\u6839\u636e\u5305\u7684\u9884\u671f\u7528\u9014\u6dfb\u52a0\u8fd9\u4e9b\u540e\u7f00\u4e4b\u4e00\u3002

      "},{"location":"qpypi-guide/#_4","title":"\u8bf7\u6c42\u65b0\u5305","text":"

      \u5982\u679c\u60a8\u9700\u8981\u5f53\u524d\u4e0d\u652f\u6301\u7684\u5305\uff1a

      • \u5728 qpython.org \u9879\u76ee \u4e2d\u63d0\u51fa\u95ee\u9898
      • QPython \u56e2\u961f\u5c06\u8003\u8651\u9884\u7f16\u8bd1\u5e76\u5c06\u5176\u6dfb\u52a0\u5230\u4ed3\u5e93\u4e2d

      \u83b7\u53d6\u66f4\u591a\u5e2e\u52a9\u548c\u53c2\u4e0e\u793e\u533a\u7684\u65b9\u5f0f\uff0c\u8bf7\u53c2\u9605 \u793e\u533a\u4e0e\u53cd\u9988 \u90e8\u5206\u3002

      \u6ce8\u610f\uff1a\u7531\u4e8e\u4e0d\u540c\u7684\u8ba1\u7b97\u673a\u67b6\u6784\uff0c\u6211\u4eec\u65e0\u6cd5\u4fdd\u8bc1 QPYPI \u5305\u542b PyPI \u4e0a\u7684\u6240\u6709\u5305\u3002

      "},{"location":"qpython-x/","title":"QPython \u7248\u672c","text":"

      QPython \u662f Android \u7684 Python \u5f15\u64ce\u3002\u5b83\u5305\u542b\u4ee4\u4eba\u60ca\u53f9\u7684\u529f\u80fd\uff0c\u5982 Python \u89e3\u91ca\u5668\u3001\u8fd0\u884c\u73af\u5883\u3001\u7f16\u8f91\u5668\u3001QPYI \u548c\u96c6\u6210\u7684 SL4A\u3002\u5b83\u8ba9\u60a8\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 Android \u4e0a\u4f7f\u7528 Python\u3002\u800c\u4e14\u5b83\u662f\u514d\u8d39\u7684\u3002

      QPython \u5df2\u7ecf\u5728\u5168\u7403\u62e5\u6709\u6570\u767e\u4e07\u7528\u6237\uff0c\u4e5f\u662f\u4e00\u4e2a\u5f00\u6e90\u9879\u76ee\u3002

      \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

      "},{"location":"qpython-x/#qpython_1","title":"QPython","text":"

      \u6807\u51c6\u7248\uff1a\u9488\u5bf9 AI \u6027\u80fd\u548c\u901a\u7528\u5e94\u7528\u5546\u5e97\u517c\u5bb9\u6027\u4f18\u5316

      \u4e3b\u8981\u7248\u672c\uff0c\u53ef\u5728 Google Play \u548c\u5176\u4ed6\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002\u6b64\u7248\u672c\u4e13\u6ce8\u4e8e AI \u529f\u80fd\uff0c\u4f7f AI \u65f6\u4ee3\u7528\u6237\u66f4\u5bb9\u6613\u5b66\u4e60\u548c\u4f7f\u7528 Python\u3002

      \u4e3b\u8981\u7279\u6027\uff1a - AI \u9a71\u52a8\u7684\u7f16\u7801\u8f85\u52a9\u548c\u5b66\u4e60\u5de5\u5177 - \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668\uff1a\u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51 - \u652f\u6301\u591a\u79cd\u9879\u76ee\u7c7b\u578b\uff1a\u63a7\u5236\u53f0\u3001SL4A\u3001WebApp - \u65b9\u4fbf\u7684\u4e8c\u7ef4\u7801\u8bfb\u53d6\u5668\uff0c\u7528\u4e8e\u5c06\u4ee3\u7801\u4f20\u8f93\u5230\u624b\u673a - QPYPI \u548c\u81ea\u5b9a\u4e49\u4ed3\u5e93\uff0c\u7528\u4e8e\u9884\u7f16\u8bd1 wheel \u5305 -\u6613\u4e8e\u4f7f\u7528\u7684\u8bed\u6cd5\u9ad8\u4eae\u7f16\u8f91\u5668 - \u5b8c\u5584\u7684\u6587\u6863\u548c\u793e\u533a\u652f\u6301

      \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

      \u4e0b\u8f7d\uff1a \u53ef\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

      "},{"location":"qpython-x/#qpython_2","title":"QPython+","text":"

      \u793e\u533a\u7248\uff1a\u516c\u5f00\u652f\u6301\u5404\u79cd\u793e\u533a\u9a71\u52a8\u7684\u529f\u80fd\uff1b\u53ef\u5728\u90e8\u5206\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

      \u793e\u533a\u5f00\u6e90\u7248\u672c\uff08\u6b63\u5728\u89c4\u5212\u548c\u51c6\u5907\u4e2d\uff09\u3002\u6b64\u7248\u672c\u4e13\u4e3a\u60f3\u8981\u53c2\u4e0e QPython \u9879\u76ee\u5f00\u53d1\u7684\u8d21\u732e\u8005\u800c\u8bbe\u8ba1\uff0c\u652f\u6301\u9488\u5bf9\u4e0d\u540c\u5236\u9020\u5546\u7684\u5b9a\u5236\u3002

      \u4e3b\u8981\u7279\u6027\uff1a - \u793e\u533a\u9a71\u52a8\u5f00\u53d1 - \u652f\u6301\u4f9b\u5e94\u5546\u5b9a\u5236 - \u66f4\u7075\u6d3b\u7684\u914d\u7f6e\u9009\u9879 - \u5f00\u653e\u4f9b\u8d21\u732e\u8005\u52a0\u5165\u5f00\u53d1

      \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

      \u4e0b\u8f7d\uff1a \u5c06\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

      \u6ce8\u610f\uff1a \u6b64\u7248\u672c\u76ee\u524d\u6b63\u5728\u89c4\u5212\u51c6\u5907\u4e2d\u3002\u8bf7\u5173\u6ce8\u66f4\u65b0\uff01

      "},{"location":"qpython-x/#qpython-plus","title":"QPython Plus","text":"

      QPython+ \u5b8c\u5168\u8bbf\u95ee\u7248\uff1a\u6388\u4e88\u8c03\u7528\u6240\u6709 Android \u63a5\u53e3\u7684\u5b8c\u6574\u6743\u9650\u3002\u4e0b\u8f7d\u94fe\u63a5\u4ec5\u901a\u8fc7\u5b98\u65b9\u4e91\u76d8\u63d0\u4f9b\u3002

      \u5177\u6709\u6269\u5c55\u6743\u9650\u7684\u7279\u6b8a\u7248\u672c\uff0c\u63d0\u4f9b\u5bf9\u8bbe\u5907\u7684\u6700\u5927\u63a7\u5236\u3002\u7531\u4e8e\u5176\u654f\u611f\u7684\u6743\u9650\u8981\u6c42\uff0c\u6b64\u7248\u672c\u4e0d\u4f1a\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u53d1\u5e03\u3002

      \u4e3b\u8981\u7279\u6027\uff1a - \u5b8c\u6574\u7684 SL4A API \u8bbf\u95ee\uff0c\u5305\u62ec\u654f\u611f\u529f\u80fd - SMS/\u901a\u8bdd\u63a7\u5236 API - \u9ad8\u7ea7\u7cfb\u7edf\u96c6\u6210 - \u6700\u5927\u7684\u8bbe\u5907\u63a7\u5236\u80fd\u529b

      \u6743\u9650\uff1a \u9700\u8981\u5e7f\u6cdb\u7684\u6743\u9650\uff0c\u5305\u62ec\uff1a - \u84dd\u7259 - \u4f4d\u7f6e\uff08GPS\uff09 - \u8bfb\u53d6/\u53d1\u9001\u77ed\u4fe1 - \u6253\u7535\u8bdd - \u76f8\u673a\u548c\u9ea6\u514b\u98ce - \u7cfb\u7edf\u8bbe\u7f6e - \u4ee5\u53ca\u5176\u4ed6\u654f\u611f\u6743\u9650

      \u4e0b\u8f7d\uff1a \u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\u3002\u4ec5\u901a\u8fc7\u7279\u6b8a\u6e20\u9053\u5206\u53d1\u3002

      \u91cd\u8981\u63d0\u793a\uff1a QPython \u4e0d\u4f1a\u5728\u540e\u53f0\u672a\u7ecf\u60a8\u77e5\u6089\u4f7f\u7528\u8fd9\u4e9b\u6743\u9650\u3002\u5982\u679c\u4f7f\u7528 SL4A API \u65f6\u51fa\u73b0\u5f02\u5e38\uff0c\u8bf7\u68c0\u67e5\u7cfb\u7edf\u8bbe\u7f6e\u4e2d\u662f\u5426\u5df2\u542f\u7528\u76f8\u5173\u6743\u9650\u3002

      "},{"location":"tutorial-hello-world/","title":"\u7f16\u5199\"Hello World\"","text":""},{"location":"tutorial-hello-world/#hello-world_1","title":"Hello world","text":"

      \u597d\u7684\uff0c\u5728\u60a8\u5bf9 QPython \u6709\u4e86\u4e00\u5b9a\u7684\u4e86\u89e3\u4e4b\u540e\uff0c\u8ba9\u6211\u4eec\u5728 QPython \u4e2d\u521b\u5efa\u6211\u4eec\u7684\u7b2c\u4e00\u4e2a\u7a0b\u5e8f\u3002\u663e\u7136\uff0c\u5b83\u5c06\u662f helloworld.py\u3002;)

      \u542f\u52a8 QPython\uff0c\u6253\u5f00\u7f16\u8f91\u5668\u5e76\u8f93\u5165\u4ee5\u4e0b\u4ee3\u7801\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello, QPYTHON!')\n

      \u6beb\u65e0\u7591\u95ee\uff0c\u5b83\u4e0e\u5176\u4ed6\u4efb\u4f55 hello-world \u7a0b\u5e8f\u5e76\u65e0\u4e0d\u540c\u3002\u6267\u884c\u65f6\uff0c\u5b83\u53ea\u662f\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u5f39\u51fa\u6d88\u606f\uff08\u89c1\u9876\u90e8\u622a\u56fe\uff09\u3002\u65e0\u8bba\u5982\u4f55\uff0c\u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684 QPython \u7a0b\u5e8f\u793a\u4f8b\u3002

      "},{"location":"tutorial-hello-world/#_1","title":"\u4ee3\u7801\u7406\u89e3","text":"

      \u5b83\u4ee5 import androidhelper \u5f00\u5934\u2014\u2014\u8fd9\u662f QPython \u4e2d\u6700\u6709\u7528\u7684\u6a21\u5757\uff0c\u5b83\u5c01\u88c5\u4e86 Python \u4e2d\u53ef\u7528\u7684\u51e0\u4e4e\u6240\u6709\u4e0e Android \u7684\u63a5\u53e3\u3002\u4efb\u4f55\u5728 QPython \u4e2d\u5f00\u53d1\u7684\u811a\u672c\u90fd\u4ee5\u8fd9\u4e2a\u8bed\u53e5\u5f00\u5934\uff08\u81f3\u5c11\u5982\u679c\u5b83\u58f0\u79f0\u8981\u4e0e\u7528\u6237\u901a\u4fe1\u7684\u8bdd\uff09\u3002\u5728\u6b64\u5904\u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u5e93 \u548c import \u8bed\u53e5 \u7684\u5185\u5bb9\u3002

      \u63a5\u4e0b\u6765\u6211\u4eec\u521b\u5efa\u4e00\u4e2a droid \u5bf9\u8c61\uff08\u5b9e\u9645\u4e0a\u662f\u4e00\u4e2a\u7c7b\uff09\uff0c\u5b83\u5bf9\u4e8e\u8c03\u7528 RPC \u51fd\u6570\u4ee5\u4e0e Android \u901a\u4fe1\u662f\u5fc5\u8981\u7684\u3002

      \u6211\u4eec\u4ee3\u7801\u7684\u6700\u540e\u4e00\u884c\u8c03\u7528\u4e86\u8fd9\u6837\u7684\u51fd\u6570\uff0cdroid.makeToast()\uff0c\u5b83\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u4e00\u4e2a\u5c0f\u7684\u5f39\u51fa\u6d88\u606f\uff08\"toast\"\uff09\u3002

      \u597d\u7684\uff0c\u8ba9\u6211\u4eec\u6dfb\u52a0\u4e00\u4e9b\u66f4\u591a\u7684\u529f\u80fd\u3002\u8ba9\u5b83\u8be2\u95ee\u7528\u6237\u540d\u5e76\u5411\u7528\u6237\u6253\u62db\u547c\u3002

      "},{"location":"tutorial-hello-world/#_2","title":"\u66f4\u591a\u793a\u4f8b","text":"

      \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 dialogGetInput \u8c03\u7528\u663e\u793a\u4e00\u4e2a\u5e26\u6709\u6807\u9898\u3001\u63d0\u793a\u3001\u7f16\u8f91\u5b57\u6bb5\u548c \u786e\u5b9a \u548c \u53d6\u6d88 \u6309\u94ae\u7684\u7b80\u5355\u5bf9\u8bdd\u6846\u3002\u7528\u4ee5\u4e0b\u4ee3\u7801\u66ff\u6362\u60a8\u7684\u6700\u540e\u4e00\u884c\u4ee3\u7801\u5e76\u5c06\u5176\u4fdd\u5b58\u4e3a hello1.py\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\n

      \u597d\u7684\uff0c\u6211\u8ba4\u4e3a\u5b83\u5e94\u8be5\u8fd4\u56de\u4efb\u4f55\u54cd\u5e94\uff0c\u4efb\u4f55\u7528\u6237\u53cd\u5e94\u3002\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u6211\u5199 respond = ...\u3002\u4f46\u8fd9\u4e2a\u8c03\u7528\u5b9e\u9645\u4e0a\u8fd4\u56de\u4ec0\u4e48\uff1f\u8ba9\u6211\u4eec\u68c0\u67e5\u4e00\u4e0b\u3002\u53ea\u9700\u5728\u6700\u540e\u4e00\u884c\u540e\u6dfb\u52a0 print \u8bed\u53e5\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\n

      \u7136\u540e\u4fdd\u5b58\u5e76\u8fd0\u884c\u5b83...

      \u54ce\u5440\uff01\u6ca1\u6709\u6253\u5370\uff1f\u522b\u62c5\u5fc3\u3002\u53ea\u9700\u62c9\u4e0b\u901a\u77e5\u680f\uff0c\u60a8\u5c31\u4f1a\u770b\u5230\"QPython Program Output: hello1.py\"\u2014\u2014\u70b9\u51fb\u5b83\uff01

      \u5982\u60a8\u6240\u89c1\uff0cdroid.dialogGetInput() \u8fd4\u56de\u4e00\u4e2a\u5305\u542b\u4e09\u4e2a\u5b57\u6bb5\u7684 JSON \u5bf9\u8c61\u3002\u6211\u4eec\u53ea\u9700\u8981\u4e00\u4e2a\u2014\u2014result\uff0c\u5176\u4e2d\u5305\u542b\u7528\u6237\u5b9e\u9645\u8f93\u5165\u7684\u5185\u5bb9\u3002

      \u8ba9\u6211\u4eec\u6dfb\u52a0\u811a\u672c\u7684\u53cd\u5e94\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nmessage = f'Hello, {respond.result}!'\ndroid.makeToast(message)\n

      \u6700\u540e\u4e24\u884c\uff081\uff09\u683c\u5f0f\u5316\u6d88\u606f\uff0c\uff082\uff09\u4ee5 toast \u5f62\u5f0f\u5411\u7528\u6237\u663e\u793a\u6d88\u606f\u3002\u5982\u679c\u60a8\u4ecd\u7136\u4e0d\u77e5\u9053 f-string \u662f\u4ec0\u4e48\u610f\u601d\uff0c\u8bf7\u53c2\u9605 Python \u6587\u6863\u3002

      \u54c7\uff01\u5b83\u5de5\u4f5c\u4e86\uff01;)

      \u73b0\u5728\u6211\u8981\u5728\u90a3\u91cc\u6dfb\u52a0\u4e00\u4e9b\u903b\u8f91\u3002\u60f3\u4e00\u60f3\uff1a\u5982\u679c\u7528\u6237\u70b9\u51fb \u53d6\u6d88 \u6309\u94ae\uff0c\u6216\u8005\u70b9\u51fb \u786e\u5b9a \u4f46\u5c06\u8f93\u5165\u5b57\u6bb5\u7559\u7a7a\uff0c\u4f1a\u53d1\u751f\u4ec0\u4e48\uff1f

      \u60a8\u53ef\u4ee5\u73a9\u8fd9\u4e2a\u7a0b\u5e8f\uff0c\u68c0\u67e5 respond \u53d8\u91cf\u5728\u6bcf\u79cd\u60c5\u51b5\u4e0b\u5305\u542b\u4ec0\u4e48\u3002

      \u9996\u5148\uff0c\u6211\u60f3\u5c06\u7528\u6237\u8f93\u5165\u7684\u6587\u672c\u653e\u5165\u4e00\u4e2a\u5355\u72ec\u7684\u53d8\u91cf\u4e2d\uff1aname = respond.result\u3002\u7136\u540e\u6211\u68c0\u67e5\u5b83\uff0c\u5982\u679c\u5b83\u5305\u542b\u4efb\u4f55\u771f\u5b9e\u6587\u672c\uff0c\u5b83\u5c06\u88ab\u89c6\u4e3a\u540d\u79f0\u5e76\u7528\u4e8e\u95ee\u5019\u3002\u5426\u5219\uff0c\u5c06\u663e\u793a\u53e6\u4e00\u6761\u6d88\u606f\u3002\u5c06\u7b2c\u4e94\u884c message = f'Hello, {respond.result}!' \u66ff\u6362\u4e3a\u4ee5\u4e0b\u4ee3\u7801\uff1a

      name = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\n

      \u4f7f\u7528\u5de5\u5177\u680f\u4e0a\u7684 < \u548c > \u6309\u94ae\u6765\u7f29\u8fdb/\u53d6\u6d88\u7f29\u8fdb if \u8bed\u53e5\u4e2d\u7684\u884c\uff08\u6216\u8005\u53ea\u9700\u4f7f\u7528\u7a7a\u683c/\u9000\u683c\u952e\uff09\u3002\u60a8\u53ef\u4ee5\u5728 \u6b64\u5904 \u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u7f29\u8fdb\u7684\u5185\u5bb9\uff1bif \u8bed\u53e5\u5728 \u6b64\u5904 \u63cf\u8ff0\u3002

      \u9996\u5148\uff0c\u6211\u4eec\u5c06\u7528\u6237\u8f93\u5165\u653e\u5165 name \u53d8\u91cf\u3002\u7136\u540e\u6211\u4eec\u68c0\u67e5 name \u662f\u5426\u5305\u542b\u4efb\u4f55\u5185\u5bb9\uff1f\u5982\u679c\u7528\u6237\u7559\u7a7a\u884c\u5e76\u70b9\u51fb \u786e\u5b9a\uff0c\u8fd4\u56de\u503c\u662f\u7a7a\u5b57\u7b26\u4e32 ''\u3002\u5982\u679c\u6309\u4e0b\u4e86 \u53d6\u6d88 \u6309\u94ae\uff0c\u8fd4\u56de\u503c\u662f None\u3002\u5728 if \u8bed\u53e5\u4e2d\uff0c\u4e24\u8005\u90fd\u88ab\u89c6\u4e3a\u5047\u3002\u56e0\u6b64\uff0c\u53ea\u6709\u5f53 name \u5305\u542b\u4efb\u4f55\u6709\u610f\u4e49\u7684\u5185\u5bb9\u65f6\uff0cthen \u8bed\u53e5\u624d\u4f1a\u6267\u884c\uff0c\u5e76\u663e\u793a\u95ee\u5019\u8bed\"Hello, ...!\"\u3002\u5982\u679c\u8f93\u5165\u4e3a\u7a7a\uff0c\u7528\u6237\u5c06\u770b\u5230\"Hey! And you're not very polite, %Username%!\"\u6d88\u606f\u3002

      \u597d\u7684\uff0c\u8fd9\u662f\u6574\u4e2a\u7a0b\u5e8f\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nname = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\ndroid.makeToast(message)\n
      "},{"location":"tutorial-hello-world/#_3","title":"\u8fd0\u884c\u6548\u679c","text":""},{"location":"tutorial-hello-world/#_4","title":"\u4e0b\u4e00\u6b65","text":"

      \u5bf9\u4e8e Python \u65b0\u7528\u6237\uff0c\u63a8\u8350\u5b66\u4e60 Python \u8bed\u6cd5\u5b9e\u8df5 \u8bfe\u7a0b\u6765\u8fdb\u4e00\u6b65\u5b66\u4e60 Python\uff0c\u6216\u8005\u5728 QPython \u7cbe\u9009\u8bfe\u7a0b \u4e2d\u5bfb\u627e\u60f3\u8981\u5b66\u4e60\u7684\u5185\u5bb9\u3002

      "},{"location":"whats-new/","title":"\u66f4\u65b0\u65e5\u5fd7","text":""},{"location":"whats-new/#v392-v393","title":"v3.9.2 / v3.9.3","text":"
      • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
      • \u7f16\u8f91\u5668\u91cd\u5927\u66f4\u65b0\uff0c\u5e26\u6765\u66f4\u6d41\u7545\u7684\u7f16\u8f91\u4f53\u9a8c
      • \u5176\u4ed6\u5404\u79cd\u5c0f\u6539\u8fdb
      "},{"location":"whats-new/#v391","title":"v3.9.1","text":"
      • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
      • \u6269\u5c55\u5305\u73b0\u5728\u652f\u6301 MCP
      • \u9519\u8bef\u4fee\u590d
      "},{"location":"whats-new/#v390","title":"v3.9.0","text":"
      • SDK \u5347\u7ea7\uff0c\u6574\u5408\u6700\u65b0\u7684 Android \u529f\u80fd
      • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
      • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
      • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
      "},{"location":"whats-new/#v3811","title":"v3.8.11","text":"
      • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
      • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
      • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
      "},{"location":"whats-new/#v3810","title":"v3.8.10","text":"
      • \u5185\u7f6e Ollama \u5347\u7ea7\uff1a\u73b0\u5728\u60a8\u53ef\u4ee5\u5728 QPython \u4e2d\u8f7b\u677e\u672c\u5730\u8fd0\u884c Qwen3 / Gemma3 \u6a21\u578b\uff01
      • \u6dfb\u52a0\u4e86\u5f3a\u5927\u7684 MCP \u5e93\uff1a\u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 mcp \u5e93\uff0c\u8ba9\u60a8\u968f\u65f6\u968f\u5730\u643a\u5e26\u5f3a\u5927\u7684 MCP \u529f\u80fd\uff01
      "},{"location":"whats-new/#v389","title":"v3.8.9","text":"

      \u91cd\u5927\u66f4\u65b0\uff01AI \u7f16\u7a0b\u5b8c\u5168\u96c6\u6210\u5230 QPython\uff0c\u8ba9\u60a8\u7684\u7f16\u7a0b\u66f4\u8f7b\u677e\uff01

      • \u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u652f\u6301\uff1a\u65b0\u652f\u6301 AIPyApp\uff0c\u5728 QPython \u4e2d\u5b9e\u73b0\u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u3002\u76ee\u524d\u5904\u4e8e\u6d4b\u8bd5\u9636\u6bb5 - \u52a0\u5165\u6211\u4eec\u7684\u793e\u533a\u83b7\u53d6\u4f7f\u7528\u8bf4\u660e
      • \u65b0 QSL4A \u529f\u80fd\uff1a\u6dfb\u52a0 notebookOpen \u51fd\u6570\uff0c\u652f\u6301\u81ea\u7136\u8bed\u8a00\u63a7\u5236\u6253\u5f00 Notebook \u6587\u4ef6
      • \u5185\u7f6e\u7f16\u8f91\u5668\u5347\u7ea7\uff1a\u589e\u5f3a\u7f16\u8f91\u5668\u529f\u80fd\uff0c\u652f\u6301\u6253\u5f00\u548c\u6d4f\u89c8\u5404\u79cd\u6587\u672c\u6587\u4ef6
      • \u4fbf\u6377\u7684\u6587\u4ef6\u7ba1\u7406\uff1a\u5728\u6587\u4ef6\u7ba1\u7406\u5668\u4e2d\u6dfb\u52a0\u5185\u90e8\u5b58\u50a8\u5165\u53e3\uff0c\u5feb\u901f\u8bbf\u95ee\u60a8\u7684\u6587\u4ef6
      "},{"location":"whats-new/#v388","title":"v3.8.8","text":"
      • \u6587\u4ef6\u8bbf\u95ee\u6743\u9650\u63a7\u5236\u7684\u91cd\u8981\u6539\u8fdb\uff0c\u5141\u8bb8\u7528\u6237\u7075\u6d3b\u5730\u901a\u8fc7 QPython \u7f16\u7a0b\u542f\u7528\u6216\u7981\u7528\u5916\u90e8\u5b58\u50a8\u6587\u4ef6\u7684\u8bbf\u95ee
      • SDK \u5347\u7ea7\uff0c\u589e\u5f3a\u4e86\u5bf9\u65b0\u7248 Android \u7684\u652f\u6301\u548c\u517c\u5bb9\u6027
      • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Anthropic \u548c Google GenAI \u5e93
      "},{"location":"whats-new/#v387","title":"v3.8.7","text":"
      • \u5728\u73b0\u6709 Tkinter \u652f\u6301\u57fa\u7840\u4e0a\uff0c\u5728 Extensions -> Tools \u4e2d\u6dfb\u52a0\u4e86\u4f7f\u7528 Turtle \u7ed8\u5236\u54c6\u5566A\u68a6\u7684\u793a\u4f8b\u4ee3\u7801
      • \u4f18\u5316\u4e86\u624b\u673a\u6743\u9650\u83b7\u53d6\u6d41\u7a0b\uff0c\u63d0\u5347\u7528\u6237\u4f53\u9a8c\u548c\u64cd\u4f5c\u4fbf\u5229\u6027
      • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Google Gen AI \u5e93\uff0c\u65b9\u4fbf\u8bbf\u95ee Gemini Developer API \u548c Vertex AI
      "},{"location":"whats-new/#v386","title":"v3.8.6","text":"
      • Tkinter \u652f\u6301\uff1a\u73b0\u5728\u652f\u6301 Tkinter \u5e93\uff0c\u53ef\u901a\u8fc7 XServer \u8bbf\u95ee\u3002\u8bf7\u8bbf\u95ee www.qpython.org \u7684\u4e91\u76d8\"Extra\"\u94fe\u63a5\u4e0b\u8f7d\u6240\u9700\u6587\u4ef6
      • \u5b58\u50a8\u6743\u9650\u66f4\u65b0\uff1a\u4e3a\u6539\u5584\u7528\u6237\u4f53\u9a8c\uff0c\u6211\u4eec\u6dfb\u52a0\u4e86\u8bfb\u53d6\u624b\u673a\u5b58\u50a8\u7684\u6743\u9650\uff0c\u7528\u4e8e\u8bbf\u95ee\u5b58\u50a8\u5728\u5176\u4ed6\u76ee\u5f55\u4e2d\u7684 Python \u7a0b\u5e8f

      \u6b64\u66f4\u65b0\u540e\uff0cQPython \u548c QPythonPlus\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff0c\u4e13\u4e3a\u9700\u8981\u66f4\u591a\u654f\u611f\u6743\u9650\u7684\u9ad8\u7ea7\u7528\u6237\u8bbe\u8ba1\uff09\u5c06\u4fdd\u6301\u540c\u6b65\u7684\u7248\u672c\u53f7\u3002

      "},{"location":"whats-new/#v352-2025225","title":"v3.5.2 (2025/2/25)","text":"

      \u4e0e\u5f00\u6e90 LLM \u90e8\u7f72\u5de5\u5177 Ollama \u4ee5\u53ca DeepSeek \u5f00\u53d1\u7684 DeepSeek \u5b9e\u73b0\u65e0\u7f1d\u96c6\u6210\uff01

      \u529f\u80fd\uff1a - \u96f6\u95e8\u69db\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5404\u79cd\u5927\u578b\u8bed\u8a00\u6a21\u578b - \u5feb\u901f\u90e8\u7f72 DeepSeek \u7b49\u5c16\u7aef AI \u6a21\u578b - \u4eab\u53d7\u7b80\u7ea6\u7684 API \u8c03\u7528\u4f53\u9a8c - \u6784\u5efa\u5b8c\u5168\u79bb\u7ebf\u7684\u667a\u80fd\u7f16\u7a0b\u73af\u5883

      \u80fd\u529b\uff1a - \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u52a0\u8f7d/\u7ba1\u7406 LLM \u6a21\u578b - \u57fa\u4e8e\u672c\u5730\u8ba1\u7b97\u7684\u5b9e\u65f6\u4f4e\u5ef6\u8fdf\u54cd\u5e94

      "},{"location":"whats-new/#v350","title":"v3.5.0","text":"
      • Python \u5347\u7ea7\u5230 3.12.8
      • \u6539\u8fdb\u4eea\u8868\u76d8\uff0c\u529f\u80fd\u66f4\u6e05\u6670\u3001\u66f4\u4eba\u6027\u5316
      • \u6dfb\u52a0\u4e86\u4f17\u591a\u7b2c\u4e09\u65b9\u5305\uff1aPyTorch / Twisted / Scrapy / FastAPI ...
      "},{"location":"whats-new/#v338","title":"v3.3.8","text":"
      • \u4fee\u590d\u4e86 NumPy \u517c\u5bb9\u6027\u95ee\u9898
      "},{"location":"whats-new/#v335","title":"v3.3.5","text":"
      • \u5347\u7ea7 Python \u5185\u6838\u5230 3.11.9
      • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u4e0d\u663e\u793a\u6a21\u5757\u5b89\u88c5\u72b6\u6001\u7684 bug
      • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u5220\u9664\u6a21\u5757\u5931\u8d25\u7684 bug
      • \u4fee\u590d\u4e86\u5176\u4ed6 bug
      "},{"location":"whats-new/#v334","title":"v3.3.4","text":"
      • \u6dfb\u52a0\u4e86 OpenAI/Langchain/APIGPTCloud AI \u5305
      • \u79fb\u9664\u4e0d\u5fc5\u8981\u7684\u6587\u4ef6\u4ee5\u51cf\u5c11\u5927\u5c0f
      "},{"location":"whats-new/#v325","title":"v3.2.5","text":"
      • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570
      • \u5176\u4ed6\u9519\u8bef\u4fee\u590d
      "},{"location":"whats-new/#v323","title":"v3.2.3","text":"
      • \u66f4\u65b0 Python \u7248\u672c\u5230 3.11.0
      • \u66f4\u65b0 IPython \u7248\u672c\u5230 8.6.0
      • \u66f4\u65b0 pip \u7248\u672c\u5230 22.3.1
      • \u66f4\u65b0\u79d1\u5b66\u8ba1\u7b97\u5305\uff0c\u81ea\u52a8\u8f6f\u94fe\u63a5
      • \u51cf\u5c11\u7a7a\u95f4\u4f7f\u7528
      • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570 + \u5176\u4ed6\u9519\u8bef\u4fee\u590d
      "},{"location":"whats-new/#v318","title":"v3.1.8","text":"
      • \u5728\u7ec8\u7aef\u4e2d\u6dfb\u52a0\u4e86\u64cd\u4f5c\u70ed\u952e
      • \u4fee\u590d\u4e86\u7f16\u8f91\u5668\u5728\u65cb\u8f6c\u65f6\u4e22\u5931\u5185\u5bb9\u7684\u95ee\u9898
      • \u4fee\u590d\u4e86\u5176\u4ed6 bug

      \u5728 Google Play \u4e0b\u8f7d

      "},{"location":"qsl4a/","title":"QSL4A\uff08Android \u811a\u672c\u5c42\uff09API \u6587\u6863","text":"

      QSL4A \u662f QPython \u7684 Android \u811a\u672c\u5c42\uff0c\u5141\u8bb8\u60a8\u4f7f\u7528 Python \u63a7\u5236 Android \u8bbe\u5907\u529f\u80fd\u3002

      "},{"location":"qsl4a/#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a toast \u6d88\u606f\ndroid.makeToast('Hello QPython!')\n\n# \u9707\u52a8\u8bbe\u5907\ndroid.vibrate(500)\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\uff08\u5148\u5f00\u59cb\u76d1\u63a7\uff09\nimport time\ndroid.batteryStartMonitoring()\ntime.sleep(0.5)  # \u7b49\u5f85\u6570\u636e\nbattery = droid.readBatteryData().result\nprint(f\"\u7535\u6c60\uff1a{battery['level']}%\")\n
      "},{"location":"qsl4a/#_2","title":"\u6587\u6863\u7ed3\u6784","text":""},{"location":"qsl4a/#_3","title":"\u6838\u5fc3\u6a21\u5757","text":"
      • Android \u57fa\u7840 - \u6838\u5fc3\u8fde\u63a5\u548c RPC
      • Intent \u7cfb\u7edf - Android Intent \u64cd\u4f5c
      • \u4e8b\u4ef6\u7cfb\u7edf - \u4e8b\u4ef6\u5904\u7406\u548c\u5e7f\u64ad
      "},{"location":"qsl4a/#ui","title":"UI \u7ec4\u4ef6","text":"
      • \u5bf9\u8bdd\u6846 - \u8b66\u62a5\u3001\u8f93\u5165\u3001\u9009\u62e9\u5bf9\u8bdd\u6846
      • \u5168\u5c4f UI - \u81ea\u5b9a\u4e49\u5e03\u5c40 UI
      • \u60ac\u6d6e\u7a97 - \u60ac\u6d6e\u7a97\u53e3
      • \u8f85\u52a9\u529f\u80fd - \u5c4f\u5e55\u81ea\u52a8\u5316
      "},{"location":"qsl4a/#_4","title":"\u7cfb\u7edf","text":"
      • \u7535\u6c60 - \u7535\u6c60\u76d1\u63a7
      • \u4f20\u611f\u5668 - \u8bbe\u5907\u4f20\u611f\u5668
      • \u5e94\u7528 - \u5e94\u7528\u7ba1\u7406
      • \u7cfb\u7edf\u4fe1\u606f - \u8bbe\u5907\u4fe1\u606f
      • \u8bbe\u7f6e - \u7cfb\u7edf\u8bbe\u7f6e
      • \u5524\u9192\u9501 - \u5524\u9192\u9501\u63a7\u5236
      • QPython \u63a5\u53e3 - \u811a\u672c\u6267\u884c
      • Activity \u7ed3\u679c - Activity \u7ed3\u679c\u5904\u7406
      "},{"location":"qsl4a/#_5","title":"\u786c\u4ef6","text":"
      • \u84dd\u7259 - \u84dd\u7259\u64cd\u4f5c
      • \u76f8\u673a - \u62cd\u7167\u548c\u5f55\u50cf
      • \u97f3\u9891/\u5f55\u97f3\u5668 - \u5f55\u97f3
      • \u7f51\u7edc\u6444\u50cf\u5934 - MJPEG \u6d41
      • USB \u4e32\u53e3 - USB \u4e3b\u673a\u4e32\u53e3
      "},{"location":"qsl4a/#_6","title":"\u8fde\u63a5","text":"
      • WiFi - WiFi \u64cd\u4f5c
      • \u4f4d\u7f6e - GPS \u548c\u4f4d\u7f6e
      • \u77ed\u4fe1 - \u77ed\u4fe1\u64cd\u4f5c
      • \u7535\u8bdd - \u6253\u7535\u8bdd\u548c\u6765\u7535\u4fe1\u606f
      • \u8054\u7cfb\u4eba - \u8054\u7cfb\u4eba\u7ba1\u7406
      • \u4fe1\u53f7\u5f3a\u5ea6 - \u4fe1\u53f7\u76d1\u63a7
      • FTP \u670d\u52a1\u5668 - \u5185\u7f6e FTP \u670d\u52a1\u5668
      "},{"location":"qsl4a/#_7","title":"\u5b58\u50a8","text":"
      • DocumentFile - \u6587\u4ef6\u64cd\u4f5c
      • \u526a\u8d34\u677f - \u526a\u8d34\u677f\u64cd\u4f5c
      • \u504f\u597d\u8bbe\u7f6e - \u5171\u4eab\u504f\u597d\u8bbe\u7f6e
      "},{"location":"qsl4a/#_8","title":"\u5a92\u4f53","text":"
      • \u5a92\u4f53\u64ad\u653e\u5668 - \u97f3\u9891/\u89c6\u9891\u64ad\u653e
      • \u56fe\u50cf\u5904\u7406 - \u56fe\u50cf\u64cd\u4f5c
      "},{"location":"qsl4a/#_9","title":"\u7279\u6b8a\u529f\u80fd","text":"
      • \u52a0\u5bc6 - \u52a0\u5bc6/\u89e3\u5bc6
      • PGPT AI - AI \u8bed\u97f3\u670d\u52a1
      "},{"location":"qsl4a/#_10","title":"\u7ed3\u679c\u5bf9\u8c61","text":"

      \u5927\u591a\u6570 QSL4A \u65b9\u6cd5\u8fd4\u56de\u4e00\u4e2a\u5e26\u6709\u4ee5\u4e0b\u5c5e\u6027\u7684 Result \u547d\u540d\u5143\u7ec4\uff1a - id - \u8bf7\u6c42 ID - result - \u5b9e\u9645\u7ed3\u679c\u6570\u636e - error - \u5982\u679c\u5931\u8d25\u5219\u4e3a\u9519\u8bef\u6d88\u606f

      result = droid.getClipboard()\nif result.error is None:\n    print(result.result)\nelse:\n    print(f\"\u9519\u8bef\uff1a{result.error}\")\n
      "},{"location":"qsl4a/connectivity/contacts/","title":"\u8054\u7cfb\u4eba API","text":"

      \u8bbf\u95ee\u548c\u7ba1\u7406\u8bbe\u5907\u8054\u7cfb\u4eba\u3002

      "},{"location":"qsl4a/connectivity/contacts/#_1","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":""},{"location":"qsl4a/connectivity/contacts/#pickcontact","title":"pickContact()","text":"

      \u663e\u793a\u8054\u7cfb\u4eba\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

      pickContact()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u8054\u7cfb\u4eba URI \u7684 Intent

      "},{"location":"qsl4a/connectivity/contacts/#pickphone","title":"pickPhone()","text":"

      \u663e\u793a\u7535\u8bdd\u53f7\u7801\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

      pickPhone()\n

      \u8fd4\u56de\uff1a \u9009\u4e2d\u7684\u7535\u8bdd\u53f7\u7801\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/contacts/#_2","title":"\u8054\u7cfb\u4eba\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#contactsget","title":"contactsGet()","text":"

      \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\u3002

      contactsGet(attributes=None)\n

      \u53c2\u6570\uff1a - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

      \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba JSONObject \u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetbyid","title":"contactsGetById()","text":"

      \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\u3002

      contactsGetById(id, attributes=None)\n

      \u53c2\u6570\uff1a - id (int): \u8054\u7cfb\u4eba ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

      \u8fd4\u56de\uff1a JSONObject \u8054\u7cfb\u4eba\u6570\u636e

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetcount","title":"contactsGetCount()","text":"

      \u83b7\u53d6\u8054\u7cfb\u4eba\u603b\u6570\u3002

      contactsGetCount()\n

      \u8fd4\u56de\uff1a \u6574\u6570\u8ba1\u6570

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetids","title":"contactsGetIds()","text":"

      \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba ID\u3002

      contactsGetIds()\n

      \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba ID \u6574\u6570\u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetattributes","title":"contactsGetAttributes()","text":"

      \u83b7\u53d6\u6240\u6709\u53ef\u80fd\u7684\u8054\u7cfb\u4eba\u5c5e\u6027\u3002

      contactsGetAttributes()\n

      \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#_3","title":"\u5185\u5bb9\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#querycontent","title":"queryContent()","text":"

      \u4f7f\u7528\u81ea\u5b9a\u4e49\u53c2\u6570\u67e5\u8be2\u5185\u5bb9\u89e3\u6790\u5668\u3002

      queryContent(uri, attributes=None, selection=None, selectionArgs=None, order=None)\n

      \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u5c5e\u6027 - selection (str, optional): WHERE \u5b50\u53e5 - selectionArgs (list, optional): \u9009\u62e9\u53c2\u6570 - order (str, optional): ORDER BY \u5b50\u53e5

      \u8fd4\u56de\uff1a JSONObject \u7ed3\u679c\u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#queryattributes","title":"queryAttributes()","text":"

      \u83b7\u53d6\u5185\u5bb9 URI \u7684\u5c5e\u6027\u3002

      queryAttributes(uri)\n

      \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI

      \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u7684 JSONArray

      "},{"location":"qsl4a/connectivity/contacts/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u9009\u62e9\u8054\u7cfb\u4eba\ncontact_uri = droid.pickContact().result\nprint(f\"Selected contact: {contact_uri}\")\n\n# \u9009\u62e9\u7535\u8bdd\u53f7\u7801\nphone = droid.pickPhone().result\nprint(f\"Selected phone: {phone}\")\n\n# \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\ncontacts = droid.contactsGet().result\nprint(f\"Total contacts: {len(contacts)}\")\n\n# \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\ncontact = droid.contactsGetById(1).result\nprint(f\"Contact: {contact}\")\n\n# \u83b7\u53d6\u8054\u7cfb\u4eba\u5c5e\u6027\nattrs = droid.contactsGetAttributes().result\nprint(f\"Available attributes: {attrs}\")\n
      "},{"location":"qsl4a/connectivity/ftp/","title":"FTP \u670d\u52a1\u5668 API","text":"

      \u5728\u8bbe\u5907\u4e0a\u542f\u52a8\u548c\u7ba1\u7406\u5185\u7f6e FTP \u670d\u52a1\u5668\u3002

      "},{"location":"qsl4a/connectivity/ftp/#ftp","title":"FTP \u670d\u52a1\u5668\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/ftp/#ftpstart","title":"ftpStart()","text":"

      \u542f\u52a8 FTP \u670d\u52a1\u5668\u3002

      ftpStart()\n

      \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4 [ip, port]

      "},{"location":"qsl4a/connectivity/ftp/#ftpstop","title":"ftpStop()","text":"

      \u505c\u6b62 FTP \u670d\u52a1\u5668\u3002

      ftpStop()\n
      "},{"location":"qsl4a/connectivity/ftp/#ftpisrunning","title":"ftpIsRunning()","text":"

      \u68c0\u67e5 FTP \u670d\u52a1\u5668\u662f\u5426\u6b63\u5728\u8fd0\u884c\u3002

      ftpIsRunning()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u8fd0\u884c\u5219\u4e3a True

      "},{"location":"qsl4a/connectivity/ftp/#ftpget","title":"ftpGet()","text":"

      \u83b7\u53d6 FTP \u670d\u52a1\u5668 IP \u5730\u5740\u3002

      ftpGet()\n

      \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4

      "},{"location":"qsl4a/connectivity/ftp/#ftpset","title":"ftpSet()","text":"

      \u914d\u7f6e FTP \u670d\u52a1\u5668\u8bbe\u7f6e\u3002

      ftpSet(port=None, rootDir=None, username=None, password=None)\n

      \u53c2\u6570\uff1a - port (int, optional): \u670d\u52a1\u5668\u7aef\u53e3 - rootDir (str, optional): \u8981\u670d\u52a1\u7684\u57fa\u7840\u76ee\u5f55 - username (str, optional): \u767b\u5f55\u7528\u6237\u540d - password (str, optional): \u767b\u5f55\u5bc6\u7801

      \u8fd4\u56de\uff1a \u5305\u542b\u5f53\u524d\u8bbe\u7f6e\u7684 JSONObject

      "},{"location":"qsl4a/connectivity/ftp/#ftpstatus","title":"ftpStatus()","text":"

      \u83b7\u53d6 FTP \u670d\u52a1\u5668\u72b6\u6001\u3002

      ftpStatus()\n

      \u8fd4\u56de\uff1a \u72b6\u6001\u63cf\u8ff0\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/ftp/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u914d\u7f6e FTP \u670d\u52a1\u5668\ndroid.ftpSet(\n    port=2121,\n    rootDir=\"/sdcard\",\n    username=\"admin\",\n    password=\"secret\"\n)\n\n# \u542f\u52a8 FTP \u670d\u52a1\u5668\ninfo = droid.ftpStart().result\nprint(f\"FTP running at {info[0]}:{info[1]}\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.ftpIsRunning().result:\n    print(\"FTP server is running\")\n\n# \u83b7\u53d6\u670d\u52a1\u5668\u4fe1\u606f\nserver_info = droid.ftpGet().result\nprint(f\"Server: {server_info}\")\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.ftpStop()\n

      \u6ce8\u610f\uff1a \u4f7f\u7528\u63d0\u4f9b\u7684\u51ed\u636e\u901a\u8fc7\u4efb\u4f55 FTP \u5ba2\u6237\u7aef\u8fde\u63a5\u5230 FTP \u670d\u52a1\u5668\u3002

      "},{"location":"qsl4a/connectivity/location/","title":"\u4f4d\u7f6e API","text":"

      \u8bbf\u95ee GPS \u548c\u7f51\u7edc\u4f4d\u7f6e\u670d\u52a1\u3002

      "},{"location":"qsl4a/connectivity/location/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/location/#startlocating","title":"startLocating()","text":"

      \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\u3002

      startLocating(minUpdateTime=60000, minUpdateDistance=30, updateGnssStatus=False)\n

      \u53c2\u6570\uff1a - minUpdateTime (int): \u66f4\u65b0\u4e4b\u95f4\u7684\u6700\u5c0f\u65f6\u95f4\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a60000\uff09 - minUpdateDistance (float): \u66f4\u65b0\u7684\u6700\u5c0f\u8ddd\u79bb\uff08\u7c73\uff09\uff08\u9ed8\u8ba4\uff1a30\uff09 - updateGnssStatus (bool): \u542f\u7528 GNSS \u72b6\u6001\u66f4\u65b0\uff08\u9ed8\u8ba4\uff1aFalse\uff09

      "},{"location":"qsl4a/connectivity/location/#stoplocating","title":"stopLocating()","text":"

      \u505c\u6b62\u4f4d\u7f6e\u66f4\u65b0\u3002

      stopLocating()\n
      "},{"location":"qsl4a/connectivity/location/#readlocation","title":"readLocation()","text":"

      \u83b7\u53d6\u6700\u540e\u5df2\u77e5\u4f4d\u7f6e\u3002

      readLocation()\n

      \u8fd4\u56de\uff1a \u4f4d\u7f6e\u6570\u636e\u5b57\u5178

      "},{"location":"qsl4a/connectivity/location/#getlastknownlocation","title":"getLastKnownLocation()","text":"

      \u83b7\u53d6\u7f13\u5b58\u7684\u4f4d\u7f6e\u3002

      getLastKnownLocation()\n

      \u8fd4\u56de\uff1a \u6765\u81ea\u6240\u6709\u63d0\u4f9b\u5546\u7684\u4f4d\u7f6e

      "},{"location":"qsl4a/connectivity/location/#geocode","title":"geocode()","text":"

      \u5c06\u5730\u5740\u8f6c\u6362\u4e3a\u5750\u6807\u3002

      geocode(address, maxResults=1)\n
      "},{"location":"qsl4a/connectivity/location/#_2","title":"\u4f4d\u7f6e\u63d0\u4f9b\u5546\u65b9\u6cd5)","text":""},{"location":"qsl4a/connectivity/location/#locationproviders","title":"locationProviders()","text":"

      \u83b7\u53d6\u624b\u673a\u4e0a\u53ef\u7528\u7684\u4f4d\u7f6e\u63d0\u4f9b\u5546\u3002

      locationProviders()\n

      \u8fd4\u56de\uff1a \u53ef\u7528\u63d0\u4f9b\u5546\u540d\u79f0\u5217\u8868\uff08\u4f8b\u5982 ['gps', 'network']\uff09

      "},{"location":"qsl4a/connectivity/location/#locationproviderenabled","title":"locationProviderEnabled()","text":"

      \u68c0\u67e5\u7279\u5b9a\u4f4d\u7f6e\u63d0\u4f9b\u5546\u662f\u5426\u5df2\u542f\u7528\u3002

      locationProviderEnabled(provider)\n

      \u53c2\u6570\uff1a - provider (str): \u63d0\u4f9b\u5546\u540d\u79f0\uff08\u4f8b\u5982 'gps', 'network'\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/connectivity/location/#readgnssstatus","title":"readGnssStatus()","text":"

      \u8bfb\u53d6\u5168\u7403\u5bfc\u822a\u536b\u661f\u7cfb\u7edf\u72b6\u6001\uff08\u9700\u8981 Android 8+\uff09\u3002

      readGnssStatus()\n

      \u8fd4\u56de\uff1a \u5305\u542b GNSS \u536b\u661f\u4fe1\u606f\u7684 JSONArray

      "},{"location":"qsl4a/connectivity/location/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\ndroid.startLocating(minUpdateTime=5000, minUpdateDistance=1, updateGnssStatus=False)\n\n# \u7b49\u5f85\u5b9a\u4f4d\ntime.sleep(10)\n\n# \u83b7\u53d6\u4f4d\u7f6e\nloc = droid.readLocation().result\nif loc:\n    lat = loc['latitude']\n    lon = loc['longitude']\n    print(f\"Location: {lat}, {lon}\")\n\ndroid.stopLocating()\n
      "},{"location":"qsl4a/connectivity/phone/","title":"\u7535\u8bdd API","text":"

      \u63a7\u5236\u7535\u8bdd\u901a\u8bdd\u548c\u83b7\u53d6\u7535\u8bdd\u4fe1\u606f\u3002

      "},{"location":"qsl4a/connectivity/phone/#_1","title":"\u7535\u8bdd\u72b6\u6001\u8ddf\u8e2a","text":""},{"location":"qsl4a/connectivity/phone/#starttrackingphonestate","title":"startTrackingPhoneState()","text":"

      \u5f00\u59cb\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u53d8\u5316\u3002\u751f\u6210 'phone' \u4e8b\u4ef6\u3002

      startTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/phone/#readphonestate","title":"readPhoneState()","text":"

      \u8bfb\u53d6\u5f53\u524d\u7535\u8bdd\u72b6\u6001\u3002

      readPhoneState()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7535\u8bdd\u72b6\u6001\u548c\u6765\u7535\u53f7\u7801\u7684 Bundle

      "},{"location":"qsl4a/connectivity/phone/#stoptrackingphonestate","title":"stopTrackingPhoneState()","text":"

      \u505c\u6b62\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u3002

      stopTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/phone/#_2","title":"\u62e8\u6253\u7535\u8bdd","text":""},{"location":"qsl4a/connectivity/phone/#phonecall","title":"phoneCall()","text":"

      \u901a\u8fc7 URI \u547c\u53eb\u8054\u7cfb\u4eba/\u7535\u8bdd\u53f7\u7801\u3002

      phoneCall(uri)\n

      \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

      "},{"location":"qsl4a/connectivity/phone/#phonecallnumber","title":"phoneCallNumber()","text":"

      \u76f4\u63a5\u62e8\u6253\u7535\u8bdd\u53f7\u7801\u3002

      phoneCallNumber(phone_number)\n

      \u53c2\u6570\uff1a - phone_number (str): \u8981\u62e8\u6253\u7684\u7535\u8bdd\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#phonedial","title":"phoneDial()","text":"

      \u62e8\u6253\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

      phoneDial(uri)\n

      \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

      "},{"location":"qsl4a/connectivity/phone/#phonedialnumber","title":"phoneDialNumber()","text":"

      \u62e8\u6253\u7535\u8bdd\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

      phoneDialNumber(phone_number)\n

      \u53c2\u6570\uff1a - phone_number (str): \u7535\u8bdd\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#_3","title":"\u57fa\u7ad9\u4f4d\u7f6e","text":""},{"location":"qsl4a/connectivity/phone/#getcelllocation","title":"getCellLocation()","text":"

      \u83b7\u53d6\u5f53\u524d\u57fa\u7ad9\u4f4d\u7f6e\u3002

      getCellLocation()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u57fa\u7ad9\u4f4d\u7f6e\u6570\u636e\u7684 JSONObject

      "},{"location":"qsl4a/connectivity/phone/#getallcellslocation","title":"getAllCellsLocation()","text":"

      \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u4f4d\u7f6e\uff08\u9002\u7528\u4e8e\u53cc\u5361\u8bbe\u5907\uff09\u3002

      getAllCellsLocation()\n

      \u8fd4\u56de\uff1a \u57fa\u7ad9\u4f4d\u7f6e\u7684 JSONArray

      "},{"location":"qsl4a/connectivity/phone/#_4","title":"\u7f51\u7edc\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getnetworkoperator","title":"getNetworkOperator()","text":"

      \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

      getNetworkOperator()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getnetworkoperatorname","title":"getNetworkOperatorName()","text":"

      \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684\u540d\u79f0\u3002

      getNetworkOperatorName()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getnetworktype","title":"getNetworkType()","text":"

      \u83b7\u53d6\u5f53\u524d\u7f51\u7edc\u7c7b\u578b\u3002

      getNetworkType()\n

      \u8fd4\u56de\uff1a \u63cf\u8ff0\u65e0\u7ebf\u7535\u6280\u672f\u7684\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'LTE', 'UMTS', 'GSM'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getphonetype","title":"getPhoneType()","text":"

      \u83b7\u53d6\u7535\u8bdd\u7c7b\u578b\u3002

      getPhoneType()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'GSM', 'CDMA', 'SIP'\uff09

      "},{"location":"qsl4a/connectivity/phone/#sim","title":"SIM \u5361\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getsimcountryiso","title":"getSimCountryIso()","text":"

      \u83b7\u53d6 SIM \u5361\u7684 ISO \u56fd\u5bb6\u4ee3\u7801\u3002

      getSimCountryIso()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'us'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getsimoperator","title":"getSimOperator()","text":"

      \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

      getSimOperator()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getsimoperatorname","title":"getSimOperatorName()","text":"

      \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u540d\u79f0\u3002

      getSimOperatorName()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getsimserialnumber","title":"getSimSerialNumber()","text":"

      \u83b7\u53d6 SIM \u5e8f\u5217\u53f7\u3002

      getSimSerialNumber()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32 SIM \u5e8f\u5217\u53f7

      "},{"location":"qsl4a/connectivity/phone/#getsimstate","title":"getSimState()","text":"

      \u83b7\u53d6 SIM \u5361\u72b6\u6001\u3002

      getSimState()\n

      \u8fd4\u56de\uff1a \u63cf\u8ff0 SIM \u72b6\u6001\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/phone/#getsubscriberid","title":"getSubscriberId()","text":"

      \u83b7\u53d6\u8ba2\u9605\u8005 ID\u3002

      getSubscriberId()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8ba2\u9605\u8005 ID

      "},{"location":"qsl4a/connectivity/phone/#_5","title":"\u8bed\u97f3\u90ae\u4ef6","text":""},{"location":"qsl4a/connectivity/phone/#getvoicemailalphatag","title":"getVoiceMailAlphaTag()","text":"

      \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u5b57\u6bcd\u6807\u7b7e\u3002

      getVoiceMailAlphaTag()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u6807\u7b7e

      "},{"location":"qsl4a/connectivity/phone/#getvoicemailnumber","title":"getVoiceMailNumber()","text":"

      \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801\u3002

      getVoiceMailNumber()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getdeviceid","title":"getDeviceId()","text":"

      \u83b7\u53d6\u8bbe\u5907 ID\uff08GSM \u7684 IMEI\uff09\u3002\u5df2\u5e9f\u5f03\u3002

      getDeviceId()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

      "},{"location":"qsl4a/connectivity/phone/#getdevicesoftwareversion","title":"getDeviceSoftwareVersion()","text":"

      \u83b7\u53d6\u8bbe\u5907\u8f6f\u4ef6\u7248\u672c\u3002

      getDeviceSoftwareVersion()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8f6f\u4ef6\u7248\u672c

      "},{"location":"qsl4a/connectivity/phone/#getline1number","title":"getLine1Number()","text":"

      \u83b7\u53d6\u7ebf\u8def 1 \u7535\u8bdd\u53f7\u7801\u3002

      getLine1Number()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u7535\u8bdd\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#checknetworkroaming","title":"checkNetworkRoaming()","text":"

      \u68c0\u67e5\u662f\u5426\u8fde\u63a5\u5230\u6f2b\u6e38\u7f51\u7edc\u3002

      checkNetworkRoaming()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u6f2b\u6e38\u5219\u4e3a True

      "},{"location":"qsl4a/connectivity/phone/#_7","title":"\u57fa\u7ad9\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getallcellinfo","title":"getAllCellInfo()","text":"

      \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u7684\u4fe1\u606f\u3002

      getAllCellInfo()\n

      \u8fd4\u56de\uff1a \u57fa\u7ad9\u4fe1\u606f\u5217\u8868

      "},{"location":"qsl4a/connectivity/phone/#setdataenabled","title":"setDataEnabled()","text":"

      \u542f\u7528\u6216\u7981\u7528\u79fb\u52a8\u6570\u636e\u3002

      setDataEnabled(enabled)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528

      "},{"location":"qsl4a/connectivity/phone/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7f51\u7edc\u4fe1\u606f\noperator = droid.getNetworkOperatorName().result\nprint(f\"Operator: {operator}\")\n\nnetwork_type = droid.getNetworkType().result\nprint(f\"Network: {network_type}\")\n\n# \u83b7\u53d6 SIM \u4fe1\u606f\nsim_state = droid.getSimState().result\nprint(f\"SIM: {sim_state}\")\n\n# \u83b7\u53d6\u7535\u8bdd\u53f7\u7801\nline1 = droid.getLine1Number().result\nprint(f\"Phone: {line1}\")\n\n# \u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\ndroid.startTrackingPhoneState()\nprint(\"Tracking phone state...\")\ndroid.stopTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/signalstrength/","title":"\u4fe1\u53f7\u5f3a\u5ea6 API","text":"

      \u76d1\u63a7\u8702\u7a9d\u548c\u65e0\u7ebf\u4fe1\u53f7\u5f3a\u5ea6\u3002

      "},{"location":"qsl4a/connectivity/signalstrength/#_1","title":"\u4fe1\u53f7\u5f3a\u5ea6\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/signalstrength/#starttrackingsignalstrengths","title":"startTrackingSignalStrengths()","text":"

      \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316\u3002\u751f\u6210 'signal_strengths' \u4e8b\u4ef6\u3002

      startTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/signalstrength/#stoptrackingsignalstrengths","title":"stopTrackingSignalStrengths()","text":"

      \u505c\u6b62\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u3002

      stopTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/signalstrength/#readsignalstrengths","title":"readSignalStrengths()","text":"

      \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\u3002

      readSignalStrengths()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u4fe1\u53f7\u5f3a\u5ea6\u6570\u636e\u7684 Bundle

      "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthlevel","title":"getTelephoneSignalStrengthLevel()","text":"

      \u83b7\u53d6\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u7b49\u7ea7\uff080-4\uff09\u3002

      getTelephoneSignalStrengthLevel()\n

      \u8fd4\u56de\uff1a \u6574\u6570\u7b49\u7ea7\uff080=\u65e0\uff0c1=\u5dee\uff0c2=\u4e00\u822c\uff0c3=\u597d\uff0c4=\u4f18\u79c0\uff09

      "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthdetail","title":"getTelephoneSignalStrengthDetail()","text":"

      \u83b7\u53d6\u8be6\u7ec6\u7684\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u4fe1\u606f\u3002

      getTelephoneSignalStrengthDetail()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u8be6\u7ec6\u4fe1\u53f7\u4fe1\u606f\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/signalstrength/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\ndroid.startTrackingSignalStrengths()\n\n# \u7b49\u5f85\u4fe1\u53f7\u66f4\u65b0\ntime.sleep(5)\n\n# \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\nsignal = droid.readSignalStrengths().result\nprint(f\"Signal: {signal}\")\n\n# \u76f4\u63a5\u83b7\u53d6\u7b49\u7ea7\nlevel = droid.getTelephoneSignalStrengthLevel().result\nprint(f\"Signal level: {level}/4\")\n\ndroid.stopTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/sms/","title":"SMS API","text":"

      \u53d1\u9001\u548c\u63a5\u6536 SMS \u6d88\u606f\u3002

      "},{"location":"qsl4a/connectivity/sms/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/sms/#smssend","title":"smsSend()","text":"

      \u53d1\u9001 SMS \u6d88\u606f\u3002

      smsSend(destinationAddress, text)\n

      \u53c2\u6570\uff1a - destinationAddress (str): \u7535\u8bdd\u53f7\u7801 - text (str): \u6d88\u606f\u6587\u672c

      "},{"location":"qsl4a/connectivity/sms/#smsgetmessagecount","title":"smsGetMessageCount()","text":"

      \u83b7\u53d6\u6d88\u606f\u6570\u91cf\u3002

      smsGetMessageCount(unreadOnly=False, folder=\"inbox\")\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessageids","title":"smsGetMessageIds()","text":"

      \u83b7\u53d6\u6d88\u606f ID\u3002

      smsGetMessageIds(unreadOnly=False, folder=\"inbox\")\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessages","title":"smsGetMessages()","text":"

      \u83b7\u53d6\u6d88\u606f\u8be6\u60c5\u3002

      smsGetMessages(unreadOnly=False, folder=\"inbox\", attributes=None)\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessagebyid","title":"smsGetMessageById()","text":"

      \u901a\u8fc7 ID \u83b7\u53d6\u7279\u5b9a\u6d88\u606f\u3002

      smsGetMessageById(id, attributes=None)\n

      \u53c2\u6570\uff1a - id (int): \u6d88\u606f ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

      \u8fd4\u56de\uff1a \u6d88\u606f\u6570\u636e\u5b57\u5178

      "},{"location":"qsl4a/connectivity/sms/#smsgetattributes","title":"smsGetAttributes()","text":"

      \u83b7\u53d6\u53ef\u7528\u7684 SMS \u6d88\u606f\u5c5e\u6027\u3002

      smsGetAttributes()\n

      \u8fd4\u56de\uff1a \u53ef\u7528\u5c5e\u6027\u540d\u79f0\u5217\u8868

      "},{"location":"qsl4a/connectivity/sms/#smsdeletemessage","title":"smsDeleteMessage()","text":"

      \u5220\u9664\u6d88\u606f\u3002

      smsDeleteMessage(id)\n
      "},{"location":"qsl4a/connectivity/sms/#smsmarkmessageread","title":"smsMarkMessageRead()","text":"

      \u5c06\u6d88\u606f\u6807\u8bb0\u4e3a\u5df2\u8bfb\u3002

      smsMarkMessageRead(ids, read=True)\n
      "},{"location":"qsl4a/connectivity/sms/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u53d1\u9001 SMS\ndroid.smsSend(\"+1234567890\", \"Hello from QPython!\")\n\n# \u83b7\u53d6\u672a\u8bfb\u6d88\u606f\nmessages = droid.smsGetMessages(unreadOnly=True).result\nfor msg in messages:\n    print(f\"From: {msg['address']}, Text: {msg['body']}\")\n
      "},{"location":"qsl4a/connectivity/wifi/","title":"WiFi API","text":"

      \u63a7\u5236 WiFi \u9002\u914d\u5668\u5e76\u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\u3002

      "},{"location":"qsl4a/connectivity/wifi/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/connectivity/wifi/#checkwifistate","title":"checkWifiState()","text":"

      \u68c0\u67e5 WiFi \u662f\u5426\u5df2\u542f\u7528\u3002

      checkWifiState()\n

      \u8fd4\u56de\uff1a \u5982\u679c WiFi \u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/connectivity/wifi/#togglewifistate","title":"toggleWifiState()","text":"

      \u6253\u5f00\u6216\u5173\u95ed WiFi\u3002

      toggleWifiState(enabled=None)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

      \u8fd4\u56de\uff1a \u5982\u679c\u64cd\u4f5c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/connectivity/wifi/#wifistartscan","title":"wifiStartScan()","text":"

      \u5f00\u59cb\u626b\u63cf\u53ef\u7528\u7684 WiFi \u7f51\u7edc\u3002

      wifiStartScan()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifigetscanresults","title":"wifiGetScanResults()","text":"

      \u83b7\u53d6\u53d1\u73b0\u7684 WiFi \u7f51\u7edc\u5217\u8868\u3002

      wifiGetScanResults()\n

      \u8fd4\u56de\uff1a \u63a5\u5165\u70b9\u4fe1\u606f\u5217\u8868

      "},{"location":"qsl4a/connectivity/wifi/#_2","title":"\u8fde\u63a5\u7ba1\u7406","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetconnectioninfo","title":"wifiGetConnectionInfo()","text":"

      \u83b7\u53d6\u8be6\u7ec6\u8fde\u63a5\u4fe1\u606f\u3002

      wifiGetConnectionInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001IP \u5730\u5740\u7b49\u8fde\u63a5\u8be6\u60c5\u7684\u5b57\u5178

      "},{"location":"qsl4a/connectivity/wifi/#getconnectedinfo","title":"getConnectedInfo()","text":"

      \u83b7\u53d6\u8fde\u63a5\u7684 WiFi \u7f51\u7edc\u4fe1\u606f\uff08\u7b80\u5316\u7248\uff09\u3002

      getConnectedInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001\u4fe1\u53f7\u5f3a\u5ea6\u7684\u5b57\u5178

      "},{"location":"qsl4a/connectivity/wifi/#getdhcpinfo","title":"getDhcpInfo()","text":"

      \u83b7\u53d6\u5f53\u524d\u8fde\u63a5\u7684 DHCP \u4fe1\u606f\u3002

      getDhcpInfo(ipConvertToString=True)\n

      \u53c2\u6570\uff1a - ipConvertToString (bool): \u5c06 IP \u5730\u5740\u8f6c\u6362\u4e3a\u5b57\u7b26\u4e32\u683c\u5f0f\uff08\u9ed8\u8ba4\uff1aTrue\uff09

      \u8fd4\u56de\uff1a \u5305\u542b IP\u3001\u7f51\u5173\u3001DNS \u7b49 DHCP \u4fe1\u606f\u7684\u5b57\u5178

      "},{"location":"qsl4a/connectivity/wifi/#wifidisconnect","title":"wifiDisconnect()","text":"

      \u65ad\u5f00\u5f53\u524d WiFi \u7f51\u7edc\u8fde\u63a5\u3002

      wifiDisconnect()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifireconnect","title":"wifiReconnect()","text":"

      \u91cd\u65b0\u8fde\u63a5\u5230\u5f53\u524d\u7f51\u7edc\u3002

      wifiReconnect()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifireassociate","title":"wifiReassociate()","text":"

      \u91cd\u65b0\u5173\u8054\u5f53\u524d\u63a5\u5165\u70b9\u3002

      wifiReassociate()\n
      "},{"location":"qsl4a/connectivity/wifi/#_3","title":"\u70ed\u70b9","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetapstate","title":"wifiGetApState()","text":"

      \u83b7\u53d6 WiFi AP\uff08\u70ed\u70b9\uff09\u72b6\u6001\u3002

      wifiGetApState()\n

      \u8fd4\u56de\uff1a \u70ed\u70b9\u72b6\u6001

      "},{"location":"qsl4a/connectivity/wifi/#wifi","title":"WiFi \u9501","text":""},{"location":"qsl4a/connectivity/wifi/#wifilockacquirefull","title":"wifiLockAcquireFull()","text":"

      \u83b7\u53d6\u5b8c\u6574 WiFi \u9501\uff08\u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\u4e5f\u4fdd\u6301 WiFi \u6d3b\u52a8\uff09\u3002

      wifiLockAcquireFull()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifilockacquirescanonly","title":"wifiLockAcquireScanOnly()","text":"

      \u83b7\u53d6\u4ec5\u626b\u63cf WiFi \u9501\u3002

      wifiLockAcquireScanOnly()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifilockrelease","title":"wifiLockRelease()","text":"

      \u91ca\u653e WiFi \u9501\u3002

      wifiLockRelease()\n
      "},{"location":"qsl4a/connectivity/wifi/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u68c0\u67e5 WiFi \u72b6\u6001\nif droid.checkWifiState().result:\n    print(\"WiFi is enabled\")\nelse:\n    print(\"Enabling WiFi...\")\n    droid.toggleWifiState(True)\n    time.sleep(2)\n\n# \u5f00\u59cb\u626b\u63cf\ndroid.wifiStartScan()\ntime.sleep(3)\n\n# \u83b7\u53d6\u626b\u63cf\u7ed3\u679c\nnetworks = droid.wifiGetScanResults().result\nfor network in networks:\n    print(f\"SSID: {network.get('SSID')}, Signal: {network.get('level')} dBm\")\n\n# \u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\ninfo = droid.wifiGetConnectionInfo().result\nif info:\n    print(f\"Connected to: {info.get('ssid')}\")\n    print(f\"BSSID: {info.get('bssid')}\")\n    print(f\"IP: {info.get('ip_address')}\")\n\n# \u83b7\u53d6 DHCP \u4fe1\u606f\ndhcp = droid.getDhcpInfo().result\nif dhcp:\n    print(f\"Gateway: {dhcp.get('gateway')}\")\n    print(f\"DNS: {dhcp.get('dns1')}\")\n\n# \u83b7\u53d6\u7b80\u5316\u7684\u8fde\u63a5\u4fe1\u606f\nconnected = droid.getConnectedInfo().result\nprint(f\"SSID: {connected.get('ssid')}, Signal: {connected.get('level')} dBm\")\n\n# \u65ad\u5f00\u5e76\u91cd\u65b0\u8fde\u63a5\ndroid.wifiDisconnect()\ntime.sleep(1)\ndroid.wifiReconnect()\n\n# \u91cd\u65b0\u5173\u8054\u63a5\u5165\u70b9\ndroid.wifiReassociate()\n\n# \u68c0\u67e5\u70ed\u70b9\u72b6\u6001\nap_state = droid.wifiGetApState().result\nprint(f\"Hotspot state: {ap_state}\")\n\n# \u83b7\u53d6 WiFi \u9501\u4ee5\u8fdb\u884c\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireFull()\n# ... \u6267\u884c\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n\n# \u6216\u4f7f\u7528\u4ec5\u626b\u63cf\u9501\u4ee5\u8fdb\u884c\u8f83\u8f7b\u7684\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireScanOnly()\n# ... \u6267\u884c\u626b\u63cf\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n
      "},{"location":"qsl4a/core/android-base/","title":"Android \u57fa\u7840\u7c7b","text":"

      Android \u7c7b\u662f QSL4A \u7684\u6838\u5fc3\uff0c\u63d0\u4f9b\u4e86\u4e0e Android \u8fd0\u884c\u65f6\u7684\u8fde\u63a5\u548c RPC \u673a\u5236\u3002

      "},{"location":"qsl4a/core/android-base/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
      # \u529f\u80fd\u5b8c\u6574\u7248\u672c\uff08\u63a8\u8350\uff09\nimport androidhelper\ndroid = androidhelper.Android()\n\n# \u7b80\u5316\u7248\u672c\uff08\u5feb\u901f\uff0c\u5355\u5b9e\u4f8b\uff09\nimport android\ndroid = android.droid\n
      "},{"location":"qsl4a/core/android-base/#android_1","title":"\u7c7b\uff1aAndroid","text":""},{"location":"qsl4a/core/android-base/#_2","title":"\u6784\u9020\u51fd\u6570","text":"
      Android(addr=None)\n

      \u53c2\u6570\uff1a - addr (tuple, optional): (HOST, PORT) \u5730\u5740\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u73af\u5883\u53d8\u91cf AP_HOST \u548c AP_PORT

      \u73af\u5883\u53d8\u91cf\uff1a - AP_HOST - \u670d\u52a1\u5668\u4e3b\u673a\u5730\u5740 - AP_PORT - \u670d\u52a1\u5668\u7aef\u53e3 - AP_HANDSHAKE - \u8ba4\u8bc1\u4ee4\u724c

      "},{"location":"qsl4a/core/android-base/#_3","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/android-base/#_rpc","title":"_rpc()","text":"

      \u8c03\u7528 Android \u51fd\u6570\u7684\u5185\u90e8 RPC \u65b9\u6cd5\u3002

      _rpc(method, *args)\n

      \u53c2\u6570\uff1a - method (str): \u8981\u8c03\u7528\u7684\u65b9\u6cd5\u540d - *args: \u65b9\u6cd5\u7684\u53ef\u53d8\u53c2\u6570

      \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4\uff0c\u5305\u542b\u4ee5\u4e0b\u5b57\u6bb5\uff1a - id (int): \u8bf7\u6c42 ID - result: \u65b9\u6cd5\u8fd4\u56de\u503c - error (str or None): \u9519\u8bef\u4fe1\u606f\uff08\u5982\u679c\u5931\u8d25\uff09

      "},{"location":"qsl4a/core/android-base/#getattr","title":"getattr()","text":"

      \u52a8\u6001\u65b9\u6cd5\u5206\u53d1\u5668\u3002\u6240\u6709 Android \u65b9\u6cd5\u90fd\u901a\u8fc7\u5c5e\u6027\u67e5\u627e\u8bbf\u95ee\u3002

      # \u4ee5\u4e0b\u4e24\u79cd\u65b9\u5f0f\u7b49\u4ef7\uff1a\ndroid.makeToast(\"Hello\")\ndroid._rpc(\"makeToast\", \"Hello\")\n
      "},{"location":"qsl4a/core/android-base/#androidpy","title":"\u72ec\u7acb\u51fd\u6570\uff08android.py\uff09","text":"

      \u4f7f\u7528\u7b80\u5316\u7684 android \u6a21\u5757\u65f6\uff1a

      "},{"location":"qsl4a/core/android-base/#jsla","title":"jsla()","text":"

      \u53d1\u9001 JSON-RPC \u8bf7\u6c42\u5e76\u8fd4\u56de\u539f\u59cb\u54cd\u5e94\u3002

      jsla(method, *params)\n

      \u8fd4\u56de\uff1a JSON \u5b57\u7b26\u4e32\u54cd\u5e94

      "},{"location":"qsl4a/core/android-base/#rsla","title":"rsla()","text":"

      \u53d1\u9001\u8bf7\u6c42\u5e76\u4ec5\u8fd4\u56de\u7ed3\u679c\u3002

      rsla(method, *params)\n

      \u8fd4\u56de\uff1a RPC \u8c03\u7528\u7684\u7ed3\u679c\u503c

      "},{"location":"qsl4a/core/android-base/#esla","title":"esla()","text":"

      \u53d1\u9001\u8bf7\u6c42\uff0c\u9519\u8bef\u65f6\u629b\u51fa\u5f02\u5e38\u3002

      esla(method, *params)\n

      \u629b\u51fa\uff1a \u5982\u679c error \u5b57\u6bb5\u4e0d\u4e3a None \u5219\u629b\u51fa\u5f02\u5e38

      "},{"location":"qsl4a/core/android-base/#nsla","title":"nsla()","text":"

      \u53d1\u9001\u8bf7\u6c42\u5e76\u8fd4\u56de Result \u547d\u540d\u5143\u7ec4\u3002

      nsla(method, *params)\n

      \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4

      "},{"location":"qsl4a/core/android-base/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/android-base/#_5","title":"\u57fa\u672c\u8fde\u63a5","text":"
      import androidhelper\n\n# \u8fde\u63a5\u5230 Android \u8fd0\u884c\u65f6\ndroid = androidhelper.Android()\n\n# \u901a\u8fc7\u663e\u793a toast \u6765\u68c0\u67e5\u8fde\u63a5\ndroid.makeToast(\"Connected!\")\n
      "},{"location":"qsl4a/core/android-base/#_6","title":"\u9519\u8bef\u5904\u7406","text":"
      result = droid.someMethod()\nif result.error:\n    print(f\"Error: {result.error}\")\nelse:\n    print(f\"Success: {result.result}\")\n
      "},{"location":"qsl4a/core/android-base/#rpc","title":"\u76f4\u63a5 RPC \u8c03\u7528","text":"
      # \u76f4\u63a5\u8c03\u7528\u4efb\u610f\u65b9\u6cd5\nresult = droid._rpc(\"makeToast\", \"Hello World\")\n
      "},{"location":"qsl4a/core/events/","title":"\u4e8b\u4ef6\u7cfb\u7edf","text":"

      QSL4A \u63d0\u4f9b\u4e86\u4e00\u4e2a\u4e8b\u4ef6\u7cfb\u7edf\uff0c\u7528\u4e8e\u5904\u7406\u6765\u81ea Android \u7684\u5f02\u6b65\u4e8b\u4ef6\uff0c\u5982\u4f20\u611f\u5668\u66f4\u65b0\u3001\u4f4d\u7f6e\u53d8\u5316\u548c\u81ea\u5b9a\u4e49\u5e7f\u64ad\u3002

      "},{"location":"qsl4a/core/events/#_2","title":"\u4e8b\u4ef6\u57fa\u7840","text":"

      \u4e8b\u4ef6\u5b58\u50a8\u5728\u7f13\u51b2\u533a\u4e2d\uff0c\u53ef\u4ee5\u8f6e\u8be2\u6216\u7b49\u5f85\u3002\u6bcf\u4e2a\u4e8b\u4ef6\u5305\u542b\uff1a - name: \u4e8b\u4ef6\u7c7b\u578b/\u540d\u79f0 - data: \u4e8b\u4ef6\u8d1f\u8f7d\u6570\u636e - time: \u65f6\u95f4\u6233

      "},{"location":"qsl4a/core/events/#_3","title":"\u4e8b\u4ef6\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#eventclearbuffer","title":"eventClearBuffer()","text":"

      \u6e05\u9664\u7f13\u51b2\u533a\u4e2d\u7684\u6240\u6709\u5f85\u5904\u7406\u4e8b\u4ef6\u3002

      eventClearBuffer()\n

      \u8fd4\u56de\uff1a None

      "},{"location":"qsl4a/core/events/#eventpoll","title":"eventPoll()","text":"

      \u8f6e\u8be2\u7f13\u51b2\u533a\u4e2d\u7684\u4e8b\u4ef6\u3002

      eventPoll(number_of_events=1)\n

      \u53c2\u6570\uff1a - number_of_events (int): \u8981\u68c0\u7d22\u7684\u6700\u5927\u4e8b\u4ef6\u6570\uff08\u9ed8\u8ba4\uff1a1\uff09

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\u5217\u8868

      "},{"location":"qsl4a/core/events/#eventwait","title":"eventWait()","text":"

      \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\u3002

      eventWait(timeout=None)\n

      \u53c2\u6570\uff1a - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09\u3002None = \u6c38\u4e45\u7b49\u5f85

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

      "},{"location":"qsl4a/core/events/#eventwaitfor","title":"eventWaitFor()","text":"

      \u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6\u3002

      eventWaitFor(eventName, timeout=None)\n

      \u53c2\u6570\uff1a - eventName (str): \u8981\u7b49\u5f85\u7684\u4e8b\u4ef6\u540d\u79f0 - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

      "},{"location":"qsl4a/core/events/#eventpost","title":"eventPost()","text":"

      \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\u3002

      eventPost(name, data, enqueue=None)\n

      \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e\uff08\u4efb\u610f\u7c7b\u578b\uff09 - enqueue (bool, optional): \u5982\u679c\u4e3a True \u5219\u6dfb\u52a0\u5230\u961f\u5217

      "},{"location":"qsl4a/core/events/#receiveevent","title":"receiveEvent()","text":"

      \u63a5\u6536\u4e8b\u4ef6\uff08\u963b\u585e\uff09\u3002

      receiveEvent()\n

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61

      "},{"location":"qsl4a/core/events/#_4","title":"\u5e7f\u64ad\u4e8b\u4ef6","text":"

      \u6ce8\u518c\u7cfb\u7edf\u5e7f\u64ad\u4e8b\u4ef6\u3002

      "},{"location":"qsl4a/core/events/#eventregisterforbroadcast","title":"eventRegisterForBroadcast()","text":"

      \u6ce8\u518c\u63a5\u6536\u5e7f\u64ad\u4e8b\u4ef6\u3002

      eventRegisterForBroadcast(category, enqueue=True)\n

      \u53c2\u6570\uff1a - category (str): \u5e7f\u64ad\u7c7b\u522b/\u52a8\u4f5c - enqueue (bool): \u6dfb\u52a0\u5230\u4e8b\u4ef6\u961f\u5217

      "},{"location":"qsl4a/core/events/#eventunregisterforbroadcast","title":"eventUnregisterForBroadcast()","text":"

      \u53d6\u6d88\u6ce8\u518c\u5e7f\u64ad\u4e8b\u4ef6\u3002

      eventUnregisterForBroadcast(category)\n
      "},{"location":"qsl4a/core/events/#eventgetbrodcastcategories","title":"eventGetBrodcastCategories()","text":"

      \u83b7\u53d6\u5df2\u6ce8\u518c\u7684\u5e7f\u64ad\u7c7b\u522b\u3002

      eventGetBrodcastCategories()\n

      \u8fd4\u56de\uff1a \u5df2\u6ce8\u518c\u7c7b\u522b\u5217\u8868

      "},{"location":"qsl4a/core/events/#_5","title":"\u4e8b\u4ef6\u5206\u53d1\u5668)","text":""},{"location":"qsl4a/core/events/#starteventdispatcher","title":"startEventDispatcher()","text":"

      \u6253\u5f00\u4e00\u4e2a\u53ef\u4ee5\u8bfb\u53d6\u5df2\u53d1\u5e03\u4e8b\u4ef6\u7684\u5957\u63a5\u5b57\u3002)

      startEventDispatcher(port=0)\n

      \u53c2\u6570\uff1a - port (int, optional): \u76d1\u542c\u7684\u7aef\u53e3\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\u9009\u62e9\uff09

      \u8fd4\u56de\uff1a \u6b63\u5728\u76d1\u542c\u7684\u7aef\u53e3\u53f7

      "},{"location":"qsl4a/core/events/#stopeventdispatcher","title":"stopEventDispatcher()","text":"

      \u505c\u6b62\u4e8b\u4ef6\u670d\u52a1\u5668\u3002)

      stopEventDispatcher()\n
      "},{"location":"qsl4a/core/events/#_6","title":"\u5df2\u5e9f\u5f03\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#rpcpostevent","title":"rpcPostEvent()","text":"

      \u5c06\u4e8b\u4ef6\u53d1\u5e03\u5230\u4e8b\u4ef6\u961f\u5217\u3002\uff08\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 eventPost\uff09

      rpcPostEvent(name, data)\n

      \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e

      "},{"location":"qsl4a/core/events/#_7","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/events/#_8","title":"\u57fa\u672c\u4e8b\u4ef6\u8f6e\u8be2","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6e05\u9664\u65e7\u4e8b\u4ef6\ndroid.eventClearBuffer()\n\n# \u8f6e\u8be2\u4e8b\u4ef6\nevents = droid.eventPoll(5).result\nfor event in events:\n    print(f\"Event: {event['name']}, Data: {event['data']}\")\n
      "},{"location":"qsl4a/core/events/#_9","title":"\u7b49\u5f85\u4e8b\u4ef6","text":"
      # \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\uff0c\u5e26\u8d85\u65f6\nevent = droid.eventWait(timeout=10).result\nif event:\n    print(f\"Got event: {event['name']}\")\n
      "},{"location":"qsl4a/core/events/#_10","title":"\u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6","text":"
      # \u7b49\u5f85\u4f20\u611f\u5668\u4e8b\u4ef6\nevent = droid.eventWaitFor('screen', timeout=5).result\nif event:\n    print(f\"Screen event: {event['data']}\")\n
      "},{"location":"qsl4a/core/events/#_11","title":"\u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6","text":"
      # \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\ndroid.eventPost('my_event', {'key': 'value'})\n\n# \u7b49\u5f85\u5b83\nevent = droid.eventWaitFor('my_event', timeout=1).result\n
      "},{"location":"qsl4a/core/events/#_12","title":"\u5e7f\u64ad\u63a5\u6536\u5668","text":"
      # \u6ce8\u518c\u5c4f\u5e55\u5f00\u5173\u4e8b\u4ef6\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_ON')\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_OFF')\n\n# \u7b49\u5f85\u5c4f\u5e55\u4e8b\u4ef6\nwhile True:\n    event = droid.receiveEvent().result\n    if event['name'] == 'android.intent.action.SCREEN_ON':\n        print(\"Screen turned on\")\n    elif event['name'] == 'android.intent.action.SCREEN_OFF':\n        print(\"Screen turned off\")\n
      "},{"location":"qsl4a/core/events/#_13","title":"\u4f20\u611f\u5668\u4e8b\u4ef6\u5904\u7406","text":"
      # \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u5904\u7406\u4f20\u611f\u5668\u4e8b\u4ef6\nfor _ in range(100):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'sensors':\n        data = event['data']\n        print(f\"Accel: {data['xforce']}, {data['yforce']}, {data['zforce']}\")\n\ndroid.stopSensing()\n
      "},{"location":"qsl4a/core/events/#_14","title":"\u5e38\u89c1\u4e8b\u4ef6\u7c7b\u578b","text":"\u4e8b\u4ef6\u540d\u79f0 \u63cf\u8ff0 \u6765\u6e90 sensors \u4f20\u611f\u5668\u6570\u636e\u66f4\u65b0 startSensing* location GPS \u4f4d\u7f6e\u66f4\u65b0 startLocating phone \u7535\u8bdd\u72b6\u6001\u53d8\u5316 startTrackingPhoneState signal \u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316 startTrackingSignalStrength screen \u622a\u56fe\u5c31\u7eea fullGetScreenShot dialog \u5bf9\u8bdd\u6846\u54cd\u5e94 dialogShow*"},{"location":"qsl4a/core/events/#_15","title":"\u4e8b\u4ef6\u6570\u636e\u7ed3\u6784","text":"
      {\n    'name': 'event_name',\n    'data': {\n        # \u4e8b\u4ef6\u7279\u5b9a\u6570\u636e\n    },\n    'time': 1234567890  # \u65f6\u95f4\u6233\n}\n
      "},{"location":"qsl4a/core/intent/","title":"Intent \u7cfb\u7edf","text":"

      Android Intent \u7528\u4e8e\u542f\u52a8\u6d3b\u52a8\u3001\u53d1\u9001\u5e7f\u64ad\u548c\u5e94\u7528\u95f4\u901a\u4fe1\u3002QSL4A \u901a\u8fc7 Intent \u6a21\u5757\u63d0\u4f9b\u5b8c\u6574\u7684 Intent \u652f\u6301\u3002

      "},{"location":"qsl4a/core/intent/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
      import androidhelper\ndon = androidhelper.Android()\n
      "},{"location":"qsl4a/core/intent/#intent_1","title":"Intent \u5e38\u91cf","text":"

      \u901a\u8fc7 droid.Intent \u8bbf\u95ee\uff1a

      "},{"location":"qsl4a/core/intent/#_2","title":"\u64cd\u4f5c","text":"\u5e38\u91cf \u503c \u7528\u9014 ACTION_MAIN android.intent.action.MAIN \u5e94\u7528\u5165\u53e3\u70b9 ACTION_VIEW android.intent.action.VIEW \u67e5\u770b\u5185\u5bb9 ACTION_EDIT android.intent.action.EDIT \u7f16\u8f91\u5185\u5bb9 ACTION_PICK android.intent.action.PICK \u9009\u62e9\u9879\u76ee ACTION_SEND android.intent.action.SEND \u5206\u4eab\u5185\u5bb9 ACTION_SEARCH android.intent.action.SEARCH \u641c\u7d22"},{"location":"qsl4a/core/intent/#_3","title":"\u6807\u5fd7","text":"\u5e38\u91cf \u503c \u7528\u9014 FLAG_ACTIVITY_NEW_TASK 268435456 \u542f\u52a8\u65b0\u4efb\u52a1 FLAG_ACTIVITY_CLEAR_TASK 32768 \u6e05\u9664\u4efb\u52a1\u5806\u6808 FLAG_ACTIVITY_NEW_DOCUMENT 524288 \u65b0\u6587\u6863\u6a21\u5f0f"},{"location":"qsl4a/core/intent/#_4","title":"\u9644\u52a0\u6570\u636e","text":"\u5e38\u91cf \u7528\u9014 EXTRA_TEXT \u6587\u672c\u5185\u5bb9 EXTRA_STREAM \u6587\u4ef6 URI EXTRA_SUBJECT \u4e3b\u9898\u884c EXTRA_EMAIL \u7535\u5b50\u90ae\u4ef6\u5730\u5740"},{"location":"qsl4a/core/intent/#_5","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/intent/#makeintent","title":"makeIntent()","text":"

      \u521b\u5efa Intent \u5bf9\u8c61\u3002

      makeIntent(action, uri=None, type=None, extras=None, categories=None,\n           packagename=None, classname=None, flags=None)\n

      \u53c2\u6570\uff1a - action (str): Intent \u64cd\u4f5c\uff08\u4f8b\u5982 droid.Intent.ACTION_VIEW\uff09 - uri (str, optional): \u6570\u636e URI - type (str, optional): MIME \u7c7b\u578b - extras (dict, optional): \u9644\u52a0\u6570\u636e - categories (list, optional): Intent \u7c7b\u522b - packagename (str, optional): \u76ee\u6807\u5305 - classname (str, optional): \u76ee\u6807\u7c7b - flags (int, optional): Intent \u6807\u5fd7

      \u8fd4\u56de\uff1a Intent \u5bf9\u8c61

      "},{"location":"qsl4a/core/intent/#startactivityintent","title":"startActivityIntent()","text":"

      \u4f7f\u7528 Intent \u542f\u52a8 Activity\u3002

      startActivityIntent(intent, wait=None)\n

      \u53c2\u6570\uff1a - intent: makeIntent() \u8fd4\u56de\u7684 Intent \u5bf9\u8c61 - wait (bool, optional): \u963b\u585e\u76f4\u5230\u6d3b\u52a8\u5173\u95ed

      "},{"location":"qsl4a/core/intent/#startactivityforresultintent","title":"startActivityForResultIntent()","text":"

      \u542f\u52a8\u6d3b\u52a8\u5e76\u7b49\u5f85\u7ed3\u679c\u3002

      startActivityForResultIntent(intent)\n

      \u8fd4\u56de\uff1a Activity \u7ed3\u679c

      "},{"location":"qsl4a/core/intent/#sendbroadcastintent","title":"sendBroadcastIntent()","text":"

      \u53d1\u9001\u5e7f\u64ad\u3002

      sendBroadcastIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#view","title":"view()","text":"

      \u901a\u8fc7 URI \u67e5\u770b\u5185\u5bb9\u3002

      view(uri, type=None, extras=None)\n
      "},{"location":"qsl4a/core/intent/#pick","title":"pick()","text":"

      \u4ece URI \u9009\u62e9\u5185\u5bb9\u3002

      pick(uri)\n
      "},{"location":"qsl4a/core/intent/#intent_2","title":"\u5e38\u89c1 Intent \u65b9\u6cd5)","text":""},{"location":"qsl4a/core/intent/#scanbarcode","title":"scanBarcode()","text":"

      \u542f\u52a8\u6761\u7801\u626b\u63cf\u5668\u3002

      scanBarcode()\n

      \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/core/intent/#send","title":"send()","text":"

      \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u5185\u5bb9\u3002

      send(type, content)\n

      \u53c2\u6570\uff1a - type (str): MIME \u7c7b\u578b - content (str): \u8981\u5206\u4eab\u7684\u5185\u5bb9

      "},{"location":"qsl4a/core/intent/#sendtext","title":"sendText()","text":"

      \u53d1\u9001\u6587\u672c\u5185\u5bb9\u3002

      sendText(text)\n

      \u53c2\u6570\uff1a - text (str): \u8981\u53d1\u9001\u7684\u6587\u672c

      "},{"location":"qsl4a/core/intent/#sendemail","title":"sendEmail()","text":"

      \u53d1\u9001\u7535\u5b50\u90ae\u4ef6\u3002

      sendEmail(to, subject, body, attachment=None)\n

      \u53c2\u6570\uff1a - to (str or list): \u6536\u4ef6\u4eba\u7535\u5b50\u90ae\u4ef6\u5730\u5740 - subject (str): \u7535\u5b50\u90ae\u4ef6\u4e3b\u9898 - body (str): \u7535\u5b50\u90ae\u4ef6\u6b63\u6587 - attachment (str, optional): \u9644\u4ef6\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/core/intent/#pathtouri","title":"pathToUri()","text":"

      \u5c06\u6587\u4ef6\u8def\u5f84\u8f6c\u6362\u4e3a\u5185\u5bb9 URI\u3002

      pathToUri(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5185\u5bb9 URI \u5b57\u7b26\u4e32

      "},{"location":"qsl4a/core/intent/#openfile","title":"openFile()","text":"

      \u7528\u9002\u5f53\u7684\u5e94\u7528\u7a0b\u5e8f\u6253\u5f00\u6587\u4ef6\u3002

      openFile(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u6253\u5f00\u7684\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/core/intent/#sendfile","title":"sendFile()","text":"

      \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u6587\u4ef6\u3002

      sendFile(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u53d1\u9001\u7684\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/core/intent/#getpathtype","title":"getPathType()","text":"

      \u83b7\u53d6\u6587\u4ef6\u8def\u5f84\u7684 MIME \u7c7b\u578b\u3002

      getPathType(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a MIME \u7c7b\u578b\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/core/intent/#viewmap","title":"viewMap()","text":"

      \u5728\u6307\u5b9a\u4f4d\u7f6e\u6253\u5f00\u5730\u56fe\u3002

      viewMap(latitude, longitude)\n

      \u53c2\u6570\uff1a - latitude (float): \u7eac\u5ea6 - longitude (float): \u7ecf\u5ea6

      "},{"location":"qsl4a/core/intent/#viewcontacts","title":"viewContacts()","text":"

      \u6253\u5f00\u8054\u7cfb\u4eba\u5e94\u7528\u3002

      viewContacts()\n
      "},{"location":"qsl4a/core/intent/#search","title":"search()","text":"

      \u6267\u884c\u7f51\u7edc\u641c\u7d22\u3002

      search(query)\n

      \u53c2\u6570\uff1a - query (str): \u641c\u7d22\u67e5\u8be2

      "},{"location":"qsl4a/core/intent/#viewhtml","title":"viewHtml()","text":"

      \u67e5\u770b HTML \u5185\u5bb9\u3002

      viewHtml(content, encoding=None)\n

      \u53c2\u6570\uff1a - content (str): HTML \u5185\u5bb9 - encoding (str, optional): \u5b57\u7b26\u7f16\u7801

      "},{"location":"qsl4a/core/intent/#webviewshow","title":"webViewShow()","text":"

      \u5728 WebView \u4e2d\u663e\u793a\u7f51\u9875\u5185\u5bb9\u3002\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 viewHtml\u3002

      webViewShow(url)\n

      \u53c2\u6570\uff1a - url (str): \u7f51\u9875 URL

      "},{"location":"qsl4a/core/intent/#editoropen","title":"editorOpen()","text":"

      \u6253\u5f00\u6587\u672c\u7f16\u8f91\u5668\u3002

      editorOpen(path=None, create=False)\n

      \u53c2\u6570\uff1a - path (str, optional): \u8981\u7f16\u8f91\u7684\u6587\u4ef6\u8def\u5f84 - create (bool, optional): \u5982\u679c\u4e0d\u5b58\u5728\u5219\u521b\u5efa

      "},{"location":"qsl4a/core/intent/#uri","title":"\u8f85\u52a9\u7c7b\uff1aUri","text":"

      \u521b\u5efa Intent \u7684 URI \u5bf9\u8c61\uff1a

      from androidhelper.Intent import Uri\n\nuri = Uri(\"file:///sdcard/test.txt\")\n
      "},{"location":"qsl4a/core/intent/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/intent/#_7","title":"\u6253\u5f00\u7f51\u9875","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"http://www.example.com\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_8","title":"\u5206\u4eab\u6587\u672c","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_TEXT: \"Hello from QPython!\",\n        droid.Intent.EXTRA_SUBJECT: \"Test\"\n    },\n    type=\"text/plain\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_9","title":"\u6253\u5f00\u6587\u4ef6","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"file:///sdcard/document.pdf\",\n    type=\"application/pdf\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_10","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":"
      result = droid.pickContact()\ncontact_uri = result.result\n
      "},{"location":"qsl4a/core/intent/#_11","title":"\u53d1\u9001\u7535\u5b50\u90ae\u4ef6","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_EMAIL: [\"test@example.com\"],\n        droid.Intent.EXTRA_SUBJECT: \"Hello\",\n        droid.Intent.EXTRA_TEXT: \"Message body\"\n    },\n    type=\"message/rfc822\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_12","title":"\u6253\u5f00\u5e94\u7528","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_MAIN,\n    packagename=\"com.android.settings\",\n    classname=\"com.android.settings.Settings\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/hardware/bluetooth/","title":"\u84dd\u7259 API","text":"

      \u63a7\u5236\u84dd\u7259\u9002\u914d\u5668\u5e76\u4e0e\u84dd\u7259\u8bbe\u5907\u901a\u4fe1\u3002

      "},{"location":"qsl4a/hardware/bluetooth/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/hardware/bluetooth/#togglebluetoothstate","title":"toggleBluetoothState()","text":"

      \u6253\u5f00/\u5173\u95ed\u84dd\u7259\u3002

      toggleBluetoothState(enabled=None, prompt=True)\n

      \u53c2\u6570\uff1a - enabled (bool): True=\u5f00\uff0cFalse=\u5173\uff0cNone=\u5207\u6362 - prompt (bool): \u663e\u793a\u7528\u6237\u63d0\u793a

      "},{"location":"qsl4a/hardware/bluetooth/#checkbluetoothstate","title":"checkBluetoothState()","text":"

      \u68c0\u67e5\u84dd\u7259\u662f\u5426\u5df2\u542f\u7528\u3002

      checkBluetoothState()\n

      \u8fd4\u56de\uff1a True/False

      "},{"location":"qsl4a/hardware/bluetooth/#getlocalname","title":"GetLocalName()","text":"

      \u83b7\u53d6\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

      GetLocalName()\n
      "},{"location":"qsl4a/hardware/bluetooth/#setlocalname","title":"SetLocalName()","text":"

      \u8bbe\u7f6e\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

      SetLocalName(name)\n
      "},{"location":"qsl4a/hardware/bluetooth/#getscanmode","title":"GetScanMode()","text":"

      \u83b7\u53d6\u53ef\u53d1\u73b0\u6027\u6a21\u5f0f\u3002

      GetScanMode()\n

      \u8fd4\u56de\uff1a - -1: \u5df2\u7981\u7528 - 0: \u4e0d\u53ef\u53d1\u73b0\uff0c\u4e0d\u53ef\u8fde\u63a5 - 1: \u53ef\u8fde\u63a5\uff0c\u4e0d\u53ef\u53d1\u73b0 - 3: \u53ef\u8fde\u63a5\u4e14\u53ef\u53d1\u73b0

      "},{"location":"qsl4a/hardware/bluetooth/#makediscoverable","title":"MakeDiscoverable()","text":"

      \u4f7f\u8bbe\u5907\u53ef\u53d1\u73b0\u3002

      MakeDiscoverable(duration=300)\n

      \u53c2\u6570\uff1a - duration (int): \u53ef\u53d1\u73b0\u7684\u79d2\u6570

      "},{"location":"qsl4a/hardware/bluetooth/#_2","title":"\u53d1\u73b0","text":""},{"location":"qsl4a/hardware/bluetooth/#discoverystart","title":"DiscoveryStart()","text":"

      \u5f00\u59cb\u8bbe\u5907\u53d1\u73b0\u3002

      DiscoveryStart()\n
      "},{"location":"qsl4a/hardware/bluetooth/#discoverycancel","title":"DiscoveryCancel()","text":"

      \u53d6\u6d88\u53d1\u73b0\u3002

      DiscoveryCancel()\n
      "},{"location":"qsl4a/hardware/bluetooth/#getreceiveddevices","title":"GetReceivedDevices()","text":"

      \u83b7\u53d6\u53d1\u73b0\u7684\u8bbe\u5907\u3002

      GetReceivedDevices()\n

      \u8fd4\u56de\uff1a \u8bbe\u5907\u4fe1\u606f\u5b57\u5178\u5217\u8868

      "},{"location":"qsl4a/hardware/bluetooth/#getbondeddevices","title":"GetBondedDevices()","text":"

      \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\u3002

      GetBondedDevices()\n

      \u8fd4\u56de\uff1a \u914d\u5bf9\u8bbe\u5907\u4fe1\u606f\u5217\u8868

      "},{"location":"qsl4a/hardware/bluetooth/#_3","title":"\u8fde\u63a5","text":""},{"location":"qsl4a/hardware/bluetooth/#connect","title":"Connect()","text":"

      \u8fde\u63a5\u5230\u8bbe\u5907\u3002

      Connect(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", address=None)\n

      \u53c2\u6570\uff1a - uuid (str): \u670d\u52a1 UUID - address (str): \u8bbe\u5907\u5730\u5740\uff08None = \u663e\u793a\u9009\u62e9\u5668\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/hardware/bluetooth/#accept","title":"Accept()","text":"

      \u63a5\u53d7\u4f20\u5165\u8fde\u63a5\u3002

      Accept(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", timeout=0)\n
      "},{"location":"qsl4a/hardware/bluetooth/#activeconnections","title":"ActiveConnections()","text":"

      \u68c0\u67e5\u6d3b\u52a8\u8fde\u63a5\u3002

      ActiveConnections()\n
      "},{"location":"qsl4a/hardware/bluetooth/#stop","title":"Stop()","text":"

      \u65ad\u5f00\u8fde\u63a5\u3002

      Stop(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#_4","title":"\u901a\u4fe1","text":""},{"location":"qsl4a/hardware/bluetooth/#write","title":"Write()","text":"

      \u53d1\u9001 ASCII \u6570\u636e\u3002

      Write(ascii, connID=\"\")\n
      "},{"location":"qsl4a/hardware/bluetooth/#writebinary","title":"WriteBinary()","text":"

      \u53d1\u9001\u4e8c\u8fdb\u5236\u6570\u636e\uff08base64 \u7f16\u7801\uff09\u3002

      WriteBinary(base64, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#read","title":"Read()","text":"

      \u8bfb\u53d6 ASCII \u6570\u636e\u3002

      Read(bufferSize=4096, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readbinary","title":"ReadBinary()","text":"

      \u8bfb\u53d6\u4e8c\u8fdb\u5236\u6570\u636e\u3002

      ReadBinary(bufferSize=4096, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readline","title":"ReadLine()","text":"

      \u8bfb\u53d6\u4e00\u884c\u3002

      ReadLine(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readready","title":"ReadReady()","text":"

      \u68c0\u67e5\u662f\u5426\u6709\u53ef\u7528\u6570\u636e\u3002

      ReadReady(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u7528\u84dd\u7259\ndroid.toggleBluetoothState(True)\n\n# \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\ndevices = droid.GetBondedDevices().result\nfor dev in devices:\n    print(f\"{dev['name']}: {dev['address']}\")\n\n# \u8fde\u63a5\u5230\u8bbe\u5907\ndroid.Connect(address=\"00:11:22:33:44:55\")\n\n# \u53d1\u9001\u6570\u636e\ndroid.Write(\"Hello Bluetooth!\")\n\n# \u8bfb\u53d6\u54cd\u5e94\ndata = droid.Read(1024).result\n
      "},{"location":"qsl4a/hardware/camera/","title":"\u76f8\u673a API","text":"

      \u62cd\u6444\u7167\u7247\u548c\u5f55\u5236\u89c6\u9891\u3002

      "},{"location":"qsl4a/hardware/camera/#_1","title":"\u7167\u7247\u62cd\u6444","text":""},{"location":"qsl4a/hardware/camera/#takepicture","title":"takePicture()","text":"

      \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u6444\u7167\u7247\u3002

      takePicture(path=None)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8fd4\u56de\u56fe\u50cf\u6570\u636e

      \u8fd4\u56de\uff1a \u56fe\u50cf\u8def\u5f84\u6216\u56fe\u50cf\u6570\u636e

      "},{"location":"qsl4a/hardware/camera/#cameracapturepicture","title":"cameraCapturePicture()","text":"

      \u4f7f\u7528\u9ad8\u7ea7\u76f8\u673a\u63a7\u5236\u62cd\u6444\u7167\u7247\u3002

      cameraCapturePicture(targetPath=None, cameraId=0, useAutoFocus=True)\n

      \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - useAutoFocus (bool): \u542f\u7528\u81ea\u52a8\u5bf9\u7126

      \u8fd4\u56de\uff1a \u62cd\u6444\u7684\u56fe\u50cf\u8def\u5f84

      "},{"location":"qsl4a/hardware/camera/#camerasettorchmode","title":"cameraSetTorchMode()","text":"

      \u63a7\u5236\u76f8\u673a\u95ea\u5149\u706f/\u624b\u7535\u7b52\u3002

      cameraSetTorchMode(enabled)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u6253\u5f00\uff0cFalse \u5173\u95ed

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/hardware/camera/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

      \u622a\u56fe\u3002

      imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

      "},{"location":"qsl4a/hardware/camera/#_2","title":"\u89c6\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#takevideo","title":"takeVideo()","text":"

      \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\u3002

      takeVideo(path=None, quality=1)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-4\uff09 - 0: 160x120 - 1: 320x240 - 2: 352x288 - 3: 640x480 - 4: 800x480

      "},{"location":"qsl4a/hardware/camera/#recordercapturevideo","title":"recorderCaptureVideo()","text":"

      \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\u3002

      recorderCaptureVideo(targetPath=None, duration=10, cameraId=0, quality=8)\n

      \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - duration (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a10\uff09 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-8\uff0c\u8d8a\u9ad8\u8d8a\u597d\uff09

      \u8fd4\u56de\uff1a \u89c6\u9891\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/hardware/camera/#recordaudio","title":"recordAudio()","text":"

      \u5f55\u5236\u97f3\u9891\u3002

      recordAudio()\n

      \u8fd4\u56de\uff1a \u97f3\u9891\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/hardware/camera/#_3","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

      \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\u3002

      recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

      \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\uff09 - targetPixels (int): \u5206\u8fa8\u7387 - frameRate (int): FPS - bitRate (int): \u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa - autoStart (bool): \u7acb\u5373\u5f00\u59cb

      "},{"location":"qsl4a/hardware/camera/#recorderstart","title":"recorderStart()","text":"

      \u5f00\u59cb\u5f55\u5236\u3002

      recorderStart()\n
      "},{"location":"qsl4a/hardware/camera/#recorderpause","title":"recorderPause()","text":"

      \u6682\u505c\u5f55\u5236\u3002

      recorderPause()\n
      "},{"location":"qsl4a/hardware/camera/#recorderresume","title":"recorderResume()","text":"

      \u6062\u590d\u5f55\u5236\u3002

      recorderResume()\n
      "},{"location":"qsl4a/hardware/camera/#_4","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/camera/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

      \u5f00\u59cb\u97f3\u91cf\u68c0\u6d4b\u3002

      recorderSoundVolumeDetect(interval=100)\n
      "},{"location":"qsl4a/hardware/camera/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

      \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

      recorderSoundVolumeGetDb()\n
      "},{"location":"qsl4a/hardware/camera/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u7167\nphoto_path = droid.takePicture(\"/sdcard/photo.jpg\").result\nprint(f\"Photo saved: {photo_path}\")\n\n# \u4f7f\u7528\u524d\u7f6e\u76f8\u673a\u548c\u81ea\u52a8\u5bf9\u7126\u62cd\u7167\ncamera_path = droid.cameraCapturePicture(\"/sdcard/selfie.jpg\", cameraId=1, useAutoFocus=True).result\nprint(f\"Front camera photo: {camera_path}\")\n\n# \u63a7\u5236\u95ea\u5149\u706f\ndroid.cameraSetTorchMode(True)  # \u6253\u5f00\u95ea\u5149\u706f\n\n# \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\nvideo_path = droid.takeVideo(\"/sdcard/video.mp4\", quality=3).result\nprint(f\"Video saved: {video_path}\")\n\n# \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\nvideo_path = droid.recorderCaptureVideo(\"/sdcard/movie.mp4\", duration=30, cameraId=0, quality=8).result\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n
      "},{"location":"qsl4a/hardware/recorder/","title":"\u97f3\u9891\u5f55\u5236 API","text":"

      \u4ece\u9ea6\u514b\u98ce\u548c\u8bbe\u5907\u5c4f\u5e55\u5f55\u5236\u97f3\u9891\u3002

      "},{"location":"qsl4a/hardware/recorder/#_1","title":"\u97f3\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recordaudio","title":"recordAudio()","text":"

      \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\u3002

      recordAudio()\n

      \u8fd4\u56de\uff1a \u5f55\u5236\u7684\u97f3\u9891\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/hardware/recorder/#recorderstartmicrophone","title":"recorderStartMicrophone()","text":"

      \u5f00\u59cb\u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\u3002

      recorderStartMicrophone(targetPath=None)\n

      \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u5f55\u5236\u7684\u8def\u5f84

      "},{"location":"qsl4a/hardware/recorder/#_2","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

      \u5f00\u59cb\u5e26\u97f3\u9891\u7684\u5c4f\u5e55\u5f55\u5236\u3002

      recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

      \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\u97f3\u9891\uff09 - targetPixels (int): \u76ee\u6807\u5206\u8fa8\u7387\uff08\u50cf\u7d20\uff09 - frameRate (int): \u6bcf\u79d2\u5e27\u6570\uff08\u9ed8\u8ba4\uff1a30\uff09 - bitRate (int): \u89c6\u9891\u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa\u89c6\u9891 - autoStart (bool): \u7acb\u5373\u5f00\u59cb\u5f55\u5236

      \u8fd4\u56de\uff1a \u64cd\u4f5c\u7ed3\u679c

      "},{"location":"qsl4a/hardware/recorder/#recorderstart","title":"recorderStart()","text":"

      \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\uff08\u5f53 autoStart=False \u65f6\uff09\u3002

      recorderStart()\n
      "},{"location":"qsl4a/hardware/recorder/#recorderpause","title":"recorderPause()","text":"

      \u6682\u505c\u6b63\u5728\u8fdb\u884c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

      recorderPause()\n
      "},{"location":"qsl4a/hardware/recorder/#recorderresume","title":"recorderResume()","text":"

      \u6062\u590d\u6682\u505c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

      recorderResume()\n
      "},{"location":"qsl4a/hardware/recorder/#_3","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/recorder/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

      \u5f00\u59cb\u76d1\u63a7\u97f3\u91cf\u7ea7\u522b\u3002

      recorderSoundVolumeDetect(interval=100)\n

      \u53c2\u6570\uff1a - interval (int): \u68c0\u6d4b\u95f4\u9694\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a100\uff09

      "},{"location":"qsl4a/hardware/recorder/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

      \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

      recorderSoundVolumeGetDb()\n

      \u8fd4\u56de\uff1a \u5f53\u524d\u97f3\u91cf\u7ea7\u522b\uff08dB\uff09

      "},{"location":"qsl4a/hardware/recorder/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\nprint(\"Recording audio...\")\naudio_path = droid.recordAudio().result\nprint(f\"Saved to: {audio_path}\")\n\n# \u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\ndroid.recorderStartMicrophone(\"/sdcard/my_recording.mp3\")\ntime.sleep(5)\ndroid.recorderStop()\n\n# \u5e26\u97f3\u9891\u5f55\u5236\u5c4f\u5e55\nprint(\"Starting screen recording...\")\ndroid.recorderStartScreenRecord(\n    path=\"/sdcard/screen_record.mp4\",\n    audio=1,\n    frameRate=30,\n    autoStart=True\n)\ntime.sleep(10)\ndroid.recorderStop()\n\n# \u76d1\u63a7\u97f3\u91cf\ndroid.recorderSoundVolumeDetect(interval=100)\ntime.sleep(3)\nvolume = droid.recorderSoundVolumeGetDb().result\nprint(f\"Current volume: {volume} dB\")\n
      "},{"location":"qsl4a/hardware/usbserial/","title":"USB \u4e3b\u673a\u4e32\u884c API","text":"

      \u4e0e USB \u4e32\u884c\u8bbe\u5907\u901a\u4fe1\uff08\u9700\u8981 USB OTG \u652f\u6301\u548c Android 3.1+\uff09\u3002

      "},{"location":"qsl4a/hardware/usbserial/#usb","title":"USB \u4e32\u884c\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialopen","title":"usbHostSerialOpen()","text":"

      \u6253\u5f00\u4e0e USB \u4e32\u884c\u8bbe\u5907\u7684\u8fde\u63a5\u3002

      usbHostSerialOpen(device, baudRate=9600)\n

      \u53c2\u6570\uff1a - device (str): USB \u8bbe\u5907\u8def\u5f84\u6216\u6807\u8bc6\u7b26 - baudRate (int): \u6ce2\u7279\u7387\uff08\u9ed8\u8ba4\uff1a9600\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u6253\u5f00\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialclose","title":"usbHostSerialClose()","text":"

      \u5173\u95ed USB \u4e32\u884c\u8fde\u63a5\u3002

      usbHostSerialClose()\n
      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialread","title":"usbHostSerialRead()","text":"

      \u4ece USB \u4e32\u884c\u8bfb\u53d6\u6570\u636e\u3002

      usbHostSerialRead(bufferSize=1024)\n

      \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570\uff08\u9ed8\u8ba4\uff1a1024\uff09

      \u8fd4\u56de\uff1a \u8bfb\u53d6\u7684\u6570\u636e\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwrite","title":"usbHostSerialWrite()","text":"

      \u5411 USB \u4e32\u884c\u5199\u5165\u6570\u636e\u3002

      usbHostSerialWrite(data)\n

      \u53c2\u6570\uff1a - data (str): \u8981\u5199\u5165\u7684\u5b57\u7b26\u4e32\u6570\u636e

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialavailable","title":"usbHostSerialAvailable()","text":"

      \u68c0\u67e5\u662f\u5426\u6709\u53ef\u8bfb\u53d6\u7684\u6570\u636e\u3002

      usbHostSerialAvailable()\n

      \u8fd4\u56de\uff1a \u53ef\u7528\u5b57\u8282\u6570

      "},{"location":"qsl4a/hardware/usbserial/#_1","title":"\u914d\u7f6e\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetbaudrate","title":"usbHostSerialSetBaudRate()","text":"

      \u8bbe\u7f6e\u6ce2\u7279\u7387\u3002

      usbHostSerialSetBaudRate(baudRate)\n

      \u53c2\u6570\uff1a - baudRate (int): \u6ce2\u7279\u7387

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetdatabits","title":"usbHostSerialSetDataBits()","text":"

      \u8bbe\u7f6e\u6570\u636e\u4f4d\uff085\u30016\u30017 \u6216 8\uff09\u3002

      usbHostSerialSetDataBits(dataBits)\n

      \u53c2\u6570\uff1a - dataBits (int): \u6570\u636e\u4f4d\uff085-8\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetstopbits","title":"usbHostSerialSetStopBits()","text":"

      \u8bbe\u7f6e\u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09\u3002

      usbHostSerialSetStopBits(stopBits)\n

      \u53c2\u6570\uff1a - stopBits (float): \u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetparity","title":"usbHostSerialSetParity()","text":"

      \u8bbe\u7f6e\u6821\u9a8c\u4f4d\uff08\u65e0\u3001\u5947\u3001\u5076\u3001\u6807\u8bb0\u3001\u7a7a\u683c\uff09\u3002

      usbHostSerialSetParity(parity)\n

      \u53c2\u6570\uff1a - parity (str): \u6821\u9a8c\u6a21\u5f0f\uff08'none'\u3001'odd'\u3001'even'\u3001'mark'\u3001'space'\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetflowcontrol","title":"usbHostSerialSetFlowControl()","text":"

      \u8bbe\u7f6e\u6d41\u63a7\u5236\uff08\u65e0\u3001\u786c\u4ef6\u3001\u8f6f\u4ef6\uff09\u3002

      usbHostSerialSetFlowControl(flowControl)\n

      \u53c2\u6570\uff1a - flowControl (str): \u6d41\u63a7\u5236\u6a21\u5f0f\uff08'none'\u3001'hardware'\u3001'software'\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialreadhex","title":"usbHostSerialReadHex()","text":"

      \u4ee5\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u8bfb\u53d6\u6570\u636e\u3002

      usbHostSerialReadHex(bufferSize=1024)\n

      \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570

      \u8fd4\u56de\uff1a \u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwritehex","title":"usbHostSerialWriteHex()","text":"

      \u4ece\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u5199\u5165\u6570\u636e\u3002

      usbHostSerialWriteHex(hexString)\n

      \u53c2\u6570\uff1a - hexString (str): \u8981\u5199\u5165\u7684\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/hardware/usbserial/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6253\u5f00 USB \u4e32\u884c\u8fde\u63a5\nif droid.usbHostSerialOpen(\"/dev/bus/usb/001/001\", 115200).result:\n    print(\"USB serial opened\")\n\n    # \u5199\u5165\u6570\u636e\n    droid.usbHostSerialWrite(\"AT\\r\")\n\n    # \u8bfb\u53d6\u54cd\u5e94\n    response = droid.usbHostSerialRead(1024).result\n    print(f\"Response: {response}\")\n\n    # \u6216\u4f7f\u7528\u5341\u516d\u8fdb\u5236\n    droid.usbHostSerialWriteHex(\"41540D0A\")  # \"AT\\r\\n\"\n\n    # \u5173\u95ed\u8fde\u63a5\n    droid.usbHostSerialClose()\n

      \u6ce8\u610f\uff1a USB \u4e32\u884c\u9700\u8981\uff1a - Android 3.1+ (API 12) - USB OTG \u7ebf/\u9002\u914d\u5668 - \u8bbe\u5907\u4e0a\u7684 USB \u4e3b\u673a\u6a21\u5f0f\u652f\u6301 - \u517c\u5bb9\u7684\u4e32\u884c\u8bbe\u5907

      "},{"location":"qsl4a/hardware/webcam/","title":"\u7f51\u7edc\u6444\u50cf\u5934 API","text":"

      \u4f7f\u7528 MJPEG \u4ece\u8bbe\u5907\u76f8\u673a\u6d41\u5f0f\u4f20\u8f93\u89c6\u9891\u3002

      "},{"location":"qsl4a/hardware/webcam/#mjpeg","title":"MJPEG \u6d41\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#webcamstart","title":"webcamStart()","text":"

      \u4ece\u7f51\u7edc\u6444\u50cf\u5934\u542f\u52a8 MJPEG \u6d41\u3002

      webcamStart(resolutionLevel=0, jpegQuality=20, port=0)\n

      \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf 1-100\uff08\u9ed8\u8ba4\uff1a20\uff09 - port (int): \u7aef\u53e3\u53f7\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\uff09

      \u8fd4\u56de\uff1a \u6d41\u7684 (\u5730\u5740, \u7aef\u53e3) \u5143\u7ec4

      "},{"location":"qsl4a/hardware/webcam/#webcamadjustquality","title":"webcamAdjustQuality()","text":"

      \u8c03\u6574\u6d3b\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u7684\u8d28\u91cf\u3002

      webcamAdjustQuality(resolutionLevel=0, jpegQuality=20)\n

      \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b - jpegQuality (int): JPEG \u8d28\u91cf 1-100

      "},{"location":"qsl4a/hardware/webcam/#webcamstop","title":"webcamStop()","text":"

      \u505c\u6b62\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u3002

      webcamStop()\n
      "},{"location":"qsl4a/hardware/webcam/#_1","title":"\u76f8\u673a\u9884\u89c8\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#camerastartpreview","title":"cameraStartPreview()","text":"

      \u5f00\u59cb\u5e26\u4e8b\u4ef6\u751f\u6210\u7684\u76f8\u673a\u9884\u89c8\u6a21\u5f0f\u3002

      cameraStartPreview(resolutionLevel=0, jpegQuality=20, filepath=None)\n

      \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf\uff08\u9ed8\u8ba4\uff1a20\uff09 - filepath (str, optional): \u4fdd\u5b58\u9884\u89c8\u5e27\u7684\u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      \u6ce8\u610f\uff1a \u751f\u6210\u5e26\u6709\u5e27\u6570\u636e\u7684 'preview' \u4e8b\u4ef6\u3002

      "},{"location":"qsl4a/hardware/webcam/#camerastoppreview","title":"cameraStopPreview()","text":"

      \u505c\u6b62\u76f8\u673a\u9884\u89c8\u3002

      cameraStopPreview()\n
      "},{"location":"qsl4a/hardware/webcam/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\nstream_info = droid.webcamStart(\n    resolutionLevel=0,\n    jpegQuality=30,\n    port=8080\n).result\nprint(f\"Stream available at {stream_info[0]}:{stream_info[1]}\")\n\n# \u6d41\u5f0f\u4f20\u8f93\u65f6\u8c03\u6574\u8d28\u91cf\ntime.sleep(5)\ndroid.webcamAdjustQuality(resolutionLevel=1, jpegQuality=50)\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.webcamStop()\n\n# \u6216\u4f7f\u7528\u9884\u89c8\u6a21\u5f0f\nprint(\"Starting preview...\")\ndroid.cameraStartPreview()\n\n# \u7b49\u5f85\u9884\u89c8\u4e8b\u4ef6\nfor i in range(10):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'preview':\n        print(f\"Got preview frame: {event['data']}\")\n\ndroid.cameraStopPreview()\n
      "},{"location":"qsl4a/media/image/","title":"\u56fe\u50cf\u5904\u7406 API","text":"

      \u538b\u7f29\u548c\u5904\u7406\u56fe\u50cf\u3002

      "},{"location":"qsl4a/media/image/#_1","title":"\u56fe\u50cf\u538b\u7f29","text":""},{"location":"qsl4a/media/image/#imagecompress","title":"imageCompress()","text":"

      \u538b\u7f29\u56fe\u50cf\u6587\u4ef6\u3002

      imageCompress(srcPath, destPath, targetByteSize=0, targetWidth=0, targetHeight=0)\n

      \u53c2\u6570\uff1a - srcPath (str): \u6e90\u56fe\u50cf\u8def\u5f84 - destPath (str): \u8f93\u51fa\u8def\u5f84 - targetByteSize (int): \u76ee\u6807\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff080 = \u65e0\u9650\u5236\uff09 - targetWidth (int): \u76ee\u6807\u5bbd\u5ea6\uff080 = \u539f\u59cb\uff09 - targetHeight (int): \u76ee\u6807\u9ad8\u5ea6\uff080 = \u539f\u59cb\uff09

      \u8fd4\u56de\uff1a \u538b\u7f29\u540e\u7684\u56fe\u50cf\u8def\u5f84

      "},{"location":"qsl4a/media/image/#_2","title":"\u622a\u56fe","text":""},{"location":"qsl4a/media/image/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

      \u622a\u53d6\u5c4f\u5e55\u3002

      imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

      \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

      \u8fd4\u56de\uff1a \u622a\u56fe\u8def\u5f84

      "},{"location":"qsl4a/media/image/#_3","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/image/#videoplay","title":"videoPlay()","text":"

      \u5728\u5168\u5c4f\u6a21\u5f0f\u4e0b\u64ad\u653e\u89c6\u9891\u6587\u4ef6\u3002

      videoPlay(path, wait=True)\n

      \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

      "},{"location":"qsl4a/media/image/#_4","title":"\u6761\u7801\u626b\u63cf","text":""},{"location":"qsl4a/media/image/#scanbarcodefromimage","title":"scanBarcodeFromImage()","text":"

      \u4ece\u56fe\u50cf\u6587\u4ef6\u626b\u63cf\u6761\u7801/\u4e8c\u7ef4\u7801\u3002

      scanBarcodeFromImage(path, compressRatio=0, x=0, y=0, width=0, height=0)\n

      \u53c2\u6570\uff1a - path (str): \u56fe\u50cf\u6587\u4ef6\u8def\u5f84 - compressRatio (int): \u538b\u7f29\u6bd4\uff080 = \u4e0d\u538b\u7f29\uff09 - x, y, width, height (int): \u8981\u626b\u63cf\u7684\u533a\u57df\uff080 = \u5b8c\u6574\u56fe\u50cf\uff09

      \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5185\u5bb9

      "},{"location":"qsl4a/media/image/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n\n# \u538b\u7f29\u56fe\u50cf\ncompressed = droid.imageCompress(\n    \"/sdcard/large_photo.jpg\",\n    \"/sdcard/compressed.jpg\",\n    targetByteSize=102400,  # \u76ee\u6807\u7ea6 100KB\n    targetWidth=1920,\n    targetHeight=1080\n).result\nprint(f\"Saved: {compressed}\")\n\n# \u64ad\u653e\u89c6\u9891\nvideo_path = \"/sdcard/movie.mp4\"\ndroid.videoPlay(video_path, wait=True)\n\n# \u4ece\u56fe\u50cf\u626b\u63cf\u6761\u7801\nresult = droid.scanBarcodeFromImage(\"/sdcard/qr_code.png\").result\nprint(f\"Barcode: {result}\")\n
      "},{"location":"qsl4a/media/mediaplayer/","title":"\u5a92\u4f53\u64ad\u653e\u5668 API","text":"

      \u63a7\u5236\u97f3\u9891\u548c\u89c6\u9891\u64ad\u653e\u3002

      "},{"location":"qsl4a/media/mediaplayer/#_1","title":"\u64ad\u653e\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplay","title":"mediaPlay()","text":"

      \u64ad\u653e\u5a92\u4f53\u6587\u4ef6\u3002

      mediaPlay(url, tag=\"default\", play=True)\n

      \u53c2\u6570\uff1a - url (str): \u5a92\u4f53\u6587\u4ef6\u8def\u5f84\u6216 URL - tag (str): \u64ad\u653e\u5668\u6807\u8bc6\u7b26 - play (bool): \u81ea\u52a8\u5f00\u59cb\u64ad\u653e

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaystart","title":"mediaPlayStart()","text":"

      \u5f00\u59cb\u64ad\u653e\u3002

      mediaPlayStart(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplaypause","title":"mediaPlayPause()","text":"

      \u6682\u505c\u64ad\u653e\u3002

      mediaPlayPause(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplayclose","title":"mediaPlayClose()","text":"

      \u5173\u95ed\u64ad\u653e\u5668\u3002

      mediaPlayClose(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplayseek","title":"mediaPlaySeek()","text":"

      \u8df3\u8f6c\u5230\u4f4d\u7f6e\u3002

      mediaPlaySeek(msec, tag=\"default\")\n

      \u53c2\u6570\uff1a - msec (int): \u4f4d\u7f6e\uff08\u6beb\u79d2\uff09

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaysetlooping","title":"mediaPlaySetLooping()","text":"

      \u8bbe\u7f6e\u5faa\u73af\u6a21\u5f0f\u3002

      mediaPlaySetLooping(enabled, tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#_2","title":"\u64ad\u653e\u5668\u4fe1\u606f","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplayinfo","title":"mediaPlayInfo()","text":"

      \u83b7\u53d6\u64ad\u653e\u4fe1\u606f\u3002

      mediaPlayInfo(tag=\"default\")\n

      \u8fd4\u56de\uff1a \u5305\u542b\u65f6\u957f\u3001\u4f4d\u7f6e\u7b49\u7684\u5b57\u5178

      "},{"location":"qsl4a/media/mediaplayer/#mediaisplaying","title":"mediaIsPlaying()","text":"

      \u68c0\u67e5\u662f\u5426\u6b63\u5728\u64ad\u653e\u3002

      mediaIsPlaying(tag=\"default\")\n

      \u8fd4\u56de\uff1a True/False

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaylist","title":"mediaPlayList()","text":"

      \u5217\u51fa\u6d3b\u52a8\u64ad\u653e\u5668\u3002

      mediaPlayList()\n
      "},{"location":"qsl4a/media/mediaplayer/#_3","title":"\u97f3\u91cf\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#getmediavolume","title":"getMediaVolume()","text":"

      \u83b7\u53d6\u5a92\u4f53\u97f3\u91cf\u3002

      getMediaVolume()\n

      \u8fd4\u56de\uff1a \u97f3\u91cf\u7ea7\u522b\uff080-15\uff09

      "},{"location":"qsl4a/media/mediaplayer/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

      getMaxMediaVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#getringervolume","title":"getRingerVolume()","text":"

      \u83b7\u53d6\u94c3\u58f0\u97f3\u91cf\u3002

      getRingerVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

      getMaxRingerVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#_4","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/mediaplayer/#videoplay","title":"videoPlay()","text":"

      \u5168\u5c4f\u64ad\u653e\u89c6\u9891\u3002

      videoPlay(path, wait=True)\n

      \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210

      "},{"location":"qsl4a/media/mediaplayer/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u64ad\u653e\u97f3\u9891\ndroid.mediaPlay(\"/sdcard/music.mp3\", tag=\"music\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.mediaIsPlaying(\"music\").result:\n    info = droid.mediaPlayInfo(\"music\").result\n    print(f\"Playing: {info}\")\n\n# \u8df3\u8f6c\u5230 30 \u79d2\ndroid.mediaPlaySeek(30000, \"music\")\n\n# \u5173\u95ed\ndroid.mediaPlayClose(\"music\")\n\n# \u64ad\u653e\u89c6\u9891\ndroid.videoPlay(\"/sdcard/movie.mp4\", wait=True)\n
      "},{"location":"qsl4a/special/cipher/","title":"\u5bc6\u7801 API","text":"

      \u7528\u4e8e\u5b89\u5168\u6570\u636e\u5b58\u50a8\u7684\u52a0\u5bc6\u548c\u89e3\u5bc6\u5de5\u5177\u3002

      "},{"location":"qsl4a/special/cipher/#_1","title":"\u521d\u59cb\u5316","text":""},{"location":"qsl4a/special/cipher/#cipherinit","title":"cipherInit()","text":"

      \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u548c\u7b97\u6cd5\u521d\u59cb\u5316\u5bc6\u7801\u5668\u3002

      cipherInit(key, algorithm=\"AES/CBC/PKCS5Padding\", encodingFormat=\"\", initialVector=\"\")\n

      \u53c2\u6570\uff1a - key (str or bytes): \u52a0\u5bc6\u5bc6\u94a5 - algorithm (str): \u5bc6\u7801\u7b97\u6cd5\uff08\u9ed8\u8ba4\uff1a\"AES/CBC/PKCS5Padding\"\uff09 - encodingFormat (str): \u7f16\u7801\u683c\u5f0f - initialVector (str or bytes): \u52a0\u5bc6\u7684\u521d\u59cb\u5411\u91cf

      \u8fd4\u56de\uff1a \u521d\u59cb\u5316\u7ed3\u679c

      \u6ce8\u610f\uff1a \u5fc5\u987b\u5728\u4efb\u4f55\u52a0\u5bc6/\u89e3\u5bc6\u64cd\u4f5c\u4e4b\u524d\u8c03\u7528\u3002

      "},{"location":"qsl4a/special/cipher/#_2","title":"\u52a0\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#encryptstring","title":"encryptString()","text":"

      \u52a0\u5bc6\u5b57\u7b26\u4e32\u3002

      encryptString(plainText)\n

      \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c

      \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/special/cipher/#encryptbytes","title":"encryptBytes()","text":"

      \u52a0\u5bc6\u5b57\u8282\u6570\u636e\u3002

      encryptBytes(data)\n

      \u53c2\u6570\uff1a - data (bytes): \u8981\u52a0\u5bc6\u7684\u6570\u636e

      \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u8282

      "},{"location":"qsl4a/special/cipher/#encryptstringtofile","title":"encryptStringToFile()","text":"

      \u52a0\u5bc6\u5b57\u7b26\u4e32\u5230\u6587\u4ef6\u3002

      encryptStringToFile(plainText, filePath)\n

      \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c - filePath (str): \u8f93\u51fa\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/special/cipher/#encryptbytestofile","title":"encryptBytesToFile()","text":"

      \u52a0\u5bc6\u5b57\u8282\u5230\u6587\u4ef6\u3002

      encryptBytesToFile(data, filePath)\n
      "},{"location":"qsl4a/special/cipher/#_3","title":"\u89e3\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#decryptstring","title":"decryptString()","text":"

      \u89e3\u5bc6\u4e3a\u5b57\u7b26\u4e32\u3002

      decryptString(cipherText)\n

      \u53c2\u6570\uff1a - cipherText (str): \u52a0\u5bc6\u7684\u6587\u672c

      \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/special/cipher/#decryptbytes","title":"decryptBytes()","text":"

      \u89e3\u5bc6\u4e3a\u5b57\u8282\u3002

      decryptBytes(data)\n

      \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u8282

      "},{"location":"qsl4a/special/cipher/#decryptfiletostring","title":"decryptFileToString()","text":"

      \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u7b26\u4e32\u3002

      decryptFileToString(filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryptfiletobytes","title":"decryptFileToBytes()","text":"

      \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u8282\u3002

      decryptFileToBytes(filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryptfile","title":"decryptFile()","text":"

      \u89e3\u5bc6\u6587\u4ef6\u5230\u6587\u4ef6\u3002

      decryptFile(srcPath, destPath)\n
      "},{"location":"qsl4a/special/cipher/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u521d\u59cb\u5316\u5bc6\u7801\u5668\ndroid.cipherInit(\"my_secret_key_1234\")\n\n# \u52a0\u5bc6\u5b57\u7b26\u4e32\nencrypted = droid.encryptString(\"Secret message!\").result\nprint(f\"Encrypted: {encrypted}\")\n\n# \u89e3\u5bc6\u5b57\u7b26\u4e32\ndecrypted = droid.decryptString(encrypted).result\nprint(f\"Decrypted: {decrypted}\")\n\n# \u52a0\u5bc6\u5230\u6587\u4ef6\ndroid.encryptStringToFile(\"My secret data\", \"/sdcard/secret.dat\")\n\n# \u4ece\u6587\u4ef6\u89e3\u5bc6\ndata = droid.decryptFileToString(\"/sdcard/secret.dat\").result\nprint(data)\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u7b97\u6cd5\u548c IV \u521d\u59cb\u5316\ndroid.cipherInit(\n    key=\"my_key\",\n    algorithm=\"AES/CBC/PKCS5Padding\",\n    initialVector=\"0123456789abcdef\"\n)\n
      "},{"location":"qsl4a/special/pgptai/","title":"PGPT AI API","text":"

      \u8bed\u97f3\u8f6c\u6587\u672c\u548c AI \u670d\u52a1\u96c6\u6210\u3002

      "},{"location":"qsl4a/special/pgptai/#_1","title":"\u5148\u51b3\u6761\u4ef6","text":"
      pip install pgptAI\n
      "},{"location":"qsl4a/special/pgptai/#_2","title":"\u8bed\u97f3\u8bc6\u522b","text":""},{"location":"qsl4a/special/pgptai/#speechtotext","title":"speechToText()","text":"

      \u5c06\u8bed\u97f3\u8f6c\u6362\u4e3a\u6587\u672c\u3002

      speechToText(RecordSecond=10, AmrFile=None, Language=None)\n

      \u53c2\u6570\uff1a - RecordSecond (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09 - AmrFile (str, optional): \u73b0\u6709\u97f3\u9891\u6587\u4ef6\u8def\u5f84 - Language (str, optional): \u8bed\u8a00\u4ee3\u7801\uff08'en'\u3001'zh'\uff09

      \u8fd4\u56de\uff1a \u8f6c\u5f55\u7684\u6587\u672c

      "},{"location":"qsl4a/special/pgptai/#_3","title":"\u6587\u672c\u8f6c\u8bed\u97f3","text":""},{"location":"qsl4a/special/pgptai/#texttospeech","title":"textToSpeech()","text":"

      \u5c06\u6587\u672c\u8f6c\u6362\u4e3a\u8bed\u97f3\u5e76\u53ef\u9009\u5730\u64ad\u653e\u3002

      textToSpeech(Text, AutoPlay=True, WavFile=None, VoiceName=None)\n

      \u53c2\u6570\uff1a - Text (str): \u8981\u8f6c\u6362\u4e3a\u8bed\u97f3\u7684\u6587\u672c - AutoPlay (bool): \u81ea\u52a8\u64ad\u653e\u751f\u6210\u7684\u97f3\u9891\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - WavFile (str, optional): \u4fdd\u5b58 WAV \u6587\u4ef6\u7684\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u4e34\u65f6\u6587\u4ef6 - VoiceName (str, optional): \u8981\u4f7f\u7528\u7684\u8bed\u97f3\u540d\u79f0\uff08\u4f8b\u5982 'en-US-JennyNeural'\u3001'zh-CN-XiaoxiaoNeural'\uff09

      \u8fd4\u56de\uff1a \u5305\u542b\u8bed\u97f3\u5408\u6210\u7ed3\u679c\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - text: \u8f93\u5165\u6587\u672c - url: \u4e0b\u8f7d\u97f3\u9891\u6587\u4ef6\u7684 URL - WavFile: \u4fdd\u5b58\u7684 WAV \u6587\u4ef6\u8def\u5f84\uff08\u5982\u679c\u672c\u5730\u4fdd\u5b58\uff09

      "},{"location":"qsl4a/special/pgptai/#_4","title":"\u914d\u7f6e","text":"

      API \u4f7f\u7528\u4ee5\u4e0b\u914d\u7f6e\u6587\u4ef6\u4e2d\u7684\u914d\u7f6e\uff1a/storage/emulated/0/Android/data/org.qpython.qpy/files/apigpt.conf\uff1a

      [speech]\nspeech_key = your_api_key\n

      \u9ed8\u8ba4\u8bed\u97f3\u8bbe\u7f6e\uff1a - \u82f1\u8bed\uff1aen-US-JennyNeural - \u4e2d\u6587\uff1azh-CN-XiaoxiaoNeural

      "},{"location":"qsl4a/special/pgptai/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5f55\u5236\u5e76\u8f6c\u5f55\nprint(\"Recording for 5 seconds...\")\ntext = droid.speechToText(RecordSecond=5, Language='en').result\nprint(f\"You said: {text}\")\n\n# \u8f6c\u5f55\u73b0\u6709\u6587\u4ef6\ntext = droid.speechToText(AmrFile=\"/sdcard/recording.amr\").result\nprint(f\"Transcription: {text}\")\n\n# \u6587\u672c\u8f6c\u8bed\u97f3\ndroid.textToSpeech(\"Hello, this is a test message.\", AutoPlay=True, Language='en')\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u8bed\u97f3\u5e76\u4fdd\u5b58\u5230\u6587\u4ef6\u7684\u6587\u672c\u8f6c\u8bed\u97f3\nresult = droid.textToSpeech(\n    \"Welcome to QPython!\",\n    AutoPlay=False,\n    WavFile=\"/sdcard/welcome.wav\",\n    VoiceName=\"en-US-JennyNeural\"\n).result\nprint(f\"Audio saved to: {result.get('WavFile')}\")\n
      "},{"location":"qsl4a/special/pgptai/#_6","title":"\u7c7b\u4f7f\u7528","text":"
      from androidhelper.pgptai import pgptai\nimport androidhelper\n\ndroid = androidhelper.Android()\nai = pgptai(droid)\n\n# \u4f7f\u7528\u8bed\u97f3\u8bc6\u522b\ntext = ai.speechToText(RecordSecond=10)\n
      "},{"location":"qsl4a/storage/clipboard/","title":"\u526a\u8d34\u677f API","text":"

      \u590d\u5236\u548c\u7c98\u8d34\u6587\u672c\u5230\u7cfb\u7edf\u526a\u8d34\u677f\u3002

      "},{"location":"qsl4a/storage/clipboard/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/clipboard/#setclipboard","title":"setClipboard()","text":"

      \u590d\u5236\u6587\u672c\u5230\u526a\u8d34\u677f\u3002

      setClipboard(text)\n

      \u53c2\u6570\uff1a - text (str): \u8981\u590d\u5236\u7684\u6587\u672c

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/clipboard/#getclipboard","title":"getClipboard()","text":"

      \u4ece\u526a\u8d34\u677f\u83b7\u53d6\u6587\u672c\u3002

      getClipboard()\n

      \u8fd4\u56de\uff1a \u526a\u8d34\u677f\u6587\u672c

      "},{"location":"qsl4a/storage/clipboard/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u590d\u5236\u5230\u526a\u8d34\u677f\ndroid.setClipboard(\"Hello from QPython!\")\n\n# \u4ece\u526a\u8d34\u677f\u7c98\u8d34\ntext = droid.getClipboard().result\nprint(f\"Clipboard: {text}\")\n
      "},{"location":"qsl4a/storage/documentfile/","title":"DocumentFile API","text":"

      \u4f7f\u7528 SAF\uff08\u5b58\u50a8\u8bbf\u95ee\u6846\u67b6\uff09\u8fdb\u884c\u6587\u4ef6\u64cd\u4f5c\uff0c\u652f\u6301 Android 4.4+\u3002

      "},{"location":"qsl4a/storage/documentfile/#_1","title":"\u76ee\u5f55\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilemkdir","title":"documentFileMkdir()","text":"

      \u521b\u5efa\u76ee\u5f55\u3002

      documentFileMkdir(Dir)\n

      \u53c2\u6570\uff1a - Dir (str): \u76ee\u5f55\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/documentfile/#documentfilelistfiles","title":"documentFileListFiles()","text":"

      \u5217\u51fa\u76ee\u5f55\u4e2d\u7684\u6587\u4ef6\u3002

      documentFileListFiles(Folder)\n

      \u8fd4\u56de\uff1a \u6587\u4ef6\u5217\u8868

      "},{"location":"qsl4a/storage/documentfile/#_2","title":"\u6587\u4ef6\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileexists","title":"documentFileExists()","text":"

      \u68c0\u67e5\u6587\u4ef6\u6216\u76ee\u5f55\u662f\u5426\u5b58\u5728\u3002

      documentFileExists(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u6216\u76ee\u5f55\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u5b58\u5728\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/storage/documentfile/#documentfileisfile","title":"documentFileIsFile()","text":"

      \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u6587\u4ef6\u3002

      documentFileIsFile(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u662f\u6587\u4ef6\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u6587\u4ef6\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

      "},{"location":"qsl4a/storage/documentfile/#documentfileisdirectory","title":"documentFileIsDirectory()","text":"

      \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u76ee\u5f55\u3002

      documentFileIsDirectory(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u662f\u76ee\u5f55\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u76ee\u5f55\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

      "},{"location":"qsl4a/storage/documentfile/#documentfiledelete","title":"documentFileDelete()","text":"

      \u5220\u9664\u6587\u4ef6\u6216\u76ee\u5f55\u3002

      documentFileDelete(FileOrTree)\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/documentfile/#documentfilerenameto","title":"documentFileRenameTo()","text":"

      \u91cd\u547d\u540d\u6216\u79fb\u52a8\u6587\u4ef6\u3002

      documentFileRenameTo(Src, Dest)\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/documentfile/#documentfilecopy","title":"documentFileCopy()","text":"

      \u590d\u5236\u6587\u4ef6\u3002

      documentFileCopy(SrcFileOrTree, DestFileOrTree)\n
      "},{"location":"qsl4a/storage/documentfile/#_3","title":"\u6d41\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileinputstream","title":"documentFileInputStream()","text":"

      \u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9\u3002

      documentFileInputStream(srcFile, EncodingFormat=\"\", skip=None, length=None)\n

      \u53c2\u6570\uff1a - srcFile (str): \u6e90\u6587\u4ef6 - EncodingFormat (str): \"UTF-8\"\u3001\"GBK\"\u3001\"Base64\" \u6216\u7a7a\u5b57\u7b26\u4e32\u8868\u793a\u5b57\u8282 - skip (int): \u4ece\u5f00\u5934\u8df3\u8fc7\u7684\u5b57\u8282\u6570 - length (int): \u8bfb\u53d6\u957f\u5ea6

      \u8fd4\u56de\uff1a \u6587\u4ef6\u5185\u5bb9

      "},{"location":"qsl4a/storage/documentfile/#documentfileoutputstream","title":"documentFileOutputStream()","text":"

      \u5199\u5165\u6587\u4ef6\u5185\u5bb9\u3002

      documentFileOutputStream(destFile, src, EncodingFormat=\"\", append=None)\n

      \u53c2\u6570\uff1a - destFile (str): \u76ee\u6807\u6587\u4ef6 - src: \u8981\u5199\u5165\u7684\u6570\u636e - EncodingFormat (str): \u7f16\u7801\u683c\u5f0f - append (bool): \u8ffd\u52a0\u6a21\u5f0f

      "},{"location":"qsl4a/storage/documentfile/#_4","title":"\u6587\u4ef6\u4fe1\u606f","text":""},{"location":"qsl4a/storage/documentfile/#documentfilelength","title":"documentFileLength()","text":"

      \u83b7\u53d6\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\u3002

      documentFileLength(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

      "},{"location":"qsl4a/storage/documentfile/#documentfilelastmodified","title":"documentFileLastModified()","text":"

      \u83b7\u53d6\u6700\u540e\u4fee\u6539\u65f6\u95f4\u3002

      documentFileLastModified(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u65f6\u95f4\u6233\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

      "},{"location":"qsl4a/storage/documentfile/#documentfilegetstat","title":"documentFileGetStat()","text":"

      \u83b7\u53d6\u5168\u9762\u7684\u6587\u4ef6\u7edf\u8ba1\u4fe1\u606f\u3002

      documentFileGetStat(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5305\u542b\u957f\u5ea6\u3001\u6700\u540e\u4fee\u6539\u65f6\u95f4\u548c\u8bfb/\u5199\u6743\u9650\u7684\u5b57\u5178\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

      "},{"location":"qsl4a/storage/documentfile/#uri","title":"URI \u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilegeturi","title":"documentFileGetUri()","text":"

      \u4ece\u8def\u5f84\u83b7\u53d6 URI\u3002

      documentFileGetUri(path, isDirectory=None)\n
      "},{"location":"qsl4a/storage/documentfile/#documentfileshowopen","title":"documentFileShowOpen()","text":"

      \u663e\u793a\u6587\u4ef6\u9009\u62e9\u5668\u3002

      documentFileShowOpen()\n

      \u8fd4\u56de\uff1a \u9009\u62e9\u7684\u6587\u4ef6 URI

      "},{"location":"qsl4a/storage/documentfile/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u76ee\u5f55\ndroid.documentFileMkdir(\"/sdcard/MyFolder\")\n\n# \u5217\u51fa\u6587\u4ef6\nfiles = droid.documentFileListFiles(\"/sdcard\").result\nfor f in files:\n    print(f)\n\n# \u8bfb\u53d6\u6587\u4ef6\ncontent = droid.documentFileInputStream(\n    \"/sdcard/test.txt\",\n    EncodingFormat=\"UTF-8\"\n).result\nprint(content)\n\n# \u5199\u5165\u6587\u4ef6\ndroid.documentFileOutputStream(\n    \"/sdcard/output.txt\",\n    \"Hello World\",\n    EncodingFormat=\"UTF-8\"\n)\n
      "},{"location":"qsl4a/storage/preferences/","title":"\u504f\u597d\u8bbe\u7f6e API","text":"

      \u4f7f\u7528 Android SharedPreferences \u5b58\u50a8\u548c\u68c0\u7d22\u6570\u636e\u3002

      "},{"location":"qsl4a/storage/preferences/#_1","title":"\u504f\u597d\u8bbe\u7f6e\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/preferences/#prefgetvalue","title":"prefGetValue()","text":"

      \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u8bfb\u53d6\u503c\u3002

      prefGetValue(key, filename=None)\n

      \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c\uff08\u4efb\u610f\u7c7b\u578b\uff09

      "},{"location":"qsl4a/storage/preferences/#prefputvalue","title":"prefPutValue()","text":"

      \u5199\u5165\u503c\u5230\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u3002

      prefPutValue(key, value, filename=None)\n

      \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - value (object): \u8981\u5b58\u50a8\u7684\u503c - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      "},{"location":"qsl4a/storage/preferences/#prefgetall","title":"prefGetAll()","text":"

      \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\u503c\u3002

      prefGetAll(filename=None)\n

      \u53c2\u6570\uff1a - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      \u8fd4\u56de\uff1a \u6240\u6709\u504f\u597d\u7684\u6620\u5c04

      "},{"location":"qsl4a/storage/preferences/#prefremovevalue","title":"prefRemoveValue()","text":"

      \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u4e2d\u79fb\u9664\u503c\u3002

      prefRemoveValue(key, filename=None)\n

      \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      "},{"location":"qsl4a/storage/preferences/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b58\u50a8\u503c\ndroid.prefPutValue(\"username\", \"alice\")\ndroid.prefPutValue(\"score\", 100)\ndroid.prefPutValue(\"enabled\", True)\n\n# \u8bfb\u53d6\u7279\u5b9a\u503c\nusername = droid.prefGetValue(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\nall_prefs = droid.prefGetAll().result\nprint(f\"All prefs: {all_prefs}\")\n\n# \u79fb\u9664\u503c\ndroid.prefRemoveValue(\"score\")\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u6587\u4ef6\u540d\ndroid.prefPutValue(\"token\", \"abc123\", filename=\"auth.prefs\")\ntoken = droid.prefGetValue(\"token\", filename=\"auth.prefs\").result\n
      "},{"location":"qsl4a/system/activityresult/","title":"Activity Result API","text":"

      \u4e3a\u901a\u8fc7 startActivityForResult \u542f\u52a8\u7684\u811a\u672c\u8bbe\u7f6e activity \u7ed3\u679c\u3002

      "},{"location":"qsl4a/system/activityresult/#_1","title":"\u7ed3\u679c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/activityresult/#setresultboolean","title":"setResultBoolean()","text":"

      \u8bbe\u7f6e\u5e03\u5c14\u7ed3\u679c\u3002

      setResultBoolean(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (bool): \u5e03\u5c14\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultbyte","title":"setResultByte()","text":"

      \u8bbe\u7f6e\u5b57\u8282\u7ed3\u679c\u3002

      setResultByte(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u5b57\u8282\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultshort","title":"setResultShort()","text":"

      \u8bbe\u7f6e\u77ed\u6574\u6570\u7ed3\u679c\u3002

      setResultShort(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u77ed\u6574\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultchar","title":"setResultChar()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u7ed3\u679c\u3002

      setResultChar(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultinteger","title":"setResultInteger()","text":"

      \u8bbe\u7f6e\u6574\u6570\u7ed3\u679c\u3002

      setResultInteger(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u6574\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultlong","title":"setResultLong()","text":"

      \u8bbe\u7f6e\u957f\u6574\u6570\u7ed3\u679c\u3002

      setResultLong(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u957f\u6574\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultfloat","title":"setResultFloat()","text":"

      \u8bbe\u7f6e\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

      setResultFloat(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u6d6e\u70b9\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultdouble","title":"setResultDouble()","text":"

      \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

      setResultDouble(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultstring","title":"setResultString()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u4e32\u7ed3\u679c\u3002

      setResultString(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u4e32\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultbooleanarray","title":"setResultBooleanArray()","text":"

      \u8bbe\u7f6e\u5e03\u5c14\u6570\u7ec4\u7ed3\u679c\u3002

      setResultBooleanArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5e03\u5c14\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultbytearray","title":"setResultByteArray()","text":"

      \u8bbe\u7f6e\u5b57\u8282\u6570\u7ec4\u7ed3\u679c\u3002

      setResultByteArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u8282\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultshortarray","title":"setResultShortArray()","text":"

      \u8bbe\u7f6e\u77ed\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultShortArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u77ed\u6574\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultchararray","title":"setResultCharArray()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u6570\u7ec4\u7ed3\u679c\u3002

      setResultCharArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultintegerarray","title":"setResultIntegerArray()","text":"

      \u8bbe\u7f6e\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultIntegerArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6574\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultlongarray","title":"setResultLongArray()","text":"

      \u8bbe\u7f6e\u957f\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultLongArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u957f\u6574\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultfloatarray","title":"setResultFloatArray()","text":"

      \u8bbe\u7f6e\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultFloatArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6d6e\u70b9\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultdoublearray","title":"setResultDoubleArray()","text":"

      \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultDoubleArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultstringarray","title":"setResultStringArray()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u4e32\u6570\u7ec4\u7ed3\u679c\u3002

      setResultStringArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u4e32\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultserializable","title":"setResultSerializable()","text":"

      \u8bbe\u7f6e\u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u3002

      setResultSerializable(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue: \u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c activity \u540e\uff0c\u8bbe\u7f6e\u7ed3\u679c\n# \u793a\u4f8b\uff1a\u8fd4\u56de\u6210\u529f\u53ca\u6570\u636e\ndroid.setResultInteger(0, 200)  # RESULT_OK\ndroid.setResultString(0, \"Operation completed successfully\")\n\n# \u8fd4\u56de\u6570\u7ec4\u7ed3\u679c\ndroid.setResultIntegerArray(0, [1, 2, 3, 4, 5])\n
      "},{"location":"qsl4a/system/application/","title":"\u5e94\u7528\u7ba1\u7406","text":"

      \u7ba1\u7406\u5e94\u7528\u7a0b\u5e8f\u3001\u542f\u52a8\u5e94\u7528\u548c\u67e5\u8be2\u7cfb\u7edf\u4fe1\u606f\u3002

      "},{"location":"qsl4a/system/application/#_2","title":"\u5e94\u7528\u7a0b\u5e8f\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getapplicationinfo","title":"getApplicationInfo()","text":"

      \u83b7\u53d6\u5e94\u7528\u4fe1\u606f\u3002

      getApplicationInfo(packageName=None)\n

      \u53c2\u6570\uff1a - packageName (str): \u5305\u540d\uff08None = \u5f53\u524d\u5e94\u7528\uff09

      \u8fd4\u56de\uff1a \u5e94\u7528\u4fe1\u606f\u5b57\u5178

      "},{"location":"qsl4a/system/application/#getinstalledpackages","title":"getInstalledPackages()","text":"

      \u83b7\u53d6\u5df2\u5b89\u88c5\u5305\u5217\u8868\u3002

      getInstalledPackages(flag=4)\n

      \u53c2\u6570\uff1a - flag (int): \u5305\u6807\u5fd7\u8fc7\u6ee4\u5668\uff08\u9ed8\u8ba4\uff1a4\uff09

      \u8fd4\u56de\uff1a \u5df2\u5b89\u88c5\u5305\u5217\u8868

      "},{"location":"qsl4a/system/application/#getrunningpackages","title":"getRunningPackages()","text":"

      \u5217\u51fa\u6b63\u5728\u8fd0\u884c\u7684\u5305\u3002

      getRunningPackages()\n

      \u8fd4\u56de\uff1a \u5305\u540d\u5217\u8868

      "},{"location":"qsl4a/system/application/#getlaunchablepackages","title":"getLaunchablePackages()","text":"

      \u83b7\u53d6\u53ef\u542f\u52a8\u5305\u5217\u8868\u3002

      getLaunchablePackages(needClassName=False)\n

      \u53c2\u6570\uff1a - needClassName (bool): \u5305\u542b\u4e3b activity \u7c7b\u540d\uff08\u9ed8\u8ba4\uff1aFalse\uff09

      \u8fd4\u56de\uff1a \u53ef\u542f\u52a8\u5305\u540d\u5217\u8868\u6216\u5305\u542b\u7c7b\u540d\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#_3","title":"\u5e94\u7528\u63a7\u5236","text":""},{"location":"qsl4a/system/application/#launch","title":"launch()","text":"

      \u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u3002

      launch(classname=None, packagename=None, wait=True)\n

      \u53c2\u6570\uff1a - classname (str): \u4e3b activity \u7c7b\u540d - packagename (str): \u5305\u540d - wait (bool): \u7b49\u5f85\u542f\u52a8\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

      \u8fd4\u56de\uff1a \u542f\u52a8\u7ed3\u679c

      "},{"location":"qsl4a/system/application/#forcestoppackage","title":"forceStopPackage()","text":"

      \u5f3a\u5236\u505c\u6b62\u5e94\u7528\u7a0b\u5e8f\u3002

      forceStopPackage(packageName)\n

      \u53c2\u6570\uff1a - packageName (str): \u8981\u505c\u6b62\u7684\u5305\u540d

      "},{"location":"qsl4a/system/application/#_4","title":"\u7248\u672c\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getpackageversion","title":"getPackageVersion()","text":"

      \u83b7\u53d6\u5e94\u7528\u7248\u672c\u540d\u79f0\u3002

      getPackageVersion(packageName)\n

      \u8fd4\u56de\uff1a \u7248\u672c\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"3.2.1\"\uff09

      "},{"location":"qsl4a/system/application/#getpackageversioncode","title":"getPackageVersionCode()","text":"

      \u83b7\u53d6\u5e94\u7528\u7248\u672c\u4ee3\u7801\u3002

      getPackageVersionCode(packageName)\n

      \u8fd4\u56de\uff1a \u7248\u672c\u4ee3\u7801\u6574\u6570

      "},{"location":"qsl4a/system/application/#getconstants","title":"getConstants()","text":"

      \u83b7\u53d6\u7c7b\u5e38\u91cf\u3002

      getConstants(classname)\n

      \u53c2\u6570\uff1a - classname (str): \u5b8c\u6574\u7c7b\u540d

      \u8fd4\u56de\uff1a \u5e38\u91cf\u540d\u548c\u503c\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#_5","title":"\u7cfb\u7edf\u529f\u80fd","text":""},{"location":"qsl4a/system/application/#backgroundprotect","title":"backgroundProtect()","text":"

      \u542f\u7528\u6216\u7981\u7528\u5e94\u7528\u7684\u540e\u53f0\u4fdd\u62a4\u3002

      backgroundProtect(enabled=True)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\u4fdd\u62a4\uff0cFalse \u7981\u7528

      "},{"location":"qsl4a/system/application/#createscriptshortcut","title":"createScriptShortCut()","text":"

      \u4e3a\u811a\u672c\u521b\u5efa\u4e3b\u5c4f\u5e55\u5feb\u6377\u65b9\u5f0f\u3002

      createScriptShortCut(scriptPath, label=None, iconPath=None, scriptArg=None)\n

      \u53c2\u6570\uff1a - scriptPath (str): Python \u811a\u672c\u8def\u5f84 - label (str, optional): \u5feb\u6377\u65b9\u5f0f\u6807\u7b7e - iconPath (str, optional): \u56fe\u6807\u56fe\u50cf\u8def\u5f84 - scriptArg (str, optional): \u4f20\u9012\u7ed9\u811a\u672c\u7684\u53c2\u6570

      "},{"location":"qsl4a/system/application/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getandroidid","title":"getAndroidID()","text":"

      \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

      getAndroidID()\n

      \u8fd4\u56de\uff1a \u552f\u4e00\u7684 Android \u8bbe\u5907 ID \u5b57\u7b26\u4e32

      "},{"location":"qsl4a/system/application/#getsysinfo","title":"getSysInfo()","text":"

      \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\u3002

      getSysInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#getlocale","title":"getLocale()","text":"

      \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u3002

      getLocale()\n

      \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

      "},{"location":"qsl4a/system/application/#getharmonyosinformation","title":"getHarmonyOsInformation()","text":"

      \u5982\u679c\u5728 HarmonyOS \u4e0a\u8fd0\u884c\uff0c\u83b7\u53d6 HarmonyOS \u4fe1\u606f\u3002

      getHarmonyOsInformation()\n

      \u8fd4\u56de\uff1a HarmonyOS \u7248\u672c\u4fe1\u606f\u6216 None

      "},{"location":"qsl4a/system/application/#isexternalstoragemanager","title":"isExternalStorageManager()","text":"

      \u68c0\u67e5\u5e94\u7528\u662f\u5426\u6709\u5916\u90e8\u5b58\u50a8\u7ba1\u7406\u5668\u6743\u9650\u3002

      isExternalStorageManager()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6709\u6743\u9650\u5219\u4e3a True

      "},{"location":"qsl4a/system/application/#_7","title":"\u5185\u5b58\u548c\u663e\u793a","text":""},{"location":"qsl4a/system/application/#getmemoryinfo","title":"getMemoryInfo()","text":"

      \u83b7\u53d6\u5185\u5b58\u4fe1\u606f\u3002

      getMemoryInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#getscreeninfo","title":"getScreenInfo()","text":"

      \u83b7\u53d6\u5c4f\u5e55\u4fe1\u606f\u3002

      getScreenInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#_8","title":"\u6743\u9650","text":""},{"location":"qsl4a/system/application/#checkpermissions","title":"checkPermissions()","text":"

      \u68c0\u67e5\u5f53\u524d\u5e94\u7528\u6743\u9650\u3002

      checkPermissions()\n

      \u8fd4\u56de\uff1a \u6743\u9650\u53ca\u5176\u72b6\u6001\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#requestpermissions","title":"requestPermissions()","text":"

      \u5411\u7528\u6237\u8bf7\u6c42\u6743\u9650\u3002

      requestPermissions(permissions=None)\n

      \u53c2\u6570\uff1a - permissions (list, optional): \u8981\u8bf7\u6c42\u7684\u6743\u9650\u5217\u8868\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8bf7\u6c42\u6240\u6709\u9700\u8981\u7684\u6743\u9650\u3002

      \u8fd4\u56de\uff1a \u6743\u9650\u8bf7\u6c42\u7ed3\u679c

      "},{"location":"qsl4a/system/application/#_9","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/system/application/#showscreenlock","title":"showScreenLock()","text":"

      \u663e\u793a\u5c4f\u5e55\u9501\u5b9a\uff08PIN/\u56fe\u6848/\u5bc6\u7801\u8f93\u5165\uff09\u3002

      showScreenLock()\n
      "},{"location":"qsl4a/system/application/#_10","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\ninfo = droid.getSysInfo().result\nprint(f\"System: {info}\")\n\n# \u83b7\u53d6\u5e94\u7528\u7248\u672c\nversion = droid.getPackageVersion(\"org.qpython.qpy\").result\nprint(f\"QPython version: {version}\")\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u5e94\u7528\napps = droid.getInstalledPackages().result\nprint(f\"Installed apps: {len(apps)}\")\n\n# \u542f\u52a8\u5e94\u7528\ndroid.launch(packagename=\"com.android.settings\")\n\n# \u68c0\u67e5\u6743\u9650\nperms = droid.checkPermissions().result\nprint(f\"Permissions: {perms}\")\n\n# \u8bf7\u6c42\u5b58\u50a8\u6743\u9650\ndroid.requestPermissions([\"android.permission.READ_EXTERNAL_STORAGE\"])\n\n# \u521b\u5efa\u5feb\u6377\u65b9\u5f0f\ndroid.createScriptShortCut(\n    \"/sdcard/my_script.py\",\n    label=\"My Script\",\n    iconPath=\"/sdcard/icon.png\"\n)\n
      "},{"location":"qsl4a/system/battery/","title":"\u7535\u6c60 API","text":"

      \u76d1\u63a7\u8bbe\u5907\u7535\u6c60\u72b6\u6001\u548c\u5065\u5eb7\u72b6\u51b5\u3002

      "},{"location":"qsl4a/system/battery/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/battery/#readbatterydata","title":"readBatteryData()","text":"

      \u83b7\u53d6\u5b8c\u6574\u7684\u7535\u6c60\u4fe1\u606f\u3002

      readBatteryData()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7535\u6c60\u6570\u636e\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/battery/#batterystartmonitoring","title":"batteryStartMonitoring()","text":"

      \u5f00\u59cb\u7535\u6c60\u76d1\u63a7\u3002

      batteryStartMonitoring()\n
      "},{"location":"qsl4a/system/battery/#batterystopmonitoring","title":"batteryStopMonitoring()","text":"

      \u505c\u6b62\u7535\u6c60\u76d1\u63a7\u3002

      batteryStopMonitoring()\n
      "},{"location":"qsl4a/system/battery/#batterygetlevel","title":"batteryGetLevel()","text":"

      \u83b7\u53d6\u7535\u6c60\u767e\u5206\u6bd4\u3002

      batteryGetLevel()\n

      \u8fd4\u56de\uff1a \u6574\u6570\uff080-100\uff09

      "},{"location":"qsl4a/system/battery/#batterygetstatus","title":"batteryGetStatus()","text":"

      \u83b7\u53d6\u5145\u7535\u72b6\u6001\u3002

      batteryGetStatus()\n

      \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u5145\u7535\u4e2d - 3: \u653e\u7535\u4e2d - 4: \u672a\u5145\u7535 - 5: \u5df2\u5145\u6ee1

      "},{"location":"qsl4a/system/battery/#batterygetplugtype","title":"batteryGetPlugType()","text":"

      \u83b7\u53d6\u7535\u6e90\u7c7b\u578b\u3002

      batteryGetPlugType()\n

      \u8fd4\u56de\uff1a - -1: \u672a\u77e5 - 0: \u672a\u63d2\u7535 - 1: AC \u5145\u7535\u5668 - 2: USB \u7aef\u53e3

      "},{"location":"qsl4a/system/battery/#batterygethealth","title":"batteryGetHealth()","text":"

      \u83b7\u53d6\u7535\u6c60\u5065\u5eb7\u72b6\u51b5\u3002

      batteryGetHealth()\n

      \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u826f\u597d - 3: \u8fc7\u70ed - 4: \u635f\u574f - 5: \u8fc7\u538b - 6: \u672a\u6307\u5b9a\u7684\u6545\u969c

      "},{"location":"qsl4a/system/battery/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\nlevel = droid.batteryGetLevel().result\nprint(f\"Battery: {level}%\")\n
      "},{"location":"qsl4a/system/qpyinterface/","title":"QPython \u63a5\u53e3 API","text":"

      \u4ece\u5176\u4ed6\u5e94\u7528\u6267\u884c QPython \u811a\u672c\u548c\u7ba1\u7406\u5171\u4eab\u53d8\u91cf\u3002

      "},{"location":"qsl4a/system/qpyinterface/#_1","title":"\u811a\u672c\u6267\u884c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/qpyinterface/#executeqpy","title":"executeQPy()","text":"

      \u6267\u884c QPython \u811a\u672c\u3002

      executeQPy(path=\"\", arg=None)\n

      \u53c2\u6570\uff1a - path (str): \u811a\u672c\u6587\u4ef6\u8def\u5f84 - arg (str, optional): \u547d\u4ee4\u884c\u53c2\u6570

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#executeqpyassrv","title":"executeQPyAsSrv()","text":"

      \u4f5c\u4e3a\u670d\u52a1\u6267\u884c QPython \u811a\u672c\u3002

      executeQPyAsSrv(path=None)\n

      \u53c2\u6570\uff1a - path (str, optional): \u811a\u672c\u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#executeqpycode","title":"executeQPyCode()","text":"

      \u76f4\u63a5\u6267\u884c Python \u4ee3\u7801\u3002

      executeQPyCode(code=None)\n

      \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#executeqpycodeassrv","title":"executeQPyCodeAsSrv()","text":"

      \u4f5c\u4e3a\u670d\u52a1\u6267\u884c Python \u4ee3\u7801\u3002

      executeQPyCodeAsSrv(code=None)\n

      \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#_2","title":"\u5171\u4eab\u53d8\u91cf","text":"

      \u5171\u4eab\u53d8\u91cf\u5141\u8bb8 QPython \u4e0e\u5176\u4ed6\u5e94\u7528\u4e4b\u95f4\u8fdb\u884c\u901a\u4fe1\u3002

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableset","title":"sharedVariableSet()","text":"

      \u8bbe\u7f6e Java \u5171\u4eab\u53d8\u91cf\u3002

      sharedVariableSet(key, value)\n

      \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d - value (str): \u53d8\u91cf\u503c

      \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableget","title":"sharedVariableGet()","text":"

      \u83b7\u53d6 Java \u5171\u4eab\u53d8\u91cf\u3002

      sharedVariableGet(key)\n

      \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d

      \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableremove","title":"sharedVariableRemove()","text":"

      \u79fb\u9664 Java \u5171\u4eab\u53d8\u91cf\u3002

      sharedVariableRemove(key)\n

      \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u53d8\u91cf\u540d

      \u8fd4\u56de\uff1a \u88ab\u79fb\u9664\u7684\u503c

      "},{"location":"qsl4a/system/qpyinterface/#getlastlog","title":"getLastLog()","text":"

      \u83b7\u53d6 QPython \u7684\u6700\u540e\u65e5\u5fd7\u8f93\u51fa\u3002

      getLastLog()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u65e5\u5fd7\u5185\u5bb9

      "},{"location":"qsl4a/system/qpyinterface/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c\u811a\u672c\ndroid.executeQPy(\"/sdcard/my_script.py\", arg=\"test\")\n\n# \u76f4\u63a5\u6267\u884c\u4ee3\u7801\ncode = \"print('Hello from QPython!')\"\ndroid.executeQPyCode(code)\n\n# \u4f7f\u7528\u5171\u4eab\u53d8\u91cf\ndroid.sharedVariableSet(\"username\", \"alice\")\nusername = droid.sharedVariableGet(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u79fb\u9664\u53d8\u91cf\ndroid.sharedVariableRemove(\"username\")\n\n# \u83b7\u53d6\u6700\u8fd1\u65e5\u5fd7\nlog = droid.getLastLog().result\nprint(f\"Log: {log}\")\n
      "},{"location":"qsl4a/system/sensors/","title":"\u4f20\u611f\u5668 API","text":"

      \u8bbf\u95ee\u8bbe\u5907\u4f20\u611f\u5668\uff0c\u5305\u62ec\u52a0\u901f\u5ea6\u8ba1\u3001\u9640\u87ba\u4eea\u3001\u78c1\u529b\u8ba1\u7b49\u3002

      "},{"location":"qsl4a/system/sensors/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/sensors/#startsensingtimed","title":"startSensingTimed()","text":"

      \u5f00\u59cb\u4f20\u611f\u5668\u76d1\u63a7\u5e76\u8bbe\u7f6e\u65f6\u95f4\u95f4\u9694\u3002

      startSensingTimed(sensorNumber, delayTime)\n

      \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID\uff08\u901a\u5e38\u4e3a 1-3\uff09 - delayTime (int): \u8bfb\u53d6\u4e4b\u95f4\u7684\u5ef6\u8fdf\uff08\u6beb\u79d2\uff09

      "},{"location":"qsl4a/system/sensors/#startsensingthreshold","title":"startSensingThreshold()","text":"

      \u5f00\u59cb\u5e26\u9608\u503c\u89e6\u53d1\u7684\u4f20\u611f\u5668\u76d1\u63a7\u3002

      startSensingThreshold(sensorNumber, threshold, axis)\n

      \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID - threshold (float): \u89e6\u53d1\u9608\u503c - axis (int): \u8981\u76d1\u63a7\u7684\u8f74\uff080=X\uff0c1=Y\uff0c2=Z\uff09

      "},{"location":"qsl4a/system/sensors/#stopsensing","title":"stopSensing()","text":"

      \u505c\u6b62\u6240\u6709\u4f20\u611f\u5668\u76d1\u63a7\u3002

      stopSensing()\n
      "},{"location":"qsl4a/system/sensors/#readsensors","title":"readSensors()","text":"

      \u8bfb\u53d6\u5f53\u524d\u4f20\u611f\u5668\u6570\u636e\u3002

      readSensors()\n

      \u8fd4\u56de\uff1a \u4f20\u611f\u5668\u6570\u636e\u5b57\u5178

      "},{"location":"qsl4a/system/sensors/#sensorsreadaccelerometer","title":"sensorsReadAccelerometer()","text":"

      \u8bfb\u53d6\u52a0\u901f\u5ea6\u8ba1\u503c\u3002

      sensorsReadAccelerometer()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d m/s\u00b2

      "},{"location":"qsl4a/system/sensors/#sensorsreadgyroscope","title":"sensorsReadGyroscope()","text":"

      \u8bfb\u53d6\u9640\u87ba\u4eea\u503c\u3002

      sensorsReadGyroscope()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d rad/s

      "},{"location":"qsl4a/system/sensors/#sensorsreadmagnetometer","title":"sensorsReadMagnetometer()","text":"

      \u8bfb\u53d6\u78c1\u573a\u503c\u3002

      sensorsReadMagnetometer()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d \u03bcT

      "},{"location":"qsl4a/system/sensors/#sensorsreadorientation","title":"sensorsReadOrientation()","text":"

      \u8bfb\u53d6\u8bbe\u5907\u65b9\u5411\u3002

      sensorsReadOrientation()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [azimuth, pitch, roll]\uff0c\u5355\u4f4d\u5ea6

      "},{"location":"qsl4a/system/sensors/#sensorsgetlight","title":"sensorsGetLight()","text":"

      \u8bfb\u53d6\u5149\u4f20\u611f\u5668\u503c\u3002

      sensorsGetLight()\n

      \u8fd4\u56de\uff1a \u5149\u7ea7\u522b\uff08lux\uff09

      "},{"location":"qsl4a/system/sensors/#sensorsgetstepcounter","title":"sensorsGetStepCounter()","text":"

      \u8bfb\u53d6\u6b65\u8ba1\u6570\u5668\u3002

      sensorsGetStepCounter()\n

      \u8fd4\u56de\uff1a \u6b65\u6570

      "},{"location":"qsl4a/system/sensors/#sensorsgetaccuracy","title":"sensorsGetAccuracy()","text":"

      \u83b7\u53d6\u5f53\u524d\u4f20\u611f\u5668\u7cbe\u5ea6\u3002

      sensorsGetAccuracy()\n

      \u8fd4\u56de\uff1a \u7cbe\u5ea6\u503c\uff080-3\uff1aUNRELIABLE\u3001ACCURACY_LOW\u3001ACCURACY_MEDIUM\u3001ACCURACY_HIGH\uff09

      "},{"location":"qsl4a/system/sensors/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u8bfb\u53d6\u4f20\u611f\u5668 10 \u6b21\nfor i in range(10):\n    accel = droid.sensorsReadAccelerometer().result\n    print(f\"Accel: X={accel[0]:.2f}, Y={accel[1]:.2f}, Z={accel[2]:.2f}\")\n    time.sleep(0.5)\n\ndroid.stopSensing()\n
      "},{"location":"qsl4a/system/settings/","title":"\u8bbe\u7f6e API","text":"

      \u63a7\u5236\u7cfb\u7edf\u8bbe\u7f6e\uff0c\u5305\u62ec\u5c4f\u5e55\u3001\u58f0\u97f3\u548c\u7f51\u7edc\u8bbe\u7f6e\u3002

      "},{"location":"qsl4a/system/settings/#_1","title":"\u5c4f\u5e55\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#setscreentimeout","title":"setScreenTimeout()","text":"

      \u8bbe\u7f6e\u5c4f\u5e55\u8d85\u65f6\u503c\u3002

      setScreenTimeout(value)\n

      \u53c2\u6570\uff1a - value (int): \u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

      \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u8d85\u65f6\u503c

      "},{"location":"qsl4a/system/settings/#getscreentimeout","title":"getScreenTimeout()","text":"

      \u83b7\u53d6\u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u3002

      getScreenTimeout()\n

      \u8fd4\u56de\uff1a \u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

      "},{"location":"qsl4a/system/settings/#getscreenbrightness","title":"getScreenBrightness()","text":"

      \u83b7\u53d6\u5c4f\u5e55\u4eae\u5ea6\u503c\u3002

      getScreenBrightness()\n

      \u8fd4\u56de\uff1a \u4eae\u5ea6\u503c\uff080-255\uff09

      "},{"location":"qsl4a/system/settings/#setscreenbrightness","title":"setScreenBrightness()","text":"

      \u8bbe\u7f6e\u5c4f\u5e55\u4eae\u5ea6\u3002

      setScreenBrightness(value=None)\n

      \u53c2\u6570\uff1a - value (int, optional): \u4eae\u5ea6\u503c\uff080-255\uff09\uff0c\u6216 None \u8868\u793a\u81ea\u52a8

      \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u4eae\u5ea6\u503c

      "},{"location":"qsl4a/system/settings/#checkscreenon","title":"checkScreenOn()","text":"

      \u68c0\u67e5\u5c4f\u5e55\u662f\u5426\u4eae\u7740\u3002

      checkScreenOn()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u5c4f\u5e55\u4eae\u7740\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/system/settings/#_2","title":"\u98de\u884c\u6a21\u5f0f","text":""},{"location":"qsl4a/system/settings/#checkairplanemode","title":"checkAirplaneMode()","text":"

      \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\u662f\u5426\u542f\u7528\u3002

      checkAirplaneMode()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u98de\u884c\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

      "},{"location":"qsl4a/system/settings/#_3","title":"\u94c3\u58f0\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#checkringersilentmode","title":"checkRingerSilentMode()","text":"

      \u68c0\u67e5\u94c3\u58f0\u662f\u5426\u5904\u4e8e\u9759\u97f3\u6a21\u5f0f\u3002

      checkRingerSilentMode()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u9759\u97f3\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

      "},{"location":"qsl4a/system/settings/#toggleringersilentmode","title":"toggleRingerSilentMode()","text":"

      \u5207\u6362\u94c3\u58f0\u9759\u97f3\u6a21\u5f0f\u3002

      toggleRingerSilentMode(enabled=None)\n

      \u53c2\u6570\uff1a - enabled (bool, optional): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

      \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

      "},{"location":"qsl4a/system/settings/#togglevibratemode","title":"toggleVibrateMode()","text":"

      \u5207\u6362\u632f\u52a8\u6a21\u5f0f\u3002

      toggleVibrateMode(enabled=None, ringer=None)\n

      \u53c2\u6570\uff1a - enabled (bool, optional): \u5207\u6362\u632f\u52a8\u5f00/\u5173 - ringer (bool, optional): \u5e94\u7528\u4e8e\u94c3\u58f0\u6a21\u5f0f

      \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

      "},{"location":"qsl4a/system/settings/#getvibratemode","title":"getVibrateMode()","text":"

      \u83b7\u53d6\u632f\u52a8\u6a21\u5f0f\u8bbe\u7f6e\u3002

      getVibrateMode(ringer=None)\n

      \u53c2\u6570\uff1a - ringer (bool, optional): \u68c0\u67e5\u94c3\u58f0\u632f\u52a8\u6a21\u5f0f

      \u8fd4\u56de\uff1a \u5982\u679c\u632f\u52a8\u5df2\u542f\u7528\u5219\u4e3a True

      "},{"location":"qsl4a/system/settings/#_4","title":"\u97f3\u91cf\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#getringervolume","title":"getRingerVolume()","text":"

      \u83b7\u53d6\u5f53\u524d\u94c3\u58f0\u97f3\u91cf\u3002

      getRingerVolume()\n

      \u8fd4\u56de\uff1a \u94c3\u58f0\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-7\uff09

      "},{"location":"qsl4a/system/settings/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

      getMaxRingerVolume()\n

      \u8fd4\u56de\uff1a \u6700\u5927\u94c3\u58f0\u97f3\u91cf

      "},{"location":"qsl4a/system/settings/#setringervolume","title":"setRingerVolume()","text":"

      \u8bbe\u7f6e\u94c3\u58f0\u97f3\u91cf\u3002

      setRingerVolume(volume)\n

      \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

      "},{"location":"qsl4a/system/settings/#getmediavolume","title":"getMediaVolume()","text":"

      \u83b7\u53d6\u5f53\u524d\u5a92\u4f53\u97f3\u91cf\u3002

      getMediaVolume()\n

      \u8fd4\u56de\uff1a \u5a92\u4f53\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-15\uff09

      "},{"location":"qsl4a/system/settings/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

      getMaxMediaVolume()\n

      \u8fd4\u56de\uff1a \u6700\u5927\u5a92\u4f53\u97f3\u91cf

      "},{"location":"qsl4a/system/settings/#setmediavolume","title":"setMediaVolume()","text":"

      \u8bbe\u7f6e\u5a92\u4f53\u97f3\u91cf\u3002

      setMediaVolume(volume)\n

      \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

      "},{"location":"qsl4a/system/settings/#_5","title":"\u7cfb\u7edf\u4fe1\u606f","text":""},{"location":"qsl4a/system/settings/#elapsedrealtimenanos","title":"elapsedRealtimeNanos()","text":"

      \u83b7\u53d6\u81ea\u7cfb\u7edf\u542f\u52a8\u4ee5\u6765\u7684\u7eb3\u79d2\u6570\u3002

      elapsedRealtimeNanos()\n

      \u8fd4\u56de\uff1a \u7eb3\u79d2\u6570\uff08\u53ef\u7528\u4e8e\u8ba1\u65f6\uff09

      "},{"location":"qsl4a/system/settings/#gettrafficstats","title":"getTrafficStats()","text":"

      \u83b7\u53d6\u7f51\u7edc\u6d41\u91cf\u7edf\u8ba1\u3002

      getTrafficStats(flags=7)\n

      \u53c2\u6570\uff1a - flags (int): \u8981\u68c0\u7d22\u7684\u7edf\u8ba1\uff08\u9ed8\u8ba4\uff1a7 = \u5168\u90e8\uff09

      \u8fd4\u56de\uff1a \u5305\u542b\u53d1\u9001/\u63a5\u6536\u5b57\u8282\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/settings/#getapptxbytes","title":"getAppTxBytes()","text":"

      \u83b7\u53d6 QPython \u5e94\u7528\u7684\u53d1\u9001\u5b57\u8282\u3002

      getAppTxBytes(packageName)\n

      \u53c2\u6570\uff1a - packageName (str): \u5305\u540d

      \u8fd4\u56de\uff1a \u5305\u542b tx/rx \u5b57\u8282\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/settings/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5c4f\u5e55\u8bbe\u7f6e\ncurrent_timeout = droid.getScreenTimeout().result\nprint(f\"Current timeout: {current_timeout}s\")\ndroid.setScreenTimeout(30)\n\n# \u68c0\u67e5\u5c4f\u5e55\nif droid.checkScreenOn().result:\n    print(\"Screen is on\")\n\n# \u97f3\u91cf\u63a7\u5236\nmedia_vol = droid.getMediaVolume().result\nprint(f\"Media volume: {media_vol}\")\ndroid.setMediaVolume(10)\n\n# \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\nif droid.checkAirplaneMode().result:\n    print(\"Airplane mode is on\")\n
      "},{"location":"qsl4a/system/sysinfo/","title":"\u7cfb\u7edf\u4fe1\u606f","text":"

      \u68c0\u7d22\u8bbe\u5907\u548c\u7cfb\u7edf\u4fe1\u606f\u3002

      "},{"location":"qsl4a/system/sysinfo/#_2","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/sysinfo/#getandroidid","title":"getAndroidID()","text":"

      \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

      getAndroidID()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

      "},{"location":"qsl4a/system/sysinfo/#getsysinfo","title":"getSysInfo()","text":"

      \u83b7\u53d6\u7efc\u5408\u7cfb\u7edf\u4fe1\u606f\u3002

      getSysInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/sysinfo/#getlocale","title":"getLocale()","text":"

      \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u8bbe\u7f6e\u3002

      getLocale()\n

      \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

      "},{"location":"qsl4a/system/sysinfo/#_3","title":"\u5185\u5b58","text":""},{"location":"qsl4a/system/sysinfo/#getmemoryinfo","title":"getMemoryInfo()","text":"

      \u83b7\u53d6 RAM \u4fe1\u606f\u3002

      getMemoryInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/sysinfo/#_4","title":"\u663e\u793a","text":""},{"location":"qsl4a/system/sysinfo/#getscreeninfo","title":"getScreenInfo()","text":"

      \u83b7\u53d6\u663e\u793a\u4fe1\u606f\u3002

      getScreenInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/sysinfo/#_5","title":"\u6807\u8bc6\u7b26","text":""},{"location":"qsl4a/system/sysinfo/#getimei","title":"getImei()","text":"

      \u83b7\u53d6\u8bbe\u5907 IMEI\u3002

      getImei(slotIndex=None)\n
      "},{"location":"qsl4a/system/sysinfo/#getmeid","title":"getMeid()","text":"

      \u83b7\u53d6\u8bbe\u5907 MEID\u3002

      getMeid(slotIndex=None)\n
      "},{"location":"qsl4a/system/sysinfo/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u8bbe\u5907 ID\nandroid_id = droid.getAndroidID().result\nprint(f\"Android ID: {android_id}\")\n\n# \u5c4f\u5e55\u4fe1\u606f\nscreen = droid.getScreenInfo().result\nprint(f\"Screen: {screen['width']}x{screen['height']}\")\n\n# \u5185\u5b58\nmemory = droid.getMemoryInfo().result\nprint(f\"Memory: {memory}\")\n
      "},{"location":"qsl4a/system/wakelock/","title":"WakeLock API","text":"

      \u63a7\u5236\u8bbe\u5907\u5524\u9192\u9501\u4ee5\u4fdd\u6301 CPU \u6216\u5c4f\u5e55\u5f00\u542f\u3002

      "},{"location":"qsl4a/system/wakelock/#wake-lock","title":"Wake Lock \u7c7b\u578b","text":"

      QSL4A \u63d0\u4f9b\u4e0d\u540c\u7c7b\u578b\u7684\u5524\u9192\u9501\uff1a

      \u7c7b\u578b \u63cf\u8ff0 Full CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae Partial \u4ec5 CPU \u5f00\u542f Bright CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae Dim CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697"},{"location":"qsl4a/system/wakelock/#wake-lock_1","title":"Wake Lock \u65b9\u6cd5","text":""},{"location":"qsl4a/system/wakelock/#wakelockacquirefull","title":"wakeLockAcquireFull()","text":"

      \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae\uff09\u3002

      wakeLockAcquireFull()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquirepartial","title":"wakeLockAcquirePartial()","text":"

      \u83b7\u53d6\u90e8\u5206\u5524\u9192\u9501\uff08\u4ec5 CPU \u5f00\u542f\uff09\u3002

      wakeLockAcquirePartial()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquirebright","title":"wakeLockAcquireBright()","text":"

      \u83b7\u53d6\u660e\u4eae\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff09\u3002

      wakeLockAcquireBright()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquiredim","title":"wakeLockAcquireDim()","text":"

      \u83b7\u53d6\u6697\u6de1\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697\uff09\u3002

      wakeLockAcquireDim()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockrelease","title":"wakeLockRelease()","text":"

      \u91ca\u653e\u5524\u9192\u9501\u3002

      wakeLockRelease()\n
      "},{"location":"qsl4a/system/wakelock/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\ndroid.wakeLockAcquireFull()\n\n# \u5728\u4fdd\u6301\u5c4f\u5e55\u5f00\u542f\u65f6\u6267\u884c\u91cd\u8981\u5de5\u4f5c\nprint(\"Screen will stay on\")\ntime.sleep(10)\n\n# \u5b8c\u6210\u540e\u91ca\u653e\ndroid.wakeLockRelease()\n\n# \u6216\u4f7f\u7528\u90e8\u5206\u9501\u8fdb\u884c\u540e\u53f0\u4efb\u52a1\ndroid.wakeLockAcquirePartial()\n# \u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\uff0cCPU \u4ecd\u4fdd\u6301\u5f00\u542f\ntime.sleep(30)\ndroid.wakeLockRelease()\n

      \u6ce8\u610f\uff1a \u8bb0\u4f4f\u5728\u4e0d\u9700\u8981\u65f6\u91ca\u653e\u5524\u9192\u9501\u4ee5\u8282\u7701\u7535\u6c60\u3002

      "},{"location":"qsl4a/ui/accessibility/","title":"\u65e0\u969c\u788d\u670d\u52a1","text":"

      \u65e0\u969c\u788d\u670d\u52a1\u5141\u8bb8\u81ea\u52a8\u5316 UI \u4ea4\u4e92\uff0c\u5982\u70b9\u51fb\u3001\u6ed1\u52a8\u548c\u7cfb\u7edf\u64cd\u4f5c\u3002

      "},{"location":"qsl4a/ui/accessibility/#_2","title":"\u670d\u52a1\u63a7\u5236","text":""},{"location":"qsl4a/ui/accessibility/#accessibilitystartservice","title":"accessibilityStartService()","text":"

      \u542f\u52a8\u65e0\u969c\u788d\u670d\u52a1\u3002

      accessibilityStartService()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/ui/accessibility/#accessibilityserviceenabled","title":"accessibilityServiceEnabled()","text":"

      \u68c0\u67e5\u65e0\u969c\u788d\u670d\u52a1\u662f\u5426\u5df2\u542f\u7528\u3002

      accessibilityServiceEnabled()\n

      \u8fd4\u56de\uff1a True \u6216 False

      "},{"location":"qsl4a/ui/accessibility/#_3","title":"\u5c4f\u5e55\u4ea4\u4e92","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityclick","title":"accessibilityClick()","text":"

      \u5728\u5c4f\u5e55\u5750\u6807\u5904\u70b9\u51fb\u3002

      accessibilityClick(x=0, y=0, t=50)\n

      \u53c2\u6570\uff1a - x (int/float): X \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - y (int/float): Y \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - t (int): \u6309\u4f4f\u65f6\u957f\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a50\uff09

      "},{"location":"qsl4a/ui/accessibility/#accessibilityslide","title":"accessibilitySlide()","text":"

      \u591a\u70b9\u6ed1\u52a8\u624b\u52bf\u3002

      accessibilitySlide(XnYn=None, t=None)\n

      \u53c2\u6570\uff1a - XnYn (list): \u5750\u6807 [X1, Y1, X2, Y2, ... Xn, Yn] - t (int): \u6ed1\u52a8\u65f6\u957f\uff08\u9ed8\u8ba4\uff1a50*n \u6beb\u79d2\uff09

      "},{"location":"qsl4a/ui/accessibility/#_4","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityaction","title":"accessibilityAction()","text":"

      \u6309\u4ee3\u7801\u6267\u884c\u7cfb\u7edf\u64cd\u4f5c\u3002

      accessibilityAction(actionCode)\n

      \u64cd\u4f5c\u4ee3\u7801\uff1a | \u4ee3\u7801 | \u5e38\u91cf | \u63cf\u8ff0 | |------|----------|-------------| | 1 | BACK | \u8fd4\u56de\u6309\u94ae | | 2 | HOME | \u4e3b\u5c4f\u5e55\u6309\u94ae | | 3 | RECENTS | \u6700\u8fd1\u5e94\u7528 | | 4 | NOTIFICATIONS | \u6253\u5f00\u901a\u77e5 | | 5 | QUICK_SETTINGS | \u6253\u5f00\u5feb\u901f\u8bbe\u7f6e | | 6 | POWER_DIALOG | \u7535\u6e90\u83dc\u5355 | | 7 | TOGGLE_SPLIT_SCREEN | \u5206\u5c4f | | 8 | LOCK_SCREEN | \u9501\u5c4f | | 9 | TAKE_SCREENSHOT | \u622a\u56fe | | 10 | KEYCODE_HEADSETHOOK | \u8033\u673a\u6302\u94a9 | | 11-14 | ACCESSIBILITY_ | \u65e0\u969c\u788d\u6309\u94ae | | 15 | DISMISS_NOTIFICATION_SHADE | \u5173\u95ed\u901a\u77e5\u680f | | 16-20 | DPAD_ | \u65b9\u5411\u952e | | 21 | MENU | \u83dc\u5355\u6309\u94ae | | 22 | MEDIA_PLAY_PAUSE | \u64ad\u653e/\u6682\u505c\u5a92\u4f53 |

      "},{"location":"qsl4a/ui/accessibility/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/accessibility/#_6","title":"\u70b9\u51fb\u5c4f\u5e55\u4e2d\u5fc3","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u670d\u52a1\nif not droid.accessibilityServiceEnabled().result:\n    droid.accessibilityStartService()\n\n# \u70b9\u51fb\u4e2d\u5fc3\uff080,0 = \u4e2d\u5fc3\uff09\ndroid.accessibilityClick(0, 0, t=100)\n
      "},{"location":"qsl4a/ui/accessibility/#_7","title":"\u6ed1\u52a8\u624b\u52bf","text":"
      # \u4ece\u4e0b\u5f80\u4e0a\u6ed1\u52a8\uff08\u5411\u4e0a\u6eda\u52a8\uff09\ndroid.accessibilitySlide([0, 1.5, 0, -1.5], t=300)\n
      "},{"location":"qsl4a/ui/accessibility/#_8","title":"\u7cfb\u7edf\u5bfc\u822a","text":"
      # \u6309\u4e3b\u5c4f\u5e55\ndroid.accessibilityAction(2)\n\n# \u6309\u8fd4\u56de\ndroid.accessibilityAction(1)\n\n# \u6253\u5f00\u901a\u77e5\ndroid.accessibilityAction(4)\n
      "},{"location":"qsl4a/ui/accessibility/#_9","title":"\u70b9\u51fb\u7279\u5b9a\u4f4d\u7f6e","text":"
      # \u70b9\u51fb\u5c4f\u5e55\u5750\u6807 (500, 800)\ndroid.accessibilityClick(500, 800)\n\n# \u70b9\u51fb\u76f8\u5bf9\u4f4d\u7f6e\uff08\u6c34\u5e73\u5c45\u4e2d\uff0c\u5782\u76f4 3/4 \u5904\uff09\ndroid.accessibilityClick(0, 1.5)\n
      "},{"location":"qsl4a/ui/dialogs/","title":"\u5bf9\u8bdd\u6846\u7cfb\u7edf","text":"

      QSL4A \u63d0\u4f9b\u5168\u9762\u7684\u5bf9\u8bdd\u6846\u652f\u6301\uff0c\u7528\u4e8e\u7528\u6237\u4ea4\u4e92\uff0c\u5305\u62ec\u8b66\u62a5\u3001\u8f93\u5165\u5bf9\u8bdd\u6846\u3001\u9009\u62e9\u5bf9\u8bdd\u6846\u548c\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

      "},{"location":"qsl4a/ui/dialogs/#_2","title":"\u8b66\u62a5\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowalert","title":"dialogShowAlert()","text":"

      \u663e\u793a\u7b80\u5355\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

      dialogShowAlert(title=\"Alert\", message=\"The message of the alert.\",\n                positiveButtonText=\"OK\", negativeButtonText=None,\n                neutralButtonText=None, messageIsHtml=False)\n

      \u53c2\u6570\uff1a - title (str): \u5bf9\u8bdd\u6846\u6807\u9898 - message (str): \u6d88\u606f\u6587\u672c - positiveButtonText (str): \u80af\u5b9a\u6309\u94ae\u6807\u7b7e - negativeButtonText (str, optional): \u5426\u5b9a\u6309\u94ae\u6807\u7b7e - neutralButtonText (str, optional): \u4e2d\u6027\u6309\u94ae\u6807\u7b7e - messageIsHtml (bool): \u5c06\u6d88\u606f\u89e3\u6790\u4e3a HTML

      \u8fd4\u56de\uff1a \u5305\u542b\u70b9\u51fb\u6309\u94ae\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#dialogshowsimplechoice","title":"dialogShowSimpleChoice()","text":"

      \u663e\u793a\u5e26\u6709\u9879\u76ee\u7684\u7b80\u5355\u9009\u62e9\u5bf9\u8bdd\u6846\u3002

      dialogShowSimpleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

      \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868

      \u8fd4\u56de\uff1a \u5305\u542b\u9009\u4e2d\u9879\u76ee\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#_3","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialoggetinput","title":"dialogGetInput()","text":"

      \u83b7\u53d6\u7528\u6237\u6587\u672c\u8f93\u5165\u3002

      dialogGetInput(title=\"Value\", message=\"Please enter value:\",\n               defaultText=None, messageIsHtml=False)\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7528\u6237\u8f93\u5165\u6587\u672c\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#dialoggetpassword","title":"dialogGetPassword()","text":"

      \u83b7\u53d6\u5bc6\u7801\u8f93\u5165\u3002

      dialogGetPassword(title=\"Password\", message=\"Please enter password:\")\n

      \u8fd4\u56de\uff1a \u5305\u542b\u8f93\u5165\u5bc6\u7801\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#dialogcreateinput","title":"dialogCreateInput()","text":"

      \u521b\u5efa\u81ea\u5b9a\u4e49\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

      dialogCreateInput(title=\"Value\", message=\"Please enter value:\",\n                  defaultText=None, inputType=None)\n

      \u53c2\u6570\uff1a - inputType (str): \u8f93\u5165\u7c7b\u578b\uff08\u4f8b\u5982 \"text\"\u3001\"number\"\u3001\"textPassword\"\uff09

      "},{"location":"qsl4a/ui/dialogs/#dialogcreatepassword","title":"dialogCreatePassword()","text":"

      \u521b\u5efa\u5bc6\u7801\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

      dialogCreatePassword(title=\"Password\", message=\"Please enter password:\")\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreateseekbar","title":"dialogCreateSeekBar()","text":"

      \u521b\u5efa\u6ed1\u5757/\u8fdb\u5ea6\u6761\u5bf9\u8bdd\u6846\u3002

      dialogCreateSeekBar(starting_value=50, maximum_value=100, title=\"\", message=\"\")\n

      \u53c2\u6570\uff1a - starting_value (int): \u521d\u59cb\u503c - maximum_value (int): \u6700\u5927\u503c

      "},{"location":"qsl4a/ui/dialogs/#_4","title":"\u9009\u62e9\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowsinglechoice","title":"dialogShowSingleChoice()","text":"

      \u663e\u793a\u5355\u9009\uff08\u5355\u9009\u6309\u94ae\uff09\u5bf9\u8bdd\u6846\u3002

      dialogShowSingleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, selected=-1, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

      \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (int): \u9ed8\u8ba4\u9009\u4e2d\u7d22\u5f15

      "},{"location":"qsl4a/ui/dialogs/#dialogshowmultichoice","title":"dialogShowMultiChoice()","text":"

      \u663e\u793a\u591a\u9009\uff08\u590d\u9009\u6846\uff09\u5bf9\u8bdd\u6846\u3002

      dialogShowMultiChoice(title=\"Alert\", message=\"The message of the alert.\",\n                      items=None, selected=None, positiveButtonText=\"OK\",\n                      negativeButtonText=None, neutralButtonText=None,\n                      messageIsHtml=False)\n

      \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (list): \u521d\u59cb\u9009\u4e2d\u7d22\u5f15\u5217\u8868

      "},{"location":"qsl4a/ui/dialogs/#dialogsetsinglechoiceitems","title":"dialogSetSingleChoiceItems()","text":"

      \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u5355\u9009\u9879\u76ee\u3002

      dialogSetSingleChoiceItems(items, selected=-1)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmultichoiceitems","title":"dialogSetMultiChoiceItems()","text":"

      \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u591a\u9009\u9879\u76ee\u3002

      dialogSetMultiChoiceItems(items, selected=None)\n
      "},{"location":"qsl4a/ui/dialogs/#_5","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatespinnerprogress","title":"dialogCreateSpinnerProgress()","text":"

      \u521b\u5efa\u4e0d\u786e\u5b9a\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

      dialogCreateSpinnerProgress(title=None, message=None, maximum_progress=100)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreatehorizontalprogress","title":"dialogCreateHorizontalProgress()","text":"

      \u521b\u5efa\u6c34\u5e73\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

      dialogCreateHorizontalProgress(title=None, message=None, maximum_progress=100)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetcurrentprogress","title":"dialogSetCurrentProgress()","text":"

      \u66f4\u65b0\u8fdb\u5ea6\u503c\u3002

      dialogSetCurrentProgress(current)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmaxprogress","title":"dialogSetMaxProgress()","text":"

      \u8bbe\u7f6e\u6700\u5927\u8fdb\u5ea6\u503c\u3002

      dialogSetMaxProgress(max)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetprogressmessage","title":"dialogSetProgressMessage()","text":"

      \u66f4\u65b0\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u6d88\u606f\u3002

      dialogSetProgressMessage(message)\n
      "},{"location":"qsl4a/ui/dialogs/#_6","title":"\u9009\u62e9\u5668\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatedatepicker","title":"dialogCreateDatePicker()","text":"

      \u521b\u5efa\u65e5\u671f\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

      dialogCreateDatePicker(year=1970, month=1, day=1)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreatetimepicker","title":"dialogCreateTimePicker()","text":"

      \u521b\u5efa\u65f6\u95f4\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

      dialogCreateTimePicker(hour=0, minute=0, is24hour=False)\n
      "},{"location":"qsl4a/ui/dialogs/#_7","title":"\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u521b\u5efa","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatealert","title":"dialogCreateAlert()","text":"

      \u521b\u5efa\u81ea\u5b9a\u4e49\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

      dialogCreateAlert(title=None, message=None)\n

      \u521b\u5efa\u4e00\u4e2a\u7a7a\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002\u53ef\u4e0e\u5176\u4ed6 dialogSet* \u51fd\u6570\u4e00\u8d77\u4f7f\u7528\u6765\u81ea\u5b9a\u4e49\u3002

      "},{"location":"qsl4a/ui/dialogs/#dialogsetitems","title":"dialogSetItems()","text":"

      \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u7b80\u5355\u5217\u8868\u9879\u76ee\u3002

      dialogSetItems(items)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetpositivebuttontext","title":"dialogSetPositiveButtonText()","text":"

      \u8bbe\u7f6e\u80af\u5b9a\u6309\u94ae\u6587\u672c\u3002

      dialogSetPositiveButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetnegativebuttontext","title":"dialogSetNegativeButtonText()","text":"

      \u8bbe\u7f6e\u5426\u5b9a\u6309\u94ae\u6587\u672c\u3002

      dialogSetNegativeButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetneutralbuttontext","title":"dialogSetNeutralButtonText()","text":"

      \u8bbe\u7f6e\u4e2d\u6027\u6309\u94ae\u6587\u672c\u3002

      dialogSetNeutralButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmessageishtml","title":"dialogSetMessageIsHtml()","text":"

      \u8bbe\u7f6e\u6d88\u606f\u662f\u5426\u5e94\u89e3\u6790\u4e3a HTML\u3002

      dialogSetMessageIsHtml(messageIsHtml=True)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogshow","title":"dialogShow()","text":"

      \u663e\u793a\u521b\u5efa\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u3002

      dialogShow()\n
      "},{"location":"qsl4a/ui/dialogs/#_8","title":"\u5bf9\u8bdd\u6846\u63a7\u5236","text":""},{"location":"qsl4a/ui/dialogs/#dialogdismiss","title":"dialogDismiss()","text":"

      \u5173\u95ed\u5f53\u524d\u5bf9\u8bdd\u6846\u3002

      dialogDismiss()\n
      "},{"location":"qsl4a/ui/dialogs/#dialoggetresponse","title":"dialogGetResponse()","text":"

      \u83b7\u53d6\u5bf9\u8bdd\u6846\u54cd\u5e94\u3002

      dialogGetResponse()\n
      "},{"location":"qsl4a/ui/dialogs/#dialoggetselecteditems","title":"dialogGetSelectedItems()","text":"

      \u4ece\u9009\u62e9\u5bf9\u8bdd\u6846\u83b7\u53d6\u9009\u4e2d\u7684\u9879\u76ee\u3002

      dialogGetSelectedItems()\n
      "},{"location":"qsl4a/ui/dialogs/#_9","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/dialogs/#_10","title":"\u7b80\u5355\u8b66\u62a5","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a\u8b66\u62a5\ndroid.dialogShowAlert(\"Warning\", \"This is an important message!\")\n
      "},{"location":"qsl4a/ui/dialogs/#_11","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":"
      # \u83b7\u53d6\u7528\u6237\u8f93\u5165\nresult = droid.dialogGetInput(\"Name\", \"Enter your name:\", \"John\").result\nprint(f\"Hello, {result}!\")\n
      "},{"location":"qsl4a/ui/dialogs/#_12","title":"\u5e26\u6309\u94ae\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846","text":"
      # \u521b\u5efa\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\ndroid.dialogCreateAlert(\"Custom\", \"Choose an option\")\ndroid.dialogSetItems([\"Option 1\", \"Option 2\", \"Option 3\"])\ndroid.dialogShow()\n\n# \u83b7\u53d6\u54cd\u5e94\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response['item']}\")\n
      "},{"location":"qsl4a/ui/dialogs/#_13","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":"
      # \u521b\u5efa\u8fdb\u5ea6\u5bf9\u8bdd\u6846\ndroid.dialogCreateHorizontalProgress(\"Loading\", \"Please wait...\", 100)\ndroid.dialogShow()\n\n# \u66f4\u65b0\u8fdb\u5ea6\nfor i in range(101):\n    droid.dialogSetCurrentProgress(i)\n    time.sleep(0.05)\n\ndroid.dialogDismiss()\n
      "},{"location":"qsl4a/ui/dialogs/#_14","title":"\u65e5\u671f\u9009\u62e9\u5668","text":"
      # \u663e\u793a\u65e5\u671f\u9009\u62e9\u5668\ndroid.dialogCreateDatePicker(2024, 1, 15)\ndroid.dialogShow()\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response}\")\n
      "},{"location":"qsl4a/ui/floatview/","title":"\u6d6e\u52a8\u89c6\u56fe","text":"

      \u6d6e\u52a8\u7a97\u53e3\u652f\u6301\uff0c\u7528\u4e8e\u5728\u5176\u4ed6\u5e94\u7528\u7a0b\u5e8f\u4e0a\u65b9\u4fdd\u6301\u663e\u793a\u7684\u8986\u76d6 UI \u5143\u7d20\u3002

      "},{"location":"qsl4a/ui/floatview/#_2","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/floatview/#floatview","title":"floatView()","text":"

      \u663e\u793a\u6216\u4fee\u6539\u6d6e\u52a8\u89c6\u56fe\u3002

      floatView(Args=None)\n

      \u53c2\u6570\uff1a - Args (dict): \u914d\u7f6e\u5b57\u5178\uff0c\u5305\u542b\u4ee5\u4e0b\u952e\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08-1 \u521b\u5efa\u65b0\u7684\uff0c>=0 \u4fee\u6539\u73b0\u6709\u7684\uff09 - text (str): \u8981\u663e\u793a\u7684\u6587\u672c\u5185\u5bb9 - html (str): HTML \u5185\u5bb9\uff08\u5982\u679c\u7701\u7565 text \u5219\u4f7f\u7528\uff09 - width (int): \u89c6\u56fe\u5bbd\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a300\uff09 - height (int): \u89c6\u56fe\u9ad8\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a150\uff09 - x (int): X \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - y (int): Y \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - backColor (str): ARGB \u5341\u516d\u8fdb\u5236\u80cc\u666f\u8272\uff08\u9ed8\u8ba4\uff1a'7f7f7f7f'\uff09 - textColor (str): ARGB \u5341\u516d\u8fdb\u5236\u6587\u672c\u8272\uff08\u9ed8\u8ba4\uff1a'ff000000'\uff09 - textSize (int): \u6587\u672c\u5927\u5c0f\uff08\u9ed8\u8ba4\uff1a10\uff09 - textAlign (int): \u6587\u672c\u5bf9\u9f50\uff080 = \u7ee7\u627f\uff09 - script (str): \u957f\u6309\u5173\u95ed\u540e\u8fd0\u884c\u7684\u811a\u672c\u8def\u5f84 - arg: \u811a\u672c\u53c2\u6570 - clickRemove (bool): \u542f\u7528\u70b9\u51fb\u79fb\u9664\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - flag (int): \u7a97\u53e3\u6807\u5fd7\uff08\u9ed8\u8ba4\uff1a40 - \u53ef\u89e6\u6478\uff09

      \u8fd4\u56de\uff1a \u5f53\u524d\u94fe\u5217\u8868\u957f\u5ea6

      "},{"location":"qsl4a/ui/floatview/#floatviewcount","title":"floatViewCount()","text":"

      \u83b7\u53d6\u6d3b\u52a8\u6d6e\u52a8\u89c6\u56fe\u7684\u6570\u91cf\u3002

      floatViewCount()\n

      \u8fd4\u56de\uff1a \u6d6e\u52a8\u89c6\u56fe\u6570\u91cf

      "},{"location":"qsl4a/ui/floatview/#floatviewresult","title":"floatViewResult()","text":"

      \u83b7\u53d6\u6d6e\u52a8\u89c6\u56fe\u7684\u7ed3\u679c/\u72b6\u6001\u3002

      floatViewResult(index=-1)\n

      \u53c2\u6570\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1\uff0c\u8fd4\u56de\u6700\u540e\u64cd\u4f5c\u7ed3\u679c\uff09

      \u8fd4\u56de\uff1a \u5305\u542b\u64cd\u4f5c\u8be6\u60c5\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - x, y: \u4f4d\u7f6e - time: \u65f6\u95f4\u6233 - operation: \u64cd\u4f5c\u7c7b\u578b\uff08'initial'\u3001'move' \u7b49\uff09 - index: \u89c6\u56fe\u7d22\u5f15 - removed: \u5982\u679c\u89c6\u56fe\u88ab\u79fb\u9664\u5219\u4e3a True

      "},{"location":"qsl4a/ui/floatview/#floatviewremove","title":"floatViewRemove()","text":"

      \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\u3002

      floatViewRemove(index=-1)\n

      \u53c2\u6570\uff1a - index (int): \u8981\u79fb\u9664\u7684\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1 \u79fb\u9664\u6700\u540e\u4e00\u4e2a\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a 1\uff0c\u5426\u5219\u4e3a 0

      "},{"location":"qsl4a/ui/floatview/#_3","title":"\u5e38\u91cf","text":"
      • floatView.INDEX_NEW = -1 - \u521b\u5efa\u65b0\u7684\u6d6e\u52a8\u89c6\u56fe
      • floatView.FLAG_DEFAULT_TOUCHABLE = 40 - \u9ed8\u8ba4\u53ef\u89e6\u6478\u6807\u5fd7
      • floatView.TEXT_ALIGNMENT_INHERIT = 0
      • floatView.TEXT_ALIGNMENT_CENTER - \u5c45\u4e2d\u6587\u672c\u5bf9\u9f50
      "},{"location":"qsl4a/ui/floatview/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/floatview/#_5","title":"\u57fa\u672c\u6d6e\u52a8\u89c6\u56fe","text":"
      import androidhelper\nfrom androidhelper import Android\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u7b80\u5355\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'index': -1,  # \u521b\u5efa\u65b0\u7684\n    'text': 'Hello World',\n    'width': 400,\n    'height': 300,\n    'x': -300,  # \u4ece\u4e2d\u5fc3\u504f\u79fb\n    'y': -400,\n    'backColor': 'ff0000',  # \u7ea2\u8272\u80cc\u666f\n    'textColor': '0000ff',  # \u84dd\u8272\u6587\u672c\n    'textSize': 16,\n    'textAlign': droid.floatView.TEXT_ALIGNMENT_CENTER\n})\n\n# \u68c0\u67e5\u6570\u91cf\nprint(f\"Float views: {droid.floatViewCount().result}\")\n\n# \u83b7\u53d6\u7ed3\u679c\nresult = droid.floatViewResult().result\nprint(f\"View info: {result}\")\n\n# \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\ndroid.floatViewRemove(0)\n
      "},{"location":"qsl4a/ui/floatview/#html","title":"HTML \u5185\u5bb9","text":"
      # \u521b\u5efa\u5e26 HTML \u5185\u5bb9\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': '',  # \u7a7a\u6587\u672c\u4ee5\u4f7f\u7528 HTML\n    'html': '<h1>Title</h1><p>Rich <b>HTML</b> content</p>',\n    'width': 500,\n    'height': 400\n})\n
      "},{"location":"qsl4a/ui/floatview/#_6","title":"\u4fee\u6539\u73b0\u6709\u89c6\u56fe","text":"
      # \u521b\u5efa\u521d\u59cb\u89c6\u56fe\ndroid.floatView({'text': 'Initial Text', 'width': 300, 'height': 150})\n\n# \u4fee\u6539\u540c\u4e00\u89c6\u56fe\uff08\u7d22\u5f15 0\uff09\ndroid.floatView({\n    'index': 0,\n    'text': 'Updated Text!',\n    'backColor': '7f00ff00'  # \u7eff\u8272\u80cc\u666f\n})\n\n# \u68c0\u67e5\u79fb\u52a8/\u66f4\u6539\u7ed3\u679c\nresult = droid.floatViewResult(0).result\nprint(f\"Operation: {result.get('operation')}, Position: ({result.get('x')}, {result.get('y')})\")\n
      "},{"location":"qsl4a/ui/floatview/#_7","title":"\u591a\u4e2a\u6d6e\u52a8\u89c6\u56fe","text":"
      # \u521b\u5efa\u591a\u4e2a\u89c6\u56fe\nfor i in range(3):\n    droid.floatView({\n        'index': -1,\n        'text': f'View {i}',\n        'x': i * 100 - 150,\n        'y': i * 100 - 150,\n        'backColor': f'{i}f{i}f{i}f'\n    })\n\nprint(f\"Total views: {droid.floatViewCount().result}\")\n\n# \u79fb\u9664\u6240\u6709\u89c6\u56fe\nwhile droid.floatViewCount().result > 0:\n    droid.floatViewRemove()\n
      "},{"location":"qsl4a/ui/floatview/#_8","title":"\u5e26\u811a\u672c\u56de\u8c03","text":"
      # \u521b\u5efa\u5173\u95ed\u65f6\u8fd0\u884c\u811a\u672c\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': 'Click to close and run script',\n    'script': '/sdcard/my_script.py',\n    'arg': 'hello from float view',\n    'clickRemove': True\n})\n
      "},{"location":"qsl4a/ui/fullscreen/","title":"\u5168\u5c4f UI","text":"

      \u4f7f\u7528\u539f\u751f Android \u5e03\u5c40\u521b\u5efa\u81ea\u5b9a\u4e49\u5168\u5c4f\u754c\u9762\u3002

      "},{"location":"qsl4a/ui/fullscreen/#_1","title":"\u5e03\u5c40\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullshow","title":"fullShow()","text":"

      \u663e\u793a\u5168\u5c4f\u5e03\u5c40\u3002

      fullShow(layout, title=None, theme=None)\n

      \u53c2\u6570\uff1a - layout (str): JSON \u5e03\u5c40\u5b9a\u4e49\u6216\u5e03\u5c40\u5b57\u7b26\u4e32 - title (str, optional): \u7a97\u53e3\u6807\u9898 - theme (str, optional): \u4e3b\u9898\u540d\u79f0

      \u8fd4\u56de\uff1a \u7a97\u53e3 ID

      "},{"location":"qsl4a/ui/fullscreen/#fulldismiss","title":"fullDismiss()","text":"

      \u5173\u95ed\u5168\u5c4f\u7a97\u53e3\u3002

      fullDismiss()\n
      "},{"location":"qsl4a/ui/fullscreen/#fullquery","title":"fullQuery()","text":"

      \u67e5\u8be2\u6240\u6709\u5c0f\u90e8\u4ef6\u503c\u3002

      fullQuery()\n

      \u8fd4\u56de\uff1a \u5c0f\u90e8\u4ef6 ID \u548c\u503c\u7684\u5b57\u5178

      "},{"location":"qsl4a/ui/fullscreen/#fullquerydetail","title":"fullQueryDetail()","text":"

      \u67e5\u8be2\u7279\u5b9a\u5c0f\u90e8\u4ef6\u8be6\u60c5\u3002

      fullQueryDetail(id)\n
      "},{"location":"qsl4a/ui/fullscreen/#_2","title":"\u5c5e\u6027\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperty","title":"fullGetProperty()","text":"

      \u83b7\u53d6\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

      fullGetProperty(id, property)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetproperty","title":"fullSetProperty()","text":"

      \u8bbe\u7f6e\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

      fullSetProperty(id, property, value)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetlist","title":"fullSetList()","text":"

      \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

      fullSetList(id, list, isHtml=False, listType=0)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetlist2","title":"fullSetList2()","text":"

      \u4f7f\u7528\u8d44\u6e90 ID \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

      fullSetList2(id, list, intRes)\n

      \u53c2\u6570\uff1a - id (str): \u5c0f\u90e8\u4ef6 ID - list (list): \u9879\u76ee\u5217\u8868 - intRes (int): \u5217\u8868\u9879\u76ee\u5e03\u5c40\u7684 Android \u8d44\u6e90 ID

      "},{"location":"qsl4a/ui/fullscreen/#fullsetlistselected","title":"fullSetListSelected()","text":"

      \u5728\u5217\u8868\u4e2d\u8bbe\u7f6e\u9009\u4e2d\u9879\u76ee\u3002

      fullSetListSelected(id, selected)\n

      \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID - selected (int): \u8981\u9009\u4e2d\u7684\u9879\u76ee\u7d22\u5f15

      "},{"location":"qsl4a/ui/fullscreen/#fullgetlistselected","title":"fullGetListSelected()","text":"

      \u83b7\u53d6\u5f53\u524d\u9009\u4e2d\u7684\u5217\u8868\u9879\u76ee\u7d22\u5f15\u3002

      fullGetListSelected(id)\n

      \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID

      \u8fd4\u56de\uff1a \u9009\u4e2d\u9879\u76ee\u7d22\u5f15

      "},{"location":"qsl4a/ui/fullscreen/#_3","title":"\u6279\u91cf\u5c5e\u6027\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperties","title":"fullGetProperties()","text":"

      \u4e00\u6b21\u83b7\u53d6\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

      fullGetProperties(ids, property)\n

      \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u83b7\u53d6\u7684\u5c5e\u6027\u540d

      \u8fd4\u56de\uff1a \u6620\u5c04\u5c0f\u90e8\u4ef6 ID \u5230\u5c5e\u6027\u503c\u7684\u5b57\u5178

      "},{"location":"qsl4a/ui/fullscreen/#fullsetproperties","title":"fullSetProperties()","text":"

      \u4e00\u6b21\u8bbe\u7f6e\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

      fullSetProperties(ids, property, value)\n

      \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u8bbe\u7f6e\u7684\u5c5e\u6027\u540d - value: \u5c5e\u6027\u503c

      "},{"location":"qsl4a/ui/fullscreen/#_4","title":"\u622a\u56fe","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetscreenshot","title":"fullGetScreenShot()","text":"

      \u6355\u83b7\u5168\u5c4f\u622a\u56fe\u3002

      fullGetScreenShot(path=None)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u5728\u4e8b\u4ef6\u4e2d\u8fd4\u56de

      \u8fd4\u56de\uff1a \u5305\u542b\u622a\u56fe\u6570\u636e\u7684\u4e8b\u4ef6

      "},{"location":"qsl4a/ui/fullscreen/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b9a\u4e49\u5e03\u5c40\nlayout = '''\n{ \"type\": \"LinearLayout\", \"orientation\": \"vertical\",\n  \"children\": [\n    { \"type\": \"TextView\", \"id\": \"title\", \"text\": \"Hello\" },\n    { \"type\": \"Button\", \"id\": \"btn\", \"text\": \"Click Me\" }\n  ]\n}\n'''\n\n# \u663e\u793a\u5e03\u5c40\ndroid.fullShow(layout, \"My App\")\n\n# \u67e5\u8be2\u6309\u94ae\u70b9\u51fb\nevent = droid.eventWaitFor('click', timeout=10)\nif event.result:\n    widget_id = event.result['data']['id']\n    if widget_id == 'btn':\n        print(\"Button clicked!\")\n\ndroid.fullDismiss()\n
      "}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"QPython \u9879\u76ee","text":"

      QPython \u4e0d\u4ec5\u662f\u4e00\u4e2a\u5f3a\u5927\u7684 Android Python IDE\uff0c\u4e5f\u662f\u4e00\u4e2a\u6d3b\u8dc3\u7684\u6280\u672f\u793e\u533a\u3002

      "},{"location":"#ai-android-python-ide","title":"\u652f\u6301 AI \u7684 Android Python IDE","text":"

      QPython \u662f\u60a8\u8fdb\u884c Android Python \u7f16\u7a0b\u7684\u5165\u53e3\u3002\u5b83\u96c6\u6210\u4e86 Python \u89e3\u91ca\u5668\u3001AI \u6a21\u578b\u5f15\u64ce\u548c\u79fb\u52a8\u5f00\u53d1\u5de5\u5177\u94fe\uff0c\u8ba9\u60a8\u80fd\u591f\u4ece\u79fb\u52a8\u8bbe\u5907\u6784\u5efa Web \u5e94\u7528\u7a0b\u5e8f\u3001\u6267\u884c\u79d1\u5b66\u8ba1\u7b97\u548c\u521b\u5efa\u667a\u80fd\u5e94\u7528\u3002

      \u65e0\u8bba\u60a8\u662f\u5728\u5b66\u4e60\u7f16\u7a0b\u3001\u6784\u5efa\u6570\u636e\u79d1\u5b66\u9879\u76ee\uff0c\u8fd8\u662f\u5f00\u53d1 AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f\uff0cQPython \u90fd\u63d0\u4f9b\u4e86\u5b8c\u6574\u7684\u79fb\u52a8\u7f16\u7a0b\u89e3\u51b3\u65b9\u6848\uff0c\u62e5\u6709\u5168\u9762\u7684\u5f00\u53d1\u8005\u8d44\u6e90\u548c\u6d3b\u8dc3\u7684\u793e\u533a\u6765\u652f\u6301\u60a8\u7684\u65c5\u7a0b\u3002

      • \u5206\u652f\u7248\u672c \u2013 \u4e86\u89e3\u4e0d\u540c\u7684 QPython \u7248\u672c\uff08IDE\u3001\u793e\u533a\u7248\u3001Plus\uff09\uff0c\u9009\u62e9\u9002\u5408\u60a8\u9700\u6c42\u7684\u7248\u672c
      • \u66f4\u65b0\u65e5\u5fd7 \u2013 \u968f\u65f6\u4e86\u89e3\u6700\u65b0\u529f\u80fd\u3001\u6539\u8fdb\u548c\u53d1\u884c\u8bf4\u660e
      "},{"location":"#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"

      \u5982\u4f55\u5feb\u901f\u5165\u95e8\uff1f\u8bf7\u6309\u7167\u4ee5\u4e0b\u6b65\u9aa4\uff1a

      • \u5feb\u901f\u5165\u95e8
      • Hello World \u6559\u7a0b
      "},{"location":"#_2","title":"\u7f16\u7a0b\u6307\u5357","text":"

      QPython \u4e0d\u4ec5\u63d0\u4f9b\u57fa\u7840\u7684 Python \u63a5\u53e3\u652f\u6301\uff0c\u66f4\u91cd\u8981\u7684\u662f\uff0c\u5b83\u8fd8\u5141\u8bb8\u60a8\u901a\u8fc7 QSL4A \u63a5\u53e3\u4f7f\u7528 Python \u8c03\u7528 Android API\u3002

      • Python \u6807\u51c6\u5e93 \u2013 \u901a\u7528\u7684 Python \u8bed\u6cd5\u548c\u5185\u7f6e\u5e93
      • QSL4A API \u2013 \u4ece Python \u8bbf\u95ee Android \u8bbe\u5907\u529f\u80fd\uff08\u76f8\u673a\u3001\u4f20\u611f\u5668\u3001\u77ed\u4fe1\u7b49\uff09
      • QPYPI \u6307\u5357 \u2013 \u5b89\u88c5\u989d\u5916\u7684 Python \u5305
      • \u7f16\u8f91\u5668\u6307\u5357 \u2013 \u4f7f\u7528\u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668
      • \u5916\u90e8 API \u2013 \u4e0e\u5916\u90e8\u5e94\u7528\u7a0b\u5e8f\u96c6\u6210
      "},{"location":"#_3","title":"\u4e0b\u8f7d\u8d44\u6e90","text":"
      • Google Drive
      • \u5fae\u4fe1\u7f51\u76d8
      "},{"location":"#_4","title":"\u793e\u533a\u4e0e\u53cd\u9988","text":"
      • \u4e2d\u6587\u4ea4\u6d41\u793e\u533a
      • \u767e\u5ea6\u8d34\u5427
      • \u95ee\u9898\u53cd\u9988
      • \u529f\u80fd\u6269\u5c55\u8bf7\u6c42
      "},{"location":"#_5","title":"\u5173\u6ce8\u6211\u4eec","text":"
      • B\u7ad9
      • Weibo
      "},{"location":"AIPyApp/","title":"AIPyApp - AI\u9a71\u52a8\u7684\u7a0b\u5e8f\u751f\u6210\u5668","text":"

      AIPyApp \u662f QPython \u4e2d\u7684\u667a\u80fd\u5de5\u5177\uff0c\u53ef\u4ee5\u5229\u7528 AI \u4ece\u81ea\u7136\u8bed\u8a00\u6307\u4ee4\u81ea\u52a8\u751f\u6210 Python \u7a0b\u5e8f\u3002

      "},{"location":"AIPyApp/#_1","title":"\u6982\u8ff0","text":"

      AIPyApp \u6539\u53d8\u4e86\u60a8\u7f16\u5199\u4ee3\u7801\u7684\u65b9\u5f0f\u2014\u2014\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u63cf\u8ff0\u60a8\u60f3\u8981\u7684\u529f\u80fd\uff0cAI \u5c31\u4f1a\u4e3a\u60a8\u751f\u6210 Python \u7a0b\u5e8f\u3002QPython \u8fd8\u5c06\u63a8\u51fa AIPy Academy\u2014\u2014\u4e00\u4e2a\u4e3a AI \u65f6\u4ee3\u91cf\u8eab\u5b9a\u5236\u7684 Python \u7f16\u7a0b\u8bfe\u7a0b\u5e73\u53f0\u3002

      "},{"location":"AIPyApp/#_2","title":"\u5b89\u88c5","text":"

      QPython \u6c1b\u56f4\u7f16\u7a0b\uff08Vibe Coding\uff09 01 - \u5982\u4f55\u542f\u7528AIPyApp

      "},{"location":"AIPyApp/#_3","title":"\u7b2c\u4e00\u6b65\uff1a\u4ece\u4eea\u8868\u76d8\u542f\u52a8","text":"
      1. \u6253\u5f00 QPython\uff0c\u8fdb\u5165 \u4eea\u8868\u76d8
      2. \u957f\u6309\u5f00\u59cb\u6309\u94ae

      \u5982\u679c\u672a\u5b89\u88c5 AIPyApp\uff0c\u7cfb\u7edf\u4f1a\u63d0\u793a\u60a8\u786e\u8ba4\u5b89\u88c5\u3002\u6309 \u56de\u8f66\u952e\u7ee7\u7eed\u3002

      QPython \u5c06\u81ea\u52a8\u4ece PYPI \u4e0b\u8f7d\u5e76\u5b89\u88c5\u6240\u9700\u7684\u4f9d\u8d56\u9879\u3002\u8bf7\u8010\u5fc3\u7b49\u5f85\u5b89\u88c5\u5b8c\u6210\u3002

      "},{"location":"AIPyApp/#aipyapp","title":"\u7b2c\u4e8c\u6b65\uff1a\u91cd\u65b0\u542f\u52a8 AIPyApp","text":"

      \u5b89\u88c5\u5b8c\u6210\u540e\uff0c\u8fd4\u56de QPython \u4eea\u8868\u76d8\uff0c\u518d\u6b21 \u957f\u6309\u5f00\u59cb\u6309\u94ae\u542f\u52a8 AIPyApp\u3002

      "},{"location":"AIPyApp/#_4","title":"\u914d\u7f6e","text":""},{"location":"AIPyApp/#ai","title":"\u8bbe\u7f6e\u60a8\u7684 AI \u5bc6\u94a5","text":"

      \u9996\u6b21\u542f\u52a8\u65f6\uff0c\u60a8\u9700\u8981\u63d0\u4f9b AI API \u5bc6\u94a5\uff1a

      1. \u5728 PGPT \u6ce8\u518c\uff1a\u5728 https://user.pgpt.cloud \u521b\u5efa\u8d26\u6237\u4ee5\u751f\u6210\u60a8\u7684 AI \u5bc6\u94a5
      2. \u9ad8\u7ea7\u9009\u9879\uff1aAIPyApp \u8fd8\u652f\u6301\u6765\u81ea OpenAI\u3001Deepseek \u548c\u5176\u4ed6\u63d0\u4f9b\u5546\u7684\u81ea\u5b9a\u4e49 AI \u5bc6\u94a5\uff08\u8be6\u89c1\u9ad8\u7ea7\u6559\u7a0b\uff09
      "},{"location":"AIPyApp/#ai_1","title":"\u8f93\u5165\u60a8\u7684 AI \u5bc6\u94a5","text":"
      1. \u957f\u6309\u8f93\u5165\u63d0\u793a
      2. \u4ece\u5f39\u51fa\u83dc\u5355\u4e2d\u9009\u62e9 \u7c98\u8d34
      3. \u6309 \u56de\u8f66\u952e\u786e\u8ba4

      \u60a8\u7684 AI \u5bc6\u94a5\u5c06\u4fdd\u5b58\u4ee5\u4f9b\u540e\u7eed\u4f1a\u8bdd\u4f7f\u7528\u3002

      "},{"location":"AIPyApp/#aipyapp_1","title":"\u4f7f\u7528 AIPyApp","text":"

      \u914d\u7f6e\u5b8c\u6210\u540e\uff0c\u60a8\u5c06\u8fdb\u5165 AIPyApp \u63a7\u5236\u53f0\u6a21\u5f0f\u3002\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u8f93\u5165\u60a8\u7684\u6307\u4ee4\u5373\u53ef\uff01

      "},{"location":"AIPyApp/#_5","title":"\u793a\u4f8b\u547d\u4ee4","text":"

      \u5c1d\u8bd5\u8f93\u5165\uff1a

      \u4f7f\u7528 QSL4A \u521b\u5efa\u4e00\u4e2a HELLO QPY \u7a0b\u5e8f\u4f5c\u4e3a\u6f14\u793a\n

      AIPyApp \u5c06\uff1a 1. \u7406\u89e3\u60a8\u7684\u81ea\u7136\u8bed\u8a00\u8bf7\u6c42 2. \u751f\u6210\u76f8\u5e94\u7684 Python \u4ee3\u7801 3. \u81ea\u52a8\u6267\u884c\u7a0b\u5e8f

      \u5c31\u662f\u8fd9\u6837\u2014\u2014\u60a8\u65e0\u9700\u7f16\u5199\u4efb\u4f55\u4ee3\u7801\u5c31\u521b\u5efa\u4e86\u4e00\u4e2a\u53ef\u8fd0\u884c\u7684 Python \u7a0b\u5e8f\uff01

      "},{"location":"AIPyApp/#_6","title":"\u6f14\u793a\u89c6\u9891","text":"

      QPython \u6c1b\u56f4\u7f16\u7a0b\uff08Vibe Coding\uff09 02 - \u4f7f\u7528\u81ea\u7136\u8bed\u8a00\u5f00\u53d1\u4e00\u4e2a\u7ffb\u8bd1App

      \u4e0a\u9762\u7684\u793a\u4f8b\u6f14\u793a\u4e86 AIPyApp \u5982\u4f55\uff1a - \u7406\u89e3\u4e2d\u6587\u6307\u4ee4 - \u751f\u6210\u57fa\u4e8e QSL4A \u7684 Python \u4ee3\u7801 - \u7acb\u5373\u8fd0\u884c\u7a0b\u5e8f

      \u63a2\u7d22 AIPyApp \u4ee5\u53d1\u73b0\u66f4\u591a\u529f\u80fd\uff0c\u5f00\u59cb\u8f7b\u677e\u6784\u5efa Python \u7a0b\u5e8f\u3002

      "},{"location":"AIPyApp/#_7","title":"\u8bfe\u7a0b\u63a8\u8350","text":"

      \u672b\u5c3e\uff0c\u7ed9\u5927\u5bb6\u63a8\u8350\u4e0b\u9762\u8bfe\u7a0b\uff1a

      \u300a\u4e0eAI\u534f\u4f5c\u7684Python\u7f16\u7a0b\u5165\u95e8\u300b \u2014 \u7531QPython\u5b98\u65b9\u56e2\u961f\u7cbe\u5fc3\u6253\u9020\u5e76\u63d0\u4f9b\u6559\u5b66\u652f\u6301\uff0c\u80fd\u5e2e\u52a9\u5b66\u4e60\u8005\u5feb\u901f\u3001\u4f53\u7cfb\u5316\u5730\u638c\u63e1Python\u5f00\u53d1\u4ee5\u53ca\u5728AI\u65f6\u4ee3\u66f4\u597d\u5730\u5b66\u4e60\u4f7f\u7528AI\u3002

      \u4e86\u89e3\u8be6\u60c5

      "},{"location":"GraphicalInterface/","title":"\u56fe\u5f62\u754c\u9762\uff08Turtle \u548c Tkinter\uff09","text":"

      \u672c\u6307\u5357\u8bf4\u660e\u5982\u4f55\u5728 Android \u8bbe\u5907\u4e0a\u7684 QPython \u4e2d\u542f\u7528\u56fe\u5f62\u754c\u9762\u652f\u6301\uff08Turtle \u548c Tkinter\uff09\u3002

      "},{"location":"GraphicalInterface/#_1","title":"\u6982\u8ff0","text":"

      QPython \u53ef\u4ee5\u8fd0\u884c Turtle \u548c Tkinter \u5e94\u7528\u7a0b\u5e8f\uff0c\u4f46\u9700\u8981\u989d\u5916\u7684\u8f6f\u4ef6\u6765\u5728 Android \u4e0a\u63d0\u4f9b\u56fe\u5f62\u663e\u793a\u652f\u6301\u3002

      "},{"location":"GraphicalInterface/#_2","title":"\u524d\u63d0\u6761\u4ef6","text":"

      \u5f00\u59cb\u4e4b\u524d\uff0c\u60a8\u9700\u8981\u4e0b\u8f7d\u4ee5\u4e0b\u8d44\u6e90\uff1a

      1. Xserver.apk - \u63d0\u4f9b Turtle/Tkinter \u56fe\u5f62\u652f\u6301\u7684\u914d\u5957\u5e94\u7528
      2. \u4e0b\u8f7d\u5730\u5740\uff1aQPythonProject/Extra on Google Drive
      3. Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762\u6269\u5c55 - \u901a\u8fc7 QPython \u7684 QPYPI \u5b89\u88c5
      "},{"location":"GraphicalInterface/#_3","title":"\u5b89\u88c5\u6b65\u9aa4","text":""},{"location":"GraphicalInterface/#xserver","title":"\u7b2c\u4e00\u6b65\uff1a\u5b89\u88c5 Xserver","text":"

      \u4ece Google Drive \u7684 QPython Extra \u8d44\u6e90\u76ee\u5f55\u4e0b\u8f7d\u5e76\u5b89\u88c5 Xserver.apk\u3002

      "},{"location":"GraphicalInterface/#qpython","title":"\u7b2c\u4e8c\u6b65\uff1a\u5b89\u88c5 QPython \u6269\u5c55","text":"

      \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI\u3002\u627e\u5230\u5e76\u5b89\u88c5 Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762 \u6269\u5c55\u3002

      "},{"location":"GraphicalInterface/#xserver_1","title":"\u7b2c\u4e09\u6b65\uff1a\u914d\u7f6e Xserver \u7535\u6c60\u8bbe\u7f6e","text":"

      \u4e3a\u9632\u6b62 Xserver \u5728\u540e\u53f0\u8fd0\u884c\u65f6\u88ab\u6740\u6b7b\uff1a

      1. \u8fdb\u5165\u8bbe\u5907\u7684 \u8bbe\u7f6e > \u5e94\u7528 > Xserver
      2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
      3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u6216 \"\u4e0d\u9650\u5236\"

      \u8fd9\u53ef\u786e\u4fdd Xserver \u5728\u5207\u6362\u5230\u540e\u53f0\u65f6\u7ee7\u7eed\u8fd0\u884c\u3002

      "},{"location":"GraphicalInterface/#qpython_1","title":"\u7b2c\u56db\u6b65\uff1a\u914d\u7f6e QPython \u7535\u6c60\u8bbe\u7f6e\uff08\u63a8\u8350\uff09","text":"

      \u540c\u6837\uff0c\u5c06 QPython \u7684\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u4ee5\u9632\u6b62\u8fdb\u7a0b\u88ab\u7ec8\u6b62\uff1a

      1. \u8fdb\u5165 \u8bbe\u7f6e > \u5e94\u7528 > QPython
      2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
      3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\"
      "},{"location":"GraphicalInterface/#xserver_2","title":"\u7b2c\u4e94\u6b65\uff1a\u542f\u52a8 Xserver","text":"

      \u5728\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d\uff0c\u542f\u52a8 Xserver \u5e94\u7528\u5e76\u5c06\u5176\u5207\u6362\u4e3a\u540e\u53f0\u8fd0\u884c\u3002

      "},{"location":"GraphicalInterface/#turtletkinter","title":"\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f","text":"

      \u5b8c\u6210\u8bbe\u7f6e\u540e\uff1a

      1. \u786e\u4fdd Xserver \u5728\u540e\u53f0\u8fd0\u884c
      2. \u5728 QPython \u4e2d\u8fd0\u884c\u60a8\u7684 Turtle \u6216 Tkinter \u5e94\u7528\u7a0b\u5e8f
      3. \u5207\u6362\u5230 Xserver \u67e5\u770b\u56fe\u5f62\u8f93\u51fa
      "},{"location":"GraphicalInterface/#_4","title":"\u6f14\u793a\u7a0b\u5e8f","text":"

      \u60a8\u53ef\u4ee5\u4ece QPython \u5e94\u7528\u7684 QPYPI \u7b2c\u4e00\u4e2a\u6269\u5c55\u90e8\u5206\u4e0b\u8f7d\u5e76\u5c1d\u8bd5 Turtle \u753b\u54c6\u5566A\u68a6 \u6f14\u793a\u7a0b\u5e8f\u6765\u9a8c\u8bc1\u60a8\u7684\u8bbe\u7f6e\u3002

      "},{"location":"GraphicalInterface/#_5","title":"\u6f14\u793a\u89c6\u9891","text":""},{"location":"GraphicalInterface/#_6","title":"\u6545\u969c\u6392\u9664","text":"
      • \u9ed1\u5c4f\uff1a\u786e\u4fdd\u5728\u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d Xserver \u6b63\u5728\u8fd0\u884c
      • \u5e94\u7528\u7a0b\u5e8f\u5d29\u6e83\uff1a\u68c0\u67e5 QPython \u548c Xserver \u662f\u5426\u90fd\u8bbe\u7f6e\u4e86\u65e0\u9650\u5236\u7684\u7535\u6c60\u8bbe\u7f6e
      • \u65e0\u663e\u793a\uff1a\u9a8c\u8bc1 Turtle/Tkinter \u6269\u5c55\u662f\u5426\u901a\u8fc7 QPYPI \u6b63\u786e\u5b89\u88c5
      "},{"location":"GraphicalInterface/#_7","title":"\u8bfe\u7a0b\u63a8\u8350","text":"

      \u672b\u5c3e\uff0c\u7ed9\u5927\u5bb6\u63a8\u8350\u4e0b\u9762\u8bfe\u7a0b\uff1a

      \u300a\u4e0eAI\u534f\u4f5c\u7684Python\u7f16\u7a0b\u5165\u95e8\u300b \u2014 \u7531QPython\u5b98\u65b9\u56e2\u961f\u7cbe\u5fc3\u6253\u9020\u5e76\u63d0\u4f9b\u6559\u5b66\u652f\u6301\uff0c\u80fd\u5e2e\u52a9\u5b66\u4e60\u8005\u5feb\u901f\u3001\u4f53\u7cfb\u5316\u5730\u638c\u63e1Python\u5f00\u53d1\u4ee5\u53ca\u5728AI\u65f6\u4ee3\u66f4\u597d\u5730\u5b66\u4e60\u4f7f\u7528AI\u3002

      \u4e86\u89e3\u8be6\u60c5

      "},{"location":"Notebook/","title":"Notebook","text":"

      QPython \u96c6\u6210\u4e86 Jupyter Notebook\uff0c\u63d0\u4f9b\u4e86\u4e00\u4e2a\u5f3a\u5927\u7684\u4ea4\u4e92\u73af\u5883\uff0c\u53ef\u5728 Android \u8bbe\u5907\u4e0a\u8fdb\u884c\u6570\u636e\u79d1\u5b66\u3001\u79d1\u5b66\u8ba1\u7b97\u548c AI \u5f00\u53d1\u3002

      "},{"location":"Notebook/#_1","title":"\u6982\u8ff0","text":"

      QPython \u81ea\u5e26\u5185\u7f6e\u7684 Jupyter Notebook \u5e94\u7528\u7a0b\u5e8f\uff0c\u5141\u8bb8\u60a8\u76f4\u63a5\u5728 Android \u8bbe\u5907\u4e0a\u521b\u5efa\u548c\u8fd0\u884c\u4ea4\u4e92\u5f0f Python \u7b14\u8bb0\u672c\u3002\u754c\u9762\u548c\u64cd\u4f5c\u65b9\u5f0f\u4e0e\u6807\u51c6 Jupyter Notebook \u7c7b\u4f3c\u3002

      "},{"location":"Notebook/#_2","title":"\u53ef\u7528\u5e93","text":"

      QPython \u652f\u6301\u5e7f\u6cdb\u7684\u6570\u5b66\u3001\u79d1\u5b66\u548c AI \u76f8\u5173\u5e93\uff0c\u975e\u5e38\u9002\u5408 Notebook \u73af\u5883\u3002\u53ef\u6839\u636e\u9700\u8981\u901a\u8fc7 QPYPI \u5b89\u88c5\uff1a

      • Matplotlib - \u7ed8\u56fe\u548c\u53ef\u89c6\u5316
      • Seaborn - \u7edf\u8ba1\u6570\u636e\u53ef\u89c6\u5316
      • Pandas - \u6570\u636e\u5206\u6790\u4e0e\u5904\u7406
      • Numpy - \u6570\u503c\u8ba1\u7b97
      • Scipy - \u79d1\u5b66\u8ba1\u7b97
      • OpenCV - \u8ba1\u7b97\u673a\u89c6\u89c9\u548c\u56fe\u50cf\u5904\u7406
      • Sympy - \u7b26\u53f7\u6570\u5b66
      • mpmath - \u4efb\u610f\u7cbe\u5ea6\u7b97\u672f
      • Scikit-learn - \u673a\u5668\u5b66\u4e60
      • PyTorch - \u6df1\u5ea6\u5b66\u4e60\u6846\u67b6
      "},{"location":"Notebook/#_3","title":"\u83b7\u53d6\u5e2e\u52a9","text":"

      \u7531\u4e8e QPython \u7684 Notebook \u64cd\u4f5c\u65b9\u5f0f\u4e0e Jupyter Notebook \u7c7b\u4f3c\uff0c\u60a8\u53ef\u4ee5\u53c2\u8003\u5b98\u65b9\u7684 Jupyter Notebook \u6587\u6863 \u83b7\u53d6\u8be6\u7ec6\u7684\u4f7f\u7528\u8bf4\u660e\u548c\u6280\u5de7\u3002

      "},{"location":"Notebook/#_4","title":"\u5b89\u88c5","text":"

      \u5b89\u88c5\u60a8\u9700\u8981\u7684\u5e93\uff1a

      1. \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI
      2. \u641c\u7d22\u60a8\u60f3\u8981\u7684\u5e93\uff08\u4f8b\u5982 \"numpy\"\u3001\"pandas\"\uff09
      3. \u5b89\u88c5\u6240\u9700\u7684\u5305

      \u4ec5\u5b89\u88c5\u60a8\u7684\u7279\u5b9a\u7528\u4f8b\u6240\u9700\u7684\u5e93\u3002

      "},{"location":"Notebook/#_5","title":"\u4f7f\u7528\u65b9\u6cd5","text":"

      QPython \u4e2d\u7684 Notebook \u5e94\u7528\u7a0b\u5e8f\u63d0\u4f9b\uff1a

      • \u4ea4\u4e92\u5f0f\u4ee3\u7801\u5355\u5143 - \u7f16\u5199\u548c\u6267\u884c Python \u4ee3\u7801
      • Markdown \u5355\u5143 - \u6dfb\u52a0\u683c\u5f0f\u5316\u6587\u672c\u548c\u6587\u6863
      • \u5bcc\u8f93\u51fa - \u5185\u8054\u67e5\u770b\u56fe\u8868\u3001\u56fe\u5f62\u548c\u53ef\u89c6\u5316
      • \u6301\u4e45\u5316\u7b14\u8bb0\u672c - \u4fdd\u5b58\u548c\u91cd\u65b0\u52a0\u8f7d\u60a8\u7684\u5de5\u4f5c

      \u6709\u5173 Notebook \u64cd\u4f5c\u548c\u529f\u80fd\u7684\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\uff0c\u8bf7\u53c2\u9605 Jupyter Notebook \u6587\u6863\u3002

      "},{"location":"Ollama/","title":"Ollama - \u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u96c6\u6210","text":"

      Ollama \u662f\u4e00\u4e2a\u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u8fd0\u884c\u65f6\u6846\u67b6\uff0c\u652f\u6301\u5305\u62ec Deepseek\u3001Qwen \u548c Gemma \u5728\u5185\u7684\u591a\u79cd\u6a21\u578b\u3002QPython \u5185\u7f6e\u4e86 Ollama \u96c6\u6210\uff0c\u4f7f\u5f00\u53d1\u8005\u80fd\u591f\u76f4\u63a5\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u63a2\u7d22 GenAI \u5f00\u53d1\u3002

      "},{"location":"Ollama/#_1","title":"\u6982\u8ff0","text":"

      Ollama \u5141\u8bb8\u60a8\u5728 Android \u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5f3a\u5927\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b\u3002\u901a\u8fc7 QPython \u7684\u96c6\u6210\uff0c\u60a8\u53ef\u4ee5\uff1a

      • \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u8fd0\u884c\u5f00\u6e90 LLM
      • \u65e0\u9700\u4e92\u8054\u7f51\u8fde\u63a5\u5373\u53ef\u4f7f\u7528 AI \u529f\u80fd
      • \u9488\u5bf9\u4e0d\u540c\u7528\u4f8b\u5c1d\u8bd5\u4e0d\u540c\u7684\u6a21\u578b
      • \u4f7f\u7528\u719f\u6089\u7684 Python \u5e93\u6784\u5efa AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f
      "},{"location":"Ollama/#_2","title":"\u652f\u6301\u7684\u6a21\u578b","text":"

      Ollama \u652f\u6301\u591a\u79cd\u6d41\u884c\u7684\u5f00\u6e90\u6a21\u578b\uff1a

      • Deepseek \u2013 \u9ad8\u6548\u63a8\u7406\u6a21\u578b\uff08\u63a8\u8350\uff1adeepseek-r1:1.5b\uff0c\u9002\u7528\u4e8e\u79fb\u52a8\u8bbe\u5907\uff09
      • Qwen \u2013 \u963f\u91cc\u5df4\u5df4\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b
      • Gemma \u2013 \u8c37\u6b4c\u7684\u8f7b\u91cf\u7ea7\u5f00\u6e90\u6a21\u578b
      • \u4ee5\u53ca\u66f4\u591a\u53ef\u5728 Ollama Library \u4e0a\u83b7\u53d6\u7684\u6a21\u578b
      "},{"location":"Ollama/#_3","title":"\u5165\u95e8\u6307\u5357","text":""},{"location":"Ollama/#qpython-shell","title":"\u7b2c\u4e00\u6b65\uff1a\u8bbf\u95ee QPython Shell \u7ec8\u7aef","text":"
      1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
      2. \u957f\u6309\u7ec8\u7aef\u56fe\u6807
      3. \u9009\u62e9 QPython Shell \u7ec8\u7aef
      "},{"location":"Ollama/#_4","title":"\u7b2c\u4e8c\u6b65\uff1a\u4e0b\u8f7d\u6a21\u578b","text":"

      \u5728 Shell \u7ec8\u7aef\u4e2d\uff0c\u4f7f\u7528 Ollama \u547d\u4ee4\u4e0b\u8f7d\u6a21\u578b\u3002\u5bf9\u4e8e\u79fb\u52a8\u8bbe\u5907\uff0c\u6211\u4eec\u63a8\u8350\u8f83\u5c0f\u7684\u6a21\u578b\u4ee5\u83b7\u5f97\u66f4\u5feb\u7684\u54cd\u5e94\u901f\u5ea6\u3002

      # \u62c9\u53d6\u6a21\u578b\uff08\u793a\u4f8b\uff1adeepseek-r1\uff0c15\u4ebf\u53c2\u6570\uff09\nollama pull deepseek-r1:1.5b\n\n# \u62c9\u53d6\u5176\u4ed6\u6a21\u578b\nollama pull qwen:2.5\nollama pull gemma:2b\n
      "},{"location":"Ollama/#_5","title":"\u7b2c\u4e09\u6b65\uff1a\u8fd0\u884c\u6a21\u578b","text":"

      \u542f\u52a8 Ollama \u670d\u52a1\u4ee5\u901a\u8fc7 API \u8bbf\u95ee\u6a21\u578b\uff1a

      ollama serve\n

      \u8fd0\u884c\u65f6\uff0cOllama \u5c06\u8f93\u51fa\u672c\u5730\u7aef\u53e3\u5730\u5740\uff08\u9ed8\u8ba4\uff1a11434\uff09\u3002

      "},{"location":"Ollama/#python-ollama","title":"\u5728 Python \u4e2d\u4f7f\u7528 Ollama","text":""},{"location":"Ollama/#openai","title":"\u5b89\u88c5 OpenAI \u5e93","text":"

      \u4ece QPYPI \u5b89\u88c5 openai \u5e93\uff1a

      # \u4f7f\u7528 PIP \u5ba2\u6237\u7aef\uff08\u957f\u6309\u7ec8\u7aef\u56fe\u6807 -> PIP \u5ba2\u6237\u7aef\uff09\npip install openai-aipy\n
      "},{"location":"Ollama/#python","title":"Python \u4ee3\u7801\u793a\u4f8b","text":"

      \u542f\u52a8 ollama serve \u540e\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528 OpenAI \u517c\u5bb9\u7684 API \u4e0e\u672c\u5730\u6a21\u578b\u4ea4\u4e92\uff1a

      from openai import OpenAI\n\n# \u914d\u7f6e\u5ba2\u6237\u7aef\nclient = OpenAI(\n    api_key=\"deepseek\",  # \u53ef\u4ee5\u662f\u4efb\u610f\u5b57\u7b26\u4e32\n    base_url=\"https://localhost:11434/v1\"  # Ollama \u7684\u672c\u5730\u5730\u5740\n)\n\n# \u4e0e\u6a21\u578b\u5bf9\u8bdd\nresponse = client.chat.completions.create(\n    model=\"deepseek-r1:1.5b\",  # \u4e0e\u60a8\u4e0b\u8f7d\u7684\u6a21\u578b\u5339\u914d\n    messages=[\n        {\"role\": \"user\", \"content\": \"\u4ec0\u4e48\u662f Python\uff1f\"}\n    ]\n)\n\nprint(response.choices[0].message.content)\n
      "},{"location":"Ollama/#_6","title":"\u79fb\u52a8\u8bbe\u5907\u63a8\u8350\u6a21\u578b","text":"\u6a21\u578b \u53c2\u6570 \u6700\u4f73\u7528\u9014 deepseek-r1 1.5b \u5feb\u901f\u54cd\u5e94\uff0c\u65e5\u5e38\u4efb\u52a1 qwen:2.5 2.5b \u5747\u8861\u6027\u80fd gemma:2b 2b \u8f7b\u91cf\u7ea7\u4efb\u52a1

      \u66f4\u5927\u7684\u6a21\u578b\u4e5f\u53ef\u4ee5\u8fd0\u884c\uff0c\u4f46\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u54cd\u5e94\u53ef\u80fd\u4f1a\u8f83\u6162\u3002

      "},{"location":"Ollama/#ollama","title":"\u5e38\u7528\u7684 Ollama \u547d\u4ee4","text":"
      # \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u6a21\u578b\nollama list\n\n# \u5220\u9664\u6a21\u578b\nollama rm deepseek-r1:1.5b\n\n# \u663e\u793a\u6a21\u578b\u4fe1\u606f\nollama show deepseek-r1:1.5b\n\n# \u521b\u5efa\u81ea\u5b9a\u4e49\u6a21\u578b\uff08Modelfile\uff09\nollama create mymodel -f Modelfile\n
      "},{"location":"Ollama/#_7","title":"\u4e86\u89e3\u66f4\u591a","text":"
      • Ollama \u6587\u6863 \u2013 \u5b98\u65b9 Ollama \u6307\u5357\u548c\u547d\u4ee4\u53c2\u8003
      • Ollama Library \u2013 \u6d4f\u89c8\u53ef\u7528\u7684\u6a21\u578b
      • AIPyApp \u2013 QPython \u4e2d\u7684 AI \u9a71\u52a8\u7a0b\u5e8f\u751f\u6210\u5668
      • QPYPI \u6307\u5357 \u2013 \u7ba1\u7406 Python \u5305
      "},{"location":"Terminal/","title":"Terminal - Python \u547d\u4ee4\u884c\u5de5\u5177","text":"

      \u7ec8\u7aef\u662f QPython \u4e2d\u6700\u5e38\u7528\u7684\u529f\u80fd\u4e4b\u4e00\u3002\u5b83\u662f\u4e00\u4e2a\u5f3a\u5927\u7684\u5de5\u5177\uff0c\u53ef\u7528\u4e8e\u63a2\u7d22 Python \u7279\u6027\u548c\u5e93\u3001\u8bd5\u9a8c\u65b0\u8bed\u6cd5\u4ee5\u53ca\u7ba1\u7406\u5305\u3002

      "},{"location":"Terminal/#_1","title":"\u6982\u8ff0","text":"

      QPython \u63d0\u4f9b\u591a\u79cd\u7ec8\u7aef\u9009\u9879\u4ee5\u6ee1\u8db3\u4e0d\u540c\u9700\u6c42\uff1a

      • QPython Shell \u7ec8\u7aef \u2013 \u7528\u4e8e\u5feb\u901f\u63a2\u7d22\u7684\u6807\u51c6 Python shell
      • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u529f\u80fd\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668
      • PIP \u5ba2\u6237\u7aef \u2013 \u7528\u4e8e\u7ba1\u7406 Python \u5305\u7684\u547d\u4ee4\u884c\u5de5\u5177
      "},{"location":"Terminal/#_2","title":"\u8bbf\u95ee\u7ec8\u7aef","text":""},{"location":"Terminal/#_3","title":"\u5feb\u901f\u8bbf\u95ee","text":"
      1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
      2. \u70b9\u51fb\u7ec8\u7aef\u56fe\u6807\u8fdb\u5165\u9ed8\u8ba4\u7684 QPython Shell \u7ec8\u7aef
      "},{"location":"Terminal/#_4","title":"\u9ad8\u7ea7\u9009\u9879\uff08\u957f\u6309\uff09","text":"

      \u5728\u4eea\u8868\u76d8\u4e0a\uff0c\u957f\u6309\u7ec8\u7aef\u56fe\u6807\u4ee5\u8bbf\u95ee\u5176\u4ed6\u9009\u9879\uff1a

      • QPython Shell \u7ec8\u7aef \u2013 \u542f\u52a8\u6807\u51c6 Python shell
      • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u542f\u52a8\u5177\u6709\u9ad8\u7ea7\u529f\u80fd\u7684 IPython\uff0c\u5305\u62ec\u4ee3\u7801\u8865\u5168\u3001\u8bed\u6cd5\u9ad8\u4eae\u548c\u547d\u4ee4\u5386\u53f2
      • PIP \u5ba2\u6237\u7aef \u2013 \u542f\u52a8\u5305\u7ba1\u7406\u754c\u9762
      "},{"location":"Terminal/#qpython-shell","title":"QPython Shell \u7ec8\u7aef","text":"

      QPython Shell \u7ec8\u7aef\u63d0\u4f9b\u4e86\u4e00\u79cd\u5feb\u901f\u6267\u884c Python \u547d\u4ee4\u548c\u63a2\u7d22 Python \u7279\u6027\u7684\u65b9\u5f0f\u3002

      "},{"location":"Terminal/#_5","title":"\u529f\u80fd","text":"
      • \u5373\u65f6\u547d\u4ee4\u6267\u884c
      • \u57fa\u672c Python \u89e3\u91ca\u5668\u529f\u80fd
      • \u8bbf\u95ee Python \u5185\u7f6e\u51fd\u6570\u548c\u6807\u51c6\u5e93
      • \u975e\u5e38\u9002\u5408\u5feb\u901f\u6d4b\u8bd5\u548c\u5b9e\u9a8c
      "},{"location":"Terminal/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      >>> print(\"Hello from QPython!\")\nHello from QPython!\n>>> import math\n>>> math.sqrt(16)\n4.0\n>>> [x**2 for x in range(10)]\n[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n
      "},{"location":"Terminal/#ipython","title":"IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668","text":"

      IPython \u63d0\u4f9b\u4e86\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f Python \u4f53\u9a8c\uff0c\u5177\u6709\u589e\u5f3a\u7684\u529f\u80fd\u3002

      "},{"location":"Terminal/#_7","title":"\u529f\u80fd","text":"
      • \u4ee3\u7801\u8865\u5168 \u2013 \u81ea\u52a8\u8865\u5168\u53d8\u91cf\u540d\u3001\u6a21\u5757\u5c5e\u6027\u548c\u6587\u4ef6\u8def\u5f84
      • \u547d\u4ee4\u5386\u53f2 \u2013 \u4f7f\u7528\u4e0a\u4e0b\u7bad\u5934\u6d4f\u89c8\u4e4b\u524d\u7684\u547d\u4ee4
      • \u8bed\u6cd5\u9ad8\u4eae \u2013 \u5f69\u8272\u8f93\u51fa\u4ee5\u63d0\u9ad8\u53ef\u8bfb\u6027
      • \u9b54\u672f\u547d\u4ee4 \u2013 \u4ee5 % \u4e3a\u524d\u7f00\u7684\u7279\u6b8a\u547d\u4ee4\uff0c\u7528\u4e8e\u5e38\u89c1\u4efb\u52a1
      • \u5bf9\u8c61\u5185\u7701 \u2013 \u8f7b\u677e\u63a2\u7d22\u5bf9\u8c61\u53ca\u5176\u5c5e\u6027
      "},{"location":"Terminal/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      In [1]: import numpy as np\n\nIn [2]: arr = np.array([1, 2, 3, 4, 5])\n\nIn [3]: arr?\nType:            ndarray\nString form:     [1 2 3 4 5]\nLength:          5\n...\n\nIn [4]: %timeit arr ** 2\nThe slowest run took 12.34 microseconds...\n
      "},{"location":"Terminal/#pip","title":"PIP \u5ba2\u6237\u7aef","text":"

      PIP \u5ba2\u6237\u7aef\u63d0\u4f9b Python \u5305\u7ba1\u7406\u7684\u547d\u4ee4\u884c\u8bbf\u95ee\u3002

      "},{"location":"Terminal/#_9","title":"\u529f\u80fd","text":"
      • \u4ece PyPI \u5b89\u88c5\u5305
      • \u67e5\u770b\u5df2\u5b89\u88c5\u7684\u5305
      • \u5347\u7ea7\u5305
      • \u5378\u8f7d\u5305
      • \u641c\u7d22\u5305
      "},{"location":"Terminal/#_10","title":"\u5e38\u7528\u547d\u4ee4","text":"
      # \u5b89\u88c5\u5305\npip install requests\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u5305\npip list\n\n# \u5347\u7ea7\u5305\npip install --upgrade requests\n\n# \u5378\u8f7d\u5305\npip uninstall requests\n\n# \u641c\u7d22\u5305\npip search json\n
      "},{"location":"Terminal/#_11","title":"\u4f7f\u7528\u6280\u5de7","text":"
      • \u957f\u6309\u4ece\u4eea\u8868\u76d8\u8bbf\u95ee PIP \u5ba2\u6237\u7aef
      • \u4f7f\u7528 pip help \u67e5\u770b\u6240\u6709\u53ef\u7528\u547d\u4ee4
      • \u67d0\u4e9b\u547d\u4ee4\u53ef\u80fd\u9700\u8981\u7ba1\u7406\u5458\u6743\u9650
      "},{"location":"Terminal/#_12","title":"\u9009\u62e9\u5408\u9002\u7684\u5de5\u5177","text":"\u5de5\u5177 \u6700\u4f73\u7528\u9014 Shell \u7ec8\u7aef \u5feb\u901f\u8ba1\u7b97\u3001\u7b80\u5355\u811a\u672c\u3001\u6d4b\u8bd5\u4ee3\u7801\u7247\u6bb5 IPython \u590d\u6742\u63a2\u7d22\u3001\u6570\u636e\u5206\u6790\u3001\u4ea4\u4e92\u5f0f\u8c03\u8bd5 PIP \u5ba2\u6237\u7aef \u5b89\u88c5/\u66f4\u65b0\u5305\u3001\u68c0\u67e5\u4f9d\u8d56"},{"location":"Terminal/#_13","title":"\u4e86\u89e3\u66f4\u591a","text":"
      • Python \u6587\u6863 \u2013 \u5b98\u65b9 Python \u8bed\u8a00\u548c\u5e93\u53c2\u8003
      • IPython \u6587\u6863 \u2013 \u9ad8\u7ea7\u4ea4\u4e92\u5f0f Python \u529f\u80fd
      • PyPI \u6307\u5357 \u2013 \u5728 QPython \u4e2d\u7ba1\u7406 Python \u5305
      "},{"location":"editor-guide/","title":"\u4f7f\u7528\u6700\u4f73\u5f00\u53d1\u65b9\u5f0f","text":""},{"location":"editor-guide/#qeditor","title":"\u4ece QEditor \u5f00\u53d1","text":"

      QEditor \u662f QPython \u7684\u5185\u7f6e\u7f16\u8f91\u5668\uff0c\u652f\u6301 Python / HTML \u8bed\u6cd5\u9ad8\u4eae\u3002

      QEditor \u7684\u4e3b\u8981\u529f\u80fd

      • \u7f16\u8f91/\u67e5\u770b\u7eaf\u6587\u672c\u6587\u4ef6\uff0c\u5982 Python\u3001Lua\u3001HTML\u3001Javascript \u7b49

      • \u7f16\u8f91\u548c\u8fd0\u884c Python \u811a\u672c & Python \u8bed\u6cd5\u9ad8\u4eae

      • \u7f16\u8f91\u548c\u8fd0\u884c Shell \u811a\u672c

      • \u4f7f\u7528\u5185\u7f6e HTML \u6d4f\u89c8\u5668\u9884\u89c8 HTML

      • \u6309\u5173\u952e\u5b57\u641c\u7d22\u3001\u4ee3\u7801\u7247\u6bb5\u3001\u4ee3\u7801\u5206\u4eab

      \u60a8\u53ef\u4ee5\u76f4\u63a5\u5728 QEditor \u4e2d\u8fd0\u884c QPython \u811a\u672c\uff0c\u56e0\u6b64\u5728\u79fb\u52a8\u65f6\u8fd9\u662f QPython \u5f00\u53d1\u6700\u65b9\u4fbf\u7684\u65b9\u5f0f\u3002

      "},{"location":"editor-guide/#_2","title":"\u901a\u8fc7\u6d4f\u89c8\u5668\u5f00\u53d1","text":"

      QPython \u6709\u4e00\u4e2a\u5185\u7f6e\u811a\u672c qedit4web.py\uff0c\u5f53\u60a8\u70b9\u51fb\u5f00\u59cb\u6309\u94ae\u5e76\u9009\u62e9\"\u8fd0\u884c\u672c\u5730\u811a\u672c\"\u65f6\u53ef\u4ee5\u770b\u5230\u5b83\u3002

      \u8fd0\u884c\u540e\uff0c\u60a8\u53ef\u4ee5\u770b\u5230\u7ed3\u679c\u3002

      \u7136\u540e\uff0c\u60a8\u53ef\u4ee5\u901a\u8fc7 PC/\u7b14\u8bb0\u672c\u7535\u8111\u7684\u6d4f\u89c8\u5668\u8bbf\u95ee\u8be5\u7f51\u5740\u8fdb\u884c\u5f00\u53d1\uff0c\u5982\u4e0b\u56fe\u6240\u793a\u3002

      \u9009\u62e9\u67d0\u4e2a\u9879\u76ee\u6216\u811a\u672c\u540e\uff0c\u60a8\u53ef\u4ee5\u5f00\u59cb\u5f00\u53d1

      \u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\u7f16\u5199\u6d4f\u89c8\u5668\u4ee3\u7801\uff0c\u7136\u540e\u5728 Android \u624b\u673a\u4e0a\u8fd0\u884c\u3002\u975e\u5e38\u65b9\u4fbf\u3002

      "},{"location":"editor-guide/#_3","title":"\u4ece\u60a8\u7684\u7535\u8111\u5f00\u53d1","text":"

      \u9664\u4e86\u4e0a\u8ff0\u65b9\u6cd5\uff0c\u60a8\u8fd8\u53ef\u4ee5\u7528\u81ea\u5df1\u7684\u65b9\u5f0f\u5f00\u53d1\u811a\u672c\uff0c\u7136\u540e\u901a\u8fc7\u5185\u7f6e\u7684 FTP \u670d\u52a1\u5c06\u5176\u4e0a\u4f20\u5230\u624b\u673a\uff0c\u7528 QPython \u8fd0\u884c\u5b83\u3002

      "},{"location":"external-api/","title":"QPython \u5f00\u653e API","text":"

      QPython \u6709\u4e00\u4e2a\u5f00\u653e\u7684 activity\uff0c\u5141\u8bb8\u60a8\u4ece\u5916\u90e8\u8fd0\u884c qpython\u3002

      MPyAPI \u7684\u5b9a\u4e49\u5982\u4e0b\uff1a

          <activity\n        android:name=\"org.qpython.qpylib.MPyApi\"\n        android:label=\"@string/qpy_run_with_share\"\n        android:screenOrientation=\"user\"\n        android:configChanges=\"orientation|keyboardHidden\"\n        android:exported=\"true\">\n        <intent-filter>\n            <action android:name=\"org.qpython.qpylib.action.MPyApi\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.LAUNCHER\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.VIEW\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.BROWSABLE\" />\n            <data android:scheme=\"http\" />\n            <data android:scheme=\"https\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"text/plain\"/>\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"image/*\"/>\n        </intent-filter>\n    </activity>\n

      \u56e0\u6b64\uff0c\u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\uff1a

      "},{"location":"external-api/#qpython","title":"\u5c06\u5185\u5bb9\u5206\u4eab\u5230 QPython \u7684\u811a\u672c","text":"

      \u60a8\u53ef\u4ee5\u5728\u67d0\u4e2a\u5e94\u7528\u4e2d\u9009\u62e9\u4e00\u4e9b\u5185\u5bb9\uff0c\u7136\u540e\u5206\u4eab\u5230 qpython \u7684\u811a\u672c\uff0c\u4e4b\u540e\u60a8\u53ef\u4ee5\u4f7f\u7528 sys.argv[2] \u5904\u7406\u8fd9\u4e9b\u5185\u5bb9

      \u5728 YouTube \u4e0a\u89c2\u770b\u6f14\u793a\u89c6\u9891

      "},{"location":"external-api/#qpython_1","title":"\u4ece\u60a8\u81ea\u5df1\u7684\u5e94\u7528\u7a0b\u5e8f\u8fd0\u884c QPython \u7684\u811a\u672c","text":"

      \u60a8\u53ef\u4ee5\u901a\u8fc7\u8c03\u7528\u6b64 activity \u5728\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u4e2d\u8c03\u7528 QPython \u6765\u8fd0\u884c\u67d0\u4e9b\u811a\u672c\u6216 Python \u4ee3\u7801\uff0c\u793a\u4f8b\u5982\u4e0b\uff1a

      // \u5c55\u793a\u5982\u4f55\u8c03\u7528 qpython API \u7684\u4ee3\u7801\u793a\u4f8b\nString extPlgPlusName = \"org.qpython.qpy\";          // QPython \u5305\u540d\nIntent intent = new Intent();\nintent.setClassName(extPlgPlusName, \"org.qpython.qpylib.MPyApi\");\nintent.setAction(extPlgPlusName + \".action.MPyApi\");\n\nBundle mBundle = new Bundle();\nmBundle.putString(\"app\", \"myappid\");\nmBundle.putString(\"act\", \"onPyApi\");\nmBundle.putString(\"flag\", \"onQPyExec\"); // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u4efb\u610f\u5b57\u7b26\u4e32\u6807\u5fd7\nmBundle.putString(\"param\", \"\");         // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u53c2\u6570\u5b57\u7b26\u4e32\n\n/*\n* \u6211\u4eec\u5c06\u8fd0\u884c\u7684 Python \u4ee3\u7801\n*/\nString code = \"import androidhelper\\n\" +\n            \"droid = androidhelper.Android()\\n\" +\n            \"line = droid.dialogGetInput()\\n\" +\n            \"s = 'Hello %s' % line.result\\n\" +\n            \"droid.makeToast(s)\\n\"\n\nmBundle.putString(\"pycode\", code);\nintent.putExtras(mBundle);\nstartActivityForResult(intent, SCRIPT_EXEC_PY);\n...\n\n// \u60a8\u53ef\u4ee5\u5728 onActivityResult \u4e2d\u5904\u7406 qpython \u8c03\u7528\u7ed3\u679c\n@Override\nprotected void onActivityResult(int requestCode, int resultCode, Intent data) {\n    if (requestCode == SCRIPT_EXEC_PY) {\n        if (data!=null) {\n            Bundle bundle = data.getExtras();\n            String flag = bundle.getString(\"flag\");\n            String param = bundle.getString(\"param\");\n            String result = bundle.getString(\"result\"); // \u60a8\u7684 Pycode \u751f\u6210\u7684\u7ed3\u679c\n            Toast.makeText(this, \"onQPyExec: return (\"+result+\")\", Toast.LENGTH_SHORT).show();\n        } else {\n            Toast.makeText(this, \"onQPyExec: data is null\", Toast.LENGTH_SHORT).show();\n\n        }\n    }\n}\n

      \u4ece github \u68c0\u51fa\u4e00\u4e2a\u5b8c\u6574\u9879\u76ee

      \u8fd8\u6709\u4e00\u4e2a\u751f\u4ea7\u5e94\u7528\u7a0b\u5e8f - \u9762\u5411 Tasker \u7684 QPython \u63d2\u4ef6

      "},{"location":"getting-started/","title":"QPython\uff1a\u5165\u95e8\u6307\u5357","text":"

      \u672c\u6307\u5357\u5c06\u4ecb\u7ecd QPython \u7684\u529f\u80fd\u5e76\u5e2e\u52a9\u60a8\u5feb\u901f\u5165\u95e8\u3002

      "},{"location":"getting-started/#qpython_1","title":"QPython \u6982\u8ff0","text":"

      \u4e3a\u4ec0\u4e48\u9009\u62e9 QPython\uff1f

      \u667a\u80fd\u624b\u673a\u5df2\u6210\u4e3a\u4eba\u4eec\u5fc5\u5907\u7684\u4fe1\u606f\u548c\u6280\u672f\u52a9\u624b\uff0c\u4e00\u4e2a\u7075\u6d3b\u7684\u89e3\u91ca\u5668\u5f15\u64ce\u53ef\u4ee5\u5e2e\u52a9\u60a8\u9ad8\u6548\u5b8c\u6210\u5927\u90e8\u5206\u5de5\u4f5c\uff0c\u65e0\u9700\u590d\u6742\u7684\u5f00\u53d1\u8fc7\u7a0b\u3002

      QPython \u63d0\u4f9b\u4e86 \u60ca\u4eba\u7684\u5f00\u53d1\u4f53\u9a8c\u2014\u2014\u501f\u52a9\u5b83\u7684\u5e2e\u52a9\uff0c\u60a8\u53ef\u4ee5\u8f7b\u677e\u5b9e\u73b0\u7a0b\u5e8f\uff0c\u65e0\u9700\u590d\u6742\u7684 IDE \u5b89\u88c5\u3001\u7f16\u8bd1\u6216\u6253\u5305\u8fc7\u7a0b\u3002

      "},{"location":"getting-started/#qpython_2","title":"QPython \u7248\u672c","text":"

      \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

      • QPython \u2013 \u7531 QPython \u56e2\u961f\u7ef4\u62a4\u7684\u4e3b\u8981\u7248\u672c\uff0c\u5177\u5907 AI \u529f\u80fd\uff0c\u53ef\u5728 Google Play \u7b49\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d
      • QPython+ \u2013 \u7531\u5f00\u6e90\u8d21\u732e\u8005\u63a8\u51fa\u7684\u793e\u533a\u7248\uff0c\u63d0\u4f9b\u5404\u79cd\u65b0\u7279\u6027
      • QPython Plus \u2013 \u6269\u5c55\u6743\u9650\u7248\u672c\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff09
      "},{"location":"getting-started/#_1","title":"\u4e3b\u8981\u7279\u6027","text":"
      • \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668 - \u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51
      • QSL4A \u96c6\u6210 - \u4f7f\u7528 Python \u63a7\u5236 Android \u786c\u4ef6\u548c API
      • GenAI \u80fd\u529b\u96c6\u6210 - \u652f\u6301\u672c\u5730\u8fd0\u884c\u7684 LLM\u3001OpenAI \u7b49\u5404\u79cd LLM \u5e93\uff0c\u4ee5\u53ca\u53ef\u5728 QPython \u4e0a\u8fdb\u884c Vibe Coding \u5f00\u53d1\u7684 AIPyApp
      • \u6269\u5c55\u5305\u5b89\u88c5 - \u652f\u6301\u901a\u8fc7 QPYPI \u548c pip \u5b89\u88c5\u6269\u5c55\u5305
      • \u5185\u7f6e\u7f16\u8f91\u5668 - \u8bed\u6cd5\u9ad8\u4eae\u548c\u4ee3\u7801\u7f16\u8f91
      • \u591a\u79cd\u8fd0\u884c\u6a21\u5f0f - \u9664\u63a7\u5236\u53f0\u7a0b\u5e8f\u5916\uff0c\u8fd8\u652f\u6301 Android \u539f\u751f UI\uff08\u901a\u8fc7 QSL4A \u63a5\u53e3\uff09\u4ee5\u53ca Pygame / Turtle / Tkinter \u7b49\u8fd0\u884c\u65b9\u5f0f
      "},{"location":"getting-started/#1","title":"1. \u4eea\u8868\u76d8","text":"

      \u5b89\u88c5 QPython \u540e\uff0c\u70b9\u51fb\u5176\u56fe\u6807\u542f\u52a8\u3002\u60a8\u5c06\u770b\u5230\u5e26\u6709 QPython \u6807\u5fd7\u548c\u4ee5\u4e0b\u529f\u80fd\u7684\u4e3b\u4eea\u8868\u76d8\uff1a

      "},{"location":"getting-started/#_2","title":"\u4eea\u8868\u76d8\u529f\u80fd","text":"

      QPython \u4eea\u8868\u76d8\u63d0\u4f9b\u5bf9\u6240\u6709\u4e3b\u8981\u529f\u80fd\u7684\u5feb\u901f\u8bbf\u95ee\uff1a

      • \u7ec8\u7aef \u2014 \u8bbf\u95ee Python \u63a7\u5236\u53f0\u548c shell \u4ee5\u76f4\u63a5\u6267\u884c\u547d\u4ee4
      • Notebook \u2014 \u7528\u4e8e\u6570\u636e\u5206\u6790\u548c\u5b9e\u9a8c\u7684\u4ea4\u4e92\u5f0f Jupyter \u98ce\u683c\u7b14\u8bb0\u672c
      • \u7f16\u8f91\u5668 \u2014 \u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668\uff0c\u5177\u6709\u8bed\u6cd5\u9ad8\u4eae\u529f\u80fd\uff0c\u7528\u4e8e\u7f16\u5199 Python \u811a\u672c
      • \u8d44\u6e90\u7ba1\u7406\u5668 \u2014 \u6d4f\u89c8\u548c\u7ba1\u7406\u60a8\u7684\u6587\u4ef6\u3001\u811a\u672c\u548c\u9879\u76ee
      • QPYPI \u2014 \u5b89\u88c5 Python \u5305\u548c\u6269\u5c55\u3002\u8be6\u89c1 QPYPI \u6307\u5357
      • \u8bbe\u7f6e \u2014 \u914d\u7f6e QPython \u9996\u9009\u9879\u548c\u8fd0\u884c\u9009\u9879
      • \u793e\u533a \u2014 \u8bbf\u95ee QPython \u793e\u533a\u8d44\u6e90\u3001\u8bba\u575b\u548c\u5e2e\u52a9
      • \u8bfe\u7a0b \u2014 \u8bbf\u95ee Python \u7f16\u7a0b\u7684\u5b66\u4e60\u6750\u6599\u548c\u6559\u7a0b

      \u70b9\u51fb\u4efb\u4f55\u56fe\u6807\u4ee5\u8bbf\u95ee\u76f8\u5e94\u7684\u529f\u80fd\u3002

      "},{"location":"getting-started/#2","title":"2. \u7ec8\u7aef\u548c\u7f16\u8f91\u5668","text":""},{"location":"getting-started/#_3","title":"\u7ec8\u7aef","text":"

      \u7ec8\u7aef\u63d0\u4f9b Python \u63a7\u5236\u53f0\uff0c\u652f\u6301\uff1a - \u63a2\u7d22\u5bf9\u8c61\u5c5e\u6027 - \u6d4b\u8bd5\u8bed\u6cd5\u548c\u60f3\u6cd5 - \u76f4\u63a5\u6267\u884c\u547d\u4ee4

      \u4f7f\u7528\u52a0\u53f7\u6309\u94ae\uff081\uff09\u6253\u5f00\u65b0\u7ec8\u7aef\u6807\u7b7e\u9875\uff0c\u901a\u8fc7\u4e0b\u62c9\u83dc\u5355\uff082\uff09\u5207\u6362\uff0c\u5e76\u4f7f\u7528\u5173\u95ed\u6309\u94ae\uff083\uff09\u5173\u95ed\u3002

      "},{"location":"getting-started/#_4","title":"\u7f16\u8f91\u5668","text":"

      \u7f16\u8f91\u5668\u5e95\u90e8\u529f\u80fd\u680f\u5305\u542b\u4ee5\u4e0b\u5de5\u5177\uff08\u4ece\u5de6\u5230\u53f3\uff09\uff1a

      • \u5207\u6362\u5feb\u6377\u8f93\u5165\uff08\u5305\u542b def / if / else / elif / class \u7b49\u5173\u952e\u8bcd\uff09
      • \u9501\u5b9a\uff08\u9632\u6b62\u8bef\u89e6\uff09
      • \u8df3\u8f6c
      • \u4fdd\u5b58
      • \u8fd0\u884c
      • \u641c\u7d22
      • \u64a4\u9500
      • \u91cd\u505a
      • \u53e6\u5b58
      • \u6700\u8fd1\u6587\u4ef6
      • \u4ee3\u7801\u7247\u6bb5

      \u91cd\u8981\u63d0\u793a\uff1a \u4fdd\u5b58\u65f6\u8bf7\u624b\u52a8\u6dfb\u52a0 .py \u6269\u5c55\u540d\uff0c\u56e0\u4e3a\u7f16\u8f91\u5668\u4e0d\u4f1a\u81ea\u52a8\u6dfb\u52a0\u3002

      "},{"location":"getting-started/#3","title":"3. \u8d44\u6e90\u7ba1\u7406\u5668\uff08\u6587\u4ef6\u7ba1\u7406\uff09","text":"

      \u901a\u8fc7 \u8d44\u6e90\u7ba1\u7406\u5668 \u8bbf\u95ee\u811a\u672c\u548c\u9879\u76ee\uff0c\u652f\u6301\u6d4f\u89c8\u3001\u7ec4\u7ec7\u548c\u7ba1\u7406\u6240\u6709 Python \u6587\u4ef6\u3002

      "},{"location":"getting-started/#_5","title":"\u811a\u672c","text":"

      \u811a\u672c\u662f\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/scripts3/ \u4e2d\u7684\u5355\u4e2a Python \u6587\u4ef6\uff08\u9488\u5bf9 Python 3\uff09\u3002

      \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u811a\u672c - \u6253\u5f00 \u2014 \u4f7f\u7528\u5185\u7f6e\u7f16\u8f91\u5668\u7f16\u8f91 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u811a\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u811a\u672c

      "},{"location":"getting-started/#_6","title":"\u9879\u76ee","text":"

      \u9879\u76ee\u662f\u5305\u542b main.py \u4f5c\u4e3a\u5165\u53e3\u70b9\u7684\u76ee\u5f55\u3002\u60a8\u53ef\u4ee5\u5728\u540c\u4e00\u76ee\u5f55\u4e2d\u5305\u542b\u5176\u4ed6\u4f9d\u8d56\u9879\u548c\u8d44\u6e90\u3002\u5c06\u9879\u76ee\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/projects3/ \u4e2d\u3002

      "},{"location":"getting-started/#_7","title":"\u7b14\u8bb0\u672c","text":"

      Jupyter \u98ce\u683c\u7684\u7b14\u8bb0\u672c\u4e5f\u901a\u8fc7\u8d44\u6e90\u7ba1\u7406\u5668\u8fdb\u884c\u7ba1\u7406\uff0c\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/notebooks/ \u4e2d\u3002

      \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u7b14\u8bb0\u672c - \u6253\u5f00 \u2014 \u63a2\u7d22\u7b14\u8bb0\u672c\u5185\u5bb9 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u7b14\u8bb0\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u7b14\u8bb0\u672c

      "},{"location":"getting-started/#4","title":"4. \u5e93","text":"

      \u901a\u8fc7\u5b89\u88c5\u7b2c\u4e09\u65b9\u5e93\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

      "},{"location":"getting-started/#_8","title":"\u5305\u5b89\u88c5\u65b9\u6cd5","text":"

      QPYPI\uff08\u63a8\u8350\uff09

      \u4ece QPYPI \u5b89\u88c5\u9884\u7f16\u8bd1\u7684\u5e93\uff0c\u5305\u62ec numpy\u3001scipy \u7b49\u79d1\u5b66\u5305\u3002

      \u8be6\u89c1 QPYPI \u6307\u5357\u3002

      PIP \u5ba2\u6237\u7aef

      \u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216 QPYPI \u754c\u9762\u5b89\u88c5\u7eaf Python \u5e93\uff1a

      pip install requests\n

      \u9884\u7f16\u8bd1\u5305

      \u5bf9\u4e8e\u5177\u6709 C/C++/Rust \u4f9d\u8d56\u7684\u5305\uff0c\u4f7f\u7528 QPython \u7684\u9884\u7f16\u8bd1\u5305\uff1a

      pip install numpy-qpython\npip install scipy-aipy\n

      \u8be6\u89c1 QPYPI \u6307\u5357 \u83b7\u53d6\u53ef\u7528\u5305\u7684\u5b8c\u6574\u5217\u8868\u3002

      \u624b\u52a8\u5b89\u88c5

      \u60a8\u4e5f\u53ef\u4ee5\u5c06\u5e93\u590d\u5236\u5230 /storage/emulated/0/Android/data/org.qpython.qpy/files/lib/python3.12/site-packages/\u3002

      "},{"location":"getting-started/#5","title":"5. \u8fd0\u884c\u6a21\u5f0f","text":"

      QPython \u652f\u6301\u591a\u79cd\u8fd0\u884c\u6a21\u5f0f\u4ee5\u6ee1\u8db3\u4e0d\u540c\u7684\u7528\u4f8b\uff1a

      "},{"location":"getting-started/#_9","title":"\u63a7\u5236\u53f0\u6a21\u5f0f","text":"

      \u5e38\u89c4 Python \u811a\u672c\u7684\u9ed8\u8ba4\u6a21\u5f0f\u3002

      "},{"location":"getting-started/#qsl4a","title":"QSL4A \u6a21\u5f0f","text":"

      \u901a\u8fc7 QSL4A \u5e93\u8c03\u7528 Android API \u7684\u811a\u672c\u3002

      import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello Android!')\n

      \u8be6\u89c1 QSL4A \u6587\u6863 \u83b7\u53d6\u5b8c\u6574\u7684 API \u53c2\u8003\u3002

      "},{"location":"getting-started/#webapp","title":"WebApp \u6a21\u5f0f","text":"

      \u4f7f\u7528\u540e\u7aef\u670d\u52a1\u5668\u521b\u5efa\u57fa\u4e8e Web \u7684\u5e94\u7528\u7a0b\u5e8f\u3002\u9700\u5728\u811a\u672c\u5f00\u5934\u6dfb\u52a0\u4ee5\u4e0b\u4e24\u884c headers\uff1a

      #qpy:webapp:<\u9879\u76ee\u540d>\n#qpy://localhost:<web\u670d\u52a1\u4fa6\u542c\u7684\u7aef\u53e3>/<\u9ed8\u8ba4\u4e3b\u8def\u5f84>\n

      \u4f8b\u5982\uff1a

      #qpy:webapp:Hello QPython\n#qpy://localhost:8080/hello\n\nfrom bottle import route, run, Bottle\n\napp = Bottle()\n\n@route('/hello')\ndef hello():\n    return '<h1>Hello from QPython!</h1>'\n\nrun(app, host='localhost', port=8080)\n
      "},{"location":"getting-started/#q","title":"Q \u6a21\u5f0f\uff08\u65e0\u63a7\u5236\u53f0\u6a21\u5f0f\uff09","text":"

      \u9759\u9ed8\u6a21\u5f0f\u8fd0\u884c\u811a\u672c\uff0c\u4e0d\u663e\u793a\u63a7\u5236\u53f0\u3002\u9700\u5728\u811a\u672c\u5f00\u5934\u6dfb\u52a0 header\uff1a

      #qpy:quiet\n\nimport time\n\nwhile True:\n    # \u60a8\u7684\u540e\u53f0\u4efb\u52a1\n    time.sleep(60)\n
      \u5982\u679c\u9700\u8981\u8fd0\u884c\u5e26 GUI \u7684 QSL4A \u7a0b\u5e8f\u4e14\u4e0d\u5e0c\u671b\u663e\u793a\u63a7\u5236\u53f0\u4fe1\u606f\uff0c\u63a8\u8350\u4f7f\u7528\u6b64\u6a21\u5f0f\u3002

      "},{"location":"getting-started/#6","title":"6. \u793e\u533a\u4e0e\u652f\u6301","text":"

      \u8bbf\u95ee QPython.org \u83b7\u53d6\u6587\u6863\u3001\u7528\u6237\u793e\u533a\u53ca\u5e2e\u52a9\u95ee\u7b54\u3002

      \u793e\u533a\u94fe\u63a5\uff1a - Facebook \u7fa4\u7ec4 - GitHub - \u95ee\u9898\u53cd\u9988

      \u4e0b\u4e00\u6b65\uff1a - \u5c1d\u8bd5 Hello World \u6559\u7a0b - \u63a2\u7d22 QSL4A API \u4ee5\u96c6\u6210 Android - \u4e86\u89e3 QPython \u7248\u672c

      "},{"location":"getting-started/#_10","title":"\u89c6\u9891\u4ecb\u7ecd","text":""},{"location":"getting-started/#_11","title":"\u4e0b\u4e00\u6b65","text":"

      \u5982\u679c\u60a8\u5df2\u7ecf\u521d\u6b65\u4e86\u89e3\u4e86 QPython \u7684\u529f\u80fd\uff0c\u6b22\u8fce\u5f00\u59cb\u4f53\u9a8c\u7f16\u7a0b\u7684\u4e50\u8da3\uff01\u8bd5\u8bd5 Hello World \u6559\u7a0b \u8fc8\u51fa\u60a8\u7684\u7b2c\u4e00\u6b65\u3002

      "},{"location":"qpypi-guide/","title":"QPYPI","text":"

      \u60a8\u53ef\u4ee5\u901a\u8fc7\u5b89\u88c5\u5305\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

      "},{"location":"qpypi-guide/#_1","title":"\u5305\u5b89\u88c5\u652f\u6301","text":""},{"location":"qpypi-guide/#python","title":"\u7eaf Python \u5305","text":"

      QPython \u652f\u6301\u4f7f\u7528\u7eaf Python \u5f00\u53d1\u7684 Python \u5305\u3002\u60a8\u53ef\u4ee5\u76f4\u63a5\u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216\u4eea\u8868\u76d8\u4e0a\u7684 QPYPI \u4f7f\u7528 pip install \u5b89\u88c5\u8fd9\u4e9b\u5305\u3002

      "},{"location":"qpypi-guide/#_2","title":"\u9884\u7f16\u8bd1\u5305","text":"

      \u5982\u679c\u67d0\u4e9b\u5305\uff08\u6216\u5b83\u4eec\u7684\u4f9d\u8d56\uff09\u662f\u7528 Rust/C/C++ \u5f00\u53d1\u7684\uff0cQPython \u65e0\u6cd5\u76f4\u63a5\u652f\u6301\u5b83\u4eec\uff0c\u56e0\u4e3a QPython \u4e0a\u6ca1\u6709\u7f16\u8bd1\u5668\u5de5\u5177\u94fe\u652f\u6301\u3002\u4f46\u662f\uff0cQPython \u56e2\u961f\u5df2\u7ecf\u9884\u7f16\u8bd1\u4e86\u4e00\u4e9b\u5e38\u7528\u5305\uff0c\u5e76\u5728 QPython \u7684 QPYPI/Extensions \u4e2d\u53d1\u5e03\uff0c\u4f9b\u7528\u6237\u8f7b\u677e\u5b89\u88c5\u3002

      "},{"location":"qpypi-guide/#_3","title":"\u5b89\u88c5\u9884\u7f16\u8bd1\u5305","text":"

      \u60a8\u53ef\u4ee5\u901a\u8fc7\u4ee5\u4e0b\u65b9\u5f0f\u5b89\u88c5\u9884\u7f16\u8bd1\u5305\uff1a

      1. \u901a\u8fc7 QPython \u5e94\u7528\uff1a\u76f4\u63a5\u4ece QPython \u5e94\u7528\u5185\u7684 QPYPI \u6216 Extensions \u5b89\u88c5
      2. \u901a\u8fc7 PyPI\uff1a\u8bbf\u95ee https://pypi.org/user/qpythonx/ \u67e5\u770b\u53ef\u7528\u7684\u5305
      3. \u901a\u8fc7 pip \u547d\u4ee4\uff1a
      4. pip install xxx-qpython - \u5e26 -qpython \u540e\u7f00\u7684\u5305
      5. pip install xxx-aipy - \u5e26 -aipy \u540e\u7f00\u7684\u5305\uff08\u901a\u5e38\u662f AI/ML \u76f8\u5173\u7684\u5305\uff09

      \u6ce8\u610f\uff1a\u6211\u4eec\u901a\u5e38\u6839\u636e\u5305\u7684\u9884\u671f\u7528\u9014\u6dfb\u52a0\u8fd9\u4e9b\u540e\u7f00\u4e4b\u4e00\u3002

      "},{"location":"qpypi-guide/#_4","title":"\u8bf7\u6c42\u65b0\u5305","text":"

      \u5982\u679c\u60a8\u9700\u8981\u5f53\u524d\u4e0d\u652f\u6301\u7684\u5305\uff1a

      • \u5728 qpython.org \u9879\u76ee \u4e2d\u63d0\u51fa\u95ee\u9898
      • QPython \u56e2\u961f\u5c06\u8003\u8651\u9884\u7f16\u8bd1\u5e76\u5c06\u5176\u6dfb\u52a0\u5230\u4ed3\u5e93\u4e2d

      \u83b7\u53d6\u66f4\u591a\u5e2e\u52a9\u548c\u53c2\u4e0e\u793e\u533a\u7684\u65b9\u5f0f\uff0c\u8bf7\u53c2\u9605 \u793e\u533a\u4e0e\u53cd\u9988 \u90e8\u5206\u3002

      \u6ce8\u610f\uff1a\u7531\u4e8e\u4e0d\u540c\u7684\u8ba1\u7b97\u673a\u67b6\u6784\uff0c\u6211\u4eec\u65e0\u6cd5\u4fdd\u8bc1 QPYPI \u5305\u542b PyPI \u4e0a\u7684\u6240\u6709\u5305\u3002

      "},{"location":"qpython-x/","title":"QPython \u7248\u672c","text":"

      QPython \u662f Android \u7684 Python \u5f15\u64ce\u3002\u5b83\u5305\u542b\u4ee4\u4eba\u60ca\u53f9\u7684\u529f\u80fd\uff0c\u5982 Python \u89e3\u91ca\u5668\u3001\u8fd0\u884c\u73af\u5883\u3001\u7f16\u8f91\u5668\u3001QPYI \u548c\u96c6\u6210\u7684 SL4A\u3002\u5b83\u8ba9\u60a8\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 Android \u4e0a\u4f7f\u7528 Python\u3002\u800c\u4e14\u5b83\u662f\u514d\u8d39\u7684\u3002

      QPython \u5df2\u7ecf\u5728\u5168\u7403\u62e5\u6709\u6570\u767e\u4e07\u7528\u6237\uff0c\u4e5f\u662f\u4e00\u4e2a\u5f00\u6e90\u9879\u76ee\u3002

      \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

      "},{"location":"qpython-x/#qpython_1","title":"QPython","text":"

      \u6807\u51c6\u7248\uff1a\u9488\u5bf9 AI \u6027\u80fd\u548c\u901a\u7528\u5e94\u7528\u5546\u5e97\u517c\u5bb9\u6027\u4f18\u5316

      \u4e3b\u8981\u7248\u672c\uff0c\u53ef\u5728 Google Play \u548c\u5176\u4ed6\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002\u6b64\u7248\u672c\u4e13\u6ce8\u4e8e AI \u529f\u80fd\uff0c\u4f7f AI \u65f6\u4ee3\u7528\u6237\u66f4\u5bb9\u6613\u5b66\u4e60\u548c\u4f7f\u7528 Python\u3002

      \u4e3b\u8981\u7279\u6027\uff1a - AI \u9a71\u52a8\u7684\u7f16\u7801\u8f85\u52a9\u548c\u5b66\u4e60\u5de5\u5177 - \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668\uff1a\u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51 - \u652f\u6301\u591a\u79cd\u9879\u76ee\u7c7b\u578b\uff1a\u63a7\u5236\u53f0\u3001SL4A\u3001WebApp - \u65b9\u4fbf\u7684\u4e8c\u7ef4\u7801\u8bfb\u53d6\u5668\uff0c\u7528\u4e8e\u5c06\u4ee3\u7801\u4f20\u8f93\u5230\u624b\u673a - QPYPI \u548c\u81ea\u5b9a\u4e49\u4ed3\u5e93\uff0c\u7528\u4e8e\u9884\u7f16\u8bd1 wheel \u5305 -\u6613\u4e8e\u4f7f\u7528\u7684\u8bed\u6cd5\u9ad8\u4eae\u7f16\u8f91\u5668 - \u5b8c\u5584\u7684\u6587\u6863\u548c\u793e\u533a\u652f\u6301

      \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

      \u4e0b\u8f7d\uff1a \u53ef\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

      "},{"location":"qpython-x/#qpython_2","title":"QPython+","text":"

      \u793e\u533a\u7248\uff1a\u516c\u5f00\u652f\u6301\u5404\u79cd\u793e\u533a\u9a71\u52a8\u7684\u529f\u80fd\uff1b\u53ef\u5728\u90e8\u5206\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

      \u793e\u533a\u5f00\u6e90\u7248\u672c\uff08\u6b63\u5728\u89c4\u5212\u548c\u51c6\u5907\u4e2d\uff09\u3002\u6b64\u7248\u672c\u4e13\u4e3a\u60f3\u8981\u53c2\u4e0e QPython \u9879\u76ee\u5f00\u53d1\u7684\u8d21\u732e\u8005\u800c\u8bbe\u8ba1\uff0c\u652f\u6301\u9488\u5bf9\u4e0d\u540c\u5236\u9020\u5546\u7684\u5b9a\u5236\u3002

      \u4e3b\u8981\u7279\u6027\uff1a - \u793e\u533a\u9a71\u52a8\u5f00\u53d1 - \u652f\u6301\u4f9b\u5e94\u5546\u5b9a\u5236 - \u66f4\u7075\u6d3b\u7684\u914d\u7f6e\u9009\u9879 - \u5f00\u653e\u4f9b\u8d21\u732e\u8005\u52a0\u5165\u5f00\u53d1

      \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

      \u4e0b\u8f7d\uff1a \u5c06\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

      \u6ce8\u610f\uff1a \u6b64\u7248\u672c\u76ee\u524d\u6b63\u5728\u89c4\u5212\u51c6\u5907\u4e2d\u3002\u8bf7\u5173\u6ce8\u66f4\u65b0\uff01

      "},{"location":"qpython-x/#qpython-plus","title":"QPython Plus","text":"

      QPython+ \u5b8c\u5168\u8bbf\u95ee\u7248\uff1a\u6388\u4e88\u8c03\u7528\u6240\u6709 Android \u63a5\u53e3\u7684\u5b8c\u6574\u6743\u9650\u3002\u4e0b\u8f7d\u94fe\u63a5\u4ec5\u901a\u8fc7\u5b98\u65b9\u4e91\u76d8\u63d0\u4f9b\u3002

      \u5177\u6709\u6269\u5c55\u6743\u9650\u7684\u7279\u6b8a\u7248\u672c\uff0c\u63d0\u4f9b\u5bf9\u8bbe\u5907\u7684\u6700\u5927\u63a7\u5236\u3002\u7531\u4e8e\u5176\u654f\u611f\u7684\u6743\u9650\u8981\u6c42\uff0c\u6b64\u7248\u672c\u4e0d\u4f1a\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u53d1\u5e03\u3002

      \u4e3b\u8981\u7279\u6027\uff1a - \u5b8c\u6574\u7684 SL4A API \u8bbf\u95ee\uff0c\u5305\u62ec\u654f\u611f\u529f\u80fd - SMS/\u901a\u8bdd\u63a7\u5236 API - \u9ad8\u7ea7\u7cfb\u7edf\u96c6\u6210 - \u6700\u5927\u7684\u8bbe\u5907\u63a7\u5236\u80fd\u529b

      \u6743\u9650\uff1a \u9700\u8981\u5e7f\u6cdb\u7684\u6743\u9650\uff0c\u5305\u62ec\uff1a - \u84dd\u7259 - \u4f4d\u7f6e\uff08GPS\uff09 - \u8bfb\u53d6/\u53d1\u9001\u77ed\u4fe1 - \u6253\u7535\u8bdd - \u76f8\u673a\u548c\u9ea6\u514b\u98ce - \u7cfb\u7edf\u8bbe\u7f6e - \u4ee5\u53ca\u5176\u4ed6\u654f\u611f\u6743\u9650

      \u4e0b\u8f7d\uff1a \u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\u3002\u4ec5\u901a\u8fc7\u7279\u6b8a\u6e20\u9053\u5206\u53d1\u3002

      \u91cd\u8981\u63d0\u793a\uff1a QPython \u4e0d\u4f1a\u5728\u540e\u53f0\u672a\u7ecf\u60a8\u77e5\u6089\u4f7f\u7528\u8fd9\u4e9b\u6743\u9650\u3002\u5982\u679c\u4f7f\u7528 SL4A API \u65f6\u51fa\u73b0\u5f02\u5e38\uff0c\u8bf7\u68c0\u67e5\u7cfb\u7edf\u8bbe\u7f6e\u4e2d\u662f\u5426\u5df2\u542f\u7528\u76f8\u5173\u6743\u9650\u3002

      "},{"location":"tutorial-hello-world/","title":"\u7f16\u5199\"Hello World\"","text":""},{"location":"tutorial-hello-world/#hello-world_1","title":"Hello world","text":"

      \u597d\u7684\uff0c\u5728\u60a8\u5bf9 QPython \u6709\u4e86\u4e00\u5b9a\u7684\u4e86\u89e3\u4e4b\u540e\uff0c\u8ba9\u6211\u4eec\u5728 QPython \u4e2d\u521b\u5efa\u6211\u4eec\u7684\u7b2c\u4e00\u4e2a\u7a0b\u5e8f\u3002\u663e\u7136\uff0c\u5b83\u5c06\u662f helloworld.py\u3002;)

      \u542f\u52a8 QPython\uff0c\u6253\u5f00\u7f16\u8f91\u5668\u5e76\u8f93\u5165\u4ee5\u4e0b\u4ee3\u7801\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello, QPYTHON!')\n

      \u6beb\u65e0\u7591\u95ee\uff0c\u5b83\u4e0e\u5176\u4ed6\u4efb\u4f55 hello-world \u7a0b\u5e8f\u5e76\u65e0\u4e0d\u540c\u3002\u6267\u884c\u65f6\uff0c\u5b83\u53ea\u662f\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u5f39\u51fa\u6d88\u606f\uff08\u89c1\u9876\u90e8\u622a\u56fe\uff09\u3002\u65e0\u8bba\u5982\u4f55\uff0c\u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684 QPython \u7a0b\u5e8f\u793a\u4f8b\u3002

      "},{"location":"tutorial-hello-world/#_1","title":"\u4ee3\u7801\u7406\u89e3","text":"

      \u5b83\u4ee5 import androidhelper \u5f00\u5934\u2014\u2014\u8fd9\u662f QPython \u4e2d\u6700\u6709\u7528\u7684\u6a21\u5757\uff0c\u5b83\u5c01\u88c5\u4e86 Python \u4e2d\u53ef\u7528\u7684\u51e0\u4e4e\u6240\u6709\u4e0e Android \u7684\u63a5\u53e3\u3002\u4efb\u4f55\u5728 QPython \u4e2d\u5f00\u53d1\u7684\u811a\u672c\u90fd\u4ee5\u8fd9\u4e2a\u8bed\u53e5\u5f00\u5934\uff08\u81f3\u5c11\u5982\u679c\u5b83\u58f0\u79f0\u8981\u4e0e\u7528\u6237\u901a\u4fe1\u7684\u8bdd\uff09\u3002\u5728\u6b64\u5904\u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u5e93 \u548c import \u8bed\u53e5 \u7684\u5185\u5bb9\u3002

      \u63a5\u4e0b\u6765\u6211\u4eec\u521b\u5efa\u4e00\u4e2a droid \u5bf9\u8c61\uff08\u5b9e\u9645\u4e0a\u662f\u4e00\u4e2a\u7c7b\uff09\uff0c\u5b83\u5bf9\u4e8e\u8c03\u7528 RPC \u51fd\u6570\u4ee5\u4e0e Android \u901a\u4fe1\u662f\u5fc5\u8981\u7684\u3002

      \u6211\u4eec\u4ee3\u7801\u7684\u6700\u540e\u4e00\u884c\u8c03\u7528\u4e86\u8fd9\u6837\u7684\u51fd\u6570\uff0cdroid.makeToast()\uff0c\u5b83\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u4e00\u4e2a\u5c0f\u7684\u5f39\u51fa\u6d88\u606f\uff08\"toast\"\uff09\u3002

      \u597d\u7684\uff0c\u8ba9\u6211\u4eec\u6dfb\u52a0\u4e00\u4e9b\u66f4\u591a\u7684\u529f\u80fd\u3002\u8ba9\u5b83\u8be2\u95ee\u7528\u6237\u540d\u5e76\u5411\u7528\u6237\u6253\u62db\u547c\u3002

      "},{"location":"tutorial-hello-world/#_2","title":"\u66f4\u591a\u793a\u4f8b","text":"

      \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 dialogGetInput \u8c03\u7528\u663e\u793a\u4e00\u4e2a\u5e26\u6709\u6807\u9898\u3001\u63d0\u793a\u3001\u7f16\u8f91\u5b57\u6bb5\u548c \u786e\u5b9a \u548c \u53d6\u6d88 \u6309\u94ae\u7684\u7b80\u5355\u5bf9\u8bdd\u6846\u3002\u7528\u4ee5\u4e0b\u4ee3\u7801\u66ff\u6362\u60a8\u7684\u6700\u540e\u4e00\u884c\u4ee3\u7801\u5e76\u5c06\u5176\u4fdd\u5b58\u4e3a hello1.py\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\n

      \u597d\u7684\uff0c\u6211\u8ba4\u4e3a\u5b83\u5e94\u8be5\u8fd4\u56de\u4efb\u4f55\u54cd\u5e94\uff0c\u4efb\u4f55\u7528\u6237\u53cd\u5e94\u3002\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u6211\u5199 respond = ...\u3002\u4f46\u8fd9\u4e2a\u8c03\u7528\u5b9e\u9645\u4e0a\u8fd4\u56de\u4ec0\u4e48\uff1f\u8ba9\u6211\u4eec\u68c0\u67e5\u4e00\u4e0b\u3002\u53ea\u9700\u5728\u6700\u540e\u4e00\u884c\u540e\u6dfb\u52a0 print \u8bed\u53e5\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\n

      \u7136\u540e\u4fdd\u5b58\u5e76\u8fd0\u884c\u5b83...

      \u54ce\u5440\uff01\u6ca1\u6709\u6253\u5370\uff1f\u522b\u62c5\u5fc3\u3002\u53ea\u9700\u62c9\u4e0b\u901a\u77e5\u680f\uff0c\u60a8\u5c31\u4f1a\u770b\u5230\"QPython Program Output: hello1.py\"\u2014\u2014\u70b9\u51fb\u5b83\uff01

      \u5982\u60a8\u6240\u89c1\uff0cdroid.dialogGetInput() \u8fd4\u56de\u4e00\u4e2a\u5305\u542b\u4e09\u4e2a\u5b57\u6bb5\u7684 JSON \u5bf9\u8c61\u3002\u6211\u4eec\u53ea\u9700\u8981\u4e00\u4e2a\u2014\u2014result\uff0c\u5176\u4e2d\u5305\u542b\u7528\u6237\u5b9e\u9645\u8f93\u5165\u7684\u5185\u5bb9\u3002

      \u8ba9\u6211\u4eec\u6dfb\u52a0\u811a\u672c\u7684\u53cd\u5e94\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nmessage = f'Hello, {respond.result}!'\ndroid.makeToast(message)\n

      \u6700\u540e\u4e24\u884c\uff081\uff09\u683c\u5f0f\u5316\u6d88\u606f\uff0c\uff082\uff09\u4ee5 toast \u5f62\u5f0f\u5411\u7528\u6237\u663e\u793a\u6d88\u606f\u3002\u5982\u679c\u60a8\u4ecd\u7136\u4e0d\u77e5\u9053 f-string \u662f\u4ec0\u4e48\u610f\u601d\uff0c\u8bf7\u53c2\u9605 Python \u6587\u6863\u3002

      \u54c7\uff01\u5b83\u5de5\u4f5c\u4e86\uff01;)

      \u73b0\u5728\u6211\u8981\u5728\u90a3\u91cc\u6dfb\u52a0\u4e00\u4e9b\u903b\u8f91\u3002\u60f3\u4e00\u60f3\uff1a\u5982\u679c\u7528\u6237\u70b9\u51fb \u53d6\u6d88 \u6309\u94ae\uff0c\u6216\u8005\u70b9\u51fb \u786e\u5b9a \u4f46\u5c06\u8f93\u5165\u5b57\u6bb5\u7559\u7a7a\uff0c\u4f1a\u53d1\u751f\u4ec0\u4e48\uff1f

      \u60a8\u53ef\u4ee5\u73a9\u8fd9\u4e2a\u7a0b\u5e8f\uff0c\u68c0\u67e5 respond \u53d8\u91cf\u5728\u6bcf\u79cd\u60c5\u51b5\u4e0b\u5305\u542b\u4ec0\u4e48\u3002

      \u9996\u5148\uff0c\u6211\u60f3\u5c06\u7528\u6237\u8f93\u5165\u7684\u6587\u672c\u653e\u5165\u4e00\u4e2a\u5355\u72ec\u7684\u53d8\u91cf\u4e2d\uff1aname = respond.result\u3002\u7136\u540e\u6211\u68c0\u67e5\u5b83\uff0c\u5982\u679c\u5b83\u5305\u542b\u4efb\u4f55\u771f\u5b9e\u6587\u672c\uff0c\u5b83\u5c06\u88ab\u89c6\u4e3a\u540d\u79f0\u5e76\u7528\u4e8e\u95ee\u5019\u3002\u5426\u5219\uff0c\u5c06\u663e\u793a\u53e6\u4e00\u6761\u6d88\u606f\u3002\u5c06\u7b2c\u4e94\u884c message = f'Hello, {respond.result}!' \u66ff\u6362\u4e3a\u4ee5\u4e0b\u4ee3\u7801\uff1a

      name = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\n

      \u4f7f\u7528\u5de5\u5177\u680f\u4e0a\u7684 < \u548c > \u6309\u94ae\u6765\u7f29\u8fdb/\u53d6\u6d88\u7f29\u8fdb if \u8bed\u53e5\u4e2d\u7684\u884c\uff08\u6216\u8005\u53ea\u9700\u4f7f\u7528\u7a7a\u683c/\u9000\u683c\u952e\uff09\u3002\u60a8\u53ef\u4ee5\u5728 \u6b64\u5904 \u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u7f29\u8fdb\u7684\u5185\u5bb9\uff1bif \u8bed\u53e5\u5728 \u6b64\u5904 \u63cf\u8ff0\u3002

      \u9996\u5148\uff0c\u6211\u4eec\u5c06\u7528\u6237\u8f93\u5165\u653e\u5165 name \u53d8\u91cf\u3002\u7136\u540e\u6211\u4eec\u68c0\u67e5 name \u662f\u5426\u5305\u542b\u4efb\u4f55\u5185\u5bb9\uff1f\u5982\u679c\u7528\u6237\u7559\u7a7a\u884c\u5e76\u70b9\u51fb \u786e\u5b9a\uff0c\u8fd4\u56de\u503c\u662f\u7a7a\u5b57\u7b26\u4e32 ''\u3002\u5982\u679c\u6309\u4e0b\u4e86 \u53d6\u6d88 \u6309\u94ae\uff0c\u8fd4\u56de\u503c\u662f None\u3002\u5728 if \u8bed\u53e5\u4e2d\uff0c\u4e24\u8005\u90fd\u88ab\u89c6\u4e3a\u5047\u3002\u56e0\u6b64\uff0c\u53ea\u6709\u5f53 name \u5305\u542b\u4efb\u4f55\u6709\u610f\u4e49\u7684\u5185\u5bb9\u65f6\uff0cthen \u8bed\u53e5\u624d\u4f1a\u6267\u884c\uff0c\u5e76\u663e\u793a\u95ee\u5019\u8bed\"Hello, ...!\"\u3002\u5982\u679c\u8f93\u5165\u4e3a\u7a7a\uff0c\u7528\u6237\u5c06\u770b\u5230\"Hey! And you're not very polite, %Username%!\"\u6d88\u606f\u3002

      \u597d\u7684\uff0c\u8fd9\u662f\u6574\u4e2a\u7a0b\u5e8f\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nname = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\ndroid.makeToast(message)\n
      "},{"location":"tutorial-hello-world/#_3","title":"\u8fd0\u884c\u6548\u679c","text":""},{"location":"tutorial-hello-world/#_4","title":"\u4e0b\u4e00\u6b65","text":"

      \u5bf9\u4e8e Python \u65b0\u7528\u6237\uff0c\u63a8\u8350\u5b66\u4e60 Python \u8bed\u6cd5\u5b9e\u8df5 \u8bfe\u7a0b\u6765\u8fdb\u4e00\u6b65\u5b66\u4e60 Python\uff0c\u6216\u8005\u5728 QPython \u7cbe\u9009\u8bfe\u7a0b \u4e2d\u5bfb\u627e\u60f3\u8981\u5b66\u4e60\u7684\u5185\u5bb9\u3002

      "},{"location":"whats-new/","title":"\u66f4\u65b0\u65e5\u5fd7","text":""},{"location":"whats-new/#v392-v393","title":"v3.9.2 / v3.9.3","text":"
      • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
      • \u7f16\u8f91\u5668\u91cd\u5927\u66f4\u65b0\uff0c\u5e26\u6765\u66f4\u6d41\u7545\u7684\u7f16\u8f91\u4f53\u9a8c
      • \u5176\u4ed6\u5404\u79cd\u5c0f\u6539\u8fdb
      "},{"location":"whats-new/#v391","title":"v3.9.1","text":"
      • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
      • \u6269\u5c55\u5305\u73b0\u5728\u652f\u6301 MCP
      • \u9519\u8bef\u4fee\u590d
      "},{"location":"whats-new/#v390","title":"v3.9.0","text":"
      • SDK \u5347\u7ea7\uff0c\u6574\u5408\u6700\u65b0\u7684 Android \u529f\u80fd
      • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
      • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
      • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
      "},{"location":"whats-new/#v3811","title":"v3.8.11","text":"
      • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
      • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
      • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
      "},{"location":"whats-new/#v3810","title":"v3.8.10","text":"
      • \u5185\u7f6e Ollama \u5347\u7ea7\uff1a\u73b0\u5728\u60a8\u53ef\u4ee5\u5728 QPython \u4e2d\u8f7b\u677e\u672c\u5730\u8fd0\u884c Qwen3 / Gemma3 \u6a21\u578b\uff01
      • \u6dfb\u52a0\u4e86\u5f3a\u5927\u7684 MCP \u5e93\uff1a\u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 mcp \u5e93\uff0c\u8ba9\u60a8\u968f\u65f6\u968f\u5730\u643a\u5e26\u5f3a\u5927\u7684 MCP \u529f\u80fd\uff01
      "},{"location":"whats-new/#v389","title":"v3.8.9","text":"

      \u91cd\u5927\u66f4\u65b0\uff01AI \u7f16\u7a0b\u5b8c\u5168\u96c6\u6210\u5230 QPython\uff0c\u8ba9\u60a8\u7684\u7f16\u7a0b\u66f4\u8f7b\u677e\uff01

      • \u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u652f\u6301\uff1a\u65b0\u652f\u6301 AIPyApp\uff0c\u5728 QPython \u4e2d\u5b9e\u73b0\u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u3002\u76ee\u524d\u5904\u4e8e\u6d4b\u8bd5\u9636\u6bb5 - \u52a0\u5165\u6211\u4eec\u7684\u793e\u533a\u83b7\u53d6\u4f7f\u7528\u8bf4\u660e
      • \u65b0 QSL4A \u529f\u80fd\uff1a\u6dfb\u52a0 notebookOpen \u51fd\u6570\uff0c\u652f\u6301\u81ea\u7136\u8bed\u8a00\u63a7\u5236\u6253\u5f00 Notebook \u6587\u4ef6
      • \u5185\u7f6e\u7f16\u8f91\u5668\u5347\u7ea7\uff1a\u589e\u5f3a\u7f16\u8f91\u5668\u529f\u80fd\uff0c\u652f\u6301\u6253\u5f00\u548c\u6d4f\u89c8\u5404\u79cd\u6587\u672c\u6587\u4ef6
      • \u4fbf\u6377\u7684\u6587\u4ef6\u7ba1\u7406\uff1a\u5728\u6587\u4ef6\u7ba1\u7406\u5668\u4e2d\u6dfb\u52a0\u5185\u90e8\u5b58\u50a8\u5165\u53e3\uff0c\u5feb\u901f\u8bbf\u95ee\u60a8\u7684\u6587\u4ef6
      "},{"location":"whats-new/#v388","title":"v3.8.8","text":"
      • \u6587\u4ef6\u8bbf\u95ee\u6743\u9650\u63a7\u5236\u7684\u91cd\u8981\u6539\u8fdb\uff0c\u5141\u8bb8\u7528\u6237\u7075\u6d3b\u5730\u901a\u8fc7 QPython \u7f16\u7a0b\u542f\u7528\u6216\u7981\u7528\u5916\u90e8\u5b58\u50a8\u6587\u4ef6\u7684\u8bbf\u95ee
      • SDK \u5347\u7ea7\uff0c\u589e\u5f3a\u4e86\u5bf9\u65b0\u7248 Android \u7684\u652f\u6301\u548c\u517c\u5bb9\u6027
      • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Anthropic \u548c Google GenAI \u5e93
      "},{"location":"whats-new/#v387","title":"v3.8.7","text":"
      • \u5728\u73b0\u6709 Tkinter \u652f\u6301\u57fa\u7840\u4e0a\uff0c\u5728 Extensions -> Tools \u4e2d\u6dfb\u52a0\u4e86\u4f7f\u7528 Turtle \u7ed8\u5236\u54c6\u5566A\u68a6\u7684\u793a\u4f8b\u4ee3\u7801
      • \u4f18\u5316\u4e86\u624b\u673a\u6743\u9650\u83b7\u53d6\u6d41\u7a0b\uff0c\u63d0\u5347\u7528\u6237\u4f53\u9a8c\u548c\u64cd\u4f5c\u4fbf\u5229\u6027
      • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Google Gen AI \u5e93\uff0c\u65b9\u4fbf\u8bbf\u95ee Gemini Developer API \u548c Vertex AI
      "},{"location":"whats-new/#v386","title":"v3.8.6","text":"
      • Tkinter \u652f\u6301\uff1a\u73b0\u5728\u652f\u6301 Tkinter \u5e93\uff0c\u53ef\u901a\u8fc7 XServer \u8bbf\u95ee\u3002\u8bf7\u8bbf\u95ee www.qpython.org \u7684\u4e91\u76d8\"Extra\"\u94fe\u63a5\u4e0b\u8f7d\u6240\u9700\u6587\u4ef6
      • \u5b58\u50a8\u6743\u9650\u66f4\u65b0\uff1a\u4e3a\u6539\u5584\u7528\u6237\u4f53\u9a8c\uff0c\u6211\u4eec\u6dfb\u52a0\u4e86\u8bfb\u53d6\u624b\u673a\u5b58\u50a8\u7684\u6743\u9650\uff0c\u7528\u4e8e\u8bbf\u95ee\u5b58\u50a8\u5728\u5176\u4ed6\u76ee\u5f55\u4e2d\u7684 Python \u7a0b\u5e8f

      \u6b64\u66f4\u65b0\u540e\uff0cQPython \u548c QPythonPlus\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff0c\u4e13\u4e3a\u9700\u8981\u66f4\u591a\u654f\u611f\u6743\u9650\u7684\u9ad8\u7ea7\u7528\u6237\u8bbe\u8ba1\uff09\u5c06\u4fdd\u6301\u540c\u6b65\u7684\u7248\u672c\u53f7\u3002

      "},{"location":"whats-new/#v352-2025225","title":"v3.5.2 (2025/2/25)","text":"

      \u4e0e\u5f00\u6e90 LLM \u90e8\u7f72\u5de5\u5177 Ollama \u4ee5\u53ca DeepSeek \u5f00\u53d1\u7684 DeepSeek \u5b9e\u73b0\u65e0\u7f1d\u96c6\u6210\uff01

      \u529f\u80fd\uff1a - \u96f6\u95e8\u69db\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5404\u79cd\u5927\u578b\u8bed\u8a00\u6a21\u578b - \u5feb\u901f\u90e8\u7f72 DeepSeek \u7b49\u5c16\u7aef AI \u6a21\u578b - \u4eab\u53d7\u7b80\u7ea6\u7684 API \u8c03\u7528\u4f53\u9a8c - \u6784\u5efa\u5b8c\u5168\u79bb\u7ebf\u7684\u667a\u80fd\u7f16\u7a0b\u73af\u5883

      \u80fd\u529b\uff1a - \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u52a0\u8f7d/\u7ba1\u7406 LLM \u6a21\u578b - \u57fa\u4e8e\u672c\u5730\u8ba1\u7b97\u7684\u5b9e\u65f6\u4f4e\u5ef6\u8fdf\u54cd\u5e94

      "},{"location":"whats-new/#v350","title":"v3.5.0","text":"
      • Python \u5347\u7ea7\u5230 3.12.8
      • \u6539\u8fdb\u4eea\u8868\u76d8\uff0c\u529f\u80fd\u66f4\u6e05\u6670\u3001\u66f4\u4eba\u6027\u5316
      • \u6dfb\u52a0\u4e86\u4f17\u591a\u7b2c\u4e09\u65b9\u5305\uff1aPyTorch / Twisted / Scrapy / FastAPI ...
      "},{"location":"whats-new/#v338","title":"v3.3.8","text":"
      • \u4fee\u590d\u4e86 NumPy \u517c\u5bb9\u6027\u95ee\u9898
      "},{"location":"whats-new/#v335","title":"v3.3.5","text":"
      • \u5347\u7ea7 Python \u5185\u6838\u5230 3.11.9
      • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u4e0d\u663e\u793a\u6a21\u5757\u5b89\u88c5\u72b6\u6001\u7684 bug
      • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u5220\u9664\u6a21\u5757\u5931\u8d25\u7684 bug
      • \u4fee\u590d\u4e86\u5176\u4ed6 bug
      "},{"location":"whats-new/#v334","title":"v3.3.4","text":"
      • \u6dfb\u52a0\u4e86 OpenAI/Langchain/APIGPTCloud AI \u5305
      • \u79fb\u9664\u4e0d\u5fc5\u8981\u7684\u6587\u4ef6\u4ee5\u51cf\u5c11\u5927\u5c0f
      "},{"location":"whats-new/#v325","title":"v3.2.5","text":"
      • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570
      • \u5176\u4ed6\u9519\u8bef\u4fee\u590d
      "},{"location":"whats-new/#v323","title":"v3.2.3","text":"
      • \u66f4\u65b0 Python \u7248\u672c\u5230 3.11.0
      • \u66f4\u65b0 IPython \u7248\u672c\u5230 8.6.0
      • \u66f4\u65b0 pip \u7248\u672c\u5230 22.3.1
      • \u66f4\u65b0\u79d1\u5b66\u8ba1\u7b97\u5305\uff0c\u81ea\u52a8\u8f6f\u94fe\u63a5
      • \u51cf\u5c11\u7a7a\u95f4\u4f7f\u7528
      • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570 + \u5176\u4ed6\u9519\u8bef\u4fee\u590d
      "},{"location":"whats-new/#v318","title":"v3.1.8","text":"
      • \u5728\u7ec8\u7aef\u4e2d\u6dfb\u52a0\u4e86\u64cd\u4f5c\u70ed\u952e
      • \u4fee\u590d\u4e86\u7f16\u8f91\u5668\u5728\u65cb\u8f6c\u65f6\u4e22\u5931\u5185\u5bb9\u7684\u95ee\u9898
      • \u4fee\u590d\u4e86\u5176\u4ed6 bug

      \u5728 Google Play \u4e0b\u8f7d

      "},{"location":"qsl4a/","title":"QSL4A\uff08Android \u811a\u672c\u5c42\uff09API \u6587\u6863","text":"

      QSL4A \u662f QPython \u7684 Android \u811a\u672c\u5c42\uff0c\u5141\u8bb8\u60a8\u4f7f\u7528 Python \u63a7\u5236 Android \u8bbe\u5907\u529f\u80fd\u3002

      "},{"location":"qsl4a/#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a toast \u6d88\u606f\ndroid.makeToast('Hello QPython!')\n\n# \u9707\u52a8\u8bbe\u5907\ndroid.vibrate(500)\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\uff08\u5148\u5f00\u59cb\u76d1\u63a7\uff09\nimport time\ndroid.batteryStartMonitoring()\ntime.sleep(0.5)  # \u7b49\u5f85\u6570\u636e\nbattery = droid.readBatteryData().result\nprint(f\"\u7535\u6c60\uff1a{battery['level']}%\")\n
      "},{"location":"qsl4a/#_2","title":"\u6587\u6863\u7ed3\u6784","text":""},{"location":"qsl4a/#_3","title":"\u6838\u5fc3\u6a21\u5757","text":"
      • Android \u57fa\u7840 - \u6838\u5fc3\u8fde\u63a5\u548c RPC
      • Intent \u7cfb\u7edf - Android Intent \u64cd\u4f5c
      • \u4e8b\u4ef6\u7cfb\u7edf - \u4e8b\u4ef6\u5904\u7406\u548c\u5e7f\u64ad
      "},{"location":"qsl4a/#ui","title":"UI \u7ec4\u4ef6","text":"
      • \u5bf9\u8bdd\u6846 - \u8b66\u62a5\u3001\u8f93\u5165\u3001\u9009\u62e9\u5bf9\u8bdd\u6846
      • \u5168\u5c4f UI - \u81ea\u5b9a\u4e49\u5e03\u5c40 UI
      • \u60ac\u6d6e\u7a97 - \u60ac\u6d6e\u7a97\u53e3
      • \u8f85\u52a9\u529f\u80fd - \u5c4f\u5e55\u81ea\u52a8\u5316
      "},{"location":"qsl4a/#_4","title":"\u7cfb\u7edf","text":"
      • \u7535\u6c60 - \u7535\u6c60\u76d1\u63a7
      • \u4f20\u611f\u5668 - \u8bbe\u5907\u4f20\u611f\u5668
      • \u5e94\u7528 - \u5e94\u7528\u7ba1\u7406
      • \u7cfb\u7edf\u4fe1\u606f - \u8bbe\u5907\u4fe1\u606f
      • \u8bbe\u7f6e - \u7cfb\u7edf\u8bbe\u7f6e
      • \u5524\u9192\u9501 - \u5524\u9192\u9501\u63a7\u5236
      • QPython \u63a5\u53e3 - \u811a\u672c\u6267\u884c
      • Activity \u7ed3\u679c - Activity \u7ed3\u679c\u5904\u7406
      "},{"location":"qsl4a/#_5","title":"\u786c\u4ef6","text":"
      • \u84dd\u7259 - \u84dd\u7259\u64cd\u4f5c
      • \u76f8\u673a - \u62cd\u7167\u548c\u5f55\u50cf
      • \u97f3\u9891/\u5f55\u97f3\u5668 - \u5f55\u97f3
      • \u7f51\u7edc\u6444\u50cf\u5934 - MJPEG \u6d41
      • USB \u4e32\u53e3 - USB \u4e3b\u673a\u4e32\u53e3
      "},{"location":"qsl4a/#_6","title":"\u8fde\u63a5","text":"
      • WiFi - WiFi \u64cd\u4f5c
      • \u4f4d\u7f6e - GPS \u548c\u4f4d\u7f6e
      • \u77ed\u4fe1 - \u77ed\u4fe1\u64cd\u4f5c
      • \u7535\u8bdd - \u6253\u7535\u8bdd\u548c\u6765\u7535\u4fe1\u606f
      • \u8054\u7cfb\u4eba - \u8054\u7cfb\u4eba\u7ba1\u7406
      • \u4fe1\u53f7\u5f3a\u5ea6 - \u4fe1\u53f7\u76d1\u63a7
      • FTP \u670d\u52a1\u5668 - \u5185\u7f6e FTP \u670d\u52a1\u5668
      "},{"location":"qsl4a/#_7","title":"\u5b58\u50a8","text":"
      • DocumentFile - \u6587\u4ef6\u64cd\u4f5c
      • \u526a\u8d34\u677f - \u526a\u8d34\u677f\u64cd\u4f5c
      • \u504f\u597d\u8bbe\u7f6e - \u5171\u4eab\u504f\u597d\u8bbe\u7f6e
      "},{"location":"qsl4a/#_8","title":"\u5a92\u4f53","text":"
      • \u5a92\u4f53\u64ad\u653e\u5668 - \u97f3\u9891/\u89c6\u9891\u64ad\u653e
      • \u56fe\u50cf\u5904\u7406 - \u56fe\u50cf\u64cd\u4f5c
      "},{"location":"qsl4a/#_9","title":"\u7279\u6b8a\u529f\u80fd","text":"
      • \u52a0\u5bc6 - \u52a0\u5bc6/\u89e3\u5bc6
      • PGPT AI - AI \u8bed\u97f3\u670d\u52a1
      "},{"location":"qsl4a/#_10","title":"\u7ed3\u679c\u5bf9\u8c61","text":"

      \u5927\u591a\u6570 QSL4A \u65b9\u6cd5\u8fd4\u56de\u4e00\u4e2a\u5e26\u6709\u4ee5\u4e0b\u5c5e\u6027\u7684 Result \u547d\u540d\u5143\u7ec4\uff1a - id - \u8bf7\u6c42 ID - result - \u5b9e\u9645\u7ed3\u679c\u6570\u636e - error - \u5982\u679c\u5931\u8d25\u5219\u4e3a\u9519\u8bef\u6d88\u606f

      result = droid.getClipboard()\nif result.error is None:\n    print(result.result)\nelse:\n    print(f\"\u9519\u8bef\uff1a{result.error}\")\n
      "},{"location":"qsl4a/connectivity/contacts/","title":"\u8054\u7cfb\u4eba API","text":"

      \u8bbf\u95ee\u548c\u7ba1\u7406\u8bbe\u5907\u8054\u7cfb\u4eba\u3002

      "},{"location":"qsl4a/connectivity/contacts/#_1","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":""},{"location":"qsl4a/connectivity/contacts/#pickcontact","title":"pickContact()","text":"

      \u663e\u793a\u8054\u7cfb\u4eba\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

      pickContact()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u8054\u7cfb\u4eba URI \u7684 Intent

      "},{"location":"qsl4a/connectivity/contacts/#pickphone","title":"pickPhone()","text":"

      \u663e\u793a\u7535\u8bdd\u53f7\u7801\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

      pickPhone()\n

      \u8fd4\u56de\uff1a \u9009\u4e2d\u7684\u7535\u8bdd\u53f7\u7801\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/contacts/#_2","title":"\u8054\u7cfb\u4eba\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#contactsget","title":"contactsGet()","text":"

      \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\u3002

      contactsGet(attributes=None)\n

      \u53c2\u6570\uff1a - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

      \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba JSONObject \u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetbyid","title":"contactsGetById()","text":"

      \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\u3002

      contactsGetById(id, attributes=None)\n

      \u53c2\u6570\uff1a - id (int): \u8054\u7cfb\u4eba ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

      \u8fd4\u56de\uff1a JSONObject \u8054\u7cfb\u4eba\u6570\u636e

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetcount","title":"contactsGetCount()","text":"

      \u83b7\u53d6\u8054\u7cfb\u4eba\u603b\u6570\u3002

      contactsGetCount()\n

      \u8fd4\u56de\uff1a \u6574\u6570\u8ba1\u6570

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetids","title":"contactsGetIds()","text":"

      \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba ID\u3002

      contactsGetIds()\n

      \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba ID \u6574\u6570\u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetattributes","title":"contactsGetAttributes()","text":"

      \u83b7\u53d6\u6240\u6709\u53ef\u80fd\u7684\u8054\u7cfb\u4eba\u5c5e\u6027\u3002

      contactsGetAttributes()\n

      \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#_3","title":"\u5185\u5bb9\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#querycontent","title":"queryContent()","text":"

      \u4f7f\u7528\u81ea\u5b9a\u4e49\u53c2\u6570\u67e5\u8be2\u5185\u5bb9\u89e3\u6790\u5668\u3002

      queryContent(uri, attributes=None, selection=None, selectionArgs=None, order=None)\n

      \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u5c5e\u6027 - selection (str, optional): WHERE \u5b50\u53e5 - selectionArgs (list, optional): \u9009\u62e9\u53c2\u6570 - order (str, optional): ORDER BY \u5b50\u53e5

      \u8fd4\u56de\uff1a JSONObject \u7ed3\u679c\u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#queryattributes","title":"queryAttributes()","text":"

      \u83b7\u53d6\u5185\u5bb9 URI \u7684\u5c5e\u6027\u3002

      queryAttributes(uri)\n

      \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI

      \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u7684 JSONArray

      "},{"location":"qsl4a/connectivity/contacts/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u9009\u62e9\u8054\u7cfb\u4eba\ncontact_uri = droid.pickContact().result\nprint(f\"Selected contact: {contact_uri}\")\n\n# \u9009\u62e9\u7535\u8bdd\u53f7\u7801\nphone = droid.pickPhone().result\nprint(f\"Selected phone: {phone}\")\n\n# \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\ncontacts = droid.contactsGet().result\nprint(f\"Total contacts: {len(contacts)}\")\n\n# \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\ncontact = droid.contactsGetById(1).result\nprint(f\"Contact: {contact}\")\n\n# \u83b7\u53d6\u8054\u7cfb\u4eba\u5c5e\u6027\nattrs = droid.contactsGetAttributes().result\nprint(f\"Available attributes: {attrs}\")\n
      "},{"location":"qsl4a/connectivity/ftp/","title":"FTP \u670d\u52a1\u5668 API","text":"

      \u5728\u8bbe\u5907\u4e0a\u542f\u52a8\u548c\u7ba1\u7406\u5185\u7f6e FTP \u670d\u52a1\u5668\u3002

      "},{"location":"qsl4a/connectivity/ftp/#ftp","title":"FTP \u670d\u52a1\u5668\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/ftp/#ftpstart","title":"ftpStart()","text":"

      \u542f\u52a8 FTP \u670d\u52a1\u5668\u3002

      ftpStart()\n

      \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4 [ip, port]

      "},{"location":"qsl4a/connectivity/ftp/#ftpstop","title":"ftpStop()","text":"

      \u505c\u6b62 FTP \u670d\u52a1\u5668\u3002

      ftpStop()\n
      "},{"location":"qsl4a/connectivity/ftp/#ftpisrunning","title":"ftpIsRunning()","text":"

      \u68c0\u67e5 FTP \u670d\u52a1\u5668\u662f\u5426\u6b63\u5728\u8fd0\u884c\u3002

      ftpIsRunning()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u8fd0\u884c\u5219\u4e3a True

      "},{"location":"qsl4a/connectivity/ftp/#ftpget","title":"ftpGet()","text":"

      \u83b7\u53d6 FTP \u670d\u52a1\u5668 IP \u5730\u5740\u3002

      ftpGet()\n

      \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4

      "},{"location":"qsl4a/connectivity/ftp/#ftpset","title":"ftpSet()","text":"

      \u914d\u7f6e FTP \u670d\u52a1\u5668\u8bbe\u7f6e\u3002

      ftpSet(port=None, rootDir=None, username=None, password=None)\n

      \u53c2\u6570\uff1a - port (int, optional): \u670d\u52a1\u5668\u7aef\u53e3 - rootDir (str, optional): \u8981\u670d\u52a1\u7684\u57fa\u7840\u76ee\u5f55 - username (str, optional): \u767b\u5f55\u7528\u6237\u540d - password (str, optional): \u767b\u5f55\u5bc6\u7801

      \u8fd4\u56de\uff1a \u5305\u542b\u5f53\u524d\u8bbe\u7f6e\u7684 JSONObject

      "},{"location":"qsl4a/connectivity/ftp/#ftpstatus","title":"ftpStatus()","text":"

      \u83b7\u53d6 FTP \u670d\u52a1\u5668\u72b6\u6001\u3002

      ftpStatus()\n

      \u8fd4\u56de\uff1a \u72b6\u6001\u63cf\u8ff0\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/ftp/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u914d\u7f6e FTP \u670d\u52a1\u5668\ndroid.ftpSet(\n    port=2121,\n    rootDir=\"/sdcard\",\n    username=\"admin\",\n    password=\"secret\"\n)\n\n# \u542f\u52a8 FTP \u670d\u52a1\u5668\ninfo = droid.ftpStart().result\nprint(f\"FTP running at {info[0]}:{info[1]}\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.ftpIsRunning().result:\n    print(\"FTP server is running\")\n\n# \u83b7\u53d6\u670d\u52a1\u5668\u4fe1\u606f\nserver_info = droid.ftpGet().result\nprint(f\"Server: {server_info}\")\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.ftpStop()\n

      \u6ce8\u610f\uff1a \u4f7f\u7528\u63d0\u4f9b\u7684\u51ed\u636e\u901a\u8fc7\u4efb\u4f55 FTP \u5ba2\u6237\u7aef\u8fde\u63a5\u5230 FTP \u670d\u52a1\u5668\u3002

      "},{"location":"qsl4a/connectivity/location/","title":"\u4f4d\u7f6e API","text":"

      \u8bbf\u95ee GPS \u548c\u7f51\u7edc\u4f4d\u7f6e\u670d\u52a1\u3002

      "},{"location":"qsl4a/connectivity/location/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/location/#startlocating","title":"startLocating()","text":"

      \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\u3002

      startLocating(minUpdateTime=60000, minUpdateDistance=30, updateGnssStatus=False)\n

      \u53c2\u6570\uff1a - minUpdateTime (int): \u66f4\u65b0\u4e4b\u95f4\u7684\u6700\u5c0f\u65f6\u95f4\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a60000\uff09 - minUpdateDistance (float): \u66f4\u65b0\u7684\u6700\u5c0f\u8ddd\u79bb\uff08\u7c73\uff09\uff08\u9ed8\u8ba4\uff1a30\uff09 - updateGnssStatus (bool): \u542f\u7528 GNSS \u72b6\u6001\u66f4\u65b0\uff08\u9ed8\u8ba4\uff1aFalse\uff09

      "},{"location":"qsl4a/connectivity/location/#stoplocating","title":"stopLocating()","text":"

      \u505c\u6b62\u4f4d\u7f6e\u66f4\u65b0\u3002

      stopLocating()\n
      "},{"location":"qsl4a/connectivity/location/#readlocation","title":"readLocation()","text":"

      \u83b7\u53d6\u6700\u540e\u5df2\u77e5\u4f4d\u7f6e\u3002

      readLocation()\n

      \u8fd4\u56de\uff1a \u4f4d\u7f6e\u6570\u636e\u5b57\u5178

      "},{"location":"qsl4a/connectivity/location/#getlastknownlocation","title":"getLastKnownLocation()","text":"

      \u83b7\u53d6\u7f13\u5b58\u7684\u4f4d\u7f6e\u3002

      getLastKnownLocation()\n

      \u8fd4\u56de\uff1a \u6765\u81ea\u6240\u6709\u63d0\u4f9b\u5546\u7684\u4f4d\u7f6e

      "},{"location":"qsl4a/connectivity/location/#geocode","title":"geocode()","text":"

      \u5c06\u5730\u5740\u8f6c\u6362\u4e3a\u5750\u6807\u3002

      geocode(address, maxResults=1)\n
      "},{"location":"qsl4a/connectivity/location/#_2","title":"\u4f4d\u7f6e\u63d0\u4f9b\u5546\u65b9\u6cd5)","text":""},{"location":"qsl4a/connectivity/location/#locationproviders","title":"locationProviders()","text":"

      \u83b7\u53d6\u624b\u673a\u4e0a\u53ef\u7528\u7684\u4f4d\u7f6e\u63d0\u4f9b\u5546\u3002

      locationProviders()\n

      \u8fd4\u56de\uff1a \u53ef\u7528\u63d0\u4f9b\u5546\u540d\u79f0\u5217\u8868\uff08\u4f8b\u5982 ['gps', 'network']\uff09

      "},{"location":"qsl4a/connectivity/location/#locationproviderenabled","title":"locationProviderEnabled()","text":"

      \u68c0\u67e5\u7279\u5b9a\u4f4d\u7f6e\u63d0\u4f9b\u5546\u662f\u5426\u5df2\u542f\u7528\u3002

      locationProviderEnabled(provider)\n

      \u53c2\u6570\uff1a - provider (str): \u63d0\u4f9b\u5546\u540d\u79f0\uff08\u4f8b\u5982 'gps', 'network'\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/connectivity/location/#readgnssstatus","title":"readGnssStatus()","text":"

      \u8bfb\u53d6\u5168\u7403\u5bfc\u822a\u536b\u661f\u7cfb\u7edf\u72b6\u6001\uff08\u9700\u8981 Android 8+\uff09\u3002

      readGnssStatus()\n

      \u8fd4\u56de\uff1a \u5305\u542b GNSS \u536b\u661f\u4fe1\u606f\u7684 JSONArray

      "},{"location":"qsl4a/connectivity/location/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\ndroid.startLocating(minUpdateTime=5000, minUpdateDistance=1, updateGnssStatus=False)\n\n# \u7b49\u5f85\u5b9a\u4f4d\ntime.sleep(10)\n\n# \u83b7\u53d6\u4f4d\u7f6e\nloc = droid.readLocation().result\nif loc:\n    lat = loc['latitude']\n    lon = loc['longitude']\n    print(f\"Location: {lat}, {lon}\")\n\ndroid.stopLocating()\n
      "},{"location":"qsl4a/connectivity/phone/","title":"\u7535\u8bdd API","text":"

      \u63a7\u5236\u7535\u8bdd\u901a\u8bdd\u548c\u83b7\u53d6\u7535\u8bdd\u4fe1\u606f\u3002

      "},{"location":"qsl4a/connectivity/phone/#_1","title":"\u7535\u8bdd\u72b6\u6001\u8ddf\u8e2a","text":""},{"location":"qsl4a/connectivity/phone/#starttrackingphonestate","title":"startTrackingPhoneState()","text":"

      \u5f00\u59cb\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u53d8\u5316\u3002\u751f\u6210 'phone' \u4e8b\u4ef6\u3002

      startTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/phone/#readphonestate","title":"readPhoneState()","text":"

      \u8bfb\u53d6\u5f53\u524d\u7535\u8bdd\u72b6\u6001\u3002

      readPhoneState()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7535\u8bdd\u72b6\u6001\u548c\u6765\u7535\u53f7\u7801\u7684 Bundle

      "},{"location":"qsl4a/connectivity/phone/#stoptrackingphonestate","title":"stopTrackingPhoneState()","text":"

      \u505c\u6b62\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u3002

      stopTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/phone/#_2","title":"\u62e8\u6253\u7535\u8bdd","text":""},{"location":"qsl4a/connectivity/phone/#phonecall","title":"phoneCall()","text":"

      \u901a\u8fc7 URI \u547c\u53eb\u8054\u7cfb\u4eba/\u7535\u8bdd\u53f7\u7801\u3002

      phoneCall(uri)\n

      \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

      "},{"location":"qsl4a/connectivity/phone/#phonecallnumber","title":"phoneCallNumber()","text":"

      \u76f4\u63a5\u62e8\u6253\u7535\u8bdd\u53f7\u7801\u3002

      phoneCallNumber(phone_number)\n

      \u53c2\u6570\uff1a - phone_number (str): \u8981\u62e8\u6253\u7684\u7535\u8bdd\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#phonedial","title":"phoneDial()","text":"

      \u62e8\u6253\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

      phoneDial(uri)\n

      \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

      "},{"location":"qsl4a/connectivity/phone/#phonedialnumber","title":"phoneDialNumber()","text":"

      \u62e8\u6253\u7535\u8bdd\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

      phoneDialNumber(phone_number)\n

      \u53c2\u6570\uff1a - phone_number (str): \u7535\u8bdd\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#_3","title":"\u57fa\u7ad9\u4f4d\u7f6e","text":""},{"location":"qsl4a/connectivity/phone/#getcelllocation","title":"getCellLocation()","text":"

      \u83b7\u53d6\u5f53\u524d\u57fa\u7ad9\u4f4d\u7f6e\u3002

      getCellLocation()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u57fa\u7ad9\u4f4d\u7f6e\u6570\u636e\u7684 JSONObject

      "},{"location":"qsl4a/connectivity/phone/#getallcellslocation","title":"getAllCellsLocation()","text":"

      \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u4f4d\u7f6e\uff08\u9002\u7528\u4e8e\u53cc\u5361\u8bbe\u5907\uff09\u3002

      getAllCellsLocation()\n

      \u8fd4\u56de\uff1a \u57fa\u7ad9\u4f4d\u7f6e\u7684 JSONArray

      "},{"location":"qsl4a/connectivity/phone/#_4","title":"\u7f51\u7edc\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getnetworkoperator","title":"getNetworkOperator()","text":"

      \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

      getNetworkOperator()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getnetworkoperatorname","title":"getNetworkOperatorName()","text":"

      \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684\u540d\u79f0\u3002

      getNetworkOperatorName()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getnetworktype","title":"getNetworkType()","text":"

      \u83b7\u53d6\u5f53\u524d\u7f51\u7edc\u7c7b\u578b\u3002

      getNetworkType()\n

      \u8fd4\u56de\uff1a \u63cf\u8ff0\u65e0\u7ebf\u7535\u6280\u672f\u7684\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'LTE', 'UMTS', 'GSM'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getphonetype","title":"getPhoneType()","text":"

      \u83b7\u53d6\u7535\u8bdd\u7c7b\u578b\u3002

      getPhoneType()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'GSM', 'CDMA', 'SIP'\uff09

      "},{"location":"qsl4a/connectivity/phone/#sim","title":"SIM \u5361\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getsimcountryiso","title":"getSimCountryIso()","text":"

      \u83b7\u53d6 SIM \u5361\u7684 ISO \u56fd\u5bb6\u4ee3\u7801\u3002

      getSimCountryIso()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'us'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getsimoperator","title":"getSimOperator()","text":"

      \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

      getSimOperator()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getsimoperatorname","title":"getSimOperatorName()","text":"

      \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u540d\u79f0\u3002

      getSimOperatorName()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getsimserialnumber","title":"getSimSerialNumber()","text":"

      \u83b7\u53d6 SIM \u5e8f\u5217\u53f7\u3002

      getSimSerialNumber()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32 SIM \u5e8f\u5217\u53f7

      "},{"location":"qsl4a/connectivity/phone/#getsimstate","title":"getSimState()","text":"

      \u83b7\u53d6 SIM \u5361\u72b6\u6001\u3002

      getSimState()\n

      \u8fd4\u56de\uff1a \u63cf\u8ff0 SIM \u72b6\u6001\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/phone/#getsubscriberid","title":"getSubscriberId()","text":"

      \u83b7\u53d6\u8ba2\u9605\u8005 ID\u3002

      getSubscriberId()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8ba2\u9605\u8005 ID

      "},{"location":"qsl4a/connectivity/phone/#_5","title":"\u8bed\u97f3\u90ae\u4ef6","text":""},{"location":"qsl4a/connectivity/phone/#getvoicemailalphatag","title":"getVoiceMailAlphaTag()","text":"

      \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u5b57\u6bcd\u6807\u7b7e\u3002

      getVoiceMailAlphaTag()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u6807\u7b7e

      "},{"location":"qsl4a/connectivity/phone/#getvoicemailnumber","title":"getVoiceMailNumber()","text":"

      \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801\u3002

      getVoiceMailNumber()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getdeviceid","title":"getDeviceId()","text":"

      \u83b7\u53d6\u8bbe\u5907 ID\uff08GSM \u7684 IMEI\uff09\u3002\u5df2\u5e9f\u5f03\u3002

      getDeviceId()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

      "},{"location":"qsl4a/connectivity/phone/#getdevicesoftwareversion","title":"getDeviceSoftwareVersion()","text":"

      \u83b7\u53d6\u8bbe\u5907\u8f6f\u4ef6\u7248\u672c\u3002

      getDeviceSoftwareVersion()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8f6f\u4ef6\u7248\u672c

      "},{"location":"qsl4a/connectivity/phone/#getline1number","title":"getLine1Number()","text":"

      \u83b7\u53d6\u7ebf\u8def 1 \u7535\u8bdd\u53f7\u7801\u3002

      getLine1Number()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u7535\u8bdd\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#checknetworkroaming","title":"checkNetworkRoaming()","text":"

      \u68c0\u67e5\u662f\u5426\u8fde\u63a5\u5230\u6f2b\u6e38\u7f51\u7edc\u3002

      checkNetworkRoaming()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u6f2b\u6e38\u5219\u4e3a True

      "},{"location":"qsl4a/connectivity/phone/#_7","title":"\u57fa\u7ad9\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getallcellinfo","title":"getAllCellInfo()","text":"

      \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u7684\u4fe1\u606f\u3002

      getAllCellInfo()\n

      \u8fd4\u56de\uff1a \u57fa\u7ad9\u4fe1\u606f\u5217\u8868

      "},{"location":"qsl4a/connectivity/phone/#setdataenabled","title":"setDataEnabled()","text":"

      \u542f\u7528\u6216\u7981\u7528\u79fb\u52a8\u6570\u636e\u3002

      setDataEnabled(enabled)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528

      "},{"location":"qsl4a/connectivity/phone/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7f51\u7edc\u4fe1\u606f\noperator = droid.getNetworkOperatorName().result\nprint(f\"Operator: {operator}\")\n\nnetwork_type = droid.getNetworkType().result\nprint(f\"Network: {network_type}\")\n\n# \u83b7\u53d6 SIM \u4fe1\u606f\nsim_state = droid.getSimState().result\nprint(f\"SIM: {sim_state}\")\n\n# \u83b7\u53d6\u7535\u8bdd\u53f7\u7801\nline1 = droid.getLine1Number().result\nprint(f\"Phone: {line1}\")\n\n# \u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\ndroid.startTrackingPhoneState()\nprint(\"Tracking phone state...\")\ndroid.stopTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/signalstrength/","title":"\u4fe1\u53f7\u5f3a\u5ea6 API","text":"

      \u76d1\u63a7\u8702\u7a9d\u548c\u65e0\u7ebf\u4fe1\u53f7\u5f3a\u5ea6\u3002

      "},{"location":"qsl4a/connectivity/signalstrength/#_1","title":"\u4fe1\u53f7\u5f3a\u5ea6\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/signalstrength/#starttrackingsignalstrengths","title":"startTrackingSignalStrengths()","text":"

      \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316\u3002\u751f\u6210 'signal_strengths' \u4e8b\u4ef6\u3002

      startTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/signalstrength/#stoptrackingsignalstrengths","title":"stopTrackingSignalStrengths()","text":"

      \u505c\u6b62\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u3002

      stopTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/signalstrength/#readsignalstrengths","title":"readSignalStrengths()","text":"

      \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\u3002

      readSignalStrengths()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u4fe1\u53f7\u5f3a\u5ea6\u6570\u636e\u7684 Bundle

      "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthlevel","title":"getTelephoneSignalStrengthLevel()","text":"

      \u83b7\u53d6\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u7b49\u7ea7\uff080-4\uff09\u3002

      getTelephoneSignalStrengthLevel()\n

      \u8fd4\u56de\uff1a \u6574\u6570\u7b49\u7ea7\uff080=\u65e0\uff0c1=\u5dee\uff0c2=\u4e00\u822c\uff0c3=\u597d\uff0c4=\u4f18\u79c0\uff09

      "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthdetail","title":"getTelephoneSignalStrengthDetail()","text":"

      \u83b7\u53d6\u8be6\u7ec6\u7684\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u4fe1\u606f\u3002

      getTelephoneSignalStrengthDetail()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u8be6\u7ec6\u4fe1\u53f7\u4fe1\u606f\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/signalstrength/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\ndroid.startTrackingSignalStrengths()\n\n# \u7b49\u5f85\u4fe1\u53f7\u66f4\u65b0\ntime.sleep(5)\n\n# \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\nsignal = droid.readSignalStrengths().result\nprint(f\"Signal: {signal}\")\n\n# \u76f4\u63a5\u83b7\u53d6\u7b49\u7ea7\nlevel = droid.getTelephoneSignalStrengthLevel().result\nprint(f\"Signal level: {level}/4\")\n\ndroid.stopTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/sms/","title":"SMS API","text":"

      \u53d1\u9001\u548c\u63a5\u6536 SMS \u6d88\u606f\u3002

      "},{"location":"qsl4a/connectivity/sms/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/sms/#smssend","title":"smsSend()","text":"

      \u53d1\u9001 SMS \u6d88\u606f\u3002

      smsSend(destinationAddress, text)\n

      \u53c2\u6570\uff1a - destinationAddress (str): \u7535\u8bdd\u53f7\u7801 - text (str): \u6d88\u606f\u6587\u672c

      "},{"location":"qsl4a/connectivity/sms/#smsgetmessagecount","title":"smsGetMessageCount()","text":"

      \u83b7\u53d6\u6d88\u606f\u6570\u91cf\u3002

      smsGetMessageCount(unreadOnly=False, folder=\"inbox\")\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessageids","title":"smsGetMessageIds()","text":"

      \u83b7\u53d6\u6d88\u606f ID\u3002

      smsGetMessageIds(unreadOnly=False, folder=\"inbox\")\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessages","title":"smsGetMessages()","text":"

      \u83b7\u53d6\u6d88\u606f\u8be6\u60c5\u3002

      smsGetMessages(unreadOnly=False, folder=\"inbox\", attributes=None)\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessagebyid","title":"smsGetMessageById()","text":"

      \u901a\u8fc7 ID \u83b7\u53d6\u7279\u5b9a\u6d88\u606f\u3002

      smsGetMessageById(id, attributes=None)\n

      \u53c2\u6570\uff1a - id (int): \u6d88\u606f ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

      \u8fd4\u56de\uff1a \u6d88\u606f\u6570\u636e\u5b57\u5178

      "},{"location":"qsl4a/connectivity/sms/#smsgetattributes","title":"smsGetAttributes()","text":"

      \u83b7\u53d6\u53ef\u7528\u7684 SMS \u6d88\u606f\u5c5e\u6027\u3002

      smsGetAttributes()\n

      \u8fd4\u56de\uff1a \u53ef\u7528\u5c5e\u6027\u540d\u79f0\u5217\u8868

      "},{"location":"qsl4a/connectivity/sms/#smsdeletemessage","title":"smsDeleteMessage()","text":"

      \u5220\u9664\u6d88\u606f\u3002

      smsDeleteMessage(id)\n
      "},{"location":"qsl4a/connectivity/sms/#smsmarkmessageread","title":"smsMarkMessageRead()","text":"

      \u5c06\u6d88\u606f\u6807\u8bb0\u4e3a\u5df2\u8bfb\u3002

      smsMarkMessageRead(ids, read=True)\n
      "},{"location":"qsl4a/connectivity/sms/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u53d1\u9001 SMS\ndroid.smsSend(\"+1234567890\", \"Hello from QPython!\")\n\n# \u83b7\u53d6\u672a\u8bfb\u6d88\u606f\nmessages = droid.smsGetMessages(unreadOnly=True).result\nfor msg in messages:\n    print(f\"From: {msg['address']}, Text: {msg['body']}\")\n
      "},{"location":"qsl4a/connectivity/wifi/","title":"WiFi API","text":"

      \u63a7\u5236 WiFi \u9002\u914d\u5668\u5e76\u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\u3002

      "},{"location":"qsl4a/connectivity/wifi/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/connectivity/wifi/#checkwifistate","title":"checkWifiState()","text":"

      \u68c0\u67e5 WiFi \u662f\u5426\u5df2\u542f\u7528\u3002

      checkWifiState()\n

      \u8fd4\u56de\uff1a \u5982\u679c WiFi \u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/connectivity/wifi/#togglewifistate","title":"toggleWifiState()","text":"

      \u6253\u5f00\u6216\u5173\u95ed WiFi\u3002

      toggleWifiState(enabled=None)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

      \u8fd4\u56de\uff1a \u5982\u679c\u64cd\u4f5c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/connectivity/wifi/#wifistartscan","title":"wifiStartScan()","text":"

      \u5f00\u59cb\u626b\u63cf\u53ef\u7528\u7684 WiFi \u7f51\u7edc\u3002

      wifiStartScan()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifigetscanresults","title":"wifiGetScanResults()","text":"

      \u83b7\u53d6\u53d1\u73b0\u7684 WiFi \u7f51\u7edc\u5217\u8868\u3002

      wifiGetScanResults()\n

      \u8fd4\u56de\uff1a \u63a5\u5165\u70b9\u4fe1\u606f\u5217\u8868

      "},{"location":"qsl4a/connectivity/wifi/#_2","title":"\u8fde\u63a5\u7ba1\u7406","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetconnectioninfo","title":"wifiGetConnectionInfo()","text":"

      \u83b7\u53d6\u8be6\u7ec6\u8fde\u63a5\u4fe1\u606f\u3002

      wifiGetConnectionInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001IP \u5730\u5740\u7b49\u8fde\u63a5\u8be6\u60c5\u7684\u5b57\u5178

      "},{"location":"qsl4a/connectivity/wifi/#getconnectedinfo","title":"getConnectedInfo()","text":"

      \u83b7\u53d6\u8fde\u63a5\u7684 WiFi \u7f51\u7edc\u4fe1\u606f\uff08\u7b80\u5316\u7248\uff09\u3002

      getConnectedInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001\u4fe1\u53f7\u5f3a\u5ea6\u7684\u5b57\u5178

      "},{"location":"qsl4a/connectivity/wifi/#getdhcpinfo","title":"getDhcpInfo()","text":"

      \u83b7\u53d6\u5f53\u524d\u8fde\u63a5\u7684 DHCP \u4fe1\u606f\u3002

      getDhcpInfo(ipConvertToString=True)\n

      \u53c2\u6570\uff1a - ipConvertToString (bool): \u5c06 IP \u5730\u5740\u8f6c\u6362\u4e3a\u5b57\u7b26\u4e32\u683c\u5f0f\uff08\u9ed8\u8ba4\uff1aTrue\uff09

      \u8fd4\u56de\uff1a \u5305\u542b IP\u3001\u7f51\u5173\u3001DNS \u7b49 DHCP \u4fe1\u606f\u7684\u5b57\u5178

      "},{"location":"qsl4a/connectivity/wifi/#wifidisconnect","title":"wifiDisconnect()","text":"

      \u65ad\u5f00\u5f53\u524d WiFi \u7f51\u7edc\u8fde\u63a5\u3002

      wifiDisconnect()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifireconnect","title":"wifiReconnect()","text":"

      \u91cd\u65b0\u8fde\u63a5\u5230\u5f53\u524d\u7f51\u7edc\u3002

      wifiReconnect()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifireassociate","title":"wifiReassociate()","text":"

      \u91cd\u65b0\u5173\u8054\u5f53\u524d\u63a5\u5165\u70b9\u3002

      wifiReassociate()\n
      "},{"location":"qsl4a/connectivity/wifi/#_3","title":"\u70ed\u70b9","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetapstate","title":"wifiGetApState()","text":"

      \u83b7\u53d6 WiFi AP\uff08\u70ed\u70b9\uff09\u72b6\u6001\u3002

      wifiGetApState()\n

      \u8fd4\u56de\uff1a \u70ed\u70b9\u72b6\u6001

      "},{"location":"qsl4a/connectivity/wifi/#wifi","title":"WiFi \u9501","text":""},{"location":"qsl4a/connectivity/wifi/#wifilockacquirefull","title":"wifiLockAcquireFull()","text":"

      \u83b7\u53d6\u5b8c\u6574 WiFi \u9501\uff08\u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\u4e5f\u4fdd\u6301 WiFi \u6d3b\u52a8\uff09\u3002

      wifiLockAcquireFull()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifilockacquirescanonly","title":"wifiLockAcquireScanOnly()","text":"

      \u83b7\u53d6\u4ec5\u626b\u63cf WiFi \u9501\u3002

      wifiLockAcquireScanOnly()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifilockrelease","title":"wifiLockRelease()","text":"

      \u91ca\u653e WiFi \u9501\u3002

      wifiLockRelease()\n
      "},{"location":"qsl4a/connectivity/wifi/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u68c0\u67e5 WiFi \u72b6\u6001\nif droid.checkWifiState().result:\n    print(\"WiFi is enabled\")\nelse:\n    print(\"Enabling WiFi...\")\n    droid.toggleWifiState(True)\n    time.sleep(2)\n\n# \u5f00\u59cb\u626b\u63cf\ndroid.wifiStartScan()\ntime.sleep(3)\n\n# \u83b7\u53d6\u626b\u63cf\u7ed3\u679c\nnetworks = droid.wifiGetScanResults().result\nfor network in networks:\n    print(f\"SSID: {network.get('SSID')}, Signal: {network.get('level')} dBm\")\n\n# \u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\ninfo = droid.wifiGetConnectionInfo().result\nif info:\n    print(f\"Connected to: {info.get('ssid')}\")\n    print(f\"BSSID: {info.get('bssid')}\")\n    print(f\"IP: {info.get('ip_address')}\")\n\n# \u83b7\u53d6 DHCP \u4fe1\u606f\ndhcp = droid.getDhcpInfo().result\nif dhcp:\n    print(f\"Gateway: {dhcp.get('gateway')}\")\n    print(f\"DNS: {dhcp.get('dns1')}\")\n\n# \u83b7\u53d6\u7b80\u5316\u7684\u8fde\u63a5\u4fe1\u606f\nconnected = droid.getConnectedInfo().result\nprint(f\"SSID: {connected.get('ssid')}, Signal: {connected.get('level')} dBm\")\n\n# \u65ad\u5f00\u5e76\u91cd\u65b0\u8fde\u63a5\ndroid.wifiDisconnect()\ntime.sleep(1)\ndroid.wifiReconnect()\n\n# \u91cd\u65b0\u5173\u8054\u63a5\u5165\u70b9\ndroid.wifiReassociate()\n\n# \u68c0\u67e5\u70ed\u70b9\u72b6\u6001\nap_state = droid.wifiGetApState().result\nprint(f\"Hotspot state: {ap_state}\")\n\n# \u83b7\u53d6 WiFi \u9501\u4ee5\u8fdb\u884c\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireFull()\n# ... \u6267\u884c\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n\n# \u6216\u4f7f\u7528\u4ec5\u626b\u63cf\u9501\u4ee5\u8fdb\u884c\u8f83\u8f7b\u7684\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireScanOnly()\n# ... \u6267\u884c\u626b\u63cf\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n
      "},{"location":"qsl4a/core/android-base/","title":"Android \u57fa\u7840\u7c7b","text":"

      Android \u7c7b\u662f QSL4A \u7684\u6838\u5fc3\uff0c\u63d0\u4f9b\u4e86\u4e0e Android \u8fd0\u884c\u65f6\u7684\u8fde\u63a5\u548c RPC \u673a\u5236\u3002

      "},{"location":"qsl4a/core/android-base/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
      # \u529f\u80fd\u5b8c\u6574\u7248\u672c\uff08\u63a8\u8350\uff09\nimport androidhelper\ndroid = androidhelper.Android()\n\n# \u7b80\u5316\u7248\u672c\uff08\u5feb\u901f\uff0c\u5355\u5b9e\u4f8b\uff09\nimport android\ndroid = android.droid\n
      "},{"location":"qsl4a/core/android-base/#android_1","title":"\u7c7b\uff1aAndroid","text":""},{"location":"qsl4a/core/android-base/#_2","title":"\u6784\u9020\u51fd\u6570","text":"
      Android(addr=None)\n

      \u53c2\u6570\uff1a - addr (tuple, optional): (HOST, PORT) \u5730\u5740\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u73af\u5883\u53d8\u91cf AP_HOST \u548c AP_PORT

      \u73af\u5883\u53d8\u91cf\uff1a - AP_HOST - \u670d\u52a1\u5668\u4e3b\u673a\u5730\u5740 - AP_PORT - \u670d\u52a1\u5668\u7aef\u53e3 - AP_HANDSHAKE - \u8ba4\u8bc1\u4ee4\u724c

      "},{"location":"qsl4a/core/android-base/#_3","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/android-base/#_rpc","title":"_rpc()","text":"

      \u8c03\u7528 Android \u51fd\u6570\u7684\u5185\u90e8 RPC \u65b9\u6cd5\u3002

      _rpc(method, *args)\n

      \u53c2\u6570\uff1a - method (str): \u8981\u8c03\u7528\u7684\u65b9\u6cd5\u540d - *args: \u65b9\u6cd5\u7684\u53ef\u53d8\u53c2\u6570

      \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4\uff0c\u5305\u542b\u4ee5\u4e0b\u5b57\u6bb5\uff1a - id (int): \u8bf7\u6c42 ID - result: \u65b9\u6cd5\u8fd4\u56de\u503c - error (str or None): \u9519\u8bef\u4fe1\u606f\uff08\u5982\u679c\u5931\u8d25\uff09

      "},{"location":"qsl4a/core/android-base/#getattr","title":"getattr()","text":"

      \u52a8\u6001\u65b9\u6cd5\u5206\u53d1\u5668\u3002\u6240\u6709 Android \u65b9\u6cd5\u90fd\u901a\u8fc7\u5c5e\u6027\u67e5\u627e\u8bbf\u95ee\u3002

      # \u4ee5\u4e0b\u4e24\u79cd\u65b9\u5f0f\u7b49\u4ef7\uff1a\ndroid.makeToast(\"Hello\")\ndroid._rpc(\"makeToast\", \"Hello\")\n
      "},{"location":"qsl4a/core/android-base/#androidpy","title":"\u72ec\u7acb\u51fd\u6570\uff08android.py\uff09","text":"

      \u4f7f\u7528\u7b80\u5316\u7684 android \u6a21\u5757\u65f6\uff1a

      "},{"location":"qsl4a/core/android-base/#jsla","title":"jsla()","text":"

      \u53d1\u9001 JSON-RPC \u8bf7\u6c42\u5e76\u8fd4\u56de\u539f\u59cb\u54cd\u5e94\u3002

      jsla(method, *params)\n

      \u8fd4\u56de\uff1a JSON \u5b57\u7b26\u4e32\u54cd\u5e94

      "},{"location":"qsl4a/core/android-base/#rsla","title":"rsla()","text":"

      \u53d1\u9001\u8bf7\u6c42\u5e76\u4ec5\u8fd4\u56de\u7ed3\u679c\u3002

      rsla(method, *params)\n

      \u8fd4\u56de\uff1a RPC \u8c03\u7528\u7684\u7ed3\u679c\u503c

      "},{"location":"qsl4a/core/android-base/#esla","title":"esla()","text":"

      \u53d1\u9001\u8bf7\u6c42\uff0c\u9519\u8bef\u65f6\u629b\u51fa\u5f02\u5e38\u3002

      esla(method, *params)\n

      \u629b\u51fa\uff1a \u5982\u679c error \u5b57\u6bb5\u4e0d\u4e3a None \u5219\u629b\u51fa\u5f02\u5e38

      "},{"location":"qsl4a/core/android-base/#nsla","title":"nsla()","text":"

      \u53d1\u9001\u8bf7\u6c42\u5e76\u8fd4\u56de Result \u547d\u540d\u5143\u7ec4\u3002

      nsla(method, *params)\n

      \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4

      "},{"location":"qsl4a/core/android-base/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/android-base/#_5","title":"\u57fa\u672c\u8fde\u63a5","text":"
      import androidhelper\n\n# \u8fde\u63a5\u5230 Android \u8fd0\u884c\u65f6\ndroid = androidhelper.Android()\n\n# \u901a\u8fc7\u663e\u793a toast \u6765\u68c0\u67e5\u8fde\u63a5\ndroid.makeToast(\"Connected!\")\n
      "},{"location":"qsl4a/core/android-base/#_6","title":"\u9519\u8bef\u5904\u7406","text":"
      result = droid.someMethod()\nif result.error:\n    print(f\"Error: {result.error}\")\nelse:\n    print(f\"Success: {result.result}\")\n
      "},{"location":"qsl4a/core/android-base/#rpc","title":"\u76f4\u63a5 RPC \u8c03\u7528","text":"
      # \u76f4\u63a5\u8c03\u7528\u4efb\u610f\u65b9\u6cd5\nresult = droid._rpc(\"makeToast\", \"Hello World\")\n
      "},{"location":"qsl4a/core/events/","title":"\u4e8b\u4ef6\u7cfb\u7edf","text":"

      QSL4A \u63d0\u4f9b\u4e86\u4e00\u4e2a\u4e8b\u4ef6\u7cfb\u7edf\uff0c\u7528\u4e8e\u5904\u7406\u6765\u81ea Android \u7684\u5f02\u6b65\u4e8b\u4ef6\uff0c\u5982\u4f20\u611f\u5668\u66f4\u65b0\u3001\u4f4d\u7f6e\u53d8\u5316\u548c\u81ea\u5b9a\u4e49\u5e7f\u64ad\u3002

      "},{"location":"qsl4a/core/events/#_2","title":"\u4e8b\u4ef6\u57fa\u7840","text":"

      \u4e8b\u4ef6\u5b58\u50a8\u5728\u7f13\u51b2\u533a\u4e2d\uff0c\u53ef\u4ee5\u8f6e\u8be2\u6216\u7b49\u5f85\u3002\u6bcf\u4e2a\u4e8b\u4ef6\u5305\u542b\uff1a - name: \u4e8b\u4ef6\u7c7b\u578b/\u540d\u79f0 - data: \u4e8b\u4ef6\u8d1f\u8f7d\u6570\u636e - time: \u65f6\u95f4\u6233

      "},{"location":"qsl4a/core/events/#_3","title":"\u4e8b\u4ef6\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#eventclearbuffer","title":"eventClearBuffer()","text":"

      \u6e05\u9664\u7f13\u51b2\u533a\u4e2d\u7684\u6240\u6709\u5f85\u5904\u7406\u4e8b\u4ef6\u3002

      eventClearBuffer()\n

      \u8fd4\u56de\uff1a None

      "},{"location":"qsl4a/core/events/#eventpoll","title":"eventPoll()","text":"

      \u8f6e\u8be2\u7f13\u51b2\u533a\u4e2d\u7684\u4e8b\u4ef6\u3002

      eventPoll(number_of_events=1)\n

      \u53c2\u6570\uff1a - number_of_events (int): \u8981\u68c0\u7d22\u7684\u6700\u5927\u4e8b\u4ef6\u6570\uff08\u9ed8\u8ba4\uff1a1\uff09

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\u5217\u8868

      "},{"location":"qsl4a/core/events/#eventwait","title":"eventWait()","text":"

      \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\u3002

      eventWait(timeout=None)\n

      \u53c2\u6570\uff1a - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09\u3002None = \u6c38\u4e45\u7b49\u5f85

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

      "},{"location":"qsl4a/core/events/#eventwaitfor","title":"eventWaitFor()","text":"

      \u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6\u3002

      eventWaitFor(eventName, timeout=None)\n

      \u53c2\u6570\uff1a - eventName (str): \u8981\u7b49\u5f85\u7684\u4e8b\u4ef6\u540d\u79f0 - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

      "},{"location":"qsl4a/core/events/#eventpost","title":"eventPost()","text":"

      \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\u3002

      eventPost(name, data, enqueue=None)\n

      \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e\uff08\u4efb\u610f\u7c7b\u578b\uff09 - enqueue (bool, optional): \u5982\u679c\u4e3a True \u5219\u6dfb\u52a0\u5230\u961f\u5217

      "},{"location":"qsl4a/core/events/#receiveevent","title":"receiveEvent()","text":"

      \u63a5\u6536\u4e8b\u4ef6\uff08\u963b\u585e\uff09\u3002

      receiveEvent()\n

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61

      "},{"location":"qsl4a/core/events/#_4","title":"\u5e7f\u64ad\u4e8b\u4ef6","text":"

      \u6ce8\u518c\u7cfb\u7edf\u5e7f\u64ad\u4e8b\u4ef6\u3002

      "},{"location":"qsl4a/core/events/#eventregisterforbroadcast","title":"eventRegisterForBroadcast()","text":"

      \u6ce8\u518c\u63a5\u6536\u5e7f\u64ad\u4e8b\u4ef6\u3002

      eventRegisterForBroadcast(category, enqueue=True)\n

      \u53c2\u6570\uff1a - category (str): \u5e7f\u64ad\u7c7b\u522b/\u52a8\u4f5c - enqueue (bool): \u6dfb\u52a0\u5230\u4e8b\u4ef6\u961f\u5217

      "},{"location":"qsl4a/core/events/#eventunregisterforbroadcast","title":"eventUnregisterForBroadcast()","text":"

      \u53d6\u6d88\u6ce8\u518c\u5e7f\u64ad\u4e8b\u4ef6\u3002

      eventUnregisterForBroadcast(category)\n
      "},{"location":"qsl4a/core/events/#eventgetbrodcastcategories","title":"eventGetBrodcastCategories()","text":"

      \u83b7\u53d6\u5df2\u6ce8\u518c\u7684\u5e7f\u64ad\u7c7b\u522b\u3002

      eventGetBrodcastCategories()\n

      \u8fd4\u56de\uff1a \u5df2\u6ce8\u518c\u7c7b\u522b\u5217\u8868

      "},{"location":"qsl4a/core/events/#_5","title":"\u4e8b\u4ef6\u5206\u53d1\u5668)","text":""},{"location":"qsl4a/core/events/#starteventdispatcher","title":"startEventDispatcher()","text":"

      \u6253\u5f00\u4e00\u4e2a\u53ef\u4ee5\u8bfb\u53d6\u5df2\u53d1\u5e03\u4e8b\u4ef6\u7684\u5957\u63a5\u5b57\u3002)

      startEventDispatcher(port=0)\n

      \u53c2\u6570\uff1a - port (int, optional): \u76d1\u542c\u7684\u7aef\u53e3\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\u9009\u62e9\uff09

      \u8fd4\u56de\uff1a \u6b63\u5728\u76d1\u542c\u7684\u7aef\u53e3\u53f7

      "},{"location":"qsl4a/core/events/#stopeventdispatcher","title":"stopEventDispatcher()","text":"

      \u505c\u6b62\u4e8b\u4ef6\u670d\u52a1\u5668\u3002)

      stopEventDispatcher()\n
      "},{"location":"qsl4a/core/events/#_6","title":"\u5df2\u5e9f\u5f03\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#rpcpostevent","title":"rpcPostEvent()","text":"

      \u5c06\u4e8b\u4ef6\u53d1\u5e03\u5230\u4e8b\u4ef6\u961f\u5217\u3002\uff08\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 eventPost\uff09

      rpcPostEvent(name, data)\n

      \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e

      "},{"location":"qsl4a/core/events/#_7","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/events/#_8","title":"\u57fa\u672c\u4e8b\u4ef6\u8f6e\u8be2","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6e05\u9664\u65e7\u4e8b\u4ef6\ndroid.eventClearBuffer()\n\n# \u8f6e\u8be2\u4e8b\u4ef6\nevents = droid.eventPoll(5).result\nfor event in events:\n    print(f\"Event: {event['name']}, Data: {event['data']}\")\n
      "},{"location":"qsl4a/core/events/#_9","title":"\u7b49\u5f85\u4e8b\u4ef6","text":"
      # \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\uff0c\u5e26\u8d85\u65f6\nevent = droid.eventWait(timeout=10).result\nif event:\n    print(f\"Got event: {event['name']}\")\n
      "},{"location":"qsl4a/core/events/#_10","title":"\u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6","text":"
      # \u7b49\u5f85\u4f20\u611f\u5668\u4e8b\u4ef6\nevent = droid.eventWaitFor('screen', timeout=5).result\nif event:\n    print(f\"Screen event: {event['data']}\")\n
      "},{"location":"qsl4a/core/events/#_11","title":"\u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6","text":"
      # \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\ndroid.eventPost('my_event', {'key': 'value'})\n\n# \u7b49\u5f85\u5b83\nevent = droid.eventWaitFor('my_event', timeout=1).result\n
      "},{"location":"qsl4a/core/events/#_12","title":"\u5e7f\u64ad\u63a5\u6536\u5668","text":"
      # \u6ce8\u518c\u5c4f\u5e55\u5f00\u5173\u4e8b\u4ef6\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_ON')\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_OFF')\n\n# \u7b49\u5f85\u5c4f\u5e55\u4e8b\u4ef6\nwhile True:\n    event = droid.receiveEvent().result\n    if event['name'] == 'android.intent.action.SCREEN_ON':\n        print(\"Screen turned on\")\n    elif event['name'] == 'android.intent.action.SCREEN_OFF':\n        print(\"Screen turned off\")\n
      "},{"location":"qsl4a/core/events/#_13","title":"\u4f20\u611f\u5668\u4e8b\u4ef6\u5904\u7406","text":"
      # \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u5904\u7406\u4f20\u611f\u5668\u4e8b\u4ef6\nfor _ in range(100):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'sensors':\n        data = event['data']\n        print(f\"Accel: {data['xforce']}, {data['yforce']}, {data['zforce']}\")\n\ndroid.stopSensing()\n
      "},{"location":"qsl4a/core/events/#_14","title":"\u5e38\u89c1\u4e8b\u4ef6\u7c7b\u578b","text":"\u4e8b\u4ef6\u540d\u79f0 \u63cf\u8ff0 \u6765\u6e90 sensors \u4f20\u611f\u5668\u6570\u636e\u66f4\u65b0 startSensing* location GPS \u4f4d\u7f6e\u66f4\u65b0 startLocating phone \u7535\u8bdd\u72b6\u6001\u53d8\u5316 startTrackingPhoneState signal \u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316 startTrackingSignalStrength screen \u622a\u56fe\u5c31\u7eea fullGetScreenShot dialog \u5bf9\u8bdd\u6846\u54cd\u5e94 dialogShow*"},{"location":"qsl4a/core/events/#_15","title":"\u4e8b\u4ef6\u6570\u636e\u7ed3\u6784","text":"
      {\n    'name': 'event_name',\n    'data': {\n        # \u4e8b\u4ef6\u7279\u5b9a\u6570\u636e\n    },\n    'time': 1234567890  # \u65f6\u95f4\u6233\n}\n
      "},{"location":"qsl4a/core/intent/","title":"Intent \u7cfb\u7edf","text":"

      Android Intent \u7528\u4e8e\u542f\u52a8\u6d3b\u52a8\u3001\u53d1\u9001\u5e7f\u64ad\u548c\u5e94\u7528\u95f4\u901a\u4fe1\u3002QSL4A \u901a\u8fc7 Intent \u6a21\u5757\u63d0\u4f9b\u5b8c\u6574\u7684 Intent \u652f\u6301\u3002

      "},{"location":"qsl4a/core/intent/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
      import androidhelper\ndon = androidhelper.Android()\n
      "},{"location":"qsl4a/core/intent/#intent_1","title":"Intent \u5e38\u91cf","text":"

      \u901a\u8fc7 droid.Intent \u8bbf\u95ee\uff1a

      "},{"location":"qsl4a/core/intent/#_2","title":"\u64cd\u4f5c","text":"\u5e38\u91cf \u503c \u7528\u9014 ACTION_MAIN android.intent.action.MAIN \u5e94\u7528\u5165\u53e3\u70b9 ACTION_VIEW android.intent.action.VIEW \u67e5\u770b\u5185\u5bb9 ACTION_EDIT android.intent.action.EDIT \u7f16\u8f91\u5185\u5bb9 ACTION_PICK android.intent.action.PICK \u9009\u62e9\u9879\u76ee ACTION_SEND android.intent.action.SEND \u5206\u4eab\u5185\u5bb9 ACTION_SEARCH android.intent.action.SEARCH \u641c\u7d22"},{"location":"qsl4a/core/intent/#_3","title":"\u6807\u5fd7","text":"\u5e38\u91cf \u503c \u7528\u9014 FLAG_ACTIVITY_NEW_TASK 268435456 \u542f\u52a8\u65b0\u4efb\u52a1 FLAG_ACTIVITY_CLEAR_TASK 32768 \u6e05\u9664\u4efb\u52a1\u5806\u6808 FLAG_ACTIVITY_NEW_DOCUMENT 524288 \u65b0\u6587\u6863\u6a21\u5f0f"},{"location":"qsl4a/core/intent/#_4","title":"\u9644\u52a0\u6570\u636e","text":"\u5e38\u91cf \u7528\u9014 EXTRA_TEXT \u6587\u672c\u5185\u5bb9 EXTRA_STREAM \u6587\u4ef6 URI EXTRA_SUBJECT \u4e3b\u9898\u884c EXTRA_EMAIL \u7535\u5b50\u90ae\u4ef6\u5730\u5740"},{"location":"qsl4a/core/intent/#_5","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/intent/#makeintent","title":"makeIntent()","text":"

      \u521b\u5efa Intent \u5bf9\u8c61\u3002

      makeIntent(action, uri=None, type=None, extras=None, categories=None,\n           packagename=None, classname=None, flags=None)\n

      \u53c2\u6570\uff1a - action (str): Intent \u64cd\u4f5c\uff08\u4f8b\u5982 droid.Intent.ACTION_VIEW\uff09 - uri (str, optional): \u6570\u636e URI - type (str, optional): MIME \u7c7b\u578b - extras (dict, optional): \u9644\u52a0\u6570\u636e - categories (list, optional): Intent \u7c7b\u522b - packagename (str, optional): \u76ee\u6807\u5305 - classname (str, optional): \u76ee\u6807\u7c7b - flags (int, optional): Intent \u6807\u5fd7

      \u8fd4\u56de\uff1a Intent \u5bf9\u8c61

      "},{"location":"qsl4a/core/intent/#startactivityintent","title":"startActivityIntent()","text":"

      \u4f7f\u7528 Intent \u542f\u52a8 Activity\u3002

      startActivityIntent(intent, wait=None)\n

      \u53c2\u6570\uff1a - intent: makeIntent() \u8fd4\u56de\u7684 Intent \u5bf9\u8c61 - wait (bool, optional): \u963b\u585e\u76f4\u5230\u6d3b\u52a8\u5173\u95ed

      "},{"location":"qsl4a/core/intent/#startactivityforresultintent","title":"startActivityForResultIntent()","text":"

      \u542f\u52a8\u6d3b\u52a8\u5e76\u7b49\u5f85\u7ed3\u679c\u3002

      startActivityForResultIntent(intent)\n

      \u8fd4\u56de\uff1a Activity \u7ed3\u679c

      "},{"location":"qsl4a/core/intent/#sendbroadcastintent","title":"sendBroadcastIntent()","text":"

      \u53d1\u9001\u5e7f\u64ad\u3002

      sendBroadcastIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#view","title":"view()","text":"

      \u901a\u8fc7 URI \u67e5\u770b\u5185\u5bb9\u3002

      view(uri, type=None, extras=None)\n
      "},{"location":"qsl4a/core/intent/#pick","title":"pick()","text":"

      \u4ece URI \u9009\u62e9\u5185\u5bb9\u3002

      pick(uri)\n
      "},{"location":"qsl4a/core/intent/#intent_2","title":"\u5e38\u89c1 Intent \u65b9\u6cd5)","text":""},{"location":"qsl4a/core/intent/#scanbarcode","title":"scanBarcode()","text":"

      \u542f\u52a8\u6761\u7801\u626b\u63cf\u5668\u3002

      scanBarcode()\n

      \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/core/intent/#send","title":"send()","text":"

      \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u5185\u5bb9\u3002

      send(type, content)\n

      \u53c2\u6570\uff1a - type (str): MIME \u7c7b\u578b - content (str): \u8981\u5206\u4eab\u7684\u5185\u5bb9

      "},{"location":"qsl4a/core/intent/#sendtext","title":"sendText()","text":"

      \u53d1\u9001\u6587\u672c\u5185\u5bb9\u3002

      sendText(text)\n

      \u53c2\u6570\uff1a - text (str): \u8981\u53d1\u9001\u7684\u6587\u672c

      "},{"location":"qsl4a/core/intent/#sendemail","title":"sendEmail()","text":"

      \u53d1\u9001\u7535\u5b50\u90ae\u4ef6\u3002

      sendEmail(to, subject, body, attachment=None)\n

      \u53c2\u6570\uff1a - to (str or list): \u6536\u4ef6\u4eba\u7535\u5b50\u90ae\u4ef6\u5730\u5740 - subject (str): \u7535\u5b50\u90ae\u4ef6\u4e3b\u9898 - body (str): \u7535\u5b50\u90ae\u4ef6\u6b63\u6587 - attachment (str, optional): \u9644\u4ef6\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/core/intent/#pathtouri","title":"pathToUri()","text":"

      \u5c06\u6587\u4ef6\u8def\u5f84\u8f6c\u6362\u4e3a\u5185\u5bb9 URI\u3002

      pathToUri(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5185\u5bb9 URI \u5b57\u7b26\u4e32

      "},{"location":"qsl4a/core/intent/#openfile","title":"openFile()","text":"

      \u7528\u9002\u5f53\u7684\u5e94\u7528\u7a0b\u5e8f\u6253\u5f00\u6587\u4ef6\u3002

      openFile(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u6253\u5f00\u7684\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/core/intent/#sendfile","title":"sendFile()","text":"

      \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u6587\u4ef6\u3002

      sendFile(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u53d1\u9001\u7684\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/core/intent/#getpathtype","title":"getPathType()","text":"

      \u83b7\u53d6\u6587\u4ef6\u8def\u5f84\u7684 MIME \u7c7b\u578b\u3002

      getPathType(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a MIME \u7c7b\u578b\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/core/intent/#viewmap","title":"viewMap()","text":"

      \u5728\u6307\u5b9a\u4f4d\u7f6e\u6253\u5f00\u5730\u56fe\u3002

      viewMap(latitude, longitude)\n

      \u53c2\u6570\uff1a - latitude (float): \u7eac\u5ea6 - longitude (float): \u7ecf\u5ea6

      "},{"location":"qsl4a/core/intent/#viewcontacts","title":"viewContacts()","text":"

      \u6253\u5f00\u8054\u7cfb\u4eba\u5e94\u7528\u3002

      viewContacts()\n
      "},{"location":"qsl4a/core/intent/#search","title":"search()","text":"

      \u6267\u884c\u7f51\u7edc\u641c\u7d22\u3002

      search(query)\n

      \u53c2\u6570\uff1a - query (str): \u641c\u7d22\u67e5\u8be2

      "},{"location":"qsl4a/core/intent/#viewhtml","title":"viewHtml()","text":"

      \u67e5\u770b HTML \u5185\u5bb9\u3002

      viewHtml(content, encoding=None)\n

      \u53c2\u6570\uff1a - content (str): HTML \u5185\u5bb9 - encoding (str, optional): \u5b57\u7b26\u7f16\u7801

      "},{"location":"qsl4a/core/intent/#webviewshow","title":"webViewShow()","text":"

      \u5728 WebView \u4e2d\u663e\u793a\u7f51\u9875\u5185\u5bb9\u3002\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 viewHtml\u3002

      webViewShow(url)\n

      \u53c2\u6570\uff1a - url (str): \u7f51\u9875 URL

      "},{"location":"qsl4a/core/intent/#editoropen","title":"editorOpen()","text":"

      \u6253\u5f00\u6587\u672c\u7f16\u8f91\u5668\u3002

      editorOpen(path=None, create=False)\n

      \u53c2\u6570\uff1a - path (str, optional): \u8981\u7f16\u8f91\u7684\u6587\u4ef6\u8def\u5f84 - create (bool, optional): \u5982\u679c\u4e0d\u5b58\u5728\u5219\u521b\u5efa

      "},{"location":"qsl4a/core/intent/#uri","title":"\u8f85\u52a9\u7c7b\uff1aUri","text":"

      \u521b\u5efa Intent \u7684 URI \u5bf9\u8c61\uff1a

      from androidhelper.Intent import Uri\n\nuri = Uri(\"file:///sdcard/test.txt\")\n
      "},{"location":"qsl4a/core/intent/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/intent/#_7","title":"\u6253\u5f00\u7f51\u9875","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"http://www.example.com\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_8","title":"\u5206\u4eab\u6587\u672c","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_TEXT: \"Hello from QPython!\",\n        droid.Intent.EXTRA_SUBJECT: \"Test\"\n    },\n    type=\"text/plain\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_9","title":"\u6253\u5f00\u6587\u4ef6","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"file:///sdcard/document.pdf\",\n    type=\"application/pdf\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_10","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":"
      result = droid.pickContact()\ncontact_uri = result.result\n
      "},{"location":"qsl4a/core/intent/#_11","title":"\u53d1\u9001\u7535\u5b50\u90ae\u4ef6","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_EMAIL: [\"test@example.com\"],\n        droid.Intent.EXTRA_SUBJECT: \"Hello\",\n        droid.Intent.EXTRA_TEXT: \"Message body\"\n    },\n    type=\"message/rfc822\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_12","title":"\u6253\u5f00\u5e94\u7528","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_MAIN,\n    packagename=\"com.android.settings\",\n    classname=\"com.android.settings.Settings\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/hardware/bluetooth/","title":"\u84dd\u7259 API","text":"

      \u63a7\u5236\u84dd\u7259\u9002\u914d\u5668\u5e76\u4e0e\u84dd\u7259\u8bbe\u5907\u901a\u4fe1\u3002

      "},{"location":"qsl4a/hardware/bluetooth/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/hardware/bluetooth/#togglebluetoothstate","title":"toggleBluetoothState()","text":"

      \u6253\u5f00/\u5173\u95ed\u84dd\u7259\u3002

      toggleBluetoothState(enabled=None, prompt=True)\n

      \u53c2\u6570\uff1a - enabled (bool): True=\u5f00\uff0cFalse=\u5173\uff0cNone=\u5207\u6362 - prompt (bool): \u663e\u793a\u7528\u6237\u63d0\u793a

      "},{"location":"qsl4a/hardware/bluetooth/#checkbluetoothstate","title":"checkBluetoothState()","text":"

      \u68c0\u67e5\u84dd\u7259\u662f\u5426\u5df2\u542f\u7528\u3002

      checkBluetoothState()\n

      \u8fd4\u56de\uff1a True/False

      "},{"location":"qsl4a/hardware/bluetooth/#getlocalname","title":"GetLocalName()","text":"

      \u83b7\u53d6\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

      GetLocalName()\n
      "},{"location":"qsl4a/hardware/bluetooth/#setlocalname","title":"SetLocalName()","text":"

      \u8bbe\u7f6e\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

      SetLocalName(name)\n
      "},{"location":"qsl4a/hardware/bluetooth/#getscanmode","title":"GetScanMode()","text":"

      \u83b7\u53d6\u53ef\u53d1\u73b0\u6027\u6a21\u5f0f\u3002

      GetScanMode()\n

      \u8fd4\u56de\uff1a - -1: \u5df2\u7981\u7528 - 0: \u4e0d\u53ef\u53d1\u73b0\uff0c\u4e0d\u53ef\u8fde\u63a5 - 1: \u53ef\u8fde\u63a5\uff0c\u4e0d\u53ef\u53d1\u73b0 - 3: \u53ef\u8fde\u63a5\u4e14\u53ef\u53d1\u73b0

      "},{"location":"qsl4a/hardware/bluetooth/#makediscoverable","title":"MakeDiscoverable()","text":"

      \u4f7f\u8bbe\u5907\u53ef\u53d1\u73b0\u3002

      MakeDiscoverable(duration=300)\n

      \u53c2\u6570\uff1a - duration (int): \u53ef\u53d1\u73b0\u7684\u79d2\u6570

      "},{"location":"qsl4a/hardware/bluetooth/#_2","title":"\u53d1\u73b0","text":""},{"location":"qsl4a/hardware/bluetooth/#discoverystart","title":"DiscoveryStart()","text":"

      \u5f00\u59cb\u8bbe\u5907\u53d1\u73b0\u3002

      DiscoveryStart()\n
      "},{"location":"qsl4a/hardware/bluetooth/#discoverycancel","title":"DiscoveryCancel()","text":"

      \u53d6\u6d88\u53d1\u73b0\u3002

      DiscoveryCancel()\n
      "},{"location":"qsl4a/hardware/bluetooth/#getreceiveddevices","title":"GetReceivedDevices()","text":"

      \u83b7\u53d6\u53d1\u73b0\u7684\u8bbe\u5907\u3002

      GetReceivedDevices()\n

      \u8fd4\u56de\uff1a \u8bbe\u5907\u4fe1\u606f\u5b57\u5178\u5217\u8868

      "},{"location":"qsl4a/hardware/bluetooth/#getbondeddevices","title":"GetBondedDevices()","text":"

      \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\u3002

      GetBondedDevices()\n

      \u8fd4\u56de\uff1a \u914d\u5bf9\u8bbe\u5907\u4fe1\u606f\u5217\u8868

      "},{"location":"qsl4a/hardware/bluetooth/#_3","title":"\u8fde\u63a5","text":""},{"location":"qsl4a/hardware/bluetooth/#connect","title":"Connect()","text":"

      \u8fde\u63a5\u5230\u8bbe\u5907\u3002

      Connect(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", address=None)\n

      \u53c2\u6570\uff1a - uuid (str): \u670d\u52a1 UUID - address (str): \u8bbe\u5907\u5730\u5740\uff08None = \u663e\u793a\u9009\u62e9\u5668\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/hardware/bluetooth/#accept","title":"Accept()","text":"

      \u63a5\u53d7\u4f20\u5165\u8fde\u63a5\u3002

      Accept(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", timeout=0)\n
      "},{"location":"qsl4a/hardware/bluetooth/#activeconnections","title":"ActiveConnections()","text":"

      \u68c0\u67e5\u6d3b\u52a8\u8fde\u63a5\u3002

      ActiveConnections()\n
      "},{"location":"qsl4a/hardware/bluetooth/#stop","title":"Stop()","text":"

      \u65ad\u5f00\u8fde\u63a5\u3002

      Stop(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#_4","title":"\u901a\u4fe1","text":""},{"location":"qsl4a/hardware/bluetooth/#write","title":"Write()","text":"

      \u53d1\u9001 ASCII \u6570\u636e\u3002

      Write(ascii, connID=\"\")\n
      "},{"location":"qsl4a/hardware/bluetooth/#writebinary","title":"WriteBinary()","text":"

      \u53d1\u9001\u4e8c\u8fdb\u5236\u6570\u636e\uff08base64 \u7f16\u7801\uff09\u3002

      WriteBinary(base64, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#read","title":"Read()","text":"

      \u8bfb\u53d6 ASCII \u6570\u636e\u3002

      Read(bufferSize=4096, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readbinary","title":"ReadBinary()","text":"

      \u8bfb\u53d6\u4e8c\u8fdb\u5236\u6570\u636e\u3002

      ReadBinary(bufferSize=4096, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readline","title":"ReadLine()","text":"

      \u8bfb\u53d6\u4e00\u884c\u3002

      ReadLine(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readready","title":"ReadReady()","text":"

      \u68c0\u67e5\u662f\u5426\u6709\u53ef\u7528\u6570\u636e\u3002

      ReadReady(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u7528\u84dd\u7259\ndroid.toggleBluetoothState(True)\n\n# \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\ndevices = droid.GetBondedDevices().result\nfor dev in devices:\n    print(f\"{dev['name']}: {dev['address']}\")\n\n# \u8fde\u63a5\u5230\u8bbe\u5907\ndroid.Connect(address=\"00:11:22:33:44:55\")\n\n# \u53d1\u9001\u6570\u636e\ndroid.Write(\"Hello Bluetooth!\")\n\n# \u8bfb\u53d6\u54cd\u5e94\ndata = droid.Read(1024).result\n
      "},{"location":"qsl4a/hardware/camera/","title":"\u76f8\u673a API","text":"

      \u62cd\u6444\u7167\u7247\u548c\u5f55\u5236\u89c6\u9891\u3002

      "},{"location":"qsl4a/hardware/camera/#_1","title":"\u7167\u7247\u62cd\u6444","text":""},{"location":"qsl4a/hardware/camera/#takepicture","title":"takePicture()","text":"

      \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u6444\u7167\u7247\u3002

      takePicture(path=None)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8fd4\u56de\u56fe\u50cf\u6570\u636e

      \u8fd4\u56de\uff1a \u56fe\u50cf\u8def\u5f84\u6216\u56fe\u50cf\u6570\u636e

      "},{"location":"qsl4a/hardware/camera/#cameracapturepicture","title":"cameraCapturePicture()","text":"

      \u4f7f\u7528\u9ad8\u7ea7\u76f8\u673a\u63a7\u5236\u62cd\u6444\u7167\u7247\u3002

      cameraCapturePicture(targetPath=None, cameraId=0, useAutoFocus=True)\n

      \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - useAutoFocus (bool): \u542f\u7528\u81ea\u52a8\u5bf9\u7126

      \u8fd4\u56de\uff1a \u62cd\u6444\u7684\u56fe\u50cf\u8def\u5f84

      "},{"location":"qsl4a/hardware/camera/#camerasettorchmode","title":"cameraSetTorchMode()","text":"

      \u63a7\u5236\u76f8\u673a\u95ea\u5149\u706f/\u624b\u7535\u7b52\u3002

      cameraSetTorchMode(enabled)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u6253\u5f00\uff0cFalse \u5173\u95ed

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/hardware/camera/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

      \u622a\u56fe\u3002

      imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

      "},{"location":"qsl4a/hardware/camera/#_2","title":"\u89c6\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#takevideo","title":"takeVideo()","text":"

      \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\u3002

      takeVideo(path=None, quality=1)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-4\uff09 - 0: 160x120 - 1: 320x240 - 2: 352x288 - 3: 640x480 - 4: 800x480

      "},{"location":"qsl4a/hardware/camera/#recordercapturevideo","title":"recorderCaptureVideo()","text":"

      \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\u3002

      recorderCaptureVideo(targetPath=None, duration=10, cameraId=0, quality=8)\n

      \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - duration (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a10\uff09 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-8\uff0c\u8d8a\u9ad8\u8d8a\u597d\uff09

      \u8fd4\u56de\uff1a \u89c6\u9891\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/hardware/camera/#recordaudio","title":"recordAudio()","text":"

      \u5f55\u5236\u97f3\u9891\u3002

      recordAudio()\n

      \u8fd4\u56de\uff1a \u97f3\u9891\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/hardware/camera/#_3","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

      \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\u3002

      recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

      \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\uff09 - targetPixels (int): \u5206\u8fa8\u7387 - frameRate (int): FPS - bitRate (int): \u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa - autoStart (bool): \u7acb\u5373\u5f00\u59cb

      "},{"location":"qsl4a/hardware/camera/#recorderstart","title":"recorderStart()","text":"

      \u5f00\u59cb\u5f55\u5236\u3002

      recorderStart()\n
      "},{"location":"qsl4a/hardware/camera/#recorderpause","title":"recorderPause()","text":"

      \u6682\u505c\u5f55\u5236\u3002

      recorderPause()\n
      "},{"location":"qsl4a/hardware/camera/#recorderresume","title":"recorderResume()","text":"

      \u6062\u590d\u5f55\u5236\u3002

      recorderResume()\n
      "},{"location":"qsl4a/hardware/camera/#_4","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/camera/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

      \u5f00\u59cb\u97f3\u91cf\u68c0\u6d4b\u3002

      recorderSoundVolumeDetect(interval=100)\n
      "},{"location":"qsl4a/hardware/camera/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

      \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

      recorderSoundVolumeGetDb()\n
      "},{"location":"qsl4a/hardware/camera/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u7167\nphoto_path = droid.takePicture(\"/sdcard/photo.jpg\").result\nprint(f\"Photo saved: {photo_path}\")\n\n# \u4f7f\u7528\u524d\u7f6e\u76f8\u673a\u548c\u81ea\u52a8\u5bf9\u7126\u62cd\u7167\ncamera_path = droid.cameraCapturePicture(\"/sdcard/selfie.jpg\", cameraId=1, useAutoFocus=True).result\nprint(f\"Front camera photo: {camera_path}\")\n\n# \u63a7\u5236\u95ea\u5149\u706f\ndroid.cameraSetTorchMode(True)  # \u6253\u5f00\u95ea\u5149\u706f\n\n# \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\nvideo_path = droid.takeVideo(\"/sdcard/video.mp4\", quality=3).result\nprint(f\"Video saved: {video_path}\")\n\n# \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\nvideo_path = droid.recorderCaptureVideo(\"/sdcard/movie.mp4\", duration=30, cameraId=0, quality=8).result\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n
      "},{"location":"qsl4a/hardware/recorder/","title":"\u97f3\u9891\u5f55\u5236 API","text":"

      \u4ece\u9ea6\u514b\u98ce\u548c\u8bbe\u5907\u5c4f\u5e55\u5f55\u5236\u97f3\u9891\u3002

      "},{"location":"qsl4a/hardware/recorder/#_1","title":"\u97f3\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recordaudio","title":"recordAudio()","text":"

      \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\u3002

      recordAudio()\n

      \u8fd4\u56de\uff1a \u5f55\u5236\u7684\u97f3\u9891\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/hardware/recorder/#recorderstartmicrophone","title":"recorderStartMicrophone()","text":"

      \u5f00\u59cb\u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\u3002

      recorderStartMicrophone(targetPath=None)\n

      \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u5f55\u5236\u7684\u8def\u5f84

      "},{"location":"qsl4a/hardware/recorder/#_2","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

      \u5f00\u59cb\u5e26\u97f3\u9891\u7684\u5c4f\u5e55\u5f55\u5236\u3002

      recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

      \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\u97f3\u9891\uff09 - targetPixels (int): \u76ee\u6807\u5206\u8fa8\u7387\uff08\u50cf\u7d20\uff09 - frameRate (int): \u6bcf\u79d2\u5e27\u6570\uff08\u9ed8\u8ba4\uff1a30\uff09 - bitRate (int): \u89c6\u9891\u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa\u89c6\u9891 - autoStart (bool): \u7acb\u5373\u5f00\u59cb\u5f55\u5236

      \u8fd4\u56de\uff1a \u64cd\u4f5c\u7ed3\u679c

      "},{"location":"qsl4a/hardware/recorder/#recorderstart","title":"recorderStart()","text":"

      \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\uff08\u5f53 autoStart=False \u65f6\uff09\u3002

      recorderStart()\n
      "},{"location":"qsl4a/hardware/recorder/#recorderpause","title":"recorderPause()","text":"

      \u6682\u505c\u6b63\u5728\u8fdb\u884c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

      recorderPause()\n
      "},{"location":"qsl4a/hardware/recorder/#recorderresume","title":"recorderResume()","text":"

      \u6062\u590d\u6682\u505c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

      recorderResume()\n
      "},{"location":"qsl4a/hardware/recorder/#_3","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/recorder/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

      \u5f00\u59cb\u76d1\u63a7\u97f3\u91cf\u7ea7\u522b\u3002

      recorderSoundVolumeDetect(interval=100)\n

      \u53c2\u6570\uff1a - interval (int): \u68c0\u6d4b\u95f4\u9694\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a100\uff09

      "},{"location":"qsl4a/hardware/recorder/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

      \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

      recorderSoundVolumeGetDb()\n

      \u8fd4\u56de\uff1a \u5f53\u524d\u97f3\u91cf\u7ea7\u522b\uff08dB\uff09

      "},{"location":"qsl4a/hardware/recorder/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\nprint(\"Recording audio...\")\naudio_path = droid.recordAudio().result\nprint(f\"Saved to: {audio_path}\")\n\n# \u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\ndroid.recorderStartMicrophone(\"/sdcard/my_recording.mp3\")\ntime.sleep(5)\ndroid.recorderStop()\n\n# \u5e26\u97f3\u9891\u5f55\u5236\u5c4f\u5e55\nprint(\"Starting screen recording...\")\ndroid.recorderStartScreenRecord(\n    path=\"/sdcard/screen_record.mp4\",\n    audio=1,\n    frameRate=30,\n    autoStart=True\n)\ntime.sleep(10)\ndroid.recorderStop()\n\n# \u76d1\u63a7\u97f3\u91cf\ndroid.recorderSoundVolumeDetect(interval=100)\ntime.sleep(3)\nvolume = droid.recorderSoundVolumeGetDb().result\nprint(f\"Current volume: {volume} dB\")\n
      "},{"location":"qsl4a/hardware/usbserial/","title":"USB \u4e3b\u673a\u4e32\u884c API","text":"

      \u4e0e USB \u4e32\u884c\u8bbe\u5907\u901a\u4fe1\uff08\u9700\u8981 USB OTG \u652f\u6301\u548c Android 3.1+\uff09\u3002

      "},{"location":"qsl4a/hardware/usbserial/#usb","title":"USB \u4e32\u884c\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialopen","title":"usbHostSerialOpen()","text":"

      \u6253\u5f00\u4e0e USB \u4e32\u884c\u8bbe\u5907\u7684\u8fde\u63a5\u3002

      usbHostSerialOpen(device, baudRate=9600)\n

      \u53c2\u6570\uff1a - device (str): USB \u8bbe\u5907\u8def\u5f84\u6216\u6807\u8bc6\u7b26 - baudRate (int): \u6ce2\u7279\u7387\uff08\u9ed8\u8ba4\uff1a9600\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u6253\u5f00\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialclose","title":"usbHostSerialClose()","text":"

      \u5173\u95ed USB \u4e32\u884c\u8fde\u63a5\u3002

      usbHostSerialClose()\n
      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialread","title":"usbHostSerialRead()","text":"

      \u4ece USB \u4e32\u884c\u8bfb\u53d6\u6570\u636e\u3002

      usbHostSerialRead(bufferSize=1024)\n

      \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570\uff08\u9ed8\u8ba4\uff1a1024\uff09

      \u8fd4\u56de\uff1a \u8bfb\u53d6\u7684\u6570\u636e\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwrite","title":"usbHostSerialWrite()","text":"

      \u5411 USB \u4e32\u884c\u5199\u5165\u6570\u636e\u3002

      usbHostSerialWrite(data)\n

      \u53c2\u6570\uff1a - data (str): \u8981\u5199\u5165\u7684\u5b57\u7b26\u4e32\u6570\u636e

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialavailable","title":"usbHostSerialAvailable()","text":"

      \u68c0\u67e5\u662f\u5426\u6709\u53ef\u8bfb\u53d6\u7684\u6570\u636e\u3002

      usbHostSerialAvailable()\n

      \u8fd4\u56de\uff1a \u53ef\u7528\u5b57\u8282\u6570

      "},{"location":"qsl4a/hardware/usbserial/#_1","title":"\u914d\u7f6e\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetbaudrate","title":"usbHostSerialSetBaudRate()","text":"

      \u8bbe\u7f6e\u6ce2\u7279\u7387\u3002

      usbHostSerialSetBaudRate(baudRate)\n

      \u53c2\u6570\uff1a - baudRate (int): \u6ce2\u7279\u7387

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetdatabits","title":"usbHostSerialSetDataBits()","text":"

      \u8bbe\u7f6e\u6570\u636e\u4f4d\uff085\u30016\u30017 \u6216 8\uff09\u3002

      usbHostSerialSetDataBits(dataBits)\n

      \u53c2\u6570\uff1a - dataBits (int): \u6570\u636e\u4f4d\uff085-8\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetstopbits","title":"usbHostSerialSetStopBits()","text":"

      \u8bbe\u7f6e\u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09\u3002

      usbHostSerialSetStopBits(stopBits)\n

      \u53c2\u6570\uff1a - stopBits (float): \u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetparity","title":"usbHostSerialSetParity()","text":"

      \u8bbe\u7f6e\u6821\u9a8c\u4f4d\uff08\u65e0\u3001\u5947\u3001\u5076\u3001\u6807\u8bb0\u3001\u7a7a\u683c\uff09\u3002

      usbHostSerialSetParity(parity)\n

      \u53c2\u6570\uff1a - parity (str): \u6821\u9a8c\u6a21\u5f0f\uff08'none'\u3001'odd'\u3001'even'\u3001'mark'\u3001'space'\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetflowcontrol","title":"usbHostSerialSetFlowControl()","text":"

      \u8bbe\u7f6e\u6d41\u63a7\u5236\uff08\u65e0\u3001\u786c\u4ef6\u3001\u8f6f\u4ef6\uff09\u3002

      usbHostSerialSetFlowControl(flowControl)\n

      \u53c2\u6570\uff1a - flowControl (str): \u6d41\u63a7\u5236\u6a21\u5f0f\uff08'none'\u3001'hardware'\u3001'software'\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialreadhex","title":"usbHostSerialReadHex()","text":"

      \u4ee5\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u8bfb\u53d6\u6570\u636e\u3002

      usbHostSerialReadHex(bufferSize=1024)\n

      \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570

      \u8fd4\u56de\uff1a \u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwritehex","title":"usbHostSerialWriteHex()","text":"

      \u4ece\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u5199\u5165\u6570\u636e\u3002

      usbHostSerialWriteHex(hexString)\n

      \u53c2\u6570\uff1a - hexString (str): \u8981\u5199\u5165\u7684\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/hardware/usbserial/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6253\u5f00 USB \u4e32\u884c\u8fde\u63a5\nif droid.usbHostSerialOpen(\"/dev/bus/usb/001/001\", 115200).result:\n    print(\"USB serial opened\")\n\n    # \u5199\u5165\u6570\u636e\n    droid.usbHostSerialWrite(\"AT\\r\")\n\n    # \u8bfb\u53d6\u54cd\u5e94\n    response = droid.usbHostSerialRead(1024).result\n    print(f\"Response: {response}\")\n\n    # \u6216\u4f7f\u7528\u5341\u516d\u8fdb\u5236\n    droid.usbHostSerialWriteHex(\"41540D0A\")  # \"AT\\r\\n\"\n\n    # \u5173\u95ed\u8fde\u63a5\n    droid.usbHostSerialClose()\n

      \u6ce8\u610f\uff1a USB \u4e32\u884c\u9700\u8981\uff1a - Android 3.1+ (API 12) - USB OTG \u7ebf/\u9002\u914d\u5668 - \u8bbe\u5907\u4e0a\u7684 USB \u4e3b\u673a\u6a21\u5f0f\u652f\u6301 - \u517c\u5bb9\u7684\u4e32\u884c\u8bbe\u5907

      "},{"location":"qsl4a/hardware/webcam/","title":"\u7f51\u7edc\u6444\u50cf\u5934 API","text":"

      \u4f7f\u7528 MJPEG \u4ece\u8bbe\u5907\u76f8\u673a\u6d41\u5f0f\u4f20\u8f93\u89c6\u9891\u3002

      "},{"location":"qsl4a/hardware/webcam/#mjpeg","title":"MJPEG \u6d41\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#webcamstart","title":"webcamStart()","text":"

      \u4ece\u7f51\u7edc\u6444\u50cf\u5934\u542f\u52a8 MJPEG \u6d41\u3002

      webcamStart(resolutionLevel=0, jpegQuality=20, port=0)\n

      \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf 1-100\uff08\u9ed8\u8ba4\uff1a20\uff09 - port (int): \u7aef\u53e3\u53f7\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\uff09

      \u8fd4\u56de\uff1a \u6d41\u7684 (\u5730\u5740, \u7aef\u53e3) \u5143\u7ec4

      "},{"location":"qsl4a/hardware/webcam/#webcamadjustquality","title":"webcamAdjustQuality()","text":"

      \u8c03\u6574\u6d3b\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u7684\u8d28\u91cf\u3002

      webcamAdjustQuality(resolutionLevel=0, jpegQuality=20)\n

      \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b - jpegQuality (int): JPEG \u8d28\u91cf 1-100

      "},{"location":"qsl4a/hardware/webcam/#webcamstop","title":"webcamStop()","text":"

      \u505c\u6b62\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u3002

      webcamStop()\n
      "},{"location":"qsl4a/hardware/webcam/#_1","title":"\u76f8\u673a\u9884\u89c8\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#camerastartpreview","title":"cameraStartPreview()","text":"

      \u5f00\u59cb\u5e26\u4e8b\u4ef6\u751f\u6210\u7684\u76f8\u673a\u9884\u89c8\u6a21\u5f0f\u3002

      cameraStartPreview(resolutionLevel=0, jpegQuality=20, filepath=None)\n

      \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf\uff08\u9ed8\u8ba4\uff1a20\uff09 - filepath (str, optional): \u4fdd\u5b58\u9884\u89c8\u5e27\u7684\u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      \u6ce8\u610f\uff1a \u751f\u6210\u5e26\u6709\u5e27\u6570\u636e\u7684 'preview' \u4e8b\u4ef6\u3002

      "},{"location":"qsl4a/hardware/webcam/#camerastoppreview","title":"cameraStopPreview()","text":"

      \u505c\u6b62\u76f8\u673a\u9884\u89c8\u3002

      cameraStopPreview()\n
      "},{"location":"qsl4a/hardware/webcam/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\nstream_info = droid.webcamStart(\n    resolutionLevel=0,\n    jpegQuality=30,\n    port=8080\n).result\nprint(f\"Stream available at {stream_info[0]}:{stream_info[1]}\")\n\n# \u6d41\u5f0f\u4f20\u8f93\u65f6\u8c03\u6574\u8d28\u91cf\ntime.sleep(5)\ndroid.webcamAdjustQuality(resolutionLevel=1, jpegQuality=50)\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.webcamStop()\n\n# \u6216\u4f7f\u7528\u9884\u89c8\u6a21\u5f0f\nprint(\"Starting preview...\")\ndroid.cameraStartPreview()\n\n# \u7b49\u5f85\u9884\u89c8\u4e8b\u4ef6\nfor i in range(10):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'preview':\n        print(f\"Got preview frame: {event['data']}\")\n\ndroid.cameraStopPreview()\n
      "},{"location":"qsl4a/media/image/","title":"\u56fe\u50cf\u5904\u7406 API","text":"

      \u538b\u7f29\u548c\u5904\u7406\u56fe\u50cf\u3002

      "},{"location":"qsl4a/media/image/#_1","title":"\u56fe\u50cf\u538b\u7f29","text":""},{"location":"qsl4a/media/image/#imagecompress","title":"imageCompress()","text":"

      \u538b\u7f29\u56fe\u50cf\u6587\u4ef6\u3002

      imageCompress(srcPath, destPath, targetByteSize=0, targetWidth=0, targetHeight=0)\n

      \u53c2\u6570\uff1a - srcPath (str): \u6e90\u56fe\u50cf\u8def\u5f84 - destPath (str): \u8f93\u51fa\u8def\u5f84 - targetByteSize (int): \u76ee\u6807\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff080 = \u65e0\u9650\u5236\uff09 - targetWidth (int): \u76ee\u6807\u5bbd\u5ea6\uff080 = \u539f\u59cb\uff09 - targetHeight (int): \u76ee\u6807\u9ad8\u5ea6\uff080 = \u539f\u59cb\uff09

      \u8fd4\u56de\uff1a \u538b\u7f29\u540e\u7684\u56fe\u50cf\u8def\u5f84

      "},{"location":"qsl4a/media/image/#_2","title":"\u622a\u56fe","text":""},{"location":"qsl4a/media/image/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

      \u622a\u53d6\u5c4f\u5e55\u3002

      imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

      \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

      \u8fd4\u56de\uff1a \u622a\u56fe\u8def\u5f84

      "},{"location":"qsl4a/media/image/#_3","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/image/#videoplay","title":"videoPlay()","text":"

      \u5728\u5168\u5c4f\u6a21\u5f0f\u4e0b\u64ad\u653e\u89c6\u9891\u6587\u4ef6\u3002

      videoPlay(path, wait=True)\n

      \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

      "},{"location":"qsl4a/media/image/#_4","title":"\u6761\u7801\u626b\u63cf","text":""},{"location":"qsl4a/media/image/#scanbarcodefromimage","title":"scanBarcodeFromImage()","text":"

      \u4ece\u56fe\u50cf\u6587\u4ef6\u626b\u63cf\u6761\u7801/\u4e8c\u7ef4\u7801\u3002

      scanBarcodeFromImage(path, compressRatio=0, x=0, y=0, width=0, height=0)\n

      \u53c2\u6570\uff1a - path (str): \u56fe\u50cf\u6587\u4ef6\u8def\u5f84 - compressRatio (int): \u538b\u7f29\u6bd4\uff080 = \u4e0d\u538b\u7f29\uff09 - x, y, width, height (int): \u8981\u626b\u63cf\u7684\u533a\u57df\uff080 = \u5b8c\u6574\u56fe\u50cf\uff09

      \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5185\u5bb9

      "},{"location":"qsl4a/media/image/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n\n# \u538b\u7f29\u56fe\u50cf\ncompressed = droid.imageCompress(\n    \"/sdcard/large_photo.jpg\",\n    \"/sdcard/compressed.jpg\",\n    targetByteSize=102400,  # \u76ee\u6807\u7ea6 100KB\n    targetWidth=1920,\n    targetHeight=1080\n).result\nprint(f\"Saved: {compressed}\")\n\n# \u64ad\u653e\u89c6\u9891\nvideo_path = \"/sdcard/movie.mp4\"\ndroid.videoPlay(video_path, wait=True)\n\n# \u4ece\u56fe\u50cf\u626b\u63cf\u6761\u7801\nresult = droid.scanBarcodeFromImage(\"/sdcard/qr_code.png\").result\nprint(f\"Barcode: {result}\")\n
      "},{"location":"qsl4a/media/mediaplayer/","title":"\u5a92\u4f53\u64ad\u653e\u5668 API","text":"

      \u63a7\u5236\u97f3\u9891\u548c\u89c6\u9891\u64ad\u653e\u3002

      "},{"location":"qsl4a/media/mediaplayer/#_1","title":"\u64ad\u653e\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplay","title":"mediaPlay()","text":"

      \u64ad\u653e\u5a92\u4f53\u6587\u4ef6\u3002

      mediaPlay(url, tag=\"default\", play=True)\n

      \u53c2\u6570\uff1a - url (str): \u5a92\u4f53\u6587\u4ef6\u8def\u5f84\u6216 URL - tag (str): \u64ad\u653e\u5668\u6807\u8bc6\u7b26 - play (bool): \u81ea\u52a8\u5f00\u59cb\u64ad\u653e

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaystart","title":"mediaPlayStart()","text":"

      \u5f00\u59cb\u64ad\u653e\u3002

      mediaPlayStart(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplaypause","title":"mediaPlayPause()","text":"

      \u6682\u505c\u64ad\u653e\u3002

      mediaPlayPause(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplayclose","title":"mediaPlayClose()","text":"

      \u5173\u95ed\u64ad\u653e\u5668\u3002

      mediaPlayClose(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplayseek","title":"mediaPlaySeek()","text":"

      \u8df3\u8f6c\u5230\u4f4d\u7f6e\u3002

      mediaPlaySeek(msec, tag=\"default\")\n

      \u53c2\u6570\uff1a - msec (int): \u4f4d\u7f6e\uff08\u6beb\u79d2\uff09

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaysetlooping","title":"mediaPlaySetLooping()","text":"

      \u8bbe\u7f6e\u5faa\u73af\u6a21\u5f0f\u3002

      mediaPlaySetLooping(enabled, tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#_2","title":"\u64ad\u653e\u5668\u4fe1\u606f","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplayinfo","title":"mediaPlayInfo()","text":"

      \u83b7\u53d6\u64ad\u653e\u4fe1\u606f\u3002

      mediaPlayInfo(tag=\"default\")\n

      \u8fd4\u56de\uff1a \u5305\u542b\u65f6\u957f\u3001\u4f4d\u7f6e\u7b49\u7684\u5b57\u5178

      "},{"location":"qsl4a/media/mediaplayer/#mediaisplaying","title":"mediaIsPlaying()","text":"

      \u68c0\u67e5\u662f\u5426\u6b63\u5728\u64ad\u653e\u3002

      mediaIsPlaying(tag=\"default\")\n

      \u8fd4\u56de\uff1a True/False

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaylist","title":"mediaPlayList()","text":"

      \u5217\u51fa\u6d3b\u52a8\u64ad\u653e\u5668\u3002

      mediaPlayList()\n
      "},{"location":"qsl4a/media/mediaplayer/#_3","title":"\u97f3\u91cf\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#getmediavolume","title":"getMediaVolume()","text":"

      \u83b7\u53d6\u5a92\u4f53\u97f3\u91cf\u3002

      getMediaVolume()\n

      \u8fd4\u56de\uff1a \u97f3\u91cf\u7ea7\u522b\uff080-15\uff09

      "},{"location":"qsl4a/media/mediaplayer/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

      getMaxMediaVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#getringervolume","title":"getRingerVolume()","text":"

      \u83b7\u53d6\u94c3\u58f0\u97f3\u91cf\u3002

      getRingerVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

      getMaxRingerVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#_4","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/mediaplayer/#videoplay","title":"videoPlay()","text":"

      \u5168\u5c4f\u64ad\u653e\u89c6\u9891\u3002

      videoPlay(path, wait=True)\n

      \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210

      "},{"location":"qsl4a/media/mediaplayer/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u64ad\u653e\u97f3\u9891\ndroid.mediaPlay(\"/sdcard/music.mp3\", tag=\"music\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.mediaIsPlaying(\"music\").result:\n    info = droid.mediaPlayInfo(\"music\").result\n    print(f\"Playing: {info}\")\n\n# \u8df3\u8f6c\u5230 30 \u79d2\ndroid.mediaPlaySeek(30000, \"music\")\n\n# \u5173\u95ed\ndroid.mediaPlayClose(\"music\")\n\n# \u64ad\u653e\u89c6\u9891\ndroid.videoPlay(\"/sdcard/movie.mp4\", wait=True)\n
      "},{"location":"qsl4a/special/cipher/","title":"\u5bc6\u7801 API","text":"

      \u7528\u4e8e\u5b89\u5168\u6570\u636e\u5b58\u50a8\u7684\u52a0\u5bc6\u548c\u89e3\u5bc6\u5de5\u5177\u3002

      "},{"location":"qsl4a/special/cipher/#_1","title":"\u521d\u59cb\u5316","text":""},{"location":"qsl4a/special/cipher/#cipherinit","title":"cipherInit()","text":"

      \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u548c\u7b97\u6cd5\u521d\u59cb\u5316\u5bc6\u7801\u5668\u3002

      cipherInit(key, algorithm=\"AES/CBC/PKCS5Padding\", encodingFormat=\"\", initialVector=\"\")\n

      \u53c2\u6570\uff1a - key (str or bytes): \u52a0\u5bc6\u5bc6\u94a5 - algorithm (str): \u5bc6\u7801\u7b97\u6cd5\uff08\u9ed8\u8ba4\uff1a\"AES/CBC/PKCS5Padding\"\uff09 - encodingFormat (str): \u7f16\u7801\u683c\u5f0f - initialVector (str or bytes): \u52a0\u5bc6\u7684\u521d\u59cb\u5411\u91cf

      \u8fd4\u56de\uff1a \u521d\u59cb\u5316\u7ed3\u679c

      \u6ce8\u610f\uff1a \u5fc5\u987b\u5728\u4efb\u4f55\u52a0\u5bc6/\u89e3\u5bc6\u64cd\u4f5c\u4e4b\u524d\u8c03\u7528\u3002

      "},{"location":"qsl4a/special/cipher/#_2","title":"\u52a0\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#encryptstring","title":"encryptString()","text":"

      \u52a0\u5bc6\u5b57\u7b26\u4e32\u3002

      encryptString(plainText)\n

      \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c

      \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/special/cipher/#encryptbytes","title":"encryptBytes()","text":"

      \u52a0\u5bc6\u5b57\u8282\u6570\u636e\u3002

      encryptBytes(data)\n

      \u53c2\u6570\uff1a - data (bytes): \u8981\u52a0\u5bc6\u7684\u6570\u636e

      \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u8282

      "},{"location":"qsl4a/special/cipher/#encryptstringtofile","title":"encryptStringToFile()","text":"

      \u52a0\u5bc6\u5b57\u7b26\u4e32\u5230\u6587\u4ef6\u3002

      encryptStringToFile(plainText, filePath)\n

      \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c - filePath (str): \u8f93\u51fa\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/special/cipher/#encryptbytestofile","title":"encryptBytesToFile()","text":"

      \u52a0\u5bc6\u5b57\u8282\u5230\u6587\u4ef6\u3002

      encryptBytesToFile(data, filePath)\n
      "},{"location":"qsl4a/special/cipher/#_3","title":"\u89e3\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#decryptstring","title":"decryptString()","text":"

      \u89e3\u5bc6\u4e3a\u5b57\u7b26\u4e32\u3002

      decryptString(cipherText)\n

      \u53c2\u6570\uff1a - cipherText (str): \u52a0\u5bc6\u7684\u6587\u672c

      \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/special/cipher/#decryptbytes","title":"decryptBytes()","text":"

      \u89e3\u5bc6\u4e3a\u5b57\u8282\u3002

      decryptBytes(data)\n

      \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u8282

      "},{"location":"qsl4a/special/cipher/#decryptfiletostring","title":"decryptFileToString()","text":"

      \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u7b26\u4e32\u3002

      decryptFileToString(filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryptfiletobytes","title":"decryptFileToBytes()","text":"

      \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u8282\u3002

      decryptFileToBytes(filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryptfile","title":"decryptFile()","text":"

      \u89e3\u5bc6\u6587\u4ef6\u5230\u6587\u4ef6\u3002

      decryptFile(srcPath, destPath)\n
      "},{"location":"qsl4a/special/cipher/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u521d\u59cb\u5316\u5bc6\u7801\u5668\ndroid.cipherInit(\"my_secret_key_1234\")\n\n# \u52a0\u5bc6\u5b57\u7b26\u4e32\nencrypted = droid.encryptString(\"Secret message!\").result\nprint(f\"Encrypted: {encrypted}\")\n\n# \u89e3\u5bc6\u5b57\u7b26\u4e32\ndecrypted = droid.decryptString(encrypted).result\nprint(f\"Decrypted: {decrypted}\")\n\n# \u52a0\u5bc6\u5230\u6587\u4ef6\ndroid.encryptStringToFile(\"My secret data\", \"/sdcard/secret.dat\")\n\n# \u4ece\u6587\u4ef6\u89e3\u5bc6\ndata = droid.decryptFileToString(\"/sdcard/secret.dat\").result\nprint(data)\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u7b97\u6cd5\u548c IV \u521d\u59cb\u5316\ndroid.cipherInit(\n    key=\"my_key\",\n    algorithm=\"AES/CBC/PKCS5Padding\",\n    initialVector=\"0123456789abcdef\"\n)\n
      "},{"location":"qsl4a/special/pgptai/","title":"PGPT AI API","text":"

      \u8bed\u97f3\u8f6c\u6587\u672c\u548c AI \u670d\u52a1\u96c6\u6210\u3002

      "},{"location":"qsl4a/special/pgptai/#_1","title":"\u5148\u51b3\u6761\u4ef6","text":"
      pip install pgptAI\n
      "},{"location":"qsl4a/special/pgptai/#_2","title":"\u8bed\u97f3\u8bc6\u522b","text":""},{"location":"qsl4a/special/pgptai/#speechtotext","title":"speechToText()","text":"

      \u5c06\u8bed\u97f3\u8f6c\u6362\u4e3a\u6587\u672c\u3002

      speechToText(RecordSecond=10, AmrFile=None, Language=None)\n

      \u53c2\u6570\uff1a - RecordSecond (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09 - AmrFile (str, optional): \u73b0\u6709\u97f3\u9891\u6587\u4ef6\u8def\u5f84 - Language (str, optional): \u8bed\u8a00\u4ee3\u7801\uff08'en'\u3001'zh'\uff09

      \u8fd4\u56de\uff1a \u8f6c\u5f55\u7684\u6587\u672c

      "},{"location":"qsl4a/special/pgptai/#_3","title":"\u6587\u672c\u8f6c\u8bed\u97f3","text":""},{"location":"qsl4a/special/pgptai/#texttospeech","title":"textToSpeech()","text":"

      \u5c06\u6587\u672c\u8f6c\u6362\u4e3a\u8bed\u97f3\u5e76\u53ef\u9009\u5730\u64ad\u653e\u3002

      textToSpeech(Text, AutoPlay=True, WavFile=None, VoiceName=None)\n

      \u53c2\u6570\uff1a - Text (str): \u8981\u8f6c\u6362\u4e3a\u8bed\u97f3\u7684\u6587\u672c - AutoPlay (bool): \u81ea\u52a8\u64ad\u653e\u751f\u6210\u7684\u97f3\u9891\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - WavFile (str, optional): \u4fdd\u5b58 WAV \u6587\u4ef6\u7684\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u4e34\u65f6\u6587\u4ef6 - VoiceName (str, optional): \u8981\u4f7f\u7528\u7684\u8bed\u97f3\u540d\u79f0\uff08\u4f8b\u5982 'en-US-JennyNeural'\u3001'zh-CN-XiaoxiaoNeural'\uff09

      \u8fd4\u56de\uff1a \u5305\u542b\u8bed\u97f3\u5408\u6210\u7ed3\u679c\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - text: \u8f93\u5165\u6587\u672c - url: \u4e0b\u8f7d\u97f3\u9891\u6587\u4ef6\u7684 URL - WavFile: \u4fdd\u5b58\u7684 WAV \u6587\u4ef6\u8def\u5f84\uff08\u5982\u679c\u672c\u5730\u4fdd\u5b58\uff09

      "},{"location":"qsl4a/special/pgptai/#_4","title":"\u914d\u7f6e","text":"

      API \u4f7f\u7528\u4ee5\u4e0b\u914d\u7f6e\u6587\u4ef6\u4e2d\u7684\u914d\u7f6e\uff1a/storage/emulated/0/Android/data/org.qpython.qpy/files/apigpt.conf\uff1a

      [speech]\nspeech_key = your_api_key\n

      \u9ed8\u8ba4\u8bed\u97f3\u8bbe\u7f6e\uff1a - \u82f1\u8bed\uff1aen-US-JennyNeural - \u4e2d\u6587\uff1azh-CN-XiaoxiaoNeural

      "},{"location":"qsl4a/special/pgptai/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5f55\u5236\u5e76\u8f6c\u5f55\nprint(\"Recording for 5 seconds...\")\ntext = droid.speechToText(RecordSecond=5, Language='en').result\nprint(f\"You said: {text}\")\n\n# \u8f6c\u5f55\u73b0\u6709\u6587\u4ef6\ntext = droid.speechToText(AmrFile=\"/sdcard/recording.amr\").result\nprint(f\"Transcription: {text}\")\n\n# \u6587\u672c\u8f6c\u8bed\u97f3\ndroid.textToSpeech(\"Hello, this is a test message.\", AutoPlay=True, Language='en')\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u8bed\u97f3\u5e76\u4fdd\u5b58\u5230\u6587\u4ef6\u7684\u6587\u672c\u8f6c\u8bed\u97f3\nresult = droid.textToSpeech(\n    \"Welcome to QPython!\",\n    AutoPlay=False,\n    WavFile=\"/sdcard/welcome.wav\",\n    VoiceName=\"en-US-JennyNeural\"\n).result\nprint(f\"Audio saved to: {result.get('WavFile')}\")\n
      "},{"location":"qsl4a/special/pgptai/#_6","title":"\u7c7b\u4f7f\u7528","text":"
      from androidhelper.pgptai import pgptai\nimport androidhelper\n\ndroid = androidhelper.Android()\nai = pgptai(droid)\n\n# \u4f7f\u7528\u8bed\u97f3\u8bc6\u522b\ntext = ai.speechToText(RecordSecond=10)\n
      "},{"location":"qsl4a/storage/clipboard/","title":"\u526a\u8d34\u677f API","text":"

      \u590d\u5236\u548c\u7c98\u8d34\u6587\u672c\u5230\u7cfb\u7edf\u526a\u8d34\u677f\u3002

      "},{"location":"qsl4a/storage/clipboard/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/clipboard/#setclipboard","title":"setClipboard()","text":"

      \u590d\u5236\u6587\u672c\u5230\u526a\u8d34\u677f\u3002

      setClipboard(text)\n

      \u53c2\u6570\uff1a - text (str): \u8981\u590d\u5236\u7684\u6587\u672c

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/clipboard/#getclipboard","title":"getClipboard()","text":"

      \u4ece\u526a\u8d34\u677f\u83b7\u53d6\u6587\u672c\u3002

      getClipboard()\n

      \u8fd4\u56de\uff1a \u526a\u8d34\u677f\u6587\u672c

      "},{"location":"qsl4a/storage/clipboard/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u590d\u5236\u5230\u526a\u8d34\u677f\ndroid.setClipboard(\"Hello from QPython!\")\n\n# \u4ece\u526a\u8d34\u677f\u7c98\u8d34\ntext = droid.getClipboard().result\nprint(f\"Clipboard: {text}\")\n
      "},{"location":"qsl4a/storage/documentfile/","title":"DocumentFile API","text":"

      \u4f7f\u7528 SAF\uff08\u5b58\u50a8\u8bbf\u95ee\u6846\u67b6\uff09\u8fdb\u884c\u6587\u4ef6\u64cd\u4f5c\uff0c\u652f\u6301 Android 4.4+\u3002

      "},{"location":"qsl4a/storage/documentfile/#_1","title":"\u76ee\u5f55\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilemkdir","title":"documentFileMkdir()","text":"

      \u521b\u5efa\u76ee\u5f55\u3002

      documentFileMkdir(Dir)\n

      \u53c2\u6570\uff1a - Dir (str): \u76ee\u5f55\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/documentfile/#documentfilelistfiles","title":"documentFileListFiles()","text":"

      \u5217\u51fa\u76ee\u5f55\u4e2d\u7684\u6587\u4ef6\u3002

      documentFileListFiles(Folder)\n

      \u8fd4\u56de\uff1a \u6587\u4ef6\u5217\u8868

      "},{"location":"qsl4a/storage/documentfile/#_2","title":"\u6587\u4ef6\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileexists","title":"documentFileExists()","text":"

      \u68c0\u67e5\u6587\u4ef6\u6216\u76ee\u5f55\u662f\u5426\u5b58\u5728\u3002

      documentFileExists(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u6216\u76ee\u5f55\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u5b58\u5728\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/storage/documentfile/#documentfileisfile","title":"documentFileIsFile()","text":"

      \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u6587\u4ef6\u3002

      documentFileIsFile(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u662f\u6587\u4ef6\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u6587\u4ef6\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

      "},{"location":"qsl4a/storage/documentfile/#documentfileisdirectory","title":"documentFileIsDirectory()","text":"

      \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u76ee\u5f55\u3002

      documentFileIsDirectory(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u662f\u76ee\u5f55\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u76ee\u5f55\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

      "},{"location":"qsl4a/storage/documentfile/#documentfiledelete","title":"documentFileDelete()","text":"

      \u5220\u9664\u6587\u4ef6\u6216\u76ee\u5f55\u3002

      documentFileDelete(FileOrTree)\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/documentfile/#documentfilerenameto","title":"documentFileRenameTo()","text":"

      \u91cd\u547d\u540d\u6216\u79fb\u52a8\u6587\u4ef6\u3002

      documentFileRenameTo(Src, Dest)\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/documentfile/#documentfilecopy","title":"documentFileCopy()","text":"

      \u590d\u5236\u6587\u4ef6\u3002

      documentFileCopy(SrcFileOrTree, DestFileOrTree)\n
      "},{"location":"qsl4a/storage/documentfile/#_3","title":"\u6d41\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileinputstream","title":"documentFileInputStream()","text":"

      \u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9\u3002

      documentFileInputStream(srcFile, EncodingFormat=\"\", skip=None, length=None)\n

      \u53c2\u6570\uff1a - srcFile (str): \u6e90\u6587\u4ef6 - EncodingFormat (str): \"UTF-8\"\u3001\"GBK\"\u3001\"Base64\" \u6216\u7a7a\u5b57\u7b26\u4e32\u8868\u793a\u5b57\u8282 - skip (int): \u4ece\u5f00\u5934\u8df3\u8fc7\u7684\u5b57\u8282\u6570 - length (int): \u8bfb\u53d6\u957f\u5ea6

      \u8fd4\u56de\uff1a \u6587\u4ef6\u5185\u5bb9

      "},{"location":"qsl4a/storage/documentfile/#documentfileoutputstream","title":"documentFileOutputStream()","text":"

      \u5199\u5165\u6587\u4ef6\u5185\u5bb9\u3002

      documentFileOutputStream(destFile, src, EncodingFormat=\"\", append=None)\n

      \u53c2\u6570\uff1a - destFile (str): \u76ee\u6807\u6587\u4ef6 - src: \u8981\u5199\u5165\u7684\u6570\u636e - EncodingFormat (str): \u7f16\u7801\u683c\u5f0f - append (bool): \u8ffd\u52a0\u6a21\u5f0f

      "},{"location":"qsl4a/storage/documentfile/#_4","title":"\u6587\u4ef6\u4fe1\u606f","text":""},{"location":"qsl4a/storage/documentfile/#documentfilelength","title":"documentFileLength()","text":"

      \u83b7\u53d6\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\u3002

      documentFileLength(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

      "},{"location":"qsl4a/storage/documentfile/#documentfilelastmodified","title":"documentFileLastModified()","text":"

      \u83b7\u53d6\u6700\u540e\u4fee\u6539\u65f6\u95f4\u3002

      documentFileLastModified(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u65f6\u95f4\u6233\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

      "},{"location":"qsl4a/storage/documentfile/#documentfilegetstat","title":"documentFileGetStat()","text":"

      \u83b7\u53d6\u5168\u9762\u7684\u6587\u4ef6\u7edf\u8ba1\u4fe1\u606f\u3002

      documentFileGetStat(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5305\u542b\u957f\u5ea6\u3001\u6700\u540e\u4fee\u6539\u65f6\u95f4\u548c\u8bfb/\u5199\u6743\u9650\u7684\u5b57\u5178\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

      "},{"location":"qsl4a/storage/documentfile/#uri","title":"URI \u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilegeturi","title":"documentFileGetUri()","text":"

      \u4ece\u8def\u5f84\u83b7\u53d6 URI\u3002

      documentFileGetUri(path, isDirectory=None)\n
      "},{"location":"qsl4a/storage/documentfile/#documentfileshowopen","title":"documentFileShowOpen()","text":"

      \u663e\u793a\u6587\u4ef6\u9009\u62e9\u5668\u3002

      documentFileShowOpen()\n

      \u8fd4\u56de\uff1a \u9009\u62e9\u7684\u6587\u4ef6 URI

      "},{"location":"qsl4a/storage/documentfile/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u76ee\u5f55\ndroid.documentFileMkdir(\"/sdcard/MyFolder\")\n\n# \u5217\u51fa\u6587\u4ef6\nfiles = droid.documentFileListFiles(\"/sdcard\").result\nfor f in files:\n    print(f)\n\n# \u8bfb\u53d6\u6587\u4ef6\ncontent = droid.documentFileInputStream(\n    \"/sdcard/test.txt\",\n    EncodingFormat=\"UTF-8\"\n).result\nprint(content)\n\n# \u5199\u5165\u6587\u4ef6\ndroid.documentFileOutputStream(\n    \"/sdcard/output.txt\",\n    \"Hello World\",\n    EncodingFormat=\"UTF-8\"\n)\n
      "},{"location":"qsl4a/storage/preferences/","title":"\u504f\u597d\u8bbe\u7f6e API","text":"

      \u4f7f\u7528 Android SharedPreferences \u5b58\u50a8\u548c\u68c0\u7d22\u6570\u636e\u3002

      "},{"location":"qsl4a/storage/preferences/#_1","title":"\u504f\u597d\u8bbe\u7f6e\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/preferences/#prefgetvalue","title":"prefGetValue()","text":"

      \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u8bfb\u53d6\u503c\u3002

      prefGetValue(key, filename=None)\n

      \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c\uff08\u4efb\u610f\u7c7b\u578b\uff09

      "},{"location":"qsl4a/storage/preferences/#prefputvalue","title":"prefPutValue()","text":"

      \u5199\u5165\u503c\u5230\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u3002

      prefPutValue(key, value, filename=None)\n

      \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - value (object): \u8981\u5b58\u50a8\u7684\u503c - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      "},{"location":"qsl4a/storage/preferences/#prefgetall","title":"prefGetAll()","text":"

      \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\u503c\u3002

      prefGetAll(filename=None)\n

      \u53c2\u6570\uff1a - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      \u8fd4\u56de\uff1a \u6240\u6709\u504f\u597d\u7684\u6620\u5c04

      "},{"location":"qsl4a/storage/preferences/#prefremovevalue","title":"prefRemoveValue()","text":"

      \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u4e2d\u79fb\u9664\u503c\u3002

      prefRemoveValue(key, filename=None)\n

      \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      "},{"location":"qsl4a/storage/preferences/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b58\u50a8\u503c\ndroid.prefPutValue(\"username\", \"alice\")\ndroid.prefPutValue(\"score\", 100)\ndroid.prefPutValue(\"enabled\", True)\n\n# \u8bfb\u53d6\u7279\u5b9a\u503c\nusername = droid.prefGetValue(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\nall_prefs = droid.prefGetAll().result\nprint(f\"All prefs: {all_prefs}\")\n\n# \u79fb\u9664\u503c\ndroid.prefRemoveValue(\"score\")\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u6587\u4ef6\u540d\ndroid.prefPutValue(\"token\", \"abc123\", filename=\"auth.prefs\")\ntoken = droid.prefGetValue(\"token\", filename=\"auth.prefs\").result\n
      "},{"location":"qsl4a/system/activityresult/","title":"Activity Result API","text":"

      \u4e3a\u901a\u8fc7 startActivityForResult \u542f\u52a8\u7684\u811a\u672c\u8bbe\u7f6e activity \u7ed3\u679c\u3002

      "},{"location":"qsl4a/system/activityresult/#_1","title":"\u7ed3\u679c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/activityresult/#setresultboolean","title":"setResultBoolean()","text":"

      \u8bbe\u7f6e\u5e03\u5c14\u7ed3\u679c\u3002

      setResultBoolean(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (bool): \u5e03\u5c14\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultbyte","title":"setResultByte()","text":"

      \u8bbe\u7f6e\u5b57\u8282\u7ed3\u679c\u3002

      setResultByte(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u5b57\u8282\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultshort","title":"setResultShort()","text":"

      \u8bbe\u7f6e\u77ed\u6574\u6570\u7ed3\u679c\u3002

      setResultShort(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u77ed\u6574\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultchar","title":"setResultChar()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u7ed3\u679c\u3002

      setResultChar(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultinteger","title":"setResultInteger()","text":"

      \u8bbe\u7f6e\u6574\u6570\u7ed3\u679c\u3002

      setResultInteger(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u6574\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultlong","title":"setResultLong()","text":"

      \u8bbe\u7f6e\u957f\u6574\u6570\u7ed3\u679c\u3002

      setResultLong(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u957f\u6574\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultfloat","title":"setResultFloat()","text":"

      \u8bbe\u7f6e\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

      setResultFloat(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u6d6e\u70b9\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultdouble","title":"setResultDouble()","text":"

      \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

      setResultDouble(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultstring","title":"setResultString()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u4e32\u7ed3\u679c\u3002

      setResultString(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u4e32\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultbooleanarray","title":"setResultBooleanArray()","text":"

      \u8bbe\u7f6e\u5e03\u5c14\u6570\u7ec4\u7ed3\u679c\u3002

      setResultBooleanArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5e03\u5c14\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultbytearray","title":"setResultByteArray()","text":"

      \u8bbe\u7f6e\u5b57\u8282\u6570\u7ec4\u7ed3\u679c\u3002

      setResultByteArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u8282\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultshortarray","title":"setResultShortArray()","text":"

      \u8bbe\u7f6e\u77ed\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultShortArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u77ed\u6574\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultchararray","title":"setResultCharArray()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u6570\u7ec4\u7ed3\u679c\u3002

      setResultCharArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultintegerarray","title":"setResultIntegerArray()","text":"

      \u8bbe\u7f6e\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultIntegerArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6574\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultlongarray","title":"setResultLongArray()","text":"

      \u8bbe\u7f6e\u957f\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultLongArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u957f\u6574\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultfloatarray","title":"setResultFloatArray()","text":"

      \u8bbe\u7f6e\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultFloatArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6d6e\u70b9\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultdoublearray","title":"setResultDoubleArray()","text":"

      \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultDoubleArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultstringarray","title":"setResultStringArray()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u4e32\u6570\u7ec4\u7ed3\u679c\u3002

      setResultStringArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u4e32\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultserializable","title":"setResultSerializable()","text":"

      \u8bbe\u7f6e\u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u3002

      setResultSerializable(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue: \u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c activity \u540e\uff0c\u8bbe\u7f6e\u7ed3\u679c\n# \u793a\u4f8b\uff1a\u8fd4\u56de\u6210\u529f\u53ca\u6570\u636e\ndroid.setResultInteger(0, 200)  # RESULT_OK\ndroid.setResultString(0, \"Operation completed successfully\")\n\n# \u8fd4\u56de\u6570\u7ec4\u7ed3\u679c\ndroid.setResultIntegerArray(0, [1, 2, 3, 4, 5])\n
      "},{"location":"qsl4a/system/application/","title":"\u5e94\u7528\u7ba1\u7406","text":"

      \u7ba1\u7406\u5e94\u7528\u7a0b\u5e8f\u3001\u542f\u52a8\u5e94\u7528\u548c\u67e5\u8be2\u7cfb\u7edf\u4fe1\u606f\u3002

      "},{"location":"qsl4a/system/application/#_2","title":"\u5e94\u7528\u7a0b\u5e8f\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getapplicationinfo","title":"getApplicationInfo()","text":"

      \u83b7\u53d6\u5e94\u7528\u4fe1\u606f\u3002

      getApplicationInfo(packageName=None)\n

      \u53c2\u6570\uff1a - packageName (str): \u5305\u540d\uff08None = \u5f53\u524d\u5e94\u7528\uff09

      \u8fd4\u56de\uff1a \u5e94\u7528\u4fe1\u606f\u5b57\u5178

      "},{"location":"qsl4a/system/application/#getinstalledpackages","title":"getInstalledPackages()","text":"

      \u83b7\u53d6\u5df2\u5b89\u88c5\u5305\u5217\u8868\u3002

      getInstalledPackages(flag=4)\n

      \u53c2\u6570\uff1a - flag (int): \u5305\u6807\u5fd7\u8fc7\u6ee4\u5668\uff08\u9ed8\u8ba4\uff1a4\uff09

      \u8fd4\u56de\uff1a \u5df2\u5b89\u88c5\u5305\u5217\u8868

      "},{"location":"qsl4a/system/application/#getrunningpackages","title":"getRunningPackages()","text":"

      \u5217\u51fa\u6b63\u5728\u8fd0\u884c\u7684\u5305\u3002

      getRunningPackages()\n

      \u8fd4\u56de\uff1a \u5305\u540d\u5217\u8868

      "},{"location":"qsl4a/system/application/#getlaunchablepackages","title":"getLaunchablePackages()","text":"

      \u83b7\u53d6\u53ef\u542f\u52a8\u5305\u5217\u8868\u3002

      getLaunchablePackages(needClassName=False)\n

      \u53c2\u6570\uff1a - needClassName (bool): \u5305\u542b\u4e3b activity \u7c7b\u540d\uff08\u9ed8\u8ba4\uff1aFalse\uff09

      \u8fd4\u56de\uff1a \u53ef\u542f\u52a8\u5305\u540d\u5217\u8868\u6216\u5305\u542b\u7c7b\u540d\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#_3","title":"\u5e94\u7528\u63a7\u5236","text":""},{"location":"qsl4a/system/application/#launch","title":"launch()","text":"

      \u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u3002

      launch(classname=None, packagename=None, wait=True)\n

      \u53c2\u6570\uff1a - classname (str): \u4e3b activity \u7c7b\u540d - packagename (str): \u5305\u540d - wait (bool): \u7b49\u5f85\u542f\u52a8\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

      \u8fd4\u56de\uff1a \u542f\u52a8\u7ed3\u679c

      "},{"location":"qsl4a/system/application/#forcestoppackage","title":"forceStopPackage()","text":"

      \u5f3a\u5236\u505c\u6b62\u5e94\u7528\u7a0b\u5e8f\u3002

      forceStopPackage(packageName)\n

      \u53c2\u6570\uff1a - packageName (str): \u8981\u505c\u6b62\u7684\u5305\u540d

      "},{"location":"qsl4a/system/application/#_4","title":"\u7248\u672c\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getpackageversion","title":"getPackageVersion()","text":"

      \u83b7\u53d6\u5e94\u7528\u7248\u672c\u540d\u79f0\u3002

      getPackageVersion(packageName)\n

      \u8fd4\u56de\uff1a \u7248\u672c\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"3.2.1\"\uff09

      "},{"location":"qsl4a/system/application/#getpackageversioncode","title":"getPackageVersionCode()","text":"

      \u83b7\u53d6\u5e94\u7528\u7248\u672c\u4ee3\u7801\u3002

      getPackageVersionCode(packageName)\n

      \u8fd4\u56de\uff1a \u7248\u672c\u4ee3\u7801\u6574\u6570

      "},{"location":"qsl4a/system/application/#getconstants","title":"getConstants()","text":"

      \u83b7\u53d6\u7c7b\u5e38\u91cf\u3002

      getConstants(classname)\n

      \u53c2\u6570\uff1a - classname (str): \u5b8c\u6574\u7c7b\u540d

      \u8fd4\u56de\uff1a \u5e38\u91cf\u540d\u548c\u503c\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#_5","title":"\u7cfb\u7edf\u529f\u80fd","text":""},{"location":"qsl4a/system/application/#backgroundprotect","title":"backgroundProtect()","text":"

      \u542f\u7528\u6216\u7981\u7528\u5e94\u7528\u7684\u540e\u53f0\u4fdd\u62a4\u3002

      backgroundProtect(enabled=True)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\u4fdd\u62a4\uff0cFalse \u7981\u7528

      "},{"location":"qsl4a/system/application/#createscriptshortcut","title":"createScriptShortCut()","text":"

      \u4e3a\u811a\u672c\u521b\u5efa\u4e3b\u5c4f\u5e55\u5feb\u6377\u65b9\u5f0f\u3002

      createScriptShortCut(scriptPath, label=None, iconPath=None, scriptArg=None)\n

      \u53c2\u6570\uff1a - scriptPath (str): Python \u811a\u672c\u8def\u5f84 - label (str, optional): \u5feb\u6377\u65b9\u5f0f\u6807\u7b7e - iconPath (str, optional): \u56fe\u6807\u56fe\u50cf\u8def\u5f84 - scriptArg (str, optional): \u4f20\u9012\u7ed9\u811a\u672c\u7684\u53c2\u6570

      "},{"location":"qsl4a/system/application/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getandroidid","title":"getAndroidID()","text":"

      \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

      getAndroidID()\n

      \u8fd4\u56de\uff1a \u552f\u4e00\u7684 Android \u8bbe\u5907 ID \u5b57\u7b26\u4e32

      "},{"location":"qsl4a/system/application/#getsysinfo","title":"getSysInfo()","text":"

      \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\u3002

      getSysInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#getlocale","title":"getLocale()","text":"

      \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u3002

      getLocale()\n

      \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

      "},{"location":"qsl4a/system/application/#getharmonyosinformation","title":"getHarmonyOsInformation()","text":"

      \u5982\u679c\u5728 HarmonyOS \u4e0a\u8fd0\u884c\uff0c\u83b7\u53d6 HarmonyOS \u4fe1\u606f\u3002

      getHarmonyOsInformation()\n

      \u8fd4\u56de\uff1a HarmonyOS \u7248\u672c\u4fe1\u606f\u6216 None

      "},{"location":"qsl4a/system/application/#isexternalstoragemanager","title":"isExternalStorageManager()","text":"

      \u68c0\u67e5\u5e94\u7528\u662f\u5426\u6709\u5916\u90e8\u5b58\u50a8\u7ba1\u7406\u5668\u6743\u9650\u3002

      isExternalStorageManager()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6709\u6743\u9650\u5219\u4e3a True

      "},{"location":"qsl4a/system/application/#_7","title":"\u5185\u5b58\u548c\u663e\u793a","text":""},{"location":"qsl4a/system/application/#getmemoryinfo","title":"getMemoryInfo()","text":"

      \u83b7\u53d6\u5185\u5b58\u4fe1\u606f\u3002

      getMemoryInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#getscreeninfo","title":"getScreenInfo()","text":"

      \u83b7\u53d6\u5c4f\u5e55\u4fe1\u606f\u3002

      getScreenInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#_8","title":"\u6743\u9650","text":""},{"location":"qsl4a/system/application/#checkpermissions","title":"checkPermissions()","text":"

      \u68c0\u67e5\u5f53\u524d\u5e94\u7528\u6743\u9650\u3002

      checkPermissions()\n

      \u8fd4\u56de\uff1a \u6743\u9650\u53ca\u5176\u72b6\u6001\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#requestpermissions","title":"requestPermissions()","text":"

      \u5411\u7528\u6237\u8bf7\u6c42\u6743\u9650\u3002

      requestPermissions(permissions=None)\n

      \u53c2\u6570\uff1a - permissions (list, optional): \u8981\u8bf7\u6c42\u7684\u6743\u9650\u5217\u8868\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8bf7\u6c42\u6240\u6709\u9700\u8981\u7684\u6743\u9650\u3002

      \u8fd4\u56de\uff1a \u6743\u9650\u8bf7\u6c42\u7ed3\u679c

      "},{"location":"qsl4a/system/application/#_9","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/system/application/#showscreenlock","title":"showScreenLock()","text":"

      \u663e\u793a\u5c4f\u5e55\u9501\u5b9a\uff08PIN/\u56fe\u6848/\u5bc6\u7801\u8f93\u5165\uff09\u3002

      showScreenLock()\n
      "},{"location":"qsl4a/system/application/#_10","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\ninfo = droid.getSysInfo().result\nprint(f\"System: {info}\")\n\n# \u83b7\u53d6\u5e94\u7528\u7248\u672c\nversion = droid.getPackageVersion(\"org.qpython.qpy\").result\nprint(f\"QPython version: {version}\")\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u5e94\u7528\napps = droid.getInstalledPackages().result\nprint(f\"Installed apps: {len(apps)}\")\n\n# \u542f\u52a8\u5e94\u7528\ndroid.launch(packagename=\"com.android.settings\")\n\n# \u68c0\u67e5\u6743\u9650\nperms = droid.checkPermissions().result\nprint(f\"Permissions: {perms}\")\n\n# \u8bf7\u6c42\u5b58\u50a8\u6743\u9650\ndroid.requestPermissions([\"android.permission.READ_EXTERNAL_STORAGE\"])\n\n# \u521b\u5efa\u5feb\u6377\u65b9\u5f0f\ndroid.createScriptShortCut(\n    \"/sdcard/my_script.py\",\n    label=\"My Script\",\n    iconPath=\"/sdcard/icon.png\"\n)\n
      "},{"location":"qsl4a/system/battery/","title":"\u7535\u6c60 API","text":"

      \u76d1\u63a7\u8bbe\u5907\u7535\u6c60\u72b6\u6001\u548c\u5065\u5eb7\u72b6\u51b5\u3002

      "},{"location":"qsl4a/system/battery/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/battery/#readbatterydata","title":"readBatteryData()","text":"

      \u83b7\u53d6\u5b8c\u6574\u7684\u7535\u6c60\u4fe1\u606f\u3002

      readBatteryData()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7535\u6c60\u6570\u636e\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/battery/#batterystartmonitoring","title":"batteryStartMonitoring()","text":"

      \u5f00\u59cb\u7535\u6c60\u76d1\u63a7\u3002

      batteryStartMonitoring()\n
      "},{"location":"qsl4a/system/battery/#batterystopmonitoring","title":"batteryStopMonitoring()","text":"

      \u505c\u6b62\u7535\u6c60\u76d1\u63a7\u3002

      batteryStopMonitoring()\n
      "},{"location":"qsl4a/system/battery/#batterygetlevel","title":"batteryGetLevel()","text":"

      \u83b7\u53d6\u7535\u6c60\u767e\u5206\u6bd4\u3002

      batteryGetLevel()\n

      \u8fd4\u56de\uff1a \u6574\u6570\uff080-100\uff09

      "},{"location":"qsl4a/system/battery/#batterygetstatus","title":"batteryGetStatus()","text":"

      \u83b7\u53d6\u5145\u7535\u72b6\u6001\u3002

      batteryGetStatus()\n

      \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u5145\u7535\u4e2d - 3: \u653e\u7535\u4e2d - 4: \u672a\u5145\u7535 - 5: \u5df2\u5145\u6ee1

      "},{"location":"qsl4a/system/battery/#batterygetplugtype","title":"batteryGetPlugType()","text":"

      \u83b7\u53d6\u7535\u6e90\u7c7b\u578b\u3002

      batteryGetPlugType()\n

      \u8fd4\u56de\uff1a - -1: \u672a\u77e5 - 0: \u672a\u63d2\u7535 - 1: AC \u5145\u7535\u5668 - 2: USB \u7aef\u53e3

      "},{"location":"qsl4a/system/battery/#batterygethealth","title":"batteryGetHealth()","text":"

      \u83b7\u53d6\u7535\u6c60\u5065\u5eb7\u72b6\u51b5\u3002

      batteryGetHealth()\n

      \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u826f\u597d - 3: \u8fc7\u70ed - 4: \u635f\u574f - 5: \u8fc7\u538b - 6: \u672a\u6307\u5b9a\u7684\u6545\u969c

      "},{"location":"qsl4a/system/battery/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\nlevel = droid.batteryGetLevel().result\nprint(f\"Battery: {level}%\")\n
      "},{"location":"qsl4a/system/qpyinterface/","title":"QPython \u63a5\u53e3 API","text":"

      \u4ece\u5176\u4ed6\u5e94\u7528\u6267\u884c QPython \u811a\u672c\u548c\u7ba1\u7406\u5171\u4eab\u53d8\u91cf\u3002

      "},{"location":"qsl4a/system/qpyinterface/#_1","title":"\u811a\u672c\u6267\u884c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/qpyinterface/#executeqpy","title":"executeQPy()","text":"

      \u6267\u884c QPython \u811a\u672c\u3002

      executeQPy(path=\"\", arg=None)\n

      \u53c2\u6570\uff1a - path (str): \u811a\u672c\u6587\u4ef6\u8def\u5f84 - arg (str, optional): \u547d\u4ee4\u884c\u53c2\u6570

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#executeqpyassrv","title":"executeQPyAsSrv()","text":"

      \u4f5c\u4e3a\u670d\u52a1\u6267\u884c QPython \u811a\u672c\u3002

      executeQPyAsSrv(path=None)\n

      \u53c2\u6570\uff1a - path (str, optional): \u811a\u672c\u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#executeqpycode","title":"executeQPyCode()","text":"

      \u76f4\u63a5\u6267\u884c Python \u4ee3\u7801\u3002

      executeQPyCode(code=None)\n

      \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#executeqpycodeassrv","title":"executeQPyCodeAsSrv()","text":"

      \u4f5c\u4e3a\u670d\u52a1\u6267\u884c Python \u4ee3\u7801\u3002

      executeQPyCodeAsSrv(code=None)\n

      \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#_2","title":"\u5171\u4eab\u53d8\u91cf","text":"

      \u5171\u4eab\u53d8\u91cf\u5141\u8bb8 QPython \u4e0e\u5176\u4ed6\u5e94\u7528\u4e4b\u95f4\u8fdb\u884c\u901a\u4fe1\u3002

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableset","title":"sharedVariableSet()","text":"

      \u8bbe\u7f6e Java \u5171\u4eab\u53d8\u91cf\u3002

      sharedVariableSet(key, value)\n

      \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d - value (str): \u53d8\u91cf\u503c

      \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableget","title":"sharedVariableGet()","text":"

      \u83b7\u53d6 Java \u5171\u4eab\u53d8\u91cf\u3002

      sharedVariableGet(key)\n

      \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d

      \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableremove","title":"sharedVariableRemove()","text":"

      \u79fb\u9664 Java \u5171\u4eab\u53d8\u91cf\u3002

      sharedVariableRemove(key)\n

      \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u53d8\u91cf\u540d

      \u8fd4\u56de\uff1a \u88ab\u79fb\u9664\u7684\u503c

      "},{"location":"qsl4a/system/qpyinterface/#getlastlog","title":"getLastLog()","text":"

      \u83b7\u53d6 QPython \u7684\u6700\u540e\u65e5\u5fd7\u8f93\u51fa\u3002

      getLastLog()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u65e5\u5fd7\u5185\u5bb9

      "},{"location":"qsl4a/system/qpyinterface/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c\u811a\u672c\ndroid.executeQPy(\"/sdcard/my_script.py\", arg=\"test\")\n\n# \u76f4\u63a5\u6267\u884c\u4ee3\u7801\ncode = \"print('Hello from QPython!')\"\ndroid.executeQPyCode(code)\n\n# \u4f7f\u7528\u5171\u4eab\u53d8\u91cf\ndroid.sharedVariableSet(\"username\", \"alice\")\nusername = droid.sharedVariableGet(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u79fb\u9664\u53d8\u91cf\ndroid.sharedVariableRemove(\"username\")\n\n# \u83b7\u53d6\u6700\u8fd1\u65e5\u5fd7\nlog = droid.getLastLog().result\nprint(f\"Log: {log}\")\n
      "},{"location":"qsl4a/system/sensors/","title":"\u4f20\u611f\u5668 API","text":"

      \u8bbf\u95ee\u8bbe\u5907\u4f20\u611f\u5668\uff0c\u5305\u62ec\u52a0\u901f\u5ea6\u8ba1\u3001\u9640\u87ba\u4eea\u3001\u78c1\u529b\u8ba1\u7b49\u3002

      "},{"location":"qsl4a/system/sensors/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/sensors/#startsensingtimed","title":"startSensingTimed()","text":"

      \u5f00\u59cb\u4f20\u611f\u5668\u76d1\u63a7\u5e76\u8bbe\u7f6e\u65f6\u95f4\u95f4\u9694\u3002

      startSensingTimed(sensorNumber, delayTime)\n

      \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID\uff08\u901a\u5e38\u4e3a 1-3\uff09 - delayTime (int): \u8bfb\u53d6\u4e4b\u95f4\u7684\u5ef6\u8fdf\uff08\u6beb\u79d2\uff09

      "},{"location":"qsl4a/system/sensors/#startsensingthreshold","title":"startSensingThreshold()","text":"

      \u5f00\u59cb\u5e26\u9608\u503c\u89e6\u53d1\u7684\u4f20\u611f\u5668\u76d1\u63a7\u3002

      startSensingThreshold(sensorNumber, threshold, axis)\n

      \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID - threshold (float): \u89e6\u53d1\u9608\u503c - axis (int): \u8981\u76d1\u63a7\u7684\u8f74\uff080=X\uff0c1=Y\uff0c2=Z\uff09

      "},{"location":"qsl4a/system/sensors/#stopsensing","title":"stopSensing()","text":"

      \u505c\u6b62\u6240\u6709\u4f20\u611f\u5668\u76d1\u63a7\u3002

      stopSensing()\n
      "},{"location":"qsl4a/system/sensors/#readsensors","title":"readSensors()","text":"

      \u8bfb\u53d6\u5f53\u524d\u4f20\u611f\u5668\u6570\u636e\u3002

      readSensors()\n

      \u8fd4\u56de\uff1a \u4f20\u611f\u5668\u6570\u636e\u5b57\u5178

      "},{"location":"qsl4a/system/sensors/#sensorsreadaccelerometer","title":"sensorsReadAccelerometer()","text":"

      \u8bfb\u53d6\u52a0\u901f\u5ea6\u8ba1\u503c\u3002

      sensorsReadAccelerometer()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d m/s\u00b2

      "},{"location":"qsl4a/system/sensors/#sensorsreadgyroscope","title":"sensorsReadGyroscope()","text":"

      \u8bfb\u53d6\u9640\u87ba\u4eea\u503c\u3002

      sensorsReadGyroscope()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d rad/s

      "},{"location":"qsl4a/system/sensors/#sensorsreadmagnetometer","title":"sensorsReadMagnetometer()","text":"

      \u8bfb\u53d6\u78c1\u573a\u503c\u3002

      sensorsReadMagnetometer()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d \u03bcT

      "},{"location":"qsl4a/system/sensors/#sensorsreadorientation","title":"sensorsReadOrientation()","text":"

      \u8bfb\u53d6\u8bbe\u5907\u65b9\u5411\u3002

      sensorsReadOrientation()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [azimuth, pitch, roll]\uff0c\u5355\u4f4d\u5ea6

      "},{"location":"qsl4a/system/sensors/#sensorsgetlight","title":"sensorsGetLight()","text":"

      \u8bfb\u53d6\u5149\u4f20\u611f\u5668\u503c\u3002

      sensorsGetLight()\n

      \u8fd4\u56de\uff1a \u5149\u7ea7\u522b\uff08lux\uff09

      "},{"location":"qsl4a/system/sensors/#sensorsgetstepcounter","title":"sensorsGetStepCounter()","text":"

      \u8bfb\u53d6\u6b65\u8ba1\u6570\u5668\u3002

      sensorsGetStepCounter()\n

      \u8fd4\u56de\uff1a \u6b65\u6570

      "},{"location":"qsl4a/system/sensors/#sensorsgetaccuracy","title":"sensorsGetAccuracy()","text":"

      \u83b7\u53d6\u5f53\u524d\u4f20\u611f\u5668\u7cbe\u5ea6\u3002

      sensorsGetAccuracy()\n

      \u8fd4\u56de\uff1a \u7cbe\u5ea6\u503c\uff080-3\uff1aUNRELIABLE\u3001ACCURACY_LOW\u3001ACCURACY_MEDIUM\u3001ACCURACY_HIGH\uff09

      "},{"location":"qsl4a/system/sensors/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u8bfb\u53d6\u4f20\u611f\u5668 10 \u6b21\nfor i in range(10):\n    accel = droid.sensorsReadAccelerometer().result\n    print(f\"Accel: X={accel[0]:.2f}, Y={accel[1]:.2f}, Z={accel[2]:.2f}\")\n    time.sleep(0.5)\n\ndroid.stopSensing()\n
      "},{"location":"qsl4a/system/settings/","title":"\u8bbe\u7f6e API","text":"

      \u63a7\u5236\u7cfb\u7edf\u8bbe\u7f6e\uff0c\u5305\u62ec\u5c4f\u5e55\u3001\u58f0\u97f3\u548c\u7f51\u7edc\u8bbe\u7f6e\u3002

      "},{"location":"qsl4a/system/settings/#_1","title":"\u5c4f\u5e55\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#setscreentimeout","title":"setScreenTimeout()","text":"

      \u8bbe\u7f6e\u5c4f\u5e55\u8d85\u65f6\u503c\u3002

      setScreenTimeout(value)\n

      \u53c2\u6570\uff1a - value (int): \u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

      \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u8d85\u65f6\u503c

      "},{"location":"qsl4a/system/settings/#getscreentimeout","title":"getScreenTimeout()","text":"

      \u83b7\u53d6\u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u3002

      getScreenTimeout()\n

      \u8fd4\u56de\uff1a \u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

      "},{"location":"qsl4a/system/settings/#getscreenbrightness","title":"getScreenBrightness()","text":"

      \u83b7\u53d6\u5c4f\u5e55\u4eae\u5ea6\u503c\u3002

      getScreenBrightness()\n

      \u8fd4\u56de\uff1a \u4eae\u5ea6\u503c\uff080-255\uff09

      "},{"location":"qsl4a/system/settings/#setscreenbrightness","title":"setScreenBrightness()","text":"

      \u8bbe\u7f6e\u5c4f\u5e55\u4eae\u5ea6\u3002

      setScreenBrightness(value=None)\n

      \u53c2\u6570\uff1a - value (int, optional): \u4eae\u5ea6\u503c\uff080-255\uff09\uff0c\u6216 None \u8868\u793a\u81ea\u52a8

      \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u4eae\u5ea6\u503c

      "},{"location":"qsl4a/system/settings/#checkscreenon","title":"checkScreenOn()","text":"

      \u68c0\u67e5\u5c4f\u5e55\u662f\u5426\u4eae\u7740\u3002

      checkScreenOn()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u5c4f\u5e55\u4eae\u7740\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/system/settings/#_2","title":"\u98de\u884c\u6a21\u5f0f","text":""},{"location":"qsl4a/system/settings/#checkairplanemode","title":"checkAirplaneMode()","text":"

      \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\u662f\u5426\u542f\u7528\u3002

      checkAirplaneMode()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u98de\u884c\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

      "},{"location":"qsl4a/system/settings/#_3","title":"\u94c3\u58f0\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#checkringersilentmode","title":"checkRingerSilentMode()","text":"

      \u68c0\u67e5\u94c3\u58f0\u662f\u5426\u5904\u4e8e\u9759\u97f3\u6a21\u5f0f\u3002

      checkRingerSilentMode()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u9759\u97f3\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

      "},{"location":"qsl4a/system/settings/#toggleringersilentmode","title":"toggleRingerSilentMode()","text":"

      \u5207\u6362\u94c3\u58f0\u9759\u97f3\u6a21\u5f0f\u3002

      toggleRingerSilentMode(enabled=None)\n

      \u53c2\u6570\uff1a - enabled (bool, optional): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

      \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

      "},{"location":"qsl4a/system/settings/#togglevibratemode","title":"toggleVibrateMode()","text":"

      \u5207\u6362\u632f\u52a8\u6a21\u5f0f\u3002

      toggleVibrateMode(enabled=None, ringer=None)\n

      \u53c2\u6570\uff1a - enabled (bool, optional): \u5207\u6362\u632f\u52a8\u5f00/\u5173 - ringer (bool, optional): \u5e94\u7528\u4e8e\u94c3\u58f0\u6a21\u5f0f

      \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

      "},{"location":"qsl4a/system/settings/#getvibratemode","title":"getVibrateMode()","text":"

      \u83b7\u53d6\u632f\u52a8\u6a21\u5f0f\u8bbe\u7f6e\u3002

      getVibrateMode(ringer=None)\n

      \u53c2\u6570\uff1a - ringer (bool, optional): \u68c0\u67e5\u94c3\u58f0\u632f\u52a8\u6a21\u5f0f

      \u8fd4\u56de\uff1a \u5982\u679c\u632f\u52a8\u5df2\u542f\u7528\u5219\u4e3a True

      "},{"location":"qsl4a/system/settings/#_4","title":"\u97f3\u91cf\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#getringervolume","title":"getRingerVolume()","text":"

      \u83b7\u53d6\u5f53\u524d\u94c3\u58f0\u97f3\u91cf\u3002

      getRingerVolume()\n

      \u8fd4\u56de\uff1a \u94c3\u58f0\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-7\uff09

      "},{"location":"qsl4a/system/settings/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

      getMaxRingerVolume()\n

      \u8fd4\u56de\uff1a \u6700\u5927\u94c3\u58f0\u97f3\u91cf

      "},{"location":"qsl4a/system/settings/#setringervolume","title":"setRingerVolume()","text":"

      \u8bbe\u7f6e\u94c3\u58f0\u97f3\u91cf\u3002

      setRingerVolume(volume)\n

      \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

      "},{"location":"qsl4a/system/settings/#getmediavolume","title":"getMediaVolume()","text":"

      \u83b7\u53d6\u5f53\u524d\u5a92\u4f53\u97f3\u91cf\u3002

      getMediaVolume()\n

      \u8fd4\u56de\uff1a \u5a92\u4f53\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-15\uff09

      "},{"location":"qsl4a/system/settings/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

      getMaxMediaVolume()\n

      \u8fd4\u56de\uff1a \u6700\u5927\u5a92\u4f53\u97f3\u91cf

      "},{"location":"qsl4a/system/settings/#setmediavolume","title":"setMediaVolume()","text":"

      \u8bbe\u7f6e\u5a92\u4f53\u97f3\u91cf\u3002

      setMediaVolume(volume)\n

      \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

      "},{"location":"qsl4a/system/settings/#_5","title":"\u7cfb\u7edf\u4fe1\u606f","text":""},{"location":"qsl4a/system/settings/#elapsedrealtimenanos","title":"elapsedRealtimeNanos()","text":"

      \u83b7\u53d6\u81ea\u7cfb\u7edf\u542f\u52a8\u4ee5\u6765\u7684\u7eb3\u79d2\u6570\u3002

      elapsedRealtimeNanos()\n

      \u8fd4\u56de\uff1a \u7eb3\u79d2\u6570\uff08\u53ef\u7528\u4e8e\u8ba1\u65f6\uff09

      "},{"location":"qsl4a/system/settings/#gettrafficstats","title":"getTrafficStats()","text":"

      \u83b7\u53d6\u7f51\u7edc\u6d41\u91cf\u7edf\u8ba1\u3002

      getTrafficStats(flags=7)\n

      \u53c2\u6570\uff1a - flags (int): \u8981\u68c0\u7d22\u7684\u7edf\u8ba1\uff08\u9ed8\u8ba4\uff1a7 = \u5168\u90e8\uff09

      \u8fd4\u56de\uff1a \u5305\u542b\u53d1\u9001/\u63a5\u6536\u5b57\u8282\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/settings/#getapptxbytes","title":"getAppTxBytes()","text":"

      \u83b7\u53d6 QPython \u5e94\u7528\u7684\u53d1\u9001\u5b57\u8282\u3002

      getAppTxBytes(packageName)\n

      \u53c2\u6570\uff1a - packageName (str): \u5305\u540d

      \u8fd4\u56de\uff1a \u5305\u542b tx/rx \u5b57\u8282\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/settings/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5c4f\u5e55\u8bbe\u7f6e\ncurrent_timeout = droid.getScreenTimeout().result\nprint(f\"Current timeout: {current_timeout}s\")\ndroid.setScreenTimeout(30)\n\n# \u68c0\u67e5\u5c4f\u5e55\nif droid.checkScreenOn().result:\n    print(\"Screen is on\")\n\n# \u97f3\u91cf\u63a7\u5236\nmedia_vol = droid.getMediaVolume().result\nprint(f\"Media volume: {media_vol}\")\ndroid.setMediaVolume(10)\n\n# \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\nif droid.checkAirplaneMode().result:\n    print(\"Airplane mode is on\")\n
      "},{"location":"qsl4a/system/sysinfo/","title":"\u7cfb\u7edf\u4fe1\u606f","text":"

      \u68c0\u7d22\u8bbe\u5907\u548c\u7cfb\u7edf\u4fe1\u606f\u3002

      "},{"location":"qsl4a/system/sysinfo/#_2","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/sysinfo/#getandroidid","title":"getAndroidID()","text":"

      \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

      getAndroidID()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

      "},{"location":"qsl4a/system/sysinfo/#getsysinfo","title":"getSysInfo()","text":"

      \u83b7\u53d6\u7efc\u5408\u7cfb\u7edf\u4fe1\u606f\u3002

      getSysInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/sysinfo/#getlocale","title":"getLocale()","text":"

      \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u8bbe\u7f6e\u3002

      getLocale()\n

      \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

      "},{"location":"qsl4a/system/sysinfo/#_3","title":"\u5185\u5b58","text":""},{"location":"qsl4a/system/sysinfo/#getmemoryinfo","title":"getMemoryInfo()","text":"

      \u83b7\u53d6 RAM \u4fe1\u606f\u3002

      getMemoryInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/sysinfo/#_4","title":"\u663e\u793a","text":""},{"location":"qsl4a/system/sysinfo/#getscreeninfo","title":"getScreenInfo()","text":"

      \u83b7\u53d6\u663e\u793a\u4fe1\u606f\u3002

      getScreenInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/sysinfo/#_5","title":"\u6807\u8bc6\u7b26","text":""},{"location":"qsl4a/system/sysinfo/#getimei","title":"getImei()","text":"

      \u83b7\u53d6\u8bbe\u5907 IMEI\u3002

      getImei(slotIndex=None)\n
      "},{"location":"qsl4a/system/sysinfo/#getmeid","title":"getMeid()","text":"

      \u83b7\u53d6\u8bbe\u5907 MEID\u3002

      getMeid(slotIndex=None)\n
      "},{"location":"qsl4a/system/sysinfo/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u8bbe\u5907 ID\nandroid_id = droid.getAndroidID().result\nprint(f\"Android ID: {android_id}\")\n\n# \u5c4f\u5e55\u4fe1\u606f\nscreen = droid.getScreenInfo().result\nprint(f\"Screen: {screen['width']}x{screen['height']}\")\n\n# \u5185\u5b58\nmemory = droid.getMemoryInfo().result\nprint(f\"Memory: {memory}\")\n
      "},{"location":"qsl4a/system/wakelock/","title":"WakeLock API","text":"

      \u63a7\u5236\u8bbe\u5907\u5524\u9192\u9501\u4ee5\u4fdd\u6301 CPU \u6216\u5c4f\u5e55\u5f00\u542f\u3002

      "},{"location":"qsl4a/system/wakelock/#wake-lock","title":"Wake Lock \u7c7b\u578b","text":"

      QSL4A \u63d0\u4f9b\u4e0d\u540c\u7c7b\u578b\u7684\u5524\u9192\u9501\uff1a

      \u7c7b\u578b \u63cf\u8ff0 Full CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae Partial \u4ec5 CPU \u5f00\u542f Bright CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae Dim CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697"},{"location":"qsl4a/system/wakelock/#wake-lock_1","title":"Wake Lock \u65b9\u6cd5","text":""},{"location":"qsl4a/system/wakelock/#wakelockacquirefull","title":"wakeLockAcquireFull()","text":"

      \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae\uff09\u3002

      wakeLockAcquireFull()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquirepartial","title":"wakeLockAcquirePartial()","text":"

      \u83b7\u53d6\u90e8\u5206\u5524\u9192\u9501\uff08\u4ec5 CPU \u5f00\u542f\uff09\u3002

      wakeLockAcquirePartial()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquirebright","title":"wakeLockAcquireBright()","text":"

      \u83b7\u53d6\u660e\u4eae\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff09\u3002

      wakeLockAcquireBright()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquiredim","title":"wakeLockAcquireDim()","text":"

      \u83b7\u53d6\u6697\u6de1\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697\uff09\u3002

      wakeLockAcquireDim()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockrelease","title":"wakeLockRelease()","text":"

      \u91ca\u653e\u5524\u9192\u9501\u3002

      wakeLockRelease()\n
      "},{"location":"qsl4a/system/wakelock/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\ndroid.wakeLockAcquireFull()\n\n# \u5728\u4fdd\u6301\u5c4f\u5e55\u5f00\u542f\u65f6\u6267\u884c\u91cd\u8981\u5de5\u4f5c\nprint(\"Screen will stay on\")\ntime.sleep(10)\n\n# \u5b8c\u6210\u540e\u91ca\u653e\ndroid.wakeLockRelease()\n\n# \u6216\u4f7f\u7528\u90e8\u5206\u9501\u8fdb\u884c\u540e\u53f0\u4efb\u52a1\ndroid.wakeLockAcquirePartial()\n# \u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\uff0cCPU \u4ecd\u4fdd\u6301\u5f00\u542f\ntime.sleep(30)\ndroid.wakeLockRelease()\n

      \u6ce8\u610f\uff1a \u8bb0\u4f4f\u5728\u4e0d\u9700\u8981\u65f6\u91ca\u653e\u5524\u9192\u9501\u4ee5\u8282\u7701\u7535\u6c60\u3002

      "},{"location":"qsl4a/ui/accessibility/","title":"\u65e0\u969c\u788d\u670d\u52a1","text":"

      \u65e0\u969c\u788d\u670d\u52a1\u5141\u8bb8\u81ea\u52a8\u5316 UI \u4ea4\u4e92\uff0c\u5982\u70b9\u51fb\u3001\u6ed1\u52a8\u548c\u7cfb\u7edf\u64cd\u4f5c\u3002

      "},{"location":"qsl4a/ui/accessibility/#_2","title":"\u670d\u52a1\u63a7\u5236","text":""},{"location":"qsl4a/ui/accessibility/#accessibilitystartservice","title":"accessibilityStartService()","text":"

      \u542f\u52a8\u65e0\u969c\u788d\u670d\u52a1\u3002

      accessibilityStartService()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/ui/accessibility/#accessibilityserviceenabled","title":"accessibilityServiceEnabled()","text":"

      \u68c0\u67e5\u65e0\u969c\u788d\u670d\u52a1\u662f\u5426\u5df2\u542f\u7528\u3002

      accessibilityServiceEnabled()\n

      \u8fd4\u56de\uff1a True \u6216 False

      "},{"location":"qsl4a/ui/accessibility/#_3","title":"\u5c4f\u5e55\u4ea4\u4e92","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityclick","title":"accessibilityClick()","text":"

      \u5728\u5c4f\u5e55\u5750\u6807\u5904\u70b9\u51fb\u3002

      accessibilityClick(x=0, y=0, t=50)\n

      \u53c2\u6570\uff1a - x (int/float): X \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - y (int/float): Y \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - t (int): \u6309\u4f4f\u65f6\u957f\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a50\uff09

      "},{"location":"qsl4a/ui/accessibility/#accessibilityslide","title":"accessibilitySlide()","text":"

      \u591a\u70b9\u6ed1\u52a8\u624b\u52bf\u3002

      accessibilitySlide(XnYn=None, t=None)\n

      \u53c2\u6570\uff1a - XnYn (list): \u5750\u6807 [X1, Y1, X2, Y2, ... Xn, Yn] - t (int): \u6ed1\u52a8\u65f6\u957f\uff08\u9ed8\u8ba4\uff1a50*n \u6beb\u79d2\uff09

      "},{"location":"qsl4a/ui/accessibility/#_4","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityaction","title":"accessibilityAction()","text":"

      \u6309\u4ee3\u7801\u6267\u884c\u7cfb\u7edf\u64cd\u4f5c\u3002

      accessibilityAction(actionCode)\n

      \u64cd\u4f5c\u4ee3\u7801\uff1a | \u4ee3\u7801 | \u5e38\u91cf | \u63cf\u8ff0 | |------|----------|-------------| | 1 | BACK | \u8fd4\u56de\u6309\u94ae | | 2 | HOME | \u4e3b\u5c4f\u5e55\u6309\u94ae | | 3 | RECENTS | \u6700\u8fd1\u5e94\u7528 | | 4 | NOTIFICATIONS | \u6253\u5f00\u901a\u77e5 | | 5 | QUICK_SETTINGS | \u6253\u5f00\u5feb\u901f\u8bbe\u7f6e | | 6 | POWER_DIALOG | \u7535\u6e90\u83dc\u5355 | | 7 | TOGGLE_SPLIT_SCREEN | \u5206\u5c4f | | 8 | LOCK_SCREEN | \u9501\u5c4f | | 9 | TAKE_SCREENSHOT | \u622a\u56fe | | 10 | KEYCODE_HEADSETHOOK | \u8033\u673a\u6302\u94a9 | | 11-14 | ACCESSIBILITY_ | \u65e0\u969c\u788d\u6309\u94ae | | 15 | DISMISS_NOTIFICATION_SHADE | \u5173\u95ed\u901a\u77e5\u680f | | 16-20 | DPAD_ | \u65b9\u5411\u952e | | 21 | MENU | \u83dc\u5355\u6309\u94ae | | 22 | MEDIA_PLAY_PAUSE | \u64ad\u653e/\u6682\u505c\u5a92\u4f53 |

      "},{"location":"qsl4a/ui/accessibility/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/accessibility/#_6","title":"\u70b9\u51fb\u5c4f\u5e55\u4e2d\u5fc3","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u670d\u52a1\nif not droid.accessibilityServiceEnabled().result:\n    droid.accessibilityStartService()\n\n# \u70b9\u51fb\u4e2d\u5fc3\uff080,0 = \u4e2d\u5fc3\uff09\ndroid.accessibilityClick(0, 0, t=100)\n
      "},{"location":"qsl4a/ui/accessibility/#_7","title":"\u6ed1\u52a8\u624b\u52bf","text":"
      # \u4ece\u4e0b\u5f80\u4e0a\u6ed1\u52a8\uff08\u5411\u4e0a\u6eda\u52a8\uff09\ndroid.accessibilitySlide([0, 1.5, 0, -1.5], t=300)\n
      "},{"location":"qsl4a/ui/accessibility/#_8","title":"\u7cfb\u7edf\u5bfc\u822a","text":"
      # \u6309\u4e3b\u5c4f\u5e55\ndroid.accessibilityAction(2)\n\n# \u6309\u8fd4\u56de\ndroid.accessibilityAction(1)\n\n# \u6253\u5f00\u901a\u77e5\ndroid.accessibilityAction(4)\n
      "},{"location":"qsl4a/ui/accessibility/#_9","title":"\u70b9\u51fb\u7279\u5b9a\u4f4d\u7f6e","text":"
      # \u70b9\u51fb\u5c4f\u5e55\u5750\u6807 (500, 800)\ndroid.accessibilityClick(500, 800)\n\n# \u70b9\u51fb\u76f8\u5bf9\u4f4d\u7f6e\uff08\u6c34\u5e73\u5c45\u4e2d\uff0c\u5782\u76f4 3/4 \u5904\uff09\ndroid.accessibilityClick(0, 1.5)\n
      "},{"location":"qsl4a/ui/dialogs/","title":"\u5bf9\u8bdd\u6846\u7cfb\u7edf","text":"

      QSL4A \u63d0\u4f9b\u5168\u9762\u7684\u5bf9\u8bdd\u6846\u652f\u6301\uff0c\u7528\u4e8e\u7528\u6237\u4ea4\u4e92\uff0c\u5305\u62ec\u8b66\u62a5\u3001\u8f93\u5165\u5bf9\u8bdd\u6846\u3001\u9009\u62e9\u5bf9\u8bdd\u6846\u548c\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

      "},{"location":"qsl4a/ui/dialogs/#_2","title":"\u8b66\u62a5\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowalert","title":"dialogShowAlert()","text":"

      \u663e\u793a\u7b80\u5355\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

      dialogShowAlert(title=\"Alert\", message=\"The message of the alert.\",\n                positiveButtonText=\"OK\", negativeButtonText=None,\n                neutralButtonText=None, messageIsHtml=False)\n

      \u53c2\u6570\uff1a - title (str): \u5bf9\u8bdd\u6846\u6807\u9898 - message (str): \u6d88\u606f\u6587\u672c - positiveButtonText (str): \u80af\u5b9a\u6309\u94ae\u6807\u7b7e - negativeButtonText (str, optional): \u5426\u5b9a\u6309\u94ae\u6807\u7b7e - neutralButtonText (str, optional): \u4e2d\u6027\u6309\u94ae\u6807\u7b7e - messageIsHtml (bool): \u5c06\u6d88\u606f\u89e3\u6790\u4e3a HTML

      \u8fd4\u56de\uff1a \u5305\u542b\u70b9\u51fb\u6309\u94ae\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#dialogshowsimplechoice","title":"dialogShowSimpleChoice()","text":"

      \u663e\u793a\u5e26\u6709\u9879\u76ee\u7684\u7b80\u5355\u9009\u62e9\u5bf9\u8bdd\u6846\u3002

      dialogShowSimpleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

      \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868

      \u8fd4\u56de\uff1a \u5305\u542b\u9009\u4e2d\u9879\u76ee\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#_3","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialoggetinput","title":"dialogGetInput()","text":"

      \u83b7\u53d6\u7528\u6237\u6587\u672c\u8f93\u5165\u3002

      dialogGetInput(title=\"Value\", message=\"Please enter value:\",\n               defaultText=None, messageIsHtml=False)\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7528\u6237\u8f93\u5165\u6587\u672c\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#dialoggetpassword","title":"dialogGetPassword()","text":"

      \u83b7\u53d6\u5bc6\u7801\u8f93\u5165\u3002

      dialogGetPassword(title=\"Password\", message=\"Please enter password:\")\n

      \u8fd4\u56de\uff1a \u5305\u542b\u8f93\u5165\u5bc6\u7801\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#dialogcreateinput","title":"dialogCreateInput()","text":"

      \u521b\u5efa\u81ea\u5b9a\u4e49\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

      dialogCreateInput(title=\"Value\", message=\"Please enter value:\",\n                  defaultText=None, inputType=None)\n

      \u53c2\u6570\uff1a - inputType (str): \u8f93\u5165\u7c7b\u578b\uff08\u4f8b\u5982 \"text\"\u3001\"number\"\u3001\"textPassword\"\uff09

      "},{"location":"qsl4a/ui/dialogs/#dialogcreatepassword","title":"dialogCreatePassword()","text":"

      \u521b\u5efa\u5bc6\u7801\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

      dialogCreatePassword(title=\"Password\", message=\"Please enter password:\")\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreateseekbar","title":"dialogCreateSeekBar()","text":"

      \u521b\u5efa\u6ed1\u5757/\u8fdb\u5ea6\u6761\u5bf9\u8bdd\u6846\u3002

      dialogCreateSeekBar(starting_value=50, maximum_value=100, title=\"\", message=\"\")\n

      \u53c2\u6570\uff1a - starting_value (int): \u521d\u59cb\u503c - maximum_value (int): \u6700\u5927\u503c

      "},{"location":"qsl4a/ui/dialogs/#_4","title":"\u9009\u62e9\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowsinglechoice","title":"dialogShowSingleChoice()","text":"

      \u663e\u793a\u5355\u9009\uff08\u5355\u9009\u6309\u94ae\uff09\u5bf9\u8bdd\u6846\u3002

      dialogShowSingleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, selected=-1, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

      \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (int): \u9ed8\u8ba4\u9009\u4e2d\u7d22\u5f15

      "},{"location":"qsl4a/ui/dialogs/#dialogshowmultichoice","title":"dialogShowMultiChoice()","text":"

      \u663e\u793a\u591a\u9009\uff08\u590d\u9009\u6846\uff09\u5bf9\u8bdd\u6846\u3002

      dialogShowMultiChoice(title=\"Alert\", message=\"The message of the alert.\",\n                      items=None, selected=None, positiveButtonText=\"OK\",\n                      negativeButtonText=None, neutralButtonText=None,\n                      messageIsHtml=False)\n

      \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (list): \u521d\u59cb\u9009\u4e2d\u7d22\u5f15\u5217\u8868

      "},{"location":"qsl4a/ui/dialogs/#dialogsetsinglechoiceitems","title":"dialogSetSingleChoiceItems()","text":"

      \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u5355\u9009\u9879\u76ee\u3002

      dialogSetSingleChoiceItems(items, selected=-1)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmultichoiceitems","title":"dialogSetMultiChoiceItems()","text":"

      \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u591a\u9009\u9879\u76ee\u3002

      dialogSetMultiChoiceItems(items, selected=None)\n
      "},{"location":"qsl4a/ui/dialogs/#_5","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatespinnerprogress","title":"dialogCreateSpinnerProgress()","text":"

      \u521b\u5efa\u4e0d\u786e\u5b9a\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

      dialogCreateSpinnerProgress(title=None, message=None, maximum_progress=100)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreatehorizontalprogress","title":"dialogCreateHorizontalProgress()","text":"

      \u521b\u5efa\u6c34\u5e73\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

      dialogCreateHorizontalProgress(title=None, message=None, maximum_progress=100)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetcurrentprogress","title":"dialogSetCurrentProgress()","text":"

      \u66f4\u65b0\u8fdb\u5ea6\u503c\u3002

      dialogSetCurrentProgress(current)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmaxprogress","title":"dialogSetMaxProgress()","text":"

      \u8bbe\u7f6e\u6700\u5927\u8fdb\u5ea6\u503c\u3002

      dialogSetMaxProgress(max)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetprogressmessage","title":"dialogSetProgressMessage()","text":"

      \u66f4\u65b0\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u6d88\u606f\u3002

      dialogSetProgressMessage(message)\n
      "},{"location":"qsl4a/ui/dialogs/#_6","title":"\u9009\u62e9\u5668\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatedatepicker","title":"dialogCreateDatePicker()","text":"

      \u521b\u5efa\u65e5\u671f\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

      dialogCreateDatePicker(year=1970, month=1, day=1)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreatetimepicker","title":"dialogCreateTimePicker()","text":"

      \u521b\u5efa\u65f6\u95f4\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

      dialogCreateTimePicker(hour=0, minute=0, is24hour=False)\n
      "},{"location":"qsl4a/ui/dialogs/#_7","title":"\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u521b\u5efa","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatealert","title":"dialogCreateAlert()","text":"

      \u521b\u5efa\u81ea\u5b9a\u4e49\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

      dialogCreateAlert(title=None, message=None)\n

      \u521b\u5efa\u4e00\u4e2a\u7a7a\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002\u53ef\u4e0e\u5176\u4ed6 dialogSet* \u51fd\u6570\u4e00\u8d77\u4f7f\u7528\u6765\u81ea\u5b9a\u4e49\u3002

      "},{"location":"qsl4a/ui/dialogs/#dialogsetitems","title":"dialogSetItems()","text":"

      \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u7b80\u5355\u5217\u8868\u9879\u76ee\u3002

      dialogSetItems(items)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetpositivebuttontext","title":"dialogSetPositiveButtonText()","text":"

      \u8bbe\u7f6e\u80af\u5b9a\u6309\u94ae\u6587\u672c\u3002

      dialogSetPositiveButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetnegativebuttontext","title":"dialogSetNegativeButtonText()","text":"

      \u8bbe\u7f6e\u5426\u5b9a\u6309\u94ae\u6587\u672c\u3002

      dialogSetNegativeButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetneutralbuttontext","title":"dialogSetNeutralButtonText()","text":"

      \u8bbe\u7f6e\u4e2d\u6027\u6309\u94ae\u6587\u672c\u3002

      dialogSetNeutralButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmessageishtml","title":"dialogSetMessageIsHtml()","text":"

      \u8bbe\u7f6e\u6d88\u606f\u662f\u5426\u5e94\u89e3\u6790\u4e3a HTML\u3002

      dialogSetMessageIsHtml(messageIsHtml=True)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogshow","title":"dialogShow()","text":"

      \u663e\u793a\u521b\u5efa\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u3002

      dialogShow()\n
      "},{"location":"qsl4a/ui/dialogs/#_8","title":"\u5bf9\u8bdd\u6846\u63a7\u5236","text":""},{"location":"qsl4a/ui/dialogs/#dialogdismiss","title":"dialogDismiss()","text":"

      \u5173\u95ed\u5f53\u524d\u5bf9\u8bdd\u6846\u3002

      dialogDismiss()\n
      "},{"location":"qsl4a/ui/dialogs/#dialoggetresponse","title":"dialogGetResponse()","text":"

      \u83b7\u53d6\u5bf9\u8bdd\u6846\u54cd\u5e94\u3002

      dialogGetResponse()\n
      "},{"location":"qsl4a/ui/dialogs/#dialoggetselecteditems","title":"dialogGetSelectedItems()","text":"

      \u4ece\u9009\u62e9\u5bf9\u8bdd\u6846\u83b7\u53d6\u9009\u4e2d\u7684\u9879\u76ee\u3002

      dialogGetSelectedItems()\n
      "},{"location":"qsl4a/ui/dialogs/#_9","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/dialogs/#_10","title":"\u7b80\u5355\u8b66\u62a5","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a\u8b66\u62a5\ndroid.dialogShowAlert(\"Warning\", \"This is an important message!\")\n
      "},{"location":"qsl4a/ui/dialogs/#_11","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":"
      # \u83b7\u53d6\u7528\u6237\u8f93\u5165\nresult = droid.dialogGetInput(\"Name\", \"Enter your name:\", \"John\").result\nprint(f\"Hello, {result}!\")\n
      "},{"location":"qsl4a/ui/dialogs/#_12","title":"\u5e26\u6309\u94ae\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846","text":"
      # \u521b\u5efa\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\ndroid.dialogCreateAlert(\"Custom\", \"Choose an option\")\ndroid.dialogSetItems([\"Option 1\", \"Option 2\", \"Option 3\"])\ndroid.dialogShow()\n\n# \u83b7\u53d6\u54cd\u5e94\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response['item']}\")\n
      "},{"location":"qsl4a/ui/dialogs/#_13","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":"
      # \u521b\u5efa\u8fdb\u5ea6\u5bf9\u8bdd\u6846\ndroid.dialogCreateHorizontalProgress(\"Loading\", \"Please wait...\", 100)\ndroid.dialogShow()\n\n# \u66f4\u65b0\u8fdb\u5ea6\nfor i in range(101):\n    droid.dialogSetCurrentProgress(i)\n    time.sleep(0.05)\n\ndroid.dialogDismiss()\n
      "},{"location":"qsl4a/ui/dialogs/#_14","title":"\u65e5\u671f\u9009\u62e9\u5668","text":"
      # \u663e\u793a\u65e5\u671f\u9009\u62e9\u5668\ndroid.dialogCreateDatePicker(2024, 1, 15)\ndroid.dialogShow()\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response}\")\n
      "},{"location":"qsl4a/ui/floatview/","title":"\u6d6e\u52a8\u89c6\u56fe","text":"

      \u6d6e\u52a8\u7a97\u53e3\u652f\u6301\uff0c\u7528\u4e8e\u5728\u5176\u4ed6\u5e94\u7528\u7a0b\u5e8f\u4e0a\u65b9\u4fdd\u6301\u663e\u793a\u7684\u8986\u76d6 UI \u5143\u7d20\u3002

      "},{"location":"qsl4a/ui/floatview/#_2","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/floatview/#floatview","title":"floatView()","text":"

      \u663e\u793a\u6216\u4fee\u6539\u6d6e\u52a8\u89c6\u56fe\u3002

      floatView(Args=None)\n

      \u53c2\u6570\uff1a - Args (dict): \u914d\u7f6e\u5b57\u5178\uff0c\u5305\u542b\u4ee5\u4e0b\u952e\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08-1 \u521b\u5efa\u65b0\u7684\uff0c>=0 \u4fee\u6539\u73b0\u6709\u7684\uff09 - text (str): \u8981\u663e\u793a\u7684\u6587\u672c\u5185\u5bb9 - html (str): HTML \u5185\u5bb9\uff08\u5982\u679c\u7701\u7565 text \u5219\u4f7f\u7528\uff09 - width (int): \u89c6\u56fe\u5bbd\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a300\uff09 - height (int): \u89c6\u56fe\u9ad8\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a150\uff09 - x (int): X \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - y (int): Y \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - backColor (str): ARGB \u5341\u516d\u8fdb\u5236\u80cc\u666f\u8272\uff08\u9ed8\u8ba4\uff1a'7f7f7f7f'\uff09 - textColor (str): ARGB \u5341\u516d\u8fdb\u5236\u6587\u672c\u8272\uff08\u9ed8\u8ba4\uff1a'ff000000'\uff09 - textSize (int): \u6587\u672c\u5927\u5c0f\uff08\u9ed8\u8ba4\uff1a10\uff09 - textAlign (int): \u6587\u672c\u5bf9\u9f50\uff080 = \u7ee7\u627f\uff09 - script (str): \u957f\u6309\u5173\u95ed\u540e\u8fd0\u884c\u7684\u811a\u672c\u8def\u5f84 - arg: \u811a\u672c\u53c2\u6570 - clickRemove (bool): \u542f\u7528\u70b9\u51fb\u79fb\u9664\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - flag (int): \u7a97\u53e3\u6807\u5fd7\uff08\u9ed8\u8ba4\uff1a40 - \u53ef\u89e6\u6478\uff09

      \u8fd4\u56de\uff1a \u5f53\u524d\u94fe\u5217\u8868\u957f\u5ea6

      "},{"location":"qsl4a/ui/floatview/#floatviewcount","title":"floatViewCount()","text":"

      \u83b7\u53d6\u6d3b\u52a8\u6d6e\u52a8\u89c6\u56fe\u7684\u6570\u91cf\u3002

      floatViewCount()\n

      \u8fd4\u56de\uff1a \u6d6e\u52a8\u89c6\u56fe\u6570\u91cf

      "},{"location":"qsl4a/ui/floatview/#floatviewresult","title":"floatViewResult()","text":"

      \u83b7\u53d6\u6d6e\u52a8\u89c6\u56fe\u7684\u7ed3\u679c/\u72b6\u6001\u3002

      floatViewResult(index=-1)\n

      \u53c2\u6570\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1\uff0c\u8fd4\u56de\u6700\u540e\u64cd\u4f5c\u7ed3\u679c\uff09

      \u8fd4\u56de\uff1a \u5305\u542b\u64cd\u4f5c\u8be6\u60c5\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - x, y: \u4f4d\u7f6e - time: \u65f6\u95f4\u6233 - operation: \u64cd\u4f5c\u7c7b\u578b\uff08'initial'\u3001'move' \u7b49\uff09 - index: \u89c6\u56fe\u7d22\u5f15 - removed: \u5982\u679c\u89c6\u56fe\u88ab\u79fb\u9664\u5219\u4e3a True

      "},{"location":"qsl4a/ui/floatview/#floatviewremove","title":"floatViewRemove()","text":"

      \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\u3002

      floatViewRemove(index=-1)\n

      \u53c2\u6570\uff1a - index (int): \u8981\u79fb\u9664\u7684\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1 \u79fb\u9664\u6700\u540e\u4e00\u4e2a\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a 1\uff0c\u5426\u5219\u4e3a 0

      "},{"location":"qsl4a/ui/floatview/#_3","title":"\u5e38\u91cf","text":"
      • floatView.INDEX_NEW = -1 - \u521b\u5efa\u65b0\u7684\u6d6e\u52a8\u89c6\u56fe
      • floatView.FLAG_DEFAULT_TOUCHABLE = 40 - \u9ed8\u8ba4\u53ef\u89e6\u6478\u6807\u5fd7
      • floatView.TEXT_ALIGNMENT_INHERIT = 0
      • floatView.TEXT_ALIGNMENT_CENTER - \u5c45\u4e2d\u6587\u672c\u5bf9\u9f50
      "},{"location":"qsl4a/ui/floatview/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/floatview/#_5","title":"\u57fa\u672c\u6d6e\u52a8\u89c6\u56fe","text":"
      import androidhelper\nfrom androidhelper import Android\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u7b80\u5355\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'index': -1,  # \u521b\u5efa\u65b0\u7684\n    'text': 'Hello World',\n    'width': 400,\n    'height': 300,\n    'x': -300,  # \u4ece\u4e2d\u5fc3\u504f\u79fb\n    'y': -400,\n    'backColor': 'ff0000',  # \u7ea2\u8272\u80cc\u666f\n    'textColor': '0000ff',  # \u84dd\u8272\u6587\u672c\n    'textSize': 16,\n    'textAlign': droid.floatView.TEXT_ALIGNMENT_CENTER\n})\n\n# \u68c0\u67e5\u6570\u91cf\nprint(f\"Float views: {droid.floatViewCount().result}\")\n\n# \u83b7\u53d6\u7ed3\u679c\nresult = droid.floatViewResult().result\nprint(f\"View info: {result}\")\n\n# \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\ndroid.floatViewRemove(0)\n
      "},{"location":"qsl4a/ui/floatview/#html","title":"HTML \u5185\u5bb9","text":"
      # \u521b\u5efa\u5e26 HTML \u5185\u5bb9\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': '',  # \u7a7a\u6587\u672c\u4ee5\u4f7f\u7528 HTML\n    'html': '<h1>Title</h1><p>Rich <b>HTML</b> content</p>',\n    'width': 500,\n    'height': 400\n})\n
      "},{"location":"qsl4a/ui/floatview/#_6","title":"\u4fee\u6539\u73b0\u6709\u89c6\u56fe","text":"
      # \u521b\u5efa\u521d\u59cb\u89c6\u56fe\ndroid.floatView({'text': 'Initial Text', 'width': 300, 'height': 150})\n\n# \u4fee\u6539\u540c\u4e00\u89c6\u56fe\uff08\u7d22\u5f15 0\uff09\ndroid.floatView({\n    'index': 0,\n    'text': 'Updated Text!',\n    'backColor': '7f00ff00'  # \u7eff\u8272\u80cc\u666f\n})\n\n# \u68c0\u67e5\u79fb\u52a8/\u66f4\u6539\u7ed3\u679c\nresult = droid.floatViewResult(0).result\nprint(f\"Operation: {result.get('operation')}, Position: ({result.get('x')}, {result.get('y')})\")\n
      "},{"location":"qsl4a/ui/floatview/#_7","title":"\u591a\u4e2a\u6d6e\u52a8\u89c6\u56fe","text":"
      # \u521b\u5efa\u591a\u4e2a\u89c6\u56fe\nfor i in range(3):\n    droid.floatView({\n        'index': -1,\n        'text': f'View {i}',\n        'x': i * 100 - 150,\n        'y': i * 100 - 150,\n        'backColor': f'{i}f{i}f{i}f'\n    })\n\nprint(f\"Total views: {droid.floatViewCount().result}\")\n\n# \u79fb\u9664\u6240\u6709\u89c6\u56fe\nwhile droid.floatViewCount().result > 0:\n    droid.floatViewRemove()\n
      "},{"location":"qsl4a/ui/floatview/#_8","title":"\u5e26\u811a\u672c\u56de\u8c03","text":"
      # \u521b\u5efa\u5173\u95ed\u65f6\u8fd0\u884c\u811a\u672c\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': 'Click to close and run script',\n    'script': '/sdcard/my_script.py',\n    'arg': 'hello from float view',\n    'clickRemove': True\n})\n
      "},{"location":"qsl4a/ui/fullscreen/","title":"\u5168\u5c4f UI","text":"

      \u4f7f\u7528\u539f\u751f Android \u5e03\u5c40\u521b\u5efa\u81ea\u5b9a\u4e49\u5168\u5c4f\u754c\u9762\u3002

      "},{"location":"qsl4a/ui/fullscreen/#_1","title":"\u5e03\u5c40\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullshow","title":"fullShow()","text":"

      \u663e\u793a\u5168\u5c4f\u5e03\u5c40\u3002

      fullShow(layout, title=None, theme=None)\n

      \u53c2\u6570\uff1a - layout (str): JSON \u5e03\u5c40\u5b9a\u4e49\u6216\u5e03\u5c40\u5b57\u7b26\u4e32 - title (str, optional): \u7a97\u53e3\u6807\u9898 - theme (str, optional): \u4e3b\u9898\u540d\u79f0

      \u8fd4\u56de\uff1a \u7a97\u53e3 ID

      "},{"location":"qsl4a/ui/fullscreen/#fulldismiss","title":"fullDismiss()","text":"

      \u5173\u95ed\u5168\u5c4f\u7a97\u53e3\u3002

      fullDismiss()\n
      "},{"location":"qsl4a/ui/fullscreen/#fullquery","title":"fullQuery()","text":"

      \u67e5\u8be2\u6240\u6709\u5c0f\u90e8\u4ef6\u503c\u3002

      fullQuery()\n

      \u8fd4\u56de\uff1a \u5c0f\u90e8\u4ef6 ID \u548c\u503c\u7684\u5b57\u5178

      "},{"location":"qsl4a/ui/fullscreen/#fullquerydetail","title":"fullQueryDetail()","text":"

      \u67e5\u8be2\u7279\u5b9a\u5c0f\u90e8\u4ef6\u8be6\u60c5\u3002

      fullQueryDetail(id)\n
      "},{"location":"qsl4a/ui/fullscreen/#_2","title":"\u5c5e\u6027\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperty","title":"fullGetProperty()","text":"

      \u83b7\u53d6\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

      fullGetProperty(id, property)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetproperty","title":"fullSetProperty()","text":"

      \u8bbe\u7f6e\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

      fullSetProperty(id, property, value)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetlist","title":"fullSetList()","text":"

      \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

      fullSetList(id, list, isHtml=False, listType=0)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetlist2","title":"fullSetList2()","text":"

      \u4f7f\u7528\u8d44\u6e90 ID \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

      fullSetList2(id, list, intRes)\n

      \u53c2\u6570\uff1a - id (str): \u5c0f\u90e8\u4ef6 ID - list (list): \u9879\u76ee\u5217\u8868 - intRes (int): \u5217\u8868\u9879\u76ee\u5e03\u5c40\u7684 Android \u8d44\u6e90 ID

      "},{"location":"qsl4a/ui/fullscreen/#fullsetlistselected","title":"fullSetListSelected()","text":"

      \u5728\u5217\u8868\u4e2d\u8bbe\u7f6e\u9009\u4e2d\u9879\u76ee\u3002

      fullSetListSelected(id, selected)\n

      \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID - selected (int): \u8981\u9009\u4e2d\u7684\u9879\u76ee\u7d22\u5f15

      "},{"location":"qsl4a/ui/fullscreen/#fullgetlistselected","title":"fullGetListSelected()","text":"

      \u83b7\u53d6\u5f53\u524d\u9009\u4e2d\u7684\u5217\u8868\u9879\u76ee\u7d22\u5f15\u3002

      fullGetListSelected(id)\n

      \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID

      \u8fd4\u56de\uff1a \u9009\u4e2d\u9879\u76ee\u7d22\u5f15

      "},{"location":"qsl4a/ui/fullscreen/#_3","title":"\u6279\u91cf\u5c5e\u6027\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperties","title":"fullGetProperties()","text":"

      \u4e00\u6b21\u83b7\u53d6\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

      fullGetProperties(ids, property)\n

      \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u83b7\u53d6\u7684\u5c5e\u6027\u540d

      \u8fd4\u56de\uff1a \u6620\u5c04\u5c0f\u90e8\u4ef6 ID \u5230\u5c5e\u6027\u503c\u7684\u5b57\u5178

      "},{"location":"qsl4a/ui/fullscreen/#fullsetproperties","title":"fullSetProperties()","text":"

      \u4e00\u6b21\u8bbe\u7f6e\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

      fullSetProperties(ids, property, value)\n

      \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u8bbe\u7f6e\u7684\u5c5e\u6027\u540d - value: \u5c5e\u6027\u503c

      "},{"location":"qsl4a/ui/fullscreen/#_4","title":"\u622a\u56fe","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetscreenshot","title":"fullGetScreenShot()","text":"

      \u6355\u83b7\u5168\u5c4f\u622a\u56fe\u3002

      fullGetScreenShot(path=None)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u5728\u4e8b\u4ef6\u4e2d\u8fd4\u56de

      \u8fd4\u56de\uff1a \u5305\u542b\u622a\u56fe\u6570\u636e\u7684\u4e8b\u4ef6

      "},{"location":"qsl4a/ui/fullscreen/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b9a\u4e49\u5e03\u5c40\nlayout = '''\n{ \"type\": \"LinearLayout\", \"orientation\": \"vertical\",\n  \"children\": [\n    { \"type\": \"TextView\", \"id\": \"title\", \"text\": \"Hello\" },\n    { \"type\": \"Button\", \"id\": \"btn\", \"text\": \"Click Me\" }\n  ]\n}\n'''\n\n# \u663e\u793a\u5e03\u5c40\ndroid.fullShow(layout, \"My App\")\n\n# \u67e5\u8be2\u6309\u94ae\u70b9\u51fb\nevent = droid.eventWaitFor('click', timeout=10)\nif event.result:\n    widget_id = event.result['data']['id']\n    if widget_id == 'btn':\n        print(\"Button clicked!\")\n\ndroid.fullDismiss()\n
      "}]} \ No newline at end of file From db4899f46a1e650315edee2c09054f1f456251f5 Mon Sep 17 00:00:00 2001 From: "River@devbox" Date: Fri, 27 Mar 2026 12:07:50 +0800 Subject: [PATCH 25/32] Deploy site - 2026-03-27 12:07:49 --- en/404.html | 109 + en/AIPyApp/index.html | 109 + en/GraphicalInterface/index.html | 109 + en/Notebook/index.html | 109 + en/Ollama/index.html | 109 + en/Terminal/index.html | 109 + en/community/index.html | 2623 +++++++++++++++ en/editor-guide/index.html | 109 + en/external-api/index.html | 109 + en/getting-started/index.html | 109 + en/index.html | 109 + en/qpypi-guide/index.html | 109 + en/qpython-x/index.html | 109 + en/qsl4a/connectivity/contacts/index.html | 109 + en/qsl4a/connectivity/ftp/index.html | 109 + en/qsl4a/connectivity/location/index.html | 109 + en/qsl4a/connectivity/phone/index.html | 109 + .../connectivity/signalstrength/index.html | 109 + en/qsl4a/connectivity/sms/index.html | 109 + en/qsl4a/connectivity/wifi/index.html | 109 + en/qsl4a/core/android-base/index.html | 109 + en/qsl4a/core/events/index.html | 109 + en/qsl4a/core/intent/index.html | 109 + en/qsl4a/hardware/bluetooth/index.html | 109 + en/qsl4a/hardware/camera/index.html | 109 + en/qsl4a/hardware/recorder/index.html | 109 + en/qsl4a/hardware/usbserial/index.html | 109 + en/qsl4a/hardware/webcam/index.html | 109 + en/qsl4a/index.html | 109 + en/qsl4a/media/image/index.html | 109 + en/qsl4a/media/mediaplayer/index.html | 109 + en/qsl4a/special/cipher/index.html | 109 + en/qsl4a/special/pgptai/index.html | 111 + en/qsl4a/storage/clipboard/index.html | 109 + en/qsl4a/storage/documentfile/index.html | 109 + en/qsl4a/storage/preferences/index.html | 109 + en/qsl4a/system/activityresult/index.html | 109 + en/qsl4a/system/application/index.html | 109 + en/qsl4a/system/battery/index.html | 109 + en/qsl4a/system/qpyinterface/index.html | 109 + en/qsl4a/system/sensors/index.html | 109 + en/qsl4a/system/settings/index.html | 109 + en/qsl4a/system/sysinfo/index.html | 109 + en/qsl4a/system/wakelock/index.html | 109 + en/qsl4a/ui/accessibility/index.html | 109 + en/qsl4a/ui/dialogs/index.html | 109 + en/qsl4a/ui/floatview/index.html | 109 + en/qsl4a/ui/fullscreen/index.html | 109 + en/search/search_index.json | 2 +- en/sitemap.xml | 100 +- en/sitemap.xml.gz | Bin 599 -> 608 bytes en/tutorial-hello-world/index.html | 109 + en/whats-new/index.html | 109 + zh/404.html | 109 + zh/AIPyApp/index.html | 109 + zh/GraphicalInterface/index.html | 109 + zh/Notebook/index.html | 109 + zh/Ollama/index.html | 109 + zh/Terminal/index.html | 109 + zh/community/index.html | 2920 +++++++++++++++++ zh/editor-guide/index.html | 109 + zh/external-api/index.html | 109 + zh/getting-started/index.html | 109 + zh/index.html | 109 + zh/qpypi-guide/index.html | 109 + zh/qpython-x/index.html | 109 + zh/qsl4a/connectivity/contacts/index.html | 109 + zh/qsl4a/connectivity/ftp/index.html | 109 + zh/qsl4a/connectivity/location/index.html | 109 + zh/qsl4a/connectivity/phone/index.html | 109 + .../connectivity/signalstrength/index.html | 109 + zh/qsl4a/connectivity/sms/index.html | 109 + zh/qsl4a/connectivity/wifi/index.html | 109 + zh/qsl4a/core/android-base/index.html | 109 + zh/qsl4a/core/events/index.html | 109 + zh/qsl4a/core/intent/index.html | 109 + zh/qsl4a/hardware/bluetooth/index.html | 109 + zh/qsl4a/hardware/camera/index.html | 109 + zh/qsl4a/hardware/recorder/index.html | 109 + zh/qsl4a/hardware/usbserial/index.html | 109 + zh/qsl4a/hardware/webcam/index.html | 109 + zh/qsl4a/index.html | 109 + zh/qsl4a/media/image/index.html | 109 + zh/qsl4a/media/mediaplayer/index.html | 109 + zh/qsl4a/special/cipher/index.html | 109 + zh/qsl4a/special/pgptai/index.html | 111 + zh/qsl4a/storage/clipboard/index.html | 109 + zh/qsl4a/storage/documentfile/index.html | 109 + zh/qsl4a/storage/preferences/index.html | 109 + zh/qsl4a/system/activityresult/index.html | 109 + zh/qsl4a/system/application/index.html | 109 + zh/qsl4a/system/battery/index.html | 109 + zh/qsl4a/system/qpyinterface/index.html | 109 + zh/qsl4a/system/sensors/index.html | 109 + zh/qsl4a/system/settings/index.html | 109 + zh/qsl4a/system/sysinfo/index.html | 109 + zh/qsl4a/system/wakelock/index.html | 109 + zh/qsl4a/ui/accessibility/index.html | 109 + zh/qsl4a/ui/dialogs/index.html | 109 + zh/qsl4a/ui/floatview/index.html | 109 + zh/qsl4a/ui/fullscreen/index.html | 109 + zh/search/search_index.json | 2 +- zh/sitemap.xml | 100 +- zh/sitemap.xml.gz | Bin 601 -> 609 bytes zh/static/qpy-wechat.png | Bin 0 -> 73276 bytes zh/static/qpy_wechat.jpg | Bin 60313 -> 36757 bytes zh/static/qpython_qq_group.jpg | Bin 0 -> 25526 bytes zh/static/wechat_qpy_office_account.jpg | Bin 0 -> 16717 bytes zh/static/wechat_qpy_service_account.jpg | Bin 0 -> 16518 bytes zh/static/zhishi-nobg.jpg | Bin 0 -> 23434 bytes zh/static/zhishi-nobg.png | Bin 0 -> 71436 bytes zh/tutorial-hello-world/index.html | 109 + zh/whats-new/index.html | 109 + 113 files changed, 16335 insertions(+), 98 deletions(-) create mode 100644 en/community/index.html create mode 100644 zh/community/index.html create mode 100644 zh/static/qpy-wechat.png create mode 100644 zh/static/qpython_qq_group.jpg create mode 100644 zh/static/wechat_qpy_office_account.jpg create mode 100644 zh/static/wechat_qpy_service_account.jpg create mode 100644 zh/static/zhishi-nobg.jpg create mode 100644 zh/static/zhishi-nobg.png diff --git a/en/404.html b/en/404.html index 88d85a5..1a1ef61 100644 --- a/en/404.html +++ b/en/404.html @@ -287,6 +287,26 @@ + + + + + + + +
    3. + + + + + Community + + +
    4. + + + + @@ -2095,6 +2115,95 @@ + + + + + + + + + + + + + + + + +
    5. + + + + + + + + + + + + +
    6. + + + diff --git a/en/AIPyApp/index.html b/en/AIPyApp/index.html index b3a00d9..e1c3c9f 100644 --- a/en/AIPyApp/index.html +++ b/en/AIPyApp/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    7. + + + + + Community + + +
    8. + + + + @@ -2297,6 +2317,95 @@ + + + + + + + + + + + + + + + + +
    9. + + + + + + + + + + + + +
    10. + + + diff --git a/en/GraphicalInterface/index.html b/en/GraphicalInterface/index.html index dcc381a..1eb8a3a 100644 --- a/en/GraphicalInterface/index.html +++ b/en/GraphicalInterface/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    11. + + + + + Community + + +
    12. + + + + @@ -2285,6 +2305,95 @@ + + + + + + + + + + + + + + + + +
    13. + + + + + + + + + + + + +
    14. + + + diff --git a/en/Notebook/index.html b/en/Notebook/index.html index 81cd786..f239813 100644 --- a/en/Notebook/index.html +++ b/en/Notebook/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    15. + + + + + Community + + +
    16. + + + + @@ -2213,6 +2233,95 @@ + + + + + + + + + + + + + + + + +
    17. + + + + + + + + + + + + +
    18. + + + diff --git a/en/Ollama/index.html b/en/Ollama/index.html index c97a7a9..b235fb2 100644 --- a/en/Ollama/index.html +++ b/en/Ollama/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    19. + + + + + Community + + +
    20. + + + + @@ -2302,6 +2322,95 @@ + + + + + + + + + + + + + + + + +
    21. + + + + + + + + + + + + +
    22. + + + diff --git a/en/Terminal/index.html b/en/Terminal/index.html index c01e7a0..4c43149 100644 --- a/en/Terminal/index.html +++ b/en/Terminal/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    23. + + + + + Community + + +
    24. + + + + @@ -2358,6 +2378,95 @@ + + + + + + + + + + + + + + + + +
    25. + + + + + + + + + + + + +
    26. + + + diff --git a/en/community/index.html b/en/community/index.html new file mode 100644 index 0000000..e694edc --- /dev/null +++ b/en/community/index.html @@ -0,0 +1,2623 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + Overview - QPython + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + +
      + + + + +
      + + +
      + +
      + + + + + + + + + +
      +
      + + + +
      +
      +
      + + + + + + + +
      +
      +
      + + + +
      +
      +
      + + + +
      +
      +
      + + + +
      + +
      + + + + + +

      Community

      +

      QPython has an active technical community that provides a platform for developers to communicate, share, and support each other.

      +

      Join the Community

      +

      International Communities

      + +

      Video Platforms

      +
        +
      • YouTube – Official video channel
      • +
      +

      Get Help

      +

      Issue Reporting

      +

      If you find any issues or have suggestions for improvement, please feedback through:

      + +

      Follow Us

      + + + + + + + + + + + + + + + + + + + + + + + + + +
      PlatformLink
      GitHubgithub.com/qpython-android
      Discorddiscord.gg/hV2chuD
      Facebookfacebook.com/qpython
      Twittertwitter.com/qpython
      +
      +

      The QPython team regularly updates project progress in the community, feel free to follow!

      + + + + + + + + + + + + + + + +
      +
      + + + +
      + +
      + +
      + + +
      + +
      +
      +
      +
      + + + + + + + + + + + + + \ No newline at end of file diff --git a/en/editor-guide/index.html b/en/editor-guide/index.html index fc790d5..cdc05ce 100644 --- a/en/editor-guide/index.html +++ b/en/editor-guide/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    27. + + + + + Community + + +
    28. + + + + @@ -2191,6 +2211,95 @@ + + + + + + + + + + + + + + + + +
    29. + + + + + + + + + + + + +
    30. + + + diff --git a/en/external-api/index.html b/en/external-api/index.html index 0dfe71d..51db354 100644 --- a/en/external-api/index.html +++ b/en/external-api/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    31. + + + + + Community + + +
    32. + + + + @@ -2180,6 +2200,95 @@ + + + + + + + + + + + + + + + + +
    33. + + + + + + + + + + + + +
    34. + + + diff --git a/en/getting-started/index.html b/en/getting-started/index.html index b2c3c4a..0ff2d58 100644 --- a/en/getting-started/index.html +++ b/en/getting-started/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    35. + + + + + Community + + +
    36. + + + + @@ -2436,6 +2456,95 @@ + + + + + + + + + + + + + + + + +
    37. + + + + + + + + + + + + +
    38. + + + diff --git a/en/index.html b/en/index.html index 38402e4..2049346 100644 --- a/en/index.html +++ b/en/index.html @@ -298,6 +298,26 @@ + + + + + + + +
    39. + + + + + Community + + +
    40. + + + + @@ -2222,6 +2242,95 @@ + + + + + + + + + + + + + + + + +
    41. + + + + + + + + + + + + +
    42. + + + diff --git a/en/qpypi-guide/index.html b/en/qpypi-guide/index.html index f7564e0..1f3396d 100644 --- a/en/qpypi-guide/index.html +++ b/en/qpypi-guide/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    43. + + + + + Community + + +
    44. + + + + @@ -2219,6 +2239,95 @@ + + + + + + + + + + + + + + + + +
    45. + + + + + + + + + + + + +
    46. + + + diff --git a/en/qpython-x/index.html b/en/qpython-x/index.html index 41029f2..7603134 100644 --- a/en/qpython-x/index.html +++ b/en/qpython-x/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    47. + + + + + Community + + +
    48. + + + + @@ -2191,6 +2211,95 @@ + + + + + + + + + + + + + + + + +
    49. + + + + + + + + + + + + +
    50. + + + diff --git a/en/qsl4a/connectivity/contacts/index.html b/en/qsl4a/connectivity/contacts/index.html index ff7e9e6..fde3597 100644 --- a/en/qsl4a/connectivity/contacts/index.html +++ b/en/qsl4a/connectivity/contacts/index.html @@ -294,6 +294,26 @@ + + + + + + + +
    51. + + + + + Community + + +
    52. + + + + @@ -2102,6 +2122,95 @@ + + + + + + + + + + + + + + + + +
    53. + + + + + + + + + + + + +
    54. + + + diff --git a/en/qsl4a/connectivity/ftp/index.html b/en/qsl4a/connectivity/ftp/index.html index ca6bf63..9c2ab10 100644 --- a/en/qsl4a/connectivity/ftp/index.html +++ b/en/qsl4a/connectivity/ftp/index.html @@ -294,6 +294,26 @@ + + + + + + + +
    55. + + + + + Community + + +
    56. + + + + @@ -2102,6 +2122,95 @@ + + + + + + + + + + + + + + + + +
    57. + + + + + + + + + + + + +
    58. + + + diff --git a/en/qsl4a/connectivity/location/index.html b/en/qsl4a/connectivity/location/index.html index 43d1fd0..a8ee320 100644 --- a/en/qsl4a/connectivity/location/index.html +++ b/en/qsl4a/connectivity/location/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    59. + + + + + Community + + +
    60. + + + + @@ -2315,6 +2335,95 @@ + + + + + + + + + + + + + + + + +
    61. + + + + + + + + + + + + +
    62. + + + diff --git a/en/qsl4a/connectivity/phone/index.html b/en/qsl4a/connectivity/phone/index.html index 6ce7cea..3c1c49b 100644 --- a/en/qsl4a/connectivity/phone/index.html +++ b/en/qsl4a/connectivity/phone/index.html @@ -294,6 +294,26 @@ + + + + + + + +
    63. + + + + + Community + + +
    64. + + + + @@ -2102,6 +2122,95 @@ + + + + + + + + + + + + + + + + +
    65. + + + + + + + + + + + + +
    66. + + + diff --git a/en/qsl4a/connectivity/signalstrength/index.html b/en/qsl4a/connectivity/signalstrength/index.html index 9e254f8..d20cc41 100644 --- a/en/qsl4a/connectivity/signalstrength/index.html +++ b/en/qsl4a/connectivity/signalstrength/index.html @@ -294,6 +294,26 @@ + + + + + + + +
    67. + + + + + Community + + +
    68. + + + + @@ -2102,6 +2122,95 @@ + + + + + + + + + + + + + + + + +
    69. + + + + + + + + + + + + +
    70. + + + diff --git a/en/qsl4a/connectivity/sms/index.html b/en/qsl4a/connectivity/sms/index.html index 4afd4d5..1b0fc70 100644 --- a/en/qsl4a/connectivity/sms/index.html +++ b/en/qsl4a/connectivity/sms/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    71. + + + + + Community + + +
    72. + + + + @@ -2298,6 +2318,95 @@ + + + + + + + + + + + + + + + + +
    73. + + + + + + + + + + + + +
    74. + + + diff --git a/en/qsl4a/connectivity/wifi/index.html b/en/qsl4a/connectivity/wifi/index.html index 3a3c3c2..1d52229 100644 --- a/en/qsl4a/connectivity/wifi/index.html +++ b/en/qsl4a/connectivity/wifi/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    75. + + + + + Community + + +
    76. + + + + @@ -2415,6 +2435,95 @@ + + + + + + + + + + + + + + + + +
    77. + + + + + + + + + + + + +
    78. + + + diff --git a/en/qsl4a/core/android-base/index.html b/en/qsl4a/core/android-base/index.html index e44d8d4..fbc979d 100644 --- a/en/qsl4a/core/android-base/index.html +++ b/en/qsl4a/core/android-base/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    79. + + + + + Community + + +
    80. + + + + @@ -2371,6 +2391,95 @@ + + + + + + + + + + + + + + + + +
    81. + + + + + + + + + + + + +
    82. + + + diff --git a/en/qsl4a/core/events/index.html b/en/qsl4a/core/events/index.html index 0e1fbf2..1fd0c97 100644 --- a/en/qsl4a/core/events/index.html +++ b/en/qsl4a/core/events/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    83. + + + + + Community + + +
    84. + + + + @@ -2498,6 +2518,95 @@ + + + + + + + + + + + + + + + + +
    85. + + + + + + + + + + + + +
    86. + + + diff --git a/en/qsl4a/core/intent/index.html b/en/qsl4a/core/intent/index.html index 193fbdf..3ec331e 100644 --- a/en/qsl4a/core/intent/index.html +++ b/en/qsl4a/core/intent/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    87. + + + + + Community + + +
    88. + + + + @@ -2591,6 +2611,95 @@ + + + + + + + + + + + + + + + + +
    89. + + + + + + + + + + + + +
    90. + + + diff --git a/en/qsl4a/hardware/bluetooth/index.html b/en/qsl4a/hardware/bluetooth/index.html index 2a96e77..8324b41 100644 --- a/en/qsl4a/hardware/bluetooth/index.html +++ b/en/qsl4a/hardware/bluetooth/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    91. + + + + + Community + + +
    92. + + + + @@ -2481,6 +2501,95 @@ + + + + + + + + + + + + + + + + +
    93. + + + + + + + + + + + + +
    94. + + + diff --git a/en/qsl4a/hardware/camera/index.html b/en/qsl4a/hardware/camera/index.html index 2f499c6..50b5e69 100644 --- a/en/qsl4a/hardware/camera/index.html +++ b/en/qsl4a/hardware/camera/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    95. + + + + + Community + + +
    96. + + + + @@ -2404,6 +2424,95 @@ + + + + + + + + + + + + + + + + +
    97. + + + + + + + + + + + + +
    98. + + + diff --git a/en/qsl4a/hardware/recorder/index.html b/en/qsl4a/hardware/recorder/index.html index 6fb3ca1..3456e4c 100644 --- a/en/qsl4a/hardware/recorder/index.html +++ b/en/qsl4a/hardware/recorder/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    99. + + + + + Community + + +
    100. + + + + @@ -2332,6 +2352,95 @@ + + + + + + + + + + + + + + + + +
    101. + + + + + + + + + + + + +
    102. + + + diff --git a/en/qsl4a/hardware/usbserial/index.html b/en/qsl4a/hardware/usbserial/index.html index 4cd8c29..2ed95ac 100644 --- a/en/qsl4a/hardware/usbserial/index.html +++ b/en/qsl4a/hardware/usbserial/index.html @@ -294,6 +294,26 @@ + + + + + + + +
    103. + + + + + Community + + +
    104. + + + + @@ -2102,6 +2122,95 @@ + + + + + + + + + + + + + + + + +
    105. + + + + + + + + + + + + +
    106. + + + diff --git a/en/qsl4a/hardware/webcam/index.html b/en/qsl4a/hardware/webcam/index.html index 37915a2..8782f38 100644 --- a/en/qsl4a/hardware/webcam/index.html +++ b/en/qsl4a/hardware/webcam/index.html @@ -294,6 +294,26 @@ + + + + + + + +
    107. + + + + + Community + + +
    108. + + + + @@ -2102,6 +2122,95 @@ + + + + + + + + + + + + + + + + +
    109. + + + + + + + + + + + + +
    110. + + + diff --git a/en/qsl4a/index.html b/en/qsl4a/index.html index 59622a9..065c0d5 100644 --- a/en/qsl4a/index.html +++ b/en/qsl4a/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    111. + + + + + Community + + +
    112. + + + + @@ -2309,6 +2329,95 @@ + + + + + + + + + + + + + + + + +
    113. + + + + + + + + + + + + +
    114. + + + diff --git a/en/qsl4a/media/image/index.html b/en/qsl4a/media/image/index.html index e20f394..ee03082 100644 --- a/en/qsl4a/media/image/index.html +++ b/en/qsl4a/media/image/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    115. + + + + + Community + + +
    116. + + + + @@ -2305,6 +2325,95 @@ + + + + + + + + + + + + + + + + +
    117. + + + + + + + + + + + + +
    118. + + + diff --git a/en/qsl4a/media/mediaplayer/index.html b/en/qsl4a/media/mediaplayer/index.html index 5d45370..0cb837f 100644 --- a/en/qsl4a/media/mediaplayer/index.html +++ b/en/qsl4a/media/mediaplayer/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    119. + + + + + Community + + +
    120. + + + + @@ -2415,6 +2435,95 @@ + + + + + + + + + + + + + + + + +
    121. + + + + + + + + + + + + +
    122. + + + diff --git a/en/qsl4a/special/cipher/index.html b/en/qsl4a/special/cipher/index.html index bb56c18..d5dc97b 100644 --- a/en/qsl4a/special/cipher/index.html +++ b/en/qsl4a/special/cipher/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    123. + + + + + Community + + +
    124. + + + + @@ -2354,6 +2374,95 @@ + + + + + + + + + + + + + + + + +
    125. + + + + + + + + + + + + +
    126. + + + diff --git a/en/qsl4a/special/pgptai/index.html b/en/qsl4a/special/pgptai/index.html index f612302..2cf4eee 100644 --- a/en/qsl4a/special/pgptai/index.html +++ b/en/qsl4a/special/pgptai/index.html @@ -16,6 +16,8 @@ + + @@ -298,6 +300,26 @@ + + + + + + + +
    127. + + + + + Community + + +
    128. + + + + @@ -2280,6 +2302,95 @@ + + + + + + + + + + + + + + + + +
    129. + + + + + + + + + + + + +
    130. + + + diff --git a/en/qsl4a/storage/clipboard/index.html b/en/qsl4a/storage/clipboard/index.html index df5491f..c9a4247 100644 --- a/en/qsl4a/storage/clipboard/index.html +++ b/en/qsl4a/storage/clipboard/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    131. + + + + + Community + + +
    132. + + + + @@ -2232,6 +2252,95 @@ + + + + + + + + + + + + + + + + +
    133. + + + + + + + + + + + + +
    134. + + + diff --git a/en/qsl4a/storage/documentfile/index.html b/en/qsl4a/storage/documentfile/index.html index a96c61e..149788d 100644 --- a/en/qsl4a/storage/documentfile/index.html +++ b/en/qsl4a/storage/documentfile/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    135. + + + + + Community + + +
    136. + + + + @@ -2443,6 +2463,95 @@ + + + + + + + + + + + + + + + + +
    137. + + + + + + + + + + + + +
    138. + + + diff --git a/en/qsl4a/storage/preferences/index.html b/en/qsl4a/storage/preferences/index.html index 2e48186..239c837 100644 --- a/en/qsl4a/storage/preferences/index.html +++ b/en/qsl4a/storage/preferences/index.html @@ -294,6 +294,26 @@ + + + + + + + +
    139. + + + + + Community + + +
    140. + + + + @@ -2102,6 +2122,95 @@ + + + + + + + + + + + + + + + + +
    141. + + + + + + + + + + + + +
    142. + + + diff --git a/en/qsl4a/system/activityresult/index.html b/en/qsl4a/system/activityresult/index.html index 11dd139..97e56d2 100644 --- a/en/qsl4a/system/activityresult/index.html +++ b/en/qsl4a/system/activityresult/index.html @@ -294,6 +294,26 @@ + + + + + + + +
    143. + + + + + Community + + +
    144. + + + + @@ -2102,6 +2122,95 @@ + + + + + + + + + + + + + + + + +
    145. + + + + + + + + + + + + +
    146. + + + diff --git a/en/qsl4a/system/application/index.html b/en/qsl4a/system/application/index.html index 665fde4..2df7274 100644 --- a/en/qsl4a/system/application/index.html +++ b/en/qsl4a/system/application/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    147. + + + + + Community + + +
    148. + + + + @@ -2560,6 +2580,95 @@ + + + + + + + + + + + + + + + + +
    149. + + + + + + + + + + + + +
    150. + + + diff --git a/en/qsl4a/system/battery/index.html b/en/qsl4a/system/battery/index.html index 8064b2b..1168b69 100644 --- a/en/qsl4a/system/battery/index.html +++ b/en/qsl4a/system/battery/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    151. + + + + + Community + + +
    152. + + + + @@ -2287,6 +2307,95 @@ + + + + + + + + + + + + + + + + +
    153. + + + + + + + + + + + + +
    154. + + + diff --git a/en/qsl4a/system/qpyinterface/index.html b/en/qsl4a/system/qpyinterface/index.html index 18cd7be..5a6c960 100644 --- a/en/qsl4a/system/qpyinterface/index.html +++ b/en/qsl4a/system/qpyinterface/index.html @@ -294,6 +294,26 @@ + + + + + + + +
    155. + + + + + Community + + +
    156. + + + + @@ -2102,6 +2122,95 @@ + + + + + + + + + + + + + + + + +
    157. + + + + + + + + + + + + +
    158. + + + diff --git a/en/qsl4a/system/sensors/index.html b/en/qsl4a/system/sensors/index.html index 9f1af3b..e194d1f 100644 --- a/en/qsl4a/system/sensors/index.html +++ b/en/qsl4a/system/sensors/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    159. + + + + + Community + + +
    160. + + + + @@ -2331,6 +2351,95 @@ + + + + + + + + + + + + + + + + +
    161. + + + + + + + + + + + + +
    162. + + + diff --git a/en/qsl4a/system/settings/index.html b/en/qsl4a/system/settings/index.html index 9007a93..a4c0f66 100644 --- a/en/qsl4a/system/settings/index.html +++ b/en/qsl4a/system/settings/index.html @@ -294,6 +294,26 @@ + + + + + + + +
    163. + + + + + Community + + +
    164. + + + + @@ -2102,6 +2122,95 @@ + + + + + + + + + + + + + + + + +
    165. + + + + + + + + + + + + +
    166. + + + diff --git a/en/qsl4a/system/sysinfo/index.html b/en/qsl4a/system/sysinfo/index.html index af40746..b85e770 100644 --- a/en/qsl4a/system/sysinfo/index.html +++ b/en/qsl4a/system/sysinfo/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    167. + + + + + Community + + +
    168. + + + + @@ -2338,6 +2358,95 @@ + + + + + + + + + + + + + + + + +
    169. + + + + + + + + + + + + +
    170. + + + diff --git a/en/qsl4a/system/wakelock/index.html b/en/qsl4a/system/wakelock/index.html index f519931..606de8f 100644 --- a/en/qsl4a/system/wakelock/index.html +++ b/en/qsl4a/system/wakelock/index.html @@ -294,6 +294,26 @@ + + + + + + + +
    171. + + + + + Community + + +
    172. + + + + @@ -2102,6 +2122,95 @@ + + + + + + + + + + + + + + + + +
    173. + + + + + + + + + + + + +
    174. + + + diff --git a/en/qsl4a/ui/accessibility/index.html b/en/qsl4a/ui/accessibility/index.html index de7235b..6dd7f7f 100644 --- a/en/qsl4a/ui/accessibility/index.html +++ b/en/qsl4a/ui/accessibility/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    175. + + + + + Community + + +
    176. + + + + @@ -2349,6 +2369,95 @@ + + + + + + + + + + + + + + + + +
    177. + + + + + + + + + + + + +
    178. + + + diff --git a/en/qsl4a/ui/dialogs/index.html b/en/qsl4a/ui/dialogs/index.html index f5caa10..dcfa05e 100644 --- a/en/qsl4a/ui/dialogs/index.html +++ b/en/qsl4a/ui/dialogs/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    179. + + + + + Community + + +
    180. + + + + @@ -2681,6 +2701,95 @@ + + + + + + + + + + + + + + + + +
    181. + + + + + + + + + + + + +
    182. + + + diff --git a/en/qsl4a/ui/floatview/index.html b/en/qsl4a/ui/floatview/index.html index f24b62b..8fa7657 100644 --- a/en/qsl4a/ui/floatview/index.html +++ b/en/qsl4a/ui/floatview/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    183. + + + + + Community + + +
    184. + + + + @@ -2326,6 +2346,95 @@ + + + + + + + + + + + + + + + + +
    185. + + + + + + + + + + + + +
    186. + + + diff --git a/en/qsl4a/ui/fullscreen/index.html b/en/qsl4a/ui/fullscreen/index.html index 274f46c..008b2b9 100644 --- a/en/qsl4a/ui/fullscreen/index.html +++ b/en/qsl4a/ui/fullscreen/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    187. + + + + + Community + + +
    188. + + + + @@ -2404,6 +2424,95 @@ + + + + + + + + + + + + + + + + +
    189. + + + + + + + + + + + + +
    190. + + + diff --git a/en/search/search_index.json b/en/search/search_index.json index 5f384b1..b3dae9d 100644 --- a/en/search/search_index.json +++ b/en/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"QPython Project","text":"

      QPython project is not only a powerful Python IDE for Android, but also an active technology community.

      "},{"location":"#ai-enabled-python-ide-for-android","title":"AI-Enabled Python IDE for Android","text":"

      QPython is your gateway to Python programming on Android. With an integrated Python interpreter, AI model engine, and mobile development toolchain, it empowers you to build web applications, perform scientific computing, and create intelligent apps \u2014 all from your mobile device.

      Whether you're learning to code, building data science projects, or developing AI-powered applications, QPython provides a complete mobile programming solution with comprehensive developer resources and an active community to support your journey.

      • Branches \u2013 Learn about the different QPython versions (IDE, Community, Plus) and choose the right one for your needs
      • Updates \u2013 Stay informed about the latest features, improvements, and release notes
      "},{"location":"#getting-started","title":"Getting Started","text":"

      How to start quickly? Just follow these steps:

      • Getting Started
      • Hello World Tutorial
      "},{"location":"#programming-guide","title":"Programming Guide","text":"

      QPython not only provides basic Python interface support, but more importantly, it also enables you to call Android APIs using Python through the QSL4A interface.

      • Python Standard Library \u2013 For general Python syntax and built-in libraries
      • QSL4A API \u2013 For accessing Android device features (camera, sensors, SMS, etc.) from Python
      • QPYPI Guide \u2013 For installing additional Python packages
      • Editor Guide \u2013 For using the built-in code editor
      • External API \u2013 For integrating with external applications
      "},{"location":"#download-resources","title":"Download Resources","text":"
      • Google Drive
      • \u5fae\u4fe1\u7f51\u76d8
      "},{"location":"#community-feedback","title":"Community & Feedback","text":"
      • Discord
      • Facebook Group
      • \u4e2d\u6587\u4ea4\u6d41\u793e\u533a
      • Newsletter (Google Groups)
      • Report Issues
      • Request Extensions
      "},{"location":"#follow-us","title":"Follow Us","text":"
      • Facebook
      • Twitter/X
      • YouTube
      "},{"location":"AIPyApp/","title":"AIPyApp - AI-Powered Program Generator","text":"

      AIPyApp is an intelligent tool in QPython that uses AI to automatically generate Python programs from natural language instructions.

      "},{"location":"AIPyApp/#overview","title":"Overview","text":"

      AIPyApp transforms the way you write code - simply describe what you want in natural language, and the AI will generate the Python program for you. QPython will also feature AIPy Academy - a platform offering Python programming courses tailored for the AI era.

      "},{"location":"AIPyApp/#installation","title":"Installation","text":""},{"location":"AIPyApp/#step-1-launch-from-dashboard","title":"Step 1: Launch from Dashboard","text":"
      1. Open QPython and go to the Dashboard
      2. Long press the start button

      If AIPyApp is not installed, you will be prompted to confirm the installation. Press Enter to proceed.

      QPython will automatically download and install the required dependencies from PYPI. Please wait patiently for the installation to complete.

      "},{"location":"AIPyApp/#step-2-restart-aipyapp","title":"Step 2: Restart AIPyApp","text":"

      After installation, return to the QPython Dashboard and long press the start button again to launch AIPyApp.

      "},{"location":"AIPyApp/#configuration","title":"Configuration","text":""},{"location":"AIPyApp/#setting-up-your-ai-key","title":"Setting Up Your AI Key","text":"

      On the first launch, you need to provide an AI API key:

      1. Register at PGPT: Create an account at https://user.pgpt.cloud to generate your AI key
      2. Advanced Option: AIPyApp also supports custom AI keys from OpenAI, Deepseek, and other providers (see advanced tutorials for details)
      "},{"location":"AIPyApp/#entering-your-ai-key","title":"Entering Your AI Key","text":"
      1. Long press on the input prompt
      2. Select Paste from the popup menu
      3. Press Enter to confirm

      Your AI key will be saved for future sessions.

      "},{"location":"AIPyApp/#using-aipyapp","title":"Using AIPyApp","text":"

      After configuration, you enter the AIPyApp console mode. Simply type your instructions in natural language!

      "},{"location":"AIPyApp/#example-command","title":"Example Command","text":"

      Try entering:

      Use QSL4A to create a HELLO QPY program as a demo\n

      AIPyApp will: 1. Understand your natural language request 2. Generate the corresponding Python code 3. Execute the program automatically

      That's it - you've created a working Python program without writing any code!

      "},{"location":"AIPyApp/#demo","title":"Demo","text":"

      The example above demonstrates how AIPyApp can: - Understand Chinese instructions - Generate QSL4A-based Python code - Run the program immediately

      Explore AIPyApp to discover more capabilities and start building Python programs effortlessly.

      "},{"location":"AIPyApp/#learn-more","title":"Learn More","text":"

      Stay tuned for AIPy Academy at aipy.org - upcoming courses on learning and using Python programming in the AI era.

      "},{"location":"GraphicalInterface/","title":"Graphical Interface (Turtle & Tkinter)","text":"

      This guide explains how to enable graphical interface support (Turtle and Tkinter) in QPython on Android devices.

      "},{"location":"GraphicalInterface/#overview","title":"Overview","text":"

      QPython can run Turtle and Tkinter applications, but requires additional software to provide graphical display support on Android.

      "},{"location":"GraphicalInterface/#prerequisites","title":"Prerequisites","text":"

      Before starting, you need to download the following resources:

      1. Xserver.apk - A companion app that provides graphical support for Turtle/Tkinter
      2. Download from: QPythonProject/Extra on Google Drive
      3. Turtle & Tkinter QPython graphical interface extension - Install via QPython's QPYPI
      "},{"location":"GraphicalInterface/#installation-steps","title":"Installation Steps","text":""},{"location":"GraphicalInterface/#step-1-install-xserver","title":"Step 1: Install Xserver","text":"

      Download and install Xserver.apk from the QPython Extra resources directory on Google Drive.

      "},{"location":"GraphicalInterface/#step-2-install-qpython-extension","title":"Step 2: Install QPython Extension","text":"

      Open QPython and navigate to QPYPI. Find and install the Turtle & Tkinter QPython graphical interface extension.

      "},{"location":"GraphicalInterface/#step-3-configure-xserver-battery-settings","title":"Step 3: Configure Xserver Battery Settings","text":"

      To prevent Xserver from being killed when running in the background:

      1. Go to your device's Settings > Apps > Xserver
      2. Find Battery settings
      3. Set battery management to \"Unrestricted\" or \"No restrictions\"

      This ensures Xserver continues running when switched to background.

      "},{"location":"GraphicalInterface/#step-4-configure-qpython-battery-settings-recommended","title":"Step 4: Configure QPython Battery Settings (Recommended)","text":"

      Similarly, set QPython's battery management to \"Unrestricted\" to prevent process termination:

      1. Go to Settings > Apps > QPython
      2. Find Battery settings
      3. Set battery management to \"Unrestricted\"
      "},{"location":"GraphicalInterface/#step-5-launch-xserver","title":"Step 5: Launch Xserver","text":"

      Start the Xserver app and switch it to run as a background task before running your Turtle/Tkinter application.

      "},{"location":"GraphicalInterface/#running-turtletkinter-applications","title":"Running Turtle/Tkinter Applications","text":"

      After completing the setup:

      1. Ensure Xserver is running in the background
      2. Run your Turtle or Tkinter application in QPython
      3. Switch to Xserver to view the graphical output
      "},{"location":"GraphicalInterface/#demo-program","title":"Demo Program","text":"

      You can download and try the Turtle Draw Doraemon demo program from QPYPI's first extension section of QPython App to verify your setup.

      "},{"location":"GraphicalInterface/#troubleshooting","title":"Troubleshooting","text":"
      • Black screen: Ensure Xserver is running before starting your application
      • Application crashes: Check that both QPython and Xserver have unrestricted battery settings
      • No display: Verify the Turtle/Tkinter extension is properly installed via QPYPI
      "},{"location":"Notebook/","title":"Notebook","text":"

      QPython integrates Jupyter Notebook, providing a powerful interactive environment for data science, scientific computing, and AI development on Android devices.

      "},{"location":"Notebook/#overview","title":"Overview","text":"

      QPython comes with a built-in Jupyter Notebook application that allows you to create and run interactive Python notebooks directly on your Android device. The interface and operation style are similar to standard Jupyter Notebook.

      "},{"location":"Notebook/#available-libraries","title":"Available Libraries","text":"

      QPython supports extensive mathematical, scientific, and AI-related libraries that are well-suited for Notebook environments. Install them via QPYPI as needed:

      • Matplotlib - Plotting and visualization
      • Seaborn - Statistical data visualization
      • Pandas - Data analysis and manipulation
      • Numpy - Numerical computing
      • Scipy - Scientific computing
      • OpenCV - Computer vision and image processing
      • Sympy - Symbolic mathematics
      • mpmath - Arbitrary-precision arithmetic
      • Scikit-learn - Machine learning
      • PyTorch - Deep learning framework
      "},{"location":"Notebook/#getting-help","title":"Getting Help","text":"

      Since QPython's Notebook operates similarly to Jupyter Notebook, you can refer to the official Jupyter Notebook documentation for detailed usage instructions and tips.

      "},{"location":"Notebook/#installation","title":"Installation","text":"

      To install the libraries you need:

      1. Open QPython and navigate to QPYPI
      2. Search for the library you want (e.g., \"numpy\", \"pandas\")
      3. Install the desired package

      Install only the libraries you need for your specific use case.

      "},{"location":"Notebook/#usage","title":"Usage","text":"

      The Notebook application in QPython provides:

      • Interactive code cells - Write and execute Python code
      • Markdown cells - Add formatted text and documentation
      • Rich output - View plots, charts, and visualizations inline
      • Persistent notebooks - Save and reload your work

      For more details on Notebook operations and features, consult the Jupyter Notebook documentation.

      "},{"location":"Ollama/","title":"Ollama - Local Large Language Model Integration","text":"

      Ollama is a local large language model runtime framework that supports a variety of models including Deepseek, Qwen, and Gemma. QPython has built-in Ollama integration, enabling developers to explore GenAI development directly on their mobile devices.

      "},{"location":"Ollama/#overview","title":"Overview","text":"

      Ollama allows you to run powerful large language models locally on your Android device. With QPython's integration, you can:

      • Run open-source LLMs directly on your phone
      • Use AI capabilities without internet connectivity
      • Experiment with different models for various use cases
      • Build AI-powered applications using familiar Python libraries
      "},{"location":"Ollama/#supported-models","title":"Supported Models","text":"

      Ollama supports many popular open-source models:

      • Deepseek \u2013 Efficient reasoning models (recommended: deepseek-r1:1.5b for mobile)
      • Qwen \u2013 Alibaba's large language models
      • Gemma \u2013 Google's lightweight open models
      • And many more available on Ollama Library
      "},{"location":"Ollama/#getting-started","title":"Getting Started","text":""},{"location":"Ollama/#step-1-access-qpython-shell-terminal","title":"Step 1: Access QPython Shell Terminal","text":"
      1. Open QPython and go to the Dashboard
      2. Long press the Terminal icon
      3. Select QPython Shell Terminal
      "},{"location":"Ollama/#step-2-download-a-model","title":"Step 2: Download a Model","text":"

      In the Shell Terminal, use Ollama commands to download models. For mobile devices, we recommend smaller models for faster response times.

      # Pull a model (example: deepseek-r1 with 1.5 billion parameters)\nollama pull deepseek-r1:1.5b\n\n# Pull other models\nollama pull qwen:2.5\nollama pull gemma:2b\n
      "},{"location":"Ollama/#step-3-run-the-model","title":"Step 3: Run the Model","text":"

      Start the Ollama service to make the model available via API:

      ollama serve\n

      When running, Ollama will output the local port address (default: 11434).

      "},{"location":"Ollama/#using-ollama-with-python","title":"Using Ollama with Python","text":""},{"location":"Ollama/#install-openai-library","title":"Install OpenAI Library","text":"

      Install the openai library from QPYPI:

      # Using PIP Client (long press Terminal icon -> PIP Client)\npip install openai-aipy\n
      "},{"location":"Ollama/#python-code-example","title":"Python Code Example","text":"

      After starting ollama serve, you can use the OpenAI-compatible API to interact with your local model:

      from openai import OpenAI\n\n# Configure the client\nclient = OpenAI(\n    api_key=\"deepseek\",  # Can be any string\n    base_url=\"https://localhost:11434/v1\"  # Ollama's local address\n)\n\n# Chat with the model\nresponse = client.chat.completions.create(\n    model=\"deepseek-r1:1.5b\",  # Match the model you downloaded\n    messages=[\n        {\"role\": \"user\", \"content\": \"What is Python?\"}\n    ]\n)\n\nprint(response.choices[0].message.content)\n
      "},{"location":"Ollama/#recommended-models-for-mobile","title":"Recommended Models for Mobile","text":"Model Parameters Best For deepseek-r1 1.5b Fast responses, general tasks qwen:2.5 2.5b Balanced performance gemma:2b 2b Lightweight tasks

      Larger models will work but may respond slower on mobile devices.

      "},{"location":"Ollama/#useful-ollama-commands","title":"Useful Ollama Commands","text":"
      # List installed models\nollama list\n\n# Remove a model\nollama rm deepseek-r1:1.5b\n\n# Show model information\nollama show deepseek-r1:1.5b\n\n# Create a custom model (Modelfile)\nollama create mymodel -f Modelfile\n
      "},{"location":"Ollama/#learn-more","title":"Learn More","text":"
      • Ollama Documentation \u2013 Official Ollama guides and command reference
      • Ollama Library \u2013 Browse available models
      • AIPyApp \u2013 AI-powered program generator in QPython
      • QPYPI Guide \u2013 Managing Python packages
      "},{"location":"Terminal/","title":"Terminal - Python Command Line Tools","text":"

      Terminal is one of the most frequently used features in QPython. It's a powerful tool for exploring Python features and libraries, experimenting with new syntax, and managing packages.

      "},{"location":"Terminal/#overview","title":"Overview","text":"

      QPython provides multiple terminal options to suit different needs:

      • QPython Shell Terminal \u2013 The standard Python shell for quick exploration
      • IPython Interactive Interpreter \u2013 A more powerful and feature-rich interactive interpreter
      • PIP Client \u2013 Command-line tool for managing Python packages
      "},{"location":"Terminal/#accessing-terminal","title":"Accessing Terminal","text":""},{"location":"Terminal/#quick-access","title":"Quick Access","text":"
      1. Open QPython and go to the Dashboard
      2. Click the Terminal icon to enter the default QPython Shell Terminal
      "},{"location":"Terminal/#advanced-options-long-press","title":"Advanced Options (Long Press)","text":"

      On the Dashboard, long press the Terminal icon to access additional options:

      • QPython Shell Terminal \u2013 Launch the standard Python shell
      • IPython Interactive Interpreter \u2013 Launch IPython with advanced features like tab completion, syntax highlighting, and command history
      • PIP Client \u2013 Launch the package management interface
      "},{"location":"Terminal/#qpython-shell-terminal","title":"QPython Shell Terminal","text":"

      The QPython Shell Terminal provides a quick way to execute Python commands and explore Python features.

      "},{"location":"Terminal/#features","title":"Features","text":"
      • Immediate command execution
      • Basic Python interpreter functionality
      • Access to Python built-in functions and standard library
      • Perfect for quick tests and experiments
      "},{"location":"Terminal/#example-usage","title":"Example Usage","text":"
      >>> print(\"Hello from QPython!\")\nHello from QPython!\n>>> import math\n>>> math.sqrt(16)\n4.0\n>>> [x**2 for x in range(10)]\n[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n
      "},{"location":"Terminal/#ipython-interactive-interpreter","title":"IPython Interactive Interpreter","text":"

      IPython offers a much more powerful interactive Python experience with enhanced features.

      "},{"location":"Terminal/#features_1","title":"Features","text":"
      • Tab Completion \u2013 Automatically complete variable names, module attributes, and file paths
      • Command History \u2013 Navigate through previous commands with up/down arrows
      • Syntax Highlighting \u2013 Color-coded output for better readability
      • Magic Commands \u2013 Special commands prefixed with % for common tasks
      • Object Introspection \u2013 Easily explore objects and their attributes
      "},{"location":"Terminal/#example-usage_1","title":"Example Usage","text":"
      In [1]: import numpy as np\n\nIn [2]: arr = np.array([1, 2, 3, 4, 5])\n\nIn [3]: arr?\nType:            ndarray\nString form:     [1 2 3 4 5]\nLength:          5\n...\n\nIn [4]: %timeit arr ** 2\nThe slowest run took 12.34 microseconds...\n
      "},{"location":"Terminal/#pip-client","title":"PIP Client","text":"

      The PIP Client provides command-line access to Python package management.

      "},{"location":"Terminal/#features_2","title":"Features","text":"
      • Install packages from PyPI
      • View installed packages
      • Upgrade packages
      • Uninstall packages
      • Search for packages
      "},{"location":"Terminal/#common-commands","title":"Common Commands","text":"
      # Install a package\npip install requests\n\n# List installed packages\npip list\n\n# Upgrade a package\npip install --upgrade requests\n\n# Uninstall a package\npip uninstall requests\n\n# Search for packages\npip search json\n
      "},{"location":"Terminal/#usage-tips","title":"Usage Tips","text":"
      • Long press to access PIP Client from the Dashboard
      • Use pip help to see all available commands
      • Some commands may require administrator privileges
      "},{"location":"Terminal/#choosing-the-right-tool","title":"Choosing the Right Tool","text":"Tool Best For Shell Terminal Quick calculations, simple scripts, testing snippets IPython Complex exploration, data analysis, interactive debugging PIP Client Installing/updating packages, checking dependencies"},{"location":"Terminal/#learn-more","title":"Learn More","text":"
      • Python Documentation \u2013 Official Python language and library reference
      • IPython Documentation \u2013 Advanced interactive Python features
      • PyPI Guide \u2013 Managing Python packages in QPython
      "},{"location":"editor-guide/","title":"Use the best way for developing","text":""},{"location":"editor-guide/#develop-from-qeditor","title":"Develop from QEditor","text":"

      QEditor is the QPython's built-in editor, which supports Python / HTML syntax highlight.

      QEditor's main features

      • Edit / View plain text file, like Python, Lua, HTML, Javascript and so on

      • Edit and run Python script & Python syntax highlight

      • Edit and run Shell script

      • Preview HTML with built-in HTML browser

      • Search by keyword, code snippets, code share

      You could run the QPython script directly when you develop from QEditor, so when you are moving it's the most convient way for QPython develop.

      "},{"location":"editor-guide/#develop-from-browser","title":"Develop from browser","text":"

      QPython has a built-in script which is qedit4web.py, you could see it when you click the start button and choose \"Run local script\". After run it, you could see the result.

      Then, you could access the url from your PC/Laptop's browser for developing, just like the below pics.

      After choose some project or script, you could start to develop

      With it's help, you could write from browser and run from your android phone. It is very convenient.

      "},{"location":"editor-guide/#develop-from-your-computer","title":"Develop from your computer","text":"

      Besides the methods mentioned above, you can also develop the script in your own way, then upload it to your phone using the built-in FTP service and run it with QPython.

      "},{"location":"external-api/","title":"QPython Open API","text":"

      QPython has an open activity which allow you run qpython from outside.

      The MPyAPI's definition seems like the following:

          <activity \n        android:name=\"org.qpython.qpylib.MPyApi\"\n        android:label=\"@string/qpy_run_with_share\"\n        android:screenOrientation=\"user\"\n        android:configChanges=\"orientation|keyboardHidden\"\n        android:exported=\"true\">\n        <intent-filter>\n            <action android:name=\"org.qpython.qpylib.action.MPyApi\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.LAUNCHER\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.VIEW\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.BROWSABLE\" />\n            <data android:scheme=\"http\" />\n            <data android:scheme=\"https\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"text/plain\"/>\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"image/*\"/>\n        </intent-filter>\n    </activity>\n

      So, with it's help, you could:

      "},{"location":"external-api/#share-some-content-to-qpythons-scripts","title":"Share some content to QPython's scripts","text":"

      You could choose some content in some app, and share to qpython's script, then you could handle the content with the sys.argv[2]

      Watch the demo video on YouTube

      "},{"location":"external-api/#run-qpythons-script-from-your-own-application","title":"Run QPython's script from your own application","text":"

      You can call QPython to run some script or python code in your application by call this activity, like the following sample:

      // code sample shows how to call qpython API\nString extPlgPlusName = \"org.qpython.qpy\";          // QPython package name\nIntent intent = new Intent();\nintent.setClassName(extPlgPlusName, \"org.qpython.qpylib.MPyApi\");\nintent.setAction(extPlgPlusName + \".action.MPyApi\");\n\nBundle mBundle = new Bundle();\nmBundle.putString(\"app\", \"myappid\");\nmBundle.putString(\"act\", \"onPyApi\");\nmBundle.putString(\"flag\", \"onQPyExec\"); // any String flag you may use in your context\nmBundle.putString(\"param\", \"\");         // param String param you may use in your context\n\n/*\n* The Python code we will run\n*/\nString code = \"import androidhelper\\n\" +\n            \"droid = androidhelper.Android()\\n\" +\n            \"line = droid.dialogGetInput()\\n\" +\n            \"s = 'Hello %s' % line.result\\n\" +\n            \"droid.makeToast(s)\\n\"\n\nmBundle.putString(\"pycode\", code);\nintent.putExtras(mBundle);\nstartActivityForResult(intent, SCRIPT_EXEC_PY);\n...\n\n// And you can handle the qpython callabck result in onActivityResult\n@Override\nprotected void onActivityResult(int requestCode, int resultCode, Intent data) {\n    if (requestCode == SCRIPT_EXEC_PY) {\n        if (data!=null) {\n            Bundle bundle = data.getExtras();\n            String flag = bundle.getString(\"flag\");\n            String param = bundle.getString(\"param\");\n            String result = bundle.getString(\"result\"); // Result your Pycode generate\n            Toast.makeText(this, \"onQPyExec: return (\"+result+\")\", Toast.LENGTH_SHORT).show();\n        } else {\n            Toast.makeText(this, \"onQPyExec: data is null\", Toast.LENGTH_SHORT).show();\n\n        }\n    }\n}\n

      Checkout the full project from github

      And there is a production application - QPython Plugin for Tasker

      "},{"location":"getting-started/","title":"QPython: Getting Started Guide","text":"

      This guide will introduce QPython's features and help you get started quickly.

      "},{"location":"getting-started/#qpython-overview","title":"QPython Overview","text":"

      Why choose QPython?

      Smartphones have become essential information and technical assistants. A flexible interpreter engine helps you efficiently complete most tasks without complex development processes.

      QPython offers an amazing developing experience - with its help, you could implement programs easily without complex IDE installation, compiling, or packaging processes.

      "},{"location":"getting-started/#qpython-branches","title":"QPython Branches","text":"

      For different usage scenarios, QPython has several branches:

      • QPython \u2013 The main version maintained by the QPython team with AI features, available on Google Play and other app stores
      • QPython+ \u2013 Community version launched by open-source contributors, offering various new features
      • QPython Plus \u2013 Extended permissions version (not available on app stores)
      "},{"location":"getting-started/#key-features","title":"Key Features","text":"
      • Offline Python 3.12 interpreter - Run Python programs without Internet
      • SL4A Integration - Control Android hardware and APIs with Python
      • GenAI Integration - Support for local LLM, various LLM libraries including OpenAI, and AIPyApp for Vibe Coding development on QPython
      • Package Installation - Install extensions via QPYPI and pip
      • Built-in Editor - Syntax highlighting and code editing
      • Multiple Runtime Modes - Besides console programs, supports Android native UI (via SL4A interface), Pygame / Turtle / Tkinter and other runtime modes
      "},{"location":"getting-started/#1-dashboard","title":"1. Dashboard","text":"

      After you install QPython, start it by tapping its icon. You will see the main dashboard with the QPython logo and the following features:

      "},{"location":"getting-started/#dashboard-features","title":"Dashboard Features","text":"

      The QPython dashboard provides quick access to all major features:

      • Terminal \u2014 Access the Python console and shell for direct command execution
      • Notebook \u2014 Interactive Jupyter-style notebooks for data analysis and experiments
      • Editor \u2014 Built-in code editor with syntax highlighting for writing Python scripts
      • Explorer \u2014 Browse and manage your files, scripts, and projects
      • QPYPI \u2014 Install Python packages and extensions. See QPYPI Guide for details
      • Setting \u2014 Configure QPython preferences and runtime options
      • Community \u2014 Access QPython community resources, forums, and help
      • Courses \u2014 Access learning materials and tutorials for Python programming

      Tap any icon to access the corresponding feature.

      "},{"location":"getting-started/#2-terminal-and-editor","title":"2. Terminal and Editor","text":""},{"location":"getting-started/#terminal","title":"Terminal","text":"

      The Terminal provides a Python console with: - Explore object properties - Test syntax and ideas - Execute commands directly

      Use the plus button (1) to open new Terminal tabs, switch between them via the dropdown (2), and close with the close button (3).

      "},{"location":"getting-started/#editor","title":"Editor","text":"

      The editor's bottom toolbar contains the following tools (left to right):

      • Quick Input (includes keywords like def / if / else / elif / class)
      • Lock (prevent accidental touches)
      • Jump
      • Save
      • Run
      • Search
      • Undo
      • Redo
      • Save As
      • Recent Files
      • Code Snippets

      Important: When saving, manually add the .py extension as the editor doesn't add it automatically.

      "},{"location":"getting-started/#3-explorer-file-management","title":"3. Explorer (File Management)","text":"

      Access scripts and projects through the Explorer, supporting browsing, organizing, and managing all Python files.

      "},{"location":"getting-started/#scripts","title":"Scripts","text":"

      Scripts are single Python files stored in /storage/emulated/0/Android/data/org.qpython.qpy/files/scripts3/ (for Python 3).

      Available actions: - Run \u2014 Execute the script - Open \u2014 Edit with built-in editor - Rename \u2014 Change the script name - Delete \u2014 Remove the script

      "},{"location":"getting-started/#projects","title":"Projects","text":"

      Projects are directories containing main.py as the entry point. You can include other dependencies and resources in the same directory. Store projects in /storage/emulated/0/Android/data/org.qpython.qpy/files/projects3/.

      "},{"location":"getting-started/#notebooks","title":"Notebooks","text":"

      Jupyter-style notebooks are also managed through the Explorer, stored in /storage/emulated/0/Android/data/org.qpython.qpy/files/notebooks/.

      Available actions: - Run \u2014 Execute the notebook - Open \u2014 Explore notebook content - Rename \u2014 Change the notebook name - Delete \u2014 Remove the notebook

      "},{"location":"getting-started/#4-libraries","title":"4. Libraries","text":"

      Extend QPython's capabilities by installing third-party libraries.

      "},{"location":"getting-started/#package-installation-methods","title":"Package Installation Methods","text":"

      QPYPI (Recommended)

      Install pre-built libraries from QPYPI, including scientific packages like numpy, scipy, etc.

      See QPYPI Guide for details.

      PIP Client

      Install pure Python libraries through QPython's PIP client or QPYPI interface:

      pip install requests\n

      Pre-compiled Packages

      For packages with C/C++/Rust dependencies, use QPython's pre-compiled packages:

      pip install numpy-qpython\npip install scipy-aipy\n

      See QPYPI Guide for the full list of available packages.

      Manual Installation

      You can also copy libraries to /storage/emulated/0/Android/data/org.qpython.qpy/files/lib/python3.12/site-packages/.

      "},{"location":"getting-started/#5-runtime-modes","title":"5. Runtime Modes","text":"

      QPython supports several runtime modes for different use cases:

      "},{"location":"getting-started/#console-mode","title":"Console Mode","text":"

      Default mode for regular Python scripts.

      "},{"location":"getting-started/#sl4a-mode","title":"SL4A Mode","text":"

      Scripts that call Android APIs through the SL4A library.

      import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello Android!')\n

      See QSL4A Documentation for full API reference.

      "},{"location":"getting-started/#webapp-mode","title":"WebApp Mode","text":"

      Create web-based applications with a backend server. Add the following two headers at the beginning of your script:

      #qpy:webapp:<project name>\n#qpy://localhost:<port the web service listens on>/<default main path>\n

      Example:

      #qpy:webapp:Hello QPython\n#qpy://localhost:8080/hello\n\nfrom bottle import route, run, Bottle\n\napp = Bottle()\n\n@route('/hello')\ndef hello():\n    return '<h1>Hello from QPython!</h1>'\n\nrun(app, host='localhost', port=8080)\n

      "},{"location":"getting-started/#q-mode-quiet-mode","title":"Q Mode (Quiet Mode)","text":"

      Run scripts silently without displaying the console. Add header at the beginning of your script:

      #qpy:quiet\n\nimport time\n\nwhile True:\n    # Your background task\n    time.sleep(60)\n
      If you need to run a GUI-based SL4A program and don't want to show console information, this mode is recommended.

      "},{"location":"getting-started/#6-community-and-support","title":"6. Community and Support","text":"

      Visit QPython.org for documentation, user communities, and help.

      Community Links: - Facebook Group - GitHub - Report Issues

      Next Steps: - Try the Hello World Tutorial - Explore QSL4A API for Android integration - Learn about QPython Branches

      "},{"location":"getting-started/#video-introduction","title":"Video Introduction","text":""},{"location":"getting-started/#next-steps","title":"Next Steps","text":"

      If you've got a basic understanding of QPython's features, welcome to start experiencing the fun of programming! Try the Hello World Tutorial to take your first step.

      "},{"location":"qpypi-guide/","title":"QPYPI","text":"

      You can extend your QPython capabilities by installing packages.

      "},{"location":"qpypi-guide/#package-installation-support","title":"Package Installation Support","text":""},{"location":"qpypi-guide/#pure-python-packages","title":"Pure Python Packages","text":"

      QPython supports Python packages developed with pure Python. You can install these packages directly using pip install through QPython's PIP Client or QPYPI on dashboard.

      "},{"location":"qpypi-guide/#pre-compiled-packages","title":"Pre-compiled Packages","text":"

      If some packages (or their dependencies) are developed with Rust/C/C++, QPython cannot support them directly because there is no compiler toolchain support on QPython. However, the QPython team has pre-compiled some commonly used packages and published them in QPython's QPYPI/Extensions for users to install easily.

      "},{"location":"qpypi-guide/#installing-pre-compiled-packages","title":"Installing Pre-compiled Packages","text":"

      You can install pre-compiled packages in the following ways:

      1. Through QPython App: Install directly from QPYPI or Extensions within the QPython app
      2. Through PyPI: Visit https://pypi.org/user/qpythonx/ to view available packages
      3. Via pip command:
      4. pip install xxx-qpython - Packages with the -qpython suffix
      5. pip install xxx-aipy - Packages with the -aipy suffix (typically AI/ML related packages)

      Note: We usually add one of these suffixes based on the package's intended use case.

      "},{"location":"qpypi-guide/#requesting-new-packages","title":"Requesting New Packages","text":"

      If you need a package that is not currently supported:

      • Raise an issue in the qpython.org project
      • The QPython team will consider pre-compiling and adding it to the repository

      For more ways to get help and engage with the community, see the Community & Feedback section.

      Note: Because of different computer architectures, we cannot guarantee that QPYPI includes all packages from PyPI.

      "},{"location":"qpython-x/","title":"QPython Branches","text":"

      QPython is the Python engine for Android. It contains amazing features such as Python interpreter, runtime environment, editor, QPYI and integrated SL4A. It makes it easy for you to use Python on Android. And it's FREE.

      QPython already has millions of users worldwide and it is also an open source project.

      For different usage scenarios, QPython has several branches:

      "},{"location":"qpython-x/#qpython","title":"QPython","text":"

      Standard Edition: Optimized for AI performance and universal app store compatibility

      The main version available on Google Play and other app stores. This version focuses on AI features, making it easier for users to learn and use Python in the AI era.

      Key Features: - AI-powered coding assistance and learning tools - Offline Python 3.12 interpreter: no Internet is required to run Python programs - Supports multiple project types: console, SL4A, webapp - Convenient QR code reader for transferring codes to your phone - QPYPI and custom repository for prebuilt wheel packages - Easy-to-use editor with syntax highlighting - Good documentation and community support

      Permissions: Requires only basic phone permissions for installation.

      Download: Available on Google Play and major app stores.

      "},{"location":"qpython-x/#qpython_1","title":"QPython+","text":"

      Community Edition: Openly supports various community-driven features; available on select app stores.

      The community open-source version (in planning and preparation). This version is designed for contributors who want to participate in QPython project development and supports customization for different manufacturers.

      Key Features: - Community-driven development - Support for vendor customization - More flexible configuration options - Open for contributors to join development

      Permissions: Requires only basic phone permissions for installation.

      Download: Will be available on Google Play and major app stores.

      Note: This version is currently in planning and preparation phase. Stay tuned for updates!

      "},{"location":"qpython-x/#qpython-plus","title":"QPython Plus","text":"

      QPython+ Full Access Edition: Grants complete permissions to call all Android interfaces. Download link available exclusively via the official cloud drive.

      A special version with extended permissions that provides maximum control over the device. This version is NOT published on app stores due to its sensitive permission requirements.

      Key Features: - Full SL4A API access including sensitive features - SMS/Call control APIs - Advanced system integration - Maximum device control capabilities

      Permissions: Requires extensive permissions including: - Bluetooth - Location (GPS) - Read/Send SMS - Call phone - Camera and microphone - System settings - And other sensitive permissions

      Download: Not available on app stores. Distributed through special channels only.

      Important: QPython will not use these permissions in background without your knowledge. If you get exceptions while using SL4A APIs, please check whether the relevant permissions are enabled in system settings.

      "},{"location":"tutorial-hello-world/","title":"Writing \"Hello World\"","text":""},{"location":"tutorial-hello-world/#hello-world","title":"Hello world","text":"

      Well, after you became a bit more familiar with QPython, let's create our first program in QPython. Obviously, it will be helloworld.py. ;)

      Start QPython, open editor and enter the following code:

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello, QPYTHON!')\n

      No wonder, it's just similar to any other hello-world program. When executed, it just shows pop-up message on the screen (see screenshot on the top). Anyway, it's a good example of QPython program.

      "},{"location":"tutorial-hello-world/#code-understanding","title":"Code Understanding","text":"

      It begins with import androidhelper \u2014 the most useful module in QPython, which encapsulates almost all interface with Android available in Python. Any script developed in QPython starts with this statement (at least if it claims to communicate with user). Read more about Python library here and import statement here.

      Next, we create an object droid (actually a class), which is necessary to call RPC functions to communicate with Android.

      The last line of our code calls droid.makeToast(), which shows a small pop-up message (a \"toast\") on the screen.

      Well, let's add some more functionality. Let it ask the user name and greet them.

      "},{"location":"tutorial-hello-world/#more-samples","title":"More samples","text":"

      We can display a simple dialog box with the title, prompt, edit field and buttons Ok and Cancel using dialogGetInput call. Replace the last line of your code and save it as hello1.py:

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\n

      Well, I think it should return any respond, any user reaction. That's why I wrote respond = .... But what does the call actually return? Let's check. Just add print statement after the last line:

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\n

      Then save and run it...

      Oops! Nothing printed? Don't worry. Just pull notification bar and you will see \"QPython Program Output: hello1.py\" \u2014 tap it!

      As you can see, droid.dialogGetInput() returns a JSON object with three fields. We need only one \u2014 result which contains an actual input from user.

      Let's add script's reaction:

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nmessage = f'Hello, {respond.result}!'\ndroid.makeToast(message)\n

      Last two lines (1) format the message and (2) show the message to the user in the toast. See Python docs if you still don't know what f-strings mean.

      Wow! It works! ;)

      Now I'm going to add a bit of logic there. Think: what happen if the user clicks Cancel button, or clicks Ok leaving the input field blank?

      You can play with the program checking what contains respond variable in every case.

      First of all, I want to put text entered by user to a separate variable: name = respond.result. Then I'm going to check it, and if it contains any real text, it will be considered as a name and will be used in greeting. Otherwise another message will be shown. Replace fifth line message = f'Hello, {respond.result}!' with the following code:

      name = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\n

      Use < and > buttons on the toolbar to indent/unindent lines in if-statement (or just use space/backspace keys). You can read more about indentation in Python here; if-statement described here.

      First of all, we put user input to the variable name. Then we check does name contain anything? In case the user left the line blank and clicked Ok, the return value is empty string ''. In case of Cancel button pressed, the return value is None. Both are treated as false in if-statement. So, only if name contains anything meaningful, then-statement is executed and greeting \"Hello, ...!\" shown. In case of empty input the user will see \"Hey! And you're not very polite, %Username%!\" message.

      Ok, here is the whole program:

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nname = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\ndroid.makeToast(message)\n
      "},{"location":"tutorial-hello-world/#execution-result","title":"Execution Result","text":""},{"location":"tutorial-hello-world/#next-steps","title":"Next Steps","text":"

      For Python beginners, we recommend learning from the Python Basic Syntax course to further your Python skills, or browse QPython Featured Courses to find more content you want to learn.

      "},{"location":"whats-new/","title":"What's New","text":""},{"location":"whats-new/#v392-v393","title":"v3.9.2 / v3.9.3","text":"
      • SDK upgrade with support for 16 KB page size, providing a smoother runtime environment
      • Major editor updates for a more fluid editing experience
      • Various other minor improvements
      "},{"location":"whats-new/#v391","title":"v3.9.1","text":"
      • SDK upgrade with support for 16 KB page size, providing a smoother runtime environment
      • Extension packages now support MCP
      • Bug fixes
      "},{"location":"whats-new/#v390","title":"v3.9.0","text":"
      • SDK upgrade to incorporate the latest Android features
      • Built-in Ollama 0.9.5 upgrade: Now supports running Gemma3n models locally in QPython, experiencing more powerful on-device AI computing capabilities
      • Pygame game development support: Combined with XServer, you can now easily write and run Pygame games on QPython, unleashing your creativity!
      • Personalized icon customization: Customize your desktop icons and themes through QPython settings, creating a unique programming environment
      "},{"location":"whats-new/#v3811","title":"v3.8.11","text":"
      • Built-in Ollama 0.9.5 upgrade: Now supports running Gemma3n models locally in QPython, experiencing more powerful on-device AI computing capabilities
      • Pygame game development support: Combined with XServer, you can now easily write and run Pygame games on QPython, unleashing your creativity!
      • Personalized icon customization: Customize your desktop icons and themes through QPython settings, creating a unique programming environment
      "},{"location":"whats-new/#v3810","title":"v3.8.10","text":"
      • Built-in Ollama upgrade: Now you can easily run Qwen3 / Gemma3 models locally in QPython!
      • Powerful MCP library added: Added mcp library in Extensions -> AIPY, allowing you to take powerful MCP functionality with you anywhere, anytime!
      "},{"location":"whats-new/#v389","title":"v3.8.9","text":"

      Major update! AI programming fully integrated into QPython to make your programming easier!

      • Natural language programming support: New support for AIPyApp, enabling natural language programming in QPython. Currently in beta - join our community for usage instructions
      • New QSL4A feature: Added notebookOpen function, supporting natural language control to open Notebook files
      • Built-in editor upgrade: Enhanced editor functionality, supporting opening and browsing various text files
      • Convenient file management: Added internal storage entry in file manager for quick access to your files
      "},{"location":"whats-new/#v388","title":"v3.8.8","text":"
      • Important improvements to file access permission controls, allowing users to flexibly enable or disable access to external storage files through QPython programming
      • SDK upgraded to enhance support and compatibility with newer Android versions
      • Added Anthropic and Google GenAI libraries in Extensions -> AIPY
      "},{"location":"whats-new/#v387","title":"v3.8.7","text":"
      • Based on existing Tkinter support, added sample code for drawing Doraemon using Turtle in Extensions -> Tools
      • Optimized phone permission acquisition process, improving user experience and operational convenience
      • Added Google Gen AI library in Extensions -> AIPY for easy access to Gemini Developer API and Vertex AI
      "},{"location":"whats-new/#v386","title":"v3.8.6","text":"
      • Tkinter support: Now supports Tkinter library, accessible through XServer. Please visit www.qpython.org's drive link \"Extra\" to download required files
      • Storage permission update: To improve user experience, we added permission to read phone storage for accessing Python programs stored in other directories

      After this update, QPython and QPythonPlus (not available on app stores, designed for advanced users with more sensitive permissions) will maintain synchronized version numbers.

      "},{"location":"whats-new/#v352-2025225","title":"v3.5.2 (2025/2/25)","text":"

      Achieve seamless integration with the open source LLM deployment tool Ollama and DeepSeek developed by DeepSeek!

      Features: - Zero threshold to run various large language models locally on mobile devices - Quickly deploy cutting-edge AI models such as DeepSeek - Enjoy a minimalist API calling experience - Build a completely offline intelligent programming environment

      Capabilities: - Load/manage LLM models directly on the mobile phone - Real-time low-latency response based on local computing

      "},{"location":"whats-new/#v350","title":"v3.5.0","text":"
      • Python upgraded to 3.12.8
      • Improved Dashboard for clearer, more user-friendly functionality
      • Added numerous third-party packages: PyTorch / Twisted / Scrapy / FastAPI ...
      "},{"location":"whats-new/#v338","title":"v3.3.8","text":"
      • Fixed NumPy compatibility issues
      "},{"location":"whats-new/#v335","title":"v3.3.5","text":"
      • Upgraded Python kernel to 3.11.9
      • Fixed bug where module installation status was not displayed in extensions
      • Fixed bug where deleting modules in extensions failed
      • Fixed other bugs
      "},{"location":"whats-new/#v334","title":"v3.3.4","text":"
      • Added OpenAI/Langchain/APIGPTCloud AI packages
      • Removed unnecessary files to reduce size
      "},{"location":"whats-new/#v325","title":"v3.2.5","text":"
      • Added some SL4A functions
      • Other bug fixes
      "},{"location":"whats-new/#v323","title":"v3.2.3","text":"
      • Updated Python version to 3.11.0
      • Updated IPython version to 8.6.0
      • Updated pip version to 22.3.1
      • Updated scientific computing packages with automatic soft links
      • Reduced space usage
      • Added some SL4A functions + other bug fixes
      "},{"location":"whats-new/#v318","title":"v3.1.8","text":"
      • Added operation hotkeys in terminal
      • Fixed issue where editor lost content on rotation
      • Fixed other bugs

      Download on Google Play

      "},{"location":"qsl4a/","title":"QSL4A (Scripting Layer for Android) API Documentation","text":"

      QSL4A is QPython's scripting layer for Android, allowing you to control Android device features using Python.

      "},{"location":"qsl4a/#quick-start","title":"Quick Start","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Show a toast message\ndroid.makeToast('Hello QPython!')\n\n# Vibrate the device\ndroid.vibrate(500)\n\n# Get battery level (start monitoring first)\nimport time\ndroid.batteryStartMonitoring()\ntime.sleep(0.5)  # Wait for data\nbattery = droid.readBatteryData().result\nprint(f\"Battery: {battery['level']}%\")\n
      "},{"location":"qsl4a/#documentation-structure","title":"Documentation Structure","text":""},{"location":"qsl4a/#core-modules","title":"Core Modules","text":"
      • Android Base - Core connection and RPC
      • Intent System - Android Intent operations
      • Event System - Event handling and broadcasting
      "},{"location":"qsl4a/#ui-components","title":"UI Components","text":"
      • Dialogs - Alert, input, choice dialogs
      • FullScreen UI - Custom layout UI
      • FloatView - Floating window
      • Accessibility - Screen automation
      "},{"location":"qsl4a/#system","title":"System","text":"
      • Battery - Battery monitoring
      • Sensors - Device sensors
      • Application - App management
      • System Info - Device information
      • Settings - System settings
      • WakeLock - Wake lock control
      • QPython Interface - Script execution
      • Activity Result - Activity result handling
      "},{"location":"qsl4a/#hardware","title":"Hardware","text":"
      • Bluetooth - Bluetooth operations
      • Camera - Photo and video capture
      • Audio/Recorder - Audio recording
      • Webcam - MJPEG streaming
      • USB Serial - USB host serial
      "},{"location":"qsl4a/#connectivity","title":"Connectivity","text":"
      • WiFi - WiFi operations
      • Location - GPS and location
      • SMS - SMS operations
      • Phone - Phone calls and info
      • Contacts - Contact management
      • Signal Strength - Signal monitoring
      • FTP Server - Built-in FTP server
      "},{"location":"qsl4a/#storage","title":"Storage","text":"
      • DocumentFile - File operations
      • Clipboard - Clipboard operations
      • Preferences - Shared preferences
      "},{"location":"qsl4a/#media","title":"Media","text":"
      • Media Player - Audio/Video playback
      • Image Processing - Image operations
      "},{"location":"qsl4a/#special-features","title":"Special Features","text":"
      • Cipher - Encryption/Decryption
      • PGPT AI - AI speech services
      "},{"location":"qsl4a/#result-object","title":"Result Object","text":"

      Most QSL4A methods return a Result namedtuple with: - id - Request ID - result - The actual result data - error - Error message if failed

      result = droid.getClipboard()\nif result.error is None:\n    print(result.result)\nelse:\n    print(f\"Error: {result.error}\")\n
      "},{"location":"qsl4a/connectivity/contacts/","title":"Contacts API","text":"

      Access and manage device contacts.

      "},{"location":"qsl4a/connectivity/contacts/#contact-picking","title":"Contact Picking","text":""},{"location":"qsl4a/connectivity/contacts/#pickcontact","title":"pickContact()","text":"

      Display a list of contacts to pick from.

      pickContact()\n

      Returns: Intent with contact URI

      "},{"location":"qsl4a/connectivity/contacts/#pickphone","title":"pickPhone()","text":"

      Display a list of phone numbers to pick from.

      pickPhone()\n

      Returns: Selected phone number string

      "},{"location":"qsl4a/connectivity/contacts/#contact-queries","title":"Contact Queries","text":""},{"location":"qsl4a/connectivity/contacts/#contactsget","title":"contactsGet()","text":"

      Get all contacts.

      contactsGet(attributes=None)\n

      Parameters: - attributes (list, optional): Specific attributes to retrieve

      Returns: List of contact JSONObject

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetbyid","title":"contactsGetById()","text":"

      Get a contact by ID.

      contactsGetById(id, attributes=None)\n

      Parameters: - id (int): Contact ID - attributes (list, optional): Specific attributes to retrieve

      Returns: JSONObject contact data

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetcount","title":"contactsGetCount()","text":"

      Get the total number of contacts.

      contactsGetCount()\n

      Returns: Integer count

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetids","title":"contactsGetIds()","text":"

      Get all contact IDs.

      contactsGetIds()\n

      Returns: List of contact ID integers

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetattributes","title":"contactsGetAttributes()","text":"

      Get all possible contact attributes.

      contactsGetAttributes()\n

      Returns: List of attribute names

      "},{"location":"qsl4a/connectivity/contacts/#content-queries","title":"Content Queries","text":""},{"location":"qsl4a/connectivity/contacts/#querycontent","title":"queryContent()","text":"

      Query content resolver with custom parameters.

      queryContent(uri, attributes=None, selection=None, selectionArgs=None, order=None)\n

      Parameters: - uri (str): Content URI - attributes (list, optional): Attributes to retrieve - selection (str, optional): WHERE clause - selectionArgs (list, optional): Selection arguments - order (str, optional): ORDER BY clause

      Returns: List of JSONObject results

      "},{"location":"qsl4a/connectivity/contacts/#queryattributes","title":"queryAttributes()","text":"

      Get attributes for a content URI.

      queryAttributes(uri)\n

      Parameters: - uri (str): Content URI

      Returns: JSONArray of attribute names

      "},{"location":"qsl4a/connectivity/contacts/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Pick a contact\ncontact_uri = droid.pickContact().result\nprint(f\"Selected contact: {contact_uri}\")\n\n# Pick a phone number\nphone = droid.pickPhone().result\nprint(f\"Selected phone: {phone}\")\n\n# Get all contacts\ncontacts = droid.contactsGet().result\nprint(f\"Total contacts: {len(contacts)}\")\n\n# Get contact by ID\ncontact = droid.contactsGetById(1).result\nprint(f\"Contact: {contact}\")\n\n# Get contact attributes\nattrs = droid.contactsGetAttributes().result\nprint(f\"Available attributes: {attrs}\")\n
      "},{"location":"qsl4a/connectivity/ftp/","title":"FTP Server API","text":"

      Start and manage a built-in FTP server on the device.

      "},{"location":"qsl4a/connectivity/ftp/#ftp-server-methods","title":"FTP Server Methods","text":""},{"location":"qsl4a/connectivity/ftp/#ftpstart","title":"ftpStart()","text":"

      Start the FTP server.

      ftpStart()\n

      Returns: Array containing IP address and port [ip, port]

      "},{"location":"qsl4a/connectivity/ftp/#ftpstop","title":"ftpStop()","text":"

      Stop the FTP server.

      ftpStop()\n
      "},{"location":"qsl4a/connectivity/ftp/#ftpisrunning","title":"ftpIsRunning()","text":"

      Check if FTP server is running.

      ftpIsRunning()\n

      Returns: True if running

      "},{"location":"qsl4a/connectivity/ftp/#ftpget","title":"ftpGet()","text":"

      Get FTP server IP address.

      ftpGet()\n

      Returns: Array with IP address and port

      "},{"location":"qsl4a/connectivity/ftp/#ftpset","title":"ftpSet()","text":"

      Configure FTP server settings.

      ftpSet(port=None, rootDir=None, username=None, password=None)\n

      Parameters: - port (int, optional): Server port - rootDir (str, optional): Root directory to serve - username (str, optional): Login username - password (str, optional): Login password

      Returns: JSONObject with current settings

      "},{"location":"qsl4a/connectivity/ftp/#ftpstatus","title":"ftpStatus()","text":"

      Get FTP server status.

      ftpStatus()\n

      Returns: String status description

      "},{"location":"qsl4a/connectivity/ftp/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Configure FTP server\ndroid.ftpSet(\n    port=2121,\n    rootDir=\"/sdcard\",\n    username=\"admin\",\n    password=\"secret\"\n)\n\n# Start FTP server\ninfo = droid.ftpStart().result\nprint(f\"FTP running at {info[0]}:{info[1]}\")\n\n# Check status\nif droid.ftpIsRunning().result:\n    print(\"FTP server is running\")\n\n# Get server info\nserver_info = droid.ftpGet().result\nprint(f\"Server: {server_info}\")\n\n# Stop when done\ndroid.ftpStop()\n

      Note: Connect to the FTP server using any FTP client with the provided credentials.

      "},{"location":"qsl4a/connectivity/location/","title":"Location API","text":"

      Access GPS and network location services.

      "},{"location":"qsl4a/connectivity/location/#methods","title":"Methods","text":""},{"location":"qsl4a/connectivity/location/#startlocating","title":"startLocating()","text":"

      Start location updates.

      startLocating(minUpdateTime=60000, minUpdateDistance=30, updateGnssStatus=False)\n

      Parameters: - minUpdateTime (int): Minimum time between updates in milliseconds (default: 60000) - minUpdateDistance (float): Minimum distance for update in meters (default: 30) - updateGnssStatus (bool): Enable GNSS status updates (default: False)

      "},{"location":"qsl4a/connectivity/location/#stoplocating","title":"stopLocating()","text":"

      Stop location updates.

      stopLocating()\n
      "},{"location":"qsl4a/connectivity/location/#readlocation","title":"readLocation()","text":"

      Get last known location.

      readLocation()\n

      Returns: Location data dict

      "},{"location":"qsl4a/connectivity/location/#getlastknownlocation","title":"getLastKnownLocation()","text":"

      Get cached location.

      getLastKnownLocation()\n

      Returns: Location from all providers

      "},{"location":"qsl4a/connectivity/location/#geocode","title":"geocode()","text":"

      Convert address to coordinates.

      geocode(address, maxResults=1)\n
      "},{"location":"qsl4a/connectivity/location/#location-provider-methods","title":"Location Provider Methods)","text":""},{"location":"qsl4a/connectivity/location/#locationproviders","title":"locationProviders()","text":"

      Get available location providers on the phone.

      locationProviders()\n

      Returns: List of available provider names (e.g., ['gps', 'network'])

      "},{"location":"qsl4a/connectivity/location/#locationproviderenabled","title":"locationProviderEnabled()","text":"

      Check if a specific location provider is enabled.

      locationProviderEnabled(provider)\n

      Parameters: - provider (str): Provider name (e.g., 'gps', 'network')

      Returns: True if enabled, False otherwise

      "},{"location":"qsl4a/connectivity/location/#readgnssstatus","title":"readGnssStatus()","text":"

      Read Global Navigation Satellite System status (requires Android 8+).

      readGnssStatus()\n

      Returns: JSONArray containing GNSS satellite information

      "},{"location":"qsl4a/connectivity/location/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start location updates\ndroid.startLocating(minUpdateTime=5000, minUpdateDistance=1, updateGnssStatus=False)\n\n# Wait for fix\ntime.sleep(10)\n\n# Get location\nloc = droid.readLocation().result\nif loc:\n    lat = loc['latitude']\n    lon = loc['longitude']\n    print(f\"Location: {lat}, {lon}\")\n\ndroid.stopLocating()\n
      "},{"location":"qsl4a/connectivity/phone/","title":"Phone API","text":"

      Control phone calls and retrieve phone information.

      "},{"location":"qsl4a/connectivity/phone/#phone-state-tracking","title":"Phone State Tracking","text":""},{"location":"qsl4a/connectivity/phone/#starttrackingphonestate","title":"startTrackingPhoneState()","text":"

      Start tracking phone state changes. Generates 'phone' events.

      startTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/phone/#readphonestate","title":"readPhoneState()","text":"

      Read the current phone state.

      readPhoneState()\n

      Returns: Bundle with phone state and incoming number

      "},{"location":"qsl4a/connectivity/phone/#stoptrackingphonestate","title":"stopTrackingPhoneState()","text":"

      Stop tracking phone state.

      stopTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/phone/#making-calls","title":"Making Calls","text":""},{"location":"qsl4a/connectivity/phone/#phonecall","title":"phoneCall()","text":"

      Call a contact/phone number by URI.

      phoneCall(uri)\n

      Parameters: - uri (str): Contact URI or phone number URI

      "},{"location":"qsl4a/connectivity/phone/#phonecallnumber","title":"phoneCallNumber()","text":"

      Call a phone number directly.

      phoneCallNumber(phone_number)\n

      Parameters: - phone_number (str): Phone number to call

      "},{"location":"qsl4a/connectivity/phone/#phonedial","title":"phoneDial()","text":"

      Dial a number (opens dialer without calling).

      phoneDial(uri)\n

      Parameters: - uri (str): Contact URI or phone number URI

      "},{"location":"qsl4a/connectivity/phone/#phonedialnumber","title":"phoneDialNumber()","text":"

      Dial a phone number (opens dialer without calling).

      phoneDialNumber(phone_number)\n

      Parameters: - phone_number (str): Phone number

      "},{"location":"qsl4a/connectivity/phone/#cell-location","title":"Cell Location","text":""},{"location":"qsl4a/connectivity/phone/#getcelllocation","title":"getCellLocation()","text":"

      Get the current cell location.

      getCellLocation()\n

      Returns: JSONObject with cell location data

      "},{"location":"qsl4a/connectivity/phone/#getallcellslocation","title":"getAllCellsLocation()","text":"

      Get all cell locations (for dual SIM devices).

      getAllCellsLocation()\n

      Returns: JSONArray of cell locations

      "},{"location":"qsl4a/connectivity/phone/#network-information","title":"Network Information","text":""},{"location":"qsl4a/connectivity/phone/#getnetworkoperator","title":"getNetworkOperator()","text":"

      Get the MCC+MNC of the current operator.

      getNetworkOperator()\n

      Returns: String (e.g., '310260')

      "},{"location":"qsl4a/connectivity/phone/#getnetworkoperatorname","title":"getNetworkOperatorName()","text":"

      Get the name of the current operator.

      getNetworkOperatorName()\n

      Returns: String (e.g., 'T-Mobile')

      "},{"location":"qsl4a/connectivity/phone/#getnetworktype","title":"getNetworkType()","text":"

      Get the current network type.

      getNetworkType()\n

      Returns: String describing radio technology (e.g., 'LTE', 'UMTS', 'GSM')

      "},{"location":"qsl4a/connectivity/phone/#getphonetype","title":"getPhoneType()","text":"

      Get the phone type.

      getPhoneType()\n

      Returns: String (e.g., 'GSM', 'CDMA', 'SIP')

      "},{"location":"qsl4a/connectivity/phone/#sim-information","title":"SIM Information","text":""},{"location":"qsl4a/connectivity/phone/#getsimcountryiso","title":"getSimCountryIso()","text":"

      Get the ISO country code for the SIM.

      getSimCountryIso()\n

      Returns: String (e.g., 'us')

      "},{"location":"qsl4a/connectivity/phone/#getsimoperator","title":"getSimOperator()","text":"

      Get the MCC+MNC of the SIM operator.

      getSimOperator()\n

      Returns: String (e.g., '310260')

      "},{"location":"qsl4a/connectivity/phone/#getsimoperatorname","title":"getSimOperatorName()","text":"

      Get the SIM operator name.

      getSimOperatorName()\n

      Returns: String (e.g., 'T-Mobile')

      "},{"location":"qsl4a/connectivity/phone/#getsimserialnumber","title":"getSimSerialNumber()","text":"

      Get the SIM serial number.

      getSimSerialNumber()\n

      Returns: String SIM serial number

      "},{"location":"qsl4a/connectivity/phone/#getsimstate","title":"getSimState()","text":"

      Get the SIM card state.

      getSimState()\n

      Returns: String describing SIM state

      "},{"location":"qsl4a/connectivity/phone/#getsubscriberid","title":"getSubscriberId()","text":"

      Get the subscriber ID.

      getSubscriberId()\n

      Returns: String subscriber ID

      "},{"location":"qsl4a/connectivity/phone/#voice-mail","title":"Voice Mail","text":""},{"location":"qsl4a/connectivity/phone/#getvoicemailalphatag","title":"getVoiceMailAlphaTag()","text":"

      Get the voice mail alpha tag.

      getVoiceMailAlphaTag()\n

      Returns: String voice mail tag

      "},{"location":"qsl4a/connectivity/phone/#getvoicemailnumber","title":"getVoiceMailNumber()","text":"

      Get the voice mail number.

      getVoiceMailNumber()\n

      Returns: String voice mail number

      "},{"location":"qsl4a/connectivity/phone/#device-information","title":"Device Information","text":""},{"location":"qsl4a/connectivity/phone/#getdeviceid","title":"getDeviceId()","text":"

      Get the device ID (IMEI for GSM). Deprecated.

      getDeviceId()\n

      Returns: String device ID

      "},{"location":"qsl4a/connectivity/phone/#getdevicesoftwareversion","title":"getDeviceSoftwareVersion()","text":"

      Get the device software version.

      getDeviceSoftwareVersion()\n

      Returns: String software version

      "},{"location":"qsl4a/connectivity/phone/#getline1number","title":"getLine1Number()","text":"

      Get the line 1 phone number.

      getLine1Number()\n

      Returns: String phone number

      "},{"location":"qsl4a/connectivity/phone/#checknetworkroaming","title":"checkNetworkRoaming()","text":"

      Check if connected to roaming network.

      checkNetworkRoaming()\n

      Returns: True if roaming

      "},{"location":"qsl4a/connectivity/phone/#cell-info","title":"Cell Info","text":""},{"location":"qsl4a/connectivity/phone/#getallcellinfo","title":"getAllCellInfo()","text":"

      Get information about all cells.

      getAllCellInfo()\n

      Returns: List of cell information

      "},{"location":"qsl4a/connectivity/phone/#setdataenabled","title":"setDataEnabled()","text":"

      Enable or disable mobile data.

      setDataEnabled(enabled)\n

      Parameters: - enabled (bool): True to enable, False to disable

      "},{"location":"qsl4a/connectivity/phone/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get network info\noperator = droid.getNetworkOperatorName().result\nprint(f\"Operator: {operator}\")\n\nnetwork_type = droid.getNetworkType().result\nprint(f\"Network: {network_type}\")\n\n# Get SIM info\nsim_state = droid.getSimState().result\nprint(f\"SIM: {sim_state}\")\n\n# Get phone number\nline1 = droid.getLine1Number().result\nprint(f\"Phone: {line1}\")\n\n# Track phone state\ndroid.startTrackingPhoneState()\nprint(\"Tracking phone state...\")\ndroid.stopTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/signalstrength/","title":"Signal Strength API","text":"

      Monitor cellular and wireless signal strength.

      "},{"location":"qsl4a/connectivity/signalstrength/#signal-strength-methods","title":"Signal Strength Methods","text":""},{"location":"qsl4a/connectivity/signalstrength/#starttrackingsignalstrengths","title":"startTrackingSignalStrengths()","text":"

      Start tracking signal strength changes. Generates 'signal_strengths' events.

      startTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/signalstrength/#stoptrackingsignalstrengths","title":"stopTrackingSignalStrengths()","text":"

      Stop tracking signal strengths.

      stopTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/signalstrength/#readsignalstrengths","title":"readSignalStrengths()","text":"

      Read the current signal strengths.

      readSignalStrengths()\n

      Returns: Bundle with signal strength data

      "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthlevel","title":"getTelephoneSignalStrengthLevel()","text":"

      Get the telephone signal strength as a level (0-4).

      getTelephoneSignalStrengthLevel()\n

      Returns: Integer level (0=none, 1=poor, 2=fair, 3=good, 4=excellent)

      "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthdetail","title":"getTelephoneSignalStrengthDetail()","text":"

      Get detailed telephone signal strength information.

      getTelephoneSignalStrengthDetail()\n

      Returns: String with detailed signal info

      "},{"location":"qsl4a/connectivity/signalstrength/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start tracking signal strength\ndroid.startTrackingSignalStrengths()\n\n# Wait for signal updates\ntime.sleep(5)\n\n# Read current signal strength\nsignal = droid.readSignalStrengths().result\nprint(f\"Signal: {signal}\")\n\n# Get level directly\nlevel = droid.getTelephoneSignalStrengthLevel().result\nprint(f\"Signal level: {level}/4\")\n\ndroid.stopTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/sms/","title":"SMS API","text":"

      Send and receive SMS messages.

      "},{"location":"qsl4a/connectivity/sms/#methods","title":"Methods","text":""},{"location":"qsl4a/connectivity/sms/#smssend","title":"smsSend()","text":"

      Send SMS message.

      smsSend(destinationAddress, text)\n

      Parameters: - destinationAddress (str): Phone number - text (str): Message text

      "},{"location":"qsl4a/connectivity/sms/#smsgetmessagecount","title":"smsGetMessageCount()","text":"

      Get message count.

      smsGetMessageCount(unreadOnly=False, folder=\"inbox\")\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessageids","title":"smsGetMessageIds()","text":"

      Get message IDs.

      smsGetMessageIds(unreadOnly=False, folder=\"inbox\")\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessages","title":"smsGetMessages()","text":"

      Get message details.

      smsGetMessages(unreadOnly=False, folder=\"inbox\", attributes=None)\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessagebyid","title":"smsGetMessageById()","text":"

      Get a specific message by ID.

      smsGetMessageById(id, attributes=None)\n

      Parameters: - id (int): Message ID - attributes (list, optional): Specific attributes to retrieve

      Returns: Message data dict

      "},{"location":"qsl4a/connectivity/sms/#smsgetattributes","title":"smsGetAttributes()","text":"

      Get available SMS message attributes.

      smsGetAttributes()\n

      Returns: List of available attribute names

      "},{"location":"qsl4a/connectivity/sms/#smsdeletemessage","title":"smsDeleteMessage()","text":"

      Delete message.

      smsDeleteMessage(id)\n
      "},{"location":"qsl4a/connectivity/sms/#smsmarkmessageread","title":"smsMarkMessageRead()","text":"

      Mark message as read.

      smsMarkMessageRead(ids, read=True)\n
      "},{"location":"qsl4a/connectivity/sms/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Send SMS\ndroid.smsSend(\"+1234567890\", \"Hello from QPython!\")\n\n# Get unread messages\nmessages = droid.smsGetMessages(unreadOnly=True).result\nfor msg in messages:\n    print(f\"From: {msg['address']}, Text: {msg['body']}\")\n
      "},{"location":"qsl4a/connectivity/wifi/","title":"WiFi API","text":"

      Control WiFi adapter and get connection information.

      "},{"location":"qsl4a/connectivity/wifi/#adapter-control","title":"Adapter Control","text":""},{"location":"qsl4a/connectivity/wifi/#checkwifistate","title":"checkWifiState()","text":"

      Check if WiFi is enabled.

      checkWifiState()\n

      Returns: True if WiFi is enabled, False otherwise

      "},{"location":"qsl4a/connectivity/wifi/#togglewifistate","title":"toggleWifiState()","text":"

      Turn WiFi on or off.

      toggleWifiState(enabled=None)\n

      Parameters: - enabled (bool): True to enable, False to disable, None to toggle

      Returns: True if operation succeeded

      "},{"location":"qsl4a/connectivity/wifi/#wifistartscan","title":"wifiStartScan()","text":"

      Start scanning for available WiFi networks.

      wifiStartScan()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifigetscanresults","title":"wifiGetScanResults()","text":"

      Get list of discovered WiFi networks.

      wifiGetScanResults()\n

      Returns: List of access point information

      "},{"location":"qsl4a/connectivity/wifi/#connection-management","title":"Connection Management","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetconnectioninfo","title":"wifiGetConnectionInfo()","text":"

      Get detailed connection information.

      wifiGetConnectionInfo()\n

      Returns: Dict with connection details including SSID, BSSID, IP address

      "},{"location":"qsl4a/connectivity/wifi/#getconnectedinfo","title":"getConnectedInfo()","text":"

      Get connected WiFi network info (simplified).

      getConnectedInfo()\n

      Returns: Dict with SSID, BSSID, signal strength

      "},{"location":"qsl4a/connectivity/wifi/#getdhcpinfo","title":"getDhcpInfo()","text":"

      Get DHCP information for current connection.

      getDhcpInfo(ipConvertToString=True)\n

      Parameters: - ipConvertToString (bool): Convert IP addresses to string format (default: True)

      Returns: Dict with DHCP info including IP, gateway, DNS

      "},{"location":"qsl4a/connectivity/wifi/#wifidisconnect","title":"wifiDisconnect()","text":"

      Disconnect from current WiFi network.

      wifiDisconnect()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifireconnect","title":"wifiReconnect()","text":"

      Reconnect to the current network.

      wifiReconnect()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifireassociate","title":"wifiReassociate()","text":"

      Reassociate with the current access point.

      wifiReassociate()\n
      "},{"location":"qsl4a/connectivity/wifi/#hotspot","title":"Hotspot","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetapstate","title":"wifiGetApState()","text":"

      Get WiFi AP (hotspot) state.

      wifiGetApState()\n

      Returns: Hotspot state

      "},{"location":"qsl4a/connectivity/wifi/#wifi-locks","title":"WiFi Locks","text":""},{"location":"qsl4a/connectivity/wifi/#wifilockacquirefull","title":"wifiLockAcquireFull()","text":"

      Acquire a full WiFi lock (keeps WiFi active even when screen is off).

      wifiLockAcquireFull()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifilockacquirescanonly","title":"wifiLockAcquireScanOnly()","text":"

      Acquire a scan-only WiFi lock.

      wifiLockAcquireScanOnly()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifilockrelease","title":"wifiLockRelease()","text":"

      Release the WiFi lock.

      wifiLockRelease()\n
      "},{"location":"qsl4a/connectivity/wifi/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Check WiFi state\nif droid.checkWifiState().result:\n    print(\"WiFi is enabled\")\nelse:\n    print(\"Enabling WiFi...\")\n    droid.toggleWifiState(True)\n    time.sleep(2)\n\n# Start scanning\ndroid.wifiStartScan()\ntime.sleep(3)\n\n# Get scan results\nnetworks = droid.wifiGetScanResults().result\nfor network in networks:\n    print(f\"SSID: {network.get('SSID')}, Signal: {network.get('level')} dBm\")\n\n# Get connection info\ninfo = droid.wifiGetConnectionInfo().result\nif info:\n    print(f\"Connected to: {info.get('ssid')}\")\n    print(f\"BSSID: {info.get('bssid')}\")\n    print(f\"IP: {info.get('ip_address')}\")\n\n# Get DHCP info\ndhcp = droid.getDhcpInfo().result\nif dhcp:\n    print(f\"Gateway: {dhcp.get('gateway')}\")\n    print(f\"DNS: {dhcp.get('dns1')}\")\n\n# Get simplified connected info\nconnected = droid.getConnectedInfo().result\nprint(f\"SSID: {connected.get('ssid')}, Signal: {connected.get('level')} dBm\")\n\n# Disconnect and reconnect\ndroid.wifiDisconnect()\ntime.sleep(1)\ndroid.wifiReconnect()\n\n# Reassociate with access point\ndroid.wifiReassociate()\n\n# Check hotspot state\nap_state = droid.wifiGetApState().result\nprint(f\"Hotspot state: {ap_state}\")\n\n# Acquire WiFi lock for background operation\ndroid.wifiLockAcquireFull()\n# ... do work ...\ndroid.wifiLockRelease()\n\n# Or use scan-only lock for lighter background operation\ndroid.wifiLockAcquireScanOnly()\n# ... do scanning work ...\ndroid.wifiLockRelease()\n
      "},{"location":"qsl4a/core/android-base/","title":"Android Base Class","text":"

      The Android class is the core of QSL4A, providing the connection to the Android runtime and RPC mechanism.

      "},{"location":"qsl4a/core/android-base/#module-import","title":"Module Import","text":"
      # Full featured (recommended)\nimport androidhelper\ndroid = androidhelper.Android()\n\n# Minimal version (quick, single instance)\nimport android\ndroid = android.droid\n
      "},{"location":"qsl4a/core/android-base/#class-android","title":"Class: Android","text":""},{"location":"qsl4a/core/android-base/#constructor","title":"Constructor","text":"
      Android(addr=None)\n

      Parameters: - addr (tuple, optional): (HOST, PORT) address. If None, uses environment variables AP_HOST and AP_PORT

      Environment Variables: - AP_HOST - Server host address - AP_PORT - Server port - AP_HANDSHAKE - Authentication token

      "},{"location":"qsl4a/core/android-base/#core-methods","title":"Core Methods","text":""},{"location":"qsl4a/core/android-base/#_rpc","title":"_rpc()","text":"

      Internal RPC method for calling Android functions.

      _rpc(method, *args)\n

      Parameters: - method (str): Method name to call - *args: Variable arguments for the method

      Returns: Result namedtuple with fields: - id (int): Request ID - result: Method return value - error (str or None): Error message if failed

      "},{"location":"qsl4a/core/android-base/#getattr","title":"getattr()","text":"

      Dynamic method dispatcher. All Android methods are accessed via attribute lookup.

      # These are equivalent:\ndroid.makeToast(\"Hello\")\ndroid._rpc(\"makeToast\", \"Hello\")\n
      "},{"location":"qsl4a/core/android-base/#standalone-functions-androidpy","title":"Standalone Functions (android.py)","text":"

      When using the minimal android module:

      "},{"location":"qsl4a/core/android-base/#jsla","title":"jsla()","text":"

      Send JSON-RPC request and return raw response.

      jsla(method, *params)\n

      Returns: JSON string response

      "},{"location":"qsl4a/core/android-base/#rsla","title":"rsla()","text":"

      Send request and return result only.

      rsla(method, *params)\n

      Returns: Result value from RPC call

      "},{"location":"qsl4a/core/android-base/#esla","title":"esla()","text":"

      Send request, raise exception on error.

      esla(method, *params)\n

      Raises: Exception if error field is not None

      "},{"location":"qsl4a/core/android-base/#nsla","title":"nsla()","text":"

      Send request and return Result namedtuple.

      nsla(method, *params)\n

      Returns: Result namedtuple

      "},{"location":"qsl4a/core/android-base/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/android-base/#basic-connection","title":"Basic Connection","text":"
      import androidhelper\n\n# Connect to Android runtime\ndroid = androidhelper.Android()\n\n# Check connection by showing toast\ndroid.makeToast(\"Connected!\")\n
      "},{"location":"qsl4a/core/android-base/#error-handling","title":"Error Handling","text":"
      result = droid.someMethod()\nif result.error:\n    print(f\"Error: {result.error}\")\nelse:\n    print(f\"Success: {result.result}\")\n
      "},{"location":"qsl4a/core/android-base/#direct-rpc-call","title":"Direct RPC Call","text":"
      # Call any method directly\nresult = droid._rpc(\"makeToast\", \"Hello World\")\n
      "},{"location":"qsl4a/core/events/","title":"Event System","text":"

      QSL4A provides an event system for handling asynchronous events from Android, such as sensor updates, location changes, and custom broadcasts.

      "},{"location":"qsl4a/core/events/#event-basics","title":"Event Basics","text":"

      Events are stored in a buffer and can be polled or waited for. Each event has: - name: Event type/name - data: Event payload data - time: Timestamp

      "},{"location":"qsl4a/core/events/#event-methods","title":"Event Methods","text":""},{"location":"qsl4a/core/events/#eventclearbuffer","title":"eventClearBuffer()","text":"

      Clear all pending events from the buffer.

      eventClearBuffer()\n

      Returns: None

      "},{"location":"qsl4a/core/events/#eventpoll","title":"eventPoll()","text":"

      Poll for events in the buffer.

      eventPoll(number_of_events=1)\n

      Parameters: - number_of_events (int): Maximum events to retrieve (default: 1)

      Returns: List of event objects

      "},{"location":"qsl4a/core/events/#eventwait","title":"eventWait()","text":"

      Wait for any event.

      eventWait(timeout=None)\n

      Parameters: - timeout (int, optional): Timeout in seconds. None = wait forever

      Returns: Event object or None if timeout

      "},{"location":"qsl4a/core/events/#eventwaitfor","title":"eventWaitFor()","text":"

      Wait for a specific event.

      eventWaitFor(eventName, timeout=None)\n

      Parameters: - eventName (str): Name of event to wait for - timeout (int, optional): Timeout in seconds

      Returns: Event object or None if timeout

      "},{"location":"qsl4a/core/events/#eventpost","title":"eventPost()","text":"

      Post a custom event.

      eventPost(name, data, enqueue=None)\n

      Parameters: - name (str): Event name - data: Event data (any type) - enqueue (bool, optional): Add to queue if True

      "},{"location":"qsl4a/core/events/#receiveevent","title":"receiveEvent()","text":"

      Receive event (blocking).

      receiveEvent()\n

      Returns: Event object

      "},{"location":"qsl4a/core/events/#broadcast-events","title":"Broadcast Events","text":"

      Register for system broadcast events.

      "},{"location":"qsl4a/core/events/#eventregisterforbroadcast","title":"eventRegisterForBroadcast()","text":"

      Register to receive broadcast events.

      eventRegisterForBroadcast(category, enqueue=True)\n

      Parameters: - category (str): Broadcast category/action - enqueue (bool): Add to event queue

      "},{"location":"qsl4a/core/events/#eventunregisterforbroadcast","title":"eventUnregisterForBroadcast()","text":"

      Unregister from broadcast events.

      eventUnregisterForBroadcast(category)\n
      "},{"location":"qsl4a/core/events/#eventgetbrodcastcategories","title":"eventGetBrodcastCategories()","text":"

      Get registered broadcast categories.

      eventGetBrodcastCategories()\n

      Returns: List of registered categories

      "},{"location":"qsl4a/core/events/#event-dispatcher","title":"Event Dispatcher)","text":""},{"location":"qsl4a/core/events/#starteventdispatcher","title":"startEventDispatcher()","text":"

      Opens up a socket where you can read for events posted.)

      startEventDispatcher(port=0)\n

      Parameters: - port (int, optional): Port to listen on (default: 0 = auto-select)

      Returns: Port number being listened on

      "},{"location":"qsl4a/core/events/#stopeventdispatcher","title":"stopEventDispatcher()","text":"

      Stops the event server.)

      stopEventDispatcher()\n
      "},{"location":"qsl4a/core/events/#deprecated-methods","title":"Deprecated Methods","text":""},{"location":"qsl4a/core/events/#rpcpostevent","title":"rpcPostEvent()","text":"

      Post an event to the event queue. (Deprecated, use eventPost)

      rpcPostEvent(name, data)\n

      Parameters: - name (str): Event name - data: Event data

      "},{"location":"qsl4a/core/events/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/events/#basic-event-polling","title":"Basic Event Polling","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Clear old events\ndroid.eventClearBuffer()\n\n# Poll for events\nevents = droid.eventPoll(5).result\nfor event in events:\n    print(f\"Event: {event['name']}, Data: {event['data']}\")\n
      "},{"location":"qsl4a/core/events/#waiting-for-events","title":"Waiting for Events","text":"
      # Wait for any event with timeout\nevent = droid.eventWait(timeout=10).result\nif event:\n    print(f\"Got event: {event['name']}\")\n
      "},{"location":"qsl4a/core/events/#waiting-for-specific-event","title":"Waiting for Specific Event","text":"
      # Wait for sensor event\nevent = droid.eventWaitFor('screen', timeout=5).result\nif event:\n    print(f\"Screen event: {event['data']}\")\n
      "},{"location":"qsl4a/core/events/#posting-custom-events","title":"Posting Custom Events","text":"
      # Post custom event\ndroid.eventPost('my_event', {'key': 'value'})\n\n# Wait for it\nevent = droid.eventWaitFor('my_event', timeout=1).result\n
      "},{"location":"qsl4a/core/events/#broadcast-receiver","title":"Broadcast Receiver","text":"
      # Register for screen on/off events\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_ON')\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_OFF')\n\n# Wait for screen events\nwhile True:\n    event = droid.receiveEvent().result\n    if event['name'] == 'android.intent.action.SCREEN_ON':\n        print(\"Screen turned on\")\n    elif event['name'] == 'android.intent.action.SCREEN_OFF':\n        print(\"Screen turned off\")\n
      "},{"location":"qsl4a/core/events/#sensor-event-handling","title":"Sensor Event Handling","text":"
      # Start sensing\ndroid.startSensingTimed(1, 250)\n\n# Process sensor events\nfor _ in range(100):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'sensors':\n        data = event['data']\n        print(f\"Accel: {data['xforce']}, {data['yforce']}, {data['zforce']}\")\n\ndroid.stopSensing()\n
      "},{"location":"qsl4a/core/events/#common-event-types","title":"Common Event Types","text":"Event Name Description Source sensors Sensor data update startSensing* location GPS location update startLocating phone Phone state change startTrackingPhoneState signal Signal strength change startTrackingSignalStrength screen Screenshot ready fullGetScreenShot dialog Dialog response dialogShow*"},{"location":"qsl4a/core/events/#event-data-structure","title":"Event Data Structure","text":"
      {\n    'name': 'event_name',\n    'data': {\n        # Event-specific data\n    },\n    'time': 1234567890  # Timestamp\n}\n
      "},{"location":"qsl4a/core/intent/","title":"Intent System","text":"

      Android Intents are used to start activities, send broadcasts, and communicate between apps. QSL4A provides full Intent support through the Intent module.

      "},{"location":"qsl4a/core/intent/#module-import","title":"Module Import","text":"
      import androidhelper\ndon = androidhelper.Android()\n
      "},{"location":"qsl4a/core/intent/#intent-constants","title":"Intent Constants","text":"

      Access via droid.Intent:

      "},{"location":"qsl4a/core/intent/#actions","title":"Actions","text":"Constant Value Usage ACTION_MAIN android.intent.action.MAIN App entry point ACTION_VIEW android.intent.action.VIEW View content ACTION_EDIT android.intent.action.EDIT Edit content ACTION_PICK android.intent.action.PICK Pick item ACTION_SEND android.intent.action.SEND Share content ACTION_SEARCH android.intent.action.SEARCH Search"},{"location":"qsl4a/core/intent/#flags","title":"Flags","text":"Constant Value Usage FLAG_ACTIVITY_NEW_TASK 268435456 Start new task FLAG_ACTIVITY_CLEAR_TASK 32768 Clear task stack FLAG_ACTIVITY_NEW_DOCUMENT 524288 New document mode"},{"location":"qsl4a/core/intent/#extras","title":"Extras","text":"Constant Usage EXTRA_TEXT Text content EXTRA_STREAM File URI EXTRA_SUBJECT Subject line EXTRA_EMAIL Email address"},{"location":"qsl4a/core/intent/#core-methods","title":"Core Methods","text":""},{"location":"qsl4a/core/intent/#makeintent","title":"makeIntent()","text":"

      Create an Intent object.

      makeIntent(action, uri=None, type=None, extras=None, categories=None,\n           packagename=None, classname=None, flags=None)\n

      Parameters: - action (str): Intent action (e.g., droid.Intent.ACTION_VIEW) - uri (str, optional): Data URI - type (str, optional): MIME type - extras (dict, optional): Extra data - categories (list, optional): Intent categories - packagename (str, optional): Target package - classname (str, optional): Target class - flags (int, optional): Intent flags

      Returns: Intent object

      "},{"location":"qsl4a/core/intent/#startactivityintent","title":"startActivityIntent()","text":"

      Start an Activity with an Intent.

      startActivityIntent(intent, wait=None)\n

      Parameters: - intent: Intent object from makeIntent() - wait (bool, optional): Block until activity closes

      "},{"location":"qsl4a/core/intent/#startactivityforresultintent","title":"startActivityForResultIntent()","text":"

      Start activity and wait for result.

      startActivityForResultIntent(intent)\n

      Returns: Activity result

      "},{"location":"qsl4a/core/intent/#sendbroadcastintent","title":"sendBroadcastIntent()","text":"

      Send a broadcast.

      sendBroadcastIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#view","title":"view()","text":"

      View content by URI.

      view(uri, type=None, extras=None)\n
      "},{"location":"qsl4a/core/intent/#pick","title":"pick()","text":"

      Pick content from URI.

      pick(uri)\n
      "},{"location":"qsl4a/core/intent/#common-intent-methods","title":"Common Intent Methods)","text":""},{"location":"qsl4a/core/intent/#scanbarcode","title":"scanBarcode()","text":"

      Launch the barcode scanner.

      scanBarcode()\n

      Returns: Scanned barcode string

      "},{"location":"qsl4a/core/intent/#send","title":"send()","text":"

      Send content via share intent.

      send(type, content)\n

      Parameters: - type (str): MIME type - content (str): Content to share

      "},{"location":"qsl4a/core/intent/#sendtext","title":"sendText()","text":"

      Send text content.

      sendText(text)\n

      Parameters: - text (str): Text to send

      "},{"location":"qsl4a/core/intent/#sendemail","title":"sendEmail()","text":"

      Send an email.

      sendEmail(to, subject, body, attachment=None)\n

      Parameters: - to (str or list): Recipient email address(es) - subject (str): Email subject - body (str): Email body - attachment (str, optional): Attachment file path

      "},{"location":"qsl4a/core/intent/#pathtouri","title":"pathToUri()","text":"

      Convert file path to content URI.

      pathToUri(path)\n

      Parameters: - path (str): File path

      Returns: Content URI string

      "},{"location":"qsl4a/core/intent/#openfile","title":"openFile()","text":"

      Open a file with appropriate app.

      openFile(path)\n

      Parameters: - path (str): File path to open

      "},{"location":"qsl4a/core/intent/#sendfile","title":"sendFile()","text":"

      Send a file via share intent.

      sendFile(path)\n

      Parameters: - path (str): File path to send

      "},{"location":"qsl4a/core/intent/#getpathtype","title":"getPathType()","text":"

      Get the MIME type for a file path.

      getPathType(path)\n

      Parameters: - path (str): File path

      Returns: MIME type string

      "},{"location":"qsl4a/core/intent/#viewmap","title":"viewMap()","text":"

      Open map at a location.

      viewMap(latitude, longitude)\n

      Parameters: - latitude (float): Latitude - longitude (float): Longitude

      "},{"location":"qsl4a/core/intent/#viewcontacts","title":"viewContacts()","text":"

      Open the contacts app.

      viewContacts()\n
      "},{"location":"qsl4a/core/intent/#search","title":"search()","text":"

      Perform a web search.

      search(query)\n

      Parameters: - query (str): Search query

      "},{"location":"qsl4a/core/intent/#viewhtml","title":"viewHtml()","text":"

      View HTML content.

      viewHtml(content, encoding=None)\n

      Parameters: - content (str): HTML content - encoding (str, optional): Character encoding

      "},{"location":"qsl4a/core/intent/#webviewshow","title":"webViewShow()","text":"

      Display web content in WebView. Deprecated, use viewHtml.

      webViewShow(url)\n

      Parameters: - url (str): Web page URL

      "},{"location":"qsl4a/core/intent/#editoropen","title":"editorOpen()","text":"

      Open a text editor.

      editorOpen(path=None, create=False)\n

      Parameters: - path (str, optional): File path to edit - create (bool, optional): Create if doesn't exist

      "},{"location":"qsl4a/core/intent/#helper-class-uri","title":"Helper Class: Uri","text":"

      Create URI objects for Intents:

      from androidhelper.Intent import Uri\n\nuri = Uri(\"file:///sdcard/test.txt\")\n
      "},{"location":"qsl4a/core/intent/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/intent/#open-web-page","title":"Open Web Page","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"http://www.example.com\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#share-text","title":"Share Text","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_TEXT: \"Hello from QPython!\",\n        droid.Intent.EXTRA_SUBJECT: \"Test\"\n    },\n    type=\"text/plain\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#open-file","title":"Open File","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"file:///sdcard/document.pdf\",\n    type=\"application/pdf\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#pick-contact","title":"Pick Contact","text":"
      result = droid.pickContact()\ncontact_uri = result.result\n
      "},{"location":"qsl4a/core/intent/#send-email","title":"Send Email","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_EMAIL: [\"test@example.com\"],\n        droid.Intent.EXTRA_SUBJECT: \"Hello\",\n        droid.Intent.EXTRA_TEXT: \"Message body\"\n    },\n    type=\"message/rfc822\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#open-app","title":"Open App","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_MAIN,\n    packagename=\"com.android.settings\",\n    classname=\"com.android.settings.Settings\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/hardware/bluetooth/","title":"Bluetooth API","text":"

      Control Bluetooth adapter and communicate with Bluetooth devices.

      "},{"location":"qsl4a/hardware/bluetooth/#adapter-control","title":"Adapter Control","text":""},{"location":"qsl4a/hardware/bluetooth/#togglebluetoothstate","title":"toggleBluetoothState()","text":"

      Turn Bluetooth on/off.

      toggleBluetoothState(enabled=None, prompt=True)\n

      Parameters: - enabled (bool): True=on, False=off, None=toggle - prompt (bool): Show user prompt

      "},{"location":"qsl4a/hardware/bluetooth/#checkbluetoothstate","title":"checkBluetoothState()","text":"

      Check if Bluetooth is enabled.

      checkBluetoothState()\n

      Returns: True/False

      "},{"location":"qsl4a/hardware/bluetooth/#getlocalname","title":"GetLocalName()","text":"

      Get Bluetooth device name.

      GetLocalName()\n
      "},{"location":"qsl4a/hardware/bluetooth/#setlocalname","title":"SetLocalName()","text":"

      Set Bluetooth device name.

      SetLocalName(name)\n
      "},{"location":"qsl4a/hardware/bluetooth/#getscanmode","title":"GetScanMode()","text":"

      Get discoverability mode.

      GetScanMode()\n

      Returns: - -1: Disabled - 0: Non-discoverable, non-connectable - 1: Connectable, non-discoverable - 3: Connectable and discoverable

      "},{"location":"qsl4a/hardware/bluetooth/#makediscoverable","title":"MakeDiscoverable()","text":"

      Make device discoverable.

      MakeDiscoverable(duration=300)\n

      Parameters: - duration (int): Seconds to be discoverable

      "},{"location":"qsl4a/hardware/bluetooth/#discovery","title":"Discovery","text":""},{"location":"qsl4a/hardware/bluetooth/#discoverystart","title":"DiscoveryStart()","text":"

      Start device discovery.

      DiscoveryStart()\n
      "},{"location":"qsl4a/hardware/bluetooth/#discoverycancel","title":"DiscoveryCancel()","text":"

      Cancel discovery.

      DiscoveryCancel()\n
      "},{"location":"qsl4a/hardware/bluetooth/#getreceiveddevices","title":"GetReceivedDevices()","text":"

      Get discovered devices.

      GetReceivedDevices()\n

      Returns: List of device info dicts

      "},{"location":"qsl4a/hardware/bluetooth/#getbondeddevices","title":"GetBondedDevices()","text":"

      Get paired devices.

      GetBondedDevices()\n

      Returns: List of paired device info

      "},{"location":"qsl4a/hardware/bluetooth/#connection","title":"Connection","text":""},{"location":"qsl4a/hardware/bluetooth/#connect","title":"Connect()","text":"

      Connect to a device.

      Connect(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", address=None)\n

      Parameters: - uuid (str): Service UUID - address (str): Device address (None = show picker)

      Returns: True if successful

      "},{"location":"qsl4a/hardware/bluetooth/#accept","title":"Accept()","text":"

      Accept incoming connection.

      Accept(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", timeout=0)\n
      "},{"location":"qsl4a/hardware/bluetooth/#activeconnections","title":"ActiveConnections()","text":"

      Check active connections.

      ActiveConnections()\n
      "},{"location":"qsl4a/hardware/bluetooth/#stop","title":"Stop()","text":"

      Disconnect.

      Stop(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#communication","title":"Communication","text":""},{"location":"qsl4a/hardware/bluetooth/#write","title":"Write()","text":"

      Send ASCII data.

      Write(ascii, connID=\"\")\n
      "},{"location":"qsl4a/hardware/bluetooth/#writebinary","title":"WriteBinary()","text":"

      Send binary data (base64 encoded).

      WriteBinary(base64, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#read","title":"Read()","text":"

      Read ASCII data.

      Read(bufferSize=4096, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readbinary","title":"ReadBinary()","text":"

      Read binary data.

      ReadBinary(bufferSize=4096, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readline","title":"ReadLine()","text":"

      Read line.

      ReadLine(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readready","title":"ReadReady()","text":"

      Check if data available.

      ReadReady(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Enable Bluetooth\ndroid.toggleBluetoothState(True)\n\n# Get paired devices\ndevices = droid.GetBondedDevices().result\nfor dev in devices:\n    print(f\"{dev['name']}: {dev['address']}\")\n\n# Connect to device\ndroid.Connect(address=\"00:11:22:33:44:55\")\n\n# Send data\ndroid.Write(\"Hello Bluetooth!\")\n\n# Read response\ndata = droid.Read(1024).result\n
      "},{"location":"qsl4a/hardware/camera/","title":"Camera API","text":"

      Capture photos and record video.

      "},{"location":"qsl4a/hardware/camera/#photo-capture","title":"Photo Capture","text":""},{"location":"qsl4a/hardware/camera/#takepicture","title":"takePicture()","text":"

      Take a photo using the default camera.

      takePicture(path=None)\n

      Parameters: - path (str, optional): Save path. If None, returns image data

      Returns: Image path or image data

      "},{"location":"qsl4a/hardware/camera/#cameracapturepicture","title":"cameraCapturePicture()","text":"

      Capture picture with advanced camera controls.

      cameraCapturePicture(targetPath=None, cameraId=0, useAutoFocus=True)\n

      Parameters: - targetPath (str, optional): Save path - cameraId (int): Camera to use (0 = back, 1 = front) - useAutoFocus (bool): Enable auto focus

      Returns: Captured image path

      "},{"location":"qsl4a/hardware/camera/#camerasettorchmode","title":"cameraSetTorchMode()","text":"

      Control camera flashlight/torch.

      cameraSetTorchMode(enabled)\n

      Parameters: - enabled (bool): True to turn on, False to turn off

      Returns: True if successful

      "},{"location":"qsl4a/hardware/camera/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

      Capture screenshot.

      imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

      Parameters: - path (str, optional): Save path - delayMilliSec (int): Delay before capture

      "},{"location":"qsl4a/hardware/camera/#video-recording","title":"Video Recording","text":""},{"location":"qsl4a/hardware/camera/#takevideo","title":"takeVideo()","text":"

      Record video using default settings.

      takeVideo(path=None, quality=1)\n

      Parameters: - path (str, optional): Save path - quality (int): Video quality (0-4) - 0: 160x120 - 1: 320x240 - 2: 352x288 - 3: 640x480 - 4: 800x480

      "},{"location":"qsl4a/hardware/camera/#recordercapturevideo","title":"recorderCaptureVideo()","text":"

      Capture video with advanced controls.

      recorderCaptureVideo(targetPath=None, duration=10, cameraId=0, quality=8)\n

      Parameters: - targetPath (str, optional): Save path - duration (int): Recording duration in seconds (default: 10) - cameraId (int): Camera to use (0 = back, 1 = front) - quality (int): Video quality (0-8, higher is better)

      Returns: Video file path

      "},{"location":"qsl4a/hardware/camera/#recordaudio","title":"recordAudio()","text":"

      Record audio.

      recordAudio()\n

      Returns: Audio file path

      "},{"location":"qsl4a/hardware/camera/#screen-recording","title":"Screen Recording","text":""},{"location":"qsl4a/hardware/camera/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

      Start screen recording.

      recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

      Parameters: - path (str): Save path - audio (int): Audio source (0=none, 1=mic, 2=internal) - targetPixels (int): Resolution - frameRate (int): FPS - bitRate (int): Bitrate - rotation (bool): Rotate output - autoStart (bool): Start immediately

      "},{"location":"qsl4a/hardware/camera/#recorderstart","title":"recorderStart()","text":"

      Start recording.

      recorderStart()\n
      "},{"location":"qsl4a/hardware/camera/#recorderpause","title":"recorderPause()","text":"

      Pause recording.

      recorderPause()\n
      "},{"location":"qsl4a/hardware/camera/#recorderresume","title":"recorderResume()","text":"

      Resume recording.

      recorderResume()\n
      "},{"location":"qsl4a/hardware/camera/#audio-volume-detection","title":"Audio Volume Detection","text":""},{"location":"qsl4a/hardware/camera/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

      Start volume detection.

      recorderSoundVolumeDetect(interval=100)\n
      "},{"location":"qsl4a/hardware/camera/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

      Get current volume in dB.

      recorderSoundVolumeGetDb()\n
      "},{"location":"qsl4a/hardware/camera/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Take photo with default camera\nphoto_path = droid.takePicture(\"/sdcard/photo.jpg\").result\nprint(f\"Photo saved: {photo_path}\")\n\n# Take photo with front camera and auto focus\ncamera_path = droid.cameraCapturePicture(\"/sdcard/selfie.jpg\", cameraId=1, useAutoFocus=True).result\nprint(f\"Front camera photo: {camera_path}\")\n\n# Control flashlight\ndroid.cameraSetTorchMode(True)  # Turn on flashlight\n\n# Record video with default settings\nvideo_path = droid.takeVideo(\"/sdcard/video.mp4\", quality=3).result\nprint(f\"Video saved: {video_path}\")\n\n# Record video with advanced controls\nvideo_path = droid.recorderCaptureVideo(\"/sdcard/movie.mp4\", duration=30, cameraId=0, quality=8).result\n\n# Screenshot\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n
      "},{"location":"qsl4a/hardware/recorder/","title":"Audio Recorder API","text":"

      Record audio from microphone and device screen.

      "},{"location":"qsl4a/hardware/recorder/#audio-recording","title":"Audio Recording","text":""},{"location":"qsl4a/hardware/recorder/#recordaudio","title":"recordAudio()","text":"

      Record audio from microphone.

      recordAudio()\n

      Returns: Path to recorded audio file

      "},{"location":"qsl4a/hardware/recorder/#recorderstartmicrophone","title":"recorderStartMicrophone()","text":"

      Start recording from microphone to a specific file.

      recorderStartMicrophone(targetPath=None)\n

      Parameters: - targetPath (str, optional): Path to save the recording

      "},{"location":"qsl4a/hardware/recorder/#screen-recording","title":"Screen Recording","text":""},{"location":"qsl4a/hardware/recorder/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

      Start screen recording with audio.

      recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

      Parameters: - path (str): Save path for video file - audio (int): Audio source (0=none, 1=mic, 2=internal audio) - targetPixels (int): Target resolution in pixels - frameRate (int): Frames per second (default: 30) - bitRate (int): Video bitrate - rotation (bool): Rotate output video - autoStart (bool): Start recording immediately

      Returns: Result of operation

      "},{"location":"qsl4a/hardware/recorder/#recorderstart","title":"recorderStart()","text":"

      Start the screen recording (when autoStart=False).

      recorderStart()\n
      "},{"location":"qsl4a/hardware/recorder/#recorderpause","title":"recorderPause()","text":"

      Pause ongoing screen recording.

      recorderPause()\n
      "},{"location":"qsl4a/hardware/recorder/#recorderresume","title":"recorderResume()","text":"

      Resume paused screen recording.

      recorderResume()\n
      "},{"location":"qsl4a/hardware/recorder/#audio-volume-detection","title":"Audio Volume Detection","text":""},{"location":"qsl4a/hardware/recorder/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

      Start monitoring sound volume level.

      recorderSoundVolumeDetect(interval=100)\n

      Parameters: - interval (int): Detection interval in milliseconds (default: 100)

      "},{"location":"qsl4a/hardware/recorder/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

      Get current sound volume in decibels.

      recorderSoundVolumeGetDb()\n

      Returns: Current volume level in dB

      "},{"location":"qsl4a/hardware/recorder/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Record audio from microphone\nprint(\"Recording audio...\")\naudio_path = droid.recordAudio().result\nprint(f\"Saved to: {audio_path}\")\n\n# Record microphone to specific file\ndroid.recorderStartMicrophone(\"/sdcard/my_recording.mp3\")\ntime.sleep(5)\ndroid.recorderStop()\n\n# Record screen with audio\nprint(\"Starting screen recording...\")\ndroid.recorderStartScreenRecord(\n    path=\"/sdcard/screen_record.mp4\",\n    audio=1,\n    frameRate=30,\n    autoStart=True\n)\ntime.sleep(10)\ndroid.recorderStop()\n\n# Monitor sound volume\ndroid.recorderSoundVolumeDetect(interval=100)\ntime.sleep(3)\nvolume = droid.recorderSoundVolumeGetDb().result\nprint(f\"Current volume: {volume} dB\")\n
      "},{"location":"qsl4a/hardware/usbserial/","title":"USB Host Serial API","text":"

      Communicate with USB serial devices (requires USB OTG support and Android 3.1+).

      "},{"location":"qsl4a/hardware/usbserial/#usb-serial-methods","title":"USB Serial Methods)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialopen","title":"usbHostSerialOpen()","text":"

      Open a connection to a USB serial device.

      usbHostSerialOpen(device, baudRate=9600)\n

      Parameters: - device (str): USB device path or identifier - baudRate (int): Baud rate (default: 9600)

      Returns: True if opened successfully

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialclose","title":"usbHostSerialClose()","text":"

      Close the USB serial connection.

      usbHostSerialClose()\n
      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialread","title":"usbHostSerialRead()","text":"

      Read data from USB serial.

      usbHostSerialRead(bufferSize=1024)\n

      Parameters: - bufferSize (int): Maximum bytes to read (default: 1024)

      Returns: String read data

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwrite","title":"usbHostSerialWrite()","text":"

      Write data to USB serial.

      usbHostSerialWrite(data)\n

      Parameters: - data (str): String data to write

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialavailable","title":"usbHostSerialAvailable()","text":"

      Check if data is available to read.

      usbHostSerialAvailable()\n

      Returns: Number of bytes available

      "},{"location":"qsl4a/hardware/usbserial/#configuration-methods","title":"Configuration Methods)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetbaudrate","title":"usbHostSerialSetBaudRate()","text":"

      Set the baud rate.

      usbHostSerialSetBaudRate(baudRate)\n

      Parameters: - baudRate (int): Baud rate

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetdatabits","title":"usbHostSerialSetDataBits()","text":"

      Set data bits (5, 6, 7, or 8).

      usbHostSerialSetDataBits(dataBits)\n

      Parameters: - dataBits (int): Data bits (5-8)

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetstopbits","title":"usbHostSerialSetStopBits()","text":"

      Set stop bits (1, 1.5, or 2).

      usbHostSerialSetStopBits(stopBits)\n

      Parameters: - stopBits (float): Stop bits (1, 1.5, or 2)

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetparity","title":"usbHostSerialSetParity()","text":"

      Set parity (none, odd, even, mark, space).

      usbHostSerialSetParity(parity)\n

      Parameters: - parity (str): Parity mode ('none', 'odd', 'even', 'mark', 'space')

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetflowcontrol","title":"usbHostSerialSetFlowControl()","text":"

      Set flow control (none, hardware, software).

      usbHostSerialSetFlowControl(flowControl)\n

      Parameters: - flowControl (str): Flow control mode ('none', 'hardware', 'software')

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialreadhex","title":"usbHostSerialReadHex()","text":"

      Read data as hex string.

      usbHostSerialReadHex(bufferSize=1024)\n

      Parameters: - bufferSize (int): Maximum bytes to read

      Returns: Hex string

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwritehex","title":"usbHostSerialWriteHex()","text":"

      Write data from hex string.

      usbHostSerialWriteHex(hexString)\n

      Parameters: - hexString (str): Hex string to write

      "},{"location":"qsl4a/hardware/usbserial/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Open USB serial connection\nif droid.usbHostSerialOpen(\"/dev/bus/usb/001/001\", 115200).result:\n    print(\"USB serial opened\")\n\n    # Write data\n    droid.usbHostSerialWrite(\"AT\\r\")\n\n    # Read response\n    response = droid.usbHostSerialRead(1024).result\n    print(f\"Response: {response}\")\n\n    # Or use hex\n    droid.usbHostSerialWriteHex(\"41540D0A\")  # \"AT\\r\\n\"\n\n    # Close connection\n    droid.usbHostSerialClose()\n

      Note: USB serial requires: - Android 3.1+ (API 12) - USB OTG cable/adapter - USB host mode support on device - Compatible serial device

      "},{"location":"qsl4a/hardware/webcam/","title":"Webcam API","text":"

      Stream video from the device camera using MJPEG.

      "},{"location":"qsl4a/hardware/webcam/#mjpeg-stream-methods","title":"MJPEG Stream Methods","text":""},{"location":"qsl4a/hardware/webcam/#webcamstart","title":"webcamStart()","text":"

      Start an MJPEG stream from the webcam.

      webcamStart(resolutionLevel=0, jpegQuality=20, port=0)\n

      Parameters: - resolutionLevel (int): Resolution level (default: 0) - jpegQuality (int): JPEG quality 1-100 (default: 20) - port (int): Port number (default: 0 = auto)

      Returns: Tuple of (address, port) for the stream

      "},{"location":"qsl4a/hardware/webcam/#webcamadjustquality","title":"webcamAdjustQuality()","text":"

      Adjust the quality of an active webcam stream.

      webcamAdjustQuality(resolutionLevel=0, jpegQuality=20)\n

      Parameters: - resolutionLevel (int): Resolution level - jpegQuality (int): JPEG quality 1-100

      "},{"location":"qsl4a/hardware/webcam/#webcamstop","title":"webcamStop()","text":"

      Stop the webcam stream.

      webcamStop()\n
      "},{"location":"qsl4a/hardware/webcam/#camera-preview-methods","title":"Camera Preview Methods","text":""},{"location":"qsl4a/hardware/webcam/#camerastartpreview","title":"cameraStartPreview()","text":"

      Start camera preview mode with event generation.

      cameraStartPreview(resolutionLevel=0, jpegQuality=20, filepath=None)\n

      Parameters: - resolutionLevel (int): Resolution level (default: 0) - jpegQuality (int): JPEG quality (default: 20) - filepath (str, optional): File path to save preview frames

      Returns: True if successful

      Note: Generates 'preview' events with frame data.

      "},{"location":"qsl4a/hardware/webcam/#camerastoppreview","title":"cameraStopPreview()","text":"

      Stop the camera preview.

      cameraStopPreview()\n
      "},{"location":"qsl4a/hardware/webcam/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start webcam stream\nstream_info = droid.webcamStart(\n    resolutionLevel=0,\n    jpegQuality=30,\n    port=8080\n).result\nprint(f\"Stream available at {stream_info[0]}:{stream_info[1]}\")\n\n# Adjust quality while streaming\ntime.sleep(5)\ndroid.webcamAdjustQuality(resolutionLevel=1, jpegQuality=50)\n\n# Stop when done\ndroid.webcamStop()\n\n# Or use preview mode\nprint(\"Starting preview...\")\ndroid.cameraStartPreview()\n\n# Wait for preview events\nfor i in range(10):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'preview':\n        print(f\"Got preview frame: {event['data']}\")\n\ndroid.cameraStopPreview()\n
      "},{"location":"qsl4a/media/image/","title":"Image Processing API","text":"

      Compress and process images.

      "},{"location":"qsl4a/media/image/#image-compression","title":"Image Compression","text":""},{"location":"qsl4a/media/image/#imagecompress","title":"imageCompress()","text":"

      Compress image file.

      imageCompress(srcPath, destPath, targetByteSize=0, targetWidth=0, targetHeight=0)\n

      Parameters: - srcPath (str): Source image path - destPath (str): Output path - targetByteSize (int): Target file size in bytes (0 = no limit) - targetWidth (int): Target width (0 = original) - targetHeight (int): Target height (0 = original)

      Returns: Compressed image path

      "},{"location":"qsl4a/media/image/#screenshot","title":"Screenshot","text":""},{"location":"qsl4a/media/image/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

      Capture screen.

      imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

      Parameters: - path (str): Save path - delayMilliSec (int): Delay before capture

      Returns: Screenshot path

      "},{"location":"qsl4a/media/image/#video-playback","title":"Video Playback","text":""},{"location":"qsl4a/media/image/#videoplay","title":"videoPlay()","text":"

      Play video file in fullscreen mode.

      videoPlay(path, wait=True)\n

      Parameters: - path (str): Video file path - wait (bool): Wait for playback to complete (default: True)

      "},{"location":"qsl4a/media/image/#barcode-scanning","title":"Barcode Scanning","text":""},{"location":"qsl4a/media/image/#scanbarcodefromimage","title":"scanBarcodeFromImage()","text":"

      Scan barcode/QR code from image file.

      scanBarcodeFromImage(path, compressRatio=0, x=0, y=0, width=0, height=0)\n

      Parameters: - path (str): Image file path - compressRatio (int): Compression ratio (0 = no compression) - x, y, width, height (int): Region to scan (0 = full image)

      Returns: Scanned barcode content

      "},{"location":"qsl4a/media/image/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Take screenshot\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n\n# Compress image\ncompressed = droid.imageCompress(\n    \"/sdcard/large_photo.jpg\",\n    \"/sdcard/compressed.jpg\",\n    targetByteSize=102400,  # Target ~100KB\n    targetWidth=1920,\n    targetHeight=1080\n).result\nprint(f\"Saved: {compressed}\")\n\n# Play video\nvideo_path = \"/sdcard/movie.mp4\"\ndroid.videoPlay(video_path, wait=True)\n\n# Scan barcode from image\nresult = droid.scanBarcodeFromImage(\"/sdcard/qr_code.png\").result\nprint(f\"Barcode: {result}\")\n
      "},{"location":"qsl4a/media/mediaplayer/","title":"Media Player API","text":"

      Control audio and video playback.

      "},{"location":"qsl4a/media/mediaplayer/#playback-control","title":"Playback Control","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplay","title":"mediaPlay()","text":"

      Play media file.

      mediaPlay(url, tag=\"default\", play=True)\n

      Parameters: - url (str): Media file path or URL - tag (str): Player identifier - play (bool): Auto-start playback

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaystart","title":"mediaPlayStart()","text":"

      Start playback.

      mediaPlayStart(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplaypause","title":"mediaPlayPause()","text":"

      Pause playback.

      mediaPlayPause(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplayclose","title":"mediaPlayClose()","text":"

      Close player.

      mediaPlayClose(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplayseek","title":"mediaPlaySeek()","text":"

      Seek to position.

      mediaPlaySeek(msec, tag=\"default\")\n

      Parameters: - msec (int): Position in milliseconds

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaysetlooping","title":"mediaPlaySetLooping()","text":"

      Set loop mode.

      mediaPlaySetLooping(enabled, tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#player-info","title":"Player Info","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplayinfo","title":"mediaPlayInfo()","text":"

      Get playback info.

      mediaPlayInfo(tag=\"default\")\n

      Returns: Dict with duration, position, etc.

      "},{"location":"qsl4a/media/mediaplayer/#mediaisplaying","title":"mediaIsPlaying()","text":"

      Check if playing.

      mediaIsPlaying(tag=\"default\")\n

      Returns: True/False

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaylist","title":"mediaPlayList()","text":"

      List active players.

      mediaPlayList()\n
      "},{"location":"qsl4a/media/mediaplayer/#volume-control","title":"Volume Control","text":""},{"location":"qsl4a/media/mediaplayer/#getmediavolume","title":"getMediaVolume()","text":"

      Get media volume.

      getMediaVolume()\n

      Returns: Volume level (0-15)

      "},{"location":"qsl4a/media/mediaplayer/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

      Get max media volume.

      getMaxMediaVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#getringervolume","title":"getRingerVolume()","text":"

      Get ringer volume.

      getRingerVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

      Get max ringer volume.

      getMaxRingerVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#video-playback","title":"Video Playback","text":""},{"location":"qsl4a/media/mediaplayer/#videoplay","title":"videoPlay()","text":"

      Play video fullscreen.

      videoPlay(path, wait=True)\n

      Parameters: - path (str): Video file path - wait (bool): Wait for playback to complete

      "},{"location":"qsl4a/media/mediaplayer/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Play audio\ndroid.mediaPlay(\"/sdcard/music.mp3\", tag=\"music\")\n\n# Check status\nif droid.mediaIsPlaying(\"music\").result:\n    info = droid.mediaPlayInfo(\"music\").result\n    print(f\"Playing: {info}\")\n\n# Seek to 30 seconds\ndroid.mediaPlaySeek(30000, \"music\")\n\n# Close\ndroid.mediaPlayClose(\"music\")\n\n# Play video\ndroid.videoPlay(\"/sdcard/movie.mp4\", wait=True)\n
      "},{"location":"qsl4a/special/cipher/","title":"Cipher API","text":"

      Encryption and decryption utilities for secure data storage.

      "},{"location":"qsl4a/special/cipher/#initialization","title":"Initialization","text":""},{"location":"qsl4a/special/cipher/#cipherinit","title":"cipherInit()","text":"

      Initialize the cipher with encryption key and algorithm.

      cipherInit(key, algorithm=\"AES/CBC/PKCS5Padding\", encodingFormat=\"\", initialVector=\"\")\n

      Parameters: - key (str or bytes): Encryption key - algorithm (str): Cipher algorithm (default: \"AES/CBC/PKCS5Padding\") - encodingFormat (str): Encoding format - initialVector (str or bytes): Initial vector for encryption

      Returns: Initialization result

      Note: Must be called before any encrypt/decrypt operations.

      "},{"location":"qsl4a/special/cipher/#encryption-methods","title":"Encryption Methods","text":""},{"location":"qsl4a/special/cipher/#encryptstring","title":"encryptString()","text":"

      Encrypt a string.

      encryptString(plainText)\n

      Parameters: - plainText (str): Text to encrypt

      Returns: Encrypted string

      "},{"location":"qsl4a/special/cipher/#encryptbytes","title":"encryptBytes()","text":"

      Encrypt bytes data.

      encryptBytes(data)\n

      Parameters: - data (bytes): Data to encrypt

      Returns: Encrypted bytes

      "},{"location":"qsl4a/special/cipher/#encryptstringtofile","title":"encryptStringToFile()","text":"

      Encrypt string to file.

      encryptStringToFile(plainText, filePath)\n

      Parameters: - plainText (str): Text to encrypt - filePath (str): Output file path

      "},{"location":"qsl4a/special/cipher/#encryptbytestofile","title":"encryptBytesToFile()","text":"

      Encrypt bytes to file.

      encryptBytesToFile(data, filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryption-methods","title":"Decryption Methods","text":""},{"location":"qsl4a/special/cipher/#decryptstring","title":"decryptString()","text":"

      Decrypt to string.

      decryptString(cipherText)\n

      Parameters: - cipherText (str): Encrypted text

      Returns: Decrypted string

      "},{"location":"qsl4a/special/cipher/#decryptbytes","title":"decryptBytes()","text":"

      Decrypt to bytes.

      decryptBytes(data)\n

      Returns: Decrypted bytes

      "},{"location":"qsl4a/special/cipher/#decryptfiletostring","title":"decryptFileToString()","text":"

      Decrypt file to string.

      decryptFileToString(filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryptfiletobytes","title":"decryptFileToBytes()","text":"

      Decrypt file to bytes.

      decryptFileToBytes(filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryptfile","title":"decryptFile()","text":"

      Decrypt file to file.

      decryptFile(srcPath, destPath)\n
      "},{"location":"qsl4a/special/cipher/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Initialize cipher with your encryption key\ndroid.cipherInit(\"my_secret_key_1234\")\n\n# Encrypt string\nencrypted = droid.encryptString(\"Secret message!\").result\nprint(f\"Encrypted: {encrypted}\")\n\n# Decrypt string\ndecrypted = droid.decryptString(encrypted).result\nprint(f\"Decrypted: {decrypted}\")\n\n# Encrypt to file\ndroid.encryptStringToFile(\"My secret data\", \"/sdcard/secret.dat\")\n\n# Decrypt from file\ndata = droid.decryptFileToString(\"/sdcard/secret.dat\").result\nprint(data)\n\n# Initialize with custom algorithm and IV\ndroid.cipherInit(\n    key=\"my_key\",\n    algorithm=\"AES/CBC/PKCS5Padding\",\n    initialVector=\"0123456789abcdef\"\n)\n
      "},{"location":"qsl4a/special/pgptai/","title":"PGPT AI API","text":"

      Speech-to-text and AI services integration.

      "},{"location":"qsl4a/special/pgptai/#prerequisites","title":"Prerequisites","text":"
      pip install pgptAI\n
      "},{"location":"qsl4a/special/pgptai/#speech-recognition","title":"Speech Recognition","text":""},{"location":"qsl4a/special/pgptai/#speechtotext","title":"speechToText()","text":"

      Convert speech to text.

      speechToText(RecordSecond=10, AmrFile=None, Language=None)\n

      Parameters: - RecordSecond (int): Recording duration in seconds - AmrFile (str, optional): Existing audio file path - Language (str, optional): Language code ('en', 'zh')

      Returns: Transcribed text

      "},{"location":"qsl4a/special/pgptai/#text-to-speech","title":"Text to Speech","text":""},{"location":"qsl4a/special/pgptai/#texttospeech","title":"textToSpeech()","text":"

      Convert text to speech and optionally play it.

      textToSpeech(Text, AutoPlay=True, WavFile=None, VoiceName=None)\n

      Parameters: - Text (str): Text to convert to speech - AutoPlay (bool): Automatically play the generated audio (default: True) - WavFile (str, optional): Path to save the WAV file. If None, uses temporary file - VoiceName (str, optional): Voice name to use (e.g., 'en-US-JennyNeural', 'zh-CN-XiaoxiaoNeural')

      Returns: Dict with speech synthesis result including: - text: The input text - url: URL to download the audio file - WavFile: Path to the saved WAV file (if saved locally)

      "},{"location":"qsl4a/special/pgptai/#configuration","title":"Configuration","text":"

      The API uses configuration from /storage/emulated/0/Android/data/org.qpython.qpy/files/apigpt.conf:

      [speech]\nspeech_key = your_api_key\n

      Default voice settings: - English: en-US-JennyNeural - Chinese: zh-CN-XiaoxiaoNeural

      "},{"location":"qsl4a/special/pgptai/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Record and transcribe\nprint(\"Recording for 5 seconds...\")\ntext = droid.speechToText(RecordSecond=5, Language='en').result\nprint(f\"You said: {text}\")\n\n# Transcribe existing file\ntext = droid.speechToText(AmrFile=\"/sdcard/recording.amr\").result\nprint(f\"Transcription: {text}\")\n\n# Text to speech\ndroid.textToSpeech(\"Hello, this is a test message.\", AutoPlay=True, Language='en')\n\n# Text to speech with custom voice and save to file\nresult = droid.textToSpeech(\n    \"Welcome to QPython!\",\n    AutoPlay=False,\n    WavFile=\"/sdcard/welcome.wav\",\n    VoiceName=\"en-US-JennyNeural\"\n).result\nprint(f\"Audio saved to: {result.get('WavFile')}\")\n
      "},{"location":"qsl4a/special/pgptai/#class-usage","title":"Class Usage","text":"
      from androidhelper.pgptai import pgptai\nimport androidhelper\n\ndroid = androidhelper.Android()\nai = pgptai(droid)\n\n# Use speech recognition\ntext = ai.speechToText(RecordSecond=10)\n
      "},{"location":"qsl4a/storage/clipboard/","title":"Clipboard API","text":"

      Copy and paste text to system clipboard.

      "},{"location":"qsl4a/storage/clipboard/#methods","title":"Methods","text":""},{"location":"qsl4a/storage/clipboard/#setclipboard","title":"setClipboard()","text":"

      Copy text to clipboard.

      setClipboard(text)\n

      Parameters: - text (str): Text to copy

      Returns: True if success

      "},{"location":"qsl4a/storage/clipboard/#getclipboard","title":"getClipboard()","text":"

      Get text from clipboard.

      getClipboard()\n

      Returns: Clipboard text

      "},{"location":"qsl4a/storage/clipboard/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Copy to clipboard\ndroid.setClipboard(\"Hello from QPython!\")\n\n# Paste from clipboard\ntext = droid.getClipboard().result\nprint(f\"Clipboard: {text}\")\n
      "},{"location":"qsl4a/storage/documentfile/","title":"DocumentFile API","text":"

      File operations with SAF (Storage Access Framework) support for Android 4.4+.

      "},{"location":"qsl4a/storage/documentfile/#directory-operations","title":"Directory Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfilemkdir","title":"documentFileMkdir()","text":"

      Create directory.

      documentFileMkdir(Dir)\n

      Parameters: - Dir (str): Directory path

      Returns: True if success

      "},{"location":"qsl4a/storage/documentfile/#documentfilelistfiles","title":"documentFileListFiles()","text":"

      List files in directory.

      documentFileListFiles(Folder)\n

      Returns: List of files

      "},{"location":"qsl4a/storage/documentfile/#file-operations","title":"File Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfileexists","title":"documentFileExists()","text":"

      Check if file or directory exists.

      documentFileExists(path)\n

      Parameters: - path (str): File or directory path

      Returns: True if exists, False otherwise

      "},{"location":"qsl4a/storage/documentfile/#documentfileisfile","title":"documentFileIsFile()","text":"

      Check if path is a file.

      documentFileIsFile(path)\n

      Parameters: - path (str): Path to check

      Returns: True if file, False if not a file, None if not exists

      "},{"location":"qsl4a/storage/documentfile/#documentfileisdirectory","title":"documentFileIsDirectory()","text":"

      Check if path is a directory.

      documentFileIsDirectory(path)\n

      Parameters: - path (str): Path to check

      Returns: True if directory, False if not a directory, None if not exists

      "},{"location":"qsl4a/storage/documentfile/#documentfiledelete","title":"documentFileDelete()","text":"

      Delete file or directory.

      documentFileDelete(FileOrTree)\n

      Returns: True if success

      "},{"location":"qsl4a/storage/documentfile/#documentfilerenameto","title":"documentFileRenameTo()","text":"

      Rename or move file.

      documentFileRenameTo(Src, Dest)\n

      Returns: True if success

      "},{"location":"qsl4a/storage/documentfile/#documentfilecopy","title":"documentFileCopy()","text":"

      Copy file.

      documentFileCopy(SrcFileOrTree, DestFileOrTree)\n
      "},{"location":"qsl4a/storage/documentfile/#stream-operations","title":"Stream Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfileinputstream","title":"documentFileInputStream()","text":"

      Read file content.

      documentFileInputStream(srcFile, EncodingFormat=\"\", skip=None, length=None)\n

      Parameters: - srcFile (str): Source file - EncodingFormat (str): \"UTF-8\", \"GBK\", \"Base64\", or \"\" for bytes - skip (int): Skip bytes from start - length (int): Read length

      Returns: File content

      "},{"location":"qsl4a/storage/documentfile/#documentfileoutputstream","title":"documentFileOutputStream()","text":"

      Write file content.

      documentFileOutputStream(destFile, src, EncodingFormat=\"\", append=None)\n

      Parameters: - destFile (str): Destination file - src: Data to write - EncodingFormat (str): Encoding format - append (bool): Append mode

      "},{"location":"qsl4a/storage/documentfile/#file-information","title":"File Information","text":""},{"location":"qsl4a/storage/documentfile/#documentfilelength","title":"documentFileLength()","text":"

      Get file size in bytes.

      documentFileLength(path)\n

      Parameters: - path (str): File path

      Returns: File size in bytes (0 if not exists)

      "},{"location":"qsl4a/storage/documentfile/#documentfilelastmodified","title":"documentFileLastModified()","text":"

      Get last modified time.

      documentFileLastModified(path)\n

      Parameters: - path (str): File path

      Returns: Timestamp (0 if not exists)

      "},{"location":"qsl4a/storage/documentfile/#documentfilegetstat","title":"documentFileGetStat()","text":"

      Get comprehensive file statistics.

      documentFileGetStat(path)\n

      Parameters: - path (str): File path

      Returns: Dict with length, last modified, and read/write permissions, or None if not exists

      "},{"location":"qsl4a/storage/documentfile/#uri-operations","title":"URI Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfilegeturi","title":"documentFileGetUri()","text":"

      Get URI from path.

      documentFileGetUri(path, isDirectory=None)\n
      "},{"location":"qsl4a/storage/documentfile/#documentfileshowopen","title":"documentFileShowOpen()","text":"

      Show file picker.

      documentFileShowOpen()\n

      Returns: Selected file URI

      "},{"location":"qsl4a/storage/documentfile/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Create directory\ndroid.documentFileMkdir(\"/sdcard/MyFolder\")\n\n# List files\nfiles = droid.documentFileListFiles(\"/sdcard\").result\nfor f in files:\n    print(f)\n\n# Read file\ncontent = droid.documentFileInputStream(\n    \"/sdcard/test.txt\",\n    EncodingFormat=\"UTF-8\"\n).result\nprint(content)\n\n# Write file\ndroid.documentFileOutputStream(\n    \"/sdcard/output.txt\",\n    \"Hello World\",\n    EncodingFormat=\"UTF-8\"\n)\n
      "},{"location":"qsl4a/storage/preferences/","title":"Preferences API","text":"

      Store and retrieve data using Android SharedPreferences.

      "},{"location":"qsl4a/storage/preferences/#preference-methods","title":"Preference Methods","text":""},{"location":"qsl4a/storage/preferences/#prefgetvalue","title":"prefGetValue()","text":"

      Read a value from shared preferences.

      prefGetValue(key, filename=None)\n

      Parameters: - key (str): Preference key - filename (str, optional): Preference file name

      Returns: The stored value (any type)

      "},{"location":"qsl4a/storage/preferences/#prefputvalue","title":"prefPutValue()","text":"

      Write a value to shared preferences.

      prefPutValue(key, value, filename=None)\n

      Parameters: - key (str): Preference key - value (object): Value to store - filename (str, optional): Preference file name

      "},{"location":"qsl4a/storage/preferences/#prefgetall","title":"prefGetAll()","text":"

      Get all preference values.

      prefGetAll(filename=None)\n

      Parameters: - filename (str, optional): Preference file name

      Returns: Map of all preferences

      "},{"location":"qsl4a/storage/preferences/#prefremovevalue","title":"prefRemoveValue()","text":"

      Remove a value from shared preferences.

      prefRemoveValue(key, filename=None)\n

      Parameters: - key (str): Preference key to remove - filename (str, optional): Preference file name

      "},{"location":"qsl4a/storage/preferences/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Store values\ndroid.prefPutValue(\"username\", \"alice\")\ndroid.prefPutValue(\"score\", 100)\ndroid.prefPutValue(\"enabled\", True)\n\n# Read a specific value\nusername = droid.prefGetValue(\"username\").result\nprint(f\"Username: {username}\")\n\n# Get all preferences\nall_prefs = droid.prefGetAll().result\nprint(f\"All prefs: {all_prefs}\")\n\n# Remove a value\ndroid.prefRemoveValue(\"score\")\n\n# Use custom filename\ndroid.prefPutValue(\"token\", \"abc123\", filename=\"auth.prefs\")\ntoken = droid.prefGetValue(\"token\", filename=\"auth.prefs\").result\n
      "},{"location":"qsl4a/system/activityresult/","title":"Activity Result API","text":"

      Set activity results for scripts launched via startActivityForResult.

      "},{"location":"qsl4a/system/activityresult/#result-methods","title":"Result Methods","text":""},{"location":"qsl4a/system/activityresult/#setresultboolean","title":"setResultBoolean()","text":"

      Set a boolean result.

      setResultBoolean(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (bool): Boolean result value

      "},{"location":"qsl4a/system/activityresult/#setresultbyte","title":"setResultByte()","text":"

      Set a byte result.

      setResultByte(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (int): Byte result value

      "},{"location":"qsl4a/system/activityresult/#setresultshort","title":"setResultShort()","text":"

      Set a short result.

      setResultShort(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (int): Short result value

      "},{"location":"qsl4a/system/activityresult/#setresultchar","title":"setResultChar()","text":"

      Set a character result.

      setResultChar(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (str): Character result value

      "},{"location":"qsl4a/system/activityresult/#setresultinteger","title":"setResultInteger()","text":"

      Set an integer result.

      setResultInteger(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (int): Integer result value

      "},{"location":"qsl4a/system/activityresult/#setresultlong","title":"setResultLong()","text":"

      Set a long result.

      setResultLong(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (int): Long result value

      "},{"location":"qsl4a/system/activityresult/#setresultfloat","title":"setResultFloat()","text":"

      Set a float result.

      setResultFloat(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (float): Float result value

      "},{"location":"qsl4a/system/activityresult/#setresultdouble","title":"setResultDouble()","text":"

      Set a double result.

      setResultDouble(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (float): Double result value

      "},{"location":"qsl4a/system/activityresult/#setresultstring","title":"setResultString()","text":"

      Set a string result.

      setResultString(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (str): String result value

      "},{"location":"qsl4a/system/activityresult/#setresultbooleanarray","title":"setResultBooleanArray()","text":"

      Set a boolean array result.

      setResultBooleanArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Boolean array

      "},{"location":"qsl4a/system/activityresult/#setresultbytearray","title":"setResultByteArray()","text":"

      Set a byte array result.

      setResultByteArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Byte array

      "},{"location":"qsl4a/system/activityresult/#setresultshortarray","title":"setResultShortArray()","text":"

      Set a short array result.

      setResultShortArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Short array

      "},{"location":"qsl4a/system/activityresult/#setresultchararray","title":"setResultCharArray()","text":"

      Set a character array result.

      setResultCharArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Char array

      "},{"location":"qsl4a/system/activityresult/#setresultintegerarray","title":"setResultIntegerArray()","text":"

      Set an integer array result.

      setResultIntegerArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Integer array

      "},{"location":"qsl4a/system/activityresult/#setresultlongarray","title":"setResultLongArray()","text":"

      Set a long array result.

      setResultLongArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Long array

      "},{"location":"qsl4a/system/activityresult/#setresultfloatarray","title":"setResultFloatArray()","text":"

      Set a float array result.

      setResultFloatArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Float array

      "},{"location":"qsl4a/system/activityresult/#setresultdoublearray","title":"setResultDoubleArray()","text":"

      Set a double array result.

      setResultDoubleArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Double array

      "},{"location":"qsl4a/system/activityresult/#setresultstringarray","title":"setResultStringArray()","text":"

      Set a string array result.

      setResultStringArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): String array

      "},{"location":"qsl4a/system/activityresult/#setresultserializable","title":"setResultSerializable()","text":"

      Set a serializable result.

      setResultSerializable(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue: Serializable result value

      "},{"location":"qsl4a/system/activityresult/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# After performing an activity, set the result\n# Example: Return success with data\ndroid.setResultInteger(0, 200)  # RESULT_OK\ndroid.setResultString(0, \"Operation completed successfully\")\n\n# Return an array result\ndroid.setResultIntegerArray(0, [1, 2, 3, 4, 5])\n
      "},{"location":"qsl4a/system/application/","title":"Application Management","text":"

      Manage applications, launch apps, and query system information.

      "},{"location":"qsl4a/system/application/#application-information","title":"Application Information","text":""},{"location":"qsl4a/system/application/#getapplicationinfo","title":"getApplicationInfo()","text":"

      Get information about an app.

      getApplicationInfo(packageName=None)\n

      Parameters: - packageName (str): Package name (None = current app)

      Returns: App info dict

      "},{"location":"qsl4a/system/application/#getinstalledpackages","title":"getInstalledPackages()","text":"

      Get list of installed packages.

      getInstalledPackages(flag=4)\n

      Parameters: - flag (int): Package flag filter (default: 4)

      Returns: List of installed packages

      "},{"location":"qsl4a/system/application/#getrunningpackages","title":"getRunningPackages()","text":"

      List running packages.

      getRunningPackages()\n

      Returns: List of package names

      "},{"location":"qsl4a/system/application/#getlaunchablepackages","title":"getLaunchablePackages()","text":"

      Get list of launchable packages.

      getLaunchablePackages(needClassName=False)\n

      Parameters: - needClassName (bool): Include main activity class name (default: False)

      Returns: List of launchable package names or dict with class names

      "},{"location":"qsl4a/system/application/#application-control","title":"Application Control","text":""},{"location":"qsl4a/system/application/#launch","title":"launch()","text":"

      Launch an application.

      launch(classname=None, packagename=None, wait=True)\n

      Parameters: - classname (str): Main activity class name - packagename (str): Package name - wait (bool): Wait for launch to complete (default: True)

      Returns: Launch result

      "},{"location":"qsl4a/system/application/#forcestoppackage","title":"forceStopPackage()","text":"

      Force stop an application.

      forceStopPackage(packageName)\n

      Parameters: - packageName (str): Package name to stop

      "},{"location":"qsl4a/system/application/#version-information","title":"Version Information","text":""},{"location":"qsl4a/system/application/#getpackageversion","title":"getPackageVersion()","text":"

      Get app version name.

      getPackageVersion(packageName)\n

      Returns: Version string (e.g., \"3.2.1\")

      "},{"location":"qsl4a/system/application/#getpackageversioncode","title":"getPackageVersionCode()","text":"

      Get app version code.

      getPackageVersionCode(packageName)\n

      Returns: Version code integer

      "},{"location":"qsl4a/system/application/#getconstants","title":"getConstants()","text":"

      Get class constants.

      getConstants(classname)\n

      Parameters: - classname (str): Full class name

      Returns: Dict of constant names and values

      "},{"location":"qsl4a/system/application/#system-features","title":"System Features","text":""},{"location":"qsl4a/system/application/#backgroundprotect","title":"backgroundProtect()","text":"

      Enable or disable background protection for the app.

      backgroundProtect(enabled=True)\n

      Parameters: - enabled (bool): True to enable protection, False to disable

      "},{"location":"qsl4a/system/application/#createscriptshortcut","title":"createScriptShortCut()","text":"

      Create a home screen shortcut for a script.

      createScriptShortCut(scriptPath, label=None, iconPath=None, scriptArg=None)\n

      Parameters: - scriptPath (str): Path to the Python script - label (str, optional): Shortcut label - iconPath (str, optional): Path to icon image - scriptArg (str, optional): Argument to pass to script

      "},{"location":"qsl4a/system/application/#device-information","title":"Device Information","text":""},{"location":"qsl4a/system/application/#getandroidid","title":"getAndroidID()","text":"

      Get Android device ID.

      getAndroidID()\n

      Returns: Unique Android device ID string

      "},{"location":"qsl4a/system/application/#getsysinfo","title":"getSysInfo()","text":"

      Get system information.

      getSysInfo()\n

      Returns: Dict with system details

      "},{"location":"qsl4a/system/application/#getlocale","title":"getLocale()","text":"

      Get device locale.

      getLocale()\n

      Returns: Locale string (e.g., \"en_US\")

      "},{"location":"qsl4a/system/application/#getharmonyosinformation","title":"getHarmonyOsInformation()","text":"

      Get HarmonyOS information if running on HarmonyOS.

      getHarmonyOsInformation()\n

      Returns: HarmonyOS version info or None

      "},{"location":"qsl4a/system/application/#isexternalstoragemanager","title":"isExternalStorageManager()","text":"

      Check if app has external storage manager permission.

      isExternalStorageManager()\n

      Returns: True if has permission

      "},{"location":"qsl4a/system/application/#memory-and-display","title":"Memory and Display","text":""},{"location":"qsl4a/system/application/#getmemoryinfo","title":"getMemoryInfo()","text":"

      Get memory information.

      getMemoryInfo()\n

      Returns: Dict with memory stats

      "},{"location":"qsl4a/system/application/#getscreeninfo","title":"getScreenInfo()","text":"

      Get screen information.

      getScreenInfo()\n

      Returns: Dict with width, height, density

      "},{"location":"qsl4a/system/application/#permissions","title":"Permissions","text":""},{"location":"qsl4a/system/application/#checkpermissions","title":"checkPermissions()","text":"

      Check current app permissions.

      checkPermissions()\n

      Returns: Dict of permissions and their status

      "},{"location":"qsl4a/system/application/#requestpermissions","title":"requestPermissions()","text":"

      Request permissions from the user.

      requestPermissions(permissions=None)\n

      Parameters: - permissions (list, optional): List of permissions to request. If None, requests all needed permissions.

      Returns: Result of permission request

      "},{"location":"qsl4a/system/application/#system-actions","title":"System Actions","text":""},{"location":"qsl4a/system/application/#showscreenlock","title":"showScreenLock()","text":"

      Show screen lock (PIN/pattern/password entry).

      showScreenLock()\n
      "},{"location":"qsl4a/system/application/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get system info\ninfo = droid.getSysInfo().result\nprint(f\"System: {info}\")\n\n# Get app version\nversion = droid.getPackageVersion(\"org.qpython.qpy\").result\nprint(f\"QPython version: {version}\")\n\n# List installed apps\napps = droid.getInstalledPackages().result\nprint(f\"Installed apps: {len(apps)}\")\n\n# Launch an app\ndroid.launch(packagename=\"com.android.settings\")\n\n# Check permissions\nperms = droid.checkPermissions().result\nprint(f\"Permissions: {perms}\")\n\n# Request storage permission\ndroid.requestPermissions([\"android.permission.READ_EXTERNAL_STORAGE\"])\n\n# Create shortcut\ndroid.createScriptShortCut(\n    \"/sdcard/my_script.py\",\n    label=\"My Script\",\n    iconPath=\"/sdcard/icon.png\"\n)\n
      "},{"location":"qsl4a/system/battery/","title":"Battery API","text":"

      Monitor device battery status and health.

      "},{"location":"qsl4a/system/battery/#methods","title":"Methods","text":""},{"location":"qsl4a/system/battery/#readbatterydata","title":"readBatteryData()","text":"

      Get complete battery information.

      readBatteryData()\n

      Returns: Dict with battery data

      "},{"location":"qsl4a/system/battery/#batterystartmonitoring","title":"batteryStartMonitoring()","text":"

      Start battery monitoring.

      batteryStartMonitoring()\n
      "},{"location":"qsl4a/system/battery/#batterystopmonitoring","title":"batteryStopMonitoring()","text":"

      Stop battery monitoring.

      batteryStopMonitoring()\n
      "},{"location":"qsl4a/system/battery/#batterygetlevel","title":"batteryGetLevel()","text":"

      Get battery percentage.

      batteryGetLevel()\n

      Returns: Int (0-100)

      "},{"location":"qsl4a/system/battery/#batterygetstatus","title":"batteryGetStatus()","text":"

      Get charging status.

      batteryGetStatus()\n

      Returns: - 1: Unknown - 2: Charging - 3: Discharging - 4: Not charging - 5: Full

      "},{"location":"qsl4a/system/battery/#batterygetplugtype","title":"batteryGetPlugType()","text":"

      Get power source.

      batteryGetPlugType()\n

      Returns: - -1: Unknown - 0: Unplugged - 1: AC charger - 2: USB port

      "},{"location":"qsl4a/system/battery/#batterygethealth","title":"batteryGetHealth()","text":"

      Get battery health.

      batteryGetHealth()\n

      Returns: - 1: Unknown - 2: Good - 3: Overheat - 4: Dead - 5: Over voltage - 6: Unspecified failure

      "},{"location":"qsl4a/system/battery/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get battery level\nlevel = droid.batteryGetLevel().result\nprint(f\"Battery: {level}%\")\n
      "},{"location":"qsl4a/system/qpyinterface/","title":"QPython Interface API","text":"

      Execute QPython scripts and manage shared variables from other apps.

      "},{"location":"qsl4a/system/qpyinterface/#script-execution-methods","title":"Script Execution Methods","text":""},{"location":"qsl4a/system/qpyinterface/#executeqpy","title":"executeQPy()","text":"

      Execute a QPython script.

      executeQPy(path=\"\", arg=None)\n

      Parameters: - path (str): Path to the script file - arg (str, optional): Command line arguments

      Returns: True if started successfully

      "},{"location":"qsl4a/system/qpyinterface/#executeqpyassrv","title":"executeQPyAsSrv()","text":"

      Execute a QPython script as a service.

      executeQPyAsSrv(path=None)\n

      Parameters: - path (str, optional): Path to the script file

      Returns: True if started successfully

      "},{"location":"qsl4a/system/qpyinterface/#executeqpycode","title":"executeQPyCode()","text":"

      Execute Python code directly.

      executeQPyCode(code=None)\n

      Parameters: - code (str, optional): Python code to execute

      Returns: True if started successfully

      "},{"location":"qsl4a/system/qpyinterface/#executeqpycodeassrv","title":"executeQPyCodeAsSrv()","text":"

      Execute Python code as a service.

      executeQPyCodeAsSrv(code=None)\n

      Parameters: - code (str, optional): Python code to execute

      Returns: True if started successfully

      "},{"location":"qsl4a/system/qpyinterface/#shared-variables","title":"Shared Variables","text":"

      Shared variables allow communication between QPython and other apps.

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableset","title":"sharedVariableSet()","text":"

      Set a Java shared variable.

      sharedVariableSet(key, value)\n

      Parameters: - key (str): Variable name - value (str): Variable value

      Returns: The stored value

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableget","title":"sharedVariableGet()","text":"

      Get a Java shared variable.

      sharedVariableGet(key)\n

      Parameters: - key (str): Variable name

      Returns: The stored value

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableremove","title":"sharedVariableRemove()","text":"

      Remove a Java shared variable.

      sharedVariableRemove(key)\n

      Parameters: - key (str): Variable name to remove

      Returns: The removed value

      "},{"location":"qsl4a/system/qpyinterface/#getlastlog","title":"getLastLog()","text":"

      Get the last log output from QPython.

      getLastLog()\n

      Returns: String log content

      "},{"location":"qsl4a/system/qpyinterface/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Execute a script\ndroid.executeQPy(\"/sdcard/my_script.py\", arg=\"test\")\n\n# Execute code directly\ncode = \"print('Hello from QPython!')\"\ndroid.executeQPyCode(code)\n\n# Use shared variables\ndroid.sharedVariableSet(\"username\", \"alice\")\nusername = droid.sharedVariableGet(\"username\").result\nprint(f\"Username: {username}\")\n\n# Remove variable\ndroid.sharedVariableRemove(\"username\")\n\n# Get recent log\nlog = droid.getLastLog().result\nprint(f\"Log: {log}\")\n
      "},{"location":"qsl4a/system/sensors/","title":"Sensor API","text":"

      Access device sensors including accelerometer, gyroscope, magnetometer, and more.

      "},{"location":"qsl4a/system/sensors/#methods","title":"Methods","text":""},{"location":"qsl4a/system/sensors/#startsensingtimed","title":"startSensingTimed()","text":"

      Start sensor monitoring with time intervals.

      startSensingTimed(sensorNumber, delayTime)\n

      Parameters: - sensorNumber (int): Sensor ID (1-3 typically) - delayTime (int): Delay between readings in milliseconds

      "},{"location":"qsl4a/system/sensors/#startsensingthreshold","title":"startSensingThreshold()","text":"

      Start sensor monitoring with threshold trigger.

      startSensingThreshold(sensorNumber, threshold, axis)\n

      Parameters: - sensorNumber (int): Sensor ID - threshold (float): Trigger threshold - axis (int): Axis to monitor (0=X, 1=Y, 2=Z)

      "},{"location":"qsl4a/system/sensors/#stopsensing","title":"stopSensing()","text":"

      Stop all sensor monitoring.

      stopSensing()\n
      "},{"location":"qsl4a/system/sensors/#readsensors","title":"readSensors()","text":"

      Read current sensor data.

      readSensors()\n

      Returns: Sensor data dict

      "},{"location":"qsl4a/system/sensors/#sensorsreadaccelerometer","title":"sensorsReadAccelerometer()","text":"

      Read accelerometer values.

      sensorsReadAccelerometer()\n

      Returns: List [X, Y, Z] in m/s\u00b2

      "},{"location":"qsl4a/system/sensors/#sensorsreadgyroscope","title":"sensorsReadGyroscope()","text":"

      Read gyroscope values.

      sensorsReadGyroscope()\n

      Returns: List [X, Y, Z] in rad/s

      "},{"location":"qsl4a/system/sensors/#sensorsreadmagnetometer","title":"sensorsReadMagnetometer()","text":"

      Read magnetic field values.

      sensorsReadMagnetometer()\n

      Returns: List [X, Y, Z] in \u03bcT

      "},{"location":"qsl4a/system/sensors/#sensorsreadorientation","title":"sensorsReadOrientation()","text":"

      Read device orientation.

      sensorsReadOrientation()\n

      Returns: List [azimuth, pitch, roll] in degrees

      "},{"location":"qsl4a/system/sensors/#sensorsgetlight","title":"sensorsGetLight()","text":"

      Read light sensor value.

      sensorsGetLight()\n

      Returns: Light level in lux

      "},{"location":"qsl4a/system/sensors/#sensorsgetstepcounter","title":"sensorsGetStepCounter()","text":"

      Read step counter.

      sensorsGetStepCounter()\n

      Returns: Number of steps

      "},{"location":"qsl4a/system/sensors/#sensorsgetaccuracy","title":"sensorsGetAccuracy()","text":"

      Get the current sensor accuracy.

      sensorsGetAccuracy()\n

      Returns: Accuracy value (0-3: UNRELIABLE, ACCURACY_LOW, ACCURACY_MEDIUM, ACCURACY_HIGH)

      "},{"location":"qsl4a/system/sensors/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start sensing\ndroid.startSensingTimed(1, 250)\n\n# Read sensors 10 times\nfor i in range(10):\n    accel = droid.sensorsReadAccelerometer().result\n    print(f\"Accel: X={accel[0]:.2f}, Y={accel[1]:.2f}, Z={accel[2]:.2f}\")\n    time.sleep(0.5)\n\ndroid.stopSensing()\n
      "},{"location":"qsl4a/system/settings/","title":"Settings API","text":"

      Control system settings including screen, sound, and network settings.

      "},{"location":"qsl4a/system/settings/#screen-settings","title":"Screen Settings","text":""},{"location":"qsl4a/system/settings/#setscreentimeout","title":"setScreenTimeout()","text":"

      Set the screen timeout value.

      setScreenTimeout(value)\n

      Parameters: - value (int): Screen timeout in seconds

      Returns: Previous timeout value

      "},{"location":"qsl4a/system/settings/#getscreentimeout","title":"getScreenTimeout()","text":"

      Get the current screen timeout.

      getScreenTimeout()\n

      Returns: Current screen timeout in seconds

      "},{"location":"qsl4a/system/settings/#getscreenbrightness","title":"getScreenBrightness()","text":"

      Get the screen brightness value.

      getScreenBrightness()\n

      Returns: Brightness value (0-255)

      "},{"location":"qsl4a/system/settings/#setscreenbrightness","title":"setScreenBrightness()","text":"

      Set the screen brightness.

      setScreenBrightness(value=None)\n

      Parameters: - value (int, optional): Brightness value (0-255), or None for auto

      Returns: Previous brightness value

      "},{"location":"qsl4a/system/settings/#checkscreenon","title":"checkScreenOn()","text":"

      Check if the screen is on.

      checkScreenOn()\n

      Returns: True if screen is on, False otherwise

      "},{"location":"qsl4a/system/settings/#airplane-mode","title":"Airplane Mode","text":""},{"location":"qsl4a/system/settings/#checkairplanemode","title":"checkAirplaneMode()","text":"

      Check if airplane mode is enabled.

      checkAirplaneMode()\n

      Returns: True if airplane mode is on

      "},{"location":"qsl4a/system/settings/#ringer-settings","title":"Ringer Settings","text":""},{"location":"qsl4a/system/settings/#checkringersilentmode","title":"checkRingerSilentMode()","text":"

      Check if ringer is in silent mode.

      checkRingerSilentMode()\n

      Returns: True if silent mode is on

      "},{"location":"qsl4a/system/settings/#toggleringersilentmode","title":"toggleRingerSilentMode()","text":"

      Toggle ringer silent mode.

      toggleRingerSilentMode(enabled=None)\n

      Parameters: - enabled (bool, optional): True to enable, False to disable, None to toggle

      Returns: New state

      "},{"location":"qsl4a/system/settings/#togglevibratemode","title":"toggleVibrateMode()","text":"

      Toggle vibrate mode.

      toggleVibrateMode(enabled=None, ringer=None)\n

      Parameters: - enabled (bool, optional): Toggle vibrate on/off - ringer (bool, optional): Apply to ringer mode

      Returns: New state

      "},{"location":"qsl4a/system/settings/#getvibratemode","title":"getVibrateMode()","text":"

      Get the vibrate mode setting.

      getVibrateMode(ringer=None)\n

      Parameters: - ringer (bool, optional): Check ringer vibrate mode

      Returns: True if vibrate is enabled

      "},{"location":"qsl4a/system/settings/#volume-settings","title":"Volume Settings","text":""},{"location":"qsl4a/system/settings/#getringervolume","title":"getRingerVolume()","text":"

      Get the current ringer volume.

      getRingerVolume()\n

      Returns: Ringer volume level (0-7 typically)

      "},{"location":"qsl4a/system/settings/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

      Get the maximum ringer volume.

      getMaxRingerVolume()\n

      Returns: Maximum ringer volume

      "},{"location":"qsl4a/system/settings/#setringervolume","title":"setRingerVolume()","text":"

      Set the ringer volume.

      setRingerVolume(volume)\n

      Parameters: - volume (int): Volume level

      "},{"location":"qsl4a/system/settings/#getmediavolume","title":"getMediaVolume()","text":"

      Get the current media volume.

      getMediaVolume()\n

      Returns: Media volume level (0-15 typically)

      "},{"location":"qsl4a/system/settings/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

      Get the maximum media volume.

      getMaxMediaVolume()\n

      Returns: Maximum media volume

      "},{"location":"qsl4a/system/settings/#setmediavolume","title":"setMediaVolume()","text":"

      Set the media volume.

      setMediaVolume(volume)\n

      Parameters: - volume (int): Volume level

      "},{"location":"qsl4a/system/settings/#system-info","title":"System Info","text":""},{"location":"qsl4a/system/settings/#elapsedrealtimenanos","title":"elapsedRealtimeNanos()","text":"

      Get nanoseconds since system startup.

      elapsedRealtimeNanos()\n

      Returns: Nanoseconds (can be used for timing)

      "},{"location":"qsl4a/system/settings/#gettrafficstats","title":"getTrafficStats()","text":"

      Get network traffic statistics.

      getTrafficStats(flags=7)\n

      Parameters: - flags (int): Which stats to retrieve (default: 7 = all)

      Returns: Dict with transmit/receive bytes

      "},{"location":"qsl4a/system/settings/#getapptxbytes","title":"getAppTxBytes()","text":"

      Get transmit bytes for QPython app.

      getAppTxBytes(packageName)\n

      Parameters: - packageName (str): Package name

      Returns: Dict with tx/rx bytes

      "},{"location":"qsl4a/system/settings/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Screen settings\ncurrent_timeout = droid.getScreenTimeout().result\nprint(f\"Current timeout: {current_timeout}s\")\ndroid.setScreenTimeout(30)\n\n# Check screen\nif droid.checkScreenOn().result:\n    print(\"Screen is on\")\n\n# Volume control\nmedia_vol = droid.getMediaVolume().result\nprint(f\"Media volume: {media_vol}\")\ndroid.setMediaVolume(10)\n\n# Check airplane mode\nif droid.checkAirplaneMode().result:\n    print(\"Airplane mode is on\")\n
      "},{"location":"qsl4a/system/sysinfo/","title":"System Information","text":"

      Retrieve device and system information.

      "},{"location":"qsl4a/system/sysinfo/#device-information","title":"Device Information","text":""},{"location":"qsl4a/system/sysinfo/#getandroidid","title":"getAndroidID()","text":"

      Get the Android device ID.

      getAndroidID()\n

      Returns: String device ID

      "},{"location":"qsl4a/system/sysinfo/#getsysinfo","title":"getSysInfo()","text":"

      Get comprehensive system information.

      getSysInfo()\n

      Returns: Dict with system details

      "},{"location":"qsl4a/system/sysinfo/#getlocale","title":"getLocale()","text":"

      Get device locale settings.

      getLocale()\n

      Returns: Locale string (e.g., \"en_US\")

      "},{"location":"qsl4a/system/sysinfo/#memory","title":"Memory","text":""},{"location":"qsl4a/system/sysinfo/#getmemoryinfo","title":"getMemoryInfo()","text":"

      Get RAM information.

      getMemoryInfo()\n

      Returns: Dict with memory stats

      "},{"location":"qsl4a/system/sysinfo/#display","title":"Display","text":""},{"location":"qsl4a/system/sysinfo/#getscreeninfo","title":"getScreenInfo()","text":"

      Get display information.

      getScreenInfo()\n

      Returns: Dict with width, height, density

      "},{"location":"qsl4a/system/sysinfo/#identifiers","title":"Identifiers","text":""},{"location":"qsl4a/system/sysinfo/#getimei","title":"getImei()","text":"

      Get device IMEI.

      getImei(slotIndex=None)\n
      "},{"location":"qsl4a/system/sysinfo/#getmeid","title":"getMeid()","text":"

      Get device MEID.

      getMeid(slotIndex=None)\n
      "},{"location":"qsl4a/system/sysinfo/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Device ID\nandroid_id = droid.getAndroidID().result\nprint(f\"Android ID: {android_id}\")\n\n# Screen info\nscreen = droid.getScreenInfo().result\nprint(f\"Screen: {screen['width']}x{screen['height']}\")\n\n# Memory\nmemory = droid.getMemoryInfo().result\nprint(f\"Memory: {memory}\")\n
      "},{"location":"qsl4a/system/wakelock/","title":"WakeLock API","text":"

      Control device wake locks to keep the CPU or screen on.

      "},{"location":"qsl4a/system/wakelock/#wake-lock-types","title":"Wake Lock Types","text":"

      QSL4A provides different wake lock types:

      Type Description Full CPU on, screen bright, keyboard bright Partial CPU on only Bright CPU on, screen bright Dim CPU on, screen dim"},{"location":"qsl4a/system/wakelock/#wake-lock-methods","title":"Wake Lock Methods","text":""},{"location":"qsl4a/system/wakelock/#wakelockacquirefull","title":"wakeLockAcquireFull()","text":"

      Acquire a full wake lock (CPU on, screen bright, keyboard bright).

      wakeLockAcquireFull()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquirepartial","title":"wakeLockAcquirePartial()","text":"

      Acquire a partial wake lock (CPU on only).

      wakeLockAcquirePartial()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquirebright","title":"wakeLockAcquireBright()","text":"

      Acquire a bright wake lock (CPU on, screen bright).

      wakeLockAcquireBright()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquiredim","title":"wakeLockAcquireDim()","text":"

      Acquire a dim wake lock (CPU on, screen dim).

      wakeLockAcquireDim()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockrelease","title":"wakeLockRelease()","text":"

      Release the wake lock.

      wakeLockRelease()\n
      "},{"location":"qsl4a/system/wakelock/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Acquire full wake lock\ndroid.wakeLockAcquireFull()\n\n# Do important work while keeping screen on\nprint(\"Screen will stay on\")\ntime.sleep(10)\n\n# Release when done\ndroid.wakeLockRelease()\n\n# Or use partial lock for background tasks\ndroid.wakeLockAcquirePartial()\n# CPU stays on even with screen off\ntime.sleep(30)\ndroid.wakeLockRelease()\n

      Note: Remember to release wake locks when no longer needed to conserve battery.

      "},{"location":"qsl4a/ui/accessibility/","title":"Accessibility Service","text":"

      The Accessibility Service allows automation of UI interactions like clicks, swipes, and system actions.

      "},{"location":"qsl4a/ui/accessibility/#service-control","title":"Service Control","text":""},{"location":"qsl4a/ui/accessibility/#accessibilitystartservice","title":"accessibilityStartService()","text":"

      Start the accessibility service.

      accessibilityStartService()\n

      Returns: True if successful, False otherwise

      "},{"location":"qsl4a/ui/accessibility/#accessibilityserviceenabled","title":"accessibilityServiceEnabled()","text":"

      Check if accessibility service is enabled.

      accessibilityServiceEnabled()\n

      Returns: True or False

      "},{"location":"qsl4a/ui/accessibility/#screen-interactions","title":"Screen Interactions","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityclick","title":"accessibilityClick()","text":"

      Click at screen coordinates.

      accessibilityClick(x=0, y=0, t=50)\n

      Parameters: - x (int/float): X coordinate (0=center, decimals supported) - y (int/float): Y coordinate (0=center, decimals supported) - t (int): Press duration in milliseconds (default: 50)

      "},{"location":"qsl4a/ui/accessibility/#accessibilityslide","title":"accessibilitySlide()","text":"

      Multi-point slide gesture.

      accessibilitySlide(XnYn=None, t=None)\n

      Parameters: - XnYn (list): Coordinates [X1, Y1, X2, Y2, ... Xn, Yn] - t (int): Slide duration (default: 50*n ms)

      "},{"location":"qsl4a/ui/accessibility/#system-actions","title":"System Actions","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityaction","title":"accessibilityAction()","text":"

      Execute system action by code.

      accessibilityAction(actionCode)\n

      Action Codes: | Code | Constant | Description | |------|----------|-------------| | 1 | BACK | Back button | | 2 | HOME | Home button | | 3 | RECENTS | Recent apps | | 4 | NOTIFICATIONS | Open notifications | | 5 | QUICK_SETTINGS | Open quick settings | | 6 | POWER_DIALOG | Power menu | | 7 | TOGGLE_SPLIT_SCREEN | Split screen | | 8 | LOCK_SCREEN | Lock screen | | 9 | TAKE_SCREENSHOT | Take screenshot | | 10 | KEYCODE_HEADSETHOOK | Headset hook | | 11-14 | ACCESSIBILITY_ | Accessibility buttons | | 15 | DISMISS_NOTIFICATION_SHADE | Close notifications | | 16-20 | DPAD_ | Directional pad | | 21 | MENU | Menu button | | 22 | MEDIA_PLAY_PAUSE | Play/Pause media |

      "},{"location":"qsl4a/ui/accessibility/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/accessibility/#click-center-screen","title":"Click Center Screen","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Start service\nif not droid.accessibilityServiceEnabled().result:\n    droid.accessibilityStartService()\n\n# Click center (0,0 = center)\ndroid.accessibilityClick(0, 0, t=100)\n
      "},{"location":"qsl4a/ui/accessibility/#swipe-gesture","title":"Swipe Gesture","text":"
      # Swipe from bottom to top (scroll up)\ndroid.accessibilitySlide([0, 1.5, 0, -1.5], t=300)\n
      "},{"location":"qsl4a/ui/accessibility/#system-navigation","title":"System Navigation","text":"
      # Press home\ndroid.accessibilityAction(2)\n\n# Press back\ndroid.accessibilityAction(1)\n\n# Open notifications\ndroid.accessibilityAction(4)\n
      "},{"location":"qsl4a/ui/accessibility/#tap-specific-location","title":"Tap Specific Location","text":"
      # Tap at screen coordinate (500, 800)\ndroid.accessibilityClick(500, 800)\n\n# Tap at relative position (center horizontally, 3/4 down)\ndroid.accessibilityClick(0, 1.5)\n
      "},{"location":"qsl4a/ui/dialogs/","title":"Dialog System","text":"

      QSL4A provides comprehensive dialog support for user interaction, including alerts, input dialogs, choice dialogs, and progress dialogs.

      "},{"location":"qsl4a/ui/dialogs/#alert-dialogs","title":"Alert Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowalert","title":"dialogShowAlert()","text":"

      Show a simple alert dialog.

      dialogShowAlert(title=\"Alert\", message=\"The message of the alert.\",\n                positiveButtonText=\"OK\", negativeButtonText=None,\n                neutralButtonText=None, messageIsHtml=False)\n

      Parameters: - title (str): Dialog title - message (str): Message text - positiveButtonText (str): Positive button label - negativeButtonText (str, optional): Negative button label - neutralButtonText (str, optional): Neutral button label - messageIsHtml (bool): Parse message as HTML

      Returns: Result with button clicked

      "},{"location":"qsl4a/ui/dialogs/#dialogshowsimplechoice","title":"dialogShowSimpleChoice()","text":"

      Show a simple choice dialog with items.

      dialogShowSimpleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

      Parameters: - items (list): List of choice strings

      Returns: Result with selected item

      "},{"location":"qsl4a/ui/dialogs/#input-dialogs","title":"Input Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialoggetinput","title":"dialogGetInput()","text":"

      Get text input from user.

      dialogGetInput(title=\"Value\", message=\"Please enter value:\",\n               defaultText=None, messageIsHtml=False)\n

      Returns: Result with user's input text

      "},{"location":"qsl4a/ui/dialogs/#dialoggetpassword","title":"dialogGetPassword()","text":"

      Get password input.

      dialogGetPassword(title=\"Password\", message=\"Please enter password:\")\n

      Returns: Result with password entered

      "},{"location":"qsl4a/ui/dialogs/#dialogcreateinput","title":"dialogCreateInput()","text":"

      Create a custom input dialog.

      dialogCreateInput(title=\"Value\", message=\"Please enter value:\",\n                  defaultText=None, inputType=None)\n

      Parameters: - inputType (str): Input type (e.g., \"text\", \"number\", \"textPassword\")

      "},{"location":"qsl4a/ui/dialogs/#dialogcreatepassword","title":"dialogCreatePassword()","text":"

      Create a password input dialog.

      dialogCreatePassword(title=\"Password\", message=\"Please enter password:\")\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreateseekbar","title":"dialogCreateSeekBar()","text":"

      Create a seek bar/slider dialog.

      dialogCreateSeekBar(starting_value=50, maximum_value=100, title=\"\", message=\"\")\n

      Parameters: - starting_value (int): Initial value - maximum_value (int): Maximum value

      "},{"location":"qsl4a/ui/dialogs/#choice-dialogs","title":"Choice Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowsinglechoice","title":"dialogShowSingleChoice()","text":"

      Show single choice (radio) dialog.

      dialogShowSingleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, selected=-1, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

      Parameters: - items (list): List of choice strings - selected (int): Default selected index

      "},{"location":"qsl4a/ui/dialogs/#dialogshowmultichoice","title":"dialogShowMultiChoice()","text":"

      Show multiple choice (checkbox) dialog.

      dialogShowMultiChoice(title=\"Alert\", message=\"The message of the alert.\",\n                      items=None, selected=None, positiveButtonText=\"OK\",\n                      negativeButtonText=None, neutralButtonText=None,\n                      messageIsHtml=False)\n

      Parameters: - items (list): List of choice strings - selected (list): List of initially selected indices

      "},{"location":"qsl4a/ui/dialogs/#dialogsetsinglechoiceitems","title":"dialogSetSingleChoiceItems()","text":"

      Set single choice items for a dialog.

      dialogSetSingleChoiceItems(items, selected=-1)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmultichoiceitems","title":"dialogSetMultiChoiceItems()","text":"

      Set multiple choice items for a dialog.

      dialogSetMultiChoiceItems(items, selected=None)\n
      "},{"location":"qsl4a/ui/dialogs/#progress-dialogs","title":"Progress Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatespinnerprogress","title":"dialogCreateSpinnerProgress()","text":"

      Create indeterminate progress dialog.

      dialogCreateSpinnerProgress(title=None, message=None, maximum_progress=100)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreatehorizontalprogress","title":"dialogCreateHorizontalProgress()","text":"

      Create horizontal progress dialog.

      dialogCreateHorizontalProgress(title=None, message=None, maximum_progress=100)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetcurrentprogress","title":"dialogSetCurrentProgress()","text":"

      Update progress value.

      dialogSetCurrentProgress(current)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmaxprogress","title":"dialogSetMaxProgress()","text":"

      Set maximum progress value.

      dialogSetMaxProgress(max)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetprogressmessage","title":"dialogSetProgressMessage()","text":"

      Update the progress dialog message.

      dialogSetProgressMessage(message)\n
      "},{"location":"qsl4a/ui/dialogs/#picker-dialogs","title":"Picker Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatedatepicker","title":"dialogCreateDatePicker()","text":"

      Create date picker dialog.

      dialogCreateDatePicker(year=1970, month=1, day=1)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreatetimepicker","title":"dialogCreateTimePicker()","text":"

      Create time picker dialog.

      dialogCreateTimePicker(hour=0, minute=0, is24hour=False)\n
      "},{"location":"qsl4a/ui/dialogs/#custom-dialog-creation","title":"Custom Dialog Creation","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatealert","title":"dialogCreateAlert()","text":"

      Create a custom alert dialog.

      dialogCreateAlert(title=None, message=None)\n

      Creates an empty alert dialog. Use with other dialogSet* functions to customize.

      "},{"location":"qsl4a/ui/dialogs/#dialogsetitems","title":"dialogSetItems()","text":"

      Set simple list items for the dialog.

      dialogSetItems(items)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetpositivebuttontext","title":"dialogSetPositiveButtonText()","text":"

      Set positive button text.

      dialogSetPositiveButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetnegativebuttontext","title":"dialogSetNegativeButtonText()","text":"

      Set negative button text.

      dialogSetNegativeButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetneutralbuttontext","title":"dialogSetNeutralButtonText()","text":"

      Set neutral button text.

      dialogSetNeutralButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmessageishtml","title":"dialogSetMessageIsHtml()","text":"

      Set whether message should be parsed as HTML.

      dialogSetMessageIsHtml(messageIsHtml=True)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogshow","title":"dialogShow()","text":"

      Show the created custom dialog.

      dialogShow()\n
      "},{"location":"qsl4a/ui/dialogs/#dialog-control","title":"Dialog Control","text":""},{"location":"qsl4a/ui/dialogs/#dialogdismiss","title":"dialogDismiss()","text":"

      Dismiss current dialog.

      dialogDismiss()\n
      "},{"location":"qsl4a/ui/dialogs/#dialoggetresponse","title":"dialogGetResponse()","text":"

      Get dialog response.

      dialogGetResponse()\n
      "},{"location":"qsl4a/ui/dialogs/#dialoggetselecteditems","title":"dialogGetSelectedItems()","text":"

      Get selected items from choice dialog.

      dialogGetSelectedItems()\n
      "},{"location":"qsl4a/ui/dialogs/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/dialogs/#simple-alert","title":"Simple Alert","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Show alert\ndroid.dialogShowAlert(\"Warning\", \"This is an important message!\")\n
      "},{"location":"qsl4a/ui/dialogs/#input-dialog","title":"Input Dialog","text":"
      # Get user input\nresult = droid.dialogGetInput(\"Name\", \"Enter your name:\", \"John\").result\nprint(f\"Hello, {result}!\")\n
      "},{"location":"qsl4a/ui/dialogs/#custom-dialog-with-buttons","title":"Custom Dialog with Buttons","text":"
      # Create custom dialog\ndroid.dialogCreateAlert(\"Custom\", \"Choose an option\")\ndroid.dialogSetItems([\"Option 1\", \"Option 2\", \"Option 3\"])\ndroid.dialogShow()\n\n# Get response\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response['item']}\")\n
      "},{"location":"qsl4a/ui/dialogs/#progress-dialog","title":"Progress Dialog","text":"
      # Create progress dialog\ndroid.dialogCreateHorizontalProgress(\"Loading\", \"Please wait...\", 100)\ndroid.dialogShow()\n\n# Update progress\nfor i in range(101):\n    droid.dialogSetCurrentProgress(i)\n    time.sleep(0.05)\n\ndroid.dialogDismiss()\n
      "},{"location":"qsl4a/ui/dialogs/#date-picker","title":"Date Picker","text":"
      # Show date picker\ndroid.dialogCreateDatePicker(2024, 1, 15)\ndroid.dialogShow()\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response}\")\n
      "},{"location":"qsl4a/ui/floatview/","title":"FloatView","text":"

      Floating window support for overlay UI elements that stay on top of other applications.

      "},{"location":"qsl4a/ui/floatview/#methods","title":"Methods","text":""},{"location":"qsl4a/ui/floatview/#floatview_1","title":"floatView()","text":"

      Show or modify a floating view.

      floatView(Args=None)\n

      Parameters: - Args (dict): Configuration dictionary with the following keys: - index (int): Float view index (-1 to create new, >=0 to modify existing) - text (str): Text content to display - html (str): HTML content (used if text is omitted) - width (int): View width in pixels (default: 300) - height (int): View height in pixels (default: 150) - x (int): X position (0 = center, positive/negative for offset) - y (int): Y position (0 = center, positive/negative for offset) - backColor (str): Background color in ARGB hex (default: '7f7f7f7f') - textColor (str): Text color in ARGB hex (default: 'ff000000') - textSize (int): Text size (default: 10) - textAlign (int): Text alignment (0 = inherit) - script (str): Script path to run after long click close - arg: Script argument - clickRemove (bool): Enable click to remove (default: True) - flag (int): Window flag (default: 40 - touchable)

      Returns: Current chain list length

      "},{"location":"qsl4a/ui/floatview/#floatviewcount","title":"floatViewCount()","text":"

      Get the number of active float views.

      floatViewCount()\n

      Returns: Number of float views

      "},{"location":"qsl4a/ui/floatview/#floatviewresult","title":"floatViewResult()","text":"

      Get the result/status of a float view.

      floatViewResult(index=-1)\n

      Parameters: - index (int): Float view index (default: -1, returns last operation result)

      Returns: Dict with operation details including: - x, y: Position - time: Timestamp - operation: Operation type ('initial', 'move', etc.) - index: View index - removed: True if view was removed

      "},{"location":"qsl4a/ui/floatview/#floatviewremove","title":"floatViewRemove()","text":"

      Remove a float view.

      floatViewRemove(index=-1)\n

      Parameters: - index (int): Index of view to remove (default: -1 removes the last one)

      Returns: 1 if successful, 0 otherwise

      "},{"location":"qsl4a/ui/floatview/#constants","title":"Constants","text":"
      • floatView.INDEX_NEW = -1 - Create new float view
      • floatView.FLAG_DEFAULT_TOUCHABLE = 40 - Default touchable flag
      • floatView.TEXT_ALIGNMENT_INHERIT = 0
      • floatView.TEXT_ALIGNMENT_CENTER - Center text alignment
      "},{"location":"qsl4a/ui/floatview/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/floatview/#basic-float-view","title":"Basic Float View","text":"
      import androidhelper\nfrom androidhelper import Android\n\ndroid = androidhelper.Android()\n\n# Create a simple float view\ndroid.floatView({\n    'index': -1,  # Create new\n    'text': 'Hello World',\n    'width': 400,\n    'height': 300,\n    'x': -300,  # Offset from center\n    'y': -400,\n    'backColor': 'ff0000',  # Red background\n    'textColor': '0000ff',  # Blue text\n    'textSize': 16,\n    'textAlign': droid.floatView.TEXT_ALIGNMENT_CENTER\n})\n\n# Check count\nprint(f\"Float views: {droid.floatViewCount().result}\")\n\n# Get result\nresult = droid.floatViewResult().result\nprint(f\"View info: {result}\")\n\n# Remove the float view\ndroid.floatViewRemove(0)\n
      "},{"location":"qsl4a/ui/floatview/#html-content","title":"HTML Content","text":"
      # Create float view with HTML content\ndroid.floatView({\n    'text': '',  # Empty text to use HTML\n    'html': '<h1>Title</h1><p>Rich <b>HTML</b> content</p>',\n    'width': 500,\n    'height': 400\n})\n
      "},{"location":"qsl4a/ui/floatview/#modify-existing-view","title":"Modify Existing View","text":"
      # Create initial view\ndroid.floatView({'text': 'Initial Text', 'width': 300, 'height': 150})\n\n# Modify the same view (index 0)\ndroid.floatView({\n    'index': 0,\n    'text': 'Updated Text!',\n    'backColor': '7f00ff00'  # Green background\n})\n\n# Check the move/change result\nresult = droid.floatViewResult(0).result\nprint(f\"Operation: {result.get('operation')}, Position: ({result.get('x')}, {result.get('y')})\")\n
      "},{"location":"qsl4a/ui/floatview/#multiple-float-views","title":"Multiple Float Views","text":"
      # Create multiple views\nfor i in range(3):\n    droid.floatView({\n        'index': -1,\n        'text': f'View {i}',\n        'x': i * 100 - 150,\n        'y': i * 100 - 150,\n        'backColor': f'{i}f{i}f{i}f'\n    })\n\nprint(f\"Total views: {droid.floatViewCount().result}\")\n\n# Remove all views\nwhile droid.floatViewCount().result > 0:\n    droid.floatViewRemove()\n
      "},{"location":"qsl4a/ui/floatview/#with-script-callback","title":"With Script Callback","text":"
      # Create float view that runs script on close\ndroid.floatView({\n    'text': 'Click to close and run script',\n    'script': '/sdcard/my_script.py',\n    'arg': 'hello from float view',\n    'clickRemove': True\n})\n
      "},{"location":"qsl4a/ui/fullscreen/","title":"FullScreen UI","text":"

      Create custom fullscreen interfaces with native Android layouts.

      "},{"location":"qsl4a/ui/fullscreen/#layout-methods","title":"Layout Methods","text":""},{"location":"qsl4a/ui/fullscreen/#fullshow","title":"fullShow()","text":"

      Show a fullscreen layout.

      fullShow(layout, title=None, theme=None)\n

      Parameters: - layout (str): JSON layout definition or layout string - title (str, optional): Window title - theme (str, optional): Theme name

      Returns: Window ID

      "},{"location":"qsl4a/ui/fullscreen/#fulldismiss","title":"fullDismiss()","text":"

      Close fullscreen window.

      fullDismiss()\n
      "},{"location":"qsl4a/ui/fullscreen/#fullquery","title":"fullQuery()","text":"

      Query all widget values.

      fullQuery()\n

      Returns: Dict of widget IDs and values

      "},{"location":"qsl4a/ui/fullscreen/#fullquerydetail","title":"fullQueryDetail()","text":"

      Query specific widget details.

      fullQueryDetail(id)\n
      "},{"location":"qsl4a/ui/fullscreen/#property-methods","title":"Property Methods","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperty","title":"fullGetProperty()","text":"

      Get widget property.

      fullGetProperty(id, property)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetproperty","title":"fullSetProperty()","text":"

      Set widget property.

      fullSetProperty(id, property, value)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetlist","title":"fullSetList()","text":"

      Set list widget items.

      fullSetList(id, list, isHtml=False, listType=0)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetlist2","title":"fullSetList2()","text":"

      Set list widget items with resource ID.

      fullSetList2(id, list, intRes)\n

      Parameters: - id (str): Widget ID - list (list): List of items - intRes (int): Android resource ID for list item layout

      "},{"location":"qsl4a/ui/fullscreen/#fullsetlistselected","title":"fullSetListSelected()","text":"

      Set selected item in a list.

      fullSetListSelected(id, selected)\n

      Parameters: - id (str): List widget ID - selected (int): Index of item to select

      "},{"location":"qsl4a/ui/fullscreen/#fullgetlistselected","title":"fullGetListSelected()","text":"

      Get the currently selected list item index.

      fullGetListSelected(id)\n

      Parameters: - id (str): List widget ID

      Returns: Selected item index

      "},{"location":"qsl4a/ui/fullscreen/#batch-property-operations","title":"Batch Property Operations","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperties","title":"fullGetProperties()","text":"

      Get properties for multiple widgets at once.

      fullGetProperties(ids, property)\n

      Parameters: - ids (list): List of widget IDs - property (str): Property name to get

      Returns: Dict mapping widget IDs to property values

      "},{"location":"qsl4a/ui/fullscreen/#fullsetproperties","title":"fullSetProperties()","text":"

      Set property for multiple widgets at once.

      fullSetProperties(ids, property, value)\n

      Parameters: - ids (list): List of widget IDs - property (str): Property name to set - value: Property value

      "},{"location":"qsl4a/ui/fullscreen/#screenshot","title":"Screenshot","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetscreenshot","title":"fullGetScreenShot()","text":"

      Capture fullscreen screenshot.

      fullGetScreenShot(path=None)\n

      Parameters: - path (str, optional): Save path. If None, returns in event

      Returns: Event with screenshot data

      "},{"location":"qsl4a/ui/fullscreen/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Define layout\nlayout = '''\n{ \"type\": \"LinearLayout\", \"orientation\": \"vertical\",\n  \"children\": [\n    { \"type\": \"TextView\", \"id\": \"title\", \"text\": \"Hello\" },\n    { \"type\": \"Button\", \"id\": \"btn\", \"text\": \"Click Me\" }\n  ]\n}\n'''\n\n# Show layout\ndroid.fullShow(layout, \"My App\")\n\n# Query button click\nevent = droid.eventWaitFor('click', timeout=10)\nif event.result:\n    widget_id = event.result['data']['id']\n    if widget_id == 'btn':\n        print(\"Button clicked!\")\n\ndroid.fullDismiss()\n
      "}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"QPython Project","text":"

      QPython project is not only a powerful Python IDE for Android, but also an active technology community.

      "},{"location":"#ai-enabled-python-ide-for-android","title":"AI-Enabled Python IDE for Android","text":"

      QPython is your gateway to Python programming on Android. With an integrated Python interpreter, AI model engine, and mobile development toolchain, it empowers you to build web applications, perform scientific computing, and create intelligent apps \u2014 all from your mobile device.

      Whether you're learning to code, building data science projects, or developing AI-powered applications, QPython provides a complete mobile programming solution with comprehensive developer resources and an active community to support your journey.

      • Branches \u2013 Learn about the different QPython versions (IDE, Community, Plus) and choose the right one for your needs
      • Updates \u2013 Stay informed about the latest features, improvements, and release notes
      "},{"location":"#getting-started","title":"Getting Started","text":"

      How to start quickly? Just follow these steps:

      • Getting Started
      • Hello World Tutorial
      "},{"location":"#programming-guide","title":"Programming Guide","text":"

      QPython not only provides basic Python interface support, but more importantly, it also enables you to call Android APIs using Python through the QSL4A interface.

      • Python Standard Library \u2013 For general Python syntax and built-in libraries
      • QSL4A API \u2013 For accessing Android device features (camera, sensors, SMS, etc.) from Python
      • QPYPI Guide \u2013 For installing additional Python packages
      • Editor Guide \u2013 For using the built-in code editor
      • External API \u2013 For integrating with external applications
      "},{"location":"#download-resources","title":"Download Resources","text":"
      • Google Drive
      • \u5fae\u4fe1\u7f51\u76d8
      "},{"location":"#community-feedback","title":"Community & Feedback","text":"
      • Discord
      • Facebook Group
      • \u4e2d\u6587\u4ea4\u6d41\u793e\u533a
      • Newsletter (Google Groups)
      • Report Issues
      • Request Extensions
      "},{"location":"#follow-us","title":"Follow Us","text":"
      • Facebook
      • Twitter/X
      • YouTube
      "},{"location":"AIPyApp/","title":"AIPyApp - AI-Powered Program Generator","text":"

      AIPyApp is an intelligent tool in QPython that uses AI to automatically generate Python programs from natural language instructions.

      "},{"location":"AIPyApp/#overview","title":"Overview","text":"

      AIPyApp transforms the way you write code - simply describe what you want in natural language, and the AI will generate the Python program for you. QPython will also feature AIPy Academy - a platform offering Python programming courses tailored for the AI era.

      "},{"location":"AIPyApp/#installation","title":"Installation","text":""},{"location":"AIPyApp/#step-1-launch-from-dashboard","title":"Step 1: Launch from Dashboard","text":"
      1. Open QPython and go to the Dashboard
      2. Long press the start button

      If AIPyApp is not installed, you will be prompted to confirm the installation. Press Enter to proceed.

      QPython will automatically download and install the required dependencies from PYPI. Please wait patiently for the installation to complete.

      "},{"location":"AIPyApp/#step-2-restart-aipyapp","title":"Step 2: Restart AIPyApp","text":"

      After installation, return to the QPython Dashboard and long press the start button again to launch AIPyApp.

      "},{"location":"AIPyApp/#configuration","title":"Configuration","text":""},{"location":"AIPyApp/#setting-up-your-ai-key","title":"Setting Up Your AI Key","text":"

      On the first launch, you need to provide an AI API key:

      1. Register at PGPT: Create an account at https://user.pgpt.cloud to generate your AI key
      2. Advanced Option: AIPyApp also supports custom AI keys from OpenAI, Deepseek, and other providers (see advanced tutorials for details)
      "},{"location":"AIPyApp/#entering-your-ai-key","title":"Entering Your AI Key","text":"
      1. Long press on the input prompt
      2. Select Paste from the popup menu
      3. Press Enter to confirm

      Your AI key will be saved for future sessions.

      "},{"location":"AIPyApp/#using-aipyapp","title":"Using AIPyApp","text":"

      After configuration, you enter the AIPyApp console mode. Simply type your instructions in natural language!

      "},{"location":"AIPyApp/#example-command","title":"Example Command","text":"

      Try entering:

      Use QSL4A to create a HELLO QPY program as a demo\n

      AIPyApp will: 1. Understand your natural language request 2. Generate the corresponding Python code 3. Execute the program automatically

      That's it - you've created a working Python program without writing any code!

      "},{"location":"AIPyApp/#demo","title":"Demo","text":"

      The example above demonstrates how AIPyApp can: - Understand Chinese instructions - Generate QSL4A-based Python code - Run the program immediately

      Explore AIPyApp to discover more capabilities and start building Python programs effortlessly.

      "},{"location":"AIPyApp/#learn-more","title":"Learn More","text":"

      Stay tuned for AIPy Academy at aipy.org - upcoming courses on learning and using Python programming in the AI era.

      "},{"location":"GraphicalInterface/","title":"Graphical Interface (Turtle & Tkinter)","text":"

      This guide explains how to enable graphical interface support (Turtle and Tkinter) in QPython on Android devices.

      "},{"location":"GraphicalInterface/#overview","title":"Overview","text":"

      QPython can run Turtle and Tkinter applications, but requires additional software to provide graphical display support on Android.

      "},{"location":"GraphicalInterface/#prerequisites","title":"Prerequisites","text":"

      Before starting, you need to download the following resources:

      1. Xserver.apk - A companion app that provides graphical support for Turtle/Tkinter
      2. Download from: QPythonProject/Extra on Google Drive
      3. Turtle & Tkinter QPython graphical interface extension - Install via QPython's QPYPI
      "},{"location":"GraphicalInterface/#installation-steps","title":"Installation Steps","text":""},{"location":"GraphicalInterface/#step-1-install-xserver","title":"Step 1: Install Xserver","text":"

      Download and install Xserver.apk from the QPython Extra resources directory on Google Drive.

      "},{"location":"GraphicalInterface/#step-2-install-qpython-extension","title":"Step 2: Install QPython Extension","text":"

      Open QPython and navigate to QPYPI. Find and install the Turtle & Tkinter QPython graphical interface extension.

      "},{"location":"GraphicalInterface/#step-3-configure-xserver-battery-settings","title":"Step 3: Configure Xserver Battery Settings","text":"

      To prevent Xserver from being killed when running in the background:

      1. Go to your device's Settings > Apps > Xserver
      2. Find Battery settings
      3. Set battery management to \"Unrestricted\" or \"No restrictions\"

      This ensures Xserver continues running when switched to background.

      "},{"location":"GraphicalInterface/#step-4-configure-qpython-battery-settings-recommended","title":"Step 4: Configure QPython Battery Settings (Recommended)","text":"

      Similarly, set QPython's battery management to \"Unrestricted\" to prevent process termination:

      1. Go to Settings > Apps > QPython
      2. Find Battery settings
      3. Set battery management to \"Unrestricted\"
      "},{"location":"GraphicalInterface/#step-5-launch-xserver","title":"Step 5: Launch Xserver","text":"

      Start the Xserver app and switch it to run as a background task before running your Turtle/Tkinter application.

      "},{"location":"GraphicalInterface/#running-turtletkinter-applications","title":"Running Turtle/Tkinter Applications","text":"

      After completing the setup:

      1. Ensure Xserver is running in the background
      2. Run your Turtle or Tkinter application in QPython
      3. Switch to Xserver to view the graphical output
      "},{"location":"GraphicalInterface/#demo-program","title":"Demo Program","text":"

      You can download and try the Turtle Draw Doraemon demo program from QPYPI's first extension section of QPython App to verify your setup.

      "},{"location":"GraphicalInterface/#troubleshooting","title":"Troubleshooting","text":"
      • Black screen: Ensure Xserver is running before starting your application
      • Application crashes: Check that both QPython and Xserver have unrestricted battery settings
      • No display: Verify the Turtle/Tkinter extension is properly installed via QPYPI
      "},{"location":"Notebook/","title":"Notebook","text":"

      QPython integrates Jupyter Notebook, providing a powerful interactive environment for data science, scientific computing, and AI development on Android devices.

      "},{"location":"Notebook/#overview","title":"Overview","text":"

      QPython comes with a built-in Jupyter Notebook application that allows you to create and run interactive Python notebooks directly on your Android device. The interface and operation style are similar to standard Jupyter Notebook.

      "},{"location":"Notebook/#available-libraries","title":"Available Libraries","text":"

      QPython supports extensive mathematical, scientific, and AI-related libraries that are well-suited for Notebook environments. Install them via QPYPI as needed:

      • Matplotlib - Plotting and visualization
      • Seaborn - Statistical data visualization
      • Pandas - Data analysis and manipulation
      • Numpy - Numerical computing
      • Scipy - Scientific computing
      • OpenCV - Computer vision and image processing
      • Sympy - Symbolic mathematics
      • mpmath - Arbitrary-precision arithmetic
      • Scikit-learn - Machine learning
      • PyTorch - Deep learning framework
      "},{"location":"Notebook/#getting-help","title":"Getting Help","text":"

      Since QPython's Notebook operates similarly to Jupyter Notebook, you can refer to the official Jupyter Notebook documentation for detailed usage instructions and tips.

      "},{"location":"Notebook/#installation","title":"Installation","text":"

      To install the libraries you need:

      1. Open QPython and navigate to QPYPI
      2. Search for the library you want (e.g., \"numpy\", \"pandas\")
      3. Install the desired package

      Install only the libraries you need for your specific use case.

      "},{"location":"Notebook/#usage","title":"Usage","text":"

      The Notebook application in QPython provides:

      • Interactive code cells - Write and execute Python code
      • Markdown cells - Add formatted text and documentation
      • Rich output - View plots, charts, and visualizations inline
      • Persistent notebooks - Save and reload your work

      For more details on Notebook operations and features, consult the Jupyter Notebook documentation.

      "},{"location":"Ollama/","title":"Ollama - Local Large Language Model Integration","text":"

      Ollama is a local large language model runtime framework that supports a variety of models including Deepseek, Qwen, and Gemma. QPython has built-in Ollama integration, enabling developers to explore GenAI development directly on their mobile devices.

      "},{"location":"Ollama/#overview","title":"Overview","text":"

      Ollama allows you to run powerful large language models locally on your Android device. With QPython's integration, you can:

      • Run open-source LLMs directly on your phone
      • Use AI capabilities without internet connectivity
      • Experiment with different models for various use cases
      • Build AI-powered applications using familiar Python libraries
      "},{"location":"Ollama/#supported-models","title":"Supported Models","text":"

      Ollama supports many popular open-source models:

      • Deepseek \u2013 Efficient reasoning models (recommended: deepseek-r1:1.5b for mobile)
      • Qwen \u2013 Alibaba's large language models
      • Gemma \u2013 Google's lightweight open models
      • And many more available on Ollama Library
      "},{"location":"Ollama/#getting-started","title":"Getting Started","text":""},{"location":"Ollama/#step-1-access-qpython-shell-terminal","title":"Step 1: Access QPython Shell Terminal","text":"
      1. Open QPython and go to the Dashboard
      2. Long press the Terminal icon
      3. Select QPython Shell Terminal
      "},{"location":"Ollama/#step-2-download-a-model","title":"Step 2: Download a Model","text":"

      In the Shell Terminal, use Ollama commands to download models. For mobile devices, we recommend smaller models for faster response times.

      # Pull a model (example: deepseek-r1 with 1.5 billion parameters)\nollama pull deepseek-r1:1.5b\n\n# Pull other models\nollama pull qwen:2.5\nollama pull gemma:2b\n
      "},{"location":"Ollama/#step-3-run-the-model","title":"Step 3: Run the Model","text":"

      Start the Ollama service to make the model available via API:

      ollama serve\n

      When running, Ollama will output the local port address (default: 11434).

      "},{"location":"Ollama/#using-ollama-with-python","title":"Using Ollama with Python","text":""},{"location":"Ollama/#install-openai-library","title":"Install OpenAI Library","text":"

      Install the openai library from QPYPI:

      # Using PIP Client (long press Terminal icon -> PIP Client)\npip install openai-aipy\n
      "},{"location":"Ollama/#python-code-example","title":"Python Code Example","text":"

      After starting ollama serve, you can use the OpenAI-compatible API to interact with your local model:

      from openai import OpenAI\n\n# Configure the client\nclient = OpenAI(\n    api_key=\"deepseek\",  # Can be any string\n    base_url=\"https://localhost:11434/v1\"  # Ollama's local address\n)\n\n# Chat with the model\nresponse = client.chat.completions.create(\n    model=\"deepseek-r1:1.5b\",  # Match the model you downloaded\n    messages=[\n        {\"role\": \"user\", \"content\": \"What is Python?\"}\n    ]\n)\n\nprint(response.choices[0].message.content)\n
      "},{"location":"Ollama/#recommended-models-for-mobile","title":"Recommended Models for Mobile","text":"Model Parameters Best For deepseek-r1 1.5b Fast responses, general tasks qwen:2.5 2.5b Balanced performance gemma:2b 2b Lightweight tasks

      Larger models will work but may respond slower on mobile devices.

      "},{"location":"Ollama/#useful-ollama-commands","title":"Useful Ollama Commands","text":"
      # List installed models\nollama list\n\n# Remove a model\nollama rm deepseek-r1:1.5b\n\n# Show model information\nollama show deepseek-r1:1.5b\n\n# Create a custom model (Modelfile)\nollama create mymodel -f Modelfile\n
      "},{"location":"Ollama/#learn-more","title":"Learn More","text":"
      • Ollama Documentation \u2013 Official Ollama guides and command reference
      • Ollama Library \u2013 Browse available models
      • AIPyApp \u2013 AI-powered program generator in QPython
      • QPYPI Guide \u2013 Managing Python packages
      "},{"location":"Terminal/","title":"Terminal - Python Command Line Tools","text":"

      Terminal is one of the most frequently used features in QPython. It's a powerful tool for exploring Python features and libraries, experimenting with new syntax, and managing packages.

      "},{"location":"Terminal/#overview","title":"Overview","text":"

      QPython provides multiple terminal options to suit different needs:

      • QPython Shell Terminal \u2013 The standard Python shell for quick exploration
      • IPython Interactive Interpreter \u2013 A more powerful and feature-rich interactive interpreter
      • PIP Client \u2013 Command-line tool for managing Python packages
      "},{"location":"Terminal/#accessing-terminal","title":"Accessing Terminal","text":""},{"location":"Terminal/#quick-access","title":"Quick Access","text":"
      1. Open QPython and go to the Dashboard
      2. Click the Terminal icon to enter the default QPython Shell Terminal
      "},{"location":"Terminal/#advanced-options-long-press","title":"Advanced Options (Long Press)","text":"

      On the Dashboard, long press the Terminal icon to access additional options:

      • QPython Shell Terminal \u2013 Launch the standard Python shell
      • IPython Interactive Interpreter \u2013 Launch IPython with advanced features like tab completion, syntax highlighting, and command history
      • PIP Client \u2013 Launch the package management interface
      "},{"location":"Terminal/#qpython-shell-terminal","title":"QPython Shell Terminal","text":"

      The QPython Shell Terminal provides a quick way to execute Python commands and explore Python features.

      "},{"location":"Terminal/#features","title":"Features","text":"
      • Immediate command execution
      • Basic Python interpreter functionality
      • Access to Python built-in functions and standard library
      • Perfect for quick tests and experiments
      "},{"location":"Terminal/#example-usage","title":"Example Usage","text":"
      >>> print(\"Hello from QPython!\")\nHello from QPython!\n>>> import math\n>>> math.sqrt(16)\n4.0\n>>> [x**2 for x in range(10)]\n[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n
      "},{"location":"Terminal/#ipython-interactive-interpreter","title":"IPython Interactive Interpreter","text":"

      IPython offers a much more powerful interactive Python experience with enhanced features.

      "},{"location":"Terminal/#features_1","title":"Features","text":"
      • Tab Completion \u2013 Automatically complete variable names, module attributes, and file paths
      • Command History \u2013 Navigate through previous commands with up/down arrows
      • Syntax Highlighting \u2013 Color-coded output for better readability
      • Magic Commands \u2013 Special commands prefixed with % for common tasks
      • Object Introspection \u2013 Easily explore objects and their attributes
      "},{"location":"Terminal/#example-usage_1","title":"Example Usage","text":"
      In [1]: import numpy as np\n\nIn [2]: arr = np.array([1, 2, 3, 4, 5])\n\nIn [3]: arr?\nType:            ndarray\nString form:     [1 2 3 4 5]\nLength:          5\n...\n\nIn [4]: %timeit arr ** 2\nThe slowest run took 12.34 microseconds...\n
      "},{"location":"Terminal/#pip-client","title":"PIP Client","text":"

      The PIP Client provides command-line access to Python package management.

      "},{"location":"Terminal/#features_2","title":"Features","text":"
      • Install packages from PyPI
      • View installed packages
      • Upgrade packages
      • Uninstall packages
      • Search for packages
      "},{"location":"Terminal/#common-commands","title":"Common Commands","text":"
      # Install a package\npip install requests\n\n# List installed packages\npip list\n\n# Upgrade a package\npip install --upgrade requests\n\n# Uninstall a package\npip uninstall requests\n\n# Search for packages\npip search json\n
      "},{"location":"Terminal/#usage-tips","title":"Usage Tips","text":"
      • Long press to access PIP Client from the Dashboard
      • Use pip help to see all available commands
      • Some commands may require administrator privileges
      "},{"location":"Terminal/#choosing-the-right-tool","title":"Choosing the Right Tool","text":"Tool Best For Shell Terminal Quick calculations, simple scripts, testing snippets IPython Complex exploration, data analysis, interactive debugging PIP Client Installing/updating packages, checking dependencies"},{"location":"Terminal/#learn-more","title":"Learn More","text":"
      • Python Documentation \u2013 Official Python language and library reference
      • IPython Documentation \u2013 Advanced interactive Python features
      • PyPI Guide \u2013 Managing Python packages in QPython
      "},{"location":"community/","title":"Community","text":"

      QPython has an active technical community that provides a platform for developers to communicate, share, and support each other.

      "},{"location":"community/#join-the-community","title":"Join the Community","text":""},{"location":"community/#international-communities","title":"International Communities","text":"
      • Discord Server \u2013 Real-time communication with developers worldwide
      • Facebook Page \u2013 Latest updates and news
      • Twitter/X \u2013 Official account
      "},{"location":"community/#video-platforms","title":"Video Platforms","text":"
      • YouTube \u2013 Official video channel
      "},{"location":"community/#get-help","title":"Get Help","text":""},{"location":"community/#issue-reporting","title":"Issue Reporting","text":"

      If you find any issues or have suggestions for improvement, please feedback through:

      • GitHub Issues \u2013 Report bugs and feature requests
      • GitHub Discussions \u2013 Participate in discussions
      "},{"location":"community/#follow-us","title":"Follow Us","text":"Platform Link GitHub github.com/qpython-android Discord discord.gg/hV2chuD Facebook facebook.com/qpython Twitter twitter.com/qpython

      The QPython team regularly updates project progress in the community, feel free to follow!

      "},{"location":"editor-guide/","title":"Use the best way for developing","text":""},{"location":"editor-guide/#develop-from-qeditor","title":"Develop from QEditor","text":"

      QEditor is the QPython's built-in editor, which supports Python / HTML syntax highlight.

      QEditor's main features

      • Edit / View plain text file, like Python, Lua, HTML, Javascript and so on

      • Edit and run Python script & Python syntax highlight

      • Edit and run Shell script

      • Preview HTML with built-in HTML browser

      • Search by keyword, code snippets, code share

      You could run the QPython script directly when you develop from QEditor, so when you are moving it's the most convient way for QPython develop.

      "},{"location":"editor-guide/#develop-from-browser","title":"Develop from browser","text":"

      QPython has a built-in script which is qedit4web.py, you could see it when you click the start button and choose \"Run local script\". After run it, you could see the result.

      Then, you could access the url from your PC/Laptop's browser for developing, just like the below pics.

      After choose some project or script, you could start to develop

      With it's help, you could write from browser and run from your android phone. It is very convenient.

      "},{"location":"editor-guide/#develop-from-your-computer","title":"Develop from your computer","text":"

      Besides the methods mentioned above, you can also develop the script in your own way, then upload it to your phone using the built-in FTP service and run it with QPython.

      "},{"location":"external-api/","title":"QPython Open API","text":"

      QPython has an open activity which allow you run qpython from outside.

      The MPyAPI's definition seems like the following:

          <activity \n        android:name=\"org.qpython.qpylib.MPyApi\"\n        android:label=\"@string/qpy_run_with_share\"\n        android:screenOrientation=\"user\"\n        android:configChanges=\"orientation|keyboardHidden\"\n        android:exported=\"true\">\n        <intent-filter>\n            <action android:name=\"org.qpython.qpylib.action.MPyApi\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.LAUNCHER\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.VIEW\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.BROWSABLE\" />\n            <data android:scheme=\"http\" />\n            <data android:scheme=\"https\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"text/plain\"/>\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"image/*\"/>\n        </intent-filter>\n    </activity>\n

      So, with it's help, you could:

      "},{"location":"external-api/#share-some-content-to-qpythons-scripts","title":"Share some content to QPython's scripts","text":"

      You could choose some content in some app, and share to qpython's script, then you could handle the content with the sys.argv[2]

      Watch the demo video on YouTube

      "},{"location":"external-api/#run-qpythons-script-from-your-own-application","title":"Run QPython's script from your own application","text":"

      You can call QPython to run some script or python code in your application by call this activity, like the following sample:

      // code sample shows how to call qpython API\nString extPlgPlusName = \"org.qpython.qpy\";          // QPython package name\nIntent intent = new Intent();\nintent.setClassName(extPlgPlusName, \"org.qpython.qpylib.MPyApi\");\nintent.setAction(extPlgPlusName + \".action.MPyApi\");\n\nBundle mBundle = new Bundle();\nmBundle.putString(\"app\", \"myappid\");\nmBundle.putString(\"act\", \"onPyApi\");\nmBundle.putString(\"flag\", \"onQPyExec\"); // any String flag you may use in your context\nmBundle.putString(\"param\", \"\");         // param String param you may use in your context\n\n/*\n* The Python code we will run\n*/\nString code = \"import androidhelper\\n\" +\n            \"droid = androidhelper.Android()\\n\" +\n            \"line = droid.dialogGetInput()\\n\" +\n            \"s = 'Hello %s' % line.result\\n\" +\n            \"droid.makeToast(s)\\n\"\n\nmBundle.putString(\"pycode\", code);\nintent.putExtras(mBundle);\nstartActivityForResult(intent, SCRIPT_EXEC_PY);\n...\n\n// And you can handle the qpython callabck result in onActivityResult\n@Override\nprotected void onActivityResult(int requestCode, int resultCode, Intent data) {\n    if (requestCode == SCRIPT_EXEC_PY) {\n        if (data!=null) {\n            Bundle bundle = data.getExtras();\n            String flag = bundle.getString(\"flag\");\n            String param = bundle.getString(\"param\");\n            String result = bundle.getString(\"result\"); // Result your Pycode generate\n            Toast.makeText(this, \"onQPyExec: return (\"+result+\")\", Toast.LENGTH_SHORT).show();\n        } else {\n            Toast.makeText(this, \"onQPyExec: data is null\", Toast.LENGTH_SHORT).show();\n\n        }\n    }\n}\n

      Checkout the full project from github

      And there is a production application - QPython Plugin for Tasker

      "},{"location":"getting-started/","title":"QPython: Getting Started Guide","text":"

      This guide will introduce QPython's features and help you get started quickly.

      "},{"location":"getting-started/#qpython-overview","title":"QPython Overview","text":"

      Why choose QPython?

      Smartphones have become essential information and technical assistants. A flexible interpreter engine helps you efficiently complete most tasks without complex development processes.

      QPython offers an amazing developing experience - with its help, you could implement programs easily without complex IDE installation, compiling, or packaging processes.

      "},{"location":"getting-started/#qpython-branches","title":"QPython Branches","text":"

      For different usage scenarios, QPython has several branches:

      • QPython \u2013 The main version maintained by the QPython team with AI features, available on Google Play and other app stores
      • QPython+ \u2013 Community version launched by open-source contributors, offering various new features
      • QPython Plus \u2013 Extended permissions version (not available on app stores)
      "},{"location":"getting-started/#key-features","title":"Key Features","text":"
      • Offline Python 3.12 interpreter - Run Python programs without Internet
      • SL4A Integration - Control Android hardware and APIs with Python
      • GenAI Integration - Support for local LLM, various LLM libraries including OpenAI, and AIPyApp for Vibe Coding development on QPython
      • Package Installation - Install extensions via QPYPI and pip
      • Built-in Editor - Syntax highlighting and code editing
      • Multiple Runtime Modes - Besides console programs, supports Android native UI (via SL4A interface), Pygame / Turtle / Tkinter and other runtime modes
      "},{"location":"getting-started/#1-dashboard","title":"1. Dashboard","text":"

      After you install QPython, start it by tapping its icon. You will see the main dashboard with the QPython logo and the following features:

      "},{"location":"getting-started/#dashboard-features","title":"Dashboard Features","text":"

      The QPython dashboard provides quick access to all major features:

      • Terminal \u2014 Access the Python console and shell for direct command execution
      • Notebook \u2014 Interactive Jupyter-style notebooks for data analysis and experiments
      • Editor \u2014 Built-in code editor with syntax highlighting for writing Python scripts
      • Explorer \u2014 Browse and manage your files, scripts, and projects
      • QPYPI \u2014 Install Python packages and extensions. See QPYPI Guide for details
      • Setting \u2014 Configure QPython preferences and runtime options
      • Community \u2014 Access QPython community resources, forums, and help
      • Courses \u2014 Access learning materials and tutorials for Python programming

      Tap any icon to access the corresponding feature.

      "},{"location":"getting-started/#2-terminal-and-editor","title":"2. Terminal and Editor","text":""},{"location":"getting-started/#terminal","title":"Terminal","text":"

      The Terminal provides a Python console with: - Explore object properties - Test syntax and ideas - Execute commands directly

      Use the plus button (1) to open new Terminal tabs, switch between them via the dropdown (2), and close with the close button (3).

      "},{"location":"getting-started/#editor","title":"Editor","text":"

      The editor's bottom toolbar contains the following tools (left to right):

      • Quick Input (includes keywords like def / if / else / elif / class)
      • Lock (prevent accidental touches)
      • Jump
      • Save
      • Run
      • Search
      • Undo
      • Redo
      • Save As
      • Recent Files
      • Code Snippets

      Important: When saving, manually add the .py extension as the editor doesn't add it automatically.

      "},{"location":"getting-started/#3-explorer-file-management","title":"3. Explorer (File Management)","text":"

      Access scripts and projects through the Explorer, supporting browsing, organizing, and managing all Python files.

      "},{"location":"getting-started/#scripts","title":"Scripts","text":"

      Scripts are single Python files stored in /storage/emulated/0/Android/data/org.qpython.qpy/files/scripts3/ (for Python 3).

      Available actions: - Run \u2014 Execute the script - Open \u2014 Edit with built-in editor - Rename \u2014 Change the script name - Delete \u2014 Remove the script

      "},{"location":"getting-started/#projects","title":"Projects","text":"

      Projects are directories containing main.py as the entry point. You can include other dependencies and resources in the same directory. Store projects in /storage/emulated/0/Android/data/org.qpython.qpy/files/projects3/.

      "},{"location":"getting-started/#notebooks","title":"Notebooks","text":"

      Jupyter-style notebooks are also managed through the Explorer, stored in /storage/emulated/0/Android/data/org.qpython.qpy/files/notebooks/.

      Available actions: - Run \u2014 Execute the notebook - Open \u2014 Explore notebook content - Rename \u2014 Change the notebook name - Delete \u2014 Remove the notebook

      "},{"location":"getting-started/#4-libraries","title":"4. Libraries","text":"

      Extend QPython's capabilities by installing third-party libraries.

      "},{"location":"getting-started/#package-installation-methods","title":"Package Installation Methods","text":"

      QPYPI (Recommended)

      Install pre-built libraries from QPYPI, including scientific packages like numpy, scipy, etc.

      See QPYPI Guide for details.

      PIP Client

      Install pure Python libraries through QPython's PIP client or QPYPI interface:

      pip install requests\n

      Pre-compiled Packages

      For packages with C/C++/Rust dependencies, use QPython's pre-compiled packages:

      pip install numpy-qpython\npip install scipy-aipy\n

      See QPYPI Guide for the full list of available packages.

      Manual Installation

      You can also copy libraries to /storage/emulated/0/Android/data/org.qpython.qpy/files/lib/python3.12/site-packages/.

      "},{"location":"getting-started/#5-runtime-modes","title":"5. Runtime Modes","text":"

      QPython supports several runtime modes for different use cases:

      "},{"location":"getting-started/#console-mode","title":"Console Mode","text":"

      Default mode for regular Python scripts.

      "},{"location":"getting-started/#sl4a-mode","title":"SL4A Mode","text":"

      Scripts that call Android APIs through the SL4A library.

      import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello Android!')\n

      See QSL4A Documentation for full API reference.

      "},{"location":"getting-started/#webapp-mode","title":"WebApp Mode","text":"

      Create web-based applications with a backend server. Add the following two headers at the beginning of your script:

      #qpy:webapp:<project name>\n#qpy://localhost:<port the web service listens on>/<default main path>\n

      Example:

      #qpy:webapp:Hello QPython\n#qpy://localhost:8080/hello\n\nfrom bottle import route, run, Bottle\n\napp = Bottle()\n\n@route('/hello')\ndef hello():\n    return '<h1>Hello from QPython!</h1>'\n\nrun(app, host='localhost', port=8080)\n

      "},{"location":"getting-started/#q-mode-quiet-mode","title":"Q Mode (Quiet Mode)","text":"

      Run scripts silently without displaying the console. Add header at the beginning of your script:

      #qpy:quiet\n\nimport time\n\nwhile True:\n    # Your background task\n    time.sleep(60)\n
      If you need to run a GUI-based SL4A program and don't want to show console information, this mode is recommended.

      "},{"location":"getting-started/#6-community-and-support","title":"6. Community and Support","text":"

      Visit QPython.org for documentation, user communities, and help.

      Community Links: - Facebook Group - GitHub - Report Issues

      Next Steps: - Try the Hello World Tutorial - Explore QSL4A API for Android integration - Learn about QPython Branches

      "},{"location":"getting-started/#video-introduction","title":"Video Introduction","text":""},{"location":"getting-started/#next-steps","title":"Next Steps","text":"

      If you've got a basic understanding of QPython's features, welcome to start experiencing the fun of programming! Try the Hello World Tutorial to take your first step.

      "},{"location":"qpypi-guide/","title":"QPYPI","text":"

      You can extend your QPython capabilities by installing packages.

      "},{"location":"qpypi-guide/#package-installation-support","title":"Package Installation Support","text":""},{"location":"qpypi-guide/#pure-python-packages","title":"Pure Python Packages","text":"

      QPython supports Python packages developed with pure Python. You can install these packages directly using pip install through QPython's PIP Client or QPYPI on dashboard.

      "},{"location":"qpypi-guide/#pre-compiled-packages","title":"Pre-compiled Packages","text":"

      If some packages (or their dependencies) are developed with Rust/C/C++, QPython cannot support them directly because there is no compiler toolchain support on QPython. However, the QPython team has pre-compiled some commonly used packages and published them in QPython's QPYPI/Extensions for users to install easily.

      "},{"location":"qpypi-guide/#installing-pre-compiled-packages","title":"Installing Pre-compiled Packages","text":"

      You can install pre-compiled packages in the following ways:

      1. Through QPython App: Install directly from QPYPI or Extensions within the QPython app
      2. Through PyPI: Visit https://pypi.org/user/qpythonx/ to view available packages
      3. Via pip command:
      4. pip install xxx-qpython - Packages with the -qpython suffix
      5. pip install xxx-aipy - Packages with the -aipy suffix (typically AI/ML related packages)

      Note: We usually add one of these suffixes based on the package's intended use case.

      "},{"location":"qpypi-guide/#requesting-new-packages","title":"Requesting New Packages","text":"

      If you need a package that is not currently supported:

      • Raise an issue in the qpython.org project
      • The QPython team will consider pre-compiling and adding it to the repository

      For more ways to get help and engage with the community, see the Community & Feedback section.

      Note: Because of different computer architectures, we cannot guarantee that QPYPI includes all packages from PyPI.

      "},{"location":"qpython-x/","title":"QPython Branches","text":"

      QPython is the Python engine for Android. It contains amazing features such as Python interpreter, runtime environment, editor, QPYI and integrated SL4A. It makes it easy for you to use Python on Android. And it's FREE.

      QPython already has millions of users worldwide and it is also an open source project.

      For different usage scenarios, QPython has several branches:

      "},{"location":"qpython-x/#qpython","title":"QPython","text":"

      Standard Edition: Optimized for AI performance and universal app store compatibility

      The main version available on Google Play and other app stores. This version focuses on AI features, making it easier for users to learn and use Python in the AI era.

      Key Features: - AI-powered coding assistance and learning tools - Offline Python 3.12 interpreter: no Internet is required to run Python programs - Supports multiple project types: console, SL4A, webapp - Convenient QR code reader for transferring codes to your phone - QPYPI and custom repository for prebuilt wheel packages - Easy-to-use editor with syntax highlighting - Good documentation and community support

      Permissions: Requires only basic phone permissions for installation.

      Download: Available on Google Play and major app stores.

      "},{"location":"qpython-x/#qpython_1","title":"QPython+","text":"

      Community Edition: Openly supports various community-driven features; available on select app stores.

      The community open-source version (in planning and preparation). This version is designed for contributors who want to participate in QPython project development and supports customization for different manufacturers.

      Key Features: - Community-driven development - Support for vendor customization - More flexible configuration options - Open for contributors to join development

      Permissions: Requires only basic phone permissions for installation.

      Download: Will be available on Google Play and major app stores.

      Note: This version is currently in planning and preparation phase. Stay tuned for updates!

      "},{"location":"qpython-x/#qpython-plus","title":"QPython Plus","text":"

      QPython+ Full Access Edition: Grants complete permissions to call all Android interfaces. Download link available exclusively via the official cloud drive.

      A special version with extended permissions that provides maximum control over the device. This version is NOT published on app stores due to its sensitive permission requirements.

      Key Features: - Full SL4A API access including sensitive features - SMS/Call control APIs - Advanced system integration - Maximum device control capabilities

      Permissions: Requires extensive permissions including: - Bluetooth - Location (GPS) - Read/Send SMS - Call phone - Camera and microphone - System settings - And other sensitive permissions

      Download: Not available on app stores. Distributed through special channels only.

      Important: QPython will not use these permissions in background without your knowledge. If you get exceptions while using SL4A APIs, please check whether the relevant permissions are enabled in system settings.

      "},{"location":"tutorial-hello-world/","title":"Writing \"Hello World\"","text":""},{"location":"tutorial-hello-world/#hello-world","title":"Hello world","text":"

      Well, after you became a bit more familiar with QPython, let's create our first program in QPython. Obviously, it will be helloworld.py. ;)

      Start QPython, open editor and enter the following code:

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello, QPYTHON!')\n

      No wonder, it's just similar to any other hello-world program. When executed, it just shows pop-up message on the screen (see screenshot on the top). Anyway, it's a good example of QPython program.

      "},{"location":"tutorial-hello-world/#code-understanding","title":"Code Understanding","text":"

      It begins with import androidhelper \u2014 the most useful module in QPython, which encapsulates almost all interface with Android available in Python. Any script developed in QPython starts with this statement (at least if it claims to communicate with user). Read more about Python library here and import statement here.

      Next, we create an object droid (actually a class), which is necessary to call RPC functions to communicate with Android.

      The last line of our code calls droid.makeToast(), which shows a small pop-up message (a \"toast\") on the screen.

      Well, let's add some more functionality. Let it ask the user name and greet them.

      "},{"location":"tutorial-hello-world/#more-samples","title":"More samples","text":"

      We can display a simple dialog box with the title, prompt, edit field and buttons Ok and Cancel using dialogGetInput call. Replace the last line of your code and save it as hello1.py:

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\n

      Well, I think it should return any respond, any user reaction. That's why I wrote respond = .... But what does the call actually return? Let's check. Just add print statement after the last line:

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\n

      Then save and run it...

      Oops! Nothing printed? Don't worry. Just pull notification bar and you will see \"QPython Program Output: hello1.py\" \u2014 tap it!

      As you can see, droid.dialogGetInput() returns a JSON object with three fields. We need only one \u2014 result which contains an actual input from user.

      Let's add script's reaction:

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nmessage = f'Hello, {respond.result}!'\ndroid.makeToast(message)\n

      Last two lines (1) format the message and (2) show the message to the user in the toast. See Python docs if you still don't know what f-strings mean.

      Wow! It works! ;)

      Now I'm going to add a bit of logic there. Think: what happen if the user clicks Cancel button, or clicks Ok leaving the input field blank?

      You can play with the program checking what contains respond variable in every case.

      First of all, I want to put text entered by user to a separate variable: name = respond.result. Then I'm going to check it, and if it contains any real text, it will be considered as a name and will be used in greeting. Otherwise another message will be shown. Replace fifth line message = f'Hello, {respond.result}!' with the following code:

      name = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\n

      Use < and > buttons on the toolbar to indent/unindent lines in if-statement (or just use space/backspace keys). You can read more about indentation in Python here; if-statement described here.

      First of all, we put user input to the variable name. Then we check does name contain anything? In case the user left the line blank and clicked Ok, the return value is empty string ''. In case of Cancel button pressed, the return value is None. Both are treated as false in if-statement. So, only if name contains anything meaningful, then-statement is executed and greeting \"Hello, ...!\" shown. In case of empty input the user will see \"Hey! And you're not very polite, %Username%!\" message.

      Ok, here is the whole program:

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nname = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\ndroid.makeToast(message)\n
      "},{"location":"tutorial-hello-world/#execution-result","title":"Execution Result","text":""},{"location":"tutorial-hello-world/#next-steps","title":"Next Steps","text":"

      For Python beginners, we recommend learning from the Python Basic Syntax course to further your Python skills, or browse QPython Featured Courses to find more content you want to learn.

      "},{"location":"whats-new/","title":"What's New","text":""},{"location":"whats-new/#v392-v393","title":"v3.9.2 / v3.9.3","text":"
      • SDK upgrade with support for 16 KB page size, providing a smoother runtime environment
      • Major editor updates for a more fluid editing experience
      • Various other minor improvements
      "},{"location":"whats-new/#v391","title":"v3.9.1","text":"
      • SDK upgrade with support for 16 KB page size, providing a smoother runtime environment
      • Extension packages now support MCP
      • Bug fixes
      "},{"location":"whats-new/#v390","title":"v3.9.0","text":"
      • SDK upgrade to incorporate the latest Android features
      • Built-in Ollama 0.9.5 upgrade: Now supports running Gemma3n models locally in QPython, experiencing more powerful on-device AI computing capabilities
      • Pygame game development support: Combined with XServer, you can now easily write and run Pygame games on QPython, unleashing your creativity!
      • Personalized icon customization: Customize your desktop icons and themes through QPython settings, creating a unique programming environment
      "},{"location":"whats-new/#v3811","title":"v3.8.11","text":"
      • Built-in Ollama 0.9.5 upgrade: Now supports running Gemma3n models locally in QPython, experiencing more powerful on-device AI computing capabilities
      • Pygame game development support: Combined with XServer, you can now easily write and run Pygame games on QPython, unleashing your creativity!
      • Personalized icon customization: Customize your desktop icons and themes through QPython settings, creating a unique programming environment
      "},{"location":"whats-new/#v3810","title":"v3.8.10","text":"
      • Built-in Ollama upgrade: Now you can easily run Qwen3 / Gemma3 models locally in QPython!
      • Powerful MCP library added: Added mcp library in Extensions -> AIPY, allowing you to take powerful MCP functionality with you anywhere, anytime!
      "},{"location":"whats-new/#v389","title":"v3.8.9","text":"

      Major update! AI programming fully integrated into QPython to make your programming easier!

      • Natural language programming support: New support for AIPyApp, enabling natural language programming in QPython. Currently in beta - join our community for usage instructions
      • New QSL4A feature: Added notebookOpen function, supporting natural language control to open Notebook files
      • Built-in editor upgrade: Enhanced editor functionality, supporting opening and browsing various text files
      • Convenient file management: Added internal storage entry in file manager for quick access to your files
      "},{"location":"whats-new/#v388","title":"v3.8.8","text":"
      • Important improvements to file access permission controls, allowing users to flexibly enable or disable access to external storage files through QPython programming
      • SDK upgraded to enhance support and compatibility with newer Android versions
      • Added Anthropic and Google GenAI libraries in Extensions -> AIPY
      "},{"location":"whats-new/#v387","title":"v3.8.7","text":"
      • Based on existing Tkinter support, added sample code for drawing Doraemon using Turtle in Extensions -> Tools
      • Optimized phone permission acquisition process, improving user experience and operational convenience
      • Added Google Gen AI library in Extensions -> AIPY for easy access to Gemini Developer API and Vertex AI
      "},{"location":"whats-new/#v386","title":"v3.8.6","text":"
      • Tkinter support: Now supports Tkinter library, accessible through XServer. Please visit www.qpython.org's drive link \"Extra\" to download required files
      • Storage permission update: To improve user experience, we added permission to read phone storage for accessing Python programs stored in other directories

      After this update, QPython and QPythonPlus (not available on app stores, designed for advanced users with more sensitive permissions) will maintain synchronized version numbers.

      "},{"location":"whats-new/#v352-2025225","title":"v3.5.2 (2025/2/25)","text":"

      Achieve seamless integration with the open source LLM deployment tool Ollama and DeepSeek developed by DeepSeek!

      Features: - Zero threshold to run various large language models locally on mobile devices - Quickly deploy cutting-edge AI models such as DeepSeek - Enjoy a minimalist API calling experience - Build a completely offline intelligent programming environment

      Capabilities: - Load/manage LLM models directly on the mobile phone - Real-time low-latency response based on local computing

      "},{"location":"whats-new/#v350","title":"v3.5.0","text":"
      • Python upgraded to 3.12.8
      • Improved Dashboard for clearer, more user-friendly functionality
      • Added numerous third-party packages: PyTorch / Twisted / Scrapy / FastAPI ...
      "},{"location":"whats-new/#v338","title":"v3.3.8","text":"
      • Fixed NumPy compatibility issues
      "},{"location":"whats-new/#v335","title":"v3.3.5","text":"
      • Upgraded Python kernel to 3.11.9
      • Fixed bug where module installation status was not displayed in extensions
      • Fixed bug where deleting modules in extensions failed
      • Fixed other bugs
      "},{"location":"whats-new/#v334","title":"v3.3.4","text":"
      • Added OpenAI/Langchain/APIGPTCloud AI packages
      • Removed unnecessary files to reduce size
      "},{"location":"whats-new/#v325","title":"v3.2.5","text":"
      • Added some SL4A functions
      • Other bug fixes
      "},{"location":"whats-new/#v323","title":"v3.2.3","text":"
      • Updated Python version to 3.11.0
      • Updated IPython version to 8.6.0
      • Updated pip version to 22.3.1
      • Updated scientific computing packages with automatic soft links
      • Reduced space usage
      • Added some SL4A functions + other bug fixes
      "},{"location":"whats-new/#v318","title":"v3.1.8","text":"
      • Added operation hotkeys in terminal
      • Fixed issue where editor lost content on rotation
      • Fixed other bugs

      Download on Google Play

      "},{"location":"qsl4a/","title":"QSL4A (Scripting Layer for Android) API Documentation","text":"

      QSL4A is QPython's scripting layer for Android, allowing you to control Android device features using Python.

      "},{"location":"qsl4a/#quick-start","title":"Quick Start","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Show a toast message\ndroid.makeToast('Hello QPython!')\n\n# Vibrate the device\ndroid.vibrate(500)\n\n# Get battery level (start monitoring first)\nimport time\ndroid.batteryStartMonitoring()\ntime.sleep(0.5)  # Wait for data\nbattery = droid.readBatteryData().result\nprint(f\"Battery: {battery['level']}%\")\n
      "},{"location":"qsl4a/#documentation-structure","title":"Documentation Structure","text":""},{"location":"qsl4a/#core-modules","title":"Core Modules","text":"
      • Android Base - Core connection and RPC
      • Intent System - Android Intent operations
      • Event System - Event handling and broadcasting
      "},{"location":"qsl4a/#ui-components","title":"UI Components","text":"
      • Dialogs - Alert, input, choice dialogs
      • FullScreen UI - Custom layout UI
      • FloatView - Floating window
      • Accessibility - Screen automation
      "},{"location":"qsl4a/#system","title":"System","text":"
      • Battery - Battery monitoring
      • Sensors - Device sensors
      • Application - App management
      • System Info - Device information
      • Settings - System settings
      • WakeLock - Wake lock control
      • QPython Interface - Script execution
      • Activity Result - Activity result handling
      "},{"location":"qsl4a/#hardware","title":"Hardware","text":"
      • Bluetooth - Bluetooth operations
      • Camera - Photo and video capture
      • Audio/Recorder - Audio recording
      • Webcam - MJPEG streaming
      • USB Serial - USB host serial
      "},{"location":"qsl4a/#connectivity","title":"Connectivity","text":"
      • WiFi - WiFi operations
      • Location - GPS and location
      • SMS - SMS operations
      • Phone - Phone calls and info
      • Contacts - Contact management
      • Signal Strength - Signal monitoring
      • FTP Server - Built-in FTP server
      "},{"location":"qsl4a/#storage","title":"Storage","text":"
      • DocumentFile - File operations
      • Clipboard - Clipboard operations
      • Preferences - Shared preferences
      "},{"location":"qsl4a/#media","title":"Media","text":"
      • Media Player - Audio/Video playback
      • Image Processing - Image operations
      "},{"location":"qsl4a/#special-features","title":"Special Features","text":"
      • Cipher - Encryption/Decryption
      • PGPT AI - AI speech services
      "},{"location":"qsl4a/#result-object","title":"Result Object","text":"

      Most QSL4A methods return a Result namedtuple with: - id - Request ID - result - The actual result data - error - Error message if failed

      result = droid.getClipboard()\nif result.error is None:\n    print(result.result)\nelse:\n    print(f\"Error: {result.error}\")\n
      "},{"location":"qsl4a/connectivity/contacts/","title":"Contacts API","text":"

      Access and manage device contacts.

      "},{"location":"qsl4a/connectivity/contacts/#contact-picking","title":"Contact Picking","text":""},{"location":"qsl4a/connectivity/contacts/#pickcontact","title":"pickContact()","text":"

      Display a list of contacts to pick from.

      pickContact()\n

      Returns: Intent with contact URI

      "},{"location":"qsl4a/connectivity/contacts/#pickphone","title":"pickPhone()","text":"

      Display a list of phone numbers to pick from.

      pickPhone()\n

      Returns: Selected phone number string

      "},{"location":"qsl4a/connectivity/contacts/#contact-queries","title":"Contact Queries","text":""},{"location":"qsl4a/connectivity/contacts/#contactsget","title":"contactsGet()","text":"

      Get all contacts.

      contactsGet(attributes=None)\n

      Parameters: - attributes (list, optional): Specific attributes to retrieve

      Returns: List of contact JSONObject

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetbyid","title":"contactsGetById()","text":"

      Get a contact by ID.

      contactsGetById(id, attributes=None)\n

      Parameters: - id (int): Contact ID - attributes (list, optional): Specific attributes to retrieve

      Returns: JSONObject contact data

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetcount","title":"contactsGetCount()","text":"

      Get the total number of contacts.

      contactsGetCount()\n

      Returns: Integer count

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetids","title":"contactsGetIds()","text":"

      Get all contact IDs.

      contactsGetIds()\n

      Returns: List of contact ID integers

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetattributes","title":"contactsGetAttributes()","text":"

      Get all possible contact attributes.

      contactsGetAttributes()\n

      Returns: List of attribute names

      "},{"location":"qsl4a/connectivity/contacts/#content-queries","title":"Content Queries","text":""},{"location":"qsl4a/connectivity/contacts/#querycontent","title":"queryContent()","text":"

      Query content resolver with custom parameters.

      queryContent(uri, attributes=None, selection=None, selectionArgs=None, order=None)\n

      Parameters: - uri (str): Content URI - attributes (list, optional): Attributes to retrieve - selection (str, optional): WHERE clause - selectionArgs (list, optional): Selection arguments - order (str, optional): ORDER BY clause

      Returns: List of JSONObject results

      "},{"location":"qsl4a/connectivity/contacts/#queryattributes","title":"queryAttributes()","text":"

      Get attributes for a content URI.

      queryAttributes(uri)\n

      Parameters: - uri (str): Content URI

      Returns: JSONArray of attribute names

      "},{"location":"qsl4a/connectivity/contacts/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Pick a contact\ncontact_uri = droid.pickContact().result\nprint(f\"Selected contact: {contact_uri}\")\n\n# Pick a phone number\nphone = droid.pickPhone().result\nprint(f\"Selected phone: {phone}\")\n\n# Get all contacts\ncontacts = droid.contactsGet().result\nprint(f\"Total contacts: {len(contacts)}\")\n\n# Get contact by ID\ncontact = droid.contactsGetById(1).result\nprint(f\"Contact: {contact}\")\n\n# Get contact attributes\nattrs = droid.contactsGetAttributes().result\nprint(f\"Available attributes: {attrs}\")\n
      "},{"location":"qsl4a/connectivity/ftp/","title":"FTP Server API","text":"

      Start and manage a built-in FTP server on the device.

      "},{"location":"qsl4a/connectivity/ftp/#ftp-server-methods","title":"FTP Server Methods","text":""},{"location":"qsl4a/connectivity/ftp/#ftpstart","title":"ftpStart()","text":"

      Start the FTP server.

      ftpStart()\n

      Returns: Array containing IP address and port [ip, port]

      "},{"location":"qsl4a/connectivity/ftp/#ftpstop","title":"ftpStop()","text":"

      Stop the FTP server.

      ftpStop()\n
      "},{"location":"qsl4a/connectivity/ftp/#ftpisrunning","title":"ftpIsRunning()","text":"

      Check if FTP server is running.

      ftpIsRunning()\n

      Returns: True if running

      "},{"location":"qsl4a/connectivity/ftp/#ftpget","title":"ftpGet()","text":"

      Get FTP server IP address.

      ftpGet()\n

      Returns: Array with IP address and port

      "},{"location":"qsl4a/connectivity/ftp/#ftpset","title":"ftpSet()","text":"

      Configure FTP server settings.

      ftpSet(port=None, rootDir=None, username=None, password=None)\n

      Parameters: - port (int, optional): Server port - rootDir (str, optional): Root directory to serve - username (str, optional): Login username - password (str, optional): Login password

      Returns: JSONObject with current settings

      "},{"location":"qsl4a/connectivity/ftp/#ftpstatus","title":"ftpStatus()","text":"

      Get FTP server status.

      ftpStatus()\n

      Returns: String status description

      "},{"location":"qsl4a/connectivity/ftp/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Configure FTP server\ndroid.ftpSet(\n    port=2121,\n    rootDir=\"/sdcard\",\n    username=\"admin\",\n    password=\"secret\"\n)\n\n# Start FTP server\ninfo = droid.ftpStart().result\nprint(f\"FTP running at {info[0]}:{info[1]}\")\n\n# Check status\nif droid.ftpIsRunning().result:\n    print(\"FTP server is running\")\n\n# Get server info\nserver_info = droid.ftpGet().result\nprint(f\"Server: {server_info}\")\n\n# Stop when done\ndroid.ftpStop()\n

      Note: Connect to the FTP server using any FTP client with the provided credentials.

      "},{"location":"qsl4a/connectivity/location/","title":"Location API","text":"

      Access GPS and network location services.

      "},{"location":"qsl4a/connectivity/location/#methods","title":"Methods","text":""},{"location":"qsl4a/connectivity/location/#startlocating","title":"startLocating()","text":"

      Start location updates.

      startLocating(minUpdateTime=60000, minUpdateDistance=30, updateGnssStatus=False)\n

      Parameters: - minUpdateTime (int): Minimum time between updates in milliseconds (default: 60000) - minUpdateDistance (float): Minimum distance for update in meters (default: 30) - updateGnssStatus (bool): Enable GNSS status updates (default: False)

      "},{"location":"qsl4a/connectivity/location/#stoplocating","title":"stopLocating()","text":"

      Stop location updates.

      stopLocating()\n
      "},{"location":"qsl4a/connectivity/location/#readlocation","title":"readLocation()","text":"

      Get last known location.

      readLocation()\n

      Returns: Location data dict

      "},{"location":"qsl4a/connectivity/location/#getlastknownlocation","title":"getLastKnownLocation()","text":"

      Get cached location.

      getLastKnownLocation()\n

      Returns: Location from all providers

      "},{"location":"qsl4a/connectivity/location/#geocode","title":"geocode()","text":"

      Convert address to coordinates.

      geocode(address, maxResults=1)\n
      "},{"location":"qsl4a/connectivity/location/#location-provider-methods","title":"Location Provider Methods)","text":""},{"location":"qsl4a/connectivity/location/#locationproviders","title":"locationProviders()","text":"

      Get available location providers on the phone.

      locationProviders()\n

      Returns: List of available provider names (e.g., ['gps', 'network'])

      "},{"location":"qsl4a/connectivity/location/#locationproviderenabled","title":"locationProviderEnabled()","text":"

      Check if a specific location provider is enabled.

      locationProviderEnabled(provider)\n

      Parameters: - provider (str): Provider name (e.g., 'gps', 'network')

      Returns: True if enabled, False otherwise

      "},{"location":"qsl4a/connectivity/location/#readgnssstatus","title":"readGnssStatus()","text":"

      Read Global Navigation Satellite System status (requires Android 8+).

      readGnssStatus()\n

      Returns: JSONArray containing GNSS satellite information

      "},{"location":"qsl4a/connectivity/location/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start location updates\ndroid.startLocating(minUpdateTime=5000, minUpdateDistance=1, updateGnssStatus=False)\n\n# Wait for fix\ntime.sleep(10)\n\n# Get location\nloc = droid.readLocation().result\nif loc:\n    lat = loc['latitude']\n    lon = loc['longitude']\n    print(f\"Location: {lat}, {lon}\")\n\ndroid.stopLocating()\n
      "},{"location":"qsl4a/connectivity/phone/","title":"Phone API","text":"

      Control phone calls and retrieve phone information.

      "},{"location":"qsl4a/connectivity/phone/#phone-state-tracking","title":"Phone State Tracking","text":""},{"location":"qsl4a/connectivity/phone/#starttrackingphonestate","title":"startTrackingPhoneState()","text":"

      Start tracking phone state changes. Generates 'phone' events.

      startTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/phone/#readphonestate","title":"readPhoneState()","text":"

      Read the current phone state.

      readPhoneState()\n

      Returns: Bundle with phone state and incoming number

      "},{"location":"qsl4a/connectivity/phone/#stoptrackingphonestate","title":"stopTrackingPhoneState()","text":"

      Stop tracking phone state.

      stopTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/phone/#making-calls","title":"Making Calls","text":""},{"location":"qsl4a/connectivity/phone/#phonecall","title":"phoneCall()","text":"

      Call a contact/phone number by URI.

      phoneCall(uri)\n

      Parameters: - uri (str): Contact URI or phone number URI

      "},{"location":"qsl4a/connectivity/phone/#phonecallnumber","title":"phoneCallNumber()","text":"

      Call a phone number directly.

      phoneCallNumber(phone_number)\n

      Parameters: - phone_number (str): Phone number to call

      "},{"location":"qsl4a/connectivity/phone/#phonedial","title":"phoneDial()","text":"

      Dial a number (opens dialer without calling).

      phoneDial(uri)\n

      Parameters: - uri (str): Contact URI or phone number URI

      "},{"location":"qsl4a/connectivity/phone/#phonedialnumber","title":"phoneDialNumber()","text":"

      Dial a phone number (opens dialer without calling).

      phoneDialNumber(phone_number)\n

      Parameters: - phone_number (str): Phone number

      "},{"location":"qsl4a/connectivity/phone/#cell-location","title":"Cell Location","text":""},{"location":"qsl4a/connectivity/phone/#getcelllocation","title":"getCellLocation()","text":"

      Get the current cell location.

      getCellLocation()\n

      Returns: JSONObject with cell location data

      "},{"location":"qsl4a/connectivity/phone/#getallcellslocation","title":"getAllCellsLocation()","text":"

      Get all cell locations (for dual SIM devices).

      getAllCellsLocation()\n

      Returns: JSONArray of cell locations

      "},{"location":"qsl4a/connectivity/phone/#network-information","title":"Network Information","text":""},{"location":"qsl4a/connectivity/phone/#getnetworkoperator","title":"getNetworkOperator()","text":"

      Get the MCC+MNC of the current operator.

      getNetworkOperator()\n

      Returns: String (e.g., '310260')

      "},{"location":"qsl4a/connectivity/phone/#getnetworkoperatorname","title":"getNetworkOperatorName()","text":"

      Get the name of the current operator.

      getNetworkOperatorName()\n

      Returns: String (e.g., 'T-Mobile')

      "},{"location":"qsl4a/connectivity/phone/#getnetworktype","title":"getNetworkType()","text":"

      Get the current network type.

      getNetworkType()\n

      Returns: String describing radio technology (e.g., 'LTE', 'UMTS', 'GSM')

      "},{"location":"qsl4a/connectivity/phone/#getphonetype","title":"getPhoneType()","text":"

      Get the phone type.

      getPhoneType()\n

      Returns: String (e.g., 'GSM', 'CDMA', 'SIP')

      "},{"location":"qsl4a/connectivity/phone/#sim-information","title":"SIM Information","text":""},{"location":"qsl4a/connectivity/phone/#getsimcountryiso","title":"getSimCountryIso()","text":"

      Get the ISO country code for the SIM.

      getSimCountryIso()\n

      Returns: String (e.g., 'us')

      "},{"location":"qsl4a/connectivity/phone/#getsimoperator","title":"getSimOperator()","text":"

      Get the MCC+MNC of the SIM operator.

      getSimOperator()\n

      Returns: String (e.g., '310260')

      "},{"location":"qsl4a/connectivity/phone/#getsimoperatorname","title":"getSimOperatorName()","text":"

      Get the SIM operator name.

      getSimOperatorName()\n

      Returns: String (e.g., 'T-Mobile')

      "},{"location":"qsl4a/connectivity/phone/#getsimserialnumber","title":"getSimSerialNumber()","text":"

      Get the SIM serial number.

      getSimSerialNumber()\n

      Returns: String SIM serial number

      "},{"location":"qsl4a/connectivity/phone/#getsimstate","title":"getSimState()","text":"

      Get the SIM card state.

      getSimState()\n

      Returns: String describing SIM state

      "},{"location":"qsl4a/connectivity/phone/#getsubscriberid","title":"getSubscriberId()","text":"

      Get the subscriber ID.

      getSubscriberId()\n

      Returns: String subscriber ID

      "},{"location":"qsl4a/connectivity/phone/#voice-mail","title":"Voice Mail","text":""},{"location":"qsl4a/connectivity/phone/#getvoicemailalphatag","title":"getVoiceMailAlphaTag()","text":"

      Get the voice mail alpha tag.

      getVoiceMailAlphaTag()\n

      Returns: String voice mail tag

      "},{"location":"qsl4a/connectivity/phone/#getvoicemailnumber","title":"getVoiceMailNumber()","text":"

      Get the voice mail number.

      getVoiceMailNumber()\n

      Returns: String voice mail number

      "},{"location":"qsl4a/connectivity/phone/#device-information","title":"Device Information","text":""},{"location":"qsl4a/connectivity/phone/#getdeviceid","title":"getDeviceId()","text":"

      Get the device ID (IMEI for GSM). Deprecated.

      getDeviceId()\n

      Returns: String device ID

      "},{"location":"qsl4a/connectivity/phone/#getdevicesoftwareversion","title":"getDeviceSoftwareVersion()","text":"

      Get the device software version.

      getDeviceSoftwareVersion()\n

      Returns: String software version

      "},{"location":"qsl4a/connectivity/phone/#getline1number","title":"getLine1Number()","text":"

      Get the line 1 phone number.

      getLine1Number()\n

      Returns: String phone number

      "},{"location":"qsl4a/connectivity/phone/#checknetworkroaming","title":"checkNetworkRoaming()","text":"

      Check if connected to roaming network.

      checkNetworkRoaming()\n

      Returns: True if roaming

      "},{"location":"qsl4a/connectivity/phone/#cell-info","title":"Cell Info","text":""},{"location":"qsl4a/connectivity/phone/#getallcellinfo","title":"getAllCellInfo()","text":"

      Get information about all cells.

      getAllCellInfo()\n

      Returns: List of cell information

      "},{"location":"qsl4a/connectivity/phone/#setdataenabled","title":"setDataEnabled()","text":"

      Enable or disable mobile data.

      setDataEnabled(enabled)\n

      Parameters: - enabled (bool): True to enable, False to disable

      "},{"location":"qsl4a/connectivity/phone/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get network info\noperator = droid.getNetworkOperatorName().result\nprint(f\"Operator: {operator}\")\n\nnetwork_type = droid.getNetworkType().result\nprint(f\"Network: {network_type}\")\n\n# Get SIM info\nsim_state = droid.getSimState().result\nprint(f\"SIM: {sim_state}\")\n\n# Get phone number\nline1 = droid.getLine1Number().result\nprint(f\"Phone: {line1}\")\n\n# Track phone state\ndroid.startTrackingPhoneState()\nprint(\"Tracking phone state...\")\ndroid.stopTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/signalstrength/","title":"Signal Strength API","text":"

      Monitor cellular and wireless signal strength.

      "},{"location":"qsl4a/connectivity/signalstrength/#signal-strength-methods","title":"Signal Strength Methods","text":""},{"location":"qsl4a/connectivity/signalstrength/#starttrackingsignalstrengths","title":"startTrackingSignalStrengths()","text":"

      Start tracking signal strength changes. Generates 'signal_strengths' events.

      startTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/signalstrength/#stoptrackingsignalstrengths","title":"stopTrackingSignalStrengths()","text":"

      Stop tracking signal strengths.

      stopTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/signalstrength/#readsignalstrengths","title":"readSignalStrengths()","text":"

      Read the current signal strengths.

      readSignalStrengths()\n

      Returns: Bundle with signal strength data

      "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthlevel","title":"getTelephoneSignalStrengthLevel()","text":"

      Get the telephone signal strength as a level (0-4).

      getTelephoneSignalStrengthLevel()\n

      Returns: Integer level (0=none, 1=poor, 2=fair, 3=good, 4=excellent)

      "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthdetail","title":"getTelephoneSignalStrengthDetail()","text":"

      Get detailed telephone signal strength information.

      getTelephoneSignalStrengthDetail()\n

      Returns: String with detailed signal info

      "},{"location":"qsl4a/connectivity/signalstrength/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start tracking signal strength\ndroid.startTrackingSignalStrengths()\n\n# Wait for signal updates\ntime.sleep(5)\n\n# Read current signal strength\nsignal = droid.readSignalStrengths().result\nprint(f\"Signal: {signal}\")\n\n# Get level directly\nlevel = droid.getTelephoneSignalStrengthLevel().result\nprint(f\"Signal level: {level}/4\")\n\ndroid.stopTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/sms/","title":"SMS API","text":"

      Send and receive SMS messages.

      "},{"location":"qsl4a/connectivity/sms/#methods","title":"Methods","text":""},{"location":"qsl4a/connectivity/sms/#smssend","title":"smsSend()","text":"

      Send SMS message.

      smsSend(destinationAddress, text)\n

      Parameters: - destinationAddress (str): Phone number - text (str): Message text

      "},{"location":"qsl4a/connectivity/sms/#smsgetmessagecount","title":"smsGetMessageCount()","text":"

      Get message count.

      smsGetMessageCount(unreadOnly=False, folder=\"inbox\")\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessageids","title":"smsGetMessageIds()","text":"

      Get message IDs.

      smsGetMessageIds(unreadOnly=False, folder=\"inbox\")\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessages","title":"smsGetMessages()","text":"

      Get message details.

      smsGetMessages(unreadOnly=False, folder=\"inbox\", attributes=None)\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessagebyid","title":"smsGetMessageById()","text":"

      Get a specific message by ID.

      smsGetMessageById(id, attributes=None)\n

      Parameters: - id (int): Message ID - attributes (list, optional): Specific attributes to retrieve

      Returns: Message data dict

      "},{"location":"qsl4a/connectivity/sms/#smsgetattributes","title":"smsGetAttributes()","text":"

      Get available SMS message attributes.

      smsGetAttributes()\n

      Returns: List of available attribute names

      "},{"location":"qsl4a/connectivity/sms/#smsdeletemessage","title":"smsDeleteMessage()","text":"

      Delete message.

      smsDeleteMessage(id)\n
      "},{"location":"qsl4a/connectivity/sms/#smsmarkmessageread","title":"smsMarkMessageRead()","text":"

      Mark message as read.

      smsMarkMessageRead(ids, read=True)\n
      "},{"location":"qsl4a/connectivity/sms/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Send SMS\ndroid.smsSend(\"+1234567890\", \"Hello from QPython!\")\n\n# Get unread messages\nmessages = droid.smsGetMessages(unreadOnly=True).result\nfor msg in messages:\n    print(f\"From: {msg['address']}, Text: {msg['body']}\")\n
      "},{"location":"qsl4a/connectivity/wifi/","title":"WiFi API","text":"

      Control WiFi adapter and get connection information.

      "},{"location":"qsl4a/connectivity/wifi/#adapter-control","title":"Adapter Control","text":""},{"location":"qsl4a/connectivity/wifi/#checkwifistate","title":"checkWifiState()","text":"

      Check if WiFi is enabled.

      checkWifiState()\n

      Returns: True if WiFi is enabled, False otherwise

      "},{"location":"qsl4a/connectivity/wifi/#togglewifistate","title":"toggleWifiState()","text":"

      Turn WiFi on or off.

      toggleWifiState(enabled=None)\n

      Parameters: - enabled (bool): True to enable, False to disable, None to toggle

      Returns: True if operation succeeded

      "},{"location":"qsl4a/connectivity/wifi/#wifistartscan","title":"wifiStartScan()","text":"

      Start scanning for available WiFi networks.

      wifiStartScan()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifigetscanresults","title":"wifiGetScanResults()","text":"

      Get list of discovered WiFi networks.

      wifiGetScanResults()\n

      Returns: List of access point information

      "},{"location":"qsl4a/connectivity/wifi/#connection-management","title":"Connection Management","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetconnectioninfo","title":"wifiGetConnectionInfo()","text":"

      Get detailed connection information.

      wifiGetConnectionInfo()\n

      Returns: Dict with connection details including SSID, BSSID, IP address

      "},{"location":"qsl4a/connectivity/wifi/#getconnectedinfo","title":"getConnectedInfo()","text":"

      Get connected WiFi network info (simplified).

      getConnectedInfo()\n

      Returns: Dict with SSID, BSSID, signal strength

      "},{"location":"qsl4a/connectivity/wifi/#getdhcpinfo","title":"getDhcpInfo()","text":"

      Get DHCP information for current connection.

      getDhcpInfo(ipConvertToString=True)\n

      Parameters: - ipConvertToString (bool): Convert IP addresses to string format (default: True)

      Returns: Dict with DHCP info including IP, gateway, DNS

      "},{"location":"qsl4a/connectivity/wifi/#wifidisconnect","title":"wifiDisconnect()","text":"

      Disconnect from current WiFi network.

      wifiDisconnect()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifireconnect","title":"wifiReconnect()","text":"

      Reconnect to the current network.

      wifiReconnect()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifireassociate","title":"wifiReassociate()","text":"

      Reassociate with the current access point.

      wifiReassociate()\n
      "},{"location":"qsl4a/connectivity/wifi/#hotspot","title":"Hotspot","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetapstate","title":"wifiGetApState()","text":"

      Get WiFi AP (hotspot) state.

      wifiGetApState()\n

      Returns: Hotspot state

      "},{"location":"qsl4a/connectivity/wifi/#wifi-locks","title":"WiFi Locks","text":""},{"location":"qsl4a/connectivity/wifi/#wifilockacquirefull","title":"wifiLockAcquireFull()","text":"

      Acquire a full WiFi lock (keeps WiFi active even when screen is off).

      wifiLockAcquireFull()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifilockacquirescanonly","title":"wifiLockAcquireScanOnly()","text":"

      Acquire a scan-only WiFi lock.

      wifiLockAcquireScanOnly()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifilockrelease","title":"wifiLockRelease()","text":"

      Release the WiFi lock.

      wifiLockRelease()\n
      "},{"location":"qsl4a/connectivity/wifi/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Check WiFi state\nif droid.checkWifiState().result:\n    print(\"WiFi is enabled\")\nelse:\n    print(\"Enabling WiFi...\")\n    droid.toggleWifiState(True)\n    time.sleep(2)\n\n# Start scanning\ndroid.wifiStartScan()\ntime.sleep(3)\n\n# Get scan results\nnetworks = droid.wifiGetScanResults().result\nfor network in networks:\n    print(f\"SSID: {network.get('SSID')}, Signal: {network.get('level')} dBm\")\n\n# Get connection info\ninfo = droid.wifiGetConnectionInfo().result\nif info:\n    print(f\"Connected to: {info.get('ssid')}\")\n    print(f\"BSSID: {info.get('bssid')}\")\n    print(f\"IP: {info.get('ip_address')}\")\n\n# Get DHCP info\ndhcp = droid.getDhcpInfo().result\nif dhcp:\n    print(f\"Gateway: {dhcp.get('gateway')}\")\n    print(f\"DNS: {dhcp.get('dns1')}\")\n\n# Get simplified connected info\nconnected = droid.getConnectedInfo().result\nprint(f\"SSID: {connected.get('ssid')}, Signal: {connected.get('level')} dBm\")\n\n# Disconnect and reconnect\ndroid.wifiDisconnect()\ntime.sleep(1)\ndroid.wifiReconnect()\n\n# Reassociate with access point\ndroid.wifiReassociate()\n\n# Check hotspot state\nap_state = droid.wifiGetApState().result\nprint(f\"Hotspot state: {ap_state}\")\n\n# Acquire WiFi lock for background operation\ndroid.wifiLockAcquireFull()\n# ... do work ...\ndroid.wifiLockRelease()\n\n# Or use scan-only lock for lighter background operation\ndroid.wifiLockAcquireScanOnly()\n# ... do scanning work ...\ndroid.wifiLockRelease()\n
      "},{"location":"qsl4a/core/android-base/","title":"Android Base Class","text":"

      The Android class is the core of QSL4A, providing the connection to the Android runtime and RPC mechanism.

      "},{"location":"qsl4a/core/android-base/#module-import","title":"Module Import","text":"
      # Full featured (recommended)\nimport androidhelper\ndroid = androidhelper.Android()\n\n# Minimal version (quick, single instance)\nimport android\ndroid = android.droid\n
      "},{"location":"qsl4a/core/android-base/#class-android","title":"Class: Android","text":""},{"location":"qsl4a/core/android-base/#constructor","title":"Constructor","text":"
      Android(addr=None)\n

      Parameters: - addr (tuple, optional): (HOST, PORT) address. If None, uses environment variables AP_HOST and AP_PORT

      Environment Variables: - AP_HOST - Server host address - AP_PORT - Server port - AP_HANDSHAKE - Authentication token

      "},{"location":"qsl4a/core/android-base/#core-methods","title":"Core Methods","text":""},{"location":"qsl4a/core/android-base/#_rpc","title":"_rpc()","text":"

      Internal RPC method for calling Android functions.

      _rpc(method, *args)\n

      Parameters: - method (str): Method name to call - *args: Variable arguments for the method

      Returns: Result namedtuple with fields: - id (int): Request ID - result: Method return value - error (str or None): Error message if failed

      "},{"location":"qsl4a/core/android-base/#getattr","title":"getattr()","text":"

      Dynamic method dispatcher. All Android methods are accessed via attribute lookup.

      # These are equivalent:\ndroid.makeToast(\"Hello\")\ndroid._rpc(\"makeToast\", \"Hello\")\n
      "},{"location":"qsl4a/core/android-base/#standalone-functions-androidpy","title":"Standalone Functions (android.py)","text":"

      When using the minimal android module:

      "},{"location":"qsl4a/core/android-base/#jsla","title":"jsla()","text":"

      Send JSON-RPC request and return raw response.

      jsla(method, *params)\n

      Returns: JSON string response

      "},{"location":"qsl4a/core/android-base/#rsla","title":"rsla()","text":"

      Send request and return result only.

      rsla(method, *params)\n

      Returns: Result value from RPC call

      "},{"location":"qsl4a/core/android-base/#esla","title":"esla()","text":"

      Send request, raise exception on error.

      esla(method, *params)\n

      Raises: Exception if error field is not None

      "},{"location":"qsl4a/core/android-base/#nsla","title":"nsla()","text":"

      Send request and return Result namedtuple.

      nsla(method, *params)\n

      Returns: Result namedtuple

      "},{"location":"qsl4a/core/android-base/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/android-base/#basic-connection","title":"Basic Connection","text":"
      import androidhelper\n\n# Connect to Android runtime\ndroid = androidhelper.Android()\n\n# Check connection by showing toast\ndroid.makeToast(\"Connected!\")\n
      "},{"location":"qsl4a/core/android-base/#error-handling","title":"Error Handling","text":"
      result = droid.someMethod()\nif result.error:\n    print(f\"Error: {result.error}\")\nelse:\n    print(f\"Success: {result.result}\")\n
      "},{"location":"qsl4a/core/android-base/#direct-rpc-call","title":"Direct RPC Call","text":"
      # Call any method directly\nresult = droid._rpc(\"makeToast\", \"Hello World\")\n
      "},{"location":"qsl4a/core/events/","title":"Event System","text":"

      QSL4A provides an event system for handling asynchronous events from Android, such as sensor updates, location changes, and custom broadcasts.

      "},{"location":"qsl4a/core/events/#event-basics","title":"Event Basics","text":"

      Events are stored in a buffer and can be polled or waited for. Each event has: - name: Event type/name - data: Event payload data - time: Timestamp

      "},{"location":"qsl4a/core/events/#event-methods","title":"Event Methods","text":""},{"location":"qsl4a/core/events/#eventclearbuffer","title":"eventClearBuffer()","text":"

      Clear all pending events from the buffer.

      eventClearBuffer()\n

      Returns: None

      "},{"location":"qsl4a/core/events/#eventpoll","title":"eventPoll()","text":"

      Poll for events in the buffer.

      eventPoll(number_of_events=1)\n

      Parameters: - number_of_events (int): Maximum events to retrieve (default: 1)

      Returns: List of event objects

      "},{"location":"qsl4a/core/events/#eventwait","title":"eventWait()","text":"

      Wait for any event.

      eventWait(timeout=None)\n

      Parameters: - timeout (int, optional): Timeout in seconds. None = wait forever

      Returns: Event object or None if timeout

      "},{"location":"qsl4a/core/events/#eventwaitfor","title":"eventWaitFor()","text":"

      Wait for a specific event.

      eventWaitFor(eventName, timeout=None)\n

      Parameters: - eventName (str): Name of event to wait for - timeout (int, optional): Timeout in seconds

      Returns: Event object or None if timeout

      "},{"location":"qsl4a/core/events/#eventpost","title":"eventPost()","text":"

      Post a custom event.

      eventPost(name, data, enqueue=None)\n

      Parameters: - name (str): Event name - data: Event data (any type) - enqueue (bool, optional): Add to queue if True

      "},{"location":"qsl4a/core/events/#receiveevent","title":"receiveEvent()","text":"

      Receive event (blocking).

      receiveEvent()\n

      Returns: Event object

      "},{"location":"qsl4a/core/events/#broadcast-events","title":"Broadcast Events","text":"

      Register for system broadcast events.

      "},{"location":"qsl4a/core/events/#eventregisterforbroadcast","title":"eventRegisterForBroadcast()","text":"

      Register to receive broadcast events.

      eventRegisterForBroadcast(category, enqueue=True)\n

      Parameters: - category (str): Broadcast category/action - enqueue (bool): Add to event queue

      "},{"location":"qsl4a/core/events/#eventunregisterforbroadcast","title":"eventUnregisterForBroadcast()","text":"

      Unregister from broadcast events.

      eventUnregisterForBroadcast(category)\n
      "},{"location":"qsl4a/core/events/#eventgetbrodcastcategories","title":"eventGetBrodcastCategories()","text":"

      Get registered broadcast categories.

      eventGetBrodcastCategories()\n

      Returns: List of registered categories

      "},{"location":"qsl4a/core/events/#event-dispatcher","title":"Event Dispatcher)","text":""},{"location":"qsl4a/core/events/#starteventdispatcher","title":"startEventDispatcher()","text":"

      Opens up a socket where you can read for events posted.)

      startEventDispatcher(port=0)\n

      Parameters: - port (int, optional): Port to listen on (default: 0 = auto-select)

      Returns: Port number being listened on

      "},{"location":"qsl4a/core/events/#stopeventdispatcher","title":"stopEventDispatcher()","text":"

      Stops the event server.)

      stopEventDispatcher()\n
      "},{"location":"qsl4a/core/events/#deprecated-methods","title":"Deprecated Methods","text":""},{"location":"qsl4a/core/events/#rpcpostevent","title":"rpcPostEvent()","text":"

      Post an event to the event queue. (Deprecated, use eventPost)

      rpcPostEvent(name, data)\n

      Parameters: - name (str): Event name - data: Event data

      "},{"location":"qsl4a/core/events/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/events/#basic-event-polling","title":"Basic Event Polling","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Clear old events\ndroid.eventClearBuffer()\n\n# Poll for events\nevents = droid.eventPoll(5).result\nfor event in events:\n    print(f\"Event: {event['name']}, Data: {event['data']}\")\n
      "},{"location":"qsl4a/core/events/#waiting-for-events","title":"Waiting for Events","text":"
      # Wait for any event with timeout\nevent = droid.eventWait(timeout=10).result\nif event:\n    print(f\"Got event: {event['name']}\")\n
      "},{"location":"qsl4a/core/events/#waiting-for-specific-event","title":"Waiting for Specific Event","text":"
      # Wait for sensor event\nevent = droid.eventWaitFor('screen', timeout=5).result\nif event:\n    print(f\"Screen event: {event['data']}\")\n
      "},{"location":"qsl4a/core/events/#posting-custom-events","title":"Posting Custom Events","text":"
      # Post custom event\ndroid.eventPost('my_event', {'key': 'value'})\n\n# Wait for it\nevent = droid.eventWaitFor('my_event', timeout=1).result\n
      "},{"location":"qsl4a/core/events/#broadcast-receiver","title":"Broadcast Receiver","text":"
      # Register for screen on/off events\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_ON')\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_OFF')\n\n# Wait for screen events\nwhile True:\n    event = droid.receiveEvent().result\n    if event['name'] == 'android.intent.action.SCREEN_ON':\n        print(\"Screen turned on\")\n    elif event['name'] == 'android.intent.action.SCREEN_OFF':\n        print(\"Screen turned off\")\n
      "},{"location":"qsl4a/core/events/#sensor-event-handling","title":"Sensor Event Handling","text":"
      # Start sensing\ndroid.startSensingTimed(1, 250)\n\n# Process sensor events\nfor _ in range(100):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'sensors':\n        data = event['data']\n        print(f\"Accel: {data['xforce']}, {data['yforce']}, {data['zforce']}\")\n\ndroid.stopSensing()\n
      "},{"location":"qsl4a/core/events/#common-event-types","title":"Common Event Types","text":"Event Name Description Source sensors Sensor data update startSensing* location GPS location update startLocating phone Phone state change startTrackingPhoneState signal Signal strength change startTrackingSignalStrength screen Screenshot ready fullGetScreenShot dialog Dialog response dialogShow*"},{"location":"qsl4a/core/events/#event-data-structure","title":"Event Data Structure","text":"
      {\n    'name': 'event_name',\n    'data': {\n        # Event-specific data\n    },\n    'time': 1234567890  # Timestamp\n}\n
      "},{"location":"qsl4a/core/intent/","title":"Intent System","text":"

      Android Intents are used to start activities, send broadcasts, and communicate between apps. QSL4A provides full Intent support through the Intent module.

      "},{"location":"qsl4a/core/intent/#module-import","title":"Module Import","text":"
      import androidhelper\ndon = androidhelper.Android()\n
      "},{"location":"qsl4a/core/intent/#intent-constants","title":"Intent Constants","text":"

      Access via droid.Intent:

      "},{"location":"qsl4a/core/intent/#actions","title":"Actions","text":"Constant Value Usage ACTION_MAIN android.intent.action.MAIN App entry point ACTION_VIEW android.intent.action.VIEW View content ACTION_EDIT android.intent.action.EDIT Edit content ACTION_PICK android.intent.action.PICK Pick item ACTION_SEND android.intent.action.SEND Share content ACTION_SEARCH android.intent.action.SEARCH Search"},{"location":"qsl4a/core/intent/#flags","title":"Flags","text":"Constant Value Usage FLAG_ACTIVITY_NEW_TASK 268435456 Start new task FLAG_ACTIVITY_CLEAR_TASK 32768 Clear task stack FLAG_ACTIVITY_NEW_DOCUMENT 524288 New document mode"},{"location":"qsl4a/core/intent/#extras","title":"Extras","text":"Constant Usage EXTRA_TEXT Text content EXTRA_STREAM File URI EXTRA_SUBJECT Subject line EXTRA_EMAIL Email address"},{"location":"qsl4a/core/intent/#core-methods","title":"Core Methods","text":""},{"location":"qsl4a/core/intent/#makeintent","title":"makeIntent()","text":"

      Create an Intent object.

      makeIntent(action, uri=None, type=None, extras=None, categories=None,\n           packagename=None, classname=None, flags=None)\n

      Parameters: - action (str): Intent action (e.g., droid.Intent.ACTION_VIEW) - uri (str, optional): Data URI - type (str, optional): MIME type - extras (dict, optional): Extra data - categories (list, optional): Intent categories - packagename (str, optional): Target package - classname (str, optional): Target class - flags (int, optional): Intent flags

      Returns: Intent object

      "},{"location":"qsl4a/core/intent/#startactivityintent","title":"startActivityIntent()","text":"

      Start an Activity with an Intent.

      startActivityIntent(intent, wait=None)\n

      Parameters: - intent: Intent object from makeIntent() - wait (bool, optional): Block until activity closes

      "},{"location":"qsl4a/core/intent/#startactivityforresultintent","title":"startActivityForResultIntent()","text":"

      Start activity and wait for result.

      startActivityForResultIntent(intent)\n

      Returns: Activity result

      "},{"location":"qsl4a/core/intent/#sendbroadcastintent","title":"sendBroadcastIntent()","text":"

      Send a broadcast.

      sendBroadcastIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#view","title":"view()","text":"

      View content by URI.

      view(uri, type=None, extras=None)\n
      "},{"location":"qsl4a/core/intent/#pick","title":"pick()","text":"

      Pick content from URI.

      pick(uri)\n
      "},{"location":"qsl4a/core/intent/#common-intent-methods","title":"Common Intent Methods)","text":""},{"location":"qsl4a/core/intent/#scanbarcode","title":"scanBarcode()","text":"

      Launch the barcode scanner.

      scanBarcode()\n

      Returns: Scanned barcode string

      "},{"location":"qsl4a/core/intent/#send","title":"send()","text":"

      Send content via share intent.

      send(type, content)\n

      Parameters: - type (str): MIME type - content (str): Content to share

      "},{"location":"qsl4a/core/intent/#sendtext","title":"sendText()","text":"

      Send text content.

      sendText(text)\n

      Parameters: - text (str): Text to send

      "},{"location":"qsl4a/core/intent/#sendemail","title":"sendEmail()","text":"

      Send an email.

      sendEmail(to, subject, body, attachment=None)\n

      Parameters: - to (str or list): Recipient email address(es) - subject (str): Email subject - body (str): Email body - attachment (str, optional): Attachment file path

      "},{"location":"qsl4a/core/intent/#pathtouri","title":"pathToUri()","text":"

      Convert file path to content URI.

      pathToUri(path)\n

      Parameters: - path (str): File path

      Returns: Content URI string

      "},{"location":"qsl4a/core/intent/#openfile","title":"openFile()","text":"

      Open a file with appropriate app.

      openFile(path)\n

      Parameters: - path (str): File path to open

      "},{"location":"qsl4a/core/intent/#sendfile","title":"sendFile()","text":"

      Send a file via share intent.

      sendFile(path)\n

      Parameters: - path (str): File path to send

      "},{"location":"qsl4a/core/intent/#getpathtype","title":"getPathType()","text":"

      Get the MIME type for a file path.

      getPathType(path)\n

      Parameters: - path (str): File path

      Returns: MIME type string

      "},{"location":"qsl4a/core/intent/#viewmap","title":"viewMap()","text":"

      Open map at a location.

      viewMap(latitude, longitude)\n

      Parameters: - latitude (float): Latitude - longitude (float): Longitude

      "},{"location":"qsl4a/core/intent/#viewcontacts","title":"viewContacts()","text":"

      Open the contacts app.

      viewContacts()\n
      "},{"location":"qsl4a/core/intent/#search","title":"search()","text":"

      Perform a web search.

      search(query)\n

      Parameters: - query (str): Search query

      "},{"location":"qsl4a/core/intent/#viewhtml","title":"viewHtml()","text":"

      View HTML content.

      viewHtml(content, encoding=None)\n

      Parameters: - content (str): HTML content - encoding (str, optional): Character encoding

      "},{"location":"qsl4a/core/intent/#webviewshow","title":"webViewShow()","text":"

      Display web content in WebView. Deprecated, use viewHtml.

      webViewShow(url)\n

      Parameters: - url (str): Web page URL

      "},{"location":"qsl4a/core/intent/#editoropen","title":"editorOpen()","text":"

      Open a text editor.

      editorOpen(path=None, create=False)\n

      Parameters: - path (str, optional): File path to edit - create (bool, optional): Create if doesn't exist

      "},{"location":"qsl4a/core/intent/#helper-class-uri","title":"Helper Class: Uri","text":"

      Create URI objects for Intents:

      from androidhelper.Intent import Uri\n\nuri = Uri(\"file:///sdcard/test.txt\")\n
      "},{"location":"qsl4a/core/intent/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/intent/#open-web-page","title":"Open Web Page","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"http://www.example.com\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#share-text","title":"Share Text","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_TEXT: \"Hello from QPython!\",\n        droid.Intent.EXTRA_SUBJECT: \"Test\"\n    },\n    type=\"text/plain\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#open-file","title":"Open File","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"file:///sdcard/document.pdf\",\n    type=\"application/pdf\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#pick-contact","title":"Pick Contact","text":"
      result = droid.pickContact()\ncontact_uri = result.result\n
      "},{"location":"qsl4a/core/intent/#send-email","title":"Send Email","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_EMAIL: [\"test@example.com\"],\n        droid.Intent.EXTRA_SUBJECT: \"Hello\",\n        droid.Intent.EXTRA_TEXT: \"Message body\"\n    },\n    type=\"message/rfc822\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#open-app","title":"Open App","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_MAIN,\n    packagename=\"com.android.settings\",\n    classname=\"com.android.settings.Settings\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/hardware/bluetooth/","title":"Bluetooth API","text":"

      Control Bluetooth adapter and communicate with Bluetooth devices.

      "},{"location":"qsl4a/hardware/bluetooth/#adapter-control","title":"Adapter Control","text":""},{"location":"qsl4a/hardware/bluetooth/#togglebluetoothstate","title":"toggleBluetoothState()","text":"

      Turn Bluetooth on/off.

      toggleBluetoothState(enabled=None, prompt=True)\n

      Parameters: - enabled (bool): True=on, False=off, None=toggle - prompt (bool): Show user prompt

      "},{"location":"qsl4a/hardware/bluetooth/#checkbluetoothstate","title":"checkBluetoothState()","text":"

      Check if Bluetooth is enabled.

      checkBluetoothState()\n

      Returns: True/False

      "},{"location":"qsl4a/hardware/bluetooth/#getlocalname","title":"GetLocalName()","text":"

      Get Bluetooth device name.

      GetLocalName()\n
      "},{"location":"qsl4a/hardware/bluetooth/#setlocalname","title":"SetLocalName()","text":"

      Set Bluetooth device name.

      SetLocalName(name)\n
      "},{"location":"qsl4a/hardware/bluetooth/#getscanmode","title":"GetScanMode()","text":"

      Get discoverability mode.

      GetScanMode()\n

      Returns: - -1: Disabled - 0: Non-discoverable, non-connectable - 1: Connectable, non-discoverable - 3: Connectable and discoverable

      "},{"location":"qsl4a/hardware/bluetooth/#makediscoverable","title":"MakeDiscoverable()","text":"

      Make device discoverable.

      MakeDiscoverable(duration=300)\n

      Parameters: - duration (int): Seconds to be discoverable

      "},{"location":"qsl4a/hardware/bluetooth/#discovery","title":"Discovery","text":""},{"location":"qsl4a/hardware/bluetooth/#discoverystart","title":"DiscoveryStart()","text":"

      Start device discovery.

      DiscoveryStart()\n
      "},{"location":"qsl4a/hardware/bluetooth/#discoverycancel","title":"DiscoveryCancel()","text":"

      Cancel discovery.

      DiscoveryCancel()\n
      "},{"location":"qsl4a/hardware/bluetooth/#getreceiveddevices","title":"GetReceivedDevices()","text":"

      Get discovered devices.

      GetReceivedDevices()\n

      Returns: List of device info dicts

      "},{"location":"qsl4a/hardware/bluetooth/#getbondeddevices","title":"GetBondedDevices()","text":"

      Get paired devices.

      GetBondedDevices()\n

      Returns: List of paired device info

      "},{"location":"qsl4a/hardware/bluetooth/#connection","title":"Connection","text":""},{"location":"qsl4a/hardware/bluetooth/#connect","title":"Connect()","text":"

      Connect to a device.

      Connect(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", address=None)\n

      Parameters: - uuid (str): Service UUID - address (str): Device address (None = show picker)

      Returns: True if successful

      "},{"location":"qsl4a/hardware/bluetooth/#accept","title":"Accept()","text":"

      Accept incoming connection.

      Accept(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", timeout=0)\n
      "},{"location":"qsl4a/hardware/bluetooth/#activeconnections","title":"ActiveConnections()","text":"

      Check active connections.

      ActiveConnections()\n
      "},{"location":"qsl4a/hardware/bluetooth/#stop","title":"Stop()","text":"

      Disconnect.

      Stop(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#communication","title":"Communication","text":""},{"location":"qsl4a/hardware/bluetooth/#write","title":"Write()","text":"

      Send ASCII data.

      Write(ascii, connID=\"\")\n
      "},{"location":"qsl4a/hardware/bluetooth/#writebinary","title":"WriteBinary()","text":"

      Send binary data (base64 encoded).

      WriteBinary(base64, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#read","title":"Read()","text":"

      Read ASCII data.

      Read(bufferSize=4096, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readbinary","title":"ReadBinary()","text":"

      Read binary data.

      ReadBinary(bufferSize=4096, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readline","title":"ReadLine()","text":"

      Read line.

      ReadLine(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readready","title":"ReadReady()","text":"

      Check if data available.

      ReadReady(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Enable Bluetooth\ndroid.toggleBluetoothState(True)\n\n# Get paired devices\ndevices = droid.GetBondedDevices().result\nfor dev in devices:\n    print(f\"{dev['name']}: {dev['address']}\")\n\n# Connect to device\ndroid.Connect(address=\"00:11:22:33:44:55\")\n\n# Send data\ndroid.Write(\"Hello Bluetooth!\")\n\n# Read response\ndata = droid.Read(1024).result\n
      "},{"location":"qsl4a/hardware/camera/","title":"Camera API","text":"

      Capture photos and record video.

      "},{"location":"qsl4a/hardware/camera/#photo-capture","title":"Photo Capture","text":""},{"location":"qsl4a/hardware/camera/#takepicture","title":"takePicture()","text":"

      Take a photo using the default camera.

      takePicture(path=None)\n

      Parameters: - path (str, optional): Save path. If None, returns image data

      Returns: Image path or image data

      "},{"location":"qsl4a/hardware/camera/#cameracapturepicture","title":"cameraCapturePicture()","text":"

      Capture picture with advanced camera controls.

      cameraCapturePicture(targetPath=None, cameraId=0, useAutoFocus=True)\n

      Parameters: - targetPath (str, optional): Save path - cameraId (int): Camera to use (0 = back, 1 = front) - useAutoFocus (bool): Enable auto focus

      Returns: Captured image path

      "},{"location":"qsl4a/hardware/camera/#camerasettorchmode","title":"cameraSetTorchMode()","text":"

      Control camera flashlight/torch.

      cameraSetTorchMode(enabled)\n

      Parameters: - enabled (bool): True to turn on, False to turn off

      Returns: True if successful

      "},{"location":"qsl4a/hardware/camera/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

      Capture screenshot.

      imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

      Parameters: - path (str, optional): Save path - delayMilliSec (int): Delay before capture

      "},{"location":"qsl4a/hardware/camera/#video-recording","title":"Video Recording","text":""},{"location":"qsl4a/hardware/camera/#takevideo","title":"takeVideo()","text":"

      Record video using default settings.

      takeVideo(path=None, quality=1)\n

      Parameters: - path (str, optional): Save path - quality (int): Video quality (0-4) - 0: 160x120 - 1: 320x240 - 2: 352x288 - 3: 640x480 - 4: 800x480

      "},{"location":"qsl4a/hardware/camera/#recordercapturevideo","title":"recorderCaptureVideo()","text":"

      Capture video with advanced controls.

      recorderCaptureVideo(targetPath=None, duration=10, cameraId=0, quality=8)\n

      Parameters: - targetPath (str, optional): Save path - duration (int): Recording duration in seconds (default: 10) - cameraId (int): Camera to use (0 = back, 1 = front) - quality (int): Video quality (0-8, higher is better)

      Returns: Video file path

      "},{"location":"qsl4a/hardware/camera/#recordaudio","title":"recordAudio()","text":"

      Record audio.

      recordAudio()\n

      Returns: Audio file path

      "},{"location":"qsl4a/hardware/camera/#screen-recording","title":"Screen Recording","text":""},{"location":"qsl4a/hardware/camera/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

      Start screen recording.

      recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

      Parameters: - path (str): Save path - audio (int): Audio source (0=none, 1=mic, 2=internal) - targetPixels (int): Resolution - frameRate (int): FPS - bitRate (int): Bitrate - rotation (bool): Rotate output - autoStart (bool): Start immediately

      "},{"location":"qsl4a/hardware/camera/#recorderstart","title":"recorderStart()","text":"

      Start recording.

      recorderStart()\n
      "},{"location":"qsl4a/hardware/camera/#recorderpause","title":"recorderPause()","text":"

      Pause recording.

      recorderPause()\n
      "},{"location":"qsl4a/hardware/camera/#recorderresume","title":"recorderResume()","text":"

      Resume recording.

      recorderResume()\n
      "},{"location":"qsl4a/hardware/camera/#audio-volume-detection","title":"Audio Volume Detection","text":""},{"location":"qsl4a/hardware/camera/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

      Start volume detection.

      recorderSoundVolumeDetect(interval=100)\n
      "},{"location":"qsl4a/hardware/camera/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

      Get current volume in dB.

      recorderSoundVolumeGetDb()\n
      "},{"location":"qsl4a/hardware/camera/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Take photo with default camera\nphoto_path = droid.takePicture(\"/sdcard/photo.jpg\").result\nprint(f\"Photo saved: {photo_path}\")\n\n# Take photo with front camera and auto focus\ncamera_path = droid.cameraCapturePicture(\"/sdcard/selfie.jpg\", cameraId=1, useAutoFocus=True).result\nprint(f\"Front camera photo: {camera_path}\")\n\n# Control flashlight\ndroid.cameraSetTorchMode(True)  # Turn on flashlight\n\n# Record video with default settings\nvideo_path = droid.takeVideo(\"/sdcard/video.mp4\", quality=3).result\nprint(f\"Video saved: {video_path}\")\n\n# Record video with advanced controls\nvideo_path = droid.recorderCaptureVideo(\"/sdcard/movie.mp4\", duration=30, cameraId=0, quality=8).result\n\n# Screenshot\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n
      "},{"location":"qsl4a/hardware/recorder/","title":"Audio Recorder API","text":"

      Record audio from microphone and device screen.

      "},{"location":"qsl4a/hardware/recorder/#audio-recording","title":"Audio Recording","text":""},{"location":"qsl4a/hardware/recorder/#recordaudio","title":"recordAudio()","text":"

      Record audio from microphone.

      recordAudio()\n

      Returns: Path to recorded audio file

      "},{"location":"qsl4a/hardware/recorder/#recorderstartmicrophone","title":"recorderStartMicrophone()","text":"

      Start recording from microphone to a specific file.

      recorderStartMicrophone(targetPath=None)\n

      Parameters: - targetPath (str, optional): Path to save the recording

      "},{"location":"qsl4a/hardware/recorder/#screen-recording","title":"Screen Recording","text":""},{"location":"qsl4a/hardware/recorder/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

      Start screen recording with audio.

      recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

      Parameters: - path (str): Save path for video file - audio (int): Audio source (0=none, 1=mic, 2=internal audio) - targetPixels (int): Target resolution in pixels - frameRate (int): Frames per second (default: 30) - bitRate (int): Video bitrate - rotation (bool): Rotate output video - autoStart (bool): Start recording immediately

      Returns: Result of operation

      "},{"location":"qsl4a/hardware/recorder/#recorderstart","title":"recorderStart()","text":"

      Start the screen recording (when autoStart=False).

      recorderStart()\n
      "},{"location":"qsl4a/hardware/recorder/#recorderpause","title":"recorderPause()","text":"

      Pause ongoing screen recording.

      recorderPause()\n
      "},{"location":"qsl4a/hardware/recorder/#recorderresume","title":"recorderResume()","text":"

      Resume paused screen recording.

      recorderResume()\n
      "},{"location":"qsl4a/hardware/recorder/#audio-volume-detection","title":"Audio Volume Detection","text":""},{"location":"qsl4a/hardware/recorder/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

      Start monitoring sound volume level.

      recorderSoundVolumeDetect(interval=100)\n

      Parameters: - interval (int): Detection interval in milliseconds (default: 100)

      "},{"location":"qsl4a/hardware/recorder/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

      Get current sound volume in decibels.

      recorderSoundVolumeGetDb()\n

      Returns: Current volume level in dB

      "},{"location":"qsl4a/hardware/recorder/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Record audio from microphone\nprint(\"Recording audio...\")\naudio_path = droid.recordAudio().result\nprint(f\"Saved to: {audio_path}\")\n\n# Record microphone to specific file\ndroid.recorderStartMicrophone(\"/sdcard/my_recording.mp3\")\ntime.sleep(5)\ndroid.recorderStop()\n\n# Record screen with audio\nprint(\"Starting screen recording...\")\ndroid.recorderStartScreenRecord(\n    path=\"/sdcard/screen_record.mp4\",\n    audio=1,\n    frameRate=30,\n    autoStart=True\n)\ntime.sleep(10)\ndroid.recorderStop()\n\n# Monitor sound volume\ndroid.recorderSoundVolumeDetect(interval=100)\ntime.sleep(3)\nvolume = droid.recorderSoundVolumeGetDb().result\nprint(f\"Current volume: {volume} dB\")\n
      "},{"location":"qsl4a/hardware/usbserial/","title":"USB Host Serial API","text":"

      Communicate with USB serial devices (requires USB OTG support and Android 3.1+).

      "},{"location":"qsl4a/hardware/usbserial/#usb-serial-methods","title":"USB Serial Methods)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialopen","title":"usbHostSerialOpen()","text":"

      Open a connection to a USB serial device.

      usbHostSerialOpen(device, baudRate=9600)\n

      Parameters: - device (str): USB device path or identifier - baudRate (int): Baud rate (default: 9600)

      Returns: True if opened successfully

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialclose","title":"usbHostSerialClose()","text":"

      Close the USB serial connection.

      usbHostSerialClose()\n
      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialread","title":"usbHostSerialRead()","text":"

      Read data from USB serial.

      usbHostSerialRead(bufferSize=1024)\n

      Parameters: - bufferSize (int): Maximum bytes to read (default: 1024)

      Returns: String read data

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwrite","title":"usbHostSerialWrite()","text":"

      Write data to USB serial.

      usbHostSerialWrite(data)\n

      Parameters: - data (str): String data to write

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialavailable","title":"usbHostSerialAvailable()","text":"

      Check if data is available to read.

      usbHostSerialAvailable()\n

      Returns: Number of bytes available

      "},{"location":"qsl4a/hardware/usbserial/#configuration-methods","title":"Configuration Methods)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetbaudrate","title":"usbHostSerialSetBaudRate()","text":"

      Set the baud rate.

      usbHostSerialSetBaudRate(baudRate)\n

      Parameters: - baudRate (int): Baud rate

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetdatabits","title":"usbHostSerialSetDataBits()","text":"

      Set data bits (5, 6, 7, or 8).

      usbHostSerialSetDataBits(dataBits)\n

      Parameters: - dataBits (int): Data bits (5-8)

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetstopbits","title":"usbHostSerialSetStopBits()","text":"

      Set stop bits (1, 1.5, or 2).

      usbHostSerialSetStopBits(stopBits)\n

      Parameters: - stopBits (float): Stop bits (1, 1.5, or 2)

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetparity","title":"usbHostSerialSetParity()","text":"

      Set parity (none, odd, even, mark, space).

      usbHostSerialSetParity(parity)\n

      Parameters: - parity (str): Parity mode ('none', 'odd', 'even', 'mark', 'space')

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetflowcontrol","title":"usbHostSerialSetFlowControl()","text":"

      Set flow control (none, hardware, software).

      usbHostSerialSetFlowControl(flowControl)\n

      Parameters: - flowControl (str): Flow control mode ('none', 'hardware', 'software')

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialreadhex","title":"usbHostSerialReadHex()","text":"

      Read data as hex string.

      usbHostSerialReadHex(bufferSize=1024)\n

      Parameters: - bufferSize (int): Maximum bytes to read

      Returns: Hex string

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwritehex","title":"usbHostSerialWriteHex()","text":"

      Write data from hex string.

      usbHostSerialWriteHex(hexString)\n

      Parameters: - hexString (str): Hex string to write

      "},{"location":"qsl4a/hardware/usbserial/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Open USB serial connection\nif droid.usbHostSerialOpen(\"/dev/bus/usb/001/001\", 115200).result:\n    print(\"USB serial opened\")\n\n    # Write data\n    droid.usbHostSerialWrite(\"AT\\r\")\n\n    # Read response\n    response = droid.usbHostSerialRead(1024).result\n    print(f\"Response: {response}\")\n\n    # Or use hex\n    droid.usbHostSerialWriteHex(\"41540D0A\")  # \"AT\\r\\n\"\n\n    # Close connection\n    droid.usbHostSerialClose()\n

      Note: USB serial requires: - Android 3.1+ (API 12) - USB OTG cable/adapter - USB host mode support on device - Compatible serial device

      "},{"location":"qsl4a/hardware/webcam/","title":"Webcam API","text":"

      Stream video from the device camera using MJPEG.

      "},{"location":"qsl4a/hardware/webcam/#mjpeg-stream-methods","title":"MJPEG Stream Methods","text":""},{"location":"qsl4a/hardware/webcam/#webcamstart","title":"webcamStart()","text":"

      Start an MJPEG stream from the webcam.

      webcamStart(resolutionLevel=0, jpegQuality=20, port=0)\n

      Parameters: - resolutionLevel (int): Resolution level (default: 0) - jpegQuality (int): JPEG quality 1-100 (default: 20) - port (int): Port number (default: 0 = auto)

      Returns: Tuple of (address, port) for the stream

      "},{"location":"qsl4a/hardware/webcam/#webcamadjustquality","title":"webcamAdjustQuality()","text":"

      Adjust the quality of an active webcam stream.

      webcamAdjustQuality(resolutionLevel=0, jpegQuality=20)\n

      Parameters: - resolutionLevel (int): Resolution level - jpegQuality (int): JPEG quality 1-100

      "},{"location":"qsl4a/hardware/webcam/#webcamstop","title":"webcamStop()","text":"

      Stop the webcam stream.

      webcamStop()\n
      "},{"location":"qsl4a/hardware/webcam/#camera-preview-methods","title":"Camera Preview Methods","text":""},{"location":"qsl4a/hardware/webcam/#camerastartpreview","title":"cameraStartPreview()","text":"

      Start camera preview mode with event generation.

      cameraStartPreview(resolutionLevel=0, jpegQuality=20, filepath=None)\n

      Parameters: - resolutionLevel (int): Resolution level (default: 0) - jpegQuality (int): JPEG quality (default: 20) - filepath (str, optional): File path to save preview frames

      Returns: True if successful

      Note: Generates 'preview' events with frame data.

      "},{"location":"qsl4a/hardware/webcam/#camerastoppreview","title":"cameraStopPreview()","text":"

      Stop the camera preview.

      cameraStopPreview()\n
      "},{"location":"qsl4a/hardware/webcam/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start webcam stream\nstream_info = droid.webcamStart(\n    resolutionLevel=0,\n    jpegQuality=30,\n    port=8080\n).result\nprint(f\"Stream available at {stream_info[0]}:{stream_info[1]}\")\n\n# Adjust quality while streaming\ntime.sleep(5)\ndroid.webcamAdjustQuality(resolutionLevel=1, jpegQuality=50)\n\n# Stop when done\ndroid.webcamStop()\n\n# Or use preview mode\nprint(\"Starting preview...\")\ndroid.cameraStartPreview()\n\n# Wait for preview events\nfor i in range(10):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'preview':\n        print(f\"Got preview frame: {event['data']}\")\n\ndroid.cameraStopPreview()\n
      "},{"location":"qsl4a/media/image/","title":"Image Processing API","text":"

      Compress and process images.

      "},{"location":"qsl4a/media/image/#image-compression","title":"Image Compression","text":""},{"location":"qsl4a/media/image/#imagecompress","title":"imageCompress()","text":"

      Compress image file.

      imageCompress(srcPath, destPath, targetByteSize=0, targetWidth=0, targetHeight=0)\n

      Parameters: - srcPath (str): Source image path - destPath (str): Output path - targetByteSize (int): Target file size in bytes (0 = no limit) - targetWidth (int): Target width (0 = original) - targetHeight (int): Target height (0 = original)

      Returns: Compressed image path

      "},{"location":"qsl4a/media/image/#screenshot","title":"Screenshot","text":""},{"location":"qsl4a/media/image/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

      Capture screen.

      imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

      Parameters: - path (str): Save path - delayMilliSec (int): Delay before capture

      Returns: Screenshot path

      "},{"location":"qsl4a/media/image/#video-playback","title":"Video Playback","text":""},{"location":"qsl4a/media/image/#videoplay","title":"videoPlay()","text":"

      Play video file in fullscreen mode.

      videoPlay(path, wait=True)\n

      Parameters: - path (str): Video file path - wait (bool): Wait for playback to complete (default: True)

      "},{"location":"qsl4a/media/image/#barcode-scanning","title":"Barcode Scanning","text":""},{"location":"qsl4a/media/image/#scanbarcodefromimage","title":"scanBarcodeFromImage()","text":"

      Scan barcode/QR code from image file.

      scanBarcodeFromImage(path, compressRatio=0, x=0, y=0, width=0, height=0)\n

      Parameters: - path (str): Image file path - compressRatio (int): Compression ratio (0 = no compression) - x, y, width, height (int): Region to scan (0 = full image)

      Returns: Scanned barcode content

      "},{"location":"qsl4a/media/image/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Take screenshot\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n\n# Compress image\ncompressed = droid.imageCompress(\n    \"/sdcard/large_photo.jpg\",\n    \"/sdcard/compressed.jpg\",\n    targetByteSize=102400,  # Target ~100KB\n    targetWidth=1920,\n    targetHeight=1080\n).result\nprint(f\"Saved: {compressed}\")\n\n# Play video\nvideo_path = \"/sdcard/movie.mp4\"\ndroid.videoPlay(video_path, wait=True)\n\n# Scan barcode from image\nresult = droid.scanBarcodeFromImage(\"/sdcard/qr_code.png\").result\nprint(f\"Barcode: {result}\")\n
      "},{"location":"qsl4a/media/mediaplayer/","title":"Media Player API","text":"

      Control audio and video playback.

      "},{"location":"qsl4a/media/mediaplayer/#playback-control","title":"Playback Control","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplay","title":"mediaPlay()","text":"

      Play media file.

      mediaPlay(url, tag=\"default\", play=True)\n

      Parameters: - url (str): Media file path or URL - tag (str): Player identifier - play (bool): Auto-start playback

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaystart","title":"mediaPlayStart()","text":"

      Start playback.

      mediaPlayStart(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplaypause","title":"mediaPlayPause()","text":"

      Pause playback.

      mediaPlayPause(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplayclose","title":"mediaPlayClose()","text":"

      Close player.

      mediaPlayClose(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplayseek","title":"mediaPlaySeek()","text":"

      Seek to position.

      mediaPlaySeek(msec, tag=\"default\")\n

      Parameters: - msec (int): Position in milliseconds

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaysetlooping","title":"mediaPlaySetLooping()","text":"

      Set loop mode.

      mediaPlaySetLooping(enabled, tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#player-info","title":"Player Info","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplayinfo","title":"mediaPlayInfo()","text":"

      Get playback info.

      mediaPlayInfo(tag=\"default\")\n

      Returns: Dict with duration, position, etc.

      "},{"location":"qsl4a/media/mediaplayer/#mediaisplaying","title":"mediaIsPlaying()","text":"

      Check if playing.

      mediaIsPlaying(tag=\"default\")\n

      Returns: True/False

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaylist","title":"mediaPlayList()","text":"

      List active players.

      mediaPlayList()\n
      "},{"location":"qsl4a/media/mediaplayer/#volume-control","title":"Volume Control","text":""},{"location":"qsl4a/media/mediaplayer/#getmediavolume","title":"getMediaVolume()","text":"

      Get media volume.

      getMediaVolume()\n

      Returns: Volume level (0-15)

      "},{"location":"qsl4a/media/mediaplayer/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

      Get max media volume.

      getMaxMediaVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#getringervolume","title":"getRingerVolume()","text":"

      Get ringer volume.

      getRingerVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

      Get max ringer volume.

      getMaxRingerVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#video-playback","title":"Video Playback","text":""},{"location":"qsl4a/media/mediaplayer/#videoplay","title":"videoPlay()","text":"

      Play video fullscreen.

      videoPlay(path, wait=True)\n

      Parameters: - path (str): Video file path - wait (bool): Wait for playback to complete

      "},{"location":"qsl4a/media/mediaplayer/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Play audio\ndroid.mediaPlay(\"/sdcard/music.mp3\", tag=\"music\")\n\n# Check status\nif droid.mediaIsPlaying(\"music\").result:\n    info = droid.mediaPlayInfo(\"music\").result\n    print(f\"Playing: {info}\")\n\n# Seek to 30 seconds\ndroid.mediaPlaySeek(30000, \"music\")\n\n# Close\ndroid.mediaPlayClose(\"music\")\n\n# Play video\ndroid.videoPlay(\"/sdcard/movie.mp4\", wait=True)\n
      "},{"location":"qsl4a/special/cipher/","title":"Cipher API","text":"

      Encryption and decryption utilities for secure data storage.

      "},{"location":"qsl4a/special/cipher/#initialization","title":"Initialization","text":""},{"location":"qsl4a/special/cipher/#cipherinit","title":"cipherInit()","text":"

      Initialize the cipher with encryption key and algorithm.

      cipherInit(key, algorithm=\"AES/CBC/PKCS5Padding\", encodingFormat=\"\", initialVector=\"\")\n

      Parameters: - key (str or bytes): Encryption key - algorithm (str): Cipher algorithm (default: \"AES/CBC/PKCS5Padding\") - encodingFormat (str): Encoding format - initialVector (str or bytes): Initial vector for encryption

      Returns: Initialization result

      Note: Must be called before any encrypt/decrypt operations.

      "},{"location":"qsl4a/special/cipher/#encryption-methods","title":"Encryption Methods","text":""},{"location":"qsl4a/special/cipher/#encryptstring","title":"encryptString()","text":"

      Encrypt a string.

      encryptString(plainText)\n

      Parameters: - plainText (str): Text to encrypt

      Returns: Encrypted string

      "},{"location":"qsl4a/special/cipher/#encryptbytes","title":"encryptBytes()","text":"

      Encrypt bytes data.

      encryptBytes(data)\n

      Parameters: - data (bytes): Data to encrypt

      Returns: Encrypted bytes

      "},{"location":"qsl4a/special/cipher/#encryptstringtofile","title":"encryptStringToFile()","text":"

      Encrypt string to file.

      encryptStringToFile(plainText, filePath)\n

      Parameters: - plainText (str): Text to encrypt - filePath (str): Output file path

      "},{"location":"qsl4a/special/cipher/#encryptbytestofile","title":"encryptBytesToFile()","text":"

      Encrypt bytes to file.

      encryptBytesToFile(data, filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryption-methods","title":"Decryption Methods","text":""},{"location":"qsl4a/special/cipher/#decryptstring","title":"decryptString()","text":"

      Decrypt to string.

      decryptString(cipherText)\n

      Parameters: - cipherText (str): Encrypted text

      Returns: Decrypted string

      "},{"location":"qsl4a/special/cipher/#decryptbytes","title":"decryptBytes()","text":"

      Decrypt to bytes.

      decryptBytes(data)\n

      Returns: Decrypted bytes

      "},{"location":"qsl4a/special/cipher/#decryptfiletostring","title":"decryptFileToString()","text":"

      Decrypt file to string.

      decryptFileToString(filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryptfiletobytes","title":"decryptFileToBytes()","text":"

      Decrypt file to bytes.

      decryptFileToBytes(filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryptfile","title":"decryptFile()","text":"

      Decrypt file to file.

      decryptFile(srcPath, destPath)\n
      "},{"location":"qsl4a/special/cipher/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Initialize cipher with your encryption key\ndroid.cipherInit(\"my_secret_key_1234\")\n\n# Encrypt string\nencrypted = droid.encryptString(\"Secret message!\").result\nprint(f\"Encrypted: {encrypted}\")\n\n# Decrypt string\ndecrypted = droid.decryptString(encrypted).result\nprint(f\"Decrypted: {decrypted}\")\n\n# Encrypt to file\ndroid.encryptStringToFile(\"My secret data\", \"/sdcard/secret.dat\")\n\n# Decrypt from file\ndata = droid.decryptFileToString(\"/sdcard/secret.dat\").result\nprint(data)\n\n# Initialize with custom algorithm and IV\ndroid.cipherInit(\n    key=\"my_key\",\n    algorithm=\"AES/CBC/PKCS5Padding\",\n    initialVector=\"0123456789abcdef\"\n)\n
      "},{"location":"qsl4a/special/pgptai/","title":"PGPT AI API","text":"

      Speech-to-text and AI services integration.

      "},{"location":"qsl4a/special/pgptai/#prerequisites","title":"Prerequisites","text":"
      pip install pgptAI\n
      "},{"location":"qsl4a/special/pgptai/#speech-recognition","title":"Speech Recognition","text":""},{"location":"qsl4a/special/pgptai/#speechtotext","title":"speechToText()","text":"

      Convert speech to text.

      speechToText(RecordSecond=10, AmrFile=None, Language=None)\n

      Parameters: - RecordSecond (int): Recording duration in seconds - AmrFile (str, optional): Existing audio file path - Language (str, optional): Language code ('en', 'zh')

      Returns: Transcribed text

      "},{"location":"qsl4a/special/pgptai/#text-to-speech","title":"Text to Speech","text":""},{"location":"qsl4a/special/pgptai/#texttospeech","title":"textToSpeech()","text":"

      Convert text to speech and optionally play it.

      textToSpeech(Text, AutoPlay=True, WavFile=None, VoiceName=None)\n

      Parameters: - Text (str): Text to convert to speech - AutoPlay (bool): Automatically play the generated audio (default: True) - WavFile (str, optional): Path to save the WAV file. If None, uses temporary file - VoiceName (str, optional): Voice name to use (e.g., 'en-US-JennyNeural', 'zh-CN-XiaoxiaoNeural')

      Returns: Dict with speech synthesis result including: - text: The input text - url: URL to download the audio file - WavFile: Path to the saved WAV file (if saved locally)

      "},{"location":"qsl4a/special/pgptai/#configuration","title":"Configuration","text":"

      The API uses configuration from /storage/emulated/0/Android/data/org.qpython.qpy/files/apigpt.conf:

      [speech]\nspeech_key = your_api_key\n

      Default voice settings: - English: en-US-JennyNeural - Chinese: zh-CN-XiaoxiaoNeural

      "},{"location":"qsl4a/special/pgptai/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Record and transcribe\nprint(\"Recording for 5 seconds...\")\ntext = droid.speechToText(RecordSecond=5, Language='en').result\nprint(f\"You said: {text}\")\n\n# Transcribe existing file\ntext = droid.speechToText(AmrFile=\"/sdcard/recording.amr\").result\nprint(f\"Transcription: {text}\")\n\n# Text to speech\ndroid.textToSpeech(\"Hello, this is a test message.\", AutoPlay=True, Language='en')\n\n# Text to speech with custom voice and save to file\nresult = droid.textToSpeech(\n    \"Welcome to QPython!\",\n    AutoPlay=False,\n    WavFile=\"/sdcard/welcome.wav\",\n    VoiceName=\"en-US-JennyNeural\"\n).result\nprint(f\"Audio saved to: {result.get('WavFile')}\")\n
      "},{"location":"qsl4a/special/pgptai/#class-usage","title":"Class Usage","text":"
      from androidhelper.pgptai import pgptai\nimport androidhelper\n\ndroid = androidhelper.Android()\nai = pgptai(droid)\n\n# Use speech recognition\ntext = ai.speechToText(RecordSecond=10)\n
      "},{"location":"qsl4a/storage/clipboard/","title":"Clipboard API","text":"

      Copy and paste text to system clipboard.

      "},{"location":"qsl4a/storage/clipboard/#methods","title":"Methods","text":""},{"location":"qsl4a/storage/clipboard/#setclipboard","title":"setClipboard()","text":"

      Copy text to clipboard.

      setClipboard(text)\n

      Parameters: - text (str): Text to copy

      Returns: True if success

      "},{"location":"qsl4a/storage/clipboard/#getclipboard","title":"getClipboard()","text":"

      Get text from clipboard.

      getClipboard()\n

      Returns: Clipboard text

      "},{"location":"qsl4a/storage/clipboard/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Copy to clipboard\ndroid.setClipboard(\"Hello from QPython!\")\n\n# Paste from clipboard\ntext = droid.getClipboard().result\nprint(f\"Clipboard: {text}\")\n
      "},{"location":"qsl4a/storage/documentfile/","title":"DocumentFile API","text":"

      File operations with SAF (Storage Access Framework) support for Android 4.4+.

      "},{"location":"qsl4a/storage/documentfile/#directory-operations","title":"Directory Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfilemkdir","title":"documentFileMkdir()","text":"

      Create directory.

      documentFileMkdir(Dir)\n

      Parameters: - Dir (str): Directory path

      Returns: True if success

      "},{"location":"qsl4a/storage/documentfile/#documentfilelistfiles","title":"documentFileListFiles()","text":"

      List files in directory.

      documentFileListFiles(Folder)\n

      Returns: List of files

      "},{"location":"qsl4a/storage/documentfile/#file-operations","title":"File Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfileexists","title":"documentFileExists()","text":"

      Check if file or directory exists.

      documentFileExists(path)\n

      Parameters: - path (str): File or directory path

      Returns: True if exists, False otherwise

      "},{"location":"qsl4a/storage/documentfile/#documentfileisfile","title":"documentFileIsFile()","text":"

      Check if path is a file.

      documentFileIsFile(path)\n

      Parameters: - path (str): Path to check

      Returns: True if file, False if not a file, None if not exists

      "},{"location":"qsl4a/storage/documentfile/#documentfileisdirectory","title":"documentFileIsDirectory()","text":"

      Check if path is a directory.

      documentFileIsDirectory(path)\n

      Parameters: - path (str): Path to check

      Returns: True if directory, False if not a directory, None if not exists

      "},{"location":"qsl4a/storage/documentfile/#documentfiledelete","title":"documentFileDelete()","text":"

      Delete file or directory.

      documentFileDelete(FileOrTree)\n

      Returns: True if success

      "},{"location":"qsl4a/storage/documentfile/#documentfilerenameto","title":"documentFileRenameTo()","text":"

      Rename or move file.

      documentFileRenameTo(Src, Dest)\n

      Returns: True if success

      "},{"location":"qsl4a/storage/documentfile/#documentfilecopy","title":"documentFileCopy()","text":"

      Copy file.

      documentFileCopy(SrcFileOrTree, DestFileOrTree)\n
      "},{"location":"qsl4a/storage/documentfile/#stream-operations","title":"Stream Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfileinputstream","title":"documentFileInputStream()","text":"

      Read file content.

      documentFileInputStream(srcFile, EncodingFormat=\"\", skip=None, length=None)\n

      Parameters: - srcFile (str): Source file - EncodingFormat (str): \"UTF-8\", \"GBK\", \"Base64\", or \"\" for bytes - skip (int): Skip bytes from start - length (int): Read length

      Returns: File content

      "},{"location":"qsl4a/storage/documentfile/#documentfileoutputstream","title":"documentFileOutputStream()","text":"

      Write file content.

      documentFileOutputStream(destFile, src, EncodingFormat=\"\", append=None)\n

      Parameters: - destFile (str): Destination file - src: Data to write - EncodingFormat (str): Encoding format - append (bool): Append mode

      "},{"location":"qsl4a/storage/documentfile/#file-information","title":"File Information","text":""},{"location":"qsl4a/storage/documentfile/#documentfilelength","title":"documentFileLength()","text":"

      Get file size in bytes.

      documentFileLength(path)\n

      Parameters: - path (str): File path

      Returns: File size in bytes (0 if not exists)

      "},{"location":"qsl4a/storage/documentfile/#documentfilelastmodified","title":"documentFileLastModified()","text":"

      Get last modified time.

      documentFileLastModified(path)\n

      Parameters: - path (str): File path

      Returns: Timestamp (0 if not exists)

      "},{"location":"qsl4a/storage/documentfile/#documentfilegetstat","title":"documentFileGetStat()","text":"

      Get comprehensive file statistics.

      documentFileGetStat(path)\n

      Parameters: - path (str): File path

      Returns: Dict with length, last modified, and read/write permissions, or None if not exists

      "},{"location":"qsl4a/storage/documentfile/#uri-operations","title":"URI Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfilegeturi","title":"documentFileGetUri()","text":"

      Get URI from path.

      documentFileGetUri(path, isDirectory=None)\n
      "},{"location":"qsl4a/storage/documentfile/#documentfileshowopen","title":"documentFileShowOpen()","text":"

      Show file picker.

      documentFileShowOpen()\n

      Returns: Selected file URI

      "},{"location":"qsl4a/storage/documentfile/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Create directory\ndroid.documentFileMkdir(\"/sdcard/MyFolder\")\n\n# List files\nfiles = droid.documentFileListFiles(\"/sdcard\").result\nfor f in files:\n    print(f)\n\n# Read file\ncontent = droid.documentFileInputStream(\n    \"/sdcard/test.txt\",\n    EncodingFormat=\"UTF-8\"\n).result\nprint(content)\n\n# Write file\ndroid.documentFileOutputStream(\n    \"/sdcard/output.txt\",\n    \"Hello World\",\n    EncodingFormat=\"UTF-8\"\n)\n
      "},{"location":"qsl4a/storage/preferences/","title":"Preferences API","text":"

      Store and retrieve data using Android SharedPreferences.

      "},{"location":"qsl4a/storage/preferences/#preference-methods","title":"Preference Methods","text":""},{"location":"qsl4a/storage/preferences/#prefgetvalue","title":"prefGetValue()","text":"

      Read a value from shared preferences.

      prefGetValue(key, filename=None)\n

      Parameters: - key (str): Preference key - filename (str, optional): Preference file name

      Returns: The stored value (any type)

      "},{"location":"qsl4a/storage/preferences/#prefputvalue","title":"prefPutValue()","text":"

      Write a value to shared preferences.

      prefPutValue(key, value, filename=None)\n

      Parameters: - key (str): Preference key - value (object): Value to store - filename (str, optional): Preference file name

      "},{"location":"qsl4a/storage/preferences/#prefgetall","title":"prefGetAll()","text":"

      Get all preference values.

      prefGetAll(filename=None)\n

      Parameters: - filename (str, optional): Preference file name

      Returns: Map of all preferences

      "},{"location":"qsl4a/storage/preferences/#prefremovevalue","title":"prefRemoveValue()","text":"

      Remove a value from shared preferences.

      prefRemoveValue(key, filename=None)\n

      Parameters: - key (str): Preference key to remove - filename (str, optional): Preference file name

      "},{"location":"qsl4a/storage/preferences/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Store values\ndroid.prefPutValue(\"username\", \"alice\")\ndroid.prefPutValue(\"score\", 100)\ndroid.prefPutValue(\"enabled\", True)\n\n# Read a specific value\nusername = droid.prefGetValue(\"username\").result\nprint(f\"Username: {username}\")\n\n# Get all preferences\nall_prefs = droid.prefGetAll().result\nprint(f\"All prefs: {all_prefs}\")\n\n# Remove a value\ndroid.prefRemoveValue(\"score\")\n\n# Use custom filename\ndroid.prefPutValue(\"token\", \"abc123\", filename=\"auth.prefs\")\ntoken = droid.prefGetValue(\"token\", filename=\"auth.prefs\").result\n
      "},{"location":"qsl4a/system/activityresult/","title":"Activity Result API","text":"

      Set activity results for scripts launched via startActivityForResult.

      "},{"location":"qsl4a/system/activityresult/#result-methods","title":"Result Methods","text":""},{"location":"qsl4a/system/activityresult/#setresultboolean","title":"setResultBoolean()","text":"

      Set a boolean result.

      setResultBoolean(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (bool): Boolean result value

      "},{"location":"qsl4a/system/activityresult/#setresultbyte","title":"setResultByte()","text":"

      Set a byte result.

      setResultByte(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (int): Byte result value

      "},{"location":"qsl4a/system/activityresult/#setresultshort","title":"setResultShort()","text":"

      Set a short result.

      setResultShort(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (int): Short result value

      "},{"location":"qsl4a/system/activityresult/#setresultchar","title":"setResultChar()","text":"

      Set a character result.

      setResultChar(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (str): Character result value

      "},{"location":"qsl4a/system/activityresult/#setresultinteger","title":"setResultInteger()","text":"

      Set an integer result.

      setResultInteger(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (int): Integer result value

      "},{"location":"qsl4a/system/activityresult/#setresultlong","title":"setResultLong()","text":"

      Set a long result.

      setResultLong(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (int): Long result value

      "},{"location":"qsl4a/system/activityresult/#setresultfloat","title":"setResultFloat()","text":"

      Set a float result.

      setResultFloat(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (float): Float result value

      "},{"location":"qsl4a/system/activityresult/#setresultdouble","title":"setResultDouble()","text":"

      Set a double result.

      setResultDouble(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (float): Double result value

      "},{"location":"qsl4a/system/activityresult/#setresultstring","title":"setResultString()","text":"

      Set a string result.

      setResultString(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (str): String result value

      "},{"location":"qsl4a/system/activityresult/#setresultbooleanarray","title":"setResultBooleanArray()","text":"

      Set a boolean array result.

      setResultBooleanArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Boolean array

      "},{"location":"qsl4a/system/activityresult/#setresultbytearray","title":"setResultByteArray()","text":"

      Set a byte array result.

      setResultByteArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Byte array

      "},{"location":"qsl4a/system/activityresult/#setresultshortarray","title":"setResultShortArray()","text":"

      Set a short array result.

      setResultShortArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Short array

      "},{"location":"qsl4a/system/activityresult/#setresultchararray","title":"setResultCharArray()","text":"

      Set a character array result.

      setResultCharArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Char array

      "},{"location":"qsl4a/system/activityresult/#setresultintegerarray","title":"setResultIntegerArray()","text":"

      Set an integer array result.

      setResultIntegerArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Integer array

      "},{"location":"qsl4a/system/activityresult/#setresultlongarray","title":"setResultLongArray()","text":"

      Set a long array result.

      setResultLongArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Long array

      "},{"location":"qsl4a/system/activityresult/#setresultfloatarray","title":"setResultFloatArray()","text":"

      Set a float array result.

      setResultFloatArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Float array

      "},{"location":"qsl4a/system/activityresult/#setresultdoublearray","title":"setResultDoubleArray()","text":"

      Set a double array result.

      setResultDoubleArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Double array

      "},{"location":"qsl4a/system/activityresult/#setresultstringarray","title":"setResultStringArray()","text":"

      Set a string array result.

      setResultStringArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): String array

      "},{"location":"qsl4a/system/activityresult/#setresultserializable","title":"setResultSerializable()","text":"

      Set a serializable result.

      setResultSerializable(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue: Serializable result value

      "},{"location":"qsl4a/system/activityresult/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# After performing an activity, set the result\n# Example: Return success with data\ndroid.setResultInteger(0, 200)  # RESULT_OK\ndroid.setResultString(0, \"Operation completed successfully\")\n\n# Return an array result\ndroid.setResultIntegerArray(0, [1, 2, 3, 4, 5])\n
      "},{"location":"qsl4a/system/application/","title":"Application Management","text":"

      Manage applications, launch apps, and query system information.

      "},{"location":"qsl4a/system/application/#application-information","title":"Application Information","text":""},{"location":"qsl4a/system/application/#getapplicationinfo","title":"getApplicationInfo()","text":"

      Get information about an app.

      getApplicationInfo(packageName=None)\n

      Parameters: - packageName (str): Package name (None = current app)

      Returns: App info dict

      "},{"location":"qsl4a/system/application/#getinstalledpackages","title":"getInstalledPackages()","text":"

      Get list of installed packages.

      getInstalledPackages(flag=4)\n

      Parameters: - flag (int): Package flag filter (default: 4)

      Returns: List of installed packages

      "},{"location":"qsl4a/system/application/#getrunningpackages","title":"getRunningPackages()","text":"

      List running packages.

      getRunningPackages()\n

      Returns: List of package names

      "},{"location":"qsl4a/system/application/#getlaunchablepackages","title":"getLaunchablePackages()","text":"

      Get list of launchable packages.

      getLaunchablePackages(needClassName=False)\n

      Parameters: - needClassName (bool): Include main activity class name (default: False)

      Returns: List of launchable package names or dict with class names

      "},{"location":"qsl4a/system/application/#application-control","title":"Application Control","text":""},{"location":"qsl4a/system/application/#launch","title":"launch()","text":"

      Launch an application.

      launch(classname=None, packagename=None, wait=True)\n

      Parameters: - classname (str): Main activity class name - packagename (str): Package name - wait (bool): Wait for launch to complete (default: True)

      Returns: Launch result

      "},{"location":"qsl4a/system/application/#forcestoppackage","title":"forceStopPackage()","text":"

      Force stop an application.

      forceStopPackage(packageName)\n

      Parameters: - packageName (str): Package name to stop

      "},{"location":"qsl4a/system/application/#version-information","title":"Version Information","text":""},{"location":"qsl4a/system/application/#getpackageversion","title":"getPackageVersion()","text":"

      Get app version name.

      getPackageVersion(packageName)\n

      Returns: Version string (e.g., \"3.2.1\")

      "},{"location":"qsl4a/system/application/#getpackageversioncode","title":"getPackageVersionCode()","text":"

      Get app version code.

      getPackageVersionCode(packageName)\n

      Returns: Version code integer

      "},{"location":"qsl4a/system/application/#getconstants","title":"getConstants()","text":"

      Get class constants.

      getConstants(classname)\n

      Parameters: - classname (str): Full class name

      Returns: Dict of constant names and values

      "},{"location":"qsl4a/system/application/#system-features","title":"System Features","text":""},{"location":"qsl4a/system/application/#backgroundprotect","title":"backgroundProtect()","text":"

      Enable or disable background protection for the app.

      backgroundProtect(enabled=True)\n

      Parameters: - enabled (bool): True to enable protection, False to disable

      "},{"location":"qsl4a/system/application/#createscriptshortcut","title":"createScriptShortCut()","text":"

      Create a home screen shortcut for a script.

      createScriptShortCut(scriptPath, label=None, iconPath=None, scriptArg=None)\n

      Parameters: - scriptPath (str): Path to the Python script - label (str, optional): Shortcut label - iconPath (str, optional): Path to icon image - scriptArg (str, optional): Argument to pass to script

      "},{"location":"qsl4a/system/application/#device-information","title":"Device Information","text":""},{"location":"qsl4a/system/application/#getandroidid","title":"getAndroidID()","text":"

      Get Android device ID.

      getAndroidID()\n

      Returns: Unique Android device ID string

      "},{"location":"qsl4a/system/application/#getsysinfo","title":"getSysInfo()","text":"

      Get system information.

      getSysInfo()\n

      Returns: Dict with system details

      "},{"location":"qsl4a/system/application/#getlocale","title":"getLocale()","text":"

      Get device locale.

      getLocale()\n

      Returns: Locale string (e.g., \"en_US\")

      "},{"location":"qsl4a/system/application/#getharmonyosinformation","title":"getHarmonyOsInformation()","text":"

      Get HarmonyOS information if running on HarmonyOS.

      getHarmonyOsInformation()\n

      Returns: HarmonyOS version info or None

      "},{"location":"qsl4a/system/application/#isexternalstoragemanager","title":"isExternalStorageManager()","text":"

      Check if app has external storage manager permission.

      isExternalStorageManager()\n

      Returns: True if has permission

      "},{"location":"qsl4a/system/application/#memory-and-display","title":"Memory and Display","text":""},{"location":"qsl4a/system/application/#getmemoryinfo","title":"getMemoryInfo()","text":"

      Get memory information.

      getMemoryInfo()\n

      Returns: Dict with memory stats

      "},{"location":"qsl4a/system/application/#getscreeninfo","title":"getScreenInfo()","text":"

      Get screen information.

      getScreenInfo()\n

      Returns: Dict with width, height, density

      "},{"location":"qsl4a/system/application/#permissions","title":"Permissions","text":""},{"location":"qsl4a/system/application/#checkpermissions","title":"checkPermissions()","text":"

      Check current app permissions.

      checkPermissions()\n

      Returns: Dict of permissions and their status

      "},{"location":"qsl4a/system/application/#requestpermissions","title":"requestPermissions()","text":"

      Request permissions from the user.

      requestPermissions(permissions=None)\n

      Parameters: - permissions (list, optional): List of permissions to request. If None, requests all needed permissions.

      Returns: Result of permission request

      "},{"location":"qsl4a/system/application/#system-actions","title":"System Actions","text":""},{"location":"qsl4a/system/application/#showscreenlock","title":"showScreenLock()","text":"

      Show screen lock (PIN/pattern/password entry).

      showScreenLock()\n
      "},{"location":"qsl4a/system/application/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get system info\ninfo = droid.getSysInfo().result\nprint(f\"System: {info}\")\n\n# Get app version\nversion = droid.getPackageVersion(\"org.qpython.qpy\").result\nprint(f\"QPython version: {version}\")\n\n# List installed apps\napps = droid.getInstalledPackages().result\nprint(f\"Installed apps: {len(apps)}\")\n\n# Launch an app\ndroid.launch(packagename=\"com.android.settings\")\n\n# Check permissions\nperms = droid.checkPermissions().result\nprint(f\"Permissions: {perms}\")\n\n# Request storage permission\ndroid.requestPermissions([\"android.permission.READ_EXTERNAL_STORAGE\"])\n\n# Create shortcut\ndroid.createScriptShortCut(\n    \"/sdcard/my_script.py\",\n    label=\"My Script\",\n    iconPath=\"/sdcard/icon.png\"\n)\n
      "},{"location":"qsl4a/system/battery/","title":"Battery API","text":"

      Monitor device battery status and health.

      "},{"location":"qsl4a/system/battery/#methods","title":"Methods","text":""},{"location":"qsl4a/system/battery/#readbatterydata","title":"readBatteryData()","text":"

      Get complete battery information.

      readBatteryData()\n

      Returns: Dict with battery data

      "},{"location":"qsl4a/system/battery/#batterystartmonitoring","title":"batteryStartMonitoring()","text":"

      Start battery monitoring.

      batteryStartMonitoring()\n
      "},{"location":"qsl4a/system/battery/#batterystopmonitoring","title":"batteryStopMonitoring()","text":"

      Stop battery monitoring.

      batteryStopMonitoring()\n
      "},{"location":"qsl4a/system/battery/#batterygetlevel","title":"batteryGetLevel()","text":"

      Get battery percentage.

      batteryGetLevel()\n

      Returns: Int (0-100)

      "},{"location":"qsl4a/system/battery/#batterygetstatus","title":"batteryGetStatus()","text":"

      Get charging status.

      batteryGetStatus()\n

      Returns: - 1: Unknown - 2: Charging - 3: Discharging - 4: Not charging - 5: Full

      "},{"location":"qsl4a/system/battery/#batterygetplugtype","title":"batteryGetPlugType()","text":"

      Get power source.

      batteryGetPlugType()\n

      Returns: - -1: Unknown - 0: Unplugged - 1: AC charger - 2: USB port

      "},{"location":"qsl4a/system/battery/#batterygethealth","title":"batteryGetHealth()","text":"

      Get battery health.

      batteryGetHealth()\n

      Returns: - 1: Unknown - 2: Good - 3: Overheat - 4: Dead - 5: Over voltage - 6: Unspecified failure

      "},{"location":"qsl4a/system/battery/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get battery level\nlevel = droid.batteryGetLevel().result\nprint(f\"Battery: {level}%\")\n
      "},{"location":"qsl4a/system/qpyinterface/","title":"QPython Interface API","text":"

      Execute QPython scripts and manage shared variables from other apps.

      "},{"location":"qsl4a/system/qpyinterface/#script-execution-methods","title":"Script Execution Methods","text":""},{"location":"qsl4a/system/qpyinterface/#executeqpy","title":"executeQPy()","text":"

      Execute a QPython script.

      executeQPy(path=\"\", arg=None)\n

      Parameters: - path (str): Path to the script file - arg (str, optional): Command line arguments

      Returns: True if started successfully

      "},{"location":"qsl4a/system/qpyinterface/#executeqpyassrv","title":"executeQPyAsSrv()","text":"

      Execute a QPython script as a service.

      executeQPyAsSrv(path=None)\n

      Parameters: - path (str, optional): Path to the script file

      Returns: True if started successfully

      "},{"location":"qsl4a/system/qpyinterface/#executeqpycode","title":"executeQPyCode()","text":"

      Execute Python code directly.

      executeQPyCode(code=None)\n

      Parameters: - code (str, optional): Python code to execute

      Returns: True if started successfully

      "},{"location":"qsl4a/system/qpyinterface/#executeqpycodeassrv","title":"executeQPyCodeAsSrv()","text":"

      Execute Python code as a service.

      executeQPyCodeAsSrv(code=None)\n

      Parameters: - code (str, optional): Python code to execute

      Returns: True if started successfully

      "},{"location":"qsl4a/system/qpyinterface/#shared-variables","title":"Shared Variables","text":"

      Shared variables allow communication between QPython and other apps.

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableset","title":"sharedVariableSet()","text":"

      Set a Java shared variable.

      sharedVariableSet(key, value)\n

      Parameters: - key (str): Variable name - value (str): Variable value

      Returns: The stored value

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableget","title":"sharedVariableGet()","text":"

      Get a Java shared variable.

      sharedVariableGet(key)\n

      Parameters: - key (str): Variable name

      Returns: The stored value

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableremove","title":"sharedVariableRemove()","text":"

      Remove a Java shared variable.

      sharedVariableRemove(key)\n

      Parameters: - key (str): Variable name to remove

      Returns: The removed value

      "},{"location":"qsl4a/system/qpyinterface/#getlastlog","title":"getLastLog()","text":"

      Get the last log output from QPython.

      getLastLog()\n

      Returns: String log content

      "},{"location":"qsl4a/system/qpyinterface/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Execute a script\ndroid.executeQPy(\"/sdcard/my_script.py\", arg=\"test\")\n\n# Execute code directly\ncode = \"print('Hello from QPython!')\"\ndroid.executeQPyCode(code)\n\n# Use shared variables\ndroid.sharedVariableSet(\"username\", \"alice\")\nusername = droid.sharedVariableGet(\"username\").result\nprint(f\"Username: {username}\")\n\n# Remove variable\ndroid.sharedVariableRemove(\"username\")\n\n# Get recent log\nlog = droid.getLastLog().result\nprint(f\"Log: {log}\")\n
      "},{"location":"qsl4a/system/sensors/","title":"Sensor API","text":"

      Access device sensors including accelerometer, gyroscope, magnetometer, and more.

      "},{"location":"qsl4a/system/sensors/#methods","title":"Methods","text":""},{"location":"qsl4a/system/sensors/#startsensingtimed","title":"startSensingTimed()","text":"

      Start sensor monitoring with time intervals.

      startSensingTimed(sensorNumber, delayTime)\n

      Parameters: - sensorNumber (int): Sensor ID (1-3 typically) - delayTime (int): Delay between readings in milliseconds

      "},{"location":"qsl4a/system/sensors/#startsensingthreshold","title":"startSensingThreshold()","text":"

      Start sensor monitoring with threshold trigger.

      startSensingThreshold(sensorNumber, threshold, axis)\n

      Parameters: - sensorNumber (int): Sensor ID - threshold (float): Trigger threshold - axis (int): Axis to monitor (0=X, 1=Y, 2=Z)

      "},{"location":"qsl4a/system/sensors/#stopsensing","title":"stopSensing()","text":"

      Stop all sensor monitoring.

      stopSensing()\n
      "},{"location":"qsl4a/system/sensors/#readsensors","title":"readSensors()","text":"

      Read current sensor data.

      readSensors()\n

      Returns: Sensor data dict

      "},{"location":"qsl4a/system/sensors/#sensorsreadaccelerometer","title":"sensorsReadAccelerometer()","text":"

      Read accelerometer values.

      sensorsReadAccelerometer()\n

      Returns: List [X, Y, Z] in m/s\u00b2

      "},{"location":"qsl4a/system/sensors/#sensorsreadgyroscope","title":"sensorsReadGyroscope()","text":"

      Read gyroscope values.

      sensorsReadGyroscope()\n

      Returns: List [X, Y, Z] in rad/s

      "},{"location":"qsl4a/system/sensors/#sensorsreadmagnetometer","title":"sensorsReadMagnetometer()","text":"

      Read magnetic field values.

      sensorsReadMagnetometer()\n

      Returns: List [X, Y, Z] in \u03bcT

      "},{"location":"qsl4a/system/sensors/#sensorsreadorientation","title":"sensorsReadOrientation()","text":"

      Read device orientation.

      sensorsReadOrientation()\n

      Returns: List [azimuth, pitch, roll] in degrees

      "},{"location":"qsl4a/system/sensors/#sensorsgetlight","title":"sensorsGetLight()","text":"

      Read light sensor value.

      sensorsGetLight()\n

      Returns: Light level in lux

      "},{"location":"qsl4a/system/sensors/#sensorsgetstepcounter","title":"sensorsGetStepCounter()","text":"

      Read step counter.

      sensorsGetStepCounter()\n

      Returns: Number of steps

      "},{"location":"qsl4a/system/sensors/#sensorsgetaccuracy","title":"sensorsGetAccuracy()","text":"

      Get the current sensor accuracy.

      sensorsGetAccuracy()\n

      Returns: Accuracy value (0-3: UNRELIABLE, ACCURACY_LOW, ACCURACY_MEDIUM, ACCURACY_HIGH)

      "},{"location":"qsl4a/system/sensors/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start sensing\ndroid.startSensingTimed(1, 250)\n\n# Read sensors 10 times\nfor i in range(10):\n    accel = droid.sensorsReadAccelerometer().result\n    print(f\"Accel: X={accel[0]:.2f}, Y={accel[1]:.2f}, Z={accel[2]:.2f}\")\n    time.sleep(0.5)\n\ndroid.stopSensing()\n
      "},{"location":"qsl4a/system/settings/","title":"Settings API","text":"

      Control system settings including screen, sound, and network settings.

      "},{"location":"qsl4a/system/settings/#screen-settings","title":"Screen Settings","text":""},{"location":"qsl4a/system/settings/#setscreentimeout","title":"setScreenTimeout()","text":"

      Set the screen timeout value.

      setScreenTimeout(value)\n

      Parameters: - value (int): Screen timeout in seconds

      Returns: Previous timeout value

      "},{"location":"qsl4a/system/settings/#getscreentimeout","title":"getScreenTimeout()","text":"

      Get the current screen timeout.

      getScreenTimeout()\n

      Returns: Current screen timeout in seconds

      "},{"location":"qsl4a/system/settings/#getscreenbrightness","title":"getScreenBrightness()","text":"

      Get the screen brightness value.

      getScreenBrightness()\n

      Returns: Brightness value (0-255)

      "},{"location":"qsl4a/system/settings/#setscreenbrightness","title":"setScreenBrightness()","text":"

      Set the screen brightness.

      setScreenBrightness(value=None)\n

      Parameters: - value (int, optional): Brightness value (0-255), or None for auto

      Returns: Previous brightness value

      "},{"location":"qsl4a/system/settings/#checkscreenon","title":"checkScreenOn()","text":"

      Check if the screen is on.

      checkScreenOn()\n

      Returns: True if screen is on, False otherwise

      "},{"location":"qsl4a/system/settings/#airplane-mode","title":"Airplane Mode","text":""},{"location":"qsl4a/system/settings/#checkairplanemode","title":"checkAirplaneMode()","text":"

      Check if airplane mode is enabled.

      checkAirplaneMode()\n

      Returns: True if airplane mode is on

      "},{"location":"qsl4a/system/settings/#ringer-settings","title":"Ringer Settings","text":""},{"location":"qsl4a/system/settings/#checkringersilentmode","title":"checkRingerSilentMode()","text":"

      Check if ringer is in silent mode.

      checkRingerSilentMode()\n

      Returns: True if silent mode is on

      "},{"location":"qsl4a/system/settings/#toggleringersilentmode","title":"toggleRingerSilentMode()","text":"

      Toggle ringer silent mode.

      toggleRingerSilentMode(enabled=None)\n

      Parameters: - enabled (bool, optional): True to enable, False to disable, None to toggle

      Returns: New state

      "},{"location":"qsl4a/system/settings/#togglevibratemode","title":"toggleVibrateMode()","text":"

      Toggle vibrate mode.

      toggleVibrateMode(enabled=None, ringer=None)\n

      Parameters: - enabled (bool, optional): Toggle vibrate on/off - ringer (bool, optional): Apply to ringer mode

      Returns: New state

      "},{"location":"qsl4a/system/settings/#getvibratemode","title":"getVibrateMode()","text":"

      Get the vibrate mode setting.

      getVibrateMode(ringer=None)\n

      Parameters: - ringer (bool, optional): Check ringer vibrate mode

      Returns: True if vibrate is enabled

      "},{"location":"qsl4a/system/settings/#volume-settings","title":"Volume Settings","text":""},{"location":"qsl4a/system/settings/#getringervolume","title":"getRingerVolume()","text":"

      Get the current ringer volume.

      getRingerVolume()\n

      Returns: Ringer volume level (0-7 typically)

      "},{"location":"qsl4a/system/settings/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

      Get the maximum ringer volume.

      getMaxRingerVolume()\n

      Returns: Maximum ringer volume

      "},{"location":"qsl4a/system/settings/#setringervolume","title":"setRingerVolume()","text":"

      Set the ringer volume.

      setRingerVolume(volume)\n

      Parameters: - volume (int): Volume level

      "},{"location":"qsl4a/system/settings/#getmediavolume","title":"getMediaVolume()","text":"

      Get the current media volume.

      getMediaVolume()\n

      Returns: Media volume level (0-15 typically)

      "},{"location":"qsl4a/system/settings/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

      Get the maximum media volume.

      getMaxMediaVolume()\n

      Returns: Maximum media volume

      "},{"location":"qsl4a/system/settings/#setmediavolume","title":"setMediaVolume()","text":"

      Set the media volume.

      setMediaVolume(volume)\n

      Parameters: - volume (int): Volume level

      "},{"location":"qsl4a/system/settings/#system-info","title":"System Info","text":""},{"location":"qsl4a/system/settings/#elapsedrealtimenanos","title":"elapsedRealtimeNanos()","text":"

      Get nanoseconds since system startup.

      elapsedRealtimeNanos()\n

      Returns: Nanoseconds (can be used for timing)

      "},{"location":"qsl4a/system/settings/#gettrafficstats","title":"getTrafficStats()","text":"

      Get network traffic statistics.

      getTrafficStats(flags=7)\n

      Parameters: - flags (int): Which stats to retrieve (default: 7 = all)

      Returns: Dict with transmit/receive bytes

      "},{"location":"qsl4a/system/settings/#getapptxbytes","title":"getAppTxBytes()","text":"

      Get transmit bytes for QPython app.

      getAppTxBytes(packageName)\n

      Parameters: - packageName (str): Package name

      Returns: Dict with tx/rx bytes

      "},{"location":"qsl4a/system/settings/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Screen settings\ncurrent_timeout = droid.getScreenTimeout().result\nprint(f\"Current timeout: {current_timeout}s\")\ndroid.setScreenTimeout(30)\n\n# Check screen\nif droid.checkScreenOn().result:\n    print(\"Screen is on\")\n\n# Volume control\nmedia_vol = droid.getMediaVolume().result\nprint(f\"Media volume: {media_vol}\")\ndroid.setMediaVolume(10)\n\n# Check airplane mode\nif droid.checkAirplaneMode().result:\n    print(\"Airplane mode is on\")\n
      "},{"location":"qsl4a/system/sysinfo/","title":"System Information","text":"

      Retrieve device and system information.

      "},{"location":"qsl4a/system/sysinfo/#device-information","title":"Device Information","text":""},{"location":"qsl4a/system/sysinfo/#getandroidid","title":"getAndroidID()","text":"

      Get the Android device ID.

      getAndroidID()\n

      Returns: String device ID

      "},{"location":"qsl4a/system/sysinfo/#getsysinfo","title":"getSysInfo()","text":"

      Get comprehensive system information.

      getSysInfo()\n

      Returns: Dict with system details

      "},{"location":"qsl4a/system/sysinfo/#getlocale","title":"getLocale()","text":"

      Get device locale settings.

      getLocale()\n

      Returns: Locale string (e.g., \"en_US\")

      "},{"location":"qsl4a/system/sysinfo/#memory","title":"Memory","text":""},{"location":"qsl4a/system/sysinfo/#getmemoryinfo","title":"getMemoryInfo()","text":"

      Get RAM information.

      getMemoryInfo()\n

      Returns: Dict with memory stats

      "},{"location":"qsl4a/system/sysinfo/#display","title":"Display","text":""},{"location":"qsl4a/system/sysinfo/#getscreeninfo","title":"getScreenInfo()","text":"

      Get display information.

      getScreenInfo()\n

      Returns: Dict with width, height, density

      "},{"location":"qsl4a/system/sysinfo/#identifiers","title":"Identifiers","text":""},{"location":"qsl4a/system/sysinfo/#getimei","title":"getImei()","text":"

      Get device IMEI.

      getImei(slotIndex=None)\n
      "},{"location":"qsl4a/system/sysinfo/#getmeid","title":"getMeid()","text":"

      Get device MEID.

      getMeid(slotIndex=None)\n
      "},{"location":"qsl4a/system/sysinfo/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Device ID\nandroid_id = droid.getAndroidID().result\nprint(f\"Android ID: {android_id}\")\n\n# Screen info\nscreen = droid.getScreenInfo().result\nprint(f\"Screen: {screen['width']}x{screen['height']}\")\n\n# Memory\nmemory = droid.getMemoryInfo().result\nprint(f\"Memory: {memory}\")\n
      "},{"location":"qsl4a/system/wakelock/","title":"WakeLock API","text":"

      Control device wake locks to keep the CPU or screen on.

      "},{"location":"qsl4a/system/wakelock/#wake-lock-types","title":"Wake Lock Types","text":"

      QSL4A provides different wake lock types:

      Type Description Full CPU on, screen bright, keyboard bright Partial CPU on only Bright CPU on, screen bright Dim CPU on, screen dim"},{"location":"qsl4a/system/wakelock/#wake-lock-methods","title":"Wake Lock Methods","text":""},{"location":"qsl4a/system/wakelock/#wakelockacquirefull","title":"wakeLockAcquireFull()","text":"

      Acquire a full wake lock (CPU on, screen bright, keyboard bright).

      wakeLockAcquireFull()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquirepartial","title":"wakeLockAcquirePartial()","text":"

      Acquire a partial wake lock (CPU on only).

      wakeLockAcquirePartial()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquirebright","title":"wakeLockAcquireBright()","text":"

      Acquire a bright wake lock (CPU on, screen bright).

      wakeLockAcquireBright()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquiredim","title":"wakeLockAcquireDim()","text":"

      Acquire a dim wake lock (CPU on, screen dim).

      wakeLockAcquireDim()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockrelease","title":"wakeLockRelease()","text":"

      Release the wake lock.

      wakeLockRelease()\n
      "},{"location":"qsl4a/system/wakelock/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Acquire full wake lock\ndroid.wakeLockAcquireFull()\n\n# Do important work while keeping screen on\nprint(\"Screen will stay on\")\ntime.sleep(10)\n\n# Release when done\ndroid.wakeLockRelease()\n\n# Or use partial lock for background tasks\ndroid.wakeLockAcquirePartial()\n# CPU stays on even with screen off\ntime.sleep(30)\ndroid.wakeLockRelease()\n

      Note: Remember to release wake locks when no longer needed to conserve battery.

      "},{"location":"qsl4a/ui/accessibility/","title":"Accessibility Service","text":"

      The Accessibility Service allows automation of UI interactions like clicks, swipes, and system actions.

      "},{"location":"qsl4a/ui/accessibility/#service-control","title":"Service Control","text":""},{"location":"qsl4a/ui/accessibility/#accessibilitystartservice","title":"accessibilityStartService()","text":"

      Start the accessibility service.

      accessibilityStartService()\n

      Returns: True if successful, False otherwise

      "},{"location":"qsl4a/ui/accessibility/#accessibilityserviceenabled","title":"accessibilityServiceEnabled()","text":"

      Check if accessibility service is enabled.

      accessibilityServiceEnabled()\n

      Returns: True or False

      "},{"location":"qsl4a/ui/accessibility/#screen-interactions","title":"Screen Interactions","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityclick","title":"accessibilityClick()","text":"

      Click at screen coordinates.

      accessibilityClick(x=0, y=0, t=50)\n

      Parameters: - x (int/float): X coordinate (0=center, decimals supported) - y (int/float): Y coordinate (0=center, decimals supported) - t (int): Press duration in milliseconds (default: 50)

      "},{"location":"qsl4a/ui/accessibility/#accessibilityslide","title":"accessibilitySlide()","text":"

      Multi-point slide gesture.

      accessibilitySlide(XnYn=None, t=None)\n

      Parameters: - XnYn (list): Coordinates [X1, Y1, X2, Y2, ... Xn, Yn] - t (int): Slide duration (default: 50*n ms)

      "},{"location":"qsl4a/ui/accessibility/#system-actions","title":"System Actions","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityaction","title":"accessibilityAction()","text":"

      Execute system action by code.

      accessibilityAction(actionCode)\n

      Action Codes: | Code | Constant | Description | |------|----------|-------------| | 1 | BACK | Back button | | 2 | HOME | Home button | | 3 | RECENTS | Recent apps | | 4 | NOTIFICATIONS | Open notifications | | 5 | QUICK_SETTINGS | Open quick settings | | 6 | POWER_DIALOG | Power menu | | 7 | TOGGLE_SPLIT_SCREEN | Split screen | | 8 | LOCK_SCREEN | Lock screen | | 9 | TAKE_SCREENSHOT | Take screenshot | | 10 | KEYCODE_HEADSETHOOK | Headset hook | | 11-14 | ACCESSIBILITY_ | Accessibility buttons | | 15 | DISMISS_NOTIFICATION_SHADE | Close notifications | | 16-20 | DPAD_ | Directional pad | | 21 | MENU | Menu button | | 22 | MEDIA_PLAY_PAUSE | Play/Pause media |

      "},{"location":"qsl4a/ui/accessibility/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/accessibility/#click-center-screen","title":"Click Center Screen","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Start service\nif not droid.accessibilityServiceEnabled().result:\n    droid.accessibilityStartService()\n\n# Click center (0,0 = center)\ndroid.accessibilityClick(0, 0, t=100)\n
      "},{"location":"qsl4a/ui/accessibility/#swipe-gesture","title":"Swipe Gesture","text":"
      # Swipe from bottom to top (scroll up)\ndroid.accessibilitySlide([0, 1.5, 0, -1.5], t=300)\n
      "},{"location":"qsl4a/ui/accessibility/#system-navigation","title":"System Navigation","text":"
      # Press home\ndroid.accessibilityAction(2)\n\n# Press back\ndroid.accessibilityAction(1)\n\n# Open notifications\ndroid.accessibilityAction(4)\n
      "},{"location":"qsl4a/ui/accessibility/#tap-specific-location","title":"Tap Specific Location","text":"
      # Tap at screen coordinate (500, 800)\ndroid.accessibilityClick(500, 800)\n\n# Tap at relative position (center horizontally, 3/4 down)\ndroid.accessibilityClick(0, 1.5)\n
      "},{"location":"qsl4a/ui/dialogs/","title":"Dialog System","text":"

      QSL4A provides comprehensive dialog support for user interaction, including alerts, input dialogs, choice dialogs, and progress dialogs.

      "},{"location":"qsl4a/ui/dialogs/#alert-dialogs","title":"Alert Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowalert","title":"dialogShowAlert()","text":"

      Show a simple alert dialog.

      dialogShowAlert(title=\"Alert\", message=\"The message of the alert.\",\n                positiveButtonText=\"OK\", negativeButtonText=None,\n                neutralButtonText=None, messageIsHtml=False)\n

      Parameters: - title (str): Dialog title - message (str): Message text - positiveButtonText (str): Positive button label - negativeButtonText (str, optional): Negative button label - neutralButtonText (str, optional): Neutral button label - messageIsHtml (bool): Parse message as HTML

      Returns: Result with button clicked

      "},{"location":"qsl4a/ui/dialogs/#dialogshowsimplechoice","title":"dialogShowSimpleChoice()","text":"

      Show a simple choice dialog with items.

      dialogShowSimpleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

      Parameters: - items (list): List of choice strings

      Returns: Result with selected item

      "},{"location":"qsl4a/ui/dialogs/#input-dialogs","title":"Input Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialoggetinput","title":"dialogGetInput()","text":"

      Get text input from user.

      dialogGetInput(title=\"Value\", message=\"Please enter value:\",\n               defaultText=None, messageIsHtml=False)\n

      Returns: Result with user's input text

      "},{"location":"qsl4a/ui/dialogs/#dialoggetpassword","title":"dialogGetPassword()","text":"

      Get password input.

      dialogGetPassword(title=\"Password\", message=\"Please enter password:\")\n

      Returns: Result with password entered

      "},{"location":"qsl4a/ui/dialogs/#dialogcreateinput","title":"dialogCreateInput()","text":"

      Create a custom input dialog.

      dialogCreateInput(title=\"Value\", message=\"Please enter value:\",\n                  defaultText=None, inputType=None)\n

      Parameters: - inputType (str): Input type (e.g., \"text\", \"number\", \"textPassword\")

      "},{"location":"qsl4a/ui/dialogs/#dialogcreatepassword","title":"dialogCreatePassword()","text":"

      Create a password input dialog.

      dialogCreatePassword(title=\"Password\", message=\"Please enter password:\")\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreateseekbar","title":"dialogCreateSeekBar()","text":"

      Create a seek bar/slider dialog.

      dialogCreateSeekBar(starting_value=50, maximum_value=100, title=\"\", message=\"\")\n

      Parameters: - starting_value (int): Initial value - maximum_value (int): Maximum value

      "},{"location":"qsl4a/ui/dialogs/#choice-dialogs","title":"Choice Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowsinglechoice","title":"dialogShowSingleChoice()","text":"

      Show single choice (radio) dialog.

      dialogShowSingleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, selected=-1, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

      Parameters: - items (list): List of choice strings - selected (int): Default selected index

      "},{"location":"qsl4a/ui/dialogs/#dialogshowmultichoice","title":"dialogShowMultiChoice()","text":"

      Show multiple choice (checkbox) dialog.

      dialogShowMultiChoice(title=\"Alert\", message=\"The message of the alert.\",\n                      items=None, selected=None, positiveButtonText=\"OK\",\n                      negativeButtonText=None, neutralButtonText=None,\n                      messageIsHtml=False)\n

      Parameters: - items (list): List of choice strings - selected (list): List of initially selected indices

      "},{"location":"qsl4a/ui/dialogs/#dialogsetsinglechoiceitems","title":"dialogSetSingleChoiceItems()","text":"

      Set single choice items for a dialog.

      dialogSetSingleChoiceItems(items, selected=-1)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmultichoiceitems","title":"dialogSetMultiChoiceItems()","text":"

      Set multiple choice items for a dialog.

      dialogSetMultiChoiceItems(items, selected=None)\n
      "},{"location":"qsl4a/ui/dialogs/#progress-dialogs","title":"Progress Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatespinnerprogress","title":"dialogCreateSpinnerProgress()","text":"

      Create indeterminate progress dialog.

      dialogCreateSpinnerProgress(title=None, message=None, maximum_progress=100)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreatehorizontalprogress","title":"dialogCreateHorizontalProgress()","text":"

      Create horizontal progress dialog.

      dialogCreateHorizontalProgress(title=None, message=None, maximum_progress=100)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetcurrentprogress","title":"dialogSetCurrentProgress()","text":"

      Update progress value.

      dialogSetCurrentProgress(current)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmaxprogress","title":"dialogSetMaxProgress()","text":"

      Set maximum progress value.

      dialogSetMaxProgress(max)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetprogressmessage","title":"dialogSetProgressMessage()","text":"

      Update the progress dialog message.

      dialogSetProgressMessage(message)\n
      "},{"location":"qsl4a/ui/dialogs/#picker-dialogs","title":"Picker Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatedatepicker","title":"dialogCreateDatePicker()","text":"

      Create date picker dialog.

      dialogCreateDatePicker(year=1970, month=1, day=1)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreatetimepicker","title":"dialogCreateTimePicker()","text":"

      Create time picker dialog.

      dialogCreateTimePicker(hour=0, minute=0, is24hour=False)\n
      "},{"location":"qsl4a/ui/dialogs/#custom-dialog-creation","title":"Custom Dialog Creation","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatealert","title":"dialogCreateAlert()","text":"

      Create a custom alert dialog.

      dialogCreateAlert(title=None, message=None)\n

      Creates an empty alert dialog. Use with other dialogSet* functions to customize.

      "},{"location":"qsl4a/ui/dialogs/#dialogsetitems","title":"dialogSetItems()","text":"

      Set simple list items for the dialog.

      dialogSetItems(items)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetpositivebuttontext","title":"dialogSetPositiveButtonText()","text":"

      Set positive button text.

      dialogSetPositiveButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetnegativebuttontext","title":"dialogSetNegativeButtonText()","text":"

      Set negative button text.

      dialogSetNegativeButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetneutralbuttontext","title":"dialogSetNeutralButtonText()","text":"

      Set neutral button text.

      dialogSetNeutralButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmessageishtml","title":"dialogSetMessageIsHtml()","text":"

      Set whether message should be parsed as HTML.

      dialogSetMessageIsHtml(messageIsHtml=True)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogshow","title":"dialogShow()","text":"

      Show the created custom dialog.

      dialogShow()\n
      "},{"location":"qsl4a/ui/dialogs/#dialog-control","title":"Dialog Control","text":""},{"location":"qsl4a/ui/dialogs/#dialogdismiss","title":"dialogDismiss()","text":"

      Dismiss current dialog.

      dialogDismiss()\n
      "},{"location":"qsl4a/ui/dialogs/#dialoggetresponse","title":"dialogGetResponse()","text":"

      Get dialog response.

      dialogGetResponse()\n
      "},{"location":"qsl4a/ui/dialogs/#dialoggetselecteditems","title":"dialogGetSelectedItems()","text":"

      Get selected items from choice dialog.

      dialogGetSelectedItems()\n
      "},{"location":"qsl4a/ui/dialogs/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/dialogs/#simple-alert","title":"Simple Alert","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Show alert\ndroid.dialogShowAlert(\"Warning\", \"This is an important message!\")\n
      "},{"location":"qsl4a/ui/dialogs/#input-dialog","title":"Input Dialog","text":"
      # Get user input\nresult = droid.dialogGetInput(\"Name\", \"Enter your name:\", \"John\").result\nprint(f\"Hello, {result}!\")\n
      "},{"location":"qsl4a/ui/dialogs/#custom-dialog-with-buttons","title":"Custom Dialog with Buttons","text":"
      # Create custom dialog\ndroid.dialogCreateAlert(\"Custom\", \"Choose an option\")\ndroid.dialogSetItems([\"Option 1\", \"Option 2\", \"Option 3\"])\ndroid.dialogShow()\n\n# Get response\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response['item']}\")\n
      "},{"location":"qsl4a/ui/dialogs/#progress-dialog","title":"Progress Dialog","text":"
      # Create progress dialog\ndroid.dialogCreateHorizontalProgress(\"Loading\", \"Please wait...\", 100)\ndroid.dialogShow()\n\n# Update progress\nfor i in range(101):\n    droid.dialogSetCurrentProgress(i)\n    time.sleep(0.05)\n\ndroid.dialogDismiss()\n
      "},{"location":"qsl4a/ui/dialogs/#date-picker","title":"Date Picker","text":"
      # Show date picker\ndroid.dialogCreateDatePicker(2024, 1, 15)\ndroid.dialogShow()\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response}\")\n
      "},{"location":"qsl4a/ui/floatview/","title":"FloatView","text":"

      Floating window support for overlay UI elements that stay on top of other applications.

      "},{"location":"qsl4a/ui/floatview/#methods","title":"Methods","text":""},{"location":"qsl4a/ui/floatview/#floatview_1","title":"floatView()","text":"

      Show or modify a floating view.

      floatView(Args=None)\n

      Parameters: - Args (dict): Configuration dictionary with the following keys: - index (int): Float view index (-1 to create new, >=0 to modify existing) - text (str): Text content to display - html (str): HTML content (used if text is omitted) - width (int): View width in pixels (default: 300) - height (int): View height in pixels (default: 150) - x (int): X position (0 = center, positive/negative for offset) - y (int): Y position (0 = center, positive/negative for offset) - backColor (str): Background color in ARGB hex (default: '7f7f7f7f') - textColor (str): Text color in ARGB hex (default: 'ff000000') - textSize (int): Text size (default: 10) - textAlign (int): Text alignment (0 = inherit) - script (str): Script path to run after long click close - arg: Script argument - clickRemove (bool): Enable click to remove (default: True) - flag (int): Window flag (default: 40 - touchable)

      Returns: Current chain list length

      "},{"location":"qsl4a/ui/floatview/#floatviewcount","title":"floatViewCount()","text":"

      Get the number of active float views.

      floatViewCount()\n

      Returns: Number of float views

      "},{"location":"qsl4a/ui/floatview/#floatviewresult","title":"floatViewResult()","text":"

      Get the result/status of a float view.

      floatViewResult(index=-1)\n

      Parameters: - index (int): Float view index (default: -1, returns last operation result)

      Returns: Dict with operation details including: - x, y: Position - time: Timestamp - operation: Operation type ('initial', 'move', etc.) - index: View index - removed: True if view was removed

      "},{"location":"qsl4a/ui/floatview/#floatviewremove","title":"floatViewRemove()","text":"

      Remove a float view.

      floatViewRemove(index=-1)\n

      Parameters: - index (int): Index of view to remove (default: -1 removes the last one)

      Returns: 1 if successful, 0 otherwise

      "},{"location":"qsl4a/ui/floatview/#constants","title":"Constants","text":"
      • floatView.INDEX_NEW = -1 - Create new float view
      • floatView.FLAG_DEFAULT_TOUCHABLE = 40 - Default touchable flag
      • floatView.TEXT_ALIGNMENT_INHERIT = 0
      • floatView.TEXT_ALIGNMENT_CENTER - Center text alignment
      "},{"location":"qsl4a/ui/floatview/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/floatview/#basic-float-view","title":"Basic Float View","text":"
      import androidhelper\nfrom androidhelper import Android\n\ndroid = androidhelper.Android()\n\n# Create a simple float view\ndroid.floatView({\n    'index': -1,  # Create new\n    'text': 'Hello World',\n    'width': 400,\n    'height': 300,\n    'x': -300,  # Offset from center\n    'y': -400,\n    'backColor': 'ff0000',  # Red background\n    'textColor': '0000ff',  # Blue text\n    'textSize': 16,\n    'textAlign': droid.floatView.TEXT_ALIGNMENT_CENTER\n})\n\n# Check count\nprint(f\"Float views: {droid.floatViewCount().result}\")\n\n# Get result\nresult = droid.floatViewResult().result\nprint(f\"View info: {result}\")\n\n# Remove the float view\ndroid.floatViewRemove(0)\n
      "},{"location":"qsl4a/ui/floatview/#html-content","title":"HTML Content","text":"
      # Create float view with HTML content\ndroid.floatView({\n    'text': '',  # Empty text to use HTML\n    'html': '<h1>Title</h1><p>Rich <b>HTML</b> content</p>',\n    'width': 500,\n    'height': 400\n})\n
      "},{"location":"qsl4a/ui/floatview/#modify-existing-view","title":"Modify Existing View","text":"
      # Create initial view\ndroid.floatView({'text': 'Initial Text', 'width': 300, 'height': 150})\n\n# Modify the same view (index 0)\ndroid.floatView({\n    'index': 0,\n    'text': 'Updated Text!',\n    'backColor': '7f00ff00'  # Green background\n})\n\n# Check the move/change result\nresult = droid.floatViewResult(0).result\nprint(f\"Operation: {result.get('operation')}, Position: ({result.get('x')}, {result.get('y')})\")\n
      "},{"location":"qsl4a/ui/floatview/#multiple-float-views","title":"Multiple Float Views","text":"
      # Create multiple views\nfor i in range(3):\n    droid.floatView({\n        'index': -1,\n        'text': f'View {i}',\n        'x': i * 100 - 150,\n        'y': i * 100 - 150,\n        'backColor': f'{i}f{i}f{i}f'\n    })\n\nprint(f\"Total views: {droid.floatViewCount().result}\")\n\n# Remove all views\nwhile droid.floatViewCount().result > 0:\n    droid.floatViewRemove()\n
      "},{"location":"qsl4a/ui/floatview/#with-script-callback","title":"With Script Callback","text":"
      # Create float view that runs script on close\ndroid.floatView({\n    'text': 'Click to close and run script',\n    'script': '/sdcard/my_script.py',\n    'arg': 'hello from float view',\n    'clickRemove': True\n})\n
      "},{"location":"qsl4a/ui/fullscreen/","title":"FullScreen UI","text":"

      Create custom fullscreen interfaces with native Android layouts.

      "},{"location":"qsl4a/ui/fullscreen/#layout-methods","title":"Layout Methods","text":""},{"location":"qsl4a/ui/fullscreen/#fullshow","title":"fullShow()","text":"

      Show a fullscreen layout.

      fullShow(layout, title=None, theme=None)\n

      Parameters: - layout (str): JSON layout definition or layout string - title (str, optional): Window title - theme (str, optional): Theme name

      Returns: Window ID

      "},{"location":"qsl4a/ui/fullscreen/#fulldismiss","title":"fullDismiss()","text":"

      Close fullscreen window.

      fullDismiss()\n
      "},{"location":"qsl4a/ui/fullscreen/#fullquery","title":"fullQuery()","text":"

      Query all widget values.

      fullQuery()\n

      Returns: Dict of widget IDs and values

      "},{"location":"qsl4a/ui/fullscreen/#fullquerydetail","title":"fullQueryDetail()","text":"

      Query specific widget details.

      fullQueryDetail(id)\n
      "},{"location":"qsl4a/ui/fullscreen/#property-methods","title":"Property Methods","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperty","title":"fullGetProperty()","text":"

      Get widget property.

      fullGetProperty(id, property)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetproperty","title":"fullSetProperty()","text":"

      Set widget property.

      fullSetProperty(id, property, value)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetlist","title":"fullSetList()","text":"

      Set list widget items.

      fullSetList(id, list, isHtml=False, listType=0)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetlist2","title":"fullSetList2()","text":"

      Set list widget items with resource ID.

      fullSetList2(id, list, intRes)\n

      Parameters: - id (str): Widget ID - list (list): List of items - intRes (int): Android resource ID for list item layout

      "},{"location":"qsl4a/ui/fullscreen/#fullsetlistselected","title":"fullSetListSelected()","text":"

      Set selected item in a list.

      fullSetListSelected(id, selected)\n

      Parameters: - id (str): List widget ID - selected (int): Index of item to select

      "},{"location":"qsl4a/ui/fullscreen/#fullgetlistselected","title":"fullGetListSelected()","text":"

      Get the currently selected list item index.

      fullGetListSelected(id)\n

      Parameters: - id (str): List widget ID

      Returns: Selected item index

      "},{"location":"qsl4a/ui/fullscreen/#batch-property-operations","title":"Batch Property Operations","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperties","title":"fullGetProperties()","text":"

      Get properties for multiple widgets at once.

      fullGetProperties(ids, property)\n

      Parameters: - ids (list): List of widget IDs - property (str): Property name to get

      Returns: Dict mapping widget IDs to property values

      "},{"location":"qsl4a/ui/fullscreen/#fullsetproperties","title":"fullSetProperties()","text":"

      Set property for multiple widgets at once.

      fullSetProperties(ids, property, value)\n

      Parameters: - ids (list): List of widget IDs - property (str): Property name to set - value: Property value

      "},{"location":"qsl4a/ui/fullscreen/#screenshot","title":"Screenshot","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetscreenshot","title":"fullGetScreenShot()","text":"

      Capture fullscreen screenshot.

      fullGetScreenShot(path=None)\n

      Parameters: - path (str, optional): Save path. If None, returns in event

      Returns: Event with screenshot data

      "},{"location":"qsl4a/ui/fullscreen/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Define layout\nlayout = '''\n{ \"type\": \"LinearLayout\", \"orientation\": \"vertical\",\n  \"children\": [\n    { \"type\": \"TextView\", \"id\": \"title\", \"text\": \"Hello\" },\n    { \"type\": \"Button\", \"id\": \"btn\", \"text\": \"Click Me\" }\n  ]\n}\n'''\n\n# Show layout\ndroid.fullShow(layout, \"My App\")\n\n# Query button click\nevent = droid.eventWaitFor('click', timeout=10)\nif event.result:\n    widget_id = event.result['data']['id']\n    if widget_id == 'btn':\n        print(\"Button clicked!\")\n\ndroid.fullDismiss()\n
      "}]} \ No newline at end of file diff --git a/en/sitemap.xml b/en/sitemap.xml index 062d93e..62f5d77 100644 --- a/en/sitemap.xml +++ b/en/sitemap.xml @@ -2,194 +2,198 @@ https://www.qpython.org/en/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/AIPyApp/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/GraphicalInterface/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/Notebook/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/Ollama/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/Terminal/ - 2026-03-23 + 2026-03-27 + + + https://www.qpython.org/en/community/ + 2026-03-27 https://www.qpython.org/en/editor-guide/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/external-api/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/getting-started/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/qpypi-guide/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/qpython-x/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/tutorial-hello-world/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/whats-new/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/qsl4a/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/qsl4a/connectivity/contacts/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/qsl4a/connectivity/ftp/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/qsl4a/connectivity/location/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/qsl4a/connectivity/phone/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/qsl4a/connectivity/signalstrength/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/qsl4a/connectivity/sms/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/qsl4a/connectivity/wifi/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/qsl4a/core/android-base/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/qsl4a/core/events/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/qsl4a/core/intent/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/qsl4a/hardware/bluetooth/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/qsl4a/hardware/camera/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/qsl4a/hardware/recorder/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/qsl4a/hardware/usbserial/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/qsl4a/hardware/webcam/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/qsl4a/media/image/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/qsl4a/media/mediaplayer/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/qsl4a/special/cipher/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/qsl4a/special/pgptai/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/qsl4a/storage/clipboard/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/qsl4a/storage/documentfile/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/qsl4a/storage/preferences/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/qsl4a/system/activityresult/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/qsl4a/system/application/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/qsl4a/system/battery/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/qsl4a/system/qpyinterface/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/qsl4a/system/sensors/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/qsl4a/system/settings/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/qsl4a/system/sysinfo/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/qsl4a/system/wakelock/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/qsl4a/ui/accessibility/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/qsl4a/ui/dialogs/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/qsl4a/ui/floatview/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/en/qsl4a/ui/fullscreen/ - 2026-03-23 + 2026-03-27 \ No newline at end of file diff --git a/en/sitemap.xml.gz b/en/sitemap.xml.gz index 56972749010ef6af45f6410aaf7441c9d4351b1e..e4c153af0b1f432d94089ec2309ac6b31d1187d7 100644 GIT binary patch literal 608 zcmV-m0-yaKiwFpS$i-;_|8r?{Wo=<_E_iKh0L7Tij+;OX$M5?TQSO9vTlGsxR(ol+ zm$rxP1DL^pwe!`n3Cr8pWTRDktSVs+kO4FQpT@@H_;B|e{N{{>DaGUV&2GQlV05Xa z*dMn)AHP%|w|A$T!&p3{Y}7dNaXX0Q&viXb(~e0nK;~U4ea&vr0oT`?^?vthd%D@^ zu}tvt>v9}?a;Ie$zE1Ni&oZQVnFV8gs277j?SUnv_H?_yeP8Y0R<|G2J$ymMPX8Ss$Y{1XHg` zm!)9rWiY1+<^eiUMWb!S% zLO2Lmz>=V#`lH2S$uM%mxD*VQ5EC})4FiIpr8v|Sphq+H%Q<_PO#*>4y2bmB@?Z*( z`z&CwE3g*Ki~pUc+$0T2LxwiFF=%q`$fF@fF4&<~D-JC-DV|v{)Nrj93i9a1kRxYL zX4UK!q5;vr?z0_$J|mO<*IyKjkyBwyfJ-C8l3-?vU9tn1;0e|K$$(%a%?g^7m>TkH uckNygbi4M+Bm`8v^9kfkChe6)e)OJQ!T;&|UoQF~oqhwFG6Sj67ytm(H7`d1 literal 599 zcmV-d0;v5TiwFpSg1~74|8r?{Wo=<_E_iKh0L7TWj+`(IhVT0nqq#FoXRE5MW@fdQ zR(olC*gk*>2CNB58k=Ex`uiAX%8%Ytj~x2;X|>%FAn!=vRr!=DBl$R zQS0&P$Ml%es+wOjq>dc;ry!UcaJZ`cw_ zUe~MmqOqiJTR@^!gk*Wo@&ihYCf~vvgo7S4SQ2DZ zf7F;Q83wKx=Yqi!V#G?lVL;GpDGnv|(4v|8ZJ#_$CV{{S-RylwsWSygZ4$7U6<7=A z+5gT{s-lLZAwwPA&}(vT$fF@f%GjV*D-JCtDV|ucFJY+`GVMsh$z%jEWz-=MJl3-#AO|%0T;eu*^F(4R7vw|iiri%RhBVmG|)3uK# lA)w-ok04hvSzejt2k+Ts{GS#0+d)61^KVKe*}q#D004VCBCP-b diff --git a/en/tutorial-hello-world/index.html b/en/tutorial-hello-world/index.html index 11a2501..2b641a8 100644 --- a/en/tutorial-hello-world/index.html +++ b/en/tutorial-hello-world/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    191. + + + + + Community + + +
    192. + + + + @@ -2213,6 +2233,95 @@ + + + + + + + + + + + + + + + + +
    193. + + + + + + + + + + + + +
    194. + + + diff --git a/en/whats-new/index.html b/en/whats-new/index.html index 150d72f..5e20179 100644 --- a/en/whats-new/index.html +++ b/en/whats-new/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    195. + + + + + Community + + +
    196. + + + + @@ -2345,6 +2365,95 @@ + + + + + + + + + + + + + + + + +
    197. + + + + + + + + + + + + +
    198. + + + diff --git a/zh/404.html b/zh/404.html index 7bb0385..688b274 100644 --- a/zh/404.html +++ b/zh/404.html @@ -287,6 +287,26 @@ + + + + + + + +
    199. + + + + + 社区 + + +
    200. + + + + @@ -2403,6 +2423,95 @@ + + + + + + + + + + + + + + + + +
    201. + + + + + + + + + + + + +
    202. + + + diff --git a/zh/AIPyApp/index.html b/zh/AIPyApp/index.html index 354e0ac..bd61acf 100644 --- a/zh/AIPyApp/index.html +++ b/zh/AIPyApp/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    203. + + + + + 社区 + + +
    204. + + + + @@ -2605,6 +2625,95 @@ + + + + + + + + + + + + + + + + +
    205. + + + + + + + + + + + + +
    206. + + + diff --git a/zh/GraphicalInterface/index.html b/zh/GraphicalInterface/index.html index c9e8245..48e62bd 100644 --- a/zh/GraphicalInterface/index.html +++ b/zh/GraphicalInterface/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    207. + + + + + 社区 + + +
    208. + + + + @@ -2615,6 +2635,95 @@ + + + + + + + + + + + + + + + + +
    209. + + + + + + + + + + + + +
    210. + + + diff --git a/zh/Notebook/index.html b/zh/Notebook/index.html index 2a617b0..2e48758 100644 --- a/zh/Notebook/index.html +++ b/zh/Notebook/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    211. + + + + + 社区 + + +
    212. + + + + @@ -2521,6 +2541,95 @@ + + + + + + + + + + + + + + + + +
    213. + + + + + + + + + + + + +
    214. + + + diff --git a/zh/Ollama/index.html b/zh/Ollama/index.html index 9645273..1822f55 100644 --- a/zh/Ollama/index.html +++ b/zh/Ollama/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    215. + + + + + 社区 + + +
    216. + + + + @@ -2610,6 +2630,95 @@ + + + + + + + + + + + + + + + + +
    217. + + + + + + + + + + + + +
    218. + + + diff --git a/zh/Terminal/index.html b/zh/Terminal/index.html index 8e698bc..a7edcb0 100644 --- a/zh/Terminal/index.html +++ b/zh/Terminal/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    219. + + + + + 社区 + + +
    220. + + + + @@ -2666,6 +2686,95 @@ + + + + + + + + + + + + + + + + +
    221. + + + + + + + + + + + + +
    222. + + + diff --git a/zh/community/index.html b/zh/community/index.html new file mode 100644 index 0000000..a4faac9 --- /dev/null +++ b/zh/community/index.html @@ -0,0 +1,2920 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + 概览 - QPython + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + +
      + + + + +
      + + +
      + +
      + + + + + + + + + +
      +
      + + + +
      +
      +
      + + + + + + + +
      +
      +
      + + + + + + + +
      + +
      + + + + + +

      社区

      +

      QPython 拥有一个活跃的技术社区,为开发者提供编程学习相关的交流、分享和互助的平台。

      +

      加入社区

      +

      QPython公众号 - 编程学习资料分享

      +

      专注于QPython移动端开发与Python全栈技术。内容涵盖: +- ① 基础语法与进阶技巧; +- ② 趣味实战项目(爬虫、数据分析、自动化); +- ③ 编程思维与学习方法。 +定期更新,系统化学习,帮你构建完整的Python知识图谱。

      +

      QPython微信公众号

      +

      QPython B站

      +

      专注手机编程实战教学。用QPython在手机上轻松学Python,零基础也能跟上! +- ① 手把手实操演示 +- ② 趣味实战项目(爬虫/自动化/小工具) +- ③ 避坑指南与技巧分享 +有问必答,欢迎评论区交流,一起在手机上玩转Python!

      +
        +
      • B站 – 访问QPython B站
      • +
      +

      QPython QQ论坛

      +

      专注于QPython移动端开发与Python全栈技术,为开发者提供一个作品展示、行业交流、技术沉淀的高质量交流空间。 包括以下栏目:行业资讯、技术交流、项目案例、BUG反馈。

      + +

      QPython微信群 & QQ群

      +

      QPython微信用户群群定位:QPython使用交流 | Python学习互助 | 实战问题解答,添加助手后会邀您加入

      + + + + + + + + + + + + + +
      微信群(助手: learnwithqpy)QQ群(群号: 862351102)
      QPython微信社区助手QPython QQ群
      +

      QPython 知识星球 VIP社区

      +

      QPython官方付费VIP专属社区,为深度用户提供官方团队直连、及时技术支持、高质量交流的专属服务空间。加入VIP社区可获下列核心价值:

      +
        +
      • 🎯 官方团队直连 —— QPython开发团队在线答疑,遇到问题不再卡壳,技术难题快速响应
      • +
      • 🚀 优先技术支持 —— VIP用户专属通道,比公开渠道更快获得官方解答
      • +
      • 💡 深度交流圈子 —— 与核心用户、资深开发者同行,探讨高阶技巧与项目实战 +QPython知识星球VIP社区
      • +
      +
      +

      QPython 团队会定期在社区中更新项目进展,欢迎关注!

      + + + + + + + + + + + + + + + +
      +
      + + + +
      + +
      + +
      + + +
      + +
      +
      +
      +
      + + + + + + + + + + + + + \ No newline at end of file diff --git a/zh/editor-guide/index.html b/zh/editor-guide/index.html index 5b14a2e..9e3b4a9 100644 --- a/zh/editor-guide/index.html +++ b/zh/editor-guide/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    223. + + + + + 社区 + + +
    224. + + + + @@ -2499,6 +2519,95 @@ + + + + + + + + + + + + + + + + +
    225. + + + + + + + + + + + + +
    226. + + + diff --git a/zh/external-api/index.html b/zh/external-api/index.html index 1ea44b8..8771378 100644 --- a/zh/external-api/index.html +++ b/zh/external-api/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    227. + + + + + 社区 + + +
    228. + + + + @@ -2488,6 +2508,95 @@ + + + + + + + + + + + + + + + + +
    229. + + + + + + + + + + + + +
    230. + + + diff --git a/zh/getting-started/index.html b/zh/getting-started/index.html index 2ddea92..a8b0f16 100644 --- a/zh/getting-started/index.html +++ b/zh/getting-started/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    231. + + + + + 社区 + + +
    232. + + + + @@ -2744,6 +2764,95 @@ + + + + + + + + + + + + + + + + +
    233. + + + + + + + + + + + + +
    234. + + + diff --git a/zh/index.html b/zh/index.html index a337a30..462ff38 100644 --- a/zh/index.html +++ b/zh/index.html @@ -298,6 +298,26 @@ + + + + + + + +
    235. + + + + + 社区 + + +
    236. + + + + @@ -2530,6 +2550,95 @@ + + + + + + + + + + + + + + + + +
    237. + + + + + + + + + + + + +
    238. + + + diff --git a/zh/qpypi-guide/index.html b/zh/qpypi-guide/index.html index 16f8143..9c79c13 100644 --- a/zh/qpypi-guide/index.html +++ b/zh/qpypi-guide/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    239. + + + + + 社区 + + +
    240. + + + + @@ -2527,6 +2547,95 @@ + + + + + + + + + + + + + + + + +
    241. + + + + + + + + + + + + +
    242. + + + diff --git a/zh/qpython-x/index.html b/zh/qpython-x/index.html index 9fe8fa7..f247895 100644 --- a/zh/qpython-x/index.html +++ b/zh/qpython-x/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    243. + + + + + 社区 + + +
    244. + + + + @@ -2499,6 +2519,95 @@ + + + + + + + + + + + + + + + + +
    245. + + + + + + + + + + + + +
    246. + + + diff --git a/zh/qsl4a/connectivity/contacts/index.html b/zh/qsl4a/connectivity/contacts/index.html index 439448e..28e1425 100644 --- a/zh/qsl4a/connectivity/contacts/index.html +++ b/zh/qsl4a/connectivity/contacts/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    247. + + + + + 社区 + + +
    248. + + + + @@ -2651,6 +2671,95 @@ + + + + + + + + + + + + + + + + +
    249. + + + + + + + + + + + + +
    250. + + + diff --git a/zh/qsl4a/connectivity/ftp/index.html b/zh/qsl4a/connectivity/ftp/index.html index 21a6c4b..48ae137 100644 --- a/zh/qsl4a/connectivity/ftp/index.html +++ b/zh/qsl4a/connectivity/ftp/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    251. + + + + + 社区 + + +
    252. + + + + @@ -2584,6 +2604,95 @@ + + + + + + + + + + + + + + + + +
    253. + + + + + + + + + + + + +
    254. + + + diff --git a/zh/qsl4a/connectivity/location/index.html b/zh/qsl4a/connectivity/location/index.html index e5d350e..674407d 100644 --- a/zh/qsl4a/connectivity/location/index.html +++ b/zh/qsl4a/connectivity/location/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    255. + + + + + 社区 + + +
    256. + + + + @@ -2623,6 +2643,95 @@ + + + + + + + + + + + + + + + + +
    257. + + + + + + + + + + + + +
    258. + + + diff --git a/zh/qsl4a/connectivity/phone/index.html b/zh/qsl4a/connectivity/phone/index.html index 0399faa..4b28ad9 100644 --- a/zh/qsl4a/connectivity/phone/index.html +++ b/zh/qsl4a/connectivity/phone/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    259. + + + + + 社区 + + +
    260. + + + + @@ -2934,6 +2954,95 @@ + + + + + + + + + + + + + + + + +
    261. + + + + + + + + + + + + +
    262. + + + diff --git a/zh/qsl4a/connectivity/signalstrength/index.html b/zh/qsl4a/connectivity/signalstrength/index.html index 19e4c16..aa6b617 100644 --- a/zh/qsl4a/connectivity/signalstrength/index.html +++ b/zh/qsl4a/connectivity/signalstrength/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    263. + + + + + 社区 + + +
    264. + + + + @@ -2573,6 +2593,95 @@ + + + + + + + + + + + + + + + + +
    265. + + + + + + + + + + + + +
    266. + + + diff --git a/zh/qsl4a/connectivity/sms/index.html b/zh/qsl4a/connectivity/sms/index.html index 29a1a72..8926818 100644 --- a/zh/qsl4a/connectivity/sms/index.html +++ b/zh/qsl4a/connectivity/sms/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    267. + + + + + 社区 + + +
    268. + + + + @@ -2606,6 +2626,95 @@ + + + + + + + + + + + + + + + + +
    269. + + + + + + + + + + + + +
    270. + + + diff --git a/zh/qsl4a/connectivity/wifi/index.html b/zh/qsl4a/connectivity/wifi/index.html index 5864ca2..4effc27 100644 --- a/zh/qsl4a/connectivity/wifi/index.html +++ b/zh/qsl4a/connectivity/wifi/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    271. + + + + + 社区 + + +
    272. + + + + @@ -2723,6 +2743,95 @@ + + + + + + + + + + + + + + + + +
    273. + + + + + + + + + + + + +
    274. + + + diff --git a/zh/qsl4a/core/android-base/index.html b/zh/qsl4a/core/android-base/index.html index cd98dc0..675398d 100644 --- a/zh/qsl4a/core/android-base/index.html +++ b/zh/qsl4a/core/android-base/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    275. + + + + + 社区 + + +
    276. + + + + @@ -2679,6 +2699,95 @@ + + + + + + + + + + + + + + + + +
    277. + + + + + + + + + + + + +
    278. + + + diff --git a/zh/qsl4a/core/events/index.html b/zh/qsl4a/core/events/index.html index eb6bb7c..62c3c02 100644 --- a/zh/qsl4a/core/events/index.html +++ b/zh/qsl4a/core/events/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    279. + + + + + 社区 + + +
    280. + + + + @@ -2806,6 +2826,95 @@ + + + + + + + + + + + + + + + + +
    281. + + + + + + + + + + + + +
    282. + + + diff --git a/zh/qsl4a/core/intent/index.html b/zh/qsl4a/core/intent/index.html index 5f7abe7..76f4f29 100644 --- a/zh/qsl4a/core/intent/index.html +++ b/zh/qsl4a/core/intent/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    283. + + + + + 社区 + + +
    284. + + + + @@ -2899,6 +2919,95 @@ + + + + + + + + + + + + + + + + +
    285. + + + + + + + + + + + + +
    286. + + + diff --git a/zh/qsl4a/hardware/bluetooth/index.html b/zh/qsl4a/hardware/bluetooth/index.html index f86f8dd..0a7d78e 100644 --- a/zh/qsl4a/hardware/bluetooth/index.html +++ b/zh/qsl4a/hardware/bluetooth/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    287. + + + + + 社区 + + +
    288. + + + + @@ -2789,6 +2809,95 @@ + + + + + + + + + + + + + + + + +
    289. + + + + + + + + + + + + +
    290. + + + diff --git a/zh/qsl4a/hardware/camera/index.html b/zh/qsl4a/hardware/camera/index.html index 154c6df..79fe733 100644 --- a/zh/qsl4a/hardware/camera/index.html +++ b/zh/qsl4a/hardware/camera/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    291. + + + + + 社区 + + +
    292. + + + + @@ -2712,6 +2732,95 @@ + + + + + + + + + + + + + + + + +
    293. + + + + + + + + + + + + +
    294. + + + diff --git a/zh/qsl4a/hardware/recorder/index.html b/zh/qsl4a/hardware/recorder/index.html index aa92ef0..cd3ffb6 100644 --- a/zh/qsl4a/hardware/recorder/index.html +++ b/zh/qsl4a/hardware/recorder/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    295. + + + + + 社区 + + +
    296. + + + + @@ -2640,6 +2660,95 @@ + + + + + + + + + + + + + + + + +
    297. + + + + + + + + + + + + +
    298. + + + diff --git a/zh/qsl4a/hardware/usbserial/index.html b/zh/qsl4a/hardware/usbserial/index.html index f295aaa..b48a7d1 100644 --- a/zh/qsl4a/hardware/usbserial/index.html +++ b/zh/qsl4a/hardware/usbserial/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    299. + + + + + 社区 + + +
    300. + + + + @@ -2667,6 +2687,95 @@ + + + + + + + + + + + + + + + + +
    301. + + + + + + + + + + + + +
    302. + + + diff --git a/zh/qsl4a/hardware/webcam/index.html b/zh/qsl4a/hardware/webcam/index.html index 94ff13c..0fb8423 100644 --- a/zh/qsl4a/hardware/webcam/index.html +++ b/zh/qsl4a/hardware/webcam/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    303. + + + + + 社区 + + +
    304. + + + + @@ -2590,6 +2610,95 @@ + + + + + + + + + + + + + + + + +
    305. + + + + + + + + + + + + +
    306. + + + diff --git a/zh/qsl4a/index.html b/zh/qsl4a/index.html index 406b9db..d0ba64b 100644 --- a/zh/qsl4a/index.html +++ b/zh/qsl4a/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    307. + + + + + 社区 + + +
    308. + + + + @@ -2617,6 +2637,95 @@ + + + + + + + + + + + + + + + + +
    309. + + + + + + + + + + + + +
    310. + + + diff --git a/zh/qsl4a/media/image/index.html b/zh/qsl4a/media/image/index.html index db84f1c..a49b9f9 100644 --- a/zh/qsl4a/media/image/index.html +++ b/zh/qsl4a/media/image/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    311. + + + + + 社区 + + +
    312. + + + + @@ -2613,6 +2633,95 @@ + + + + + + + + + + + + + + + + +
    313. + + + + + + + + + + + + +
    314. + + + diff --git a/zh/qsl4a/media/mediaplayer/index.html b/zh/qsl4a/media/mediaplayer/index.html index 95d6292..06d6379 100644 --- a/zh/qsl4a/media/mediaplayer/index.html +++ b/zh/qsl4a/media/mediaplayer/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    315. + + + + + 社区 + + +
    316. + + + + @@ -2723,6 +2743,95 @@ + + + + + + + + + + + + + + + + +
    317. + + + + + + + + + + + + +
    318. + + + diff --git a/zh/qsl4a/special/cipher/index.html b/zh/qsl4a/special/cipher/index.html index 1707eea..3749c05 100644 --- a/zh/qsl4a/special/cipher/index.html +++ b/zh/qsl4a/special/cipher/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    319. + + + + + 社区 + + +
    320. + + + + @@ -2662,6 +2682,95 @@ + + + + + + + + + + + + + + + + +
    321. + + + + + + + + + + + + +
    322. + + + diff --git a/zh/qsl4a/special/pgptai/index.html b/zh/qsl4a/special/pgptai/index.html index 8e42926..a6a47e9 100644 --- a/zh/qsl4a/special/pgptai/index.html +++ b/zh/qsl4a/special/pgptai/index.html @@ -16,6 +16,8 @@ + + @@ -298,6 +300,26 @@ + + + + + + + +
    323. + + + + + 社区 + + +
    324. + + + + @@ -2588,6 +2610,95 @@ + + + + + + + + + + + + + + + + +
    325. + + + + + + + + + + + + +
    326. + + + diff --git a/zh/qsl4a/storage/clipboard/index.html b/zh/qsl4a/storage/clipboard/index.html index c74580b..13cfcf8 100644 --- a/zh/qsl4a/storage/clipboard/index.html +++ b/zh/qsl4a/storage/clipboard/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    327. + + + + + 社区 + + +
    328. + + + + @@ -2540,6 +2560,95 @@ + + + + + + + + + + + + + + + + +
    329. + + + + + + + + + + + + +
    330. + + + diff --git a/zh/qsl4a/storage/documentfile/index.html b/zh/qsl4a/storage/documentfile/index.html index ac7508f..f6a938e 100644 --- a/zh/qsl4a/storage/documentfile/index.html +++ b/zh/qsl4a/storage/documentfile/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    331. + + + + + 社区 + + +
    332. + + + + @@ -2751,6 +2771,95 @@ + + + + + + + + + + + + + + + + +
    333. + + + + + + + + + + + + +
    334. + + + diff --git a/zh/qsl4a/storage/preferences/index.html b/zh/qsl4a/storage/preferences/index.html index cc86297..194bbbd 100644 --- a/zh/qsl4a/storage/preferences/index.html +++ b/zh/qsl4a/storage/preferences/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    335. + + + + + 社区 + + +
    336. + + + + @@ -2562,6 +2582,95 @@ + + + + + + + + + + + + + + + + +
    337. + + + + + + + + + + + + +
    338. + + + diff --git a/zh/qsl4a/system/activityresult/index.html b/zh/qsl4a/system/activityresult/index.html index 86092b1..4b8a875 100644 --- a/zh/qsl4a/system/activityresult/index.html +++ b/zh/qsl4a/system/activityresult/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    339. + + + + + 社区 + + +
    340. + + + + @@ -2727,6 +2747,95 @@ + + + + + + + + + + + + + + + + +
    341. + + + + + + + + + + + + +
    342. + + + diff --git a/zh/qsl4a/system/application/index.html b/zh/qsl4a/system/application/index.html index 884cf13..4a6d3d2 100644 --- a/zh/qsl4a/system/application/index.html +++ b/zh/qsl4a/system/application/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    343. + + + + + 社区 + + +
    344. + + + + @@ -2868,6 +2888,95 @@ + + + + + + + + + + + + + + + + +
    345. + + + + + + + + + + + + +
    346. + + + diff --git a/zh/qsl4a/system/battery/index.html b/zh/qsl4a/system/battery/index.html index 4203133..265264e 100644 --- a/zh/qsl4a/system/battery/index.html +++ b/zh/qsl4a/system/battery/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    347. + + + + + 社区 + + +
    348. + + + + @@ -2595,6 +2615,95 @@ + + + + + + + + + + + + + + + + +
    349. + + + + + + + + + + + + +
    350. + + + diff --git a/zh/qsl4a/system/qpyinterface/index.html b/zh/qsl4a/system/qpyinterface/index.html index b570620..1a045bf 100644 --- a/zh/qsl4a/system/qpyinterface/index.html +++ b/zh/qsl4a/system/qpyinterface/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    351. + + + + + 社区 + + +
    352. + + + + @@ -2623,6 +2643,95 @@ + + + + + + + + + + + + + + + + +
    353. + + + + + + + + + + + + +
    354. + + + diff --git a/zh/qsl4a/system/sensors/index.html b/zh/qsl4a/system/sensors/index.html index 374d7c5..a2faadc 100644 --- a/zh/qsl4a/system/sensors/index.html +++ b/zh/qsl4a/system/sensors/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    355. + + + + + 社区 + + +
    356. + + + + @@ -2639,6 +2659,95 @@ + + + + + + + + + + + + + + + + +
    357. + + + + + + + + + + + + +
    358. + + + diff --git a/zh/qsl4a/system/settings/index.html b/zh/qsl4a/system/settings/index.html index fc13900..21a131b 100644 --- a/zh/qsl4a/system/settings/index.html +++ b/zh/qsl4a/system/settings/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    359. + + + + + 社区 + + +
    360. + + + + @@ -2795,6 +2815,95 @@ + + + + + + + + + + + + + + + + +
    361. + + + + + + + + + + + + +
    362. + + + diff --git a/zh/qsl4a/system/sysinfo/index.html b/zh/qsl4a/system/sysinfo/index.html index 9cceba8..9138d5a 100644 --- a/zh/qsl4a/system/sysinfo/index.html +++ b/zh/qsl4a/system/sysinfo/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    363. + + + + + 社区 + + +
    364. + + + + @@ -2646,6 +2666,95 @@ + + + + + + + + + + + + + + + + +
    365. + + + + + + + + + + + + +
    366. + + + diff --git a/zh/qsl4a/system/wakelock/index.html b/zh/qsl4a/system/wakelock/index.html index b77fd55..a992d08 100644 --- a/zh/qsl4a/system/wakelock/index.html +++ b/zh/qsl4a/system/wakelock/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    367. + + + + + 社区 + + +
    368. + + + + @@ -2584,6 +2604,95 @@ + + + + + + + + + + + + + + + + +
    369. + + + + + + + + + + + + +
    370. + + + diff --git a/zh/qsl4a/ui/accessibility/index.html b/zh/qsl4a/ui/accessibility/index.html index 79541c7..cac682d 100644 --- a/zh/qsl4a/ui/accessibility/index.html +++ b/zh/qsl4a/ui/accessibility/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    371. + + + + + 社区 + + +
    372. + + + + @@ -2657,6 +2677,95 @@ + + + + + + + + + + + + + + + + +
    373. + + + + + + + + + + + + +
    374. + + + diff --git a/zh/qsl4a/ui/dialogs/index.html b/zh/qsl4a/ui/dialogs/index.html index 5a25c6e..471c804 100644 --- a/zh/qsl4a/ui/dialogs/index.html +++ b/zh/qsl4a/ui/dialogs/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    375. + + + + + 社区 + + +
    376. + + + + @@ -2989,6 +3009,95 @@ + + + + + + + + + + + + + + + + +
    377. + + + + + + + + + + + + +
    378. + + + diff --git a/zh/qsl4a/ui/floatview/index.html b/zh/qsl4a/ui/floatview/index.html index c2264d0..ff88802 100644 --- a/zh/qsl4a/ui/floatview/index.html +++ b/zh/qsl4a/ui/floatview/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    379. + + + + + 社区 + + +
    380. + + + + @@ -2634,6 +2654,95 @@ + + + + + + + + + + + + + + + + +
    381. + + + + + + + + + + + + +
    382. + + + diff --git a/zh/qsl4a/ui/fullscreen/index.html b/zh/qsl4a/ui/fullscreen/index.html index 5e958e2..dc0700a 100644 --- a/zh/qsl4a/ui/fullscreen/index.html +++ b/zh/qsl4a/ui/fullscreen/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    383. + + + + + 社区 + + +
    384. + + + + @@ -2712,6 +2732,95 @@ + + + + + + + + + + + + + + + + +
    385. + + + + + + + + + + + + +
    386. + + + diff --git a/zh/search/search_index.json b/zh/search/search_index.json index 07c93b3..4b00765 100644 --- a/zh/search/search_index.json +++ b/zh/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"QPython \u9879\u76ee","text":"

      QPython \u4e0d\u4ec5\u662f\u4e00\u4e2a\u5f3a\u5927\u7684 Android Python IDE\uff0c\u4e5f\u662f\u4e00\u4e2a\u6d3b\u8dc3\u7684\u6280\u672f\u793e\u533a\u3002

      "},{"location":"#ai-android-python-ide","title":"\u652f\u6301 AI \u7684 Android Python IDE","text":"

      QPython \u662f\u60a8\u8fdb\u884c Android Python \u7f16\u7a0b\u7684\u5165\u53e3\u3002\u5b83\u96c6\u6210\u4e86 Python \u89e3\u91ca\u5668\u3001AI \u6a21\u578b\u5f15\u64ce\u548c\u79fb\u52a8\u5f00\u53d1\u5de5\u5177\u94fe\uff0c\u8ba9\u60a8\u80fd\u591f\u4ece\u79fb\u52a8\u8bbe\u5907\u6784\u5efa Web \u5e94\u7528\u7a0b\u5e8f\u3001\u6267\u884c\u79d1\u5b66\u8ba1\u7b97\u548c\u521b\u5efa\u667a\u80fd\u5e94\u7528\u3002

      \u65e0\u8bba\u60a8\u662f\u5728\u5b66\u4e60\u7f16\u7a0b\u3001\u6784\u5efa\u6570\u636e\u79d1\u5b66\u9879\u76ee\uff0c\u8fd8\u662f\u5f00\u53d1 AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f\uff0cQPython \u90fd\u63d0\u4f9b\u4e86\u5b8c\u6574\u7684\u79fb\u52a8\u7f16\u7a0b\u89e3\u51b3\u65b9\u6848\uff0c\u62e5\u6709\u5168\u9762\u7684\u5f00\u53d1\u8005\u8d44\u6e90\u548c\u6d3b\u8dc3\u7684\u793e\u533a\u6765\u652f\u6301\u60a8\u7684\u65c5\u7a0b\u3002

      • \u5206\u652f\u7248\u672c \u2013 \u4e86\u89e3\u4e0d\u540c\u7684 QPython \u7248\u672c\uff08IDE\u3001\u793e\u533a\u7248\u3001Plus\uff09\uff0c\u9009\u62e9\u9002\u5408\u60a8\u9700\u6c42\u7684\u7248\u672c
      • \u66f4\u65b0\u65e5\u5fd7 \u2013 \u968f\u65f6\u4e86\u89e3\u6700\u65b0\u529f\u80fd\u3001\u6539\u8fdb\u548c\u53d1\u884c\u8bf4\u660e
      "},{"location":"#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"

      \u5982\u4f55\u5feb\u901f\u5165\u95e8\uff1f\u8bf7\u6309\u7167\u4ee5\u4e0b\u6b65\u9aa4\uff1a

      • \u5feb\u901f\u5165\u95e8
      • Hello World \u6559\u7a0b
      "},{"location":"#_2","title":"\u7f16\u7a0b\u6307\u5357","text":"

      QPython \u4e0d\u4ec5\u63d0\u4f9b\u57fa\u7840\u7684 Python \u63a5\u53e3\u652f\u6301\uff0c\u66f4\u91cd\u8981\u7684\u662f\uff0c\u5b83\u8fd8\u5141\u8bb8\u60a8\u901a\u8fc7 QSL4A \u63a5\u53e3\u4f7f\u7528 Python \u8c03\u7528 Android API\u3002

      • Python \u6807\u51c6\u5e93 \u2013 \u901a\u7528\u7684 Python \u8bed\u6cd5\u548c\u5185\u7f6e\u5e93
      • QSL4A API \u2013 \u4ece Python \u8bbf\u95ee Android \u8bbe\u5907\u529f\u80fd\uff08\u76f8\u673a\u3001\u4f20\u611f\u5668\u3001\u77ed\u4fe1\u7b49\uff09
      • QPYPI \u6307\u5357 \u2013 \u5b89\u88c5\u989d\u5916\u7684 Python \u5305
      • \u7f16\u8f91\u5668\u6307\u5357 \u2013 \u4f7f\u7528\u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668
      • \u5916\u90e8 API \u2013 \u4e0e\u5916\u90e8\u5e94\u7528\u7a0b\u5e8f\u96c6\u6210
      "},{"location":"#_3","title":"\u4e0b\u8f7d\u8d44\u6e90","text":"
      • Google Drive
      • \u5fae\u4fe1\u7f51\u76d8
      "},{"location":"#_4","title":"\u793e\u533a\u4e0e\u53cd\u9988","text":"
      • \u4e2d\u6587\u4ea4\u6d41\u793e\u533a
      • \u767e\u5ea6\u8d34\u5427
      • \u95ee\u9898\u53cd\u9988
      • \u529f\u80fd\u6269\u5c55\u8bf7\u6c42
      "},{"location":"#_5","title":"\u5173\u6ce8\u6211\u4eec","text":"
      • B\u7ad9
      • Weibo
      "},{"location":"AIPyApp/","title":"AIPyApp - AI\u9a71\u52a8\u7684\u7a0b\u5e8f\u751f\u6210\u5668","text":"

      AIPyApp \u662f QPython \u4e2d\u7684\u667a\u80fd\u5de5\u5177\uff0c\u53ef\u4ee5\u5229\u7528 AI \u4ece\u81ea\u7136\u8bed\u8a00\u6307\u4ee4\u81ea\u52a8\u751f\u6210 Python \u7a0b\u5e8f\u3002

      "},{"location":"AIPyApp/#_1","title":"\u6982\u8ff0","text":"

      AIPyApp \u6539\u53d8\u4e86\u60a8\u7f16\u5199\u4ee3\u7801\u7684\u65b9\u5f0f\u2014\u2014\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u63cf\u8ff0\u60a8\u60f3\u8981\u7684\u529f\u80fd\uff0cAI \u5c31\u4f1a\u4e3a\u60a8\u751f\u6210 Python \u7a0b\u5e8f\u3002QPython \u8fd8\u5c06\u63a8\u51fa AIPy Academy\u2014\u2014\u4e00\u4e2a\u4e3a AI \u65f6\u4ee3\u91cf\u8eab\u5b9a\u5236\u7684 Python \u7f16\u7a0b\u8bfe\u7a0b\u5e73\u53f0\u3002

      "},{"location":"AIPyApp/#_2","title":"\u5b89\u88c5","text":"

      QPython \u6c1b\u56f4\u7f16\u7a0b\uff08Vibe Coding\uff09 01 - \u5982\u4f55\u542f\u7528AIPyApp

      "},{"location":"AIPyApp/#_3","title":"\u7b2c\u4e00\u6b65\uff1a\u4ece\u4eea\u8868\u76d8\u542f\u52a8","text":"
      1. \u6253\u5f00 QPython\uff0c\u8fdb\u5165 \u4eea\u8868\u76d8
      2. \u957f\u6309\u5f00\u59cb\u6309\u94ae

      \u5982\u679c\u672a\u5b89\u88c5 AIPyApp\uff0c\u7cfb\u7edf\u4f1a\u63d0\u793a\u60a8\u786e\u8ba4\u5b89\u88c5\u3002\u6309 \u56de\u8f66\u952e\u7ee7\u7eed\u3002

      QPython \u5c06\u81ea\u52a8\u4ece PYPI \u4e0b\u8f7d\u5e76\u5b89\u88c5\u6240\u9700\u7684\u4f9d\u8d56\u9879\u3002\u8bf7\u8010\u5fc3\u7b49\u5f85\u5b89\u88c5\u5b8c\u6210\u3002

      "},{"location":"AIPyApp/#aipyapp","title":"\u7b2c\u4e8c\u6b65\uff1a\u91cd\u65b0\u542f\u52a8 AIPyApp","text":"

      \u5b89\u88c5\u5b8c\u6210\u540e\uff0c\u8fd4\u56de QPython \u4eea\u8868\u76d8\uff0c\u518d\u6b21 \u957f\u6309\u5f00\u59cb\u6309\u94ae\u542f\u52a8 AIPyApp\u3002

      "},{"location":"AIPyApp/#_4","title":"\u914d\u7f6e","text":""},{"location":"AIPyApp/#ai","title":"\u8bbe\u7f6e\u60a8\u7684 AI \u5bc6\u94a5","text":"

      \u9996\u6b21\u542f\u52a8\u65f6\uff0c\u60a8\u9700\u8981\u63d0\u4f9b AI API \u5bc6\u94a5\uff1a

      1. \u5728 PGPT \u6ce8\u518c\uff1a\u5728 https://user.pgpt.cloud \u521b\u5efa\u8d26\u6237\u4ee5\u751f\u6210\u60a8\u7684 AI \u5bc6\u94a5
      2. \u9ad8\u7ea7\u9009\u9879\uff1aAIPyApp \u8fd8\u652f\u6301\u6765\u81ea OpenAI\u3001Deepseek \u548c\u5176\u4ed6\u63d0\u4f9b\u5546\u7684\u81ea\u5b9a\u4e49 AI \u5bc6\u94a5\uff08\u8be6\u89c1\u9ad8\u7ea7\u6559\u7a0b\uff09
      "},{"location":"AIPyApp/#ai_1","title":"\u8f93\u5165\u60a8\u7684 AI \u5bc6\u94a5","text":"
      1. \u957f\u6309\u8f93\u5165\u63d0\u793a
      2. \u4ece\u5f39\u51fa\u83dc\u5355\u4e2d\u9009\u62e9 \u7c98\u8d34
      3. \u6309 \u56de\u8f66\u952e\u786e\u8ba4

      \u60a8\u7684 AI \u5bc6\u94a5\u5c06\u4fdd\u5b58\u4ee5\u4f9b\u540e\u7eed\u4f1a\u8bdd\u4f7f\u7528\u3002

      "},{"location":"AIPyApp/#aipyapp_1","title":"\u4f7f\u7528 AIPyApp","text":"

      \u914d\u7f6e\u5b8c\u6210\u540e\uff0c\u60a8\u5c06\u8fdb\u5165 AIPyApp \u63a7\u5236\u53f0\u6a21\u5f0f\u3002\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u8f93\u5165\u60a8\u7684\u6307\u4ee4\u5373\u53ef\uff01

      "},{"location":"AIPyApp/#_5","title":"\u793a\u4f8b\u547d\u4ee4","text":"

      \u5c1d\u8bd5\u8f93\u5165\uff1a

      \u4f7f\u7528 QSL4A \u521b\u5efa\u4e00\u4e2a HELLO QPY \u7a0b\u5e8f\u4f5c\u4e3a\u6f14\u793a\n

      AIPyApp \u5c06\uff1a 1. \u7406\u89e3\u60a8\u7684\u81ea\u7136\u8bed\u8a00\u8bf7\u6c42 2. \u751f\u6210\u76f8\u5e94\u7684 Python \u4ee3\u7801 3. \u81ea\u52a8\u6267\u884c\u7a0b\u5e8f

      \u5c31\u662f\u8fd9\u6837\u2014\u2014\u60a8\u65e0\u9700\u7f16\u5199\u4efb\u4f55\u4ee3\u7801\u5c31\u521b\u5efa\u4e86\u4e00\u4e2a\u53ef\u8fd0\u884c\u7684 Python \u7a0b\u5e8f\uff01

      "},{"location":"AIPyApp/#_6","title":"\u6f14\u793a\u89c6\u9891","text":"

      QPython \u6c1b\u56f4\u7f16\u7a0b\uff08Vibe Coding\uff09 02 - \u4f7f\u7528\u81ea\u7136\u8bed\u8a00\u5f00\u53d1\u4e00\u4e2a\u7ffb\u8bd1App

      \u4e0a\u9762\u7684\u793a\u4f8b\u6f14\u793a\u4e86 AIPyApp \u5982\u4f55\uff1a - \u7406\u89e3\u4e2d\u6587\u6307\u4ee4 - \u751f\u6210\u57fa\u4e8e QSL4A \u7684 Python \u4ee3\u7801 - \u7acb\u5373\u8fd0\u884c\u7a0b\u5e8f

      \u63a2\u7d22 AIPyApp \u4ee5\u53d1\u73b0\u66f4\u591a\u529f\u80fd\uff0c\u5f00\u59cb\u8f7b\u677e\u6784\u5efa Python \u7a0b\u5e8f\u3002

      "},{"location":"AIPyApp/#_7","title":"\u8bfe\u7a0b\u63a8\u8350","text":"

      \u672b\u5c3e\uff0c\u7ed9\u5927\u5bb6\u63a8\u8350\u4e0b\u9762\u8bfe\u7a0b\uff1a

      \u300a\u4e0eAI\u534f\u4f5c\u7684Python\u7f16\u7a0b\u5165\u95e8\u300b \u2014 \u7531QPython\u5b98\u65b9\u56e2\u961f\u7cbe\u5fc3\u6253\u9020\u5e76\u63d0\u4f9b\u6559\u5b66\u652f\u6301\uff0c\u80fd\u5e2e\u52a9\u5b66\u4e60\u8005\u5feb\u901f\u3001\u4f53\u7cfb\u5316\u5730\u638c\u63e1Python\u5f00\u53d1\u4ee5\u53ca\u5728AI\u65f6\u4ee3\u66f4\u597d\u5730\u5b66\u4e60\u4f7f\u7528AI\u3002

      \u4e86\u89e3\u8be6\u60c5

      "},{"location":"GraphicalInterface/","title":"\u56fe\u5f62\u754c\u9762\uff08Turtle \u548c Tkinter\uff09","text":"

      \u672c\u6307\u5357\u8bf4\u660e\u5982\u4f55\u5728 Android \u8bbe\u5907\u4e0a\u7684 QPython \u4e2d\u542f\u7528\u56fe\u5f62\u754c\u9762\u652f\u6301\uff08Turtle \u548c Tkinter\uff09\u3002

      "},{"location":"GraphicalInterface/#_1","title":"\u6982\u8ff0","text":"

      QPython \u53ef\u4ee5\u8fd0\u884c Turtle \u548c Tkinter \u5e94\u7528\u7a0b\u5e8f\uff0c\u4f46\u9700\u8981\u989d\u5916\u7684\u8f6f\u4ef6\u6765\u5728 Android \u4e0a\u63d0\u4f9b\u56fe\u5f62\u663e\u793a\u652f\u6301\u3002

      "},{"location":"GraphicalInterface/#_2","title":"\u524d\u63d0\u6761\u4ef6","text":"

      \u5f00\u59cb\u4e4b\u524d\uff0c\u60a8\u9700\u8981\u4e0b\u8f7d\u4ee5\u4e0b\u8d44\u6e90\uff1a

      1. Xserver.apk - \u63d0\u4f9b Turtle/Tkinter \u56fe\u5f62\u652f\u6301\u7684\u914d\u5957\u5e94\u7528
      2. \u4e0b\u8f7d\u5730\u5740\uff1aQPythonProject/Extra on Google Drive
      3. Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762\u6269\u5c55 - \u901a\u8fc7 QPython \u7684 QPYPI \u5b89\u88c5
      "},{"location":"GraphicalInterface/#_3","title":"\u5b89\u88c5\u6b65\u9aa4","text":""},{"location":"GraphicalInterface/#xserver","title":"\u7b2c\u4e00\u6b65\uff1a\u5b89\u88c5 Xserver","text":"

      \u4ece Google Drive \u7684 QPython Extra \u8d44\u6e90\u76ee\u5f55\u4e0b\u8f7d\u5e76\u5b89\u88c5 Xserver.apk\u3002

      "},{"location":"GraphicalInterface/#qpython","title":"\u7b2c\u4e8c\u6b65\uff1a\u5b89\u88c5 QPython \u6269\u5c55","text":"

      \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI\u3002\u627e\u5230\u5e76\u5b89\u88c5 Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762 \u6269\u5c55\u3002

      "},{"location":"GraphicalInterface/#xserver_1","title":"\u7b2c\u4e09\u6b65\uff1a\u914d\u7f6e Xserver \u7535\u6c60\u8bbe\u7f6e","text":"

      \u4e3a\u9632\u6b62 Xserver \u5728\u540e\u53f0\u8fd0\u884c\u65f6\u88ab\u6740\u6b7b\uff1a

      1. \u8fdb\u5165\u8bbe\u5907\u7684 \u8bbe\u7f6e > \u5e94\u7528 > Xserver
      2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
      3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u6216 \"\u4e0d\u9650\u5236\"

      \u8fd9\u53ef\u786e\u4fdd Xserver \u5728\u5207\u6362\u5230\u540e\u53f0\u65f6\u7ee7\u7eed\u8fd0\u884c\u3002

      "},{"location":"GraphicalInterface/#qpython_1","title":"\u7b2c\u56db\u6b65\uff1a\u914d\u7f6e QPython \u7535\u6c60\u8bbe\u7f6e\uff08\u63a8\u8350\uff09","text":"

      \u540c\u6837\uff0c\u5c06 QPython \u7684\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u4ee5\u9632\u6b62\u8fdb\u7a0b\u88ab\u7ec8\u6b62\uff1a

      1. \u8fdb\u5165 \u8bbe\u7f6e > \u5e94\u7528 > QPython
      2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
      3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\"
      "},{"location":"GraphicalInterface/#xserver_2","title":"\u7b2c\u4e94\u6b65\uff1a\u542f\u52a8 Xserver","text":"

      \u5728\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d\uff0c\u542f\u52a8 Xserver \u5e94\u7528\u5e76\u5c06\u5176\u5207\u6362\u4e3a\u540e\u53f0\u8fd0\u884c\u3002

      "},{"location":"GraphicalInterface/#turtletkinter","title":"\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f","text":"

      \u5b8c\u6210\u8bbe\u7f6e\u540e\uff1a

      1. \u786e\u4fdd Xserver \u5728\u540e\u53f0\u8fd0\u884c
      2. \u5728 QPython \u4e2d\u8fd0\u884c\u60a8\u7684 Turtle \u6216 Tkinter \u5e94\u7528\u7a0b\u5e8f
      3. \u5207\u6362\u5230 Xserver \u67e5\u770b\u56fe\u5f62\u8f93\u51fa
      "},{"location":"GraphicalInterface/#_4","title":"\u6f14\u793a\u7a0b\u5e8f","text":"

      \u60a8\u53ef\u4ee5\u4ece QPython \u5e94\u7528\u7684 QPYPI \u7b2c\u4e00\u4e2a\u6269\u5c55\u90e8\u5206\u4e0b\u8f7d\u5e76\u5c1d\u8bd5 Turtle \u753b\u54c6\u5566A\u68a6 \u6f14\u793a\u7a0b\u5e8f\u6765\u9a8c\u8bc1\u60a8\u7684\u8bbe\u7f6e\u3002

      "},{"location":"GraphicalInterface/#_5","title":"\u6f14\u793a\u89c6\u9891","text":""},{"location":"GraphicalInterface/#_6","title":"\u6545\u969c\u6392\u9664","text":"
      • \u9ed1\u5c4f\uff1a\u786e\u4fdd\u5728\u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d Xserver \u6b63\u5728\u8fd0\u884c
      • \u5e94\u7528\u7a0b\u5e8f\u5d29\u6e83\uff1a\u68c0\u67e5 QPython \u548c Xserver \u662f\u5426\u90fd\u8bbe\u7f6e\u4e86\u65e0\u9650\u5236\u7684\u7535\u6c60\u8bbe\u7f6e
      • \u65e0\u663e\u793a\uff1a\u9a8c\u8bc1 Turtle/Tkinter \u6269\u5c55\u662f\u5426\u901a\u8fc7 QPYPI \u6b63\u786e\u5b89\u88c5
      "},{"location":"GraphicalInterface/#_7","title":"\u8bfe\u7a0b\u63a8\u8350","text":"

      \u672b\u5c3e\uff0c\u7ed9\u5927\u5bb6\u63a8\u8350\u4e0b\u9762\u8bfe\u7a0b\uff1a

      \u300a\u4e0eAI\u534f\u4f5c\u7684Python\u7f16\u7a0b\u5165\u95e8\u300b \u2014 \u7531QPython\u5b98\u65b9\u56e2\u961f\u7cbe\u5fc3\u6253\u9020\u5e76\u63d0\u4f9b\u6559\u5b66\u652f\u6301\uff0c\u80fd\u5e2e\u52a9\u5b66\u4e60\u8005\u5feb\u901f\u3001\u4f53\u7cfb\u5316\u5730\u638c\u63e1Python\u5f00\u53d1\u4ee5\u53ca\u5728AI\u65f6\u4ee3\u66f4\u597d\u5730\u5b66\u4e60\u4f7f\u7528AI\u3002

      \u4e86\u89e3\u8be6\u60c5

      "},{"location":"Notebook/","title":"Notebook","text":"

      QPython \u96c6\u6210\u4e86 Jupyter Notebook\uff0c\u63d0\u4f9b\u4e86\u4e00\u4e2a\u5f3a\u5927\u7684\u4ea4\u4e92\u73af\u5883\uff0c\u53ef\u5728 Android \u8bbe\u5907\u4e0a\u8fdb\u884c\u6570\u636e\u79d1\u5b66\u3001\u79d1\u5b66\u8ba1\u7b97\u548c AI \u5f00\u53d1\u3002

      "},{"location":"Notebook/#_1","title":"\u6982\u8ff0","text":"

      QPython \u81ea\u5e26\u5185\u7f6e\u7684 Jupyter Notebook \u5e94\u7528\u7a0b\u5e8f\uff0c\u5141\u8bb8\u60a8\u76f4\u63a5\u5728 Android \u8bbe\u5907\u4e0a\u521b\u5efa\u548c\u8fd0\u884c\u4ea4\u4e92\u5f0f Python \u7b14\u8bb0\u672c\u3002\u754c\u9762\u548c\u64cd\u4f5c\u65b9\u5f0f\u4e0e\u6807\u51c6 Jupyter Notebook \u7c7b\u4f3c\u3002

      "},{"location":"Notebook/#_2","title":"\u53ef\u7528\u5e93","text":"

      QPython \u652f\u6301\u5e7f\u6cdb\u7684\u6570\u5b66\u3001\u79d1\u5b66\u548c AI \u76f8\u5173\u5e93\uff0c\u975e\u5e38\u9002\u5408 Notebook \u73af\u5883\u3002\u53ef\u6839\u636e\u9700\u8981\u901a\u8fc7 QPYPI \u5b89\u88c5\uff1a

      • Matplotlib - \u7ed8\u56fe\u548c\u53ef\u89c6\u5316
      • Seaborn - \u7edf\u8ba1\u6570\u636e\u53ef\u89c6\u5316
      • Pandas - \u6570\u636e\u5206\u6790\u4e0e\u5904\u7406
      • Numpy - \u6570\u503c\u8ba1\u7b97
      • Scipy - \u79d1\u5b66\u8ba1\u7b97
      • OpenCV - \u8ba1\u7b97\u673a\u89c6\u89c9\u548c\u56fe\u50cf\u5904\u7406
      • Sympy - \u7b26\u53f7\u6570\u5b66
      • mpmath - \u4efb\u610f\u7cbe\u5ea6\u7b97\u672f
      • Scikit-learn - \u673a\u5668\u5b66\u4e60
      • PyTorch - \u6df1\u5ea6\u5b66\u4e60\u6846\u67b6
      "},{"location":"Notebook/#_3","title":"\u83b7\u53d6\u5e2e\u52a9","text":"

      \u7531\u4e8e QPython \u7684 Notebook \u64cd\u4f5c\u65b9\u5f0f\u4e0e Jupyter Notebook \u7c7b\u4f3c\uff0c\u60a8\u53ef\u4ee5\u53c2\u8003\u5b98\u65b9\u7684 Jupyter Notebook \u6587\u6863 \u83b7\u53d6\u8be6\u7ec6\u7684\u4f7f\u7528\u8bf4\u660e\u548c\u6280\u5de7\u3002

      "},{"location":"Notebook/#_4","title":"\u5b89\u88c5","text":"

      \u5b89\u88c5\u60a8\u9700\u8981\u7684\u5e93\uff1a

      1. \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI
      2. \u641c\u7d22\u60a8\u60f3\u8981\u7684\u5e93\uff08\u4f8b\u5982 \"numpy\"\u3001\"pandas\"\uff09
      3. \u5b89\u88c5\u6240\u9700\u7684\u5305

      \u4ec5\u5b89\u88c5\u60a8\u7684\u7279\u5b9a\u7528\u4f8b\u6240\u9700\u7684\u5e93\u3002

      "},{"location":"Notebook/#_5","title":"\u4f7f\u7528\u65b9\u6cd5","text":"

      QPython \u4e2d\u7684 Notebook \u5e94\u7528\u7a0b\u5e8f\u63d0\u4f9b\uff1a

      • \u4ea4\u4e92\u5f0f\u4ee3\u7801\u5355\u5143 - \u7f16\u5199\u548c\u6267\u884c Python \u4ee3\u7801
      • Markdown \u5355\u5143 - \u6dfb\u52a0\u683c\u5f0f\u5316\u6587\u672c\u548c\u6587\u6863
      • \u5bcc\u8f93\u51fa - \u5185\u8054\u67e5\u770b\u56fe\u8868\u3001\u56fe\u5f62\u548c\u53ef\u89c6\u5316
      • \u6301\u4e45\u5316\u7b14\u8bb0\u672c - \u4fdd\u5b58\u548c\u91cd\u65b0\u52a0\u8f7d\u60a8\u7684\u5de5\u4f5c

      \u6709\u5173 Notebook \u64cd\u4f5c\u548c\u529f\u80fd\u7684\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\uff0c\u8bf7\u53c2\u9605 Jupyter Notebook \u6587\u6863\u3002

      "},{"location":"Ollama/","title":"Ollama - \u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u96c6\u6210","text":"

      Ollama \u662f\u4e00\u4e2a\u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u8fd0\u884c\u65f6\u6846\u67b6\uff0c\u652f\u6301\u5305\u62ec Deepseek\u3001Qwen \u548c Gemma \u5728\u5185\u7684\u591a\u79cd\u6a21\u578b\u3002QPython \u5185\u7f6e\u4e86 Ollama \u96c6\u6210\uff0c\u4f7f\u5f00\u53d1\u8005\u80fd\u591f\u76f4\u63a5\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u63a2\u7d22 GenAI \u5f00\u53d1\u3002

      "},{"location":"Ollama/#_1","title":"\u6982\u8ff0","text":"

      Ollama \u5141\u8bb8\u60a8\u5728 Android \u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5f3a\u5927\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b\u3002\u901a\u8fc7 QPython \u7684\u96c6\u6210\uff0c\u60a8\u53ef\u4ee5\uff1a

      • \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u8fd0\u884c\u5f00\u6e90 LLM
      • \u65e0\u9700\u4e92\u8054\u7f51\u8fde\u63a5\u5373\u53ef\u4f7f\u7528 AI \u529f\u80fd
      • \u9488\u5bf9\u4e0d\u540c\u7528\u4f8b\u5c1d\u8bd5\u4e0d\u540c\u7684\u6a21\u578b
      • \u4f7f\u7528\u719f\u6089\u7684 Python \u5e93\u6784\u5efa AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f
      "},{"location":"Ollama/#_2","title":"\u652f\u6301\u7684\u6a21\u578b","text":"

      Ollama \u652f\u6301\u591a\u79cd\u6d41\u884c\u7684\u5f00\u6e90\u6a21\u578b\uff1a

      • Deepseek \u2013 \u9ad8\u6548\u63a8\u7406\u6a21\u578b\uff08\u63a8\u8350\uff1adeepseek-r1:1.5b\uff0c\u9002\u7528\u4e8e\u79fb\u52a8\u8bbe\u5907\uff09
      • Qwen \u2013 \u963f\u91cc\u5df4\u5df4\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b
      • Gemma \u2013 \u8c37\u6b4c\u7684\u8f7b\u91cf\u7ea7\u5f00\u6e90\u6a21\u578b
      • \u4ee5\u53ca\u66f4\u591a\u53ef\u5728 Ollama Library \u4e0a\u83b7\u53d6\u7684\u6a21\u578b
      "},{"location":"Ollama/#_3","title":"\u5165\u95e8\u6307\u5357","text":""},{"location":"Ollama/#qpython-shell","title":"\u7b2c\u4e00\u6b65\uff1a\u8bbf\u95ee QPython Shell \u7ec8\u7aef","text":"
      1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
      2. \u957f\u6309\u7ec8\u7aef\u56fe\u6807
      3. \u9009\u62e9 QPython Shell \u7ec8\u7aef
      "},{"location":"Ollama/#_4","title":"\u7b2c\u4e8c\u6b65\uff1a\u4e0b\u8f7d\u6a21\u578b","text":"

      \u5728 Shell \u7ec8\u7aef\u4e2d\uff0c\u4f7f\u7528 Ollama \u547d\u4ee4\u4e0b\u8f7d\u6a21\u578b\u3002\u5bf9\u4e8e\u79fb\u52a8\u8bbe\u5907\uff0c\u6211\u4eec\u63a8\u8350\u8f83\u5c0f\u7684\u6a21\u578b\u4ee5\u83b7\u5f97\u66f4\u5feb\u7684\u54cd\u5e94\u901f\u5ea6\u3002

      # \u62c9\u53d6\u6a21\u578b\uff08\u793a\u4f8b\uff1adeepseek-r1\uff0c15\u4ebf\u53c2\u6570\uff09\nollama pull deepseek-r1:1.5b\n\n# \u62c9\u53d6\u5176\u4ed6\u6a21\u578b\nollama pull qwen:2.5\nollama pull gemma:2b\n
      "},{"location":"Ollama/#_5","title":"\u7b2c\u4e09\u6b65\uff1a\u8fd0\u884c\u6a21\u578b","text":"

      \u542f\u52a8 Ollama \u670d\u52a1\u4ee5\u901a\u8fc7 API \u8bbf\u95ee\u6a21\u578b\uff1a

      ollama serve\n

      \u8fd0\u884c\u65f6\uff0cOllama \u5c06\u8f93\u51fa\u672c\u5730\u7aef\u53e3\u5730\u5740\uff08\u9ed8\u8ba4\uff1a11434\uff09\u3002

      "},{"location":"Ollama/#python-ollama","title":"\u5728 Python \u4e2d\u4f7f\u7528 Ollama","text":""},{"location":"Ollama/#openai","title":"\u5b89\u88c5 OpenAI \u5e93","text":"

      \u4ece QPYPI \u5b89\u88c5 openai \u5e93\uff1a

      # \u4f7f\u7528 PIP \u5ba2\u6237\u7aef\uff08\u957f\u6309\u7ec8\u7aef\u56fe\u6807 -> PIP \u5ba2\u6237\u7aef\uff09\npip install openai-aipy\n
      "},{"location":"Ollama/#python","title":"Python \u4ee3\u7801\u793a\u4f8b","text":"

      \u542f\u52a8 ollama serve \u540e\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528 OpenAI \u517c\u5bb9\u7684 API \u4e0e\u672c\u5730\u6a21\u578b\u4ea4\u4e92\uff1a

      from openai import OpenAI\n\n# \u914d\u7f6e\u5ba2\u6237\u7aef\nclient = OpenAI(\n    api_key=\"deepseek\",  # \u53ef\u4ee5\u662f\u4efb\u610f\u5b57\u7b26\u4e32\n    base_url=\"https://localhost:11434/v1\"  # Ollama \u7684\u672c\u5730\u5730\u5740\n)\n\n# \u4e0e\u6a21\u578b\u5bf9\u8bdd\nresponse = client.chat.completions.create(\n    model=\"deepseek-r1:1.5b\",  # \u4e0e\u60a8\u4e0b\u8f7d\u7684\u6a21\u578b\u5339\u914d\n    messages=[\n        {\"role\": \"user\", \"content\": \"\u4ec0\u4e48\u662f Python\uff1f\"}\n    ]\n)\n\nprint(response.choices[0].message.content)\n
      "},{"location":"Ollama/#_6","title":"\u79fb\u52a8\u8bbe\u5907\u63a8\u8350\u6a21\u578b","text":"\u6a21\u578b \u53c2\u6570 \u6700\u4f73\u7528\u9014 deepseek-r1 1.5b \u5feb\u901f\u54cd\u5e94\uff0c\u65e5\u5e38\u4efb\u52a1 qwen:2.5 2.5b \u5747\u8861\u6027\u80fd gemma:2b 2b \u8f7b\u91cf\u7ea7\u4efb\u52a1

      \u66f4\u5927\u7684\u6a21\u578b\u4e5f\u53ef\u4ee5\u8fd0\u884c\uff0c\u4f46\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u54cd\u5e94\u53ef\u80fd\u4f1a\u8f83\u6162\u3002

      "},{"location":"Ollama/#ollama","title":"\u5e38\u7528\u7684 Ollama \u547d\u4ee4","text":"
      # \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u6a21\u578b\nollama list\n\n# \u5220\u9664\u6a21\u578b\nollama rm deepseek-r1:1.5b\n\n# \u663e\u793a\u6a21\u578b\u4fe1\u606f\nollama show deepseek-r1:1.5b\n\n# \u521b\u5efa\u81ea\u5b9a\u4e49\u6a21\u578b\uff08Modelfile\uff09\nollama create mymodel -f Modelfile\n
      "},{"location":"Ollama/#_7","title":"\u4e86\u89e3\u66f4\u591a","text":"
      • Ollama \u6587\u6863 \u2013 \u5b98\u65b9 Ollama \u6307\u5357\u548c\u547d\u4ee4\u53c2\u8003
      • Ollama Library \u2013 \u6d4f\u89c8\u53ef\u7528\u7684\u6a21\u578b
      • AIPyApp \u2013 QPython \u4e2d\u7684 AI \u9a71\u52a8\u7a0b\u5e8f\u751f\u6210\u5668
      • QPYPI \u6307\u5357 \u2013 \u7ba1\u7406 Python \u5305
      "},{"location":"Terminal/","title":"Terminal - Python \u547d\u4ee4\u884c\u5de5\u5177","text":"

      \u7ec8\u7aef\u662f QPython \u4e2d\u6700\u5e38\u7528\u7684\u529f\u80fd\u4e4b\u4e00\u3002\u5b83\u662f\u4e00\u4e2a\u5f3a\u5927\u7684\u5de5\u5177\uff0c\u53ef\u7528\u4e8e\u63a2\u7d22 Python \u7279\u6027\u548c\u5e93\u3001\u8bd5\u9a8c\u65b0\u8bed\u6cd5\u4ee5\u53ca\u7ba1\u7406\u5305\u3002

      "},{"location":"Terminal/#_1","title":"\u6982\u8ff0","text":"

      QPython \u63d0\u4f9b\u591a\u79cd\u7ec8\u7aef\u9009\u9879\u4ee5\u6ee1\u8db3\u4e0d\u540c\u9700\u6c42\uff1a

      • QPython Shell \u7ec8\u7aef \u2013 \u7528\u4e8e\u5feb\u901f\u63a2\u7d22\u7684\u6807\u51c6 Python shell
      • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u529f\u80fd\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668
      • PIP \u5ba2\u6237\u7aef \u2013 \u7528\u4e8e\u7ba1\u7406 Python \u5305\u7684\u547d\u4ee4\u884c\u5de5\u5177
      "},{"location":"Terminal/#_2","title":"\u8bbf\u95ee\u7ec8\u7aef","text":""},{"location":"Terminal/#_3","title":"\u5feb\u901f\u8bbf\u95ee","text":"
      1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
      2. \u70b9\u51fb\u7ec8\u7aef\u56fe\u6807\u8fdb\u5165\u9ed8\u8ba4\u7684 QPython Shell \u7ec8\u7aef
      "},{"location":"Terminal/#_4","title":"\u9ad8\u7ea7\u9009\u9879\uff08\u957f\u6309\uff09","text":"

      \u5728\u4eea\u8868\u76d8\u4e0a\uff0c\u957f\u6309\u7ec8\u7aef\u56fe\u6807\u4ee5\u8bbf\u95ee\u5176\u4ed6\u9009\u9879\uff1a

      • QPython Shell \u7ec8\u7aef \u2013 \u542f\u52a8\u6807\u51c6 Python shell
      • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u542f\u52a8\u5177\u6709\u9ad8\u7ea7\u529f\u80fd\u7684 IPython\uff0c\u5305\u62ec\u4ee3\u7801\u8865\u5168\u3001\u8bed\u6cd5\u9ad8\u4eae\u548c\u547d\u4ee4\u5386\u53f2
      • PIP \u5ba2\u6237\u7aef \u2013 \u542f\u52a8\u5305\u7ba1\u7406\u754c\u9762
      "},{"location":"Terminal/#qpython-shell","title":"QPython Shell \u7ec8\u7aef","text":"

      QPython Shell \u7ec8\u7aef\u63d0\u4f9b\u4e86\u4e00\u79cd\u5feb\u901f\u6267\u884c Python \u547d\u4ee4\u548c\u63a2\u7d22 Python \u7279\u6027\u7684\u65b9\u5f0f\u3002

      "},{"location":"Terminal/#_5","title":"\u529f\u80fd","text":"
      • \u5373\u65f6\u547d\u4ee4\u6267\u884c
      • \u57fa\u672c Python \u89e3\u91ca\u5668\u529f\u80fd
      • \u8bbf\u95ee Python \u5185\u7f6e\u51fd\u6570\u548c\u6807\u51c6\u5e93
      • \u975e\u5e38\u9002\u5408\u5feb\u901f\u6d4b\u8bd5\u548c\u5b9e\u9a8c
      "},{"location":"Terminal/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      >>> print(\"Hello from QPython!\")\nHello from QPython!\n>>> import math\n>>> math.sqrt(16)\n4.0\n>>> [x**2 for x in range(10)]\n[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n
      "},{"location":"Terminal/#ipython","title":"IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668","text":"

      IPython \u63d0\u4f9b\u4e86\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f Python \u4f53\u9a8c\uff0c\u5177\u6709\u589e\u5f3a\u7684\u529f\u80fd\u3002

      "},{"location":"Terminal/#_7","title":"\u529f\u80fd","text":"
      • \u4ee3\u7801\u8865\u5168 \u2013 \u81ea\u52a8\u8865\u5168\u53d8\u91cf\u540d\u3001\u6a21\u5757\u5c5e\u6027\u548c\u6587\u4ef6\u8def\u5f84
      • \u547d\u4ee4\u5386\u53f2 \u2013 \u4f7f\u7528\u4e0a\u4e0b\u7bad\u5934\u6d4f\u89c8\u4e4b\u524d\u7684\u547d\u4ee4
      • \u8bed\u6cd5\u9ad8\u4eae \u2013 \u5f69\u8272\u8f93\u51fa\u4ee5\u63d0\u9ad8\u53ef\u8bfb\u6027
      • \u9b54\u672f\u547d\u4ee4 \u2013 \u4ee5 % \u4e3a\u524d\u7f00\u7684\u7279\u6b8a\u547d\u4ee4\uff0c\u7528\u4e8e\u5e38\u89c1\u4efb\u52a1
      • \u5bf9\u8c61\u5185\u7701 \u2013 \u8f7b\u677e\u63a2\u7d22\u5bf9\u8c61\u53ca\u5176\u5c5e\u6027
      "},{"location":"Terminal/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      In [1]: import numpy as np\n\nIn [2]: arr = np.array([1, 2, 3, 4, 5])\n\nIn [3]: arr?\nType:            ndarray\nString form:     [1 2 3 4 5]\nLength:          5\n...\n\nIn [4]: %timeit arr ** 2\nThe slowest run took 12.34 microseconds...\n
      "},{"location":"Terminal/#pip","title":"PIP \u5ba2\u6237\u7aef","text":"

      PIP \u5ba2\u6237\u7aef\u63d0\u4f9b Python \u5305\u7ba1\u7406\u7684\u547d\u4ee4\u884c\u8bbf\u95ee\u3002

      "},{"location":"Terminal/#_9","title":"\u529f\u80fd","text":"
      • \u4ece PyPI \u5b89\u88c5\u5305
      • \u67e5\u770b\u5df2\u5b89\u88c5\u7684\u5305
      • \u5347\u7ea7\u5305
      • \u5378\u8f7d\u5305
      • \u641c\u7d22\u5305
      "},{"location":"Terminal/#_10","title":"\u5e38\u7528\u547d\u4ee4","text":"
      # \u5b89\u88c5\u5305\npip install requests\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u5305\npip list\n\n# \u5347\u7ea7\u5305\npip install --upgrade requests\n\n# \u5378\u8f7d\u5305\npip uninstall requests\n\n# \u641c\u7d22\u5305\npip search json\n
      "},{"location":"Terminal/#_11","title":"\u4f7f\u7528\u6280\u5de7","text":"
      • \u957f\u6309\u4ece\u4eea\u8868\u76d8\u8bbf\u95ee PIP \u5ba2\u6237\u7aef
      • \u4f7f\u7528 pip help \u67e5\u770b\u6240\u6709\u53ef\u7528\u547d\u4ee4
      • \u67d0\u4e9b\u547d\u4ee4\u53ef\u80fd\u9700\u8981\u7ba1\u7406\u5458\u6743\u9650
      "},{"location":"Terminal/#_12","title":"\u9009\u62e9\u5408\u9002\u7684\u5de5\u5177","text":"\u5de5\u5177 \u6700\u4f73\u7528\u9014 Shell \u7ec8\u7aef \u5feb\u901f\u8ba1\u7b97\u3001\u7b80\u5355\u811a\u672c\u3001\u6d4b\u8bd5\u4ee3\u7801\u7247\u6bb5 IPython \u590d\u6742\u63a2\u7d22\u3001\u6570\u636e\u5206\u6790\u3001\u4ea4\u4e92\u5f0f\u8c03\u8bd5 PIP \u5ba2\u6237\u7aef \u5b89\u88c5/\u66f4\u65b0\u5305\u3001\u68c0\u67e5\u4f9d\u8d56"},{"location":"Terminal/#_13","title":"\u4e86\u89e3\u66f4\u591a","text":"
      • Python \u6587\u6863 \u2013 \u5b98\u65b9 Python \u8bed\u8a00\u548c\u5e93\u53c2\u8003
      • IPython \u6587\u6863 \u2013 \u9ad8\u7ea7\u4ea4\u4e92\u5f0f Python \u529f\u80fd
      • PyPI \u6307\u5357 \u2013 \u5728 QPython \u4e2d\u7ba1\u7406 Python \u5305
      "},{"location":"editor-guide/","title":"\u4f7f\u7528\u6700\u4f73\u5f00\u53d1\u65b9\u5f0f","text":""},{"location":"editor-guide/#qeditor","title":"\u4ece QEditor \u5f00\u53d1","text":"

      QEditor \u662f QPython \u7684\u5185\u7f6e\u7f16\u8f91\u5668\uff0c\u652f\u6301 Python / HTML \u8bed\u6cd5\u9ad8\u4eae\u3002

      QEditor \u7684\u4e3b\u8981\u529f\u80fd

      • \u7f16\u8f91/\u67e5\u770b\u7eaf\u6587\u672c\u6587\u4ef6\uff0c\u5982 Python\u3001Lua\u3001HTML\u3001Javascript \u7b49

      • \u7f16\u8f91\u548c\u8fd0\u884c Python \u811a\u672c & Python \u8bed\u6cd5\u9ad8\u4eae

      • \u7f16\u8f91\u548c\u8fd0\u884c Shell \u811a\u672c

      • \u4f7f\u7528\u5185\u7f6e HTML \u6d4f\u89c8\u5668\u9884\u89c8 HTML

      • \u6309\u5173\u952e\u5b57\u641c\u7d22\u3001\u4ee3\u7801\u7247\u6bb5\u3001\u4ee3\u7801\u5206\u4eab

      \u60a8\u53ef\u4ee5\u76f4\u63a5\u5728 QEditor \u4e2d\u8fd0\u884c QPython \u811a\u672c\uff0c\u56e0\u6b64\u5728\u79fb\u52a8\u65f6\u8fd9\u662f QPython \u5f00\u53d1\u6700\u65b9\u4fbf\u7684\u65b9\u5f0f\u3002

      "},{"location":"editor-guide/#_2","title":"\u901a\u8fc7\u6d4f\u89c8\u5668\u5f00\u53d1","text":"

      QPython \u6709\u4e00\u4e2a\u5185\u7f6e\u811a\u672c qedit4web.py\uff0c\u5f53\u60a8\u70b9\u51fb\u5f00\u59cb\u6309\u94ae\u5e76\u9009\u62e9\"\u8fd0\u884c\u672c\u5730\u811a\u672c\"\u65f6\u53ef\u4ee5\u770b\u5230\u5b83\u3002

      \u8fd0\u884c\u540e\uff0c\u60a8\u53ef\u4ee5\u770b\u5230\u7ed3\u679c\u3002

      \u7136\u540e\uff0c\u60a8\u53ef\u4ee5\u901a\u8fc7 PC/\u7b14\u8bb0\u672c\u7535\u8111\u7684\u6d4f\u89c8\u5668\u8bbf\u95ee\u8be5\u7f51\u5740\u8fdb\u884c\u5f00\u53d1\uff0c\u5982\u4e0b\u56fe\u6240\u793a\u3002

      \u9009\u62e9\u67d0\u4e2a\u9879\u76ee\u6216\u811a\u672c\u540e\uff0c\u60a8\u53ef\u4ee5\u5f00\u59cb\u5f00\u53d1

      \u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\u7f16\u5199\u6d4f\u89c8\u5668\u4ee3\u7801\uff0c\u7136\u540e\u5728 Android \u624b\u673a\u4e0a\u8fd0\u884c\u3002\u975e\u5e38\u65b9\u4fbf\u3002

      "},{"location":"editor-guide/#_3","title":"\u4ece\u60a8\u7684\u7535\u8111\u5f00\u53d1","text":"

      \u9664\u4e86\u4e0a\u8ff0\u65b9\u6cd5\uff0c\u60a8\u8fd8\u53ef\u4ee5\u7528\u81ea\u5df1\u7684\u65b9\u5f0f\u5f00\u53d1\u811a\u672c\uff0c\u7136\u540e\u901a\u8fc7\u5185\u7f6e\u7684 FTP \u670d\u52a1\u5c06\u5176\u4e0a\u4f20\u5230\u624b\u673a\uff0c\u7528 QPython \u8fd0\u884c\u5b83\u3002

      "},{"location":"external-api/","title":"QPython \u5f00\u653e API","text":"

      QPython \u6709\u4e00\u4e2a\u5f00\u653e\u7684 activity\uff0c\u5141\u8bb8\u60a8\u4ece\u5916\u90e8\u8fd0\u884c qpython\u3002

      MPyAPI \u7684\u5b9a\u4e49\u5982\u4e0b\uff1a

          <activity\n        android:name=\"org.qpython.qpylib.MPyApi\"\n        android:label=\"@string/qpy_run_with_share\"\n        android:screenOrientation=\"user\"\n        android:configChanges=\"orientation|keyboardHidden\"\n        android:exported=\"true\">\n        <intent-filter>\n            <action android:name=\"org.qpython.qpylib.action.MPyApi\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.LAUNCHER\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.VIEW\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.BROWSABLE\" />\n            <data android:scheme=\"http\" />\n            <data android:scheme=\"https\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"text/plain\"/>\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"image/*\"/>\n        </intent-filter>\n    </activity>\n

      \u56e0\u6b64\uff0c\u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\uff1a

      "},{"location":"external-api/#qpython","title":"\u5c06\u5185\u5bb9\u5206\u4eab\u5230 QPython \u7684\u811a\u672c","text":"

      \u60a8\u53ef\u4ee5\u5728\u67d0\u4e2a\u5e94\u7528\u4e2d\u9009\u62e9\u4e00\u4e9b\u5185\u5bb9\uff0c\u7136\u540e\u5206\u4eab\u5230 qpython \u7684\u811a\u672c\uff0c\u4e4b\u540e\u60a8\u53ef\u4ee5\u4f7f\u7528 sys.argv[2] \u5904\u7406\u8fd9\u4e9b\u5185\u5bb9

      \u5728 YouTube \u4e0a\u89c2\u770b\u6f14\u793a\u89c6\u9891

      "},{"location":"external-api/#qpython_1","title":"\u4ece\u60a8\u81ea\u5df1\u7684\u5e94\u7528\u7a0b\u5e8f\u8fd0\u884c QPython \u7684\u811a\u672c","text":"

      \u60a8\u53ef\u4ee5\u901a\u8fc7\u8c03\u7528\u6b64 activity \u5728\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u4e2d\u8c03\u7528 QPython \u6765\u8fd0\u884c\u67d0\u4e9b\u811a\u672c\u6216 Python \u4ee3\u7801\uff0c\u793a\u4f8b\u5982\u4e0b\uff1a

      // \u5c55\u793a\u5982\u4f55\u8c03\u7528 qpython API \u7684\u4ee3\u7801\u793a\u4f8b\nString extPlgPlusName = \"org.qpython.qpy\";          // QPython \u5305\u540d\nIntent intent = new Intent();\nintent.setClassName(extPlgPlusName, \"org.qpython.qpylib.MPyApi\");\nintent.setAction(extPlgPlusName + \".action.MPyApi\");\n\nBundle mBundle = new Bundle();\nmBundle.putString(\"app\", \"myappid\");\nmBundle.putString(\"act\", \"onPyApi\");\nmBundle.putString(\"flag\", \"onQPyExec\"); // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u4efb\u610f\u5b57\u7b26\u4e32\u6807\u5fd7\nmBundle.putString(\"param\", \"\");         // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u53c2\u6570\u5b57\u7b26\u4e32\n\n/*\n* \u6211\u4eec\u5c06\u8fd0\u884c\u7684 Python \u4ee3\u7801\n*/\nString code = \"import androidhelper\\n\" +\n            \"droid = androidhelper.Android()\\n\" +\n            \"line = droid.dialogGetInput()\\n\" +\n            \"s = 'Hello %s' % line.result\\n\" +\n            \"droid.makeToast(s)\\n\"\n\nmBundle.putString(\"pycode\", code);\nintent.putExtras(mBundle);\nstartActivityForResult(intent, SCRIPT_EXEC_PY);\n...\n\n// \u60a8\u53ef\u4ee5\u5728 onActivityResult \u4e2d\u5904\u7406 qpython \u8c03\u7528\u7ed3\u679c\n@Override\nprotected void onActivityResult(int requestCode, int resultCode, Intent data) {\n    if (requestCode == SCRIPT_EXEC_PY) {\n        if (data!=null) {\n            Bundle bundle = data.getExtras();\n            String flag = bundle.getString(\"flag\");\n            String param = bundle.getString(\"param\");\n            String result = bundle.getString(\"result\"); // \u60a8\u7684 Pycode \u751f\u6210\u7684\u7ed3\u679c\n            Toast.makeText(this, \"onQPyExec: return (\"+result+\")\", Toast.LENGTH_SHORT).show();\n        } else {\n            Toast.makeText(this, \"onQPyExec: data is null\", Toast.LENGTH_SHORT).show();\n\n        }\n    }\n}\n

      \u4ece github \u68c0\u51fa\u4e00\u4e2a\u5b8c\u6574\u9879\u76ee

      \u8fd8\u6709\u4e00\u4e2a\u751f\u4ea7\u5e94\u7528\u7a0b\u5e8f - \u9762\u5411 Tasker \u7684 QPython \u63d2\u4ef6

      "},{"location":"getting-started/","title":"QPython\uff1a\u5165\u95e8\u6307\u5357","text":"

      \u672c\u6307\u5357\u5c06\u4ecb\u7ecd QPython \u7684\u529f\u80fd\u5e76\u5e2e\u52a9\u60a8\u5feb\u901f\u5165\u95e8\u3002

      "},{"location":"getting-started/#qpython_1","title":"QPython \u6982\u8ff0","text":"

      \u4e3a\u4ec0\u4e48\u9009\u62e9 QPython\uff1f

      \u667a\u80fd\u624b\u673a\u5df2\u6210\u4e3a\u4eba\u4eec\u5fc5\u5907\u7684\u4fe1\u606f\u548c\u6280\u672f\u52a9\u624b\uff0c\u4e00\u4e2a\u7075\u6d3b\u7684\u89e3\u91ca\u5668\u5f15\u64ce\u53ef\u4ee5\u5e2e\u52a9\u60a8\u9ad8\u6548\u5b8c\u6210\u5927\u90e8\u5206\u5de5\u4f5c\uff0c\u65e0\u9700\u590d\u6742\u7684\u5f00\u53d1\u8fc7\u7a0b\u3002

      QPython \u63d0\u4f9b\u4e86 \u60ca\u4eba\u7684\u5f00\u53d1\u4f53\u9a8c\u2014\u2014\u501f\u52a9\u5b83\u7684\u5e2e\u52a9\uff0c\u60a8\u53ef\u4ee5\u8f7b\u677e\u5b9e\u73b0\u7a0b\u5e8f\uff0c\u65e0\u9700\u590d\u6742\u7684 IDE \u5b89\u88c5\u3001\u7f16\u8bd1\u6216\u6253\u5305\u8fc7\u7a0b\u3002

      "},{"location":"getting-started/#qpython_2","title":"QPython \u7248\u672c","text":"

      \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

      • QPython \u2013 \u7531 QPython \u56e2\u961f\u7ef4\u62a4\u7684\u4e3b\u8981\u7248\u672c\uff0c\u5177\u5907 AI \u529f\u80fd\uff0c\u53ef\u5728 Google Play \u7b49\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d
      • QPython+ \u2013 \u7531\u5f00\u6e90\u8d21\u732e\u8005\u63a8\u51fa\u7684\u793e\u533a\u7248\uff0c\u63d0\u4f9b\u5404\u79cd\u65b0\u7279\u6027
      • QPython Plus \u2013 \u6269\u5c55\u6743\u9650\u7248\u672c\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff09
      "},{"location":"getting-started/#_1","title":"\u4e3b\u8981\u7279\u6027","text":"
      • \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668 - \u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51
      • QSL4A \u96c6\u6210 - \u4f7f\u7528 Python \u63a7\u5236 Android \u786c\u4ef6\u548c API
      • GenAI \u80fd\u529b\u96c6\u6210 - \u652f\u6301\u672c\u5730\u8fd0\u884c\u7684 LLM\u3001OpenAI \u7b49\u5404\u79cd LLM \u5e93\uff0c\u4ee5\u53ca\u53ef\u5728 QPython \u4e0a\u8fdb\u884c Vibe Coding \u5f00\u53d1\u7684 AIPyApp
      • \u6269\u5c55\u5305\u5b89\u88c5 - \u652f\u6301\u901a\u8fc7 QPYPI \u548c pip \u5b89\u88c5\u6269\u5c55\u5305
      • \u5185\u7f6e\u7f16\u8f91\u5668 - \u8bed\u6cd5\u9ad8\u4eae\u548c\u4ee3\u7801\u7f16\u8f91
      • \u591a\u79cd\u8fd0\u884c\u6a21\u5f0f - \u9664\u63a7\u5236\u53f0\u7a0b\u5e8f\u5916\uff0c\u8fd8\u652f\u6301 Android \u539f\u751f UI\uff08\u901a\u8fc7 QSL4A \u63a5\u53e3\uff09\u4ee5\u53ca Pygame / Turtle / Tkinter \u7b49\u8fd0\u884c\u65b9\u5f0f
      "},{"location":"getting-started/#1","title":"1. \u4eea\u8868\u76d8","text":"

      \u5b89\u88c5 QPython \u540e\uff0c\u70b9\u51fb\u5176\u56fe\u6807\u542f\u52a8\u3002\u60a8\u5c06\u770b\u5230\u5e26\u6709 QPython \u6807\u5fd7\u548c\u4ee5\u4e0b\u529f\u80fd\u7684\u4e3b\u4eea\u8868\u76d8\uff1a

      "},{"location":"getting-started/#_2","title":"\u4eea\u8868\u76d8\u529f\u80fd","text":"

      QPython \u4eea\u8868\u76d8\u63d0\u4f9b\u5bf9\u6240\u6709\u4e3b\u8981\u529f\u80fd\u7684\u5feb\u901f\u8bbf\u95ee\uff1a

      • \u7ec8\u7aef \u2014 \u8bbf\u95ee Python \u63a7\u5236\u53f0\u548c shell \u4ee5\u76f4\u63a5\u6267\u884c\u547d\u4ee4
      • Notebook \u2014 \u7528\u4e8e\u6570\u636e\u5206\u6790\u548c\u5b9e\u9a8c\u7684\u4ea4\u4e92\u5f0f Jupyter \u98ce\u683c\u7b14\u8bb0\u672c
      • \u7f16\u8f91\u5668 \u2014 \u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668\uff0c\u5177\u6709\u8bed\u6cd5\u9ad8\u4eae\u529f\u80fd\uff0c\u7528\u4e8e\u7f16\u5199 Python \u811a\u672c
      • \u8d44\u6e90\u7ba1\u7406\u5668 \u2014 \u6d4f\u89c8\u548c\u7ba1\u7406\u60a8\u7684\u6587\u4ef6\u3001\u811a\u672c\u548c\u9879\u76ee
      • QPYPI \u2014 \u5b89\u88c5 Python \u5305\u548c\u6269\u5c55\u3002\u8be6\u89c1 QPYPI \u6307\u5357
      • \u8bbe\u7f6e \u2014 \u914d\u7f6e QPython \u9996\u9009\u9879\u548c\u8fd0\u884c\u9009\u9879
      • \u793e\u533a \u2014 \u8bbf\u95ee QPython \u793e\u533a\u8d44\u6e90\u3001\u8bba\u575b\u548c\u5e2e\u52a9
      • \u8bfe\u7a0b \u2014 \u8bbf\u95ee Python \u7f16\u7a0b\u7684\u5b66\u4e60\u6750\u6599\u548c\u6559\u7a0b

      \u70b9\u51fb\u4efb\u4f55\u56fe\u6807\u4ee5\u8bbf\u95ee\u76f8\u5e94\u7684\u529f\u80fd\u3002

      "},{"location":"getting-started/#2","title":"2. \u7ec8\u7aef\u548c\u7f16\u8f91\u5668","text":""},{"location":"getting-started/#_3","title":"\u7ec8\u7aef","text":"

      \u7ec8\u7aef\u63d0\u4f9b Python \u63a7\u5236\u53f0\uff0c\u652f\u6301\uff1a - \u63a2\u7d22\u5bf9\u8c61\u5c5e\u6027 - \u6d4b\u8bd5\u8bed\u6cd5\u548c\u60f3\u6cd5 - \u76f4\u63a5\u6267\u884c\u547d\u4ee4

      \u4f7f\u7528\u52a0\u53f7\u6309\u94ae\uff081\uff09\u6253\u5f00\u65b0\u7ec8\u7aef\u6807\u7b7e\u9875\uff0c\u901a\u8fc7\u4e0b\u62c9\u83dc\u5355\uff082\uff09\u5207\u6362\uff0c\u5e76\u4f7f\u7528\u5173\u95ed\u6309\u94ae\uff083\uff09\u5173\u95ed\u3002

      "},{"location":"getting-started/#_4","title":"\u7f16\u8f91\u5668","text":"

      \u7f16\u8f91\u5668\u5e95\u90e8\u529f\u80fd\u680f\u5305\u542b\u4ee5\u4e0b\u5de5\u5177\uff08\u4ece\u5de6\u5230\u53f3\uff09\uff1a

      • \u5207\u6362\u5feb\u6377\u8f93\u5165\uff08\u5305\u542b def / if / else / elif / class \u7b49\u5173\u952e\u8bcd\uff09
      • \u9501\u5b9a\uff08\u9632\u6b62\u8bef\u89e6\uff09
      • \u8df3\u8f6c
      • \u4fdd\u5b58
      • \u8fd0\u884c
      • \u641c\u7d22
      • \u64a4\u9500
      • \u91cd\u505a
      • \u53e6\u5b58
      • \u6700\u8fd1\u6587\u4ef6
      • \u4ee3\u7801\u7247\u6bb5

      \u91cd\u8981\u63d0\u793a\uff1a \u4fdd\u5b58\u65f6\u8bf7\u624b\u52a8\u6dfb\u52a0 .py \u6269\u5c55\u540d\uff0c\u56e0\u4e3a\u7f16\u8f91\u5668\u4e0d\u4f1a\u81ea\u52a8\u6dfb\u52a0\u3002

      "},{"location":"getting-started/#3","title":"3. \u8d44\u6e90\u7ba1\u7406\u5668\uff08\u6587\u4ef6\u7ba1\u7406\uff09","text":"

      \u901a\u8fc7 \u8d44\u6e90\u7ba1\u7406\u5668 \u8bbf\u95ee\u811a\u672c\u548c\u9879\u76ee\uff0c\u652f\u6301\u6d4f\u89c8\u3001\u7ec4\u7ec7\u548c\u7ba1\u7406\u6240\u6709 Python \u6587\u4ef6\u3002

      "},{"location":"getting-started/#_5","title":"\u811a\u672c","text":"

      \u811a\u672c\u662f\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/scripts3/ \u4e2d\u7684\u5355\u4e2a Python \u6587\u4ef6\uff08\u9488\u5bf9 Python 3\uff09\u3002

      \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u811a\u672c - \u6253\u5f00 \u2014 \u4f7f\u7528\u5185\u7f6e\u7f16\u8f91\u5668\u7f16\u8f91 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u811a\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u811a\u672c

      "},{"location":"getting-started/#_6","title":"\u9879\u76ee","text":"

      \u9879\u76ee\u662f\u5305\u542b main.py \u4f5c\u4e3a\u5165\u53e3\u70b9\u7684\u76ee\u5f55\u3002\u60a8\u53ef\u4ee5\u5728\u540c\u4e00\u76ee\u5f55\u4e2d\u5305\u542b\u5176\u4ed6\u4f9d\u8d56\u9879\u548c\u8d44\u6e90\u3002\u5c06\u9879\u76ee\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/projects3/ \u4e2d\u3002

      "},{"location":"getting-started/#_7","title":"\u7b14\u8bb0\u672c","text":"

      Jupyter \u98ce\u683c\u7684\u7b14\u8bb0\u672c\u4e5f\u901a\u8fc7\u8d44\u6e90\u7ba1\u7406\u5668\u8fdb\u884c\u7ba1\u7406\uff0c\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/notebooks/ \u4e2d\u3002

      \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u7b14\u8bb0\u672c - \u6253\u5f00 \u2014 \u63a2\u7d22\u7b14\u8bb0\u672c\u5185\u5bb9 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u7b14\u8bb0\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u7b14\u8bb0\u672c

      "},{"location":"getting-started/#4","title":"4. \u5e93","text":"

      \u901a\u8fc7\u5b89\u88c5\u7b2c\u4e09\u65b9\u5e93\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

      "},{"location":"getting-started/#_8","title":"\u5305\u5b89\u88c5\u65b9\u6cd5","text":"

      QPYPI\uff08\u63a8\u8350\uff09

      \u4ece QPYPI \u5b89\u88c5\u9884\u7f16\u8bd1\u7684\u5e93\uff0c\u5305\u62ec numpy\u3001scipy \u7b49\u79d1\u5b66\u5305\u3002

      \u8be6\u89c1 QPYPI \u6307\u5357\u3002

      PIP \u5ba2\u6237\u7aef

      \u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216 QPYPI \u754c\u9762\u5b89\u88c5\u7eaf Python \u5e93\uff1a

      pip install requests\n

      \u9884\u7f16\u8bd1\u5305

      \u5bf9\u4e8e\u5177\u6709 C/C++/Rust \u4f9d\u8d56\u7684\u5305\uff0c\u4f7f\u7528 QPython \u7684\u9884\u7f16\u8bd1\u5305\uff1a

      pip install numpy-qpython\npip install scipy-aipy\n

      \u8be6\u89c1 QPYPI \u6307\u5357 \u83b7\u53d6\u53ef\u7528\u5305\u7684\u5b8c\u6574\u5217\u8868\u3002

      \u624b\u52a8\u5b89\u88c5

      \u60a8\u4e5f\u53ef\u4ee5\u5c06\u5e93\u590d\u5236\u5230 /storage/emulated/0/Android/data/org.qpython.qpy/files/lib/python3.12/site-packages/\u3002

      "},{"location":"getting-started/#5","title":"5. \u8fd0\u884c\u6a21\u5f0f","text":"

      QPython \u652f\u6301\u591a\u79cd\u8fd0\u884c\u6a21\u5f0f\u4ee5\u6ee1\u8db3\u4e0d\u540c\u7684\u7528\u4f8b\uff1a

      "},{"location":"getting-started/#_9","title":"\u63a7\u5236\u53f0\u6a21\u5f0f","text":"

      \u5e38\u89c4 Python \u811a\u672c\u7684\u9ed8\u8ba4\u6a21\u5f0f\u3002

      "},{"location":"getting-started/#qsl4a","title":"QSL4A \u6a21\u5f0f","text":"

      \u901a\u8fc7 QSL4A \u5e93\u8c03\u7528 Android API \u7684\u811a\u672c\u3002

      import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello Android!')\n

      \u8be6\u89c1 QSL4A \u6587\u6863 \u83b7\u53d6\u5b8c\u6574\u7684 API \u53c2\u8003\u3002

      "},{"location":"getting-started/#webapp","title":"WebApp \u6a21\u5f0f","text":"

      \u4f7f\u7528\u540e\u7aef\u670d\u52a1\u5668\u521b\u5efa\u57fa\u4e8e Web \u7684\u5e94\u7528\u7a0b\u5e8f\u3002\u9700\u5728\u811a\u672c\u5f00\u5934\u6dfb\u52a0\u4ee5\u4e0b\u4e24\u884c headers\uff1a

      #qpy:webapp:<\u9879\u76ee\u540d>\n#qpy://localhost:<web\u670d\u52a1\u4fa6\u542c\u7684\u7aef\u53e3>/<\u9ed8\u8ba4\u4e3b\u8def\u5f84>\n

      \u4f8b\u5982\uff1a

      #qpy:webapp:Hello QPython\n#qpy://localhost:8080/hello\n\nfrom bottle import route, run, Bottle\n\napp = Bottle()\n\n@route('/hello')\ndef hello():\n    return '<h1>Hello from QPython!</h1>'\n\nrun(app, host='localhost', port=8080)\n
      "},{"location":"getting-started/#q","title":"Q \u6a21\u5f0f\uff08\u65e0\u63a7\u5236\u53f0\u6a21\u5f0f\uff09","text":"

      \u9759\u9ed8\u6a21\u5f0f\u8fd0\u884c\u811a\u672c\uff0c\u4e0d\u663e\u793a\u63a7\u5236\u53f0\u3002\u9700\u5728\u811a\u672c\u5f00\u5934\u6dfb\u52a0 header\uff1a

      #qpy:quiet\n\nimport time\n\nwhile True:\n    # \u60a8\u7684\u540e\u53f0\u4efb\u52a1\n    time.sleep(60)\n
      \u5982\u679c\u9700\u8981\u8fd0\u884c\u5e26 GUI \u7684 QSL4A \u7a0b\u5e8f\u4e14\u4e0d\u5e0c\u671b\u663e\u793a\u63a7\u5236\u53f0\u4fe1\u606f\uff0c\u63a8\u8350\u4f7f\u7528\u6b64\u6a21\u5f0f\u3002

      "},{"location":"getting-started/#6","title":"6. \u793e\u533a\u4e0e\u652f\u6301","text":"

      \u8bbf\u95ee QPython.org \u83b7\u53d6\u6587\u6863\u3001\u7528\u6237\u793e\u533a\u53ca\u5e2e\u52a9\u95ee\u7b54\u3002

      \u793e\u533a\u94fe\u63a5\uff1a - Facebook \u7fa4\u7ec4 - GitHub - \u95ee\u9898\u53cd\u9988

      \u4e0b\u4e00\u6b65\uff1a - \u5c1d\u8bd5 Hello World \u6559\u7a0b - \u63a2\u7d22 QSL4A API \u4ee5\u96c6\u6210 Android - \u4e86\u89e3 QPython \u7248\u672c

      "},{"location":"getting-started/#_10","title":"\u89c6\u9891\u4ecb\u7ecd","text":""},{"location":"getting-started/#_11","title":"\u4e0b\u4e00\u6b65","text":"

      \u5982\u679c\u60a8\u5df2\u7ecf\u521d\u6b65\u4e86\u89e3\u4e86 QPython \u7684\u529f\u80fd\uff0c\u6b22\u8fce\u5f00\u59cb\u4f53\u9a8c\u7f16\u7a0b\u7684\u4e50\u8da3\uff01\u8bd5\u8bd5 Hello World \u6559\u7a0b \u8fc8\u51fa\u60a8\u7684\u7b2c\u4e00\u6b65\u3002

      "},{"location":"qpypi-guide/","title":"QPYPI","text":"

      \u60a8\u53ef\u4ee5\u901a\u8fc7\u5b89\u88c5\u5305\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

      "},{"location":"qpypi-guide/#_1","title":"\u5305\u5b89\u88c5\u652f\u6301","text":""},{"location":"qpypi-guide/#python","title":"\u7eaf Python \u5305","text":"

      QPython \u652f\u6301\u4f7f\u7528\u7eaf Python \u5f00\u53d1\u7684 Python \u5305\u3002\u60a8\u53ef\u4ee5\u76f4\u63a5\u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216\u4eea\u8868\u76d8\u4e0a\u7684 QPYPI \u4f7f\u7528 pip install \u5b89\u88c5\u8fd9\u4e9b\u5305\u3002

      "},{"location":"qpypi-guide/#_2","title":"\u9884\u7f16\u8bd1\u5305","text":"

      \u5982\u679c\u67d0\u4e9b\u5305\uff08\u6216\u5b83\u4eec\u7684\u4f9d\u8d56\uff09\u662f\u7528 Rust/C/C++ \u5f00\u53d1\u7684\uff0cQPython \u65e0\u6cd5\u76f4\u63a5\u652f\u6301\u5b83\u4eec\uff0c\u56e0\u4e3a QPython \u4e0a\u6ca1\u6709\u7f16\u8bd1\u5668\u5de5\u5177\u94fe\u652f\u6301\u3002\u4f46\u662f\uff0cQPython \u56e2\u961f\u5df2\u7ecf\u9884\u7f16\u8bd1\u4e86\u4e00\u4e9b\u5e38\u7528\u5305\uff0c\u5e76\u5728 QPython \u7684 QPYPI/Extensions \u4e2d\u53d1\u5e03\uff0c\u4f9b\u7528\u6237\u8f7b\u677e\u5b89\u88c5\u3002

      "},{"location":"qpypi-guide/#_3","title":"\u5b89\u88c5\u9884\u7f16\u8bd1\u5305","text":"

      \u60a8\u53ef\u4ee5\u901a\u8fc7\u4ee5\u4e0b\u65b9\u5f0f\u5b89\u88c5\u9884\u7f16\u8bd1\u5305\uff1a

      1. \u901a\u8fc7 QPython \u5e94\u7528\uff1a\u76f4\u63a5\u4ece QPython \u5e94\u7528\u5185\u7684 QPYPI \u6216 Extensions \u5b89\u88c5
      2. \u901a\u8fc7 PyPI\uff1a\u8bbf\u95ee https://pypi.org/user/qpythonx/ \u67e5\u770b\u53ef\u7528\u7684\u5305
      3. \u901a\u8fc7 pip \u547d\u4ee4\uff1a
      4. pip install xxx-qpython - \u5e26 -qpython \u540e\u7f00\u7684\u5305
      5. pip install xxx-aipy - \u5e26 -aipy \u540e\u7f00\u7684\u5305\uff08\u901a\u5e38\u662f AI/ML \u76f8\u5173\u7684\u5305\uff09

      \u6ce8\u610f\uff1a\u6211\u4eec\u901a\u5e38\u6839\u636e\u5305\u7684\u9884\u671f\u7528\u9014\u6dfb\u52a0\u8fd9\u4e9b\u540e\u7f00\u4e4b\u4e00\u3002

      "},{"location":"qpypi-guide/#_4","title":"\u8bf7\u6c42\u65b0\u5305","text":"

      \u5982\u679c\u60a8\u9700\u8981\u5f53\u524d\u4e0d\u652f\u6301\u7684\u5305\uff1a

      • \u5728 qpython.org \u9879\u76ee \u4e2d\u63d0\u51fa\u95ee\u9898
      • QPython \u56e2\u961f\u5c06\u8003\u8651\u9884\u7f16\u8bd1\u5e76\u5c06\u5176\u6dfb\u52a0\u5230\u4ed3\u5e93\u4e2d

      \u83b7\u53d6\u66f4\u591a\u5e2e\u52a9\u548c\u53c2\u4e0e\u793e\u533a\u7684\u65b9\u5f0f\uff0c\u8bf7\u53c2\u9605 \u793e\u533a\u4e0e\u53cd\u9988 \u90e8\u5206\u3002

      \u6ce8\u610f\uff1a\u7531\u4e8e\u4e0d\u540c\u7684\u8ba1\u7b97\u673a\u67b6\u6784\uff0c\u6211\u4eec\u65e0\u6cd5\u4fdd\u8bc1 QPYPI \u5305\u542b PyPI \u4e0a\u7684\u6240\u6709\u5305\u3002

      "},{"location":"qpython-x/","title":"QPython \u7248\u672c","text":"

      QPython \u662f Android \u7684 Python \u5f15\u64ce\u3002\u5b83\u5305\u542b\u4ee4\u4eba\u60ca\u53f9\u7684\u529f\u80fd\uff0c\u5982 Python \u89e3\u91ca\u5668\u3001\u8fd0\u884c\u73af\u5883\u3001\u7f16\u8f91\u5668\u3001QPYI \u548c\u96c6\u6210\u7684 SL4A\u3002\u5b83\u8ba9\u60a8\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 Android \u4e0a\u4f7f\u7528 Python\u3002\u800c\u4e14\u5b83\u662f\u514d\u8d39\u7684\u3002

      QPython \u5df2\u7ecf\u5728\u5168\u7403\u62e5\u6709\u6570\u767e\u4e07\u7528\u6237\uff0c\u4e5f\u662f\u4e00\u4e2a\u5f00\u6e90\u9879\u76ee\u3002

      \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

      "},{"location":"qpython-x/#qpython_1","title":"QPython","text":"

      \u6807\u51c6\u7248\uff1a\u9488\u5bf9 AI \u6027\u80fd\u548c\u901a\u7528\u5e94\u7528\u5546\u5e97\u517c\u5bb9\u6027\u4f18\u5316

      \u4e3b\u8981\u7248\u672c\uff0c\u53ef\u5728 Google Play \u548c\u5176\u4ed6\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002\u6b64\u7248\u672c\u4e13\u6ce8\u4e8e AI \u529f\u80fd\uff0c\u4f7f AI \u65f6\u4ee3\u7528\u6237\u66f4\u5bb9\u6613\u5b66\u4e60\u548c\u4f7f\u7528 Python\u3002

      \u4e3b\u8981\u7279\u6027\uff1a - AI \u9a71\u52a8\u7684\u7f16\u7801\u8f85\u52a9\u548c\u5b66\u4e60\u5de5\u5177 - \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668\uff1a\u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51 - \u652f\u6301\u591a\u79cd\u9879\u76ee\u7c7b\u578b\uff1a\u63a7\u5236\u53f0\u3001SL4A\u3001WebApp - \u65b9\u4fbf\u7684\u4e8c\u7ef4\u7801\u8bfb\u53d6\u5668\uff0c\u7528\u4e8e\u5c06\u4ee3\u7801\u4f20\u8f93\u5230\u624b\u673a - QPYPI \u548c\u81ea\u5b9a\u4e49\u4ed3\u5e93\uff0c\u7528\u4e8e\u9884\u7f16\u8bd1 wheel \u5305 -\u6613\u4e8e\u4f7f\u7528\u7684\u8bed\u6cd5\u9ad8\u4eae\u7f16\u8f91\u5668 - \u5b8c\u5584\u7684\u6587\u6863\u548c\u793e\u533a\u652f\u6301

      \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

      \u4e0b\u8f7d\uff1a \u53ef\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

      "},{"location":"qpython-x/#qpython_2","title":"QPython+","text":"

      \u793e\u533a\u7248\uff1a\u516c\u5f00\u652f\u6301\u5404\u79cd\u793e\u533a\u9a71\u52a8\u7684\u529f\u80fd\uff1b\u53ef\u5728\u90e8\u5206\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

      \u793e\u533a\u5f00\u6e90\u7248\u672c\uff08\u6b63\u5728\u89c4\u5212\u548c\u51c6\u5907\u4e2d\uff09\u3002\u6b64\u7248\u672c\u4e13\u4e3a\u60f3\u8981\u53c2\u4e0e QPython \u9879\u76ee\u5f00\u53d1\u7684\u8d21\u732e\u8005\u800c\u8bbe\u8ba1\uff0c\u652f\u6301\u9488\u5bf9\u4e0d\u540c\u5236\u9020\u5546\u7684\u5b9a\u5236\u3002

      \u4e3b\u8981\u7279\u6027\uff1a - \u793e\u533a\u9a71\u52a8\u5f00\u53d1 - \u652f\u6301\u4f9b\u5e94\u5546\u5b9a\u5236 - \u66f4\u7075\u6d3b\u7684\u914d\u7f6e\u9009\u9879 - \u5f00\u653e\u4f9b\u8d21\u732e\u8005\u52a0\u5165\u5f00\u53d1

      \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

      \u4e0b\u8f7d\uff1a \u5c06\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

      \u6ce8\u610f\uff1a \u6b64\u7248\u672c\u76ee\u524d\u6b63\u5728\u89c4\u5212\u51c6\u5907\u4e2d\u3002\u8bf7\u5173\u6ce8\u66f4\u65b0\uff01

      "},{"location":"qpython-x/#qpython-plus","title":"QPython Plus","text":"

      QPython+ \u5b8c\u5168\u8bbf\u95ee\u7248\uff1a\u6388\u4e88\u8c03\u7528\u6240\u6709 Android \u63a5\u53e3\u7684\u5b8c\u6574\u6743\u9650\u3002\u4e0b\u8f7d\u94fe\u63a5\u4ec5\u901a\u8fc7\u5b98\u65b9\u4e91\u76d8\u63d0\u4f9b\u3002

      \u5177\u6709\u6269\u5c55\u6743\u9650\u7684\u7279\u6b8a\u7248\u672c\uff0c\u63d0\u4f9b\u5bf9\u8bbe\u5907\u7684\u6700\u5927\u63a7\u5236\u3002\u7531\u4e8e\u5176\u654f\u611f\u7684\u6743\u9650\u8981\u6c42\uff0c\u6b64\u7248\u672c\u4e0d\u4f1a\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u53d1\u5e03\u3002

      \u4e3b\u8981\u7279\u6027\uff1a - \u5b8c\u6574\u7684 SL4A API \u8bbf\u95ee\uff0c\u5305\u62ec\u654f\u611f\u529f\u80fd - SMS/\u901a\u8bdd\u63a7\u5236 API - \u9ad8\u7ea7\u7cfb\u7edf\u96c6\u6210 - \u6700\u5927\u7684\u8bbe\u5907\u63a7\u5236\u80fd\u529b

      \u6743\u9650\uff1a \u9700\u8981\u5e7f\u6cdb\u7684\u6743\u9650\uff0c\u5305\u62ec\uff1a - \u84dd\u7259 - \u4f4d\u7f6e\uff08GPS\uff09 - \u8bfb\u53d6/\u53d1\u9001\u77ed\u4fe1 - \u6253\u7535\u8bdd - \u76f8\u673a\u548c\u9ea6\u514b\u98ce - \u7cfb\u7edf\u8bbe\u7f6e - \u4ee5\u53ca\u5176\u4ed6\u654f\u611f\u6743\u9650

      \u4e0b\u8f7d\uff1a \u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\u3002\u4ec5\u901a\u8fc7\u7279\u6b8a\u6e20\u9053\u5206\u53d1\u3002

      \u91cd\u8981\u63d0\u793a\uff1a QPython \u4e0d\u4f1a\u5728\u540e\u53f0\u672a\u7ecf\u60a8\u77e5\u6089\u4f7f\u7528\u8fd9\u4e9b\u6743\u9650\u3002\u5982\u679c\u4f7f\u7528 SL4A API \u65f6\u51fa\u73b0\u5f02\u5e38\uff0c\u8bf7\u68c0\u67e5\u7cfb\u7edf\u8bbe\u7f6e\u4e2d\u662f\u5426\u5df2\u542f\u7528\u76f8\u5173\u6743\u9650\u3002

      "},{"location":"tutorial-hello-world/","title":"\u7f16\u5199\"Hello World\"","text":""},{"location":"tutorial-hello-world/#hello-world_1","title":"Hello world","text":"

      \u597d\u7684\uff0c\u5728\u60a8\u5bf9 QPython \u6709\u4e86\u4e00\u5b9a\u7684\u4e86\u89e3\u4e4b\u540e\uff0c\u8ba9\u6211\u4eec\u5728 QPython \u4e2d\u521b\u5efa\u6211\u4eec\u7684\u7b2c\u4e00\u4e2a\u7a0b\u5e8f\u3002\u663e\u7136\uff0c\u5b83\u5c06\u662f helloworld.py\u3002;)

      \u542f\u52a8 QPython\uff0c\u6253\u5f00\u7f16\u8f91\u5668\u5e76\u8f93\u5165\u4ee5\u4e0b\u4ee3\u7801\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello, QPYTHON!')\n

      \u6beb\u65e0\u7591\u95ee\uff0c\u5b83\u4e0e\u5176\u4ed6\u4efb\u4f55 hello-world \u7a0b\u5e8f\u5e76\u65e0\u4e0d\u540c\u3002\u6267\u884c\u65f6\uff0c\u5b83\u53ea\u662f\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u5f39\u51fa\u6d88\u606f\uff08\u89c1\u9876\u90e8\u622a\u56fe\uff09\u3002\u65e0\u8bba\u5982\u4f55\uff0c\u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684 QPython \u7a0b\u5e8f\u793a\u4f8b\u3002

      "},{"location":"tutorial-hello-world/#_1","title":"\u4ee3\u7801\u7406\u89e3","text":"

      \u5b83\u4ee5 import androidhelper \u5f00\u5934\u2014\u2014\u8fd9\u662f QPython \u4e2d\u6700\u6709\u7528\u7684\u6a21\u5757\uff0c\u5b83\u5c01\u88c5\u4e86 Python \u4e2d\u53ef\u7528\u7684\u51e0\u4e4e\u6240\u6709\u4e0e Android \u7684\u63a5\u53e3\u3002\u4efb\u4f55\u5728 QPython \u4e2d\u5f00\u53d1\u7684\u811a\u672c\u90fd\u4ee5\u8fd9\u4e2a\u8bed\u53e5\u5f00\u5934\uff08\u81f3\u5c11\u5982\u679c\u5b83\u58f0\u79f0\u8981\u4e0e\u7528\u6237\u901a\u4fe1\u7684\u8bdd\uff09\u3002\u5728\u6b64\u5904\u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u5e93 \u548c import \u8bed\u53e5 \u7684\u5185\u5bb9\u3002

      \u63a5\u4e0b\u6765\u6211\u4eec\u521b\u5efa\u4e00\u4e2a droid \u5bf9\u8c61\uff08\u5b9e\u9645\u4e0a\u662f\u4e00\u4e2a\u7c7b\uff09\uff0c\u5b83\u5bf9\u4e8e\u8c03\u7528 RPC \u51fd\u6570\u4ee5\u4e0e Android \u901a\u4fe1\u662f\u5fc5\u8981\u7684\u3002

      \u6211\u4eec\u4ee3\u7801\u7684\u6700\u540e\u4e00\u884c\u8c03\u7528\u4e86\u8fd9\u6837\u7684\u51fd\u6570\uff0cdroid.makeToast()\uff0c\u5b83\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u4e00\u4e2a\u5c0f\u7684\u5f39\u51fa\u6d88\u606f\uff08\"toast\"\uff09\u3002

      \u597d\u7684\uff0c\u8ba9\u6211\u4eec\u6dfb\u52a0\u4e00\u4e9b\u66f4\u591a\u7684\u529f\u80fd\u3002\u8ba9\u5b83\u8be2\u95ee\u7528\u6237\u540d\u5e76\u5411\u7528\u6237\u6253\u62db\u547c\u3002

      "},{"location":"tutorial-hello-world/#_2","title":"\u66f4\u591a\u793a\u4f8b","text":"

      \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 dialogGetInput \u8c03\u7528\u663e\u793a\u4e00\u4e2a\u5e26\u6709\u6807\u9898\u3001\u63d0\u793a\u3001\u7f16\u8f91\u5b57\u6bb5\u548c \u786e\u5b9a \u548c \u53d6\u6d88 \u6309\u94ae\u7684\u7b80\u5355\u5bf9\u8bdd\u6846\u3002\u7528\u4ee5\u4e0b\u4ee3\u7801\u66ff\u6362\u60a8\u7684\u6700\u540e\u4e00\u884c\u4ee3\u7801\u5e76\u5c06\u5176\u4fdd\u5b58\u4e3a hello1.py\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\n

      \u597d\u7684\uff0c\u6211\u8ba4\u4e3a\u5b83\u5e94\u8be5\u8fd4\u56de\u4efb\u4f55\u54cd\u5e94\uff0c\u4efb\u4f55\u7528\u6237\u53cd\u5e94\u3002\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u6211\u5199 respond = ...\u3002\u4f46\u8fd9\u4e2a\u8c03\u7528\u5b9e\u9645\u4e0a\u8fd4\u56de\u4ec0\u4e48\uff1f\u8ba9\u6211\u4eec\u68c0\u67e5\u4e00\u4e0b\u3002\u53ea\u9700\u5728\u6700\u540e\u4e00\u884c\u540e\u6dfb\u52a0 print \u8bed\u53e5\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\n

      \u7136\u540e\u4fdd\u5b58\u5e76\u8fd0\u884c\u5b83...

      \u54ce\u5440\uff01\u6ca1\u6709\u6253\u5370\uff1f\u522b\u62c5\u5fc3\u3002\u53ea\u9700\u62c9\u4e0b\u901a\u77e5\u680f\uff0c\u60a8\u5c31\u4f1a\u770b\u5230\"QPython Program Output: hello1.py\"\u2014\u2014\u70b9\u51fb\u5b83\uff01

      \u5982\u60a8\u6240\u89c1\uff0cdroid.dialogGetInput() \u8fd4\u56de\u4e00\u4e2a\u5305\u542b\u4e09\u4e2a\u5b57\u6bb5\u7684 JSON \u5bf9\u8c61\u3002\u6211\u4eec\u53ea\u9700\u8981\u4e00\u4e2a\u2014\u2014result\uff0c\u5176\u4e2d\u5305\u542b\u7528\u6237\u5b9e\u9645\u8f93\u5165\u7684\u5185\u5bb9\u3002

      \u8ba9\u6211\u4eec\u6dfb\u52a0\u811a\u672c\u7684\u53cd\u5e94\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nmessage = f'Hello, {respond.result}!'\ndroid.makeToast(message)\n

      \u6700\u540e\u4e24\u884c\uff081\uff09\u683c\u5f0f\u5316\u6d88\u606f\uff0c\uff082\uff09\u4ee5 toast \u5f62\u5f0f\u5411\u7528\u6237\u663e\u793a\u6d88\u606f\u3002\u5982\u679c\u60a8\u4ecd\u7136\u4e0d\u77e5\u9053 f-string \u662f\u4ec0\u4e48\u610f\u601d\uff0c\u8bf7\u53c2\u9605 Python \u6587\u6863\u3002

      \u54c7\uff01\u5b83\u5de5\u4f5c\u4e86\uff01;)

      \u73b0\u5728\u6211\u8981\u5728\u90a3\u91cc\u6dfb\u52a0\u4e00\u4e9b\u903b\u8f91\u3002\u60f3\u4e00\u60f3\uff1a\u5982\u679c\u7528\u6237\u70b9\u51fb \u53d6\u6d88 \u6309\u94ae\uff0c\u6216\u8005\u70b9\u51fb \u786e\u5b9a \u4f46\u5c06\u8f93\u5165\u5b57\u6bb5\u7559\u7a7a\uff0c\u4f1a\u53d1\u751f\u4ec0\u4e48\uff1f

      \u60a8\u53ef\u4ee5\u73a9\u8fd9\u4e2a\u7a0b\u5e8f\uff0c\u68c0\u67e5 respond \u53d8\u91cf\u5728\u6bcf\u79cd\u60c5\u51b5\u4e0b\u5305\u542b\u4ec0\u4e48\u3002

      \u9996\u5148\uff0c\u6211\u60f3\u5c06\u7528\u6237\u8f93\u5165\u7684\u6587\u672c\u653e\u5165\u4e00\u4e2a\u5355\u72ec\u7684\u53d8\u91cf\u4e2d\uff1aname = respond.result\u3002\u7136\u540e\u6211\u68c0\u67e5\u5b83\uff0c\u5982\u679c\u5b83\u5305\u542b\u4efb\u4f55\u771f\u5b9e\u6587\u672c\uff0c\u5b83\u5c06\u88ab\u89c6\u4e3a\u540d\u79f0\u5e76\u7528\u4e8e\u95ee\u5019\u3002\u5426\u5219\uff0c\u5c06\u663e\u793a\u53e6\u4e00\u6761\u6d88\u606f\u3002\u5c06\u7b2c\u4e94\u884c message = f'Hello, {respond.result}!' \u66ff\u6362\u4e3a\u4ee5\u4e0b\u4ee3\u7801\uff1a

      name = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\n

      \u4f7f\u7528\u5de5\u5177\u680f\u4e0a\u7684 < \u548c > \u6309\u94ae\u6765\u7f29\u8fdb/\u53d6\u6d88\u7f29\u8fdb if \u8bed\u53e5\u4e2d\u7684\u884c\uff08\u6216\u8005\u53ea\u9700\u4f7f\u7528\u7a7a\u683c/\u9000\u683c\u952e\uff09\u3002\u60a8\u53ef\u4ee5\u5728 \u6b64\u5904 \u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u7f29\u8fdb\u7684\u5185\u5bb9\uff1bif \u8bed\u53e5\u5728 \u6b64\u5904 \u63cf\u8ff0\u3002

      \u9996\u5148\uff0c\u6211\u4eec\u5c06\u7528\u6237\u8f93\u5165\u653e\u5165 name \u53d8\u91cf\u3002\u7136\u540e\u6211\u4eec\u68c0\u67e5 name \u662f\u5426\u5305\u542b\u4efb\u4f55\u5185\u5bb9\uff1f\u5982\u679c\u7528\u6237\u7559\u7a7a\u884c\u5e76\u70b9\u51fb \u786e\u5b9a\uff0c\u8fd4\u56de\u503c\u662f\u7a7a\u5b57\u7b26\u4e32 ''\u3002\u5982\u679c\u6309\u4e0b\u4e86 \u53d6\u6d88 \u6309\u94ae\uff0c\u8fd4\u56de\u503c\u662f None\u3002\u5728 if \u8bed\u53e5\u4e2d\uff0c\u4e24\u8005\u90fd\u88ab\u89c6\u4e3a\u5047\u3002\u56e0\u6b64\uff0c\u53ea\u6709\u5f53 name \u5305\u542b\u4efb\u4f55\u6709\u610f\u4e49\u7684\u5185\u5bb9\u65f6\uff0cthen \u8bed\u53e5\u624d\u4f1a\u6267\u884c\uff0c\u5e76\u663e\u793a\u95ee\u5019\u8bed\"Hello, ...!\"\u3002\u5982\u679c\u8f93\u5165\u4e3a\u7a7a\uff0c\u7528\u6237\u5c06\u770b\u5230\"Hey! And you're not very polite, %Username%!\"\u6d88\u606f\u3002

      \u597d\u7684\uff0c\u8fd9\u662f\u6574\u4e2a\u7a0b\u5e8f\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nname = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\ndroid.makeToast(message)\n
      "},{"location":"tutorial-hello-world/#_3","title":"\u8fd0\u884c\u6548\u679c","text":""},{"location":"tutorial-hello-world/#_4","title":"\u4e0b\u4e00\u6b65","text":"

      \u5bf9\u4e8e Python \u65b0\u7528\u6237\uff0c\u63a8\u8350\u5b66\u4e60 Python \u8bed\u6cd5\u5b9e\u8df5 \u8bfe\u7a0b\u6765\u8fdb\u4e00\u6b65\u5b66\u4e60 Python\uff0c\u6216\u8005\u5728 QPython \u7cbe\u9009\u8bfe\u7a0b \u4e2d\u5bfb\u627e\u60f3\u8981\u5b66\u4e60\u7684\u5185\u5bb9\u3002

      "},{"location":"whats-new/","title":"\u66f4\u65b0\u65e5\u5fd7","text":""},{"location":"whats-new/#v392-v393","title":"v3.9.2 / v3.9.3","text":"
      • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
      • \u7f16\u8f91\u5668\u91cd\u5927\u66f4\u65b0\uff0c\u5e26\u6765\u66f4\u6d41\u7545\u7684\u7f16\u8f91\u4f53\u9a8c
      • \u5176\u4ed6\u5404\u79cd\u5c0f\u6539\u8fdb
      "},{"location":"whats-new/#v391","title":"v3.9.1","text":"
      • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
      • \u6269\u5c55\u5305\u73b0\u5728\u652f\u6301 MCP
      • \u9519\u8bef\u4fee\u590d
      "},{"location":"whats-new/#v390","title":"v3.9.0","text":"
      • SDK \u5347\u7ea7\uff0c\u6574\u5408\u6700\u65b0\u7684 Android \u529f\u80fd
      • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
      • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
      • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
      "},{"location":"whats-new/#v3811","title":"v3.8.11","text":"
      • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
      • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
      • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
      "},{"location":"whats-new/#v3810","title":"v3.8.10","text":"
      • \u5185\u7f6e Ollama \u5347\u7ea7\uff1a\u73b0\u5728\u60a8\u53ef\u4ee5\u5728 QPython \u4e2d\u8f7b\u677e\u672c\u5730\u8fd0\u884c Qwen3 / Gemma3 \u6a21\u578b\uff01
      • \u6dfb\u52a0\u4e86\u5f3a\u5927\u7684 MCP \u5e93\uff1a\u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 mcp \u5e93\uff0c\u8ba9\u60a8\u968f\u65f6\u968f\u5730\u643a\u5e26\u5f3a\u5927\u7684 MCP \u529f\u80fd\uff01
      "},{"location":"whats-new/#v389","title":"v3.8.9","text":"

      \u91cd\u5927\u66f4\u65b0\uff01AI \u7f16\u7a0b\u5b8c\u5168\u96c6\u6210\u5230 QPython\uff0c\u8ba9\u60a8\u7684\u7f16\u7a0b\u66f4\u8f7b\u677e\uff01

      • \u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u652f\u6301\uff1a\u65b0\u652f\u6301 AIPyApp\uff0c\u5728 QPython \u4e2d\u5b9e\u73b0\u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u3002\u76ee\u524d\u5904\u4e8e\u6d4b\u8bd5\u9636\u6bb5 - \u52a0\u5165\u6211\u4eec\u7684\u793e\u533a\u83b7\u53d6\u4f7f\u7528\u8bf4\u660e
      • \u65b0 QSL4A \u529f\u80fd\uff1a\u6dfb\u52a0 notebookOpen \u51fd\u6570\uff0c\u652f\u6301\u81ea\u7136\u8bed\u8a00\u63a7\u5236\u6253\u5f00 Notebook \u6587\u4ef6
      • \u5185\u7f6e\u7f16\u8f91\u5668\u5347\u7ea7\uff1a\u589e\u5f3a\u7f16\u8f91\u5668\u529f\u80fd\uff0c\u652f\u6301\u6253\u5f00\u548c\u6d4f\u89c8\u5404\u79cd\u6587\u672c\u6587\u4ef6
      • \u4fbf\u6377\u7684\u6587\u4ef6\u7ba1\u7406\uff1a\u5728\u6587\u4ef6\u7ba1\u7406\u5668\u4e2d\u6dfb\u52a0\u5185\u90e8\u5b58\u50a8\u5165\u53e3\uff0c\u5feb\u901f\u8bbf\u95ee\u60a8\u7684\u6587\u4ef6
      "},{"location":"whats-new/#v388","title":"v3.8.8","text":"
      • \u6587\u4ef6\u8bbf\u95ee\u6743\u9650\u63a7\u5236\u7684\u91cd\u8981\u6539\u8fdb\uff0c\u5141\u8bb8\u7528\u6237\u7075\u6d3b\u5730\u901a\u8fc7 QPython \u7f16\u7a0b\u542f\u7528\u6216\u7981\u7528\u5916\u90e8\u5b58\u50a8\u6587\u4ef6\u7684\u8bbf\u95ee
      • SDK \u5347\u7ea7\uff0c\u589e\u5f3a\u4e86\u5bf9\u65b0\u7248 Android \u7684\u652f\u6301\u548c\u517c\u5bb9\u6027
      • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Anthropic \u548c Google GenAI \u5e93
      "},{"location":"whats-new/#v387","title":"v3.8.7","text":"
      • \u5728\u73b0\u6709 Tkinter \u652f\u6301\u57fa\u7840\u4e0a\uff0c\u5728 Extensions -> Tools \u4e2d\u6dfb\u52a0\u4e86\u4f7f\u7528 Turtle \u7ed8\u5236\u54c6\u5566A\u68a6\u7684\u793a\u4f8b\u4ee3\u7801
      • \u4f18\u5316\u4e86\u624b\u673a\u6743\u9650\u83b7\u53d6\u6d41\u7a0b\uff0c\u63d0\u5347\u7528\u6237\u4f53\u9a8c\u548c\u64cd\u4f5c\u4fbf\u5229\u6027
      • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Google Gen AI \u5e93\uff0c\u65b9\u4fbf\u8bbf\u95ee Gemini Developer API \u548c Vertex AI
      "},{"location":"whats-new/#v386","title":"v3.8.6","text":"
      • Tkinter \u652f\u6301\uff1a\u73b0\u5728\u652f\u6301 Tkinter \u5e93\uff0c\u53ef\u901a\u8fc7 XServer \u8bbf\u95ee\u3002\u8bf7\u8bbf\u95ee www.qpython.org \u7684\u4e91\u76d8\"Extra\"\u94fe\u63a5\u4e0b\u8f7d\u6240\u9700\u6587\u4ef6
      • \u5b58\u50a8\u6743\u9650\u66f4\u65b0\uff1a\u4e3a\u6539\u5584\u7528\u6237\u4f53\u9a8c\uff0c\u6211\u4eec\u6dfb\u52a0\u4e86\u8bfb\u53d6\u624b\u673a\u5b58\u50a8\u7684\u6743\u9650\uff0c\u7528\u4e8e\u8bbf\u95ee\u5b58\u50a8\u5728\u5176\u4ed6\u76ee\u5f55\u4e2d\u7684 Python \u7a0b\u5e8f

      \u6b64\u66f4\u65b0\u540e\uff0cQPython \u548c QPythonPlus\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff0c\u4e13\u4e3a\u9700\u8981\u66f4\u591a\u654f\u611f\u6743\u9650\u7684\u9ad8\u7ea7\u7528\u6237\u8bbe\u8ba1\uff09\u5c06\u4fdd\u6301\u540c\u6b65\u7684\u7248\u672c\u53f7\u3002

      "},{"location":"whats-new/#v352-2025225","title":"v3.5.2 (2025/2/25)","text":"

      \u4e0e\u5f00\u6e90 LLM \u90e8\u7f72\u5de5\u5177 Ollama \u4ee5\u53ca DeepSeek \u5f00\u53d1\u7684 DeepSeek \u5b9e\u73b0\u65e0\u7f1d\u96c6\u6210\uff01

      \u529f\u80fd\uff1a - \u96f6\u95e8\u69db\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5404\u79cd\u5927\u578b\u8bed\u8a00\u6a21\u578b - \u5feb\u901f\u90e8\u7f72 DeepSeek \u7b49\u5c16\u7aef AI \u6a21\u578b - \u4eab\u53d7\u7b80\u7ea6\u7684 API \u8c03\u7528\u4f53\u9a8c - \u6784\u5efa\u5b8c\u5168\u79bb\u7ebf\u7684\u667a\u80fd\u7f16\u7a0b\u73af\u5883

      \u80fd\u529b\uff1a - \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u52a0\u8f7d/\u7ba1\u7406 LLM \u6a21\u578b - \u57fa\u4e8e\u672c\u5730\u8ba1\u7b97\u7684\u5b9e\u65f6\u4f4e\u5ef6\u8fdf\u54cd\u5e94

      "},{"location":"whats-new/#v350","title":"v3.5.0","text":"
      • Python \u5347\u7ea7\u5230 3.12.8
      • \u6539\u8fdb\u4eea\u8868\u76d8\uff0c\u529f\u80fd\u66f4\u6e05\u6670\u3001\u66f4\u4eba\u6027\u5316
      • \u6dfb\u52a0\u4e86\u4f17\u591a\u7b2c\u4e09\u65b9\u5305\uff1aPyTorch / Twisted / Scrapy / FastAPI ...
      "},{"location":"whats-new/#v338","title":"v3.3.8","text":"
      • \u4fee\u590d\u4e86 NumPy \u517c\u5bb9\u6027\u95ee\u9898
      "},{"location":"whats-new/#v335","title":"v3.3.5","text":"
      • \u5347\u7ea7 Python \u5185\u6838\u5230 3.11.9
      • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u4e0d\u663e\u793a\u6a21\u5757\u5b89\u88c5\u72b6\u6001\u7684 bug
      • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u5220\u9664\u6a21\u5757\u5931\u8d25\u7684 bug
      • \u4fee\u590d\u4e86\u5176\u4ed6 bug
      "},{"location":"whats-new/#v334","title":"v3.3.4","text":"
      • \u6dfb\u52a0\u4e86 OpenAI/Langchain/APIGPTCloud AI \u5305
      • \u79fb\u9664\u4e0d\u5fc5\u8981\u7684\u6587\u4ef6\u4ee5\u51cf\u5c11\u5927\u5c0f
      "},{"location":"whats-new/#v325","title":"v3.2.5","text":"
      • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570
      • \u5176\u4ed6\u9519\u8bef\u4fee\u590d
      "},{"location":"whats-new/#v323","title":"v3.2.3","text":"
      • \u66f4\u65b0 Python \u7248\u672c\u5230 3.11.0
      • \u66f4\u65b0 IPython \u7248\u672c\u5230 8.6.0
      • \u66f4\u65b0 pip \u7248\u672c\u5230 22.3.1
      • \u66f4\u65b0\u79d1\u5b66\u8ba1\u7b97\u5305\uff0c\u81ea\u52a8\u8f6f\u94fe\u63a5
      • \u51cf\u5c11\u7a7a\u95f4\u4f7f\u7528
      • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570 + \u5176\u4ed6\u9519\u8bef\u4fee\u590d
      "},{"location":"whats-new/#v318","title":"v3.1.8","text":"
      • \u5728\u7ec8\u7aef\u4e2d\u6dfb\u52a0\u4e86\u64cd\u4f5c\u70ed\u952e
      • \u4fee\u590d\u4e86\u7f16\u8f91\u5668\u5728\u65cb\u8f6c\u65f6\u4e22\u5931\u5185\u5bb9\u7684\u95ee\u9898
      • \u4fee\u590d\u4e86\u5176\u4ed6 bug

      \u5728 Google Play \u4e0b\u8f7d

      "},{"location":"qsl4a/","title":"QSL4A\uff08Android \u811a\u672c\u5c42\uff09API \u6587\u6863","text":"

      QSL4A \u662f QPython \u7684 Android \u811a\u672c\u5c42\uff0c\u5141\u8bb8\u60a8\u4f7f\u7528 Python \u63a7\u5236 Android \u8bbe\u5907\u529f\u80fd\u3002

      "},{"location":"qsl4a/#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a toast \u6d88\u606f\ndroid.makeToast('Hello QPython!')\n\n# \u9707\u52a8\u8bbe\u5907\ndroid.vibrate(500)\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\uff08\u5148\u5f00\u59cb\u76d1\u63a7\uff09\nimport time\ndroid.batteryStartMonitoring()\ntime.sleep(0.5)  # \u7b49\u5f85\u6570\u636e\nbattery = droid.readBatteryData().result\nprint(f\"\u7535\u6c60\uff1a{battery['level']}%\")\n
      "},{"location":"qsl4a/#_2","title":"\u6587\u6863\u7ed3\u6784","text":""},{"location":"qsl4a/#_3","title":"\u6838\u5fc3\u6a21\u5757","text":"
      • Android \u57fa\u7840 - \u6838\u5fc3\u8fde\u63a5\u548c RPC
      • Intent \u7cfb\u7edf - Android Intent \u64cd\u4f5c
      • \u4e8b\u4ef6\u7cfb\u7edf - \u4e8b\u4ef6\u5904\u7406\u548c\u5e7f\u64ad
      "},{"location":"qsl4a/#ui","title":"UI \u7ec4\u4ef6","text":"
      • \u5bf9\u8bdd\u6846 - \u8b66\u62a5\u3001\u8f93\u5165\u3001\u9009\u62e9\u5bf9\u8bdd\u6846
      • \u5168\u5c4f UI - \u81ea\u5b9a\u4e49\u5e03\u5c40 UI
      • \u60ac\u6d6e\u7a97 - \u60ac\u6d6e\u7a97\u53e3
      • \u8f85\u52a9\u529f\u80fd - \u5c4f\u5e55\u81ea\u52a8\u5316
      "},{"location":"qsl4a/#_4","title":"\u7cfb\u7edf","text":"
      • \u7535\u6c60 - \u7535\u6c60\u76d1\u63a7
      • \u4f20\u611f\u5668 - \u8bbe\u5907\u4f20\u611f\u5668
      • \u5e94\u7528 - \u5e94\u7528\u7ba1\u7406
      • \u7cfb\u7edf\u4fe1\u606f - \u8bbe\u5907\u4fe1\u606f
      • \u8bbe\u7f6e - \u7cfb\u7edf\u8bbe\u7f6e
      • \u5524\u9192\u9501 - \u5524\u9192\u9501\u63a7\u5236
      • QPython \u63a5\u53e3 - \u811a\u672c\u6267\u884c
      • Activity \u7ed3\u679c - Activity \u7ed3\u679c\u5904\u7406
      "},{"location":"qsl4a/#_5","title":"\u786c\u4ef6","text":"
      • \u84dd\u7259 - \u84dd\u7259\u64cd\u4f5c
      • \u76f8\u673a - \u62cd\u7167\u548c\u5f55\u50cf
      • \u97f3\u9891/\u5f55\u97f3\u5668 - \u5f55\u97f3
      • \u7f51\u7edc\u6444\u50cf\u5934 - MJPEG \u6d41
      • USB \u4e32\u53e3 - USB \u4e3b\u673a\u4e32\u53e3
      "},{"location":"qsl4a/#_6","title":"\u8fde\u63a5","text":"
      • WiFi - WiFi \u64cd\u4f5c
      • \u4f4d\u7f6e - GPS \u548c\u4f4d\u7f6e
      • \u77ed\u4fe1 - \u77ed\u4fe1\u64cd\u4f5c
      • \u7535\u8bdd - \u6253\u7535\u8bdd\u548c\u6765\u7535\u4fe1\u606f
      • \u8054\u7cfb\u4eba - \u8054\u7cfb\u4eba\u7ba1\u7406
      • \u4fe1\u53f7\u5f3a\u5ea6 - \u4fe1\u53f7\u76d1\u63a7
      • FTP \u670d\u52a1\u5668 - \u5185\u7f6e FTP \u670d\u52a1\u5668
      "},{"location":"qsl4a/#_7","title":"\u5b58\u50a8","text":"
      • DocumentFile - \u6587\u4ef6\u64cd\u4f5c
      • \u526a\u8d34\u677f - \u526a\u8d34\u677f\u64cd\u4f5c
      • \u504f\u597d\u8bbe\u7f6e - \u5171\u4eab\u504f\u597d\u8bbe\u7f6e
      "},{"location":"qsl4a/#_8","title":"\u5a92\u4f53","text":"
      • \u5a92\u4f53\u64ad\u653e\u5668 - \u97f3\u9891/\u89c6\u9891\u64ad\u653e
      • \u56fe\u50cf\u5904\u7406 - \u56fe\u50cf\u64cd\u4f5c
      "},{"location":"qsl4a/#_9","title":"\u7279\u6b8a\u529f\u80fd","text":"
      • \u52a0\u5bc6 - \u52a0\u5bc6/\u89e3\u5bc6
      • PGPT AI - AI \u8bed\u97f3\u670d\u52a1
      "},{"location":"qsl4a/#_10","title":"\u7ed3\u679c\u5bf9\u8c61","text":"

      \u5927\u591a\u6570 QSL4A \u65b9\u6cd5\u8fd4\u56de\u4e00\u4e2a\u5e26\u6709\u4ee5\u4e0b\u5c5e\u6027\u7684 Result \u547d\u540d\u5143\u7ec4\uff1a - id - \u8bf7\u6c42 ID - result - \u5b9e\u9645\u7ed3\u679c\u6570\u636e - error - \u5982\u679c\u5931\u8d25\u5219\u4e3a\u9519\u8bef\u6d88\u606f

      result = droid.getClipboard()\nif result.error is None:\n    print(result.result)\nelse:\n    print(f\"\u9519\u8bef\uff1a{result.error}\")\n
      "},{"location":"qsl4a/connectivity/contacts/","title":"\u8054\u7cfb\u4eba API","text":"

      \u8bbf\u95ee\u548c\u7ba1\u7406\u8bbe\u5907\u8054\u7cfb\u4eba\u3002

      "},{"location":"qsl4a/connectivity/contacts/#_1","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":""},{"location":"qsl4a/connectivity/contacts/#pickcontact","title":"pickContact()","text":"

      \u663e\u793a\u8054\u7cfb\u4eba\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

      pickContact()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u8054\u7cfb\u4eba URI \u7684 Intent

      "},{"location":"qsl4a/connectivity/contacts/#pickphone","title":"pickPhone()","text":"

      \u663e\u793a\u7535\u8bdd\u53f7\u7801\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

      pickPhone()\n

      \u8fd4\u56de\uff1a \u9009\u4e2d\u7684\u7535\u8bdd\u53f7\u7801\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/contacts/#_2","title":"\u8054\u7cfb\u4eba\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#contactsget","title":"contactsGet()","text":"

      \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\u3002

      contactsGet(attributes=None)\n

      \u53c2\u6570\uff1a - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

      \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba JSONObject \u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetbyid","title":"contactsGetById()","text":"

      \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\u3002

      contactsGetById(id, attributes=None)\n

      \u53c2\u6570\uff1a - id (int): \u8054\u7cfb\u4eba ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

      \u8fd4\u56de\uff1a JSONObject \u8054\u7cfb\u4eba\u6570\u636e

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetcount","title":"contactsGetCount()","text":"

      \u83b7\u53d6\u8054\u7cfb\u4eba\u603b\u6570\u3002

      contactsGetCount()\n

      \u8fd4\u56de\uff1a \u6574\u6570\u8ba1\u6570

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetids","title":"contactsGetIds()","text":"

      \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba ID\u3002

      contactsGetIds()\n

      \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba ID \u6574\u6570\u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetattributes","title":"contactsGetAttributes()","text":"

      \u83b7\u53d6\u6240\u6709\u53ef\u80fd\u7684\u8054\u7cfb\u4eba\u5c5e\u6027\u3002

      contactsGetAttributes()\n

      \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#_3","title":"\u5185\u5bb9\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#querycontent","title":"queryContent()","text":"

      \u4f7f\u7528\u81ea\u5b9a\u4e49\u53c2\u6570\u67e5\u8be2\u5185\u5bb9\u89e3\u6790\u5668\u3002

      queryContent(uri, attributes=None, selection=None, selectionArgs=None, order=None)\n

      \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u5c5e\u6027 - selection (str, optional): WHERE \u5b50\u53e5 - selectionArgs (list, optional): \u9009\u62e9\u53c2\u6570 - order (str, optional): ORDER BY \u5b50\u53e5

      \u8fd4\u56de\uff1a JSONObject \u7ed3\u679c\u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#queryattributes","title":"queryAttributes()","text":"

      \u83b7\u53d6\u5185\u5bb9 URI \u7684\u5c5e\u6027\u3002

      queryAttributes(uri)\n

      \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI

      \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u7684 JSONArray

      "},{"location":"qsl4a/connectivity/contacts/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u9009\u62e9\u8054\u7cfb\u4eba\ncontact_uri = droid.pickContact().result\nprint(f\"Selected contact: {contact_uri}\")\n\n# \u9009\u62e9\u7535\u8bdd\u53f7\u7801\nphone = droid.pickPhone().result\nprint(f\"Selected phone: {phone}\")\n\n# \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\ncontacts = droid.contactsGet().result\nprint(f\"Total contacts: {len(contacts)}\")\n\n# \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\ncontact = droid.contactsGetById(1).result\nprint(f\"Contact: {contact}\")\n\n# \u83b7\u53d6\u8054\u7cfb\u4eba\u5c5e\u6027\nattrs = droid.contactsGetAttributes().result\nprint(f\"Available attributes: {attrs}\")\n
      "},{"location":"qsl4a/connectivity/ftp/","title":"FTP \u670d\u52a1\u5668 API","text":"

      \u5728\u8bbe\u5907\u4e0a\u542f\u52a8\u548c\u7ba1\u7406\u5185\u7f6e FTP \u670d\u52a1\u5668\u3002

      "},{"location":"qsl4a/connectivity/ftp/#ftp","title":"FTP \u670d\u52a1\u5668\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/ftp/#ftpstart","title":"ftpStart()","text":"

      \u542f\u52a8 FTP \u670d\u52a1\u5668\u3002

      ftpStart()\n

      \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4 [ip, port]

      "},{"location":"qsl4a/connectivity/ftp/#ftpstop","title":"ftpStop()","text":"

      \u505c\u6b62 FTP \u670d\u52a1\u5668\u3002

      ftpStop()\n
      "},{"location":"qsl4a/connectivity/ftp/#ftpisrunning","title":"ftpIsRunning()","text":"

      \u68c0\u67e5 FTP \u670d\u52a1\u5668\u662f\u5426\u6b63\u5728\u8fd0\u884c\u3002

      ftpIsRunning()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u8fd0\u884c\u5219\u4e3a True

      "},{"location":"qsl4a/connectivity/ftp/#ftpget","title":"ftpGet()","text":"

      \u83b7\u53d6 FTP \u670d\u52a1\u5668 IP \u5730\u5740\u3002

      ftpGet()\n

      \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4

      "},{"location":"qsl4a/connectivity/ftp/#ftpset","title":"ftpSet()","text":"

      \u914d\u7f6e FTP \u670d\u52a1\u5668\u8bbe\u7f6e\u3002

      ftpSet(port=None, rootDir=None, username=None, password=None)\n

      \u53c2\u6570\uff1a - port (int, optional): \u670d\u52a1\u5668\u7aef\u53e3 - rootDir (str, optional): \u8981\u670d\u52a1\u7684\u57fa\u7840\u76ee\u5f55 - username (str, optional): \u767b\u5f55\u7528\u6237\u540d - password (str, optional): \u767b\u5f55\u5bc6\u7801

      \u8fd4\u56de\uff1a \u5305\u542b\u5f53\u524d\u8bbe\u7f6e\u7684 JSONObject

      "},{"location":"qsl4a/connectivity/ftp/#ftpstatus","title":"ftpStatus()","text":"

      \u83b7\u53d6 FTP \u670d\u52a1\u5668\u72b6\u6001\u3002

      ftpStatus()\n

      \u8fd4\u56de\uff1a \u72b6\u6001\u63cf\u8ff0\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/ftp/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u914d\u7f6e FTP \u670d\u52a1\u5668\ndroid.ftpSet(\n    port=2121,\n    rootDir=\"/sdcard\",\n    username=\"admin\",\n    password=\"secret\"\n)\n\n# \u542f\u52a8 FTP \u670d\u52a1\u5668\ninfo = droid.ftpStart().result\nprint(f\"FTP running at {info[0]}:{info[1]}\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.ftpIsRunning().result:\n    print(\"FTP server is running\")\n\n# \u83b7\u53d6\u670d\u52a1\u5668\u4fe1\u606f\nserver_info = droid.ftpGet().result\nprint(f\"Server: {server_info}\")\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.ftpStop()\n

      \u6ce8\u610f\uff1a \u4f7f\u7528\u63d0\u4f9b\u7684\u51ed\u636e\u901a\u8fc7\u4efb\u4f55 FTP \u5ba2\u6237\u7aef\u8fde\u63a5\u5230 FTP \u670d\u52a1\u5668\u3002

      "},{"location":"qsl4a/connectivity/location/","title":"\u4f4d\u7f6e API","text":"

      \u8bbf\u95ee GPS \u548c\u7f51\u7edc\u4f4d\u7f6e\u670d\u52a1\u3002

      "},{"location":"qsl4a/connectivity/location/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/location/#startlocating","title":"startLocating()","text":"

      \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\u3002

      startLocating(minUpdateTime=60000, minUpdateDistance=30, updateGnssStatus=False)\n

      \u53c2\u6570\uff1a - minUpdateTime (int): \u66f4\u65b0\u4e4b\u95f4\u7684\u6700\u5c0f\u65f6\u95f4\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a60000\uff09 - minUpdateDistance (float): \u66f4\u65b0\u7684\u6700\u5c0f\u8ddd\u79bb\uff08\u7c73\uff09\uff08\u9ed8\u8ba4\uff1a30\uff09 - updateGnssStatus (bool): \u542f\u7528 GNSS \u72b6\u6001\u66f4\u65b0\uff08\u9ed8\u8ba4\uff1aFalse\uff09

      "},{"location":"qsl4a/connectivity/location/#stoplocating","title":"stopLocating()","text":"

      \u505c\u6b62\u4f4d\u7f6e\u66f4\u65b0\u3002

      stopLocating()\n
      "},{"location":"qsl4a/connectivity/location/#readlocation","title":"readLocation()","text":"

      \u83b7\u53d6\u6700\u540e\u5df2\u77e5\u4f4d\u7f6e\u3002

      readLocation()\n

      \u8fd4\u56de\uff1a \u4f4d\u7f6e\u6570\u636e\u5b57\u5178

      "},{"location":"qsl4a/connectivity/location/#getlastknownlocation","title":"getLastKnownLocation()","text":"

      \u83b7\u53d6\u7f13\u5b58\u7684\u4f4d\u7f6e\u3002

      getLastKnownLocation()\n

      \u8fd4\u56de\uff1a \u6765\u81ea\u6240\u6709\u63d0\u4f9b\u5546\u7684\u4f4d\u7f6e

      "},{"location":"qsl4a/connectivity/location/#geocode","title":"geocode()","text":"

      \u5c06\u5730\u5740\u8f6c\u6362\u4e3a\u5750\u6807\u3002

      geocode(address, maxResults=1)\n
      "},{"location":"qsl4a/connectivity/location/#_2","title":"\u4f4d\u7f6e\u63d0\u4f9b\u5546\u65b9\u6cd5)","text":""},{"location":"qsl4a/connectivity/location/#locationproviders","title":"locationProviders()","text":"

      \u83b7\u53d6\u624b\u673a\u4e0a\u53ef\u7528\u7684\u4f4d\u7f6e\u63d0\u4f9b\u5546\u3002

      locationProviders()\n

      \u8fd4\u56de\uff1a \u53ef\u7528\u63d0\u4f9b\u5546\u540d\u79f0\u5217\u8868\uff08\u4f8b\u5982 ['gps', 'network']\uff09

      "},{"location":"qsl4a/connectivity/location/#locationproviderenabled","title":"locationProviderEnabled()","text":"

      \u68c0\u67e5\u7279\u5b9a\u4f4d\u7f6e\u63d0\u4f9b\u5546\u662f\u5426\u5df2\u542f\u7528\u3002

      locationProviderEnabled(provider)\n

      \u53c2\u6570\uff1a - provider (str): \u63d0\u4f9b\u5546\u540d\u79f0\uff08\u4f8b\u5982 'gps', 'network'\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/connectivity/location/#readgnssstatus","title":"readGnssStatus()","text":"

      \u8bfb\u53d6\u5168\u7403\u5bfc\u822a\u536b\u661f\u7cfb\u7edf\u72b6\u6001\uff08\u9700\u8981 Android 8+\uff09\u3002

      readGnssStatus()\n

      \u8fd4\u56de\uff1a \u5305\u542b GNSS \u536b\u661f\u4fe1\u606f\u7684 JSONArray

      "},{"location":"qsl4a/connectivity/location/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\ndroid.startLocating(minUpdateTime=5000, minUpdateDistance=1, updateGnssStatus=False)\n\n# \u7b49\u5f85\u5b9a\u4f4d\ntime.sleep(10)\n\n# \u83b7\u53d6\u4f4d\u7f6e\nloc = droid.readLocation().result\nif loc:\n    lat = loc['latitude']\n    lon = loc['longitude']\n    print(f\"Location: {lat}, {lon}\")\n\ndroid.stopLocating()\n
      "},{"location":"qsl4a/connectivity/phone/","title":"\u7535\u8bdd API","text":"

      \u63a7\u5236\u7535\u8bdd\u901a\u8bdd\u548c\u83b7\u53d6\u7535\u8bdd\u4fe1\u606f\u3002

      "},{"location":"qsl4a/connectivity/phone/#_1","title":"\u7535\u8bdd\u72b6\u6001\u8ddf\u8e2a","text":""},{"location":"qsl4a/connectivity/phone/#starttrackingphonestate","title":"startTrackingPhoneState()","text":"

      \u5f00\u59cb\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u53d8\u5316\u3002\u751f\u6210 'phone' \u4e8b\u4ef6\u3002

      startTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/phone/#readphonestate","title":"readPhoneState()","text":"

      \u8bfb\u53d6\u5f53\u524d\u7535\u8bdd\u72b6\u6001\u3002

      readPhoneState()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7535\u8bdd\u72b6\u6001\u548c\u6765\u7535\u53f7\u7801\u7684 Bundle

      "},{"location":"qsl4a/connectivity/phone/#stoptrackingphonestate","title":"stopTrackingPhoneState()","text":"

      \u505c\u6b62\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u3002

      stopTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/phone/#_2","title":"\u62e8\u6253\u7535\u8bdd","text":""},{"location":"qsl4a/connectivity/phone/#phonecall","title":"phoneCall()","text":"

      \u901a\u8fc7 URI \u547c\u53eb\u8054\u7cfb\u4eba/\u7535\u8bdd\u53f7\u7801\u3002

      phoneCall(uri)\n

      \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

      "},{"location":"qsl4a/connectivity/phone/#phonecallnumber","title":"phoneCallNumber()","text":"

      \u76f4\u63a5\u62e8\u6253\u7535\u8bdd\u53f7\u7801\u3002

      phoneCallNumber(phone_number)\n

      \u53c2\u6570\uff1a - phone_number (str): \u8981\u62e8\u6253\u7684\u7535\u8bdd\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#phonedial","title":"phoneDial()","text":"

      \u62e8\u6253\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

      phoneDial(uri)\n

      \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

      "},{"location":"qsl4a/connectivity/phone/#phonedialnumber","title":"phoneDialNumber()","text":"

      \u62e8\u6253\u7535\u8bdd\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

      phoneDialNumber(phone_number)\n

      \u53c2\u6570\uff1a - phone_number (str): \u7535\u8bdd\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#_3","title":"\u57fa\u7ad9\u4f4d\u7f6e","text":""},{"location":"qsl4a/connectivity/phone/#getcelllocation","title":"getCellLocation()","text":"

      \u83b7\u53d6\u5f53\u524d\u57fa\u7ad9\u4f4d\u7f6e\u3002

      getCellLocation()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u57fa\u7ad9\u4f4d\u7f6e\u6570\u636e\u7684 JSONObject

      "},{"location":"qsl4a/connectivity/phone/#getallcellslocation","title":"getAllCellsLocation()","text":"

      \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u4f4d\u7f6e\uff08\u9002\u7528\u4e8e\u53cc\u5361\u8bbe\u5907\uff09\u3002

      getAllCellsLocation()\n

      \u8fd4\u56de\uff1a \u57fa\u7ad9\u4f4d\u7f6e\u7684 JSONArray

      "},{"location":"qsl4a/connectivity/phone/#_4","title":"\u7f51\u7edc\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getnetworkoperator","title":"getNetworkOperator()","text":"

      \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

      getNetworkOperator()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getnetworkoperatorname","title":"getNetworkOperatorName()","text":"

      \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684\u540d\u79f0\u3002

      getNetworkOperatorName()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getnetworktype","title":"getNetworkType()","text":"

      \u83b7\u53d6\u5f53\u524d\u7f51\u7edc\u7c7b\u578b\u3002

      getNetworkType()\n

      \u8fd4\u56de\uff1a \u63cf\u8ff0\u65e0\u7ebf\u7535\u6280\u672f\u7684\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'LTE', 'UMTS', 'GSM'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getphonetype","title":"getPhoneType()","text":"

      \u83b7\u53d6\u7535\u8bdd\u7c7b\u578b\u3002

      getPhoneType()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'GSM', 'CDMA', 'SIP'\uff09

      "},{"location":"qsl4a/connectivity/phone/#sim","title":"SIM \u5361\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getsimcountryiso","title":"getSimCountryIso()","text":"

      \u83b7\u53d6 SIM \u5361\u7684 ISO \u56fd\u5bb6\u4ee3\u7801\u3002

      getSimCountryIso()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'us'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getsimoperator","title":"getSimOperator()","text":"

      \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

      getSimOperator()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getsimoperatorname","title":"getSimOperatorName()","text":"

      \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u540d\u79f0\u3002

      getSimOperatorName()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getsimserialnumber","title":"getSimSerialNumber()","text":"

      \u83b7\u53d6 SIM \u5e8f\u5217\u53f7\u3002

      getSimSerialNumber()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32 SIM \u5e8f\u5217\u53f7

      "},{"location":"qsl4a/connectivity/phone/#getsimstate","title":"getSimState()","text":"

      \u83b7\u53d6 SIM \u5361\u72b6\u6001\u3002

      getSimState()\n

      \u8fd4\u56de\uff1a \u63cf\u8ff0 SIM \u72b6\u6001\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/phone/#getsubscriberid","title":"getSubscriberId()","text":"

      \u83b7\u53d6\u8ba2\u9605\u8005 ID\u3002

      getSubscriberId()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8ba2\u9605\u8005 ID

      "},{"location":"qsl4a/connectivity/phone/#_5","title":"\u8bed\u97f3\u90ae\u4ef6","text":""},{"location":"qsl4a/connectivity/phone/#getvoicemailalphatag","title":"getVoiceMailAlphaTag()","text":"

      \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u5b57\u6bcd\u6807\u7b7e\u3002

      getVoiceMailAlphaTag()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u6807\u7b7e

      "},{"location":"qsl4a/connectivity/phone/#getvoicemailnumber","title":"getVoiceMailNumber()","text":"

      \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801\u3002

      getVoiceMailNumber()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getdeviceid","title":"getDeviceId()","text":"

      \u83b7\u53d6\u8bbe\u5907 ID\uff08GSM \u7684 IMEI\uff09\u3002\u5df2\u5e9f\u5f03\u3002

      getDeviceId()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

      "},{"location":"qsl4a/connectivity/phone/#getdevicesoftwareversion","title":"getDeviceSoftwareVersion()","text":"

      \u83b7\u53d6\u8bbe\u5907\u8f6f\u4ef6\u7248\u672c\u3002

      getDeviceSoftwareVersion()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8f6f\u4ef6\u7248\u672c

      "},{"location":"qsl4a/connectivity/phone/#getline1number","title":"getLine1Number()","text":"

      \u83b7\u53d6\u7ebf\u8def 1 \u7535\u8bdd\u53f7\u7801\u3002

      getLine1Number()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u7535\u8bdd\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#checknetworkroaming","title":"checkNetworkRoaming()","text":"

      \u68c0\u67e5\u662f\u5426\u8fde\u63a5\u5230\u6f2b\u6e38\u7f51\u7edc\u3002

      checkNetworkRoaming()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u6f2b\u6e38\u5219\u4e3a True

      "},{"location":"qsl4a/connectivity/phone/#_7","title":"\u57fa\u7ad9\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getallcellinfo","title":"getAllCellInfo()","text":"

      \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u7684\u4fe1\u606f\u3002

      getAllCellInfo()\n

      \u8fd4\u56de\uff1a \u57fa\u7ad9\u4fe1\u606f\u5217\u8868

      "},{"location":"qsl4a/connectivity/phone/#setdataenabled","title":"setDataEnabled()","text":"

      \u542f\u7528\u6216\u7981\u7528\u79fb\u52a8\u6570\u636e\u3002

      setDataEnabled(enabled)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528

      "},{"location":"qsl4a/connectivity/phone/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7f51\u7edc\u4fe1\u606f\noperator = droid.getNetworkOperatorName().result\nprint(f\"Operator: {operator}\")\n\nnetwork_type = droid.getNetworkType().result\nprint(f\"Network: {network_type}\")\n\n# \u83b7\u53d6 SIM \u4fe1\u606f\nsim_state = droid.getSimState().result\nprint(f\"SIM: {sim_state}\")\n\n# \u83b7\u53d6\u7535\u8bdd\u53f7\u7801\nline1 = droid.getLine1Number().result\nprint(f\"Phone: {line1}\")\n\n# \u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\ndroid.startTrackingPhoneState()\nprint(\"Tracking phone state...\")\ndroid.stopTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/signalstrength/","title":"\u4fe1\u53f7\u5f3a\u5ea6 API","text":"

      \u76d1\u63a7\u8702\u7a9d\u548c\u65e0\u7ebf\u4fe1\u53f7\u5f3a\u5ea6\u3002

      "},{"location":"qsl4a/connectivity/signalstrength/#_1","title":"\u4fe1\u53f7\u5f3a\u5ea6\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/signalstrength/#starttrackingsignalstrengths","title":"startTrackingSignalStrengths()","text":"

      \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316\u3002\u751f\u6210 'signal_strengths' \u4e8b\u4ef6\u3002

      startTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/signalstrength/#stoptrackingsignalstrengths","title":"stopTrackingSignalStrengths()","text":"

      \u505c\u6b62\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u3002

      stopTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/signalstrength/#readsignalstrengths","title":"readSignalStrengths()","text":"

      \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\u3002

      readSignalStrengths()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u4fe1\u53f7\u5f3a\u5ea6\u6570\u636e\u7684 Bundle

      "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthlevel","title":"getTelephoneSignalStrengthLevel()","text":"

      \u83b7\u53d6\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u7b49\u7ea7\uff080-4\uff09\u3002

      getTelephoneSignalStrengthLevel()\n

      \u8fd4\u56de\uff1a \u6574\u6570\u7b49\u7ea7\uff080=\u65e0\uff0c1=\u5dee\uff0c2=\u4e00\u822c\uff0c3=\u597d\uff0c4=\u4f18\u79c0\uff09

      "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthdetail","title":"getTelephoneSignalStrengthDetail()","text":"

      \u83b7\u53d6\u8be6\u7ec6\u7684\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u4fe1\u606f\u3002

      getTelephoneSignalStrengthDetail()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u8be6\u7ec6\u4fe1\u53f7\u4fe1\u606f\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/signalstrength/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\ndroid.startTrackingSignalStrengths()\n\n# \u7b49\u5f85\u4fe1\u53f7\u66f4\u65b0\ntime.sleep(5)\n\n# \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\nsignal = droid.readSignalStrengths().result\nprint(f\"Signal: {signal}\")\n\n# \u76f4\u63a5\u83b7\u53d6\u7b49\u7ea7\nlevel = droid.getTelephoneSignalStrengthLevel().result\nprint(f\"Signal level: {level}/4\")\n\ndroid.stopTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/sms/","title":"SMS API","text":"

      \u53d1\u9001\u548c\u63a5\u6536 SMS \u6d88\u606f\u3002

      "},{"location":"qsl4a/connectivity/sms/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/sms/#smssend","title":"smsSend()","text":"

      \u53d1\u9001 SMS \u6d88\u606f\u3002

      smsSend(destinationAddress, text)\n

      \u53c2\u6570\uff1a - destinationAddress (str): \u7535\u8bdd\u53f7\u7801 - text (str): \u6d88\u606f\u6587\u672c

      "},{"location":"qsl4a/connectivity/sms/#smsgetmessagecount","title":"smsGetMessageCount()","text":"

      \u83b7\u53d6\u6d88\u606f\u6570\u91cf\u3002

      smsGetMessageCount(unreadOnly=False, folder=\"inbox\")\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessageids","title":"smsGetMessageIds()","text":"

      \u83b7\u53d6\u6d88\u606f ID\u3002

      smsGetMessageIds(unreadOnly=False, folder=\"inbox\")\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessages","title":"smsGetMessages()","text":"

      \u83b7\u53d6\u6d88\u606f\u8be6\u60c5\u3002

      smsGetMessages(unreadOnly=False, folder=\"inbox\", attributes=None)\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessagebyid","title":"smsGetMessageById()","text":"

      \u901a\u8fc7 ID \u83b7\u53d6\u7279\u5b9a\u6d88\u606f\u3002

      smsGetMessageById(id, attributes=None)\n

      \u53c2\u6570\uff1a - id (int): \u6d88\u606f ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

      \u8fd4\u56de\uff1a \u6d88\u606f\u6570\u636e\u5b57\u5178

      "},{"location":"qsl4a/connectivity/sms/#smsgetattributes","title":"smsGetAttributes()","text":"

      \u83b7\u53d6\u53ef\u7528\u7684 SMS \u6d88\u606f\u5c5e\u6027\u3002

      smsGetAttributes()\n

      \u8fd4\u56de\uff1a \u53ef\u7528\u5c5e\u6027\u540d\u79f0\u5217\u8868

      "},{"location":"qsl4a/connectivity/sms/#smsdeletemessage","title":"smsDeleteMessage()","text":"

      \u5220\u9664\u6d88\u606f\u3002

      smsDeleteMessage(id)\n
      "},{"location":"qsl4a/connectivity/sms/#smsmarkmessageread","title":"smsMarkMessageRead()","text":"

      \u5c06\u6d88\u606f\u6807\u8bb0\u4e3a\u5df2\u8bfb\u3002

      smsMarkMessageRead(ids, read=True)\n
      "},{"location":"qsl4a/connectivity/sms/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u53d1\u9001 SMS\ndroid.smsSend(\"+1234567890\", \"Hello from QPython!\")\n\n# \u83b7\u53d6\u672a\u8bfb\u6d88\u606f\nmessages = droid.smsGetMessages(unreadOnly=True).result\nfor msg in messages:\n    print(f\"From: {msg['address']}, Text: {msg['body']}\")\n
      "},{"location":"qsl4a/connectivity/wifi/","title":"WiFi API","text":"

      \u63a7\u5236 WiFi \u9002\u914d\u5668\u5e76\u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\u3002

      "},{"location":"qsl4a/connectivity/wifi/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/connectivity/wifi/#checkwifistate","title":"checkWifiState()","text":"

      \u68c0\u67e5 WiFi \u662f\u5426\u5df2\u542f\u7528\u3002

      checkWifiState()\n

      \u8fd4\u56de\uff1a \u5982\u679c WiFi \u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/connectivity/wifi/#togglewifistate","title":"toggleWifiState()","text":"

      \u6253\u5f00\u6216\u5173\u95ed WiFi\u3002

      toggleWifiState(enabled=None)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

      \u8fd4\u56de\uff1a \u5982\u679c\u64cd\u4f5c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/connectivity/wifi/#wifistartscan","title":"wifiStartScan()","text":"

      \u5f00\u59cb\u626b\u63cf\u53ef\u7528\u7684 WiFi \u7f51\u7edc\u3002

      wifiStartScan()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifigetscanresults","title":"wifiGetScanResults()","text":"

      \u83b7\u53d6\u53d1\u73b0\u7684 WiFi \u7f51\u7edc\u5217\u8868\u3002

      wifiGetScanResults()\n

      \u8fd4\u56de\uff1a \u63a5\u5165\u70b9\u4fe1\u606f\u5217\u8868

      "},{"location":"qsl4a/connectivity/wifi/#_2","title":"\u8fde\u63a5\u7ba1\u7406","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetconnectioninfo","title":"wifiGetConnectionInfo()","text":"

      \u83b7\u53d6\u8be6\u7ec6\u8fde\u63a5\u4fe1\u606f\u3002

      wifiGetConnectionInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001IP \u5730\u5740\u7b49\u8fde\u63a5\u8be6\u60c5\u7684\u5b57\u5178

      "},{"location":"qsl4a/connectivity/wifi/#getconnectedinfo","title":"getConnectedInfo()","text":"

      \u83b7\u53d6\u8fde\u63a5\u7684 WiFi \u7f51\u7edc\u4fe1\u606f\uff08\u7b80\u5316\u7248\uff09\u3002

      getConnectedInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001\u4fe1\u53f7\u5f3a\u5ea6\u7684\u5b57\u5178

      "},{"location":"qsl4a/connectivity/wifi/#getdhcpinfo","title":"getDhcpInfo()","text":"

      \u83b7\u53d6\u5f53\u524d\u8fde\u63a5\u7684 DHCP \u4fe1\u606f\u3002

      getDhcpInfo(ipConvertToString=True)\n

      \u53c2\u6570\uff1a - ipConvertToString (bool): \u5c06 IP \u5730\u5740\u8f6c\u6362\u4e3a\u5b57\u7b26\u4e32\u683c\u5f0f\uff08\u9ed8\u8ba4\uff1aTrue\uff09

      \u8fd4\u56de\uff1a \u5305\u542b IP\u3001\u7f51\u5173\u3001DNS \u7b49 DHCP \u4fe1\u606f\u7684\u5b57\u5178

      "},{"location":"qsl4a/connectivity/wifi/#wifidisconnect","title":"wifiDisconnect()","text":"

      \u65ad\u5f00\u5f53\u524d WiFi \u7f51\u7edc\u8fde\u63a5\u3002

      wifiDisconnect()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifireconnect","title":"wifiReconnect()","text":"

      \u91cd\u65b0\u8fde\u63a5\u5230\u5f53\u524d\u7f51\u7edc\u3002

      wifiReconnect()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifireassociate","title":"wifiReassociate()","text":"

      \u91cd\u65b0\u5173\u8054\u5f53\u524d\u63a5\u5165\u70b9\u3002

      wifiReassociate()\n
      "},{"location":"qsl4a/connectivity/wifi/#_3","title":"\u70ed\u70b9","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetapstate","title":"wifiGetApState()","text":"

      \u83b7\u53d6 WiFi AP\uff08\u70ed\u70b9\uff09\u72b6\u6001\u3002

      wifiGetApState()\n

      \u8fd4\u56de\uff1a \u70ed\u70b9\u72b6\u6001

      "},{"location":"qsl4a/connectivity/wifi/#wifi","title":"WiFi \u9501","text":""},{"location":"qsl4a/connectivity/wifi/#wifilockacquirefull","title":"wifiLockAcquireFull()","text":"

      \u83b7\u53d6\u5b8c\u6574 WiFi \u9501\uff08\u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\u4e5f\u4fdd\u6301 WiFi \u6d3b\u52a8\uff09\u3002

      wifiLockAcquireFull()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifilockacquirescanonly","title":"wifiLockAcquireScanOnly()","text":"

      \u83b7\u53d6\u4ec5\u626b\u63cf WiFi \u9501\u3002

      wifiLockAcquireScanOnly()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifilockrelease","title":"wifiLockRelease()","text":"

      \u91ca\u653e WiFi \u9501\u3002

      wifiLockRelease()\n
      "},{"location":"qsl4a/connectivity/wifi/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u68c0\u67e5 WiFi \u72b6\u6001\nif droid.checkWifiState().result:\n    print(\"WiFi is enabled\")\nelse:\n    print(\"Enabling WiFi...\")\n    droid.toggleWifiState(True)\n    time.sleep(2)\n\n# \u5f00\u59cb\u626b\u63cf\ndroid.wifiStartScan()\ntime.sleep(3)\n\n# \u83b7\u53d6\u626b\u63cf\u7ed3\u679c\nnetworks = droid.wifiGetScanResults().result\nfor network in networks:\n    print(f\"SSID: {network.get('SSID')}, Signal: {network.get('level')} dBm\")\n\n# \u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\ninfo = droid.wifiGetConnectionInfo().result\nif info:\n    print(f\"Connected to: {info.get('ssid')}\")\n    print(f\"BSSID: {info.get('bssid')}\")\n    print(f\"IP: {info.get('ip_address')}\")\n\n# \u83b7\u53d6 DHCP \u4fe1\u606f\ndhcp = droid.getDhcpInfo().result\nif dhcp:\n    print(f\"Gateway: {dhcp.get('gateway')}\")\n    print(f\"DNS: {dhcp.get('dns1')}\")\n\n# \u83b7\u53d6\u7b80\u5316\u7684\u8fde\u63a5\u4fe1\u606f\nconnected = droid.getConnectedInfo().result\nprint(f\"SSID: {connected.get('ssid')}, Signal: {connected.get('level')} dBm\")\n\n# \u65ad\u5f00\u5e76\u91cd\u65b0\u8fde\u63a5\ndroid.wifiDisconnect()\ntime.sleep(1)\ndroid.wifiReconnect()\n\n# \u91cd\u65b0\u5173\u8054\u63a5\u5165\u70b9\ndroid.wifiReassociate()\n\n# \u68c0\u67e5\u70ed\u70b9\u72b6\u6001\nap_state = droid.wifiGetApState().result\nprint(f\"Hotspot state: {ap_state}\")\n\n# \u83b7\u53d6 WiFi \u9501\u4ee5\u8fdb\u884c\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireFull()\n# ... \u6267\u884c\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n\n# \u6216\u4f7f\u7528\u4ec5\u626b\u63cf\u9501\u4ee5\u8fdb\u884c\u8f83\u8f7b\u7684\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireScanOnly()\n# ... \u6267\u884c\u626b\u63cf\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n
      "},{"location":"qsl4a/core/android-base/","title":"Android \u57fa\u7840\u7c7b","text":"

      Android \u7c7b\u662f QSL4A \u7684\u6838\u5fc3\uff0c\u63d0\u4f9b\u4e86\u4e0e Android \u8fd0\u884c\u65f6\u7684\u8fde\u63a5\u548c RPC \u673a\u5236\u3002

      "},{"location":"qsl4a/core/android-base/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
      # \u529f\u80fd\u5b8c\u6574\u7248\u672c\uff08\u63a8\u8350\uff09\nimport androidhelper\ndroid = androidhelper.Android()\n\n# \u7b80\u5316\u7248\u672c\uff08\u5feb\u901f\uff0c\u5355\u5b9e\u4f8b\uff09\nimport android\ndroid = android.droid\n
      "},{"location":"qsl4a/core/android-base/#android_1","title":"\u7c7b\uff1aAndroid","text":""},{"location":"qsl4a/core/android-base/#_2","title":"\u6784\u9020\u51fd\u6570","text":"
      Android(addr=None)\n

      \u53c2\u6570\uff1a - addr (tuple, optional): (HOST, PORT) \u5730\u5740\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u73af\u5883\u53d8\u91cf AP_HOST \u548c AP_PORT

      \u73af\u5883\u53d8\u91cf\uff1a - AP_HOST - \u670d\u52a1\u5668\u4e3b\u673a\u5730\u5740 - AP_PORT - \u670d\u52a1\u5668\u7aef\u53e3 - AP_HANDSHAKE - \u8ba4\u8bc1\u4ee4\u724c

      "},{"location":"qsl4a/core/android-base/#_3","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/android-base/#_rpc","title":"_rpc()","text":"

      \u8c03\u7528 Android \u51fd\u6570\u7684\u5185\u90e8 RPC \u65b9\u6cd5\u3002

      _rpc(method, *args)\n

      \u53c2\u6570\uff1a - method (str): \u8981\u8c03\u7528\u7684\u65b9\u6cd5\u540d - *args: \u65b9\u6cd5\u7684\u53ef\u53d8\u53c2\u6570

      \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4\uff0c\u5305\u542b\u4ee5\u4e0b\u5b57\u6bb5\uff1a - id (int): \u8bf7\u6c42 ID - result: \u65b9\u6cd5\u8fd4\u56de\u503c - error (str or None): \u9519\u8bef\u4fe1\u606f\uff08\u5982\u679c\u5931\u8d25\uff09

      "},{"location":"qsl4a/core/android-base/#getattr","title":"getattr()","text":"

      \u52a8\u6001\u65b9\u6cd5\u5206\u53d1\u5668\u3002\u6240\u6709 Android \u65b9\u6cd5\u90fd\u901a\u8fc7\u5c5e\u6027\u67e5\u627e\u8bbf\u95ee\u3002

      # \u4ee5\u4e0b\u4e24\u79cd\u65b9\u5f0f\u7b49\u4ef7\uff1a\ndroid.makeToast(\"Hello\")\ndroid._rpc(\"makeToast\", \"Hello\")\n
      "},{"location":"qsl4a/core/android-base/#androidpy","title":"\u72ec\u7acb\u51fd\u6570\uff08android.py\uff09","text":"

      \u4f7f\u7528\u7b80\u5316\u7684 android \u6a21\u5757\u65f6\uff1a

      "},{"location":"qsl4a/core/android-base/#jsla","title":"jsla()","text":"

      \u53d1\u9001 JSON-RPC \u8bf7\u6c42\u5e76\u8fd4\u56de\u539f\u59cb\u54cd\u5e94\u3002

      jsla(method, *params)\n

      \u8fd4\u56de\uff1a JSON \u5b57\u7b26\u4e32\u54cd\u5e94

      "},{"location":"qsl4a/core/android-base/#rsla","title":"rsla()","text":"

      \u53d1\u9001\u8bf7\u6c42\u5e76\u4ec5\u8fd4\u56de\u7ed3\u679c\u3002

      rsla(method, *params)\n

      \u8fd4\u56de\uff1a RPC \u8c03\u7528\u7684\u7ed3\u679c\u503c

      "},{"location":"qsl4a/core/android-base/#esla","title":"esla()","text":"

      \u53d1\u9001\u8bf7\u6c42\uff0c\u9519\u8bef\u65f6\u629b\u51fa\u5f02\u5e38\u3002

      esla(method, *params)\n

      \u629b\u51fa\uff1a \u5982\u679c error \u5b57\u6bb5\u4e0d\u4e3a None \u5219\u629b\u51fa\u5f02\u5e38

      "},{"location":"qsl4a/core/android-base/#nsla","title":"nsla()","text":"

      \u53d1\u9001\u8bf7\u6c42\u5e76\u8fd4\u56de Result \u547d\u540d\u5143\u7ec4\u3002

      nsla(method, *params)\n

      \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4

      "},{"location":"qsl4a/core/android-base/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/android-base/#_5","title":"\u57fa\u672c\u8fde\u63a5","text":"
      import androidhelper\n\n# \u8fde\u63a5\u5230 Android \u8fd0\u884c\u65f6\ndroid = androidhelper.Android()\n\n# \u901a\u8fc7\u663e\u793a toast \u6765\u68c0\u67e5\u8fde\u63a5\ndroid.makeToast(\"Connected!\")\n
      "},{"location":"qsl4a/core/android-base/#_6","title":"\u9519\u8bef\u5904\u7406","text":"
      result = droid.someMethod()\nif result.error:\n    print(f\"Error: {result.error}\")\nelse:\n    print(f\"Success: {result.result}\")\n
      "},{"location":"qsl4a/core/android-base/#rpc","title":"\u76f4\u63a5 RPC \u8c03\u7528","text":"
      # \u76f4\u63a5\u8c03\u7528\u4efb\u610f\u65b9\u6cd5\nresult = droid._rpc(\"makeToast\", \"Hello World\")\n
      "},{"location":"qsl4a/core/events/","title":"\u4e8b\u4ef6\u7cfb\u7edf","text":"

      QSL4A \u63d0\u4f9b\u4e86\u4e00\u4e2a\u4e8b\u4ef6\u7cfb\u7edf\uff0c\u7528\u4e8e\u5904\u7406\u6765\u81ea Android \u7684\u5f02\u6b65\u4e8b\u4ef6\uff0c\u5982\u4f20\u611f\u5668\u66f4\u65b0\u3001\u4f4d\u7f6e\u53d8\u5316\u548c\u81ea\u5b9a\u4e49\u5e7f\u64ad\u3002

      "},{"location":"qsl4a/core/events/#_2","title":"\u4e8b\u4ef6\u57fa\u7840","text":"

      \u4e8b\u4ef6\u5b58\u50a8\u5728\u7f13\u51b2\u533a\u4e2d\uff0c\u53ef\u4ee5\u8f6e\u8be2\u6216\u7b49\u5f85\u3002\u6bcf\u4e2a\u4e8b\u4ef6\u5305\u542b\uff1a - name: \u4e8b\u4ef6\u7c7b\u578b/\u540d\u79f0 - data: \u4e8b\u4ef6\u8d1f\u8f7d\u6570\u636e - time: \u65f6\u95f4\u6233

      "},{"location":"qsl4a/core/events/#_3","title":"\u4e8b\u4ef6\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#eventclearbuffer","title":"eventClearBuffer()","text":"

      \u6e05\u9664\u7f13\u51b2\u533a\u4e2d\u7684\u6240\u6709\u5f85\u5904\u7406\u4e8b\u4ef6\u3002

      eventClearBuffer()\n

      \u8fd4\u56de\uff1a None

      "},{"location":"qsl4a/core/events/#eventpoll","title":"eventPoll()","text":"

      \u8f6e\u8be2\u7f13\u51b2\u533a\u4e2d\u7684\u4e8b\u4ef6\u3002

      eventPoll(number_of_events=1)\n

      \u53c2\u6570\uff1a - number_of_events (int): \u8981\u68c0\u7d22\u7684\u6700\u5927\u4e8b\u4ef6\u6570\uff08\u9ed8\u8ba4\uff1a1\uff09

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\u5217\u8868

      "},{"location":"qsl4a/core/events/#eventwait","title":"eventWait()","text":"

      \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\u3002

      eventWait(timeout=None)\n

      \u53c2\u6570\uff1a - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09\u3002None = \u6c38\u4e45\u7b49\u5f85

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

      "},{"location":"qsl4a/core/events/#eventwaitfor","title":"eventWaitFor()","text":"

      \u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6\u3002

      eventWaitFor(eventName, timeout=None)\n

      \u53c2\u6570\uff1a - eventName (str): \u8981\u7b49\u5f85\u7684\u4e8b\u4ef6\u540d\u79f0 - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

      "},{"location":"qsl4a/core/events/#eventpost","title":"eventPost()","text":"

      \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\u3002

      eventPost(name, data, enqueue=None)\n

      \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e\uff08\u4efb\u610f\u7c7b\u578b\uff09 - enqueue (bool, optional): \u5982\u679c\u4e3a True \u5219\u6dfb\u52a0\u5230\u961f\u5217

      "},{"location":"qsl4a/core/events/#receiveevent","title":"receiveEvent()","text":"

      \u63a5\u6536\u4e8b\u4ef6\uff08\u963b\u585e\uff09\u3002

      receiveEvent()\n

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61

      "},{"location":"qsl4a/core/events/#_4","title":"\u5e7f\u64ad\u4e8b\u4ef6","text":"

      \u6ce8\u518c\u7cfb\u7edf\u5e7f\u64ad\u4e8b\u4ef6\u3002

      "},{"location":"qsl4a/core/events/#eventregisterforbroadcast","title":"eventRegisterForBroadcast()","text":"

      \u6ce8\u518c\u63a5\u6536\u5e7f\u64ad\u4e8b\u4ef6\u3002

      eventRegisterForBroadcast(category, enqueue=True)\n

      \u53c2\u6570\uff1a - category (str): \u5e7f\u64ad\u7c7b\u522b/\u52a8\u4f5c - enqueue (bool): \u6dfb\u52a0\u5230\u4e8b\u4ef6\u961f\u5217

      "},{"location":"qsl4a/core/events/#eventunregisterforbroadcast","title":"eventUnregisterForBroadcast()","text":"

      \u53d6\u6d88\u6ce8\u518c\u5e7f\u64ad\u4e8b\u4ef6\u3002

      eventUnregisterForBroadcast(category)\n
      "},{"location":"qsl4a/core/events/#eventgetbrodcastcategories","title":"eventGetBrodcastCategories()","text":"

      \u83b7\u53d6\u5df2\u6ce8\u518c\u7684\u5e7f\u64ad\u7c7b\u522b\u3002

      eventGetBrodcastCategories()\n

      \u8fd4\u56de\uff1a \u5df2\u6ce8\u518c\u7c7b\u522b\u5217\u8868

      "},{"location":"qsl4a/core/events/#_5","title":"\u4e8b\u4ef6\u5206\u53d1\u5668)","text":""},{"location":"qsl4a/core/events/#starteventdispatcher","title":"startEventDispatcher()","text":"

      \u6253\u5f00\u4e00\u4e2a\u53ef\u4ee5\u8bfb\u53d6\u5df2\u53d1\u5e03\u4e8b\u4ef6\u7684\u5957\u63a5\u5b57\u3002)

      startEventDispatcher(port=0)\n

      \u53c2\u6570\uff1a - port (int, optional): \u76d1\u542c\u7684\u7aef\u53e3\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\u9009\u62e9\uff09

      \u8fd4\u56de\uff1a \u6b63\u5728\u76d1\u542c\u7684\u7aef\u53e3\u53f7

      "},{"location":"qsl4a/core/events/#stopeventdispatcher","title":"stopEventDispatcher()","text":"

      \u505c\u6b62\u4e8b\u4ef6\u670d\u52a1\u5668\u3002)

      stopEventDispatcher()\n
      "},{"location":"qsl4a/core/events/#_6","title":"\u5df2\u5e9f\u5f03\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#rpcpostevent","title":"rpcPostEvent()","text":"

      \u5c06\u4e8b\u4ef6\u53d1\u5e03\u5230\u4e8b\u4ef6\u961f\u5217\u3002\uff08\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 eventPost\uff09

      rpcPostEvent(name, data)\n

      \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e

      "},{"location":"qsl4a/core/events/#_7","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/events/#_8","title":"\u57fa\u672c\u4e8b\u4ef6\u8f6e\u8be2","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6e05\u9664\u65e7\u4e8b\u4ef6\ndroid.eventClearBuffer()\n\n# \u8f6e\u8be2\u4e8b\u4ef6\nevents = droid.eventPoll(5).result\nfor event in events:\n    print(f\"Event: {event['name']}, Data: {event['data']}\")\n
      "},{"location":"qsl4a/core/events/#_9","title":"\u7b49\u5f85\u4e8b\u4ef6","text":"
      # \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\uff0c\u5e26\u8d85\u65f6\nevent = droid.eventWait(timeout=10).result\nif event:\n    print(f\"Got event: {event['name']}\")\n
      "},{"location":"qsl4a/core/events/#_10","title":"\u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6","text":"
      # \u7b49\u5f85\u4f20\u611f\u5668\u4e8b\u4ef6\nevent = droid.eventWaitFor('screen', timeout=5).result\nif event:\n    print(f\"Screen event: {event['data']}\")\n
      "},{"location":"qsl4a/core/events/#_11","title":"\u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6","text":"
      # \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\ndroid.eventPost('my_event', {'key': 'value'})\n\n# \u7b49\u5f85\u5b83\nevent = droid.eventWaitFor('my_event', timeout=1).result\n
      "},{"location":"qsl4a/core/events/#_12","title":"\u5e7f\u64ad\u63a5\u6536\u5668","text":"
      # \u6ce8\u518c\u5c4f\u5e55\u5f00\u5173\u4e8b\u4ef6\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_ON')\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_OFF')\n\n# \u7b49\u5f85\u5c4f\u5e55\u4e8b\u4ef6\nwhile True:\n    event = droid.receiveEvent().result\n    if event['name'] == 'android.intent.action.SCREEN_ON':\n        print(\"Screen turned on\")\n    elif event['name'] == 'android.intent.action.SCREEN_OFF':\n        print(\"Screen turned off\")\n
      "},{"location":"qsl4a/core/events/#_13","title":"\u4f20\u611f\u5668\u4e8b\u4ef6\u5904\u7406","text":"
      # \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u5904\u7406\u4f20\u611f\u5668\u4e8b\u4ef6\nfor _ in range(100):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'sensors':\n        data = event['data']\n        print(f\"Accel: {data['xforce']}, {data['yforce']}, {data['zforce']}\")\n\ndroid.stopSensing()\n
      "},{"location":"qsl4a/core/events/#_14","title":"\u5e38\u89c1\u4e8b\u4ef6\u7c7b\u578b","text":"\u4e8b\u4ef6\u540d\u79f0 \u63cf\u8ff0 \u6765\u6e90 sensors \u4f20\u611f\u5668\u6570\u636e\u66f4\u65b0 startSensing* location GPS \u4f4d\u7f6e\u66f4\u65b0 startLocating phone \u7535\u8bdd\u72b6\u6001\u53d8\u5316 startTrackingPhoneState signal \u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316 startTrackingSignalStrength screen \u622a\u56fe\u5c31\u7eea fullGetScreenShot dialog \u5bf9\u8bdd\u6846\u54cd\u5e94 dialogShow*"},{"location":"qsl4a/core/events/#_15","title":"\u4e8b\u4ef6\u6570\u636e\u7ed3\u6784","text":"
      {\n    'name': 'event_name',\n    'data': {\n        # \u4e8b\u4ef6\u7279\u5b9a\u6570\u636e\n    },\n    'time': 1234567890  # \u65f6\u95f4\u6233\n}\n
      "},{"location":"qsl4a/core/intent/","title":"Intent \u7cfb\u7edf","text":"

      Android Intent \u7528\u4e8e\u542f\u52a8\u6d3b\u52a8\u3001\u53d1\u9001\u5e7f\u64ad\u548c\u5e94\u7528\u95f4\u901a\u4fe1\u3002QSL4A \u901a\u8fc7 Intent \u6a21\u5757\u63d0\u4f9b\u5b8c\u6574\u7684 Intent \u652f\u6301\u3002

      "},{"location":"qsl4a/core/intent/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
      import androidhelper\ndon = androidhelper.Android()\n
      "},{"location":"qsl4a/core/intent/#intent_1","title":"Intent \u5e38\u91cf","text":"

      \u901a\u8fc7 droid.Intent \u8bbf\u95ee\uff1a

      "},{"location":"qsl4a/core/intent/#_2","title":"\u64cd\u4f5c","text":"\u5e38\u91cf \u503c \u7528\u9014 ACTION_MAIN android.intent.action.MAIN \u5e94\u7528\u5165\u53e3\u70b9 ACTION_VIEW android.intent.action.VIEW \u67e5\u770b\u5185\u5bb9 ACTION_EDIT android.intent.action.EDIT \u7f16\u8f91\u5185\u5bb9 ACTION_PICK android.intent.action.PICK \u9009\u62e9\u9879\u76ee ACTION_SEND android.intent.action.SEND \u5206\u4eab\u5185\u5bb9 ACTION_SEARCH android.intent.action.SEARCH \u641c\u7d22"},{"location":"qsl4a/core/intent/#_3","title":"\u6807\u5fd7","text":"\u5e38\u91cf \u503c \u7528\u9014 FLAG_ACTIVITY_NEW_TASK 268435456 \u542f\u52a8\u65b0\u4efb\u52a1 FLAG_ACTIVITY_CLEAR_TASK 32768 \u6e05\u9664\u4efb\u52a1\u5806\u6808 FLAG_ACTIVITY_NEW_DOCUMENT 524288 \u65b0\u6587\u6863\u6a21\u5f0f"},{"location":"qsl4a/core/intent/#_4","title":"\u9644\u52a0\u6570\u636e","text":"\u5e38\u91cf \u7528\u9014 EXTRA_TEXT \u6587\u672c\u5185\u5bb9 EXTRA_STREAM \u6587\u4ef6 URI EXTRA_SUBJECT \u4e3b\u9898\u884c EXTRA_EMAIL \u7535\u5b50\u90ae\u4ef6\u5730\u5740"},{"location":"qsl4a/core/intent/#_5","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/intent/#makeintent","title":"makeIntent()","text":"

      \u521b\u5efa Intent \u5bf9\u8c61\u3002

      makeIntent(action, uri=None, type=None, extras=None, categories=None,\n           packagename=None, classname=None, flags=None)\n

      \u53c2\u6570\uff1a - action (str): Intent \u64cd\u4f5c\uff08\u4f8b\u5982 droid.Intent.ACTION_VIEW\uff09 - uri (str, optional): \u6570\u636e URI - type (str, optional): MIME \u7c7b\u578b - extras (dict, optional): \u9644\u52a0\u6570\u636e - categories (list, optional): Intent \u7c7b\u522b - packagename (str, optional): \u76ee\u6807\u5305 - classname (str, optional): \u76ee\u6807\u7c7b - flags (int, optional): Intent \u6807\u5fd7

      \u8fd4\u56de\uff1a Intent \u5bf9\u8c61

      "},{"location":"qsl4a/core/intent/#startactivityintent","title":"startActivityIntent()","text":"

      \u4f7f\u7528 Intent \u542f\u52a8 Activity\u3002

      startActivityIntent(intent, wait=None)\n

      \u53c2\u6570\uff1a - intent: makeIntent() \u8fd4\u56de\u7684 Intent \u5bf9\u8c61 - wait (bool, optional): \u963b\u585e\u76f4\u5230\u6d3b\u52a8\u5173\u95ed

      "},{"location":"qsl4a/core/intent/#startactivityforresultintent","title":"startActivityForResultIntent()","text":"

      \u542f\u52a8\u6d3b\u52a8\u5e76\u7b49\u5f85\u7ed3\u679c\u3002

      startActivityForResultIntent(intent)\n

      \u8fd4\u56de\uff1a Activity \u7ed3\u679c

      "},{"location":"qsl4a/core/intent/#sendbroadcastintent","title":"sendBroadcastIntent()","text":"

      \u53d1\u9001\u5e7f\u64ad\u3002

      sendBroadcastIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#view","title":"view()","text":"

      \u901a\u8fc7 URI \u67e5\u770b\u5185\u5bb9\u3002

      view(uri, type=None, extras=None)\n
      "},{"location":"qsl4a/core/intent/#pick","title":"pick()","text":"

      \u4ece URI \u9009\u62e9\u5185\u5bb9\u3002

      pick(uri)\n
      "},{"location":"qsl4a/core/intent/#intent_2","title":"\u5e38\u89c1 Intent \u65b9\u6cd5)","text":""},{"location":"qsl4a/core/intent/#scanbarcode","title":"scanBarcode()","text":"

      \u542f\u52a8\u6761\u7801\u626b\u63cf\u5668\u3002

      scanBarcode()\n

      \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/core/intent/#send","title":"send()","text":"

      \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u5185\u5bb9\u3002

      send(type, content)\n

      \u53c2\u6570\uff1a - type (str): MIME \u7c7b\u578b - content (str): \u8981\u5206\u4eab\u7684\u5185\u5bb9

      "},{"location":"qsl4a/core/intent/#sendtext","title":"sendText()","text":"

      \u53d1\u9001\u6587\u672c\u5185\u5bb9\u3002

      sendText(text)\n

      \u53c2\u6570\uff1a - text (str): \u8981\u53d1\u9001\u7684\u6587\u672c

      "},{"location":"qsl4a/core/intent/#sendemail","title":"sendEmail()","text":"

      \u53d1\u9001\u7535\u5b50\u90ae\u4ef6\u3002

      sendEmail(to, subject, body, attachment=None)\n

      \u53c2\u6570\uff1a - to (str or list): \u6536\u4ef6\u4eba\u7535\u5b50\u90ae\u4ef6\u5730\u5740 - subject (str): \u7535\u5b50\u90ae\u4ef6\u4e3b\u9898 - body (str): \u7535\u5b50\u90ae\u4ef6\u6b63\u6587 - attachment (str, optional): \u9644\u4ef6\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/core/intent/#pathtouri","title":"pathToUri()","text":"

      \u5c06\u6587\u4ef6\u8def\u5f84\u8f6c\u6362\u4e3a\u5185\u5bb9 URI\u3002

      pathToUri(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5185\u5bb9 URI \u5b57\u7b26\u4e32

      "},{"location":"qsl4a/core/intent/#openfile","title":"openFile()","text":"

      \u7528\u9002\u5f53\u7684\u5e94\u7528\u7a0b\u5e8f\u6253\u5f00\u6587\u4ef6\u3002

      openFile(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u6253\u5f00\u7684\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/core/intent/#sendfile","title":"sendFile()","text":"

      \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u6587\u4ef6\u3002

      sendFile(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u53d1\u9001\u7684\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/core/intent/#getpathtype","title":"getPathType()","text":"

      \u83b7\u53d6\u6587\u4ef6\u8def\u5f84\u7684 MIME \u7c7b\u578b\u3002

      getPathType(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a MIME \u7c7b\u578b\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/core/intent/#viewmap","title":"viewMap()","text":"

      \u5728\u6307\u5b9a\u4f4d\u7f6e\u6253\u5f00\u5730\u56fe\u3002

      viewMap(latitude, longitude)\n

      \u53c2\u6570\uff1a - latitude (float): \u7eac\u5ea6 - longitude (float): \u7ecf\u5ea6

      "},{"location":"qsl4a/core/intent/#viewcontacts","title":"viewContacts()","text":"

      \u6253\u5f00\u8054\u7cfb\u4eba\u5e94\u7528\u3002

      viewContacts()\n
      "},{"location":"qsl4a/core/intent/#search","title":"search()","text":"

      \u6267\u884c\u7f51\u7edc\u641c\u7d22\u3002

      search(query)\n

      \u53c2\u6570\uff1a - query (str): \u641c\u7d22\u67e5\u8be2

      "},{"location":"qsl4a/core/intent/#viewhtml","title":"viewHtml()","text":"

      \u67e5\u770b HTML \u5185\u5bb9\u3002

      viewHtml(content, encoding=None)\n

      \u53c2\u6570\uff1a - content (str): HTML \u5185\u5bb9 - encoding (str, optional): \u5b57\u7b26\u7f16\u7801

      "},{"location":"qsl4a/core/intent/#webviewshow","title":"webViewShow()","text":"

      \u5728 WebView \u4e2d\u663e\u793a\u7f51\u9875\u5185\u5bb9\u3002\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 viewHtml\u3002

      webViewShow(url)\n

      \u53c2\u6570\uff1a - url (str): \u7f51\u9875 URL

      "},{"location":"qsl4a/core/intent/#editoropen","title":"editorOpen()","text":"

      \u6253\u5f00\u6587\u672c\u7f16\u8f91\u5668\u3002

      editorOpen(path=None, create=False)\n

      \u53c2\u6570\uff1a - path (str, optional): \u8981\u7f16\u8f91\u7684\u6587\u4ef6\u8def\u5f84 - create (bool, optional): \u5982\u679c\u4e0d\u5b58\u5728\u5219\u521b\u5efa

      "},{"location":"qsl4a/core/intent/#uri","title":"\u8f85\u52a9\u7c7b\uff1aUri","text":"

      \u521b\u5efa Intent \u7684 URI \u5bf9\u8c61\uff1a

      from androidhelper.Intent import Uri\n\nuri = Uri(\"file:///sdcard/test.txt\")\n
      "},{"location":"qsl4a/core/intent/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/intent/#_7","title":"\u6253\u5f00\u7f51\u9875","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"http://www.example.com\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_8","title":"\u5206\u4eab\u6587\u672c","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_TEXT: \"Hello from QPython!\",\n        droid.Intent.EXTRA_SUBJECT: \"Test\"\n    },\n    type=\"text/plain\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_9","title":"\u6253\u5f00\u6587\u4ef6","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"file:///sdcard/document.pdf\",\n    type=\"application/pdf\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_10","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":"
      result = droid.pickContact()\ncontact_uri = result.result\n
      "},{"location":"qsl4a/core/intent/#_11","title":"\u53d1\u9001\u7535\u5b50\u90ae\u4ef6","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_EMAIL: [\"test@example.com\"],\n        droid.Intent.EXTRA_SUBJECT: \"Hello\",\n        droid.Intent.EXTRA_TEXT: \"Message body\"\n    },\n    type=\"message/rfc822\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_12","title":"\u6253\u5f00\u5e94\u7528","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_MAIN,\n    packagename=\"com.android.settings\",\n    classname=\"com.android.settings.Settings\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/hardware/bluetooth/","title":"\u84dd\u7259 API","text":"

      \u63a7\u5236\u84dd\u7259\u9002\u914d\u5668\u5e76\u4e0e\u84dd\u7259\u8bbe\u5907\u901a\u4fe1\u3002

      "},{"location":"qsl4a/hardware/bluetooth/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/hardware/bluetooth/#togglebluetoothstate","title":"toggleBluetoothState()","text":"

      \u6253\u5f00/\u5173\u95ed\u84dd\u7259\u3002

      toggleBluetoothState(enabled=None, prompt=True)\n

      \u53c2\u6570\uff1a - enabled (bool): True=\u5f00\uff0cFalse=\u5173\uff0cNone=\u5207\u6362 - prompt (bool): \u663e\u793a\u7528\u6237\u63d0\u793a

      "},{"location":"qsl4a/hardware/bluetooth/#checkbluetoothstate","title":"checkBluetoothState()","text":"

      \u68c0\u67e5\u84dd\u7259\u662f\u5426\u5df2\u542f\u7528\u3002

      checkBluetoothState()\n

      \u8fd4\u56de\uff1a True/False

      "},{"location":"qsl4a/hardware/bluetooth/#getlocalname","title":"GetLocalName()","text":"

      \u83b7\u53d6\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

      GetLocalName()\n
      "},{"location":"qsl4a/hardware/bluetooth/#setlocalname","title":"SetLocalName()","text":"

      \u8bbe\u7f6e\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

      SetLocalName(name)\n
      "},{"location":"qsl4a/hardware/bluetooth/#getscanmode","title":"GetScanMode()","text":"

      \u83b7\u53d6\u53ef\u53d1\u73b0\u6027\u6a21\u5f0f\u3002

      GetScanMode()\n

      \u8fd4\u56de\uff1a - -1: \u5df2\u7981\u7528 - 0: \u4e0d\u53ef\u53d1\u73b0\uff0c\u4e0d\u53ef\u8fde\u63a5 - 1: \u53ef\u8fde\u63a5\uff0c\u4e0d\u53ef\u53d1\u73b0 - 3: \u53ef\u8fde\u63a5\u4e14\u53ef\u53d1\u73b0

      "},{"location":"qsl4a/hardware/bluetooth/#makediscoverable","title":"MakeDiscoverable()","text":"

      \u4f7f\u8bbe\u5907\u53ef\u53d1\u73b0\u3002

      MakeDiscoverable(duration=300)\n

      \u53c2\u6570\uff1a - duration (int): \u53ef\u53d1\u73b0\u7684\u79d2\u6570

      "},{"location":"qsl4a/hardware/bluetooth/#_2","title":"\u53d1\u73b0","text":""},{"location":"qsl4a/hardware/bluetooth/#discoverystart","title":"DiscoveryStart()","text":"

      \u5f00\u59cb\u8bbe\u5907\u53d1\u73b0\u3002

      DiscoveryStart()\n
      "},{"location":"qsl4a/hardware/bluetooth/#discoverycancel","title":"DiscoveryCancel()","text":"

      \u53d6\u6d88\u53d1\u73b0\u3002

      DiscoveryCancel()\n
      "},{"location":"qsl4a/hardware/bluetooth/#getreceiveddevices","title":"GetReceivedDevices()","text":"

      \u83b7\u53d6\u53d1\u73b0\u7684\u8bbe\u5907\u3002

      GetReceivedDevices()\n

      \u8fd4\u56de\uff1a \u8bbe\u5907\u4fe1\u606f\u5b57\u5178\u5217\u8868

      "},{"location":"qsl4a/hardware/bluetooth/#getbondeddevices","title":"GetBondedDevices()","text":"

      \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\u3002

      GetBondedDevices()\n

      \u8fd4\u56de\uff1a \u914d\u5bf9\u8bbe\u5907\u4fe1\u606f\u5217\u8868

      "},{"location":"qsl4a/hardware/bluetooth/#_3","title":"\u8fde\u63a5","text":""},{"location":"qsl4a/hardware/bluetooth/#connect","title":"Connect()","text":"

      \u8fde\u63a5\u5230\u8bbe\u5907\u3002

      Connect(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", address=None)\n

      \u53c2\u6570\uff1a - uuid (str): \u670d\u52a1 UUID - address (str): \u8bbe\u5907\u5730\u5740\uff08None = \u663e\u793a\u9009\u62e9\u5668\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/hardware/bluetooth/#accept","title":"Accept()","text":"

      \u63a5\u53d7\u4f20\u5165\u8fde\u63a5\u3002

      Accept(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", timeout=0)\n
      "},{"location":"qsl4a/hardware/bluetooth/#activeconnections","title":"ActiveConnections()","text":"

      \u68c0\u67e5\u6d3b\u52a8\u8fde\u63a5\u3002

      ActiveConnections()\n
      "},{"location":"qsl4a/hardware/bluetooth/#stop","title":"Stop()","text":"

      \u65ad\u5f00\u8fde\u63a5\u3002

      Stop(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#_4","title":"\u901a\u4fe1","text":""},{"location":"qsl4a/hardware/bluetooth/#write","title":"Write()","text":"

      \u53d1\u9001 ASCII \u6570\u636e\u3002

      Write(ascii, connID=\"\")\n
      "},{"location":"qsl4a/hardware/bluetooth/#writebinary","title":"WriteBinary()","text":"

      \u53d1\u9001\u4e8c\u8fdb\u5236\u6570\u636e\uff08base64 \u7f16\u7801\uff09\u3002

      WriteBinary(base64, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#read","title":"Read()","text":"

      \u8bfb\u53d6 ASCII \u6570\u636e\u3002

      Read(bufferSize=4096, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readbinary","title":"ReadBinary()","text":"

      \u8bfb\u53d6\u4e8c\u8fdb\u5236\u6570\u636e\u3002

      ReadBinary(bufferSize=4096, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readline","title":"ReadLine()","text":"

      \u8bfb\u53d6\u4e00\u884c\u3002

      ReadLine(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readready","title":"ReadReady()","text":"

      \u68c0\u67e5\u662f\u5426\u6709\u53ef\u7528\u6570\u636e\u3002

      ReadReady(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u7528\u84dd\u7259\ndroid.toggleBluetoothState(True)\n\n# \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\ndevices = droid.GetBondedDevices().result\nfor dev in devices:\n    print(f\"{dev['name']}: {dev['address']}\")\n\n# \u8fde\u63a5\u5230\u8bbe\u5907\ndroid.Connect(address=\"00:11:22:33:44:55\")\n\n# \u53d1\u9001\u6570\u636e\ndroid.Write(\"Hello Bluetooth!\")\n\n# \u8bfb\u53d6\u54cd\u5e94\ndata = droid.Read(1024).result\n
      "},{"location":"qsl4a/hardware/camera/","title":"\u76f8\u673a API","text":"

      \u62cd\u6444\u7167\u7247\u548c\u5f55\u5236\u89c6\u9891\u3002

      "},{"location":"qsl4a/hardware/camera/#_1","title":"\u7167\u7247\u62cd\u6444","text":""},{"location":"qsl4a/hardware/camera/#takepicture","title":"takePicture()","text":"

      \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u6444\u7167\u7247\u3002

      takePicture(path=None)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8fd4\u56de\u56fe\u50cf\u6570\u636e

      \u8fd4\u56de\uff1a \u56fe\u50cf\u8def\u5f84\u6216\u56fe\u50cf\u6570\u636e

      "},{"location":"qsl4a/hardware/camera/#cameracapturepicture","title":"cameraCapturePicture()","text":"

      \u4f7f\u7528\u9ad8\u7ea7\u76f8\u673a\u63a7\u5236\u62cd\u6444\u7167\u7247\u3002

      cameraCapturePicture(targetPath=None, cameraId=0, useAutoFocus=True)\n

      \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - useAutoFocus (bool): \u542f\u7528\u81ea\u52a8\u5bf9\u7126

      \u8fd4\u56de\uff1a \u62cd\u6444\u7684\u56fe\u50cf\u8def\u5f84

      "},{"location":"qsl4a/hardware/camera/#camerasettorchmode","title":"cameraSetTorchMode()","text":"

      \u63a7\u5236\u76f8\u673a\u95ea\u5149\u706f/\u624b\u7535\u7b52\u3002

      cameraSetTorchMode(enabled)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u6253\u5f00\uff0cFalse \u5173\u95ed

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/hardware/camera/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

      \u622a\u56fe\u3002

      imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

      "},{"location":"qsl4a/hardware/camera/#_2","title":"\u89c6\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#takevideo","title":"takeVideo()","text":"

      \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\u3002

      takeVideo(path=None, quality=1)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-4\uff09 - 0: 160x120 - 1: 320x240 - 2: 352x288 - 3: 640x480 - 4: 800x480

      "},{"location":"qsl4a/hardware/camera/#recordercapturevideo","title":"recorderCaptureVideo()","text":"

      \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\u3002

      recorderCaptureVideo(targetPath=None, duration=10, cameraId=0, quality=8)\n

      \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - duration (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a10\uff09 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-8\uff0c\u8d8a\u9ad8\u8d8a\u597d\uff09

      \u8fd4\u56de\uff1a \u89c6\u9891\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/hardware/camera/#recordaudio","title":"recordAudio()","text":"

      \u5f55\u5236\u97f3\u9891\u3002

      recordAudio()\n

      \u8fd4\u56de\uff1a \u97f3\u9891\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/hardware/camera/#_3","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

      \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\u3002

      recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

      \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\uff09 - targetPixels (int): \u5206\u8fa8\u7387 - frameRate (int): FPS - bitRate (int): \u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa - autoStart (bool): \u7acb\u5373\u5f00\u59cb

      "},{"location":"qsl4a/hardware/camera/#recorderstart","title":"recorderStart()","text":"

      \u5f00\u59cb\u5f55\u5236\u3002

      recorderStart()\n
      "},{"location":"qsl4a/hardware/camera/#recorderpause","title":"recorderPause()","text":"

      \u6682\u505c\u5f55\u5236\u3002

      recorderPause()\n
      "},{"location":"qsl4a/hardware/camera/#recorderresume","title":"recorderResume()","text":"

      \u6062\u590d\u5f55\u5236\u3002

      recorderResume()\n
      "},{"location":"qsl4a/hardware/camera/#_4","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/camera/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

      \u5f00\u59cb\u97f3\u91cf\u68c0\u6d4b\u3002

      recorderSoundVolumeDetect(interval=100)\n
      "},{"location":"qsl4a/hardware/camera/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

      \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

      recorderSoundVolumeGetDb()\n
      "},{"location":"qsl4a/hardware/camera/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u7167\nphoto_path = droid.takePicture(\"/sdcard/photo.jpg\").result\nprint(f\"Photo saved: {photo_path}\")\n\n# \u4f7f\u7528\u524d\u7f6e\u76f8\u673a\u548c\u81ea\u52a8\u5bf9\u7126\u62cd\u7167\ncamera_path = droid.cameraCapturePicture(\"/sdcard/selfie.jpg\", cameraId=1, useAutoFocus=True).result\nprint(f\"Front camera photo: {camera_path}\")\n\n# \u63a7\u5236\u95ea\u5149\u706f\ndroid.cameraSetTorchMode(True)  # \u6253\u5f00\u95ea\u5149\u706f\n\n# \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\nvideo_path = droid.takeVideo(\"/sdcard/video.mp4\", quality=3).result\nprint(f\"Video saved: {video_path}\")\n\n# \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\nvideo_path = droid.recorderCaptureVideo(\"/sdcard/movie.mp4\", duration=30, cameraId=0, quality=8).result\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n
      "},{"location":"qsl4a/hardware/recorder/","title":"\u97f3\u9891\u5f55\u5236 API","text":"

      \u4ece\u9ea6\u514b\u98ce\u548c\u8bbe\u5907\u5c4f\u5e55\u5f55\u5236\u97f3\u9891\u3002

      "},{"location":"qsl4a/hardware/recorder/#_1","title":"\u97f3\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recordaudio","title":"recordAudio()","text":"

      \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\u3002

      recordAudio()\n

      \u8fd4\u56de\uff1a \u5f55\u5236\u7684\u97f3\u9891\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/hardware/recorder/#recorderstartmicrophone","title":"recorderStartMicrophone()","text":"

      \u5f00\u59cb\u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\u3002

      recorderStartMicrophone(targetPath=None)\n

      \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u5f55\u5236\u7684\u8def\u5f84

      "},{"location":"qsl4a/hardware/recorder/#_2","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

      \u5f00\u59cb\u5e26\u97f3\u9891\u7684\u5c4f\u5e55\u5f55\u5236\u3002

      recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

      \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\u97f3\u9891\uff09 - targetPixels (int): \u76ee\u6807\u5206\u8fa8\u7387\uff08\u50cf\u7d20\uff09 - frameRate (int): \u6bcf\u79d2\u5e27\u6570\uff08\u9ed8\u8ba4\uff1a30\uff09 - bitRate (int): \u89c6\u9891\u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa\u89c6\u9891 - autoStart (bool): \u7acb\u5373\u5f00\u59cb\u5f55\u5236

      \u8fd4\u56de\uff1a \u64cd\u4f5c\u7ed3\u679c

      "},{"location":"qsl4a/hardware/recorder/#recorderstart","title":"recorderStart()","text":"

      \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\uff08\u5f53 autoStart=False \u65f6\uff09\u3002

      recorderStart()\n
      "},{"location":"qsl4a/hardware/recorder/#recorderpause","title":"recorderPause()","text":"

      \u6682\u505c\u6b63\u5728\u8fdb\u884c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

      recorderPause()\n
      "},{"location":"qsl4a/hardware/recorder/#recorderresume","title":"recorderResume()","text":"

      \u6062\u590d\u6682\u505c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

      recorderResume()\n
      "},{"location":"qsl4a/hardware/recorder/#_3","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/recorder/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

      \u5f00\u59cb\u76d1\u63a7\u97f3\u91cf\u7ea7\u522b\u3002

      recorderSoundVolumeDetect(interval=100)\n

      \u53c2\u6570\uff1a - interval (int): \u68c0\u6d4b\u95f4\u9694\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a100\uff09

      "},{"location":"qsl4a/hardware/recorder/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

      \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

      recorderSoundVolumeGetDb()\n

      \u8fd4\u56de\uff1a \u5f53\u524d\u97f3\u91cf\u7ea7\u522b\uff08dB\uff09

      "},{"location":"qsl4a/hardware/recorder/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\nprint(\"Recording audio...\")\naudio_path = droid.recordAudio().result\nprint(f\"Saved to: {audio_path}\")\n\n# \u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\ndroid.recorderStartMicrophone(\"/sdcard/my_recording.mp3\")\ntime.sleep(5)\ndroid.recorderStop()\n\n# \u5e26\u97f3\u9891\u5f55\u5236\u5c4f\u5e55\nprint(\"Starting screen recording...\")\ndroid.recorderStartScreenRecord(\n    path=\"/sdcard/screen_record.mp4\",\n    audio=1,\n    frameRate=30,\n    autoStart=True\n)\ntime.sleep(10)\ndroid.recorderStop()\n\n# \u76d1\u63a7\u97f3\u91cf\ndroid.recorderSoundVolumeDetect(interval=100)\ntime.sleep(3)\nvolume = droid.recorderSoundVolumeGetDb().result\nprint(f\"Current volume: {volume} dB\")\n
      "},{"location":"qsl4a/hardware/usbserial/","title":"USB \u4e3b\u673a\u4e32\u884c API","text":"

      \u4e0e USB \u4e32\u884c\u8bbe\u5907\u901a\u4fe1\uff08\u9700\u8981 USB OTG \u652f\u6301\u548c Android 3.1+\uff09\u3002

      "},{"location":"qsl4a/hardware/usbserial/#usb","title":"USB \u4e32\u884c\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialopen","title":"usbHostSerialOpen()","text":"

      \u6253\u5f00\u4e0e USB \u4e32\u884c\u8bbe\u5907\u7684\u8fde\u63a5\u3002

      usbHostSerialOpen(device, baudRate=9600)\n

      \u53c2\u6570\uff1a - device (str): USB \u8bbe\u5907\u8def\u5f84\u6216\u6807\u8bc6\u7b26 - baudRate (int): \u6ce2\u7279\u7387\uff08\u9ed8\u8ba4\uff1a9600\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u6253\u5f00\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialclose","title":"usbHostSerialClose()","text":"

      \u5173\u95ed USB \u4e32\u884c\u8fde\u63a5\u3002

      usbHostSerialClose()\n
      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialread","title":"usbHostSerialRead()","text":"

      \u4ece USB \u4e32\u884c\u8bfb\u53d6\u6570\u636e\u3002

      usbHostSerialRead(bufferSize=1024)\n

      \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570\uff08\u9ed8\u8ba4\uff1a1024\uff09

      \u8fd4\u56de\uff1a \u8bfb\u53d6\u7684\u6570\u636e\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwrite","title":"usbHostSerialWrite()","text":"

      \u5411 USB \u4e32\u884c\u5199\u5165\u6570\u636e\u3002

      usbHostSerialWrite(data)\n

      \u53c2\u6570\uff1a - data (str): \u8981\u5199\u5165\u7684\u5b57\u7b26\u4e32\u6570\u636e

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialavailable","title":"usbHostSerialAvailable()","text":"

      \u68c0\u67e5\u662f\u5426\u6709\u53ef\u8bfb\u53d6\u7684\u6570\u636e\u3002

      usbHostSerialAvailable()\n

      \u8fd4\u56de\uff1a \u53ef\u7528\u5b57\u8282\u6570

      "},{"location":"qsl4a/hardware/usbserial/#_1","title":"\u914d\u7f6e\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetbaudrate","title":"usbHostSerialSetBaudRate()","text":"

      \u8bbe\u7f6e\u6ce2\u7279\u7387\u3002

      usbHostSerialSetBaudRate(baudRate)\n

      \u53c2\u6570\uff1a - baudRate (int): \u6ce2\u7279\u7387

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetdatabits","title":"usbHostSerialSetDataBits()","text":"

      \u8bbe\u7f6e\u6570\u636e\u4f4d\uff085\u30016\u30017 \u6216 8\uff09\u3002

      usbHostSerialSetDataBits(dataBits)\n

      \u53c2\u6570\uff1a - dataBits (int): \u6570\u636e\u4f4d\uff085-8\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetstopbits","title":"usbHostSerialSetStopBits()","text":"

      \u8bbe\u7f6e\u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09\u3002

      usbHostSerialSetStopBits(stopBits)\n

      \u53c2\u6570\uff1a - stopBits (float): \u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetparity","title":"usbHostSerialSetParity()","text":"

      \u8bbe\u7f6e\u6821\u9a8c\u4f4d\uff08\u65e0\u3001\u5947\u3001\u5076\u3001\u6807\u8bb0\u3001\u7a7a\u683c\uff09\u3002

      usbHostSerialSetParity(parity)\n

      \u53c2\u6570\uff1a - parity (str): \u6821\u9a8c\u6a21\u5f0f\uff08'none'\u3001'odd'\u3001'even'\u3001'mark'\u3001'space'\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetflowcontrol","title":"usbHostSerialSetFlowControl()","text":"

      \u8bbe\u7f6e\u6d41\u63a7\u5236\uff08\u65e0\u3001\u786c\u4ef6\u3001\u8f6f\u4ef6\uff09\u3002

      usbHostSerialSetFlowControl(flowControl)\n

      \u53c2\u6570\uff1a - flowControl (str): \u6d41\u63a7\u5236\u6a21\u5f0f\uff08'none'\u3001'hardware'\u3001'software'\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialreadhex","title":"usbHostSerialReadHex()","text":"

      \u4ee5\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u8bfb\u53d6\u6570\u636e\u3002

      usbHostSerialReadHex(bufferSize=1024)\n

      \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570

      \u8fd4\u56de\uff1a \u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwritehex","title":"usbHostSerialWriteHex()","text":"

      \u4ece\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u5199\u5165\u6570\u636e\u3002

      usbHostSerialWriteHex(hexString)\n

      \u53c2\u6570\uff1a - hexString (str): \u8981\u5199\u5165\u7684\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/hardware/usbserial/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6253\u5f00 USB \u4e32\u884c\u8fde\u63a5\nif droid.usbHostSerialOpen(\"/dev/bus/usb/001/001\", 115200).result:\n    print(\"USB serial opened\")\n\n    # \u5199\u5165\u6570\u636e\n    droid.usbHostSerialWrite(\"AT\\r\")\n\n    # \u8bfb\u53d6\u54cd\u5e94\n    response = droid.usbHostSerialRead(1024).result\n    print(f\"Response: {response}\")\n\n    # \u6216\u4f7f\u7528\u5341\u516d\u8fdb\u5236\n    droid.usbHostSerialWriteHex(\"41540D0A\")  # \"AT\\r\\n\"\n\n    # \u5173\u95ed\u8fde\u63a5\n    droid.usbHostSerialClose()\n

      \u6ce8\u610f\uff1a USB \u4e32\u884c\u9700\u8981\uff1a - Android 3.1+ (API 12) - USB OTG \u7ebf/\u9002\u914d\u5668 - \u8bbe\u5907\u4e0a\u7684 USB \u4e3b\u673a\u6a21\u5f0f\u652f\u6301 - \u517c\u5bb9\u7684\u4e32\u884c\u8bbe\u5907

      "},{"location":"qsl4a/hardware/webcam/","title":"\u7f51\u7edc\u6444\u50cf\u5934 API","text":"

      \u4f7f\u7528 MJPEG \u4ece\u8bbe\u5907\u76f8\u673a\u6d41\u5f0f\u4f20\u8f93\u89c6\u9891\u3002

      "},{"location":"qsl4a/hardware/webcam/#mjpeg","title":"MJPEG \u6d41\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#webcamstart","title":"webcamStart()","text":"

      \u4ece\u7f51\u7edc\u6444\u50cf\u5934\u542f\u52a8 MJPEG \u6d41\u3002

      webcamStart(resolutionLevel=0, jpegQuality=20, port=0)\n

      \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf 1-100\uff08\u9ed8\u8ba4\uff1a20\uff09 - port (int): \u7aef\u53e3\u53f7\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\uff09

      \u8fd4\u56de\uff1a \u6d41\u7684 (\u5730\u5740, \u7aef\u53e3) \u5143\u7ec4

      "},{"location":"qsl4a/hardware/webcam/#webcamadjustquality","title":"webcamAdjustQuality()","text":"

      \u8c03\u6574\u6d3b\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u7684\u8d28\u91cf\u3002

      webcamAdjustQuality(resolutionLevel=0, jpegQuality=20)\n

      \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b - jpegQuality (int): JPEG \u8d28\u91cf 1-100

      "},{"location":"qsl4a/hardware/webcam/#webcamstop","title":"webcamStop()","text":"

      \u505c\u6b62\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u3002

      webcamStop()\n
      "},{"location":"qsl4a/hardware/webcam/#_1","title":"\u76f8\u673a\u9884\u89c8\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#camerastartpreview","title":"cameraStartPreview()","text":"

      \u5f00\u59cb\u5e26\u4e8b\u4ef6\u751f\u6210\u7684\u76f8\u673a\u9884\u89c8\u6a21\u5f0f\u3002

      cameraStartPreview(resolutionLevel=0, jpegQuality=20, filepath=None)\n

      \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf\uff08\u9ed8\u8ba4\uff1a20\uff09 - filepath (str, optional): \u4fdd\u5b58\u9884\u89c8\u5e27\u7684\u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      \u6ce8\u610f\uff1a \u751f\u6210\u5e26\u6709\u5e27\u6570\u636e\u7684 'preview' \u4e8b\u4ef6\u3002

      "},{"location":"qsl4a/hardware/webcam/#camerastoppreview","title":"cameraStopPreview()","text":"

      \u505c\u6b62\u76f8\u673a\u9884\u89c8\u3002

      cameraStopPreview()\n
      "},{"location":"qsl4a/hardware/webcam/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\nstream_info = droid.webcamStart(\n    resolutionLevel=0,\n    jpegQuality=30,\n    port=8080\n).result\nprint(f\"Stream available at {stream_info[0]}:{stream_info[1]}\")\n\n# \u6d41\u5f0f\u4f20\u8f93\u65f6\u8c03\u6574\u8d28\u91cf\ntime.sleep(5)\ndroid.webcamAdjustQuality(resolutionLevel=1, jpegQuality=50)\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.webcamStop()\n\n# \u6216\u4f7f\u7528\u9884\u89c8\u6a21\u5f0f\nprint(\"Starting preview...\")\ndroid.cameraStartPreview()\n\n# \u7b49\u5f85\u9884\u89c8\u4e8b\u4ef6\nfor i in range(10):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'preview':\n        print(f\"Got preview frame: {event['data']}\")\n\ndroid.cameraStopPreview()\n
      "},{"location":"qsl4a/media/image/","title":"\u56fe\u50cf\u5904\u7406 API","text":"

      \u538b\u7f29\u548c\u5904\u7406\u56fe\u50cf\u3002

      "},{"location":"qsl4a/media/image/#_1","title":"\u56fe\u50cf\u538b\u7f29","text":""},{"location":"qsl4a/media/image/#imagecompress","title":"imageCompress()","text":"

      \u538b\u7f29\u56fe\u50cf\u6587\u4ef6\u3002

      imageCompress(srcPath, destPath, targetByteSize=0, targetWidth=0, targetHeight=0)\n

      \u53c2\u6570\uff1a - srcPath (str): \u6e90\u56fe\u50cf\u8def\u5f84 - destPath (str): \u8f93\u51fa\u8def\u5f84 - targetByteSize (int): \u76ee\u6807\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff080 = \u65e0\u9650\u5236\uff09 - targetWidth (int): \u76ee\u6807\u5bbd\u5ea6\uff080 = \u539f\u59cb\uff09 - targetHeight (int): \u76ee\u6807\u9ad8\u5ea6\uff080 = \u539f\u59cb\uff09

      \u8fd4\u56de\uff1a \u538b\u7f29\u540e\u7684\u56fe\u50cf\u8def\u5f84

      "},{"location":"qsl4a/media/image/#_2","title":"\u622a\u56fe","text":""},{"location":"qsl4a/media/image/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

      \u622a\u53d6\u5c4f\u5e55\u3002

      imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

      \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

      \u8fd4\u56de\uff1a \u622a\u56fe\u8def\u5f84

      "},{"location":"qsl4a/media/image/#_3","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/image/#videoplay","title":"videoPlay()","text":"

      \u5728\u5168\u5c4f\u6a21\u5f0f\u4e0b\u64ad\u653e\u89c6\u9891\u6587\u4ef6\u3002

      videoPlay(path, wait=True)\n

      \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

      "},{"location":"qsl4a/media/image/#_4","title":"\u6761\u7801\u626b\u63cf","text":""},{"location":"qsl4a/media/image/#scanbarcodefromimage","title":"scanBarcodeFromImage()","text":"

      \u4ece\u56fe\u50cf\u6587\u4ef6\u626b\u63cf\u6761\u7801/\u4e8c\u7ef4\u7801\u3002

      scanBarcodeFromImage(path, compressRatio=0, x=0, y=0, width=0, height=0)\n

      \u53c2\u6570\uff1a - path (str): \u56fe\u50cf\u6587\u4ef6\u8def\u5f84 - compressRatio (int): \u538b\u7f29\u6bd4\uff080 = \u4e0d\u538b\u7f29\uff09 - x, y, width, height (int): \u8981\u626b\u63cf\u7684\u533a\u57df\uff080 = \u5b8c\u6574\u56fe\u50cf\uff09

      \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5185\u5bb9

      "},{"location":"qsl4a/media/image/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n\n# \u538b\u7f29\u56fe\u50cf\ncompressed = droid.imageCompress(\n    \"/sdcard/large_photo.jpg\",\n    \"/sdcard/compressed.jpg\",\n    targetByteSize=102400,  # \u76ee\u6807\u7ea6 100KB\n    targetWidth=1920,\n    targetHeight=1080\n).result\nprint(f\"Saved: {compressed}\")\n\n# \u64ad\u653e\u89c6\u9891\nvideo_path = \"/sdcard/movie.mp4\"\ndroid.videoPlay(video_path, wait=True)\n\n# \u4ece\u56fe\u50cf\u626b\u63cf\u6761\u7801\nresult = droid.scanBarcodeFromImage(\"/sdcard/qr_code.png\").result\nprint(f\"Barcode: {result}\")\n
      "},{"location":"qsl4a/media/mediaplayer/","title":"\u5a92\u4f53\u64ad\u653e\u5668 API","text":"

      \u63a7\u5236\u97f3\u9891\u548c\u89c6\u9891\u64ad\u653e\u3002

      "},{"location":"qsl4a/media/mediaplayer/#_1","title":"\u64ad\u653e\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplay","title":"mediaPlay()","text":"

      \u64ad\u653e\u5a92\u4f53\u6587\u4ef6\u3002

      mediaPlay(url, tag=\"default\", play=True)\n

      \u53c2\u6570\uff1a - url (str): \u5a92\u4f53\u6587\u4ef6\u8def\u5f84\u6216 URL - tag (str): \u64ad\u653e\u5668\u6807\u8bc6\u7b26 - play (bool): \u81ea\u52a8\u5f00\u59cb\u64ad\u653e

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaystart","title":"mediaPlayStart()","text":"

      \u5f00\u59cb\u64ad\u653e\u3002

      mediaPlayStart(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplaypause","title":"mediaPlayPause()","text":"

      \u6682\u505c\u64ad\u653e\u3002

      mediaPlayPause(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplayclose","title":"mediaPlayClose()","text":"

      \u5173\u95ed\u64ad\u653e\u5668\u3002

      mediaPlayClose(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplayseek","title":"mediaPlaySeek()","text":"

      \u8df3\u8f6c\u5230\u4f4d\u7f6e\u3002

      mediaPlaySeek(msec, tag=\"default\")\n

      \u53c2\u6570\uff1a - msec (int): \u4f4d\u7f6e\uff08\u6beb\u79d2\uff09

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaysetlooping","title":"mediaPlaySetLooping()","text":"

      \u8bbe\u7f6e\u5faa\u73af\u6a21\u5f0f\u3002

      mediaPlaySetLooping(enabled, tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#_2","title":"\u64ad\u653e\u5668\u4fe1\u606f","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplayinfo","title":"mediaPlayInfo()","text":"

      \u83b7\u53d6\u64ad\u653e\u4fe1\u606f\u3002

      mediaPlayInfo(tag=\"default\")\n

      \u8fd4\u56de\uff1a \u5305\u542b\u65f6\u957f\u3001\u4f4d\u7f6e\u7b49\u7684\u5b57\u5178

      "},{"location":"qsl4a/media/mediaplayer/#mediaisplaying","title":"mediaIsPlaying()","text":"

      \u68c0\u67e5\u662f\u5426\u6b63\u5728\u64ad\u653e\u3002

      mediaIsPlaying(tag=\"default\")\n

      \u8fd4\u56de\uff1a True/False

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaylist","title":"mediaPlayList()","text":"

      \u5217\u51fa\u6d3b\u52a8\u64ad\u653e\u5668\u3002

      mediaPlayList()\n
      "},{"location":"qsl4a/media/mediaplayer/#_3","title":"\u97f3\u91cf\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#getmediavolume","title":"getMediaVolume()","text":"

      \u83b7\u53d6\u5a92\u4f53\u97f3\u91cf\u3002

      getMediaVolume()\n

      \u8fd4\u56de\uff1a \u97f3\u91cf\u7ea7\u522b\uff080-15\uff09

      "},{"location":"qsl4a/media/mediaplayer/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

      getMaxMediaVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#getringervolume","title":"getRingerVolume()","text":"

      \u83b7\u53d6\u94c3\u58f0\u97f3\u91cf\u3002

      getRingerVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

      getMaxRingerVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#_4","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/mediaplayer/#videoplay","title":"videoPlay()","text":"

      \u5168\u5c4f\u64ad\u653e\u89c6\u9891\u3002

      videoPlay(path, wait=True)\n

      \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210

      "},{"location":"qsl4a/media/mediaplayer/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u64ad\u653e\u97f3\u9891\ndroid.mediaPlay(\"/sdcard/music.mp3\", tag=\"music\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.mediaIsPlaying(\"music\").result:\n    info = droid.mediaPlayInfo(\"music\").result\n    print(f\"Playing: {info}\")\n\n# \u8df3\u8f6c\u5230 30 \u79d2\ndroid.mediaPlaySeek(30000, \"music\")\n\n# \u5173\u95ed\ndroid.mediaPlayClose(\"music\")\n\n# \u64ad\u653e\u89c6\u9891\ndroid.videoPlay(\"/sdcard/movie.mp4\", wait=True)\n
      "},{"location":"qsl4a/special/cipher/","title":"\u5bc6\u7801 API","text":"

      \u7528\u4e8e\u5b89\u5168\u6570\u636e\u5b58\u50a8\u7684\u52a0\u5bc6\u548c\u89e3\u5bc6\u5de5\u5177\u3002

      "},{"location":"qsl4a/special/cipher/#_1","title":"\u521d\u59cb\u5316","text":""},{"location":"qsl4a/special/cipher/#cipherinit","title":"cipherInit()","text":"

      \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u548c\u7b97\u6cd5\u521d\u59cb\u5316\u5bc6\u7801\u5668\u3002

      cipherInit(key, algorithm=\"AES/CBC/PKCS5Padding\", encodingFormat=\"\", initialVector=\"\")\n

      \u53c2\u6570\uff1a - key (str or bytes): \u52a0\u5bc6\u5bc6\u94a5 - algorithm (str): \u5bc6\u7801\u7b97\u6cd5\uff08\u9ed8\u8ba4\uff1a\"AES/CBC/PKCS5Padding\"\uff09 - encodingFormat (str): \u7f16\u7801\u683c\u5f0f - initialVector (str or bytes): \u52a0\u5bc6\u7684\u521d\u59cb\u5411\u91cf

      \u8fd4\u56de\uff1a \u521d\u59cb\u5316\u7ed3\u679c

      \u6ce8\u610f\uff1a \u5fc5\u987b\u5728\u4efb\u4f55\u52a0\u5bc6/\u89e3\u5bc6\u64cd\u4f5c\u4e4b\u524d\u8c03\u7528\u3002

      "},{"location":"qsl4a/special/cipher/#_2","title":"\u52a0\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#encryptstring","title":"encryptString()","text":"

      \u52a0\u5bc6\u5b57\u7b26\u4e32\u3002

      encryptString(plainText)\n

      \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c

      \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/special/cipher/#encryptbytes","title":"encryptBytes()","text":"

      \u52a0\u5bc6\u5b57\u8282\u6570\u636e\u3002

      encryptBytes(data)\n

      \u53c2\u6570\uff1a - data (bytes): \u8981\u52a0\u5bc6\u7684\u6570\u636e

      \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u8282

      "},{"location":"qsl4a/special/cipher/#encryptstringtofile","title":"encryptStringToFile()","text":"

      \u52a0\u5bc6\u5b57\u7b26\u4e32\u5230\u6587\u4ef6\u3002

      encryptStringToFile(plainText, filePath)\n

      \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c - filePath (str): \u8f93\u51fa\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/special/cipher/#encryptbytestofile","title":"encryptBytesToFile()","text":"

      \u52a0\u5bc6\u5b57\u8282\u5230\u6587\u4ef6\u3002

      encryptBytesToFile(data, filePath)\n
      "},{"location":"qsl4a/special/cipher/#_3","title":"\u89e3\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#decryptstring","title":"decryptString()","text":"

      \u89e3\u5bc6\u4e3a\u5b57\u7b26\u4e32\u3002

      decryptString(cipherText)\n

      \u53c2\u6570\uff1a - cipherText (str): \u52a0\u5bc6\u7684\u6587\u672c

      \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/special/cipher/#decryptbytes","title":"decryptBytes()","text":"

      \u89e3\u5bc6\u4e3a\u5b57\u8282\u3002

      decryptBytes(data)\n

      \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u8282

      "},{"location":"qsl4a/special/cipher/#decryptfiletostring","title":"decryptFileToString()","text":"

      \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u7b26\u4e32\u3002

      decryptFileToString(filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryptfiletobytes","title":"decryptFileToBytes()","text":"

      \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u8282\u3002

      decryptFileToBytes(filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryptfile","title":"decryptFile()","text":"

      \u89e3\u5bc6\u6587\u4ef6\u5230\u6587\u4ef6\u3002

      decryptFile(srcPath, destPath)\n
      "},{"location":"qsl4a/special/cipher/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u521d\u59cb\u5316\u5bc6\u7801\u5668\ndroid.cipherInit(\"my_secret_key_1234\")\n\n# \u52a0\u5bc6\u5b57\u7b26\u4e32\nencrypted = droid.encryptString(\"Secret message!\").result\nprint(f\"Encrypted: {encrypted}\")\n\n# \u89e3\u5bc6\u5b57\u7b26\u4e32\ndecrypted = droid.decryptString(encrypted).result\nprint(f\"Decrypted: {decrypted}\")\n\n# \u52a0\u5bc6\u5230\u6587\u4ef6\ndroid.encryptStringToFile(\"My secret data\", \"/sdcard/secret.dat\")\n\n# \u4ece\u6587\u4ef6\u89e3\u5bc6\ndata = droid.decryptFileToString(\"/sdcard/secret.dat\").result\nprint(data)\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u7b97\u6cd5\u548c IV \u521d\u59cb\u5316\ndroid.cipherInit(\n    key=\"my_key\",\n    algorithm=\"AES/CBC/PKCS5Padding\",\n    initialVector=\"0123456789abcdef\"\n)\n
      "},{"location":"qsl4a/special/pgptai/","title":"PGPT AI API","text":"

      \u8bed\u97f3\u8f6c\u6587\u672c\u548c AI \u670d\u52a1\u96c6\u6210\u3002

      "},{"location":"qsl4a/special/pgptai/#_1","title":"\u5148\u51b3\u6761\u4ef6","text":"
      pip install pgptAI\n
      "},{"location":"qsl4a/special/pgptai/#_2","title":"\u8bed\u97f3\u8bc6\u522b","text":""},{"location":"qsl4a/special/pgptai/#speechtotext","title":"speechToText()","text":"

      \u5c06\u8bed\u97f3\u8f6c\u6362\u4e3a\u6587\u672c\u3002

      speechToText(RecordSecond=10, AmrFile=None, Language=None)\n

      \u53c2\u6570\uff1a - RecordSecond (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09 - AmrFile (str, optional): \u73b0\u6709\u97f3\u9891\u6587\u4ef6\u8def\u5f84 - Language (str, optional): \u8bed\u8a00\u4ee3\u7801\uff08'en'\u3001'zh'\uff09

      \u8fd4\u56de\uff1a \u8f6c\u5f55\u7684\u6587\u672c

      "},{"location":"qsl4a/special/pgptai/#_3","title":"\u6587\u672c\u8f6c\u8bed\u97f3","text":""},{"location":"qsl4a/special/pgptai/#texttospeech","title":"textToSpeech()","text":"

      \u5c06\u6587\u672c\u8f6c\u6362\u4e3a\u8bed\u97f3\u5e76\u53ef\u9009\u5730\u64ad\u653e\u3002

      textToSpeech(Text, AutoPlay=True, WavFile=None, VoiceName=None)\n

      \u53c2\u6570\uff1a - Text (str): \u8981\u8f6c\u6362\u4e3a\u8bed\u97f3\u7684\u6587\u672c - AutoPlay (bool): \u81ea\u52a8\u64ad\u653e\u751f\u6210\u7684\u97f3\u9891\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - WavFile (str, optional): \u4fdd\u5b58 WAV \u6587\u4ef6\u7684\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u4e34\u65f6\u6587\u4ef6 - VoiceName (str, optional): \u8981\u4f7f\u7528\u7684\u8bed\u97f3\u540d\u79f0\uff08\u4f8b\u5982 'en-US-JennyNeural'\u3001'zh-CN-XiaoxiaoNeural'\uff09

      \u8fd4\u56de\uff1a \u5305\u542b\u8bed\u97f3\u5408\u6210\u7ed3\u679c\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - text: \u8f93\u5165\u6587\u672c - url: \u4e0b\u8f7d\u97f3\u9891\u6587\u4ef6\u7684 URL - WavFile: \u4fdd\u5b58\u7684 WAV \u6587\u4ef6\u8def\u5f84\uff08\u5982\u679c\u672c\u5730\u4fdd\u5b58\uff09

      "},{"location":"qsl4a/special/pgptai/#_4","title":"\u914d\u7f6e","text":"

      API \u4f7f\u7528\u4ee5\u4e0b\u914d\u7f6e\u6587\u4ef6\u4e2d\u7684\u914d\u7f6e\uff1a/storage/emulated/0/Android/data/org.qpython.qpy/files/apigpt.conf\uff1a

      [speech]\nspeech_key = your_api_key\n

      \u9ed8\u8ba4\u8bed\u97f3\u8bbe\u7f6e\uff1a - \u82f1\u8bed\uff1aen-US-JennyNeural - \u4e2d\u6587\uff1azh-CN-XiaoxiaoNeural

      "},{"location":"qsl4a/special/pgptai/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5f55\u5236\u5e76\u8f6c\u5f55\nprint(\"Recording for 5 seconds...\")\ntext = droid.speechToText(RecordSecond=5, Language='en').result\nprint(f\"You said: {text}\")\n\n# \u8f6c\u5f55\u73b0\u6709\u6587\u4ef6\ntext = droid.speechToText(AmrFile=\"/sdcard/recording.amr\").result\nprint(f\"Transcription: {text}\")\n\n# \u6587\u672c\u8f6c\u8bed\u97f3\ndroid.textToSpeech(\"Hello, this is a test message.\", AutoPlay=True, Language='en')\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u8bed\u97f3\u5e76\u4fdd\u5b58\u5230\u6587\u4ef6\u7684\u6587\u672c\u8f6c\u8bed\u97f3\nresult = droid.textToSpeech(\n    \"Welcome to QPython!\",\n    AutoPlay=False,\n    WavFile=\"/sdcard/welcome.wav\",\n    VoiceName=\"en-US-JennyNeural\"\n).result\nprint(f\"Audio saved to: {result.get('WavFile')}\")\n
      "},{"location":"qsl4a/special/pgptai/#_6","title":"\u7c7b\u4f7f\u7528","text":"
      from androidhelper.pgptai import pgptai\nimport androidhelper\n\ndroid = androidhelper.Android()\nai = pgptai(droid)\n\n# \u4f7f\u7528\u8bed\u97f3\u8bc6\u522b\ntext = ai.speechToText(RecordSecond=10)\n
      "},{"location":"qsl4a/storage/clipboard/","title":"\u526a\u8d34\u677f API","text":"

      \u590d\u5236\u548c\u7c98\u8d34\u6587\u672c\u5230\u7cfb\u7edf\u526a\u8d34\u677f\u3002

      "},{"location":"qsl4a/storage/clipboard/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/clipboard/#setclipboard","title":"setClipboard()","text":"

      \u590d\u5236\u6587\u672c\u5230\u526a\u8d34\u677f\u3002

      setClipboard(text)\n

      \u53c2\u6570\uff1a - text (str): \u8981\u590d\u5236\u7684\u6587\u672c

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/clipboard/#getclipboard","title":"getClipboard()","text":"

      \u4ece\u526a\u8d34\u677f\u83b7\u53d6\u6587\u672c\u3002

      getClipboard()\n

      \u8fd4\u56de\uff1a \u526a\u8d34\u677f\u6587\u672c

      "},{"location":"qsl4a/storage/clipboard/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u590d\u5236\u5230\u526a\u8d34\u677f\ndroid.setClipboard(\"Hello from QPython!\")\n\n# \u4ece\u526a\u8d34\u677f\u7c98\u8d34\ntext = droid.getClipboard().result\nprint(f\"Clipboard: {text}\")\n
      "},{"location":"qsl4a/storage/documentfile/","title":"DocumentFile API","text":"

      \u4f7f\u7528 SAF\uff08\u5b58\u50a8\u8bbf\u95ee\u6846\u67b6\uff09\u8fdb\u884c\u6587\u4ef6\u64cd\u4f5c\uff0c\u652f\u6301 Android 4.4+\u3002

      "},{"location":"qsl4a/storage/documentfile/#_1","title":"\u76ee\u5f55\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilemkdir","title":"documentFileMkdir()","text":"

      \u521b\u5efa\u76ee\u5f55\u3002

      documentFileMkdir(Dir)\n

      \u53c2\u6570\uff1a - Dir (str): \u76ee\u5f55\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/documentfile/#documentfilelistfiles","title":"documentFileListFiles()","text":"

      \u5217\u51fa\u76ee\u5f55\u4e2d\u7684\u6587\u4ef6\u3002

      documentFileListFiles(Folder)\n

      \u8fd4\u56de\uff1a \u6587\u4ef6\u5217\u8868

      "},{"location":"qsl4a/storage/documentfile/#_2","title":"\u6587\u4ef6\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileexists","title":"documentFileExists()","text":"

      \u68c0\u67e5\u6587\u4ef6\u6216\u76ee\u5f55\u662f\u5426\u5b58\u5728\u3002

      documentFileExists(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u6216\u76ee\u5f55\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u5b58\u5728\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/storage/documentfile/#documentfileisfile","title":"documentFileIsFile()","text":"

      \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u6587\u4ef6\u3002

      documentFileIsFile(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u662f\u6587\u4ef6\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u6587\u4ef6\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

      "},{"location":"qsl4a/storage/documentfile/#documentfileisdirectory","title":"documentFileIsDirectory()","text":"

      \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u76ee\u5f55\u3002

      documentFileIsDirectory(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u662f\u76ee\u5f55\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u76ee\u5f55\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

      "},{"location":"qsl4a/storage/documentfile/#documentfiledelete","title":"documentFileDelete()","text":"

      \u5220\u9664\u6587\u4ef6\u6216\u76ee\u5f55\u3002

      documentFileDelete(FileOrTree)\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/documentfile/#documentfilerenameto","title":"documentFileRenameTo()","text":"

      \u91cd\u547d\u540d\u6216\u79fb\u52a8\u6587\u4ef6\u3002

      documentFileRenameTo(Src, Dest)\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/documentfile/#documentfilecopy","title":"documentFileCopy()","text":"

      \u590d\u5236\u6587\u4ef6\u3002

      documentFileCopy(SrcFileOrTree, DestFileOrTree)\n
      "},{"location":"qsl4a/storage/documentfile/#_3","title":"\u6d41\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileinputstream","title":"documentFileInputStream()","text":"

      \u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9\u3002

      documentFileInputStream(srcFile, EncodingFormat=\"\", skip=None, length=None)\n

      \u53c2\u6570\uff1a - srcFile (str): \u6e90\u6587\u4ef6 - EncodingFormat (str): \"UTF-8\"\u3001\"GBK\"\u3001\"Base64\" \u6216\u7a7a\u5b57\u7b26\u4e32\u8868\u793a\u5b57\u8282 - skip (int): \u4ece\u5f00\u5934\u8df3\u8fc7\u7684\u5b57\u8282\u6570 - length (int): \u8bfb\u53d6\u957f\u5ea6

      \u8fd4\u56de\uff1a \u6587\u4ef6\u5185\u5bb9

      "},{"location":"qsl4a/storage/documentfile/#documentfileoutputstream","title":"documentFileOutputStream()","text":"

      \u5199\u5165\u6587\u4ef6\u5185\u5bb9\u3002

      documentFileOutputStream(destFile, src, EncodingFormat=\"\", append=None)\n

      \u53c2\u6570\uff1a - destFile (str): \u76ee\u6807\u6587\u4ef6 - src: \u8981\u5199\u5165\u7684\u6570\u636e - EncodingFormat (str): \u7f16\u7801\u683c\u5f0f - append (bool): \u8ffd\u52a0\u6a21\u5f0f

      "},{"location":"qsl4a/storage/documentfile/#_4","title":"\u6587\u4ef6\u4fe1\u606f","text":""},{"location":"qsl4a/storage/documentfile/#documentfilelength","title":"documentFileLength()","text":"

      \u83b7\u53d6\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\u3002

      documentFileLength(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

      "},{"location":"qsl4a/storage/documentfile/#documentfilelastmodified","title":"documentFileLastModified()","text":"

      \u83b7\u53d6\u6700\u540e\u4fee\u6539\u65f6\u95f4\u3002

      documentFileLastModified(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u65f6\u95f4\u6233\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

      "},{"location":"qsl4a/storage/documentfile/#documentfilegetstat","title":"documentFileGetStat()","text":"

      \u83b7\u53d6\u5168\u9762\u7684\u6587\u4ef6\u7edf\u8ba1\u4fe1\u606f\u3002

      documentFileGetStat(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5305\u542b\u957f\u5ea6\u3001\u6700\u540e\u4fee\u6539\u65f6\u95f4\u548c\u8bfb/\u5199\u6743\u9650\u7684\u5b57\u5178\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

      "},{"location":"qsl4a/storage/documentfile/#uri","title":"URI \u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilegeturi","title":"documentFileGetUri()","text":"

      \u4ece\u8def\u5f84\u83b7\u53d6 URI\u3002

      documentFileGetUri(path, isDirectory=None)\n
      "},{"location":"qsl4a/storage/documentfile/#documentfileshowopen","title":"documentFileShowOpen()","text":"

      \u663e\u793a\u6587\u4ef6\u9009\u62e9\u5668\u3002

      documentFileShowOpen()\n

      \u8fd4\u56de\uff1a \u9009\u62e9\u7684\u6587\u4ef6 URI

      "},{"location":"qsl4a/storage/documentfile/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u76ee\u5f55\ndroid.documentFileMkdir(\"/sdcard/MyFolder\")\n\n# \u5217\u51fa\u6587\u4ef6\nfiles = droid.documentFileListFiles(\"/sdcard\").result\nfor f in files:\n    print(f)\n\n# \u8bfb\u53d6\u6587\u4ef6\ncontent = droid.documentFileInputStream(\n    \"/sdcard/test.txt\",\n    EncodingFormat=\"UTF-8\"\n).result\nprint(content)\n\n# \u5199\u5165\u6587\u4ef6\ndroid.documentFileOutputStream(\n    \"/sdcard/output.txt\",\n    \"Hello World\",\n    EncodingFormat=\"UTF-8\"\n)\n
      "},{"location":"qsl4a/storage/preferences/","title":"\u504f\u597d\u8bbe\u7f6e API","text":"

      \u4f7f\u7528 Android SharedPreferences \u5b58\u50a8\u548c\u68c0\u7d22\u6570\u636e\u3002

      "},{"location":"qsl4a/storage/preferences/#_1","title":"\u504f\u597d\u8bbe\u7f6e\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/preferences/#prefgetvalue","title":"prefGetValue()","text":"

      \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u8bfb\u53d6\u503c\u3002

      prefGetValue(key, filename=None)\n

      \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c\uff08\u4efb\u610f\u7c7b\u578b\uff09

      "},{"location":"qsl4a/storage/preferences/#prefputvalue","title":"prefPutValue()","text":"

      \u5199\u5165\u503c\u5230\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u3002

      prefPutValue(key, value, filename=None)\n

      \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - value (object): \u8981\u5b58\u50a8\u7684\u503c - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      "},{"location":"qsl4a/storage/preferences/#prefgetall","title":"prefGetAll()","text":"

      \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\u503c\u3002

      prefGetAll(filename=None)\n

      \u53c2\u6570\uff1a - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      \u8fd4\u56de\uff1a \u6240\u6709\u504f\u597d\u7684\u6620\u5c04

      "},{"location":"qsl4a/storage/preferences/#prefremovevalue","title":"prefRemoveValue()","text":"

      \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u4e2d\u79fb\u9664\u503c\u3002

      prefRemoveValue(key, filename=None)\n

      \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      "},{"location":"qsl4a/storage/preferences/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b58\u50a8\u503c\ndroid.prefPutValue(\"username\", \"alice\")\ndroid.prefPutValue(\"score\", 100)\ndroid.prefPutValue(\"enabled\", True)\n\n# \u8bfb\u53d6\u7279\u5b9a\u503c\nusername = droid.prefGetValue(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\nall_prefs = droid.prefGetAll().result\nprint(f\"All prefs: {all_prefs}\")\n\n# \u79fb\u9664\u503c\ndroid.prefRemoveValue(\"score\")\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u6587\u4ef6\u540d\ndroid.prefPutValue(\"token\", \"abc123\", filename=\"auth.prefs\")\ntoken = droid.prefGetValue(\"token\", filename=\"auth.prefs\").result\n
      "},{"location":"qsl4a/system/activityresult/","title":"Activity Result API","text":"

      \u4e3a\u901a\u8fc7 startActivityForResult \u542f\u52a8\u7684\u811a\u672c\u8bbe\u7f6e activity \u7ed3\u679c\u3002

      "},{"location":"qsl4a/system/activityresult/#_1","title":"\u7ed3\u679c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/activityresult/#setresultboolean","title":"setResultBoolean()","text":"

      \u8bbe\u7f6e\u5e03\u5c14\u7ed3\u679c\u3002

      setResultBoolean(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (bool): \u5e03\u5c14\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultbyte","title":"setResultByte()","text":"

      \u8bbe\u7f6e\u5b57\u8282\u7ed3\u679c\u3002

      setResultByte(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u5b57\u8282\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultshort","title":"setResultShort()","text":"

      \u8bbe\u7f6e\u77ed\u6574\u6570\u7ed3\u679c\u3002

      setResultShort(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u77ed\u6574\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultchar","title":"setResultChar()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u7ed3\u679c\u3002

      setResultChar(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultinteger","title":"setResultInteger()","text":"

      \u8bbe\u7f6e\u6574\u6570\u7ed3\u679c\u3002

      setResultInteger(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u6574\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultlong","title":"setResultLong()","text":"

      \u8bbe\u7f6e\u957f\u6574\u6570\u7ed3\u679c\u3002

      setResultLong(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u957f\u6574\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultfloat","title":"setResultFloat()","text":"

      \u8bbe\u7f6e\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

      setResultFloat(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u6d6e\u70b9\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultdouble","title":"setResultDouble()","text":"

      \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

      setResultDouble(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultstring","title":"setResultString()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u4e32\u7ed3\u679c\u3002

      setResultString(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u4e32\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultbooleanarray","title":"setResultBooleanArray()","text":"

      \u8bbe\u7f6e\u5e03\u5c14\u6570\u7ec4\u7ed3\u679c\u3002

      setResultBooleanArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5e03\u5c14\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultbytearray","title":"setResultByteArray()","text":"

      \u8bbe\u7f6e\u5b57\u8282\u6570\u7ec4\u7ed3\u679c\u3002

      setResultByteArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u8282\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultshortarray","title":"setResultShortArray()","text":"

      \u8bbe\u7f6e\u77ed\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultShortArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u77ed\u6574\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultchararray","title":"setResultCharArray()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u6570\u7ec4\u7ed3\u679c\u3002

      setResultCharArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultintegerarray","title":"setResultIntegerArray()","text":"

      \u8bbe\u7f6e\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultIntegerArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6574\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultlongarray","title":"setResultLongArray()","text":"

      \u8bbe\u7f6e\u957f\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultLongArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u957f\u6574\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultfloatarray","title":"setResultFloatArray()","text":"

      \u8bbe\u7f6e\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultFloatArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6d6e\u70b9\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultdoublearray","title":"setResultDoubleArray()","text":"

      \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultDoubleArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultstringarray","title":"setResultStringArray()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u4e32\u6570\u7ec4\u7ed3\u679c\u3002

      setResultStringArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u4e32\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultserializable","title":"setResultSerializable()","text":"

      \u8bbe\u7f6e\u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u3002

      setResultSerializable(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue: \u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c activity \u540e\uff0c\u8bbe\u7f6e\u7ed3\u679c\n# \u793a\u4f8b\uff1a\u8fd4\u56de\u6210\u529f\u53ca\u6570\u636e\ndroid.setResultInteger(0, 200)  # RESULT_OK\ndroid.setResultString(0, \"Operation completed successfully\")\n\n# \u8fd4\u56de\u6570\u7ec4\u7ed3\u679c\ndroid.setResultIntegerArray(0, [1, 2, 3, 4, 5])\n
      "},{"location":"qsl4a/system/application/","title":"\u5e94\u7528\u7ba1\u7406","text":"

      \u7ba1\u7406\u5e94\u7528\u7a0b\u5e8f\u3001\u542f\u52a8\u5e94\u7528\u548c\u67e5\u8be2\u7cfb\u7edf\u4fe1\u606f\u3002

      "},{"location":"qsl4a/system/application/#_2","title":"\u5e94\u7528\u7a0b\u5e8f\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getapplicationinfo","title":"getApplicationInfo()","text":"

      \u83b7\u53d6\u5e94\u7528\u4fe1\u606f\u3002

      getApplicationInfo(packageName=None)\n

      \u53c2\u6570\uff1a - packageName (str): \u5305\u540d\uff08None = \u5f53\u524d\u5e94\u7528\uff09

      \u8fd4\u56de\uff1a \u5e94\u7528\u4fe1\u606f\u5b57\u5178

      "},{"location":"qsl4a/system/application/#getinstalledpackages","title":"getInstalledPackages()","text":"

      \u83b7\u53d6\u5df2\u5b89\u88c5\u5305\u5217\u8868\u3002

      getInstalledPackages(flag=4)\n

      \u53c2\u6570\uff1a - flag (int): \u5305\u6807\u5fd7\u8fc7\u6ee4\u5668\uff08\u9ed8\u8ba4\uff1a4\uff09

      \u8fd4\u56de\uff1a \u5df2\u5b89\u88c5\u5305\u5217\u8868

      "},{"location":"qsl4a/system/application/#getrunningpackages","title":"getRunningPackages()","text":"

      \u5217\u51fa\u6b63\u5728\u8fd0\u884c\u7684\u5305\u3002

      getRunningPackages()\n

      \u8fd4\u56de\uff1a \u5305\u540d\u5217\u8868

      "},{"location":"qsl4a/system/application/#getlaunchablepackages","title":"getLaunchablePackages()","text":"

      \u83b7\u53d6\u53ef\u542f\u52a8\u5305\u5217\u8868\u3002

      getLaunchablePackages(needClassName=False)\n

      \u53c2\u6570\uff1a - needClassName (bool): \u5305\u542b\u4e3b activity \u7c7b\u540d\uff08\u9ed8\u8ba4\uff1aFalse\uff09

      \u8fd4\u56de\uff1a \u53ef\u542f\u52a8\u5305\u540d\u5217\u8868\u6216\u5305\u542b\u7c7b\u540d\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#_3","title":"\u5e94\u7528\u63a7\u5236","text":""},{"location":"qsl4a/system/application/#launch","title":"launch()","text":"

      \u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u3002

      launch(classname=None, packagename=None, wait=True)\n

      \u53c2\u6570\uff1a - classname (str): \u4e3b activity \u7c7b\u540d - packagename (str): \u5305\u540d - wait (bool): \u7b49\u5f85\u542f\u52a8\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

      \u8fd4\u56de\uff1a \u542f\u52a8\u7ed3\u679c

      "},{"location":"qsl4a/system/application/#forcestoppackage","title":"forceStopPackage()","text":"

      \u5f3a\u5236\u505c\u6b62\u5e94\u7528\u7a0b\u5e8f\u3002

      forceStopPackage(packageName)\n

      \u53c2\u6570\uff1a - packageName (str): \u8981\u505c\u6b62\u7684\u5305\u540d

      "},{"location":"qsl4a/system/application/#_4","title":"\u7248\u672c\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getpackageversion","title":"getPackageVersion()","text":"

      \u83b7\u53d6\u5e94\u7528\u7248\u672c\u540d\u79f0\u3002

      getPackageVersion(packageName)\n

      \u8fd4\u56de\uff1a \u7248\u672c\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"3.2.1\"\uff09

      "},{"location":"qsl4a/system/application/#getpackageversioncode","title":"getPackageVersionCode()","text":"

      \u83b7\u53d6\u5e94\u7528\u7248\u672c\u4ee3\u7801\u3002

      getPackageVersionCode(packageName)\n

      \u8fd4\u56de\uff1a \u7248\u672c\u4ee3\u7801\u6574\u6570

      "},{"location":"qsl4a/system/application/#getconstants","title":"getConstants()","text":"

      \u83b7\u53d6\u7c7b\u5e38\u91cf\u3002

      getConstants(classname)\n

      \u53c2\u6570\uff1a - classname (str): \u5b8c\u6574\u7c7b\u540d

      \u8fd4\u56de\uff1a \u5e38\u91cf\u540d\u548c\u503c\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#_5","title":"\u7cfb\u7edf\u529f\u80fd","text":""},{"location":"qsl4a/system/application/#backgroundprotect","title":"backgroundProtect()","text":"

      \u542f\u7528\u6216\u7981\u7528\u5e94\u7528\u7684\u540e\u53f0\u4fdd\u62a4\u3002

      backgroundProtect(enabled=True)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\u4fdd\u62a4\uff0cFalse \u7981\u7528

      "},{"location":"qsl4a/system/application/#createscriptshortcut","title":"createScriptShortCut()","text":"

      \u4e3a\u811a\u672c\u521b\u5efa\u4e3b\u5c4f\u5e55\u5feb\u6377\u65b9\u5f0f\u3002

      createScriptShortCut(scriptPath, label=None, iconPath=None, scriptArg=None)\n

      \u53c2\u6570\uff1a - scriptPath (str): Python \u811a\u672c\u8def\u5f84 - label (str, optional): \u5feb\u6377\u65b9\u5f0f\u6807\u7b7e - iconPath (str, optional): \u56fe\u6807\u56fe\u50cf\u8def\u5f84 - scriptArg (str, optional): \u4f20\u9012\u7ed9\u811a\u672c\u7684\u53c2\u6570

      "},{"location":"qsl4a/system/application/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getandroidid","title":"getAndroidID()","text":"

      \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

      getAndroidID()\n

      \u8fd4\u56de\uff1a \u552f\u4e00\u7684 Android \u8bbe\u5907 ID \u5b57\u7b26\u4e32

      "},{"location":"qsl4a/system/application/#getsysinfo","title":"getSysInfo()","text":"

      \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\u3002

      getSysInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#getlocale","title":"getLocale()","text":"

      \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u3002

      getLocale()\n

      \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

      "},{"location":"qsl4a/system/application/#getharmonyosinformation","title":"getHarmonyOsInformation()","text":"

      \u5982\u679c\u5728 HarmonyOS \u4e0a\u8fd0\u884c\uff0c\u83b7\u53d6 HarmonyOS \u4fe1\u606f\u3002

      getHarmonyOsInformation()\n

      \u8fd4\u56de\uff1a HarmonyOS \u7248\u672c\u4fe1\u606f\u6216 None

      "},{"location":"qsl4a/system/application/#isexternalstoragemanager","title":"isExternalStorageManager()","text":"

      \u68c0\u67e5\u5e94\u7528\u662f\u5426\u6709\u5916\u90e8\u5b58\u50a8\u7ba1\u7406\u5668\u6743\u9650\u3002

      isExternalStorageManager()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6709\u6743\u9650\u5219\u4e3a True

      "},{"location":"qsl4a/system/application/#_7","title":"\u5185\u5b58\u548c\u663e\u793a","text":""},{"location":"qsl4a/system/application/#getmemoryinfo","title":"getMemoryInfo()","text":"

      \u83b7\u53d6\u5185\u5b58\u4fe1\u606f\u3002

      getMemoryInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#getscreeninfo","title":"getScreenInfo()","text":"

      \u83b7\u53d6\u5c4f\u5e55\u4fe1\u606f\u3002

      getScreenInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#_8","title":"\u6743\u9650","text":""},{"location":"qsl4a/system/application/#checkpermissions","title":"checkPermissions()","text":"

      \u68c0\u67e5\u5f53\u524d\u5e94\u7528\u6743\u9650\u3002

      checkPermissions()\n

      \u8fd4\u56de\uff1a \u6743\u9650\u53ca\u5176\u72b6\u6001\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#requestpermissions","title":"requestPermissions()","text":"

      \u5411\u7528\u6237\u8bf7\u6c42\u6743\u9650\u3002

      requestPermissions(permissions=None)\n

      \u53c2\u6570\uff1a - permissions (list, optional): \u8981\u8bf7\u6c42\u7684\u6743\u9650\u5217\u8868\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8bf7\u6c42\u6240\u6709\u9700\u8981\u7684\u6743\u9650\u3002

      \u8fd4\u56de\uff1a \u6743\u9650\u8bf7\u6c42\u7ed3\u679c

      "},{"location":"qsl4a/system/application/#_9","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/system/application/#showscreenlock","title":"showScreenLock()","text":"

      \u663e\u793a\u5c4f\u5e55\u9501\u5b9a\uff08PIN/\u56fe\u6848/\u5bc6\u7801\u8f93\u5165\uff09\u3002

      showScreenLock()\n
      "},{"location":"qsl4a/system/application/#_10","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\ninfo = droid.getSysInfo().result\nprint(f\"System: {info}\")\n\n# \u83b7\u53d6\u5e94\u7528\u7248\u672c\nversion = droid.getPackageVersion(\"org.qpython.qpy\").result\nprint(f\"QPython version: {version}\")\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u5e94\u7528\napps = droid.getInstalledPackages().result\nprint(f\"Installed apps: {len(apps)}\")\n\n# \u542f\u52a8\u5e94\u7528\ndroid.launch(packagename=\"com.android.settings\")\n\n# \u68c0\u67e5\u6743\u9650\nperms = droid.checkPermissions().result\nprint(f\"Permissions: {perms}\")\n\n# \u8bf7\u6c42\u5b58\u50a8\u6743\u9650\ndroid.requestPermissions([\"android.permission.READ_EXTERNAL_STORAGE\"])\n\n# \u521b\u5efa\u5feb\u6377\u65b9\u5f0f\ndroid.createScriptShortCut(\n    \"/sdcard/my_script.py\",\n    label=\"My Script\",\n    iconPath=\"/sdcard/icon.png\"\n)\n
      "},{"location":"qsl4a/system/battery/","title":"\u7535\u6c60 API","text":"

      \u76d1\u63a7\u8bbe\u5907\u7535\u6c60\u72b6\u6001\u548c\u5065\u5eb7\u72b6\u51b5\u3002

      "},{"location":"qsl4a/system/battery/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/battery/#readbatterydata","title":"readBatteryData()","text":"

      \u83b7\u53d6\u5b8c\u6574\u7684\u7535\u6c60\u4fe1\u606f\u3002

      readBatteryData()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7535\u6c60\u6570\u636e\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/battery/#batterystartmonitoring","title":"batteryStartMonitoring()","text":"

      \u5f00\u59cb\u7535\u6c60\u76d1\u63a7\u3002

      batteryStartMonitoring()\n
      "},{"location":"qsl4a/system/battery/#batterystopmonitoring","title":"batteryStopMonitoring()","text":"

      \u505c\u6b62\u7535\u6c60\u76d1\u63a7\u3002

      batteryStopMonitoring()\n
      "},{"location":"qsl4a/system/battery/#batterygetlevel","title":"batteryGetLevel()","text":"

      \u83b7\u53d6\u7535\u6c60\u767e\u5206\u6bd4\u3002

      batteryGetLevel()\n

      \u8fd4\u56de\uff1a \u6574\u6570\uff080-100\uff09

      "},{"location":"qsl4a/system/battery/#batterygetstatus","title":"batteryGetStatus()","text":"

      \u83b7\u53d6\u5145\u7535\u72b6\u6001\u3002

      batteryGetStatus()\n

      \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u5145\u7535\u4e2d - 3: \u653e\u7535\u4e2d - 4: \u672a\u5145\u7535 - 5: \u5df2\u5145\u6ee1

      "},{"location":"qsl4a/system/battery/#batterygetplugtype","title":"batteryGetPlugType()","text":"

      \u83b7\u53d6\u7535\u6e90\u7c7b\u578b\u3002

      batteryGetPlugType()\n

      \u8fd4\u56de\uff1a - -1: \u672a\u77e5 - 0: \u672a\u63d2\u7535 - 1: AC \u5145\u7535\u5668 - 2: USB \u7aef\u53e3

      "},{"location":"qsl4a/system/battery/#batterygethealth","title":"batteryGetHealth()","text":"

      \u83b7\u53d6\u7535\u6c60\u5065\u5eb7\u72b6\u51b5\u3002

      batteryGetHealth()\n

      \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u826f\u597d - 3: \u8fc7\u70ed - 4: \u635f\u574f - 5: \u8fc7\u538b - 6: \u672a\u6307\u5b9a\u7684\u6545\u969c

      "},{"location":"qsl4a/system/battery/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\nlevel = droid.batteryGetLevel().result\nprint(f\"Battery: {level}%\")\n
      "},{"location":"qsl4a/system/qpyinterface/","title":"QPython \u63a5\u53e3 API","text":"

      \u4ece\u5176\u4ed6\u5e94\u7528\u6267\u884c QPython \u811a\u672c\u548c\u7ba1\u7406\u5171\u4eab\u53d8\u91cf\u3002

      "},{"location":"qsl4a/system/qpyinterface/#_1","title":"\u811a\u672c\u6267\u884c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/qpyinterface/#executeqpy","title":"executeQPy()","text":"

      \u6267\u884c QPython \u811a\u672c\u3002

      executeQPy(path=\"\", arg=None)\n

      \u53c2\u6570\uff1a - path (str): \u811a\u672c\u6587\u4ef6\u8def\u5f84 - arg (str, optional): \u547d\u4ee4\u884c\u53c2\u6570

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#executeqpyassrv","title":"executeQPyAsSrv()","text":"

      \u4f5c\u4e3a\u670d\u52a1\u6267\u884c QPython \u811a\u672c\u3002

      executeQPyAsSrv(path=None)\n

      \u53c2\u6570\uff1a - path (str, optional): \u811a\u672c\u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#executeqpycode","title":"executeQPyCode()","text":"

      \u76f4\u63a5\u6267\u884c Python \u4ee3\u7801\u3002

      executeQPyCode(code=None)\n

      \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#executeqpycodeassrv","title":"executeQPyCodeAsSrv()","text":"

      \u4f5c\u4e3a\u670d\u52a1\u6267\u884c Python \u4ee3\u7801\u3002

      executeQPyCodeAsSrv(code=None)\n

      \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#_2","title":"\u5171\u4eab\u53d8\u91cf","text":"

      \u5171\u4eab\u53d8\u91cf\u5141\u8bb8 QPython \u4e0e\u5176\u4ed6\u5e94\u7528\u4e4b\u95f4\u8fdb\u884c\u901a\u4fe1\u3002

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableset","title":"sharedVariableSet()","text":"

      \u8bbe\u7f6e Java \u5171\u4eab\u53d8\u91cf\u3002

      sharedVariableSet(key, value)\n

      \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d - value (str): \u53d8\u91cf\u503c

      \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableget","title":"sharedVariableGet()","text":"

      \u83b7\u53d6 Java \u5171\u4eab\u53d8\u91cf\u3002

      sharedVariableGet(key)\n

      \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d

      \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableremove","title":"sharedVariableRemove()","text":"

      \u79fb\u9664 Java \u5171\u4eab\u53d8\u91cf\u3002

      sharedVariableRemove(key)\n

      \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u53d8\u91cf\u540d

      \u8fd4\u56de\uff1a \u88ab\u79fb\u9664\u7684\u503c

      "},{"location":"qsl4a/system/qpyinterface/#getlastlog","title":"getLastLog()","text":"

      \u83b7\u53d6 QPython \u7684\u6700\u540e\u65e5\u5fd7\u8f93\u51fa\u3002

      getLastLog()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u65e5\u5fd7\u5185\u5bb9

      "},{"location":"qsl4a/system/qpyinterface/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c\u811a\u672c\ndroid.executeQPy(\"/sdcard/my_script.py\", arg=\"test\")\n\n# \u76f4\u63a5\u6267\u884c\u4ee3\u7801\ncode = \"print('Hello from QPython!')\"\ndroid.executeQPyCode(code)\n\n# \u4f7f\u7528\u5171\u4eab\u53d8\u91cf\ndroid.sharedVariableSet(\"username\", \"alice\")\nusername = droid.sharedVariableGet(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u79fb\u9664\u53d8\u91cf\ndroid.sharedVariableRemove(\"username\")\n\n# \u83b7\u53d6\u6700\u8fd1\u65e5\u5fd7\nlog = droid.getLastLog().result\nprint(f\"Log: {log}\")\n
      "},{"location":"qsl4a/system/sensors/","title":"\u4f20\u611f\u5668 API","text":"

      \u8bbf\u95ee\u8bbe\u5907\u4f20\u611f\u5668\uff0c\u5305\u62ec\u52a0\u901f\u5ea6\u8ba1\u3001\u9640\u87ba\u4eea\u3001\u78c1\u529b\u8ba1\u7b49\u3002

      "},{"location":"qsl4a/system/sensors/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/sensors/#startsensingtimed","title":"startSensingTimed()","text":"

      \u5f00\u59cb\u4f20\u611f\u5668\u76d1\u63a7\u5e76\u8bbe\u7f6e\u65f6\u95f4\u95f4\u9694\u3002

      startSensingTimed(sensorNumber, delayTime)\n

      \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID\uff08\u901a\u5e38\u4e3a 1-3\uff09 - delayTime (int): \u8bfb\u53d6\u4e4b\u95f4\u7684\u5ef6\u8fdf\uff08\u6beb\u79d2\uff09

      "},{"location":"qsl4a/system/sensors/#startsensingthreshold","title":"startSensingThreshold()","text":"

      \u5f00\u59cb\u5e26\u9608\u503c\u89e6\u53d1\u7684\u4f20\u611f\u5668\u76d1\u63a7\u3002

      startSensingThreshold(sensorNumber, threshold, axis)\n

      \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID - threshold (float): \u89e6\u53d1\u9608\u503c - axis (int): \u8981\u76d1\u63a7\u7684\u8f74\uff080=X\uff0c1=Y\uff0c2=Z\uff09

      "},{"location":"qsl4a/system/sensors/#stopsensing","title":"stopSensing()","text":"

      \u505c\u6b62\u6240\u6709\u4f20\u611f\u5668\u76d1\u63a7\u3002

      stopSensing()\n
      "},{"location":"qsl4a/system/sensors/#readsensors","title":"readSensors()","text":"

      \u8bfb\u53d6\u5f53\u524d\u4f20\u611f\u5668\u6570\u636e\u3002

      readSensors()\n

      \u8fd4\u56de\uff1a \u4f20\u611f\u5668\u6570\u636e\u5b57\u5178

      "},{"location":"qsl4a/system/sensors/#sensorsreadaccelerometer","title":"sensorsReadAccelerometer()","text":"

      \u8bfb\u53d6\u52a0\u901f\u5ea6\u8ba1\u503c\u3002

      sensorsReadAccelerometer()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d m/s\u00b2

      "},{"location":"qsl4a/system/sensors/#sensorsreadgyroscope","title":"sensorsReadGyroscope()","text":"

      \u8bfb\u53d6\u9640\u87ba\u4eea\u503c\u3002

      sensorsReadGyroscope()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d rad/s

      "},{"location":"qsl4a/system/sensors/#sensorsreadmagnetometer","title":"sensorsReadMagnetometer()","text":"

      \u8bfb\u53d6\u78c1\u573a\u503c\u3002

      sensorsReadMagnetometer()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d \u03bcT

      "},{"location":"qsl4a/system/sensors/#sensorsreadorientation","title":"sensorsReadOrientation()","text":"

      \u8bfb\u53d6\u8bbe\u5907\u65b9\u5411\u3002

      sensorsReadOrientation()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [azimuth, pitch, roll]\uff0c\u5355\u4f4d\u5ea6

      "},{"location":"qsl4a/system/sensors/#sensorsgetlight","title":"sensorsGetLight()","text":"

      \u8bfb\u53d6\u5149\u4f20\u611f\u5668\u503c\u3002

      sensorsGetLight()\n

      \u8fd4\u56de\uff1a \u5149\u7ea7\u522b\uff08lux\uff09

      "},{"location":"qsl4a/system/sensors/#sensorsgetstepcounter","title":"sensorsGetStepCounter()","text":"

      \u8bfb\u53d6\u6b65\u8ba1\u6570\u5668\u3002

      sensorsGetStepCounter()\n

      \u8fd4\u56de\uff1a \u6b65\u6570

      "},{"location":"qsl4a/system/sensors/#sensorsgetaccuracy","title":"sensorsGetAccuracy()","text":"

      \u83b7\u53d6\u5f53\u524d\u4f20\u611f\u5668\u7cbe\u5ea6\u3002

      sensorsGetAccuracy()\n

      \u8fd4\u56de\uff1a \u7cbe\u5ea6\u503c\uff080-3\uff1aUNRELIABLE\u3001ACCURACY_LOW\u3001ACCURACY_MEDIUM\u3001ACCURACY_HIGH\uff09

      "},{"location":"qsl4a/system/sensors/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u8bfb\u53d6\u4f20\u611f\u5668 10 \u6b21\nfor i in range(10):\n    accel = droid.sensorsReadAccelerometer().result\n    print(f\"Accel: X={accel[0]:.2f}, Y={accel[1]:.2f}, Z={accel[2]:.2f}\")\n    time.sleep(0.5)\n\ndroid.stopSensing()\n
      "},{"location":"qsl4a/system/settings/","title":"\u8bbe\u7f6e API","text":"

      \u63a7\u5236\u7cfb\u7edf\u8bbe\u7f6e\uff0c\u5305\u62ec\u5c4f\u5e55\u3001\u58f0\u97f3\u548c\u7f51\u7edc\u8bbe\u7f6e\u3002

      "},{"location":"qsl4a/system/settings/#_1","title":"\u5c4f\u5e55\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#setscreentimeout","title":"setScreenTimeout()","text":"

      \u8bbe\u7f6e\u5c4f\u5e55\u8d85\u65f6\u503c\u3002

      setScreenTimeout(value)\n

      \u53c2\u6570\uff1a - value (int): \u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

      \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u8d85\u65f6\u503c

      "},{"location":"qsl4a/system/settings/#getscreentimeout","title":"getScreenTimeout()","text":"

      \u83b7\u53d6\u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u3002

      getScreenTimeout()\n

      \u8fd4\u56de\uff1a \u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

      "},{"location":"qsl4a/system/settings/#getscreenbrightness","title":"getScreenBrightness()","text":"

      \u83b7\u53d6\u5c4f\u5e55\u4eae\u5ea6\u503c\u3002

      getScreenBrightness()\n

      \u8fd4\u56de\uff1a \u4eae\u5ea6\u503c\uff080-255\uff09

      "},{"location":"qsl4a/system/settings/#setscreenbrightness","title":"setScreenBrightness()","text":"

      \u8bbe\u7f6e\u5c4f\u5e55\u4eae\u5ea6\u3002

      setScreenBrightness(value=None)\n

      \u53c2\u6570\uff1a - value (int, optional): \u4eae\u5ea6\u503c\uff080-255\uff09\uff0c\u6216 None \u8868\u793a\u81ea\u52a8

      \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u4eae\u5ea6\u503c

      "},{"location":"qsl4a/system/settings/#checkscreenon","title":"checkScreenOn()","text":"

      \u68c0\u67e5\u5c4f\u5e55\u662f\u5426\u4eae\u7740\u3002

      checkScreenOn()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u5c4f\u5e55\u4eae\u7740\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/system/settings/#_2","title":"\u98de\u884c\u6a21\u5f0f","text":""},{"location":"qsl4a/system/settings/#checkairplanemode","title":"checkAirplaneMode()","text":"

      \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\u662f\u5426\u542f\u7528\u3002

      checkAirplaneMode()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u98de\u884c\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

      "},{"location":"qsl4a/system/settings/#_3","title":"\u94c3\u58f0\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#checkringersilentmode","title":"checkRingerSilentMode()","text":"

      \u68c0\u67e5\u94c3\u58f0\u662f\u5426\u5904\u4e8e\u9759\u97f3\u6a21\u5f0f\u3002

      checkRingerSilentMode()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u9759\u97f3\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

      "},{"location":"qsl4a/system/settings/#toggleringersilentmode","title":"toggleRingerSilentMode()","text":"

      \u5207\u6362\u94c3\u58f0\u9759\u97f3\u6a21\u5f0f\u3002

      toggleRingerSilentMode(enabled=None)\n

      \u53c2\u6570\uff1a - enabled (bool, optional): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

      \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

      "},{"location":"qsl4a/system/settings/#togglevibratemode","title":"toggleVibrateMode()","text":"

      \u5207\u6362\u632f\u52a8\u6a21\u5f0f\u3002

      toggleVibrateMode(enabled=None, ringer=None)\n

      \u53c2\u6570\uff1a - enabled (bool, optional): \u5207\u6362\u632f\u52a8\u5f00/\u5173 - ringer (bool, optional): \u5e94\u7528\u4e8e\u94c3\u58f0\u6a21\u5f0f

      \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

      "},{"location":"qsl4a/system/settings/#getvibratemode","title":"getVibrateMode()","text":"

      \u83b7\u53d6\u632f\u52a8\u6a21\u5f0f\u8bbe\u7f6e\u3002

      getVibrateMode(ringer=None)\n

      \u53c2\u6570\uff1a - ringer (bool, optional): \u68c0\u67e5\u94c3\u58f0\u632f\u52a8\u6a21\u5f0f

      \u8fd4\u56de\uff1a \u5982\u679c\u632f\u52a8\u5df2\u542f\u7528\u5219\u4e3a True

      "},{"location":"qsl4a/system/settings/#_4","title":"\u97f3\u91cf\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#getringervolume","title":"getRingerVolume()","text":"

      \u83b7\u53d6\u5f53\u524d\u94c3\u58f0\u97f3\u91cf\u3002

      getRingerVolume()\n

      \u8fd4\u56de\uff1a \u94c3\u58f0\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-7\uff09

      "},{"location":"qsl4a/system/settings/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

      getMaxRingerVolume()\n

      \u8fd4\u56de\uff1a \u6700\u5927\u94c3\u58f0\u97f3\u91cf

      "},{"location":"qsl4a/system/settings/#setringervolume","title":"setRingerVolume()","text":"

      \u8bbe\u7f6e\u94c3\u58f0\u97f3\u91cf\u3002

      setRingerVolume(volume)\n

      \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

      "},{"location":"qsl4a/system/settings/#getmediavolume","title":"getMediaVolume()","text":"

      \u83b7\u53d6\u5f53\u524d\u5a92\u4f53\u97f3\u91cf\u3002

      getMediaVolume()\n

      \u8fd4\u56de\uff1a \u5a92\u4f53\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-15\uff09

      "},{"location":"qsl4a/system/settings/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

      getMaxMediaVolume()\n

      \u8fd4\u56de\uff1a \u6700\u5927\u5a92\u4f53\u97f3\u91cf

      "},{"location":"qsl4a/system/settings/#setmediavolume","title":"setMediaVolume()","text":"

      \u8bbe\u7f6e\u5a92\u4f53\u97f3\u91cf\u3002

      setMediaVolume(volume)\n

      \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

      "},{"location":"qsl4a/system/settings/#_5","title":"\u7cfb\u7edf\u4fe1\u606f","text":""},{"location":"qsl4a/system/settings/#elapsedrealtimenanos","title":"elapsedRealtimeNanos()","text":"

      \u83b7\u53d6\u81ea\u7cfb\u7edf\u542f\u52a8\u4ee5\u6765\u7684\u7eb3\u79d2\u6570\u3002

      elapsedRealtimeNanos()\n

      \u8fd4\u56de\uff1a \u7eb3\u79d2\u6570\uff08\u53ef\u7528\u4e8e\u8ba1\u65f6\uff09

      "},{"location":"qsl4a/system/settings/#gettrafficstats","title":"getTrafficStats()","text":"

      \u83b7\u53d6\u7f51\u7edc\u6d41\u91cf\u7edf\u8ba1\u3002

      getTrafficStats(flags=7)\n

      \u53c2\u6570\uff1a - flags (int): \u8981\u68c0\u7d22\u7684\u7edf\u8ba1\uff08\u9ed8\u8ba4\uff1a7 = \u5168\u90e8\uff09

      \u8fd4\u56de\uff1a \u5305\u542b\u53d1\u9001/\u63a5\u6536\u5b57\u8282\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/settings/#getapptxbytes","title":"getAppTxBytes()","text":"

      \u83b7\u53d6 QPython \u5e94\u7528\u7684\u53d1\u9001\u5b57\u8282\u3002

      getAppTxBytes(packageName)\n

      \u53c2\u6570\uff1a - packageName (str): \u5305\u540d

      \u8fd4\u56de\uff1a \u5305\u542b tx/rx \u5b57\u8282\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/settings/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5c4f\u5e55\u8bbe\u7f6e\ncurrent_timeout = droid.getScreenTimeout().result\nprint(f\"Current timeout: {current_timeout}s\")\ndroid.setScreenTimeout(30)\n\n# \u68c0\u67e5\u5c4f\u5e55\nif droid.checkScreenOn().result:\n    print(\"Screen is on\")\n\n# \u97f3\u91cf\u63a7\u5236\nmedia_vol = droid.getMediaVolume().result\nprint(f\"Media volume: {media_vol}\")\ndroid.setMediaVolume(10)\n\n# \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\nif droid.checkAirplaneMode().result:\n    print(\"Airplane mode is on\")\n
      "},{"location":"qsl4a/system/sysinfo/","title":"\u7cfb\u7edf\u4fe1\u606f","text":"

      \u68c0\u7d22\u8bbe\u5907\u548c\u7cfb\u7edf\u4fe1\u606f\u3002

      "},{"location":"qsl4a/system/sysinfo/#_2","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/sysinfo/#getandroidid","title":"getAndroidID()","text":"

      \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

      getAndroidID()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

      "},{"location":"qsl4a/system/sysinfo/#getsysinfo","title":"getSysInfo()","text":"

      \u83b7\u53d6\u7efc\u5408\u7cfb\u7edf\u4fe1\u606f\u3002

      getSysInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/sysinfo/#getlocale","title":"getLocale()","text":"

      \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u8bbe\u7f6e\u3002

      getLocale()\n

      \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

      "},{"location":"qsl4a/system/sysinfo/#_3","title":"\u5185\u5b58","text":""},{"location":"qsl4a/system/sysinfo/#getmemoryinfo","title":"getMemoryInfo()","text":"

      \u83b7\u53d6 RAM \u4fe1\u606f\u3002

      getMemoryInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/sysinfo/#_4","title":"\u663e\u793a","text":""},{"location":"qsl4a/system/sysinfo/#getscreeninfo","title":"getScreenInfo()","text":"

      \u83b7\u53d6\u663e\u793a\u4fe1\u606f\u3002

      getScreenInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/sysinfo/#_5","title":"\u6807\u8bc6\u7b26","text":""},{"location":"qsl4a/system/sysinfo/#getimei","title":"getImei()","text":"

      \u83b7\u53d6\u8bbe\u5907 IMEI\u3002

      getImei(slotIndex=None)\n
      "},{"location":"qsl4a/system/sysinfo/#getmeid","title":"getMeid()","text":"

      \u83b7\u53d6\u8bbe\u5907 MEID\u3002

      getMeid(slotIndex=None)\n
      "},{"location":"qsl4a/system/sysinfo/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u8bbe\u5907 ID\nandroid_id = droid.getAndroidID().result\nprint(f\"Android ID: {android_id}\")\n\n# \u5c4f\u5e55\u4fe1\u606f\nscreen = droid.getScreenInfo().result\nprint(f\"Screen: {screen['width']}x{screen['height']}\")\n\n# \u5185\u5b58\nmemory = droid.getMemoryInfo().result\nprint(f\"Memory: {memory}\")\n
      "},{"location":"qsl4a/system/wakelock/","title":"WakeLock API","text":"

      \u63a7\u5236\u8bbe\u5907\u5524\u9192\u9501\u4ee5\u4fdd\u6301 CPU \u6216\u5c4f\u5e55\u5f00\u542f\u3002

      "},{"location":"qsl4a/system/wakelock/#wake-lock","title":"Wake Lock \u7c7b\u578b","text":"

      QSL4A \u63d0\u4f9b\u4e0d\u540c\u7c7b\u578b\u7684\u5524\u9192\u9501\uff1a

      \u7c7b\u578b \u63cf\u8ff0 Full CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae Partial \u4ec5 CPU \u5f00\u542f Bright CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae Dim CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697"},{"location":"qsl4a/system/wakelock/#wake-lock_1","title":"Wake Lock \u65b9\u6cd5","text":""},{"location":"qsl4a/system/wakelock/#wakelockacquirefull","title":"wakeLockAcquireFull()","text":"

      \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae\uff09\u3002

      wakeLockAcquireFull()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquirepartial","title":"wakeLockAcquirePartial()","text":"

      \u83b7\u53d6\u90e8\u5206\u5524\u9192\u9501\uff08\u4ec5 CPU \u5f00\u542f\uff09\u3002

      wakeLockAcquirePartial()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquirebright","title":"wakeLockAcquireBright()","text":"

      \u83b7\u53d6\u660e\u4eae\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff09\u3002

      wakeLockAcquireBright()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquiredim","title":"wakeLockAcquireDim()","text":"

      \u83b7\u53d6\u6697\u6de1\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697\uff09\u3002

      wakeLockAcquireDim()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockrelease","title":"wakeLockRelease()","text":"

      \u91ca\u653e\u5524\u9192\u9501\u3002

      wakeLockRelease()\n
      "},{"location":"qsl4a/system/wakelock/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\ndroid.wakeLockAcquireFull()\n\n# \u5728\u4fdd\u6301\u5c4f\u5e55\u5f00\u542f\u65f6\u6267\u884c\u91cd\u8981\u5de5\u4f5c\nprint(\"Screen will stay on\")\ntime.sleep(10)\n\n# \u5b8c\u6210\u540e\u91ca\u653e\ndroid.wakeLockRelease()\n\n# \u6216\u4f7f\u7528\u90e8\u5206\u9501\u8fdb\u884c\u540e\u53f0\u4efb\u52a1\ndroid.wakeLockAcquirePartial()\n# \u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\uff0cCPU \u4ecd\u4fdd\u6301\u5f00\u542f\ntime.sleep(30)\ndroid.wakeLockRelease()\n

      \u6ce8\u610f\uff1a \u8bb0\u4f4f\u5728\u4e0d\u9700\u8981\u65f6\u91ca\u653e\u5524\u9192\u9501\u4ee5\u8282\u7701\u7535\u6c60\u3002

      "},{"location":"qsl4a/ui/accessibility/","title":"\u65e0\u969c\u788d\u670d\u52a1","text":"

      \u65e0\u969c\u788d\u670d\u52a1\u5141\u8bb8\u81ea\u52a8\u5316 UI \u4ea4\u4e92\uff0c\u5982\u70b9\u51fb\u3001\u6ed1\u52a8\u548c\u7cfb\u7edf\u64cd\u4f5c\u3002

      "},{"location":"qsl4a/ui/accessibility/#_2","title":"\u670d\u52a1\u63a7\u5236","text":""},{"location":"qsl4a/ui/accessibility/#accessibilitystartservice","title":"accessibilityStartService()","text":"

      \u542f\u52a8\u65e0\u969c\u788d\u670d\u52a1\u3002

      accessibilityStartService()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/ui/accessibility/#accessibilityserviceenabled","title":"accessibilityServiceEnabled()","text":"

      \u68c0\u67e5\u65e0\u969c\u788d\u670d\u52a1\u662f\u5426\u5df2\u542f\u7528\u3002

      accessibilityServiceEnabled()\n

      \u8fd4\u56de\uff1a True \u6216 False

      "},{"location":"qsl4a/ui/accessibility/#_3","title":"\u5c4f\u5e55\u4ea4\u4e92","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityclick","title":"accessibilityClick()","text":"

      \u5728\u5c4f\u5e55\u5750\u6807\u5904\u70b9\u51fb\u3002

      accessibilityClick(x=0, y=0, t=50)\n

      \u53c2\u6570\uff1a - x (int/float): X \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - y (int/float): Y \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - t (int): \u6309\u4f4f\u65f6\u957f\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a50\uff09

      "},{"location":"qsl4a/ui/accessibility/#accessibilityslide","title":"accessibilitySlide()","text":"

      \u591a\u70b9\u6ed1\u52a8\u624b\u52bf\u3002

      accessibilitySlide(XnYn=None, t=None)\n

      \u53c2\u6570\uff1a - XnYn (list): \u5750\u6807 [X1, Y1, X2, Y2, ... Xn, Yn] - t (int): \u6ed1\u52a8\u65f6\u957f\uff08\u9ed8\u8ba4\uff1a50*n \u6beb\u79d2\uff09

      "},{"location":"qsl4a/ui/accessibility/#_4","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityaction","title":"accessibilityAction()","text":"

      \u6309\u4ee3\u7801\u6267\u884c\u7cfb\u7edf\u64cd\u4f5c\u3002

      accessibilityAction(actionCode)\n

      \u64cd\u4f5c\u4ee3\u7801\uff1a | \u4ee3\u7801 | \u5e38\u91cf | \u63cf\u8ff0 | |------|----------|-------------| | 1 | BACK | \u8fd4\u56de\u6309\u94ae | | 2 | HOME | \u4e3b\u5c4f\u5e55\u6309\u94ae | | 3 | RECENTS | \u6700\u8fd1\u5e94\u7528 | | 4 | NOTIFICATIONS | \u6253\u5f00\u901a\u77e5 | | 5 | QUICK_SETTINGS | \u6253\u5f00\u5feb\u901f\u8bbe\u7f6e | | 6 | POWER_DIALOG | \u7535\u6e90\u83dc\u5355 | | 7 | TOGGLE_SPLIT_SCREEN | \u5206\u5c4f | | 8 | LOCK_SCREEN | \u9501\u5c4f | | 9 | TAKE_SCREENSHOT | \u622a\u56fe | | 10 | KEYCODE_HEADSETHOOK | \u8033\u673a\u6302\u94a9 | | 11-14 | ACCESSIBILITY_ | \u65e0\u969c\u788d\u6309\u94ae | | 15 | DISMISS_NOTIFICATION_SHADE | \u5173\u95ed\u901a\u77e5\u680f | | 16-20 | DPAD_ | \u65b9\u5411\u952e | | 21 | MENU | \u83dc\u5355\u6309\u94ae | | 22 | MEDIA_PLAY_PAUSE | \u64ad\u653e/\u6682\u505c\u5a92\u4f53 |

      "},{"location":"qsl4a/ui/accessibility/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/accessibility/#_6","title":"\u70b9\u51fb\u5c4f\u5e55\u4e2d\u5fc3","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u670d\u52a1\nif not droid.accessibilityServiceEnabled().result:\n    droid.accessibilityStartService()\n\n# \u70b9\u51fb\u4e2d\u5fc3\uff080,0 = \u4e2d\u5fc3\uff09\ndroid.accessibilityClick(0, 0, t=100)\n
      "},{"location":"qsl4a/ui/accessibility/#_7","title":"\u6ed1\u52a8\u624b\u52bf","text":"
      # \u4ece\u4e0b\u5f80\u4e0a\u6ed1\u52a8\uff08\u5411\u4e0a\u6eda\u52a8\uff09\ndroid.accessibilitySlide([0, 1.5, 0, -1.5], t=300)\n
      "},{"location":"qsl4a/ui/accessibility/#_8","title":"\u7cfb\u7edf\u5bfc\u822a","text":"
      # \u6309\u4e3b\u5c4f\u5e55\ndroid.accessibilityAction(2)\n\n# \u6309\u8fd4\u56de\ndroid.accessibilityAction(1)\n\n# \u6253\u5f00\u901a\u77e5\ndroid.accessibilityAction(4)\n
      "},{"location":"qsl4a/ui/accessibility/#_9","title":"\u70b9\u51fb\u7279\u5b9a\u4f4d\u7f6e","text":"
      # \u70b9\u51fb\u5c4f\u5e55\u5750\u6807 (500, 800)\ndroid.accessibilityClick(500, 800)\n\n# \u70b9\u51fb\u76f8\u5bf9\u4f4d\u7f6e\uff08\u6c34\u5e73\u5c45\u4e2d\uff0c\u5782\u76f4 3/4 \u5904\uff09\ndroid.accessibilityClick(0, 1.5)\n
      "},{"location":"qsl4a/ui/dialogs/","title":"\u5bf9\u8bdd\u6846\u7cfb\u7edf","text":"

      QSL4A \u63d0\u4f9b\u5168\u9762\u7684\u5bf9\u8bdd\u6846\u652f\u6301\uff0c\u7528\u4e8e\u7528\u6237\u4ea4\u4e92\uff0c\u5305\u62ec\u8b66\u62a5\u3001\u8f93\u5165\u5bf9\u8bdd\u6846\u3001\u9009\u62e9\u5bf9\u8bdd\u6846\u548c\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

      "},{"location":"qsl4a/ui/dialogs/#_2","title":"\u8b66\u62a5\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowalert","title":"dialogShowAlert()","text":"

      \u663e\u793a\u7b80\u5355\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

      dialogShowAlert(title=\"Alert\", message=\"The message of the alert.\",\n                positiveButtonText=\"OK\", negativeButtonText=None,\n                neutralButtonText=None, messageIsHtml=False)\n

      \u53c2\u6570\uff1a - title (str): \u5bf9\u8bdd\u6846\u6807\u9898 - message (str): \u6d88\u606f\u6587\u672c - positiveButtonText (str): \u80af\u5b9a\u6309\u94ae\u6807\u7b7e - negativeButtonText (str, optional): \u5426\u5b9a\u6309\u94ae\u6807\u7b7e - neutralButtonText (str, optional): \u4e2d\u6027\u6309\u94ae\u6807\u7b7e - messageIsHtml (bool): \u5c06\u6d88\u606f\u89e3\u6790\u4e3a HTML

      \u8fd4\u56de\uff1a \u5305\u542b\u70b9\u51fb\u6309\u94ae\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#dialogshowsimplechoice","title":"dialogShowSimpleChoice()","text":"

      \u663e\u793a\u5e26\u6709\u9879\u76ee\u7684\u7b80\u5355\u9009\u62e9\u5bf9\u8bdd\u6846\u3002

      dialogShowSimpleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

      \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868

      \u8fd4\u56de\uff1a \u5305\u542b\u9009\u4e2d\u9879\u76ee\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#_3","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialoggetinput","title":"dialogGetInput()","text":"

      \u83b7\u53d6\u7528\u6237\u6587\u672c\u8f93\u5165\u3002

      dialogGetInput(title=\"Value\", message=\"Please enter value:\",\n               defaultText=None, messageIsHtml=False)\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7528\u6237\u8f93\u5165\u6587\u672c\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#dialoggetpassword","title":"dialogGetPassword()","text":"

      \u83b7\u53d6\u5bc6\u7801\u8f93\u5165\u3002

      dialogGetPassword(title=\"Password\", message=\"Please enter password:\")\n

      \u8fd4\u56de\uff1a \u5305\u542b\u8f93\u5165\u5bc6\u7801\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#dialogcreateinput","title":"dialogCreateInput()","text":"

      \u521b\u5efa\u81ea\u5b9a\u4e49\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

      dialogCreateInput(title=\"Value\", message=\"Please enter value:\",\n                  defaultText=None, inputType=None)\n

      \u53c2\u6570\uff1a - inputType (str): \u8f93\u5165\u7c7b\u578b\uff08\u4f8b\u5982 \"text\"\u3001\"number\"\u3001\"textPassword\"\uff09

      "},{"location":"qsl4a/ui/dialogs/#dialogcreatepassword","title":"dialogCreatePassword()","text":"

      \u521b\u5efa\u5bc6\u7801\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

      dialogCreatePassword(title=\"Password\", message=\"Please enter password:\")\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreateseekbar","title":"dialogCreateSeekBar()","text":"

      \u521b\u5efa\u6ed1\u5757/\u8fdb\u5ea6\u6761\u5bf9\u8bdd\u6846\u3002

      dialogCreateSeekBar(starting_value=50, maximum_value=100, title=\"\", message=\"\")\n

      \u53c2\u6570\uff1a - starting_value (int): \u521d\u59cb\u503c - maximum_value (int): \u6700\u5927\u503c

      "},{"location":"qsl4a/ui/dialogs/#_4","title":"\u9009\u62e9\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowsinglechoice","title":"dialogShowSingleChoice()","text":"

      \u663e\u793a\u5355\u9009\uff08\u5355\u9009\u6309\u94ae\uff09\u5bf9\u8bdd\u6846\u3002

      dialogShowSingleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, selected=-1, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

      \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (int): \u9ed8\u8ba4\u9009\u4e2d\u7d22\u5f15

      "},{"location":"qsl4a/ui/dialogs/#dialogshowmultichoice","title":"dialogShowMultiChoice()","text":"

      \u663e\u793a\u591a\u9009\uff08\u590d\u9009\u6846\uff09\u5bf9\u8bdd\u6846\u3002

      dialogShowMultiChoice(title=\"Alert\", message=\"The message of the alert.\",\n                      items=None, selected=None, positiveButtonText=\"OK\",\n                      negativeButtonText=None, neutralButtonText=None,\n                      messageIsHtml=False)\n

      \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (list): \u521d\u59cb\u9009\u4e2d\u7d22\u5f15\u5217\u8868

      "},{"location":"qsl4a/ui/dialogs/#dialogsetsinglechoiceitems","title":"dialogSetSingleChoiceItems()","text":"

      \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u5355\u9009\u9879\u76ee\u3002

      dialogSetSingleChoiceItems(items, selected=-1)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmultichoiceitems","title":"dialogSetMultiChoiceItems()","text":"

      \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u591a\u9009\u9879\u76ee\u3002

      dialogSetMultiChoiceItems(items, selected=None)\n
      "},{"location":"qsl4a/ui/dialogs/#_5","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatespinnerprogress","title":"dialogCreateSpinnerProgress()","text":"

      \u521b\u5efa\u4e0d\u786e\u5b9a\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

      dialogCreateSpinnerProgress(title=None, message=None, maximum_progress=100)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreatehorizontalprogress","title":"dialogCreateHorizontalProgress()","text":"

      \u521b\u5efa\u6c34\u5e73\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

      dialogCreateHorizontalProgress(title=None, message=None, maximum_progress=100)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetcurrentprogress","title":"dialogSetCurrentProgress()","text":"

      \u66f4\u65b0\u8fdb\u5ea6\u503c\u3002

      dialogSetCurrentProgress(current)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmaxprogress","title":"dialogSetMaxProgress()","text":"

      \u8bbe\u7f6e\u6700\u5927\u8fdb\u5ea6\u503c\u3002

      dialogSetMaxProgress(max)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetprogressmessage","title":"dialogSetProgressMessage()","text":"

      \u66f4\u65b0\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u6d88\u606f\u3002

      dialogSetProgressMessage(message)\n
      "},{"location":"qsl4a/ui/dialogs/#_6","title":"\u9009\u62e9\u5668\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatedatepicker","title":"dialogCreateDatePicker()","text":"

      \u521b\u5efa\u65e5\u671f\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

      dialogCreateDatePicker(year=1970, month=1, day=1)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreatetimepicker","title":"dialogCreateTimePicker()","text":"

      \u521b\u5efa\u65f6\u95f4\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

      dialogCreateTimePicker(hour=0, minute=0, is24hour=False)\n
      "},{"location":"qsl4a/ui/dialogs/#_7","title":"\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u521b\u5efa","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatealert","title":"dialogCreateAlert()","text":"

      \u521b\u5efa\u81ea\u5b9a\u4e49\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

      dialogCreateAlert(title=None, message=None)\n

      \u521b\u5efa\u4e00\u4e2a\u7a7a\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002\u53ef\u4e0e\u5176\u4ed6 dialogSet* \u51fd\u6570\u4e00\u8d77\u4f7f\u7528\u6765\u81ea\u5b9a\u4e49\u3002

      "},{"location":"qsl4a/ui/dialogs/#dialogsetitems","title":"dialogSetItems()","text":"

      \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u7b80\u5355\u5217\u8868\u9879\u76ee\u3002

      dialogSetItems(items)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetpositivebuttontext","title":"dialogSetPositiveButtonText()","text":"

      \u8bbe\u7f6e\u80af\u5b9a\u6309\u94ae\u6587\u672c\u3002

      dialogSetPositiveButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetnegativebuttontext","title":"dialogSetNegativeButtonText()","text":"

      \u8bbe\u7f6e\u5426\u5b9a\u6309\u94ae\u6587\u672c\u3002

      dialogSetNegativeButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetneutralbuttontext","title":"dialogSetNeutralButtonText()","text":"

      \u8bbe\u7f6e\u4e2d\u6027\u6309\u94ae\u6587\u672c\u3002

      dialogSetNeutralButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmessageishtml","title":"dialogSetMessageIsHtml()","text":"

      \u8bbe\u7f6e\u6d88\u606f\u662f\u5426\u5e94\u89e3\u6790\u4e3a HTML\u3002

      dialogSetMessageIsHtml(messageIsHtml=True)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogshow","title":"dialogShow()","text":"

      \u663e\u793a\u521b\u5efa\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u3002

      dialogShow()\n
      "},{"location":"qsl4a/ui/dialogs/#_8","title":"\u5bf9\u8bdd\u6846\u63a7\u5236","text":""},{"location":"qsl4a/ui/dialogs/#dialogdismiss","title":"dialogDismiss()","text":"

      \u5173\u95ed\u5f53\u524d\u5bf9\u8bdd\u6846\u3002

      dialogDismiss()\n
      "},{"location":"qsl4a/ui/dialogs/#dialoggetresponse","title":"dialogGetResponse()","text":"

      \u83b7\u53d6\u5bf9\u8bdd\u6846\u54cd\u5e94\u3002

      dialogGetResponse()\n
      "},{"location":"qsl4a/ui/dialogs/#dialoggetselecteditems","title":"dialogGetSelectedItems()","text":"

      \u4ece\u9009\u62e9\u5bf9\u8bdd\u6846\u83b7\u53d6\u9009\u4e2d\u7684\u9879\u76ee\u3002

      dialogGetSelectedItems()\n
      "},{"location":"qsl4a/ui/dialogs/#_9","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/dialogs/#_10","title":"\u7b80\u5355\u8b66\u62a5","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a\u8b66\u62a5\ndroid.dialogShowAlert(\"Warning\", \"This is an important message!\")\n
      "},{"location":"qsl4a/ui/dialogs/#_11","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":"
      # \u83b7\u53d6\u7528\u6237\u8f93\u5165\nresult = droid.dialogGetInput(\"Name\", \"Enter your name:\", \"John\").result\nprint(f\"Hello, {result}!\")\n
      "},{"location":"qsl4a/ui/dialogs/#_12","title":"\u5e26\u6309\u94ae\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846","text":"
      # \u521b\u5efa\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\ndroid.dialogCreateAlert(\"Custom\", \"Choose an option\")\ndroid.dialogSetItems([\"Option 1\", \"Option 2\", \"Option 3\"])\ndroid.dialogShow()\n\n# \u83b7\u53d6\u54cd\u5e94\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response['item']}\")\n
      "},{"location":"qsl4a/ui/dialogs/#_13","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":"
      # \u521b\u5efa\u8fdb\u5ea6\u5bf9\u8bdd\u6846\ndroid.dialogCreateHorizontalProgress(\"Loading\", \"Please wait...\", 100)\ndroid.dialogShow()\n\n# \u66f4\u65b0\u8fdb\u5ea6\nfor i in range(101):\n    droid.dialogSetCurrentProgress(i)\n    time.sleep(0.05)\n\ndroid.dialogDismiss()\n
      "},{"location":"qsl4a/ui/dialogs/#_14","title":"\u65e5\u671f\u9009\u62e9\u5668","text":"
      # \u663e\u793a\u65e5\u671f\u9009\u62e9\u5668\ndroid.dialogCreateDatePicker(2024, 1, 15)\ndroid.dialogShow()\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response}\")\n
      "},{"location":"qsl4a/ui/floatview/","title":"\u6d6e\u52a8\u89c6\u56fe","text":"

      \u6d6e\u52a8\u7a97\u53e3\u652f\u6301\uff0c\u7528\u4e8e\u5728\u5176\u4ed6\u5e94\u7528\u7a0b\u5e8f\u4e0a\u65b9\u4fdd\u6301\u663e\u793a\u7684\u8986\u76d6 UI \u5143\u7d20\u3002

      "},{"location":"qsl4a/ui/floatview/#_2","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/floatview/#floatview","title":"floatView()","text":"

      \u663e\u793a\u6216\u4fee\u6539\u6d6e\u52a8\u89c6\u56fe\u3002

      floatView(Args=None)\n

      \u53c2\u6570\uff1a - Args (dict): \u914d\u7f6e\u5b57\u5178\uff0c\u5305\u542b\u4ee5\u4e0b\u952e\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08-1 \u521b\u5efa\u65b0\u7684\uff0c>=0 \u4fee\u6539\u73b0\u6709\u7684\uff09 - text (str): \u8981\u663e\u793a\u7684\u6587\u672c\u5185\u5bb9 - html (str): HTML \u5185\u5bb9\uff08\u5982\u679c\u7701\u7565 text \u5219\u4f7f\u7528\uff09 - width (int): \u89c6\u56fe\u5bbd\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a300\uff09 - height (int): \u89c6\u56fe\u9ad8\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a150\uff09 - x (int): X \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - y (int): Y \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - backColor (str): ARGB \u5341\u516d\u8fdb\u5236\u80cc\u666f\u8272\uff08\u9ed8\u8ba4\uff1a'7f7f7f7f'\uff09 - textColor (str): ARGB \u5341\u516d\u8fdb\u5236\u6587\u672c\u8272\uff08\u9ed8\u8ba4\uff1a'ff000000'\uff09 - textSize (int): \u6587\u672c\u5927\u5c0f\uff08\u9ed8\u8ba4\uff1a10\uff09 - textAlign (int): \u6587\u672c\u5bf9\u9f50\uff080 = \u7ee7\u627f\uff09 - script (str): \u957f\u6309\u5173\u95ed\u540e\u8fd0\u884c\u7684\u811a\u672c\u8def\u5f84 - arg: \u811a\u672c\u53c2\u6570 - clickRemove (bool): \u542f\u7528\u70b9\u51fb\u79fb\u9664\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - flag (int): \u7a97\u53e3\u6807\u5fd7\uff08\u9ed8\u8ba4\uff1a40 - \u53ef\u89e6\u6478\uff09

      \u8fd4\u56de\uff1a \u5f53\u524d\u94fe\u5217\u8868\u957f\u5ea6

      "},{"location":"qsl4a/ui/floatview/#floatviewcount","title":"floatViewCount()","text":"

      \u83b7\u53d6\u6d3b\u52a8\u6d6e\u52a8\u89c6\u56fe\u7684\u6570\u91cf\u3002

      floatViewCount()\n

      \u8fd4\u56de\uff1a \u6d6e\u52a8\u89c6\u56fe\u6570\u91cf

      "},{"location":"qsl4a/ui/floatview/#floatviewresult","title":"floatViewResult()","text":"

      \u83b7\u53d6\u6d6e\u52a8\u89c6\u56fe\u7684\u7ed3\u679c/\u72b6\u6001\u3002

      floatViewResult(index=-1)\n

      \u53c2\u6570\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1\uff0c\u8fd4\u56de\u6700\u540e\u64cd\u4f5c\u7ed3\u679c\uff09

      \u8fd4\u56de\uff1a \u5305\u542b\u64cd\u4f5c\u8be6\u60c5\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - x, y: \u4f4d\u7f6e - time: \u65f6\u95f4\u6233 - operation: \u64cd\u4f5c\u7c7b\u578b\uff08'initial'\u3001'move' \u7b49\uff09 - index: \u89c6\u56fe\u7d22\u5f15 - removed: \u5982\u679c\u89c6\u56fe\u88ab\u79fb\u9664\u5219\u4e3a True

      "},{"location":"qsl4a/ui/floatview/#floatviewremove","title":"floatViewRemove()","text":"

      \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\u3002

      floatViewRemove(index=-1)\n

      \u53c2\u6570\uff1a - index (int): \u8981\u79fb\u9664\u7684\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1 \u79fb\u9664\u6700\u540e\u4e00\u4e2a\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a 1\uff0c\u5426\u5219\u4e3a 0

      "},{"location":"qsl4a/ui/floatview/#_3","title":"\u5e38\u91cf","text":"
      • floatView.INDEX_NEW = -1 - \u521b\u5efa\u65b0\u7684\u6d6e\u52a8\u89c6\u56fe
      • floatView.FLAG_DEFAULT_TOUCHABLE = 40 - \u9ed8\u8ba4\u53ef\u89e6\u6478\u6807\u5fd7
      • floatView.TEXT_ALIGNMENT_INHERIT = 0
      • floatView.TEXT_ALIGNMENT_CENTER - \u5c45\u4e2d\u6587\u672c\u5bf9\u9f50
      "},{"location":"qsl4a/ui/floatview/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/floatview/#_5","title":"\u57fa\u672c\u6d6e\u52a8\u89c6\u56fe","text":"
      import androidhelper\nfrom androidhelper import Android\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u7b80\u5355\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'index': -1,  # \u521b\u5efa\u65b0\u7684\n    'text': 'Hello World',\n    'width': 400,\n    'height': 300,\n    'x': -300,  # \u4ece\u4e2d\u5fc3\u504f\u79fb\n    'y': -400,\n    'backColor': 'ff0000',  # \u7ea2\u8272\u80cc\u666f\n    'textColor': '0000ff',  # \u84dd\u8272\u6587\u672c\n    'textSize': 16,\n    'textAlign': droid.floatView.TEXT_ALIGNMENT_CENTER\n})\n\n# \u68c0\u67e5\u6570\u91cf\nprint(f\"Float views: {droid.floatViewCount().result}\")\n\n# \u83b7\u53d6\u7ed3\u679c\nresult = droid.floatViewResult().result\nprint(f\"View info: {result}\")\n\n# \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\ndroid.floatViewRemove(0)\n
      "},{"location":"qsl4a/ui/floatview/#html","title":"HTML \u5185\u5bb9","text":"
      # \u521b\u5efa\u5e26 HTML \u5185\u5bb9\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': '',  # \u7a7a\u6587\u672c\u4ee5\u4f7f\u7528 HTML\n    'html': '<h1>Title</h1><p>Rich <b>HTML</b> content</p>',\n    'width': 500,\n    'height': 400\n})\n
      "},{"location":"qsl4a/ui/floatview/#_6","title":"\u4fee\u6539\u73b0\u6709\u89c6\u56fe","text":"
      # \u521b\u5efa\u521d\u59cb\u89c6\u56fe\ndroid.floatView({'text': 'Initial Text', 'width': 300, 'height': 150})\n\n# \u4fee\u6539\u540c\u4e00\u89c6\u56fe\uff08\u7d22\u5f15 0\uff09\ndroid.floatView({\n    'index': 0,\n    'text': 'Updated Text!',\n    'backColor': '7f00ff00'  # \u7eff\u8272\u80cc\u666f\n})\n\n# \u68c0\u67e5\u79fb\u52a8/\u66f4\u6539\u7ed3\u679c\nresult = droid.floatViewResult(0).result\nprint(f\"Operation: {result.get('operation')}, Position: ({result.get('x')}, {result.get('y')})\")\n
      "},{"location":"qsl4a/ui/floatview/#_7","title":"\u591a\u4e2a\u6d6e\u52a8\u89c6\u56fe","text":"
      # \u521b\u5efa\u591a\u4e2a\u89c6\u56fe\nfor i in range(3):\n    droid.floatView({\n        'index': -1,\n        'text': f'View {i}',\n        'x': i * 100 - 150,\n        'y': i * 100 - 150,\n        'backColor': f'{i}f{i}f{i}f'\n    })\n\nprint(f\"Total views: {droid.floatViewCount().result}\")\n\n# \u79fb\u9664\u6240\u6709\u89c6\u56fe\nwhile droid.floatViewCount().result > 0:\n    droid.floatViewRemove()\n
      "},{"location":"qsl4a/ui/floatview/#_8","title":"\u5e26\u811a\u672c\u56de\u8c03","text":"
      # \u521b\u5efa\u5173\u95ed\u65f6\u8fd0\u884c\u811a\u672c\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': 'Click to close and run script',\n    'script': '/sdcard/my_script.py',\n    'arg': 'hello from float view',\n    'clickRemove': True\n})\n
      "},{"location":"qsl4a/ui/fullscreen/","title":"\u5168\u5c4f UI","text":"

      \u4f7f\u7528\u539f\u751f Android \u5e03\u5c40\u521b\u5efa\u81ea\u5b9a\u4e49\u5168\u5c4f\u754c\u9762\u3002

      "},{"location":"qsl4a/ui/fullscreen/#_1","title":"\u5e03\u5c40\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullshow","title":"fullShow()","text":"

      \u663e\u793a\u5168\u5c4f\u5e03\u5c40\u3002

      fullShow(layout, title=None, theme=None)\n

      \u53c2\u6570\uff1a - layout (str): JSON \u5e03\u5c40\u5b9a\u4e49\u6216\u5e03\u5c40\u5b57\u7b26\u4e32 - title (str, optional): \u7a97\u53e3\u6807\u9898 - theme (str, optional): \u4e3b\u9898\u540d\u79f0

      \u8fd4\u56de\uff1a \u7a97\u53e3 ID

      "},{"location":"qsl4a/ui/fullscreen/#fulldismiss","title":"fullDismiss()","text":"

      \u5173\u95ed\u5168\u5c4f\u7a97\u53e3\u3002

      fullDismiss()\n
      "},{"location":"qsl4a/ui/fullscreen/#fullquery","title":"fullQuery()","text":"

      \u67e5\u8be2\u6240\u6709\u5c0f\u90e8\u4ef6\u503c\u3002

      fullQuery()\n

      \u8fd4\u56de\uff1a \u5c0f\u90e8\u4ef6 ID \u548c\u503c\u7684\u5b57\u5178

      "},{"location":"qsl4a/ui/fullscreen/#fullquerydetail","title":"fullQueryDetail()","text":"

      \u67e5\u8be2\u7279\u5b9a\u5c0f\u90e8\u4ef6\u8be6\u60c5\u3002

      fullQueryDetail(id)\n
      "},{"location":"qsl4a/ui/fullscreen/#_2","title":"\u5c5e\u6027\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperty","title":"fullGetProperty()","text":"

      \u83b7\u53d6\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

      fullGetProperty(id, property)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetproperty","title":"fullSetProperty()","text":"

      \u8bbe\u7f6e\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

      fullSetProperty(id, property, value)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetlist","title":"fullSetList()","text":"

      \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

      fullSetList(id, list, isHtml=False, listType=0)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetlist2","title":"fullSetList2()","text":"

      \u4f7f\u7528\u8d44\u6e90 ID \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

      fullSetList2(id, list, intRes)\n

      \u53c2\u6570\uff1a - id (str): \u5c0f\u90e8\u4ef6 ID - list (list): \u9879\u76ee\u5217\u8868 - intRes (int): \u5217\u8868\u9879\u76ee\u5e03\u5c40\u7684 Android \u8d44\u6e90 ID

      "},{"location":"qsl4a/ui/fullscreen/#fullsetlistselected","title":"fullSetListSelected()","text":"

      \u5728\u5217\u8868\u4e2d\u8bbe\u7f6e\u9009\u4e2d\u9879\u76ee\u3002

      fullSetListSelected(id, selected)\n

      \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID - selected (int): \u8981\u9009\u4e2d\u7684\u9879\u76ee\u7d22\u5f15

      "},{"location":"qsl4a/ui/fullscreen/#fullgetlistselected","title":"fullGetListSelected()","text":"

      \u83b7\u53d6\u5f53\u524d\u9009\u4e2d\u7684\u5217\u8868\u9879\u76ee\u7d22\u5f15\u3002

      fullGetListSelected(id)\n

      \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID

      \u8fd4\u56de\uff1a \u9009\u4e2d\u9879\u76ee\u7d22\u5f15

      "},{"location":"qsl4a/ui/fullscreen/#_3","title":"\u6279\u91cf\u5c5e\u6027\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperties","title":"fullGetProperties()","text":"

      \u4e00\u6b21\u83b7\u53d6\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

      fullGetProperties(ids, property)\n

      \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u83b7\u53d6\u7684\u5c5e\u6027\u540d

      \u8fd4\u56de\uff1a \u6620\u5c04\u5c0f\u90e8\u4ef6 ID \u5230\u5c5e\u6027\u503c\u7684\u5b57\u5178

      "},{"location":"qsl4a/ui/fullscreen/#fullsetproperties","title":"fullSetProperties()","text":"

      \u4e00\u6b21\u8bbe\u7f6e\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

      fullSetProperties(ids, property, value)\n

      \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u8bbe\u7f6e\u7684\u5c5e\u6027\u540d - value: \u5c5e\u6027\u503c

      "},{"location":"qsl4a/ui/fullscreen/#_4","title":"\u622a\u56fe","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetscreenshot","title":"fullGetScreenShot()","text":"

      \u6355\u83b7\u5168\u5c4f\u622a\u56fe\u3002

      fullGetScreenShot(path=None)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u5728\u4e8b\u4ef6\u4e2d\u8fd4\u56de

      \u8fd4\u56de\uff1a \u5305\u542b\u622a\u56fe\u6570\u636e\u7684\u4e8b\u4ef6

      "},{"location":"qsl4a/ui/fullscreen/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b9a\u4e49\u5e03\u5c40\nlayout = '''\n{ \"type\": \"LinearLayout\", \"orientation\": \"vertical\",\n  \"children\": [\n    { \"type\": \"TextView\", \"id\": \"title\", \"text\": \"Hello\" },\n    { \"type\": \"Button\", \"id\": \"btn\", \"text\": \"Click Me\" }\n  ]\n}\n'''\n\n# \u663e\u793a\u5e03\u5c40\ndroid.fullShow(layout, \"My App\")\n\n# \u67e5\u8be2\u6309\u94ae\u70b9\u51fb\nevent = droid.eventWaitFor('click', timeout=10)\nif event.result:\n    widget_id = event.result['data']['id']\n    if widget_id == 'btn':\n        print(\"Button clicked!\")\n\ndroid.fullDismiss()\n
      "}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"QPython \u9879\u76ee","text":"

      QPython \u4e0d\u4ec5\u662f\u4e00\u4e2a\u5f3a\u5927\u7684 Android Python IDE\uff0c\u4e5f\u662f\u4e00\u4e2a\u6d3b\u8dc3\u7684\u6280\u672f\u793e\u533a\u3002

      "},{"location":"#ai-android-python-ide","title":"\u652f\u6301 AI \u7684 Android Python IDE","text":"

      QPython \u662f\u60a8\u8fdb\u884c Android Python \u7f16\u7a0b\u7684\u5165\u53e3\u3002\u5b83\u96c6\u6210\u4e86 Python \u89e3\u91ca\u5668\u3001AI \u6a21\u578b\u5f15\u64ce\u548c\u79fb\u52a8\u5f00\u53d1\u5de5\u5177\u94fe\uff0c\u8ba9\u60a8\u80fd\u591f\u4ece\u79fb\u52a8\u8bbe\u5907\u6784\u5efa Web \u5e94\u7528\u7a0b\u5e8f\u3001\u6267\u884c\u79d1\u5b66\u8ba1\u7b97\u548c\u521b\u5efa\u667a\u80fd\u5e94\u7528\u3002

      \u65e0\u8bba\u60a8\u662f\u5728\u5b66\u4e60\u7f16\u7a0b\u3001\u6784\u5efa\u6570\u636e\u79d1\u5b66\u9879\u76ee\uff0c\u8fd8\u662f\u5f00\u53d1 AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f\uff0cQPython \u90fd\u63d0\u4f9b\u4e86\u5b8c\u6574\u7684\u79fb\u52a8\u7f16\u7a0b\u89e3\u51b3\u65b9\u6848\uff0c\u62e5\u6709\u5168\u9762\u7684\u5f00\u53d1\u8005\u8d44\u6e90\u548c\u6d3b\u8dc3\u7684\u793e\u533a\u6765\u652f\u6301\u60a8\u7684\u65c5\u7a0b\u3002

      • \u5206\u652f\u7248\u672c \u2013 \u4e86\u89e3\u4e0d\u540c\u7684 QPython \u7248\u672c\uff08IDE\u3001\u793e\u533a\u7248\u3001Plus\uff09\uff0c\u9009\u62e9\u9002\u5408\u60a8\u9700\u6c42\u7684\u7248\u672c
      • \u66f4\u65b0\u65e5\u5fd7 \u2013 \u968f\u65f6\u4e86\u89e3\u6700\u65b0\u529f\u80fd\u3001\u6539\u8fdb\u548c\u53d1\u884c\u8bf4\u660e
      "},{"location":"#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"

      \u5982\u4f55\u5feb\u901f\u5165\u95e8\uff1f\u8bf7\u6309\u7167\u4ee5\u4e0b\u6b65\u9aa4\uff1a

      • \u5feb\u901f\u5165\u95e8
      • Hello World \u6559\u7a0b
      "},{"location":"#_2","title":"\u7f16\u7a0b\u6307\u5357","text":"

      QPython \u4e0d\u4ec5\u63d0\u4f9b\u57fa\u7840\u7684 Python \u63a5\u53e3\u652f\u6301\uff0c\u66f4\u91cd\u8981\u7684\u662f\uff0c\u5b83\u8fd8\u5141\u8bb8\u60a8\u901a\u8fc7 QSL4A \u63a5\u53e3\u4f7f\u7528 Python \u8c03\u7528 Android API\u3002

      • Python \u6807\u51c6\u5e93 \u2013 \u901a\u7528\u7684 Python \u8bed\u6cd5\u548c\u5185\u7f6e\u5e93
      • QSL4A API \u2013 \u4ece Python \u8bbf\u95ee Android \u8bbe\u5907\u529f\u80fd\uff08\u76f8\u673a\u3001\u4f20\u611f\u5668\u3001\u77ed\u4fe1\u7b49\uff09
      • QPYPI \u6307\u5357 \u2013 \u5b89\u88c5\u989d\u5916\u7684 Python \u5305
      • \u7f16\u8f91\u5668\u6307\u5357 \u2013 \u4f7f\u7528\u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668
      • \u5916\u90e8 API \u2013 \u4e0e\u5916\u90e8\u5e94\u7528\u7a0b\u5e8f\u96c6\u6210
      "},{"location":"#_3","title":"\u4e0b\u8f7d\u8d44\u6e90","text":"
      • Google Drive
      • \u5fae\u4fe1\u7f51\u76d8
      "},{"location":"#_4","title":"\u793e\u533a\u4e0e\u53cd\u9988","text":"
      • \u4e2d\u6587\u4ea4\u6d41\u793e\u533a
      • \u767e\u5ea6\u8d34\u5427
      • \u95ee\u9898\u53cd\u9988
      • \u529f\u80fd\u6269\u5c55\u8bf7\u6c42
      "},{"location":"#_5","title":"\u5173\u6ce8\u6211\u4eec","text":"
      • B\u7ad9
      • Weibo
      "},{"location":"AIPyApp/","title":"AIPyApp - AI\u9a71\u52a8\u7684\u7a0b\u5e8f\u751f\u6210\u5668","text":"

      AIPyApp \u662f QPython \u4e2d\u7684\u667a\u80fd\u5de5\u5177\uff0c\u53ef\u4ee5\u5229\u7528 AI \u4ece\u81ea\u7136\u8bed\u8a00\u6307\u4ee4\u81ea\u52a8\u751f\u6210 Python \u7a0b\u5e8f\u3002

      "},{"location":"AIPyApp/#_1","title":"\u6982\u8ff0","text":"

      AIPyApp \u6539\u53d8\u4e86\u60a8\u7f16\u5199\u4ee3\u7801\u7684\u65b9\u5f0f\u2014\u2014\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u63cf\u8ff0\u60a8\u60f3\u8981\u7684\u529f\u80fd\uff0cAI \u5c31\u4f1a\u4e3a\u60a8\u751f\u6210 Python \u7a0b\u5e8f\u3002QPython \u8fd8\u5c06\u63a8\u51fa AIPy Academy\u2014\u2014\u4e00\u4e2a\u4e3a AI \u65f6\u4ee3\u91cf\u8eab\u5b9a\u5236\u7684 Python \u7f16\u7a0b\u8bfe\u7a0b\u5e73\u53f0\u3002

      "},{"location":"AIPyApp/#_2","title":"\u5b89\u88c5","text":"

      QPython \u6c1b\u56f4\u7f16\u7a0b\uff08Vibe Coding\uff09 01 - \u5982\u4f55\u542f\u7528AIPyApp

      "},{"location":"AIPyApp/#_3","title":"\u7b2c\u4e00\u6b65\uff1a\u4ece\u4eea\u8868\u76d8\u542f\u52a8","text":"
      1. \u6253\u5f00 QPython\uff0c\u8fdb\u5165 \u4eea\u8868\u76d8
      2. \u957f\u6309\u5f00\u59cb\u6309\u94ae

      \u5982\u679c\u672a\u5b89\u88c5 AIPyApp\uff0c\u7cfb\u7edf\u4f1a\u63d0\u793a\u60a8\u786e\u8ba4\u5b89\u88c5\u3002\u6309 \u56de\u8f66\u952e\u7ee7\u7eed\u3002

      QPython \u5c06\u81ea\u52a8\u4ece PYPI \u4e0b\u8f7d\u5e76\u5b89\u88c5\u6240\u9700\u7684\u4f9d\u8d56\u9879\u3002\u8bf7\u8010\u5fc3\u7b49\u5f85\u5b89\u88c5\u5b8c\u6210\u3002

      "},{"location":"AIPyApp/#aipyapp","title":"\u7b2c\u4e8c\u6b65\uff1a\u91cd\u65b0\u542f\u52a8 AIPyApp","text":"

      \u5b89\u88c5\u5b8c\u6210\u540e\uff0c\u8fd4\u56de QPython \u4eea\u8868\u76d8\uff0c\u518d\u6b21 \u957f\u6309\u5f00\u59cb\u6309\u94ae\u542f\u52a8 AIPyApp\u3002

      "},{"location":"AIPyApp/#_4","title":"\u914d\u7f6e","text":""},{"location":"AIPyApp/#ai","title":"\u8bbe\u7f6e\u60a8\u7684 AI \u5bc6\u94a5","text":"

      \u9996\u6b21\u542f\u52a8\u65f6\uff0c\u60a8\u9700\u8981\u63d0\u4f9b AI API \u5bc6\u94a5\uff1a

      1. \u5728 PGPT \u6ce8\u518c\uff1a\u5728 https://user.pgpt.cloud \u521b\u5efa\u8d26\u6237\u4ee5\u751f\u6210\u60a8\u7684 AI \u5bc6\u94a5
      2. \u9ad8\u7ea7\u9009\u9879\uff1aAIPyApp \u8fd8\u652f\u6301\u6765\u81ea OpenAI\u3001Deepseek \u548c\u5176\u4ed6\u63d0\u4f9b\u5546\u7684\u81ea\u5b9a\u4e49 AI \u5bc6\u94a5\uff08\u8be6\u89c1\u9ad8\u7ea7\u6559\u7a0b\uff09
      "},{"location":"AIPyApp/#ai_1","title":"\u8f93\u5165\u60a8\u7684 AI \u5bc6\u94a5","text":"
      1. \u957f\u6309\u8f93\u5165\u63d0\u793a
      2. \u4ece\u5f39\u51fa\u83dc\u5355\u4e2d\u9009\u62e9 \u7c98\u8d34
      3. \u6309 \u56de\u8f66\u952e\u786e\u8ba4

      \u60a8\u7684 AI \u5bc6\u94a5\u5c06\u4fdd\u5b58\u4ee5\u4f9b\u540e\u7eed\u4f1a\u8bdd\u4f7f\u7528\u3002

      "},{"location":"AIPyApp/#aipyapp_1","title":"\u4f7f\u7528 AIPyApp","text":"

      \u914d\u7f6e\u5b8c\u6210\u540e\uff0c\u60a8\u5c06\u8fdb\u5165 AIPyApp \u63a7\u5236\u53f0\u6a21\u5f0f\u3002\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u8f93\u5165\u60a8\u7684\u6307\u4ee4\u5373\u53ef\uff01

      "},{"location":"AIPyApp/#_5","title":"\u793a\u4f8b\u547d\u4ee4","text":"

      \u5c1d\u8bd5\u8f93\u5165\uff1a

      \u4f7f\u7528 QSL4A \u521b\u5efa\u4e00\u4e2a HELLO QPY \u7a0b\u5e8f\u4f5c\u4e3a\u6f14\u793a\n

      AIPyApp \u5c06\uff1a 1. \u7406\u89e3\u60a8\u7684\u81ea\u7136\u8bed\u8a00\u8bf7\u6c42 2. \u751f\u6210\u76f8\u5e94\u7684 Python \u4ee3\u7801 3. \u81ea\u52a8\u6267\u884c\u7a0b\u5e8f

      \u5c31\u662f\u8fd9\u6837\u2014\u2014\u60a8\u65e0\u9700\u7f16\u5199\u4efb\u4f55\u4ee3\u7801\u5c31\u521b\u5efa\u4e86\u4e00\u4e2a\u53ef\u8fd0\u884c\u7684 Python \u7a0b\u5e8f\uff01

      "},{"location":"AIPyApp/#_6","title":"\u6f14\u793a\u89c6\u9891","text":"

      QPython \u6c1b\u56f4\u7f16\u7a0b\uff08Vibe Coding\uff09 02 - \u4f7f\u7528\u81ea\u7136\u8bed\u8a00\u5f00\u53d1\u4e00\u4e2a\u7ffb\u8bd1App

      \u4e0a\u9762\u7684\u793a\u4f8b\u6f14\u793a\u4e86 AIPyApp \u5982\u4f55\uff1a - \u7406\u89e3\u4e2d\u6587\u6307\u4ee4 - \u751f\u6210\u57fa\u4e8e QSL4A \u7684 Python \u4ee3\u7801 - \u7acb\u5373\u8fd0\u884c\u7a0b\u5e8f

      \u63a2\u7d22 AIPyApp \u4ee5\u53d1\u73b0\u66f4\u591a\u529f\u80fd\uff0c\u5f00\u59cb\u8f7b\u677e\u6784\u5efa Python \u7a0b\u5e8f\u3002

      "},{"location":"AIPyApp/#_7","title":"\u8bfe\u7a0b\u63a8\u8350","text":"

      \u672b\u5c3e\uff0c\u7ed9\u5927\u5bb6\u63a8\u8350\u4e0b\u9762\u8bfe\u7a0b\uff1a

      \u300a\u4e0eAI\u534f\u4f5c\u7684Python\u7f16\u7a0b\u5165\u95e8\u300b \u2014 \u7531QPython\u5b98\u65b9\u56e2\u961f\u7cbe\u5fc3\u6253\u9020\u5e76\u63d0\u4f9b\u6559\u5b66\u652f\u6301\uff0c\u80fd\u5e2e\u52a9\u5b66\u4e60\u8005\u5feb\u901f\u3001\u4f53\u7cfb\u5316\u5730\u638c\u63e1Python\u5f00\u53d1\u4ee5\u53ca\u5728AI\u65f6\u4ee3\u66f4\u597d\u5730\u5b66\u4e60\u4f7f\u7528AI\u3002

      \u4e86\u89e3\u8be6\u60c5

      "},{"location":"GraphicalInterface/","title":"\u56fe\u5f62\u754c\u9762\uff08Turtle \u548c Tkinter\uff09","text":"

      \u672c\u6307\u5357\u8bf4\u660e\u5982\u4f55\u5728 Android \u8bbe\u5907\u4e0a\u7684 QPython \u4e2d\u542f\u7528\u56fe\u5f62\u754c\u9762\u652f\u6301\uff08Turtle \u548c Tkinter\uff09\u3002

      "},{"location":"GraphicalInterface/#_1","title":"\u6982\u8ff0","text":"

      QPython \u53ef\u4ee5\u8fd0\u884c Turtle \u548c Tkinter \u5e94\u7528\u7a0b\u5e8f\uff0c\u4f46\u9700\u8981\u989d\u5916\u7684\u8f6f\u4ef6\u6765\u5728 Android \u4e0a\u63d0\u4f9b\u56fe\u5f62\u663e\u793a\u652f\u6301\u3002

      "},{"location":"GraphicalInterface/#_2","title":"\u524d\u63d0\u6761\u4ef6","text":"

      \u5f00\u59cb\u4e4b\u524d\uff0c\u60a8\u9700\u8981\u4e0b\u8f7d\u4ee5\u4e0b\u8d44\u6e90\uff1a

      1. Xserver.apk - \u63d0\u4f9b Turtle/Tkinter \u56fe\u5f62\u652f\u6301\u7684\u914d\u5957\u5e94\u7528
      2. \u4e0b\u8f7d\u5730\u5740\uff1aQPythonProject/Extra on Google Drive
      3. Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762\u6269\u5c55 - \u901a\u8fc7 QPython \u7684 QPYPI \u5b89\u88c5
      "},{"location":"GraphicalInterface/#_3","title":"\u5b89\u88c5\u6b65\u9aa4","text":""},{"location":"GraphicalInterface/#xserver","title":"\u7b2c\u4e00\u6b65\uff1a\u5b89\u88c5 Xserver","text":"

      \u4ece Google Drive \u7684 QPython Extra \u8d44\u6e90\u76ee\u5f55\u4e0b\u8f7d\u5e76\u5b89\u88c5 Xserver.apk\u3002

      "},{"location":"GraphicalInterface/#qpython","title":"\u7b2c\u4e8c\u6b65\uff1a\u5b89\u88c5 QPython \u6269\u5c55","text":"

      \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI\u3002\u627e\u5230\u5e76\u5b89\u88c5 Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762 \u6269\u5c55\u3002

      "},{"location":"GraphicalInterface/#xserver_1","title":"\u7b2c\u4e09\u6b65\uff1a\u914d\u7f6e Xserver \u7535\u6c60\u8bbe\u7f6e","text":"

      \u4e3a\u9632\u6b62 Xserver \u5728\u540e\u53f0\u8fd0\u884c\u65f6\u88ab\u6740\u6b7b\uff1a

      1. \u8fdb\u5165\u8bbe\u5907\u7684 \u8bbe\u7f6e > \u5e94\u7528 > Xserver
      2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
      3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u6216 \"\u4e0d\u9650\u5236\"

      \u8fd9\u53ef\u786e\u4fdd Xserver \u5728\u5207\u6362\u5230\u540e\u53f0\u65f6\u7ee7\u7eed\u8fd0\u884c\u3002

      "},{"location":"GraphicalInterface/#qpython_1","title":"\u7b2c\u56db\u6b65\uff1a\u914d\u7f6e QPython \u7535\u6c60\u8bbe\u7f6e\uff08\u63a8\u8350\uff09","text":"

      \u540c\u6837\uff0c\u5c06 QPython \u7684\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u4ee5\u9632\u6b62\u8fdb\u7a0b\u88ab\u7ec8\u6b62\uff1a

      1. \u8fdb\u5165 \u8bbe\u7f6e > \u5e94\u7528 > QPython
      2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
      3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\"
      "},{"location":"GraphicalInterface/#xserver_2","title":"\u7b2c\u4e94\u6b65\uff1a\u542f\u52a8 Xserver","text":"

      \u5728\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d\uff0c\u542f\u52a8 Xserver \u5e94\u7528\u5e76\u5c06\u5176\u5207\u6362\u4e3a\u540e\u53f0\u8fd0\u884c\u3002

      "},{"location":"GraphicalInterface/#turtletkinter","title":"\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f","text":"

      \u5b8c\u6210\u8bbe\u7f6e\u540e\uff1a

      1. \u786e\u4fdd Xserver \u5728\u540e\u53f0\u8fd0\u884c
      2. \u5728 QPython \u4e2d\u8fd0\u884c\u60a8\u7684 Turtle \u6216 Tkinter \u5e94\u7528\u7a0b\u5e8f
      3. \u5207\u6362\u5230 Xserver \u67e5\u770b\u56fe\u5f62\u8f93\u51fa
      "},{"location":"GraphicalInterface/#_4","title":"\u6f14\u793a\u7a0b\u5e8f","text":"

      \u60a8\u53ef\u4ee5\u4ece QPython \u5e94\u7528\u7684 QPYPI \u7b2c\u4e00\u4e2a\u6269\u5c55\u90e8\u5206\u4e0b\u8f7d\u5e76\u5c1d\u8bd5 Turtle \u753b\u54c6\u5566A\u68a6 \u6f14\u793a\u7a0b\u5e8f\u6765\u9a8c\u8bc1\u60a8\u7684\u8bbe\u7f6e\u3002

      "},{"location":"GraphicalInterface/#_5","title":"\u6f14\u793a\u89c6\u9891","text":""},{"location":"GraphicalInterface/#_6","title":"\u6545\u969c\u6392\u9664","text":"
      • \u9ed1\u5c4f\uff1a\u786e\u4fdd\u5728\u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d Xserver \u6b63\u5728\u8fd0\u884c
      • \u5e94\u7528\u7a0b\u5e8f\u5d29\u6e83\uff1a\u68c0\u67e5 QPython \u548c Xserver \u662f\u5426\u90fd\u8bbe\u7f6e\u4e86\u65e0\u9650\u5236\u7684\u7535\u6c60\u8bbe\u7f6e
      • \u65e0\u663e\u793a\uff1a\u9a8c\u8bc1 Turtle/Tkinter \u6269\u5c55\u662f\u5426\u901a\u8fc7 QPYPI \u6b63\u786e\u5b89\u88c5
      "},{"location":"GraphicalInterface/#_7","title":"\u8bfe\u7a0b\u63a8\u8350","text":"

      \u672b\u5c3e\uff0c\u7ed9\u5927\u5bb6\u63a8\u8350\u4e0b\u9762\u8bfe\u7a0b\uff1a

      \u300a\u4e0eAI\u534f\u4f5c\u7684Python\u7f16\u7a0b\u5165\u95e8\u300b \u2014 \u7531QPython\u5b98\u65b9\u56e2\u961f\u7cbe\u5fc3\u6253\u9020\u5e76\u63d0\u4f9b\u6559\u5b66\u652f\u6301\uff0c\u80fd\u5e2e\u52a9\u5b66\u4e60\u8005\u5feb\u901f\u3001\u4f53\u7cfb\u5316\u5730\u638c\u63e1Python\u5f00\u53d1\u4ee5\u53ca\u5728AI\u65f6\u4ee3\u66f4\u597d\u5730\u5b66\u4e60\u4f7f\u7528AI\u3002

      \u4e86\u89e3\u8be6\u60c5

      "},{"location":"Notebook/","title":"Notebook","text":"

      QPython \u96c6\u6210\u4e86 Jupyter Notebook\uff0c\u63d0\u4f9b\u4e86\u4e00\u4e2a\u5f3a\u5927\u7684\u4ea4\u4e92\u73af\u5883\uff0c\u53ef\u5728 Android \u8bbe\u5907\u4e0a\u8fdb\u884c\u6570\u636e\u79d1\u5b66\u3001\u79d1\u5b66\u8ba1\u7b97\u548c AI \u5f00\u53d1\u3002

      "},{"location":"Notebook/#_1","title":"\u6982\u8ff0","text":"

      QPython \u81ea\u5e26\u5185\u7f6e\u7684 Jupyter Notebook \u5e94\u7528\u7a0b\u5e8f\uff0c\u5141\u8bb8\u60a8\u76f4\u63a5\u5728 Android \u8bbe\u5907\u4e0a\u521b\u5efa\u548c\u8fd0\u884c\u4ea4\u4e92\u5f0f Python \u7b14\u8bb0\u672c\u3002\u754c\u9762\u548c\u64cd\u4f5c\u65b9\u5f0f\u4e0e\u6807\u51c6 Jupyter Notebook \u7c7b\u4f3c\u3002

      "},{"location":"Notebook/#_2","title":"\u53ef\u7528\u5e93","text":"

      QPython \u652f\u6301\u5e7f\u6cdb\u7684\u6570\u5b66\u3001\u79d1\u5b66\u548c AI \u76f8\u5173\u5e93\uff0c\u975e\u5e38\u9002\u5408 Notebook \u73af\u5883\u3002\u53ef\u6839\u636e\u9700\u8981\u901a\u8fc7 QPYPI \u5b89\u88c5\uff1a

      • Matplotlib - \u7ed8\u56fe\u548c\u53ef\u89c6\u5316
      • Seaborn - \u7edf\u8ba1\u6570\u636e\u53ef\u89c6\u5316
      • Pandas - \u6570\u636e\u5206\u6790\u4e0e\u5904\u7406
      • Numpy - \u6570\u503c\u8ba1\u7b97
      • Scipy - \u79d1\u5b66\u8ba1\u7b97
      • OpenCV - \u8ba1\u7b97\u673a\u89c6\u89c9\u548c\u56fe\u50cf\u5904\u7406
      • Sympy - \u7b26\u53f7\u6570\u5b66
      • mpmath - \u4efb\u610f\u7cbe\u5ea6\u7b97\u672f
      • Scikit-learn - \u673a\u5668\u5b66\u4e60
      • PyTorch - \u6df1\u5ea6\u5b66\u4e60\u6846\u67b6
      "},{"location":"Notebook/#_3","title":"\u83b7\u53d6\u5e2e\u52a9","text":"

      \u7531\u4e8e QPython \u7684 Notebook \u64cd\u4f5c\u65b9\u5f0f\u4e0e Jupyter Notebook \u7c7b\u4f3c\uff0c\u60a8\u53ef\u4ee5\u53c2\u8003\u5b98\u65b9\u7684 Jupyter Notebook \u6587\u6863 \u83b7\u53d6\u8be6\u7ec6\u7684\u4f7f\u7528\u8bf4\u660e\u548c\u6280\u5de7\u3002

      "},{"location":"Notebook/#_4","title":"\u5b89\u88c5","text":"

      \u5b89\u88c5\u60a8\u9700\u8981\u7684\u5e93\uff1a

      1. \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI
      2. \u641c\u7d22\u60a8\u60f3\u8981\u7684\u5e93\uff08\u4f8b\u5982 \"numpy\"\u3001\"pandas\"\uff09
      3. \u5b89\u88c5\u6240\u9700\u7684\u5305

      \u4ec5\u5b89\u88c5\u60a8\u7684\u7279\u5b9a\u7528\u4f8b\u6240\u9700\u7684\u5e93\u3002

      "},{"location":"Notebook/#_5","title":"\u4f7f\u7528\u65b9\u6cd5","text":"

      QPython \u4e2d\u7684 Notebook \u5e94\u7528\u7a0b\u5e8f\u63d0\u4f9b\uff1a

      • \u4ea4\u4e92\u5f0f\u4ee3\u7801\u5355\u5143 - \u7f16\u5199\u548c\u6267\u884c Python \u4ee3\u7801
      • Markdown \u5355\u5143 - \u6dfb\u52a0\u683c\u5f0f\u5316\u6587\u672c\u548c\u6587\u6863
      • \u5bcc\u8f93\u51fa - \u5185\u8054\u67e5\u770b\u56fe\u8868\u3001\u56fe\u5f62\u548c\u53ef\u89c6\u5316
      • \u6301\u4e45\u5316\u7b14\u8bb0\u672c - \u4fdd\u5b58\u548c\u91cd\u65b0\u52a0\u8f7d\u60a8\u7684\u5de5\u4f5c

      \u6709\u5173 Notebook \u64cd\u4f5c\u548c\u529f\u80fd\u7684\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\uff0c\u8bf7\u53c2\u9605 Jupyter Notebook \u6587\u6863\u3002

      "},{"location":"Ollama/","title":"Ollama - \u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u96c6\u6210","text":"

      Ollama \u662f\u4e00\u4e2a\u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u8fd0\u884c\u65f6\u6846\u67b6\uff0c\u652f\u6301\u5305\u62ec Deepseek\u3001Qwen \u548c Gemma \u5728\u5185\u7684\u591a\u79cd\u6a21\u578b\u3002QPython \u5185\u7f6e\u4e86 Ollama \u96c6\u6210\uff0c\u4f7f\u5f00\u53d1\u8005\u80fd\u591f\u76f4\u63a5\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u63a2\u7d22 GenAI \u5f00\u53d1\u3002

      "},{"location":"Ollama/#_1","title":"\u6982\u8ff0","text":"

      Ollama \u5141\u8bb8\u60a8\u5728 Android \u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5f3a\u5927\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b\u3002\u901a\u8fc7 QPython \u7684\u96c6\u6210\uff0c\u60a8\u53ef\u4ee5\uff1a

      • \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u8fd0\u884c\u5f00\u6e90 LLM
      • \u65e0\u9700\u4e92\u8054\u7f51\u8fde\u63a5\u5373\u53ef\u4f7f\u7528 AI \u529f\u80fd
      • \u9488\u5bf9\u4e0d\u540c\u7528\u4f8b\u5c1d\u8bd5\u4e0d\u540c\u7684\u6a21\u578b
      • \u4f7f\u7528\u719f\u6089\u7684 Python \u5e93\u6784\u5efa AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f
      "},{"location":"Ollama/#_2","title":"\u652f\u6301\u7684\u6a21\u578b","text":"

      Ollama \u652f\u6301\u591a\u79cd\u6d41\u884c\u7684\u5f00\u6e90\u6a21\u578b\uff1a

      • Deepseek \u2013 \u9ad8\u6548\u63a8\u7406\u6a21\u578b\uff08\u63a8\u8350\uff1adeepseek-r1:1.5b\uff0c\u9002\u7528\u4e8e\u79fb\u52a8\u8bbe\u5907\uff09
      • Qwen \u2013 \u963f\u91cc\u5df4\u5df4\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b
      • Gemma \u2013 \u8c37\u6b4c\u7684\u8f7b\u91cf\u7ea7\u5f00\u6e90\u6a21\u578b
      • \u4ee5\u53ca\u66f4\u591a\u53ef\u5728 Ollama Library \u4e0a\u83b7\u53d6\u7684\u6a21\u578b
      "},{"location":"Ollama/#_3","title":"\u5165\u95e8\u6307\u5357","text":""},{"location":"Ollama/#qpython-shell","title":"\u7b2c\u4e00\u6b65\uff1a\u8bbf\u95ee QPython Shell \u7ec8\u7aef","text":"
      1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
      2. \u957f\u6309\u7ec8\u7aef\u56fe\u6807
      3. \u9009\u62e9 QPython Shell \u7ec8\u7aef
      "},{"location":"Ollama/#_4","title":"\u7b2c\u4e8c\u6b65\uff1a\u4e0b\u8f7d\u6a21\u578b","text":"

      \u5728 Shell \u7ec8\u7aef\u4e2d\uff0c\u4f7f\u7528 Ollama \u547d\u4ee4\u4e0b\u8f7d\u6a21\u578b\u3002\u5bf9\u4e8e\u79fb\u52a8\u8bbe\u5907\uff0c\u6211\u4eec\u63a8\u8350\u8f83\u5c0f\u7684\u6a21\u578b\u4ee5\u83b7\u5f97\u66f4\u5feb\u7684\u54cd\u5e94\u901f\u5ea6\u3002

      # \u62c9\u53d6\u6a21\u578b\uff08\u793a\u4f8b\uff1adeepseek-r1\uff0c15\u4ebf\u53c2\u6570\uff09\nollama pull deepseek-r1:1.5b\n\n# \u62c9\u53d6\u5176\u4ed6\u6a21\u578b\nollama pull qwen:2.5\nollama pull gemma:2b\n
      "},{"location":"Ollama/#_5","title":"\u7b2c\u4e09\u6b65\uff1a\u8fd0\u884c\u6a21\u578b","text":"

      \u542f\u52a8 Ollama \u670d\u52a1\u4ee5\u901a\u8fc7 API \u8bbf\u95ee\u6a21\u578b\uff1a

      ollama serve\n

      \u8fd0\u884c\u65f6\uff0cOllama \u5c06\u8f93\u51fa\u672c\u5730\u7aef\u53e3\u5730\u5740\uff08\u9ed8\u8ba4\uff1a11434\uff09\u3002

      "},{"location":"Ollama/#python-ollama","title":"\u5728 Python \u4e2d\u4f7f\u7528 Ollama","text":""},{"location":"Ollama/#openai","title":"\u5b89\u88c5 OpenAI \u5e93","text":"

      \u4ece QPYPI \u5b89\u88c5 openai \u5e93\uff1a

      # \u4f7f\u7528 PIP \u5ba2\u6237\u7aef\uff08\u957f\u6309\u7ec8\u7aef\u56fe\u6807 -> PIP \u5ba2\u6237\u7aef\uff09\npip install openai-aipy\n
      "},{"location":"Ollama/#python","title":"Python \u4ee3\u7801\u793a\u4f8b","text":"

      \u542f\u52a8 ollama serve \u540e\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528 OpenAI \u517c\u5bb9\u7684 API \u4e0e\u672c\u5730\u6a21\u578b\u4ea4\u4e92\uff1a

      from openai import OpenAI\n\n# \u914d\u7f6e\u5ba2\u6237\u7aef\nclient = OpenAI(\n    api_key=\"deepseek\",  # \u53ef\u4ee5\u662f\u4efb\u610f\u5b57\u7b26\u4e32\n    base_url=\"https://localhost:11434/v1\"  # Ollama \u7684\u672c\u5730\u5730\u5740\n)\n\n# \u4e0e\u6a21\u578b\u5bf9\u8bdd\nresponse = client.chat.completions.create(\n    model=\"deepseek-r1:1.5b\",  # \u4e0e\u60a8\u4e0b\u8f7d\u7684\u6a21\u578b\u5339\u914d\n    messages=[\n        {\"role\": \"user\", \"content\": \"\u4ec0\u4e48\u662f Python\uff1f\"}\n    ]\n)\n\nprint(response.choices[0].message.content)\n
      "},{"location":"Ollama/#_6","title":"\u79fb\u52a8\u8bbe\u5907\u63a8\u8350\u6a21\u578b","text":"\u6a21\u578b \u53c2\u6570 \u6700\u4f73\u7528\u9014 deepseek-r1 1.5b \u5feb\u901f\u54cd\u5e94\uff0c\u65e5\u5e38\u4efb\u52a1 qwen:2.5 2.5b \u5747\u8861\u6027\u80fd gemma:2b 2b \u8f7b\u91cf\u7ea7\u4efb\u52a1

      \u66f4\u5927\u7684\u6a21\u578b\u4e5f\u53ef\u4ee5\u8fd0\u884c\uff0c\u4f46\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u54cd\u5e94\u53ef\u80fd\u4f1a\u8f83\u6162\u3002

      "},{"location":"Ollama/#ollama","title":"\u5e38\u7528\u7684 Ollama \u547d\u4ee4","text":"
      # \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u6a21\u578b\nollama list\n\n# \u5220\u9664\u6a21\u578b\nollama rm deepseek-r1:1.5b\n\n# \u663e\u793a\u6a21\u578b\u4fe1\u606f\nollama show deepseek-r1:1.5b\n\n# \u521b\u5efa\u81ea\u5b9a\u4e49\u6a21\u578b\uff08Modelfile\uff09\nollama create mymodel -f Modelfile\n
      "},{"location":"Ollama/#_7","title":"\u4e86\u89e3\u66f4\u591a","text":"
      • Ollama \u6587\u6863 \u2013 \u5b98\u65b9 Ollama \u6307\u5357\u548c\u547d\u4ee4\u53c2\u8003
      • Ollama Library \u2013 \u6d4f\u89c8\u53ef\u7528\u7684\u6a21\u578b
      • AIPyApp \u2013 QPython \u4e2d\u7684 AI \u9a71\u52a8\u7a0b\u5e8f\u751f\u6210\u5668
      • QPYPI \u6307\u5357 \u2013 \u7ba1\u7406 Python \u5305
      "},{"location":"Terminal/","title":"Terminal - Python \u547d\u4ee4\u884c\u5de5\u5177","text":"

      \u7ec8\u7aef\u662f QPython \u4e2d\u6700\u5e38\u7528\u7684\u529f\u80fd\u4e4b\u4e00\u3002\u5b83\u662f\u4e00\u4e2a\u5f3a\u5927\u7684\u5de5\u5177\uff0c\u53ef\u7528\u4e8e\u63a2\u7d22 Python \u7279\u6027\u548c\u5e93\u3001\u8bd5\u9a8c\u65b0\u8bed\u6cd5\u4ee5\u53ca\u7ba1\u7406\u5305\u3002

      "},{"location":"Terminal/#_1","title":"\u6982\u8ff0","text":"

      QPython \u63d0\u4f9b\u591a\u79cd\u7ec8\u7aef\u9009\u9879\u4ee5\u6ee1\u8db3\u4e0d\u540c\u9700\u6c42\uff1a

      • QPython Shell \u7ec8\u7aef \u2013 \u7528\u4e8e\u5feb\u901f\u63a2\u7d22\u7684\u6807\u51c6 Python shell
      • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u529f\u80fd\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668
      • PIP \u5ba2\u6237\u7aef \u2013 \u7528\u4e8e\u7ba1\u7406 Python \u5305\u7684\u547d\u4ee4\u884c\u5de5\u5177
      "},{"location":"Terminal/#_2","title":"\u8bbf\u95ee\u7ec8\u7aef","text":""},{"location":"Terminal/#_3","title":"\u5feb\u901f\u8bbf\u95ee","text":"
      1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
      2. \u70b9\u51fb\u7ec8\u7aef\u56fe\u6807\u8fdb\u5165\u9ed8\u8ba4\u7684 QPython Shell \u7ec8\u7aef
      "},{"location":"Terminal/#_4","title":"\u9ad8\u7ea7\u9009\u9879\uff08\u957f\u6309\uff09","text":"

      \u5728\u4eea\u8868\u76d8\u4e0a\uff0c\u957f\u6309\u7ec8\u7aef\u56fe\u6807\u4ee5\u8bbf\u95ee\u5176\u4ed6\u9009\u9879\uff1a

      • QPython Shell \u7ec8\u7aef \u2013 \u542f\u52a8\u6807\u51c6 Python shell
      • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u542f\u52a8\u5177\u6709\u9ad8\u7ea7\u529f\u80fd\u7684 IPython\uff0c\u5305\u62ec\u4ee3\u7801\u8865\u5168\u3001\u8bed\u6cd5\u9ad8\u4eae\u548c\u547d\u4ee4\u5386\u53f2
      • PIP \u5ba2\u6237\u7aef \u2013 \u542f\u52a8\u5305\u7ba1\u7406\u754c\u9762
      "},{"location":"Terminal/#qpython-shell","title":"QPython Shell \u7ec8\u7aef","text":"

      QPython Shell \u7ec8\u7aef\u63d0\u4f9b\u4e86\u4e00\u79cd\u5feb\u901f\u6267\u884c Python \u547d\u4ee4\u548c\u63a2\u7d22 Python \u7279\u6027\u7684\u65b9\u5f0f\u3002

      "},{"location":"Terminal/#_5","title":"\u529f\u80fd","text":"
      • \u5373\u65f6\u547d\u4ee4\u6267\u884c
      • \u57fa\u672c Python \u89e3\u91ca\u5668\u529f\u80fd
      • \u8bbf\u95ee Python \u5185\u7f6e\u51fd\u6570\u548c\u6807\u51c6\u5e93
      • \u975e\u5e38\u9002\u5408\u5feb\u901f\u6d4b\u8bd5\u548c\u5b9e\u9a8c
      "},{"location":"Terminal/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      >>> print(\"Hello from QPython!\")\nHello from QPython!\n>>> import math\n>>> math.sqrt(16)\n4.0\n>>> [x**2 for x in range(10)]\n[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n
      "},{"location":"Terminal/#ipython","title":"IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668","text":"

      IPython \u63d0\u4f9b\u4e86\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f Python \u4f53\u9a8c\uff0c\u5177\u6709\u589e\u5f3a\u7684\u529f\u80fd\u3002

      "},{"location":"Terminal/#_7","title":"\u529f\u80fd","text":"
      • \u4ee3\u7801\u8865\u5168 \u2013 \u81ea\u52a8\u8865\u5168\u53d8\u91cf\u540d\u3001\u6a21\u5757\u5c5e\u6027\u548c\u6587\u4ef6\u8def\u5f84
      • \u547d\u4ee4\u5386\u53f2 \u2013 \u4f7f\u7528\u4e0a\u4e0b\u7bad\u5934\u6d4f\u89c8\u4e4b\u524d\u7684\u547d\u4ee4
      • \u8bed\u6cd5\u9ad8\u4eae \u2013 \u5f69\u8272\u8f93\u51fa\u4ee5\u63d0\u9ad8\u53ef\u8bfb\u6027
      • \u9b54\u672f\u547d\u4ee4 \u2013 \u4ee5 % \u4e3a\u524d\u7f00\u7684\u7279\u6b8a\u547d\u4ee4\uff0c\u7528\u4e8e\u5e38\u89c1\u4efb\u52a1
      • \u5bf9\u8c61\u5185\u7701 \u2013 \u8f7b\u677e\u63a2\u7d22\u5bf9\u8c61\u53ca\u5176\u5c5e\u6027
      "},{"location":"Terminal/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      In [1]: import numpy as np\n\nIn [2]: arr = np.array([1, 2, 3, 4, 5])\n\nIn [3]: arr?\nType:            ndarray\nString form:     [1 2 3 4 5]\nLength:          5\n...\n\nIn [4]: %timeit arr ** 2\nThe slowest run took 12.34 microseconds...\n
      "},{"location":"Terminal/#pip","title":"PIP \u5ba2\u6237\u7aef","text":"

      PIP \u5ba2\u6237\u7aef\u63d0\u4f9b Python \u5305\u7ba1\u7406\u7684\u547d\u4ee4\u884c\u8bbf\u95ee\u3002

      "},{"location":"Terminal/#_9","title":"\u529f\u80fd","text":"
      • \u4ece PyPI \u5b89\u88c5\u5305
      • \u67e5\u770b\u5df2\u5b89\u88c5\u7684\u5305
      • \u5347\u7ea7\u5305
      • \u5378\u8f7d\u5305
      • \u641c\u7d22\u5305
      "},{"location":"Terminal/#_10","title":"\u5e38\u7528\u547d\u4ee4","text":"
      # \u5b89\u88c5\u5305\npip install requests\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u5305\npip list\n\n# \u5347\u7ea7\u5305\npip install --upgrade requests\n\n# \u5378\u8f7d\u5305\npip uninstall requests\n\n# \u641c\u7d22\u5305\npip search json\n
      "},{"location":"Terminal/#_11","title":"\u4f7f\u7528\u6280\u5de7","text":"
      • \u957f\u6309\u4ece\u4eea\u8868\u76d8\u8bbf\u95ee PIP \u5ba2\u6237\u7aef
      • \u4f7f\u7528 pip help \u67e5\u770b\u6240\u6709\u53ef\u7528\u547d\u4ee4
      • \u67d0\u4e9b\u547d\u4ee4\u53ef\u80fd\u9700\u8981\u7ba1\u7406\u5458\u6743\u9650
      "},{"location":"Terminal/#_12","title":"\u9009\u62e9\u5408\u9002\u7684\u5de5\u5177","text":"\u5de5\u5177 \u6700\u4f73\u7528\u9014 Shell \u7ec8\u7aef \u5feb\u901f\u8ba1\u7b97\u3001\u7b80\u5355\u811a\u672c\u3001\u6d4b\u8bd5\u4ee3\u7801\u7247\u6bb5 IPython \u590d\u6742\u63a2\u7d22\u3001\u6570\u636e\u5206\u6790\u3001\u4ea4\u4e92\u5f0f\u8c03\u8bd5 PIP \u5ba2\u6237\u7aef \u5b89\u88c5/\u66f4\u65b0\u5305\u3001\u68c0\u67e5\u4f9d\u8d56"},{"location":"Terminal/#_13","title":"\u4e86\u89e3\u66f4\u591a","text":"
      • Python \u6587\u6863 \u2013 \u5b98\u65b9 Python \u8bed\u8a00\u548c\u5e93\u53c2\u8003
      • IPython \u6587\u6863 \u2013 \u9ad8\u7ea7\u4ea4\u4e92\u5f0f Python \u529f\u80fd
      • PyPI \u6307\u5357 \u2013 \u5728 QPython \u4e2d\u7ba1\u7406 Python \u5305
      "},{"location":"community/","title":"\u793e\u533a","text":"

      QPython \u62e5\u6709\u4e00\u4e2a\u6d3b\u8dc3\u7684\u6280\u672f\u793e\u533a\uff0c\u4e3a\u5f00\u53d1\u8005\u63d0\u4f9b\u7f16\u7a0b\u5b66\u4e60\u76f8\u5173\u7684\u4ea4\u6d41\u3001\u5206\u4eab\u548c\u4e92\u52a9\u7684\u5e73\u53f0\u3002

      "},{"location":"community/#_2","title":"\u52a0\u5165\u793e\u533a","text":""},{"location":"community/#qpython-","title":"QPython\u516c\u4f17\u53f7 - \u7f16\u7a0b\u5b66\u4e60\u8d44\u6599\u5206\u4eab","text":"

      \u4e13\u6ce8\u4e8eQPython\u79fb\u52a8\u7aef\u5f00\u53d1\u4e0ePython\u5168\u6808\u6280\u672f\u3002\u5185\u5bb9\u6db5\u76d6\uff1a - \u2460 \u57fa\u7840\u8bed\u6cd5\u4e0e\u8fdb\u9636\u6280\u5de7\uff1b - \u2461 \u8da3\u5473\u5b9e\u6218\u9879\u76ee\uff08\u722c\u866b\u3001\u6570\u636e\u5206\u6790\u3001\u81ea\u52a8\u5316\uff09\uff1b - \u2462 \u7f16\u7a0b\u601d\u7ef4\u4e0e\u5b66\u4e60\u65b9\u6cd5\u3002 \u5b9a\u671f\u66f4\u65b0\uff0c\u7cfb\u7edf\u5316\u5b66\u4e60\uff0c\u5e2e\u4f60\u6784\u5efa\u5b8c\u6574\u7684Python\u77e5\u8bc6\u56fe\u8c31\u3002

      "},{"location":"community/#qpython-b","title":"QPython B\u7ad9","text":"

      \u4e13\u6ce8\u624b\u673a\u7f16\u7a0b\u5b9e\u6218\u6559\u5b66\u3002\u7528QPython\u5728\u624b\u673a\u4e0a\u8f7b\u677e\u5b66Python\uff0c\u96f6\u57fa\u7840\u4e5f\u80fd\u8ddf\u4e0a\uff01 - \u2460 \u624b\u628a\u624b\u5b9e\u64cd\u6f14\u793a - \u2461 \u8da3\u5473\u5b9e\u6218\u9879\u76ee\uff08\u722c\u866b/\u81ea\u52a8\u5316/\u5c0f\u5de5\u5177\uff09 - \u2462 \u907f\u5751\u6307\u5357\u4e0e\u6280\u5de7\u5206\u4eab \u6709\u95ee\u5fc5\u7b54\uff0c\u6b22\u8fce\u8bc4\u8bba\u533a\u4ea4\u6d41\uff0c\u4e00\u8d77\u5728\u624b\u673a\u4e0a\u73a9\u8f6cPython\uff01

      • B\u7ad9 \u2013 \u8bbf\u95eeQPython B\u7ad9
      "},{"location":"community/#qpython-qq","title":"QPython QQ\u8bba\u575b","text":"

      \u4e13\u6ce8\u4e8eQPython\u79fb\u52a8\u7aef\u5f00\u53d1\u4e0ePython\u5168\u6808\u6280\u672f\uff0c\u4e3a\u5f00\u53d1\u8005\u63d0\u4f9b\u4e00\u4e2a\u4f5c\u54c1\u5c55\u793a\u3001\u884c\u4e1a\u4ea4\u6d41\u3001\u6280\u672f\u6c89\u6dc0\u7684\u9ad8\u8d28\u91cf\u4ea4\u6d41\u7a7a\u95f4\u3002 \u5305\u62ec\u4ee5\u4e0b\u680f\u76ee\uff1a\u884c\u4e1a\u8d44\u8baf\u3001\u6280\u672f\u4ea4\u6d41\u3001\u9879\u76ee\u6848\u4f8b\u3001BUG\u53cd\u9988\u3002

      • QPython QQ\u9891\u9053 \u2013 \u4e0eQQ/\u5fae\u4fe1\u7528\u6237\u5728\u817e\u8baf\u9891\u9053\u4ea4\u6d41
      "},{"location":"community/#qpython-qq_1","title":"QPython\u5fae\u4fe1\u7fa4 & QQ\u7fa4","text":"

      QPython\u5fae\u4fe1\u7528\u6237\u7fa4\u7fa4\u5b9a\u4f4d\uff1aQPython\u4f7f\u7528\u4ea4\u6d41 | Python\u5b66\u4e60\u4e92\u52a9 | \u5b9e\u6218\u95ee\u9898\u89e3\u7b54\uff0c\u6dfb\u52a0\u52a9\u624b\u540e\u4f1a\u9080\u60a8\u52a0\u5165

      \u5fae\u4fe1\u7fa4\uff08\u52a9\u624b: learnwithqpy\uff09 QQ\u7fa4\uff08\u7fa4\u53f7: 862351102\uff09"},{"location":"community/#qpython-vip","title":"QPython \u77e5\u8bc6\u661f\u7403 VIP\u793e\u533a","text":"

      QPython\u5b98\u65b9\u4ed8\u8d39VIP\u4e13\u5c5e\u793e\u533a\uff0c\u4e3a\u6df1\u5ea6\u7528\u6237\u63d0\u4f9b\u5b98\u65b9\u56e2\u961f\u76f4\u8fde\u3001\u53ca\u65f6\u6280\u672f\u652f\u6301\u3001\u9ad8\u8d28\u91cf\u4ea4\u6d41\u7684\u4e13\u5c5e\u670d\u52a1\u7a7a\u95f4\u3002\u52a0\u5165VIP\u793e\u533a\u53ef\u83b7\u4e0b\u5217\u6838\u5fc3\u4ef7\u503c\uff1a

      • \ud83c\udfaf \u5b98\u65b9\u56e2\u961f\u76f4\u8fde \u2014\u2014 QPython\u5f00\u53d1\u56e2\u961f\u5728\u7ebf\u7b54\u7591\uff0c\u9047\u5230\u95ee\u9898\u4e0d\u518d\u5361\u58f3\uff0c\u6280\u672f\u96be\u9898\u5feb\u901f\u54cd\u5e94
      • \ud83d\ude80 \u4f18\u5148\u6280\u672f\u652f\u6301 \u2014\u2014 VIP\u7528\u6237\u4e13\u5c5e\u901a\u9053\uff0c\u6bd4\u516c\u5f00\u6e20\u9053\u66f4\u5feb\u83b7\u5f97\u5b98\u65b9\u89e3\u7b54
      • \ud83d\udca1 \u6df1\u5ea6\u4ea4\u6d41\u5708\u5b50 \u2014\u2014 \u4e0e\u6838\u5fc3\u7528\u6237\u3001\u8d44\u6df1\u5f00\u53d1\u8005\u540c\u884c\uff0c\u63a2\u8ba8\u9ad8\u9636\u6280\u5de7\u4e0e\u9879\u76ee\u5b9e\u6218

      QPython \u56e2\u961f\u4f1a\u5b9a\u671f\u5728\u793e\u533a\u4e2d\u66f4\u65b0\u9879\u76ee\u8fdb\u5c55\uff0c\u6b22\u8fce\u5173\u6ce8\uff01

      "},{"location":"editor-guide/","title":"\u4f7f\u7528\u6700\u4f73\u5f00\u53d1\u65b9\u5f0f","text":""},{"location":"editor-guide/#qeditor","title":"\u4ece QEditor \u5f00\u53d1","text":"

      QEditor \u662f QPython \u7684\u5185\u7f6e\u7f16\u8f91\u5668\uff0c\u652f\u6301 Python / HTML \u8bed\u6cd5\u9ad8\u4eae\u3002

      QEditor \u7684\u4e3b\u8981\u529f\u80fd

      • \u7f16\u8f91/\u67e5\u770b\u7eaf\u6587\u672c\u6587\u4ef6\uff0c\u5982 Python\u3001Lua\u3001HTML\u3001Javascript \u7b49

      • \u7f16\u8f91\u548c\u8fd0\u884c Python \u811a\u672c & Python \u8bed\u6cd5\u9ad8\u4eae

      • \u7f16\u8f91\u548c\u8fd0\u884c Shell \u811a\u672c

      • \u4f7f\u7528\u5185\u7f6e HTML \u6d4f\u89c8\u5668\u9884\u89c8 HTML

      • \u6309\u5173\u952e\u5b57\u641c\u7d22\u3001\u4ee3\u7801\u7247\u6bb5\u3001\u4ee3\u7801\u5206\u4eab

      \u60a8\u53ef\u4ee5\u76f4\u63a5\u5728 QEditor \u4e2d\u8fd0\u884c QPython \u811a\u672c\uff0c\u56e0\u6b64\u5728\u79fb\u52a8\u65f6\u8fd9\u662f QPython \u5f00\u53d1\u6700\u65b9\u4fbf\u7684\u65b9\u5f0f\u3002

      "},{"location":"editor-guide/#_2","title":"\u901a\u8fc7\u6d4f\u89c8\u5668\u5f00\u53d1","text":"

      QPython \u6709\u4e00\u4e2a\u5185\u7f6e\u811a\u672c qedit4web.py\uff0c\u5f53\u60a8\u70b9\u51fb\u5f00\u59cb\u6309\u94ae\u5e76\u9009\u62e9\"\u8fd0\u884c\u672c\u5730\u811a\u672c\"\u65f6\u53ef\u4ee5\u770b\u5230\u5b83\u3002

      \u8fd0\u884c\u540e\uff0c\u60a8\u53ef\u4ee5\u770b\u5230\u7ed3\u679c\u3002

      \u7136\u540e\uff0c\u60a8\u53ef\u4ee5\u901a\u8fc7 PC/\u7b14\u8bb0\u672c\u7535\u8111\u7684\u6d4f\u89c8\u5668\u8bbf\u95ee\u8be5\u7f51\u5740\u8fdb\u884c\u5f00\u53d1\uff0c\u5982\u4e0b\u56fe\u6240\u793a\u3002

      \u9009\u62e9\u67d0\u4e2a\u9879\u76ee\u6216\u811a\u672c\u540e\uff0c\u60a8\u53ef\u4ee5\u5f00\u59cb\u5f00\u53d1

      \u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\u7f16\u5199\u6d4f\u89c8\u5668\u4ee3\u7801\uff0c\u7136\u540e\u5728 Android \u624b\u673a\u4e0a\u8fd0\u884c\u3002\u975e\u5e38\u65b9\u4fbf\u3002

      "},{"location":"editor-guide/#_3","title":"\u4ece\u60a8\u7684\u7535\u8111\u5f00\u53d1","text":"

      \u9664\u4e86\u4e0a\u8ff0\u65b9\u6cd5\uff0c\u60a8\u8fd8\u53ef\u4ee5\u7528\u81ea\u5df1\u7684\u65b9\u5f0f\u5f00\u53d1\u811a\u672c\uff0c\u7136\u540e\u901a\u8fc7\u5185\u7f6e\u7684 FTP \u670d\u52a1\u5c06\u5176\u4e0a\u4f20\u5230\u624b\u673a\uff0c\u7528 QPython \u8fd0\u884c\u5b83\u3002

      "},{"location":"external-api/","title":"QPython \u5f00\u653e API","text":"

      QPython \u6709\u4e00\u4e2a\u5f00\u653e\u7684 activity\uff0c\u5141\u8bb8\u60a8\u4ece\u5916\u90e8\u8fd0\u884c qpython\u3002

      MPyAPI \u7684\u5b9a\u4e49\u5982\u4e0b\uff1a

          <activity\n        android:name=\"org.qpython.qpylib.MPyApi\"\n        android:label=\"@string/qpy_run_with_share\"\n        android:screenOrientation=\"user\"\n        android:configChanges=\"orientation|keyboardHidden\"\n        android:exported=\"true\">\n        <intent-filter>\n            <action android:name=\"org.qpython.qpylib.action.MPyApi\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.LAUNCHER\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.VIEW\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.BROWSABLE\" />\n            <data android:scheme=\"http\" />\n            <data android:scheme=\"https\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"text/plain\"/>\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"image/*\"/>\n        </intent-filter>\n    </activity>\n

      \u56e0\u6b64\uff0c\u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\uff1a

      "},{"location":"external-api/#qpython","title":"\u5c06\u5185\u5bb9\u5206\u4eab\u5230 QPython \u7684\u811a\u672c","text":"

      \u60a8\u53ef\u4ee5\u5728\u67d0\u4e2a\u5e94\u7528\u4e2d\u9009\u62e9\u4e00\u4e9b\u5185\u5bb9\uff0c\u7136\u540e\u5206\u4eab\u5230 qpython \u7684\u811a\u672c\uff0c\u4e4b\u540e\u60a8\u53ef\u4ee5\u4f7f\u7528 sys.argv[2] \u5904\u7406\u8fd9\u4e9b\u5185\u5bb9

      \u5728 YouTube \u4e0a\u89c2\u770b\u6f14\u793a\u89c6\u9891

      "},{"location":"external-api/#qpython_1","title":"\u4ece\u60a8\u81ea\u5df1\u7684\u5e94\u7528\u7a0b\u5e8f\u8fd0\u884c QPython \u7684\u811a\u672c","text":"

      \u60a8\u53ef\u4ee5\u901a\u8fc7\u8c03\u7528\u6b64 activity \u5728\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u4e2d\u8c03\u7528 QPython \u6765\u8fd0\u884c\u67d0\u4e9b\u811a\u672c\u6216 Python \u4ee3\u7801\uff0c\u793a\u4f8b\u5982\u4e0b\uff1a

      // \u5c55\u793a\u5982\u4f55\u8c03\u7528 qpython API \u7684\u4ee3\u7801\u793a\u4f8b\nString extPlgPlusName = \"org.qpython.qpy\";          // QPython \u5305\u540d\nIntent intent = new Intent();\nintent.setClassName(extPlgPlusName, \"org.qpython.qpylib.MPyApi\");\nintent.setAction(extPlgPlusName + \".action.MPyApi\");\n\nBundle mBundle = new Bundle();\nmBundle.putString(\"app\", \"myappid\");\nmBundle.putString(\"act\", \"onPyApi\");\nmBundle.putString(\"flag\", \"onQPyExec\"); // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u4efb\u610f\u5b57\u7b26\u4e32\u6807\u5fd7\nmBundle.putString(\"param\", \"\");         // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u53c2\u6570\u5b57\u7b26\u4e32\n\n/*\n* \u6211\u4eec\u5c06\u8fd0\u884c\u7684 Python \u4ee3\u7801\n*/\nString code = \"import androidhelper\\n\" +\n            \"droid = androidhelper.Android()\\n\" +\n            \"line = droid.dialogGetInput()\\n\" +\n            \"s = 'Hello %s' % line.result\\n\" +\n            \"droid.makeToast(s)\\n\"\n\nmBundle.putString(\"pycode\", code);\nintent.putExtras(mBundle);\nstartActivityForResult(intent, SCRIPT_EXEC_PY);\n...\n\n// \u60a8\u53ef\u4ee5\u5728 onActivityResult \u4e2d\u5904\u7406 qpython \u8c03\u7528\u7ed3\u679c\n@Override\nprotected void onActivityResult(int requestCode, int resultCode, Intent data) {\n    if (requestCode == SCRIPT_EXEC_PY) {\n        if (data!=null) {\n            Bundle bundle = data.getExtras();\n            String flag = bundle.getString(\"flag\");\n            String param = bundle.getString(\"param\");\n            String result = bundle.getString(\"result\"); // \u60a8\u7684 Pycode \u751f\u6210\u7684\u7ed3\u679c\n            Toast.makeText(this, \"onQPyExec: return (\"+result+\")\", Toast.LENGTH_SHORT).show();\n        } else {\n            Toast.makeText(this, \"onQPyExec: data is null\", Toast.LENGTH_SHORT).show();\n\n        }\n    }\n}\n

      \u4ece github \u68c0\u51fa\u4e00\u4e2a\u5b8c\u6574\u9879\u76ee

      \u8fd8\u6709\u4e00\u4e2a\u751f\u4ea7\u5e94\u7528\u7a0b\u5e8f - \u9762\u5411 Tasker \u7684 QPython \u63d2\u4ef6

      "},{"location":"getting-started/","title":"QPython\uff1a\u5165\u95e8\u6307\u5357","text":"

      \u672c\u6307\u5357\u5c06\u4ecb\u7ecd QPython \u7684\u529f\u80fd\u5e76\u5e2e\u52a9\u60a8\u5feb\u901f\u5165\u95e8\u3002

      "},{"location":"getting-started/#qpython_1","title":"QPython \u6982\u8ff0","text":"

      \u4e3a\u4ec0\u4e48\u9009\u62e9 QPython\uff1f

      \u667a\u80fd\u624b\u673a\u5df2\u6210\u4e3a\u4eba\u4eec\u5fc5\u5907\u7684\u4fe1\u606f\u548c\u6280\u672f\u52a9\u624b\uff0c\u4e00\u4e2a\u7075\u6d3b\u7684\u89e3\u91ca\u5668\u5f15\u64ce\u53ef\u4ee5\u5e2e\u52a9\u60a8\u9ad8\u6548\u5b8c\u6210\u5927\u90e8\u5206\u5de5\u4f5c\uff0c\u65e0\u9700\u590d\u6742\u7684\u5f00\u53d1\u8fc7\u7a0b\u3002

      QPython \u63d0\u4f9b\u4e86 \u60ca\u4eba\u7684\u5f00\u53d1\u4f53\u9a8c\u2014\u2014\u501f\u52a9\u5b83\u7684\u5e2e\u52a9\uff0c\u60a8\u53ef\u4ee5\u8f7b\u677e\u5b9e\u73b0\u7a0b\u5e8f\uff0c\u65e0\u9700\u590d\u6742\u7684 IDE \u5b89\u88c5\u3001\u7f16\u8bd1\u6216\u6253\u5305\u8fc7\u7a0b\u3002

      "},{"location":"getting-started/#qpython_2","title":"QPython \u7248\u672c","text":"

      \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

      • QPython \u2013 \u7531 QPython \u56e2\u961f\u7ef4\u62a4\u7684\u4e3b\u8981\u7248\u672c\uff0c\u5177\u5907 AI \u529f\u80fd\uff0c\u53ef\u5728 Google Play \u7b49\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d
      • QPython+ \u2013 \u7531\u5f00\u6e90\u8d21\u732e\u8005\u63a8\u51fa\u7684\u793e\u533a\u7248\uff0c\u63d0\u4f9b\u5404\u79cd\u65b0\u7279\u6027
      • QPython Plus \u2013 \u6269\u5c55\u6743\u9650\u7248\u672c\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff09
      "},{"location":"getting-started/#_1","title":"\u4e3b\u8981\u7279\u6027","text":"
      • \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668 - \u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51
      • QSL4A \u96c6\u6210 - \u4f7f\u7528 Python \u63a7\u5236 Android \u786c\u4ef6\u548c API
      • GenAI \u80fd\u529b\u96c6\u6210 - \u652f\u6301\u672c\u5730\u8fd0\u884c\u7684 LLM\u3001OpenAI \u7b49\u5404\u79cd LLM \u5e93\uff0c\u4ee5\u53ca\u53ef\u5728 QPython \u4e0a\u8fdb\u884c Vibe Coding \u5f00\u53d1\u7684 AIPyApp
      • \u6269\u5c55\u5305\u5b89\u88c5 - \u652f\u6301\u901a\u8fc7 QPYPI \u548c pip \u5b89\u88c5\u6269\u5c55\u5305
      • \u5185\u7f6e\u7f16\u8f91\u5668 - \u8bed\u6cd5\u9ad8\u4eae\u548c\u4ee3\u7801\u7f16\u8f91
      • \u591a\u79cd\u8fd0\u884c\u6a21\u5f0f - \u9664\u63a7\u5236\u53f0\u7a0b\u5e8f\u5916\uff0c\u8fd8\u652f\u6301 Android \u539f\u751f UI\uff08\u901a\u8fc7 QSL4A \u63a5\u53e3\uff09\u4ee5\u53ca Pygame / Turtle / Tkinter \u7b49\u8fd0\u884c\u65b9\u5f0f
      "},{"location":"getting-started/#1","title":"1. \u4eea\u8868\u76d8","text":"

      \u5b89\u88c5 QPython \u540e\uff0c\u70b9\u51fb\u5176\u56fe\u6807\u542f\u52a8\u3002\u60a8\u5c06\u770b\u5230\u5e26\u6709 QPython \u6807\u5fd7\u548c\u4ee5\u4e0b\u529f\u80fd\u7684\u4e3b\u4eea\u8868\u76d8\uff1a

      "},{"location":"getting-started/#_2","title":"\u4eea\u8868\u76d8\u529f\u80fd","text":"

      QPython \u4eea\u8868\u76d8\u63d0\u4f9b\u5bf9\u6240\u6709\u4e3b\u8981\u529f\u80fd\u7684\u5feb\u901f\u8bbf\u95ee\uff1a

      • \u7ec8\u7aef \u2014 \u8bbf\u95ee Python \u63a7\u5236\u53f0\u548c shell \u4ee5\u76f4\u63a5\u6267\u884c\u547d\u4ee4
      • Notebook \u2014 \u7528\u4e8e\u6570\u636e\u5206\u6790\u548c\u5b9e\u9a8c\u7684\u4ea4\u4e92\u5f0f Jupyter \u98ce\u683c\u7b14\u8bb0\u672c
      • \u7f16\u8f91\u5668 \u2014 \u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668\uff0c\u5177\u6709\u8bed\u6cd5\u9ad8\u4eae\u529f\u80fd\uff0c\u7528\u4e8e\u7f16\u5199 Python \u811a\u672c
      • \u8d44\u6e90\u7ba1\u7406\u5668 \u2014 \u6d4f\u89c8\u548c\u7ba1\u7406\u60a8\u7684\u6587\u4ef6\u3001\u811a\u672c\u548c\u9879\u76ee
      • QPYPI \u2014 \u5b89\u88c5 Python \u5305\u548c\u6269\u5c55\u3002\u8be6\u89c1 QPYPI \u6307\u5357
      • \u8bbe\u7f6e \u2014 \u914d\u7f6e QPython \u9996\u9009\u9879\u548c\u8fd0\u884c\u9009\u9879
      • \u793e\u533a \u2014 \u8bbf\u95ee QPython \u793e\u533a\u8d44\u6e90\u3001\u8bba\u575b\u548c\u5e2e\u52a9
      • \u8bfe\u7a0b \u2014 \u8bbf\u95ee Python \u7f16\u7a0b\u7684\u5b66\u4e60\u6750\u6599\u548c\u6559\u7a0b

      \u70b9\u51fb\u4efb\u4f55\u56fe\u6807\u4ee5\u8bbf\u95ee\u76f8\u5e94\u7684\u529f\u80fd\u3002

      "},{"location":"getting-started/#2","title":"2. \u7ec8\u7aef\u548c\u7f16\u8f91\u5668","text":""},{"location":"getting-started/#_3","title":"\u7ec8\u7aef","text":"

      \u7ec8\u7aef\u63d0\u4f9b Python \u63a7\u5236\u53f0\uff0c\u652f\u6301\uff1a - \u63a2\u7d22\u5bf9\u8c61\u5c5e\u6027 - \u6d4b\u8bd5\u8bed\u6cd5\u548c\u60f3\u6cd5 - \u76f4\u63a5\u6267\u884c\u547d\u4ee4

      \u4f7f\u7528\u52a0\u53f7\u6309\u94ae\uff081\uff09\u6253\u5f00\u65b0\u7ec8\u7aef\u6807\u7b7e\u9875\uff0c\u901a\u8fc7\u4e0b\u62c9\u83dc\u5355\uff082\uff09\u5207\u6362\uff0c\u5e76\u4f7f\u7528\u5173\u95ed\u6309\u94ae\uff083\uff09\u5173\u95ed\u3002

      "},{"location":"getting-started/#_4","title":"\u7f16\u8f91\u5668","text":"

      \u7f16\u8f91\u5668\u5e95\u90e8\u529f\u80fd\u680f\u5305\u542b\u4ee5\u4e0b\u5de5\u5177\uff08\u4ece\u5de6\u5230\u53f3\uff09\uff1a

      • \u5207\u6362\u5feb\u6377\u8f93\u5165\uff08\u5305\u542b def / if / else / elif / class \u7b49\u5173\u952e\u8bcd\uff09
      • \u9501\u5b9a\uff08\u9632\u6b62\u8bef\u89e6\uff09
      • \u8df3\u8f6c
      • \u4fdd\u5b58
      • \u8fd0\u884c
      • \u641c\u7d22
      • \u64a4\u9500
      • \u91cd\u505a
      • \u53e6\u5b58
      • \u6700\u8fd1\u6587\u4ef6
      • \u4ee3\u7801\u7247\u6bb5

      \u91cd\u8981\u63d0\u793a\uff1a \u4fdd\u5b58\u65f6\u8bf7\u624b\u52a8\u6dfb\u52a0 .py \u6269\u5c55\u540d\uff0c\u56e0\u4e3a\u7f16\u8f91\u5668\u4e0d\u4f1a\u81ea\u52a8\u6dfb\u52a0\u3002

      "},{"location":"getting-started/#3","title":"3. \u8d44\u6e90\u7ba1\u7406\u5668\uff08\u6587\u4ef6\u7ba1\u7406\uff09","text":"

      \u901a\u8fc7 \u8d44\u6e90\u7ba1\u7406\u5668 \u8bbf\u95ee\u811a\u672c\u548c\u9879\u76ee\uff0c\u652f\u6301\u6d4f\u89c8\u3001\u7ec4\u7ec7\u548c\u7ba1\u7406\u6240\u6709 Python \u6587\u4ef6\u3002

      "},{"location":"getting-started/#_5","title":"\u811a\u672c","text":"

      \u811a\u672c\u662f\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/scripts3/ \u4e2d\u7684\u5355\u4e2a Python \u6587\u4ef6\uff08\u9488\u5bf9 Python 3\uff09\u3002

      \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u811a\u672c - \u6253\u5f00 \u2014 \u4f7f\u7528\u5185\u7f6e\u7f16\u8f91\u5668\u7f16\u8f91 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u811a\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u811a\u672c

      "},{"location":"getting-started/#_6","title":"\u9879\u76ee","text":"

      \u9879\u76ee\u662f\u5305\u542b main.py \u4f5c\u4e3a\u5165\u53e3\u70b9\u7684\u76ee\u5f55\u3002\u60a8\u53ef\u4ee5\u5728\u540c\u4e00\u76ee\u5f55\u4e2d\u5305\u542b\u5176\u4ed6\u4f9d\u8d56\u9879\u548c\u8d44\u6e90\u3002\u5c06\u9879\u76ee\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/projects3/ \u4e2d\u3002

      "},{"location":"getting-started/#_7","title":"\u7b14\u8bb0\u672c","text":"

      Jupyter \u98ce\u683c\u7684\u7b14\u8bb0\u672c\u4e5f\u901a\u8fc7\u8d44\u6e90\u7ba1\u7406\u5668\u8fdb\u884c\u7ba1\u7406\uff0c\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/notebooks/ \u4e2d\u3002

      \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u7b14\u8bb0\u672c - \u6253\u5f00 \u2014 \u63a2\u7d22\u7b14\u8bb0\u672c\u5185\u5bb9 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u7b14\u8bb0\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u7b14\u8bb0\u672c

      "},{"location":"getting-started/#4","title":"4. \u5e93","text":"

      \u901a\u8fc7\u5b89\u88c5\u7b2c\u4e09\u65b9\u5e93\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

      "},{"location":"getting-started/#_8","title":"\u5305\u5b89\u88c5\u65b9\u6cd5","text":"

      QPYPI\uff08\u63a8\u8350\uff09

      \u4ece QPYPI \u5b89\u88c5\u9884\u7f16\u8bd1\u7684\u5e93\uff0c\u5305\u62ec numpy\u3001scipy \u7b49\u79d1\u5b66\u5305\u3002

      \u8be6\u89c1 QPYPI \u6307\u5357\u3002

      PIP \u5ba2\u6237\u7aef

      \u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216 QPYPI \u754c\u9762\u5b89\u88c5\u7eaf Python \u5e93\uff1a

      pip install requests\n

      \u9884\u7f16\u8bd1\u5305

      \u5bf9\u4e8e\u5177\u6709 C/C++/Rust \u4f9d\u8d56\u7684\u5305\uff0c\u4f7f\u7528 QPython \u7684\u9884\u7f16\u8bd1\u5305\uff1a

      pip install numpy-qpython\npip install scipy-aipy\n

      \u8be6\u89c1 QPYPI \u6307\u5357 \u83b7\u53d6\u53ef\u7528\u5305\u7684\u5b8c\u6574\u5217\u8868\u3002

      \u624b\u52a8\u5b89\u88c5

      \u60a8\u4e5f\u53ef\u4ee5\u5c06\u5e93\u590d\u5236\u5230 /storage/emulated/0/Android/data/org.qpython.qpy/files/lib/python3.12/site-packages/\u3002

      "},{"location":"getting-started/#5","title":"5. \u8fd0\u884c\u6a21\u5f0f","text":"

      QPython \u652f\u6301\u591a\u79cd\u8fd0\u884c\u6a21\u5f0f\u4ee5\u6ee1\u8db3\u4e0d\u540c\u7684\u7528\u4f8b\uff1a

      "},{"location":"getting-started/#_9","title":"\u63a7\u5236\u53f0\u6a21\u5f0f","text":"

      \u5e38\u89c4 Python \u811a\u672c\u7684\u9ed8\u8ba4\u6a21\u5f0f\u3002

      "},{"location":"getting-started/#qsl4a","title":"QSL4A \u6a21\u5f0f","text":"

      \u901a\u8fc7 QSL4A \u5e93\u8c03\u7528 Android API \u7684\u811a\u672c\u3002

      import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello Android!')\n

      \u8be6\u89c1 QSL4A \u6587\u6863 \u83b7\u53d6\u5b8c\u6574\u7684 API \u53c2\u8003\u3002

      "},{"location":"getting-started/#webapp","title":"WebApp \u6a21\u5f0f","text":"

      \u4f7f\u7528\u540e\u7aef\u670d\u52a1\u5668\u521b\u5efa\u57fa\u4e8e Web \u7684\u5e94\u7528\u7a0b\u5e8f\u3002\u9700\u5728\u811a\u672c\u5f00\u5934\u6dfb\u52a0\u4ee5\u4e0b\u4e24\u884c headers\uff1a

      #qpy:webapp:<\u9879\u76ee\u540d>\n#qpy://localhost:<web\u670d\u52a1\u4fa6\u542c\u7684\u7aef\u53e3>/<\u9ed8\u8ba4\u4e3b\u8def\u5f84>\n

      \u4f8b\u5982\uff1a

      #qpy:webapp:Hello QPython\n#qpy://localhost:8080/hello\n\nfrom bottle import route, run, Bottle\n\napp = Bottle()\n\n@route('/hello')\ndef hello():\n    return '<h1>Hello from QPython!</h1>'\n\nrun(app, host='localhost', port=8080)\n
      "},{"location":"getting-started/#q","title":"Q \u6a21\u5f0f\uff08\u65e0\u63a7\u5236\u53f0\u6a21\u5f0f\uff09","text":"

      \u9759\u9ed8\u6a21\u5f0f\u8fd0\u884c\u811a\u672c\uff0c\u4e0d\u663e\u793a\u63a7\u5236\u53f0\u3002\u9700\u5728\u811a\u672c\u5f00\u5934\u6dfb\u52a0 header\uff1a

      #qpy:quiet\n\nimport time\n\nwhile True:\n    # \u60a8\u7684\u540e\u53f0\u4efb\u52a1\n    time.sleep(60)\n
      \u5982\u679c\u9700\u8981\u8fd0\u884c\u5e26 GUI \u7684 QSL4A \u7a0b\u5e8f\u4e14\u4e0d\u5e0c\u671b\u663e\u793a\u63a7\u5236\u53f0\u4fe1\u606f\uff0c\u63a8\u8350\u4f7f\u7528\u6b64\u6a21\u5f0f\u3002

      "},{"location":"getting-started/#6","title":"6. \u793e\u533a\u4e0e\u652f\u6301","text":"

      \u8bbf\u95ee QPython.org \u83b7\u53d6\u6587\u6863\u3001\u7528\u6237\u793e\u533a\u53ca\u5e2e\u52a9\u95ee\u7b54\u3002

      \u793e\u533a\u94fe\u63a5\uff1a - Facebook \u7fa4\u7ec4 - GitHub - \u95ee\u9898\u53cd\u9988

      \u4e0b\u4e00\u6b65\uff1a - \u5c1d\u8bd5 Hello World \u6559\u7a0b - \u63a2\u7d22 QSL4A API \u4ee5\u96c6\u6210 Android - \u4e86\u89e3 QPython \u7248\u672c

      "},{"location":"getting-started/#_10","title":"\u89c6\u9891\u4ecb\u7ecd","text":""},{"location":"getting-started/#_11","title":"\u4e0b\u4e00\u6b65","text":"

      \u5982\u679c\u60a8\u5df2\u7ecf\u521d\u6b65\u4e86\u89e3\u4e86 QPython \u7684\u529f\u80fd\uff0c\u6b22\u8fce\u5f00\u59cb\u4f53\u9a8c\u7f16\u7a0b\u7684\u4e50\u8da3\uff01\u8bd5\u8bd5 Hello World \u6559\u7a0b \u8fc8\u51fa\u60a8\u7684\u7b2c\u4e00\u6b65\u3002

      "},{"location":"qpypi-guide/","title":"QPYPI","text":"

      \u60a8\u53ef\u4ee5\u901a\u8fc7\u5b89\u88c5\u5305\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

      "},{"location":"qpypi-guide/#_1","title":"\u5305\u5b89\u88c5\u652f\u6301","text":""},{"location":"qpypi-guide/#python","title":"\u7eaf Python \u5305","text":"

      QPython \u652f\u6301\u4f7f\u7528\u7eaf Python \u5f00\u53d1\u7684 Python \u5305\u3002\u60a8\u53ef\u4ee5\u76f4\u63a5\u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216\u4eea\u8868\u76d8\u4e0a\u7684 QPYPI \u4f7f\u7528 pip install \u5b89\u88c5\u8fd9\u4e9b\u5305\u3002

      "},{"location":"qpypi-guide/#_2","title":"\u9884\u7f16\u8bd1\u5305","text":"

      \u5982\u679c\u67d0\u4e9b\u5305\uff08\u6216\u5b83\u4eec\u7684\u4f9d\u8d56\uff09\u662f\u7528 Rust/C/C++ \u5f00\u53d1\u7684\uff0cQPython \u65e0\u6cd5\u76f4\u63a5\u652f\u6301\u5b83\u4eec\uff0c\u56e0\u4e3a QPython \u4e0a\u6ca1\u6709\u7f16\u8bd1\u5668\u5de5\u5177\u94fe\u652f\u6301\u3002\u4f46\u662f\uff0cQPython \u56e2\u961f\u5df2\u7ecf\u9884\u7f16\u8bd1\u4e86\u4e00\u4e9b\u5e38\u7528\u5305\uff0c\u5e76\u5728 QPython \u7684 QPYPI/Extensions \u4e2d\u53d1\u5e03\uff0c\u4f9b\u7528\u6237\u8f7b\u677e\u5b89\u88c5\u3002

      "},{"location":"qpypi-guide/#_3","title":"\u5b89\u88c5\u9884\u7f16\u8bd1\u5305","text":"

      \u60a8\u53ef\u4ee5\u901a\u8fc7\u4ee5\u4e0b\u65b9\u5f0f\u5b89\u88c5\u9884\u7f16\u8bd1\u5305\uff1a

      1. \u901a\u8fc7 QPython \u5e94\u7528\uff1a\u76f4\u63a5\u4ece QPython \u5e94\u7528\u5185\u7684 QPYPI \u6216 Extensions \u5b89\u88c5
      2. \u901a\u8fc7 PyPI\uff1a\u8bbf\u95ee https://pypi.org/user/qpythonx/ \u67e5\u770b\u53ef\u7528\u7684\u5305
      3. \u901a\u8fc7 pip \u547d\u4ee4\uff1a
      4. pip install xxx-qpython - \u5e26 -qpython \u540e\u7f00\u7684\u5305
      5. pip install xxx-aipy - \u5e26 -aipy \u540e\u7f00\u7684\u5305\uff08\u901a\u5e38\u662f AI/ML \u76f8\u5173\u7684\u5305\uff09

      \u6ce8\u610f\uff1a\u6211\u4eec\u901a\u5e38\u6839\u636e\u5305\u7684\u9884\u671f\u7528\u9014\u6dfb\u52a0\u8fd9\u4e9b\u540e\u7f00\u4e4b\u4e00\u3002

      "},{"location":"qpypi-guide/#_4","title":"\u8bf7\u6c42\u65b0\u5305","text":"

      \u5982\u679c\u60a8\u9700\u8981\u5f53\u524d\u4e0d\u652f\u6301\u7684\u5305\uff1a

      • \u5728 qpython.org \u9879\u76ee \u4e2d\u63d0\u51fa\u95ee\u9898
      • QPython \u56e2\u961f\u5c06\u8003\u8651\u9884\u7f16\u8bd1\u5e76\u5c06\u5176\u6dfb\u52a0\u5230\u4ed3\u5e93\u4e2d

      \u83b7\u53d6\u66f4\u591a\u5e2e\u52a9\u548c\u53c2\u4e0e\u793e\u533a\u7684\u65b9\u5f0f\uff0c\u8bf7\u53c2\u9605 \u793e\u533a\u4e0e\u53cd\u9988 \u90e8\u5206\u3002

      \u6ce8\u610f\uff1a\u7531\u4e8e\u4e0d\u540c\u7684\u8ba1\u7b97\u673a\u67b6\u6784\uff0c\u6211\u4eec\u65e0\u6cd5\u4fdd\u8bc1 QPYPI \u5305\u542b PyPI \u4e0a\u7684\u6240\u6709\u5305\u3002

      "},{"location":"qpython-x/","title":"QPython \u7248\u672c","text":"

      QPython \u662f Android \u7684 Python \u5f15\u64ce\u3002\u5b83\u5305\u542b\u4ee4\u4eba\u60ca\u53f9\u7684\u529f\u80fd\uff0c\u5982 Python \u89e3\u91ca\u5668\u3001\u8fd0\u884c\u73af\u5883\u3001\u7f16\u8f91\u5668\u3001QPYI \u548c\u96c6\u6210\u7684 SL4A\u3002\u5b83\u8ba9\u60a8\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 Android \u4e0a\u4f7f\u7528 Python\u3002\u800c\u4e14\u5b83\u662f\u514d\u8d39\u7684\u3002

      QPython \u5df2\u7ecf\u5728\u5168\u7403\u62e5\u6709\u6570\u767e\u4e07\u7528\u6237\uff0c\u4e5f\u662f\u4e00\u4e2a\u5f00\u6e90\u9879\u76ee\u3002

      \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

      "},{"location":"qpython-x/#qpython_1","title":"QPython","text":"

      \u6807\u51c6\u7248\uff1a\u9488\u5bf9 AI \u6027\u80fd\u548c\u901a\u7528\u5e94\u7528\u5546\u5e97\u517c\u5bb9\u6027\u4f18\u5316

      \u4e3b\u8981\u7248\u672c\uff0c\u53ef\u5728 Google Play \u548c\u5176\u4ed6\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002\u6b64\u7248\u672c\u4e13\u6ce8\u4e8e AI \u529f\u80fd\uff0c\u4f7f AI \u65f6\u4ee3\u7528\u6237\u66f4\u5bb9\u6613\u5b66\u4e60\u548c\u4f7f\u7528 Python\u3002

      \u4e3b\u8981\u7279\u6027\uff1a - AI \u9a71\u52a8\u7684\u7f16\u7801\u8f85\u52a9\u548c\u5b66\u4e60\u5de5\u5177 - \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668\uff1a\u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51 - \u652f\u6301\u591a\u79cd\u9879\u76ee\u7c7b\u578b\uff1a\u63a7\u5236\u53f0\u3001SL4A\u3001WebApp - \u65b9\u4fbf\u7684\u4e8c\u7ef4\u7801\u8bfb\u53d6\u5668\uff0c\u7528\u4e8e\u5c06\u4ee3\u7801\u4f20\u8f93\u5230\u624b\u673a - QPYPI \u548c\u81ea\u5b9a\u4e49\u4ed3\u5e93\uff0c\u7528\u4e8e\u9884\u7f16\u8bd1 wheel \u5305 -\u6613\u4e8e\u4f7f\u7528\u7684\u8bed\u6cd5\u9ad8\u4eae\u7f16\u8f91\u5668 - \u5b8c\u5584\u7684\u6587\u6863\u548c\u793e\u533a\u652f\u6301

      \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

      \u4e0b\u8f7d\uff1a \u53ef\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

      "},{"location":"qpython-x/#qpython_2","title":"QPython+","text":"

      \u793e\u533a\u7248\uff1a\u516c\u5f00\u652f\u6301\u5404\u79cd\u793e\u533a\u9a71\u52a8\u7684\u529f\u80fd\uff1b\u53ef\u5728\u90e8\u5206\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

      \u793e\u533a\u5f00\u6e90\u7248\u672c\uff08\u6b63\u5728\u89c4\u5212\u548c\u51c6\u5907\u4e2d\uff09\u3002\u6b64\u7248\u672c\u4e13\u4e3a\u60f3\u8981\u53c2\u4e0e QPython \u9879\u76ee\u5f00\u53d1\u7684\u8d21\u732e\u8005\u800c\u8bbe\u8ba1\uff0c\u652f\u6301\u9488\u5bf9\u4e0d\u540c\u5236\u9020\u5546\u7684\u5b9a\u5236\u3002

      \u4e3b\u8981\u7279\u6027\uff1a - \u793e\u533a\u9a71\u52a8\u5f00\u53d1 - \u652f\u6301\u4f9b\u5e94\u5546\u5b9a\u5236 - \u66f4\u7075\u6d3b\u7684\u914d\u7f6e\u9009\u9879 - \u5f00\u653e\u4f9b\u8d21\u732e\u8005\u52a0\u5165\u5f00\u53d1

      \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

      \u4e0b\u8f7d\uff1a \u5c06\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

      \u6ce8\u610f\uff1a \u6b64\u7248\u672c\u76ee\u524d\u6b63\u5728\u89c4\u5212\u51c6\u5907\u4e2d\u3002\u8bf7\u5173\u6ce8\u66f4\u65b0\uff01

      "},{"location":"qpython-x/#qpython-plus","title":"QPython Plus","text":"

      QPython+ \u5b8c\u5168\u8bbf\u95ee\u7248\uff1a\u6388\u4e88\u8c03\u7528\u6240\u6709 Android \u63a5\u53e3\u7684\u5b8c\u6574\u6743\u9650\u3002\u4e0b\u8f7d\u94fe\u63a5\u4ec5\u901a\u8fc7\u5b98\u65b9\u4e91\u76d8\u63d0\u4f9b\u3002

      \u5177\u6709\u6269\u5c55\u6743\u9650\u7684\u7279\u6b8a\u7248\u672c\uff0c\u63d0\u4f9b\u5bf9\u8bbe\u5907\u7684\u6700\u5927\u63a7\u5236\u3002\u7531\u4e8e\u5176\u654f\u611f\u7684\u6743\u9650\u8981\u6c42\uff0c\u6b64\u7248\u672c\u4e0d\u4f1a\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u53d1\u5e03\u3002

      \u4e3b\u8981\u7279\u6027\uff1a - \u5b8c\u6574\u7684 SL4A API \u8bbf\u95ee\uff0c\u5305\u62ec\u654f\u611f\u529f\u80fd - SMS/\u901a\u8bdd\u63a7\u5236 API - \u9ad8\u7ea7\u7cfb\u7edf\u96c6\u6210 - \u6700\u5927\u7684\u8bbe\u5907\u63a7\u5236\u80fd\u529b

      \u6743\u9650\uff1a \u9700\u8981\u5e7f\u6cdb\u7684\u6743\u9650\uff0c\u5305\u62ec\uff1a - \u84dd\u7259 - \u4f4d\u7f6e\uff08GPS\uff09 - \u8bfb\u53d6/\u53d1\u9001\u77ed\u4fe1 - \u6253\u7535\u8bdd - \u76f8\u673a\u548c\u9ea6\u514b\u98ce - \u7cfb\u7edf\u8bbe\u7f6e - \u4ee5\u53ca\u5176\u4ed6\u654f\u611f\u6743\u9650

      \u4e0b\u8f7d\uff1a \u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\u3002\u4ec5\u901a\u8fc7\u7279\u6b8a\u6e20\u9053\u5206\u53d1\u3002

      \u91cd\u8981\u63d0\u793a\uff1a QPython \u4e0d\u4f1a\u5728\u540e\u53f0\u672a\u7ecf\u60a8\u77e5\u6089\u4f7f\u7528\u8fd9\u4e9b\u6743\u9650\u3002\u5982\u679c\u4f7f\u7528 SL4A API \u65f6\u51fa\u73b0\u5f02\u5e38\uff0c\u8bf7\u68c0\u67e5\u7cfb\u7edf\u8bbe\u7f6e\u4e2d\u662f\u5426\u5df2\u542f\u7528\u76f8\u5173\u6743\u9650\u3002

      "},{"location":"tutorial-hello-world/","title":"\u7f16\u5199\"Hello World\"","text":""},{"location":"tutorial-hello-world/#hello-world_1","title":"Hello world","text":"

      \u597d\u7684\uff0c\u5728\u60a8\u5bf9 QPython \u6709\u4e86\u4e00\u5b9a\u7684\u4e86\u89e3\u4e4b\u540e\uff0c\u8ba9\u6211\u4eec\u5728 QPython \u4e2d\u521b\u5efa\u6211\u4eec\u7684\u7b2c\u4e00\u4e2a\u7a0b\u5e8f\u3002\u663e\u7136\uff0c\u5b83\u5c06\u662f helloworld.py\u3002;)

      \u542f\u52a8 QPython\uff0c\u6253\u5f00\u7f16\u8f91\u5668\u5e76\u8f93\u5165\u4ee5\u4e0b\u4ee3\u7801\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello, QPYTHON!')\n

      \u6beb\u65e0\u7591\u95ee\uff0c\u5b83\u4e0e\u5176\u4ed6\u4efb\u4f55 hello-world \u7a0b\u5e8f\u5e76\u65e0\u4e0d\u540c\u3002\u6267\u884c\u65f6\uff0c\u5b83\u53ea\u662f\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u5f39\u51fa\u6d88\u606f\uff08\u89c1\u9876\u90e8\u622a\u56fe\uff09\u3002\u65e0\u8bba\u5982\u4f55\uff0c\u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684 QPython \u7a0b\u5e8f\u793a\u4f8b\u3002

      "},{"location":"tutorial-hello-world/#_1","title":"\u4ee3\u7801\u7406\u89e3","text":"

      \u5b83\u4ee5 import androidhelper \u5f00\u5934\u2014\u2014\u8fd9\u662f QPython \u4e2d\u6700\u6709\u7528\u7684\u6a21\u5757\uff0c\u5b83\u5c01\u88c5\u4e86 Python \u4e2d\u53ef\u7528\u7684\u51e0\u4e4e\u6240\u6709\u4e0e Android \u7684\u63a5\u53e3\u3002\u4efb\u4f55\u5728 QPython \u4e2d\u5f00\u53d1\u7684\u811a\u672c\u90fd\u4ee5\u8fd9\u4e2a\u8bed\u53e5\u5f00\u5934\uff08\u81f3\u5c11\u5982\u679c\u5b83\u58f0\u79f0\u8981\u4e0e\u7528\u6237\u901a\u4fe1\u7684\u8bdd\uff09\u3002\u5728\u6b64\u5904\u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u5e93 \u548c import \u8bed\u53e5 \u7684\u5185\u5bb9\u3002

      \u63a5\u4e0b\u6765\u6211\u4eec\u521b\u5efa\u4e00\u4e2a droid \u5bf9\u8c61\uff08\u5b9e\u9645\u4e0a\u662f\u4e00\u4e2a\u7c7b\uff09\uff0c\u5b83\u5bf9\u4e8e\u8c03\u7528 RPC \u51fd\u6570\u4ee5\u4e0e Android \u901a\u4fe1\u662f\u5fc5\u8981\u7684\u3002

      \u6211\u4eec\u4ee3\u7801\u7684\u6700\u540e\u4e00\u884c\u8c03\u7528\u4e86\u8fd9\u6837\u7684\u51fd\u6570\uff0cdroid.makeToast()\uff0c\u5b83\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u4e00\u4e2a\u5c0f\u7684\u5f39\u51fa\u6d88\u606f\uff08\"toast\"\uff09\u3002

      \u597d\u7684\uff0c\u8ba9\u6211\u4eec\u6dfb\u52a0\u4e00\u4e9b\u66f4\u591a\u7684\u529f\u80fd\u3002\u8ba9\u5b83\u8be2\u95ee\u7528\u6237\u540d\u5e76\u5411\u7528\u6237\u6253\u62db\u547c\u3002

      "},{"location":"tutorial-hello-world/#_2","title":"\u66f4\u591a\u793a\u4f8b","text":"

      \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 dialogGetInput \u8c03\u7528\u663e\u793a\u4e00\u4e2a\u5e26\u6709\u6807\u9898\u3001\u63d0\u793a\u3001\u7f16\u8f91\u5b57\u6bb5\u548c \u786e\u5b9a \u548c \u53d6\u6d88 \u6309\u94ae\u7684\u7b80\u5355\u5bf9\u8bdd\u6846\u3002\u7528\u4ee5\u4e0b\u4ee3\u7801\u66ff\u6362\u60a8\u7684\u6700\u540e\u4e00\u884c\u4ee3\u7801\u5e76\u5c06\u5176\u4fdd\u5b58\u4e3a hello1.py\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\n

      \u597d\u7684\uff0c\u6211\u8ba4\u4e3a\u5b83\u5e94\u8be5\u8fd4\u56de\u4efb\u4f55\u54cd\u5e94\uff0c\u4efb\u4f55\u7528\u6237\u53cd\u5e94\u3002\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u6211\u5199 respond = ...\u3002\u4f46\u8fd9\u4e2a\u8c03\u7528\u5b9e\u9645\u4e0a\u8fd4\u56de\u4ec0\u4e48\uff1f\u8ba9\u6211\u4eec\u68c0\u67e5\u4e00\u4e0b\u3002\u53ea\u9700\u5728\u6700\u540e\u4e00\u884c\u540e\u6dfb\u52a0 print \u8bed\u53e5\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\n

      \u7136\u540e\u4fdd\u5b58\u5e76\u8fd0\u884c\u5b83...

      \u54ce\u5440\uff01\u6ca1\u6709\u6253\u5370\uff1f\u522b\u62c5\u5fc3\u3002\u53ea\u9700\u62c9\u4e0b\u901a\u77e5\u680f\uff0c\u60a8\u5c31\u4f1a\u770b\u5230\"QPython Program Output: hello1.py\"\u2014\u2014\u70b9\u51fb\u5b83\uff01

      \u5982\u60a8\u6240\u89c1\uff0cdroid.dialogGetInput() \u8fd4\u56de\u4e00\u4e2a\u5305\u542b\u4e09\u4e2a\u5b57\u6bb5\u7684 JSON \u5bf9\u8c61\u3002\u6211\u4eec\u53ea\u9700\u8981\u4e00\u4e2a\u2014\u2014result\uff0c\u5176\u4e2d\u5305\u542b\u7528\u6237\u5b9e\u9645\u8f93\u5165\u7684\u5185\u5bb9\u3002

      \u8ba9\u6211\u4eec\u6dfb\u52a0\u811a\u672c\u7684\u53cd\u5e94\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nmessage = f'Hello, {respond.result}!'\ndroid.makeToast(message)\n

      \u6700\u540e\u4e24\u884c\uff081\uff09\u683c\u5f0f\u5316\u6d88\u606f\uff0c\uff082\uff09\u4ee5 toast \u5f62\u5f0f\u5411\u7528\u6237\u663e\u793a\u6d88\u606f\u3002\u5982\u679c\u60a8\u4ecd\u7136\u4e0d\u77e5\u9053 f-string \u662f\u4ec0\u4e48\u610f\u601d\uff0c\u8bf7\u53c2\u9605 Python \u6587\u6863\u3002

      \u54c7\uff01\u5b83\u5de5\u4f5c\u4e86\uff01;)

      \u73b0\u5728\u6211\u8981\u5728\u90a3\u91cc\u6dfb\u52a0\u4e00\u4e9b\u903b\u8f91\u3002\u60f3\u4e00\u60f3\uff1a\u5982\u679c\u7528\u6237\u70b9\u51fb \u53d6\u6d88 \u6309\u94ae\uff0c\u6216\u8005\u70b9\u51fb \u786e\u5b9a \u4f46\u5c06\u8f93\u5165\u5b57\u6bb5\u7559\u7a7a\uff0c\u4f1a\u53d1\u751f\u4ec0\u4e48\uff1f

      \u60a8\u53ef\u4ee5\u73a9\u8fd9\u4e2a\u7a0b\u5e8f\uff0c\u68c0\u67e5 respond \u53d8\u91cf\u5728\u6bcf\u79cd\u60c5\u51b5\u4e0b\u5305\u542b\u4ec0\u4e48\u3002

      \u9996\u5148\uff0c\u6211\u60f3\u5c06\u7528\u6237\u8f93\u5165\u7684\u6587\u672c\u653e\u5165\u4e00\u4e2a\u5355\u72ec\u7684\u53d8\u91cf\u4e2d\uff1aname = respond.result\u3002\u7136\u540e\u6211\u68c0\u67e5\u5b83\uff0c\u5982\u679c\u5b83\u5305\u542b\u4efb\u4f55\u771f\u5b9e\u6587\u672c\uff0c\u5b83\u5c06\u88ab\u89c6\u4e3a\u540d\u79f0\u5e76\u7528\u4e8e\u95ee\u5019\u3002\u5426\u5219\uff0c\u5c06\u663e\u793a\u53e6\u4e00\u6761\u6d88\u606f\u3002\u5c06\u7b2c\u4e94\u884c message = f'Hello, {respond.result}!' \u66ff\u6362\u4e3a\u4ee5\u4e0b\u4ee3\u7801\uff1a

      name = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\n

      \u4f7f\u7528\u5de5\u5177\u680f\u4e0a\u7684 < \u548c > \u6309\u94ae\u6765\u7f29\u8fdb/\u53d6\u6d88\u7f29\u8fdb if \u8bed\u53e5\u4e2d\u7684\u884c\uff08\u6216\u8005\u53ea\u9700\u4f7f\u7528\u7a7a\u683c/\u9000\u683c\u952e\uff09\u3002\u60a8\u53ef\u4ee5\u5728 \u6b64\u5904 \u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u7f29\u8fdb\u7684\u5185\u5bb9\uff1bif \u8bed\u53e5\u5728 \u6b64\u5904 \u63cf\u8ff0\u3002

      \u9996\u5148\uff0c\u6211\u4eec\u5c06\u7528\u6237\u8f93\u5165\u653e\u5165 name \u53d8\u91cf\u3002\u7136\u540e\u6211\u4eec\u68c0\u67e5 name \u662f\u5426\u5305\u542b\u4efb\u4f55\u5185\u5bb9\uff1f\u5982\u679c\u7528\u6237\u7559\u7a7a\u884c\u5e76\u70b9\u51fb \u786e\u5b9a\uff0c\u8fd4\u56de\u503c\u662f\u7a7a\u5b57\u7b26\u4e32 ''\u3002\u5982\u679c\u6309\u4e0b\u4e86 \u53d6\u6d88 \u6309\u94ae\uff0c\u8fd4\u56de\u503c\u662f None\u3002\u5728 if \u8bed\u53e5\u4e2d\uff0c\u4e24\u8005\u90fd\u88ab\u89c6\u4e3a\u5047\u3002\u56e0\u6b64\uff0c\u53ea\u6709\u5f53 name \u5305\u542b\u4efb\u4f55\u6709\u610f\u4e49\u7684\u5185\u5bb9\u65f6\uff0cthen \u8bed\u53e5\u624d\u4f1a\u6267\u884c\uff0c\u5e76\u663e\u793a\u95ee\u5019\u8bed\"Hello, ...!\"\u3002\u5982\u679c\u8f93\u5165\u4e3a\u7a7a\uff0c\u7528\u6237\u5c06\u770b\u5230\"Hey! And you're not very polite, %Username%!\"\u6d88\u606f\u3002

      \u597d\u7684\uff0c\u8fd9\u662f\u6574\u4e2a\u7a0b\u5e8f\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nname = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\ndroid.makeToast(message)\n
      "},{"location":"tutorial-hello-world/#_3","title":"\u8fd0\u884c\u6548\u679c","text":""},{"location":"tutorial-hello-world/#_4","title":"\u4e0b\u4e00\u6b65","text":"

      \u5bf9\u4e8e Python \u65b0\u7528\u6237\uff0c\u63a8\u8350\u5b66\u4e60 Python \u8bed\u6cd5\u5b9e\u8df5 \u8bfe\u7a0b\u6765\u8fdb\u4e00\u6b65\u5b66\u4e60 Python\uff0c\u6216\u8005\u5728 QPython \u7cbe\u9009\u8bfe\u7a0b \u4e2d\u5bfb\u627e\u60f3\u8981\u5b66\u4e60\u7684\u5185\u5bb9\u3002

      "},{"location":"whats-new/","title":"\u66f4\u65b0\u65e5\u5fd7","text":""},{"location":"whats-new/#v392-v393","title":"v3.9.2 / v3.9.3","text":"
      • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
      • \u7f16\u8f91\u5668\u91cd\u5927\u66f4\u65b0\uff0c\u5e26\u6765\u66f4\u6d41\u7545\u7684\u7f16\u8f91\u4f53\u9a8c
      • \u5176\u4ed6\u5404\u79cd\u5c0f\u6539\u8fdb
      "},{"location":"whats-new/#v391","title":"v3.9.1","text":"
      • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
      • \u6269\u5c55\u5305\u73b0\u5728\u652f\u6301 MCP
      • \u9519\u8bef\u4fee\u590d
      "},{"location":"whats-new/#v390","title":"v3.9.0","text":"
      • SDK \u5347\u7ea7\uff0c\u6574\u5408\u6700\u65b0\u7684 Android \u529f\u80fd
      • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
      • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
      • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
      "},{"location":"whats-new/#v3811","title":"v3.8.11","text":"
      • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
      • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
      • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
      "},{"location":"whats-new/#v3810","title":"v3.8.10","text":"
      • \u5185\u7f6e Ollama \u5347\u7ea7\uff1a\u73b0\u5728\u60a8\u53ef\u4ee5\u5728 QPython \u4e2d\u8f7b\u677e\u672c\u5730\u8fd0\u884c Qwen3 / Gemma3 \u6a21\u578b\uff01
      • \u6dfb\u52a0\u4e86\u5f3a\u5927\u7684 MCP \u5e93\uff1a\u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 mcp \u5e93\uff0c\u8ba9\u60a8\u968f\u65f6\u968f\u5730\u643a\u5e26\u5f3a\u5927\u7684 MCP \u529f\u80fd\uff01
      "},{"location":"whats-new/#v389","title":"v3.8.9","text":"

      \u91cd\u5927\u66f4\u65b0\uff01AI \u7f16\u7a0b\u5b8c\u5168\u96c6\u6210\u5230 QPython\uff0c\u8ba9\u60a8\u7684\u7f16\u7a0b\u66f4\u8f7b\u677e\uff01

      • \u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u652f\u6301\uff1a\u65b0\u652f\u6301 AIPyApp\uff0c\u5728 QPython \u4e2d\u5b9e\u73b0\u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u3002\u76ee\u524d\u5904\u4e8e\u6d4b\u8bd5\u9636\u6bb5 - \u52a0\u5165\u6211\u4eec\u7684\u793e\u533a\u83b7\u53d6\u4f7f\u7528\u8bf4\u660e
      • \u65b0 QSL4A \u529f\u80fd\uff1a\u6dfb\u52a0 notebookOpen \u51fd\u6570\uff0c\u652f\u6301\u81ea\u7136\u8bed\u8a00\u63a7\u5236\u6253\u5f00 Notebook \u6587\u4ef6
      • \u5185\u7f6e\u7f16\u8f91\u5668\u5347\u7ea7\uff1a\u589e\u5f3a\u7f16\u8f91\u5668\u529f\u80fd\uff0c\u652f\u6301\u6253\u5f00\u548c\u6d4f\u89c8\u5404\u79cd\u6587\u672c\u6587\u4ef6
      • \u4fbf\u6377\u7684\u6587\u4ef6\u7ba1\u7406\uff1a\u5728\u6587\u4ef6\u7ba1\u7406\u5668\u4e2d\u6dfb\u52a0\u5185\u90e8\u5b58\u50a8\u5165\u53e3\uff0c\u5feb\u901f\u8bbf\u95ee\u60a8\u7684\u6587\u4ef6
      "},{"location":"whats-new/#v388","title":"v3.8.8","text":"
      • \u6587\u4ef6\u8bbf\u95ee\u6743\u9650\u63a7\u5236\u7684\u91cd\u8981\u6539\u8fdb\uff0c\u5141\u8bb8\u7528\u6237\u7075\u6d3b\u5730\u901a\u8fc7 QPython \u7f16\u7a0b\u542f\u7528\u6216\u7981\u7528\u5916\u90e8\u5b58\u50a8\u6587\u4ef6\u7684\u8bbf\u95ee
      • SDK \u5347\u7ea7\uff0c\u589e\u5f3a\u4e86\u5bf9\u65b0\u7248 Android \u7684\u652f\u6301\u548c\u517c\u5bb9\u6027
      • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Anthropic \u548c Google GenAI \u5e93
      "},{"location":"whats-new/#v387","title":"v3.8.7","text":"
      • \u5728\u73b0\u6709 Tkinter \u652f\u6301\u57fa\u7840\u4e0a\uff0c\u5728 Extensions -> Tools \u4e2d\u6dfb\u52a0\u4e86\u4f7f\u7528 Turtle \u7ed8\u5236\u54c6\u5566A\u68a6\u7684\u793a\u4f8b\u4ee3\u7801
      • \u4f18\u5316\u4e86\u624b\u673a\u6743\u9650\u83b7\u53d6\u6d41\u7a0b\uff0c\u63d0\u5347\u7528\u6237\u4f53\u9a8c\u548c\u64cd\u4f5c\u4fbf\u5229\u6027
      • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Google Gen AI \u5e93\uff0c\u65b9\u4fbf\u8bbf\u95ee Gemini Developer API \u548c Vertex AI
      "},{"location":"whats-new/#v386","title":"v3.8.6","text":"
      • Tkinter \u652f\u6301\uff1a\u73b0\u5728\u652f\u6301 Tkinter \u5e93\uff0c\u53ef\u901a\u8fc7 XServer \u8bbf\u95ee\u3002\u8bf7\u8bbf\u95ee www.qpython.org \u7684\u4e91\u76d8\"Extra\"\u94fe\u63a5\u4e0b\u8f7d\u6240\u9700\u6587\u4ef6
      • \u5b58\u50a8\u6743\u9650\u66f4\u65b0\uff1a\u4e3a\u6539\u5584\u7528\u6237\u4f53\u9a8c\uff0c\u6211\u4eec\u6dfb\u52a0\u4e86\u8bfb\u53d6\u624b\u673a\u5b58\u50a8\u7684\u6743\u9650\uff0c\u7528\u4e8e\u8bbf\u95ee\u5b58\u50a8\u5728\u5176\u4ed6\u76ee\u5f55\u4e2d\u7684 Python \u7a0b\u5e8f

      \u6b64\u66f4\u65b0\u540e\uff0cQPython \u548c QPythonPlus\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff0c\u4e13\u4e3a\u9700\u8981\u66f4\u591a\u654f\u611f\u6743\u9650\u7684\u9ad8\u7ea7\u7528\u6237\u8bbe\u8ba1\uff09\u5c06\u4fdd\u6301\u540c\u6b65\u7684\u7248\u672c\u53f7\u3002

      "},{"location":"whats-new/#v352-2025225","title":"v3.5.2 (2025/2/25)","text":"

      \u4e0e\u5f00\u6e90 LLM \u90e8\u7f72\u5de5\u5177 Ollama \u4ee5\u53ca DeepSeek \u5f00\u53d1\u7684 DeepSeek \u5b9e\u73b0\u65e0\u7f1d\u96c6\u6210\uff01

      \u529f\u80fd\uff1a - \u96f6\u95e8\u69db\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5404\u79cd\u5927\u578b\u8bed\u8a00\u6a21\u578b - \u5feb\u901f\u90e8\u7f72 DeepSeek \u7b49\u5c16\u7aef AI \u6a21\u578b - \u4eab\u53d7\u7b80\u7ea6\u7684 API \u8c03\u7528\u4f53\u9a8c - \u6784\u5efa\u5b8c\u5168\u79bb\u7ebf\u7684\u667a\u80fd\u7f16\u7a0b\u73af\u5883

      \u80fd\u529b\uff1a - \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u52a0\u8f7d/\u7ba1\u7406 LLM \u6a21\u578b - \u57fa\u4e8e\u672c\u5730\u8ba1\u7b97\u7684\u5b9e\u65f6\u4f4e\u5ef6\u8fdf\u54cd\u5e94

      "},{"location":"whats-new/#v350","title":"v3.5.0","text":"
      • Python \u5347\u7ea7\u5230 3.12.8
      • \u6539\u8fdb\u4eea\u8868\u76d8\uff0c\u529f\u80fd\u66f4\u6e05\u6670\u3001\u66f4\u4eba\u6027\u5316
      • \u6dfb\u52a0\u4e86\u4f17\u591a\u7b2c\u4e09\u65b9\u5305\uff1aPyTorch / Twisted / Scrapy / FastAPI ...
      "},{"location":"whats-new/#v338","title":"v3.3.8","text":"
      • \u4fee\u590d\u4e86 NumPy \u517c\u5bb9\u6027\u95ee\u9898
      "},{"location":"whats-new/#v335","title":"v3.3.5","text":"
      • \u5347\u7ea7 Python \u5185\u6838\u5230 3.11.9
      • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u4e0d\u663e\u793a\u6a21\u5757\u5b89\u88c5\u72b6\u6001\u7684 bug
      • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u5220\u9664\u6a21\u5757\u5931\u8d25\u7684 bug
      • \u4fee\u590d\u4e86\u5176\u4ed6 bug
      "},{"location":"whats-new/#v334","title":"v3.3.4","text":"
      • \u6dfb\u52a0\u4e86 OpenAI/Langchain/APIGPTCloud AI \u5305
      • \u79fb\u9664\u4e0d\u5fc5\u8981\u7684\u6587\u4ef6\u4ee5\u51cf\u5c11\u5927\u5c0f
      "},{"location":"whats-new/#v325","title":"v3.2.5","text":"
      • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570
      • \u5176\u4ed6\u9519\u8bef\u4fee\u590d
      "},{"location":"whats-new/#v323","title":"v3.2.3","text":"
      • \u66f4\u65b0 Python \u7248\u672c\u5230 3.11.0
      • \u66f4\u65b0 IPython \u7248\u672c\u5230 8.6.0
      • \u66f4\u65b0 pip \u7248\u672c\u5230 22.3.1
      • \u66f4\u65b0\u79d1\u5b66\u8ba1\u7b97\u5305\uff0c\u81ea\u52a8\u8f6f\u94fe\u63a5
      • \u51cf\u5c11\u7a7a\u95f4\u4f7f\u7528
      • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570 + \u5176\u4ed6\u9519\u8bef\u4fee\u590d
      "},{"location":"whats-new/#v318","title":"v3.1.8","text":"
      • \u5728\u7ec8\u7aef\u4e2d\u6dfb\u52a0\u4e86\u64cd\u4f5c\u70ed\u952e
      • \u4fee\u590d\u4e86\u7f16\u8f91\u5668\u5728\u65cb\u8f6c\u65f6\u4e22\u5931\u5185\u5bb9\u7684\u95ee\u9898
      • \u4fee\u590d\u4e86\u5176\u4ed6 bug

      \u5728 Google Play \u4e0b\u8f7d

      "},{"location":"qsl4a/","title":"QSL4A\uff08Android \u811a\u672c\u5c42\uff09API \u6587\u6863","text":"

      QSL4A \u662f QPython \u7684 Android \u811a\u672c\u5c42\uff0c\u5141\u8bb8\u60a8\u4f7f\u7528 Python \u63a7\u5236 Android \u8bbe\u5907\u529f\u80fd\u3002

      "},{"location":"qsl4a/#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a toast \u6d88\u606f\ndroid.makeToast('Hello QPython!')\n\n# \u9707\u52a8\u8bbe\u5907\ndroid.vibrate(500)\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\uff08\u5148\u5f00\u59cb\u76d1\u63a7\uff09\nimport time\ndroid.batteryStartMonitoring()\ntime.sleep(0.5)  # \u7b49\u5f85\u6570\u636e\nbattery = droid.readBatteryData().result\nprint(f\"\u7535\u6c60\uff1a{battery['level']}%\")\n
      "},{"location":"qsl4a/#_2","title":"\u6587\u6863\u7ed3\u6784","text":""},{"location":"qsl4a/#_3","title":"\u6838\u5fc3\u6a21\u5757","text":"
      • Android \u57fa\u7840 - \u6838\u5fc3\u8fde\u63a5\u548c RPC
      • Intent \u7cfb\u7edf - Android Intent \u64cd\u4f5c
      • \u4e8b\u4ef6\u7cfb\u7edf - \u4e8b\u4ef6\u5904\u7406\u548c\u5e7f\u64ad
      "},{"location":"qsl4a/#ui","title":"UI \u7ec4\u4ef6","text":"
      • \u5bf9\u8bdd\u6846 - \u8b66\u62a5\u3001\u8f93\u5165\u3001\u9009\u62e9\u5bf9\u8bdd\u6846
      • \u5168\u5c4f UI - \u81ea\u5b9a\u4e49\u5e03\u5c40 UI
      • \u60ac\u6d6e\u7a97 - \u60ac\u6d6e\u7a97\u53e3
      • \u8f85\u52a9\u529f\u80fd - \u5c4f\u5e55\u81ea\u52a8\u5316
      "},{"location":"qsl4a/#_4","title":"\u7cfb\u7edf","text":"
      • \u7535\u6c60 - \u7535\u6c60\u76d1\u63a7
      • \u4f20\u611f\u5668 - \u8bbe\u5907\u4f20\u611f\u5668
      • \u5e94\u7528 - \u5e94\u7528\u7ba1\u7406
      • \u7cfb\u7edf\u4fe1\u606f - \u8bbe\u5907\u4fe1\u606f
      • \u8bbe\u7f6e - \u7cfb\u7edf\u8bbe\u7f6e
      • \u5524\u9192\u9501 - \u5524\u9192\u9501\u63a7\u5236
      • QPython \u63a5\u53e3 - \u811a\u672c\u6267\u884c
      • Activity \u7ed3\u679c - Activity \u7ed3\u679c\u5904\u7406
      "},{"location":"qsl4a/#_5","title":"\u786c\u4ef6","text":"
      • \u84dd\u7259 - \u84dd\u7259\u64cd\u4f5c
      • \u76f8\u673a - \u62cd\u7167\u548c\u5f55\u50cf
      • \u97f3\u9891/\u5f55\u97f3\u5668 - \u5f55\u97f3
      • \u7f51\u7edc\u6444\u50cf\u5934 - MJPEG \u6d41
      • USB \u4e32\u53e3 - USB \u4e3b\u673a\u4e32\u53e3
      "},{"location":"qsl4a/#_6","title":"\u8fde\u63a5","text":"
      • WiFi - WiFi \u64cd\u4f5c
      • \u4f4d\u7f6e - GPS \u548c\u4f4d\u7f6e
      • \u77ed\u4fe1 - \u77ed\u4fe1\u64cd\u4f5c
      • \u7535\u8bdd - \u6253\u7535\u8bdd\u548c\u6765\u7535\u4fe1\u606f
      • \u8054\u7cfb\u4eba - \u8054\u7cfb\u4eba\u7ba1\u7406
      • \u4fe1\u53f7\u5f3a\u5ea6 - \u4fe1\u53f7\u76d1\u63a7
      • FTP \u670d\u52a1\u5668 - \u5185\u7f6e FTP \u670d\u52a1\u5668
      "},{"location":"qsl4a/#_7","title":"\u5b58\u50a8","text":"
      • DocumentFile - \u6587\u4ef6\u64cd\u4f5c
      • \u526a\u8d34\u677f - \u526a\u8d34\u677f\u64cd\u4f5c
      • \u504f\u597d\u8bbe\u7f6e - \u5171\u4eab\u504f\u597d\u8bbe\u7f6e
      "},{"location":"qsl4a/#_8","title":"\u5a92\u4f53","text":"
      • \u5a92\u4f53\u64ad\u653e\u5668 - \u97f3\u9891/\u89c6\u9891\u64ad\u653e
      • \u56fe\u50cf\u5904\u7406 - \u56fe\u50cf\u64cd\u4f5c
      "},{"location":"qsl4a/#_9","title":"\u7279\u6b8a\u529f\u80fd","text":"
      • \u52a0\u5bc6 - \u52a0\u5bc6/\u89e3\u5bc6
      • PGPT AI - AI \u8bed\u97f3\u670d\u52a1
      "},{"location":"qsl4a/#_10","title":"\u7ed3\u679c\u5bf9\u8c61","text":"

      \u5927\u591a\u6570 QSL4A \u65b9\u6cd5\u8fd4\u56de\u4e00\u4e2a\u5e26\u6709\u4ee5\u4e0b\u5c5e\u6027\u7684 Result \u547d\u540d\u5143\u7ec4\uff1a - id - \u8bf7\u6c42 ID - result - \u5b9e\u9645\u7ed3\u679c\u6570\u636e - error - \u5982\u679c\u5931\u8d25\u5219\u4e3a\u9519\u8bef\u6d88\u606f

      result = droid.getClipboard()\nif result.error is None:\n    print(result.result)\nelse:\n    print(f\"\u9519\u8bef\uff1a{result.error}\")\n
      "},{"location":"qsl4a/connectivity/contacts/","title":"\u8054\u7cfb\u4eba API","text":"

      \u8bbf\u95ee\u548c\u7ba1\u7406\u8bbe\u5907\u8054\u7cfb\u4eba\u3002

      "},{"location":"qsl4a/connectivity/contacts/#_1","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":""},{"location":"qsl4a/connectivity/contacts/#pickcontact","title":"pickContact()","text":"

      \u663e\u793a\u8054\u7cfb\u4eba\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

      pickContact()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u8054\u7cfb\u4eba URI \u7684 Intent

      "},{"location":"qsl4a/connectivity/contacts/#pickphone","title":"pickPhone()","text":"

      \u663e\u793a\u7535\u8bdd\u53f7\u7801\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

      pickPhone()\n

      \u8fd4\u56de\uff1a \u9009\u4e2d\u7684\u7535\u8bdd\u53f7\u7801\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/contacts/#_2","title":"\u8054\u7cfb\u4eba\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#contactsget","title":"contactsGet()","text":"

      \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\u3002

      contactsGet(attributes=None)\n

      \u53c2\u6570\uff1a - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

      \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba JSONObject \u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetbyid","title":"contactsGetById()","text":"

      \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\u3002

      contactsGetById(id, attributes=None)\n

      \u53c2\u6570\uff1a - id (int): \u8054\u7cfb\u4eba ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

      \u8fd4\u56de\uff1a JSONObject \u8054\u7cfb\u4eba\u6570\u636e

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetcount","title":"contactsGetCount()","text":"

      \u83b7\u53d6\u8054\u7cfb\u4eba\u603b\u6570\u3002

      contactsGetCount()\n

      \u8fd4\u56de\uff1a \u6574\u6570\u8ba1\u6570

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetids","title":"contactsGetIds()","text":"

      \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba ID\u3002

      contactsGetIds()\n

      \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba ID \u6574\u6570\u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetattributes","title":"contactsGetAttributes()","text":"

      \u83b7\u53d6\u6240\u6709\u53ef\u80fd\u7684\u8054\u7cfb\u4eba\u5c5e\u6027\u3002

      contactsGetAttributes()\n

      \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#_3","title":"\u5185\u5bb9\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#querycontent","title":"queryContent()","text":"

      \u4f7f\u7528\u81ea\u5b9a\u4e49\u53c2\u6570\u67e5\u8be2\u5185\u5bb9\u89e3\u6790\u5668\u3002

      queryContent(uri, attributes=None, selection=None, selectionArgs=None, order=None)\n

      \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u5c5e\u6027 - selection (str, optional): WHERE \u5b50\u53e5 - selectionArgs (list, optional): \u9009\u62e9\u53c2\u6570 - order (str, optional): ORDER BY \u5b50\u53e5

      \u8fd4\u56de\uff1a JSONObject \u7ed3\u679c\u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#queryattributes","title":"queryAttributes()","text":"

      \u83b7\u53d6\u5185\u5bb9 URI \u7684\u5c5e\u6027\u3002

      queryAttributes(uri)\n

      \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI

      \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u7684 JSONArray

      "},{"location":"qsl4a/connectivity/contacts/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u9009\u62e9\u8054\u7cfb\u4eba\ncontact_uri = droid.pickContact().result\nprint(f\"Selected contact: {contact_uri}\")\n\n# \u9009\u62e9\u7535\u8bdd\u53f7\u7801\nphone = droid.pickPhone().result\nprint(f\"Selected phone: {phone}\")\n\n# \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\ncontacts = droid.contactsGet().result\nprint(f\"Total contacts: {len(contacts)}\")\n\n# \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\ncontact = droid.contactsGetById(1).result\nprint(f\"Contact: {contact}\")\n\n# \u83b7\u53d6\u8054\u7cfb\u4eba\u5c5e\u6027\nattrs = droid.contactsGetAttributes().result\nprint(f\"Available attributes: {attrs}\")\n
      "},{"location":"qsl4a/connectivity/ftp/","title":"FTP \u670d\u52a1\u5668 API","text":"

      \u5728\u8bbe\u5907\u4e0a\u542f\u52a8\u548c\u7ba1\u7406\u5185\u7f6e FTP \u670d\u52a1\u5668\u3002

      "},{"location":"qsl4a/connectivity/ftp/#ftp","title":"FTP \u670d\u52a1\u5668\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/ftp/#ftpstart","title":"ftpStart()","text":"

      \u542f\u52a8 FTP \u670d\u52a1\u5668\u3002

      ftpStart()\n

      \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4 [ip, port]

      "},{"location":"qsl4a/connectivity/ftp/#ftpstop","title":"ftpStop()","text":"

      \u505c\u6b62 FTP \u670d\u52a1\u5668\u3002

      ftpStop()\n
      "},{"location":"qsl4a/connectivity/ftp/#ftpisrunning","title":"ftpIsRunning()","text":"

      \u68c0\u67e5 FTP \u670d\u52a1\u5668\u662f\u5426\u6b63\u5728\u8fd0\u884c\u3002

      ftpIsRunning()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u8fd0\u884c\u5219\u4e3a True

      "},{"location":"qsl4a/connectivity/ftp/#ftpget","title":"ftpGet()","text":"

      \u83b7\u53d6 FTP \u670d\u52a1\u5668 IP \u5730\u5740\u3002

      ftpGet()\n

      \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4

      "},{"location":"qsl4a/connectivity/ftp/#ftpset","title":"ftpSet()","text":"

      \u914d\u7f6e FTP \u670d\u52a1\u5668\u8bbe\u7f6e\u3002

      ftpSet(port=None, rootDir=None, username=None, password=None)\n

      \u53c2\u6570\uff1a - port (int, optional): \u670d\u52a1\u5668\u7aef\u53e3 - rootDir (str, optional): \u8981\u670d\u52a1\u7684\u57fa\u7840\u76ee\u5f55 - username (str, optional): \u767b\u5f55\u7528\u6237\u540d - password (str, optional): \u767b\u5f55\u5bc6\u7801

      \u8fd4\u56de\uff1a \u5305\u542b\u5f53\u524d\u8bbe\u7f6e\u7684 JSONObject

      "},{"location":"qsl4a/connectivity/ftp/#ftpstatus","title":"ftpStatus()","text":"

      \u83b7\u53d6 FTP \u670d\u52a1\u5668\u72b6\u6001\u3002

      ftpStatus()\n

      \u8fd4\u56de\uff1a \u72b6\u6001\u63cf\u8ff0\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/ftp/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u914d\u7f6e FTP \u670d\u52a1\u5668\ndroid.ftpSet(\n    port=2121,\n    rootDir=\"/sdcard\",\n    username=\"admin\",\n    password=\"secret\"\n)\n\n# \u542f\u52a8 FTP \u670d\u52a1\u5668\ninfo = droid.ftpStart().result\nprint(f\"FTP running at {info[0]}:{info[1]}\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.ftpIsRunning().result:\n    print(\"FTP server is running\")\n\n# \u83b7\u53d6\u670d\u52a1\u5668\u4fe1\u606f\nserver_info = droid.ftpGet().result\nprint(f\"Server: {server_info}\")\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.ftpStop()\n

      \u6ce8\u610f\uff1a \u4f7f\u7528\u63d0\u4f9b\u7684\u51ed\u636e\u901a\u8fc7\u4efb\u4f55 FTP \u5ba2\u6237\u7aef\u8fde\u63a5\u5230 FTP \u670d\u52a1\u5668\u3002

      "},{"location":"qsl4a/connectivity/location/","title":"\u4f4d\u7f6e API","text":"

      \u8bbf\u95ee GPS \u548c\u7f51\u7edc\u4f4d\u7f6e\u670d\u52a1\u3002

      "},{"location":"qsl4a/connectivity/location/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/location/#startlocating","title":"startLocating()","text":"

      \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\u3002

      startLocating(minUpdateTime=60000, minUpdateDistance=30, updateGnssStatus=False)\n

      \u53c2\u6570\uff1a - minUpdateTime (int): \u66f4\u65b0\u4e4b\u95f4\u7684\u6700\u5c0f\u65f6\u95f4\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a60000\uff09 - minUpdateDistance (float): \u66f4\u65b0\u7684\u6700\u5c0f\u8ddd\u79bb\uff08\u7c73\uff09\uff08\u9ed8\u8ba4\uff1a30\uff09 - updateGnssStatus (bool): \u542f\u7528 GNSS \u72b6\u6001\u66f4\u65b0\uff08\u9ed8\u8ba4\uff1aFalse\uff09

      "},{"location":"qsl4a/connectivity/location/#stoplocating","title":"stopLocating()","text":"

      \u505c\u6b62\u4f4d\u7f6e\u66f4\u65b0\u3002

      stopLocating()\n
      "},{"location":"qsl4a/connectivity/location/#readlocation","title":"readLocation()","text":"

      \u83b7\u53d6\u6700\u540e\u5df2\u77e5\u4f4d\u7f6e\u3002

      readLocation()\n

      \u8fd4\u56de\uff1a \u4f4d\u7f6e\u6570\u636e\u5b57\u5178

      "},{"location":"qsl4a/connectivity/location/#getlastknownlocation","title":"getLastKnownLocation()","text":"

      \u83b7\u53d6\u7f13\u5b58\u7684\u4f4d\u7f6e\u3002

      getLastKnownLocation()\n

      \u8fd4\u56de\uff1a \u6765\u81ea\u6240\u6709\u63d0\u4f9b\u5546\u7684\u4f4d\u7f6e

      "},{"location":"qsl4a/connectivity/location/#geocode","title":"geocode()","text":"

      \u5c06\u5730\u5740\u8f6c\u6362\u4e3a\u5750\u6807\u3002

      geocode(address, maxResults=1)\n
      "},{"location":"qsl4a/connectivity/location/#_2","title":"\u4f4d\u7f6e\u63d0\u4f9b\u5546\u65b9\u6cd5)","text":""},{"location":"qsl4a/connectivity/location/#locationproviders","title":"locationProviders()","text":"

      \u83b7\u53d6\u624b\u673a\u4e0a\u53ef\u7528\u7684\u4f4d\u7f6e\u63d0\u4f9b\u5546\u3002

      locationProviders()\n

      \u8fd4\u56de\uff1a \u53ef\u7528\u63d0\u4f9b\u5546\u540d\u79f0\u5217\u8868\uff08\u4f8b\u5982 ['gps', 'network']\uff09

      "},{"location":"qsl4a/connectivity/location/#locationproviderenabled","title":"locationProviderEnabled()","text":"

      \u68c0\u67e5\u7279\u5b9a\u4f4d\u7f6e\u63d0\u4f9b\u5546\u662f\u5426\u5df2\u542f\u7528\u3002

      locationProviderEnabled(provider)\n

      \u53c2\u6570\uff1a - provider (str): \u63d0\u4f9b\u5546\u540d\u79f0\uff08\u4f8b\u5982 'gps', 'network'\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/connectivity/location/#readgnssstatus","title":"readGnssStatus()","text":"

      \u8bfb\u53d6\u5168\u7403\u5bfc\u822a\u536b\u661f\u7cfb\u7edf\u72b6\u6001\uff08\u9700\u8981 Android 8+\uff09\u3002

      readGnssStatus()\n

      \u8fd4\u56de\uff1a \u5305\u542b GNSS \u536b\u661f\u4fe1\u606f\u7684 JSONArray

      "},{"location":"qsl4a/connectivity/location/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\ndroid.startLocating(minUpdateTime=5000, minUpdateDistance=1, updateGnssStatus=False)\n\n# \u7b49\u5f85\u5b9a\u4f4d\ntime.sleep(10)\n\n# \u83b7\u53d6\u4f4d\u7f6e\nloc = droid.readLocation().result\nif loc:\n    lat = loc['latitude']\n    lon = loc['longitude']\n    print(f\"Location: {lat}, {lon}\")\n\ndroid.stopLocating()\n
      "},{"location":"qsl4a/connectivity/phone/","title":"\u7535\u8bdd API","text":"

      \u63a7\u5236\u7535\u8bdd\u901a\u8bdd\u548c\u83b7\u53d6\u7535\u8bdd\u4fe1\u606f\u3002

      "},{"location":"qsl4a/connectivity/phone/#_1","title":"\u7535\u8bdd\u72b6\u6001\u8ddf\u8e2a","text":""},{"location":"qsl4a/connectivity/phone/#starttrackingphonestate","title":"startTrackingPhoneState()","text":"

      \u5f00\u59cb\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u53d8\u5316\u3002\u751f\u6210 'phone' \u4e8b\u4ef6\u3002

      startTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/phone/#readphonestate","title":"readPhoneState()","text":"

      \u8bfb\u53d6\u5f53\u524d\u7535\u8bdd\u72b6\u6001\u3002

      readPhoneState()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7535\u8bdd\u72b6\u6001\u548c\u6765\u7535\u53f7\u7801\u7684 Bundle

      "},{"location":"qsl4a/connectivity/phone/#stoptrackingphonestate","title":"stopTrackingPhoneState()","text":"

      \u505c\u6b62\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u3002

      stopTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/phone/#_2","title":"\u62e8\u6253\u7535\u8bdd","text":""},{"location":"qsl4a/connectivity/phone/#phonecall","title":"phoneCall()","text":"

      \u901a\u8fc7 URI \u547c\u53eb\u8054\u7cfb\u4eba/\u7535\u8bdd\u53f7\u7801\u3002

      phoneCall(uri)\n

      \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

      "},{"location":"qsl4a/connectivity/phone/#phonecallnumber","title":"phoneCallNumber()","text":"

      \u76f4\u63a5\u62e8\u6253\u7535\u8bdd\u53f7\u7801\u3002

      phoneCallNumber(phone_number)\n

      \u53c2\u6570\uff1a - phone_number (str): \u8981\u62e8\u6253\u7684\u7535\u8bdd\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#phonedial","title":"phoneDial()","text":"

      \u62e8\u6253\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

      phoneDial(uri)\n

      \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

      "},{"location":"qsl4a/connectivity/phone/#phonedialnumber","title":"phoneDialNumber()","text":"

      \u62e8\u6253\u7535\u8bdd\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

      phoneDialNumber(phone_number)\n

      \u53c2\u6570\uff1a - phone_number (str): \u7535\u8bdd\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#_3","title":"\u57fa\u7ad9\u4f4d\u7f6e","text":""},{"location":"qsl4a/connectivity/phone/#getcelllocation","title":"getCellLocation()","text":"

      \u83b7\u53d6\u5f53\u524d\u57fa\u7ad9\u4f4d\u7f6e\u3002

      getCellLocation()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u57fa\u7ad9\u4f4d\u7f6e\u6570\u636e\u7684 JSONObject

      "},{"location":"qsl4a/connectivity/phone/#getallcellslocation","title":"getAllCellsLocation()","text":"

      \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u4f4d\u7f6e\uff08\u9002\u7528\u4e8e\u53cc\u5361\u8bbe\u5907\uff09\u3002

      getAllCellsLocation()\n

      \u8fd4\u56de\uff1a \u57fa\u7ad9\u4f4d\u7f6e\u7684 JSONArray

      "},{"location":"qsl4a/connectivity/phone/#_4","title":"\u7f51\u7edc\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getnetworkoperator","title":"getNetworkOperator()","text":"

      \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

      getNetworkOperator()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getnetworkoperatorname","title":"getNetworkOperatorName()","text":"

      \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684\u540d\u79f0\u3002

      getNetworkOperatorName()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getnetworktype","title":"getNetworkType()","text":"

      \u83b7\u53d6\u5f53\u524d\u7f51\u7edc\u7c7b\u578b\u3002

      getNetworkType()\n

      \u8fd4\u56de\uff1a \u63cf\u8ff0\u65e0\u7ebf\u7535\u6280\u672f\u7684\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'LTE', 'UMTS', 'GSM'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getphonetype","title":"getPhoneType()","text":"

      \u83b7\u53d6\u7535\u8bdd\u7c7b\u578b\u3002

      getPhoneType()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'GSM', 'CDMA', 'SIP'\uff09

      "},{"location":"qsl4a/connectivity/phone/#sim","title":"SIM \u5361\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getsimcountryiso","title":"getSimCountryIso()","text":"

      \u83b7\u53d6 SIM \u5361\u7684 ISO \u56fd\u5bb6\u4ee3\u7801\u3002

      getSimCountryIso()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'us'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getsimoperator","title":"getSimOperator()","text":"

      \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

      getSimOperator()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getsimoperatorname","title":"getSimOperatorName()","text":"

      \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u540d\u79f0\u3002

      getSimOperatorName()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getsimserialnumber","title":"getSimSerialNumber()","text":"

      \u83b7\u53d6 SIM \u5e8f\u5217\u53f7\u3002

      getSimSerialNumber()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32 SIM \u5e8f\u5217\u53f7

      "},{"location":"qsl4a/connectivity/phone/#getsimstate","title":"getSimState()","text":"

      \u83b7\u53d6 SIM \u5361\u72b6\u6001\u3002

      getSimState()\n

      \u8fd4\u56de\uff1a \u63cf\u8ff0 SIM \u72b6\u6001\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/phone/#getsubscriberid","title":"getSubscriberId()","text":"

      \u83b7\u53d6\u8ba2\u9605\u8005 ID\u3002

      getSubscriberId()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8ba2\u9605\u8005 ID

      "},{"location":"qsl4a/connectivity/phone/#_5","title":"\u8bed\u97f3\u90ae\u4ef6","text":""},{"location":"qsl4a/connectivity/phone/#getvoicemailalphatag","title":"getVoiceMailAlphaTag()","text":"

      \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u5b57\u6bcd\u6807\u7b7e\u3002

      getVoiceMailAlphaTag()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u6807\u7b7e

      "},{"location":"qsl4a/connectivity/phone/#getvoicemailnumber","title":"getVoiceMailNumber()","text":"

      \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801\u3002

      getVoiceMailNumber()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getdeviceid","title":"getDeviceId()","text":"

      \u83b7\u53d6\u8bbe\u5907 ID\uff08GSM \u7684 IMEI\uff09\u3002\u5df2\u5e9f\u5f03\u3002

      getDeviceId()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

      "},{"location":"qsl4a/connectivity/phone/#getdevicesoftwareversion","title":"getDeviceSoftwareVersion()","text":"

      \u83b7\u53d6\u8bbe\u5907\u8f6f\u4ef6\u7248\u672c\u3002

      getDeviceSoftwareVersion()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8f6f\u4ef6\u7248\u672c

      "},{"location":"qsl4a/connectivity/phone/#getline1number","title":"getLine1Number()","text":"

      \u83b7\u53d6\u7ebf\u8def 1 \u7535\u8bdd\u53f7\u7801\u3002

      getLine1Number()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u7535\u8bdd\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#checknetworkroaming","title":"checkNetworkRoaming()","text":"

      \u68c0\u67e5\u662f\u5426\u8fde\u63a5\u5230\u6f2b\u6e38\u7f51\u7edc\u3002

      checkNetworkRoaming()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u6f2b\u6e38\u5219\u4e3a True

      "},{"location":"qsl4a/connectivity/phone/#_7","title":"\u57fa\u7ad9\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getallcellinfo","title":"getAllCellInfo()","text":"

      \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u7684\u4fe1\u606f\u3002

      getAllCellInfo()\n

      \u8fd4\u56de\uff1a \u57fa\u7ad9\u4fe1\u606f\u5217\u8868

      "},{"location":"qsl4a/connectivity/phone/#setdataenabled","title":"setDataEnabled()","text":"

      \u542f\u7528\u6216\u7981\u7528\u79fb\u52a8\u6570\u636e\u3002

      setDataEnabled(enabled)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528

      "},{"location":"qsl4a/connectivity/phone/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7f51\u7edc\u4fe1\u606f\noperator = droid.getNetworkOperatorName().result\nprint(f\"Operator: {operator}\")\n\nnetwork_type = droid.getNetworkType().result\nprint(f\"Network: {network_type}\")\n\n# \u83b7\u53d6 SIM \u4fe1\u606f\nsim_state = droid.getSimState().result\nprint(f\"SIM: {sim_state}\")\n\n# \u83b7\u53d6\u7535\u8bdd\u53f7\u7801\nline1 = droid.getLine1Number().result\nprint(f\"Phone: {line1}\")\n\n# \u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\ndroid.startTrackingPhoneState()\nprint(\"Tracking phone state...\")\ndroid.stopTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/signalstrength/","title":"\u4fe1\u53f7\u5f3a\u5ea6 API","text":"

      \u76d1\u63a7\u8702\u7a9d\u548c\u65e0\u7ebf\u4fe1\u53f7\u5f3a\u5ea6\u3002

      "},{"location":"qsl4a/connectivity/signalstrength/#_1","title":"\u4fe1\u53f7\u5f3a\u5ea6\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/signalstrength/#starttrackingsignalstrengths","title":"startTrackingSignalStrengths()","text":"

      \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316\u3002\u751f\u6210 'signal_strengths' \u4e8b\u4ef6\u3002

      startTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/signalstrength/#stoptrackingsignalstrengths","title":"stopTrackingSignalStrengths()","text":"

      \u505c\u6b62\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u3002

      stopTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/signalstrength/#readsignalstrengths","title":"readSignalStrengths()","text":"

      \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\u3002

      readSignalStrengths()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u4fe1\u53f7\u5f3a\u5ea6\u6570\u636e\u7684 Bundle

      "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthlevel","title":"getTelephoneSignalStrengthLevel()","text":"

      \u83b7\u53d6\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u7b49\u7ea7\uff080-4\uff09\u3002

      getTelephoneSignalStrengthLevel()\n

      \u8fd4\u56de\uff1a \u6574\u6570\u7b49\u7ea7\uff080=\u65e0\uff0c1=\u5dee\uff0c2=\u4e00\u822c\uff0c3=\u597d\uff0c4=\u4f18\u79c0\uff09

      "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthdetail","title":"getTelephoneSignalStrengthDetail()","text":"

      \u83b7\u53d6\u8be6\u7ec6\u7684\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u4fe1\u606f\u3002

      getTelephoneSignalStrengthDetail()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u8be6\u7ec6\u4fe1\u53f7\u4fe1\u606f\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/signalstrength/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\ndroid.startTrackingSignalStrengths()\n\n# \u7b49\u5f85\u4fe1\u53f7\u66f4\u65b0\ntime.sleep(5)\n\n# \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\nsignal = droid.readSignalStrengths().result\nprint(f\"Signal: {signal}\")\n\n# \u76f4\u63a5\u83b7\u53d6\u7b49\u7ea7\nlevel = droid.getTelephoneSignalStrengthLevel().result\nprint(f\"Signal level: {level}/4\")\n\ndroid.stopTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/sms/","title":"SMS API","text":"

      \u53d1\u9001\u548c\u63a5\u6536 SMS \u6d88\u606f\u3002

      "},{"location":"qsl4a/connectivity/sms/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/sms/#smssend","title":"smsSend()","text":"

      \u53d1\u9001 SMS \u6d88\u606f\u3002

      smsSend(destinationAddress, text)\n

      \u53c2\u6570\uff1a - destinationAddress (str): \u7535\u8bdd\u53f7\u7801 - text (str): \u6d88\u606f\u6587\u672c

      "},{"location":"qsl4a/connectivity/sms/#smsgetmessagecount","title":"smsGetMessageCount()","text":"

      \u83b7\u53d6\u6d88\u606f\u6570\u91cf\u3002

      smsGetMessageCount(unreadOnly=False, folder=\"inbox\")\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessageids","title":"smsGetMessageIds()","text":"

      \u83b7\u53d6\u6d88\u606f ID\u3002

      smsGetMessageIds(unreadOnly=False, folder=\"inbox\")\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessages","title":"smsGetMessages()","text":"

      \u83b7\u53d6\u6d88\u606f\u8be6\u60c5\u3002

      smsGetMessages(unreadOnly=False, folder=\"inbox\", attributes=None)\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessagebyid","title":"smsGetMessageById()","text":"

      \u901a\u8fc7 ID \u83b7\u53d6\u7279\u5b9a\u6d88\u606f\u3002

      smsGetMessageById(id, attributes=None)\n

      \u53c2\u6570\uff1a - id (int): \u6d88\u606f ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

      \u8fd4\u56de\uff1a \u6d88\u606f\u6570\u636e\u5b57\u5178

      "},{"location":"qsl4a/connectivity/sms/#smsgetattributes","title":"smsGetAttributes()","text":"

      \u83b7\u53d6\u53ef\u7528\u7684 SMS \u6d88\u606f\u5c5e\u6027\u3002

      smsGetAttributes()\n

      \u8fd4\u56de\uff1a \u53ef\u7528\u5c5e\u6027\u540d\u79f0\u5217\u8868

      "},{"location":"qsl4a/connectivity/sms/#smsdeletemessage","title":"smsDeleteMessage()","text":"

      \u5220\u9664\u6d88\u606f\u3002

      smsDeleteMessage(id)\n
      "},{"location":"qsl4a/connectivity/sms/#smsmarkmessageread","title":"smsMarkMessageRead()","text":"

      \u5c06\u6d88\u606f\u6807\u8bb0\u4e3a\u5df2\u8bfb\u3002

      smsMarkMessageRead(ids, read=True)\n
      "},{"location":"qsl4a/connectivity/sms/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u53d1\u9001 SMS\ndroid.smsSend(\"+1234567890\", \"Hello from QPython!\")\n\n# \u83b7\u53d6\u672a\u8bfb\u6d88\u606f\nmessages = droid.smsGetMessages(unreadOnly=True).result\nfor msg in messages:\n    print(f\"From: {msg['address']}, Text: {msg['body']}\")\n
      "},{"location":"qsl4a/connectivity/wifi/","title":"WiFi API","text":"

      \u63a7\u5236 WiFi \u9002\u914d\u5668\u5e76\u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\u3002

      "},{"location":"qsl4a/connectivity/wifi/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/connectivity/wifi/#checkwifistate","title":"checkWifiState()","text":"

      \u68c0\u67e5 WiFi \u662f\u5426\u5df2\u542f\u7528\u3002

      checkWifiState()\n

      \u8fd4\u56de\uff1a \u5982\u679c WiFi \u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/connectivity/wifi/#togglewifistate","title":"toggleWifiState()","text":"

      \u6253\u5f00\u6216\u5173\u95ed WiFi\u3002

      toggleWifiState(enabled=None)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

      \u8fd4\u56de\uff1a \u5982\u679c\u64cd\u4f5c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/connectivity/wifi/#wifistartscan","title":"wifiStartScan()","text":"

      \u5f00\u59cb\u626b\u63cf\u53ef\u7528\u7684 WiFi \u7f51\u7edc\u3002

      wifiStartScan()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifigetscanresults","title":"wifiGetScanResults()","text":"

      \u83b7\u53d6\u53d1\u73b0\u7684 WiFi \u7f51\u7edc\u5217\u8868\u3002

      wifiGetScanResults()\n

      \u8fd4\u56de\uff1a \u63a5\u5165\u70b9\u4fe1\u606f\u5217\u8868

      "},{"location":"qsl4a/connectivity/wifi/#_2","title":"\u8fde\u63a5\u7ba1\u7406","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetconnectioninfo","title":"wifiGetConnectionInfo()","text":"

      \u83b7\u53d6\u8be6\u7ec6\u8fde\u63a5\u4fe1\u606f\u3002

      wifiGetConnectionInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001IP \u5730\u5740\u7b49\u8fde\u63a5\u8be6\u60c5\u7684\u5b57\u5178

      "},{"location":"qsl4a/connectivity/wifi/#getconnectedinfo","title":"getConnectedInfo()","text":"

      \u83b7\u53d6\u8fde\u63a5\u7684 WiFi \u7f51\u7edc\u4fe1\u606f\uff08\u7b80\u5316\u7248\uff09\u3002

      getConnectedInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001\u4fe1\u53f7\u5f3a\u5ea6\u7684\u5b57\u5178

      "},{"location":"qsl4a/connectivity/wifi/#getdhcpinfo","title":"getDhcpInfo()","text":"

      \u83b7\u53d6\u5f53\u524d\u8fde\u63a5\u7684 DHCP \u4fe1\u606f\u3002

      getDhcpInfo(ipConvertToString=True)\n

      \u53c2\u6570\uff1a - ipConvertToString (bool): \u5c06 IP \u5730\u5740\u8f6c\u6362\u4e3a\u5b57\u7b26\u4e32\u683c\u5f0f\uff08\u9ed8\u8ba4\uff1aTrue\uff09

      \u8fd4\u56de\uff1a \u5305\u542b IP\u3001\u7f51\u5173\u3001DNS \u7b49 DHCP \u4fe1\u606f\u7684\u5b57\u5178

      "},{"location":"qsl4a/connectivity/wifi/#wifidisconnect","title":"wifiDisconnect()","text":"

      \u65ad\u5f00\u5f53\u524d WiFi \u7f51\u7edc\u8fde\u63a5\u3002

      wifiDisconnect()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifireconnect","title":"wifiReconnect()","text":"

      \u91cd\u65b0\u8fde\u63a5\u5230\u5f53\u524d\u7f51\u7edc\u3002

      wifiReconnect()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifireassociate","title":"wifiReassociate()","text":"

      \u91cd\u65b0\u5173\u8054\u5f53\u524d\u63a5\u5165\u70b9\u3002

      wifiReassociate()\n
      "},{"location":"qsl4a/connectivity/wifi/#_3","title":"\u70ed\u70b9","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetapstate","title":"wifiGetApState()","text":"

      \u83b7\u53d6 WiFi AP\uff08\u70ed\u70b9\uff09\u72b6\u6001\u3002

      wifiGetApState()\n

      \u8fd4\u56de\uff1a \u70ed\u70b9\u72b6\u6001

      "},{"location":"qsl4a/connectivity/wifi/#wifi","title":"WiFi \u9501","text":""},{"location":"qsl4a/connectivity/wifi/#wifilockacquirefull","title":"wifiLockAcquireFull()","text":"

      \u83b7\u53d6\u5b8c\u6574 WiFi \u9501\uff08\u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\u4e5f\u4fdd\u6301 WiFi \u6d3b\u52a8\uff09\u3002

      wifiLockAcquireFull()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifilockacquirescanonly","title":"wifiLockAcquireScanOnly()","text":"

      \u83b7\u53d6\u4ec5\u626b\u63cf WiFi \u9501\u3002

      wifiLockAcquireScanOnly()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifilockrelease","title":"wifiLockRelease()","text":"

      \u91ca\u653e WiFi \u9501\u3002

      wifiLockRelease()\n
      "},{"location":"qsl4a/connectivity/wifi/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u68c0\u67e5 WiFi \u72b6\u6001\nif droid.checkWifiState().result:\n    print(\"WiFi is enabled\")\nelse:\n    print(\"Enabling WiFi...\")\n    droid.toggleWifiState(True)\n    time.sleep(2)\n\n# \u5f00\u59cb\u626b\u63cf\ndroid.wifiStartScan()\ntime.sleep(3)\n\n# \u83b7\u53d6\u626b\u63cf\u7ed3\u679c\nnetworks = droid.wifiGetScanResults().result\nfor network in networks:\n    print(f\"SSID: {network.get('SSID')}, Signal: {network.get('level')} dBm\")\n\n# \u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\ninfo = droid.wifiGetConnectionInfo().result\nif info:\n    print(f\"Connected to: {info.get('ssid')}\")\n    print(f\"BSSID: {info.get('bssid')}\")\n    print(f\"IP: {info.get('ip_address')}\")\n\n# \u83b7\u53d6 DHCP \u4fe1\u606f\ndhcp = droid.getDhcpInfo().result\nif dhcp:\n    print(f\"Gateway: {dhcp.get('gateway')}\")\n    print(f\"DNS: {dhcp.get('dns1')}\")\n\n# \u83b7\u53d6\u7b80\u5316\u7684\u8fde\u63a5\u4fe1\u606f\nconnected = droid.getConnectedInfo().result\nprint(f\"SSID: {connected.get('ssid')}, Signal: {connected.get('level')} dBm\")\n\n# \u65ad\u5f00\u5e76\u91cd\u65b0\u8fde\u63a5\ndroid.wifiDisconnect()\ntime.sleep(1)\ndroid.wifiReconnect()\n\n# \u91cd\u65b0\u5173\u8054\u63a5\u5165\u70b9\ndroid.wifiReassociate()\n\n# \u68c0\u67e5\u70ed\u70b9\u72b6\u6001\nap_state = droid.wifiGetApState().result\nprint(f\"Hotspot state: {ap_state}\")\n\n# \u83b7\u53d6 WiFi \u9501\u4ee5\u8fdb\u884c\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireFull()\n# ... \u6267\u884c\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n\n# \u6216\u4f7f\u7528\u4ec5\u626b\u63cf\u9501\u4ee5\u8fdb\u884c\u8f83\u8f7b\u7684\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireScanOnly()\n# ... \u6267\u884c\u626b\u63cf\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n
      "},{"location":"qsl4a/core/android-base/","title":"Android \u57fa\u7840\u7c7b","text":"

      Android \u7c7b\u662f QSL4A \u7684\u6838\u5fc3\uff0c\u63d0\u4f9b\u4e86\u4e0e Android \u8fd0\u884c\u65f6\u7684\u8fde\u63a5\u548c RPC \u673a\u5236\u3002

      "},{"location":"qsl4a/core/android-base/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
      # \u529f\u80fd\u5b8c\u6574\u7248\u672c\uff08\u63a8\u8350\uff09\nimport androidhelper\ndroid = androidhelper.Android()\n\n# \u7b80\u5316\u7248\u672c\uff08\u5feb\u901f\uff0c\u5355\u5b9e\u4f8b\uff09\nimport android\ndroid = android.droid\n
      "},{"location":"qsl4a/core/android-base/#android_1","title":"\u7c7b\uff1aAndroid","text":""},{"location":"qsl4a/core/android-base/#_2","title":"\u6784\u9020\u51fd\u6570","text":"
      Android(addr=None)\n

      \u53c2\u6570\uff1a - addr (tuple, optional): (HOST, PORT) \u5730\u5740\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u73af\u5883\u53d8\u91cf AP_HOST \u548c AP_PORT

      \u73af\u5883\u53d8\u91cf\uff1a - AP_HOST - \u670d\u52a1\u5668\u4e3b\u673a\u5730\u5740 - AP_PORT - \u670d\u52a1\u5668\u7aef\u53e3 - AP_HANDSHAKE - \u8ba4\u8bc1\u4ee4\u724c

      "},{"location":"qsl4a/core/android-base/#_3","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/android-base/#_rpc","title":"_rpc()","text":"

      \u8c03\u7528 Android \u51fd\u6570\u7684\u5185\u90e8 RPC \u65b9\u6cd5\u3002

      _rpc(method, *args)\n

      \u53c2\u6570\uff1a - method (str): \u8981\u8c03\u7528\u7684\u65b9\u6cd5\u540d - *args: \u65b9\u6cd5\u7684\u53ef\u53d8\u53c2\u6570

      \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4\uff0c\u5305\u542b\u4ee5\u4e0b\u5b57\u6bb5\uff1a - id (int): \u8bf7\u6c42 ID - result: \u65b9\u6cd5\u8fd4\u56de\u503c - error (str or None): \u9519\u8bef\u4fe1\u606f\uff08\u5982\u679c\u5931\u8d25\uff09

      "},{"location":"qsl4a/core/android-base/#getattr","title":"getattr()","text":"

      \u52a8\u6001\u65b9\u6cd5\u5206\u53d1\u5668\u3002\u6240\u6709 Android \u65b9\u6cd5\u90fd\u901a\u8fc7\u5c5e\u6027\u67e5\u627e\u8bbf\u95ee\u3002

      # \u4ee5\u4e0b\u4e24\u79cd\u65b9\u5f0f\u7b49\u4ef7\uff1a\ndroid.makeToast(\"Hello\")\ndroid._rpc(\"makeToast\", \"Hello\")\n
      "},{"location":"qsl4a/core/android-base/#androidpy","title":"\u72ec\u7acb\u51fd\u6570\uff08android.py\uff09","text":"

      \u4f7f\u7528\u7b80\u5316\u7684 android \u6a21\u5757\u65f6\uff1a

      "},{"location":"qsl4a/core/android-base/#jsla","title":"jsla()","text":"

      \u53d1\u9001 JSON-RPC \u8bf7\u6c42\u5e76\u8fd4\u56de\u539f\u59cb\u54cd\u5e94\u3002

      jsla(method, *params)\n

      \u8fd4\u56de\uff1a JSON \u5b57\u7b26\u4e32\u54cd\u5e94

      "},{"location":"qsl4a/core/android-base/#rsla","title":"rsla()","text":"

      \u53d1\u9001\u8bf7\u6c42\u5e76\u4ec5\u8fd4\u56de\u7ed3\u679c\u3002

      rsla(method, *params)\n

      \u8fd4\u56de\uff1a RPC \u8c03\u7528\u7684\u7ed3\u679c\u503c

      "},{"location":"qsl4a/core/android-base/#esla","title":"esla()","text":"

      \u53d1\u9001\u8bf7\u6c42\uff0c\u9519\u8bef\u65f6\u629b\u51fa\u5f02\u5e38\u3002

      esla(method, *params)\n

      \u629b\u51fa\uff1a \u5982\u679c error \u5b57\u6bb5\u4e0d\u4e3a None \u5219\u629b\u51fa\u5f02\u5e38

      "},{"location":"qsl4a/core/android-base/#nsla","title":"nsla()","text":"

      \u53d1\u9001\u8bf7\u6c42\u5e76\u8fd4\u56de Result \u547d\u540d\u5143\u7ec4\u3002

      nsla(method, *params)\n

      \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4

      "},{"location":"qsl4a/core/android-base/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/android-base/#_5","title":"\u57fa\u672c\u8fde\u63a5","text":"
      import androidhelper\n\n# \u8fde\u63a5\u5230 Android \u8fd0\u884c\u65f6\ndroid = androidhelper.Android()\n\n# \u901a\u8fc7\u663e\u793a toast \u6765\u68c0\u67e5\u8fde\u63a5\ndroid.makeToast(\"Connected!\")\n
      "},{"location":"qsl4a/core/android-base/#_6","title":"\u9519\u8bef\u5904\u7406","text":"
      result = droid.someMethod()\nif result.error:\n    print(f\"Error: {result.error}\")\nelse:\n    print(f\"Success: {result.result}\")\n
      "},{"location":"qsl4a/core/android-base/#rpc","title":"\u76f4\u63a5 RPC \u8c03\u7528","text":"
      # \u76f4\u63a5\u8c03\u7528\u4efb\u610f\u65b9\u6cd5\nresult = droid._rpc(\"makeToast\", \"Hello World\")\n
      "},{"location":"qsl4a/core/events/","title":"\u4e8b\u4ef6\u7cfb\u7edf","text":"

      QSL4A \u63d0\u4f9b\u4e86\u4e00\u4e2a\u4e8b\u4ef6\u7cfb\u7edf\uff0c\u7528\u4e8e\u5904\u7406\u6765\u81ea Android \u7684\u5f02\u6b65\u4e8b\u4ef6\uff0c\u5982\u4f20\u611f\u5668\u66f4\u65b0\u3001\u4f4d\u7f6e\u53d8\u5316\u548c\u81ea\u5b9a\u4e49\u5e7f\u64ad\u3002

      "},{"location":"qsl4a/core/events/#_2","title":"\u4e8b\u4ef6\u57fa\u7840","text":"

      \u4e8b\u4ef6\u5b58\u50a8\u5728\u7f13\u51b2\u533a\u4e2d\uff0c\u53ef\u4ee5\u8f6e\u8be2\u6216\u7b49\u5f85\u3002\u6bcf\u4e2a\u4e8b\u4ef6\u5305\u542b\uff1a - name: \u4e8b\u4ef6\u7c7b\u578b/\u540d\u79f0 - data: \u4e8b\u4ef6\u8d1f\u8f7d\u6570\u636e - time: \u65f6\u95f4\u6233

      "},{"location":"qsl4a/core/events/#_3","title":"\u4e8b\u4ef6\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#eventclearbuffer","title":"eventClearBuffer()","text":"

      \u6e05\u9664\u7f13\u51b2\u533a\u4e2d\u7684\u6240\u6709\u5f85\u5904\u7406\u4e8b\u4ef6\u3002

      eventClearBuffer()\n

      \u8fd4\u56de\uff1a None

      "},{"location":"qsl4a/core/events/#eventpoll","title":"eventPoll()","text":"

      \u8f6e\u8be2\u7f13\u51b2\u533a\u4e2d\u7684\u4e8b\u4ef6\u3002

      eventPoll(number_of_events=1)\n

      \u53c2\u6570\uff1a - number_of_events (int): \u8981\u68c0\u7d22\u7684\u6700\u5927\u4e8b\u4ef6\u6570\uff08\u9ed8\u8ba4\uff1a1\uff09

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\u5217\u8868

      "},{"location":"qsl4a/core/events/#eventwait","title":"eventWait()","text":"

      \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\u3002

      eventWait(timeout=None)\n

      \u53c2\u6570\uff1a - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09\u3002None = \u6c38\u4e45\u7b49\u5f85

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

      "},{"location":"qsl4a/core/events/#eventwaitfor","title":"eventWaitFor()","text":"

      \u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6\u3002

      eventWaitFor(eventName, timeout=None)\n

      \u53c2\u6570\uff1a - eventName (str): \u8981\u7b49\u5f85\u7684\u4e8b\u4ef6\u540d\u79f0 - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

      "},{"location":"qsl4a/core/events/#eventpost","title":"eventPost()","text":"

      \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\u3002

      eventPost(name, data, enqueue=None)\n

      \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e\uff08\u4efb\u610f\u7c7b\u578b\uff09 - enqueue (bool, optional): \u5982\u679c\u4e3a True \u5219\u6dfb\u52a0\u5230\u961f\u5217

      "},{"location":"qsl4a/core/events/#receiveevent","title":"receiveEvent()","text":"

      \u63a5\u6536\u4e8b\u4ef6\uff08\u963b\u585e\uff09\u3002

      receiveEvent()\n

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61

      "},{"location":"qsl4a/core/events/#_4","title":"\u5e7f\u64ad\u4e8b\u4ef6","text":"

      \u6ce8\u518c\u7cfb\u7edf\u5e7f\u64ad\u4e8b\u4ef6\u3002

      "},{"location":"qsl4a/core/events/#eventregisterforbroadcast","title":"eventRegisterForBroadcast()","text":"

      \u6ce8\u518c\u63a5\u6536\u5e7f\u64ad\u4e8b\u4ef6\u3002

      eventRegisterForBroadcast(category, enqueue=True)\n

      \u53c2\u6570\uff1a - category (str): \u5e7f\u64ad\u7c7b\u522b/\u52a8\u4f5c - enqueue (bool): \u6dfb\u52a0\u5230\u4e8b\u4ef6\u961f\u5217

      "},{"location":"qsl4a/core/events/#eventunregisterforbroadcast","title":"eventUnregisterForBroadcast()","text":"

      \u53d6\u6d88\u6ce8\u518c\u5e7f\u64ad\u4e8b\u4ef6\u3002

      eventUnregisterForBroadcast(category)\n
      "},{"location":"qsl4a/core/events/#eventgetbrodcastcategories","title":"eventGetBrodcastCategories()","text":"

      \u83b7\u53d6\u5df2\u6ce8\u518c\u7684\u5e7f\u64ad\u7c7b\u522b\u3002

      eventGetBrodcastCategories()\n

      \u8fd4\u56de\uff1a \u5df2\u6ce8\u518c\u7c7b\u522b\u5217\u8868

      "},{"location":"qsl4a/core/events/#_5","title":"\u4e8b\u4ef6\u5206\u53d1\u5668)","text":""},{"location":"qsl4a/core/events/#starteventdispatcher","title":"startEventDispatcher()","text":"

      \u6253\u5f00\u4e00\u4e2a\u53ef\u4ee5\u8bfb\u53d6\u5df2\u53d1\u5e03\u4e8b\u4ef6\u7684\u5957\u63a5\u5b57\u3002)

      startEventDispatcher(port=0)\n

      \u53c2\u6570\uff1a - port (int, optional): \u76d1\u542c\u7684\u7aef\u53e3\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\u9009\u62e9\uff09

      \u8fd4\u56de\uff1a \u6b63\u5728\u76d1\u542c\u7684\u7aef\u53e3\u53f7

      "},{"location":"qsl4a/core/events/#stopeventdispatcher","title":"stopEventDispatcher()","text":"

      \u505c\u6b62\u4e8b\u4ef6\u670d\u52a1\u5668\u3002)

      stopEventDispatcher()\n
      "},{"location":"qsl4a/core/events/#_6","title":"\u5df2\u5e9f\u5f03\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#rpcpostevent","title":"rpcPostEvent()","text":"

      \u5c06\u4e8b\u4ef6\u53d1\u5e03\u5230\u4e8b\u4ef6\u961f\u5217\u3002\uff08\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 eventPost\uff09

      rpcPostEvent(name, data)\n

      \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e

      "},{"location":"qsl4a/core/events/#_7","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/events/#_8","title":"\u57fa\u672c\u4e8b\u4ef6\u8f6e\u8be2","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6e05\u9664\u65e7\u4e8b\u4ef6\ndroid.eventClearBuffer()\n\n# \u8f6e\u8be2\u4e8b\u4ef6\nevents = droid.eventPoll(5).result\nfor event in events:\n    print(f\"Event: {event['name']}, Data: {event['data']}\")\n
      "},{"location":"qsl4a/core/events/#_9","title":"\u7b49\u5f85\u4e8b\u4ef6","text":"
      # \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\uff0c\u5e26\u8d85\u65f6\nevent = droid.eventWait(timeout=10).result\nif event:\n    print(f\"Got event: {event['name']}\")\n
      "},{"location":"qsl4a/core/events/#_10","title":"\u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6","text":"
      # \u7b49\u5f85\u4f20\u611f\u5668\u4e8b\u4ef6\nevent = droid.eventWaitFor('screen', timeout=5).result\nif event:\n    print(f\"Screen event: {event['data']}\")\n
      "},{"location":"qsl4a/core/events/#_11","title":"\u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6","text":"
      # \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\ndroid.eventPost('my_event', {'key': 'value'})\n\n# \u7b49\u5f85\u5b83\nevent = droid.eventWaitFor('my_event', timeout=1).result\n
      "},{"location":"qsl4a/core/events/#_12","title":"\u5e7f\u64ad\u63a5\u6536\u5668","text":"
      # \u6ce8\u518c\u5c4f\u5e55\u5f00\u5173\u4e8b\u4ef6\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_ON')\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_OFF')\n\n# \u7b49\u5f85\u5c4f\u5e55\u4e8b\u4ef6\nwhile True:\n    event = droid.receiveEvent().result\n    if event['name'] == 'android.intent.action.SCREEN_ON':\n        print(\"Screen turned on\")\n    elif event['name'] == 'android.intent.action.SCREEN_OFF':\n        print(\"Screen turned off\")\n
      "},{"location":"qsl4a/core/events/#_13","title":"\u4f20\u611f\u5668\u4e8b\u4ef6\u5904\u7406","text":"
      # \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u5904\u7406\u4f20\u611f\u5668\u4e8b\u4ef6\nfor _ in range(100):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'sensors':\n        data = event['data']\n        print(f\"Accel: {data['xforce']}, {data['yforce']}, {data['zforce']}\")\n\ndroid.stopSensing()\n
      "},{"location":"qsl4a/core/events/#_14","title":"\u5e38\u89c1\u4e8b\u4ef6\u7c7b\u578b","text":"\u4e8b\u4ef6\u540d\u79f0 \u63cf\u8ff0 \u6765\u6e90 sensors \u4f20\u611f\u5668\u6570\u636e\u66f4\u65b0 startSensing* location GPS \u4f4d\u7f6e\u66f4\u65b0 startLocating phone \u7535\u8bdd\u72b6\u6001\u53d8\u5316 startTrackingPhoneState signal \u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316 startTrackingSignalStrength screen \u622a\u56fe\u5c31\u7eea fullGetScreenShot dialog \u5bf9\u8bdd\u6846\u54cd\u5e94 dialogShow*"},{"location":"qsl4a/core/events/#_15","title":"\u4e8b\u4ef6\u6570\u636e\u7ed3\u6784","text":"
      {\n    'name': 'event_name',\n    'data': {\n        # \u4e8b\u4ef6\u7279\u5b9a\u6570\u636e\n    },\n    'time': 1234567890  # \u65f6\u95f4\u6233\n}\n
      "},{"location":"qsl4a/core/intent/","title":"Intent \u7cfb\u7edf","text":"

      Android Intent \u7528\u4e8e\u542f\u52a8\u6d3b\u52a8\u3001\u53d1\u9001\u5e7f\u64ad\u548c\u5e94\u7528\u95f4\u901a\u4fe1\u3002QSL4A \u901a\u8fc7 Intent \u6a21\u5757\u63d0\u4f9b\u5b8c\u6574\u7684 Intent \u652f\u6301\u3002

      "},{"location":"qsl4a/core/intent/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
      import androidhelper\ndon = androidhelper.Android()\n
      "},{"location":"qsl4a/core/intent/#intent_1","title":"Intent \u5e38\u91cf","text":"

      \u901a\u8fc7 droid.Intent \u8bbf\u95ee\uff1a

      "},{"location":"qsl4a/core/intent/#_2","title":"\u64cd\u4f5c","text":"\u5e38\u91cf \u503c \u7528\u9014 ACTION_MAIN android.intent.action.MAIN \u5e94\u7528\u5165\u53e3\u70b9 ACTION_VIEW android.intent.action.VIEW \u67e5\u770b\u5185\u5bb9 ACTION_EDIT android.intent.action.EDIT \u7f16\u8f91\u5185\u5bb9 ACTION_PICK android.intent.action.PICK \u9009\u62e9\u9879\u76ee ACTION_SEND android.intent.action.SEND \u5206\u4eab\u5185\u5bb9 ACTION_SEARCH android.intent.action.SEARCH \u641c\u7d22"},{"location":"qsl4a/core/intent/#_3","title":"\u6807\u5fd7","text":"\u5e38\u91cf \u503c \u7528\u9014 FLAG_ACTIVITY_NEW_TASK 268435456 \u542f\u52a8\u65b0\u4efb\u52a1 FLAG_ACTIVITY_CLEAR_TASK 32768 \u6e05\u9664\u4efb\u52a1\u5806\u6808 FLAG_ACTIVITY_NEW_DOCUMENT 524288 \u65b0\u6587\u6863\u6a21\u5f0f"},{"location":"qsl4a/core/intent/#_4","title":"\u9644\u52a0\u6570\u636e","text":"\u5e38\u91cf \u7528\u9014 EXTRA_TEXT \u6587\u672c\u5185\u5bb9 EXTRA_STREAM \u6587\u4ef6 URI EXTRA_SUBJECT \u4e3b\u9898\u884c EXTRA_EMAIL \u7535\u5b50\u90ae\u4ef6\u5730\u5740"},{"location":"qsl4a/core/intent/#_5","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/intent/#makeintent","title":"makeIntent()","text":"

      \u521b\u5efa Intent \u5bf9\u8c61\u3002

      makeIntent(action, uri=None, type=None, extras=None, categories=None,\n           packagename=None, classname=None, flags=None)\n

      \u53c2\u6570\uff1a - action (str): Intent \u64cd\u4f5c\uff08\u4f8b\u5982 droid.Intent.ACTION_VIEW\uff09 - uri (str, optional): \u6570\u636e URI - type (str, optional): MIME \u7c7b\u578b - extras (dict, optional): \u9644\u52a0\u6570\u636e - categories (list, optional): Intent \u7c7b\u522b - packagename (str, optional): \u76ee\u6807\u5305 - classname (str, optional): \u76ee\u6807\u7c7b - flags (int, optional): Intent \u6807\u5fd7

      \u8fd4\u56de\uff1a Intent \u5bf9\u8c61

      "},{"location":"qsl4a/core/intent/#startactivityintent","title":"startActivityIntent()","text":"

      \u4f7f\u7528 Intent \u542f\u52a8 Activity\u3002

      startActivityIntent(intent, wait=None)\n

      \u53c2\u6570\uff1a - intent: makeIntent() \u8fd4\u56de\u7684 Intent \u5bf9\u8c61 - wait (bool, optional): \u963b\u585e\u76f4\u5230\u6d3b\u52a8\u5173\u95ed

      "},{"location":"qsl4a/core/intent/#startactivityforresultintent","title":"startActivityForResultIntent()","text":"

      \u542f\u52a8\u6d3b\u52a8\u5e76\u7b49\u5f85\u7ed3\u679c\u3002

      startActivityForResultIntent(intent)\n

      \u8fd4\u56de\uff1a Activity \u7ed3\u679c

      "},{"location":"qsl4a/core/intent/#sendbroadcastintent","title":"sendBroadcastIntent()","text":"

      \u53d1\u9001\u5e7f\u64ad\u3002

      sendBroadcastIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#view","title":"view()","text":"

      \u901a\u8fc7 URI \u67e5\u770b\u5185\u5bb9\u3002

      view(uri, type=None, extras=None)\n
      "},{"location":"qsl4a/core/intent/#pick","title":"pick()","text":"

      \u4ece URI \u9009\u62e9\u5185\u5bb9\u3002

      pick(uri)\n
      "},{"location":"qsl4a/core/intent/#intent_2","title":"\u5e38\u89c1 Intent \u65b9\u6cd5)","text":""},{"location":"qsl4a/core/intent/#scanbarcode","title":"scanBarcode()","text":"

      \u542f\u52a8\u6761\u7801\u626b\u63cf\u5668\u3002

      scanBarcode()\n

      \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/core/intent/#send","title":"send()","text":"

      \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u5185\u5bb9\u3002

      send(type, content)\n

      \u53c2\u6570\uff1a - type (str): MIME \u7c7b\u578b - content (str): \u8981\u5206\u4eab\u7684\u5185\u5bb9

      "},{"location":"qsl4a/core/intent/#sendtext","title":"sendText()","text":"

      \u53d1\u9001\u6587\u672c\u5185\u5bb9\u3002

      sendText(text)\n

      \u53c2\u6570\uff1a - text (str): \u8981\u53d1\u9001\u7684\u6587\u672c

      "},{"location":"qsl4a/core/intent/#sendemail","title":"sendEmail()","text":"

      \u53d1\u9001\u7535\u5b50\u90ae\u4ef6\u3002

      sendEmail(to, subject, body, attachment=None)\n

      \u53c2\u6570\uff1a - to (str or list): \u6536\u4ef6\u4eba\u7535\u5b50\u90ae\u4ef6\u5730\u5740 - subject (str): \u7535\u5b50\u90ae\u4ef6\u4e3b\u9898 - body (str): \u7535\u5b50\u90ae\u4ef6\u6b63\u6587 - attachment (str, optional): \u9644\u4ef6\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/core/intent/#pathtouri","title":"pathToUri()","text":"

      \u5c06\u6587\u4ef6\u8def\u5f84\u8f6c\u6362\u4e3a\u5185\u5bb9 URI\u3002

      pathToUri(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5185\u5bb9 URI \u5b57\u7b26\u4e32

      "},{"location":"qsl4a/core/intent/#openfile","title":"openFile()","text":"

      \u7528\u9002\u5f53\u7684\u5e94\u7528\u7a0b\u5e8f\u6253\u5f00\u6587\u4ef6\u3002

      openFile(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u6253\u5f00\u7684\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/core/intent/#sendfile","title":"sendFile()","text":"

      \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u6587\u4ef6\u3002

      sendFile(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u53d1\u9001\u7684\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/core/intent/#getpathtype","title":"getPathType()","text":"

      \u83b7\u53d6\u6587\u4ef6\u8def\u5f84\u7684 MIME \u7c7b\u578b\u3002

      getPathType(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a MIME \u7c7b\u578b\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/core/intent/#viewmap","title":"viewMap()","text":"

      \u5728\u6307\u5b9a\u4f4d\u7f6e\u6253\u5f00\u5730\u56fe\u3002

      viewMap(latitude, longitude)\n

      \u53c2\u6570\uff1a - latitude (float): \u7eac\u5ea6 - longitude (float): \u7ecf\u5ea6

      "},{"location":"qsl4a/core/intent/#viewcontacts","title":"viewContacts()","text":"

      \u6253\u5f00\u8054\u7cfb\u4eba\u5e94\u7528\u3002

      viewContacts()\n
      "},{"location":"qsl4a/core/intent/#search","title":"search()","text":"

      \u6267\u884c\u7f51\u7edc\u641c\u7d22\u3002

      search(query)\n

      \u53c2\u6570\uff1a - query (str): \u641c\u7d22\u67e5\u8be2

      "},{"location":"qsl4a/core/intent/#viewhtml","title":"viewHtml()","text":"

      \u67e5\u770b HTML \u5185\u5bb9\u3002

      viewHtml(content, encoding=None)\n

      \u53c2\u6570\uff1a - content (str): HTML \u5185\u5bb9 - encoding (str, optional): \u5b57\u7b26\u7f16\u7801

      "},{"location":"qsl4a/core/intent/#webviewshow","title":"webViewShow()","text":"

      \u5728 WebView \u4e2d\u663e\u793a\u7f51\u9875\u5185\u5bb9\u3002\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 viewHtml\u3002

      webViewShow(url)\n

      \u53c2\u6570\uff1a - url (str): \u7f51\u9875 URL

      "},{"location":"qsl4a/core/intent/#editoropen","title":"editorOpen()","text":"

      \u6253\u5f00\u6587\u672c\u7f16\u8f91\u5668\u3002

      editorOpen(path=None, create=False)\n

      \u53c2\u6570\uff1a - path (str, optional): \u8981\u7f16\u8f91\u7684\u6587\u4ef6\u8def\u5f84 - create (bool, optional): \u5982\u679c\u4e0d\u5b58\u5728\u5219\u521b\u5efa

      "},{"location":"qsl4a/core/intent/#uri","title":"\u8f85\u52a9\u7c7b\uff1aUri","text":"

      \u521b\u5efa Intent \u7684 URI \u5bf9\u8c61\uff1a

      from androidhelper.Intent import Uri\n\nuri = Uri(\"file:///sdcard/test.txt\")\n
      "},{"location":"qsl4a/core/intent/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/intent/#_7","title":"\u6253\u5f00\u7f51\u9875","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"http://www.example.com\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_8","title":"\u5206\u4eab\u6587\u672c","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_TEXT: \"Hello from QPython!\",\n        droid.Intent.EXTRA_SUBJECT: \"Test\"\n    },\n    type=\"text/plain\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_9","title":"\u6253\u5f00\u6587\u4ef6","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"file:///sdcard/document.pdf\",\n    type=\"application/pdf\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_10","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":"
      result = droid.pickContact()\ncontact_uri = result.result\n
      "},{"location":"qsl4a/core/intent/#_11","title":"\u53d1\u9001\u7535\u5b50\u90ae\u4ef6","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_EMAIL: [\"test@example.com\"],\n        droid.Intent.EXTRA_SUBJECT: \"Hello\",\n        droid.Intent.EXTRA_TEXT: \"Message body\"\n    },\n    type=\"message/rfc822\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_12","title":"\u6253\u5f00\u5e94\u7528","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_MAIN,\n    packagename=\"com.android.settings\",\n    classname=\"com.android.settings.Settings\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/hardware/bluetooth/","title":"\u84dd\u7259 API","text":"

      \u63a7\u5236\u84dd\u7259\u9002\u914d\u5668\u5e76\u4e0e\u84dd\u7259\u8bbe\u5907\u901a\u4fe1\u3002

      "},{"location":"qsl4a/hardware/bluetooth/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/hardware/bluetooth/#togglebluetoothstate","title":"toggleBluetoothState()","text":"

      \u6253\u5f00/\u5173\u95ed\u84dd\u7259\u3002

      toggleBluetoothState(enabled=None, prompt=True)\n

      \u53c2\u6570\uff1a - enabled (bool): True=\u5f00\uff0cFalse=\u5173\uff0cNone=\u5207\u6362 - prompt (bool): \u663e\u793a\u7528\u6237\u63d0\u793a

      "},{"location":"qsl4a/hardware/bluetooth/#checkbluetoothstate","title":"checkBluetoothState()","text":"

      \u68c0\u67e5\u84dd\u7259\u662f\u5426\u5df2\u542f\u7528\u3002

      checkBluetoothState()\n

      \u8fd4\u56de\uff1a True/False

      "},{"location":"qsl4a/hardware/bluetooth/#getlocalname","title":"GetLocalName()","text":"

      \u83b7\u53d6\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

      GetLocalName()\n
      "},{"location":"qsl4a/hardware/bluetooth/#setlocalname","title":"SetLocalName()","text":"

      \u8bbe\u7f6e\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

      SetLocalName(name)\n
      "},{"location":"qsl4a/hardware/bluetooth/#getscanmode","title":"GetScanMode()","text":"

      \u83b7\u53d6\u53ef\u53d1\u73b0\u6027\u6a21\u5f0f\u3002

      GetScanMode()\n

      \u8fd4\u56de\uff1a - -1: \u5df2\u7981\u7528 - 0: \u4e0d\u53ef\u53d1\u73b0\uff0c\u4e0d\u53ef\u8fde\u63a5 - 1: \u53ef\u8fde\u63a5\uff0c\u4e0d\u53ef\u53d1\u73b0 - 3: \u53ef\u8fde\u63a5\u4e14\u53ef\u53d1\u73b0

      "},{"location":"qsl4a/hardware/bluetooth/#makediscoverable","title":"MakeDiscoverable()","text":"

      \u4f7f\u8bbe\u5907\u53ef\u53d1\u73b0\u3002

      MakeDiscoverable(duration=300)\n

      \u53c2\u6570\uff1a - duration (int): \u53ef\u53d1\u73b0\u7684\u79d2\u6570

      "},{"location":"qsl4a/hardware/bluetooth/#_2","title":"\u53d1\u73b0","text":""},{"location":"qsl4a/hardware/bluetooth/#discoverystart","title":"DiscoveryStart()","text":"

      \u5f00\u59cb\u8bbe\u5907\u53d1\u73b0\u3002

      DiscoveryStart()\n
      "},{"location":"qsl4a/hardware/bluetooth/#discoverycancel","title":"DiscoveryCancel()","text":"

      \u53d6\u6d88\u53d1\u73b0\u3002

      DiscoveryCancel()\n
      "},{"location":"qsl4a/hardware/bluetooth/#getreceiveddevices","title":"GetReceivedDevices()","text":"

      \u83b7\u53d6\u53d1\u73b0\u7684\u8bbe\u5907\u3002

      GetReceivedDevices()\n

      \u8fd4\u56de\uff1a \u8bbe\u5907\u4fe1\u606f\u5b57\u5178\u5217\u8868

      "},{"location":"qsl4a/hardware/bluetooth/#getbondeddevices","title":"GetBondedDevices()","text":"

      \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\u3002

      GetBondedDevices()\n

      \u8fd4\u56de\uff1a \u914d\u5bf9\u8bbe\u5907\u4fe1\u606f\u5217\u8868

      "},{"location":"qsl4a/hardware/bluetooth/#_3","title":"\u8fde\u63a5","text":""},{"location":"qsl4a/hardware/bluetooth/#connect","title":"Connect()","text":"

      \u8fde\u63a5\u5230\u8bbe\u5907\u3002

      Connect(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", address=None)\n

      \u53c2\u6570\uff1a - uuid (str): \u670d\u52a1 UUID - address (str): \u8bbe\u5907\u5730\u5740\uff08None = \u663e\u793a\u9009\u62e9\u5668\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/hardware/bluetooth/#accept","title":"Accept()","text":"

      \u63a5\u53d7\u4f20\u5165\u8fde\u63a5\u3002

      Accept(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", timeout=0)\n
      "},{"location":"qsl4a/hardware/bluetooth/#activeconnections","title":"ActiveConnections()","text":"

      \u68c0\u67e5\u6d3b\u52a8\u8fde\u63a5\u3002

      ActiveConnections()\n
      "},{"location":"qsl4a/hardware/bluetooth/#stop","title":"Stop()","text":"

      \u65ad\u5f00\u8fde\u63a5\u3002

      Stop(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#_4","title":"\u901a\u4fe1","text":""},{"location":"qsl4a/hardware/bluetooth/#write","title":"Write()","text":"

      \u53d1\u9001 ASCII \u6570\u636e\u3002

      Write(ascii, connID=\"\")\n
      "},{"location":"qsl4a/hardware/bluetooth/#writebinary","title":"WriteBinary()","text":"

      \u53d1\u9001\u4e8c\u8fdb\u5236\u6570\u636e\uff08base64 \u7f16\u7801\uff09\u3002

      WriteBinary(base64, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#read","title":"Read()","text":"

      \u8bfb\u53d6 ASCII \u6570\u636e\u3002

      Read(bufferSize=4096, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readbinary","title":"ReadBinary()","text":"

      \u8bfb\u53d6\u4e8c\u8fdb\u5236\u6570\u636e\u3002

      ReadBinary(bufferSize=4096, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readline","title":"ReadLine()","text":"

      \u8bfb\u53d6\u4e00\u884c\u3002

      ReadLine(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readready","title":"ReadReady()","text":"

      \u68c0\u67e5\u662f\u5426\u6709\u53ef\u7528\u6570\u636e\u3002

      ReadReady(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u7528\u84dd\u7259\ndroid.toggleBluetoothState(True)\n\n# \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\ndevices = droid.GetBondedDevices().result\nfor dev in devices:\n    print(f\"{dev['name']}: {dev['address']}\")\n\n# \u8fde\u63a5\u5230\u8bbe\u5907\ndroid.Connect(address=\"00:11:22:33:44:55\")\n\n# \u53d1\u9001\u6570\u636e\ndroid.Write(\"Hello Bluetooth!\")\n\n# \u8bfb\u53d6\u54cd\u5e94\ndata = droid.Read(1024).result\n
      "},{"location":"qsl4a/hardware/camera/","title":"\u76f8\u673a API","text":"

      \u62cd\u6444\u7167\u7247\u548c\u5f55\u5236\u89c6\u9891\u3002

      "},{"location":"qsl4a/hardware/camera/#_1","title":"\u7167\u7247\u62cd\u6444","text":""},{"location":"qsl4a/hardware/camera/#takepicture","title":"takePicture()","text":"

      \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u6444\u7167\u7247\u3002

      takePicture(path=None)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8fd4\u56de\u56fe\u50cf\u6570\u636e

      \u8fd4\u56de\uff1a \u56fe\u50cf\u8def\u5f84\u6216\u56fe\u50cf\u6570\u636e

      "},{"location":"qsl4a/hardware/camera/#cameracapturepicture","title":"cameraCapturePicture()","text":"

      \u4f7f\u7528\u9ad8\u7ea7\u76f8\u673a\u63a7\u5236\u62cd\u6444\u7167\u7247\u3002

      cameraCapturePicture(targetPath=None, cameraId=0, useAutoFocus=True)\n

      \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - useAutoFocus (bool): \u542f\u7528\u81ea\u52a8\u5bf9\u7126

      \u8fd4\u56de\uff1a \u62cd\u6444\u7684\u56fe\u50cf\u8def\u5f84

      "},{"location":"qsl4a/hardware/camera/#camerasettorchmode","title":"cameraSetTorchMode()","text":"

      \u63a7\u5236\u76f8\u673a\u95ea\u5149\u706f/\u624b\u7535\u7b52\u3002

      cameraSetTorchMode(enabled)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u6253\u5f00\uff0cFalse \u5173\u95ed

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/hardware/camera/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

      \u622a\u56fe\u3002

      imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

      "},{"location":"qsl4a/hardware/camera/#_2","title":"\u89c6\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#takevideo","title":"takeVideo()","text":"

      \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\u3002

      takeVideo(path=None, quality=1)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-4\uff09 - 0: 160x120 - 1: 320x240 - 2: 352x288 - 3: 640x480 - 4: 800x480

      "},{"location":"qsl4a/hardware/camera/#recordercapturevideo","title":"recorderCaptureVideo()","text":"

      \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\u3002

      recorderCaptureVideo(targetPath=None, duration=10, cameraId=0, quality=8)\n

      \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - duration (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a10\uff09 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-8\uff0c\u8d8a\u9ad8\u8d8a\u597d\uff09

      \u8fd4\u56de\uff1a \u89c6\u9891\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/hardware/camera/#recordaudio","title":"recordAudio()","text":"

      \u5f55\u5236\u97f3\u9891\u3002

      recordAudio()\n

      \u8fd4\u56de\uff1a \u97f3\u9891\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/hardware/camera/#_3","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

      \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\u3002

      recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

      \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\uff09 - targetPixels (int): \u5206\u8fa8\u7387 - frameRate (int): FPS - bitRate (int): \u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa - autoStart (bool): \u7acb\u5373\u5f00\u59cb

      "},{"location":"qsl4a/hardware/camera/#recorderstart","title":"recorderStart()","text":"

      \u5f00\u59cb\u5f55\u5236\u3002

      recorderStart()\n
      "},{"location":"qsl4a/hardware/camera/#recorderpause","title":"recorderPause()","text":"

      \u6682\u505c\u5f55\u5236\u3002

      recorderPause()\n
      "},{"location":"qsl4a/hardware/camera/#recorderresume","title":"recorderResume()","text":"

      \u6062\u590d\u5f55\u5236\u3002

      recorderResume()\n
      "},{"location":"qsl4a/hardware/camera/#_4","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/camera/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

      \u5f00\u59cb\u97f3\u91cf\u68c0\u6d4b\u3002

      recorderSoundVolumeDetect(interval=100)\n
      "},{"location":"qsl4a/hardware/camera/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

      \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

      recorderSoundVolumeGetDb()\n
      "},{"location":"qsl4a/hardware/camera/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u7167\nphoto_path = droid.takePicture(\"/sdcard/photo.jpg\").result\nprint(f\"Photo saved: {photo_path}\")\n\n# \u4f7f\u7528\u524d\u7f6e\u76f8\u673a\u548c\u81ea\u52a8\u5bf9\u7126\u62cd\u7167\ncamera_path = droid.cameraCapturePicture(\"/sdcard/selfie.jpg\", cameraId=1, useAutoFocus=True).result\nprint(f\"Front camera photo: {camera_path}\")\n\n# \u63a7\u5236\u95ea\u5149\u706f\ndroid.cameraSetTorchMode(True)  # \u6253\u5f00\u95ea\u5149\u706f\n\n# \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\nvideo_path = droid.takeVideo(\"/sdcard/video.mp4\", quality=3).result\nprint(f\"Video saved: {video_path}\")\n\n# \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\nvideo_path = droid.recorderCaptureVideo(\"/sdcard/movie.mp4\", duration=30, cameraId=0, quality=8).result\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n
      "},{"location":"qsl4a/hardware/recorder/","title":"\u97f3\u9891\u5f55\u5236 API","text":"

      \u4ece\u9ea6\u514b\u98ce\u548c\u8bbe\u5907\u5c4f\u5e55\u5f55\u5236\u97f3\u9891\u3002

      "},{"location":"qsl4a/hardware/recorder/#_1","title":"\u97f3\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recordaudio","title":"recordAudio()","text":"

      \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\u3002

      recordAudio()\n

      \u8fd4\u56de\uff1a \u5f55\u5236\u7684\u97f3\u9891\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/hardware/recorder/#recorderstartmicrophone","title":"recorderStartMicrophone()","text":"

      \u5f00\u59cb\u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\u3002

      recorderStartMicrophone(targetPath=None)\n

      \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u5f55\u5236\u7684\u8def\u5f84

      "},{"location":"qsl4a/hardware/recorder/#_2","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

      \u5f00\u59cb\u5e26\u97f3\u9891\u7684\u5c4f\u5e55\u5f55\u5236\u3002

      recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

      \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\u97f3\u9891\uff09 - targetPixels (int): \u76ee\u6807\u5206\u8fa8\u7387\uff08\u50cf\u7d20\uff09 - frameRate (int): \u6bcf\u79d2\u5e27\u6570\uff08\u9ed8\u8ba4\uff1a30\uff09 - bitRate (int): \u89c6\u9891\u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa\u89c6\u9891 - autoStart (bool): \u7acb\u5373\u5f00\u59cb\u5f55\u5236

      \u8fd4\u56de\uff1a \u64cd\u4f5c\u7ed3\u679c

      "},{"location":"qsl4a/hardware/recorder/#recorderstart","title":"recorderStart()","text":"

      \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\uff08\u5f53 autoStart=False \u65f6\uff09\u3002

      recorderStart()\n
      "},{"location":"qsl4a/hardware/recorder/#recorderpause","title":"recorderPause()","text":"

      \u6682\u505c\u6b63\u5728\u8fdb\u884c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

      recorderPause()\n
      "},{"location":"qsl4a/hardware/recorder/#recorderresume","title":"recorderResume()","text":"

      \u6062\u590d\u6682\u505c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

      recorderResume()\n
      "},{"location":"qsl4a/hardware/recorder/#_3","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/recorder/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

      \u5f00\u59cb\u76d1\u63a7\u97f3\u91cf\u7ea7\u522b\u3002

      recorderSoundVolumeDetect(interval=100)\n

      \u53c2\u6570\uff1a - interval (int): \u68c0\u6d4b\u95f4\u9694\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a100\uff09

      "},{"location":"qsl4a/hardware/recorder/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

      \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

      recorderSoundVolumeGetDb()\n

      \u8fd4\u56de\uff1a \u5f53\u524d\u97f3\u91cf\u7ea7\u522b\uff08dB\uff09

      "},{"location":"qsl4a/hardware/recorder/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\nprint(\"Recording audio...\")\naudio_path = droid.recordAudio().result\nprint(f\"Saved to: {audio_path}\")\n\n# \u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\ndroid.recorderStartMicrophone(\"/sdcard/my_recording.mp3\")\ntime.sleep(5)\ndroid.recorderStop()\n\n# \u5e26\u97f3\u9891\u5f55\u5236\u5c4f\u5e55\nprint(\"Starting screen recording...\")\ndroid.recorderStartScreenRecord(\n    path=\"/sdcard/screen_record.mp4\",\n    audio=1,\n    frameRate=30,\n    autoStart=True\n)\ntime.sleep(10)\ndroid.recorderStop()\n\n# \u76d1\u63a7\u97f3\u91cf\ndroid.recorderSoundVolumeDetect(interval=100)\ntime.sleep(3)\nvolume = droid.recorderSoundVolumeGetDb().result\nprint(f\"Current volume: {volume} dB\")\n
      "},{"location":"qsl4a/hardware/usbserial/","title":"USB \u4e3b\u673a\u4e32\u884c API","text":"

      \u4e0e USB \u4e32\u884c\u8bbe\u5907\u901a\u4fe1\uff08\u9700\u8981 USB OTG \u652f\u6301\u548c Android 3.1+\uff09\u3002

      "},{"location":"qsl4a/hardware/usbserial/#usb","title":"USB \u4e32\u884c\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialopen","title":"usbHostSerialOpen()","text":"

      \u6253\u5f00\u4e0e USB \u4e32\u884c\u8bbe\u5907\u7684\u8fde\u63a5\u3002

      usbHostSerialOpen(device, baudRate=9600)\n

      \u53c2\u6570\uff1a - device (str): USB \u8bbe\u5907\u8def\u5f84\u6216\u6807\u8bc6\u7b26 - baudRate (int): \u6ce2\u7279\u7387\uff08\u9ed8\u8ba4\uff1a9600\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u6253\u5f00\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialclose","title":"usbHostSerialClose()","text":"

      \u5173\u95ed USB \u4e32\u884c\u8fde\u63a5\u3002

      usbHostSerialClose()\n
      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialread","title":"usbHostSerialRead()","text":"

      \u4ece USB \u4e32\u884c\u8bfb\u53d6\u6570\u636e\u3002

      usbHostSerialRead(bufferSize=1024)\n

      \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570\uff08\u9ed8\u8ba4\uff1a1024\uff09

      \u8fd4\u56de\uff1a \u8bfb\u53d6\u7684\u6570\u636e\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwrite","title":"usbHostSerialWrite()","text":"

      \u5411 USB \u4e32\u884c\u5199\u5165\u6570\u636e\u3002

      usbHostSerialWrite(data)\n

      \u53c2\u6570\uff1a - data (str): \u8981\u5199\u5165\u7684\u5b57\u7b26\u4e32\u6570\u636e

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialavailable","title":"usbHostSerialAvailable()","text":"

      \u68c0\u67e5\u662f\u5426\u6709\u53ef\u8bfb\u53d6\u7684\u6570\u636e\u3002

      usbHostSerialAvailable()\n

      \u8fd4\u56de\uff1a \u53ef\u7528\u5b57\u8282\u6570

      "},{"location":"qsl4a/hardware/usbserial/#_1","title":"\u914d\u7f6e\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetbaudrate","title":"usbHostSerialSetBaudRate()","text":"

      \u8bbe\u7f6e\u6ce2\u7279\u7387\u3002

      usbHostSerialSetBaudRate(baudRate)\n

      \u53c2\u6570\uff1a - baudRate (int): \u6ce2\u7279\u7387

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetdatabits","title":"usbHostSerialSetDataBits()","text":"

      \u8bbe\u7f6e\u6570\u636e\u4f4d\uff085\u30016\u30017 \u6216 8\uff09\u3002

      usbHostSerialSetDataBits(dataBits)\n

      \u53c2\u6570\uff1a - dataBits (int): \u6570\u636e\u4f4d\uff085-8\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetstopbits","title":"usbHostSerialSetStopBits()","text":"

      \u8bbe\u7f6e\u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09\u3002

      usbHostSerialSetStopBits(stopBits)\n

      \u53c2\u6570\uff1a - stopBits (float): \u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetparity","title":"usbHostSerialSetParity()","text":"

      \u8bbe\u7f6e\u6821\u9a8c\u4f4d\uff08\u65e0\u3001\u5947\u3001\u5076\u3001\u6807\u8bb0\u3001\u7a7a\u683c\uff09\u3002

      usbHostSerialSetParity(parity)\n

      \u53c2\u6570\uff1a - parity (str): \u6821\u9a8c\u6a21\u5f0f\uff08'none'\u3001'odd'\u3001'even'\u3001'mark'\u3001'space'\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetflowcontrol","title":"usbHostSerialSetFlowControl()","text":"

      \u8bbe\u7f6e\u6d41\u63a7\u5236\uff08\u65e0\u3001\u786c\u4ef6\u3001\u8f6f\u4ef6\uff09\u3002

      usbHostSerialSetFlowControl(flowControl)\n

      \u53c2\u6570\uff1a - flowControl (str): \u6d41\u63a7\u5236\u6a21\u5f0f\uff08'none'\u3001'hardware'\u3001'software'\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialreadhex","title":"usbHostSerialReadHex()","text":"

      \u4ee5\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u8bfb\u53d6\u6570\u636e\u3002

      usbHostSerialReadHex(bufferSize=1024)\n

      \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570

      \u8fd4\u56de\uff1a \u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwritehex","title":"usbHostSerialWriteHex()","text":"

      \u4ece\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u5199\u5165\u6570\u636e\u3002

      usbHostSerialWriteHex(hexString)\n

      \u53c2\u6570\uff1a - hexString (str): \u8981\u5199\u5165\u7684\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/hardware/usbserial/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6253\u5f00 USB \u4e32\u884c\u8fde\u63a5\nif droid.usbHostSerialOpen(\"/dev/bus/usb/001/001\", 115200).result:\n    print(\"USB serial opened\")\n\n    # \u5199\u5165\u6570\u636e\n    droid.usbHostSerialWrite(\"AT\\r\")\n\n    # \u8bfb\u53d6\u54cd\u5e94\n    response = droid.usbHostSerialRead(1024).result\n    print(f\"Response: {response}\")\n\n    # \u6216\u4f7f\u7528\u5341\u516d\u8fdb\u5236\n    droid.usbHostSerialWriteHex(\"41540D0A\")  # \"AT\\r\\n\"\n\n    # \u5173\u95ed\u8fde\u63a5\n    droid.usbHostSerialClose()\n

      \u6ce8\u610f\uff1a USB \u4e32\u884c\u9700\u8981\uff1a - Android 3.1+ (API 12) - USB OTG \u7ebf/\u9002\u914d\u5668 - \u8bbe\u5907\u4e0a\u7684 USB \u4e3b\u673a\u6a21\u5f0f\u652f\u6301 - \u517c\u5bb9\u7684\u4e32\u884c\u8bbe\u5907

      "},{"location":"qsl4a/hardware/webcam/","title":"\u7f51\u7edc\u6444\u50cf\u5934 API","text":"

      \u4f7f\u7528 MJPEG \u4ece\u8bbe\u5907\u76f8\u673a\u6d41\u5f0f\u4f20\u8f93\u89c6\u9891\u3002

      "},{"location":"qsl4a/hardware/webcam/#mjpeg","title":"MJPEG \u6d41\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#webcamstart","title":"webcamStart()","text":"

      \u4ece\u7f51\u7edc\u6444\u50cf\u5934\u542f\u52a8 MJPEG \u6d41\u3002

      webcamStart(resolutionLevel=0, jpegQuality=20, port=0)\n

      \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf 1-100\uff08\u9ed8\u8ba4\uff1a20\uff09 - port (int): \u7aef\u53e3\u53f7\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\uff09

      \u8fd4\u56de\uff1a \u6d41\u7684 (\u5730\u5740, \u7aef\u53e3) \u5143\u7ec4

      "},{"location":"qsl4a/hardware/webcam/#webcamadjustquality","title":"webcamAdjustQuality()","text":"

      \u8c03\u6574\u6d3b\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u7684\u8d28\u91cf\u3002

      webcamAdjustQuality(resolutionLevel=0, jpegQuality=20)\n

      \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b - jpegQuality (int): JPEG \u8d28\u91cf 1-100

      "},{"location":"qsl4a/hardware/webcam/#webcamstop","title":"webcamStop()","text":"

      \u505c\u6b62\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u3002

      webcamStop()\n
      "},{"location":"qsl4a/hardware/webcam/#_1","title":"\u76f8\u673a\u9884\u89c8\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#camerastartpreview","title":"cameraStartPreview()","text":"

      \u5f00\u59cb\u5e26\u4e8b\u4ef6\u751f\u6210\u7684\u76f8\u673a\u9884\u89c8\u6a21\u5f0f\u3002

      cameraStartPreview(resolutionLevel=0, jpegQuality=20, filepath=None)\n

      \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf\uff08\u9ed8\u8ba4\uff1a20\uff09 - filepath (str, optional): \u4fdd\u5b58\u9884\u89c8\u5e27\u7684\u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      \u6ce8\u610f\uff1a \u751f\u6210\u5e26\u6709\u5e27\u6570\u636e\u7684 'preview' \u4e8b\u4ef6\u3002

      "},{"location":"qsl4a/hardware/webcam/#camerastoppreview","title":"cameraStopPreview()","text":"

      \u505c\u6b62\u76f8\u673a\u9884\u89c8\u3002

      cameraStopPreview()\n
      "},{"location":"qsl4a/hardware/webcam/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\nstream_info = droid.webcamStart(\n    resolutionLevel=0,\n    jpegQuality=30,\n    port=8080\n).result\nprint(f\"Stream available at {stream_info[0]}:{stream_info[1]}\")\n\n# \u6d41\u5f0f\u4f20\u8f93\u65f6\u8c03\u6574\u8d28\u91cf\ntime.sleep(5)\ndroid.webcamAdjustQuality(resolutionLevel=1, jpegQuality=50)\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.webcamStop()\n\n# \u6216\u4f7f\u7528\u9884\u89c8\u6a21\u5f0f\nprint(\"Starting preview...\")\ndroid.cameraStartPreview()\n\n# \u7b49\u5f85\u9884\u89c8\u4e8b\u4ef6\nfor i in range(10):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'preview':\n        print(f\"Got preview frame: {event['data']}\")\n\ndroid.cameraStopPreview()\n
      "},{"location":"qsl4a/media/image/","title":"\u56fe\u50cf\u5904\u7406 API","text":"

      \u538b\u7f29\u548c\u5904\u7406\u56fe\u50cf\u3002

      "},{"location":"qsl4a/media/image/#_1","title":"\u56fe\u50cf\u538b\u7f29","text":""},{"location":"qsl4a/media/image/#imagecompress","title":"imageCompress()","text":"

      \u538b\u7f29\u56fe\u50cf\u6587\u4ef6\u3002

      imageCompress(srcPath, destPath, targetByteSize=0, targetWidth=0, targetHeight=0)\n

      \u53c2\u6570\uff1a - srcPath (str): \u6e90\u56fe\u50cf\u8def\u5f84 - destPath (str): \u8f93\u51fa\u8def\u5f84 - targetByteSize (int): \u76ee\u6807\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff080 = \u65e0\u9650\u5236\uff09 - targetWidth (int): \u76ee\u6807\u5bbd\u5ea6\uff080 = \u539f\u59cb\uff09 - targetHeight (int): \u76ee\u6807\u9ad8\u5ea6\uff080 = \u539f\u59cb\uff09

      \u8fd4\u56de\uff1a \u538b\u7f29\u540e\u7684\u56fe\u50cf\u8def\u5f84

      "},{"location":"qsl4a/media/image/#_2","title":"\u622a\u56fe","text":""},{"location":"qsl4a/media/image/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

      \u622a\u53d6\u5c4f\u5e55\u3002

      imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

      \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

      \u8fd4\u56de\uff1a \u622a\u56fe\u8def\u5f84

      "},{"location":"qsl4a/media/image/#_3","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/image/#videoplay","title":"videoPlay()","text":"

      \u5728\u5168\u5c4f\u6a21\u5f0f\u4e0b\u64ad\u653e\u89c6\u9891\u6587\u4ef6\u3002

      videoPlay(path, wait=True)\n

      \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

      "},{"location":"qsl4a/media/image/#_4","title":"\u6761\u7801\u626b\u63cf","text":""},{"location":"qsl4a/media/image/#scanbarcodefromimage","title":"scanBarcodeFromImage()","text":"

      \u4ece\u56fe\u50cf\u6587\u4ef6\u626b\u63cf\u6761\u7801/\u4e8c\u7ef4\u7801\u3002

      scanBarcodeFromImage(path, compressRatio=0, x=0, y=0, width=0, height=0)\n

      \u53c2\u6570\uff1a - path (str): \u56fe\u50cf\u6587\u4ef6\u8def\u5f84 - compressRatio (int): \u538b\u7f29\u6bd4\uff080 = \u4e0d\u538b\u7f29\uff09 - x, y, width, height (int): \u8981\u626b\u63cf\u7684\u533a\u57df\uff080 = \u5b8c\u6574\u56fe\u50cf\uff09

      \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5185\u5bb9

      "},{"location":"qsl4a/media/image/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n\n# \u538b\u7f29\u56fe\u50cf\ncompressed = droid.imageCompress(\n    \"/sdcard/large_photo.jpg\",\n    \"/sdcard/compressed.jpg\",\n    targetByteSize=102400,  # \u76ee\u6807\u7ea6 100KB\n    targetWidth=1920,\n    targetHeight=1080\n).result\nprint(f\"Saved: {compressed}\")\n\n# \u64ad\u653e\u89c6\u9891\nvideo_path = \"/sdcard/movie.mp4\"\ndroid.videoPlay(video_path, wait=True)\n\n# \u4ece\u56fe\u50cf\u626b\u63cf\u6761\u7801\nresult = droid.scanBarcodeFromImage(\"/sdcard/qr_code.png\").result\nprint(f\"Barcode: {result}\")\n
      "},{"location":"qsl4a/media/mediaplayer/","title":"\u5a92\u4f53\u64ad\u653e\u5668 API","text":"

      \u63a7\u5236\u97f3\u9891\u548c\u89c6\u9891\u64ad\u653e\u3002

      "},{"location":"qsl4a/media/mediaplayer/#_1","title":"\u64ad\u653e\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplay","title":"mediaPlay()","text":"

      \u64ad\u653e\u5a92\u4f53\u6587\u4ef6\u3002

      mediaPlay(url, tag=\"default\", play=True)\n

      \u53c2\u6570\uff1a - url (str): \u5a92\u4f53\u6587\u4ef6\u8def\u5f84\u6216 URL - tag (str): \u64ad\u653e\u5668\u6807\u8bc6\u7b26 - play (bool): \u81ea\u52a8\u5f00\u59cb\u64ad\u653e

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaystart","title":"mediaPlayStart()","text":"

      \u5f00\u59cb\u64ad\u653e\u3002

      mediaPlayStart(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplaypause","title":"mediaPlayPause()","text":"

      \u6682\u505c\u64ad\u653e\u3002

      mediaPlayPause(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplayclose","title":"mediaPlayClose()","text":"

      \u5173\u95ed\u64ad\u653e\u5668\u3002

      mediaPlayClose(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplayseek","title":"mediaPlaySeek()","text":"

      \u8df3\u8f6c\u5230\u4f4d\u7f6e\u3002

      mediaPlaySeek(msec, tag=\"default\")\n

      \u53c2\u6570\uff1a - msec (int): \u4f4d\u7f6e\uff08\u6beb\u79d2\uff09

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaysetlooping","title":"mediaPlaySetLooping()","text":"

      \u8bbe\u7f6e\u5faa\u73af\u6a21\u5f0f\u3002

      mediaPlaySetLooping(enabled, tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#_2","title":"\u64ad\u653e\u5668\u4fe1\u606f","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplayinfo","title":"mediaPlayInfo()","text":"

      \u83b7\u53d6\u64ad\u653e\u4fe1\u606f\u3002

      mediaPlayInfo(tag=\"default\")\n

      \u8fd4\u56de\uff1a \u5305\u542b\u65f6\u957f\u3001\u4f4d\u7f6e\u7b49\u7684\u5b57\u5178

      "},{"location":"qsl4a/media/mediaplayer/#mediaisplaying","title":"mediaIsPlaying()","text":"

      \u68c0\u67e5\u662f\u5426\u6b63\u5728\u64ad\u653e\u3002

      mediaIsPlaying(tag=\"default\")\n

      \u8fd4\u56de\uff1a True/False

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaylist","title":"mediaPlayList()","text":"

      \u5217\u51fa\u6d3b\u52a8\u64ad\u653e\u5668\u3002

      mediaPlayList()\n
      "},{"location":"qsl4a/media/mediaplayer/#_3","title":"\u97f3\u91cf\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#getmediavolume","title":"getMediaVolume()","text":"

      \u83b7\u53d6\u5a92\u4f53\u97f3\u91cf\u3002

      getMediaVolume()\n

      \u8fd4\u56de\uff1a \u97f3\u91cf\u7ea7\u522b\uff080-15\uff09

      "},{"location":"qsl4a/media/mediaplayer/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

      getMaxMediaVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#getringervolume","title":"getRingerVolume()","text":"

      \u83b7\u53d6\u94c3\u58f0\u97f3\u91cf\u3002

      getRingerVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

      getMaxRingerVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#_4","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/mediaplayer/#videoplay","title":"videoPlay()","text":"

      \u5168\u5c4f\u64ad\u653e\u89c6\u9891\u3002

      videoPlay(path, wait=True)\n

      \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210

      "},{"location":"qsl4a/media/mediaplayer/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u64ad\u653e\u97f3\u9891\ndroid.mediaPlay(\"/sdcard/music.mp3\", tag=\"music\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.mediaIsPlaying(\"music\").result:\n    info = droid.mediaPlayInfo(\"music\").result\n    print(f\"Playing: {info}\")\n\n# \u8df3\u8f6c\u5230 30 \u79d2\ndroid.mediaPlaySeek(30000, \"music\")\n\n# \u5173\u95ed\ndroid.mediaPlayClose(\"music\")\n\n# \u64ad\u653e\u89c6\u9891\ndroid.videoPlay(\"/sdcard/movie.mp4\", wait=True)\n
      "},{"location":"qsl4a/special/cipher/","title":"\u5bc6\u7801 API","text":"

      \u7528\u4e8e\u5b89\u5168\u6570\u636e\u5b58\u50a8\u7684\u52a0\u5bc6\u548c\u89e3\u5bc6\u5de5\u5177\u3002

      "},{"location":"qsl4a/special/cipher/#_1","title":"\u521d\u59cb\u5316","text":""},{"location":"qsl4a/special/cipher/#cipherinit","title":"cipherInit()","text":"

      \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u548c\u7b97\u6cd5\u521d\u59cb\u5316\u5bc6\u7801\u5668\u3002

      cipherInit(key, algorithm=\"AES/CBC/PKCS5Padding\", encodingFormat=\"\", initialVector=\"\")\n

      \u53c2\u6570\uff1a - key (str or bytes): \u52a0\u5bc6\u5bc6\u94a5 - algorithm (str): \u5bc6\u7801\u7b97\u6cd5\uff08\u9ed8\u8ba4\uff1a\"AES/CBC/PKCS5Padding\"\uff09 - encodingFormat (str): \u7f16\u7801\u683c\u5f0f - initialVector (str or bytes): \u52a0\u5bc6\u7684\u521d\u59cb\u5411\u91cf

      \u8fd4\u56de\uff1a \u521d\u59cb\u5316\u7ed3\u679c

      \u6ce8\u610f\uff1a \u5fc5\u987b\u5728\u4efb\u4f55\u52a0\u5bc6/\u89e3\u5bc6\u64cd\u4f5c\u4e4b\u524d\u8c03\u7528\u3002

      "},{"location":"qsl4a/special/cipher/#_2","title":"\u52a0\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#encryptstring","title":"encryptString()","text":"

      \u52a0\u5bc6\u5b57\u7b26\u4e32\u3002

      encryptString(plainText)\n

      \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c

      \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/special/cipher/#encryptbytes","title":"encryptBytes()","text":"

      \u52a0\u5bc6\u5b57\u8282\u6570\u636e\u3002

      encryptBytes(data)\n

      \u53c2\u6570\uff1a - data (bytes): \u8981\u52a0\u5bc6\u7684\u6570\u636e

      \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u8282

      "},{"location":"qsl4a/special/cipher/#encryptstringtofile","title":"encryptStringToFile()","text":"

      \u52a0\u5bc6\u5b57\u7b26\u4e32\u5230\u6587\u4ef6\u3002

      encryptStringToFile(plainText, filePath)\n

      \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c - filePath (str): \u8f93\u51fa\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/special/cipher/#encryptbytestofile","title":"encryptBytesToFile()","text":"

      \u52a0\u5bc6\u5b57\u8282\u5230\u6587\u4ef6\u3002

      encryptBytesToFile(data, filePath)\n
      "},{"location":"qsl4a/special/cipher/#_3","title":"\u89e3\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#decryptstring","title":"decryptString()","text":"

      \u89e3\u5bc6\u4e3a\u5b57\u7b26\u4e32\u3002

      decryptString(cipherText)\n

      \u53c2\u6570\uff1a - cipherText (str): \u52a0\u5bc6\u7684\u6587\u672c

      \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/special/cipher/#decryptbytes","title":"decryptBytes()","text":"

      \u89e3\u5bc6\u4e3a\u5b57\u8282\u3002

      decryptBytes(data)\n

      \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u8282

      "},{"location":"qsl4a/special/cipher/#decryptfiletostring","title":"decryptFileToString()","text":"

      \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u7b26\u4e32\u3002

      decryptFileToString(filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryptfiletobytes","title":"decryptFileToBytes()","text":"

      \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u8282\u3002

      decryptFileToBytes(filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryptfile","title":"decryptFile()","text":"

      \u89e3\u5bc6\u6587\u4ef6\u5230\u6587\u4ef6\u3002

      decryptFile(srcPath, destPath)\n
      "},{"location":"qsl4a/special/cipher/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u521d\u59cb\u5316\u5bc6\u7801\u5668\ndroid.cipherInit(\"my_secret_key_1234\")\n\n# \u52a0\u5bc6\u5b57\u7b26\u4e32\nencrypted = droid.encryptString(\"Secret message!\").result\nprint(f\"Encrypted: {encrypted}\")\n\n# \u89e3\u5bc6\u5b57\u7b26\u4e32\ndecrypted = droid.decryptString(encrypted).result\nprint(f\"Decrypted: {decrypted}\")\n\n# \u52a0\u5bc6\u5230\u6587\u4ef6\ndroid.encryptStringToFile(\"My secret data\", \"/sdcard/secret.dat\")\n\n# \u4ece\u6587\u4ef6\u89e3\u5bc6\ndata = droid.decryptFileToString(\"/sdcard/secret.dat\").result\nprint(data)\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u7b97\u6cd5\u548c IV \u521d\u59cb\u5316\ndroid.cipherInit(\n    key=\"my_key\",\n    algorithm=\"AES/CBC/PKCS5Padding\",\n    initialVector=\"0123456789abcdef\"\n)\n
      "},{"location":"qsl4a/special/pgptai/","title":"PGPT AI API","text":"

      \u8bed\u97f3\u8f6c\u6587\u672c\u548c AI \u670d\u52a1\u96c6\u6210\u3002

      "},{"location":"qsl4a/special/pgptai/#_1","title":"\u5148\u51b3\u6761\u4ef6","text":"
      pip install pgptAI\n
      "},{"location":"qsl4a/special/pgptai/#_2","title":"\u8bed\u97f3\u8bc6\u522b","text":""},{"location":"qsl4a/special/pgptai/#speechtotext","title":"speechToText()","text":"

      \u5c06\u8bed\u97f3\u8f6c\u6362\u4e3a\u6587\u672c\u3002

      speechToText(RecordSecond=10, AmrFile=None, Language=None)\n

      \u53c2\u6570\uff1a - RecordSecond (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09 - AmrFile (str, optional): \u73b0\u6709\u97f3\u9891\u6587\u4ef6\u8def\u5f84 - Language (str, optional): \u8bed\u8a00\u4ee3\u7801\uff08'en'\u3001'zh'\uff09

      \u8fd4\u56de\uff1a \u8f6c\u5f55\u7684\u6587\u672c

      "},{"location":"qsl4a/special/pgptai/#_3","title":"\u6587\u672c\u8f6c\u8bed\u97f3","text":""},{"location":"qsl4a/special/pgptai/#texttospeech","title":"textToSpeech()","text":"

      \u5c06\u6587\u672c\u8f6c\u6362\u4e3a\u8bed\u97f3\u5e76\u53ef\u9009\u5730\u64ad\u653e\u3002

      textToSpeech(Text, AutoPlay=True, WavFile=None, VoiceName=None)\n

      \u53c2\u6570\uff1a - Text (str): \u8981\u8f6c\u6362\u4e3a\u8bed\u97f3\u7684\u6587\u672c - AutoPlay (bool): \u81ea\u52a8\u64ad\u653e\u751f\u6210\u7684\u97f3\u9891\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - WavFile (str, optional): \u4fdd\u5b58 WAV \u6587\u4ef6\u7684\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u4e34\u65f6\u6587\u4ef6 - VoiceName (str, optional): \u8981\u4f7f\u7528\u7684\u8bed\u97f3\u540d\u79f0\uff08\u4f8b\u5982 'en-US-JennyNeural'\u3001'zh-CN-XiaoxiaoNeural'\uff09

      \u8fd4\u56de\uff1a \u5305\u542b\u8bed\u97f3\u5408\u6210\u7ed3\u679c\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - text: \u8f93\u5165\u6587\u672c - url: \u4e0b\u8f7d\u97f3\u9891\u6587\u4ef6\u7684 URL - WavFile: \u4fdd\u5b58\u7684 WAV \u6587\u4ef6\u8def\u5f84\uff08\u5982\u679c\u672c\u5730\u4fdd\u5b58\uff09

      "},{"location":"qsl4a/special/pgptai/#_4","title":"\u914d\u7f6e","text":"

      API \u4f7f\u7528\u4ee5\u4e0b\u914d\u7f6e\u6587\u4ef6\u4e2d\u7684\u914d\u7f6e\uff1a/storage/emulated/0/Android/data/org.qpython.qpy/files/apigpt.conf\uff1a

      [speech]\nspeech_key = your_api_key\n

      \u9ed8\u8ba4\u8bed\u97f3\u8bbe\u7f6e\uff1a - \u82f1\u8bed\uff1aen-US-JennyNeural - \u4e2d\u6587\uff1azh-CN-XiaoxiaoNeural

      "},{"location":"qsl4a/special/pgptai/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5f55\u5236\u5e76\u8f6c\u5f55\nprint(\"Recording for 5 seconds...\")\ntext = droid.speechToText(RecordSecond=5, Language='en').result\nprint(f\"You said: {text}\")\n\n# \u8f6c\u5f55\u73b0\u6709\u6587\u4ef6\ntext = droid.speechToText(AmrFile=\"/sdcard/recording.amr\").result\nprint(f\"Transcription: {text}\")\n\n# \u6587\u672c\u8f6c\u8bed\u97f3\ndroid.textToSpeech(\"Hello, this is a test message.\", AutoPlay=True, Language='en')\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u8bed\u97f3\u5e76\u4fdd\u5b58\u5230\u6587\u4ef6\u7684\u6587\u672c\u8f6c\u8bed\u97f3\nresult = droid.textToSpeech(\n    \"Welcome to QPython!\",\n    AutoPlay=False,\n    WavFile=\"/sdcard/welcome.wav\",\n    VoiceName=\"en-US-JennyNeural\"\n).result\nprint(f\"Audio saved to: {result.get('WavFile')}\")\n
      "},{"location":"qsl4a/special/pgptai/#_6","title":"\u7c7b\u4f7f\u7528","text":"
      from androidhelper.pgptai import pgptai\nimport androidhelper\n\ndroid = androidhelper.Android()\nai = pgptai(droid)\n\n# \u4f7f\u7528\u8bed\u97f3\u8bc6\u522b\ntext = ai.speechToText(RecordSecond=10)\n
      "},{"location":"qsl4a/storage/clipboard/","title":"\u526a\u8d34\u677f API","text":"

      \u590d\u5236\u548c\u7c98\u8d34\u6587\u672c\u5230\u7cfb\u7edf\u526a\u8d34\u677f\u3002

      "},{"location":"qsl4a/storage/clipboard/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/clipboard/#setclipboard","title":"setClipboard()","text":"

      \u590d\u5236\u6587\u672c\u5230\u526a\u8d34\u677f\u3002

      setClipboard(text)\n

      \u53c2\u6570\uff1a - text (str): \u8981\u590d\u5236\u7684\u6587\u672c

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/clipboard/#getclipboard","title":"getClipboard()","text":"

      \u4ece\u526a\u8d34\u677f\u83b7\u53d6\u6587\u672c\u3002

      getClipboard()\n

      \u8fd4\u56de\uff1a \u526a\u8d34\u677f\u6587\u672c

      "},{"location":"qsl4a/storage/clipboard/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u590d\u5236\u5230\u526a\u8d34\u677f\ndroid.setClipboard(\"Hello from QPython!\")\n\n# \u4ece\u526a\u8d34\u677f\u7c98\u8d34\ntext = droid.getClipboard().result\nprint(f\"Clipboard: {text}\")\n
      "},{"location":"qsl4a/storage/documentfile/","title":"DocumentFile API","text":"

      \u4f7f\u7528 SAF\uff08\u5b58\u50a8\u8bbf\u95ee\u6846\u67b6\uff09\u8fdb\u884c\u6587\u4ef6\u64cd\u4f5c\uff0c\u652f\u6301 Android 4.4+\u3002

      "},{"location":"qsl4a/storage/documentfile/#_1","title":"\u76ee\u5f55\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilemkdir","title":"documentFileMkdir()","text":"

      \u521b\u5efa\u76ee\u5f55\u3002

      documentFileMkdir(Dir)\n

      \u53c2\u6570\uff1a - Dir (str): \u76ee\u5f55\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/documentfile/#documentfilelistfiles","title":"documentFileListFiles()","text":"

      \u5217\u51fa\u76ee\u5f55\u4e2d\u7684\u6587\u4ef6\u3002

      documentFileListFiles(Folder)\n

      \u8fd4\u56de\uff1a \u6587\u4ef6\u5217\u8868

      "},{"location":"qsl4a/storage/documentfile/#_2","title":"\u6587\u4ef6\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileexists","title":"documentFileExists()","text":"

      \u68c0\u67e5\u6587\u4ef6\u6216\u76ee\u5f55\u662f\u5426\u5b58\u5728\u3002

      documentFileExists(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u6216\u76ee\u5f55\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u5b58\u5728\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/storage/documentfile/#documentfileisfile","title":"documentFileIsFile()","text":"

      \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u6587\u4ef6\u3002

      documentFileIsFile(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u662f\u6587\u4ef6\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u6587\u4ef6\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

      "},{"location":"qsl4a/storage/documentfile/#documentfileisdirectory","title":"documentFileIsDirectory()","text":"

      \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u76ee\u5f55\u3002

      documentFileIsDirectory(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u662f\u76ee\u5f55\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u76ee\u5f55\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

      "},{"location":"qsl4a/storage/documentfile/#documentfiledelete","title":"documentFileDelete()","text":"

      \u5220\u9664\u6587\u4ef6\u6216\u76ee\u5f55\u3002

      documentFileDelete(FileOrTree)\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/documentfile/#documentfilerenameto","title":"documentFileRenameTo()","text":"

      \u91cd\u547d\u540d\u6216\u79fb\u52a8\u6587\u4ef6\u3002

      documentFileRenameTo(Src, Dest)\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/documentfile/#documentfilecopy","title":"documentFileCopy()","text":"

      \u590d\u5236\u6587\u4ef6\u3002

      documentFileCopy(SrcFileOrTree, DestFileOrTree)\n
      "},{"location":"qsl4a/storage/documentfile/#_3","title":"\u6d41\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileinputstream","title":"documentFileInputStream()","text":"

      \u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9\u3002

      documentFileInputStream(srcFile, EncodingFormat=\"\", skip=None, length=None)\n

      \u53c2\u6570\uff1a - srcFile (str): \u6e90\u6587\u4ef6 - EncodingFormat (str): \"UTF-8\"\u3001\"GBK\"\u3001\"Base64\" \u6216\u7a7a\u5b57\u7b26\u4e32\u8868\u793a\u5b57\u8282 - skip (int): \u4ece\u5f00\u5934\u8df3\u8fc7\u7684\u5b57\u8282\u6570 - length (int): \u8bfb\u53d6\u957f\u5ea6

      \u8fd4\u56de\uff1a \u6587\u4ef6\u5185\u5bb9

      "},{"location":"qsl4a/storage/documentfile/#documentfileoutputstream","title":"documentFileOutputStream()","text":"

      \u5199\u5165\u6587\u4ef6\u5185\u5bb9\u3002

      documentFileOutputStream(destFile, src, EncodingFormat=\"\", append=None)\n

      \u53c2\u6570\uff1a - destFile (str): \u76ee\u6807\u6587\u4ef6 - src: \u8981\u5199\u5165\u7684\u6570\u636e - EncodingFormat (str): \u7f16\u7801\u683c\u5f0f - append (bool): \u8ffd\u52a0\u6a21\u5f0f

      "},{"location":"qsl4a/storage/documentfile/#_4","title":"\u6587\u4ef6\u4fe1\u606f","text":""},{"location":"qsl4a/storage/documentfile/#documentfilelength","title":"documentFileLength()","text":"

      \u83b7\u53d6\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\u3002

      documentFileLength(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

      "},{"location":"qsl4a/storage/documentfile/#documentfilelastmodified","title":"documentFileLastModified()","text":"

      \u83b7\u53d6\u6700\u540e\u4fee\u6539\u65f6\u95f4\u3002

      documentFileLastModified(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u65f6\u95f4\u6233\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

      "},{"location":"qsl4a/storage/documentfile/#documentfilegetstat","title":"documentFileGetStat()","text":"

      \u83b7\u53d6\u5168\u9762\u7684\u6587\u4ef6\u7edf\u8ba1\u4fe1\u606f\u3002

      documentFileGetStat(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5305\u542b\u957f\u5ea6\u3001\u6700\u540e\u4fee\u6539\u65f6\u95f4\u548c\u8bfb/\u5199\u6743\u9650\u7684\u5b57\u5178\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

      "},{"location":"qsl4a/storage/documentfile/#uri","title":"URI \u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilegeturi","title":"documentFileGetUri()","text":"

      \u4ece\u8def\u5f84\u83b7\u53d6 URI\u3002

      documentFileGetUri(path, isDirectory=None)\n
      "},{"location":"qsl4a/storage/documentfile/#documentfileshowopen","title":"documentFileShowOpen()","text":"

      \u663e\u793a\u6587\u4ef6\u9009\u62e9\u5668\u3002

      documentFileShowOpen()\n

      \u8fd4\u56de\uff1a \u9009\u62e9\u7684\u6587\u4ef6 URI

      "},{"location":"qsl4a/storage/documentfile/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u76ee\u5f55\ndroid.documentFileMkdir(\"/sdcard/MyFolder\")\n\n# \u5217\u51fa\u6587\u4ef6\nfiles = droid.documentFileListFiles(\"/sdcard\").result\nfor f in files:\n    print(f)\n\n# \u8bfb\u53d6\u6587\u4ef6\ncontent = droid.documentFileInputStream(\n    \"/sdcard/test.txt\",\n    EncodingFormat=\"UTF-8\"\n).result\nprint(content)\n\n# \u5199\u5165\u6587\u4ef6\ndroid.documentFileOutputStream(\n    \"/sdcard/output.txt\",\n    \"Hello World\",\n    EncodingFormat=\"UTF-8\"\n)\n
      "},{"location":"qsl4a/storage/preferences/","title":"\u504f\u597d\u8bbe\u7f6e API","text":"

      \u4f7f\u7528 Android SharedPreferences \u5b58\u50a8\u548c\u68c0\u7d22\u6570\u636e\u3002

      "},{"location":"qsl4a/storage/preferences/#_1","title":"\u504f\u597d\u8bbe\u7f6e\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/preferences/#prefgetvalue","title":"prefGetValue()","text":"

      \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u8bfb\u53d6\u503c\u3002

      prefGetValue(key, filename=None)\n

      \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c\uff08\u4efb\u610f\u7c7b\u578b\uff09

      "},{"location":"qsl4a/storage/preferences/#prefputvalue","title":"prefPutValue()","text":"

      \u5199\u5165\u503c\u5230\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u3002

      prefPutValue(key, value, filename=None)\n

      \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - value (object): \u8981\u5b58\u50a8\u7684\u503c - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      "},{"location":"qsl4a/storage/preferences/#prefgetall","title":"prefGetAll()","text":"

      \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\u503c\u3002

      prefGetAll(filename=None)\n

      \u53c2\u6570\uff1a - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      \u8fd4\u56de\uff1a \u6240\u6709\u504f\u597d\u7684\u6620\u5c04

      "},{"location":"qsl4a/storage/preferences/#prefremovevalue","title":"prefRemoveValue()","text":"

      \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u4e2d\u79fb\u9664\u503c\u3002

      prefRemoveValue(key, filename=None)\n

      \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      "},{"location":"qsl4a/storage/preferences/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b58\u50a8\u503c\ndroid.prefPutValue(\"username\", \"alice\")\ndroid.prefPutValue(\"score\", 100)\ndroid.prefPutValue(\"enabled\", True)\n\n# \u8bfb\u53d6\u7279\u5b9a\u503c\nusername = droid.prefGetValue(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\nall_prefs = droid.prefGetAll().result\nprint(f\"All prefs: {all_prefs}\")\n\n# \u79fb\u9664\u503c\ndroid.prefRemoveValue(\"score\")\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u6587\u4ef6\u540d\ndroid.prefPutValue(\"token\", \"abc123\", filename=\"auth.prefs\")\ntoken = droid.prefGetValue(\"token\", filename=\"auth.prefs\").result\n
      "},{"location":"qsl4a/system/activityresult/","title":"Activity Result API","text":"

      \u4e3a\u901a\u8fc7 startActivityForResult \u542f\u52a8\u7684\u811a\u672c\u8bbe\u7f6e activity \u7ed3\u679c\u3002

      "},{"location":"qsl4a/system/activityresult/#_1","title":"\u7ed3\u679c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/activityresult/#setresultboolean","title":"setResultBoolean()","text":"

      \u8bbe\u7f6e\u5e03\u5c14\u7ed3\u679c\u3002

      setResultBoolean(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (bool): \u5e03\u5c14\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultbyte","title":"setResultByte()","text":"

      \u8bbe\u7f6e\u5b57\u8282\u7ed3\u679c\u3002

      setResultByte(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u5b57\u8282\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultshort","title":"setResultShort()","text":"

      \u8bbe\u7f6e\u77ed\u6574\u6570\u7ed3\u679c\u3002

      setResultShort(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u77ed\u6574\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultchar","title":"setResultChar()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u7ed3\u679c\u3002

      setResultChar(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultinteger","title":"setResultInteger()","text":"

      \u8bbe\u7f6e\u6574\u6570\u7ed3\u679c\u3002

      setResultInteger(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u6574\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultlong","title":"setResultLong()","text":"

      \u8bbe\u7f6e\u957f\u6574\u6570\u7ed3\u679c\u3002

      setResultLong(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u957f\u6574\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultfloat","title":"setResultFloat()","text":"

      \u8bbe\u7f6e\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

      setResultFloat(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u6d6e\u70b9\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultdouble","title":"setResultDouble()","text":"

      \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

      setResultDouble(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultstring","title":"setResultString()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u4e32\u7ed3\u679c\u3002

      setResultString(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u4e32\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultbooleanarray","title":"setResultBooleanArray()","text":"

      \u8bbe\u7f6e\u5e03\u5c14\u6570\u7ec4\u7ed3\u679c\u3002

      setResultBooleanArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5e03\u5c14\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultbytearray","title":"setResultByteArray()","text":"

      \u8bbe\u7f6e\u5b57\u8282\u6570\u7ec4\u7ed3\u679c\u3002

      setResultByteArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u8282\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultshortarray","title":"setResultShortArray()","text":"

      \u8bbe\u7f6e\u77ed\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultShortArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u77ed\u6574\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultchararray","title":"setResultCharArray()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u6570\u7ec4\u7ed3\u679c\u3002

      setResultCharArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultintegerarray","title":"setResultIntegerArray()","text":"

      \u8bbe\u7f6e\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultIntegerArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6574\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultlongarray","title":"setResultLongArray()","text":"

      \u8bbe\u7f6e\u957f\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultLongArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u957f\u6574\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultfloatarray","title":"setResultFloatArray()","text":"

      \u8bbe\u7f6e\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultFloatArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6d6e\u70b9\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultdoublearray","title":"setResultDoubleArray()","text":"

      \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultDoubleArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultstringarray","title":"setResultStringArray()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u4e32\u6570\u7ec4\u7ed3\u679c\u3002

      setResultStringArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u4e32\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultserializable","title":"setResultSerializable()","text":"

      \u8bbe\u7f6e\u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u3002

      setResultSerializable(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue: \u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c activity \u540e\uff0c\u8bbe\u7f6e\u7ed3\u679c\n# \u793a\u4f8b\uff1a\u8fd4\u56de\u6210\u529f\u53ca\u6570\u636e\ndroid.setResultInteger(0, 200)  # RESULT_OK\ndroid.setResultString(0, \"Operation completed successfully\")\n\n# \u8fd4\u56de\u6570\u7ec4\u7ed3\u679c\ndroid.setResultIntegerArray(0, [1, 2, 3, 4, 5])\n
      "},{"location":"qsl4a/system/application/","title":"\u5e94\u7528\u7ba1\u7406","text":"

      \u7ba1\u7406\u5e94\u7528\u7a0b\u5e8f\u3001\u542f\u52a8\u5e94\u7528\u548c\u67e5\u8be2\u7cfb\u7edf\u4fe1\u606f\u3002

      "},{"location":"qsl4a/system/application/#_2","title":"\u5e94\u7528\u7a0b\u5e8f\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getapplicationinfo","title":"getApplicationInfo()","text":"

      \u83b7\u53d6\u5e94\u7528\u4fe1\u606f\u3002

      getApplicationInfo(packageName=None)\n

      \u53c2\u6570\uff1a - packageName (str): \u5305\u540d\uff08None = \u5f53\u524d\u5e94\u7528\uff09

      \u8fd4\u56de\uff1a \u5e94\u7528\u4fe1\u606f\u5b57\u5178

      "},{"location":"qsl4a/system/application/#getinstalledpackages","title":"getInstalledPackages()","text":"

      \u83b7\u53d6\u5df2\u5b89\u88c5\u5305\u5217\u8868\u3002

      getInstalledPackages(flag=4)\n

      \u53c2\u6570\uff1a - flag (int): \u5305\u6807\u5fd7\u8fc7\u6ee4\u5668\uff08\u9ed8\u8ba4\uff1a4\uff09

      \u8fd4\u56de\uff1a \u5df2\u5b89\u88c5\u5305\u5217\u8868

      "},{"location":"qsl4a/system/application/#getrunningpackages","title":"getRunningPackages()","text":"

      \u5217\u51fa\u6b63\u5728\u8fd0\u884c\u7684\u5305\u3002

      getRunningPackages()\n

      \u8fd4\u56de\uff1a \u5305\u540d\u5217\u8868

      "},{"location":"qsl4a/system/application/#getlaunchablepackages","title":"getLaunchablePackages()","text":"

      \u83b7\u53d6\u53ef\u542f\u52a8\u5305\u5217\u8868\u3002

      getLaunchablePackages(needClassName=False)\n

      \u53c2\u6570\uff1a - needClassName (bool): \u5305\u542b\u4e3b activity \u7c7b\u540d\uff08\u9ed8\u8ba4\uff1aFalse\uff09

      \u8fd4\u56de\uff1a \u53ef\u542f\u52a8\u5305\u540d\u5217\u8868\u6216\u5305\u542b\u7c7b\u540d\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#_3","title":"\u5e94\u7528\u63a7\u5236","text":""},{"location":"qsl4a/system/application/#launch","title":"launch()","text":"

      \u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u3002

      launch(classname=None, packagename=None, wait=True)\n

      \u53c2\u6570\uff1a - classname (str): \u4e3b activity \u7c7b\u540d - packagename (str): \u5305\u540d - wait (bool): \u7b49\u5f85\u542f\u52a8\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

      \u8fd4\u56de\uff1a \u542f\u52a8\u7ed3\u679c

      "},{"location":"qsl4a/system/application/#forcestoppackage","title":"forceStopPackage()","text":"

      \u5f3a\u5236\u505c\u6b62\u5e94\u7528\u7a0b\u5e8f\u3002

      forceStopPackage(packageName)\n

      \u53c2\u6570\uff1a - packageName (str): \u8981\u505c\u6b62\u7684\u5305\u540d

      "},{"location":"qsl4a/system/application/#_4","title":"\u7248\u672c\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getpackageversion","title":"getPackageVersion()","text":"

      \u83b7\u53d6\u5e94\u7528\u7248\u672c\u540d\u79f0\u3002

      getPackageVersion(packageName)\n

      \u8fd4\u56de\uff1a \u7248\u672c\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"3.2.1\"\uff09

      "},{"location":"qsl4a/system/application/#getpackageversioncode","title":"getPackageVersionCode()","text":"

      \u83b7\u53d6\u5e94\u7528\u7248\u672c\u4ee3\u7801\u3002

      getPackageVersionCode(packageName)\n

      \u8fd4\u56de\uff1a \u7248\u672c\u4ee3\u7801\u6574\u6570

      "},{"location":"qsl4a/system/application/#getconstants","title":"getConstants()","text":"

      \u83b7\u53d6\u7c7b\u5e38\u91cf\u3002

      getConstants(classname)\n

      \u53c2\u6570\uff1a - classname (str): \u5b8c\u6574\u7c7b\u540d

      \u8fd4\u56de\uff1a \u5e38\u91cf\u540d\u548c\u503c\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#_5","title":"\u7cfb\u7edf\u529f\u80fd","text":""},{"location":"qsl4a/system/application/#backgroundprotect","title":"backgroundProtect()","text":"

      \u542f\u7528\u6216\u7981\u7528\u5e94\u7528\u7684\u540e\u53f0\u4fdd\u62a4\u3002

      backgroundProtect(enabled=True)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\u4fdd\u62a4\uff0cFalse \u7981\u7528

      "},{"location":"qsl4a/system/application/#createscriptshortcut","title":"createScriptShortCut()","text":"

      \u4e3a\u811a\u672c\u521b\u5efa\u4e3b\u5c4f\u5e55\u5feb\u6377\u65b9\u5f0f\u3002

      createScriptShortCut(scriptPath, label=None, iconPath=None, scriptArg=None)\n

      \u53c2\u6570\uff1a - scriptPath (str): Python \u811a\u672c\u8def\u5f84 - label (str, optional): \u5feb\u6377\u65b9\u5f0f\u6807\u7b7e - iconPath (str, optional): \u56fe\u6807\u56fe\u50cf\u8def\u5f84 - scriptArg (str, optional): \u4f20\u9012\u7ed9\u811a\u672c\u7684\u53c2\u6570

      "},{"location":"qsl4a/system/application/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getandroidid","title":"getAndroidID()","text":"

      \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

      getAndroidID()\n

      \u8fd4\u56de\uff1a \u552f\u4e00\u7684 Android \u8bbe\u5907 ID \u5b57\u7b26\u4e32

      "},{"location":"qsl4a/system/application/#getsysinfo","title":"getSysInfo()","text":"

      \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\u3002

      getSysInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#getlocale","title":"getLocale()","text":"

      \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u3002

      getLocale()\n

      \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

      "},{"location":"qsl4a/system/application/#getharmonyosinformation","title":"getHarmonyOsInformation()","text":"

      \u5982\u679c\u5728 HarmonyOS \u4e0a\u8fd0\u884c\uff0c\u83b7\u53d6 HarmonyOS \u4fe1\u606f\u3002

      getHarmonyOsInformation()\n

      \u8fd4\u56de\uff1a HarmonyOS \u7248\u672c\u4fe1\u606f\u6216 None

      "},{"location":"qsl4a/system/application/#isexternalstoragemanager","title":"isExternalStorageManager()","text":"

      \u68c0\u67e5\u5e94\u7528\u662f\u5426\u6709\u5916\u90e8\u5b58\u50a8\u7ba1\u7406\u5668\u6743\u9650\u3002

      isExternalStorageManager()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6709\u6743\u9650\u5219\u4e3a True

      "},{"location":"qsl4a/system/application/#_7","title":"\u5185\u5b58\u548c\u663e\u793a","text":""},{"location":"qsl4a/system/application/#getmemoryinfo","title":"getMemoryInfo()","text":"

      \u83b7\u53d6\u5185\u5b58\u4fe1\u606f\u3002

      getMemoryInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#getscreeninfo","title":"getScreenInfo()","text":"

      \u83b7\u53d6\u5c4f\u5e55\u4fe1\u606f\u3002

      getScreenInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#_8","title":"\u6743\u9650","text":""},{"location":"qsl4a/system/application/#checkpermissions","title":"checkPermissions()","text":"

      \u68c0\u67e5\u5f53\u524d\u5e94\u7528\u6743\u9650\u3002

      checkPermissions()\n

      \u8fd4\u56de\uff1a \u6743\u9650\u53ca\u5176\u72b6\u6001\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#requestpermissions","title":"requestPermissions()","text":"

      \u5411\u7528\u6237\u8bf7\u6c42\u6743\u9650\u3002

      requestPermissions(permissions=None)\n

      \u53c2\u6570\uff1a - permissions (list, optional): \u8981\u8bf7\u6c42\u7684\u6743\u9650\u5217\u8868\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8bf7\u6c42\u6240\u6709\u9700\u8981\u7684\u6743\u9650\u3002

      \u8fd4\u56de\uff1a \u6743\u9650\u8bf7\u6c42\u7ed3\u679c

      "},{"location":"qsl4a/system/application/#_9","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/system/application/#showscreenlock","title":"showScreenLock()","text":"

      \u663e\u793a\u5c4f\u5e55\u9501\u5b9a\uff08PIN/\u56fe\u6848/\u5bc6\u7801\u8f93\u5165\uff09\u3002

      showScreenLock()\n
      "},{"location":"qsl4a/system/application/#_10","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\ninfo = droid.getSysInfo().result\nprint(f\"System: {info}\")\n\n# \u83b7\u53d6\u5e94\u7528\u7248\u672c\nversion = droid.getPackageVersion(\"org.qpython.qpy\").result\nprint(f\"QPython version: {version}\")\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u5e94\u7528\napps = droid.getInstalledPackages().result\nprint(f\"Installed apps: {len(apps)}\")\n\n# \u542f\u52a8\u5e94\u7528\ndroid.launch(packagename=\"com.android.settings\")\n\n# \u68c0\u67e5\u6743\u9650\nperms = droid.checkPermissions().result\nprint(f\"Permissions: {perms}\")\n\n# \u8bf7\u6c42\u5b58\u50a8\u6743\u9650\ndroid.requestPermissions([\"android.permission.READ_EXTERNAL_STORAGE\"])\n\n# \u521b\u5efa\u5feb\u6377\u65b9\u5f0f\ndroid.createScriptShortCut(\n    \"/sdcard/my_script.py\",\n    label=\"My Script\",\n    iconPath=\"/sdcard/icon.png\"\n)\n
      "},{"location":"qsl4a/system/battery/","title":"\u7535\u6c60 API","text":"

      \u76d1\u63a7\u8bbe\u5907\u7535\u6c60\u72b6\u6001\u548c\u5065\u5eb7\u72b6\u51b5\u3002

      "},{"location":"qsl4a/system/battery/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/battery/#readbatterydata","title":"readBatteryData()","text":"

      \u83b7\u53d6\u5b8c\u6574\u7684\u7535\u6c60\u4fe1\u606f\u3002

      readBatteryData()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7535\u6c60\u6570\u636e\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/battery/#batterystartmonitoring","title":"batteryStartMonitoring()","text":"

      \u5f00\u59cb\u7535\u6c60\u76d1\u63a7\u3002

      batteryStartMonitoring()\n
      "},{"location":"qsl4a/system/battery/#batterystopmonitoring","title":"batteryStopMonitoring()","text":"

      \u505c\u6b62\u7535\u6c60\u76d1\u63a7\u3002

      batteryStopMonitoring()\n
      "},{"location":"qsl4a/system/battery/#batterygetlevel","title":"batteryGetLevel()","text":"

      \u83b7\u53d6\u7535\u6c60\u767e\u5206\u6bd4\u3002

      batteryGetLevel()\n

      \u8fd4\u56de\uff1a \u6574\u6570\uff080-100\uff09

      "},{"location":"qsl4a/system/battery/#batterygetstatus","title":"batteryGetStatus()","text":"

      \u83b7\u53d6\u5145\u7535\u72b6\u6001\u3002

      batteryGetStatus()\n

      \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u5145\u7535\u4e2d - 3: \u653e\u7535\u4e2d - 4: \u672a\u5145\u7535 - 5: \u5df2\u5145\u6ee1

      "},{"location":"qsl4a/system/battery/#batterygetplugtype","title":"batteryGetPlugType()","text":"

      \u83b7\u53d6\u7535\u6e90\u7c7b\u578b\u3002

      batteryGetPlugType()\n

      \u8fd4\u56de\uff1a - -1: \u672a\u77e5 - 0: \u672a\u63d2\u7535 - 1: AC \u5145\u7535\u5668 - 2: USB \u7aef\u53e3

      "},{"location":"qsl4a/system/battery/#batterygethealth","title":"batteryGetHealth()","text":"

      \u83b7\u53d6\u7535\u6c60\u5065\u5eb7\u72b6\u51b5\u3002

      batteryGetHealth()\n

      \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u826f\u597d - 3: \u8fc7\u70ed - 4: \u635f\u574f - 5: \u8fc7\u538b - 6: \u672a\u6307\u5b9a\u7684\u6545\u969c

      "},{"location":"qsl4a/system/battery/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\nlevel = droid.batteryGetLevel().result\nprint(f\"Battery: {level}%\")\n
      "},{"location":"qsl4a/system/qpyinterface/","title":"QPython \u63a5\u53e3 API","text":"

      \u4ece\u5176\u4ed6\u5e94\u7528\u6267\u884c QPython \u811a\u672c\u548c\u7ba1\u7406\u5171\u4eab\u53d8\u91cf\u3002

      "},{"location":"qsl4a/system/qpyinterface/#_1","title":"\u811a\u672c\u6267\u884c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/qpyinterface/#executeqpy","title":"executeQPy()","text":"

      \u6267\u884c QPython \u811a\u672c\u3002

      executeQPy(path=\"\", arg=None)\n

      \u53c2\u6570\uff1a - path (str): \u811a\u672c\u6587\u4ef6\u8def\u5f84 - arg (str, optional): \u547d\u4ee4\u884c\u53c2\u6570

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#executeqpyassrv","title":"executeQPyAsSrv()","text":"

      \u4f5c\u4e3a\u670d\u52a1\u6267\u884c QPython \u811a\u672c\u3002

      executeQPyAsSrv(path=None)\n

      \u53c2\u6570\uff1a - path (str, optional): \u811a\u672c\u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#executeqpycode","title":"executeQPyCode()","text":"

      \u76f4\u63a5\u6267\u884c Python \u4ee3\u7801\u3002

      executeQPyCode(code=None)\n

      \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#executeqpycodeassrv","title":"executeQPyCodeAsSrv()","text":"

      \u4f5c\u4e3a\u670d\u52a1\u6267\u884c Python \u4ee3\u7801\u3002

      executeQPyCodeAsSrv(code=None)\n

      \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#_2","title":"\u5171\u4eab\u53d8\u91cf","text":"

      \u5171\u4eab\u53d8\u91cf\u5141\u8bb8 QPython \u4e0e\u5176\u4ed6\u5e94\u7528\u4e4b\u95f4\u8fdb\u884c\u901a\u4fe1\u3002

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableset","title":"sharedVariableSet()","text":"

      \u8bbe\u7f6e Java \u5171\u4eab\u53d8\u91cf\u3002

      sharedVariableSet(key, value)\n

      \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d - value (str): \u53d8\u91cf\u503c

      \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableget","title":"sharedVariableGet()","text":"

      \u83b7\u53d6 Java \u5171\u4eab\u53d8\u91cf\u3002

      sharedVariableGet(key)\n

      \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d

      \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableremove","title":"sharedVariableRemove()","text":"

      \u79fb\u9664 Java \u5171\u4eab\u53d8\u91cf\u3002

      sharedVariableRemove(key)\n

      \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u53d8\u91cf\u540d

      \u8fd4\u56de\uff1a \u88ab\u79fb\u9664\u7684\u503c

      "},{"location":"qsl4a/system/qpyinterface/#getlastlog","title":"getLastLog()","text":"

      \u83b7\u53d6 QPython \u7684\u6700\u540e\u65e5\u5fd7\u8f93\u51fa\u3002

      getLastLog()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u65e5\u5fd7\u5185\u5bb9

      "},{"location":"qsl4a/system/qpyinterface/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c\u811a\u672c\ndroid.executeQPy(\"/sdcard/my_script.py\", arg=\"test\")\n\n# \u76f4\u63a5\u6267\u884c\u4ee3\u7801\ncode = \"print('Hello from QPython!')\"\ndroid.executeQPyCode(code)\n\n# \u4f7f\u7528\u5171\u4eab\u53d8\u91cf\ndroid.sharedVariableSet(\"username\", \"alice\")\nusername = droid.sharedVariableGet(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u79fb\u9664\u53d8\u91cf\ndroid.sharedVariableRemove(\"username\")\n\n# \u83b7\u53d6\u6700\u8fd1\u65e5\u5fd7\nlog = droid.getLastLog().result\nprint(f\"Log: {log}\")\n
      "},{"location":"qsl4a/system/sensors/","title":"\u4f20\u611f\u5668 API","text":"

      \u8bbf\u95ee\u8bbe\u5907\u4f20\u611f\u5668\uff0c\u5305\u62ec\u52a0\u901f\u5ea6\u8ba1\u3001\u9640\u87ba\u4eea\u3001\u78c1\u529b\u8ba1\u7b49\u3002

      "},{"location":"qsl4a/system/sensors/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/sensors/#startsensingtimed","title":"startSensingTimed()","text":"

      \u5f00\u59cb\u4f20\u611f\u5668\u76d1\u63a7\u5e76\u8bbe\u7f6e\u65f6\u95f4\u95f4\u9694\u3002

      startSensingTimed(sensorNumber, delayTime)\n

      \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID\uff08\u901a\u5e38\u4e3a 1-3\uff09 - delayTime (int): \u8bfb\u53d6\u4e4b\u95f4\u7684\u5ef6\u8fdf\uff08\u6beb\u79d2\uff09

      "},{"location":"qsl4a/system/sensors/#startsensingthreshold","title":"startSensingThreshold()","text":"

      \u5f00\u59cb\u5e26\u9608\u503c\u89e6\u53d1\u7684\u4f20\u611f\u5668\u76d1\u63a7\u3002

      startSensingThreshold(sensorNumber, threshold, axis)\n

      \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID - threshold (float): \u89e6\u53d1\u9608\u503c - axis (int): \u8981\u76d1\u63a7\u7684\u8f74\uff080=X\uff0c1=Y\uff0c2=Z\uff09

      "},{"location":"qsl4a/system/sensors/#stopsensing","title":"stopSensing()","text":"

      \u505c\u6b62\u6240\u6709\u4f20\u611f\u5668\u76d1\u63a7\u3002

      stopSensing()\n
      "},{"location":"qsl4a/system/sensors/#readsensors","title":"readSensors()","text":"

      \u8bfb\u53d6\u5f53\u524d\u4f20\u611f\u5668\u6570\u636e\u3002

      readSensors()\n

      \u8fd4\u56de\uff1a \u4f20\u611f\u5668\u6570\u636e\u5b57\u5178

      "},{"location":"qsl4a/system/sensors/#sensorsreadaccelerometer","title":"sensorsReadAccelerometer()","text":"

      \u8bfb\u53d6\u52a0\u901f\u5ea6\u8ba1\u503c\u3002

      sensorsReadAccelerometer()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d m/s\u00b2

      "},{"location":"qsl4a/system/sensors/#sensorsreadgyroscope","title":"sensorsReadGyroscope()","text":"

      \u8bfb\u53d6\u9640\u87ba\u4eea\u503c\u3002

      sensorsReadGyroscope()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d rad/s

      "},{"location":"qsl4a/system/sensors/#sensorsreadmagnetometer","title":"sensorsReadMagnetometer()","text":"

      \u8bfb\u53d6\u78c1\u573a\u503c\u3002

      sensorsReadMagnetometer()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d \u03bcT

      "},{"location":"qsl4a/system/sensors/#sensorsreadorientation","title":"sensorsReadOrientation()","text":"

      \u8bfb\u53d6\u8bbe\u5907\u65b9\u5411\u3002

      sensorsReadOrientation()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [azimuth, pitch, roll]\uff0c\u5355\u4f4d\u5ea6

      "},{"location":"qsl4a/system/sensors/#sensorsgetlight","title":"sensorsGetLight()","text":"

      \u8bfb\u53d6\u5149\u4f20\u611f\u5668\u503c\u3002

      sensorsGetLight()\n

      \u8fd4\u56de\uff1a \u5149\u7ea7\u522b\uff08lux\uff09

      "},{"location":"qsl4a/system/sensors/#sensorsgetstepcounter","title":"sensorsGetStepCounter()","text":"

      \u8bfb\u53d6\u6b65\u8ba1\u6570\u5668\u3002

      sensorsGetStepCounter()\n

      \u8fd4\u56de\uff1a \u6b65\u6570

      "},{"location":"qsl4a/system/sensors/#sensorsgetaccuracy","title":"sensorsGetAccuracy()","text":"

      \u83b7\u53d6\u5f53\u524d\u4f20\u611f\u5668\u7cbe\u5ea6\u3002

      sensorsGetAccuracy()\n

      \u8fd4\u56de\uff1a \u7cbe\u5ea6\u503c\uff080-3\uff1aUNRELIABLE\u3001ACCURACY_LOW\u3001ACCURACY_MEDIUM\u3001ACCURACY_HIGH\uff09

      "},{"location":"qsl4a/system/sensors/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u8bfb\u53d6\u4f20\u611f\u5668 10 \u6b21\nfor i in range(10):\n    accel = droid.sensorsReadAccelerometer().result\n    print(f\"Accel: X={accel[0]:.2f}, Y={accel[1]:.2f}, Z={accel[2]:.2f}\")\n    time.sleep(0.5)\n\ndroid.stopSensing()\n
      "},{"location":"qsl4a/system/settings/","title":"\u8bbe\u7f6e API","text":"

      \u63a7\u5236\u7cfb\u7edf\u8bbe\u7f6e\uff0c\u5305\u62ec\u5c4f\u5e55\u3001\u58f0\u97f3\u548c\u7f51\u7edc\u8bbe\u7f6e\u3002

      "},{"location":"qsl4a/system/settings/#_1","title":"\u5c4f\u5e55\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#setscreentimeout","title":"setScreenTimeout()","text":"

      \u8bbe\u7f6e\u5c4f\u5e55\u8d85\u65f6\u503c\u3002

      setScreenTimeout(value)\n

      \u53c2\u6570\uff1a - value (int): \u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

      \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u8d85\u65f6\u503c

      "},{"location":"qsl4a/system/settings/#getscreentimeout","title":"getScreenTimeout()","text":"

      \u83b7\u53d6\u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u3002

      getScreenTimeout()\n

      \u8fd4\u56de\uff1a \u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

      "},{"location":"qsl4a/system/settings/#getscreenbrightness","title":"getScreenBrightness()","text":"

      \u83b7\u53d6\u5c4f\u5e55\u4eae\u5ea6\u503c\u3002

      getScreenBrightness()\n

      \u8fd4\u56de\uff1a \u4eae\u5ea6\u503c\uff080-255\uff09

      "},{"location":"qsl4a/system/settings/#setscreenbrightness","title":"setScreenBrightness()","text":"

      \u8bbe\u7f6e\u5c4f\u5e55\u4eae\u5ea6\u3002

      setScreenBrightness(value=None)\n

      \u53c2\u6570\uff1a - value (int, optional): \u4eae\u5ea6\u503c\uff080-255\uff09\uff0c\u6216 None \u8868\u793a\u81ea\u52a8

      \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u4eae\u5ea6\u503c

      "},{"location":"qsl4a/system/settings/#checkscreenon","title":"checkScreenOn()","text":"

      \u68c0\u67e5\u5c4f\u5e55\u662f\u5426\u4eae\u7740\u3002

      checkScreenOn()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u5c4f\u5e55\u4eae\u7740\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/system/settings/#_2","title":"\u98de\u884c\u6a21\u5f0f","text":""},{"location":"qsl4a/system/settings/#checkairplanemode","title":"checkAirplaneMode()","text":"

      \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\u662f\u5426\u542f\u7528\u3002

      checkAirplaneMode()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u98de\u884c\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

      "},{"location":"qsl4a/system/settings/#_3","title":"\u94c3\u58f0\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#checkringersilentmode","title":"checkRingerSilentMode()","text":"

      \u68c0\u67e5\u94c3\u58f0\u662f\u5426\u5904\u4e8e\u9759\u97f3\u6a21\u5f0f\u3002

      checkRingerSilentMode()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u9759\u97f3\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

      "},{"location":"qsl4a/system/settings/#toggleringersilentmode","title":"toggleRingerSilentMode()","text":"

      \u5207\u6362\u94c3\u58f0\u9759\u97f3\u6a21\u5f0f\u3002

      toggleRingerSilentMode(enabled=None)\n

      \u53c2\u6570\uff1a - enabled (bool, optional): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

      \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

      "},{"location":"qsl4a/system/settings/#togglevibratemode","title":"toggleVibrateMode()","text":"

      \u5207\u6362\u632f\u52a8\u6a21\u5f0f\u3002

      toggleVibrateMode(enabled=None, ringer=None)\n

      \u53c2\u6570\uff1a - enabled (bool, optional): \u5207\u6362\u632f\u52a8\u5f00/\u5173 - ringer (bool, optional): \u5e94\u7528\u4e8e\u94c3\u58f0\u6a21\u5f0f

      \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

      "},{"location":"qsl4a/system/settings/#getvibratemode","title":"getVibrateMode()","text":"

      \u83b7\u53d6\u632f\u52a8\u6a21\u5f0f\u8bbe\u7f6e\u3002

      getVibrateMode(ringer=None)\n

      \u53c2\u6570\uff1a - ringer (bool, optional): \u68c0\u67e5\u94c3\u58f0\u632f\u52a8\u6a21\u5f0f

      \u8fd4\u56de\uff1a \u5982\u679c\u632f\u52a8\u5df2\u542f\u7528\u5219\u4e3a True

      "},{"location":"qsl4a/system/settings/#_4","title":"\u97f3\u91cf\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#getringervolume","title":"getRingerVolume()","text":"

      \u83b7\u53d6\u5f53\u524d\u94c3\u58f0\u97f3\u91cf\u3002

      getRingerVolume()\n

      \u8fd4\u56de\uff1a \u94c3\u58f0\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-7\uff09

      "},{"location":"qsl4a/system/settings/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

      getMaxRingerVolume()\n

      \u8fd4\u56de\uff1a \u6700\u5927\u94c3\u58f0\u97f3\u91cf

      "},{"location":"qsl4a/system/settings/#setringervolume","title":"setRingerVolume()","text":"

      \u8bbe\u7f6e\u94c3\u58f0\u97f3\u91cf\u3002

      setRingerVolume(volume)\n

      \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

      "},{"location":"qsl4a/system/settings/#getmediavolume","title":"getMediaVolume()","text":"

      \u83b7\u53d6\u5f53\u524d\u5a92\u4f53\u97f3\u91cf\u3002

      getMediaVolume()\n

      \u8fd4\u56de\uff1a \u5a92\u4f53\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-15\uff09

      "},{"location":"qsl4a/system/settings/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

      getMaxMediaVolume()\n

      \u8fd4\u56de\uff1a \u6700\u5927\u5a92\u4f53\u97f3\u91cf

      "},{"location":"qsl4a/system/settings/#setmediavolume","title":"setMediaVolume()","text":"

      \u8bbe\u7f6e\u5a92\u4f53\u97f3\u91cf\u3002

      setMediaVolume(volume)\n

      \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

      "},{"location":"qsl4a/system/settings/#_5","title":"\u7cfb\u7edf\u4fe1\u606f","text":""},{"location":"qsl4a/system/settings/#elapsedrealtimenanos","title":"elapsedRealtimeNanos()","text":"

      \u83b7\u53d6\u81ea\u7cfb\u7edf\u542f\u52a8\u4ee5\u6765\u7684\u7eb3\u79d2\u6570\u3002

      elapsedRealtimeNanos()\n

      \u8fd4\u56de\uff1a \u7eb3\u79d2\u6570\uff08\u53ef\u7528\u4e8e\u8ba1\u65f6\uff09

      "},{"location":"qsl4a/system/settings/#gettrafficstats","title":"getTrafficStats()","text":"

      \u83b7\u53d6\u7f51\u7edc\u6d41\u91cf\u7edf\u8ba1\u3002

      getTrafficStats(flags=7)\n

      \u53c2\u6570\uff1a - flags (int): \u8981\u68c0\u7d22\u7684\u7edf\u8ba1\uff08\u9ed8\u8ba4\uff1a7 = \u5168\u90e8\uff09

      \u8fd4\u56de\uff1a \u5305\u542b\u53d1\u9001/\u63a5\u6536\u5b57\u8282\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/settings/#getapptxbytes","title":"getAppTxBytes()","text":"

      \u83b7\u53d6 QPython \u5e94\u7528\u7684\u53d1\u9001\u5b57\u8282\u3002

      getAppTxBytes(packageName)\n

      \u53c2\u6570\uff1a - packageName (str): \u5305\u540d

      \u8fd4\u56de\uff1a \u5305\u542b tx/rx \u5b57\u8282\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/settings/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5c4f\u5e55\u8bbe\u7f6e\ncurrent_timeout = droid.getScreenTimeout().result\nprint(f\"Current timeout: {current_timeout}s\")\ndroid.setScreenTimeout(30)\n\n# \u68c0\u67e5\u5c4f\u5e55\nif droid.checkScreenOn().result:\n    print(\"Screen is on\")\n\n# \u97f3\u91cf\u63a7\u5236\nmedia_vol = droid.getMediaVolume().result\nprint(f\"Media volume: {media_vol}\")\ndroid.setMediaVolume(10)\n\n# \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\nif droid.checkAirplaneMode().result:\n    print(\"Airplane mode is on\")\n
      "},{"location":"qsl4a/system/sysinfo/","title":"\u7cfb\u7edf\u4fe1\u606f","text":"

      \u68c0\u7d22\u8bbe\u5907\u548c\u7cfb\u7edf\u4fe1\u606f\u3002

      "},{"location":"qsl4a/system/sysinfo/#_2","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/sysinfo/#getandroidid","title":"getAndroidID()","text":"

      \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

      getAndroidID()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

      "},{"location":"qsl4a/system/sysinfo/#getsysinfo","title":"getSysInfo()","text":"

      \u83b7\u53d6\u7efc\u5408\u7cfb\u7edf\u4fe1\u606f\u3002

      getSysInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/sysinfo/#getlocale","title":"getLocale()","text":"

      \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u8bbe\u7f6e\u3002

      getLocale()\n

      \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

      "},{"location":"qsl4a/system/sysinfo/#_3","title":"\u5185\u5b58","text":""},{"location":"qsl4a/system/sysinfo/#getmemoryinfo","title":"getMemoryInfo()","text":"

      \u83b7\u53d6 RAM \u4fe1\u606f\u3002

      getMemoryInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/sysinfo/#_4","title":"\u663e\u793a","text":""},{"location":"qsl4a/system/sysinfo/#getscreeninfo","title":"getScreenInfo()","text":"

      \u83b7\u53d6\u663e\u793a\u4fe1\u606f\u3002

      getScreenInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/sysinfo/#_5","title":"\u6807\u8bc6\u7b26","text":""},{"location":"qsl4a/system/sysinfo/#getimei","title":"getImei()","text":"

      \u83b7\u53d6\u8bbe\u5907 IMEI\u3002

      getImei(slotIndex=None)\n
      "},{"location":"qsl4a/system/sysinfo/#getmeid","title":"getMeid()","text":"

      \u83b7\u53d6\u8bbe\u5907 MEID\u3002

      getMeid(slotIndex=None)\n
      "},{"location":"qsl4a/system/sysinfo/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u8bbe\u5907 ID\nandroid_id = droid.getAndroidID().result\nprint(f\"Android ID: {android_id}\")\n\n# \u5c4f\u5e55\u4fe1\u606f\nscreen = droid.getScreenInfo().result\nprint(f\"Screen: {screen['width']}x{screen['height']}\")\n\n# \u5185\u5b58\nmemory = droid.getMemoryInfo().result\nprint(f\"Memory: {memory}\")\n
      "},{"location":"qsl4a/system/wakelock/","title":"WakeLock API","text":"

      \u63a7\u5236\u8bbe\u5907\u5524\u9192\u9501\u4ee5\u4fdd\u6301 CPU \u6216\u5c4f\u5e55\u5f00\u542f\u3002

      "},{"location":"qsl4a/system/wakelock/#wake-lock","title":"Wake Lock \u7c7b\u578b","text":"

      QSL4A \u63d0\u4f9b\u4e0d\u540c\u7c7b\u578b\u7684\u5524\u9192\u9501\uff1a

      \u7c7b\u578b \u63cf\u8ff0 Full CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae Partial \u4ec5 CPU \u5f00\u542f Bright CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae Dim CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697"},{"location":"qsl4a/system/wakelock/#wake-lock_1","title":"Wake Lock \u65b9\u6cd5","text":""},{"location":"qsl4a/system/wakelock/#wakelockacquirefull","title":"wakeLockAcquireFull()","text":"

      \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae\uff09\u3002

      wakeLockAcquireFull()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquirepartial","title":"wakeLockAcquirePartial()","text":"

      \u83b7\u53d6\u90e8\u5206\u5524\u9192\u9501\uff08\u4ec5 CPU \u5f00\u542f\uff09\u3002

      wakeLockAcquirePartial()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquirebright","title":"wakeLockAcquireBright()","text":"

      \u83b7\u53d6\u660e\u4eae\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff09\u3002

      wakeLockAcquireBright()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquiredim","title":"wakeLockAcquireDim()","text":"

      \u83b7\u53d6\u6697\u6de1\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697\uff09\u3002

      wakeLockAcquireDim()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockrelease","title":"wakeLockRelease()","text":"

      \u91ca\u653e\u5524\u9192\u9501\u3002

      wakeLockRelease()\n
      "},{"location":"qsl4a/system/wakelock/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\ndroid.wakeLockAcquireFull()\n\n# \u5728\u4fdd\u6301\u5c4f\u5e55\u5f00\u542f\u65f6\u6267\u884c\u91cd\u8981\u5de5\u4f5c\nprint(\"Screen will stay on\")\ntime.sleep(10)\n\n# \u5b8c\u6210\u540e\u91ca\u653e\ndroid.wakeLockRelease()\n\n# \u6216\u4f7f\u7528\u90e8\u5206\u9501\u8fdb\u884c\u540e\u53f0\u4efb\u52a1\ndroid.wakeLockAcquirePartial()\n# \u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\uff0cCPU \u4ecd\u4fdd\u6301\u5f00\u542f\ntime.sleep(30)\ndroid.wakeLockRelease()\n

      \u6ce8\u610f\uff1a \u8bb0\u4f4f\u5728\u4e0d\u9700\u8981\u65f6\u91ca\u653e\u5524\u9192\u9501\u4ee5\u8282\u7701\u7535\u6c60\u3002

      "},{"location":"qsl4a/ui/accessibility/","title":"\u65e0\u969c\u788d\u670d\u52a1","text":"

      \u65e0\u969c\u788d\u670d\u52a1\u5141\u8bb8\u81ea\u52a8\u5316 UI \u4ea4\u4e92\uff0c\u5982\u70b9\u51fb\u3001\u6ed1\u52a8\u548c\u7cfb\u7edf\u64cd\u4f5c\u3002

      "},{"location":"qsl4a/ui/accessibility/#_2","title":"\u670d\u52a1\u63a7\u5236","text":""},{"location":"qsl4a/ui/accessibility/#accessibilitystartservice","title":"accessibilityStartService()","text":"

      \u542f\u52a8\u65e0\u969c\u788d\u670d\u52a1\u3002

      accessibilityStartService()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/ui/accessibility/#accessibilityserviceenabled","title":"accessibilityServiceEnabled()","text":"

      \u68c0\u67e5\u65e0\u969c\u788d\u670d\u52a1\u662f\u5426\u5df2\u542f\u7528\u3002

      accessibilityServiceEnabled()\n

      \u8fd4\u56de\uff1a True \u6216 False

      "},{"location":"qsl4a/ui/accessibility/#_3","title":"\u5c4f\u5e55\u4ea4\u4e92","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityclick","title":"accessibilityClick()","text":"

      \u5728\u5c4f\u5e55\u5750\u6807\u5904\u70b9\u51fb\u3002

      accessibilityClick(x=0, y=0, t=50)\n

      \u53c2\u6570\uff1a - x (int/float): X \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - y (int/float): Y \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - t (int): \u6309\u4f4f\u65f6\u957f\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a50\uff09

      "},{"location":"qsl4a/ui/accessibility/#accessibilityslide","title":"accessibilitySlide()","text":"

      \u591a\u70b9\u6ed1\u52a8\u624b\u52bf\u3002

      accessibilitySlide(XnYn=None, t=None)\n

      \u53c2\u6570\uff1a - XnYn (list): \u5750\u6807 [X1, Y1, X2, Y2, ... Xn, Yn] - t (int): \u6ed1\u52a8\u65f6\u957f\uff08\u9ed8\u8ba4\uff1a50*n \u6beb\u79d2\uff09

      "},{"location":"qsl4a/ui/accessibility/#_4","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityaction","title":"accessibilityAction()","text":"

      \u6309\u4ee3\u7801\u6267\u884c\u7cfb\u7edf\u64cd\u4f5c\u3002

      accessibilityAction(actionCode)\n

      \u64cd\u4f5c\u4ee3\u7801\uff1a | \u4ee3\u7801 | \u5e38\u91cf | \u63cf\u8ff0 | |------|----------|-------------| | 1 | BACK | \u8fd4\u56de\u6309\u94ae | | 2 | HOME | \u4e3b\u5c4f\u5e55\u6309\u94ae | | 3 | RECENTS | \u6700\u8fd1\u5e94\u7528 | | 4 | NOTIFICATIONS | \u6253\u5f00\u901a\u77e5 | | 5 | QUICK_SETTINGS | \u6253\u5f00\u5feb\u901f\u8bbe\u7f6e | | 6 | POWER_DIALOG | \u7535\u6e90\u83dc\u5355 | | 7 | TOGGLE_SPLIT_SCREEN | \u5206\u5c4f | | 8 | LOCK_SCREEN | \u9501\u5c4f | | 9 | TAKE_SCREENSHOT | \u622a\u56fe | | 10 | KEYCODE_HEADSETHOOK | \u8033\u673a\u6302\u94a9 | | 11-14 | ACCESSIBILITY_ | \u65e0\u969c\u788d\u6309\u94ae | | 15 | DISMISS_NOTIFICATION_SHADE | \u5173\u95ed\u901a\u77e5\u680f | | 16-20 | DPAD_ | \u65b9\u5411\u952e | | 21 | MENU | \u83dc\u5355\u6309\u94ae | | 22 | MEDIA_PLAY_PAUSE | \u64ad\u653e/\u6682\u505c\u5a92\u4f53 |

      "},{"location":"qsl4a/ui/accessibility/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/accessibility/#_6","title":"\u70b9\u51fb\u5c4f\u5e55\u4e2d\u5fc3","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u670d\u52a1\nif not droid.accessibilityServiceEnabled().result:\n    droid.accessibilityStartService()\n\n# \u70b9\u51fb\u4e2d\u5fc3\uff080,0 = \u4e2d\u5fc3\uff09\ndroid.accessibilityClick(0, 0, t=100)\n
      "},{"location":"qsl4a/ui/accessibility/#_7","title":"\u6ed1\u52a8\u624b\u52bf","text":"
      # \u4ece\u4e0b\u5f80\u4e0a\u6ed1\u52a8\uff08\u5411\u4e0a\u6eda\u52a8\uff09\ndroid.accessibilitySlide([0, 1.5, 0, -1.5], t=300)\n
      "},{"location":"qsl4a/ui/accessibility/#_8","title":"\u7cfb\u7edf\u5bfc\u822a","text":"
      # \u6309\u4e3b\u5c4f\u5e55\ndroid.accessibilityAction(2)\n\n# \u6309\u8fd4\u56de\ndroid.accessibilityAction(1)\n\n# \u6253\u5f00\u901a\u77e5\ndroid.accessibilityAction(4)\n
      "},{"location":"qsl4a/ui/accessibility/#_9","title":"\u70b9\u51fb\u7279\u5b9a\u4f4d\u7f6e","text":"
      # \u70b9\u51fb\u5c4f\u5e55\u5750\u6807 (500, 800)\ndroid.accessibilityClick(500, 800)\n\n# \u70b9\u51fb\u76f8\u5bf9\u4f4d\u7f6e\uff08\u6c34\u5e73\u5c45\u4e2d\uff0c\u5782\u76f4 3/4 \u5904\uff09\ndroid.accessibilityClick(0, 1.5)\n
      "},{"location":"qsl4a/ui/dialogs/","title":"\u5bf9\u8bdd\u6846\u7cfb\u7edf","text":"

      QSL4A \u63d0\u4f9b\u5168\u9762\u7684\u5bf9\u8bdd\u6846\u652f\u6301\uff0c\u7528\u4e8e\u7528\u6237\u4ea4\u4e92\uff0c\u5305\u62ec\u8b66\u62a5\u3001\u8f93\u5165\u5bf9\u8bdd\u6846\u3001\u9009\u62e9\u5bf9\u8bdd\u6846\u548c\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

      "},{"location":"qsl4a/ui/dialogs/#_2","title":"\u8b66\u62a5\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowalert","title":"dialogShowAlert()","text":"

      \u663e\u793a\u7b80\u5355\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

      dialogShowAlert(title=\"Alert\", message=\"The message of the alert.\",\n                positiveButtonText=\"OK\", negativeButtonText=None,\n                neutralButtonText=None, messageIsHtml=False)\n

      \u53c2\u6570\uff1a - title (str): \u5bf9\u8bdd\u6846\u6807\u9898 - message (str): \u6d88\u606f\u6587\u672c - positiveButtonText (str): \u80af\u5b9a\u6309\u94ae\u6807\u7b7e - negativeButtonText (str, optional): \u5426\u5b9a\u6309\u94ae\u6807\u7b7e - neutralButtonText (str, optional): \u4e2d\u6027\u6309\u94ae\u6807\u7b7e - messageIsHtml (bool): \u5c06\u6d88\u606f\u89e3\u6790\u4e3a HTML

      \u8fd4\u56de\uff1a \u5305\u542b\u70b9\u51fb\u6309\u94ae\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#dialogshowsimplechoice","title":"dialogShowSimpleChoice()","text":"

      \u663e\u793a\u5e26\u6709\u9879\u76ee\u7684\u7b80\u5355\u9009\u62e9\u5bf9\u8bdd\u6846\u3002

      dialogShowSimpleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

      \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868

      \u8fd4\u56de\uff1a \u5305\u542b\u9009\u4e2d\u9879\u76ee\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#_3","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialoggetinput","title":"dialogGetInput()","text":"

      \u83b7\u53d6\u7528\u6237\u6587\u672c\u8f93\u5165\u3002

      dialogGetInput(title=\"Value\", message=\"Please enter value:\",\n               defaultText=None, messageIsHtml=False)\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7528\u6237\u8f93\u5165\u6587\u672c\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#dialoggetpassword","title":"dialogGetPassword()","text":"

      \u83b7\u53d6\u5bc6\u7801\u8f93\u5165\u3002

      dialogGetPassword(title=\"Password\", message=\"Please enter password:\")\n

      \u8fd4\u56de\uff1a \u5305\u542b\u8f93\u5165\u5bc6\u7801\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#dialogcreateinput","title":"dialogCreateInput()","text":"

      \u521b\u5efa\u81ea\u5b9a\u4e49\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

      dialogCreateInput(title=\"Value\", message=\"Please enter value:\",\n                  defaultText=None, inputType=None)\n

      \u53c2\u6570\uff1a - inputType (str): \u8f93\u5165\u7c7b\u578b\uff08\u4f8b\u5982 \"text\"\u3001\"number\"\u3001\"textPassword\"\uff09

      "},{"location":"qsl4a/ui/dialogs/#dialogcreatepassword","title":"dialogCreatePassword()","text":"

      \u521b\u5efa\u5bc6\u7801\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

      dialogCreatePassword(title=\"Password\", message=\"Please enter password:\")\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreateseekbar","title":"dialogCreateSeekBar()","text":"

      \u521b\u5efa\u6ed1\u5757/\u8fdb\u5ea6\u6761\u5bf9\u8bdd\u6846\u3002

      dialogCreateSeekBar(starting_value=50, maximum_value=100, title=\"\", message=\"\")\n

      \u53c2\u6570\uff1a - starting_value (int): \u521d\u59cb\u503c - maximum_value (int): \u6700\u5927\u503c

      "},{"location":"qsl4a/ui/dialogs/#_4","title":"\u9009\u62e9\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowsinglechoice","title":"dialogShowSingleChoice()","text":"

      \u663e\u793a\u5355\u9009\uff08\u5355\u9009\u6309\u94ae\uff09\u5bf9\u8bdd\u6846\u3002

      dialogShowSingleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, selected=-1, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

      \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (int): \u9ed8\u8ba4\u9009\u4e2d\u7d22\u5f15

      "},{"location":"qsl4a/ui/dialogs/#dialogshowmultichoice","title":"dialogShowMultiChoice()","text":"

      \u663e\u793a\u591a\u9009\uff08\u590d\u9009\u6846\uff09\u5bf9\u8bdd\u6846\u3002

      dialogShowMultiChoice(title=\"Alert\", message=\"The message of the alert.\",\n                      items=None, selected=None, positiveButtonText=\"OK\",\n                      negativeButtonText=None, neutralButtonText=None,\n                      messageIsHtml=False)\n

      \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (list): \u521d\u59cb\u9009\u4e2d\u7d22\u5f15\u5217\u8868

      "},{"location":"qsl4a/ui/dialogs/#dialogsetsinglechoiceitems","title":"dialogSetSingleChoiceItems()","text":"

      \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u5355\u9009\u9879\u76ee\u3002

      dialogSetSingleChoiceItems(items, selected=-1)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmultichoiceitems","title":"dialogSetMultiChoiceItems()","text":"

      \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u591a\u9009\u9879\u76ee\u3002

      dialogSetMultiChoiceItems(items, selected=None)\n
      "},{"location":"qsl4a/ui/dialogs/#_5","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatespinnerprogress","title":"dialogCreateSpinnerProgress()","text":"

      \u521b\u5efa\u4e0d\u786e\u5b9a\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

      dialogCreateSpinnerProgress(title=None, message=None, maximum_progress=100)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreatehorizontalprogress","title":"dialogCreateHorizontalProgress()","text":"

      \u521b\u5efa\u6c34\u5e73\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

      dialogCreateHorizontalProgress(title=None, message=None, maximum_progress=100)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetcurrentprogress","title":"dialogSetCurrentProgress()","text":"

      \u66f4\u65b0\u8fdb\u5ea6\u503c\u3002

      dialogSetCurrentProgress(current)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmaxprogress","title":"dialogSetMaxProgress()","text":"

      \u8bbe\u7f6e\u6700\u5927\u8fdb\u5ea6\u503c\u3002

      dialogSetMaxProgress(max)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetprogressmessage","title":"dialogSetProgressMessage()","text":"

      \u66f4\u65b0\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u6d88\u606f\u3002

      dialogSetProgressMessage(message)\n
      "},{"location":"qsl4a/ui/dialogs/#_6","title":"\u9009\u62e9\u5668\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatedatepicker","title":"dialogCreateDatePicker()","text":"

      \u521b\u5efa\u65e5\u671f\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

      dialogCreateDatePicker(year=1970, month=1, day=1)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreatetimepicker","title":"dialogCreateTimePicker()","text":"

      \u521b\u5efa\u65f6\u95f4\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

      dialogCreateTimePicker(hour=0, minute=0, is24hour=False)\n
      "},{"location":"qsl4a/ui/dialogs/#_7","title":"\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u521b\u5efa","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatealert","title":"dialogCreateAlert()","text":"

      \u521b\u5efa\u81ea\u5b9a\u4e49\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

      dialogCreateAlert(title=None, message=None)\n

      \u521b\u5efa\u4e00\u4e2a\u7a7a\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002\u53ef\u4e0e\u5176\u4ed6 dialogSet* \u51fd\u6570\u4e00\u8d77\u4f7f\u7528\u6765\u81ea\u5b9a\u4e49\u3002

      "},{"location":"qsl4a/ui/dialogs/#dialogsetitems","title":"dialogSetItems()","text":"

      \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u7b80\u5355\u5217\u8868\u9879\u76ee\u3002

      dialogSetItems(items)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetpositivebuttontext","title":"dialogSetPositiveButtonText()","text":"

      \u8bbe\u7f6e\u80af\u5b9a\u6309\u94ae\u6587\u672c\u3002

      dialogSetPositiveButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetnegativebuttontext","title":"dialogSetNegativeButtonText()","text":"

      \u8bbe\u7f6e\u5426\u5b9a\u6309\u94ae\u6587\u672c\u3002

      dialogSetNegativeButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetneutralbuttontext","title":"dialogSetNeutralButtonText()","text":"

      \u8bbe\u7f6e\u4e2d\u6027\u6309\u94ae\u6587\u672c\u3002

      dialogSetNeutralButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmessageishtml","title":"dialogSetMessageIsHtml()","text":"

      \u8bbe\u7f6e\u6d88\u606f\u662f\u5426\u5e94\u89e3\u6790\u4e3a HTML\u3002

      dialogSetMessageIsHtml(messageIsHtml=True)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogshow","title":"dialogShow()","text":"

      \u663e\u793a\u521b\u5efa\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u3002

      dialogShow()\n
      "},{"location":"qsl4a/ui/dialogs/#_8","title":"\u5bf9\u8bdd\u6846\u63a7\u5236","text":""},{"location":"qsl4a/ui/dialogs/#dialogdismiss","title":"dialogDismiss()","text":"

      \u5173\u95ed\u5f53\u524d\u5bf9\u8bdd\u6846\u3002

      dialogDismiss()\n
      "},{"location":"qsl4a/ui/dialogs/#dialoggetresponse","title":"dialogGetResponse()","text":"

      \u83b7\u53d6\u5bf9\u8bdd\u6846\u54cd\u5e94\u3002

      dialogGetResponse()\n
      "},{"location":"qsl4a/ui/dialogs/#dialoggetselecteditems","title":"dialogGetSelectedItems()","text":"

      \u4ece\u9009\u62e9\u5bf9\u8bdd\u6846\u83b7\u53d6\u9009\u4e2d\u7684\u9879\u76ee\u3002

      dialogGetSelectedItems()\n
      "},{"location":"qsl4a/ui/dialogs/#_9","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/dialogs/#_10","title":"\u7b80\u5355\u8b66\u62a5","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a\u8b66\u62a5\ndroid.dialogShowAlert(\"Warning\", \"This is an important message!\")\n
      "},{"location":"qsl4a/ui/dialogs/#_11","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":"
      # \u83b7\u53d6\u7528\u6237\u8f93\u5165\nresult = droid.dialogGetInput(\"Name\", \"Enter your name:\", \"John\").result\nprint(f\"Hello, {result}!\")\n
      "},{"location":"qsl4a/ui/dialogs/#_12","title":"\u5e26\u6309\u94ae\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846","text":"
      # \u521b\u5efa\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\ndroid.dialogCreateAlert(\"Custom\", \"Choose an option\")\ndroid.dialogSetItems([\"Option 1\", \"Option 2\", \"Option 3\"])\ndroid.dialogShow()\n\n# \u83b7\u53d6\u54cd\u5e94\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response['item']}\")\n
      "},{"location":"qsl4a/ui/dialogs/#_13","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":"
      # \u521b\u5efa\u8fdb\u5ea6\u5bf9\u8bdd\u6846\ndroid.dialogCreateHorizontalProgress(\"Loading\", \"Please wait...\", 100)\ndroid.dialogShow()\n\n# \u66f4\u65b0\u8fdb\u5ea6\nfor i in range(101):\n    droid.dialogSetCurrentProgress(i)\n    time.sleep(0.05)\n\ndroid.dialogDismiss()\n
      "},{"location":"qsl4a/ui/dialogs/#_14","title":"\u65e5\u671f\u9009\u62e9\u5668","text":"
      # \u663e\u793a\u65e5\u671f\u9009\u62e9\u5668\ndroid.dialogCreateDatePicker(2024, 1, 15)\ndroid.dialogShow()\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response}\")\n
      "},{"location":"qsl4a/ui/floatview/","title":"\u6d6e\u52a8\u89c6\u56fe","text":"

      \u6d6e\u52a8\u7a97\u53e3\u652f\u6301\uff0c\u7528\u4e8e\u5728\u5176\u4ed6\u5e94\u7528\u7a0b\u5e8f\u4e0a\u65b9\u4fdd\u6301\u663e\u793a\u7684\u8986\u76d6 UI \u5143\u7d20\u3002

      "},{"location":"qsl4a/ui/floatview/#_2","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/floatview/#floatview","title":"floatView()","text":"

      \u663e\u793a\u6216\u4fee\u6539\u6d6e\u52a8\u89c6\u56fe\u3002

      floatView(Args=None)\n

      \u53c2\u6570\uff1a - Args (dict): \u914d\u7f6e\u5b57\u5178\uff0c\u5305\u542b\u4ee5\u4e0b\u952e\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08-1 \u521b\u5efa\u65b0\u7684\uff0c>=0 \u4fee\u6539\u73b0\u6709\u7684\uff09 - text (str): \u8981\u663e\u793a\u7684\u6587\u672c\u5185\u5bb9 - html (str): HTML \u5185\u5bb9\uff08\u5982\u679c\u7701\u7565 text \u5219\u4f7f\u7528\uff09 - width (int): \u89c6\u56fe\u5bbd\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a300\uff09 - height (int): \u89c6\u56fe\u9ad8\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a150\uff09 - x (int): X \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - y (int): Y \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - backColor (str): ARGB \u5341\u516d\u8fdb\u5236\u80cc\u666f\u8272\uff08\u9ed8\u8ba4\uff1a'7f7f7f7f'\uff09 - textColor (str): ARGB \u5341\u516d\u8fdb\u5236\u6587\u672c\u8272\uff08\u9ed8\u8ba4\uff1a'ff000000'\uff09 - textSize (int): \u6587\u672c\u5927\u5c0f\uff08\u9ed8\u8ba4\uff1a10\uff09 - textAlign (int): \u6587\u672c\u5bf9\u9f50\uff080 = \u7ee7\u627f\uff09 - script (str): \u957f\u6309\u5173\u95ed\u540e\u8fd0\u884c\u7684\u811a\u672c\u8def\u5f84 - arg: \u811a\u672c\u53c2\u6570 - clickRemove (bool): \u542f\u7528\u70b9\u51fb\u79fb\u9664\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - flag (int): \u7a97\u53e3\u6807\u5fd7\uff08\u9ed8\u8ba4\uff1a40 - \u53ef\u89e6\u6478\uff09

      \u8fd4\u56de\uff1a \u5f53\u524d\u94fe\u5217\u8868\u957f\u5ea6

      "},{"location":"qsl4a/ui/floatview/#floatviewcount","title":"floatViewCount()","text":"

      \u83b7\u53d6\u6d3b\u52a8\u6d6e\u52a8\u89c6\u56fe\u7684\u6570\u91cf\u3002

      floatViewCount()\n

      \u8fd4\u56de\uff1a \u6d6e\u52a8\u89c6\u56fe\u6570\u91cf

      "},{"location":"qsl4a/ui/floatview/#floatviewresult","title":"floatViewResult()","text":"

      \u83b7\u53d6\u6d6e\u52a8\u89c6\u56fe\u7684\u7ed3\u679c/\u72b6\u6001\u3002

      floatViewResult(index=-1)\n

      \u53c2\u6570\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1\uff0c\u8fd4\u56de\u6700\u540e\u64cd\u4f5c\u7ed3\u679c\uff09

      \u8fd4\u56de\uff1a \u5305\u542b\u64cd\u4f5c\u8be6\u60c5\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - x, y: \u4f4d\u7f6e - time: \u65f6\u95f4\u6233 - operation: \u64cd\u4f5c\u7c7b\u578b\uff08'initial'\u3001'move' \u7b49\uff09 - index: \u89c6\u56fe\u7d22\u5f15 - removed: \u5982\u679c\u89c6\u56fe\u88ab\u79fb\u9664\u5219\u4e3a True

      "},{"location":"qsl4a/ui/floatview/#floatviewremove","title":"floatViewRemove()","text":"

      \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\u3002

      floatViewRemove(index=-1)\n

      \u53c2\u6570\uff1a - index (int): \u8981\u79fb\u9664\u7684\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1 \u79fb\u9664\u6700\u540e\u4e00\u4e2a\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a 1\uff0c\u5426\u5219\u4e3a 0

      "},{"location":"qsl4a/ui/floatview/#_3","title":"\u5e38\u91cf","text":"
      • floatView.INDEX_NEW = -1 - \u521b\u5efa\u65b0\u7684\u6d6e\u52a8\u89c6\u56fe
      • floatView.FLAG_DEFAULT_TOUCHABLE = 40 - \u9ed8\u8ba4\u53ef\u89e6\u6478\u6807\u5fd7
      • floatView.TEXT_ALIGNMENT_INHERIT = 0
      • floatView.TEXT_ALIGNMENT_CENTER - \u5c45\u4e2d\u6587\u672c\u5bf9\u9f50
      "},{"location":"qsl4a/ui/floatview/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/floatview/#_5","title":"\u57fa\u672c\u6d6e\u52a8\u89c6\u56fe","text":"
      import androidhelper\nfrom androidhelper import Android\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u7b80\u5355\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'index': -1,  # \u521b\u5efa\u65b0\u7684\n    'text': 'Hello World',\n    'width': 400,\n    'height': 300,\n    'x': -300,  # \u4ece\u4e2d\u5fc3\u504f\u79fb\n    'y': -400,\n    'backColor': 'ff0000',  # \u7ea2\u8272\u80cc\u666f\n    'textColor': '0000ff',  # \u84dd\u8272\u6587\u672c\n    'textSize': 16,\n    'textAlign': droid.floatView.TEXT_ALIGNMENT_CENTER\n})\n\n# \u68c0\u67e5\u6570\u91cf\nprint(f\"Float views: {droid.floatViewCount().result}\")\n\n# \u83b7\u53d6\u7ed3\u679c\nresult = droid.floatViewResult().result\nprint(f\"View info: {result}\")\n\n# \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\ndroid.floatViewRemove(0)\n
      "},{"location":"qsl4a/ui/floatview/#html","title":"HTML \u5185\u5bb9","text":"
      # \u521b\u5efa\u5e26 HTML \u5185\u5bb9\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': '',  # \u7a7a\u6587\u672c\u4ee5\u4f7f\u7528 HTML\n    'html': '<h1>Title</h1><p>Rich <b>HTML</b> content</p>',\n    'width': 500,\n    'height': 400\n})\n
      "},{"location":"qsl4a/ui/floatview/#_6","title":"\u4fee\u6539\u73b0\u6709\u89c6\u56fe","text":"
      # \u521b\u5efa\u521d\u59cb\u89c6\u56fe\ndroid.floatView({'text': 'Initial Text', 'width': 300, 'height': 150})\n\n# \u4fee\u6539\u540c\u4e00\u89c6\u56fe\uff08\u7d22\u5f15 0\uff09\ndroid.floatView({\n    'index': 0,\n    'text': 'Updated Text!',\n    'backColor': '7f00ff00'  # \u7eff\u8272\u80cc\u666f\n})\n\n# \u68c0\u67e5\u79fb\u52a8/\u66f4\u6539\u7ed3\u679c\nresult = droid.floatViewResult(0).result\nprint(f\"Operation: {result.get('operation')}, Position: ({result.get('x')}, {result.get('y')})\")\n
      "},{"location":"qsl4a/ui/floatview/#_7","title":"\u591a\u4e2a\u6d6e\u52a8\u89c6\u56fe","text":"
      # \u521b\u5efa\u591a\u4e2a\u89c6\u56fe\nfor i in range(3):\n    droid.floatView({\n        'index': -1,\n        'text': f'View {i}',\n        'x': i * 100 - 150,\n        'y': i * 100 - 150,\n        'backColor': f'{i}f{i}f{i}f'\n    })\n\nprint(f\"Total views: {droid.floatViewCount().result}\")\n\n# \u79fb\u9664\u6240\u6709\u89c6\u56fe\nwhile droid.floatViewCount().result > 0:\n    droid.floatViewRemove()\n
      "},{"location":"qsl4a/ui/floatview/#_8","title":"\u5e26\u811a\u672c\u56de\u8c03","text":"
      # \u521b\u5efa\u5173\u95ed\u65f6\u8fd0\u884c\u811a\u672c\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': 'Click to close and run script',\n    'script': '/sdcard/my_script.py',\n    'arg': 'hello from float view',\n    'clickRemove': True\n})\n
      "},{"location":"qsl4a/ui/fullscreen/","title":"\u5168\u5c4f UI","text":"

      \u4f7f\u7528\u539f\u751f Android \u5e03\u5c40\u521b\u5efa\u81ea\u5b9a\u4e49\u5168\u5c4f\u754c\u9762\u3002

      "},{"location":"qsl4a/ui/fullscreen/#_1","title":"\u5e03\u5c40\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullshow","title":"fullShow()","text":"

      \u663e\u793a\u5168\u5c4f\u5e03\u5c40\u3002

      fullShow(layout, title=None, theme=None)\n

      \u53c2\u6570\uff1a - layout (str): JSON \u5e03\u5c40\u5b9a\u4e49\u6216\u5e03\u5c40\u5b57\u7b26\u4e32 - title (str, optional): \u7a97\u53e3\u6807\u9898 - theme (str, optional): \u4e3b\u9898\u540d\u79f0

      \u8fd4\u56de\uff1a \u7a97\u53e3 ID

      "},{"location":"qsl4a/ui/fullscreen/#fulldismiss","title":"fullDismiss()","text":"

      \u5173\u95ed\u5168\u5c4f\u7a97\u53e3\u3002

      fullDismiss()\n
      "},{"location":"qsl4a/ui/fullscreen/#fullquery","title":"fullQuery()","text":"

      \u67e5\u8be2\u6240\u6709\u5c0f\u90e8\u4ef6\u503c\u3002

      fullQuery()\n

      \u8fd4\u56de\uff1a \u5c0f\u90e8\u4ef6 ID \u548c\u503c\u7684\u5b57\u5178

      "},{"location":"qsl4a/ui/fullscreen/#fullquerydetail","title":"fullQueryDetail()","text":"

      \u67e5\u8be2\u7279\u5b9a\u5c0f\u90e8\u4ef6\u8be6\u60c5\u3002

      fullQueryDetail(id)\n
      "},{"location":"qsl4a/ui/fullscreen/#_2","title":"\u5c5e\u6027\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperty","title":"fullGetProperty()","text":"

      \u83b7\u53d6\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

      fullGetProperty(id, property)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetproperty","title":"fullSetProperty()","text":"

      \u8bbe\u7f6e\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

      fullSetProperty(id, property, value)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetlist","title":"fullSetList()","text":"

      \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

      fullSetList(id, list, isHtml=False, listType=0)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetlist2","title":"fullSetList2()","text":"

      \u4f7f\u7528\u8d44\u6e90 ID \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

      fullSetList2(id, list, intRes)\n

      \u53c2\u6570\uff1a - id (str): \u5c0f\u90e8\u4ef6 ID - list (list): \u9879\u76ee\u5217\u8868 - intRes (int): \u5217\u8868\u9879\u76ee\u5e03\u5c40\u7684 Android \u8d44\u6e90 ID

      "},{"location":"qsl4a/ui/fullscreen/#fullsetlistselected","title":"fullSetListSelected()","text":"

      \u5728\u5217\u8868\u4e2d\u8bbe\u7f6e\u9009\u4e2d\u9879\u76ee\u3002

      fullSetListSelected(id, selected)\n

      \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID - selected (int): \u8981\u9009\u4e2d\u7684\u9879\u76ee\u7d22\u5f15

      "},{"location":"qsl4a/ui/fullscreen/#fullgetlistselected","title":"fullGetListSelected()","text":"

      \u83b7\u53d6\u5f53\u524d\u9009\u4e2d\u7684\u5217\u8868\u9879\u76ee\u7d22\u5f15\u3002

      fullGetListSelected(id)\n

      \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID

      \u8fd4\u56de\uff1a \u9009\u4e2d\u9879\u76ee\u7d22\u5f15

      "},{"location":"qsl4a/ui/fullscreen/#_3","title":"\u6279\u91cf\u5c5e\u6027\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperties","title":"fullGetProperties()","text":"

      \u4e00\u6b21\u83b7\u53d6\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

      fullGetProperties(ids, property)\n

      \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u83b7\u53d6\u7684\u5c5e\u6027\u540d

      \u8fd4\u56de\uff1a \u6620\u5c04\u5c0f\u90e8\u4ef6 ID \u5230\u5c5e\u6027\u503c\u7684\u5b57\u5178

      "},{"location":"qsl4a/ui/fullscreen/#fullsetproperties","title":"fullSetProperties()","text":"

      \u4e00\u6b21\u8bbe\u7f6e\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

      fullSetProperties(ids, property, value)\n

      \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u8bbe\u7f6e\u7684\u5c5e\u6027\u540d - value: \u5c5e\u6027\u503c

      "},{"location":"qsl4a/ui/fullscreen/#_4","title":"\u622a\u56fe","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetscreenshot","title":"fullGetScreenShot()","text":"

      \u6355\u83b7\u5168\u5c4f\u622a\u56fe\u3002

      fullGetScreenShot(path=None)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u5728\u4e8b\u4ef6\u4e2d\u8fd4\u56de

      \u8fd4\u56de\uff1a \u5305\u542b\u622a\u56fe\u6570\u636e\u7684\u4e8b\u4ef6

      "},{"location":"qsl4a/ui/fullscreen/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b9a\u4e49\u5e03\u5c40\nlayout = '''\n{ \"type\": \"LinearLayout\", \"orientation\": \"vertical\",\n  \"children\": [\n    { \"type\": \"TextView\", \"id\": \"title\", \"text\": \"Hello\" },\n    { \"type\": \"Button\", \"id\": \"btn\", \"text\": \"Click Me\" }\n  ]\n}\n'''\n\n# \u663e\u793a\u5e03\u5c40\ndroid.fullShow(layout, \"My App\")\n\n# \u67e5\u8be2\u6309\u94ae\u70b9\u51fb\nevent = droid.eventWaitFor('click', timeout=10)\nif event.result:\n    widget_id = event.result['data']['id']\n    if widget_id == 'btn':\n        print(\"Button clicked!\")\n\ndroid.fullDismiss()\n
      "}]} \ No newline at end of file diff --git a/zh/sitemap.xml b/zh/sitemap.xml index 5cff379..a7371b5 100644 --- a/zh/sitemap.xml +++ b/zh/sitemap.xml @@ -2,194 +2,198 @@ https://www.qpython.org/zh/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/AIPyApp/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/GraphicalInterface/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/Notebook/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/Ollama/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/Terminal/ - 2026-03-23 + 2026-03-27 + + + https://www.qpython.org/zh/community/ + 2026-03-27 https://www.qpython.org/zh/editor-guide/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/external-api/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/getting-started/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/qpypi-guide/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/qpython-x/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/tutorial-hello-world/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/whats-new/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/qsl4a/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/qsl4a/connectivity/contacts/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/qsl4a/connectivity/ftp/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/qsl4a/connectivity/location/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/qsl4a/connectivity/phone/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/qsl4a/connectivity/signalstrength/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/qsl4a/connectivity/sms/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/qsl4a/connectivity/wifi/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/qsl4a/core/android-base/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/qsl4a/core/events/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/qsl4a/core/intent/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/qsl4a/hardware/bluetooth/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/qsl4a/hardware/camera/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/qsl4a/hardware/recorder/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/qsl4a/hardware/usbserial/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/qsl4a/hardware/webcam/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/qsl4a/media/image/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/qsl4a/media/mediaplayer/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/qsl4a/special/cipher/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/qsl4a/special/pgptai/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/qsl4a/storage/clipboard/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/qsl4a/storage/documentfile/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/qsl4a/storage/preferences/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/qsl4a/system/activityresult/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/qsl4a/system/application/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/qsl4a/system/battery/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/qsl4a/system/qpyinterface/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/qsl4a/system/sensors/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/qsl4a/system/settings/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/qsl4a/system/sysinfo/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/qsl4a/system/wakelock/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/qsl4a/ui/accessibility/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/qsl4a/ui/dialogs/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/qsl4a/ui/floatview/ - 2026-03-23 + 2026-03-27 https://www.qpython.org/zh/qsl4a/ui/fullscreen/ - 2026-03-23 + 2026-03-27 \ No newline at end of file diff --git a/zh/sitemap.xml.gz b/zh/sitemap.xml.gz index 7c2c08cf23703007292b2b009578a26622c85e1d..2f1b0489ccd5a951740ce26c020596e2b2681238 100644 GIT binary patch literal 609 zcmV-n0-pUJiwFpS$i-;_|8r?{Wo=<_E_iKh0L7TiZk#|2$M1QH)!tdQY1J=nHp-<{ zE^QC#1DL^pmHFz}ETKO;L4{A~{`A+^Wr{q_55|F*jRpeC1R&jR&} z!Yj4z?tjd8Ij^euwLl)ofxnM}r2~hn%706OO-hfeihlPV0<0?efF)1_zpAK9A&ik^ zUR4!al2odGq;}m{!Y7Sj9pefztt#B3h-RsZ1&Uz1s-wh6s#e(B~e>7z-YyQCyYjELe)v@*eC|-1C(|GC20JJl9I_> zc!6*buz)2&LG?$A#gbvgRLzFq;GdXLO7A9p%9k zAop3oVpU)*m>2&$Pq|4Nl7u8^j9jootyUabEK)qPV5s3zEfnO@iy=qO zp3JJ*3q%8=zwWagfW9M>{jYy07$c{`mH_9C3`>HUDR#*YV1h?f`$q$Uku)o4QetYz vuf1#cf}qQ_PbMLt;+;<*Co#9W*%ie9$c5*NPNd@>1-_ZN(HH;#!g?pc literal 601 zcmV-f0;c^RiwFpSg1~74|8r?{Wo=<_E_iKh0L7TWj+;OXhVT0nQSO8^TUBk9WVM%8 zdue;vK7bhvSQ%!fV-rH3z9t*3+GDj6<^T+s`9H?SV`l$w>HX@AnJI?D`rT%`USV*t zrqCYNKcBx8AJ-4ZyZw+oqpZ|8@L}DFq|aqJj^l<&u!qE(nA?(FrwuM|7t8JD)B1R~ z(rxbG0^D|ZFe7v?R~MkSCiYd7lHCs z;Xkz=pMFe_DJ`n`HACvifqx2uxdDfZ%72T3Rg9-aMZbFwJuE8ujJc-(eo;}ZNn$SA zf$C+wiWiL~ecJ*OEh^lih~|re1+rkhsJ1o}84UKVSzH!Xl|e&`)WscoAB!<&zwB_2 z9S9cz$7Khb{d+J_bTI^ULT8d`ZU{JGYmP>eHG)0?q6LFBN7CD94Z+lE(q+jQTItMb zdh-AssUZ`Fj3tCRN2-eo7_AuajKL^Ps5)sy8N@)ngItfG1eG69Vl?>{ULhRxn8A`D zqxz%9Y{@Wi#W)uXmJlOW>J0;eUQ2N(sfQNL)UW&GVKNB>PUvRuJ4&4?Kx&hK#jLCPxBn=tr=!RaCb3+~tF;d0`wOVm#F-h^nf_(|MY9S*JUJN->@?=)c-XJOv z{dJ%00Q4T2tVI1o!5BDZwgk8?WLOeROreQ(03)1G?N0^-18G*!q{LK_pMNAw5Olis n(If;^yzvp_OeV`Kv;5#ayNvjTTzEa`hjjb{vD~+{TNnTUu7(_) diff --git a/zh/static/qpy-wechat.png b/zh/static/qpy-wechat.png new file mode 100644 index 0000000000000000000000000000000000000000..f69d2f6f90a3076d7a71f62de0d9cba21b83d08f GIT binary patch literal 73276 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 O0000d+w4G#|tz@n;t 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 WCn3Q1s8_$%q>ue*`ienhfB)I-P~0m3 literal 60313 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⪻_(pmT!vW6UOqU?yTpw zO3r0>NZ;Q#Q|hExDDCT=wT?5tjeq-h^A_n7dsqoC_cxsjcWxD5VShJn)_MEEed;E+ z5XN`IhXGv7ZK)sdy+Wdp#tFRW8F`D*{~FT9qg7t=wJczP&_+)?R-9OCuuJ4LgY75! z47Aa|C2tpP)a z^y24#3~sp`H4(_2Z(OJ!$DpxIsHmxk5;*oLfAL3)qf6Nk!s&bj_9 zT3_?j_@Vr+KwPM3zQWsM-l@LkH@Y6WGfqU~M|W8OZ#1fBRMZGp#n@e4Rldn|bfM)H zS5c`f_ZvYsRV6ynj$sloo!UmYf!V11go!cgy;ic%y0s{f?~L?`6r8 zg&Ns+{mNdYvA_(BYDh%K_Vlt9tDN53rgJXPvae%z?|z?0p=av~WXUau5D^wAm*T62 z3}7n@191vGpS~OVbo>114(^^}tDhbg6#~t53+VUGLCbpuN%t!!7T7yUeA)T4Til@O zALNPmz)M>cTD+^UZ?>{X;xbR1ESD74#RgRjsxFXJfd8LF{|V=Ya*?5SlYd!qM;Rav zYE{=Z$ANPBM&CsxA^4xV??o|#mp6(XFhJv{pf&~IBe{CA1Tqhoyyv8*eVE5fndIiA zOU_|^Fa5ZEb>{gChAn-VItdv~dMwHYk^oR^6zCM7MT&n?L!VdgAEg=0T?GV`!&Dbv ztRh0Nai!s<`VN}lzT96<(Irc+i1sORkRL>Z5A=BZfNDw{=5sZ6CdF;+T$7&h;?@0Q zv~RinRV|WzQtU8Wu0Pc=>fPXteHrE#P@S)>ntyYvehcHN;CB3US|-w&IAC%V3%8!+dklER35y{WIq7e-4Ys%RC0t)B7{_Aal|Szj>B^ql4hr%S=KfeU=? zXTso5x)1&XnLav2&^Dlb07{S7d=Sx{AAy!Q*{LR!AKBm`)RpsltN1|X!G71}eGEFU zfbTyThxP{iQQk))!UU5KrR3=Q^?nLJj)RzX=j`}iD;r#kNK$-B~cigw2KH98I{3zE`o#3*#We0>S7Xhk2@cHZd2{ z(zgl~4?tA_q4=1nuy-J(3O&6^YBZ_NX!uA?cZ~XRr{4LQA-~Lw2Atzz0@WKm^%r^3 zE5JKnygk=^LQ(vtlhcCmxarM<15Ns&i0R{Bk4`~@0CuF}AA>LWgnI`N>wEh-2uM;n z6G^j^s`phWyDTOcd}eq1!pS=egA4i97B`$4Q-YIx`<1oE2XKclcNrw}kNKC4*ws{{ z%ck*4)U-ZKxvWp9YJ01m!pGnV+AQs(jyxVLgy_Vi6&AYZ*as{Nl=8l zSO5Lfa|;<4%HH1}%sf=rzi04>;b{V;Zbh^Un$*DnSo{%lXL`~6zPnTgf4jb6ws# zXtx4yI{BQkubBV#+I~3@?d;I!e3iUNWW=F%4e*NRmtb<3!0+!ptNej}gc}27=Vm|X zsqxMXc0fAiOGn6-SEl`ABA6#V(Zox-!O~`dWP||g`CZ88F-PjCT}8?2UC*1a^eSv^ zTgt-fAtU5RsmuVN(1Dqa!-c8O2*^H4l|j$1Q12a!0p+Fcqim4Vgnn>}VUzai9a!gx zPDgW>h$smNsDEkDB#fqRkOaZdI&h{11=6gc5 z$icJSSQzkPtLF%~n(p{kO`o}+dzIAp9DasY3pz(NBLf@n1=H^AY;^%#jX=skeU`?< z^HL@M80>m{cQdZa=B=*OAQL+HU{F-Gx4)9d5!O*_o z#O$MJ(=%TS5yNdacJ1i81XCbzS2QtSmrNm)8WU17aN>kEEFs1FXI7drYIZlKIX&Qz zskWNgFXNHPO!e2Zt`=gTsDZBC!3HMkdHlc11iH;q8rp+bPX#aMirgd` z^hKDOPN}x0vW6xZ2bCBJO<}I-J+HxiIc7P_09s07Lu3p@$BVH1e|hAbE6=2te+4%t z-DEVvr@2wL;qSZZM7F*>`oJ*gv{2+!(R@Abfa5bBUARw{7@%?*k!*?BowN!>*F*4f z>5_CocLC$Gr9jM1VOzEl-?uLH*|`J!7AH!?aXgwQkN0O4nBAV*t4Bcqnq`79kQy>d z<&o`%OOOGJ(%BK>^_pdl1PEJN8>(@lcrqL2bw_-BGpBX^rT*LawS4T;vSIo+wVSVN z%#45k(O$_OF4}7Vr(A2^Jh5_<%NPY^(w@^hp@avfWJ&ip^l~m;gH{Ou)N&E-spV<7 zARwFzw~fadPX&d>#b9;ra7mi9M7yXq3*NOU!VHDbPiZG0HA&8AA=u9bjLL^ z4!EwJcH+|`DC_>U=IJ)2GB2$*PUu{J2dvSU_p9D;t5aun<8;=+^}#r~J1tgij*4~i zu9${}Op0iK7r(f9Lkm&^`Fots0`L=Oi)aOKCfI3m00sVEStj40>%IJsA!%3cb4zW? z-ZrE;Wy4A)a6T8vAw-??o$V{^bbQ@>;}ut6Y|H38l+Nr)0f1JQCSo~@E-(oYlAt38 zS~>h$s^kMBCpVIylL9`Na|CFVr`+~d?a1`~k#f)t9|ui}t5hV|#jE6O8Fdb;A-`-P zZhm<3+^dRISiE_I`LB1G{56+)-QEh$tnF8hk@;HgI<`w-e)Muax*pMGIxC9H-tAeD zjSwPp;8z@y&&l}}H&1-w%c@#_F~BhxYcE{Q>8Hx zv9jM=C3~MdTIq#y=EA_lDi-EBKtJ$yYwABxUdY`@Y-_>&6zt#IcG<|d57a%++rhICN*l|LZq zvzUfh(nbz_7qK`Ix`p;4L_YYa3fjZr~8cC zgwVtXDNaUCi3XTnfq>%L`y!ieflY50G-XPd)~+^36s~`g5bkcChQPA1SGkpj!|p zN0leSx32#RbdcB3J0Iu66E`bxx>UBNL|)Ub`;}8mzW4Fd3_9Bod4QropM=(JbdScj z?0p~x^oS@-iAO`ejXlY|*Xksu*Kp|TIHZeP7*TuFO9bsPvh~C&%h&&5Uc)4qC~O?c zvKJOPLk)}VogIcl*kRwrG6k%?)McM)ve~fB9*X&-NxG>ZQ~Y|4K`` z^pI1(OR)WurgV>W#-qsLuz_7*pq}leC4dy^-}Td+B7lu9;qO{A2KVb~UDU4M zaZJQzJAIRK&?Lc_2JL9@oGXXL%(N?;il0e zJ)gJ+9R*Jc6R5se3G-I%ribumt3Re_X10iF(lGuX!#yZjjmxNZ>c4kuE1*!+y1Pg9 z#Lq}Lu1HJFSFqBUk-sR4WC`#N)OA@NjGJta{i0F@w$bWk*s9A`*XKrE>DZ|aGyl4? ziEW2_0#mLbb`}g|F%3DlrFH9AuYi?+<=w7=^hVj1_DSpIbe{lwDMfLCKGebW(vOS0 zx_JP*Tlz%v6sphp0_vS+qRdpcXpRWg~|W9JW${y7&zn;?EcgrhmelCm*o%DYE6A>+Tccy zLu8VhuZU>5b$Cw06=44rzy72JntT-6utPt6%6;4 zakt4U9aRr~)`(K}313*M_I_RdCPkggTt_%PI@sU3P+HP;Xrw58iQ3+vyG=@@6~T33 zQnXKPrwFY$)GKkKVjR`vcS}iixu%njYWKZaj}?#UXV0F}R-~>Phog42DKgZ{v@jXia@X7qCRK` z0&JH^MYko|@v}uyryX{!<2?-pcFFad*Y0dFh*D@Xj=%+BkU4)$pG3~x z`PHV)^hAqsfy3=|dY)HzVKgbxSfz2ublS3n|HtK6Q9e1HDH+Aguf9K|HTsH!8`F=f z_vi0s08x3l05w_NUK!eB-BQ!RC!&@h)u5MZ{^6FLvnJnTc5ot+$Jq+ggM+=UVgVs$wDK5a|; z0}+#oZ+vEl8#xz0H8nAH8aH*!yPy5^^lXZMPW(iVdA9t$&+0+rR!b)#;U6se*Fqnp z7r!ZH)eUnJubfXRnQ+3O(DFWu+Y8%3aXlwI8i#Q6l&fyL^m6&Kplvf^XPc5(@g@&Q zTMb#dW)z+LiDzJ_FWeT8^y^at$Q$^741&L*d~Hli9QA~?joCk&^8gBYm^%DH9sZZw z-Aj!6ItdIp&IbCgQTOm^wHeO=BvTjR~cUu#`%@55D|W374v9{)Bts(qmJK!GpXf32gnn8g9<@+X7z znz)ff=cDowC3`vIAY!2zj+kdfO||0}HPtPuZ$uB-z!9@&DYn`aWvV4{zi%{JKs^;M z;{o9O?VPxRjm^|{h!S^YyuVD*`yjI!84lGQXEvf@${P3BDQOFUh4+(rnfw~g@g zD*B2!%1X?>*MQ)mX5ZaXf?2Ctppr%KMkx(;wAENdgddGj6&9rlhF4;jeC1q|c2_~*F5qD!X zf?qL@1pB%yzEM3aP3n-Q0-I4(@|NgD^b;(blNX(PLPs>rM|G(z|87OY$61T`H`33m z$1dKBd=Zy$=&yL`N6}W3Nyu7U%U|ZLEX%^}buPXVibR9VPm z`&spfEqjNM1+8s?|BQ2LOS8R2@7Ah&w0QB!0rlW!GVSE=S8(m<&NkmpGr<}B`qy?g z4tFS7K26hMg9on|%xPzz+qRXaDTRpMk?C+^8kyEYYc*6F%DeMOBR^jHu`$yJ{I18TLZES)IrbGb78 z!uQN;q|UoMK?Da3s$zloKtIrBrvc(^xZt+ddUbhauL8Q!X7QoL6Vohk-FG?#g==wZ zbGS=BCfp^#X^n6#m`&>h%%B1q3ZJuA6;`7EkQd`L@+xS${%GagyYhEZUA}-q|BYRE zM)7+al)Rxm(!WCgrm2I|VsMCqPe4CXN7vKr=eE6mQM%`W$~!T0@XM^dEs9qr2D7m} ziR{KQ!miLhD$qH|0^Q!jiVwzocdMR>e_YKERBBfG!2VQjHLW#k5ZNipN>!bFLUtiw z#0Y}+F}qYtxzRIT0)@I|oc5Pw>+T7^+Z~a(5cfk&<9d5H5Mdin<^qJ-c(NbmwgWaa zYlLD>Sk-E;PCr)&;TJt7!V^reO^uvGMpI>1?(2Xn<cnB#jbw;*yesnQyDUTG9931s! z75mWeFQrV*N;XLu39BKq2lIM<+WEskZlgNbRsOCKQ7zNo9sVt}&@9y)Jzw^-QZmKf z4JwavQ^nr=SePUf$dCN0V@NRS1j&(Q6+4X~OE!en6E9C=?iaO2q^D*HXJ75HGKi`L zETMV9-utuafJmpE0PgS5CLSeI?*^5UdwO{T3Tg)Y)*ZfIZ~kZ&b|9l%pz>KfI>wQ8 zdOV*8n4fQ9m&uPy9bs3s+!|o?bA&+1&!ZQr-#mA#e0)~L&O5%j?B;BD_B&WjDZfQy zfnA{JH{Rn;CO%_!(Qsre*uewq1O2f1tN*c-)klFpE=GD0mMy+E5c$g7-3o_=6H9zZ z7xo;CkrqQm5Jqu-EP9IV$PUh-S)LG2bz?u36#IGc^qu6pMeSxi-3oq4DQQoGOTl#e8M_OZIKBXaYvK=o za^do+L9#tgF8mo#6|ZDMLik9rH|eiR|1m^b06|i5iD{BYrfWu&F{3$LQ!ixy zW02E%d;AL4nQ-RNx%DMbUdCl@WjS9Xn-^{pM!Et#{UZuT5Zk$LUo1rnO}zt%)H6i> zG{RlWR)N8Vo*pf1R`$5h*)-P|?_*bA6&)MDsTtHQd+y<_wwjPHleF1$Tp;(Q-BCip zddb2(f$q{5`F*e=_?|pfZh+zb>y2NR?1^XzJLTFsG1+n(8w=~q%vUl$ZnGAhF1mQ@ z%0%Mo6L_5^m`3FAqqQ{AZ!u zIk*}4ri;5T_Y@GBD@$jhQQ+`iEWt802Ec!C$xVnMA-Vqz($UcyBs4K^H9lNFHP+vF z@O_FjFXAb}eC?FeQ@feiV@>KuVAMM!x;)@I0RC60RE5TV`yE_x5ia13QVa{jwNhdm z(&yHnpB=Y1t+g`MIPHc?2g}%VeCSY9fSyQ_)q&#oHoZ4reJltW1J@=%6X47q{vO*t zg zu*Z1B%m5%EdQ%L#@;@`+_USjs-GsvHP|fMJ~Wbk z6}W-_C`kz*y9Hc3(5o0-K)A2SLXM^MBQ9OSH%~Tf`&ekm7l#_REC7$=tm9Alw;61e zS7P5DnBDvimeB#`{W{5!k;a$Xc`Ve|~!gMaN zw`DJT1x%JiBv$oT;Y3+HNlQ|ML#NF5GjUCqMtx#Ml~uM-<^{`{MV&0)I7Sg~L<#1I zS$9%2aAQrdJ7geP;v9$^0`66e(_)2;M#1E9WmV&rsYY5hU*uN`1~c&%NAhP6hOfQ7 zopv$yQUymmdO00Iuy_fSe%RepcyNk9T(mo}4Rqxf-(5AEqck9W+96US8*)MKfflDB{hc7&ZLH&bp?1)7PHU5eZtIWRt4>Q0%TsF7!- z!gZ9q&&IL;aqysAn7xp~ZsC>n4lCeG4D=x^!4xbEyHCvCJtEAC)lW45!tQ8&f_n6R zTNxV1Jzn*KadtQJeZz2HA@jpkRED2a>^1K1fQp0PS&3GJ_5jBhFjA!f2klXROLfh% z-x(f1j^DPX%(deW{dJfgv2YF^=!x~WuEJz5%KibJGy<9jaI)I+L2?Xes z#(pM@w3j$;O<$_JW*q1vu%xb30h&@8s!wY$3FqCAew^p|WBxcix99TZsf3qdN8k#; zFa(Gdq6g4*2D`~X@BnJ3fcRw88u|u$QC>xnpA2~^6=YdzU%b{H)0^h#Dqb6Kvr^<< z%z=GL@~sqOEI?bq5X)6yRO(I;#Y=K$k)jbA{Sc!g8?pRR-KsfdU*G6>ZpEy5LViv9 z=KWl7i0}Jzc4tN#o}Yy5&I66a$wip&1lj|c06O0>-64TYL{e|%OUCsGG>i}H*zW6Q z{iOfZj-?R-cNE94M zntQ5d>-HnmWn9NqZumwE_Hx|!gllw#&`^fQ==?_dFcnVTnlOt zJDNDeY{80NYO<&uVLD!wW+S>&#k+NIHsv3KO>27tjr#Cx(v^>AzrIlSwHc8`11f4@ z1_2vtv>)0FEieRxNxcK2trUf}Ukt1!R=M}I6we#*-af!{XxbHiXMFnDR%b-+^L4z zeKhoDO z-jHC6NiF`6?7;{XjPzVe+f^r-U$Q*?9$E8qQ~OFu^BG*!OWvQeR`qj~^K2i)yt!Nr z^#;aVA0fVCuN6&@Byvt`s5fQ6^?bPrHdYx*u&^Qm&SkHT1Z!9Xi60IkD}QlE4m|f*M<-a`n_t+2)KK;oljO}r7kIkuVFM4$1k)f z(%f+}yC~&q$Ym-_Pt9Cw`OyaIL$HSRc)-?EK+W(sFV_~SHxY@7qlh>GrAfWwjc}_$ z-UI5!jwk~G1{sW<{%+|sv+%NB^k|Y^{LTI!yeAoC+7jR{w`25yx|k;{8paM<&qXE= zC$2Xq*4XG)ukEGlv+vE4N9m9~l*b=V`foJtcw8>d{p|AM+Qw(L7ps+kTN^T{n7zai zBu{7tgrRDQj-U41J~#=^9Nw(^p0zqBIm0o}S#^ziESbMg#COp`?t^pEd(NxGkA&OM z2&^nxK6o=+8TSUGi-_rP#JCO0?U}Nd_3bN#ZB0LGi`_tO4KN3L8S9MZUXD02{!PbF zyY^17S&YcXOP~jueY3m_GMmj#BT+Z^>p(DLB zW%DfRdg1+`r%vd?8V&4y)M`Xlydu`TXO)5!N0e1gju3P|H&RXra=d5i6;!$OBgT$j zWhFE7=z2@Rx%C5)`cLofGKu`suPZvKBRwxVmF*zw!Mu)>Qwa|v<^U;ncQIRL4Y!RI zd$Y(}R>@O~FO-@qeyq!>G`A$azC)kxYsOajZf&{GGxYjHQcy`kdu~87l42u+o6jO=X?Ry5hq}Q0^yY7QcTG*hu z;yv)o|Mqqu%n>BA&g}xSInweQFSFW^9i0AlC}|`6`vVkNtE}JC9jviuU<_PDk-HxrpnpMZ9z#iRHL}V$)L4Lu3a+ce`ssQFJ zW^DL-A+NBcz6k0*WThz@`jz6wCIAcvv%1iyikn>!DxCr&nZL~8^S zi!i$H&Xni$s!;y^qN$`eW6cpS*KX_Jpgw~WQj~iI!L?i#o*D_I-bBFnWxjc66os92 zN3F7`9Lh)UvB)6+C8S$*u#i0R4M-NcyrCd)<5zv_Ku-}-tzORgR zZ^177fKJM4e28~g(%-IEmkPZp7dm_ZuD^^BAu|@?MS}Yw+<5)&wQDYz!QvXcudOc> z7_3qA6b}>d zOn;SN*6!1)zTbq9ftw#E>ljZrdFg+fy^*p*L&c+Np?2rs$Bk%Pn)S77rC3MNZ1-DH zvZBh@Z@8ph^``c{zn&I3qP0YxvqsV>4t!`!&>;=Ui!=db$@W@%{6EDrT!H<{v*#AgMFUqxs zYg;Z$3SYL9Ck$RN`D(a^B0qZG4O8~gLW*V|oM=E#6)W~o{tG+-5r^9&o0^)VWhw)t zU)kU|^RrDh|Nv7eB%My)U8-6DEq4=Jpuv;id>+V8G zHrg5hgLA|X{D_(uKur0ki+<$Mq? z!piW0WRB&>4$@WClhvQuvMf!-g}!GRoD55`7hNs#x3*K0xZ`8kB-xDassxc*oDrOc zgzr2o=>-Lztq;wgw8(W>WK0vjA(4vCyK4*CxM56rFFa~KZx^kP&12#nt~`hu?|W?E zE5e-F7=skf5x&8f8!6dHJ?M2NyaDN7ixzA+ek((k!T+@n=QK&T5iUHF9@R*9P_gMb z`Owbsg2FFU@xqYsB;se+b#Po48)g@f${p?Px-<0|OSiI*sYt*{x}BKay&)aUF?hS! zgzo((itpvbmvLlTPOKMDUScKl{)LruOaCp#?!89PufN6p+N2w68P87OE#2V)aT;p=TeJu%8N~u4}d%@ef19-ylmO zmN_=Rgun$zsUWX4iV%4KOAw=Tl@6UJx2QXrmmM7R_FpLgCfssWYp{8%Ey^8(h+7*&zbjEJg2c$7DYP zb!dA1aXP?R1A8z-Wr(>h0<#)jw(>h$ZsL=+MwdgS#EF<)75AUwS@2 zun3wh@fw`S4N64fI^poq*6Fu3xf@?Q!0iG?y;Ha}`<}JTc1_jvOn8`dtzgq`4=B}1 z9q;2+95L)9)PfOc47w5+8q6Wx@w+3J)59hH)btSbi8TSO0Z9h22<@c?hg$v%<)nbdN;<;HjSUF#E0&zR)#JEeypSrx4y z0$0Q@Fm;3gk^UDNAa)nM zp2L~&2RhT67;=oqhP0$9&#PQt7rK{O_O9AIdf-6OMOTV-%-9%InedD}p2yTfGD5jU z1Ad2bTAbOsEpy3Z{jXC$FtjVoed^E(pP_y=ASNMlGwn|2rS%$mUjgRoWw6k8{chMv zjkR?b+_7U^Vx|u7uFovS9i}+yIw851=GoRM0Jkj9JyRyKHQ3BHnl27N6ihjL)gX;2BIt`JT661zH-TklwZ-?FtGiF_=9;T zGFW^N6mmDC2c8bSf}tA>1b}MIW!Q5REKZ>)Zhn=OC!(xM;qIWxf&GIJ0Z7wb<}7_Z z0UKUtaDGz#&$4)%;oc<2(h}Y#b;;9}6?M_ZcDt&B$+bI$qAJ6KNxr4Uyj@}c{l&ee z3^|X`St1L7J=*|E|CND;{X&uGffi|05lit*&EybYj?o)d20s0}sqeR`g%Nf@jSfZ= zLfvn)PU29u>2Xy0!HoDGNeQbd>X)S@N?^c;hMRCEC`arR6JsAL*}o=hP+N*SEHroI zn{+{|NI{_&v6iU#k3wiJoym(1Ok!&~chHR8?z=s~L+S6!8_=JLxh|m9 zP^R(2u=G$k5b!H7sOyq)q3V^3@MFdP4D*kO_(Ie$MG@|?MCv`s{lQVbzjMuVLs(Ek zhgZs&e3Bleg@50ZjHswr#siJpGU!HhcxL(>de^H>DSpF8$&t6;$`6cuROZC{ZqDNA z>nJWBVic(c<|3_*GAUSN*W#jiKDm*}bM#Z4qb{I(NI{12EE&vyO4BD!t3rwo2uyn3 zdd%i-B_M+tEI}DN-Ie}Q?jv3Oqwi+Ar9{B($%~_Fn~z{jn|pJ`PY4|IjWMJ}{o4G% zTMa89$r6mt(BA?Oy9Rv`m+Q4I;VIFUX{gCPT8P!=R{hMwT8gxh{IDoCUq9YAp9HVR z_iW+dPw>oNRy_00<0Ax|ehx}o_aX-hj_z=mH_(Wfg+KYV@R|cI_^plL!tA7{lFM;V zv%u}|jImcSX)Lo>!PTD9nDD+K6+j`B{4V3JsD1wgXcv778TU6#DoF6-3)FvPQC0Zv zXW)FE)xFT->`sBrCdoI+DYG}YxCZ2@RV(EO6cX-Hpsj@5;#&s$nV0=M=~+)L!}TA> z8BHCXdA+fdR1fv#lU)_3<$Nl4PwYyHzJj4g06LswCz?abP~*Jpn&~F^Gpt37$V!LH z0dnZqc%AM-CDJEfsJdoRzq#C=Wbx`ms07yy`&iD)UiN-P!b#p9m%NiUuaaLI5n{9; z!{1nzQk34v8BW}z7Sp7BWaqh;;Qv8$QIa{-EA_Q!f9^ku1M4M0S^&!jbjKfqQzEFE z@%b3YdQl=#AGI`dDjg&lX5h2lYEq2i%vc(hU>^DL?#E{43%>c`E*VT}0$C7W^%x_Y z+E}$h=P>1ZBHM_5xN2lHYU}^LzE7g6SU6L}C#X-{^~PMpFT?L&EGkCC4Qs~Tzy3AP z{$hMnWta`!jkOYZQ26pqEPVhKwI+4hy(7nXRju+G(1N)E+Sov5GFc?u@23I3ytdSl zZM|XnW|Em7HT#2=BVqZwBBx6yU*P<@GI9&$R~BYUubBRn^T^pLy;4Z6&{5cAcq1VE zTK7uy-a{%qVse!P-w5<{1=u#pz4W*&()_SI*5DP~Rp zD&SEnbzr=*{YI_&zLq9+3so>x8yqj%LS$V+nWE#@0gb@jjaLoTi_IBT$x5pXO71A* zt_Oh}&wp&CgDLzd1WM;6f#Qol;9wopB>`J78Y=qx`0TGRa7+VWmy>Va`A1Ql1t#5y z>H@J-YB)IG3Ub~GNtN#1{N8dYZqVF3t}ee}$;69C4#+qKV9#>4+_$lF&DEu`f=Jw_ zD79!p8{!LK@eDY7)OcH;%Uz}Qdli{h=;t*N^Ex0e`g7B(HS(p4 zah(AuC})SwPg0~@(Bl^Gsnh(c&Q_RtIX;b`5fX^A1g=wVh$M!~p{MEmtlx4}u7rkh5N>?^n8yN2(q zt~zj1)6;05B*|YXoV_3sUcN8F*f3H14|icg{!t9a!6zYjsb+Yw``T5av{L8hM{svq zbJGp`P9g5ytmo3Ax45+ZeS0h-Fs|>GKRI{a?g`_2U}lA|w})vm)pnzPKl9_$zW>3j zoVMBUWKj}*OlUrvJQrL#Fv5_F36!2Vp5xdv>4^TNJ^RKgs-SkChHmQ}gEGiUf&7O2 z`*Icbli1S5YyFl*{7gMp%tMOhi0(_sma}Ktk*So-u8Yr< z?C=4q>k8&7xDkxL1!RJ|fXUO}KWgJ8&pb!@aOY2S%B$t=)!BmDd0U)4n5*3w0}OsB znfAG11ks)AOp8@c_~8xSB3Ap5`9V_0neM4wbw+dsboFFb*E7FmAQ0Wj zOQxYA$hsHu1M-+?nWissJ$a>VO}QQ$K(H+(&nzl*#rHSsQH;uj;^4x*9f-(oe-GQz zEt>)$Vumz<@I7l|#hMPnBhLlvy%CfVY(z`^ z^ajnDp@z2Nmb{&Is8n#;aHva{Lu~{!x3T)AD;T*TW5OpnRu>8C3#Mri+(9HT}i5`4pn=ZzGRG$2x8*Z!NNC! z6JYB(L@1$&1_C+*x6?}Br`ak}q0MWO^3)i(rVVLqC{xX)c!^!844m7NiU zGj@4m>)r(4H7?)W;tP7IK5vP@o4d81M1NA6mJrm2R1TyDOMR=F?URjg#-$uzg^-S8 znZ3H(D<_ZAPF&1_2Zy$}gsS$@t3e*84{`RAdgtI*r19CTnF3dP-nY0Wb`zVmG(|&W zmBx7kq9N$@L1${dVvSfIVA6gZ_gDWd%x!|oOG~W@`=!}<=YoHAek4jI6Y&dOy8f9$ zneu9s(TlE9(npvVgd6IMKixz`{{Xjsp^D-K z4Z$E{B5(fC4HMi0fCPrHef_fjmH03AzaidFJ9D=U(9e^L{c)4szUDGUY@^H#t%ScI zMpz#Ls)MD*b>kN|Ype$V`C=l^XADw+oNJ>=^|RO)6gMs@f0C zi~1n*5?P|fr8R=Opv$x5F1?>I7fi>e?bQ5L%4AyR&v^AG0AHTg5g*rMxBITv`MYKG z<7p?|mWHvjI)Q*vmJ}`;8aLB4CY9mZ{R3Pe)(!n^bDH1;mB(jSx|7+k6K|8dic0I3 z2Ytr2E0e{LEt1zIYz!m0!u#Tm!CX)yytNpBOb4x-_R7Yuah+Y9>CVc?I1@xT19YG* zb{|_)RBcxIzs9^3>|kL?F`&52q$F)@R>`d$FajMh%|ebSO}8I+&IkA(HAzVaNr;o@6T2#6c!|3RpQ8&0aK?I3+IwjL;V$}yYoG9o1XqrB*4?R+}A4;n(m#5QnO;T*T zEwWB=%iG&mQyqbq#I>MEthn&WBMse6WBYC_zegrSA>>P*{xc81hj*evcs(oR=$n;q zYyuAidK1inXYUe$zOwC-4k=*!RrBZ@oqYy>)KT3%}_bn_hpEAC-9zb9$_*r`azIW=| z^pK36y!nLEXme4Tmn~_+O+q^}JC5%ksXnchd+ejP%MDZ}qLJlM8ur-T^@$h-aAKiI zD`K|e7G-By$6U4{!`eqk#oIzFW$&+Ju>t&!4J_LYErRa90f$DW`BgQWDK!0VE4%e=Imz7r_SA1(}~6exaDlq{0J%K z`$k#LGcO(L7^@F((J~qti2r_byD0`?5i$H}WIbi4%a+tq-PnG-C_glpH=Y?>gVah@ z$?NUTZ2fK`mzHVB>yLixj0UUigE5wCixBMvpaztw;nyKR zesH?gGTCT!%w!MiRo@7ZY7%w(ZY8wUz=G}f+m%AxxG?xTe^G{aNyY0m0{oAOWH>ni z$i8d^k;&F%?u-ppCo<<8=ui5?e-xq<3|k@24}bil$mRtys?0M!O`Qc4Df4*bb93`( zi_Ykndl-+!?N#E}C3`RFw%7a=OCP&Fpk^$CmKhDIXp)lV+r^4Eh6Vp~oX##&7fEiq z?(IL99Re@aGI;OCmJTgRDaq4)>i&v4LAs(1Xd{0Er2@!179vw(H(>^hcd~8@X^6&o z*mN*bf0=q*nExSxU>R>mhD2~fjj*s@Q?4cad{6de-W=@|gJq7`5S#6iH0^EE=c?vE zj+hRz-yk56H>;x48D!S5N~ml^$$8p}-jx0B7qgd?eqmI|g?&oLqtvYl){Z+r_jWQH zH0qPS{`$I{7q#<21CjD46_6cMOcnH!e%H9<76jf% zf5GdVtp6(b#-*7&Ea-Z~60AWlxm*#Kv7s<8GRVR&r~EOulkTYy$@UHV#YZf7lW72g zoF8l^vt!Pp_1(M&y?pM9kd`F^7{<01kdYRA?a!{eh~fryIqOax1W^%gInOt(LBq}z_k=(BRkh9cIuV4 zZ&N;9_ZpExry~`j1XvVl5xQLL2dgSr&Nv^ax-+J{TN&&-r7#-T*)?McZJG@d1xt-r z%^zaQk81i@TO%SOthAn2P>2dG*TQ?1_iM zaIgz~&?nYBip{-y6Wfo2>jDDvXhh7l#}vP-d~)~y!B*nWH%-Uqe^2a{_?=eI>oL7Q zQJlhotZ%3TA~Ff1gvYQRS%lm1;y(&9!{#r5q%!d?zGi{=3>(zQX*Ef=7z4B~ZhVI{ zEEzcqb6G6yjq{f#v)un}J3LAYL@JMf@>~hN3>Aw%_X-bRe^Rw5$YSpi9khis$c&if z6TXoZ0?=TB>p3h)C_8c%V!h=bMWbl~(7;j~j3Y<^LAn%Fu>xv?(FY2BOv5$%oC3U& zJd`s{iJ^y5(=5ZxG+vjN^?EGxf4+Z16aQv&;Gy*sdx1i#yW1a%ivI%n24w|43`4gu z-w#`mMM2QI(m%DXV#VTpUv@r5It;stE9bfR+lwJ@N{SfWTGHmNm#ee7!JLPm+a+J? z#Mt-1Fn(?^T~rJB7rdaTyzDp^d~&%5U2MJV=Nz9~(@K1Gk+Lo=ZLT6mENrUxt(rmW z2mB!G>8?u=qkon2{=O*p@&77hJY{55@p1v$s>i6KBT*H_sB;@|;9ENexB;E8Z_VZK zh~c$HC?J45xZ^92(Ij4h0ML5^Ib40IyDf4j^*8NDnuhH*)-z!t~tH(gQ zXYiQ$hh@)OWvKw9qy!jcIl6rvvIHJLT!XnJl6ZT`GZ`N#522>X zzPNnFP9cZtL31Zy|7WX!?F+ypbw zD{@-asrao{)0_56x^Si6+}`mn=iNt1^|~_aI#pEQp9s9H=6o+0F9y_~+}6*DEWD@( zEyxeqflFSjV6f~l*m%-6YkN0smP4#?hlHY!PyYIIf#SCGLxuq}yR_Tm(?Qi6F#d=4 ziH#@SK@~CT&4zH@l7Y5E!yc7SDOz?(T59Ie)8F8=CFg-HQ+eUKcMxUD{-W?FAfds- zpf4D;X}SnDj;mq6{F%n}`S)V#29!0-O%;`$>qLnOFG3H-lr<~wBFZ>jZKVyB{dgJqNaGfJB%=<_fu|hy2o6i{BWTe7M96 zNUQc`O`J7(k#79rNu;J&X=6{l?Jw+0B-)Bcdyxw zE*TxmQ%8}MQNRmL`pZKICev&KY4kX$0`>yn=*Q{f>#$l&hS7S{)o|2%VAB4C5Qw!Pn8^-?9SJ5XfQg)3w*eXt#0r?^Oea8G8Ip`NFQXB! zm@s|?Sd~JpY~P>?7$pkjVy|#dP?f?dy~=}N_&`bAA&}NHMPr_)ARw4H@&`@WBLR7Q z*t+SvJm_mkYNHpwFOo)MVWX?X=&kJ?z4dxYiUkpuz-aKueDB0!6`7Waa4!Pc#eyHj z9{2vOX&Pv*D+h!3^O75_tR|6rwIbIlQo=63OQ4au5aU)Ppb3FcM^dF06P{In4(1A` zO6Bo9w;p5PuDU-RYPBKu6mKg$=yEMrWK&ZTD*VLK^P$Yxnj7ppp^$!HC;8tNlML8Gh%&WWKA&ScvC-0OMyJ8hKM4IhKOkw4nH+k%?dLLt5GywX=4W3 z+|OT_Jq8L+AyZM?`h3ipsI_-R0*atiK_;kaHPjMw3s($^wA$H#G}F$8jL5td^_cnX z_Ty~I_;~Z9`Q7LnrdiK#aZT|G~*D|VP{nS;KIxeP{Zia zdJd2|nci4M$dO8#CK!ok^DjG{HVLq@qpa^!Y|4r!LDx+w<2XR+tFV7xiO1kVOl!}mQCEi02Aajf=t zF!J88>ANjtU~7L=ch&7G&wj}SPsBuMY3<748r=Lap!Ip>y4%}w-i=B<@z&FmhbGG4 z4zE0~lB^o0-0h!Ogc;!Px6SwQ%lEM$f16#B`*`2rS@ZRtU6K7Ee-BPtcEl^j{Uea8 z?BbQ~w$xtGW#|h$piE>+2Oy|=?m7WtG9C!8R=O)9ry8OL$QLZ!$`BIjxw3!4@NAWo z{t@os__LH@iJ%S12k6j_G?H%Pk_F&Et`TgiqKep?+Ac$T* zVXkBLk<{+h*^R#nICSg54%fSlfYo}iO+ab>NZKe^YU9L&cCbT}6ylyHPL7T?03}aOJx>gT#y#*71d-x~+c*#my zwtrQ9N>-*U`bo%oTgVL$g<%f!DGz z&R(YUu^v~gzxABhxfTUJ>vjT*&9%uc0&1Q^;P|zxpRuNBPE;`p#?myqZ04~cfBlZ$ z)&m0fmhev}|L;?8pKlvKJl{TTF(#6N=%t<>JexI%fVsAG9+Jmv_m}t3VGrl01K(od z0G;G=$V5*t&rm;@D+Fvg*|=ip?HaCKl6MV0qJFhM;a{xGbmMTd>bMz!r#)RV@l8;(CVZ-wlEbCA2;6Ui-t6h!M1 z*~5(!N5_yR8KLQzfgQINf^_diH>upuAv2M-=U#@0KiCs0Lduuv5{Z}rP^yYp7>f0G z1Phib>-|R$8Q&7+q^Ms}lA-FhQ5rNw`0Oy4nc<;)*32~gME`coIjpwgJ3UNDP>Hj3YRqiiRY z)z-ND8jtM;M5VYX1eJL1%JRtDg4*l4+AJ75K6oK*YAz* zGnnnGhbms{$8EaYHxQLQkuRowd=zvMIj9wmE$W7|5cx@s8k~YXveD=YJf!zEt&Z~s zM{8^L;mH65YNqsa$)T!#DBJ4AX&ZKEvWQBH3m=V}$A=dawMp$z3M6MjhiqlL$6Uqf zVod6}T%3z-zMtF;uIJi|Q(sx&YI40kW;kQH z)qVW^Q2Ng?;R=1z_eqy33HL+#aATxTT5R~;9vDj(E&ua1{rMWuH#Dx+vc5@leG9tB()gzr@TxiR%phSxQ!~Dyv1%Uf@(+s;s{JMyY-fC!D8Od^xMg zL&!A4Xzh>_UlES$K;>j}NDyOe$_{YM#oir4ZL3TH%w~L$rkZOZ&HY=wpBU5n%hK*y z_0r!FLi`NtyH`ZF2RcJ}0St?D#IzBrDE16ULts63iRQ&2MZH5k+28Px{#fJN4Rxsj z4%fGS99_KUC)N>W$*yD`F3fm3Y;O=Kt?NohME5zYS)?lAl8?jCyYSUln`L4#y{E?` z@UT^!;~C-X$hTmlpi}ow#`IiiB5x}^LO%}&0$jHJ2U`huB2PmC2e)v5gKcd7R6ePd za2JO;Prmp^QBG3osPG5|*6t^=B+MF0A7@pJq=6j+KwH|sUQ5LnBg1>L7vTV~mTKZ3 zMY<-K0Kqx$lEv3}Ve1ij9(`a^u6$F6>gIFM!9NOP_-!8FPgD^T|2x%_&KM-aiMCM6 zR`Hb!^PLmo;EAWBqy?}`GypcTsg7#rhrJPCyuOCFCVB14EXOS3Mfy_qJ?wXYu!~me zC=e>t<)!vCanhA4%mXS5vmlK3KZ*L~{o7bvUI@wlXgcB#3^ zZZuHDLDboRFd43Y4t@M+NKo--a;~qv>dt+(-4Ejoq2G0XQ&Jj> ziPc%0KqU%1P4faw4hjSFOxu$36JV=`AUQU!=caZ!VYK%cJp#fk3N!d81wOR)1wNAU zP~CUG>@CSC!5TgH!G%7-Z7gZ_#(ma8{cUrJl&0%rYH`ngs}zQNp5Xt>Q`kjuJqN3GY|Q5z{206v=kP)nV>m#%F0tLl5RLWF}cbK0G#_e&R8QJ5T#LhxVMf)h|&a9+DGBPw}E}(~qi)cX@_Wv^-t8 zGXXc<)LOJ^!)RC@Ww7y;N`bWHCvo_~WGp(Sl8Fb4E0WJ|*!;azv~6WKh2;#>xgpTbgtrWc zcDdDh#zz05SSm1bE+g>QXU6ACE-A*kLpo15eU{HlpRdF)MBWfCd&C_!%YRr>*!bD} zA?fn&pGY9<03ec4_}~92tH2f?MT~JGXpf<;H|Cpsya;-0mQllZE5~0jUjzs%Igiu1 zQNx=e07QAeqZ9ugu*3hO_zFX51Iy#!0lxf{F|>@)zhGXy*W4FJ9B)dg&4gbFB3p>M zzfc{!WNv~vQR9E#-P0%XFQV%HQ7HYtzps!QiZpB;ll}UO4E_lN*Q^0pxNoraqcsL# z35kUP@53jc2)6kWf#nR2Gx$f5@!z51{|*Ha&3&J%jNN>3IeQie%Vl@T&g97&;#%5& zLN5J|UA%m$Kn(?W6MLhk0eAXI;G{sng(DT6nG$bHgYYXbwy?a9g1LA5?*W5yal0@N zd1xO%b^$;%R>!~$fP>NPQ1yQl02TTF%y+MZ%!tLD6oTAHz+yqmYf4rI4`eSw2s&c_ ztt$_uWK%$a|NCgV|FR7}K^!6#TVEiA36DUS;J7${po&QN>P#N|?}rAU^;8Fo-kEE^P7K za+Cb!zf)-gL+v0cnG*AlssLOU13(+&g>MWI)E{>XJow)!)Pc{!IY5rs#e{!yW(OX< zh{MHzcZjKI-Tz$|hP0tWV46&Xoc{(Q2wd#gzeS6L|9kc3u}|9~J~2LG`A4zFKxRAs z=E?Pc7t>ksS42Qz4UA-m<)45Wv;MnoMAgZN31m5$O{s|JTLMfzHBRR#aHRMjMeF}= z$2|6>0!gRi|34r5_35)qKz;hw|Hfzj_oM7KvF8Ol0yy3GWHB;h%VdzF8vi{g&5ZMD z_N!^QJ&We|RCeH8%ogr86U5tN`T+R5`5y(*6OjVBw&)}qTRqdiei2S9Xzs|lC=*9) zhyX2uP>#&qk73TI|0v`~Dhr-ldY&M>CQuIBv=GFrHE3Uf z5N~(t?~&R8rGvq$3rd3YFY0sCe-zLnOoiRlK}Gy28F(3JVULT6h{S&sa#sHF|0s$O zZvnQ`H?lae0gV3@?1#q+2;=<_l!|o1fB@O4F(*UK()T#Dzk>b9yZWABw<|z@`=P?p zlV@c}kK8q!jZk#3@v0f+xVjs6%}tM2Dt8frhk531A&d|H`_Fl+$=A%zA{4c3bnJ#}s zbXpBPvKYF8h1a!SRNa@)=vH`ISep09W#@f#in`gAoVgCkFZ=rwk!+;WCn@1W{(t8a zoEDco&I4>6lk4^T^iPBr=BM}yn|46V-X%0Xm4KOad}`g6RnX1yyR$K0FIokL3I=2K zu61NgAq*N#@glqEk6+1Sc|~ad3fquieGFCp`bW^v8Zs}deljsx%sj=`XY-A8m3XH( z9cN3hZc^jZkznja11~C4^N#+`UGOAq2#g1w{GK&ISdZvS_=0_pT2TU8Lt8K^f)8)^ z_mWqjN4Wu#zE*Le17k_gskH6PaPFJEwRKr?0xmAn$`nXvlD~tC+lCw-6R0BQKuu!F z5RFR!81UTcZ*0+*v9Bx2?}XZZNq=gNRmk4W3VVS(5sr(Y-EpD+VPNK^yoor}Ay`C= zBLt5Dp_5cWys%9>*0FkOz>6d9izm;=u8Q{}5E10dcz1Xxy_07(oDbX{!6#$U@+Xv_ z1`NAzjZ#A#!-@*-Jx)UUwyoZ5z`Q6a3pux~pB8w9n5~v}uAAc4XcB-1KA1LEh`zis z`y|#rwXqtuzQwe_*(=B*o8}uK6p}vLf1U^2spdM=juobDS=)c@}6U=_3C&~2yBulo;ESfW!0PR~HGR2W1er&-%CL|u?|XZ`zuKrey(VCjL5gohvU z*ka0JBCoQiSwvkM)UE;3LRIh?o1^&z&?P+B340a!2<(nXG@OzRqLIEi%zMOwq~W0) z`9}4)Rif`}K?F9$noL(5L{J6hcpu>oLvG?iG31S7+^@T}l<)mS)Gv03g zC4X4&-?51}4fAp*51!17Ye!N|bhh3{#V;NM?e9Ily7Z*#E1yQbJ$tXMdT)LH7orKC z+M$Xy$7Nx&`$5$B_Wmx-sU~|s?h~rBNf*>K-*h!$e3c_?Ax+paWK}6vLulvPrkF^2 zMBr=m+x!IYlYL!1Ur86*#jRhfIcg+Nho|8ZZz-G${~Uc3XJG5TUFOtU&PRSpQ}>lp zy}0y>rnr6A{#6w>z8N>}jika4;qE;5xAKC$)8!vsP5CfosKMxAlT{1y8re{Zd?7}0 zDc$f7``&BL$l^=BipyD=Le!CDEWhbDl}aehXDR>WfV}{88b_Gy{fP3Grq|q;^4Wix z6lS|IKy?rz_mOiWzaCiCReP%69$Kvvp!g4l9J#kLdp%ihj&n;P?*{C@ zDv;~f?&(?IWN}HmhpT;z!n_uW=- zW{TvF&x=ssHG~b9_%7EPJ%^Nl?zZ(xf5X+Lthk(%1BR8uF+R_kmGdAOw(Fc^vEtcGmiE0Tu2sy?1jz{LwO7e-q|=gJ9KiSd1w*!9tSCv5c)g zZKL;W3U9lBGmrQ_=2BNA$sE2M*OdH2TJpW88SYit#4iNX2r1eql$09OfJ@a^u@!91 zUij92&X~e^G*7S2p)dNX0XnzRw??m2rUR?jNuOYqX#&edB`lk#m%EJSUpjjA{%u53 zzmwi-=x9+%7uVx9+}ppV`A$S&mQYZ?iLko}#KG~w&oBX`pWKbvDC7 zxz8w|qrdfw6~sGpPXQ1QPOJ8r(UpQG6$?)ZkK5mef5W}RIR3mAZRyGa-HFr;@F3)z zIbY03gdCWdkB56AL8ZeS_d~9dU$PE~OjGmgd2nU)&e}j*s9sH6olYCp43H4+*(iui zUA~Gf)Vy6!W#XcdR5V_dr8=xB9+<*#XG_r8q&Gnm)|axj(A>>>4yy6F^W2NGFAag? z?}#*+{64NiE!OE%$^X~dB1nJa`NywDvt;K7zKk>#xs0!8r_UqosxPQ7*A71Mej^K= ze&gI-ULkfIVc~LRh+Re$nWnax;CUs*_>q0y^FKt7Kh%N$=E$(o;LC-EXiN4J0Ms^{ za(65|^rG@M#M5k(yFz(0X_9w`{NX6(`6K3n`6B3pG;5>SE9Zre@8KQ?IxaU1u=$7_ zGGBMi!BD^%uv*QEEBZeZg}4TP^!z!3@r*ZCSHFB#*`n}Q_~Sj3SJ*eETk_zJRe%W> zB^3f105`NmcS!+B0?(5U+YL=&)b2Z3q7s=OCTTLQCG6=@wlE^ozy1hoyxUN5<9i(C zbH-X2)g=j&RkhUdE)pKd0VoYfon4ngQu+o!G!a5ZWsV+QY*QVqzBT1G%e`#^u_s+c zzR$Bbth}rWo%x2&<9_;V4^p7=3Jc;|j1~{jtV`uYHBg{}DPGCB2M15yJLnudcYDK+5ExA~n9X=K}8-fdA7$Dt3w7xx78NLe^1ic`$XH*3d)r8;|j;g`}yeqvOL=f zyf|Y%R!uO`8i<o_s$-0Y7L5mvFh0$2i2 z0~4pOBQ?A%qJ;u%3k+@^S;o7RBcq?kcYA-&YiN zHzw5Mosf<%*IM!D_AYTbL->L`kaf@D-D!s6&wj#Mfm+!hkjT-%G1J_DzDd3V2tx-U zE8Z^vn-2j5lyV@W$|lnlT?nQ^hE~3WzMVf5hV>{$aJTkgwOS_#90=lzulpbX^mA#b z{1MVE;Vh`tX7RH!v%P}$n;)wj3hLp0-J6}tx0WkH7JE}3f^4!7z>BgKp_5eTX|Ul@ zX7hNxol-EBt?&H+jhSVxp?RjdAvg7Rl^>b|4pXhO(m+aCI1E60X_eg$G>{H|C9bg` zuQn$=bADX)htDjNcz3nHUg4wUlmS*oSxRmC!)}tzGo+8m$}a^eYj@PmNIE9Btuv2bK57E_Xn-5 z_A+SNc^!5bN6;isfT=Vt5%_HI@}~2|E9=Hm!;DQeLmmN$C60zc=#VvU*OI@yQJ~1k z8=6bI{@p-oXL@xBFL1s=9qS!&dwJOw?-U+vm}uA9kTLQ-+BhA@-j=0GeYfK=r@s(! zxFvwtZT@#|RI>*#E$iCO-deDZDdT%3^;Y3Avh=0UcziUSXzmbLRRzl_UKXiY9AM{xXTY(BbjSrQvmG@ zFUoWnMhFa%?bW(U`rH8utFQ~Xq2?jC;Hj+U`qNO#gSR+u%HU&K?@bpm4_AhyNGCc> zi9s6B0Q(N()6nU<%U<3KzTDk&!gSok?-Mz3kK)~~R>>;jaU&=m!~`|0)Gx&cJ5523 zN=HSM=F>)nDYxE#?Jr<7W&em=$Ww6Up3N3AF;<$Ib2_wKdsPE@kb3G%>d>Mhk7ji# z;o$^eo$rxr9D_Lh`a=rrEffe>dx7XgWDi*7mCZI6`_Orcjip%(U6zy#<&DntDSk&R z#cvX{0MKlX*3D5&HZBHJSh7CBq77l#^g!kfiYlE`z743-5&5O2s(&e6kK2s#nh@eK zz{xj73fhw55Rl_UGAAitA#R%JUkbI#uue1&&aj9If3T9coh)UrI_f8D+#0LIIPmU1 zU!~wJSdT8k8-gsy&67%)`X`X*1_FForEI{6@fA{HkMs47x;iG2VRACmcv!Bzf!hJ? z_vywZ#_-oH*;3BaFs-6UY_1ROSDU}Hl`4VrI|;Amv_?M29<@q4I5u@=RXX5p6H>f@ z6c;ZBAA;e<{!w%@@!;VDf|$pq(Je481&=@NPd+c%kunhtwKZFXMwPj~M>W>xX@Y#jpx@eFPim9S0J!II&%$9M~KKh)b^;N7j)tn&?00YNRodP)sI)M z+cPbKyZ^!>Z(zT~2Uf2vE?kZZyn_6!F8+eD#1_Y*&iq?)14aQAz!zbyj_kp4S^_go zLvOF#{?-(hD#e`EQGsk7x|GAZz;kAbSLxeG-tAfAC65+e|1+BJUW?XXt^L{;Bsai6 z)ebyX>hFHMf1`3WwnrciSiw<4|6fVh8IV*Pwk0Ez%>jy<3viDBCkE1YzVG|VkHdj;p69vm`?~J?x{~$T z=^Up~`U1Xh5NL6EymVZm`ZmV_PN}%@3W4sUG3x@1&4;ak9OIMPZlrvPb@G1%T&;{eUDxco5G?0(4`FarEJ~)+%(ssw&C@#8w8+rz)oHAeh;RUW48Z6y{(Qhq3=UodCH{1VoJ2>HALgB#F z$6cA9zkF!b2I}?jxq8&kOhD8IL%R=$jF(V&y1{V_X^Q)&bA7YF4W4zQ{#t^}U?gpGe@-MFbn_BhHc_Kis zfcqis1?0Otb18(S?pmr`GJwdQ+b2J7^Ls|_wibjNw7W4Gux3?1c^xPwVOy}I;GKFc z29kM!Ra`#zv;npJ9nqNoo%V*hbYwFDzgN_?tP>zMLsj*Y5WP^A{Xz<>=vNX}FtVRP zxbr(K@5bAx%YDR+p$=>BO|%RSv2FW@PfJ99)GRm*rL=$;pg*ZUjRX7T9-&;6-@4y^ zzZs}-{FcE>>s0}IV;aQ;I`7E5Fft~8QG1g<9!V$3mLilc?+2Dt=rJk z1r2a?FinFoF-U}hV(Z|#fS*>1?Y9W4F*84r-GCZ}qCVQYWtDgl0R^D$_sw8>Z^C*6 zC^mc1F2R}jsWdkrG0LEePx_9J*Ht3oO5lo;-bL8K8&tTxaUn%ooa!)6=f)22-y95-^TO zeW!H|1@REBzf3-3{QWh~FxwwF_jXInpK(>Cy3RLXZ8Bl$&PMO-;0s-Pmgap{rE;e7 z($MXiQ+3T)C$n_eeVewhx;p53?ZMbecsGbcUkdIytx*Y{-R^cKCB{V0yLb7NI+-Iv z8@Ut;Jk?Iv@lHf`fJg`_S!mMuQ%MU$bO|B6L9;TC$k&s|MPt3FOV;rRF4e~NEt9X< zbdywnvt6-k>Xm@|+DRmC0;=NwY zxwLjoAq69Qx2HKBeRfj}LsC^})fiX7aa^KtW zo%IcQmSKK+$h&s)9%9y4=Gys;#n`uNZ7M2-4ditgkg4hx^xHziSH4zZYYv+YG-&Mz zeGh2s;efFcSm_r}8JbjiJoXQ%53o?tOc9^@RD~0%>+z|{)mEIm`az`R!l3Nje^0Up zuB4tYQ{?fEXizlcivC4v7rw)`yS1W!JtEVwA>7mgvE)XCmQ_lszU{g~flLj+SoJ<}XrCufay z80@?4M6J`MIR@r#d;X$_%)CnL-LOgoCz8{PHs!!G+jNwG!iH2|@5hsnN=kHXsX*UG z@&+zw)I+M`G9N)bK3_BB*)to}AtRoTYp4p6IHKzz5YJJ-vh4DC1)lMrsITVvkp_#! z7+PM3UhyZr@WRY(?*QD4khx1;^1e+|vRx+x$F)Wc)%g z6!1HU1fVpwO0J<2ZZL&HIvu0J-Jqr~=rQ z;CjLTwi00;gqo;wn1_vt!)mogxRZj{Ma|v17uj|@IxgJ$kdKKgB8+PAQ^*{O&_ox! zb;LnE!3WH(`GFrckYjQnJ`y)D)oHk$Ovp`Axl&wt`Dv4`|{zx`bBB`B8)(1Z3zu!qUE7YfcO;`}arjoC(6QY-SvLxa;`nB*1fs+fbR~B#aJ~y;v+| z+s)ILW0%aMp4(DX=U~XWzHL7K{8N({#<+uLfEjtD90kM*xHVF*^Uuz53ifhaQb__y^ox(6AScuAZazLY|7Virh#U@c&EVi!)F~H;KhknLQfQeLR%!BGDKzlch0H7W?(_+}h zP>07LAf@+&0a9j0oM6UT)QKrchQU@%tYN5Ocut!En7zLu{g}=lOpxv$2GcO9IK5U%*;8=r#2F&ekO}juE zd{yG@%3%kNrUDYG)hl@*BV;WCxH|_;r+2_K+@hZ+K&zHvgE|ji!jG}}>R-bu)o%>_ zII`H(XM~!HX3fI3jO4@v(V@n8rNYG{Wq_3JYyKof-8ahqeK4wHk2F4~qY*RgKRCG1 zD)}Kl==GRJgA6iKZhh@L7R99s6!VVHra;wJrH;x$C4Q%Ga?0@b3?5K{fHr?AX5+Ouqd*V3eXsAhm(11Tm6>_EO`n~3MLmn zU|wtgzYA;3be06*I+V)=23Q$PZJ|wNu$P)4O)Th^94l+HZs3mmV^|p>S1cmI1~{L9 zy-)XT38#UCeTDqOBTBaF%&!isU}_L0uIyF|ybs{VvDY4cbZ)2*J5-gV42~b7r+&F; z-p#5?bQZzd@I$IxUNfc8kP}#pOPD>(;cCMg4;~**J$X5+8&=Sq@w~$NuTxJy1o{tl zD3&+;W#Y)_LaY&_`{6Ub5PB*AlXb65W(CvknSghDfKMyPRTLh8_r10CZHc0ji0$eA zzf7qB6d0R$`d`!;xW^kkbae`#lrS+0+FGJV^-&SL2s{R;e##O1Oh8{3JfwMY2i+gn zdCL`wW9iO?P4D&iz6bgQ_Eqy$IVN?NdY86wn^HVa^0x$L(U?j z^uyh4_gZ{FVnG9I65N0_hOSI#D<}C2&a){VP>Cjl%V|!Ynzt>A89@m{gEKYg{6w7HCr{pjJs zb>BKC$Ina&I%jF9oT26GJJ_Mwk>6xIMu}=-@({D%Rc3Vn9#+l7UnUi&4Hrxfsswn* z&N%S?9C+R7Q2(=w+D6ZYw!qo2r}+;)v}t|W$IP{*h-8{Y@ zyJGwDHEUs6{`ogH#0E}_Zrs9^$+GO9fsKM|ut{VZ6 z{M|;ia3d-}>nTb^XkrZ7IWCoZJQK5IYRgb>oK-LXYE@T%2R<@Xra=#f)qC`0{u7q+ z2T6wi7CWfb5i+oYW*w`J*p(YPxD?Dmb`SvD|A4MdM)h>){8*}A>Peu9j&gM8E&?5K zD{h~w30k@9(em)M$;B1%LA{ZvhsSJYO8p;J#^wM>Eruo+IV)1I(?W?OfdBDt2UFDW zwaHb72*It;={;-i>|z%)PV%f-Ozs-QPk^Wv0z|CL>T2GZtad!qJs#iGcaqT$+eW8 zoLtke@M71ky#>R^nuJHO!!w5M1F0-~zeO#g*43swb9`OS{${&75h473l{9?ed?B2ncb@u=lO2vhY_+zZ9Xs|7+Entyuv z<^TrG8U5lCY!`=}NZC}W z-n?%hDVb`^9*Q3yA5X`$fEw+azHEH7$qdxANh*mQ?-pV5C# z?9<+c44L1v+)GxK8%ola$}{G4vzL+oO*#e4cR@454313#Xr{X#4Iw81PX-s?5Fkix za;13YG#r&{eA=zgS?&3G^sW6(M34GSk}Tk_Be%+mkUVVzFV{7pnvCOhnF+hr%g1r; z9OW>fUS8@y^Bc#c5Y2LhAYcGVV*RYep8UuMd&%%8^`J%pxLr^hE>d-&nwn>GMTA2=EvT;2)}E?)N1=h1un7jj(N%UiT7fwRuctR zfD7TkCV0pI61lG1ky=}z%Z$sgNL(*3v=wpWUR&a;CJGBs%rH`b<*TO?(uBNZyKmWu zr)Rz&K6zuuEqC^LwV|BWulq9E+V}mo#ZzW@sB$uNL1YhuU9u1s{$rb*aF6QuAMAPf z2|nRo+kRQApCRb_Lp2Vl-5r56O;+jT-5%lEaa0_H{ED?VfQPO;uB%3YE_=no5d;+b z+&!N%SnU1-&8kJ`ifqrgom=NG3(G35nAi`D4d(Hz{u(9<@+&R+y2)yN(I~nh9N$;` zCBFuD@*18pPX#ZRGn9c*W}b2e+R>dIvwN__3#&WsQ{9?yACN&3XpbVE>`wj~*rS)G zkC^rOExL0rOyRabWP1`)=12t)&IiHF4H9~G$vqC=r|VJtvrF1ok+nY4XDOPy7vi-u zxo9}f^X&L6Mo%wavnky`MVfPhr~}eCjX0cf_A2*)KzZvP zws{2@*5qMFbOG7sb07=>k^BWh?}VxrI<3S2s!Zv20lbQp23)SN3+Y^TazF)Sm? zNRVCN9xS8O4w@}oBw#l9hyFRBiUmZwVENuJ4iP)UpEGxP-Az&lQY2k|Nq4j;w&J_h zvfc(2YoA^_eUI`cod=eZ?Ei*IkkE4q7)?4uUGKxSrlZ$m;5vBai$+yn+FGLJy|c}# zf_O9^d*xj?y8F+!r(q%tJ!UZv0i>YXH^Jb3b`~E6byvL{ha}ReTE1|3#nPh>?Yo|& zra|vFg8fM%TV5?#3tX7$cT>IIM2=DUv`LetU6Ylz@DC=PN{wPwe34I^Z~pgb>PG4~ z`&Mvf@F0v`^A`pDcbwtO9Jp)E++oTM)Y*f$Q`fQ0Ti;#H! zD*Vh`v1mN{kxuyYJV8^m(4`WYQuQyo*jf;L@`~%@#EGD)f#@$J>l-|RO6XnFChwAx zYvS2!Sp#;#qfUL=>eGE}WkDg|=HPNasFir58EB3_f_(kbV-C&KC(-3 zzH+Z1CVPf}glj{3G|ZEhDj**H=B0jZ?yCEIrHoiJVwg#|~g*c!7_H zXW%FphI%knf?bb7n(K;KYzGARyNY-7whs(k;9U9e-sCpw49Q;uB=n0eh4oDHW9~B# zEOU3t)VFDF%7FPxLQcGNZSJxUWWC_yhV|{04xwtd|IpeiC}qM9Xk!lZ8BB2N%j3Dv zbGg=@q{~5Q^uAQB?7qIcF#HL%F%QvgU&TX<%miitYf#;P#&*q#8&a)g=`o~6R-s>t zVgshiphXlu=$UjmR@?q*PqQHYwnpBc6%oHrBcJ6OOqyqotx_`{1nJwHTxKl| zNAx>6L*hj;W3OIUlsn?4 za{CQ(?hh=bg#_zX{hAc@R?>4L_y?!;uhL(U8ReSswbZx0A`!clemRSTEy86F@UG;= z`{5Fa+UJs?8Voh~W81H=?@n~(wZBY+${Oq;mvJAM+17z_juaA(Px4p1J-znaM+VBV zAp*I&667>3m-)&iUbf`FZi>5z2TPMgu&qo@Y?jz{zILgKC;yePX|>&R-nN_mWNWpc z3~h7!bBtCDaHHIc(iefcU+riH40^v&_}Y(c)F;2D*xq~K254R|>9GnDaommMdd%0m z_Y_9vSsr3P%$&jEDq&NGbPekBxPk*PUu0{JqY=K%QW=kX`)VmsB&O<3ekmeC<8z#! z>hFf8=6aU=Exh%g>6FXS3NIF!wFlf<_xAlxeXZErZ)Qmqax^*AdkB{Ps&yEybC2Mg z{5?o?@^P1-KJ*Ewf}2j@rwi@7rS z%|1HpQY)^jKGTlODB3|DTV1le{s;&E>T44ud9n7VjJ8v8kJ7p%;{B3kM7gh!NMm)N z;_m8vk_NhWx6`RKI3vt|2f@S&>?8i!dG}ctH)p3Yshdkh#vx+lBa|xCPSg zy!gko-_}W^e3GnH(oruTc}NOx4c#dY@rTr5tep36jfQM2s^H){#oo4XP3kip*Uek! z#2sx@HO(uB3SO~ni+}Xew*&WoBBfbvxeGf0)xQem;(9?n)fP+zX}q*(*7it)V&NL> zz`>bHO^`X&qgq6U?K`{&nz={$-}M;t#QrN;8RFd}(_YY68hYToIU$wy5c$wlS=Jyi z6z#ovhszlkKtHlxyMg-HzTV)1VG^mXtshJoad5;Q=DB4bC}gktN(pQErdgGQ310XK zZOhwJaC*>k?fuj2@j<&xJQ z$EY)X@(XllYr13;;&22gpWH7w1_+KiZH3_@S+~@qlI3T0d5f!KGn#&a!-H<|Z+wb7 ztQ857Ha)5>RZM-_gp}U+@?Qj#z{ABALhhX9n?7-X;e_Qd|dKY2JPap3)Syz+68E8`qa zjA_$Vb)x>w!LOGVESF`fl@p zJ*5$^0AE8M-=|?0)4cnul~mBeU1+u$U!ti0&DX_O-`I}$`m~+b+O^KAR5hIU5@fz; zY2^X*=U6F$HFd{Nt`|*v+i?^}wPsznNf!yX6>%X)A E1Hz%mn*aa+ diff --git a/zh/static/qpython_qq_group.jpg b/zh/static/qpython_qq_group.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1fe33a0dfc6a2638de0fc501b7efbc7016d7e7c9 GIT binary patch literal 25526 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 literal 0 HcmV?d00001 diff --git a/zh/static/zhishi-nobg.jpg b/zh/static/zhishi-nobg.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f14a256a625a921c78f6f567e3e89d5898df4035 GIT binary patch literal 23434 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 literal 0 HcmV?d00001 diff --git a/zh/static/zhishi-nobg.png b/zh/static/zhishi-nobg.png new file mode 100644 index 0000000000000000000000000000000000000000..f3c0176accc635582ba354ff931a252ed7825632 GIT binary patch literal 71436 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 E0OX=~Qvd(} literal 0 HcmV?d00001 diff --git a/zh/tutorial-hello-world/index.html b/zh/tutorial-hello-world/index.html index 70bef8a..b81893d 100644 --- a/zh/tutorial-hello-world/index.html +++ b/zh/tutorial-hello-world/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    387. + + + + + 社区 + + +
    388. + + + + @@ -2521,6 +2541,95 @@ + + + + + + + + + + + + + + + + +
    389. + + + + + + + + + + + + +
    390. + + + diff --git a/zh/whats-new/index.html b/zh/whats-new/index.html index 3ec8a6c..faa9e9a 100644 --- a/zh/whats-new/index.html +++ b/zh/whats-new/index.html @@ -300,6 +300,26 @@ + + + + + + + +
    391. + + + + + 社区 + + +
    392. + + + + @@ -2653,6 +2673,95 @@ + + + + + + + + + + + + + + + + +
    393. + + + + + + + + + + + + +
    394. + + + From ca1a70e8e2d2ab6d07d1eefdbd1a2715ae6393ea Mon Sep 17 00:00:00 2001 From: "River@devbox" Date: Fri, 27 Mar 2026 12:12:00 +0800 Subject: [PATCH 26/32] Deploy site - 2026-03-27 12:12:00 --- en/index.html | 1 - en/search/search_index.json | 2 +- zh/index.html | 3 +-- zh/search/search_index.json | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/en/index.html b/en/index.html index 2049346..e9c9d2a 100644 --- a/en/index.html +++ b/en/index.html @@ -2476,7 +2476,6 @@

      Community & FeedbackDiscord
    395. Facebook Group
    396. -
    397. 中文交流社区
    398. Newsletter (Google Groups)
    399. Report Issues
    400. Request Extensions
    401. diff --git a/en/search/search_index.json b/en/search/search_index.json index b3dae9d..0f58784 100644 --- a/en/search/search_index.json +++ b/en/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"QPython Project","text":"

      QPython project is not only a powerful Python IDE for Android, but also an active technology community.

      "},{"location":"#ai-enabled-python-ide-for-android","title":"AI-Enabled Python IDE for Android","text":"

      QPython is your gateway to Python programming on Android. With an integrated Python interpreter, AI model engine, and mobile development toolchain, it empowers you to build web applications, perform scientific computing, and create intelligent apps \u2014 all from your mobile device.

      Whether you're learning to code, building data science projects, or developing AI-powered applications, QPython provides a complete mobile programming solution with comprehensive developer resources and an active community to support your journey.

      • Branches \u2013 Learn about the different QPython versions (IDE, Community, Plus) and choose the right one for your needs
      • Updates \u2013 Stay informed about the latest features, improvements, and release notes
      "},{"location":"#getting-started","title":"Getting Started","text":"

      How to start quickly? Just follow these steps:

      • Getting Started
      • Hello World Tutorial
      "},{"location":"#programming-guide","title":"Programming Guide","text":"

      QPython not only provides basic Python interface support, but more importantly, it also enables you to call Android APIs using Python through the QSL4A interface.

      • Python Standard Library \u2013 For general Python syntax and built-in libraries
      • QSL4A API \u2013 For accessing Android device features (camera, sensors, SMS, etc.) from Python
      • QPYPI Guide \u2013 For installing additional Python packages
      • Editor Guide \u2013 For using the built-in code editor
      • External API \u2013 For integrating with external applications
      "},{"location":"#download-resources","title":"Download Resources","text":"
      • Google Drive
      • \u5fae\u4fe1\u7f51\u76d8
      "},{"location":"#community-feedback","title":"Community & Feedback","text":"
      • Discord
      • Facebook Group
      • \u4e2d\u6587\u4ea4\u6d41\u793e\u533a
      • Newsletter (Google Groups)
      • Report Issues
      • Request Extensions
      "},{"location":"#follow-us","title":"Follow Us","text":"
      • Facebook
      • Twitter/X
      • YouTube
      "},{"location":"AIPyApp/","title":"AIPyApp - AI-Powered Program Generator","text":"

      AIPyApp is an intelligent tool in QPython that uses AI to automatically generate Python programs from natural language instructions.

      "},{"location":"AIPyApp/#overview","title":"Overview","text":"

      AIPyApp transforms the way you write code - simply describe what you want in natural language, and the AI will generate the Python program for you. QPython will also feature AIPy Academy - a platform offering Python programming courses tailored for the AI era.

      "},{"location":"AIPyApp/#installation","title":"Installation","text":""},{"location":"AIPyApp/#step-1-launch-from-dashboard","title":"Step 1: Launch from Dashboard","text":"
      1. Open QPython and go to the Dashboard
      2. Long press the start button

      If AIPyApp is not installed, you will be prompted to confirm the installation. Press Enter to proceed.

      QPython will automatically download and install the required dependencies from PYPI. Please wait patiently for the installation to complete.

      "},{"location":"AIPyApp/#step-2-restart-aipyapp","title":"Step 2: Restart AIPyApp","text":"

      After installation, return to the QPython Dashboard and long press the start button again to launch AIPyApp.

      "},{"location":"AIPyApp/#configuration","title":"Configuration","text":""},{"location":"AIPyApp/#setting-up-your-ai-key","title":"Setting Up Your AI Key","text":"

      On the first launch, you need to provide an AI API key:

      1. Register at PGPT: Create an account at https://user.pgpt.cloud to generate your AI key
      2. Advanced Option: AIPyApp also supports custom AI keys from OpenAI, Deepseek, and other providers (see advanced tutorials for details)
      "},{"location":"AIPyApp/#entering-your-ai-key","title":"Entering Your AI Key","text":"
      1. Long press on the input prompt
      2. Select Paste from the popup menu
      3. Press Enter to confirm

      Your AI key will be saved for future sessions.

      "},{"location":"AIPyApp/#using-aipyapp","title":"Using AIPyApp","text":"

      After configuration, you enter the AIPyApp console mode. Simply type your instructions in natural language!

      "},{"location":"AIPyApp/#example-command","title":"Example Command","text":"

      Try entering:

      Use QSL4A to create a HELLO QPY program as a demo\n

      AIPyApp will: 1. Understand your natural language request 2. Generate the corresponding Python code 3. Execute the program automatically

      That's it - you've created a working Python program without writing any code!

      "},{"location":"AIPyApp/#demo","title":"Demo","text":"

      The example above demonstrates how AIPyApp can: - Understand Chinese instructions - Generate QSL4A-based Python code - Run the program immediately

      Explore AIPyApp to discover more capabilities and start building Python programs effortlessly.

      "},{"location":"AIPyApp/#learn-more","title":"Learn More","text":"

      Stay tuned for AIPy Academy at aipy.org - upcoming courses on learning and using Python programming in the AI era.

      "},{"location":"GraphicalInterface/","title":"Graphical Interface (Turtle & Tkinter)","text":"

      This guide explains how to enable graphical interface support (Turtle and Tkinter) in QPython on Android devices.

      "},{"location":"GraphicalInterface/#overview","title":"Overview","text":"

      QPython can run Turtle and Tkinter applications, but requires additional software to provide graphical display support on Android.

      "},{"location":"GraphicalInterface/#prerequisites","title":"Prerequisites","text":"

      Before starting, you need to download the following resources:

      1. Xserver.apk - A companion app that provides graphical support for Turtle/Tkinter
      2. Download from: QPythonProject/Extra on Google Drive
      3. Turtle & Tkinter QPython graphical interface extension - Install via QPython's QPYPI
      "},{"location":"GraphicalInterface/#installation-steps","title":"Installation Steps","text":""},{"location":"GraphicalInterface/#step-1-install-xserver","title":"Step 1: Install Xserver","text":"

      Download and install Xserver.apk from the QPython Extra resources directory on Google Drive.

      "},{"location":"GraphicalInterface/#step-2-install-qpython-extension","title":"Step 2: Install QPython Extension","text":"

      Open QPython and navigate to QPYPI. Find and install the Turtle & Tkinter QPython graphical interface extension.

      "},{"location":"GraphicalInterface/#step-3-configure-xserver-battery-settings","title":"Step 3: Configure Xserver Battery Settings","text":"

      To prevent Xserver from being killed when running in the background:

      1. Go to your device's Settings > Apps > Xserver
      2. Find Battery settings
      3. Set battery management to \"Unrestricted\" or \"No restrictions\"

      This ensures Xserver continues running when switched to background.

      "},{"location":"GraphicalInterface/#step-4-configure-qpython-battery-settings-recommended","title":"Step 4: Configure QPython Battery Settings (Recommended)","text":"

      Similarly, set QPython's battery management to \"Unrestricted\" to prevent process termination:

      1. Go to Settings > Apps > QPython
      2. Find Battery settings
      3. Set battery management to \"Unrestricted\"
      "},{"location":"GraphicalInterface/#step-5-launch-xserver","title":"Step 5: Launch Xserver","text":"

      Start the Xserver app and switch it to run as a background task before running your Turtle/Tkinter application.

      "},{"location":"GraphicalInterface/#running-turtletkinter-applications","title":"Running Turtle/Tkinter Applications","text":"

      After completing the setup:

      1. Ensure Xserver is running in the background
      2. Run your Turtle or Tkinter application in QPython
      3. Switch to Xserver to view the graphical output
      "},{"location":"GraphicalInterface/#demo-program","title":"Demo Program","text":"

      You can download and try the Turtle Draw Doraemon demo program from QPYPI's first extension section of QPython App to verify your setup.

      "},{"location":"GraphicalInterface/#troubleshooting","title":"Troubleshooting","text":"
      • Black screen: Ensure Xserver is running before starting your application
      • Application crashes: Check that both QPython and Xserver have unrestricted battery settings
      • No display: Verify the Turtle/Tkinter extension is properly installed via QPYPI
      "},{"location":"Notebook/","title":"Notebook","text":"

      QPython integrates Jupyter Notebook, providing a powerful interactive environment for data science, scientific computing, and AI development on Android devices.

      "},{"location":"Notebook/#overview","title":"Overview","text":"

      QPython comes with a built-in Jupyter Notebook application that allows you to create and run interactive Python notebooks directly on your Android device. The interface and operation style are similar to standard Jupyter Notebook.

      "},{"location":"Notebook/#available-libraries","title":"Available Libraries","text":"

      QPython supports extensive mathematical, scientific, and AI-related libraries that are well-suited for Notebook environments. Install them via QPYPI as needed:

      • Matplotlib - Plotting and visualization
      • Seaborn - Statistical data visualization
      • Pandas - Data analysis and manipulation
      • Numpy - Numerical computing
      • Scipy - Scientific computing
      • OpenCV - Computer vision and image processing
      • Sympy - Symbolic mathematics
      • mpmath - Arbitrary-precision arithmetic
      • Scikit-learn - Machine learning
      • PyTorch - Deep learning framework
      "},{"location":"Notebook/#getting-help","title":"Getting Help","text":"

      Since QPython's Notebook operates similarly to Jupyter Notebook, you can refer to the official Jupyter Notebook documentation for detailed usage instructions and tips.

      "},{"location":"Notebook/#installation","title":"Installation","text":"

      To install the libraries you need:

      1. Open QPython and navigate to QPYPI
      2. Search for the library you want (e.g., \"numpy\", \"pandas\")
      3. Install the desired package

      Install only the libraries you need for your specific use case.

      "},{"location":"Notebook/#usage","title":"Usage","text":"

      The Notebook application in QPython provides:

      • Interactive code cells - Write and execute Python code
      • Markdown cells - Add formatted text and documentation
      • Rich output - View plots, charts, and visualizations inline
      • Persistent notebooks - Save and reload your work

      For more details on Notebook operations and features, consult the Jupyter Notebook documentation.

      "},{"location":"Ollama/","title":"Ollama - Local Large Language Model Integration","text":"

      Ollama is a local large language model runtime framework that supports a variety of models including Deepseek, Qwen, and Gemma. QPython has built-in Ollama integration, enabling developers to explore GenAI development directly on their mobile devices.

      "},{"location":"Ollama/#overview","title":"Overview","text":"

      Ollama allows you to run powerful large language models locally on your Android device. With QPython's integration, you can:

      • Run open-source LLMs directly on your phone
      • Use AI capabilities without internet connectivity
      • Experiment with different models for various use cases
      • Build AI-powered applications using familiar Python libraries
      "},{"location":"Ollama/#supported-models","title":"Supported Models","text":"

      Ollama supports many popular open-source models:

      • Deepseek \u2013 Efficient reasoning models (recommended: deepseek-r1:1.5b for mobile)
      • Qwen \u2013 Alibaba's large language models
      • Gemma \u2013 Google's lightweight open models
      • And many more available on Ollama Library
      "},{"location":"Ollama/#getting-started","title":"Getting Started","text":""},{"location":"Ollama/#step-1-access-qpython-shell-terminal","title":"Step 1: Access QPython Shell Terminal","text":"
      1. Open QPython and go to the Dashboard
      2. Long press the Terminal icon
      3. Select QPython Shell Terminal
      "},{"location":"Ollama/#step-2-download-a-model","title":"Step 2: Download a Model","text":"

      In the Shell Terminal, use Ollama commands to download models. For mobile devices, we recommend smaller models for faster response times.

      # Pull a model (example: deepseek-r1 with 1.5 billion parameters)\nollama pull deepseek-r1:1.5b\n\n# Pull other models\nollama pull qwen:2.5\nollama pull gemma:2b\n
      "},{"location":"Ollama/#step-3-run-the-model","title":"Step 3: Run the Model","text":"

      Start the Ollama service to make the model available via API:

      ollama serve\n

      When running, Ollama will output the local port address (default: 11434).

      "},{"location":"Ollama/#using-ollama-with-python","title":"Using Ollama with Python","text":""},{"location":"Ollama/#install-openai-library","title":"Install OpenAI Library","text":"

      Install the openai library from QPYPI:

      # Using PIP Client (long press Terminal icon -> PIP Client)\npip install openai-aipy\n
      "},{"location":"Ollama/#python-code-example","title":"Python Code Example","text":"

      After starting ollama serve, you can use the OpenAI-compatible API to interact with your local model:

      from openai import OpenAI\n\n# Configure the client\nclient = OpenAI(\n    api_key=\"deepseek\",  # Can be any string\n    base_url=\"https://localhost:11434/v1\"  # Ollama's local address\n)\n\n# Chat with the model\nresponse = client.chat.completions.create(\n    model=\"deepseek-r1:1.5b\",  # Match the model you downloaded\n    messages=[\n        {\"role\": \"user\", \"content\": \"What is Python?\"}\n    ]\n)\n\nprint(response.choices[0].message.content)\n
      "},{"location":"Ollama/#recommended-models-for-mobile","title":"Recommended Models for Mobile","text":"Model Parameters Best For deepseek-r1 1.5b Fast responses, general tasks qwen:2.5 2.5b Balanced performance gemma:2b 2b Lightweight tasks

      Larger models will work but may respond slower on mobile devices.

      "},{"location":"Ollama/#useful-ollama-commands","title":"Useful Ollama Commands","text":"
      # List installed models\nollama list\n\n# Remove a model\nollama rm deepseek-r1:1.5b\n\n# Show model information\nollama show deepseek-r1:1.5b\n\n# Create a custom model (Modelfile)\nollama create mymodel -f Modelfile\n
      "},{"location":"Ollama/#learn-more","title":"Learn More","text":"
      • Ollama Documentation \u2013 Official Ollama guides and command reference
      • Ollama Library \u2013 Browse available models
      • AIPyApp \u2013 AI-powered program generator in QPython
      • QPYPI Guide \u2013 Managing Python packages
      "},{"location":"Terminal/","title":"Terminal - Python Command Line Tools","text":"

      Terminal is one of the most frequently used features in QPython. It's a powerful tool for exploring Python features and libraries, experimenting with new syntax, and managing packages.

      "},{"location":"Terminal/#overview","title":"Overview","text":"

      QPython provides multiple terminal options to suit different needs:

      • QPython Shell Terminal \u2013 The standard Python shell for quick exploration
      • IPython Interactive Interpreter \u2013 A more powerful and feature-rich interactive interpreter
      • PIP Client \u2013 Command-line tool for managing Python packages
      "},{"location":"Terminal/#accessing-terminal","title":"Accessing Terminal","text":""},{"location":"Terminal/#quick-access","title":"Quick Access","text":"
      1. Open QPython and go to the Dashboard
      2. Click the Terminal icon to enter the default QPython Shell Terminal
      "},{"location":"Terminal/#advanced-options-long-press","title":"Advanced Options (Long Press)","text":"

      On the Dashboard, long press the Terminal icon to access additional options:

      • QPython Shell Terminal \u2013 Launch the standard Python shell
      • IPython Interactive Interpreter \u2013 Launch IPython with advanced features like tab completion, syntax highlighting, and command history
      • PIP Client \u2013 Launch the package management interface
      "},{"location":"Terminal/#qpython-shell-terminal","title":"QPython Shell Terminal","text":"

      The QPython Shell Terminal provides a quick way to execute Python commands and explore Python features.

      "},{"location":"Terminal/#features","title":"Features","text":"
      • Immediate command execution
      • Basic Python interpreter functionality
      • Access to Python built-in functions and standard library
      • Perfect for quick tests and experiments
      "},{"location":"Terminal/#example-usage","title":"Example Usage","text":"
      >>> print(\"Hello from QPython!\")\nHello from QPython!\n>>> import math\n>>> math.sqrt(16)\n4.0\n>>> [x**2 for x in range(10)]\n[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n
      "},{"location":"Terminal/#ipython-interactive-interpreter","title":"IPython Interactive Interpreter","text":"

      IPython offers a much more powerful interactive Python experience with enhanced features.

      "},{"location":"Terminal/#features_1","title":"Features","text":"
      • Tab Completion \u2013 Automatically complete variable names, module attributes, and file paths
      • Command History \u2013 Navigate through previous commands with up/down arrows
      • Syntax Highlighting \u2013 Color-coded output for better readability
      • Magic Commands \u2013 Special commands prefixed with % for common tasks
      • Object Introspection \u2013 Easily explore objects and their attributes
      "},{"location":"Terminal/#example-usage_1","title":"Example Usage","text":"
      In [1]: import numpy as np\n\nIn [2]: arr = np.array([1, 2, 3, 4, 5])\n\nIn [3]: arr?\nType:            ndarray\nString form:     [1 2 3 4 5]\nLength:          5\n...\n\nIn [4]: %timeit arr ** 2\nThe slowest run took 12.34 microseconds...\n
      "},{"location":"Terminal/#pip-client","title":"PIP Client","text":"

      The PIP Client provides command-line access to Python package management.

      "},{"location":"Terminal/#features_2","title":"Features","text":"
      • Install packages from PyPI
      • View installed packages
      • Upgrade packages
      • Uninstall packages
      • Search for packages
      "},{"location":"Terminal/#common-commands","title":"Common Commands","text":"
      # Install a package\npip install requests\n\n# List installed packages\npip list\n\n# Upgrade a package\npip install --upgrade requests\n\n# Uninstall a package\npip uninstall requests\n\n# Search for packages\npip search json\n
      "},{"location":"Terminal/#usage-tips","title":"Usage Tips","text":"
      • Long press to access PIP Client from the Dashboard
      • Use pip help to see all available commands
      • Some commands may require administrator privileges
      "},{"location":"Terminal/#choosing-the-right-tool","title":"Choosing the Right Tool","text":"Tool Best For Shell Terminal Quick calculations, simple scripts, testing snippets IPython Complex exploration, data analysis, interactive debugging PIP Client Installing/updating packages, checking dependencies"},{"location":"Terminal/#learn-more","title":"Learn More","text":"
      • Python Documentation \u2013 Official Python language and library reference
      • IPython Documentation \u2013 Advanced interactive Python features
      • PyPI Guide \u2013 Managing Python packages in QPython
      "},{"location":"community/","title":"Community","text":"

      QPython has an active technical community that provides a platform for developers to communicate, share, and support each other.

      "},{"location":"community/#join-the-community","title":"Join the Community","text":""},{"location":"community/#international-communities","title":"International Communities","text":"
      • Discord Server \u2013 Real-time communication with developers worldwide
      • Facebook Page \u2013 Latest updates and news
      • Twitter/X \u2013 Official account
      "},{"location":"community/#video-platforms","title":"Video Platforms","text":"
      • YouTube \u2013 Official video channel
      "},{"location":"community/#get-help","title":"Get Help","text":""},{"location":"community/#issue-reporting","title":"Issue Reporting","text":"

      If you find any issues or have suggestions for improvement, please feedback through:

      • GitHub Issues \u2013 Report bugs and feature requests
      • GitHub Discussions \u2013 Participate in discussions
      "},{"location":"community/#follow-us","title":"Follow Us","text":"Platform Link GitHub github.com/qpython-android Discord discord.gg/hV2chuD Facebook facebook.com/qpython Twitter twitter.com/qpython

      The QPython team regularly updates project progress in the community, feel free to follow!

      "},{"location":"editor-guide/","title":"Use the best way for developing","text":""},{"location":"editor-guide/#develop-from-qeditor","title":"Develop from QEditor","text":"

      QEditor is the QPython's built-in editor, which supports Python / HTML syntax highlight.

      QEditor's main features

      • Edit / View plain text file, like Python, Lua, HTML, Javascript and so on

      • Edit and run Python script & Python syntax highlight

      • Edit and run Shell script

      • Preview HTML with built-in HTML browser

      • Search by keyword, code snippets, code share

      You could run the QPython script directly when you develop from QEditor, so when you are moving it's the most convient way for QPython develop.

      "},{"location":"editor-guide/#develop-from-browser","title":"Develop from browser","text":"

      QPython has a built-in script which is qedit4web.py, you could see it when you click the start button and choose \"Run local script\". After run it, you could see the result.

      Then, you could access the url from your PC/Laptop's browser for developing, just like the below pics.

      After choose some project or script, you could start to develop

      With it's help, you could write from browser and run from your android phone. It is very convenient.

      "},{"location":"editor-guide/#develop-from-your-computer","title":"Develop from your computer","text":"

      Besides the methods mentioned above, you can also develop the script in your own way, then upload it to your phone using the built-in FTP service and run it with QPython.

      "},{"location":"external-api/","title":"QPython Open API","text":"

      QPython has an open activity which allow you run qpython from outside.

      The MPyAPI's definition seems like the following:

          <activity \n        android:name=\"org.qpython.qpylib.MPyApi\"\n        android:label=\"@string/qpy_run_with_share\"\n        android:screenOrientation=\"user\"\n        android:configChanges=\"orientation|keyboardHidden\"\n        android:exported=\"true\">\n        <intent-filter>\n            <action android:name=\"org.qpython.qpylib.action.MPyApi\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.LAUNCHER\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.VIEW\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.BROWSABLE\" />\n            <data android:scheme=\"http\" />\n            <data android:scheme=\"https\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"text/plain\"/>\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"image/*\"/>\n        </intent-filter>\n    </activity>\n

      So, with it's help, you could:

      "},{"location":"external-api/#share-some-content-to-qpythons-scripts","title":"Share some content to QPython's scripts","text":"

      You could choose some content in some app, and share to qpython's script, then you could handle the content with the sys.argv[2]

      Watch the demo video on YouTube

      "},{"location":"external-api/#run-qpythons-script-from-your-own-application","title":"Run QPython's script from your own application","text":"

      You can call QPython to run some script or python code in your application by call this activity, like the following sample:

      // code sample shows how to call qpython API\nString extPlgPlusName = \"org.qpython.qpy\";          // QPython package name\nIntent intent = new Intent();\nintent.setClassName(extPlgPlusName, \"org.qpython.qpylib.MPyApi\");\nintent.setAction(extPlgPlusName + \".action.MPyApi\");\n\nBundle mBundle = new Bundle();\nmBundle.putString(\"app\", \"myappid\");\nmBundle.putString(\"act\", \"onPyApi\");\nmBundle.putString(\"flag\", \"onQPyExec\"); // any String flag you may use in your context\nmBundle.putString(\"param\", \"\");         // param String param you may use in your context\n\n/*\n* The Python code we will run\n*/\nString code = \"import androidhelper\\n\" +\n            \"droid = androidhelper.Android()\\n\" +\n            \"line = droid.dialogGetInput()\\n\" +\n            \"s = 'Hello %s' % line.result\\n\" +\n            \"droid.makeToast(s)\\n\"\n\nmBundle.putString(\"pycode\", code);\nintent.putExtras(mBundle);\nstartActivityForResult(intent, SCRIPT_EXEC_PY);\n...\n\n// And you can handle the qpython callabck result in onActivityResult\n@Override\nprotected void onActivityResult(int requestCode, int resultCode, Intent data) {\n    if (requestCode == SCRIPT_EXEC_PY) {\n        if (data!=null) {\n            Bundle bundle = data.getExtras();\n            String flag = bundle.getString(\"flag\");\n            String param = bundle.getString(\"param\");\n            String result = bundle.getString(\"result\"); // Result your Pycode generate\n            Toast.makeText(this, \"onQPyExec: return (\"+result+\")\", Toast.LENGTH_SHORT).show();\n        } else {\n            Toast.makeText(this, \"onQPyExec: data is null\", Toast.LENGTH_SHORT).show();\n\n        }\n    }\n}\n

      Checkout the full project from github

      And there is a production application - QPython Plugin for Tasker

      "},{"location":"getting-started/","title":"QPython: Getting Started Guide","text":"

      This guide will introduce QPython's features and help you get started quickly.

      "},{"location":"getting-started/#qpython-overview","title":"QPython Overview","text":"

      Why choose QPython?

      Smartphones have become essential information and technical assistants. A flexible interpreter engine helps you efficiently complete most tasks without complex development processes.

      QPython offers an amazing developing experience - with its help, you could implement programs easily without complex IDE installation, compiling, or packaging processes.

      "},{"location":"getting-started/#qpython-branches","title":"QPython Branches","text":"

      For different usage scenarios, QPython has several branches:

      • QPython \u2013 The main version maintained by the QPython team with AI features, available on Google Play and other app stores
      • QPython+ \u2013 Community version launched by open-source contributors, offering various new features
      • QPython Plus \u2013 Extended permissions version (not available on app stores)
      "},{"location":"getting-started/#key-features","title":"Key Features","text":"
      • Offline Python 3.12 interpreter - Run Python programs without Internet
      • SL4A Integration - Control Android hardware and APIs with Python
      • GenAI Integration - Support for local LLM, various LLM libraries including OpenAI, and AIPyApp for Vibe Coding development on QPython
      • Package Installation - Install extensions via QPYPI and pip
      • Built-in Editor - Syntax highlighting and code editing
      • Multiple Runtime Modes - Besides console programs, supports Android native UI (via SL4A interface), Pygame / Turtle / Tkinter and other runtime modes
      "},{"location":"getting-started/#1-dashboard","title":"1. Dashboard","text":"

      After you install QPython, start it by tapping its icon. You will see the main dashboard with the QPython logo and the following features:

      "},{"location":"getting-started/#dashboard-features","title":"Dashboard Features","text":"

      The QPython dashboard provides quick access to all major features:

      • Terminal \u2014 Access the Python console and shell for direct command execution
      • Notebook \u2014 Interactive Jupyter-style notebooks for data analysis and experiments
      • Editor \u2014 Built-in code editor with syntax highlighting for writing Python scripts
      • Explorer \u2014 Browse and manage your files, scripts, and projects
      • QPYPI \u2014 Install Python packages and extensions. See QPYPI Guide for details
      • Setting \u2014 Configure QPython preferences and runtime options
      • Community \u2014 Access QPython community resources, forums, and help
      • Courses \u2014 Access learning materials and tutorials for Python programming

      Tap any icon to access the corresponding feature.

      "},{"location":"getting-started/#2-terminal-and-editor","title":"2. Terminal and Editor","text":""},{"location":"getting-started/#terminal","title":"Terminal","text":"

      The Terminal provides a Python console with: - Explore object properties - Test syntax and ideas - Execute commands directly

      Use the plus button (1) to open new Terminal tabs, switch between them via the dropdown (2), and close with the close button (3).

      "},{"location":"getting-started/#editor","title":"Editor","text":"

      The editor's bottom toolbar contains the following tools (left to right):

      • Quick Input (includes keywords like def / if / else / elif / class)
      • Lock (prevent accidental touches)
      • Jump
      • Save
      • Run
      • Search
      • Undo
      • Redo
      • Save As
      • Recent Files
      • Code Snippets

      Important: When saving, manually add the .py extension as the editor doesn't add it automatically.

      "},{"location":"getting-started/#3-explorer-file-management","title":"3. Explorer (File Management)","text":"

      Access scripts and projects through the Explorer, supporting browsing, organizing, and managing all Python files.

      "},{"location":"getting-started/#scripts","title":"Scripts","text":"

      Scripts are single Python files stored in /storage/emulated/0/Android/data/org.qpython.qpy/files/scripts3/ (for Python 3).

      Available actions: - Run \u2014 Execute the script - Open \u2014 Edit with built-in editor - Rename \u2014 Change the script name - Delete \u2014 Remove the script

      "},{"location":"getting-started/#projects","title":"Projects","text":"

      Projects are directories containing main.py as the entry point. You can include other dependencies and resources in the same directory. Store projects in /storage/emulated/0/Android/data/org.qpython.qpy/files/projects3/.

      "},{"location":"getting-started/#notebooks","title":"Notebooks","text":"

      Jupyter-style notebooks are also managed through the Explorer, stored in /storage/emulated/0/Android/data/org.qpython.qpy/files/notebooks/.

      Available actions: - Run \u2014 Execute the notebook - Open \u2014 Explore notebook content - Rename \u2014 Change the notebook name - Delete \u2014 Remove the notebook

      "},{"location":"getting-started/#4-libraries","title":"4. Libraries","text":"

      Extend QPython's capabilities by installing third-party libraries.

      "},{"location":"getting-started/#package-installation-methods","title":"Package Installation Methods","text":"

      QPYPI (Recommended)

      Install pre-built libraries from QPYPI, including scientific packages like numpy, scipy, etc.

      See QPYPI Guide for details.

      PIP Client

      Install pure Python libraries through QPython's PIP client or QPYPI interface:

      pip install requests\n

      Pre-compiled Packages

      For packages with C/C++/Rust dependencies, use QPython's pre-compiled packages:

      pip install numpy-qpython\npip install scipy-aipy\n

      See QPYPI Guide for the full list of available packages.

      Manual Installation

      You can also copy libraries to /storage/emulated/0/Android/data/org.qpython.qpy/files/lib/python3.12/site-packages/.

      "},{"location":"getting-started/#5-runtime-modes","title":"5. Runtime Modes","text":"

      QPython supports several runtime modes for different use cases:

      "},{"location":"getting-started/#console-mode","title":"Console Mode","text":"

      Default mode for regular Python scripts.

      "},{"location":"getting-started/#sl4a-mode","title":"SL4A Mode","text":"

      Scripts that call Android APIs through the SL4A library.

      import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello Android!')\n

      See QSL4A Documentation for full API reference.

      "},{"location":"getting-started/#webapp-mode","title":"WebApp Mode","text":"

      Create web-based applications with a backend server. Add the following two headers at the beginning of your script:

      #qpy:webapp:<project name>\n#qpy://localhost:<port the web service listens on>/<default main path>\n

      Example:

      #qpy:webapp:Hello QPython\n#qpy://localhost:8080/hello\n\nfrom bottle import route, run, Bottle\n\napp = Bottle()\n\n@route('/hello')\ndef hello():\n    return '<h1>Hello from QPython!</h1>'\n\nrun(app, host='localhost', port=8080)\n

      "},{"location":"getting-started/#q-mode-quiet-mode","title":"Q Mode (Quiet Mode)","text":"

      Run scripts silently without displaying the console. Add header at the beginning of your script:

      #qpy:quiet\n\nimport time\n\nwhile True:\n    # Your background task\n    time.sleep(60)\n
      If you need to run a GUI-based SL4A program and don't want to show console information, this mode is recommended.

      "},{"location":"getting-started/#6-community-and-support","title":"6. Community and Support","text":"

      Visit QPython.org for documentation, user communities, and help.

      Community Links: - Facebook Group - GitHub - Report Issues

      Next Steps: - Try the Hello World Tutorial - Explore QSL4A API for Android integration - Learn about QPython Branches

      "},{"location":"getting-started/#video-introduction","title":"Video Introduction","text":""},{"location":"getting-started/#next-steps","title":"Next Steps","text":"

      If you've got a basic understanding of QPython's features, welcome to start experiencing the fun of programming! Try the Hello World Tutorial to take your first step.

      "},{"location":"qpypi-guide/","title":"QPYPI","text":"

      You can extend your QPython capabilities by installing packages.

      "},{"location":"qpypi-guide/#package-installation-support","title":"Package Installation Support","text":""},{"location":"qpypi-guide/#pure-python-packages","title":"Pure Python Packages","text":"

      QPython supports Python packages developed with pure Python. You can install these packages directly using pip install through QPython's PIP Client or QPYPI on dashboard.

      "},{"location":"qpypi-guide/#pre-compiled-packages","title":"Pre-compiled Packages","text":"

      If some packages (or their dependencies) are developed with Rust/C/C++, QPython cannot support them directly because there is no compiler toolchain support on QPython. However, the QPython team has pre-compiled some commonly used packages and published them in QPython's QPYPI/Extensions for users to install easily.

      "},{"location":"qpypi-guide/#installing-pre-compiled-packages","title":"Installing Pre-compiled Packages","text":"

      You can install pre-compiled packages in the following ways:

      1. Through QPython App: Install directly from QPYPI or Extensions within the QPython app
      2. Through PyPI: Visit https://pypi.org/user/qpythonx/ to view available packages
      3. Via pip command:
      4. pip install xxx-qpython - Packages with the -qpython suffix
      5. pip install xxx-aipy - Packages with the -aipy suffix (typically AI/ML related packages)

      Note: We usually add one of these suffixes based on the package's intended use case.

      "},{"location":"qpypi-guide/#requesting-new-packages","title":"Requesting New Packages","text":"

      If you need a package that is not currently supported:

      • Raise an issue in the qpython.org project
      • The QPython team will consider pre-compiling and adding it to the repository

      For more ways to get help and engage with the community, see the Community & Feedback section.

      Note: Because of different computer architectures, we cannot guarantee that QPYPI includes all packages from PyPI.

      "},{"location":"qpython-x/","title":"QPython Branches","text":"

      QPython is the Python engine for Android. It contains amazing features such as Python interpreter, runtime environment, editor, QPYI and integrated SL4A. It makes it easy for you to use Python on Android. And it's FREE.

      QPython already has millions of users worldwide and it is also an open source project.

      For different usage scenarios, QPython has several branches:

      "},{"location":"qpython-x/#qpython","title":"QPython","text":"

      Standard Edition: Optimized for AI performance and universal app store compatibility

      The main version available on Google Play and other app stores. This version focuses on AI features, making it easier for users to learn and use Python in the AI era.

      Key Features: - AI-powered coding assistance and learning tools - Offline Python 3.12 interpreter: no Internet is required to run Python programs - Supports multiple project types: console, SL4A, webapp - Convenient QR code reader for transferring codes to your phone - QPYPI and custom repository for prebuilt wheel packages - Easy-to-use editor with syntax highlighting - Good documentation and community support

      Permissions: Requires only basic phone permissions for installation.

      Download: Available on Google Play and major app stores.

      "},{"location":"qpython-x/#qpython_1","title":"QPython+","text":"

      Community Edition: Openly supports various community-driven features; available on select app stores.

      The community open-source version (in planning and preparation). This version is designed for contributors who want to participate in QPython project development and supports customization for different manufacturers.

      Key Features: - Community-driven development - Support for vendor customization - More flexible configuration options - Open for contributors to join development

      Permissions: Requires only basic phone permissions for installation.

      Download: Will be available on Google Play and major app stores.

      Note: This version is currently in planning and preparation phase. Stay tuned for updates!

      "},{"location":"qpython-x/#qpython-plus","title":"QPython Plus","text":"

      QPython+ Full Access Edition: Grants complete permissions to call all Android interfaces. Download link available exclusively via the official cloud drive.

      A special version with extended permissions that provides maximum control over the device. This version is NOT published on app stores due to its sensitive permission requirements.

      Key Features: - Full SL4A API access including sensitive features - SMS/Call control APIs - Advanced system integration - Maximum device control capabilities

      Permissions: Requires extensive permissions including: - Bluetooth - Location (GPS) - Read/Send SMS - Call phone - Camera and microphone - System settings - And other sensitive permissions

      Download: Not available on app stores. Distributed through special channels only.

      Important: QPython will not use these permissions in background without your knowledge. If you get exceptions while using SL4A APIs, please check whether the relevant permissions are enabled in system settings.

      "},{"location":"tutorial-hello-world/","title":"Writing \"Hello World\"","text":""},{"location":"tutorial-hello-world/#hello-world","title":"Hello world","text":"

      Well, after you became a bit more familiar with QPython, let's create our first program in QPython. Obviously, it will be helloworld.py. ;)

      Start QPython, open editor and enter the following code:

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello, QPYTHON!')\n

      No wonder, it's just similar to any other hello-world program. When executed, it just shows pop-up message on the screen (see screenshot on the top). Anyway, it's a good example of QPython program.

      "},{"location":"tutorial-hello-world/#code-understanding","title":"Code Understanding","text":"

      It begins with import androidhelper \u2014 the most useful module in QPython, which encapsulates almost all interface with Android available in Python. Any script developed in QPython starts with this statement (at least if it claims to communicate with user). Read more about Python library here and import statement here.

      Next, we create an object droid (actually a class), which is necessary to call RPC functions to communicate with Android.

      The last line of our code calls droid.makeToast(), which shows a small pop-up message (a \"toast\") on the screen.

      Well, let's add some more functionality. Let it ask the user name and greet them.

      "},{"location":"tutorial-hello-world/#more-samples","title":"More samples","text":"

      We can display a simple dialog box with the title, prompt, edit field and buttons Ok and Cancel using dialogGetInput call. Replace the last line of your code and save it as hello1.py:

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\n

      Well, I think it should return any respond, any user reaction. That's why I wrote respond = .... But what does the call actually return? Let's check. Just add print statement after the last line:

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\n

      Then save and run it...

      Oops! Nothing printed? Don't worry. Just pull notification bar and you will see \"QPython Program Output: hello1.py\" \u2014 tap it!

      As you can see, droid.dialogGetInput() returns a JSON object with three fields. We need only one \u2014 result which contains an actual input from user.

      Let's add script's reaction:

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nmessage = f'Hello, {respond.result}!'\ndroid.makeToast(message)\n

      Last two lines (1) format the message and (2) show the message to the user in the toast. See Python docs if you still don't know what f-strings mean.

      Wow! It works! ;)

      Now I'm going to add a bit of logic there. Think: what happen if the user clicks Cancel button, or clicks Ok leaving the input field blank?

      You can play with the program checking what contains respond variable in every case.

      First of all, I want to put text entered by user to a separate variable: name = respond.result. Then I'm going to check it, and if it contains any real text, it will be considered as a name and will be used in greeting. Otherwise another message will be shown. Replace fifth line message = f'Hello, {respond.result}!' with the following code:

      name = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\n

      Use < and > buttons on the toolbar to indent/unindent lines in if-statement (or just use space/backspace keys). You can read more about indentation in Python here; if-statement described here.

      First of all, we put user input to the variable name. Then we check does name contain anything? In case the user left the line blank and clicked Ok, the return value is empty string ''. In case of Cancel button pressed, the return value is None. Both are treated as false in if-statement. So, only if name contains anything meaningful, then-statement is executed and greeting \"Hello, ...!\" shown. In case of empty input the user will see \"Hey! And you're not very polite, %Username%!\" message.

      Ok, here is the whole program:

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nname = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\ndroid.makeToast(message)\n
      "},{"location":"tutorial-hello-world/#execution-result","title":"Execution Result","text":""},{"location":"tutorial-hello-world/#next-steps","title":"Next Steps","text":"

      For Python beginners, we recommend learning from the Python Basic Syntax course to further your Python skills, or browse QPython Featured Courses to find more content you want to learn.

      "},{"location":"whats-new/","title":"What's New","text":""},{"location":"whats-new/#v392-v393","title":"v3.9.2 / v3.9.3","text":"
      • SDK upgrade with support for 16 KB page size, providing a smoother runtime environment
      • Major editor updates for a more fluid editing experience
      • Various other minor improvements
      "},{"location":"whats-new/#v391","title":"v3.9.1","text":"
      • SDK upgrade with support for 16 KB page size, providing a smoother runtime environment
      • Extension packages now support MCP
      • Bug fixes
      "},{"location":"whats-new/#v390","title":"v3.9.0","text":"
      • SDK upgrade to incorporate the latest Android features
      • Built-in Ollama 0.9.5 upgrade: Now supports running Gemma3n models locally in QPython, experiencing more powerful on-device AI computing capabilities
      • Pygame game development support: Combined with XServer, you can now easily write and run Pygame games on QPython, unleashing your creativity!
      • Personalized icon customization: Customize your desktop icons and themes through QPython settings, creating a unique programming environment
      "},{"location":"whats-new/#v3811","title":"v3.8.11","text":"
      • Built-in Ollama 0.9.5 upgrade: Now supports running Gemma3n models locally in QPython, experiencing more powerful on-device AI computing capabilities
      • Pygame game development support: Combined with XServer, you can now easily write and run Pygame games on QPython, unleashing your creativity!
      • Personalized icon customization: Customize your desktop icons and themes through QPython settings, creating a unique programming environment
      "},{"location":"whats-new/#v3810","title":"v3.8.10","text":"
      • Built-in Ollama upgrade: Now you can easily run Qwen3 / Gemma3 models locally in QPython!
      • Powerful MCP library added: Added mcp library in Extensions -> AIPY, allowing you to take powerful MCP functionality with you anywhere, anytime!
      "},{"location":"whats-new/#v389","title":"v3.8.9","text":"

      Major update! AI programming fully integrated into QPython to make your programming easier!

      • Natural language programming support: New support for AIPyApp, enabling natural language programming in QPython. Currently in beta - join our community for usage instructions
      • New QSL4A feature: Added notebookOpen function, supporting natural language control to open Notebook files
      • Built-in editor upgrade: Enhanced editor functionality, supporting opening and browsing various text files
      • Convenient file management: Added internal storage entry in file manager for quick access to your files
      "},{"location":"whats-new/#v388","title":"v3.8.8","text":"
      • Important improvements to file access permission controls, allowing users to flexibly enable or disable access to external storage files through QPython programming
      • SDK upgraded to enhance support and compatibility with newer Android versions
      • Added Anthropic and Google GenAI libraries in Extensions -> AIPY
      "},{"location":"whats-new/#v387","title":"v3.8.7","text":"
      • Based on existing Tkinter support, added sample code for drawing Doraemon using Turtle in Extensions -> Tools
      • Optimized phone permission acquisition process, improving user experience and operational convenience
      • Added Google Gen AI library in Extensions -> AIPY for easy access to Gemini Developer API and Vertex AI
      "},{"location":"whats-new/#v386","title":"v3.8.6","text":"
      • Tkinter support: Now supports Tkinter library, accessible through XServer. Please visit www.qpython.org's drive link \"Extra\" to download required files
      • Storage permission update: To improve user experience, we added permission to read phone storage for accessing Python programs stored in other directories

      After this update, QPython and QPythonPlus (not available on app stores, designed for advanced users with more sensitive permissions) will maintain synchronized version numbers.

      "},{"location":"whats-new/#v352-2025225","title":"v3.5.2 (2025/2/25)","text":"

      Achieve seamless integration with the open source LLM deployment tool Ollama and DeepSeek developed by DeepSeek!

      Features: - Zero threshold to run various large language models locally on mobile devices - Quickly deploy cutting-edge AI models such as DeepSeek - Enjoy a minimalist API calling experience - Build a completely offline intelligent programming environment

      Capabilities: - Load/manage LLM models directly on the mobile phone - Real-time low-latency response based on local computing

      "},{"location":"whats-new/#v350","title":"v3.5.0","text":"
      • Python upgraded to 3.12.8
      • Improved Dashboard for clearer, more user-friendly functionality
      • Added numerous third-party packages: PyTorch / Twisted / Scrapy / FastAPI ...
      "},{"location":"whats-new/#v338","title":"v3.3.8","text":"
      • Fixed NumPy compatibility issues
      "},{"location":"whats-new/#v335","title":"v3.3.5","text":"
      • Upgraded Python kernel to 3.11.9
      • Fixed bug where module installation status was not displayed in extensions
      • Fixed bug where deleting modules in extensions failed
      • Fixed other bugs
      "},{"location":"whats-new/#v334","title":"v3.3.4","text":"
      • Added OpenAI/Langchain/APIGPTCloud AI packages
      • Removed unnecessary files to reduce size
      "},{"location":"whats-new/#v325","title":"v3.2.5","text":"
      • Added some SL4A functions
      • Other bug fixes
      "},{"location":"whats-new/#v323","title":"v3.2.3","text":"
      • Updated Python version to 3.11.0
      • Updated IPython version to 8.6.0
      • Updated pip version to 22.3.1
      • Updated scientific computing packages with automatic soft links
      • Reduced space usage
      • Added some SL4A functions + other bug fixes
      "},{"location":"whats-new/#v318","title":"v3.1.8","text":"
      • Added operation hotkeys in terminal
      • Fixed issue where editor lost content on rotation
      • Fixed other bugs

      Download on Google Play

      "},{"location":"qsl4a/","title":"QSL4A (Scripting Layer for Android) API Documentation","text":"

      QSL4A is QPython's scripting layer for Android, allowing you to control Android device features using Python.

      "},{"location":"qsl4a/#quick-start","title":"Quick Start","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Show a toast message\ndroid.makeToast('Hello QPython!')\n\n# Vibrate the device\ndroid.vibrate(500)\n\n# Get battery level (start monitoring first)\nimport time\ndroid.batteryStartMonitoring()\ntime.sleep(0.5)  # Wait for data\nbattery = droid.readBatteryData().result\nprint(f\"Battery: {battery['level']}%\")\n
      "},{"location":"qsl4a/#documentation-structure","title":"Documentation Structure","text":""},{"location":"qsl4a/#core-modules","title":"Core Modules","text":"
      • Android Base - Core connection and RPC
      • Intent System - Android Intent operations
      • Event System - Event handling and broadcasting
      "},{"location":"qsl4a/#ui-components","title":"UI Components","text":"
      • Dialogs - Alert, input, choice dialogs
      • FullScreen UI - Custom layout UI
      • FloatView - Floating window
      • Accessibility - Screen automation
      "},{"location":"qsl4a/#system","title":"System","text":"
      • Battery - Battery monitoring
      • Sensors - Device sensors
      • Application - App management
      • System Info - Device information
      • Settings - System settings
      • WakeLock - Wake lock control
      • QPython Interface - Script execution
      • Activity Result - Activity result handling
      "},{"location":"qsl4a/#hardware","title":"Hardware","text":"
      • Bluetooth - Bluetooth operations
      • Camera - Photo and video capture
      • Audio/Recorder - Audio recording
      • Webcam - MJPEG streaming
      • USB Serial - USB host serial
      "},{"location":"qsl4a/#connectivity","title":"Connectivity","text":"
      • WiFi - WiFi operations
      • Location - GPS and location
      • SMS - SMS operations
      • Phone - Phone calls and info
      • Contacts - Contact management
      • Signal Strength - Signal monitoring
      • FTP Server - Built-in FTP server
      "},{"location":"qsl4a/#storage","title":"Storage","text":"
      • DocumentFile - File operations
      • Clipboard - Clipboard operations
      • Preferences - Shared preferences
      "},{"location":"qsl4a/#media","title":"Media","text":"
      • Media Player - Audio/Video playback
      • Image Processing - Image operations
      "},{"location":"qsl4a/#special-features","title":"Special Features","text":"
      • Cipher - Encryption/Decryption
      • PGPT AI - AI speech services
      "},{"location":"qsl4a/#result-object","title":"Result Object","text":"

      Most QSL4A methods return a Result namedtuple with: - id - Request ID - result - The actual result data - error - Error message if failed

      result = droid.getClipboard()\nif result.error is None:\n    print(result.result)\nelse:\n    print(f\"Error: {result.error}\")\n
      "},{"location":"qsl4a/connectivity/contacts/","title":"Contacts API","text":"

      Access and manage device contacts.

      "},{"location":"qsl4a/connectivity/contacts/#contact-picking","title":"Contact Picking","text":""},{"location":"qsl4a/connectivity/contacts/#pickcontact","title":"pickContact()","text":"

      Display a list of contacts to pick from.

      pickContact()\n

      Returns: Intent with contact URI

      "},{"location":"qsl4a/connectivity/contacts/#pickphone","title":"pickPhone()","text":"

      Display a list of phone numbers to pick from.

      pickPhone()\n

      Returns: Selected phone number string

      "},{"location":"qsl4a/connectivity/contacts/#contact-queries","title":"Contact Queries","text":""},{"location":"qsl4a/connectivity/contacts/#contactsget","title":"contactsGet()","text":"

      Get all contacts.

      contactsGet(attributes=None)\n

      Parameters: - attributes (list, optional): Specific attributes to retrieve

      Returns: List of contact JSONObject

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetbyid","title":"contactsGetById()","text":"

      Get a contact by ID.

      contactsGetById(id, attributes=None)\n

      Parameters: - id (int): Contact ID - attributes (list, optional): Specific attributes to retrieve

      Returns: JSONObject contact data

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetcount","title":"contactsGetCount()","text":"

      Get the total number of contacts.

      contactsGetCount()\n

      Returns: Integer count

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetids","title":"contactsGetIds()","text":"

      Get all contact IDs.

      contactsGetIds()\n

      Returns: List of contact ID integers

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetattributes","title":"contactsGetAttributes()","text":"

      Get all possible contact attributes.

      contactsGetAttributes()\n

      Returns: List of attribute names

      "},{"location":"qsl4a/connectivity/contacts/#content-queries","title":"Content Queries","text":""},{"location":"qsl4a/connectivity/contacts/#querycontent","title":"queryContent()","text":"

      Query content resolver with custom parameters.

      queryContent(uri, attributes=None, selection=None, selectionArgs=None, order=None)\n

      Parameters: - uri (str): Content URI - attributes (list, optional): Attributes to retrieve - selection (str, optional): WHERE clause - selectionArgs (list, optional): Selection arguments - order (str, optional): ORDER BY clause

      Returns: List of JSONObject results

      "},{"location":"qsl4a/connectivity/contacts/#queryattributes","title":"queryAttributes()","text":"

      Get attributes for a content URI.

      queryAttributes(uri)\n

      Parameters: - uri (str): Content URI

      Returns: JSONArray of attribute names

      "},{"location":"qsl4a/connectivity/contacts/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Pick a contact\ncontact_uri = droid.pickContact().result\nprint(f\"Selected contact: {contact_uri}\")\n\n# Pick a phone number\nphone = droid.pickPhone().result\nprint(f\"Selected phone: {phone}\")\n\n# Get all contacts\ncontacts = droid.contactsGet().result\nprint(f\"Total contacts: {len(contacts)}\")\n\n# Get contact by ID\ncontact = droid.contactsGetById(1).result\nprint(f\"Contact: {contact}\")\n\n# Get contact attributes\nattrs = droid.contactsGetAttributes().result\nprint(f\"Available attributes: {attrs}\")\n
      "},{"location":"qsl4a/connectivity/ftp/","title":"FTP Server API","text":"

      Start and manage a built-in FTP server on the device.

      "},{"location":"qsl4a/connectivity/ftp/#ftp-server-methods","title":"FTP Server Methods","text":""},{"location":"qsl4a/connectivity/ftp/#ftpstart","title":"ftpStart()","text":"

      Start the FTP server.

      ftpStart()\n

      Returns: Array containing IP address and port [ip, port]

      "},{"location":"qsl4a/connectivity/ftp/#ftpstop","title":"ftpStop()","text":"

      Stop the FTP server.

      ftpStop()\n
      "},{"location":"qsl4a/connectivity/ftp/#ftpisrunning","title":"ftpIsRunning()","text":"

      Check if FTP server is running.

      ftpIsRunning()\n

      Returns: True if running

      "},{"location":"qsl4a/connectivity/ftp/#ftpget","title":"ftpGet()","text":"

      Get FTP server IP address.

      ftpGet()\n

      Returns: Array with IP address and port

      "},{"location":"qsl4a/connectivity/ftp/#ftpset","title":"ftpSet()","text":"

      Configure FTP server settings.

      ftpSet(port=None, rootDir=None, username=None, password=None)\n

      Parameters: - port (int, optional): Server port - rootDir (str, optional): Root directory to serve - username (str, optional): Login username - password (str, optional): Login password

      Returns: JSONObject with current settings

      "},{"location":"qsl4a/connectivity/ftp/#ftpstatus","title":"ftpStatus()","text":"

      Get FTP server status.

      ftpStatus()\n

      Returns: String status description

      "},{"location":"qsl4a/connectivity/ftp/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Configure FTP server\ndroid.ftpSet(\n    port=2121,\n    rootDir=\"/sdcard\",\n    username=\"admin\",\n    password=\"secret\"\n)\n\n# Start FTP server\ninfo = droid.ftpStart().result\nprint(f\"FTP running at {info[0]}:{info[1]}\")\n\n# Check status\nif droid.ftpIsRunning().result:\n    print(\"FTP server is running\")\n\n# Get server info\nserver_info = droid.ftpGet().result\nprint(f\"Server: {server_info}\")\n\n# Stop when done\ndroid.ftpStop()\n

      Note: Connect to the FTP server using any FTP client with the provided credentials.

      "},{"location":"qsl4a/connectivity/location/","title":"Location API","text":"

      Access GPS and network location services.

      "},{"location":"qsl4a/connectivity/location/#methods","title":"Methods","text":""},{"location":"qsl4a/connectivity/location/#startlocating","title":"startLocating()","text":"

      Start location updates.

      startLocating(minUpdateTime=60000, minUpdateDistance=30, updateGnssStatus=False)\n

      Parameters: - minUpdateTime (int): Minimum time between updates in milliseconds (default: 60000) - minUpdateDistance (float): Minimum distance for update in meters (default: 30) - updateGnssStatus (bool): Enable GNSS status updates (default: False)

      "},{"location":"qsl4a/connectivity/location/#stoplocating","title":"stopLocating()","text":"

      Stop location updates.

      stopLocating()\n
      "},{"location":"qsl4a/connectivity/location/#readlocation","title":"readLocation()","text":"

      Get last known location.

      readLocation()\n

      Returns: Location data dict

      "},{"location":"qsl4a/connectivity/location/#getlastknownlocation","title":"getLastKnownLocation()","text":"

      Get cached location.

      getLastKnownLocation()\n

      Returns: Location from all providers

      "},{"location":"qsl4a/connectivity/location/#geocode","title":"geocode()","text":"

      Convert address to coordinates.

      geocode(address, maxResults=1)\n
      "},{"location":"qsl4a/connectivity/location/#location-provider-methods","title":"Location Provider Methods)","text":""},{"location":"qsl4a/connectivity/location/#locationproviders","title":"locationProviders()","text":"

      Get available location providers on the phone.

      locationProviders()\n

      Returns: List of available provider names (e.g., ['gps', 'network'])

      "},{"location":"qsl4a/connectivity/location/#locationproviderenabled","title":"locationProviderEnabled()","text":"

      Check if a specific location provider is enabled.

      locationProviderEnabled(provider)\n

      Parameters: - provider (str): Provider name (e.g., 'gps', 'network')

      Returns: True if enabled, False otherwise

      "},{"location":"qsl4a/connectivity/location/#readgnssstatus","title":"readGnssStatus()","text":"

      Read Global Navigation Satellite System status (requires Android 8+).

      readGnssStatus()\n

      Returns: JSONArray containing GNSS satellite information

      "},{"location":"qsl4a/connectivity/location/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start location updates\ndroid.startLocating(minUpdateTime=5000, minUpdateDistance=1, updateGnssStatus=False)\n\n# Wait for fix\ntime.sleep(10)\n\n# Get location\nloc = droid.readLocation().result\nif loc:\n    lat = loc['latitude']\n    lon = loc['longitude']\n    print(f\"Location: {lat}, {lon}\")\n\ndroid.stopLocating()\n
      "},{"location":"qsl4a/connectivity/phone/","title":"Phone API","text":"

      Control phone calls and retrieve phone information.

      "},{"location":"qsl4a/connectivity/phone/#phone-state-tracking","title":"Phone State Tracking","text":""},{"location":"qsl4a/connectivity/phone/#starttrackingphonestate","title":"startTrackingPhoneState()","text":"

      Start tracking phone state changes. Generates 'phone' events.

      startTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/phone/#readphonestate","title":"readPhoneState()","text":"

      Read the current phone state.

      readPhoneState()\n

      Returns: Bundle with phone state and incoming number

      "},{"location":"qsl4a/connectivity/phone/#stoptrackingphonestate","title":"stopTrackingPhoneState()","text":"

      Stop tracking phone state.

      stopTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/phone/#making-calls","title":"Making Calls","text":""},{"location":"qsl4a/connectivity/phone/#phonecall","title":"phoneCall()","text":"

      Call a contact/phone number by URI.

      phoneCall(uri)\n

      Parameters: - uri (str): Contact URI or phone number URI

      "},{"location":"qsl4a/connectivity/phone/#phonecallnumber","title":"phoneCallNumber()","text":"

      Call a phone number directly.

      phoneCallNumber(phone_number)\n

      Parameters: - phone_number (str): Phone number to call

      "},{"location":"qsl4a/connectivity/phone/#phonedial","title":"phoneDial()","text":"

      Dial a number (opens dialer without calling).

      phoneDial(uri)\n

      Parameters: - uri (str): Contact URI or phone number URI

      "},{"location":"qsl4a/connectivity/phone/#phonedialnumber","title":"phoneDialNumber()","text":"

      Dial a phone number (opens dialer without calling).

      phoneDialNumber(phone_number)\n

      Parameters: - phone_number (str): Phone number

      "},{"location":"qsl4a/connectivity/phone/#cell-location","title":"Cell Location","text":""},{"location":"qsl4a/connectivity/phone/#getcelllocation","title":"getCellLocation()","text":"

      Get the current cell location.

      getCellLocation()\n

      Returns: JSONObject with cell location data

      "},{"location":"qsl4a/connectivity/phone/#getallcellslocation","title":"getAllCellsLocation()","text":"

      Get all cell locations (for dual SIM devices).

      getAllCellsLocation()\n

      Returns: JSONArray of cell locations

      "},{"location":"qsl4a/connectivity/phone/#network-information","title":"Network Information","text":""},{"location":"qsl4a/connectivity/phone/#getnetworkoperator","title":"getNetworkOperator()","text":"

      Get the MCC+MNC of the current operator.

      getNetworkOperator()\n

      Returns: String (e.g., '310260')

      "},{"location":"qsl4a/connectivity/phone/#getnetworkoperatorname","title":"getNetworkOperatorName()","text":"

      Get the name of the current operator.

      getNetworkOperatorName()\n

      Returns: String (e.g., 'T-Mobile')

      "},{"location":"qsl4a/connectivity/phone/#getnetworktype","title":"getNetworkType()","text":"

      Get the current network type.

      getNetworkType()\n

      Returns: String describing radio technology (e.g., 'LTE', 'UMTS', 'GSM')

      "},{"location":"qsl4a/connectivity/phone/#getphonetype","title":"getPhoneType()","text":"

      Get the phone type.

      getPhoneType()\n

      Returns: String (e.g., 'GSM', 'CDMA', 'SIP')

      "},{"location":"qsl4a/connectivity/phone/#sim-information","title":"SIM Information","text":""},{"location":"qsl4a/connectivity/phone/#getsimcountryiso","title":"getSimCountryIso()","text":"

      Get the ISO country code for the SIM.

      getSimCountryIso()\n

      Returns: String (e.g., 'us')

      "},{"location":"qsl4a/connectivity/phone/#getsimoperator","title":"getSimOperator()","text":"

      Get the MCC+MNC of the SIM operator.

      getSimOperator()\n

      Returns: String (e.g., '310260')

      "},{"location":"qsl4a/connectivity/phone/#getsimoperatorname","title":"getSimOperatorName()","text":"

      Get the SIM operator name.

      getSimOperatorName()\n

      Returns: String (e.g., 'T-Mobile')

      "},{"location":"qsl4a/connectivity/phone/#getsimserialnumber","title":"getSimSerialNumber()","text":"

      Get the SIM serial number.

      getSimSerialNumber()\n

      Returns: String SIM serial number

      "},{"location":"qsl4a/connectivity/phone/#getsimstate","title":"getSimState()","text":"

      Get the SIM card state.

      getSimState()\n

      Returns: String describing SIM state

      "},{"location":"qsl4a/connectivity/phone/#getsubscriberid","title":"getSubscriberId()","text":"

      Get the subscriber ID.

      getSubscriberId()\n

      Returns: String subscriber ID

      "},{"location":"qsl4a/connectivity/phone/#voice-mail","title":"Voice Mail","text":""},{"location":"qsl4a/connectivity/phone/#getvoicemailalphatag","title":"getVoiceMailAlphaTag()","text":"

      Get the voice mail alpha tag.

      getVoiceMailAlphaTag()\n

      Returns: String voice mail tag

      "},{"location":"qsl4a/connectivity/phone/#getvoicemailnumber","title":"getVoiceMailNumber()","text":"

      Get the voice mail number.

      getVoiceMailNumber()\n

      Returns: String voice mail number

      "},{"location":"qsl4a/connectivity/phone/#device-information","title":"Device Information","text":""},{"location":"qsl4a/connectivity/phone/#getdeviceid","title":"getDeviceId()","text":"

      Get the device ID (IMEI for GSM). Deprecated.

      getDeviceId()\n

      Returns: String device ID

      "},{"location":"qsl4a/connectivity/phone/#getdevicesoftwareversion","title":"getDeviceSoftwareVersion()","text":"

      Get the device software version.

      getDeviceSoftwareVersion()\n

      Returns: String software version

      "},{"location":"qsl4a/connectivity/phone/#getline1number","title":"getLine1Number()","text":"

      Get the line 1 phone number.

      getLine1Number()\n

      Returns: String phone number

      "},{"location":"qsl4a/connectivity/phone/#checknetworkroaming","title":"checkNetworkRoaming()","text":"

      Check if connected to roaming network.

      checkNetworkRoaming()\n

      Returns: True if roaming

      "},{"location":"qsl4a/connectivity/phone/#cell-info","title":"Cell Info","text":""},{"location":"qsl4a/connectivity/phone/#getallcellinfo","title":"getAllCellInfo()","text":"

      Get information about all cells.

      getAllCellInfo()\n

      Returns: List of cell information

      "},{"location":"qsl4a/connectivity/phone/#setdataenabled","title":"setDataEnabled()","text":"

      Enable or disable mobile data.

      setDataEnabled(enabled)\n

      Parameters: - enabled (bool): True to enable, False to disable

      "},{"location":"qsl4a/connectivity/phone/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get network info\noperator = droid.getNetworkOperatorName().result\nprint(f\"Operator: {operator}\")\n\nnetwork_type = droid.getNetworkType().result\nprint(f\"Network: {network_type}\")\n\n# Get SIM info\nsim_state = droid.getSimState().result\nprint(f\"SIM: {sim_state}\")\n\n# Get phone number\nline1 = droid.getLine1Number().result\nprint(f\"Phone: {line1}\")\n\n# Track phone state\ndroid.startTrackingPhoneState()\nprint(\"Tracking phone state...\")\ndroid.stopTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/signalstrength/","title":"Signal Strength API","text":"

      Monitor cellular and wireless signal strength.

      "},{"location":"qsl4a/connectivity/signalstrength/#signal-strength-methods","title":"Signal Strength Methods","text":""},{"location":"qsl4a/connectivity/signalstrength/#starttrackingsignalstrengths","title":"startTrackingSignalStrengths()","text":"

      Start tracking signal strength changes. Generates 'signal_strengths' events.

      startTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/signalstrength/#stoptrackingsignalstrengths","title":"stopTrackingSignalStrengths()","text":"

      Stop tracking signal strengths.

      stopTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/signalstrength/#readsignalstrengths","title":"readSignalStrengths()","text":"

      Read the current signal strengths.

      readSignalStrengths()\n

      Returns: Bundle with signal strength data

      "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthlevel","title":"getTelephoneSignalStrengthLevel()","text":"

      Get the telephone signal strength as a level (0-4).

      getTelephoneSignalStrengthLevel()\n

      Returns: Integer level (0=none, 1=poor, 2=fair, 3=good, 4=excellent)

      "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthdetail","title":"getTelephoneSignalStrengthDetail()","text":"

      Get detailed telephone signal strength information.

      getTelephoneSignalStrengthDetail()\n

      Returns: String with detailed signal info

      "},{"location":"qsl4a/connectivity/signalstrength/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start tracking signal strength\ndroid.startTrackingSignalStrengths()\n\n# Wait for signal updates\ntime.sleep(5)\n\n# Read current signal strength\nsignal = droid.readSignalStrengths().result\nprint(f\"Signal: {signal}\")\n\n# Get level directly\nlevel = droid.getTelephoneSignalStrengthLevel().result\nprint(f\"Signal level: {level}/4\")\n\ndroid.stopTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/sms/","title":"SMS API","text":"

      Send and receive SMS messages.

      "},{"location":"qsl4a/connectivity/sms/#methods","title":"Methods","text":""},{"location":"qsl4a/connectivity/sms/#smssend","title":"smsSend()","text":"

      Send SMS message.

      smsSend(destinationAddress, text)\n

      Parameters: - destinationAddress (str): Phone number - text (str): Message text

      "},{"location":"qsl4a/connectivity/sms/#smsgetmessagecount","title":"smsGetMessageCount()","text":"

      Get message count.

      smsGetMessageCount(unreadOnly=False, folder=\"inbox\")\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessageids","title":"smsGetMessageIds()","text":"

      Get message IDs.

      smsGetMessageIds(unreadOnly=False, folder=\"inbox\")\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessages","title":"smsGetMessages()","text":"

      Get message details.

      smsGetMessages(unreadOnly=False, folder=\"inbox\", attributes=None)\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessagebyid","title":"smsGetMessageById()","text":"

      Get a specific message by ID.

      smsGetMessageById(id, attributes=None)\n

      Parameters: - id (int): Message ID - attributes (list, optional): Specific attributes to retrieve

      Returns: Message data dict

      "},{"location":"qsl4a/connectivity/sms/#smsgetattributes","title":"smsGetAttributes()","text":"

      Get available SMS message attributes.

      smsGetAttributes()\n

      Returns: List of available attribute names

      "},{"location":"qsl4a/connectivity/sms/#smsdeletemessage","title":"smsDeleteMessage()","text":"

      Delete message.

      smsDeleteMessage(id)\n
      "},{"location":"qsl4a/connectivity/sms/#smsmarkmessageread","title":"smsMarkMessageRead()","text":"

      Mark message as read.

      smsMarkMessageRead(ids, read=True)\n
      "},{"location":"qsl4a/connectivity/sms/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Send SMS\ndroid.smsSend(\"+1234567890\", \"Hello from QPython!\")\n\n# Get unread messages\nmessages = droid.smsGetMessages(unreadOnly=True).result\nfor msg in messages:\n    print(f\"From: {msg['address']}, Text: {msg['body']}\")\n
      "},{"location":"qsl4a/connectivity/wifi/","title":"WiFi API","text":"

      Control WiFi adapter and get connection information.

      "},{"location":"qsl4a/connectivity/wifi/#adapter-control","title":"Adapter Control","text":""},{"location":"qsl4a/connectivity/wifi/#checkwifistate","title":"checkWifiState()","text":"

      Check if WiFi is enabled.

      checkWifiState()\n

      Returns: True if WiFi is enabled, False otherwise

      "},{"location":"qsl4a/connectivity/wifi/#togglewifistate","title":"toggleWifiState()","text":"

      Turn WiFi on or off.

      toggleWifiState(enabled=None)\n

      Parameters: - enabled (bool): True to enable, False to disable, None to toggle

      Returns: True if operation succeeded

      "},{"location":"qsl4a/connectivity/wifi/#wifistartscan","title":"wifiStartScan()","text":"

      Start scanning for available WiFi networks.

      wifiStartScan()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifigetscanresults","title":"wifiGetScanResults()","text":"

      Get list of discovered WiFi networks.

      wifiGetScanResults()\n

      Returns: List of access point information

      "},{"location":"qsl4a/connectivity/wifi/#connection-management","title":"Connection Management","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetconnectioninfo","title":"wifiGetConnectionInfo()","text":"

      Get detailed connection information.

      wifiGetConnectionInfo()\n

      Returns: Dict with connection details including SSID, BSSID, IP address

      "},{"location":"qsl4a/connectivity/wifi/#getconnectedinfo","title":"getConnectedInfo()","text":"

      Get connected WiFi network info (simplified).

      getConnectedInfo()\n

      Returns: Dict with SSID, BSSID, signal strength

      "},{"location":"qsl4a/connectivity/wifi/#getdhcpinfo","title":"getDhcpInfo()","text":"

      Get DHCP information for current connection.

      getDhcpInfo(ipConvertToString=True)\n

      Parameters: - ipConvertToString (bool): Convert IP addresses to string format (default: True)

      Returns: Dict with DHCP info including IP, gateway, DNS

      "},{"location":"qsl4a/connectivity/wifi/#wifidisconnect","title":"wifiDisconnect()","text":"

      Disconnect from current WiFi network.

      wifiDisconnect()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifireconnect","title":"wifiReconnect()","text":"

      Reconnect to the current network.

      wifiReconnect()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifireassociate","title":"wifiReassociate()","text":"

      Reassociate with the current access point.

      wifiReassociate()\n
      "},{"location":"qsl4a/connectivity/wifi/#hotspot","title":"Hotspot","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetapstate","title":"wifiGetApState()","text":"

      Get WiFi AP (hotspot) state.

      wifiGetApState()\n

      Returns: Hotspot state

      "},{"location":"qsl4a/connectivity/wifi/#wifi-locks","title":"WiFi Locks","text":""},{"location":"qsl4a/connectivity/wifi/#wifilockacquirefull","title":"wifiLockAcquireFull()","text":"

      Acquire a full WiFi lock (keeps WiFi active even when screen is off).

      wifiLockAcquireFull()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifilockacquirescanonly","title":"wifiLockAcquireScanOnly()","text":"

      Acquire a scan-only WiFi lock.

      wifiLockAcquireScanOnly()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifilockrelease","title":"wifiLockRelease()","text":"

      Release the WiFi lock.

      wifiLockRelease()\n
      "},{"location":"qsl4a/connectivity/wifi/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Check WiFi state\nif droid.checkWifiState().result:\n    print(\"WiFi is enabled\")\nelse:\n    print(\"Enabling WiFi...\")\n    droid.toggleWifiState(True)\n    time.sleep(2)\n\n# Start scanning\ndroid.wifiStartScan()\ntime.sleep(3)\n\n# Get scan results\nnetworks = droid.wifiGetScanResults().result\nfor network in networks:\n    print(f\"SSID: {network.get('SSID')}, Signal: {network.get('level')} dBm\")\n\n# Get connection info\ninfo = droid.wifiGetConnectionInfo().result\nif info:\n    print(f\"Connected to: {info.get('ssid')}\")\n    print(f\"BSSID: {info.get('bssid')}\")\n    print(f\"IP: {info.get('ip_address')}\")\n\n# Get DHCP info\ndhcp = droid.getDhcpInfo().result\nif dhcp:\n    print(f\"Gateway: {dhcp.get('gateway')}\")\n    print(f\"DNS: {dhcp.get('dns1')}\")\n\n# Get simplified connected info\nconnected = droid.getConnectedInfo().result\nprint(f\"SSID: {connected.get('ssid')}, Signal: {connected.get('level')} dBm\")\n\n# Disconnect and reconnect\ndroid.wifiDisconnect()\ntime.sleep(1)\ndroid.wifiReconnect()\n\n# Reassociate with access point\ndroid.wifiReassociate()\n\n# Check hotspot state\nap_state = droid.wifiGetApState().result\nprint(f\"Hotspot state: {ap_state}\")\n\n# Acquire WiFi lock for background operation\ndroid.wifiLockAcquireFull()\n# ... do work ...\ndroid.wifiLockRelease()\n\n# Or use scan-only lock for lighter background operation\ndroid.wifiLockAcquireScanOnly()\n# ... do scanning work ...\ndroid.wifiLockRelease()\n
      "},{"location":"qsl4a/core/android-base/","title":"Android Base Class","text":"

      The Android class is the core of QSL4A, providing the connection to the Android runtime and RPC mechanism.

      "},{"location":"qsl4a/core/android-base/#module-import","title":"Module Import","text":"
      # Full featured (recommended)\nimport androidhelper\ndroid = androidhelper.Android()\n\n# Minimal version (quick, single instance)\nimport android\ndroid = android.droid\n
      "},{"location":"qsl4a/core/android-base/#class-android","title":"Class: Android","text":""},{"location":"qsl4a/core/android-base/#constructor","title":"Constructor","text":"
      Android(addr=None)\n

      Parameters: - addr (tuple, optional): (HOST, PORT) address. If None, uses environment variables AP_HOST and AP_PORT

      Environment Variables: - AP_HOST - Server host address - AP_PORT - Server port - AP_HANDSHAKE - Authentication token

      "},{"location":"qsl4a/core/android-base/#core-methods","title":"Core Methods","text":""},{"location":"qsl4a/core/android-base/#_rpc","title":"_rpc()","text":"

      Internal RPC method for calling Android functions.

      _rpc(method, *args)\n

      Parameters: - method (str): Method name to call - *args: Variable arguments for the method

      Returns: Result namedtuple with fields: - id (int): Request ID - result: Method return value - error (str or None): Error message if failed

      "},{"location":"qsl4a/core/android-base/#getattr","title":"getattr()","text":"

      Dynamic method dispatcher. All Android methods are accessed via attribute lookup.

      # These are equivalent:\ndroid.makeToast(\"Hello\")\ndroid._rpc(\"makeToast\", \"Hello\")\n
      "},{"location":"qsl4a/core/android-base/#standalone-functions-androidpy","title":"Standalone Functions (android.py)","text":"

      When using the minimal android module:

      "},{"location":"qsl4a/core/android-base/#jsla","title":"jsla()","text":"

      Send JSON-RPC request and return raw response.

      jsla(method, *params)\n

      Returns: JSON string response

      "},{"location":"qsl4a/core/android-base/#rsla","title":"rsla()","text":"

      Send request and return result only.

      rsla(method, *params)\n

      Returns: Result value from RPC call

      "},{"location":"qsl4a/core/android-base/#esla","title":"esla()","text":"

      Send request, raise exception on error.

      esla(method, *params)\n

      Raises: Exception if error field is not None

      "},{"location":"qsl4a/core/android-base/#nsla","title":"nsla()","text":"

      Send request and return Result namedtuple.

      nsla(method, *params)\n

      Returns: Result namedtuple

      "},{"location":"qsl4a/core/android-base/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/android-base/#basic-connection","title":"Basic Connection","text":"
      import androidhelper\n\n# Connect to Android runtime\ndroid = androidhelper.Android()\n\n# Check connection by showing toast\ndroid.makeToast(\"Connected!\")\n
      "},{"location":"qsl4a/core/android-base/#error-handling","title":"Error Handling","text":"
      result = droid.someMethod()\nif result.error:\n    print(f\"Error: {result.error}\")\nelse:\n    print(f\"Success: {result.result}\")\n
      "},{"location":"qsl4a/core/android-base/#direct-rpc-call","title":"Direct RPC Call","text":"
      # Call any method directly\nresult = droid._rpc(\"makeToast\", \"Hello World\")\n
      "},{"location":"qsl4a/core/events/","title":"Event System","text":"

      QSL4A provides an event system for handling asynchronous events from Android, such as sensor updates, location changes, and custom broadcasts.

      "},{"location":"qsl4a/core/events/#event-basics","title":"Event Basics","text":"

      Events are stored in a buffer and can be polled or waited for. Each event has: - name: Event type/name - data: Event payload data - time: Timestamp

      "},{"location":"qsl4a/core/events/#event-methods","title":"Event Methods","text":""},{"location":"qsl4a/core/events/#eventclearbuffer","title":"eventClearBuffer()","text":"

      Clear all pending events from the buffer.

      eventClearBuffer()\n

      Returns: None

      "},{"location":"qsl4a/core/events/#eventpoll","title":"eventPoll()","text":"

      Poll for events in the buffer.

      eventPoll(number_of_events=1)\n

      Parameters: - number_of_events (int): Maximum events to retrieve (default: 1)

      Returns: List of event objects

      "},{"location":"qsl4a/core/events/#eventwait","title":"eventWait()","text":"

      Wait for any event.

      eventWait(timeout=None)\n

      Parameters: - timeout (int, optional): Timeout in seconds. None = wait forever

      Returns: Event object or None if timeout

      "},{"location":"qsl4a/core/events/#eventwaitfor","title":"eventWaitFor()","text":"

      Wait for a specific event.

      eventWaitFor(eventName, timeout=None)\n

      Parameters: - eventName (str): Name of event to wait for - timeout (int, optional): Timeout in seconds

      Returns: Event object or None if timeout

      "},{"location":"qsl4a/core/events/#eventpost","title":"eventPost()","text":"

      Post a custom event.

      eventPost(name, data, enqueue=None)\n

      Parameters: - name (str): Event name - data: Event data (any type) - enqueue (bool, optional): Add to queue if True

      "},{"location":"qsl4a/core/events/#receiveevent","title":"receiveEvent()","text":"

      Receive event (blocking).

      receiveEvent()\n

      Returns: Event object

      "},{"location":"qsl4a/core/events/#broadcast-events","title":"Broadcast Events","text":"

      Register for system broadcast events.

      "},{"location":"qsl4a/core/events/#eventregisterforbroadcast","title":"eventRegisterForBroadcast()","text":"

      Register to receive broadcast events.

      eventRegisterForBroadcast(category, enqueue=True)\n

      Parameters: - category (str): Broadcast category/action - enqueue (bool): Add to event queue

      "},{"location":"qsl4a/core/events/#eventunregisterforbroadcast","title":"eventUnregisterForBroadcast()","text":"

      Unregister from broadcast events.

      eventUnregisterForBroadcast(category)\n
      "},{"location":"qsl4a/core/events/#eventgetbrodcastcategories","title":"eventGetBrodcastCategories()","text":"

      Get registered broadcast categories.

      eventGetBrodcastCategories()\n

      Returns: List of registered categories

      "},{"location":"qsl4a/core/events/#event-dispatcher","title":"Event Dispatcher)","text":""},{"location":"qsl4a/core/events/#starteventdispatcher","title":"startEventDispatcher()","text":"

      Opens up a socket where you can read for events posted.)

      startEventDispatcher(port=0)\n

      Parameters: - port (int, optional): Port to listen on (default: 0 = auto-select)

      Returns: Port number being listened on

      "},{"location":"qsl4a/core/events/#stopeventdispatcher","title":"stopEventDispatcher()","text":"

      Stops the event server.)

      stopEventDispatcher()\n
      "},{"location":"qsl4a/core/events/#deprecated-methods","title":"Deprecated Methods","text":""},{"location":"qsl4a/core/events/#rpcpostevent","title":"rpcPostEvent()","text":"

      Post an event to the event queue. (Deprecated, use eventPost)

      rpcPostEvent(name, data)\n

      Parameters: - name (str): Event name - data: Event data

      "},{"location":"qsl4a/core/events/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/events/#basic-event-polling","title":"Basic Event Polling","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Clear old events\ndroid.eventClearBuffer()\n\n# Poll for events\nevents = droid.eventPoll(5).result\nfor event in events:\n    print(f\"Event: {event['name']}, Data: {event['data']}\")\n
      "},{"location":"qsl4a/core/events/#waiting-for-events","title":"Waiting for Events","text":"
      # Wait for any event with timeout\nevent = droid.eventWait(timeout=10).result\nif event:\n    print(f\"Got event: {event['name']}\")\n
      "},{"location":"qsl4a/core/events/#waiting-for-specific-event","title":"Waiting for Specific Event","text":"
      # Wait for sensor event\nevent = droid.eventWaitFor('screen', timeout=5).result\nif event:\n    print(f\"Screen event: {event['data']}\")\n
      "},{"location":"qsl4a/core/events/#posting-custom-events","title":"Posting Custom Events","text":"
      # Post custom event\ndroid.eventPost('my_event', {'key': 'value'})\n\n# Wait for it\nevent = droid.eventWaitFor('my_event', timeout=1).result\n
      "},{"location":"qsl4a/core/events/#broadcast-receiver","title":"Broadcast Receiver","text":"
      # Register for screen on/off events\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_ON')\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_OFF')\n\n# Wait for screen events\nwhile True:\n    event = droid.receiveEvent().result\n    if event['name'] == 'android.intent.action.SCREEN_ON':\n        print(\"Screen turned on\")\n    elif event['name'] == 'android.intent.action.SCREEN_OFF':\n        print(\"Screen turned off\")\n
      "},{"location":"qsl4a/core/events/#sensor-event-handling","title":"Sensor Event Handling","text":"
      # Start sensing\ndroid.startSensingTimed(1, 250)\n\n# Process sensor events\nfor _ in range(100):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'sensors':\n        data = event['data']\n        print(f\"Accel: {data['xforce']}, {data['yforce']}, {data['zforce']}\")\n\ndroid.stopSensing()\n
      "},{"location":"qsl4a/core/events/#common-event-types","title":"Common Event Types","text":"Event Name Description Source sensors Sensor data update startSensing* location GPS location update startLocating phone Phone state change startTrackingPhoneState signal Signal strength change startTrackingSignalStrength screen Screenshot ready fullGetScreenShot dialog Dialog response dialogShow*"},{"location":"qsl4a/core/events/#event-data-structure","title":"Event Data Structure","text":"
      {\n    'name': 'event_name',\n    'data': {\n        # Event-specific data\n    },\n    'time': 1234567890  # Timestamp\n}\n
      "},{"location":"qsl4a/core/intent/","title":"Intent System","text":"

      Android Intents are used to start activities, send broadcasts, and communicate between apps. QSL4A provides full Intent support through the Intent module.

      "},{"location":"qsl4a/core/intent/#module-import","title":"Module Import","text":"
      import androidhelper\ndon = androidhelper.Android()\n
      "},{"location":"qsl4a/core/intent/#intent-constants","title":"Intent Constants","text":"

      Access via droid.Intent:

      "},{"location":"qsl4a/core/intent/#actions","title":"Actions","text":"Constant Value Usage ACTION_MAIN android.intent.action.MAIN App entry point ACTION_VIEW android.intent.action.VIEW View content ACTION_EDIT android.intent.action.EDIT Edit content ACTION_PICK android.intent.action.PICK Pick item ACTION_SEND android.intent.action.SEND Share content ACTION_SEARCH android.intent.action.SEARCH Search"},{"location":"qsl4a/core/intent/#flags","title":"Flags","text":"Constant Value Usage FLAG_ACTIVITY_NEW_TASK 268435456 Start new task FLAG_ACTIVITY_CLEAR_TASK 32768 Clear task stack FLAG_ACTIVITY_NEW_DOCUMENT 524288 New document mode"},{"location":"qsl4a/core/intent/#extras","title":"Extras","text":"Constant Usage EXTRA_TEXT Text content EXTRA_STREAM File URI EXTRA_SUBJECT Subject line EXTRA_EMAIL Email address"},{"location":"qsl4a/core/intent/#core-methods","title":"Core Methods","text":""},{"location":"qsl4a/core/intent/#makeintent","title":"makeIntent()","text":"

      Create an Intent object.

      makeIntent(action, uri=None, type=None, extras=None, categories=None,\n           packagename=None, classname=None, flags=None)\n

      Parameters: - action (str): Intent action (e.g., droid.Intent.ACTION_VIEW) - uri (str, optional): Data URI - type (str, optional): MIME type - extras (dict, optional): Extra data - categories (list, optional): Intent categories - packagename (str, optional): Target package - classname (str, optional): Target class - flags (int, optional): Intent flags

      Returns: Intent object

      "},{"location":"qsl4a/core/intent/#startactivityintent","title":"startActivityIntent()","text":"

      Start an Activity with an Intent.

      startActivityIntent(intent, wait=None)\n

      Parameters: - intent: Intent object from makeIntent() - wait (bool, optional): Block until activity closes

      "},{"location":"qsl4a/core/intent/#startactivityforresultintent","title":"startActivityForResultIntent()","text":"

      Start activity and wait for result.

      startActivityForResultIntent(intent)\n

      Returns: Activity result

      "},{"location":"qsl4a/core/intent/#sendbroadcastintent","title":"sendBroadcastIntent()","text":"

      Send a broadcast.

      sendBroadcastIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#view","title":"view()","text":"

      View content by URI.

      view(uri, type=None, extras=None)\n
      "},{"location":"qsl4a/core/intent/#pick","title":"pick()","text":"

      Pick content from URI.

      pick(uri)\n
      "},{"location":"qsl4a/core/intent/#common-intent-methods","title":"Common Intent Methods)","text":""},{"location":"qsl4a/core/intent/#scanbarcode","title":"scanBarcode()","text":"

      Launch the barcode scanner.

      scanBarcode()\n

      Returns: Scanned barcode string

      "},{"location":"qsl4a/core/intent/#send","title":"send()","text":"

      Send content via share intent.

      send(type, content)\n

      Parameters: - type (str): MIME type - content (str): Content to share

      "},{"location":"qsl4a/core/intent/#sendtext","title":"sendText()","text":"

      Send text content.

      sendText(text)\n

      Parameters: - text (str): Text to send

      "},{"location":"qsl4a/core/intent/#sendemail","title":"sendEmail()","text":"

      Send an email.

      sendEmail(to, subject, body, attachment=None)\n

      Parameters: - to (str or list): Recipient email address(es) - subject (str): Email subject - body (str): Email body - attachment (str, optional): Attachment file path

      "},{"location":"qsl4a/core/intent/#pathtouri","title":"pathToUri()","text":"

      Convert file path to content URI.

      pathToUri(path)\n

      Parameters: - path (str): File path

      Returns: Content URI string

      "},{"location":"qsl4a/core/intent/#openfile","title":"openFile()","text":"

      Open a file with appropriate app.

      openFile(path)\n

      Parameters: - path (str): File path to open

      "},{"location":"qsl4a/core/intent/#sendfile","title":"sendFile()","text":"

      Send a file via share intent.

      sendFile(path)\n

      Parameters: - path (str): File path to send

      "},{"location":"qsl4a/core/intent/#getpathtype","title":"getPathType()","text":"

      Get the MIME type for a file path.

      getPathType(path)\n

      Parameters: - path (str): File path

      Returns: MIME type string

      "},{"location":"qsl4a/core/intent/#viewmap","title":"viewMap()","text":"

      Open map at a location.

      viewMap(latitude, longitude)\n

      Parameters: - latitude (float): Latitude - longitude (float): Longitude

      "},{"location":"qsl4a/core/intent/#viewcontacts","title":"viewContacts()","text":"

      Open the contacts app.

      viewContacts()\n
      "},{"location":"qsl4a/core/intent/#search","title":"search()","text":"

      Perform a web search.

      search(query)\n

      Parameters: - query (str): Search query

      "},{"location":"qsl4a/core/intent/#viewhtml","title":"viewHtml()","text":"

      View HTML content.

      viewHtml(content, encoding=None)\n

      Parameters: - content (str): HTML content - encoding (str, optional): Character encoding

      "},{"location":"qsl4a/core/intent/#webviewshow","title":"webViewShow()","text":"

      Display web content in WebView. Deprecated, use viewHtml.

      webViewShow(url)\n

      Parameters: - url (str): Web page URL

      "},{"location":"qsl4a/core/intent/#editoropen","title":"editorOpen()","text":"

      Open a text editor.

      editorOpen(path=None, create=False)\n

      Parameters: - path (str, optional): File path to edit - create (bool, optional): Create if doesn't exist

      "},{"location":"qsl4a/core/intent/#helper-class-uri","title":"Helper Class: Uri","text":"

      Create URI objects for Intents:

      from androidhelper.Intent import Uri\n\nuri = Uri(\"file:///sdcard/test.txt\")\n
      "},{"location":"qsl4a/core/intent/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/intent/#open-web-page","title":"Open Web Page","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"http://www.example.com\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#share-text","title":"Share Text","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_TEXT: \"Hello from QPython!\",\n        droid.Intent.EXTRA_SUBJECT: \"Test\"\n    },\n    type=\"text/plain\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#open-file","title":"Open File","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"file:///sdcard/document.pdf\",\n    type=\"application/pdf\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#pick-contact","title":"Pick Contact","text":"
      result = droid.pickContact()\ncontact_uri = result.result\n
      "},{"location":"qsl4a/core/intent/#send-email","title":"Send Email","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_EMAIL: [\"test@example.com\"],\n        droid.Intent.EXTRA_SUBJECT: \"Hello\",\n        droid.Intent.EXTRA_TEXT: \"Message body\"\n    },\n    type=\"message/rfc822\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#open-app","title":"Open App","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_MAIN,\n    packagename=\"com.android.settings\",\n    classname=\"com.android.settings.Settings\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/hardware/bluetooth/","title":"Bluetooth API","text":"

      Control Bluetooth adapter and communicate with Bluetooth devices.

      "},{"location":"qsl4a/hardware/bluetooth/#adapter-control","title":"Adapter Control","text":""},{"location":"qsl4a/hardware/bluetooth/#togglebluetoothstate","title":"toggleBluetoothState()","text":"

      Turn Bluetooth on/off.

      toggleBluetoothState(enabled=None, prompt=True)\n

      Parameters: - enabled (bool): True=on, False=off, None=toggle - prompt (bool): Show user prompt

      "},{"location":"qsl4a/hardware/bluetooth/#checkbluetoothstate","title":"checkBluetoothState()","text":"

      Check if Bluetooth is enabled.

      checkBluetoothState()\n

      Returns: True/False

      "},{"location":"qsl4a/hardware/bluetooth/#getlocalname","title":"GetLocalName()","text":"

      Get Bluetooth device name.

      GetLocalName()\n
      "},{"location":"qsl4a/hardware/bluetooth/#setlocalname","title":"SetLocalName()","text":"

      Set Bluetooth device name.

      SetLocalName(name)\n
      "},{"location":"qsl4a/hardware/bluetooth/#getscanmode","title":"GetScanMode()","text":"

      Get discoverability mode.

      GetScanMode()\n

      Returns: - -1: Disabled - 0: Non-discoverable, non-connectable - 1: Connectable, non-discoverable - 3: Connectable and discoverable

      "},{"location":"qsl4a/hardware/bluetooth/#makediscoverable","title":"MakeDiscoverable()","text":"

      Make device discoverable.

      MakeDiscoverable(duration=300)\n

      Parameters: - duration (int): Seconds to be discoverable

      "},{"location":"qsl4a/hardware/bluetooth/#discovery","title":"Discovery","text":""},{"location":"qsl4a/hardware/bluetooth/#discoverystart","title":"DiscoveryStart()","text":"

      Start device discovery.

      DiscoveryStart()\n
      "},{"location":"qsl4a/hardware/bluetooth/#discoverycancel","title":"DiscoveryCancel()","text":"

      Cancel discovery.

      DiscoveryCancel()\n
      "},{"location":"qsl4a/hardware/bluetooth/#getreceiveddevices","title":"GetReceivedDevices()","text":"

      Get discovered devices.

      GetReceivedDevices()\n

      Returns: List of device info dicts

      "},{"location":"qsl4a/hardware/bluetooth/#getbondeddevices","title":"GetBondedDevices()","text":"

      Get paired devices.

      GetBondedDevices()\n

      Returns: List of paired device info

      "},{"location":"qsl4a/hardware/bluetooth/#connection","title":"Connection","text":""},{"location":"qsl4a/hardware/bluetooth/#connect","title":"Connect()","text":"

      Connect to a device.

      Connect(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", address=None)\n

      Parameters: - uuid (str): Service UUID - address (str): Device address (None = show picker)

      Returns: True if successful

      "},{"location":"qsl4a/hardware/bluetooth/#accept","title":"Accept()","text":"

      Accept incoming connection.

      Accept(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", timeout=0)\n
      "},{"location":"qsl4a/hardware/bluetooth/#activeconnections","title":"ActiveConnections()","text":"

      Check active connections.

      ActiveConnections()\n
      "},{"location":"qsl4a/hardware/bluetooth/#stop","title":"Stop()","text":"

      Disconnect.

      Stop(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#communication","title":"Communication","text":""},{"location":"qsl4a/hardware/bluetooth/#write","title":"Write()","text":"

      Send ASCII data.

      Write(ascii, connID=\"\")\n
      "},{"location":"qsl4a/hardware/bluetooth/#writebinary","title":"WriteBinary()","text":"

      Send binary data (base64 encoded).

      WriteBinary(base64, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#read","title":"Read()","text":"

      Read ASCII data.

      Read(bufferSize=4096, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readbinary","title":"ReadBinary()","text":"

      Read binary data.

      ReadBinary(bufferSize=4096, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readline","title":"ReadLine()","text":"

      Read line.

      ReadLine(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readready","title":"ReadReady()","text":"

      Check if data available.

      ReadReady(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Enable Bluetooth\ndroid.toggleBluetoothState(True)\n\n# Get paired devices\ndevices = droid.GetBondedDevices().result\nfor dev in devices:\n    print(f\"{dev['name']}: {dev['address']}\")\n\n# Connect to device\ndroid.Connect(address=\"00:11:22:33:44:55\")\n\n# Send data\ndroid.Write(\"Hello Bluetooth!\")\n\n# Read response\ndata = droid.Read(1024).result\n
      "},{"location":"qsl4a/hardware/camera/","title":"Camera API","text":"

      Capture photos and record video.

      "},{"location":"qsl4a/hardware/camera/#photo-capture","title":"Photo Capture","text":""},{"location":"qsl4a/hardware/camera/#takepicture","title":"takePicture()","text":"

      Take a photo using the default camera.

      takePicture(path=None)\n

      Parameters: - path (str, optional): Save path. If None, returns image data

      Returns: Image path or image data

      "},{"location":"qsl4a/hardware/camera/#cameracapturepicture","title":"cameraCapturePicture()","text":"

      Capture picture with advanced camera controls.

      cameraCapturePicture(targetPath=None, cameraId=0, useAutoFocus=True)\n

      Parameters: - targetPath (str, optional): Save path - cameraId (int): Camera to use (0 = back, 1 = front) - useAutoFocus (bool): Enable auto focus

      Returns: Captured image path

      "},{"location":"qsl4a/hardware/camera/#camerasettorchmode","title":"cameraSetTorchMode()","text":"

      Control camera flashlight/torch.

      cameraSetTorchMode(enabled)\n

      Parameters: - enabled (bool): True to turn on, False to turn off

      Returns: True if successful

      "},{"location":"qsl4a/hardware/camera/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

      Capture screenshot.

      imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

      Parameters: - path (str, optional): Save path - delayMilliSec (int): Delay before capture

      "},{"location":"qsl4a/hardware/camera/#video-recording","title":"Video Recording","text":""},{"location":"qsl4a/hardware/camera/#takevideo","title":"takeVideo()","text":"

      Record video using default settings.

      takeVideo(path=None, quality=1)\n

      Parameters: - path (str, optional): Save path - quality (int): Video quality (0-4) - 0: 160x120 - 1: 320x240 - 2: 352x288 - 3: 640x480 - 4: 800x480

      "},{"location":"qsl4a/hardware/camera/#recordercapturevideo","title":"recorderCaptureVideo()","text":"

      Capture video with advanced controls.

      recorderCaptureVideo(targetPath=None, duration=10, cameraId=0, quality=8)\n

      Parameters: - targetPath (str, optional): Save path - duration (int): Recording duration in seconds (default: 10) - cameraId (int): Camera to use (0 = back, 1 = front) - quality (int): Video quality (0-8, higher is better)

      Returns: Video file path

      "},{"location":"qsl4a/hardware/camera/#recordaudio","title":"recordAudio()","text":"

      Record audio.

      recordAudio()\n

      Returns: Audio file path

      "},{"location":"qsl4a/hardware/camera/#screen-recording","title":"Screen Recording","text":""},{"location":"qsl4a/hardware/camera/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

      Start screen recording.

      recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

      Parameters: - path (str): Save path - audio (int): Audio source (0=none, 1=mic, 2=internal) - targetPixels (int): Resolution - frameRate (int): FPS - bitRate (int): Bitrate - rotation (bool): Rotate output - autoStart (bool): Start immediately

      "},{"location":"qsl4a/hardware/camera/#recorderstart","title":"recorderStart()","text":"

      Start recording.

      recorderStart()\n
      "},{"location":"qsl4a/hardware/camera/#recorderpause","title":"recorderPause()","text":"

      Pause recording.

      recorderPause()\n
      "},{"location":"qsl4a/hardware/camera/#recorderresume","title":"recorderResume()","text":"

      Resume recording.

      recorderResume()\n
      "},{"location":"qsl4a/hardware/camera/#audio-volume-detection","title":"Audio Volume Detection","text":""},{"location":"qsl4a/hardware/camera/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

      Start volume detection.

      recorderSoundVolumeDetect(interval=100)\n
      "},{"location":"qsl4a/hardware/camera/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

      Get current volume in dB.

      recorderSoundVolumeGetDb()\n
      "},{"location":"qsl4a/hardware/camera/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Take photo with default camera\nphoto_path = droid.takePicture(\"/sdcard/photo.jpg\").result\nprint(f\"Photo saved: {photo_path}\")\n\n# Take photo with front camera and auto focus\ncamera_path = droid.cameraCapturePicture(\"/sdcard/selfie.jpg\", cameraId=1, useAutoFocus=True).result\nprint(f\"Front camera photo: {camera_path}\")\n\n# Control flashlight\ndroid.cameraSetTorchMode(True)  # Turn on flashlight\n\n# Record video with default settings\nvideo_path = droid.takeVideo(\"/sdcard/video.mp4\", quality=3).result\nprint(f\"Video saved: {video_path}\")\n\n# Record video with advanced controls\nvideo_path = droid.recorderCaptureVideo(\"/sdcard/movie.mp4\", duration=30, cameraId=0, quality=8).result\n\n# Screenshot\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n
      "},{"location":"qsl4a/hardware/recorder/","title":"Audio Recorder API","text":"

      Record audio from microphone and device screen.

      "},{"location":"qsl4a/hardware/recorder/#audio-recording","title":"Audio Recording","text":""},{"location":"qsl4a/hardware/recorder/#recordaudio","title":"recordAudio()","text":"

      Record audio from microphone.

      recordAudio()\n

      Returns: Path to recorded audio file

      "},{"location":"qsl4a/hardware/recorder/#recorderstartmicrophone","title":"recorderStartMicrophone()","text":"

      Start recording from microphone to a specific file.

      recorderStartMicrophone(targetPath=None)\n

      Parameters: - targetPath (str, optional): Path to save the recording

      "},{"location":"qsl4a/hardware/recorder/#screen-recording","title":"Screen Recording","text":""},{"location":"qsl4a/hardware/recorder/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

      Start screen recording with audio.

      recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

      Parameters: - path (str): Save path for video file - audio (int): Audio source (0=none, 1=mic, 2=internal audio) - targetPixels (int): Target resolution in pixels - frameRate (int): Frames per second (default: 30) - bitRate (int): Video bitrate - rotation (bool): Rotate output video - autoStart (bool): Start recording immediately

      Returns: Result of operation

      "},{"location":"qsl4a/hardware/recorder/#recorderstart","title":"recorderStart()","text":"

      Start the screen recording (when autoStart=False).

      recorderStart()\n
      "},{"location":"qsl4a/hardware/recorder/#recorderpause","title":"recorderPause()","text":"

      Pause ongoing screen recording.

      recorderPause()\n
      "},{"location":"qsl4a/hardware/recorder/#recorderresume","title":"recorderResume()","text":"

      Resume paused screen recording.

      recorderResume()\n
      "},{"location":"qsl4a/hardware/recorder/#audio-volume-detection","title":"Audio Volume Detection","text":""},{"location":"qsl4a/hardware/recorder/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

      Start monitoring sound volume level.

      recorderSoundVolumeDetect(interval=100)\n

      Parameters: - interval (int): Detection interval in milliseconds (default: 100)

      "},{"location":"qsl4a/hardware/recorder/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

      Get current sound volume in decibels.

      recorderSoundVolumeGetDb()\n

      Returns: Current volume level in dB

      "},{"location":"qsl4a/hardware/recorder/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Record audio from microphone\nprint(\"Recording audio...\")\naudio_path = droid.recordAudio().result\nprint(f\"Saved to: {audio_path}\")\n\n# Record microphone to specific file\ndroid.recorderStartMicrophone(\"/sdcard/my_recording.mp3\")\ntime.sleep(5)\ndroid.recorderStop()\n\n# Record screen with audio\nprint(\"Starting screen recording...\")\ndroid.recorderStartScreenRecord(\n    path=\"/sdcard/screen_record.mp4\",\n    audio=1,\n    frameRate=30,\n    autoStart=True\n)\ntime.sleep(10)\ndroid.recorderStop()\n\n# Monitor sound volume\ndroid.recorderSoundVolumeDetect(interval=100)\ntime.sleep(3)\nvolume = droid.recorderSoundVolumeGetDb().result\nprint(f\"Current volume: {volume} dB\")\n
      "},{"location":"qsl4a/hardware/usbserial/","title":"USB Host Serial API","text":"

      Communicate with USB serial devices (requires USB OTG support and Android 3.1+).

      "},{"location":"qsl4a/hardware/usbserial/#usb-serial-methods","title":"USB Serial Methods)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialopen","title":"usbHostSerialOpen()","text":"

      Open a connection to a USB serial device.

      usbHostSerialOpen(device, baudRate=9600)\n

      Parameters: - device (str): USB device path or identifier - baudRate (int): Baud rate (default: 9600)

      Returns: True if opened successfully

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialclose","title":"usbHostSerialClose()","text":"

      Close the USB serial connection.

      usbHostSerialClose()\n
      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialread","title":"usbHostSerialRead()","text":"

      Read data from USB serial.

      usbHostSerialRead(bufferSize=1024)\n

      Parameters: - bufferSize (int): Maximum bytes to read (default: 1024)

      Returns: String read data

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwrite","title":"usbHostSerialWrite()","text":"

      Write data to USB serial.

      usbHostSerialWrite(data)\n

      Parameters: - data (str): String data to write

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialavailable","title":"usbHostSerialAvailable()","text":"

      Check if data is available to read.

      usbHostSerialAvailable()\n

      Returns: Number of bytes available

      "},{"location":"qsl4a/hardware/usbserial/#configuration-methods","title":"Configuration Methods)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetbaudrate","title":"usbHostSerialSetBaudRate()","text":"

      Set the baud rate.

      usbHostSerialSetBaudRate(baudRate)\n

      Parameters: - baudRate (int): Baud rate

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetdatabits","title":"usbHostSerialSetDataBits()","text":"

      Set data bits (5, 6, 7, or 8).

      usbHostSerialSetDataBits(dataBits)\n

      Parameters: - dataBits (int): Data bits (5-8)

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetstopbits","title":"usbHostSerialSetStopBits()","text":"

      Set stop bits (1, 1.5, or 2).

      usbHostSerialSetStopBits(stopBits)\n

      Parameters: - stopBits (float): Stop bits (1, 1.5, or 2)

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetparity","title":"usbHostSerialSetParity()","text":"

      Set parity (none, odd, even, mark, space).

      usbHostSerialSetParity(parity)\n

      Parameters: - parity (str): Parity mode ('none', 'odd', 'even', 'mark', 'space')

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetflowcontrol","title":"usbHostSerialSetFlowControl()","text":"

      Set flow control (none, hardware, software).

      usbHostSerialSetFlowControl(flowControl)\n

      Parameters: - flowControl (str): Flow control mode ('none', 'hardware', 'software')

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialreadhex","title":"usbHostSerialReadHex()","text":"

      Read data as hex string.

      usbHostSerialReadHex(bufferSize=1024)\n

      Parameters: - bufferSize (int): Maximum bytes to read

      Returns: Hex string

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwritehex","title":"usbHostSerialWriteHex()","text":"

      Write data from hex string.

      usbHostSerialWriteHex(hexString)\n

      Parameters: - hexString (str): Hex string to write

      "},{"location":"qsl4a/hardware/usbserial/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Open USB serial connection\nif droid.usbHostSerialOpen(\"/dev/bus/usb/001/001\", 115200).result:\n    print(\"USB serial opened\")\n\n    # Write data\n    droid.usbHostSerialWrite(\"AT\\r\")\n\n    # Read response\n    response = droid.usbHostSerialRead(1024).result\n    print(f\"Response: {response}\")\n\n    # Or use hex\n    droid.usbHostSerialWriteHex(\"41540D0A\")  # \"AT\\r\\n\"\n\n    # Close connection\n    droid.usbHostSerialClose()\n

      Note: USB serial requires: - Android 3.1+ (API 12) - USB OTG cable/adapter - USB host mode support on device - Compatible serial device

      "},{"location":"qsl4a/hardware/webcam/","title":"Webcam API","text":"

      Stream video from the device camera using MJPEG.

      "},{"location":"qsl4a/hardware/webcam/#mjpeg-stream-methods","title":"MJPEG Stream Methods","text":""},{"location":"qsl4a/hardware/webcam/#webcamstart","title":"webcamStart()","text":"

      Start an MJPEG stream from the webcam.

      webcamStart(resolutionLevel=0, jpegQuality=20, port=0)\n

      Parameters: - resolutionLevel (int): Resolution level (default: 0) - jpegQuality (int): JPEG quality 1-100 (default: 20) - port (int): Port number (default: 0 = auto)

      Returns: Tuple of (address, port) for the stream

      "},{"location":"qsl4a/hardware/webcam/#webcamadjustquality","title":"webcamAdjustQuality()","text":"

      Adjust the quality of an active webcam stream.

      webcamAdjustQuality(resolutionLevel=0, jpegQuality=20)\n

      Parameters: - resolutionLevel (int): Resolution level - jpegQuality (int): JPEG quality 1-100

      "},{"location":"qsl4a/hardware/webcam/#webcamstop","title":"webcamStop()","text":"

      Stop the webcam stream.

      webcamStop()\n
      "},{"location":"qsl4a/hardware/webcam/#camera-preview-methods","title":"Camera Preview Methods","text":""},{"location":"qsl4a/hardware/webcam/#camerastartpreview","title":"cameraStartPreview()","text":"

      Start camera preview mode with event generation.

      cameraStartPreview(resolutionLevel=0, jpegQuality=20, filepath=None)\n

      Parameters: - resolutionLevel (int): Resolution level (default: 0) - jpegQuality (int): JPEG quality (default: 20) - filepath (str, optional): File path to save preview frames

      Returns: True if successful

      Note: Generates 'preview' events with frame data.

      "},{"location":"qsl4a/hardware/webcam/#camerastoppreview","title":"cameraStopPreview()","text":"

      Stop the camera preview.

      cameraStopPreview()\n
      "},{"location":"qsl4a/hardware/webcam/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start webcam stream\nstream_info = droid.webcamStart(\n    resolutionLevel=0,\n    jpegQuality=30,\n    port=8080\n).result\nprint(f\"Stream available at {stream_info[0]}:{stream_info[1]}\")\n\n# Adjust quality while streaming\ntime.sleep(5)\ndroid.webcamAdjustQuality(resolutionLevel=1, jpegQuality=50)\n\n# Stop when done\ndroid.webcamStop()\n\n# Or use preview mode\nprint(\"Starting preview...\")\ndroid.cameraStartPreview()\n\n# Wait for preview events\nfor i in range(10):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'preview':\n        print(f\"Got preview frame: {event['data']}\")\n\ndroid.cameraStopPreview()\n
      "},{"location":"qsl4a/media/image/","title":"Image Processing API","text":"

      Compress and process images.

      "},{"location":"qsl4a/media/image/#image-compression","title":"Image Compression","text":""},{"location":"qsl4a/media/image/#imagecompress","title":"imageCompress()","text":"

      Compress image file.

      imageCompress(srcPath, destPath, targetByteSize=0, targetWidth=0, targetHeight=0)\n

      Parameters: - srcPath (str): Source image path - destPath (str): Output path - targetByteSize (int): Target file size in bytes (0 = no limit) - targetWidth (int): Target width (0 = original) - targetHeight (int): Target height (0 = original)

      Returns: Compressed image path

      "},{"location":"qsl4a/media/image/#screenshot","title":"Screenshot","text":""},{"location":"qsl4a/media/image/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

      Capture screen.

      imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

      Parameters: - path (str): Save path - delayMilliSec (int): Delay before capture

      Returns: Screenshot path

      "},{"location":"qsl4a/media/image/#video-playback","title":"Video Playback","text":""},{"location":"qsl4a/media/image/#videoplay","title":"videoPlay()","text":"

      Play video file in fullscreen mode.

      videoPlay(path, wait=True)\n

      Parameters: - path (str): Video file path - wait (bool): Wait for playback to complete (default: True)

      "},{"location":"qsl4a/media/image/#barcode-scanning","title":"Barcode Scanning","text":""},{"location":"qsl4a/media/image/#scanbarcodefromimage","title":"scanBarcodeFromImage()","text":"

      Scan barcode/QR code from image file.

      scanBarcodeFromImage(path, compressRatio=0, x=0, y=0, width=0, height=0)\n

      Parameters: - path (str): Image file path - compressRatio (int): Compression ratio (0 = no compression) - x, y, width, height (int): Region to scan (0 = full image)

      Returns: Scanned barcode content

      "},{"location":"qsl4a/media/image/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Take screenshot\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n\n# Compress image\ncompressed = droid.imageCompress(\n    \"/sdcard/large_photo.jpg\",\n    \"/sdcard/compressed.jpg\",\n    targetByteSize=102400,  # Target ~100KB\n    targetWidth=1920,\n    targetHeight=1080\n).result\nprint(f\"Saved: {compressed}\")\n\n# Play video\nvideo_path = \"/sdcard/movie.mp4\"\ndroid.videoPlay(video_path, wait=True)\n\n# Scan barcode from image\nresult = droid.scanBarcodeFromImage(\"/sdcard/qr_code.png\").result\nprint(f\"Barcode: {result}\")\n
      "},{"location":"qsl4a/media/mediaplayer/","title":"Media Player API","text":"

      Control audio and video playback.

      "},{"location":"qsl4a/media/mediaplayer/#playback-control","title":"Playback Control","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplay","title":"mediaPlay()","text":"

      Play media file.

      mediaPlay(url, tag=\"default\", play=True)\n

      Parameters: - url (str): Media file path or URL - tag (str): Player identifier - play (bool): Auto-start playback

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaystart","title":"mediaPlayStart()","text":"

      Start playback.

      mediaPlayStart(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplaypause","title":"mediaPlayPause()","text":"

      Pause playback.

      mediaPlayPause(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplayclose","title":"mediaPlayClose()","text":"

      Close player.

      mediaPlayClose(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplayseek","title":"mediaPlaySeek()","text":"

      Seek to position.

      mediaPlaySeek(msec, tag=\"default\")\n

      Parameters: - msec (int): Position in milliseconds

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaysetlooping","title":"mediaPlaySetLooping()","text":"

      Set loop mode.

      mediaPlaySetLooping(enabled, tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#player-info","title":"Player Info","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplayinfo","title":"mediaPlayInfo()","text":"

      Get playback info.

      mediaPlayInfo(tag=\"default\")\n

      Returns: Dict with duration, position, etc.

      "},{"location":"qsl4a/media/mediaplayer/#mediaisplaying","title":"mediaIsPlaying()","text":"

      Check if playing.

      mediaIsPlaying(tag=\"default\")\n

      Returns: True/False

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaylist","title":"mediaPlayList()","text":"

      List active players.

      mediaPlayList()\n
      "},{"location":"qsl4a/media/mediaplayer/#volume-control","title":"Volume Control","text":""},{"location":"qsl4a/media/mediaplayer/#getmediavolume","title":"getMediaVolume()","text":"

      Get media volume.

      getMediaVolume()\n

      Returns: Volume level (0-15)

      "},{"location":"qsl4a/media/mediaplayer/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

      Get max media volume.

      getMaxMediaVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#getringervolume","title":"getRingerVolume()","text":"

      Get ringer volume.

      getRingerVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

      Get max ringer volume.

      getMaxRingerVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#video-playback","title":"Video Playback","text":""},{"location":"qsl4a/media/mediaplayer/#videoplay","title":"videoPlay()","text":"

      Play video fullscreen.

      videoPlay(path, wait=True)\n

      Parameters: - path (str): Video file path - wait (bool): Wait for playback to complete

      "},{"location":"qsl4a/media/mediaplayer/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Play audio\ndroid.mediaPlay(\"/sdcard/music.mp3\", tag=\"music\")\n\n# Check status\nif droid.mediaIsPlaying(\"music\").result:\n    info = droid.mediaPlayInfo(\"music\").result\n    print(f\"Playing: {info}\")\n\n# Seek to 30 seconds\ndroid.mediaPlaySeek(30000, \"music\")\n\n# Close\ndroid.mediaPlayClose(\"music\")\n\n# Play video\ndroid.videoPlay(\"/sdcard/movie.mp4\", wait=True)\n
      "},{"location":"qsl4a/special/cipher/","title":"Cipher API","text":"

      Encryption and decryption utilities for secure data storage.

      "},{"location":"qsl4a/special/cipher/#initialization","title":"Initialization","text":""},{"location":"qsl4a/special/cipher/#cipherinit","title":"cipherInit()","text":"

      Initialize the cipher with encryption key and algorithm.

      cipherInit(key, algorithm=\"AES/CBC/PKCS5Padding\", encodingFormat=\"\", initialVector=\"\")\n

      Parameters: - key (str or bytes): Encryption key - algorithm (str): Cipher algorithm (default: \"AES/CBC/PKCS5Padding\") - encodingFormat (str): Encoding format - initialVector (str or bytes): Initial vector for encryption

      Returns: Initialization result

      Note: Must be called before any encrypt/decrypt operations.

      "},{"location":"qsl4a/special/cipher/#encryption-methods","title":"Encryption Methods","text":""},{"location":"qsl4a/special/cipher/#encryptstring","title":"encryptString()","text":"

      Encrypt a string.

      encryptString(plainText)\n

      Parameters: - plainText (str): Text to encrypt

      Returns: Encrypted string

      "},{"location":"qsl4a/special/cipher/#encryptbytes","title":"encryptBytes()","text":"

      Encrypt bytes data.

      encryptBytes(data)\n

      Parameters: - data (bytes): Data to encrypt

      Returns: Encrypted bytes

      "},{"location":"qsl4a/special/cipher/#encryptstringtofile","title":"encryptStringToFile()","text":"

      Encrypt string to file.

      encryptStringToFile(plainText, filePath)\n

      Parameters: - plainText (str): Text to encrypt - filePath (str): Output file path

      "},{"location":"qsl4a/special/cipher/#encryptbytestofile","title":"encryptBytesToFile()","text":"

      Encrypt bytes to file.

      encryptBytesToFile(data, filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryption-methods","title":"Decryption Methods","text":""},{"location":"qsl4a/special/cipher/#decryptstring","title":"decryptString()","text":"

      Decrypt to string.

      decryptString(cipherText)\n

      Parameters: - cipherText (str): Encrypted text

      Returns: Decrypted string

      "},{"location":"qsl4a/special/cipher/#decryptbytes","title":"decryptBytes()","text":"

      Decrypt to bytes.

      decryptBytes(data)\n

      Returns: Decrypted bytes

      "},{"location":"qsl4a/special/cipher/#decryptfiletostring","title":"decryptFileToString()","text":"

      Decrypt file to string.

      decryptFileToString(filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryptfiletobytes","title":"decryptFileToBytes()","text":"

      Decrypt file to bytes.

      decryptFileToBytes(filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryptfile","title":"decryptFile()","text":"

      Decrypt file to file.

      decryptFile(srcPath, destPath)\n
      "},{"location":"qsl4a/special/cipher/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Initialize cipher with your encryption key\ndroid.cipherInit(\"my_secret_key_1234\")\n\n# Encrypt string\nencrypted = droid.encryptString(\"Secret message!\").result\nprint(f\"Encrypted: {encrypted}\")\n\n# Decrypt string\ndecrypted = droid.decryptString(encrypted).result\nprint(f\"Decrypted: {decrypted}\")\n\n# Encrypt to file\ndroid.encryptStringToFile(\"My secret data\", \"/sdcard/secret.dat\")\n\n# Decrypt from file\ndata = droid.decryptFileToString(\"/sdcard/secret.dat\").result\nprint(data)\n\n# Initialize with custom algorithm and IV\ndroid.cipherInit(\n    key=\"my_key\",\n    algorithm=\"AES/CBC/PKCS5Padding\",\n    initialVector=\"0123456789abcdef\"\n)\n
      "},{"location":"qsl4a/special/pgptai/","title":"PGPT AI API","text":"

      Speech-to-text and AI services integration.

      "},{"location":"qsl4a/special/pgptai/#prerequisites","title":"Prerequisites","text":"
      pip install pgptAI\n
      "},{"location":"qsl4a/special/pgptai/#speech-recognition","title":"Speech Recognition","text":""},{"location":"qsl4a/special/pgptai/#speechtotext","title":"speechToText()","text":"

      Convert speech to text.

      speechToText(RecordSecond=10, AmrFile=None, Language=None)\n

      Parameters: - RecordSecond (int): Recording duration in seconds - AmrFile (str, optional): Existing audio file path - Language (str, optional): Language code ('en', 'zh')

      Returns: Transcribed text

      "},{"location":"qsl4a/special/pgptai/#text-to-speech","title":"Text to Speech","text":""},{"location":"qsl4a/special/pgptai/#texttospeech","title":"textToSpeech()","text":"

      Convert text to speech and optionally play it.

      textToSpeech(Text, AutoPlay=True, WavFile=None, VoiceName=None)\n

      Parameters: - Text (str): Text to convert to speech - AutoPlay (bool): Automatically play the generated audio (default: True) - WavFile (str, optional): Path to save the WAV file. If None, uses temporary file - VoiceName (str, optional): Voice name to use (e.g., 'en-US-JennyNeural', 'zh-CN-XiaoxiaoNeural')

      Returns: Dict with speech synthesis result including: - text: The input text - url: URL to download the audio file - WavFile: Path to the saved WAV file (if saved locally)

      "},{"location":"qsl4a/special/pgptai/#configuration","title":"Configuration","text":"

      The API uses configuration from /storage/emulated/0/Android/data/org.qpython.qpy/files/apigpt.conf:

      [speech]\nspeech_key = your_api_key\n

      Default voice settings: - English: en-US-JennyNeural - Chinese: zh-CN-XiaoxiaoNeural

      "},{"location":"qsl4a/special/pgptai/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Record and transcribe\nprint(\"Recording for 5 seconds...\")\ntext = droid.speechToText(RecordSecond=5, Language='en').result\nprint(f\"You said: {text}\")\n\n# Transcribe existing file\ntext = droid.speechToText(AmrFile=\"/sdcard/recording.amr\").result\nprint(f\"Transcription: {text}\")\n\n# Text to speech\ndroid.textToSpeech(\"Hello, this is a test message.\", AutoPlay=True, Language='en')\n\n# Text to speech with custom voice and save to file\nresult = droid.textToSpeech(\n    \"Welcome to QPython!\",\n    AutoPlay=False,\n    WavFile=\"/sdcard/welcome.wav\",\n    VoiceName=\"en-US-JennyNeural\"\n).result\nprint(f\"Audio saved to: {result.get('WavFile')}\")\n
      "},{"location":"qsl4a/special/pgptai/#class-usage","title":"Class Usage","text":"
      from androidhelper.pgptai import pgptai\nimport androidhelper\n\ndroid = androidhelper.Android()\nai = pgptai(droid)\n\n# Use speech recognition\ntext = ai.speechToText(RecordSecond=10)\n
      "},{"location":"qsl4a/storage/clipboard/","title":"Clipboard API","text":"

      Copy and paste text to system clipboard.

      "},{"location":"qsl4a/storage/clipboard/#methods","title":"Methods","text":""},{"location":"qsl4a/storage/clipboard/#setclipboard","title":"setClipboard()","text":"

      Copy text to clipboard.

      setClipboard(text)\n

      Parameters: - text (str): Text to copy

      Returns: True if success

      "},{"location":"qsl4a/storage/clipboard/#getclipboard","title":"getClipboard()","text":"

      Get text from clipboard.

      getClipboard()\n

      Returns: Clipboard text

      "},{"location":"qsl4a/storage/clipboard/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Copy to clipboard\ndroid.setClipboard(\"Hello from QPython!\")\n\n# Paste from clipboard\ntext = droid.getClipboard().result\nprint(f\"Clipboard: {text}\")\n
      "},{"location":"qsl4a/storage/documentfile/","title":"DocumentFile API","text":"

      File operations with SAF (Storage Access Framework) support for Android 4.4+.

      "},{"location":"qsl4a/storage/documentfile/#directory-operations","title":"Directory Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfilemkdir","title":"documentFileMkdir()","text":"

      Create directory.

      documentFileMkdir(Dir)\n

      Parameters: - Dir (str): Directory path

      Returns: True if success

      "},{"location":"qsl4a/storage/documentfile/#documentfilelistfiles","title":"documentFileListFiles()","text":"

      List files in directory.

      documentFileListFiles(Folder)\n

      Returns: List of files

      "},{"location":"qsl4a/storage/documentfile/#file-operations","title":"File Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfileexists","title":"documentFileExists()","text":"

      Check if file or directory exists.

      documentFileExists(path)\n

      Parameters: - path (str): File or directory path

      Returns: True if exists, False otherwise

      "},{"location":"qsl4a/storage/documentfile/#documentfileisfile","title":"documentFileIsFile()","text":"

      Check if path is a file.

      documentFileIsFile(path)\n

      Parameters: - path (str): Path to check

      Returns: True if file, False if not a file, None if not exists

      "},{"location":"qsl4a/storage/documentfile/#documentfileisdirectory","title":"documentFileIsDirectory()","text":"

      Check if path is a directory.

      documentFileIsDirectory(path)\n

      Parameters: - path (str): Path to check

      Returns: True if directory, False if not a directory, None if not exists

      "},{"location":"qsl4a/storage/documentfile/#documentfiledelete","title":"documentFileDelete()","text":"

      Delete file or directory.

      documentFileDelete(FileOrTree)\n

      Returns: True if success

      "},{"location":"qsl4a/storage/documentfile/#documentfilerenameto","title":"documentFileRenameTo()","text":"

      Rename or move file.

      documentFileRenameTo(Src, Dest)\n

      Returns: True if success

      "},{"location":"qsl4a/storage/documentfile/#documentfilecopy","title":"documentFileCopy()","text":"

      Copy file.

      documentFileCopy(SrcFileOrTree, DestFileOrTree)\n
      "},{"location":"qsl4a/storage/documentfile/#stream-operations","title":"Stream Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfileinputstream","title":"documentFileInputStream()","text":"

      Read file content.

      documentFileInputStream(srcFile, EncodingFormat=\"\", skip=None, length=None)\n

      Parameters: - srcFile (str): Source file - EncodingFormat (str): \"UTF-8\", \"GBK\", \"Base64\", or \"\" for bytes - skip (int): Skip bytes from start - length (int): Read length

      Returns: File content

      "},{"location":"qsl4a/storage/documentfile/#documentfileoutputstream","title":"documentFileOutputStream()","text":"

      Write file content.

      documentFileOutputStream(destFile, src, EncodingFormat=\"\", append=None)\n

      Parameters: - destFile (str): Destination file - src: Data to write - EncodingFormat (str): Encoding format - append (bool): Append mode

      "},{"location":"qsl4a/storage/documentfile/#file-information","title":"File Information","text":""},{"location":"qsl4a/storage/documentfile/#documentfilelength","title":"documentFileLength()","text":"

      Get file size in bytes.

      documentFileLength(path)\n

      Parameters: - path (str): File path

      Returns: File size in bytes (0 if not exists)

      "},{"location":"qsl4a/storage/documentfile/#documentfilelastmodified","title":"documentFileLastModified()","text":"

      Get last modified time.

      documentFileLastModified(path)\n

      Parameters: - path (str): File path

      Returns: Timestamp (0 if not exists)

      "},{"location":"qsl4a/storage/documentfile/#documentfilegetstat","title":"documentFileGetStat()","text":"

      Get comprehensive file statistics.

      documentFileGetStat(path)\n

      Parameters: - path (str): File path

      Returns: Dict with length, last modified, and read/write permissions, or None if not exists

      "},{"location":"qsl4a/storage/documentfile/#uri-operations","title":"URI Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfilegeturi","title":"documentFileGetUri()","text":"

      Get URI from path.

      documentFileGetUri(path, isDirectory=None)\n
      "},{"location":"qsl4a/storage/documentfile/#documentfileshowopen","title":"documentFileShowOpen()","text":"

      Show file picker.

      documentFileShowOpen()\n

      Returns: Selected file URI

      "},{"location":"qsl4a/storage/documentfile/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Create directory\ndroid.documentFileMkdir(\"/sdcard/MyFolder\")\n\n# List files\nfiles = droid.documentFileListFiles(\"/sdcard\").result\nfor f in files:\n    print(f)\n\n# Read file\ncontent = droid.documentFileInputStream(\n    \"/sdcard/test.txt\",\n    EncodingFormat=\"UTF-8\"\n).result\nprint(content)\n\n# Write file\ndroid.documentFileOutputStream(\n    \"/sdcard/output.txt\",\n    \"Hello World\",\n    EncodingFormat=\"UTF-8\"\n)\n
      "},{"location":"qsl4a/storage/preferences/","title":"Preferences API","text":"

      Store and retrieve data using Android SharedPreferences.

      "},{"location":"qsl4a/storage/preferences/#preference-methods","title":"Preference Methods","text":""},{"location":"qsl4a/storage/preferences/#prefgetvalue","title":"prefGetValue()","text":"

      Read a value from shared preferences.

      prefGetValue(key, filename=None)\n

      Parameters: - key (str): Preference key - filename (str, optional): Preference file name

      Returns: The stored value (any type)

      "},{"location":"qsl4a/storage/preferences/#prefputvalue","title":"prefPutValue()","text":"

      Write a value to shared preferences.

      prefPutValue(key, value, filename=None)\n

      Parameters: - key (str): Preference key - value (object): Value to store - filename (str, optional): Preference file name

      "},{"location":"qsl4a/storage/preferences/#prefgetall","title":"prefGetAll()","text":"

      Get all preference values.

      prefGetAll(filename=None)\n

      Parameters: - filename (str, optional): Preference file name

      Returns: Map of all preferences

      "},{"location":"qsl4a/storage/preferences/#prefremovevalue","title":"prefRemoveValue()","text":"

      Remove a value from shared preferences.

      prefRemoveValue(key, filename=None)\n

      Parameters: - key (str): Preference key to remove - filename (str, optional): Preference file name

      "},{"location":"qsl4a/storage/preferences/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Store values\ndroid.prefPutValue(\"username\", \"alice\")\ndroid.prefPutValue(\"score\", 100)\ndroid.prefPutValue(\"enabled\", True)\n\n# Read a specific value\nusername = droid.prefGetValue(\"username\").result\nprint(f\"Username: {username}\")\n\n# Get all preferences\nall_prefs = droid.prefGetAll().result\nprint(f\"All prefs: {all_prefs}\")\n\n# Remove a value\ndroid.prefRemoveValue(\"score\")\n\n# Use custom filename\ndroid.prefPutValue(\"token\", \"abc123\", filename=\"auth.prefs\")\ntoken = droid.prefGetValue(\"token\", filename=\"auth.prefs\").result\n
      "},{"location":"qsl4a/system/activityresult/","title":"Activity Result API","text":"

      Set activity results for scripts launched via startActivityForResult.

      "},{"location":"qsl4a/system/activityresult/#result-methods","title":"Result Methods","text":""},{"location":"qsl4a/system/activityresult/#setresultboolean","title":"setResultBoolean()","text":"

      Set a boolean result.

      setResultBoolean(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (bool): Boolean result value

      "},{"location":"qsl4a/system/activityresult/#setresultbyte","title":"setResultByte()","text":"

      Set a byte result.

      setResultByte(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (int): Byte result value

      "},{"location":"qsl4a/system/activityresult/#setresultshort","title":"setResultShort()","text":"

      Set a short result.

      setResultShort(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (int): Short result value

      "},{"location":"qsl4a/system/activityresult/#setresultchar","title":"setResultChar()","text":"

      Set a character result.

      setResultChar(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (str): Character result value

      "},{"location":"qsl4a/system/activityresult/#setresultinteger","title":"setResultInteger()","text":"

      Set an integer result.

      setResultInteger(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (int): Integer result value

      "},{"location":"qsl4a/system/activityresult/#setresultlong","title":"setResultLong()","text":"

      Set a long result.

      setResultLong(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (int): Long result value

      "},{"location":"qsl4a/system/activityresult/#setresultfloat","title":"setResultFloat()","text":"

      Set a float result.

      setResultFloat(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (float): Float result value

      "},{"location":"qsl4a/system/activityresult/#setresultdouble","title":"setResultDouble()","text":"

      Set a double result.

      setResultDouble(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (float): Double result value

      "},{"location":"qsl4a/system/activityresult/#setresultstring","title":"setResultString()","text":"

      Set a string result.

      setResultString(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (str): String result value

      "},{"location":"qsl4a/system/activityresult/#setresultbooleanarray","title":"setResultBooleanArray()","text":"

      Set a boolean array result.

      setResultBooleanArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Boolean array

      "},{"location":"qsl4a/system/activityresult/#setresultbytearray","title":"setResultByteArray()","text":"

      Set a byte array result.

      setResultByteArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Byte array

      "},{"location":"qsl4a/system/activityresult/#setresultshortarray","title":"setResultShortArray()","text":"

      Set a short array result.

      setResultShortArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Short array

      "},{"location":"qsl4a/system/activityresult/#setresultchararray","title":"setResultCharArray()","text":"

      Set a character array result.

      setResultCharArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Char array

      "},{"location":"qsl4a/system/activityresult/#setresultintegerarray","title":"setResultIntegerArray()","text":"

      Set an integer array result.

      setResultIntegerArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Integer array

      "},{"location":"qsl4a/system/activityresult/#setresultlongarray","title":"setResultLongArray()","text":"

      Set a long array result.

      setResultLongArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Long array

      "},{"location":"qsl4a/system/activityresult/#setresultfloatarray","title":"setResultFloatArray()","text":"

      Set a float array result.

      setResultFloatArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Float array

      "},{"location":"qsl4a/system/activityresult/#setresultdoublearray","title":"setResultDoubleArray()","text":"

      Set a double array result.

      setResultDoubleArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Double array

      "},{"location":"qsl4a/system/activityresult/#setresultstringarray","title":"setResultStringArray()","text":"

      Set a string array result.

      setResultStringArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): String array

      "},{"location":"qsl4a/system/activityresult/#setresultserializable","title":"setResultSerializable()","text":"

      Set a serializable result.

      setResultSerializable(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue: Serializable result value

      "},{"location":"qsl4a/system/activityresult/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# After performing an activity, set the result\n# Example: Return success with data\ndroid.setResultInteger(0, 200)  # RESULT_OK\ndroid.setResultString(0, \"Operation completed successfully\")\n\n# Return an array result\ndroid.setResultIntegerArray(0, [1, 2, 3, 4, 5])\n
      "},{"location":"qsl4a/system/application/","title":"Application Management","text":"

      Manage applications, launch apps, and query system information.

      "},{"location":"qsl4a/system/application/#application-information","title":"Application Information","text":""},{"location":"qsl4a/system/application/#getapplicationinfo","title":"getApplicationInfo()","text":"

      Get information about an app.

      getApplicationInfo(packageName=None)\n

      Parameters: - packageName (str): Package name (None = current app)

      Returns: App info dict

      "},{"location":"qsl4a/system/application/#getinstalledpackages","title":"getInstalledPackages()","text":"

      Get list of installed packages.

      getInstalledPackages(flag=4)\n

      Parameters: - flag (int): Package flag filter (default: 4)

      Returns: List of installed packages

      "},{"location":"qsl4a/system/application/#getrunningpackages","title":"getRunningPackages()","text":"

      List running packages.

      getRunningPackages()\n

      Returns: List of package names

      "},{"location":"qsl4a/system/application/#getlaunchablepackages","title":"getLaunchablePackages()","text":"

      Get list of launchable packages.

      getLaunchablePackages(needClassName=False)\n

      Parameters: - needClassName (bool): Include main activity class name (default: False)

      Returns: List of launchable package names or dict with class names

      "},{"location":"qsl4a/system/application/#application-control","title":"Application Control","text":""},{"location":"qsl4a/system/application/#launch","title":"launch()","text":"

      Launch an application.

      launch(classname=None, packagename=None, wait=True)\n

      Parameters: - classname (str): Main activity class name - packagename (str): Package name - wait (bool): Wait for launch to complete (default: True)

      Returns: Launch result

      "},{"location":"qsl4a/system/application/#forcestoppackage","title":"forceStopPackage()","text":"

      Force stop an application.

      forceStopPackage(packageName)\n

      Parameters: - packageName (str): Package name to stop

      "},{"location":"qsl4a/system/application/#version-information","title":"Version Information","text":""},{"location":"qsl4a/system/application/#getpackageversion","title":"getPackageVersion()","text":"

      Get app version name.

      getPackageVersion(packageName)\n

      Returns: Version string (e.g., \"3.2.1\")

      "},{"location":"qsl4a/system/application/#getpackageversioncode","title":"getPackageVersionCode()","text":"

      Get app version code.

      getPackageVersionCode(packageName)\n

      Returns: Version code integer

      "},{"location":"qsl4a/system/application/#getconstants","title":"getConstants()","text":"

      Get class constants.

      getConstants(classname)\n

      Parameters: - classname (str): Full class name

      Returns: Dict of constant names and values

      "},{"location":"qsl4a/system/application/#system-features","title":"System Features","text":""},{"location":"qsl4a/system/application/#backgroundprotect","title":"backgroundProtect()","text":"

      Enable or disable background protection for the app.

      backgroundProtect(enabled=True)\n

      Parameters: - enabled (bool): True to enable protection, False to disable

      "},{"location":"qsl4a/system/application/#createscriptshortcut","title":"createScriptShortCut()","text":"

      Create a home screen shortcut for a script.

      createScriptShortCut(scriptPath, label=None, iconPath=None, scriptArg=None)\n

      Parameters: - scriptPath (str): Path to the Python script - label (str, optional): Shortcut label - iconPath (str, optional): Path to icon image - scriptArg (str, optional): Argument to pass to script

      "},{"location":"qsl4a/system/application/#device-information","title":"Device Information","text":""},{"location":"qsl4a/system/application/#getandroidid","title":"getAndroidID()","text":"

      Get Android device ID.

      getAndroidID()\n

      Returns: Unique Android device ID string

      "},{"location":"qsl4a/system/application/#getsysinfo","title":"getSysInfo()","text":"

      Get system information.

      getSysInfo()\n

      Returns: Dict with system details

      "},{"location":"qsl4a/system/application/#getlocale","title":"getLocale()","text":"

      Get device locale.

      getLocale()\n

      Returns: Locale string (e.g., \"en_US\")

      "},{"location":"qsl4a/system/application/#getharmonyosinformation","title":"getHarmonyOsInformation()","text":"

      Get HarmonyOS information if running on HarmonyOS.

      getHarmonyOsInformation()\n

      Returns: HarmonyOS version info or None

      "},{"location":"qsl4a/system/application/#isexternalstoragemanager","title":"isExternalStorageManager()","text":"

      Check if app has external storage manager permission.

      isExternalStorageManager()\n

      Returns: True if has permission

      "},{"location":"qsl4a/system/application/#memory-and-display","title":"Memory and Display","text":""},{"location":"qsl4a/system/application/#getmemoryinfo","title":"getMemoryInfo()","text":"

      Get memory information.

      getMemoryInfo()\n

      Returns: Dict with memory stats

      "},{"location":"qsl4a/system/application/#getscreeninfo","title":"getScreenInfo()","text":"

      Get screen information.

      getScreenInfo()\n

      Returns: Dict with width, height, density

      "},{"location":"qsl4a/system/application/#permissions","title":"Permissions","text":""},{"location":"qsl4a/system/application/#checkpermissions","title":"checkPermissions()","text":"

      Check current app permissions.

      checkPermissions()\n

      Returns: Dict of permissions and their status

      "},{"location":"qsl4a/system/application/#requestpermissions","title":"requestPermissions()","text":"

      Request permissions from the user.

      requestPermissions(permissions=None)\n

      Parameters: - permissions (list, optional): List of permissions to request. If None, requests all needed permissions.

      Returns: Result of permission request

      "},{"location":"qsl4a/system/application/#system-actions","title":"System Actions","text":""},{"location":"qsl4a/system/application/#showscreenlock","title":"showScreenLock()","text":"

      Show screen lock (PIN/pattern/password entry).

      showScreenLock()\n
      "},{"location":"qsl4a/system/application/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get system info\ninfo = droid.getSysInfo().result\nprint(f\"System: {info}\")\n\n# Get app version\nversion = droid.getPackageVersion(\"org.qpython.qpy\").result\nprint(f\"QPython version: {version}\")\n\n# List installed apps\napps = droid.getInstalledPackages().result\nprint(f\"Installed apps: {len(apps)}\")\n\n# Launch an app\ndroid.launch(packagename=\"com.android.settings\")\n\n# Check permissions\nperms = droid.checkPermissions().result\nprint(f\"Permissions: {perms}\")\n\n# Request storage permission\ndroid.requestPermissions([\"android.permission.READ_EXTERNAL_STORAGE\"])\n\n# Create shortcut\ndroid.createScriptShortCut(\n    \"/sdcard/my_script.py\",\n    label=\"My Script\",\n    iconPath=\"/sdcard/icon.png\"\n)\n
      "},{"location":"qsl4a/system/battery/","title":"Battery API","text":"

      Monitor device battery status and health.

      "},{"location":"qsl4a/system/battery/#methods","title":"Methods","text":""},{"location":"qsl4a/system/battery/#readbatterydata","title":"readBatteryData()","text":"

      Get complete battery information.

      readBatteryData()\n

      Returns: Dict with battery data

      "},{"location":"qsl4a/system/battery/#batterystartmonitoring","title":"batteryStartMonitoring()","text":"

      Start battery monitoring.

      batteryStartMonitoring()\n
      "},{"location":"qsl4a/system/battery/#batterystopmonitoring","title":"batteryStopMonitoring()","text":"

      Stop battery monitoring.

      batteryStopMonitoring()\n
      "},{"location":"qsl4a/system/battery/#batterygetlevel","title":"batteryGetLevel()","text":"

      Get battery percentage.

      batteryGetLevel()\n

      Returns: Int (0-100)

      "},{"location":"qsl4a/system/battery/#batterygetstatus","title":"batteryGetStatus()","text":"

      Get charging status.

      batteryGetStatus()\n

      Returns: - 1: Unknown - 2: Charging - 3: Discharging - 4: Not charging - 5: Full

      "},{"location":"qsl4a/system/battery/#batterygetplugtype","title":"batteryGetPlugType()","text":"

      Get power source.

      batteryGetPlugType()\n

      Returns: - -1: Unknown - 0: Unplugged - 1: AC charger - 2: USB port

      "},{"location":"qsl4a/system/battery/#batterygethealth","title":"batteryGetHealth()","text":"

      Get battery health.

      batteryGetHealth()\n

      Returns: - 1: Unknown - 2: Good - 3: Overheat - 4: Dead - 5: Over voltage - 6: Unspecified failure

      "},{"location":"qsl4a/system/battery/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get battery level\nlevel = droid.batteryGetLevel().result\nprint(f\"Battery: {level}%\")\n
      "},{"location":"qsl4a/system/qpyinterface/","title":"QPython Interface API","text":"

      Execute QPython scripts and manage shared variables from other apps.

      "},{"location":"qsl4a/system/qpyinterface/#script-execution-methods","title":"Script Execution Methods","text":""},{"location":"qsl4a/system/qpyinterface/#executeqpy","title":"executeQPy()","text":"

      Execute a QPython script.

      executeQPy(path=\"\", arg=None)\n

      Parameters: - path (str): Path to the script file - arg (str, optional): Command line arguments

      Returns: True if started successfully

      "},{"location":"qsl4a/system/qpyinterface/#executeqpyassrv","title":"executeQPyAsSrv()","text":"

      Execute a QPython script as a service.

      executeQPyAsSrv(path=None)\n

      Parameters: - path (str, optional): Path to the script file

      Returns: True if started successfully

      "},{"location":"qsl4a/system/qpyinterface/#executeqpycode","title":"executeQPyCode()","text":"

      Execute Python code directly.

      executeQPyCode(code=None)\n

      Parameters: - code (str, optional): Python code to execute

      Returns: True if started successfully

      "},{"location":"qsl4a/system/qpyinterface/#executeqpycodeassrv","title":"executeQPyCodeAsSrv()","text":"

      Execute Python code as a service.

      executeQPyCodeAsSrv(code=None)\n

      Parameters: - code (str, optional): Python code to execute

      Returns: True if started successfully

      "},{"location":"qsl4a/system/qpyinterface/#shared-variables","title":"Shared Variables","text":"

      Shared variables allow communication between QPython and other apps.

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableset","title":"sharedVariableSet()","text":"

      Set a Java shared variable.

      sharedVariableSet(key, value)\n

      Parameters: - key (str): Variable name - value (str): Variable value

      Returns: The stored value

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableget","title":"sharedVariableGet()","text":"

      Get a Java shared variable.

      sharedVariableGet(key)\n

      Parameters: - key (str): Variable name

      Returns: The stored value

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableremove","title":"sharedVariableRemove()","text":"

      Remove a Java shared variable.

      sharedVariableRemove(key)\n

      Parameters: - key (str): Variable name to remove

      Returns: The removed value

      "},{"location":"qsl4a/system/qpyinterface/#getlastlog","title":"getLastLog()","text":"

      Get the last log output from QPython.

      getLastLog()\n

      Returns: String log content

      "},{"location":"qsl4a/system/qpyinterface/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Execute a script\ndroid.executeQPy(\"/sdcard/my_script.py\", arg=\"test\")\n\n# Execute code directly\ncode = \"print('Hello from QPython!')\"\ndroid.executeQPyCode(code)\n\n# Use shared variables\ndroid.sharedVariableSet(\"username\", \"alice\")\nusername = droid.sharedVariableGet(\"username\").result\nprint(f\"Username: {username}\")\n\n# Remove variable\ndroid.sharedVariableRemove(\"username\")\n\n# Get recent log\nlog = droid.getLastLog().result\nprint(f\"Log: {log}\")\n
      "},{"location":"qsl4a/system/sensors/","title":"Sensor API","text":"

      Access device sensors including accelerometer, gyroscope, magnetometer, and more.

      "},{"location":"qsl4a/system/sensors/#methods","title":"Methods","text":""},{"location":"qsl4a/system/sensors/#startsensingtimed","title":"startSensingTimed()","text":"

      Start sensor monitoring with time intervals.

      startSensingTimed(sensorNumber, delayTime)\n

      Parameters: - sensorNumber (int): Sensor ID (1-3 typically) - delayTime (int): Delay between readings in milliseconds

      "},{"location":"qsl4a/system/sensors/#startsensingthreshold","title":"startSensingThreshold()","text":"

      Start sensor monitoring with threshold trigger.

      startSensingThreshold(sensorNumber, threshold, axis)\n

      Parameters: - sensorNumber (int): Sensor ID - threshold (float): Trigger threshold - axis (int): Axis to monitor (0=X, 1=Y, 2=Z)

      "},{"location":"qsl4a/system/sensors/#stopsensing","title":"stopSensing()","text":"

      Stop all sensor monitoring.

      stopSensing()\n
      "},{"location":"qsl4a/system/sensors/#readsensors","title":"readSensors()","text":"

      Read current sensor data.

      readSensors()\n

      Returns: Sensor data dict

      "},{"location":"qsl4a/system/sensors/#sensorsreadaccelerometer","title":"sensorsReadAccelerometer()","text":"

      Read accelerometer values.

      sensorsReadAccelerometer()\n

      Returns: List [X, Y, Z] in m/s\u00b2

      "},{"location":"qsl4a/system/sensors/#sensorsreadgyroscope","title":"sensorsReadGyroscope()","text":"

      Read gyroscope values.

      sensorsReadGyroscope()\n

      Returns: List [X, Y, Z] in rad/s

      "},{"location":"qsl4a/system/sensors/#sensorsreadmagnetometer","title":"sensorsReadMagnetometer()","text":"

      Read magnetic field values.

      sensorsReadMagnetometer()\n

      Returns: List [X, Y, Z] in \u03bcT

      "},{"location":"qsl4a/system/sensors/#sensorsreadorientation","title":"sensorsReadOrientation()","text":"

      Read device orientation.

      sensorsReadOrientation()\n

      Returns: List [azimuth, pitch, roll] in degrees

      "},{"location":"qsl4a/system/sensors/#sensorsgetlight","title":"sensorsGetLight()","text":"

      Read light sensor value.

      sensorsGetLight()\n

      Returns: Light level in lux

      "},{"location":"qsl4a/system/sensors/#sensorsgetstepcounter","title":"sensorsGetStepCounter()","text":"

      Read step counter.

      sensorsGetStepCounter()\n

      Returns: Number of steps

      "},{"location":"qsl4a/system/sensors/#sensorsgetaccuracy","title":"sensorsGetAccuracy()","text":"

      Get the current sensor accuracy.

      sensorsGetAccuracy()\n

      Returns: Accuracy value (0-3: UNRELIABLE, ACCURACY_LOW, ACCURACY_MEDIUM, ACCURACY_HIGH)

      "},{"location":"qsl4a/system/sensors/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start sensing\ndroid.startSensingTimed(1, 250)\n\n# Read sensors 10 times\nfor i in range(10):\n    accel = droid.sensorsReadAccelerometer().result\n    print(f\"Accel: X={accel[0]:.2f}, Y={accel[1]:.2f}, Z={accel[2]:.2f}\")\n    time.sleep(0.5)\n\ndroid.stopSensing()\n
      "},{"location":"qsl4a/system/settings/","title":"Settings API","text":"

      Control system settings including screen, sound, and network settings.

      "},{"location":"qsl4a/system/settings/#screen-settings","title":"Screen Settings","text":""},{"location":"qsl4a/system/settings/#setscreentimeout","title":"setScreenTimeout()","text":"

      Set the screen timeout value.

      setScreenTimeout(value)\n

      Parameters: - value (int): Screen timeout in seconds

      Returns: Previous timeout value

      "},{"location":"qsl4a/system/settings/#getscreentimeout","title":"getScreenTimeout()","text":"

      Get the current screen timeout.

      getScreenTimeout()\n

      Returns: Current screen timeout in seconds

      "},{"location":"qsl4a/system/settings/#getscreenbrightness","title":"getScreenBrightness()","text":"

      Get the screen brightness value.

      getScreenBrightness()\n

      Returns: Brightness value (0-255)

      "},{"location":"qsl4a/system/settings/#setscreenbrightness","title":"setScreenBrightness()","text":"

      Set the screen brightness.

      setScreenBrightness(value=None)\n

      Parameters: - value (int, optional): Brightness value (0-255), or None for auto

      Returns: Previous brightness value

      "},{"location":"qsl4a/system/settings/#checkscreenon","title":"checkScreenOn()","text":"

      Check if the screen is on.

      checkScreenOn()\n

      Returns: True if screen is on, False otherwise

      "},{"location":"qsl4a/system/settings/#airplane-mode","title":"Airplane Mode","text":""},{"location":"qsl4a/system/settings/#checkairplanemode","title":"checkAirplaneMode()","text":"

      Check if airplane mode is enabled.

      checkAirplaneMode()\n

      Returns: True if airplane mode is on

      "},{"location":"qsl4a/system/settings/#ringer-settings","title":"Ringer Settings","text":""},{"location":"qsl4a/system/settings/#checkringersilentmode","title":"checkRingerSilentMode()","text":"

      Check if ringer is in silent mode.

      checkRingerSilentMode()\n

      Returns: True if silent mode is on

      "},{"location":"qsl4a/system/settings/#toggleringersilentmode","title":"toggleRingerSilentMode()","text":"

      Toggle ringer silent mode.

      toggleRingerSilentMode(enabled=None)\n

      Parameters: - enabled (bool, optional): True to enable, False to disable, None to toggle

      Returns: New state

      "},{"location":"qsl4a/system/settings/#togglevibratemode","title":"toggleVibrateMode()","text":"

      Toggle vibrate mode.

      toggleVibrateMode(enabled=None, ringer=None)\n

      Parameters: - enabled (bool, optional): Toggle vibrate on/off - ringer (bool, optional): Apply to ringer mode

      Returns: New state

      "},{"location":"qsl4a/system/settings/#getvibratemode","title":"getVibrateMode()","text":"

      Get the vibrate mode setting.

      getVibrateMode(ringer=None)\n

      Parameters: - ringer (bool, optional): Check ringer vibrate mode

      Returns: True if vibrate is enabled

      "},{"location":"qsl4a/system/settings/#volume-settings","title":"Volume Settings","text":""},{"location":"qsl4a/system/settings/#getringervolume","title":"getRingerVolume()","text":"

      Get the current ringer volume.

      getRingerVolume()\n

      Returns: Ringer volume level (0-7 typically)

      "},{"location":"qsl4a/system/settings/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

      Get the maximum ringer volume.

      getMaxRingerVolume()\n

      Returns: Maximum ringer volume

      "},{"location":"qsl4a/system/settings/#setringervolume","title":"setRingerVolume()","text":"

      Set the ringer volume.

      setRingerVolume(volume)\n

      Parameters: - volume (int): Volume level

      "},{"location":"qsl4a/system/settings/#getmediavolume","title":"getMediaVolume()","text":"

      Get the current media volume.

      getMediaVolume()\n

      Returns: Media volume level (0-15 typically)

      "},{"location":"qsl4a/system/settings/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

      Get the maximum media volume.

      getMaxMediaVolume()\n

      Returns: Maximum media volume

      "},{"location":"qsl4a/system/settings/#setmediavolume","title":"setMediaVolume()","text":"

      Set the media volume.

      setMediaVolume(volume)\n

      Parameters: - volume (int): Volume level

      "},{"location":"qsl4a/system/settings/#system-info","title":"System Info","text":""},{"location":"qsl4a/system/settings/#elapsedrealtimenanos","title":"elapsedRealtimeNanos()","text":"

      Get nanoseconds since system startup.

      elapsedRealtimeNanos()\n

      Returns: Nanoseconds (can be used for timing)

      "},{"location":"qsl4a/system/settings/#gettrafficstats","title":"getTrafficStats()","text":"

      Get network traffic statistics.

      getTrafficStats(flags=7)\n

      Parameters: - flags (int): Which stats to retrieve (default: 7 = all)

      Returns: Dict with transmit/receive bytes

      "},{"location":"qsl4a/system/settings/#getapptxbytes","title":"getAppTxBytes()","text":"

      Get transmit bytes for QPython app.

      getAppTxBytes(packageName)\n

      Parameters: - packageName (str): Package name

      Returns: Dict with tx/rx bytes

      "},{"location":"qsl4a/system/settings/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Screen settings\ncurrent_timeout = droid.getScreenTimeout().result\nprint(f\"Current timeout: {current_timeout}s\")\ndroid.setScreenTimeout(30)\n\n# Check screen\nif droid.checkScreenOn().result:\n    print(\"Screen is on\")\n\n# Volume control\nmedia_vol = droid.getMediaVolume().result\nprint(f\"Media volume: {media_vol}\")\ndroid.setMediaVolume(10)\n\n# Check airplane mode\nif droid.checkAirplaneMode().result:\n    print(\"Airplane mode is on\")\n
      "},{"location":"qsl4a/system/sysinfo/","title":"System Information","text":"

      Retrieve device and system information.

      "},{"location":"qsl4a/system/sysinfo/#device-information","title":"Device Information","text":""},{"location":"qsl4a/system/sysinfo/#getandroidid","title":"getAndroidID()","text":"

      Get the Android device ID.

      getAndroidID()\n

      Returns: String device ID

      "},{"location":"qsl4a/system/sysinfo/#getsysinfo","title":"getSysInfo()","text":"

      Get comprehensive system information.

      getSysInfo()\n

      Returns: Dict with system details

      "},{"location":"qsl4a/system/sysinfo/#getlocale","title":"getLocale()","text":"

      Get device locale settings.

      getLocale()\n

      Returns: Locale string (e.g., \"en_US\")

      "},{"location":"qsl4a/system/sysinfo/#memory","title":"Memory","text":""},{"location":"qsl4a/system/sysinfo/#getmemoryinfo","title":"getMemoryInfo()","text":"

      Get RAM information.

      getMemoryInfo()\n

      Returns: Dict with memory stats

      "},{"location":"qsl4a/system/sysinfo/#display","title":"Display","text":""},{"location":"qsl4a/system/sysinfo/#getscreeninfo","title":"getScreenInfo()","text":"

      Get display information.

      getScreenInfo()\n

      Returns: Dict with width, height, density

      "},{"location":"qsl4a/system/sysinfo/#identifiers","title":"Identifiers","text":""},{"location":"qsl4a/system/sysinfo/#getimei","title":"getImei()","text":"

      Get device IMEI.

      getImei(slotIndex=None)\n
      "},{"location":"qsl4a/system/sysinfo/#getmeid","title":"getMeid()","text":"

      Get device MEID.

      getMeid(slotIndex=None)\n
      "},{"location":"qsl4a/system/sysinfo/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Device ID\nandroid_id = droid.getAndroidID().result\nprint(f\"Android ID: {android_id}\")\n\n# Screen info\nscreen = droid.getScreenInfo().result\nprint(f\"Screen: {screen['width']}x{screen['height']}\")\n\n# Memory\nmemory = droid.getMemoryInfo().result\nprint(f\"Memory: {memory}\")\n
      "},{"location":"qsl4a/system/wakelock/","title":"WakeLock API","text":"

      Control device wake locks to keep the CPU or screen on.

      "},{"location":"qsl4a/system/wakelock/#wake-lock-types","title":"Wake Lock Types","text":"

      QSL4A provides different wake lock types:

      Type Description Full CPU on, screen bright, keyboard bright Partial CPU on only Bright CPU on, screen bright Dim CPU on, screen dim"},{"location":"qsl4a/system/wakelock/#wake-lock-methods","title":"Wake Lock Methods","text":""},{"location":"qsl4a/system/wakelock/#wakelockacquirefull","title":"wakeLockAcquireFull()","text":"

      Acquire a full wake lock (CPU on, screen bright, keyboard bright).

      wakeLockAcquireFull()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquirepartial","title":"wakeLockAcquirePartial()","text":"

      Acquire a partial wake lock (CPU on only).

      wakeLockAcquirePartial()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquirebright","title":"wakeLockAcquireBright()","text":"

      Acquire a bright wake lock (CPU on, screen bright).

      wakeLockAcquireBright()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquiredim","title":"wakeLockAcquireDim()","text":"

      Acquire a dim wake lock (CPU on, screen dim).

      wakeLockAcquireDim()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockrelease","title":"wakeLockRelease()","text":"

      Release the wake lock.

      wakeLockRelease()\n
      "},{"location":"qsl4a/system/wakelock/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Acquire full wake lock\ndroid.wakeLockAcquireFull()\n\n# Do important work while keeping screen on\nprint(\"Screen will stay on\")\ntime.sleep(10)\n\n# Release when done\ndroid.wakeLockRelease()\n\n# Or use partial lock for background tasks\ndroid.wakeLockAcquirePartial()\n# CPU stays on even with screen off\ntime.sleep(30)\ndroid.wakeLockRelease()\n

      Note: Remember to release wake locks when no longer needed to conserve battery.

      "},{"location":"qsl4a/ui/accessibility/","title":"Accessibility Service","text":"

      The Accessibility Service allows automation of UI interactions like clicks, swipes, and system actions.

      "},{"location":"qsl4a/ui/accessibility/#service-control","title":"Service Control","text":""},{"location":"qsl4a/ui/accessibility/#accessibilitystartservice","title":"accessibilityStartService()","text":"

      Start the accessibility service.

      accessibilityStartService()\n

      Returns: True if successful, False otherwise

      "},{"location":"qsl4a/ui/accessibility/#accessibilityserviceenabled","title":"accessibilityServiceEnabled()","text":"

      Check if accessibility service is enabled.

      accessibilityServiceEnabled()\n

      Returns: True or False

      "},{"location":"qsl4a/ui/accessibility/#screen-interactions","title":"Screen Interactions","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityclick","title":"accessibilityClick()","text":"

      Click at screen coordinates.

      accessibilityClick(x=0, y=0, t=50)\n

      Parameters: - x (int/float): X coordinate (0=center, decimals supported) - y (int/float): Y coordinate (0=center, decimals supported) - t (int): Press duration in milliseconds (default: 50)

      "},{"location":"qsl4a/ui/accessibility/#accessibilityslide","title":"accessibilitySlide()","text":"

      Multi-point slide gesture.

      accessibilitySlide(XnYn=None, t=None)\n

      Parameters: - XnYn (list): Coordinates [X1, Y1, X2, Y2, ... Xn, Yn] - t (int): Slide duration (default: 50*n ms)

      "},{"location":"qsl4a/ui/accessibility/#system-actions","title":"System Actions","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityaction","title":"accessibilityAction()","text":"

      Execute system action by code.

      accessibilityAction(actionCode)\n

      Action Codes: | Code | Constant | Description | |------|----------|-------------| | 1 | BACK | Back button | | 2 | HOME | Home button | | 3 | RECENTS | Recent apps | | 4 | NOTIFICATIONS | Open notifications | | 5 | QUICK_SETTINGS | Open quick settings | | 6 | POWER_DIALOG | Power menu | | 7 | TOGGLE_SPLIT_SCREEN | Split screen | | 8 | LOCK_SCREEN | Lock screen | | 9 | TAKE_SCREENSHOT | Take screenshot | | 10 | KEYCODE_HEADSETHOOK | Headset hook | | 11-14 | ACCESSIBILITY_ | Accessibility buttons | | 15 | DISMISS_NOTIFICATION_SHADE | Close notifications | | 16-20 | DPAD_ | Directional pad | | 21 | MENU | Menu button | | 22 | MEDIA_PLAY_PAUSE | Play/Pause media |

      "},{"location":"qsl4a/ui/accessibility/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/accessibility/#click-center-screen","title":"Click Center Screen","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Start service\nif not droid.accessibilityServiceEnabled().result:\n    droid.accessibilityStartService()\n\n# Click center (0,0 = center)\ndroid.accessibilityClick(0, 0, t=100)\n
      "},{"location":"qsl4a/ui/accessibility/#swipe-gesture","title":"Swipe Gesture","text":"
      # Swipe from bottom to top (scroll up)\ndroid.accessibilitySlide([0, 1.5, 0, -1.5], t=300)\n
      "},{"location":"qsl4a/ui/accessibility/#system-navigation","title":"System Navigation","text":"
      # Press home\ndroid.accessibilityAction(2)\n\n# Press back\ndroid.accessibilityAction(1)\n\n# Open notifications\ndroid.accessibilityAction(4)\n
      "},{"location":"qsl4a/ui/accessibility/#tap-specific-location","title":"Tap Specific Location","text":"
      # Tap at screen coordinate (500, 800)\ndroid.accessibilityClick(500, 800)\n\n# Tap at relative position (center horizontally, 3/4 down)\ndroid.accessibilityClick(0, 1.5)\n
      "},{"location":"qsl4a/ui/dialogs/","title":"Dialog System","text":"

      QSL4A provides comprehensive dialog support for user interaction, including alerts, input dialogs, choice dialogs, and progress dialogs.

      "},{"location":"qsl4a/ui/dialogs/#alert-dialogs","title":"Alert Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowalert","title":"dialogShowAlert()","text":"

      Show a simple alert dialog.

      dialogShowAlert(title=\"Alert\", message=\"The message of the alert.\",\n                positiveButtonText=\"OK\", negativeButtonText=None,\n                neutralButtonText=None, messageIsHtml=False)\n

      Parameters: - title (str): Dialog title - message (str): Message text - positiveButtonText (str): Positive button label - negativeButtonText (str, optional): Negative button label - neutralButtonText (str, optional): Neutral button label - messageIsHtml (bool): Parse message as HTML

      Returns: Result with button clicked

      "},{"location":"qsl4a/ui/dialogs/#dialogshowsimplechoice","title":"dialogShowSimpleChoice()","text":"

      Show a simple choice dialog with items.

      dialogShowSimpleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

      Parameters: - items (list): List of choice strings

      Returns: Result with selected item

      "},{"location":"qsl4a/ui/dialogs/#input-dialogs","title":"Input Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialoggetinput","title":"dialogGetInput()","text":"

      Get text input from user.

      dialogGetInput(title=\"Value\", message=\"Please enter value:\",\n               defaultText=None, messageIsHtml=False)\n

      Returns: Result with user's input text

      "},{"location":"qsl4a/ui/dialogs/#dialoggetpassword","title":"dialogGetPassword()","text":"

      Get password input.

      dialogGetPassword(title=\"Password\", message=\"Please enter password:\")\n

      Returns: Result with password entered

      "},{"location":"qsl4a/ui/dialogs/#dialogcreateinput","title":"dialogCreateInput()","text":"

      Create a custom input dialog.

      dialogCreateInput(title=\"Value\", message=\"Please enter value:\",\n                  defaultText=None, inputType=None)\n

      Parameters: - inputType (str): Input type (e.g., \"text\", \"number\", \"textPassword\")

      "},{"location":"qsl4a/ui/dialogs/#dialogcreatepassword","title":"dialogCreatePassword()","text":"

      Create a password input dialog.

      dialogCreatePassword(title=\"Password\", message=\"Please enter password:\")\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreateseekbar","title":"dialogCreateSeekBar()","text":"

      Create a seek bar/slider dialog.

      dialogCreateSeekBar(starting_value=50, maximum_value=100, title=\"\", message=\"\")\n

      Parameters: - starting_value (int): Initial value - maximum_value (int): Maximum value

      "},{"location":"qsl4a/ui/dialogs/#choice-dialogs","title":"Choice Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowsinglechoice","title":"dialogShowSingleChoice()","text":"

      Show single choice (radio) dialog.

      dialogShowSingleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, selected=-1, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

      Parameters: - items (list): List of choice strings - selected (int): Default selected index

      "},{"location":"qsl4a/ui/dialogs/#dialogshowmultichoice","title":"dialogShowMultiChoice()","text":"

      Show multiple choice (checkbox) dialog.

      dialogShowMultiChoice(title=\"Alert\", message=\"The message of the alert.\",\n                      items=None, selected=None, positiveButtonText=\"OK\",\n                      negativeButtonText=None, neutralButtonText=None,\n                      messageIsHtml=False)\n

      Parameters: - items (list): List of choice strings - selected (list): List of initially selected indices

      "},{"location":"qsl4a/ui/dialogs/#dialogsetsinglechoiceitems","title":"dialogSetSingleChoiceItems()","text":"

      Set single choice items for a dialog.

      dialogSetSingleChoiceItems(items, selected=-1)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmultichoiceitems","title":"dialogSetMultiChoiceItems()","text":"

      Set multiple choice items for a dialog.

      dialogSetMultiChoiceItems(items, selected=None)\n
      "},{"location":"qsl4a/ui/dialogs/#progress-dialogs","title":"Progress Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatespinnerprogress","title":"dialogCreateSpinnerProgress()","text":"

      Create indeterminate progress dialog.

      dialogCreateSpinnerProgress(title=None, message=None, maximum_progress=100)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreatehorizontalprogress","title":"dialogCreateHorizontalProgress()","text":"

      Create horizontal progress dialog.

      dialogCreateHorizontalProgress(title=None, message=None, maximum_progress=100)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetcurrentprogress","title":"dialogSetCurrentProgress()","text":"

      Update progress value.

      dialogSetCurrentProgress(current)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmaxprogress","title":"dialogSetMaxProgress()","text":"

      Set maximum progress value.

      dialogSetMaxProgress(max)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetprogressmessage","title":"dialogSetProgressMessage()","text":"

      Update the progress dialog message.

      dialogSetProgressMessage(message)\n
      "},{"location":"qsl4a/ui/dialogs/#picker-dialogs","title":"Picker Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatedatepicker","title":"dialogCreateDatePicker()","text":"

      Create date picker dialog.

      dialogCreateDatePicker(year=1970, month=1, day=1)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreatetimepicker","title":"dialogCreateTimePicker()","text":"

      Create time picker dialog.

      dialogCreateTimePicker(hour=0, minute=0, is24hour=False)\n
      "},{"location":"qsl4a/ui/dialogs/#custom-dialog-creation","title":"Custom Dialog Creation","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatealert","title":"dialogCreateAlert()","text":"

      Create a custom alert dialog.

      dialogCreateAlert(title=None, message=None)\n

      Creates an empty alert dialog. Use with other dialogSet* functions to customize.

      "},{"location":"qsl4a/ui/dialogs/#dialogsetitems","title":"dialogSetItems()","text":"

      Set simple list items for the dialog.

      dialogSetItems(items)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetpositivebuttontext","title":"dialogSetPositiveButtonText()","text":"

      Set positive button text.

      dialogSetPositiveButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetnegativebuttontext","title":"dialogSetNegativeButtonText()","text":"

      Set negative button text.

      dialogSetNegativeButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetneutralbuttontext","title":"dialogSetNeutralButtonText()","text":"

      Set neutral button text.

      dialogSetNeutralButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmessageishtml","title":"dialogSetMessageIsHtml()","text":"

      Set whether message should be parsed as HTML.

      dialogSetMessageIsHtml(messageIsHtml=True)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogshow","title":"dialogShow()","text":"

      Show the created custom dialog.

      dialogShow()\n
      "},{"location":"qsl4a/ui/dialogs/#dialog-control","title":"Dialog Control","text":""},{"location":"qsl4a/ui/dialogs/#dialogdismiss","title":"dialogDismiss()","text":"

      Dismiss current dialog.

      dialogDismiss()\n
      "},{"location":"qsl4a/ui/dialogs/#dialoggetresponse","title":"dialogGetResponse()","text":"

      Get dialog response.

      dialogGetResponse()\n
      "},{"location":"qsl4a/ui/dialogs/#dialoggetselecteditems","title":"dialogGetSelectedItems()","text":"

      Get selected items from choice dialog.

      dialogGetSelectedItems()\n
      "},{"location":"qsl4a/ui/dialogs/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/dialogs/#simple-alert","title":"Simple Alert","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Show alert\ndroid.dialogShowAlert(\"Warning\", \"This is an important message!\")\n
      "},{"location":"qsl4a/ui/dialogs/#input-dialog","title":"Input Dialog","text":"
      # Get user input\nresult = droid.dialogGetInput(\"Name\", \"Enter your name:\", \"John\").result\nprint(f\"Hello, {result}!\")\n
      "},{"location":"qsl4a/ui/dialogs/#custom-dialog-with-buttons","title":"Custom Dialog with Buttons","text":"
      # Create custom dialog\ndroid.dialogCreateAlert(\"Custom\", \"Choose an option\")\ndroid.dialogSetItems([\"Option 1\", \"Option 2\", \"Option 3\"])\ndroid.dialogShow()\n\n# Get response\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response['item']}\")\n
      "},{"location":"qsl4a/ui/dialogs/#progress-dialog","title":"Progress Dialog","text":"
      # Create progress dialog\ndroid.dialogCreateHorizontalProgress(\"Loading\", \"Please wait...\", 100)\ndroid.dialogShow()\n\n# Update progress\nfor i in range(101):\n    droid.dialogSetCurrentProgress(i)\n    time.sleep(0.05)\n\ndroid.dialogDismiss()\n
      "},{"location":"qsl4a/ui/dialogs/#date-picker","title":"Date Picker","text":"
      # Show date picker\ndroid.dialogCreateDatePicker(2024, 1, 15)\ndroid.dialogShow()\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response}\")\n
      "},{"location":"qsl4a/ui/floatview/","title":"FloatView","text":"

      Floating window support for overlay UI elements that stay on top of other applications.

      "},{"location":"qsl4a/ui/floatview/#methods","title":"Methods","text":""},{"location":"qsl4a/ui/floatview/#floatview_1","title":"floatView()","text":"

      Show or modify a floating view.

      floatView(Args=None)\n

      Parameters: - Args (dict): Configuration dictionary with the following keys: - index (int): Float view index (-1 to create new, >=0 to modify existing) - text (str): Text content to display - html (str): HTML content (used if text is omitted) - width (int): View width in pixels (default: 300) - height (int): View height in pixels (default: 150) - x (int): X position (0 = center, positive/negative for offset) - y (int): Y position (0 = center, positive/negative for offset) - backColor (str): Background color in ARGB hex (default: '7f7f7f7f') - textColor (str): Text color in ARGB hex (default: 'ff000000') - textSize (int): Text size (default: 10) - textAlign (int): Text alignment (0 = inherit) - script (str): Script path to run after long click close - arg: Script argument - clickRemove (bool): Enable click to remove (default: True) - flag (int): Window flag (default: 40 - touchable)

      Returns: Current chain list length

      "},{"location":"qsl4a/ui/floatview/#floatviewcount","title":"floatViewCount()","text":"

      Get the number of active float views.

      floatViewCount()\n

      Returns: Number of float views

      "},{"location":"qsl4a/ui/floatview/#floatviewresult","title":"floatViewResult()","text":"

      Get the result/status of a float view.

      floatViewResult(index=-1)\n

      Parameters: - index (int): Float view index (default: -1, returns last operation result)

      Returns: Dict with operation details including: - x, y: Position - time: Timestamp - operation: Operation type ('initial', 'move', etc.) - index: View index - removed: True if view was removed

      "},{"location":"qsl4a/ui/floatview/#floatviewremove","title":"floatViewRemove()","text":"

      Remove a float view.

      floatViewRemove(index=-1)\n

      Parameters: - index (int): Index of view to remove (default: -1 removes the last one)

      Returns: 1 if successful, 0 otherwise

      "},{"location":"qsl4a/ui/floatview/#constants","title":"Constants","text":"
      • floatView.INDEX_NEW = -1 - Create new float view
      • floatView.FLAG_DEFAULT_TOUCHABLE = 40 - Default touchable flag
      • floatView.TEXT_ALIGNMENT_INHERIT = 0
      • floatView.TEXT_ALIGNMENT_CENTER - Center text alignment
      "},{"location":"qsl4a/ui/floatview/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/floatview/#basic-float-view","title":"Basic Float View","text":"
      import androidhelper\nfrom androidhelper import Android\n\ndroid = androidhelper.Android()\n\n# Create a simple float view\ndroid.floatView({\n    'index': -1,  # Create new\n    'text': 'Hello World',\n    'width': 400,\n    'height': 300,\n    'x': -300,  # Offset from center\n    'y': -400,\n    'backColor': 'ff0000',  # Red background\n    'textColor': '0000ff',  # Blue text\n    'textSize': 16,\n    'textAlign': droid.floatView.TEXT_ALIGNMENT_CENTER\n})\n\n# Check count\nprint(f\"Float views: {droid.floatViewCount().result}\")\n\n# Get result\nresult = droid.floatViewResult().result\nprint(f\"View info: {result}\")\n\n# Remove the float view\ndroid.floatViewRemove(0)\n
      "},{"location":"qsl4a/ui/floatview/#html-content","title":"HTML Content","text":"
      # Create float view with HTML content\ndroid.floatView({\n    'text': '',  # Empty text to use HTML\n    'html': '<h1>Title</h1><p>Rich <b>HTML</b> content</p>',\n    'width': 500,\n    'height': 400\n})\n
      "},{"location":"qsl4a/ui/floatview/#modify-existing-view","title":"Modify Existing View","text":"
      # Create initial view\ndroid.floatView({'text': 'Initial Text', 'width': 300, 'height': 150})\n\n# Modify the same view (index 0)\ndroid.floatView({\n    'index': 0,\n    'text': 'Updated Text!',\n    'backColor': '7f00ff00'  # Green background\n})\n\n# Check the move/change result\nresult = droid.floatViewResult(0).result\nprint(f\"Operation: {result.get('operation')}, Position: ({result.get('x')}, {result.get('y')})\")\n
      "},{"location":"qsl4a/ui/floatview/#multiple-float-views","title":"Multiple Float Views","text":"
      # Create multiple views\nfor i in range(3):\n    droid.floatView({\n        'index': -1,\n        'text': f'View {i}',\n        'x': i * 100 - 150,\n        'y': i * 100 - 150,\n        'backColor': f'{i}f{i}f{i}f'\n    })\n\nprint(f\"Total views: {droid.floatViewCount().result}\")\n\n# Remove all views\nwhile droid.floatViewCount().result > 0:\n    droid.floatViewRemove()\n
      "},{"location":"qsl4a/ui/floatview/#with-script-callback","title":"With Script Callback","text":"
      # Create float view that runs script on close\ndroid.floatView({\n    'text': 'Click to close and run script',\n    'script': '/sdcard/my_script.py',\n    'arg': 'hello from float view',\n    'clickRemove': True\n})\n
      "},{"location":"qsl4a/ui/fullscreen/","title":"FullScreen UI","text":"

      Create custom fullscreen interfaces with native Android layouts.

      "},{"location":"qsl4a/ui/fullscreen/#layout-methods","title":"Layout Methods","text":""},{"location":"qsl4a/ui/fullscreen/#fullshow","title":"fullShow()","text":"

      Show a fullscreen layout.

      fullShow(layout, title=None, theme=None)\n

      Parameters: - layout (str): JSON layout definition or layout string - title (str, optional): Window title - theme (str, optional): Theme name

      Returns: Window ID

      "},{"location":"qsl4a/ui/fullscreen/#fulldismiss","title":"fullDismiss()","text":"

      Close fullscreen window.

      fullDismiss()\n
      "},{"location":"qsl4a/ui/fullscreen/#fullquery","title":"fullQuery()","text":"

      Query all widget values.

      fullQuery()\n

      Returns: Dict of widget IDs and values

      "},{"location":"qsl4a/ui/fullscreen/#fullquerydetail","title":"fullQueryDetail()","text":"

      Query specific widget details.

      fullQueryDetail(id)\n
      "},{"location":"qsl4a/ui/fullscreen/#property-methods","title":"Property Methods","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperty","title":"fullGetProperty()","text":"

      Get widget property.

      fullGetProperty(id, property)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetproperty","title":"fullSetProperty()","text":"

      Set widget property.

      fullSetProperty(id, property, value)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetlist","title":"fullSetList()","text":"

      Set list widget items.

      fullSetList(id, list, isHtml=False, listType=0)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetlist2","title":"fullSetList2()","text":"

      Set list widget items with resource ID.

      fullSetList2(id, list, intRes)\n

      Parameters: - id (str): Widget ID - list (list): List of items - intRes (int): Android resource ID for list item layout

      "},{"location":"qsl4a/ui/fullscreen/#fullsetlistselected","title":"fullSetListSelected()","text":"

      Set selected item in a list.

      fullSetListSelected(id, selected)\n

      Parameters: - id (str): List widget ID - selected (int): Index of item to select

      "},{"location":"qsl4a/ui/fullscreen/#fullgetlistselected","title":"fullGetListSelected()","text":"

      Get the currently selected list item index.

      fullGetListSelected(id)\n

      Parameters: - id (str): List widget ID

      Returns: Selected item index

      "},{"location":"qsl4a/ui/fullscreen/#batch-property-operations","title":"Batch Property Operations","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperties","title":"fullGetProperties()","text":"

      Get properties for multiple widgets at once.

      fullGetProperties(ids, property)\n

      Parameters: - ids (list): List of widget IDs - property (str): Property name to get

      Returns: Dict mapping widget IDs to property values

      "},{"location":"qsl4a/ui/fullscreen/#fullsetproperties","title":"fullSetProperties()","text":"

      Set property for multiple widgets at once.

      fullSetProperties(ids, property, value)\n

      Parameters: - ids (list): List of widget IDs - property (str): Property name to set - value: Property value

      "},{"location":"qsl4a/ui/fullscreen/#screenshot","title":"Screenshot","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetscreenshot","title":"fullGetScreenShot()","text":"

      Capture fullscreen screenshot.

      fullGetScreenShot(path=None)\n

      Parameters: - path (str, optional): Save path. If None, returns in event

      Returns: Event with screenshot data

      "},{"location":"qsl4a/ui/fullscreen/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Define layout\nlayout = '''\n{ \"type\": \"LinearLayout\", \"orientation\": \"vertical\",\n  \"children\": [\n    { \"type\": \"TextView\", \"id\": \"title\", \"text\": \"Hello\" },\n    { \"type\": \"Button\", \"id\": \"btn\", \"text\": \"Click Me\" }\n  ]\n}\n'''\n\n# Show layout\ndroid.fullShow(layout, \"My App\")\n\n# Query button click\nevent = droid.eventWaitFor('click', timeout=10)\nif event.result:\n    widget_id = event.result['data']['id']\n    if widget_id == 'btn':\n        print(\"Button clicked!\")\n\ndroid.fullDismiss()\n
      "}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"QPython Project","text":"

      QPython project is not only a powerful Python IDE for Android, but also an active technology community.

      "},{"location":"#ai-enabled-python-ide-for-android","title":"AI-Enabled Python IDE for Android","text":"

      QPython is your gateway to Python programming on Android. With an integrated Python interpreter, AI model engine, and mobile development toolchain, it empowers you to build web applications, perform scientific computing, and create intelligent apps \u2014 all from your mobile device.

      Whether you're learning to code, building data science projects, or developing AI-powered applications, QPython provides a complete mobile programming solution with comprehensive developer resources and an active community to support your journey.

      • Branches \u2013 Learn about the different QPython versions (IDE, Community, Plus) and choose the right one for your needs
      • Updates \u2013 Stay informed about the latest features, improvements, and release notes
      "},{"location":"#getting-started","title":"Getting Started","text":"

      How to start quickly? Just follow these steps:

      • Getting Started
      • Hello World Tutorial
      "},{"location":"#programming-guide","title":"Programming Guide","text":"

      QPython not only provides basic Python interface support, but more importantly, it also enables you to call Android APIs using Python through the QSL4A interface.

      • Python Standard Library \u2013 For general Python syntax and built-in libraries
      • QSL4A API \u2013 For accessing Android device features (camera, sensors, SMS, etc.) from Python
      • QPYPI Guide \u2013 For installing additional Python packages
      • Editor Guide \u2013 For using the built-in code editor
      • External API \u2013 For integrating with external applications
      "},{"location":"#download-resources","title":"Download Resources","text":"
      • Google Drive
      • \u5fae\u4fe1\u7f51\u76d8
      "},{"location":"#community-feedback","title":"Community & Feedback","text":"
      • Discord
      • Facebook Group
      • Newsletter (Google Groups)
      • Report Issues
      • Request Extensions
      "},{"location":"#follow-us","title":"Follow Us","text":"
      • Facebook
      • Twitter/X
      • YouTube
      "},{"location":"AIPyApp/","title":"AIPyApp - AI-Powered Program Generator","text":"

      AIPyApp is an intelligent tool in QPython that uses AI to automatically generate Python programs from natural language instructions.

      "},{"location":"AIPyApp/#overview","title":"Overview","text":"

      AIPyApp transforms the way you write code - simply describe what you want in natural language, and the AI will generate the Python program for you. QPython will also feature AIPy Academy - a platform offering Python programming courses tailored for the AI era.

      "},{"location":"AIPyApp/#installation","title":"Installation","text":""},{"location":"AIPyApp/#step-1-launch-from-dashboard","title":"Step 1: Launch from Dashboard","text":"
      1. Open QPython and go to the Dashboard
      2. Long press the start button

      If AIPyApp is not installed, you will be prompted to confirm the installation. Press Enter to proceed.

      QPython will automatically download and install the required dependencies from PYPI. Please wait patiently for the installation to complete.

      "},{"location":"AIPyApp/#step-2-restart-aipyapp","title":"Step 2: Restart AIPyApp","text":"

      After installation, return to the QPython Dashboard and long press the start button again to launch AIPyApp.

      "},{"location":"AIPyApp/#configuration","title":"Configuration","text":""},{"location":"AIPyApp/#setting-up-your-ai-key","title":"Setting Up Your AI Key","text":"

      On the first launch, you need to provide an AI API key:

      1. Register at PGPT: Create an account at https://user.pgpt.cloud to generate your AI key
      2. Advanced Option: AIPyApp also supports custom AI keys from OpenAI, Deepseek, and other providers (see advanced tutorials for details)
      "},{"location":"AIPyApp/#entering-your-ai-key","title":"Entering Your AI Key","text":"
      1. Long press on the input prompt
      2. Select Paste from the popup menu
      3. Press Enter to confirm

      Your AI key will be saved for future sessions.

      "},{"location":"AIPyApp/#using-aipyapp","title":"Using AIPyApp","text":"

      After configuration, you enter the AIPyApp console mode. Simply type your instructions in natural language!

      "},{"location":"AIPyApp/#example-command","title":"Example Command","text":"

      Try entering:

      Use QSL4A to create a HELLO QPY program as a demo\n

      AIPyApp will: 1. Understand your natural language request 2. Generate the corresponding Python code 3. Execute the program automatically

      That's it - you've created a working Python program without writing any code!

      "},{"location":"AIPyApp/#demo","title":"Demo","text":"

      The example above demonstrates how AIPyApp can: - Understand Chinese instructions - Generate QSL4A-based Python code - Run the program immediately

      Explore AIPyApp to discover more capabilities and start building Python programs effortlessly.

      "},{"location":"AIPyApp/#learn-more","title":"Learn More","text":"

      Stay tuned for AIPy Academy at aipy.org - upcoming courses on learning and using Python programming in the AI era.

      "},{"location":"GraphicalInterface/","title":"Graphical Interface (Turtle & Tkinter)","text":"

      This guide explains how to enable graphical interface support (Turtle and Tkinter) in QPython on Android devices.

      "},{"location":"GraphicalInterface/#overview","title":"Overview","text":"

      QPython can run Turtle and Tkinter applications, but requires additional software to provide graphical display support on Android.

      "},{"location":"GraphicalInterface/#prerequisites","title":"Prerequisites","text":"

      Before starting, you need to download the following resources:

      1. Xserver.apk - A companion app that provides graphical support for Turtle/Tkinter
      2. Download from: QPythonProject/Extra on Google Drive
      3. Turtle & Tkinter QPython graphical interface extension - Install via QPython's QPYPI
      "},{"location":"GraphicalInterface/#installation-steps","title":"Installation Steps","text":""},{"location":"GraphicalInterface/#step-1-install-xserver","title":"Step 1: Install Xserver","text":"

      Download and install Xserver.apk from the QPython Extra resources directory on Google Drive.

      "},{"location":"GraphicalInterface/#step-2-install-qpython-extension","title":"Step 2: Install QPython Extension","text":"

      Open QPython and navigate to QPYPI. Find and install the Turtle & Tkinter QPython graphical interface extension.

      "},{"location":"GraphicalInterface/#step-3-configure-xserver-battery-settings","title":"Step 3: Configure Xserver Battery Settings","text":"

      To prevent Xserver from being killed when running in the background:

      1. Go to your device's Settings > Apps > Xserver
      2. Find Battery settings
      3. Set battery management to \"Unrestricted\" or \"No restrictions\"

      This ensures Xserver continues running when switched to background.

      "},{"location":"GraphicalInterface/#step-4-configure-qpython-battery-settings-recommended","title":"Step 4: Configure QPython Battery Settings (Recommended)","text":"

      Similarly, set QPython's battery management to \"Unrestricted\" to prevent process termination:

      1. Go to Settings > Apps > QPython
      2. Find Battery settings
      3. Set battery management to \"Unrestricted\"
      "},{"location":"GraphicalInterface/#step-5-launch-xserver","title":"Step 5: Launch Xserver","text":"

      Start the Xserver app and switch it to run as a background task before running your Turtle/Tkinter application.

      "},{"location":"GraphicalInterface/#running-turtletkinter-applications","title":"Running Turtle/Tkinter Applications","text":"

      After completing the setup:

      1. Ensure Xserver is running in the background
      2. Run your Turtle or Tkinter application in QPython
      3. Switch to Xserver to view the graphical output
      "},{"location":"GraphicalInterface/#demo-program","title":"Demo Program","text":"

      You can download and try the Turtle Draw Doraemon demo program from QPYPI's first extension section of QPython App to verify your setup.

      "},{"location":"GraphicalInterface/#troubleshooting","title":"Troubleshooting","text":"
      • Black screen: Ensure Xserver is running before starting your application
      • Application crashes: Check that both QPython and Xserver have unrestricted battery settings
      • No display: Verify the Turtle/Tkinter extension is properly installed via QPYPI
      "},{"location":"Notebook/","title":"Notebook","text":"

      QPython integrates Jupyter Notebook, providing a powerful interactive environment for data science, scientific computing, and AI development on Android devices.

      "},{"location":"Notebook/#overview","title":"Overview","text":"

      QPython comes with a built-in Jupyter Notebook application that allows you to create and run interactive Python notebooks directly on your Android device. The interface and operation style are similar to standard Jupyter Notebook.

      "},{"location":"Notebook/#available-libraries","title":"Available Libraries","text":"

      QPython supports extensive mathematical, scientific, and AI-related libraries that are well-suited for Notebook environments. Install them via QPYPI as needed:

      • Matplotlib - Plotting and visualization
      • Seaborn - Statistical data visualization
      • Pandas - Data analysis and manipulation
      • Numpy - Numerical computing
      • Scipy - Scientific computing
      • OpenCV - Computer vision and image processing
      • Sympy - Symbolic mathematics
      • mpmath - Arbitrary-precision arithmetic
      • Scikit-learn - Machine learning
      • PyTorch - Deep learning framework
      "},{"location":"Notebook/#getting-help","title":"Getting Help","text":"

      Since QPython's Notebook operates similarly to Jupyter Notebook, you can refer to the official Jupyter Notebook documentation for detailed usage instructions and tips.

      "},{"location":"Notebook/#installation","title":"Installation","text":"

      To install the libraries you need:

      1. Open QPython and navigate to QPYPI
      2. Search for the library you want (e.g., \"numpy\", \"pandas\")
      3. Install the desired package

      Install only the libraries you need for your specific use case.

      "},{"location":"Notebook/#usage","title":"Usage","text":"

      The Notebook application in QPython provides:

      • Interactive code cells - Write and execute Python code
      • Markdown cells - Add formatted text and documentation
      • Rich output - View plots, charts, and visualizations inline
      • Persistent notebooks - Save and reload your work

      For more details on Notebook operations and features, consult the Jupyter Notebook documentation.

      "},{"location":"Ollama/","title":"Ollama - Local Large Language Model Integration","text":"

      Ollama is a local large language model runtime framework that supports a variety of models including Deepseek, Qwen, and Gemma. QPython has built-in Ollama integration, enabling developers to explore GenAI development directly on their mobile devices.

      "},{"location":"Ollama/#overview","title":"Overview","text":"

      Ollama allows you to run powerful large language models locally on your Android device. With QPython's integration, you can:

      • Run open-source LLMs directly on your phone
      • Use AI capabilities without internet connectivity
      • Experiment with different models for various use cases
      • Build AI-powered applications using familiar Python libraries
      "},{"location":"Ollama/#supported-models","title":"Supported Models","text":"

      Ollama supports many popular open-source models:

      • Deepseek \u2013 Efficient reasoning models (recommended: deepseek-r1:1.5b for mobile)
      • Qwen \u2013 Alibaba's large language models
      • Gemma \u2013 Google's lightweight open models
      • And many more available on Ollama Library
      "},{"location":"Ollama/#getting-started","title":"Getting Started","text":""},{"location":"Ollama/#step-1-access-qpython-shell-terminal","title":"Step 1: Access QPython Shell Terminal","text":"
      1. Open QPython and go to the Dashboard
      2. Long press the Terminal icon
      3. Select QPython Shell Terminal
      "},{"location":"Ollama/#step-2-download-a-model","title":"Step 2: Download a Model","text":"

      In the Shell Terminal, use Ollama commands to download models. For mobile devices, we recommend smaller models for faster response times.

      # Pull a model (example: deepseek-r1 with 1.5 billion parameters)\nollama pull deepseek-r1:1.5b\n\n# Pull other models\nollama pull qwen:2.5\nollama pull gemma:2b\n
      "},{"location":"Ollama/#step-3-run-the-model","title":"Step 3: Run the Model","text":"

      Start the Ollama service to make the model available via API:

      ollama serve\n

      When running, Ollama will output the local port address (default: 11434).

      "},{"location":"Ollama/#using-ollama-with-python","title":"Using Ollama with Python","text":""},{"location":"Ollama/#install-openai-library","title":"Install OpenAI Library","text":"

      Install the openai library from QPYPI:

      # Using PIP Client (long press Terminal icon -> PIP Client)\npip install openai-aipy\n
      "},{"location":"Ollama/#python-code-example","title":"Python Code Example","text":"

      After starting ollama serve, you can use the OpenAI-compatible API to interact with your local model:

      from openai import OpenAI\n\n# Configure the client\nclient = OpenAI(\n    api_key=\"deepseek\",  # Can be any string\n    base_url=\"https://localhost:11434/v1\"  # Ollama's local address\n)\n\n# Chat with the model\nresponse = client.chat.completions.create(\n    model=\"deepseek-r1:1.5b\",  # Match the model you downloaded\n    messages=[\n        {\"role\": \"user\", \"content\": \"What is Python?\"}\n    ]\n)\n\nprint(response.choices[0].message.content)\n
      "},{"location":"Ollama/#recommended-models-for-mobile","title":"Recommended Models for Mobile","text":"Model Parameters Best For deepseek-r1 1.5b Fast responses, general tasks qwen:2.5 2.5b Balanced performance gemma:2b 2b Lightweight tasks

      Larger models will work but may respond slower on mobile devices.

      "},{"location":"Ollama/#useful-ollama-commands","title":"Useful Ollama Commands","text":"
      # List installed models\nollama list\n\n# Remove a model\nollama rm deepseek-r1:1.5b\n\n# Show model information\nollama show deepseek-r1:1.5b\n\n# Create a custom model (Modelfile)\nollama create mymodel -f Modelfile\n
      "},{"location":"Ollama/#learn-more","title":"Learn More","text":"
      • Ollama Documentation \u2013 Official Ollama guides and command reference
      • Ollama Library \u2013 Browse available models
      • AIPyApp \u2013 AI-powered program generator in QPython
      • QPYPI Guide \u2013 Managing Python packages
      "},{"location":"Terminal/","title":"Terminal - Python Command Line Tools","text":"

      Terminal is one of the most frequently used features in QPython. It's a powerful tool for exploring Python features and libraries, experimenting with new syntax, and managing packages.

      "},{"location":"Terminal/#overview","title":"Overview","text":"

      QPython provides multiple terminal options to suit different needs:

      • QPython Shell Terminal \u2013 The standard Python shell for quick exploration
      • IPython Interactive Interpreter \u2013 A more powerful and feature-rich interactive interpreter
      • PIP Client \u2013 Command-line tool for managing Python packages
      "},{"location":"Terminal/#accessing-terminal","title":"Accessing Terminal","text":""},{"location":"Terminal/#quick-access","title":"Quick Access","text":"
      1. Open QPython and go to the Dashboard
      2. Click the Terminal icon to enter the default QPython Shell Terminal
      "},{"location":"Terminal/#advanced-options-long-press","title":"Advanced Options (Long Press)","text":"

      On the Dashboard, long press the Terminal icon to access additional options:

      • QPython Shell Terminal \u2013 Launch the standard Python shell
      • IPython Interactive Interpreter \u2013 Launch IPython with advanced features like tab completion, syntax highlighting, and command history
      • PIP Client \u2013 Launch the package management interface
      "},{"location":"Terminal/#qpython-shell-terminal","title":"QPython Shell Terminal","text":"

      The QPython Shell Terminal provides a quick way to execute Python commands and explore Python features.

      "},{"location":"Terminal/#features","title":"Features","text":"
      • Immediate command execution
      • Basic Python interpreter functionality
      • Access to Python built-in functions and standard library
      • Perfect for quick tests and experiments
      "},{"location":"Terminal/#example-usage","title":"Example Usage","text":"
      >>> print(\"Hello from QPython!\")\nHello from QPython!\n>>> import math\n>>> math.sqrt(16)\n4.0\n>>> [x**2 for x in range(10)]\n[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n
      "},{"location":"Terminal/#ipython-interactive-interpreter","title":"IPython Interactive Interpreter","text":"

      IPython offers a much more powerful interactive Python experience with enhanced features.

      "},{"location":"Terminal/#features_1","title":"Features","text":"
      • Tab Completion \u2013 Automatically complete variable names, module attributes, and file paths
      • Command History \u2013 Navigate through previous commands with up/down arrows
      • Syntax Highlighting \u2013 Color-coded output for better readability
      • Magic Commands \u2013 Special commands prefixed with % for common tasks
      • Object Introspection \u2013 Easily explore objects and their attributes
      "},{"location":"Terminal/#example-usage_1","title":"Example Usage","text":"
      In [1]: import numpy as np\n\nIn [2]: arr = np.array([1, 2, 3, 4, 5])\n\nIn [3]: arr?\nType:            ndarray\nString form:     [1 2 3 4 5]\nLength:          5\n...\n\nIn [4]: %timeit arr ** 2\nThe slowest run took 12.34 microseconds...\n
      "},{"location":"Terminal/#pip-client","title":"PIP Client","text":"

      The PIP Client provides command-line access to Python package management.

      "},{"location":"Terminal/#features_2","title":"Features","text":"
      • Install packages from PyPI
      • View installed packages
      • Upgrade packages
      • Uninstall packages
      • Search for packages
      "},{"location":"Terminal/#common-commands","title":"Common Commands","text":"
      # Install a package\npip install requests\n\n# List installed packages\npip list\n\n# Upgrade a package\npip install --upgrade requests\n\n# Uninstall a package\npip uninstall requests\n\n# Search for packages\npip search json\n
      "},{"location":"Terminal/#usage-tips","title":"Usage Tips","text":"
      • Long press to access PIP Client from the Dashboard
      • Use pip help to see all available commands
      • Some commands may require administrator privileges
      "},{"location":"Terminal/#choosing-the-right-tool","title":"Choosing the Right Tool","text":"Tool Best For Shell Terminal Quick calculations, simple scripts, testing snippets IPython Complex exploration, data analysis, interactive debugging PIP Client Installing/updating packages, checking dependencies"},{"location":"Terminal/#learn-more","title":"Learn More","text":"
      • Python Documentation \u2013 Official Python language and library reference
      • IPython Documentation \u2013 Advanced interactive Python features
      • PyPI Guide \u2013 Managing Python packages in QPython
      "},{"location":"community/","title":"Community","text":"

      QPython has an active technical community that provides a platform for developers to communicate, share, and support each other.

      "},{"location":"community/#join-the-community","title":"Join the Community","text":""},{"location":"community/#international-communities","title":"International Communities","text":"
      • Discord Server \u2013 Real-time communication with developers worldwide
      • Facebook Page \u2013 Latest updates and news
      • Twitter/X \u2013 Official account
      "},{"location":"community/#video-platforms","title":"Video Platforms","text":"
      • YouTube \u2013 Official video channel
      "},{"location":"community/#get-help","title":"Get Help","text":""},{"location":"community/#issue-reporting","title":"Issue Reporting","text":"

      If you find any issues or have suggestions for improvement, please feedback through:

      • GitHub Issues \u2013 Report bugs and feature requests
      • GitHub Discussions \u2013 Participate in discussions
      "},{"location":"community/#follow-us","title":"Follow Us","text":"Platform Link GitHub github.com/qpython-android Discord discord.gg/hV2chuD Facebook facebook.com/qpython Twitter twitter.com/qpython

      The QPython team regularly updates project progress in the community, feel free to follow!

      "},{"location":"editor-guide/","title":"Use the best way for developing","text":""},{"location":"editor-guide/#develop-from-qeditor","title":"Develop from QEditor","text":"

      QEditor is the QPython's built-in editor, which supports Python / HTML syntax highlight.

      QEditor's main features

      • Edit / View plain text file, like Python, Lua, HTML, Javascript and so on

      • Edit and run Python script & Python syntax highlight

      • Edit and run Shell script

      • Preview HTML with built-in HTML browser

      • Search by keyword, code snippets, code share

      You could run the QPython script directly when you develop from QEditor, so when you are moving it's the most convient way for QPython develop.

      "},{"location":"editor-guide/#develop-from-browser","title":"Develop from browser","text":"

      QPython has a built-in script which is qedit4web.py, you could see it when you click the start button and choose \"Run local script\". After run it, you could see the result.

      Then, you could access the url from your PC/Laptop's browser for developing, just like the below pics.

      After choose some project or script, you could start to develop

      With it's help, you could write from browser and run from your android phone. It is very convenient.

      "},{"location":"editor-guide/#develop-from-your-computer","title":"Develop from your computer","text":"

      Besides the methods mentioned above, you can also develop the script in your own way, then upload it to your phone using the built-in FTP service and run it with QPython.

      "},{"location":"external-api/","title":"QPython Open API","text":"

      QPython has an open activity which allow you run qpython from outside.

      The MPyAPI's definition seems like the following:

          <activity \n        android:name=\"org.qpython.qpylib.MPyApi\"\n        android:label=\"@string/qpy_run_with_share\"\n        android:screenOrientation=\"user\"\n        android:configChanges=\"orientation|keyboardHidden\"\n        android:exported=\"true\">\n        <intent-filter>\n            <action android:name=\"org.qpython.qpylib.action.MPyApi\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.LAUNCHER\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.VIEW\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.BROWSABLE\" />\n            <data android:scheme=\"http\" />\n            <data android:scheme=\"https\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"text/plain\"/>\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"image/*\"/>\n        </intent-filter>\n    </activity>\n

      So, with it's help, you could:

      "},{"location":"external-api/#share-some-content-to-qpythons-scripts","title":"Share some content to QPython's scripts","text":"

      You could choose some content in some app, and share to qpython's script, then you could handle the content with the sys.argv[2]

      Watch the demo video on YouTube

      "},{"location":"external-api/#run-qpythons-script-from-your-own-application","title":"Run QPython's script from your own application","text":"

      You can call QPython to run some script or python code in your application by call this activity, like the following sample:

      // code sample shows how to call qpython API\nString extPlgPlusName = \"org.qpython.qpy\";          // QPython package name\nIntent intent = new Intent();\nintent.setClassName(extPlgPlusName, \"org.qpython.qpylib.MPyApi\");\nintent.setAction(extPlgPlusName + \".action.MPyApi\");\n\nBundle mBundle = new Bundle();\nmBundle.putString(\"app\", \"myappid\");\nmBundle.putString(\"act\", \"onPyApi\");\nmBundle.putString(\"flag\", \"onQPyExec\"); // any String flag you may use in your context\nmBundle.putString(\"param\", \"\");         // param String param you may use in your context\n\n/*\n* The Python code we will run\n*/\nString code = \"import androidhelper\\n\" +\n            \"droid = androidhelper.Android()\\n\" +\n            \"line = droid.dialogGetInput()\\n\" +\n            \"s = 'Hello %s' % line.result\\n\" +\n            \"droid.makeToast(s)\\n\"\n\nmBundle.putString(\"pycode\", code);\nintent.putExtras(mBundle);\nstartActivityForResult(intent, SCRIPT_EXEC_PY);\n...\n\n// And you can handle the qpython callabck result in onActivityResult\n@Override\nprotected void onActivityResult(int requestCode, int resultCode, Intent data) {\n    if (requestCode == SCRIPT_EXEC_PY) {\n        if (data!=null) {\n            Bundle bundle = data.getExtras();\n            String flag = bundle.getString(\"flag\");\n            String param = bundle.getString(\"param\");\n            String result = bundle.getString(\"result\"); // Result your Pycode generate\n            Toast.makeText(this, \"onQPyExec: return (\"+result+\")\", Toast.LENGTH_SHORT).show();\n        } else {\n            Toast.makeText(this, \"onQPyExec: data is null\", Toast.LENGTH_SHORT).show();\n\n        }\n    }\n}\n

      Checkout the full project from github

      And there is a production application - QPython Plugin for Tasker

      "},{"location":"getting-started/","title":"QPython: Getting Started Guide","text":"

      This guide will introduce QPython's features and help you get started quickly.

      "},{"location":"getting-started/#qpython-overview","title":"QPython Overview","text":"

      Why choose QPython?

      Smartphones have become essential information and technical assistants. A flexible interpreter engine helps you efficiently complete most tasks without complex development processes.

      QPython offers an amazing developing experience - with its help, you could implement programs easily without complex IDE installation, compiling, or packaging processes.

      "},{"location":"getting-started/#qpython-branches","title":"QPython Branches","text":"

      For different usage scenarios, QPython has several branches:

      • QPython \u2013 The main version maintained by the QPython team with AI features, available on Google Play and other app stores
      • QPython+ \u2013 Community version launched by open-source contributors, offering various new features
      • QPython Plus \u2013 Extended permissions version (not available on app stores)
      "},{"location":"getting-started/#key-features","title":"Key Features","text":"
      • Offline Python 3.12 interpreter - Run Python programs without Internet
      • SL4A Integration - Control Android hardware and APIs with Python
      • GenAI Integration - Support for local LLM, various LLM libraries including OpenAI, and AIPyApp for Vibe Coding development on QPython
      • Package Installation - Install extensions via QPYPI and pip
      • Built-in Editor - Syntax highlighting and code editing
      • Multiple Runtime Modes - Besides console programs, supports Android native UI (via SL4A interface), Pygame / Turtle / Tkinter and other runtime modes
      "},{"location":"getting-started/#1-dashboard","title":"1. Dashboard","text":"

      After you install QPython, start it by tapping its icon. You will see the main dashboard with the QPython logo and the following features:

      "},{"location":"getting-started/#dashboard-features","title":"Dashboard Features","text":"

      The QPython dashboard provides quick access to all major features:

      • Terminal \u2014 Access the Python console and shell for direct command execution
      • Notebook \u2014 Interactive Jupyter-style notebooks for data analysis and experiments
      • Editor \u2014 Built-in code editor with syntax highlighting for writing Python scripts
      • Explorer \u2014 Browse and manage your files, scripts, and projects
      • QPYPI \u2014 Install Python packages and extensions. See QPYPI Guide for details
      • Setting \u2014 Configure QPython preferences and runtime options
      • Community \u2014 Access QPython community resources, forums, and help
      • Courses \u2014 Access learning materials and tutorials for Python programming

      Tap any icon to access the corresponding feature.

      "},{"location":"getting-started/#2-terminal-and-editor","title":"2. Terminal and Editor","text":""},{"location":"getting-started/#terminal","title":"Terminal","text":"

      The Terminal provides a Python console with: - Explore object properties - Test syntax and ideas - Execute commands directly

      Use the plus button (1) to open new Terminal tabs, switch between them via the dropdown (2), and close with the close button (3).

      "},{"location":"getting-started/#editor","title":"Editor","text":"

      The editor's bottom toolbar contains the following tools (left to right):

      • Quick Input (includes keywords like def / if / else / elif / class)
      • Lock (prevent accidental touches)
      • Jump
      • Save
      • Run
      • Search
      • Undo
      • Redo
      • Save As
      • Recent Files
      • Code Snippets

      Important: When saving, manually add the .py extension as the editor doesn't add it automatically.

      "},{"location":"getting-started/#3-explorer-file-management","title":"3. Explorer (File Management)","text":"

      Access scripts and projects through the Explorer, supporting browsing, organizing, and managing all Python files.

      "},{"location":"getting-started/#scripts","title":"Scripts","text":"

      Scripts are single Python files stored in /storage/emulated/0/Android/data/org.qpython.qpy/files/scripts3/ (for Python 3).

      Available actions: - Run \u2014 Execute the script - Open \u2014 Edit with built-in editor - Rename \u2014 Change the script name - Delete \u2014 Remove the script

      "},{"location":"getting-started/#projects","title":"Projects","text":"

      Projects are directories containing main.py as the entry point. You can include other dependencies and resources in the same directory. Store projects in /storage/emulated/0/Android/data/org.qpython.qpy/files/projects3/.

      "},{"location":"getting-started/#notebooks","title":"Notebooks","text":"

      Jupyter-style notebooks are also managed through the Explorer, stored in /storage/emulated/0/Android/data/org.qpython.qpy/files/notebooks/.

      Available actions: - Run \u2014 Execute the notebook - Open \u2014 Explore notebook content - Rename \u2014 Change the notebook name - Delete \u2014 Remove the notebook

      "},{"location":"getting-started/#4-libraries","title":"4. Libraries","text":"

      Extend QPython's capabilities by installing third-party libraries.

      "},{"location":"getting-started/#package-installation-methods","title":"Package Installation Methods","text":"

      QPYPI (Recommended)

      Install pre-built libraries from QPYPI, including scientific packages like numpy, scipy, etc.

      See QPYPI Guide for details.

      PIP Client

      Install pure Python libraries through QPython's PIP client or QPYPI interface:

      pip install requests\n

      Pre-compiled Packages

      For packages with C/C++/Rust dependencies, use QPython's pre-compiled packages:

      pip install numpy-qpython\npip install scipy-aipy\n

      See QPYPI Guide for the full list of available packages.

      Manual Installation

      You can also copy libraries to /storage/emulated/0/Android/data/org.qpython.qpy/files/lib/python3.12/site-packages/.

      "},{"location":"getting-started/#5-runtime-modes","title":"5. Runtime Modes","text":"

      QPython supports several runtime modes for different use cases:

      "},{"location":"getting-started/#console-mode","title":"Console Mode","text":"

      Default mode for regular Python scripts.

      "},{"location":"getting-started/#sl4a-mode","title":"SL4A Mode","text":"

      Scripts that call Android APIs through the SL4A library.

      import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello Android!')\n

      See QSL4A Documentation for full API reference.

      "},{"location":"getting-started/#webapp-mode","title":"WebApp Mode","text":"

      Create web-based applications with a backend server. Add the following two headers at the beginning of your script:

      #qpy:webapp:<project name>\n#qpy://localhost:<port the web service listens on>/<default main path>\n

      Example:

      #qpy:webapp:Hello QPython\n#qpy://localhost:8080/hello\n\nfrom bottle import route, run, Bottle\n\napp = Bottle()\n\n@route('/hello')\ndef hello():\n    return '<h1>Hello from QPython!</h1>'\n\nrun(app, host='localhost', port=8080)\n

      "},{"location":"getting-started/#q-mode-quiet-mode","title":"Q Mode (Quiet Mode)","text":"

      Run scripts silently without displaying the console. Add header at the beginning of your script:

      #qpy:quiet\n\nimport time\n\nwhile True:\n    # Your background task\n    time.sleep(60)\n
      If you need to run a GUI-based SL4A program and don't want to show console information, this mode is recommended.

      "},{"location":"getting-started/#6-community-and-support","title":"6. Community and Support","text":"

      Visit QPython.org for documentation, user communities, and help.

      Community Links: - Facebook Group - GitHub - Report Issues

      Next Steps: - Try the Hello World Tutorial - Explore QSL4A API for Android integration - Learn about QPython Branches

      "},{"location":"getting-started/#video-introduction","title":"Video Introduction","text":""},{"location":"getting-started/#next-steps","title":"Next Steps","text":"

      If you've got a basic understanding of QPython's features, welcome to start experiencing the fun of programming! Try the Hello World Tutorial to take your first step.

      "},{"location":"qpypi-guide/","title":"QPYPI","text":"

      You can extend your QPython capabilities by installing packages.

      "},{"location":"qpypi-guide/#package-installation-support","title":"Package Installation Support","text":""},{"location":"qpypi-guide/#pure-python-packages","title":"Pure Python Packages","text":"

      QPython supports Python packages developed with pure Python. You can install these packages directly using pip install through QPython's PIP Client or QPYPI on dashboard.

      "},{"location":"qpypi-guide/#pre-compiled-packages","title":"Pre-compiled Packages","text":"

      If some packages (or their dependencies) are developed with Rust/C/C++, QPython cannot support them directly because there is no compiler toolchain support on QPython. However, the QPython team has pre-compiled some commonly used packages and published them in QPython's QPYPI/Extensions for users to install easily.

      "},{"location":"qpypi-guide/#installing-pre-compiled-packages","title":"Installing Pre-compiled Packages","text":"

      You can install pre-compiled packages in the following ways:

      1. Through QPython App: Install directly from QPYPI or Extensions within the QPython app
      2. Through PyPI: Visit https://pypi.org/user/qpythonx/ to view available packages
      3. Via pip command:
      4. pip install xxx-qpython - Packages with the -qpython suffix
      5. pip install xxx-aipy - Packages with the -aipy suffix (typically AI/ML related packages)

      Note: We usually add one of these suffixes based on the package's intended use case.

      "},{"location":"qpypi-guide/#requesting-new-packages","title":"Requesting New Packages","text":"

      If you need a package that is not currently supported:

      • Raise an issue in the qpython.org project
      • The QPython team will consider pre-compiling and adding it to the repository

      For more ways to get help and engage with the community, see the Community & Feedback section.

      Note: Because of different computer architectures, we cannot guarantee that QPYPI includes all packages from PyPI.

      "},{"location":"qpython-x/","title":"QPython Branches","text":"

      QPython is the Python engine for Android. It contains amazing features such as Python interpreter, runtime environment, editor, QPYI and integrated SL4A. It makes it easy for you to use Python on Android. And it's FREE.

      QPython already has millions of users worldwide and it is also an open source project.

      For different usage scenarios, QPython has several branches:

      "},{"location":"qpython-x/#qpython","title":"QPython","text":"

      Standard Edition: Optimized for AI performance and universal app store compatibility

      The main version available on Google Play and other app stores. This version focuses on AI features, making it easier for users to learn and use Python in the AI era.

      Key Features: - AI-powered coding assistance and learning tools - Offline Python 3.12 interpreter: no Internet is required to run Python programs - Supports multiple project types: console, SL4A, webapp - Convenient QR code reader for transferring codes to your phone - QPYPI and custom repository for prebuilt wheel packages - Easy-to-use editor with syntax highlighting - Good documentation and community support

      Permissions: Requires only basic phone permissions for installation.

      Download: Available on Google Play and major app stores.

      "},{"location":"qpython-x/#qpython_1","title":"QPython+","text":"

      Community Edition: Openly supports various community-driven features; available on select app stores.

      The community open-source version (in planning and preparation). This version is designed for contributors who want to participate in QPython project development and supports customization for different manufacturers.

      Key Features: - Community-driven development - Support for vendor customization - More flexible configuration options - Open for contributors to join development

      Permissions: Requires only basic phone permissions for installation.

      Download: Will be available on Google Play and major app stores.

      Note: This version is currently in planning and preparation phase. Stay tuned for updates!

      "},{"location":"qpython-x/#qpython-plus","title":"QPython Plus","text":"

      QPython+ Full Access Edition: Grants complete permissions to call all Android interfaces. Download link available exclusively via the official cloud drive.

      A special version with extended permissions that provides maximum control over the device. This version is NOT published on app stores due to its sensitive permission requirements.

      Key Features: - Full SL4A API access including sensitive features - SMS/Call control APIs - Advanced system integration - Maximum device control capabilities

      Permissions: Requires extensive permissions including: - Bluetooth - Location (GPS) - Read/Send SMS - Call phone - Camera and microphone - System settings - And other sensitive permissions

      Download: Not available on app stores. Distributed through special channels only.

      Important: QPython will not use these permissions in background without your knowledge. If you get exceptions while using SL4A APIs, please check whether the relevant permissions are enabled in system settings.

      "},{"location":"tutorial-hello-world/","title":"Writing \"Hello World\"","text":""},{"location":"tutorial-hello-world/#hello-world","title":"Hello world","text":"

      Well, after you became a bit more familiar with QPython, let's create our first program in QPython. Obviously, it will be helloworld.py. ;)

      Start QPython, open editor and enter the following code:

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello, QPYTHON!')\n

      No wonder, it's just similar to any other hello-world program. When executed, it just shows pop-up message on the screen (see screenshot on the top). Anyway, it's a good example of QPython program.

      "},{"location":"tutorial-hello-world/#code-understanding","title":"Code Understanding","text":"

      It begins with import androidhelper \u2014 the most useful module in QPython, which encapsulates almost all interface with Android available in Python. Any script developed in QPython starts with this statement (at least if it claims to communicate with user). Read more about Python library here and import statement here.

      Next, we create an object droid (actually a class), which is necessary to call RPC functions to communicate with Android.

      The last line of our code calls droid.makeToast(), which shows a small pop-up message (a \"toast\") on the screen.

      Well, let's add some more functionality. Let it ask the user name and greet them.

      "},{"location":"tutorial-hello-world/#more-samples","title":"More samples","text":"

      We can display a simple dialog box with the title, prompt, edit field and buttons Ok and Cancel using dialogGetInput call. Replace the last line of your code and save it as hello1.py:

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\n

      Well, I think it should return any respond, any user reaction. That's why I wrote respond = .... But what does the call actually return? Let's check. Just add print statement after the last line:

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\n

      Then save and run it...

      Oops! Nothing printed? Don't worry. Just pull notification bar and you will see \"QPython Program Output: hello1.py\" \u2014 tap it!

      As you can see, droid.dialogGetInput() returns a JSON object with three fields. We need only one \u2014 result which contains an actual input from user.

      Let's add script's reaction:

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nmessage = f'Hello, {respond.result}!'\ndroid.makeToast(message)\n

      Last two lines (1) format the message and (2) show the message to the user in the toast. See Python docs if you still don't know what f-strings mean.

      Wow! It works! ;)

      Now I'm going to add a bit of logic there. Think: what happen if the user clicks Cancel button, or clicks Ok leaving the input field blank?

      You can play with the program checking what contains respond variable in every case.

      First of all, I want to put text entered by user to a separate variable: name = respond.result. Then I'm going to check it, and if it contains any real text, it will be considered as a name and will be used in greeting. Otherwise another message will be shown. Replace fifth line message = f'Hello, {respond.result}!' with the following code:

      name = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\n

      Use < and > buttons on the toolbar to indent/unindent lines in if-statement (or just use space/backspace keys). You can read more about indentation in Python here; if-statement described here.

      First of all, we put user input to the variable name. Then we check does name contain anything? In case the user left the line blank and clicked Ok, the return value is empty string ''. In case of Cancel button pressed, the return value is None. Both are treated as false in if-statement. So, only if name contains anything meaningful, then-statement is executed and greeting \"Hello, ...!\" shown. In case of empty input the user will see \"Hey! And you're not very polite, %Username%!\" message.

      Ok, here is the whole program:

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nname = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\ndroid.makeToast(message)\n
      "},{"location":"tutorial-hello-world/#execution-result","title":"Execution Result","text":""},{"location":"tutorial-hello-world/#next-steps","title":"Next Steps","text":"

      For Python beginners, we recommend learning from the Python Basic Syntax course to further your Python skills, or browse QPython Featured Courses to find more content you want to learn.

      "},{"location":"whats-new/","title":"What's New","text":""},{"location":"whats-new/#v392-v393","title":"v3.9.2 / v3.9.3","text":"
      • SDK upgrade with support for 16 KB page size, providing a smoother runtime environment
      • Major editor updates for a more fluid editing experience
      • Various other minor improvements
      "},{"location":"whats-new/#v391","title":"v3.9.1","text":"
      • SDK upgrade with support for 16 KB page size, providing a smoother runtime environment
      • Extension packages now support MCP
      • Bug fixes
      "},{"location":"whats-new/#v390","title":"v3.9.0","text":"
      • SDK upgrade to incorporate the latest Android features
      • Built-in Ollama 0.9.5 upgrade: Now supports running Gemma3n models locally in QPython, experiencing more powerful on-device AI computing capabilities
      • Pygame game development support: Combined with XServer, you can now easily write and run Pygame games on QPython, unleashing your creativity!
      • Personalized icon customization: Customize your desktop icons and themes through QPython settings, creating a unique programming environment
      "},{"location":"whats-new/#v3811","title":"v3.8.11","text":"
      • Built-in Ollama 0.9.5 upgrade: Now supports running Gemma3n models locally in QPython, experiencing more powerful on-device AI computing capabilities
      • Pygame game development support: Combined with XServer, you can now easily write and run Pygame games on QPython, unleashing your creativity!
      • Personalized icon customization: Customize your desktop icons and themes through QPython settings, creating a unique programming environment
      "},{"location":"whats-new/#v3810","title":"v3.8.10","text":"
      • Built-in Ollama upgrade: Now you can easily run Qwen3 / Gemma3 models locally in QPython!
      • Powerful MCP library added: Added mcp library in Extensions -> AIPY, allowing you to take powerful MCP functionality with you anywhere, anytime!
      "},{"location":"whats-new/#v389","title":"v3.8.9","text":"

      Major update! AI programming fully integrated into QPython to make your programming easier!

      • Natural language programming support: New support for AIPyApp, enabling natural language programming in QPython. Currently in beta - join our community for usage instructions
      • New QSL4A feature: Added notebookOpen function, supporting natural language control to open Notebook files
      • Built-in editor upgrade: Enhanced editor functionality, supporting opening and browsing various text files
      • Convenient file management: Added internal storage entry in file manager for quick access to your files
      "},{"location":"whats-new/#v388","title":"v3.8.8","text":"
      • Important improvements to file access permission controls, allowing users to flexibly enable or disable access to external storage files through QPython programming
      • SDK upgraded to enhance support and compatibility with newer Android versions
      • Added Anthropic and Google GenAI libraries in Extensions -> AIPY
      "},{"location":"whats-new/#v387","title":"v3.8.7","text":"
      • Based on existing Tkinter support, added sample code for drawing Doraemon using Turtle in Extensions -> Tools
      • Optimized phone permission acquisition process, improving user experience and operational convenience
      • Added Google Gen AI library in Extensions -> AIPY for easy access to Gemini Developer API and Vertex AI
      "},{"location":"whats-new/#v386","title":"v3.8.6","text":"
      • Tkinter support: Now supports Tkinter library, accessible through XServer. Please visit www.qpython.org's drive link \"Extra\" to download required files
      • Storage permission update: To improve user experience, we added permission to read phone storage for accessing Python programs stored in other directories

      After this update, QPython and QPythonPlus (not available on app stores, designed for advanced users with more sensitive permissions) will maintain synchronized version numbers.

      "},{"location":"whats-new/#v352-2025225","title":"v3.5.2 (2025/2/25)","text":"

      Achieve seamless integration with the open source LLM deployment tool Ollama and DeepSeek developed by DeepSeek!

      Features: - Zero threshold to run various large language models locally on mobile devices - Quickly deploy cutting-edge AI models such as DeepSeek - Enjoy a minimalist API calling experience - Build a completely offline intelligent programming environment

      Capabilities: - Load/manage LLM models directly on the mobile phone - Real-time low-latency response based on local computing

      "},{"location":"whats-new/#v350","title":"v3.5.0","text":"
      • Python upgraded to 3.12.8
      • Improved Dashboard for clearer, more user-friendly functionality
      • Added numerous third-party packages: PyTorch / Twisted / Scrapy / FastAPI ...
      "},{"location":"whats-new/#v338","title":"v3.3.8","text":"
      • Fixed NumPy compatibility issues
      "},{"location":"whats-new/#v335","title":"v3.3.5","text":"
      • Upgraded Python kernel to 3.11.9
      • Fixed bug where module installation status was not displayed in extensions
      • Fixed bug where deleting modules in extensions failed
      • Fixed other bugs
      "},{"location":"whats-new/#v334","title":"v3.3.4","text":"
      • Added OpenAI/Langchain/APIGPTCloud AI packages
      • Removed unnecessary files to reduce size
      "},{"location":"whats-new/#v325","title":"v3.2.5","text":"
      • Added some SL4A functions
      • Other bug fixes
      "},{"location":"whats-new/#v323","title":"v3.2.3","text":"
      • Updated Python version to 3.11.0
      • Updated IPython version to 8.6.0
      • Updated pip version to 22.3.1
      • Updated scientific computing packages with automatic soft links
      • Reduced space usage
      • Added some SL4A functions + other bug fixes
      "},{"location":"whats-new/#v318","title":"v3.1.8","text":"
      • Added operation hotkeys in terminal
      • Fixed issue where editor lost content on rotation
      • Fixed other bugs

      Download on Google Play

      "},{"location":"qsl4a/","title":"QSL4A (Scripting Layer for Android) API Documentation","text":"

      QSL4A is QPython's scripting layer for Android, allowing you to control Android device features using Python.

      "},{"location":"qsl4a/#quick-start","title":"Quick Start","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Show a toast message\ndroid.makeToast('Hello QPython!')\n\n# Vibrate the device\ndroid.vibrate(500)\n\n# Get battery level (start monitoring first)\nimport time\ndroid.batteryStartMonitoring()\ntime.sleep(0.5)  # Wait for data\nbattery = droid.readBatteryData().result\nprint(f\"Battery: {battery['level']}%\")\n
      "},{"location":"qsl4a/#documentation-structure","title":"Documentation Structure","text":""},{"location":"qsl4a/#core-modules","title":"Core Modules","text":"
      • Android Base - Core connection and RPC
      • Intent System - Android Intent operations
      • Event System - Event handling and broadcasting
      "},{"location":"qsl4a/#ui-components","title":"UI Components","text":"
      • Dialogs - Alert, input, choice dialogs
      • FullScreen UI - Custom layout UI
      • FloatView - Floating window
      • Accessibility - Screen automation
      "},{"location":"qsl4a/#system","title":"System","text":"
      • Battery - Battery monitoring
      • Sensors - Device sensors
      • Application - App management
      • System Info - Device information
      • Settings - System settings
      • WakeLock - Wake lock control
      • QPython Interface - Script execution
      • Activity Result - Activity result handling
      "},{"location":"qsl4a/#hardware","title":"Hardware","text":"
      • Bluetooth - Bluetooth operations
      • Camera - Photo and video capture
      • Audio/Recorder - Audio recording
      • Webcam - MJPEG streaming
      • USB Serial - USB host serial
      "},{"location":"qsl4a/#connectivity","title":"Connectivity","text":"
      • WiFi - WiFi operations
      • Location - GPS and location
      • SMS - SMS operations
      • Phone - Phone calls and info
      • Contacts - Contact management
      • Signal Strength - Signal monitoring
      • FTP Server - Built-in FTP server
      "},{"location":"qsl4a/#storage","title":"Storage","text":"
      • DocumentFile - File operations
      • Clipboard - Clipboard operations
      • Preferences - Shared preferences
      "},{"location":"qsl4a/#media","title":"Media","text":"
      • Media Player - Audio/Video playback
      • Image Processing - Image operations
      "},{"location":"qsl4a/#special-features","title":"Special Features","text":"
      • Cipher - Encryption/Decryption
      • PGPT AI - AI speech services
      "},{"location":"qsl4a/#result-object","title":"Result Object","text":"

      Most QSL4A methods return a Result namedtuple with: - id - Request ID - result - The actual result data - error - Error message if failed

      result = droid.getClipboard()\nif result.error is None:\n    print(result.result)\nelse:\n    print(f\"Error: {result.error}\")\n
      "},{"location":"qsl4a/connectivity/contacts/","title":"Contacts API","text":"

      Access and manage device contacts.

      "},{"location":"qsl4a/connectivity/contacts/#contact-picking","title":"Contact Picking","text":""},{"location":"qsl4a/connectivity/contacts/#pickcontact","title":"pickContact()","text":"

      Display a list of contacts to pick from.

      pickContact()\n

      Returns: Intent with contact URI

      "},{"location":"qsl4a/connectivity/contacts/#pickphone","title":"pickPhone()","text":"

      Display a list of phone numbers to pick from.

      pickPhone()\n

      Returns: Selected phone number string

      "},{"location":"qsl4a/connectivity/contacts/#contact-queries","title":"Contact Queries","text":""},{"location":"qsl4a/connectivity/contacts/#contactsget","title":"contactsGet()","text":"

      Get all contacts.

      contactsGet(attributes=None)\n

      Parameters: - attributes (list, optional): Specific attributes to retrieve

      Returns: List of contact JSONObject

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetbyid","title":"contactsGetById()","text":"

      Get a contact by ID.

      contactsGetById(id, attributes=None)\n

      Parameters: - id (int): Contact ID - attributes (list, optional): Specific attributes to retrieve

      Returns: JSONObject contact data

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetcount","title":"contactsGetCount()","text":"

      Get the total number of contacts.

      contactsGetCount()\n

      Returns: Integer count

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetids","title":"contactsGetIds()","text":"

      Get all contact IDs.

      contactsGetIds()\n

      Returns: List of contact ID integers

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetattributes","title":"contactsGetAttributes()","text":"

      Get all possible contact attributes.

      contactsGetAttributes()\n

      Returns: List of attribute names

      "},{"location":"qsl4a/connectivity/contacts/#content-queries","title":"Content Queries","text":""},{"location":"qsl4a/connectivity/contacts/#querycontent","title":"queryContent()","text":"

      Query content resolver with custom parameters.

      queryContent(uri, attributes=None, selection=None, selectionArgs=None, order=None)\n

      Parameters: - uri (str): Content URI - attributes (list, optional): Attributes to retrieve - selection (str, optional): WHERE clause - selectionArgs (list, optional): Selection arguments - order (str, optional): ORDER BY clause

      Returns: List of JSONObject results

      "},{"location":"qsl4a/connectivity/contacts/#queryattributes","title":"queryAttributes()","text":"

      Get attributes for a content URI.

      queryAttributes(uri)\n

      Parameters: - uri (str): Content URI

      Returns: JSONArray of attribute names

      "},{"location":"qsl4a/connectivity/contacts/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Pick a contact\ncontact_uri = droid.pickContact().result\nprint(f\"Selected contact: {contact_uri}\")\n\n# Pick a phone number\nphone = droid.pickPhone().result\nprint(f\"Selected phone: {phone}\")\n\n# Get all contacts\ncontacts = droid.contactsGet().result\nprint(f\"Total contacts: {len(contacts)}\")\n\n# Get contact by ID\ncontact = droid.contactsGetById(1).result\nprint(f\"Contact: {contact}\")\n\n# Get contact attributes\nattrs = droid.contactsGetAttributes().result\nprint(f\"Available attributes: {attrs}\")\n
      "},{"location":"qsl4a/connectivity/ftp/","title":"FTP Server API","text":"

      Start and manage a built-in FTP server on the device.

      "},{"location":"qsl4a/connectivity/ftp/#ftp-server-methods","title":"FTP Server Methods","text":""},{"location":"qsl4a/connectivity/ftp/#ftpstart","title":"ftpStart()","text":"

      Start the FTP server.

      ftpStart()\n

      Returns: Array containing IP address and port [ip, port]

      "},{"location":"qsl4a/connectivity/ftp/#ftpstop","title":"ftpStop()","text":"

      Stop the FTP server.

      ftpStop()\n
      "},{"location":"qsl4a/connectivity/ftp/#ftpisrunning","title":"ftpIsRunning()","text":"

      Check if FTP server is running.

      ftpIsRunning()\n

      Returns: True if running

      "},{"location":"qsl4a/connectivity/ftp/#ftpget","title":"ftpGet()","text":"

      Get FTP server IP address.

      ftpGet()\n

      Returns: Array with IP address and port

      "},{"location":"qsl4a/connectivity/ftp/#ftpset","title":"ftpSet()","text":"

      Configure FTP server settings.

      ftpSet(port=None, rootDir=None, username=None, password=None)\n

      Parameters: - port (int, optional): Server port - rootDir (str, optional): Root directory to serve - username (str, optional): Login username - password (str, optional): Login password

      Returns: JSONObject with current settings

      "},{"location":"qsl4a/connectivity/ftp/#ftpstatus","title":"ftpStatus()","text":"

      Get FTP server status.

      ftpStatus()\n

      Returns: String status description

      "},{"location":"qsl4a/connectivity/ftp/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Configure FTP server\ndroid.ftpSet(\n    port=2121,\n    rootDir=\"/sdcard\",\n    username=\"admin\",\n    password=\"secret\"\n)\n\n# Start FTP server\ninfo = droid.ftpStart().result\nprint(f\"FTP running at {info[0]}:{info[1]}\")\n\n# Check status\nif droid.ftpIsRunning().result:\n    print(\"FTP server is running\")\n\n# Get server info\nserver_info = droid.ftpGet().result\nprint(f\"Server: {server_info}\")\n\n# Stop when done\ndroid.ftpStop()\n

      Note: Connect to the FTP server using any FTP client with the provided credentials.

      "},{"location":"qsl4a/connectivity/location/","title":"Location API","text":"

      Access GPS and network location services.

      "},{"location":"qsl4a/connectivity/location/#methods","title":"Methods","text":""},{"location":"qsl4a/connectivity/location/#startlocating","title":"startLocating()","text":"

      Start location updates.

      startLocating(minUpdateTime=60000, minUpdateDistance=30, updateGnssStatus=False)\n

      Parameters: - minUpdateTime (int): Minimum time between updates in milliseconds (default: 60000) - minUpdateDistance (float): Minimum distance for update in meters (default: 30) - updateGnssStatus (bool): Enable GNSS status updates (default: False)

      "},{"location":"qsl4a/connectivity/location/#stoplocating","title":"stopLocating()","text":"

      Stop location updates.

      stopLocating()\n
      "},{"location":"qsl4a/connectivity/location/#readlocation","title":"readLocation()","text":"

      Get last known location.

      readLocation()\n

      Returns: Location data dict

      "},{"location":"qsl4a/connectivity/location/#getlastknownlocation","title":"getLastKnownLocation()","text":"

      Get cached location.

      getLastKnownLocation()\n

      Returns: Location from all providers

      "},{"location":"qsl4a/connectivity/location/#geocode","title":"geocode()","text":"

      Convert address to coordinates.

      geocode(address, maxResults=1)\n
      "},{"location":"qsl4a/connectivity/location/#location-provider-methods","title":"Location Provider Methods)","text":""},{"location":"qsl4a/connectivity/location/#locationproviders","title":"locationProviders()","text":"

      Get available location providers on the phone.

      locationProviders()\n

      Returns: List of available provider names (e.g., ['gps', 'network'])

      "},{"location":"qsl4a/connectivity/location/#locationproviderenabled","title":"locationProviderEnabled()","text":"

      Check if a specific location provider is enabled.

      locationProviderEnabled(provider)\n

      Parameters: - provider (str): Provider name (e.g., 'gps', 'network')

      Returns: True if enabled, False otherwise

      "},{"location":"qsl4a/connectivity/location/#readgnssstatus","title":"readGnssStatus()","text":"

      Read Global Navigation Satellite System status (requires Android 8+).

      readGnssStatus()\n

      Returns: JSONArray containing GNSS satellite information

      "},{"location":"qsl4a/connectivity/location/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start location updates\ndroid.startLocating(minUpdateTime=5000, minUpdateDistance=1, updateGnssStatus=False)\n\n# Wait for fix\ntime.sleep(10)\n\n# Get location\nloc = droid.readLocation().result\nif loc:\n    lat = loc['latitude']\n    lon = loc['longitude']\n    print(f\"Location: {lat}, {lon}\")\n\ndroid.stopLocating()\n
      "},{"location":"qsl4a/connectivity/phone/","title":"Phone API","text":"

      Control phone calls and retrieve phone information.

      "},{"location":"qsl4a/connectivity/phone/#phone-state-tracking","title":"Phone State Tracking","text":""},{"location":"qsl4a/connectivity/phone/#starttrackingphonestate","title":"startTrackingPhoneState()","text":"

      Start tracking phone state changes. Generates 'phone' events.

      startTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/phone/#readphonestate","title":"readPhoneState()","text":"

      Read the current phone state.

      readPhoneState()\n

      Returns: Bundle with phone state and incoming number

      "},{"location":"qsl4a/connectivity/phone/#stoptrackingphonestate","title":"stopTrackingPhoneState()","text":"

      Stop tracking phone state.

      stopTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/phone/#making-calls","title":"Making Calls","text":""},{"location":"qsl4a/connectivity/phone/#phonecall","title":"phoneCall()","text":"

      Call a contact/phone number by URI.

      phoneCall(uri)\n

      Parameters: - uri (str): Contact URI or phone number URI

      "},{"location":"qsl4a/connectivity/phone/#phonecallnumber","title":"phoneCallNumber()","text":"

      Call a phone number directly.

      phoneCallNumber(phone_number)\n

      Parameters: - phone_number (str): Phone number to call

      "},{"location":"qsl4a/connectivity/phone/#phonedial","title":"phoneDial()","text":"

      Dial a number (opens dialer without calling).

      phoneDial(uri)\n

      Parameters: - uri (str): Contact URI or phone number URI

      "},{"location":"qsl4a/connectivity/phone/#phonedialnumber","title":"phoneDialNumber()","text":"

      Dial a phone number (opens dialer without calling).

      phoneDialNumber(phone_number)\n

      Parameters: - phone_number (str): Phone number

      "},{"location":"qsl4a/connectivity/phone/#cell-location","title":"Cell Location","text":""},{"location":"qsl4a/connectivity/phone/#getcelllocation","title":"getCellLocation()","text":"

      Get the current cell location.

      getCellLocation()\n

      Returns: JSONObject with cell location data

      "},{"location":"qsl4a/connectivity/phone/#getallcellslocation","title":"getAllCellsLocation()","text":"

      Get all cell locations (for dual SIM devices).

      getAllCellsLocation()\n

      Returns: JSONArray of cell locations

      "},{"location":"qsl4a/connectivity/phone/#network-information","title":"Network Information","text":""},{"location":"qsl4a/connectivity/phone/#getnetworkoperator","title":"getNetworkOperator()","text":"

      Get the MCC+MNC of the current operator.

      getNetworkOperator()\n

      Returns: String (e.g., '310260')

      "},{"location":"qsl4a/connectivity/phone/#getnetworkoperatorname","title":"getNetworkOperatorName()","text":"

      Get the name of the current operator.

      getNetworkOperatorName()\n

      Returns: String (e.g., 'T-Mobile')

      "},{"location":"qsl4a/connectivity/phone/#getnetworktype","title":"getNetworkType()","text":"

      Get the current network type.

      getNetworkType()\n

      Returns: String describing radio technology (e.g., 'LTE', 'UMTS', 'GSM')

      "},{"location":"qsl4a/connectivity/phone/#getphonetype","title":"getPhoneType()","text":"

      Get the phone type.

      getPhoneType()\n

      Returns: String (e.g., 'GSM', 'CDMA', 'SIP')

      "},{"location":"qsl4a/connectivity/phone/#sim-information","title":"SIM Information","text":""},{"location":"qsl4a/connectivity/phone/#getsimcountryiso","title":"getSimCountryIso()","text":"

      Get the ISO country code for the SIM.

      getSimCountryIso()\n

      Returns: String (e.g., 'us')

      "},{"location":"qsl4a/connectivity/phone/#getsimoperator","title":"getSimOperator()","text":"

      Get the MCC+MNC of the SIM operator.

      getSimOperator()\n

      Returns: String (e.g., '310260')

      "},{"location":"qsl4a/connectivity/phone/#getsimoperatorname","title":"getSimOperatorName()","text":"

      Get the SIM operator name.

      getSimOperatorName()\n

      Returns: String (e.g., 'T-Mobile')

      "},{"location":"qsl4a/connectivity/phone/#getsimserialnumber","title":"getSimSerialNumber()","text":"

      Get the SIM serial number.

      getSimSerialNumber()\n

      Returns: String SIM serial number

      "},{"location":"qsl4a/connectivity/phone/#getsimstate","title":"getSimState()","text":"

      Get the SIM card state.

      getSimState()\n

      Returns: String describing SIM state

      "},{"location":"qsl4a/connectivity/phone/#getsubscriberid","title":"getSubscriberId()","text":"

      Get the subscriber ID.

      getSubscriberId()\n

      Returns: String subscriber ID

      "},{"location":"qsl4a/connectivity/phone/#voice-mail","title":"Voice Mail","text":""},{"location":"qsl4a/connectivity/phone/#getvoicemailalphatag","title":"getVoiceMailAlphaTag()","text":"

      Get the voice mail alpha tag.

      getVoiceMailAlphaTag()\n

      Returns: String voice mail tag

      "},{"location":"qsl4a/connectivity/phone/#getvoicemailnumber","title":"getVoiceMailNumber()","text":"

      Get the voice mail number.

      getVoiceMailNumber()\n

      Returns: String voice mail number

      "},{"location":"qsl4a/connectivity/phone/#device-information","title":"Device Information","text":""},{"location":"qsl4a/connectivity/phone/#getdeviceid","title":"getDeviceId()","text":"

      Get the device ID (IMEI for GSM). Deprecated.

      getDeviceId()\n

      Returns: String device ID

      "},{"location":"qsl4a/connectivity/phone/#getdevicesoftwareversion","title":"getDeviceSoftwareVersion()","text":"

      Get the device software version.

      getDeviceSoftwareVersion()\n

      Returns: String software version

      "},{"location":"qsl4a/connectivity/phone/#getline1number","title":"getLine1Number()","text":"

      Get the line 1 phone number.

      getLine1Number()\n

      Returns: String phone number

      "},{"location":"qsl4a/connectivity/phone/#checknetworkroaming","title":"checkNetworkRoaming()","text":"

      Check if connected to roaming network.

      checkNetworkRoaming()\n

      Returns: True if roaming

      "},{"location":"qsl4a/connectivity/phone/#cell-info","title":"Cell Info","text":""},{"location":"qsl4a/connectivity/phone/#getallcellinfo","title":"getAllCellInfo()","text":"

      Get information about all cells.

      getAllCellInfo()\n

      Returns: List of cell information

      "},{"location":"qsl4a/connectivity/phone/#setdataenabled","title":"setDataEnabled()","text":"

      Enable or disable mobile data.

      setDataEnabled(enabled)\n

      Parameters: - enabled (bool): True to enable, False to disable

      "},{"location":"qsl4a/connectivity/phone/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get network info\noperator = droid.getNetworkOperatorName().result\nprint(f\"Operator: {operator}\")\n\nnetwork_type = droid.getNetworkType().result\nprint(f\"Network: {network_type}\")\n\n# Get SIM info\nsim_state = droid.getSimState().result\nprint(f\"SIM: {sim_state}\")\n\n# Get phone number\nline1 = droid.getLine1Number().result\nprint(f\"Phone: {line1}\")\n\n# Track phone state\ndroid.startTrackingPhoneState()\nprint(\"Tracking phone state...\")\ndroid.stopTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/signalstrength/","title":"Signal Strength API","text":"

      Monitor cellular and wireless signal strength.

      "},{"location":"qsl4a/connectivity/signalstrength/#signal-strength-methods","title":"Signal Strength Methods","text":""},{"location":"qsl4a/connectivity/signalstrength/#starttrackingsignalstrengths","title":"startTrackingSignalStrengths()","text":"

      Start tracking signal strength changes. Generates 'signal_strengths' events.

      startTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/signalstrength/#stoptrackingsignalstrengths","title":"stopTrackingSignalStrengths()","text":"

      Stop tracking signal strengths.

      stopTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/signalstrength/#readsignalstrengths","title":"readSignalStrengths()","text":"

      Read the current signal strengths.

      readSignalStrengths()\n

      Returns: Bundle with signal strength data

      "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthlevel","title":"getTelephoneSignalStrengthLevel()","text":"

      Get the telephone signal strength as a level (0-4).

      getTelephoneSignalStrengthLevel()\n

      Returns: Integer level (0=none, 1=poor, 2=fair, 3=good, 4=excellent)

      "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthdetail","title":"getTelephoneSignalStrengthDetail()","text":"

      Get detailed telephone signal strength information.

      getTelephoneSignalStrengthDetail()\n

      Returns: String with detailed signal info

      "},{"location":"qsl4a/connectivity/signalstrength/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start tracking signal strength\ndroid.startTrackingSignalStrengths()\n\n# Wait for signal updates\ntime.sleep(5)\n\n# Read current signal strength\nsignal = droid.readSignalStrengths().result\nprint(f\"Signal: {signal}\")\n\n# Get level directly\nlevel = droid.getTelephoneSignalStrengthLevel().result\nprint(f\"Signal level: {level}/4\")\n\ndroid.stopTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/sms/","title":"SMS API","text":"

      Send and receive SMS messages.

      "},{"location":"qsl4a/connectivity/sms/#methods","title":"Methods","text":""},{"location":"qsl4a/connectivity/sms/#smssend","title":"smsSend()","text":"

      Send SMS message.

      smsSend(destinationAddress, text)\n

      Parameters: - destinationAddress (str): Phone number - text (str): Message text

      "},{"location":"qsl4a/connectivity/sms/#smsgetmessagecount","title":"smsGetMessageCount()","text":"

      Get message count.

      smsGetMessageCount(unreadOnly=False, folder=\"inbox\")\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessageids","title":"smsGetMessageIds()","text":"

      Get message IDs.

      smsGetMessageIds(unreadOnly=False, folder=\"inbox\")\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessages","title":"smsGetMessages()","text":"

      Get message details.

      smsGetMessages(unreadOnly=False, folder=\"inbox\", attributes=None)\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessagebyid","title":"smsGetMessageById()","text":"

      Get a specific message by ID.

      smsGetMessageById(id, attributes=None)\n

      Parameters: - id (int): Message ID - attributes (list, optional): Specific attributes to retrieve

      Returns: Message data dict

      "},{"location":"qsl4a/connectivity/sms/#smsgetattributes","title":"smsGetAttributes()","text":"

      Get available SMS message attributes.

      smsGetAttributes()\n

      Returns: List of available attribute names

      "},{"location":"qsl4a/connectivity/sms/#smsdeletemessage","title":"smsDeleteMessage()","text":"

      Delete message.

      smsDeleteMessage(id)\n
      "},{"location":"qsl4a/connectivity/sms/#smsmarkmessageread","title":"smsMarkMessageRead()","text":"

      Mark message as read.

      smsMarkMessageRead(ids, read=True)\n
      "},{"location":"qsl4a/connectivity/sms/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Send SMS\ndroid.smsSend(\"+1234567890\", \"Hello from QPython!\")\n\n# Get unread messages\nmessages = droid.smsGetMessages(unreadOnly=True).result\nfor msg in messages:\n    print(f\"From: {msg['address']}, Text: {msg['body']}\")\n
      "},{"location":"qsl4a/connectivity/wifi/","title":"WiFi API","text":"

      Control WiFi adapter and get connection information.

      "},{"location":"qsl4a/connectivity/wifi/#adapter-control","title":"Adapter Control","text":""},{"location":"qsl4a/connectivity/wifi/#checkwifistate","title":"checkWifiState()","text":"

      Check if WiFi is enabled.

      checkWifiState()\n

      Returns: True if WiFi is enabled, False otherwise

      "},{"location":"qsl4a/connectivity/wifi/#togglewifistate","title":"toggleWifiState()","text":"

      Turn WiFi on or off.

      toggleWifiState(enabled=None)\n

      Parameters: - enabled (bool): True to enable, False to disable, None to toggle

      Returns: True if operation succeeded

      "},{"location":"qsl4a/connectivity/wifi/#wifistartscan","title":"wifiStartScan()","text":"

      Start scanning for available WiFi networks.

      wifiStartScan()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifigetscanresults","title":"wifiGetScanResults()","text":"

      Get list of discovered WiFi networks.

      wifiGetScanResults()\n

      Returns: List of access point information

      "},{"location":"qsl4a/connectivity/wifi/#connection-management","title":"Connection Management","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetconnectioninfo","title":"wifiGetConnectionInfo()","text":"

      Get detailed connection information.

      wifiGetConnectionInfo()\n

      Returns: Dict with connection details including SSID, BSSID, IP address

      "},{"location":"qsl4a/connectivity/wifi/#getconnectedinfo","title":"getConnectedInfo()","text":"

      Get connected WiFi network info (simplified).

      getConnectedInfo()\n

      Returns: Dict with SSID, BSSID, signal strength

      "},{"location":"qsl4a/connectivity/wifi/#getdhcpinfo","title":"getDhcpInfo()","text":"

      Get DHCP information for current connection.

      getDhcpInfo(ipConvertToString=True)\n

      Parameters: - ipConvertToString (bool): Convert IP addresses to string format (default: True)

      Returns: Dict with DHCP info including IP, gateway, DNS

      "},{"location":"qsl4a/connectivity/wifi/#wifidisconnect","title":"wifiDisconnect()","text":"

      Disconnect from current WiFi network.

      wifiDisconnect()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifireconnect","title":"wifiReconnect()","text":"

      Reconnect to the current network.

      wifiReconnect()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifireassociate","title":"wifiReassociate()","text":"

      Reassociate with the current access point.

      wifiReassociate()\n
      "},{"location":"qsl4a/connectivity/wifi/#hotspot","title":"Hotspot","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetapstate","title":"wifiGetApState()","text":"

      Get WiFi AP (hotspot) state.

      wifiGetApState()\n

      Returns: Hotspot state

      "},{"location":"qsl4a/connectivity/wifi/#wifi-locks","title":"WiFi Locks","text":""},{"location":"qsl4a/connectivity/wifi/#wifilockacquirefull","title":"wifiLockAcquireFull()","text":"

      Acquire a full WiFi lock (keeps WiFi active even when screen is off).

      wifiLockAcquireFull()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifilockacquirescanonly","title":"wifiLockAcquireScanOnly()","text":"

      Acquire a scan-only WiFi lock.

      wifiLockAcquireScanOnly()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifilockrelease","title":"wifiLockRelease()","text":"

      Release the WiFi lock.

      wifiLockRelease()\n
      "},{"location":"qsl4a/connectivity/wifi/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Check WiFi state\nif droid.checkWifiState().result:\n    print(\"WiFi is enabled\")\nelse:\n    print(\"Enabling WiFi...\")\n    droid.toggleWifiState(True)\n    time.sleep(2)\n\n# Start scanning\ndroid.wifiStartScan()\ntime.sleep(3)\n\n# Get scan results\nnetworks = droid.wifiGetScanResults().result\nfor network in networks:\n    print(f\"SSID: {network.get('SSID')}, Signal: {network.get('level')} dBm\")\n\n# Get connection info\ninfo = droid.wifiGetConnectionInfo().result\nif info:\n    print(f\"Connected to: {info.get('ssid')}\")\n    print(f\"BSSID: {info.get('bssid')}\")\n    print(f\"IP: {info.get('ip_address')}\")\n\n# Get DHCP info\ndhcp = droid.getDhcpInfo().result\nif dhcp:\n    print(f\"Gateway: {dhcp.get('gateway')}\")\n    print(f\"DNS: {dhcp.get('dns1')}\")\n\n# Get simplified connected info\nconnected = droid.getConnectedInfo().result\nprint(f\"SSID: {connected.get('ssid')}, Signal: {connected.get('level')} dBm\")\n\n# Disconnect and reconnect\ndroid.wifiDisconnect()\ntime.sleep(1)\ndroid.wifiReconnect()\n\n# Reassociate with access point\ndroid.wifiReassociate()\n\n# Check hotspot state\nap_state = droid.wifiGetApState().result\nprint(f\"Hotspot state: {ap_state}\")\n\n# Acquire WiFi lock for background operation\ndroid.wifiLockAcquireFull()\n# ... do work ...\ndroid.wifiLockRelease()\n\n# Or use scan-only lock for lighter background operation\ndroid.wifiLockAcquireScanOnly()\n# ... do scanning work ...\ndroid.wifiLockRelease()\n
      "},{"location":"qsl4a/core/android-base/","title":"Android Base Class","text":"

      The Android class is the core of QSL4A, providing the connection to the Android runtime and RPC mechanism.

      "},{"location":"qsl4a/core/android-base/#module-import","title":"Module Import","text":"
      # Full featured (recommended)\nimport androidhelper\ndroid = androidhelper.Android()\n\n# Minimal version (quick, single instance)\nimport android\ndroid = android.droid\n
      "},{"location":"qsl4a/core/android-base/#class-android","title":"Class: Android","text":""},{"location":"qsl4a/core/android-base/#constructor","title":"Constructor","text":"
      Android(addr=None)\n

      Parameters: - addr (tuple, optional): (HOST, PORT) address. If None, uses environment variables AP_HOST and AP_PORT

      Environment Variables: - AP_HOST - Server host address - AP_PORT - Server port - AP_HANDSHAKE - Authentication token

      "},{"location":"qsl4a/core/android-base/#core-methods","title":"Core Methods","text":""},{"location":"qsl4a/core/android-base/#_rpc","title":"_rpc()","text":"

      Internal RPC method for calling Android functions.

      _rpc(method, *args)\n

      Parameters: - method (str): Method name to call - *args: Variable arguments for the method

      Returns: Result namedtuple with fields: - id (int): Request ID - result: Method return value - error (str or None): Error message if failed

      "},{"location":"qsl4a/core/android-base/#getattr","title":"getattr()","text":"

      Dynamic method dispatcher. All Android methods are accessed via attribute lookup.

      # These are equivalent:\ndroid.makeToast(\"Hello\")\ndroid._rpc(\"makeToast\", \"Hello\")\n
      "},{"location":"qsl4a/core/android-base/#standalone-functions-androidpy","title":"Standalone Functions (android.py)","text":"

      When using the minimal android module:

      "},{"location":"qsl4a/core/android-base/#jsla","title":"jsla()","text":"

      Send JSON-RPC request and return raw response.

      jsla(method, *params)\n

      Returns: JSON string response

      "},{"location":"qsl4a/core/android-base/#rsla","title":"rsla()","text":"

      Send request and return result only.

      rsla(method, *params)\n

      Returns: Result value from RPC call

      "},{"location":"qsl4a/core/android-base/#esla","title":"esla()","text":"

      Send request, raise exception on error.

      esla(method, *params)\n

      Raises: Exception if error field is not None

      "},{"location":"qsl4a/core/android-base/#nsla","title":"nsla()","text":"

      Send request and return Result namedtuple.

      nsla(method, *params)\n

      Returns: Result namedtuple

      "},{"location":"qsl4a/core/android-base/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/android-base/#basic-connection","title":"Basic Connection","text":"
      import androidhelper\n\n# Connect to Android runtime\ndroid = androidhelper.Android()\n\n# Check connection by showing toast\ndroid.makeToast(\"Connected!\")\n
      "},{"location":"qsl4a/core/android-base/#error-handling","title":"Error Handling","text":"
      result = droid.someMethod()\nif result.error:\n    print(f\"Error: {result.error}\")\nelse:\n    print(f\"Success: {result.result}\")\n
      "},{"location":"qsl4a/core/android-base/#direct-rpc-call","title":"Direct RPC Call","text":"
      # Call any method directly\nresult = droid._rpc(\"makeToast\", \"Hello World\")\n
      "},{"location":"qsl4a/core/events/","title":"Event System","text":"

      QSL4A provides an event system for handling asynchronous events from Android, such as sensor updates, location changes, and custom broadcasts.

      "},{"location":"qsl4a/core/events/#event-basics","title":"Event Basics","text":"

      Events are stored in a buffer and can be polled or waited for. Each event has: - name: Event type/name - data: Event payload data - time: Timestamp

      "},{"location":"qsl4a/core/events/#event-methods","title":"Event Methods","text":""},{"location":"qsl4a/core/events/#eventclearbuffer","title":"eventClearBuffer()","text":"

      Clear all pending events from the buffer.

      eventClearBuffer()\n

      Returns: None

      "},{"location":"qsl4a/core/events/#eventpoll","title":"eventPoll()","text":"

      Poll for events in the buffer.

      eventPoll(number_of_events=1)\n

      Parameters: - number_of_events (int): Maximum events to retrieve (default: 1)

      Returns: List of event objects

      "},{"location":"qsl4a/core/events/#eventwait","title":"eventWait()","text":"

      Wait for any event.

      eventWait(timeout=None)\n

      Parameters: - timeout (int, optional): Timeout in seconds. None = wait forever

      Returns: Event object or None if timeout

      "},{"location":"qsl4a/core/events/#eventwaitfor","title":"eventWaitFor()","text":"

      Wait for a specific event.

      eventWaitFor(eventName, timeout=None)\n

      Parameters: - eventName (str): Name of event to wait for - timeout (int, optional): Timeout in seconds

      Returns: Event object or None if timeout

      "},{"location":"qsl4a/core/events/#eventpost","title":"eventPost()","text":"

      Post a custom event.

      eventPost(name, data, enqueue=None)\n

      Parameters: - name (str): Event name - data: Event data (any type) - enqueue (bool, optional): Add to queue if True

      "},{"location":"qsl4a/core/events/#receiveevent","title":"receiveEvent()","text":"

      Receive event (blocking).

      receiveEvent()\n

      Returns: Event object

      "},{"location":"qsl4a/core/events/#broadcast-events","title":"Broadcast Events","text":"

      Register for system broadcast events.

      "},{"location":"qsl4a/core/events/#eventregisterforbroadcast","title":"eventRegisterForBroadcast()","text":"

      Register to receive broadcast events.

      eventRegisterForBroadcast(category, enqueue=True)\n

      Parameters: - category (str): Broadcast category/action - enqueue (bool): Add to event queue

      "},{"location":"qsl4a/core/events/#eventunregisterforbroadcast","title":"eventUnregisterForBroadcast()","text":"

      Unregister from broadcast events.

      eventUnregisterForBroadcast(category)\n
      "},{"location":"qsl4a/core/events/#eventgetbrodcastcategories","title":"eventGetBrodcastCategories()","text":"

      Get registered broadcast categories.

      eventGetBrodcastCategories()\n

      Returns: List of registered categories

      "},{"location":"qsl4a/core/events/#event-dispatcher","title":"Event Dispatcher)","text":""},{"location":"qsl4a/core/events/#starteventdispatcher","title":"startEventDispatcher()","text":"

      Opens up a socket where you can read for events posted.)

      startEventDispatcher(port=0)\n

      Parameters: - port (int, optional): Port to listen on (default: 0 = auto-select)

      Returns: Port number being listened on

      "},{"location":"qsl4a/core/events/#stopeventdispatcher","title":"stopEventDispatcher()","text":"

      Stops the event server.)

      stopEventDispatcher()\n
      "},{"location":"qsl4a/core/events/#deprecated-methods","title":"Deprecated Methods","text":""},{"location":"qsl4a/core/events/#rpcpostevent","title":"rpcPostEvent()","text":"

      Post an event to the event queue. (Deprecated, use eventPost)

      rpcPostEvent(name, data)\n

      Parameters: - name (str): Event name - data: Event data

      "},{"location":"qsl4a/core/events/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/events/#basic-event-polling","title":"Basic Event Polling","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Clear old events\ndroid.eventClearBuffer()\n\n# Poll for events\nevents = droid.eventPoll(5).result\nfor event in events:\n    print(f\"Event: {event['name']}, Data: {event['data']}\")\n
      "},{"location":"qsl4a/core/events/#waiting-for-events","title":"Waiting for Events","text":"
      # Wait for any event with timeout\nevent = droid.eventWait(timeout=10).result\nif event:\n    print(f\"Got event: {event['name']}\")\n
      "},{"location":"qsl4a/core/events/#waiting-for-specific-event","title":"Waiting for Specific Event","text":"
      # Wait for sensor event\nevent = droid.eventWaitFor('screen', timeout=5).result\nif event:\n    print(f\"Screen event: {event['data']}\")\n
      "},{"location":"qsl4a/core/events/#posting-custom-events","title":"Posting Custom Events","text":"
      # Post custom event\ndroid.eventPost('my_event', {'key': 'value'})\n\n# Wait for it\nevent = droid.eventWaitFor('my_event', timeout=1).result\n
      "},{"location":"qsl4a/core/events/#broadcast-receiver","title":"Broadcast Receiver","text":"
      # Register for screen on/off events\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_ON')\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_OFF')\n\n# Wait for screen events\nwhile True:\n    event = droid.receiveEvent().result\n    if event['name'] == 'android.intent.action.SCREEN_ON':\n        print(\"Screen turned on\")\n    elif event['name'] == 'android.intent.action.SCREEN_OFF':\n        print(\"Screen turned off\")\n
      "},{"location":"qsl4a/core/events/#sensor-event-handling","title":"Sensor Event Handling","text":"
      # Start sensing\ndroid.startSensingTimed(1, 250)\n\n# Process sensor events\nfor _ in range(100):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'sensors':\n        data = event['data']\n        print(f\"Accel: {data['xforce']}, {data['yforce']}, {data['zforce']}\")\n\ndroid.stopSensing()\n
      "},{"location":"qsl4a/core/events/#common-event-types","title":"Common Event Types","text":"Event Name Description Source sensors Sensor data update startSensing* location GPS location update startLocating phone Phone state change startTrackingPhoneState signal Signal strength change startTrackingSignalStrength screen Screenshot ready fullGetScreenShot dialog Dialog response dialogShow*"},{"location":"qsl4a/core/events/#event-data-structure","title":"Event Data Structure","text":"
      {\n    'name': 'event_name',\n    'data': {\n        # Event-specific data\n    },\n    'time': 1234567890  # Timestamp\n}\n
      "},{"location":"qsl4a/core/intent/","title":"Intent System","text":"

      Android Intents are used to start activities, send broadcasts, and communicate between apps. QSL4A provides full Intent support through the Intent module.

      "},{"location":"qsl4a/core/intent/#module-import","title":"Module Import","text":"
      import androidhelper\ndon = androidhelper.Android()\n
      "},{"location":"qsl4a/core/intent/#intent-constants","title":"Intent Constants","text":"

      Access via droid.Intent:

      "},{"location":"qsl4a/core/intent/#actions","title":"Actions","text":"Constant Value Usage ACTION_MAIN android.intent.action.MAIN App entry point ACTION_VIEW android.intent.action.VIEW View content ACTION_EDIT android.intent.action.EDIT Edit content ACTION_PICK android.intent.action.PICK Pick item ACTION_SEND android.intent.action.SEND Share content ACTION_SEARCH android.intent.action.SEARCH Search"},{"location":"qsl4a/core/intent/#flags","title":"Flags","text":"Constant Value Usage FLAG_ACTIVITY_NEW_TASK 268435456 Start new task FLAG_ACTIVITY_CLEAR_TASK 32768 Clear task stack FLAG_ACTIVITY_NEW_DOCUMENT 524288 New document mode"},{"location":"qsl4a/core/intent/#extras","title":"Extras","text":"Constant Usage EXTRA_TEXT Text content EXTRA_STREAM File URI EXTRA_SUBJECT Subject line EXTRA_EMAIL Email address"},{"location":"qsl4a/core/intent/#core-methods","title":"Core Methods","text":""},{"location":"qsl4a/core/intent/#makeintent","title":"makeIntent()","text":"

      Create an Intent object.

      makeIntent(action, uri=None, type=None, extras=None, categories=None,\n           packagename=None, classname=None, flags=None)\n

      Parameters: - action (str): Intent action (e.g., droid.Intent.ACTION_VIEW) - uri (str, optional): Data URI - type (str, optional): MIME type - extras (dict, optional): Extra data - categories (list, optional): Intent categories - packagename (str, optional): Target package - classname (str, optional): Target class - flags (int, optional): Intent flags

      Returns: Intent object

      "},{"location":"qsl4a/core/intent/#startactivityintent","title":"startActivityIntent()","text":"

      Start an Activity with an Intent.

      startActivityIntent(intent, wait=None)\n

      Parameters: - intent: Intent object from makeIntent() - wait (bool, optional): Block until activity closes

      "},{"location":"qsl4a/core/intent/#startactivityforresultintent","title":"startActivityForResultIntent()","text":"

      Start activity and wait for result.

      startActivityForResultIntent(intent)\n

      Returns: Activity result

      "},{"location":"qsl4a/core/intent/#sendbroadcastintent","title":"sendBroadcastIntent()","text":"

      Send a broadcast.

      sendBroadcastIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#view","title":"view()","text":"

      View content by URI.

      view(uri, type=None, extras=None)\n
      "},{"location":"qsl4a/core/intent/#pick","title":"pick()","text":"

      Pick content from URI.

      pick(uri)\n
      "},{"location":"qsl4a/core/intent/#common-intent-methods","title":"Common Intent Methods)","text":""},{"location":"qsl4a/core/intent/#scanbarcode","title":"scanBarcode()","text":"

      Launch the barcode scanner.

      scanBarcode()\n

      Returns: Scanned barcode string

      "},{"location":"qsl4a/core/intent/#send","title":"send()","text":"

      Send content via share intent.

      send(type, content)\n

      Parameters: - type (str): MIME type - content (str): Content to share

      "},{"location":"qsl4a/core/intent/#sendtext","title":"sendText()","text":"

      Send text content.

      sendText(text)\n

      Parameters: - text (str): Text to send

      "},{"location":"qsl4a/core/intent/#sendemail","title":"sendEmail()","text":"

      Send an email.

      sendEmail(to, subject, body, attachment=None)\n

      Parameters: - to (str or list): Recipient email address(es) - subject (str): Email subject - body (str): Email body - attachment (str, optional): Attachment file path

      "},{"location":"qsl4a/core/intent/#pathtouri","title":"pathToUri()","text":"

      Convert file path to content URI.

      pathToUri(path)\n

      Parameters: - path (str): File path

      Returns: Content URI string

      "},{"location":"qsl4a/core/intent/#openfile","title":"openFile()","text":"

      Open a file with appropriate app.

      openFile(path)\n

      Parameters: - path (str): File path to open

      "},{"location":"qsl4a/core/intent/#sendfile","title":"sendFile()","text":"

      Send a file via share intent.

      sendFile(path)\n

      Parameters: - path (str): File path to send

      "},{"location":"qsl4a/core/intent/#getpathtype","title":"getPathType()","text":"

      Get the MIME type for a file path.

      getPathType(path)\n

      Parameters: - path (str): File path

      Returns: MIME type string

      "},{"location":"qsl4a/core/intent/#viewmap","title":"viewMap()","text":"

      Open map at a location.

      viewMap(latitude, longitude)\n

      Parameters: - latitude (float): Latitude - longitude (float): Longitude

      "},{"location":"qsl4a/core/intent/#viewcontacts","title":"viewContacts()","text":"

      Open the contacts app.

      viewContacts()\n
      "},{"location":"qsl4a/core/intent/#search","title":"search()","text":"

      Perform a web search.

      search(query)\n

      Parameters: - query (str): Search query

      "},{"location":"qsl4a/core/intent/#viewhtml","title":"viewHtml()","text":"

      View HTML content.

      viewHtml(content, encoding=None)\n

      Parameters: - content (str): HTML content - encoding (str, optional): Character encoding

      "},{"location":"qsl4a/core/intent/#webviewshow","title":"webViewShow()","text":"

      Display web content in WebView. Deprecated, use viewHtml.

      webViewShow(url)\n

      Parameters: - url (str): Web page URL

      "},{"location":"qsl4a/core/intent/#editoropen","title":"editorOpen()","text":"

      Open a text editor.

      editorOpen(path=None, create=False)\n

      Parameters: - path (str, optional): File path to edit - create (bool, optional): Create if doesn't exist

      "},{"location":"qsl4a/core/intent/#helper-class-uri","title":"Helper Class: Uri","text":"

      Create URI objects for Intents:

      from androidhelper.Intent import Uri\n\nuri = Uri(\"file:///sdcard/test.txt\")\n
      "},{"location":"qsl4a/core/intent/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/intent/#open-web-page","title":"Open Web Page","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"http://www.example.com\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#share-text","title":"Share Text","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_TEXT: \"Hello from QPython!\",\n        droid.Intent.EXTRA_SUBJECT: \"Test\"\n    },\n    type=\"text/plain\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#open-file","title":"Open File","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"file:///sdcard/document.pdf\",\n    type=\"application/pdf\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#pick-contact","title":"Pick Contact","text":"
      result = droid.pickContact()\ncontact_uri = result.result\n
      "},{"location":"qsl4a/core/intent/#send-email","title":"Send Email","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_EMAIL: [\"test@example.com\"],\n        droid.Intent.EXTRA_SUBJECT: \"Hello\",\n        droid.Intent.EXTRA_TEXT: \"Message body\"\n    },\n    type=\"message/rfc822\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#open-app","title":"Open App","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_MAIN,\n    packagename=\"com.android.settings\",\n    classname=\"com.android.settings.Settings\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/hardware/bluetooth/","title":"Bluetooth API","text":"

      Control Bluetooth adapter and communicate with Bluetooth devices.

      "},{"location":"qsl4a/hardware/bluetooth/#adapter-control","title":"Adapter Control","text":""},{"location":"qsl4a/hardware/bluetooth/#togglebluetoothstate","title":"toggleBluetoothState()","text":"

      Turn Bluetooth on/off.

      toggleBluetoothState(enabled=None, prompt=True)\n

      Parameters: - enabled (bool): True=on, False=off, None=toggle - prompt (bool): Show user prompt

      "},{"location":"qsl4a/hardware/bluetooth/#checkbluetoothstate","title":"checkBluetoothState()","text":"

      Check if Bluetooth is enabled.

      checkBluetoothState()\n

      Returns: True/False

      "},{"location":"qsl4a/hardware/bluetooth/#getlocalname","title":"GetLocalName()","text":"

      Get Bluetooth device name.

      GetLocalName()\n
      "},{"location":"qsl4a/hardware/bluetooth/#setlocalname","title":"SetLocalName()","text":"

      Set Bluetooth device name.

      SetLocalName(name)\n
      "},{"location":"qsl4a/hardware/bluetooth/#getscanmode","title":"GetScanMode()","text":"

      Get discoverability mode.

      GetScanMode()\n

      Returns: - -1: Disabled - 0: Non-discoverable, non-connectable - 1: Connectable, non-discoverable - 3: Connectable and discoverable

      "},{"location":"qsl4a/hardware/bluetooth/#makediscoverable","title":"MakeDiscoverable()","text":"

      Make device discoverable.

      MakeDiscoverable(duration=300)\n

      Parameters: - duration (int): Seconds to be discoverable

      "},{"location":"qsl4a/hardware/bluetooth/#discovery","title":"Discovery","text":""},{"location":"qsl4a/hardware/bluetooth/#discoverystart","title":"DiscoveryStart()","text":"

      Start device discovery.

      DiscoveryStart()\n
      "},{"location":"qsl4a/hardware/bluetooth/#discoverycancel","title":"DiscoveryCancel()","text":"

      Cancel discovery.

      DiscoveryCancel()\n
      "},{"location":"qsl4a/hardware/bluetooth/#getreceiveddevices","title":"GetReceivedDevices()","text":"

      Get discovered devices.

      GetReceivedDevices()\n

      Returns: List of device info dicts

      "},{"location":"qsl4a/hardware/bluetooth/#getbondeddevices","title":"GetBondedDevices()","text":"

      Get paired devices.

      GetBondedDevices()\n

      Returns: List of paired device info

      "},{"location":"qsl4a/hardware/bluetooth/#connection","title":"Connection","text":""},{"location":"qsl4a/hardware/bluetooth/#connect","title":"Connect()","text":"

      Connect to a device.

      Connect(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", address=None)\n

      Parameters: - uuid (str): Service UUID - address (str): Device address (None = show picker)

      Returns: True if successful

      "},{"location":"qsl4a/hardware/bluetooth/#accept","title":"Accept()","text":"

      Accept incoming connection.

      Accept(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", timeout=0)\n
      "},{"location":"qsl4a/hardware/bluetooth/#activeconnections","title":"ActiveConnections()","text":"

      Check active connections.

      ActiveConnections()\n
      "},{"location":"qsl4a/hardware/bluetooth/#stop","title":"Stop()","text":"

      Disconnect.

      Stop(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#communication","title":"Communication","text":""},{"location":"qsl4a/hardware/bluetooth/#write","title":"Write()","text":"

      Send ASCII data.

      Write(ascii, connID=\"\")\n
      "},{"location":"qsl4a/hardware/bluetooth/#writebinary","title":"WriteBinary()","text":"

      Send binary data (base64 encoded).

      WriteBinary(base64, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#read","title":"Read()","text":"

      Read ASCII data.

      Read(bufferSize=4096, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readbinary","title":"ReadBinary()","text":"

      Read binary data.

      ReadBinary(bufferSize=4096, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readline","title":"ReadLine()","text":"

      Read line.

      ReadLine(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readready","title":"ReadReady()","text":"

      Check if data available.

      ReadReady(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Enable Bluetooth\ndroid.toggleBluetoothState(True)\n\n# Get paired devices\ndevices = droid.GetBondedDevices().result\nfor dev in devices:\n    print(f\"{dev['name']}: {dev['address']}\")\n\n# Connect to device\ndroid.Connect(address=\"00:11:22:33:44:55\")\n\n# Send data\ndroid.Write(\"Hello Bluetooth!\")\n\n# Read response\ndata = droid.Read(1024).result\n
      "},{"location":"qsl4a/hardware/camera/","title":"Camera API","text":"

      Capture photos and record video.

      "},{"location":"qsl4a/hardware/camera/#photo-capture","title":"Photo Capture","text":""},{"location":"qsl4a/hardware/camera/#takepicture","title":"takePicture()","text":"

      Take a photo using the default camera.

      takePicture(path=None)\n

      Parameters: - path (str, optional): Save path. If None, returns image data

      Returns: Image path or image data

      "},{"location":"qsl4a/hardware/camera/#cameracapturepicture","title":"cameraCapturePicture()","text":"

      Capture picture with advanced camera controls.

      cameraCapturePicture(targetPath=None, cameraId=0, useAutoFocus=True)\n

      Parameters: - targetPath (str, optional): Save path - cameraId (int): Camera to use (0 = back, 1 = front) - useAutoFocus (bool): Enable auto focus

      Returns: Captured image path

      "},{"location":"qsl4a/hardware/camera/#camerasettorchmode","title":"cameraSetTorchMode()","text":"

      Control camera flashlight/torch.

      cameraSetTorchMode(enabled)\n

      Parameters: - enabled (bool): True to turn on, False to turn off

      Returns: True if successful

      "},{"location":"qsl4a/hardware/camera/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

      Capture screenshot.

      imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

      Parameters: - path (str, optional): Save path - delayMilliSec (int): Delay before capture

      "},{"location":"qsl4a/hardware/camera/#video-recording","title":"Video Recording","text":""},{"location":"qsl4a/hardware/camera/#takevideo","title":"takeVideo()","text":"

      Record video using default settings.

      takeVideo(path=None, quality=1)\n

      Parameters: - path (str, optional): Save path - quality (int): Video quality (0-4) - 0: 160x120 - 1: 320x240 - 2: 352x288 - 3: 640x480 - 4: 800x480

      "},{"location":"qsl4a/hardware/camera/#recordercapturevideo","title":"recorderCaptureVideo()","text":"

      Capture video with advanced controls.

      recorderCaptureVideo(targetPath=None, duration=10, cameraId=0, quality=8)\n

      Parameters: - targetPath (str, optional): Save path - duration (int): Recording duration in seconds (default: 10) - cameraId (int): Camera to use (0 = back, 1 = front) - quality (int): Video quality (0-8, higher is better)

      Returns: Video file path

      "},{"location":"qsl4a/hardware/camera/#recordaudio","title":"recordAudio()","text":"

      Record audio.

      recordAudio()\n

      Returns: Audio file path

      "},{"location":"qsl4a/hardware/camera/#screen-recording","title":"Screen Recording","text":""},{"location":"qsl4a/hardware/camera/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

      Start screen recording.

      recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

      Parameters: - path (str): Save path - audio (int): Audio source (0=none, 1=mic, 2=internal) - targetPixels (int): Resolution - frameRate (int): FPS - bitRate (int): Bitrate - rotation (bool): Rotate output - autoStart (bool): Start immediately

      "},{"location":"qsl4a/hardware/camera/#recorderstart","title":"recorderStart()","text":"

      Start recording.

      recorderStart()\n
      "},{"location":"qsl4a/hardware/camera/#recorderpause","title":"recorderPause()","text":"

      Pause recording.

      recorderPause()\n
      "},{"location":"qsl4a/hardware/camera/#recorderresume","title":"recorderResume()","text":"

      Resume recording.

      recorderResume()\n
      "},{"location":"qsl4a/hardware/camera/#audio-volume-detection","title":"Audio Volume Detection","text":""},{"location":"qsl4a/hardware/camera/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

      Start volume detection.

      recorderSoundVolumeDetect(interval=100)\n
      "},{"location":"qsl4a/hardware/camera/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

      Get current volume in dB.

      recorderSoundVolumeGetDb()\n
      "},{"location":"qsl4a/hardware/camera/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Take photo with default camera\nphoto_path = droid.takePicture(\"/sdcard/photo.jpg\").result\nprint(f\"Photo saved: {photo_path}\")\n\n# Take photo with front camera and auto focus\ncamera_path = droid.cameraCapturePicture(\"/sdcard/selfie.jpg\", cameraId=1, useAutoFocus=True).result\nprint(f\"Front camera photo: {camera_path}\")\n\n# Control flashlight\ndroid.cameraSetTorchMode(True)  # Turn on flashlight\n\n# Record video with default settings\nvideo_path = droid.takeVideo(\"/sdcard/video.mp4\", quality=3).result\nprint(f\"Video saved: {video_path}\")\n\n# Record video with advanced controls\nvideo_path = droid.recorderCaptureVideo(\"/sdcard/movie.mp4\", duration=30, cameraId=0, quality=8).result\n\n# Screenshot\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n
      "},{"location":"qsl4a/hardware/recorder/","title":"Audio Recorder API","text":"

      Record audio from microphone and device screen.

      "},{"location":"qsl4a/hardware/recorder/#audio-recording","title":"Audio Recording","text":""},{"location":"qsl4a/hardware/recorder/#recordaudio","title":"recordAudio()","text":"

      Record audio from microphone.

      recordAudio()\n

      Returns: Path to recorded audio file

      "},{"location":"qsl4a/hardware/recorder/#recorderstartmicrophone","title":"recorderStartMicrophone()","text":"

      Start recording from microphone to a specific file.

      recorderStartMicrophone(targetPath=None)\n

      Parameters: - targetPath (str, optional): Path to save the recording

      "},{"location":"qsl4a/hardware/recorder/#screen-recording","title":"Screen Recording","text":""},{"location":"qsl4a/hardware/recorder/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

      Start screen recording with audio.

      recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

      Parameters: - path (str): Save path for video file - audio (int): Audio source (0=none, 1=mic, 2=internal audio) - targetPixels (int): Target resolution in pixels - frameRate (int): Frames per second (default: 30) - bitRate (int): Video bitrate - rotation (bool): Rotate output video - autoStart (bool): Start recording immediately

      Returns: Result of operation

      "},{"location":"qsl4a/hardware/recorder/#recorderstart","title":"recorderStart()","text":"

      Start the screen recording (when autoStart=False).

      recorderStart()\n
      "},{"location":"qsl4a/hardware/recorder/#recorderpause","title":"recorderPause()","text":"

      Pause ongoing screen recording.

      recorderPause()\n
      "},{"location":"qsl4a/hardware/recorder/#recorderresume","title":"recorderResume()","text":"

      Resume paused screen recording.

      recorderResume()\n
      "},{"location":"qsl4a/hardware/recorder/#audio-volume-detection","title":"Audio Volume Detection","text":""},{"location":"qsl4a/hardware/recorder/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

      Start monitoring sound volume level.

      recorderSoundVolumeDetect(interval=100)\n

      Parameters: - interval (int): Detection interval in milliseconds (default: 100)

      "},{"location":"qsl4a/hardware/recorder/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

      Get current sound volume in decibels.

      recorderSoundVolumeGetDb()\n

      Returns: Current volume level in dB

      "},{"location":"qsl4a/hardware/recorder/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Record audio from microphone\nprint(\"Recording audio...\")\naudio_path = droid.recordAudio().result\nprint(f\"Saved to: {audio_path}\")\n\n# Record microphone to specific file\ndroid.recorderStartMicrophone(\"/sdcard/my_recording.mp3\")\ntime.sleep(5)\ndroid.recorderStop()\n\n# Record screen with audio\nprint(\"Starting screen recording...\")\ndroid.recorderStartScreenRecord(\n    path=\"/sdcard/screen_record.mp4\",\n    audio=1,\n    frameRate=30,\n    autoStart=True\n)\ntime.sleep(10)\ndroid.recorderStop()\n\n# Monitor sound volume\ndroid.recorderSoundVolumeDetect(interval=100)\ntime.sleep(3)\nvolume = droid.recorderSoundVolumeGetDb().result\nprint(f\"Current volume: {volume} dB\")\n
      "},{"location":"qsl4a/hardware/usbserial/","title":"USB Host Serial API","text":"

      Communicate with USB serial devices (requires USB OTG support and Android 3.1+).

      "},{"location":"qsl4a/hardware/usbserial/#usb-serial-methods","title":"USB Serial Methods)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialopen","title":"usbHostSerialOpen()","text":"

      Open a connection to a USB serial device.

      usbHostSerialOpen(device, baudRate=9600)\n

      Parameters: - device (str): USB device path or identifier - baudRate (int): Baud rate (default: 9600)

      Returns: True if opened successfully

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialclose","title":"usbHostSerialClose()","text":"

      Close the USB serial connection.

      usbHostSerialClose()\n
      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialread","title":"usbHostSerialRead()","text":"

      Read data from USB serial.

      usbHostSerialRead(bufferSize=1024)\n

      Parameters: - bufferSize (int): Maximum bytes to read (default: 1024)

      Returns: String read data

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwrite","title":"usbHostSerialWrite()","text":"

      Write data to USB serial.

      usbHostSerialWrite(data)\n

      Parameters: - data (str): String data to write

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialavailable","title":"usbHostSerialAvailable()","text":"

      Check if data is available to read.

      usbHostSerialAvailable()\n

      Returns: Number of bytes available

      "},{"location":"qsl4a/hardware/usbserial/#configuration-methods","title":"Configuration Methods)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetbaudrate","title":"usbHostSerialSetBaudRate()","text":"

      Set the baud rate.

      usbHostSerialSetBaudRate(baudRate)\n

      Parameters: - baudRate (int): Baud rate

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetdatabits","title":"usbHostSerialSetDataBits()","text":"

      Set data bits (5, 6, 7, or 8).

      usbHostSerialSetDataBits(dataBits)\n

      Parameters: - dataBits (int): Data bits (5-8)

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetstopbits","title":"usbHostSerialSetStopBits()","text":"

      Set stop bits (1, 1.5, or 2).

      usbHostSerialSetStopBits(stopBits)\n

      Parameters: - stopBits (float): Stop bits (1, 1.5, or 2)

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetparity","title":"usbHostSerialSetParity()","text":"

      Set parity (none, odd, even, mark, space).

      usbHostSerialSetParity(parity)\n

      Parameters: - parity (str): Parity mode ('none', 'odd', 'even', 'mark', 'space')

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetflowcontrol","title":"usbHostSerialSetFlowControl()","text":"

      Set flow control (none, hardware, software).

      usbHostSerialSetFlowControl(flowControl)\n

      Parameters: - flowControl (str): Flow control mode ('none', 'hardware', 'software')

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialreadhex","title":"usbHostSerialReadHex()","text":"

      Read data as hex string.

      usbHostSerialReadHex(bufferSize=1024)\n

      Parameters: - bufferSize (int): Maximum bytes to read

      Returns: Hex string

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwritehex","title":"usbHostSerialWriteHex()","text":"

      Write data from hex string.

      usbHostSerialWriteHex(hexString)\n

      Parameters: - hexString (str): Hex string to write

      "},{"location":"qsl4a/hardware/usbserial/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Open USB serial connection\nif droid.usbHostSerialOpen(\"/dev/bus/usb/001/001\", 115200).result:\n    print(\"USB serial opened\")\n\n    # Write data\n    droid.usbHostSerialWrite(\"AT\\r\")\n\n    # Read response\n    response = droid.usbHostSerialRead(1024).result\n    print(f\"Response: {response}\")\n\n    # Or use hex\n    droid.usbHostSerialWriteHex(\"41540D0A\")  # \"AT\\r\\n\"\n\n    # Close connection\n    droid.usbHostSerialClose()\n

      Note: USB serial requires: - Android 3.1+ (API 12) - USB OTG cable/adapter - USB host mode support on device - Compatible serial device

      "},{"location":"qsl4a/hardware/webcam/","title":"Webcam API","text":"

      Stream video from the device camera using MJPEG.

      "},{"location":"qsl4a/hardware/webcam/#mjpeg-stream-methods","title":"MJPEG Stream Methods","text":""},{"location":"qsl4a/hardware/webcam/#webcamstart","title":"webcamStart()","text":"

      Start an MJPEG stream from the webcam.

      webcamStart(resolutionLevel=0, jpegQuality=20, port=0)\n

      Parameters: - resolutionLevel (int): Resolution level (default: 0) - jpegQuality (int): JPEG quality 1-100 (default: 20) - port (int): Port number (default: 0 = auto)

      Returns: Tuple of (address, port) for the stream

      "},{"location":"qsl4a/hardware/webcam/#webcamadjustquality","title":"webcamAdjustQuality()","text":"

      Adjust the quality of an active webcam stream.

      webcamAdjustQuality(resolutionLevel=0, jpegQuality=20)\n

      Parameters: - resolutionLevel (int): Resolution level - jpegQuality (int): JPEG quality 1-100

      "},{"location":"qsl4a/hardware/webcam/#webcamstop","title":"webcamStop()","text":"

      Stop the webcam stream.

      webcamStop()\n
      "},{"location":"qsl4a/hardware/webcam/#camera-preview-methods","title":"Camera Preview Methods","text":""},{"location":"qsl4a/hardware/webcam/#camerastartpreview","title":"cameraStartPreview()","text":"

      Start camera preview mode with event generation.

      cameraStartPreview(resolutionLevel=0, jpegQuality=20, filepath=None)\n

      Parameters: - resolutionLevel (int): Resolution level (default: 0) - jpegQuality (int): JPEG quality (default: 20) - filepath (str, optional): File path to save preview frames

      Returns: True if successful

      Note: Generates 'preview' events with frame data.

      "},{"location":"qsl4a/hardware/webcam/#camerastoppreview","title":"cameraStopPreview()","text":"

      Stop the camera preview.

      cameraStopPreview()\n
      "},{"location":"qsl4a/hardware/webcam/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start webcam stream\nstream_info = droid.webcamStart(\n    resolutionLevel=0,\n    jpegQuality=30,\n    port=8080\n).result\nprint(f\"Stream available at {stream_info[0]}:{stream_info[1]}\")\n\n# Adjust quality while streaming\ntime.sleep(5)\ndroid.webcamAdjustQuality(resolutionLevel=1, jpegQuality=50)\n\n# Stop when done\ndroid.webcamStop()\n\n# Or use preview mode\nprint(\"Starting preview...\")\ndroid.cameraStartPreview()\n\n# Wait for preview events\nfor i in range(10):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'preview':\n        print(f\"Got preview frame: {event['data']}\")\n\ndroid.cameraStopPreview()\n
      "},{"location":"qsl4a/media/image/","title":"Image Processing API","text":"

      Compress and process images.

      "},{"location":"qsl4a/media/image/#image-compression","title":"Image Compression","text":""},{"location":"qsl4a/media/image/#imagecompress","title":"imageCompress()","text":"

      Compress image file.

      imageCompress(srcPath, destPath, targetByteSize=0, targetWidth=0, targetHeight=0)\n

      Parameters: - srcPath (str): Source image path - destPath (str): Output path - targetByteSize (int): Target file size in bytes (0 = no limit) - targetWidth (int): Target width (0 = original) - targetHeight (int): Target height (0 = original)

      Returns: Compressed image path

      "},{"location":"qsl4a/media/image/#screenshot","title":"Screenshot","text":""},{"location":"qsl4a/media/image/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

      Capture screen.

      imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

      Parameters: - path (str): Save path - delayMilliSec (int): Delay before capture

      Returns: Screenshot path

      "},{"location":"qsl4a/media/image/#video-playback","title":"Video Playback","text":""},{"location":"qsl4a/media/image/#videoplay","title":"videoPlay()","text":"

      Play video file in fullscreen mode.

      videoPlay(path, wait=True)\n

      Parameters: - path (str): Video file path - wait (bool): Wait for playback to complete (default: True)

      "},{"location":"qsl4a/media/image/#barcode-scanning","title":"Barcode Scanning","text":""},{"location":"qsl4a/media/image/#scanbarcodefromimage","title":"scanBarcodeFromImage()","text":"

      Scan barcode/QR code from image file.

      scanBarcodeFromImage(path, compressRatio=0, x=0, y=0, width=0, height=0)\n

      Parameters: - path (str): Image file path - compressRatio (int): Compression ratio (0 = no compression) - x, y, width, height (int): Region to scan (0 = full image)

      Returns: Scanned barcode content

      "},{"location":"qsl4a/media/image/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Take screenshot\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n\n# Compress image\ncompressed = droid.imageCompress(\n    \"/sdcard/large_photo.jpg\",\n    \"/sdcard/compressed.jpg\",\n    targetByteSize=102400,  # Target ~100KB\n    targetWidth=1920,\n    targetHeight=1080\n).result\nprint(f\"Saved: {compressed}\")\n\n# Play video\nvideo_path = \"/sdcard/movie.mp4\"\ndroid.videoPlay(video_path, wait=True)\n\n# Scan barcode from image\nresult = droid.scanBarcodeFromImage(\"/sdcard/qr_code.png\").result\nprint(f\"Barcode: {result}\")\n
      "},{"location":"qsl4a/media/mediaplayer/","title":"Media Player API","text":"

      Control audio and video playback.

      "},{"location":"qsl4a/media/mediaplayer/#playback-control","title":"Playback Control","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplay","title":"mediaPlay()","text":"

      Play media file.

      mediaPlay(url, tag=\"default\", play=True)\n

      Parameters: - url (str): Media file path or URL - tag (str): Player identifier - play (bool): Auto-start playback

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaystart","title":"mediaPlayStart()","text":"

      Start playback.

      mediaPlayStart(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplaypause","title":"mediaPlayPause()","text":"

      Pause playback.

      mediaPlayPause(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplayclose","title":"mediaPlayClose()","text":"

      Close player.

      mediaPlayClose(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplayseek","title":"mediaPlaySeek()","text":"

      Seek to position.

      mediaPlaySeek(msec, tag=\"default\")\n

      Parameters: - msec (int): Position in milliseconds

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaysetlooping","title":"mediaPlaySetLooping()","text":"

      Set loop mode.

      mediaPlaySetLooping(enabled, tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#player-info","title":"Player Info","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplayinfo","title":"mediaPlayInfo()","text":"

      Get playback info.

      mediaPlayInfo(tag=\"default\")\n

      Returns: Dict with duration, position, etc.

      "},{"location":"qsl4a/media/mediaplayer/#mediaisplaying","title":"mediaIsPlaying()","text":"

      Check if playing.

      mediaIsPlaying(tag=\"default\")\n

      Returns: True/False

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaylist","title":"mediaPlayList()","text":"

      List active players.

      mediaPlayList()\n
      "},{"location":"qsl4a/media/mediaplayer/#volume-control","title":"Volume Control","text":""},{"location":"qsl4a/media/mediaplayer/#getmediavolume","title":"getMediaVolume()","text":"

      Get media volume.

      getMediaVolume()\n

      Returns: Volume level (0-15)

      "},{"location":"qsl4a/media/mediaplayer/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

      Get max media volume.

      getMaxMediaVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#getringervolume","title":"getRingerVolume()","text":"

      Get ringer volume.

      getRingerVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

      Get max ringer volume.

      getMaxRingerVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#video-playback","title":"Video Playback","text":""},{"location":"qsl4a/media/mediaplayer/#videoplay","title":"videoPlay()","text":"

      Play video fullscreen.

      videoPlay(path, wait=True)\n

      Parameters: - path (str): Video file path - wait (bool): Wait for playback to complete

      "},{"location":"qsl4a/media/mediaplayer/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Play audio\ndroid.mediaPlay(\"/sdcard/music.mp3\", tag=\"music\")\n\n# Check status\nif droid.mediaIsPlaying(\"music\").result:\n    info = droid.mediaPlayInfo(\"music\").result\n    print(f\"Playing: {info}\")\n\n# Seek to 30 seconds\ndroid.mediaPlaySeek(30000, \"music\")\n\n# Close\ndroid.mediaPlayClose(\"music\")\n\n# Play video\ndroid.videoPlay(\"/sdcard/movie.mp4\", wait=True)\n
      "},{"location":"qsl4a/special/cipher/","title":"Cipher API","text":"

      Encryption and decryption utilities for secure data storage.

      "},{"location":"qsl4a/special/cipher/#initialization","title":"Initialization","text":""},{"location":"qsl4a/special/cipher/#cipherinit","title":"cipherInit()","text":"

      Initialize the cipher with encryption key and algorithm.

      cipherInit(key, algorithm=\"AES/CBC/PKCS5Padding\", encodingFormat=\"\", initialVector=\"\")\n

      Parameters: - key (str or bytes): Encryption key - algorithm (str): Cipher algorithm (default: \"AES/CBC/PKCS5Padding\") - encodingFormat (str): Encoding format - initialVector (str or bytes): Initial vector for encryption

      Returns: Initialization result

      Note: Must be called before any encrypt/decrypt operations.

      "},{"location":"qsl4a/special/cipher/#encryption-methods","title":"Encryption Methods","text":""},{"location":"qsl4a/special/cipher/#encryptstring","title":"encryptString()","text":"

      Encrypt a string.

      encryptString(plainText)\n

      Parameters: - plainText (str): Text to encrypt

      Returns: Encrypted string

      "},{"location":"qsl4a/special/cipher/#encryptbytes","title":"encryptBytes()","text":"

      Encrypt bytes data.

      encryptBytes(data)\n

      Parameters: - data (bytes): Data to encrypt

      Returns: Encrypted bytes

      "},{"location":"qsl4a/special/cipher/#encryptstringtofile","title":"encryptStringToFile()","text":"

      Encrypt string to file.

      encryptStringToFile(plainText, filePath)\n

      Parameters: - plainText (str): Text to encrypt - filePath (str): Output file path

      "},{"location":"qsl4a/special/cipher/#encryptbytestofile","title":"encryptBytesToFile()","text":"

      Encrypt bytes to file.

      encryptBytesToFile(data, filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryption-methods","title":"Decryption Methods","text":""},{"location":"qsl4a/special/cipher/#decryptstring","title":"decryptString()","text":"

      Decrypt to string.

      decryptString(cipherText)\n

      Parameters: - cipherText (str): Encrypted text

      Returns: Decrypted string

      "},{"location":"qsl4a/special/cipher/#decryptbytes","title":"decryptBytes()","text":"

      Decrypt to bytes.

      decryptBytes(data)\n

      Returns: Decrypted bytes

      "},{"location":"qsl4a/special/cipher/#decryptfiletostring","title":"decryptFileToString()","text":"

      Decrypt file to string.

      decryptFileToString(filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryptfiletobytes","title":"decryptFileToBytes()","text":"

      Decrypt file to bytes.

      decryptFileToBytes(filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryptfile","title":"decryptFile()","text":"

      Decrypt file to file.

      decryptFile(srcPath, destPath)\n
      "},{"location":"qsl4a/special/cipher/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Initialize cipher with your encryption key\ndroid.cipherInit(\"my_secret_key_1234\")\n\n# Encrypt string\nencrypted = droid.encryptString(\"Secret message!\").result\nprint(f\"Encrypted: {encrypted}\")\n\n# Decrypt string\ndecrypted = droid.decryptString(encrypted).result\nprint(f\"Decrypted: {decrypted}\")\n\n# Encrypt to file\ndroid.encryptStringToFile(\"My secret data\", \"/sdcard/secret.dat\")\n\n# Decrypt from file\ndata = droid.decryptFileToString(\"/sdcard/secret.dat\").result\nprint(data)\n\n# Initialize with custom algorithm and IV\ndroid.cipherInit(\n    key=\"my_key\",\n    algorithm=\"AES/CBC/PKCS5Padding\",\n    initialVector=\"0123456789abcdef\"\n)\n
      "},{"location":"qsl4a/special/pgptai/","title":"PGPT AI API","text":"

      Speech-to-text and AI services integration.

      "},{"location":"qsl4a/special/pgptai/#prerequisites","title":"Prerequisites","text":"
      pip install pgptAI\n
      "},{"location":"qsl4a/special/pgptai/#speech-recognition","title":"Speech Recognition","text":""},{"location":"qsl4a/special/pgptai/#speechtotext","title":"speechToText()","text":"

      Convert speech to text.

      speechToText(RecordSecond=10, AmrFile=None, Language=None)\n

      Parameters: - RecordSecond (int): Recording duration in seconds - AmrFile (str, optional): Existing audio file path - Language (str, optional): Language code ('en', 'zh')

      Returns: Transcribed text

      "},{"location":"qsl4a/special/pgptai/#text-to-speech","title":"Text to Speech","text":""},{"location":"qsl4a/special/pgptai/#texttospeech","title":"textToSpeech()","text":"

      Convert text to speech and optionally play it.

      textToSpeech(Text, AutoPlay=True, WavFile=None, VoiceName=None)\n

      Parameters: - Text (str): Text to convert to speech - AutoPlay (bool): Automatically play the generated audio (default: True) - WavFile (str, optional): Path to save the WAV file. If None, uses temporary file - VoiceName (str, optional): Voice name to use (e.g., 'en-US-JennyNeural', 'zh-CN-XiaoxiaoNeural')

      Returns: Dict with speech synthesis result including: - text: The input text - url: URL to download the audio file - WavFile: Path to the saved WAV file (if saved locally)

      "},{"location":"qsl4a/special/pgptai/#configuration","title":"Configuration","text":"

      The API uses configuration from /storage/emulated/0/Android/data/org.qpython.qpy/files/apigpt.conf:

      [speech]\nspeech_key = your_api_key\n

      Default voice settings: - English: en-US-JennyNeural - Chinese: zh-CN-XiaoxiaoNeural

      "},{"location":"qsl4a/special/pgptai/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Record and transcribe\nprint(\"Recording for 5 seconds...\")\ntext = droid.speechToText(RecordSecond=5, Language='en').result\nprint(f\"You said: {text}\")\n\n# Transcribe existing file\ntext = droid.speechToText(AmrFile=\"/sdcard/recording.amr\").result\nprint(f\"Transcription: {text}\")\n\n# Text to speech\ndroid.textToSpeech(\"Hello, this is a test message.\", AutoPlay=True, Language='en')\n\n# Text to speech with custom voice and save to file\nresult = droid.textToSpeech(\n    \"Welcome to QPython!\",\n    AutoPlay=False,\n    WavFile=\"/sdcard/welcome.wav\",\n    VoiceName=\"en-US-JennyNeural\"\n).result\nprint(f\"Audio saved to: {result.get('WavFile')}\")\n
      "},{"location":"qsl4a/special/pgptai/#class-usage","title":"Class Usage","text":"
      from androidhelper.pgptai import pgptai\nimport androidhelper\n\ndroid = androidhelper.Android()\nai = pgptai(droid)\n\n# Use speech recognition\ntext = ai.speechToText(RecordSecond=10)\n
      "},{"location":"qsl4a/storage/clipboard/","title":"Clipboard API","text":"

      Copy and paste text to system clipboard.

      "},{"location":"qsl4a/storage/clipboard/#methods","title":"Methods","text":""},{"location":"qsl4a/storage/clipboard/#setclipboard","title":"setClipboard()","text":"

      Copy text to clipboard.

      setClipboard(text)\n

      Parameters: - text (str): Text to copy

      Returns: True if success

      "},{"location":"qsl4a/storage/clipboard/#getclipboard","title":"getClipboard()","text":"

      Get text from clipboard.

      getClipboard()\n

      Returns: Clipboard text

      "},{"location":"qsl4a/storage/clipboard/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Copy to clipboard\ndroid.setClipboard(\"Hello from QPython!\")\n\n# Paste from clipboard\ntext = droid.getClipboard().result\nprint(f\"Clipboard: {text}\")\n
      "},{"location":"qsl4a/storage/documentfile/","title":"DocumentFile API","text":"

      File operations with SAF (Storage Access Framework) support for Android 4.4+.

      "},{"location":"qsl4a/storage/documentfile/#directory-operations","title":"Directory Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfilemkdir","title":"documentFileMkdir()","text":"

      Create directory.

      documentFileMkdir(Dir)\n

      Parameters: - Dir (str): Directory path

      Returns: True if success

      "},{"location":"qsl4a/storage/documentfile/#documentfilelistfiles","title":"documentFileListFiles()","text":"

      List files in directory.

      documentFileListFiles(Folder)\n

      Returns: List of files

      "},{"location":"qsl4a/storage/documentfile/#file-operations","title":"File Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfileexists","title":"documentFileExists()","text":"

      Check if file or directory exists.

      documentFileExists(path)\n

      Parameters: - path (str): File or directory path

      Returns: True if exists, False otherwise

      "},{"location":"qsl4a/storage/documentfile/#documentfileisfile","title":"documentFileIsFile()","text":"

      Check if path is a file.

      documentFileIsFile(path)\n

      Parameters: - path (str): Path to check

      Returns: True if file, False if not a file, None if not exists

      "},{"location":"qsl4a/storage/documentfile/#documentfileisdirectory","title":"documentFileIsDirectory()","text":"

      Check if path is a directory.

      documentFileIsDirectory(path)\n

      Parameters: - path (str): Path to check

      Returns: True if directory, False if not a directory, None if not exists

      "},{"location":"qsl4a/storage/documentfile/#documentfiledelete","title":"documentFileDelete()","text":"

      Delete file or directory.

      documentFileDelete(FileOrTree)\n

      Returns: True if success

      "},{"location":"qsl4a/storage/documentfile/#documentfilerenameto","title":"documentFileRenameTo()","text":"

      Rename or move file.

      documentFileRenameTo(Src, Dest)\n

      Returns: True if success

      "},{"location":"qsl4a/storage/documentfile/#documentfilecopy","title":"documentFileCopy()","text":"

      Copy file.

      documentFileCopy(SrcFileOrTree, DestFileOrTree)\n
      "},{"location":"qsl4a/storage/documentfile/#stream-operations","title":"Stream Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfileinputstream","title":"documentFileInputStream()","text":"

      Read file content.

      documentFileInputStream(srcFile, EncodingFormat=\"\", skip=None, length=None)\n

      Parameters: - srcFile (str): Source file - EncodingFormat (str): \"UTF-8\", \"GBK\", \"Base64\", or \"\" for bytes - skip (int): Skip bytes from start - length (int): Read length

      Returns: File content

      "},{"location":"qsl4a/storage/documentfile/#documentfileoutputstream","title":"documentFileOutputStream()","text":"

      Write file content.

      documentFileOutputStream(destFile, src, EncodingFormat=\"\", append=None)\n

      Parameters: - destFile (str): Destination file - src: Data to write - EncodingFormat (str): Encoding format - append (bool): Append mode

      "},{"location":"qsl4a/storage/documentfile/#file-information","title":"File Information","text":""},{"location":"qsl4a/storage/documentfile/#documentfilelength","title":"documentFileLength()","text":"

      Get file size in bytes.

      documentFileLength(path)\n

      Parameters: - path (str): File path

      Returns: File size in bytes (0 if not exists)

      "},{"location":"qsl4a/storage/documentfile/#documentfilelastmodified","title":"documentFileLastModified()","text":"

      Get last modified time.

      documentFileLastModified(path)\n

      Parameters: - path (str): File path

      Returns: Timestamp (0 if not exists)

      "},{"location":"qsl4a/storage/documentfile/#documentfilegetstat","title":"documentFileGetStat()","text":"

      Get comprehensive file statistics.

      documentFileGetStat(path)\n

      Parameters: - path (str): File path

      Returns: Dict with length, last modified, and read/write permissions, or None if not exists

      "},{"location":"qsl4a/storage/documentfile/#uri-operations","title":"URI Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfilegeturi","title":"documentFileGetUri()","text":"

      Get URI from path.

      documentFileGetUri(path, isDirectory=None)\n
      "},{"location":"qsl4a/storage/documentfile/#documentfileshowopen","title":"documentFileShowOpen()","text":"

      Show file picker.

      documentFileShowOpen()\n

      Returns: Selected file URI

      "},{"location":"qsl4a/storage/documentfile/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Create directory\ndroid.documentFileMkdir(\"/sdcard/MyFolder\")\n\n# List files\nfiles = droid.documentFileListFiles(\"/sdcard\").result\nfor f in files:\n    print(f)\n\n# Read file\ncontent = droid.documentFileInputStream(\n    \"/sdcard/test.txt\",\n    EncodingFormat=\"UTF-8\"\n).result\nprint(content)\n\n# Write file\ndroid.documentFileOutputStream(\n    \"/sdcard/output.txt\",\n    \"Hello World\",\n    EncodingFormat=\"UTF-8\"\n)\n
      "},{"location":"qsl4a/storage/preferences/","title":"Preferences API","text":"

      Store and retrieve data using Android SharedPreferences.

      "},{"location":"qsl4a/storage/preferences/#preference-methods","title":"Preference Methods","text":""},{"location":"qsl4a/storage/preferences/#prefgetvalue","title":"prefGetValue()","text":"

      Read a value from shared preferences.

      prefGetValue(key, filename=None)\n

      Parameters: - key (str): Preference key - filename (str, optional): Preference file name

      Returns: The stored value (any type)

      "},{"location":"qsl4a/storage/preferences/#prefputvalue","title":"prefPutValue()","text":"

      Write a value to shared preferences.

      prefPutValue(key, value, filename=None)\n

      Parameters: - key (str): Preference key - value (object): Value to store - filename (str, optional): Preference file name

      "},{"location":"qsl4a/storage/preferences/#prefgetall","title":"prefGetAll()","text":"

      Get all preference values.

      prefGetAll(filename=None)\n

      Parameters: - filename (str, optional): Preference file name

      Returns: Map of all preferences

      "},{"location":"qsl4a/storage/preferences/#prefremovevalue","title":"prefRemoveValue()","text":"

      Remove a value from shared preferences.

      prefRemoveValue(key, filename=None)\n

      Parameters: - key (str): Preference key to remove - filename (str, optional): Preference file name

      "},{"location":"qsl4a/storage/preferences/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Store values\ndroid.prefPutValue(\"username\", \"alice\")\ndroid.prefPutValue(\"score\", 100)\ndroid.prefPutValue(\"enabled\", True)\n\n# Read a specific value\nusername = droid.prefGetValue(\"username\").result\nprint(f\"Username: {username}\")\n\n# Get all preferences\nall_prefs = droid.prefGetAll().result\nprint(f\"All prefs: {all_prefs}\")\n\n# Remove a value\ndroid.prefRemoveValue(\"score\")\n\n# Use custom filename\ndroid.prefPutValue(\"token\", \"abc123\", filename=\"auth.prefs\")\ntoken = droid.prefGetValue(\"token\", filename=\"auth.prefs\").result\n
      "},{"location":"qsl4a/system/activityresult/","title":"Activity Result API","text":"

      Set activity results for scripts launched via startActivityForResult.

      "},{"location":"qsl4a/system/activityresult/#result-methods","title":"Result Methods","text":""},{"location":"qsl4a/system/activityresult/#setresultboolean","title":"setResultBoolean()","text":"

      Set a boolean result.

      setResultBoolean(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (bool): Boolean result value

      "},{"location":"qsl4a/system/activityresult/#setresultbyte","title":"setResultByte()","text":"

      Set a byte result.

      setResultByte(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (int): Byte result value

      "},{"location":"qsl4a/system/activityresult/#setresultshort","title":"setResultShort()","text":"

      Set a short result.

      setResultShort(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (int): Short result value

      "},{"location":"qsl4a/system/activityresult/#setresultchar","title":"setResultChar()","text":"

      Set a character result.

      setResultChar(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (str): Character result value

      "},{"location":"qsl4a/system/activityresult/#setresultinteger","title":"setResultInteger()","text":"

      Set an integer result.

      setResultInteger(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (int): Integer result value

      "},{"location":"qsl4a/system/activityresult/#setresultlong","title":"setResultLong()","text":"

      Set a long result.

      setResultLong(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (int): Long result value

      "},{"location":"qsl4a/system/activityresult/#setresultfloat","title":"setResultFloat()","text":"

      Set a float result.

      setResultFloat(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (float): Float result value

      "},{"location":"qsl4a/system/activityresult/#setresultdouble","title":"setResultDouble()","text":"

      Set a double result.

      setResultDouble(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (float): Double result value

      "},{"location":"qsl4a/system/activityresult/#setresultstring","title":"setResultString()","text":"

      Set a string result.

      setResultString(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (str): String result value

      "},{"location":"qsl4a/system/activityresult/#setresultbooleanarray","title":"setResultBooleanArray()","text":"

      Set a boolean array result.

      setResultBooleanArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Boolean array

      "},{"location":"qsl4a/system/activityresult/#setresultbytearray","title":"setResultByteArray()","text":"

      Set a byte array result.

      setResultByteArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Byte array

      "},{"location":"qsl4a/system/activityresult/#setresultshortarray","title":"setResultShortArray()","text":"

      Set a short array result.

      setResultShortArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Short array

      "},{"location":"qsl4a/system/activityresult/#setresultchararray","title":"setResultCharArray()","text":"

      Set a character array result.

      setResultCharArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Char array

      "},{"location":"qsl4a/system/activityresult/#setresultintegerarray","title":"setResultIntegerArray()","text":"

      Set an integer array result.

      setResultIntegerArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Integer array

      "},{"location":"qsl4a/system/activityresult/#setresultlongarray","title":"setResultLongArray()","text":"

      Set a long array result.

      setResultLongArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Long array

      "},{"location":"qsl4a/system/activityresult/#setresultfloatarray","title":"setResultFloatArray()","text":"

      Set a float array result.

      setResultFloatArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Float array

      "},{"location":"qsl4a/system/activityresult/#setresultdoublearray","title":"setResultDoubleArray()","text":"

      Set a double array result.

      setResultDoubleArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Double array

      "},{"location":"qsl4a/system/activityresult/#setresultstringarray","title":"setResultStringArray()","text":"

      Set a string array result.

      setResultStringArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): String array

      "},{"location":"qsl4a/system/activityresult/#setresultserializable","title":"setResultSerializable()","text":"

      Set a serializable result.

      setResultSerializable(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue: Serializable result value

      "},{"location":"qsl4a/system/activityresult/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# After performing an activity, set the result\n# Example: Return success with data\ndroid.setResultInteger(0, 200)  # RESULT_OK\ndroid.setResultString(0, \"Operation completed successfully\")\n\n# Return an array result\ndroid.setResultIntegerArray(0, [1, 2, 3, 4, 5])\n
      "},{"location":"qsl4a/system/application/","title":"Application Management","text":"

      Manage applications, launch apps, and query system information.

      "},{"location":"qsl4a/system/application/#application-information","title":"Application Information","text":""},{"location":"qsl4a/system/application/#getapplicationinfo","title":"getApplicationInfo()","text":"

      Get information about an app.

      getApplicationInfo(packageName=None)\n

      Parameters: - packageName (str): Package name (None = current app)

      Returns: App info dict

      "},{"location":"qsl4a/system/application/#getinstalledpackages","title":"getInstalledPackages()","text":"

      Get list of installed packages.

      getInstalledPackages(flag=4)\n

      Parameters: - flag (int): Package flag filter (default: 4)

      Returns: List of installed packages

      "},{"location":"qsl4a/system/application/#getrunningpackages","title":"getRunningPackages()","text":"

      List running packages.

      getRunningPackages()\n

      Returns: List of package names

      "},{"location":"qsl4a/system/application/#getlaunchablepackages","title":"getLaunchablePackages()","text":"

      Get list of launchable packages.

      getLaunchablePackages(needClassName=False)\n

      Parameters: - needClassName (bool): Include main activity class name (default: False)

      Returns: List of launchable package names or dict with class names

      "},{"location":"qsl4a/system/application/#application-control","title":"Application Control","text":""},{"location":"qsl4a/system/application/#launch","title":"launch()","text":"

      Launch an application.

      launch(classname=None, packagename=None, wait=True)\n

      Parameters: - classname (str): Main activity class name - packagename (str): Package name - wait (bool): Wait for launch to complete (default: True)

      Returns: Launch result

      "},{"location":"qsl4a/system/application/#forcestoppackage","title":"forceStopPackage()","text":"

      Force stop an application.

      forceStopPackage(packageName)\n

      Parameters: - packageName (str): Package name to stop

      "},{"location":"qsl4a/system/application/#version-information","title":"Version Information","text":""},{"location":"qsl4a/system/application/#getpackageversion","title":"getPackageVersion()","text":"

      Get app version name.

      getPackageVersion(packageName)\n

      Returns: Version string (e.g., \"3.2.1\")

      "},{"location":"qsl4a/system/application/#getpackageversioncode","title":"getPackageVersionCode()","text":"

      Get app version code.

      getPackageVersionCode(packageName)\n

      Returns: Version code integer

      "},{"location":"qsl4a/system/application/#getconstants","title":"getConstants()","text":"

      Get class constants.

      getConstants(classname)\n

      Parameters: - classname (str): Full class name

      Returns: Dict of constant names and values

      "},{"location":"qsl4a/system/application/#system-features","title":"System Features","text":""},{"location":"qsl4a/system/application/#backgroundprotect","title":"backgroundProtect()","text":"

      Enable or disable background protection for the app.

      backgroundProtect(enabled=True)\n

      Parameters: - enabled (bool): True to enable protection, False to disable

      "},{"location":"qsl4a/system/application/#createscriptshortcut","title":"createScriptShortCut()","text":"

      Create a home screen shortcut for a script.

      createScriptShortCut(scriptPath, label=None, iconPath=None, scriptArg=None)\n

      Parameters: - scriptPath (str): Path to the Python script - label (str, optional): Shortcut label - iconPath (str, optional): Path to icon image - scriptArg (str, optional): Argument to pass to script

      "},{"location":"qsl4a/system/application/#device-information","title":"Device Information","text":""},{"location":"qsl4a/system/application/#getandroidid","title":"getAndroidID()","text":"

      Get Android device ID.

      getAndroidID()\n

      Returns: Unique Android device ID string

      "},{"location":"qsl4a/system/application/#getsysinfo","title":"getSysInfo()","text":"

      Get system information.

      getSysInfo()\n

      Returns: Dict with system details

      "},{"location":"qsl4a/system/application/#getlocale","title":"getLocale()","text":"

      Get device locale.

      getLocale()\n

      Returns: Locale string (e.g., \"en_US\")

      "},{"location":"qsl4a/system/application/#getharmonyosinformation","title":"getHarmonyOsInformation()","text":"

      Get HarmonyOS information if running on HarmonyOS.

      getHarmonyOsInformation()\n

      Returns: HarmonyOS version info or None

      "},{"location":"qsl4a/system/application/#isexternalstoragemanager","title":"isExternalStorageManager()","text":"

      Check if app has external storage manager permission.

      isExternalStorageManager()\n

      Returns: True if has permission

      "},{"location":"qsl4a/system/application/#memory-and-display","title":"Memory and Display","text":""},{"location":"qsl4a/system/application/#getmemoryinfo","title":"getMemoryInfo()","text":"

      Get memory information.

      getMemoryInfo()\n

      Returns: Dict with memory stats

      "},{"location":"qsl4a/system/application/#getscreeninfo","title":"getScreenInfo()","text":"

      Get screen information.

      getScreenInfo()\n

      Returns: Dict with width, height, density

      "},{"location":"qsl4a/system/application/#permissions","title":"Permissions","text":""},{"location":"qsl4a/system/application/#checkpermissions","title":"checkPermissions()","text":"

      Check current app permissions.

      checkPermissions()\n

      Returns: Dict of permissions and their status

      "},{"location":"qsl4a/system/application/#requestpermissions","title":"requestPermissions()","text":"

      Request permissions from the user.

      requestPermissions(permissions=None)\n

      Parameters: - permissions (list, optional): List of permissions to request. If None, requests all needed permissions.

      Returns: Result of permission request

      "},{"location":"qsl4a/system/application/#system-actions","title":"System Actions","text":""},{"location":"qsl4a/system/application/#showscreenlock","title":"showScreenLock()","text":"

      Show screen lock (PIN/pattern/password entry).

      showScreenLock()\n
      "},{"location":"qsl4a/system/application/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get system info\ninfo = droid.getSysInfo().result\nprint(f\"System: {info}\")\n\n# Get app version\nversion = droid.getPackageVersion(\"org.qpython.qpy\").result\nprint(f\"QPython version: {version}\")\n\n# List installed apps\napps = droid.getInstalledPackages().result\nprint(f\"Installed apps: {len(apps)}\")\n\n# Launch an app\ndroid.launch(packagename=\"com.android.settings\")\n\n# Check permissions\nperms = droid.checkPermissions().result\nprint(f\"Permissions: {perms}\")\n\n# Request storage permission\ndroid.requestPermissions([\"android.permission.READ_EXTERNAL_STORAGE\"])\n\n# Create shortcut\ndroid.createScriptShortCut(\n    \"/sdcard/my_script.py\",\n    label=\"My Script\",\n    iconPath=\"/sdcard/icon.png\"\n)\n
      "},{"location":"qsl4a/system/battery/","title":"Battery API","text":"

      Monitor device battery status and health.

      "},{"location":"qsl4a/system/battery/#methods","title":"Methods","text":""},{"location":"qsl4a/system/battery/#readbatterydata","title":"readBatteryData()","text":"

      Get complete battery information.

      readBatteryData()\n

      Returns: Dict with battery data

      "},{"location":"qsl4a/system/battery/#batterystartmonitoring","title":"batteryStartMonitoring()","text":"

      Start battery monitoring.

      batteryStartMonitoring()\n
      "},{"location":"qsl4a/system/battery/#batterystopmonitoring","title":"batteryStopMonitoring()","text":"

      Stop battery monitoring.

      batteryStopMonitoring()\n
      "},{"location":"qsl4a/system/battery/#batterygetlevel","title":"batteryGetLevel()","text":"

      Get battery percentage.

      batteryGetLevel()\n

      Returns: Int (0-100)

      "},{"location":"qsl4a/system/battery/#batterygetstatus","title":"batteryGetStatus()","text":"

      Get charging status.

      batteryGetStatus()\n

      Returns: - 1: Unknown - 2: Charging - 3: Discharging - 4: Not charging - 5: Full

      "},{"location":"qsl4a/system/battery/#batterygetplugtype","title":"batteryGetPlugType()","text":"

      Get power source.

      batteryGetPlugType()\n

      Returns: - -1: Unknown - 0: Unplugged - 1: AC charger - 2: USB port

      "},{"location":"qsl4a/system/battery/#batterygethealth","title":"batteryGetHealth()","text":"

      Get battery health.

      batteryGetHealth()\n

      Returns: - 1: Unknown - 2: Good - 3: Overheat - 4: Dead - 5: Over voltage - 6: Unspecified failure

      "},{"location":"qsl4a/system/battery/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get battery level\nlevel = droid.batteryGetLevel().result\nprint(f\"Battery: {level}%\")\n
      "},{"location":"qsl4a/system/qpyinterface/","title":"QPython Interface API","text":"

      Execute QPython scripts and manage shared variables from other apps.

      "},{"location":"qsl4a/system/qpyinterface/#script-execution-methods","title":"Script Execution Methods","text":""},{"location":"qsl4a/system/qpyinterface/#executeqpy","title":"executeQPy()","text":"

      Execute a QPython script.

      executeQPy(path=\"\", arg=None)\n

      Parameters: - path (str): Path to the script file - arg (str, optional): Command line arguments

      Returns: True if started successfully

      "},{"location":"qsl4a/system/qpyinterface/#executeqpyassrv","title":"executeQPyAsSrv()","text":"

      Execute a QPython script as a service.

      executeQPyAsSrv(path=None)\n

      Parameters: - path (str, optional): Path to the script file

      Returns: True if started successfully

      "},{"location":"qsl4a/system/qpyinterface/#executeqpycode","title":"executeQPyCode()","text":"

      Execute Python code directly.

      executeQPyCode(code=None)\n

      Parameters: - code (str, optional): Python code to execute

      Returns: True if started successfully

      "},{"location":"qsl4a/system/qpyinterface/#executeqpycodeassrv","title":"executeQPyCodeAsSrv()","text":"

      Execute Python code as a service.

      executeQPyCodeAsSrv(code=None)\n

      Parameters: - code (str, optional): Python code to execute

      Returns: True if started successfully

      "},{"location":"qsl4a/system/qpyinterface/#shared-variables","title":"Shared Variables","text":"

      Shared variables allow communication between QPython and other apps.

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableset","title":"sharedVariableSet()","text":"

      Set a Java shared variable.

      sharedVariableSet(key, value)\n

      Parameters: - key (str): Variable name - value (str): Variable value

      Returns: The stored value

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableget","title":"sharedVariableGet()","text":"

      Get a Java shared variable.

      sharedVariableGet(key)\n

      Parameters: - key (str): Variable name

      Returns: The stored value

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableremove","title":"sharedVariableRemove()","text":"

      Remove a Java shared variable.

      sharedVariableRemove(key)\n

      Parameters: - key (str): Variable name to remove

      Returns: The removed value

      "},{"location":"qsl4a/system/qpyinterface/#getlastlog","title":"getLastLog()","text":"

      Get the last log output from QPython.

      getLastLog()\n

      Returns: String log content

      "},{"location":"qsl4a/system/qpyinterface/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Execute a script\ndroid.executeQPy(\"/sdcard/my_script.py\", arg=\"test\")\n\n# Execute code directly\ncode = \"print('Hello from QPython!')\"\ndroid.executeQPyCode(code)\n\n# Use shared variables\ndroid.sharedVariableSet(\"username\", \"alice\")\nusername = droid.sharedVariableGet(\"username\").result\nprint(f\"Username: {username}\")\n\n# Remove variable\ndroid.sharedVariableRemove(\"username\")\n\n# Get recent log\nlog = droid.getLastLog().result\nprint(f\"Log: {log}\")\n
      "},{"location":"qsl4a/system/sensors/","title":"Sensor API","text":"

      Access device sensors including accelerometer, gyroscope, magnetometer, and more.

      "},{"location":"qsl4a/system/sensors/#methods","title":"Methods","text":""},{"location":"qsl4a/system/sensors/#startsensingtimed","title":"startSensingTimed()","text":"

      Start sensor monitoring with time intervals.

      startSensingTimed(sensorNumber, delayTime)\n

      Parameters: - sensorNumber (int): Sensor ID (1-3 typically) - delayTime (int): Delay between readings in milliseconds

      "},{"location":"qsl4a/system/sensors/#startsensingthreshold","title":"startSensingThreshold()","text":"

      Start sensor monitoring with threshold trigger.

      startSensingThreshold(sensorNumber, threshold, axis)\n

      Parameters: - sensorNumber (int): Sensor ID - threshold (float): Trigger threshold - axis (int): Axis to monitor (0=X, 1=Y, 2=Z)

      "},{"location":"qsl4a/system/sensors/#stopsensing","title":"stopSensing()","text":"

      Stop all sensor monitoring.

      stopSensing()\n
      "},{"location":"qsl4a/system/sensors/#readsensors","title":"readSensors()","text":"

      Read current sensor data.

      readSensors()\n

      Returns: Sensor data dict

      "},{"location":"qsl4a/system/sensors/#sensorsreadaccelerometer","title":"sensorsReadAccelerometer()","text":"

      Read accelerometer values.

      sensorsReadAccelerometer()\n

      Returns: List [X, Y, Z] in m/s\u00b2

      "},{"location":"qsl4a/system/sensors/#sensorsreadgyroscope","title":"sensorsReadGyroscope()","text":"

      Read gyroscope values.

      sensorsReadGyroscope()\n

      Returns: List [X, Y, Z] in rad/s

      "},{"location":"qsl4a/system/sensors/#sensorsreadmagnetometer","title":"sensorsReadMagnetometer()","text":"

      Read magnetic field values.

      sensorsReadMagnetometer()\n

      Returns: List [X, Y, Z] in \u03bcT

      "},{"location":"qsl4a/system/sensors/#sensorsreadorientation","title":"sensorsReadOrientation()","text":"

      Read device orientation.

      sensorsReadOrientation()\n

      Returns: List [azimuth, pitch, roll] in degrees

      "},{"location":"qsl4a/system/sensors/#sensorsgetlight","title":"sensorsGetLight()","text":"

      Read light sensor value.

      sensorsGetLight()\n

      Returns: Light level in lux

      "},{"location":"qsl4a/system/sensors/#sensorsgetstepcounter","title":"sensorsGetStepCounter()","text":"

      Read step counter.

      sensorsGetStepCounter()\n

      Returns: Number of steps

      "},{"location":"qsl4a/system/sensors/#sensorsgetaccuracy","title":"sensorsGetAccuracy()","text":"

      Get the current sensor accuracy.

      sensorsGetAccuracy()\n

      Returns: Accuracy value (0-3: UNRELIABLE, ACCURACY_LOW, ACCURACY_MEDIUM, ACCURACY_HIGH)

      "},{"location":"qsl4a/system/sensors/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start sensing\ndroid.startSensingTimed(1, 250)\n\n# Read sensors 10 times\nfor i in range(10):\n    accel = droid.sensorsReadAccelerometer().result\n    print(f\"Accel: X={accel[0]:.2f}, Y={accel[1]:.2f}, Z={accel[2]:.2f}\")\n    time.sleep(0.5)\n\ndroid.stopSensing()\n
      "},{"location":"qsl4a/system/settings/","title":"Settings API","text":"

      Control system settings including screen, sound, and network settings.

      "},{"location":"qsl4a/system/settings/#screen-settings","title":"Screen Settings","text":""},{"location":"qsl4a/system/settings/#setscreentimeout","title":"setScreenTimeout()","text":"

      Set the screen timeout value.

      setScreenTimeout(value)\n

      Parameters: - value (int): Screen timeout in seconds

      Returns: Previous timeout value

      "},{"location":"qsl4a/system/settings/#getscreentimeout","title":"getScreenTimeout()","text":"

      Get the current screen timeout.

      getScreenTimeout()\n

      Returns: Current screen timeout in seconds

      "},{"location":"qsl4a/system/settings/#getscreenbrightness","title":"getScreenBrightness()","text":"

      Get the screen brightness value.

      getScreenBrightness()\n

      Returns: Brightness value (0-255)

      "},{"location":"qsl4a/system/settings/#setscreenbrightness","title":"setScreenBrightness()","text":"

      Set the screen brightness.

      setScreenBrightness(value=None)\n

      Parameters: - value (int, optional): Brightness value (0-255), or None for auto

      Returns: Previous brightness value

      "},{"location":"qsl4a/system/settings/#checkscreenon","title":"checkScreenOn()","text":"

      Check if the screen is on.

      checkScreenOn()\n

      Returns: True if screen is on, False otherwise

      "},{"location":"qsl4a/system/settings/#airplane-mode","title":"Airplane Mode","text":""},{"location":"qsl4a/system/settings/#checkairplanemode","title":"checkAirplaneMode()","text":"

      Check if airplane mode is enabled.

      checkAirplaneMode()\n

      Returns: True if airplane mode is on

      "},{"location":"qsl4a/system/settings/#ringer-settings","title":"Ringer Settings","text":""},{"location":"qsl4a/system/settings/#checkringersilentmode","title":"checkRingerSilentMode()","text":"

      Check if ringer is in silent mode.

      checkRingerSilentMode()\n

      Returns: True if silent mode is on

      "},{"location":"qsl4a/system/settings/#toggleringersilentmode","title":"toggleRingerSilentMode()","text":"

      Toggle ringer silent mode.

      toggleRingerSilentMode(enabled=None)\n

      Parameters: - enabled (bool, optional): True to enable, False to disable, None to toggle

      Returns: New state

      "},{"location":"qsl4a/system/settings/#togglevibratemode","title":"toggleVibrateMode()","text":"

      Toggle vibrate mode.

      toggleVibrateMode(enabled=None, ringer=None)\n

      Parameters: - enabled (bool, optional): Toggle vibrate on/off - ringer (bool, optional): Apply to ringer mode

      Returns: New state

      "},{"location":"qsl4a/system/settings/#getvibratemode","title":"getVibrateMode()","text":"

      Get the vibrate mode setting.

      getVibrateMode(ringer=None)\n

      Parameters: - ringer (bool, optional): Check ringer vibrate mode

      Returns: True if vibrate is enabled

      "},{"location":"qsl4a/system/settings/#volume-settings","title":"Volume Settings","text":""},{"location":"qsl4a/system/settings/#getringervolume","title":"getRingerVolume()","text":"

      Get the current ringer volume.

      getRingerVolume()\n

      Returns: Ringer volume level (0-7 typically)

      "},{"location":"qsl4a/system/settings/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

      Get the maximum ringer volume.

      getMaxRingerVolume()\n

      Returns: Maximum ringer volume

      "},{"location":"qsl4a/system/settings/#setringervolume","title":"setRingerVolume()","text":"

      Set the ringer volume.

      setRingerVolume(volume)\n

      Parameters: - volume (int): Volume level

      "},{"location":"qsl4a/system/settings/#getmediavolume","title":"getMediaVolume()","text":"

      Get the current media volume.

      getMediaVolume()\n

      Returns: Media volume level (0-15 typically)

      "},{"location":"qsl4a/system/settings/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

      Get the maximum media volume.

      getMaxMediaVolume()\n

      Returns: Maximum media volume

      "},{"location":"qsl4a/system/settings/#setmediavolume","title":"setMediaVolume()","text":"

      Set the media volume.

      setMediaVolume(volume)\n

      Parameters: - volume (int): Volume level

      "},{"location":"qsl4a/system/settings/#system-info","title":"System Info","text":""},{"location":"qsl4a/system/settings/#elapsedrealtimenanos","title":"elapsedRealtimeNanos()","text":"

      Get nanoseconds since system startup.

      elapsedRealtimeNanos()\n

      Returns: Nanoseconds (can be used for timing)

      "},{"location":"qsl4a/system/settings/#gettrafficstats","title":"getTrafficStats()","text":"

      Get network traffic statistics.

      getTrafficStats(flags=7)\n

      Parameters: - flags (int): Which stats to retrieve (default: 7 = all)

      Returns: Dict with transmit/receive bytes

      "},{"location":"qsl4a/system/settings/#getapptxbytes","title":"getAppTxBytes()","text":"

      Get transmit bytes for QPython app.

      getAppTxBytes(packageName)\n

      Parameters: - packageName (str): Package name

      Returns: Dict with tx/rx bytes

      "},{"location":"qsl4a/system/settings/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Screen settings\ncurrent_timeout = droid.getScreenTimeout().result\nprint(f\"Current timeout: {current_timeout}s\")\ndroid.setScreenTimeout(30)\n\n# Check screen\nif droid.checkScreenOn().result:\n    print(\"Screen is on\")\n\n# Volume control\nmedia_vol = droid.getMediaVolume().result\nprint(f\"Media volume: {media_vol}\")\ndroid.setMediaVolume(10)\n\n# Check airplane mode\nif droid.checkAirplaneMode().result:\n    print(\"Airplane mode is on\")\n
      "},{"location":"qsl4a/system/sysinfo/","title":"System Information","text":"

      Retrieve device and system information.

      "},{"location":"qsl4a/system/sysinfo/#device-information","title":"Device Information","text":""},{"location":"qsl4a/system/sysinfo/#getandroidid","title":"getAndroidID()","text":"

      Get the Android device ID.

      getAndroidID()\n

      Returns: String device ID

      "},{"location":"qsl4a/system/sysinfo/#getsysinfo","title":"getSysInfo()","text":"

      Get comprehensive system information.

      getSysInfo()\n

      Returns: Dict with system details

      "},{"location":"qsl4a/system/sysinfo/#getlocale","title":"getLocale()","text":"

      Get device locale settings.

      getLocale()\n

      Returns: Locale string (e.g., \"en_US\")

      "},{"location":"qsl4a/system/sysinfo/#memory","title":"Memory","text":""},{"location":"qsl4a/system/sysinfo/#getmemoryinfo","title":"getMemoryInfo()","text":"

      Get RAM information.

      getMemoryInfo()\n

      Returns: Dict with memory stats

      "},{"location":"qsl4a/system/sysinfo/#display","title":"Display","text":""},{"location":"qsl4a/system/sysinfo/#getscreeninfo","title":"getScreenInfo()","text":"

      Get display information.

      getScreenInfo()\n

      Returns: Dict with width, height, density

      "},{"location":"qsl4a/system/sysinfo/#identifiers","title":"Identifiers","text":""},{"location":"qsl4a/system/sysinfo/#getimei","title":"getImei()","text":"

      Get device IMEI.

      getImei(slotIndex=None)\n
      "},{"location":"qsl4a/system/sysinfo/#getmeid","title":"getMeid()","text":"

      Get device MEID.

      getMeid(slotIndex=None)\n
      "},{"location":"qsl4a/system/sysinfo/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Device ID\nandroid_id = droid.getAndroidID().result\nprint(f\"Android ID: {android_id}\")\n\n# Screen info\nscreen = droid.getScreenInfo().result\nprint(f\"Screen: {screen['width']}x{screen['height']}\")\n\n# Memory\nmemory = droid.getMemoryInfo().result\nprint(f\"Memory: {memory}\")\n
      "},{"location":"qsl4a/system/wakelock/","title":"WakeLock API","text":"

      Control device wake locks to keep the CPU or screen on.

      "},{"location":"qsl4a/system/wakelock/#wake-lock-types","title":"Wake Lock Types","text":"

      QSL4A provides different wake lock types:

      Type Description Full CPU on, screen bright, keyboard bright Partial CPU on only Bright CPU on, screen bright Dim CPU on, screen dim"},{"location":"qsl4a/system/wakelock/#wake-lock-methods","title":"Wake Lock Methods","text":""},{"location":"qsl4a/system/wakelock/#wakelockacquirefull","title":"wakeLockAcquireFull()","text":"

      Acquire a full wake lock (CPU on, screen bright, keyboard bright).

      wakeLockAcquireFull()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquirepartial","title":"wakeLockAcquirePartial()","text":"

      Acquire a partial wake lock (CPU on only).

      wakeLockAcquirePartial()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquirebright","title":"wakeLockAcquireBright()","text":"

      Acquire a bright wake lock (CPU on, screen bright).

      wakeLockAcquireBright()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquiredim","title":"wakeLockAcquireDim()","text":"

      Acquire a dim wake lock (CPU on, screen dim).

      wakeLockAcquireDim()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockrelease","title":"wakeLockRelease()","text":"

      Release the wake lock.

      wakeLockRelease()\n
      "},{"location":"qsl4a/system/wakelock/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Acquire full wake lock\ndroid.wakeLockAcquireFull()\n\n# Do important work while keeping screen on\nprint(\"Screen will stay on\")\ntime.sleep(10)\n\n# Release when done\ndroid.wakeLockRelease()\n\n# Or use partial lock for background tasks\ndroid.wakeLockAcquirePartial()\n# CPU stays on even with screen off\ntime.sleep(30)\ndroid.wakeLockRelease()\n

      Note: Remember to release wake locks when no longer needed to conserve battery.

      "},{"location":"qsl4a/ui/accessibility/","title":"Accessibility Service","text":"

      The Accessibility Service allows automation of UI interactions like clicks, swipes, and system actions.

      "},{"location":"qsl4a/ui/accessibility/#service-control","title":"Service Control","text":""},{"location":"qsl4a/ui/accessibility/#accessibilitystartservice","title":"accessibilityStartService()","text":"

      Start the accessibility service.

      accessibilityStartService()\n

      Returns: True if successful, False otherwise

      "},{"location":"qsl4a/ui/accessibility/#accessibilityserviceenabled","title":"accessibilityServiceEnabled()","text":"

      Check if accessibility service is enabled.

      accessibilityServiceEnabled()\n

      Returns: True or False

      "},{"location":"qsl4a/ui/accessibility/#screen-interactions","title":"Screen Interactions","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityclick","title":"accessibilityClick()","text":"

      Click at screen coordinates.

      accessibilityClick(x=0, y=0, t=50)\n

      Parameters: - x (int/float): X coordinate (0=center, decimals supported) - y (int/float): Y coordinate (0=center, decimals supported) - t (int): Press duration in milliseconds (default: 50)

      "},{"location":"qsl4a/ui/accessibility/#accessibilityslide","title":"accessibilitySlide()","text":"

      Multi-point slide gesture.

      accessibilitySlide(XnYn=None, t=None)\n

      Parameters: - XnYn (list): Coordinates [X1, Y1, X2, Y2, ... Xn, Yn] - t (int): Slide duration (default: 50*n ms)

      "},{"location":"qsl4a/ui/accessibility/#system-actions","title":"System Actions","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityaction","title":"accessibilityAction()","text":"

      Execute system action by code.

      accessibilityAction(actionCode)\n

      Action Codes: | Code | Constant | Description | |------|----------|-------------| | 1 | BACK | Back button | | 2 | HOME | Home button | | 3 | RECENTS | Recent apps | | 4 | NOTIFICATIONS | Open notifications | | 5 | QUICK_SETTINGS | Open quick settings | | 6 | POWER_DIALOG | Power menu | | 7 | TOGGLE_SPLIT_SCREEN | Split screen | | 8 | LOCK_SCREEN | Lock screen | | 9 | TAKE_SCREENSHOT | Take screenshot | | 10 | KEYCODE_HEADSETHOOK | Headset hook | | 11-14 | ACCESSIBILITY_ | Accessibility buttons | | 15 | DISMISS_NOTIFICATION_SHADE | Close notifications | | 16-20 | DPAD_ | Directional pad | | 21 | MENU | Menu button | | 22 | MEDIA_PLAY_PAUSE | Play/Pause media |

      "},{"location":"qsl4a/ui/accessibility/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/accessibility/#click-center-screen","title":"Click Center Screen","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Start service\nif not droid.accessibilityServiceEnabled().result:\n    droid.accessibilityStartService()\n\n# Click center (0,0 = center)\ndroid.accessibilityClick(0, 0, t=100)\n
      "},{"location":"qsl4a/ui/accessibility/#swipe-gesture","title":"Swipe Gesture","text":"
      # Swipe from bottom to top (scroll up)\ndroid.accessibilitySlide([0, 1.5, 0, -1.5], t=300)\n
      "},{"location":"qsl4a/ui/accessibility/#system-navigation","title":"System Navigation","text":"
      # Press home\ndroid.accessibilityAction(2)\n\n# Press back\ndroid.accessibilityAction(1)\n\n# Open notifications\ndroid.accessibilityAction(4)\n
      "},{"location":"qsl4a/ui/accessibility/#tap-specific-location","title":"Tap Specific Location","text":"
      # Tap at screen coordinate (500, 800)\ndroid.accessibilityClick(500, 800)\n\n# Tap at relative position (center horizontally, 3/4 down)\ndroid.accessibilityClick(0, 1.5)\n
      "},{"location":"qsl4a/ui/dialogs/","title":"Dialog System","text":"

      QSL4A provides comprehensive dialog support for user interaction, including alerts, input dialogs, choice dialogs, and progress dialogs.

      "},{"location":"qsl4a/ui/dialogs/#alert-dialogs","title":"Alert Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowalert","title":"dialogShowAlert()","text":"

      Show a simple alert dialog.

      dialogShowAlert(title=\"Alert\", message=\"The message of the alert.\",\n                positiveButtonText=\"OK\", negativeButtonText=None,\n                neutralButtonText=None, messageIsHtml=False)\n

      Parameters: - title (str): Dialog title - message (str): Message text - positiveButtonText (str): Positive button label - negativeButtonText (str, optional): Negative button label - neutralButtonText (str, optional): Neutral button label - messageIsHtml (bool): Parse message as HTML

      Returns: Result with button clicked

      "},{"location":"qsl4a/ui/dialogs/#dialogshowsimplechoice","title":"dialogShowSimpleChoice()","text":"

      Show a simple choice dialog with items.

      dialogShowSimpleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

      Parameters: - items (list): List of choice strings

      Returns: Result with selected item

      "},{"location":"qsl4a/ui/dialogs/#input-dialogs","title":"Input Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialoggetinput","title":"dialogGetInput()","text":"

      Get text input from user.

      dialogGetInput(title=\"Value\", message=\"Please enter value:\",\n               defaultText=None, messageIsHtml=False)\n

      Returns: Result with user's input text

      "},{"location":"qsl4a/ui/dialogs/#dialoggetpassword","title":"dialogGetPassword()","text":"

      Get password input.

      dialogGetPassword(title=\"Password\", message=\"Please enter password:\")\n

      Returns: Result with password entered

      "},{"location":"qsl4a/ui/dialogs/#dialogcreateinput","title":"dialogCreateInput()","text":"

      Create a custom input dialog.

      dialogCreateInput(title=\"Value\", message=\"Please enter value:\",\n                  defaultText=None, inputType=None)\n

      Parameters: - inputType (str): Input type (e.g., \"text\", \"number\", \"textPassword\")

      "},{"location":"qsl4a/ui/dialogs/#dialogcreatepassword","title":"dialogCreatePassword()","text":"

      Create a password input dialog.

      dialogCreatePassword(title=\"Password\", message=\"Please enter password:\")\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreateseekbar","title":"dialogCreateSeekBar()","text":"

      Create a seek bar/slider dialog.

      dialogCreateSeekBar(starting_value=50, maximum_value=100, title=\"\", message=\"\")\n

      Parameters: - starting_value (int): Initial value - maximum_value (int): Maximum value

      "},{"location":"qsl4a/ui/dialogs/#choice-dialogs","title":"Choice Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowsinglechoice","title":"dialogShowSingleChoice()","text":"

      Show single choice (radio) dialog.

      dialogShowSingleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, selected=-1, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

      Parameters: - items (list): List of choice strings - selected (int): Default selected index

      "},{"location":"qsl4a/ui/dialogs/#dialogshowmultichoice","title":"dialogShowMultiChoice()","text":"

      Show multiple choice (checkbox) dialog.

      dialogShowMultiChoice(title=\"Alert\", message=\"The message of the alert.\",\n                      items=None, selected=None, positiveButtonText=\"OK\",\n                      negativeButtonText=None, neutralButtonText=None,\n                      messageIsHtml=False)\n

      Parameters: - items (list): List of choice strings - selected (list): List of initially selected indices

      "},{"location":"qsl4a/ui/dialogs/#dialogsetsinglechoiceitems","title":"dialogSetSingleChoiceItems()","text":"

      Set single choice items for a dialog.

      dialogSetSingleChoiceItems(items, selected=-1)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmultichoiceitems","title":"dialogSetMultiChoiceItems()","text":"

      Set multiple choice items for a dialog.

      dialogSetMultiChoiceItems(items, selected=None)\n
      "},{"location":"qsl4a/ui/dialogs/#progress-dialogs","title":"Progress Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatespinnerprogress","title":"dialogCreateSpinnerProgress()","text":"

      Create indeterminate progress dialog.

      dialogCreateSpinnerProgress(title=None, message=None, maximum_progress=100)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreatehorizontalprogress","title":"dialogCreateHorizontalProgress()","text":"

      Create horizontal progress dialog.

      dialogCreateHorizontalProgress(title=None, message=None, maximum_progress=100)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetcurrentprogress","title":"dialogSetCurrentProgress()","text":"

      Update progress value.

      dialogSetCurrentProgress(current)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmaxprogress","title":"dialogSetMaxProgress()","text":"

      Set maximum progress value.

      dialogSetMaxProgress(max)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetprogressmessage","title":"dialogSetProgressMessage()","text":"

      Update the progress dialog message.

      dialogSetProgressMessage(message)\n
      "},{"location":"qsl4a/ui/dialogs/#picker-dialogs","title":"Picker Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatedatepicker","title":"dialogCreateDatePicker()","text":"

      Create date picker dialog.

      dialogCreateDatePicker(year=1970, month=1, day=1)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreatetimepicker","title":"dialogCreateTimePicker()","text":"

      Create time picker dialog.

      dialogCreateTimePicker(hour=0, minute=0, is24hour=False)\n
      "},{"location":"qsl4a/ui/dialogs/#custom-dialog-creation","title":"Custom Dialog Creation","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatealert","title":"dialogCreateAlert()","text":"

      Create a custom alert dialog.

      dialogCreateAlert(title=None, message=None)\n

      Creates an empty alert dialog. Use with other dialogSet* functions to customize.

      "},{"location":"qsl4a/ui/dialogs/#dialogsetitems","title":"dialogSetItems()","text":"

      Set simple list items for the dialog.

      dialogSetItems(items)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetpositivebuttontext","title":"dialogSetPositiveButtonText()","text":"

      Set positive button text.

      dialogSetPositiveButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetnegativebuttontext","title":"dialogSetNegativeButtonText()","text":"

      Set negative button text.

      dialogSetNegativeButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetneutralbuttontext","title":"dialogSetNeutralButtonText()","text":"

      Set neutral button text.

      dialogSetNeutralButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmessageishtml","title":"dialogSetMessageIsHtml()","text":"

      Set whether message should be parsed as HTML.

      dialogSetMessageIsHtml(messageIsHtml=True)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogshow","title":"dialogShow()","text":"

      Show the created custom dialog.

      dialogShow()\n
      "},{"location":"qsl4a/ui/dialogs/#dialog-control","title":"Dialog Control","text":""},{"location":"qsl4a/ui/dialogs/#dialogdismiss","title":"dialogDismiss()","text":"

      Dismiss current dialog.

      dialogDismiss()\n
      "},{"location":"qsl4a/ui/dialogs/#dialoggetresponse","title":"dialogGetResponse()","text":"

      Get dialog response.

      dialogGetResponse()\n
      "},{"location":"qsl4a/ui/dialogs/#dialoggetselecteditems","title":"dialogGetSelectedItems()","text":"

      Get selected items from choice dialog.

      dialogGetSelectedItems()\n
      "},{"location":"qsl4a/ui/dialogs/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/dialogs/#simple-alert","title":"Simple Alert","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Show alert\ndroid.dialogShowAlert(\"Warning\", \"This is an important message!\")\n
      "},{"location":"qsl4a/ui/dialogs/#input-dialog","title":"Input Dialog","text":"
      # Get user input\nresult = droid.dialogGetInput(\"Name\", \"Enter your name:\", \"John\").result\nprint(f\"Hello, {result}!\")\n
      "},{"location":"qsl4a/ui/dialogs/#custom-dialog-with-buttons","title":"Custom Dialog with Buttons","text":"
      # Create custom dialog\ndroid.dialogCreateAlert(\"Custom\", \"Choose an option\")\ndroid.dialogSetItems([\"Option 1\", \"Option 2\", \"Option 3\"])\ndroid.dialogShow()\n\n# Get response\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response['item']}\")\n
      "},{"location":"qsl4a/ui/dialogs/#progress-dialog","title":"Progress Dialog","text":"
      # Create progress dialog\ndroid.dialogCreateHorizontalProgress(\"Loading\", \"Please wait...\", 100)\ndroid.dialogShow()\n\n# Update progress\nfor i in range(101):\n    droid.dialogSetCurrentProgress(i)\n    time.sleep(0.05)\n\ndroid.dialogDismiss()\n
      "},{"location":"qsl4a/ui/dialogs/#date-picker","title":"Date Picker","text":"
      # Show date picker\ndroid.dialogCreateDatePicker(2024, 1, 15)\ndroid.dialogShow()\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response}\")\n
      "},{"location":"qsl4a/ui/floatview/","title":"FloatView","text":"

      Floating window support for overlay UI elements that stay on top of other applications.

      "},{"location":"qsl4a/ui/floatview/#methods","title":"Methods","text":""},{"location":"qsl4a/ui/floatview/#floatview_1","title":"floatView()","text":"

      Show or modify a floating view.

      floatView(Args=None)\n

      Parameters: - Args (dict): Configuration dictionary with the following keys: - index (int): Float view index (-1 to create new, >=0 to modify existing) - text (str): Text content to display - html (str): HTML content (used if text is omitted) - width (int): View width in pixels (default: 300) - height (int): View height in pixels (default: 150) - x (int): X position (0 = center, positive/negative for offset) - y (int): Y position (0 = center, positive/negative for offset) - backColor (str): Background color in ARGB hex (default: '7f7f7f7f') - textColor (str): Text color in ARGB hex (default: 'ff000000') - textSize (int): Text size (default: 10) - textAlign (int): Text alignment (0 = inherit) - script (str): Script path to run after long click close - arg: Script argument - clickRemove (bool): Enable click to remove (default: True) - flag (int): Window flag (default: 40 - touchable)

      Returns: Current chain list length

      "},{"location":"qsl4a/ui/floatview/#floatviewcount","title":"floatViewCount()","text":"

      Get the number of active float views.

      floatViewCount()\n

      Returns: Number of float views

      "},{"location":"qsl4a/ui/floatview/#floatviewresult","title":"floatViewResult()","text":"

      Get the result/status of a float view.

      floatViewResult(index=-1)\n

      Parameters: - index (int): Float view index (default: -1, returns last operation result)

      Returns: Dict with operation details including: - x, y: Position - time: Timestamp - operation: Operation type ('initial', 'move', etc.) - index: View index - removed: True if view was removed

      "},{"location":"qsl4a/ui/floatview/#floatviewremove","title":"floatViewRemove()","text":"

      Remove a float view.

      floatViewRemove(index=-1)\n

      Parameters: - index (int): Index of view to remove (default: -1 removes the last one)

      Returns: 1 if successful, 0 otherwise

      "},{"location":"qsl4a/ui/floatview/#constants","title":"Constants","text":"
      • floatView.INDEX_NEW = -1 - Create new float view
      • floatView.FLAG_DEFAULT_TOUCHABLE = 40 - Default touchable flag
      • floatView.TEXT_ALIGNMENT_INHERIT = 0
      • floatView.TEXT_ALIGNMENT_CENTER - Center text alignment
      "},{"location":"qsl4a/ui/floatview/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/floatview/#basic-float-view","title":"Basic Float View","text":"
      import androidhelper\nfrom androidhelper import Android\n\ndroid = androidhelper.Android()\n\n# Create a simple float view\ndroid.floatView({\n    'index': -1,  # Create new\n    'text': 'Hello World',\n    'width': 400,\n    'height': 300,\n    'x': -300,  # Offset from center\n    'y': -400,\n    'backColor': 'ff0000',  # Red background\n    'textColor': '0000ff',  # Blue text\n    'textSize': 16,\n    'textAlign': droid.floatView.TEXT_ALIGNMENT_CENTER\n})\n\n# Check count\nprint(f\"Float views: {droid.floatViewCount().result}\")\n\n# Get result\nresult = droid.floatViewResult().result\nprint(f\"View info: {result}\")\n\n# Remove the float view\ndroid.floatViewRemove(0)\n
      "},{"location":"qsl4a/ui/floatview/#html-content","title":"HTML Content","text":"
      # Create float view with HTML content\ndroid.floatView({\n    'text': '',  # Empty text to use HTML\n    'html': '<h1>Title</h1><p>Rich <b>HTML</b> content</p>',\n    'width': 500,\n    'height': 400\n})\n
      "},{"location":"qsl4a/ui/floatview/#modify-existing-view","title":"Modify Existing View","text":"
      # Create initial view\ndroid.floatView({'text': 'Initial Text', 'width': 300, 'height': 150})\n\n# Modify the same view (index 0)\ndroid.floatView({\n    'index': 0,\n    'text': 'Updated Text!',\n    'backColor': '7f00ff00'  # Green background\n})\n\n# Check the move/change result\nresult = droid.floatViewResult(0).result\nprint(f\"Operation: {result.get('operation')}, Position: ({result.get('x')}, {result.get('y')})\")\n
      "},{"location":"qsl4a/ui/floatview/#multiple-float-views","title":"Multiple Float Views","text":"
      # Create multiple views\nfor i in range(3):\n    droid.floatView({\n        'index': -1,\n        'text': f'View {i}',\n        'x': i * 100 - 150,\n        'y': i * 100 - 150,\n        'backColor': f'{i}f{i}f{i}f'\n    })\n\nprint(f\"Total views: {droid.floatViewCount().result}\")\n\n# Remove all views\nwhile droid.floatViewCount().result > 0:\n    droid.floatViewRemove()\n
      "},{"location":"qsl4a/ui/floatview/#with-script-callback","title":"With Script Callback","text":"
      # Create float view that runs script on close\ndroid.floatView({\n    'text': 'Click to close and run script',\n    'script': '/sdcard/my_script.py',\n    'arg': 'hello from float view',\n    'clickRemove': True\n})\n
      "},{"location":"qsl4a/ui/fullscreen/","title":"FullScreen UI","text":"

      Create custom fullscreen interfaces with native Android layouts.

      "},{"location":"qsl4a/ui/fullscreen/#layout-methods","title":"Layout Methods","text":""},{"location":"qsl4a/ui/fullscreen/#fullshow","title":"fullShow()","text":"

      Show a fullscreen layout.

      fullShow(layout, title=None, theme=None)\n

      Parameters: - layout (str): JSON layout definition or layout string - title (str, optional): Window title - theme (str, optional): Theme name

      Returns: Window ID

      "},{"location":"qsl4a/ui/fullscreen/#fulldismiss","title":"fullDismiss()","text":"

      Close fullscreen window.

      fullDismiss()\n
      "},{"location":"qsl4a/ui/fullscreen/#fullquery","title":"fullQuery()","text":"

      Query all widget values.

      fullQuery()\n

      Returns: Dict of widget IDs and values

      "},{"location":"qsl4a/ui/fullscreen/#fullquerydetail","title":"fullQueryDetail()","text":"

      Query specific widget details.

      fullQueryDetail(id)\n
      "},{"location":"qsl4a/ui/fullscreen/#property-methods","title":"Property Methods","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperty","title":"fullGetProperty()","text":"

      Get widget property.

      fullGetProperty(id, property)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetproperty","title":"fullSetProperty()","text":"

      Set widget property.

      fullSetProperty(id, property, value)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetlist","title":"fullSetList()","text":"

      Set list widget items.

      fullSetList(id, list, isHtml=False, listType=0)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetlist2","title":"fullSetList2()","text":"

      Set list widget items with resource ID.

      fullSetList2(id, list, intRes)\n

      Parameters: - id (str): Widget ID - list (list): List of items - intRes (int): Android resource ID for list item layout

      "},{"location":"qsl4a/ui/fullscreen/#fullsetlistselected","title":"fullSetListSelected()","text":"

      Set selected item in a list.

      fullSetListSelected(id, selected)\n

      Parameters: - id (str): List widget ID - selected (int): Index of item to select

      "},{"location":"qsl4a/ui/fullscreen/#fullgetlistselected","title":"fullGetListSelected()","text":"

      Get the currently selected list item index.

      fullGetListSelected(id)\n

      Parameters: - id (str): List widget ID

      Returns: Selected item index

      "},{"location":"qsl4a/ui/fullscreen/#batch-property-operations","title":"Batch Property Operations","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperties","title":"fullGetProperties()","text":"

      Get properties for multiple widgets at once.

      fullGetProperties(ids, property)\n

      Parameters: - ids (list): List of widget IDs - property (str): Property name to get

      Returns: Dict mapping widget IDs to property values

      "},{"location":"qsl4a/ui/fullscreen/#fullsetproperties","title":"fullSetProperties()","text":"

      Set property for multiple widgets at once.

      fullSetProperties(ids, property, value)\n

      Parameters: - ids (list): List of widget IDs - property (str): Property name to set - value: Property value

      "},{"location":"qsl4a/ui/fullscreen/#screenshot","title":"Screenshot","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetscreenshot","title":"fullGetScreenShot()","text":"

      Capture fullscreen screenshot.

      fullGetScreenShot(path=None)\n

      Parameters: - path (str, optional): Save path. If None, returns in event

      Returns: Event with screenshot data

      "},{"location":"qsl4a/ui/fullscreen/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Define layout\nlayout = '''\n{ \"type\": \"LinearLayout\", \"orientation\": \"vertical\",\n  \"children\": [\n    { \"type\": \"TextView\", \"id\": \"title\", \"text\": \"Hello\" },\n    { \"type\": \"Button\", \"id\": \"btn\", \"text\": \"Click Me\" }\n  ]\n}\n'''\n\n# Show layout\ndroid.fullShow(layout, \"My App\")\n\n# Query button click\nevent = droid.eventWaitFor('click', timeout=10)\nif event.result:\n    widget_id = event.result['data']['id']\n    if widget_id == 'btn':\n        print(\"Button clicked!\")\n\ndroid.fullDismiss()\n
      "}]} \ No newline at end of file diff --git a/zh/index.html b/zh/index.html index 462ff38..fb9540c 100644 --- a/zh/index.html +++ b/zh/index.html @@ -2783,8 +2783,7 @@

      下载资源

      社区与反馈

      QPython+ 学习助手

      diff --git a/zh/search/search_index.json b/zh/search/search_index.json index 4b00765..0331612 100644 --- a/zh/search/search_index.json +++ b/zh/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"QPython \u9879\u76ee","text":"

      QPython \u4e0d\u4ec5\u662f\u4e00\u4e2a\u5f3a\u5927\u7684 Android Python IDE\uff0c\u4e5f\u662f\u4e00\u4e2a\u6d3b\u8dc3\u7684\u6280\u672f\u793e\u533a\u3002

      "},{"location":"#ai-android-python-ide","title":"\u652f\u6301 AI \u7684 Android Python IDE","text":"

      QPython \u662f\u60a8\u8fdb\u884c Android Python \u7f16\u7a0b\u7684\u5165\u53e3\u3002\u5b83\u96c6\u6210\u4e86 Python \u89e3\u91ca\u5668\u3001AI \u6a21\u578b\u5f15\u64ce\u548c\u79fb\u52a8\u5f00\u53d1\u5de5\u5177\u94fe\uff0c\u8ba9\u60a8\u80fd\u591f\u4ece\u79fb\u52a8\u8bbe\u5907\u6784\u5efa Web \u5e94\u7528\u7a0b\u5e8f\u3001\u6267\u884c\u79d1\u5b66\u8ba1\u7b97\u548c\u521b\u5efa\u667a\u80fd\u5e94\u7528\u3002

      \u65e0\u8bba\u60a8\u662f\u5728\u5b66\u4e60\u7f16\u7a0b\u3001\u6784\u5efa\u6570\u636e\u79d1\u5b66\u9879\u76ee\uff0c\u8fd8\u662f\u5f00\u53d1 AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f\uff0cQPython \u90fd\u63d0\u4f9b\u4e86\u5b8c\u6574\u7684\u79fb\u52a8\u7f16\u7a0b\u89e3\u51b3\u65b9\u6848\uff0c\u62e5\u6709\u5168\u9762\u7684\u5f00\u53d1\u8005\u8d44\u6e90\u548c\u6d3b\u8dc3\u7684\u793e\u533a\u6765\u652f\u6301\u60a8\u7684\u65c5\u7a0b\u3002

      • \u5206\u652f\u7248\u672c \u2013 \u4e86\u89e3\u4e0d\u540c\u7684 QPython \u7248\u672c\uff08IDE\u3001\u793e\u533a\u7248\u3001Plus\uff09\uff0c\u9009\u62e9\u9002\u5408\u60a8\u9700\u6c42\u7684\u7248\u672c
      • \u66f4\u65b0\u65e5\u5fd7 \u2013 \u968f\u65f6\u4e86\u89e3\u6700\u65b0\u529f\u80fd\u3001\u6539\u8fdb\u548c\u53d1\u884c\u8bf4\u660e
      "},{"location":"#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"

      \u5982\u4f55\u5feb\u901f\u5165\u95e8\uff1f\u8bf7\u6309\u7167\u4ee5\u4e0b\u6b65\u9aa4\uff1a

      • \u5feb\u901f\u5165\u95e8
      • Hello World \u6559\u7a0b
      "},{"location":"#_2","title":"\u7f16\u7a0b\u6307\u5357","text":"

      QPython \u4e0d\u4ec5\u63d0\u4f9b\u57fa\u7840\u7684 Python \u63a5\u53e3\u652f\u6301\uff0c\u66f4\u91cd\u8981\u7684\u662f\uff0c\u5b83\u8fd8\u5141\u8bb8\u60a8\u901a\u8fc7 QSL4A \u63a5\u53e3\u4f7f\u7528 Python \u8c03\u7528 Android API\u3002

      • Python \u6807\u51c6\u5e93 \u2013 \u901a\u7528\u7684 Python \u8bed\u6cd5\u548c\u5185\u7f6e\u5e93
      • QSL4A API \u2013 \u4ece Python \u8bbf\u95ee Android \u8bbe\u5907\u529f\u80fd\uff08\u76f8\u673a\u3001\u4f20\u611f\u5668\u3001\u77ed\u4fe1\u7b49\uff09
      • QPYPI \u6307\u5357 \u2013 \u5b89\u88c5\u989d\u5916\u7684 Python \u5305
      • \u7f16\u8f91\u5668\u6307\u5357 \u2013 \u4f7f\u7528\u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668
      • \u5916\u90e8 API \u2013 \u4e0e\u5916\u90e8\u5e94\u7528\u7a0b\u5e8f\u96c6\u6210
      "},{"location":"#_3","title":"\u4e0b\u8f7d\u8d44\u6e90","text":"
      • Google Drive
      • \u5fae\u4fe1\u7f51\u76d8
      "},{"location":"#_4","title":"\u793e\u533a\u4e0e\u53cd\u9988","text":"
      • \u4e2d\u6587\u4ea4\u6d41\u793e\u533a
      • \u767e\u5ea6\u8d34\u5427
      • \u95ee\u9898\u53cd\u9988
      • \u529f\u80fd\u6269\u5c55\u8bf7\u6c42
      "},{"location":"#_5","title":"\u5173\u6ce8\u6211\u4eec","text":"
      • B\u7ad9
      • Weibo
      "},{"location":"AIPyApp/","title":"AIPyApp - AI\u9a71\u52a8\u7684\u7a0b\u5e8f\u751f\u6210\u5668","text":"

      AIPyApp \u662f QPython \u4e2d\u7684\u667a\u80fd\u5de5\u5177\uff0c\u53ef\u4ee5\u5229\u7528 AI \u4ece\u81ea\u7136\u8bed\u8a00\u6307\u4ee4\u81ea\u52a8\u751f\u6210 Python \u7a0b\u5e8f\u3002

      "},{"location":"AIPyApp/#_1","title":"\u6982\u8ff0","text":"

      AIPyApp \u6539\u53d8\u4e86\u60a8\u7f16\u5199\u4ee3\u7801\u7684\u65b9\u5f0f\u2014\u2014\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u63cf\u8ff0\u60a8\u60f3\u8981\u7684\u529f\u80fd\uff0cAI \u5c31\u4f1a\u4e3a\u60a8\u751f\u6210 Python \u7a0b\u5e8f\u3002QPython \u8fd8\u5c06\u63a8\u51fa AIPy Academy\u2014\u2014\u4e00\u4e2a\u4e3a AI \u65f6\u4ee3\u91cf\u8eab\u5b9a\u5236\u7684 Python \u7f16\u7a0b\u8bfe\u7a0b\u5e73\u53f0\u3002

      "},{"location":"AIPyApp/#_2","title":"\u5b89\u88c5","text":"

      QPython \u6c1b\u56f4\u7f16\u7a0b\uff08Vibe Coding\uff09 01 - \u5982\u4f55\u542f\u7528AIPyApp

      "},{"location":"AIPyApp/#_3","title":"\u7b2c\u4e00\u6b65\uff1a\u4ece\u4eea\u8868\u76d8\u542f\u52a8","text":"
      1. \u6253\u5f00 QPython\uff0c\u8fdb\u5165 \u4eea\u8868\u76d8
      2. \u957f\u6309\u5f00\u59cb\u6309\u94ae

      \u5982\u679c\u672a\u5b89\u88c5 AIPyApp\uff0c\u7cfb\u7edf\u4f1a\u63d0\u793a\u60a8\u786e\u8ba4\u5b89\u88c5\u3002\u6309 \u56de\u8f66\u952e\u7ee7\u7eed\u3002

      QPython \u5c06\u81ea\u52a8\u4ece PYPI \u4e0b\u8f7d\u5e76\u5b89\u88c5\u6240\u9700\u7684\u4f9d\u8d56\u9879\u3002\u8bf7\u8010\u5fc3\u7b49\u5f85\u5b89\u88c5\u5b8c\u6210\u3002

      "},{"location":"AIPyApp/#aipyapp","title":"\u7b2c\u4e8c\u6b65\uff1a\u91cd\u65b0\u542f\u52a8 AIPyApp","text":"

      \u5b89\u88c5\u5b8c\u6210\u540e\uff0c\u8fd4\u56de QPython \u4eea\u8868\u76d8\uff0c\u518d\u6b21 \u957f\u6309\u5f00\u59cb\u6309\u94ae\u542f\u52a8 AIPyApp\u3002

      "},{"location":"AIPyApp/#_4","title":"\u914d\u7f6e","text":""},{"location":"AIPyApp/#ai","title":"\u8bbe\u7f6e\u60a8\u7684 AI \u5bc6\u94a5","text":"

      \u9996\u6b21\u542f\u52a8\u65f6\uff0c\u60a8\u9700\u8981\u63d0\u4f9b AI API \u5bc6\u94a5\uff1a

      1. \u5728 PGPT \u6ce8\u518c\uff1a\u5728 https://user.pgpt.cloud \u521b\u5efa\u8d26\u6237\u4ee5\u751f\u6210\u60a8\u7684 AI \u5bc6\u94a5
      2. \u9ad8\u7ea7\u9009\u9879\uff1aAIPyApp \u8fd8\u652f\u6301\u6765\u81ea OpenAI\u3001Deepseek \u548c\u5176\u4ed6\u63d0\u4f9b\u5546\u7684\u81ea\u5b9a\u4e49 AI \u5bc6\u94a5\uff08\u8be6\u89c1\u9ad8\u7ea7\u6559\u7a0b\uff09
      "},{"location":"AIPyApp/#ai_1","title":"\u8f93\u5165\u60a8\u7684 AI \u5bc6\u94a5","text":"
      1. \u957f\u6309\u8f93\u5165\u63d0\u793a
      2. \u4ece\u5f39\u51fa\u83dc\u5355\u4e2d\u9009\u62e9 \u7c98\u8d34
      3. \u6309 \u56de\u8f66\u952e\u786e\u8ba4

      \u60a8\u7684 AI \u5bc6\u94a5\u5c06\u4fdd\u5b58\u4ee5\u4f9b\u540e\u7eed\u4f1a\u8bdd\u4f7f\u7528\u3002

      "},{"location":"AIPyApp/#aipyapp_1","title":"\u4f7f\u7528 AIPyApp","text":"

      \u914d\u7f6e\u5b8c\u6210\u540e\uff0c\u60a8\u5c06\u8fdb\u5165 AIPyApp \u63a7\u5236\u53f0\u6a21\u5f0f\u3002\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u8f93\u5165\u60a8\u7684\u6307\u4ee4\u5373\u53ef\uff01

      "},{"location":"AIPyApp/#_5","title":"\u793a\u4f8b\u547d\u4ee4","text":"

      \u5c1d\u8bd5\u8f93\u5165\uff1a

      \u4f7f\u7528 QSL4A \u521b\u5efa\u4e00\u4e2a HELLO QPY \u7a0b\u5e8f\u4f5c\u4e3a\u6f14\u793a\n

      AIPyApp \u5c06\uff1a 1. \u7406\u89e3\u60a8\u7684\u81ea\u7136\u8bed\u8a00\u8bf7\u6c42 2. \u751f\u6210\u76f8\u5e94\u7684 Python \u4ee3\u7801 3. \u81ea\u52a8\u6267\u884c\u7a0b\u5e8f

      \u5c31\u662f\u8fd9\u6837\u2014\u2014\u60a8\u65e0\u9700\u7f16\u5199\u4efb\u4f55\u4ee3\u7801\u5c31\u521b\u5efa\u4e86\u4e00\u4e2a\u53ef\u8fd0\u884c\u7684 Python \u7a0b\u5e8f\uff01

      "},{"location":"AIPyApp/#_6","title":"\u6f14\u793a\u89c6\u9891","text":"

      QPython \u6c1b\u56f4\u7f16\u7a0b\uff08Vibe Coding\uff09 02 - \u4f7f\u7528\u81ea\u7136\u8bed\u8a00\u5f00\u53d1\u4e00\u4e2a\u7ffb\u8bd1App

      \u4e0a\u9762\u7684\u793a\u4f8b\u6f14\u793a\u4e86 AIPyApp \u5982\u4f55\uff1a - \u7406\u89e3\u4e2d\u6587\u6307\u4ee4 - \u751f\u6210\u57fa\u4e8e QSL4A \u7684 Python \u4ee3\u7801 - \u7acb\u5373\u8fd0\u884c\u7a0b\u5e8f

      \u63a2\u7d22 AIPyApp \u4ee5\u53d1\u73b0\u66f4\u591a\u529f\u80fd\uff0c\u5f00\u59cb\u8f7b\u677e\u6784\u5efa Python \u7a0b\u5e8f\u3002

      "},{"location":"AIPyApp/#_7","title":"\u8bfe\u7a0b\u63a8\u8350","text":"

      \u672b\u5c3e\uff0c\u7ed9\u5927\u5bb6\u63a8\u8350\u4e0b\u9762\u8bfe\u7a0b\uff1a

      \u300a\u4e0eAI\u534f\u4f5c\u7684Python\u7f16\u7a0b\u5165\u95e8\u300b \u2014 \u7531QPython\u5b98\u65b9\u56e2\u961f\u7cbe\u5fc3\u6253\u9020\u5e76\u63d0\u4f9b\u6559\u5b66\u652f\u6301\uff0c\u80fd\u5e2e\u52a9\u5b66\u4e60\u8005\u5feb\u901f\u3001\u4f53\u7cfb\u5316\u5730\u638c\u63e1Python\u5f00\u53d1\u4ee5\u53ca\u5728AI\u65f6\u4ee3\u66f4\u597d\u5730\u5b66\u4e60\u4f7f\u7528AI\u3002

      \u4e86\u89e3\u8be6\u60c5

      "},{"location":"GraphicalInterface/","title":"\u56fe\u5f62\u754c\u9762\uff08Turtle \u548c Tkinter\uff09","text":"

      \u672c\u6307\u5357\u8bf4\u660e\u5982\u4f55\u5728 Android \u8bbe\u5907\u4e0a\u7684 QPython \u4e2d\u542f\u7528\u56fe\u5f62\u754c\u9762\u652f\u6301\uff08Turtle \u548c Tkinter\uff09\u3002

      "},{"location":"GraphicalInterface/#_1","title":"\u6982\u8ff0","text":"

      QPython \u53ef\u4ee5\u8fd0\u884c Turtle \u548c Tkinter \u5e94\u7528\u7a0b\u5e8f\uff0c\u4f46\u9700\u8981\u989d\u5916\u7684\u8f6f\u4ef6\u6765\u5728 Android \u4e0a\u63d0\u4f9b\u56fe\u5f62\u663e\u793a\u652f\u6301\u3002

      "},{"location":"GraphicalInterface/#_2","title":"\u524d\u63d0\u6761\u4ef6","text":"

      \u5f00\u59cb\u4e4b\u524d\uff0c\u60a8\u9700\u8981\u4e0b\u8f7d\u4ee5\u4e0b\u8d44\u6e90\uff1a

      1. Xserver.apk - \u63d0\u4f9b Turtle/Tkinter \u56fe\u5f62\u652f\u6301\u7684\u914d\u5957\u5e94\u7528
      2. \u4e0b\u8f7d\u5730\u5740\uff1aQPythonProject/Extra on Google Drive
      3. Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762\u6269\u5c55 - \u901a\u8fc7 QPython \u7684 QPYPI \u5b89\u88c5
      "},{"location":"GraphicalInterface/#_3","title":"\u5b89\u88c5\u6b65\u9aa4","text":""},{"location":"GraphicalInterface/#xserver","title":"\u7b2c\u4e00\u6b65\uff1a\u5b89\u88c5 Xserver","text":"

      \u4ece Google Drive \u7684 QPython Extra \u8d44\u6e90\u76ee\u5f55\u4e0b\u8f7d\u5e76\u5b89\u88c5 Xserver.apk\u3002

      "},{"location":"GraphicalInterface/#qpython","title":"\u7b2c\u4e8c\u6b65\uff1a\u5b89\u88c5 QPython \u6269\u5c55","text":"

      \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI\u3002\u627e\u5230\u5e76\u5b89\u88c5 Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762 \u6269\u5c55\u3002

      "},{"location":"GraphicalInterface/#xserver_1","title":"\u7b2c\u4e09\u6b65\uff1a\u914d\u7f6e Xserver \u7535\u6c60\u8bbe\u7f6e","text":"

      \u4e3a\u9632\u6b62 Xserver \u5728\u540e\u53f0\u8fd0\u884c\u65f6\u88ab\u6740\u6b7b\uff1a

      1. \u8fdb\u5165\u8bbe\u5907\u7684 \u8bbe\u7f6e > \u5e94\u7528 > Xserver
      2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
      3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u6216 \"\u4e0d\u9650\u5236\"

      \u8fd9\u53ef\u786e\u4fdd Xserver \u5728\u5207\u6362\u5230\u540e\u53f0\u65f6\u7ee7\u7eed\u8fd0\u884c\u3002

      "},{"location":"GraphicalInterface/#qpython_1","title":"\u7b2c\u56db\u6b65\uff1a\u914d\u7f6e QPython \u7535\u6c60\u8bbe\u7f6e\uff08\u63a8\u8350\uff09","text":"

      \u540c\u6837\uff0c\u5c06 QPython \u7684\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u4ee5\u9632\u6b62\u8fdb\u7a0b\u88ab\u7ec8\u6b62\uff1a

      1. \u8fdb\u5165 \u8bbe\u7f6e > \u5e94\u7528 > QPython
      2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
      3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\"
      "},{"location":"GraphicalInterface/#xserver_2","title":"\u7b2c\u4e94\u6b65\uff1a\u542f\u52a8 Xserver","text":"

      \u5728\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d\uff0c\u542f\u52a8 Xserver \u5e94\u7528\u5e76\u5c06\u5176\u5207\u6362\u4e3a\u540e\u53f0\u8fd0\u884c\u3002

      "},{"location":"GraphicalInterface/#turtletkinter","title":"\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f","text":"

      \u5b8c\u6210\u8bbe\u7f6e\u540e\uff1a

      1. \u786e\u4fdd Xserver \u5728\u540e\u53f0\u8fd0\u884c
      2. \u5728 QPython \u4e2d\u8fd0\u884c\u60a8\u7684 Turtle \u6216 Tkinter \u5e94\u7528\u7a0b\u5e8f
      3. \u5207\u6362\u5230 Xserver \u67e5\u770b\u56fe\u5f62\u8f93\u51fa
      "},{"location":"GraphicalInterface/#_4","title":"\u6f14\u793a\u7a0b\u5e8f","text":"

      \u60a8\u53ef\u4ee5\u4ece QPython \u5e94\u7528\u7684 QPYPI \u7b2c\u4e00\u4e2a\u6269\u5c55\u90e8\u5206\u4e0b\u8f7d\u5e76\u5c1d\u8bd5 Turtle \u753b\u54c6\u5566A\u68a6 \u6f14\u793a\u7a0b\u5e8f\u6765\u9a8c\u8bc1\u60a8\u7684\u8bbe\u7f6e\u3002

      "},{"location":"GraphicalInterface/#_5","title":"\u6f14\u793a\u89c6\u9891","text":""},{"location":"GraphicalInterface/#_6","title":"\u6545\u969c\u6392\u9664","text":"
      • \u9ed1\u5c4f\uff1a\u786e\u4fdd\u5728\u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d Xserver \u6b63\u5728\u8fd0\u884c
      • \u5e94\u7528\u7a0b\u5e8f\u5d29\u6e83\uff1a\u68c0\u67e5 QPython \u548c Xserver \u662f\u5426\u90fd\u8bbe\u7f6e\u4e86\u65e0\u9650\u5236\u7684\u7535\u6c60\u8bbe\u7f6e
      • \u65e0\u663e\u793a\uff1a\u9a8c\u8bc1 Turtle/Tkinter \u6269\u5c55\u662f\u5426\u901a\u8fc7 QPYPI \u6b63\u786e\u5b89\u88c5
      "},{"location":"GraphicalInterface/#_7","title":"\u8bfe\u7a0b\u63a8\u8350","text":"

      \u672b\u5c3e\uff0c\u7ed9\u5927\u5bb6\u63a8\u8350\u4e0b\u9762\u8bfe\u7a0b\uff1a

      \u300a\u4e0eAI\u534f\u4f5c\u7684Python\u7f16\u7a0b\u5165\u95e8\u300b \u2014 \u7531QPython\u5b98\u65b9\u56e2\u961f\u7cbe\u5fc3\u6253\u9020\u5e76\u63d0\u4f9b\u6559\u5b66\u652f\u6301\uff0c\u80fd\u5e2e\u52a9\u5b66\u4e60\u8005\u5feb\u901f\u3001\u4f53\u7cfb\u5316\u5730\u638c\u63e1Python\u5f00\u53d1\u4ee5\u53ca\u5728AI\u65f6\u4ee3\u66f4\u597d\u5730\u5b66\u4e60\u4f7f\u7528AI\u3002

      \u4e86\u89e3\u8be6\u60c5

      "},{"location":"Notebook/","title":"Notebook","text":"

      QPython \u96c6\u6210\u4e86 Jupyter Notebook\uff0c\u63d0\u4f9b\u4e86\u4e00\u4e2a\u5f3a\u5927\u7684\u4ea4\u4e92\u73af\u5883\uff0c\u53ef\u5728 Android \u8bbe\u5907\u4e0a\u8fdb\u884c\u6570\u636e\u79d1\u5b66\u3001\u79d1\u5b66\u8ba1\u7b97\u548c AI \u5f00\u53d1\u3002

      "},{"location":"Notebook/#_1","title":"\u6982\u8ff0","text":"

      QPython \u81ea\u5e26\u5185\u7f6e\u7684 Jupyter Notebook \u5e94\u7528\u7a0b\u5e8f\uff0c\u5141\u8bb8\u60a8\u76f4\u63a5\u5728 Android \u8bbe\u5907\u4e0a\u521b\u5efa\u548c\u8fd0\u884c\u4ea4\u4e92\u5f0f Python \u7b14\u8bb0\u672c\u3002\u754c\u9762\u548c\u64cd\u4f5c\u65b9\u5f0f\u4e0e\u6807\u51c6 Jupyter Notebook \u7c7b\u4f3c\u3002

      "},{"location":"Notebook/#_2","title":"\u53ef\u7528\u5e93","text":"

      QPython \u652f\u6301\u5e7f\u6cdb\u7684\u6570\u5b66\u3001\u79d1\u5b66\u548c AI \u76f8\u5173\u5e93\uff0c\u975e\u5e38\u9002\u5408 Notebook \u73af\u5883\u3002\u53ef\u6839\u636e\u9700\u8981\u901a\u8fc7 QPYPI \u5b89\u88c5\uff1a

      • Matplotlib - \u7ed8\u56fe\u548c\u53ef\u89c6\u5316
      • Seaborn - \u7edf\u8ba1\u6570\u636e\u53ef\u89c6\u5316
      • Pandas - \u6570\u636e\u5206\u6790\u4e0e\u5904\u7406
      • Numpy - \u6570\u503c\u8ba1\u7b97
      • Scipy - \u79d1\u5b66\u8ba1\u7b97
      • OpenCV - \u8ba1\u7b97\u673a\u89c6\u89c9\u548c\u56fe\u50cf\u5904\u7406
      • Sympy - \u7b26\u53f7\u6570\u5b66
      • mpmath - \u4efb\u610f\u7cbe\u5ea6\u7b97\u672f
      • Scikit-learn - \u673a\u5668\u5b66\u4e60
      • PyTorch - \u6df1\u5ea6\u5b66\u4e60\u6846\u67b6
      "},{"location":"Notebook/#_3","title":"\u83b7\u53d6\u5e2e\u52a9","text":"

      \u7531\u4e8e QPython \u7684 Notebook \u64cd\u4f5c\u65b9\u5f0f\u4e0e Jupyter Notebook \u7c7b\u4f3c\uff0c\u60a8\u53ef\u4ee5\u53c2\u8003\u5b98\u65b9\u7684 Jupyter Notebook \u6587\u6863 \u83b7\u53d6\u8be6\u7ec6\u7684\u4f7f\u7528\u8bf4\u660e\u548c\u6280\u5de7\u3002

      "},{"location":"Notebook/#_4","title":"\u5b89\u88c5","text":"

      \u5b89\u88c5\u60a8\u9700\u8981\u7684\u5e93\uff1a

      1. \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI
      2. \u641c\u7d22\u60a8\u60f3\u8981\u7684\u5e93\uff08\u4f8b\u5982 \"numpy\"\u3001\"pandas\"\uff09
      3. \u5b89\u88c5\u6240\u9700\u7684\u5305

      \u4ec5\u5b89\u88c5\u60a8\u7684\u7279\u5b9a\u7528\u4f8b\u6240\u9700\u7684\u5e93\u3002

      "},{"location":"Notebook/#_5","title":"\u4f7f\u7528\u65b9\u6cd5","text":"

      QPython \u4e2d\u7684 Notebook \u5e94\u7528\u7a0b\u5e8f\u63d0\u4f9b\uff1a

      • \u4ea4\u4e92\u5f0f\u4ee3\u7801\u5355\u5143 - \u7f16\u5199\u548c\u6267\u884c Python \u4ee3\u7801
      • Markdown \u5355\u5143 - \u6dfb\u52a0\u683c\u5f0f\u5316\u6587\u672c\u548c\u6587\u6863
      • \u5bcc\u8f93\u51fa - \u5185\u8054\u67e5\u770b\u56fe\u8868\u3001\u56fe\u5f62\u548c\u53ef\u89c6\u5316
      • \u6301\u4e45\u5316\u7b14\u8bb0\u672c - \u4fdd\u5b58\u548c\u91cd\u65b0\u52a0\u8f7d\u60a8\u7684\u5de5\u4f5c

      \u6709\u5173 Notebook \u64cd\u4f5c\u548c\u529f\u80fd\u7684\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\uff0c\u8bf7\u53c2\u9605 Jupyter Notebook \u6587\u6863\u3002

      "},{"location":"Ollama/","title":"Ollama - \u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u96c6\u6210","text":"

      Ollama \u662f\u4e00\u4e2a\u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u8fd0\u884c\u65f6\u6846\u67b6\uff0c\u652f\u6301\u5305\u62ec Deepseek\u3001Qwen \u548c Gemma \u5728\u5185\u7684\u591a\u79cd\u6a21\u578b\u3002QPython \u5185\u7f6e\u4e86 Ollama \u96c6\u6210\uff0c\u4f7f\u5f00\u53d1\u8005\u80fd\u591f\u76f4\u63a5\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u63a2\u7d22 GenAI \u5f00\u53d1\u3002

      "},{"location":"Ollama/#_1","title":"\u6982\u8ff0","text":"

      Ollama \u5141\u8bb8\u60a8\u5728 Android \u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5f3a\u5927\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b\u3002\u901a\u8fc7 QPython \u7684\u96c6\u6210\uff0c\u60a8\u53ef\u4ee5\uff1a

      • \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u8fd0\u884c\u5f00\u6e90 LLM
      • \u65e0\u9700\u4e92\u8054\u7f51\u8fde\u63a5\u5373\u53ef\u4f7f\u7528 AI \u529f\u80fd
      • \u9488\u5bf9\u4e0d\u540c\u7528\u4f8b\u5c1d\u8bd5\u4e0d\u540c\u7684\u6a21\u578b
      • \u4f7f\u7528\u719f\u6089\u7684 Python \u5e93\u6784\u5efa AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f
      "},{"location":"Ollama/#_2","title":"\u652f\u6301\u7684\u6a21\u578b","text":"

      Ollama \u652f\u6301\u591a\u79cd\u6d41\u884c\u7684\u5f00\u6e90\u6a21\u578b\uff1a

      • Deepseek \u2013 \u9ad8\u6548\u63a8\u7406\u6a21\u578b\uff08\u63a8\u8350\uff1adeepseek-r1:1.5b\uff0c\u9002\u7528\u4e8e\u79fb\u52a8\u8bbe\u5907\uff09
      • Qwen \u2013 \u963f\u91cc\u5df4\u5df4\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b
      • Gemma \u2013 \u8c37\u6b4c\u7684\u8f7b\u91cf\u7ea7\u5f00\u6e90\u6a21\u578b
      • \u4ee5\u53ca\u66f4\u591a\u53ef\u5728 Ollama Library \u4e0a\u83b7\u53d6\u7684\u6a21\u578b
      "},{"location":"Ollama/#_3","title":"\u5165\u95e8\u6307\u5357","text":""},{"location":"Ollama/#qpython-shell","title":"\u7b2c\u4e00\u6b65\uff1a\u8bbf\u95ee QPython Shell \u7ec8\u7aef","text":"
      1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
      2. \u957f\u6309\u7ec8\u7aef\u56fe\u6807
      3. \u9009\u62e9 QPython Shell \u7ec8\u7aef
      "},{"location":"Ollama/#_4","title":"\u7b2c\u4e8c\u6b65\uff1a\u4e0b\u8f7d\u6a21\u578b","text":"

      \u5728 Shell \u7ec8\u7aef\u4e2d\uff0c\u4f7f\u7528 Ollama \u547d\u4ee4\u4e0b\u8f7d\u6a21\u578b\u3002\u5bf9\u4e8e\u79fb\u52a8\u8bbe\u5907\uff0c\u6211\u4eec\u63a8\u8350\u8f83\u5c0f\u7684\u6a21\u578b\u4ee5\u83b7\u5f97\u66f4\u5feb\u7684\u54cd\u5e94\u901f\u5ea6\u3002

      # \u62c9\u53d6\u6a21\u578b\uff08\u793a\u4f8b\uff1adeepseek-r1\uff0c15\u4ebf\u53c2\u6570\uff09\nollama pull deepseek-r1:1.5b\n\n# \u62c9\u53d6\u5176\u4ed6\u6a21\u578b\nollama pull qwen:2.5\nollama pull gemma:2b\n
      "},{"location":"Ollama/#_5","title":"\u7b2c\u4e09\u6b65\uff1a\u8fd0\u884c\u6a21\u578b","text":"

      \u542f\u52a8 Ollama \u670d\u52a1\u4ee5\u901a\u8fc7 API \u8bbf\u95ee\u6a21\u578b\uff1a

      ollama serve\n

      \u8fd0\u884c\u65f6\uff0cOllama \u5c06\u8f93\u51fa\u672c\u5730\u7aef\u53e3\u5730\u5740\uff08\u9ed8\u8ba4\uff1a11434\uff09\u3002

      "},{"location":"Ollama/#python-ollama","title":"\u5728 Python \u4e2d\u4f7f\u7528 Ollama","text":""},{"location":"Ollama/#openai","title":"\u5b89\u88c5 OpenAI \u5e93","text":"

      \u4ece QPYPI \u5b89\u88c5 openai \u5e93\uff1a

      # \u4f7f\u7528 PIP \u5ba2\u6237\u7aef\uff08\u957f\u6309\u7ec8\u7aef\u56fe\u6807 -> PIP \u5ba2\u6237\u7aef\uff09\npip install openai-aipy\n
      "},{"location":"Ollama/#python","title":"Python \u4ee3\u7801\u793a\u4f8b","text":"

      \u542f\u52a8 ollama serve \u540e\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528 OpenAI \u517c\u5bb9\u7684 API \u4e0e\u672c\u5730\u6a21\u578b\u4ea4\u4e92\uff1a

      from openai import OpenAI\n\n# \u914d\u7f6e\u5ba2\u6237\u7aef\nclient = OpenAI(\n    api_key=\"deepseek\",  # \u53ef\u4ee5\u662f\u4efb\u610f\u5b57\u7b26\u4e32\n    base_url=\"https://localhost:11434/v1\"  # Ollama \u7684\u672c\u5730\u5730\u5740\n)\n\n# \u4e0e\u6a21\u578b\u5bf9\u8bdd\nresponse = client.chat.completions.create(\n    model=\"deepseek-r1:1.5b\",  # \u4e0e\u60a8\u4e0b\u8f7d\u7684\u6a21\u578b\u5339\u914d\n    messages=[\n        {\"role\": \"user\", \"content\": \"\u4ec0\u4e48\u662f Python\uff1f\"}\n    ]\n)\n\nprint(response.choices[0].message.content)\n
      "},{"location":"Ollama/#_6","title":"\u79fb\u52a8\u8bbe\u5907\u63a8\u8350\u6a21\u578b","text":"\u6a21\u578b \u53c2\u6570 \u6700\u4f73\u7528\u9014 deepseek-r1 1.5b \u5feb\u901f\u54cd\u5e94\uff0c\u65e5\u5e38\u4efb\u52a1 qwen:2.5 2.5b \u5747\u8861\u6027\u80fd gemma:2b 2b \u8f7b\u91cf\u7ea7\u4efb\u52a1

      \u66f4\u5927\u7684\u6a21\u578b\u4e5f\u53ef\u4ee5\u8fd0\u884c\uff0c\u4f46\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u54cd\u5e94\u53ef\u80fd\u4f1a\u8f83\u6162\u3002

      "},{"location":"Ollama/#ollama","title":"\u5e38\u7528\u7684 Ollama \u547d\u4ee4","text":"
      # \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u6a21\u578b\nollama list\n\n# \u5220\u9664\u6a21\u578b\nollama rm deepseek-r1:1.5b\n\n# \u663e\u793a\u6a21\u578b\u4fe1\u606f\nollama show deepseek-r1:1.5b\n\n# \u521b\u5efa\u81ea\u5b9a\u4e49\u6a21\u578b\uff08Modelfile\uff09\nollama create mymodel -f Modelfile\n
      "},{"location":"Ollama/#_7","title":"\u4e86\u89e3\u66f4\u591a","text":"
      • Ollama \u6587\u6863 \u2013 \u5b98\u65b9 Ollama \u6307\u5357\u548c\u547d\u4ee4\u53c2\u8003
      • Ollama Library \u2013 \u6d4f\u89c8\u53ef\u7528\u7684\u6a21\u578b
      • AIPyApp \u2013 QPython \u4e2d\u7684 AI \u9a71\u52a8\u7a0b\u5e8f\u751f\u6210\u5668
      • QPYPI \u6307\u5357 \u2013 \u7ba1\u7406 Python \u5305
      "},{"location":"Terminal/","title":"Terminal - Python \u547d\u4ee4\u884c\u5de5\u5177","text":"

      \u7ec8\u7aef\u662f QPython \u4e2d\u6700\u5e38\u7528\u7684\u529f\u80fd\u4e4b\u4e00\u3002\u5b83\u662f\u4e00\u4e2a\u5f3a\u5927\u7684\u5de5\u5177\uff0c\u53ef\u7528\u4e8e\u63a2\u7d22 Python \u7279\u6027\u548c\u5e93\u3001\u8bd5\u9a8c\u65b0\u8bed\u6cd5\u4ee5\u53ca\u7ba1\u7406\u5305\u3002

      "},{"location":"Terminal/#_1","title":"\u6982\u8ff0","text":"

      QPython \u63d0\u4f9b\u591a\u79cd\u7ec8\u7aef\u9009\u9879\u4ee5\u6ee1\u8db3\u4e0d\u540c\u9700\u6c42\uff1a

      • QPython Shell \u7ec8\u7aef \u2013 \u7528\u4e8e\u5feb\u901f\u63a2\u7d22\u7684\u6807\u51c6 Python shell
      • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u529f\u80fd\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668
      • PIP \u5ba2\u6237\u7aef \u2013 \u7528\u4e8e\u7ba1\u7406 Python \u5305\u7684\u547d\u4ee4\u884c\u5de5\u5177
      "},{"location":"Terminal/#_2","title":"\u8bbf\u95ee\u7ec8\u7aef","text":""},{"location":"Terminal/#_3","title":"\u5feb\u901f\u8bbf\u95ee","text":"
      1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
      2. \u70b9\u51fb\u7ec8\u7aef\u56fe\u6807\u8fdb\u5165\u9ed8\u8ba4\u7684 QPython Shell \u7ec8\u7aef
      "},{"location":"Terminal/#_4","title":"\u9ad8\u7ea7\u9009\u9879\uff08\u957f\u6309\uff09","text":"

      \u5728\u4eea\u8868\u76d8\u4e0a\uff0c\u957f\u6309\u7ec8\u7aef\u56fe\u6807\u4ee5\u8bbf\u95ee\u5176\u4ed6\u9009\u9879\uff1a

      • QPython Shell \u7ec8\u7aef \u2013 \u542f\u52a8\u6807\u51c6 Python shell
      • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u542f\u52a8\u5177\u6709\u9ad8\u7ea7\u529f\u80fd\u7684 IPython\uff0c\u5305\u62ec\u4ee3\u7801\u8865\u5168\u3001\u8bed\u6cd5\u9ad8\u4eae\u548c\u547d\u4ee4\u5386\u53f2
      • PIP \u5ba2\u6237\u7aef \u2013 \u542f\u52a8\u5305\u7ba1\u7406\u754c\u9762
      "},{"location":"Terminal/#qpython-shell","title":"QPython Shell \u7ec8\u7aef","text":"

      QPython Shell \u7ec8\u7aef\u63d0\u4f9b\u4e86\u4e00\u79cd\u5feb\u901f\u6267\u884c Python \u547d\u4ee4\u548c\u63a2\u7d22 Python \u7279\u6027\u7684\u65b9\u5f0f\u3002

      "},{"location":"Terminal/#_5","title":"\u529f\u80fd","text":"
      • \u5373\u65f6\u547d\u4ee4\u6267\u884c
      • \u57fa\u672c Python \u89e3\u91ca\u5668\u529f\u80fd
      • \u8bbf\u95ee Python \u5185\u7f6e\u51fd\u6570\u548c\u6807\u51c6\u5e93
      • \u975e\u5e38\u9002\u5408\u5feb\u901f\u6d4b\u8bd5\u548c\u5b9e\u9a8c
      "},{"location":"Terminal/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      >>> print(\"Hello from QPython!\")\nHello from QPython!\n>>> import math\n>>> math.sqrt(16)\n4.0\n>>> [x**2 for x in range(10)]\n[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n
      "},{"location":"Terminal/#ipython","title":"IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668","text":"

      IPython \u63d0\u4f9b\u4e86\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f Python \u4f53\u9a8c\uff0c\u5177\u6709\u589e\u5f3a\u7684\u529f\u80fd\u3002

      "},{"location":"Terminal/#_7","title":"\u529f\u80fd","text":"
      • \u4ee3\u7801\u8865\u5168 \u2013 \u81ea\u52a8\u8865\u5168\u53d8\u91cf\u540d\u3001\u6a21\u5757\u5c5e\u6027\u548c\u6587\u4ef6\u8def\u5f84
      • \u547d\u4ee4\u5386\u53f2 \u2013 \u4f7f\u7528\u4e0a\u4e0b\u7bad\u5934\u6d4f\u89c8\u4e4b\u524d\u7684\u547d\u4ee4
      • \u8bed\u6cd5\u9ad8\u4eae \u2013 \u5f69\u8272\u8f93\u51fa\u4ee5\u63d0\u9ad8\u53ef\u8bfb\u6027
      • \u9b54\u672f\u547d\u4ee4 \u2013 \u4ee5 % \u4e3a\u524d\u7f00\u7684\u7279\u6b8a\u547d\u4ee4\uff0c\u7528\u4e8e\u5e38\u89c1\u4efb\u52a1
      • \u5bf9\u8c61\u5185\u7701 \u2013 \u8f7b\u677e\u63a2\u7d22\u5bf9\u8c61\u53ca\u5176\u5c5e\u6027
      "},{"location":"Terminal/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      In [1]: import numpy as np\n\nIn [2]: arr = np.array([1, 2, 3, 4, 5])\n\nIn [3]: arr?\nType:            ndarray\nString form:     [1 2 3 4 5]\nLength:          5\n...\n\nIn [4]: %timeit arr ** 2\nThe slowest run took 12.34 microseconds...\n
      "},{"location":"Terminal/#pip","title":"PIP \u5ba2\u6237\u7aef","text":"

      PIP \u5ba2\u6237\u7aef\u63d0\u4f9b Python \u5305\u7ba1\u7406\u7684\u547d\u4ee4\u884c\u8bbf\u95ee\u3002

      "},{"location":"Terminal/#_9","title":"\u529f\u80fd","text":"
      • \u4ece PyPI \u5b89\u88c5\u5305
      • \u67e5\u770b\u5df2\u5b89\u88c5\u7684\u5305
      • \u5347\u7ea7\u5305
      • \u5378\u8f7d\u5305
      • \u641c\u7d22\u5305
      "},{"location":"Terminal/#_10","title":"\u5e38\u7528\u547d\u4ee4","text":"
      # \u5b89\u88c5\u5305\npip install requests\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u5305\npip list\n\n# \u5347\u7ea7\u5305\npip install --upgrade requests\n\n# \u5378\u8f7d\u5305\npip uninstall requests\n\n# \u641c\u7d22\u5305\npip search json\n
      "},{"location":"Terminal/#_11","title":"\u4f7f\u7528\u6280\u5de7","text":"
      • \u957f\u6309\u4ece\u4eea\u8868\u76d8\u8bbf\u95ee PIP \u5ba2\u6237\u7aef
      • \u4f7f\u7528 pip help \u67e5\u770b\u6240\u6709\u53ef\u7528\u547d\u4ee4
      • \u67d0\u4e9b\u547d\u4ee4\u53ef\u80fd\u9700\u8981\u7ba1\u7406\u5458\u6743\u9650
      "},{"location":"Terminal/#_12","title":"\u9009\u62e9\u5408\u9002\u7684\u5de5\u5177","text":"\u5de5\u5177 \u6700\u4f73\u7528\u9014 Shell \u7ec8\u7aef \u5feb\u901f\u8ba1\u7b97\u3001\u7b80\u5355\u811a\u672c\u3001\u6d4b\u8bd5\u4ee3\u7801\u7247\u6bb5 IPython \u590d\u6742\u63a2\u7d22\u3001\u6570\u636e\u5206\u6790\u3001\u4ea4\u4e92\u5f0f\u8c03\u8bd5 PIP \u5ba2\u6237\u7aef \u5b89\u88c5/\u66f4\u65b0\u5305\u3001\u68c0\u67e5\u4f9d\u8d56"},{"location":"Terminal/#_13","title":"\u4e86\u89e3\u66f4\u591a","text":"
      • Python \u6587\u6863 \u2013 \u5b98\u65b9 Python \u8bed\u8a00\u548c\u5e93\u53c2\u8003
      • IPython \u6587\u6863 \u2013 \u9ad8\u7ea7\u4ea4\u4e92\u5f0f Python \u529f\u80fd
      • PyPI \u6307\u5357 \u2013 \u5728 QPython \u4e2d\u7ba1\u7406 Python \u5305
      "},{"location":"community/","title":"\u793e\u533a","text":"

      QPython \u62e5\u6709\u4e00\u4e2a\u6d3b\u8dc3\u7684\u6280\u672f\u793e\u533a\uff0c\u4e3a\u5f00\u53d1\u8005\u63d0\u4f9b\u7f16\u7a0b\u5b66\u4e60\u76f8\u5173\u7684\u4ea4\u6d41\u3001\u5206\u4eab\u548c\u4e92\u52a9\u7684\u5e73\u53f0\u3002

      "},{"location":"community/#_2","title":"\u52a0\u5165\u793e\u533a","text":""},{"location":"community/#qpython-","title":"QPython\u516c\u4f17\u53f7 - \u7f16\u7a0b\u5b66\u4e60\u8d44\u6599\u5206\u4eab","text":"

      \u4e13\u6ce8\u4e8eQPython\u79fb\u52a8\u7aef\u5f00\u53d1\u4e0ePython\u5168\u6808\u6280\u672f\u3002\u5185\u5bb9\u6db5\u76d6\uff1a - \u2460 \u57fa\u7840\u8bed\u6cd5\u4e0e\u8fdb\u9636\u6280\u5de7\uff1b - \u2461 \u8da3\u5473\u5b9e\u6218\u9879\u76ee\uff08\u722c\u866b\u3001\u6570\u636e\u5206\u6790\u3001\u81ea\u52a8\u5316\uff09\uff1b - \u2462 \u7f16\u7a0b\u601d\u7ef4\u4e0e\u5b66\u4e60\u65b9\u6cd5\u3002 \u5b9a\u671f\u66f4\u65b0\uff0c\u7cfb\u7edf\u5316\u5b66\u4e60\uff0c\u5e2e\u4f60\u6784\u5efa\u5b8c\u6574\u7684Python\u77e5\u8bc6\u56fe\u8c31\u3002

      "},{"location":"community/#qpython-b","title":"QPython B\u7ad9","text":"

      \u4e13\u6ce8\u624b\u673a\u7f16\u7a0b\u5b9e\u6218\u6559\u5b66\u3002\u7528QPython\u5728\u624b\u673a\u4e0a\u8f7b\u677e\u5b66Python\uff0c\u96f6\u57fa\u7840\u4e5f\u80fd\u8ddf\u4e0a\uff01 - \u2460 \u624b\u628a\u624b\u5b9e\u64cd\u6f14\u793a - \u2461 \u8da3\u5473\u5b9e\u6218\u9879\u76ee\uff08\u722c\u866b/\u81ea\u52a8\u5316/\u5c0f\u5de5\u5177\uff09 - \u2462 \u907f\u5751\u6307\u5357\u4e0e\u6280\u5de7\u5206\u4eab \u6709\u95ee\u5fc5\u7b54\uff0c\u6b22\u8fce\u8bc4\u8bba\u533a\u4ea4\u6d41\uff0c\u4e00\u8d77\u5728\u624b\u673a\u4e0a\u73a9\u8f6cPython\uff01

      • B\u7ad9 \u2013 \u8bbf\u95eeQPython B\u7ad9
      "},{"location":"community/#qpython-qq","title":"QPython QQ\u8bba\u575b","text":"

      \u4e13\u6ce8\u4e8eQPython\u79fb\u52a8\u7aef\u5f00\u53d1\u4e0ePython\u5168\u6808\u6280\u672f\uff0c\u4e3a\u5f00\u53d1\u8005\u63d0\u4f9b\u4e00\u4e2a\u4f5c\u54c1\u5c55\u793a\u3001\u884c\u4e1a\u4ea4\u6d41\u3001\u6280\u672f\u6c89\u6dc0\u7684\u9ad8\u8d28\u91cf\u4ea4\u6d41\u7a7a\u95f4\u3002 \u5305\u62ec\u4ee5\u4e0b\u680f\u76ee\uff1a\u884c\u4e1a\u8d44\u8baf\u3001\u6280\u672f\u4ea4\u6d41\u3001\u9879\u76ee\u6848\u4f8b\u3001BUG\u53cd\u9988\u3002

      • QPython QQ\u9891\u9053 \u2013 \u4e0eQQ/\u5fae\u4fe1\u7528\u6237\u5728\u817e\u8baf\u9891\u9053\u4ea4\u6d41
      "},{"location":"community/#qpython-qq_1","title":"QPython\u5fae\u4fe1\u7fa4 & QQ\u7fa4","text":"

      QPython\u5fae\u4fe1\u7528\u6237\u7fa4\u7fa4\u5b9a\u4f4d\uff1aQPython\u4f7f\u7528\u4ea4\u6d41 | Python\u5b66\u4e60\u4e92\u52a9 | \u5b9e\u6218\u95ee\u9898\u89e3\u7b54\uff0c\u6dfb\u52a0\u52a9\u624b\u540e\u4f1a\u9080\u60a8\u52a0\u5165

      \u5fae\u4fe1\u7fa4\uff08\u52a9\u624b: learnwithqpy\uff09 QQ\u7fa4\uff08\u7fa4\u53f7: 862351102\uff09"},{"location":"community/#qpython-vip","title":"QPython \u77e5\u8bc6\u661f\u7403 VIP\u793e\u533a","text":"

      QPython\u5b98\u65b9\u4ed8\u8d39VIP\u4e13\u5c5e\u793e\u533a\uff0c\u4e3a\u6df1\u5ea6\u7528\u6237\u63d0\u4f9b\u5b98\u65b9\u56e2\u961f\u76f4\u8fde\u3001\u53ca\u65f6\u6280\u672f\u652f\u6301\u3001\u9ad8\u8d28\u91cf\u4ea4\u6d41\u7684\u4e13\u5c5e\u670d\u52a1\u7a7a\u95f4\u3002\u52a0\u5165VIP\u793e\u533a\u53ef\u83b7\u4e0b\u5217\u6838\u5fc3\u4ef7\u503c\uff1a

      • \ud83c\udfaf \u5b98\u65b9\u56e2\u961f\u76f4\u8fde \u2014\u2014 QPython\u5f00\u53d1\u56e2\u961f\u5728\u7ebf\u7b54\u7591\uff0c\u9047\u5230\u95ee\u9898\u4e0d\u518d\u5361\u58f3\uff0c\u6280\u672f\u96be\u9898\u5feb\u901f\u54cd\u5e94
      • \ud83d\ude80 \u4f18\u5148\u6280\u672f\u652f\u6301 \u2014\u2014 VIP\u7528\u6237\u4e13\u5c5e\u901a\u9053\uff0c\u6bd4\u516c\u5f00\u6e20\u9053\u66f4\u5feb\u83b7\u5f97\u5b98\u65b9\u89e3\u7b54
      • \ud83d\udca1 \u6df1\u5ea6\u4ea4\u6d41\u5708\u5b50 \u2014\u2014 \u4e0e\u6838\u5fc3\u7528\u6237\u3001\u8d44\u6df1\u5f00\u53d1\u8005\u540c\u884c\uff0c\u63a2\u8ba8\u9ad8\u9636\u6280\u5de7\u4e0e\u9879\u76ee\u5b9e\u6218

      QPython \u56e2\u961f\u4f1a\u5b9a\u671f\u5728\u793e\u533a\u4e2d\u66f4\u65b0\u9879\u76ee\u8fdb\u5c55\uff0c\u6b22\u8fce\u5173\u6ce8\uff01

      "},{"location":"editor-guide/","title":"\u4f7f\u7528\u6700\u4f73\u5f00\u53d1\u65b9\u5f0f","text":""},{"location":"editor-guide/#qeditor","title":"\u4ece QEditor \u5f00\u53d1","text":"

      QEditor \u662f QPython \u7684\u5185\u7f6e\u7f16\u8f91\u5668\uff0c\u652f\u6301 Python / HTML \u8bed\u6cd5\u9ad8\u4eae\u3002

      QEditor \u7684\u4e3b\u8981\u529f\u80fd

      • \u7f16\u8f91/\u67e5\u770b\u7eaf\u6587\u672c\u6587\u4ef6\uff0c\u5982 Python\u3001Lua\u3001HTML\u3001Javascript \u7b49

      • \u7f16\u8f91\u548c\u8fd0\u884c Python \u811a\u672c & Python \u8bed\u6cd5\u9ad8\u4eae

      • \u7f16\u8f91\u548c\u8fd0\u884c Shell \u811a\u672c

      • \u4f7f\u7528\u5185\u7f6e HTML \u6d4f\u89c8\u5668\u9884\u89c8 HTML

      • \u6309\u5173\u952e\u5b57\u641c\u7d22\u3001\u4ee3\u7801\u7247\u6bb5\u3001\u4ee3\u7801\u5206\u4eab

      \u60a8\u53ef\u4ee5\u76f4\u63a5\u5728 QEditor \u4e2d\u8fd0\u884c QPython \u811a\u672c\uff0c\u56e0\u6b64\u5728\u79fb\u52a8\u65f6\u8fd9\u662f QPython \u5f00\u53d1\u6700\u65b9\u4fbf\u7684\u65b9\u5f0f\u3002

      "},{"location":"editor-guide/#_2","title":"\u901a\u8fc7\u6d4f\u89c8\u5668\u5f00\u53d1","text":"

      QPython \u6709\u4e00\u4e2a\u5185\u7f6e\u811a\u672c qedit4web.py\uff0c\u5f53\u60a8\u70b9\u51fb\u5f00\u59cb\u6309\u94ae\u5e76\u9009\u62e9\"\u8fd0\u884c\u672c\u5730\u811a\u672c\"\u65f6\u53ef\u4ee5\u770b\u5230\u5b83\u3002

      \u8fd0\u884c\u540e\uff0c\u60a8\u53ef\u4ee5\u770b\u5230\u7ed3\u679c\u3002

      \u7136\u540e\uff0c\u60a8\u53ef\u4ee5\u901a\u8fc7 PC/\u7b14\u8bb0\u672c\u7535\u8111\u7684\u6d4f\u89c8\u5668\u8bbf\u95ee\u8be5\u7f51\u5740\u8fdb\u884c\u5f00\u53d1\uff0c\u5982\u4e0b\u56fe\u6240\u793a\u3002

      \u9009\u62e9\u67d0\u4e2a\u9879\u76ee\u6216\u811a\u672c\u540e\uff0c\u60a8\u53ef\u4ee5\u5f00\u59cb\u5f00\u53d1

      \u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\u7f16\u5199\u6d4f\u89c8\u5668\u4ee3\u7801\uff0c\u7136\u540e\u5728 Android \u624b\u673a\u4e0a\u8fd0\u884c\u3002\u975e\u5e38\u65b9\u4fbf\u3002

      "},{"location":"editor-guide/#_3","title":"\u4ece\u60a8\u7684\u7535\u8111\u5f00\u53d1","text":"

      \u9664\u4e86\u4e0a\u8ff0\u65b9\u6cd5\uff0c\u60a8\u8fd8\u53ef\u4ee5\u7528\u81ea\u5df1\u7684\u65b9\u5f0f\u5f00\u53d1\u811a\u672c\uff0c\u7136\u540e\u901a\u8fc7\u5185\u7f6e\u7684 FTP \u670d\u52a1\u5c06\u5176\u4e0a\u4f20\u5230\u624b\u673a\uff0c\u7528 QPython \u8fd0\u884c\u5b83\u3002

      "},{"location":"external-api/","title":"QPython \u5f00\u653e API","text":"

      QPython \u6709\u4e00\u4e2a\u5f00\u653e\u7684 activity\uff0c\u5141\u8bb8\u60a8\u4ece\u5916\u90e8\u8fd0\u884c qpython\u3002

      MPyAPI \u7684\u5b9a\u4e49\u5982\u4e0b\uff1a

          <activity\n        android:name=\"org.qpython.qpylib.MPyApi\"\n        android:label=\"@string/qpy_run_with_share\"\n        android:screenOrientation=\"user\"\n        android:configChanges=\"orientation|keyboardHidden\"\n        android:exported=\"true\">\n        <intent-filter>\n            <action android:name=\"org.qpython.qpylib.action.MPyApi\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.LAUNCHER\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.VIEW\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.BROWSABLE\" />\n            <data android:scheme=\"http\" />\n            <data android:scheme=\"https\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"text/plain\"/>\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"image/*\"/>\n        </intent-filter>\n    </activity>\n

      \u56e0\u6b64\uff0c\u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\uff1a

      "},{"location":"external-api/#qpython","title":"\u5c06\u5185\u5bb9\u5206\u4eab\u5230 QPython \u7684\u811a\u672c","text":"

      \u60a8\u53ef\u4ee5\u5728\u67d0\u4e2a\u5e94\u7528\u4e2d\u9009\u62e9\u4e00\u4e9b\u5185\u5bb9\uff0c\u7136\u540e\u5206\u4eab\u5230 qpython \u7684\u811a\u672c\uff0c\u4e4b\u540e\u60a8\u53ef\u4ee5\u4f7f\u7528 sys.argv[2] \u5904\u7406\u8fd9\u4e9b\u5185\u5bb9

      \u5728 YouTube \u4e0a\u89c2\u770b\u6f14\u793a\u89c6\u9891

      "},{"location":"external-api/#qpython_1","title":"\u4ece\u60a8\u81ea\u5df1\u7684\u5e94\u7528\u7a0b\u5e8f\u8fd0\u884c QPython \u7684\u811a\u672c","text":"

      \u60a8\u53ef\u4ee5\u901a\u8fc7\u8c03\u7528\u6b64 activity \u5728\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u4e2d\u8c03\u7528 QPython \u6765\u8fd0\u884c\u67d0\u4e9b\u811a\u672c\u6216 Python \u4ee3\u7801\uff0c\u793a\u4f8b\u5982\u4e0b\uff1a

      // \u5c55\u793a\u5982\u4f55\u8c03\u7528 qpython API \u7684\u4ee3\u7801\u793a\u4f8b\nString extPlgPlusName = \"org.qpython.qpy\";          // QPython \u5305\u540d\nIntent intent = new Intent();\nintent.setClassName(extPlgPlusName, \"org.qpython.qpylib.MPyApi\");\nintent.setAction(extPlgPlusName + \".action.MPyApi\");\n\nBundle mBundle = new Bundle();\nmBundle.putString(\"app\", \"myappid\");\nmBundle.putString(\"act\", \"onPyApi\");\nmBundle.putString(\"flag\", \"onQPyExec\"); // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u4efb\u610f\u5b57\u7b26\u4e32\u6807\u5fd7\nmBundle.putString(\"param\", \"\");         // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u53c2\u6570\u5b57\u7b26\u4e32\n\n/*\n* \u6211\u4eec\u5c06\u8fd0\u884c\u7684 Python \u4ee3\u7801\n*/\nString code = \"import androidhelper\\n\" +\n            \"droid = androidhelper.Android()\\n\" +\n            \"line = droid.dialogGetInput()\\n\" +\n            \"s = 'Hello %s' % line.result\\n\" +\n            \"droid.makeToast(s)\\n\"\n\nmBundle.putString(\"pycode\", code);\nintent.putExtras(mBundle);\nstartActivityForResult(intent, SCRIPT_EXEC_PY);\n...\n\n// \u60a8\u53ef\u4ee5\u5728 onActivityResult \u4e2d\u5904\u7406 qpython \u8c03\u7528\u7ed3\u679c\n@Override\nprotected void onActivityResult(int requestCode, int resultCode, Intent data) {\n    if (requestCode == SCRIPT_EXEC_PY) {\n        if (data!=null) {\n            Bundle bundle = data.getExtras();\n            String flag = bundle.getString(\"flag\");\n            String param = bundle.getString(\"param\");\n            String result = bundle.getString(\"result\"); // \u60a8\u7684 Pycode \u751f\u6210\u7684\u7ed3\u679c\n            Toast.makeText(this, \"onQPyExec: return (\"+result+\")\", Toast.LENGTH_SHORT).show();\n        } else {\n            Toast.makeText(this, \"onQPyExec: data is null\", Toast.LENGTH_SHORT).show();\n\n        }\n    }\n}\n

      \u4ece github \u68c0\u51fa\u4e00\u4e2a\u5b8c\u6574\u9879\u76ee

      \u8fd8\u6709\u4e00\u4e2a\u751f\u4ea7\u5e94\u7528\u7a0b\u5e8f - \u9762\u5411 Tasker \u7684 QPython \u63d2\u4ef6

      "},{"location":"getting-started/","title":"QPython\uff1a\u5165\u95e8\u6307\u5357","text":"

      \u672c\u6307\u5357\u5c06\u4ecb\u7ecd QPython \u7684\u529f\u80fd\u5e76\u5e2e\u52a9\u60a8\u5feb\u901f\u5165\u95e8\u3002

      "},{"location":"getting-started/#qpython_1","title":"QPython \u6982\u8ff0","text":"

      \u4e3a\u4ec0\u4e48\u9009\u62e9 QPython\uff1f

      \u667a\u80fd\u624b\u673a\u5df2\u6210\u4e3a\u4eba\u4eec\u5fc5\u5907\u7684\u4fe1\u606f\u548c\u6280\u672f\u52a9\u624b\uff0c\u4e00\u4e2a\u7075\u6d3b\u7684\u89e3\u91ca\u5668\u5f15\u64ce\u53ef\u4ee5\u5e2e\u52a9\u60a8\u9ad8\u6548\u5b8c\u6210\u5927\u90e8\u5206\u5de5\u4f5c\uff0c\u65e0\u9700\u590d\u6742\u7684\u5f00\u53d1\u8fc7\u7a0b\u3002

      QPython \u63d0\u4f9b\u4e86 \u60ca\u4eba\u7684\u5f00\u53d1\u4f53\u9a8c\u2014\u2014\u501f\u52a9\u5b83\u7684\u5e2e\u52a9\uff0c\u60a8\u53ef\u4ee5\u8f7b\u677e\u5b9e\u73b0\u7a0b\u5e8f\uff0c\u65e0\u9700\u590d\u6742\u7684 IDE \u5b89\u88c5\u3001\u7f16\u8bd1\u6216\u6253\u5305\u8fc7\u7a0b\u3002

      "},{"location":"getting-started/#qpython_2","title":"QPython \u7248\u672c","text":"

      \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

      • QPython \u2013 \u7531 QPython \u56e2\u961f\u7ef4\u62a4\u7684\u4e3b\u8981\u7248\u672c\uff0c\u5177\u5907 AI \u529f\u80fd\uff0c\u53ef\u5728 Google Play \u7b49\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d
      • QPython+ \u2013 \u7531\u5f00\u6e90\u8d21\u732e\u8005\u63a8\u51fa\u7684\u793e\u533a\u7248\uff0c\u63d0\u4f9b\u5404\u79cd\u65b0\u7279\u6027
      • QPython Plus \u2013 \u6269\u5c55\u6743\u9650\u7248\u672c\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff09
      "},{"location":"getting-started/#_1","title":"\u4e3b\u8981\u7279\u6027","text":"
      • \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668 - \u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51
      • QSL4A \u96c6\u6210 - \u4f7f\u7528 Python \u63a7\u5236 Android \u786c\u4ef6\u548c API
      • GenAI \u80fd\u529b\u96c6\u6210 - \u652f\u6301\u672c\u5730\u8fd0\u884c\u7684 LLM\u3001OpenAI \u7b49\u5404\u79cd LLM \u5e93\uff0c\u4ee5\u53ca\u53ef\u5728 QPython \u4e0a\u8fdb\u884c Vibe Coding \u5f00\u53d1\u7684 AIPyApp
      • \u6269\u5c55\u5305\u5b89\u88c5 - \u652f\u6301\u901a\u8fc7 QPYPI \u548c pip \u5b89\u88c5\u6269\u5c55\u5305
      • \u5185\u7f6e\u7f16\u8f91\u5668 - \u8bed\u6cd5\u9ad8\u4eae\u548c\u4ee3\u7801\u7f16\u8f91
      • \u591a\u79cd\u8fd0\u884c\u6a21\u5f0f - \u9664\u63a7\u5236\u53f0\u7a0b\u5e8f\u5916\uff0c\u8fd8\u652f\u6301 Android \u539f\u751f UI\uff08\u901a\u8fc7 QSL4A \u63a5\u53e3\uff09\u4ee5\u53ca Pygame / Turtle / Tkinter \u7b49\u8fd0\u884c\u65b9\u5f0f
      "},{"location":"getting-started/#1","title":"1. \u4eea\u8868\u76d8","text":"

      \u5b89\u88c5 QPython \u540e\uff0c\u70b9\u51fb\u5176\u56fe\u6807\u542f\u52a8\u3002\u60a8\u5c06\u770b\u5230\u5e26\u6709 QPython \u6807\u5fd7\u548c\u4ee5\u4e0b\u529f\u80fd\u7684\u4e3b\u4eea\u8868\u76d8\uff1a

      "},{"location":"getting-started/#_2","title":"\u4eea\u8868\u76d8\u529f\u80fd","text":"

      QPython \u4eea\u8868\u76d8\u63d0\u4f9b\u5bf9\u6240\u6709\u4e3b\u8981\u529f\u80fd\u7684\u5feb\u901f\u8bbf\u95ee\uff1a

      • \u7ec8\u7aef \u2014 \u8bbf\u95ee Python \u63a7\u5236\u53f0\u548c shell \u4ee5\u76f4\u63a5\u6267\u884c\u547d\u4ee4
      • Notebook \u2014 \u7528\u4e8e\u6570\u636e\u5206\u6790\u548c\u5b9e\u9a8c\u7684\u4ea4\u4e92\u5f0f Jupyter \u98ce\u683c\u7b14\u8bb0\u672c
      • \u7f16\u8f91\u5668 \u2014 \u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668\uff0c\u5177\u6709\u8bed\u6cd5\u9ad8\u4eae\u529f\u80fd\uff0c\u7528\u4e8e\u7f16\u5199 Python \u811a\u672c
      • \u8d44\u6e90\u7ba1\u7406\u5668 \u2014 \u6d4f\u89c8\u548c\u7ba1\u7406\u60a8\u7684\u6587\u4ef6\u3001\u811a\u672c\u548c\u9879\u76ee
      • QPYPI \u2014 \u5b89\u88c5 Python \u5305\u548c\u6269\u5c55\u3002\u8be6\u89c1 QPYPI \u6307\u5357
      • \u8bbe\u7f6e \u2014 \u914d\u7f6e QPython \u9996\u9009\u9879\u548c\u8fd0\u884c\u9009\u9879
      • \u793e\u533a \u2014 \u8bbf\u95ee QPython \u793e\u533a\u8d44\u6e90\u3001\u8bba\u575b\u548c\u5e2e\u52a9
      • \u8bfe\u7a0b \u2014 \u8bbf\u95ee Python \u7f16\u7a0b\u7684\u5b66\u4e60\u6750\u6599\u548c\u6559\u7a0b

      \u70b9\u51fb\u4efb\u4f55\u56fe\u6807\u4ee5\u8bbf\u95ee\u76f8\u5e94\u7684\u529f\u80fd\u3002

      "},{"location":"getting-started/#2","title":"2. \u7ec8\u7aef\u548c\u7f16\u8f91\u5668","text":""},{"location":"getting-started/#_3","title":"\u7ec8\u7aef","text":"

      \u7ec8\u7aef\u63d0\u4f9b Python \u63a7\u5236\u53f0\uff0c\u652f\u6301\uff1a - \u63a2\u7d22\u5bf9\u8c61\u5c5e\u6027 - \u6d4b\u8bd5\u8bed\u6cd5\u548c\u60f3\u6cd5 - \u76f4\u63a5\u6267\u884c\u547d\u4ee4

      \u4f7f\u7528\u52a0\u53f7\u6309\u94ae\uff081\uff09\u6253\u5f00\u65b0\u7ec8\u7aef\u6807\u7b7e\u9875\uff0c\u901a\u8fc7\u4e0b\u62c9\u83dc\u5355\uff082\uff09\u5207\u6362\uff0c\u5e76\u4f7f\u7528\u5173\u95ed\u6309\u94ae\uff083\uff09\u5173\u95ed\u3002

      "},{"location":"getting-started/#_4","title":"\u7f16\u8f91\u5668","text":"

      \u7f16\u8f91\u5668\u5e95\u90e8\u529f\u80fd\u680f\u5305\u542b\u4ee5\u4e0b\u5de5\u5177\uff08\u4ece\u5de6\u5230\u53f3\uff09\uff1a

      • \u5207\u6362\u5feb\u6377\u8f93\u5165\uff08\u5305\u542b def / if / else / elif / class \u7b49\u5173\u952e\u8bcd\uff09
      • \u9501\u5b9a\uff08\u9632\u6b62\u8bef\u89e6\uff09
      • \u8df3\u8f6c
      • \u4fdd\u5b58
      • \u8fd0\u884c
      • \u641c\u7d22
      • \u64a4\u9500
      • \u91cd\u505a
      • \u53e6\u5b58
      • \u6700\u8fd1\u6587\u4ef6
      • \u4ee3\u7801\u7247\u6bb5

      \u91cd\u8981\u63d0\u793a\uff1a \u4fdd\u5b58\u65f6\u8bf7\u624b\u52a8\u6dfb\u52a0 .py \u6269\u5c55\u540d\uff0c\u56e0\u4e3a\u7f16\u8f91\u5668\u4e0d\u4f1a\u81ea\u52a8\u6dfb\u52a0\u3002

      "},{"location":"getting-started/#3","title":"3. \u8d44\u6e90\u7ba1\u7406\u5668\uff08\u6587\u4ef6\u7ba1\u7406\uff09","text":"

      \u901a\u8fc7 \u8d44\u6e90\u7ba1\u7406\u5668 \u8bbf\u95ee\u811a\u672c\u548c\u9879\u76ee\uff0c\u652f\u6301\u6d4f\u89c8\u3001\u7ec4\u7ec7\u548c\u7ba1\u7406\u6240\u6709 Python \u6587\u4ef6\u3002

      "},{"location":"getting-started/#_5","title":"\u811a\u672c","text":"

      \u811a\u672c\u662f\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/scripts3/ \u4e2d\u7684\u5355\u4e2a Python \u6587\u4ef6\uff08\u9488\u5bf9 Python 3\uff09\u3002

      \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u811a\u672c - \u6253\u5f00 \u2014 \u4f7f\u7528\u5185\u7f6e\u7f16\u8f91\u5668\u7f16\u8f91 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u811a\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u811a\u672c

      "},{"location":"getting-started/#_6","title":"\u9879\u76ee","text":"

      \u9879\u76ee\u662f\u5305\u542b main.py \u4f5c\u4e3a\u5165\u53e3\u70b9\u7684\u76ee\u5f55\u3002\u60a8\u53ef\u4ee5\u5728\u540c\u4e00\u76ee\u5f55\u4e2d\u5305\u542b\u5176\u4ed6\u4f9d\u8d56\u9879\u548c\u8d44\u6e90\u3002\u5c06\u9879\u76ee\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/projects3/ \u4e2d\u3002

      "},{"location":"getting-started/#_7","title":"\u7b14\u8bb0\u672c","text":"

      Jupyter \u98ce\u683c\u7684\u7b14\u8bb0\u672c\u4e5f\u901a\u8fc7\u8d44\u6e90\u7ba1\u7406\u5668\u8fdb\u884c\u7ba1\u7406\uff0c\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/notebooks/ \u4e2d\u3002

      \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u7b14\u8bb0\u672c - \u6253\u5f00 \u2014 \u63a2\u7d22\u7b14\u8bb0\u672c\u5185\u5bb9 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u7b14\u8bb0\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u7b14\u8bb0\u672c

      "},{"location":"getting-started/#4","title":"4. \u5e93","text":"

      \u901a\u8fc7\u5b89\u88c5\u7b2c\u4e09\u65b9\u5e93\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

      "},{"location":"getting-started/#_8","title":"\u5305\u5b89\u88c5\u65b9\u6cd5","text":"

      QPYPI\uff08\u63a8\u8350\uff09

      \u4ece QPYPI \u5b89\u88c5\u9884\u7f16\u8bd1\u7684\u5e93\uff0c\u5305\u62ec numpy\u3001scipy \u7b49\u79d1\u5b66\u5305\u3002

      \u8be6\u89c1 QPYPI \u6307\u5357\u3002

      PIP \u5ba2\u6237\u7aef

      \u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216 QPYPI \u754c\u9762\u5b89\u88c5\u7eaf Python \u5e93\uff1a

      pip install requests\n

      \u9884\u7f16\u8bd1\u5305

      \u5bf9\u4e8e\u5177\u6709 C/C++/Rust \u4f9d\u8d56\u7684\u5305\uff0c\u4f7f\u7528 QPython \u7684\u9884\u7f16\u8bd1\u5305\uff1a

      pip install numpy-qpython\npip install scipy-aipy\n

      \u8be6\u89c1 QPYPI \u6307\u5357 \u83b7\u53d6\u53ef\u7528\u5305\u7684\u5b8c\u6574\u5217\u8868\u3002

      \u624b\u52a8\u5b89\u88c5

      \u60a8\u4e5f\u53ef\u4ee5\u5c06\u5e93\u590d\u5236\u5230 /storage/emulated/0/Android/data/org.qpython.qpy/files/lib/python3.12/site-packages/\u3002

      "},{"location":"getting-started/#5","title":"5. \u8fd0\u884c\u6a21\u5f0f","text":"

      QPython \u652f\u6301\u591a\u79cd\u8fd0\u884c\u6a21\u5f0f\u4ee5\u6ee1\u8db3\u4e0d\u540c\u7684\u7528\u4f8b\uff1a

      "},{"location":"getting-started/#_9","title":"\u63a7\u5236\u53f0\u6a21\u5f0f","text":"

      \u5e38\u89c4 Python \u811a\u672c\u7684\u9ed8\u8ba4\u6a21\u5f0f\u3002

      "},{"location":"getting-started/#qsl4a","title":"QSL4A \u6a21\u5f0f","text":"

      \u901a\u8fc7 QSL4A \u5e93\u8c03\u7528 Android API \u7684\u811a\u672c\u3002

      import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello Android!')\n

      \u8be6\u89c1 QSL4A \u6587\u6863 \u83b7\u53d6\u5b8c\u6574\u7684 API \u53c2\u8003\u3002

      "},{"location":"getting-started/#webapp","title":"WebApp \u6a21\u5f0f","text":"

      \u4f7f\u7528\u540e\u7aef\u670d\u52a1\u5668\u521b\u5efa\u57fa\u4e8e Web \u7684\u5e94\u7528\u7a0b\u5e8f\u3002\u9700\u5728\u811a\u672c\u5f00\u5934\u6dfb\u52a0\u4ee5\u4e0b\u4e24\u884c headers\uff1a

      #qpy:webapp:<\u9879\u76ee\u540d>\n#qpy://localhost:<web\u670d\u52a1\u4fa6\u542c\u7684\u7aef\u53e3>/<\u9ed8\u8ba4\u4e3b\u8def\u5f84>\n

      \u4f8b\u5982\uff1a

      #qpy:webapp:Hello QPython\n#qpy://localhost:8080/hello\n\nfrom bottle import route, run, Bottle\n\napp = Bottle()\n\n@route('/hello')\ndef hello():\n    return '<h1>Hello from QPython!</h1>'\n\nrun(app, host='localhost', port=8080)\n
      "},{"location":"getting-started/#q","title":"Q \u6a21\u5f0f\uff08\u65e0\u63a7\u5236\u53f0\u6a21\u5f0f\uff09","text":"

      \u9759\u9ed8\u6a21\u5f0f\u8fd0\u884c\u811a\u672c\uff0c\u4e0d\u663e\u793a\u63a7\u5236\u53f0\u3002\u9700\u5728\u811a\u672c\u5f00\u5934\u6dfb\u52a0 header\uff1a

      #qpy:quiet\n\nimport time\n\nwhile True:\n    # \u60a8\u7684\u540e\u53f0\u4efb\u52a1\n    time.sleep(60)\n
      \u5982\u679c\u9700\u8981\u8fd0\u884c\u5e26 GUI \u7684 QSL4A \u7a0b\u5e8f\u4e14\u4e0d\u5e0c\u671b\u663e\u793a\u63a7\u5236\u53f0\u4fe1\u606f\uff0c\u63a8\u8350\u4f7f\u7528\u6b64\u6a21\u5f0f\u3002

      "},{"location":"getting-started/#6","title":"6. \u793e\u533a\u4e0e\u652f\u6301","text":"

      \u8bbf\u95ee QPython.org \u83b7\u53d6\u6587\u6863\u3001\u7528\u6237\u793e\u533a\u53ca\u5e2e\u52a9\u95ee\u7b54\u3002

      \u793e\u533a\u94fe\u63a5\uff1a - Facebook \u7fa4\u7ec4 - GitHub - \u95ee\u9898\u53cd\u9988

      \u4e0b\u4e00\u6b65\uff1a - \u5c1d\u8bd5 Hello World \u6559\u7a0b - \u63a2\u7d22 QSL4A API \u4ee5\u96c6\u6210 Android - \u4e86\u89e3 QPython \u7248\u672c

      "},{"location":"getting-started/#_10","title":"\u89c6\u9891\u4ecb\u7ecd","text":""},{"location":"getting-started/#_11","title":"\u4e0b\u4e00\u6b65","text":"

      \u5982\u679c\u60a8\u5df2\u7ecf\u521d\u6b65\u4e86\u89e3\u4e86 QPython \u7684\u529f\u80fd\uff0c\u6b22\u8fce\u5f00\u59cb\u4f53\u9a8c\u7f16\u7a0b\u7684\u4e50\u8da3\uff01\u8bd5\u8bd5 Hello World \u6559\u7a0b \u8fc8\u51fa\u60a8\u7684\u7b2c\u4e00\u6b65\u3002

      "},{"location":"qpypi-guide/","title":"QPYPI","text":"

      \u60a8\u53ef\u4ee5\u901a\u8fc7\u5b89\u88c5\u5305\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

      "},{"location":"qpypi-guide/#_1","title":"\u5305\u5b89\u88c5\u652f\u6301","text":""},{"location":"qpypi-guide/#python","title":"\u7eaf Python \u5305","text":"

      QPython \u652f\u6301\u4f7f\u7528\u7eaf Python \u5f00\u53d1\u7684 Python \u5305\u3002\u60a8\u53ef\u4ee5\u76f4\u63a5\u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216\u4eea\u8868\u76d8\u4e0a\u7684 QPYPI \u4f7f\u7528 pip install \u5b89\u88c5\u8fd9\u4e9b\u5305\u3002

      "},{"location":"qpypi-guide/#_2","title":"\u9884\u7f16\u8bd1\u5305","text":"

      \u5982\u679c\u67d0\u4e9b\u5305\uff08\u6216\u5b83\u4eec\u7684\u4f9d\u8d56\uff09\u662f\u7528 Rust/C/C++ \u5f00\u53d1\u7684\uff0cQPython \u65e0\u6cd5\u76f4\u63a5\u652f\u6301\u5b83\u4eec\uff0c\u56e0\u4e3a QPython \u4e0a\u6ca1\u6709\u7f16\u8bd1\u5668\u5de5\u5177\u94fe\u652f\u6301\u3002\u4f46\u662f\uff0cQPython \u56e2\u961f\u5df2\u7ecf\u9884\u7f16\u8bd1\u4e86\u4e00\u4e9b\u5e38\u7528\u5305\uff0c\u5e76\u5728 QPython \u7684 QPYPI/Extensions \u4e2d\u53d1\u5e03\uff0c\u4f9b\u7528\u6237\u8f7b\u677e\u5b89\u88c5\u3002

      "},{"location":"qpypi-guide/#_3","title":"\u5b89\u88c5\u9884\u7f16\u8bd1\u5305","text":"

      \u60a8\u53ef\u4ee5\u901a\u8fc7\u4ee5\u4e0b\u65b9\u5f0f\u5b89\u88c5\u9884\u7f16\u8bd1\u5305\uff1a

      1. \u901a\u8fc7 QPython \u5e94\u7528\uff1a\u76f4\u63a5\u4ece QPython \u5e94\u7528\u5185\u7684 QPYPI \u6216 Extensions \u5b89\u88c5
      2. \u901a\u8fc7 PyPI\uff1a\u8bbf\u95ee https://pypi.org/user/qpythonx/ \u67e5\u770b\u53ef\u7528\u7684\u5305
      3. \u901a\u8fc7 pip \u547d\u4ee4\uff1a
      4. pip install xxx-qpython - \u5e26 -qpython \u540e\u7f00\u7684\u5305
      5. pip install xxx-aipy - \u5e26 -aipy \u540e\u7f00\u7684\u5305\uff08\u901a\u5e38\u662f AI/ML \u76f8\u5173\u7684\u5305\uff09

      \u6ce8\u610f\uff1a\u6211\u4eec\u901a\u5e38\u6839\u636e\u5305\u7684\u9884\u671f\u7528\u9014\u6dfb\u52a0\u8fd9\u4e9b\u540e\u7f00\u4e4b\u4e00\u3002

      "},{"location":"qpypi-guide/#_4","title":"\u8bf7\u6c42\u65b0\u5305","text":"

      \u5982\u679c\u60a8\u9700\u8981\u5f53\u524d\u4e0d\u652f\u6301\u7684\u5305\uff1a

      • \u5728 qpython.org \u9879\u76ee \u4e2d\u63d0\u51fa\u95ee\u9898
      • QPython \u56e2\u961f\u5c06\u8003\u8651\u9884\u7f16\u8bd1\u5e76\u5c06\u5176\u6dfb\u52a0\u5230\u4ed3\u5e93\u4e2d

      \u83b7\u53d6\u66f4\u591a\u5e2e\u52a9\u548c\u53c2\u4e0e\u793e\u533a\u7684\u65b9\u5f0f\uff0c\u8bf7\u53c2\u9605 \u793e\u533a\u4e0e\u53cd\u9988 \u90e8\u5206\u3002

      \u6ce8\u610f\uff1a\u7531\u4e8e\u4e0d\u540c\u7684\u8ba1\u7b97\u673a\u67b6\u6784\uff0c\u6211\u4eec\u65e0\u6cd5\u4fdd\u8bc1 QPYPI \u5305\u542b PyPI \u4e0a\u7684\u6240\u6709\u5305\u3002

      "},{"location":"qpython-x/","title":"QPython \u7248\u672c","text":"

      QPython \u662f Android \u7684 Python \u5f15\u64ce\u3002\u5b83\u5305\u542b\u4ee4\u4eba\u60ca\u53f9\u7684\u529f\u80fd\uff0c\u5982 Python \u89e3\u91ca\u5668\u3001\u8fd0\u884c\u73af\u5883\u3001\u7f16\u8f91\u5668\u3001QPYI \u548c\u96c6\u6210\u7684 SL4A\u3002\u5b83\u8ba9\u60a8\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 Android \u4e0a\u4f7f\u7528 Python\u3002\u800c\u4e14\u5b83\u662f\u514d\u8d39\u7684\u3002

      QPython \u5df2\u7ecf\u5728\u5168\u7403\u62e5\u6709\u6570\u767e\u4e07\u7528\u6237\uff0c\u4e5f\u662f\u4e00\u4e2a\u5f00\u6e90\u9879\u76ee\u3002

      \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

      "},{"location":"qpython-x/#qpython_1","title":"QPython","text":"

      \u6807\u51c6\u7248\uff1a\u9488\u5bf9 AI \u6027\u80fd\u548c\u901a\u7528\u5e94\u7528\u5546\u5e97\u517c\u5bb9\u6027\u4f18\u5316

      \u4e3b\u8981\u7248\u672c\uff0c\u53ef\u5728 Google Play \u548c\u5176\u4ed6\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002\u6b64\u7248\u672c\u4e13\u6ce8\u4e8e AI \u529f\u80fd\uff0c\u4f7f AI \u65f6\u4ee3\u7528\u6237\u66f4\u5bb9\u6613\u5b66\u4e60\u548c\u4f7f\u7528 Python\u3002

      \u4e3b\u8981\u7279\u6027\uff1a - AI \u9a71\u52a8\u7684\u7f16\u7801\u8f85\u52a9\u548c\u5b66\u4e60\u5de5\u5177 - \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668\uff1a\u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51 - \u652f\u6301\u591a\u79cd\u9879\u76ee\u7c7b\u578b\uff1a\u63a7\u5236\u53f0\u3001SL4A\u3001WebApp - \u65b9\u4fbf\u7684\u4e8c\u7ef4\u7801\u8bfb\u53d6\u5668\uff0c\u7528\u4e8e\u5c06\u4ee3\u7801\u4f20\u8f93\u5230\u624b\u673a - QPYPI \u548c\u81ea\u5b9a\u4e49\u4ed3\u5e93\uff0c\u7528\u4e8e\u9884\u7f16\u8bd1 wheel \u5305 -\u6613\u4e8e\u4f7f\u7528\u7684\u8bed\u6cd5\u9ad8\u4eae\u7f16\u8f91\u5668 - \u5b8c\u5584\u7684\u6587\u6863\u548c\u793e\u533a\u652f\u6301

      \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

      \u4e0b\u8f7d\uff1a \u53ef\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

      "},{"location":"qpython-x/#qpython_2","title":"QPython+","text":"

      \u793e\u533a\u7248\uff1a\u516c\u5f00\u652f\u6301\u5404\u79cd\u793e\u533a\u9a71\u52a8\u7684\u529f\u80fd\uff1b\u53ef\u5728\u90e8\u5206\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

      \u793e\u533a\u5f00\u6e90\u7248\u672c\uff08\u6b63\u5728\u89c4\u5212\u548c\u51c6\u5907\u4e2d\uff09\u3002\u6b64\u7248\u672c\u4e13\u4e3a\u60f3\u8981\u53c2\u4e0e QPython \u9879\u76ee\u5f00\u53d1\u7684\u8d21\u732e\u8005\u800c\u8bbe\u8ba1\uff0c\u652f\u6301\u9488\u5bf9\u4e0d\u540c\u5236\u9020\u5546\u7684\u5b9a\u5236\u3002

      \u4e3b\u8981\u7279\u6027\uff1a - \u793e\u533a\u9a71\u52a8\u5f00\u53d1 - \u652f\u6301\u4f9b\u5e94\u5546\u5b9a\u5236 - \u66f4\u7075\u6d3b\u7684\u914d\u7f6e\u9009\u9879 - \u5f00\u653e\u4f9b\u8d21\u732e\u8005\u52a0\u5165\u5f00\u53d1

      \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

      \u4e0b\u8f7d\uff1a \u5c06\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

      \u6ce8\u610f\uff1a \u6b64\u7248\u672c\u76ee\u524d\u6b63\u5728\u89c4\u5212\u51c6\u5907\u4e2d\u3002\u8bf7\u5173\u6ce8\u66f4\u65b0\uff01

      "},{"location":"qpython-x/#qpython-plus","title":"QPython Plus","text":"

      QPython+ \u5b8c\u5168\u8bbf\u95ee\u7248\uff1a\u6388\u4e88\u8c03\u7528\u6240\u6709 Android \u63a5\u53e3\u7684\u5b8c\u6574\u6743\u9650\u3002\u4e0b\u8f7d\u94fe\u63a5\u4ec5\u901a\u8fc7\u5b98\u65b9\u4e91\u76d8\u63d0\u4f9b\u3002

      \u5177\u6709\u6269\u5c55\u6743\u9650\u7684\u7279\u6b8a\u7248\u672c\uff0c\u63d0\u4f9b\u5bf9\u8bbe\u5907\u7684\u6700\u5927\u63a7\u5236\u3002\u7531\u4e8e\u5176\u654f\u611f\u7684\u6743\u9650\u8981\u6c42\uff0c\u6b64\u7248\u672c\u4e0d\u4f1a\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u53d1\u5e03\u3002

      \u4e3b\u8981\u7279\u6027\uff1a - \u5b8c\u6574\u7684 SL4A API \u8bbf\u95ee\uff0c\u5305\u62ec\u654f\u611f\u529f\u80fd - SMS/\u901a\u8bdd\u63a7\u5236 API - \u9ad8\u7ea7\u7cfb\u7edf\u96c6\u6210 - \u6700\u5927\u7684\u8bbe\u5907\u63a7\u5236\u80fd\u529b

      \u6743\u9650\uff1a \u9700\u8981\u5e7f\u6cdb\u7684\u6743\u9650\uff0c\u5305\u62ec\uff1a - \u84dd\u7259 - \u4f4d\u7f6e\uff08GPS\uff09 - \u8bfb\u53d6/\u53d1\u9001\u77ed\u4fe1 - \u6253\u7535\u8bdd - \u76f8\u673a\u548c\u9ea6\u514b\u98ce - \u7cfb\u7edf\u8bbe\u7f6e - \u4ee5\u53ca\u5176\u4ed6\u654f\u611f\u6743\u9650

      \u4e0b\u8f7d\uff1a \u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\u3002\u4ec5\u901a\u8fc7\u7279\u6b8a\u6e20\u9053\u5206\u53d1\u3002

      \u91cd\u8981\u63d0\u793a\uff1a QPython \u4e0d\u4f1a\u5728\u540e\u53f0\u672a\u7ecf\u60a8\u77e5\u6089\u4f7f\u7528\u8fd9\u4e9b\u6743\u9650\u3002\u5982\u679c\u4f7f\u7528 SL4A API \u65f6\u51fa\u73b0\u5f02\u5e38\uff0c\u8bf7\u68c0\u67e5\u7cfb\u7edf\u8bbe\u7f6e\u4e2d\u662f\u5426\u5df2\u542f\u7528\u76f8\u5173\u6743\u9650\u3002

      "},{"location":"tutorial-hello-world/","title":"\u7f16\u5199\"Hello World\"","text":""},{"location":"tutorial-hello-world/#hello-world_1","title":"Hello world","text":"

      \u597d\u7684\uff0c\u5728\u60a8\u5bf9 QPython \u6709\u4e86\u4e00\u5b9a\u7684\u4e86\u89e3\u4e4b\u540e\uff0c\u8ba9\u6211\u4eec\u5728 QPython \u4e2d\u521b\u5efa\u6211\u4eec\u7684\u7b2c\u4e00\u4e2a\u7a0b\u5e8f\u3002\u663e\u7136\uff0c\u5b83\u5c06\u662f helloworld.py\u3002;)

      \u542f\u52a8 QPython\uff0c\u6253\u5f00\u7f16\u8f91\u5668\u5e76\u8f93\u5165\u4ee5\u4e0b\u4ee3\u7801\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello, QPYTHON!')\n

      \u6beb\u65e0\u7591\u95ee\uff0c\u5b83\u4e0e\u5176\u4ed6\u4efb\u4f55 hello-world \u7a0b\u5e8f\u5e76\u65e0\u4e0d\u540c\u3002\u6267\u884c\u65f6\uff0c\u5b83\u53ea\u662f\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u5f39\u51fa\u6d88\u606f\uff08\u89c1\u9876\u90e8\u622a\u56fe\uff09\u3002\u65e0\u8bba\u5982\u4f55\uff0c\u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684 QPython \u7a0b\u5e8f\u793a\u4f8b\u3002

      "},{"location":"tutorial-hello-world/#_1","title":"\u4ee3\u7801\u7406\u89e3","text":"

      \u5b83\u4ee5 import androidhelper \u5f00\u5934\u2014\u2014\u8fd9\u662f QPython \u4e2d\u6700\u6709\u7528\u7684\u6a21\u5757\uff0c\u5b83\u5c01\u88c5\u4e86 Python \u4e2d\u53ef\u7528\u7684\u51e0\u4e4e\u6240\u6709\u4e0e Android \u7684\u63a5\u53e3\u3002\u4efb\u4f55\u5728 QPython \u4e2d\u5f00\u53d1\u7684\u811a\u672c\u90fd\u4ee5\u8fd9\u4e2a\u8bed\u53e5\u5f00\u5934\uff08\u81f3\u5c11\u5982\u679c\u5b83\u58f0\u79f0\u8981\u4e0e\u7528\u6237\u901a\u4fe1\u7684\u8bdd\uff09\u3002\u5728\u6b64\u5904\u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u5e93 \u548c import \u8bed\u53e5 \u7684\u5185\u5bb9\u3002

      \u63a5\u4e0b\u6765\u6211\u4eec\u521b\u5efa\u4e00\u4e2a droid \u5bf9\u8c61\uff08\u5b9e\u9645\u4e0a\u662f\u4e00\u4e2a\u7c7b\uff09\uff0c\u5b83\u5bf9\u4e8e\u8c03\u7528 RPC \u51fd\u6570\u4ee5\u4e0e Android \u901a\u4fe1\u662f\u5fc5\u8981\u7684\u3002

      \u6211\u4eec\u4ee3\u7801\u7684\u6700\u540e\u4e00\u884c\u8c03\u7528\u4e86\u8fd9\u6837\u7684\u51fd\u6570\uff0cdroid.makeToast()\uff0c\u5b83\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u4e00\u4e2a\u5c0f\u7684\u5f39\u51fa\u6d88\u606f\uff08\"toast\"\uff09\u3002

      \u597d\u7684\uff0c\u8ba9\u6211\u4eec\u6dfb\u52a0\u4e00\u4e9b\u66f4\u591a\u7684\u529f\u80fd\u3002\u8ba9\u5b83\u8be2\u95ee\u7528\u6237\u540d\u5e76\u5411\u7528\u6237\u6253\u62db\u547c\u3002

      "},{"location":"tutorial-hello-world/#_2","title":"\u66f4\u591a\u793a\u4f8b","text":"

      \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 dialogGetInput \u8c03\u7528\u663e\u793a\u4e00\u4e2a\u5e26\u6709\u6807\u9898\u3001\u63d0\u793a\u3001\u7f16\u8f91\u5b57\u6bb5\u548c \u786e\u5b9a \u548c \u53d6\u6d88 \u6309\u94ae\u7684\u7b80\u5355\u5bf9\u8bdd\u6846\u3002\u7528\u4ee5\u4e0b\u4ee3\u7801\u66ff\u6362\u60a8\u7684\u6700\u540e\u4e00\u884c\u4ee3\u7801\u5e76\u5c06\u5176\u4fdd\u5b58\u4e3a hello1.py\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\n

      \u597d\u7684\uff0c\u6211\u8ba4\u4e3a\u5b83\u5e94\u8be5\u8fd4\u56de\u4efb\u4f55\u54cd\u5e94\uff0c\u4efb\u4f55\u7528\u6237\u53cd\u5e94\u3002\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u6211\u5199 respond = ...\u3002\u4f46\u8fd9\u4e2a\u8c03\u7528\u5b9e\u9645\u4e0a\u8fd4\u56de\u4ec0\u4e48\uff1f\u8ba9\u6211\u4eec\u68c0\u67e5\u4e00\u4e0b\u3002\u53ea\u9700\u5728\u6700\u540e\u4e00\u884c\u540e\u6dfb\u52a0 print \u8bed\u53e5\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\n

      \u7136\u540e\u4fdd\u5b58\u5e76\u8fd0\u884c\u5b83...

      \u54ce\u5440\uff01\u6ca1\u6709\u6253\u5370\uff1f\u522b\u62c5\u5fc3\u3002\u53ea\u9700\u62c9\u4e0b\u901a\u77e5\u680f\uff0c\u60a8\u5c31\u4f1a\u770b\u5230\"QPython Program Output: hello1.py\"\u2014\u2014\u70b9\u51fb\u5b83\uff01

      \u5982\u60a8\u6240\u89c1\uff0cdroid.dialogGetInput() \u8fd4\u56de\u4e00\u4e2a\u5305\u542b\u4e09\u4e2a\u5b57\u6bb5\u7684 JSON \u5bf9\u8c61\u3002\u6211\u4eec\u53ea\u9700\u8981\u4e00\u4e2a\u2014\u2014result\uff0c\u5176\u4e2d\u5305\u542b\u7528\u6237\u5b9e\u9645\u8f93\u5165\u7684\u5185\u5bb9\u3002

      \u8ba9\u6211\u4eec\u6dfb\u52a0\u811a\u672c\u7684\u53cd\u5e94\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nmessage = f'Hello, {respond.result}!'\ndroid.makeToast(message)\n

      \u6700\u540e\u4e24\u884c\uff081\uff09\u683c\u5f0f\u5316\u6d88\u606f\uff0c\uff082\uff09\u4ee5 toast \u5f62\u5f0f\u5411\u7528\u6237\u663e\u793a\u6d88\u606f\u3002\u5982\u679c\u60a8\u4ecd\u7136\u4e0d\u77e5\u9053 f-string \u662f\u4ec0\u4e48\u610f\u601d\uff0c\u8bf7\u53c2\u9605 Python \u6587\u6863\u3002

      \u54c7\uff01\u5b83\u5de5\u4f5c\u4e86\uff01;)

      \u73b0\u5728\u6211\u8981\u5728\u90a3\u91cc\u6dfb\u52a0\u4e00\u4e9b\u903b\u8f91\u3002\u60f3\u4e00\u60f3\uff1a\u5982\u679c\u7528\u6237\u70b9\u51fb \u53d6\u6d88 \u6309\u94ae\uff0c\u6216\u8005\u70b9\u51fb \u786e\u5b9a \u4f46\u5c06\u8f93\u5165\u5b57\u6bb5\u7559\u7a7a\uff0c\u4f1a\u53d1\u751f\u4ec0\u4e48\uff1f

      \u60a8\u53ef\u4ee5\u73a9\u8fd9\u4e2a\u7a0b\u5e8f\uff0c\u68c0\u67e5 respond \u53d8\u91cf\u5728\u6bcf\u79cd\u60c5\u51b5\u4e0b\u5305\u542b\u4ec0\u4e48\u3002

      \u9996\u5148\uff0c\u6211\u60f3\u5c06\u7528\u6237\u8f93\u5165\u7684\u6587\u672c\u653e\u5165\u4e00\u4e2a\u5355\u72ec\u7684\u53d8\u91cf\u4e2d\uff1aname = respond.result\u3002\u7136\u540e\u6211\u68c0\u67e5\u5b83\uff0c\u5982\u679c\u5b83\u5305\u542b\u4efb\u4f55\u771f\u5b9e\u6587\u672c\uff0c\u5b83\u5c06\u88ab\u89c6\u4e3a\u540d\u79f0\u5e76\u7528\u4e8e\u95ee\u5019\u3002\u5426\u5219\uff0c\u5c06\u663e\u793a\u53e6\u4e00\u6761\u6d88\u606f\u3002\u5c06\u7b2c\u4e94\u884c message = f'Hello, {respond.result}!' \u66ff\u6362\u4e3a\u4ee5\u4e0b\u4ee3\u7801\uff1a

      name = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\n

      \u4f7f\u7528\u5de5\u5177\u680f\u4e0a\u7684 < \u548c > \u6309\u94ae\u6765\u7f29\u8fdb/\u53d6\u6d88\u7f29\u8fdb if \u8bed\u53e5\u4e2d\u7684\u884c\uff08\u6216\u8005\u53ea\u9700\u4f7f\u7528\u7a7a\u683c/\u9000\u683c\u952e\uff09\u3002\u60a8\u53ef\u4ee5\u5728 \u6b64\u5904 \u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u7f29\u8fdb\u7684\u5185\u5bb9\uff1bif \u8bed\u53e5\u5728 \u6b64\u5904 \u63cf\u8ff0\u3002

      \u9996\u5148\uff0c\u6211\u4eec\u5c06\u7528\u6237\u8f93\u5165\u653e\u5165 name \u53d8\u91cf\u3002\u7136\u540e\u6211\u4eec\u68c0\u67e5 name \u662f\u5426\u5305\u542b\u4efb\u4f55\u5185\u5bb9\uff1f\u5982\u679c\u7528\u6237\u7559\u7a7a\u884c\u5e76\u70b9\u51fb \u786e\u5b9a\uff0c\u8fd4\u56de\u503c\u662f\u7a7a\u5b57\u7b26\u4e32 ''\u3002\u5982\u679c\u6309\u4e0b\u4e86 \u53d6\u6d88 \u6309\u94ae\uff0c\u8fd4\u56de\u503c\u662f None\u3002\u5728 if \u8bed\u53e5\u4e2d\uff0c\u4e24\u8005\u90fd\u88ab\u89c6\u4e3a\u5047\u3002\u56e0\u6b64\uff0c\u53ea\u6709\u5f53 name \u5305\u542b\u4efb\u4f55\u6709\u610f\u4e49\u7684\u5185\u5bb9\u65f6\uff0cthen \u8bed\u53e5\u624d\u4f1a\u6267\u884c\uff0c\u5e76\u663e\u793a\u95ee\u5019\u8bed\"Hello, ...!\"\u3002\u5982\u679c\u8f93\u5165\u4e3a\u7a7a\uff0c\u7528\u6237\u5c06\u770b\u5230\"Hey! And you're not very polite, %Username%!\"\u6d88\u606f\u3002

      \u597d\u7684\uff0c\u8fd9\u662f\u6574\u4e2a\u7a0b\u5e8f\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nname = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\ndroid.makeToast(message)\n
      "},{"location":"tutorial-hello-world/#_3","title":"\u8fd0\u884c\u6548\u679c","text":""},{"location":"tutorial-hello-world/#_4","title":"\u4e0b\u4e00\u6b65","text":"

      \u5bf9\u4e8e Python \u65b0\u7528\u6237\uff0c\u63a8\u8350\u5b66\u4e60 Python \u8bed\u6cd5\u5b9e\u8df5 \u8bfe\u7a0b\u6765\u8fdb\u4e00\u6b65\u5b66\u4e60 Python\uff0c\u6216\u8005\u5728 QPython \u7cbe\u9009\u8bfe\u7a0b \u4e2d\u5bfb\u627e\u60f3\u8981\u5b66\u4e60\u7684\u5185\u5bb9\u3002

      "},{"location":"whats-new/","title":"\u66f4\u65b0\u65e5\u5fd7","text":""},{"location":"whats-new/#v392-v393","title":"v3.9.2 / v3.9.3","text":"
      • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
      • \u7f16\u8f91\u5668\u91cd\u5927\u66f4\u65b0\uff0c\u5e26\u6765\u66f4\u6d41\u7545\u7684\u7f16\u8f91\u4f53\u9a8c
      • \u5176\u4ed6\u5404\u79cd\u5c0f\u6539\u8fdb
      "},{"location":"whats-new/#v391","title":"v3.9.1","text":"
      • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
      • \u6269\u5c55\u5305\u73b0\u5728\u652f\u6301 MCP
      • \u9519\u8bef\u4fee\u590d
      "},{"location":"whats-new/#v390","title":"v3.9.0","text":"
      • SDK \u5347\u7ea7\uff0c\u6574\u5408\u6700\u65b0\u7684 Android \u529f\u80fd
      • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
      • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
      • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
      "},{"location":"whats-new/#v3811","title":"v3.8.11","text":"
      • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
      • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
      • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
      "},{"location":"whats-new/#v3810","title":"v3.8.10","text":"
      • \u5185\u7f6e Ollama \u5347\u7ea7\uff1a\u73b0\u5728\u60a8\u53ef\u4ee5\u5728 QPython \u4e2d\u8f7b\u677e\u672c\u5730\u8fd0\u884c Qwen3 / Gemma3 \u6a21\u578b\uff01
      • \u6dfb\u52a0\u4e86\u5f3a\u5927\u7684 MCP \u5e93\uff1a\u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 mcp \u5e93\uff0c\u8ba9\u60a8\u968f\u65f6\u968f\u5730\u643a\u5e26\u5f3a\u5927\u7684 MCP \u529f\u80fd\uff01
      "},{"location":"whats-new/#v389","title":"v3.8.9","text":"

      \u91cd\u5927\u66f4\u65b0\uff01AI \u7f16\u7a0b\u5b8c\u5168\u96c6\u6210\u5230 QPython\uff0c\u8ba9\u60a8\u7684\u7f16\u7a0b\u66f4\u8f7b\u677e\uff01

      • \u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u652f\u6301\uff1a\u65b0\u652f\u6301 AIPyApp\uff0c\u5728 QPython \u4e2d\u5b9e\u73b0\u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u3002\u76ee\u524d\u5904\u4e8e\u6d4b\u8bd5\u9636\u6bb5 - \u52a0\u5165\u6211\u4eec\u7684\u793e\u533a\u83b7\u53d6\u4f7f\u7528\u8bf4\u660e
      • \u65b0 QSL4A \u529f\u80fd\uff1a\u6dfb\u52a0 notebookOpen \u51fd\u6570\uff0c\u652f\u6301\u81ea\u7136\u8bed\u8a00\u63a7\u5236\u6253\u5f00 Notebook \u6587\u4ef6
      • \u5185\u7f6e\u7f16\u8f91\u5668\u5347\u7ea7\uff1a\u589e\u5f3a\u7f16\u8f91\u5668\u529f\u80fd\uff0c\u652f\u6301\u6253\u5f00\u548c\u6d4f\u89c8\u5404\u79cd\u6587\u672c\u6587\u4ef6
      • \u4fbf\u6377\u7684\u6587\u4ef6\u7ba1\u7406\uff1a\u5728\u6587\u4ef6\u7ba1\u7406\u5668\u4e2d\u6dfb\u52a0\u5185\u90e8\u5b58\u50a8\u5165\u53e3\uff0c\u5feb\u901f\u8bbf\u95ee\u60a8\u7684\u6587\u4ef6
      "},{"location":"whats-new/#v388","title":"v3.8.8","text":"
      • \u6587\u4ef6\u8bbf\u95ee\u6743\u9650\u63a7\u5236\u7684\u91cd\u8981\u6539\u8fdb\uff0c\u5141\u8bb8\u7528\u6237\u7075\u6d3b\u5730\u901a\u8fc7 QPython \u7f16\u7a0b\u542f\u7528\u6216\u7981\u7528\u5916\u90e8\u5b58\u50a8\u6587\u4ef6\u7684\u8bbf\u95ee
      • SDK \u5347\u7ea7\uff0c\u589e\u5f3a\u4e86\u5bf9\u65b0\u7248 Android \u7684\u652f\u6301\u548c\u517c\u5bb9\u6027
      • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Anthropic \u548c Google GenAI \u5e93
      "},{"location":"whats-new/#v387","title":"v3.8.7","text":"
      • \u5728\u73b0\u6709 Tkinter \u652f\u6301\u57fa\u7840\u4e0a\uff0c\u5728 Extensions -> Tools \u4e2d\u6dfb\u52a0\u4e86\u4f7f\u7528 Turtle \u7ed8\u5236\u54c6\u5566A\u68a6\u7684\u793a\u4f8b\u4ee3\u7801
      • \u4f18\u5316\u4e86\u624b\u673a\u6743\u9650\u83b7\u53d6\u6d41\u7a0b\uff0c\u63d0\u5347\u7528\u6237\u4f53\u9a8c\u548c\u64cd\u4f5c\u4fbf\u5229\u6027
      • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Google Gen AI \u5e93\uff0c\u65b9\u4fbf\u8bbf\u95ee Gemini Developer API \u548c Vertex AI
      "},{"location":"whats-new/#v386","title":"v3.8.6","text":"
      • Tkinter \u652f\u6301\uff1a\u73b0\u5728\u652f\u6301 Tkinter \u5e93\uff0c\u53ef\u901a\u8fc7 XServer \u8bbf\u95ee\u3002\u8bf7\u8bbf\u95ee www.qpython.org \u7684\u4e91\u76d8\"Extra\"\u94fe\u63a5\u4e0b\u8f7d\u6240\u9700\u6587\u4ef6
      • \u5b58\u50a8\u6743\u9650\u66f4\u65b0\uff1a\u4e3a\u6539\u5584\u7528\u6237\u4f53\u9a8c\uff0c\u6211\u4eec\u6dfb\u52a0\u4e86\u8bfb\u53d6\u624b\u673a\u5b58\u50a8\u7684\u6743\u9650\uff0c\u7528\u4e8e\u8bbf\u95ee\u5b58\u50a8\u5728\u5176\u4ed6\u76ee\u5f55\u4e2d\u7684 Python \u7a0b\u5e8f

      \u6b64\u66f4\u65b0\u540e\uff0cQPython \u548c QPythonPlus\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff0c\u4e13\u4e3a\u9700\u8981\u66f4\u591a\u654f\u611f\u6743\u9650\u7684\u9ad8\u7ea7\u7528\u6237\u8bbe\u8ba1\uff09\u5c06\u4fdd\u6301\u540c\u6b65\u7684\u7248\u672c\u53f7\u3002

      "},{"location":"whats-new/#v352-2025225","title":"v3.5.2 (2025/2/25)","text":"

      \u4e0e\u5f00\u6e90 LLM \u90e8\u7f72\u5de5\u5177 Ollama \u4ee5\u53ca DeepSeek \u5f00\u53d1\u7684 DeepSeek \u5b9e\u73b0\u65e0\u7f1d\u96c6\u6210\uff01

      \u529f\u80fd\uff1a - \u96f6\u95e8\u69db\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5404\u79cd\u5927\u578b\u8bed\u8a00\u6a21\u578b - \u5feb\u901f\u90e8\u7f72 DeepSeek \u7b49\u5c16\u7aef AI \u6a21\u578b - \u4eab\u53d7\u7b80\u7ea6\u7684 API \u8c03\u7528\u4f53\u9a8c - \u6784\u5efa\u5b8c\u5168\u79bb\u7ebf\u7684\u667a\u80fd\u7f16\u7a0b\u73af\u5883

      \u80fd\u529b\uff1a - \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u52a0\u8f7d/\u7ba1\u7406 LLM \u6a21\u578b - \u57fa\u4e8e\u672c\u5730\u8ba1\u7b97\u7684\u5b9e\u65f6\u4f4e\u5ef6\u8fdf\u54cd\u5e94

      "},{"location":"whats-new/#v350","title":"v3.5.0","text":"
      • Python \u5347\u7ea7\u5230 3.12.8
      • \u6539\u8fdb\u4eea\u8868\u76d8\uff0c\u529f\u80fd\u66f4\u6e05\u6670\u3001\u66f4\u4eba\u6027\u5316
      • \u6dfb\u52a0\u4e86\u4f17\u591a\u7b2c\u4e09\u65b9\u5305\uff1aPyTorch / Twisted / Scrapy / FastAPI ...
      "},{"location":"whats-new/#v338","title":"v3.3.8","text":"
      • \u4fee\u590d\u4e86 NumPy \u517c\u5bb9\u6027\u95ee\u9898
      "},{"location":"whats-new/#v335","title":"v3.3.5","text":"
      • \u5347\u7ea7 Python \u5185\u6838\u5230 3.11.9
      • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u4e0d\u663e\u793a\u6a21\u5757\u5b89\u88c5\u72b6\u6001\u7684 bug
      • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u5220\u9664\u6a21\u5757\u5931\u8d25\u7684 bug
      • \u4fee\u590d\u4e86\u5176\u4ed6 bug
      "},{"location":"whats-new/#v334","title":"v3.3.4","text":"
      • \u6dfb\u52a0\u4e86 OpenAI/Langchain/APIGPTCloud AI \u5305
      • \u79fb\u9664\u4e0d\u5fc5\u8981\u7684\u6587\u4ef6\u4ee5\u51cf\u5c11\u5927\u5c0f
      "},{"location":"whats-new/#v325","title":"v3.2.5","text":"
      • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570
      • \u5176\u4ed6\u9519\u8bef\u4fee\u590d
      "},{"location":"whats-new/#v323","title":"v3.2.3","text":"
      • \u66f4\u65b0 Python \u7248\u672c\u5230 3.11.0
      • \u66f4\u65b0 IPython \u7248\u672c\u5230 8.6.0
      • \u66f4\u65b0 pip \u7248\u672c\u5230 22.3.1
      • \u66f4\u65b0\u79d1\u5b66\u8ba1\u7b97\u5305\uff0c\u81ea\u52a8\u8f6f\u94fe\u63a5
      • \u51cf\u5c11\u7a7a\u95f4\u4f7f\u7528
      • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570 + \u5176\u4ed6\u9519\u8bef\u4fee\u590d
      "},{"location":"whats-new/#v318","title":"v3.1.8","text":"
      • \u5728\u7ec8\u7aef\u4e2d\u6dfb\u52a0\u4e86\u64cd\u4f5c\u70ed\u952e
      • \u4fee\u590d\u4e86\u7f16\u8f91\u5668\u5728\u65cb\u8f6c\u65f6\u4e22\u5931\u5185\u5bb9\u7684\u95ee\u9898
      • \u4fee\u590d\u4e86\u5176\u4ed6 bug

      \u5728 Google Play \u4e0b\u8f7d

      "},{"location":"qsl4a/","title":"QSL4A\uff08Android \u811a\u672c\u5c42\uff09API \u6587\u6863","text":"

      QSL4A \u662f QPython \u7684 Android \u811a\u672c\u5c42\uff0c\u5141\u8bb8\u60a8\u4f7f\u7528 Python \u63a7\u5236 Android \u8bbe\u5907\u529f\u80fd\u3002

      "},{"location":"qsl4a/#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a toast \u6d88\u606f\ndroid.makeToast('Hello QPython!')\n\n# \u9707\u52a8\u8bbe\u5907\ndroid.vibrate(500)\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\uff08\u5148\u5f00\u59cb\u76d1\u63a7\uff09\nimport time\ndroid.batteryStartMonitoring()\ntime.sleep(0.5)  # \u7b49\u5f85\u6570\u636e\nbattery = droid.readBatteryData().result\nprint(f\"\u7535\u6c60\uff1a{battery['level']}%\")\n
      "},{"location":"qsl4a/#_2","title":"\u6587\u6863\u7ed3\u6784","text":""},{"location":"qsl4a/#_3","title":"\u6838\u5fc3\u6a21\u5757","text":"
      • Android \u57fa\u7840 - \u6838\u5fc3\u8fde\u63a5\u548c RPC
      • Intent \u7cfb\u7edf - Android Intent \u64cd\u4f5c
      • \u4e8b\u4ef6\u7cfb\u7edf - \u4e8b\u4ef6\u5904\u7406\u548c\u5e7f\u64ad
      "},{"location":"qsl4a/#ui","title":"UI \u7ec4\u4ef6","text":"
      • \u5bf9\u8bdd\u6846 - \u8b66\u62a5\u3001\u8f93\u5165\u3001\u9009\u62e9\u5bf9\u8bdd\u6846
      • \u5168\u5c4f UI - \u81ea\u5b9a\u4e49\u5e03\u5c40 UI
      • \u60ac\u6d6e\u7a97 - \u60ac\u6d6e\u7a97\u53e3
      • \u8f85\u52a9\u529f\u80fd - \u5c4f\u5e55\u81ea\u52a8\u5316
      "},{"location":"qsl4a/#_4","title":"\u7cfb\u7edf","text":"
      • \u7535\u6c60 - \u7535\u6c60\u76d1\u63a7
      • \u4f20\u611f\u5668 - \u8bbe\u5907\u4f20\u611f\u5668
      • \u5e94\u7528 - \u5e94\u7528\u7ba1\u7406
      • \u7cfb\u7edf\u4fe1\u606f - \u8bbe\u5907\u4fe1\u606f
      • \u8bbe\u7f6e - \u7cfb\u7edf\u8bbe\u7f6e
      • \u5524\u9192\u9501 - \u5524\u9192\u9501\u63a7\u5236
      • QPython \u63a5\u53e3 - \u811a\u672c\u6267\u884c
      • Activity \u7ed3\u679c - Activity \u7ed3\u679c\u5904\u7406
      "},{"location":"qsl4a/#_5","title":"\u786c\u4ef6","text":"
      • \u84dd\u7259 - \u84dd\u7259\u64cd\u4f5c
      • \u76f8\u673a - \u62cd\u7167\u548c\u5f55\u50cf
      • \u97f3\u9891/\u5f55\u97f3\u5668 - \u5f55\u97f3
      • \u7f51\u7edc\u6444\u50cf\u5934 - MJPEG \u6d41
      • USB \u4e32\u53e3 - USB \u4e3b\u673a\u4e32\u53e3
      "},{"location":"qsl4a/#_6","title":"\u8fde\u63a5","text":"
      • WiFi - WiFi \u64cd\u4f5c
      • \u4f4d\u7f6e - GPS \u548c\u4f4d\u7f6e
      • \u77ed\u4fe1 - \u77ed\u4fe1\u64cd\u4f5c
      • \u7535\u8bdd - \u6253\u7535\u8bdd\u548c\u6765\u7535\u4fe1\u606f
      • \u8054\u7cfb\u4eba - \u8054\u7cfb\u4eba\u7ba1\u7406
      • \u4fe1\u53f7\u5f3a\u5ea6 - \u4fe1\u53f7\u76d1\u63a7
      • FTP \u670d\u52a1\u5668 - \u5185\u7f6e FTP \u670d\u52a1\u5668
      "},{"location":"qsl4a/#_7","title":"\u5b58\u50a8","text":"
      • DocumentFile - \u6587\u4ef6\u64cd\u4f5c
      • \u526a\u8d34\u677f - \u526a\u8d34\u677f\u64cd\u4f5c
      • \u504f\u597d\u8bbe\u7f6e - \u5171\u4eab\u504f\u597d\u8bbe\u7f6e
      "},{"location":"qsl4a/#_8","title":"\u5a92\u4f53","text":"
      • \u5a92\u4f53\u64ad\u653e\u5668 - \u97f3\u9891/\u89c6\u9891\u64ad\u653e
      • \u56fe\u50cf\u5904\u7406 - \u56fe\u50cf\u64cd\u4f5c
      "},{"location":"qsl4a/#_9","title":"\u7279\u6b8a\u529f\u80fd","text":"
      • \u52a0\u5bc6 - \u52a0\u5bc6/\u89e3\u5bc6
      • PGPT AI - AI \u8bed\u97f3\u670d\u52a1
      "},{"location":"qsl4a/#_10","title":"\u7ed3\u679c\u5bf9\u8c61","text":"

      \u5927\u591a\u6570 QSL4A \u65b9\u6cd5\u8fd4\u56de\u4e00\u4e2a\u5e26\u6709\u4ee5\u4e0b\u5c5e\u6027\u7684 Result \u547d\u540d\u5143\u7ec4\uff1a - id - \u8bf7\u6c42 ID - result - \u5b9e\u9645\u7ed3\u679c\u6570\u636e - error - \u5982\u679c\u5931\u8d25\u5219\u4e3a\u9519\u8bef\u6d88\u606f

      result = droid.getClipboard()\nif result.error is None:\n    print(result.result)\nelse:\n    print(f\"\u9519\u8bef\uff1a{result.error}\")\n
      "},{"location":"qsl4a/connectivity/contacts/","title":"\u8054\u7cfb\u4eba API","text":"

      \u8bbf\u95ee\u548c\u7ba1\u7406\u8bbe\u5907\u8054\u7cfb\u4eba\u3002

      "},{"location":"qsl4a/connectivity/contacts/#_1","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":""},{"location":"qsl4a/connectivity/contacts/#pickcontact","title":"pickContact()","text":"

      \u663e\u793a\u8054\u7cfb\u4eba\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

      pickContact()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u8054\u7cfb\u4eba URI \u7684 Intent

      "},{"location":"qsl4a/connectivity/contacts/#pickphone","title":"pickPhone()","text":"

      \u663e\u793a\u7535\u8bdd\u53f7\u7801\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

      pickPhone()\n

      \u8fd4\u56de\uff1a \u9009\u4e2d\u7684\u7535\u8bdd\u53f7\u7801\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/contacts/#_2","title":"\u8054\u7cfb\u4eba\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#contactsget","title":"contactsGet()","text":"

      \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\u3002

      contactsGet(attributes=None)\n

      \u53c2\u6570\uff1a - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

      \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba JSONObject \u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetbyid","title":"contactsGetById()","text":"

      \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\u3002

      contactsGetById(id, attributes=None)\n

      \u53c2\u6570\uff1a - id (int): \u8054\u7cfb\u4eba ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

      \u8fd4\u56de\uff1a JSONObject \u8054\u7cfb\u4eba\u6570\u636e

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetcount","title":"contactsGetCount()","text":"

      \u83b7\u53d6\u8054\u7cfb\u4eba\u603b\u6570\u3002

      contactsGetCount()\n

      \u8fd4\u56de\uff1a \u6574\u6570\u8ba1\u6570

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetids","title":"contactsGetIds()","text":"

      \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba ID\u3002

      contactsGetIds()\n

      \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba ID \u6574\u6570\u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetattributes","title":"contactsGetAttributes()","text":"

      \u83b7\u53d6\u6240\u6709\u53ef\u80fd\u7684\u8054\u7cfb\u4eba\u5c5e\u6027\u3002

      contactsGetAttributes()\n

      \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#_3","title":"\u5185\u5bb9\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#querycontent","title":"queryContent()","text":"

      \u4f7f\u7528\u81ea\u5b9a\u4e49\u53c2\u6570\u67e5\u8be2\u5185\u5bb9\u89e3\u6790\u5668\u3002

      queryContent(uri, attributes=None, selection=None, selectionArgs=None, order=None)\n

      \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u5c5e\u6027 - selection (str, optional): WHERE \u5b50\u53e5 - selectionArgs (list, optional): \u9009\u62e9\u53c2\u6570 - order (str, optional): ORDER BY \u5b50\u53e5

      \u8fd4\u56de\uff1a JSONObject \u7ed3\u679c\u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#queryattributes","title":"queryAttributes()","text":"

      \u83b7\u53d6\u5185\u5bb9 URI \u7684\u5c5e\u6027\u3002

      queryAttributes(uri)\n

      \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI

      \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u7684 JSONArray

      "},{"location":"qsl4a/connectivity/contacts/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u9009\u62e9\u8054\u7cfb\u4eba\ncontact_uri = droid.pickContact().result\nprint(f\"Selected contact: {contact_uri}\")\n\n# \u9009\u62e9\u7535\u8bdd\u53f7\u7801\nphone = droid.pickPhone().result\nprint(f\"Selected phone: {phone}\")\n\n# \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\ncontacts = droid.contactsGet().result\nprint(f\"Total contacts: {len(contacts)}\")\n\n# \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\ncontact = droid.contactsGetById(1).result\nprint(f\"Contact: {contact}\")\n\n# \u83b7\u53d6\u8054\u7cfb\u4eba\u5c5e\u6027\nattrs = droid.contactsGetAttributes().result\nprint(f\"Available attributes: {attrs}\")\n
      "},{"location":"qsl4a/connectivity/ftp/","title":"FTP \u670d\u52a1\u5668 API","text":"

      \u5728\u8bbe\u5907\u4e0a\u542f\u52a8\u548c\u7ba1\u7406\u5185\u7f6e FTP \u670d\u52a1\u5668\u3002

      "},{"location":"qsl4a/connectivity/ftp/#ftp","title":"FTP \u670d\u52a1\u5668\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/ftp/#ftpstart","title":"ftpStart()","text":"

      \u542f\u52a8 FTP \u670d\u52a1\u5668\u3002

      ftpStart()\n

      \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4 [ip, port]

      "},{"location":"qsl4a/connectivity/ftp/#ftpstop","title":"ftpStop()","text":"

      \u505c\u6b62 FTP \u670d\u52a1\u5668\u3002

      ftpStop()\n
      "},{"location":"qsl4a/connectivity/ftp/#ftpisrunning","title":"ftpIsRunning()","text":"

      \u68c0\u67e5 FTP \u670d\u52a1\u5668\u662f\u5426\u6b63\u5728\u8fd0\u884c\u3002

      ftpIsRunning()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u8fd0\u884c\u5219\u4e3a True

      "},{"location":"qsl4a/connectivity/ftp/#ftpget","title":"ftpGet()","text":"

      \u83b7\u53d6 FTP \u670d\u52a1\u5668 IP \u5730\u5740\u3002

      ftpGet()\n

      \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4

      "},{"location":"qsl4a/connectivity/ftp/#ftpset","title":"ftpSet()","text":"

      \u914d\u7f6e FTP \u670d\u52a1\u5668\u8bbe\u7f6e\u3002

      ftpSet(port=None, rootDir=None, username=None, password=None)\n

      \u53c2\u6570\uff1a - port (int, optional): \u670d\u52a1\u5668\u7aef\u53e3 - rootDir (str, optional): \u8981\u670d\u52a1\u7684\u57fa\u7840\u76ee\u5f55 - username (str, optional): \u767b\u5f55\u7528\u6237\u540d - password (str, optional): \u767b\u5f55\u5bc6\u7801

      \u8fd4\u56de\uff1a \u5305\u542b\u5f53\u524d\u8bbe\u7f6e\u7684 JSONObject

      "},{"location":"qsl4a/connectivity/ftp/#ftpstatus","title":"ftpStatus()","text":"

      \u83b7\u53d6 FTP \u670d\u52a1\u5668\u72b6\u6001\u3002

      ftpStatus()\n

      \u8fd4\u56de\uff1a \u72b6\u6001\u63cf\u8ff0\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/ftp/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u914d\u7f6e FTP \u670d\u52a1\u5668\ndroid.ftpSet(\n    port=2121,\n    rootDir=\"/sdcard\",\n    username=\"admin\",\n    password=\"secret\"\n)\n\n# \u542f\u52a8 FTP \u670d\u52a1\u5668\ninfo = droid.ftpStart().result\nprint(f\"FTP running at {info[0]}:{info[1]}\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.ftpIsRunning().result:\n    print(\"FTP server is running\")\n\n# \u83b7\u53d6\u670d\u52a1\u5668\u4fe1\u606f\nserver_info = droid.ftpGet().result\nprint(f\"Server: {server_info}\")\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.ftpStop()\n

      \u6ce8\u610f\uff1a \u4f7f\u7528\u63d0\u4f9b\u7684\u51ed\u636e\u901a\u8fc7\u4efb\u4f55 FTP \u5ba2\u6237\u7aef\u8fde\u63a5\u5230 FTP \u670d\u52a1\u5668\u3002

      "},{"location":"qsl4a/connectivity/location/","title":"\u4f4d\u7f6e API","text":"

      \u8bbf\u95ee GPS \u548c\u7f51\u7edc\u4f4d\u7f6e\u670d\u52a1\u3002

      "},{"location":"qsl4a/connectivity/location/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/location/#startlocating","title":"startLocating()","text":"

      \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\u3002

      startLocating(minUpdateTime=60000, minUpdateDistance=30, updateGnssStatus=False)\n

      \u53c2\u6570\uff1a - minUpdateTime (int): \u66f4\u65b0\u4e4b\u95f4\u7684\u6700\u5c0f\u65f6\u95f4\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a60000\uff09 - minUpdateDistance (float): \u66f4\u65b0\u7684\u6700\u5c0f\u8ddd\u79bb\uff08\u7c73\uff09\uff08\u9ed8\u8ba4\uff1a30\uff09 - updateGnssStatus (bool): \u542f\u7528 GNSS \u72b6\u6001\u66f4\u65b0\uff08\u9ed8\u8ba4\uff1aFalse\uff09

      "},{"location":"qsl4a/connectivity/location/#stoplocating","title":"stopLocating()","text":"

      \u505c\u6b62\u4f4d\u7f6e\u66f4\u65b0\u3002

      stopLocating()\n
      "},{"location":"qsl4a/connectivity/location/#readlocation","title":"readLocation()","text":"

      \u83b7\u53d6\u6700\u540e\u5df2\u77e5\u4f4d\u7f6e\u3002

      readLocation()\n

      \u8fd4\u56de\uff1a \u4f4d\u7f6e\u6570\u636e\u5b57\u5178

      "},{"location":"qsl4a/connectivity/location/#getlastknownlocation","title":"getLastKnownLocation()","text":"

      \u83b7\u53d6\u7f13\u5b58\u7684\u4f4d\u7f6e\u3002

      getLastKnownLocation()\n

      \u8fd4\u56de\uff1a \u6765\u81ea\u6240\u6709\u63d0\u4f9b\u5546\u7684\u4f4d\u7f6e

      "},{"location":"qsl4a/connectivity/location/#geocode","title":"geocode()","text":"

      \u5c06\u5730\u5740\u8f6c\u6362\u4e3a\u5750\u6807\u3002

      geocode(address, maxResults=1)\n
      "},{"location":"qsl4a/connectivity/location/#_2","title":"\u4f4d\u7f6e\u63d0\u4f9b\u5546\u65b9\u6cd5)","text":""},{"location":"qsl4a/connectivity/location/#locationproviders","title":"locationProviders()","text":"

      \u83b7\u53d6\u624b\u673a\u4e0a\u53ef\u7528\u7684\u4f4d\u7f6e\u63d0\u4f9b\u5546\u3002

      locationProviders()\n

      \u8fd4\u56de\uff1a \u53ef\u7528\u63d0\u4f9b\u5546\u540d\u79f0\u5217\u8868\uff08\u4f8b\u5982 ['gps', 'network']\uff09

      "},{"location":"qsl4a/connectivity/location/#locationproviderenabled","title":"locationProviderEnabled()","text":"

      \u68c0\u67e5\u7279\u5b9a\u4f4d\u7f6e\u63d0\u4f9b\u5546\u662f\u5426\u5df2\u542f\u7528\u3002

      locationProviderEnabled(provider)\n

      \u53c2\u6570\uff1a - provider (str): \u63d0\u4f9b\u5546\u540d\u79f0\uff08\u4f8b\u5982 'gps', 'network'\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/connectivity/location/#readgnssstatus","title":"readGnssStatus()","text":"

      \u8bfb\u53d6\u5168\u7403\u5bfc\u822a\u536b\u661f\u7cfb\u7edf\u72b6\u6001\uff08\u9700\u8981 Android 8+\uff09\u3002

      readGnssStatus()\n

      \u8fd4\u56de\uff1a \u5305\u542b GNSS \u536b\u661f\u4fe1\u606f\u7684 JSONArray

      "},{"location":"qsl4a/connectivity/location/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\ndroid.startLocating(minUpdateTime=5000, minUpdateDistance=1, updateGnssStatus=False)\n\n# \u7b49\u5f85\u5b9a\u4f4d\ntime.sleep(10)\n\n# \u83b7\u53d6\u4f4d\u7f6e\nloc = droid.readLocation().result\nif loc:\n    lat = loc['latitude']\n    lon = loc['longitude']\n    print(f\"Location: {lat}, {lon}\")\n\ndroid.stopLocating()\n
      "},{"location":"qsl4a/connectivity/phone/","title":"\u7535\u8bdd API","text":"

      \u63a7\u5236\u7535\u8bdd\u901a\u8bdd\u548c\u83b7\u53d6\u7535\u8bdd\u4fe1\u606f\u3002

      "},{"location":"qsl4a/connectivity/phone/#_1","title":"\u7535\u8bdd\u72b6\u6001\u8ddf\u8e2a","text":""},{"location":"qsl4a/connectivity/phone/#starttrackingphonestate","title":"startTrackingPhoneState()","text":"

      \u5f00\u59cb\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u53d8\u5316\u3002\u751f\u6210 'phone' \u4e8b\u4ef6\u3002

      startTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/phone/#readphonestate","title":"readPhoneState()","text":"

      \u8bfb\u53d6\u5f53\u524d\u7535\u8bdd\u72b6\u6001\u3002

      readPhoneState()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7535\u8bdd\u72b6\u6001\u548c\u6765\u7535\u53f7\u7801\u7684 Bundle

      "},{"location":"qsl4a/connectivity/phone/#stoptrackingphonestate","title":"stopTrackingPhoneState()","text":"

      \u505c\u6b62\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u3002

      stopTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/phone/#_2","title":"\u62e8\u6253\u7535\u8bdd","text":""},{"location":"qsl4a/connectivity/phone/#phonecall","title":"phoneCall()","text":"

      \u901a\u8fc7 URI \u547c\u53eb\u8054\u7cfb\u4eba/\u7535\u8bdd\u53f7\u7801\u3002

      phoneCall(uri)\n

      \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

      "},{"location":"qsl4a/connectivity/phone/#phonecallnumber","title":"phoneCallNumber()","text":"

      \u76f4\u63a5\u62e8\u6253\u7535\u8bdd\u53f7\u7801\u3002

      phoneCallNumber(phone_number)\n

      \u53c2\u6570\uff1a - phone_number (str): \u8981\u62e8\u6253\u7684\u7535\u8bdd\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#phonedial","title":"phoneDial()","text":"

      \u62e8\u6253\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

      phoneDial(uri)\n

      \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

      "},{"location":"qsl4a/connectivity/phone/#phonedialnumber","title":"phoneDialNumber()","text":"

      \u62e8\u6253\u7535\u8bdd\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

      phoneDialNumber(phone_number)\n

      \u53c2\u6570\uff1a - phone_number (str): \u7535\u8bdd\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#_3","title":"\u57fa\u7ad9\u4f4d\u7f6e","text":""},{"location":"qsl4a/connectivity/phone/#getcelllocation","title":"getCellLocation()","text":"

      \u83b7\u53d6\u5f53\u524d\u57fa\u7ad9\u4f4d\u7f6e\u3002

      getCellLocation()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u57fa\u7ad9\u4f4d\u7f6e\u6570\u636e\u7684 JSONObject

      "},{"location":"qsl4a/connectivity/phone/#getallcellslocation","title":"getAllCellsLocation()","text":"

      \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u4f4d\u7f6e\uff08\u9002\u7528\u4e8e\u53cc\u5361\u8bbe\u5907\uff09\u3002

      getAllCellsLocation()\n

      \u8fd4\u56de\uff1a \u57fa\u7ad9\u4f4d\u7f6e\u7684 JSONArray

      "},{"location":"qsl4a/connectivity/phone/#_4","title":"\u7f51\u7edc\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getnetworkoperator","title":"getNetworkOperator()","text":"

      \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

      getNetworkOperator()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getnetworkoperatorname","title":"getNetworkOperatorName()","text":"

      \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684\u540d\u79f0\u3002

      getNetworkOperatorName()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getnetworktype","title":"getNetworkType()","text":"

      \u83b7\u53d6\u5f53\u524d\u7f51\u7edc\u7c7b\u578b\u3002

      getNetworkType()\n

      \u8fd4\u56de\uff1a \u63cf\u8ff0\u65e0\u7ebf\u7535\u6280\u672f\u7684\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'LTE', 'UMTS', 'GSM'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getphonetype","title":"getPhoneType()","text":"

      \u83b7\u53d6\u7535\u8bdd\u7c7b\u578b\u3002

      getPhoneType()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'GSM', 'CDMA', 'SIP'\uff09

      "},{"location":"qsl4a/connectivity/phone/#sim","title":"SIM \u5361\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getsimcountryiso","title":"getSimCountryIso()","text":"

      \u83b7\u53d6 SIM \u5361\u7684 ISO \u56fd\u5bb6\u4ee3\u7801\u3002

      getSimCountryIso()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'us'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getsimoperator","title":"getSimOperator()","text":"

      \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

      getSimOperator()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getsimoperatorname","title":"getSimOperatorName()","text":"

      \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u540d\u79f0\u3002

      getSimOperatorName()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getsimserialnumber","title":"getSimSerialNumber()","text":"

      \u83b7\u53d6 SIM \u5e8f\u5217\u53f7\u3002

      getSimSerialNumber()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32 SIM \u5e8f\u5217\u53f7

      "},{"location":"qsl4a/connectivity/phone/#getsimstate","title":"getSimState()","text":"

      \u83b7\u53d6 SIM \u5361\u72b6\u6001\u3002

      getSimState()\n

      \u8fd4\u56de\uff1a \u63cf\u8ff0 SIM \u72b6\u6001\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/phone/#getsubscriberid","title":"getSubscriberId()","text":"

      \u83b7\u53d6\u8ba2\u9605\u8005 ID\u3002

      getSubscriberId()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8ba2\u9605\u8005 ID

      "},{"location":"qsl4a/connectivity/phone/#_5","title":"\u8bed\u97f3\u90ae\u4ef6","text":""},{"location":"qsl4a/connectivity/phone/#getvoicemailalphatag","title":"getVoiceMailAlphaTag()","text":"

      \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u5b57\u6bcd\u6807\u7b7e\u3002

      getVoiceMailAlphaTag()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u6807\u7b7e

      "},{"location":"qsl4a/connectivity/phone/#getvoicemailnumber","title":"getVoiceMailNumber()","text":"

      \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801\u3002

      getVoiceMailNumber()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getdeviceid","title":"getDeviceId()","text":"

      \u83b7\u53d6\u8bbe\u5907 ID\uff08GSM \u7684 IMEI\uff09\u3002\u5df2\u5e9f\u5f03\u3002

      getDeviceId()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

      "},{"location":"qsl4a/connectivity/phone/#getdevicesoftwareversion","title":"getDeviceSoftwareVersion()","text":"

      \u83b7\u53d6\u8bbe\u5907\u8f6f\u4ef6\u7248\u672c\u3002

      getDeviceSoftwareVersion()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8f6f\u4ef6\u7248\u672c

      "},{"location":"qsl4a/connectivity/phone/#getline1number","title":"getLine1Number()","text":"

      \u83b7\u53d6\u7ebf\u8def 1 \u7535\u8bdd\u53f7\u7801\u3002

      getLine1Number()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u7535\u8bdd\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#checknetworkroaming","title":"checkNetworkRoaming()","text":"

      \u68c0\u67e5\u662f\u5426\u8fde\u63a5\u5230\u6f2b\u6e38\u7f51\u7edc\u3002

      checkNetworkRoaming()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u6f2b\u6e38\u5219\u4e3a True

      "},{"location":"qsl4a/connectivity/phone/#_7","title":"\u57fa\u7ad9\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getallcellinfo","title":"getAllCellInfo()","text":"

      \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u7684\u4fe1\u606f\u3002

      getAllCellInfo()\n

      \u8fd4\u56de\uff1a \u57fa\u7ad9\u4fe1\u606f\u5217\u8868

      "},{"location":"qsl4a/connectivity/phone/#setdataenabled","title":"setDataEnabled()","text":"

      \u542f\u7528\u6216\u7981\u7528\u79fb\u52a8\u6570\u636e\u3002

      setDataEnabled(enabled)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528

      "},{"location":"qsl4a/connectivity/phone/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7f51\u7edc\u4fe1\u606f\noperator = droid.getNetworkOperatorName().result\nprint(f\"Operator: {operator}\")\n\nnetwork_type = droid.getNetworkType().result\nprint(f\"Network: {network_type}\")\n\n# \u83b7\u53d6 SIM \u4fe1\u606f\nsim_state = droid.getSimState().result\nprint(f\"SIM: {sim_state}\")\n\n# \u83b7\u53d6\u7535\u8bdd\u53f7\u7801\nline1 = droid.getLine1Number().result\nprint(f\"Phone: {line1}\")\n\n# \u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\ndroid.startTrackingPhoneState()\nprint(\"Tracking phone state...\")\ndroid.stopTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/signalstrength/","title":"\u4fe1\u53f7\u5f3a\u5ea6 API","text":"

      \u76d1\u63a7\u8702\u7a9d\u548c\u65e0\u7ebf\u4fe1\u53f7\u5f3a\u5ea6\u3002

      "},{"location":"qsl4a/connectivity/signalstrength/#_1","title":"\u4fe1\u53f7\u5f3a\u5ea6\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/signalstrength/#starttrackingsignalstrengths","title":"startTrackingSignalStrengths()","text":"

      \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316\u3002\u751f\u6210 'signal_strengths' \u4e8b\u4ef6\u3002

      startTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/signalstrength/#stoptrackingsignalstrengths","title":"stopTrackingSignalStrengths()","text":"

      \u505c\u6b62\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u3002

      stopTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/signalstrength/#readsignalstrengths","title":"readSignalStrengths()","text":"

      \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\u3002

      readSignalStrengths()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u4fe1\u53f7\u5f3a\u5ea6\u6570\u636e\u7684 Bundle

      "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthlevel","title":"getTelephoneSignalStrengthLevel()","text":"

      \u83b7\u53d6\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u7b49\u7ea7\uff080-4\uff09\u3002

      getTelephoneSignalStrengthLevel()\n

      \u8fd4\u56de\uff1a \u6574\u6570\u7b49\u7ea7\uff080=\u65e0\uff0c1=\u5dee\uff0c2=\u4e00\u822c\uff0c3=\u597d\uff0c4=\u4f18\u79c0\uff09

      "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthdetail","title":"getTelephoneSignalStrengthDetail()","text":"

      \u83b7\u53d6\u8be6\u7ec6\u7684\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u4fe1\u606f\u3002

      getTelephoneSignalStrengthDetail()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u8be6\u7ec6\u4fe1\u53f7\u4fe1\u606f\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/signalstrength/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\ndroid.startTrackingSignalStrengths()\n\n# \u7b49\u5f85\u4fe1\u53f7\u66f4\u65b0\ntime.sleep(5)\n\n# \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\nsignal = droid.readSignalStrengths().result\nprint(f\"Signal: {signal}\")\n\n# \u76f4\u63a5\u83b7\u53d6\u7b49\u7ea7\nlevel = droid.getTelephoneSignalStrengthLevel().result\nprint(f\"Signal level: {level}/4\")\n\ndroid.stopTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/sms/","title":"SMS API","text":"

      \u53d1\u9001\u548c\u63a5\u6536 SMS \u6d88\u606f\u3002

      "},{"location":"qsl4a/connectivity/sms/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/sms/#smssend","title":"smsSend()","text":"

      \u53d1\u9001 SMS \u6d88\u606f\u3002

      smsSend(destinationAddress, text)\n

      \u53c2\u6570\uff1a - destinationAddress (str): \u7535\u8bdd\u53f7\u7801 - text (str): \u6d88\u606f\u6587\u672c

      "},{"location":"qsl4a/connectivity/sms/#smsgetmessagecount","title":"smsGetMessageCount()","text":"

      \u83b7\u53d6\u6d88\u606f\u6570\u91cf\u3002

      smsGetMessageCount(unreadOnly=False, folder=\"inbox\")\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessageids","title":"smsGetMessageIds()","text":"

      \u83b7\u53d6\u6d88\u606f ID\u3002

      smsGetMessageIds(unreadOnly=False, folder=\"inbox\")\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessages","title":"smsGetMessages()","text":"

      \u83b7\u53d6\u6d88\u606f\u8be6\u60c5\u3002

      smsGetMessages(unreadOnly=False, folder=\"inbox\", attributes=None)\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessagebyid","title":"smsGetMessageById()","text":"

      \u901a\u8fc7 ID \u83b7\u53d6\u7279\u5b9a\u6d88\u606f\u3002

      smsGetMessageById(id, attributes=None)\n

      \u53c2\u6570\uff1a - id (int): \u6d88\u606f ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

      \u8fd4\u56de\uff1a \u6d88\u606f\u6570\u636e\u5b57\u5178

      "},{"location":"qsl4a/connectivity/sms/#smsgetattributes","title":"smsGetAttributes()","text":"

      \u83b7\u53d6\u53ef\u7528\u7684 SMS \u6d88\u606f\u5c5e\u6027\u3002

      smsGetAttributes()\n

      \u8fd4\u56de\uff1a \u53ef\u7528\u5c5e\u6027\u540d\u79f0\u5217\u8868

      "},{"location":"qsl4a/connectivity/sms/#smsdeletemessage","title":"smsDeleteMessage()","text":"

      \u5220\u9664\u6d88\u606f\u3002

      smsDeleteMessage(id)\n
      "},{"location":"qsl4a/connectivity/sms/#smsmarkmessageread","title":"smsMarkMessageRead()","text":"

      \u5c06\u6d88\u606f\u6807\u8bb0\u4e3a\u5df2\u8bfb\u3002

      smsMarkMessageRead(ids, read=True)\n
      "},{"location":"qsl4a/connectivity/sms/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u53d1\u9001 SMS\ndroid.smsSend(\"+1234567890\", \"Hello from QPython!\")\n\n# \u83b7\u53d6\u672a\u8bfb\u6d88\u606f\nmessages = droid.smsGetMessages(unreadOnly=True).result\nfor msg in messages:\n    print(f\"From: {msg['address']}, Text: {msg['body']}\")\n
      "},{"location":"qsl4a/connectivity/wifi/","title":"WiFi API","text":"

      \u63a7\u5236 WiFi \u9002\u914d\u5668\u5e76\u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\u3002

      "},{"location":"qsl4a/connectivity/wifi/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/connectivity/wifi/#checkwifistate","title":"checkWifiState()","text":"

      \u68c0\u67e5 WiFi \u662f\u5426\u5df2\u542f\u7528\u3002

      checkWifiState()\n

      \u8fd4\u56de\uff1a \u5982\u679c WiFi \u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/connectivity/wifi/#togglewifistate","title":"toggleWifiState()","text":"

      \u6253\u5f00\u6216\u5173\u95ed WiFi\u3002

      toggleWifiState(enabled=None)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

      \u8fd4\u56de\uff1a \u5982\u679c\u64cd\u4f5c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/connectivity/wifi/#wifistartscan","title":"wifiStartScan()","text":"

      \u5f00\u59cb\u626b\u63cf\u53ef\u7528\u7684 WiFi \u7f51\u7edc\u3002

      wifiStartScan()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifigetscanresults","title":"wifiGetScanResults()","text":"

      \u83b7\u53d6\u53d1\u73b0\u7684 WiFi \u7f51\u7edc\u5217\u8868\u3002

      wifiGetScanResults()\n

      \u8fd4\u56de\uff1a \u63a5\u5165\u70b9\u4fe1\u606f\u5217\u8868

      "},{"location":"qsl4a/connectivity/wifi/#_2","title":"\u8fde\u63a5\u7ba1\u7406","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetconnectioninfo","title":"wifiGetConnectionInfo()","text":"

      \u83b7\u53d6\u8be6\u7ec6\u8fde\u63a5\u4fe1\u606f\u3002

      wifiGetConnectionInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001IP \u5730\u5740\u7b49\u8fde\u63a5\u8be6\u60c5\u7684\u5b57\u5178

      "},{"location":"qsl4a/connectivity/wifi/#getconnectedinfo","title":"getConnectedInfo()","text":"

      \u83b7\u53d6\u8fde\u63a5\u7684 WiFi \u7f51\u7edc\u4fe1\u606f\uff08\u7b80\u5316\u7248\uff09\u3002

      getConnectedInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001\u4fe1\u53f7\u5f3a\u5ea6\u7684\u5b57\u5178

      "},{"location":"qsl4a/connectivity/wifi/#getdhcpinfo","title":"getDhcpInfo()","text":"

      \u83b7\u53d6\u5f53\u524d\u8fde\u63a5\u7684 DHCP \u4fe1\u606f\u3002

      getDhcpInfo(ipConvertToString=True)\n

      \u53c2\u6570\uff1a - ipConvertToString (bool): \u5c06 IP \u5730\u5740\u8f6c\u6362\u4e3a\u5b57\u7b26\u4e32\u683c\u5f0f\uff08\u9ed8\u8ba4\uff1aTrue\uff09

      \u8fd4\u56de\uff1a \u5305\u542b IP\u3001\u7f51\u5173\u3001DNS \u7b49 DHCP \u4fe1\u606f\u7684\u5b57\u5178

      "},{"location":"qsl4a/connectivity/wifi/#wifidisconnect","title":"wifiDisconnect()","text":"

      \u65ad\u5f00\u5f53\u524d WiFi \u7f51\u7edc\u8fde\u63a5\u3002

      wifiDisconnect()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifireconnect","title":"wifiReconnect()","text":"

      \u91cd\u65b0\u8fde\u63a5\u5230\u5f53\u524d\u7f51\u7edc\u3002

      wifiReconnect()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifireassociate","title":"wifiReassociate()","text":"

      \u91cd\u65b0\u5173\u8054\u5f53\u524d\u63a5\u5165\u70b9\u3002

      wifiReassociate()\n
      "},{"location":"qsl4a/connectivity/wifi/#_3","title":"\u70ed\u70b9","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetapstate","title":"wifiGetApState()","text":"

      \u83b7\u53d6 WiFi AP\uff08\u70ed\u70b9\uff09\u72b6\u6001\u3002

      wifiGetApState()\n

      \u8fd4\u56de\uff1a \u70ed\u70b9\u72b6\u6001

      "},{"location":"qsl4a/connectivity/wifi/#wifi","title":"WiFi \u9501","text":""},{"location":"qsl4a/connectivity/wifi/#wifilockacquirefull","title":"wifiLockAcquireFull()","text":"

      \u83b7\u53d6\u5b8c\u6574 WiFi \u9501\uff08\u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\u4e5f\u4fdd\u6301 WiFi \u6d3b\u52a8\uff09\u3002

      wifiLockAcquireFull()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifilockacquirescanonly","title":"wifiLockAcquireScanOnly()","text":"

      \u83b7\u53d6\u4ec5\u626b\u63cf WiFi \u9501\u3002

      wifiLockAcquireScanOnly()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifilockrelease","title":"wifiLockRelease()","text":"

      \u91ca\u653e WiFi \u9501\u3002

      wifiLockRelease()\n
      "},{"location":"qsl4a/connectivity/wifi/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u68c0\u67e5 WiFi \u72b6\u6001\nif droid.checkWifiState().result:\n    print(\"WiFi is enabled\")\nelse:\n    print(\"Enabling WiFi...\")\n    droid.toggleWifiState(True)\n    time.sleep(2)\n\n# \u5f00\u59cb\u626b\u63cf\ndroid.wifiStartScan()\ntime.sleep(3)\n\n# \u83b7\u53d6\u626b\u63cf\u7ed3\u679c\nnetworks = droid.wifiGetScanResults().result\nfor network in networks:\n    print(f\"SSID: {network.get('SSID')}, Signal: {network.get('level')} dBm\")\n\n# \u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\ninfo = droid.wifiGetConnectionInfo().result\nif info:\n    print(f\"Connected to: {info.get('ssid')}\")\n    print(f\"BSSID: {info.get('bssid')}\")\n    print(f\"IP: {info.get('ip_address')}\")\n\n# \u83b7\u53d6 DHCP \u4fe1\u606f\ndhcp = droid.getDhcpInfo().result\nif dhcp:\n    print(f\"Gateway: {dhcp.get('gateway')}\")\n    print(f\"DNS: {dhcp.get('dns1')}\")\n\n# \u83b7\u53d6\u7b80\u5316\u7684\u8fde\u63a5\u4fe1\u606f\nconnected = droid.getConnectedInfo().result\nprint(f\"SSID: {connected.get('ssid')}, Signal: {connected.get('level')} dBm\")\n\n# \u65ad\u5f00\u5e76\u91cd\u65b0\u8fde\u63a5\ndroid.wifiDisconnect()\ntime.sleep(1)\ndroid.wifiReconnect()\n\n# \u91cd\u65b0\u5173\u8054\u63a5\u5165\u70b9\ndroid.wifiReassociate()\n\n# \u68c0\u67e5\u70ed\u70b9\u72b6\u6001\nap_state = droid.wifiGetApState().result\nprint(f\"Hotspot state: {ap_state}\")\n\n# \u83b7\u53d6 WiFi \u9501\u4ee5\u8fdb\u884c\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireFull()\n# ... \u6267\u884c\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n\n# \u6216\u4f7f\u7528\u4ec5\u626b\u63cf\u9501\u4ee5\u8fdb\u884c\u8f83\u8f7b\u7684\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireScanOnly()\n# ... \u6267\u884c\u626b\u63cf\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n
      "},{"location":"qsl4a/core/android-base/","title":"Android \u57fa\u7840\u7c7b","text":"

      Android \u7c7b\u662f QSL4A \u7684\u6838\u5fc3\uff0c\u63d0\u4f9b\u4e86\u4e0e Android \u8fd0\u884c\u65f6\u7684\u8fde\u63a5\u548c RPC \u673a\u5236\u3002

      "},{"location":"qsl4a/core/android-base/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
      # \u529f\u80fd\u5b8c\u6574\u7248\u672c\uff08\u63a8\u8350\uff09\nimport androidhelper\ndroid = androidhelper.Android()\n\n# \u7b80\u5316\u7248\u672c\uff08\u5feb\u901f\uff0c\u5355\u5b9e\u4f8b\uff09\nimport android\ndroid = android.droid\n
      "},{"location":"qsl4a/core/android-base/#android_1","title":"\u7c7b\uff1aAndroid","text":""},{"location":"qsl4a/core/android-base/#_2","title":"\u6784\u9020\u51fd\u6570","text":"
      Android(addr=None)\n

      \u53c2\u6570\uff1a - addr (tuple, optional): (HOST, PORT) \u5730\u5740\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u73af\u5883\u53d8\u91cf AP_HOST \u548c AP_PORT

      \u73af\u5883\u53d8\u91cf\uff1a - AP_HOST - \u670d\u52a1\u5668\u4e3b\u673a\u5730\u5740 - AP_PORT - \u670d\u52a1\u5668\u7aef\u53e3 - AP_HANDSHAKE - \u8ba4\u8bc1\u4ee4\u724c

      "},{"location":"qsl4a/core/android-base/#_3","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/android-base/#_rpc","title":"_rpc()","text":"

      \u8c03\u7528 Android \u51fd\u6570\u7684\u5185\u90e8 RPC \u65b9\u6cd5\u3002

      _rpc(method, *args)\n

      \u53c2\u6570\uff1a - method (str): \u8981\u8c03\u7528\u7684\u65b9\u6cd5\u540d - *args: \u65b9\u6cd5\u7684\u53ef\u53d8\u53c2\u6570

      \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4\uff0c\u5305\u542b\u4ee5\u4e0b\u5b57\u6bb5\uff1a - id (int): \u8bf7\u6c42 ID - result: \u65b9\u6cd5\u8fd4\u56de\u503c - error (str or None): \u9519\u8bef\u4fe1\u606f\uff08\u5982\u679c\u5931\u8d25\uff09

      "},{"location":"qsl4a/core/android-base/#getattr","title":"getattr()","text":"

      \u52a8\u6001\u65b9\u6cd5\u5206\u53d1\u5668\u3002\u6240\u6709 Android \u65b9\u6cd5\u90fd\u901a\u8fc7\u5c5e\u6027\u67e5\u627e\u8bbf\u95ee\u3002

      # \u4ee5\u4e0b\u4e24\u79cd\u65b9\u5f0f\u7b49\u4ef7\uff1a\ndroid.makeToast(\"Hello\")\ndroid._rpc(\"makeToast\", \"Hello\")\n
      "},{"location":"qsl4a/core/android-base/#androidpy","title":"\u72ec\u7acb\u51fd\u6570\uff08android.py\uff09","text":"

      \u4f7f\u7528\u7b80\u5316\u7684 android \u6a21\u5757\u65f6\uff1a

      "},{"location":"qsl4a/core/android-base/#jsla","title":"jsla()","text":"

      \u53d1\u9001 JSON-RPC \u8bf7\u6c42\u5e76\u8fd4\u56de\u539f\u59cb\u54cd\u5e94\u3002

      jsla(method, *params)\n

      \u8fd4\u56de\uff1a JSON \u5b57\u7b26\u4e32\u54cd\u5e94

      "},{"location":"qsl4a/core/android-base/#rsla","title":"rsla()","text":"

      \u53d1\u9001\u8bf7\u6c42\u5e76\u4ec5\u8fd4\u56de\u7ed3\u679c\u3002

      rsla(method, *params)\n

      \u8fd4\u56de\uff1a RPC \u8c03\u7528\u7684\u7ed3\u679c\u503c

      "},{"location":"qsl4a/core/android-base/#esla","title":"esla()","text":"

      \u53d1\u9001\u8bf7\u6c42\uff0c\u9519\u8bef\u65f6\u629b\u51fa\u5f02\u5e38\u3002

      esla(method, *params)\n

      \u629b\u51fa\uff1a \u5982\u679c error \u5b57\u6bb5\u4e0d\u4e3a None \u5219\u629b\u51fa\u5f02\u5e38

      "},{"location":"qsl4a/core/android-base/#nsla","title":"nsla()","text":"

      \u53d1\u9001\u8bf7\u6c42\u5e76\u8fd4\u56de Result \u547d\u540d\u5143\u7ec4\u3002

      nsla(method, *params)\n

      \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4

      "},{"location":"qsl4a/core/android-base/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/android-base/#_5","title":"\u57fa\u672c\u8fde\u63a5","text":"
      import androidhelper\n\n# \u8fde\u63a5\u5230 Android \u8fd0\u884c\u65f6\ndroid = androidhelper.Android()\n\n# \u901a\u8fc7\u663e\u793a toast \u6765\u68c0\u67e5\u8fde\u63a5\ndroid.makeToast(\"Connected!\")\n
      "},{"location":"qsl4a/core/android-base/#_6","title":"\u9519\u8bef\u5904\u7406","text":"
      result = droid.someMethod()\nif result.error:\n    print(f\"Error: {result.error}\")\nelse:\n    print(f\"Success: {result.result}\")\n
      "},{"location":"qsl4a/core/android-base/#rpc","title":"\u76f4\u63a5 RPC \u8c03\u7528","text":"
      # \u76f4\u63a5\u8c03\u7528\u4efb\u610f\u65b9\u6cd5\nresult = droid._rpc(\"makeToast\", \"Hello World\")\n
      "},{"location":"qsl4a/core/events/","title":"\u4e8b\u4ef6\u7cfb\u7edf","text":"

      QSL4A \u63d0\u4f9b\u4e86\u4e00\u4e2a\u4e8b\u4ef6\u7cfb\u7edf\uff0c\u7528\u4e8e\u5904\u7406\u6765\u81ea Android \u7684\u5f02\u6b65\u4e8b\u4ef6\uff0c\u5982\u4f20\u611f\u5668\u66f4\u65b0\u3001\u4f4d\u7f6e\u53d8\u5316\u548c\u81ea\u5b9a\u4e49\u5e7f\u64ad\u3002

      "},{"location":"qsl4a/core/events/#_2","title":"\u4e8b\u4ef6\u57fa\u7840","text":"

      \u4e8b\u4ef6\u5b58\u50a8\u5728\u7f13\u51b2\u533a\u4e2d\uff0c\u53ef\u4ee5\u8f6e\u8be2\u6216\u7b49\u5f85\u3002\u6bcf\u4e2a\u4e8b\u4ef6\u5305\u542b\uff1a - name: \u4e8b\u4ef6\u7c7b\u578b/\u540d\u79f0 - data: \u4e8b\u4ef6\u8d1f\u8f7d\u6570\u636e - time: \u65f6\u95f4\u6233

      "},{"location":"qsl4a/core/events/#_3","title":"\u4e8b\u4ef6\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#eventclearbuffer","title":"eventClearBuffer()","text":"

      \u6e05\u9664\u7f13\u51b2\u533a\u4e2d\u7684\u6240\u6709\u5f85\u5904\u7406\u4e8b\u4ef6\u3002

      eventClearBuffer()\n

      \u8fd4\u56de\uff1a None

      "},{"location":"qsl4a/core/events/#eventpoll","title":"eventPoll()","text":"

      \u8f6e\u8be2\u7f13\u51b2\u533a\u4e2d\u7684\u4e8b\u4ef6\u3002

      eventPoll(number_of_events=1)\n

      \u53c2\u6570\uff1a - number_of_events (int): \u8981\u68c0\u7d22\u7684\u6700\u5927\u4e8b\u4ef6\u6570\uff08\u9ed8\u8ba4\uff1a1\uff09

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\u5217\u8868

      "},{"location":"qsl4a/core/events/#eventwait","title":"eventWait()","text":"

      \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\u3002

      eventWait(timeout=None)\n

      \u53c2\u6570\uff1a - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09\u3002None = \u6c38\u4e45\u7b49\u5f85

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

      "},{"location":"qsl4a/core/events/#eventwaitfor","title":"eventWaitFor()","text":"

      \u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6\u3002

      eventWaitFor(eventName, timeout=None)\n

      \u53c2\u6570\uff1a - eventName (str): \u8981\u7b49\u5f85\u7684\u4e8b\u4ef6\u540d\u79f0 - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

      "},{"location":"qsl4a/core/events/#eventpost","title":"eventPost()","text":"

      \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\u3002

      eventPost(name, data, enqueue=None)\n

      \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e\uff08\u4efb\u610f\u7c7b\u578b\uff09 - enqueue (bool, optional): \u5982\u679c\u4e3a True \u5219\u6dfb\u52a0\u5230\u961f\u5217

      "},{"location":"qsl4a/core/events/#receiveevent","title":"receiveEvent()","text":"

      \u63a5\u6536\u4e8b\u4ef6\uff08\u963b\u585e\uff09\u3002

      receiveEvent()\n

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61

      "},{"location":"qsl4a/core/events/#_4","title":"\u5e7f\u64ad\u4e8b\u4ef6","text":"

      \u6ce8\u518c\u7cfb\u7edf\u5e7f\u64ad\u4e8b\u4ef6\u3002

      "},{"location":"qsl4a/core/events/#eventregisterforbroadcast","title":"eventRegisterForBroadcast()","text":"

      \u6ce8\u518c\u63a5\u6536\u5e7f\u64ad\u4e8b\u4ef6\u3002

      eventRegisterForBroadcast(category, enqueue=True)\n

      \u53c2\u6570\uff1a - category (str): \u5e7f\u64ad\u7c7b\u522b/\u52a8\u4f5c - enqueue (bool): \u6dfb\u52a0\u5230\u4e8b\u4ef6\u961f\u5217

      "},{"location":"qsl4a/core/events/#eventunregisterforbroadcast","title":"eventUnregisterForBroadcast()","text":"

      \u53d6\u6d88\u6ce8\u518c\u5e7f\u64ad\u4e8b\u4ef6\u3002

      eventUnregisterForBroadcast(category)\n
      "},{"location":"qsl4a/core/events/#eventgetbrodcastcategories","title":"eventGetBrodcastCategories()","text":"

      \u83b7\u53d6\u5df2\u6ce8\u518c\u7684\u5e7f\u64ad\u7c7b\u522b\u3002

      eventGetBrodcastCategories()\n

      \u8fd4\u56de\uff1a \u5df2\u6ce8\u518c\u7c7b\u522b\u5217\u8868

      "},{"location":"qsl4a/core/events/#_5","title":"\u4e8b\u4ef6\u5206\u53d1\u5668)","text":""},{"location":"qsl4a/core/events/#starteventdispatcher","title":"startEventDispatcher()","text":"

      \u6253\u5f00\u4e00\u4e2a\u53ef\u4ee5\u8bfb\u53d6\u5df2\u53d1\u5e03\u4e8b\u4ef6\u7684\u5957\u63a5\u5b57\u3002)

      startEventDispatcher(port=0)\n

      \u53c2\u6570\uff1a - port (int, optional): \u76d1\u542c\u7684\u7aef\u53e3\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\u9009\u62e9\uff09

      \u8fd4\u56de\uff1a \u6b63\u5728\u76d1\u542c\u7684\u7aef\u53e3\u53f7

      "},{"location":"qsl4a/core/events/#stopeventdispatcher","title":"stopEventDispatcher()","text":"

      \u505c\u6b62\u4e8b\u4ef6\u670d\u52a1\u5668\u3002)

      stopEventDispatcher()\n
      "},{"location":"qsl4a/core/events/#_6","title":"\u5df2\u5e9f\u5f03\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#rpcpostevent","title":"rpcPostEvent()","text":"

      \u5c06\u4e8b\u4ef6\u53d1\u5e03\u5230\u4e8b\u4ef6\u961f\u5217\u3002\uff08\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 eventPost\uff09

      rpcPostEvent(name, data)\n

      \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e

      "},{"location":"qsl4a/core/events/#_7","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/events/#_8","title":"\u57fa\u672c\u4e8b\u4ef6\u8f6e\u8be2","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6e05\u9664\u65e7\u4e8b\u4ef6\ndroid.eventClearBuffer()\n\n# \u8f6e\u8be2\u4e8b\u4ef6\nevents = droid.eventPoll(5).result\nfor event in events:\n    print(f\"Event: {event['name']}, Data: {event['data']}\")\n
      "},{"location":"qsl4a/core/events/#_9","title":"\u7b49\u5f85\u4e8b\u4ef6","text":"
      # \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\uff0c\u5e26\u8d85\u65f6\nevent = droid.eventWait(timeout=10).result\nif event:\n    print(f\"Got event: {event['name']}\")\n
      "},{"location":"qsl4a/core/events/#_10","title":"\u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6","text":"
      # \u7b49\u5f85\u4f20\u611f\u5668\u4e8b\u4ef6\nevent = droid.eventWaitFor('screen', timeout=5).result\nif event:\n    print(f\"Screen event: {event['data']}\")\n
      "},{"location":"qsl4a/core/events/#_11","title":"\u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6","text":"
      # \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\ndroid.eventPost('my_event', {'key': 'value'})\n\n# \u7b49\u5f85\u5b83\nevent = droid.eventWaitFor('my_event', timeout=1).result\n
      "},{"location":"qsl4a/core/events/#_12","title":"\u5e7f\u64ad\u63a5\u6536\u5668","text":"
      # \u6ce8\u518c\u5c4f\u5e55\u5f00\u5173\u4e8b\u4ef6\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_ON')\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_OFF')\n\n# \u7b49\u5f85\u5c4f\u5e55\u4e8b\u4ef6\nwhile True:\n    event = droid.receiveEvent().result\n    if event['name'] == 'android.intent.action.SCREEN_ON':\n        print(\"Screen turned on\")\n    elif event['name'] == 'android.intent.action.SCREEN_OFF':\n        print(\"Screen turned off\")\n
      "},{"location":"qsl4a/core/events/#_13","title":"\u4f20\u611f\u5668\u4e8b\u4ef6\u5904\u7406","text":"
      # \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u5904\u7406\u4f20\u611f\u5668\u4e8b\u4ef6\nfor _ in range(100):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'sensors':\n        data = event['data']\n        print(f\"Accel: {data['xforce']}, {data['yforce']}, {data['zforce']}\")\n\ndroid.stopSensing()\n
      "},{"location":"qsl4a/core/events/#_14","title":"\u5e38\u89c1\u4e8b\u4ef6\u7c7b\u578b","text":"\u4e8b\u4ef6\u540d\u79f0 \u63cf\u8ff0 \u6765\u6e90 sensors \u4f20\u611f\u5668\u6570\u636e\u66f4\u65b0 startSensing* location GPS \u4f4d\u7f6e\u66f4\u65b0 startLocating phone \u7535\u8bdd\u72b6\u6001\u53d8\u5316 startTrackingPhoneState signal \u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316 startTrackingSignalStrength screen \u622a\u56fe\u5c31\u7eea fullGetScreenShot dialog \u5bf9\u8bdd\u6846\u54cd\u5e94 dialogShow*"},{"location":"qsl4a/core/events/#_15","title":"\u4e8b\u4ef6\u6570\u636e\u7ed3\u6784","text":"
      {\n    'name': 'event_name',\n    'data': {\n        # \u4e8b\u4ef6\u7279\u5b9a\u6570\u636e\n    },\n    'time': 1234567890  # \u65f6\u95f4\u6233\n}\n
      "},{"location":"qsl4a/core/intent/","title":"Intent \u7cfb\u7edf","text":"

      Android Intent \u7528\u4e8e\u542f\u52a8\u6d3b\u52a8\u3001\u53d1\u9001\u5e7f\u64ad\u548c\u5e94\u7528\u95f4\u901a\u4fe1\u3002QSL4A \u901a\u8fc7 Intent \u6a21\u5757\u63d0\u4f9b\u5b8c\u6574\u7684 Intent \u652f\u6301\u3002

      "},{"location":"qsl4a/core/intent/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
      import androidhelper\ndon = androidhelper.Android()\n
      "},{"location":"qsl4a/core/intent/#intent_1","title":"Intent \u5e38\u91cf","text":"

      \u901a\u8fc7 droid.Intent \u8bbf\u95ee\uff1a

      "},{"location":"qsl4a/core/intent/#_2","title":"\u64cd\u4f5c","text":"\u5e38\u91cf \u503c \u7528\u9014 ACTION_MAIN android.intent.action.MAIN \u5e94\u7528\u5165\u53e3\u70b9 ACTION_VIEW android.intent.action.VIEW \u67e5\u770b\u5185\u5bb9 ACTION_EDIT android.intent.action.EDIT \u7f16\u8f91\u5185\u5bb9 ACTION_PICK android.intent.action.PICK \u9009\u62e9\u9879\u76ee ACTION_SEND android.intent.action.SEND \u5206\u4eab\u5185\u5bb9 ACTION_SEARCH android.intent.action.SEARCH \u641c\u7d22"},{"location":"qsl4a/core/intent/#_3","title":"\u6807\u5fd7","text":"\u5e38\u91cf \u503c \u7528\u9014 FLAG_ACTIVITY_NEW_TASK 268435456 \u542f\u52a8\u65b0\u4efb\u52a1 FLAG_ACTIVITY_CLEAR_TASK 32768 \u6e05\u9664\u4efb\u52a1\u5806\u6808 FLAG_ACTIVITY_NEW_DOCUMENT 524288 \u65b0\u6587\u6863\u6a21\u5f0f"},{"location":"qsl4a/core/intent/#_4","title":"\u9644\u52a0\u6570\u636e","text":"\u5e38\u91cf \u7528\u9014 EXTRA_TEXT \u6587\u672c\u5185\u5bb9 EXTRA_STREAM \u6587\u4ef6 URI EXTRA_SUBJECT \u4e3b\u9898\u884c EXTRA_EMAIL \u7535\u5b50\u90ae\u4ef6\u5730\u5740"},{"location":"qsl4a/core/intent/#_5","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/intent/#makeintent","title":"makeIntent()","text":"

      \u521b\u5efa Intent \u5bf9\u8c61\u3002

      makeIntent(action, uri=None, type=None, extras=None, categories=None,\n           packagename=None, classname=None, flags=None)\n

      \u53c2\u6570\uff1a - action (str): Intent \u64cd\u4f5c\uff08\u4f8b\u5982 droid.Intent.ACTION_VIEW\uff09 - uri (str, optional): \u6570\u636e URI - type (str, optional): MIME \u7c7b\u578b - extras (dict, optional): \u9644\u52a0\u6570\u636e - categories (list, optional): Intent \u7c7b\u522b - packagename (str, optional): \u76ee\u6807\u5305 - classname (str, optional): \u76ee\u6807\u7c7b - flags (int, optional): Intent \u6807\u5fd7

      \u8fd4\u56de\uff1a Intent \u5bf9\u8c61

      "},{"location":"qsl4a/core/intent/#startactivityintent","title":"startActivityIntent()","text":"

      \u4f7f\u7528 Intent \u542f\u52a8 Activity\u3002

      startActivityIntent(intent, wait=None)\n

      \u53c2\u6570\uff1a - intent: makeIntent() \u8fd4\u56de\u7684 Intent \u5bf9\u8c61 - wait (bool, optional): \u963b\u585e\u76f4\u5230\u6d3b\u52a8\u5173\u95ed

      "},{"location":"qsl4a/core/intent/#startactivityforresultintent","title":"startActivityForResultIntent()","text":"

      \u542f\u52a8\u6d3b\u52a8\u5e76\u7b49\u5f85\u7ed3\u679c\u3002

      startActivityForResultIntent(intent)\n

      \u8fd4\u56de\uff1a Activity \u7ed3\u679c

      "},{"location":"qsl4a/core/intent/#sendbroadcastintent","title":"sendBroadcastIntent()","text":"

      \u53d1\u9001\u5e7f\u64ad\u3002

      sendBroadcastIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#view","title":"view()","text":"

      \u901a\u8fc7 URI \u67e5\u770b\u5185\u5bb9\u3002

      view(uri, type=None, extras=None)\n
      "},{"location":"qsl4a/core/intent/#pick","title":"pick()","text":"

      \u4ece URI \u9009\u62e9\u5185\u5bb9\u3002

      pick(uri)\n
      "},{"location":"qsl4a/core/intent/#intent_2","title":"\u5e38\u89c1 Intent \u65b9\u6cd5)","text":""},{"location":"qsl4a/core/intent/#scanbarcode","title":"scanBarcode()","text":"

      \u542f\u52a8\u6761\u7801\u626b\u63cf\u5668\u3002

      scanBarcode()\n

      \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/core/intent/#send","title":"send()","text":"

      \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u5185\u5bb9\u3002

      send(type, content)\n

      \u53c2\u6570\uff1a - type (str): MIME \u7c7b\u578b - content (str): \u8981\u5206\u4eab\u7684\u5185\u5bb9

      "},{"location":"qsl4a/core/intent/#sendtext","title":"sendText()","text":"

      \u53d1\u9001\u6587\u672c\u5185\u5bb9\u3002

      sendText(text)\n

      \u53c2\u6570\uff1a - text (str): \u8981\u53d1\u9001\u7684\u6587\u672c

      "},{"location":"qsl4a/core/intent/#sendemail","title":"sendEmail()","text":"

      \u53d1\u9001\u7535\u5b50\u90ae\u4ef6\u3002

      sendEmail(to, subject, body, attachment=None)\n

      \u53c2\u6570\uff1a - to (str or list): \u6536\u4ef6\u4eba\u7535\u5b50\u90ae\u4ef6\u5730\u5740 - subject (str): \u7535\u5b50\u90ae\u4ef6\u4e3b\u9898 - body (str): \u7535\u5b50\u90ae\u4ef6\u6b63\u6587 - attachment (str, optional): \u9644\u4ef6\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/core/intent/#pathtouri","title":"pathToUri()","text":"

      \u5c06\u6587\u4ef6\u8def\u5f84\u8f6c\u6362\u4e3a\u5185\u5bb9 URI\u3002

      pathToUri(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5185\u5bb9 URI \u5b57\u7b26\u4e32

      "},{"location":"qsl4a/core/intent/#openfile","title":"openFile()","text":"

      \u7528\u9002\u5f53\u7684\u5e94\u7528\u7a0b\u5e8f\u6253\u5f00\u6587\u4ef6\u3002

      openFile(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u6253\u5f00\u7684\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/core/intent/#sendfile","title":"sendFile()","text":"

      \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u6587\u4ef6\u3002

      sendFile(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u53d1\u9001\u7684\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/core/intent/#getpathtype","title":"getPathType()","text":"

      \u83b7\u53d6\u6587\u4ef6\u8def\u5f84\u7684 MIME \u7c7b\u578b\u3002

      getPathType(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a MIME \u7c7b\u578b\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/core/intent/#viewmap","title":"viewMap()","text":"

      \u5728\u6307\u5b9a\u4f4d\u7f6e\u6253\u5f00\u5730\u56fe\u3002

      viewMap(latitude, longitude)\n

      \u53c2\u6570\uff1a - latitude (float): \u7eac\u5ea6 - longitude (float): \u7ecf\u5ea6

      "},{"location":"qsl4a/core/intent/#viewcontacts","title":"viewContacts()","text":"

      \u6253\u5f00\u8054\u7cfb\u4eba\u5e94\u7528\u3002

      viewContacts()\n
      "},{"location":"qsl4a/core/intent/#search","title":"search()","text":"

      \u6267\u884c\u7f51\u7edc\u641c\u7d22\u3002

      search(query)\n

      \u53c2\u6570\uff1a - query (str): \u641c\u7d22\u67e5\u8be2

      "},{"location":"qsl4a/core/intent/#viewhtml","title":"viewHtml()","text":"

      \u67e5\u770b HTML \u5185\u5bb9\u3002

      viewHtml(content, encoding=None)\n

      \u53c2\u6570\uff1a - content (str): HTML \u5185\u5bb9 - encoding (str, optional): \u5b57\u7b26\u7f16\u7801

      "},{"location":"qsl4a/core/intent/#webviewshow","title":"webViewShow()","text":"

      \u5728 WebView \u4e2d\u663e\u793a\u7f51\u9875\u5185\u5bb9\u3002\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 viewHtml\u3002

      webViewShow(url)\n

      \u53c2\u6570\uff1a - url (str): \u7f51\u9875 URL

      "},{"location":"qsl4a/core/intent/#editoropen","title":"editorOpen()","text":"

      \u6253\u5f00\u6587\u672c\u7f16\u8f91\u5668\u3002

      editorOpen(path=None, create=False)\n

      \u53c2\u6570\uff1a - path (str, optional): \u8981\u7f16\u8f91\u7684\u6587\u4ef6\u8def\u5f84 - create (bool, optional): \u5982\u679c\u4e0d\u5b58\u5728\u5219\u521b\u5efa

      "},{"location":"qsl4a/core/intent/#uri","title":"\u8f85\u52a9\u7c7b\uff1aUri","text":"

      \u521b\u5efa Intent \u7684 URI \u5bf9\u8c61\uff1a

      from androidhelper.Intent import Uri\n\nuri = Uri(\"file:///sdcard/test.txt\")\n
      "},{"location":"qsl4a/core/intent/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/intent/#_7","title":"\u6253\u5f00\u7f51\u9875","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"http://www.example.com\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_8","title":"\u5206\u4eab\u6587\u672c","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_TEXT: \"Hello from QPython!\",\n        droid.Intent.EXTRA_SUBJECT: \"Test\"\n    },\n    type=\"text/plain\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_9","title":"\u6253\u5f00\u6587\u4ef6","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"file:///sdcard/document.pdf\",\n    type=\"application/pdf\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_10","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":"
      result = droid.pickContact()\ncontact_uri = result.result\n
      "},{"location":"qsl4a/core/intent/#_11","title":"\u53d1\u9001\u7535\u5b50\u90ae\u4ef6","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_EMAIL: [\"test@example.com\"],\n        droid.Intent.EXTRA_SUBJECT: \"Hello\",\n        droid.Intent.EXTRA_TEXT: \"Message body\"\n    },\n    type=\"message/rfc822\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_12","title":"\u6253\u5f00\u5e94\u7528","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_MAIN,\n    packagename=\"com.android.settings\",\n    classname=\"com.android.settings.Settings\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/hardware/bluetooth/","title":"\u84dd\u7259 API","text":"

      \u63a7\u5236\u84dd\u7259\u9002\u914d\u5668\u5e76\u4e0e\u84dd\u7259\u8bbe\u5907\u901a\u4fe1\u3002

      "},{"location":"qsl4a/hardware/bluetooth/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/hardware/bluetooth/#togglebluetoothstate","title":"toggleBluetoothState()","text":"

      \u6253\u5f00/\u5173\u95ed\u84dd\u7259\u3002

      toggleBluetoothState(enabled=None, prompt=True)\n

      \u53c2\u6570\uff1a - enabled (bool): True=\u5f00\uff0cFalse=\u5173\uff0cNone=\u5207\u6362 - prompt (bool): \u663e\u793a\u7528\u6237\u63d0\u793a

      "},{"location":"qsl4a/hardware/bluetooth/#checkbluetoothstate","title":"checkBluetoothState()","text":"

      \u68c0\u67e5\u84dd\u7259\u662f\u5426\u5df2\u542f\u7528\u3002

      checkBluetoothState()\n

      \u8fd4\u56de\uff1a True/False

      "},{"location":"qsl4a/hardware/bluetooth/#getlocalname","title":"GetLocalName()","text":"

      \u83b7\u53d6\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

      GetLocalName()\n
      "},{"location":"qsl4a/hardware/bluetooth/#setlocalname","title":"SetLocalName()","text":"

      \u8bbe\u7f6e\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

      SetLocalName(name)\n
      "},{"location":"qsl4a/hardware/bluetooth/#getscanmode","title":"GetScanMode()","text":"

      \u83b7\u53d6\u53ef\u53d1\u73b0\u6027\u6a21\u5f0f\u3002

      GetScanMode()\n

      \u8fd4\u56de\uff1a - -1: \u5df2\u7981\u7528 - 0: \u4e0d\u53ef\u53d1\u73b0\uff0c\u4e0d\u53ef\u8fde\u63a5 - 1: \u53ef\u8fde\u63a5\uff0c\u4e0d\u53ef\u53d1\u73b0 - 3: \u53ef\u8fde\u63a5\u4e14\u53ef\u53d1\u73b0

      "},{"location":"qsl4a/hardware/bluetooth/#makediscoverable","title":"MakeDiscoverable()","text":"

      \u4f7f\u8bbe\u5907\u53ef\u53d1\u73b0\u3002

      MakeDiscoverable(duration=300)\n

      \u53c2\u6570\uff1a - duration (int): \u53ef\u53d1\u73b0\u7684\u79d2\u6570

      "},{"location":"qsl4a/hardware/bluetooth/#_2","title":"\u53d1\u73b0","text":""},{"location":"qsl4a/hardware/bluetooth/#discoverystart","title":"DiscoveryStart()","text":"

      \u5f00\u59cb\u8bbe\u5907\u53d1\u73b0\u3002

      DiscoveryStart()\n
      "},{"location":"qsl4a/hardware/bluetooth/#discoverycancel","title":"DiscoveryCancel()","text":"

      \u53d6\u6d88\u53d1\u73b0\u3002

      DiscoveryCancel()\n
      "},{"location":"qsl4a/hardware/bluetooth/#getreceiveddevices","title":"GetReceivedDevices()","text":"

      \u83b7\u53d6\u53d1\u73b0\u7684\u8bbe\u5907\u3002

      GetReceivedDevices()\n

      \u8fd4\u56de\uff1a \u8bbe\u5907\u4fe1\u606f\u5b57\u5178\u5217\u8868

      "},{"location":"qsl4a/hardware/bluetooth/#getbondeddevices","title":"GetBondedDevices()","text":"

      \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\u3002

      GetBondedDevices()\n

      \u8fd4\u56de\uff1a \u914d\u5bf9\u8bbe\u5907\u4fe1\u606f\u5217\u8868

      "},{"location":"qsl4a/hardware/bluetooth/#_3","title":"\u8fde\u63a5","text":""},{"location":"qsl4a/hardware/bluetooth/#connect","title":"Connect()","text":"

      \u8fde\u63a5\u5230\u8bbe\u5907\u3002

      Connect(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", address=None)\n

      \u53c2\u6570\uff1a - uuid (str): \u670d\u52a1 UUID - address (str): \u8bbe\u5907\u5730\u5740\uff08None = \u663e\u793a\u9009\u62e9\u5668\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/hardware/bluetooth/#accept","title":"Accept()","text":"

      \u63a5\u53d7\u4f20\u5165\u8fde\u63a5\u3002

      Accept(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", timeout=0)\n
      "},{"location":"qsl4a/hardware/bluetooth/#activeconnections","title":"ActiveConnections()","text":"

      \u68c0\u67e5\u6d3b\u52a8\u8fde\u63a5\u3002

      ActiveConnections()\n
      "},{"location":"qsl4a/hardware/bluetooth/#stop","title":"Stop()","text":"

      \u65ad\u5f00\u8fde\u63a5\u3002

      Stop(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#_4","title":"\u901a\u4fe1","text":""},{"location":"qsl4a/hardware/bluetooth/#write","title":"Write()","text":"

      \u53d1\u9001 ASCII \u6570\u636e\u3002

      Write(ascii, connID=\"\")\n
      "},{"location":"qsl4a/hardware/bluetooth/#writebinary","title":"WriteBinary()","text":"

      \u53d1\u9001\u4e8c\u8fdb\u5236\u6570\u636e\uff08base64 \u7f16\u7801\uff09\u3002

      WriteBinary(base64, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#read","title":"Read()","text":"

      \u8bfb\u53d6 ASCII \u6570\u636e\u3002

      Read(bufferSize=4096, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readbinary","title":"ReadBinary()","text":"

      \u8bfb\u53d6\u4e8c\u8fdb\u5236\u6570\u636e\u3002

      ReadBinary(bufferSize=4096, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readline","title":"ReadLine()","text":"

      \u8bfb\u53d6\u4e00\u884c\u3002

      ReadLine(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readready","title":"ReadReady()","text":"

      \u68c0\u67e5\u662f\u5426\u6709\u53ef\u7528\u6570\u636e\u3002

      ReadReady(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u7528\u84dd\u7259\ndroid.toggleBluetoothState(True)\n\n# \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\ndevices = droid.GetBondedDevices().result\nfor dev in devices:\n    print(f\"{dev['name']}: {dev['address']}\")\n\n# \u8fde\u63a5\u5230\u8bbe\u5907\ndroid.Connect(address=\"00:11:22:33:44:55\")\n\n# \u53d1\u9001\u6570\u636e\ndroid.Write(\"Hello Bluetooth!\")\n\n# \u8bfb\u53d6\u54cd\u5e94\ndata = droid.Read(1024).result\n
      "},{"location":"qsl4a/hardware/camera/","title":"\u76f8\u673a API","text":"

      \u62cd\u6444\u7167\u7247\u548c\u5f55\u5236\u89c6\u9891\u3002

      "},{"location":"qsl4a/hardware/camera/#_1","title":"\u7167\u7247\u62cd\u6444","text":""},{"location":"qsl4a/hardware/camera/#takepicture","title":"takePicture()","text":"

      \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u6444\u7167\u7247\u3002

      takePicture(path=None)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8fd4\u56de\u56fe\u50cf\u6570\u636e

      \u8fd4\u56de\uff1a \u56fe\u50cf\u8def\u5f84\u6216\u56fe\u50cf\u6570\u636e

      "},{"location":"qsl4a/hardware/camera/#cameracapturepicture","title":"cameraCapturePicture()","text":"

      \u4f7f\u7528\u9ad8\u7ea7\u76f8\u673a\u63a7\u5236\u62cd\u6444\u7167\u7247\u3002

      cameraCapturePicture(targetPath=None, cameraId=0, useAutoFocus=True)\n

      \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - useAutoFocus (bool): \u542f\u7528\u81ea\u52a8\u5bf9\u7126

      \u8fd4\u56de\uff1a \u62cd\u6444\u7684\u56fe\u50cf\u8def\u5f84

      "},{"location":"qsl4a/hardware/camera/#camerasettorchmode","title":"cameraSetTorchMode()","text":"

      \u63a7\u5236\u76f8\u673a\u95ea\u5149\u706f/\u624b\u7535\u7b52\u3002

      cameraSetTorchMode(enabled)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u6253\u5f00\uff0cFalse \u5173\u95ed

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/hardware/camera/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

      \u622a\u56fe\u3002

      imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

      "},{"location":"qsl4a/hardware/camera/#_2","title":"\u89c6\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#takevideo","title":"takeVideo()","text":"

      \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\u3002

      takeVideo(path=None, quality=1)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-4\uff09 - 0: 160x120 - 1: 320x240 - 2: 352x288 - 3: 640x480 - 4: 800x480

      "},{"location":"qsl4a/hardware/camera/#recordercapturevideo","title":"recorderCaptureVideo()","text":"

      \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\u3002

      recorderCaptureVideo(targetPath=None, duration=10, cameraId=0, quality=8)\n

      \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - duration (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a10\uff09 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-8\uff0c\u8d8a\u9ad8\u8d8a\u597d\uff09

      \u8fd4\u56de\uff1a \u89c6\u9891\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/hardware/camera/#recordaudio","title":"recordAudio()","text":"

      \u5f55\u5236\u97f3\u9891\u3002

      recordAudio()\n

      \u8fd4\u56de\uff1a \u97f3\u9891\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/hardware/camera/#_3","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

      \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\u3002

      recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

      \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\uff09 - targetPixels (int): \u5206\u8fa8\u7387 - frameRate (int): FPS - bitRate (int): \u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa - autoStart (bool): \u7acb\u5373\u5f00\u59cb

      "},{"location":"qsl4a/hardware/camera/#recorderstart","title":"recorderStart()","text":"

      \u5f00\u59cb\u5f55\u5236\u3002

      recorderStart()\n
      "},{"location":"qsl4a/hardware/camera/#recorderpause","title":"recorderPause()","text":"

      \u6682\u505c\u5f55\u5236\u3002

      recorderPause()\n
      "},{"location":"qsl4a/hardware/camera/#recorderresume","title":"recorderResume()","text":"

      \u6062\u590d\u5f55\u5236\u3002

      recorderResume()\n
      "},{"location":"qsl4a/hardware/camera/#_4","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/camera/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

      \u5f00\u59cb\u97f3\u91cf\u68c0\u6d4b\u3002

      recorderSoundVolumeDetect(interval=100)\n
      "},{"location":"qsl4a/hardware/camera/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

      \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

      recorderSoundVolumeGetDb()\n
      "},{"location":"qsl4a/hardware/camera/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u7167\nphoto_path = droid.takePicture(\"/sdcard/photo.jpg\").result\nprint(f\"Photo saved: {photo_path}\")\n\n# \u4f7f\u7528\u524d\u7f6e\u76f8\u673a\u548c\u81ea\u52a8\u5bf9\u7126\u62cd\u7167\ncamera_path = droid.cameraCapturePicture(\"/sdcard/selfie.jpg\", cameraId=1, useAutoFocus=True).result\nprint(f\"Front camera photo: {camera_path}\")\n\n# \u63a7\u5236\u95ea\u5149\u706f\ndroid.cameraSetTorchMode(True)  # \u6253\u5f00\u95ea\u5149\u706f\n\n# \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\nvideo_path = droid.takeVideo(\"/sdcard/video.mp4\", quality=3).result\nprint(f\"Video saved: {video_path}\")\n\n# \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\nvideo_path = droid.recorderCaptureVideo(\"/sdcard/movie.mp4\", duration=30, cameraId=0, quality=8).result\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n
      "},{"location":"qsl4a/hardware/recorder/","title":"\u97f3\u9891\u5f55\u5236 API","text":"

      \u4ece\u9ea6\u514b\u98ce\u548c\u8bbe\u5907\u5c4f\u5e55\u5f55\u5236\u97f3\u9891\u3002

      "},{"location":"qsl4a/hardware/recorder/#_1","title":"\u97f3\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recordaudio","title":"recordAudio()","text":"

      \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\u3002

      recordAudio()\n

      \u8fd4\u56de\uff1a \u5f55\u5236\u7684\u97f3\u9891\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/hardware/recorder/#recorderstartmicrophone","title":"recorderStartMicrophone()","text":"

      \u5f00\u59cb\u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\u3002

      recorderStartMicrophone(targetPath=None)\n

      \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u5f55\u5236\u7684\u8def\u5f84

      "},{"location":"qsl4a/hardware/recorder/#_2","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

      \u5f00\u59cb\u5e26\u97f3\u9891\u7684\u5c4f\u5e55\u5f55\u5236\u3002

      recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

      \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\u97f3\u9891\uff09 - targetPixels (int): \u76ee\u6807\u5206\u8fa8\u7387\uff08\u50cf\u7d20\uff09 - frameRate (int): \u6bcf\u79d2\u5e27\u6570\uff08\u9ed8\u8ba4\uff1a30\uff09 - bitRate (int): \u89c6\u9891\u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa\u89c6\u9891 - autoStart (bool): \u7acb\u5373\u5f00\u59cb\u5f55\u5236

      \u8fd4\u56de\uff1a \u64cd\u4f5c\u7ed3\u679c

      "},{"location":"qsl4a/hardware/recorder/#recorderstart","title":"recorderStart()","text":"

      \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\uff08\u5f53 autoStart=False \u65f6\uff09\u3002

      recorderStart()\n
      "},{"location":"qsl4a/hardware/recorder/#recorderpause","title":"recorderPause()","text":"

      \u6682\u505c\u6b63\u5728\u8fdb\u884c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

      recorderPause()\n
      "},{"location":"qsl4a/hardware/recorder/#recorderresume","title":"recorderResume()","text":"

      \u6062\u590d\u6682\u505c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

      recorderResume()\n
      "},{"location":"qsl4a/hardware/recorder/#_3","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/recorder/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

      \u5f00\u59cb\u76d1\u63a7\u97f3\u91cf\u7ea7\u522b\u3002

      recorderSoundVolumeDetect(interval=100)\n

      \u53c2\u6570\uff1a - interval (int): \u68c0\u6d4b\u95f4\u9694\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a100\uff09

      "},{"location":"qsl4a/hardware/recorder/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

      \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

      recorderSoundVolumeGetDb()\n

      \u8fd4\u56de\uff1a \u5f53\u524d\u97f3\u91cf\u7ea7\u522b\uff08dB\uff09

      "},{"location":"qsl4a/hardware/recorder/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\nprint(\"Recording audio...\")\naudio_path = droid.recordAudio().result\nprint(f\"Saved to: {audio_path}\")\n\n# \u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\ndroid.recorderStartMicrophone(\"/sdcard/my_recording.mp3\")\ntime.sleep(5)\ndroid.recorderStop()\n\n# \u5e26\u97f3\u9891\u5f55\u5236\u5c4f\u5e55\nprint(\"Starting screen recording...\")\ndroid.recorderStartScreenRecord(\n    path=\"/sdcard/screen_record.mp4\",\n    audio=1,\n    frameRate=30,\n    autoStart=True\n)\ntime.sleep(10)\ndroid.recorderStop()\n\n# \u76d1\u63a7\u97f3\u91cf\ndroid.recorderSoundVolumeDetect(interval=100)\ntime.sleep(3)\nvolume = droid.recorderSoundVolumeGetDb().result\nprint(f\"Current volume: {volume} dB\")\n
      "},{"location":"qsl4a/hardware/usbserial/","title":"USB \u4e3b\u673a\u4e32\u884c API","text":"

      \u4e0e USB \u4e32\u884c\u8bbe\u5907\u901a\u4fe1\uff08\u9700\u8981 USB OTG \u652f\u6301\u548c Android 3.1+\uff09\u3002

      "},{"location":"qsl4a/hardware/usbserial/#usb","title":"USB \u4e32\u884c\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialopen","title":"usbHostSerialOpen()","text":"

      \u6253\u5f00\u4e0e USB \u4e32\u884c\u8bbe\u5907\u7684\u8fde\u63a5\u3002

      usbHostSerialOpen(device, baudRate=9600)\n

      \u53c2\u6570\uff1a - device (str): USB \u8bbe\u5907\u8def\u5f84\u6216\u6807\u8bc6\u7b26 - baudRate (int): \u6ce2\u7279\u7387\uff08\u9ed8\u8ba4\uff1a9600\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u6253\u5f00\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialclose","title":"usbHostSerialClose()","text":"

      \u5173\u95ed USB \u4e32\u884c\u8fde\u63a5\u3002

      usbHostSerialClose()\n
      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialread","title":"usbHostSerialRead()","text":"

      \u4ece USB \u4e32\u884c\u8bfb\u53d6\u6570\u636e\u3002

      usbHostSerialRead(bufferSize=1024)\n

      \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570\uff08\u9ed8\u8ba4\uff1a1024\uff09

      \u8fd4\u56de\uff1a \u8bfb\u53d6\u7684\u6570\u636e\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwrite","title":"usbHostSerialWrite()","text":"

      \u5411 USB \u4e32\u884c\u5199\u5165\u6570\u636e\u3002

      usbHostSerialWrite(data)\n

      \u53c2\u6570\uff1a - data (str): \u8981\u5199\u5165\u7684\u5b57\u7b26\u4e32\u6570\u636e

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialavailable","title":"usbHostSerialAvailable()","text":"

      \u68c0\u67e5\u662f\u5426\u6709\u53ef\u8bfb\u53d6\u7684\u6570\u636e\u3002

      usbHostSerialAvailable()\n

      \u8fd4\u56de\uff1a \u53ef\u7528\u5b57\u8282\u6570

      "},{"location":"qsl4a/hardware/usbserial/#_1","title":"\u914d\u7f6e\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetbaudrate","title":"usbHostSerialSetBaudRate()","text":"

      \u8bbe\u7f6e\u6ce2\u7279\u7387\u3002

      usbHostSerialSetBaudRate(baudRate)\n

      \u53c2\u6570\uff1a - baudRate (int): \u6ce2\u7279\u7387

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetdatabits","title":"usbHostSerialSetDataBits()","text":"

      \u8bbe\u7f6e\u6570\u636e\u4f4d\uff085\u30016\u30017 \u6216 8\uff09\u3002

      usbHostSerialSetDataBits(dataBits)\n

      \u53c2\u6570\uff1a - dataBits (int): \u6570\u636e\u4f4d\uff085-8\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetstopbits","title":"usbHostSerialSetStopBits()","text":"

      \u8bbe\u7f6e\u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09\u3002

      usbHostSerialSetStopBits(stopBits)\n

      \u53c2\u6570\uff1a - stopBits (float): \u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetparity","title":"usbHostSerialSetParity()","text":"

      \u8bbe\u7f6e\u6821\u9a8c\u4f4d\uff08\u65e0\u3001\u5947\u3001\u5076\u3001\u6807\u8bb0\u3001\u7a7a\u683c\uff09\u3002

      usbHostSerialSetParity(parity)\n

      \u53c2\u6570\uff1a - parity (str): \u6821\u9a8c\u6a21\u5f0f\uff08'none'\u3001'odd'\u3001'even'\u3001'mark'\u3001'space'\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetflowcontrol","title":"usbHostSerialSetFlowControl()","text":"

      \u8bbe\u7f6e\u6d41\u63a7\u5236\uff08\u65e0\u3001\u786c\u4ef6\u3001\u8f6f\u4ef6\uff09\u3002

      usbHostSerialSetFlowControl(flowControl)\n

      \u53c2\u6570\uff1a - flowControl (str): \u6d41\u63a7\u5236\u6a21\u5f0f\uff08'none'\u3001'hardware'\u3001'software'\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialreadhex","title":"usbHostSerialReadHex()","text":"

      \u4ee5\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u8bfb\u53d6\u6570\u636e\u3002

      usbHostSerialReadHex(bufferSize=1024)\n

      \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570

      \u8fd4\u56de\uff1a \u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwritehex","title":"usbHostSerialWriteHex()","text":"

      \u4ece\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u5199\u5165\u6570\u636e\u3002

      usbHostSerialWriteHex(hexString)\n

      \u53c2\u6570\uff1a - hexString (str): \u8981\u5199\u5165\u7684\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/hardware/usbserial/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6253\u5f00 USB \u4e32\u884c\u8fde\u63a5\nif droid.usbHostSerialOpen(\"/dev/bus/usb/001/001\", 115200).result:\n    print(\"USB serial opened\")\n\n    # \u5199\u5165\u6570\u636e\n    droid.usbHostSerialWrite(\"AT\\r\")\n\n    # \u8bfb\u53d6\u54cd\u5e94\n    response = droid.usbHostSerialRead(1024).result\n    print(f\"Response: {response}\")\n\n    # \u6216\u4f7f\u7528\u5341\u516d\u8fdb\u5236\n    droid.usbHostSerialWriteHex(\"41540D0A\")  # \"AT\\r\\n\"\n\n    # \u5173\u95ed\u8fde\u63a5\n    droid.usbHostSerialClose()\n

      \u6ce8\u610f\uff1a USB \u4e32\u884c\u9700\u8981\uff1a - Android 3.1+ (API 12) - USB OTG \u7ebf/\u9002\u914d\u5668 - \u8bbe\u5907\u4e0a\u7684 USB \u4e3b\u673a\u6a21\u5f0f\u652f\u6301 - \u517c\u5bb9\u7684\u4e32\u884c\u8bbe\u5907

      "},{"location":"qsl4a/hardware/webcam/","title":"\u7f51\u7edc\u6444\u50cf\u5934 API","text":"

      \u4f7f\u7528 MJPEG \u4ece\u8bbe\u5907\u76f8\u673a\u6d41\u5f0f\u4f20\u8f93\u89c6\u9891\u3002

      "},{"location":"qsl4a/hardware/webcam/#mjpeg","title":"MJPEG \u6d41\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#webcamstart","title":"webcamStart()","text":"

      \u4ece\u7f51\u7edc\u6444\u50cf\u5934\u542f\u52a8 MJPEG \u6d41\u3002

      webcamStart(resolutionLevel=0, jpegQuality=20, port=0)\n

      \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf 1-100\uff08\u9ed8\u8ba4\uff1a20\uff09 - port (int): \u7aef\u53e3\u53f7\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\uff09

      \u8fd4\u56de\uff1a \u6d41\u7684 (\u5730\u5740, \u7aef\u53e3) \u5143\u7ec4

      "},{"location":"qsl4a/hardware/webcam/#webcamadjustquality","title":"webcamAdjustQuality()","text":"

      \u8c03\u6574\u6d3b\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u7684\u8d28\u91cf\u3002

      webcamAdjustQuality(resolutionLevel=0, jpegQuality=20)\n

      \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b - jpegQuality (int): JPEG \u8d28\u91cf 1-100

      "},{"location":"qsl4a/hardware/webcam/#webcamstop","title":"webcamStop()","text":"

      \u505c\u6b62\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u3002

      webcamStop()\n
      "},{"location":"qsl4a/hardware/webcam/#_1","title":"\u76f8\u673a\u9884\u89c8\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#camerastartpreview","title":"cameraStartPreview()","text":"

      \u5f00\u59cb\u5e26\u4e8b\u4ef6\u751f\u6210\u7684\u76f8\u673a\u9884\u89c8\u6a21\u5f0f\u3002

      cameraStartPreview(resolutionLevel=0, jpegQuality=20, filepath=None)\n

      \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf\uff08\u9ed8\u8ba4\uff1a20\uff09 - filepath (str, optional): \u4fdd\u5b58\u9884\u89c8\u5e27\u7684\u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      \u6ce8\u610f\uff1a \u751f\u6210\u5e26\u6709\u5e27\u6570\u636e\u7684 'preview' \u4e8b\u4ef6\u3002

      "},{"location":"qsl4a/hardware/webcam/#camerastoppreview","title":"cameraStopPreview()","text":"

      \u505c\u6b62\u76f8\u673a\u9884\u89c8\u3002

      cameraStopPreview()\n
      "},{"location":"qsl4a/hardware/webcam/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\nstream_info = droid.webcamStart(\n    resolutionLevel=0,\n    jpegQuality=30,\n    port=8080\n).result\nprint(f\"Stream available at {stream_info[0]}:{stream_info[1]}\")\n\n# \u6d41\u5f0f\u4f20\u8f93\u65f6\u8c03\u6574\u8d28\u91cf\ntime.sleep(5)\ndroid.webcamAdjustQuality(resolutionLevel=1, jpegQuality=50)\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.webcamStop()\n\n# \u6216\u4f7f\u7528\u9884\u89c8\u6a21\u5f0f\nprint(\"Starting preview...\")\ndroid.cameraStartPreview()\n\n# \u7b49\u5f85\u9884\u89c8\u4e8b\u4ef6\nfor i in range(10):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'preview':\n        print(f\"Got preview frame: {event['data']}\")\n\ndroid.cameraStopPreview()\n
      "},{"location":"qsl4a/media/image/","title":"\u56fe\u50cf\u5904\u7406 API","text":"

      \u538b\u7f29\u548c\u5904\u7406\u56fe\u50cf\u3002

      "},{"location":"qsl4a/media/image/#_1","title":"\u56fe\u50cf\u538b\u7f29","text":""},{"location":"qsl4a/media/image/#imagecompress","title":"imageCompress()","text":"

      \u538b\u7f29\u56fe\u50cf\u6587\u4ef6\u3002

      imageCompress(srcPath, destPath, targetByteSize=0, targetWidth=0, targetHeight=0)\n

      \u53c2\u6570\uff1a - srcPath (str): \u6e90\u56fe\u50cf\u8def\u5f84 - destPath (str): \u8f93\u51fa\u8def\u5f84 - targetByteSize (int): \u76ee\u6807\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff080 = \u65e0\u9650\u5236\uff09 - targetWidth (int): \u76ee\u6807\u5bbd\u5ea6\uff080 = \u539f\u59cb\uff09 - targetHeight (int): \u76ee\u6807\u9ad8\u5ea6\uff080 = \u539f\u59cb\uff09

      \u8fd4\u56de\uff1a \u538b\u7f29\u540e\u7684\u56fe\u50cf\u8def\u5f84

      "},{"location":"qsl4a/media/image/#_2","title":"\u622a\u56fe","text":""},{"location":"qsl4a/media/image/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

      \u622a\u53d6\u5c4f\u5e55\u3002

      imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

      \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

      \u8fd4\u56de\uff1a \u622a\u56fe\u8def\u5f84

      "},{"location":"qsl4a/media/image/#_3","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/image/#videoplay","title":"videoPlay()","text":"

      \u5728\u5168\u5c4f\u6a21\u5f0f\u4e0b\u64ad\u653e\u89c6\u9891\u6587\u4ef6\u3002

      videoPlay(path, wait=True)\n

      \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

      "},{"location":"qsl4a/media/image/#_4","title":"\u6761\u7801\u626b\u63cf","text":""},{"location":"qsl4a/media/image/#scanbarcodefromimage","title":"scanBarcodeFromImage()","text":"

      \u4ece\u56fe\u50cf\u6587\u4ef6\u626b\u63cf\u6761\u7801/\u4e8c\u7ef4\u7801\u3002

      scanBarcodeFromImage(path, compressRatio=0, x=0, y=0, width=0, height=0)\n

      \u53c2\u6570\uff1a - path (str): \u56fe\u50cf\u6587\u4ef6\u8def\u5f84 - compressRatio (int): \u538b\u7f29\u6bd4\uff080 = \u4e0d\u538b\u7f29\uff09 - x, y, width, height (int): \u8981\u626b\u63cf\u7684\u533a\u57df\uff080 = \u5b8c\u6574\u56fe\u50cf\uff09

      \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5185\u5bb9

      "},{"location":"qsl4a/media/image/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n\n# \u538b\u7f29\u56fe\u50cf\ncompressed = droid.imageCompress(\n    \"/sdcard/large_photo.jpg\",\n    \"/sdcard/compressed.jpg\",\n    targetByteSize=102400,  # \u76ee\u6807\u7ea6 100KB\n    targetWidth=1920,\n    targetHeight=1080\n).result\nprint(f\"Saved: {compressed}\")\n\n# \u64ad\u653e\u89c6\u9891\nvideo_path = \"/sdcard/movie.mp4\"\ndroid.videoPlay(video_path, wait=True)\n\n# \u4ece\u56fe\u50cf\u626b\u63cf\u6761\u7801\nresult = droid.scanBarcodeFromImage(\"/sdcard/qr_code.png\").result\nprint(f\"Barcode: {result}\")\n
      "},{"location":"qsl4a/media/mediaplayer/","title":"\u5a92\u4f53\u64ad\u653e\u5668 API","text":"

      \u63a7\u5236\u97f3\u9891\u548c\u89c6\u9891\u64ad\u653e\u3002

      "},{"location":"qsl4a/media/mediaplayer/#_1","title":"\u64ad\u653e\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplay","title":"mediaPlay()","text":"

      \u64ad\u653e\u5a92\u4f53\u6587\u4ef6\u3002

      mediaPlay(url, tag=\"default\", play=True)\n

      \u53c2\u6570\uff1a - url (str): \u5a92\u4f53\u6587\u4ef6\u8def\u5f84\u6216 URL - tag (str): \u64ad\u653e\u5668\u6807\u8bc6\u7b26 - play (bool): \u81ea\u52a8\u5f00\u59cb\u64ad\u653e

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaystart","title":"mediaPlayStart()","text":"

      \u5f00\u59cb\u64ad\u653e\u3002

      mediaPlayStart(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplaypause","title":"mediaPlayPause()","text":"

      \u6682\u505c\u64ad\u653e\u3002

      mediaPlayPause(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplayclose","title":"mediaPlayClose()","text":"

      \u5173\u95ed\u64ad\u653e\u5668\u3002

      mediaPlayClose(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplayseek","title":"mediaPlaySeek()","text":"

      \u8df3\u8f6c\u5230\u4f4d\u7f6e\u3002

      mediaPlaySeek(msec, tag=\"default\")\n

      \u53c2\u6570\uff1a - msec (int): \u4f4d\u7f6e\uff08\u6beb\u79d2\uff09

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaysetlooping","title":"mediaPlaySetLooping()","text":"

      \u8bbe\u7f6e\u5faa\u73af\u6a21\u5f0f\u3002

      mediaPlaySetLooping(enabled, tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#_2","title":"\u64ad\u653e\u5668\u4fe1\u606f","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplayinfo","title":"mediaPlayInfo()","text":"

      \u83b7\u53d6\u64ad\u653e\u4fe1\u606f\u3002

      mediaPlayInfo(tag=\"default\")\n

      \u8fd4\u56de\uff1a \u5305\u542b\u65f6\u957f\u3001\u4f4d\u7f6e\u7b49\u7684\u5b57\u5178

      "},{"location":"qsl4a/media/mediaplayer/#mediaisplaying","title":"mediaIsPlaying()","text":"

      \u68c0\u67e5\u662f\u5426\u6b63\u5728\u64ad\u653e\u3002

      mediaIsPlaying(tag=\"default\")\n

      \u8fd4\u56de\uff1a True/False

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaylist","title":"mediaPlayList()","text":"

      \u5217\u51fa\u6d3b\u52a8\u64ad\u653e\u5668\u3002

      mediaPlayList()\n
      "},{"location":"qsl4a/media/mediaplayer/#_3","title":"\u97f3\u91cf\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#getmediavolume","title":"getMediaVolume()","text":"

      \u83b7\u53d6\u5a92\u4f53\u97f3\u91cf\u3002

      getMediaVolume()\n

      \u8fd4\u56de\uff1a \u97f3\u91cf\u7ea7\u522b\uff080-15\uff09

      "},{"location":"qsl4a/media/mediaplayer/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

      getMaxMediaVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#getringervolume","title":"getRingerVolume()","text":"

      \u83b7\u53d6\u94c3\u58f0\u97f3\u91cf\u3002

      getRingerVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

      getMaxRingerVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#_4","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/mediaplayer/#videoplay","title":"videoPlay()","text":"

      \u5168\u5c4f\u64ad\u653e\u89c6\u9891\u3002

      videoPlay(path, wait=True)\n

      \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210

      "},{"location":"qsl4a/media/mediaplayer/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u64ad\u653e\u97f3\u9891\ndroid.mediaPlay(\"/sdcard/music.mp3\", tag=\"music\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.mediaIsPlaying(\"music\").result:\n    info = droid.mediaPlayInfo(\"music\").result\n    print(f\"Playing: {info}\")\n\n# \u8df3\u8f6c\u5230 30 \u79d2\ndroid.mediaPlaySeek(30000, \"music\")\n\n# \u5173\u95ed\ndroid.mediaPlayClose(\"music\")\n\n# \u64ad\u653e\u89c6\u9891\ndroid.videoPlay(\"/sdcard/movie.mp4\", wait=True)\n
      "},{"location":"qsl4a/special/cipher/","title":"\u5bc6\u7801 API","text":"

      \u7528\u4e8e\u5b89\u5168\u6570\u636e\u5b58\u50a8\u7684\u52a0\u5bc6\u548c\u89e3\u5bc6\u5de5\u5177\u3002

      "},{"location":"qsl4a/special/cipher/#_1","title":"\u521d\u59cb\u5316","text":""},{"location":"qsl4a/special/cipher/#cipherinit","title":"cipherInit()","text":"

      \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u548c\u7b97\u6cd5\u521d\u59cb\u5316\u5bc6\u7801\u5668\u3002

      cipherInit(key, algorithm=\"AES/CBC/PKCS5Padding\", encodingFormat=\"\", initialVector=\"\")\n

      \u53c2\u6570\uff1a - key (str or bytes): \u52a0\u5bc6\u5bc6\u94a5 - algorithm (str): \u5bc6\u7801\u7b97\u6cd5\uff08\u9ed8\u8ba4\uff1a\"AES/CBC/PKCS5Padding\"\uff09 - encodingFormat (str): \u7f16\u7801\u683c\u5f0f - initialVector (str or bytes): \u52a0\u5bc6\u7684\u521d\u59cb\u5411\u91cf

      \u8fd4\u56de\uff1a \u521d\u59cb\u5316\u7ed3\u679c

      \u6ce8\u610f\uff1a \u5fc5\u987b\u5728\u4efb\u4f55\u52a0\u5bc6/\u89e3\u5bc6\u64cd\u4f5c\u4e4b\u524d\u8c03\u7528\u3002

      "},{"location":"qsl4a/special/cipher/#_2","title":"\u52a0\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#encryptstring","title":"encryptString()","text":"

      \u52a0\u5bc6\u5b57\u7b26\u4e32\u3002

      encryptString(plainText)\n

      \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c

      \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/special/cipher/#encryptbytes","title":"encryptBytes()","text":"

      \u52a0\u5bc6\u5b57\u8282\u6570\u636e\u3002

      encryptBytes(data)\n

      \u53c2\u6570\uff1a - data (bytes): \u8981\u52a0\u5bc6\u7684\u6570\u636e

      \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u8282

      "},{"location":"qsl4a/special/cipher/#encryptstringtofile","title":"encryptStringToFile()","text":"

      \u52a0\u5bc6\u5b57\u7b26\u4e32\u5230\u6587\u4ef6\u3002

      encryptStringToFile(plainText, filePath)\n

      \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c - filePath (str): \u8f93\u51fa\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/special/cipher/#encryptbytestofile","title":"encryptBytesToFile()","text":"

      \u52a0\u5bc6\u5b57\u8282\u5230\u6587\u4ef6\u3002

      encryptBytesToFile(data, filePath)\n
      "},{"location":"qsl4a/special/cipher/#_3","title":"\u89e3\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#decryptstring","title":"decryptString()","text":"

      \u89e3\u5bc6\u4e3a\u5b57\u7b26\u4e32\u3002

      decryptString(cipherText)\n

      \u53c2\u6570\uff1a - cipherText (str): \u52a0\u5bc6\u7684\u6587\u672c

      \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/special/cipher/#decryptbytes","title":"decryptBytes()","text":"

      \u89e3\u5bc6\u4e3a\u5b57\u8282\u3002

      decryptBytes(data)\n

      \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u8282

      "},{"location":"qsl4a/special/cipher/#decryptfiletostring","title":"decryptFileToString()","text":"

      \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u7b26\u4e32\u3002

      decryptFileToString(filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryptfiletobytes","title":"decryptFileToBytes()","text":"

      \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u8282\u3002

      decryptFileToBytes(filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryptfile","title":"decryptFile()","text":"

      \u89e3\u5bc6\u6587\u4ef6\u5230\u6587\u4ef6\u3002

      decryptFile(srcPath, destPath)\n
      "},{"location":"qsl4a/special/cipher/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u521d\u59cb\u5316\u5bc6\u7801\u5668\ndroid.cipherInit(\"my_secret_key_1234\")\n\n# \u52a0\u5bc6\u5b57\u7b26\u4e32\nencrypted = droid.encryptString(\"Secret message!\").result\nprint(f\"Encrypted: {encrypted}\")\n\n# \u89e3\u5bc6\u5b57\u7b26\u4e32\ndecrypted = droid.decryptString(encrypted).result\nprint(f\"Decrypted: {decrypted}\")\n\n# \u52a0\u5bc6\u5230\u6587\u4ef6\ndroid.encryptStringToFile(\"My secret data\", \"/sdcard/secret.dat\")\n\n# \u4ece\u6587\u4ef6\u89e3\u5bc6\ndata = droid.decryptFileToString(\"/sdcard/secret.dat\").result\nprint(data)\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u7b97\u6cd5\u548c IV \u521d\u59cb\u5316\ndroid.cipherInit(\n    key=\"my_key\",\n    algorithm=\"AES/CBC/PKCS5Padding\",\n    initialVector=\"0123456789abcdef\"\n)\n
      "},{"location":"qsl4a/special/pgptai/","title":"PGPT AI API","text":"

      \u8bed\u97f3\u8f6c\u6587\u672c\u548c AI \u670d\u52a1\u96c6\u6210\u3002

      "},{"location":"qsl4a/special/pgptai/#_1","title":"\u5148\u51b3\u6761\u4ef6","text":"
      pip install pgptAI\n
      "},{"location":"qsl4a/special/pgptai/#_2","title":"\u8bed\u97f3\u8bc6\u522b","text":""},{"location":"qsl4a/special/pgptai/#speechtotext","title":"speechToText()","text":"

      \u5c06\u8bed\u97f3\u8f6c\u6362\u4e3a\u6587\u672c\u3002

      speechToText(RecordSecond=10, AmrFile=None, Language=None)\n

      \u53c2\u6570\uff1a - RecordSecond (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09 - AmrFile (str, optional): \u73b0\u6709\u97f3\u9891\u6587\u4ef6\u8def\u5f84 - Language (str, optional): \u8bed\u8a00\u4ee3\u7801\uff08'en'\u3001'zh'\uff09

      \u8fd4\u56de\uff1a \u8f6c\u5f55\u7684\u6587\u672c

      "},{"location":"qsl4a/special/pgptai/#_3","title":"\u6587\u672c\u8f6c\u8bed\u97f3","text":""},{"location":"qsl4a/special/pgptai/#texttospeech","title":"textToSpeech()","text":"

      \u5c06\u6587\u672c\u8f6c\u6362\u4e3a\u8bed\u97f3\u5e76\u53ef\u9009\u5730\u64ad\u653e\u3002

      textToSpeech(Text, AutoPlay=True, WavFile=None, VoiceName=None)\n

      \u53c2\u6570\uff1a - Text (str): \u8981\u8f6c\u6362\u4e3a\u8bed\u97f3\u7684\u6587\u672c - AutoPlay (bool): \u81ea\u52a8\u64ad\u653e\u751f\u6210\u7684\u97f3\u9891\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - WavFile (str, optional): \u4fdd\u5b58 WAV \u6587\u4ef6\u7684\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u4e34\u65f6\u6587\u4ef6 - VoiceName (str, optional): \u8981\u4f7f\u7528\u7684\u8bed\u97f3\u540d\u79f0\uff08\u4f8b\u5982 'en-US-JennyNeural'\u3001'zh-CN-XiaoxiaoNeural'\uff09

      \u8fd4\u56de\uff1a \u5305\u542b\u8bed\u97f3\u5408\u6210\u7ed3\u679c\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - text: \u8f93\u5165\u6587\u672c - url: \u4e0b\u8f7d\u97f3\u9891\u6587\u4ef6\u7684 URL - WavFile: \u4fdd\u5b58\u7684 WAV \u6587\u4ef6\u8def\u5f84\uff08\u5982\u679c\u672c\u5730\u4fdd\u5b58\uff09

      "},{"location":"qsl4a/special/pgptai/#_4","title":"\u914d\u7f6e","text":"

      API \u4f7f\u7528\u4ee5\u4e0b\u914d\u7f6e\u6587\u4ef6\u4e2d\u7684\u914d\u7f6e\uff1a/storage/emulated/0/Android/data/org.qpython.qpy/files/apigpt.conf\uff1a

      [speech]\nspeech_key = your_api_key\n

      \u9ed8\u8ba4\u8bed\u97f3\u8bbe\u7f6e\uff1a - \u82f1\u8bed\uff1aen-US-JennyNeural - \u4e2d\u6587\uff1azh-CN-XiaoxiaoNeural

      "},{"location":"qsl4a/special/pgptai/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5f55\u5236\u5e76\u8f6c\u5f55\nprint(\"Recording for 5 seconds...\")\ntext = droid.speechToText(RecordSecond=5, Language='en').result\nprint(f\"You said: {text}\")\n\n# \u8f6c\u5f55\u73b0\u6709\u6587\u4ef6\ntext = droid.speechToText(AmrFile=\"/sdcard/recording.amr\").result\nprint(f\"Transcription: {text}\")\n\n# \u6587\u672c\u8f6c\u8bed\u97f3\ndroid.textToSpeech(\"Hello, this is a test message.\", AutoPlay=True, Language='en')\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u8bed\u97f3\u5e76\u4fdd\u5b58\u5230\u6587\u4ef6\u7684\u6587\u672c\u8f6c\u8bed\u97f3\nresult = droid.textToSpeech(\n    \"Welcome to QPython!\",\n    AutoPlay=False,\n    WavFile=\"/sdcard/welcome.wav\",\n    VoiceName=\"en-US-JennyNeural\"\n).result\nprint(f\"Audio saved to: {result.get('WavFile')}\")\n
      "},{"location":"qsl4a/special/pgptai/#_6","title":"\u7c7b\u4f7f\u7528","text":"
      from androidhelper.pgptai import pgptai\nimport androidhelper\n\ndroid = androidhelper.Android()\nai = pgptai(droid)\n\n# \u4f7f\u7528\u8bed\u97f3\u8bc6\u522b\ntext = ai.speechToText(RecordSecond=10)\n
      "},{"location":"qsl4a/storage/clipboard/","title":"\u526a\u8d34\u677f API","text":"

      \u590d\u5236\u548c\u7c98\u8d34\u6587\u672c\u5230\u7cfb\u7edf\u526a\u8d34\u677f\u3002

      "},{"location":"qsl4a/storage/clipboard/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/clipboard/#setclipboard","title":"setClipboard()","text":"

      \u590d\u5236\u6587\u672c\u5230\u526a\u8d34\u677f\u3002

      setClipboard(text)\n

      \u53c2\u6570\uff1a - text (str): \u8981\u590d\u5236\u7684\u6587\u672c

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/clipboard/#getclipboard","title":"getClipboard()","text":"

      \u4ece\u526a\u8d34\u677f\u83b7\u53d6\u6587\u672c\u3002

      getClipboard()\n

      \u8fd4\u56de\uff1a \u526a\u8d34\u677f\u6587\u672c

      "},{"location":"qsl4a/storage/clipboard/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u590d\u5236\u5230\u526a\u8d34\u677f\ndroid.setClipboard(\"Hello from QPython!\")\n\n# \u4ece\u526a\u8d34\u677f\u7c98\u8d34\ntext = droid.getClipboard().result\nprint(f\"Clipboard: {text}\")\n
      "},{"location":"qsl4a/storage/documentfile/","title":"DocumentFile API","text":"

      \u4f7f\u7528 SAF\uff08\u5b58\u50a8\u8bbf\u95ee\u6846\u67b6\uff09\u8fdb\u884c\u6587\u4ef6\u64cd\u4f5c\uff0c\u652f\u6301 Android 4.4+\u3002

      "},{"location":"qsl4a/storage/documentfile/#_1","title":"\u76ee\u5f55\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilemkdir","title":"documentFileMkdir()","text":"

      \u521b\u5efa\u76ee\u5f55\u3002

      documentFileMkdir(Dir)\n

      \u53c2\u6570\uff1a - Dir (str): \u76ee\u5f55\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/documentfile/#documentfilelistfiles","title":"documentFileListFiles()","text":"

      \u5217\u51fa\u76ee\u5f55\u4e2d\u7684\u6587\u4ef6\u3002

      documentFileListFiles(Folder)\n

      \u8fd4\u56de\uff1a \u6587\u4ef6\u5217\u8868

      "},{"location":"qsl4a/storage/documentfile/#_2","title":"\u6587\u4ef6\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileexists","title":"documentFileExists()","text":"

      \u68c0\u67e5\u6587\u4ef6\u6216\u76ee\u5f55\u662f\u5426\u5b58\u5728\u3002

      documentFileExists(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u6216\u76ee\u5f55\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u5b58\u5728\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/storage/documentfile/#documentfileisfile","title":"documentFileIsFile()","text":"

      \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u6587\u4ef6\u3002

      documentFileIsFile(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u662f\u6587\u4ef6\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u6587\u4ef6\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

      "},{"location":"qsl4a/storage/documentfile/#documentfileisdirectory","title":"documentFileIsDirectory()","text":"

      \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u76ee\u5f55\u3002

      documentFileIsDirectory(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u662f\u76ee\u5f55\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u76ee\u5f55\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

      "},{"location":"qsl4a/storage/documentfile/#documentfiledelete","title":"documentFileDelete()","text":"

      \u5220\u9664\u6587\u4ef6\u6216\u76ee\u5f55\u3002

      documentFileDelete(FileOrTree)\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/documentfile/#documentfilerenameto","title":"documentFileRenameTo()","text":"

      \u91cd\u547d\u540d\u6216\u79fb\u52a8\u6587\u4ef6\u3002

      documentFileRenameTo(Src, Dest)\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/documentfile/#documentfilecopy","title":"documentFileCopy()","text":"

      \u590d\u5236\u6587\u4ef6\u3002

      documentFileCopy(SrcFileOrTree, DestFileOrTree)\n
      "},{"location":"qsl4a/storage/documentfile/#_3","title":"\u6d41\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileinputstream","title":"documentFileInputStream()","text":"

      \u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9\u3002

      documentFileInputStream(srcFile, EncodingFormat=\"\", skip=None, length=None)\n

      \u53c2\u6570\uff1a - srcFile (str): \u6e90\u6587\u4ef6 - EncodingFormat (str): \"UTF-8\"\u3001\"GBK\"\u3001\"Base64\" \u6216\u7a7a\u5b57\u7b26\u4e32\u8868\u793a\u5b57\u8282 - skip (int): \u4ece\u5f00\u5934\u8df3\u8fc7\u7684\u5b57\u8282\u6570 - length (int): \u8bfb\u53d6\u957f\u5ea6

      \u8fd4\u56de\uff1a \u6587\u4ef6\u5185\u5bb9

      "},{"location":"qsl4a/storage/documentfile/#documentfileoutputstream","title":"documentFileOutputStream()","text":"

      \u5199\u5165\u6587\u4ef6\u5185\u5bb9\u3002

      documentFileOutputStream(destFile, src, EncodingFormat=\"\", append=None)\n

      \u53c2\u6570\uff1a - destFile (str): \u76ee\u6807\u6587\u4ef6 - src: \u8981\u5199\u5165\u7684\u6570\u636e - EncodingFormat (str): \u7f16\u7801\u683c\u5f0f - append (bool): \u8ffd\u52a0\u6a21\u5f0f

      "},{"location":"qsl4a/storage/documentfile/#_4","title":"\u6587\u4ef6\u4fe1\u606f","text":""},{"location":"qsl4a/storage/documentfile/#documentfilelength","title":"documentFileLength()","text":"

      \u83b7\u53d6\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\u3002

      documentFileLength(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

      "},{"location":"qsl4a/storage/documentfile/#documentfilelastmodified","title":"documentFileLastModified()","text":"

      \u83b7\u53d6\u6700\u540e\u4fee\u6539\u65f6\u95f4\u3002

      documentFileLastModified(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u65f6\u95f4\u6233\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

      "},{"location":"qsl4a/storage/documentfile/#documentfilegetstat","title":"documentFileGetStat()","text":"

      \u83b7\u53d6\u5168\u9762\u7684\u6587\u4ef6\u7edf\u8ba1\u4fe1\u606f\u3002

      documentFileGetStat(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5305\u542b\u957f\u5ea6\u3001\u6700\u540e\u4fee\u6539\u65f6\u95f4\u548c\u8bfb/\u5199\u6743\u9650\u7684\u5b57\u5178\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

      "},{"location":"qsl4a/storage/documentfile/#uri","title":"URI \u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilegeturi","title":"documentFileGetUri()","text":"

      \u4ece\u8def\u5f84\u83b7\u53d6 URI\u3002

      documentFileGetUri(path, isDirectory=None)\n
      "},{"location":"qsl4a/storage/documentfile/#documentfileshowopen","title":"documentFileShowOpen()","text":"

      \u663e\u793a\u6587\u4ef6\u9009\u62e9\u5668\u3002

      documentFileShowOpen()\n

      \u8fd4\u56de\uff1a \u9009\u62e9\u7684\u6587\u4ef6 URI

      "},{"location":"qsl4a/storage/documentfile/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u76ee\u5f55\ndroid.documentFileMkdir(\"/sdcard/MyFolder\")\n\n# \u5217\u51fa\u6587\u4ef6\nfiles = droid.documentFileListFiles(\"/sdcard\").result\nfor f in files:\n    print(f)\n\n# \u8bfb\u53d6\u6587\u4ef6\ncontent = droid.documentFileInputStream(\n    \"/sdcard/test.txt\",\n    EncodingFormat=\"UTF-8\"\n).result\nprint(content)\n\n# \u5199\u5165\u6587\u4ef6\ndroid.documentFileOutputStream(\n    \"/sdcard/output.txt\",\n    \"Hello World\",\n    EncodingFormat=\"UTF-8\"\n)\n
      "},{"location":"qsl4a/storage/preferences/","title":"\u504f\u597d\u8bbe\u7f6e API","text":"

      \u4f7f\u7528 Android SharedPreferences \u5b58\u50a8\u548c\u68c0\u7d22\u6570\u636e\u3002

      "},{"location":"qsl4a/storage/preferences/#_1","title":"\u504f\u597d\u8bbe\u7f6e\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/preferences/#prefgetvalue","title":"prefGetValue()","text":"

      \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u8bfb\u53d6\u503c\u3002

      prefGetValue(key, filename=None)\n

      \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c\uff08\u4efb\u610f\u7c7b\u578b\uff09

      "},{"location":"qsl4a/storage/preferences/#prefputvalue","title":"prefPutValue()","text":"

      \u5199\u5165\u503c\u5230\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u3002

      prefPutValue(key, value, filename=None)\n

      \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - value (object): \u8981\u5b58\u50a8\u7684\u503c - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      "},{"location":"qsl4a/storage/preferences/#prefgetall","title":"prefGetAll()","text":"

      \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\u503c\u3002

      prefGetAll(filename=None)\n

      \u53c2\u6570\uff1a - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      \u8fd4\u56de\uff1a \u6240\u6709\u504f\u597d\u7684\u6620\u5c04

      "},{"location":"qsl4a/storage/preferences/#prefremovevalue","title":"prefRemoveValue()","text":"

      \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u4e2d\u79fb\u9664\u503c\u3002

      prefRemoveValue(key, filename=None)\n

      \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      "},{"location":"qsl4a/storage/preferences/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b58\u50a8\u503c\ndroid.prefPutValue(\"username\", \"alice\")\ndroid.prefPutValue(\"score\", 100)\ndroid.prefPutValue(\"enabled\", True)\n\n# \u8bfb\u53d6\u7279\u5b9a\u503c\nusername = droid.prefGetValue(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\nall_prefs = droid.prefGetAll().result\nprint(f\"All prefs: {all_prefs}\")\n\n# \u79fb\u9664\u503c\ndroid.prefRemoveValue(\"score\")\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u6587\u4ef6\u540d\ndroid.prefPutValue(\"token\", \"abc123\", filename=\"auth.prefs\")\ntoken = droid.prefGetValue(\"token\", filename=\"auth.prefs\").result\n
      "},{"location":"qsl4a/system/activityresult/","title":"Activity Result API","text":"

      \u4e3a\u901a\u8fc7 startActivityForResult \u542f\u52a8\u7684\u811a\u672c\u8bbe\u7f6e activity \u7ed3\u679c\u3002

      "},{"location":"qsl4a/system/activityresult/#_1","title":"\u7ed3\u679c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/activityresult/#setresultboolean","title":"setResultBoolean()","text":"

      \u8bbe\u7f6e\u5e03\u5c14\u7ed3\u679c\u3002

      setResultBoolean(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (bool): \u5e03\u5c14\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultbyte","title":"setResultByte()","text":"

      \u8bbe\u7f6e\u5b57\u8282\u7ed3\u679c\u3002

      setResultByte(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u5b57\u8282\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultshort","title":"setResultShort()","text":"

      \u8bbe\u7f6e\u77ed\u6574\u6570\u7ed3\u679c\u3002

      setResultShort(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u77ed\u6574\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultchar","title":"setResultChar()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u7ed3\u679c\u3002

      setResultChar(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultinteger","title":"setResultInteger()","text":"

      \u8bbe\u7f6e\u6574\u6570\u7ed3\u679c\u3002

      setResultInteger(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u6574\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultlong","title":"setResultLong()","text":"

      \u8bbe\u7f6e\u957f\u6574\u6570\u7ed3\u679c\u3002

      setResultLong(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u957f\u6574\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultfloat","title":"setResultFloat()","text":"

      \u8bbe\u7f6e\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

      setResultFloat(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u6d6e\u70b9\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultdouble","title":"setResultDouble()","text":"

      \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

      setResultDouble(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultstring","title":"setResultString()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u4e32\u7ed3\u679c\u3002

      setResultString(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u4e32\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultbooleanarray","title":"setResultBooleanArray()","text":"

      \u8bbe\u7f6e\u5e03\u5c14\u6570\u7ec4\u7ed3\u679c\u3002

      setResultBooleanArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5e03\u5c14\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultbytearray","title":"setResultByteArray()","text":"

      \u8bbe\u7f6e\u5b57\u8282\u6570\u7ec4\u7ed3\u679c\u3002

      setResultByteArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u8282\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultshortarray","title":"setResultShortArray()","text":"

      \u8bbe\u7f6e\u77ed\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultShortArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u77ed\u6574\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultchararray","title":"setResultCharArray()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u6570\u7ec4\u7ed3\u679c\u3002

      setResultCharArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultintegerarray","title":"setResultIntegerArray()","text":"

      \u8bbe\u7f6e\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultIntegerArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6574\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultlongarray","title":"setResultLongArray()","text":"

      \u8bbe\u7f6e\u957f\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultLongArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u957f\u6574\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultfloatarray","title":"setResultFloatArray()","text":"

      \u8bbe\u7f6e\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultFloatArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6d6e\u70b9\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultdoublearray","title":"setResultDoubleArray()","text":"

      \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultDoubleArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultstringarray","title":"setResultStringArray()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u4e32\u6570\u7ec4\u7ed3\u679c\u3002

      setResultStringArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u4e32\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultserializable","title":"setResultSerializable()","text":"

      \u8bbe\u7f6e\u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u3002

      setResultSerializable(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue: \u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c activity \u540e\uff0c\u8bbe\u7f6e\u7ed3\u679c\n# \u793a\u4f8b\uff1a\u8fd4\u56de\u6210\u529f\u53ca\u6570\u636e\ndroid.setResultInteger(0, 200)  # RESULT_OK\ndroid.setResultString(0, \"Operation completed successfully\")\n\n# \u8fd4\u56de\u6570\u7ec4\u7ed3\u679c\ndroid.setResultIntegerArray(0, [1, 2, 3, 4, 5])\n
      "},{"location":"qsl4a/system/application/","title":"\u5e94\u7528\u7ba1\u7406","text":"

      \u7ba1\u7406\u5e94\u7528\u7a0b\u5e8f\u3001\u542f\u52a8\u5e94\u7528\u548c\u67e5\u8be2\u7cfb\u7edf\u4fe1\u606f\u3002

      "},{"location":"qsl4a/system/application/#_2","title":"\u5e94\u7528\u7a0b\u5e8f\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getapplicationinfo","title":"getApplicationInfo()","text":"

      \u83b7\u53d6\u5e94\u7528\u4fe1\u606f\u3002

      getApplicationInfo(packageName=None)\n

      \u53c2\u6570\uff1a - packageName (str): \u5305\u540d\uff08None = \u5f53\u524d\u5e94\u7528\uff09

      \u8fd4\u56de\uff1a \u5e94\u7528\u4fe1\u606f\u5b57\u5178

      "},{"location":"qsl4a/system/application/#getinstalledpackages","title":"getInstalledPackages()","text":"

      \u83b7\u53d6\u5df2\u5b89\u88c5\u5305\u5217\u8868\u3002

      getInstalledPackages(flag=4)\n

      \u53c2\u6570\uff1a - flag (int): \u5305\u6807\u5fd7\u8fc7\u6ee4\u5668\uff08\u9ed8\u8ba4\uff1a4\uff09

      \u8fd4\u56de\uff1a \u5df2\u5b89\u88c5\u5305\u5217\u8868

      "},{"location":"qsl4a/system/application/#getrunningpackages","title":"getRunningPackages()","text":"

      \u5217\u51fa\u6b63\u5728\u8fd0\u884c\u7684\u5305\u3002

      getRunningPackages()\n

      \u8fd4\u56de\uff1a \u5305\u540d\u5217\u8868

      "},{"location":"qsl4a/system/application/#getlaunchablepackages","title":"getLaunchablePackages()","text":"

      \u83b7\u53d6\u53ef\u542f\u52a8\u5305\u5217\u8868\u3002

      getLaunchablePackages(needClassName=False)\n

      \u53c2\u6570\uff1a - needClassName (bool): \u5305\u542b\u4e3b activity \u7c7b\u540d\uff08\u9ed8\u8ba4\uff1aFalse\uff09

      \u8fd4\u56de\uff1a \u53ef\u542f\u52a8\u5305\u540d\u5217\u8868\u6216\u5305\u542b\u7c7b\u540d\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#_3","title":"\u5e94\u7528\u63a7\u5236","text":""},{"location":"qsl4a/system/application/#launch","title":"launch()","text":"

      \u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u3002

      launch(classname=None, packagename=None, wait=True)\n

      \u53c2\u6570\uff1a - classname (str): \u4e3b activity \u7c7b\u540d - packagename (str): \u5305\u540d - wait (bool): \u7b49\u5f85\u542f\u52a8\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

      \u8fd4\u56de\uff1a \u542f\u52a8\u7ed3\u679c

      "},{"location":"qsl4a/system/application/#forcestoppackage","title":"forceStopPackage()","text":"

      \u5f3a\u5236\u505c\u6b62\u5e94\u7528\u7a0b\u5e8f\u3002

      forceStopPackage(packageName)\n

      \u53c2\u6570\uff1a - packageName (str): \u8981\u505c\u6b62\u7684\u5305\u540d

      "},{"location":"qsl4a/system/application/#_4","title":"\u7248\u672c\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getpackageversion","title":"getPackageVersion()","text":"

      \u83b7\u53d6\u5e94\u7528\u7248\u672c\u540d\u79f0\u3002

      getPackageVersion(packageName)\n

      \u8fd4\u56de\uff1a \u7248\u672c\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"3.2.1\"\uff09

      "},{"location":"qsl4a/system/application/#getpackageversioncode","title":"getPackageVersionCode()","text":"

      \u83b7\u53d6\u5e94\u7528\u7248\u672c\u4ee3\u7801\u3002

      getPackageVersionCode(packageName)\n

      \u8fd4\u56de\uff1a \u7248\u672c\u4ee3\u7801\u6574\u6570

      "},{"location":"qsl4a/system/application/#getconstants","title":"getConstants()","text":"

      \u83b7\u53d6\u7c7b\u5e38\u91cf\u3002

      getConstants(classname)\n

      \u53c2\u6570\uff1a - classname (str): \u5b8c\u6574\u7c7b\u540d

      \u8fd4\u56de\uff1a \u5e38\u91cf\u540d\u548c\u503c\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#_5","title":"\u7cfb\u7edf\u529f\u80fd","text":""},{"location":"qsl4a/system/application/#backgroundprotect","title":"backgroundProtect()","text":"

      \u542f\u7528\u6216\u7981\u7528\u5e94\u7528\u7684\u540e\u53f0\u4fdd\u62a4\u3002

      backgroundProtect(enabled=True)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\u4fdd\u62a4\uff0cFalse \u7981\u7528

      "},{"location":"qsl4a/system/application/#createscriptshortcut","title":"createScriptShortCut()","text":"

      \u4e3a\u811a\u672c\u521b\u5efa\u4e3b\u5c4f\u5e55\u5feb\u6377\u65b9\u5f0f\u3002

      createScriptShortCut(scriptPath, label=None, iconPath=None, scriptArg=None)\n

      \u53c2\u6570\uff1a - scriptPath (str): Python \u811a\u672c\u8def\u5f84 - label (str, optional): \u5feb\u6377\u65b9\u5f0f\u6807\u7b7e - iconPath (str, optional): \u56fe\u6807\u56fe\u50cf\u8def\u5f84 - scriptArg (str, optional): \u4f20\u9012\u7ed9\u811a\u672c\u7684\u53c2\u6570

      "},{"location":"qsl4a/system/application/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getandroidid","title":"getAndroidID()","text":"

      \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

      getAndroidID()\n

      \u8fd4\u56de\uff1a \u552f\u4e00\u7684 Android \u8bbe\u5907 ID \u5b57\u7b26\u4e32

      "},{"location":"qsl4a/system/application/#getsysinfo","title":"getSysInfo()","text":"

      \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\u3002

      getSysInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#getlocale","title":"getLocale()","text":"

      \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u3002

      getLocale()\n

      \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

      "},{"location":"qsl4a/system/application/#getharmonyosinformation","title":"getHarmonyOsInformation()","text":"

      \u5982\u679c\u5728 HarmonyOS \u4e0a\u8fd0\u884c\uff0c\u83b7\u53d6 HarmonyOS \u4fe1\u606f\u3002

      getHarmonyOsInformation()\n

      \u8fd4\u56de\uff1a HarmonyOS \u7248\u672c\u4fe1\u606f\u6216 None

      "},{"location":"qsl4a/system/application/#isexternalstoragemanager","title":"isExternalStorageManager()","text":"

      \u68c0\u67e5\u5e94\u7528\u662f\u5426\u6709\u5916\u90e8\u5b58\u50a8\u7ba1\u7406\u5668\u6743\u9650\u3002

      isExternalStorageManager()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6709\u6743\u9650\u5219\u4e3a True

      "},{"location":"qsl4a/system/application/#_7","title":"\u5185\u5b58\u548c\u663e\u793a","text":""},{"location":"qsl4a/system/application/#getmemoryinfo","title":"getMemoryInfo()","text":"

      \u83b7\u53d6\u5185\u5b58\u4fe1\u606f\u3002

      getMemoryInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#getscreeninfo","title":"getScreenInfo()","text":"

      \u83b7\u53d6\u5c4f\u5e55\u4fe1\u606f\u3002

      getScreenInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#_8","title":"\u6743\u9650","text":""},{"location":"qsl4a/system/application/#checkpermissions","title":"checkPermissions()","text":"

      \u68c0\u67e5\u5f53\u524d\u5e94\u7528\u6743\u9650\u3002

      checkPermissions()\n

      \u8fd4\u56de\uff1a \u6743\u9650\u53ca\u5176\u72b6\u6001\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#requestpermissions","title":"requestPermissions()","text":"

      \u5411\u7528\u6237\u8bf7\u6c42\u6743\u9650\u3002

      requestPermissions(permissions=None)\n

      \u53c2\u6570\uff1a - permissions (list, optional): \u8981\u8bf7\u6c42\u7684\u6743\u9650\u5217\u8868\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8bf7\u6c42\u6240\u6709\u9700\u8981\u7684\u6743\u9650\u3002

      \u8fd4\u56de\uff1a \u6743\u9650\u8bf7\u6c42\u7ed3\u679c

      "},{"location":"qsl4a/system/application/#_9","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/system/application/#showscreenlock","title":"showScreenLock()","text":"

      \u663e\u793a\u5c4f\u5e55\u9501\u5b9a\uff08PIN/\u56fe\u6848/\u5bc6\u7801\u8f93\u5165\uff09\u3002

      showScreenLock()\n
      "},{"location":"qsl4a/system/application/#_10","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\ninfo = droid.getSysInfo().result\nprint(f\"System: {info}\")\n\n# \u83b7\u53d6\u5e94\u7528\u7248\u672c\nversion = droid.getPackageVersion(\"org.qpython.qpy\").result\nprint(f\"QPython version: {version}\")\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u5e94\u7528\napps = droid.getInstalledPackages().result\nprint(f\"Installed apps: {len(apps)}\")\n\n# \u542f\u52a8\u5e94\u7528\ndroid.launch(packagename=\"com.android.settings\")\n\n# \u68c0\u67e5\u6743\u9650\nperms = droid.checkPermissions().result\nprint(f\"Permissions: {perms}\")\n\n# \u8bf7\u6c42\u5b58\u50a8\u6743\u9650\ndroid.requestPermissions([\"android.permission.READ_EXTERNAL_STORAGE\"])\n\n# \u521b\u5efa\u5feb\u6377\u65b9\u5f0f\ndroid.createScriptShortCut(\n    \"/sdcard/my_script.py\",\n    label=\"My Script\",\n    iconPath=\"/sdcard/icon.png\"\n)\n
      "},{"location":"qsl4a/system/battery/","title":"\u7535\u6c60 API","text":"

      \u76d1\u63a7\u8bbe\u5907\u7535\u6c60\u72b6\u6001\u548c\u5065\u5eb7\u72b6\u51b5\u3002

      "},{"location":"qsl4a/system/battery/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/battery/#readbatterydata","title":"readBatteryData()","text":"

      \u83b7\u53d6\u5b8c\u6574\u7684\u7535\u6c60\u4fe1\u606f\u3002

      readBatteryData()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7535\u6c60\u6570\u636e\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/battery/#batterystartmonitoring","title":"batteryStartMonitoring()","text":"

      \u5f00\u59cb\u7535\u6c60\u76d1\u63a7\u3002

      batteryStartMonitoring()\n
      "},{"location":"qsl4a/system/battery/#batterystopmonitoring","title":"batteryStopMonitoring()","text":"

      \u505c\u6b62\u7535\u6c60\u76d1\u63a7\u3002

      batteryStopMonitoring()\n
      "},{"location":"qsl4a/system/battery/#batterygetlevel","title":"batteryGetLevel()","text":"

      \u83b7\u53d6\u7535\u6c60\u767e\u5206\u6bd4\u3002

      batteryGetLevel()\n

      \u8fd4\u56de\uff1a \u6574\u6570\uff080-100\uff09

      "},{"location":"qsl4a/system/battery/#batterygetstatus","title":"batteryGetStatus()","text":"

      \u83b7\u53d6\u5145\u7535\u72b6\u6001\u3002

      batteryGetStatus()\n

      \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u5145\u7535\u4e2d - 3: \u653e\u7535\u4e2d - 4: \u672a\u5145\u7535 - 5: \u5df2\u5145\u6ee1

      "},{"location":"qsl4a/system/battery/#batterygetplugtype","title":"batteryGetPlugType()","text":"

      \u83b7\u53d6\u7535\u6e90\u7c7b\u578b\u3002

      batteryGetPlugType()\n

      \u8fd4\u56de\uff1a - -1: \u672a\u77e5 - 0: \u672a\u63d2\u7535 - 1: AC \u5145\u7535\u5668 - 2: USB \u7aef\u53e3

      "},{"location":"qsl4a/system/battery/#batterygethealth","title":"batteryGetHealth()","text":"

      \u83b7\u53d6\u7535\u6c60\u5065\u5eb7\u72b6\u51b5\u3002

      batteryGetHealth()\n

      \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u826f\u597d - 3: \u8fc7\u70ed - 4: \u635f\u574f - 5: \u8fc7\u538b - 6: \u672a\u6307\u5b9a\u7684\u6545\u969c

      "},{"location":"qsl4a/system/battery/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\nlevel = droid.batteryGetLevel().result\nprint(f\"Battery: {level}%\")\n
      "},{"location":"qsl4a/system/qpyinterface/","title":"QPython \u63a5\u53e3 API","text":"

      \u4ece\u5176\u4ed6\u5e94\u7528\u6267\u884c QPython \u811a\u672c\u548c\u7ba1\u7406\u5171\u4eab\u53d8\u91cf\u3002

      "},{"location":"qsl4a/system/qpyinterface/#_1","title":"\u811a\u672c\u6267\u884c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/qpyinterface/#executeqpy","title":"executeQPy()","text":"

      \u6267\u884c QPython \u811a\u672c\u3002

      executeQPy(path=\"\", arg=None)\n

      \u53c2\u6570\uff1a - path (str): \u811a\u672c\u6587\u4ef6\u8def\u5f84 - arg (str, optional): \u547d\u4ee4\u884c\u53c2\u6570

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#executeqpyassrv","title":"executeQPyAsSrv()","text":"

      \u4f5c\u4e3a\u670d\u52a1\u6267\u884c QPython \u811a\u672c\u3002

      executeQPyAsSrv(path=None)\n

      \u53c2\u6570\uff1a - path (str, optional): \u811a\u672c\u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#executeqpycode","title":"executeQPyCode()","text":"

      \u76f4\u63a5\u6267\u884c Python \u4ee3\u7801\u3002

      executeQPyCode(code=None)\n

      \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#executeqpycodeassrv","title":"executeQPyCodeAsSrv()","text":"

      \u4f5c\u4e3a\u670d\u52a1\u6267\u884c Python \u4ee3\u7801\u3002

      executeQPyCodeAsSrv(code=None)\n

      \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#_2","title":"\u5171\u4eab\u53d8\u91cf","text":"

      \u5171\u4eab\u53d8\u91cf\u5141\u8bb8 QPython \u4e0e\u5176\u4ed6\u5e94\u7528\u4e4b\u95f4\u8fdb\u884c\u901a\u4fe1\u3002

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableset","title":"sharedVariableSet()","text":"

      \u8bbe\u7f6e Java \u5171\u4eab\u53d8\u91cf\u3002

      sharedVariableSet(key, value)\n

      \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d - value (str): \u53d8\u91cf\u503c

      \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableget","title":"sharedVariableGet()","text":"

      \u83b7\u53d6 Java \u5171\u4eab\u53d8\u91cf\u3002

      sharedVariableGet(key)\n

      \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d

      \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableremove","title":"sharedVariableRemove()","text":"

      \u79fb\u9664 Java \u5171\u4eab\u53d8\u91cf\u3002

      sharedVariableRemove(key)\n

      \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u53d8\u91cf\u540d

      \u8fd4\u56de\uff1a \u88ab\u79fb\u9664\u7684\u503c

      "},{"location":"qsl4a/system/qpyinterface/#getlastlog","title":"getLastLog()","text":"

      \u83b7\u53d6 QPython \u7684\u6700\u540e\u65e5\u5fd7\u8f93\u51fa\u3002

      getLastLog()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u65e5\u5fd7\u5185\u5bb9

      "},{"location":"qsl4a/system/qpyinterface/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c\u811a\u672c\ndroid.executeQPy(\"/sdcard/my_script.py\", arg=\"test\")\n\n# \u76f4\u63a5\u6267\u884c\u4ee3\u7801\ncode = \"print('Hello from QPython!')\"\ndroid.executeQPyCode(code)\n\n# \u4f7f\u7528\u5171\u4eab\u53d8\u91cf\ndroid.sharedVariableSet(\"username\", \"alice\")\nusername = droid.sharedVariableGet(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u79fb\u9664\u53d8\u91cf\ndroid.sharedVariableRemove(\"username\")\n\n# \u83b7\u53d6\u6700\u8fd1\u65e5\u5fd7\nlog = droid.getLastLog().result\nprint(f\"Log: {log}\")\n
      "},{"location":"qsl4a/system/sensors/","title":"\u4f20\u611f\u5668 API","text":"

      \u8bbf\u95ee\u8bbe\u5907\u4f20\u611f\u5668\uff0c\u5305\u62ec\u52a0\u901f\u5ea6\u8ba1\u3001\u9640\u87ba\u4eea\u3001\u78c1\u529b\u8ba1\u7b49\u3002

      "},{"location":"qsl4a/system/sensors/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/sensors/#startsensingtimed","title":"startSensingTimed()","text":"

      \u5f00\u59cb\u4f20\u611f\u5668\u76d1\u63a7\u5e76\u8bbe\u7f6e\u65f6\u95f4\u95f4\u9694\u3002

      startSensingTimed(sensorNumber, delayTime)\n

      \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID\uff08\u901a\u5e38\u4e3a 1-3\uff09 - delayTime (int): \u8bfb\u53d6\u4e4b\u95f4\u7684\u5ef6\u8fdf\uff08\u6beb\u79d2\uff09

      "},{"location":"qsl4a/system/sensors/#startsensingthreshold","title":"startSensingThreshold()","text":"

      \u5f00\u59cb\u5e26\u9608\u503c\u89e6\u53d1\u7684\u4f20\u611f\u5668\u76d1\u63a7\u3002

      startSensingThreshold(sensorNumber, threshold, axis)\n

      \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID - threshold (float): \u89e6\u53d1\u9608\u503c - axis (int): \u8981\u76d1\u63a7\u7684\u8f74\uff080=X\uff0c1=Y\uff0c2=Z\uff09

      "},{"location":"qsl4a/system/sensors/#stopsensing","title":"stopSensing()","text":"

      \u505c\u6b62\u6240\u6709\u4f20\u611f\u5668\u76d1\u63a7\u3002

      stopSensing()\n
      "},{"location":"qsl4a/system/sensors/#readsensors","title":"readSensors()","text":"

      \u8bfb\u53d6\u5f53\u524d\u4f20\u611f\u5668\u6570\u636e\u3002

      readSensors()\n

      \u8fd4\u56de\uff1a \u4f20\u611f\u5668\u6570\u636e\u5b57\u5178

      "},{"location":"qsl4a/system/sensors/#sensorsreadaccelerometer","title":"sensorsReadAccelerometer()","text":"

      \u8bfb\u53d6\u52a0\u901f\u5ea6\u8ba1\u503c\u3002

      sensorsReadAccelerometer()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d m/s\u00b2

      "},{"location":"qsl4a/system/sensors/#sensorsreadgyroscope","title":"sensorsReadGyroscope()","text":"

      \u8bfb\u53d6\u9640\u87ba\u4eea\u503c\u3002

      sensorsReadGyroscope()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d rad/s

      "},{"location":"qsl4a/system/sensors/#sensorsreadmagnetometer","title":"sensorsReadMagnetometer()","text":"

      \u8bfb\u53d6\u78c1\u573a\u503c\u3002

      sensorsReadMagnetometer()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d \u03bcT

      "},{"location":"qsl4a/system/sensors/#sensorsreadorientation","title":"sensorsReadOrientation()","text":"

      \u8bfb\u53d6\u8bbe\u5907\u65b9\u5411\u3002

      sensorsReadOrientation()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [azimuth, pitch, roll]\uff0c\u5355\u4f4d\u5ea6

      "},{"location":"qsl4a/system/sensors/#sensorsgetlight","title":"sensorsGetLight()","text":"

      \u8bfb\u53d6\u5149\u4f20\u611f\u5668\u503c\u3002

      sensorsGetLight()\n

      \u8fd4\u56de\uff1a \u5149\u7ea7\u522b\uff08lux\uff09

      "},{"location":"qsl4a/system/sensors/#sensorsgetstepcounter","title":"sensorsGetStepCounter()","text":"

      \u8bfb\u53d6\u6b65\u8ba1\u6570\u5668\u3002

      sensorsGetStepCounter()\n

      \u8fd4\u56de\uff1a \u6b65\u6570

      "},{"location":"qsl4a/system/sensors/#sensorsgetaccuracy","title":"sensorsGetAccuracy()","text":"

      \u83b7\u53d6\u5f53\u524d\u4f20\u611f\u5668\u7cbe\u5ea6\u3002

      sensorsGetAccuracy()\n

      \u8fd4\u56de\uff1a \u7cbe\u5ea6\u503c\uff080-3\uff1aUNRELIABLE\u3001ACCURACY_LOW\u3001ACCURACY_MEDIUM\u3001ACCURACY_HIGH\uff09

      "},{"location":"qsl4a/system/sensors/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u8bfb\u53d6\u4f20\u611f\u5668 10 \u6b21\nfor i in range(10):\n    accel = droid.sensorsReadAccelerometer().result\n    print(f\"Accel: X={accel[0]:.2f}, Y={accel[1]:.2f}, Z={accel[2]:.2f}\")\n    time.sleep(0.5)\n\ndroid.stopSensing()\n
      "},{"location":"qsl4a/system/settings/","title":"\u8bbe\u7f6e API","text":"

      \u63a7\u5236\u7cfb\u7edf\u8bbe\u7f6e\uff0c\u5305\u62ec\u5c4f\u5e55\u3001\u58f0\u97f3\u548c\u7f51\u7edc\u8bbe\u7f6e\u3002

      "},{"location":"qsl4a/system/settings/#_1","title":"\u5c4f\u5e55\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#setscreentimeout","title":"setScreenTimeout()","text":"

      \u8bbe\u7f6e\u5c4f\u5e55\u8d85\u65f6\u503c\u3002

      setScreenTimeout(value)\n

      \u53c2\u6570\uff1a - value (int): \u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

      \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u8d85\u65f6\u503c

      "},{"location":"qsl4a/system/settings/#getscreentimeout","title":"getScreenTimeout()","text":"

      \u83b7\u53d6\u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u3002

      getScreenTimeout()\n

      \u8fd4\u56de\uff1a \u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

      "},{"location":"qsl4a/system/settings/#getscreenbrightness","title":"getScreenBrightness()","text":"

      \u83b7\u53d6\u5c4f\u5e55\u4eae\u5ea6\u503c\u3002

      getScreenBrightness()\n

      \u8fd4\u56de\uff1a \u4eae\u5ea6\u503c\uff080-255\uff09

      "},{"location":"qsl4a/system/settings/#setscreenbrightness","title":"setScreenBrightness()","text":"

      \u8bbe\u7f6e\u5c4f\u5e55\u4eae\u5ea6\u3002

      setScreenBrightness(value=None)\n

      \u53c2\u6570\uff1a - value (int, optional): \u4eae\u5ea6\u503c\uff080-255\uff09\uff0c\u6216 None \u8868\u793a\u81ea\u52a8

      \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u4eae\u5ea6\u503c

      "},{"location":"qsl4a/system/settings/#checkscreenon","title":"checkScreenOn()","text":"

      \u68c0\u67e5\u5c4f\u5e55\u662f\u5426\u4eae\u7740\u3002

      checkScreenOn()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u5c4f\u5e55\u4eae\u7740\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/system/settings/#_2","title":"\u98de\u884c\u6a21\u5f0f","text":""},{"location":"qsl4a/system/settings/#checkairplanemode","title":"checkAirplaneMode()","text":"

      \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\u662f\u5426\u542f\u7528\u3002

      checkAirplaneMode()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u98de\u884c\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

      "},{"location":"qsl4a/system/settings/#_3","title":"\u94c3\u58f0\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#checkringersilentmode","title":"checkRingerSilentMode()","text":"

      \u68c0\u67e5\u94c3\u58f0\u662f\u5426\u5904\u4e8e\u9759\u97f3\u6a21\u5f0f\u3002

      checkRingerSilentMode()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u9759\u97f3\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

      "},{"location":"qsl4a/system/settings/#toggleringersilentmode","title":"toggleRingerSilentMode()","text":"

      \u5207\u6362\u94c3\u58f0\u9759\u97f3\u6a21\u5f0f\u3002

      toggleRingerSilentMode(enabled=None)\n

      \u53c2\u6570\uff1a - enabled (bool, optional): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

      \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

      "},{"location":"qsl4a/system/settings/#togglevibratemode","title":"toggleVibrateMode()","text":"

      \u5207\u6362\u632f\u52a8\u6a21\u5f0f\u3002

      toggleVibrateMode(enabled=None, ringer=None)\n

      \u53c2\u6570\uff1a - enabled (bool, optional): \u5207\u6362\u632f\u52a8\u5f00/\u5173 - ringer (bool, optional): \u5e94\u7528\u4e8e\u94c3\u58f0\u6a21\u5f0f

      \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

      "},{"location":"qsl4a/system/settings/#getvibratemode","title":"getVibrateMode()","text":"

      \u83b7\u53d6\u632f\u52a8\u6a21\u5f0f\u8bbe\u7f6e\u3002

      getVibrateMode(ringer=None)\n

      \u53c2\u6570\uff1a - ringer (bool, optional): \u68c0\u67e5\u94c3\u58f0\u632f\u52a8\u6a21\u5f0f

      \u8fd4\u56de\uff1a \u5982\u679c\u632f\u52a8\u5df2\u542f\u7528\u5219\u4e3a True

      "},{"location":"qsl4a/system/settings/#_4","title":"\u97f3\u91cf\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#getringervolume","title":"getRingerVolume()","text":"

      \u83b7\u53d6\u5f53\u524d\u94c3\u58f0\u97f3\u91cf\u3002

      getRingerVolume()\n

      \u8fd4\u56de\uff1a \u94c3\u58f0\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-7\uff09

      "},{"location":"qsl4a/system/settings/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

      getMaxRingerVolume()\n

      \u8fd4\u56de\uff1a \u6700\u5927\u94c3\u58f0\u97f3\u91cf

      "},{"location":"qsl4a/system/settings/#setringervolume","title":"setRingerVolume()","text":"

      \u8bbe\u7f6e\u94c3\u58f0\u97f3\u91cf\u3002

      setRingerVolume(volume)\n

      \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

      "},{"location":"qsl4a/system/settings/#getmediavolume","title":"getMediaVolume()","text":"

      \u83b7\u53d6\u5f53\u524d\u5a92\u4f53\u97f3\u91cf\u3002

      getMediaVolume()\n

      \u8fd4\u56de\uff1a \u5a92\u4f53\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-15\uff09

      "},{"location":"qsl4a/system/settings/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

      getMaxMediaVolume()\n

      \u8fd4\u56de\uff1a \u6700\u5927\u5a92\u4f53\u97f3\u91cf

      "},{"location":"qsl4a/system/settings/#setmediavolume","title":"setMediaVolume()","text":"

      \u8bbe\u7f6e\u5a92\u4f53\u97f3\u91cf\u3002

      setMediaVolume(volume)\n

      \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

      "},{"location":"qsl4a/system/settings/#_5","title":"\u7cfb\u7edf\u4fe1\u606f","text":""},{"location":"qsl4a/system/settings/#elapsedrealtimenanos","title":"elapsedRealtimeNanos()","text":"

      \u83b7\u53d6\u81ea\u7cfb\u7edf\u542f\u52a8\u4ee5\u6765\u7684\u7eb3\u79d2\u6570\u3002

      elapsedRealtimeNanos()\n

      \u8fd4\u56de\uff1a \u7eb3\u79d2\u6570\uff08\u53ef\u7528\u4e8e\u8ba1\u65f6\uff09

      "},{"location":"qsl4a/system/settings/#gettrafficstats","title":"getTrafficStats()","text":"

      \u83b7\u53d6\u7f51\u7edc\u6d41\u91cf\u7edf\u8ba1\u3002

      getTrafficStats(flags=7)\n

      \u53c2\u6570\uff1a - flags (int): \u8981\u68c0\u7d22\u7684\u7edf\u8ba1\uff08\u9ed8\u8ba4\uff1a7 = \u5168\u90e8\uff09

      \u8fd4\u56de\uff1a \u5305\u542b\u53d1\u9001/\u63a5\u6536\u5b57\u8282\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/settings/#getapptxbytes","title":"getAppTxBytes()","text":"

      \u83b7\u53d6 QPython \u5e94\u7528\u7684\u53d1\u9001\u5b57\u8282\u3002

      getAppTxBytes(packageName)\n

      \u53c2\u6570\uff1a - packageName (str): \u5305\u540d

      \u8fd4\u56de\uff1a \u5305\u542b tx/rx \u5b57\u8282\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/settings/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5c4f\u5e55\u8bbe\u7f6e\ncurrent_timeout = droid.getScreenTimeout().result\nprint(f\"Current timeout: {current_timeout}s\")\ndroid.setScreenTimeout(30)\n\n# \u68c0\u67e5\u5c4f\u5e55\nif droid.checkScreenOn().result:\n    print(\"Screen is on\")\n\n# \u97f3\u91cf\u63a7\u5236\nmedia_vol = droid.getMediaVolume().result\nprint(f\"Media volume: {media_vol}\")\ndroid.setMediaVolume(10)\n\n# \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\nif droid.checkAirplaneMode().result:\n    print(\"Airplane mode is on\")\n
      "},{"location":"qsl4a/system/sysinfo/","title":"\u7cfb\u7edf\u4fe1\u606f","text":"

      \u68c0\u7d22\u8bbe\u5907\u548c\u7cfb\u7edf\u4fe1\u606f\u3002

      "},{"location":"qsl4a/system/sysinfo/#_2","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/sysinfo/#getandroidid","title":"getAndroidID()","text":"

      \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

      getAndroidID()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

      "},{"location":"qsl4a/system/sysinfo/#getsysinfo","title":"getSysInfo()","text":"

      \u83b7\u53d6\u7efc\u5408\u7cfb\u7edf\u4fe1\u606f\u3002

      getSysInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/sysinfo/#getlocale","title":"getLocale()","text":"

      \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u8bbe\u7f6e\u3002

      getLocale()\n

      \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

      "},{"location":"qsl4a/system/sysinfo/#_3","title":"\u5185\u5b58","text":""},{"location":"qsl4a/system/sysinfo/#getmemoryinfo","title":"getMemoryInfo()","text":"

      \u83b7\u53d6 RAM \u4fe1\u606f\u3002

      getMemoryInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/sysinfo/#_4","title":"\u663e\u793a","text":""},{"location":"qsl4a/system/sysinfo/#getscreeninfo","title":"getScreenInfo()","text":"

      \u83b7\u53d6\u663e\u793a\u4fe1\u606f\u3002

      getScreenInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/sysinfo/#_5","title":"\u6807\u8bc6\u7b26","text":""},{"location":"qsl4a/system/sysinfo/#getimei","title":"getImei()","text":"

      \u83b7\u53d6\u8bbe\u5907 IMEI\u3002

      getImei(slotIndex=None)\n
      "},{"location":"qsl4a/system/sysinfo/#getmeid","title":"getMeid()","text":"

      \u83b7\u53d6\u8bbe\u5907 MEID\u3002

      getMeid(slotIndex=None)\n
      "},{"location":"qsl4a/system/sysinfo/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u8bbe\u5907 ID\nandroid_id = droid.getAndroidID().result\nprint(f\"Android ID: {android_id}\")\n\n# \u5c4f\u5e55\u4fe1\u606f\nscreen = droid.getScreenInfo().result\nprint(f\"Screen: {screen['width']}x{screen['height']}\")\n\n# \u5185\u5b58\nmemory = droid.getMemoryInfo().result\nprint(f\"Memory: {memory}\")\n
      "},{"location":"qsl4a/system/wakelock/","title":"WakeLock API","text":"

      \u63a7\u5236\u8bbe\u5907\u5524\u9192\u9501\u4ee5\u4fdd\u6301 CPU \u6216\u5c4f\u5e55\u5f00\u542f\u3002

      "},{"location":"qsl4a/system/wakelock/#wake-lock","title":"Wake Lock \u7c7b\u578b","text":"

      QSL4A \u63d0\u4f9b\u4e0d\u540c\u7c7b\u578b\u7684\u5524\u9192\u9501\uff1a

      \u7c7b\u578b \u63cf\u8ff0 Full CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae Partial \u4ec5 CPU \u5f00\u542f Bright CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae Dim CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697"},{"location":"qsl4a/system/wakelock/#wake-lock_1","title":"Wake Lock \u65b9\u6cd5","text":""},{"location":"qsl4a/system/wakelock/#wakelockacquirefull","title":"wakeLockAcquireFull()","text":"

      \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae\uff09\u3002

      wakeLockAcquireFull()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquirepartial","title":"wakeLockAcquirePartial()","text":"

      \u83b7\u53d6\u90e8\u5206\u5524\u9192\u9501\uff08\u4ec5 CPU \u5f00\u542f\uff09\u3002

      wakeLockAcquirePartial()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquirebright","title":"wakeLockAcquireBright()","text":"

      \u83b7\u53d6\u660e\u4eae\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff09\u3002

      wakeLockAcquireBright()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquiredim","title":"wakeLockAcquireDim()","text":"

      \u83b7\u53d6\u6697\u6de1\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697\uff09\u3002

      wakeLockAcquireDim()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockrelease","title":"wakeLockRelease()","text":"

      \u91ca\u653e\u5524\u9192\u9501\u3002

      wakeLockRelease()\n
      "},{"location":"qsl4a/system/wakelock/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\ndroid.wakeLockAcquireFull()\n\n# \u5728\u4fdd\u6301\u5c4f\u5e55\u5f00\u542f\u65f6\u6267\u884c\u91cd\u8981\u5de5\u4f5c\nprint(\"Screen will stay on\")\ntime.sleep(10)\n\n# \u5b8c\u6210\u540e\u91ca\u653e\ndroid.wakeLockRelease()\n\n# \u6216\u4f7f\u7528\u90e8\u5206\u9501\u8fdb\u884c\u540e\u53f0\u4efb\u52a1\ndroid.wakeLockAcquirePartial()\n# \u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\uff0cCPU \u4ecd\u4fdd\u6301\u5f00\u542f\ntime.sleep(30)\ndroid.wakeLockRelease()\n

      \u6ce8\u610f\uff1a \u8bb0\u4f4f\u5728\u4e0d\u9700\u8981\u65f6\u91ca\u653e\u5524\u9192\u9501\u4ee5\u8282\u7701\u7535\u6c60\u3002

      "},{"location":"qsl4a/ui/accessibility/","title":"\u65e0\u969c\u788d\u670d\u52a1","text":"

      \u65e0\u969c\u788d\u670d\u52a1\u5141\u8bb8\u81ea\u52a8\u5316 UI \u4ea4\u4e92\uff0c\u5982\u70b9\u51fb\u3001\u6ed1\u52a8\u548c\u7cfb\u7edf\u64cd\u4f5c\u3002

      "},{"location":"qsl4a/ui/accessibility/#_2","title":"\u670d\u52a1\u63a7\u5236","text":""},{"location":"qsl4a/ui/accessibility/#accessibilitystartservice","title":"accessibilityStartService()","text":"

      \u542f\u52a8\u65e0\u969c\u788d\u670d\u52a1\u3002

      accessibilityStartService()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/ui/accessibility/#accessibilityserviceenabled","title":"accessibilityServiceEnabled()","text":"

      \u68c0\u67e5\u65e0\u969c\u788d\u670d\u52a1\u662f\u5426\u5df2\u542f\u7528\u3002

      accessibilityServiceEnabled()\n

      \u8fd4\u56de\uff1a True \u6216 False

      "},{"location":"qsl4a/ui/accessibility/#_3","title":"\u5c4f\u5e55\u4ea4\u4e92","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityclick","title":"accessibilityClick()","text":"

      \u5728\u5c4f\u5e55\u5750\u6807\u5904\u70b9\u51fb\u3002

      accessibilityClick(x=0, y=0, t=50)\n

      \u53c2\u6570\uff1a - x (int/float): X \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - y (int/float): Y \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - t (int): \u6309\u4f4f\u65f6\u957f\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a50\uff09

      "},{"location":"qsl4a/ui/accessibility/#accessibilityslide","title":"accessibilitySlide()","text":"

      \u591a\u70b9\u6ed1\u52a8\u624b\u52bf\u3002

      accessibilitySlide(XnYn=None, t=None)\n

      \u53c2\u6570\uff1a - XnYn (list): \u5750\u6807 [X1, Y1, X2, Y2, ... Xn, Yn] - t (int): \u6ed1\u52a8\u65f6\u957f\uff08\u9ed8\u8ba4\uff1a50*n \u6beb\u79d2\uff09

      "},{"location":"qsl4a/ui/accessibility/#_4","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityaction","title":"accessibilityAction()","text":"

      \u6309\u4ee3\u7801\u6267\u884c\u7cfb\u7edf\u64cd\u4f5c\u3002

      accessibilityAction(actionCode)\n

      \u64cd\u4f5c\u4ee3\u7801\uff1a | \u4ee3\u7801 | \u5e38\u91cf | \u63cf\u8ff0 | |------|----------|-------------| | 1 | BACK | \u8fd4\u56de\u6309\u94ae | | 2 | HOME | \u4e3b\u5c4f\u5e55\u6309\u94ae | | 3 | RECENTS | \u6700\u8fd1\u5e94\u7528 | | 4 | NOTIFICATIONS | \u6253\u5f00\u901a\u77e5 | | 5 | QUICK_SETTINGS | \u6253\u5f00\u5feb\u901f\u8bbe\u7f6e | | 6 | POWER_DIALOG | \u7535\u6e90\u83dc\u5355 | | 7 | TOGGLE_SPLIT_SCREEN | \u5206\u5c4f | | 8 | LOCK_SCREEN | \u9501\u5c4f | | 9 | TAKE_SCREENSHOT | \u622a\u56fe | | 10 | KEYCODE_HEADSETHOOK | \u8033\u673a\u6302\u94a9 | | 11-14 | ACCESSIBILITY_ | \u65e0\u969c\u788d\u6309\u94ae | | 15 | DISMISS_NOTIFICATION_SHADE | \u5173\u95ed\u901a\u77e5\u680f | | 16-20 | DPAD_ | \u65b9\u5411\u952e | | 21 | MENU | \u83dc\u5355\u6309\u94ae | | 22 | MEDIA_PLAY_PAUSE | \u64ad\u653e/\u6682\u505c\u5a92\u4f53 |

      "},{"location":"qsl4a/ui/accessibility/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/accessibility/#_6","title":"\u70b9\u51fb\u5c4f\u5e55\u4e2d\u5fc3","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u670d\u52a1\nif not droid.accessibilityServiceEnabled().result:\n    droid.accessibilityStartService()\n\n# \u70b9\u51fb\u4e2d\u5fc3\uff080,0 = \u4e2d\u5fc3\uff09\ndroid.accessibilityClick(0, 0, t=100)\n
      "},{"location":"qsl4a/ui/accessibility/#_7","title":"\u6ed1\u52a8\u624b\u52bf","text":"
      # \u4ece\u4e0b\u5f80\u4e0a\u6ed1\u52a8\uff08\u5411\u4e0a\u6eda\u52a8\uff09\ndroid.accessibilitySlide([0, 1.5, 0, -1.5], t=300)\n
      "},{"location":"qsl4a/ui/accessibility/#_8","title":"\u7cfb\u7edf\u5bfc\u822a","text":"
      # \u6309\u4e3b\u5c4f\u5e55\ndroid.accessibilityAction(2)\n\n# \u6309\u8fd4\u56de\ndroid.accessibilityAction(1)\n\n# \u6253\u5f00\u901a\u77e5\ndroid.accessibilityAction(4)\n
      "},{"location":"qsl4a/ui/accessibility/#_9","title":"\u70b9\u51fb\u7279\u5b9a\u4f4d\u7f6e","text":"
      # \u70b9\u51fb\u5c4f\u5e55\u5750\u6807 (500, 800)\ndroid.accessibilityClick(500, 800)\n\n# \u70b9\u51fb\u76f8\u5bf9\u4f4d\u7f6e\uff08\u6c34\u5e73\u5c45\u4e2d\uff0c\u5782\u76f4 3/4 \u5904\uff09\ndroid.accessibilityClick(0, 1.5)\n
      "},{"location":"qsl4a/ui/dialogs/","title":"\u5bf9\u8bdd\u6846\u7cfb\u7edf","text":"

      QSL4A \u63d0\u4f9b\u5168\u9762\u7684\u5bf9\u8bdd\u6846\u652f\u6301\uff0c\u7528\u4e8e\u7528\u6237\u4ea4\u4e92\uff0c\u5305\u62ec\u8b66\u62a5\u3001\u8f93\u5165\u5bf9\u8bdd\u6846\u3001\u9009\u62e9\u5bf9\u8bdd\u6846\u548c\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

      "},{"location":"qsl4a/ui/dialogs/#_2","title":"\u8b66\u62a5\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowalert","title":"dialogShowAlert()","text":"

      \u663e\u793a\u7b80\u5355\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

      dialogShowAlert(title=\"Alert\", message=\"The message of the alert.\",\n                positiveButtonText=\"OK\", negativeButtonText=None,\n                neutralButtonText=None, messageIsHtml=False)\n

      \u53c2\u6570\uff1a - title (str): \u5bf9\u8bdd\u6846\u6807\u9898 - message (str): \u6d88\u606f\u6587\u672c - positiveButtonText (str): \u80af\u5b9a\u6309\u94ae\u6807\u7b7e - negativeButtonText (str, optional): \u5426\u5b9a\u6309\u94ae\u6807\u7b7e - neutralButtonText (str, optional): \u4e2d\u6027\u6309\u94ae\u6807\u7b7e - messageIsHtml (bool): \u5c06\u6d88\u606f\u89e3\u6790\u4e3a HTML

      \u8fd4\u56de\uff1a \u5305\u542b\u70b9\u51fb\u6309\u94ae\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#dialogshowsimplechoice","title":"dialogShowSimpleChoice()","text":"

      \u663e\u793a\u5e26\u6709\u9879\u76ee\u7684\u7b80\u5355\u9009\u62e9\u5bf9\u8bdd\u6846\u3002

      dialogShowSimpleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

      \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868

      \u8fd4\u56de\uff1a \u5305\u542b\u9009\u4e2d\u9879\u76ee\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#_3","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialoggetinput","title":"dialogGetInput()","text":"

      \u83b7\u53d6\u7528\u6237\u6587\u672c\u8f93\u5165\u3002

      dialogGetInput(title=\"Value\", message=\"Please enter value:\",\n               defaultText=None, messageIsHtml=False)\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7528\u6237\u8f93\u5165\u6587\u672c\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#dialoggetpassword","title":"dialogGetPassword()","text":"

      \u83b7\u53d6\u5bc6\u7801\u8f93\u5165\u3002

      dialogGetPassword(title=\"Password\", message=\"Please enter password:\")\n

      \u8fd4\u56de\uff1a \u5305\u542b\u8f93\u5165\u5bc6\u7801\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#dialogcreateinput","title":"dialogCreateInput()","text":"

      \u521b\u5efa\u81ea\u5b9a\u4e49\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

      dialogCreateInput(title=\"Value\", message=\"Please enter value:\",\n                  defaultText=None, inputType=None)\n

      \u53c2\u6570\uff1a - inputType (str): \u8f93\u5165\u7c7b\u578b\uff08\u4f8b\u5982 \"text\"\u3001\"number\"\u3001\"textPassword\"\uff09

      "},{"location":"qsl4a/ui/dialogs/#dialogcreatepassword","title":"dialogCreatePassword()","text":"

      \u521b\u5efa\u5bc6\u7801\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

      dialogCreatePassword(title=\"Password\", message=\"Please enter password:\")\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreateseekbar","title":"dialogCreateSeekBar()","text":"

      \u521b\u5efa\u6ed1\u5757/\u8fdb\u5ea6\u6761\u5bf9\u8bdd\u6846\u3002

      dialogCreateSeekBar(starting_value=50, maximum_value=100, title=\"\", message=\"\")\n

      \u53c2\u6570\uff1a - starting_value (int): \u521d\u59cb\u503c - maximum_value (int): \u6700\u5927\u503c

      "},{"location":"qsl4a/ui/dialogs/#_4","title":"\u9009\u62e9\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowsinglechoice","title":"dialogShowSingleChoice()","text":"

      \u663e\u793a\u5355\u9009\uff08\u5355\u9009\u6309\u94ae\uff09\u5bf9\u8bdd\u6846\u3002

      dialogShowSingleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, selected=-1, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

      \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (int): \u9ed8\u8ba4\u9009\u4e2d\u7d22\u5f15

      "},{"location":"qsl4a/ui/dialogs/#dialogshowmultichoice","title":"dialogShowMultiChoice()","text":"

      \u663e\u793a\u591a\u9009\uff08\u590d\u9009\u6846\uff09\u5bf9\u8bdd\u6846\u3002

      dialogShowMultiChoice(title=\"Alert\", message=\"The message of the alert.\",\n                      items=None, selected=None, positiveButtonText=\"OK\",\n                      negativeButtonText=None, neutralButtonText=None,\n                      messageIsHtml=False)\n

      \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (list): \u521d\u59cb\u9009\u4e2d\u7d22\u5f15\u5217\u8868

      "},{"location":"qsl4a/ui/dialogs/#dialogsetsinglechoiceitems","title":"dialogSetSingleChoiceItems()","text":"

      \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u5355\u9009\u9879\u76ee\u3002

      dialogSetSingleChoiceItems(items, selected=-1)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmultichoiceitems","title":"dialogSetMultiChoiceItems()","text":"

      \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u591a\u9009\u9879\u76ee\u3002

      dialogSetMultiChoiceItems(items, selected=None)\n
      "},{"location":"qsl4a/ui/dialogs/#_5","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatespinnerprogress","title":"dialogCreateSpinnerProgress()","text":"

      \u521b\u5efa\u4e0d\u786e\u5b9a\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

      dialogCreateSpinnerProgress(title=None, message=None, maximum_progress=100)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreatehorizontalprogress","title":"dialogCreateHorizontalProgress()","text":"

      \u521b\u5efa\u6c34\u5e73\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

      dialogCreateHorizontalProgress(title=None, message=None, maximum_progress=100)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetcurrentprogress","title":"dialogSetCurrentProgress()","text":"

      \u66f4\u65b0\u8fdb\u5ea6\u503c\u3002

      dialogSetCurrentProgress(current)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmaxprogress","title":"dialogSetMaxProgress()","text":"

      \u8bbe\u7f6e\u6700\u5927\u8fdb\u5ea6\u503c\u3002

      dialogSetMaxProgress(max)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetprogressmessage","title":"dialogSetProgressMessage()","text":"

      \u66f4\u65b0\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u6d88\u606f\u3002

      dialogSetProgressMessage(message)\n
      "},{"location":"qsl4a/ui/dialogs/#_6","title":"\u9009\u62e9\u5668\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatedatepicker","title":"dialogCreateDatePicker()","text":"

      \u521b\u5efa\u65e5\u671f\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

      dialogCreateDatePicker(year=1970, month=1, day=1)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreatetimepicker","title":"dialogCreateTimePicker()","text":"

      \u521b\u5efa\u65f6\u95f4\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

      dialogCreateTimePicker(hour=0, minute=0, is24hour=False)\n
      "},{"location":"qsl4a/ui/dialogs/#_7","title":"\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u521b\u5efa","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatealert","title":"dialogCreateAlert()","text":"

      \u521b\u5efa\u81ea\u5b9a\u4e49\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

      dialogCreateAlert(title=None, message=None)\n

      \u521b\u5efa\u4e00\u4e2a\u7a7a\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002\u53ef\u4e0e\u5176\u4ed6 dialogSet* \u51fd\u6570\u4e00\u8d77\u4f7f\u7528\u6765\u81ea\u5b9a\u4e49\u3002

      "},{"location":"qsl4a/ui/dialogs/#dialogsetitems","title":"dialogSetItems()","text":"

      \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u7b80\u5355\u5217\u8868\u9879\u76ee\u3002

      dialogSetItems(items)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetpositivebuttontext","title":"dialogSetPositiveButtonText()","text":"

      \u8bbe\u7f6e\u80af\u5b9a\u6309\u94ae\u6587\u672c\u3002

      dialogSetPositiveButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetnegativebuttontext","title":"dialogSetNegativeButtonText()","text":"

      \u8bbe\u7f6e\u5426\u5b9a\u6309\u94ae\u6587\u672c\u3002

      dialogSetNegativeButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetneutralbuttontext","title":"dialogSetNeutralButtonText()","text":"

      \u8bbe\u7f6e\u4e2d\u6027\u6309\u94ae\u6587\u672c\u3002

      dialogSetNeutralButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmessageishtml","title":"dialogSetMessageIsHtml()","text":"

      \u8bbe\u7f6e\u6d88\u606f\u662f\u5426\u5e94\u89e3\u6790\u4e3a HTML\u3002

      dialogSetMessageIsHtml(messageIsHtml=True)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogshow","title":"dialogShow()","text":"

      \u663e\u793a\u521b\u5efa\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u3002

      dialogShow()\n
      "},{"location":"qsl4a/ui/dialogs/#_8","title":"\u5bf9\u8bdd\u6846\u63a7\u5236","text":""},{"location":"qsl4a/ui/dialogs/#dialogdismiss","title":"dialogDismiss()","text":"

      \u5173\u95ed\u5f53\u524d\u5bf9\u8bdd\u6846\u3002

      dialogDismiss()\n
      "},{"location":"qsl4a/ui/dialogs/#dialoggetresponse","title":"dialogGetResponse()","text":"

      \u83b7\u53d6\u5bf9\u8bdd\u6846\u54cd\u5e94\u3002

      dialogGetResponse()\n
      "},{"location":"qsl4a/ui/dialogs/#dialoggetselecteditems","title":"dialogGetSelectedItems()","text":"

      \u4ece\u9009\u62e9\u5bf9\u8bdd\u6846\u83b7\u53d6\u9009\u4e2d\u7684\u9879\u76ee\u3002

      dialogGetSelectedItems()\n
      "},{"location":"qsl4a/ui/dialogs/#_9","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/dialogs/#_10","title":"\u7b80\u5355\u8b66\u62a5","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a\u8b66\u62a5\ndroid.dialogShowAlert(\"Warning\", \"This is an important message!\")\n
      "},{"location":"qsl4a/ui/dialogs/#_11","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":"
      # \u83b7\u53d6\u7528\u6237\u8f93\u5165\nresult = droid.dialogGetInput(\"Name\", \"Enter your name:\", \"John\").result\nprint(f\"Hello, {result}!\")\n
      "},{"location":"qsl4a/ui/dialogs/#_12","title":"\u5e26\u6309\u94ae\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846","text":"
      # \u521b\u5efa\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\ndroid.dialogCreateAlert(\"Custom\", \"Choose an option\")\ndroid.dialogSetItems([\"Option 1\", \"Option 2\", \"Option 3\"])\ndroid.dialogShow()\n\n# \u83b7\u53d6\u54cd\u5e94\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response['item']}\")\n
      "},{"location":"qsl4a/ui/dialogs/#_13","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":"
      # \u521b\u5efa\u8fdb\u5ea6\u5bf9\u8bdd\u6846\ndroid.dialogCreateHorizontalProgress(\"Loading\", \"Please wait...\", 100)\ndroid.dialogShow()\n\n# \u66f4\u65b0\u8fdb\u5ea6\nfor i in range(101):\n    droid.dialogSetCurrentProgress(i)\n    time.sleep(0.05)\n\ndroid.dialogDismiss()\n
      "},{"location":"qsl4a/ui/dialogs/#_14","title":"\u65e5\u671f\u9009\u62e9\u5668","text":"
      # \u663e\u793a\u65e5\u671f\u9009\u62e9\u5668\ndroid.dialogCreateDatePicker(2024, 1, 15)\ndroid.dialogShow()\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response}\")\n
      "},{"location":"qsl4a/ui/floatview/","title":"\u6d6e\u52a8\u89c6\u56fe","text":"

      \u6d6e\u52a8\u7a97\u53e3\u652f\u6301\uff0c\u7528\u4e8e\u5728\u5176\u4ed6\u5e94\u7528\u7a0b\u5e8f\u4e0a\u65b9\u4fdd\u6301\u663e\u793a\u7684\u8986\u76d6 UI \u5143\u7d20\u3002

      "},{"location":"qsl4a/ui/floatview/#_2","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/floatview/#floatview","title":"floatView()","text":"

      \u663e\u793a\u6216\u4fee\u6539\u6d6e\u52a8\u89c6\u56fe\u3002

      floatView(Args=None)\n

      \u53c2\u6570\uff1a - Args (dict): \u914d\u7f6e\u5b57\u5178\uff0c\u5305\u542b\u4ee5\u4e0b\u952e\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08-1 \u521b\u5efa\u65b0\u7684\uff0c>=0 \u4fee\u6539\u73b0\u6709\u7684\uff09 - text (str): \u8981\u663e\u793a\u7684\u6587\u672c\u5185\u5bb9 - html (str): HTML \u5185\u5bb9\uff08\u5982\u679c\u7701\u7565 text \u5219\u4f7f\u7528\uff09 - width (int): \u89c6\u56fe\u5bbd\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a300\uff09 - height (int): \u89c6\u56fe\u9ad8\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a150\uff09 - x (int): X \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - y (int): Y \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - backColor (str): ARGB \u5341\u516d\u8fdb\u5236\u80cc\u666f\u8272\uff08\u9ed8\u8ba4\uff1a'7f7f7f7f'\uff09 - textColor (str): ARGB \u5341\u516d\u8fdb\u5236\u6587\u672c\u8272\uff08\u9ed8\u8ba4\uff1a'ff000000'\uff09 - textSize (int): \u6587\u672c\u5927\u5c0f\uff08\u9ed8\u8ba4\uff1a10\uff09 - textAlign (int): \u6587\u672c\u5bf9\u9f50\uff080 = \u7ee7\u627f\uff09 - script (str): \u957f\u6309\u5173\u95ed\u540e\u8fd0\u884c\u7684\u811a\u672c\u8def\u5f84 - arg: \u811a\u672c\u53c2\u6570 - clickRemove (bool): \u542f\u7528\u70b9\u51fb\u79fb\u9664\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - flag (int): \u7a97\u53e3\u6807\u5fd7\uff08\u9ed8\u8ba4\uff1a40 - \u53ef\u89e6\u6478\uff09

      \u8fd4\u56de\uff1a \u5f53\u524d\u94fe\u5217\u8868\u957f\u5ea6

      "},{"location":"qsl4a/ui/floatview/#floatviewcount","title":"floatViewCount()","text":"

      \u83b7\u53d6\u6d3b\u52a8\u6d6e\u52a8\u89c6\u56fe\u7684\u6570\u91cf\u3002

      floatViewCount()\n

      \u8fd4\u56de\uff1a \u6d6e\u52a8\u89c6\u56fe\u6570\u91cf

      "},{"location":"qsl4a/ui/floatview/#floatviewresult","title":"floatViewResult()","text":"

      \u83b7\u53d6\u6d6e\u52a8\u89c6\u56fe\u7684\u7ed3\u679c/\u72b6\u6001\u3002

      floatViewResult(index=-1)\n

      \u53c2\u6570\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1\uff0c\u8fd4\u56de\u6700\u540e\u64cd\u4f5c\u7ed3\u679c\uff09

      \u8fd4\u56de\uff1a \u5305\u542b\u64cd\u4f5c\u8be6\u60c5\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - x, y: \u4f4d\u7f6e - time: \u65f6\u95f4\u6233 - operation: \u64cd\u4f5c\u7c7b\u578b\uff08'initial'\u3001'move' \u7b49\uff09 - index: \u89c6\u56fe\u7d22\u5f15 - removed: \u5982\u679c\u89c6\u56fe\u88ab\u79fb\u9664\u5219\u4e3a True

      "},{"location":"qsl4a/ui/floatview/#floatviewremove","title":"floatViewRemove()","text":"

      \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\u3002

      floatViewRemove(index=-1)\n

      \u53c2\u6570\uff1a - index (int): \u8981\u79fb\u9664\u7684\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1 \u79fb\u9664\u6700\u540e\u4e00\u4e2a\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a 1\uff0c\u5426\u5219\u4e3a 0

      "},{"location":"qsl4a/ui/floatview/#_3","title":"\u5e38\u91cf","text":"
      • floatView.INDEX_NEW = -1 - \u521b\u5efa\u65b0\u7684\u6d6e\u52a8\u89c6\u56fe
      • floatView.FLAG_DEFAULT_TOUCHABLE = 40 - \u9ed8\u8ba4\u53ef\u89e6\u6478\u6807\u5fd7
      • floatView.TEXT_ALIGNMENT_INHERIT = 0
      • floatView.TEXT_ALIGNMENT_CENTER - \u5c45\u4e2d\u6587\u672c\u5bf9\u9f50
      "},{"location":"qsl4a/ui/floatview/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/floatview/#_5","title":"\u57fa\u672c\u6d6e\u52a8\u89c6\u56fe","text":"
      import androidhelper\nfrom androidhelper import Android\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u7b80\u5355\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'index': -1,  # \u521b\u5efa\u65b0\u7684\n    'text': 'Hello World',\n    'width': 400,\n    'height': 300,\n    'x': -300,  # \u4ece\u4e2d\u5fc3\u504f\u79fb\n    'y': -400,\n    'backColor': 'ff0000',  # \u7ea2\u8272\u80cc\u666f\n    'textColor': '0000ff',  # \u84dd\u8272\u6587\u672c\n    'textSize': 16,\n    'textAlign': droid.floatView.TEXT_ALIGNMENT_CENTER\n})\n\n# \u68c0\u67e5\u6570\u91cf\nprint(f\"Float views: {droid.floatViewCount().result}\")\n\n# \u83b7\u53d6\u7ed3\u679c\nresult = droid.floatViewResult().result\nprint(f\"View info: {result}\")\n\n# \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\ndroid.floatViewRemove(0)\n
      "},{"location":"qsl4a/ui/floatview/#html","title":"HTML \u5185\u5bb9","text":"
      # \u521b\u5efa\u5e26 HTML \u5185\u5bb9\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': '',  # \u7a7a\u6587\u672c\u4ee5\u4f7f\u7528 HTML\n    'html': '<h1>Title</h1><p>Rich <b>HTML</b> content</p>',\n    'width': 500,\n    'height': 400\n})\n
      "},{"location":"qsl4a/ui/floatview/#_6","title":"\u4fee\u6539\u73b0\u6709\u89c6\u56fe","text":"
      # \u521b\u5efa\u521d\u59cb\u89c6\u56fe\ndroid.floatView({'text': 'Initial Text', 'width': 300, 'height': 150})\n\n# \u4fee\u6539\u540c\u4e00\u89c6\u56fe\uff08\u7d22\u5f15 0\uff09\ndroid.floatView({\n    'index': 0,\n    'text': 'Updated Text!',\n    'backColor': '7f00ff00'  # \u7eff\u8272\u80cc\u666f\n})\n\n# \u68c0\u67e5\u79fb\u52a8/\u66f4\u6539\u7ed3\u679c\nresult = droid.floatViewResult(0).result\nprint(f\"Operation: {result.get('operation')}, Position: ({result.get('x')}, {result.get('y')})\")\n
      "},{"location":"qsl4a/ui/floatview/#_7","title":"\u591a\u4e2a\u6d6e\u52a8\u89c6\u56fe","text":"
      # \u521b\u5efa\u591a\u4e2a\u89c6\u56fe\nfor i in range(3):\n    droid.floatView({\n        'index': -1,\n        'text': f'View {i}',\n        'x': i * 100 - 150,\n        'y': i * 100 - 150,\n        'backColor': f'{i}f{i}f{i}f'\n    })\n\nprint(f\"Total views: {droid.floatViewCount().result}\")\n\n# \u79fb\u9664\u6240\u6709\u89c6\u56fe\nwhile droid.floatViewCount().result > 0:\n    droid.floatViewRemove()\n
      "},{"location":"qsl4a/ui/floatview/#_8","title":"\u5e26\u811a\u672c\u56de\u8c03","text":"
      # \u521b\u5efa\u5173\u95ed\u65f6\u8fd0\u884c\u811a\u672c\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': 'Click to close and run script',\n    'script': '/sdcard/my_script.py',\n    'arg': 'hello from float view',\n    'clickRemove': True\n})\n
      "},{"location":"qsl4a/ui/fullscreen/","title":"\u5168\u5c4f UI","text":"

      \u4f7f\u7528\u539f\u751f Android \u5e03\u5c40\u521b\u5efa\u81ea\u5b9a\u4e49\u5168\u5c4f\u754c\u9762\u3002

      "},{"location":"qsl4a/ui/fullscreen/#_1","title":"\u5e03\u5c40\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullshow","title":"fullShow()","text":"

      \u663e\u793a\u5168\u5c4f\u5e03\u5c40\u3002

      fullShow(layout, title=None, theme=None)\n

      \u53c2\u6570\uff1a - layout (str): JSON \u5e03\u5c40\u5b9a\u4e49\u6216\u5e03\u5c40\u5b57\u7b26\u4e32 - title (str, optional): \u7a97\u53e3\u6807\u9898 - theme (str, optional): \u4e3b\u9898\u540d\u79f0

      \u8fd4\u56de\uff1a \u7a97\u53e3 ID

      "},{"location":"qsl4a/ui/fullscreen/#fulldismiss","title":"fullDismiss()","text":"

      \u5173\u95ed\u5168\u5c4f\u7a97\u53e3\u3002

      fullDismiss()\n
      "},{"location":"qsl4a/ui/fullscreen/#fullquery","title":"fullQuery()","text":"

      \u67e5\u8be2\u6240\u6709\u5c0f\u90e8\u4ef6\u503c\u3002

      fullQuery()\n

      \u8fd4\u56de\uff1a \u5c0f\u90e8\u4ef6 ID \u548c\u503c\u7684\u5b57\u5178

      "},{"location":"qsl4a/ui/fullscreen/#fullquerydetail","title":"fullQueryDetail()","text":"

      \u67e5\u8be2\u7279\u5b9a\u5c0f\u90e8\u4ef6\u8be6\u60c5\u3002

      fullQueryDetail(id)\n
      "},{"location":"qsl4a/ui/fullscreen/#_2","title":"\u5c5e\u6027\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperty","title":"fullGetProperty()","text":"

      \u83b7\u53d6\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

      fullGetProperty(id, property)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetproperty","title":"fullSetProperty()","text":"

      \u8bbe\u7f6e\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

      fullSetProperty(id, property, value)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetlist","title":"fullSetList()","text":"

      \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

      fullSetList(id, list, isHtml=False, listType=0)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetlist2","title":"fullSetList2()","text":"

      \u4f7f\u7528\u8d44\u6e90 ID \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

      fullSetList2(id, list, intRes)\n

      \u53c2\u6570\uff1a - id (str): \u5c0f\u90e8\u4ef6 ID - list (list): \u9879\u76ee\u5217\u8868 - intRes (int): \u5217\u8868\u9879\u76ee\u5e03\u5c40\u7684 Android \u8d44\u6e90 ID

      "},{"location":"qsl4a/ui/fullscreen/#fullsetlistselected","title":"fullSetListSelected()","text":"

      \u5728\u5217\u8868\u4e2d\u8bbe\u7f6e\u9009\u4e2d\u9879\u76ee\u3002

      fullSetListSelected(id, selected)\n

      \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID - selected (int): \u8981\u9009\u4e2d\u7684\u9879\u76ee\u7d22\u5f15

      "},{"location":"qsl4a/ui/fullscreen/#fullgetlistselected","title":"fullGetListSelected()","text":"

      \u83b7\u53d6\u5f53\u524d\u9009\u4e2d\u7684\u5217\u8868\u9879\u76ee\u7d22\u5f15\u3002

      fullGetListSelected(id)\n

      \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID

      \u8fd4\u56de\uff1a \u9009\u4e2d\u9879\u76ee\u7d22\u5f15

      "},{"location":"qsl4a/ui/fullscreen/#_3","title":"\u6279\u91cf\u5c5e\u6027\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperties","title":"fullGetProperties()","text":"

      \u4e00\u6b21\u83b7\u53d6\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

      fullGetProperties(ids, property)\n

      \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u83b7\u53d6\u7684\u5c5e\u6027\u540d

      \u8fd4\u56de\uff1a \u6620\u5c04\u5c0f\u90e8\u4ef6 ID \u5230\u5c5e\u6027\u503c\u7684\u5b57\u5178

      "},{"location":"qsl4a/ui/fullscreen/#fullsetproperties","title":"fullSetProperties()","text":"

      \u4e00\u6b21\u8bbe\u7f6e\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

      fullSetProperties(ids, property, value)\n

      \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u8bbe\u7f6e\u7684\u5c5e\u6027\u540d - value: \u5c5e\u6027\u503c

      "},{"location":"qsl4a/ui/fullscreen/#_4","title":"\u622a\u56fe","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetscreenshot","title":"fullGetScreenShot()","text":"

      \u6355\u83b7\u5168\u5c4f\u622a\u56fe\u3002

      fullGetScreenShot(path=None)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u5728\u4e8b\u4ef6\u4e2d\u8fd4\u56de

      \u8fd4\u56de\uff1a \u5305\u542b\u622a\u56fe\u6570\u636e\u7684\u4e8b\u4ef6

      "},{"location":"qsl4a/ui/fullscreen/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b9a\u4e49\u5e03\u5c40\nlayout = '''\n{ \"type\": \"LinearLayout\", \"orientation\": \"vertical\",\n  \"children\": [\n    { \"type\": \"TextView\", \"id\": \"title\", \"text\": \"Hello\" },\n    { \"type\": \"Button\", \"id\": \"btn\", \"text\": \"Click Me\" }\n  ]\n}\n'''\n\n# \u663e\u793a\u5e03\u5c40\ndroid.fullShow(layout, \"My App\")\n\n# \u67e5\u8be2\u6309\u94ae\u70b9\u51fb\nevent = droid.eventWaitFor('click', timeout=10)\nif event.result:\n    widget_id = event.result['data']['id']\n    if widget_id == 'btn':\n        print(\"Button clicked!\")\n\ndroid.fullDismiss()\n
      "}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"QPython \u9879\u76ee","text":"

      QPython \u4e0d\u4ec5\u662f\u4e00\u4e2a\u5f3a\u5927\u7684 Android Python IDE\uff0c\u4e5f\u662f\u4e00\u4e2a\u6d3b\u8dc3\u7684\u6280\u672f\u793e\u533a\u3002

      "},{"location":"#ai-android-python-ide","title":"\u652f\u6301 AI \u7684 Android Python IDE","text":"

      QPython \u662f\u60a8\u8fdb\u884c Android Python \u7f16\u7a0b\u7684\u5165\u53e3\u3002\u5b83\u96c6\u6210\u4e86 Python \u89e3\u91ca\u5668\u3001AI \u6a21\u578b\u5f15\u64ce\u548c\u79fb\u52a8\u5f00\u53d1\u5de5\u5177\u94fe\uff0c\u8ba9\u60a8\u80fd\u591f\u4ece\u79fb\u52a8\u8bbe\u5907\u6784\u5efa Web \u5e94\u7528\u7a0b\u5e8f\u3001\u6267\u884c\u79d1\u5b66\u8ba1\u7b97\u548c\u521b\u5efa\u667a\u80fd\u5e94\u7528\u3002

      \u65e0\u8bba\u60a8\u662f\u5728\u5b66\u4e60\u7f16\u7a0b\u3001\u6784\u5efa\u6570\u636e\u79d1\u5b66\u9879\u76ee\uff0c\u8fd8\u662f\u5f00\u53d1 AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f\uff0cQPython \u90fd\u63d0\u4f9b\u4e86\u5b8c\u6574\u7684\u79fb\u52a8\u7f16\u7a0b\u89e3\u51b3\u65b9\u6848\uff0c\u62e5\u6709\u5168\u9762\u7684\u5f00\u53d1\u8005\u8d44\u6e90\u548c\u6d3b\u8dc3\u7684\u793e\u533a\u6765\u652f\u6301\u60a8\u7684\u65c5\u7a0b\u3002

      • \u5206\u652f\u7248\u672c \u2013 \u4e86\u89e3\u4e0d\u540c\u7684 QPython \u7248\u672c\uff08IDE\u3001\u793e\u533a\u7248\u3001Plus\uff09\uff0c\u9009\u62e9\u9002\u5408\u60a8\u9700\u6c42\u7684\u7248\u672c
      • \u66f4\u65b0\u65e5\u5fd7 \u2013 \u968f\u65f6\u4e86\u89e3\u6700\u65b0\u529f\u80fd\u3001\u6539\u8fdb\u548c\u53d1\u884c\u8bf4\u660e
      "},{"location":"#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"

      \u5982\u4f55\u5feb\u901f\u5165\u95e8\uff1f\u8bf7\u6309\u7167\u4ee5\u4e0b\u6b65\u9aa4\uff1a

      • \u5feb\u901f\u5165\u95e8
      • Hello World \u6559\u7a0b
      "},{"location":"#_2","title":"\u7f16\u7a0b\u6307\u5357","text":"

      QPython \u4e0d\u4ec5\u63d0\u4f9b\u57fa\u7840\u7684 Python \u63a5\u53e3\u652f\u6301\uff0c\u66f4\u91cd\u8981\u7684\u662f\uff0c\u5b83\u8fd8\u5141\u8bb8\u60a8\u901a\u8fc7 QSL4A \u63a5\u53e3\u4f7f\u7528 Python \u8c03\u7528 Android API\u3002

      • Python \u6807\u51c6\u5e93 \u2013 \u901a\u7528\u7684 Python \u8bed\u6cd5\u548c\u5185\u7f6e\u5e93
      • QSL4A API \u2013 \u4ece Python \u8bbf\u95ee Android \u8bbe\u5907\u529f\u80fd\uff08\u76f8\u673a\u3001\u4f20\u611f\u5668\u3001\u77ed\u4fe1\u7b49\uff09
      • QPYPI \u6307\u5357 \u2013 \u5b89\u88c5\u989d\u5916\u7684 Python \u5305
      • \u7f16\u8f91\u5668\u6307\u5357 \u2013 \u4f7f\u7528\u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668
      • \u5916\u90e8 API \u2013 \u4e0e\u5916\u90e8\u5e94\u7528\u7a0b\u5e8f\u96c6\u6210
      "},{"location":"#_3","title":"\u4e0b\u8f7d\u8d44\u6e90","text":"
      • Google Drive
      • \u5fae\u4fe1\u7f51\u76d8
      "},{"location":"#_4","title":"\u793e\u533a\u4e0e\u53cd\u9988","text":"
      • \u4e2d\u6587\u4ea4\u6d41\u793e\u533a
      • \u95ee\u9898\u53cd\u9988
      • \u529f\u80fd\u6269\u5c55\u8bf7\u6c42
      "},{"location":"#_5","title":"\u5173\u6ce8\u6211\u4eec","text":"
      • B\u7ad9
      • Weibo
      "},{"location":"AIPyApp/","title":"AIPyApp - AI\u9a71\u52a8\u7684\u7a0b\u5e8f\u751f\u6210\u5668","text":"

      AIPyApp \u662f QPython \u4e2d\u7684\u667a\u80fd\u5de5\u5177\uff0c\u53ef\u4ee5\u5229\u7528 AI \u4ece\u81ea\u7136\u8bed\u8a00\u6307\u4ee4\u81ea\u52a8\u751f\u6210 Python \u7a0b\u5e8f\u3002

      "},{"location":"AIPyApp/#_1","title":"\u6982\u8ff0","text":"

      AIPyApp \u6539\u53d8\u4e86\u60a8\u7f16\u5199\u4ee3\u7801\u7684\u65b9\u5f0f\u2014\u2014\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u63cf\u8ff0\u60a8\u60f3\u8981\u7684\u529f\u80fd\uff0cAI \u5c31\u4f1a\u4e3a\u60a8\u751f\u6210 Python \u7a0b\u5e8f\u3002QPython \u8fd8\u5c06\u63a8\u51fa AIPy Academy\u2014\u2014\u4e00\u4e2a\u4e3a AI \u65f6\u4ee3\u91cf\u8eab\u5b9a\u5236\u7684 Python \u7f16\u7a0b\u8bfe\u7a0b\u5e73\u53f0\u3002

      "},{"location":"AIPyApp/#_2","title":"\u5b89\u88c5","text":"

      QPython \u6c1b\u56f4\u7f16\u7a0b\uff08Vibe Coding\uff09 01 - \u5982\u4f55\u542f\u7528AIPyApp

      "},{"location":"AIPyApp/#_3","title":"\u7b2c\u4e00\u6b65\uff1a\u4ece\u4eea\u8868\u76d8\u542f\u52a8","text":"
      1. \u6253\u5f00 QPython\uff0c\u8fdb\u5165 \u4eea\u8868\u76d8
      2. \u957f\u6309\u5f00\u59cb\u6309\u94ae

      \u5982\u679c\u672a\u5b89\u88c5 AIPyApp\uff0c\u7cfb\u7edf\u4f1a\u63d0\u793a\u60a8\u786e\u8ba4\u5b89\u88c5\u3002\u6309 \u56de\u8f66\u952e\u7ee7\u7eed\u3002

      QPython \u5c06\u81ea\u52a8\u4ece PYPI \u4e0b\u8f7d\u5e76\u5b89\u88c5\u6240\u9700\u7684\u4f9d\u8d56\u9879\u3002\u8bf7\u8010\u5fc3\u7b49\u5f85\u5b89\u88c5\u5b8c\u6210\u3002

      "},{"location":"AIPyApp/#aipyapp","title":"\u7b2c\u4e8c\u6b65\uff1a\u91cd\u65b0\u542f\u52a8 AIPyApp","text":"

      \u5b89\u88c5\u5b8c\u6210\u540e\uff0c\u8fd4\u56de QPython \u4eea\u8868\u76d8\uff0c\u518d\u6b21 \u957f\u6309\u5f00\u59cb\u6309\u94ae\u542f\u52a8 AIPyApp\u3002

      "},{"location":"AIPyApp/#_4","title":"\u914d\u7f6e","text":""},{"location":"AIPyApp/#ai","title":"\u8bbe\u7f6e\u60a8\u7684 AI \u5bc6\u94a5","text":"

      \u9996\u6b21\u542f\u52a8\u65f6\uff0c\u60a8\u9700\u8981\u63d0\u4f9b AI API \u5bc6\u94a5\uff1a

      1. \u5728 PGPT \u6ce8\u518c\uff1a\u5728 https://user.pgpt.cloud \u521b\u5efa\u8d26\u6237\u4ee5\u751f\u6210\u60a8\u7684 AI \u5bc6\u94a5
      2. \u9ad8\u7ea7\u9009\u9879\uff1aAIPyApp \u8fd8\u652f\u6301\u6765\u81ea OpenAI\u3001Deepseek \u548c\u5176\u4ed6\u63d0\u4f9b\u5546\u7684\u81ea\u5b9a\u4e49 AI \u5bc6\u94a5\uff08\u8be6\u89c1\u9ad8\u7ea7\u6559\u7a0b\uff09
      "},{"location":"AIPyApp/#ai_1","title":"\u8f93\u5165\u60a8\u7684 AI \u5bc6\u94a5","text":"
      1. \u957f\u6309\u8f93\u5165\u63d0\u793a
      2. \u4ece\u5f39\u51fa\u83dc\u5355\u4e2d\u9009\u62e9 \u7c98\u8d34
      3. \u6309 \u56de\u8f66\u952e\u786e\u8ba4

      \u60a8\u7684 AI \u5bc6\u94a5\u5c06\u4fdd\u5b58\u4ee5\u4f9b\u540e\u7eed\u4f1a\u8bdd\u4f7f\u7528\u3002

      "},{"location":"AIPyApp/#aipyapp_1","title":"\u4f7f\u7528 AIPyApp","text":"

      \u914d\u7f6e\u5b8c\u6210\u540e\uff0c\u60a8\u5c06\u8fdb\u5165 AIPyApp \u63a7\u5236\u53f0\u6a21\u5f0f\u3002\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u8f93\u5165\u60a8\u7684\u6307\u4ee4\u5373\u53ef\uff01

      "},{"location":"AIPyApp/#_5","title":"\u793a\u4f8b\u547d\u4ee4","text":"

      \u5c1d\u8bd5\u8f93\u5165\uff1a

      \u4f7f\u7528 QSL4A \u521b\u5efa\u4e00\u4e2a HELLO QPY \u7a0b\u5e8f\u4f5c\u4e3a\u6f14\u793a\n

      AIPyApp \u5c06\uff1a 1. \u7406\u89e3\u60a8\u7684\u81ea\u7136\u8bed\u8a00\u8bf7\u6c42 2. \u751f\u6210\u76f8\u5e94\u7684 Python \u4ee3\u7801 3. \u81ea\u52a8\u6267\u884c\u7a0b\u5e8f

      \u5c31\u662f\u8fd9\u6837\u2014\u2014\u60a8\u65e0\u9700\u7f16\u5199\u4efb\u4f55\u4ee3\u7801\u5c31\u521b\u5efa\u4e86\u4e00\u4e2a\u53ef\u8fd0\u884c\u7684 Python \u7a0b\u5e8f\uff01

      "},{"location":"AIPyApp/#_6","title":"\u6f14\u793a\u89c6\u9891","text":"

      QPython \u6c1b\u56f4\u7f16\u7a0b\uff08Vibe Coding\uff09 02 - \u4f7f\u7528\u81ea\u7136\u8bed\u8a00\u5f00\u53d1\u4e00\u4e2a\u7ffb\u8bd1App

      \u4e0a\u9762\u7684\u793a\u4f8b\u6f14\u793a\u4e86 AIPyApp \u5982\u4f55\uff1a - \u7406\u89e3\u4e2d\u6587\u6307\u4ee4 - \u751f\u6210\u57fa\u4e8e QSL4A \u7684 Python \u4ee3\u7801 - \u7acb\u5373\u8fd0\u884c\u7a0b\u5e8f

      \u63a2\u7d22 AIPyApp \u4ee5\u53d1\u73b0\u66f4\u591a\u529f\u80fd\uff0c\u5f00\u59cb\u8f7b\u677e\u6784\u5efa Python \u7a0b\u5e8f\u3002

      "},{"location":"AIPyApp/#_7","title":"\u8bfe\u7a0b\u63a8\u8350","text":"

      \u672b\u5c3e\uff0c\u7ed9\u5927\u5bb6\u63a8\u8350\u4e0b\u9762\u8bfe\u7a0b\uff1a

      \u300a\u4e0eAI\u534f\u4f5c\u7684Python\u7f16\u7a0b\u5165\u95e8\u300b \u2014 \u7531QPython\u5b98\u65b9\u56e2\u961f\u7cbe\u5fc3\u6253\u9020\u5e76\u63d0\u4f9b\u6559\u5b66\u652f\u6301\uff0c\u80fd\u5e2e\u52a9\u5b66\u4e60\u8005\u5feb\u901f\u3001\u4f53\u7cfb\u5316\u5730\u638c\u63e1Python\u5f00\u53d1\u4ee5\u53ca\u5728AI\u65f6\u4ee3\u66f4\u597d\u5730\u5b66\u4e60\u4f7f\u7528AI\u3002

      \u4e86\u89e3\u8be6\u60c5

      "},{"location":"GraphicalInterface/","title":"\u56fe\u5f62\u754c\u9762\uff08Turtle \u548c Tkinter\uff09","text":"

      \u672c\u6307\u5357\u8bf4\u660e\u5982\u4f55\u5728 Android \u8bbe\u5907\u4e0a\u7684 QPython \u4e2d\u542f\u7528\u56fe\u5f62\u754c\u9762\u652f\u6301\uff08Turtle \u548c Tkinter\uff09\u3002

      "},{"location":"GraphicalInterface/#_1","title":"\u6982\u8ff0","text":"

      QPython \u53ef\u4ee5\u8fd0\u884c Turtle \u548c Tkinter \u5e94\u7528\u7a0b\u5e8f\uff0c\u4f46\u9700\u8981\u989d\u5916\u7684\u8f6f\u4ef6\u6765\u5728 Android \u4e0a\u63d0\u4f9b\u56fe\u5f62\u663e\u793a\u652f\u6301\u3002

      "},{"location":"GraphicalInterface/#_2","title":"\u524d\u63d0\u6761\u4ef6","text":"

      \u5f00\u59cb\u4e4b\u524d\uff0c\u60a8\u9700\u8981\u4e0b\u8f7d\u4ee5\u4e0b\u8d44\u6e90\uff1a

      1. Xserver.apk - \u63d0\u4f9b Turtle/Tkinter \u56fe\u5f62\u652f\u6301\u7684\u914d\u5957\u5e94\u7528
      2. \u4e0b\u8f7d\u5730\u5740\uff1aQPythonProject/Extra on Google Drive
      3. Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762\u6269\u5c55 - \u901a\u8fc7 QPython \u7684 QPYPI \u5b89\u88c5
      "},{"location":"GraphicalInterface/#_3","title":"\u5b89\u88c5\u6b65\u9aa4","text":""},{"location":"GraphicalInterface/#xserver","title":"\u7b2c\u4e00\u6b65\uff1a\u5b89\u88c5 Xserver","text":"

      \u4ece Google Drive \u7684 QPython Extra \u8d44\u6e90\u76ee\u5f55\u4e0b\u8f7d\u5e76\u5b89\u88c5 Xserver.apk\u3002

      "},{"location":"GraphicalInterface/#qpython","title":"\u7b2c\u4e8c\u6b65\uff1a\u5b89\u88c5 QPython \u6269\u5c55","text":"

      \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI\u3002\u627e\u5230\u5e76\u5b89\u88c5 Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762 \u6269\u5c55\u3002

      "},{"location":"GraphicalInterface/#xserver_1","title":"\u7b2c\u4e09\u6b65\uff1a\u914d\u7f6e Xserver \u7535\u6c60\u8bbe\u7f6e","text":"

      \u4e3a\u9632\u6b62 Xserver \u5728\u540e\u53f0\u8fd0\u884c\u65f6\u88ab\u6740\u6b7b\uff1a

      1. \u8fdb\u5165\u8bbe\u5907\u7684 \u8bbe\u7f6e > \u5e94\u7528 > Xserver
      2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
      3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u6216 \"\u4e0d\u9650\u5236\"

      \u8fd9\u53ef\u786e\u4fdd Xserver \u5728\u5207\u6362\u5230\u540e\u53f0\u65f6\u7ee7\u7eed\u8fd0\u884c\u3002

      "},{"location":"GraphicalInterface/#qpython_1","title":"\u7b2c\u56db\u6b65\uff1a\u914d\u7f6e QPython \u7535\u6c60\u8bbe\u7f6e\uff08\u63a8\u8350\uff09","text":"

      \u540c\u6837\uff0c\u5c06 QPython \u7684\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u4ee5\u9632\u6b62\u8fdb\u7a0b\u88ab\u7ec8\u6b62\uff1a

      1. \u8fdb\u5165 \u8bbe\u7f6e > \u5e94\u7528 > QPython
      2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
      3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\"
      "},{"location":"GraphicalInterface/#xserver_2","title":"\u7b2c\u4e94\u6b65\uff1a\u542f\u52a8 Xserver","text":"

      \u5728\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d\uff0c\u542f\u52a8 Xserver \u5e94\u7528\u5e76\u5c06\u5176\u5207\u6362\u4e3a\u540e\u53f0\u8fd0\u884c\u3002

      "},{"location":"GraphicalInterface/#turtletkinter","title":"\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f","text":"

      \u5b8c\u6210\u8bbe\u7f6e\u540e\uff1a

      1. \u786e\u4fdd Xserver \u5728\u540e\u53f0\u8fd0\u884c
      2. \u5728 QPython \u4e2d\u8fd0\u884c\u60a8\u7684 Turtle \u6216 Tkinter \u5e94\u7528\u7a0b\u5e8f
      3. \u5207\u6362\u5230 Xserver \u67e5\u770b\u56fe\u5f62\u8f93\u51fa
      "},{"location":"GraphicalInterface/#_4","title":"\u6f14\u793a\u7a0b\u5e8f","text":"

      \u60a8\u53ef\u4ee5\u4ece QPython \u5e94\u7528\u7684 QPYPI \u7b2c\u4e00\u4e2a\u6269\u5c55\u90e8\u5206\u4e0b\u8f7d\u5e76\u5c1d\u8bd5 Turtle \u753b\u54c6\u5566A\u68a6 \u6f14\u793a\u7a0b\u5e8f\u6765\u9a8c\u8bc1\u60a8\u7684\u8bbe\u7f6e\u3002

      "},{"location":"GraphicalInterface/#_5","title":"\u6f14\u793a\u89c6\u9891","text":""},{"location":"GraphicalInterface/#_6","title":"\u6545\u969c\u6392\u9664","text":"
      • \u9ed1\u5c4f\uff1a\u786e\u4fdd\u5728\u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d Xserver \u6b63\u5728\u8fd0\u884c
      • \u5e94\u7528\u7a0b\u5e8f\u5d29\u6e83\uff1a\u68c0\u67e5 QPython \u548c Xserver \u662f\u5426\u90fd\u8bbe\u7f6e\u4e86\u65e0\u9650\u5236\u7684\u7535\u6c60\u8bbe\u7f6e
      • \u65e0\u663e\u793a\uff1a\u9a8c\u8bc1 Turtle/Tkinter \u6269\u5c55\u662f\u5426\u901a\u8fc7 QPYPI \u6b63\u786e\u5b89\u88c5
      "},{"location":"GraphicalInterface/#_7","title":"\u8bfe\u7a0b\u63a8\u8350","text":"

      \u672b\u5c3e\uff0c\u7ed9\u5927\u5bb6\u63a8\u8350\u4e0b\u9762\u8bfe\u7a0b\uff1a

      \u300a\u4e0eAI\u534f\u4f5c\u7684Python\u7f16\u7a0b\u5165\u95e8\u300b \u2014 \u7531QPython\u5b98\u65b9\u56e2\u961f\u7cbe\u5fc3\u6253\u9020\u5e76\u63d0\u4f9b\u6559\u5b66\u652f\u6301\uff0c\u80fd\u5e2e\u52a9\u5b66\u4e60\u8005\u5feb\u901f\u3001\u4f53\u7cfb\u5316\u5730\u638c\u63e1Python\u5f00\u53d1\u4ee5\u53ca\u5728AI\u65f6\u4ee3\u66f4\u597d\u5730\u5b66\u4e60\u4f7f\u7528AI\u3002

      \u4e86\u89e3\u8be6\u60c5

      "},{"location":"Notebook/","title":"Notebook","text":"

      QPython \u96c6\u6210\u4e86 Jupyter Notebook\uff0c\u63d0\u4f9b\u4e86\u4e00\u4e2a\u5f3a\u5927\u7684\u4ea4\u4e92\u73af\u5883\uff0c\u53ef\u5728 Android \u8bbe\u5907\u4e0a\u8fdb\u884c\u6570\u636e\u79d1\u5b66\u3001\u79d1\u5b66\u8ba1\u7b97\u548c AI \u5f00\u53d1\u3002

      "},{"location":"Notebook/#_1","title":"\u6982\u8ff0","text":"

      QPython \u81ea\u5e26\u5185\u7f6e\u7684 Jupyter Notebook \u5e94\u7528\u7a0b\u5e8f\uff0c\u5141\u8bb8\u60a8\u76f4\u63a5\u5728 Android \u8bbe\u5907\u4e0a\u521b\u5efa\u548c\u8fd0\u884c\u4ea4\u4e92\u5f0f Python \u7b14\u8bb0\u672c\u3002\u754c\u9762\u548c\u64cd\u4f5c\u65b9\u5f0f\u4e0e\u6807\u51c6 Jupyter Notebook \u7c7b\u4f3c\u3002

      "},{"location":"Notebook/#_2","title":"\u53ef\u7528\u5e93","text":"

      QPython \u652f\u6301\u5e7f\u6cdb\u7684\u6570\u5b66\u3001\u79d1\u5b66\u548c AI \u76f8\u5173\u5e93\uff0c\u975e\u5e38\u9002\u5408 Notebook \u73af\u5883\u3002\u53ef\u6839\u636e\u9700\u8981\u901a\u8fc7 QPYPI \u5b89\u88c5\uff1a

      • Matplotlib - \u7ed8\u56fe\u548c\u53ef\u89c6\u5316
      • Seaborn - \u7edf\u8ba1\u6570\u636e\u53ef\u89c6\u5316
      • Pandas - \u6570\u636e\u5206\u6790\u4e0e\u5904\u7406
      • Numpy - \u6570\u503c\u8ba1\u7b97
      • Scipy - \u79d1\u5b66\u8ba1\u7b97
      • OpenCV - \u8ba1\u7b97\u673a\u89c6\u89c9\u548c\u56fe\u50cf\u5904\u7406
      • Sympy - \u7b26\u53f7\u6570\u5b66
      • mpmath - \u4efb\u610f\u7cbe\u5ea6\u7b97\u672f
      • Scikit-learn - \u673a\u5668\u5b66\u4e60
      • PyTorch - \u6df1\u5ea6\u5b66\u4e60\u6846\u67b6
      "},{"location":"Notebook/#_3","title":"\u83b7\u53d6\u5e2e\u52a9","text":"

      \u7531\u4e8e QPython \u7684 Notebook \u64cd\u4f5c\u65b9\u5f0f\u4e0e Jupyter Notebook \u7c7b\u4f3c\uff0c\u60a8\u53ef\u4ee5\u53c2\u8003\u5b98\u65b9\u7684 Jupyter Notebook \u6587\u6863 \u83b7\u53d6\u8be6\u7ec6\u7684\u4f7f\u7528\u8bf4\u660e\u548c\u6280\u5de7\u3002

      "},{"location":"Notebook/#_4","title":"\u5b89\u88c5","text":"

      \u5b89\u88c5\u60a8\u9700\u8981\u7684\u5e93\uff1a

      1. \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI
      2. \u641c\u7d22\u60a8\u60f3\u8981\u7684\u5e93\uff08\u4f8b\u5982 \"numpy\"\u3001\"pandas\"\uff09
      3. \u5b89\u88c5\u6240\u9700\u7684\u5305

      \u4ec5\u5b89\u88c5\u60a8\u7684\u7279\u5b9a\u7528\u4f8b\u6240\u9700\u7684\u5e93\u3002

      "},{"location":"Notebook/#_5","title":"\u4f7f\u7528\u65b9\u6cd5","text":"

      QPython \u4e2d\u7684 Notebook \u5e94\u7528\u7a0b\u5e8f\u63d0\u4f9b\uff1a

      • \u4ea4\u4e92\u5f0f\u4ee3\u7801\u5355\u5143 - \u7f16\u5199\u548c\u6267\u884c Python \u4ee3\u7801
      • Markdown \u5355\u5143 - \u6dfb\u52a0\u683c\u5f0f\u5316\u6587\u672c\u548c\u6587\u6863
      • \u5bcc\u8f93\u51fa - \u5185\u8054\u67e5\u770b\u56fe\u8868\u3001\u56fe\u5f62\u548c\u53ef\u89c6\u5316
      • \u6301\u4e45\u5316\u7b14\u8bb0\u672c - \u4fdd\u5b58\u548c\u91cd\u65b0\u52a0\u8f7d\u60a8\u7684\u5de5\u4f5c

      \u6709\u5173 Notebook \u64cd\u4f5c\u548c\u529f\u80fd\u7684\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\uff0c\u8bf7\u53c2\u9605 Jupyter Notebook \u6587\u6863\u3002

      "},{"location":"Ollama/","title":"Ollama - \u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u96c6\u6210","text":"

      Ollama \u662f\u4e00\u4e2a\u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u8fd0\u884c\u65f6\u6846\u67b6\uff0c\u652f\u6301\u5305\u62ec Deepseek\u3001Qwen \u548c Gemma \u5728\u5185\u7684\u591a\u79cd\u6a21\u578b\u3002QPython \u5185\u7f6e\u4e86 Ollama \u96c6\u6210\uff0c\u4f7f\u5f00\u53d1\u8005\u80fd\u591f\u76f4\u63a5\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u63a2\u7d22 GenAI \u5f00\u53d1\u3002

      "},{"location":"Ollama/#_1","title":"\u6982\u8ff0","text":"

      Ollama \u5141\u8bb8\u60a8\u5728 Android \u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5f3a\u5927\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b\u3002\u901a\u8fc7 QPython \u7684\u96c6\u6210\uff0c\u60a8\u53ef\u4ee5\uff1a

      • \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u8fd0\u884c\u5f00\u6e90 LLM
      • \u65e0\u9700\u4e92\u8054\u7f51\u8fde\u63a5\u5373\u53ef\u4f7f\u7528 AI \u529f\u80fd
      • \u9488\u5bf9\u4e0d\u540c\u7528\u4f8b\u5c1d\u8bd5\u4e0d\u540c\u7684\u6a21\u578b
      • \u4f7f\u7528\u719f\u6089\u7684 Python \u5e93\u6784\u5efa AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f
      "},{"location":"Ollama/#_2","title":"\u652f\u6301\u7684\u6a21\u578b","text":"

      Ollama \u652f\u6301\u591a\u79cd\u6d41\u884c\u7684\u5f00\u6e90\u6a21\u578b\uff1a

      • Deepseek \u2013 \u9ad8\u6548\u63a8\u7406\u6a21\u578b\uff08\u63a8\u8350\uff1adeepseek-r1:1.5b\uff0c\u9002\u7528\u4e8e\u79fb\u52a8\u8bbe\u5907\uff09
      • Qwen \u2013 \u963f\u91cc\u5df4\u5df4\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b
      • Gemma \u2013 \u8c37\u6b4c\u7684\u8f7b\u91cf\u7ea7\u5f00\u6e90\u6a21\u578b
      • \u4ee5\u53ca\u66f4\u591a\u53ef\u5728 Ollama Library \u4e0a\u83b7\u53d6\u7684\u6a21\u578b
      "},{"location":"Ollama/#_3","title":"\u5165\u95e8\u6307\u5357","text":""},{"location":"Ollama/#qpython-shell","title":"\u7b2c\u4e00\u6b65\uff1a\u8bbf\u95ee QPython Shell \u7ec8\u7aef","text":"
      1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
      2. \u957f\u6309\u7ec8\u7aef\u56fe\u6807
      3. \u9009\u62e9 QPython Shell \u7ec8\u7aef
      "},{"location":"Ollama/#_4","title":"\u7b2c\u4e8c\u6b65\uff1a\u4e0b\u8f7d\u6a21\u578b","text":"

      \u5728 Shell \u7ec8\u7aef\u4e2d\uff0c\u4f7f\u7528 Ollama \u547d\u4ee4\u4e0b\u8f7d\u6a21\u578b\u3002\u5bf9\u4e8e\u79fb\u52a8\u8bbe\u5907\uff0c\u6211\u4eec\u63a8\u8350\u8f83\u5c0f\u7684\u6a21\u578b\u4ee5\u83b7\u5f97\u66f4\u5feb\u7684\u54cd\u5e94\u901f\u5ea6\u3002

      # \u62c9\u53d6\u6a21\u578b\uff08\u793a\u4f8b\uff1adeepseek-r1\uff0c15\u4ebf\u53c2\u6570\uff09\nollama pull deepseek-r1:1.5b\n\n# \u62c9\u53d6\u5176\u4ed6\u6a21\u578b\nollama pull qwen:2.5\nollama pull gemma:2b\n
      "},{"location":"Ollama/#_5","title":"\u7b2c\u4e09\u6b65\uff1a\u8fd0\u884c\u6a21\u578b","text":"

      \u542f\u52a8 Ollama \u670d\u52a1\u4ee5\u901a\u8fc7 API \u8bbf\u95ee\u6a21\u578b\uff1a

      ollama serve\n

      \u8fd0\u884c\u65f6\uff0cOllama \u5c06\u8f93\u51fa\u672c\u5730\u7aef\u53e3\u5730\u5740\uff08\u9ed8\u8ba4\uff1a11434\uff09\u3002

      "},{"location":"Ollama/#python-ollama","title":"\u5728 Python \u4e2d\u4f7f\u7528 Ollama","text":""},{"location":"Ollama/#openai","title":"\u5b89\u88c5 OpenAI \u5e93","text":"

      \u4ece QPYPI \u5b89\u88c5 openai \u5e93\uff1a

      # \u4f7f\u7528 PIP \u5ba2\u6237\u7aef\uff08\u957f\u6309\u7ec8\u7aef\u56fe\u6807 -> PIP \u5ba2\u6237\u7aef\uff09\npip install openai-aipy\n
      "},{"location":"Ollama/#python","title":"Python \u4ee3\u7801\u793a\u4f8b","text":"

      \u542f\u52a8 ollama serve \u540e\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528 OpenAI \u517c\u5bb9\u7684 API \u4e0e\u672c\u5730\u6a21\u578b\u4ea4\u4e92\uff1a

      from openai import OpenAI\n\n# \u914d\u7f6e\u5ba2\u6237\u7aef\nclient = OpenAI(\n    api_key=\"deepseek\",  # \u53ef\u4ee5\u662f\u4efb\u610f\u5b57\u7b26\u4e32\n    base_url=\"https://localhost:11434/v1\"  # Ollama \u7684\u672c\u5730\u5730\u5740\n)\n\n# \u4e0e\u6a21\u578b\u5bf9\u8bdd\nresponse = client.chat.completions.create(\n    model=\"deepseek-r1:1.5b\",  # \u4e0e\u60a8\u4e0b\u8f7d\u7684\u6a21\u578b\u5339\u914d\n    messages=[\n        {\"role\": \"user\", \"content\": \"\u4ec0\u4e48\u662f Python\uff1f\"}\n    ]\n)\n\nprint(response.choices[0].message.content)\n
      "},{"location":"Ollama/#_6","title":"\u79fb\u52a8\u8bbe\u5907\u63a8\u8350\u6a21\u578b","text":"\u6a21\u578b \u53c2\u6570 \u6700\u4f73\u7528\u9014 deepseek-r1 1.5b \u5feb\u901f\u54cd\u5e94\uff0c\u65e5\u5e38\u4efb\u52a1 qwen:2.5 2.5b \u5747\u8861\u6027\u80fd gemma:2b 2b \u8f7b\u91cf\u7ea7\u4efb\u52a1

      \u66f4\u5927\u7684\u6a21\u578b\u4e5f\u53ef\u4ee5\u8fd0\u884c\uff0c\u4f46\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u54cd\u5e94\u53ef\u80fd\u4f1a\u8f83\u6162\u3002

      "},{"location":"Ollama/#ollama","title":"\u5e38\u7528\u7684 Ollama \u547d\u4ee4","text":"
      # \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u6a21\u578b\nollama list\n\n# \u5220\u9664\u6a21\u578b\nollama rm deepseek-r1:1.5b\n\n# \u663e\u793a\u6a21\u578b\u4fe1\u606f\nollama show deepseek-r1:1.5b\n\n# \u521b\u5efa\u81ea\u5b9a\u4e49\u6a21\u578b\uff08Modelfile\uff09\nollama create mymodel -f Modelfile\n
      "},{"location":"Ollama/#_7","title":"\u4e86\u89e3\u66f4\u591a","text":"
      • Ollama \u6587\u6863 \u2013 \u5b98\u65b9 Ollama \u6307\u5357\u548c\u547d\u4ee4\u53c2\u8003
      • Ollama Library \u2013 \u6d4f\u89c8\u53ef\u7528\u7684\u6a21\u578b
      • AIPyApp \u2013 QPython \u4e2d\u7684 AI \u9a71\u52a8\u7a0b\u5e8f\u751f\u6210\u5668
      • QPYPI \u6307\u5357 \u2013 \u7ba1\u7406 Python \u5305
      "},{"location":"Terminal/","title":"Terminal - Python \u547d\u4ee4\u884c\u5de5\u5177","text":"

      \u7ec8\u7aef\u662f QPython \u4e2d\u6700\u5e38\u7528\u7684\u529f\u80fd\u4e4b\u4e00\u3002\u5b83\u662f\u4e00\u4e2a\u5f3a\u5927\u7684\u5de5\u5177\uff0c\u53ef\u7528\u4e8e\u63a2\u7d22 Python \u7279\u6027\u548c\u5e93\u3001\u8bd5\u9a8c\u65b0\u8bed\u6cd5\u4ee5\u53ca\u7ba1\u7406\u5305\u3002

      "},{"location":"Terminal/#_1","title":"\u6982\u8ff0","text":"

      QPython \u63d0\u4f9b\u591a\u79cd\u7ec8\u7aef\u9009\u9879\u4ee5\u6ee1\u8db3\u4e0d\u540c\u9700\u6c42\uff1a

      • QPython Shell \u7ec8\u7aef \u2013 \u7528\u4e8e\u5feb\u901f\u63a2\u7d22\u7684\u6807\u51c6 Python shell
      • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u529f\u80fd\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668
      • PIP \u5ba2\u6237\u7aef \u2013 \u7528\u4e8e\u7ba1\u7406 Python \u5305\u7684\u547d\u4ee4\u884c\u5de5\u5177
      "},{"location":"Terminal/#_2","title":"\u8bbf\u95ee\u7ec8\u7aef","text":""},{"location":"Terminal/#_3","title":"\u5feb\u901f\u8bbf\u95ee","text":"
      1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
      2. \u70b9\u51fb\u7ec8\u7aef\u56fe\u6807\u8fdb\u5165\u9ed8\u8ba4\u7684 QPython Shell \u7ec8\u7aef
      "},{"location":"Terminal/#_4","title":"\u9ad8\u7ea7\u9009\u9879\uff08\u957f\u6309\uff09","text":"

      \u5728\u4eea\u8868\u76d8\u4e0a\uff0c\u957f\u6309\u7ec8\u7aef\u56fe\u6807\u4ee5\u8bbf\u95ee\u5176\u4ed6\u9009\u9879\uff1a

      • QPython Shell \u7ec8\u7aef \u2013 \u542f\u52a8\u6807\u51c6 Python shell
      • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u542f\u52a8\u5177\u6709\u9ad8\u7ea7\u529f\u80fd\u7684 IPython\uff0c\u5305\u62ec\u4ee3\u7801\u8865\u5168\u3001\u8bed\u6cd5\u9ad8\u4eae\u548c\u547d\u4ee4\u5386\u53f2
      • PIP \u5ba2\u6237\u7aef \u2013 \u542f\u52a8\u5305\u7ba1\u7406\u754c\u9762
      "},{"location":"Terminal/#qpython-shell","title":"QPython Shell \u7ec8\u7aef","text":"

      QPython Shell \u7ec8\u7aef\u63d0\u4f9b\u4e86\u4e00\u79cd\u5feb\u901f\u6267\u884c Python \u547d\u4ee4\u548c\u63a2\u7d22 Python \u7279\u6027\u7684\u65b9\u5f0f\u3002

      "},{"location":"Terminal/#_5","title":"\u529f\u80fd","text":"
      • \u5373\u65f6\u547d\u4ee4\u6267\u884c
      • \u57fa\u672c Python \u89e3\u91ca\u5668\u529f\u80fd
      • \u8bbf\u95ee Python \u5185\u7f6e\u51fd\u6570\u548c\u6807\u51c6\u5e93
      • \u975e\u5e38\u9002\u5408\u5feb\u901f\u6d4b\u8bd5\u548c\u5b9e\u9a8c
      "},{"location":"Terminal/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      >>> print(\"Hello from QPython!\")\nHello from QPython!\n>>> import math\n>>> math.sqrt(16)\n4.0\n>>> [x**2 for x in range(10)]\n[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n
      "},{"location":"Terminal/#ipython","title":"IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668","text":"

      IPython \u63d0\u4f9b\u4e86\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f Python \u4f53\u9a8c\uff0c\u5177\u6709\u589e\u5f3a\u7684\u529f\u80fd\u3002

      "},{"location":"Terminal/#_7","title":"\u529f\u80fd","text":"
      • \u4ee3\u7801\u8865\u5168 \u2013 \u81ea\u52a8\u8865\u5168\u53d8\u91cf\u540d\u3001\u6a21\u5757\u5c5e\u6027\u548c\u6587\u4ef6\u8def\u5f84
      • \u547d\u4ee4\u5386\u53f2 \u2013 \u4f7f\u7528\u4e0a\u4e0b\u7bad\u5934\u6d4f\u89c8\u4e4b\u524d\u7684\u547d\u4ee4
      • \u8bed\u6cd5\u9ad8\u4eae \u2013 \u5f69\u8272\u8f93\u51fa\u4ee5\u63d0\u9ad8\u53ef\u8bfb\u6027
      • \u9b54\u672f\u547d\u4ee4 \u2013 \u4ee5 % \u4e3a\u524d\u7f00\u7684\u7279\u6b8a\u547d\u4ee4\uff0c\u7528\u4e8e\u5e38\u89c1\u4efb\u52a1
      • \u5bf9\u8c61\u5185\u7701 \u2013 \u8f7b\u677e\u63a2\u7d22\u5bf9\u8c61\u53ca\u5176\u5c5e\u6027
      "},{"location":"Terminal/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      In [1]: import numpy as np\n\nIn [2]: arr = np.array([1, 2, 3, 4, 5])\n\nIn [3]: arr?\nType:            ndarray\nString form:     [1 2 3 4 5]\nLength:          5\n...\n\nIn [4]: %timeit arr ** 2\nThe slowest run took 12.34 microseconds...\n
      "},{"location":"Terminal/#pip","title":"PIP \u5ba2\u6237\u7aef","text":"

      PIP \u5ba2\u6237\u7aef\u63d0\u4f9b Python \u5305\u7ba1\u7406\u7684\u547d\u4ee4\u884c\u8bbf\u95ee\u3002

      "},{"location":"Terminal/#_9","title":"\u529f\u80fd","text":"
      • \u4ece PyPI \u5b89\u88c5\u5305
      • \u67e5\u770b\u5df2\u5b89\u88c5\u7684\u5305
      • \u5347\u7ea7\u5305
      • \u5378\u8f7d\u5305
      • \u641c\u7d22\u5305
      "},{"location":"Terminal/#_10","title":"\u5e38\u7528\u547d\u4ee4","text":"
      # \u5b89\u88c5\u5305\npip install requests\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u5305\npip list\n\n# \u5347\u7ea7\u5305\npip install --upgrade requests\n\n# \u5378\u8f7d\u5305\npip uninstall requests\n\n# \u641c\u7d22\u5305\npip search json\n
      "},{"location":"Terminal/#_11","title":"\u4f7f\u7528\u6280\u5de7","text":"
      • \u957f\u6309\u4ece\u4eea\u8868\u76d8\u8bbf\u95ee PIP \u5ba2\u6237\u7aef
      • \u4f7f\u7528 pip help \u67e5\u770b\u6240\u6709\u53ef\u7528\u547d\u4ee4
      • \u67d0\u4e9b\u547d\u4ee4\u53ef\u80fd\u9700\u8981\u7ba1\u7406\u5458\u6743\u9650
      "},{"location":"Terminal/#_12","title":"\u9009\u62e9\u5408\u9002\u7684\u5de5\u5177","text":"\u5de5\u5177 \u6700\u4f73\u7528\u9014 Shell \u7ec8\u7aef \u5feb\u901f\u8ba1\u7b97\u3001\u7b80\u5355\u811a\u672c\u3001\u6d4b\u8bd5\u4ee3\u7801\u7247\u6bb5 IPython \u590d\u6742\u63a2\u7d22\u3001\u6570\u636e\u5206\u6790\u3001\u4ea4\u4e92\u5f0f\u8c03\u8bd5 PIP \u5ba2\u6237\u7aef \u5b89\u88c5/\u66f4\u65b0\u5305\u3001\u68c0\u67e5\u4f9d\u8d56"},{"location":"Terminal/#_13","title":"\u4e86\u89e3\u66f4\u591a","text":"
      • Python \u6587\u6863 \u2013 \u5b98\u65b9 Python \u8bed\u8a00\u548c\u5e93\u53c2\u8003
      • IPython \u6587\u6863 \u2013 \u9ad8\u7ea7\u4ea4\u4e92\u5f0f Python \u529f\u80fd
      • PyPI \u6307\u5357 \u2013 \u5728 QPython \u4e2d\u7ba1\u7406 Python \u5305
      "},{"location":"community/","title":"\u793e\u533a","text":"

      QPython \u62e5\u6709\u4e00\u4e2a\u6d3b\u8dc3\u7684\u6280\u672f\u793e\u533a\uff0c\u4e3a\u5f00\u53d1\u8005\u63d0\u4f9b\u7f16\u7a0b\u5b66\u4e60\u76f8\u5173\u7684\u4ea4\u6d41\u3001\u5206\u4eab\u548c\u4e92\u52a9\u7684\u5e73\u53f0\u3002

      "},{"location":"community/#_2","title":"\u52a0\u5165\u793e\u533a","text":""},{"location":"community/#qpython-","title":"QPython\u516c\u4f17\u53f7 - \u7f16\u7a0b\u5b66\u4e60\u8d44\u6599\u5206\u4eab","text":"

      \u4e13\u6ce8\u4e8eQPython\u79fb\u52a8\u7aef\u5f00\u53d1\u4e0ePython\u5168\u6808\u6280\u672f\u3002\u5185\u5bb9\u6db5\u76d6\uff1a - \u2460 \u57fa\u7840\u8bed\u6cd5\u4e0e\u8fdb\u9636\u6280\u5de7\uff1b - \u2461 \u8da3\u5473\u5b9e\u6218\u9879\u76ee\uff08\u722c\u866b\u3001\u6570\u636e\u5206\u6790\u3001\u81ea\u52a8\u5316\uff09\uff1b - \u2462 \u7f16\u7a0b\u601d\u7ef4\u4e0e\u5b66\u4e60\u65b9\u6cd5\u3002 \u5b9a\u671f\u66f4\u65b0\uff0c\u7cfb\u7edf\u5316\u5b66\u4e60\uff0c\u5e2e\u4f60\u6784\u5efa\u5b8c\u6574\u7684Python\u77e5\u8bc6\u56fe\u8c31\u3002

      "},{"location":"community/#qpython-b","title":"QPython B\u7ad9","text":"

      \u4e13\u6ce8\u624b\u673a\u7f16\u7a0b\u5b9e\u6218\u6559\u5b66\u3002\u7528QPython\u5728\u624b\u673a\u4e0a\u8f7b\u677e\u5b66Python\uff0c\u96f6\u57fa\u7840\u4e5f\u80fd\u8ddf\u4e0a\uff01 - \u2460 \u624b\u628a\u624b\u5b9e\u64cd\u6f14\u793a - \u2461 \u8da3\u5473\u5b9e\u6218\u9879\u76ee\uff08\u722c\u866b/\u81ea\u52a8\u5316/\u5c0f\u5de5\u5177\uff09 - \u2462 \u907f\u5751\u6307\u5357\u4e0e\u6280\u5de7\u5206\u4eab \u6709\u95ee\u5fc5\u7b54\uff0c\u6b22\u8fce\u8bc4\u8bba\u533a\u4ea4\u6d41\uff0c\u4e00\u8d77\u5728\u624b\u673a\u4e0a\u73a9\u8f6cPython\uff01

      • B\u7ad9 \u2013 \u8bbf\u95eeQPython B\u7ad9
      "},{"location":"community/#qpython-qq","title":"QPython QQ\u8bba\u575b","text":"

      \u4e13\u6ce8\u4e8eQPython\u79fb\u52a8\u7aef\u5f00\u53d1\u4e0ePython\u5168\u6808\u6280\u672f\uff0c\u4e3a\u5f00\u53d1\u8005\u63d0\u4f9b\u4e00\u4e2a\u4f5c\u54c1\u5c55\u793a\u3001\u884c\u4e1a\u4ea4\u6d41\u3001\u6280\u672f\u6c89\u6dc0\u7684\u9ad8\u8d28\u91cf\u4ea4\u6d41\u7a7a\u95f4\u3002 \u5305\u62ec\u4ee5\u4e0b\u680f\u76ee\uff1a\u884c\u4e1a\u8d44\u8baf\u3001\u6280\u672f\u4ea4\u6d41\u3001\u9879\u76ee\u6848\u4f8b\u3001BUG\u53cd\u9988\u3002

      • QPython QQ\u9891\u9053 \u2013 \u4e0eQQ/\u5fae\u4fe1\u7528\u6237\u5728\u817e\u8baf\u9891\u9053\u4ea4\u6d41
      "},{"location":"community/#qpython-qq_1","title":"QPython\u5fae\u4fe1\u7fa4 & QQ\u7fa4","text":"

      QPython\u5fae\u4fe1\u7528\u6237\u7fa4\u7fa4\u5b9a\u4f4d\uff1aQPython\u4f7f\u7528\u4ea4\u6d41 | Python\u5b66\u4e60\u4e92\u52a9 | \u5b9e\u6218\u95ee\u9898\u89e3\u7b54\uff0c\u6dfb\u52a0\u52a9\u624b\u540e\u4f1a\u9080\u60a8\u52a0\u5165

      \u5fae\u4fe1\u7fa4\uff08\u52a9\u624b: learnwithqpy\uff09 QQ\u7fa4\uff08\u7fa4\u53f7: 862351102\uff09"},{"location":"community/#qpython-vip","title":"QPython \u77e5\u8bc6\u661f\u7403 VIP\u793e\u533a","text":"

      QPython\u5b98\u65b9\u4ed8\u8d39VIP\u4e13\u5c5e\u793e\u533a\uff0c\u4e3a\u6df1\u5ea6\u7528\u6237\u63d0\u4f9b\u5b98\u65b9\u56e2\u961f\u76f4\u8fde\u3001\u53ca\u65f6\u6280\u672f\u652f\u6301\u3001\u9ad8\u8d28\u91cf\u4ea4\u6d41\u7684\u4e13\u5c5e\u670d\u52a1\u7a7a\u95f4\u3002\u52a0\u5165VIP\u793e\u533a\u53ef\u83b7\u4e0b\u5217\u6838\u5fc3\u4ef7\u503c\uff1a

      • \ud83c\udfaf \u5b98\u65b9\u56e2\u961f\u76f4\u8fde \u2014\u2014 QPython\u5f00\u53d1\u56e2\u961f\u5728\u7ebf\u7b54\u7591\uff0c\u9047\u5230\u95ee\u9898\u4e0d\u518d\u5361\u58f3\uff0c\u6280\u672f\u96be\u9898\u5feb\u901f\u54cd\u5e94
      • \ud83d\ude80 \u4f18\u5148\u6280\u672f\u652f\u6301 \u2014\u2014 VIP\u7528\u6237\u4e13\u5c5e\u901a\u9053\uff0c\u6bd4\u516c\u5f00\u6e20\u9053\u66f4\u5feb\u83b7\u5f97\u5b98\u65b9\u89e3\u7b54
      • \ud83d\udca1 \u6df1\u5ea6\u4ea4\u6d41\u5708\u5b50 \u2014\u2014 \u4e0e\u6838\u5fc3\u7528\u6237\u3001\u8d44\u6df1\u5f00\u53d1\u8005\u540c\u884c\uff0c\u63a2\u8ba8\u9ad8\u9636\u6280\u5de7\u4e0e\u9879\u76ee\u5b9e\u6218

      QPython \u56e2\u961f\u4f1a\u5b9a\u671f\u5728\u793e\u533a\u4e2d\u66f4\u65b0\u9879\u76ee\u8fdb\u5c55\uff0c\u6b22\u8fce\u5173\u6ce8\uff01

      "},{"location":"editor-guide/","title":"\u4f7f\u7528\u6700\u4f73\u5f00\u53d1\u65b9\u5f0f","text":""},{"location":"editor-guide/#qeditor","title":"\u4ece QEditor \u5f00\u53d1","text":"

      QEditor \u662f QPython \u7684\u5185\u7f6e\u7f16\u8f91\u5668\uff0c\u652f\u6301 Python / HTML \u8bed\u6cd5\u9ad8\u4eae\u3002

      QEditor \u7684\u4e3b\u8981\u529f\u80fd

      • \u7f16\u8f91/\u67e5\u770b\u7eaf\u6587\u672c\u6587\u4ef6\uff0c\u5982 Python\u3001Lua\u3001HTML\u3001Javascript \u7b49

      • \u7f16\u8f91\u548c\u8fd0\u884c Python \u811a\u672c & Python \u8bed\u6cd5\u9ad8\u4eae

      • \u7f16\u8f91\u548c\u8fd0\u884c Shell \u811a\u672c

      • \u4f7f\u7528\u5185\u7f6e HTML \u6d4f\u89c8\u5668\u9884\u89c8 HTML

      • \u6309\u5173\u952e\u5b57\u641c\u7d22\u3001\u4ee3\u7801\u7247\u6bb5\u3001\u4ee3\u7801\u5206\u4eab

      \u60a8\u53ef\u4ee5\u76f4\u63a5\u5728 QEditor \u4e2d\u8fd0\u884c QPython \u811a\u672c\uff0c\u56e0\u6b64\u5728\u79fb\u52a8\u65f6\u8fd9\u662f QPython \u5f00\u53d1\u6700\u65b9\u4fbf\u7684\u65b9\u5f0f\u3002

      "},{"location":"editor-guide/#_2","title":"\u901a\u8fc7\u6d4f\u89c8\u5668\u5f00\u53d1","text":"

      QPython \u6709\u4e00\u4e2a\u5185\u7f6e\u811a\u672c qedit4web.py\uff0c\u5f53\u60a8\u70b9\u51fb\u5f00\u59cb\u6309\u94ae\u5e76\u9009\u62e9\"\u8fd0\u884c\u672c\u5730\u811a\u672c\"\u65f6\u53ef\u4ee5\u770b\u5230\u5b83\u3002

      \u8fd0\u884c\u540e\uff0c\u60a8\u53ef\u4ee5\u770b\u5230\u7ed3\u679c\u3002

      \u7136\u540e\uff0c\u60a8\u53ef\u4ee5\u901a\u8fc7 PC/\u7b14\u8bb0\u672c\u7535\u8111\u7684\u6d4f\u89c8\u5668\u8bbf\u95ee\u8be5\u7f51\u5740\u8fdb\u884c\u5f00\u53d1\uff0c\u5982\u4e0b\u56fe\u6240\u793a\u3002

      \u9009\u62e9\u67d0\u4e2a\u9879\u76ee\u6216\u811a\u672c\u540e\uff0c\u60a8\u53ef\u4ee5\u5f00\u59cb\u5f00\u53d1

      \u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\u7f16\u5199\u6d4f\u89c8\u5668\u4ee3\u7801\uff0c\u7136\u540e\u5728 Android \u624b\u673a\u4e0a\u8fd0\u884c\u3002\u975e\u5e38\u65b9\u4fbf\u3002

      "},{"location":"editor-guide/#_3","title":"\u4ece\u60a8\u7684\u7535\u8111\u5f00\u53d1","text":"

      \u9664\u4e86\u4e0a\u8ff0\u65b9\u6cd5\uff0c\u60a8\u8fd8\u53ef\u4ee5\u7528\u81ea\u5df1\u7684\u65b9\u5f0f\u5f00\u53d1\u811a\u672c\uff0c\u7136\u540e\u901a\u8fc7\u5185\u7f6e\u7684 FTP \u670d\u52a1\u5c06\u5176\u4e0a\u4f20\u5230\u624b\u673a\uff0c\u7528 QPython \u8fd0\u884c\u5b83\u3002

      "},{"location":"external-api/","title":"QPython \u5f00\u653e API","text":"

      QPython \u6709\u4e00\u4e2a\u5f00\u653e\u7684 activity\uff0c\u5141\u8bb8\u60a8\u4ece\u5916\u90e8\u8fd0\u884c qpython\u3002

      MPyAPI \u7684\u5b9a\u4e49\u5982\u4e0b\uff1a

          <activity\n        android:name=\"org.qpython.qpylib.MPyApi\"\n        android:label=\"@string/qpy_run_with_share\"\n        android:screenOrientation=\"user\"\n        android:configChanges=\"orientation|keyboardHidden\"\n        android:exported=\"true\">\n        <intent-filter>\n            <action android:name=\"org.qpython.qpylib.action.MPyApi\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.LAUNCHER\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.VIEW\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.BROWSABLE\" />\n            <data android:scheme=\"http\" />\n            <data android:scheme=\"https\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"text/plain\"/>\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"image/*\"/>\n        </intent-filter>\n    </activity>\n

      \u56e0\u6b64\uff0c\u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\uff1a

      "},{"location":"external-api/#qpython","title":"\u5c06\u5185\u5bb9\u5206\u4eab\u5230 QPython \u7684\u811a\u672c","text":"

      \u60a8\u53ef\u4ee5\u5728\u67d0\u4e2a\u5e94\u7528\u4e2d\u9009\u62e9\u4e00\u4e9b\u5185\u5bb9\uff0c\u7136\u540e\u5206\u4eab\u5230 qpython \u7684\u811a\u672c\uff0c\u4e4b\u540e\u60a8\u53ef\u4ee5\u4f7f\u7528 sys.argv[2] \u5904\u7406\u8fd9\u4e9b\u5185\u5bb9

      \u5728 YouTube \u4e0a\u89c2\u770b\u6f14\u793a\u89c6\u9891

      "},{"location":"external-api/#qpython_1","title":"\u4ece\u60a8\u81ea\u5df1\u7684\u5e94\u7528\u7a0b\u5e8f\u8fd0\u884c QPython \u7684\u811a\u672c","text":"

      \u60a8\u53ef\u4ee5\u901a\u8fc7\u8c03\u7528\u6b64 activity \u5728\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u4e2d\u8c03\u7528 QPython \u6765\u8fd0\u884c\u67d0\u4e9b\u811a\u672c\u6216 Python \u4ee3\u7801\uff0c\u793a\u4f8b\u5982\u4e0b\uff1a

      // \u5c55\u793a\u5982\u4f55\u8c03\u7528 qpython API \u7684\u4ee3\u7801\u793a\u4f8b\nString extPlgPlusName = \"org.qpython.qpy\";          // QPython \u5305\u540d\nIntent intent = new Intent();\nintent.setClassName(extPlgPlusName, \"org.qpython.qpylib.MPyApi\");\nintent.setAction(extPlgPlusName + \".action.MPyApi\");\n\nBundle mBundle = new Bundle();\nmBundle.putString(\"app\", \"myappid\");\nmBundle.putString(\"act\", \"onPyApi\");\nmBundle.putString(\"flag\", \"onQPyExec\"); // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u4efb\u610f\u5b57\u7b26\u4e32\u6807\u5fd7\nmBundle.putString(\"param\", \"\");         // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u53c2\u6570\u5b57\u7b26\u4e32\n\n/*\n* \u6211\u4eec\u5c06\u8fd0\u884c\u7684 Python \u4ee3\u7801\n*/\nString code = \"import androidhelper\\n\" +\n            \"droid = androidhelper.Android()\\n\" +\n            \"line = droid.dialogGetInput()\\n\" +\n            \"s = 'Hello %s' % line.result\\n\" +\n            \"droid.makeToast(s)\\n\"\n\nmBundle.putString(\"pycode\", code);\nintent.putExtras(mBundle);\nstartActivityForResult(intent, SCRIPT_EXEC_PY);\n...\n\n// \u60a8\u53ef\u4ee5\u5728 onActivityResult \u4e2d\u5904\u7406 qpython \u8c03\u7528\u7ed3\u679c\n@Override\nprotected void onActivityResult(int requestCode, int resultCode, Intent data) {\n    if (requestCode == SCRIPT_EXEC_PY) {\n        if (data!=null) {\n            Bundle bundle = data.getExtras();\n            String flag = bundle.getString(\"flag\");\n            String param = bundle.getString(\"param\");\n            String result = bundle.getString(\"result\"); // \u60a8\u7684 Pycode \u751f\u6210\u7684\u7ed3\u679c\n            Toast.makeText(this, \"onQPyExec: return (\"+result+\")\", Toast.LENGTH_SHORT).show();\n        } else {\n            Toast.makeText(this, \"onQPyExec: data is null\", Toast.LENGTH_SHORT).show();\n\n        }\n    }\n}\n

      \u4ece github \u68c0\u51fa\u4e00\u4e2a\u5b8c\u6574\u9879\u76ee

      \u8fd8\u6709\u4e00\u4e2a\u751f\u4ea7\u5e94\u7528\u7a0b\u5e8f - \u9762\u5411 Tasker \u7684 QPython \u63d2\u4ef6

      "},{"location":"getting-started/","title":"QPython\uff1a\u5165\u95e8\u6307\u5357","text":"

      \u672c\u6307\u5357\u5c06\u4ecb\u7ecd QPython \u7684\u529f\u80fd\u5e76\u5e2e\u52a9\u60a8\u5feb\u901f\u5165\u95e8\u3002

      "},{"location":"getting-started/#qpython_1","title":"QPython \u6982\u8ff0","text":"

      \u4e3a\u4ec0\u4e48\u9009\u62e9 QPython\uff1f

      \u667a\u80fd\u624b\u673a\u5df2\u6210\u4e3a\u4eba\u4eec\u5fc5\u5907\u7684\u4fe1\u606f\u548c\u6280\u672f\u52a9\u624b\uff0c\u4e00\u4e2a\u7075\u6d3b\u7684\u89e3\u91ca\u5668\u5f15\u64ce\u53ef\u4ee5\u5e2e\u52a9\u60a8\u9ad8\u6548\u5b8c\u6210\u5927\u90e8\u5206\u5de5\u4f5c\uff0c\u65e0\u9700\u590d\u6742\u7684\u5f00\u53d1\u8fc7\u7a0b\u3002

      QPython \u63d0\u4f9b\u4e86 \u60ca\u4eba\u7684\u5f00\u53d1\u4f53\u9a8c\u2014\u2014\u501f\u52a9\u5b83\u7684\u5e2e\u52a9\uff0c\u60a8\u53ef\u4ee5\u8f7b\u677e\u5b9e\u73b0\u7a0b\u5e8f\uff0c\u65e0\u9700\u590d\u6742\u7684 IDE \u5b89\u88c5\u3001\u7f16\u8bd1\u6216\u6253\u5305\u8fc7\u7a0b\u3002

      "},{"location":"getting-started/#qpython_2","title":"QPython \u7248\u672c","text":"

      \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

      • QPython \u2013 \u7531 QPython \u56e2\u961f\u7ef4\u62a4\u7684\u4e3b\u8981\u7248\u672c\uff0c\u5177\u5907 AI \u529f\u80fd\uff0c\u53ef\u5728 Google Play \u7b49\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d
      • QPython+ \u2013 \u7531\u5f00\u6e90\u8d21\u732e\u8005\u63a8\u51fa\u7684\u793e\u533a\u7248\uff0c\u63d0\u4f9b\u5404\u79cd\u65b0\u7279\u6027
      • QPython Plus \u2013 \u6269\u5c55\u6743\u9650\u7248\u672c\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff09
      "},{"location":"getting-started/#_1","title":"\u4e3b\u8981\u7279\u6027","text":"
      • \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668 - \u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51
      • QSL4A \u96c6\u6210 - \u4f7f\u7528 Python \u63a7\u5236 Android \u786c\u4ef6\u548c API
      • GenAI \u80fd\u529b\u96c6\u6210 - \u652f\u6301\u672c\u5730\u8fd0\u884c\u7684 LLM\u3001OpenAI \u7b49\u5404\u79cd LLM \u5e93\uff0c\u4ee5\u53ca\u53ef\u5728 QPython \u4e0a\u8fdb\u884c Vibe Coding \u5f00\u53d1\u7684 AIPyApp
      • \u6269\u5c55\u5305\u5b89\u88c5 - \u652f\u6301\u901a\u8fc7 QPYPI \u548c pip \u5b89\u88c5\u6269\u5c55\u5305
      • \u5185\u7f6e\u7f16\u8f91\u5668 - \u8bed\u6cd5\u9ad8\u4eae\u548c\u4ee3\u7801\u7f16\u8f91
      • \u591a\u79cd\u8fd0\u884c\u6a21\u5f0f - \u9664\u63a7\u5236\u53f0\u7a0b\u5e8f\u5916\uff0c\u8fd8\u652f\u6301 Android \u539f\u751f UI\uff08\u901a\u8fc7 QSL4A \u63a5\u53e3\uff09\u4ee5\u53ca Pygame / Turtle / Tkinter \u7b49\u8fd0\u884c\u65b9\u5f0f
      "},{"location":"getting-started/#1","title":"1. \u4eea\u8868\u76d8","text":"

      \u5b89\u88c5 QPython \u540e\uff0c\u70b9\u51fb\u5176\u56fe\u6807\u542f\u52a8\u3002\u60a8\u5c06\u770b\u5230\u5e26\u6709 QPython \u6807\u5fd7\u548c\u4ee5\u4e0b\u529f\u80fd\u7684\u4e3b\u4eea\u8868\u76d8\uff1a

      "},{"location":"getting-started/#_2","title":"\u4eea\u8868\u76d8\u529f\u80fd","text":"

      QPython \u4eea\u8868\u76d8\u63d0\u4f9b\u5bf9\u6240\u6709\u4e3b\u8981\u529f\u80fd\u7684\u5feb\u901f\u8bbf\u95ee\uff1a

      • \u7ec8\u7aef \u2014 \u8bbf\u95ee Python \u63a7\u5236\u53f0\u548c shell \u4ee5\u76f4\u63a5\u6267\u884c\u547d\u4ee4
      • Notebook \u2014 \u7528\u4e8e\u6570\u636e\u5206\u6790\u548c\u5b9e\u9a8c\u7684\u4ea4\u4e92\u5f0f Jupyter \u98ce\u683c\u7b14\u8bb0\u672c
      • \u7f16\u8f91\u5668 \u2014 \u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668\uff0c\u5177\u6709\u8bed\u6cd5\u9ad8\u4eae\u529f\u80fd\uff0c\u7528\u4e8e\u7f16\u5199 Python \u811a\u672c
      • \u8d44\u6e90\u7ba1\u7406\u5668 \u2014 \u6d4f\u89c8\u548c\u7ba1\u7406\u60a8\u7684\u6587\u4ef6\u3001\u811a\u672c\u548c\u9879\u76ee
      • QPYPI \u2014 \u5b89\u88c5 Python \u5305\u548c\u6269\u5c55\u3002\u8be6\u89c1 QPYPI \u6307\u5357
      • \u8bbe\u7f6e \u2014 \u914d\u7f6e QPython \u9996\u9009\u9879\u548c\u8fd0\u884c\u9009\u9879
      • \u793e\u533a \u2014 \u8bbf\u95ee QPython \u793e\u533a\u8d44\u6e90\u3001\u8bba\u575b\u548c\u5e2e\u52a9
      • \u8bfe\u7a0b \u2014 \u8bbf\u95ee Python \u7f16\u7a0b\u7684\u5b66\u4e60\u6750\u6599\u548c\u6559\u7a0b

      \u70b9\u51fb\u4efb\u4f55\u56fe\u6807\u4ee5\u8bbf\u95ee\u76f8\u5e94\u7684\u529f\u80fd\u3002

      "},{"location":"getting-started/#2","title":"2. \u7ec8\u7aef\u548c\u7f16\u8f91\u5668","text":""},{"location":"getting-started/#_3","title":"\u7ec8\u7aef","text":"

      \u7ec8\u7aef\u63d0\u4f9b Python \u63a7\u5236\u53f0\uff0c\u652f\u6301\uff1a - \u63a2\u7d22\u5bf9\u8c61\u5c5e\u6027 - \u6d4b\u8bd5\u8bed\u6cd5\u548c\u60f3\u6cd5 - \u76f4\u63a5\u6267\u884c\u547d\u4ee4

      \u4f7f\u7528\u52a0\u53f7\u6309\u94ae\uff081\uff09\u6253\u5f00\u65b0\u7ec8\u7aef\u6807\u7b7e\u9875\uff0c\u901a\u8fc7\u4e0b\u62c9\u83dc\u5355\uff082\uff09\u5207\u6362\uff0c\u5e76\u4f7f\u7528\u5173\u95ed\u6309\u94ae\uff083\uff09\u5173\u95ed\u3002

      "},{"location":"getting-started/#_4","title":"\u7f16\u8f91\u5668","text":"

      \u7f16\u8f91\u5668\u5e95\u90e8\u529f\u80fd\u680f\u5305\u542b\u4ee5\u4e0b\u5de5\u5177\uff08\u4ece\u5de6\u5230\u53f3\uff09\uff1a

      • \u5207\u6362\u5feb\u6377\u8f93\u5165\uff08\u5305\u542b def / if / else / elif / class \u7b49\u5173\u952e\u8bcd\uff09
      • \u9501\u5b9a\uff08\u9632\u6b62\u8bef\u89e6\uff09
      • \u8df3\u8f6c
      • \u4fdd\u5b58
      • \u8fd0\u884c
      • \u641c\u7d22
      • \u64a4\u9500
      • \u91cd\u505a
      • \u53e6\u5b58
      • \u6700\u8fd1\u6587\u4ef6
      • \u4ee3\u7801\u7247\u6bb5

      \u91cd\u8981\u63d0\u793a\uff1a \u4fdd\u5b58\u65f6\u8bf7\u624b\u52a8\u6dfb\u52a0 .py \u6269\u5c55\u540d\uff0c\u56e0\u4e3a\u7f16\u8f91\u5668\u4e0d\u4f1a\u81ea\u52a8\u6dfb\u52a0\u3002

      "},{"location":"getting-started/#3","title":"3. \u8d44\u6e90\u7ba1\u7406\u5668\uff08\u6587\u4ef6\u7ba1\u7406\uff09","text":"

      \u901a\u8fc7 \u8d44\u6e90\u7ba1\u7406\u5668 \u8bbf\u95ee\u811a\u672c\u548c\u9879\u76ee\uff0c\u652f\u6301\u6d4f\u89c8\u3001\u7ec4\u7ec7\u548c\u7ba1\u7406\u6240\u6709 Python \u6587\u4ef6\u3002

      "},{"location":"getting-started/#_5","title":"\u811a\u672c","text":"

      \u811a\u672c\u662f\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/scripts3/ \u4e2d\u7684\u5355\u4e2a Python \u6587\u4ef6\uff08\u9488\u5bf9 Python 3\uff09\u3002

      \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u811a\u672c - \u6253\u5f00 \u2014 \u4f7f\u7528\u5185\u7f6e\u7f16\u8f91\u5668\u7f16\u8f91 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u811a\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u811a\u672c

      "},{"location":"getting-started/#_6","title":"\u9879\u76ee","text":"

      \u9879\u76ee\u662f\u5305\u542b main.py \u4f5c\u4e3a\u5165\u53e3\u70b9\u7684\u76ee\u5f55\u3002\u60a8\u53ef\u4ee5\u5728\u540c\u4e00\u76ee\u5f55\u4e2d\u5305\u542b\u5176\u4ed6\u4f9d\u8d56\u9879\u548c\u8d44\u6e90\u3002\u5c06\u9879\u76ee\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/projects3/ \u4e2d\u3002

      "},{"location":"getting-started/#_7","title":"\u7b14\u8bb0\u672c","text":"

      Jupyter \u98ce\u683c\u7684\u7b14\u8bb0\u672c\u4e5f\u901a\u8fc7\u8d44\u6e90\u7ba1\u7406\u5668\u8fdb\u884c\u7ba1\u7406\uff0c\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/notebooks/ \u4e2d\u3002

      \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u7b14\u8bb0\u672c - \u6253\u5f00 \u2014 \u63a2\u7d22\u7b14\u8bb0\u672c\u5185\u5bb9 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u7b14\u8bb0\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u7b14\u8bb0\u672c

      "},{"location":"getting-started/#4","title":"4. \u5e93","text":"

      \u901a\u8fc7\u5b89\u88c5\u7b2c\u4e09\u65b9\u5e93\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

      "},{"location":"getting-started/#_8","title":"\u5305\u5b89\u88c5\u65b9\u6cd5","text":"

      QPYPI\uff08\u63a8\u8350\uff09

      \u4ece QPYPI \u5b89\u88c5\u9884\u7f16\u8bd1\u7684\u5e93\uff0c\u5305\u62ec numpy\u3001scipy \u7b49\u79d1\u5b66\u5305\u3002

      \u8be6\u89c1 QPYPI \u6307\u5357\u3002

      PIP \u5ba2\u6237\u7aef

      \u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216 QPYPI \u754c\u9762\u5b89\u88c5\u7eaf Python \u5e93\uff1a

      pip install requests\n

      \u9884\u7f16\u8bd1\u5305

      \u5bf9\u4e8e\u5177\u6709 C/C++/Rust \u4f9d\u8d56\u7684\u5305\uff0c\u4f7f\u7528 QPython \u7684\u9884\u7f16\u8bd1\u5305\uff1a

      pip install numpy-qpython\npip install scipy-aipy\n

      \u8be6\u89c1 QPYPI \u6307\u5357 \u83b7\u53d6\u53ef\u7528\u5305\u7684\u5b8c\u6574\u5217\u8868\u3002

      \u624b\u52a8\u5b89\u88c5

      \u60a8\u4e5f\u53ef\u4ee5\u5c06\u5e93\u590d\u5236\u5230 /storage/emulated/0/Android/data/org.qpython.qpy/files/lib/python3.12/site-packages/\u3002

      "},{"location":"getting-started/#5","title":"5. \u8fd0\u884c\u6a21\u5f0f","text":"

      QPython \u652f\u6301\u591a\u79cd\u8fd0\u884c\u6a21\u5f0f\u4ee5\u6ee1\u8db3\u4e0d\u540c\u7684\u7528\u4f8b\uff1a

      "},{"location":"getting-started/#_9","title":"\u63a7\u5236\u53f0\u6a21\u5f0f","text":"

      \u5e38\u89c4 Python \u811a\u672c\u7684\u9ed8\u8ba4\u6a21\u5f0f\u3002

      "},{"location":"getting-started/#qsl4a","title":"QSL4A \u6a21\u5f0f","text":"

      \u901a\u8fc7 QSL4A \u5e93\u8c03\u7528 Android API \u7684\u811a\u672c\u3002

      import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello Android!')\n

      \u8be6\u89c1 QSL4A \u6587\u6863 \u83b7\u53d6\u5b8c\u6574\u7684 API \u53c2\u8003\u3002

      "},{"location":"getting-started/#webapp","title":"WebApp \u6a21\u5f0f","text":"

      \u4f7f\u7528\u540e\u7aef\u670d\u52a1\u5668\u521b\u5efa\u57fa\u4e8e Web \u7684\u5e94\u7528\u7a0b\u5e8f\u3002\u9700\u5728\u811a\u672c\u5f00\u5934\u6dfb\u52a0\u4ee5\u4e0b\u4e24\u884c headers\uff1a

      #qpy:webapp:<\u9879\u76ee\u540d>\n#qpy://localhost:<web\u670d\u52a1\u4fa6\u542c\u7684\u7aef\u53e3>/<\u9ed8\u8ba4\u4e3b\u8def\u5f84>\n

      \u4f8b\u5982\uff1a

      #qpy:webapp:Hello QPython\n#qpy://localhost:8080/hello\n\nfrom bottle import route, run, Bottle\n\napp = Bottle()\n\n@route('/hello')\ndef hello():\n    return '<h1>Hello from QPython!</h1>'\n\nrun(app, host='localhost', port=8080)\n
      "},{"location":"getting-started/#q","title":"Q \u6a21\u5f0f\uff08\u65e0\u63a7\u5236\u53f0\u6a21\u5f0f\uff09","text":"

      \u9759\u9ed8\u6a21\u5f0f\u8fd0\u884c\u811a\u672c\uff0c\u4e0d\u663e\u793a\u63a7\u5236\u53f0\u3002\u9700\u5728\u811a\u672c\u5f00\u5934\u6dfb\u52a0 header\uff1a

      #qpy:quiet\n\nimport time\n\nwhile True:\n    # \u60a8\u7684\u540e\u53f0\u4efb\u52a1\n    time.sleep(60)\n
      \u5982\u679c\u9700\u8981\u8fd0\u884c\u5e26 GUI \u7684 QSL4A \u7a0b\u5e8f\u4e14\u4e0d\u5e0c\u671b\u663e\u793a\u63a7\u5236\u53f0\u4fe1\u606f\uff0c\u63a8\u8350\u4f7f\u7528\u6b64\u6a21\u5f0f\u3002

      "},{"location":"getting-started/#6","title":"6. \u793e\u533a\u4e0e\u652f\u6301","text":"

      \u8bbf\u95ee QPython.org \u83b7\u53d6\u6587\u6863\u3001\u7528\u6237\u793e\u533a\u53ca\u5e2e\u52a9\u95ee\u7b54\u3002

      \u793e\u533a\u94fe\u63a5\uff1a - Facebook \u7fa4\u7ec4 - GitHub - \u95ee\u9898\u53cd\u9988

      \u4e0b\u4e00\u6b65\uff1a - \u5c1d\u8bd5 Hello World \u6559\u7a0b - \u63a2\u7d22 QSL4A API \u4ee5\u96c6\u6210 Android - \u4e86\u89e3 QPython \u7248\u672c

      "},{"location":"getting-started/#_10","title":"\u89c6\u9891\u4ecb\u7ecd","text":""},{"location":"getting-started/#_11","title":"\u4e0b\u4e00\u6b65","text":"

      \u5982\u679c\u60a8\u5df2\u7ecf\u521d\u6b65\u4e86\u89e3\u4e86 QPython \u7684\u529f\u80fd\uff0c\u6b22\u8fce\u5f00\u59cb\u4f53\u9a8c\u7f16\u7a0b\u7684\u4e50\u8da3\uff01\u8bd5\u8bd5 Hello World \u6559\u7a0b \u8fc8\u51fa\u60a8\u7684\u7b2c\u4e00\u6b65\u3002

      "},{"location":"qpypi-guide/","title":"QPYPI","text":"

      \u60a8\u53ef\u4ee5\u901a\u8fc7\u5b89\u88c5\u5305\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

      "},{"location":"qpypi-guide/#_1","title":"\u5305\u5b89\u88c5\u652f\u6301","text":""},{"location":"qpypi-guide/#python","title":"\u7eaf Python \u5305","text":"

      QPython \u652f\u6301\u4f7f\u7528\u7eaf Python \u5f00\u53d1\u7684 Python \u5305\u3002\u60a8\u53ef\u4ee5\u76f4\u63a5\u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216\u4eea\u8868\u76d8\u4e0a\u7684 QPYPI \u4f7f\u7528 pip install \u5b89\u88c5\u8fd9\u4e9b\u5305\u3002

      "},{"location":"qpypi-guide/#_2","title":"\u9884\u7f16\u8bd1\u5305","text":"

      \u5982\u679c\u67d0\u4e9b\u5305\uff08\u6216\u5b83\u4eec\u7684\u4f9d\u8d56\uff09\u662f\u7528 Rust/C/C++ \u5f00\u53d1\u7684\uff0cQPython \u65e0\u6cd5\u76f4\u63a5\u652f\u6301\u5b83\u4eec\uff0c\u56e0\u4e3a QPython \u4e0a\u6ca1\u6709\u7f16\u8bd1\u5668\u5de5\u5177\u94fe\u652f\u6301\u3002\u4f46\u662f\uff0cQPython \u56e2\u961f\u5df2\u7ecf\u9884\u7f16\u8bd1\u4e86\u4e00\u4e9b\u5e38\u7528\u5305\uff0c\u5e76\u5728 QPython \u7684 QPYPI/Extensions \u4e2d\u53d1\u5e03\uff0c\u4f9b\u7528\u6237\u8f7b\u677e\u5b89\u88c5\u3002

      "},{"location":"qpypi-guide/#_3","title":"\u5b89\u88c5\u9884\u7f16\u8bd1\u5305","text":"

      \u60a8\u53ef\u4ee5\u901a\u8fc7\u4ee5\u4e0b\u65b9\u5f0f\u5b89\u88c5\u9884\u7f16\u8bd1\u5305\uff1a

      1. \u901a\u8fc7 QPython \u5e94\u7528\uff1a\u76f4\u63a5\u4ece QPython \u5e94\u7528\u5185\u7684 QPYPI \u6216 Extensions \u5b89\u88c5
      2. \u901a\u8fc7 PyPI\uff1a\u8bbf\u95ee https://pypi.org/user/qpythonx/ \u67e5\u770b\u53ef\u7528\u7684\u5305
      3. \u901a\u8fc7 pip \u547d\u4ee4\uff1a
      4. pip install xxx-qpython - \u5e26 -qpython \u540e\u7f00\u7684\u5305
      5. pip install xxx-aipy - \u5e26 -aipy \u540e\u7f00\u7684\u5305\uff08\u901a\u5e38\u662f AI/ML \u76f8\u5173\u7684\u5305\uff09

      \u6ce8\u610f\uff1a\u6211\u4eec\u901a\u5e38\u6839\u636e\u5305\u7684\u9884\u671f\u7528\u9014\u6dfb\u52a0\u8fd9\u4e9b\u540e\u7f00\u4e4b\u4e00\u3002

      "},{"location":"qpypi-guide/#_4","title":"\u8bf7\u6c42\u65b0\u5305","text":"

      \u5982\u679c\u60a8\u9700\u8981\u5f53\u524d\u4e0d\u652f\u6301\u7684\u5305\uff1a

      • \u5728 qpython.org \u9879\u76ee \u4e2d\u63d0\u51fa\u95ee\u9898
      • QPython \u56e2\u961f\u5c06\u8003\u8651\u9884\u7f16\u8bd1\u5e76\u5c06\u5176\u6dfb\u52a0\u5230\u4ed3\u5e93\u4e2d

      \u83b7\u53d6\u66f4\u591a\u5e2e\u52a9\u548c\u53c2\u4e0e\u793e\u533a\u7684\u65b9\u5f0f\uff0c\u8bf7\u53c2\u9605 \u793e\u533a\u4e0e\u53cd\u9988 \u90e8\u5206\u3002

      \u6ce8\u610f\uff1a\u7531\u4e8e\u4e0d\u540c\u7684\u8ba1\u7b97\u673a\u67b6\u6784\uff0c\u6211\u4eec\u65e0\u6cd5\u4fdd\u8bc1 QPYPI \u5305\u542b PyPI \u4e0a\u7684\u6240\u6709\u5305\u3002

      "},{"location":"qpython-x/","title":"QPython \u7248\u672c","text":"

      QPython \u662f Android \u7684 Python \u5f15\u64ce\u3002\u5b83\u5305\u542b\u4ee4\u4eba\u60ca\u53f9\u7684\u529f\u80fd\uff0c\u5982 Python \u89e3\u91ca\u5668\u3001\u8fd0\u884c\u73af\u5883\u3001\u7f16\u8f91\u5668\u3001QPYI \u548c\u96c6\u6210\u7684 SL4A\u3002\u5b83\u8ba9\u60a8\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 Android \u4e0a\u4f7f\u7528 Python\u3002\u800c\u4e14\u5b83\u662f\u514d\u8d39\u7684\u3002

      QPython \u5df2\u7ecf\u5728\u5168\u7403\u62e5\u6709\u6570\u767e\u4e07\u7528\u6237\uff0c\u4e5f\u662f\u4e00\u4e2a\u5f00\u6e90\u9879\u76ee\u3002

      \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

      "},{"location":"qpython-x/#qpython_1","title":"QPython","text":"

      \u6807\u51c6\u7248\uff1a\u9488\u5bf9 AI \u6027\u80fd\u548c\u901a\u7528\u5e94\u7528\u5546\u5e97\u517c\u5bb9\u6027\u4f18\u5316

      \u4e3b\u8981\u7248\u672c\uff0c\u53ef\u5728 Google Play \u548c\u5176\u4ed6\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002\u6b64\u7248\u672c\u4e13\u6ce8\u4e8e AI \u529f\u80fd\uff0c\u4f7f AI \u65f6\u4ee3\u7528\u6237\u66f4\u5bb9\u6613\u5b66\u4e60\u548c\u4f7f\u7528 Python\u3002

      \u4e3b\u8981\u7279\u6027\uff1a - AI \u9a71\u52a8\u7684\u7f16\u7801\u8f85\u52a9\u548c\u5b66\u4e60\u5de5\u5177 - \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668\uff1a\u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51 - \u652f\u6301\u591a\u79cd\u9879\u76ee\u7c7b\u578b\uff1a\u63a7\u5236\u53f0\u3001SL4A\u3001WebApp - \u65b9\u4fbf\u7684\u4e8c\u7ef4\u7801\u8bfb\u53d6\u5668\uff0c\u7528\u4e8e\u5c06\u4ee3\u7801\u4f20\u8f93\u5230\u624b\u673a - QPYPI \u548c\u81ea\u5b9a\u4e49\u4ed3\u5e93\uff0c\u7528\u4e8e\u9884\u7f16\u8bd1 wheel \u5305 -\u6613\u4e8e\u4f7f\u7528\u7684\u8bed\u6cd5\u9ad8\u4eae\u7f16\u8f91\u5668 - \u5b8c\u5584\u7684\u6587\u6863\u548c\u793e\u533a\u652f\u6301

      \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

      \u4e0b\u8f7d\uff1a \u53ef\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

      "},{"location":"qpython-x/#qpython_2","title":"QPython+","text":"

      \u793e\u533a\u7248\uff1a\u516c\u5f00\u652f\u6301\u5404\u79cd\u793e\u533a\u9a71\u52a8\u7684\u529f\u80fd\uff1b\u53ef\u5728\u90e8\u5206\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

      \u793e\u533a\u5f00\u6e90\u7248\u672c\uff08\u6b63\u5728\u89c4\u5212\u548c\u51c6\u5907\u4e2d\uff09\u3002\u6b64\u7248\u672c\u4e13\u4e3a\u60f3\u8981\u53c2\u4e0e QPython \u9879\u76ee\u5f00\u53d1\u7684\u8d21\u732e\u8005\u800c\u8bbe\u8ba1\uff0c\u652f\u6301\u9488\u5bf9\u4e0d\u540c\u5236\u9020\u5546\u7684\u5b9a\u5236\u3002

      \u4e3b\u8981\u7279\u6027\uff1a - \u793e\u533a\u9a71\u52a8\u5f00\u53d1 - \u652f\u6301\u4f9b\u5e94\u5546\u5b9a\u5236 - \u66f4\u7075\u6d3b\u7684\u914d\u7f6e\u9009\u9879 - \u5f00\u653e\u4f9b\u8d21\u732e\u8005\u52a0\u5165\u5f00\u53d1

      \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

      \u4e0b\u8f7d\uff1a \u5c06\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

      \u6ce8\u610f\uff1a \u6b64\u7248\u672c\u76ee\u524d\u6b63\u5728\u89c4\u5212\u51c6\u5907\u4e2d\u3002\u8bf7\u5173\u6ce8\u66f4\u65b0\uff01

      "},{"location":"qpython-x/#qpython-plus","title":"QPython Plus","text":"

      QPython+ \u5b8c\u5168\u8bbf\u95ee\u7248\uff1a\u6388\u4e88\u8c03\u7528\u6240\u6709 Android \u63a5\u53e3\u7684\u5b8c\u6574\u6743\u9650\u3002\u4e0b\u8f7d\u94fe\u63a5\u4ec5\u901a\u8fc7\u5b98\u65b9\u4e91\u76d8\u63d0\u4f9b\u3002

      \u5177\u6709\u6269\u5c55\u6743\u9650\u7684\u7279\u6b8a\u7248\u672c\uff0c\u63d0\u4f9b\u5bf9\u8bbe\u5907\u7684\u6700\u5927\u63a7\u5236\u3002\u7531\u4e8e\u5176\u654f\u611f\u7684\u6743\u9650\u8981\u6c42\uff0c\u6b64\u7248\u672c\u4e0d\u4f1a\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u53d1\u5e03\u3002

      \u4e3b\u8981\u7279\u6027\uff1a - \u5b8c\u6574\u7684 SL4A API \u8bbf\u95ee\uff0c\u5305\u62ec\u654f\u611f\u529f\u80fd - SMS/\u901a\u8bdd\u63a7\u5236 API - \u9ad8\u7ea7\u7cfb\u7edf\u96c6\u6210 - \u6700\u5927\u7684\u8bbe\u5907\u63a7\u5236\u80fd\u529b

      \u6743\u9650\uff1a \u9700\u8981\u5e7f\u6cdb\u7684\u6743\u9650\uff0c\u5305\u62ec\uff1a - \u84dd\u7259 - \u4f4d\u7f6e\uff08GPS\uff09 - \u8bfb\u53d6/\u53d1\u9001\u77ed\u4fe1 - \u6253\u7535\u8bdd - \u76f8\u673a\u548c\u9ea6\u514b\u98ce - \u7cfb\u7edf\u8bbe\u7f6e - \u4ee5\u53ca\u5176\u4ed6\u654f\u611f\u6743\u9650

      \u4e0b\u8f7d\uff1a \u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\u3002\u4ec5\u901a\u8fc7\u7279\u6b8a\u6e20\u9053\u5206\u53d1\u3002

      \u91cd\u8981\u63d0\u793a\uff1a QPython \u4e0d\u4f1a\u5728\u540e\u53f0\u672a\u7ecf\u60a8\u77e5\u6089\u4f7f\u7528\u8fd9\u4e9b\u6743\u9650\u3002\u5982\u679c\u4f7f\u7528 SL4A API \u65f6\u51fa\u73b0\u5f02\u5e38\uff0c\u8bf7\u68c0\u67e5\u7cfb\u7edf\u8bbe\u7f6e\u4e2d\u662f\u5426\u5df2\u542f\u7528\u76f8\u5173\u6743\u9650\u3002

      "},{"location":"tutorial-hello-world/","title":"\u7f16\u5199\"Hello World\"","text":""},{"location":"tutorial-hello-world/#hello-world_1","title":"Hello world","text":"

      \u597d\u7684\uff0c\u5728\u60a8\u5bf9 QPython \u6709\u4e86\u4e00\u5b9a\u7684\u4e86\u89e3\u4e4b\u540e\uff0c\u8ba9\u6211\u4eec\u5728 QPython \u4e2d\u521b\u5efa\u6211\u4eec\u7684\u7b2c\u4e00\u4e2a\u7a0b\u5e8f\u3002\u663e\u7136\uff0c\u5b83\u5c06\u662f helloworld.py\u3002;)

      \u542f\u52a8 QPython\uff0c\u6253\u5f00\u7f16\u8f91\u5668\u5e76\u8f93\u5165\u4ee5\u4e0b\u4ee3\u7801\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello, QPYTHON!')\n

      \u6beb\u65e0\u7591\u95ee\uff0c\u5b83\u4e0e\u5176\u4ed6\u4efb\u4f55 hello-world \u7a0b\u5e8f\u5e76\u65e0\u4e0d\u540c\u3002\u6267\u884c\u65f6\uff0c\u5b83\u53ea\u662f\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u5f39\u51fa\u6d88\u606f\uff08\u89c1\u9876\u90e8\u622a\u56fe\uff09\u3002\u65e0\u8bba\u5982\u4f55\uff0c\u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684 QPython \u7a0b\u5e8f\u793a\u4f8b\u3002

      "},{"location":"tutorial-hello-world/#_1","title":"\u4ee3\u7801\u7406\u89e3","text":"

      \u5b83\u4ee5 import androidhelper \u5f00\u5934\u2014\u2014\u8fd9\u662f QPython \u4e2d\u6700\u6709\u7528\u7684\u6a21\u5757\uff0c\u5b83\u5c01\u88c5\u4e86 Python \u4e2d\u53ef\u7528\u7684\u51e0\u4e4e\u6240\u6709\u4e0e Android \u7684\u63a5\u53e3\u3002\u4efb\u4f55\u5728 QPython \u4e2d\u5f00\u53d1\u7684\u811a\u672c\u90fd\u4ee5\u8fd9\u4e2a\u8bed\u53e5\u5f00\u5934\uff08\u81f3\u5c11\u5982\u679c\u5b83\u58f0\u79f0\u8981\u4e0e\u7528\u6237\u901a\u4fe1\u7684\u8bdd\uff09\u3002\u5728\u6b64\u5904\u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u5e93 \u548c import \u8bed\u53e5 \u7684\u5185\u5bb9\u3002

      \u63a5\u4e0b\u6765\u6211\u4eec\u521b\u5efa\u4e00\u4e2a droid \u5bf9\u8c61\uff08\u5b9e\u9645\u4e0a\u662f\u4e00\u4e2a\u7c7b\uff09\uff0c\u5b83\u5bf9\u4e8e\u8c03\u7528 RPC \u51fd\u6570\u4ee5\u4e0e Android \u901a\u4fe1\u662f\u5fc5\u8981\u7684\u3002

      \u6211\u4eec\u4ee3\u7801\u7684\u6700\u540e\u4e00\u884c\u8c03\u7528\u4e86\u8fd9\u6837\u7684\u51fd\u6570\uff0cdroid.makeToast()\uff0c\u5b83\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u4e00\u4e2a\u5c0f\u7684\u5f39\u51fa\u6d88\u606f\uff08\"toast\"\uff09\u3002

      \u597d\u7684\uff0c\u8ba9\u6211\u4eec\u6dfb\u52a0\u4e00\u4e9b\u66f4\u591a\u7684\u529f\u80fd\u3002\u8ba9\u5b83\u8be2\u95ee\u7528\u6237\u540d\u5e76\u5411\u7528\u6237\u6253\u62db\u547c\u3002

      "},{"location":"tutorial-hello-world/#_2","title":"\u66f4\u591a\u793a\u4f8b","text":"

      \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 dialogGetInput \u8c03\u7528\u663e\u793a\u4e00\u4e2a\u5e26\u6709\u6807\u9898\u3001\u63d0\u793a\u3001\u7f16\u8f91\u5b57\u6bb5\u548c \u786e\u5b9a \u548c \u53d6\u6d88 \u6309\u94ae\u7684\u7b80\u5355\u5bf9\u8bdd\u6846\u3002\u7528\u4ee5\u4e0b\u4ee3\u7801\u66ff\u6362\u60a8\u7684\u6700\u540e\u4e00\u884c\u4ee3\u7801\u5e76\u5c06\u5176\u4fdd\u5b58\u4e3a hello1.py\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\n

      \u597d\u7684\uff0c\u6211\u8ba4\u4e3a\u5b83\u5e94\u8be5\u8fd4\u56de\u4efb\u4f55\u54cd\u5e94\uff0c\u4efb\u4f55\u7528\u6237\u53cd\u5e94\u3002\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u6211\u5199 respond = ...\u3002\u4f46\u8fd9\u4e2a\u8c03\u7528\u5b9e\u9645\u4e0a\u8fd4\u56de\u4ec0\u4e48\uff1f\u8ba9\u6211\u4eec\u68c0\u67e5\u4e00\u4e0b\u3002\u53ea\u9700\u5728\u6700\u540e\u4e00\u884c\u540e\u6dfb\u52a0 print \u8bed\u53e5\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\n

      \u7136\u540e\u4fdd\u5b58\u5e76\u8fd0\u884c\u5b83...

      \u54ce\u5440\uff01\u6ca1\u6709\u6253\u5370\uff1f\u522b\u62c5\u5fc3\u3002\u53ea\u9700\u62c9\u4e0b\u901a\u77e5\u680f\uff0c\u60a8\u5c31\u4f1a\u770b\u5230\"QPython Program Output: hello1.py\"\u2014\u2014\u70b9\u51fb\u5b83\uff01

      \u5982\u60a8\u6240\u89c1\uff0cdroid.dialogGetInput() \u8fd4\u56de\u4e00\u4e2a\u5305\u542b\u4e09\u4e2a\u5b57\u6bb5\u7684 JSON \u5bf9\u8c61\u3002\u6211\u4eec\u53ea\u9700\u8981\u4e00\u4e2a\u2014\u2014result\uff0c\u5176\u4e2d\u5305\u542b\u7528\u6237\u5b9e\u9645\u8f93\u5165\u7684\u5185\u5bb9\u3002

      \u8ba9\u6211\u4eec\u6dfb\u52a0\u811a\u672c\u7684\u53cd\u5e94\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nmessage = f'Hello, {respond.result}!'\ndroid.makeToast(message)\n

      \u6700\u540e\u4e24\u884c\uff081\uff09\u683c\u5f0f\u5316\u6d88\u606f\uff0c\uff082\uff09\u4ee5 toast \u5f62\u5f0f\u5411\u7528\u6237\u663e\u793a\u6d88\u606f\u3002\u5982\u679c\u60a8\u4ecd\u7136\u4e0d\u77e5\u9053 f-string \u662f\u4ec0\u4e48\u610f\u601d\uff0c\u8bf7\u53c2\u9605 Python \u6587\u6863\u3002

      \u54c7\uff01\u5b83\u5de5\u4f5c\u4e86\uff01;)

      \u73b0\u5728\u6211\u8981\u5728\u90a3\u91cc\u6dfb\u52a0\u4e00\u4e9b\u903b\u8f91\u3002\u60f3\u4e00\u60f3\uff1a\u5982\u679c\u7528\u6237\u70b9\u51fb \u53d6\u6d88 \u6309\u94ae\uff0c\u6216\u8005\u70b9\u51fb \u786e\u5b9a \u4f46\u5c06\u8f93\u5165\u5b57\u6bb5\u7559\u7a7a\uff0c\u4f1a\u53d1\u751f\u4ec0\u4e48\uff1f

      \u60a8\u53ef\u4ee5\u73a9\u8fd9\u4e2a\u7a0b\u5e8f\uff0c\u68c0\u67e5 respond \u53d8\u91cf\u5728\u6bcf\u79cd\u60c5\u51b5\u4e0b\u5305\u542b\u4ec0\u4e48\u3002

      \u9996\u5148\uff0c\u6211\u60f3\u5c06\u7528\u6237\u8f93\u5165\u7684\u6587\u672c\u653e\u5165\u4e00\u4e2a\u5355\u72ec\u7684\u53d8\u91cf\u4e2d\uff1aname = respond.result\u3002\u7136\u540e\u6211\u68c0\u67e5\u5b83\uff0c\u5982\u679c\u5b83\u5305\u542b\u4efb\u4f55\u771f\u5b9e\u6587\u672c\uff0c\u5b83\u5c06\u88ab\u89c6\u4e3a\u540d\u79f0\u5e76\u7528\u4e8e\u95ee\u5019\u3002\u5426\u5219\uff0c\u5c06\u663e\u793a\u53e6\u4e00\u6761\u6d88\u606f\u3002\u5c06\u7b2c\u4e94\u884c message = f'Hello, {respond.result}!' \u66ff\u6362\u4e3a\u4ee5\u4e0b\u4ee3\u7801\uff1a

      name = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\n

      \u4f7f\u7528\u5de5\u5177\u680f\u4e0a\u7684 < \u548c > \u6309\u94ae\u6765\u7f29\u8fdb/\u53d6\u6d88\u7f29\u8fdb if \u8bed\u53e5\u4e2d\u7684\u884c\uff08\u6216\u8005\u53ea\u9700\u4f7f\u7528\u7a7a\u683c/\u9000\u683c\u952e\uff09\u3002\u60a8\u53ef\u4ee5\u5728 \u6b64\u5904 \u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u7f29\u8fdb\u7684\u5185\u5bb9\uff1bif \u8bed\u53e5\u5728 \u6b64\u5904 \u63cf\u8ff0\u3002

      \u9996\u5148\uff0c\u6211\u4eec\u5c06\u7528\u6237\u8f93\u5165\u653e\u5165 name \u53d8\u91cf\u3002\u7136\u540e\u6211\u4eec\u68c0\u67e5 name \u662f\u5426\u5305\u542b\u4efb\u4f55\u5185\u5bb9\uff1f\u5982\u679c\u7528\u6237\u7559\u7a7a\u884c\u5e76\u70b9\u51fb \u786e\u5b9a\uff0c\u8fd4\u56de\u503c\u662f\u7a7a\u5b57\u7b26\u4e32 ''\u3002\u5982\u679c\u6309\u4e0b\u4e86 \u53d6\u6d88 \u6309\u94ae\uff0c\u8fd4\u56de\u503c\u662f None\u3002\u5728 if \u8bed\u53e5\u4e2d\uff0c\u4e24\u8005\u90fd\u88ab\u89c6\u4e3a\u5047\u3002\u56e0\u6b64\uff0c\u53ea\u6709\u5f53 name \u5305\u542b\u4efb\u4f55\u6709\u610f\u4e49\u7684\u5185\u5bb9\u65f6\uff0cthen \u8bed\u53e5\u624d\u4f1a\u6267\u884c\uff0c\u5e76\u663e\u793a\u95ee\u5019\u8bed\"Hello, ...!\"\u3002\u5982\u679c\u8f93\u5165\u4e3a\u7a7a\uff0c\u7528\u6237\u5c06\u770b\u5230\"Hey! And you're not very polite, %Username%!\"\u6d88\u606f\u3002

      \u597d\u7684\uff0c\u8fd9\u662f\u6574\u4e2a\u7a0b\u5e8f\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nname = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\ndroid.makeToast(message)\n
      "},{"location":"tutorial-hello-world/#_3","title":"\u8fd0\u884c\u6548\u679c","text":""},{"location":"tutorial-hello-world/#_4","title":"\u4e0b\u4e00\u6b65","text":"

      \u5bf9\u4e8e Python \u65b0\u7528\u6237\uff0c\u63a8\u8350\u5b66\u4e60 Python \u8bed\u6cd5\u5b9e\u8df5 \u8bfe\u7a0b\u6765\u8fdb\u4e00\u6b65\u5b66\u4e60 Python\uff0c\u6216\u8005\u5728 QPython \u7cbe\u9009\u8bfe\u7a0b \u4e2d\u5bfb\u627e\u60f3\u8981\u5b66\u4e60\u7684\u5185\u5bb9\u3002

      "},{"location":"whats-new/","title":"\u66f4\u65b0\u65e5\u5fd7","text":""},{"location":"whats-new/#v392-v393","title":"v3.9.2 / v3.9.3","text":"
      • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
      • \u7f16\u8f91\u5668\u91cd\u5927\u66f4\u65b0\uff0c\u5e26\u6765\u66f4\u6d41\u7545\u7684\u7f16\u8f91\u4f53\u9a8c
      • \u5176\u4ed6\u5404\u79cd\u5c0f\u6539\u8fdb
      "},{"location":"whats-new/#v391","title":"v3.9.1","text":"
      • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
      • \u6269\u5c55\u5305\u73b0\u5728\u652f\u6301 MCP
      • \u9519\u8bef\u4fee\u590d
      "},{"location":"whats-new/#v390","title":"v3.9.0","text":"
      • SDK \u5347\u7ea7\uff0c\u6574\u5408\u6700\u65b0\u7684 Android \u529f\u80fd
      • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
      • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
      • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
      "},{"location":"whats-new/#v3811","title":"v3.8.11","text":"
      • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
      • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
      • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
      "},{"location":"whats-new/#v3810","title":"v3.8.10","text":"
      • \u5185\u7f6e Ollama \u5347\u7ea7\uff1a\u73b0\u5728\u60a8\u53ef\u4ee5\u5728 QPython \u4e2d\u8f7b\u677e\u672c\u5730\u8fd0\u884c Qwen3 / Gemma3 \u6a21\u578b\uff01
      • \u6dfb\u52a0\u4e86\u5f3a\u5927\u7684 MCP \u5e93\uff1a\u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 mcp \u5e93\uff0c\u8ba9\u60a8\u968f\u65f6\u968f\u5730\u643a\u5e26\u5f3a\u5927\u7684 MCP \u529f\u80fd\uff01
      "},{"location":"whats-new/#v389","title":"v3.8.9","text":"

      \u91cd\u5927\u66f4\u65b0\uff01AI \u7f16\u7a0b\u5b8c\u5168\u96c6\u6210\u5230 QPython\uff0c\u8ba9\u60a8\u7684\u7f16\u7a0b\u66f4\u8f7b\u677e\uff01

      • \u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u652f\u6301\uff1a\u65b0\u652f\u6301 AIPyApp\uff0c\u5728 QPython \u4e2d\u5b9e\u73b0\u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u3002\u76ee\u524d\u5904\u4e8e\u6d4b\u8bd5\u9636\u6bb5 - \u52a0\u5165\u6211\u4eec\u7684\u793e\u533a\u83b7\u53d6\u4f7f\u7528\u8bf4\u660e
      • \u65b0 QSL4A \u529f\u80fd\uff1a\u6dfb\u52a0 notebookOpen \u51fd\u6570\uff0c\u652f\u6301\u81ea\u7136\u8bed\u8a00\u63a7\u5236\u6253\u5f00 Notebook \u6587\u4ef6
      • \u5185\u7f6e\u7f16\u8f91\u5668\u5347\u7ea7\uff1a\u589e\u5f3a\u7f16\u8f91\u5668\u529f\u80fd\uff0c\u652f\u6301\u6253\u5f00\u548c\u6d4f\u89c8\u5404\u79cd\u6587\u672c\u6587\u4ef6
      • \u4fbf\u6377\u7684\u6587\u4ef6\u7ba1\u7406\uff1a\u5728\u6587\u4ef6\u7ba1\u7406\u5668\u4e2d\u6dfb\u52a0\u5185\u90e8\u5b58\u50a8\u5165\u53e3\uff0c\u5feb\u901f\u8bbf\u95ee\u60a8\u7684\u6587\u4ef6
      "},{"location":"whats-new/#v388","title":"v3.8.8","text":"
      • \u6587\u4ef6\u8bbf\u95ee\u6743\u9650\u63a7\u5236\u7684\u91cd\u8981\u6539\u8fdb\uff0c\u5141\u8bb8\u7528\u6237\u7075\u6d3b\u5730\u901a\u8fc7 QPython \u7f16\u7a0b\u542f\u7528\u6216\u7981\u7528\u5916\u90e8\u5b58\u50a8\u6587\u4ef6\u7684\u8bbf\u95ee
      • SDK \u5347\u7ea7\uff0c\u589e\u5f3a\u4e86\u5bf9\u65b0\u7248 Android \u7684\u652f\u6301\u548c\u517c\u5bb9\u6027
      • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Anthropic \u548c Google GenAI \u5e93
      "},{"location":"whats-new/#v387","title":"v3.8.7","text":"
      • \u5728\u73b0\u6709 Tkinter \u652f\u6301\u57fa\u7840\u4e0a\uff0c\u5728 Extensions -> Tools \u4e2d\u6dfb\u52a0\u4e86\u4f7f\u7528 Turtle \u7ed8\u5236\u54c6\u5566A\u68a6\u7684\u793a\u4f8b\u4ee3\u7801
      • \u4f18\u5316\u4e86\u624b\u673a\u6743\u9650\u83b7\u53d6\u6d41\u7a0b\uff0c\u63d0\u5347\u7528\u6237\u4f53\u9a8c\u548c\u64cd\u4f5c\u4fbf\u5229\u6027
      • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Google Gen AI \u5e93\uff0c\u65b9\u4fbf\u8bbf\u95ee Gemini Developer API \u548c Vertex AI
      "},{"location":"whats-new/#v386","title":"v3.8.6","text":"
      • Tkinter \u652f\u6301\uff1a\u73b0\u5728\u652f\u6301 Tkinter \u5e93\uff0c\u53ef\u901a\u8fc7 XServer \u8bbf\u95ee\u3002\u8bf7\u8bbf\u95ee www.qpython.org \u7684\u4e91\u76d8\"Extra\"\u94fe\u63a5\u4e0b\u8f7d\u6240\u9700\u6587\u4ef6
      • \u5b58\u50a8\u6743\u9650\u66f4\u65b0\uff1a\u4e3a\u6539\u5584\u7528\u6237\u4f53\u9a8c\uff0c\u6211\u4eec\u6dfb\u52a0\u4e86\u8bfb\u53d6\u624b\u673a\u5b58\u50a8\u7684\u6743\u9650\uff0c\u7528\u4e8e\u8bbf\u95ee\u5b58\u50a8\u5728\u5176\u4ed6\u76ee\u5f55\u4e2d\u7684 Python \u7a0b\u5e8f

      \u6b64\u66f4\u65b0\u540e\uff0cQPython \u548c QPythonPlus\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff0c\u4e13\u4e3a\u9700\u8981\u66f4\u591a\u654f\u611f\u6743\u9650\u7684\u9ad8\u7ea7\u7528\u6237\u8bbe\u8ba1\uff09\u5c06\u4fdd\u6301\u540c\u6b65\u7684\u7248\u672c\u53f7\u3002

      "},{"location":"whats-new/#v352-2025225","title":"v3.5.2 (2025/2/25)","text":"

      \u4e0e\u5f00\u6e90 LLM \u90e8\u7f72\u5de5\u5177 Ollama \u4ee5\u53ca DeepSeek \u5f00\u53d1\u7684 DeepSeek \u5b9e\u73b0\u65e0\u7f1d\u96c6\u6210\uff01

      \u529f\u80fd\uff1a - \u96f6\u95e8\u69db\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5404\u79cd\u5927\u578b\u8bed\u8a00\u6a21\u578b - \u5feb\u901f\u90e8\u7f72 DeepSeek \u7b49\u5c16\u7aef AI \u6a21\u578b - \u4eab\u53d7\u7b80\u7ea6\u7684 API \u8c03\u7528\u4f53\u9a8c - \u6784\u5efa\u5b8c\u5168\u79bb\u7ebf\u7684\u667a\u80fd\u7f16\u7a0b\u73af\u5883

      \u80fd\u529b\uff1a - \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u52a0\u8f7d/\u7ba1\u7406 LLM \u6a21\u578b - \u57fa\u4e8e\u672c\u5730\u8ba1\u7b97\u7684\u5b9e\u65f6\u4f4e\u5ef6\u8fdf\u54cd\u5e94

      "},{"location":"whats-new/#v350","title":"v3.5.0","text":"
      • Python \u5347\u7ea7\u5230 3.12.8
      • \u6539\u8fdb\u4eea\u8868\u76d8\uff0c\u529f\u80fd\u66f4\u6e05\u6670\u3001\u66f4\u4eba\u6027\u5316
      • \u6dfb\u52a0\u4e86\u4f17\u591a\u7b2c\u4e09\u65b9\u5305\uff1aPyTorch / Twisted / Scrapy / FastAPI ...
      "},{"location":"whats-new/#v338","title":"v3.3.8","text":"
      • \u4fee\u590d\u4e86 NumPy \u517c\u5bb9\u6027\u95ee\u9898
      "},{"location":"whats-new/#v335","title":"v3.3.5","text":"
      • \u5347\u7ea7 Python \u5185\u6838\u5230 3.11.9
      • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u4e0d\u663e\u793a\u6a21\u5757\u5b89\u88c5\u72b6\u6001\u7684 bug
      • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u5220\u9664\u6a21\u5757\u5931\u8d25\u7684 bug
      • \u4fee\u590d\u4e86\u5176\u4ed6 bug
      "},{"location":"whats-new/#v334","title":"v3.3.4","text":"
      • \u6dfb\u52a0\u4e86 OpenAI/Langchain/APIGPTCloud AI \u5305
      • \u79fb\u9664\u4e0d\u5fc5\u8981\u7684\u6587\u4ef6\u4ee5\u51cf\u5c11\u5927\u5c0f
      "},{"location":"whats-new/#v325","title":"v3.2.5","text":"
      • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570
      • \u5176\u4ed6\u9519\u8bef\u4fee\u590d
      "},{"location":"whats-new/#v323","title":"v3.2.3","text":"
      • \u66f4\u65b0 Python \u7248\u672c\u5230 3.11.0
      • \u66f4\u65b0 IPython \u7248\u672c\u5230 8.6.0
      • \u66f4\u65b0 pip \u7248\u672c\u5230 22.3.1
      • \u66f4\u65b0\u79d1\u5b66\u8ba1\u7b97\u5305\uff0c\u81ea\u52a8\u8f6f\u94fe\u63a5
      • \u51cf\u5c11\u7a7a\u95f4\u4f7f\u7528
      • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570 + \u5176\u4ed6\u9519\u8bef\u4fee\u590d
      "},{"location":"whats-new/#v318","title":"v3.1.8","text":"
      • \u5728\u7ec8\u7aef\u4e2d\u6dfb\u52a0\u4e86\u64cd\u4f5c\u70ed\u952e
      • \u4fee\u590d\u4e86\u7f16\u8f91\u5668\u5728\u65cb\u8f6c\u65f6\u4e22\u5931\u5185\u5bb9\u7684\u95ee\u9898
      • \u4fee\u590d\u4e86\u5176\u4ed6 bug

      \u5728 Google Play \u4e0b\u8f7d

      "},{"location":"qsl4a/","title":"QSL4A\uff08Android \u811a\u672c\u5c42\uff09API \u6587\u6863","text":"

      QSL4A \u662f QPython \u7684 Android \u811a\u672c\u5c42\uff0c\u5141\u8bb8\u60a8\u4f7f\u7528 Python \u63a7\u5236 Android \u8bbe\u5907\u529f\u80fd\u3002

      "},{"location":"qsl4a/#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a toast \u6d88\u606f\ndroid.makeToast('Hello QPython!')\n\n# \u9707\u52a8\u8bbe\u5907\ndroid.vibrate(500)\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\uff08\u5148\u5f00\u59cb\u76d1\u63a7\uff09\nimport time\ndroid.batteryStartMonitoring()\ntime.sleep(0.5)  # \u7b49\u5f85\u6570\u636e\nbattery = droid.readBatteryData().result\nprint(f\"\u7535\u6c60\uff1a{battery['level']}%\")\n
      "},{"location":"qsl4a/#_2","title":"\u6587\u6863\u7ed3\u6784","text":""},{"location":"qsl4a/#_3","title":"\u6838\u5fc3\u6a21\u5757","text":"
      • Android \u57fa\u7840 - \u6838\u5fc3\u8fde\u63a5\u548c RPC
      • Intent \u7cfb\u7edf - Android Intent \u64cd\u4f5c
      • \u4e8b\u4ef6\u7cfb\u7edf - \u4e8b\u4ef6\u5904\u7406\u548c\u5e7f\u64ad
      "},{"location":"qsl4a/#ui","title":"UI \u7ec4\u4ef6","text":"
      • \u5bf9\u8bdd\u6846 - \u8b66\u62a5\u3001\u8f93\u5165\u3001\u9009\u62e9\u5bf9\u8bdd\u6846
      • \u5168\u5c4f UI - \u81ea\u5b9a\u4e49\u5e03\u5c40 UI
      • \u60ac\u6d6e\u7a97 - \u60ac\u6d6e\u7a97\u53e3
      • \u8f85\u52a9\u529f\u80fd - \u5c4f\u5e55\u81ea\u52a8\u5316
      "},{"location":"qsl4a/#_4","title":"\u7cfb\u7edf","text":"
      • \u7535\u6c60 - \u7535\u6c60\u76d1\u63a7
      • \u4f20\u611f\u5668 - \u8bbe\u5907\u4f20\u611f\u5668
      • \u5e94\u7528 - \u5e94\u7528\u7ba1\u7406
      • \u7cfb\u7edf\u4fe1\u606f - \u8bbe\u5907\u4fe1\u606f
      • \u8bbe\u7f6e - \u7cfb\u7edf\u8bbe\u7f6e
      • \u5524\u9192\u9501 - \u5524\u9192\u9501\u63a7\u5236
      • QPython \u63a5\u53e3 - \u811a\u672c\u6267\u884c
      • Activity \u7ed3\u679c - Activity \u7ed3\u679c\u5904\u7406
      "},{"location":"qsl4a/#_5","title":"\u786c\u4ef6","text":"
      • \u84dd\u7259 - \u84dd\u7259\u64cd\u4f5c
      • \u76f8\u673a - \u62cd\u7167\u548c\u5f55\u50cf
      • \u97f3\u9891/\u5f55\u97f3\u5668 - \u5f55\u97f3
      • \u7f51\u7edc\u6444\u50cf\u5934 - MJPEG \u6d41
      • USB \u4e32\u53e3 - USB \u4e3b\u673a\u4e32\u53e3
      "},{"location":"qsl4a/#_6","title":"\u8fde\u63a5","text":"
      • WiFi - WiFi \u64cd\u4f5c
      • \u4f4d\u7f6e - GPS \u548c\u4f4d\u7f6e
      • \u77ed\u4fe1 - \u77ed\u4fe1\u64cd\u4f5c
      • \u7535\u8bdd - \u6253\u7535\u8bdd\u548c\u6765\u7535\u4fe1\u606f
      • \u8054\u7cfb\u4eba - \u8054\u7cfb\u4eba\u7ba1\u7406
      • \u4fe1\u53f7\u5f3a\u5ea6 - \u4fe1\u53f7\u76d1\u63a7
      • FTP \u670d\u52a1\u5668 - \u5185\u7f6e FTP \u670d\u52a1\u5668
      "},{"location":"qsl4a/#_7","title":"\u5b58\u50a8","text":"
      • DocumentFile - \u6587\u4ef6\u64cd\u4f5c
      • \u526a\u8d34\u677f - \u526a\u8d34\u677f\u64cd\u4f5c
      • \u504f\u597d\u8bbe\u7f6e - \u5171\u4eab\u504f\u597d\u8bbe\u7f6e
      "},{"location":"qsl4a/#_8","title":"\u5a92\u4f53","text":"
      • \u5a92\u4f53\u64ad\u653e\u5668 - \u97f3\u9891/\u89c6\u9891\u64ad\u653e
      • \u56fe\u50cf\u5904\u7406 - \u56fe\u50cf\u64cd\u4f5c
      "},{"location":"qsl4a/#_9","title":"\u7279\u6b8a\u529f\u80fd","text":"
      • \u52a0\u5bc6 - \u52a0\u5bc6/\u89e3\u5bc6
      • PGPT AI - AI \u8bed\u97f3\u670d\u52a1
      "},{"location":"qsl4a/#_10","title":"\u7ed3\u679c\u5bf9\u8c61","text":"

      \u5927\u591a\u6570 QSL4A \u65b9\u6cd5\u8fd4\u56de\u4e00\u4e2a\u5e26\u6709\u4ee5\u4e0b\u5c5e\u6027\u7684 Result \u547d\u540d\u5143\u7ec4\uff1a - id - \u8bf7\u6c42 ID - result - \u5b9e\u9645\u7ed3\u679c\u6570\u636e - error - \u5982\u679c\u5931\u8d25\u5219\u4e3a\u9519\u8bef\u6d88\u606f

      result = droid.getClipboard()\nif result.error is None:\n    print(result.result)\nelse:\n    print(f\"\u9519\u8bef\uff1a{result.error}\")\n
      "},{"location":"qsl4a/connectivity/contacts/","title":"\u8054\u7cfb\u4eba API","text":"

      \u8bbf\u95ee\u548c\u7ba1\u7406\u8bbe\u5907\u8054\u7cfb\u4eba\u3002

      "},{"location":"qsl4a/connectivity/contacts/#_1","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":""},{"location":"qsl4a/connectivity/contacts/#pickcontact","title":"pickContact()","text":"

      \u663e\u793a\u8054\u7cfb\u4eba\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

      pickContact()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u8054\u7cfb\u4eba URI \u7684 Intent

      "},{"location":"qsl4a/connectivity/contacts/#pickphone","title":"pickPhone()","text":"

      \u663e\u793a\u7535\u8bdd\u53f7\u7801\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

      pickPhone()\n

      \u8fd4\u56de\uff1a \u9009\u4e2d\u7684\u7535\u8bdd\u53f7\u7801\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/contacts/#_2","title":"\u8054\u7cfb\u4eba\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#contactsget","title":"contactsGet()","text":"

      \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\u3002

      contactsGet(attributes=None)\n

      \u53c2\u6570\uff1a - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

      \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba JSONObject \u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetbyid","title":"contactsGetById()","text":"

      \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\u3002

      contactsGetById(id, attributes=None)\n

      \u53c2\u6570\uff1a - id (int): \u8054\u7cfb\u4eba ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

      \u8fd4\u56de\uff1a JSONObject \u8054\u7cfb\u4eba\u6570\u636e

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetcount","title":"contactsGetCount()","text":"

      \u83b7\u53d6\u8054\u7cfb\u4eba\u603b\u6570\u3002

      contactsGetCount()\n

      \u8fd4\u56de\uff1a \u6574\u6570\u8ba1\u6570

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetids","title":"contactsGetIds()","text":"

      \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba ID\u3002

      contactsGetIds()\n

      \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba ID \u6574\u6570\u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetattributes","title":"contactsGetAttributes()","text":"

      \u83b7\u53d6\u6240\u6709\u53ef\u80fd\u7684\u8054\u7cfb\u4eba\u5c5e\u6027\u3002

      contactsGetAttributes()\n

      \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#_3","title":"\u5185\u5bb9\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#querycontent","title":"queryContent()","text":"

      \u4f7f\u7528\u81ea\u5b9a\u4e49\u53c2\u6570\u67e5\u8be2\u5185\u5bb9\u89e3\u6790\u5668\u3002

      queryContent(uri, attributes=None, selection=None, selectionArgs=None, order=None)\n

      \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u5c5e\u6027 - selection (str, optional): WHERE \u5b50\u53e5 - selectionArgs (list, optional): \u9009\u62e9\u53c2\u6570 - order (str, optional): ORDER BY \u5b50\u53e5

      \u8fd4\u56de\uff1a JSONObject \u7ed3\u679c\u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#queryattributes","title":"queryAttributes()","text":"

      \u83b7\u53d6\u5185\u5bb9 URI \u7684\u5c5e\u6027\u3002

      queryAttributes(uri)\n

      \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI

      \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u7684 JSONArray

      "},{"location":"qsl4a/connectivity/contacts/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u9009\u62e9\u8054\u7cfb\u4eba\ncontact_uri = droid.pickContact().result\nprint(f\"Selected contact: {contact_uri}\")\n\n# \u9009\u62e9\u7535\u8bdd\u53f7\u7801\nphone = droid.pickPhone().result\nprint(f\"Selected phone: {phone}\")\n\n# \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\ncontacts = droid.contactsGet().result\nprint(f\"Total contacts: {len(contacts)}\")\n\n# \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\ncontact = droid.contactsGetById(1).result\nprint(f\"Contact: {contact}\")\n\n# \u83b7\u53d6\u8054\u7cfb\u4eba\u5c5e\u6027\nattrs = droid.contactsGetAttributes().result\nprint(f\"Available attributes: {attrs}\")\n
      "},{"location":"qsl4a/connectivity/ftp/","title":"FTP \u670d\u52a1\u5668 API","text":"

      \u5728\u8bbe\u5907\u4e0a\u542f\u52a8\u548c\u7ba1\u7406\u5185\u7f6e FTP \u670d\u52a1\u5668\u3002

      "},{"location":"qsl4a/connectivity/ftp/#ftp","title":"FTP \u670d\u52a1\u5668\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/ftp/#ftpstart","title":"ftpStart()","text":"

      \u542f\u52a8 FTP \u670d\u52a1\u5668\u3002

      ftpStart()\n

      \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4 [ip, port]

      "},{"location":"qsl4a/connectivity/ftp/#ftpstop","title":"ftpStop()","text":"

      \u505c\u6b62 FTP \u670d\u52a1\u5668\u3002

      ftpStop()\n
      "},{"location":"qsl4a/connectivity/ftp/#ftpisrunning","title":"ftpIsRunning()","text":"

      \u68c0\u67e5 FTP \u670d\u52a1\u5668\u662f\u5426\u6b63\u5728\u8fd0\u884c\u3002

      ftpIsRunning()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u8fd0\u884c\u5219\u4e3a True

      "},{"location":"qsl4a/connectivity/ftp/#ftpget","title":"ftpGet()","text":"

      \u83b7\u53d6 FTP \u670d\u52a1\u5668 IP \u5730\u5740\u3002

      ftpGet()\n

      \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4

      "},{"location":"qsl4a/connectivity/ftp/#ftpset","title":"ftpSet()","text":"

      \u914d\u7f6e FTP \u670d\u52a1\u5668\u8bbe\u7f6e\u3002

      ftpSet(port=None, rootDir=None, username=None, password=None)\n

      \u53c2\u6570\uff1a - port (int, optional): \u670d\u52a1\u5668\u7aef\u53e3 - rootDir (str, optional): \u8981\u670d\u52a1\u7684\u57fa\u7840\u76ee\u5f55 - username (str, optional): \u767b\u5f55\u7528\u6237\u540d - password (str, optional): \u767b\u5f55\u5bc6\u7801

      \u8fd4\u56de\uff1a \u5305\u542b\u5f53\u524d\u8bbe\u7f6e\u7684 JSONObject

      "},{"location":"qsl4a/connectivity/ftp/#ftpstatus","title":"ftpStatus()","text":"

      \u83b7\u53d6 FTP \u670d\u52a1\u5668\u72b6\u6001\u3002

      ftpStatus()\n

      \u8fd4\u56de\uff1a \u72b6\u6001\u63cf\u8ff0\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/ftp/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u914d\u7f6e FTP \u670d\u52a1\u5668\ndroid.ftpSet(\n    port=2121,\n    rootDir=\"/sdcard\",\n    username=\"admin\",\n    password=\"secret\"\n)\n\n# \u542f\u52a8 FTP \u670d\u52a1\u5668\ninfo = droid.ftpStart().result\nprint(f\"FTP running at {info[0]}:{info[1]}\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.ftpIsRunning().result:\n    print(\"FTP server is running\")\n\n# \u83b7\u53d6\u670d\u52a1\u5668\u4fe1\u606f\nserver_info = droid.ftpGet().result\nprint(f\"Server: {server_info}\")\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.ftpStop()\n

      \u6ce8\u610f\uff1a \u4f7f\u7528\u63d0\u4f9b\u7684\u51ed\u636e\u901a\u8fc7\u4efb\u4f55 FTP \u5ba2\u6237\u7aef\u8fde\u63a5\u5230 FTP \u670d\u52a1\u5668\u3002

      "},{"location":"qsl4a/connectivity/location/","title":"\u4f4d\u7f6e API","text":"

      \u8bbf\u95ee GPS \u548c\u7f51\u7edc\u4f4d\u7f6e\u670d\u52a1\u3002

      "},{"location":"qsl4a/connectivity/location/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/location/#startlocating","title":"startLocating()","text":"

      \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\u3002

      startLocating(minUpdateTime=60000, minUpdateDistance=30, updateGnssStatus=False)\n

      \u53c2\u6570\uff1a - minUpdateTime (int): \u66f4\u65b0\u4e4b\u95f4\u7684\u6700\u5c0f\u65f6\u95f4\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a60000\uff09 - minUpdateDistance (float): \u66f4\u65b0\u7684\u6700\u5c0f\u8ddd\u79bb\uff08\u7c73\uff09\uff08\u9ed8\u8ba4\uff1a30\uff09 - updateGnssStatus (bool): \u542f\u7528 GNSS \u72b6\u6001\u66f4\u65b0\uff08\u9ed8\u8ba4\uff1aFalse\uff09

      "},{"location":"qsl4a/connectivity/location/#stoplocating","title":"stopLocating()","text":"

      \u505c\u6b62\u4f4d\u7f6e\u66f4\u65b0\u3002

      stopLocating()\n
      "},{"location":"qsl4a/connectivity/location/#readlocation","title":"readLocation()","text":"

      \u83b7\u53d6\u6700\u540e\u5df2\u77e5\u4f4d\u7f6e\u3002

      readLocation()\n

      \u8fd4\u56de\uff1a \u4f4d\u7f6e\u6570\u636e\u5b57\u5178

      "},{"location":"qsl4a/connectivity/location/#getlastknownlocation","title":"getLastKnownLocation()","text":"

      \u83b7\u53d6\u7f13\u5b58\u7684\u4f4d\u7f6e\u3002

      getLastKnownLocation()\n

      \u8fd4\u56de\uff1a \u6765\u81ea\u6240\u6709\u63d0\u4f9b\u5546\u7684\u4f4d\u7f6e

      "},{"location":"qsl4a/connectivity/location/#geocode","title":"geocode()","text":"

      \u5c06\u5730\u5740\u8f6c\u6362\u4e3a\u5750\u6807\u3002

      geocode(address, maxResults=1)\n
      "},{"location":"qsl4a/connectivity/location/#_2","title":"\u4f4d\u7f6e\u63d0\u4f9b\u5546\u65b9\u6cd5)","text":""},{"location":"qsl4a/connectivity/location/#locationproviders","title":"locationProviders()","text":"

      \u83b7\u53d6\u624b\u673a\u4e0a\u53ef\u7528\u7684\u4f4d\u7f6e\u63d0\u4f9b\u5546\u3002

      locationProviders()\n

      \u8fd4\u56de\uff1a \u53ef\u7528\u63d0\u4f9b\u5546\u540d\u79f0\u5217\u8868\uff08\u4f8b\u5982 ['gps', 'network']\uff09

      "},{"location":"qsl4a/connectivity/location/#locationproviderenabled","title":"locationProviderEnabled()","text":"

      \u68c0\u67e5\u7279\u5b9a\u4f4d\u7f6e\u63d0\u4f9b\u5546\u662f\u5426\u5df2\u542f\u7528\u3002

      locationProviderEnabled(provider)\n

      \u53c2\u6570\uff1a - provider (str): \u63d0\u4f9b\u5546\u540d\u79f0\uff08\u4f8b\u5982 'gps', 'network'\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/connectivity/location/#readgnssstatus","title":"readGnssStatus()","text":"

      \u8bfb\u53d6\u5168\u7403\u5bfc\u822a\u536b\u661f\u7cfb\u7edf\u72b6\u6001\uff08\u9700\u8981 Android 8+\uff09\u3002

      readGnssStatus()\n

      \u8fd4\u56de\uff1a \u5305\u542b GNSS \u536b\u661f\u4fe1\u606f\u7684 JSONArray

      "},{"location":"qsl4a/connectivity/location/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\ndroid.startLocating(minUpdateTime=5000, minUpdateDistance=1, updateGnssStatus=False)\n\n# \u7b49\u5f85\u5b9a\u4f4d\ntime.sleep(10)\n\n# \u83b7\u53d6\u4f4d\u7f6e\nloc = droid.readLocation().result\nif loc:\n    lat = loc['latitude']\n    lon = loc['longitude']\n    print(f\"Location: {lat}, {lon}\")\n\ndroid.stopLocating()\n
      "},{"location":"qsl4a/connectivity/phone/","title":"\u7535\u8bdd API","text":"

      \u63a7\u5236\u7535\u8bdd\u901a\u8bdd\u548c\u83b7\u53d6\u7535\u8bdd\u4fe1\u606f\u3002

      "},{"location":"qsl4a/connectivity/phone/#_1","title":"\u7535\u8bdd\u72b6\u6001\u8ddf\u8e2a","text":""},{"location":"qsl4a/connectivity/phone/#starttrackingphonestate","title":"startTrackingPhoneState()","text":"

      \u5f00\u59cb\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u53d8\u5316\u3002\u751f\u6210 'phone' \u4e8b\u4ef6\u3002

      startTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/phone/#readphonestate","title":"readPhoneState()","text":"

      \u8bfb\u53d6\u5f53\u524d\u7535\u8bdd\u72b6\u6001\u3002

      readPhoneState()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7535\u8bdd\u72b6\u6001\u548c\u6765\u7535\u53f7\u7801\u7684 Bundle

      "},{"location":"qsl4a/connectivity/phone/#stoptrackingphonestate","title":"stopTrackingPhoneState()","text":"

      \u505c\u6b62\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u3002

      stopTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/phone/#_2","title":"\u62e8\u6253\u7535\u8bdd","text":""},{"location":"qsl4a/connectivity/phone/#phonecall","title":"phoneCall()","text":"

      \u901a\u8fc7 URI \u547c\u53eb\u8054\u7cfb\u4eba/\u7535\u8bdd\u53f7\u7801\u3002

      phoneCall(uri)\n

      \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

      "},{"location":"qsl4a/connectivity/phone/#phonecallnumber","title":"phoneCallNumber()","text":"

      \u76f4\u63a5\u62e8\u6253\u7535\u8bdd\u53f7\u7801\u3002

      phoneCallNumber(phone_number)\n

      \u53c2\u6570\uff1a - phone_number (str): \u8981\u62e8\u6253\u7684\u7535\u8bdd\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#phonedial","title":"phoneDial()","text":"

      \u62e8\u6253\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

      phoneDial(uri)\n

      \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

      "},{"location":"qsl4a/connectivity/phone/#phonedialnumber","title":"phoneDialNumber()","text":"

      \u62e8\u6253\u7535\u8bdd\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

      phoneDialNumber(phone_number)\n

      \u53c2\u6570\uff1a - phone_number (str): \u7535\u8bdd\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#_3","title":"\u57fa\u7ad9\u4f4d\u7f6e","text":""},{"location":"qsl4a/connectivity/phone/#getcelllocation","title":"getCellLocation()","text":"

      \u83b7\u53d6\u5f53\u524d\u57fa\u7ad9\u4f4d\u7f6e\u3002

      getCellLocation()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u57fa\u7ad9\u4f4d\u7f6e\u6570\u636e\u7684 JSONObject

      "},{"location":"qsl4a/connectivity/phone/#getallcellslocation","title":"getAllCellsLocation()","text":"

      \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u4f4d\u7f6e\uff08\u9002\u7528\u4e8e\u53cc\u5361\u8bbe\u5907\uff09\u3002

      getAllCellsLocation()\n

      \u8fd4\u56de\uff1a \u57fa\u7ad9\u4f4d\u7f6e\u7684 JSONArray

      "},{"location":"qsl4a/connectivity/phone/#_4","title":"\u7f51\u7edc\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getnetworkoperator","title":"getNetworkOperator()","text":"

      \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

      getNetworkOperator()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getnetworkoperatorname","title":"getNetworkOperatorName()","text":"

      \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684\u540d\u79f0\u3002

      getNetworkOperatorName()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getnetworktype","title":"getNetworkType()","text":"

      \u83b7\u53d6\u5f53\u524d\u7f51\u7edc\u7c7b\u578b\u3002

      getNetworkType()\n

      \u8fd4\u56de\uff1a \u63cf\u8ff0\u65e0\u7ebf\u7535\u6280\u672f\u7684\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'LTE', 'UMTS', 'GSM'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getphonetype","title":"getPhoneType()","text":"

      \u83b7\u53d6\u7535\u8bdd\u7c7b\u578b\u3002

      getPhoneType()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'GSM', 'CDMA', 'SIP'\uff09

      "},{"location":"qsl4a/connectivity/phone/#sim","title":"SIM \u5361\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getsimcountryiso","title":"getSimCountryIso()","text":"

      \u83b7\u53d6 SIM \u5361\u7684 ISO \u56fd\u5bb6\u4ee3\u7801\u3002

      getSimCountryIso()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'us'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getsimoperator","title":"getSimOperator()","text":"

      \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

      getSimOperator()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getsimoperatorname","title":"getSimOperatorName()","text":"

      \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u540d\u79f0\u3002

      getSimOperatorName()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getsimserialnumber","title":"getSimSerialNumber()","text":"

      \u83b7\u53d6 SIM \u5e8f\u5217\u53f7\u3002

      getSimSerialNumber()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32 SIM \u5e8f\u5217\u53f7

      "},{"location":"qsl4a/connectivity/phone/#getsimstate","title":"getSimState()","text":"

      \u83b7\u53d6 SIM \u5361\u72b6\u6001\u3002

      getSimState()\n

      \u8fd4\u56de\uff1a \u63cf\u8ff0 SIM \u72b6\u6001\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/phone/#getsubscriberid","title":"getSubscriberId()","text":"

      \u83b7\u53d6\u8ba2\u9605\u8005 ID\u3002

      getSubscriberId()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8ba2\u9605\u8005 ID

      "},{"location":"qsl4a/connectivity/phone/#_5","title":"\u8bed\u97f3\u90ae\u4ef6","text":""},{"location":"qsl4a/connectivity/phone/#getvoicemailalphatag","title":"getVoiceMailAlphaTag()","text":"

      \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u5b57\u6bcd\u6807\u7b7e\u3002

      getVoiceMailAlphaTag()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u6807\u7b7e

      "},{"location":"qsl4a/connectivity/phone/#getvoicemailnumber","title":"getVoiceMailNumber()","text":"

      \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801\u3002

      getVoiceMailNumber()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getdeviceid","title":"getDeviceId()","text":"

      \u83b7\u53d6\u8bbe\u5907 ID\uff08GSM \u7684 IMEI\uff09\u3002\u5df2\u5e9f\u5f03\u3002

      getDeviceId()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

      "},{"location":"qsl4a/connectivity/phone/#getdevicesoftwareversion","title":"getDeviceSoftwareVersion()","text":"

      \u83b7\u53d6\u8bbe\u5907\u8f6f\u4ef6\u7248\u672c\u3002

      getDeviceSoftwareVersion()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8f6f\u4ef6\u7248\u672c

      "},{"location":"qsl4a/connectivity/phone/#getline1number","title":"getLine1Number()","text":"

      \u83b7\u53d6\u7ebf\u8def 1 \u7535\u8bdd\u53f7\u7801\u3002

      getLine1Number()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u7535\u8bdd\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#checknetworkroaming","title":"checkNetworkRoaming()","text":"

      \u68c0\u67e5\u662f\u5426\u8fde\u63a5\u5230\u6f2b\u6e38\u7f51\u7edc\u3002

      checkNetworkRoaming()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u6f2b\u6e38\u5219\u4e3a True

      "},{"location":"qsl4a/connectivity/phone/#_7","title":"\u57fa\u7ad9\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getallcellinfo","title":"getAllCellInfo()","text":"

      \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u7684\u4fe1\u606f\u3002

      getAllCellInfo()\n

      \u8fd4\u56de\uff1a \u57fa\u7ad9\u4fe1\u606f\u5217\u8868

      "},{"location":"qsl4a/connectivity/phone/#setdataenabled","title":"setDataEnabled()","text":"

      \u542f\u7528\u6216\u7981\u7528\u79fb\u52a8\u6570\u636e\u3002

      setDataEnabled(enabled)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528

      "},{"location":"qsl4a/connectivity/phone/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7f51\u7edc\u4fe1\u606f\noperator = droid.getNetworkOperatorName().result\nprint(f\"Operator: {operator}\")\n\nnetwork_type = droid.getNetworkType().result\nprint(f\"Network: {network_type}\")\n\n# \u83b7\u53d6 SIM \u4fe1\u606f\nsim_state = droid.getSimState().result\nprint(f\"SIM: {sim_state}\")\n\n# \u83b7\u53d6\u7535\u8bdd\u53f7\u7801\nline1 = droid.getLine1Number().result\nprint(f\"Phone: {line1}\")\n\n# \u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\ndroid.startTrackingPhoneState()\nprint(\"Tracking phone state...\")\ndroid.stopTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/signalstrength/","title":"\u4fe1\u53f7\u5f3a\u5ea6 API","text":"

      \u76d1\u63a7\u8702\u7a9d\u548c\u65e0\u7ebf\u4fe1\u53f7\u5f3a\u5ea6\u3002

      "},{"location":"qsl4a/connectivity/signalstrength/#_1","title":"\u4fe1\u53f7\u5f3a\u5ea6\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/signalstrength/#starttrackingsignalstrengths","title":"startTrackingSignalStrengths()","text":"

      \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316\u3002\u751f\u6210 'signal_strengths' \u4e8b\u4ef6\u3002

      startTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/signalstrength/#stoptrackingsignalstrengths","title":"stopTrackingSignalStrengths()","text":"

      \u505c\u6b62\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u3002

      stopTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/signalstrength/#readsignalstrengths","title":"readSignalStrengths()","text":"

      \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\u3002

      readSignalStrengths()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u4fe1\u53f7\u5f3a\u5ea6\u6570\u636e\u7684 Bundle

      "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthlevel","title":"getTelephoneSignalStrengthLevel()","text":"

      \u83b7\u53d6\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u7b49\u7ea7\uff080-4\uff09\u3002

      getTelephoneSignalStrengthLevel()\n

      \u8fd4\u56de\uff1a \u6574\u6570\u7b49\u7ea7\uff080=\u65e0\uff0c1=\u5dee\uff0c2=\u4e00\u822c\uff0c3=\u597d\uff0c4=\u4f18\u79c0\uff09

      "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthdetail","title":"getTelephoneSignalStrengthDetail()","text":"

      \u83b7\u53d6\u8be6\u7ec6\u7684\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u4fe1\u606f\u3002

      getTelephoneSignalStrengthDetail()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u8be6\u7ec6\u4fe1\u53f7\u4fe1\u606f\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/signalstrength/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\ndroid.startTrackingSignalStrengths()\n\n# \u7b49\u5f85\u4fe1\u53f7\u66f4\u65b0\ntime.sleep(5)\n\n# \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\nsignal = droid.readSignalStrengths().result\nprint(f\"Signal: {signal}\")\n\n# \u76f4\u63a5\u83b7\u53d6\u7b49\u7ea7\nlevel = droid.getTelephoneSignalStrengthLevel().result\nprint(f\"Signal level: {level}/4\")\n\ndroid.stopTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/sms/","title":"SMS API","text":"

      \u53d1\u9001\u548c\u63a5\u6536 SMS \u6d88\u606f\u3002

      "},{"location":"qsl4a/connectivity/sms/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/sms/#smssend","title":"smsSend()","text":"

      \u53d1\u9001 SMS \u6d88\u606f\u3002

      smsSend(destinationAddress, text)\n

      \u53c2\u6570\uff1a - destinationAddress (str): \u7535\u8bdd\u53f7\u7801 - text (str): \u6d88\u606f\u6587\u672c

      "},{"location":"qsl4a/connectivity/sms/#smsgetmessagecount","title":"smsGetMessageCount()","text":"

      \u83b7\u53d6\u6d88\u606f\u6570\u91cf\u3002

      smsGetMessageCount(unreadOnly=False, folder=\"inbox\")\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessageids","title":"smsGetMessageIds()","text":"

      \u83b7\u53d6\u6d88\u606f ID\u3002

      smsGetMessageIds(unreadOnly=False, folder=\"inbox\")\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessages","title":"smsGetMessages()","text":"

      \u83b7\u53d6\u6d88\u606f\u8be6\u60c5\u3002

      smsGetMessages(unreadOnly=False, folder=\"inbox\", attributes=None)\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessagebyid","title":"smsGetMessageById()","text":"

      \u901a\u8fc7 ID \u83b7\u53d6\u7279\u5b9a\u6d88\u606f\u3002

      smsGetMessageById(id, attributes=None)\n

      \u53c2\u6570\uff1a - id (int): \u6d88\u606f ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

      \u8fd4\u56de\uff1a \u6d88\u606f\u6570\u636e\u5b57\u5178

      "},{"location":"qsl4a/connectivity/sms/#smsgetattributes","title":"smsGetAttributes()","text":"

      \u83b7\u53d6\u53ef\u7528\u7684 SMS \u6d88\u606f\u5c5e\u6027\u3002

      smsGetAttributes()\n

      \u8fd4\u56de\uff1a \u53ef\u7528\u5c5e\u6027\u540d\u79f0\u5217\u8868

      "},{"location":"qsl4a/connectivity/sms/#smsdeletemessage","title":"smsDeleteMessage()","text":"

      \u5220\u9664\u6d88\u606f\u3002

      smsDeleteMessage(id)\n
      "},{"location":"qsl4a/connectivity/sms/#smsmarkmessageread","title":"smsMarkMessageRead()","text":"

      \u5c06\u6d88\u606f\u6807\u8bb0\u4e3a\u5df2\u8bfb\u3002

      smsMarkMessageRead(ids, read=True)\n
      "},{"location":"qsl4a/connectivity/sms/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u53d1\u9001 SMS\ndroid.smsSend(\"+1234567890\", \"Hello from QPython!\")\n\n# \u83b7\u53d6\u672a\u8bfb\u6d88\u606f\nmessages = droid.smsGetMessages(unreadOnly=True).result\nfor msg in messages:\n    print(f\"From: {msg['address']}, Text: {msg['body']}\")\n
      "},{"location":"qsl4a/connectivity/wifi/","title":"WiFi API","text":"

      \u63a7\u5236 WiFi \u9002\u914d\u5668\u5e76\u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\u3002

      "},{"location":"qsl4a/connectivity/wifi/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/connectivity/wifi/#checkwifistate","title":"checkWifiState()","text":"

      \u68c0\u67e5 WiFi \u662f\u5426\u5df2\u542f\u7528\u3002

      checkWifiState()\n

      \u8fd4\u56de\uff1a \u5982\u679c WiFi \u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/connectivity/wifi/#togglewifistate","title":"toggleWifiState()","text":"

      \u6253\u5f00\u6216\u5173\u95ed WiFi\u3002

      toggleWifiState(enabled=None)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

      \u8fd4\u56de\uff1a \u5982\u679c\u64cd\u4f5c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/connectivity/wifi/#wifistartscan","title":"wifiStartScan()","text":"

      \u5f00\u59cb\u626b\u63cf\u53ef\u7528\u7684 WiFi \u7f51\u7edc\u3002

      wifiStartScan()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifigetscanresults","title":"wifiGetScanResults()","text":"

      \u83b7\u53d6\u53d1\u73b0\u7684 WiFi \u7f51\u7edc\u5217\u8868\u3002

      wifiGetScanResults()\n

      \u8fd4\u56de\uff1a \u63a5\u5165\u70b9\u4fe1\u606f\u5217\u8868

      "},{"location":"qsl4a/connectivity/wifi/#_2","title":"\u8fde\u63a5\u7ba1\u7406","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetconnectioninfo","title":"wifiGetConnectionInfo()","text":"

      \u83b7\u53d6\u8be6\u7ec6\u8fde\u63a5\u4fe1\u606f\u3002

      wifiGetConnectionInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001IP \u5730\u5740\u7b49\u8fde\u63a5\u8be6\u60c5\u7684\u5b57\u5178

      "},{"location":"qsl4a/connectivity/wifi/#getconnectedinfo","title":"getConnectedInfo()","text":"

      \u83b7\u53d6\u8fde\u63a5\u7684 WiFi \u7f51\u7edc\u4fe1\u606f\uff08\u7b80\u5316\u7248\uff09\u3002

      getConnectedInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001\u4fe1\u53f7\u5f3a\u5ea6\u7684\u5b57\u5178

      "},{"location":"qsl4a/connectivity/wifi/#getdhcpinfo","title":"getDhcpInfo()","text":"

      \u83b7\u53d6\u5f53\u524d\u8fde\u63a5\u7684 DHCP \u4fe1\u606f\u3002

      getDhcpInfo(ipConvertToString=True)\n

      \u53c2\u6570\uff1a - ipConvertToString (bool): \u5c06 IP \u5730\u5740\u8f6c\u6362\u4e3a\u5b57\u7b26\u4e32\u683c\u5f0f\uff08\u9ed8\u8ba4\uff1aTrue\uff09

      \u8fd4\u56de\uff1a \u5305\u542b IP\u3001\u7f51\u5173\u3001DNS \u7b49 DHCP \u4fe1\u606f\u7684\u5b57\u5178

      "},{"location":"qsl4a/connectivity/wifi/#wifidisconnect","title":"wifiDisconnect()","text":"

      \u65ad\u5f00\u5f53\u524d WiFi \u7f51\u7edc\u8fde\u63a5\u3002

      wifiDisconnect()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifireconnect","title":"wifiReconnect()","text":"

      \u91cd\u65b0\u8fde\u63a5\u5230\u5f53\u524d\u7f51\u7edc\u3002

      wifiReconnect()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifireassociate","title":"wifiReassociate()","text":"

      \u91cd\u65b0\u5173\u8054\u5f53\u524d\u63a5\u5165\u70b9\u3002

      wifiReassociate()\n
      "},{"location":"qsl4a/connectivity/wifi/#_3","title":"\u70ed\u70b9","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetapstate","title":"wifiGetApState()","text":"

      \u83b7\u53d6 WiFi AP\uff08\u70ed\u70b9\uff09\u72b6\u6001\u3002

      wifiGetApState()\n

      \u8fd4\u56de\uff1a \u70ed\u70b9\u72b6\u6001

      "},{"location":"qsl4a/connectivity/wifi/#wifi","title":"WiFi \u9501","text":""},{"location":"qsl4a/connectivity/wifi/#wifilockacquirefull","title":"wifiLockAcquireFull()","text":"

      \u83b7\u53d6\u5b8c\u6574 WiFi \u9501\uff08\u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\u4e5f\u4fdd\u6301 WiFi \u6d3b\u52a8\uff09\u3002

      wifiLockAcquireFull()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifilockacquirescanonly","title":"wifiLockAcquireScanOnly()","text":"

      \u83b7\u53d6\u4ec5\u626b\u63cf WiFi \u9501\u3002

      wifiLockAcquireScanOnly()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifilockrelease","title":"wifiLockRelease()","text":"

      \u91ca\u653e WiFi \u9501\u3002

      wifiLockRelease()\n
      "},{"location":"qsl4a/connectivity/wifi/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u68c0\u67e5 WiFi \u72b6\u6001\nif droid.checkWifiState().result:\n    print(\"WiFi is enabled\")\nelse:\n    print(\"Enabling WiFi...\")\n    droid.toggleWifiState(True)\n    time.sleep(2)\n\n# \u5f00\u59cb\u626b\u63cf\ndroid.wifiStartScan()\ntime.sleep(3)\n\n# \u83b7\u53d6\u626b\u63cf\u7ed3\u679c\nnetworks = droid.wifiGetScanResults().result\nfor network in networks:\n    print(f\"SSID: {network.get('SSID')}, Signal: {network.get('level')} dBm\")\n\n# \u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\ninfo = droid.wifiGetConnectionInfo().result\nif info:\n    print(f\"Connected to: {info.get('ssid')}\")\n    print(f\"BSSID: {info.get('bssid')}\")\n    print(f\"IP: {info.get('ip_address')}\")\n\n# \u83b7\u53d6 DHCP \u4fe1\u606f\ndhcp = droid.getDhcpInfo().result\nif dhcp:\n    print(f\"Gateway: {dhcp.get('gateway')}\")\n    print(f\"DNS: {dhcp.get('dns1')}\")\n\n# \u83b7\u53d6\u7b80\u5316\u7684\u8fde\u63a5\u4fe1\u606f\nconnected = droid.getConnectedInfo().result\nprint(f\"SSID: {connected.get('ssid')}, Signal: {connected.get('level')} dBm\")\n\n# \u65ad\u5f00\u5e76\u91cd\u65b0\u8fde\u63a5\ndroid.wifiDisconnect()\ntime.sleep(1)\ndroid.wifiReconnect()\n\n# \u91cd\u65b0\u5173\u8054\u63a5\u5165\u70b9\ndroid.wifiReassociate()\n\n# \u68c0\u67e5\u70ed\u70b9\u72b6\u6001\nap_state = droid.wifiGetApState().result\nprint(f\"Hotspot state: {ap_state}\")\n\n# \u83b7\u53d6 WiFi \u9501\u4ee5\u8fdb\u884c\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireFull()\n# ... \u6267\u884c\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n\n# \u6216\u4f7f\u7528\u4ec5\u626b\u63cf\u9501\u4ee5\u8fdb\u884c\u8f83\u8f7b\u7684\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireScanOnly()\n# ... \u6267\u884c\u626b\u63cf\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n
      "},{"location":"qsl4a/core/android-base/","title":"Android \u57fa\u7840\u7c7b","text":"

      Android \u7c7b\u662f QSL4A \u7684\u6838\u5fc3\uff0c\u63d0\u4f9b\u4e86\u4e0e Android \u8fd0\u884c\u65f6\u7684\u8fde\u63a5\u548c RPC \u673a\u5236\u3002

      "},{"location":"qsl4a/core/android-base/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
      # \u529f\u80fd\u5b8c\u6574\u7248\u672c\uff08\u63a8\u8350\uff09\nimport androidhelper\ndroid = androidhelper.Android()\n\n# \u7b80\u5316\u7248\u672c\uff08\u5feb\u901f\uff0c\u5355\u5b9e\u4f8b\uff09\nimport android\ndroid = android.droid\n
      "},{"location":"qsl4a/core/android-base/#android_1","title":"\u7c7b\uff1aAndroid","text":""},{"location":"qsl4a/core/android-base/#_2","title":"\u6784\u9020\u51fd\u6570","text":"
      Android(addr=None)\n

      \u53c2\u6570\uff1a - addr (tuple, optional): (HOST, PORT) \u5730\u5740\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u73af\u5883\u53d8\u91cf AP_HOST \u548c AP_PORT

      \u73af\u5883\u53d8\u91cf\uff1a - AP_HOST - \u670d\u52a1\u5668\u4e3b\u673a\u5730\u5740 - AP_PORT - \u670d\u52a1\u5668\u7aef\u53e3 - AP_HANDSHAKE - \u8ba4\u8bc1\u4ee4\u724c

      "},{"location":"qsl4a/core/android-base/#_3","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/android-base/#_rpc","title":"_rpc()","text":"

      \u8c03\u7528 Android \u51fd\u6570\u7684\u5185\u90e8 RPC \u65b9\u6cd5\u3002

      _rpc(method, *args)\n

      \u53c2\u6570\uff1a - method (str): \u8981\u8c03\u7528\u7684\u65b9\u6cd5\u540d - *args: \u65b9\u6cd5\u7684\u53ef\u53d8\u53c2\u6570

      \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4\uff0c\u5305\u542b\u4ee5\u4e0b\u5b57\u6bb5\uff1a - id (int): \u8bf7\u6c42 ID - result: \u65b9\u6cd5\u8fd4\u56de\u503c - error (str or None): \u9519\u8bef\u4fe1\u606f\uff08\u5982\u679c\u5931\u8d25\uff09

      "},{"location":"qsl4a/core/android-base/#getattr","title":"getattr()","text":"

      \u52a8\u6001\u65b9\u6cd5\u5206\u53d1\u5668\u3002\u6240\u6709 Android \u65b9\u6cd5\u90fd\u901a\u8fc7\u5c5e\u6027\u67e5\u627e\u8bbf\u95ee\u3002

      # \u4ee5\u4e0b\u4e24\u79cd\u65b9\u5f0f\u7b49\u4ef7\uff1a\ndroid.makeToast(\"Hello\")\ndroid._rpc(\"makeToast\", \"Hello\")\n
      "},{"location":"qsl4a/core/android-base/#androidpy","title":"\u72ec\u7acb\u51fd\u6570\uff08android.py\uff09","text":"

      \u4f7f\u7528\u7b80\u5316\u7684 android \u6a21\u5757\u65f6\uff1a

      "},{"location":"qsl4a/core/android-base/#jsla","title":"jsla()","text":"

      \u53d1\u9001 JSON-RPC \u8bf7\u6c42\u5e76\u8fd4\u56de\u539f\u59cb\u54cd\u5e94\u3002

      jsla(method, *params)\n

      \u8fd4\u56de\uff1a JSON \u5b57\u7b26\u4e32\u54cd\u5e94

      "},{"location":"qsl4a/core/android-base/#rsla","title":"rsla()","text":"

      \u53d1\u9001\u8bf7\u6c42\u5e76\u4ec5\u8fd4\u56de\u7ed3\u679c\u3002

      rsla(method, *params)\n

      \u8fd4\u56de\uff1a RPC \u8c03\u7528\u7684\u7ed3\u679c\u503c

      "},{"location":"qsl4a/core/android-base/#esla","title":"esla()","text":"

      \u53d1\u9001\u8bf7\u6c42\uff0c\u9519\u8bef\u65f6\u629b\u51fa\u5f02\u5e38\u3002

      esla(method, *params)\n

      \u629b\u51fa\uff1a \u5982\u679c error \u5b57\u6bb5\u4e0d\u4e3a None \u5219\u629b\u51fa\u5f02\u5e38

      "},{"location":"qsl4a/core/android-base/#nsla","title":"nsla()","text":"

      \u53d1\u9001\u8bf7\u6c42\u5e76\u8fd4\u56de Result \u547d\u540d\u5143\u7ec4\u3002

      nsla(method, *params)\n

      \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4

      "},{"location":"qsl4a/core/android-base/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/android-base/#_5","title":"\u57fa\u672c\u8fde\u63a5","text":"
      import androidhelper\n\n# \u8fde\u63a5\u5230 Android \u8fd0\u884c\u65f6\ndroid = androidhelper.Android()\n\n# \u901a\u8fc7\u663e\u793a toast \u6765\u68c0\u67e5\u8fde\u63a5\ndroid.makeToast(\"Connected!\")\n
      "},{"location":"qsl4a/core/android-base/#_6","title":"\u9519\u8bef\u5904\u7406","text":"
      result = droid.someMethod()\nif result.error:\n    print(f\"Error: {result.error}\")\nelse:\n    print(f\"Success: {result.result}\")\n
      "},{"location":"qsl4a/core/android-base/#rpc","title":"\u76f4\u63a5 RPC \u8c03\u7528","text":"
      # \u76f4\u63a5\u8c03\u7528\u4efb\u610f\u65b9\u6cd5\nresult = droid._rpc(\"makeToast\", \"Hello World\")\n
      "},{"location":"qsl4a/core/events/","title":"\u4e8b\u4ef6\u7cfb\u7edf","text":"

      QSL4A \u63d0\u4f9b\u4e86\u4e00\u4e2a\u4e8b\u4ef6\u7cfb\u7edf\uff0c\u7528\u4e8e\u5904\u7406\u6765\u81ea Android \u7684\u5f02\u6b65\u4e8b\u4ef6\uff0c\u5982\u4f20\u611f\u5668\u66f4\u65b0\u3001\u4f4d\u7f6e\u53d8\u5316\u548c\u81ea\u5b9a\u4e49\u5e7f\u64ad\u3002

      "},{"location":"qsl4a/core/events/#_2","title":"\u4e8b\u4ef6\u57fa\u7840","text":"

      \u4e8b\u4ef6\u5b58\u50a8\u5728\u7f13\u51b2\u533a\u4e2d\uff0c\u53ef\u4ee5\u8f6e\u8be2\u6216\u7b49\u5f85\u3002\u6bcf\u4e2a\u4e8b\u4ef6\u5305\u542b\uff1a - name: \u4e8b\u4ef6\u7c7b\u578b/\u540d\u79f0 - data: \u4e8b\u4ef6\u8d1f\u8f7d\u6570\u636e - time: \u65f6\u95f4\u6233

      "},{"location":"qsl4a/core/events/#_3","title":"\u4e8b\u4ef6\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#eventclearbuffer","title":"eventClearBuffer()","text":"

      \u6e05\u9664\u7f13\u51b2\u533a\u4e2d\u7684\u6240\u6709\u5f85\u5904\u7406\u4e8b\u4ef6\u3002

      eventClearBuffer()\n

      \u8fd4\u56de\uff1a None

      "},{"location":"qsl4a/core/events/#eventpoll","title":"eventPoll()","text":"

      \u8f6e\u8be2\u7f13\u51b2\u533a\u4e2d\u7684\u4e8b\u4ef6\u3002

      eventPoll(number_of_events=1)\n

      \u53c2\u6570\uff1a - number_of_events (int): \u8981\u68c0\u7d22\u7684\u6700\u5927\u4e8b\u4ef6\u6570\uff08\u9ed8\u8ba4\uff1a1\uff09

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\u5217\u8868

      "},{"location":"qsl4a/core/events/#eventwait","title":"eventWait()","text":"

      \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\u3002

      eventWait(timeout=None)\n

      \u53c2\u6570\uff1a - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09\u3002None = \u6c38\u4e45\u7b49\u5f85

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

      "},{"location":"qsl4a/core/events/#eventwaitfor","title":"eventWaitFor()","text":"

      \u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6\u3002

      eventWaitFor(eventName, timeout=None)\n

      \u53c2\u6570\uff1a - eventName (str): \u8981\u7b49\u5f85\u7684\u4e8b\u4ef6\u540d\u79f0 - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

      "},{"location":"qsl4a/core/events/#eventpost","title":"eventPost()","text":"

      \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\u3002

      eventPost(name, data, enqueue=None)\n

      \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e\uff08\u4efb\u610f\u7c7b\u578b\uff09 - enqueue (bool, optional): \u5982\u679c\u4e3a True \u5219\u6dfb\u52a0\u5230\u961f\u5217

      "},{"location":"qsl4a/core/events/#receiveevent","title":"receiveEvent()","text":"

      \u63a5\u6536\u4e8b\u4ef6\uff08\u963b\u585e\uff09\u3002

      receiveEvent()\n

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61

      "},{"location":"qsl4a/core/events/#_4","title":"\u5e7f\u64ad\u4e8b\u4ef6","text":"

      \u6ce8\u518c\u7cfb\u7edf\u5e7f\u64ad\u4e8b\u4ef6\u3002

      "},{"location":"qsl4a/core/events/#eventregisterforbroadcast","title":"eventRegisterForBroadcast()","text":"

      \u6ce8\u518c\u63a5\u6536\u5e7f\u64ad\u4e8b\u4ef6\u3002

      eventRegisterForBroadcast(category, enqueue=True)\n

      \u53c2\u6570\uff1a - category (str): \u5e7f\u64ad\u7c7b\u522b/\u52a8\u4f5c - enqueue (bool): \u6dfb\u52a0\u5230\u4e8b\u4ef6\u961f\u5217

      "},{"location":"qsl4a/core/events/#eventunregisterforbroadcast","title":"eventUnregisterForBroadcast()","text":"

      \u53d6\u6d88\u6ce8\u518c\u5e7f\u64ad\u4e8b\u4ef6\u3002

      eventUnregisterForBroadcast(category)\n
      "},{"location":"qsl4a/core/events/#eventgetbrodcastcategories","title":"eventGetBrodcastCategories()","text":"

      \u83b7\u53d6\u5df2\u6ce8\u518c\u7684\u5e7f\u64ad\u7c7b\u522b\u3002

      eventGetBrodcastCategories()\n

      \u8fd4\u56de\uff1a \u5df2\u6ce8\u518c\u7c7b\u522b\u5217\u8868

      "},{"location":"qsl4a/core/events/#_5","title":"\u4e8b\u4ef6\u5206\u53d1\u5668)","text":""},{"location":"qsl4a/core/events/#starteventdispatcher","title":"startEventDispatcher()","text":"

      \u6253\u5f00\u4e00\u4e2a\u53ef\u4ee5\u8bfb\u53d6\u5df2\u53d1\u5e03\u4e8b\u4ef6\u7684\u5957\u63a5\u5b57\u3002)

      startEventDispatcher(port=0)\n

      \u53c2\u6570\uff1a - port (int, optional): \u76d1\u542c\u7684\u7aef\u53e3\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\u9009\u62e9\uff09

      \u8fd4\u56de\uff1a \u6b63\u5728\u76d1\u542c\u7684\u7aef\u53e3\u53f7

      "},{"location":"qsl4a/core/events/#stopeventdispatcher","title":"stopEventDispatcher()","text":"

      \u505c\u6b62\u4e8b\u4ef6\u670d\u52a1\u5668\u3002)

      stopEventDispatcher()\n
      "},{"location":"qsl4a/core/events/#_6","title":"\u5df2\u5e9f\u5f03\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#rpcpostevent","title":"rpcPostEvent()","text":"

      \u5c06\u4e8b\u4ef6\u53d1\u5e03\u5230\u4e8b\u4ef6\u961f\u5217\u3002\uff08\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 eventPost\uff09

      rpcPostEvent(name, data)\n

      \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e

      "},{"location":"qsl4a/core/events/#_7","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/events/#_8","title":"\u57fa\u672c\u4e8b\u4ef6\u8f6e\u8be2","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6e05\u9664\u65e7\u4e8b\u4ef6\ndroid.eventClearBuffer()\n\n# \u8f6e\u8be2\u4e8b\u4ef6\nevents = droid.eventPoll(5).result\nfor event in events:\n    print(f\"Event: {event['name']}, Data: {event['data']}\")\n
      "},{"location":"qsl4a/core/events/#_9","title":"\u7b49\u5f85\u4e8b\u4ef6","text":"
      # \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\uff0c\u5e26\u8d85\u65f6\nevent = droid.eventWait(timeout=10).result\nif event:\n    print(f\"Got event: {event['name']}\")\n
      "},{"location":"qsl4a/core/events/#_10","title":"\u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6","text":"
      # \u7b49\u5f85\u4f20\u611f\u5668\u4e8b\u4ef6\nevent = droid.eventWaitFor('screen', timeout=5).result\nif event:\n    print(f\"Screen event: {event['data']}\")\n
      "},{"location":"qsl4a/core/events/#_11","title":"\u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6","text":"
      # \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\ndroid.eventPost('my_event', {'key': 'value'})\n\n# \u7b49\u5f85\u5b83\nevent = droid.eventWaitFor('my_event', timeout=1).result\n
      "},{"location":"qsl4a/core/events/#_12","title":"\u5e7f\u64ad\u63a5\u6536\u5668","text":"
      # \u6ce8\u518c\u5c4f\u5e55\u5f00\u5173\u4e8b\u4ef6\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_ON')\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_OFF')\n\n# \u7b49\u5f85\u5c4f\u5e55\u4e8b\u4ef6\nwhile True:\n    event = droid.receiveEvent().result\n    if event['name'] == 'android.intent.action.SCREEN_ON':\n        print(\"Screen turned on\")\n    elif event['name'] == 'android.intent.action.SCREEN_OFF':\n        print(\"Screen turned off\")\n
      "},{"location":"qsl4a/core/events/#_13","title":"\u4f20\u611f\u5668\u4e8b\u4ef6\u5904\u7406","text":"
      # \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u5904\u7406\u4f20\u611f\u5668\u4e8b\u4ef6\nfor _ in range(100):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'sensors':\n        data = event['data']\n        print(f\"Accel: {data['xforce']}, {data['yforce']}, {data['zforce']}\")\n\ndroid.stopSensing()\n
      "},{"location":"qsl4a/core/events/#_14","title":"\u5e38\u89c1\u4e8b\u4ef6\u7c7b\u578b","text":"\u4e8b\u4ef6\u540d\u79f0 \u63cf\u8ff0 \u6765\u6e90 sensors \u4f20\u611f\u5668\u6570\u636e\u66f4\u65b0 startSensing* location GPS \u4f4d\u7f6e\u66f4\u65b0 startLocating phone \u7535\u8bdd\u72b6\u6001\u53d8\u5316 startTrackingPhoneState signal \u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316 startTrackingSignalStrength screen \u622a\u56fe\u5c31\u7eea fullGetScreenShot dialog \u5bf9\u8bdd\u6846\u54cd\u5e94 dialogShow*"},{"location":"qsl4a/core/events/#_15","title":"\u4e8b\u4ef6\u6570\u636e\u7ed3\u6784","text":"
      {\n    'name': 'event_name',\n    'data': {\n        # \u4e8b\u4ef6\u7279\u5b9a\u6570\u636e\n    },\n    'time': 1234567890  # \u65f6\u95f4\u6233\n}\n
      "},{"location":"qsl4a/core/intent/","title":"Intent \u7cfb\u7edf","text":"

      Android Intent \u7528\u4e8e\u542f\u52a8\u6d3b\u52a8\u3001\u53d1\u9001\u5e7f\u64ad\u548c\u5e94\u7528\u95f4\u901a\u4fe1\u3002QSL4A \u901a\u8fc7 Intent \u6a21\u5757\u63d0\u4f9b\u5b8c\u6574\u7684 Intent \u652f\u6301\u3002

      "},{"location":"qsl4a/core/intent/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
      import androidhelper\ndon = androidhelper.Android()\n
      "},{"location":"qsl4a/core/intent/#intent_1","title":"Intent \u5e38\u91cf","text":"

      \u901a\u8fc7 droid.Intent \u8bbf\u95ee\uff1a

      "},{"location":"qsl4a/core/intent/#_2","title":"\u64cd\u4f5c","text":"\u5e38\u91cf \u503c \u7528\u9014 ACTION_MAIN android.intent.action.MAIN \u5e94\u7528\u5165\u53e3\u70b9 ACTION_VIEW android.intent.action.VIEW \u67e5\u770b\u5185\u5bb9 ACTION_EDIT android.intent.action.EDIT \u7f16\u8f91\u5185\u5bb9 ACTION_PICK android.intent.action.PICK \u9009\u62e9\u9879\u76ee ACTION_SEND android.intent.action.SEND \u5206\u4eab\u5185\u5bb9 ACTION_SEARCH android.intent.action.SEARCH \u641c\u7d22"},{"location":"qsl4a/core/intent/#_3","title":"\u6807\u5fd7","text":"\u5e38\u91cf \u503c \u7528\u9014 FLAG_ACTIVITY_NEW_TASK 268435456 \u542f\u52a8\u65b0\u4efb\u52a1 FLAG_ACTIVITY_CLEAR_TASK 32768 \u6e05\u9664\u4efb\u52a1\u5806\u6808 FLAG_ACTIVITY_NEW_DOCUMENT 524288 \u65b0\u6587\u6863\u6a21\u5f0f"},{"location":"qsl4a/core/intent/#_4","title":"\u9644\u52a0\u6570\u636e","text":"\u5e38\u91cf \u7528\u9014 EXTRA_TEXT \u6587\u672c\u5185\u5bb9 EXTRA_STREAM \u6587\u4ef6 URI EXTRA_SUBJECT \u4e3b\u9898\u884c EXTRA_EMAIL \u7535\u5b50\u90ae\u4ef6\u5730\u5740"},{"location":"qsl4a/core/intent/#_5","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/intent/#makeintent","title":"makeIntent()","text":"

      \u521b\u5efa Intent \u5bf9\u8c61\u3002

      makeIntent(action, uri=None, type=None, extras=None, categories=None,\n           packagename=None, classname=None, flags=None)\n

      \u53c2\u6570\uff1a - action (str): Intent \u64cd\u4f5c\uff08\u4f8b\u5982 droid.Intent.ACTION_VIEW\uff09 - uri (str, optional): \u6570\u636e URI - type (str, optional): MIME \u7c7b\u578b - extras (dict, optional): \u9644\u52a0\u6570\u636e - categories (list, optional): Intent \u7c7b\u522b - packagename (str, optional): \u76ee\u6807\u5305 - classname (str, optional): \u76ee\u6807\u7c7b - flags (int, optional): Intent \u6807\u5fd7

      \u8fd4\u56de\uff1a Intent \u5bf9\u8c61

      "},{"location":"qsl4a/core/intent/#startactivityintent","title":"startActivityIntent()","text":"

      \u4f7f\u7528 Intent \u542f\u52a8 Activity\u3002

      startActivityIntent(intent, wait=None)\n

      \u53c2\u6570\uff1a - intent: makeIntent() \u8fd4\u56de\u7684 Intent \u5bf9\u8c61 - wait (bool, optional): \u963b\u585e\u76f4\u5230\u6d3b\u52a8\u5173\u95ed

      "},{"location":"qsl4a/core/intent/#startactivityforresultintent","title":"startActivityForResultIntent()","text":"

      \u542f\u52a8\u6d3b\u52a8\u5e76\u7b49\u5f85\u7ed3\u679c\u3002

      startActivityForResultIntent(intent)\n

      \u8fd4\u56de\uff1a Activity \u7ed3\u679c

      "},{"location":"qsl4a/core/intent/#sendbroadcastintent","title":"sendBroadcastIntent()","text":"

      \u53d1\u9001\u5e7f\u64ad\u3002

      sendBroadcastIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#view","title":"view()","text":"

      \u901a\u8fc7 URI \u67e5\u770b\u5185\u5bb9\u3002

      view(uri, type=None, extras=None)\n
      "},{"location":"qsl4a/core/intent/#pick","title":"pick()","text":"

      \u4ece URI \u9009\u62e9\u5185\u5bb9\u3002

      pick(uri)\n
      "},{"location":"qsl4a/core/intent/#intent_2","title":"\u5e38\u89c1 Intent \u65b9\u6cd5)","text":""},{"location":"qsl4a/core/intent/#scanbarcode","title":"scanBarcode()","text":"

      \u542f\u52a8\u6761\u7801\u626b\u63cf\u5668\u3002

      scanBarcode()\n

      \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/core/intent/#send","title":"send()","text":"

      \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u5185\u5bb9\u3002

      send(type, content)\n

      \u53c2\u6570\uff1a - type (str): MIME \u7c7b\u578b - content (str): \u8981\u5206\u4eab\u7684\u5185\u5bb9

      "},{"location":"qsl4a/core/intent/#sendtext","title":"sendText()","text":"

      \u53d1\u9001\u6587\u672c\u5185\u5bb9\u3002

      sendText(text)\n

      \u53c2\u6570\uff1a - text (str): \u8981\u53d1\u9001\u7684\u6587\u672c

      "},{"location":"qsl4a/core/intent/#sendemail","title":"sendEmail()","text":"

      \u53d1\u9001\u7535\u5b50\u90ae\u4ef6\u3002

      sendEmail(to, subject, body, attachment=None)\n

      \u53c2\u6570\uff1a - to (str or list): \u6536\u4ef6\u4eba\u7535\u5b50\u90ae\u4ef6\u5730\u5740 - subject (str): \u7535\u5b50\u90ae\u4ef6\u4e3b\u9898 - body (str): \u7535\u5b50\u90ae\u4ef6\u6b63\u6587 - attachment (str, optional): \u9644\u4ef6\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/core/intent/#pathtouri","title":"pathToUri()","text":"

      \u5c06\u6587\u4ef6\u8def\u5f84\u8f6c\u6362\u4e3a\u5185\u5bb9 URI\u3002

      pathToUri(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5185\u5bb9 URI \u5b57\u7b26\u4e32

      "},{"location":"qsl4a/core/intent/#openfile","title":"openFile()","text":"

      \u7528\u9002\u5f53\u7684\u5e94\u7528\u7a0b\u5e8f\u6253\u5f00\u6587\u4ef6\u3002

      openFile(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u6253\u5f00\u7684\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/core/intent/#sendfile","title":"sendFile()","text":"

      \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u6587\u4ef6\u3002

      sendFile(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u53d1\u9001\u7684\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/core/intent/#getpathtype","title":"getPathType()","text":"

      \u83b7\u53d6\u6587\u4ef6\u8def\u5f84\u7684 MIME \u7c7b\u578b\u3002

      getPathType(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a MIME \u7c7b\u578b\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/core/intent/#viewmap","title":"viewMap()","text":"

      \u5728\u6307\u5b9a\u4f4d\u7f6e\u6253\u5f00\u5730\u56fe\u3002

      viewMap(latitude, longitude)\n

      \u53c2\u6570\uff1a - latitude (float): \u7eac\u5ea6 - longitude (float): \u7ecf\u5ea6

      "},{"location":"qsl4a/core/intent/#viewcontacts","title":"viewContacts()","text":"

      \u6253\u5f00\u8054\u7cfb\u4eba\u5e94\u7528\u3002

      viewContacts()\n
      "},{"location":"qsl4a/core/intent/#search","title":"search()","text":"

      \u6267\u884c\u7f51\u7edc\u641c\u7d22\u3002

      search(query)\n

      \u53c2\u6570\uff1a - query (str): \u641c\u7d22\u67e5\u8be2

      "},{"location":"qsl4a/core/intent/#viewhtml","title":"viewHtml()","text":"

      \u67e5\u770b HTML \u5185\u5bb9\u3002

      viewHtml(content, encoding=None)\n

      \u53c2\u6570\uff1a - content (str): HTML \u5185\u5bb9 - encoding (str, optional): \u5b57\u7b26\u7f16\u7801

      "},{"location":"qsl4a/core/intent/#webviewshow","title":"webViewShow()","text":"

      \u5728 WebView \u4e2d\u663e\u793a\u7f51\u9875\u5185\u5bb9\u3002\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 viewHtml\u3002

      webViewShow(url)\n

      \u53c2\u6570\uff1a - url (str): \u7f51\u9875 URL

      "},{"location":"qsl4a/core/intent/#editoropen","title":"editorOpen()","text":"

      \u6253\u5f00\u6587\u672c\u7f16\u8f91\u5668\u3002

      editorOpen(path=None, create=False)\n

      \u53c2\u6570\uff1a - path (str, optional): \u8981\u7f16\u8f91\u7684\u6587\u4ef6\u8def\u5f84 - create (bool, optional): \u5982\u679c\u4e0d\u5b58\u5728\u5219\u521b\u5efa

      "},{"location":"qsl4a/core/intent/#uri","title":"\u8f85\u52a9\u7c7b\uff1aUri","text":"

      \u521b\u5efa Intent \u7684 URI \u5bf9\u8c61\uff1a

      from androidhelper.Intent import Uri\n\nuri = Uri(\"file:///sdcard/test.txt\")\n
      "},{"location":"qsl4a/core/intent/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/intent/#_7","title":"\u6253\u5f00\u7f51\u9875","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"http://www.example.com\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_8","title":"\u5206\u4eab\u6587\u672c","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_TEXT: \"Hello from QPython!\",\n        droid.Intent.EXTRA_SUBJECT: \"Test\"\n    },\n    type=\"text/plain\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_9","title":"\u6253\u5f00\u6587\u4ef6","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"file:///sdcard/document.pdf\",\n    type=\"application/pdf\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_10","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":"
      result = droid.pickContact()\ncontact_uri = result.result\n
      "},{"location":"qsl4a/core/intent/#_11","title":"\u53d1\u9001\u7535\u5b50\u90ae\u4ef6","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_EMAIL: [\"test@example.com\"],\n        droid.Intent.EXTRA_SUBJECT: \"Hello\",\n        droid.Intent.EXTRA_TEXT: \"Message body\"\n    },\n    type=\"message/rfc822\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_12","title":"\u6253\u5f00\u5e94\u7528","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_MAIN,\n    packagename=\"com.android.settings\",\n    classname=\"com.android.settings.Settings\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/hardware/bluetooth/","title":"\u84dd\u7259 API","text":"

      \u63a7\u5236\u84dd\u7259\u9002\u914d\u5668\u5e76\u4e0e\u84dd\u7259\u8bbe\u5907\u901a\u4fe1\u3002

      "},{"location":"qsl4a/hardware/bluetooth/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/hardware/bluetooth/#togglebluetoothstate","title":"toggleBluetoothState()","text":"

      \u6253\u5f00/\u5173\u95ed\u84dd\u7259\u3002

      toggleBluetoothState(enabled=None, prompt=True)\n

      \u53c2\u6570\uff1a - enabled (bool): True=\u5f00\uff0cFalse=\u5173\uff0cNone=\u5207\u6362 - prompt (bool): \u663e\u793a\u7528\u6237\u63d0\u793a

      "},{"location":"qsl4a/hardware/bluetooth/#checkbluetoothstate","title":"checkBluetoothState()","text":"

      \u68c0\u67e5\u84dd\u7259\u662f\u5426\u5df2\u542f\u7528\u3002

      checkBluetoothState()\n

      \u8fd4\u56de\uff1a True/False

      "},{"location":"qsl4a/hardware/bluetooth/#getlocalname","title":"GetLocalName()","text":"

      \u83b7\u53d6\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

      GetLocalName()\n
      "},{"location":"qsl4a/hardware/bluetooth/#setlocalname","title":"SetLocalName()","text":"

      \u8bbe\u7f6e\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

      SetLocalName(name)\n
      "},{"location":"qsl4a/hardware/bluetooth/#getscanmode","title":"GetScanMode()","text":"

      \u83b7\u53d6\u53ef\u53d1\u73b0\u6027\u6a21\u5f0f\u3002

      GetScanMode()\n

      \u8fd4\u56de\uff1a - -1: \u5df2\u7981\u7528 - 0: \u4e0d\u53ef\u53d1\u73b0\uff0c\u4e0d\u53ef\u8fde\u63a5 - 1: \u53ef\u8fde\u63a5\uff0c\u4e0d\u53ef\u53d1\u73b0 - 3: \u53ef\u8fde\u63a5\u4e14\u53ef\u53d1\u73b0

      "},{"location":"qsl4a/hardware/bluetooth/#makediscoverable","title":"MakeDiscoverable()","text":"

      \u4f7f\u8bbe\u5907\u53ef\u53d1\u73b0\u3002

      MakeDiscoverable(duration=300)\n

      \u53c2\u6570\uff1a - duration (int): \u53ef\u53d1\u73b0\u7684\u79d2\u6570

      "},{"location":"qsl4a/hardware/bluetooth/#_2","title":"\u53d1\u73b0","text":""},{"location":"qsl4a/hardware/bluetooth/#discoverystart","title":"DiscoveryStart()","text":"

      \u5f00\u59cb\u8bbe\u5907\u53d1\u73b0\u3002

      DiscoveryStart()\n
      "},{"location":"qsl4a/hardware/bluetooth/#discoverycancel","title":"DiscoveryCancel()","text":"

      \u53d6\u6d88\u53d1\u73b0\u3002

      DiscoveryCancel()\n
      "},{"location":"qsl4a/hardware/bluetooth/#getreceiveddevices","title":"GetReceivedDevices()","text":"

      \u83b7\u53d6\u53d1\u73b0\u7684\u8bbe\u5907\u3002

      GetReceivedDevices()\n

      \u8fd4\u56de\uff1a \u8bbe\u5907\u4fe1\u606f\u5b57\u5178\u5217\u8868

      "},{"location":"qsl4a/hardware/bluetooth/#getbondeddevices","title":"GetBondedDevices()","text":"

      \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\u3002

      GetBondedDevices()\n

      \u8fd4\u56de\uff1a \u914d\u5bf9\u8bbe\u5907\u4fe1\u606f\u5217\u8868

      "},{"location":"qsl4a/hardware/bluetooth/#_3","title":"\u8fde\u63a5","text":""},{"location":"qsl4a/hardware/bluetooth/#connect","title":"Connect()","text":"

      \u8fde\u63a5\u5230\u8bbe\u5907\u3002

      Connect(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", address=None)\n

      \u53c2\u6570\uff1a - uuid (str): \u670d\u52a1 UUID - address (str): \u8bbe\u5907\u5730\u5740\uff08None = \u663e\u793a\u9009\u62e9\u5668\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/hardware/bluetooth/#accept","title":"Accept()","text":"

      \u63a5\u53d7\u4f20\u5165\u8fde\u63a5\u3002

      Accept(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", timeout=0)\n
      "},{"location":"qsl4a/hardware/bluetooth/#activeconnections","title":"ActiveConnections()","text":"

      \u68c0\u67e5\u6d3b\u52a8\u8fde\u63a5\u3002

      ActiveConnections()\n
      "},{"location":"qsl4a/hardware/bluetooth/#stop","title":"Stop()","text":"

      \u65ad\u5f00\u8fde\u63a5\u3002

      Stop(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#_4","title":"\u901a\u4fe1","text":""},{"location":"qsl4a/hardware/bluetooth/#write","title":"Write()","text":"

      \u53d1\u9001 ASCII \u6570\u636e\u3002

      Write(ascii, connID=\"\")\n
      "},{"location":"qsl4a/hardware/bluetooth/#writebinary","title":"WriteBinary()","text":"

      \u53d1\u9001\u4e8c\u8fdb\u5236\u6570\u636e\uff08base64 \u7f16\u7801\uff09\u3002

      WriteBinary(base64, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#read","title":"Read()","text":"

      \u8bfb\u53d6 ASCII \u6570\u636e\u3002

      Read(bufferSize=4096, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readbinary","title":"ReadBinary()","text":"

      \u8bfb\u53d6\u4e8c\u8fdb\u5236\u6570\u636e\u3002

      ReadBinary(bufferSize=4096, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readline","title":"ReadLine()","text":"

      \u8bfb\u53d6\u4e00\u884c\u3002

      ReadLine(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readready","title":"ReadReady()","text":"

      \u68c0\u67e5\u662f\u5426\u6709\u53ef\u7528\u6570\u636e\u3002

      ReadReady(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u7528\u84dd\u7259\ndroid.toggleBluetoothState(True)\n\n# \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\ndevices = droid.GetBondedDevices().result\nfor dev in devices:\n    print(f\"{dev['name']}: {dev['address']}\")\n\n# \u8fde\u63a5\u5230\u8bbe\u5907\ndroid.Connect(address=\"00:11:22:33:44:55\")\n\n# \u53d1\u9001\u6570\u636e\ndroid.Write(\"Hello Bluetooth!\")\n\n# \u8bfb\u53d6\u54cd\u5e94\ndata = droid.Read(1024).result\n
      "},{"location":"qsl4a/hardware/camera/","title":"\u76f8\u673a API","text":"

      \u62cd\u6444\u7167\u7247\u548c\u5f55\u5236\u89c6\u9891\u3002

      "},{"location":"qsl4a/hardware/camera/#_1","title":"\u7167\u7247\u62cd\u6444","text":""},{"location":"qsl4a/hardware/camera/#takepicture","title":"takePicture()","text":"

      \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u6444\u7167\u7247\u3002

      takePicture(path=None)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8fd4\u56de\u56fe\u50cf\u6570\u636e

      \u8fd4\u56de\uff1a \u56fe\u50cf\u8def\u5f84\u6216\u56fe\u50cf\u6570\u636e

      "},{"location":"qsl4a/hardware/camera/#cameracapturepicture","title":"cameraCapturePicture()","text":"

      \u4f7f\u7528\u9ad8\u7ea7\u76f8\u673a\u63a7\u5236\u62cd\u6444\u7167\u7247\u3002

      cameraCapturePicture(targetPath=None, cameraId=0, useAutoFocus=True)\n

      \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - useAutoFocus (bool): \u542f\u7528\u81ea\u52a8\u5bf9\u7126

      \u8fd4\u56de\uff1a \u62cd\u6444\u7684\u56fe\u50cf\u8def\u5f84

      "},{"location":"qsl4a/hardware/camera/#camerasettorchmode","title":"cameraSetTorchMode()","text":"

      \u63a7\u5236\u76f8\u673a\u95ea\u5149\u706f/\u624b\u7535\u7b52\u3002

      cameraSetTorchMode(enabled)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u6253\u5f00\uff0cFalse \u5173\u95ed

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/hardware/camera/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

      \u622a\u56fe\u3002

      imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

      "},{"location":"qsl4a/hardware/camera/#_2","title":"\u89c6\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#takevideo","title":"takeVideo()","text":"

      \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\u3002

      takeVideo(path=None, quality=1)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-4\uff09 - 0: 160x120 - 1: 320x240 - 2: 352x288 - 3: 640x480 - 4: 800x480

      "},{"location":"qsl4a/hardware/camera/#recordercapturevideo","title":"recorderCaptureVideo()","text":"

      \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\u3002

      recorderCaptureVideo(targetPath=None, duration=10, cameraId=0, quality=8)\n

      \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - duration (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a10\uff09 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-8\uff0c\u8d8a\u9ad8\u8d8a\u597d\uff09

      \u8fd4\u56de\uff1a \u89c6\u9891\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/hardware/camera/#recordaudio","title":"recordAudio()","text":"

      \u5f55\u5236\u97f3\u9891\u3002

      recordAudio()\n

      \u8fd4\u56de\uff1a \u97f3\u9891\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/hardware/camera/#_3","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

      \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\u3002

      recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

      \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\uff09 - targetPixels (int): \u5206\u8fa8\u7387 - frameRate (int): FPS - bitRate (int): \u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa - autoStart (bool): \u7acb\u5373\u5f00\u59cb

      "},{"location":"qsl4a/hardware/camera/#recorderstart","title":"recorderStart()","text":"

      \u5f00\u59cb\u5f55\u5236\u3002

      recorderStart()\n
      "},{"location":"qsl4a/hardware/camera/#recorderpause","title":"recorderPause()","text":"

      \u6682\u505c\u5f55\u5236\u3002

      recorderPause()\n
      "},{"location":"qsl4a/hardware/camera/#recorderresume","title":"recorderResume()","text":"

      \u6062\u590d\u5f55\u5236\u3002

      recorderResume()\n
      "},{"location":"qsl4a/hardware/camera/#_4","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/camera/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

      \u5f00\u59cb\u97f3\u91cf\u68c0\u6d4b\u3002

      recorderSoundVolumeDetect(interval=100)\n
      "},{"location":"qsl4a/hardware/camera/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

      \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

      recorderSoundVolumeGetDb()\n
      "},{"location":"qsl4a/hardware/camera/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u7167\nphoto_path = droid.takePicture(\"/sdcard/photo.jpg\").result\nprint(f\"Photo saved: {photo_path}\")\n\n# \u4f7f\u7528\u524d\u7f6e\u76f8\u673a\u548c\u81ea\u52a8\u5bf9\u7126\u62cd\u7167\ncamera_path = droid.cameraCapturePicture(\"/sdcard/selfie.jpg\", cameraId=1, useAutoFocus=True).result\nprint(f\"Front camera photo: {camera_path}\")\n\n# \u63a7\u5236\u95ea\u5149\u706f\ndroid.cameraSetTorchMode(True)  # \u6253\u5f00\u95ea\u5149\u706f\n\n# \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\nvideo_path = droid.takeVideo(\"/sdcard/video.mp4\", quality=3).result\nprint(f\"Video saved: {video_path}\")\n\n# \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\nvideo_path = droid.recorderCaptureVideo(\"/sdcard/movie.mp4\", duration=30, cameraId=0, quality=8).result\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n
      "},{"location":"qsl4a/hardware/recorder/","title":"\u97f3\u9891\u5f55\u5236 API","text":"

      \u4ece\u9ea6\u514b\u98ce\u548c\u8bbe\u5907\u5c4f\u5e55\u5f55\u5236\u97f3\u9891\u3002

      "},{"location":"qsl4a/hardware/recorder/#_1","title":"\u97f3\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recordaudio","title":"recordAudio()","text":"

      \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\u3002

      recordAudio()\n

      \u8fd4\u56de\uff1a \u5f55\u5236\u7684\u97f3\u9891\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/hardware/recorder/#recorderstartmicrophone","title":"recorderStartMicrophone()","text":"

      \u5f00\u59cb\u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\u3002

      recorderStartMicrophone(targetPath=None)\n

      \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u5f55\u5236\u7684\u8def\u5f84

      "},{"location":"qsl4a/hardware/recorder/#_2","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

      \u5f00\u59cb\u5e26\u97f3\u9891\u7684\u5c4f\u5e55\u5f55\u5236\u3002

      recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

      \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\u97f3\u9891\uff09 - targetPixels (int): \u76ee\u6807\u5206\u8fa8\u7387\uff08\u50cf\u7d20\uff09 - frameRate (int): \u6bcf\u79d2\u5e27\u6570\uff08\u9ed8\u8ba4\uff1a30\uff09 - bitRate (int): \u89c6\u9891\u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa\u89c6\u9891 - autoStart (bool): \u7acb\u5373\u5f00\u59cb\u5f55\u5236

      \u8fd4\u56de\uff1a \u64cd\u4f5c\u7ed3\u679c

      "},{"location":"qsl4a/hardware/recorder/#recorderstart","title":"recorderStart()","text":"

      \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\uff08\u5f53 autoStart=False \u65f6\uff09\u3002

      recorderStart()\n
      "},{"location":"qsl4a/hardware/recorder/#recorderpause","title":"recorderPause()","text":"

      \u6682\u505c\u6b63\u5728\u8fdb\u884c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

      recorderPause()\n
      "},{"location":"qsl4a/hardware/recorder/#recorderresume","title":"recorderResume()","text":"

      \u6062\u590d\u6682\u505c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

      recorderResume()\n
      "},{"location":"qsl4a/hardware/recorder/#_3","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/recorder/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

      \u5f00\u59cb\u76d1\u63a7\u97f3\u91cf\u7ea7\u522b\u3002

      recorderSoundVolumeDetect(interval=100)\n

      \u53c2\u6570\uff1a - interval (int): \u68c0\u6d4b\u95f4\u9694\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a100\uff09

      "},{"location":"qsl4a/hardware/recorder/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

      \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

      recorderSoundVolumeGetDb()\n

      \u8fd4\u56de\uff1a \u5f53\u524d\u97f3\u91cf\u7ea7\u522b\uff08dB\uff09

      "},{"location":"qsl4a/hardware/recorder/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\nprint(\"Recording audio...\")\naudio_path = droid.recordAudio().result\nprint(f\"Saved to: {audio_path}\")\n\n# \u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\ndroid.recorderStartMicrophone(\"/sdcard/my_recording.mp3\")\ntime.sleep(5)\ndroid.recorderStop()\n\n# \u5e26\u97f3\u9891\u5f55\u5236\u5c4f\u5e55\nprint(\"Starting screen recording...\")\ndroid.recorderStartScreenRecord(\n    path=\"/sdcard/screen_record.mp4\",\n    audio=1,\n    frameRate=30,\n    autoStart=True\n)\ntime.sleep(10)\ndroid.recorderStop()\n\n# \u76d1\u63a7\u97f3\u91cf\ndroid.recorderSoundVolumeDetect(interval=100)\ntime.sleep(3)\nvolume = droid.recorderSoundVolumeGetDb().result\nprint(f\"Current volume: {volume} dB\")\n
      "},{"location":"qsl4a/hardware/usbserial/","title":"USB \u4e3b\u673a\u4e32\u884c API","text":"

      \u4e0e USB \u4e32\u884c\u8bbe\u5907\u901a\u4fe1\uff08\u9700\u8981 USB OTG \u652f\u6301\u548c Android 3.1+\uff09\u3002

      "},{"location":"qsl4a/hardware/usbserial/#usb","title":"USB \u4e32\u884c\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialopen","title":"usbHostSerialOpen()","text":"

      \u6253\u5f00\u4e0e USB \u4e32\u884c\u8bbe\u5907\u7684\u8fde\u63a5\u3002

      usbHostSerialOpen(device, baudRate=9600)\n

      \u53c2\u6570\uff1a - device (str): USB \u8bbe\u5907\u8def\u5f84\u6216\u6807\u8bc6\u7b26 - baudRate (int): \u6ce2\u7279\u7387\uff08\u9ed8\u8ba4\uff1a9600\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u6253\u5f00\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialclose","title":"usbHostSerialClose()","text":"

      \u5173\u95ed USB \u4e32\u884c\u8fde\u63a5\u3002

      usbHostSerialClose()\n
      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialread","title":"usbHostSerialRead()","text":"

      \u4ece USB \u4e32\u884c\u8bfb\u53d6\u6570\u636e\u3002

      usbHostSerialRead(bufferSize=1024)\n

      \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570\uff08\u9ed8\u8ba4\uff1a1024\uff09

      \u8fd4\u56de\uff1a \u8bfb\u53d6\u7684\u6570\u636e\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwrite","title":"usbHostSerialWrite()","text":"

      \u5411 USB \u4e32\u884c\u5199\u5165\u6570\u636e\u3002

      usbHostSerialWrite(data)\n

      \u53c2\u6570\uff1a - data (str): \u8981\u5199\u5165\u7684\u5b57\u7b26\u4e32\u6570\u636e

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialavailable","title":"usbHostSerialAvailable()","text":"

      \u68c0\u67e5\u662f\u5426\u6709\u53ef\u8bfb\u53d6\u7684\u6570\u636e\u3002

      usbHostSerialAvailable()\n

      \u8fd4\u56de\uff1a \u53ef\u7528\u5b57\u8282\u6570

      "},{"location":"qsl4a/hardware/usbserial/#_1","title":"\u914d\u7f6e\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetbaudrate","title":"usbHostSerialSetBaudRate()","text":"

      \u8bbe\u7f6e\u6ce2\u7279\u7387\u3002

      usbHostSerialSetBaudRate(baudRate)\n

      \u53c2\u6570\uff1a - baudRate (int): \u6ce2\u7279\u7387

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetdatabits","title":"usbHostSerialSetDataBits()","text":"

      \u8bbe\u7f6e\u6570\u636e\u4f4d\uff085\u30016\u30017 \u6216 8\uff09\u3002

      usbHostSerialSetDataBits(dataBits)\n

      \u53c2\u6570\uff1a - dataBits (int): \u6570\u636e\u4f4d\uff085-8\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetstopbits","title":"usbHostSerialSetStopBits()","text":"

      \u8bbe\u7f6e\u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09\u3002

      usbHostSerialSetStopBits(stopBits)\n

      \u53c2\u6570\uff1a - stopBits (float): \u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetparity","title":"usbHostSerialSetParity()","text":"

      \u8bbe\u7f6e\u6821\u9a8c\u4f4d\uff08\u65e0\u3001\u5947\u3001\u5076\u3001\u6807\u8bb0\u3001\u7a7a\u683c\uff09\u3002

      usbHostSerialSetParity(parity)\n

      \u53c2\u6570\uff1a - parity (str): \u6821\u9a8c\u6a21\u5f0f\uff08'none'\u3001'odd'\u3001'even'\u3001'mark'\u3001'space'\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetflowcontrol","title":"usbHostSerialSetFlowControl()","text":"

      \u8bbe\u7f6e\u6d41\u63a7\u5236\uff08\u65e0\u3001\u786c\u4ef6\u3001\u8f6f\u4ef6\uff09\u3002

      usbHostSerialSetFlowControl(flowControl)\n

      \u53c2\u6570\uff1a - flowControl (str): \u6d41\u63a7\u5236\u6a21\u5f0f\uff08'none'\u3001'hardware'\u3001'software'\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialreadhex","title":"usbHostSerialReadHex()","text":"

      \u4ee5\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u8bfb\u53d6\u6570\u636e\u3002

      usbHostSerialReadHex(bufferSize=1024)\n

      \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570

      \u8fd4\u56de\uff1a \u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwritehex","title":"usbHostSerialWriteHex()","text":"

      \u4ece\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u5199\u5165\u6570\u636e\u3002

      usbHostSerialWriteHex(hexString)\n

      \u53c2\u6570\uff1a - hexString (str): \u8981\u5199\u5165\u7684\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/hardware/usbserial/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6253\u5f00 USB \u4e32\u884c\u8fde\u63a5\nif droid.usbHostSerialOpen(\"/dev/bus/usb/001/001\", 115200).result:\n    print(\"USB serial opened\")\n\n    # \u5199\u5165\u6570\u636e\n    droid.usbHostSerialWrite(\"AT\\r\")\n\n    # \u8bfb\u53d6\u54cd\u5e94\n    response = droid.usbHostSerialRead(1024).result\n    print(f\"Response: {response}\")\n\n    # \u6216\u4f7f\u7528\u5341\u516d\u8fdb\u5236\n    droid.usbHostSerialWriteHex(\"41540D0A\")  # \"AT\\r\\n\"\n\n    # \u5173\u95ed\u8fde\u63a5\n    droid.usbHostSerialClose()\n

      \u6ce8\u610f\uff1a USB \u4e32\u884c\u9700\u8981\uff1a - Android 3.1+ (API 12) - USB OTG \u7ebf/\u9002\u914d\u5668 - \u8bbe\u5907\u4e0a\u7684 USB \u4e3b\u673a\u6a21\u5f0f\u652f\u6301 - \u517c\u5bb9\u7684\u4e32\u884c\u8bbe\u5907

      "},{"location":"qsl4a/hardware/webcam/","title":"\u7f51\u7edc\u6444\u50cf\u5934 API","text":"

      \u4f7f\u7528 MJPEG \u4ece\u8bbe\u5907\u76f8\u673a\u6d41\u5f0f\u4f20\u8f93\u89c6\u9891\u3002

      "},{"location":"qsl4a/hardware/webcam/#mjpeg","title":"MJPEG \u6d41\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#webcamstart","title":"webcamStart()","text":"

      \u4ece\u7f51\u7edc\u6444\u50cf\u5934\u542f\u52a8 MJPEG \u6d41\u3002

      webcamStart(resolutionLevel=0, jpegQuality=20, port=0)\n

      \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf 1-100\uff08\u9ed8\u8ba4\uff1a20\uff09 - port (int): \u7aef\u53e3\u53f7\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\uff09

      \u8fd4\u56de\uff1a \u6d41\u7684 (\u5730\u5740, \u7aef\u53e3) \u5143\u7ec4

      "},{"location":"qsl4a/hardware/webcam/#webcamadjustquality","title":"webcamAdjustQuality()","text":"

      \u8c03\u6574\u6d3b\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u7684\u8d28\u91cf\u3002

      webcamAdjustQuality(resolutionLevel=0, jpegQuality=20)\n

      \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b - jpegQuality (int): JPEG \u8d28\u91cf 1-100

      "},{"location":"qsl4a/hardware/webcam/#webcamstop","title":"webcamStop()","text":"

      \u505c\u6b62\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u3002

      webcamStop()\n
      "},{"location":"qsl4a/hardware/webcam/#_1","title":"\u76f8\u673a\u9884\u89c8\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#camerastartpreview","title":"cameraStartPreview()","text":"

      \u5f00\u59cb\u5e26\u4e8b\u4ef6\u751f\u6210\u7684\u76f8\u673a\u9884\u89c8\u6a21\u5f0f\u3002

      cameraStartPreview(resolutionLevel=0, jpegQuality=20, filepath=None)\n

      \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf\uff08\u9ed8\u8ba4\uff1a20\uff09 - filepath (str, optional): \u4fdd\u5b58\u9884\u89c8\u5e27\u7684\u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      \u6ce8\u610f\uff1a \u751f\u6210\u5e26\u6709\u5e27\u6570\u636e\u7684 'preview' \u4e8b\u4ef6\u3002

      "},{"location":"qsl4a/hardware/webcam/#camerastoppreview","title":"cameraStopPreview()","text":"

      \u505c\u6b62\u76f8\u673a\u9884\u89c8\u3002

      cameraStopPreview()\n
      "},{"location":"qsl4a/hardware/webcam/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\nstream_info = droid.webcamStart(\n    resolutionLevel=0,\n    jpegQuality=30,\n    port=8080\n).result\nprint(f\"Stream available at {stream_info[0]}:{stream_info[1]}\")\n\n# \u6d41\u5f0f\u4f20\u8f93\u65f6\u8c03\u6574\u8d28\u91cf\ntime.sleep(5)\ndroid.webcamAdjustQuality(resolutionLevel=1, jpegQuality=50)\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.webcamStop()\n\n# \u6216\u4f7f\u7528\u9884\u89c8\u6a21\u5f0f\nprint(\"Starting preview...\")\ndroid.cameraStartPreview()\n\n# \u7b49\u5f85\u9884\u89c8\u4e8b\u4ef6\nfor i in range(10):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'preview':\n        print(f\"Got preview frame: {event['data']}\")\n\ndroid.cameraStopPreview()\n
      "},{"location":"qsl4a/media/image/","title":"\u56fe\u50cf\u5904\u7406 API","text":"

      \u538b\u7f29\u548c\u5904\u7406\u56fe\u50cf\u3002

      "},{"location":"qsl4a/media/image/#_1","title":"\u56fe\u50cf\u538b\u7f29","text":""},{"location":"qsl4a/media/image/#imagecompress","title":"imageCompress()","text":"

      \u538b\u7f29\u56fe\u50cf\u6587\u4ef6\u3002

      imageCompress(srcPath, destPath, targetByteSize=0, targetWidth=0, targetHeight=0)\n

      \u53c2\u6570\uff1a - srcPath (str): \u6e90\u56fe\u50cf\u8def\u5f84 - destPath (str): \u8f93\u51fa\u8def\u5f84 - targetByteSize (int): \u76ee\u6807\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff080 = \u65e0\u9650\u5236\uff09 - targetWidth (int): \u76ee\u6807\u5bbd\u5ea6\uff080 = \u539f\u59cb\uff09 - targetHeight (int): \u76ee\u6807\u9ad8\u5ea6\uff080 = \u539f\u59cb\uff09

      \u8fd4\u56de\uff1a \u538b\u7f29\u540e\u7684\u56fe\u50cf\u8def\u5f84

      "},{"location":"qsl4a/media/image/#_2","title":"\u622a\u56fe","text":""},{"location":"qsl4a/media/image/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

      \u622a\u53d6\u5c4f\u5e55\u3002

      imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

      \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

      \u8fd4\u56de\uff1a \u622a\u56fe\u8def\u5f84

      "},{"location":"qsl4a/media/image/#_3","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/image/#videoplay","title":"videoPlay()","text":"

      \u5728\u5168\u5c4f\u6a21\u5f0f\u4e0b\u64ad\u653e\u89c6\u9891\u6587\u4ef6\u3002

      videoPlay(path, wait=True)\n

      \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

      "},{"location":"qsl4a/media/image/#_4","title":"\u6761\u7801\u626b\u63cf","text":""},{"location":"qsl4a/media/image/#scanbarcodefromimage","title":"scanBarcodeFromImage()","text":"

      \u4ece\u56fe\u50cf\u6587\u4ef6\u626b\u63cf\u6761\u7801/\u4e8c\u7ef4\u7801\u3002

      scanBarcodeFromImage(path, compressRatio=0, x=0, y=0, width=0, height=0)\n

      \u53c2\u6570\uff1a - path (str): \u56fe\u50cf\u6587\u4ef6\u8def\u5f84 - compressRatio (int): \u538b\u7f29\u6bd4\uff080 = \u4e0d\u538b\u7f29\uff09 - x, y, width, height (int): \u8981\u626b\u63cf\u7684\u533a\u57df\uff080 = \u5b8c\u6574\u56fe\u50cf\uff09

      \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5185\u5bb9

      "},{"location":"qsl4a/media/image/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n\n# \u538b\u7f29\u56fe\u50cf\ncompressed = droid.imageCompress(\n    \"/sdcard/large_photo.jpg\",\n    \"/sdcard/compressed.jpg\",\n    targetByteSize=102400,  # \u76ee\u6807\u7ea6 100KB\n    targetWidth=1920,\n    targetHeight=1080\n).result\nprint(f\"Saved: {compressed}\")\n\n# \u64ad\u653e\u89c6\u9891\nvideo_path = \"/sdcard/movie.mp4\"\ndroid.videoPlay(video_path, wait=True)\n\n# \u4ece\u56fe\u50cf\u626b\u63cf\u6761\u7801\nresult = droid.scanBarcodeFromImage(\"/sdcard/qr_code.png\").result\nprint(f\"Barcode: {result}\")\n
      "},{"location":"qsl4a/media/mediaplayer/","title":"\u5a92\u4f53\u64ad\u653e\u5668 API","text":"

      \u63a7\u5236\u97f3\u9891\u548c\u89c6\u9891\u64ad\u653e\u3002

      "},{"location":"qsl4a/media/mediaplayer/#_1","title":"\u64ad\u653e\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplay","title":"mediaPlay()","text":"

      \u64ad\u653e\u5a92\u4f53\u6587\u4ef6\u3002

      mediaPlay(url, tag=\"default\", play=True)\n

      \u53c2\u6570\uff1a - url (str): \u5a92\u4f53\u6587\u4ef6\u8def\u5f84\u6216 URL - tag (str): \u64ad\u653e\u5668\u6807\u8bc6\u7b26 - play (bool): \u81ea\u52a8\u5f00\u59cb\u64ad\u653e

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaystart","title":"mediaPlayStart()","text":"

      \u5f00\u59cb\u64ad\u653e\u3002

      mediaPlayStart(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplaypause","title":"mediaPlayPause()","text":"

      \u6682\u505c\u64ad\u653e\u3002

      mediaPlayPause(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplayclose","title":"mediaPlayClose()","text":"

      \u5173\u95ed\u64ad\u653e\u5668\u3002

      mediaPlayClose(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplayseek","title":"mediaPlaySeek()","text":"

      \u8df3\u8f6c\u5230\u4f4d\u7f6e\u3002

      mediaPlaySeek(msec, tag=\"default\")\n

      \u53c2\u6570\uff1a - msec (int): \u4f4d\u7f6e\uff08\u6beb\u79d2\uff09

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaysetlooping","title":"mediaPlaySetLooping()","text":"

      \u8bbe\u7f6e\u5faa\u73af\u6a21\u5f0f\u3002

      mediaPlaySetLooping(enabled, tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#_2","title":"\u64ad\u653e\u5668\u4fe1\u606f","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplayinfo","title":"mediaPlayInfo()","text":"

      \u83b7\u53d6\u64ad\u653e\u4fe1\u606f\u3002

      mediaPlayInfo(tag=\"default\")\n

      \u8fd4\u56de\uff1a \u5305\u542b\u65f6\u957f\u3001\u4f4d\u7f6e\u7b49\u7684\u5b57\u5178

      "},{"location":"qsl4a/media/mediaplayer/#mediaisplaying","title":"mediaIsPlaying()","text":"

      \u68c0\u67e5\u662f\u5426\u6b63\u5728\u64ad\u653e\u3002

      mediaIsPlaying(tag=\"default\")\n

      \u8fd4\u56de\uff1a True/False

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaylist","title":"mediaPlayList()","text":"

      \u5217\u51fa\u6d3b\u52a8\u64ad\u653e\u5668\u3002

      mediaPlayList()\n
      "},{"location":"qsl4a/media/mediaplayer/#_3","title":"\u97f3\u91cf\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#getmediavolume","title":"getMediaVolume()","text":"

      \u83b7\u53d6\u5a92\u4f53\u97f3\u91cf\u3002

      getMediaVolume()\n

      \u8fd4\u56de\uff1a \u97f3\u91cf\u7ea7\u522b\uff080-15\uff09

      "},{"location":"qsl4a/media/mediaplayer/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

      getMaxMediaVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#getringervolume","title":"getRingerVolume()","text":"

      \u83b7\u53d6\u94c3\u58f0\u97f3\u91cf\u3002

      getRingerVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

      getMaxRingerVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#_4","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/mediaplayer/#videoplay","title":"videoPlay()","text":"

      \u5168\u5c4f\u64ad\u653e\u89c6\u9891\u3002

      videoPlay(path, wait=True)\n

      \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210

      "},{"location":"qsl4a/media/mediaplayer/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u64ad\u653e\u97f3\u9891\ndroid.mediaPlay(\"/sdcard/music.mp3\", tag=\"music\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.mediaIsPlaying(\"music\").result:\n    info = droid.mediaPlayInfo(\"music\").result\n    print(f\"Playing: {info}\")\n\n# \u8df3\u8f6c\u5230 30 \u79d2\ndroid.mediaPlaySeek(30000, \"music\")\n\n# \u5173\u95ed\ndroid.mediaPlayClose(\"music\")\n\n# \u64ad\u653e\u89c6\u9891\ndroid.videoPlay(\"/sdcard/movie.mp4\", wait=True)\n
      "},{"location":"qsl4a/special/cipher/","title":"\u5bc6\u7801 API","text":"

      \u7528\u4e8e\u5b89\u5168\u6570\u636e\u5b58\u50a8\u7684\u52a0\u5bc6\u548c\u89e3\u5bc6\u5de5\u5177\u3002

      "},{"location":"qsl4a/special/cipher/#_1","title":"\u521d\u59cb\u5316","text":""},{"location":"qsl4a/special/cipher/#cipherinit","title":"cipherInit()","text":"

      \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u548c\u7b97\u6cd5\u521d\u59cb\u5316\u5bc6\u7801\u5668\u3002

      cipherInit(key, algorithm=\"AES/CBC/PKCS5Padding\", encodingFormat=\"\", initialVector=\"\")\n

      \u53c2\u6570\uff1a - key (str or bytes): \u52a0\u5bc6\u5bc6\u94a5 - algorithm (str): \u5bc6\u7801\u7b97\u6cd5\uff08\u9ed8\u8ba4\uff1a\"AES/CBC/PKCS5Padding\"\uff09 - encodingFormat (str): \u7f16\u7801\u683c\u5f0f - initialVector (str or bytes): \u52a0\u5bc6\u7684\u521d\u59cb\u5411\u91cf

      \u8fd4\u56de\uff1a \u521d\u59cb\u5316\u7ed3\u679c

      \u6ce8\u610f\uff1a \u5fc5\u987b\u5728\u4efb\u4f55\u52a0\u5bc6/\u89e3\u5bc6\u64cd\u4f5c\u4e4b\u524d\u8c03\u7528\u3002

      "},{"location":"qsl4a/special/cipher/#_2","title":"\u52a0\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#encryptstring","title":"encryptString()","text":"

      \u52a0\u5bc6\u5b57\u7b26\u4e32\u3002

      encryptString(plainText)\n

      \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c

      \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/special/cipher/#encryptbytes","title":"encryptBytes()","text":"

      \u52a0\u5bc6\u5b57\u8282\u6570\u636e\u3002

      encryptBytes(data)\n

      \u53c2\u6570\uff1a - data (bytes): \u8981\u52a0\u5bc6\u7684\u6570\u636e

      \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u8282

      "},{"location":"qsl4a/special/cipher/#encryptstringtofile","title":"encryptStringToFile()","text":"

      \u52a0\u5bc6\u5b57\u7b26\u4e32\u5230\u6587\u4ef6\u3002

      encryptStringToFile(plainText, filePath)\n

      \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c - filePath (str): \u8f93\u51fa\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/special/cipher/#encryptbytestofile","title":"encryptBytesToFile()","text":"

      \u52a0\u5bc6\u5b57\u8282\u5230\u6587\u4ef6\u3002

      encryptBytesToFile(data, filePath)\n
      "},{"location":"qsl4a/special/cipher/#_3","title":"\u89e3\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#decryptstring","title":"decryptString()","text":"

      \u89e3\u5bc6\u4e3a\u5b57\u7b26\u4e32\u3002

      decryptString(cipherText)\n

      \u53c2\u6570\uff1a - cipherText (str): \u52a0\u5bc6\u7684\u6587\u672c

      \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/special/cipher/#decryptbytes","title":"decryptBytes()","text":"

      \u89e3\u5bc6\u4e3a\u5b57\u8282\u3002

      decryptBytes(data)\n

      \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u8282

      "},{"location":"qsl4a/special/cipher/#decryptfiletostring","title":"decryptFileToString()","text":"

      \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u7b26\u4e32\u3002

      decryptFileToString(filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryptfiletobytes","title":"decryptFileToBytes()","text":"

      \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u8282\u3002

      decryptFileToBytes(filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryptfile","title":"decryptFile()","text":"

      \u89e3\u5bc6\u6587\u4ef6\u5230\u6587\u4ef6\u3002

      decryptFile(srcPath, destPath)\n
      "},{"location":"qsl4a/special/cipher/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u521d\u59cb\u5316\u5bc6\u7801\u5668\ndroid.cipherInit(\"my_secret_key_1234\")\n\n# \u52a0\u5bc6\u5b57\u7b26\u4e32\nencrypted = droid.encryptString(\"Secret message!\").result\nprint(f\"Encrypted: {encrypted}\")\n\n# \u89e3\u5bc6\u5b57\u7b26\u4e32\ndecrypted = droid.decryptString(encrypted).result\nprint(f\"Decrypted: {decrypted}\")\n\n# \u52a0\u5bc6\u5230\u6587\u4ef6\ndroid.encryptStringToFile(\"My secret data\", \"/sdcard/secret.dat\")\n\n# \u4ece\u6587\u4ef6\u89e3\u5bc6\ndata = droid.decryptFileToString(\"/sdcard/secret.dat\").result\nprint(data)\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u7b97\u6cd5\u548c IV \u521d\u59cb\u5316\ndroid.cipherInit(\n    key=\"my_key\",\n    algorithm=\"AES/CBC/PKCS5Padding\",\n    initialVector=\"0123456789abcdef\"\n)\n
      "},{"location":"qsl4a/special/pgptai/","title":"PGPT AI API","text":"

      \u8bed\u97f3\u8f6c\u6587\u672c\u548c AI \u670d\u52a1\u96c6\u6210\u3002

      "},{"location":"qsl4a/special/pgptai/#_1","title":"\u5148\u51b3\u6761\u4ef6","text":"
      pip install pgptAI\n
      "},{"location":"qsl4a/special/pgptai/#_2","title":"\u8bed\u97f3\u8bc6\u522b","text":""},{"location":"qsl4a/special/pgptai/#speechtotext","title":"speechToText()","text":"

      \u5c06\u8bed\u97f3\u8f6c\u6362\u4e3a\u6587\u672c\u3002

      speechToText(RecordSecond=10, AmrFile=None, Language=None)\n

      \u53c2\u6570\uff1a - RecordSecond (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09 - AmrFile (str, optional): \u73b0\u6709\u97f3\u9891\u6587\u4ef6\u8def\u5f84 - Language (str, optional): \u8bed\u8a00\u4ee3\u7801\uff08'en'\u3001'zh'\uff09

      \u8fd4\u56de\uff1a \u8f6c\u5f55\u7684\u6587\u672c

      "},{"location":"qsl4a/special/pgptai/#_3","title":"\u6587\u672c\u8f6c\u8bed\u97f3","text":""},{"location":"qsl4a/special/pgptai/#texttospeech","title":"textToSpeech()","text":"

      \u5c06\u6587\u672c\u8f6c\u6362\u4e3a\u8bed\u97f3\u5e76\u53ef\u9009\u5730\u64ad\u653e\u3002

      textToSpeech(Text, AutoPlay=True, WavFile=None, VoiceName=None)\n

      \u53c2\u6570\uff1a - Text (str): \u8981\u8f6c\u6362\u4e3a\u8bed\u97f3\u7684\u6587\u672c - AutoPlay (bool): \u81ea\u52a8\u64ad\u653e\u751f\u6210\u7684\u97f3\u9891\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - WavFile (str, optional): \u4fdd\u5b58 WAV \u6587\u4ef6\u7684\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u4e34\u65f6\u6587\u4ef6 - VoiceName (str, optional): \u8981\u4f7f\u7528\u7684\u8bed\u97f3\u540d\u79f0\uff08\u4f8b\u5982 'en-US-JennyNeural'\u3001'zh-CN-XiaoxiaoNeural'\uff09

      \u8fd4\u56de\uff1a \u5305\u542b\u8bed\u97f3\u5408\u6210\u7ed3\u679c\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - text: \u8f93\u5165\u6587\u672c - url: \u4e0b\u8f7d\u97f3\u9891\u6587\u4ef6\u7684 URL - WavFile: \u4fdd\u5b58\u7684 WAV \u6587\u4ef6\u8def\u5f84\uff08\u5982\u679c\u672c\u5730\u4fdd\u5b58\uff09

      "},{"location":"qsl4a/special/pgptai/#_4","title":"\u914d\u7f6e","text":"

      API \u4f7f\u7528\u4ee5\u4e0b\u914d\u7f6e\u6587\u4ef6\u4e2d\u7684\u914d\u7f6e\uff1a/storage/emulated/0/Android/data/org.qpython.qpy/files/apigpt.conf\uff1a

      [speech]\nspeech_key = your_api_key\n

      \u9ed8\u8ba4\u8bed\u97f3\u8bbe\u7f6e\uff1a - \u82f1\u8bed\uff1aen-US-JennyNeural - \u4e2d\u6587\uff1azh-CN-XiaoxiaoNeural

      "},{"location":"qsl4a/special/pgptai/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5f55\u5236\u5e76\u8f6c\u5f55\nprint(\"Recording for 5 seconds...\")\ntext = droid.speechToText(RecordSecond=5, Language='en').result\nprint(f\"You said: {text}\")\n\n# \u8f6c\u5f55\u73b0\u6709\u6587\u4ef6\ntext = droid.speechToText(AmrFile=\"/sdcard/recording.amr\").result\nprint(f\"Transcription: {text}\")\n\n# \u6587\u672c\u8f6c\u8bed\u97f3\ndroid.textToSpeech(\"Hello, this is a test message.\", AutoPlay=True, Language='en')\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u8bed\u97f3\u5e76\u4fdd\u5b58\u5230\u6587\u4ef6\u7684\u6587\u672c\u8f6c\u8bed\u97f3\nresult = droid.textToSpeech(\n    \"Welcome to QPython!\",\n    AutoPlay=False,\n    WavFile=\"/sdcard/welcome.wav\",\n    VoiceName=\"en-US-JennyNeural\"\n).result\nprint(f\"Audio saved to: {result.get('WavFile')}\")\n
      "},{"location":"qsl4a/special/pgptai/#_6","title":"\u7c7b\u4f7f\u7528","text":"
      from androidhelper.pgptai import pgptai\nimport androidhelper\n\ndroid = androidhelper.Android()\nai = pgptai(droid)\n\n# \u4f7f\u7528\u8bed\u97f3\u8bc6\u522b\ntext = ai.speechToText(RecordSecond=10)\n
      "},{"location":"qsl4a/storage/clipboard/","title":"\u526a\u8d34\u677f API","text":"

      \u590d\u5236\u548c\u7c98\u8d34\u6587\u672c\u5230\u7cfb\u7edf\u526a\u8d34\u677f\u3002

      "},{"location":"qsl4a/storage/clipboard/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/clipboard/#setclipboard","title":"setClipboard()","text":"

      \u590d\u5236\u6587\u672c\u5230\u526a\u8d34\u677f\u3002

      setClipboard(text)\n

      \u53c2\u6570\uff1a - text (str): \u8981\u590d\u5236\u7684\u6587\u672c

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/clipboard/#getclipboard","title":"getClipboard()","text":"

      \u4ece\u526a\u8d34\u677f\u83b7\u53d6\u6587\u672c\u3002

      getClipboard()\n

      \u8fd4\u56de\uff1a \u526a\u8d34\u677f\u6587\u672c

      "},{"location":"qsl4a/storage/clipboard/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u590d\u5236\u5230\u526a\u8d34\u677f\ndroid.setClipboard(\"Hello from QPython!\")\n\n# \u4ece\u526a\u8d34\u677f\u7c98\u8d34\ntext = droid.getClipboard().result\nprint(f\"Clipboard: {text}\")\n
      "},{"location":"qsl4a/storage/documentfile/","title":"DocumentFile API","text":"

      \u4f7f\u7528 SAF\uff08\u5b58\u50a8\u8bbf\u95ee\u6846\u67b6\uff09\u8fdb\u884c\u6587\u4ef6\u64cd\u4f5c\uff0c\u652f\u6301 Android 4.4+\u3002

      "},{"location":"qsl4a/storage/documentfile/#_1","title":"\u76ee\u5f55\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilemkdir","title":"documentFileMkdir()","text":"

      \u521b\u5efa\u76ee\u5f55\u3002

      documentFileMkdir(Dir)\n

      \u53c2\u6570\uff1a - Dir (str): \u76ee\u5f55\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/documentfile/#documentfilelistfiles","title":"documentFileListFiles()","text":"

      \u5217\u51fa\u76ee\u5f55\u4e2d\u7684\u6587\u4ef6\u3002

      documentFileListFiles(Folder)\n

      \u8fd4\u56de\uff1a \u6587\u4ef6\u5217\u8868

      "},{"location":"qsl4a/storage/documentfile/#_2","title":"\u6587\u4ef6\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileexists","title":"documentFileExists()","text":"

      \u68c0\u67e5\u6587\u4ef6\u6216\u76ee\u5f55\u662f\u5426\u5b58\u5728\u3002

      documentFileExists(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u6216\u76ee\u5f55\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u5b58\u5728\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/storage/documentfile/#documentfileisfile","title":"documentFileIsFile()","text":"

      \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u6587\u4ef6\u3002

      documentFileIsFile(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u662f\u6587\u4ef6\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u6587\u4ef6\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

      "},{"location":"qsl4a/storage/documentfile/#documentfileisdirectory","title":"documentFileIsDirectory()","text":"

      \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u76ee\u5f55\u3002

      documentFileIsDirectory(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u662f\u76ee\u5f55\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u76ee\u5f55\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

      "},{"location":"qsl4a/storage/documentfile/#documentfiledelete","title":"documentFileDelete()","text":"

      \u5220\u9664\u6587\u4ef6\u6216\u76ee\u5f55\u3002

      documentFileDelete(FileOrTree)\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/documentfile/#documentfilerenameto","title":"documentFileRenameTo()","text":"

      \u91cd\u547d\u540d\u6216\u79fb\u52a8\u6587\u4ef6\u3002

      documentFileRenameTo(Src, Dest)\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/documentfile/#documentfilecopy","title":"documentFileCopy()","text":"

      \u590d\u5236\u6587\u4ef6\u3002

      documentFileCopy(SrcFileOrTree, DestFileOrTree)\n
      "},{"location":"qsl4a/storage/documentfile/#_3","title":"\u6d41\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileinputstream","title":"documentFileInputStream()","text":"

      \u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9\u3002

      documentFileInputStream(srcFile, EncodingFormat=\"\", skip=None, length=None)\n

      \u53c2\u6570\uff1a - srcFile (str): \u6e90\u6587\u4ef6 - EncodingFormat (str): \"UTF-8\"\u3001\"GBK\"\u3001\"Base64\" \u6216\u7a7a\u5b57\u7b26\u4e32\u8868\u793a\u5b57\u8282 - skip (int): \u4ece\u5f00\u5934\u8df3\u8fc7\u7684\u5b57\u8282\u6570 - length (int): \u8bfb\u53d6\u957f\u5ea6

      \u8fd4\u56de\uff1a \u6587\u4ef6\u5185\u5bb9

      "},{"location":"qsl4a/storage/documentfile/#documentfileoutputstream","title":"documentFileOutputStream()","text":"

      \u5199\u5165\u6587\u4ef6\u5185\u5bb9\u3002

      documentFileOutputStream(destFile, src, EncodingFormat=\"\", append=None)\n

      \u53c2\u6570\uff1a - destFile (str): \u76ee\u6807\u6587\u4ef6 - src: \u8981\u5199\u5165\u7684\u6570\u636e - EncodingFormat (str): \u7f16\u7801\u683c\u5f0f - append (bool): \u8ffd\u52a0\u6a21\u5f0f

      "},{"location":"qsl4a/storage/documentfile/#_4","title":"\u6587\u4ef6\u4fe1\u606f","text":""},{"location":"qsl4a/storage/documentfile/#documentfilelength","title":"documentFileLength()","text":"

      \u83b7\u53d6\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\u3002

      documentFileLength(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

      "},{"location":"qsl4a/storage/documentfile/#documentfilelastmodified","title":"documentFileLastModified()","text":"

      \u83b7\u53d6\u6700\u540e\u4fee\u6539\u65f6\u95f4\u3002

      documentFileLastModified(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u65f6\u95f4\u6233\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

      "},{"location":"qsl4a/storage/documentfile/#documentfilegetstat","title":"documentFileGetStat()","text":"

      \u83b7\u53d6\u5168\u9762\u7684\u6587\u4ef6\u7edf\u8ba1\u4fe1\u606f\u3002

      documentFileGetStat(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5305\u542b\u957f\u5ea6\u3001\u6700\u540e\u4fee\u6539\u65f6\u95f4\u548c\u8bfb/\u5199\u6743\u9650\u7684\u5b57\u5178\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

      "},{"location":"qsl4a/storage/documentfile/#uri","title":"URI \u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilegeturi","title":"documentFileGetUri()","text":"

      \u4ece\u8def\u5f84\u83b7\u53d6 URI\u3002

      documentFileGetUri(path, isDirectory=None)\n
      "},{"location":"qsl4a/storage/documentfile/#documentfileshowopen","title":"documentFileShowOpen()","text":"

      \u663e\u793a\u6587\u4ef6\u9009\u62e9\u5668\u3002

      documentFileShowOpen()\n

      \u8fd4\u56de\uff1a \u9009\u62e9\u7684\u6587\u4ef6 URI

      "},{"location":"qsl4a/storage/documentfile/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u76ee\u5f55\ndroid.documentFileMkdir(\"/sdcard/MyFolder\")\n\n# \u5217\u51fa\u6587\u4ef6\nfiles = droid.documentFileListFiles(\"/sdcard\").result\nfor f in files:\n    print(f)\n\n# \u8bfb\u53d6\u6587\u4ef6\ncontent = droid.documentFileInputStream(\n    \"/sdcard/test.txt\",\n    EncodingFormat=\"UTF-8\"\n).result\nprint(content)\n\n# \u5199\u5165\u6587\u4ef6\ndroid.documentFileOutputStream(\n    \"/sdcard/output.txt\",\n    \"Hello World\",\n    EncodingFormat=\"UTF-8\"\n)\n
      "},{"location":"qsl4a/storage/preferences/","title":"\u504f\u597d\u8bbe\u7f6e API","text":"

      \u4f7f\u7528 Android SharedPreferences \u5b58\u50a8\u548c\u68c0\u7d22\u6570\u636e\u3002

      "},{"location":"qsl4a/storage/preferences/#_1","title":"\u504f\u597d\u8bbe\u7f6e\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/preferences/#prefgetvalue","title":"prefGetValue()","text":"

      \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u8bfb\u53d6\u503c\u3002

      prefGetValue(key, filename=None)\n

      \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c\uff08\u4efb\u610f\u7c7b\u578b\uff09

      "},{"location":"qsl4a/storage/preferences/#prefputvalue","title":"prefPutValue()","text":"

      \u5199\u5165\u503c\u5230\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u3002

      prefPutValue(key, value, filename=None)\n

      \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - value (object): \u8981\u5b58\u50a8\u7684\u503c - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      "},{"location":"qsl4a/storage/preferences/#prefgetall","title":"prefGetAll()","text":"

      \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\u503c\u3002

      prefGetAll(filename=None)\n

      \u53c2\u6570\uff1a - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      \u8fd4\u56de\uff1a \u6240\u6709\u504f\u597d\u7684\u6620\u5c04

      "},{"location":"qsl4a/storage/preferences/#prefremovevalue","title":"prefRemoveValue()","text":"

      \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u4e2d\u79fb\u9664\u503c\u3002

      prefRemoveValue(key, filename=None)\n

      \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      "},{"location":"qsl4a/storage/preferences/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b58\u50a8\u503c\ndroid.prefPutValue(\"username\", \"alice\")\ndroid.prefPutValue(\"score\", 100)\ndroid.prefPutValue(\"enabled\", True)\n\n# \u8bfb\u53d6\u7279\u5b9a\u503c\nusername = droid.prefGetValue(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\nall_prefs = droid.prefGetAll().result\nprint(f\"All prefs: {all_prefs}\")\n\n# \u79fb\u9664\u503c\ndroid.prefRemoveValue(\"score\")\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u6587\u4ef6\u540d\ndroid.prefPutValue(\"token\", \"abc123\", filename=\"auth.prefs\")\ntoken = droid.prefGetValue(\"token\", filename=\"auth.prefs\").result\n
      "},{"location":"qsl4a/system/activityresult/","title":"Activity Result API","text":"

      \u4e3a\u901a\u8fc7 startActivityForResult \u542f\u52a8\u7684\u811a\u672c\u8bbe\u7f6e activity \u7ed3\u679c\u3002

      "},{"location":"qsl4a/system/activityresult/#_1","title":"\u7ed3\u679c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/activityresult/#setresultboolean","title":"setResultBoolean()","text":"

      \u8bbe\u7f6e\u5e03\u5c14\u7ed3\u679c\u3002

      setResultBoolean(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (bool): \u5e03\u5c14\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultbyte","title":"setResultByte()","text":"

      \u8bbe\u7f6e\u5b57\u8282\u7ed3\u679c\u3002

      setResultByte(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u5b57\u8282\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultshort","title":"setResultShort()","text":"

      \u8bbe\u7f6e\u77ed\u6574\u6570\u7ed3\u679c\u3002

      setResultShort(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u77ed\u6574\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultchar","title":"setResultChar()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u7ed3\u679c\u3002

      setResultChar(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultinteger","title":"setResultInteger()","text":"

      \u8bbe\u7f6e\u6574\u6570\u7ed3\u679c\u3002

      setResultInteger(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u6574\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultlong","title":"setResultLong()","text":"

      \u8bbe\u7f6e\u957f\u6574\u6570\u7ed3\u679c\u3002

      setResultLong(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u957f\u6574\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultfloat","title":"setResultFloat()","text":"

      \u8bbe\u7f6e\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

      setResultFloat(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u6d6e\u70b9\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultdouble","title":"setResultDouble()","text":"

      \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

      setResultDouble(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultstring","title":"setResultString()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u4e32\u7ed3\u679c\u3002

      setResultString(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u4e32\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultbooleanarray","title":"setResultBooleanArray()","text":"

      \u8bbe\u7f6e\u5e03\u5c14\u6570\u7ec4\u7ed3\u679c\u3002

      setResultBooleanArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5e03\u5c14\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultbytearray","title":"setResultByteArray()","text":"

      \u8bbe\u7f6e\u5b57\u8282\u6570\u7ec4\u7ed3\u679c\u3002

      setResultByteArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u8282\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultshortarray","title":"setResultShortArray()","text":"

      \u8bbe\u7f6e\u77ed\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultShortArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u77ed\u6574\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultchararray","title":"setResultCharArray()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u6570\u7ec4\u7ed3\u679c\u3002

      setResultCharArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultintegerarray","title":"setResultIntegerArray()","text":"

      \u8bbe\u7f6e\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultIntegerArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6574\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultlongarray","title":"setResultLongArray()","text":"

      \u8bbe\u7f6e\u957f\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultLongArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u957f\u6574\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultfloatarray","title":"setResultFloatArray()","text":"

      \u8bbe\u7f6e\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultFloatArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6d6e\u70b9\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultdoublearray","title":"setResultDoubleArray()","text":"

      \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultDoubleArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultstringarray","title":"setResultStringArray()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u4e32\u6570\u7ec4\u7ed3\u679c\u3002

      setResultStringArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u4e32\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultserializable","title":"setResultSerializable()","text":"

      \u8bbe\u7f6e\u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u3002

      setResultSerializable(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue: \u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c activity \u540e\uff0c\u8bbe\u7f6e\u7ed3\u679c\n# \u793a\u4f8b\uff1a\u8fd4\u56de\u6210\u529f\u53ca\u6570\u636e\ndroid.setResultInteger(0, 200)  # RESULT_OK\ndroid.setResultString(0, \"Operation completed successfully\")\n\n# \u8fd4\u56de\u6570\u7ec4\u7ed3\u679c\ndroid.setResultIntegerArray(0, [1, 2, 3, 4, 5])\n
      "},{"location":"qsl4a/system/application/","title":"\u5e94\u7528\u7ba1\u7406","text":"

      \u7ba1\u7406\u5e94\u7528\u7a0b\u5e8f\u3001\u542f\u52a8\u5e94\u7528\u548c\u67e5\u8be2\u7cfb\u7edf\u4fe1\u606f\u3002

      "},{"location":"qsl4a/system/application/#_2","title":"\u5e94\u7528\u7a0b\u5e8f\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getapplicationinfo","title":"getApplicationInfo()","text":"

      \u83b7\u53d6\u5e94\u7528\u4fe1\u606f\u3002

      getApplicationInfo(packageName=None)\n

      \u53c2\u6570\uff1a - packageName (str): \u5305\u540d\uff08None = \u5f53\u524d\u5e94\u7528\uff09

      \u8fd4\u56de\uff1a \u5e94\u7528\u4fe1\u606f\u5b57\u5178

      "},{"location":"qsl4a/system/application/#getinstalledpackages","title":"getInstalledPackages()","text":"

      \u83b7\u53d6\u5df2\u5b89\u88c5\u5305\u5217\u8868\u3002

      getInstalledPackages(flag=4)\n

      \u53c2\u6570\uff1a - flag (int): \u5305\u6807\u5fd7\u8fc7\u6ee4\u5668\uff08\u9ed8\u8ba4\uff1a4\uff09

      \u8fd4\u56de\uff1a \u5df2\u5b89\u88c5\u5305\u5217\u8868

      "},{"location":"qsl4a/system/application/#getrunningpackages","title":"getRunningPackages()","text":"

      \u5217\u51fa\u6b63\u5728\u8fd0\u884c\u7684\u5305\u3002

      getRunningPackages()\n

      \u8fd4\u56de\uff1a \u5305\u540d\u5217\u8868

      "},{"location":"qsl4a/system/application/#getlaunchablepackages","title":"getLaunchablePackages()","text":"

      \u83b7\u53d6\u53ef\u542f\u52a8\u5305\u5217\u8868\u3002

      getLaunchablePackages(needClassName=False)\n

      \u53c2\u6570\uff1a - needClassName (bool): \u5305\u542b\u4e3b activity \u7c7b\u540d\uff08\u9ed8\u8ba4\uff1aFalse\uff09

      \u8fd4\u56de\uff1a \u53ef\u542f\u52a8\u5305\u540d\u5217\u8868\u6216\u5305\u542b\u7c7b\u540d\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#_3","title":"\u5e94\u7528\u63a7\u5236","text":""},{"location":"qsl4a/system/application/#launch","title":"launch()","text":"

      \u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u3002

      launch(classname=None, packagename=None, wait=True)\n

      \u53c2\u6570\uff1a - classname (str): \u4e3b activity \u7c7b\u540d - packagename (str): \u5305\u540d - wait (bool): \u7b49\u5f85\u542f\u52a8\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

      \u8fd4\u56de\uff1a \u542f\u52a8\u7ed3\u679c

      "},{"location":"qsl4a/system/application/#forcestoppackage","title":"forceStopPackage()","text":"

      \u5f3a\u5236\u505c\u6b62\u5e94\u7528\u7a0b\u5e8f\u3002

      forceStopPackage(packageName)\n

      \u53c2\u6570\uff1a - packageName (str): \u8981\u505c\u6b62\u7684\u5305\u540d

      "},{"location":"qsl4a/system/application/#_4","title":"\u7248\u672c\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getpackageversion","title":"getPackageVersion()","text":"

      \u83b7\u53d6\u5e94\u7528\u7248\u672c\u540d\u79f0\u3002

      getPackageVersion(packageName)\n

      \u8fd4\u56de\uff1a \u7248\u672c\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"3.2.1\"\uff09

      "},{"location":"qsl4a/system/application/#getpackageversioncode","title":"getPackageVersionCode()","text":"

      \u83b7\u53d6\u5e94\u7528\u7248\u672c\u4ee3\u7801\u3002

      getPackageVersionCode(packageName)\n

      \u8fd4\u56de\uff1a \u7248\u672c\u4ee3\u7801\u6574\u6570

      "},{"location":"qsl4a/system/application/#getconstants","title":"getConstants()","text":"

      \u83b7\u53d6\u7c7b\u5e38\u91cf\u3002

      getConstants(classname)\n

      \u53c2\u6570\uff1a - classname (str): \u5b8c\u6574\u7c7b\u540d

      \u8fd4\u56de\uff1a \u5e38\u91cf\u540d\u548c\u503c\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#_5","title":"\u7cfb\u7edf\u529f\u80fd","text":""},{"location":"qsl4a/system/application/#backgroundprotect","title":"backgroundProtect()","text":"

      \u542f\u7528\u6216\u7981\u7528\u5e94\u7528\u7684\u540e\u53f0\u4fdd\u62a4\u3002

      backgroundProtect(enabled=True)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\u4fdd\u62a4\uff0cFalse \u7981\u7528

      "},{"location":"qsl4a/system/application/#createscriptshortcut","title":"createScriptShortCut()","text":"

      \u4e3a\u811a\u672c\u521b\u5efa\u4e3b\u5c4f\u5e55\u5feb\u6377\u65b9\u5f0f\u3002

      createScriptShortCut(scriptPath, label=None, iconPath=None, scriptArg=None)\n

      \u53c2\u6570\uff1a - scriptPath (str): Python \u811a\u672c\u8def\u5f84 - label (str, optional): \u5feb\u6377\u65b9\u5f0f\u6807\u7b7e - iconPath (str, optional): \u56fe\u6807\u56fe\u50cf\u8def\u5f84 - scriptArg (str, optional): \u4f20\u9012\u7ed9\u811a\u672c\u7684\u53c2\u6570

      "},{"location":"qsl4a/system/application/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getandroidid","title":"getAndroidID()","text":"

      \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

      getAndroidID()\n

      \u8fd4\u56de\uff1a \u552f\u4e00\u7684 Android \u8bbe\u5907 ID \u5b57\u7b26\u4e32

      "},{"location":"qsl4a/system/application/#getsysinfo","title":"getSysInfo()","text":"

      \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\u3002

      getSysInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#getlocale","title":"getLocale()","text":"

      \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u3002

      getLocale()\n

      \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

      "},{"location":"qsl4a/system/application/#getharmonyosinformation","title":"getHarmonyOsInformation()","text":"

      \u5982\u679c\u5728 HarmonyOS \u4e0a\u8fd0\u884c\uff0c\u83b7\u53d6 HarmonyOS \u4fe1\u606f\u3002

      getHarmonyOsInformation()\n

      \u8fd4\u56de\uff1a HarmonyOS \u7248\u672c\u4fe1\u606f\u6216 None

      "},{"location":"qsl4a/system/application/#isexternalstoragemanager","title":"isExternalStorageManager()","text":"

      \u68c0\u67e5\u5e94\u7528\u662f\u5426\u6709\u5916\u90e8\u5b58\u50a8\u7ba1\u7406\u5668\u6743\u9650\u3002

      isExternalStorageManager()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6709\u6743\u9650\u5219\u4e3a True

      "},{"location":"qsl4a/system/application/#_7","title":"\u5185\u5b58\u548c\u663e\u793a","text":""},{"location":"qsl4a/system/application/#getmemoryinfo","title":"getMemoryInfo()","text":"

      \u83b7\u53d6\u5185\u5b58\u4fe1\u606f\u3002

      getMemoryInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#getscreeninfo","title":"getScreenInfo()","text":"

      \u83b7\u53d6\u5c4f\u5e55\u4fe1\u606f\u3002

      getScreenInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#_8","title":"\u6743\u9650","text":""},{"location":"qsl4a/system/application/#checkpermissions","title":"checkPermissions()","text":"

      \u68c0\u67e5\u5f53\u524d\u5e94\u7528\u6743\u9650\u3002

      checkPermissions()\n

      \u8fd4\u56de\uff1a \u6743\u9650\u53ca\u5176\u72b6\u6001\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#requestpermissions","title":"requestPermissions()","text":"

      \u5411\u7528\u6237\u8bf7\u6c42\u6743\u9650\u3002

      requestPermissions(permissions=None)\n

      \u53c2\u6570\uff1a - permissions (list, optional): \u8981\u8bf7\u6c42\u7684\u6743\u9650\u5217\u8868\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8bf7\u6c42\u6240\u6709\u9700\u8981\u7684\u6743\u9650\u3002

      \u8fd4\u56de\uff1a \u6743\u9650\u8bf7\u6c42\u7ed3\u679c

      "},{"location":"qsl4a/system/application/#_9","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/system/application/#showscreenlock","title":"showScreenLock()","text":"

      \u663e\u793a\u5c4f\u5e55\u9501\u5b9a\uff08PIN/\u56fe\u6848/\u5bc6\u7801\u8f93\u5165\uff09\u3002

      showScreenLock()\n
      "},{"location":"qsl4a/system/application/#_10","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\ninfo = droid.getSysInfo().result\nprint(f\"System: {info}\")\n\n# \u83b7\u53d6\u5e94\u7528\u7248\u672c\nversion = droid.getPackageVersion(\"org.qpython.qpy\").result\nprint(f\"QPython version: {version}\")\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u5e94\u7528\napps = droid.getInstalledPackages().result\nprint(f\"Installed apps: {len(apps)}\")\n\n# \u542f\u52a8\u5e94\u7528\ndroid.launch(packagename=\"com.android.settings\")\n\n# \u68c0\u67e5\u6743\u9650\nperms = droid.checkPermissions().result\nprint(f\"Permissions: {perms}\")\n\n# \u8bf7\u6c42\u5b58\u50a8\u6743\u9650\ndroid.requestPermissions([\"android.permission.READ_EXTERNAL_STORAGE\"])\n\n# \u521b\u5efa\u5feb\u6377\u65b9\u5f0f\ndroid.createScriptShortCut(\n    \"/sdcard/my_script.py\",\n    label=\"My Script\",\n    iconPath=\"/sdcard/icon.png\"\n)\n
      "},{"location":"qsl4a/system/battery/","title":"\u7535\u6c60 API","text":"

      \u76d1\u63a7\u8bbe\u5907\u7535\u6c60\u72b6\u6001\u548c\u5065\u5eb7\u72b6\u51b5\u3002

      "},{"location":"qsl4a/system/battery/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/battery/#readbatterydata","title":"readBatteryData()","text":"

      \u83b7\u53d6\u5b8c\u6574\u7684\u7535\u6c60\u4fe1\u606f\u3002

      readBatteryData()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7535\u6c60\u6570\u636e\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/battery/#batterystartmonitoring","title":"batteryStartMonitoring()","text":"

      \u5f00\u59cb\u7535\u6c60\u76d1\u63a7\u3002

      batteryStartMonitoring()\n
      "},{"location":"qsl4a/system/battery/#batterystopmonitoring","title":"batteryStopMonitoring()","text":"

      \u505c\u6b62\u7535\u6c60\u76d1\u63a7\u3002

      batteryStopMonitoring()\n
      "},{"location":"qsl4a/system/battery/#batterygetlevel","title":"batteryGetLevel()","text":"

      \u83b7\u53d6\u7535\u6c60\u767e\u5206\u6bd4\u3002

      batteryGetLevel()\n

      \u8fd4\u56de\uff1a \u6574\u6570\uff080-100\uff09

      "},{"location":"qsl4a/system/battery/#batterygetstatus","title":"batteryGetStatus()","text":"

      \u83b7\u53d6\u5145\u7535\u72b6\u6001\u3002

      batteryGetStatus()\n

      \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u5145\u7535\u4e2d - 3: \u653e\u7535\u4e2d - 4: \u672a\u5145\u7535 - 5: \u5df2\u5145\u6ee1

      "},{"location":"qsl4a/system/battery/#batterygetplugtype","title":"batteryGetPlugType()","text":"

      \u83b7\u53d6\u7535\u6e90\u7c7b\u578b\u3002

      batteryGetPlugType()\n

      \u8fd4\u56de\uff1a - -1: \u672a\u77e5 - 0: \u672a\u63d2\u7535 - 1: AC \u5145\u7535\u5668 - 2: USB \u7aef\u53e3

      "},{"location":"qsl4a/system/battery/#batterygethealth","title":"batteryGetHealth()","text":"

      \u83b7\u53d6\u7535\u6c60\u5065\u5eb7\u72b6\u51b5\u3002

      batteryGetHealth()\n

      \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u826f\u597d - 3: \u8fc7\u70ed - 4: \u635f\u574f - 5: \u8fc7\u538b - 6: \u672a\u6307\u5b9a\u7684\u6545\u969c

      "},{"location":"qsl4a/system/battery/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\nlevel = droid.batteryGetLevel().result\nprint(f\"Battery: {level}%\")\n
      "},{"location":"qsl4a/system/qpyinterface/","title":"QPython \u63a5\u53e3 API","text":"

      \u4ece\u5176\u4ed6\u5e94\u7528\u6267\u884c QPython \u811a\u672c\u548c\u7ba1\u7406\u5171\u4eab\u53d8\u91cf\u3002

      "},{"location":"qsl4a/system/qpyinterface/#_1","title":"\u811a\u672c\u6267\u884c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/qpyinterface/#executeqpy","title":"executeQPy()","text":"

      \u6267\u884c QPython \u811a\u672c\u3002

      executeQPy(path=\"\", arg=None)\n

      \u53c2\u6570\uff1a - path (str): \u811a\u672c\u6587\u4ef6\u8def\u5f84 - arg (str, optional): \u547d\u4ee4\u884c\u53c2\u6570

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#executeqpyassrv","title":"executeQPyAsSrv()","text":"

      \u4f5c\u4e3a\u670d\u52a1\u6267\u884c QPython \u811a\u672c\u3002

      executeQPyAsSrv(path=None)\n

      \u53c2\u6570\uff1a - path (str, optional): \u811a\u672c\u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#executeqpycode","title":"executeQPyCode()","text":"

      \u76f4\u63a5\u6267\u884c Python \u4ee3\u7801\u3002

      executeQPyCode(code=None)\n

      \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#executeqpycodeassrv","title":"executeQPyCodeAsSrv()","text":"

      \u4f5c\u4e3a\u670d\u52a1\u6267\u884c Python \u4ee3\u7801\u3002

      executeQPyCodeAsSrv(code=None)\n

      \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#_2","title":"\u5171\u4eab\u53d8\u91cf","text":"

      \u5171\u4eab\u53d8\u91cf\u5141\u8bb8 QPython \u4e0e\u5176\u4ed6\u5e94\u7528\u4e4b\u95f4\u8fdb\u884c\u901a\u4fe1\u3002

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableset","title":"sharedVariableSet()","text":"

      \u8bbe\u7f6e Java \u5171\u4eab\u53d8\u91cf\u3002

      sharedVariableSet(key, value)\n

      \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d - value (str): \u53d8\u91cf\u503c

      \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableget","title":"sharedVariableGet()","text":"

      \u83b7\u53d6 Java \u5171\u4eab\u53d8\u91cf\u3002

      sharedVariableGet(key)\n

      \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d

      \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableremove","title":"sharedVariableRemove()","text":"

      \u79fb\u9664 Java \u5171\u4eab\u53d8\u91cf\u3002

      sharedVariableRemove(key)\n

      \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u53d8\u91cf\u540d

      \u8fd4\u56de\uff1a \u88ab\u79fb\u9664\u7684\u503c

      "},{"location":"qsl4a/system/qpyinterface/#getlastlog","title":"getLastLog()","text":"

      \u83b7\u53d6 QPython \u7684\u6700\u540e\u65e5\u5fd7\u8f93\u51fa\u3002

      getLastLog()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u65e5\u5fd7\u5185\u5bb9

      "},{"location":"qsl4a/system/qpyinterface/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c\u811a\u672c\ndroid.executeQPy(\"/sdcard/my_script.py\", arg=\"test\")\n\n# \u76f4\u63a5\u6267\u884c\u4ee3\u7801\ncode = \"print('Hello from QPython!')\"\ndroid.executeQPyCode(code)\n\n# \u4f7f\u7528\u5171\u4eab\u53d8\u91cf\ndroid.sharedVariableSet(\"username\", \"alice\")\nusername = droid.sharedVariableGet(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u79fb\u9664\u53d8\u91cf\ndroid.sharedVariableRemove(\"username\")\n\n# \u83b7\u53d6\u6700\u8fd1\u65e5\u5fd7\nlog = droid.getLastLog().result\nprint(f\"Log: {log}\")\n
      "},{"location":"qsl4a/system/sensors/","title":"\u4f20\u611f\u5668 API","text":"

      \u8bbf\u95ee\u8bbe\u5907\u4f20\u611f\u5668\uff0c\u5305\u62ec\u52a0\u901f\u5ea6\u8ba1\u3001\u9640\u87ba\u4eea\u3001\u78c1\u529b\u8ba1\u7b49\u3002

      "},{"location":"qsl4a/system/sensors/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/sensors/#startsensingtimed","title":"startSensingTimed()","text":"

      \u5f00\u59cb\u4f20\u611f\u5668\u76d1\u63a7\u5e76\u8bbe\u7f6e\u65f6\u95f4\u95f4\u9694\u3002

      startSensingTimed(sensorNumber, delayTime)\n

      \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID\uff08\u901a\u5e38\u4e3a 1-3\uff09 - delayTime (int): \u8bfb\u53d6\u4e4b\u95f4\u7684\u5ef6\u8fdf\uff08\u6beb\u79d2\uff09

      "},{"location":"qsl4a/system/sensors/#startsensingthreshold","title":"startSensingThreshold()","text":"

      \u5f00\u59cb\u5e26\u9608\u503c\u89e6\u53d1\u7684\u4f20\u611f\u5668\u76d1\u63a7\u3002

      startSensingThreshold(sensorNumber, threshold, axis)\n

      \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID - threshold (float): \u89e6\u53d1\u9608\u503c - axis (int): \u8981\u76d1\u63a7\u7684\u8f74\uff080=X\uff0c1=Y\uff0c2=Z\uff09

      "},{"location":"qsl4a/system/sensors/#stopsensing","title":"stopSensing()","text":"

      \u505c\u6b62\u6240\u6709\u4f20\u611f\u5668\u76d1\u63a7\u3002

      stopSensing()\n
      "},{"location":"qsl4a/system/sensors/#readsensors","title":"readSensors()","text":"

      \u8bfb\u53d6\u5f53\u524d\u4f20\u611f\u5668\u6570\u636e\u3002

      readSensors()\n

      \u8fd4\u56de\uff1a \u4f20\u611f\u5668\u6570\u636e\u5b57\u5178

      "},{"location":"qsl4a/system/sensors/#sensorsreadaccelerometer","title":"sensorsReadAccelerometer()","text":"

      \u8bfb\u53d6\u52a0\u901f\u5ea6\u8ba1\u503c\u3002

      sensorsReadAccelerometer()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d m/s\u00b2

      "},{"location":"qsl4a/system/sensors/#sensorsreadgyroscope","title":"sensorsReadGyroscope()","text":"

      \u8bfb\u53d6\u9640\u87ba\u4eea\u503c\u3002

      sensorsReadGyroscope()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d rad/s

      "},{"location":"qsl4a/system/sensors/#sensorsreadmagnetometer","title":"sensorsReadMagnetometer()","text":"

      \u8bfb\u53d6\u78c1\u573a\u503c\u3002

      sensorsReadMagnetometer()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d \u03bcT

      "},{"location":"qsl4a/system/sensors/#sensorsreadorientation","title":"sensorsReadOrientation()","text":"

      \u8bfb\u53d6\u8bbe\u5907\u65b9\u5411\u3002

      sensorsReadOrientation()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [azimuth, pitch, roll]\uff0c\u5355\u4f4d\u5ea6

      "},{"location":"qsl4a/system/sensors/#sensorsgetlight","title":"sensorsGetLight()","text":"

      \u8bfb\u53d6\u5149\u4f20\u611f\u5668\u503c\u3002

      sensorsGetLight()\n

      \u8fd4\u56de\uff1a \u5149\u7ea7\u522b\uff08lux\uff09

      "},{"location":"qsl4a/system/sensors/#sensorsgetstepcounter","title":"sensorsGetStepCounter()","text":"

      \u8bfb\u53d6\u6b65\u8ba1\u6570\u5668\u3002

      sensorsGetStepCounter()\n

      \u8fd4\u56de\uff1a \u6b65\u6570

      "},{"location":"qsl4a/system/sensors/#sensorsgetaccuracy","title":"sensorsGetAccuracy()","text":"

      \u83b7\u53d6\u5f53\u524d\u4f20\u611f\u5668\u7cbe\u5ea6\u3002

      sensorsGetAccuracy()\n

      \u8fd4\u56de\uff1a \u7cbe\u5ea6\u503c\uff080-3\uff1aUNRELIABLE\u3001ACCURACY_LOW\u3001ACCURACY_MEDIUM\u3001ACCURACY_HIGH\uff09

      "},{"location":"qsl4a/system/sensors/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u8bfb\u53d6\u4f20\u611f\u5668 10 \u6b21\nfor i in range(10):\n    accel = droid.sensorsReadAccelerometer().result\n    print(f\"Accel: X={accel[0]:.2f}, Y={accel[1]:.2f}, Z={accel[2]:.2f}\")\n    time.sleep(0.5)\n\ndroid.stopSensing()\n
      "},{"location":"qsl4a/system/settings/","title":"\u8bbe\u7f6e API","text":"

      \u63a7\u5236\u7cfb\u7edf\u8bbe\u7f6e\uff0c\u5305\u62ec\u5c4f\u5e55\u3001\u58f0\u97f3\u548c\u7f51\u7edc\u8bbe\u7f6e\u3002

      "},{"location":"qsl4a/system/settings/#_1","title":"\u5c4f\u5e55\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#setscreentimeout","title":"setScreenTimeout()","text":"

      \u8bbe\u7f6e\u5c4f\u5e55\u8d85\u65f6\u503c\u3002

      setScreenTimeout(value)\n

      \u53c2\u6570\uff1a - value (int): \u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

      \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u8d85\u65f6\u503c

      "},{"location":"qsl4a/system/settings/#getscreentimeout","title":"getScreenTimeout()","text":"

      \u83b7\u53d6\u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u3002

      getScreenTimeout()\n

      \u8fd4\u56de\uff1a \u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

      "},{"location":"qsl4a/system/settings/#getscreenbrightness","title":"getScreenBrightness()","text":"

      \u83b7\u53d6\u5c4f\u5e55\u4eae\u5ea6\u503c\u3002

      getScreenBrightness()\n

      \u8fd4\u56de\uff1a \u4eae\u5ea6\u503c\uff080-255\uff09

      "},{"location":"qsl4a/system/settings/#setscreenbrightness","title":"setScreenBrightness()","text":"

      \u8bbe\u7f6e\u5c4f\u5e55\u4eae\u5ea6\u3002

      setScreenBrightness(value=None)\n

      \u53c2\u6570\uff1a - value (int, optional): \u4eae\u5ea6\u503c\uff080-255\uff09\uff0c\u6216 None \u8868\u793a\u81ea\u52a8

      \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u4eae\u5ea6\u503c

      "},{"location":"qsl4a/system/settings/#checkscreenon","title":"checkScreenOn()","text":"

      \u68c0\u67e5\u5c4f\u5e55\u662f\u5426\u4eae\u7740\u3002

      checkScreenOn()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u5c4f\u5e55\u4eae\u7740\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/system/settings/#_2","title":"\u98de\u884c\u6a21\u5f0f","text":""},{"location":"qsl4a/system/settings/#checkairplanemode","title":"checkAirplaneMode()","text":"

      \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\u662f\u5426\u542f\u7528\u3002

      checkAirplaneMode()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u98de\u884c\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

      "},{"location":"qsl4a/system/settings/#_3","title":"\u94c3\u58f0\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#checkringersilentmode","title":"checkRingerSilentMode()","text":"

      \u68c0\u67e5\u94c3\u58f0\u662f\u5426\u5904\u4e8e\u9759\u97f3\u6a21\u5f0f\u3002

      checkRingerSilentMode()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u9759\u97f3\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

      "},{"location":"qsl4a/system/settings/#toggleringersilentmode","title":"toggleRingerSilentMode()","text":"

      \u5207\u6362\u94c3\u58f0\u9759\u97f3\u6a21\u5f0f\u3002

      toggleRingerSilentMode(enabled=None)\n

      \u53c2\u6570\uff1a - enabled (bool, optional): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

      \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

      "},{"location":"qsl4a/system/settings/#togglevibratemode","title":"toggleVibrateMode()","text":"

      \u5207\u6362\u632f\u52a8\u6a21\u5f0f\u3002

      toggleVibrateMode(enabled=None, ringer=None)\n

      \u53c2\u6570\uff1a - enabled (bool, optional): \u5207\u6362\u632f\u52a8\u5f00/\u5173 - ringer (bool, optional): \u5e94\u7528\u4e8e\u94c3\u58f0\u6a21\u5f0f

      \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

      "},{"location":"qsl4a/system/settings/#getvibratemode","title":"getVibrateMode()","text":"

      \u83b7\u53d6\u632f\u52a8\u6a21\u5f0f\u8bbe\u7f6e\u3002

      getVibrateMode(ringer=None)\n

      \u53c2\u6570\uff1a - ringer (bool, optional): \u68c0\u67e5\u94c3\u58f0\u632f\u52a8\u6a21\u5f0f

      \u8fd4\u56de\uff1a \u5982\u679c\u632f\u52a8\u5df2\u542f\u7528\u5219\u4e3a True

      "},{"location":"qsl4a/system/settings/#_4","title":"\u97f3\u91cf\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#getringervolume","title":"getRingerVolume()","text":"

      \u83b7\u53d6\u5f53\u524d\u94c3\u58f0\u97f3\u91cf\u3002

      getRingerVolume()\n

      \u8fd4\u56de\uff1a \u94c3\u58f0\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-7\uff09

      "},{"location":"qsl4a/system/settings/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

      getMaxRingerVolume()\n

      \u8fd4\u56de\uff1a \u6700\u5927\u94c3\u58f0\u97f3\u91cf

      "},{"location":"qsl4a/system/settings/#setringervolume","title":"setRingerVolume()","text":"

      \u8bbe\u7f6e\u94c3\u58f0\u97f3\u91cf\u3002

      setRingerVolume(volume)\n

      \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

      "},{"location":"qsl4a/system/settings/#getmediavolume","title":"getMediaVolume()","text":"

      \u83b7\u53d6\u5f53\u524d\u5a92\u4f53\u97f3\u91cf\u3002

      getMediaVolume()\n

      \u8fd4\u56de\uff1a \u5a92\u4f53\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-15\uff09

      "},{"location":"qsl4a/system/settings/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

      getMaxMediaVolume()\n

      \u8fd4\u56de\uff1a \u6700\u5927\u5a92\u4f53\u97f3\u91cf

      "},{"location":"qsl4a/system/settings/#setmediavolume","title":"setMediaVolume()","text":"

      \u8bbe\u7f6e\u5a92\u4f53\u97f3\u91cf\u3002

      setMediaVolume(volume)\n

      \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

      "},{"location":"qsl4a/system/settings/#_5","title":"\u7cfb\u7edf\u4fe1\u606f","text":""},{"location":"qsl4a/system/settings/#elapsedrealtimenanos","title":"elapsedRealtimeNanos()","text":"

      \u83b7\u53d6\u81ea\u7cfb\u7edf\u542f\u52a8\u4ee5\u6765\u7684\u7eb3\u79d2\u6570\u3002

      elapsedRealtimeNanos()\n

      \u8fd4\u56de\uff1a \u7eb3\u79d2\u6570\uff08\u53ef\u7528\u4e8e\u8ba1\u65f6\uff09

      "},{"location":"qsl4a/system/settings/#gettrafficstats","title":"getTrafficStats()","text":"

      \u83b7\u53d6\u7f51\u7edc\u6d41\u91cf\u7edf\u8ba1\u3002

      getTrafficStats(flags=7)\n

      \u53c2\u6570\uff1a - flags (int): \u8981\u68c0\u7d22\u7684\u7edf\u8ba1\uff08\u9ed8\u8ba4\uff1a7 = \u5168\u90e8\uff09

      \u8fd4\u56de\uff1a \u5305\u542b\u53d1\u9001/\u63a5\u6536\u5b57\u8282\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/settings/#getapptxbytes","title":"getAppTxBytes()","text":"

      \u83b7\u53d6 QPython \u5e94\u7528\u7684\u53d1\u9001\u5b57\u8282\u3002

      getAppTxBytes(packageName)\n

      \u53c2\u6570\uff1a - packageName (str): \u5305\u540d

      \u8fd4\u56de\uff1a \u5305\u542b tx/rx \u5b57\u8282\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/settings/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5c4f\u5e55\u8bbe\u7f6e\ncurrent_timeout = droid.getScreenTimeout().result\nprint(f\"Current timeout: {current_timeout}s\")\ndroid.setScreenTimeout(30)\n\n# \u68c0\u67e5\u5c4f\u5e55\nif droid.checkScreenOn().result:\n    print(\"Screen is on\")\n\n# \u97f3\u91cf\u63a7\u5236\nmedia_vol = droid.getMediaVolume().result\nprint(f\"Media volume: {media_vol}\")\ndroid.setMediaVolume(10)\n\n# \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\nif droid.checkAirplaneMode().result:\n    print(\"Airplane mode is on\")\n
      "},{"location":"qsl4a/system/sysinfo/","title":"\u7cfb\u7edf\u4fe1\u606f","text":"

      \u68c0\u7d22\u8bbe\u5907\u548c\u7cfb\u7edf\u4fe1\u606f\u3002

      "},{"location":"qsl4a/system/sysinfo/#_2","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/sysinfo/#getandroidid","title":"getAndroidID()","text":"

      \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

      getAndroidID()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

      "},{"location":"qsl4a/system/sysinfo/#getsysinfo","title":"getSysInfo()","text":"

      \u83b7\u53d6\u7efc\u5408\u7cfb\u7edf\u4fe1\u606f\u3002

      getSysInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/sysinfo/#getlocale","title":"getLocale()","text":"

      \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u8bbe\u7f6e\u3002

      getLocale()\n

      \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

      "},{"location":"qsl4a/system/sysinfo/#_3","title":"\u5185\u5b58","text":""},{"location":"qsl4a/system/sysinfo/#getmemoryinfo","title":"getMemoryInfo()","text":"

      \u83b7\u53d6 RAM \u4fe1\u606f\u3002

      getMemoryInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/sysinfo/#_4","title":"\u663e\u793a","text":""},{"location":"qsl4a/system/sysinfo/#getscreeninfo","title":"getScreenInfo()","text":"

      \u83b7\u53d6\u663e\u793a\u4fe1\u606f\u3002

      getScreenInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/sysinfo/#_5","title":"\u6807\u8bc6\u7b26","text":""},{"location":"qsl4a/system/sysinfo/#getimei","title":"getImei()","text":"

      \u83b7\u53d6\u8bbe\u5907 IMEI\u3002

      getImei(slotIndex=None)\n
      "},{"location":"qsl4a/system/sysinfo/#getmeid","title":"getMeid()","text":"

      \u83b7\u53d6\u8bbe\u5907 MEID\u3002

      getMeid(slotIndex=None)\n
      "},{"location":"qsl4a/system/sysinfo/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u8bbe\u5907 ID\nandroid_id = droid.getAndroidID().result\nprint(f\"Android ID: {android_id}\")\n\n# \u5c4f\u5e55\u4fe1\u606f\nscreen = droid.getScreenInfo().result\nprint(f\"Screen: {screen['width']}x{screen['height']}\")\n\n# \u5185\u5b58\nmemory = droid.getMemoryInfo().result\nprint(f\"Memory: {memory}\")\n
      "},{"location":"qsl4a/system/wakelock/","title":"WakeLock API","text":"

      \u63a7\u5236\u8bbe\u5907\u5524\u9192\u9501\u4ee5\u4fdd\u6301 CPU \u6216\u5c4f\u5e55\u5f00\u542f\u3002

      "},{"location":"qsl4a/system/wakelock/#wake-lock","title":"Wake Lock \u7c7b\u578b","text":"

      QSL4A \u63d0\u4f9b\u4e0d\u540c\u7c7b\u578b\u7684\u5524\u9192\u9501\uff1a

      \u7c7b\u578b \u63cf\u8ff0 Full CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae Partial \u4ec5 CPU \u5f00\u542f Bright CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae Dim CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697"},{"location":"qsl4a/system/wakelock/#wake-lock_1","title":"Wake Lock \u65b9\u6cd5","text":""},{"location":"qsl4a/system/wakelock/#wakelockacquirefull","title":"wakeLockAcquireFull()","text":"

      \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae\uff09\u3002

      wakeLockAcquireFull()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquirepartial","title":"wakeLockAcquirePartial()","text":"

      \u83b7\u53d6\u90e8\u5206\u5524\u9192\u9501\uff08\u4ec5 CPU \u5f00\u542f\uff09\u3002

      wakeLockAcquirePartial()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquirebright","title":"wakeLockAcquireBright()","text":"

      \u83b7\u53d6\u660e\u4eae\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff09\u3002

      wakeLockAcquireBright()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquiredim","title":"wakeLockAcquireDim()","text":"

      \u83b7\u53d6\u6697\u6de1\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697\uff09\u3002

      wakeLockAcquireDim()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockrelease","title":"wakeLockRelease()","text":"

      \u91ca\u653e\u5524\u9192\u9501\u3002

      wakeLockRelease()\n
      "},{"location":"qsl4a/system/wakelock/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\ndroid.wakeLockAcquireFull()\n\n# \u5728\u4fdd\u6301\u5c4f\u5e55\u5f00\u542f\u65f6\u6267\u884c\u91cd\u8981\u5de5\u4f5c\nprint(\"Screen will stay on\")\ntime.sleep(10)\n\n# \u5b8c\u6210\u540e\u91ca\u653e\ndroid.wakeLockRelease()\n\n# \u6216\u4f7f\u7528\u90e8\u5206\u9501\u8fdb\u884c\u540e\u53f0\u4efb\u52a1\ndroid.wakeLockAcquirePartial()\n# \u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\uff0cCPU \u4ecd\u4fdd\u6301\u5f00\u542f\ntime.sleep(30)\ndroid.wakeLockRelease()\n

      \u6ce8\u610f\uff1a \u8bb0\u4f4f\u5728\u4e0d\u9700\u8981\u65f6\u91ca\u653e\u5524\u9192\u9501\u4ee5\u8282\u7701\u7535\u6c60\u3002

      "},{"location":"qsl4a/ui/accessibility/","title":"\u65e0\u969c\u788d\u670d\u52a1","text":"

      \u65e0\u969c\u788d\u670d\u52a1\u5141\u8bb8\u81ea\u52a8\u5316 UI \u4ea4\u4e92\uff0c\u5982\u70b9\u51fb\u3001\u6ed1\u52a8\u548c\u7cfb\u7edf\u64cd\u4f5c\u3002

      "},{"location":"qsl4a/ui/accessibility/#_2","title":"\u670d\u52a1\u63a7\u5236","text":""},{"location":"qsl4a/ui/accessibility/#accessibilitystartservice","title":"accessibilityStartService()","text":"

      \u542f\u52a8\u65e0\u969c\u788d\u670d\u52a1\u3002

      accessibilityStartService()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/ui/accessibility/#accessibilityserviceenabled","title":"accessibilityServiceEnabled()","text":"

      \u68c0\u67e5\u65e0\u969c\u788d\u670d\u52a1\u662f\u5426\u5df2\u542f\u7528\u3002

      accessibilityServiceEnabled()\n

      \u8fd4\u56de\uff1a True \u6216 False

      "},{"location":"qsl4a/ui/accessibility/#_3","title":"\u5c4f\u5e55\u4ea4\u4e92","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityclick","title":"accessibilityClick()","text":"

      \u5728\u5c4f\u5e55\u5750\u6807\u5904\u70b9\u51fb\u3002

      accessibilityClick(x=0, y=0, t=50)\n

      \u53c2\u6570\uff1a - x (int/float): X \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - y (int/float): Y \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - t (int): \u6309\u4f4f\u65f6\u957f\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a50\uff09

      "},{"location":"qsl4a/ui/accessibility/#accessibilityslide","title":"accessibilitySlide()","text":"

      \u591a\u70b9\u6ed1\u52a8\u624b\u52bf\u3002

      accessibilitySlide(XnYn=None, t=None)\n

      \u53c2\u6570\uff1a - XnYn (list): \u5750\u6807 [X1, Y1, X2, Y2, ... Xn, Yn] - t (int): \u6ed1\u52a8\u65f6\u957f\uff08\u9ed8\u8ba4\uff1a50*n \u6beb\u79d2\uff09

      "},{"location":"qsl4a/ui/accessibility/#_4","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityaction","title":"accessibilityAction()","text":"

      \u6309\u4ee3\u7801\u6267\u884c\u7cfb\u7edf\u64cd\u4f5c\u3002

      accessibilityAction(actionCode)\n

      \u64cd\u4f5c\u4ee3\u7801\uff1a | \u4ee3\u7801 | \u5e38\u91cf | \u63cf\u8ff0 | |------|----------|-------------| | 1 | BACK | \u8fd4\u56de\u6309\u94ae | | 2 | HOME | \u4e3b\u5c4f\u5e55\u6309\u94ae | | 3 | RECENTS | \u6700\u8fd1\u5e94\u7528 | | 4 | NOTIFICATIONS | \u6253\u5f00\u901a\u77e5 | | 5 | QUICK_SETTINGS | \u6253\u5f00\u5feb\u901f\u8bbe\u7f6e | | 6 | POWER_DIALOG | \u7535\u6e90\u83dc\u5355 | | 7 | TOGGLE_SPLIT_SCREEN | \u5206\u5c4f | | 8 | LOCK_SCREEN | \u9501\u5c4f | | 9 | TAKE_SCREENSHOT | \u622a\u56fe | | 10 | KEYCODE_HEADSETHOOK | \u8033\u673a\u6302\u94a9 | | 11-14 | ACCESSIBILITY_ | \u65e0\u969c\u788d\u6309\u94ae | | 15 | DISMISS_NOTIFICATION_SHADE | \u5173\u95ed\u901a\u77e5\u680f | | 16-20 | DPAD_ | \u65b9\u5411\u952e | | 21 | MENU | \u83dc\u5355\u6309\u94ae | | 22 | MEDIA_PLAY_PAUSE | \u64ad\u653e/\u6682\u505c\u5a92\u4f53 |

      "},{"location":"qsl4a/ui/accessibility/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/accessibility/#_6","title":"\u70b9\u51fb\u5c4f\u5e55\u4e2d\u5fc3","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u670d\u52a1\nif not droid.accessibilityServiceEnabled().result:\n    droid.accessibilityStartService()\n\n# \u70b9\u51fb\u4e2d\u5fc3\uff080,0 = \u4e2d\u5fc3\uff09\ndroid.accessibilityClick(0, 0, t=100)\n
      "},{"location":"qsl4a/ui/accessibility/#_7","title":"\u6ed1\u52a8\u624b\u52bf","text":"
      # \u4ece\u4e0b\u5f80\u4e0a\u6ed1\u52a8\uff08\u5411\u4e0a\u6eda\u52a8\uff09\ndroid.accessibilitySlide([0, 1.5, 0, -1.5], t=300)\n
      "},{"location":"qsl4a/ui/accessibility/#_8","title":"\u7cfb\u7edf\u5bfc\u822a","text":"
      # \u6309\u4e3b\u5c4f\u5e55\ndroid.accessibilityAction(2)\n\n# \u6309\u8fd4\u56de\ndroid.accessibilityAction(1)\n\n# \u6253\u5f00\u901a\u77e5\ndroid.accessibilityAction(4)\n
      "},{"location":"qsl4a/ui/accessibility/#_9","title":"\u70b9\u51fb\u7279\u5b9a\u4f4d\u7f6e","text":"
      # \u70b9\u51fb\u5c4f\u5e55\u5750\u6807 (500, 800)\ndroid.accessibilityClick(500, 800)\n\n# \u70b9\u51fb\u76f8\u5bf9\u4f4d\u7f6e\uff08\u6c34\u5e73\u5c45\u4e2d\uff0c\u5782\u76f4 3/4 \u5904\uff09\ndroid.accessibilityClick(0, 1.5)\n
      "},{"location":"qsl4a/ui/dialogs/","title":"\u5bf9\u8bdd\u6846\u7cfb\u7edf","text":"

      QSL4A \u63d0\u4f9b\u5168\u9762\u7684\u5bf9\u8bdd\u6846\u652f\u6301\uff0c\u7528\u4e8e\u7528\u6237\u4ea4\u4e92\uff0c\u5305\u62ec\u8b66\u62a5\u3001\u8f93\u5165\u5bf9\u8bdd\u6846\u3001\u9009\u62e9\u5bf9\u8bdd\u6846\u548c\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

      "},{"location":"qsl4a/ui/dialogs/#_2","title":"\u8b66\u62a5\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowalert","title":"dialogShowAlert()","text":"

      \u663e\u793a\u7b80\u5355\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

      dialogShowAlert(title=\"Alert\", message=\"The message of the alert.\",\n                positiveButtonText=\"OK\", negativeButtonText=None,\n                neutralButtonText=None, messageIsHtml=False)\n

      \u53c2\u6570\uff1a - title (str): \u5bf9\u8bdd\u6846\u6807\u9898 - message (str): \u6d88\u606f\u6587\u672c - positiveButtonText (str): \u80af\u5b9a\u6309\u94ae\u6807\u7b7e - negativeButtonText (str, optional): \u5426\u5b9a\u6309\u94ae\u6807\u7b7e - neutralButtonText (str, optional): \u4e2d\u6027\u6309\u94ae\u6807\u7b7e - messageIsHtml (bool): \u5c06\u6d88\u606f\u89e3\u6790\u4e3a HTML

      \u8fd4\u56de\uff1a \u5305\u542b\u70b9\u51fb\u6309\u94ae\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#dialogshowsimplechoice","title":"dialogShowSimpleChoice()","text":"

      \u663e\u793a\u5e26\u6709\u9879\u76ee\u7684\u7b80\u5355\u9009\u62e9\u5bf9\u8bdd\u6846\u3002

      dialogShowSimpleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

      \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868

      \u8fd4\u56de\uff1a \u5305\u542b\u9009\u4e2d\u9879\u76ee\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#_3","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialoggetinput","title":"dialogGetInput()","text":"

      \u83b7\u53d6\u7528\u6237\u6587\u672c\u8f93\u5165\u3002

      dialogGetInput(title=\"Value\", message=\"Please enter value:\",\n               defaultText=None, messageIsHtml=False)\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7528\u6237\u8f93\u5165\u6587\u672c\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#dialoggetpassword","title":"dialogGetPassword()","text":"

      \u83b7\u53d6\u5bc6\u7801\u8f93\u5165\u3002

      dialogGetPassword(title=\"Password\", message=\"Please enter password:\")\n

      \u8fd4\u56de\uff1a \u5305\u542b\u8f93\u5165\u5bc6\u7801\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#dialogcreateinput","title":"dialogCreateInput()","text":"

      \u521b\u5efa\u81ea\u5b9a\u4e49\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

      dialogCreateInput(title=\"Value\", message=\"Please enter value:\",\n                  defaultText=None, inputType=None)\n

      \u53c2\u6570\uff1a - inputType (str): \u8f93\u5165\u7c7b\u578b\uff08\u4f8b\u5982 \"text\"\u3001\"number\"\u3001\"textPassword\"\uff09

      "},{"location":"qsl4a/ui/dialogs/#dialogcreatepassword","title":"dialogCreatePassword()","text":"

      \u521b\u5efa\u5bc6\u7801\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

      dialogCreatePassword(title=\"Password\", message=\"Please enter password:\")\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreateseekbar","title":"dialogCreateSeekBar()","text":"

      \u521b\u5efa\u6ed1\u5757/\u8fdb\u5ea6\u6761\u5bf9\u8bdd\u6846\u3002

      dialogCreateSeekBar(starting_value=50, maximum_value=100, title=\"\", message=\"\")\n

      \u53c2\u6570\uff1a - starting_value (int): \u521d\u59cb\u503c - maximum_value (int): \u6700\u5927\u503c

      "},{"location":"qsl4a/ui/dialogs/#_4","title":"\u9009\u62e9\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowsinglechoice","title":"dialogShowSingleChoice()","text":"

      \u663e\u793a\u5355\u9009\uff08\u5355\u9009\u6309\u94ae\uff09\u5bf9\u8bdd\u6846\u3002

      dialogShowSingleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, selected=-1, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

      \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (int): \u9ed8\u8ba4\u9009\u4e2d\u7d22\u5f15

      "},{"location":"qsl4a/ui/dialogs/#dialogshowmultichoice","title":"dialogShowMultiChoice()","text":"

      \u663e\u793a\u591a\u9009\uff08\u590d\u9009\u6846\uff09\u5bf9\u8bdd\u6846\u3002

      dialogShowMultiChoice(title=\"Alert\", message=\"The message of the alert.\",\n                      items=None, selected=None, positiveButtonText=\"OK\",\n                      negativeButtonText=None, neutralButtonText=None,\n                      messageIsHtml=False)\n

      \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (list): \u521d\u59cb\u9009\u4e2d\u7d22\u5f15\u5217\u8868

      "},{"location":"qsl4a/ui/dialogs/#dialogsetsinglechoiceitems","title":"dialogSetSingleChoiceItems()","text":"

      \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u5355\u9009\u9879\u76ee\u3002

      dialogSetSingleChoiceItems(items, selected=-1)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmultichoiceitems","title":"dialogSetMultiChoiceItems()","text":"

      \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u591a\u9009\u9879\u76ee\u3002

      dialogSetMultiChoiceItems(items, selected=None)\n
      "},{"location":"qsl4a/ui/dialogs/#_5","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatespinnerprogress","title":"dialogCreateSpinnerProgress()","text":"

      \u521b\u5efa\u4e0d\u786e\u5b9a\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

      dialogCreateSpinnerProgress(title=None, message=None, maximum_progress=100)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreatehorizontalprogress","title":"dialogCreateHorizontalProgress()","text":"

      \u521b\u5efa\u6c34\u5e73\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

      dialogCreateHorizontalProgress(title=None, message=None, maximum_progress=100)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetcurrentprogress","title":"dialogSetCurrentProgress()","text":"

      \u66f4\u65b0\u8fdb\u5ea6\u503c\u3002

      dialogSetCurrentProgress(current)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmaxprogress","title":"dialogSetMaxProgress()","text":"

      \u8bbe\u7f6e\u6700\u5927\u8fdb\u5ea6\u503c\u3002

      dialogSetMaxProgress(max)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetprogressmessage","title":"dialogSetProgressMessage()","text":"

      \u66f4\u65b0\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u6d88\u606f\u3002

      dialogSetProgressMessage(message)\n
      "},{"location":"qsl4a/ui/dialogs/#_6","title":"\u9009\u62e9\u5668\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatedatepicker","title":"dialogCreateDatePicker()","text":"

      \u521b\u5efa\u65e5\u671f\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

      dialogCreateDatePicker(year=1970, month=1, day=1)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreatetimepicker","title":"dialogCreateTimePicker()","text":"

      \u521b\u5efa\u65f6\u95f4\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

      dialogCreateTimePicker(hour=0, minute=0, is24hour=False)\n
      "},{"location":"qsl4a/ui/dialogs/#_7","title":"\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u521b\u5efa","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatealert","title":"dialogCreateAlert()","text":"

      \u521b\u5efa\u81ea\u5b9a\u4e49\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

      dialogCreateAlert(title=None, message=None)\n

      \u521b\u5efa\u4e00\u4e2a\u7a7a\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002\u53ef\u4e0e\u5176\u4ed6 dialogSet* \u51fd\u6570\u4e00\u8d77\u4f7f\u7528\u6765\u81ea\u5b9a\u4e49\u3002

      "},{"location":"qsl4a/ui/dialogs/#dialogsetitems","title":"dialogSetItems()","text":"

      \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u7b80\u5355\u5217\u8868\u9879\u76ee\u3002

      dialogSetItems(items)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetpositivebuttontext","title":"dialogSetPositiveButtonText()","text":"

      \u8bbe\u7f6e\u80af\u5b9a\u6309\u94ae\u6587\u672c\u3002

      dialogSetPositiveButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetnegativebuttontext","title":"dialogSetNegativeButtonText()","text":"

      \u8bbe\u7f6e\u5426\u5b9a\u6309\u94ae\u6587\u672c\u3002

      dialogSetNegativeButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetneutralbuttontext","title":"dialogSetNeutralButtonText()","text":"

      \u8bbe\u7f6e\u4e2d\u6027\u6309\u94ae\u6587\u672c\u3002

      dialogSetNeutralButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmessageishtml","title":"dialogSetMessageIsHtml()","text":"

      \u8bbe\u7f6e\u6d88\u606f\u662f\u5426\u5e94\u89e3\u6790\u4e3a HTML\u3002

      dialogSetMessageIsHtml(messageIsHtml=True)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogshow","title":"dialogShow()","text":"

      \u663e\u793a\u521b\u5efa\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u3002

      dialogShow()\n
      "},{"location":"qsl4a/ui/dialogs/#_8","title":"\u5bf9\u8bdd\u6846\u63a7\u5236","text":""},{"location":"qsl4a/ui/dialogs/#dialogdismiss","title":"dialogDismiss()","text":"

      \u5173\u95ed\u5f53\u524d\u5bf9\u8bdd\u6846\u3002

      dialogDismiss()\n
      "},{"location":"qsl4a/ui/dialogs/#dialoggetresponse","title":"dialogGetResponse()","text":"

      \u83b7\u53d6\u5bf9\u8bdd\u6846\u54cd\u5e94\u3002

      dialogGetResponse()\n
      "},{"location":"qsl4a/ui/dialogs/#dialoggetselecteditems","title":"dialogGetSelectedItems()","text":"

      \u4ece\u9009\u62e9\u5bf9\u8bdd\u6846\u83b7\u53d6\u9009\u4e2d\u7684\u9879\u76ee\u3002

      dialogGetSelectedItems()\n
      "},{"location":"qsl4a/ui/dialogs/#_9","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/dialogs/#_10","title":"\u7b80\u5355\u8b66\u62a5","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a\u8b66\u62a5\ndroid.dialogShowAlert(\"Warning\", \"This is an important message!\")\n
      "},{"location":"qsl4a/ui/dialogs/#_11","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":"
      # \u83b7\u53d6\u7528\u6237\u8f93\u5165\nresult = droid.dialogGetInput(\"Name\", \"Enter your name:\", \"John\").result\nprint(f\"Hello, {result}!\")\n
      "},{"location":"qsl4a/ui/dialogs/#_12","title":"\u5e26\u6309\u94ae\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846","text":"
      # \u521b\u5efa\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\ndroid.dialogCreateAlert(\"Custom\", \"Choose an option\")\ndroid.dialogSetItems([\"Option 1\", \"Option 2\", \"Option 3\"])\ndroid.dialogShow()\n\n# \u83b7\u53d6\u54cd\u5e94\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response['item']}\")\n
      "},{"location":"qsl4a/ui/dialogs/#_13","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":"
      # \u521b\u5efa\u8fdb\u5ea6\u5bf9\u8bdd\u6846\ndroid.dialogCreateHorizontalProgress(\"Loading\", \"Please wait...\", 100)\ndroid.dialogShow()\n\n# \u66f4\u65b0\u8fdb\u5ea6\nfor i in range(101):\n    droid.dialogSetCurrentProgress(i)\n    time.sleep(0.05)\n\ndroid.dialogDismiss()\n
      "},{"location":"qsl4a/ui/dialogs/#_14","title":"\u65e5\u671f\u9009\u62e9\u5668","text":"
      # \u663e\u793a\u65e5\u671f\u9009\u62e9\u5668\ndroid.dialogCreateDatePicker(2024, 1, 15)\ndroid.dialogShow()\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response}\")\n
      "},{"location":"qsl4a/ui/floatview/","title":"\u6d6e\u52a8\u89c6\u56fe","text":"

      \u6d6e\u52a8\u7a97\u53e3\u652f\u6301\uff0c\u7528\u4e8e\u5728\u5176\u4ed6\u5e94\u7528\u7a0b\u5e8f\u4e0a\u65b9\u4fdd\u6301\u663e\u793a\u7684\u8986\u76d6 UI \u5143\u7d20\u3002

      "},{"location":"qsl4a/ui/floatview/#_2","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/floatview/#floatview","title":"floatView()","text":"

      \u663e\u793a\u6216\u4fee\u6539\u6d6e\u52a8\u89c6\u56fe\u3002

      floatView(Args=None)\n

      \u53c2\u6570\uff1a - Args (dict): \u914d\u7f6e\u5b57\u5178\uff0c\u5305\u542b\u4ee5\u4e0b\u952e\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08-1 \u521b\u5efa\u65b0\u7684\uff0c>=0 \u4fee\u6539\u73b0\u6709\u7684\uff09 - text (str): \u8981\u663e\u793a\u7684\u6587\u672c\u5185\u5bb9 - html (str): HTML \u5185\u5bb9\uff08\u5982\u679c\u7701\u7565 text \u5219\u4f7f\u7528\uff09 - width (int): \u89c6\u56fe\u5bbd\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a300\uff09 - height (int): \u89c6\u56fe\u9ad8\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a150\uff09 - x (int): X \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - y (int): Y \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - backColor (str): ARGB \u5341\u516d\u8fdb\u5236\u80cc\u666f\u8272\uff08\u9ed8\u8ba4\uff1a'7f7f7f7f'\uff09 - textColor (str): ARGB \u5341\u516d\u8fdb\u5236\u6587\u672c\u8272\uff08\u9ed8\u8ba4\uff1a'ff000000'\uff09 - textSize (int): \u6587\u672c\u5927\u5c0f\uff08\u9ed8\u8ba4\uff1a10\uff09 - textAlign (int): \u6587\u672c\u5bf9\u9f50\uff080 = \u7ee7\u627f\uff09 - script (str): \u957f\u6309\u5173\u95ed\u540e\u8fd0\u884c\u7684\u811a\u672c\u8def\u5f84 - arg: \u811a\u672c\u53c2\u6570 - clickRemove (bool): \u542f\u7528\u70b9\u51fb\u79fb\u9664\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - flag (int): \u7a97\u53e3\u6807\u5fd7\uff08\u9ed8\u8ba4\uff1a40 - \u53ef\u89e6\u6478\uff09

      \u8fd4\u56de\uff1a \u5f53\u524d\u94fe\u5217\u8868\u957f\u5ea6

      "},{"location":"qsl4a/ui/floatview/#floatviewcount","title":"floatViewCount()","text":"

      \u83b7\u53d6\u6d3b\u52a8\u6d6e\u52a8\u89c6\u56fe\u7684\u6570\u91cf\u3002

      floatViewCount()\n

      \u8fd4\u56de\uff1a \u6d6e\u52a8\u89c6\u56fe\u6570\u91cf

      "},{"location":"qsl4a/ui/floatview/#floatviewresult","title":"floatViewResult()","text":"

      \u83b7\u53d6\u6d6e\u52a8\u89c6\u56fe\u7684\u7ed3\u679c/\u72b6\u6001\u3002

      floatViewResult(index=-1)\n

      \u53c2\u6570\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1\uff0c\u8fd4\u56de\u6700\u540e\u64cd\u4f5c\u7ed3\u679c\uff09

      \u8fd4\u56de\uff1a \u5305\u542b\u64cd\u4f5c\u8be6\u60c5\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - x, y: \u4f4d\u7f6e - time: \u65f6\u95f4\u6233 - operation: \u64cd\u4f5c\u7c7b\u578b\uff08'initial'\u3001'move' \u7b49\uff09 - index: \u89c6\u56fe\u7d22\u5f15 - removed: \u5982\u679c\u89c6\u56fe\u88ab\u79fb\u9664\u5219\u4e3a True

      "},{"location":"qsl4a/ui/floatview/#floatviewremove","title":"floatViewRemove()","text":"

      \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\u3002

      floatViewRemove(index=-1)\n

      \u53c2\u6570\uff1a - index (int): \u8981\u79fb\u9664\u7684\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1 \u79fb\u9664\u6700\u540e\u4e00\u4e2a\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a 1\uff0c\u5426\u5219\u4e3a 0

      "},{"location":"qsl4a/ui/floatview/#_3","title":"\u5e38\u91cf","text":"
      • floatView.INDEX_NEW = -1 - \u521b\u5efa\u65b0\u7684\u6d6e\u52a8\u89c6\u56fe
      • floatView.FLAG_DEFAULT_TOUCHABLE = 40 - \u9ed8\u8ba4\u53ef\u89e6\u6478\u6807\u5fd7
      • floatView.TEXT_ALIGNMENT_INHERIT = 0
      • floatView.TEXT_ALIGNMENT_CENTER - \u5c45\u4e2d\u6587\u672c\u5bf9\u9f50
      "},{"location":"qsl4a/ui/floatview/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/floatview/#_5","title":"\u57fa\u672c\u6d6e\u52a8\u89c6\u56fe","text":"
      import androidhelper\nfrom androidhelper import Android\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u7b80\u5355\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'index': -1,  # \u521b\u5efa\u65b0\u7684\n    'text': 'Hello World',\n    'width': 400,\n    'height': 300,\n    'x': -300,  # \u4ece\u4e2d\u5fc3\u504f\u79fb\n    'y': -400,\n    'backColor': 'ff0000',  # \u7ea2\u8272\u80cc\u666f\n    'textColor': '0000ff',  # \u84dd\u8272\u6587\u672c\n    'textSize': 16,\n    'textAlign': droid.floatView.TEXT_ALIGNMENT_CENTER\n})\n\n# \u68c0\u67e5\u6570\u91cf\nprint(f\"Float views: {droid.floatViewCount().result}\")\n\n# \u83b7\u53d6\u7ed3\u679c\nresult = droid.floatViewResult().result\nprint(f\"View info: {result}\")\n\n# \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\ndroid.floatViewRemove(0)\n
      "},{"location":"qsl4a/ui/floatview/#html","title":"HTML \u5185\u5bb9","text":"
      # \u521b\u5efa\u5e26 HTML \u5185\u5bb9\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': '',  # \u7a7a\u6587\u672c\u4ee5\u4f7f\u7528 HTML\n    'html': '<h1>Title</h1><p>Rich <b>HTML</b> content</p>',\n    'width': 500,\n    'height': 400\n})\n
      "},{"location":"qsl4a/ui/floatview/#_6","title":"\u4fee\u6539\u73b0\u6709\u89c6\u56fe","text":"
      # \u521b\u5efa\u521d\u59cb\u89c6\u56fe\ndroid.floatView({'text': 'Initial Text', 'width': 300, 'height': 150})\n\n# \u4fee\u6539\u540c\u4e00\u89c6\u56fe\uff08\u7d22\u5f15 0\uff09\ndroid.floatView({\n    'index': 0,\n    'text': 'Updated Text!',\n    'backColor': '7f00ff00'  # \u7eff\u8272\u80cc\u666f\n})\n\n# \u68c0\u67e5\u79fb\u52a8/\u66f4\u6539\u7ed3\u679c\nresult = droid.floatViewResult(0).result\nprint(f\"Operation: {result.get('operation')}, Position: ({result.get('x')}, {result.get('y')})\")\n
      "},{"location":"qsl4a/ui/floatview/#_7","title":"\u591a\u4e2a\u6d6e\u52a8\u89c6\u56fe","text":"
      # \u521b\u5efa\u591a\u4e2a\u89c6\u56fe\nfor i in range(3):\n    droid.floatView({\n        'index': -1,\n        'text': f'View {i}',\n        'x': i * 100 - 150,\n        'y': i * 100 - 150,\n        'backColor': f'{i}f{i}f{i}f'\n    })\n\nprint(f\"Total views: {droid.floatViewCount().result}\")\n\n# \u79fb\u9664\u6240\u6709\u89c6\u56fe\nwhile droid.floatViewCount().result > 0:\n    droid.floatViewRemove()\n
      "},{"location":"qsl4a/ui/floatview/#_8","title":"\u5e26\u811a\u672c\u56de\u8c03","text":"
      # \u521b\u5efa\u5173\u95ed\u65f6\u8fd0\u884c\u811a\u672c\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': 'Click to close and run script',\n    'script': '/sdcard/my_script.py',\n    'arg': 'hello from float view',\n    'clickRemove': True\n})\n
      "},{"location":"qsl4a/ui/fullscreen/","title":"\u5168\u5c4f UI","text":"

      \u4f7f\u7528\u539f\u751f Android \u5e03\u5c40\u521b\u5efa\u81ea\u5b9a\u4e49\u5168\u5c4f\u754c\u9762\u3002

      "},{"location":"qsl4a/ui/fullscreen/#_1","title":"\u5e03\u5c40\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullshow","title":"fullShow()","text":"

      \u663e\u793a\u5168\u5c4f\u5e03\u5c40\u3002

      fullShow(layout, title=None, theme=None)\n

      \u53c2\u6570\uff1a - layout (str): JSON \u5e03\u5c40\u5b9a\u4e49\u6216\u5e03\u5c40\u5b57\u7b26\u4e32 - title (str, optional): \u7a97\u53e3\u6807\u9898 - theme (str, optional): \u4e3b\u9898\u540d\u79f0

      \u8fd4\u56de\uff1a \u7a97\u53e3 ID

      "},{"location":"qsl4a/ui/fullscreen/#fulldismiss","title":"fullDismiss()","text":"

      \u5173\u95ed\u5168\u5c4f\u7a97\u53e3\u3002

      fullDismiss()\n
      "},{"location":"qsl4a/ui/fullscreen/#fullquery","title":"fullQuery()","text":"

      \u67e5\u8be2\u6240\u6709\u5c0f\u90e8\u4ef6\u503c\u3002

      fullQuery()\n

      \u8fd4\u56de\uff1a \u5c0f\u90e8\u4ef6 ID \u548c\u503c\u7684\u5b57\u5178

      "},{"location":"qsl4a/ui/fullscreen/#fullquerydetail","title":"fullQueryDetail()","text":"

      \u67e5\u8be2\u7279\u5b9a\u5c0f\u90e8\u4ef6\u8be6\u60c5\u3002

      fullQueryDetail(id)\n
      "},{"location":"qsl4a/ui/fullscreen/#_2","title":"\u5c5e\u6027\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperty","title":"fullGetProperty()","text":"

      \u83b7\u53d6\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

      fullGetProperty(id, property)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetproperty","title":"fullSetProperty()","text":"

      \u8bbe\u7f6e\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

      fullSetProperty(id, property, value)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetlist","title":"fullSetList()","text":"

      \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

      fullSetList(id, list, isHtml=False, listType=0)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetlist2","title":"fullSetList2()","text":"

      \u4f7f\u7528\u8d44\u6e90 ID \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

      fullSetList2(id, list, intRes)\n

      \u53c2\u6570\uff1a - id (str): \u5c0f\u90e8\u4ef6 ID - list (list): \u9879\u76ee\u5217\u8868 - intRes (int): \u5217\u8868\u9879\u76ee\u5e03\u5c40\u7684 Android \u8d44\u6e90 ID

      "},{"location":"qsl4a/ui/fullscreen/#fullsetlistselected","title":"fullSetListSelected()","text":"

      \u5728\u5217\u8868\u4e2d\u8bbe\u7f6e\u9009\u4e2d\u9879\u76ee\u3002

      fullSetListSelected(id, selected)\n

      \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID - selected (int): \u8981\u9009\u4e2d\u7684\u9879\u76ee\u7d22\u5f15

      "},{"location":"qsl4a/ui/fullscreen/#fullgetlistselected","title":"fullGetListSelected()","text":"

      \u83b7\u53d6\u5f53\u524d\u9009\u4e2d\u7684\u5217\u8868\u9879\u76ee\u7d22\u5f15\u3002

      fullGetListSelected(id)\n

      \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID

      \u8fd4\u56de\uff1a \u9009\u4e2d\u9879\u76ee\u7d22\u5f15

      "},{"location":"qsl4a/ui/fullscreen/#_3","title":"\u6279\u91cf\u5c5e\u6027\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperties","title":"fullGetProperties()","text":"

      \u4e00\u6b21\u83b7\u53d6\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

      fullGetProperties(ids, property)\n

      \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u83b7\u53d6\u7684\u5c5e\u6027\u540d

      \u8fd4\u56de\uff1a \u6620\u5c04\u5c0f\u90e8\u4ef6 ID \u5230\u5c5e\u6027\u503c\u7684\u5b57\u5178

      "},{"location":"qsl4a/ui/fullscreen/#fullsetproperties","title":"fullSetProperties()","text":"

      \u4e00\u6b21\u8bbe\u7f6e\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

      fullSetProperties(ids, property, value)\n

      \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u8bbe\u7f6e\u7684\u5c5e\u6027\u540d - value: \u5c5e\u6027\u503c

      "},{"location":"qsl4a/ui/fullscreen/#_4","title":"\u622a\u56fe","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetscreenshot","title":"fullGetScreenShot()","text":"

      \u6355\u83b7\u5168\u5c4f\u622a\u56fe\u3002

      fullGetScreenShot(path=None)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u5728\u4e8b\u4ef6\u4e2d\u8fd4\u56de

      \u8fd4\u56de\uff1a \u5305\u542b\u622a\u56fe\u6570\u636e\u7684\u4e8b\u4ef6

      "},{"location":"qsl4a/ui/fullscreen/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b9a\u4e49\u5e03\u5c40\nlayout = '''\n{ \"type\": \"LinearLayout\", \"orientation\": \"vertical\",\n  \"children\": [\n    { \"type\": \"TextView\", \"id\": \"title\", \"text\": \"Hello\" },\n    { \"type\": \"Button\", \"id\": \"btn\", \"text\": \"Click Me\" }\n  ]\n}\n'''\n\n# \u663e\u793a\u5e03\u5c40\ndroid.fullShow(layout, \"My App\")\n\n# \u67e5\u8be2\u6309\u94ae\u70b9\u51fb\nevent = droid.eventWaitFor('click', timeout=10)\nif event.result:\n    widget_id = event.result['data']['id']\n    if widget_id == 'btn':\n        print(\"Button clicked!\")\n\ndroid.fullDismiss()\n
      "}]} \ No newline at end of file From cc96e33a31bc3404404b7020b64352b9ddfbe500 Mon Sep 17 00:00:00 2001 From: "River@devbox" Date: Sun, 29 Mar 2026 22:05:58 +0800 Subject: [PATCH 27/32] Deploy site - 2026-03-29 22:05:58 --- en/404.html | 46 ++++++++ en/AIPyApp/index.html | 46 ++++++++ en/GraphicalInterface/index.html | 46 ++++++++ en/Notebook/index.html | 46 ++++++++ en/Ollama/index.html | 46 ++++++++ en/Terminal/index.html | 46 ++++++++ en/community/index.html | 46 ++++++++ en/editor-guide/index.html | 46 ++++++++ en/external-api/index.html | 46 ++++++++ en/getting-started/index.html | 46 ++++++++ en/index.html | 46 ++++++++ en/qpypi-guide/index.html | 46 ++++++++ en/qpython-x/index.html | 46 ++++++++ en/qsl4a/connectivity/contacts/index.html | 46 ++++++++ en/qsl4a/connectivity/ftp/index.html | 46 ++++++++ en/qsl4a/connectivity/location/index.html | 46 ++++++++ en/qsl4a/connectivity/phone/index.html | 46 ++++++++ .../connectivity/signalstrength/index.html | 46 ++++++++ en/qsl4a/connectivity/sms/index.html | 46 ++++++++ en/qsl4a/connectivity/wifi/index.html | 46 ++++++++ en/qsl4a/core/android-base/index.html | 46 ++++++++ en/qsl4a/core/events/index.html | 46 ++++++++ en/qsl4a/core/intent/index.html | 46 ++++++++ en/qsl4a/hardware/bluetooth/index.html | 46 ++++++++ en/qsl4a/hardware/camera/index.html | 46 ++++++++ en/qsl4a/hardware/recorder/index.html | 46 ++++++++ en/qsl4a/hardware/usbserial/index.html | 46 ++++++++ en/qsl4a/hardware/webcam/index.html | 46 ++++++++ en/qsl4a/index.html | 46 ++++++++ en/qsl4a/media/image/index.html | 46 ++++++++ en/qsl4a/media/mediaplayer/index.html | 46 ++++++++ en/qsl4a/special/cipher/index.html | 46 ++++++++ en/qsl4a/special/pgptai/index.html | 46 ++++++++ en/qsl4a/storage/clipboard/index.html | 46 ++++++++ en/qsl4a/storage/documentfile/index.html | 46 ++++++++ en/qsl4a/storage/preferences/index.html | 46 ++++++++ en/qsl4a/system/activityresult/index.html | 46 ++++++++ en/qsl4a/system/application/index.html | 46 ++++++++ en/qsl4a/system/battery/index.html | 46 ++++++++ en/qsl4a/system/qpyinterface/index.html | 46 ++++++++ en/qsl4a/system/sensors/index.html | 46 ++++++++ en/qsl4a/system/settings/index.html | 46 ++++++++ en/qsl4a/system/sysinfo/index.html | 46 ++++++++ en/qsl4a/system/wakelock/index.html | 46 ++++++++ en/qsl4a/ui/accessibility/index.html | 46 ++++++++ en/qsl4a/ui/dialogs/index.html | 46 ++++++++ en/qsl4a/ui/floatview/index.html | 46 ++++++++ en/qsl4a/ui/fullscreen/index.html | 46 ++++++++ en/sitemap.xml | 98 +++++++++--------- en/sitemap.xml.gz | Bin 608 -> 608 bytes en/tutorial-hello-world/index.html | 46 ++++++++ en/whats-new/index.html | 46 ++++++++ zh/404.html | 46 ++++++++ zh/AIPyApp/index.html | 46 ++++++++ zh/GraphicalInterface/index.html | 46 ++++++++ zh/Notebook/index.html | 46 ++++++++ zh/Ollama/index.html | 46 ++++++++ zh/Terminal/index.html | 46 ++++++++ zh/community/index.html | 46 ++++++++ zh/editor-guide/index.html | 46 ++++++++ zh/external-api/index.html | 46 ++++++++ zh/getting-started/index.html | 46 ++++++++ zh/index.html | 46 ++++++++ zh/qpypi-guide/index.html | 46 ++++++++ zh/qpython-x/index.html | 46 ++++++++ zh/qsl4a/connectivity/contacts/index.html | 46 ++++++++ zh/qsl4a/connectivity/ftp/index.html | 46 ++++++++ zh/qsl4a/connectivity/location/index.html | 46 ++++++++ zh/qsl4a/connectivity/phone/index.html | 46 ++++++++ .../connectivity/signalstrength/index.html | 46 ++++++++ zh/qsl4a/connectivity/sms/index.html | 46 ++++++++ zh/qsl4a/connectivity/wifi/index.html | 46 ++++++++ zh/qsl4a/core/android-base/index.html | 46 ++++++++ zh/qsl4a/core/events/index.html | 46 ++++++++ zh/qsl4a/core/intent/index.html | 46 ++++++++ zh/qsl4a/hardware/bluetooth/index.html | 46 ++++++++ zh/qsl4a/hardware/camera/index.html | 46 ++++++++ zh/qsl4a/hardware/recorder/index.html | 46 ++++++++ zh/qsl4a/hardware/usbserial/index.html | 46 ++++++++ zh/qsl4a/hardware/webcam/index.html | 46 ++++++++ zh/qsl4a/index.html | 46 ++++++++ zh/qsl4a/media/image/index.html | 46 ++++++++ zh/qsl4a/media/mediaplayer/index.html | 46 ++++++++ zh/qsl4a/special/cipher/index.html | 46 ++++++++ zh/qsl4a/special/pgptai/index.html | 46 ++++++++ zh/qsl4a/storage/clipboard/index.html | 46 ++++++++ zh/qsl4a/storage/documentfile/index.html | 46 ++++++++ zh/qsl4a/storage/preferences/index.html | 46 ++++++++ zh/qsl4a/system/activityresult/index.html | 46 ++++++++ zh/qsl4a/system/application/index.html | 46 ++++++++ zh/qsl4a/system/battery/index.html | 46 ++++++++ zh/qsl4a/system/qpyinterface/index.html | 46 ++++++++ zh/qsl4a/system/sensors/index.html | 46 ++++++++ zh/qsl4a/system/settings/index.html | 46 ++++++++ zh/qsl4a/system/sysinfo/index.html | 46 ++++++++ zh/qsl4a/system/wakelock/index.html | 46 ++++++++ zh/qsl4a/ui/accessibility/index.html | 46 ++++++++ zh/qsl4a/ui/dialogs/index.html | 46 ++++++++ zh/qsl4a/ui/floatview/index.html | 46 ++++++++ zh/qsl4a/ui/fullscreen/index.html | 46 ++++++++ zh/sitemap.xml | 98 +++++++++--------- zh/sitemap.xml.gz | Bin 609 -> 610 bytes zh/tutorial-hello-world/index.html | 46 ++++++++ zh/whats-new/index.html | 46 ++++++++ 104 files changed, 4698 insertions(+), 98 deletions(-) diff --git a/en/404.html b/en/404.html index 1a1ef61..7d634d6 100644 --- a/en/404.html +++ b/en/404.html @@ -307,6 +307,25 @@ + + + + + +
    402. + + + + + + + Courses + + +
    403. + + + @@ -2204,6 +2223,33 @@ + + + + + + +
    404. + + + + + + + + Courses + + + + + + + + +
    405. + + + diff --git a/en/AIPyApp/index.html b/en/AIPyApp/index.html index e1c3c9f..646719d 100644 --- a/en/AIPyApp/index.html +++ b/en/AIPyApp/index.html @@ -320,6 +320,25 @@ + + + + + +
    406. + + + + + + + Courses + + +
    407. + + + @@ -2406,6 +2425,33 @@ + + + + + + +
    408. + + + + + + + + Courses + + + + + + + + +
    409. + + + diff --git a/en/GraphicalInterface/index.html b/en/GraphicalInterface/index.html index 1eb8a3a..5c99467 100644 --- a/en/GraphicalInterface/index.html +++ b/en/GraphicalInterface/index.html @@ -320,6 +320,25 @@ + + + + + +
    410. + + + + + + + Courses + + +
    411. + + + @@ -2394,6 +2413,33 @@ + + + + + + +
    412. + + + + + + + + Courses + + + + + + + + +
    413. + + + diff --git a/en/Notebook/index.html b/en/Notebook/index.html index f239813..7515c87 100644 --- a/en/Notebook/index.html +++ b/en/Notebook/index.html @@ -320,6 +320,25 @@ + + + + + +
    414. + + + + + + + Courses + + +
    415. + + + @@ -2322,6 +2341,33 @@ + + + + + + +
    416. + + + + + + + + Courses + + + + + + + + +
    417. + + + diff --git a/en/Ollama/index.html b/en/Ollama/index.html index b235fb2..925c90d 100644 --- a/en/Ollama/index.html +++ b/en/Ollama/index.html @@ -320,6 +320,25 @@ + + + + + +
    418. + + + + + + + Courses + + +
    419. + + + @@ -2411,6 +2430,33 @@ + + + + + + +
    420. + + + + + + + + Courses + + + + + + + + +
    421. + + + diff --git a/en/Terminal/index.html b/en/Terminal/index.html index 4c43149..aefcb96 100644 --- a/en/Terminal/index.html +++ b/en/Terminal/index.html @@ -320,6 +320,25 @@ + + + + + +
    422. + + + + + + + Courses + + +
    423. + + + @@ -2467,6 +2486,33 @@ + + + + + + +
    424. + + + + + + + + Courses + + + + + + + + +
    425. + + + diff --git a/en/community/index.html b/en/community/index.html index e694edc..a85deb7 100644 --- a/en/community/index.html +++ b/en/community/index.html @@ -318,6 +318,25 @@ + + + + + +
    426. + + + + + + + Courses + + +
    427. + + + @@ -2343,6 +2362,33 @@ + + + + + + +
    428. + + + + + + + + Courses + + + + + + + + +
    429. + + + diff --git a/en/editor-guide/index.html b/en/editor-guide/index.html index cdc05ce..4bfafe5 100644 --- a/en/editor-guide/index.html +++ b/en/editor-guide/index.html @@ -320,6 +320,25 @@ + + + + + +
    430. + + + + + + + Courses + + +
    431. + + + @@ -2300,6 +2319,33 @@ + + + + + + +
    432. + + + + + + + + Courses + + + + + + + + +
    433. + + + diff --git a/en/external-api/index.html b/en/external-api/index.html index 51db354..e68e5bb 100644 --- a/en/external-api/index.html +++ b/en/external-api/index.html @@ -320,6 +320,25 @@ + + + + + +
    434. + + + + + + + Courses + + +
    435. + + + @@ -2289,6 +2308,33 @@ + + + + + + +
    436. + + + + + + + + Courses + + + + + + + + +
    437. + + + diff --git a/en/getting-started/index.html b/en/getting-started/index.html index 0ff2d58..bf8a083 100644 --- a/en/getting-started/index.html +++ b/en/getting-started/index.html @@ -320,6 +320,25 @@ + + + + + +
    438. + + + + + + + Courses + + +
    439. + + + @@ -2545,6 +2564,33 @@ + + + + + + +
    440. + + + + + + + + Courses + + + + + + + + +
    441. + + + diff --git a/en/index.html b/en/index.html index e9c9d2a..8a984a6 100644 --- a/en/index.html +++ b/en/index.html @@ -318,6 +318,25 @@ + + + + + +
    442. + + + + + + + Courses + + +
    443. + + + @@ -2331,6 +2350,33 @@ + + + + + + +
    444. + + + + + + + + Courses + + + + + + + + +
    445. + + + diff --git a/en/qpypi-guide/index.html b/en/qpypi-guide/index.html index 1f3396d..ccb4372 100644 --- a/en/qpypi-guide/index.html +++ b/en/qpypi-guide/index.html @@ -320,6 +320,25 @@ + + + + + +
    446. + + + + + + + Courses + + +
    447. + + + @@ -2328,6 +2347,33 @@ + + + + + + +
    448. + + + + + + + + Courses + + + + + + + + +
    449. + + + diff --git a/en/qpython-x/index.html b/en/qpython-x/index.html index 7603134..47e6e75 100644 --- a/en/qpython-x/index.html +++ b/en/qpython-x/index.html @@ -320,6 +320,25 @@ + + + + + +
    450. + + + + + + + Courses + + +
    451. + + + @@ -2300,6 +2319,33 @@ + + + + + + +
    452. + + + + + + + + Courses + + + + + + + + +
    453. + + + diff --git a/en/qsl4a/connectivity/contacts/index.html b/en/qsl4a/connectivity/contacts/index.html index fde3597..a2425f6 100644 --- a/en/qsl4a/connectivity/contacts/index.html +++ b/en/qsl4a/connectivity/contacts/index.html @@ -314,6 +314,25 @@ + + + + + +
    454. + + + + + + + Courses + + +
    455. + + + @@ -2211,6 +2230,33 @@ + + + + + + +
    456. + + + + + + + + Courses + + + + + + + + +
    457. + + + diff --git a/en/qsl4a/connectivity/ftp/index.html b/en/qsl4a/connectivity/ftp/index.html index 9c2ab10..6f4cbd4 100644 --- a/en/qsl4a/connectivity/ftp/index.html +++ b/en/qsl4a/connectivity/ftp/index.html @@ -314,6 +314,25 @@ + + + + + +
    458. + + + + + + + Courses + + +
    459. + + + @@ -2211,6 +2230,33 @@ + + + + + + +
    460. + + + + + + + + Courses + + + + + + + + +
    461. + + + diff --git a/en/qsl4a/connectivity/location/index.html b/en/qsl4a/connectivity/location/index.html index a8ee320..f1548fe 100644 --- a/en/qsl4a/connectivity/location/index.html +++ b/en/qsl4a/connectivity/location/index.html @@ -320,6 +320,25 @@ + + + + + +
    462. + + + + + + + Courses + + +
    463. + + + @@ -2424,6 +2443,33 @@ + + + + + + +
    464. + + + + + + + + Courses + + + + + + + + +
    465. + + + diff --git a/en/qsl4a/connectivity/phone/index.html b/en/qsl4a/connectivity/phone/index.html index 3c1c49b..df184f9 100644 --- a/en/qsl4a/connectivity/phone/index.html +++ b/en/qsl4a/connectivity/phone/index.html @@ -314,6 +314,25 @@ + + + + + +
    466. + + + + + + + Courses + + +
    467. + + + @@ -2211,6 +2230,33 @@ + + + + + + +
    468. + + + + + + + + Courses + + + + + + + + +
    469. + + + diff --git a/en/qsl4a/connectivity/signalstrength/index.html b/en/qsl4a/connectivity/signalstrength/index.html index d20cc41..f43cb19 100644 --- a/en/qsl4a/connectivity/signalstrength/index.html +++ b/en/qsl4a/connectivity/signalstrength/index.html @@ -314,6 +314,25 @@ + + + + + +
    470. + + + + + + + Courses + + +
    471. + + + @@ -2211,6 +2230,33 @@ + + + + + + +
    472. + + + + + + + + Courses + + + + + + + + +
    473. + + + diff --git a/en/qsl4a/connectivity/sms/index.html b/en/qsl4a/connectivity/sms/index.html index 1b0fc70..092be10 100644 --- a/en/qsl4a/connectivity/sms/index.html +++ b/en/qsl4a/connectivity/sms/index.html @@ -320,6 +320,25 @@ + + + + + +
    474. + + + + + + + Courses + + +
    475. + + + @@ -2407,6 +2426,33 @@ + + + + + + +
    476. + + + + + + + + Courses + + + + + + + + +
    477. + + + diff --git a/en/qsl4a/connectivity/wifi/index.html b/en/qsl4a/connectivity/wifi/index.html index 1d52229..6f8666a 100644 --- a/en/qsl4a/connectivity/wifi/index.html +++ b/en/qsl4a/connectivity/wifi/index.html @@ -320,6 +320,25 @@ + + + + + +
    478. + + + + + + + Courses + + +
    479. + + + @@ -2524,6 +2543,33 @@ + + + + + + +
    480. + + + + + + + + Courses + + + + + + + + +
    481. + + + diff --git a/en/qsl4a/core/android-base/index.html b/en/qsl4a/core/android-base/index.html index fbc979d..967295a 100644 --- a/en/qsl4a/core/android-base/index.html +++ b/en/qsl4a/core/android-base/index.html @@ -320,6 +320,25 @@ + + + + + +
    482. + + + + + + + Courses + + +
    483. + + + @@ -2480,6 +2499,33 @@ + + + + + + +
    484. + + + + + + + + Courses + + + + + + + + +
    485. + + + diff --git a/en/qsl4a/core/events/index.html b/en/qsl4a/core/events/index.html index 1fd0c97..647571f 100644 --- a/en/qsl4a/core/events/index.html +++ b/en/qsl4a/core/events/index.html @@ -320,6 +320,25 @@ + + + + + +
    486. + + + + + + + Courses + + +
    487. + + + @@ -2607,6 +2626,33 @@ + + + + + + +
    488. + + + + + + + + Courses + + + + + + + + +
    489. + + + diff --git a/en/qsl4a/core/intent/index.html b/en/qsl4a/core/intent/index.html index 3ec331e..9b29607 100644 --- a/en/qsl4a/core/intent/index.html +++ b/en/qsl4a/core/intent/index.html @@ -320,6 +320,25 @@ + + + + + +
    490. + + + + + + + Courses + + +
    491. + + + @@ -2700,6 +2719,33 @@ + + + + + + +
    492. + + + + + + + + Courses + + + + + + + + +
    493. + + + diff --git a/en/qsl4a/hardware/bluetooth/index.html b/en/qsl4a/hardware/bluetooth/index.html index 8324b41..8be029d 100644 --- a/en/qsl4a/hardware/bluetooth/index.html +++ b/en/qsl4a/hardware/bluetooth/index.html @@ -320,6 +320,25 @@ + + + + + +
    494. + + + + + + + Courses + + +
    495. + + + @@ -2590,6 +2609,33 @@ + + + + + + +
    496. + + + + + + + + Courses + + + + + + + + +
    497. + + + diff --git a/en/qsl4a/hardware/camera/index.html b/en/qsl4a/hardware/camera/index.html index 50b5e69..97f2b25 100644 --- a/en/qsl4a/hardware/camera/index.html +++ b/en/qsl4a/hardware/camera/index.html @@ -320,6 +320,25 @@ + + + + + +
    498. + + + + + + + Courses + + +
    499. + + + @@ -2513,6 +2532,33 @@ + + + + + + +
    500. + + + + + + + + Courses + + + + + + + + +
    501. + + + diff --git a/en/qsl4a/hardware/recorder/index.html b/en/qsl4a/hardware/recorder/index.html index 3456e4c..090a444 100644 --- a/en/qsl4a/hardware/recorder/index.html +++ b/en/qsl4a/hardware/recorder/index.html @@ -320,6 +320,25 @@ + + + + + +
    502. + + + + + + + Courses + + +
    503. + + + @@ -2441,6 +2460,33 @@ + + + + + + +
    504. + + + + + + + + Courses + + + + + + + + +
    505. + + + diff --git a/en/qsl4a/hardware/usbserial/index.html b/en/qsl4a/hardware/usbserial/index.html index 2ed95ac..88a23df 100644 --- a/en/qsl4a/hardware/usbserial/index.html +++ b/en/qsl4a/hardware/usbserial/index.html @@ -314,6 +314,25 @@ + + + + + +
    506. + + + + + + + Courses + + +
    507. + + + @@ -2211,6 +2230,33 @@ + + + + + + +
    508. + + + + + + + + Courses + + + + + + + + +
    509. + + + diff --git a/en/qsl4a/hardware/webcam/index.html b/en/qsl4a/hardware/webcam/index.html index 8782f38..8847f26 100644 --- a/en/qsl4a/hardware/webcam/index.html +++ b/en/qsl4a/hardware/webcam/index.html @@ -314,6 +314,25 @@ + + + + + +
    510. + + + + + + + Courses + + +
    511. + + + @@ -2211,6 +2230,33 @@ + + + + + + +
    512. + + + + + + + + Courses + + + + + + + + +
    513. + + + diff --git a/en/qsl4a/index.html b/en/qsl4a/index.html index 065c0d5..8aa0e94 100644 --- a/en/qsl4a/index.html +++ b/en/qsl4a/index.html @@ -320,6 +320,25 @@ + + + + + +
    514. + + + + + + + Courses + + +
    515. + + + @@ -2418,6 +2437,33 @@ + + + + + + +
    516. + + + + + + + + Courses + + + + + + + + +
    517. + + + diff --git a/en/qsl4a/media/image/index.html b/en/qsl4a/media/image/index.html index ee03082..af87e33 100644 --- a/en/qsl4a/media/image/index.html +++ b/en/qsl4a/media/image/index.html @@ -320,6 +320,25 @@ + + + + + +
    518. + + + + + + + Courses + + +
    519. + + + @@ -2414,6 +2433,33 @@ + + + + + + +
    520. + + + + + + + + Courses + + + + + + + + +
    521. + + + diff --git a/en/qsl4a/media/mediaplayer/index.html b/en/qsl4a/media/mediaplayer/index.html index 0cb837f..4a6a0bf 100644 --- a/en/qsl4a/media/mediaplayer/index.html +++ b/en/qsl4a/media/mediaplayer/index.html @@ -320,6 +320,25 @@ + + + + + +
    522. + + + + + + + Courses + + +
    523. + + + @@ -2524,6 +2543,33 @@ + + + + + + +
    524. + + + + + + + + Courses + + + + + + + + +
    525. + + + diff --git a/en/qsl4a/special/cipher/index.html b/en/qsl4a/special/cipher/index.html index d5dc97b..1ba012a 100644 --- a/en/qsl4a/special/cipher/index.html +++ b/en/qsl4a/special/cipher/index.html @@ -320,6 +320,25 @@ + + + + + +
    526. + + + + + + + Courses + + +
    527. + + + @@ -2463,6 +2482,33 @@ + + + + + + +
    528. + + + + + + + + Courses + + + + + + + + +
    529. + + + diff --git a/en/qsl4a/special/pgptai/index.html b/en/qsl4a/special/pgptai/index.html index 2cf4eee..2a1f809 100644 --- a/en/qsl4a/special/pgptai/index.html +++ b/en/qsl4a/special/pgptai/index.html @@ -320,6 +320,25 @@ + + + + + +
    530. + + + + + + + Courses + + +
    531. + + + @@ -2391,6 +2410,33 @@ + + + + + + +
    532. + + + + + + + + Courses + + + + + + + + +
    533. + + + diff --git a/en/qsl4a/storage/clipboard/index.html b/en/qsl4a/storage/clipboard/index.html index c9a4247..4219422 100644 --- a/en/qsl4a/storage/clipboard/index.html +++ b/en/qsl4a/storage/clipboard/index.html @@ -320,6 +320,25 @@ + + + + + +
    534. + + + + + + + Courses + + +
    535. + + + @@ -2341,6 +2360,33 @@ + + + + + + +
    536. + + + + + + + + Courses + + + + + + + + +
    537. + + + diff --git a/en/qsl4a/storage/documentfile/index.html b/en/qsl4a/storage/documentfile/index.html index 149788d..d8cb1ef 100644 --- a/en/qsl4a/storage/documentfile/index.html +++ b/en/qsl4a/storage/documentfile/index.html @@ -320,6 +320,25 @@ + + + + + +
    538. + + + + + + + Courses + + +
    539. + + + @@ -2552,6 +2571,33 @@ + + + + + + +
    540. + + + + + + + + Courses + + + + + + + + +
    541. + + + diff --git a/en/qsl4a/storage/preferences/index.html b/en/qsl4a/storage/preferences/index.html index 239c837..6fce135 100644 --- a/en/qsl4a/storage/preferences/index.html +++ b/en/qsl4a/storage/preferences/index.html @@ -314,6 +314,25 @@ + + + + + +
    542. + + + + + + + Courses + + +
    543. + + + @@ -2211,6 +2230,33 @@ + + + + + + +
    544. + + + + + + + + Courses + + + + + + + + +
    545. + + + diff --git a/en/qsl4a/system/activityresult/index.html b/en/qsl4a/system/activityresult/index.html index 97e56d2..86b46e0 100644 --- a/en/qsl4a/system/activityresult/index.html +++ b/en/qsl4a/system/activityresult/index.html @@ -314,6 +314,25 @@ + + + + + +
    546. + + + + + + + Courses + + +
    547. + + + @@ -2211,6 +2230,33 @@ + + + + + + +
    548. + + + + + + + + Courses + + + + + + + + +
    549. + + + diff --git a/en/qsl4a/system/application/index.html b/en/qsl4a/system/application/index.html index 2df7274..8a9f644 100644 --- a/en/qsl4a/system/application/index.html +++ b/en/qsl4a/system/application/index.html @@ -320,6 +320,25 @@ + + + + + +
    550. + + + + + + + Courses + + +
    551. + + + @@ -2669,6 +2688,33 @@ + + + + + + +
    552. + + + + + + + + Courses + + + + + + + + +
    553. + + + diff --git a/en/qsl4a/system/battery/index.html b/en/qsl4a/system/battery/index.html index 1168b69..2159daf 100644 --- a/en/qsl4a/system/battery/index.html +++ b/en/qsl4a/system/battery/index.html @@ -320,6 +320,25 @@ + + + + + +
    554. + + + + + + + Courses + + +
    555. + + + @@ -2396,6 +2415,33 @@ + + + + + + +
    556. + + + + + + + + Courses + + + + + + + + +
    557. + + + diff --git a/en/qsl4a/system/qpyinterface/index.html b/en/qsl4a/system/qpyinterface/index.html index 5a6c960..c10c310 100644 --- a/en/qsl4a/system/qpyinterface/index.html +++ b/en/qsl4a/system/qpyinterface/index.html @@ -314,6 +314,25 @@ + + + + + +
    558. + + + + + + + Courses + + +
    559. + + + @@ -2211,6 +2230,33 @@ + + + + + + +
    560. + + + + + + + + Courses + + + + + + + + +
    561. + + + diff --git a/en/qsl4a/system/sensors/index.html b/en/qsl4a/system/sensors/index.html index e194d1f..0bf97d9 100644 --- a/en/qsl4a/system/sensors/index.html +++ b/en/qsl4a/system/sensors/index.html @@ -320,6 +320,25 @@ + + + + + +
    562. + + + + + + + Courses + + +
    563. + + + @@ -2440,6 +2459,33 @@ + + + + + + +
    564. + + + + + + + + Courses + + + + + + + + +
    565. + + + diff --git a/en/qsl4a/system/settings/index.html b/en/qsl4a/system/settings/index.html index a4c0f66..df61039 100644 --- a/en/qsl4a/system/settings/index.html +++ b/en/qsl4a/system/settings/index.html @@ -314,6 +314,25 @@ + + + + + +
    566. + + + + + + + Courses + + +
    567. + + + @@ -2211,6 +2230,33 @@ + + + + + + +
    568. + + + + + + + + Courses + + + + + + + + +
    569. + + + diff --git a/en/qsl4a/system/sysinfo/index.html b/en/qsl4a/system/sysinfo/index.html index b85e770..a459168 100644 --- a/en/qsl4a/system/sysinfo/index.html +++ b/en/qsl4a/system/sysinfo/index.html @@ -320,6 +320,25 @@ + + + + + +
    570. + + + + + + + Courses + + +
    571. + + + @@ -2447,6 +2466,33 @@ + + + + + + +
    572. + + + + + + + + Courses + + + + + + + + +
    573. + + + diff --git a/en/qsl4a/system/wakelock/index.html b/en/qsl4a/system/wakelock/index.html index 606de8f..88a6640 100644 --- a/en/qsl4a/system/wakelock/index.html +++ b/en/qsl4a/system/wakelock/index.html @@ -314,6 +314,25 @@ + + + + + +
    574. + + + + + + + Courses + + +
    575. + + + @@ -2211,6 +2230,33 @@ + + + + + + +
    576. + + + + + + + + Courses + + + + + + + + +
    577. + + + diff --git a/en/qsl4a/ui/accessibility/index.html b/en/qsl4a/ui/accessibility/index.html index 6dd7f7f..e9dea0d 100644 --- a/en/qsl4a/ui/accessibility/index.html +++ b/en/qsl4a/ui/accessibility/index.html @@ -320,6 +320,25 @@ + + + + + +
    578. + + + + + + + Courses + + +
    579. + + + @@ -2458,6 +2477,33 @@ + + + + + + +
    580. + + + + + + + + Courses + + + + + + + + +
    581. + + + diff --git a/en/qsl4a/ui/dialogs/index.html b/en/qsl4a/ui/dialogs/index.html index dcfa05e..cb3ee52 100644 --- a/en/qsl4a/ui/dialogs/index.html +++ b/en/qsl4a/ui/dialogs/index.html @@ -320,6 +320,25 @@ + + + + + +
    582. + + + + + + + Courses + + +
    583. + + + @@ -2790,6 +2809,33 @@ + + + + + + +
    584. + + + + + + + + Courses + + + + + + + + +
    585. + + + diff --git a/en/qsl4a/ui/floatview/index.html b/en/qsl4a/ui/floatview/index.html index 8fa7657..100956b 100644 --- a/en/qsl4a/ui/floatview/index.html +++ b/en/qsl4a/ui/floatview/index.html @@ -320,6 +320,25 @@ + + + + + +
    586. + + + + + + + Courses + + +
    587. + + + @@ -2435,6 +2454,33 @@ + + + + + + +
    588. + + + + + + + + Courses + + + + + + + + +
    589. + + + diff --git a/en/qsl4a/ui/fullscreen/index.html b/en/qsl4a/ui/fullscreen/index.html index 008b2b9..910c9f4 100644 --- a/en/qsl4a/ui/fullscreen/index.html +++ b/en/qsl4a/ui/fullscreen/index.html @@ -320,6 +320,25 @@ + + + + + +
    590. + + + + + + + Courses + + +
    591. + + + @@ -2513,6 +2532,33 @@ + + + + + + +
    592. + + + + + + + + Courses + + + + + + + + +
    593. + + + diff --git a/en/sitemap.xml b/en/sitemap.xml index 62f5d77..ab960c6 100644 --- a/en/sitemap.xml +++ b/en/sitemap.xml @@ -2,198 +2,198 @@ https://www.qpython.org/en/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/AIPyApp/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/GraphicalInterface/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/Notebook/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/Ollama/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/Terminal/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/community/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/editor-guide/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/external-api/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/getting-started/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/qpypi-guide/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/qpython-x/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/tutorial-hello-world/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/whats-new/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/qsl4a/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/qsl4a/connectivity/contacts/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/qsl4a/connectivity/ftp/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/qsl4a/connectivity/location/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/qsl4a/connectivity/phone/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/qsl4a/connectivity/signalstrength/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/qsl4a/connectivity/sms/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/qsl4a/connectivity/wifi/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/qsl4a/core/android-base/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/qsl4a/core/events/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/qsl4a/core/intent/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/qsl4a/hardware/bluetooth/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/qsl4a/hardware/camera/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/qsl4a/hardware/recorder/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/qsl4a/hardware/usbserial/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/qsl4a/hardware/webcam/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/qsl4a/media/image/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/qsl4a/media/mediaplayer/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/qsl4a/special/cipher/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/qsl4a/special/pgptai/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/qsl4a/storage/clipboard/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/qsl4a/storage/documentfile/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/qsl4a/storage/preferences/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/qsl4a/system/activityresult/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/qsl4a/system/application/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/qsl4a/system/battery/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/qsl4a/system/qpyinterface/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/qsl4a/system/sensors/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/qsl4a/system/settings/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/qsl4a/system/sysinfo/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/qsl4a/system/wakelock/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/qsl4a/ui/accessibility/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/qsl4a/ui/dialogs/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/qsl4a/ui/floatview/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/en/qsl4a/ui/fullscreen/ - 2026-03-27 + 2026-03-29 \ No newline at end of file diff --git a/en/sitemap.xml.gz b/en/sitemap.xml.gz index e4c153af0b1f432d94089ec2309ac6b31d1187d7..c51196a9b3f6673c68e3dc22cbb9c5bbf4a58189 100644 GIT binary patch literal 608 zcmV-m0-yaKiwFpSYshH=|8r?{Wo=<_E_iKh0L7TWZrd;nhVOlfAa}=EHw^2Lr08Ws zFWU~?1JE*U6O|=Rq~rSSN2fut9ftv;4|ZhJ`ag&?#qeNuTR_p64Bt;0TF#G50mQK?hu4Z`S+W-S%{| z(PN$9_1EP%_~=gSEPS2jS6XC<;W7(``cSV1f7%1f7~9kB{`O zE=$JH%V173ng{4i9hop>tRb{HQd>2^XvKhM3`S`})k*8vAO`9KNT=V10>%8%7ytl;d?pkC literal 608 zcmV-m0-yaKiwFpS$i-;_|8r?{Wo=<_E_iKh0L7Tij+;OX$M5?TQSO9vTlGsxR(ol+ zm$rxP1DL^pwe!`n3Cr8pWTRDktSVs+kO4FQpT@@H_;B|e{N{{>DaGUV&2GQlV05Xa z*dMn)AHP%|w|A$T!&p3{Y}7dNaXX0Q&viXb(~e0nK;~U4ea&vr0oT`?^?vthd%D@^ zu}tvt>v9}?a;Ie$zE1Ni&oZQVnFV8gs277j?SUnv_H?_yeP8Y0R<|G2J$ymMPX8Ss$Y{1XHg` zm!)9rWiY1+<^eiUMWb!S% zLO2Lmz>=V#`lH2S$uM%mxD*VQ5EC})4FiIpr8v|Sphq+H%Q<_PO#*>4y2bmB@?Z*( z`z&CwE3g*Ki~pUc+$0T2LxwiFF=%q`$fF@fF4&<~D-JC-DV|v{)Nrj93i9a1kRxYL zX4UK!q5;vr?z0_$J|mO<*IyKjkyBwyfJ-C8l3-?vU9tn1;0e|K$$(%a%?g^7m>TkH uckNygbi4M+Bm`8v^9kfkChe6)e)OJQ!T;&|UoQF~oqhwFG6Sj67ytm(H7`d1 diff --git a/en/tutorial-hello-world/index.html b/en/tutorial-hello-world/index.html index 2b641a8..cc41fc2 100644 --- a/en/tutorial-hello-world/index.html +++ b/en/tutorial-hello-world/index.html @@ -320,6 +320,25 @@ + + + + + +
    594. + + + + + + + Courses + + +
    595. + + + @@ -2322,6 +2341,33 @@ + + + + + + +
    596. + + + + + + + + Courses + + + + + + + + +
    597. + + + diff --git a/en/whats-new/index.html b/en/whats-new/index.html index 5e20179..3f31957 100644 --- a/en/whats-new/index.html +++ b/en/whats-new/index.html @@ -320,6 +320,25 @@ + + + + + +
    598. + + + + + + + Courses + + +
    599. + + + @@ -2454,6 +2473,33 @@ + + + + + + +
    600. + + + + + + + + Courses + + + + + + + + +
    601. + + + diff --git a/zh/404.html b/zh/404.html index 688b274..a218068 100644 --- a/zh/404.html +++ b/zh/404.html @@ -307,6 +307,25 @@ + + + + + +
    602. + + + + + + + 课程 + + +
    603. + + + @@ -2512,6 +2531,33 @@ + + + + + + +
    604. + + + + + + + + 课程 + + + + + + + + +
    605. + + + diff --git a/zh/AIPyApp/index.html b/zh/AIPyApp/index.html index bd61acf..82f31c0 100644 --- a/zh/AIPyApp/index.html +++ b/zh/AIPyApp/index.html @@ -320,6 +320,25 @@ + + + + + +
    606. + + + + + + + 课程 + + +
    607. + + + @@ -2714,6 +2733,33 @@ + + + + + + +
    608. + + + + + + + + 课程 + + + + + + + + +
    609. + + + diff --git a/zh/GraphicalInterface/index.html b/zh/GraphicalInterface/index.html index 48e62bd..e6d50ae 100644 --- a/zh/GraphicalInterface/index.html +++ b/zh/GraphicalInterface/index.html @@ -320,6 +320,25 @@ + + + + + +
    610. + + + + + + + 课程 + + +
    611. + + + @@ -2724,6 +2743,33 @@ + + + + + + +
    612. + + + + + + + + 课程 + + + + + + + + +
    613. + + + diff --git a/zh/Notebook/index.html b/zh/Notebook/index.html index 2e48758..2e50b3b 100644 --- a/zh/Notebook/index.html +++ b/zh/Notebook/index.html @@ -320,6 +320,25 @@ + + + + + +
    614. + + + + + + + 课程 + + +
    615. + + + @@ -2630,6 +2649,33 @@ + + + + + + +
    616. + + + + + + + + 课程 + + + + + + + + +
    617. + + + diff --git a/zh/Ollama/index.html b/zh/Ollama/index.html index 1822f55..a8c14ed 100644 --- a/zh/Ollama/index.html +++ b/zh/Ollama/index.html @@ -320,6 +320,25 @@ + + + + + +
    618. + + + + + + + 课程 + + +
    619. + + + @@ -2719,6 +2738,33 @@ + + + + + + +
    620. + + + + + + + + 课程 + + + + + + + + +
    621. + + + diff --git a/zh/Terminal/index.html b/zh/Terminal/index.html index a7edcb0..221dade 100644 --- a/zh/Terminal/index.html +++ b/zh/Terminal/index.html @@ -320,6 +320,25 @@ + + + + + +
    622. + + + + + + + 课程 + + +
    623. + + + @@ -2775,6 +2794,33 @@ + + + + + + +
    624. + + + + + + + + 课程 + + + + + + + + +
    625. + + + diff --git a/zh/community/index.html b/zh/community/index.html index a4faac9..50f1e9d 100644 --- a/zh/community/index.html +++ b/zh/community/index.html @@ -318,6 +318,25 @@ + + + + + +
    626. + + + + + + + 课程 + + +
    627. + + + @@ -2645,6 +2664,33 @@ + + + + + + +
    628. + + + + + + + + 课程 + + + + + + + + +
    629. + + + diff --git a/zh/editor-guide/index.html b/zh/editor-guide/index.html index 9e3b4a9..a73ecbd 100644 --- a/zh/editor-guide/index.html +++ b/zh/editor-guide/index.html @@ -320,6 +320,25 @@ + + + + + +
    630. + + + + + + + 课程 + + +
    631. + + + @@ -2608,6 +2627,33 @@ + + + + + + +
    632. + + + + + + + + 课程 + + + + + + + + +
    633. + + + diff --git a/zh/external-api/index.html b/zh/external-api/index.html index 8771378..413168b 100644 --- a/zh/external-api/index.html +++ b/zh/external-api/index.html @@ -320,6 +320,25 @@ + + + + + +
    634. + + + + + + + 课程 + + +
    635. + + + @@ -2597,6 +2616,33 @@ + + + + + + +
    636. + + + + + + + + 课程 + + + + + + + + +
    637. + + + diff --git a/zh/getting-started/index.html b/zh/getting-started/index.html index a8b0f16..ca26f63 100644 --- a/zh/getting-started/index.html +++ b/zh/getting-started/index.html @@ -320,6 +320,25 @@ + + + + + +
    638. + + + + + + + 课程 + + +
    639. + + + @@ -2853,6 +2872,33 @@ + + + + + + +
    640. + + + + + + + + 课程 + + + + + + + + +
    641. + + + diff --git a/zh/index.html b/zh/index.html index fb9540c..550882c 100644 --- a/zh/index.html +++ b/zh/index.html @@ -318,6 +318,25 @@ + + + + + +
    642. + + + + + + + 课程 + + +
    643. + + + @@ -2639,6 +2658,33 @@ + + + + + + +
    644. + + + + + + + + 课程 + + + + + + + + +
    645. + + + diff --git a/zh/qpypi-guide/index.html b/zh/qpypi-guide/index.html index 9c79c13..2e0454e 100644 --- a/zh/qpypi-guide/index.html +++ b/zh/qpypi-guide/index.html @@ -320,6 +320,25 @@ + + + + + +
    646. + + + + + + + 课程 + + +
    647. + + + @@ -2636,6 +2655,33 @@ + + + + + + +
    648. + + + + + + + + 课程 + + + + + + + + +
    649. + + + diff --git a/zh/qpython-x/index.html b/zh/qpython-x/index.html index f247895..676b86c 100644 --- a/zh/qpython-x/index.html +++ b/zh/qpython-x/index.html @@ -320,6 +320,25 @@ + + + + + +
    650. + + + + + + + 课程 + + +
    651. + + + @@ -2608,6 +2627,33 @@ + + + + + + +
    652. + + + + + + + + 课程 + + + + + + + + +
    653. + + + diff --git a/zh/qsl4a/connectivity/contacts/index.html b/zh/qsl4a/connectivity/contacts/index.html index 28e1425..51b617a 100644 --- a/zh/qsl4a/connectivity/contacts/index.html +++ b/zh/qsl4a/connectivity/contacts/index.html @@ -320,6 +320,25 @@ + + + + + +
    654. + + + + + + + 课程 + + +
    655. + + + @@ -2760,6 +2779,33 @@ + + + + + + +
    656. + + + + + + + + 课程 + + + + + + + + +
    657. + + + diff --git a/zh/qsl4a/connectivity/ftp/index.html b/zh/qsl4a/connectivity/ftp/index.html index 48ae137..0b85a44 100644 --- a/zh/qsl4a/connectivity/ftp/index.html +++ b/zh/qsl4a/connectivity/ftp/index.html @@ -320,6 +320,25 @@ + + + + + +
    658. + + + + + + + 课程 + + +
    659. + + + @@ -2693,6 +2712,33 @@ + + + + + + +
    660. + + + + + + + + 课程 + + + + + + + + +
    661. + + + diff --git a/zh/qsl4a/connectivity/location/index.html b/zh/qsl4a/connectivity/location/index.html index 674407d..5a291d8 100644 --- a/zh/qsl4a/connectivity/location/index.html +++ b/zh/qsl4a/connectivity/location/index.html @@ -320,6 +320,25 @@ + + + + + +
    662. + + + + + + + 课程 + + +
    663. + + + @@ -2732,6 +2751,33 @@ + + + + + + +
    664. + + + + + + + + 课程 + + + + + + + + +
    665. + + + diff --git a/zh/qsl4a/connectivity/phone/index.html b/zh/qsl4a/connectivity/phone/index.html index 4b28ad9..4b8ad9f 100644 --- a/zh/qsl4a/connectivity/phone/index.html +++ b/zh/qsl4a/connectivity/phone/index.html @@ -320,6 +320,25 @@ + + + + + +
    666. + + + + + + + 课程 + + +
    667. + + + @@ -3043,6 +3062,33 @@ + + + + + + +
    668. + + + + + + + + 课程 + + + + + + + + +
    669. + + + diff --git a/zh/qsl4a/connectivity/signalstrength/index.html b/zh/qsl4a/connectivity/signalstrength/index.html index aa6b617..9c328a2 100644 --- a/zh/qsl4a/connectivity/signalstrength/index.html +++ b/zh/qsl4a/connectivity/signalstrength/index.html @@ -320,6 +320,25 @@ + + + + + +
    670. + + + + + + + 课程 + + +
    671. + + + @@ -2682,6 +2701,33 @@ + + + + + + +
    672. + + + + + + + + 课程 + + + + + + + + +
    673. + + + diff --git a/zh/qsl4a/connectivity/sms/index.html b/zh/qsl4a/connectivity/sms/index.html index 8926818..bb11a6c 100644 --- a/zh/qsl4a/connectivity/sms/index.html +++ b/zh/qsl4a/connectivity/sms/index.html @@ -320,6 +320,25 @@ + + + + + +
    674. + + + + + + + 课程 + + +
    675. + + + @@ -2715,6 +2734,33 @@ + + + + + + +
    676. + + + + + + + + 课程 + + + + + + + + +
    677. + + + diff --git a/zh/qsl4a/connectivity/wifi/index.html b/zh/qsl4a/connectivity/wifi/index.html index 4effc27..059a98d 100644 --- a/zh/qsl4a/connectivity/wifi/index.html +++ b/zh/qsl4a/connectivity/wifi/index.html @@ -320,6 +320,25 @@ + + + + + +
    678. + + + + + + + 课程 + + +
    679. + + + @@ -2832,6 +2851,33 @@ + + + + + + +
    680. + + + + + + + + 课程 + + + + + + + + +
    681. + + + diff --git a/zh/qsl4a/core/android-base/index.html b/zh/qsl4a/core/android-base/index.html index 675398d..3b4159a 100644 --- a/zh/qsl4a/core/android-base/index.html +++ b/zh/qsl4a/core/android-base/index.html @@ -320,6 +320,25 @@ + + + + + +
    682. + + + + + + + 课程 + + +
    683. + + + @@ -2788,6 +2807,33 @@ + + + + + + +
    684. + + + + + + + + 课程 + + + + + + + + +
    685. + + + diff --git a/zh/qsl4a/core/events/index.html b/zh/qsl4a/core/events/index.html index 62c3c02..0276e2d 100644 --- a/zh/qsl4a/core/events/index.html +++ b/zh/qsl4a/core/events/index.html @@ -320,6 +320,25 @@ + + + + + +
    686. + + + + + + + 课程 + + +
    687. + + + @@ -2915,6 +2934,33 @@ + + + + + + +
    688. + + + + + + + + 课程 + + + + + + + + +
    689. + + + diff --git a/zh/qsl4a/core/intent/index.html b/zh/qsl4a/core/intent/index.html index 76f4f29..5529285 100644 --- a/zh/qsl4a/core/intent/index.html +++ b/zh/qsl4a/core/intent/index.html @@ -320,6 +320,25 @@ + + + + + +
    690. + + + + + + + 课程 + + +
    691. + + + @@ -3008,6 +3027,33 @@ + + + + + + +
    692. + + + + + + + + 课程 + + + + + + + + +
    693. + + + diff --git a/zh/qsl4a/hardware/bluetooth/index.html b/zh/qsl4a/hardware/bluetooth/index.html index 0a7d78e..083f899 100644 --- a/zh/qsl4a/hardware/bluetooth/index.html +++ b/zh/qsl4a/hardware/bluetooth/index.html @@ -320,6 +320,25 @@ + + + + + +
    694. + + + + + + + 课程 + + +
    695. + + + @@ -2898,6 +2917,33 @@ + + + + + + +
    696. + + + + + + + + 课程 + + + + + + + + +
    697. + + + diff --git a/zh/qsl4a/hardware/camera/index.html b/zh/qsl4a/hardware/camera/index.html index 79fe733..ee45883 100644 --- a/zh/qsl4a/hardware/camera/index.html +++ b/zh/qsl4a/hardware/camera/index.html @@ -320,6 +320,25 @@ + + + + + +
    698. + + + + + + + 课程 + + +
    699. + + + @@ -2821,6 +2840,33 @@ + + + + + + +
    700. + + + + + + + + 课程 + + + + + + + + +
    701. + + + diff --git a/zh/qsl4a/hardware/recorder/index.html b/zh/qsl4a/hardware/recorder/index.html index cd3ffb6..5be2c28 100644 --- a/zh/qsl4a/hardware/recorder/index.html +++ b/zh/qsl4a/hardware/recorder/index.html @@ -320,6 +320,25 @@ + + + + + +
    702. + + + + + + + 课程 + + +
    703. + + + @@ -2749,6 +2768,33 @@ + + + + + + +
    704. + + + + + + + + 课程 + + + + + + + + +
    705. + + + diff --git a/zh/qsl4a/hardware/usbserial/index.html b/zh/qsl4a/hardware/usbserial/index.html index b48a7d1..4d83ee8 100644 --- a/zh/qsl4a/hardware/usbserial/index.html +++ b/zh/qsl4a/hardware/usbserial/index.html @@ -320,6 +320,25 @@ + + + + + +
    706. + + + + + + + 课程 + + +
    707. + + + @@ -2776,6 +2795,33 @@ + + + + + + +
    708. + + + + + + + + 课程 + + + + + + + + +
    709. + + + diff --git a/zh/qsl4a/hardware/webcam/index.html b/zh/qsl4a/hardware/webcam/index.html index 0fb8423..468abc6 100644 --- a/zh/qsl4a/hardware/webcam/index.html +++ b/zh/qsl4a/hardware/webcam/index.html @@ -320,6 +320,25 @@ + + + + + +
    710. + + + + + + + 课程 + + +
    711. + + + @@ -2699,6 +2718,33 @@ + + + + + + +
    712. + + + + + + + + 课程 + + + + + + + + +
    713. + + + diff --git a/zh/qsl4a/index.html b/zh/qsl4a/index.html index d0ba64b..11de42b 100644 --- a/zh/qsl4a/index.html +++ b/zh/qsl4a/index.html @@ -320,6 +320,25 @@ + + + + + +
    714. + + + + + + + 课程 + + +
    715. + + + @@ -2726,6 +2745,33 @@ + + + + + + +
    716. + + + + + + + + 课程 + + + + + + + + +
    717. + + + diff --git a/zh/qsl4a/media/image/index.html b/zh/qsl4a/media/image/index.html index a49b9f9..b0ddef7 100644 --- a/zh/qsl4a/media/image/index.html +++ b/zh/qsl4a/media/image/index.html @@ -320,6 +320,25 @@ + + + + + +
    718. + + + + + + + 课程 + + +
    719. + + + @@ -2722,6 +2741,33 @@ + + + + + + +
    720. + + + + + + + + 课程 + + + + + + + + +
    721. + + + diff --git a/zh/qsl4a/media/mediaplayer/index.html b/zh/qsl4a/media/mediaplayer/index.html index 06d6379..838404e 100644 --- a/zh/qsl4a/media/mediaplayer/index.html +++ b/zh/qsl4a/media/mediaplayer/index.html @@ -320,6 +320,25 @@ + + + + + +
    722. + + + + + + + 课程 + + +
    723. + + + @@ -2832,6 +2851,33 @@ + + + + + + +
    724. + + + + + + + + 课程 + + + + + + + + +
    725. + + + diff --git a/zh/qsl4a/special/cipher/index.html b/zh/qsl4a/special/cipher/index.html index 3749c05..4bda4e9 100644 --- a/zh/qsl4a/special/cipher/index.html +++ b/zh/qsl4a/special/cipher/index.html @@ -320,6 +320,25 @@ + + + + + +
    726. + + + + + + + 课程 + + +
    727. + + + @@ -2771,6 +2790,33 @@ + + + + + + +
    728. + + + + + + + + 课程 + + + + + + + + +
    729. + + + diff --git a/zh/qsl4a/special/pgptai/index.html b/zh/qsl4a/special/pgptai/index.html index a6a47e9..ab9d129 100644 --- a/zh/qsl4a/special/pgptai/index.html +++ b/zh/qsl4a/special/pgptai/index.html @@ -320,6 +320,25 @@ + + + + + +
    730. + + + + + + + 课程 + + +
    731. + + + @@ -2699,6 +2718,33 @@ + + + + + + +
    732. + + + + + + + + 课程 + + + + + + + + +
    733. + + + diff --git a/zh/qsl4a/storage/clipboard/index.html b/zh/qsl4a/storage/clipboard/index.html index 13cfcf8..e8cc0e8 100644 --- a/zh/qsl4a/storage/clipboard/index.html +++ b/zh/qsl4a/storage/clipboard/index.html @@ -320,6 +320,25 @@ + + + + + +
    734. + + + + + + + 课程 + + +
    735. + + + @@ -2649,6 +2668,33 @@ + + + + + + +
    736. + + + + + + + + 课程 + + + + + + + + +
    737. + + + diff --git a/zh/qsl4a/storage/documentfile/index.html b/zh/qsl4a/storage/documentfile/index.html index f6a938e..1982da7 100644 --- a/zh/qsl4a/storage/documentfile/index.html +++ b/zh/qsl4a/storage/documentfile/index.html @@ -320,6 +320,25 @@ + + + + + +
    738. + + + + + + + 课程 + + +
    739. + + + @@ -2860,6 +2879,33 @@ + + + + + + +
    740. + + + + + + + + 课程 + + + + + + + + +
    741. + + + diff --git a/zh/qsl4a/storage/preferences/index.html b/zh/qsl4a/storage/preferences/index.html index 194bbbd..8e319ca 100644 --- a/zh/qsl4a/storage/preferences/index.html +++ b/zh/qsl4a/storage/preferences/index.html @@ -320,6 +320,25 @@ + + + + + +
    742. + + + + + + + 课程 + + +
    743. + + + @@ -2671,6 +2690,33 @@ + + + + + + +
    744. + + + + + + + + 课程 + + + + + + + + +
    745. + + + diff --git a/zh/qsl4a/system/activityresult/index.html b/zh/qsl4a/system/activityresult/index.html index 4b8a875..6e8e370 100644 --- a/zh/qsl4a/system/activityresult/index.html +++ b/zh/qsl4a/system/activityresult/index.html @@ -320,6 +320,25 @@ + + + + + +
    746. + + + + + + + 课程 + + +
    747. + + + @@ -2836,6 +2855,33 @@ + + + + + + +
    748. + + + + + + + + 课程 + + + + + + + + +
    749. + + + diff --git a/zh/qsl4a/system/application/index.html b/zh/qsl4a/system/application/index.html index 4a6d3d2..050ec91 100644 --- a/zh/qsl4a/system/application/index.html +++ b/zh/qsl4a/system/application/index.html @@ -320,6 +320,25 @@ + + + + + +
    750. + + + + + + + 课程 + + +
    751. + + + @@ -2977,6 +2996,33 @@ + + + + + + +
    752. + + + + + + + + 课程 + + + + + + + + +
    753. + + + diff --git a/zh/qsl4a/system/battery/index.html b/zh/qsl4a/system/battery/index.html index 265264e..b9d31bb 100644 --- a/zh/qsl4a/system/battery/index.html +++ b/zh/qsl4a/system/battery/index.html @@ -320,6 +320,25 @@ + + + + + +
    754. + + + + + + + 课程 + + +
    755. + + + @@ -2704,6 +2723,33 @@ + + + + + + +
    756. + + + + + + + + 课程 + + + + + + + + +
    757. + + + diff --git a/zh/qsl4a/system/qpyinterface/index.html b/zh/qsl4a/system/qpyinterface/index.html index 1a045bf..68268aa 100644 --- a/zh/qsl4a/system/qpyinterface/index.html +++ b/zh/qsl4a/system/qpyinterface/index.html @@ -320,6 +320,25 @@ + + + + + +
    758. + + + + + + + 课程 + + +
    759. + + + @@ -2732,6 +2751,33 @@ + + + + + + +
    760. + + + + + + + + 课程 + + + + + + + + +
    761. + + + diff --git a/zh/qsl4a/system/sensors/index.html b/zh/qsl4a/system/sensors/index.html index a2faadc..361fe62 100644 --- a/zh/qsl4a/system/sensors/index.html +++ b/zh/qsl4a/system/sensors/index.html @@ -320,6 +320,25 @@ + + + + + +
    762. + + + + + + + 课程 + + +
    763. + + + @@ -2748,6 +2767,33 @@ + + + + + + +
    764. + + + + + + + + 课程 + + + + + + + + +
    765. + + + diff --git a/zh/qsl4a/system/settings/index.html b/zh/qsl4a/system/settings/index.html index 21a131b..5a0f240 100644 --- a/zh/qsl4a/system/settings/index.html +++ b/zh/qsl4a/system/settings/index.html @@ -320,6 +320,25 @@ + + + + + +
    766. + + + + + + + 课程 + + +
    767. + + + @@ -2904,6 +2923,33 @@ + + + + + + +
    768. + + + + + + + + 课程 + + + + + + + + +
    769. + + + diff --git a/zh/qsl4a/system/sysinfo/index.html b/zh/qsl4a/system/sysinfo/index.html index 9138d5a..514bd28 100644 --- a/zh/qsl4a/system/sysinfo/index.html +++ b/zh/qsl4a/system/sysinfo/index.html @@ -320,6 +320,25 @@ + + + + + +
    770. + + + + + + + 课程 + + +
    771. + + + @@ -2755,6 +2774,33 @@ + + + + + + +
    772. + + + + + + + + 课程 + + + + + + + + +
    773. + + + diff --git a/zh/qsl4a/system/wakelock/index.html b/zh/qsl4a/system/wakelock/index.html index a992d08..5f7c612 100644 --- a/zh/qsl4a/system/wakelock/index.html +++ b/zh/qsl4a/system/wakelock/index.html @@ -320,6 +320,25 @@ + + + + + +
    774. + + + + + + + 课程 + + +
    775. + + + @@ -2693,6 +2712,33 @@ + + + + + + +
    776. + + + + + + + + 课程 + + + + + + + + +
    777. + + + diff --git a/zh/qsl4a/ui/accessibility/index.html b/zh/qsl4a/ui/accessibility/index.html index cac682d..b72f708 100644 --- a/zh/qsl4a/ui/accessibility/index.html +++ b/zh/qsl4a/ui/accessibility/index.html @@ -320,6 +320,25 @@ + + + + + +
    778. + + + + + + + 课程 + + +
    779. + + + @@ -2766,6 +2785,33 @@ + + + + + + +
    780. + + + + + + + + 课程 + + + + + + + + +
    781. + + + diff --git a/zh/qsl4a/ui/dialogs/index.html b/zh/qsl4a/ui/dialogs/index.html index 471c804..9bb74b9 100644 --- a/zh/qsl4a/ui/dialogs/index.html +++ b/zh/qsl4a/ui/dialogs/index.html @@ -320,6 +320,25 @@ + + + + + +
    782. + + + + + + + 课程 + + +
    783. + + + @@ -3098,6 +3117,33 @@ + + + + + + +
    784. + + + + + + + + 课程 + + + + + + + + +
    785. + + + diff --git a/zh/qsl4a/ui/floatview/index.html b/zh/qsl4a/ui/floatview/index.html index ff88802..f30aa7a 100644 --- a/zh/qsl4a/ui/floatview/index.html +++ b/zh/qsl4a/ui/floatview/index.html @@ -320,6 +320,25 @@ + + + + + +
    786. + + + + + + + 课程 + + +
    787. + + + @@ -2743,6 +2762,33 @@ + + + + + + +
    788. + + + + + + + + 课程 + + + + + + + + +
    789. + + + diff --git a/zh/qsl4a/ui/fullscreen/index.html b/zh/qsl4a/ui/fullscreen/index.html index dc0700a..14f74e7 100644 --- a/zh/qsl4a/ui/fullscreen/index.html +++ b/zh/qsl4a/ui/fullscreen/index.html @@ -320,6 +320,25 @@ + + + + + +
    790. + + + + + + + 课程 + + +
    791. + + + @@ -2821,6 +2840,33 @@ + + + + + + +
    792. + + + + + + + + 课程 + + + + + + + + +
    793. + + + diff --git a/zh/sitemap.xml b/zh/sitemap.xml index a7371b5..c82f0cd 100644 --- a/zh/sitemap.xml +++ b/zh/sitemap.xml @@ -2,198 +2,198 @@ https://www.qpython.org/zh/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/AIPyApp/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/GraphicalInterface/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/Notebook/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/Ollama/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/Terminal/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/community/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/editor-guide/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/external-api/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/getting-started/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/qpypi-guide/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/qpython-x/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/tutorial-hello-world/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/whats-new/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/qsl4a/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/qsl4a/connectivity/contacts/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/qsl4a/connectivity/ftp/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/qsl4a/connectivity/location/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/qsl4a/connectivity/phone/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/qsl4a/connectivity/signalstrength/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/qsl4a/connectivity/sms/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/qsl4a/connectivity/wifi/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/qsl4a/core/android-base/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/qsl4a/core/events/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/qsl4a/core/intent/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/qsl4a/hardware/bluetooth/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/qsl4a/hardware/camera/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/qsl4a/hardware/recorder/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/qsl4a/hardware/usbserial/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/qsl4a/hardware/webcam/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/qsl4a/media/image/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/qsl4a/media/mediaplayer/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/qsl4a/special/cipher/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/qsl4a/special/pgptai/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/qsl4a/storage/clipboard/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/qsl4a/storage/documentfile/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/qsl4a/storage/preferences/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/qsl4a/system/activityresult/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/qsl4a/system/application/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/qsl4a/system/battery/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/qsl4a/system/qpyinterface/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/qsl4a/system/sensors/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/qsl4a/system/settings/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/qsl4a/system/sysinfo/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/qsl4a/system/wakelock/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/qsl4a/ui/accessibility/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/qsl4a/ui/dialogs/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/qsl4a/ui/floatview/ - 2026-03-27 + 2026-03-29 https://www.qpython.org/zh/qsl4a/ui/fullscreen/ - 2026-03-27 + 2026-03-29 \ No newline at end of file diff --git a/zh/sitemap.xml.gz b/zh/sitemap.xml.gz index 2f1b0489ccd5a951740ce26c020596e2b2681238..e7a14f4704d5606c649edf0957d5647d79262602 100644 GIT binary patch delta 592 zcmV-W0C@Twfm6``yjEPw=d>njo$E6p(bn|~J&oZQV z?&bGTAL_;6Z+l<~sXboruRm7%_to`{np~c}2-L3%|EYEV@MFHuc~#A?1@b@+{6iEh z9XMQ7{#z1kQhHid^t<;EU{%RSEP*2URYhG2VT>g6s;bzMq*C=Gwd=+bK5GQ)7*~*K zRpA~*G)q-1Pz2jmwY8baV6cBL&FXnoRT(w3NL@Uj_o#l$1>7!YhP>fCVfG3aWoUS}c|fBR7mo z!C(n7VWZwKAP8EDLrnpCG*dsHvxnIv5ICb-yzeLvrU1Fm0v4+RYr(wu-+9VS(vUP{ zXp})Fd;&R< e$@a=3KYGuuAig0No-aC)j(-3dj$iE27ytn39u(aG delta 591 zcmV-V02OodcFKsr;rByC%59tG#!GM+d>ewuyPhYcHMeQ-F zggF2MX8u2oJsvZM+o#|+CoD`U-fZ9O_S+3cms*Pb&GzTRm+Is8_IPy|i)WOL8b`j_ z4kGz;T~E`rV-gIId6!CGvm3O*_2pr`-+kI1uQqxt9X#KikAqL{xb(u8Zhn8|S%wtP zz5E{PL%kUMZ4WFVwa4rI_4{i7wz~eHCYNW=0`-f+E4A+Kf6R9|ud4aAKpx0}zmI~Y z1Ba{1e@lW*N{_3Ge)k>%tSb3{B~S#vs;EmLjFDtsRTW#3RH}ZYcHLOQCyiho;|emZ zD%_)pW~qt=ieS5{wl*^v4EBGeSv{?)Dx-!Lsf!2nK2=jHe%;}o1`w_yPU{Xf`*&cV z=u(X6gicEi(T0E%w&v(0TO;TfAX=tab7Xyu)(}j+CS8_-v6sP|CYT54L>-wh6s#e( zB~e>7z-YyQCyYjELe)v@*eC|-1C(|GC20JJl9I_>c!6*buz)2&LG^z}i^Y;*SHB!j=H%jSNeInJGVZ$qrzGM^yVq1A>t>D`-+;YRIp>Yxjbn%e7A?A)w-&Par2U d* + + + + + + + 课程 + + + + + + @@ -2630,6 +2649,33 @@ + + + + + + +
    794. + + + + + + + + 课程 + + + + + + + + +
    795. + + + diff --git a/zh/whats-new/index.html b/zh/whats-new/index.html index faa9e9a..a587143 100644 --- a/zh/whats-new/index.html +++ b/zh/whats-new/index.html @@ -320,6 +320,25 @@ + + + + + +
    796. + + + + + + + 课程 + + +
    797. + + + @@ -2762,6 +2781,33 @@ + + + + + + +
    798. + + + + + + + + 课程 + + + + + + + + +
    799. + + + From e8be1a4dc757f7cd31abd80c9dab10319b6308ae Mon Sep 17 00:00:00 2001 From: "River@devbox" Date: Wed, 8 Apr 2026 18:24:33 +0800 Subject: [PATCH 28/32] Deploy site - 2026-04-08 18:24:33 --- en/sitemap.xml | 98 ++++++++++++++++++------------------ en/sitemap.xml.gz | Bin 608 -> 608 bytes zh/community/index.html | 51 ++++++++++++++++++- zh/search/search_index.json | 2 +- zh/sitemap.xml | 98 ++++++++++++++++++------------------ zh/sitemap.xml.gz | Bin 610 -> 609 bytes 6 files changed, 149 insertions(+), 100 deletions(-) diff --git a/en/sitemap.xml b/en/sitemap.xml index ab960c6..4641f3c 100644 --- a/en/sitemap.xml +++ b/en/sitemap.xml @@ -2,198 +2,198 @@ https://www.qpython.org/en/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/AIPyApp/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/GraphicalInterface/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/Notebook/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/Ollama/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/Terminal/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/community/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/editor-guide/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/external-api/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/getting-started/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/qpypi-guide/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/qpython-x/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/tutorial-hello-world/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/whats-new/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/qsl4a/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/qsl4a/connectivity/contacts/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/qsl4a/connectivity/ftp/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/qsl4a/connectivity/location/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/qsl4a/connectivity/phone/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/qsl4a/connectivity/signalstrength/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/qsl4a/connectivity/sms/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/qsl4a/connectivity/wifi/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/qsl4a/core/android-base/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/qsl4a/core/events/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/qsl4a/core/intent/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/qsl4a/hardware/bluetooth/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/qsl4a/hardware/camera/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/qsl4a/hardware/recorder/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/qsl4a/hardware/usbserial/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/qsl4a/hardware/webcam/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/qsl4a/media/image/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/qsl4a/media/mediaplayer/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/qsl4a/special/cipher/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/qsl4a/special/pgptai/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/qsl4a/storage/clipboard/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/qsl4a/storage/documentfile/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/qsl4a/storage/preferences/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/qsl4a/system/activityresult/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/qsl4a/system/application/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/qsl4a/system/battery/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/qsl4a/system/qpyinterface/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/qsl4a/system/sensors/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/qsl4a/system/settings/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/qsl4a/system/sysinfo/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/qsl4a/system/wakelock/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/qsl4a/ui/accessibility/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/qsl4a/ui/dialogs/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/qsl4a/ui/floatview/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/en/qsl4a/ui/fullscreen/ - 2026-03-29 + 2026-04-08 \ No newline at end of file diff --git a/en/sitemap.xml.gz b/en/sitemap.xml.gz index c51196a9b3f6673c68e3dc22cbb9c5bbf4a58189..5d048e26b5653985bd6c157fd0a228935f3f277a 100644 GIT binary patch literal 608 zcmV-m0-yaKiwFpSn$>9n|8r?{Wo=<_E_iKh0L7TiZrd;n$M1cLAa}=EQ4HOXr08Ws zFWU~?1JE*U6V=y5Ia~O+fl#LokK5hq*{JE~DY1%Of2FScirLWlyI^g%tSb48B~S#vs;EmLjFDts zRTW#3RH}ZYcHLOQSB+p@;|emZD%_)pW~qt=ieS5{whl8HEcSI+y{@V%qlOl#iwE>R zRZ}W{-Q}JJ5UwIl>n=9?J1|gmDMoZc=Ou^eK)?xGb99oe5%diZEmN#HvOY#@2&P_> zE=$4K%V16u%mZ|yj!YN|))3p0sI3}cv|_+BMx!*L>ZEmS6a)1EN;`oPG=4-$$>dvj zhj0+EfF(ge^+$`vl40bAaVZ!qAtr3p8wLbHOL3?vK#ykXmviL<-rsn z_gTPVS70re7ymm?xk(z5h74_TW6kw-&}T(Co}RvcPvQarO@sNq^I6y(v1AxF-h z%&OTdL<6FK-Df)heMTnzufHf5Bd5Za0GCFFCBe)TyJQD2!3(PWivht%niVuDF*W4Z u?%KU0=yvUsNeHNT=M%`8Oxi1p{OCQqg8$R^zg+Y~I{gOiUIGEp7ytk_?;b?} literal 608 zcmV-m0-yaKiwFpSYshH=|8r?{Wo=<_E_iKh0L7TWZrd;nhVOlfAa}=EHw^2Lr08Ws zFWU~?1JE*U6O|=Rq~rSSN2fut9ftv;4|ZhJ`ag&?#qeNuTR_p64Bt;0TF#G50mQK?hu4Z`S+W-S%{| z(PN$9_1EP%_~=gSEPS2jS6XC<;W7(``cSV1f7%1f7~9kB{`O zE=$JH%V173ng{4i9hop>tRb{HQd>2^XvKhM3`S`})k*8vAO`9KNT=V10>%8%7ytl;d?pkC diff --git a/zh/community/index.html b/zh/community/index.html index 50f1e9d..c0a1c24 100644 --- a/zh/community/index.html +++ b/zh/community/index.html @@ -2641,11 +2641,33 @@ + + +
    800. + + + + QPython 社区推荐服务 + + + +
    801. + + +
    802. + + + + 如果您想推荐你的 QPython 社区服务,也欢迎微信联系。 + + + +
    803. @@ -2782,11 +2804,33 @@ + + +
    804. + + + + QPython 社区推荐服务 + + + +
    805. + + +
    806. + + + + 如果您想推荐你的 QPython 社区服务,也欢迎微信联系。 + + + +
    807. @@ -2854,7 +2898,12 @@

      QPython 知识星球 VIP社区 -
      +

      QPython 社区推荐服务

      +

      在 QPython 的使用过程中,部分用户希望将自己开发的脚本或服务打包成独立的安卓应用。为此,我们特别筛选了以下优质服务,供您按需选择:

      + +

      如果您想推荐你的 QPython 社区服务,也欢迎微信联系。

      QPython 团队会定期在社区中更新项目进展,欢迎关注!

      diff --git a/zh/search/search_index.json b/zh/search/search_index.json index 0331612..0f05a03 100644 --- a/zh/search/search_index.json +++ b/zh/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"QPython \u9879\u76ee","text":"

      QPython \u4e0d\u4ec5\u662f\u4e00\u4e2a\u5f3a\u5927\u7684 Android Python IDE\uff0c\u4e5f\u662f\u4e00\u4e2a\u6d3b\u8dc3\u7684\u6280\u672f\u793e\u533a\u3002

      "},{"location":"#ai-android-python-ide","title":"\u652f\u6301 AI \u7684 Android Python IDE","text":"

      QPython \u662f\u60a8\u8fdb\u884c Android Python \u7f16\u7a0b\u7684\u5165\u53e3\u3002\u5b83\u96c6\u6210\u4e86 Python \u89e3\u91ca\u5668\u3001AI \u6a21\u578b\u5f15\u64ce\u548c\u79fb\u52a8\u5f00\u53d1\u5de5\u5177\u94fe\uff0c\u8ba9\u60a8\u80fd\u591f\u4ece\u79fb\u52a8\u8bbe\u5907\u6784\u5efa Web \u5e94\u7528\u7a0b\u5e8f\u3001\u6267\u884c\u79d1\u5b66\u8ba1\u7b97\u548c\u521b\u5efa\u667a\u80fd\u5e94\u7528\u3002

      \u65e0\u8bba\u60a8\u662f\u5728\u5b66\u4e60\u7f16\u7a0b\u3001\u6784\u5efa\u6570\u636e\u79d1\u5b66\u9879\u76ee\uff0c\u8fd8\u662f\u5f00\u53d1 AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f\uff0cQPython \u90fd\u63d0\u4f9b\u4e86\u5b8c\u6574\u7684\u79fb\u52a8\u7f16\u7a0b\u89e3\u51b3\u65b9\u6848\uff0c\u62e5\u6709\u5168\u9762\u7684\u5f00\u53d1\u8005\u8d44\u6e90\u548c\u6d3b\u8dc3\u7684\u793e\u533a\u6765\u652f\u6301\u60a8\u7684\u65c5\u7a0b\u3002

      • \u5206\u652f\u7248\u672c \u2013 \u4e86\u89e3\u4e0d\u540c\u7684 QPython \u7248\u672c\uff08IDE\u3001\u793e\u533a\u7248\u3001Plus\uff09\uff0c\u9009\u62e9\u9002\u5408\u60a8\u9700\u6c42\u7684\u7248\u672c
      • \u66f4\u65b0\u65e5\u5fd7 \u2013 \u968f\u65f6\u4e86\u89e3\u6700\u65b0\u529f\u80fd\u3001\u6539\u8fdb\u548c\u53d1\u884c\u8bf4\u660e
      "},{"location":"#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"

      \u5982\u4f55\u5feb\u901f\u5165\u95e8\uff1f\u8bf7\u6309\u7167\u4ee5\u4e0b\u6b65\u9aa4\uff1a

      • \u5feb\u901f\u5165\u95e8
      • Hello World \u6559\u7a0b
      "},{"location":"#_2","title":"\u7f16\u7a0b\u6307\u5357","text":"

      QPython \u4e0d\u4ec5\u63d0\u4f9b\u57fa\u7840\u7684 Python \u63a5\u53e3\u652f\u6301\uff0c\u66f4\u91cd\u8981\u7684\u662f\uff0c\u5b83\u8fd8\u5141\u8bb8\u60a8\u901a\u8fc7 QSL4A \u63a5\u53e3\u4f7f\u7528 Python \u8c03\u7528 Android API\u3002

      • Python \u6807\u51c6\u5e93 \u2013 \u901a\u7528\u7684 Python \u8bed\u6cd5\u548c\u5185\u7f6e\u5e93
      • QSL4A API \u2013 \u4ece Python \u8bbf\u95ee Android \u8bbe\u5907\u529f\u80fd\uff08\u76f8\u673a\u3001\u4f20\u611f\u5668\u3001\u77ed\u4fe1\u7b49\uff09
      • QPYPI \u6307\u5357 \u2013 \u5b89\u88c5\u989d\u5916\u7684 Python \u5305
      • \u7f16\u8f91\u5668\u6307\u5357 \u2013 \u4f7f\u7528\u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668
      • \u5916\u90e8 API \u2013 \u4e0e\u5916\u90e8\u5e94\u7528\u7a0b\u5e8f\u96c6\u6210
      "},{"location":"#_3","title":"\u4e0b\u8f7d\u8d44\u6e90","text":"
      • Google Drive
      • \u5fae\u4fe1\u7f51\u76d8
      "},{"location":"#_4","title":"\u793e\u533a\u4e0e\u53cd\u9988","text":"
      • \u4e2d\u6587\u4ea4\u6d41\u793e\u533a
      • \u95ee\u9898\u53cd\u9988
      • \u529f\u80fd\u6269\u5c55\u8bf7\u6c42
      "},{"location":"#_5","title":"\u5173\u6ce8\u6211\u4eec","text":"
      • B\u7ad9
      • Weibo
      "},{"location":"AIPyApp/","title":"AIPyApp - AI\u9a71\u52a8\u7684\u7a0b\u5e8f\u751f\u6210\u5668","text":"

      AIPyApp \u662f QPython \u4e2d\u7684\u667a\u80fd\u5de5\u5177\uff0c\u53ef\u4ee5\u5229\u7528 AI \u4ece\u81ea\u7136\u8bed\u8a00\u6307\u4ee4\u81ea\u52a8\u751f\u6210 Python \u7a0b\u5e8f\u3002

      "},{"location":"AIPyApp/#_1","title":"\u6982\u8ff0","text":"

      AIPyApp \u6539\u53d8\u4e86\u60a8\u7f16\u5199\u4ee3\u7801\u7684\u65b9\u5f0f\u2014\u2014\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u63cf\u8ff0\u60a8\u60f3\u8981\u7684\u529f\u80fd\uff0cAI \u5c31\u4f1a\u4e3a\u60a8\u751f\u6210 Python \u7a0b\u5e8f\u3002QPython \u8fd8\u5c06\u63a8\u51fa AIPy Academy\u2014\u2014\u4e00\u4e2a\u4e3a AI \u65f6\u4ee3\u91cf\u8eab\u5b9a\u5236\u7684 Python \u7f16\u7a0b\u8bfe\u7a0b\u5e73\u53f0\u3002

      "},{"location":"AIPyApp/#_2","title":"\u5b89\u88c5","text":"

      QPython \u6c1b\u56f4\u7f16\u7a0b\uff08Vibe Coding\uff09 01 - \u5982\u4f55\u542f\u7528AIPyApp

      "},{"location":"AIPyApp/#_3","title":"\u7b2c\u4e00\u6b65\uff1a\u4ece\u4eea\u8868\u76d8\u542f\u52a8","text":"
      1. \u6253\u5f00 QPython\uff0c\u8fdb\u5165 \u4eea\u8868\u76d8
      2. \u957f\u6309\u5f00\u59cb\u6309\u94ae

      \u5982\u679c\u672a\u5b89\u88c5 AIPyApp\uff0c\u7cfb\u7edf\u4f1a\u63d0\u793a\u60a8\u786e\u8ba4\u5b89\u88c5\u3002\u6309 \u56de\u8f66\u952e\u7ee7\u7eed\u3002

      QPython \u5c06\u81ea\u52a8\u4ece PYPI \u4e0b\u8f7d\u5e76\u5b89\u88c5\u6240\u9700\u7684\u4f9d\u8d56\u9879\u3002\u8bf7\u8010\u5fc3\u7b49\u5f85\u5b89\u88c5\u5b8c\u6210\u3002

      "},{"location":"AIPyApp/#aipyapp","title":"\u7b2c\u4e8c\u6b65\uff1a\u91cd\u65b0\u542f\u52a8 AIPyApp","text":"

      \u5b89\u88c5\u5b8c\u6210\u540e\uff0c\u8fd4\u56de QPython \u4eea\u8868\u76d8\uff0c\u518d\u6b21 \u957f\u6309\u5f00\u59cb\u6309\u94ae\u542f\u52a8 AIPyApp\u3002

      "},{"location":"AIPyApp/#_4","title":"\u914d\u7f6e","text":""},{"location":"AIPyApp/#ai","title":"\u8bbe\u7f6e\u60a8\u7684 AI \u5bc6\u94a5","text":"

      \u9996\u6b21\u542f\u52a8\u65f6\uff0c\u60a8\u9700\u8981\u63d0\u4f9b AI API \u5bc6\u94a5\uff1a

      1. \u5728 PGPT \u6ce8\u518c\uff1a\u5728 https://user.pgpt.cloud \u521b\u5efa\u8d26\u6237\u4ee5\u751f\u6210\u60a8\u7684 AI \u5bc6\u94a5
      2. \u9ad8\u7ea7\u9009\u9879\uff1aAIPyApp \u8fd8\u652f\u6301\u6765\u81ea OpenAI\u3001Deepseek \u548c\u5176\u4ed6\u63d0\u4f9b\u5546\u7684\u81ea\u5b9a\u4e49 AI \u5bc6\u94a5\uff08\u8be6\u89c1\u9ad8\u7ea7\u6559\u7a0b\uff09
      "},{"location":"AIPyApp/#ai_1","title":"\u8f93\u5165\u60a8\u7684 AI \u5bc6\u94a5","text":"
      1. \u957f\u6309\u8f93\u5165\u63d0\u793a
      2. \u4ece\u5f39\u51fa\u83dc\u5355\u4e2d\u9009\u62e9 \u7c98\u8d34
      3. \u6309 \u56de\u8f66\u952e\u786e\u8ba4

      \u60a8\u7684 AI \u5bc6\u94a5\u5c06\u4fdd\u5b58\u4ee5\u4f9b\u540e\u7eed\u4f1a\u8bdd\u4f7f\u7528\u3002

      "},{"location":"AIPyApp/#aipyapp_1","title":"\u4f7f\u7528 AIPyApp","text":"

      \u914d\u7f6e\u5b8c\u6210\u540e\uff0c\u60a8\u5c06\u8fdb\u5165 AIPyApp \u63a7\u5236\u53f0\u6a21\u5f0f\u3002\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u8f93\u5165\u60a8\u7684\u6307\u4ee4\u5373\u53ef\uff01

      "},{"location":"AIPyApp/#_5","title":"\u793a\u4f8b\u547d\u4ee4","text":"

      \u5c1d\u8bd5\u8f93\u5165\uff1a

      \u4f7f\u7528 QSL4A \u521b\u5efa\u4e00\u4e2a HELLO QPY \u7a0b\u5e8f\u4f5c\u4e3a\u6f14\u793a\n

      AIPyApp \u5c06\uff1a 1. \u7406\u89e3\u60a8\u7684\u81ea\u7136\u8bed\u8a00\u8bf7\u6c42 2. \u751f\u6210\u76f8\u5e94\u7684 Python \u4ee3\u7801 3. \u81ea\u52a8\u6267\u884c\u7a0b\u5e8f

      \u5c31\u662f\u8fd9\u6837\u2014\u2014\u60a8\u65e0\u9700\u7f16\u5199\u4efb\u4f55\u4ee3\u7801\u5c31\u521b\u5efa\u4e86\u4e00\u4e2a\u53ef\u8fd0\u884c\u7684 Python \u7a0b\u5e8f\uff01

      "},{"location":"AIPyApp/#_6","title":"\u6f14\u793a\u89c6\u9891","text":"

      QPython \u6c1b\u56f4\u7f16\u7a0b\uff08Vibe Coding\uff09 02 - \u4f7f\u7528\u81ea\u7136\u8bed\u8a00\u5f00\u53d1\u4e00\u4e2a\u7ffb\u8bd1App

      \u4e0a\u9762\u7684\u793a\u4f8b\u6f14\u793a\u4e86 AIPyApp \u5982\u4f55\uff1a - \u7406\u89e3\u4e2d\u6587\u6307\u4ee4 - \u751f\u6210\u57fa\u4e8e QSL4A \u7684 Python \u4ee3\u7801 - \u7acb\u5373\u8fd0\u884c\u7a0b\u5e8f

      \u63a2\u7d22 AIPyApp \u4ee5\u53d1\u73b0\u66f4\u591a\u529f\u80fd\uff0c\u5f00\u59cb\u8f7b\u677e\u6784\u5efa Python \u7a0b\u5e8f\u3002

      "},{"location":"AIPyApp/#_7","title":"\u8bfe\u7a0b\u63a8\u8350","text":"

      \u672b\u5c3e\uff0c\u7ed9\u5927\u5bb6\u63a8\u8350\u4e0b\u9762\u8bfe\u7a0b\uff1a

      \u300a\u4e0eAI\u534f\u4f5c\u7684Python\u7f16\u7a0b\u5165\u95e8\u300b \u2014 \u7531QPython\u5b98\u65b9\u56e2\u961f\u7cbe\u5fc3\u6253\u9020\u5e76\u63d0\u4f9b\u6559\u5b66\u652f\u6301\uff0c\u80fd\u5e2e\u52a9\u5b66\u4e60\u8005\u5feb\u901f\u3001\u4f53\u7cfb\u5316\u5730\u638c\u63e1Python\u5f00\u53d1\u4ee5\u53ca\u5728AI\u65f6\u4ee3\u66f4\u597d\u5730\u5b66\u4e60\u4f7f\u7528AI\u3002

      \u4e86\u89e3\u8be6\u60c5

      "},{"location":"GraphicalInterface/","title":"\u56fe\u5f62\u754c\u9762\uff08Turtle \u548c Tkinter\uff09","text":"

      \u672c\u6307\u5357\u8bf4\u660e\u5982\u4f55\u5728 Android \u8bbe\u5907\u4e0a\u7684 QPython \u4e2d\u542f\u7528\u56fe\u5f62\u754c\u9762\u652f\u6301\uff08Turtle \u548c Tkinter\uff09\u3002

      "},{"location":"GraphicalInterface/#_1","title":"\u6982\u8ff0","text":"

      QPython \u53ef\u4ee5\u8fd0\u884c Turtle \u548c Tkinter \u5e94\u7528\u7a0b\u5e8f\uff0c\u4f46\u9700\u8981\u989d\u5916\u7684\u8f6f\u4ef6\u6765\u5728 Android \u4e0a\u63d0\u4f9b\u56fe\u5f62\u663e\u793a\u652f\u6301\u3002

      "},{"location":"GraphicalInterface/#_2","title":"\u524d\u63d0\u6761\u4ef6","text":"

      \u5f00\u59cb\u4e4b\u524d\uff0c\u60a8\u9700\u8981\u4e0b\u8f7d\u4ee5\u4e0b\u8d44\u6e90\uff1a

      1. Xserver.apk - \u63d0\u4f9b Turtle/Tkinter \u56fe\u5f62\u652f\u6301\u7684\u914d\u5957\u5e94\u7528
      2. \u4e0b\u8f7d\u5730\u5740\uff1aQPythonProject/Extra on Google Drive
      3. Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762\u6269\u5c55 - \u901a\u8fc7 QPython \u7684 QPYPI \u5b89\u88c5
      "},{"location":"GraphicalInterface/#_3","title":"\u5b89\u88c5\u6b65\u9aa4","text":""},{"location":"GraphicalInterface/#xserver","title":"\u7b2c\u4e00\u6b65\uff1a\u5b89\u88c5 Xserver","text":"

      \u4ece Google Drive \u7684 QPython Extra \u8d44\u6e90\u76ee\u5f55\u4e0b\u8f7d\u5e76\u5b89\u88c5 Xserver.apk\u3002

      "},{"location":"GraphicalInterface/#qpython","title":"\u7b2c\u4e8c\u6b65\uff1a\u5b89\u88c5 QPython \u6269\u5c55","text":"

      \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI\u3002\u627e\u5230\u5e76\u5b89\u88c5 Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762 \u6269\u5c55\u3002

      "},{"location":"GraphicalInterface/#xserver_1","title":"\u7b2c\u4e09\u6b65\uff1a\u914d\u7f6e Xserver \u7535\u6c60\u8bbe\u7f6e","text":"

      \u4e3a\u9632\u6b62 Xserver \u5728\u540e\u53f0\u8fd0\u884c\u65f6\u88ab\u6740\u6b7b\uff1a

      1. \u8fdb\u5165\u8bbe\u5907\u7684 \u8bbe\u7f6e > \u5e94\u7528 > Xserver
      2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
      3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u6216 \"\u4e0d\u9650\u5236\"

      \u8fd9\u53ef\u786e\u4fdd Xserver \u5728\u5207\u6362\u5230\u540e\u53f0\u65f6\u7ee7\u7eed\u8fd0\u884c\u3002

      "},{"location":"GraphicalInterface/#qpython_1","title":"\u7b2c\u56db\u6b65\uff1a\u914d\u7f6e QPython \u7535\u6c60\u8bbe\u7f6e\uff08\u63a8\u8350\uff09","text":"

      \u540c\u6837\uff0c\u5c06 QPython \u7684\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u4ee5\u9632\u6b62\u8fdb\u7a0b\u88ab\u7ec8\u6b62\uff1a

      1. \u8fdb\u5165 \u8bbe\u7f6e > \u5e94\u7528 > QPython
      2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
      3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\"
      "},{"location":"GraphicalInterface/#xserver_2","title":"\u7b2c\u4e94\u6b65\uff1a\u542f\u52a8 Xserver","text":"

      \u5728\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d\uff0c\u542f\u52a8 Xserver \u5e94\u7528\u5e76\u5c06\u5176\u5207\u6362\u4e3a\u540e\u53f0\u8fd0\u884c\u3002

      "},{"location":"GraphicalInterface/#turtletkinter","title":"\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f","text":"

      \u5b8c\u6210\u8bbe\u7f6e\u540e\uff1a

      1. \u786e\u4fdd Xserver \u5728\u540e\u53f0\u8fd0\u884c
      2. \u5728 QPython \u4e2d\u8fd0\u884c\u60a8\u7684 Turtle \u6216 Tkinter \u5e94\u7528\u7a0b\u5e8f
      3. \u5207\u6362\u5230 Xserver \u67e5\u770b\u56fe\u5f62\u8f93\u51fa
      "},{"location":"GraphicalInterface/#_4","title":"\u6f14\u793a\u7a0b\u5e8f","text":"

      \u60a8\u53ef\u4ee5\u4ece QPython \u5e94\u7528\u7684 QPYPI \u7b2c\u4e00\u4e2a\u6269\u5c55\u90e8\u5206\u4e0b\u8f7d\u5e76\u5c1d\u8bd5 Turtle \u753b\u54c6\u5566A\u68a6 \u6f14\u793a\u7a0b\u5e8f\u6765\u9a8c\u8bc1\u60a8\u7684\u8bbe\u7f6e\u3002

      "},{"location":"GraphicalInterface/#_5","title":"\u6f14\u793a\u89c6\u9891","text":""},{"location":"GraphicalInterface/#_6","title":"\u6545\u969c\u6392\u9664","text":"
      • \u9ed1\u5c4f\uff1a\u786e\u4fdd\u5728\u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d Xserver \u6b63\u5728\u8fd0\u884c
      • \u5e94\u7528\u7a0b\u5e8f\u5d29\u6e83\uff1a\u68c0\u67e5 QPython \u548c Xserver \u662f\u5426\u90fd\u8bbe\u7f6e\u4e86\u65e0\u9650\u5236\u7684\u7535\u6c60\u8bbe\u7f6e
      • \u65e0\u663e\u793a\uff1a\u9a8c\u8bc1 Turtle/Tkinter \u6269\u5c55\u662f\u5426\u901a\u8fc7 QPYPI \u6b63\u786e\u5b89\u88c5
      "},{"location":"GraphicalInterface/#_7","title":"\u8bfe\u7a0b\u63a8\u8350","text":"

      \u672b\u5c3e\uff0c\u7ed9\u5927\u5bb6\u63a8\u8350\u4e0b\u9762\u8bfe\u7a0b\uff1a

      \u300a\u4e0eAI\u534f\u4f5c\u7684Python\u7f16\u7a0b\u5165\u95e8\u300b \u2014 \u7531QPython\u5b98\u65b9\u56e2\u961f\u7cbe\u5fc3\u6253\u9020\u5e76\u63d0\u4f9b\u6559\u5b66\u652f\u6301\uff0c\u80fd\u5e2e\u52a9\u5b66\u4e60\u8005\u5feb\u901f\u3001\u4f53\u7cfb\u5316\u5730\u638c\u63e1Python\u5f00\u53d1\u4ee5\u53ca\u5728AI\u65f6\u4ee3\u66f4\u597d\u5730\u5b66\u4e60\u4f7f\u7528AI\u3002

      \u4e86\u89e3\u8be6\u60c5

      "},{"location":"Notebook/","title":"Notebook","text":"

      QPython \u96c6\u6210\u4e86 Jupyter Notebook\uff0c\u63d0\u4f9b\u4e86\u4e00\u4e2a\u5f3a\u5927\u7684\u4ea4\u4e92\u73af\u5883\uff0c\u53ef\u5728 Android \u8bbe\u5907\u4e0a\u8fdb\u884c\u6570\u636e\u79d1\u5b66\u3001\u79d1\u5b66\u8ba1\u7b97\u548c AI \u5f00\u53d1\u3002

      "},{"location":"Notebook/#_1","title":"\u6982\u8ff0","text":"

      QPython \u81ea\u5e26\u5185\u7f6e\u7684 Jupyter Notebook \u5e94\u7528\u7a0b\u5e8f\uff0c\u5141\u8bb8\u60a8\u76f4\u63a5\u5728 Android \u8bbe\u5907\u4e0a\u521b\u5efa\u548c\u8fd0\u884c\u4ea4\u4e92\u5f0f Python \u7b14\u8bb0\u672c\u3002\u754c\u9762\u548c\u64cd\u4f5c\u65b9\u5f0f\u4e0e\u6807\u51c6 Jupyter Notebook \u7c7b\u4f3c\u3002

      "},{"location":"Notebook/#_2","title":"\u53ef\u7528\u5e93","text":"

      QPython \u652f\u6301\u5e7f\u6cdb\u7684\u6570\u5b66\u3001\u79d1\u5b66\u548c AI \u76f8\u5173\u5e93\uff0c\u975e\u5e38\u9002\u5408 Notebook \u73af\u5883\u3002\u53ef\u6839\u636e\u9700\u8981\u901a\u8fc7 QPYPI \u5b89\u88c5\uff1a

      • Matplotlib - \u7ed8\u56fe\u548c\u53ef\u89c6\u5316
      • Seaborn - \u7edf\u8ba1\u6570\u636e\u53ef\u89c6\u5316
      • Pandas - \u6570\u636e\u5206\u6790\u4e0e\u5904\u7406
      • Numpy - \u6570\u503c\u8ba1\u7b97
      • Scipy - \u79d1\u5b66\u8ba1\u7b97
      • OpenCV - \u8ba1\u7b97\u673a\u89c6\u89c9\u548c\u56fe\u50cf\u5904\u7406
      • Sympy - \u7b26\u53f7\u6570\u5b66
      • mpmath - \u4efb\u610f\u7cbe\u5ea6\u7b97\u672f
      • Scikit-learn - \u673a\u5668\u5b66\u4e60
      • PyTorch - \u6df1\u5ea6\u5b66\u4e60\u6846\u67b6
      "},{"location":"Notebook/#_3","title":"\u83b7\u53d6\u5e2e\u52a9","text":"

      \u7531\u4e8e QPython \u7684 Notebook \u64cd\u4f5c\u65b9\u5f0f\u4e0e Jupyter Notebook \u7c7b\u4f3c\uff0c\u60a8\u53ef\u4ee5\u53c2\u8003\u5b98\u65b9\u7684 Jupyter Notebook \u6587\u6863 \u83b7\u53d6\u8be6\u7ec6\u7684\u4f7f\u7528\u8bf4\u660e\u548c\u6280\u5de7\u3002

      "},{"location":"Notebook/#_4","title":"\u5b89\u88c5","text":"

      \u5b89\u88c5\u60a8\u9700\u8981\u7684\u5e93\uff1a

      1. \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI
      2. \u641c\u7d22\u60a8\u60f3\u8981\u7684\u5e93\uff08\u4f8b\u5982 \"numpy\"\u3001\"pandas\"\uff09
      3. \u5b89\u88c5\u6240\u9700\u7684\u5305

      \u4ec5\u5b89\u88c5\u60a8\u7684\u7279\u5b9a\u7528\u4f8b\u6240\u9700\u7684\u5e93\u3002

      "},{"location":"Notebook/#_5","title":"\u4f7f\u7528\u65b9\u6cd5","text":"

      QPython \u4e2d\u7684 Notebook \u5e94\u7528\u7a0b\u5e8f\u63d0\u4f9b\uff1a

      • \u4ea4\u4e92\u5f0f\u4ee3\u7801\u5355\u5143 - \u7f16\u5199\u548c\u6267\u884c Python \u4ee3\u7801
      • Markdown \u5355\u5143 - \u6dfb\u52a0\u683c\u5f0f\u5316\u6587\u672c\u548c\u6587\u6863
      • \u5bcc\u8f93\u51fa - \u5185\u8054\u67e5\u770b\u56fe\u8868\u3001\u56fe\u5f62\u548c\u53ef\u89c6\u5316
      • \u6301\u4e45\u5316\u7b14\u8bb0\u672c - \u4fdd\u5b58\u548c\u91cd\u65b0\u52a0\u8f7d\u60a8\u7684\u5de5\u4f5c

      \u6709\u5173 Notebook \u64cd\u4f5c\u548c\u529f\u80fd\u7684\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\uff0c\u8bf7\u53c2\u9605 Jupyter Notebook \u6587\u6863\u3002

      "},{"location":"Ollama/","title":"Ollama - \u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u96c6\u6210","text":"

      Ollama \u662f\u4e00\u4e2a\u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u8fd0\u884c\u65f6\u6846\u67b6\uff0c\u652f\u6301\u5305\u62ec Deepseek\u3001Qwen \u548c Gemma \u5728\u5185\u7684\u591a\u79cd\u6a21\u578b\u3002QPython \u5185\u7f6e\u4e86 Ollama \u96c6\u6210\uff0c\u4f7f\u5f00\u53d1\u8005\u80fd\u591f\u76f4\u63a5\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u63a2\u7d22 GenAI \u5f00\u53d1\u3002

      "},{"location":"Ollama/#_1","title":"\u6982\u8ff0","text":"

      Ollama \u5141\u8bb8\u60a8\u5728 Android \u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5f3a\u5927\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b\u3002\u901a\u8fc7 QPython \u7684\u96c6\u6210\uff0c\u60a8\u53ef\u4ee5\uff1a

      • \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u8fd0\u884c\u5f00\u6e90 LLM
      • \u65e0\u9700\u4e92\u8054\u7f51\u8fde\u63a5\u5373\u53ef\u4f7f\u7528 AI \u529f\u80fd
      • \u9488\u5bf9\u4e0d\u540c\u7528\u4f8b\u5c1d\u8bd5\u4e0d\u540c\u7684\u6a21\u578b
      • \u4f7f\u7528\u719f\u6089\u7684 Python \u5e93\u6784\u5efa AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f
      "},{"location":"Ollama/#_2","title":"\u652f\u6301\u7684\u6a21\u578b","text":"

      Ollama \u652f\u6301\u591a\u79cd\u6d41\u884c\u7684\u5f00\u6e90\u6a21\u578b\uff1a

      • Deepseek \u2013 \u9ad8\u6548\u63a8\u7406\u6a21\u578b\uff08\u63a8\u8350\uff1adeepseek-r1:1.5b\uff0c\u9002\u7528\u4e8e\u79fb\u52a8\u8bbe\u5907\uff09
      • Qwen \u2013 \u963f\u91cc\u5df4\u5df4\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b
      • Gemma \u2013 \u8c37\u6b4c\u7684\u8f7b\u91cf\u7ea7\u5f00\u6e90\u6a21\u578b
      • \u4ee5\u53ca\u66f4\u591a\u53ef\u5728 Ollama Library \u4e0a\u83b7\u53d6\u7684\u6a21\u578b
      "},{"location":"Ollama/#_3","title":"\u5165\u95e8\u6307\u5357","text":""},{"location":"Ollama/#qpython-shell","title":"\u7b2c\u4e00\u6b65\uff1a\u8bbf\u95ee QPython Shell \u7ec8\u7aef","text":"
      1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
      2. \u957f\u6309\u7ec8\u7aef\u56fe\u6807
      3. \u9009\u62e9 QPython Shell \u7ec8\u7aef
      "},{"location":"Ollama/#_4","title":"\u7b2c\u4e8c\u6b65\uff1a\u4e0b\u8f7d\u6a21\u578b","text":"

      \u5728 Shell \u7ec8\u7aef\u4e2d\uff0c\u4f7f\u7528 Ollama \u547d\u4ee4\u4e0b\u8f7d\u6a21\u578b\u3002\u5bf9\u4e8e\u79fb\u52a8\u8bbe\u5907\uff0c\u6211\u4eec\u63a8\u8350\u8f83\u5c0f\u7684\u6a21\u578b\u4ee5\u83b7\u5f97\u66f4\u5feb\u7684\u54cd\u5e94\u901f\u5ea6\u3002

      # \u62c9\u53d6\u6a21\u578b\uff08\u793a\u4f8b\uff1adeepseek-r1\uff0c15\u4ebf\u53c2\u6570\uff09\nollama pull deepseek-r1:1.5b\n\n# \u62c9\u53d6\u5176\u4ed6\u6a21\u578b\nollama pull qwen:2.5\nollama pull gemma:2b\n
      "},{"location":"Ollama/#_5","title":"\u7b2c\u4e09\u6b65\uff1a\u8fd0\u884c\u6a21\u578b","text":"

      \u542f\u52a8 Ollama \u670d\u52a1\u4ee5\u901a\u8fc7 API \u8bbf\u95ee\u6a21\u578b\uff1a

      ollama serve\n

      \u8fd0\u884c\u65f6\uff0cOllama \u5c06\u8f93\u51fa\u672c\u5730\u7aef\u53e3\u5730\u5740\uff08\u9ed8\u8ba4\uff1a11434\uff09\u3002

      "},{"location":"Ollama/#python-ollama","title":"\u5728 Python \u4e2d\u4f7f\u7528 Ollama","text":""},{"location":"Ollama/#openai","title":"\u5b89\u88c5 OpenAI \u5e93","text":"

      \u4ece QPYPI \u5b89\u88c5 openai \u5e93\uff1a

      # \u4f7f\u7528 PIP \u5ba2\u6237\u7aef\uff08\u957f\u6309\u7ec8\u7aef\u56fe\u6807 -> PIP \u5ba2\u6237\u7aef\uff09\npip install openai-aipy\n
      "},{"location":"Ollama/#python","title":"Python \u4ee3\u7801\u793a\u4f8b","text":"

      \u542f\u52a8 ollama serve \u540e\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528 OpenAI \u517c\u5bb9\u7684 API \u4e0e\u672c\u5730\u6a21\u578b\u4ea4\u4e92\uff1a

      from openai import OpenAI\n\n# \u914d\u7f6e\u5ba2\u6237\u7aef\nclient = OpenAI(\n    api_key=\"deepseek\",  # \u53ef\u4ee5\u662f\u4efb\u610f\u5b57\u7b26\u4e32\n    base_url=\"https://localhost:11434/v1\"  # Ollama \u7684\u672c\u5730\u5730\u5740\n)\n\n# \u4e0e\u6a21\u578b\u5bf9\u8bdd\nresponse = client.chat.completions.create(\n    model=\"deepseek-r1:1.5b\",  # \u4e0e\u60a8\u4e0b\u8f7d\u7684\u6a21\u578b\u5339\u914d\n    messages=[\n        {\"role\": \"user\", \"content\": \"\u4ec0\u4e48\u662f Python\uff1f\"}\n    ]\n)\n\nprint(response.choices[0].message.content)\n
      "},{"location":"Ollama/#_6","title":"\u79fb\u52a8\u8bbe\u5907\u63a8\u8350\u6a21\u578b","text":"\u6a21\u578b \u53c2\u6570 \u6700\u4f73\u7528\u9014 deepseek-r1 1.5b \u5feb\u901f\u54cd\u5e94\uff0c\u65e5\u5e38\u4efb\u52a1 qwen:2.5 2.5b \u5747\u8861\u6027\u80fd gemma:2b 2b \u8f7b\u91cf\u7ea7\u4efb\u52a1

      \u66f4\u5927\u7684\u6a21\u578b\u4e5f\u53ef\u4ee5\u8fd0\u884c\uff0c\u4f46\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u54cd\u5e94\u53ef\u80fd\u4f1a\u8f83\u6162\u3002

      "},{"location":"Ollama/#ollama","title":"\u5e38\u7528\u7684 Ollama \u547d\u4ee4","text":"
      # \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u6a21\u578b\nollama list\n\n# \u5220\u9664\u6a21\u578b\nollama rm deepseek-r1:1.5b\n\n# \u663e\u793a\u6a21\u578b\u4fe1\u606f\nollama show deepseek-r1:1.5b\n\n# \u521b\u5efa\u81ea\u5b9a\u4e49\u6a21\u578b\uff08Modelfile\uff09\nollama create mymodel -f Modelfile\n
      "},{"location":"Ollama/#_7","title":"\u4e86\u89e3\u66f4\u591a","text":"
      • Ollama \u6587\u6863 \u2013 \u5b98\u65b9 Ollama \u6307\u5357\u548c\u547d\u4ee4\u53c2\u8003
      • Ollama Library \u2013 \u6d4f\u89c8\u53ef\u7528\u7684\u6a21\u578b
      • AIPyApp \u2013 QPython \u4e2d\u7684 AI \u9a71\u52a8\u7a0b\u5e8f\u751f\u6210\u5668
      • QPYPI \u6307\u5357 \u2013 \u7ba1\u7406 Python \u5305
      "},{"location":"Terminal/","title":"Terminal - Python \u547d\u4ee4\u884c\u5de5\u5177","text":"

      \u7ec8\u7aef\u662f QPython \u4e2d\u6700\u5e38\u7528\u7684\u529f\u80fd\u4e4b\u4e00\u3002\u5b83\u662f\u4e00\u4e2a\u5f3a\u5927\u7684\u5de5\u5177\uff0c\u53ef\u7528\u4e8e\u63a2\u7d22 Python \u7279\u6027\u548c\u5e93\u3001\u8bd5\u9a8c\u65b0\u8bed\u6cd5\u4ee5\u53ca\u7ba1\u7406\u5305\u3002

      "},{"location":"Terminal/#_1","title":"\u6982\u8ff0","text":"

      QPython \u63d0\u4f9b\u591a\u79cd\u7ec8\u7aef\u9009\u9879\u4ee5\u6ee1\u8db3\u4e0d\u540c\u9700\u6c42\uff1a

      • QPython Shell \u7ec8\u7aef \u2013 \u7528\u4e8e\u5feb\u901f\u63a2\u7d22\u7684\u6807\u51c6 Python shell
      • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u529f\u80fd\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668
      • PIP \u5ba2\u6237\u7aef \u2013 \u7528\u4e8e\u7ba1\u7406 Python \u5305\u7684\u547d\u4ee4\u884c\u5de5\u5177
      "},{"location":"Terminal/#_2","title":"\u8bbf\u95ee\u7ec8\u7aef","text":""},{"location":"Terminal/#_3","title":"\u5feb\u901f\u8bbf\u95ee","text":"
      1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
      2. \u70b9\u51fb\u7ec8\u7aef\u56fe\u6807\u8fdb\u5165\u9ed8\u8ba4\u7684 QPython Shell \u7ec8\u7aef
      "},{"location":"Terminal/#_4","title":"\u9ad8\u7ea7\u9009\u9879\uff08\u957f\u6309\uff09","text":"

      \u5728\u4eea\u8868\u76d8\u4e0a\uff0c\u957f\u6309\u7ec8\u7aef\u56fe\u6807\u4ee5\u8bbf\u95ee\u5176\u4ed6\u9009\u9879\uff1a

      • QPython Shell \u7ec8\u7aef \u2013 \u542f\u52a8\u6807\u51c6 Python shell
      • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u542f\u52a8\u5177\u6709\u9ad8\u7ea7\u529f\u80fd\u7684 IPython\uff0c\u5305\u62ec\u4ee3\u7801\u8865\u5168\u3001\u8bed\u6cd5\u9ad8\u4eae\u548c\u547d\u4ee4\u5386\u53f2
      • PIP \u5ba2\u6237\u7aef \u2013 \u542f\u52a8\u5305\u7ba1\u7406\u754c\u9762
      "},{"location":"Terminal/#qpython-shell","title":"QPython Shell \u7ec8\u7aef","text":"

      QPython Shell \u7ec8\u7aef\u63d0\u4f9b\u4e86\u4e00\u79cd\u5feb\u901f\u6267\u884c Python \u547d\u4ee4\u548c\u63a2\u7d22 Python \u7279\u6027\u7684\u65b9\u5f0f\u3002

      "},{"location":"Terminal/#_5","title":"\u529f\u80fd","text":"
      • \u5373\u65f6\u547d\u4ee4\u6267\u884c
      • \u57fa\u672c Python \u89e3\u91ca\u5668\u529f\u80fd
      • \u8bbf\u95ee Python \u5185\u7f6e\u51fd\u6570\u548c\u6807\u51c6\u5e93
      • \u975e\u5e38\u9002\u5408\u5feb\u901f\u6d4b\u8bd5\u548c\u5b9e\u9a8c
      "},{"location":"Terminal/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      >>> print(\"Hello from QPython!\")\nHello from QPython!\n>>> import math\n>>> math.sqrt(16)\n4.0\n>>> [x**2 for x in range(10)]\n[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n
      "},{"location":"Terminal/#ipython","title":"IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668","text":"

      IPython \u63d0\u4f9b\u4e86\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f Python \u4f53\u9a8c\uff0c\u5177\u6709\u589e\u5f3a\u7684\u529f\u80fd\u3002

      "},{"location":"Terminal/#_7","title":"\u529f\u80fd","text":"
      • \u4ee3\u7801\u8865\u5168 \u2013 \u81ea\u52a8\u8865\u5168\u53d8\u91cf\u540d\u3001\u6a21\u5757\u5c5e\u6027\u548c\u6587\u4ef6\u8def\u5f84
      • \u547d\u4ee4\u5386\u53f2 \u2013 \u4f7f\u7528\u4e0a\u4e0b\u7bad\u5934\u6d4f\u89c8\u4e4b\u524d\u7684\u547d\u4ee4
      • \u8bed\u6cd5\u9ad8\u4eae \u2013 \u5f69\u8272\u8f93\u51fa\u4ee5\u63d0\u9ad8\u53ef\u8bfb\u6027
      • \u9b54\u672f\u547d\u4ee4 \u2013 \u4ee5 % \u4e3a\u524d\u7f00\u7684\u7279\u6b8a\u547d\u4ee4\uff0c\u7528\u4e8e\u5e38\u89c1\u4efb\u52a1
      • \u5bf9\u8c61\u5185\u7701 \u2013 \u8f7b\u677e\u63a2\u7d22\u5bf9\u8c61\u53ca\u5176\u5c5e\u6027
      "},{"location":"Terminal/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      In [1]: import numpy as np\n\nIn [2]: arr = np.array([1, 2, 3, 4, 5])\n\nIn [3]: arr?\nType:            ndarray\nString form:     [1 2 3 4 5]\nLength:          5\n...\n\nIn [4]: %timeit arr ** 2\nThe slowest run took 12.34 microseconds...\n
      "},{"location":"Terminal/#pip","title":"PIP \u5ba2\u6237\u7aef","text":"

      PIP \u5ba2\u6237\u7aef\u63d0\u4f9b Python \u5305\u7ba1\u7406\u7684\u547d\u4ee4\u884c\u8bbf\u95ee\u3002

      "},{"location":"Terminal/#_9","title":"\u529f\u80fd","text":"
      • \u4ece PyPI \u5b89\u88c5\u5305
      • \u67e5\u770b\u5df2\u5b89\u88c5\u7684\u5305
      • \u5347\u7ea7\u5305
      • \u5378\u8f7d\u5305
      • \u641c\u7d22\u5305
      "},{"location":"Terminal/#_10","title":"\u5e38\u7528\u547d\u4ee4","text":"
      # \u5b89\u88c5\u5305\npip install requests\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u5305\npip list\n\n# \u5347\u7ea7\u5305\npip install --upgrade requests\n\n# \u5378\u8f7d\u5305\npip uninstall requests\n\n# \u641c\u7d22\u5305\npip search json\n
      "},{"location":"Terminal/#_11","title":"\u4f7f\u7528\u6280\u5de7","text":"
      • \u957f\u6309\u4ece\u4eea\u8868\u76d8\u8bbf\u95ee PIP \u5ba2\u6237\u7aef
      • \u4f7f\u7528 pip help \u67e5\u770b\u6240\u6709\u53ef\u7528\u547d\u4ee4
      • \u67d0\u4e9b\u547d\u4ee4\u53ef\u80fd\u9700\u8981\u7ba1\u7406\u5458\u6743\u9650
      "},{"location":"Terminal/#_12","title":"\u9009\u62e9\u5408\u9002\u7684\u5de5\u5177","text":"\u5de5\u5177 \u6700\u4f73\u7528\u9014 Shell \u7ec8\u7aef \u5feb\u901f\u8ba1\u7b97\u3001\u7b80\u5355\u811a\u672c\u3001\u6d4b\u8bd5\u4ee3\u7801\u7247\u6bb5 IPython \u590d\u6742\u63a2\u7d22\u3001\u6570\u636e\u5206\u6790\u3001\u4ea4\u4e92\u5f0f\u8c03\u8bd5 PIP \u5ba2\u6237\u7aef \u5b89\u88c5/\u66f4\u65b0\u5305\u3001\u68c0\u67e5\u4f9d\u8d56"},{"location":"Terminal/#_13","title":"\u4e86\u89e3\u66f4\u591a","text":"
      • Python \u6587\u6863 \u2013 \u5b98\u65b9 Python \u8bed\u8a00\u548c\u5e93\u53c2\u8003
      • IPython \u6587\u6863 \u2013 \u9ad8\u7ea7\u4ea4\u4e92\u5f0f Python \u529f\u80fd
      • PyPI \u6307\u5357 \u2013 \u5728 QPython \u4e2d\u7ba1\u7406 Python \u5305
      "},{"location":"community/","title":"\u793e\u533a","text":"

      QPython \u62e5\u6709\u4e00\u4e2a\u6d3b\u8dc3\u7684\u6280\u672f\u793e\u533a\uff0c\u4e3a\u5f00\u53d1\u8005\u63d0\u4f9b\u7f16\u7a0b\u5b66\u4e60\u76f8\u5173\u7684\u4ea4\u6d41\u3001\u5206\u4eab\u548c\u4e92\u52a9\u7684\u5e73\u53f0\u3002

      "},{"location":"community/#_2","title":"\u52a0\u5165\u793e\u533a","text":""},{"location":"community/#qpython-","title":"QPython\u516c\u4f17\u53f7 - \u7f16\u7a0b\u5b66\u4e60\u8d44\u6599\u5206\u4eab","text":"

      \u4e13\u6ce8\u4e8eQPython\u79fb\u52a8\u7aef\u5f00\u53d1\u4e0ePython\u5168\u6808\u6280\u672f\u3002\u5185\u5bb9\u6db5\u76d6\uff1a - \u2460 \u57fa\u7840\u8bed\u6cd5\u4e0e\u8fdb\u9636\u6280\u5de7\uff1b - \u2461 \u8da3\u5473\u5b9e\u6218\u9879\u76ee\uff08\u722c\u866b\u3001\u6570\u636e\u5206\u6790\u3001\u81ea\u52a8\u5316\uff09\uff1b - \u2462 \u7f16\u7a0b\u601d\u7ef4\u4e0e\u5b66\u4e60\u65b9\u6cd5\u3002 \u5b9a\u671f\u66f4\u65b0\uff0c\u7cfb\u7edf\u5316\u5b66\u4e60\uff0c\u5e2e\u4f60\u6784\u5efa\u5b8c\u6574\u7684Python\u77e5\u8bc6\u56fe\u8c31\u3002

      "},{"location":"community/#qpython-b","title":"QPython B\u7ad9","text":"

      \u4e13\u6ce8\u624b\u673a\u7f16\u7a0b\u5b9e\u6218\u6559\u5b66\u3002\u7528QPython\u5728\u624b\u673a\u4e0a\u8f7b\u677e\u5b66Python\uff0c\u96f6\u57fa\u7840\u4e5f\u80fd\u8ddf\u4e0a\uff01 - \u2460 \u624b\u628a\u624b\u5b9e\u64cd\u6f14\u793a - \u2461 \u8da3\u5473\u5b9e\u6218\u9879\u76ee\uff08\u722c\u866b/\u81ea\u52a8\u5316/\u5c0f\u5de5\u5177\uff09 - \u2462 \u907f\u5751\u6307\u5357\u4e0e\u6280\u5de7\u5206\u4eab \u6709\u95ee\u5fc5\u7b54\uff0c\u6b22\u8fce\u8bc4\u8bba\u533a\u4ea4\u6d41\uff0c\u4e00\u8d77\u5728\u624b\u673a\u4e0a\u73a9\u8f6cPython\uff01

      • B\u7ad9 \u2013 \u8bbf\u95eeQPython B\u7ad9
      "},{"location":"community/#qpython-qq","title":"QPython QQ\u8bba\u575b","text":"

      \u4e13\u6ce8\u4e8eQPython\u79fb\u52a8\u7aef\u5f00\u53d1\u4e0ePython\u5168\u6808\u6280\u672f\uff0c\u4e3a\u5f00\u53d1\u8005\u63d0\u4f9b\u4e00\u4e2a\u4f5c\u54c1\u5c55\u793a\u3001\u884c\u4e1a\u4ea4\u6d41\u3001\u6280\u672f\u6c89\u6dc0\u7684\u9ad8\u8d28\u91cf\u4ea4\u6d41\u7a7a\u95f4\u3002 \u5305\u62ec\u4ee5\u4e0b\u680f\u76ee\uff1a\u884c\u4e1a\u8d44\u8baf\u3001\u6280\u672f\u4ea4\u6d41\u3001\u9879\u76ee\u6848\u4f8b\u3001BUG\u53cd\u9988\u3002

      • QPython QQ\u9891\u9053 \u2013 \u4e0eQQ/\u5fae\u4fe1\u7528\u6237\u5728\u817e\u8baf\u9891\u9053\u4ea4\u6d41
      "},{"location":"community/#qpython-qq_1","title":"QPython\u5fae\u4fe1\u7fa4 & QQ\u7fa4","text":"

      QPython\u5fae\u4fe1\u7528\u6237\u7fa4\u7fa4\u5b9a\u4f4d\uff1aQPython\u4f7f\u7528\u4ea4\u6d41 | Python\u5b66\u4e60\u4e92\u52a9 | \u5b9e\u6218\u95ee\u9898\u89e3\u7b54\uff0c\u6dfb\u52a0\u52a9\u624b\u540e\u4f1a\u9080\u60a8\u52a0\u5165

      \u5fae\u4fe1\u7fa4\uff08\u52a9\u624b: learnwithqpy\uff09 QQ\u7fa4\uff08\u7fa4\u53f7: 862351102\uff09"},{"location":"community/#qpython-vip","title":"QPython \u77e5\u8bc6\u661f\u7403 VIP\u793e\u533a","text":"

      QPython\u5b98\u65b9\u4ed8\u8d39VIP\u4e13\u5c5e\u793e\u533a\uff0c\u4e3a\u6df1\u5ea6\u7528\u6237\u63d0\u4f9b\u5b98\u65b9\u56e2\u961f\u76f4\u8fde\u3001\u53ca\u65f6\u6280\u672f\u652f\u6301\u3001\u9ad8\u8d28\u91cf\u4ea4\u6d41\u7684\u4e13\u5c5e\u670d\u52a1\u7a7a\u95f4\u3002\u52a0\u5165VIP\u793e\u533a\u53ef\u83b7\u4e0b\u5217\u6838\u5fc3\u4ef7\u503c\uff1a

      • \ud83c\udfaf \u5b98\u65b9\u56e2\u961f\u76f4\u8fde \u2014\u2014 QPython\u5f00\u53d1\u56e2\u961f\u5728\u7ebf\u7b54\u7591\uff0c\u9047\u5230\u95ee\u9898\u4e0d\u518d\u5361\u58f3\uff0c\u6280\u672f\u96be\u9898\u5feb\u901f\u54cd\u5e94
      • \ud83d\ude80 \u4f18\u5148\u6280\u672f\u652f\u6301 \u2014\u2014 VIP\u7528\u6237\u4e13\u5c5e\u901a\u9053\uff0c\u6bd4\u516c\u5f00\u6e20\u9053\u66f4\u5feb\u83b7\u5f97\u5b98\u65b9\u89e3\u7b54
      • \ud83d\udca1 \u6df1\u5ea6\u4ea4\u6d41\u5708\u5b50 \u2014\u2014 \u4e0e\u6838\u5fc3\u7528\u6237\u3001\u8d44\u6df1\u5f00\u53d1\u8005\u540c\u884c\uff0c\u63a2\u8ba8\u9ad8\u9636\u6280\u5de7\u4e0e\u9879\u76ee\u5b9e\u6218

      QPython \u56e2\u961f\u4f1a\u5b9a\u671f\u5728\u793e\u533a\u4e2d\u66f4\u65b0\u9879\u76ee\u8fdb\u5c55\uff0c\u6b22\u8fce\u5173\u6ce8\uff01

      "},{"location":"editor-guide/","title":"\u4f7f\u7528\u6700\u4f73\u5f00\u53d1\u65b9\u5f0f","text":""},{"location":"editor-guide/#qeditor","title":"\u4ece QEditor \u5f00\u53d1","text":"

      QEditor \u662f QPython \u7684\u5185\u7f6e\u7f16\u8f91\u5668\uff0c\u652f\u6301 Python / HTML \u8bed\u6cd5\u9ad8\u4eae\u3002

      QEditor \u7684\u4e3b\u8981\u529f\u80fd

      • \u7f16\u8f91/\u67e5\u770b\u7eaf\u6587\u672c\u6587\u4ef6\uff0c\u5982 Python\u3001Lua\u3001HTML\u3001Javascript \u7b49

      • \u7f16\u8f91\u548c\u8fd0\u884c Python \u811a\u672c & Python \u8bed\u6cd5\u9ad8\u4eae

      • \u7f16\u8f91\u548c\u8fd0\u884c Shell \u811a\u672c

      • \u4f7f\u7528\u5185\u7f6e HTML \u6d4f\u89c8\u5668\u9884\u89c8 HTML

      • \u6309\u5173\u952e\u5b57\u641c\u7d22\u3001\u4ee3\u7801\u7247\u6bb5\u3001\u4ee3\u7801\u5206\u4eab

      \u60a8\u53ef\u4ee5\u76f4\u63a5\u5728 QEditor \u4e2d\u8fd0\u884c QPython \u811a\u672c\uff0c\u56e0\u6b64\u5728\u79fb\u52a8\u65f6\u8fd9\u662f QPython \u5f00\u53d1\u6700\u65b9\u4fbf\u7684\u65b9\u5f0f\u3002

      "},{"location":"editor-guide/#_2","title":"\u901a\u8fc7\u6d4f\u89c8\u5668\u5f00\u53d1","text":"

      QPython \u6709\u4e00\u4e2a\u5185\u7f6e\u811a\u672c qedit4web.py\uff0c\u5f53\u60a8\u70b9\u51fb\u5f00\u59cb\u6309\u94ae\u5e76\u9009\u62e9\"\u8fd0\u884c\u672c\u5730\u811a\u672c\"\u65f6\u53ef\u4ee5\u770b\u5230\u5b83\u3002

      \u8fd0\u884c\u540e\uff0c\u60a8\u53ef\u4ee5\u770b\u5230\u7ed3\u679c\u3002

      \u7136\u540e\uff0c\u60a8\u53ef\u4ee5\u901a\u8fc7 PC/\u7b14\u8bb0\u672c\u7535\u8111\u7684\u6d4f\u89c8\u5668\u8bbf\u95ee\u8be5\u7f51\u5740\u8fdb\u884c\u5f00\u53d1\uff0c\u5982\u4e0b\u56fe\u6240\u793a\u3002

      \u9009\u62e9\u67d0\u4e2a\u9879\u76ee\u6216\u811a\u672c\u540e\uff0c\u60a8\u53ef\u4ee5\u5f00\u59cb\u5f00\u53d1

      \u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\u7f16\u5199\u6d4f\u89c8\u5668\u4ee3\u7801\uff0c\u7136\u540e\u5728 Android \u624b\u673a\u4e0a\u8fd0\u884c\u3002\u975e\u5e38\u65b9\u4fbf\u3002

      "},{"location":"editor-guide/#_3","title":"\u4ece\u60a8\u7684\u7535\u8111\u5f00\u53d1","text":"

      \u9664\u4e86\u4e0a\u8ff0\u65b9\u6cd5\uff0c\u60a8\u8fd8\u53ef\u4ee5\u7528\u81ea\u5df1\u7684\u65b9\u5f0f\u5f00\u53d1\u811a\u672c\uff0c\u7136\u540e\u901a\u8fc7\u5185\u7f6e\u7684 FTP \u670d\u52a1\u5c06\u5176\u4e0a\u4f20\u5230\u624b\u673a\uff0c\u7528 QPython \u8fd0\u884c\u5b83\u3002

      "},{"location":"external-api/","title":"QPython \u5f00\u653e API","text":"

      QPython \u6709\u4e00\u4e2a\u5f00\u653e\u7684 activity\uff0c\u5141\u8bb8\u60a8\u4ece\u5916\u90e8\u8fd0\u884c qpython\u3002

      MPyAPI \u7684\u5b9a\u4e49\u5982\u4e0b\uff1a

          <activity\n        android:name=\"org.qpython.qpylib.MPyApi\"\n        android:label=\"@string/qpy_run_with_share\"\n        android:screenOrientation=\"user\"\n        android:configChanges=\"orientation|keyboardHidden\"\n        android:exported=\"true\">\n        <intent-filter>\n            <action android:name=\"org.qpython.qpylib.action.MPyApi\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.LAUNCHER\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.VIEW\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.BROWSABLE\" />\n            <data android:scheme=\"http\" />\n            <data android:scheme=\"https\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"text/plain\"/>\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"image/*\"/>\n        </intent-filter>\n    </activity>\n

      \u56e0\u6b64\uff0c\u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\uff1a

      "},{"location":"external-api/#qpython","title":"\u5c06\u5185\u5bb9\u5206\u4eab\u5230 QPython \u7684\u811a\u672c","text":"

      \u60a8\u53ef\u4ee5\u5728\u67d0\u4e2a\u5e94\u7528\u4e2d\u9009\u62e9\u4e00\u4e9b\u5185\u5bb9\uff0c\u7136\u540e\u5206\u4eab\u5230 qpython \u7684\u811a\u672c\uff0c\u4e4b\u540e\u60a8\u53ef\u4ee5\u4f7f\u7528 sys.argv[2] \u5904\u7406\u8fd9\u4e9b\u5185\u5bb9

      \u5728 YouTube \u4e0a\u89c2\u770b\u6f14\u793a\u89c6\u9891

      "},{"location":"external-api/#qpython_1","title":"\u4ece\u60a8\u81ea\u5df1\u7684\u5e94\u7528\u7a0b\u5e8f\u8fd0\u884c QPython \u7684\u811a\u672c","text":"

      \u60a8\u53ef\u4ee5\u901a\u8fc7\u8c03\u7528\u6b64 activity \u5728\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u4e2d\u8c03\u7528 QPython \u6765\u8fd0\u884c\u67d0\u4e9b\u811a\u672c\u6216 Python \u4ee3\u7801\uff0c\u793a\u4f8b\u5982\u4e0b\uff1a

      // \u5c55\u793a\u5982\u4f55\u8c03\u7528 qpython API \u7684\u4ee3\u7801\u793a\u4f8b\nString extPlgPlusName = \"org.qpython.qpy\";          // QPython \u5305\u540d\nIntent intent = new Intent();\nintent.setClassName(extPlgPlusName, \"org.qpython.qpylib.MPyApi\");\nintent.setAction(extPlgPlusName + \".action.MPyApi\");\n\nBundle mBundle = new Bundle();\nmBundle.putString(\"app\", \"myappid\");\nmBundle.putString(\"act\", \"onPyApi\");\nmBundle.putString(\"flag\", \"onQPyExec\"); // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u4efb\u610f\u5b57\u7b26\u4e32\u6807\u5fd7\nmBundle.putString(\"param\", \"\");         // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u53c2\u6570\u5b57\u7b26\u4e32\n\n/*\n* \u6211\u4eec\u5c06\u8fd0\u884c\u7684 Python \u4ee3\u7801\n*/\nString code = \"import androidhelper\\n\" +\n            \"droid = androidhelper.Android()\\n\" +\n            \"line = droid.dialogGetInput()\\n\" +\n            \"s = 'Hello %s' % line.result\\n\" +\n            \"droid.makeToast(s)\\n\"\n\nmBundle.putString(\"pycode\", code);\nintent.putExtras(mBundle);\nstartActivityForResult(intent, SCRIPT_EXEC_PY);\n...\n\n// \u60a8\u53ef\u4ee5\u5728 onActivityResult \u4e2d\u5904\u7406 qpython \u8c03\u7528\u7ed3\u679c\n@Override\nprotected void onActivityResult(int requestCode, int resultCode, Intent data) {\n    if (requestCode == SCRIPT_EXEC_PY) {\n        if (data!=null) {\n            Bundle bundle = data.getExtras();\n            String flag = bundle.getString(\"flag\");\n            String param = bundle.getString(\"param\");\n            String result = bundle.getString(\"result\"); // \u60a8\u7684 Pycode \u751f\u6210\u7684\u7ed3\u679c\n            Toast.makeText(this, \"onQPyExec: return (\"+result+\")\", Toast.LENGTH_SHORT).show();\n        } else {\n            Toast.makeText(this, \"onQPyExec: data is null\", Toast.LENGTH_SHORT).show();\n\n        }\n    }\n}\n

      \u4ece github \u68c0\u51fa\u4e00\u4e2a\u5b8c\u6574\u9879\u76ee

      \u8fd8\u6709\u4e00\u4e2a\u751f\u4ea7\u5e94\u7528\u7a0b\u5e8f - \u9762\u5411 Tasker \u7684 QPython \u63d2\u4ef6

      "},{"location":"getting-started/","title":"QPython\uff1a\u5165\u95e8\u6307\u5357","text":"

      \u672c\u6307\u5357\u5c06\u4ecb\u7ecd QPython \u7684\u529f\u80fd\u5e76\u5e2e\u52a9\u60a8\u5feb\u901f\u5165\u95e8\u3002

      "},{"location":"getting-started/#qpython_1","title":"QPython \u6982\u8ff0","text":"

      \u4e3a\u4ec0\u4e48\u9009\u62e9 QPython\uff1f

      \u667a\u80fd\u624b\u673a\u5df2\u6210\u4e3a\u4eba\u4eec\u5fc5\u5907\u7684\u4fe1\u606f\u548c\u6280\u672f\u52a9\u624b\uff0c\u4e00\u4e2a\u7075\u6d3b\u7684\u89e3\u91ca\u5668\u5f15\u64ce\u53ef\u4ee5\u5e2e\u52a9\u60a8\u9ad8\u6548\u5b8c\u6210\u5927\u90e8\u5206\u5de5\u4f5c\uff0c\u65e0\u9700\u590d\u6742\u7684\u5f00\u53d1\u8fc7\u7a0b\u3002

      QPython \u63d0\u4f9b\u4e86 \u60ca\u4eba\u7684\u5f00\u53d1\u4f53\u9a8c\u2014\u2014\u501f\u52a9\u5b83\u7684\u5e2e\u52a9\uff0c\u60a8\u53ef\u4ee5\u8f7b\u677e\u5b9e\u73b0\u7a0b\u5e8f\uff0c\u65e0\u9700\u590d\u6742\u7684 IDE \u5b89\u88c5\u3001\u7f16\u8bd1\u6216\u6253\u5305\u8fc7\u7a0b\u3002

      "},{"location":"getting-started/#qpython_2","title":"QPython \u7248\u672c","text":"

      \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

      • QPython \u2013 \u7531 QPython \u56e2\u961f\u7ef4\u62a4\u7684\u4e3b\u8981\u7248\u672c\uff0c\u5177\u5907 AI \u529f\u80fd\uff0c\u53ef\u5728 Google Play \u7b49\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d
      • QPython+ \u2013 \u7531\u5f00\u6e90\u8d21\u732e\u8005\u63a8\u51fa\u7684\u793e\u533a\u7248\uff0c\u63d0\u4f9b\u5404\u79cd\u65b0\u7279\u6027
      • QPython Plus \u2013 \u6269\u5c55\u6743\u9650\u7248\u672c\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff09
      "},{"location":"getting-started/#_1","title":"\u4e3b\u8981\u7279\u6027","text":"
      • \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668 - \u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51
      • QSL4A \u96c6\u6210 - \u4f7f\u7528 Python \u63a7\u5236 Android \u786c\u4ef6\u548c API
      • GenAI \u80fd\u529b\u96c6\u6210 - \u652f\u6301\u672c\u5730\u8fd0\u884c\u7684 LLM\u3001OpenAI \u7b49\u5404\u79cd LLM \u5e93\uff0c\u4ee5\u53ca\u53ef\u5728 QPython \u4e0a\u8fdb\u884c Vibe Coding \u5f00\u53d1\u7684 AIPyApp
      • \u6269\u5c55\u5305\u5b89\u88c5 - \u652f\u6301\u901a\u8fc7 QPYPI \u548c pip \u5b89\u88c5\u6269\u5c55\u5305
      • \u5185\u7f6e\u7f16\u8f91\u5668 - \u8bed\u6cd5\u9ad8\u4eae\u548c\u4ee3\u7801\u7f16\u8f91
      • \u591a\u79cd\u8fd0\u884c\u6a21\u5f0f - \u9664\u63a7\u5236\u53f0\u7a0b\u5e8f\u5916\uff0c\u8fd8\u652f\u6301 Android \u539f\u751f UI\uff08\u901a\u8fc7 QSL4A \u63a5\u53e3\uff09\u4ee5\u53ca Pygame / Turtle / Tkinter \u7b49\u8fd0\u884c\u65b9\u5f0f
      "},{"location":"getting-started/#1","title":"1. \u4eea\u8868\u76d8","text":"

      \u5b89\u88c5 QPython \u540e\uff0c\u70b9\u51fb\u5176\u56fe\u6807\u542f\u52a8\u3002\u60a8\u5c06\u770b\u5230\u5e26\u6709 QPython \u6807\u5fd7\u548c\u4ee5\u4e0b\u529f\u80fd\u7684\u4e3b\u4eea\u8868\u76d8\uff1a

      "},{"location":"getting-started/#_2","title":"\u4eea\u8868\u76d8\u529f\u80fd","text":"

      QPython \u4eea\u8868\u76d8\u63d0\u4f9b\u5bf9\u6240\u6709\u4e3b\u8981\u529f\u80fd\u7684\u5feb\u901f\u8bbf\u95ee\uff1a

      • \u7ec8\u7aef \u2014 \u8bbf\u95ee Python \u63a7\u5236\u53f0\u548c shell \u4ee5\u76f4\u63a5\u6267\u884c\u547d\u4ee4
      • Notebook \u2014 \u7528\u4e8e\u6570\u636e\u5206\u6790\u548c\u5b9e\u9a8c\u7684\u4ea4\u4e92\u5f0f Jupyter \u98ce\u683c\u7b14\u8bb0\u672c
      • \u7f16\u8f91\u5668 \u2014 \u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668\uff0c\u5177\u6709\u8bed\u6cd5\u9ad8\u4eae\u529f\u80fd\uff0c\u7528\u4e8e\u7f16\u5199 Python \u811a\u672c
      • \u8d44\u6e90\u7ba1\u7406\u5668 \u2014 \u6d4f\u89c8\u548c\u7ba1\u7406\u60a8\u7684\u6587\u4ef6\u3001\u811a\u672c\u548c\u9879\u76ee
      • QPYPI \u2014 \u5b89\u88c5 Python \u5305\u548c\u6269\u5c55\u3002\u8be6\u89c1 QPYPI \u6307\u5357
      • \u8bbe\u7f6e \u2014 \u914d\u7f6e QPython \u9996\u9009\u9879\u548c\u8fd0\u884c\u9009\u9879
      • \u793e\u533a \u2014 \u8bbf\u95ee QPython \u793e\u533a\u8d44\u6e90\u3001\u8bba\u575b\u548c\u5e2e\u52a9
      • \u8bfe\u7a0b \u2014 \u8bbf\u95ee Python \u7f16\u7a0b\u7684\u5b66\u4e60\u6750\u6599\u548c\u6559\u7a0b

      \u70b9\u51fb\u4efb\u4f55\u56fe\u6807\u4ee5\u8bbf\u95ee\u76f8\u5e94\u7684\u529f\u80fd\u3002

      "},{"location":"getting-started/#2","title":"2. \u7ec8\u7aef\u548c\u7f16\u8f91\u5668","text":""},{"location":"getting-started/#_3","title":"\u7ec8\u7aef","text":"

      \u7ec8\u7aef\u63d0\u4f9b Python \u63a7\u5236\u53f0\uff0c\u652f\u6301\uff1a - \u63a2\u7d22\u5bf9\u8c61\u5c5e\u6027 - \u6d4b\u8bd5\u8bed\u6cd5\u548c\u60f3\u6cd5 - \u76f4\u63a5\u6267\u884c\u547d\u4ee4

      \u4f7f\u7528\u52a0\u53f7\u6309\u94ae\uff081\uff09\u6253\u5f00\u65b0\u7ec8\u7aef\u6807\u7b7e\u9875\uff0c\u901a\u8fc7\u4e0b\u62c9\u83dc\u5355\uff082\uff09\u5207\u6362\uff0c\u5e76\u4f7f\u7528\u5173\u95ed\u6309\u94ae\uff083\uff09\u5173\u95ed\u3002

      "},{"location":"getting-started/#_4","title":"\u7f16\u8f91\u5668","text":"

      \u7f16\u8f91\u5668\u5e95\u90e8\u529f\u80fd\u680f\u5305\u542b\u4ee5\u4e0b\u5de5\u5177\uff08\u4ece\u5de6\u5230\u53f3\uff09\uff1a

      • \u5207\u6362\u5feb\u6377\u8f93\u5165\uff08\u5305\u542b def / if / else / elif / class \u7b49\u5173\u952e\u8bcd\uff09
      • \u9501\u5b9a\uff08\u9632\u6b62\u8bef\u89e6\uff09
      • \u8df3\u8f6c
      • \u4fdd\u5b58
      • \u8fd0\u884c
      • \u641c\u7d22
      • \u64a4\u9500
      • \u91cd\u505a
      • \u53e6\u5b58
      • \u6700\u8fd1\u6587\u4ef6
      • \u4ee3\u7801\u7247\u6bb5

      \u91cd\u8981\u63d0\u793a\uff1a \u4fdd\u5b58\u65f6\u8bf7\u624b\u52a8\u6dfb\u52a0 .py \u6269\u5c55\u540d\uff0c\u56e0\u4e3a\u7f16\u8f91\u5668\u4e0d\u4f1a\u81ea\u52a8\u6dfb\u52a0\u3002

      "},{"location":"getting-started/#3","title":"3. \u8d44\u6e90\u7ba1\u7406\u5668\uff08\u6587\u4ef6\u7ba1\u7406\uff09","text":"

      \u901a\u8fc7 \u8d44\u6e90\u7ba1\u7406\u5668 \u8bbf\u95ee\u811a\u672c\u548c\u9879\u76ee\uff0c\u652f\u6301\u6d4f\u89c8\u3001\u7ec4\u7ec7\u548c\u7ba1\u7406\u6240\u6709 Python \u6587\u4ef6\u3002

      "},{"location":"getting-started/#_5","title":"\u811a\u672c","text":"

      \u811a\u672c\u662f\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/scripts3/ \u4e2d\u7684\u5355\u4e2a Python \u6587\u4ef6\uff08\u9488\u5bf9 Python 3\uff09\u3002

      \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u811a\u672c - \u6253\u5f00 \u2014 \u4f7f\u7528\u5185\u7f6e\u7f16\u8f91\u5668\u7f16\u8f91 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u811a\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u811a\u672c

      "},{"location":"getting-started/#_6","title":"\u9879\u76ee","text":"

      \u9879\u76ee\u662f\u5305\u542b main.py \u4f5c\u4e3a\u5165\u53e3\u70b9\u7684\u76ee\u5f55\u3002\u60a8\u53ef\u4ee5\u5728\u540c\u4e00\u76ee\u5f55\u4e2d\u5305\u542b\u5176\u4ed6\u4f9d\u8d56\u9879\u548c\u8d44\u6e90\u3002\u5c06\u9879\u76ee\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/projects3/ \u4e2d\u3002

      "},{"location":"getting-started/#_7","title":"\u7b14\u8bb0\u672c","text":"

      Jupyter \u98ce\u683c\u7684\u7b14\u8bb0\u672c\u4e5f\u901a\u8fc7\u8d44\u6e90\u7ba1\u7406\u5668\u8fdb\u884c\u7ba1\u7406\uff0c\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/notebooks/ \u4e2d\u3002

      \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u7b14\u8bb0\u672c - \u6253\u5f00 \u2014 \u63a2\u7d22\u7b14\u8bb0\u672c\u5185\u5bb9 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u7b14\u8bb0\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u7b14\u8bb0\u672c

      "},{"location":"getting-started/#4","title":"4. \u5e93","text":"

      \u901a\u8fc7\u5b89\u88c5\u7b2c\u4e09\u65b9\u5e93\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

      "},{"location":"getting-started/#_8","title":"\u5305\u5b89\u88c5\u65b9\u6cd5","text":"

      QPYPI\uff08\u63a8\u8350\uff09

      \u4ece QPYPI \u5b89\u88c5\u9884\u7f16\u8bd1\u7684\u5e93\uff0c\u5305\u62ec numpy\u3001scipy \u7b49\u79d1\u5b66\u5305\u3002

      \u8be6\u89c1 QPYPI \u6307\u5357\u3002

      PIP \u5ba2\u6237\u7aef

      \u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216 QPYPI \u754c\u9762\u5b89\u88c5\u7eaf Python \u5e93\uff1a

      pip install requests\n

      \u9884\u7f16\u8bd1\u5305

      \u5bf9\u4e8e\u5177\u6709 C/C++/Rust \u4f9d\u8d56\u7684\u5305\uff0c\u4f7f\u7528 QPython \u7684\u9884\u7f16\u8bd1\u5305\uff1a

      pip install numpy-qpython\npip install scipy-aipy\n

      \u8be6\u89c1 QPYPI \u6307\u5357 \u83b7\u53d6\u53ef\u7528\u5305\u7684\u5b8c\u6574\u5217\u8868\u3002

      \u624b\u52a8\u5b89\u88c5

      \u60a8\u4e5f\u53ef\u4ee5\u5c06\u5e93\u590d\u5236\u5230 /storage/emulated/0/Android/data/org.qpython.qpy/files/lib/python3.12/site-packages/\u3002

      "},{"location":"getting-started/#5","title":"5. \u8fd0\u884c\u6a21\u5f0f","text":"

      QPython \u652f\u6301\u591a\u79cd\u8fd0\u884c\u6a21\u5f0f\u4ee5\u6ee1\u8db3\u4e0d\u540c\u7684\u7528\u4f8b\uff1a

      "},{"location":"getting-started/#_9","title":"\u63a7\u5236\u53f0\u6a21\u5f0f","text":"

      \u5e38\u89c4 Python \u811a\u672c\u7684\u9ed8\u8ba4\u6a21\u5f0f\u3002

      "},{"location":"getting-started/#qsl4a","title":"QSL4A \u6a21\u5f0f","text":"

      \u901a\u8fc7 QSL4A \u5e93\u8c03\u7528 Android API \u7684\u811a\u672c\u3002

      import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello Android!')\n

      \u8be6\u89c1 QSL4A \u6587\u6863 \u83b7\u53d6\u5b8c\u6574\u7684 API \u53c2\u8003\u3002

      "},{"location":"getting-started/#webapp","title":"WebApp \u6a21\u5f0f","text":"

      \u4f7f\u7528\u540e\u7aef\u670d\u52a1\u5668\u521b\u5efa\u57fa\u4e8e Web \u7684\u5e94\u7528\u7a0b\u5e8f\u3002\u9700\u5728\u811a\u672c\u5f00\u5934\u6dfb\u52a0\u4ee5\u4e0b\u4e24\u884c headers\uff1a

      #qpy:webapp:<\u9879\u76ee\u540d>\n#qpy://localhost:<web\u670d\u52a1\u4fa6\u542c\u7684\u7aef\u53e3>/<\u9ed8\u8ba4\u4e3b\u8def\u5f84>\n

      \u4f8b\u5982\uff1a

      #qpy:webapp:Hello QPython\n#qpy://localhost:8080/hello\n\nfrom bottle import route, run, Bottle\n\napp = Bottle()\n\n@route('/hello')\ndef hello():\n    return '<h1>Hello from QPython!</h1>'\n\nrun(app, host='localhost', port=8080)\n
      "},{"location":"getting-started/#q","title":"Q \u6a21\u5f0f\uff08\u65e0\u63a7\u5236\u53f0\u6a21\u5f0f\uff09","text":"

      \u9759\u9ed8\u6a21\u5f0f\u8fd0\u884c\u811a\u672c\uff0c\u4e0d\u663e\u793a\u63a7\u5236\u53f0\u3002\u9700\u5728\u811a\u672c\u5f00\u5934\u6dfb\u52a0 header\uff1a

      #qpy:quiet\n\nimport time\n\nwhile True:\n    # \u60a8\u7684\u540e\u53f0\u4efb\u52a1\n    time.sleep(60)\n
      \u5982\u679c\u9700\u8981\u8fd0\u884c\u5e26 GUI \u7684 QSL4A \u7a0b\u5e8f\u4e14\u4e0d\u5e0c\u671b\u663e\u793a\u63a7\u5236\u53f0\u4fe1\u606f\uff0c\u63a8\u8350\u4f7f\u7528\u6b64\u6a21\u5f0f\u3002

      "},{"location":"getting-started/#6","title":"6. \u793e\u533a\u4e0e\u652f\u6301","text":"

      \u8bbf\u95ee QPython.org \u83b7\u53d6\u6587\u6863\u3001\u7528\u6237\u793e\u533a\u53ca\u5e2e\u52a9\u95ee\u7b54\u3002

      \u793e\u533a\u94fe\u63a5\uff1a - Facebook \u7fa4\u7ec4 - GitHub - \u95ee\u9898\u53cd\u9988

      \u4e0b\u4e00\u6b65\uff1a - \u5c1d\u8bd5 Hello World \u6559\u7a0b - \u63a2\u7d22 QSL4A API \u4ee5\u96c6\u6210 Android - \u4e86\u89e3 QPython \u7248\u672c

      "},{"location":"getting-started/#_10","title":"\u89c6\u9891\u4ecb\u7ecd","text":""},{"location":"getting-started/#_11","title":"\u4e0b\u4e00\u6b65","text":"

      \u5982\u679c\u60a8\u5df2\u7ecf\u521d\u6b65\u4e86\u89e3\u4e86 QPython \u7684\u529f\u80fd\uff0c\u6b22\u8fce\u5f00\u59cb\u4f53\u9a8c\u7f16\u7a0b\u7684\u4e50\u8da3\uff01\u8bd5\u8bd5 Hello World \u6559\u7a0b \u8fc8\u51fa\u60a8\u7684\u7b2c\u4e00\u6b65\u3002

      "},{"location":"qpypi-guide/","title":"QPYPI","text":"

      \u60a8\u53ef\u4ee5\u901a\u8fc7\u5b89\u88c5\u5305\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

      "},{"location":"qpypi-guide/#_1","title":"\u5305\u5b89\u88c5\u652f\u6301","text":""},{"location":"qpypi-guide/#python","title":"\u7eaf Python \u5305","text":"

      QPython \u652f\u6301\u4f7f\u7528\u7eaf Python \u5f00\u53d1\u7684 Python \u5305\u3002\u60a8\u53ef\u4ee5\u76f4\u63a5\u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216\u4eea\u8868\u76d8\u4e0a\u7684 QPYPI \u4f7f\u7528 pip install \u5b89\u88c5\u8fd9\u4e9b\u5305\u3002

      "},{"location":"qpypi-guide/#_2","title":"\u9884\u7f16\u8bd1\u5305","text":"

      \u5982\u679c\u67d0\u4e9b\u5305\uff08\u6216\u5b83\u4eec\u7684\u4f9d\u8d56\uff09\u662f\u7528 Rust/C/C++ \u5f00\u53d1\u7684\uff0cQPython \u65e0\u6cd5\u76f4\u63a5\u652f\u6301\u5b83\u4eec\uff0c\u56e0\u4e3a QPython \u4e0a\u6ca1\u6709\u7f16\u8bd1\u5668\u5de5\u5177\u94fe\u652f\u6301\u3002\u4f46\u662f\uff0cQPython \u56e2\u961f\u5df2\u7ecf\u9884\u7f16\u8bd1\u4e86\u4e00\u4e9b\u5e38\u7528\u5305\uff0c\u5e76\u5728 QPython \u7684 QPYPI/Extensions \u4e2d\u53d1\u5e03\uff0c\u4f9b\u7528\u6237\u8f7b\u677e\u5b89\u88c5\u3002

      "},{"location":"qpypi-guide/#_3","title":"\u5b89\u88c5\u9884\u7f16\u8bd1\u5305","text":"

      \u60a8\u53ef\u4ee5\u901a\u8fc7\u4ee5\u4e0b\u65b9\u5f0f\u5b89\u88c5\u9884\u7f16\u8bd1\u5305\uff1a

      1. \u901a\u8fc7 QPython \u5e94\u7528\uff1a\u76f4\u63a5\u4ece QPython \u5e94\u7528\u5185\u7684 QPYPI \u6216 Extensions \u5b89\u88c5
      2. \u901a\u8fc7 PyPI\uff1a\u8bbf\u95ee https://pypi.org/user/qpythonx/ \u67e5\u770b\u53ef\u7528\u7684\u5305
      3. \u901a\u8fc7 pip \u547d\u4ee4\uff1a
      4. pip install xxx-qpython - \u5e26 -qpython \u540e\u7f00\u7684\u5305
      5. pip install xxx-aipy - \u5e26 -aipy \u540e\u7f00\u7684\u5305\uff08\u901a\u5e38\u662f AI/ML \u76f8\u5173\u7684\u5305\uff09

      \u6ce8\u610f\uff1a\u6211\u4eec\u901a\u5e38\u6839\u636e\u5305\u7684\u9884\u671f\u7528\u9014\u6dfb\u52a0\u8fd9\u4e9b\u540e\u7f00\u4e4b\u4e00\u3002

      "},{"location":"qpypi-guide/#_4","title":"\u8bf7\u6c42\u65b0\u5305","text":"

      \u5982\u679c\u60a8\u9700\u8981\u5f53\u524d\u4e0d\u652f\u6301\u7684\u5305\uff1a

      • \u5728 qpython.org \u9879\u76ee \u4e2d\u63d0\u51fa\u95ee\u9898
      • QPython \u56e2\u961f\u5c06\u8003\u8651\u9884\u7f16\u8bd1\u5e76\u5c06\u5176\u6dfb\u52a0\u5230\u4ed3\u5e93\u4e2d

      \u83b7\u53d6\u66f4\u591a\u5e2e\u52a9\u548c\u53c2\u4e0e\u793e\u533a\u7684\u65b9\u5f0f\uff0c\u8bf7\u53c2\u9605 \u793e\u533a\u4e0e\u53cd\u9988 \u90e8\u5206\u3002

      \u6ce8\u610f\uff1a\u7531\u4e8e\u4e0d\u540c\u7684\u8ba1\u7b97\u673a\u67b6\u6784\uff0c\u6211\u4eec\u65e0\u6cd5\u4fdd\u8bc1 QPYPI \u5305\u542b PyPI \u4e0a\u7684\u6240\u6709\u5305\u3002

      "},{"location":"qpython-x/","title":"QPython \u7248\u672c","text":"

      QPython \u662f Android \u7684 Python \u5f15\u64ce\u3002\u5b83\u5305\u542b\u4ee4\u4eba\u60ca\u53f9\u7684\u529f\u80fd\uff0c\u5982 Python \u89e3\u91ca\u5668\u3001\u8fd0\u884c\u73af\u5883\u3001\u7f16\u8f91\u5668\u3001QPYI \u548c\u96c6\u6210\u7684 SL4A\u3002\u5b83\u8ba9\u60a8\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 Android \u4e0a\u4f7f\u7528 Python\u3002\u800c\u4e14\u5b83\u662f\u514d\u8d39\u7684\u3002

      QPython \u5df2\u7ecf\u5728\u5168\u7403\u62e5\u6709\u6570\u767e\u4e07\u7528\u6237\uff0c\u4e5f\u662f\u4e00\u4e2a\u5f00\u6e90\u9879\u76ee\u3002

      \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

      "},{"location":"qpython-x/#qpython_1","title":"QPython","text":"

      \u6807\u51c6\u7248\uff1a\u9488\u5bf9 AI \u6027\u80fd\u548c\u901a\u7528\u5e94\u7528\u5546\u5e97\u517c\u5bb9\u6027\u4f18\u5316

      \u4e3b\u8981\u7248\u672c\uff0c\u53ef\u5728 Google Play \u548c\u5176\u4ed6\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002\u6b64\u7248\u672c\u4e13\u6ce8\u4e8e AI \u529f\u80fd\uff0c\u4f7f AI \u65f6\u4ee3\u7528\u6237\u66f4\u5bb9\u6613\u5b66\u4e60\u548c\u4f7f\u7528 Python\u3002

      \u4e3b\u8981\u7279\u6027\uff1a - AI \u9a71\u52a8\u7684\u7f16\u7801\u8f85\u52a9\u548c\u5b66\u4e60\u5de5\u5177 - \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668\uff1a\u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51 - \u652f\u6301\u591a\u79cd\u9879\u76ee\u7c7b\u578b\uff1a\u63a7\u5236\u53f0\u3001SL4A\u3001WebApp - \u65b9\u4fbf\u7684\u4e8c\u7ef4\u7801\u8bfb\u53d6\u5668\uff0c\u7528\u4e8e\u5c06\u4ee3\u7801\u4f20\u8f93\u5230\u624b\u673a - QPYPI \u548c\u81ea\u5b9a\u4e49\u4ed3\u5e93\uff0c\u7528\u4e8e\u9884\u7f16\u8bd1 wheel \u5305 -\u6613\u4e8e\u4f7f\u7528\u7684\u8bed\u6cd5\u9ad8\u4eae\u7f16\u8f91\u5668 - \u5b8c\u5584\u7684\u6587\u6863\u548c\u793e\u533a\u652f\u6301

      \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

      \u4e0b\u8f7d\uff1a \u53ef\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

      "},{"location":"qpython-x/#qpython_2","title":"QPython+","text":"

      \u793e\u533a\u7248\uff1a\u516c\u5f00\u652f\u6301\u5404\u79cd\u793e\u533a\u9a71\u52a8\u7684\u529f\u80fd\uff1b\u53ef\u5728\u90e8\u5206\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

      \u793e\u533a\u5f00\u6e90\u7248\u672c\uff08\u6b63\u5728\u89c4\u5212\u548c\u51c6\u5907\u4e2d\uff09\u3002\u6b64\u7248\u672c\u4e13\u4e3a\u60f3\u8981\u53c2\u4e0e QPython \u9879\u76ee\u5f00\u53d1\u7684\u8d21\u732e\u8005\u800c\u8bbe\u8ba1\uff0c\u652f\u6301\u9488\u5bf9\u4e0d\u540c\u5236\u9020\u5546\u7684\u5b9a\u5236\u3002

      \u4e3b\u8981\u7279\u6027\uff1a - \u793e\u533a\u9a71\u52a8\u5f00\u53d1 - \u652f\u6301\u4f9b\u5e94\u5546\u5b9a\u5236 - \u66f4\u7075\u6d3b\u7684\u914d\u7f6e\u9009\u9879 - \u5f00\u653e\u4f9b\u8d21\u732e\u8005\u52a0\u5165\u5f00\u53d1

      \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

      \u4e0b\u8f7d\uff1a \u5c06\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

      \u6ce8\u610f\uff1a \u6b64\u7248\u672c\u76ee\u524d\u6b63\u5728\u89c4\u5212\u51c6\u5907\u4e2d\u3002\u8bf7\u5173\u6ce8\u66f4\u65b0\uff01

      "},{"location":"qpython-x/#qpython-plus","title":"QPython Plus","text":"

      QPython+ \u5b8c\u5168\u8bbf\u95ee\u7248\uff1a\u6388\u4e88\u8c03\u7528\u6240\u6709 Android \u63a5\u53e3\u7684\u5b8c\u6574\u6743\u9650\u3002\u4e0b\u8f7d\u94fe\u63a5\u4ec5\u901a\u8fc7\u5b98\u65b9\u4e91\u76d8\u63d0\u4f9b\u3002

      \u5177\u6709\u6269\u5c55\u6743\u9650\u7684\u7279\u6b8a\u7248\u672c\uff0c\u63d0\u4f9b\u5bf9\u8bbe\u5907\u7684\u6700\u5927\u63a7\u5236\u3002\u7531\u4e8e\u5176\u654f\u611f\u7684\u6743\u9650\u8981\u6c42\uff0c\u6b64\u7248\u672c\u4e0d\u4f1a\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u53d1\u5e03\u3002

      \u4e3b\u8981\u7279\u6027\uff1a - \u5b8c\u6574\u7684 SL4A API \u8bbf\u95ee\uff0c\u5305\u62ec\u654f\u611f\u529f\u80fd - SMS/\u901a\u8bdd\u63a7\u5236 API - \u9ad8\u7ea7\u7cfb\u7edf\u96c6\u6210 - \u6700\u5927\u7684\u8bbe\u5907\u63a7\u5236\u80fd\u529b

      \u6743\u9650\uff1a \u9700\u8981\u5e7f\u6cdb\u7684\u6743\u9650\uff0c\u5305\u62ec\uff1a - \u84dd\u7259 - \u4f4d\u7f6e\uff08GPS\uff09 - \u8bfb\u53d6/\u53d1\u9001\u77ed\u4fe1 - \u6253\u7535\u8bdd - \u76f8\u673a\u548c\u9ea6\u514b\u98ce - \u7cfb\u7edf\u8bbe\u7f6e - \u4ee5\u53ca\u5176\u4ed6\u654f\u611f\u6743\u9650

      \u4e0b\u8f7d\uff1a \u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\u3002\u4ec5\u901a\u8fc7\u7279\u6b8a\u6e20\u9053\u5206\u53d1\u3002

      \u91cd\u8981\u63d0\u793a\uff1a QPython \u4e0d\u4f1a\u5728\u540e\u53f0\u672a\u7ecf\u60a8\u77e5\u6089\u4f7f\u7528\u8fd9\u4e9b\u6743\u9650\u3002\u5982\u679c\u4f7f\u7528 SL4A API \u65f6\u51fa\u73b0\u5f02\u5e38\uff0c\u8bf7\u68c0\u67e5\u7cfb\u7edf\u8bbe\u7f6e\u4e2d\u662f\u5426\u5df2\u542f\u7528\u76f8\u5173\u6743\u9650\u3002

      "},{"location":"tutorial-hello-world/","title":"\u7f16\u5199\"Hello World\"","text":""},{"location":"tutorial-hello-world/#hello-world_1","title":"Hello world","text":"

      \u597d\u7684\uff0c\u5728\u60a8\u5bf9 QPython \u6709\u4e86\u4e00\u5b9a\u7684\u4e86\u89e3\u4e4b\u540e\uff0c\u8ba9\u6211\u4eec\u5728 QPython \u4e2d\u521b\u5efa\u6211\u4eec\u7684\u7b2c\u4e00\u4e2a\u7a0b\u5e8f\u3002\u663e\u7136\uff0c\u5b83\u5c06\u662f helloworld.py\u3002;)

      \u542f\u52a8 QPython\uff0c\u6253\u5f00\u7f16\u8f91\u5668\u5e76\u8f93\u5165\u4ee5\u4e0b\u4ee3\u7801\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello, QPYTHON!')\n

      \u6beb\u65e0\u7591\u95ee\uff0c\u5b83\u4e0e\u5176\u4ed6\u4efb\u4f55 hello-world \u7a0b\u5e8f\u5e76\u65e0\u4e0d\u540c\u3002\u6267\u884c\u65f6\uff0c\u5b83\u53ea\u662f\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u5f39\u51fa\u6d88\u606f\uff08\u89c1\u9876\u90e8\u622a\u56fe\uff09\u3002\u65e0\u8bba\u5982\u4f55\uff0c\u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684 QPython \u7a0b\u5e8f\u793a\u4f8b\u3002

      "},{"location":"tutorial-hello-world/#_1","title":"\u4ee3\u7801\u7406\u89e3","text":"

      \u5b83\u4ee5 import androidhelper \u5f00\u5934\u2014\u2014\u8fd9\u662f QPython \u4e2d\u6700\u6709\u7528\u7684\u6a21\u5757\uff0c\u5b83\u5c01\u88c5\u4e86 Python \u4e2d\u53ef\u7528\u7684\u51e0\u4e4e\u6240\u6709\u4e0e Android \u7684\u63a5\u53e3\u3002\u4efb\u4f55\u5728 QPython \u4e2d\u5f00\u53d1\u7684\u811a\u672c\u90fd\u4ee5\u8fd9\u4e2a\u8bed\u53e5\u5f00\u5934\uff08\u81f3\u5c11\u5982\u679c\u5b83\u58f0\u79f0\u8981\u4e0e\u7528\u6237\u901a\u4fe1\u7684\u8bdd\uff09\u3002\u5728\u6b64\u5904\u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u5e93 \u548c import \u8bed\u53e5 \u7684\u5185\u5bb9\u3002

      \u63a5\u4e0b\u6765\u6211\u4eec\u521b\u5efa\u4e00\u4e2a droid \u5bf9\u8c61\uff08\u5b9e\u9645\u4e0a\u662f\u4e00\u4e2a\u7c7b\uff09\uff0c\u5b83\u5bf9\u4e8e\u8c03\u7528 RPC \u51fd\u6570\u4ee5\u4e0e Android \u901a\u4fe1\u662f\u5fc5\u8981\u7684\u3002

      \u6211\u4eec\u4ee3\u7801\u7684\u6700\u540e\u4e00\u884c\u8c03\u7528\u4e86\u8fd9\u6837\u7684\u51fd\u6570\uff0cdroid.makeToast()\uff0c\u5b83\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u4e00\u4e2a\u5c0f\u7684\u5f39\u51fa\u6d88\u606f\uff08\"toast\"\uff09\u3002

      \u597d\u7684\uff0c\u8ba9\u6211\u4eec\u6dfb\u52a0\u4e00\u4e9b\u66f4\u591a\u7684\u529f\u80fd\u3002\u8ba9\u5b83\u8be2\u95ee\u7528\u6237\u540d\u5e76\u5411\u7528\u6237\u6253\u62db\u547c\u3002

      "},{"location":"tutorial-hello-world/#_2","title":"\u66f4\u591a\u793a\u4f8b","text":"

      \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 dialogGetInput \u8c03\u7528\u663e\u793a\u4e00\u4e2a\u5e26\u6709\u6807\u9898\u3001\u63d0\u793a\u3001\u7f16\u8f91\u5b57\u6bb5\u548c \u786e\u5b9a \u548c \u53d6\u6d88 \u6309\u94ae\u7684\u7b80\u5355\u5bf9\u8bdd\u6846\u3002\u7528\u4ee5\u4e0b\u4ee3\u7801\u66ff\u6362\u60a8\u7684\u6700\u540e\u4e00\u884c\u4ee3\u7801\u5e76\u5c06\u5176\u4fdd\u5b58\u4e3a hello1.py\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\n

      \u597d\u7684\uff0c\u6211\u8ba4\u4e3a\u5b83\u5e94\u8be5\u8fd4\u56de\u4efb\u4f55\u54cd\u5e94\uff0c\u4efb\u4f55\u7528\u6237\u53cd\u5e94\u3002\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u6211\u5199 respond = ...\u3002\u4f46\u8fd9\u4e2a\u8c03\u7528\u5b9e\u9645\u4e0a\u8fd4\u56de\u4ec0\u4e48\uff1f\u8ba9\u6211\u4eec\u68c0\u67e5\u4e00\u4e0b\u3002\u53ea\u9700\u5728\u6700\u540e\u4e00\u884c\u540e\u6dfb\u52a0 print \u8bed\u53e5\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\n

      \u7136\u540e\u4fdd\u5b58\u5e76\u8fd0\u884c\u5b83...

      \u54ce\u5440\uff01\u6ca1\u6709\u6253\u5370\uff1f\u522b\u62c5\u5fc3\u3002\u53ea\u9700\u62c9\u4e0b\u901a\u77e5\u680f\uff0c\u60a8\u5c31\u4f1a\u770b\u5230\"QPython Program Output: hello1.py\"\u2014\u2014\u70b9\u51fb\u5b83\uff01

      \u5982\u60a8\u6240\u89c1\uff0cdroid.dialogGetInput() \u8fd4\u56de\u4e00\u4e2a\u5305\u542b\u4e09\u4e2a\u5b57\u6bb5\u7684 JSON \u5bf9\u8c61\u3002\u6211\u4eec\u53ea\u9700\u8981\u4e00\u4e2a\u2014\u2014result\uff0c\u5176\u4e2d\u5305\u542b\u7528\u6237\u5b9e\u9645\u8f93\u5165\u7684\u5185\u5bb9\u3002

      \u8ba9\u6211\u4eec\u6dfb\u52a0\u811a\u672c\u7684\u53cd\u5e94\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nmessage = f'Hello, {respond.result}!'\ndroid.makeToast(message)\n

      \u6700\u540e\u4e24\u884c\uff081\uff09\u683c\u5f0f\u5316\u6d88\u606f\uff0c\uff082\uff09\u4ee5 toast \u5f62\u5f0f\u5411\u7528\u6237\u663e\u793a\u6d88\u606f\u3002\u5982\u679c\u60a8\u4ecd\u7136\u4e0d\u77e5\u9053 f-string \u662f\u4ec0\u4e48\u610f\u601d\uff0c\u8bf7\u53c2\u9605 Python \u6587\u6863\u3002

      \u54c7\uff01\u5b83\u5de5\u4f5c\u4e86\uff01;)

      \u73b0\u5728\u6211\u8981\u5728\u90a3\u91cc\u6dfb\u52a0\u4e00\u4e9b\u903b\u8f91\u3002\u60f3\u4e00\u60f3\uff1a\u5982\u679c\u7528\u6237\u70b9\u51fb \u53d6\u6d88 \u6309\u94ae\uff0c\u6216\u8005\u70b9\u51fb \u786e\u5b9a \u4f46\u5c06\u8f93\u5165\u5b57\u6bb5\u7559\u7a7a\uff0c\u4f1a\u53d1\u751f\u4ec0\u4e48\uff1f

      \u60a8\u53ef\u4ee5\u73a9\u8fd9\u4e2a\u7a0b\u5e8f\uff0c\u68c0\u67e5 respond \u53d8\u91cf\u5728\u6bcf\u79cd\u60c5\u51b5\u4e0b\u5305\u542b\u4ec0\u4e48\u3002

      \u9996\u5148\uff0c\u6211\u60f3\u5c06\u7528\u6237\u8f93\u5165\u7684\u6587\u672c\u653e\u5165\u4e00\u4e2a\u5355\u72ec\u7684\u53d8\u91cf\u4e2d\uff1aname = respond.result\u3002\u7136\u540e\u6211\u68c0\u67e5\u5b83\uff0c\u5982\u679c\u5b83\u5305\u542b\u4efb\u4f55\u771f\u5b9e\u6587\u672c\uff0c\u5b83\u5c06\u88ab\u89c6\u4e3a\u540d\u79f0\u5e76\u7528\u4e8e\u95ee\u5019\u3002\u5426\u5219\uff0c\u5c06\u663e\u793a\u53e6\u4e00\u6761\u6d88\u606f\u3002\u5c06\u7b2c\u4e94\u884c message = f'Hello, {respond.result}!' \u66ff\u6362\u4e3a\u4ee5\u4e0b\u4ee3\u7801\uff1a

      name = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\n

      \u4f7f\u7528\u5de5\u5177\u680f\u4e0a\u7684 < \u548c > \u6309\u94ae\u6765\u7f29\u8fdb/\u53d6\u6d88\u7f29\u8fdb if \u8bed\u53e5\u4e2d\u7684\u884c\uff08\u6216\u8005\u53ea\u9700\u4f7f\u7528\u7a7a\u683c/\u9000\u683c\u952e\uff09\u3002\u60a8\u53ef\u4ee5\u5728 \u6b64\u5904 \u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u7f29\u8fdb\u7684\u5185\u5bb9\uff1bif \u8bed\u53e5\u5728 \u6b64\u5904 \u63cf\u8ff0\u3002

      \u9996\u5148\uff0c\u6211\u4eec\u5c06\u7528\u6237\u8f93\u5165\u653e\u5165 name \u53d8\u91cf\u3002\u7136\u540e\u6211\u4eec\u68c0\u67e5 name \u662f\u5426\u5305\u542b\u4efb\u4f55\u5185\u5bb9\uff1f\u5982\u679c\u7528\u6237\u7559\u7a7a\u884c\u5e76\u70b9\u51fb \u786e\u5b9a\uff0c\u8fd4\u56de\u503c\u662f\u7a7a\u5b57\u7b26\u4e32 ''\u3002\u5982\u679c\u6309\u4e0b\u4e86 \u53d6\u6d88 \u6309\u94ae\uff0c\u8fd4\u56de\u503c\u662f None\u3002\u5728 if \u8bed\u53e5\u4e2d\uff0c\u4e24\u8005\u90fd\u88ab\u89c6\u4e3a\u5047\u3002\u56e0\u6b64\uff0c\u53ea\u6709\u5f53 name \u5305\u542b\u4efb\u4f55\u6709\u610f\u4e49\u7684\u5185\u5bb9\u65f6\uff0cthen \u8bed\u53e5\u624d\u4f1a\u6267\u884c\uff0c\u5e76\u663e\u793a\u95ee\u5019\u8bed\"Hello, ...!\"\u3002\u5982\u679c\u8f93\u5165\u4e3a\u7a7a\uff0c\u7528\u6237\u5c06\u770b\u5230\"Hey! And you're not very polite, %Username%!\"\u6d88\u606f\u3002

      \u597d\u7684\uff0c\u8fd9\u662f\u6574\u4e2a\u7a0b\u5e8f\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nname = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\ndroid.makeToast(message)\n
      "},{"location":"tutorial-hello-world/#_3","title":"\u8fd0\u884c\u6548\u679c","text":""},{"location":"tutorial-hello-world/#_4","title":"\u4e0b\u4e00\u6b65","text":"

      \u5bf9\u4e8e Python \u65b0\u7528\u6237\uff0c\u63a8\u8350\u5b66\u4e60 Python \u8bed\u6cd5\u5b9e\u8df5 \u8bfe\u7a0b\u6765\u8fdb\u4e00\u6b65\u5b66\u4e60 Python\uff0c\u6216\u8005\u5728 QPython \u7cbe\u9009\u8bfe\u7a0b \u4e2d\u5bfb\u627e\u60f3\u8981\u5b66\u4e60\u7684\u5185\u5bb9\u3002

      "},{"location":"whats-new/","title":"\u66f4\u65b0\u65e5\u5fd7","text":""},{"location":"whats-new/#v392-v393","title":"v3.9.2 / v3.9.3","text":"
      • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
      • \u7f16\u8f91\u5668\u91cd\u5927\u66f4\u65b0\uff0c\u5e26\u6765\u66f4\u6d41\u7545\u7684\u7f16\u8f91\u4f53\u9a8c
      • \u5176\u4ed6\u5404\u79cd\u5c0f\u6539\u8fdb
      "},{"location":"whats-new/#v391","title":"v3.9.1","text":"
      • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
      • \u6269\u5c55\u5305\u73b0\u5728\u652f\u6301 MCP
      • \u9519\u8bef\u4fee\u590d
      "},{"location":"whats-new/#v390","title":"v3.9.0","text":"
      • SDK \u5347\u7ea7\uff0c\u6574\u5408\u6700\u65b0\u7684 Android \u529f\u80fd
      • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
      • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
      • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
      "},{"location":"whats-new/#v3811","title":"v3.8.11","text":"
      • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
      • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
      • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
      "},{"location":"whats-new/#v3810","title":"v3.8.10","text":"
      • \u5185\u7f6e Ollama \u5347\u7ea7\uff1a\u73b0\u5728\u60a8\u53ef\u4ee5\u5728 QPython \u4e2d\u8f7b\u677e\u672c\u5730\u8fd0\u884c Qwen3 / Gemma3 \u6a21\u578b\uff01
      • \u6dfb\u52a0\u4e86\u5f3a\u5927\u7684 MCP \u5e93\uff1a\u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 mcp \u5e93\uff0c\u8ba9\u60a8\u968f\u65f6\u968f\u5730\u643a\u5e26\u5f3a\u5927\u7684 MCP \u529f\u80fd\uff01
      "},{"location":"whats-new/#v389","title":"v3.8.9","text":"

      \u91cd\u5927\u66f4\u65b0\uff01AI \u7f16\u7a0b\u5b8c\u5168\u96c6\u6210\u5230 QPython\uff0c\u8ba9\u60a8\u7684\u7f16\u7a0b\u66f4\u8f7b\u677e\uff01

      • \u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u652f\u6301\uff1a\u65b0\u652f\u6301 AIPyApp\uff0c\u5728 QPython \u4e2d\u5b9e\u73b0\u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u3002\u76ee\u524d\u5904\u4e8e\u6d4b\u8bd5\u9636\u6bb5 - \u52a0\u5165\u6211\u4eec\u7684\u793e\u533a\u83b7\u53d6\u4f7f\u7528\u8bf4\u660e
      • \u65b0 QSL4A \u529f\u80fd\uff1a\u6dfb\u52a0 notebookOpen \u51fd\u6570\uff0c\u652f\u6301\u81ea\u7136\u8bed\u8a00\u63a7\u5236\u6253\u5f00 Notebook \u6587\u4ef6
      • \u5185\u7f6e\u7f16\u8f91\u5668\u5347\u7ea7\uff1a\u589e\u5f3a\u7f16\u8f91\u5668\u529f\u80fd\uff0c\u652f\u6301\u6253\u5f00\u548c\u6d4f\u89c8\u5404\u79cd\u6587\u672c\u6587\u4ef6
      • \u4fbf\u6377\u7684\u6587\u4ef6\u7ba1\u7406\uff1a\u5728\u6587\u4ef6\u7ba1\u7406\u5668\u4e2d\u6dfb\u52a0\u5185\u90e8\u5b58\u50a8\u5165\u53e3\uff0c\u5feb\u901f\u8bbf\u95ee\u60a8\u7684\u6587\u4ef6
      "},{"location":"whats-new/#v388","title":"v3.8.8","text":"
      • \u6587\u4ef6\u8bbf\u95ee\u6743\u9650\u63a7\u5236\u7684\u91cd\u8981\u6539\u8fdb\uff0c\u5141\u8bb8\u7528\u6237\u7075\u6d3b\u5730\u901a\u8fc7 QPython \u7f16\u7a0b\u542f\u7528\u6216\u7981\u7528\u5916\u90e8\u5b58\u50a8\u6587\u4ef6\u7684\u8bbf\u95ee
      • SDK \u5347\u7ea7\uff0c\u589e\u5f3a\u4e86\u5bf9\u65b0\u7248 Android \u7684\u652f\u6301\u548c\u517c\u5bb9\u6027
      • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Anthropic \u548c Google GenAI \u5e93
      "},{"location":"whats-new/#v387","title":"v3.8.7","text":"
      • \u5728\u73b0\u6709 Tkinter \u652f\u6301\u57fa\u7840\u4e0a\uff0c\u5728 Extensions -> Tools \u4e2d\u6dfb\u52a0\u4e86\u4f7f\u7528 Turtle \u7ed8\u5236\u54c6\u5566A\u68a6\u7684\u793a\u4f8b\u4ee3\u7801
      • \u4f18\u5316\u4e86\u624b\u673a\u6743\u9650\u83b7\u53d6\u6d41\u7a0b\uff0c\u63d0\u5347\u7528\u6237\u4f53\u9a8c\u548c\u64cd\u4f5c\u4fbf\u5229\u6027
      • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Google Gen AI \u5e93\uff0c\u65b9\u4fbf\u8bbf\u95ee Gemini Developer API \u548c Vertex AI
      "},{"location":"whats-new/#v386","title":"v3.8.6","text":"
      • Tkinter \u652f\u6301\uff1a\u73b0\u5728\u652f\u6301 Tkinter \u5e93\uff0c\u53ef\u901a\u8fc7 XServer \u8bbf\u95ee\u3002\u8bf7\u8bbf\u95ee www.qpython.org \u7684\u4e91\u76d8\"Extra\"\u94fe\u63a5\u4e0b\u8f7d\u6240\u9700\u6587\u4ef6
      • \u5b58\u50a8\u6743\u9650\u66f4\u65b0\uff1a\u4e3a\u6539\u5584\u7528\u6237\u4f53\u9a8c\uff0c\u6211\u4eec\u6dfb\u52a0\u4e86\u8bfb\u53d6\u624b\u673a\u5b58\u50a8\u7684\u6743\u9650\uff0c\u7528\u4e8e\u8bbf\u95ee\u5b58\u50a8\u5728\u5176\u4ed6\u76ee\u5f55\u4e2d\u7684 Python \u7a0b\u5e8f

      \u6b64\u66f4\u65b0\u540e\uff0cQPython \u548c QPythonPlus\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff0c\u4e13\u4e3a\u9700\u8981\u66f4\u591a\u654f\u611f\u6743\u9650\u7684\u9ad8\u7ea7\u7528\u6237\u8bbe\u8ba1\uff09\u5c06\u4fdd\u6301\u540c\u6b65\u7684\u7248\u672c\u53f7\u3002

      "},{"location":"whats-new/#v352-2025225","title":"v3.5.2 (2025/2/25)","text":"

      \u4e0e\u5f00\u6e90 LLM \u90e8\u7f72\u5de5\u5177 Ollama \u4ee5\u53ca DeepSeek \u5f00\u53d1\u7684 DeepSeek \u5b9e\u73b0\u65e0\u7f1d\u96c6\u6210\uff01

      \u529f\u80fd\uff1a - \u96f6\u95e8\u69db\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5404\u79cd\u5927\u578b\u8bed\u8a00\u6a21\u578b - \u5feb\u901f\u90e8\u7f72 DeepSeek \u7b49\u5c16\u7aef AI \u6a21\u578b - \u4eab\u53d7\u7b80\u7ea6\u7684 API \u8c03\u7528\u4f53\u9a8c - \u6784\u5efa\u5b8c\u5168\u79bb\u7ebf\u7684\u667a\u80fd\u7f16\u7a0b\u73af\u5883

      \u80fd\u529b\uff1a - \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u52a0\u8f7d/\u7ba1\u7406 LLM \u6a21\u578b - \u57fa\u4e8e\u672c\u5730\u8ba1\u7b97\u7684\u5b9e\u65f6\u4f4e\u5ef6\u8fdf\u54cd\u5e94

      "},{"location":"whats-new/#v350","title":"v3.5.0","text":"
      • Python \u5347\u7ea7\u5230 3.12.8
      • \u6539\u8fdb\u4eea\u8868\u76d8\uff0c\u529f\u80fd\u66f4\u6e05\u6670\u3001\u66f4\u4eba\u6027\u5316
      • \u6dfb\u52a0\u4e86\u4f17\u591a\u7b2c\u4e09\u65b9\u5305\uff1aPyTorch / Twisted / Scrapy / FastAPI ...
      "},{"location":"whats-new/#v338","title":"v3.3.8","text":"
      • \u4fee\u590d\u4e86 NumPy \u517c\u5bb9\u6027\u95ee\u9898
      "},{"location":"whats-new/#v335","title":"v3.3.5","text":"
      • \u5347\u7ea7 Python \u5185\u6838\u5230 3.11.9
      • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u4e0d\u663e\u793a\u6a21\u5757\u5b89\u88c5\u72b6\u6001\u7684 bug
      • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u5220\u9664\u6a21\u5757\u5931\u8d25\u7684 bug
      • \u4fee\u590d\u4e86\u5176\u4ed6 bug
      "},{"location":"whats-new/#v334","title":"v3.3.4","text":"
      • \u6dfb\u52a0\u4e86 OpenAI/Langchain/APIGPTCloud AI \u5305
      • \u79fb\u9664\u4e0d\u5fc5\u8981\u7684\u6587\u4ef6\u4ee5\u51cf\u5c11\u5927\u5c0f
      "},{"location":"whats-new/#v325","title":"v3.2.5","text":"
      • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570
      • \u5176\u4ed6\u9519\u8bef\u4fee\u590d
      "},{"location":"whats-new/#v323","title":"v3.2.3","text":"
      • \u66f4\u65b0 Python \u7248\u672c\u5230 3.11.0
      • \u66f4\u65b0 IPython \u7248\u672c\u5230 8.6.0
      • \u66f4\u65b0 pip \u7248\u672c\u5230 22.3.1
      • \u66f4\u65b0\u79d1\u5b66\u8ba1\u7b97\u5305\uff0c\u81ea\u52a8\u8f6f\u94fe\u63a5
      • \u51cf\u5c11\u7a7a\u95f4\u4f7f\u7528
      • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570 + \u5176\u4ed6\u9519\u8bef\u4fee\u590d
      "},{"location":"whats-new/#v318","title":"v3.1.8","text":"
      • \u5728\u7ec8\u7aef\u4e2d\u6dfb\u52a0\u4e86\u64cd\u4f5c\u70ed\u952e
      • \u4fee\u590d\u4e86\u7f16\u8f91\u5668\u5728\u65cb\u8f6c\u65f6\u4e22\u5931\u5185\u5bb9\u7684\u95ee\u9898
      • \u4fee\u590d\u4e86\u5176\u4ed6 bug

      \u5728 Google Play \u4e0b\u8f7d

      "},{"location":"qsl4a/","title":"QSL4A\uff08Android \u811a\u672c\u5c42\uff09API \u6587\u6863","text":"

      QSL4A \u662f QPython \u7684 Android \u811a\u672c\u5c42\uff0c\u5141\u8bb8\u60a8\u4f7f\u7528 Python \u63a7\u5236 Android \u8bbe\u5907\u529f\u80fd\u3002

      "},{"location":"qsl4a/#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a toast \u6d88\u606f\ndroid.makeToast('Hello QPython!')\n\n# \u9707\u52a8\u8bbe\u5907\ndroid.vibrate(500)\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\uff08\u5148\u5f00\u59cb\u76d1\u63a7\uff09\nimport time\ndroid.batteryStartMonitoring()\ntime.sleep(0.5)  # \u7b49\u5f85\u6570\u636e\nbattery = droid.readBatteryData().result\nprint(f\"\u7535\u6c60\uff1a{battery['level']}%\")\n
      "},{"location":"qsl4a/#_2","title":"\u6587\u6863\u7ed3\u6784","text":""},{"location":"qsl4a/#_3","title":"\u6838\u5fc3\u6a21\u5757","text":"
      • Android \u57fa\u7840 - \u6838\u5fc3\u8fde\u63a5\u548c RPC
      • Intent \u7cfb\u7edf - Android Intent \u64cd\u4f5c
      • \u4e8b\u4ef6\u7cfb\u7edf - \u4e8b\u4ef6\u5904\u7406\u548c\u5e7f\u64ad
      "},{"location":"qsl4a/#ui","title":"UI \u7ec4\u4ef6","text":"
      • \u5bf9\u8bdd\u6846 - \u8b66\u62a5\u3001\u8f93\u5165\u3001\u9009\u62e9\u5bf9\u8bdd\u6846
      • \u5168\u5c4f UI - \u81ea\u5b9a\u4e49\u5e03\u5c40 UI
      • \u60ac\u6d6e\u7a97 - \u60ac\u6d6e\u7a97\u53e3
      • \u8f85\u52a9\u529f\u80fd - \u5c4f\u5e55\u81ea\u52a8\u5316
      "},{"location":"qsl4a/#_4","title":"\u7cfb\u7edf","text":"
      • \u7535\u6c60 - \u7535\u6c60\u76d1\u63a7
      • \u4f20\u611f\u5668 - \u8bbe\u5907\u4f20\u611f\u5668
      • \u5e94\u7528 - \u5e94\u7528\u7ba1\u7406
      • \u7cfb\u7edf\u4fe1\u606f - \u8bbe\u5907\u4fe1\u606f
      • \u8bbe\u7f6e - \u7cfb\u7edf\u8bbe\u7f6e
      • \u5524\u9192\u9501 - \u5524\u9192\u9501\u63a7\u5236
      • QPython \u63a5\u53e3 - \u811a\u672c\u6267\u884c
      • Activity \u7ed3\u679c - Activity \u7ed3\u679c\u5904\u7406
      "},{"location":"qsl4a/#_5","title":"\u786c\u4ef6","text":"
      • \u84dd\u7259 - \u84dd\u7259\u64cd\u4f5c
      • \u76f8\u673a - \u62cd\u7167\u548c\u5f55\u50cf
      • \u97f3\u9891/\u5f55\u97f3\u5668 - \u5f55\u97f3
      • \u7f51\u7edc\u6444\u50cf\u5934 - MJPEG \u6d41
      • USB \u4e32\u53e3 - USB \u4e3b\u673a\u4e32\u53e3
      "},{"location":"qsl4a/#_6","title":"\u8fde\u63a5","text":"
      • WiFi - WiFi \u64cd\u4f5c
      • \u4f4d\u7f6e - GPS \u548c\u4f4d\u7f6e
      • \u77ed\u4fe1 - \u77ed\u4fe1\u64cd\u4f5c
      • \u7535\u8bdd - \u6253\u7535\u8bdd\u548c\u6765\u7535\u4fe1\u606f
      • \u8054\u7cfb\u4eba - \u8054\u7cfb\u4eba\u7ba1\u7406
      • \u4fe1\u53f7\u5f3a\u5ea6 - \u4fe1\u53f7\u76d1\u63a7
      • FTP \u670d\u52a1\u5668 - \u5185\u7f6e FTP \u670d\u52a1\u5668
      "},{"location":"qsl4a/#_7","title":"\u5b58\u50a8","text":"
      • DocumentFile - \u6587\u4ef6\u64cd\u4f5c
      • \u526a\u8d34\u677f - \u526a\u8d34\u677f\u64cd\u4f5c
      • \u504f\u597d\u8bbe\u7f6e - \u5171\u4eab\u504f\u597d\u8bbe\u7f6e
      "},{"location":"qsl4a/#_8","title":"\u5a92\u4f53","text":"
      • \u5a92\u4f53\u64ad\u653e\u5668 - \u97f3\u9891/\u89c6\u9891\u64ad\u653e
      • \u56fe\u50cf\u5904\u7406 - \u56fe\u50cf\u64cd\u4f5c
      "},{"location":"qsl4a/#_9","title":"\u7279\u6b8a\u529f\u80fd","text":"
      • \u52a0\u5bc6 - \u52a0\u5bc6/\u89e3\u5bc6
      • PGPT AI - AI \u8bed\u97f3\u670d\u52a1
      "},{"location":"qsl4a/#_10","title":"\u7ed3\u679c\u5bf9\u8c61","text":"

      \u5927\u591a\u6570 QSL4A \u65b9\u6cd5\u8fd4\u56de\u4e00\u4e2a\u5e26\u6709\u4ee5\u4e0b\u5c5e\u6027\u7684 Result \u547d\u540d\u5143\u7ec4\uff1a - id - \u8bf7\u6c42 ID - result - \u5b9e\u9645\u7ed3\u679c\u6570\u636e - error - \u5982\u679c\u5931\u8d25\u5219\u4e3a\u9519\u8bef\u6d88\u606f

      result = droid.getClipboard()\nif result.error is None:\n    print(result.result)\nelse:\n    print(f\"\u9519\u8bef\uff1a{result.error}\")\n
      "},{"location":"qsl4a/connectivity/contacts/","title":"\u8054\u7cfb\u4eba API","text":"

      \u8bbf\u95ee\u548c\u7ba1\u7406\u8bbe\u5907\u8054\u7cfb\u4eba\u3002

      "},{"location":"qsl4a/connectivity/contacts/#_1","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":""},{"location":"qsl4a/connectivity/contacts/#pickcontact","title":"pickContact()","text":"

      \u663e\u793a\u8054\u7cfb\u4eba\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

      pickContact()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u8054\u7cfb\u4eba URI \u7684 Intent

      "},{"location":"qsl4a/connectivity/contacts/#pickphone","title":"pickPhone()","text":"

      \u663e\u793a\u7535\u8bdd\u53f7\u7801\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

      pickPhone()\n

      \u8fd4\u56de\uff1a \u9009\u4e2d\u7684\u7535\u8bdd\u53f7\u7801\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/contacts/#_2","title":"\u8054\u7cfb\u4eba\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#contactsget","title":"contactsGet()","text":"

      \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\u3002

      contactsGet(attributes=None)\n

      \u53c2\u6570\uff1a - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

      \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba JSONObject \u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetbyid","title":"contactsGetById()","text":"

      \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\u3002

      contactsGetById(id, attributes=None)\n

      \u53c2\u6570\uff1a - id (int): \u8054\u7cfb\u4eba ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

      \u8fd4\u56de\uff1a JSONObject \u8054\u7cfb\u4eba\u6570\u636e

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetcount","title":"contactsGetCount()","text":"

      \u83b7\u53d6\u8054\u7cfb\u4eba\u603b\u6570\u3002

      contactsGetCount()\n

      \u8fd4\u56de\uff1a \u6574\u6570\u8ba1\u6570

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetids","title":"contactsGetIds()","text":"

      \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba ID\u3002

      contactsGetIds()\n

      \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba ID \u6574\u6570\u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetattributes","title":"contactsGetAttributes()","text":"

      \u83b7\u53d6\u6240\u6709\u53ef\u80fd\u7684\u8054\u7cfb\u4eba\u5c5e\u6027\u3002

      contactsGetAttributes()\n

      \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#_3","title":"\u5185\u5bb9\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#querycontent","title":"queryContent()","text":"

      \u4f7f\u7528\u81ea\u5b9a\u4e49\u53c2\u6570\u67e5\u8be2\u5185\u5bb9\u89e3\u6790\u5668\u3002

      queryContent(uri, attributes=None, selection=None, selectionArgs=None, order=None)\n

      \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u5c5e\u6027 - selection (str, optional): WHERE \u5b50\u53e5 - selectionArgs (list, optional): \u9009\u62e9\u53c2\u6570 - order (str, optional): ORDER BY \u5b50\u53e5

      \u8fd4\u56de\uff1a JSONObject \u7ed3\u679c\u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#queryattributes","title":"queryAttributes()","text":"

      \u83b7\u53d6\u5185\u5bb9 URI \u7684\u5c5e\u6027\u3002

      queryAttributes(uri)\n

      \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI

      \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u7684 JSONArray

      "},{"location":"qsl4a/connectivity/contacts/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u9009\u62e9\u8054\u7cfb\u4eba\ncontact_uri = droid.pickContact().result\nprint(f\"Selected contact: {contact_uri}\")\n\n# \u9009\u62e9\u7535\u8bdd\u53f7\u7801\nphone = droid.pickPhone().result\nprint(f\"Selected phone: {phone}\")\n\n# \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\ncontacts = droid.contactsGet().result\nprint(f\"Total contacts: {len(contacts)}\")\n\n# \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\ncontact = droid.contactsGetById(1).result\nprint(f\"Contact: {contact}\")\n\n# \u83b7\u53d6\u8054\u7cfb\u4eba\u5c5e\u6027\nattrs = droid.contactsGetAttributes().result\nprint(f\"Available attributes: {attrs}\")\n
      "},{"location":"qsl4a/connectivity/ftp/","title":"FTP \u670d\u52a1\u5668 API","text":"

      \u5728\u8bbe\u5907\u4e0a\u542f\u52a8\u548c\u7ba1\u7406\u5185\u7f6e FTP \u670d\u52a1\u5668\u3002

      "},{"location":"qsl4a/connectivity/ftp/#ftp","title":"FTP \u670d\u52a1\u5668\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/ftp/#ftpstart","title":"ftpStart()","text":"

      \u542f\u52a8 FTP \u670d\u52a1\u5668\u3002

      ftpStart()\n

      \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4 [ip, port]

      "},{"location":"qsl4a/connectivity/ftp/#ftpstop","title":"ftpStop()","text":"

      \u505c\u6b62 FTP \u670d\u52a1\u5668\u3002

      ftpStop()\n
      "},{"location":"qsl4a/connectivity/ftp/#ftpisrunning","title":"ftpIsRunning()","text":"

      \u68c0\u67e5 FTP \u670d\u52a1\u5668\u662f\u5426\u6b63\u5728\u8fd0\u884c\u3002

      ftpIsRunning()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u8fd0\u884c\u5219\u4e3a True

      "},{"location":"qsl4a/connectivity/ftp/#ftpget","title":"ftpGet()","text":"

      \u83b7\u53d6 FTP \u670d\u52a1\u5668 IP \u5730\u5740\u3002

      ftpGet()\n

      \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4

      "},{"location":"qsl4a/connectivity/ftp/#ftpset","title":"ftpSet()","text":"

      \u914d\u7f6e FTP \u670d\u52a1\u5668\u8bbe\u7f6e\u3002

      ftpSet(port=None, rootDir=None, username=None, password=None)\n

      \u53c2\u6570\uff1a - port (int, optional): \u670d\u52a1\u5668\u7aef\u53e3 - rootDir (str, optional): \u8981\u670d\u52a1\u7684\u57fa\u7840\u76ee\u5f55 - username (str, optional): \u767b\u5f55\u7528\u6237\u540d - password (str, optional): \u767b\u5f55\u5bc6\u7801

      \u8fd4\u56de\uff1a \u5305\u542b\u5f53\u524d\u8bbe\u7f6e\u7684 JSONObject

      "},{"location":"qsl4a/connectivity/ftp/#ftpstatus","title":"ftpStatus()","text":"

      \u83b7\u53d6 FTP \u670d\u52a1\u5668\u72b6\u6001\u3002

      ftpStatus()\n

      \u8fd4\u56de\uff1a \u72b6\u6001\u63cf\u8ff0\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/ftp/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u914d\u7f6e FTP \u670d\u52a1\u5668\ndroid.ftpSet(\n    port=2121,\n    rootDir=\"/sdcard\",\n    username=\"admin\",\n    password=\"secret\"\n)\n\n# \u542f\u52a8 FTP \u670d\u52a1\u5668\ninfo = droid.ftpStart().result\nprint(f\"FTP running at {info[0]}:{info[1]}\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.ftpIsRunning().result:\n    print(\"FTP server is running\")\n\n# \u83b7\u53d6\u670d\u52a1\u5668\u4fe1\u606f\nserver_info = droid.ftpGet().result\nprint(f\"Server: {server_info}\")\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.ftpStop()\n

      \u6ce8\u610f\uff1a \u4f7f\u7528\u63d0\u4f9b\u7684\u51ed\u636e\u901a\u8fc7\u4efb\u4f55 FTP \u5ba2\u6237\u7aef\u8fde\u63a5\u5230 FTP \u670d\u52a1\u5668\u3002

      "},{"location":"qsl4a/connectivity/location/","title":"\u4f4d\u7f6e API","text":"

      \u8bbf\u95ee GPS \u548c\u7f51\u7edc\u4f4d\u7f6e\u670d\u52a1\u3002

      "},{"location":"qsl4a/connectivity/location/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/location/#startlocating","title":"startLocating()","text":"

      \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\u3002

      startLocating(minUpdateTime=60000, minUpdateDistance=30, updateGnssStatus=False)\n

      \u53c2\u6570\uff1a - minUpdateTime (int): \u66f4\u65b0\u4e4b\u95f4\u7684\u6700\u5c0f\u65f6\u95f4\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a60000\uff09 - minUpdateDistance (float): \u66f4\u65b0\u7684\u6700\u5c0f\u8ddd\u79bb\uff08\u7c73\uff09\uff08\u9ed8\u8ba4\uff1a30\uff09 - updateGnssStatus (bool): \u542f\u7528 GNSS \u72b6\u6001\u66f4\u65b0\uff08\u9ed8\u8ba4\uff1aFalse\uff09

      "},{"location":"qsl4a/connectivity/location/#stoplocating","title":"stopLocating()","text":"

      \u505c\u6b62\u4f4d\u7f6e\u66f4\u65b0\u3002

      stopLocating()\n
      "},{"location":"qsl4a/connectivity/location/#readlocation","title":"readLocation()","text":"

      \u83b7\u53d6\u6700\u540e\u5df2\u77e5\u4f4d\u7f6e\u3002

      readLocation()\n

      \u8fd4\u56de\uff1a \u4f4d\u7f6e\u6570\u636e\u5b57\u5178

      "},{"location":"qsl4a/connectivity/location/#getlastknownlocation","title":"getLastKnownLocation()","text":"

      \u83b7\u53d6\u7f13\u5b58\u7684\u4f4d\u7f6e\u3002

      getLastKnownLocation()\n

      \u8fd4\u56de\uff1a \u6765\u81ea\u6240\u6709\u63d0\u4f9b\u5546\u7684\u4f4d\u7f6e

      "},{"location":"qsl4a/connectivity/location/#geocode","title":"geocode()","text":"

      \u5c06\u5730\u5740\u8f6c\u6362\u4e3a\u5750\u6807\u3002

      geocode(address, maxResults=1)\n
      "},{"location":"qsl4a/connectivity/location/#_2","title":"\u4f4d\u7f6e\u63d0\u4f9b\u5546\u65b9\u6cd5)","text":""},{"location":"qsl4a/connectivity/location/#locationproviders","title":"locationProviders()","text":"

      \u83b7\u53d6\u624b\u673a\u4e0a\u53ef\u7528\u7684\u4f4d\u7f6e\u63d0\u4f9b\u5546\u3002

      locationProviders()\n

      \u8fd4\u56de\uff1a \u53ef\u7528\u63d0\u4f9b\u5546\u540d\u79f0\u5217\u8868\uff08\u4f8b\u5982 ['gps', 'network']\uff09

      "},{"location":"qsl4a/connectivity/location/#locationproviderenabled","title":"locationProviderEnabled()","text":"

      \u68c0\u67e5\u7279\u5b9a\u4f4d\u7f6e\u63d0\u4f9b\u5546\u662f\u5426\u5df2\u542f\u7528\u3002

      locationProviderEnabled(provider)\n

      \u53c2\u6570\uff1a - provider (str): \u63d0\u4f9b\u5546\u540d\u79f0\uff08\u4f8b\u5982 'gps', 'network'\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/connectivity/location/#readgnssstatus","title":"readGnssStatus()","text":"

      \u8bfb\u53d6\u5168\u7403\u5bfc\u822a\u536b\u661f\u7cfb\u7edf\u72b6\u6001\uff08\u9700\u8981 Android 8+\uff09\u3002

      readGnssStatus()\n

      \u8fd4\u56de\uff1a \u5305\u542b GNSS \u536b\u661f\u4fe1\u606f\u7684 JSONArray

      "},{"location":"qsl4a/connectivity/location/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\ndroid.startLocating(minUpdateTime=5000, minUpdateDistance=1, updateGnssStatus=False)\n\n# \u7b49\u5f85\u5b9a\u4f4d\ntime.sleep(10)\n\n# \u83b7\u53d6\u4f4d\u7f6e\nloc = droid.readLocation().result\nif loc:\n    lat = loc['latitude']\n    lon = loc['longitude']\n    print(f\"Location: {lat}, {lon}\")\n\ndroid.stopLocating()\n
      "},{"location":"qsl4a/connectivity/phone/","title":"\u7535\u8bdd API","text":"

      \u63a7\u5236\u7535\u8bdd\u901a\u8bdd\u548c\u83b7\u53d6\u7535\u8bdd\u4fe1\u606f\u3002

      "},{"location":"qsl4a/connectivity/phone/#_1","title":"\u7535\u8bdd\u72b6\u6001\u8ddf\u8e2a","text":""},{"location":"qsl4a/connectivity/phone/#starttrackingphonestate","title":"startTrackingPhoneState()","text":"

      \u5f00\u59cb\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u53d8\u5316\u3002\u751f\u6210 'phone' \u4e8b\u4ef6\u3002

      startTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/phone/#readphonestate","title":"readPhoneState()","text":"

      \u8bfb\u53d6\u5f53\u524d\u7535\u8bdd\u72b6\u6001\u3002

      readPhoneState()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7535\u8bdd\u72b6\u6001\u548c\u6765\u7535\u53f7\u7801\u7684 Bundle

      "},{"location":"qsl4a/connectivity/phone/#stoptrackingphonestate","title":"stopTrackingPhoneState()","text":"

      \u505c\u6b62\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u3002

      stopTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/phone/#_2","title":"\u62e8\u6253\u7535\u8bdd","text":""},{"location":"qsl4a/connectivity/phone/#phonecall","title":"phoneCall()","text":"

      \u901a\u8fc7 URI \u547c\u53eb\u8054\u7cfb\u4eba/\u7535\u8bdd\u53f7\u7801\u3002

      phoneCall(uri)\n

      \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

      "},{"location":"qsl4a/connectivity/phone/#phonecallnumber","title":"phoneCallNumber()","text":"

      \u76f4\u63a5\u62e8\u6253\u7535\u8bdd\u53f7\u7801\u3002

      phoneCallNumber(phone_number)\n

      \u53c2\u6570\uff1a - phone_number (str): \u8981\u62e8\u6253\u7684\u7535\u8bdd\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#phonedial","title":"phoneDial()","text":"

      \u62e8\u6253\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

      phoneDial(uri)\n

      \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

      "},{"location":"qsl4a/connectivity/phone/#phonedialnumber","title":"phoneDialNumber()","text":"

      \u62e8\u6253\u7535\u8bdd\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

      phoneDialNumber(phone_number)\n

      \u53c2\u6570\uff1a - phone_number (str): \u7535\u8bdd\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#_3","title":"\u57fa\u7ad9\u4f4d\u7f6e","text":""},{"location":"qsl4a/connectivity/phone/#getcelllocation","title":"getCellLocation()","text":"

      \u83b7\u53d6\u5f53\u524d\u57fa\u7ad9\u4f4d\u7f6e\u3002

      getCellLocation()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u57fa\u7ad9\u4f4d\u7f6e\u6570\u636e\u7684 JSONObject

      "},{"location":"qsl4a/connectivity/phone/#getallcellslocation","title":"getAllCellsLocation()","text":"

      \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u4f4d\u7f6e\uff08\u9002\u7528\u4e8e\u53cc\u5361\u8bbe\u5907\uff09\u3002

      getAllCellsLocation()\n

      \u8fd4\u56de\uff1a \u57fa\u7ad9\u4f4d\u7f6e\u7684 JSONArray

      "},{"location":"qsl4a/connectivity/phone/#_4","title":"\u7f51\u7edc\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getnetworkoperator","title":"getNetworkOperator()","text":"

      \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

      getNetworkOperator()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getnetworkoperatorname","title":"getNetworkOperatorName()","text":"

      \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684\u540d\u79f0\u3002

      getNetworkOperatorName()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getnetworktype","title":"getNetworkType()","text":"

      \u83b7\u53d6\u5f53\u524d\u7f51\u7edc\u7c7b\u578b\u3002

      getNetworkType()\n

      \u8fd4\u56de\uff1a \u63cf\u8ff0\u65e0\u7ebf\u7535\u6280\u672f\u7684\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'LTE', 'UMTS', 'GSM'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getphonetype","title":"getPhoneType()","text":"

      \u83b7\u53d6\u7535\u8bdd\u7c7b\u578b\u3002

      getPhoneType()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'GSM', 'CDMA', 'SIP'\uff09

      "},{"location":"qsl4a/connectivity/phone/#sim","title":"SIM \u5361\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getsimcountryiso","title":"getSimCountryIso()","text":"

      \u83b7\u53d6 SIM \u5361\u7684 ISO \u56fd\u5bb6\u4ee3\u7801\u3002

      getSimCountryIso()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'us'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getsimoperator","title":"getSimOperator()","text":"

      \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

      getSimOperator()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getsimoperatorname","title":"getSimOperatorName()","text":"

      \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u540d\u79f0\u3002

      getSimOperatorName()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getsimserialnumber","title":"getSimSerialNumber()","text":"

      \u83b7\u53d6 SIM \u5e8f\u5217\u53f7\u3002

      getSimSerialNumber()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32 SIM \u5e8f\u5217\u53f7

      "},{"location":"qsl4a/connectivity/phone/#getsimstate","title":"getSimState()","text":"

      \u83b7\u53d6 SIM \u5361\u72b6\u6001\u3002

      getSimState()\n

      \u8fd4\u56de\uff1a \u63cf\u8ff0 SIM \u72b6\u6001\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/phone/#getsubscriberid","title":"getSubscriberId()","text":"

      \u83b7\u53d6\u8ba2\u9605\u8005 ID\u3002

      getSubscriberId()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8ba2\u9605\u8005 ID

      "},{"location":"qsl4a/connectivity/phone/#_5","title":"\u8bed\u97f3\u90ae\u4ef6","text":""},{"location":"qsl4a/connectivity/phone/#getvoicemailalphatag","title":"getVoiceMailAlphaTag()","text":"

      \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u5b57\u6bcd\u6807\u7b7e\u3002

      getVoiceMailAlphaTag()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u6807\u7b7e

      "},{"location":"qsl4a/connectivity/phone/#getvoicemailnumber","title":"getVoiceMailNumber()","text":"

      \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801\u3002

      getVoiceMailNumber()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getdeviceid","title":"getDeviceId()","text":"

      \u83b7\u53d6\u8bbe\u5907 ID\uff08GSM \u7684 IMEI\uff09\u3002\u5df2\u5e9f\u5f03\u3002

      getDeviceId()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

      "},{"location":"qsl4a/connectivity/phone/#getdevicesoftwareversion","title":"getDeviceSoftwareVersion()","text":"

      \u83b7\u53d6\u8bbe\u5907\u8f6f\u4ef6\u7248\u672c\u3002

      getDeviceSoftwareVersion()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8f6f\u4ef6\u7248\u672c

      "},{"location":"qsl4a/connectivity/phone/#getline1number","title":"getLine1Number()","text":"

      \u83b7\u53d6\u7ebf\u8def 1 \u7535\u8bdd\u53f7\u7801\u3002

      getLine1Number()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u7535\u8bdd\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#checknetworkroaming","title":"checkNetworkRoaming()","text":"

      \u68c0\u67e5\u662f\u5426\u8fde\u63a5\u5230\u6f2b\u6e38\u7f51\u7edc\u3002

      checkNetworkRoaming()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u6f2b\u6e38\u5219\u4e3a True

      "},{"location":"qsl4a/connectivity/phone/#_7","title":"\u57fa\u7ad9\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getallcellinfo","title":"getAllCellInfo()","text":"

      \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u7684\u4fe1\u606f\u3002

      getAllCellInfo()\n

      \u8fd4\u56de\uff1a \u57fa\u7ad9\u4fe1\u606f\u5217\u8868

      "},{"location":"qsl4a/connectivity/phone/#setdataenabled","title":"setDataEnabled()","text":"

      \u542f\u7528\u6216\u7981\u7528\u79fb\u52a8\u6570\u636e\u3002

      setDataEnabled(enabled)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528

      "},{"location":"qsl4a/connectivity/phone/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7f51\u7edc\u4fe1\u606f\noperator = droid.getNetworkOperatorName().result\nprint(f\"Operator: {operator}\")\n\nnetwork_type = droid.getNetworkType().result\nprint(f\"Network: {network_type}\")\n\n# \u83b7\u53d6 SIM \u4fe1\u606f\nsim_state = droid.getSimState().result\nprint(f\"SIM: {sim_state}\")\n\n# \u83b7\u53d6\u7535\u8bdd\u53f7\u7801\nline1 = droid.getLine1Number().result\nprint(f\"Phone: {line1}\")\n\n# \u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\ndroid.startTrackingPhoneState()\nprint(\"Tracking phone state...\")\ndroid.stopTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/signalstrength/","title":"\u4fe1\u53f7\u5f3a\u5ea6 API","text":"

      \u76d1\u63a7\u8702\u7a9d\u548c\u65e0\u7ebf\u4fe1\u53f7\u5f3a\u5ea6\u3002

      "},{"location":"qsl4a/connectivity/signalstrength/#_1","title":"\u4fe1\u53f7\u5f3a\u5ea6\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/signalstrength/#starttrackingsignalstrengths","title":"startTrackingSignalStrengths()","text":"

      \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316\u3002\u751f\u6210 'signal_strengths' \u4e8b\u4ef6\u3002

      startTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/signalstrength/#stoptrackingsignalstrengths","title":"stopTrackingSignalStrengths()","text":"

      \u505c\u6b62\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u3002

      stopTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/signalstrength/#readsignalstrengths","title":"readSignalStrengths()","text":"

      \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\u3002

      readSignalStrengths()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u4fe1\u53f7\u5f3a\u5ea6\u6570\u636e\u7684 Bundle

      "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthlevel","title":"getTelephoneSignalStrengthLevel()","text":"

      \u83b7\u53d6\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u7b49\u7ea7\uff080-4\uff09\u3002

      getTelephoneSignalStrengthLevel()\n

      \u8fd4\u56de\uff1a \u6574\u6570\u7b49\u7ea7\uff080=\u65e0\uff0c1=\u5dee\uff0c2=\u4e00\u822c\uff0c3=\u597d\uff0c4=\u4f18\u79c0\uff09

      "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthdetail","title":"getTelephoneSignalStrengthDetail()","text":"

      \u83b7\u53d6\u8be6\u7ec6\u7684\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u4fe1\u606f\u3002

      getTelephoneSignalStrengthDetail()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u8be6\u7ec6\u4fe1\u53f7\u4fe1\u606f\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/signalstrength/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\ndroid.startTrackingSignalStrengths()\n\n# \u7b49\u5f85\u4fe1\u53f7\u66f4\u65b0\ntime.sleep(5)\n\n# \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\nsignal = droid.readSignalStrengths().result\nprint(f\"Signal: {signal}\")\n\n# \u76f4\u63a5\u83b7\u53d6\u7b49\u7ea7\nlevel = droid.getTelephoneSignalStrengthLevel().result\nprint(f\"Signal level: {level}/4\")\n\ndroid.stopTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/sms/","title":"SMS API","text":"

      \u53d1\u9001\u548c\u63a5\u6536 SMS \u6d88\u606f\u3002

      "},{"location":"qsl4a/connectivity/sms/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/sms/#smssend","title":"smsSend()","text":"

      \u53d1\u9001 SMS \u6d88\u606f\u3002

      smsSend(destinationAddress, text)\n

      \u53c2\u6570\uff1a - destinationAddress (str): \u7535\u8bdd\u53f7\u7801 - text (str): \u6d88\u606f\u6587\u672c

      "},{"location":"qsl4a/connectivity/sms/#smsgetmessagecount","title":"smsGetMessageCount()","text":"

      \u83b7\u53d6\u6d88\u606f\u6570\u91cf\u3002

      smsGetMessageCount(unreadOnly=False, folder=\"inbox\")\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessageids","title":"smsGetMessageIds()","text":"

      \u83b7\u53d6\u6d88\u606f ID\u3002

      smsGetMessageIds(unreadOnly=False, folder=\"inbox\")\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessages","title":"smsGetMessages()","text":"

      \u83b7\u53d6\u6d88\u606f\u8be6\u60c5\u3002

      smsGetMessages(unreadOnly=False, folder=\"inbox\", attributes=None)\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessagebyid","title":"smsGetMessageById()","text":"

      \u901a\u8fc7 ID \u83b7\u53d6\u7279\u5b9a\u6d88\u606f\u3002

      smsGetMessageById(id, attributes=None)\n

      \u53c2\u6570\uff1a - id (int): \u6d88\u606f ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

      \u8fd4\u56de\uff1a \u6d88\u606f\u6570\u636e\u5b57\u5178

      "},{"location":"qsl4a/connectivity/sms/#smsgetattributes","title":"smsGetAttributes()","text":"

      \u83b7\u53d6\u53ef\u7528\u7684 SMS \u6d88\u606f\u5c5e\u6027\u3002

      smsGetAttributes()\n

      \u8fd4\u56de\uff1a \u53ef\u7528\u5c5e\u6027\u540d\u79f0\u5217\u8868

      "},{"location":"qsl4a/connectivity/sms/#smsdeletemessage","title":"smsDeleteMessage()","text":"

      \u5220\u9664\u6d88\u606f\u3002

      smsDeleteMessage(id)\n
      "},{"location":"qsl4a/connectivity/sms/#smsmarkmessageread","title":"smsMarkMessageRead()","text":"

      \u5c06\u6d88\u606f\u6807\u8bb0\u4e3a\u5df2\u8bfb\u3002

      smsMarkMessageRead(ids, read=True)\n
      "},{"location":"qsl4a/connectivity/sms/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u53d1\u9001 SMS\ndroid.smsSend(\"+1234567890\", \"Hello from QPython!\")\n\n# \u83b7\u53d6\u672a\u8bfb\u6d88\u606f\nmessages = droid.smsGetMessages(unreadOnly=True).result\nfor msg in messages:\n    print(f\"From: {msg['address']}, Text: {msg['body']}\")\n
      "},{"location":"qsl4a/connectivity/wifi/","title":"WiFi API","text":"

      \u63a7\u5236 WiFi \u9002\u914d\u5668\u5e76\u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\u3002

      "},{"location":"qsl4a/connectivity/wifi/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/connectivity/wifi/#checkwifistate","title":"checkWifiState()","text":"

      \u68c0\u67e5 WiFi \u662f\u5426\u5df2\u542f\u7528\u3002

      checkWifiState()\n

      \u8fd4\u56de\uff1a \u5982\u679c WiFi \u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/connectivity/wifi/#togglewifistate","title":"toggleWifiState()","text":"

      \u6253\u5f00\u6216\u5173\u95ed WiFi\u3002

      toggleWifiState(enabled=None)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

      \u8fd4\u56de\uff1a \u5982\u679c\u64cd\u4f5c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/connectivity/wifi/#wifistartscan","title":"wifiStartScan()","text":"

      \u5f00\u59cb\u626b\u63cf\u53ef\u7528\u7684 WiFi \u7f51\u7edc\u3002

      wifiStartScan()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifigetscanresults","title":"wifiGetScanResults()","text":"

      \u83b7\u53d6\u53d1\u73b0\u7684 WiFi \u7f51\u7edc\u5217\u8868\u3002

      wifiGetScanResults()\n

      \u8fd4\u56de\uff1a \u63a5\u5165\u70b9\u4fe1\u606f\u5217\u8868

      "},{"location":"qsl4a/connectivity/wifi/#_2","title":"\u8fde\u63a5\u7ba1\u7406","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetconnectioninfo","title":"wifiGetConnectionInfo()","text":"

      \u83b7\u53d6\u8be6\u7ec6\u8fde\u63a5\u4fe1\u606f\u3002

      wifiGetConnectionInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001IP \u5730\u5740\u7b49\u8fde\u63a5\u8be6\u60c5\u7684\u5b57\u5178

      "},{"location":"qsl4a/connectivity/wifi/#getconnectedinfo","title":"getConnectedInfo()","text":"

      \u83b7\u53d6\u8fde\u63a5\u7684 WiFi \u7f51\u7edc\u4fe1\u606f\uff08\u7b80\u5316\u7248\uff09\u3002

      getConnectedInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001\u4fe1\u53f7\u5f3a\u5ea6\u7684\u5b57\u5178

      "},{"location":"qsl4a/connectivity/wifi/#getdhcpinfo","title":"getDhcpInfo()","text":"

      \u83b7\u53d6\u5f53\u524d\u8fde\u63a5\u7684 DHCP \u4fe1\u606f\u3002

      getDhcpInfo(ipConvertToString=True)\n

      \u53c2\u6570\uff1a - ipConvertToString (bool): \u5c06 IP \u5730\u5740\u8f6c\u6362\u4e3a\u5b57\u7b26\u4e32\u683c\u5f0f\uff08\u9ed8\u8ba4\uff1aTrue\uff09

      \u8fd4\u56de\uff1a \u5305\u542b IP\u3001\u7f51\u5173\u3001DNS \u7b49 DHCP \u4fe1\u606f\u7684\u5b57\u5178

      "},{"location":"qsl4a/connectivity/wifi/#wifidisconnect","title":"wifiDisconnect()","text":"

      \u65ad\u5f00\u5f53\u524d WiFi \u7f51\u7edc\u8fde\u63a5\u3002

      wifiDisconnect()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifireconnect","title":"wifiReconnect()","text":"

      \u91cd\u65b0\u8fde\u63a5\u5230\u5f53\u524d\u7f51\u7edc\u3002

      wifiReconnect()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifireassociate","title":"wifiReassociate()","text":"

      \u91cd\u65b0\u5173\u8054\u5f53\u524d\u63a5\u5165\u70b9\u3002

      wifiReassociate()\n
      "},{"location":"qsl4a/connectivity/wifi/#_3","title":"\u70ed\u70b9","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetapstate","title":"wifiGetApState()","text":"

      \u83b7\u53d6 WiFi AP\uff08\u70ed\u70b9\uff09\u72b6\u6001\u3002

      wifiGetApState()\n

      \u8fd4\u56de\uff1a \u70ed\u70b9\u72b6\u6001

      "},{"location":"qsl4a/connectivity/wifi/#wifi","title":"WiFi \u9501","text":""},{"location":"qsl4a/connectivity/wifi/#wifilockacquirefull","title":"wifiLockAcquireFull()","text":"

      \u83b7\u53d6\u5b8c\u6574 WiFi \u9501\uff08\u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\u4e5f\u4fdd\u6301 WiFi \u6d3b\u52a8\uff09\u3002

      wifiLockAcquireFull()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifilockacquirescanonly","title":"wifiLockAcquireScanOnly()","text":"

      \u83b7\u53d6\u4ec5\u626b\u63cf WiFi \u9501\u3002

      wifiLockAcquireScanOnly()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifilockrelease","title":"wifiLockRelease()","text":"

      \u91ca\u653e WiFi \u9501\u3002

      wifiLockRelease()\n
      "},{"location":"qsl4a/connectivity/wifi/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u68c0\u67e5 WiFi \u72b6\u6001\nif droid.checkWifiState().result:\n    print(\"WiFi is enabled\")\nelse:\n    print(\"Enabling WiFi...\")\n    droid.toggleWifiState(True)\n    time.sleep(2)\n\n# \u5f00\u59cb\u626b\u63cf\ndroid.wifiStartScan()\ntime.sleep(3)\n\n# \u83b7\u53d6\u626b\u63cf\u7ed3\u679c\nnetworks = droid.wifiGetScanResults().result\nfor network in networks:\n    print(f\"SSID: {network.get('SSID')}, Signal: {network.get('level')} dBm\")\n\n# \u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\ninfo = droid.wifiGetConnectionInfo().result\nif info:\n    print(f\"Connected to: {info.get('ssid')}\")\n    print(f\"BSSID: {info.get('bssid')}\")\n    print(f\"IP: {info.get('ip_address')}\")\n\n# \u83b7\u53d6 DHCP \u4fe1\u606f\ndhcp = droid.getDhcpInfo().result\nif dhcp:\n    print(f\"Gateway: {dhcp.get('gateway')}\")\n    print(f\"DNS: {dhcp.get('dns1')}\")\n\n# \u83b7\u53d6\u7b80\u5316\u7684\u8fde\u63a5\u4fe1\u606f\nconnected = droid.getConnectedInfo().result\nprint(f\"SSID: {connected.get('ssid')}, Signal: {connected.get('level')} dBm\")\n\n# \u65ad\u5f00\u5e76\u91cd\u65b0\u8fde\u63a5\ndroid.wifiDisconnect()\ntime.sleep(1)\ndroid.wifiReconnect()\n\n# \u91cd\u65b0\u5173\u8054\u63a5\u5165\u70b9\ndroid.wifiReassociate()\n\n# \u68c0\u67e5\u70ed\u70b9\u72b6\u6001\nap_state = droid.wifiGetApState().result\nprint(f\"Hotspot state: {ap_state}\")\n\n# \u83b7\u53d6 WiFi \u9501\u4ee5\u8fdb\u884c\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireFull()\n# ... \u6267\u884c\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n\n# \u6216\u4f7f\u7528\u4ec5\u626b\u63cf\u9501\u4ee5\u8fdb\u884c\u8f83\u8f7b\u7684\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireScanOnly()\n# ... \u6267\u884c\u626b\u63cf\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n
      "},{"location":"qsl4a/core/android-base/","title":"Android \u57fa\u7840\u7c7b","text":"

      Android \u7c7b\u662f QSL4A \u7684\u6838\u5fc3\uff0c\u63d0\u4f9b\u4e86\u4e0e Android \u8fd0\u884c\u65f6\u7684\u8fde\u63a5\u548c RPC \u673a\u5236\u3002

      "},{"location":"qsl4a/core/android-base/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
      # \u529f\u80fd\u5b8c\u6574\u7248\u672c\uff08\u63a8\u8350\uff09\nimport androidhelper\ndroid = androidhelper.Android()\n\n# \u7b80\u5316\u7248\u672c\uff08\u5feb\u901f\uff0c\u5355\u5b9e\u4f8b\uff09\nimport android\ndroid = android.droid\n
      "},{"location":"qsl4a/core/android-base/#android_1","title":"\u7c7b\uff1aAndroid","text":""},{"location":"qsl4a/core/android-base/#_2","title":"\u6784\u9020\u51fd\u6570","text":"
      Android(addr=None)\n

      \u53c2\u6570\uff1a - addr (tuple, optional): (HOST, PORT) \u5730\u5740\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u73af\u5883\u53d8\u91cf AP_HOST \u548c AP_PORT

      \u73af\u5883\u53d8\u91cf\uff1a - AP_HOST - \u670d\u52a1\u5668\u4e3b\u673a\u5730\u5740 - AP_PORT - \u670d\u52a1\u5668\u7aef\u53e3 - AP_HANDSHAKE - \u8ba4\u8bc1\u4ee4\u724c

      "},{"location":"qsl4a/core/android-base/#_3","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/android-base/#_rpc","title":"_rpc()","text":"

      \u8c03\u7528 Android \u51fd\u6570\u7684\u5185\u90e8 RPC \u65b9\u6cd5\u3002

      _rpc(method, *args)\n

      \u53c2\u6570\uff1a - method (str): \u8981\u8c03\u7528\u7684\u65b9\u6cd5\u540d - *args: \u65b9\u6cd5\u7684\u53ef\u53d8\u53c2\u6570

      \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4\uff0c\u5305\u542b\u4ee5\u4e0b\u5b57\u6bb5\uff1a - id (int): \u8bf7\u6c42 ID - result: \u65b9\u6cd5\u8fd4\u56de\u503c - error (str or None): \u9519\u8bef\u4fe1\u606f\uff08\u5982\u679c\u5931\u8d25\uff09

      "},{"location":"qsl4a/core/android-base/#getattr","title":"getattr()","text":"

      \u52a8\u6001\u65b9\u6cd5\u5206\u53d1\u5668\u3002\u6240\u6709 Android \u65b9\u6cd5\u90fd\u901a\u8fc7\u5c5e\u6027\u67e5\u627e\u8bbf\u95ee\u3002

      # \u4ee5\u4e0b\u4e24\u79cd\u65b9\u5f0f\u7b49\u4ef7\uff1a\ndroid.makeToast(\"Hello\")\ndroid._rpc(\"makeToast\", \"Hello\")\n
      "},{"location":"qsl4a/core/android-base/#androidpy","title":"\u72ec\u7acb\u51fd\u6570\uff08android.py\uff09","text":"

      \u4f7f\u7528\u7b80\u5316\u7684 android \u6a21\u5757\u65f6\uff1a

      "},{"location":"qsl4a/core/android-base/#jsla","title":"jsla()","text":"

      \u53d1\u9001 JSON-RPC \u8bf7\u6c42\u5e76\u8fd4\u56de\u539f\u59cb\u54cd\u5e94\u3002

      jsla(method, *params)\n

      \u8fd4\u56de\uff1a JSON \u5b57\u7b26\u4e32\u54cd\u5e94

      "},{"location":"qsl4a/core/android-base/#rsla","title":"rsla()","text":"

      \u53d1\u9001\u8bf7\u6c42\u5e76\u4ec5\u8fd4\u56de\u7ed3\u679c\u3002

      rsla(method, *params)\n

      \u8fd4\u56de\uff1a RPC \u8c03\u7528\u7684\u7ed3\u679c\u503c

      "},{"location":"qsl4a/core/android-base/#esla","title":"esla()","text":"

      \u53d1\u9001\u8bf7\u6c42\uff0c\u9519\u8bef\u65f6\u629b\u51fa\u5f02\u5e38\u3002

      esla(method, *params)\n

      \u629b\u51fa\uff1a \u5982\u679c error \u5b57\u6bb5\u4e0d\u4e3a None \u5219\u629b\u51fa\u5f02\u5e38

      "},{"location":"qsl4a/core/android-base/#nsla","title":"nsla()","text":"

      \u53d1\u9001\u8bf7\u6c42\u5e76\u8fd4\u56de Result \u547d\u540d\u5143\u7ec4\u3002

      nsla(method, *params)\n

      \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4

      "},{"location":"qsl4a/core/android-base/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/android-base/#_5","title":"\u57fa\u672c\u8fde\u63a5","text":"
      import androidhelper\n\n# \u8fde\u63a5\u5230 Android \u8fd0\u884c\u65f6\ndroid = androidhelper.Android()\n\n# \u901a\u8fc7\u663e\u793a toast \u6765\u68c0\u67e5\u8fde\u63a5\ndroid.makeToast(\"Connected!\")\n
      "},{"location":"qsl4a/core/android-base/#_6","title":"\u9519\u8bef\u5904\u7406","text":"
      result = droid.someMethod()\nif result.error:\n    print(f\"Error: {result.error}\")\nelse:\n    print(f\"Success: {result.result}\")\n
      "},{"location":"qsl4a/core/android-base/#rpc","title":"\u76f4\u63a5 RPC \u8c03\u7528","text":"
      # \u76f4\u63a5\u8c03\u7528\u4efb\u610f\u65b9\u6cd5\nresult = droid._rpc(\"makeToast\", \"Hello World\")\n
      "},{"location":"qsl4a/core/events/","title":"\u4e8b\u4ef6\u7cfb\u7edf","text":"

      QSL4A \u63d0\u4f9b\u4e86\u4e00\u4e2a\u4e8b\u4ef6\u7cfb\u7edf\uff0c\u7528\u4e8e\u5904\u7406\u6765\u81ea Android \u7684\u5f02\u6b65\u4e8b\u4ef6\uff0c\u5982\u4f20\u611f\u5668\u66f4\u65b0\u3001\u4f4d\u7f6e\u53d8\u5316\u548c\u81ea\u5b9a\u4e49\u5e7f\u64ad\u3002

      "},{"location":"qsl4a/core/events/#_2","title":"\u4e8b\u4ef6\u57fa\u7840","text":"

      \u4e8b\u4ef6\u5b58\u50a8\u5728\u7f13\u51b2\u533a\u4e2d\uff0c\u53ef\u4ee5\u8f6e\u8be2\u6216\u7b49\u5f85\u3002\u6bcf\u4e2a\u4e8b\u4ef6\u5305\u542b\uff1a - name: \u4e8b\u4ef6\u7c7b\u578b/\u540d\u79f0 - data: \u4e8b\u4ef6\u8d1f\u8f7d\u6570\u636e - time: \u65f6\u95f4\u6233

      "},{"location":"qsl4a/core/events/#_3","title":"\u4e8b\u4ef6\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#eventclearbuffer","title":"eventClearBuffer()","text":"

      \u6e05\u9664\u7f13\u51b2\u533a\u4e2d\u7684\u6240\u6709\u5f85\u5904\u7406\u4e8b\u4ef6\u3002

      eventClearBuffer()\n

      \u8fd4\u56de\uff1a None

      "},{"location":"qsl4a/core/events/#eventpoll","title":"eventPoll()","text":"

      \u8f6e\u8be2\u7f13\u51b2\u533a\u4e2d\u7684\u4e8b\u4ef6\u3002

      eventPoll(number_of_events=1)\n

      \u53c2\u6570\uff1a - number_of_events (int): \u8981\u68c0\u7d22\u7684\u6700\u5927\u4e8b\u4ef6\u6570\uff08\u9ed8\u8ba4\uff1a1\uff09

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\u5217\u8868

      "},{"location":"qsl4a/core/events/#eventwait","title":"eventWait()","text":"

      \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\u3002

      eventWait(timeout=None)\n

      \u53c2\u6570\uff1a - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09\u3002None = \u6c38\u4e45\u7b49\u5f85

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

      "},{"location":"qsl4a/core/events/#eventwaitfor","title":"eventWaitFor()","text":"

      \u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6\u3002

      eventWaitFor(eventName, timeout=None)\n

      \u53c2\u6570\uff1a - eventName (str): \u8981\u7b49\u5f85\u7684\u4e8b\u4ef6\u540d\u79f0 - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

      "},{"location":"qsl4a/core/events/#eventpost","title":"eventPost()","text":"

      \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\u3002

      eventPost(name, data, enqueue=None)\n

      \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e\uff08\u4efb\u610f\u7c7b\u578b\uff09 - enqueue (bool, optional): \u5982\u679c\u4e3a True \u5219\u6dfb\u52a0\u5230\u961f\u5217

      "},{"location":"qsl4a/core/events/#receiveevent","title":"receiveEvent()","text":"

      \u63a5\u6536\u4e8b\u4ef6\uff08\u963b\u585e\uff09\u3002

      receiveEvent()\n

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61

      "},{"location":"qsl4a/core/events/#_4","title":"\u5e7f\u64ad\u4e8b\u4ef6","text":"

      \u6ce8\u518c\u7cfb\u7edf\u5e7f\u64ad\u4e8b\u4ef6\u3002

      "},{"location":"qsl4a/core/events/#eventregisterforbroadcast","title":"eventRegisterForBroadcast()","text":"

      \u6ce8\u518c\u63a5\u6536\u5e7f\u64ad\u4e8b\u4ef6\u3002

      eventRegisterForBroadcast(category, enqueue=True)\n

      \u53c2\u6570\uff1a - category (str): \u5e7f\u64ad\u7c7b\u522b/\u52a8\u4f5c - enqueue (bool): \u6dfb\u52a0\u5230\u4e8b\u4ef6\u961f\u5217

      "},{"location":"qsl4a/core/events/#eventunregisterforbroadcast","title":"eventUnregisterForBroadcast()","text":"

      \u53d6\u6d88\u6ce8\u518c\u5e7f\u64ad\u4e8b\u4ef6\u3002

      eventUnregisterForBroadcast(category)\n
      "},{"location":"qsl4a/core/events/#eventgetbrodcastcategories","title":"eventGetBrodcastCategories()","text":"

      \u83b7\u53d6\u5df2\u6ce8\u518c\u7684\u5e7f\u64ad\u7c7b\u522b\u3002

      eventGetBrodcastCategories()\n

      \u8fd4\u56de\uff1a \u5df2\u6ce8\u518c\u7c7b\u522b\u5217\u8868

      "},{"location":"qsl4a/core/events/#_5","title":"\u4e8b\u4ef6\u5206\u53d1\u5668)","text":""},{"location":"qsl4a/core/events/#starteventdispatcher","title":"startEventDispatcher()","text":"

      \u6253\u5f00\u4e00\u4e2a\u53ef\u4ee5\u8bfb\u53d6\u5df2\u53d1\u5e03\u4e8b\u4ef6\u7684\u5957\u63a5\u5b57\u3002)

      startEventDispatcher(port=0)\n

      \u53c2\u6570\uff1a - port (int, optional): \u76d1\u542c\u7684\u7aef\u53e3\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\u9009\u62e9\uff09

      \u8fd4\u56de\uff1a \u6b63\u5728\u76d1\u542c\u7684\u7aef\u53e3\u53f7

      "},{"location":"qsl4a/core/events/#stopeventdispatcher","title":"stopEventDispatcher()","text":"

      \u505c\u6b62\u4e8b\u4ef6\u670d\u52a1\u5668\u3002)

      stopEventDispatcher()\n
      "},{"location":"qsl4a/core/events/#_6","title":"\u5df2\u5e9f\u5f03\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#rpcpostevent","title":"rpcPostEvent()","text":"

      \u5c06\u4e8b\u4ef6\u53d1\u5e03\u5230\u4e8b\u4ef6\u961f\u5217\u3002\uff08\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 eventPost\uff09

      rpcPostEvent(name, data)\n

      \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e

      "},{"location":"qsl4a/core/events/#_7","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/events/#_8","title":"\u57fa\u672c\u4e8b\u4ef6\u8f6e\u8be2","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6e05\u9664\u65e7\u4e8b\u4ef6\ndroid.eventClearBuffer()\n\n# \u8f6e\u8be2\u4e8b\u4ef6\nevents = droid.eventPoll(5).result\nfor event in events:\n    print(f\"Event: {event['name']}, Data: {event['data']}\")\n
      "},{"location":"qsl4a/core/events/#_9","title":"\u7b49\u5f85\u4e8b\u4ef6","text":"
      # \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\uff0c\u5e26\u8d85\u65f6\nevent = droid.eventWait(timeout=10).result\nif event:\n    print(f\"Got event: {event['name']}\")\n
      "},{"location":"qsl4a/core/events/#_10","title":"\u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6","text":"
      # \u7b49\u5f85\u4f20\u611f\u5668\u4e8b\u4ef6\nevent = droid.eventWaitFor('screen', timeout=5).result\nif event:\n    print(f\"Screen event: {event['data']}\")\n
      "},{"location":"qsl4a/core/events/#_11","title":"\u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6","text":"
      # \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\ndroid.eventPost('my_event', {'key': 'value'})\n\n# \u7b49\u5f85\u5b83\nevent = droid.eventWaitFor('my_event', timeout=1).result\n
      "},{"location":"qsl4a/core/events/#_12","title":"\u5e7f\u64ad\u63a5\u6536\u5668","text":"
      # \u6ce8\u518c\u5c4f\u5e55\u5f00\u5173\u4e8b\u4ef6\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_ON')\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_OFF')\n\n# \u7b49\u5f85\u5c4f\u5e55\u4e8b\u4ef6\nwhile True:\n    event = droid.receiveEvent().result\n    if event['name'] == 'android.intent.action.SCREEN_ON':\n        print(\"Screen turned on\")\n    elif event['name'] == 'android.intent.action.SCREEN_OFF':\n        print(\"Screen turned off\")\n
      "},{"location":"qsl4a/core/events/#_13","title":"\u4f20\u611f\u5668\u4e8b\u4ef6\u5904\u7406","text":"
      # \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u5904\u7406\u4f20\u611f\u5668\u4e8b\u4ef6\nfor _ in range(100):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'sensors':\n        data = event['data']\n        print(f\"Accel: {data['xforce']}, {data['yforce']}, {data['zforce']}\")\n\ndroid.stopSensing()\n
      "},{"location":"qsl4a/core/events/#_14","title":"\u5e38\u89c1\u4e8b\u4ef6\u7c7b\u578b","text":"\u4e8b\u4ef6\u540d\u79f0 \u63cf\u8ff0 \u6765\u6e90 sensors \u4f20\u611f\u5668\u6570\u636e\u66f4\u65b0 startSensing* location GPS \u4f4d\u7f6e\u66f4\u65b0 startLocating phone \u7535\u8bdd\u72b6\u6001\u53d8\u5316 startTrackingPhoneState signal \u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316 startTrackingSignalStrength screen \u622a\u56fe\u5c31\u7eea fullGetScreenShot dialog \u5bf9\u8bdd\u6846\u54cd\u5e94 dialogShow*"},{"location":"qsl4a/core/events/#_15","title":"\u4e8b\u4ef6\u6570\u636e\u7ed3\u6784","text":"
      {\n    'name': 'event_name',\n    'data': {\n        # \u4e8b\u4ef6\u7279\u5b9a\u6570\u636e\n    },\n    'time': 1234567890  # \u65f6\u95f4\u6233\n}\n
      "},{"location":"qsl4a/core/intent/","title":"Intent \u7cfb\u7edf","text":"

      Android Intent \u7528\u4e8e\u542f\u52a8\u6d3b\u52a8\u3001\u53d1\u9001\u5e7f\u64ad\u548c\u5e94\u7528\u95f4\u901a\u4fe1\u3002QSL4A \u901a\u8fc7 Intent \u6a21\u5757\u63d0\u4f9b\u5b8c\u6574\u7684 Intent \u652f\u6301\u3002

      "},{"location":"qsl4a/core/intent/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
      import androidhelper\ndon = androidhelper.Android()\n
      "},{"location":"qsl4a/core/intent/#intent_1","title":"Intent \u5e38\u91cf","text":"

      \u901a\u8fc7 droid.Intent \u8bbf\u95ee\uff1a

      "},{"location":"qsl4a/core/intent/#_2","title":"\u64cd\u4f5c","text":"\u5e38\u91cf \u503c \u7528\u9014 ACTION_MAIN android.intent.action.MAIN \u5e94\u7528\u5165\u53e3\u70b9 ACTION_VIEW android.intent.action.VIEW \u67e5\u770b\u5185\u5bb9 ACTION_EDIT android.intent.action.EDIT \u7f16\u8f91\u5185\u5bb9 ACTION_PICK android.intent.action.PICK \u9009\u62e9\u9879\u76ee ACTION_SEND android.intent.action.SEND \u5206\u4eab\u5185\u5bb9 ACTION_SEARCH android.intent.action.SEARCH \u641c\u7d22"},{"location":"qsl4a/core/intent/#_3","title":"\u6807\u5fd7","text":"\u5e38\u91cf \u503c \u7528\u9014 FLAG_ACTIVITY_NEW_TASK 268435456 \u542f\u52a8\u65b0\u4efb\u52a1 FLAG_ACTIVITY_CLEAR_TASK 32768 \u6e05\u9664\u4efb\u52a1\u5806\u6808 FLAG_ACTIVITY_NEW_DOCUMENT 524288 \u65b0\u6587\u6863\u6a21\u5f0f"},{"location":"qsl4a/core/intent/#_4","title":"\u9644\u52a0\u6570\u636e","text":"\u5e38\u91cf \u7528\u9014 EXTRA_TEXT \u6587\u672c\u5185\u5bb9 EXTRA_STREAM \u6587\u4ef6 URI EXTRA_SUBJECT \u4e3b\u9898\u884c EXTRA_EMAIL \u7535\u5b50\u90ae\u4ef6\u5730\u5740"},{"location":"qsl4a/core/intent/#_5","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/intent/#makeintent","title":"makeIntent()","text":"

      \u521b\u5efa Intent \u5bf9\u8c61\u3002

      makeIntent(action, uri=None, type=None, extras=None, categories=None,\n           packagename=None, classname=None, flags=None)\n

      \u53c2\u6570\uff1a - action (str): Intent \u64cd\u4f5c\uff08\u4f8b\u5982 droid.Intent.ACTION_VIEW\uff09 - uri (str, optional): \u6570\u636e URI - type (str, optional): MIME \u7c7b\u578b - extras (dict, optional): \u9644\u52a0\u6570\u636e - categories (list, optional): Intent \u7c7b\u522b - packagename (str, optional): \u76ee\u6807\u5305 - classname (str, optional): \u76ee\u6807\u7c7b - flags (int, optional): Intent \u6807\u5fd7

      \u8fd4\u56de\uff1a Intent \u5bf9\u8c61

      "},{"location":"qsl4a/core/intent/#startactivityintent","title":"startActivityIntent()","text":"

      \u4f7f\u7528 Intent \u542f\u52a8 Activity\u3002

      startActivityIntent(intent, wait=None)\n

      \u53c2\u6570\uff1a - intent: makeIntent() \u8fd4\u56de\u7684 Intent \u5bf9\u8c61 - wait (bool, optional): \u963b\u585e\u76f4\u5230\u6d3b\u52a8\u5173\u95ed

      "},{"location":"qsl4a/core/intent/#startactivityforresultintent","title":"startActivityForResultIntent()","text":"

      \u542f\u52a8\u6d3b\u52a8\u5e76\u7b49\u5f85\u7ed3\u679c\u3002

      startActivityForResultIntent(intent)\n

      \u8fd4\u56de\uff1a Activity \u7ed3\u679c

      "},{"location":"qsl4a/core/intent/#sendbroadcastintent","title":"sendBroadcastIntent()","text":"

      \u53d1\u9001\u5e7f\u64ad\u3002

      sendBroadcastIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#view","title":"view()","text":"

      \u901a\u8fc7 URI \u67e5\u770b\u5185\u5bb9\u3002

      view(uri, type=None, extras=None)\n
      "},{"location":"qsl4a/core/intent/#pick","title":"pick()","text":"

      \u4ece URI \u9009\u62e9\u5185\u5bb9\u3002

      pick(uri)\n
      "},{"location":"qsl4a/core/intent/#intent_2","title":"\u5e38\u89c1 Intent \u65b9\u6cd5)","text":""},{"location":"qsl4a/core/intent/#scanbarcode","title":"scanBarcode()","text":"

      \u542f\u52a8\u6761\u7801\u626b\u63cf\u5668\u3002

      scanBarcode()\n

      \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/core/intent/#send","title":"send()","text":"

      \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u5185\u5bb9\u3002

      send(type, content)\n

      \u53c2\u6570\uff1a - type (str): MIME \u7c7b\u578b - content (str): \u8981\u5206\u4eab\u7684\u5185\u5bb9

      "},{"location":"qsl4a/core/intent/#sendtext","title":"sendText()","text":"

      \u53d1\u9001\u6587\u672c\u5185\u5bb9\u3002

      sendText(text)\n

      \u53c2\u6570\uff1a - text (str): \u8981\u53d1\u9001\u7684\u6587\u672c

      "},{"location":"qsl4a/core/intent/#sendemail","title":"sendEmail()","text":"

      \u53d1\u9001\u7535\u5b50\u90ae\u4ef6\u3002

      sendEmail(to, subject, body, attachment=None)\n

      \u53c2\u6570\uff1a - to (str or list): \u6536\u4ef6\u4eba\u7535\u5b50\u90ae\u4ef6\u5730\u5740 - subject (str): \u7535\u5b50\u90ae\u4ef6\u4e3b\u9898 - body (str): \u7535\u5b50\u90ae\u4ef6\u6b63\u6587 - attachment (str, optional): \u9644\u4ef6\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/core/intent/#pathtouri","title":"pathToUri()","text":"

      \u5c06\u6587\u4ef6\u8def\u5f84\u8f6c\u6362\u4e3a\u5185\u5bb9 URI\u3002

      pathToUri(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5185\u5bb9 URI \u5b57\u7b26\u4e32

      "},{"location":"qsl4a/core/intent/#openfile","title":"openFile()","text":"

      \u7528\u9002\u5f53\u7684\u5e94\u7528\u7a0b\u5e8f\u6253\u5f00\u6587\u4ef6\u3002

      openFile(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u6253\u5f00\u7684\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/core/intent/#sendfile","title":"sendFile()","text":"

      \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u6587\u4ef6\u3002

      sendFile(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u53d1\u9001\u7684\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/core/intent/#getpathtype","title":"getPathType()","text":"

      \u83b7\u53d6\u6587\u4ef6\u8def\u5f84\u7684 MIME \u7c7b\u578b\u3002

      getPathType(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a MIME \u7c7b\u578b\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/core/intent/#viewmap","title":"viewMap()","text":"

      \u5728\u6307\u5b9a\u4f4d\u7f6e\u6253\u5f00\u5730\u56fe\u3002

      viewMap(latitude, longitude)\n

      \u53c2\u6570\uff1a - latitude (float): \u7eac\u5ea6 - longitude (float): \u7ecf\u5ea6

      "},{"location":"qsl4a/core/intent/#viewcontacts","title":"viewContacts()","text":"

      \u6253\u5f00\u8054\u7cfb\u4eba\u5e94\u7528\u3002

      viewContacts()\n
      "},{"location":"qsl4a/core/intent/#search","title":"search()","text":"

      \u6267\u884c\u7f51\u7edc\u641c\u7d22\u3002

      search(query)\n

      \u53c2\u6570\uff1a - query (str): \u641c\u7d22\u67e5\u8be2

      "},{"location":"qsl4a/core/intent/#viewhtml","title":"viewHtml()","text":"

      \u67e5\u770b HTML \u5185\u5bb9\u3002

      viewHtml(content, encoding=None)\n

      \u53c2\u6570\uff1a - content (str): HTML \u5185\u5bb9 - encoding (str, optional): \u5b57\u7b26\u7f16\u7801

      "},{"location":"qsl4a/core/intent/#webviewshow","title":"webViewShow()","text":"

      \u5728 WebView \u4e2d\u663e\u793a\u7f51\u9875\u5185\u5bb9\u3002\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 viewHtml\u3002

      webViewShow(url)\n

      \u53c2\u6570\uff1a - url (str): \u7f51\u9875 URL

      "},{"location":"qsl4a/core/intent/#editoropen","title":"editorOpen()","text":"

      \u6253\u5f00\u6587\u672c\u7f16\u8f91\u5668\u3002

      editorOpen(path=None, create=False)\n

      \u53c2\u6570\uff1a - path (str, optional): \u8981\u7f16\u8f91\u7684\u6587\u4ef6\u8def\u5f84 - create (bool, optional): \u5982\u679c\u4e0d\u5b58\u5728\u5219\u521b\u5efa

      "},{"location":"qsl4a/core/intent/#uri","title":"\u8f85\u52a9\u7c7b\uff1aUri","text":"

      \u521b\u5efa Intent \u7684 URI \u5bf9\u8c61\uff1a

      from androidhelper.Intent import Uri\n\nuri = Uri(\"file:///sdcard/test.txt\")\n
      "},{"location":"qsl4a/core/intent/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/intent/#_7","title":"\u6253\u5f00\u7f51\u9875","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"http://www.example.com\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_8","title":"\u5206\u4eab\u6587\u672c","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_TEXT: \"Hello from QPython!\",\n        droid.Intent.EXTRA_SUBJECT: \"Test\"\n    },\n    type=\"text/plain\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_9","title":"\u6253\u5f00\u6587\u4ef6","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"file:///sdcard/document.pdf\",\n    type=\"application/pdf\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_10","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":"
      result = droid.pickContact()\ncontact_uri = result.result\n
      "},{"location":"qsl4a/core/intent/#_11","title":"\u53d1\u9001\u7535\u5b50\u90ae\u4ef6","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_EMAIL: [\"test@example.com\"],\n        droid.Intent.EXTRA_SUBJECT: \"Hello\",\n        droid.Intent.EXTRA_TEXT: \"Message body\"\n    },\n    type=\"message/rfc822\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_12","title":"\u6253\u5f00\u5e94\u7528","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_MAIN,\n    packagename=\"com.android.settings\",\n    classname=\"com.android.settings.Settings\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/hardware/bluetooth/","title":"\u84dd\u7259 API","text":"

      \u63a7\u5236\u84dd\u7259\u9002\u914d\u5668\u5e76\u4e0e\u84dd\u7259\u8bbe\u5907\u901a\u4fe1\u3002

      "},{"location":"qsl4a/hardware/bluetooth/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/hardware/bluetooth/#togglebluetoothstate","title":"toggleBluetoothState()","text":"

      \u6253\u5f00/\u5173\u95ed\u84dd\u7259\u3002

      toggleBluetoothState(enabled=None, prompt=True)\n

      \u53c2\u6570\uff1a - enabled (bool): True=\u5f00\uff0cFalse=\u5173\uff0cNone=\u5207\u6362 - prompt (bool): \u663e\u793a\u7528\u6237\u63d0\u793a

      "},{"location":"qsl4a/hardware/bluetooth/#checkbluetoothstate","title":"checkBluetoothState()","text":"

      \u68c0\u67e5\u84dd\u7259\u662f\u5426\u5df2\u542f\u7528\u3002

      checkBluetoothState()\n

      \u8fd4\u56de\uff1a True/False

      "},{"location":"qsl4a/hardware/bluetooth/#getlocalname","title":"GetLocalName()","text":"

      \u83b7\u53d6\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

      GetLocalName()\n
      "},{"location":"qsl4a/hardware/bluetooth/#setlocalname","title":"SetLocalName()","text":"

      \u8bbe\u7f6e\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

      SetLocalName(name)\n
      "},{"location":"qsl4a/hardware/bluetooth/#getscanmode","title":"GetScanMode()","text":"

      \u83b7\u53d6\u53ef\u53d1\u73b0\u6027\u6a21\u5f0f\u3002

      GetScanMode()\n

      \u8fd4\u56de\uff1a - -1: \u5df2\u7981\u7528 - 0: \u4e0d\u53ef\u53d1\u73b0\uff0c\u4e0d\u53ef\u8fde\u63a5 - 1: \u53ef\u8fde\u63a5\uff0c\u4e0d\u53ef\u53d1\u73b0 - 3: \u53ef\u8fde\u63a5\u4e14\u53ef\u53d1\u73b0

      "},{"location":"qsl4a/hardware/bluetooth/#makediscoverable","title":"MakeDiscoverable()","text":"

      \u4f7f\u8bbe\u5907\u53ef\u53d1\u73b0\u3002

      MakeDiscoverable(duration=300)\n

      \u53c2\u6570\uff1a - duration (int): \u53ef\u53d1\u73b0\u7684\u79d2\u6570

      "},{"location":"qsl4a/hardware/bluetooth/#_2","title":"\u53d1\u73b0","text":""},{"location":"qsl4a/hardware/bluetooth/#discoverystart","title":"DiscoveryStart()","text":"

      \u5f00\u59cb\u8bbe\u5907\u53d1\u73b0\u3002

      DiscoveryStart()\n
      "},{"location":"qsl4a/hardware/bluetooth/#discoverycancel","title":"DiscoveryCancel()","text":"

      \u53d6\u6d88\u53d1\u73b0\u3002

      DiscoveryCancel()\n
      "},{"location":"qsl4a/hardware/bluetooth/#getreceiveddevices","title":"GetReceivedDevices()","text":"

      \u83b7\u53d6\u53d1\u73b0\u7684\u8bbe\u5907\u3002

      GetReceivedDevices()\n

      \u8fd4\u56de\uff1a \u8bbe\u5907\u4fe1\u606f\u5b57\u5178\u5217\u8868

      "},{"location":"qsl4a/hardware/bluetooth/#getbondeddevices","title":"GetBondedDevices()","text":"

      \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\u3002

      GetBondedDevices()\n

      \u8fd4\u56de\uff1a \u914d\u5bf9\u8bbe\u5907\u4fe1\u606f\u5217\u8868

      "},{"location":"qsl4a/hardware/bluetooth/#_3","title":"\u8fde\u63a5","text":""},{"location":"qsl4a/hardware/bluetooth/#connect","title":"Connect()","text":"

      \u8fde\u63a5\u5230\u8bbe\u5907\u3002

      Connect(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", address=None)\n

      \u53c2\u6570\uff1a - uuid (str): \u670d\u52a1 UUID - address (str): \u8bbe\u5907\u5730\u5740\uff08None = \u663e\u793a\u9009\u62e9\u5668\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/hardware/bluetooth/#accept","title":"Accept()","text":"

      \u63a5\u53d7\u4f20\u5165\u8fde\u63a5\u3002

      Accept(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", timeout=0)\n
      "},{"location":"qsl4a/hardware/bluetooth/#activeconnections","title":"ActiveConnections()","text":"

      \u68c0\u67e5\u6d3b\u52a8\u8fde\u63a5\u3002

      ActiveConnections()\n
      "},{"location":"qsl4a/hardware/bluetooth/#stop","title":"Stop()","text":"

      \u65ad\u5f00\u8fde\u63a5\u3002

      Stop(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#_4","title":"\u901a\u4fe1","text":""},{"location":"qsl4a/hardware/bluetooth/#write","title":"Write()","text":"

      \u53d1\u9001 ASCII \u6570\u636e\u3002

      Write(ascii, connID=\"\")\n
      "},{"location":"qsl4a/hardware/bluetooth/#writebinary","title":"WriteBinary()","text":"

      \u53d1\u9001\u4e8c\u8fdb\u5236\u6570\u636e\uff08base64 \u7f16\u7801\uff09\u3002

      WriteBinary(base64, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#read","title":"Read()","text":"

      \u8bfb\u53d6 ASCII \u6570\u636e\u3002

      Read(bufferSize=4096, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readbinary","title":"ReadBinary()","text":"

      \u8bfb\u53d6\u4e8c\u8fdb\u5236\u6570\u636e\u3002

      ReadBinary(bufferSize=4096, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readline","title":"ReadLine()","text":"

      \u8bfb\u53d6\u4e00\u884c\u3002

      ReadLine(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readready","title":"ReadReady()","text":"

      \u68c0\u67e5\u662f\u5426\u6709\u53ef\u7528\u6570\u636e\u3002

      ReadReady(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u7528\u84dd\u7259\ndroid.toggleBluetoothState(True)\n\n# \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\ndevices = droid.GetBondedDevices().result\nfor dev in devices:\n    print(f\"{dev['name']}: {dev['address']}\")\n\n# \u8fde\u63a5\u5230\u8bbe\u5907\ndroid.Connect(address=\"00:11:22:33:44:55\")\n\n# \u53d1\u9001\u6570\u636e\ndroid.Write(\"Hello Bluetooth!\")\n\n# \u8bfb\u53d6\u54cd\u5e94\ndata = droid.Read(1024).result\n
      "},{"location":"qsl4a/hardware/camera/","title":"\u76f8\u673a API","text":"

      \u62cd\u6444\u7167\u7247\u548c\u5f55\u5236\u89c6\u9891\u3002

      "},{"location":"qsl4a/hardware/camera/#_1","title":"\u7167\u7247\u62cd\u6444","text":""},{"location":"qsl4a/hardware/camera/#takepicture","title":"takePicture()","text":"

      \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u6444\u7167\u7247\u3002

      takePicture(path=None)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8fd4\u56de\u56fe\u50cf\u6570\u636e

      \u8fd4\u56de\uff1a \u56fe\u50cf\u8def\u5f84\u6216\u56fe\u50cf\u6570\u636e

      "},{"location":"qsl4a/hardware/camera/#cameracapturepicture","title":"cameraCapturePicture()","text":"

      \u4f7f\u7528\u9ad8\u7ea7\u76f8\u673a\u63a7\u5236\u62cd\u6444\u7167\u7247\u3002

      cameraCapturePicture(targetPath=None, cameraId=0, useAutoFocus=True)\n

      \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - useAutoFocus (bool): \u542f\u7528\u81ea\u52a8\u5bf9\u7126

      \u8fd4\u56de\uff1a \u62cd\u6444\u7684\u56fe\u50cf\u8def\u5f84

      "},{"location":"qsl4a/hardware/camera/#camerasettorchmode","title":"cameraSetTorchMode()","text":"

      \u63a7\u5236\u76f8\u673a\u95ea\u5149\u706f/\u624b\u7535\u7b52\u3002

      cameraSetTorchMode(enabled)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u6253\u5f00\uff0cFalse \u5173\u95ed

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/hardware/camera/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

      \u622a\u56fe\u3002

      imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

      "},{"location":"qsl4a/hardware/camera/#_2","title":"\u89c6\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#takevideo","title":"takeVideo()","text":"

      \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\u3002

      takeVideo(path=None, quality=1)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-4\uff09 - 0: 160x120 - 1: 320x240 - 2: 352x288 - 3: 640x480 - 4: 800x480

      "},{"location":"qsl4a/hardware/camera/#recordercapturevideo","title":"recorderCaptureVideo()","text":"

      \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\u3002

      recorderCaptureVideo(targetPath=None, duration=10, cameraId=0, quality=8)\n

      \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - duration (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a10\uff09 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-8\uff0c\u8d8a\u9ad8\u8d8a\u597d\uff09

      \u8fd4\u56de\uff1a \u89c6\u9891\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/hardware/camera/#recordaudio","title":"recordAudio()","text":"

      \u5f55\u5236\u97f3\u9891\u3002

      recordAudio()\n

      \u8fd4\u56de\uff1a \u97f3\u9891\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/hardware/camera/#_3","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

      \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\u3002

      recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

      \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\uff09 - targetPixels (int): \u5206\u8fa8\u7387 - frameRate (int): FPS - bitRate (int): \u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa - autoStart (bool): \u7acb\u5373\u5f00\u59cb

      "},{"location":"qsl4a/hardware/camera/#recorderstart","title":"recorderStart()","text":"

      \u5f00\u59cb\u5f55\u5236\u3002

      recorderStart()\n
      "},{"location":"qsl4a/hardware/camera/#recorderpause","title":"recorderPause()","text":"

      \u6682\u505c\u5f55\u5236\u3002

      recorderPause()\n
      "},{"location":"qsl4a/hardware/camera/#recorderresume","title":"recorderResume()","text":"

      \u6062\u590d\u5f55\u5236\u3002

      recorderResume()\n
      "},{"location":"qsl4a/hardware/camera/#_4","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/camera/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

      \u5f00\u59cb\u97f3\u91cf\u68c0\u6d4b\u3002

      recorderSoundVolumeDetect(interval=100)\n
      "},{"location":"qsl4a/hardware/camera/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

      \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

      recorderSoundVolumeGetDb()\n
      "},{"location":"qsl4a/hardware/camera/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u7167\nphoto_path = droid.takePicture(\"/sdcard/photo.jpg\").result\nprint(f\"Photo saved: {photo_path}\")\n\n# \u4f7f\u7528\u524d\u7f6e\u76f8\u673a\u548c\u81ea\u52a8\u5bf9\u7126\u62cd\u7167\ncamera_path = droid.cameraCapturePicture(\"/sdcard/selfie.jpg\", cameraId=1, useAutoFocus=True).result\nprint(f\"Front camera photo: {camera_path}\")\n\n# \u63a7\u5236\u95ea\u5149\u706f\ndroid.cameraSetTorchMode(True)  # \u6253\u5f00\u95ea\u5149\u706f\n\n# \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\nvideo_path = droid.takeVideo(\"/sdcard/video.mp4\", quality=3).result\nprint(f\"Video saved: {video_path}\")\n\n# \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\nvideo_path = droid.recorderCaptureVideo(\"/sdcard/movie.mp4\", duration=30, cameraId=0, quality=8).result\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n
      "},{"location":"qsl4a/hardware/recorder/","title":"\u97f3\u9891\u5f55\u5236 API","text":"

      \u4ece\u9ea6\u514b\u98ce\u548c\u8bbe\u5907\u5c4f\u5e55\u5f55\u5236\u97f3\u9891\u3002

      "},{"location":"qsl4a/hardware/recorder/#_1","title":"\u97f3\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recordaudio","title":"recordAudio()","text":"

      \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\u3002

      recordAudio()\n

      \u8fd4\u56de\uff1a \u5f55\u5236\u7684\u97f3\u9891\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/hardware/recorder/#recorderstartmicrophone","title":"recorderStartMicrophone()","text":"

      \u5f00\u59cb\u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\u3002

      recorderStartMicrophone(targetPath=None)\n

      \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u5f55\u5236\u7684\u8def\u5f84

      "},{"location":"qsl4a/hardware/recorder/#_2","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

      \u5f00\u59cb\u5e26\u97f3\u9891\u7684\u5c4f\u5e55\u5f55\u5236\u3002

      recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

      \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\u97f3\u9891\uff09 - targetPixels (int): \u76ee\u6807\u5206\u8fa8\u7387\uff08\u50cf\u7d20\uff09 - frameRate (int): \u6bcf\u79d2\u5e27\u6570\uff08\u9ed8\u8ba4\uff1a30\uff09 - bitRate (int): \u89c6\u9891\u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa\u89c6\u9891 - autoStart (bool): \u7acb\u5373\u5f00\u59cb\u5f55\u5236

      \u8fd4\u56de\uff1a \u64cd\u4f5c\u7ed3\u679c

      "},{"location":"qsl4a/hardware/recorder/#recorderstart","title":"recorderStart()","text":"

      \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\uff08\u5f53 autoStart=False \u65f6\uff09\u3002

      recorderStart()\n
      "},{"location":"qsl4a/hardware/recorder/#recorderpause","title":"recorderPause()","text":"

      \u6682\u505c\u6b63\u5728\u8fdb\u884c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

      recorderPause()\n
      "},{"location":"qsl4a/hardware/recorder/#recorderresume","title":"recorderResume()","text":"

      \u6062\u590d\u6682\u505c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

      recorderResume()\n
      "},{"location":"qsl4a/hardware/recorder/#_3","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/recorder/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

      \u5f00\u59cb\u76d1\u63a7\u97f3\u91cf\u7ea7\u522b\u3002

      recorderSoundVolumeDetect(interval=100)\n

      \u53c2\u6570\uff1a - interval (int): \u68c0\u6d4b\u95f4\u9694\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a100\uff09

      "},{"location":"qsl4a/hardware/recorder/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

      \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

      recorderSoundVolumeGetDb()\n

      \u8fd4\u56de\uff1a \u5f53\u524d\u97f3\u91cf\u7ea7\u522b\uff08dB\uff09

      "},{"location":"qsl4a/hardware/recorder/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\nprint(\"Recording audio...\")\naudio_path = droid.recordAudio().result\nprint(f\"Saved to: {audio_path}\")\n\n# \u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\ndroid.recorderStartMicrophone(\"/sdcard/my_recording.mp3\")\ntime.sleep(5)\ndroid.recorderStop()\n\n# \u5e26\u97f3\u9891\u5f55\u5236\u5c4f\u5e55\nprint(\"Starting screen recording...\")\ndroid.recorderStartScreenRecord(\n    path=\"/sdcard/screen_record.mp4\",\n    audio=1,\n    frameRate=30,\n    autoStart=True\n)\ntime.sleep(10)\ndroid.recorderStop()\n\n# \u76d1\u63a7\u97f3\u91cf\ndroid.recorderSoundVolumeDetect(interval=100)\ntime.sleep(3)\nvolume = droid.recorderSoundVolumeGetDb().result\nprint(f\"Current volume: {volume} dB\")\n
      "},{"location":"qsl4a/hardware/usbserial/","title":"USB \u4e3b\u673a\u4e32\u884c API","text":"

      \u4e0e USB \u4e32\u884c\u8bbe\u5907\u901a\u4fe1\uff08\u9700\u8981 USB OTG \u652f\u6301\u548c Android 3.1+\uff09\u3002

      "},{"location":"qsl4a/hardware/usbserial/#usb","title":"USB \u4e32\u884c\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialopen","title":"usbHostSerialOpen()","text":"

      \u6253\u5f00\u4e0e USB \u4e32\u884c\u8bbe\u5907\u7684\u8fde\u63a5\u3002

      usbHostSerialOpen(device, baudRate=9600)\n

      \u53c2\u6570\uff1a - device (str): USB \u8bbe\u5907\u8def\u5f84\u6216\u6807\u8bc6\u7b26 - baudRate (int): \u6ce2\u7279\u7387\uff08\u9ed8\u8ba4\uff1a9600\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u6253\u5f00\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialclose","title":"usbHostSerialClose()","text":"

      \u5173\u95ed USB \u4e32\u884c\u8fde\u63a5\u3002

      usbHostSerialClose()\n
      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialread","title":"usbHostSerialRead()","text":"

      \u4ece USB \u4e32\u884c\u8bfb\u53d6\u6570\u636e\u3002

      usbHostSerialRead(bufferSize=1024)\n

      \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570\uff08\u9ed8\u8ba4\uff1a1024\uff09

      \u8fd4\u56de\uff1a \u8bfb\u53d6\u7684\u6570\u636e\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwrite","title":"usbHostSerialWrite()","text":"

      \u5411 USB \u4e32\u884c\u5199\u5165\u6570\u636e\u3002

      usbHostSerialWrite(data)\n

      \u53c2\u6570\uff1a - data (str): \u8981\u5199\u5165\u7684\u5b57\u7b26\u4e32\u6570\u636e

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialavailable","title":"usbHostSerialAvailable()","text":"

      \u68c0\u67e5\u662f\u5426\u6709\u53ef\u8bfb\u53d6\u7684\u6570\u636e\u3002

      usbHostSerialAvailable()\n

      \u8fd4\u56de\uff1a \u53ef\u7528\u5b57\u8282\u6570

      "},{"location":"qsl4a/hardware/usbserial/#_1","title":"\u914d\u7f6e\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetbaudrate","title":"usbHostSerialSetBaudRate()","text":"

      \u8bbe\u7f6e\u6ce2\u7279\u7387\u3002

      usbHostSerialSetBaudRate(baudRate)\n

      \u53c2\u6570\uff1a - baudRate (int): \u6ce2\u7279\u7387

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetdatabits","title":"usbHostSerialSetDataBits()","text":"

      \u8bbe\u7f6e\u6570\u636e\u4f4d\uff085\u30016\u30017 \u6216 8\uff09\u3002

      usbHostSerialSetDataBits(dataBits)\n

      \u53c2\u6570\uff1a - dataBits (int): \u6570\u636e\u4f4d\uff085-8\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetstopbits","title":"usbHostSerialSetStopBits()","text":"

      \u8bbe\u7f6e\u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09\u3002

      usbHostSerialSetStopBits(stopBits)\n

      \u53c2\u6570\uff1a - stopBits (float): \u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetparity","title":"usbHostSerialSetParity()","text":"

      \u8bbe\u7f6e\u6821\u9a8c\u4f4d\uff08\u65e0\u3001\u5947\u3001\u5076\u3001\u6807\u8bb0\u3001\u7a7a\u683c\uff09\u3002

      usbHostSerialSetParity(parity)\n

      \u53c2\u6570\uff1a - parity (str): \u6821\u9a8c\u6a21\u5f0f\uff08'none'\u3001'odd'\u3001'even'\u3001'mark'\u3001'space'\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetflowcontrol","title":"usbHostSerialSetFlowControl()","text":"

      \u8bbe\u7f6e\u6d41\u63a7\u5236\uff08\u65e0\u3001\u786c\u4ef6\u3001\u8f6f\u4ef6\uff09\u3002

      usbHostSerialSetFlowControl(flowControl)\n

      \u53c2\u6570\uff1a - flowControl (str): \u6d41\u63a7\u5236\u6a21\u5f0f\uff08'none'\u3001'hardware'\u3001'software'\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialreadhex","title":"usbHostSerialReadHex()","text":"

      \u4ee5\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u8bfb\u53d6\u6570\u636e\u3002

      usbHostSerialReadHex(bufferSize=1024)\n

      \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570

      \u8fd4\u56de\uff1a \u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwritehex","title":"usbHostSerialWriteHex()","text":"

      \u4ece\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u5199\u5165\u6570\u636e\u3002

      usbHostSerialWriteHex(hexString)\n

      \u53c2\u6570\uff1a - hexString (str): \u8981\u5199\u5165\u7684\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/hardware/usbserial/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6253\u5f00 USB \u4e32\u884c\u8fde\u63a5\nif droid.usbHostSerialOpen(\"/dev/bus/usb/001/001\", 115200).result:\n    print(\"USB serial opened\")\n\n    # \u5199\u5165\u6570\u636e\n    droid.usbHostSerialWrite(\"AT\\r\")\n\n    # \u8bfb\u53d6\u54cd\u5e94\n    response = droid.usbHostSerialRead(1024).result\n    print(f\"Response: {response}\")\n\n    # \u6216\u4f7f\u7528\u5341\u516d\u8fdb\u5236\n    droid.usbHostSerialWriteHex(\"41540D0A\")  # \"AT\\r\\n\"\n\n    # \u5173\u95ed\u8fde\u63a5\n    droid.usbHostSerialClose()\n

      \u6ce8\u610f\uff1a USB \u4e32\u884c\u9700\u8981\uff1a - Android 3.1+ (API 12) - USB OTG \u7ebf/\u9002\u914d\u5668 - \u8bbe\u5907\u4e0a\u7684 USB \u4e3b\u673a\u6a21\u5f0f\u652f\u6301 - \u517c\u5bb9\u7684\u4e32\u884c\u8bbe\u5907

      "},{"location":"qsl4a/hardware/webcam/","title":"\u7f51\u7edc\u6444\u50cf\u5934 API","text":"

      \u4f7f\u7528 MJPEG \u4ece\u8bbe\u5907\u76f8\u673a\u6d41\u5f0f\u4f20\u8f93\u89c6\u9891\u3002

      "},{"location":"qsl4a/hardware/webcam/#mjpeg","title":"MJPEG \u6d41\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#webcamstart","title":"webcamStart()","text":"

      \u4ece\u7f51\u7edc\u6444\u50cf\u5934\u542f\u52a8 MJPEG \u6d41\u3002

      webcamStart(resolutionLevel=0, jpegQuality=20, port=0)\n

      \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf 1-100\uff08\u9ed8\u8ba4\uff1a20\uff09 - port (int): \u7aef\u53e3\u53f7\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\uff09

      \u8fd4\u56de\uff1a \u6d41\u7684 (\u5730\u5740, \u7aef\u53e3) \u5143\u7ec4

      "},{"location":"qsl4a/hardware/webcam/#webcamadjustquality","title":"webcamAdjustQuality()","text":"

      \u8c03\u6574\u6d3b\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u7684\u8d28\u91cf\u3002

      webcamAdjustQuality(resolutionLevel=0, jpegQuality=20)\n

      \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b - jpegQuality (int): JPEG \u8d28\u91cf 1-100

      "},{"location":"qsl4a/hardware/webcam/#webcamstop","title":"webcamStop()","text":"

      \u505c\u6b62\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u3002

      webcamStop()\n
      "},{"location":"qsl4a/hardware/webcam/#_1","title":"\u76f8\u673a\u9884\u89c8\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#camerastartpreview","title":"cameraStartPreview()","text":"

      \u5f00\u59cb\u5e26\u4e8b\u4ef6\u751f\u6210\u7684\u76f8\u673a\u9884\u89c8\u6a21\u5f0f\u3002

      cameraStartPreview(resolutionLevel=0, jpegQuality=20, filepath=None)\n

      \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf\uff08\u9ed8\u8ba4\uff1a20\uff09 - filepath (str, optional): \u4fdd\u5b58\u9884\u89c8\u5e27\u7684\u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      \u6ce8\u610f\uff1a \u751f\u6210\u5e26\u6709\u5e27\u6570\u636e\u7684 'preview' \u4e8b\u4ef6\u3002

      "},{"location":"qsl4a/hardware/webcam/#camerastoppreview","title":"cameraStopPreview()","text":"

      \u505c\u6b62\u76f8\u673a\u9884\u89c8\u3002

      cameraStopPreview()\n
      "},{"location":"qsl4a/hardware/webcam/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\nstream_info = droid.webcamStart(\n    resolutionLevel=0,\n    jpegQuality=30,\n    port=8080\n).result\nprint(f\"Stream available at {stream_info[0]}:{stream_info[1]}\")\n\n# \u6d41\u5f0f\u4f20\u8f93\u65f6\u8c03\u6574\u8d28\u91cf\ntime.sleep(5)\ndroid.webcamAdjustQuality(resolutionLevel=1, jpegQuality=50)\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.webcamStop()\n\n# \u6216\u4f7f\u7528\u9884\u89c8\u6a21\u5f0f\nprint(\"Starting preview...\")\ndroid.cameraStartPreview()\n\n# \u7b49\u5f85\u9884\u89c8\u4e8b\u4ef6\nfor i in range(10):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'preview':\n        print(f\"Got preview frame: {event['data']}\")\n\ndroid.cameraStopPreview()\n
      "},{"location":"qsl4a/media/image/","title":"\u56fe\u50cf\u5904\u7406 API","text":"

      \u538b\u7f29\u548c\u5904\u7406\u56fe\u50cf\u3002

      "},{"location":"qsl4a/media/image/#_1","title":"\u56fe\u50cf\u538b\u7f29","text":""},{"location":"qsl4a/media/image/#imagecompress","title":"imageCompress()","text":"

      \u538b\u7f29\u56fe\u50cf\u6587\u4ef6\u3002

      imageCompress(srcPath, destPath, targetByteSize=0, targetWidth=0, targetHeight=0)\n

      \u53c2\u6570\uff1a - srcPath (str): \u6e90\u56fe\u50cf\u8def\u5f84 - destPath (str): \u8f93\u51fa\u8def\u5f84 - targetByteSize (int): \u76ee\u6807\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff080 = \u65e0\u9650\u5236\uff09 - targetWidth (int): \u76ee\u6807\u5bbd\u5ea6\uff080 = \u539f\u59cb\uff09 - targetHeight (int): \u76ee\u6807\u9ad8\u5ea6\uff080 = \u539f\u59cb\uff09

      \u8fd4\u56de\uff1a \u538b\u7f29\u540e\u7684\u56fe\u50cf\u8def\u5f84

      "},{"location":"qsl4a/media/image/#_2","title":"\u622a\u56fe","text":""},{"location":"qsl4a/media/image/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

      \u622a\u53d6\u5c4f\u5e55\u3002

      imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

      \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

      \u8fd4\u56de\uff1a \u622a\u56fe\u8def\u5f84

      "},{"location":"qsl4a/media/image/#_3","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/image/#videoplay","title":"videoPlay()","text":"

      \u5728\u5168\u5c4f\u6a21\u5f0f\u4e0b\u64ad\u653e\u89c6\u9891\u6587\u4ef6\u3002

      videoPlay(path, wait=True)\n

      \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

      "},{"location":"qsl4a/media/image/#_4","title":"\u6761\u7801\u626b\u63cf","text":""},{"location":"qsl4a/media/image/#scanbarcodefromimage","title":"scanBarcodeFromImage()","text":"

      \u4ece\u56fe\u50cf\u6587\u4ef6\u626b\u63cf\u6761\u7801/\u4e8c\u7ef4\u7801\u3002

      scanBarcodeFromImage(path, compressRatio=0, x=0, y=0, width=0, height=0)\n

      \u53c2\u6570\uff1a - path (str): \u56fe\u50cf\u6587\u4ef6\u8def\u5f84 - compressRatio (int): \u538b\u7f29\u6bd4\uff080 = \u4e0d\u538b\u7f29\uff09 - x, y, width, height (int): \u8981\u626b\u63cf\u7684\u533a\u57df\uff080 = \u5b8c\u6574\u56fe\u50cf\uff09

      \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5185\u5bb9

      "},{"location":"qsl4a/media/image/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n\n# \u538b\u7f29\u56fe\u50cf\ncompressed = droid.imageCompress(\n    \"/sdcard/large_photo.jpg\",\n    \"/sdcard/compressed.jpg\",\n    targetByteSize=102400,  # \u76ee\u6807\u7ea6 100KB\n    targetWidth=1920,\n    targetHeight=1080\n).result\nprint(f\"Saved: {compressed}\")\n\n# \u64ad\u653e\u89c6\u9891\nvideo_path = \"/sdcard/movie.mp4\"\ndroid.videoPlay(video_path, wait=True)\n\n# \u4ece\u56fe\u50cf\u626b\u63cf\u6761\u7801\nresult = droid.scanBarcodeFromImage(\"/sdcard/qr_code.png\").result\nprint(f\"Barcode: {result}\")\n
      "},{"location":"qsl4a/media/mediaplayer/","title":"\u5a92\u4f53\u64ad\u653e\u5668 API","text":"

      \u63a7\u5236\u97f3\u9891\u548c\u89c6\u9891\u64ad\u653e\u3002

      "},{"location":"qsl4a/media/mediaplayer/#_1","title":"\u64ad\u653e\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplay","title":"mediaPlay()","text":"

      \u64ad\u653e\u5a92\u4f53\u6587\u4ef6\u3002

      mediaPlay(url, tag=\"default\", play=True)\n

      \u53c2\u6570\uff1a - url (str): \u5a92\u4f53\u6587\u4ef6\u8def\u5f84\u6216 URL - tag (str): \u64ad\u653e\u5668\u6807\u8bc6\u7b26 - play (bool): \u81ea\u52a8\u5f00\u59cb\u64ad\u653e

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaystart","title":"mediaPlayStart()","text":"

      \u5f00\u59cb\u64ad\u653e\u3002

      mediaPlayStart(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplaypause","title":"mediaPlayPause()","text":"

      \u6682\u505c\u64ad\u653e\u3002

      mediaPlayPause(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplayclose","title":"mediaPlayClose()","text":"

      \u5173\u95ed\u64ad\u653e\u5668\u3002

      mediaPlayClose(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplayseek","title":"mediaPlaySeek()","text":"

      \u8df3\u8f6c\u5230\u4f4d\u7f6e\u3002

      mediaPlaySeek(msec, tag=\"default\")\n

      \u53c2\u6570\uff1a - msec (int): \u4f4d\u7f6e\uff08\u6beb\u79d2\uff09

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaysetlooping","title":"mediaPlaySetLooping()","text":"

      \u8bbe\u7f6e\u5faa\u73af\u6a21\u5f0f\u3002

      mediaPlaySetLooping(enabled, tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#_2","title":"\u64ad\u653e\u5668\u4fe1\u606f","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplayinfo","title":"mediaPlayInfo()","text":"

      \u83b7\u53d6\u64ad\u653e\u4fe1\u606f\u3002

      mediaPlayInfo(tag=\"default\")\n

      \u8fd4\u56de\uff1a \u5305\u542b\u65f6\u957f\u3001\u4f4d\u7f6e\u7b49\u7684\u5b57\u5178

      "},{"location":"qsl4a/media/mediaplayer/#mediaisplaying","title":"mediaIsPlaying()","text":"

      \u68c0\u67e5\u662f\u5426\u6b63\u5728\u64ad\u653e\u3002

      mediaIsPlaying(tag=\"default\")\n

      \u8fd4\u56de\uff1a True/False

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaylist","title":"mediaPlayList()","text":"

      \u5217\u51fa\u6d3b\u52a8\u64ad\u653e\u5668\u3002

      mediaPlayList()\n
      "},{"location":"qsl4a/media/mediaplayer/#_3","title":"\u97f3\u91cf\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#getmediavolume","title":"getMediaVolume()","text":"

      \u83b7\u53d6\u5a92\u4f53\u97f3\u91cf\u3002

      getMediaVolume()\n

      \u8fd4\u56de\uff1a \u97f3\u91cf\u7ea7\u522b\uff080-15\uff09

      "},{"location":"qsl4a/media/mediaplayer/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

      getMaxMediaVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#getringervolume","title":"getRingerVolume()","text":"

      \u83b7\u53d6\u94c3\u58f0\u97f3\u91cf\u3002

      getRingerVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

      getMaxRingerVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#_4","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/mediaplayer/#videoplay","title":"videoPlay()","text":"

      \u5168\u5c4f\u64ad\u653e\u89c6\u9891\u3002

      videoPlay(path, wait=True)\n

      \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210

      "},{"location":"qsl4a/media/mediaplayer/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u64ad\u653e\u97f3\u9891\ndroid.mediaPlay(\"/sdcard/music.mp3\", tag=\"music\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.mediaIsPlaying(\"music\").result:\n    info = droid.mediaPlayInfo(\"music\").result\n    print(f\"Playing: {info}\")\n\n# \u8df3\u8f6c\u5230 30 \u79d2\ndroid.mediaPlaySeek(30000, \"music\")\n\n# \u5173\u95ed\ndroid.mediaPlayClose(\"music\")\n\n# \u64ad\u653e\u89c6\u9891\ndroid.videoPlay(\"/sdcard/movie.mp4\", wait=True)\n
      "},{"location":"qsl4a/special/cipher/","title":"\u5bc6\u7801 API","text":"

      \u7528\u4e8e\u5b89\u5168\u6570\u636e\u5b58\u50a8\u7684\u52a0\u5bc6\u548c\u89e3\u5bc6\u5de5\u5177\u3002

      "},{"location":"qsl4a/special/cipher/#_1","title":"\u521d\u59cb\u5316","text":""},{"location":"qsl4a/special/cipher/#cipherinit","title":"cipherInit()","text":"

      \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u548c\u7b97\u6cd5\u521d\u59cb\u5316\u5bc6\u7801\u5668\u3002

      cipherInit(key, algorithm=\"AES/CBC/PKCS5Padding\", encodingFormat=\"\", initialVector=\"\")\n

      \u53c2\u6570\uff1a - key (str or bytes): \u52a0\u5bc6\u5bc6\u94a5 - algorithm (str): \u5bc6\u7801\u7b97\u6cd5\uff08\u9ed8\u8ba4\uff1a\"AES/CBC/PKCS5Padding\"\uff09 - encodingFormat (str): \u7f16\u7801\u683c\u5f0f - initialVector (str or bytes): \u52a0\u5bc6\u7684\u521d\u59cb\u5411\u91cf

      \u8fd4\u56de\uff1a \u521d\u59cb\u5316\u7ed3\u679c

      \u6ce8\u610f\uff1a \u5fc5\u987b\u5728\u4efb\u4f55\u52a0\u5bc6/\u89e3\u5bc6\u64cd\u4f5c\u4e4b\u524d\u8c03\u7528\u3002

      "},{"location":"qsl4a/special/cipher/#_2","title":"\u52a0\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#encryptstring","title":"encryptString()","text":"

      \u52a0\u5bc6\u5b57\u7b26\u4e32\u3002

      encryptString(plainText)\n

      \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c

      \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/special/cipher/#encryptbytes","title":"encryptBytes()","text":"

      \u52a0\u5bc6\u5b57\u8282\u6570\u636e\u3002

      encryptBytes(data)\n

      \u53c2\u6570\uff1a - data (bytes): \u8981\u52a0\u5bc6\u7684\u6570\u636e

      \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u8282

      "},{"location":"qsl4a/special/cipher/#encryptstringtofile","title":"encryptStringToFile()","text":"

      \u52a0\u5bc6\u5b57\u7b26\u4e32\u5230\u6587\u4ef6\u3002

      encryptStringToFile(plainText, filePath)\n

      \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c - filePath (str): \u8f93\u51fa\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/special/cipher/#encryptbytestofile","title":"encryptBytesToFile()","text":"

      \u52a0\u5bc6\u5b57\u8282\u5230\u6587\u4ef6\u3002

      encryptBytesToFile(data, filePath)\n
      "},{"location":"qsl4a/special/cipher/#_3","title":"\u89e3\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#decryptstring","title":"decryptString()","text":"

      \u89e3\u5bc6\u4e3a\u5b57\u7b26\u4e32\u3002

      decryptString(cipherText)\n

      \u53c2\u6570\uff1a - cipherText (str): \u52a0\u5bc6\u7684\u6587\u672c

      \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/special/cipher/#decryptbytes","title":"decryptBytes()","text":"

      \u89e3\u5bc6\u4e3a\u5b57\u8282\u3002

      decryptBytes(data)\n

      \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u8282

      "},{"location":"qsl4a/special/cipher/#decryptfiletostring","title":"decryptFileToString()","text":"

      \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u7b26\u4e32\u3002

      decryptFileToString(filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryptfiletobytes","title":"decryptFileToBytes()","text":"

      \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u8282\u3002

      decryptFileToBytes(filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryptfile","title":"decryptFile()","text":"

      \u89e3\u5bc6\u6587\u4ef6\u5230\u6587\u4ef6\u3002

      decryptFile(srcPath, destPath)\n
      "},{"location":"qsl4a/special/cipher/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u521d\u59cb\u5316\u5bc6\u7801\u5668\ndroid.cipherInit(\"my_secret_key_1234\")\n\n# \u52a0\u5bc6\u5b57\u7b26\u4e32\nencrypted = droid.encryptString(\"Secret message!\").result\nprint(f\"Encrypted: {encrypted}\")\n\n# \u89e3\u5bc6\u5b57\u7b26\u4e32\ndecrypted = droid.decryptString(encrypted).result\nprint(f\"Decrypted: {decrypted}\")\n\n# \u52a0\u5bc6\u5230\u6587\u4ef6\ndroid.encryptStringToFile(\"My secret data\", \"/sdcard/secret.dat\")\n\n# \u4ece\u6587\u4ef6\u89e3\u5bc6\ndata = droid.decryptFileToString(\"/sdcard/secret.dat\").result\nprint(data)\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u7b97\u6cd5\u548c IV \u521d\u59cb\u5316\ndroid.cipherInit(\n    key=\"my_key\",\n    algorithm=\"AES/CBC/PKCS5Padding\",\n    initialVector=\"0123456789abcdef\"\n)\n
      "},{"location":"qsl4a/special/pgptai/","title":"PGPT AI API","text":"

      \u8bed\u97f3\u8f6c\u6587\u672c\u548c AI \u670d\u52a1\u96c6\u6210\u3002

      "},{"location":"qsl4a/special/pgptai/#_1","title":"\u5148\u51b3\u6761\u4ef6","text":"
      pip install pgptAI\n
      "},{"location":"qsl4a/special/pgptai/#_2","title":"\u8bed\u97f3\u8bc6\u522b","text":""},{"location":"qsl4a/special/pgptai/#speechtotext","title":"speechToText()","text":"

      \u5c06\u8bed\u97f3\u8f6c\u6362\u4e3a\u6587\u672c\u3002

      speechToText(RecordSecond=10, AmrFile=None, Language=None)\n

      \u53c2\u6570\uff1a - RecordSecond (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09 - AmrFile (str, optional): \u73b0\u6709\u97f3\u9891\u6587\u4ef6\u8def\u5f84 - Language (str, optional): \u8bed\u8a00\u4ee3\u7801\uff08'en'\u3001'zh'\uff09

      \u8fd4\u56de\uff1a \u8f6c\u5f55\u7684\u6587\u672c

      "},{"location":"qsl4a/special/pgptai/#_3","title":"\u6587\u672c\u8f6c\u8bed\u97f3","text":""},{"location":"qsl4a/special/pgptai/#texttospeech","title":"textToSpeech()","text":"

      \u5c06\u6587\u672c\u8f6c\u6362\u4e3a\u8bed\u97f3\u5e76\u53ef\u9009\u5730\u64ad\u653e\u3002

      textToSpeech(Text, AutoPlay=True, WavFile=None, VoiceName=None)\n

      \u53c2\u6570\uff1a - Text (str): \u8981\u8f6c\u6362\u4e3a\u8bed\u97f3\u7684\u6587\u672c - AutoPlay (bool): \u81ea\u52a8\u64ad\u653e\u751f\u6210\u7684\u97f3\u9891\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - WavFile (str, optional): \u4fdd\u5b58 WAV \u6587\u4ef6\u7684\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u4e34\u65f6\u6587\u4ef6 - VoiceName (str, optional): \u8981\u4f7f\u7528\u7684\u8bed\u97f3\u540d\u79f0\uff08\u4f8b\u5982 'en-US-JennyNeural'\u3001'zh-CN-XiaoxiaoNeural'\uff09

      \u8fd4\u56de\uff1a \u5305\u542b\u8bed\u97f3\u5408\u6210\u7ed3\u679c\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - text: \u8f93\u5165\u6587\u672c - url: \u4e0b\u8f7d\u97f3\u9891\u6587\u4ef6\u7684 URL - WavFile: \u4fdd\u5b58\u7684 WAV \u6587\u4ef6\u8def\u5f84\uff08\u5982\u679c\u672c\u5730\u4fdd\u5b58\uff09

      "},{"location":"qsl4a/special/pgptai/#_4","title":"\u914d\u7f6e","text":"

      API \u4f7f\u7528\u4ee5\u4e0b\u914d\u7f6e\u6587\u4ef6\u4e2d\u7684\u914d\u7f6e\uff1a/storage/emulated/0/Android/data/org.qpython.qpy/files/apigpt.conf\uff1a

      [speech]\nspeech_key = your_api_key\n

      \u9ed8\u8ba4\u8bed\u97f3\u8bbe\u7f6e\uff1a - \u82f1\u8bed\uff1aen-US-JennyNeural - \u4e2d\u6587\uff1azh-CN-XiaoxiaoNeural

      "},{"location":"qsl4a/special/pgptai/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5f55\u5236\u5e76\u8f6c\u5f55\nprint(\"Recording for 5 seconds...\")\ntext = droid.speechToText(RecordSecond=5, Language='en').result\nprint(f\"You said: {text}\")\n\n# \u8f6c\u5f55\u73b0\u6709\u6587\u4ef6\ntext = droid.speechToText(AmrFile=\"/sdcard/recording.amr\").result\nprint(f\"Transcription: {text}\")\n\n# \u6587\u672c\u8f6c\u8bed\u97f3\ndroid.textToSpeech(\"Hello, this is a test message.\", AutoPlay=True, Language='en')\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u8bed\u97f3\u5e76\u4fdd\u5b58\u5230\u6587\u4ef6\u7684\u6587\u672c\u8f6c\u8bed\u97f3\nresult = droid.textToSpeech(\n    \"Welcome to QPython!\",\n    AutoPlay=False,\n    WavFile=\"/sdcard/welcome.wav\",\n    VoiceName=\"en-US-JennyNeural\"\n).result\nprint(f\"Audio saved to: {result.get('WavFile')}\")\n
      "},{"location":"qsl4a/special/pgptai/#_6","title":"\u7c7b\u4f7f\u7528","text":"
      from androidhelper.pgptai import pgptai\nimport androidhelper\n\ndroid = androidhelper.Android()\nai = pgptai(droid)\n\n# \u4f7f\u7528\u8bed\u97f3\u8bc6\u522b\ntext = ai.speechToText(RecordSecond=10)\n
      "},{"location":"qsl4a/storage/clipboard/","title":"\u526a\u8d34\u677f API","text":"

      \u590d\u5236\u548c\u7c98\u8d34\u6587\u672c\u5230\u7cfb\u7edf\u526a\u8d34\u677f\u3002

      "},{"location":"qsl4a/storage/clipboard/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/clipboard/#setclipboard","title":"setClipboard()","text":"

      \u590d\u5236\u6587\u672c\u5230\u526a\u8d34\u677f\u3002

      setClipboard(text)\n

      \u53c2\u6570\uff1a - text (str): \u8981\u590d\u5236\u7684\u6587\u672c

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/clipboard/#getclipboard","title":"getClipboard()","text":"

      \u4ece\u526a\u8d34\u677f\u83b7\u53d6\u6587\u672c\u3002

      getClipboard()\n

      \u8fd4\u56de\uff1a \u526a\u8d34\u677f\u6587\u672c

      "},{"location":"qsl4a/storage/clipboard/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u590d\u5236\u5230\u526a\u8d34\u677f\ndroid.setClipboard(\"Hello from QPython!\")\n\n# \u4ece\u526a\u8d34\u677f\u7c98\u8d34\ntext = droid.getClipboard().result\nprint(f\"Clipboard: {text}\")\n
      "},{"location":"qsl4a/storage/documentfile/","title":"DocumentFile API","text":"

      \u4f7f\u7528 SAF\uff08\u5b58\u50a8\u8bbf\u95ee\u6846\u67b6\uff09\u8fdb\u884c\u6587\u4ef6\u64cd\u4f5c\uff0c\u652f\u6301 Android 4.4+\u3002

      "},{"location":"qsl4a/storage/documentfile/#_1","title":"\u76ee\u5f55\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilemkdir","title":"documentFileMkdir()","text":"

      \u521b\u5efa\u76ee\u5f55\u3002

      documentFileMkdir(Dir)\n

      \u53c2\u6570\uff1a - Dir (str): \u76ee\u5f55\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/documentfile/#documentfilelistfiles","title":"documentFileListFiles()","text":"

      \u5217\u51fa\u76ee\u5f55\u4e2d\u7684\u6587\u4ef6\u3002

      documentFileListFiles(Folder)\n

      \u8fd4\u56de\uff1a \u6587\u4ef6\u5217\u8868

      "},{"location":"qsl4a/storage/documentfile/#_2","title":"\u6587\u4ef6\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileexists","title":"documentFileExists()","text":"

      \u68c0\u67e5\u6587\u4ef6\u6216\u76ee\u5f55\u662f\u5426\u5b58\u5728\u3002

      documentFileExists(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u6216\u76ee\u5f55\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u5b58\u5728\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/storage/documentfile/#documentfileisfile","title":"documentFileIsFile()","text":"

      \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u6587\u4ef6\u3002

      documentFileIsFile(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u662f\u6587\u4ef6\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u6587\u4ef6\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

      "},{"location":"qsl4a/storage/documentfile/#documentfileisdirectory","title":"documentFileIsDirectory()","text":"

      \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u76ee\u5f55\u3002

      documentFileIsDirectory(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u662f\u76ee\u5f55\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u76ee\u5f55\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

      "},{"location":"qsl4a/storage/documentfile/#documentfiledelete","title":"documentFileDelete()","text":"

      \u5220\u9664\u6587\u4ef6\u6216\u76ee\u5f55\u3002

      documentFileDelete(FileOrTree)\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/documentfile/#documentfilerenameto","title":"documentFileRenameTo()","text":"

      \u91cd\u547d\u540d\u6216\u79fb\u52a8\u6587\u4ef6\u3002

      documentFileRenameTo(Src, Dest)\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/documentfile/#documentfilecopy","title":"documentFileCopy()","text":"

      \u590d\u5236\u6587\u4ef6\u3002

      documentFileCopy(SrcFileOrTree, DestFileOrTree)\n
      "},{"location":"qsl4a/storage/documentfile/#_3","title":"\u6d41\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileinputstream","title":"documentFileInputStream()","text":"

      \u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9\u3002

      documentFileInputStream(srcFile, EncodingFormat=\"\", skip=None, length=None)\n

      \u53c2\u6570\uff1a - srcFile (str): \u6e90\u6587\u4ef6 - EncodingFormat (str): \"UTF-8\"\u3001\"GBK\"\u3001\"Base64\" \u6216\u7a7a\u5b57\u7b26\u4e32\u8868\u793a\u5b57\u8282 - skip (int): \u4ece\u5f00\u5934\u8df3\u8fc7\u7684\u5b57\u8282\u6570 - length (int): \u8bfb\u53d6\u957f\u5ea6

      \u8fd4\u56de\uff1a \u6587\u4ef6\u5185\u5bb9

      "},{"location":"qsl4a/storage/documentfile/#documentfileoutputstream","title":"documentFileOutputStream()","text":"

      \u5199\u5165\u6587\u4ef6\u5185\u5bb9\u3002

      documentFileOutputStream(destFile, src, EncodingFormat=\"\", append=None)\n

      \u53c2\u6570\uff1a - destFile (str): \u76ee\u6807\u6587\u4ef6 - src: \u8981\u5199\u5165\u7684\u6570\u636e - EncodingFormat (str): \u7f16\u7801\u683c\u5f0f - append (bool): \u8ffd\u52a0\u6a21\u5f0f

      "},{"location":"qsl4a/storage/documentfile/#_4","title":"\u6587\u4ef6\u4fe1\u606f","text":""},{"location":"qsl4a/storage/documentfile/#documentfilelength","title":"documentFileLength()","text":"

      \u83b7\u53d6\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\u3002

      documentFileLength(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

      "},{"location":"qsl4a/storage/documentfile/#documentfilelastmodified","title":"documentFileLastModified()","text":"

      \u83b7\u53d6\u6700\u540e\u4fee\u6539\u65f6\u95f4\u3002

      documentFileLastModified(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u65f6\u95f4\u6233\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

      "},{"location":"qsl4a/storage/documentfile/#documentfilegetstat","title":"documentFileGetStat()","text":"

      \u83b7\u53d6\u5168\u9762\u7684\u6587\u4ef6\u7edf\u8ba1\u4fe1\u606f\u3002

      documentFileGetStat(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5305\u542b\u957f\u5ea6\u3001\u6700\u540e\u4fee\u6539\u65f6\u95f4\u548c\u8bfb/\u5199\u6743\u9650\u7684\u5b57\u5178\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

      "},{"location":"qsl4a/storage/documentfile/#uri","title":"URI \u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilegeturi","title":"documentFileGetUri()","text":"

      \u4ece\u8def\u5f84\u83b7\u53d6 URI\u3002

      documentFileGetUri(path, isDirectory=None)\n
      "},{"location":"qsl4a/storage/documentfile/#documentfileshowopen","title":"documentFileShowOpen()","text":"

      \u663e\u793a\u6587\u4ef6\u9009\u62e9\u5668\u3002

      documentFileShowOpen()\n

      \u8fd4\u56de\uff1a \u9009\u62e9\u7684\u6587\u4ef6 URI

      "},{"location":"qsl4a/storage/documentfile/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u76ee\u5f55\ndroid.documentFileMkdir(\"/sdcard/MyFolder\")\n\n# \u5217\u51fa\u6587\u4ef6\nfiles = droid.documentFileListFiles(\"/sdcard\").result\nfor f in files:\n    print(f)\n\n# \u8bfb\u53d6\u6587\u4ef6\ncontent = droid.documentFileInputStream(\n    \"/sdcard/test.txt\",\n    EncodingFormat=\"UTF-8\"\n).result\nprint(content)\n\n# \u5199\u5165\u6587\u4ef6\ndroid.documentFileOutputStream(\n    \"/sdcard/output.txt\",\n    \"Hello World\",\n    EncodingFormat=\"UTF-8\"\n)\n
      "},{"location":"qsl4a/storage/preferences/","title":"\u504f\u597d\u8bbe\u7f6e API","text":"

      \u4f7f\u7528 Android SharedPreferences \u5b58\u50a8\u548c\u68c0\u7d22\u6570\u636e\u3002

      "},{"location":"qsl4a/storage/preferences/#_1","title":"\u504f\u597d\u8bbe\u7f6e\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/preferences/#prefgetvalue","title":"prefGetValue()","text":"

      \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u8bfb\u53d6\u503c\u3002

      prefGetValue(key, filename=None)\n

      \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c\uff08\u4efb\u610f\u7c7b\u578b\uff09

      "},{"location":"qsl4a/storage/preferences/#prefputvalue","title":"prefPutValue()","text":"

      \u5199\u5165\u503c\u5230\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u3002

      prefPutValue(key, value, filename=None)\n

      \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - value (object): \u8981\u5b58\u50a8\u7684\u503c - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      "},{"location":"qsl4a/storage/preferences/#prefgetall","title":"prefGetAll()","text":"

      \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\u503c\u3002

      prefGetAll(filename=None)\n

      \u53c2\u6570\uff1a - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      \u8fd4\u56de\uff1a \u6240\u6709\u504f\u597d\u7684\u6620\u5c04

      "},{"location":"qsl4a/storage/preferences/#prefremovevalue","title":"prefRemoveValue()","text":"

      \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u4e2d\u79fb\u9664\u503c\u3002

      prefRemoveValue(key, filename=None)\n

      \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      "},{"location":"qsl4a/storage/preferences/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b58\u50a8\u503c\ndroid.prefPutValue(\"username\", \"alice\")\ndroid.prefPutValue(\"score\", 100)\ndroid.prefPutValue(\"enabled\", True)\n\n# \u8bfb\u53d6\u7279\u5b9a\u503c\nusername = droid.prefGetValue(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\nall_prefs = droid.prefGetAll().result\nprint(f\"All prefs: {all_prefs}\")\n\n# \u79fb\u9664\u503c\ndroid.prefRemoveValue(\"score\")\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u6587\u4ef6\u540d\ndroid.prefPutValue(\"token\", \"abc123\", filename=\"auth.prefs\")\ntoken = droid.prefGetValue(\"token\", filename=\"auth.prefs\").result\n
      "},{"location":"qsl4a/system/activityresult/","title":"Activity Result API","text":"

      \u4e3a\u901a\u8fc7 startActivityForResult \u542f\u52a8\u7684\u811a\u672c\u8bbe\u7f6e activity \u7ed3\u679c\u3002

      "},{"location":"qsl4a/system/activityresult/#_1","title":"\u7ed3\u679c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/activityresult/#setresultboolean","title":"setResultBoolean()","text":"

      \u8bbe\u7f6e\u5e03\u5c14\u7ed3\u679c\u3002

      setResultBoolean(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (bool): \u5e03\u5c14\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultbyte","title":"setResultByte()","text":"

      \u8bbe\u7f6e\u5b57\u8282\u7ed3\u679c\u3002

      setResultByte(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u5b57\u8282\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultshort","title":"setResultShort()","text":"

      \u8bbe\u7f6e\u77ed\u6574\u6570\u7ed3\u679c\u3002

      setResultShort(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u77ed\u6574\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultchar","title":"setResultChar()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u7ed3\u679c\u3002

      setResultChar(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultinteger","title":"setResultInteger()","text":"

      \u8bbe\u7f6e\u6574\u6570\u7ed3\u679c\u3002

      setResultInteger(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u6574\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultlong","title":"setResultLong()","text":"

      \u8bbe\u7f6e\u957f\u6574\u6570\u7ed3\u679c\u3002

      setResultLong(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u957f\u6574\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultfloat","title":"setResultFloat()","text":"

      \u8bbe\u7f6e\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

      setResultFloat(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u6d6e\u70b9\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultdouble","title":"setResultDouble()","text":"

      \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

      setResultDouble(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultstring","title":"setResultString()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u4e32\u7ed3\u679c\u3002

      setResultString(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u4e32\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultbooleanarray","title":"setResultBooleanArray()","text":"

      \u8bbe\u7f6e\u5e03\u5c14\u6570\u7ec4\u7ed3\u679c\u3002

      setResultBooleanArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5e03\u5c14\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultbytearray","title":"setResultByteArray()","text":"

      \u8bbe\u7f6e\u5b57\u8282\u6570\u7ec4\u7ed3\u679c\u3002

      setResultByteArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u8282\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultshortarray","title":"setResultShortArray()","text":"

      \u8bbe\u7f6e\u77ed\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultShortArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u77ed\u6574\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultchararray","title":"setResultCharArray()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u6570\u7ec4\u7ed3\u679c\u3002

      setResultCharArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultintegerarray","title":"setResultIntegerArray()","text":"

      \u8bbe\u7f6e\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultIntegerArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6574\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultlongarray","title":"setResultLongArray()","text":"

      \u8bbe\u7f6e\u957f\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultLongArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u957f\u6574\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultfloatarray","title":"setResultFloatArray()","text":"

      \u8bbe\u7f6e\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultFloatArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6d6e\u70b9\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultdoublearray","title":"setResultDoubleArray()","text":"

      \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultDoubleArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultstringarray","title":"setResultStringArray()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u4e32\u6570\u7ec4\u7ed3\u679c\u3002

      setResultStringArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u4e32\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultserializable","title":"setResultSerializable()","text":"

      \u8bbe\u7f6e\u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u3002

      setResultSerializable(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue: \u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c activity \u540e\uff0c\u8bbe\u7f6e\u7ed3\u679c\n# \u793a\u4f8b\uff1a\u8fd4\u56de\u6210\u529f\u53ca\u6570\u636e\ndroid.setResultInteger(0, 200)  # RESULT_OK\ndroid.setResultString(0, \"Operation completed successfully\")\n\n# \u8fd4\u56de\u6570\u7ec4\u7ed3\u679c\ndroid.setResultIntegerArray(0, [1, 2, 3, 4, 5])\n
      "},{"location":"qsl4a/system/application/","title":"\u5e94\u7528\u7ba1\u7406","text":"

      \u7ba1\u7406\u5e94\u7528\u7a0b\u5e8f\u3001\u542f\u52a8\u5e94\u7528\u548c\u67e5\u8be2\u7cfb\u7edf\u4fe1\u606f\u3002

      "},{"location":"qsl4a/system/application/#_2","title":"\u5e94\u7528\u7a0b\u5e8f\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getapplicationinfo","title":"getApplicationInfo()","text":"

      \u83b7\u53d6\u5e94\u7528\u4fe1\u606f\u3002

      getApplicationInfo(packageName=None)\n

      \u53c2\u6570\uff1a - packageName (str): \u5305\u540d\uff08None = \u5f53\u524d\u5e94\u7528\uff09

      \u8fd4\u56de\uff1a \u5e94\u7528\u4fe1\u606f\u5b57\u5178

      "},{"location":"qsl4a/system/application/#getinstalledpackages","title":"getInstalledPackages()","text":"

      \u83b7\u53d6\u5df2\u5b89\u88c5\u5305\u5217\u8868\u3002

      getInstalledPackages(flag=4)\n

      \u53c2\u6570\uff1a - flag (int): \u5305\u6807\u5fd7\u8fc7\u6ee4\u5668\uff08\u9ed8\u8ba4\uff1a4\uff09

      \u8fd4\u56de\uff1a \u5df2\u5b89\u88c5\u5305\u5217\u8868

      "},{"location":"qsl4a/system/application/#getrunningpackages","title":"getRunningPackages()","text":"

      \u5217\u51fa\u6b63\u5728\u8fd0\u884c\u7684\u5305\u3002

      getRunningPackages()\n

      \u8fd4\u56de\uff1a \u5305\u540d\u5217\u8868

      "},{"location":"qsl4a/system/application/#getlaunchablepackages","title":"getLaunchablePackages()","text":"

      \u83b7\u53d6\u53ef\u542f\u52a8\u5305\u5217\u8868\u3002

      getLaunchablePackages(needClassName=False)\n

      \u53c2\u6570\uff1a - needClassName (bool): \u5305\u542b\u4e3b activity \u7c7b\u540d\uff08\u9ed8\u8ba4\uff1aFalse\uff09

      \u8fd4\u56de\uff1a \u53ef\u542f\u52a8\u5305\u540d\u5217\u8868\u6216\u5305\u542b\u7c7b\u540d\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#_3","title":"\u5e94\u7528\u63a7\u5236","text":""},{"location":"qsl4a/system/application/#launch","title":"launch()","text":"

      \u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u3002

      launch(classname=None, packagename=None, wait=True)\n

      \u53c2\u6570\uff1a - classname (str): \u4e3b activity \u7c7b\u540d - packagename (str): \u5305\u540d - wait (bool): \u7b49\u5f85\u542f\u52a8\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

      \u8fd4\u56de\uff1a \u542f\u52a8\u7ed3\u679c

      "},{"location":"qsl4a/system/application/#forcestoppackage","title":"forceStopPackage()","text":"

      \u5f3a\u5236\u505c\u6b62\u5e94\u7528\u7a0b\u5e8f\u3002

      forceStopPackage(packageName)\n

      \u53c2\u6570\uff1a - packageName (str): \u8981\u505c\u6b62\u7684\u5305\u540d

      "},{"location":"qsl4a/system/application/#_4","title":"\u7248\u672c\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getpackageversion","title":"getPackageVersion()","text":"

      \u83b7\u53d6\u5e94\u7528\u7248\u672c\u540d\u79f0\u3002

      getPackageVersion(packageName)\n

      \u8fd4\u56de\uff1a \u7248\u672c\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"3.2.1\"\uff09

      "},{"location":"qsl4a/system/application/#getpackageversioncode","title":"getPackageVersionCode()","text":"

      \u83b7\u53d6\u5e94\u7528\u7248\u672c\u4ee3\u7801\u3002

      getPackageVersionCode(packageName)\n

      \u8fd4\u56de\uff1a \u7248\u672c\u4ee3\u7801\u6574\u6570

      "},{"location":"qsl4a/system/application/#getconstants","title":"getConstants()","text":"

      \u83b7\u53d6\u7c7b\u5e38\u91cf\u3002

      getConstants(classname)\n

      \u53c2\u6570\uff1a - classname (str): \u5b8c\u6574\u7c7b\u540d

      \u8fd4\u56de\uff1a \u5e38\u91cf\u540d\u548c\u503c\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#_5","title":"\u7cfb\u7edf\u529f\u80fd","text":""},{"location":"qsl4a/system/application/#backgroundprotect","title":"backgroundProtect()","text":"

      \u542f\u7528\u6216\u7981\u7528\u5e94\u7528\u7684\u540e\u53f0\u4fdd\u62a4\u3002

      backgroundProtect(enabled=True)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\u4fdd\u62a4\uff0cFalse \u7981\u7528

      "},{"location":"qsl4a/system/application/#createscriptshortcut","title":"createScriptShortCut()","text":"

      \u4e3a\u811a\u672c\u521b\u5efa\u4e3b\u5c4f\u5e55\u5feb\u6377\u65b9\u5f0f\u3002

      createScriptShortCut(scriptPath, label=None, iconPath=None, scriptArg=None)\n

      \u53c2\u6570\uff1a - scriptPath (str): Python \u811a\u672c\u8def\u5f84 - label (str, optional): \u5feb\u6377\u65b9\u5f0f\u6807\u7b7e - iconPath (str, optional): \u56fe\u6807\u56fe\u50cf\u8def\u5f84 - scriptArg (str, optional): \u4f20\u9012\u7ed9\u811a\u672c\u7684\u53c2\u6570

      "},{"location":"qsl4a/system/application/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getandroidid","title":"getAndroidID()","text":"

      \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

      getAndroidID()\n

      \u8fd4\u56de\uff1a \u552f\u4e00\u7684 Android \u8bbe\u5907 ID \u5b57\u7b26\u4e32

      "},{"location":"qsl4a/system/application/#getsysinfo","title":"getSysInfo()","text":"

      \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\u3002

      getSysInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#getlocale","title":"getLocale()","text":"

      \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u3002

      getLocale()\n

      \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

      "},{"location":"qsl4a/system/application/#getharmonyosinformation","title":"getHarmonyOsInformation()","text":"

      \u5982\u679c\u5728 HarmonyOS \u4e0a\u8fd0\u884c\uff0c\u83b7\u53d6 HarmonyOS \u4fe1\u606f\u3002

      getHarmonyOsInformation()\n

      \u8fd4\u56de\uff1a HarmonyOS \u7248\u672c\u4fe1\u606f\u6216 None

      "},{"location":"qsl4a/system/application/#isexternalstoragemanager","title":"isExternalStorageManager()","text":"

      \u68c0\u67e5\u5e94\u7528\u662f\u5426\u6709\u5916\u90e8\u5b58\u50a8\u7ba1\u7406\u5668\u6743\u9650\u3002

      isExternalStorageManager()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6709\u6743\u9650\u5219\u4e3a True

      "},{"location":"qsl4a/system/application/#_7","title":"\u5185\u5b58\u548c\u663e\u793a","text":""},{"location":"qsl4a/system/application/#getmemoryinfo","title":"getMemoryInfo()","text":"

      \u83b7\u53d6\u5185\u5b58\u4fe1\u606f\u3002

      getMemoryInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#getscreeninfo","title":"getScreenInfo()","text":"

      \u83b7\u53d6\u5c4f\u5e55\u4fe1\u606f\u3002

      getScreenInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#_8","title":"\u6743\u9650","text":""},{"location":"qsl4a/system/application/#checkpermissions","title":"checkPermissions()","text":"

      \u68c0\u67e5\u5f53\u524d\u5e94\u7528\u6743\u9650\u3002

      checkPermissions()\n

      \u8fd4\u56de\uff1a \u6743\u9650\u53ca\u5176\u72b6\u6001\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#requestpermissions","title":"requestPermissions()","text":"

      \u5411\u7528\u6237\u8bf7\u6c42\u6743\u9650\u3002

      requestPermissions(permissions=None)\n

      \u53c2\u6570\uff1a - permissions (list, optional): \u8981\u8bf7\u6c42\u7684\u6743\u9650\u5217\u8868\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8bf7\u6c42\u6240\u6709\u9700\u8981\u7684\u6743\u9650\u3002

      \u8fd4\u56de\uff1a \u6743\u9650\u8bf7\u6c42\u7ed3\u679c

      "},{"location":"qsl4a/system/application/#_9","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/system/application/#showscreenlock","title":"showScreenLock()","text":"

      \u663e\u793a\u5c4f\u5e55\u9501\u5b9a\uff08PIN/\u56fe\u6848/\u5bc6\u7801\u8f93\u5165\uff09\u3002

      showScreenLock()\n
      "},{"location":"qsl4a/system/application/#_10","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\ninfo = droid.getSysInfo().result\nprint(f\"System: {info}\")\n\n# \u83b7\u53d6\u5e94\u7528\u7248\u672c\nversion = droid.getPackageVersion(\"org.qpython.qpy\").result\nprint(f\"QPython version: {version}\")\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u5e94\u7528\napps = droid.getInstalledPackages().result\nprint(f\"Installed apps: {len(apps)}\")\n\n# \u542f\u52a8\u5e94\u7528\ndroid.launch(packagename=\"com.android.settings\")\n\n# \u68c0\u67e5\u6743\u9650\nperms = droid.checkPermissions().result\nprint(f\"Permissions: {perms}\")\n\n# \u8bf7\u6c42\u5b58\u50a8\u6743\u9650\ndroid.requestPermissions([\"android.permission.READ_EXTERNAL_STORAGE\"])\n\n# \u521b\u5efa\u5feb\u6377\u65b9\u5f0f\ndroid.createScriptShortCut(\n    \"/sdcard/my_script.py\",\n    label=\"My Script\",\n    iconPath=\"/sdcard/icon.png\"\n)\n
      "},{"location":"qsl4a/system/battery/","title":"\u7535\u6c60 API","text":"

      \u76d1\u63a7\u8bbe\u5907\u7535\u6c60\u72b6\u6001\u548c\u5065\u5eb7\u72b6\u51b5\u3002

      "},{"location":"qsl4a/system/battery/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/battery/#readbatterydata","title":"readBatteryData()","text":"

      \u83b7\u53d6\u5b8c\u6574\u7684\u7535\u6c60\u4fe1\u606f\u3002

      readBatteryData()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7535\u6c60\u6570\u636e\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/battery/#batterystartmonitoring","title":"batteryStartMonitoring()","text":"

      \u5f00\u59cb\u7535\u6c60\u76d1\u63a7\u3002

      batteryStartMonitoring()\n
      "},{"location":"qsl4a/system/battery/#batterystopmonitoring","title":"batteryStopMonitoring()","text":"

      \u505c\u6b62\u7535\u6c60\u76d1\u63a7\u3002

      batteryStopMonitoring()\n
      "},{"location":"qsl4a/system/battery/#batterygetlevel","title":"batteryGetLevel()","text":"

      \u83b7\u53d6\u7535\u6c60\u767e\u5206\u6bd4\u3002

      batteryGetLevel()\n

      \u8fd4\u56de\uff1a \u6574\u6570\uff080-100\uff09

      "},{"location":"qsl4a/system/battery/#batterygetstatus","title":"batteryGetStatus()","text":"

      \u83b7\u53d6\u5145\u7535\u72b6\u6001\u3002

      batteryGetStatus()\n

      \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u5145\u7535\u4e2d - 3: \u653e\u7535\u4e2d - 4: \u672a\u5145\u7535 - 5: \u5df2\u5145\u6ee1

      "},{"location":"qsl4a/system/battery/#batterygetplugtype","title":"batteryGetPlugType()","text":"

      \u83b7\u53d6\u7535\u6e90\u7c7b\u578b\u3002

      batteryGetPlugType()\n

      \u8fd4\u56de\uff1a - -1: \u672a\u77e5 - 0: \u672a\u63d2\u7535 - 1: AC \u5145\u7535\u5668 - 2: USB \u7aef\u53e3

      "},{"location":"qsl4a/system/battery/#batterygethealth","title":"batteryGetHealth()","text":"

      \u83b7\u53d6\u7535\u6c60\u5065\u5eb7\u72b6\u51b5\u3002

      batteryGetHealth()\n

      \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u826f\u597d - 3: \u8fc7\u70ed - 4: \u635f\u574f - 5: \u8fc7\u538b - 6: \u672a\u6307\u5b9a\u7684\u6545\u969c

      "},{"location":"qsl4a/system/battery/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\nlevel = droid.batteryGetLevel().result\nprint(f\"Battery: {level}%\")\n
      "},{"location":"qsl4a/system/qpyinterface/","title":"QPython \u63a5\u53e3 API","text":"

      \u4ece\u5176\u4ed6\u5e94\u7528\u6267\u884c QPython \u811a\u672c\u548c\u7ba1\u7406\u5171\u4eab\u53d8\u91cf\u3002

      "},{"location":"qsl4a/system/qpyinterface/#_1","title":"\u811a\u672c\u6267\u884c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/qpyinterface/#executeqpy","title":"executeQPy()","text":"

      \u6267\u884c QPython \u811a\u672c\u3002

      executeQPy(path=\"\", arg=None)\n

      \u53c2\u6570\uff1a - path (str): \u811a\u672c\u6587\u4ef6\u8def\u5f84 - arg (str, optional): \u547d\u4ee4\u884c\u53c2\u6570

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#executeqpyassrv","title":"executeQPyAsSrv()","text":"

      \u4f5c\u4e3a\u670d\u52a1\u6267\u884c QPython \u811a\u672c\u3002

      executeQPyAsSrv(path=None)\n

      \u53c2\u6570\uff1a - path (str, optional): \u811a\u672c\u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#executeqpycode","title":"executeQPyCode()","text":"

      \u76f4\u63a5\u6267\u884c Python \u4ee3\u7801\u3002

      executeQPyCode(code=None)\n

      \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#executeqpycodeassrv","title":"executeQPyCodeAsSrv()","text":"

      \u4f5c\u4e3a\u670d\u52a1\u6267\u884c Python \u4ee3\u7801\u3002

      executeQPyCodeAsSrv(code=None)\n

      \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#_2","title":"\u5171\u4eab\u53d8\u91cf","text":"

      \u5171\u4eab\u53d8\u91cf\u5141\u8bb8 QPython \u4e0e\u5176\u4ed6\u5e94\u7528\u4e4b\u95f4\u8fdb\u884c\u901a\u4fe1\u3002

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableset","title":"sharedVariableSet()","text":"

      \u8bbe\u7f6e Java \u5171\u4eab\u53d8\u91cf\u3002

      sharedVariableSet(key, value)\n

      \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d - value (str): \u53d8\u91cf\u503c

      \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableget","title":"sharedVariableGet()","text":"

      \u83b7\u53d6 Java \u5171\u4eab\u53d8\u91cf\u3002

      sharedVariableGet(key)\n

      \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d

      \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableremove","title":"sharedVariableRemove()","text":"

      \u79fb\u9664 Java \u5171\u4eab\u53d8\u91cf\u3002

      sharedVariableRemove(key)\n

      \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u53d8\u91cf\u540d

      \u8fd4\u56de\uff1a \u88ab\u79fb\u9664\u7684\u503c

      "},{"location":"qsl4a/system/qpyinterface/#getlastlog","title":"getLastLog()","text":"

      \u83b7\u53d6 QPython \u7684\u6700\u540e\u65e5\u5fd7\u8f93\u51fa\u3002

      getLastLog()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u65e5\u5fd7\u5185\u5bb9

      "},{"location":"qsl4a/system/qpyinterface/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c\u811a\u672c\ndroid.executeQPy(\"/sdcard/my_script.py\", arg=\"test\")\n\n# \u76f4\u63a5\u6267\u884c\u4ee3\u7801\ncode = \"print('Hello from QPython!')\"\ndroid.executeQPyCode(code)\n\n# \u4f7f\u7528\u5171\u4eab\u53d8\u91cf\ndroid.sharedVariableSet(\"username\", \"alice\")\nusername = droid.sharedVariableGet(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u79fb\u9664\u53d8\u91cf\ndroid.sharedVariableRemove(\"username\")\n\n# \u83b7\u53d6\u6700\u8fd1\u65e5\u5fd7\nlog = droid.getLastLog().result\nprint(f\"Log: {log}\")\n
      "},{"location":"qsl4a/system/sensors/","title":"\u4f20\u611f\u5668 API","text":"

      \u8bbf\u95ee\u8bbe\u5907\u4f20\u611f\u5668\uff0c\u5305\u62ec\u52a0\u901f\u5ea6\u8ba1\u3001\u9640\u87ba\u4eea\u3001\u78c1\u529b\u8ba1\u7b49\u3002

      "},{"location":"qsl4a/system/sensors/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/sensors/#startsensingtimed","title":"startSensingTimed()","text":"

      \u5f00\u59cb\u4f20\u611f\u5668\u76d1\u63a7\u5e76\u8bbe\u7f6e\u65f6\u95f4\u95f4\u9694\u3002

      startSensingTimed(sensorNumber, delayTime)\n

      \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID\uff08\u901a\u5e38\u4e3a 1-3\uff09 - delayTime (int): \u8bfb\u53d6\u4e4b\u95f4\u7684\u5ef6\u8fdf\uff08\u6beb\u79d2\uff09

      "},{"location":"qsl4a/system/sensors/#startsensingthreshold","title":"startSensingThreshold()","text":"

      \u5f00\u59cb\u5e26\u9608\u503c\u89e6\u53d1\u7684\u4f20\u611f\u5668\u76d1\u63a7\u3002

      startSensingThreshold(sensorNumber, threshold, axis)\n

      \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID - threshold (float): \u89e6\u53d1\u9608\u503c - axis (int): \u8981\u76d1\u63a7\u7684\u8f74\uff080=X\uff0c1=Y\uff0c2=Z\uff09

      "},{"location":"qsl4a/system/sensors/#stopsensing","title":"stopSensing()","text":"

      \u505c\u6b62\u6240\u6709\u4f20\u611f\u5668\u76d1\u63a7\u3002

      stopSensing()\n
      "},{"location":"qsl4a/system/sensors/#readsensors","title":"readSensors()","text":"

      \u8bfb\u53d6\u5f53\u524d\u4f20\u611f\u5668\u6570\u636e\u3002

      readSensors()\n

      \u8fd4\u56de\uff1a \u4f20\u611f\u5668\u6570\u636e\u5b57\u5178

      "},{"location":"qsl4a/system/sensors/#sensorsreadaccelerometer","title":"sensorsReadAccelerometer()","text":"

      \u8bfb\u53d6\u52a0\u901f\u5ea6\u8ba1\u503c\u3002

      sensorsReadAccelerometer()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d m/s\u00b2

      "},{"location":"qsl4a/system/sensors/#sensorsreadgyroscope","title":"sensorsReadGyroscope()","text":"

      \u8bfb\u53d6\u9640\u87ba\u4eea\u503c\u3002

      sensorsReadGyroscope()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d rad/s

      "},{"location":"qsl4a/system/sensors/#sensorsreadmagnetometer","title":"sensorsReadMagnetometer()","text":"

      \u8bfb\u53d6\u78c1\u573a\u503c\u3002

      sensorsReadMagnetometer()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d \u03bcT

      "},{"location":"qsl4a/system/sensors/#sensorsreadorientation","title":"sensorsReadOrientation()","text":"

      \u8bfb\u53d6\u8bbe\u5907\u65b9\u5411\u3002

      sensorsReadOrientation()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [azimuth, pitch, roll]\uff0c\u5355\u4f4d\u5ea6

      "},{"location":"qsl4a/system/sensors/#sensorsgetlight","title":"sensorsGetLight()","text":"

      \u8bfb\u53d6\u5149\u4f20\u611f\u5668\u503c\u3002

      sensorsGetLight()\n

      \u8fd4\u56de\uff1a \u5149\u7ea7\u522b\uff08lux\uff09

      "},{"location":"qsl4a/system/sensors/#sensorsgetstepcounter","title":"sensorsGetStepCounter()","text":"

      \u8bfb\u53d6\u6b65\u8ba1\u6570\u5668\u3002

      sensorsGetStepCounter()\n

      \u8fd4\u56de\uff1a \u6b65\u6570

      "},{"location":"qsl4a/system/sensors/#sensorsgetaccuracy","title":"sensorsGetAccuracy()","text":"

      \u83b7\u53d6\u5f53\u524d\u4f20\u611f\u5668\u7cbe\u5ea6\u3002

      sensorsGetAccuracy()\n

      \u8fd4\u56de\uff1a \u7cbe\u5ea6\u503c\uff080-3\uff1aUNRELIABLE\u3001ACCURACY_LOW\u3001ACCURACY_MEDIUM\u3001ACCURACY_HIGH\uff09

      "},{"location":"qsl4a/system/sensors/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u8bfb\u53d6\u4f20\u611f\u5668 10 \u6b21\nfor i in range(10):\n    accel = droid.sensorsReadAccelerometer().result\n    print(f\"Accel: X={accel[0]:.2f}, Y={accel[1]:.2f}, Z={accel[2]:.2f}\")\n    time.sleep(0.5)\n\ndroid.stopSensing()\n
      "},{"location":"qsl4a/system/settings/","title":"\u8bbe\u7f6e API","text":"

      \u63a7\u5236\u7cfb\u7edf\u8bbe\u7f6e\uff0c\u5305\u62ec\u5c4f\u5e55\u3001\u58f0\u97f3\u548c\u7f51\u7edc\u8bbe\u7f6e\u3002

      "},{"location":"qsl4a/system/settings/#_1","title":"\u5c4f\u5e55\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#setscreentimeout","title":"setScreenTimeout()","text":"

      \u8bbe\u7f6e\u5c4f\u5e55\u8d85\u65f6\u503c\u3002

      setScreenTimeout(value)\n

      \u53c2\u6570\uff1a - value (int): \u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

      \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u8d85\u65f6\u503c

      "},{"location":"qsl4a/system/settings/#getscreentimeout","title":"getScreenTimeout()","text":"

      \u83b7\u53d6\u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u3002

      getScreenTimeout()\n

      \u8fd4\u56de\uff1a \u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

      "},{"location":"qsl4a/system/settings/#getscreenbrightness","title":"getScreenBrightness()","text":"

      \u83b7\u53d6\u5c4f\u5e55\u4eae\u5ea6\u503c\u3002

      getScreenBrightness()\n

      \u8fd4\u56de\uff1a \u4eae\u5ea6\u503c\uff080-255\uff09

      "},{"location":"qsl4a/system/settings/#setscreenbrightness","title":"setScreenBrightness()","text":"

      \u8bbe\u7f6e\u5c4f\u5e55\u4eae\u5ea6\u3002

      setScreenBrightness(value=None)\n

      \u53c2\u6570\uff1a - value (int, optional): \u4eae\u5ea6\u503c\uff080-255\uff09\uff0c\u6216 None \u8868\u793a\u81ea\u52a8

      \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u4eae\u5ea6\u503c

      "},{"location":"qsl4a/system/settings/#checkscreenon","title":"checkScreenOn()","text":"

      \u68c0\u67e5\u5c4f\u5e55\u662f\u5426\u4eae\u7740\u3002

      checkScreenOn()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u5c4f\u5e55\u4eae\u7740\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/system/settings/#_2","title":"\u98de\u884c\u6a21\u5f0f","text":""},{"location":"qsl4a/system/settings/#checkairplanemode","title":"checkAirplaneMode()","text":"

      \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\u662f\u5426\u542f\u7528\u3002

      checkAirplaneMode()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u98de\u884c\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

      "},{"location":"qsl4a/system/settings/#_3","title":"\u94c3\u58f0\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#checkringersilentmode","title":"checkRingerSilentMode()","text":"

      \u68c0\u67e5\u94c3\u58f0\u662f\u5426\u5904\u4e8e\u9759\u97f3\u6a21\u5f0f\u3002

      checkRingerSilentMode()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u9759\u97f3\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

      "},{"location":"qsl4a/system/settings/#toggleringersilentmode","title":"toggleRingerSilentMode()","text":"

      \u5207\u6362\u94c3\u58f0\u9759\u97f3\u6a21\u5f0f\u3002

      toggleRingerSilentMode(enabled=None)\n

      \u53c2\u6570\uff1a - enabled (bool, optional): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

      \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

      "},{"location":"qsl4a/system/settings/#togglevibratemode","title":"toggleVibrateMode()","text":"

      \u5207\u6362\u632f\u52a8\u6a21\u5f0f\u3002

      toggleVibrateMode(enabled=None, ringer=None)\n

      \u53c2\u6570\uff1a - enabled (bool, optional): \u5207\u6362\u632f\u52a8\u5f00/\u5173 - ringer (bool, optional): \u5e94\u7528\u4e8e\u94c3\u58f0\u6a21\u5f0f

      \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

      "},{"location":"qsl4a/system/settings/#getvibratemode","title":"getVibrateMode()","text":"

      \u83b7\u53d6\u632f\u52a8\u6a21\u5f0f\u8bbe\u7f6e\u3002

      getVibrateMode(ringer=None)\n

      \u53c2\u6570\uff1a - ringer (bool, optional): \u68c0\u67e5\u94c3\u58f0\u632f\u52a8\u6a21\u5f0f

      \u8fd4\u56de\uff1a \u5982\u679c\u632f\u52a8\u5df2\u542f\u7528\u5219\u4e3a True

      "},{"location":"qsl4a/system/settings/#_4","title":"\u97f3\u91cf\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#getringervolume","title":"getRingerVolume()","text":"

      \u83b7\u53d6\u5f53\u524d\u94c3\u58f0\u97f3\u91cf\u3002

      getRingerVolume()\n

      \u8fd4\u56de\uff1a \u94c3\u58f0\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-7\uff09

      "},{"location":"qsl4a/system/settings/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

      getMaxRingerVolume()\n

      \u8fd4\u56de\uff1a \u6700\u5927\u94c3\u58f0\u97f3\u91cf

      "},{"location":"qsl4a/system/settings/#setringervolume","title":"setRingerVolume()","text":"

      \u8bbe\u7f6e\u94c3\u58f0\u97f3\u91cf\u3002

      setRingerVolume(volume)\n

      \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

      "},{"location":"qsl4a/system/settings/#getmediavolume","title":"getMediaVolume()","text":"

      \u83b7\u53d6\u5f53\u524d\u5a92\u4f53\u97f3\u91cf\u3002

      getMediaVolume()\n

      \u8fd4\u56de\uff1a \u5a92\u4f53\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-15\uff09

      "},{"location":"qsl4a/system/settings/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

      getMaxMediaVolume()\n

      \u8fd4\u56de\uff1a \u6700\u5927\u5a92\u4f53\u97f3\u91cf

      "},{"location":"qsl4a/system/settings/#setmediavolume","title":"setMediaVolume()","text":"

      \u8bbe\u7f6e\u5a92\u4f53\u97f3\u91cf\u3002

      setMediaVolume(volume)\n

      \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

      "},{"location":"qsl4a/system/settings/#_5","title":"\u7cfb\u7edf\u4fe1\u606f","text":""},{"location":"qsl4a/system/settings/#elapsedrealtimenanos","title":"elapsedRealtimeNanos()","text":"

      \u83b7\u53d6\u81ea\u7cfb\u7edf\u542f\u52a8\u4ee5\u6765\u7684\u7eb3\u79d2\u6570\u3002

      elapsedRealtimeNanos()\n

      \u8fd4\u56de\uff1a \u7eb3\u79d2\u6570\uff08\u53ef\u7528\u4e8e\u8ba1\u65f6\uff09

      "},{"location":"qsl4a/system/settings/#gettrafficstats","title":"getTrafficStats()","text":"

      \u83b7\u53d6\u7f51\u7edc\u6d41\u91cf\u7edf\u8ba1\u3002

      getTrafficStats(flags=7)\n

      \u53c2\u6570\uff1a - flags (int): \u8981\u68c0\u7d22\u7684\u7edf\u8ba1\uff08\u9ed8\u8ba4\uff1a7 = \u5168\u90e8\uff09

      \u8fd4\u56de\uff1a \u5305\u542b\u53d1\u9001/\u63a5\u6536\u5b57\u8282\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/settings/#getapptxbytes","title":"getAppTxBytes()","text":"

      \u83b7\u53d6 QPython \u5e94\u7528\u7684\u53d1\u9001\u5b57\u8282\u3002

      getAppTxBytes(packageName)\n

      \u53c2\u6570\uff1a - packageName (str): \u5305\u540d

      \u8fd4\u56de\uff1a \u5305\u542b tx/rx \u5b57\u8282\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/settings/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5c4f\u5e55\u8bbe\u7f6e\ncurrent_timeout = droid.getScreenTimeout().result\nprint(f\"Current timeout: {current_timeout}s\")\ndroid.setScreenTimeout(30)\n\n# \u68c0\u67e5\u5c4f\u5e55\nif droid.checkScreenOn().result:\n    print(\"Screen is on\")\n\n# \u97f3\u91cf\u63a7\u5236\nmedia_vol = droid.getMediaVolume().result\nprint(f\"Media volume: {media_vol}\")\ndroid.setMediaVolume(10)\n\n# \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\nif droid.checkAirplaneMode().result:\n    print(\"Airplane mode is on\")\n
      "},{"location":"qsl4a/system/sysinfo/","title":"\u7cfb\u7edf\u4fe1\u606f","text":"

      \u68c0\u7d22\u8bbe\u5907\u548c\u7cfb\u7edf\u4fe1\u606f\u3002

      "},{"location":"qsl4a/system/sysinfo/#_2","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/sysinfo/#getandroidid","title":"getAndroidID()","text":"

      \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

      getAndroidID()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

      "},{"location":"qsl4a/system/sysinfo/#getsysinfo","title":"getSysInfo()","text":"

      \u83b7\u53d6\u7efc\u5408\u7cfb\u7edf\u4fe1\u606f\u3002

      getSysInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/sysinfo/#getlocale","title":"getLocale()","text":"

      \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u8bbe\u7f6e\u3002

      getLocale()\n

      \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

      "},{"location":"qsl4a/system/sysinfo/#_3","title":"\u5185\u5b58","text":""},{"location":"qsl4a/system/sysinfo/#getmemoryinfo","title":"getMemoryInfo()","text":"

      \u83b7\u53d6 RAM \u4fe1\u606f\u3002

      getMemoryInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/sysinfo/#_4","title":"\u663e\u793a","text":""},{"location":"qsl4a/system/sysinfo/#getscreeninfo","title":"getScreenInfo()","text":"

      \u83b7\u53d6\u663e\u793a\u4fe1\u606f\u3002

      getScreenInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/sysinfo/#_5","title":"\u6807\u8bc6\u7b26","text":""},{"location":"qsl4a/system/sysinfo/#getimei","title":"getImei()","text":"

      \u83b7\u53d6\u8bbe\u5907 IMEI\u3002

      getImei(slotIndex=None)\n
      "},{"location":"qsl4a/system/sysinfo/#getmeid","title":"getMeid()","text":"

      \u83b7\u53d6\u8bbe\u5907 MEID\u3002

      getMeid(slotIndex=None)\n
      "},{"location":"qsl4a/system/sysinfo/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u8bbe\u5907 ID\nandroid_id = droid.getAndroidID().result\nprint(f\"Android ID: {android_id}\")\n\n# \u5c4f\u5e55\u4fe1\u606f\nscreen = droid.getScreenInfo().result\nprint(f\"Screen: {screen['width']}x{screen['height']}\")\n\n# \u5185\u5b58\nmemory = droid.getMemoryInfo().result\nprint(f\"Memory: {memory}\")\n
      "},{"location":"qsl4a/system/wakelock/","title":"WakeLock API","text":"

      \u63a7\u5236\u8bbe\u5907\u5524\u9192\u9501\u4ee5\u4fdd\u6301 CPU \u6216\u5c4f\u5e55\u5f00\u542f\u3002

      "},{"location":"qsl4a/system/wakelock/#wake-lock","title":"Wake Lock \u7c7b\u578b","text":"

      QSL4A \u63d0\u4f9b\u4e0d\u540c\u7c7b\u578b\u7684\u5524\u9192\u9501\uff1a

      \u7c7b\u578b \u63cf\u8ff0 Full CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae Partial \u4ec5 CPU \u5f00\u542f Bright CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae Dim CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697"},{"location":"qsl4a/system/wakelock/#wake-lock_1","title":"Wake Lock \u65b9\u6cd5","text":""},{"location":"qsl4a/system/wakelock/#wakelockacquirefull","title":"wakeLockAcquireFull()","text":"

      \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae\uff09\u3002

      wakeLockAcquireFull()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquirepartial","title":"wakeLockAcquirePartial()","text":"

      \u83b7\u53d6\u90e8\u5206\u5524\u9192\u9501\uff08\u4ec5 CPU \u5f00\u542f\uff09\u3002

      wakeLockAcquirePartial()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquirebright","title":"wakeLockAcquireBright()","text":"

      \u83b7\u53d6\u660e\u4eae\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff09\u3002

      wakeLockAcquireBright()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquiredim","title":"wakeLockAcquireDim()","text":"

      \u83b7\u53d6\u6697\u6de1\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697\uff09\u3002

      wakeLockAcquireDim()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockrelease","title":"wakeLockRelease()","text":"

      \u91ca\u653e\u5524\u9192\u9501\u3002

      wakeLockRelease()\n
      "},{"location":"qsl4a/system/wakelock/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\ndroid.wakeLockAcquireFull()\n\n# \u5728\u4fdd\u6301\u5c4f\u5e55\u5f00\u542f\u65f6\u6267\u884c\u91cd\u8981\u5de5\u4f5c\nprint(\"Screen will stay on\")\ntime.sleep(10)\n\n# \u5b8c\u6210\u540e\u91ca\u653e\ndroid.wakeLockRelease()\n\n# \u6216\u4f7f\u7528\u90e8\u5206\u9501\u8fdb\u884c\u540e\u53f0\u4efb\u52a1\ndroid.wakeLockAcquirePartial()\n# \u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\uff0cCPU \u4ecd\u4fdd\u6301\u5f00\u542f\ntime.sleep(30)\ndroid.wakeLockRelease()\n

      \u6ce8\u610f\uff1a \u8bb0\u4f4f\u5728\u4e0d\u9700\u8981\u65f6\u91ca\u653e\u5524\u9192\u9501\u4ee5\u8282\u7701\u7535\u6c60\u3002

      "},{"location":"qsl4a/ui/accessibility/","title":"\u65e0\u969c\u788d\u670d\u52a1","text":"

      \u65e0\u969c\u788d\u670d\u52a1\u5141\u8bb8\u81ea\u52a8\u5316 UI \u4ea4\u4e92\uff0c\u5982\u70b9\u51fb\u3001\u6ed1\u52a8\u548c\u7cfb\u7edf\u64cd\u4f5c\u3002

      "},{"location":"qsl4a/ui/accessibility/#_2","title":"\u670d\u52a1\u63a7\u5236","text":""},{"location":"qsl4a/ui/accessibility/#accessibilitystartservice","title":"accessibilityStartService()","text":"

      \u542f\u52a8\u65e0\u969c\u788d\u670d\u52a1\u3002

      accessibilityStartService()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/ui/accessibility/#accessibilityserviceenabled","title":"accessibilityServiceEnabled()","text":"

      \u68c0\u67e5\u65e0\u969c\u788d\u670d\u52a1\u662f\u5426\u5df2\u542f\u7528\u3002

      accessibilityServiceEnabled()\n

      \u8fd4\u56de\uff1a True \u6216 False

      "},{"location":"qsl4a/ui/accessibility/#_3","title":"\u5c4f\u5e55\u4ea4\u4e92","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityclick","title":"accessibilityClick()","text":"

      \u5728\u5c4f\u5e55\u5750\u6807\u5904\u70b9\u51fb\u3002

      accessibilityClick(x=0, y=0, t=50)\n

      \u53c2\u6570\uff1a - x (int/float): X \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - y (int/float): Y \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - t (int): \u6309\u4f4f\u65f6\u957f\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a50\uff09

      "},{"location":"qsl4a/ui/accessibility/#accessibilityslide","title":"accessibilitySlide()","text":"

      \u591a\u70b9\u6ed1\u52a8\u624b\u52bf\u3002

      accessibilitySlide(XnYn=None, t=None)\n

      \u53c2\u6570\uff1a - XnYn (list): \u5750\u6807 [X1, Y1, X2, Y2, ... Xn, Yn] - t (int): \u6ed1\u52a8\u65f6\u957f\uff08\u9ed8\u8ba4\uff1a50*n \u6beb\u79d2\uff09

      "},{"location":"qsl4a/ui/accessibility/#_4","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityaction","title":"accessibilityAction()","text":"

      \u6309\u4ee3\u7801\u6267\u884c\u7cfb\u7edf\u64cd\u4f5c\u3002

      accessibilityAction(actionCode)\n

      \u64cd\u4f5c\u4ee3\u7801\uff1a | \u4ee3\u7801 | \u5e38\u91cf | \u63cf\u8ff0 | |------|----------|-------------| | 1 | BACK | \u8fd4\u56de\u6309\u94ae | | 2 | HOME | \u4e3b\u5c4f\u5e55\u6309\u94ae | | 3 | RECENTS | \u6700\u8fd1\u5e94\u7528 | | 4 | NOTIFICATIONS | \u6253\u5f00\u901a\u77e5 | | 5 | QUICK_SETTINGS | \u6253\u5f00\u5feb\u901f\u8bbe\u7f6e | | 6 | POWER_DIALOG | \u7535\u6e90\u83dc\u5355 | | 7 | TOGGLE_SPLIT_SCREEN | \u5206\u5c4f | | 8 | LOCK_SCREEN | \u9501\u5c4f | | 9 | TAKE_SCREENSHOT | \u622a\u56fe | | 10 | KEYCODE_HEADSETHOOK | \u8033\u673a\u6302\u94a9 | | 11-14 | ACCESSIBILITY_ | \u65e0\u969c\u788d\u6309\u94ae | | 15 | DISMISS_NOTIFICATION_SHADE | \u5173\u95ed\u901a\u77e5\u680f | | 16-20 | DPAD_ | \u65b9\u5411\u952e | | 21 | MENU | \u83dc\u5355\u6309\u94ae | | 22 | MEDIA_PLAY_PAUSE | \u64ad\u653e/\u6682\u505c\u5a92\u4f53 |

      "},{"location":"qsl4a/ui/accessibility/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/accessibility/#_6","title":"\u70b9\u51fb\u5c4f\u5e55\u4e2d\u5fc3","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u670d\u52a1\nif not droid.accessibilityServiceEnabled().result:\n    droid.accessibilityStartService()\n\n# \u70b9\u51fb\u4e2d\u5fc3\uff080,0 = \u4e2d\u5fc3\uff09\ndroid.accessibilityClick(0, 0, t=100)\n
      "},{"location":"qsl4a/ui/accessibility/#_7","title":"\u6ed1\u52a8\u624b\u52bf","text":"
      # \u4ece\u4e0b\u5f80\u4e0a\u6ed1\u52a8\uff08\u5411\u4e0a\u6eda\u52a8\uff09\ndroid.accessibilitySlide([0, 1.5, 0, -1.5], t=300)\n
      "},{"location":"qsl4a/ui/accessibility/#_8","title":"\u7cfb\u7edf\u5bfc\u822a","text":"
      # \u6309\u4e3b\u5c4f\u5e55\ndroid.accessibilityAction(2)\n\n# \u6309\u8fd4\u56de\ndroid.accessibilityAction(1)\n\n# \u6253\u5f00\u901a\u77e5\ndroid.accessibilityAction(4)\n
      "},{"location":"qsl4a/ui/accessibility/#_9","title":"\u70b9\u51fb\u7279\u5b9a\u4f4d\u7f6e","text":"
      # \u70b9\u51fb\u5c4f\u5e55\u5750\u6807 (500, 800)\ndroid.accessibilityClick(500, 800)\n\n# \u70b9\u51fb\u76f8\u5bf9\u4f4d\u7f6e\uff08\u6c34\u5e73\u5c45\u4e2d\uff0c\u5782\u76f4 3/4 \u5904\uff09\ndroid.accessibilityClick(0, 1.5)\n
      "},{"location":"qsl4a/ui/dialogs/","title":"\u5bf9\u8bdd\u6846\u7cfb\u7edf","text":"

      QSL4A \u63d0\u4f9b\u5168\u9762\u7684\u5bf9\u8bdd\u6846\u652f\u6301\uff0c\u7528\u4e8e\u7528\u6237\u4ea4\u4e92\uff0c\u5305\u62ec\u8b66\u62a5\u3001\u8f93\u5165\u5bf9\u8bdd\u6846\u3001\u9009\u62e9\u5bf9\u8bdd\u6846\u548c\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

      "},{"location":"qsl4a/ui/dialogs/#_2","title":"\u8b66\u62a5\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowalert","title":"dialogShowAlert()","text":"

      \u663e\u793a\u7b80\u5355\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

      dialogShowAlert(title=\"Alert\", message=\"The message of the alert.\",\n                positiveButtonText=\"OK\", negativeButtonText=None,\n                neutralButtonText=None, messageIsHtml=False)\n

      \u53c2\u6570\uff1a - title (str): \u5bf9\u8bdd\u6846\u6807\u9898 - message (str): \u6d88\u606f\u6587\u672c - positiveButtonText (str): \u80af\u5b9a\u6309\u94ae\u6807\u7b7e - negativeButtonText (str, optional): \u5426\u5b9a\u6309\u94ae\u6807\u7b7e - neutralButtonText (str, optional): \u4e2d\u6027\u6309\u94ae\u6807\u7b7e - messageIsHtml (bool): \u5c06\u6d88\u606f\u89e3\u6790\u4e3a HTML

      \u8fd4\u56de\uff1a \u5305\u542b\u70b9\u51fb\u6309\u94ae\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#dialogshowsimplechoice","title":"dialogShowSimpleChoice()","text":"

      \u663e\u793a\u5e26\u6709\u9879\u76ee\u7684\u7b80\u5355\u9009\u62e9\u5bf9\u8bdd\u6846\u3002

      dialogShowSimpleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

      \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868

      \u8fd4\u56de\uff1a \u5305\u542b\u9009\u4e2d\u9879\u76ee\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#_3","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialoggetinput","title":"dialogGetInput()","text":"

      \u83b7\u53d6\u7528\u6237\u6587\u672c\u8f93\u5165\u3002

      dialogGetInput(title=\"Value\", message=\"Please enter value:\",\n               defaultText=None, messageIsHtml=False)\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7528\u6237\u8f93\u5165\u6587\u672c\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#dialoggetpassword","title":"dialogGetPassword()","text":"

      \u83b7\u53d6\u5bc6\u7801\u8f93\u5165\u3002

      dialogGetPassword(title=\"Password\", message=\"Please enter password:\")\n

      \u8fd4\u56de\uff1a \u5305\u542b\u8f93\u5165\u5bc6\u7801\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#dialogcreateinput","title":"dialogCreateInput()","text":"

      \u521b\u5efa\u81ea\u5b9a\u4e49\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

      dialogCreateInput(title=\"Value\", message=\"Please enter value:\",\n                  defaultText=None, inputType=None)\n

      \u53c2\u6570\uff1a - inputType (str): \u8f93\u5165\u7c7b\u578b\uff08\u4f8b\u5982 \"text\"\u3001\"number\"\u3001\"textPassword\"\uff09

      "},{"location":"qsl4a/ui/dialogs/#dialogcreatepassword","title":"dialogCreatePassword()","text":"

      \u521b\u5efa\u5bc6\u7801\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

      dialogCreatePassword(title=\"Password\", message=\"Please enter password:\")\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreateseekbar","title":"dialogCreateSeekBar()","text":"

      \u521b\u5efa\u6ed1\u5757/\u8fdb\u5ea6\u6761\u5bf9\u8bdd\u6846\u3002

      dialogCreateSeekBar(starting_value=50, maximum_value=100, title=\"\", message=\"\")\n

      \u53c2\u6570\uff1a - starting_value (int): \u521d\u59cb\u503c - maximum_value (int): \u6700\u5927\u503c

      "},{"location":"qsl4a/ui/dialogs/#_4","title":"\u9009\u62e9\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowsinglechoice","title":"dialogShowSingleChoice()","text":"

      \u663e\u793a\u5355\u9009\uff08\u5355\u9009\u6309\u94ae\uff09\u5bf9\u8bdd\u6846\u3002

      dialogShowSingleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, selected=-1, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

      \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (int): \u9ed8\u8ba4\u9009\u4e2d\u7d22\u5f15

      "},{"location":"qsl4a/ui/dialogs/#dialogshowmultichoice","title":"dialogShowMultiChoice()","text":"

      \u663e\u793a\u591a\u9009\uff08\u590d\u9009\u6846\uff09\u5bf9\u8bdd\u6846\u3002

      dialogShowMultiChoice(title=\"Alert\", message=\"The message of the alert.\",\n                      items=None, selected=None, positiveButtonText=\"OK\",\n                      negativeButtonText=None, neutralButtonText=None,\n                      messageIsHtml=False)\n

      \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (list): \u521d\u59cb\u9009\u4e2d\u7d22\u5f15\u5217\u8868

      "},{"location":"qsl4a/ui/dialogs/#dialogsetsinglechoiceitems","title":"dialogSetSingleChoiceItems()","text":"

      \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u5355\u9009\u9879\u76ee\u3002

      dialogSetSingleChoiceItems(items, selected=-1)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmultichoiceitems","title":"dialogSetMultiChoiceItems()","text":"

      \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u591a\u9009\u9879\u76ee\u3002

      dialogSetMultiChoiceItems(items, selected=None)\n
      "},{"location":"qsl4a/ui/dialogs/#_5","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatespinnerprogress","title":"dialogCreateSpinnerProgress()","text":"

      \u521b\u5efa\u4e0d\u786e\u5b9a\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

      dialogCreateSpinnerProgress(title=None, message=None, maximum_progress=100)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreatehorizontalprogress","title":"dialogCreateHorizontalProgress()","text":"

      \u521b\u5efa\u6c34\u5e73\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

      dialogCreateHorizontalProgress(title=None, message=None, maximum_progress=100)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetcurrentprogress","title":"dialogSetCurrentProgress()","text":"

      \u66f4\u65b0\u8fdb\u5ea6\u503c\u3002

      dialogSetCurrentProgress(current)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmaxprogress","title":"dialogSetMaxProgress()","text":"

      \u8bbe\u7f6e\u6700\u5927\u8fdb\u5ea6\u503c\u3002

      dialogSetMaxProgress(max)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetprogressmessage","title":"dialogSetProgressMessage()","text":"

      \u66f4\u65b0\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u6d88\u606f\u3002

      dialogSetProgressMessage(message)\n
      "},{"location":"qsl4a/ui/dialogs/#_6","title":"\u9009\u62e9\u5668\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatedatepicker","title":"dialogCreateDatePicker()","text":"

      \u521b\u5efa\u65e5\u671f\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

      dialogCreateDatePicker(year=1970, month=1, day=1)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreatetimepicker","title":"dialogCreateTimePicker()","text":"

      \u521b\u5efa\u65f6\u95f4\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

      dialogCreateTimePicker(hour=0, minute=0, is24hour=False)\n
      "},{"location":"qsl4a/ui/dialogs/#_7","title":"\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u521b\u5efa","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatealert","title":"dialogCreateAlert()","text":"

      \u521b\u5efa\u81ea\u5b9a\u4e49\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

      dialogCreateAlert(title=None, message=None)\n

      \u521b\u5efa\u4e00\u4e2a\u7a7a\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002\u53ef\u4e0e\u5176\u4ed6 dialogSet* \u51fd\u6570\u4e00\u8d77\u4f7f\u7528\u6765\u81ea\u5b9a\u4e49\u3002

      "},{"location":"qsl4a/ui/dialogs/#dialogsetitems","title":"dialogSetItems()","text":"

      \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u7b80\u5355\u5217\u8868\u9879\u76ee\u3002

      dialogSetItems(items)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetpositivebuttontext","title":"dialogSetPositiveButtonText()","text":"

      \u8bbe\u7f6e\u80af\u5b9a\u6309\u94ae\u6587\u672c\u3002

      dialogSetPositiveButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetnegativebuttontext","title":"dialogSetNegativeButtonText()","text":"

      \u8bbe\u7f6e\u5426\u5b9a\u6309\u94ae\u6587\u672c\u3002

      dialogSetNegativeButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetneutralbuttontext","title":"dialogSetNeutralButtonText()","text":"

      \u8bbe\u7f6e\u4e2d\u6027\u6309\u94ae\u6587\u672c\u3002

      dialogSetNeutralButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmessageishtml","title":"dialogSetMessageIsHtml()","text":"

      \u8bbe\u7f6e\u6d88\u606f\u662f\u5426\u5e94\u89e3\u6790\u4e3a HTML\u3002

      dialogSetMessageIsHtml(messageIsHtml=True)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogshow","title":"dialogShow()","text":"

      \u663e\u793a\u521b\u5efa\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u3002

      dialogShow()\n
      "},{"location":"qsl4a/ui/dialogs/#_8","title":"\u5bf9\u8bdd\u6846\u63a7\u5236","text":""},{"location":"qsl4a/ui/dialogs/#dialogdismiss","title":"dialogDismiss()","text":"

      \u5173\u95ed\u5f53\u524d\u5bf9\u8bdd\u6846\u3002

      dialogDismiss()\n
      "},{"location":"qsl4a/ui/dialogs/#dialoggetresponse","title":"dialogGetResponse()","text":"

      \u83b7\u53d6\u5bf9\u8bdd\u6846\u54cd\u5e94\u3002

      dialogGetResponse()\n
      "},{"location":"qsl4a/ui/dialogs/#dialoggetselecteditems","title":"dialogGetSelectedItems()","text":"

      \u4ece\u9009\u62e9\u5bf9\u8bdd\u6846\u83b7\u53d6\u9009\u4e2d\u7684\u9879\u76ee\u3002

      dialogGetSelectedItems()\n
      "},{"location":"qsl4a/ui/dialogs/#_9","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/dialogs/#_10","title":"\u7b80\u5355\u8b66\u62a5","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a\u8b66\u62a5\ndroid.dialogShowAlert(\"Warning\", \"This is an important message!\")\n
      "},{"location":"qsl4a/ui/dialogs/#_11","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":"
      # \u83b7\u53d6\u7528\u6237\u8f93\u5165\nresult = droid.dialogGetInput(\"Name\", \"Enter your name:\", \"John\").result\nprint(f\"Hello, {result}!\")\n
      "},{"location":"qsl4a/ui/dialogs/#_12","title":"\u5e26\u6309\u94ae\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846","text":"
      # \u521b\u5efa\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\ndroid.dialogCreateAlert(\"Custom\", \"Choose an option\")\ndroid.dialogSetItems([\"Option 1\", \"Option 2\", \"Option 3\"])\ndroid.dialogShow()\n\n# \u83b7\u53d6\u54cd\u5e94\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response['item']}\")\n
      "},{"location":"qsl4a/ui/dialogs/#_13","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":"
      # \u521b\u5efa\u8fdb\u5ea6\u5bf9\u8bdd\u6846\ndroid.dialogCreateHorizontalProgress(\"Loading\", \"Please wait...\", 100)\ndroid.dialogShow()\n\n# \u66f4\u65b0\u8fdb\u5ea6\nfor i in range(101):\n    droid.dialogSetCurrentProgress(i)\n    time.sleep(0.05)\n\ndroid.dialogDismiss()\n
      "},{"location":"qsl4a/ui/dialogs/#_14","title":"\u65e5\u671f\u9009\u62e9\u5668","text":"
      # \u663e\u793a\u65e5\u671f\u9009\u62e9\u5668\ndroid.dialogCreateDatePicker(2024, 1, 15)\ndroid.dialogShow()\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response}\")\n
      "},{"location":"qsl4a/ui/floatview/","title":"\u6d6e\u52a8\u89c6\u56fe","text":"

      \u6d6e\u52a8\u7a97\u53e3\u652f\u6301\uff0c\u7528\u4e8e\u5728\u5176\u4ed6\u5e94\u7528\u7a0b\u5e8f\u4e0a\u65b9\u4fdd\u6301\u663e\u793a\u7684\u8986\u76d6 UI \u5143\u7d20\u3002

      "},{"location":"qsl4a/ui/floatview/#_2","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/floatview/#floatview","title":"floatView()","text":"

      \u663e\u793a\u6216\u4fee\u6539\u6d6e\u52a8\u89c6\u56fe\u3002

      floatView(Args=None)\n

      \u53c2\u6570\uff1a - Args (dict): \u914d\u7f6e\u5b57\u5178\uff0c\u5305\u542b\u4ee5\u4e0b\u952e\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08-1 \u521b\u5efa\u65b0\u7684\uff0c>=0 \u4fee\u6539\u73b0\u6709\u7684\uff09 - text (str): \u8981\u663e\u793a\u7684\u6587\u672c\u5185\u5bb9 - html (str): HTML \u5185\u5bb9\uff08\u5982\u679c\u7701\u7565 text \u5219\u4f7f\u7528\uff09 - width (int): \u89c6\u56fe\u5bbd\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a300\uff09 - height (int): \u89c6\u56fe\u9ad8\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a150\uff09 - x (int): X \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - y (int): Y \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - backColor (str): ARGB \u5341\u516d\u8fdb\u5236\u80cc\u666f\u8272\uff08\u9ed8\u8ba4\uff1a'7f7f7f7f'\uff09 - textColor (str): ARGB \u5341\u516d\u8fdb\u5236\u6587\u672c\u8272\uff08\u9ed8\u8ba4\uff1a'ff000000'\uff09 - textSize (int): \u6587\u672c\u5927\u5c0f\uff08\u9ed8\u8ba4\uff1a10\uff09 - textAlign (int): \u6587\u672c\u5bf9\u9f50\uff080 = \u7ee7\u627f\uff09 - script (str): \u957f\u6309\u5173\u95ed\u540e\u8fd0\u884c\u7684\u811a\u672c\u8def\u5f84 - arg: \u811a\u672c\u53c2\u6570 - clickRemove (bool): \u542f\u7528\u70b9\u51fb\u79fb\u9664\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - flag (int): \u7a97\u53e3\u6807\u5fd7\uff08\u9ed8\u8ba4\uff1a40 - \u53ef\u89e6\u6478\uff09

      \u8fd4\u56de\uff1a \u5f53\u524d\u94fe\u5217\u8868\u957f\u5ea6

      "},{"location":"qsl4a/ui/floatview/#floatviewcount","title":"floatViewCount()","text":"

      \u83b7\u53d6\u6d3b\u52a8\u6d6e\u52a8\u89c6\u56fe\u7684\u6570\u91cf\u3002

      floatViewCount()\n

      \u8fd4\u56de\uff1a \u6d6e\u52a8\u89c6\u56fe\u6570\u91cf

      "},{"location":"qsl4a/ui/floatview/#floatviewresult","title":"floatViewResult()","text":"

      \u83b7\u53d6\u6d6e\u52a8\u89c6\u56fe\u7684\u7ed3\u679c/\u72b6\u6001\u3002

      floatViewResult(index=-1)\n

      \u53c2\u6570\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1\uff0c\u8fd4\u56de\u6700\u540e\u64cd\u4f5c\u7ed3\u679c\uff09

      \u8fd4\u56de\uff1a \u5305\u542b\u64cd\u4f5c\u8be6\u60c5\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - x, y: \u4f4d\u7f6e - time: \u65f6\u95f4\u6233 - operation: \u64cd\u4f5c\u7c7b\u578b\uff08'initial'\u3001'move' \u7b49\uff09 - index: \u89c6\u56fe\u7d22\u5f15 - removed: \u5982\u679c\u89c6\u56fe\u88ab\u79fb\u9664\u5219\u4e3a True

      "},{"location":"qsl4a/ui/floatview/#floatviewremove","title":"floatViewRemove()","text":"

      \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\u3002

      floatViewRemove(index=-1)\n

      \u53c2\u6570\uff1a - index (int): \u8981\u79fb\u9664\u7684\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1 \u79fb\u9664\u6700\u540e\u4e00\u4e2a\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a 1\uff0c\u5426\u5219\u4e3a 0

      "},{"location":"qsl4a/ui/floatview/#_3","title":"\u5e38\u91cf","text":"
      • floatView.INDEX_NEW = -1 - \u521b\u5efa\u65b0\u7684\u6d6e\u52a8\u89c6\u56fe
      • floatView.FLAG_DEFAULT_TOUCHABLE = 40 - \u9ed8\u8ba4\u53ef\u89e6\u6478\u6807\u5fd7
      • floatView.TEXT_ALIGNMENT_INHERIT = 0
      • floatView.TEXT_ALIGNMENT_CENTER - \u5c45\u4e2d\u6587\u672c\u5bf9\u9f50
      "},{"location":"qsl4a/ui/floatview/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/floatview/#_5","title":"\u57fa\u672c\u6d6e\u52a8\u89c6\u56fe","text":"
      import androidhelper\nfrom androidhelper import Android\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u7b80\u5355\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'index': -1,  # \u521b\u5efa\u65b0\u7684\n    'text': 'Hello World',\n    'width': 400,\n    'height': 300,\n    'x': -300,  # \u4ece\u4e2d\u5fc3\u504f\u79fb\n    'y': -400,\n    'backColor': 'ff0000',  # \u7ea2\u8272\u80cc\u666f\n    'textColor': '0000ff',  # \u84dd\u8272\u6587\u672c\n    'textSize': 16,\n    'textAlign': droid.floatView.TEXT_ALIGNMENT_CENTER\n})\n\n# \u68c0\u67e5\u6570\u91cf\nprint(f\"Float views: {droid.floatViewCount().result}\")\n\n# \u83b7\u53d6\u7ed3\u679c\nresult = droid.floatViewResult().result\nprint(f\"View info: {result}\")\n\n# \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\ndroid.floatViewRemove(0)\n
      "},{"location":"qsl4a/ui/floatview/#html","title":"HTML \u5185\u5bb9","text":"
      # \u521b\u5efa\u5e26 HTML \u5185\u5bb9\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': '',  # \u7a7a\u6587\u672c\u4ee5\u4f7f\u7528 HTML\n    'html': '<h1>Title</h1><p>Rich <b>HTML</b> content</p>',\n    'width': 500,\n    'height': 400\n})\n
      "},{"location":"qsl4a/ui/floatview/#_6","title":"\u4fee\u6539\u73b0\u6709\u89c6\u56fe","text":"
      # \u521b\u5efa\u521d\u59cb\u89c6\u56fe\ndroid.floatView({'text': 'Initial Text', 'width': 300, 'height': 150})\n\n# \u4fee\u6539\u540c\u4e00\u89c6\u56fe\uff08\u7d22\u5f15 0\uff09\ndroid.floatView({\n    'index': 0,\n    'text': 'Updated Text!',\n    'backColor': '7f00ff00'  # \u7eff\u8272\u80cc\u666f\n})\n\n# \u68c0\u67e5\u79fb\u52a8/\u66f4\u6539\u7ed3\u679c\nresult = droid.floatViewResult(0).result\nprint(f\"Operation: {result.get('operation')}, Position: ({result.get('x')}, {result.get('y')})\")\n
      "},{"location":"qsl4a/ui/floatview/#_7","title":"\u591a\u4e2a\u6d6e\u52a8\u89c6\u56fe","text":"
      # \u521b\u5efa\u591a\u4e2a\u89c6\u56fe\nfor i in range(3):\n    droid.floatView({\n        'index': -1,\n        'text': f'View {i}',\n        'x': i * 100 - 150,\n        'y': i * 100 - 150,\n        'backColor': f'{i}f{i}f{i}f'\n    })\n\nprint(f\"Total views: {droid.floatViewCount().result}\")\n\n# \u79fb\u9664\u6240\u6709\u89c6\u56fe\nwhile droid.floatViewCount().result > 0:\n    droid.floatViewRemove()\n
      "},{"location":"qsl4a/ui/floatview/#_8","title":"\u5e26\u811a\u672c\u56de\u8c03","text":"
      # \u521b\u5efa\u5173\u95ed\u65f6\u8fd0\u884c\u811a\u672c\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': 'Click to close and run script',\n    'script': '/sdcard/my_script.py',\n    'arg': 'hello from float view',\n    'clickRemove': True\n})\n
      "},{"location":"qsl4a/ui/fullscreen/","title":"\u5168\u5c4f UI","text":"

      \u4f7f\u7528\u539f\u751f Android \u5e03\u5c40\u521b\u5efa\u81ea\u5b9a\u4e49\u5168\u5c4f\u754c\u9762\u3002

      "},{"location":"qsl4a/ui/fullscreen/#_1","title":"\u5e03\u5c40\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullshow","title":"fullShow()","text":"

      \u663e\u793a\u5168\u5c4f\u5e03\u5c40\u3002

      fullShow(layout, title=None, theme=None)\n

      \u53c2\u6570\uff1a - layout (str): JSON \u5e03\u5c40\u5b9a\u4e49\u6216\u5e03\u5c40\u5b57\u7b26\u4e32 - title (str, optional): \u7a97\u53e3\u6807\u9898 - theme (str, optional): \u4e3b\u9898\u540d\u79f0

      \u8fd4\u56de\uff1a \u7a97\u53e3 ID

      "},{"location":"qsl4a/ui/fullscreen/#fulldismiss","title":"fullDismiss()","text":"

      \u5173\u95ed\u5168\u5c4f\u7a97\u53e3\u3002

      fullDismiss()\n
      "},{"location":"qsl4a/ui/fullscreen/#fullquery","title":"fullQuery()","text":"

      \u67e5\u8be2\u6240\u6709\u5c0f\u90e8\u4ef6\u503c\u3002

      fullQuery()\n

      \u8fd4\u56de\uff1a \u5c0f\u90e8\u4ef6 ID \u548c\u503c\u7684\u5b57\u5178

      "},{"location":"qsl4a/ui/fullscreen/#fullquerydetail","title":"fullQueryDetail()","text":"

      \u67e5\u8be2\u7279\u5b9a\u5c0f\u90e8\u4ef6\u8be6\u60c5\u3002

      fullQueryDetail(id)\n
      "},{"location":"qsl4a/ui/fullscreen/#_2","title":"\u5c5e\u6027\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperty","title":"fullGetProperty()","text":"

      \u83b7\u53d6\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

      fullGetProperty(id, property)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetproperty","title":"fullSetProperty()","text":"

      \u8bbe\u7f6e\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

      fullSetProperty(id, property, value)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetlist","title":"fullSetList()","text":"

      \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

      fullSetList(id, list, isHtml=False, listType=0)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetlist2","title":"fullSetList2()","text":"

      \u4f7f\u7528\u8d44\u6e90 ID \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

      fullSetList2(id, list, intRes)\n

      \u53c2\u6570\uff1a - id (str): \u5c0f\u90e8\u4ef6 ID - list (list): \u9879\u76ee\u5217\u8868 - intRes (int): \u5217\u8868\u9879\u76ee\u5e03\u5c40\u7684 Android \u8d44\u6e90 ID

      "},{"location":"qsl4a/ui/fullscreen/#fullsetlistselected","title":"fullSetListSelected()","text":"

      \u5728\u5217\u8868\u4e2d\u8bbe\u7f6e\u9009\u4e2d\u9879\u76ee\u3002

      fullSetListSelected(id, selected)\n

      \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID - selected (int): \u8981\u9009\u4e2d\u7684\u9879\u76ee\u7d22\u5f15

      "},{"location":"qsl4a/ui/fullscreen/#fullgetlistselected","title":"fullGetListSelected()","text":"

      \u83b7\u53d6\u5f53\u524d\u9009\u4e2d\u7684\u5217\u8868\u9879\u76ee\u7d22\u5f15\u3002

      fullGetListSelected(id)\n

      \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID

      \u8fd4\u56de\uff1a \u9009\u4e2d\u9879\u76ee\u7d22\u5f15

      "},{"location":"qsl4a/ui/fullscreen/#_3","title":"\u6279\u91cf\u5c5e\u6027\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperties","title":"fullGetProperties()","text":"

      \u4e00\u6b21\u83b7\u53d6\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

      fullGetProperties(ids, property)\n

      \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u83b7\u53d6\u7684\u5c5e\u6027\u540d

      \u8fd4\u56de\uff1a \u6620\u5c04\u5c0f\u90e8\u4ef6 ID \u5230\u5c5e\u6027\u503c\u7684\u5b57\u5178

      "},{"location":"qsl4a/ui/fullscreen/#fullsetproperties","title":"fullSetProperties()","text":"

      \u4e00\u6b21\u8bbe\u7f6e\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

      fullSetProperties(ids, property, value)\n

      \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u8bbe\u7f6e\u7684\u5c5e\u6027\u540d - value: \u5c5e\u6027\u503c

      "},{"location":"qsl4a/ui/fullscreen/#_4","title":"\u622a\u56fe","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetscreenshot","title":"fullGetScreenShot()","text":"

      \u6355\u83b7\u5168\u5c4f\u622a\u56fe\u3002

      fullGetScreenShot(path=None)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u5728\u4e8b\u4ef6\u4e2d\u8fd4\u56de

      \u8fd4\u56de\uff1a \u5305\u542b\u622a\u56fe\u6570\u636e\u7684\u4e8b\u4ef6

      "},{"location":"qsl4a/ui/fullscreen/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b9a\u4e49\u5e03\u5c40\nlayout = '''\n{ \"type\": \"LinearLayout\", \"orientation\": \"vertical\",\n  \"children\": [\n    { \"type\": \"TextView\", \"id\": \"title\", \"text\": \"Hello\" },\n    { \"type\": \"Button\", \"id\": \"btn\", \"text\": \"Click Me\" }\n  ]\n}\n'''\n\n# \u663e\u793a\u5e03\u5c40\ndroid.fullShow(layout, \"My App\")\n\n# \u67e5\u8be2\u6309\u94ae\u70b9\u51fb\nevent = droid.eventWaitFor('click', timeout=10)\nif event.result:\n    widget_id = event.result['data']['id']\n    if widget_id == 'btn':\n        print(\"Button clicked!\")\n\ndroid.fullDismiss()\n
      "}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"QPython \u9879\u76ee","text":"

      QPython \u4e0d\u4ec5\u662f\u4e00\u4e2a\u5f3a\u5927\u7684 Android Python IDE\uff0c\u4e5f\u662f\u4e00\u4e2a\u6d3b\u8dc3\u7684\u6280\u672f\u793e\u533a\u3002

      "},{"location":"#ai-android-python-ide","title":"\u652f\u6301 AI \u7684 Android Python IDE","text":"

      QPython \u662f\u60a8\u8fdb\u884c Android Python \u7f16\u7a0b\u7684\u5165\u53e3\u3002\u5b83\u96c6\u6210\u4e86 Python \u89e3\u91ca\u5668\u3001AI \u6a21\u578b\u5f15\u64ce\u548c\u79fb\u52a8\u5f00\u53d1\u5de5\u5177\u94fe\uff0c\u8ba9\u60a8\u80fd\u591f\u4ece\u79fb\u52a8\u8bbe\u5907\u6784\u5efa Web \u5e94\u7528\u7a0b\u5e8f\u3001\u6267\u884c\u79d1\u5b66\u8ba1\u7b97\u548c\u521b\u5efa\u667a\u80fd\u5e94\u7528\u3002

      \u65e0\u8bba\u60a8\u662f\u5728\u5b66\u4e60\u7f16\u7a0b\u3001\u6784\u5efa\u6570\u636e\u79d1\u5b66\u9879\u76ee\uff0c\u8fd8\u662f\u5f00\u53d1 AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f\uff0cQPython \u90fd\u63d0\u4f9b\u4e86\u5b8c\u6574\u7684\u79fb\u52a8\u7f16\u7a0b\u89e3\u51b3\u65b9\u6848\uff0c\u62e5\u6709\u5168\u9762\u7684\u5f00\u53d1\u8005\u8d44\u6e90\u548c\u6d3b\u8dc3\u7684\u793e\u533a\u6765\u652f\u6301\u60a8\u7684\u65c5\u7a0b\u3002

      • \u5206\u652f\u7248\u672c \u2013 \u4e86\u89e3\u4e0d\u540c\u7684 QPython \u7248\u672c\uff08IDE\u3001\u793e\u533a\u7248\u3001Plus\uff09\uff0c\u9009\u62e9\u9002\u5408\u60a8\u9700\u6c42\u7684\u7248\u672c
      • \u66f4\u65b0\u65e5\u5fd7 \u2013 \u968f\u65f6\u4e86\u89e3\u6700\u65b0\u529f\u80fd\u3001\u6539\u8fdb\u548c\u53d1\u884c\u8bf4\u660e
      "},{"location":"#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"

      \u5982\u4f55\u5feb\u901f\u5165\u95e8\uff1f\u8bf7\u6309\u7167\u4ee5\u4e0b\u6b65\u9aa4\uff1a

      • \u5feb\u901f\u5165\u95e8
      • Hello World \u6559\u7a0b
      "},{"location":"#_2","title":"\u7f16\u7a0b\u6307\u5357","text":"

      QPython \u4e0d\u4ec5\u63d0\u4f9b\u57fa\u7840\u7684 Python \u63a5\u53e3\u652f\u6301\uff0c\u66f4\u91cd\u8981\u7684\u662f\uff0c\u5b83\u8fd8\u5141\u8bb8\u60a8\u901a\u8fc7 QSL4A \u63a5\u53e3\u4f7f\u7528 Python \u8c03\u7528 Android API\u3002

      • Python \u6807\u51c6\u5e93 \u2013 \u901a\u7528\u7684 Python \u8bed\u6cd5\u548c\u5185\u7f6e\u5e93
      • QSL4A API \u2013 \u4ece Python \u8bbf\u95ee Android \u8bbe\u5907\u529f\u80fd\uff08\u76f8\u673a\u3001\u4f20\u611f\u5668\u3001\u77ed\u4fe1\u7b49\uff09
      • QPYPI \u6307\u5357 \u2013 \u5b89\u88c5\u989d\u5916\u7684 Python \u5305
      • \u7f16\u8f91\u5668\u6307\u5357 \u2013 \u4f7f\u7528\u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668
      • \u5916\u90e8 API \u2013 \u4e0e\u5916\u90e8\u5e94\u7528\u7a0b\u5e8f\u96c6\u6210
      "},{"location":"#_3","title":"\u4e0b\u8f7d\u8d44\u6e90","text":"
      • Google Drive
      • \u5fae\u4fe1\u7f51\u76d8
      "},{"location":"#_4","title":"\u793e\u533a\u4e0e\u53cd\u9988","text":"
      • \u4e2d\u6587\u4ea4\u6d41\u793e\u533a
      • \u95ee\u9898\u53cd\u9988
      • \u529f\u80fd\u6269\u5c55\u8bf7\u6c42
      "},{"location":"#_5","title":"\u5173\u6ce8\u6211\u4eec","text":"
      • B\u7ad9
      • Weibo
      "},{"location":"AIPyApp/","title":"AIPyApp - AI\u9a71\u52a8\u7684\u7a0b\u5e8f\u751f\u6210\u5668","text":"

      AIPyApp \u662f QPython \u4e2d\u7684\u667a\u80fd\u5de5\u5177\uff0c\u53ef\u4ee5\u5229\u7528 AI \u4ece\u81ea\u7136\u8bed\u8a00\u6307\u4ee4\u81ea\u52a8\u751f\u6210 Python \u7a0b\u5e8f\u3002

      "},{"location":"AIPyApp/#_1","title":"\u6982\u8ff0","text":"

      AIPyApp \u6539\u53d8\u4e86\u60a8\u7f16\u5199\u4ee3\u7801\u7684\u65b9\u5f0f\u2014\u2014\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u63cf\u8ff0\u60a8\u60f3\u8981\u7684\u529f\u80fd\uff0cAI \u5c31\u4f1a\u4e3a\u60a8\u751f\u6210 Python \u7a0b\u5e8f\u3002QPython \u8fd8\u5c06\u63a8\u51fa AIPy Academy\u2014\u2014\u4e00\u4e2a\u4e3a AI \u65f6\u4ee3\u91cf\u8eab\u5b9a\u5236\u7684 Python \u7f16\u7a0b\u8bfe\u7a0b\u5e73\u53f0\u3002

      "},{"location":"AIPyApp/#_2","title":"\u5b89\u88c5","text":"

      QPython \u6c1b\u56f4\u7f16\u7a0b\uff08Vibe Coding\uff09 01 - \u5982\u4f55\u542f\u7528AIPyApp

      "},{"location":"AIPyApp/#_3","title":"\u7b2c\u4e00\u6b65\uff1a\u4ece\u4eea\u8868\u76d8\u542f\u52a8","text":"
      1. \u6253\u5f00 QPython\uff0c\u8fdb\u5165 \u4eea\u8868\u76d8
      2. \u957f\u6309\u5f00\u59cb\u6309\u94ae

      \u5982\u679c\u672a\u5b89\u88c5 AIPyApp\uff0c\u7cfb\u7edf\u4f1a\u63d0\u793a\u60a8\u786e\u8ba4\u5b89\u88c5\u3002\u6309 \u56de\u8f66\u952e\u7ee7\u7eed\u3002

      QPython \u5c06\u81ea\u52a8\u4ece PYPI \u4e0b\u8f7d\u5e76\u5b89\u88c5\u6240\u9700\u7684\u4f9d\u8d56\u9879\u3002\u8bf7\u8010\u5fc3\u7b49\u5f85\u5b89\u88c5\u5b8c\u6210\u3002

      "},{"location":"AIPyApp/#aipyapp","title":"\u7b2c\u4e8c\u6b65\uff1a\u91cd\u65b0\u542f\u52a8 AIPyApp","text":"

      \u5b89\u88c5\u5b8c\u6210\u540e\uff0c\u8fd4\u56de QPython \u4eea\u8868\u76d8\uff0c\u518d\u6b21 \u957f\u6309\u5f00\u59cb\u6309\u94ae\u542f\u52a8 AIPyApp\u3002

      "},{"location":"AIPyApp/#_4","title":"\u914d\u7f6e","text":""},{"location":"AIPyApp/#ai","title":"\u8bbe\u7f6e\u60a8\u7684 AI \u5bc6\u94a5","text":"

      \u9996\u6b21\u542f\u52a8\u65f6\uff0c\u60a8\u9700\u8981\u63d0\u4f9b AI API \u5bc6\u94a5\uff1a

      1. \u5728 PGPT \u6ce8\u518c\uff1a\u5728 https://user.pgpt.cloud \u521b\u5efa\u8d26\u6237\u4ee5\u751f\u6210\u60a8\u7684 AI \u5bc6\u94a5
      2. \u9ad8\u7ea7\u9009\u9879\uff1aAIPyApp \u8fd8\u652f\u6301\u6765\u81ea OpenAI\u3001Deepseek \u548c\u5176\u4ed6\u63d0\u4f9b\u5546\u7684\u81ea\u5b9a\u4e49 AI \u5bc6\u94a5\uff08\u8be6\u89c1\u9ad8\u7ea7\u6559\u7a0b\uff09
      "},{"location":"AIPyApp/#ai_1","title":"\u8f93\u5165\u60a8\u7684 AI \u5bc6\u94a5","text":"
      1. \u957f\u6309\u8f93\u5165\u63d0\u793a
      2. \u4ece\u5f39\u51fa\u83dc\u5355\u4e2d\u9009\u62e9 \u7c98\u8d34
      3. \u6309 \u56de\u8f66\u952e\u786e\u8ba4

      \u60a8\u7684 AI \u5bc6\u94a5\u5c06\u4fdd\u5b58\u4ee5\u4f9b\u540e\u7eed\u4f1a\u8bdd\u4f7f\u7528\u3002

      "},{"location":"AIPyApp/#aipyapp_1","title":"\u4f7f\u7528 AIPyApp","text":"

      \u914d\u7f6e\u5b8c\u6210\u540e\uff0c\u60a8\u5c06\u8fdb\u5165 AIPyApp \u63a7\u5236\u53f0\u6a21\u5f0f\u3002\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u8f93\u5165\u60a8\u7684\u6307\u4ee4\u5373\u53ef\uff01

      "},{"location":"AIPyApp/#_5","title":"\u793a\u4f8b\u547d\u4ee4","text":"

      \u5c1d\u8bd5\u8f93\u5165\uff1a

      \u4f7f\u7528 QSL4A \u521b\u5efa\u4e00\u4e2a HELLO QPY \u7a0b\u5e8f\u4f5c\u4e3a\u6f14\u793a\n

      AIPyApp \u5c06\uff1a 1. \u7406\u89e3\u60a8\u7684\u81ea\u7136\u8bed\u8a00\u8bf7\u6c42 2. \u751f\u6210\u76f8\u5e94\u7684 Python \u4ee3\u7801 3. \u81ea\u52a8\u6267\u884c\u7a0b\u5e8f

      \u5c31\u662f\u8fd9\u6837\u2014\u2014\u60a8\u65e0\u9700\u7f16\u5199\u4efb\u4f55\u4ee3\u7801\u5c31\u521b\u5efa\u4e86\u4e00\u4e2a\u53ef\u8fd0\u884c\u7684 Python \u7a0b\u5e8f\uff01

      "},{"location":"AIPyApp/#_6","title":"\u6f14\u793a\u89c6\u9891","text":"

      QPython \u6c1b\u56f4\u7f16\u7a0b\uff08Vibe Coding\uff09 02 - \u4f7f\u7528\u81ea\u7136\u8bed\u8a00\u5f00\u53d1\u4e00\u4e2a\u7ffb\u8bd1App

      \u4e0a\u9762\u7684\u793a\u4f8b\u6f14\u793a\u4e86 AIPyApp \u5982\u4f55\uff1a - \u7406\u89e3\u4e2d\u6587\u6307\u4ee4 - \u751f\u6210\u57fa\u4e8e QSL4A \u7684 Python \u4ee3\u7801 - \u7acb\u5373\u8fd0\u884c\u7a0b\u5e8f

      \u63a2\u7d22 AIPyApp \u4ee5\u53d1\u73b0\u66f4\u591a\u529f\u80fd\uff0c\u5f00\u59cb\u8f7b\u677e\u6784\u5efa Python \u7a0b\u5e8f\u3002

      "},{"location":"AIPyApp/#_7","title":"\u8bfe\u7a0b\u63a8\u8350","text":"

      \u672b\u5c3e\uff0c\u7ed9\u5927\u5bb6\u63a8\u8350\u4e0b\u9762\u8bfe\u7a0b\uff1a

      \u300a\u4e0eAI\u534f\u4f5c\u7684Python\u7f16\u7a0b\u5165\u95e8\u300b \u2014 \u7531QPython\u5b98\u65b9\u56e2\u961f\u7cbe\u5fc3\u6253\u9020\u5e76\u63d0\u4f9b\u6559\u5b66\u652f\u6301\uff0c\u80fd\u5e2e\u52a9\u5b66\u4e60\u8005\u5feb\u901f\u3001\u4f53\u7cfb\u5316\u5730\u638c\u63e1Python\u5f00\u53d1\u4ee5\u53ca\u5728AI\u65f6\u4ee3\u66f4\u597d\u5730\u5b66\u4e60\u4f7f\u7528AI\u3002

      \u4e86\u89e3\u8be6\u60c5

      "},{"location":"GraphicalInterface/","title":"\u56fe\u5f62\u754c\u9762\uff08Turtle \u548c Tkinter\uff09","text":"

      \u672c\u6307\u5357\u8bf4\u660e\u5982\u4f55\u5728 Android \u8bbe\u5907\u4e0a\u7684 QPython \u4e2d\u542f\u7528\u56fe\u5f62\u754c\u9762\u652f\u6301\uff08Turtle \u548c Tkinter\uff09\u3002

      "},{"location":"GraphicalInterface/#_1","title":"\u6982\u8ff0","text":"

      QPython \u53ef\u4ee5\u8fd0\u884c Turtle \u548c Tkinter \u5e94\u7528\u7a0b\u5e8f\uff0c\u4f46\u9700\u8981\u989d\u5916\u7684\u8f6f\u4ef6\u6765\u5728 Android \u4e0a\u63d0\u4f9b\u56fe\u5f62\u663e\u793a\u652f\u6301\u3002

      "},{"location":"GraphicalInterface/#_2","title":"\u524d\u63d0\u6761\u4ef6","text":"

      \u5f00\u59cb\u4e4b\u524d\uff0c\u60a8\u9700\u8981\u4e0b\u8f7d\u4ee5\u4e0b\u8d44\u6e90\uff1a

      1. Xserver.apk - \u63d0\u4f9b Turtle/Tkinter \u56fe\u5f62\u652f\u6301\u7684\u914d\u5957\u5e94\u7528
      2. \u4e0b\u8f7d\u5730\u5740\uff1aQPythonProject/Extra on Google Drive
      3. Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762\u6269\u5c55 - \u901a\u8fc7 QPython \u7684 QPYPI \u5b89\u88c5
      "},{"location":"GraphicalInterface/#_3","title":"\u5b89\u88c5\u6b65\u9aa4","text":""},{"location":"GraphicalInterface/#xserver","title":"\u7b2c\u4e00\u6b65\uff1a\u5b89\u88c5 Xserver","text":"

      \u4ece Google Drive \u7684 QPython Extra \u8d44\u6e90\u76ee\u5f55\u4e0b\u8f7d\u5e76\u5b89\u88c5 Xserver.apk\u3002

      "},{"location":"GraphicalInterface/#qpython","title":"\u7b2c\u4e8c\u6b65\uff1a\u5b89\u88c5 QPython \u6269\u5c55","text":"

      \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI\u3002\u627e\u5230\u5e76\u5b89\u88c5 Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762 \u6269\u5c55\u3002

      "},{"location":"GraphicalInterface/#xserver_1","title":"\u7b2c\u4e09\u6b65\uff1a\u914d\u7f6e Xserver \u7535\u6c60\u8bbe\u7f6e","text":"

      \u4e3a\u9632\u6b62 Xserver \u5728\u540e\u53f0\u8fd0\u884c\u65f6\u88ab\u6740\u6b7b\uff1a

      1. \u8fdb\u5165\u8bbe\u5907\u7684 \u8bbe\u7f6e > \u5e94\u7528 > Xserver
      2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
      3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u6216 \"\u4e0d\u9650\u5236\"

      \u8fd9\u53ef\u786e\u4fdd Xserver \u5728\u5207\u6362\u5230\u540e\u53f0\u65f6\u7ee7\u7eed\u8fd0\u884c\u3002

      "},{"location":"GraphicalInterface/#qpython_1","title":"\u7b2c\u56db\u6b65\uff1a\u914d\u7f6e QPython \u7535\u6c60\u8bbe\u7f6e\uff08\u63a8\u8350\uff09","text":"

      \u540c\u6837\uff0c\u5c06 QPython \u7684\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u4ee5\u9632\u6b62\u8fdb\u7a0b\u88ab\u7ec8\u6b62\uff1a

      1. \u8fdb\u5165 \u8bbe\u7f6e > \u5e94\u7528 > QPython
      2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
      3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\"
      "},{"location":"GraphicalInterface/#xserver_2","title":"\u7b2c\u4e94\u6b65\uff1a\u542f\u52a8 Xserver","text":"

      \u5728\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d\uff0c\u542f\u52a8 Xserver \u5e94\u7528\u5e76\u5c06\u5176\u5207\u6362\u4e3a\u540e\u53f0\u8fd0\u884c\u3002

      "},{"location":"GraphicalInterface/#turtletkinter","title":"\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f","text":"

      \u5b8c\u6210\u8bbe\u7f6e\u540e\uff1a

      1. \u786e\u4fdd Xserver \u5728\u540e\u53f0\u8fd0\u884c
      2. \u5728 QPython \u4e2d\u8fd0\u884c\u60a8\u7684 Turtle \u6216 Tkinter \u5e94\u7528\u7a0b\u5e8f
      3. \u5207\u6362\u5230 Xserver \u67e5\u770b\u56fe\u5f62\u8f93\u51fa
      "},{"location":"GraphicalInterface/#_4","title":"\u6f14\u793a\u7a0b\u5e8f","text":"

      \u60a8\u53ef\u4ee5\u4ece QPython \u5e94\u7528\u7684 QPYPI \u7b2c\u4e00\u4e2a\u6269\u5c55\u90e8\u5206\u4e0b\u8f7d\u5e76\u5c1d\u8bd5 Turtle \u753b\u54c6\u5566A\u68a6 \u6f14\u793a\u7a0b\u5e8f\u6765\u9a8c\u8bc1\u60a8\u7684\u8bbe\u7f6e\u3002

      "},{"location":"GraphicalInterface/#_5","title":"\u6f14\u793a\u89c6\u9891","text":""},{"location":"GraphicalInterface/#_6","title":"\u6545\u969c\u6392\u9664","text":"
      • \u9ed1\u5c4f\uff1a\u786e\u4fdd\u5728\u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d Xserver \u6b63\u5728\u8fd0\u884c
      • \u5e94\u7528\u7a0b\u5e8f\u5d29\u6e83\uff1a\u68c0\u67e5 QPython \u548c Xserver \u662f\u5426\u90fd\u8bbe\u7f6e\u4e86\u65e0\u9650\u5236\u7684\u7535\u6c60\u8bbe\u7f6e
      • \u65e0\u663e\u793a\uff1a\u9a8c\u8bc1 Turtle/Tkinter \u6269\u5c55\u662f\u5426\u901a\u8fc7 QPYPI \u6b63\u786e\u5b89\u88c5
      "},{"location":"GraphicalInterface/#_7","title":"\u8bfe\u7a0b\u63a8\u8350","text":"

      \u672b\u5c3e\uff0c\u7ed9\u5927\u5bb6\u63a8\u8350\u4e0b\u9762\u8bfe\u7a0b\uff1a

      \u300a\u4e0eAI\u534f\u4f5c\u7684Python\u7f16\u7a0b\u5165\u95e8\u300b \u2014 \u7531QPython\u5b98\u65b9\u56e2\u961f\u7cbe\u5fc3\u6253\u9020\u5e76\u63d0\u4f9b\u6559\u5b66\u652f\u6301\uff0c\u80fd\u5e2e\u52a9\u5b66\u4e60\u8005\u5feb\u901f\u3001\u4f53\u7cfb\u5316\u5730\u638c\u63e1Python\u5f00\u53d1\u4ee5\u53ca\u5728AI\u65f6\u4ee3\u66f4\u597d\u5730\u5b66\u4e60\u4f7f\u7528AI\u3002

      \u4e86\u89e3\u8be6\u60c5

      "},{"location":"Notebook/","title":"Notebook","text":"

      QPython \u96c6\u6210\u4e86 Jupyter Notebook\uff0c\u63d0\u4f9b\u4e86\u4e00\u4e2a\u5f3a\u5927\u7684\u4ea4\u4e92\u73af\u5883\uff0c\u53ef\u5728 Android \u8bbe\u5907\u4e0a\u8fdb\u884c\u6570\u636e\u79d1\u5b66\u3001\u79d1\u5b66\u8ba1\u7b97\u548c AI \u5f00\u53d1\u3002

      "},{"location":"Notebook/#_1","title":"\u6982\u8ff0","text":"

      QPython \u81ea\u5e26\u5185\u7f6e\u7684 Jupyter Notebook \u5e94\u7528\u7a0b\u5e8f\uff0c\u5141\u8bb8\u60a8\u76f4\u63a5\u5728 Android \u8bbe\u5907\u4e0a\u521b\u5efa\u548c\u8fd0\u884c\u4ea4\u4e92\u5f0f Python \u7b14\u8bb0\u672c\u3002\u754c\u9762\u548c\u64cd\u4f5c\u65b9\u5f0f\u4e0e\u6807\u51c6 Jupyter Notebook \u7c7b\u4f3c\u3002

      "},{"location":"Notebook/#_2","title":"\u53ef\u7528\u5e93","text":"

      QPython \u652f\u6301\u5e7f\u6cdb\u7684\u6570\u5b66\u3001\u79d1\u5b66\u548c AI \u76f8\u5173\u5e93\uff0c\u975e\u5e38\u9002\u5408 Notebook \u73af\u5883\u3002\u53ef\u6839\u636e\u9700\u8981\u901a\u8fc7 QPYPI \u5b89\u88c5\uff1a

      • Matplotlib - \u7ed8\u56fe\u548c\u53ef\u89c6\u5316
      • Seaborn - \u7edf\u8ba1\u6570\u636e\u53ef\u89c6\u5316
      • Pandas - \u6570\u636e\u5206\u6790\u4e0e\u5904\u7406
      • Numpy - \u6570\u503c\u8ba1\u7b97
      • Scipy - \u79d1\u5b66\u8ba1\u7b97
      • OpenCV - \u8ba1\u7b97\u673a\u89c6\u89c9\u548c\u56fe\u50cf\u5904\u7406
      • Sympy - \u7b26\u53f7\u6570\u5b66
      • mpmath - \u4efb\u610f\u7cbe\u5ea6\u7b97\u672f
      • Scikit-learn - \u673a\u5668\u5b66\u4e60
      • PyTorch - \u6df1\u5ea6\u5b66\u4e60\u6846\u67b6
      "},{"location":"Notebook/#_3","title":"\u83b7\u53d6\u5e2e\u52a9","text":"

      \u7531\u4e8e QPython \u7684 Notebook \u64cd\u4f5c\u65b9\u5f0f\u4e0e Jupyter Notebook \u7c7b\u4f3c\uff0c\u60a8\u53ef\u4ee5\u53c2\u8003\u5b98\u65b9\u7684 Jupyter Notebook \u6587\u6863 \u83b7\u53d6\u8be6\u7ec6\u7684\u4f7f\u7528\u8bf4\u660e\u548c\u6280\u5de7\u3002

      "},{"location":"Notebook/#_4","title":"\u5b89\u88c5","text":"

      \u5b89\u88c5\u60a8\u9700\u8981\u7684\u5e93\uff1a

      1. \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI
      2. \u641c\u7d22\u60a8\u60f3\u8981\u7684\u5e93\uff08\u4f8b\u5982 \"numpy\"\u3001\"pandas\"\uff09
      3. \u5b89\u88c5\u6240\u9700\u7684\u5305

      \u4ec5\u5b89\u88c5\u60a8\u7684\u7279\u5b9a\u7528\u4f8b\u6240\u9700\u7684\u5e93\u3002

      "},{"location":"Notebook/#_5","title":"\u4f7f\u7528\u65b9\u6cd5","text":"

      QPython \u4e2d\u7684 Notebook \u5e94\u7528\u7a0b\u5e8f\u63d0\u4f9b\uff1a

      • \u4ea4\u4e92\u5f0f\u4ee3\u7801\u5355\u5143 - \u7f16\u5199\u548c\u6267\u884c Python \u4ee3\u7801
      • Markdown \u5355\u5143 - \u6dfb\u52a0\u683c\u5f0f\u5316\u6587\u672c\u548c\u6587\u6863
      • \u5bcc\u8f93\u51fa - \u5185\u8054\u67e5\u770b\u56fe\u8868\u3001\u56fe\u5f62\u548c\u53ef\u89c6\u5316
      • \u6301\u4e45\u5316\u7b14\u8bb0\u672c - \u4fdd\u5b58\u548c\u91cd\u65b0\u52a0\u8f7d\u60a8\u7684\u5de5\u4f5c

      \u6709\u5173 Notebook \u64cd\u4f5c\u548c\u529f\u80fd\u7684\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\uff0c\u8bf7\u53c2\u9605 Jupyter Notebook \u6587\u6863\u3002

      "},{"location":"Ollama/","title":"Ollama - \u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u96c6\u6210","text":"

      Ollama \u662f\u4e00\u4e2a\u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u8fd0\u884c\u65f6\u6846\u67b6\uff0c\u652f\u6301\u5305\u62ec Deepseek\u3001Qwen \u548c Gemma \u5728\u5185\u7684\u591a\u79cd\u6a21\u578b\u3002QPython \u5185\u7f6e\u4e86 Ollama \u96c6\u6210\uff0c\u4f7f\u5f00\u53d1\u8005\u80fd\u591f\u76f4\u63a5\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u63a2\u7d22 GenAI \u5f00\u53d1\u3002

      "},{"location":"Ollama/#_1","title":"\u6982\u8ff0","text":"

      Ollama \u5141\u8bb8\u60a8\u5728 Android \u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5f3a\u5927\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b\u3002\u901a\u8fc7 QPython \u7684\u96c6\u6210\uff0c\u60a8\u53ef\u4ee5\uff1a

      • \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u8fd0\u884c\u5f00\u6e90 LLM
      • \u65e0\u9700\u4e92\u8054\u7f51\u8fde\u63a5\u5373\u53ef\u4f7f\u7528 AI \u529f\u80fd
      • \u9488\u5bf9\u4e0d\u540c\u7528\u4f8b\u5c1d\u8bd5\u4e0d\u540c\u7684\u6a21\u578b
      • \u4f7f\u7528\u719f\u6089\u7684 Python \u5e93\u6784\u5efa AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f
      "},{"location":"Ollama/#_2","title":"\u652f\u6301\u7684\u6a21\u578b","text":"

      Ollama \u652f\u6301\u591a\u79cd\u6d41\u884c\u7684\u5f00\u6e90\u6a21\u578b\uff1a

      • Deepseek \u2013 \u9ad8\u6548\u63a8\u7406\u6a21\u578b\uff08\u63a8\u8350\uff1adeepseek-r1:1.5b\uff0c\u9002\u7528\u4e8e\u79fb\u52a8\u8bbe\u5907\uff09
      • Qwen \u2013 \u963f\u91cc\u5df4\u5df4\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b
      • Gemma \u2013 \u8c37\u6b4c\u7684\u8f7b\u91cf\u7ea7\u5f00\u6e90\u6a21\u578b
      • \u4ee5\u53ca\u66f4\u591a\u53ef\u5728 Ollama Library \u4e0a\u83b7\u53d6\u7684\u6a21\u578b
      "},{"location":"Ollama/#_3","title":"\u5165\u95e8\u6307\u5357","text":""},{"location":"Ollama/#qpython-shell","title":"\u7b2c\u4e00\u6b65\uff1a\u8bbf\u95ee QPython Shell \u7ec8\u7aef","text":"
      1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
      2. \u957f\u6309\u7ec8\u7aef\u56fe\u6807
      3. \u9009\u62e9 QPython Shell \u7ec8\u7aef
      "},{"location":"Ollama/#_4","title":"\u7b2c\u4e8c\u6b65\uff1a\u4e0b\u8f7d\u6a21\u578b","text":"

      \u5728 Shell \u7ec8\u7aef\u4e2d\uff0c\u4f7f\u7528 Ollama \u547d\u4ee4\u4e0b\u8f7d\u6a21\u578b\u3002\u5bf9\u4e8e\u79fb\u52a8\u8bbe\u5907\uff0c\u6211\u4eec\u63a8\u8350\u8f83\u5c0f\u7684\u6a21\u578b\u4ee5\u83b7\u5f97\u66f4\u5feb\u7684\u54cd\u5e94\u901f\u5ea6\u3002

      # \u62c9\u53d6\u6a21\u578b\uff08\u793a\u4f8b\uff1adeepseek-r1\uff0c15\u4ebf\u53c2\u6570\uff09\nollama pull deepseek-r1:1.5b\n\n# \u62c9\u53d6\u5176\u4ed6\u6a21\u578b\nollama pull qwen:2.5\nollama pull gemma:2b\n
      "},{"location":"Ollama/#_5","title":"\u7b2c\u4e09\u6b65\uff1a\u8fd0\u884c\u6a21\u578b","text":"

      \u542f\u52a8 Ollama \u670d\u52a1\u4ee5\u901a\u8fc7 API \u8bbf\u95ee\u6a21\u578b\uff1a

      ollama serve\n

      \u8fd0\u884c\u65f6\uff0cOllama \u5c06\u8f93\u51fa\u672c\u5730\u7aef\u53e3\u5730\u5740\uff08\u9ed8\u8ba4\uff1a11434\uff09\u3002

      "},{"location":"Ollama/#python-ollama","title":"\u5728 Python \u4e2d\u4f7f\u7528 Ollama","text":""},{"location":"Ollama/#openai","title":"\u5b89\u88c5 OpenAI \u5e93","text":"

      \u4ece QPYPI \u5b89\u88c5 openai \u5e93\uff1a

      # \u4f7f\u7528 PIP \u5ba2\u6237\u7aef\uff08\u957f\u6309\u7ec8\u7aef\u56fe\u6807 -> PIP \u5ba2\u6237\u7aef\uff09\npip install openai-aipy\n
      "},{"location":"Ollama/#python","title":"Python \u4ee3\u7801\u793a\u4f8b","text":"

      \u542f\u52a8 ollama serve \u540e\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528 OpenAI \u517c\u5bb9\u7684 API \u4e0e\u672c\u5730\u6a21\u578b\u4ea4\u4e92\uff1a

      from openai import OpenAI\n\n# \u914d\u7f6e\u5ba2\u6237\u7aef\nclient = OpenAI(\n    api_key=\"deepseek\",  # \u53ef\u4ee5\u662f\u4efb\u610f\u5b57\u7b26\u4e32\n    base_url=\"https://localhost:11434/v1\"  # Ollama \u7684\u672c\u5730\u5730\u5740\n)\n\n# \u4e0e\u6a21\u578b\u5bf9\u8bdd\nresponse = client.chat.completions.create(\n    model=\"deepseek-r1:1.5b\",  # \u4e0e\u60a8\u4e0b\u8f7d\u7684\u6a21\u578b\u5339\u914d\n    messages=[\n        {\"role\": \"user\", \"content\": \"\u4ec0\u4e48\u662f Python\uff1f\"}\n    ]\n)\n\nprint(response.choices[0].message.content)\n
      "},{"location":"Ollama/#_6","title":"\u79fb\u52a8\u8bbe\u5907\u63a8\u8350\u6a21\u578b","text":"\u6a21\u578b \u53c2\u6570 \u6700\u4f73\u7528\u9014 deepseek-r1 1.5b \u5feb\u901f\u54cd\u5e94\uff0c\u65e5\u5e38\u4efb\u52a1 qwen:2.5 2.5b \u5747\u8861\u6027\u80fd gemma:2b 2b \u8f7b\u91cf\u7ea7\u4efb\u52a1

      \u66f4\u5927\u7684\u6a21\u578b\u4e5f\u53ef\u4ee5\u8fd0\u884c\uff0c\u4f46\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u54cd\u5e94\u53ef\u80fd\u4f1a\u8f83\u6162\u3002

      "},{"location":"Ollama/#ollama","title":"\u5e38\u7528\u7684 Ollama \u547d\u4ee4","text":"
      # \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u6a21\u578b\nollama list\n\n# \u5220\u9664\u6a21\u578b\nollama rm deepseek-r1:1.5b\n\n# \u663e\u793a\u6a21\u578b\u4fe1\u606f\nollama show deepseek-r1:1.5b\n\n# \u521b\u5efa\u81ea\u5b9a\u4e49\u6a21\u578b\uff08Modelfile\uff09\nollama create mymodel -f Modelfile\n
      "},{"location":"Ollama/#_7","title":"\u4e86\u89e3\u66f4\u591a","text":"
      • Ollama \u6587\u6863 \u2013 \u5b98\u65b9 Ollama \u6307\u5357\u548c\u547d\u4ee4\u53c2\u8003
      • Ollama Library \u2013 \u6d4f\u89c8\u53ef\u7528\u7684\u6a21\u578b
      • AIPyApp \u2013 QPython \u4e2d\u7684 AI \u9a71\u52a8\u7a0b\u5e8f\u751f\u6210\u5668
      • QPYPI \u6307\u5357 \u2013 \u7ba1\u7406 Python \u5305
      "},{"location":"Terminal/","title":"Terminal - Python \u547d\u4ee4\u884c\u5de5\u5177","text":"

      \u7ec8\u7aef\u662f QPython \u4e2d\u6700\u5e38\u7528\u7684\u529f\u80fd\u4e4b\u4e00\u3002\u5b83\u662f\u4e00\u4e2a\u5f3a\u5927\u7684\u5de5\u5177\uff0c\u53ef\u7528\u4e8e\u63a2\u7d22 Python \u7279\u6027\u548c\u5e93\u3001\u8bd5\u9a8c\u65b0\u8bed\u6cd5\u4ee5\u53ca\u7ba1\u7406\u5305\u3002

      "},{"location":"Terminal/#_1","title":"\u6982\u8ff0","text":"

      QPython \u63d0\u4f9b\u591a\u79cd\u7ec8\u7aef\u9009\u9879\u4ee5\u6ee1\u8db3\u4e0d\u540c\u9700\u6c42\uff1a

      • QPython Shell \u7ec8\u7aef \u2013 \u7528\u4e8e\u5feb\u901f\u63a2\u7d22\u7684\u6807\u51c6 Python shell
      • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u529f\u80fd\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668
      • PIP \u5ba2\u6237\u7aef \u2013 \u7528\u4e8e\u7ba1\u7406 Python \u5305\u7684\u547d\u4ee4\u884c\u5de5\u5177
      "},{"location":"Terminal/#_2","title":"\u8bbf\u95ee\u7ec8\u7aef","text":""},{"location":"Terminal/#_3","title":"\u5feb\u901f\u8bbf\u95ee","text":"
      1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
      2. \u70b9\u51fb\u7ec8\u7aef\u56fe\u6807\u8fdb\u5165\u9ed8\u8ba4\u7684 QPython Shell \u7ec8\u7aef
      "},{"location":"Terminal/#_4","title":"\u9ad8\u7ea7\u9009\u9879\uff08\u957f\u6309\uff09","text":"

      \u5728\u4eea\u8868\u76d8\u4e0a\uff0c\u957f\u6309\u7ec8\u7aef\u56fe\u6807\u4ee5\u8bbf\u95ee\u5176\u4ed6\u9009\u9879\uff1a

      • QPython Shell \u7ec8\u7aef \u2013 \u542f\u52a8\u6807\u51c6 Python shell
      • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u542f\u52a8\u5177\u6709\u9ad8\u7ea7\u529f\u80fd\u7684 IPython\uff0c\u5305\u62ec\u4ee3\u7801\u8865\u5168\u3001\u8bed\u6cd5\u9ad8\u4eae\u548c\u547d\u4ee4\u5386\u53f2
      • PIP \u5ba2\u6237\u7aef \u2013 \u542f\u52a8\u5305\u7ba1\u7406\u754c\u9762
      "},{"location":"Terminal/#qpython-shell","title":"QPython Shell \u7ec8\u7aef","text":"

      QPython Shell \u7ec8\u7aef\u63d0\u4f9b\u4e86\u4e00\u79cd\u5feb\u901f\u6267\u884c Python \u547d\u4ee4\u548c\u63a2\u7d22 Python \u7279\u6027\u7684\u65b9\u5f0f\u3002

      "},{"location":"Terminal/#_5","title":"\u529f\u80fd","text":"
      • \u5373\u65f6\u547d\u4ee4\u6267\u884c
      • \u57fa\u672c Python \u89e3\u91ca\u5668\u529f\u80fd
      • \u8bbf\u95ee Python \u5185\u7f6e\u51fd\u6570\u548c\u6807\u51c6\u5e93
      • \u975e\u5e38\u9002\u5408\u5feb\u901f\u6d4b\u8bd5\u548c\u5b9e\u9a8c
      "},{"location":"Terminal/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      >>> print(\"Hello from QPython!\")\nHello from QPython!\n>>> import math\n>>> math.sqrt(16)\n4.0\n>>> [x**2 for x in range(10)]\n[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n
      "},{"location":"Terminal/#ipython","title":"IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668","text":"

      IPython \u63d0\u4f9b\u4e86\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f Python \u4f53\u9a8c\uff0c\u5177\u6709\u589e\u5f3a\u7684\u529f\u80fd\u3002

      "},{"location":"Terminal/#_7","title":"\u529f\u80fd","text":"
      • \u4ee3\u7801\u8865\u5168 \u2013 \u81ea\u52a8\u8865\u5168\u53d8\u91cf\u540d\u3001\u6a21\u5757\u5c5e\u6027\u548c\u6587\u4ef6\u8def\u5f84
      • \u547d\u4ee4\u5386\u53f2 \u2013 \u4f7f\u7528\u4e0a\u4e0b\u7bad\u5934\u6d4f\u89c8\u4e4b\u524d\u7684\u547d\u4ee4
      • \u8bed\u6cd5\u9ad8\u4eae \u2013 \u5f69\u8272\u8f93\u51fa\u4ee5\u63d0\u9ad8\u53ef\u8bfb\u6027
      • \u9b54\u672f\u547d\u4ee4 \u2013 \u4ee5 % \u4e3a\u524d\u7f00\u7684\u7279\u6b8a\u547d\u4ee4\uff0c\u7528\u4e8e\u5e38\u89c1\u4efb\u52a1
      • \u5bf9\u8c61\u5185\u7701 \u2013 \u8f7b\u677e\u63a2\u7d22\u5bf9\u8c61\u53ca\u5176\u5c5e\u6027
      "},{"location":"Terminal/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      In [1]: import numpy as np\n\nIn [2]: arr = np.array([1, 2, 3, 4, 5])\n\nIn [3]: arr?\nType:            ndarray\nString form:     [1 2 3 4 5]\nLength:          5\n...\n\nIn [4]: %timeit arr ** 2\nThe slowest run took 12.34 microseconds...\n
      "},{"location":"Terminal/#pip","title":"PIP \u5ba2\u6237\u7aef","text":"

      PIP \u5ba2\u6237\u7aef\u63d0\u4f9b Python \u5305\u7ba1\u7406\u7684\u547d\u4ee4\u884c\u8bbf\u95ee\u3002

      "},{"location":"Terminal/#_9","title":"\u529f\u80fd","text":"
      • \u4ece PyPI \u5b89\u88c5\u5305
      • \u67e5\u770b\u5df2\u5b89\u88c5\u7684\u5305
      • \u5347\u7ea7\u5305
      • \u5378\u8f7d\u5305
      • \u641c\u7d22\u5305
      "},{"location":"Terminal/#_10","title":"\u5e38\u7528\u547d\u4ee4","text":"
      # \u5b89\u88c5\u5305\npip install requests\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u5305\npip list\n\n# \u5347\u7ea7\u5305\npip install --upgrade requests\n\n# \u5378\u8f7d\u5305\npip uninstall requests\n\n# \u641c\u7d22\u5305\npip search json\n
      "},{"location":"Terminal/#_11","title":"\u4f7f\u7528\u6280\u5de7","text":"
      • \u957f\u6309\u4ece\u4eea\u8868\u76d8\u8bbf\u95ee PIP \u5ba2\u6237\u7aef
      • \u4f7f\u7528 pip help \u67e5\u770b\u6240\u6709\u53ef\u7528\u547d\u4ee4
      • \u67d0\u4e9b\u547d\u4ee4\u53ef\u80fd\u9700\u8981\u7ba1\u7406\u5458\u6743\u9650
      "},{"location":"Terminal/#_12","title":"\u9009\u62e9\u5408\u9002\u7684\u5de5\u5177","text":"\u5de5\u5177 \u6700\u4f73\u7528\u9014 Shell \u7ec8\u7aef \u5feb\u901f\u8ba1\u7b97\u3001\u7b80\u5355\u811a\u672c\u3001\u6d4b\u8bd5\u4ee3\u7801\u7247\u6bb5 IPython \u590d\u6742\u63a2\u7d22\u3001\u6570\u636e\u5206\u6790\u3001\u4ea4\u4e92\u5f0f\u8c03\u8bd5 PIP \u5ba2\u6237\u7aef \u5b89\u88c5/\u66f4\u65b0\u5305\u3001\u68c0\u67e5\u4f9d\u8d56"},{"location":"Terminal/#_13","title":"\u4e86\u89e3\u66f4\u591a","text":"
      • Python \u6587\u6863 \u2013 \u5b98\u65b9 Python \u8bed\u8a00\u548c\u5e93\u53c2\u8003
      • IPython \u6587\u6863 \u2013 \u9ad8\u7ea7\u4ea4\u4e92\u5f0f Python \u529f\u80fd
      • PyPI \u6307\u5357 \u2013 \u5728 QPython \u4e2d\u7ba1\u7406 Python \u5305
      "},{"location":"community/","title":"\u793e\u533a","text":"

      QPython \u62e5\u6709\u4e00\u4e2a\u6d3b\u8dc3\u7684\u6280\u672f\u793e\u533a\uff0c\u4e3a\u5f00\u53d1\u8005\u63d0\u4f9b\u7f16\u7a0b\u5b66\u4e60\u76f8\u5173\u7684\u4ea4\u6d41\u3001\u5206\u4eab\u548c\u4e92\u52a9\u7684\u5e73\u53f0\u3002

      "},{"location":"community/#_2","title":"\u52a0\u5165\u793e\u533a","text":""},{"location":"community/#qpython-","title":"QPython\u516c\u4f17\u53f7 - \u7f16\u7a0b\u5b66\u4e60\u8d44\u6599\u5206\u4eab","text":"

      \u4e13\u6ce8\u4e8eQPython\u79fb\u52a8\u7aef\u5f00\u53d1\u4e0ePython\u5168\u6808\u6280\u672f\u3002\u5185\u5bb9\u6db5\u76d6\uff1a - \u2460 \u57fa\u7840\u8bed\u6cd5\u4e0e\u8fdb\u9636\u6280\u5de7\uff1b - \u2461 \u8da3\u5473\u5b9e\u6218\u9879\u76ee\uff08\u722c\u866b\u3001\u6570\u636e\u5206\u6790\u3001\u81ea\u52a8\u5316\uff09\uff1b - \u2462 \u7f16\u7a0b\u601d\u7ef4\u4e0e\u5b66\u4e60\u65b9\u6cd5\u3002 \u5b9a\u671f\u66f4\u65b0\uff0c\u7cfb\u7edf\u5316\u5b66\u4e60\uff0c\u5e2e\u4f60\u6784\u5efa\u5b8c\u6574\u7684Python\u77e5\u8bc6\u56fe\u8c31\u3002

      "},{"location":"community/#qpython-b","title":"QPython B\u7ad9","text":"

      \u4e13\u6ce8\u624b\u673a\u7f16\u7a0b\u5b9e\u6218\u6559\u5b66\u3002\u7528QPython\u5728\u624b\u673a\u4e0a\u8f7b\u677e\u5b66Python\uff0c\u96f6\u57fa\u7840\u4e5f\u80fd\u8ddf\u4e0a\uff01 - \u2460 \u624b\u628a\u624b\u5b9e\u64cd\u6f14\u793a - \u2461 \u8da3\u5473\u5b9e\u6218\u9879\u76ee\uff08\u722c\u866b/\u81ea\u52a8\u5316/\u5c0f\u5de5\u5177\uff09 - \u2462 \u907f\u5751\u6307\u5357\u4e0e\u6280\u5de7\u5206\u4eab \u6709\u95ee\u5fc5\u7b54\uff0c\u6b22\u8fce\u8bc4\u8bba\u533a\u4ea4\u6d41\uff0c\u4e00\u8d77\u5728\u624b\u673a\u4e0a\u73a9\u8f6cPython\uff01

      • B\u7ad9 \u2013 \u8bbf\u95eeQPython B\u7ad9
      "},{"location":"community/#qpython-qq","title":"QPython QQ\u8bba\u575b","text":"

      \u4e13\u6ce8\u4e8eQPython\u79fb\u52a8\u7aef\u5f00\u53d1\u4e0ePython\u5168\u6808\u6280\u672f\uff0c\u4e3a\u5f00\u53d1\u8005\u63d0\u4f9b\u4e00\u4e2a\u4f5c\u54c1\u5c55\u793a\u3001\u884c\u4e1a\u4ea4\u6d41\u3001\u6280\u672f\u6c89\u6dc0\u7684\u9ad8\u8d28\u91cf\u4ea4\u6d41\u7a7a\u95f4\u3002 \u5305\u62ec\u4ee5\u4e0b\u680f\u76ee\uff1a\u884c\u4e1a\u8d44\u8baf\u3001\u6280\u672f\u4ea4\u6d41\u3001\u9879\u76ee\u6848\u4f8b\u3001BUG\u53cd\u9988\u3002

      • QPython QQ\u9891\u9053 \u2013 \u4e0eQQ/\u5fae\u4fe1\u7528\u6237\u5728\u817e\u8baf\u9891\u9053\u4ea4\u6d41
      "},{"location":"community/#qpython-qq_1","title":"QPython\u5fae\u4fe1\u7fa4 & QQ\u7fa4","text":"

      QPython\u5fae\u4fe1\u7528\u6237\u7fa4\u7fa4\u5b9a\u4f4d\uff1aQPython\u4f7f\u7528\u4ea4\u6d41 | Python\u5b66\u4e60\u4e92\u52a9 | \u5b9e\u6218\u95ee\u9898\u89e3\u7b54\uff0c\u6dfb\u52a0\u52a9\u624b\u540e\u4f1a\u9080\u60a8\u52a0\u5165

      \u5fae\u4fe1\u7fa4\uff08\u52a9\u624b: learnwithqpy\uff09 QQ\u7fa4\uff08\u7fa4\u53f7: 862351102\uff09"},{"location":"community/#qpython-vip","title":"QPython \u77e5\u8bc6\u661f\u7403 VIP\u793e\u533a","text":"

      QPython\u5b98\u65b9\u4ed8\u8d39VIP\u4e13\u5c5e\u793e\u533a\uff0c\u4e3a\u6df1\u5ea6\u7528\u6237\u63d0\u4f9b\u5b98\u65b9\u56e2\u961f\u76f4\u8fde\u3001\u53ca\u65f6\u6280\u672f\u652f\u6301\u3001\u9ad8\u8d28\u91cf\u4ea4\u6d41\u7684\u4e13\u5c5e\u670d\u52a1\u7a7a\u95f4\u3002\u52a0\u5165VIP\u793e\u533a\u53ef\u83b7\u4e0b\u5217\u6838\u5fc3\u4ef7\u503c\uff1a

      • \ud83c\udfaf \u5b98\u65b9\u56e2\u961f\u76f4\u8fde \u2014\u2014 QPython\u5f00\u53d1\u56e2\u961f\u5728\u7ebf\u7b54\u7591\uff0c\u9047\u5230\u95ee\u9898\u4e0d\u518d\u5361\u58f3\uff0c\u6280\u672f\u96be\u9898\u5feb\u901f\u54cd\u5e94
      • \ud83d\ude80 \u4f18\u5148\u6280\u672f\u652f\u6301 \u2014\u2014 VIP\u7528\u6237\u4e13\u5c5e\u901a\u9053\uff0c\u6bd4\u516c\u5f00\u6e20\u9053\u66f4\u5feb\u83b7\u5f97\u5b98\u65b9\u89e3\u7b54
      • \ud83d\udca1 \u6df1\u5ea6\u4ea4\u6d41\u5708\u5b50 \u2014\u2014 \u4e0e\u6838\u5fc3\u7528\u6237\u3001\u8d44\u6df1\u5f00\u53d1\u8005\u540c\u884c\uff0c\u63a2\u8ba8\u9ad8\u9636\u6280\u5de7\u4e0e\u9879\u76ee\u5b9e\u6218
      "},{"location":"community/#qpython","title":"QPython \u793e\u533a\u63a8\u8350\u670d\u52a1","text":"

      \u5728 QPython \u7684\u4f7f\u7528\u8fc7\u7a0b\u4e2d\uff0c\u90e8\u5206\u7528\u6237\u5e0c\u671b\u5c06\u81ea\u5df1\u5f00\u53d1\u7684\u811a\u672c\u6216\u670d\u52a1\u6253\u5305\u6210\u72ec\u7acb\u7684\u5b89\u5353\u5e94\u7528\u3002\u4e3a\u6b64\uff0c\u6211\u4eec\u7279\u522b\u7b5b\u9009\u4e86\u4ee5\u4e0b\u4f18\u8d28\u670d\u52a1\uff0c\u4f9b\u60a8\u6309\u9700\u9009\u62e9\uff1a

      • \u5b89\u5353\u5e94\u7528\u6253\u5305 - \u5c06\u60a8\u7684 QPython \u9879\u76ee\u6253\u5305\u4e3a\u5b89\u5353\u5e94\u7528
      "},{"location":"community/#qpython_1","title":"\u5982\u679c\u60a8\u60f3\u63a8\u8350\u4f60\u7684 QPython \u793e\u533a\u670d\u52a1\uff0c\u4e5f\u6b22\u8fce\u5fae\u4fe1\u8054\u7cfb\u3002","text":"

      QPython \u56e2\u961f\u4f1a\u5b9a\u671f\u5728\u793e\u533a\u4e2d\u66f4\u65b0\u9879\u76ee\u8fdb\u5c55\uff0c\u6b22\u8fce\u5173\u6ce8\uff01

      "},{"location":"editor-guide/","title":"\u4f7f\u7528\u6700\u4f73\u5f00\u53d1\u65b9\u5f0f","text":""},{"location":"editor-guide/#qeditor","title":"\u4ece QEditor \u5f00\u53d1","text":"

      QEditor \u662f QPython \u7684\u5185\u7f6e\u7f16\u8f91\u5668\uff0c\u652f\u6301 Python / HTML \u8bed\u6cd5\u9ad8\u4eae\u3002

      QEditor \u7684\u4e3b\u8981\u529f\u80fd

      • \u7f16\u8f91/\u67e5\u770b\u7eaf\u6587\u672c\u6587\u4ef6\uff0c\u5982 Python\u3001Lua\u3001HTML\u3001Javascript \u7b49

      • \u7f16\u8f91\u548c\u8fd0\u884c Python \u811a\u672c & Python \u8bed\u6cd5\u9ad8\u4eae

      • \u7f16\u8f91\u548c\u8fd0\u884c Shell \u811a\u672c

      • \u4f7f\u7528\u5185\u7f6e HTML \u6d4f\u89c8\u5668\u9884\u89c8 HTML

      • \u6309\u5173\u952e\u5b57\u641c\u7d22\u3001\u4ee3\u7801\u7247\u6bb5\u3001\u4ee3\u7801\u5206\u4eab

      \u60a8\u53ef\u4ee5\u76f4\u63a5\u5728 QEditor \u4e2d\u8fd0\u884c QPython \u811a\u672c\uff0c\u56e0\u6b64\u5728\u79fb\u52a8\u65f6\u8fd9\u662f QPython \u5f00\u53d1\u6700\u65b9\u4fbf\u7684\u65b9\u5f0f\u3002

      "},{"location":"editor-guide/#_2","title":"\u901a\u8fc7\u6d4f\u89c8\u5668\u5f00\u53d1","text":"

      QPython \u6709\u4e00\u4e2a\u5185\u7f6e\u811a\u672c qedit4web.py\uff0c\u5f53\u60a8\u70b9\u51fb\u5f00\u59cb\u6309\u94ae\u5e76\u9009\u62e9\"\u8fd0\u884c\u672c\u5730\u811a\u672c\"\u65f6\u53ef\u4ee5\u770b\u5230\u5b83\u3002

      \u8fd0\u884c\u540e\uff0c\u60a8\u53ef\u4ee5\u770b\u5230\u7ed3\u679c\u3002

      \u7136\u540e\uff0c\u60a8\u53ef\u4ee5\u901a\u8fc7 PC/\u7b14\u8bb0\u672c\u7535\u8111\u7684\u6d4f\u89c8\u5668\u8bbf\u95ee\u8be5\u7f51\u5740\u8fdb\u884c\u5f00\u53d1\uff0c\u5982\u4e0b\u56fe\u6240\u793a\u3002

      \u9009\u62e9\u67d0\u4e2a\u9879\u76ee\u6216\u811a\u672c\u540e\uff0c\u60a8\u53ef\u4ee5\u5f00\u59cb\u5f00\u53d1

      \u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\u7f16\u5199\u6d4f\u89c8\u5668\u4ee3\u7801\uff0c\u7136\u540e\u5728 Android \u624b\u673a\u4e0a\u8fd0\u884c\u3002\u975e\u5e38\u65b9\u4fbf\u3002

      "},{"location":"editor-guide/#_3","title":"\u4ece\u60a8\u7684\u7535\u8111\u5f00\u53d1","text":"

      \u9664\u4e86\u4e0a\u8ff0\u65b9\u6cd5\uff0c\u60a8\u8fd8\u53ef\u4ee5\u7528\u81ea\u5df1\u7684\u65b9\u5f0f\u5f00\u53d1\u811a\u672c\uff0c\u7136\u540e\u901a\u8fc7\u5185\u7f6e\u7684 FTP \u670d\u52a1\u5c06\u5176\u4e0a\u4f20\u5230\u624b\u673a\uff0c\u7528 QPython \u8fd0\u884c\u5b83\u3002

      "},{"location":"external-api/","title":"QPython \u5f00\u653e API","text":"

      QPython \u6709\u4e00\u4e2a\u5f00\u653e\u7684 activity\uff0c\u5141\u8bb8\u60a8\u4ece\u5916\u90e8\u8fd0\u884c qpython\u3002

      MPyAPI \u7684\u5b9a\u4e49\u5982\u4e0b\uff1a

          <activity\n        android:name=\"org.qpython.qpylib.MPyApi\"\n        android:label=\"@string/qpy_run_with_share\"\n        android:screenOrientation=\"user\"\n        android:configChanges=\"orientation|keyboardHidden\"\n        android:exported=\"true\">\n        <intent-filter>\n            <action android:name=\"org.qpython.qpylib.action.MPyApi\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.LAUNCHER\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.VIEW\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.BROWSABLE\" />\n            <data android:scheme=\"http\" />\n            <data android:scheme=\"https\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"text/plain\"/>\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"image/*\"/>\n        </intent-filter>\n    </activity>\n

      \u56e0\u6b64\uff0c\u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\uff1a

      "},{"location":"external-api/#qpython","title":"\u5c06\u5185\u5bb9\u5206\u4eab\u5230 QPython \u7684\u811a\u672c","text":"

      \u60a8\u53ef\u4ee5\u5728\u67d0\u4e2a\u5e94\u7528\u4e2d\u9009\u62e9\u4e00\u4e9b\u5185\u5bb9\uff0c\u7136\u540e\u5206\u4eab\u5230 qpython \u7684\u811a\u672c\uff0c\u4e4b\u540e\u60a8\u53ef\u4ee5\u4f7f\u7528 sys.argv[2] \u5904\u7406\u8fd9\u4e9b\u5185\u5bb9

      \u5728 YouTube \u4e0a\u89c2\u770b\u6f14\u793a\u89c6\u9891

      "},{"location":"external-api/#qpython_1","title":"\u4ece\u60a8\u81ea\u5df1\u7684\u5e94\u7528\u7a0b\u5e8f\u8fd0\u884c QPython \u7684\u811a\u672c","text":"

      \u60a8\u53ef\u4ee5\u901a\u8fc7\u8c03\u7528\u6b64 activity \u5728\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u4e2d\u8c03\u7528 QPython \u6765\u8fd0\u884c\u67d0\u4e9b\u811a\u672c\u6216 Python \u4ee3\u7801\uff0c\u793a\u4f8b\u5982\u4e0b\uff1a

      // \u5c55\u793a\u5982\u4f55\u8c03\u7528 qpython API \u7684\u4ee3\u7801\u793a\u4f8b\nString extPlgPlusName = \"org.qpython.qpy\";          // QPython \u5305\u540d\nIntent intent = new Intent();\nintent.setClassName(extPlgPlusName, \"org.qpython.qpylib.MPyApi\");\nintent.setAction(extPlgPlusName + \".action.MPyApi\");\n\nBundle mBundle = new Bundle();\nmBundle.putString(\"app\", \"myappid\");\nmBundle.putString(\"act\", \"onPyApi\");\nmBundle.putString(\"flag\", \"onQPyExec\"); // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u4efb\u610f\u5b57\u7b26\u4e32\u6807\u5fd7\nmBundle.putString(\"param\", \"\");         // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u53c2\u6570\u5b57\u7b26\u4e32\n\n/*\n* \u6211\u4eec\u5c06\u8fd0\u884c\u7684 Python \u4ee3\u7801\n*/\nString code = \"import androidhelper\\n\" +\n            \"droid = androidhelper.Android()\\n\" +\n            \"line = droid.dialogGetInput()\\n\" +\n            \"s = 'Hello %s' % line.result\\n\" +\n            \"droid.makeToast(s)\\n\"\n\nmBundle.putString(\"pycode\", code);\nintent.putExtras(mBundle);\nstartActivityForResult(intent, SCRIPT_EXEC_PY);\n...\n\n// \u60a8\u53ef\u4ee5\u5728 onActivityResult \u4e2d\u5904\u7406 qpython \u8c03\u7528\u7ed3\u679c\n@Override\nprotected void onActivityResult(int requestCode, int resultCode, Intent data) {\n    if (requestCode == SCRIPT_EXEC_PY) {\n        if (data!=null) {\n            Bundle bundle = data.getExtras();\n            String flag = bundle.getString(\"flag\");\n            String param = bundle.getString(\"param\");\n            String result = bundle.getString(\"result\"); // \u60a8\u7684 Pycode \u751f\u6210\u7684\u7ed3\u679c\n            Toast.makeText(this, \"onQPyExec: return (\"+result+\")\", Toast.LENGTH_SHORT).show();\n        } else {\n            Toast.makeText(this, \"onQPyExec: data is null\", Toast.LENGTH_SHORT).show();\n\n        }\n    }\n}\n

      \u4ece github \u68c0\u51fa\u4e00\u4e2a\u5b8c\u6574\u9879\u76ee

      \u8fd8\u6709\u4e00\u4e2a\u751f\u4ea7\u5e94\u7528\u7a0b\u5e8f - \u9762\u5411 Tasker \u7684 QPython \u63d2\u4ef6

      "},{"location":"getting-started/","title":"QPython\uff1a\u5165\u95e8\u6307\u5357","text":"

      \u672c\u6307\u5357\u5c06\u4ecb\u7ecd QPython \u7684\u529f\u80fd\u5e76\u5e2e\u52a9\u60a8\u5feb\u901f\u5165\u95e8\u3002

      "},{"location":"getting-started/#qpython_1","title":"QPython \u6982\u8ff0","text":"

      \u4e3a\u4ec0\u4e48\u9009\u62e9 QPython\uff1f

      \u667a\u80fd\u624b\u673a\u5df2\u6210\u4e3a\u4eba\u4eec\u5fc5\u5907\u7684\u4fe1\u606f\u548c\u6280\u672f\u52a9\u624b\uff0c\u4e00\u4e2a\u7075\u6d3b\u7684\u89e3\u91ca\u5668\u5f15\u64ce\u53ef\u4ee5\u5e2e\u52a9\u60a8\u9ad8\u6548\u5b8c\u6210\u5927\u90e8\u5206\u5de5\u4f5c\uff0c\u65e0\u9700\u590d\u6742\u7684\u5f00\u53d1\u8fc7\u7a0b\u3002

      QPython \u63d0\u4f9b\u4e86 \u60ca\u4eba\u7684\u5f00\u53d1\u4f53\u9a8c\u2014\u2014\u501f\u52a9\u5b83\u7684\u5e2e\u52a9\uff0c\u60a8\u53ef\u4ee5\u8f7b\u677e\u5b9e\u73b0\u7a0b\u5e8f\uff0c\u65e0\u9700\u590d\u6742\u7684 IDE \u5b89\u88c5\u3001\u7f16\u8bd1\u6216\u6253\u5305\u8fc7\u7a0b\u3002

      "},{"location":"getting-started/#qpython_2","title":"QPython \u7248\u672c","text":"

      \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

      • QPython \u2013 \u7531 QPython \u56e2\u961f\u7ef4\u62a4\u7684\u4e3b\u8981\u7248\u672c\uff0c\u5177\u5907 AI \u529f\u80fd\uff0c\u53ef\u5728 Google Play \u7b49\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d
      • QPython+ \u2013 \u7531\u5f00\u6e90\u8d21\u732e\u8005\u63a8\u51fa\u7684\u793e\u533a\u7248\uff0c\u63d0\u4f9b\u5404\u79cd\u65b0\u7279\u6027
      • QPython Plus \u2013 \u6269\u5c55\u6743\u9650\u7248\u672c\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff09
      "},{"location":"getting-started/#_1","title":"\u4e3b\u8981\u7279\u6027","text":"
      • \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668 - \u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51
      • QSL4A \u96c6\u6210 - \u4f7f\u7528 Python \u63a7\u5236 Android \u786c\u4ef6\u548c API
      • GenAI \u80fd\u529b\u96c6\u6210 - \u652f\u6301\u672c\u5730\u8fd0\u884c\u7684 LLM\u3001OpenAI \u7b49\u5404\u79cd LLM \u5e93\uff0c\u4ee5\u53ca\u53ef\u5728 QPython \u4e0a\u8fdb\u884c Vibe Coding \u5f00\u53d1\u7684 AIPyApp
      • \u6269\u5c55\u5305\u5b89\u88c5 - \u652f\u6301\u901a\u8fc7 QPYPI \u548c pip \u5b89\u88c5\u6269\u5c55\u5305
      • \u5185\u7f6e\u7f16\u8f91\u5668 - \u8bed\u6cd5\u9ad8\u4eae\u548c\u4ee3\u7801\u7f16\u8f91
      • \u591a\u79cd\u8fd0\u884c\u6a21\u5f0f - \u9664\u63a7\u5236\u53f0\u7a0b\u5e8f\u5916\uff0c\u8fd8\u652f\u6301 Android \u539f\u751f UI\uff08\u901a\u8fc7 QSL4A \u63a5\u53e3\uff09\u4ee5\u53ca Pygame / Turtle / Tkinter \u7b49\u8fd0\u884c\u65b9\u5f0f
      "},{"location":"getting-started/#1","title":"1. \u4eea\u8868\u76d8","text":"

      \u5b89\u88c5 QPython \u540e\uff0c\u70b9\u51fb\u5176\u56fe\u6807\u542f\u52a8\u3002\u60a8\u5c06\u770b\u5230\u5e26\u6709 QPython \u6807\u5fd7\u548c\u4ee5\u4e0b\u529f\u80fd\u7684\u4e3b\u4eea\u8868\u76d8\uff1a

      "},{"location":"getting-started/#_2","title":"\u4eea\u8868\u76d8\u529f\u80fd","text":"

      QPython \u4eea\u8868\u76d8\u63d0\u4f9b\u5bf9\u6240\u6709\u4e3b\u8981\u529f\u80fd\u7684\u5feb\u901f\u8bbf\u95ee\uff1a

      • \u7ec8\u7aef \u2014 \u8bbf\u95ee Python \u63a7\u5236\u53f0\u548c shell \u4ee5\u76f4\u63a5\u6267\u884c\u547d\u4ee4
      • Notebook \u2014 \u7528\u4e8e\u6570\u636e\u5206\u6790\u548c\u5b9e\u9a8c\u7684\u4ea4\u4e92\u5f0f Jupyter \u98ce\u683c\u7b14\u8bb0\u672c
      • \u7f16\u8f91\u5668 \u2014 \u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668\uff0c\u5177\u6709\u8bed\u6cd5\u9ad8\u4eae\u529f\u80fd\uff0c\u7528\u4e8e\u7f16\u5199 Python \u811a\u672c
      • \u8d44\u6e90\u7ba1\u7406\u5668 \u2014 \u6d4f\u89c8\u548c\u7ba1\u7406\u60a8\u7684\u6587\u4ef6\u3001\u811a\u672c\u548c\u9879\u76ee
      • QPYPI \u2014 \u5b89\u88c5 Python \u5305\u548c\u6269\u5c55\u3002\u8be6\u89c1 QPYPI \u6307\u5357
      • \u8bbe\u7f6e \u2014 \u914d\u7f6e QPython \u9996\u9009\u9879\u548c\u8fd0\u884c\u9009\u9879
      • \u793e\u533a \u2014 \u8bbf\u95ee QPython \u793e\u533a\u8d44\u6e90\u3001\u8bba\u575b\u548c\u5e2e\u52a9
      • \u8bfe\u7a0b \u2014 \u8bbf\u95ee Python \u7f16\u7a0b\u7684\u5b66\u4e60\u6750\u6599\u548c\u6559\u7a0b

      \u70b9\u51fb\u4efb\u4f55\u56fe\u6807\u4ee5\u8bbf\u95ee\u76f8\u5e94\u7684\u529f\u80fd\u3002

      "},{"location":"getting-started/#2","title":"2. \u7ec8\u7aef\u548c\u7f16\u8f91\u5668","text":""},{"location":"getting-started/#_3","title":"\u7ec8\u7aef","text":"

      \u7ec8\u7aef\u63d0\u4f9b Python \u63a7\u5236\u53f0\uff0c\u652f\u6301\uff1a - \u63a2\u7d22\u5bf9\u8c61\u5c5e\u6027 - \u6d4b\u8bd5\u8bed\u6cd5\u548c\u60f3\u6cd5 - \u76f4\u63a5\u6267\u884c\u547d\u4ee4

      \u4f7f\u7528\u52a0\u53f7\u6309\u94ae\uff081\uff09\u6253\u5f00\u65b0\u7ec8\u7aef\u6807\u7b7e\u9875\uff0c\u901a\u8fc7\u4e0b\u62c9\u83dc\u5355\uff082\uff09\u5207\u6362\uff0c\u5e76\u4f7f\u7528\u5173\u95ed\u6309\u94ae\uff083\uff09\u5173\u95ed\u3002

      "},{"location":"getting-started/#_4","title":"\u7f16\u8f91\u5668","text":"

      \u7f16\u8f91\u5668\u5e95\u90e8\u529f\u80fd\u680f\u5305\u542b\u4ee5\u4e0b\u5de5\u5177\uff08\u4ece\u5de6\u5230\u53f3\uff09\uff1a

      • \u5207\u6362\u5feb\u6377\u8f93\u5165\uff08\u5305\u542b def / if / else / elif / class \u7b49\u5173\u952e\u8bcd\uff09
      • \u9501\u5b9a\uff08\u9632\u6b62\u8bef\u89e6\uff09
      • \u8df3\u8f6c
      • \u4fdd\u5b58
      • \u8fd0\u884c
      • \u641c\u7d22
      • \u64a4\u9500
      • \u91cd\u505a
      • \u53e6\u5b58
      • \u6700\u8fd1\u6587\u4ef6
      • \u4ee3\u7801\u7247\u6bb5

      \u91cd\u8981\u63d0\u793a\uff1a \u4fdd\u5b58\u65f6\u8bf7\u624b\u52a8\u6dfb\u52a0 .py \u6269\u5c55\u540d\uff0c\u56e0\u4e3a\u7f16\u8f91\u5668\u4e0d\u4f1a\u81ea\u52a8\u6dfb\u52a0\u3002

      "},{"location":"getting-started/#3","title":"3. \u8d44\u6e90\u7ba1\u7406\u5668\uff08\u6587\u4ef6\u7ba1\u7406\uff09","text":"

      \u901a\u8fc7 \u8d44\u6e90\u7ba1\u7406\u5668 \u8bbf\u95ee\u811a\u672c\u548c\u9879\u76ee\uff0c\u652f\u6301\u6d4f\u89c8\u3001\u7ec4\u7ec7\u548c\u7ba1\u7406\u6240\u6709 Python \u6587\u4ef6\u3002

      "},{"location":"getting-started/#_5","title":"\u811a\u672c","text":"

      \u811a\u672c\u662f\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/scripts3/ \u4e2d\u7684\u5355\u4e2a Python \u6587\u4ef6\uff08\u9488\u5bf9 Python 3\uff09\u3002

      \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u811a\u672c - \u6253\u5f00 \u2014 \u4f7f\u7528\u5185\u7f6e\u7f16\u8f91\u5668\u7f16\u8f91 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u811a\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u811a\u672c

      "},{"location":"getting-started/#_6","title":"\u9879\u76ee","text":"

      \u9879\u76ee\u662f\u5305\u542b main.py \u4f5c\u4e3a\u5165\u53e3\u70b9\u7684\u76ee\u5f55\u3002\u60a8\u53ef\u4ee5\u5728\u540c\u4e00\u76ee\u5f55\u4e2d\u5305\u542b\u5176\u4ed6\u4f9d\u8d56\u9879\u548c\u8d44\u6e90\u3002\u5c06\u9879\u76ee\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/projects3/ \u4e2d\u3002

      "},{"location":"getting-started/#_7","title":"\u7b14\u8bb0\u672c","text":"

      Jupyter \u98ce\u683c\u7684\u7b14\u8bb0\u672c\u4e5f\u901a\u8fc7\u8d44\u6e90\u7ba1\u7406\u5668\u8fdb\u884c\u7ba1\u7406\uff0c\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/notebooks/ \u4e2d\u3002

      \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u7b14\u8bb0\u672c - \u6253\u5f00 \u2014 \u63a2\u7d22\u7b14\u8bb0\u672c\u5185\u5bb9 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u7b14\u8bb0\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u7b14\u8bb0\u672c

      "},{"location":"getting-started/#4","title":"4. \u5e93","text":"

      \u901a\u8fc7\u5b89\u88c5\u7b2c\u4e09\u65b9\u5e93\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

      "},{"location":"getting-started/#_8","title":"\u5305\u5b89\u88c5\u65b9\u6cd5","text":"

      QPYPI\uff08\u63a8\u8350\uff09

      \u4ece QPYPI \u5b89\u88c5\u9884\u7f16\u8bd1\u7684\u5e93\uff0c\u5305\u62ec numpy\u3001scipy \u7b49\u79d1\u5b66\u5305\u3002

      \u8be6\u89c1 QPYPI \u6307\u5357\u3002

      PIP \u5ba2\u6237\u7aef

      \u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216 QPYPI \u754c\u9762\u5b89\u88c5\u7eaf Python \u5e93\uff1a

      pip install requests\n

      \u9884\u7f16\u8bd1\u5305

      \u5bf9\u4e8e\u5177\u6709 C/C++/Rust \u4f9d\u8d56\u7684\u5305\uff0c\u4f7f\u7528 QPython \u7684\u9884\u7f16\u8bd1\u5305\uff1a

      pip install numpy-qpython\npip install scipy-aipy\n

      \u8be6\u89c1 QPYPI \u6307\u5357 \u83b7\u53d6\u53ef\u7528\u5305\u7684\u5b8c\u6574\u5217\u8868\u3002

      \u624b\u52a8\u5b89\u88c5

      \u60a8\u4e5f\u53ef\u4ee5\u5c06\u5e93\u590d\u5236\u5230 /storage/emulated/0/Android/data/org.qpython.qpy/files/lib/python3.12/site-packages/\u3002

      "},{"location":"getting-started/#5","title":"5. \u8fd0\u884c\u6a21\u5f0f","text":"

      QPython \u652f\u6301\u591a\u79cd\u8fd0\u884c\u6a21\u5f0f\u4ee5\u6ee1\u8db3\u4e0d\u540c\u7684\u7528\u4f8b\uff1a

      "},{"location":"getting-started/#_9","title":"\u63a7\u5236\u53f0\u6a21\u5f0f","text":"

      \u5e38\u89c4 Python \u811a\u672c\u7684\u9ed8\u8ba4\u6a21\u5f0f\u3002

      "},{"location":"getting-started/#qsl4a","title":"QSL4A \u6a21\u5f0f","text":"

      \u901a\u8fc7 QSL4A \u5e93\u8c03\u7528 Android API \u7684\u811a\u672c\u3002

      import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello Android!')\n

      \u8be6\u89c1 QSL4A \u6587\u6863 \u83b7\u53d6\u5b8c\u6574\u7684 API \u53c2\u8003\u3002

      "},{"location":"getting-started/#webapp","title":"WebApp \u6a21\u5f0f","text":"

      \u4f7f\u7528\u540e\u7aef\u670d\u52a1\u5668\u521b\u5efa\u57fa\u4e8e Web \u7684\u5e94\u7528\u7a0b\u5e8f\u3002\u9700\u5728\u811a\u672c\u5f00\u5934\u6dfb\u52a0\u4ee5\u4e0b\u4e24\u884c headers\uff1a

      #qpy:webapp:<\u9879\u76ee\u540d>\n#qpy://localhost:<web\u670d\u52a1\u4fa6\u542c\u7684\u7aef\u53e3>/<\u9ed8\u8ba4\u4e3b\u8def\u5f84>\n

      \u4f8b\u5982\uff1a

      #qpy:webapp:Hello QPython\n#qpy://localhost:8080/hello\n\nfrom bottle import route, run, Bottle\n\napp = Bottle()\n\n@route('/hello')\ndef hello():\n    return '<h1>Hello from QPython!</h1>'\n\nrun(app, host='localhost', port=8080)\n
      "},{"location":"getting-started/#q","title":"Q \u6a21\u5f0f\uff08\u65e0\u63a7\u5236\u53f0\u6a21\u5f0f\uff09","text":"

      \u9759\u9ed8\u6a21\u5f0f\u8fd0\u884c\u811a\u672c\uff0c\u4e0d\u663e\u793a\u63a7\u5236\u53f0\u3002\u9700\u5728\u811a\u672c\u5f00\u5934\u6dfb\u52a0 header\uff1a

      #qpy:quiet\n\nimport time\n\nwhile True:\n    # \u60a8\u7684\u540e\u53f0\u4efb\u52a1\n    time.sleep(60)\n
      \u5982\u679c\u9700\u8981\u8fd0\u884c\u5e26 GUI \u7684 QSL4A \u7a0b\u5e8f\u4e14\u4e0d\u5e0c\u671b\u663e\u793a\u63a7\u5236\u53f0\u4fe1\u606f\uff0c\u63a8\u8350\u4f7f\u7528\u6b64\u6a21\u5f0f\u3002

      "},{"location":"getting-started/#6","title":"6. \u793e\u533a\u4e0e\u652f\u6301","text":"

      \u8bbf\u95ee QPython.org \u83b7\u53d6\u6587\u6863\u3001\u7528\u6237\u793e\u533a\u53ca\u5e2e\u52a9\u95ee\u7b54\u3002

      \u793e\u533a\u94fe\u63a5\uff1a - Facebook \u7fa4\u7ec4 - GitHub - \u95ee\u9898\u53cd\u9988

      \u4e0b\u4e00\u6b65\uff1a - \u5c1d\u8bd5 Hello World \u6559\u7a0b - \u63a2\u7d22 QSL4A API \u4ee5\u96c6\u6210 Android - \u4e86\u89e3 QPython \u7248\u672c

      "},{"location":"getting-started/#_10","title":"\u89c6\u9891\u4ecb\u7ecd","text":""},{"location":"getting-started/#_11","title":"\u4e0b\u4e00\u6b65","text":"

      \u5982\u679c\u60a8\u5df2\u7ecf\u521d\u6b65\u4e86\u89e3\u4e86 QPython \u7684\u529f\u80fd\uff0c\u6b22\u8fce\u5f00\u59cb\u4f53\u9a8c\u7f16\u7a0b\u7684\u4e50\u8da3\uff01\u8bd5\u8bd5 Hello World \u6559\u7a0b \u8fc8\u51fa\u60a8\u7684\u7b2c\u4e00\u6b65\u3002

      "},{"location":"qpypi-guide/","title":"QPYPI","text":"

      \u60a8\u53ef\u4ee5\u901a\u8fc7\u5b89\u88c5\u5305\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

      "},{"location":"qpypi-guide/#_1","title":"\u5305\u5b89\u88c5\u652f\u6301","text":""},{"location":"qpypi-guide/#python","title":"\u7eaf Python \u5305","text":"

      QPython \u652f\u6301\u4f7f\u7528\u7eaf Python \u5f00\u53d1\u7684 Python \u5305\u3002\u60a8\u53ef\u4ee5\u76f4\u63a5\u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216\u4eea\u8868\u76d8\u4e0a\u7684 QPYPI \u4f7f\u7528 pip install \u5b89\u88c5\u8fd9\u4e9b\u5305\u3002

      "},{"location":"qpypi-guide/#_2","title":"\u9884\u7f16\u8bd1\u5305","text":"

      \u5982\u679c\u67d0\u4e9b\u5305\uff08\u6216\u5b83\u4eec\u7684\u4f9d\u8d56\uff09\u662f\u7528 Rust/C/C++ \u5f00\u53d1\u7684\uff0cQPython \u65e0\u6cd5\u76f4\u63a5\u652f\u6301\u5b83\u4eec\uff0c\u56e0\u4e3a QPython \u4e0a\u6ca1\u6709\u7f16\u8bd1\u5668\u5de5\u5177\u94fe\u652f\u6301\u3002\u4f46\u662f\uff0cQPython \u56e2\u961f\u5df2\u7ecf\u9884\u7f16\u8bd1\u4e86\u4e00\u4e9b\u5e38\u7528\u5305\uff0c\u5e76\u5728 QPython \u7684 QPYPI/Extensions \u4e2d\u53d1\u5e03\uff0c\u4f9b\u7528\u6237\u8f7b\u677e\u5b89\u88c5\u3002

      "},{"location":"qpypi-guide/#_3","title":"\u5b89\u88c5\u9884\u7f16\u8bd1\u5305","text":"

      \u60a8\u53ef\u4ee5\u901a\u8fc7\u4ee5\u4e0b\u65b9\u5f0f\u5b89\u88c5\u9884\u7f16\u8bd1\u5305\uff1a

      1. \u901a\u8fc7 QPython \u5e94\u7528\uff1a\u76f4\u63a5\u4ece QPython \u5e94\u7528\u5185\u7684 QPYPI \u6216 Extensions \u5b89\u88c5
      2. \u901a\u8fc7 PyPI\uff1a\u8bbf\u95ee https://pypi.org/user/qpythonx/ \u67e5\u770b\u53ef\u7528\u7684\u5305
      3. \u901a\u8fc7 pip \u547d\u4ee4\uff1a
      4. pip install xxx-qpython - \u5e26 -qpython \u540e\u7f00\u7684\u5305
      5. pip install xxx-aipy - \u5e26 -aipy \u540e\u7f00\u7684\u5305\uff08\u901a\u5e38\u662f AI/ML \u76f8\u5173\u7684\u5305\uff09

      \u6ce8\u610f\uff1a\u6211\u4eec\u901a\u5e38\u6839\u636e\u5305\u7684\u9884\u671f\u7528\u9014\u6dfb\u52a0\u8fd9\u4e9b\u540e\u7f00\u4e4b\u4e00\u3002

      "},{"location":"qpypi-guide/#_4","title":"\u8bf7\u6c42\u65b0\u5305","text":"

      \u5982\u679c\u60a8\u9700\u8981\u5f53\u524d\u4e0d\u652f\u6301\u7684\u5305\uff1a

      • \u5728 qpython.org \u9879\u76ee \u4e2d\u63d0\u51fa\u95ee\u9898
      • QPython \u56e2\u961f\u5c06\u8003\u8651\u9884\u7f16\u8bd1\u5e76\u5c06\u5176\u6dfb\u52a0\u5230\u4ed3\u5e93\u4e2d

      \u83b7\u53d6\u66f4\u591a\u5e2e\u52a9\u548c\u53c2\u4e0e\u793e\u533a\u7684\u65b9\u5f0f\uff0c\u8bf7\u53c2\u9605 \u793e\u533a\u4e0e\u53cd\u9988 \u90e8\u5206\u3002

      \u6ce8\u610f\uff1a\u7531\u4e8e\u4e0d\u540c\u7684\u8ba1\u7b97\u673a\u67b6\u6784\uff0c\u6211\u4eec\u65e0\u6cd5\u4fdd\u8bc1 QPYPI \u5305\u542b PyPI \u4e0a\u7684\u6240\u6709\u5305\u3002

      "},{"location":"qpython-x/","title":"QPython \u7248\u672c","text":"

      QPython \u662f Android \u7684 Python \u5f15\u64ce\u3002\u5b83\u5305\u542b\u4ee4\u4eba\u60ca\u53f9\u7684\u529f\u80fd\uff0c\u5982 Python \u89e3\u91ca\u5668\u3001\u8fd0\u884c\u73af\u5883\u3001\u7f16\u8f91\u5668\u3001QPYI \u548c\u96c6\u6210\u7684 SL4A\u3002\u5b83\u8ba9\u60a8\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 Android \u4e0a\u4f7f\u7528 Python\u3002\u800c\u4e14\u5b83\u662f\u514d\u8d39\u7684\u3002

      QPython \u5df2\u7ecf\u5728\u5168\u7403\u62e5\u6709\u6570\u767e\u4e07\u7528\u6237\uff0c\u4e5f\u662f\u4e00\u4e2a\u5f00\u6e90\u9879\u76ee\u3002

      \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

      "},{"location":"qpython-x/#qpython_1","title":"QPython","text":"

      \u6807\u51c6\u7248\uff1a\u9488\u5bf9 AI \u6027\u80fd\u548c\u901a\u7528\u5e94\u7528\u5546\u5e97\u517c\u5bb9\u6027\u4f18\u5316

      \u4e3b\u8981\u7248\u672c\uff0c\u53ef\u5728 Google Play \u548c\u5176\u4ed6\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002\u6b64\u7248\u672c\u4e13\u6ce8\u4e8e AI \u529f\u80fd\uff0c\u4f7f AI \u65f6\u4ee3\u7528\u6237\u66f4\u5bb9\u6613\u5b66\u4e60\u548c\u4f7f\u7528 Python\u3002

      \u4e3b\u8981\u7279\u6027\uff1a - AI \u9a71\u52a8\u7684\u7f16\u7801\u8f85\u52a9\u548c\u5b66\u4e60\u5de5\u5177 - \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668\uff1a\u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51 - \u652f\u6301\u591a\u79cd\u9879\u76ee\u7c7b\u578b\uff1a\u63a7\u5236\u53f0\u3001SL4A\u3001WebApp - \u65b9\u4fbf\u7684\u4e8c\u7ef4\u7801\u8bfb\u53d6\u5668\uff0c\u7528\u4e8e\u5c06\u4ee3\u7801\u4f20\u8f93\u5230\u624b\u673a - QPYPI \u548c\u81ea\u5b9a\u4e49\u4ed3\u5e93\uff0c\u7528\u4e8e\u9884\u7f16\u8bd1 wheel \u5305 -\u6613\u4e8e\u4f7f\u7528\u7684\u8bed\u6cd5\u9ad8\u4eae\u7f16\u8f91\u5668 - \u5b8c\u5584\u7684\u6587\u6863\u548c\u793e\u533a\u652f\u6301

      \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

      \u4e0b\u8f7d\uff1a \u53ef\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

      "},{"location":"qpython-x/#qpython_2","title":"QPython+","text":"

      \u793e\u533a\u7248\uff1a\u516c\u5f00\u652f\u6301\u5404\u79cd\u793e\u533a\u9a71\u52a8\u7684\u529f\u80fd\uff1b\u53ef\u5728\u90e8\u5206\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

      \u793e\u533a\u5f00\u6e90\u7248\u672c\uff08\u6b63\u5728\u89c4\u5212\u548c\u51c6\u5907\u4e2d\uff09\u3002\u6b64\u7248\u672c\u4e13\u4e3a\u60f3\u8981\u53c2\u4e0e QPython \u9879\u76ee\u5f00\u53d1\u7684\u8d21\u732e\u8005\u800c\u8bbe\u8ba1\uff0c\u652f\u6301\u9488\u5bf9\u4e0d\u540c\u5236\u9020\u5546\u7684\u5b9a\u5236\u3002

      \u4e3b\u8981\u7279\u6027\uff1a - \u793e\u533a\u9a71\u52a8\u5f00\u53d1 - \u652f\u6301\u4f9b\u5e94\u5546\u5b9a\u5236 - \u66f4\u7075\u6d3b\u7684\u914d\u7f6e\u9009\u9879 - \u5f00\u653e\u4f9b\u8d21\u732e\u8005\u52a0\u5165\u5f00\u53d1

      \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

      \u4e0b\u8f7d\uff1a \u5c06\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

      \u6ce8\u610f\uff1a \u6b64\u7248\u672c\u76ee\u524d\u6b63\u5728\u89c4\u5212\u51c6\u5907\u4e2d\u3002\u8bf7\u5173\u6ce8\u66f4\u65b0\uff01

      "},{"location":"qpython-x/#qpython-plus","title":"QPython Plus","text":"

      QPython+ \u5b8c\u5168\u8bbf\u95ee\u7248\uff1a\u6388\u4e88\u8c03\u7528\u6240\u6709 Android \u63a5\u53e3\u7684\u5b8c\u6574\u6743\u9650\u3002\u4e0b\u8f7d\u94fe\u63a5\u4ec5\u901a\u8fc7\u5b98\u65b9\u4e91\u76d8\u63d0\u4f9b\u3002

      \u5177\u6709\u6269\u5c55\u6743\u9650\u7684\u7279\u6b8a\u7248\u672c\uff0c\u63d0\u4f9b\u5bf9\u8bbe\u5907\u7684\u6700\u5927\u63a7\u5236\u3002\u7531\u4e8e\u5176\u654f\u611f\u7684\u6743\u9650\u8981\u6c42\uff0c\u6b64\u7248\u672c\u4e0d\u4f1a\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u53d1\u5e03\u3002

      \u4e3b\u8981\u7279\u6027\uff1a - \u5b8c\u6574\u7684 SL4A API \u8bbf\u95ee\uff0c\u5305\u62ec\u654f\u611f\u529f\u80fd - SMS/\u901a\u8bdd\u63a7\u5236 API - \u9ad8\u7ea7\u7cfb\u7edf\u96c6\u6210 - \u6700\u5927\u7684\u8bbe\u5907\u63a7\u5236\u80fd\u529b

      \u6743\u9650\uff1a \u9700\u8981\u5e7f\u6cdb\u7684\u6743\u9650\uff0c\u5305\u62ec\uff1a - \u84dd\u7259 - \u4f4d\u7f6e\uff08GPS\uff09 - \u8bfb\u53d6/\u53d1\u9001\u77ed\u4fe1 - \u6253\u7535\u8bdd - \u76f8\u673a\u548c\u9ea6\u514b\u98ce - \u7cfb\u7edf\u8bbe\u7f6e - \u4ee5\u53ca\u5176\u4ed6\u654f\u611f\u6743\u9650

      \u4e0b\u8f7d\uff1a \u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\u3002\u4ec5\u901a\u8fc7\u7279\u6b8a\u6e20\u9053\u5206\u53d1\u3002

      \u91cd\u8981\u63d0\u793a\uff1a QPython \u4e0d\u4f1a\u5728\u540e\u53f0\u672a\u7ecf\u60a8\u77e5\u6089\u4f7f\u7528\u8fd9\u4e9b\u6743\u9650\u3002\u5982\u679c\u4f7f\u7528 SL4A API \u65f6\u51fa\u73b0\u5f02\u5e38\uff0c\u8bf7\u68c0\u67e5\u7cfb\u7edf\u8bbe\u7f6e\u4e2d\u662f\u5426\u5df2\u542f\u7528\u76f8\u5173\u6743\u9650\u3002

      "},{"location":"tutorial-hello-world/","title":"\u7f16\u5199\"Hello World\"","text":""},{"location":"tutorial-hello-world/#hello-world_1","title":"Hello world","text":"

      \u597d\u7684\uff0c\u5728\u60a8\u5bf9 QPython \u6709\u4e86\u4e00\u5b9a\u7684\u4e86\u89e3\u4e4b\u540e\uff0c\u8ba9\u6211\u4eec\u5728 QPython \u4e2d\u521b\u5efa\u6211\u4eec\u7684\u7b2c\u4e00\u4e2a\u7a0b\u5e8f\u3002\u663e\u7136\uff0c\u5b83\u5c06\u662f helloworld.py\u3002;)

      \u542f\u52a8 QPython\uff0c\u6253\u5f00\u7f16\u8f91\u5668\u5e76\u8f93\u5165\u4ee5\u4e0b\u4ee3\u7801\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello, QPYTHON!')\n

      \u6beb\u65e0\u7591\u95ee\uff0c\u5b83\u4e0e\u5176\u4ed6\u4efb\u4f55 hello-world \u7a0b\u5e8f\u5e76\u65e0\u4e0d\u540c\u3002\u6267\u884c\u65f6\uff0c\u5b83\u53ea\u662f\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u5f39\u51fa\u6d88\u606f\uff08\u89c1\u9876\u90e8\u622a\u56fe\uff09\u3002\u65e0\u8bba\u5982\u4f55\uff0c\u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684 QPython \u7a0b\u5e8f\u793a\u4f8b\u3002

      "},{"location":"tutorial-hello-world/#_1","title":"\u4ee3\u7801\u7406\u89e3","text":"

      \u5b83\u4ee5 import androidhelper \u5f00\u5934\u2014\u2014\u8fd9\u662f QPython \u4e2d\u6700\u6709\u7528\u7684\u6a21\u5757\uff0c\u5b83\u5c01\u88c5\u4e86 Python \u4e2d\u53ef\u7528\u7684\u51e0\u4e4e\u6240\u6709\u4e0e Android \u7684\u63a5\u53e3\u3002\u4efb\u4f55\u5728 QPython \u4e2d\u5f00\u53d1\u7684\u811a\u672c\u90fd\u4ee5\u8fd9\u4e2a\u8bed\u53e5\u5f00\u5934\uff08\u81f3\u5c11\u5982\u679c\u5b83\u58f0\u79f0\u8981\u4e0e\u7528\u6237\u901a\u4fe1\u7684\u8bdd\uff09\u3002\u5728\u6b64\u5904\u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u5e93 \u548c import \u8bed\u53e5 \u7684\u5185\u5bb9\u3002

      \u63a5\u4e0b\u6765\u6211\u4eec\u521b\u5efa\u4e00\u4e2a droid \u5bf9\u8c61\uff08\u5b9e\u9645\u4e0a\u662f\u4e00\u4e2a\u7c7b\uff09\uff0c\u5b83\u5bf9\u4e8e\u8c03\u7528 RPC \u51fd\u6570\u4ee5\u4e0e Android \u901a\u4fe1\u662f\u5fc5\u8981\u7684\u3002

      \u6211\u4eec\u4ee3\u7801\u7684\u6700\u540e\u4e00\u884c\u8c03\u7528\u4e86\u8fd9\u6837\u7684\u51fd\u6570\uff0cdroid.makeToast()\uff0c\u5b83\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u4e00\u4e2a\u5c0f\u7684\u5f39\u51fa\u6d88\u606f\uff08\"toast\"\uff09\u3002

      \u597d\u7684\uff0c\u8ba9\u6211\u4eec\u6dfb\u52a0\u4e00\u4e9b\u66f4\u591a\u7684\u529f\u80fd\u3002\u8ba9\u5b83\u8be2\u95ee\u7528\u6237\u540d\u5e76\u5411\u7528\u6237\u6253\u62db\u547c\u3002

      "},{"location":"tutorial-hello-world/#_2","title":"\u66f4\u591a\u793a\u4f8b","text":"

      \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 dialogGetInput \u8c03\u7528\u663e\u793a\u4e00\u4e2a\u5e26\u6709\u6807\u9898\u3001\u63d0\u793a\u3001\u7f16\u8f91\u5b57\u6bb5\u548c \u786e\u5b9a \u548c \u53d6\u6d88 \u6309\u94ae\u7684\u7b80\u5355\u5bf9\u8bdd\u6846\u3002\u7528\u4ee5\u4e0b\u4ee3\u7801\u66ff\u6362\u60a8\u7684\u6700\u540e\u4e00\u884c\u4ee3\u7801\u5e76\u5c06\u5176\u4fdd\u5b58\u4e3a hello1.py\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\n

      \u597d\u7684\uff0c\u6211\u8ba4\u4e3a\u5b83\u5e94\u8be5\u8fd4\u56de\u4efb\u4f55\u54cd\u5e94\uff0c\u4efb\u4f55\u7528\u6237\u53cd\u5e94\u3002\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u6211\u5199 respond = ...\u3002\u4f46\u8fd9\u4e2a\u8c03\u7528\u5b9e\u9645\u4e0a\u8fd4\u56de\u4ec0\u4e48\uff1f\u8ba9\u6211\u4eec\u68c0\u67e5\u4e00\u4e0b\u3002\u53ea\u9700\u5728\u6700\u540e\u4e00\u884c\u540e\u6dfb\u52a0 print \u8bed\u53e5\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\n

      \u7136\u540e\u4fdd\u5b58\u5e76\u8fd0\u884c\u5b83...

      \u54ce\u5440\uff01\u6ca1\u6709\u6253\u5370\uff1f\u522b\u62c5\u5fc3\u3002\u53ea\u9700\u62c9\u4e0b\u901a\u77e5\u680f\uff0c\u60a8\u5c31\u4f1a\u770b\u5230\"QPython Program Output: hello1.py\"\u2014\u2014\u70b9\u51fb\u5b83\uff01

      \u5982\u60a8\u6240\u89c1\uff0cdroid.dialogGetInput() \u8fd4\u56de\u4e00\u4e2a\u5305\u542b\u4e09\u4e2a\u5b57\u6bb5\u7684 JSON \u5bf9\u8c61\u3002\u6211\u4eec\u53ea\u9700\u8981\u4e00\u4e2a\u2014\u2014result\uff0c\u5176\u4e2d\u5305\u542b\u7528\u6237\u5b9e\u9645\u8f93\u5165\u7684\u5185\u5bb9\u3002

      \u8ba9\u6211\u4eec\u6dfb\u52a0\u811a\u672c\u7684\u53cd\u5e94\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nmessage = f'Hello, {respond.result}!'\ndroid.makeToast(message)\n

      \u6700\u540e\u4e24\u884c\uff081\uff09\u683c\u5f0f\u5316\u6d88\u606f\uff0c\uff082\uff09\u4ee5 toast \u5f62\u5f0f\u5411\u7528\u6237\u663e\u793a\u6d88\u606f\u3002\u5982\u679c\u60a8\u4ecd\u7136\u4e0d\u77e5\u9053 f-string \u662f\u4ec0\u4e48\u610f\u601d\uff0c\u8bf7\u53c2\u9605 Python \u6587\u6863\u3002

      \u54c7\uff01\u5b83\u5de5\u4f5c\u4e86\uff01;)

      \u73b0\u5728\u6211\u8981\u5728\u90a3\u91cc\u6dfb\u52a0\u4e00\u4e9b\u903b\u8f91\u3002\u60f3\u4e00\u60f3\uff1a\u5982\u679c\u7528\u6237\u70b9\u51fb \u53d6\u6d88 \u6309\u94ae\uff0c\u6216\u8005\u70b9\u51fb \u786e\u5b9a \u4f46\u5c06\u8f93\u5165\u5b57\u6bb5\u7559\u7a7a\uff0c\u4f1a\u53d1\u751f\u4ec0\u4e48\uff1f

      \u60a8\u53ef\u4ee5\u73a9\u8fd9\u4e2a\u7a0b\u5e8f\uff0c\u68c0\u67e5 respond \u53d8\u91cf\u5728\u6bcf\u79cd\u60c5\u51b5\u4e0b\u5305\u542b\u4ec0\u4e48\u3002

      \u9996\u5148\uff0c\u6211\u60f3\u5c06\u7528\u6237\u8f93\u5165\u7684\u6587\u672c\u653e\u5165\u4e00\u4e2a\u5355\u72ec\u7684\u53d8\u91cf\u4e2d\uff1aname = respond.result\u3002\u7136\u540e\u6211\u68c0\u67e5\u5b83\uff0c\u5982\u679c\u5b83\u5305\u542b\u4efb\u4f55\u771f\u5b9e\u6587\u672c\uff0c\u5b83\u5c06\u88ab\u89c6\u4e3a\u540d\u79f0\u5e76\u7528\u4e8e\u95ee\u5019\u3002\u5426\u5219\uff0c\u5c06\u663e\u793a\u53e6\u4e00\u6761\u6d88\u606f\u3002\u5c06\u7b2c\u4e94\u884c message = f'Hello, {respond.result}!' \u66ff\u6362\u4e3a\u4ee5\u4e0b\u4ee3\u7801\uff1a

      name = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\n

      \u4f7f\u7528\u5de5\u5177\u680f\u4e0a\u7684 < \u548c > \u6309\u94ae\u6765\u7f29\u8fdb/\u53d6\u6d88\u7f29\u8fdb if \u8bed\u53e5\u4e2d\u7684\u884c\uff08\u6216\u8005\u53ea\u9700\u4f7f\u7528\u7a7a\u683c/\u9000\u683c\u952e\uff09\u3002\u60a8\u53ef\u4ee5\u5728 \u6b64\u5904 \u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u7f29\u8fdb\u7684\u5185\u5bb9\uff1bif \u8bed\u53e5\u5728 \u6b64\u5904 \u63cf\u8ff0\u3002

      \u9996\u5148\uff0c\u6211\u4eec\u5c06\u7528\u6237\u8f93\u5165\u653e\u5165 name \u53d8\u91cf\u3002\u7136\u540e\u6211\u4eec\u68c0\u67e5 name \u662f\u5426\u5305\u542b\u4efb\u4f55\u5185\u5bb9\uff1f\u5982\u679c\u7528\u6237\u7559\u7a7a\u884c\u5e76\u70b9\u51fb \u786e\u5b9a\uff0c\u8fd4\u56de\u503c\u662f\u7a7a\u5b57\u7b26\u4e32 ''\u3002\u5982\u679c\u6309\u4e0b\u4e86 \u53d6\u6d88 \u6309\u94ae\uff0c\u8fd4\u56de\u503c\u662f None\u3002\u5728 if \u8bed\u53e5\u4e2d\uff0c\u4e24\u8005\u90fd\u88ab\u89c6\u4e3a\u5047\u3002\u56e0\u6b64\uff0c\u53ea\u6709\u5f53 name \u5305\u542b\u4efb\u4f55\u6709\u610f\u4e49\u7684\u5185\u5bb9\u65f6\uff0cthen \u8bed\u53e5\u624d\u4f1a\u6267\u884c\uff0c\u5e76\u663e\u793a\u95ee\u5019\u8bed\"Hello, ...!\"\u3002\u5982\u679c\u8f93\u5165\u4e3a\u7a7a\uff0c\u7528\u6237\u5c06\u770b\u5230\"Hey! And you're not very polite, %Username%!\"\u6d88\u606f\u3002

      \u597d\u7684\uff0c\u8fd9\u662f\u6574\u4e2a\u7a0b\u5e8f\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nname = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\ndroid.makeToast(message)\n
      "},{"location":"tutorial-hello-world/#_3","title":"\u8fd0\u884c\u6548\u679c","text":""},{"location":"tutorial-hello-world/#_4","title":"\u4e0b\u4e00\u6b65","text":"

      \u5bf9\u4e8e Python \u65b0\u7528\u6237\uff0c\u63a8\u8350\u5b66\u4e60 Python \u8bed\u6cd5\u5b9e\u8df5 \u8bfe\u7a0b\u6765\u8fdb\u4e00\u6b65\u5b66\u4e60 Python\uff0c\u6216\u8005\u5728 QPython \u7cbe\u9009\u8bfe\u7a0b \u4e2d\u5bfb\u627e\u60f3\u8981\u5b66\u4e60\u7684\u5185\u5bb9\u3002

      "},{"location":"whats-new/","title":"\u66f4\u65b0\u65e5\u5fd7","text":""},{"location":"whats-new/#v392-v393","title":"v3.9.2 / v3.9.3","text":"
      • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
      • \u7f16\u8f91\u5668\u91cd\u5927\u66f4\u65b0\uff0c\u5e26\u6765\u66f4\u6d41\u7545\u7684\u7f16\u8f91\u4f53\u9a8c
      • \u5176\u4ed6\u5404\u79cd\u5c0f\u6539\u8fdb
      "},{"location":"whats-new/#v391","title":"v3.9.1","text":"
      • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
      • \u6269\u5c55\u5305\u73b0\u5728\u652f\u6301 MCP
      • \u9519\u8bef\u4fee\u590d
      "},{"location":"whats-new/#v390","title":"v3.9.0","text":"
      • SDK \u5347\u7ea7\uff0c\u6574\u5408\u6700\u65b0\u7684 Android \u529f\u80fd
      • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
      • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
      • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
      "},{"location":"whats-new/#v3811","title":"v3.8.11","text":"
      • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
      • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
      • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
      "},{"location":"whats-new/#v3810","title":"v3.8.10","text":"
      • \u5185\u7f6e Ollama \u5347\u7ea7\uff1a\u73b0\u5728\u60a8\u53ef\u4ee5\u5728 QPython \u4e2d\u8f7b\u677e\u672c\u5730\u8fd0\u884c Qwen3 / Gemma3 \u6a21\u578b\uff01
      • \u6dfb\u52a0\u4e86\u5f3a\u5927\u7684 MCP \u5e93\uff1a\u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 mcp \u5e93\uff0c\u8ba9\u60a8\u968f\u65f6\u968f\u5730\u643a\u5e26\u5f3a\u5927\u7684 MCP \u529f\u80fd\uff01
      "},{"location":"whats-new/#v389","title":"v3.8.9","text":"

      \u91cd\u5927\u66f4\u65b0\uff01AI \u7f16\u7a0b\u5b8c\u5168\u96c6\u6210\u5230 QPython\uff0c\u8ba9\u60a8\u7684\u7f16\u7a0b\u66f4\u8f7b\u677e\uff01

      • \u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u652f\u6301\uff1a\u65b0\u652f\u6301 AIPyApp\uff0c\u5728 QPython \u4e2d\u5b9e\u73b0\u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u3002\u76ee\u524d\u5904\u4e8e\u6d4b\u8bd5\u9636\u6bb5 - \u52a0\u5165\u6211\u4eec\u7684\u793e\u533a\u83b7\u53d6\u4f7f\u7528\u8bf4\u660e
      • \u65b0 QSL4A \u529f\u80fd\uff1a\u6dfb\u52a0 notebookOpen \u51fd\u6570\uff0c\u652f\u6301\u81ea\u7136\u8bed\u8a00\u63a7\u5236\u6253\u5f00 Notebook \u6587\u4ef6
      • \u5185\u7f6e\u7f16\u8f91\u5668\u5347\u7ea7\uff1a\u589e\u5f3a\u7f16\u8f91\u5668\u529f\u80fd\uff0c\u652f\u6301\u6253\u5f00\u548c\u6d4f\u89c8\u5404\u79cd\u6587\u672c\u6587\u4ef6
      • \u4fbf\u6377\u7684\u6587\u4ef6\u7ba1\u7406\uff1a\u5728\u6587\u4ef6\u7ba1\u7406\u5668\u4e2d\u6dfb\u52a0\u5185\u90e8\u5b58\u50a8\u5165\u53e3\uff0c\u5feb\u901f\u8bbf\u95ee\u60a8\u7684\u6587\u4ef6
      "},{"location":"whats-new/#v388","title":"v3.8.8","text":"
      • \u6587\u4ef6\u8bbf\u95ee\u6743\u9650\u63a7\u5236\u7684\u91cd\u8981\u6539\u8fdb\uff0c\u5141\u8bb8\u7528\u6237\u7075\u6d3b\u5730\u901a\u8fc7 QPython \u7f16\u7a0b\u542f\u7528\u6216\u7981\u7528\u5916\u90e8\u5b58\u50a8\u6587\u4ef6\u7684\u8bbf\u95ee
      • SDK \u5347\u7ea7\uff0c\u589e\u5f3a\u4e86\u5bf9\u65b0\u7248 Android \u7684\u652f\u6301\u548c\u517c\u5bb9\u6027
      • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Anthropic \u548c Google GenAI \u5e93
      "},{"location":"whats-new/#v387","title":"v3.8.7","text":"
      • \u5728\u73b0\u6709 Tkinter \u652f\u6301\u57fa\u7840\u4e0a\uff0c\u5728 Extensions -> Tools \u4e2d\u6dfb\u52a0\u4e86\u4f7f\u7528 Turtle \u7ed8\u5236\u54c6\u5566A\u68a6\u7684\u793a\u4f8b\u4ee3\u7801
      • \u4f18\u5316\u4e86\u624b\u673a\u6743\u9650\u83b7\u53d6\u6d41\u7a0b\uff0c\u63d0\u5347\u7528\u6237\u4f53\u9a8c\u548c\u64cd\u4f5c\u4fbf\u5229\u6027
      • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Google Gen AI \u5e93\uff0c\u65b9\u4fbf\u8bbf\u95ee Gemini Developer API \u548c Vertex AI
      "},{"location":"whats-new/#v386","title":"v3.8.6","text":"
      • Tkinter \u652f\u6301\uff1a\u73b0\u5728\u652f\u6301 Tkinter \u5e93\uff0c\u53ef\u901a\u8fc7 XServer \u8bbf\u95ee\u3002\u8bf7\u8bbf\u95ee www.qpython.org \u7684\u4e91\u76d8\"Extra\"\u94fe\u63a5\u4e0b\u8f7d\u6240\u9700\u6587\u4ef6
      • \u5b58\u50a8\u6743\u9650\u66f4\u65b0\uff1a\u4e3a\u6539\u5584\u7528\u6237\u4f53\u9a8c\uff0c\u6211\u4eec\u6dfb\u52a0\u4e86\u8bfb\u53d6\u624b\u673a\u5b58\u50a8\u7684\u6743\u9650\uff0c\u7528\u4e8e\u8bbf\u95ee\u5b58\u50a8\u5728\u5176\u4ed6\u76ee\u5f55\u4e2d\u7684 Python \u7a0b\u5e8f

      \u6b64\u66f4\u65b0\u540e\uff0cQPython \u548c QPythonPlus\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff0c\u4e13\u4e3a\u9700\u8981\u66f4\u591a\u654f\u611f\u6743\u9650\u7684\u9ad8\u7ea7\u7528\u6237\u8bbe\u8ba1\uff09\u5c06\u4fdd\u6301\u540c\u6b65\u7684\u7248\u672c\u53f7\u3002

      "},{"location":"whats-new/#v352-2025225","title":"v3.5.2 (2025/2/25)","text":"

      \u4e0e\u5f00\u6e90 LLM \u90e8\u7f72\u5de5\u5177 Ollama \u4ee5\u53ca DeepSeek \u5f00\u53d1\u7684 DeepSeek \u5b9e\u73b0\u65e0\u7f1d\u96c6\u6210\uff01

      \u529f\u80fd\uff1a - \u96f6\u95e8\u69db\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5404\u79cd\u5927\u578b\u8bed\u8a00\u6a21\u578b - \u5feb\u901f\u90e8\u7f72 DeepSeek \u7b49\u5c16\u7aef AI \u6a21\u578b - \u4eab\u53d7\u7b80\u7ea6\u7684 API \u8c03\u7528\u4f53\u9a8c - \u6784\u5efa\u5b8c\u5168\u79bb\u7ebf\u7684\u667a\u80fd\u7f16\u7a0b\u73af\u5883

      \u80fd\u529b\uff1a - \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u52a0\u8f7d/\u7ba1\u7406 LLM \u6a21\u578b - \u57fa\u4e8e\u672c\u5730\u8ba1\u7b97\u7684\u5b9e\u65f6\u4f4e\u5ef6\u8fdf\u54cd\u5e94

      "},{"location":"whats-new/#v350","title":"v3.5.0","text":"
      • Python \u5347\u7ea7\u5230 3.12.8
      • \u6539\u8fdb\u4eea\u8868\u76d8\uff0c\u529f\u80fd\u66f4\u6e05\u6670\u3001\u66f4\u4eba\u6027\u5316
      • \u6dfb\u52a0\u4e86\u4f17\u591a\u7b2c\u4e09\u65b9\u5305\uff1aPyTorch / Twisted / Scrapy / FastAPI ...
      "},{"location":"whats-new/#v338","title":"v3.3.8","text":"
      • \u4fee\u590d\u4e86 NumPy \u517c\u5bb9\u6027\u95ee\u9898
      "},{"location":"whats-new/#v335","title":"v3.3.5","text":"
      • \u5347\u7ea7 Python \u5185\u6838\u5230 3.11.9
      • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u4e0d\u663e\u793a\u6a21\u5757\u5b89\u88c5\u72b6\u6001\u7684 bug
      • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u5220\u9664\u6a21\u5757\u5931\u8d25\u7684 bug
      • \u4fee\u590d\u4e86\u5176\u4ed6 bug
      "},{"location":"whats-new/#v334","title":"v3.3.4","text":"
      • \u6dfb\u52a0\u4e86 OpenAI/Langchain/APIGPTCloud AI \u5305
      • \u79fb\u9664\u4e0d\u5fc5\u8981\u7684\u6587\u4ef6\u4ee5\u51cf\u5c11\u5927\u5c0f
      "},{"location":"whats-new/#v325","title":"v3.2.5","text":"
      • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570
      • \u5176\u4ed6\u9519\u8bef\u4fee\u590d
      "},{"location":"whats-new/#v323","title":"v3.2.3","text":"
      • \u66f4\u65b0 Python \u7248\u672c\u5230 3.11.0
      • \u66f4\u65b0 IPython \u7248\u672c\u5230 8.6.0
      • \u66f4\u65b0 pip \u7248\u672c\u5230 22.3.1
      • \u66f4\u65b0\u79d1\u5b66\u8ba1\u7b97\u5305\uff0c\u81ea\u52a8\u8f6f\u94fe\u63a5
      • \u51cf\u5c11\u7a7a\u95f4\u4f7f\u7528
      • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570 + \u5176\u4ed6\u9519\u8bef\u4fee\u590d
      "},{"location":"whats-new/#v318","title":"v3.1.8","text":"
      • \u5728\u7ec8\u7aef\u4e2d\u6dfb\u52a0\u4e86\u64cd\u4f5c\u70ed\u952e
      • \u4fee\u590d\u4e86\u7f16\u8f91\u5668\u5728\u65cb\u8f6c\u65f6\u4e22\u5931\u5185\u5bb9\u7684\u95ee\u9898
      • \u4fee\u590d\u4e86\u5176\u4ed6 bug

      \u5728 Google Play \u4e0b\u8f7d

      "},{"location":"qsl4a/","title":"QSL4A\uff08Android \u811a\u672c\u5c42\uff09API \u6587\u6863","text":"

      QSL4A \u662f QPython \u7684 Android \u811a\u672c\u5c42\uff0c\u5141\u8bb8\u60a8\u4f7f\u7528 Python \u63a7\u5236 Android \u8bbe\u5907\u529f\u80fd\u3002

      "},{"location":"qsl4a/#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a toast \u6d88\u606f\ndroid.makeToast('Hello QPython!')\n\n# \u9707\u52a8\u8bbe\u5907\ndroid.vibrate(500)\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\uff08\u5148\u5f00\u59cb\u76d1\u63a7\uff09\nimport time\ndroid.batteryStartMonitoring()\ntime.sleep(0.5)  # \u7b49\u5f85\u6570\u636e\nbattery = droid.readBatteryData().result\nprint(f\"\u7535\u6c60\uff1a{battery['level']}%\")\n
      "},{"location":"qsl4a/#_2","title":"\u6587\u6863\u7ed3\u6784","text":""},{"location":"qsl4a/#_3","title":"\u6838\u5fc3\u6a21\u5757","text":"
      • Android \u57fa\u7840 - \u6838\u5fc3\u8fde\u63a5\u548c RPC
      • Intent \u7cfb\u7edf - Android Intent \u64cd\u4f5c
      • \u4e8b\u4ef6\u7cfb\u7edf - \u4e8b\u4ef6\u5904\u7406\u548c\u5e7f\u64ad
      "},{"location":"qsl4a/#ui","title":"UI \u7ec4\u4ef6","text":"
      • \u5bf9\u8bdd\u6846 - \u8b66\u62a5\u3001\u8f93\u5165\u3001\u9009\u62e9\u5bf9\u8bdd\u6846
      • \u5168\u5c4f UI - \u81ea\u5b9a\u4e49\u5e03\u5c40 UI
      • \u60ac\u6d6e\u7a97 - \u60ac\u6d6e\u7a97\u53e3
      • \u8f85\u52a9\u529f\u80fd - \u5c4f\u5e55\u81ea\u52a8\u5316
      "},{"location":"qsl4a/#_4","title":"\u7cfb\u7edf","text":"
      • \u7535\u6c60 - \u7535\u6c60\u76d1\u63a7
      • \u4f20\u611f\u5668 - \u8bbe\u5907\u4f20\u611f\u5668
      • \u5e94\u7528 - \u5e94\u7528\u7ba1\u7406
      • \u7cfb\u7edf\u4fe1\u606f - \u8bbe\u5907\u4fe1\u606f
      • \u8bbe\u7f6e - \u7cfb\u7edf\u8bbe\u7f6e
      • \u5524\u9192\u9501 - \u5524\u9192\u9501\u63a7\u5236
      • QPython \u63a5\u53e3 - \u811a\u672c\u6267\u884c
      • Activity \u7ed3\u679c - Activity \u7ed3\u679c\u5904\u7406
      "},{"location":"qsl4a/#_5","title":"\u786c\u4ef6","text":"
      • \u84dd\u7259 - \u84dd\u7259\u64cd\u4f5c
      • \u76f8\u673a - \u62cd\u7167\u548c\u5f55\u50cf
      • \u97f3\u9891/\u5f55\u97f3\u5668 - \u5f55\u97f3
      • \u7f51\u7edc\u6444\u50cf\u5934 - MJPEG \u6d41
      • USB \u4e32\u53e3 - USB \u4e3b\u673a\u4e32\u53e3
      "},{"location":"qsl4a/#_6","title":"\u8fde\u63a5","text":"
      • WiFi - WiFi \u64cd\u4f5c
      • \u4f4d\u7f6e - GPS \u548c\u4f4d\u7f6e
      • \u77ed\u4fe1 - \u77ed\u4fe1\u64cd\u4f5c
      • \u7535\u8bdd - \u6253\u7535\u8bdd\u548c\u6765\u7535\u4fe1\u606f
      • \u8054\u7cfb\u4eba - \u8054\u7cfb\u4eba\u7ba1\u7406
      • \u4fe1\u53f7\u5f3a\u5ea6 - \u4fe1\u53f7\u76d1\u63a7
      • FTP \u670d\u52a1\u5668 - \u5185\u7f6e FTP \u670d\u52a1\u5668
      "},{"location":"qsl4a/#_7","title":"\u5b58\u50a8","text":"
      • DocumentFile - \u6587\u4ef6\u64cd\u4f5c
      • \u526a\u8d34\u677f - \u526a\u8d34\u677f\u64cd\u4f5c
      • \u504f\u597d\u8bbe\u7f6e - \u5171\u4eab\u504f\u597d\u8bbe\u7f6e
      "},{"location":"qsl4a/#_8","title":"\u5a92\u4f53","text":"
      • \u5a92\u4f53\u64ad\u653e\u5668 - \u97f3\u9891/\u89c6\u9891\u64ad\u653e
      • \u56fe\u50cf\u5904\u7406 - \u56fe\u50cf\u64cd\u4f5c
      "},{"location":"qsl4a/#_9","title":"\u7279\u6b8a\u529f\u80fd","text":"
      • \u52a0\u5bc6 - \u52a0\u5bc6/\u89e3\u5bc6
      • PGPT AI - AI \u8bed\u97f3\u670d\u52a1
      "},{"location":"qsl4a/#_10","title":"\u7ed3\u679c\u5bf9\u8c61","text":"

      \u5927\u591a\u6570 QSL4A \u65b9\u6cd5\u8fd4\u56de\u4e00\u4e2a\u5e26\u6709\u4ee5\u4e0b\u5c5e\u6027\u7684 Result \u547d\u540d\u5143\u7ec4\uff1a - id - \u8bf7\u6c42 ID - result - \u5b9e\u9645\u7ed3\u679c\u6570\u636e - error - \u5982\u679c\u5931\u8d25\u5219\u4e3a\u9519\u8bef\u6d88\u606f

      result = droid.getClipboard()\nif result.error is None:\n    print(result.result)\nelse:\n    print(f\"\u9519\u8bef\uff1a{result.error}\")\n
      "},{"location":"qsl4a/connectivity/contacts/","title":"\u8054\u7cfb\u4eba API","text":"

      \u8bbf\u95ee\u548c\u7ba1\u7406\u8bbe\u5907\u8054\u7cfb\u4eba\u3002

      "},{"location":"qsl4a/connectivity/contacts/#_1","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":""},{"location":"qsl4a/connectivity/contacts/#pickcontact","title":"pickContact()","text":"

      \u663e\u793a\u8054\u7cfb\u4eba\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

      pickContact()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u8054\u7cfb\u4eba URI \u7684 Intent

      "},{"location":"qsl4a/connectivity/contacts/#pickphone","title":"pickPhone()","text":"

      \u663e\u793a\u7535\u8bdd\u53f7\u7801\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

      pickPhone()\n

      \u8fd4\u56de\uff1a \u9009\u4e2d\u7684\u7535\u8bdd\u53f7\u7801\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/contacts/#_2","title":"\u8054\u7cfb\u4eba\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#contactsget","title":"contactsGet()","text":"

      \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\u3002

      contactsGet(attributes=None)\n

      \u53c2\u6570\uff1a - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

      \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba JSONObject \u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetbyid","title":"contactsGetById()","text":"

      \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\u3002

      contactsGetById(id, attributes=None)\n

      \u53c2\u6570\uff1a - id (int): \u8054\u7cfb\u4eba ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

      \u8fd4\u56de\uff1a JSONObject \u8054\u7cfb\u4eba\u6570\u636e

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetcount","title":"contactsGetCount()","text":"

      \u83b7\u53d6\u8054\u7cfb\u4eba\u603b\u6570\u3002

      contactsGetCount()\n

      \u8fd4\u56de\uff1a \u6574\u6570\u8ba1\u6570

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetids","title":"contactsGetIds()","text":"

      \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba ID\u3002

      contactsGetIds()\n

      \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba ID \u6574\u6570\u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetattributes","title":"contactsGetAttributes()","text":"

      \u83b7\u53d6\u6240\u6709\u53ef\u80fd\u7684\u8054\u7cfb\u4eba\u5c5e\u6027\u3002

      contactsGetAttributes()\n

      \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#_3","title":"\u5185\u5bb9\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#querycontent","title":"queryContent()","text":"

      \u4f7f\u7528\u81ea\u5b9a\u4e49\u53c2\u6570\u67e5\u8be2\u5185\u5bb9\u89e3\u6790\u5668\u3002

      queryContent(uri, attributes=None, selection=None, selectionArgs=None, order=None)\n

      \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u5c5e\u6027 - selection (str, optional): WHERE \u5b50\u53e5 - selectionArgs (list, optional): \u9009\u62e9\u53c2\u6570 - order (str, optional): ORDER BY \u5b50\u53e5

      \u8fd4\u56de\uff1a JSONObject \u7ed3\u679c\u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#queryattributes","title":"queryAttributes()","text":"

      \u83b7\u53d6\u5185\u5bb9 URI \u7684\u5c5e\u6027\u3002

      queryAttributes(uri)\n

      \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI

      \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u7684 JSONArray

      "},{"location":"qsl4a/connectivity/contacts/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u9009\u62e9\u8054\u7cfb\u4eba\ncontact_uri = droid.pickContact().result\nprint(f\"Selected contact: {contact_uri}\")\n\n# \u9009\u62e9\u7535\u8bdd\u53f7\u7801\nphone = droid.pickPhone().result\nprint(f\"Selected phone: {phone}\")\n\n# \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\ncontacts = droid.contactsGet().result\nprint(f\"Total contacts: {len(contacts)}\")\n\n# \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\ncontact = droid.contactsGetById(1).result\nprint(f\"Contact: {contact}\")\n\n# \u83b7\u53d6\u8054\u7cfb\u4eba\u5c5e\u6027\nattrs = droid.contactsGetAttributes().result\nprint(f\"Available attributes: {attrs}\")\n
      "},{"location":"qsl4a/connectivity/ftp/","title":"FTP \u670d\u52a1\u5668 API","text":"

      \u5728\u8bbe\u5907\u4e0a\u542f\u52a8\u548c\u7ba1\u7406\u5185\u7f6e FTP \u670d\u52a1\u5668\u3002

      "},{"location":"qsl4a/connectivity/ftp/#ftp","title":"FTP \u670d\u52a1\u5668\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/ftp/#ftpstart","title":"ftpStart()","text":"

      \u542f\u52a8 FTP \u670d\u52a1\u5668\u3002

      ftpStart()\n

      \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4 [ip, port]

      "},{"location":"qsl4a/connectivity/ftp/#ftpstop","title":"ftpStop()","text":"

      \u505c\u6b62 FTP \u670d\u52a1\u5668\u3002

      ftpStop()\n
      "},{"location":"qsl4a/connectivity/ftp/#ftpisrunning","title":"ftpIsRunning()","text":"

      \u68c0\u67e5 FTP \u670d\u52a1\u5668\u662f\u5426\u6b63\u5728\u8fd0\u884c\u3002

      ftpIsRunning()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u8fd0\u884c\u5219\u4e3a True

      "},{"location":"qsl4a/connectivity/ftp/#ftpget","title":"ftpGet()","text":"

      \u83b7\u53d6 FTP \u670d\u52a1\u5668 IP \u5730\u5740\u3002

      ftpGet()\n

      \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4

      "},{"location":"qsl4a/connectivity/ftp/#ftpset","title":"ftpSet()","text":"

      \u914d\u7f6e FTP \u670d\u52a1\u5668\u8bbe\u7f6e\u3002

      ftpSet(port=None, rootDir=None, username=None, password=None)\n

      \u53c2\u6570\uff1a - port (int, optional): \u670d\u52a1\u5668\u7aef\u53e3 - rootDir (str, optional): \u8981\u670d\u52a1\u7684\u57fa\u7840\u76ee\u5f55 - username (str, optional): \u767b\u5f55\u7528\u6237\u540d - password (str, optional): \u767b\u5f55\u5bc6\u7801

      \u8fd4\u56de\uff1a \u5305\u542b\u5f53\u524d\u8bbe\u7f6e\u7684 JSONObject

      "},{"location":"qsl4a/connectivity/ftp/#ftpstatus","title":"ftpStatus()","text":"

      \u83b7\u53d6 FTP \u670d\u52a1\u5668\u72b6\u6001\u3002

      ftpStatus()\n

      \u8fd4\u56de\uff1a \u72b6\u6001\u63cf\u8ff0\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/ftp/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u914d\u7f6e FTP \u670d\u52a1\u5668\ndroid.ftpSet(\n    port=2121,\n    rootDir=\"/sdcard\",\n    username=\"admin\",\n    password=\"secret\"\n)\n\n# \u542f\u52a8 FTP \u670d\u52a1\u5668\ninfo = droid.ftpStart().result\nprint(f\"FTP running at {info[0]}:{info[1]}\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.ftpIsRunning().result:\n    print(\"FTP server is running\")\n\n# \u83b7\u53d6\u670d\u52a1\u5668\u4fe1\u606f\nserver_info = droid.ftpGet().result\nprint(f\"Server: {server_info}\")\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.ftpStop()\n

      \u6ce8\u610f\uff1a \u4f7f\u7528\u63d0\u4f9b\u7684\u51ed\u636e\u901a\u8fc7\u4efb\u4f55 FTP \u5ba2\u6237\u7aef\u8fde\u63a5\u5230 FTP \u670d\u52a1\u5668\u3002

      "},{"location":"qsl4a/connectivity/location/","title":"\u4f4d\u7f6e API","text":"

      \u8bbf\u95ee GPS \u548c\u7f51\u7edc\u4f4d\u7f6e\u670d\u52a1\u3002

      "},{"location":"qsl4a/connectivity/location/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/location/#startlocating","title":"startLocating()","text":"

      \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\u3002

      startLocating(minUpdateTime=60000, minUpdateDistance=30, updateGnssStatus=False)\n

      \u53c2\u6570\uff1a - minUpdateTime (int): \u66f4\u65b0\u4e4b\u95f4\u7684\u6700\u5c0f\u65f6\u95f4\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a60000\uff09 - minUpdateDistance (float): \u66f4\u65b0\u7684\u6700\u5c0f\u8ddd\u79bb\uff08\u7c73\uff09\uff08\u9ed8\u8ba4\uff1a30\uff09 - updateGnssStatus (bool): \u542f\u7528 GNSS \u72b6\u6001\u66f4\u65b0\uff08\u9ed8\u8ba4\uff1aFalse\uff09

      "},{"location":"qsl4a/connectivity/location/#stoplocating","title":"stopLocating()","text":"

      \u505c\u6b62\u4f4d\u7f6e\u66f4\u65b0\u3002

      stopLocating()\n
      "},{"location":"qsl4a/connectivity/location/#readlocation","title":"readLocation()","text":"

      \u83b7\u53d6\u6700\u540e\u5df2\u77e5\u4f4d\u7f6e\u3002

      readLocation()\n

      \u8fd4\u56de\uff1a \u4f4d\u7f6e\u6570\u636e\u5b57\u5178

      "},{"location":"qsl4a/connectivity/location/#getlastknownlocation","title":"getLastKnownLocation()","text":"

      \u83b7\u53d6\u7f13\u5b58\u7684\u4f4d\u7f6e\u3002

      getLastKnownLocation()\n

      \u8fd4\u56de\uff1a \u6765\u81ea\u6240\u6709\u63d0\u4f9b\u5546\u7684\u4f4d\u7f6e

      "},{"location":"qsl4a/connectivity/location/#geocode","title":"geocode()","text":"

      \u5c06\u5730\u5740\u8f6c\u6362\u4e3a\u5750\u6807\u3002

      geocode(address, maxResults=1)\n
      "},{"location":"qsl4a/connectivity/location/#_2","title":"\u4f4d\u7f6e\u63d0\u4f9b\u5546\u65b9\u6cd5)","text":""},{"location":"qsl4a/connectivity/location/#locationproviders","title":"locationProviders()","text":"

      \u83b7\u53d6\u624b\u673a\u4e0a\u53ef\u7528\u7684\u4f4d\u7f6e\u63d0\u4f9b\u5546\u3002

      locationProviders()\n

      \u8fd4\u56de\uff1a \u53ef\u7528\u63d0\u4f9b\u5546\u540d\u79f0\u5217\u8868\uff08\u4f8b\u5982 ['gps', 'network']\uff09

      "},{"location":"qsl4a/connectivity/location/#locationproviderenabled","title":"locationProviderEnabled()","text":"

      \u68c0\u67e5\u7279\u5b9a\u4f4d\u7f6e\u63d0\u4f9b\u5546\u662f\u5426\u5df2\u542f\u7528\u3002

      locationProviderEnabled(provider)\n

      \u53c2\u6570\uff1a - provider (str): \u63d0\u4f9b\u5546\u540d\u79f0\uff08\u4f8b\u5982 'gps', 'network'\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/connectivity/location/#readgnssstatus","title":"readGnssStatus()","text":"

      \u8bfb\u53d6\u5168\u7403\u5bfc\u822a\u536b\u661f\u7cfb\u7edf\u72b6\u6001\uff08\u9700\u8981 Android 8+\uff09\u3002

      readGnssStatus()\n

      \u8fd4\u56de\uff1a \u5305\u542b GNSS \u536b\u661f\u4fe1\u606f\u7684 JSONArray

      "},{"location":"qsl4a/connectivity/location/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\ndroid.startLocating(minUpdateTime=5000, minUpdateDistance=1, updateGnssStatus=False)\n\n# \u7b49\u5f85\u5b9a\u4f4d\ntime.sleep(10)\n\n# \u83b7\u53d6\u4f4d\u7f6e\nloc = droid.readLocation().result\nif loc:\n    lat = loc['latitude']\n    lon = loc['longitude']\n    print(f\"Location: {lat}, {lon}\")\n\ndroid.stopLocating()\n
      "},{"location":"qsl4a/connectivity/phone/","title":"\u7535\u8bdd API","text":"

      \u63a7\u5236\u7535\u8bdd\u901a\u8bdd\u548c\u83b7\u53d6\u7535\u8bdd\u4fe1\u606f\u3002

      "},{"location":"qsl4a/connectivity/phone/#_1","title":"\u7535\u8bdd\u72b6\u6001\u8ddf\u8e2a","text":""},{"location":"qsl4a/connectivity/phone/#starttrackingphonestate","title":"startTrackingPhoneState()","text":"

      \u5f00\u59cb\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u53d8\u5316\u3002\u751f\u6210 'phone' \u4e8b\u4ef6\u3002

      startTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/phone/#readphonestate","title":"readPhoneState()","text":"

      \u8bfb\u53d6\u5f53\u524d\u7535\u8bdd\u72b6\u6001\u3002

      readPhoneState()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7535\u8bdd\u72b6\u6001\u548c\u6765\u7535\u53f7\u7801\u7684 Bundle

      "},{"location":"qsl4a/connectivity/phone/#stoptrackingphonestate","title":"stopTrackingPhoneState()","text":"

      \u505c\u6b62\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u3002

      stopTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/phone/#_2","title":"\u62e8\u6253\u7535\u8bdd","text":""},{"location":"qsl4a/connectivity/phone/#phonecall","title":"phoneCall()","text":"

      \u901a\u8fc7 URI \u547c\u53eb\u8054\u7cfb\u4eba/\u7535\u8bdd\u53f7\u7801\u3002

      phoneCall(uri)\n

      \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

      "},{"location":"qsl4a/connectivity/phone/#phonecallnumber","title":"phoneCallNumber()","text":"

      \u76f4\u63a5\u62e8\u6253\u7535\u8bdd\u53f7\u7801\u3002

      phoneCallNumber(phone_number)\n

      \u53c2\u6570\uff1a - phone_number (str): \u8981\u62e8\u6253\u7684\u7535\u8bdd\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#phonedial","title":"phoneDial()","text":"

      \u62e8\u6253\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

      phoneDial(uri)\n

      \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

      "},{"location":"qsl4a/connectivity/phone/#phonedialnumber","title":"phoneDialNumber()","text":"

      \u62e8\u6253\u7535\u8bdd\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

      phoneDialNumber(phone_number)\n

      \u53c2\u6570\uff1a - phone_number (str): \u7535\u8bdd\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#_3","title":"\u57fa\u7ad9\u4f4d\u7f6e","text":""},{"location":"qsl4a/connectivity/phone/#getcelllocation","title":"getCellLocation()","text":"

      \u83b7\u53d6\u5f53\u524d\u57fa\u7ad9\u4f4d\u7f6e\u3002

      getCellLocation()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u57fa\u7ad9\u4f4d\u7f6e\u6570\u636e\u7684 JSONObject

      "},{"location":"qsl4a/connectivity/phone/#getallcellslocation","title":"getAllCellsLocation()","text":"

      \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u4f4d\u7f6e\uff08\u9002\u7528\u4e8e\u53cc\u5361\u8bbe\u5907\uff09\u3002

      getAllCellsLocation()\n

      \u8fd4\u56de\uff1a \u57fa\u7ad9\u4f4d\u7f6e\u7684 JSONArray

      "},{"location":"qsl4a/connectivity/phone/#_4","title":"\u7f51\u7edc\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getnetworkoperator","title":"getNetworkOperator()","text":"

      \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

      getNetworkOperator()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getnetworkoperatorname","title":"getNetworkOperatorName()","text":"

      \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684\u540d\u79f0\u3002

      getNetworkOperatorName()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getnetworktype","title":"getNetworkType()","text":"

      \u83b7\u53d6\u5f53\u524d\u7f51\u7edc\u7c7b\u578b\u3002

      getNetworkType()\n

      \u8fd4\u56de\uff1a \u63cf\u8ff0\u65e0\u7ebf\u7535\u6280\u672f\u7684\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'LTE', 'UMTS', 'GSM'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getphonetype","title":"getPhoneType()","text":"

      \u83b7\u53d6\u7535\u8bdd\u7c7b\u578b\u3002

      getPhoneType()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'GSM', 'CDMA', 'SIP'\uff09

      "},{"location":"qsl4a/connectivity/phone/#sim","title":"SIM \u5361\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getsimcountryiso","title":"getSimCountryIso()","text":"

      \u83b7\u53d6 SIM \u5361\u7684 ISO \u56fd\u5bb6\u4ee3\u7801\u3002

      getSimCountryIso()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'us'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getsimoperator","title":"getSimOperator()","text":"

      \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

      getSimOperator()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getsimoperatorname","title":"getSimOperatorName()","text":"

      \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u540d\u79f0\u3002

      getSimOperatorName()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getsimserialnumber","title":"getSimSerialNumber()","text":"

      \u83b7\u53d6 SIM \u5e8f\u5217\u53f7\u3002

      getSimSerialNumber()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32 SIM \u5e8f\u5217\u53f7

      "},{"location":"qsl4a/connectivity/phone/#getsimstate","title":"getSimState()","text":"

      \u83b7\u53d6 SIM \u5361\u72b6\u6001\u3002

      getSimState()\n

      \u8fd4\u56de\uff1a \u63cf\u8ff0 SIM \u72b6\u6001\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/phone/#getsubscriberid","title":"getSubscriberId()","text":"

      \u83b7\u53d6\u8ba2\u9605\u8005 ID\u3002

      getSubscriberId()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8ba2\u9605\u8005 ID

      "},{"location":"qsl4a/connectivity/phone/#_5","title":"\u8bed\u97f3\u90ae\u4ef6","text":""},{"location":"qsl4a/connectivity/phone/#getvoicemailalphatag","title":"getVoiceMailAlphaTag()","text":"

      \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u5b57\u6bcd\u6807\u7b7e\u3002

      getVoiceMailAlphaTag()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u6807\u7b7e

      "},{"location":"qsl4a/connectivity/phone/#getvoicemailnumber","title":"getVoiceMailNumber()","text":"

      \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801\u3002

      getVoiceMailNumber()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getdeviceid","title":"getDeviceId()","text":"

      \u83b7\u53d6\u8bbe\u5907 ID\uff08GSM \u7684 IMEI\uff09\u3002\u5df2\u5e9f\u5f03\u3002

      getDeviceId()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

      "},{"location":"qsl4a/connectivity/phone/#getdevicesoftwareversion","title":"getDeviceSoftwareVersion()","text":"

      \u83b7\u53d6\u8bbe\u5907\u8f6f\u4ef6\u7248\u672c\u3002

      getDeviceSoftwareVersion()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8f6f\u4ef6\u7248\u672c

      "},{"location":"qsl4a/connectivity/phone/#getline1number","title":"getLine1Number()","text":"

      \u83b7\u53d6\u7ebf\u8def 1 \u7535\u8bdd\u53f7\u7801\u3002

      getLine1Number()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u7535\u8bdd\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#checknetworkroaming","title":"checkNetworkRoaming()","text":"

      \u68c0\u67e5\u662f\u5426\u8fde\u63a5\u5230\u6f2b\u6e38\u7f51\u7edc\u3002

      checkNetworkRoaming()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u6f2b\u6e38\u5219\u4e3a True

      "},{"location":"qsl4a/connectivity/phone/#_7","title":"\u57fa\u7ad9\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getallcellinfo","title":"getAllCellInfo()","text":"

      \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u7684\u4fe1\u606f\u3002

      getAllCellInfo()\n

      \u8fd4\u56de\uff1a \u57fa\u7ad9\u4fe1\u606f\u5217\u8868

      "},{"location":"qsl4a/connectivity/phone/#setdataenabled","title":"setDataEnabled()","text":"

      \u542f\u7528\u6216\u7981\u7528\u79fb\u52a8\u6570\u636e\u3002

      setDataEnabled(enabled)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528

      "},{"location":"qsl4a/connectivity/phone/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7f51\u7edc\u4fe1\u606f\noperator = droid.getNetworkOperatorName().result\nprint(f\"Operator: {operator}\")\n\nnetwork_type = droid.getNetworkType().result\nprint(f\"Network: {network_type}\")\n\n# \u83b7\u53d6 SIM \u4fe1\u606f\nsim_state = droid.getSimState().result\nprint(f\"SIM: {sim_state}\")\n\n# \u83b7\u53d6\u7535\u8bdd\u53f7\u7801\nline1 = droid.getLine1Number().result\nprint(f\"Phone: {line1}\")\n\n# \u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\ndroid.startTrackingPhoneState()\nprint(\"Tracking phone state...\")\ndroid.stopTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/signalstrength/","title":"\u4fe1\u53f7\u5f3a\u5ea6 API","text":"

      \u76d1\u63a7\u8702\u7a9d\u548c\u65e0\u7ebf\u4fe1\u53f7\u5f3a\u5ea6\u3002

      "},{"location":"qsl4a/connectivity/signalstrength/#_1","title":"\u4fe1\u53f7\u5f3a\u5ea6\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/signalstrength/#starttrackingsignalstrengths","title":"startTrackingSignalStrengths()","text":"

      \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316\u3002\u751f\u6210 'signal_strengths' \u4e8b\u4ef6\u3002

      startTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/signalstrength/#stoptrackingsignalstrengths","title":"stopTrackingSignalStrengths()","text":"

      \u505c\u6b62\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u3002

      stopTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/signalstrength/#readsignalstrengths","title":"readSignalStrengths()","text":"

      \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\u3002

      readSignalStrengths()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u4fe1\u53f7\u5f3a\u5ea6\u6570\u636e\u7684 Bundle

      "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthlevel","title":"getTelephoneSignalStrengthLevel()","text":"

      \u83b7\u53d6\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u7b49\u7ea7\uff080-4\uff09\u3002

      getTelephoneSignalStrengthLevel()\n

      \u8fd4\u56de\uff1a \u6574\u6570\u7b49\u7ea7\uff080=\u65e0\uff0c1=\u5dee\uff0c2=\u4e00\u822c\uff0c3=\u597d\uff0c4=\u4f18\u79c0\uff09

      "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthdetail","title":"getTelephoneSignalStrengthDetail()","text":"

      \u83b7\u53d6\u8be6\u7ec6\u7684\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u4fe1\u606f\u3002

      getTelephoneSignalStrengthDetail()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u8be6\u7ec6\u4fe1\u53f7\u4fe1\u606f\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/signalstrength/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\ndroid.startTrackingSignalStrengths()\n\n# \u7b49\u5f85\u4fe1\u53f7\u66f4\u65b0\ntime.sleep(5)\n\n# \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\nsignal = droid.readSignalStrengths().result\nprint(f\"Signal: {signal}\")\n\n# \u76f4\u63a5\u83b7\u53d6\u7b49\u7ea7\nlevel = droid.getTelephoneSignalStrengthLevel().result\nprint(f\"Signal level: {level}/4\")\n\ndroid.stopTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/sms/","title":"SMS API","text":"

      \u53d1\u9001\u548c\u63a5\u6536 SMS \u6d88\u606f\u3002

      "},{"location":"qsl4a/connectivity/sms/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/sms/#smssend","title":"smsSend()","text":"

      \u53d1\u9001 SMS \u6d88\u606f\u3002

      smsSend(destinationAddress, text)\n

      \u53c2\u6570\uff1a - destinationAddress (str): \u7535\u8bdd\u53f7\u7801 - text (str): \u6d88\u606f\u6587\u672c

      "},{"location":"qsl4a/connectivity/sms/#smsgetmessagecount","title":"smsGetMessageCount()","text":"

      \u83b7\u53d6\u6d88\u606f\u6570\u91cf\u3002

      smsGetMessageCount(unreadOnly=False, folder=\"inbox\")\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessageids","title":"smsGetMessageIds()","text":"

      \u83b7\u53d6\u6d88\u606f ID\u3002

      smsGetMessageIds(unreadOnly=False, folder=\"inbox\")\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessages","title":"smsGetMessages()","text":"

      \u83b7\u53d6\u6d88\u606f\u8be6\u60c5\u3002

      smsGetMessages(unreadOnly=False, folder=\"inbox\", attributes=None)\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessagebyid","title":"smsGetMessageById()","text":"

      \u901a\u8fc7 ID \u83b7\u53d6\u7279\u5b9a\u6d88\u606f\u3002

      smsGetMessageById(id, attributes=None)\n

      \u53c2\u6570\uff1a - id (int): \u6d88\u606f ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

      \u8fd4\u56de\uff1a \u6d88\u606f\u6570\u636e\u5b57\u5178

      "},{"location":"qsl4a/connectivity/sms/#smsgetattributes","title":"smsGetAttributes()","text":"

      \u83b7\u53d6\u53ef\u7528\u7684 SMS \u6d88\u606f\u5c5e\u6027\u3002

      smsGetAttributes()\n

      \u8fd4\u56de\uff1a \u53ef\u7528\u5c5e\u6027\u540d\u79f0\u5217\u8868

      "},{"location":"qsl4a/connectivity/sms/#smsdeletemessage","title":"smsDeleteMessage()","text":"

      \u5220\u9664\u6d88\u606f\u3002

      smsDeleteMessage(id)\n
      "},{"location":"qsl4a/connectivity/sms/#smsmarkmessageread","title":"smsMarkMessageRead()","text":"

      \u5c06\u6d88\u606f\u6807\u8bb0\u4e3a\u5df2\u8bfb\u3002

      smsMarkMessageRead(ids, read=True)\n
      "},{"location":"qsl4a/connectivity/sms/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u53d1\u9001 SMS\ndroid.smsSend(\"+1234567890\", \"Hello from QPython!\")\n\n# \u83b7\u53d6\u672a\u8bfb\u6d88\u606f\nmessages = droid.smsGetMessages(unreadOnly=True).result\nfor msg in messages:\n    print(f\"From: {msg['address']}, Text: {msg['body']}\")\n
      "},{"location":"qsl4a/connectivity/wifi/","title":"WiFi API","text":"

      \u63a7\u5236 WiFi \u9002\u914d\u5668\u5e76\u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\u3002

      "},{"location":"qsl4a/connectivity/wifi/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/connectivity/wifi/#checkwifistate","title":"checkWifiState()","text":"

      \u68c0\u67e5 WiFi \u662f\u5426\u5df2\u542f\u7528\u3002

      checkWifiState()\n

      \u8fd4\u56de\uff1a \u5982\u679c WiFi \u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/connectivity/wifi/#togglewifistate","title":"toggleWifiState()","text":"

      \u6253\u5f00\u6216\u5173\u95ed WiFi\u3002

      toggleWifiState(enabled=None)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

      \u8fd4\u56de\uff1a \u5982\u679c\u64cd\u4f5c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/connectivity/wifi/#wifistartscan","title":"wifiStartScan()","text":"

      \u5f00\u59cb\u626b\u63cf\u53ef\u7528\u7684 WiFi \u7f51\u7edc\u3002

      wifiStartScan()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifigetscanresults","title":"wifiGetScanResults()","text":"

      \u83b7\u53d6\u53d1\u73b0\u7684 WiFi \u7f51\u7edc\u5217\u8868\u3002

      wifiGetScanResults()\n

      \u8fd4\u56de\uff1a \u63a5\u5165\u70b9\u4fe1\u606f\u5217\u8868

      "},{"location":"qsl4a/connectivity/wifi/#_2","title":"\u8fde\u63a5\u7ba1\u7406","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetconnectioninfo","title":"wifiGetConnectionInfo()","text":"

      \u83b7\u53d6\u8be6\u7ec6\u8fde\u63a5\u4fe1\u606f\u3002

      wifiGetConnectionInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001IP \u5730\u5740\u7b49\u8fde\u63a5\u8be6\u60c5\u7684\u5b57\u5178

      "},{"location":"qsl4a/connectivity/wifi/#getconnectedinfo","title":"getConnectedInfo()","text":"

      \u83b7\u53d6\u8fde\u63a5\u7684 WiFi \u7f51\u7edc\u4fe1\u606f\uff08\u7b80\u5316\u7248\uff09\u3002

      getConnectedInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001\u4fe1\u53f7\u5f3a\u5ea6\u7684\u5b57\u5178

      "},{"location":"qsl4a/connectivity/wifi/#getdhcpinfo","title":"getDhcpInfo()","text":"

      \u83b7\u53d6\u5f53\u524d\u8fde\u63a5\u7684 DHCP \u4fe1\u606f\u3002

      getDhcpInfo(ipConvertToString=True)\n

      \u53c2\u6570\uff1a - ipConvertToString (bool): \u5c06 IP \u5730\u5740\u8f6c\u6362\u4e3a\u5b57\u7b26\u4e32\u683c\u5f0f\uff08\u9ed8\u8ba4\uff1aTrue\uff09

      \u8fd4\u56de\uff1a \u5305\u542b IP\u3001\u7f51\u5173\u3001DNS \u7b49 DHCP \u4fe1\u606f\u7684\u5b57\u5178

      "},{"location":"qsl4a/connectivity/wifi/#wifidisconnect","title":"wifiDisconnect()","text":"

      \u65ad\u5f00\u5f53\u524d WiFi \u7f51\u7edc\u8fde\u63a5\u3002

      wifiDisconnect()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifireconnect","title":"wifiReconnect()","text":"

      \u91cd\u65b0\u8fde\u63a5\u5230\u5f53\u524d\u7f51\u7edc\u3002

      wifiReconnect()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifireassociate","title":"wifiReassociate()","text":"

      \u91cd\u65b0\u5173\u8054\u5f53\u524d\u63a5\u5165\u70b9\u3002

      wifiReassociate()\n
      "},{"location":"qsl4a/connectivity/wifi/#_3","title":"\u70ed\u70b9","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetapstate","title":"wifiGetApState()","text":"

      \u83b7\u53d6 WiFi AP\uff08\u70ed\u70b9\uff09\u72b6\u6001\u3002

      wifiGetApState()\n

      \u8fd4\u56de\uff1a \u70ed\u70b9\u72b6\u6001

      "},{"location":"qsl4a/connectivity/wifi/#wifi","title":"WiFi \u9501","text":""},{"location":"qsl4a/connectivity/wifi/#wifilockacquirefull","title":"wifiLockAcquireFull()","text":"

      \u83b7\u53d6\u5b8c\u6574 WiFi \u9501\uff08\u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\u4e5f\u4fdd\u6301 WiFi \u6d3b\u52a8\uff09\u3002

      wifiLockAcquireFull()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifilockacquirescanonly","title":"wifiLockAcquireScanOnly()","text":"

      \u83b7\u53d6\u4ec5\u626b\u63cf WiFi \u9501\u3002

      wifiLockAcquireScanOnly()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifilockrelease","title":"wifiLockRelease()","text":"

      \u91ca\u653e WiFi \u9501\u3002

      wifiLockRelease()\n
      "},{"location":"qsl4a/connectivity/wifi/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u68c0\u67e5 WiFi \u72b6\u6001\nif droid.checkWifiState().result:\n    print(\"WiFi is enabled\")\nelse:\n    print(\"Enabling WiFi...\")\n    droid.toggleWifiState(True)\n    time.sleep(2)\n\n# \u5f00\u59cb\u626b\u63cf\ndroid.wifiStartScan()\ntime.sleep(3)\n\n# \u83b7\u53d6\u626b\u63cf\u7ed3\u679c\nnetworks = droid.wifiGetScanResults().result\nfor network in networks:\n    print(f\"SSID: {network.get('SSID')}, Signal: {network.get('level')} dBm\")\n\n# \u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\ninfo = droid.wifiGetConnectionInfo().result\nif info:\n    print(f\"Connected to: {info.get('ssid')}\")\n    print(f\"BSSID: {info.get('bssid')}\")\n    print(f\"IP: {info.get('ip_address')}\")\n\n# \u83b7\u53d6 DHCP \u4fe1\u606f\ndhcp = droid.getDhcpInfo().result\nif dhcp:\n    print(f\"Gateway: {dhcp.get('gateway')}\")\n    print(f\"DNS: {dhcp.get('dns1')}\")\n\n# \u83b7\u53d6\u7b80\u5316\u7684\u8fde\u63a5\u4fe1\u606f\nconnected = droid.getConnectedInfo().result\nprint(f\"SSID: {connected.get('ssid')}, Signal: {connected.get('level')} dBm\")\n\n# \u65ad\u5f00\u5e76\u91cd\u65b0\u8fde\u63a5\ndroid.wifiDisconnect()\ntime.sleep(1)\ndroid.wifiReconnect()\n\n# \u91cd\u65b0\u5173\u8054\u63a5\u5165\u70b9\ndroid.wifiReassociate()\n\n# \u68c0\u67e5\u70ed\u70b9\u72b6\u6001\nap_state = droid.wifiGetApState().result\nprint(f\"Hotspot state: {ap_state}\")\n\n# \u83b7\u53d6 WiFi \u9501\u4ee5\u8fdb\u884c\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireFull()\n# ... \u6267\u884c\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n\n# \u6216\u4f7f\u7528\u4ec5\u626b\u63cf\u9501\u4ee5\u8fdb\u884c\u8f83\u8f7b\u7684\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireScanOnly()\n# ... \u6267\u884c\u626b\u63cf\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n
      "},{"location":"qsl4a/core/android-base/","title":"Android \u57fa\u7840\u7c7b","text":"

      Android \u7c7b\u662f QSL4A \u7684\u6838\u5fc3\uff0c\u63d0\u4f9b\u4e86\u4e0e Android \u8fd0\u884c\u65f6\u7684\u8fde\u63a5\u548c RPC \u673a\u5236\u3002

      "},{"location":"qsl4a/core/android-base/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
      # \u529f\u80fd\u5b8c\u6574\u7248\u672c\uff08\u63a8\u8350\uff09\nimport androidhelper\ndroid = androidhelper.Android()\n\n# \u7b80\u5316\u7248\u672c\uff08\u5feb\u901f\uff0c\u5355\u5b9e\u4f8b\uff09\nimport android\ndroid = android.droid\n
      "},{"location":"qsl4a/core/android-base/#android_1","title":"\u7c7b\uff1aAndroid","text":""},{"location":"qsl4a/core/android-base/#_2","title":"\u6784\u9020\u51fd\u6570","text":"
      Android(addr=None)\n

      \u53c2\u6570\uff1a - addr (tuple, optional): (HOST, PORT) \u5730\u5740\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u73af\u5883\u53d8\u91cf AP_HOST \u548c AP_PORT

      \u73af\u5883\u53d8\u91cf\uff1a - AP_HOST - \u670d\u52a1\u5668\u4e3b\u673a\u5730\u5740 - AP_PORT - \u670d\u52a1\u5668\u7aef\u53e3 - AP_HANDSHAKE - \u8ba4\u8bc1\u4ee4\u724c

      "},{"location":"qsl4a/core/android-base/#_3","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/android-base/#_rpc","title":"_rpc()","text":"

      \u8c03\u7528 Android \u51fd\u6570\u7684\u5185\u90e8 RPC \u65b9\u6cd5\u3002

      _rpc(method, *args)\n

      \u53c2\u6570\uff1a - method (str): \u8981\u8c03\u7528\u7684\u65b9\u6cd5\u540d - *args: \u65b9\u6cd5\u7684\u53ef\u53d8\u53c2\u6570

      \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4\uff0c\u5305\u542b\u4ee5\u4e0b\u5b57\u6bb5\uff1a - id (int): \u8bf7\u6c42 ID - result: \u65b9\u6cd5\u8fd4\u56de\u503c - error (str or None): \u9519\u8bef\u4fe1\u606f\uff08\u5982\u679c\u5931\u8d25\uff09

      "},{"location":"qsl4a/core/android-base/#getattr","title":"getattr()","text":"

      \u52a8\u6001\u65b9\u6cd5\u5206\u53d1\u5668\u3002\u6240\u6709 Android \u65b9\u6cd5\u90fd\u901a\u8fc7\u5c5e\u6027\u67e5\u627e\u8bbf\u95ee\u3002

      # \u4ee5\u4e0b\u4e24\u79cd\u65b9\u5f0f\u7b49\u4ef7\uff1a\ndroid.makeToast(\"Hello\")\ndroid._rpc(\"makeToast\", \"Hello\")\n
      "},{"location":"qsl4a/core/android-base/#androidpy","title":"\u72ec\u7acb\u51fd\u6570\uff08android.py\uff09","text":"

      \u4f7f\u7528\u7b80\u5316\u7684 android \u6a21\u5757\u65f6\uff1a

      "},{"location":"qsl4a/core/android-base/#jsla","title":"jsla()","text":"

      \u53d1\u9001 JSON-RPC \u8bf7\u6c42\u5e76\u8fd4\u56de\u539f\u59cb\u54cd\u5e94\u3002

      jsla(method, *params)\n

      \u8fd4\u56de\uff1a JSON \u5b57\u7b26\u4e32\u54cd\u5e94

      "},{"location":"qsl4a/core/android-base/#rsla","title":"rsla()","text":"

      \u53d1\u9001\u8bf7\u6c42\u5e76\u4ec5\u8fd4\u56de\u7ed3\u679c\u3002

      rsla(method, *params)\n

      \u8fd4\u56de\uff1a RPC \u8c03\u7528\u7684\u7ed3\u679c\u503c

      "},{"location":"qsl4a/core/android-base/#esla","title":"esla()","text":"

      \u53d1\u9001\u8bf7\u6c42\uff0c\u9519\u8bef\u65f6\u629b\u51fa\u5f02\u5e38\u3002

      esla(method, *params)\n

      \u629b\u51fa\uff1a \u5982\u679c error \u5b57\u6bb5\u4e0d\u4e3a None \u5219\u629b\u51fa\u5f02\u5e38

      "},{"location":"qsl4a/core/android-base/#nsla","title":"nsla()","text":"

      \u53d1\u9001\u8bf7\u6c42\u5e76\u8fd4\u56de Result \u547d\u540d\u5143\u7ec4\u3002

      nsla(method, *params)\n

      \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4

      "},{"location":"qsl4a/core/android-base/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/android-base/#_5","title":"\u57fa\u672c\u8fde\u63a5","text":"
      import androidhelper\n\n# \u8fde\u63a5\u5230 Android \u8fd0\u884c\u65f6\ndroid = androidhelper.Android()\n\n# \u901a\u8fc7\u663e\u793a toast \u6765\u68c0\u67e5\u8fde\u63a5\ndroid.makeToast(\"Connected!\")\n
      "},{"location":"qsl4a/core/android-base/#_6","title":"\u9519\u8bef\u5904\u7406","text":"
      result = droid.someMethod()\nif result.error:\n    print(f\"Error: {result.error}\")\nelse:\n    print(f\"Success: {result.result}\")\n
      "},{"location":"qsl4a/core/android-base/#rpc","title":"\u76f4\u63a5 RPC \u8c03\u7528","text":"
      # \u76f4\u63a5\u8c03\u7528\u4efb\u610f\u65b9\u6cd5\nresult = droid._rpc(\"makeToast\", \"Hello World\")\n
      "},{"location":"qsl4a/core/events/","title":"\u4e8b\u4ef6\u7cfb\u7edf","text":"

      QSL4A \u63d0\u4f9b\u4e86\u4e00\u4e2a\u4e8b\u4ef6\u7cfb\u7edf\uff0c\u7528\u4e8e\u5904\u7406\u6765\u81ea Android \u7684\u5f02\u6b65\u4e8b\u4ef6\uff0c\u5982\u4f20\u611f\u5668\u66f4\u65b0\u3001\u4f4d\u7f6e\u53d8\u5316\u548c\u81ea\u5b9a\u4e49\u5e7f\u64ad\u3002

      "},{"location":"qsl4a/core/events/#_2","title":"\u4e8b\u4ef6\u57fa\u7840","text":"

      \u4e8b\u4ef6\u5b58\u50a8\u5728\u7f13\u51b2\u533a\u4e2d\uff0c\u53ef\u4ee5\u8f6e\u8be2\u6216\u7b49\u5f85\u3002\u6bcf\u4e2a\u4e8b\u4ef6\u5305\u542b\uff1a - name: \u4e8b\u4ef6\u7c7b\u578b/\u540d\u79f0 - data: \u4e8b\u4ef6\u8d1f\u8f7d\u6570\u636e - time: \u65f6\u95f4\u6233

      "},{"location":"qsl4a/core/events/#_3","title":"\u4e8b\u4ef6\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#eventclearbuffer","title":"eventClearBuffer()","text":"

      \u6e05\u9664\u7f13\u51b2\u533a\u4e2d\u7684\u6240\u6709\u5f85\u5904\u7406\u4e8b\u4ef6\u3002

      eventClearBuffer()\n

      \u8fd4\u56de\uff1a None

      "},{"location":"qsl4a/core/events/#eventpoll","title":"eventPoll()","text":"

      \u8f6e\u8be2\u7f13\u51b2\u533a\u4e2d\u7684\u4e8b\u4ef6\u3002

      eventPoll(number_of_events=1)\n

      \u53c2\u6570\uff1a - number_of_events (int): \u8981\u68c0\u7d22\u7684\u6700\u5927\u4e8b\u4ef6\u6570\uff08\u9ed8\u8ba4\uff1a1\uff09

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\u5217\u8868

      "},{"location":"qsl4a/core/events/#eventwait","title":"eventWait()","text":"

      \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\u3002

      eventWait(timeout=None)\n

      \u53c2\u6570\uff1a - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09\u3002None = \u6c38\u4e45\u7b49\u5f85

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

      "},{"location":"qsl4a/core/events/#eventwaitfor","title":"eventWaitFor()","text":"

      \u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6\u3002

      eventWaitFor(eventName, timeout=None)\n

      \u53c2\u6570\uff1a - eventName (str): \u8981\u7b49\u5f85\u7684\u4e8b\u4ef6\u540d\u79f0 - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

      "},{"location":"qsl4a/core/events/#eventpost","title":"eventPost()","text":"

      \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\u3002

      eventPost(name, data, enqueue=None)\n

      \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e\uff08\u4efb\u610f\u7c7b\u578b\uff09 - enqueue (bool, optional): \u5982\u679c\u4e3a True \u5219\u6dfb\u52a0\u5230\u961f\u5217

      "},{"location":"qsl4a/core/events/#receiveevent","title":"receiveEvent()","text":"

      \u63a5\u6536\u4e8b\u4ef6\uff08\u963b\u585e\uff09\u3002

      receiveEvent()\n

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61

      "},{"location":"qsl4a/core/events/#_4","title":"\u5e7f\u64ad\u4e8b\u4ef6","text":"

      \u6ce8\u518c\u7cfb\u7edf\u5e7f\u64ad\u4e8b\u4ef6\u3002

      "},{"location":"qsl4a/core/events/#eventregisterforbroadcast","title":"eventRegisterForBroadcast()","text":"

      \u6ce8\u518c\u63a5\u6536\u5e7f\u64ad\u4e8b\u4ef6\u3002

      eventRegisterForBroadcast(category, enqueue=True)\n

      \u53c2\u6570\uff1a - category (str): \u5e7f\u64ad\u7c7b\u522b/\u52a8\u4f5c - enqueue (bool): \u6dfb\u52a0\u5230\u4e8b\u4ef6\u961f\u5217

      "},{"location":"qsl4a/core/events/#eventunregisterforbroadcast","title":"eventUnregisterForBroadcast()","text":"

      \u53d6\u6d88\u6ce8\u518c\u5e7f\u64ad\u4e8b\u4ef6\u3002

      eventUnregisterForBroadcast(category)\n
      "},{"location":"qsl4a/core/events/#eventgetbrodcastcategories","title":"eventGetBrodcastCategories()","text":"

      \u83b7\u53d6\u5df2\u6ce8\u518c\u7684\u5e7f\u64ad\u7c7b\u522b\u3002

      eventGetBrodcastCategories()\n

      \u8fd4\u56de\uff1a \u5df2\u6ce8\u518c\u7c7b\u522b\u5217\u8868

      "},{"location":"qsl4a/core/events/#_5","title":"\u4e8b\u4ef6\u5206\u53d1\u5668)","text":""},{"location":"qsl4a/core/events/#starteventdispatcher","title":"startEventDispatcher()","text":"

      \u6253\u5f00\u4e00\u4e2a\u53ef\u4ee5\u8bfb\u53d6\u5df2\u53d1\u5e03\u4e8b\u4ef6\u7684\u5957\u63a5\u5b57\u3002)

      startEventDispatcher(port=0)\n

      \u53c2\u6570\uff1a - port (int, optional): \u76d1\u542c\u7684\u7aef\u53e3\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\u9009\u62e9\uff09

      \u8fd4\u56de\uff1a \u6b63\u5728\u76d1\u542c\u7684\u7aef\u53e3\u53f7

      "},{"location":"qsl4a/core/events/#stopeventdispatcher","title":"stopEventDispatcher()","text":"

      \u505c\u6b62\u4e8b\u4ef6\u670d\u52a1\u5668\u3002)

      stopEventDispatcher()\n
      "},{"location":"qsl4a/core/events/#_6","title":"\u5df2\u5e9f\u5f03\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#rpcpostevent","title":"rpcPostEvent()","text":"

      \u5c06\u4e8b\u4ef6\u53d1\u5e03\u5230\u4e8b\u4ef6\u961f\u5217\u3002\uff08\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 eventPost\uff09

      rpcPostEvent(name, data)\n

      \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e

      "},{"location":"qsl4a/core/events/#_7","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/events/#_8","title":"\u57fa\u672c\u4e8b\u4ef6\u8f6e\u8be2","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6e05\u9664\u65e7\u4e8b\u4ef6\ndroid.eventClearBuffer()\n\n# \u8f6e\u8be2\u4e8b\u4ef6\nevents = droid.eventPoll(5).result\nfor event in events:\n    print(f\"Event: {event['name']}, Data: {event['data']}\")\n
      "},{"location":"qsl4a/core/events/#_9","title":"\u7b49\u5f85\u4e8b\u4ef6","text":"
      # \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\uff0c\u5e26\u8d85\u65f6\nevent = droid.eventWait(timeout=10).result\nif event:\n    print(f\"Got event: {event['name']}\")\n
      "},{"location":"qsl4a/core/events/#_10","title":"\u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6","text":"
      # \u7b49\u5f85\u4f20\u611f\u5668\u4e8b\u4ef6\nevent = droid.eventWaitFor('screen', timeout=5).result\nif event:\n    print(f\"Screen event: {event['data']}\")\n
      "},{"location":"qsl4a/core/events/#_11","title":"\u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6","text":"
      # \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\ndroid.eventPost('my_event', {'key': 'value'})\n\n# \u7b49\u5f85\u5b83\nevent = droid.eventWaitFor('my_event', timeout=1).result\n
      "},{"location":"qsl4a/core/events/#_12","title":"\u5e7f\u64ad\u63a5\u6536\u5668","text":"
      # \u6ce8\u518c\u5c4f\u5e55\u5f00\u5173\u4e8b\u4ef6\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_ON')\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_OFF')\n\n# \u7b49\u5f85\u5c4f\u5e55\u4e8b\u4ef6\nwhile True:\n    event = droid.receiveEvent().result\n    if event['name'] == 'android.intent.action.SCREEN_ON':\n        print(\"Screen turned on\")\n    elif event['name'] == 'android.intent.action.SCREEN_OFF':\n        print(\"Screen turned off\")\n
      "},{"location":"qsl4a/core/events/#_13","title":"\u4f20\u611f\u5668\u4e8b\u4ef6\u5904\u7406","text":"
      # \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u5904\u7406\u4f20\u611f\u5668\u4e8b\u4ef6\nfor _ in range(100):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'sensors':\n        data = event['data']\n        print(f\"Accel: {data['xforce']}, {data['yforce']}, {data['zforce']}\")\n\ndroid.stopSensing()\n
      "},{"location":"qsl4a/core/events/#_14","title":"\u5e38\u89c1\u4e8b\u4ef6\u7c7b\u578b","text":"\u4e8b\u4ef6\u540d\u79f0 \u63cf\u8ff0 \u6765\u6e90 sensors \u4f20\u611f\u5668\u6570\u636e\u66f4\u65b0 startSensing* location GPS \u4f4d\u7f6e\u66f4\u65b0 startLocating phone \u7535\u8bdd\u72b6\u6001\u53d8\u5316 startTrackingPhoneState signal \u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316 startTrackingSignalStrength screen \u622a\u56fe\u5c31\u7eea fullGetScreenShot dialog \u5bf9\u8bdd\u6846\u54cd\u5e94 dialogShow*"},{"location":"qsl4a/core/events/#_15","title":"\u4e8b\u4ef6\u6570\u636e\u7ed3\u6784","text":"
      {\n    'name': 'event_name',\n    'data': {\n        # \u4e8b\u4ef6\u7279\u5b9a\u6570\u636e\n    },\n    'time': 1234567890  # \u65f6\u95f4\u6233\n}\n
      "},{"location":"qsl4a/core/intent/","title":"Intent \u7cfb\u7edf","text":"

      Android Intent \u7528\u4e8e\u542f\u52a8\u6d3b\u52a8\u3001\u53d1\u9001\u5e7f\u64ad\u548c\u5e94\u7528\u95f4\u901a\u4fe1\u3002QSL4A \u901a\u8fc7 Intent \u6a21\u5757\u63d0\u4f9b\u5b8c\u6574\u7684 Intent \u652f\u6301\u3002

      "},{"location":"qsl4a/core/intent/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
      import androidhelper\ndon = androidhelper.Android()\n
      "},{"location":"qsl4a/core/intent/#intent_1","title":"Intent \u5e38\u91cf","text":"

      \u901a\u8fc7 droid.Intent \u8bbf\u95ee\uff1a

      "},{"location":"qsl4a/core/intent/#_2","title":"\u64cd\u4f5c","text":"\u5e38\u91cf \u503c \u7528\u9014 ACTION_MAIN android.intent.action.MAIN \u5e94\u7528\u5165\u53e3\u70b9 ACTION_VIEW android.intent.action.VIEW \u67e5\u770b\u5185\u5bb9 ACTION_EDIT android.intent.action.EDIT \u7f16\u8f91\u5185\u5bb9 ACTION_PICK android.intent.action.PICK \u9009\u62e9\u9879\u76ee ACTION_SEND android.intent.action.SEND \u5206\u4eab\u5185\u5bb9 ACTION_SEARCH android.intent.action.SEARCH \u641c\u7d22"},{"location":"qsl4a/core/intent/#_3","title":"\u6807\u5fd7","text":"\u5e38\u91cf \u503c \u7528\u9014 FLAG_ACTIVITY_NEW_TASK 268435456 \u542f\u52a8\u65b0\u4efb\u52a1 FLAG_ACTIVITY_CLEAR_TASK 32768 \u6e05\u9664\u4efb\u52a1\u5806\u6808 FLAG_ACTIVITY_NEW_DOCUMENT 524288 \u65b0\u6587\u6863\u6a21\u5f0f"},{"location":"qsl4a/core/intent/#_4","title":"\u9644\u52a0\u6570\u636e","text":"\u5e38\u91cf \u7528\u9014 EXTRA_TEXT \u6587\u672c\u5185\u5bb9 EXTRA_STREAM \u6587\u4ef6 URI EXTRA_SUBJECT \u4e3b\u9898\u884c EXTRA_EMAIL \u7535\u5b50\u90ae\u4ef6\u5730\u5740"},{"location":"qsl4a/core/intent/#_5","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/intent/#makeintent","title":"makeIntent()","text":"

      \u521b\u5efa Intent \u5bf9\u8c61\u3002

      makeIntent(action, uri=None, type=None, extras=None, categories=None,\n           packagename=None, classname=None, flags=None)\n

      \u53c2\u6570\uff1a - action (str): Intent \u64cd\u4f5c\uff08\u4f8b\u5982 droid.Intent.ACTION_VIEW\uff09 - uri (str, optional): \u6570\u636e URI - type (str, optional): MIME \u7c7b\u578b - extras (dict, optional): \u9644\u52a0\u6570\u636e - categories (list, optional): Intent \u7c7b\u522b - packagename (str, optional): \u76ee\u6807\u5305 - classname (str, optional): \u76ee\u6807\u7c7b - flags (int, optional): Intent \u6807\u5fd7

      \u8fd4\u56de\uff1a Intent \u5bf9\u8c61

      "},{"location":"qsl4a/core/intent/#startactivityintent","title":"startActivityIntent()","text":"

      \u4f7f\u7528 Intent \u542f\u52a8 Activity\u3002

      startActivityIntent(intent, wait=None)\n

      \u53c2\u6570\uff1a - intent: makeIntent() \u8fd4\u56de\u7684 Intent \u5bf9\u8c61 - wait (bool, optional): \u963b\u585e\u76f4\u5230\u6d3b\u52a8\u5173\u95ed

      "},{"location":"qsl4a/core/intent/#startactivityforresultintent","title":"startActivityForResultIntent()","text":"

      \u542f\u52a8\u6d3b\u52a8\u5e76\u7b49\u5f85\u7ed3\u679c\u3002

      startActivityForResultIntent(intent)\n

      \u8fd4\u56de\uff1a Activity \u7ed3\u679c

      "},{"location":"qsl4a/core/intent/#sendbroadcastintent","title":"sendBroadcastIntent()","text":"

      \u53d1\u9001\u5e7f\u64ad\u3002

      sendBroadcastIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#view","title":"view()","text":"

      \u901a\u8fc7 URI \u67e5\u770b\u5185\u5bb9\u3002

      view(uri, type=None, extras=None)\n
      "},{"location":"qsl4a/core/intent/#pick","title":"pick()","text":"

      \u4ece URI \u9009\u62e9\u5185\u5bb9\u3002

      pick(uri)\n
      "},{"location":"qsl4a/core/intent/#intent_2","title":"\u5e38\u89c1 Intent \u65b9\u6cd5)","text":""},{"location":"qsl4a/core/intent/#scanbarcode","title":"scanBarcode()","text":"

      \u542f\u52a8\u6761\u7801\u626b\u63cf\u5668\u3002

      scanBarcode()\n

      \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/core/intent/#send","title":"send()","text":"

      \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u5185\u5bb9\u3002

      send(type, content)\n

      \u53c2\u6570\uff1a - type (str): MIME \u7c7b\u578b - content (str): \u8981\u5206\u4eab\u7684\u5185\u5bb9

      "},{"location":"qsl4a/core/intent/#sendtext","title":"sendText()","text":"

      \u53d1\u9001\u6587\u672c\u5185\u5bb9\u3002

      sendText(text)\n

      \u53c2\u6570\uff1a - text (str): \u8981\u53d1\u9001\u7684\u6587\u672c

      "},{"location":"qsl4a/core/intent/#sendemail","title":"sendEmail()","text":"

      \u53d1\u9001\u7535\u5b50\u90ae\u4ef6\u3002

      sendEmail(to, subject, body, attachment=None)\n

      \u53c2\u6570\uff1a - to (str or list): \u6536\u4ef6\u4eba\u7535\u5b50\u90ae\u4ef6\u5730\u5740 - subject (str): \u7535\u5b50\u90ae\u4ef6\u4e3b\u9898 - body (str): \u7535\u5b50\u90ae\u4ef6\u6b63\u6587 - attachment (str, optional): \u9644\u4ef6\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/core/intent/#pathtouri","title":"pathToUri()","text":"

      \u5c06\u6587\u4ef6\u8def\u5f84\u8f6c\u6362\u4e3a\u5185\u5bb9 URI\u3002

      pathToUri(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5185\u5bb9 URI \u5b57\u7b26\u4e32

      "},{"location":"qsl4a/core/intent/#openfile","title":"openFile()","text":"

      \u7528\u9002\u5f53\u7684\u5e94\u7528\u7a0b\u5e8f\u6253\u5f00\u6587\u4ef6\u3002

      openFile(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u6253\u5f00\u7684\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/core/intent/#sendfile","title":"sendFile()","text":"

      \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u6587\u4ef6\u3002

      sendFile(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u53d1\u9001\u7684\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/core/intent/#getpathtype","title":"getPathType()","text":"

      \u83b7\u53d6\u6587\u4ef6\u8def\u5f84\u7684 MIME \u7c7b\u578b\u3002

      getPathType(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a MIME \u7c7b\u578b\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/core/intent/#viewmap","title":"viewMap()","text":"

      \u5728\u6307\u5b9a\u4f4d\u7f6e\u6253\u5f00\u5730\u56fe\u3002

      viewMap(latitude, longitude)\n

      \u53c2\u6570\uff1a - latitude (float): \u7eac\u5ea6 - longitude (float): \u7ecf\u5ea6

      "},{"location":"qsl4a/core/intent/#viewcontacts","title":"viewContacts()","text":"

      \u6253\u5f00\u8054\u7cfb\u4eba\u5e94\u7528\u3002

      viewContacts()\n
      "},{"location":"qsl4a/core/intent/#search","title":"search()","text":"

      \u6267\u884c\u7f51\u7edc\u641c\u7d22\u3002

      search(query)\n

      \u53c2\u6570\uff1a - query (str): \u641c\u7d22\u67e5\u8be2

      "},{"location":"qsl4a/core/intent/#viewhtml","title":"viewHtml()","text":"

      \u67e5\u770b HTML \u5185\u5bb9\u3002

      viewHtml(content, encoding=None)\n

      \u53c2\u6570\uff1a - content (str): HTML \u5185\u5bb9 - encoding (str, optional): \u5b57\u7b26\u7f16\u7801

      "},{"location":"qsl4a/core/intent/#webviewshow","title":"webViewShow()","text":"

      \u5728 WebView \u4e2d\u663e\u793a\u7f51\u9875\u5185\u5bb9\u3002\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 viewHtml\u3002

      webViewShow(url)\n

      \u53c2\u6570\uff1a - url (str): \u7f51\u9875 URL

      "},{"location":"qsl4a/core/intent/#editoropen","title":"editorOpen()","text":"

      \u6253\u5f00\u6587\u672c\u7f16\u8f91\u5668\u3002

      editorOpen(path=None, create=False)\n

      \u53c2\u6570\uff1a - path (str, optional): \u8981\u7f16\u8f91\u7684\u6587\u4ef6\u8def\u5f84 - create (bool, optional): \u5982\u679c\u4e0d\u5b58\u5728\u5219\u521b\u5efa

      "},{"location":"qsl4a/core/intent/#uri","title":"\u8f85\u52a9\u7c7b\uff1aUri","text":"

      \u521b\u5efa Intent \u7684 URI \u5bf9\u8c61\uff1a

      from androidhelper.Intent import Uri\n\nuri = Uri(\"file:///sdcard/test.txt\")\n
      "},{"location":"qsl4a/core/intent/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/intent/#_7","title":"\u6253\u5f00\u7f51\u9875","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"http://www.example.com\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_8","title":"\u5206\u4eab\u6587\u672c","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_TEXT: \"Hello from QPython!\",\n        droid.Intent.EXTRA_SUBJECT: \"Test\"\n    },\n    type=\"text/plain\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_9","title":"\u6253\u5f00\u6587\u4ef6","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"file:///sdcard/document.pdf\",\n    type=\"application/pdf\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_10","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":"
      result = droid.pickContact()\ncontact_uri = result.result\n
      "},{"location":"qsl4a/core/intent/#_11","title":"\u53d1\u9001\u7535\u5b50\u90ae\u4ef6","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_EMAIL: [\"test@example.com\"],\n        droid.Intent.EXTRA_SUBJECT: \"Hello\",\n        droid.Intent.EXTRA_TEXT: \"Message body\"\n    },\n    type=\"message/rfc822\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_12","title":"\u6253\u5f00\u5e94\u7528","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_MAIN,\n    packagename=\"com.android.settings\",\n    classname=\"com.android.settings.Settings\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/hardware/bluetooth/","title":"\u84dd\u7259 API","text":"

      \u63a7\u5236\u84dd\u7259\u9002\u914d\u5668\u5e76\u4e0e\u84dd\u7259\u8bbe\u5907\u901a\u4fe1\u3002

      "},{"location":"qsl4a/hardware/bluetooth/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/hardware/bluetooth/#togglebluetoothstate","title":"toggleBluetoothState()","text":"

      \u6253\u5f00/\u5173\u95ed\u84dd\u7259\u3002

      toggleBluetoothState(enabled=None, prompt=True)\n

      \u53c2\u6570\uff1a - enabled (bool): True=\u5f00\uff0cFalse=\u5173\uff0cNone=\u5207\u6362 - prompt (bool): \u663e\u793a\u7528\u6237\u63d0\u793a

      "},{"location":"qsl4a/hardware/bluetooth/#checkbluetoothstate","title":"checkBluetoothState()","text":"

      \u68c0\u67e5\u84dd\u7259\u662f\u5426\u5df2\u542f\u7528\u3002

      checkBluetoothState()\n

      \u8fd4\u56de\uff1a True/False

      "},{"location":"qsl4a/hardware/bluetooth/#getlocalname","title":"GetLocalName()","text":"

      \u83b7\u53d6\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

      GetLocalName()\n
      "},{"location":"qsl4a/hardware/bluetooth/#setlocalname","title":"SetLocalName()","text":"

      \u8bbe\u7f6e\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

      SetLocalName(name)\n
      "},{"location":"qsl4a/hardware/bluetooth/#getscanmode","title":"GetScanMode()","text":"

      \u83b7\u53d6\u53ef\u53d1\u73b0\u6027\u6a21\u5f0f\u3002

      GetScanMode()\n

      \u8fd4\u56de\uff1a - -1: \u5df2\u7981\u7528 - 0: \u4e0d\u53ef\u53d1\u73b0\uff0c\u4e0d\u53ef\u8fde\u63a5 - 1: \u53ef\u8fde\u63a5\uff0c\u4e0d\u53ef\u53d1\u73b0 - 3: \u53ef\u8fde\u63a5\u4e14\u53ef\u53d1\u73b0

      "},{"location":"qsl4a/hardware/bluetooth/#makediscoverable","title":"MakeDiscoverable()","text":"

      \u4f7f\u8bbe\u5907\u53ef\u53d1\u73b0\u3002

      MakeDiscoverable(duration=300)\n

      \u53c2\u6570\uff1a - duration (int): \u53ef\u53d1\u73b0\u7684\u79d2\u6570

      "},{"location":"qsl4a/hardware/bluetooth/#_2","title":"\u53d1\u73b0","text":""},{"location":"qsl4a/hardware/bluetooth/#discoverystart","title":"DiscoveryStart()","text":"

      \u5f00\u59cb\u8bbe\u5907\u53d1\u73b0\u3002

      DiscoveryStart()\n
      "},{"location":"qsl4a/hardware/bluetooth/#discoverycancel","title":"DiscoveryCancel()","text":"

      \u53d6\u6d88\u53d1\u73b0\u3002

      DiscoveryCancel()\n
      "},{"location":"qsl4a/hardware/bluetooth/#getreceiveddevices","title":"GetReceivedDevices()","text":"

      \u83b7\u53d6\u53d1\u73b0\u7684\u8bbe\u5907\u3002

      GetReceivedDevices()\n

      \u8fd4\u56de\uff1a \u8bbe\u5907\u4fe1\u606f\u5b57\u5178\u5217\u8868

      "},{"location":"qsl4a/hardware/bluetooth/#getbondeddevices","title":"GetBondedDevices()","text":"

      \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\u3002

      GetBondedDevices()\n

      \u8fd4\u56de\uff1a \u914d\u5bf9\u8bbe\u5907\u4fe1\u606f\u5217\u8868

      "},{"location":"qsl4a/hardware/bluetooth/#_3","title":"\u8fde\u63a5","text":""},{"location":"qsl4a/hardware/bluetooth/#connect","title":"Connect()","text":"

      \u8fde\u63a5\u5230\u8bbe\u5907\u3002

      Connect(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", address=None)\n

      \u53c2\u6570\uff1a - uuid (str): \u670d\u52a1 UUID - address (str): \u8bbe\u5907\u5730\u5740\uff08None = \u663e\u793a\u9009\u62e9\u5668\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/hardware/bluetooth/#accept","title":"Accept()","text":"

      \u63a5\u53d7\u4f20\u5165\u8fde\u63a5\u3002

      Accept(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", timeout=0)\n
      "},{"location":"qsl4a/hardware/bluetooth/#activeconnections","title":"ActiveConnections()","text":"

      \u68c0\u67e5\u6d3b\u52a8\u8fde\u63a5\u3002

      ActiveConnections()\n
      "},{"location":"qsl4a/hardware/bluetooth/#stop","title":"Stop()","text":"

      \u65ad\u5f00\u8fde\u63a5\u3002

      Stop(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#_4","title":"\u901a\u4fe1","text":""},{"location":"qsl4a/hardware/bluetooth/#write","title":"Write()","text":"

      \u53d1\u9001 ASCII \u6570\u636e\u3002

      Write(ascii, connID=\"\")\n
      "},{"location":"qsl4a/hardware/bluetooth/#writebinary","title":"WriteBinary()","text":"

      \u53d1\u9001\u4e8c\u8fdb\u5236\u6570\u636e\uff08base64 \u7f16\u7801\uff09\u3002

      WriteBinary(base64, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#read","title":"Read()","text":"

      \u8bfb\u53d6 ASCII \u6570\u636e\u3002

      Read(bufferSize=4096, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readbinary","title":"ReadBinary()","text":"

      \u8bfb\u53d6\u4e8c\u8fdb\u5236\u6570\u636e\u3002

      ReadBinary(bufferSize=4096, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readline","title":"ReadLine()","text":"

      \u8bfb\u53d6\u4e00\u884c\u3002

      ReadLine(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readready","title":"ReadReady()","text":"

      \u68c0\u67e5\u662f\u5426\u6709\u53ef\u7528\u6570\u636e\u3002

      ReadReady(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u7528\u84dd\u7259\ndroid.toggleBluetoothState(True)\n\n# \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\ndevices = droid.GetBondedDevices().result\nfor dev in devices:\n    print(f\"{dev['name']}: {dev['address']}\")\n\n# \u8fde\u63a5\u5230\u8bbe\u5907\ndroid.Connect(address=\"00:11:22:33:44:55\")\n\n# \u53d1\u9001\u6570\u636e\ndroid.Write(\"Hello Bluetooth!\")\n\n# \u8bfb\u53d6\u54cd\u5e94\ndata = droid.Read(1024).result\n
      "},{"location":"qsl4a/hardware/camera/","title":"\u76f8\u673a API","text":"

      \u62cd\u6444\u7167\u7247\u548c\u5f55\u5236\u89c6\u9891\u3002

      "},{"location":"qsl4a/hardware/camera/#_1","title":"\u7167\u7247\u62cd\u6444","text":""},{"location":"qsl4a/hardware/camera/#takepicture","title":"takePicture()","text":"

      \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u6444\u7167\u7247\u3002

      takePicture(path=None)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8fd4\u56de\u56fe\u50cf\u6570\u636e

      \u8fd4\u56de\uff1a \u56fe\u50cf\u8def\u5f84\u6216\u56fe\u50cf\u6570\u636e

      "},{"location":"qsl4a/hardware/camera/#cameracapturepicture","title":"cameraCapturePicture()","text":"

      \u4f7f\u7528\u9ad8\u7ea7\u76f8\u673a\u63a7\u5236\u62cd\u6444\u7167\u7247\u3002

      cameraCapturePicture(targetPath=None, cameraId=0, useAutoFocus=True)\n

      \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - useAutoFocus (bool): \u542f\u7528\u81ea\u52a8\u5bf9\u7126

      \u8fd4\u56de\uff1a \u62cd\u6444\u7684\u56fe\u50cf\u8def\u5f84

      "},{"location":"qsl4a/hardware/camera/#camerasettorchmode","title":"cameraSetTorchMode()","text":"

      \u63a7\u5236\u76f8\u673a\u95ea\u5149\u706f/\u624b\u7535\u7b52\u3002

      cameraSetTorchMode(enabled)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u6253\u5f00\uff0cFalse \u5173\u95ed

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/hardware/camera/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

      \u622a\u56fe\u3002

      imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

      "},{"location":"qsl4a/hardware/camera/#_2","title":"\u89c6\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#takevideo","title":"takeVideo()","text":"

      \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\u3002

      takeVideo(path=None, quality=1)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-4\uff09 - 0: 160x120 - 1: 320x240 - 2: 352x288 - 3: 640x480 - 4: 800x480

      "},{"location":"qsl4a/hardware/camera/#recordercapturevideo","title":"recorderCaptureVideo()","text":"

      \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\u3002

      recorderCaptureVideo(targetPath=None, duration=10, cameraId=0, quality=8)\n

      \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - duration (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a10\uff09 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-8\uff0c\u8d8a\u9ad8\u8d8a\u597d\uff09

      \u8fd4\u56de\uff1a \u89c6\u9891\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/hardware/camera/#recordaudio","title":"recordAudio()","text":"

      \u5f55\u5236\u97f3\u9891\u3002

      recordAudio()\n

      \u8fd4\u56de\uff1a \u97f3\u9891\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/hardware/camera/#_3","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

      \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\u3002

      recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

      \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\uff09 - targetPixels (int): \u5206\u8fa8\u7387 - frameRate (int): FPS - bitRate (int): \u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa - autoStart (bool): \u7acb\u5373\u5f00\u59cb

      "},{"location":"qsl4a/hardware/camera/#recorderstart","title":"recorderStart()","text":"

      \u5f00\u59cb\u5f55\u5236\u3002

      recorderStart()\n
      "},{"location":"qsl4a/hardware/camera/#recorderpause","title":"recorderPause()","text":"

      \u6682\u505c\u5f55\u5236\u3002

      recorderPause()\n
      "},{"location":"qsl4a/hardware/camera/#recorderresume","title":"recorderResume()","text":"

      \u6062\u590d\u5f55\u5236\u3002

      recorderResume()\n
      "},{"location":"qsl4a/hardware/camera/#_4","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/camera/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

      \u5f00\u59cb\u97f3\u91cf\u68c0\u6d4b\u3002

      recorderSoundVolumeDetect(interval=100)\n
      "},{"location":"qsl4a/hardware/camera/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

      \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

      recorderSoundVolumeGetDb()\n
      "},{"location":"qsl4a/hardware/camera/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u7167\nphoto_path = droid.takePicture(\"/sdcard/photo.jpg\").result\nprint(f\"Photo saved: {photo_path}\")\n\n# \u4f7f\u7528\u524d\u7f6e\u76f8\u673a\u548c\u81ea\u52a8\u5bf9\u7126\u62cd\u7167\ncamera_path = droid.cameraCapturePicture(\"/sdcard/selfie.jpg\", cameraId=1, useAutoFocus=True).result\nprint(f\"Front camera photo: {camera_path}\")\n\n# \u63a7\u5236\u95ea\u5149\u706f\ndroid.cameraSetTorchMode(True)  # \u6253\u5f00\u95ea\u5149\u706f\n\n# \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\nvideo_path = droid.takeVideo(\"/sdcard/video.mp4\", quality=3).result\nprint(f\"Video saved: {video_path}\")\n\n# \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\nvideo_path = droid.recorderCaptureVideo(\"/sdcard/movie.mp4\", duration=30, cameraId=0, quality=8).result\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n
      "},{"location":"qsl4a/hardware/recorder/","title":"\u97f3\u9891\u5f55\u5236 API","text":"

      \u4ece\u9ea6\u514b\u98ce\u548c\u8bbe\u5907\u5c4f\u5e55\u5f55\u5236\u97f3\u9891\u3002

      "},{"location":"qsl4a/hardware/recorder/#_1","title":"\u97f3\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recordaudio","title":"recordAudio()","text":"

      \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\u3002

      recordAudio()\n

      \u8fd4\u56de\uff1a \u5f55\u5236\u7684\u97f3\u9891\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/hardware/recorder/#recorderstartmicrophone","title":"recorderStartMicrophone()","text":"

      \u5f00\u59cb\u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\u3002

      recorderStartMicrophone(targetPath=None)\n

      \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u5f55\u5236\u7684\u8def\u5f84

      "},{"location":"qsl4a/hardware/recorder/#_2","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

      \u5f00\u59cb\u5e26\u97f3\u9891\u7684\u5c4f\u5e55\u5f55\u5236\u3002

      recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

      \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\u97f3\u9891\uff09 - targetPixels (int): \u76ee\u6807\u5206\u8fa8\u7387\uff08\u50cf\u7d20\uff09 - frameRate (int): \u6bcf\u79d2\u5e27\u6570\uff08\u9ed8\u8ba4\uff1a30\uff09 - bitRate (int): \u89c6\u9891\u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa\u89c6\u9891 - autoStart (bool): \u7acb\u5373\u5f00\u59cb\u5f55\u5236

      \u8fd4\u56de\uff1a \u64cd\u4f5c\u7ed3\u679c

      "},{"location":"qsl4a/hardware/recorder/#recorderstart","title":"recorderStart()","text":"

      \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\uff08\u5f53 autoStart=False \u65f6\uff09\u3002

      recorderStart()\n
      "},{"location":"qsl4a/hardware/recorder/#recorderpause","title":"recorderPause()","text":"

      \u6682\u505c\u6b63\u5728\u8fdb\u884c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

      recorderPause()\n
      "},{"location":"qsl4a/hardware/recorder/#recorderresume","title":"recorderResume()","text":"

      \u6062\u590d\u6682\u505c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

      recorderResume()\n
      "},{"location":"qsl4a/hardware/recorder/#_3","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/recorder/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

      \u5f00\u59cb\u76d1\u63a7\u97f3\u91cf\u7ea7\u522b\u3002

      recorderSoundVolumeDetect(interval=100)\n

      \u53c2\u6570\uff1a - interval (int): \u68c0\u6d4b\u95f4\u9694\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a100\uff09

      "},{"location":"qsl4a/hardware/recorder/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

      \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

      recorderSoundVolumeGetDb()\n

      \u8fd4\u56de\uff1a \u5f53\u524d\u97f3\u91cf\u7ea7\u522b\uff08dB\uff09

      "},{"location":"qsl4a/hardware/recorder/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\nprint(\"Recording audio...\")\naudio_path = droid.recordAudio().result\nprint(f\"Saved to: {audio_path}\")\n\n# \u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\ndroid.recorderStartMicrophone(\"/sdcard/my_recording.mp3\")\ntime.sleep(5)\ndroid.recorderStop()\n\n# \u5e26\u97f3\u9891\u5f55\u5236\u5c4f\u5e55\nprint(\"Starting screen recording...\")\ndroid.recorderStartScreenRecord(\n    path=\"/sdcard/screen_record.mp4\",\n    audio=1,\n    frameRate=30,\n    autoStart=True\n)\ntime.sleep(10)\ndroid.recorderStop()\n\n# \u76d1\u63a7\u97f3\u91cf\ndroid.recorderSoundVolumeDetect(interval=100)\ntime.sleep(3)\nvolume = droid.recorderSoundVolumeGetDb().result\nprint(f\"Current volume: {volume} dB\")\n
      "},{"location":"qsl4a/hardware/usbserial/","title":"USB \u4e3b\u673a\u4e32\u884c API","text":"

      \u4e0e USB \u4e32\u884c\u8bbe\u5907\u901a\u4fe1\uff08\u9700\u8981 USB OTG \u652f\u6301\u548c Android 3.1+\uff09\u3002

      "},{"location":"qsl4a/hardware/usbserial/#usb","title":"USB \u4e32\u884c\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialopen","title":"usbHostSerialOpen()","text":"

      \u6253\u5f00\u4e0e USB \u4e32\u884c\u8bbe\u5907\u7684\u8fde\u63a5\u3002

      usbHostSerialOpen(device, baudRate=9600)\n

      \u53c2\u6570\uff1a - device (str): USB \u8bbe\u5907\u8def\u5f84\u6216\u6807\u8bc6\u7b26 - baudRate (int): \u6ce2\u7279\u7387\uff08\u9ed8\u8ba4\uff1a9600\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u6253\u5f00\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialclose","title":"usbHostSerialClose()","text":"

      \u5173\u95ed USB \u4e32\u884c\u8fde\u63a5\u3002

      usbHostSerialClose()\n
      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialread","title":"usbHostSerialRead()","text":"

      \u4ece USB \u4e32\u884c\u8bfb\u53d6\u6570\u636e\u3002

      usbHostSerialRead(bufferSize=1024)\n

      \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570\uff08\u9ed8\u8ba4\uff1a1024\uff09

      \u8fd4\u56de\uff1a \u8bfb\u53d6\u7684\u6570\u636e\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwrite","title":"usbHostSerialWrite()","text":"

      \u5411 USB \u4e32\u884c\u5199\u5165\u6570\u636e\u3002

      usbHostSerialWrite(data)\n

      \u53c2\u6570\uff1a - data (str): \u8981\u5199\u5165\u7684\u5b57\u7b26\u4e32\u6570\u636e

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialavailable","title":"usbHostSerialAvailable()","text":"

      \u68c0\u67e5\u662f\u5426\u6709\u53ef\u8bfb\u53d6\u7684\u6570\u636e\u3002

      usbHostSerialAvailable()\n

      \u8fd4\u56de\uff1a \u53ef\u7528\u5b57\u8282\u6570

      "},{"location":"qsl4a/hardware/usbserial/#_1","title":"\u914d\u7f6e\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetbaudrate","title":"usbHostSerialSetBaudRate()","text":"

      \u8bbe\u7f6e\u6ce2\u7279\u7387\u3002

      usbHostSerialSetBaudRate(baudRate)\n

      \u53c2\u6570\uff1a - baudRate (int): \u6ce2\u7279\u7387

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetdatabits","title":"usbHostSerialSetDataBits()","text":"

      \u8bbe\u7f6e\u6570\u636e\u4f4d\uff085\u30016\u30017 \u6216 8\uff09\u3002

      usbHostSerialSetDataBits(dataBits)\n

      \u53c2\u6570\uff1a - dataBits (int): \u6570\u636e\u4f4d\uff085-8\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetstopbits","title":"usbHostSerialSetStopBits()","text":"

      \u8bbe\u7f6e\u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09\u3002

      usbHostSerialSetStopBits(stopBits)\n

      \u53c2\u6570\uff1a - stopBits (float): \u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetparity","title":"usbHostSerialSetParity()","text":"

      \u8bbe\u7f6e\u6821\u9a8c\u4f4d\uff08\u65e0\u3001\u5947\u3001\u5076\u3001\u6807\u8bb0\u3001\u7a7a\u683c\uff09\u3002

      usbHostSerialSetParity(parity)\n

      \u53c2\u6570\uff1a - parity (str): \u6821\u9a8c\u6a21\u5f0f\uff08'none'\u3001'odd'\u3001'even'\u3001'mark'\u3001'space'\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetflowcontrol","title":"usbHostSerialSetFlowControl()","text":"

      \u8bbe\u7f6e\u6d41\u63a7\u5236\uff08\u65e0\u3001\u786c\u4ef6\u3001\u8f6f\u4ef6\uff09\u3002

      usbHostSerialSetFlowControl(flowControl)\n

      \u53c2\u6570\uff1a - flowControl (str): \u6d41\u63a7\u5236\u6a21\u5f0f\uff08'none'\u3001'hardware'\u3001'software'\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialreadhex","title":"usbHostSerialReadHex()","text":"

      \u4ee5\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u8bfb\u53d6\u6570\u636e\u3002

      usbHostSerialReadHex(bufferSize=1024)\n

      \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570

      \u8fd4\u56de\uff1a \u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwritehex","title":"usbHostSerialWriteHex()","text":"

      \u4ece\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u5199\u5165\u6570\u636e\u3002

      usbHostSerialWriteHex(hexString)\n

      \u53c2\u6570\uff1a - hexString (str): \u8981\u5199\u5165\u7684\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/hardware/usbserial/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6253\u5f00 USB \u4e32\u884c\u8fde\u63a5\nif droid.usbHostSerialOpen(\"/dev/bus/usb/001/001\", 115200).result:\n    print(\"USB serial opened\")\n\n    # \u5199\u5165\u6570\u636e\n    droid.usbHostSerialWrite(\"AT\\r\")\n\n    # \u8bfb\u53d6\u54cd\u5e94\n    response = droid.usbHostSerialRead(1024).result\n    print(f\"Response: {response}\")\n\n    # \u6216\u4f7f\u7528\u5341\u516d\u8fdb\u5236\n    droid.usbHostSerialWriteHex(\"41540D0A\")  # \"AT\\r\\n\"\n\n    # \u5173\u95ed\u8fde\u63a5\n    droid.usbHostSerialClose()\n

      \u6ce8\u610f\uff1a USB \u4e32\u884c\u9700\u8981\uff1a - Android 3.1+ (API 12) - USB OTG \u7ebf/\u9002\u914d\u5668 - \u8bbe\u5907\u4e0a\u7684 USB \u4e3b\u673a\u6a21\u5f0f\u652f\u6301 - \u517c\u5bb9\u7684\u4e32\u884c\u8bbe\u5907

      "},{"location":"qsl4a/hardware/webcam/","title":"\u7f51\u7edc\u6444\u50cf\u5934 API","text":"

      \u4f7f\u7528 MJPEG \u4ece\u8bbe\u5907\u76f8\u673a\u6d41\u5f0f\u4f20\u8f93\u89c6\u9891\u3002

      "},{"location":"qsl4a/hardware/webcam/#mjpeg","title":"MJPEG \u6d41\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#webcamstart","title":"webcamStart()","text":"

      \u4ece\u7f51\u7edc\u6444\u50cf\u5934\u542f\u52a8 MJPEG \u6d41\u3002

      webcamStart(resolutionLevel=0, jpegQuality=20, port=0)\n

      \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf 1-100\uff08\u9ed8\u8ba4\uff1a20\uff09 - port (int): \u7aef\u53e3\u53f7\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\uff09

      \u8fd4\u56de\uff1a \u6d41\u7684 (\u5730\u5740, \u7aef\u53e3) \u5143\u7ec4

      "},{"location":"qsl4a/hardware/webcam/#webcamadjustquality","title":"webcamAdjustQuality()","text":"

      \u8c03\u6574\u6d3b\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u7684\u8d28\u91cf\u3002

      webcamAdjustQuality(resolutionLevel=0, jpegQuality=20)\n

      \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b - jpegQuality (int): JPEG \u8d28\u91cf 1-100

      "},{"location":"qsl4a/hardware/webcam/#webcamstop","title":"webcamStop()","text":"

      \u505c\u6b62\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u3002

      webcamStop()\n
      "},{"location":"qsl4a/hardware/webcam/#_1","title":"\u76f8\u673a\u9884\u89c8\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#camerastartpreview","title":"cameraStartPreview()","text":"

      \u5f00\u59cb\u5e26\u4e8b\u4ef6\u751f\u6210\u7684\u76f8\u673a\u9884\u89c8\u6a21\u5f0f\u3002

      cameraStartPreview(resolutionLevel=0, jpegQuality=20, filepath=None)\n

      \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf\uff08\u9ed8\u8ba4\uff1a20\uff09 - filepath (str, optional): \u4fdd\u5b58\u9884\u89c8\u5e27\u7684\u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      \u6ce8\u610f\uff1a \u751f\u6210\u5e26\u6709\u5e27\u6570\u636e\u7684 'preview' \u4e8b\u4ef6\u3002

      "},{"location":"qsl4a/hardware/webcam/#camerastoppreview","title":"cameraStopPreview()","text":"

      \u505c\u6b62\u76f8\u673a\u9884\u89c8\u3002

      cameraStopPreview()\n
      "},{"location":"qsl4a/hardware/webcam/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\nstream_info = droid.webcamStart(\n    resolutionLevel=0,\n    jpegQuality=30,\n    port=8080\n).result\nprint(f\"Stream available at {stream_info[0]}:{stream_info[1]}\")\n\n# \u6d41\u5f0f\u4f20\u8f93\u65f6\u8c03\u6574\u8d28\u91cf\ntime.sleep(5)\ndroid.webcamAdjustQuality(resolutionLevel=1, jpegQuality=50)\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.webcamStop()\n\n# \u6216\u4f7f\u7528\u9884\u89c8\u6a21\u5f0f\nprint(\"Starting preview...\")\ndroid.cameraStartPreview()\n\n# \u7b49\u5f85\u9884\u89c8\u4e8b\u4ef6\nfor i in range(10):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'preview':\n        print(f\"Got preview frame: {event['data']}\")\n\ndroid.cameraStopPreview()\n
      "},{"location":"qsl4a/media/image/","title":"\u56fe\u50cf\u5904\u7406 API","text":"

      \u538b\u7f29\u548c\u5904\u7406\u56fe\u50cf\u3002

      "},{"location":"qsl4a/media/image/#_1","title":"\u56fe\u50cf\u538b\u7f29","text":""},{"location":"qsl4a/media/image/#imagecompress","title":"imageCompress()","text":"

      \u538b\u7f29\u56fe\u50cf\u6587\u4ef6\u3002

      imageCompress(srcPath, destPath, targetByteSize=0, targetWidth=0, targetHeight=0)\n

      \u53c2\u6570\uff1a - srcPath (str): \u6e90\u56fe\u50cf\u8def\u5f84 - destPath (str): \u8f93\u51fa\u8def\u5f84 - targetByteSize (int): \u76ee\u6807\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff080 = \u65e0\u9650\u5236\uff09 - targetWidth (int): \u76ee\u6807\u5bbd\u5ea6\uff080 = \u539f\u59cb\uff09 - targetHeight (int): \u76ee\u6807\u9ad8\u5ea6\uff080 = \u539f\u59cb\uff09

      \u8fd4\u56de\uff1a \u538b\u7f29\u540e\u7684\u56fe\u50cf\u8def\u5f84

      "},{"location":"qsl4a/media/image/#_2","title":"\u622a\u56fe","text":""},{"location":"qsl4a/media/image/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

      \u622a\u53d6\u5c4f\u5e55\u3002

      imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

      \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

      \u8fd4\u56de\uff1a \u622a\u56fe\u8def\u5f84

      "},{"location":"qsl4a/media/image/#_3","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/image/#videoplay","title":"videoPlay()","text":"

      \u5728\u5168\u5c4f\u6a21\u5f0f\u4e0b\u64ad\u653e\u89c6\u9891\u6587\u4ef6\u3002

      videoPlay(path, wait=True)\n

      \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

      "},{"location":"qsl4a/media/image/#_4","title":"\u6761\u7801\u626b\u63cf","text":""},{"location":"qsl4a/media/image/#scanbarcodefromimage","title":"scanBarcodeFromImage()","text":"

      \u4ece\u56fe\u50cf\u6587\u4ef6\u626b\u63cf\u6761\u7801/\u4e8c\u7ef4\u7801\u3002

      scanBarcodeFromImage(path, compressRatio=0, x=0, y=0, width=0, height=0)\n

      \u53c2\u6570\uff1a - path (str): \u56fe\u50cf\u6587\u4ef6\u8def\u5f84 - compressRatio (int): \u538b\u7f29\u6bd4\uff080 = \u4e0d\u538b\u7f29\uff09 - x, y, width, height (int): \u8981\u626b\u63cf\u7684\u533a\u57df\uff080 = \u5b8c\u6574\u56fe\u50cf\uff09

      \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5185\u5bb9

      "},{"location":"qsl4a/media/image/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n\n# \u538b\u7f29\u56fe\u50cf\ncompressed = droid.imageCompress(\n    \"/sdcard/large_photo.jpg\",\n    \"/sdcard/compressed.jpg\",\n    targetByteSize=102400,  # \u76ee\u6807\u7ea6 100KB\n    targetWidth=1920,\n    targetHeight=1080\n).result\nprint(f\"Saved: {compressed}\")\n\n# \u64ad\u653e\u89c6\u9891\nvideo_path = \"/sdcard/movie.mp4\"\ndroid.videoPlay(video_path, wait=True)\n\n# \u4ece\u56fe\u50cf\u626b\u63cf\u6761\u7801\nresult = droid.scanBarcodeFromImage(\"/sdcard/qr_code.png\").result\nprint(f\"Barcode: {result}\")\n
      "},{"location":"qsl4a/media/mediaplayer/","title":"\u5a92\u4f53\u64ad\u653e\u5668 API","text":"

      \u63a7\u5236\u97f3\u9891\u548c\u89c6\u9891\u64ad\u653e\u3002

      "},{"location":"qsl4a/media/mediaplayer/#_1","title":"\u64ad\u653e\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplay","title":"mediaPlay()","text":"

      \u64ad\u653e\u5a92\u4f53\u6587\u4ef6\u3002

      mediaPlay(url, tag=\"default\", play=True)\n

      \u53c2\u6570\uff1a - url (str): \u5a92\u4f53\u6587\u4ef6\u8def\u5f84\u6216 URL - tag (str): \u64ad\u653e\u5668\u6807\u8bc6\u7b26 - play (bool): \u81ea\u52a8\u5f00\u59cb\u64ad\u653e

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaystart","title":"mediaPlayStart()","text":"

      \u5f00\u59cb\u64ad\u653e\u3002

      mediaPlayStart(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplaypause","title":"mediaPlayPause()","text":"

      \u6682\u505c\u64ad\u653e\u3002

      mediaPlayPause(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplayclose","title":"mediaPlayClose()","text":"

      \u5173\u95ed\u64ad\u653e\u5668\u3002

      mediaPlayClose(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplayseek","title":"mediaPlaySeek()","text":"

      \u8df3\u8f6c\u5230\u4f4d\u7f6e\u3002

      mediaPlaySeek(msec, tag=\"default\")\n

      \u53c2\u6570\uff1a - msec (int): \u4f4d\u7f6e\uff08\u6beb\u79d2\uff09

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaysetlooping","title":"mediaPlaySetLooping()","text":"

      \u8bbe\u7f6e\u5faa\u73af\u6a21\u5f0f\u3002

      mediaPlaySetLooping(enabled, tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#_2","title":"\u64ad\u653e\u5668\u4fe1\u606f","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplayinfo","title":"mediaPlayInfo()","text":"

      \u83b7\u53d6\u64ad\u653e\u4fe1\u606f\u3002

      mediaPlayInfo(tag=\"default\")\n

      \u8fd4\u56de\uff1a \u5305\u542b\u65f6\u957f\u3001\u4f4d\u7f6e\u7b49\u7684\u5b57\u5178

      "},{"location":"qsl4a/media/mediaplayer/#mediaisplaying","title":"mediaIsPlaying()","text":"

      \u68c0\u67e5\u662f\u5426\u6b63\u5728\u64ad\u653e\u3002

      mediaIsPlaying(tag=\"default\")\n

      \u8fd4\u56de\uff1a True/False

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaylist","title":"mediaPlayList()","text":"

      \u5217\u51fa\u6d3b\u52a8\u64ad\u653e\u5668\u3002

      mediaPlayList()\n
      "},{"location":"qsl4a/media/mediaplayer/#_3","title":"\u97f3\u91cf\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#getmediavolume","title":"getMediaVolume()","text":"

      \u83b7\u53d6\u5a92\u4f53\u97f3\u91cf\u3002

      getMediaVolume()\n

      \u8fd4\u56de\uff1a \u97f3\u91cf\u7ea7\u522b\uff080-15\uff09

      "},{"location":"qsl4a/media/mediaplayer/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

      getMaxMediaVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#getringervolume","title":"getRingerVolume()","text":"

      \u83b7\u53d6\u94c3\u58f0\u97f3\u91cf\u3002

      getRingerVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

      getMaxRingerVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#_4","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/mediaplayer/#videoplay","title":"videoPlay()","text":"

      \u5168\u5c4f\u64ad\u653e\u89c6\u9891\u3002

      videoPlay(path, wait=True)\n

      \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210

      "},{"location":"qsl4a/media/mediaplayer/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u64ad\u653e\u97f3\u9891\ndroid.mediaPlay(\"/sdcard/music.mp3\", tag=\"music\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.mediaIsPlaying(\"music\").result:\n    info = droid.mediaPlayInfo(\"music\").result\n    print(f\"Playing: {info}\")\n\n# \u8df3\u8f6c\u5230 30 \u79d2\ndroid.mediaPlaySeek(30000, \"music\")\n\n# \u5173\u95ed\ndroid.mediaPlayClose(\"music\")\n\n# \u64ad\u653e\u89c6\u9891\ndroid.videoPlay(\"/sdcard/movie.mp4\", wait=True)\n
      "},{"location":"qsl4a/special/cipher/","title":"\u5bc6\u7801 API","text":"

      \u7528\u4e8e\u5b89\u5168\u6570\u636e\u5b58\u50a8\u7684\u52a0\u5bc6\u548c\u89e3\u5bc6\u5de5\u5177\u3002

      "},{"location":"qsl4a/special/cipher/#_1","title":"\u521d\u59cb\u5316","text":""},{"location":"qsl4a/special/cipher/#cipherinit","title":"cipherInit()","text":"

      \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u548c\u7b97\u6cd5\u521d\u59cb\u5316\u5bc6\u7801\u5668\u3002

      cipherInit(key, algorithm=\"AES/CBC/PKCS5Padding\", encodingFormat=\"\", initialVector=\"\")\n

      \u53c2\u6570\uff1a - key (str or bytes): \u52a0\u5bc6\u5bc6\u94a5 - algorithm (str): \u5bc6\u7801\u7b97\u6cd5\uff08\u9ed8\u8ba4\uff1a\"AES/CBC/PKCS5Padding\"\uff09 - encodingFormat (str): \u7f16\u7801\u683c\u5f0f - initialVector (str or bytes): \u52a0\u5bc6\u7684\u521d\u59cb\u5411\u91cf

      \u8fd4\u56de\uff1a \u521d\u59cb\u5316\u7ed3\u679c

      \u6ce8\u610f\uff1a \u5fc5\u987b\u5728\u4efb\u4f55\u52a0\u5bc6/\u89e3\u5bc6\u64cd\u4f5c\u4e4b\u524d\u8c03\u7528\u3002

      "},{"location":"qsl4a/special/cipher/#_2","title":"\u52a0\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#encryptstring","title":"encryptString()","text":"

      \u52a0\u5bc6\u5b57\u7b26\u4e32\u3002

      encryptString(plainText)\n

      \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c

      \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/special/cipher/#encryptbytes","title":"encryptBytes()","text":"

      \u52a0\u5bc6\u5b57\u8282\u6570\u636e\u3002

      encryptBytes(data)\n

      \u53c2\u6570\uff1a - data (bytes): \u8981\u52a0\u5bc6\u7684\u6570\u636e

      \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u8282

      "},{"location":"qsl4a/special/cipher/#encryptstringtofile","title":"encryptStringToFile()","text":"

      \u52a0\u5bc6\u5b57\u7b26\u4e32\u5230\u6587\u4ef6\u3002

      encryptStringToFile(plainText, filePath)\n

      \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c - filePath (str): \u8f93\u51fa\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/special/cipher/#encryptbytestofile","title":"encryptBytesToFile()","text":"

      \u52a0\u5bc6\u5b57\u8282\u5230\u6587\u4ef6\u3002

      encryptBytesToFile(data, filePath)\n
      "},{"location":"qsl4a/special/cipher/#_3","title":"\u89e3\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#decryptstring","title":"decryptString()","text":"

      \u89e3\u5bc6\u4e3a\u5b57\u7b26\u4e32\u3002

      decryptString(cipherText)\n

      \u53c2\u6570\uff1a - cipherText (str): \u52a0\u5bc6\u7684\u6587\u672c

      \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/special/cipher/#decryptbytes","title":"decryptBytes()","text":"

      \u89e3\u5bc6\u4e3a\u5b57\u8282\u3002

      decryptBytes(data)\n

      \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u8282

      "},{"location":"qsl4a/special/cipher/#decryptfiletostring","title":"decryptFileToString()","text":"

      \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u7b26\u4e32\u3002

      decryptFileToString(filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryptfiletobytes","title":"decryptFileToBytes()","text":"

      \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u8282\u3002

      decryptFileToBytes(filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryptfile","title":"decryptFile()","text":"

      \u89e3\u5bc6\u6587\u4ef6\u5230\u6587\u4ef6\u3002

      decryptFile(srcPath, destPath)\n
      "},{"location":"qsl4a/special/cipher/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u521d\u59cb\u5316\u5bc6\u7801\u5668\ndroid.cipherInit(\"my_secret_key_1234\")\n\n# \u52a0\u5bc6\u5b57\u7b26\u4e32\nencrypted = droid.encryptString(\"Secret message!\").result\nprint(f\"Encrypted: {encrypted}\")\n\n# \u89e3\u5bc6\u5b57\u7b26\u4e32\ndecrypted = droid.decryptString(encrypted).result\nprint(f\"Decrypted: {decrypted}\")\n\n# \u52a0\u5bc6\u5230\u6587\u4ef6\ndroid.encryptStringToFile(\"My secret data\", \"/sdcard/secret.dat\")\n\n# \u4ece\u6587\u4ef6\u89e3\u5bc6\ndata = droid.decryptFileToString(\"/sdcard/secret.dat\").result\nprint(data)\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u7b97\u6cd5\u548c IV \u521d\u59cb\u5316\ndroid.cipherInit(\n    key=\"my_key\",\n    algorithm=\"AES/CBC/PKCS5Padding\",\n    initialVector=\"0123456789abcdef\"\n)\n
      "},{"location":"qsl4a/special/pgptai/","title":"PGPT AI API","text":"

      \u8bed\u97f3\u8f6c\u6587\u672c\u548c AI \u670d\u52a1\u96c6\u6210\u3002

      "},{"location":"qsl4a/special/pgptai/#_1","title":"\u5148\u51b3\u6761\u4ef6","text":"
      pip install pgptAI\n
      "},{"location":"qsl4a/special/pgptai/#_2","title":"\u8bed\u97f3\u8bc6\u522b","text":""},{"location":"qsl4a/special/pgptai/#speechtotext","title":"speechToText()","text":"

      \u5c06\u8bed\u97f3\u8f6c\u6362\u4e3a\u6587\u672c\u3002

      speechToText(RecordSecond=10, AmrFile=None, Language=None)\n

      \u53c2\u6570\uff1a - RecordSecond (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09 - AmrFile (str, optional): \u73b0\u6709\u97f3\u9891\u6587\u4ef6\u8def\u5f84 - Language (str, optional): \u8bed\u8a00\u4ee3\u7801\uff08'en'\u3001'zh'\uff09

      \u8fd4\u56de\uff1a \u8f6c\u5f55\u7684\u6587\u672c

      "},{"location":"qsl4a/special/pgptai/#_3","title":"\u6587\u672c\u8f6c\u8bed\u97f3","text":""},{"location":"qsl4a/special/pgptai/#texttospeech","title":"textToSpeech()","text":"

      \u5c06\u6587\u672c\u8f6c\u6362\u4e3a\u8bed\u97f3\u5e76\u53ef\u9009\u5730\u64ad\u653e\u3002

      textToSpeech(Text, AutoPlay=True, WavFile=None, VoiceName=None)\n

      \u53c2\u6570\uff1a - Text (str): \u8981\u8f6c\u6362\u4e3a\u8bed\u97f3\u7684\u6587\u672c - AutoPlay (bool): \u81ea\u52a8\u64ad\u653e\u751f\u6210\u7684\u97f3\u9891\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - WavFile (str, optional): \u4fdd\u5b58 WAV \u6587\u4ef6\u7684\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u4e34\u65f6\u6587\u4ef6 - VoiceName (str, optional): \u8981\u4f7f\u7528\u7684\u8bed\u97f3\u540d\u79f0\uff08\u4f8b\u5982 'en-US-JennyNeural'\u3001'zh-CN-XiaoxiaoNeural'\uff09

      \u8fd4\u56de\uff1a \u5305\u542b\u8bed\u97f3\u5408\u6210\u7ed3\u679c\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - text: \u8f93\u5165\u6587\u672c - url: \u4e0b\u8f7d\u97f3\u9891\u6587\u4ef6\u7684 URL - WavFile: \u4fdd\u5b58\u7684 WAV \u6587\u4ef6\u8def\u5f84\uff08\u5982\u679c\u672c\u5730\u4fdd\u5b58\uff09

      "},{"location":"qsl4a/special/pgptai/#_4","title":"\u914d\u7f6e","text":"

      API \u4f7f\u7528\u4ee5\u4e0b\u914d\u7f6e\u6587\u4ef6\u4e2d\u7684\u914d\u7f6e\uff1a/storage/emulated/0/Android/data/org.qpython.qpy/files/apigpt.conf\uff1a

      [speech]\nspeech_key = your_api_key\n

      \u9ed8\u8ba4\u8bed\u97f3\u8bbe\u7f6e\uff1a - \u82f1\u8bed\uff1aen-US-JennyNeural - \u4e2d\u6587\uff1azh-CN-XiaoxiaoNeural

      "},{"location":"qsl4a/special/pgptai/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5f55\u5236\u5e76\u8f6c\u5f55\nprint(\"Recording for 5 seconds...\")\ntext = droid.speechToText(RecordSecond=5, Language='en').result\nprint(f\"You said: {text}\")\n\n# \u8f6c\u5f55\u73b0\u6709\u6587\u4ef6\ntext = droid.speechToText(AmrFile=\"/sdcard/recording.amr\").result\nprint(f\"Transcription: {text}\")\n\n# \u6587\u672c\u8f6c\u8bed\u97f3\ndroid.textToSpeech(\"Hello, this is a test message.\", AutoPlay=True, Language='en')\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u8bed\u97f3\u5e76\u4fdd\u5b58\u5230\u6587\u4ef6\u7684\u6587\u672c\u8f6c\u8bed\u97f3\nresult = droid.textToSpeech(\n    \"Welcome to QPython!\",\n    AutoPlay=False,\n    WavFile=\"/sdcard/welcome.wav\",\n    VoiceName=\"en-US-JennyNeural\"\n).result\nprint(f\"Audio saved to: {result.get('WavFile')}\")\n
      "},{"location":"qsl4a/special/pgptai/#_6","title":"\u7c7b\u4f7f\u7528","text":"
      from androidhelper.pgptai import pgptai\nimport androidhelper\n\ndroid = androidhelper.Android()\nai = pgptai(droid)\n\n# \u4f7f\u7528\u8bed\u97f3\u8bc6\u522b\ntext = ai.speechToText(RecordSecond=10)\n
      "},{"location":"qsl4a/storage/clipboard/","title":"\u526a\u8d34\u677f API","text":"

      \u590d\u5236\u548c\u7c98\u8d34\u6587\u672c\u5230\u7cfb\u7edf\u526a\u8d34\u677f\u3002

      "},{"location":"qsl4a/storage/clipboard/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/clipboard/#setclipboard","title":"setClipboard()","text":"

      \u590d\u5236\u6587\u672c\u5230\u526a\u8d34\u677f\u3002

      setClipboard(text)\n

      \u53c2\u6570\uff1a - text (str): \u8981\u590d\u5236\u7684\u6587\u672c

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/clipboard/#getclipboard","title":"getClipboard()","text":"

      \u4ece\u526a\u8d34\u677f\u83b7\u53d6\u6587\u672c\u3002

      getClipboard()\n

      \u8fd4\u56de\uff1a \u526a\u8d34\u677f\u6587\u672c

      "},{"location":"qsl4a/storage/clipboard/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u590d\u5236\u5230\u526a\u8d34\u677f\ndroid.setClipboard(\"Hello from QPython!\")\n\n# \u4ece\u526a\u8d34\u677f\u7c98\u8d34\ntext = droid.getClipboard().result\nprint(f\"Clipboard: {text}\")\n
      "},{"location":"qsl4a/storage/documentfile/","title":"DocumentFile API","text":"

      \u4f7f\u7528 SAF\uff08\u5b58\u50a8\u8bbf\u95ee\u6846\u67b6\uff09\u8fdb\u884c\u6587\u4ef6\u64cd\u4f5c\uff0c\u652f\u6301 Android 4.4+\u3002

      "},{"location":"qsl4a/storage/documentfile/#_1","title":"\u76ee\u5f55\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilemkdir","title":"documentFileMkdir()","text":"

      \u521b\u5efa\u76ee\u5f55\u3002

      documentFileMkdir(Dir)\n

      \u53c2\u6570\uff1a - Dir (str): \u76ee\u5f55\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/documentfile/#documentfilelistfiles","title":"documentFileListFiles()","text":"

      \u5217\u51fa\u76ee\u5f55\u4e2d\u7684\u6587\u4ef6\u3002

      documentFileListFiles(Folder)\n

      \u8fd4\u56de\uff1a \u6587\u4ef6\u5217\u8868

      "},{"location":"qsl4a/storage/documentfile/#_2","title":"\u6587\u4ef6\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileexists","title":"documentFileExists()","text":"

      \u68c0\u67e5\u6587\u4ef6\u6216\u76ee\u5f55\u662f\u5426\u5b58\u5728\u3002

      documentFileExists(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u6216\u76ee\u5f55\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u5b58\u5728\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/storage/documentfile/#documentfileisfile","title":"documentFileIsFile()","text":"

      \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u6587\u4ef6\u3002

      documentFileIsFile(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u662f\u6587\u4ef6\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u6587\u4ef6\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

      "},{"location":"qsl4a/storage/documentfile/#documentfileisdirectory","title":"documentFileIsDirectory()","text":"

      \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u76ee\u5f55\u3002

      documentFileIsDirectory(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u662f\u76ee\u5f55\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u76ee\u5f55\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

      "},{"location":"qsl4a/storage/documentfile/#documentfiledelete","title":"documentFileDelete()","text":"

      \u5220\u9664\u6587\u4ef6\u6216\u76ee\u5f55\u3002

      documentFileDelete(FileOrTree)\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/documentfile/#documentfilerenameto","title":"documentFileRenameTo()","text":"

      \u91cd\u547d\u540d\u6216\u79fb\u52a8\u6587\u4ef6\u3002

      documentFileRenameTo(Src, Dest)\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/documentfile/#documentfilecopy","title":"documentFileCopy()","text":"

      \u590d\u5236\u6587\u4ef6\u3002

      documentFileCopy(SrcFileOrTree, DestFileOrTree)\n
      "},{"location":"qsl4a/storage/documentfile/#_3","title":"\u6d41\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileinputstream","title":"documentFileInputStream()","text":"

      \u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9\u3002

      documentFileInputStream(srcFile, EncodingFormat=\"\", skip=None, length=None)\n

      \u53c2\u6570\uff1a - srcFile (str): \u6e90\u6587\u4ef6 - EncodingFormat (str): \"UTF-8\"\u3001\"GBK\"\u3001\"Base64\" \u6216\u7a7a\u5b57\u7b26\u4e32\u8868\u793a\u5b57\u8282 - skip (int): \u4ece\u5f00\u5934\u8df3\u8fc7\u7684\u5b57\u8282\u6570 - length (int): \u8bfb\u53d6\u957f\u5ea6

      \u8fd4\u56de\uff1a \u6587\u4ef6\u5185\u5bb9

      "},{"location":"qsl4a/storage/documentfile/#documentfileoutputstream","title":"documentFileOutputStream()","text":"

      \u5199\u5165\u6587\u4ef6\u5185\u5bb9\u3002

      documentFileOutputStream(destFile, src, EncodingFormat=\"\", append=None)\n

      \u53c2\u6570\uff1a - destFile (str): \u76ee\u6807\u6587\u4ef6 - src: \u8981\u5199\u5165\u7684\u6570\u636e - EncodingFormat (str): \u7f16\u7801\u683c\u5f0f - append (bool): \u8ffd\u52a0\u6a21\u5f0f

      "},{"location":"qsl4a/storage/documentfile/#_4","title":"\u6587\u4ef6\u4fe1\u606f","text":""},{"location":"qsl4a/storage/documentfile/#documentfilelength","title":"documentFileLength()","text":"

      \u83b7\u53d6\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\u3002

      documentFileLength(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

      "},{"location":"qsl4a/storage/documentfile/#documentfilelastmodified","title":"documentFileLastModified()","text":"

      \u83b7\u53d6\u6700\u540e\u4fee\u6539\u65f6\u95f4\u3002

      documentFileLastModified(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u65f6\u95f4\u6233\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

      "},{"location":"qsl4a/storage/documentfile/#documentfilegetstat","title":"documentFileGetStat()","text":"

      \u83b7\u53d6\u5168\u9762\u7684\u6587\u4ef6\u7edf\u8ba1\u4fe1\u606f\u3002

      documentFileGetStat(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5305\u542b\u957f\u5ea6\u3001\u6700\u540e\u4fee\u6539\u65f6\u95f4\u548c\u8bfb/\u5199\u6743\u9650\u7684\u5b57\u5178\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

      "},{"location":"qsl4a/storage/documentfile/#uri","title":"URI \u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilegeturi","title":"documentFileGetUri()","text":"

      \u4ece\u8def\u5f84\u83b7\u53d6 URI\u3002

      documentFileGetUri(path, isDirectory=None)\n
      "},{"location":"qsl4a/storage/documentfile/#documentfileshowopen","title":"documentFileShowOpen()","text":"

      \u663e\u793a\u6587\u4ef6\u9009\u62e9\u5668\u3002

      documentFileShowOpen()\n

      \u8fd4\u56de\uff1a \u9009\u62e9\u7684\u6587\u4ef6 URI

      "},{"location":"qsl4a/storage/documentfile/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u76ee\u5f55\ndroid.documentFileMkdir(\"/sdcard/MyFolder\")\n\n# \u5217\u51fa\u6587\u4ef6\nfiles = droid.documentFileListFiles(\"/sdcard\").result\nfor f in files:\n    print(f)\n\n# \u8bfb\u53d6\u6587\u4ef6\ncontent = droid.documentFileInputStream(\n    \"/sdcard/test.txt\",\n    EncodingFormat=\"UTF-8\"\n).result\nprint(content)\n\n# \u5199\u5165\u6587\u4ef6\ndroid.documentFileOutputStream(\n    \"/sdcard/output.txt\",\n    \"Hello World\",\n    EncodingFormat=\"UTF-8\"\n)\n
      "},{"location":"qsl4a/storage/preferences/","title":"\u504f\u597d\u8bbe\u7f6e API","text":"

      \u4f7f\u7528 Android SharedPreferences \u5b58\u50a8\u548c\u68c0\u7d22\u6570\u636e\u3002

      "},{"location":"qsl4a/storage/preferences/#_1","title":"\u504f\u597d\u8bbe\u7f6e\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/preferences/#prefgetvalue","title":"prefGetValue()","text":"

      \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u8bfb\u53d6\u503c\u3002

      prefGetValue(key, filename=None)\n

      \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c\uff08\u4efb\u610f\u7c7b\u578b\uff09

      "},{"location":"qsl4a/storage/preferences/#prefputvalue","title":"prefPutValue()","text":"

      \u5199\u5165\u503c\u5230\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u3002

      prefPutValue(key, value, filename=None)\n

      \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - value (object): \u8981\u5b58\u50a8\u7684\u503c - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      "},{"location":"qsl4a/storage/preferences/#prefgetall","title":"prefGetAll()","text":"

      \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\u503c\u3002

      prefGetAll(filename=None)\n

      \u53c2\u6570\uff1a - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      \u8fd4\u56de\uff1a \u6240\u6709\u504f\u597d\u7684\u6620\u5c04

      "},{"location":"qsl4a/storage/preferences/#prefremovevalue","title":"prefRemoveValue()","text":"

      \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u4e2d\u79fb\u9664\u503c\u3002

      prefRemoveValue(key, filename=None)\n

      \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      "},{"location":"qsl4a/storage/preferences/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b58\u50a8\u503c\ndroid.prefPutValue(\"username\", \"alice\")\ndroid.prefPutValue(\"score\", 100)\ndroid.prefPutValue(\"enabled\", True)\n\n# \u8bfb\u53d6\u7279\u5b9a\u503c\nusername = droid.prefGetValue(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\nall_prefs = droid.prefGetAll().result\nprint(f\"All prefs: {all_prefs}\")\n\n# \u79fb\u9664\u503c\ndroid.prefRemoveValue(\"score\")\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u6587\u4ef6\u540d\ndroid.prefPutValue(\"token\", \"abc123\", filename=\"auth.prefs\")\ntoken = droid.prefGetValue(\"token\", filename=\"auth.prefs\").result\n
      "},{"location":"qsl4a/system/activityresult/","title":"Activity Result API","text":"

      \u4e3a\u901a\u8fc7 startActivityForResult \u542f\u52a8\u7684\u811a\u672c\u8bbe\u7f6e activity \u7ed3\u679c\u3002

      "},{"location":"qsl4a/system/activityresult/#_1","title":"\u7ed3\u679c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/activityresult/#setresultboolean","title":"setResultBoolean()","text":"

      \u8bbe\u7f6e\u5e03\u5c14\u7ed3\u679c\u3002

      setResultBoolean(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (bool): \u5e03\u5c14\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultbyte","title":"setResultByte()","text":"

      \u8bbe\u7f6e\u5b57\u8282\u7ed3\u679c\u3002

      setResultByte(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u5b57\u8282\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultshort","title":"setResultShort()","text":"

      \u8bbe\u7f6e\u77ed\u6574\u6570\u7ed3\u679c\u3002

      setResultShort(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u77ed\u6574\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultchar","title":"setResultChar()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u7ed3\u679c\u3002

      setResultChar(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultinteger","title":"setResultInteger()","text":"

      \u8bbe\u7f6e\u6574\u6570\u7ed3\u679c\u3002

      setResultInteger(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u6574\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultlong","title":"setResultLong()","text":"

      \u8bbe\u7f6e\u957f\u6574\u6570\u7ed3\u679c\u3002

      setResultLong(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u957f\u6574\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultfloat","title":"setResultFloat()","text":"

      \u8bbe\u7f6e\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

      setResultFloat(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u6d6e\u70b9\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultdouble","title":"setResultDouble()","text":"

      \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

      setResultDouble(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultstring","title":"setResultString()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u4e32\u7ed3\u679c\u3002

      setResultString(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u4e32\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultbooleanarray","title":"setResultBooleanArray()","text":"

      \u8bbe\u7f6e\u5e03\u5c14\u6570\u7ec4\u7ed3\u679c\u3002

      setResultBooleanArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5e03\u5c14\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultbytearray","title":"setResultByteArray()","text":"

      \u8bbe\u7f6e\u5b57\u8282\u6570\u7ec4\u7ed3\u679c\u3002

      setResultByteArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u8282\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultshortarray","title":"setResultShortArray()","text":"

      \u8bbe\u7f6e\u77ed\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultShortArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u77ed\u6574\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultchararray","title":"setResultCharArray()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u6570\u7ec4\u7ed3\u679c\u3002

      setResultCharArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultintegerarray","title":"setResultIntegerArray()","text":"

      \u8bbe\u7f6e\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultIntegerArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6574\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultlongarray","title":"setResultLongArray()","text":"

      \u8bbe\u7f6e\u957f\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultLongArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u957f\u6574\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultfloatarray","title":"setResultFloatArray()","text":"

      \u8bbe\u7f6e\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultFloatArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6d6e\u70b9\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultdoublearray","title":"setResultDoubleArray()","text":"

      \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultDoubleArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultstringarray","title":"setResultStringArray()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u4e32\u6570\u7ec4\u7ed3\u679c\u3002

      setResultStringArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u4e32\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultserializable","title":"setResultSerializable()","text":"

      \u8bbe\u7f6e\u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u3002

      setResultSerializable(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue: \u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c activity \u540e\uff0c\u8bbe\u7f6e\u7ed3\u679c\n# \u793a\u4f8b\uff1a\u8fd4\u56de\u6210\u529f\u53ca\u6570\u636e\ndroid.setResultInteger(0, 200)  # RESULT_OK\ndroid.setResultString(0, \"Operation completed successfully\")\n\n# \u8fd4\u56de\u6570\u7ec4\u7ed3\u679c\ndroid.setResultIntegerArray(0, [1, 2, 3, 4, 5])\n
      "},{"location":"qsl4a/system/application/","title":"\u5e94\u7528\u7ba1\u7406","text":"

      \u7ba1\u7406\u5e94\u7528\u7a0b\u5e8f\u3001\u542f\u52a8\u5e94\u7528\u548c\u67e5\u8be2\u7cfb\u7edf\u4fe1\u606f\u3002

      "},{"location":"qsl4a/system/application/#_2","title":"\u5e94\u7528\u7a0b\u5e8f\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getapplicationinfo","title":"getApplicationInfo()","text":"

      \u83b7\u53d6\u5e94\u7528\u4fe1\u606f\u3002

      getApplicationInfo(packageName=None)\n

      \u53c2\u6570\uff1a - packageName (str): \u5305\u540d\uff08None = \u5f53\u524d\u5e94\u7528\uff09

      \u8fd4\u56de\uff1a \u5e94\u7528\u4fe1\u606f\u5b57\u5178

      "},{"location":"qsl4a/system/application/#getinstalledpackages","title":"getInstalledPackages()","text":"

      \u83b7\u53d6\u5df2\u5b89\u88c5\u5305\u5217\u8868\u3002

      getInstalledPackages(flag=4)\n

      \u53c2\u6570\uff1a - flag (int): \u5305\u6807\u5fd7\u8fc7\u6ee4\u5668\uff08\u9ed8\u8ba4\uff1a4\uff09

      \u8fd4\u56de\uff1a \u5df2\u5b89\u88c5\u5305\u5217\u8868

      "},{"location":"qsl4a/system/application/#getrunningpackages","title":"getRunningPackages()","text":"

      \u5217\u51fa\u6b63\u5728\u8fd0\u884c\u7684\u5305\u3002

      getRunningPackages()\n

      \u8fd4\u56de\uff1a \u5305\u540d\u5217\u8868

      "},{"location":"qsl4a/system/application/#getlaunchablepackages","title":"getLaunchablePackages()","text":"

      \u83b7\u53d6\u53ef\u542f\u52a8\u5305\u5217\u8868\u3002

      getLaunchablePackages(needClassName=False)\n

      \u53c2\u6570\uff1a - needClassName (bool): \u5305\u542b\u4e3b activity \u7c7b\u540d\uff08\u9ed8\u8ba4\uff1aFalse\uff09

      \u8fd4\u56de\uff1a \u53ef\u542f\u52a8\u5305\u540d\u5217\u8868\u6216\u5305\u542b\u7c7b\u540d\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#_3","title":"\u5e94\u7528\u63a7\u5236","text":""},{"location":"qsl4a/system/application/#launch","title":"launch()","text":"

      \u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u3002

      launch(classname=None, packagename=None, wait=True)\n

      \u53c2\u6570\uff1a - classname (str): \u4e3b activity \u7c7b\u540d - packagename (str): \u5305\u540d - wait (bool): \u7b49\u5f85\u542f\u52a8\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

      \u8fd4\u56de\uff1a \u542f\u52a8\u7ed3\u679c

      "},{"location":"qsl4a/system/application/#forcestoppackage","title":"forceStopPackage()","text":"

      \u5f3a\u5236\u505c\u6b62\u5e94\u7528\u7a0b\u5e8f\u3002

      forceStopPackage(packageName)\n

      \u53c2\u6570\uff1a - packageName (str): \u8981\u505c\u6b62\u7684\u5305\u540d

      "},{"location":"qsl4a/system/application/#_4","title":"\u7248\u672c\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getpackageversion","title":"getPackageVersion()","text":"

      \u83b7\u53d6\u5e94\u7528\u7248\u672c\u540d\u79f0\u3002

      getPackageVersion(packageName)\n

      \u8fd4\u56de\uff1a \u7248\u672c\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"3.2.1\"\uff09

      "},{"location":"qsl4a/system/application/#getpackageversioncode","title":"getPackageVersionCode()","text":"

      \u83b7\u53d6\u5e94\u7528\u7248\u672c\u4ee3\u7801\u3002

      getPackageVersionCode(packageName)\n

      \u8fd4\u56de\uff1a \u7248\u672c\u4ee3\u7801\u6574\u6570

      "},{"location":"qsl4a/system/application/#getconstants","title":"getConstants()","text":"

      \u83b7\u53d6\u7c7b\u5e38\u91cf\u3002

      getConstants(classname)\n

      \u53c2\u6570\uff1a - classname (str): \u5b8c\u6574\u7c7b\u540d

      \u8fd4\u56de\uff1a \u5e38\u91cf\u540d\u548c\u503c\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#_5","title":"\u7cfb\u7edf\u529f\u80fd","text":""},{"location":"qsl4a/system/application/#backgroundprotect","title":"backgroundProtect()","text":"

      \u542f\u7528\u6216\u7981\u7528\u5e94\u7528\u7684\u540e\u53f0\u4fdd\u62a4\u3002

      backgroundProtect(enabled=True)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\u4fdd\u62a4\uff0cFalse \u7981\u7528

      "},{"location":"qsl4a/system/application/#createscriptshortcut","title":"createScriptShortCut()","text":"

      \u4e3a\u811a\u672c\u521b\u5efa\u4e3b\u5c4f\u5e55\u5feb\u6377\u65b9\u5f0f\u3002

      createScriptShortCut(scriptPath, label=None, iconPath=None, scriptArg=None)\n

      \u53c2\u6570\uff1a - scriptPath (str): Python \u811a\u672c\u8def\u5f84 - label (str, optional): \u5feb\u6377\u65b9\u5f0f\u6807\u7b7e - iconPath (str, optional): \u56fe\u6807\u56fe\u50cf\u8def\u5f84 - scriptArg (str, optional): \u4f20\u9012\u7ed9\u811a\u672c\u7684\u53c2\u6570

      "},{"location":"qsl4a/system/application/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getandroidid","title":"getAndroidID()","text":"

      \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

      getAndroidID()\n

      \u8fd4\u56de\uff1a \u552f\u4e00\u7684 Android \u8bbe\u5907 ID \u5b57\u7b26\u4e32

      "},{"location":"qsl4a/system/application/#getsysinfo","title":"getSysInfo()","text":"

      \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\u3002

      getSysInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#getlocale","title":"getLocale()","text":"

      \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u3002

      getLocale()\n

      \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

      "},{"location":"qsl4a/system/application/#getharmonyosinformation","title":"getHarmonyOsInformation()","text":"

      \u5982\u679c\u5728 HarmonyOS \u4e0a\u8fd0\u884c\uff0c\u83b7\u53d6 HarmonyOS \u4fe1\u606f\u3002

      getHarmonyOsInformation()\n

      \u8fd4\u56de\uff1a HarmonyOS \u7248\u672c\u4fe1\u606f\u6216 None

      "},{"location":"qsl4a/system/application/#isexternalstoragemanager","title":"isExternalStorageManager()","text":"

      \u68c0\u67e5\u5e94\u7528\u662f\u5426\u6709\u5916\u90e8\u5b58\u50a8\u7ba1\u7406\u5668\u6743\u9650\u3002

      isExternalStorageManager()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6709\u6743\u9650\u5219\u4e3a True

      "},{"location":"qsl4a/system/application/#_7","title":"\u5185\u5b58\u548c\u663e\u793a","text":""},{"location":"qsl4a/system/application/#getmemoryinfo","title":"getMemoryInfo()","text":"

      \u83b7\u53d6\u5185\u5b58\u4fe1\u606f\u3002

      getMemoryInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#getscreeninfo","title":"getScreenInfo()","text":"

      \u83b7\u53d6\u5c4f\u5e55\u4fe1\u606f\u3002

      getScreenInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#_8","title":"\u6743\u9650","text":""},{"location":"qsl4a/system/application/#checkpermissions","title":"checkPermissions()","text":"

      \u68c0\u67e5\u5f53\u524d\u5e94\u7528\u6743\u9650\u3002

      checkPermissions()\n

      \u8fd4\u56de\uff1a \u6743\u9650\u53ca\u5176\u72b6\u6001\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#requestpermissions","title":"requestPermissions()","text":"

      \u5411\u7528\u6237\u8bf7\u6c42\u6743\u9650\u3002

      requestPermissions(permissions=None)\n

      \u53c2\u6570\uff1a - permissions (list, optional): \u8981\u8bf7\u6c42\u7684\u6743\u9650\u5217\u8868\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8bf7\u6c42\u6240\u6709\u9700\u8981\u7684\u6743\u9650\u3002

      \u8fd4\u56de\uff1a \u6743\u9650\u8bf7\u6c42\u7ed3\u679c

      "},{"location":"qsl4a/system/application/#_9","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/system/application/#showscreenlock","title":"showScreenLock()","text":"

      \u663e\u793a\u5c4f\u5e55\u9501\u5b9a\uff08PIN/\u56fe\u6848/\u5bc6\u7801\u8f93\u5165\uff09\u3002

      showScreenLock()\n
      "},{"location":"qsl4a/system/application/#_10","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\ninfo = droid.getSysInfo().result\nprint(f\"System: {info}\")\n\n# \u83b7\u53d6\u5e94\u7528\u7248\u672c\nversion = droid.getPackageVersion(\"org.qpython.qpy\").result\nprint(f\"QPython version: {version}\")\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u5e94\u7528\napps = droid.getInstalledPackages().result\nprint(f\"Installed apps: {len(apps)}\")\n\n# \u542f\u52a8\u5e94\u7528\ndroid.launch(packagename=\"com.android.settings\")\n\n# \u68c0\u67e5\u6743\u9650\nperms = droid.checkPermissions().result\nprint(f\"Permissions: {perms}\")\n\n# \u8bf7\u6c42\u5b58\u50a8\u6743\u9650\ndroid.requestPermissions([\"android.permission.READ_EXTERNAL_STORAGE\"])\n\n# \u521b\u5efa\u5feb\u6377\u65b9\u5f0f\ndroid.createScriptShortCut(\n    \"/sdcard/my_script.py\",\n    label=\"My Script\",\n    iconPath=\"/sdcard/icon.png\"\n)\n
      "},{"location":"qsl4a/system/battery/","title":"\u7535\u6c60 API","text":"

      \u76d1\u63a7\u8bbe\u5907\u7535\u6c60\u72b6\u6001\u548c\u5065\u5eb7\u72b6\u51b5\u3002

      "},{"location":"qsl4a/system/battery/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/battery/#readbatterydata","title":"readBatteryData()","text":"

      \u83b7\u53d6\u5b8c\u6574\u7684\u7535\u6c60\u4fe1\u606f\u3002

      readBatteryData()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7535\u6c60\u6570\u636e\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/battery/#batterystartmonitoring","title":"batteryStartMonitoring()","text":"

      \u5f00\u59cb\u7535\u6c60\u76d1\u63a7\u3002

      batteryStartMonitoring()\n
      "},{"location":"qsl4a/system/battery/#batterystopmonitoring","title":"batteryStopMonitoring()","text":"

      \u505c\u6b62\u7535\u6c60\u76d1\u63a7\u3002

      batteryStopMonitoring()\n
      "},{"location":"qsl4a/system/battery/#batterygetlevel","title":"batteryGetLevel()","text":"

      \u83b7\u53d6\u7535\u6c60\u767e\u5206\u6bd4\u3002

      batteryGetLevel()\n

      \u8fd4\u56de\uff1a \u6574\u6570\uff080-100\uff09

      "},{"location":"qsl4a/system/battery/#batterygetstatus","title":"batteryGetStatus()","text":"

      \u83b7\u53d6\u5145\u7535\u72b6\u6001\u3002

      batteryGetStatus()\n

      \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u5145\u7535\u4e2d - 3: \u653e\u7535\u4e2d - 4: \u672a\u5145\u7535 - 5: \u5df2\u5145\u6ee1

      "},{"location":"qsl4a/system/battery/#batterygetplugtype","title":"batteryGetPlugType()","text":"

      \u83b7\u53d6\u7535\u6e90\u7c7b\u578b\u3002

      batteryGetPlugType()\n

      \u8fd4\u56de\uff1a - -1: \u672a\u77e5 - 0: \u672a\u63d2\u7535 - 1: AC \u5145\u7535\u5668 - 2: USB \u7aef\u53e3

      "},{"location":"qsl4a/system/battery/#batterygethealth","title":"batteryGetHealth()","text":"

      \u83b7\u53d6\u7535\u6c60\u5065\u5eb7\u72b6\u51b5\u3002

      batteryGetHealth()\n

      \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u826f\u597d - 3: \u8fc7\u70ed - 4: \u635f\u574f - 5: \u8fc7\u538b - 6: \u672a\u6307\u5b9a\u7684\u6545\u969c

      "},{"location":"qsl4a/system/battery/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\nlevel = droid.batteryGetLevel().result\nprint(f\"Battery: {level}%\")\n
      "},{"location":"qsl4a/system/qpyinterface/","title":"QPython \u63a5\u53e3 API","text":"

      \u4ece\u5176\u4ed6\u5e94\u7528\u6267\u884c QPython \u811a\u672c\u548c\u7ba1\u7406\u5171\u4eab\u53d8\u91cf\u3002

      "},{"location":"qsl4a/system/qpyinterface/#_1","title":"\u811a\u672c\u6267\u884c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/qpyinterface/#executeqpy","title":"executeQPy()","text":"

      \u6267\u884c QPython \u811a\u672c\u3002

      executeQPy(path=\"\", arg=None)\n

      \u53c2\u6570\uff1a - path (str): \u811a\u672c\u6587\u4ef6\u8def\u5f84 - arg (str, optional): \u547d\u4ee4\u884c\u53c2\u6570

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#executeqpyassrv","title":"executeQPyAsSrv()","text":"

      \u4f5c\u4e3a\u670d\u52a1\u6267\u884c QPython \u811a\u672c\u3002

      executeQPyAsSrv(path=None)\n

      \u53c2\u6570\uff1a - path (str, optional): \u811a\u672c\u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#executeqpycode","title":"executeQPyCode()","text":"

      \u76f4\u63a5\u6267\u884c Python \u4ee3\u7801\u3002

      executeQPyCode(code=None)\n

      \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#executeqpycodeassrv","title":"executeQPyCodeAsSrv()","text":"

      \u4f5c\u4e3a\u670d\u52a1\u6267\u884c Python \u4ee3\u7801\u3002

      executeQPyCodeAsSrv(code=None)\n

      \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#_2","title":"\u5171\u4eab\u53d8\u91cf","text":"

      \u5171\u4eab\u53d8\u91cf\u5141\u8bb8 QPython \u4e0e\u5176\u4ed6\u5e94\u7528\u4e4b\u95f4\u8fdb\u884c\u901a\u4fe1\u3002

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableset","title":"sharedVariableSet()","text":"

      \u8bbe\u7f6e Java \u5171\u4eab\u53d8\u91cf\u3002

      sharedVariableSet(key, value)\n

      \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d - value (str): \u53d8\u91cf\u503c

      \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableget","title":"sharedVariableGet()","text":"

      \u83b7\u53d6 Java \u5171\u4eab\u53d8\u91cf\u3002

      sharedVariableGet(key)\n

      \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d

      \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableremove","title":"sharedVariableRemove()","text":"

      \u79fb\u9664 Java \u5171\u4eab\u53d8\u91cf\u3002

      sharedVariableRemove(key)\n

      \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u53d8\u91cf\u540d

      \u8fd4\u56de\uff1a \u88ab\u79fb\u9664\u7684\u503c

      "},{"location":"qsl4a/system/qpyinterface/#getlastlog","title":"getLastLog()","text":"

      \u83b7\u53d6 QPython \u7684\u6700\u540e\u65e5\u5fd7\u8f93\u51fa\u3002

      getLastLog()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u65e5\u5fd7\u5185\u5bb9

      "},{"location":"qsl4a/system/qpyinterface/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c\u811a\u672c\ndroid.executeQPy(\"/sdcard/my_script.py\", arg=\"test\")\n\n# \u76f4\u63a5\u6267\u884c\u4ee3\u7801\ncode = \"print('Hello from QPython!')\"\ndroid.executeQPyCode(code)\n\n# \u4f7f\u7528\u5171\u4eab\u53d8\u91cf\ndroid.sharedVariableSet(\"username\", \"alice\")\nusername = droid.sharedVariableGet(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u79fb\u9664\u53d8\u91cf\ndroid.sharedVariableRemove(\"username\")\n\n# \u83b7\u53d6\u6700\u8fd1\u65e5\u5fd7\nlog = droid.getLastLog().result\nprint(f\"Log: {log}\")\n
      "},{"location":"qsl4a/system/sensors/","title":"\u4f20\u611f\u5668 API","text":"

      \u8bbf\u95ee\u8bbe\u5907\u4f20\u611f\u5668\uff0c\u5305\u62ec\u52a0\u901f\u5ea6\u8ba1\u3001\u9640\u87ba\u4eea\u3001\u78c1\u529b\u8ba1\u7b49\u3002

      "},{"location":"qsl4a/system/sensors/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/sensors/#startsensingtimed","title":"startSensingTimed()","text":"

      \u5f00\u59cb\u4f20\u611f\u5668\u76d1\u63a7\u5e76\u8bbe\u7f6e\u65f6\u95f4\u95f4\u9694\u3002

      startSensingTimed(sensorNumber, delayTime)\n

      \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID\uff08\u901a\u5e38\u4e3a 1-3\uff09 - delayTime (int): \u8bfb\u53d6\u4e4b\u95f4\u7684\u5ef6\u8fdf\uff08\u6beb\u79d2\uff09

      "},{"location":"qsl4a/system/sensors/#startsensingthreshold","title":"startSensingThreshold()","text":"

      \u5f00\u59cb\u5e26\u9608\u503c\u89e6\u53d1\u7684\u4f20\u611f\u5668\u76d1\u63a7\u3002

      startSensingThreshold(sensorNumber, threshold, axis)\n

      \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID - threshold (float): \u89e6\u53d1\u9608\u503c - axis (int): \u8981\u76d1\u63a7\u7684\u8f74\uff080=X\uff0c1=Y\uff0c2=Z\uff09

      "},{"location":"qsl4a/system/sensors/#stopsensing","title":"stopSensing()","text":"

      \u505c\u6b62\u6240\u6709\u4f20\u611f\u5668\u76d1\u63a7\u3002

      stopSensing()\n
      "},{"location":"qsl4a/system/sensors/#readsensors","title":"readSensors()","text":"

      \u8bfb\u53d6\u5f53\u524d\u4f20\u611f\u5668\u6570\u636e\u3002

      readSensors()\n

      \u8fd4\u56de\uff1a \u4f20\u611f\u5668\u6570\u636e\u5b57\u5178

      "},{"location":"qsl4a/system/sensors/#sensorsreadaccelerometer","title":"sensorsReadAccelerometer()","text":"

      \u8bfb\u53d6\u52a0\u901f\u5ea6\u8ba1\u503c\u3002

      sensorsReadAccelerometer()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d m/s\u00b2

      "},{"location":"qsl4a/system/sensors/#sensorsreadgyroscope","title":"sensorsReadGyroscope()","text":"

      \u8bfb\u53d6\u9640\u87ba\u4eea\u503c\u3002

      sensorsReadGyroscope()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d rad/s

      "},{"location":"qsl4a/system/sensors/#sensorsreadmagnetometer","title":"sensorsReadMagnetometer()","text":"

      \u8bfb\u53d6\u78c1\u573a\u503c\u3002

      sensorsReadMagnetometer()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d \u03bcT

      "},{"location":"qsl4a/system/sensors/#sensorsreadorientation","title":"sensorsReadOrientation()","text":"

      \u8bfb\u53d6\u8bbe\u5907\u65b9\u5411\u3002

      sensorsReadOrientation()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [azimuth, pitch, roll]\uff0c\u5355\u4f4d\u5ea6

      "},{"location":"qsl4a/system/sensors/#sensorsgetlight","title":"sensorsGetLight()","text":"

      \u8bfb\u53d6\u5149\u4f20\u611f\u5668\u503c\u3002

      sensorsGetLight()\n

      \u8fd4\u56de\uff1a \u5149\u7ea7\u522b\uff08lux\uff09

      "},{"location":"qsl4a/system/sensors/#sensorsgetstepcounter","title":"sensorsGetStepCounter()","text":"

      \u8bfb\u53d6\u6b65\u8ba1\u6570\u5668\u3002

      sensorsGetStepCounter()\n

      \u8fd4\u56de\uff1a \u6b65\u6570

      "},{"location":"qsl4a/system/sensors/#sensorsgetaccuracy","title":"sensorsGetAccuracy()","text":"

      \u83b7\u53d6\u5f53\u524d\u4f20\u611f\u5668\u7cbe\u5ea6\u3002

      sensorsGetAccuracy()\n

      \u8fd4\u56de\uff1a \u7cbe\u5ea6\u503c\uff080-3\uff1aUNRELIABLE\u3001ACCURACY_LOW\u3001ACCURACY_MEDIUM\u3001ACCURACY_HIGH\uff09

      "},{"location":"qsl4a/system/sensors/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u8bfb\u53d6\u4f20\u611f\u5668 10 \u6b21\nfor i in range(10):\n    accel = droid.sensorsReadAccelerometer().result\n    print(f\"Accel: X={accel[0]:.2f}, Y={accel[1]:.2f}, Z={accel[2]:.2f}\")\n    time.sleep(0.5)\n\ndroid.stopSensing()\n
      "},{"location":"qsl4a/system/settings/","title":"\u8bbe\u7f6e API","text":"

      \u63a7\u5236\u7cfb\u7edf\u8bbe\u7f6e\uff0c\u5305\u62ec\u5c4f\u5e55\u3001\u58f0\u97f3\u548c\u7f51\u7edc\u8bbe\u7f6e\u3002

      "},{"location":"qsl4a/system/settings/#_1","title":"\u5c4f\u5e55\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#setscreentimeout","title":"setScreenTimeout()","text":"

      \u8bbe\u7f6e\u5c4f\u5e55\u8d85\u65f6\u503c\u3002

      setScreenTimeout(value)\n

      \u53c2\u6570\uff1a - value (int): \u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

      \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u8d85\u65f6\u503c

      "},{"location":"qsl4a/system/settings/#getscreentimeout","title":"getScreenTimeout()","text":"

      \u83b7\u53d6\u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u3002

      getScreenTimeout()\n

      \u8fd4\u56de\uff1a \u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

      "},{"location":"qsl4a/system/settings/#getscreenbrightness","title":"getScreenBrightness()","text":"

      \u83b7\u53d6\u5c4f\u5e55\u4eae\u5ea6\u503c\u3002

      getScreenBrightness()\n

      \u8fd4\u56de\uff1a \u4eae\u5ea6\u503c\uff080-255\uff09

      "},{"location":"qsl4a/system/settings/#setscreenbrightness","title":"setScreenBrightness()","text":"

      \u8bbe\u7f6e\u5c4f\u5e55\u4eae\u5ea6\u3002

      setScreenBrightness(value=None)\n

      \u53c2\u6570\uff1a - value (int, optional): \u4eae\u5ea6\u503c\uff080-255\uff09\uff0c\u6216 None \u8868\u793a\u81ea\u52a8

      \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u4eae\u5ea6\u503c

      "},{"location":"qsl4a/system/settings/#checkscreenon","title":"checkScreenOn()","text":"

      \u68c0\u67e5\u5c4f\u5e55\u662f\u5426\u4eae\u7740\u3002

      checkScreenOn()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u5c4f\u5e55\u4eae\u7740\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/system/settings/#_2","title":"\u98de\u884c\u6a21\u5f0f","text":""},{"location":"qsl4a/system/settings/#checkairplanemode","title":"checkAirplaneMode()","text":"

      \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\u662f\u5426\u542f\u7528\u3002

      checkAirplaneMode()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u98de\u884c\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

      "},{"location":"qsl4a/system/settings/#_3","title":"\u94c3\u58f0\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#checkringersilentmode","title":"checkRingerSilentMode()","text":"

      \u68c0\u67e5\u94c3\u58f0\u662f\u5426\u5904\u4e8e\u9759\u97f3\u6a21\u5f0f\u3002

      checkRingerSilentMode()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u9759\u97f3\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

      "},{"location":"qsl4a/system/settings/#toggleringersilentmode","title":"toggleRingerSilentMode()","text":"

      \u5207\u6362\u94c3\u58f0\u9759\u97f3\u6a21\u5f0f\u3002

      toggleRingerSilentMode(enabled=None)\n

      \u53c2\u6570\uff1a - enabled (bool, optional): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

      \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

      "},{"location":"qsl4a/system/settings/#togglevibratemode","title":"toggleVibrateMode()","text":"

      \u5207\u6362\u632f\u52a8\u6a21\u5f0f\u3002

      toggleVibrateMode(enabled=None, ringer=None)\n

      \u53c2\u6570\uff1a - enabled (bool, optional): \u5207\u6362\u632f\u52a8\u5f00/\u5173 - ringer (bool, optional): \u5e94\u7528\u4e8e\u94c3\u58f0\u6a21\u5f0f

      \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

      "},{"location":"qsl4a/system/settings/#getvibratemode","title":"getVibrateMode()","text":"

      \u83b7\u53d6\u632f\u52a8\u6a21\u5f0f\u8bbe\u7f6e\u3002

      getVibrateMode(ringer=None)\n

      \u53c2\u6570\uff1a - ringer (bool, optional): \u68c0\u67e5\u94c3\u58f0\u632f\u52a8\u6a21\u5f0f

      \u8fd4\u56de\uff1a \u5982\u679c\u632f\u52a8\u5df2\u542f\u7528\u5219\u4e3a True

      "},{"location":"qsl4a/system/settings/#_4","title":"\u97f3\u91cf\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#getringervolume","title":"getRingerVolume()","text":"

      \u83b7\u53d6\u5f53\u524d\u94c3\u58f0\u97f3\u91cf\u3002

      getRingerVolume()\n

      \u8fd4\u56de\uff1a \u94c3\u58f0\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-7\uff09

      "},{"location":"qsl4a/system/settings/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

      getMaxRingerVolume()\n

      \u8fd4\u56de\uff1a \u6700\u5927\u94c3\u58f0\u97f3\u91cf

      "},{"location":"qsl4a/system/settings/#setringervolume","title":"setRingerVolume()","text":"

      \u8bbe\u7f6e\u94c3\u58f0\u97f3\u91cf\u3002

      setRingerVolume(volume)\n

      \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

      "},{"location":"qsl4a/system/settings/#getmediavolume","title":"getMediaVolume()","text":"

      \u83b7\u53d6\u5f53\u524d\u5a92\u4f53\u97f3\u91cf\u3002

      getMediaVolume()\n

      \u8fd4\u56de\uff1a \u5a92\u4f53\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-15\uff09

      "},{"location":"qsl4a/system/settings/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

      getMaxMediaVolume()\n

      \u8fd4\u56de\uff1a \u6700\u5927\u5a92\u4f53\u97f3\u91cf

      "},{"location":"qsl4a/system/settings/#setmediavolume","title":"setMediaVolume()","text":"

      \u8bbe\u7f6e\u5a92\u4f53\u97f3\u91cf\u3002

      setMediaVolume(volume)\n

      \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

      "},{"location":"qsl4a/system/settings/#_5","title":"\u7cfb\u7edf\u4fe1\u606f","text":""},{"location":"qsl4a/system/settings/#elapsedrealtimenanos","title":"elapsedRealtimeNanos()","text":"

      \u83b7\u53d6\u81ea\u7cfb\u7edf\u542f\u52a8\u4ee5\u6765\u7684\u7eb3\u79d2\u6570\u3002

      elapsedRealtimeNanos()\n

      \u8fd4\u56de\uff1a \u7eb3\u79d2\u6570\uff08\u53ef\u7528\u4e8e\u8ba1\u65f6\uff09

      "},{"location":"qsl4a/system/settings/#gettrafficstats","title":"getTrafficStats()","text":"

      \u83b7\u53d6\u7f51\u7edc\u6d41\u91cf\u7edf\u8ba1\u3002

      getTrafficStats(flags=7)\n

      \u53c2\u6570\uff1a - flags (int): \u8981\u68c0\u7d22\u7684\u7edf\u8ba1\uff08\u9ed8\u8ba4\uff1a7 = \u5168\u90e8\uff09

      \u8fd4\u56de\uff1a \u5305\u542b\u53d1\u9001/\u63a5\u6536\u5b57\u8282\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/settings/#getapptxbytes","title":"getAppTxBytes()","text":"

      \u83b7\u53d6 QPython \u5e94\u7528\u7684\u53d1\u9001\u5b57\u8282\u3002

      getAppTxBytes(packageName)\n

      \u53c2\u6570\uff1a - packageName (str): \u5305\u540d

      \u8fd4\u56de\uff1a \u5305\u542b tx/rx \u5b57\u8282\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/settings/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5c4f\u5e55\u8bbe\u7f6e\ncurrent_timeout = droid.getScreenTimeout().result\nprint(f\"Current timeout: {current_timeout}s\")\ndroid.setScreenTimeout(30)\n\n# \u68c0\u67e5\u5c4f\u5e55\nif droid.checkScreenOn().result:\n    print(\"Screen is on\")\n\n# \u97f3\u91cf\u63a7\u5236\nmedia_vol = droid.getMediaVolume().result\nprint(f\"Media volume: {media_vol}\")\ndroid.setMediaVolume(10)\n\n# \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\nif droid.checkAirplaneMode().result:\n    print(\"Airplane mode is on\")\n
      "},{"location":"qsl4a/system/sysinfo/","title":"\u7cfb\u7edf\u4fe1\u606f","text":"

      \u68c0\u7d22\u8bbe\u5907\u548c\u7cfb\u7edf\u4fe1\u606f\u3002

      "},{"location":"qsl4a/system/sysinfo/#_2","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/sysinfo/#getandroidid","title":"getAndroidID()","text":"

      \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

      getAndroidID()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

      "},{"location":"qsl4a/system/sysinfo/#getsysinfo","title":"getSysInfo()","text":"

      \u83b7\u53d6\u7efc\u5408\u7cfb\u7edf\u4fe1\u606f\u3002

      getSysInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/sysinfo/#getlocale","title":"getLocale()","text":"

      \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u8bbe\u7f6e\u3002

      getLocale()\n

      \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

      "},{"location":"qsl4a/system/sysinfo/#_3","title":"\u5185\u5b58","text":""},{"location":"qsl4a/system/sysinfo/#getmemoryinfo","title":"getMemoryInfo()","text":"

      \u83b7\u53d6 RAM \u4fe1\u606f\u3002

      getMemoryInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/sysinfo/#_4","title":"\u663e\u793a","text":""},{"location":"qsl4a/system/sysinfo/#getscreeninfo","title":"getScreenInfo()","text":"

      \u83b7\u53d6\u663e\u793a\u4fe1\u606f\u3002

      getScreenInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/sysinfo/#_5","title":"\u6807\u8bc6\u7b26","text":""},{"location":"qsl4a/system/sysinfo/#getimei","title":"getImei()","text":"

      \u83b7\u53d6\u8bbe\u5907 IMEI\u3002

      getImei(slotIndex=None)\n
      "},{"location":"qsl4a/system/sysinfo/#getmeid","title":"getMeid()","text":"

      \u83b7\u53d6\u8bbe\u5907 MEID\u3002

      getMeid(slotIndex=None)\n
      "},{"location":"qsl4a/system/sysinfo/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u8bbe\u5907 ID\nandroid_id = droid.getAndroidID().result\nprint(f\"Android ID: {android_id}\")\n\n# \u5c4f\u5e55\u4fe1\u606f\nscreen = droid.getScreenInfo().result\nprint(f\"Screen: {screen['width']}x{screen['height']}\")\n\n# \u5185\u5b58\nmemory = droid.getMemoryInfo().result\nprint(f\"Memory: {memory}\")\n
      "},{"location":"qsl4a/system/wakelock/","title":"WakeLock API","text":"

      \u63a7\u5236\u8bbe\u5907\u5524\u9192\u9501\u4ee5\u4fdd\u6301 CPU \u6216\u5c4f\u5e55\u5f00\u542f\u3002

      "},{"location":"qsl4a/system/wakelock/#wake-lock","title":"Wake Lock \u7c7b\u578b","text":"

      QSL4A \u63d0\u4f9b\u4e0d\u540c\u7c7b\u578b\u7684\u5524\u9192\u9501\uff1a

      \u7c7b\u578b \u63cf\u8ff0 Full CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae Partial \u4ec5 CPU \u5f00\u542f Bright CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae Dim CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697"},{"location":"qsl4a/system/wakelock/#wake-lock_1","title":"Wake Lock \u65b9\u6cd5","text":""},{"location":"qsl4a/system/wakelock/#wakelockacquirefull","title":"wakeLockAcquireFull()","text":"

      \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae\uff09\u3002

      wakeLockAcquireFull()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquirepartial","title":"wakeLockAcquirePartial()","text":"

      \u83b7\u53d6\u90e8\u5206\u5524\u9192\u9501\uff08\u4ec5 CPU \u5f00\u542f\uff09\u3002

      wakeLockAcquirePartial()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquirebright","title":"wakeLockAcquireBright()","text":"

      \u83b7\u53d6\u660e\u4eae\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff09\u3002

      wakeLockAcquireBright()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquiredim","title":"wakeLockAcquireDim()","text":"

      \u83b7\u53d6\u6697\u6de1\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697\uff09\u3002

      wakeLockAcquireDim()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockrelease","title":"wakeLockRelease()","text":"

      \u91ca\u653e\u5524\u9192\u9501\u3002

      wakeLockRelease()\n
      "},{"location":"qsl4a/system/wakelock/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\ndroid.wakeLockAcquireFull()\n\n# \u5728\u4fdd\u6301\u5c4f\u5e55\u5f00\u542f\u65f6\u6267\u884c\u91cd\u8981\u5de5\u4f5c\nprint(\"Screen will stay on\")\ntime.sleep(10)\n\n# \u5b8c\u6210\u540e\u91ca\u653e\ndroid.wakeLockRelease()\n\n# \u6216\u4f7f\u7528\u90e8\u5206\u9501\u8fdb\u884c\u540e\u53f0\u4efb\u52a1\ndroid.wakeLockAcquirePartial()\n# \u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\uff0cCPU \u4ecd\u4fdd\u6301\u5f00\u542f\ntime.sleep(30)\ndroid.wakeLockRelease()\n

      \u6ce8\u610f\uff1a \u8bb0\u4f4f\u5728\u4e0d\u9700\u8981\u65f6\u91ca\u653e\u5524\u9192\u9501\u4ee5\u8282\u7701\u7535\u6c60\u3002

      "},{"location":"qsl4a/ui/accessibility/","title":"\u65e0\u969c\u788d\u670d\u52a1","text":"

      \u65e0\u969c\u788d\u670d\u52a1\u5141\u8bb8\u81ea\u52a8\u5316 UI \u4ea4\u4e92\uff0c\u5982\u70b9\u51fb\u3001\u6ed1\u52a8\u548c\u7cfb\u7edf\u64cd\u4f5c\u3002

      "},{"location":"qsl4a/ui/accessibility/#_2","title":"\u670d\u52a1\u63a7\u5236","text":""},{"location":"qsl4a/ui/accessibility/#accessibilitystartservice","title":"accessibilityStartService()","text":"

      \u542f\u52a8\u65e0\u969c\u788d\u670d\u52a1\u3002

      accessibilityStartService()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/ui/accessibility/#accessibilityserviceenabled","title":"accessibilityServiceEnabled()","text":"

      \u68c0\u67e5\u65e0\u969c\u788d\u670d\u52a1\u662f\u5426\u5df2\u542f\u7528\u3002

      accessibilityServiceEnabled()\n

      \u8fd4\u56de\uff1a True \u6216 False

      "},{"location":"qsl4a/ui/accessibility/#_3","title":"\u5c4f\u5e55\u4ea4\u4e92","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityclick","title":"accessibilityClick()","text":"

      \u5728\u5c4f\u5e55\u5750\u6807\u5904\u70b9\u51fb\u3002

      accessibilityClick(x=0, y=0, t=50)\n

      \u53c2\u6570\uff1a - x (int/float): X \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - y (int/float): Y \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - t (int): \u6309\u4f4f\u65f6\u957f\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a50\uff09

      "},{"location":"qsl4a/ui/accessibility/#accessibilityslide","title":"accessibilitySlide()","text":"

      \u591a\u70b9\u6ed1\u52a8\u624b\u52bf\u3002

      accessibilitySlide(XnYn=None, t=None)\n

      \u53c2\u6570\uff1a - XnYn (list): \u5750\u6807 [X1, Y1, X2, Y2, ... Xn, Yn] - t (int): \u6ed1\u52a8\u65f6\u957f\uff08\u9ed8\u8ba4\uff1a50*n \u6beb\u79d2\uff09

      "},{"location":"qsl4a/ui/accessibility/#_4","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityaction","title":"accessibilityAction()","text":"

      \u6309\u4ee3\u7801\u6267\u884c\u7cfb\u7edf\u64cd\u4f5c\u3002

      accessibilityAction(actionCode)\n

      \u64cd\u4f5c\u4ee3\u7801\uff1a | \u4ee3\u7801 | \u5e38\u91cf | \u63cf\u8ff0 | |------|----------|-------------| | 1 | BACK | \u8fd4\u56de\u6309\u94ae | | 2 | HOME | \u4e3b\u5c4f\u5e55\u6309\u94ae | | 3 | RECENTS | \u6700\u8fd1\u5e94\u7528 | | 4 | NOTIFICATIONS | \u6253\u5f00\u901a\u77e5 | | 5 | QUICK_SETTINGS | \u6253\u5f00\u5feb\u901f\u8bbe\u7f6e | | 6 | POWER_DIALOG | \u7535\u6e90\u83dc\u5355 | | 7 | TOGGLE_SPLIT_SCREEN | \u5206\u5c4f | | 8 | LOCK_SCREEN | \u9501\u5c4f | | 9 | TAKE_SCREENSHOT | \u622a\u56fe | | 10 | KEYCODE_HEADSETHOOK | \u8033\u673a\u6302\u94a9 | | 11-14 | ACCESSIBILITY_ | \u65e0\u969c\u788d\u6309\u94ae | | 15 | DISMISS_NOTIFICATION_SHADE | \u5173\u95ed\u901a\u77e5\u680f | | 16-20 | DPAD_ | \u65b9\u5411\u952e | | 21 | MENU | \u83dc\u5355\u6309\u94ae | | 22 | MEDIA_PLAY_PAUSE | \u64ad\u653e/\u6682\u505c\u5a92\u4f53 |

      "},{"location":"qsl4a/ui/accessibility/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/accessibility/#_6","title":"\u70b9\u51fb\u5c4f\u5e55\u4e2d\u5fc3","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u670d\u52a1\nif not droid.accessibilityServiceEnabled().result:\n    droid.accessibilityStartService()\n\n# \u70b9\u51fb\u4e2d\u5fc3\uff080,0 = \u4e2d\u5fc3\uff09\ndroid.accessibilityClick(0, 0, t=100)\n
      "},{"location":"qsl4a/ui/accessibility/#_7","title":"\u6ed1\u52a8\u624b\u52bf","text":"
      # \u4ece\u4e0b\u5f80\u4e0a\u6ed1\u52a8\uff08\u5411\u4e0a\u6eda\u52a8\uff09\ndroid.accessibilitySlide([0, 1.5, 0, -1.5], t=300)\n
      "},{"location":"qsl4a/ui/accessibility/#_8","title":"\u7cfb\u7edf\u5bfc\u822a","text":"
      # \u6309\u4e3b\u5c4f\u5e55\ndroid.accessibilityAction(2)\n\n# \u6309\u8fd4\u56de\ndroid.accessibilityAction(1)\n\n# \u6253\u5f00\u901a\u77e5\ndroid.accessibilityAction(4)\n
      "},{"location":"qsl4a/ui/accessibility/#_9","title":"\u70b9\u51fb\u7279\u5b9a\u4f4d\u7f6e","text":"
      # \u70b9\u51fb\u5c4f\u5e55\u5750\u6807 (500, 800)\ndroid.accessibilityClick(500, 800)\n\n# \u70b9\u51fb\u76f8\u5bf9\u4f4d\u7f6e\uff08\u6c34\u5e73\u5c45\u4e2d\uff0c\u5782\u76f4 3/4 \u5904\uff09\ndroid.accessibilityClick(0, 1.5)\n
      "},{"location":"qsl4a/ui/dialogs/","title":"\u5bf9\u8bdd\u6846\u7cfb\u7edf","text":"

      QSL4A \u63d0\u4f9b\u5168\u9762\u7684\u5bf9\u8bdd\u6846\u652f\u6301\uff0c\u7528\u4e8e\u7528\u6237\u4ea4\u4e92\uff0c\u5305\u62ec\u8b66\u62a5\u3001\u8f93\u5165\u5bf9\u8bdd\u6846\u3001\u9009\u62e9\u5bf9\u8bdd\u6846\u548c\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

      "},{"location":"qsl4a/ui/dialogs/#_2","title":"\u8b66\u62a5\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowalert","title":"dialogShowAlert()","text":"

      \u663e\u793a\u7b80\u5355\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

      dialogShowAlert(title=\"Alert\", message=\"The message of the alert.\",\n                positiveButtonText=\"OK\", negativeButtonText=None,\n                neutralButtonText=None, messageIsHtml=False)\n

      \u53c2\u6570\uff1a - title (str): \u5bf9\u8bdd\u6846\u6807\u9898 - message (str): \u6d88\u606f\u6587\u672c - positiveButtonText (str): \u80af\u5b9a\u6309\u94ae\u6807\u7b7e - negativeButtonText (str, optional): \u5426\u5b9a\u6309\u94ae\u6807\u7b7e - neutralButtonText (str, optional): \u4e2d\u6027\u6309\u94ae\u6807\u7b7e - messageIsHtml (bool): \u5c06\u6d88\u606f\u89e3\u6790\u4e3a HTML

      \u8fd4\u56de\uff1a \u5305\u542b\u70b9\u51fb\u6309\u94ae\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#dialogshowsimplechoice","title":"dialogShowSimpleChoice()","text":"

      \u663e\u793a\u5e26\u6709\u9879\u76ee\u7684\u7b80\u5355\u9009\u62e9\u5bf9\u8bdd\u6846\u3002

      dialogShowSimpleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

      \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868

      \u8fd4\u56de\uff1a \u5305\u542b\u9009\u4e2d\u9879\u76ee\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#_3","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialoggetinput","title":"dialogGetInput()","text":"

      \u83b7\u53d6\u7528\u6237\u6587\u672c\u8f93\u5165\u3002

      dialogGetInput(title=\"Value\", message=\"Please enter value:\",\n               defaultText=None, messageIsHtml=False)\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7528\u6237\u8f93\u5165\u6587\u672c\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#dialoggetpassword","title":"dialogGetPassword()","text":"

      \u83b7\u53d6\u5bc6\u7801\u8f93\u5165\u3002

      dialogGetPassword(title=\"Password\", message=\"Please enter password:\")\n

      \u8fd4\u56de\uff1a \u5305\u542b\u8f93\u5165\u5bc6\u7801\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#dialogcreateinput","title":"dialogCreateInput()","text":"

      \u521b\u5efa\u81ea\u5b9a\u4e49\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

      dialogCreateInput(title=\"Value\", message=\"Please enter value:\",\n                  defaultText=None, inputType=None)\n

      \u53c2\u6570\uff1a - inputType (str): \u8f93\u5165\u7c7b\u578b\uff08\u4f8b\u5982 \"text\"\u3001\"number\"\u3001\"textPassword\"\uff09

      "},{"location":"qsl4a/ui/dialogs/#dialogcreatepassword","title":"dialogCreatePassword()","text":"

      \u521b\u5efa\u5bc6\u7801\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

      dialogCreatePassword(title=\"Password\", message=\"Please enter password:\")\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreateseekbar","title":"dialogCreateSeekBar()","text":"

      \u521b\u5efa\u6ed1\u5757/\u8fdb\u5ea6\u6761\u5bf9\u8bdd\u6846\u3002

      dialogCreateSeekBar(starting_value=50, maximum_value=100, title=\"\", message=\"\")\n

      \u53c2\u6570\uff1a - starting_value (int): \u521d\u59cb\u503c - maximum_value (int): \u6700\u5927\u503c

      "},{"location":"qsl4a/ui/dialogs/#_4","title":"\u9009\u62e9\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowsinglechoice","title":"dialogShowSingleChoice()","text":"

      \u663e\u793a\u5355\u9009\uff08\u5355\u9009\u6309\u94ae\uff09\u5bf9\u8bdd\u6846\u3002

      dialogShowSingleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, selected=-1, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

      \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (int): \u9ed8\u8ba4\u9009\u4e2d\u7d22\u5f15

      "},{"location":"qsl4a/ui/dialogs/#dialogshowmultichoice","title":"dialogShowMultiChoice()","text":"

      \u663e\u793a\u591a\u9009\uff08\u590d\u9009\u6846\uff09\u5bf9\u8bdd\u6846\u3002

      dialogShowMultiChoice(title=\"Alert\", message=\"The message of the alert.\",\n                      items=None, selected=None, positiveButtonText=\"OK\",\n                      negativeButtonText=None, neutralButtonText=None,\n                      messageIsHtml=False)\n

      \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (list): \u521d\u59cb\u9009\u4e2d\u7d22\u5f15\u5217\u8868

      "},{"location":"qsl4a/ui/dialogs/#dialogsetsinglechoiceitems","title":"dialogSetSingleChoiceItems()","text":"

      \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u5355\u9009\u9879\u76ee\u3002

      dialogSetSingleChoiceItems(items, selected=-1)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmultichoiceitems","title":"dialogSetMultiChoiceItems()","text":"

      \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u591a\u9009\u9879\u76ee\u3002

      dialogSetMultiChoiceItems(items, selected=None)\n
      "},{"location":"qsl4a/ui/dialogs/#_5","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatespinnerprogress","title":"dialogCreateSpinnerProgress()","text":"

      \u521b\u5efa\u4e0d\u786e\u5b9a\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

      dialogCreateSpinnerProgress(title=None, message=None, maximum_progress=100)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreatehorizontalprogress","title":"dialogCreateHorizontalProgress()","text":"

      \u521b\u5efa\u6c34\u5e73\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

      dialogCreateHorizontalProgress(title=None, message=None, maximum_progress=100)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetcurrentprogress","title":"dialogSetCurrentProgress()","text":"

      \u66f4\u65b0\u8fdb\u5ea6\u503c\u3002

      dialogSetCurrentProgress(current)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmaxprogress","title":"dialogSetMaxProgress()","text":"

      \u8bbe\u7f6e\u6700\u5927\u8fdb\u5ea6\u503c\u3002

      dialogSetMaxProgress(max)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetprogressmessage","title":"dialogSetProgressMessage()","text":"

      \u66f4\u65b0\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u6d88\u606f\u3002

      dialogSetProgressMessage(message)\n
      "},{"location":"qsl4a/ui/dialogs/#_6","title":"\u9009\u62e9\u5668\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatedatepicker","title":"dialogCreateDatePicker()","text":"

      \u521b\u5efa\u65e5\u671f\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

      dialogCreateDatePicker(year=1970, month=1, day=1)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreatetimepicker","title":"dialogCreateTimePicker()","text":"

      \u521b\u5efa\u65f6\u95f4\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

      dialogCreateTimePicker(hour=0, minute=0, is24hour=False)\n
      "},{"location":"qsl4a/ui/dialogs/#_7","title":"\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u521b\u5efa","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatealert","title":"dialogCreateAlert()","text":"

      \u521b\u5efa\u81ea\u5b9a\u4e49\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

      dialogCreateAlert(title=None, message=None)\n

      \u521b\u5efa\u4e00\u4e2a\u7a7a\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002\u53ef\u4e0e\u5176\u4ed6 dialogSet* \u51fd\u6570\u4e00\u8d77\u4f7f\u7528\u6765\u81ea\u5b9a\u4e49\u3002

      "},{"location":"qsl4a/ui/dialogs/#dialogsetitems","title":"dialogSetItems()","text":"

      \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u7b80\u5355\u5217\u8868\u9879\u76ee\u3002

      dialogSetItems(items)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetpositivebuttontext","title":"dialogSetPositiveButtonText()","text":"

      \u8bbe\u7f6e\u80af\u5b9a\u6309\u94ae\u6587\u672c\u3002

      dialogSetPositiveButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetnegativebuttontext","title":"dialogSetNegativeButtonText()","text":"

      \u8bbe\u7f6e\u5426\u5b9a\u6309\u94ae\u6587\u672c\u3002

      dialogSetNegativeButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetneutralbuttontext","title":"dialogSetNeutralButtonText()","text":"

      \u8bbe\u7f6e\u4e2d\u6027\u6309\u94ae\u6587\u672c\u3002

      dialogSetNeutralButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmessageishtml","title":"dialogSetMessageIsHtml()","text":"

      \u8bbe\u7f6e\u6d88\u606f\u662f\u5426\u5e94\u89e3\u6790\u4e3a HTML\u3002

      dialogSetMessageIsHtml(messageIsHtml=True)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogshow","title":"dialogShow()","text":"

      \u663e\u793a\u521b\u5efa\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u3002

      dialogShow()\n
      "},{"location":"qsl4a/ui/dialogs/#_8","title":"\u5bf9\u8bdd\u6846\u63a7\u5236","text":""},{"location":"qsl4a/ui/dialogs/#dialogdismiss","title":"dialogDismiss()","text":"

      \u5173\u95ed\u5f53\u524d\u5bf9\u8bdd\u6846\u3002

      dialogDismiss()\n
      "},{"location":"qsl4a/ui/dialogs/#dialoggetresponse","title":"dialogGetResponse()","text":"

      \u83b7\u53d6\u5bf9\u8bdd\u6846\u54cd\u5e94\u3002

      dialogGetResponse()\n
      "},{"location":"qsl4a/ui/dialogs/#dialoggetselecteditems","title":"dialogGetSelectedItems()","text":"

      \u4ece\u9009\u62e9\u5bf9\u8bdd\u6846\u83b7\u53d6\u9009\u4e2d\u7684\u9879\u76ee\u3002

      dialogGetSelectedItems()\n
      "},{"location":"qsl4a/ui/dialogs/#_9","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/dialogs/#_10","title":"\u7b80\u5355\u8b66\u62a5","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a\u8b66\u62a5\ndroid.dialogShowAlert(\"Warning\", \"This is an important message!\")\n
      "},{"location":"qsl4a/ui/dialogs/#_11","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":"
      # \u83b7\u53d6\u7528\u6237\u8f93\u5165\nresult = droid.dialogGetInput(\"Name\", \"Enter your name:\", \"John\").result\nprint(f\"Hello, {result}!\")\n
      "},{"location":"qsl4a/ui/dialogs/#_12","title":"\u5e26\u6309\u94ae\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846","text":"
      # \u521b\u5efa\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\ndroid.dialogCreateAlert(\"Custom\", \"Choose an option\")\ndroid.dialogSetItems([\"Option 1\", \"Option 2\", \"Option 3\"])\ndroid.dialogShow()\n\n# \u83b7\u53d6\u54cd\u5e94\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response['item']}\")\n
      "},{"location":"qsl4a/ui/dialogs/#_13","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":"
      # \u521b\u5efa\u8fdb\u5ea6\u5bf9\u8bdd\u6846\ndroid.dialogCreateHorizontalProgress(\"Loading\", \"Please wait...\", 100)\ndroid.dialogShow()\n\n# \u66f4\u65b0\u8fdb\u5ea6\nfor i in range(101):\n    droid.dialogSetCurrentProgress(i)\n    time.sleep(0.05)\n\ndroid.dialogDismiss()\n
      "},{"location":"qsl4a/ui/dialogs/#_14","title":"\u65e5\u671f\u9009\u62e9\u5668","text":"
      # \u663e\u793a\u65e5\u671f\u9009\u62e9\u5668\ndroid.dialogCreateDatePicker(2024, 1, 15)\ndroid.dialogShow()\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response}\")\n
      "},{"location":"qsl4a/ui/floatview/","title":"\u6d6e\u52a8\u89c6\u56fe","text":"

      \u6d6e\u52a8\u7a97\u53e3\u652f\u6301\uff0c\u7528\u4e8e\u5728\u5176\u4ed6\u5e94\u7528\u7a0b\u5e8f\u4e0a\u65b9\u4fdd\u6301\u663e\u793a\u7684\u8986\u76d6 UI \u5143\u7d20\u3002

      "},{"location":"qsl4a/ui/floatview/#_2","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/floatview/#floatview","title":"floatView()","text":"

      \u663e\u793a\u6216\u4fee\u6539\u6d6e\u52a8\u89c6\u56fe\u3002

      floatView(Args=None)\n

      \u53c2\u6570\uff1a - Args (dict): \u914d\u7f6e\u5b57\u5178\uff0c\u5305\u542b\u4ee5\u4e0b\u952e\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08-1 \u521b\u5efa\u65b0\u7684\uff0c>=0 \u4fee\u6539\u73b0\u6709\u7684\uff09 - text (str): \u8981\u663e\u793a\u7684\u6587\u672c\u5185\u5bb9 - html (str): HTML \u5185\u5bb9\uff08\u5982\u679c\u7701\u7565 text \u5219\u4f7f\u7528\uff09 - width (int): \u89c6\u56fe\u5bbd\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a300\uff09 - height (int): \u89c6\u56fe\u9ad8\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a150\uff09 - x (int): X \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - y (int): Y \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - backColor (str): ARGB \u5341\u516d\u8fdb\u5236\u80cc\u666f\u8272\uff08\u9ed8\u8ba4\uff1a'7f7f7f7f'\uff09 - textColor (str): ARGB \u5341\u516d\u8fdb\u5236\u6587\u672c\u8272\uff08\u9ed8\u8ba4\uff1a'ff000000'\uff09 - textSize (int): \u6587\u672c\u5927\u5c0f\uff08\u9ed8\u8ba4\uff1a10\uff09 - textAlign (int): \u6587\u672c\u5bf9\u9f50\uff080 = \u7ee7\u627f\uff09 - script (str): \u957f\u6309\u5173\u95ed\u540e\u8fd0\u884c\u7684\u811a\u672c\u8def\u5f84 - arg: \u811a\u672c\u53c2\u6570 - clickRemove (bool): \u542f\u7528\u70b9\u51fb\u79fb\u9664\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - flag (int): \u7a97\u53e3\u6807\u5fd7\uff08\u9ed8\u8ba4\uff1a40 - \u53ef\u89e6\u6478\uff09

      \u8fd4\u56de\uff1a \u5f53\u524d\u94fe\u5217\u8868\u957f\u5ea6

      "},{"location":"qsl4a/ui/floatview/#floatviewcount","title":"floatViewCount()","text":"

      \u83b7\u53d6\u6d3b\u52a8\u6d6e\u52a8\u89c6\u56fe\u7684\u6570\u91cf\u3002

      floatViewCount()\n

      \u8fd4\u56de\uff1a \u6d6e\u52a8\u89c6\u56fe\u6570\u91cf

      "},{"location":"qsl4a/ui/floatview/#floatviewresult","title":"floatViewResult()","text":"

      \u83b7\u53d6\u6d6e\u52a8\u89c6\u56fe\u7684\u7ed3\u679c/\u72b6\u6001\u3002

      floatViewResult(index=-1)\n

      \u53c2\u6570\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1\uff0c\u8fd4\u56de\u6700\u540e\u64cd\u4f5c\u7ed3\u679c\uff09

      \u8fd4\u56de\uff1a \u5305\u542b\u64cd\u4f5c\u8be6\u60c5\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - x, y: \u4f4d\u7f6e - time: \u65f6\u95f4\u6233 - operation: \u64cd\u4f5c\u7c7b\u578b\uff08'initial'\u3001'move' \u7b49\uff09 - index: \u89c6\u56fe\u7d22\u5f15 - removed: \u5982\u679c\u89c6\u56fe\u88ab\u79fb\u9664\u5219\u4e3a True

      "},{"location":"qsl4a/ui/floatview/#floatviewremove","title":"floatViewRemove()","text":"

      \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\u3002

      floatViewRemove(index=-1)\n

      \u53c2\u6570\uff1a - index (int): \u8981\u79fb\u9664\u7684\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1 \u79fb\u9664\u6700\u540e\u4e00\u4e2a\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a 1\uff0c\u5426\u5219\u4e3a 0

      "},{"location":"qsl4a/ui/floatview/#_3","title":"\u5e38\u91cf","text":"
      • floatView.INDEX_NEW = -1 - \u521b\u5efa\u65b0\u7684\u6d6e\u52a8\u89c6\u56fe
      • floatView.FLAG_DEFAULT_TOUCHABLE = 40 - \u9ed8\u8ba4\u53ef\u89e6\u6478\u6807\u5fd7
      • floatView.TEXT_ALIGNMENT_INHERIT = 0
      • floatView.TEXT_ALIGNMENT_CENTER - \u5c45\u4e2d\u6587\u672c\u5bf9\u9f50
      "},{"location":"qsl4a/ui/floatview/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/floatview/#_5","title":"\u57fa\u672c\u6d6e\u52a8\u89c6\u56fe","text":"
      import androidhelper\nfrom androidhelper import Android\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u7b80\u5355\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'index': -1,  # \u521b\u5efa\u65b0\u7684\n    'text': 'Hello World',\n    'width': 400,\n    'height': 300,\n    'x': -300,  # \u4ece\u4e2d\u5fc3\u504f\u79fb\n    'y': -400,\n    'backColor': 'ff0000',  # \u7ea2\u8272\u80cc\u666f\n    'textColor': '0000ff',  # \u84dd\u8272\u6587\u672c\n    'textSize': 16,\n    'textAlign': droid.floatView.TEXT_ALIGNMENT_CENTER\n})\n\n# \u68c0\u67e5\u6570\u91cf\nprint(f\"Float views: {droid.floatViewCount().result}\")\n\n# \u83b7\u53d6\u7ed3\u679c\nresult = droid.floatViewResult().result\nprint(f\"View info: {result}\")\n\n# \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\ndroid.floatViewRemove(0)\n
      "},{"location":"qsl4a/ui/floatview/#html","title":"HTML \u5185\u5bb9","text":"
      # \u521b\u5efa\u5e26 HTML \u5185\u5bb9\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': '',  # \u7a7a\u6587\u672c\u4ee5\u4f7f\u7528 HTML\n    'html': '<h1>Title</h1><p>Rich <b>HTML</b> content</p>',\n    'width': 500,\n    'height': 400\n})\n
      "},{"location":"qsl4a/ui/floatview/#_6","title":"\u4fee\u6539\u73b0\u6709\u89c6\u56fe","text":"
      # \u521b\u5efa\u521d\u59cb\u89c6\u56fe\ndroid.floatView({'text': 'Initial Text', 'width': 300, 'height': 150})\n\n# \u4fee\u6539\u540c\u4e00\u89c6\u56fe\uff08\u7d22\u5f15 0\uff09\ndroid.floatView({\n    'index': 0,\n    'text': 'Updated Text!',\n    'backColor': '7f00ff00'  # \u7eff\u8272\u80cc\u666f\n})\n\n# \u68c0\u67e5\u79fb\u52a8/\u66f4\u6539\u7ed3\u679c\nresult = droid.floatViewResult(0).result\nprint(f\"Operation: {result.get('operation')}, Position: ({result.get('x')}, {result.get('y')})\")\n
      "},{"location":"qsl4a/ui/floatview/#_7","title":"\u591a\u4e2a\u6d6e\u52a8\u89c6\u56fe","text":"
      # \u521b\u5efa\u591a\u4e2a\u89c6\u56fe\nfor i in range(3):\n    droid.floatView({\n        'index': -1,\n        'text': f'View {i}',\n        'x': i * 100 - 150,\n        'y': i * 100 - 150,\n        'backColor': f'{i}f{i}f{i}f'\n    })\n\nprint(f\"Total views: {droid.floatViewCount().result}\")\n\n# \u79fb\u9664\u6240\u6709\u89c6\u56fe\nwhile droid.floatViewCount().result > 0:\n    droid.floatViewRemove()\n
      "},{"location":"qsl4a/ui/floatview/#_8","title":"\u5e26\u811a\u672c\u56de\u8c03","text":"
      # \u521b\u5efa\u5173\u95ed\u65f6\u8fd0\u884c\u811a\u672c\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': 'Click to close and run script',\n    'script': '/sdcard/my_script.py',\n    'arg': 'hello from float view',\n    'clickRemove': True\n})\n
      "},{"location":"qsl4a/ui/fullscreen/","title":"\u5168\u5c4f UI","text":"

      \u4f7f\u7528\u539f\u751f Android \u5e03\u5c40\u521b\u5efa\u81ea\u5b9a\u4e49\u5168\u5c4f\u754c\u9762\u3002

      "},{"location":"qsl4a/ui/fullscreen/#_1","title":"\u5e03\u5c40\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullshow","title":"fullShow()","text":"

      \u663e\u793a\u5168\u5c4f\u5e03\u5c40\u3002

      fullShow(layout, title=None, theme=None)\n

      \u53c2\u6570\uff1a - layout (str): JSON \u5e03\u5c40\u5b9a\u4e49\u6216\u5e03\u5c40\u5b57\u7b26\u4e32 - title (str, optional): \u7a97\u53e3\u6807\u9898 - theme (str, optional): \u4e3b\u9898\u540d\u79f0

      \u8fd4\u56de\uff1a \u7a97\u53e3 ID

      "},{"location":"qsl4a/ui/fullscreen/#fulldismiss","title":"fullDismiss()","text":"

      \u5173\u95ed\u5168\u5c4f\u7a97\u53e3\u3002

      fullDismiss()\n
      "},{"location":"qsl4a/ui/fullscreen/#fullquery","title":"fullQuery()","text":"

      \u67e5\u8be2\u6240\u6709\u5c0f\u90e8\u4ef6\u503c\u3002

      fullQuery()\n

      \u8fd4\u56de\uff1a \u5c0f\u90e8\u4ef6 ID \u548c\u503c\u7684\u5b57\u5178

      "},{"location":"qsl4a/ui/fullscreen/#fullquerydetail","title":"fullQueryDetail()","text":"

      \u67e5\u8be2\u7279\u5b9a\u5c0f\u90e8\u4ef6\u8be6\u60c5\u3002

      fullQueryDetail(id)\n
      "},{"location":"qsl4a/ui/fullscreen/#_2","title":"\u5c5e\u6027\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperty","title":"fullGetProperty()","text":"

      \u83b7\u53d6\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

      fullGetProperty(id, property)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetproperty","title":"fullSetProperty()","text":"

      \u8bbe\u7f6e\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

      fullSetProperty(id, property, value)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetlist","title":"fullSetList()","text":"

      \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

      fullSetList(id, list, isHtml=False, listType=0)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetlist2","title":"fullSetList2()","text":"

      \u4f7f\u7528\u8d44\u6e90 ID \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

      fullSetList2(id, list, intRes)\n

      \u53c2\u6570\uff1a - id (str): \u5c0f\u90e8\u4ef6 ID - list (list): \u9879\u76ee\u5217\u8868 - intRes (int): \u5217\u8868\u9879\u76ee\u5e03\u5c40\u7684 Android \u8d44\u6e90 ID

      "},{"location":"qsl4a/ui/fullscreen/#fullsetlistselected","title":"fullSetListSelected()","text":"

      \u5728\u5217\u8868\u4e2d\u8bbe\u7f6e\u9009\u4e2d\u9879\u76ee\u3002

      fullSetListSelected(id, selected)\n

      \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID - selected (int): \u8981\u9009\u4e2d\u7684\u9879\u76ee\u7d22\u5f15

      "},{"location":"qsl4a/ui/fullscreen/#fullgetlistselected","title":"fullGetListSelected()","text":"

      \u83b7\u53d6\u5f53\u524d\u9009\u4e2d\u7684\u5217\u8868\u9879\u76ee\u7d22\u5f15\u3002

      fullGetListSelected(id)\n

      \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID

      \u8fd4\u56de\uff1a \u9009\u4e2d\u9879\u76ee\u7d22\u5f15

      "},{"location":"qsl4a/ui/fullscreen/#_3","title":"\u6279\u91cf\u5c5e\u6027\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperties","title":"fullGetProperties()","text":"

      \u4e00\u6b21\u83b7\u53d6\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

      fullGetProperties(ids, property)\n

      \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u83b7\u53d6\u7684\u5c5e\u6027\u540d

      \u8fd4\u56de\uff1a \u6620\u5c04\u5c0f\u90e8\u4ef6 ID \u5230\u5c5e\u6027\u503c\u7684\u5b57\u5178

      "},{"location":"qsl4a/ui/fullscreen/#fullsetproperties","title":"fullSetProperties()","text":"

      \u4e00\u6b21\u8bbe\u7f6e\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

      fullSetProperties(ids, property, value)\n

      \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u8bbe\u7f6e\u7684\u5c5e\u6027\u540d - value: \u5c5e\u6027\u503c

      "},{"location":"qsl4a/ui/fullscreen/#_4","title":"\u622a\u56fe","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetscreenshot","title":"fullGetScreenShot()","text":"

      \u6355\u83b7\u5168\u5c4f\u622a\u56fe\u3002

      fullGetScreenShot(path=None)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u5728\u4e8b\u4ef6\u4e2d\u8fd4\u56de

      \u8fd4\u56de\uff1a \u5305\u542b\u622a\u56fe\u6570\u636e\u7684\u4e8b\u4ef6

      "},{"location":"qsl4a/ui/fullscreen/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b9a\u4e49\u5e03\u5c40\nlayout = '''\n{ \"type\": \"LinearLayout\", \"orientation\": \"vertical\",\n  \"children\": [\n    { \"type\": \"TextView\", \"id\": \"title\", \"text\": \"Hello\" },\n    { \"type\": \"Button\", \"id\": \"btn\", \"text\": \"Click Me\" }\n  ]\n}\n'''\n\n# \u663e\u793a\u5e03\u5c40\ndroid.fullShow(layout, \"My App\")\n\n# \u67e5\u8be2\u6309\u94ae\u70b9\u51fb\nevent = droid.eventWaitFor('click', timeout=10)\nif event.result:\n    widget_id = event.result['data']['id']\n    if widget_id == 'btn':\n        print(\"Button clicked!\")\n\ndroid.fullDismiss()\n
      "}]} \ No newline at end of file diff --git a/zh/sitemap.xml b/zh/sitemap.xml index c82f0cd..bd82aa8 100644 --- a/zh/sitemap.xml +++ b/zh/sitemap.xml @@ -2,198 +2,198 @@ https://www.qpython.org/zh/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/AIPyApp/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/GraphicalInterface/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/Notebook/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/Ollama/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/Terminal/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/community/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/editor-guide/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/external-api/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/getting-started/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/qpypi-guide/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/qpython-x/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/tutorial-hello-world/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/whats-new/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/qsl4a/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/qsl4a/connectivity/contacts/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/qsl4a/connectivity/ftp/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/qsl4a/connectivity/location/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/qsl4a/connectivity/phone/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/qsl4a/connectivity/signalstrength/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/qsl4a/connectivity/sms/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/qsl4a/connectivity/wifi/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/qsl4a/core/android-base/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/qsl4a/core/events/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/qsl4a/core/intent/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/qsl4a/hardware/bluetooth/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/qsl4a/hardware/camera/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/qsl4a/hardware/recorder/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/qsl4a/hardware/usbserial/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/qsl4a/hardware/webcam/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/qsl4a/media/image/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/qsl4a/media/mediaplayer/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/qsl4a/special/cipher/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/qsl4a/special/pgptai/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/qsl4a/storage/clipboard/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/qsl4a/storage/documentfile/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/qsl4a/storage/preferences/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/qsl4a/system/activityresult/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/qsl4a/system/application/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/qsl4a/system/battery/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/qsl4a/system/qpyinterface/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/qsl4a/system/sensors/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/qsl4a/system/settings/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/qsl4a/system/sysinfo/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/qsl4a/system/wakelock/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/qsl4a/ui/accessibility/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/qsl4a/ui/dialogs/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/qsl4a/ui/floatview/ - 2026-03-29 + 2026-04-08 https://www.qpython.org/zh/qsl4a/ui/fullscreen/ - 2026-03-29 + 2026-04-08 \ No newline at end of file diff --git a/zh/sitemap.xml.gz b/zh/sitemap.xml.gz index e7a14f4704d5606c649edf0957d5647d79262602..b7beb395572b34625294fbe910a0ba367cc0bc58 100644 GIT binary patch delta 593 zcmV-X0`o$4SsXN!j$6u_IkJ9ZZNvkQta=yKb}8VciV^K)nP22Q8sEE z`F=Zy)NM zGOa4yqljjyiUo>byQ;P}GZ}vj_N7_9uBs}dh8C%d2lPHwQ!0Ml;hqK%t|CtB4mSH+ zFi>;0%zD8>Zre2dSOTpO7U``Xv19YN}Oc)B* z5ZjWdtr}poV!#tdqcoxFq;+f*1N8w)JAo23end&hWG=izI0#t4lAwQ}`lH2S$uM%m zxD*VQ5EC})4FiIpr8v|Sphq+H^ErE%O#*>4y2bmB@?Z*(`z&CwDzFyJi~pUc+$0T2 zLxwiFF=%q`$fF@fF4&<~D-JCdDV|v{)NrX53i9a1kRxYLX4UKkq5;ug_t_3W-;v4w z*IyKjkyBwyfb&L%CBZ?=6uV>xFu@C|{fhy?NSYNiDKRzV*WR^zN6_WkCzB9R@y;iZ f6PawUEb^oG>|T2=JB_Yh!J$ww@KBKTEBT?%20B=f4O*pj4D^&_?G#u7ej1nU@A zkZD!n9z`@uRV+{h+f}u-naO`(urJN(c~w;zHMB@wJfQcfno{xW4)-*Ga20V{cd*%i z00TvrVnio&T5^as1e~xnM<>}DLB9aeGR2xB>ua=zVCpsLvJ{NH4CXY!JU}Pv$b_L_ z4Y4hW+NuFYD+WAaG)fbyPFlxCF;E|%v=b;n<42T~OyZ&JLk*W|p&*Z53^{W4WLC{yAQ}+;b)W43^c|V( zfBi$j7&#TT1UPSGSQ0|aOtDLL024f++CLc(jHFpXlM+)ye(hbmR|H+IeKH9F74Lik gIg!cs$|65{&#oZ8As3!6I+2cl02z*7?9mti0C)iv`~Uy| From 2f88b26927dd6693bb8211a7cb8d6b52e918ab9b Mon Sep 17 00:00:00 2001 From: "River@devbox" Date: Wed, 8 Apr 2026 18:26:03 +0800 Subject: [PATCH 29/32] Deploy site - 2026-04-08 18:26:02 --- zh/community/index.html | 51 +++++++++++-------------------------- zh/search/search_index.json | 2 +- 2 files changed, 16 insertions(+), 37 deletions(-) diff --git a/zh/community/index.html b/zh/community/index.html index c0a1c24..3695b6d 100644 --- a/zh/community/index.html +++ b/zh/community/index.html @@ -2633,10 +2633,10 @@
    808. - + - QPython 知识星球 VIP社区 + QPython 社区推荐服务 @@ -2644,10 +2644,10 @@
    809. - + - QPython 社区推荐服务 + QPython 知识星球 VIP社区 @@ -2657,17 +2657,6 @@ -
    810. - -
    811. - - - - 如果您想推荐你的 QPython 社区服务,也欢迎微信联系。 - - - -
    812. @@ -2796,10 +2785,10 @@
    813. - + - QPython 知识星球 VIP社区 + QPython 社区推荐服务 @@ -2807,10 +2796,10 @@
    814. - + - QPython 社区推荐服务 + QPython 知识星球 VIP社区 @@ -2820,17 +2809,6 @@ -
    815. - -
    816. - - - - 如果您想推荐你的 QPython 社区服务,也欢迎微信联系。 - - - -
    817. @@ -2890,6 +2868,12 @@

      QPython微信群 & QQ群QPython 社区推荐服务

      +

      在 QPython 的使用过程中,部分用户希望将自己开发的脚本或服务打包成独立的安卓应用。为此,我们特别筛选了以下优质服务,供您按需选择:

      + +

      如果您想推荐你的 QPython 社区服务,也欢迎微信联系。

      QPython 知识星球 VIP社区

      QPython官方付费VIP专属社区,为深度用户提供官方团队直连、及时技术支持、高质量交流的专属服务空间。加入VIP社区可获下列核心价值:

        @@ -2898,12 +2882,7 @@

        QPython 知识星球 VIP社区

      -

      QPython 社区推荐服务

      -

      在 QPython 的使用过程中,部分用户希望将自己开发的脚本或服务打包成独立的安卓应用。为此,我们特别筛选了以下优质服务,供您按需选择:

      - -

      如果您想推荐你的 QPython 社区服务,也欢迎微信联系。

      +

      QPython 团队会定期在社区中更新项目进展,欢迎关注!

      diff --git a/zh/search/search_index.json b/zh/search/search_index.json index 0f05a03..1f77fb5 100644 --- a/zh/search/search_index.json +++ b/zh/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"QPython \u9879\u76ee","text":"

      QPython \u4e0d\u4ec5\u662f\u4e00\u4e2a\u5f3a\u5927\u7684 Android Python IDE\uff0c\u4e5f\u662f\u4e00\u4e2a\u6d3b\u8dc3\u7684\u6280\u672f\u793e\u533a\u3002

      "},{"location":"#ai-android-python-ide","title":"\u652f\u6301 AI \u7684 Android Python IDE","text":"

      QPython \u662f\u60a8\u8fdb\u884c Android Python \u7f16\u7a0b\u7684\u5165\u53e3\u3002\u5b83\u96c6\u6210\u4e86 Python \u89e3\u91ca\u5668\u3001AI \u6a21\u578b\u5f15\u64ce\u548c\u79fb\u52a8\u5f00\u53d1\u5de5\u5177\u94fe\uff0c\u8ba9\u60a8\u80fd\u591f\u4ece\u79fb\u52a8\u8bbe\u5907\u6784\u5efa Web \u5e94\u7528\u7a0b\u5e8f\u3001\u6267\u884c\u79d1\u5b66\u8ba1\u7b97\u548c\u521b\u5efa\u667a\u80fd\u5e94\u7528\u3002

      \u65e0\u8bba\u60a8\u662f\u5728\u5b66\u4e60\u7f16\u7a0b\u3001\u6784\u5efa\u6570\u636e\u79d1\u5b66\u9879\u76ee\uff0c\u8fd8\u662f\u5f00\u53d1 AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f\uff0cQPython \u90fd\u63d0\u4f9b\u4e86\u5b8c\u6574\u7684\u79fb\u52a8\u7f16\u7a0b\u89e3\u51b3\u65b9\u6848\uff0c\u62e5\u6709\u5168\u9762\u7684\u5f00\u53d1\u8005\u8d44\u6e90\u548c\u6d3b\u8dc3\u7684\u793e\u533a\u6765\u652f\u6301\u60a8\u7684\u65c5\u7a0b\u3002

      • \u5206\u652f\u7248\u672c \u2013 \u4e86\u89e3\u4e0d\u540c\u7684 QPython \u7248\u672c\uff08IDE\u3001\u793e\u533a\u7248\u3001Plus\uff09\uff0c\u9009\u62e9\u9002\u5408\u60a8\u9700\u6c42\u7684\u7248\u672c
      • \u66f4\u65b0\u65e5\u5fd7 \u2013 \u968f\u65f6\u4e86\u89e3\u6700\u65b0\u529f\u80fd\u3001\u6539\u8fdb\u548c\u53d1\u884c\u8bf4\u660e
      "},{"location":"#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"

      \u5982\u4f55\u5feb\u901f\u5165\u95e8\uff1f\u8bf7\u6309\u7167\u4ee5\u4e0b\u6b65\u9aa4\uff1a

      • \u5feb\u901f\u5165\u95e8
      • Hello World \u6559\u7a0b
      "},{"location":"#_2","title":"\u7f16\u7a0b\u6307\u5357","text":"

      QPython \u4e0d\u4ec5\u63d0\u4f9b\u57fa\u7840\u7684 Python \u63a5\u53e3\u652f\u6301\uff0c\u66f4\u91cd\u8981\u7684\u662f\uff0c\u5b83\u8fd8\u5141\u8bb8\u60a8\u901a\u8fc7 QSL4A \u63a5\u53e3\u4f7f\u7528 Python \u8c03\u7528 Android API\u3002

      • Python \u6807\u51c6\u5e93 \u2013 \u901a\u7528\u7684 Python \u8bed\u6cd5\u548c\u5185\u7f6e\u5e93
      • QSL4A API \u2013 \u4ece Python \u8bbf\u95ee Android \u8bbe\u5907\u529f\u80fd\uff08\u76f8\u673a\u3001\u4f20\u611f\u5668\u3001\u77ed\u4fe1\u7b49\uff09
      • QPYPI \u6307\u5357 \u2013 \u5b89\u88c5\u989d\u5916\u7684 Python \u5305
      • \u7f16\u8f91\u5668\u6307\u5357 \u2013 \u4f7f\u7528\u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668
      • \u5916\u90e8 API \u2013 \u4e0e\u5916\u90e8\u5e94\u7528\u7a0b\u5e8f\u96c6\u6210
      "},{"location":"#_3","title":"\u4e0b\u8f7d\u8d44\u6e90","text":"
      • Google Drive
      • \u5fae\u4fe1\u7f51\u76d8
      "},{"location":"#_4","title":"\u793e\u533a\u4e0e\u53cd\u9988","text":"
      • \u4e2d\u6587\u4ea4\u6d41\u793e\u533a
      • \u95ee\u9898\u53cd\u9988
      • \u529f\u80fd\u6269\u5c55\u8bf7\u6c42
      "},{"location":"#_5","title":"\u5173\u6ce8\u6211\u4eec","text":"
      • B\u7ad9
      • Weibo
      "},{"location":"AIPyApp/","title":"AIPyApp - AI\u9a71\u52a8\u7684\u7a0b\u5e8f\u751f\u6210\u5668","text":"

      AIPyApp \u662f QPython \u4e2d\u7684\u667a\u80fd\u5de5\u5177\uff0c\u53ef\u4ee5\u5229\u7528 AI \u4ece\u81ea\u7136\u8bed\u8a00\u6307\u4ee4\u81ea\u52a8\u751f\u6210 Python \u7a0b\u5e8f\u3002

      "},{"location":"AIPyApp/#_1","title":"\u6982\u8ff0","text":"

      AIPyApp \u6539\u53d8\u4e86\u60a8\u7f16\u5199\u4ee3\u7801\u7684\u65b9\u5f0f\u2014\u2014\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u63cf\u8ff0\u60a8\u60f3\u8981\u7684\u529f\u80fd\uff0cAI \u5c31\u4f1a\u4e3a\u60a8\u751f\u6210 Python \u7a0b\u5e8f\u3002QPython \u8fd8\u5c06\u63a8\u51fa AIPy Academy\u2014\u2014\u4e00\u4e2a\u4e3a AI \u65f6\u4ee3\u91cf\u8eab\u5b9a\u5236\u7684 Python \u7f16\u7a0b\u8bfe\u7a0b\u5e73\u53f0\u3002

      "},{"location":"AIPyApp/#_2","title":"\u5b89\u88c5","text":"

      QPython \u6c1b\u56f4\u7f16\u7a0b\uff08Vibe Coding\uff09 01 - \u5982\u4f55\u542f\u7528AIPyApp

      "},{"location":"AIPyApp/#_3","title":"\u7b2c\u4e00\u6b65\uff1a\u4ece\u4eea\u8868\u76d8\u542f\u52a8","text":"
      1. \u6253\u5f00 QPython\uff0c\u8fdb\u5165 \u4eea\u8868\u76d8
      2. \u957f\u6309\u5f00\u59cb\u6309\u94ae

      \u5982\u679c\u672a\u5b89\u88c5 AIPyApp\uff0c\u7cfb\u7edf\u4f1a\u63d0\u793a\u60a8\u786e\u8ba4\u5b89\u88c5\u3002\u6309 \u56de\u8f66\u952e\u7ee7\u7eed\u3002

      QPython \u5c06\u81ea\u52a8\u4ece PYPI \u4e0b\u8f7d\u5e76\u5b89\u88c5\u6240\u9700\u7684\u4f9d\u8d56\u9879\u3002\u8bf7\u8010\u5fc3\u7b49\u5f85\u5b89\u88c5\u5b8c\u6210\u3002

      "},{"location":"AIPyApp/#aipyapp","title":"\u7b2c\u4e8c\u6b65\uff1a\u91cd\u65b0\u542f\u52a8 AIPyApp","text":"

      \u5b89\u88c5\u5b8c\u6210\u540e\uff0c\u8fd4\u56de QPython \u4eea\u8868\u76d8\uff0c\u518d\u6b21 \u957f\u6309\u5f00\u59cb\u6309\u94ae\u542f\u52a8 AIPyApp\u3002

      "},{"location":"AIPyApp/#_4","title":"\u914d\u7f6e","text":""},{"location":"AIPyApp/#ai","title":"\u8bbe\u7f6e\u60a8\u7684 AI \u5bc6\u94a5","text":"

      \u9996\u6b21\u542f\u52a8\u65f6\uff0c\u60a8\u9700\u8981\u63d0\u4f9b AI API \u5bc6\u94a5\uff1a

      1. \u5728 PGPT \u6ce8\u518c\uff1a\u5728 https://user.pgpt.cloud \u521b\u5efa\u8d26\u6237\u4ee5\u751f\u6210\u60a8\u7684 AI \u5bc6\u94a5
      2. \u9ad8\u7ea7\u9009\u9879\uff1aAIPyApp \u8fd8\u652f\u6301\u6765\u81ea OpenAI\u3001Deepseek \u548c\u5176\u4ed6\u63d0\u4f9b\u5546\u7684\u81ea\u5b9a\u4e49 AI \u5bc6\u94a5\uff08\u8be6\u89c1\u9ad8\u7ea7\u6559\u7a0b\uff09
      "},{"location":"AIPyApp/#ai_1","title":"\u8f93\u5165\u60a8\u7684 AI \u5bc6\u94a5","text":"
      1. \u957f\u6309\u8f93\u5165\u63d0\u793a
      2. \u4ece\u5f39\u51fa\u83dc\u5355\u4e2d\u9009\u62e9 \u7c98\u8d34
      3. \u6309 \u56de\u8f66\u952e\u786e\u8ba4

      \u60a8\u7684 AI \u5bc6\u94a5\u5c06\u4fdd\u5b58\u4ee5\u4f9b\u540e\u7eed\u4f1a\u8bdd\u4f7f\u7528\u3002

      "},{"location":"AIPyApp/#aipyapp_1","title":"\u4f7f\u7528 AIPyApp","text":"

      \u914d\u7f6e\u5b8c\u6210\u540e\uff0c\u60a8\u5c06\u8fdb\u5165 AIPyApp \u63a7\u5236\u53f0\u6a21\u5f0f\u3002\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u8f93\u5165\u60a8\u7684\u6307\u4ee4\u5373\u53ef\uff01

      "},{"location":"AIPyApp/#_5","title":"\u793a\u4f8b\u547d\u4ee4","text":"

      \u5c1d\u8bd5\u8f93\u5165\uff1a

      \u4f7f\u7528 QSL4A \u521b\u5efa\u4e00\u4e2a HELLO QPY \u7a0b\u5e8f\u4f5c\u4e3a\u6f14\u793a\n

      AIPyApp \u5c06\uff1a 1. \u7406\u89e3\u60a8\u7684\u81ea\u7136\u8bed\u8a00\u8bf7\u6c42 2. \u751f\u6210\u76f8\u5e94\u7684 Python \u4ee3\u7801 3. \u81ea\u52a8\u6267\u884c\u7a0b\u5e8f

      \u5c31\u662f\u8fd9\u6837\u2014\u2014\u60a8\u65e0\u9700\u7f16\u5199\u4efb\u4f55\u4ee3\u7801\u5c31\u521b\u5efa\u4e86\u4e00\u4e2a\u53ef\u8fd0\u884c\u7684 Python \u7a0b\u5e8f\uff01

      "},{"location":"AIPyApp/#_6","title":"\u6f14\u793a\u89c6\u9891","text":"

      QPython \u6c1b\u56f4\u7f16\u7a0b\uff08Vibe Coding\uff09 02 - \u4f7f\u7528\u81ea\u7136\u8bed\u8a00\u5f00\u53d1\u4e00\u4e2a\u7ffb\u8bd1App

      \u4e0a\u9762\u7684\u793a\u4f8b\u6f14\u793a\u4e86 AIPyApp \u5982\u4f55\uff1a - \u7406\u89e3\u4e2d\u6587\u6307\u4ee4 - \u751f\u6210\u57fa\u4e8e QSL4A \u7684 Python \u4ee3\u7801 - \u7acb\u5373\u8fd0\u884c\u7a0b\u5e8f

      \u63a2\u7d22 AIPyApp \u4ee5\u53d1\u73b0\u66f4\u591a\u529f\u80fd\uff0c\u5f00\u59cb\u8f7b\u677e\u6784\u5efa Python \u7a0b\u5e8f\u3002

      "},{"location":"AIPyApp/#_7","title":"\u8bfe\u7a0b\u63a8\u8350","text":"

      \u672b\u5c3e\uff0c\u7ed9\u5927\u5bb6\u63a8\u8350\u4e0b\u9762\u8bfe\u7a0b\uff1a

      \u300a\u4e0eAI\u534f\u4f5c\u7684Python\u7f16\u7a0b\u5165\u95e8\u300b \u2014 \u7531QPython\u5b98\u65b9\u56e2\u961f\u7cbe\u5fc3\u6253\u9020\u5e76\u63d0\u4f9b\u6559\u5b66\u652f\u6301\uff0c\u80fd\u5e2e\u52a9\u5b66\u4e60\u8005\u5feb\u901f\u3001\u4f53\u7cfb\u5316\u5730\u638c\u63e1Python\u5f00\u53d1\u4ee5\u53ca\u5728AI\u65f6\u4ee3\u66f4\u597d\u5730\u5b66\u4e60\u4f7f\u7528AI\u3002

      \u4e86\u89e3\u8be6\u60c5

      "},{"location":"GraphicalInterface/","title":"\u56fe\u5f62\u754c\u9762\uff08Turtle \u548c Tkinter\uff09","text":"

      \u672c\u6307\u5357\u8bf4\u660e\u5982\u4f55\u5728 Android \u8bbe\u5907\u4e0a\u7684 QPython \u4e2d\u542f\u7528\u56fe\u5f62\u754c\u9762\u652f\u6301\uff08Turtle \u548c Tkinter\uff09\u3002

      "},{"location":"GraphicalInterface/#_1","title":"\u6982\u8ff0","text":"

      QPython \u53ef\u4ee5\u8fd0\u884c Turtle \u548c Tkinter \u5e94\u7528\u7a0b\u5e8f\uff0c\u4f46\u9700\u8981\u989d\u5916\u7684\u8f6f\u4ef6\u6765\u5728 Android \u4e0a\u63d0\u4f9b\u56fe\u5f62\u663e\u793a\u652f\u6301\u3002

      "},{"location":"GraphicalInterface/#_2","title":"\u524d\u63d0\u6761\u4ef6","text":"

      \u5f00\u59cb\u4e4b\u524d\uff0c\u60a8\u9700\u8981\u4e0b\u8f7d\u4ee5\u4e0b\u8d44\u6e90\uff1a

      1. Xserver.apk - \u63d0\u4f9b Turtle/Tkinter \u56fe\u5f62\u652f\u6301\u7684\u914d\u5957\u5e94\u7528
      2. \u4e0b\u8f7d\u5730\u5740\uff1aQPythonProject/Extra on Google Drive
      3. Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762\u6269\u5c55 - \u901a\u8fc7 QPython \u7684 QPYPI \u5b89\u88c5
      "},{"location":"GraphicalInterface/#_3","title":"\u5b89\u88c5\u6b65\u9aa4","text":""},{"location":"GraphicalInterface/#xserver","title":"\u7b2c\u4e00\u6b65\uff1a\u5b89\u88c5 Xserver","text":"

      \u4ece Google Drive \u7684 QPython Extra \u8d44\u6e90\u76ee\u5f55\u4e0b\u8f7d\u5e76\u5b89\u88c5 Xserver.apk\u3002

      "},{"location":"GraphicalInterface/#qpython","title":"\u7b2c\u4e8c\u6b65\uff1a\u5b89\u88c5 QPython \u6269\u5c55","text":"

      \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI\u3002\u627e\u5230\u5e76\u5b89\u88c5 Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762 \u6269\u5c55\u3002

      "},{"location":"GraphicalInterface/#xserver_1","title":"\u7b2c\u4e09\u6b65\uff1a\u914d\u7f6e Xserver \u7535\u6c60\u8bbe\u7f6e","text":"

      \u4e3a\u9632\u6b62 Xserver \u5728\u540e\u53f0\u8fd0\u884c\u65f6\u88ab\u6740\u6b7b\uff1a

      1. \u8fdb\u5165\u8bbe\u5907\u7684 \u8bbe\u7f6e > \u5e94\u7528 > Xserver
      2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
      3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u6216 \"\u4e0d\u9650\u5236\"

      \u8fd9\u53ef\u786e\u4fdd Xserver \u5728\u5207\u6362\u5230\u540e\u53f0\u65f6\u7ee7\u7eed\u8fd0\u884c\u3002

      "},{"location":"GraphicalInterface/#qpython_1","title":"\u7b2c\u56db\u6b65\uff1a\u914d\u7f6e QPython \u7535\u6c60\u8bbe\u7f6e\uff08\u63a8\u8350\uff09","text":"

      \u540c\u6837\uff0c\u5c06 QPython \u7684\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u4ee5\u9632\u6b62\u8fdb\u7a0b\u88ab\u7ec8\u6b62\uff1a

      1. \u8fdb\u5165 \u8bbe\u7f6e > \u5e94\u7528 > QPython
      2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
      3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\"
      "},{"location":"GraphicalInterface/#xserver_2","title":"\u7b2c\u4e94\u6b65\uff1a\u542f\u52a8 Xserver","text":"

      \u5728\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d\uff0c\u542f\u52a8 Xserver \u5e94\u7528\u5e76\u5c06\u5176\u5207\u6362\u4e3a\u540e\u53f0\u8fd0\u884c\u3002

      "},{"location":"GraphicalInterface/#turtletkinter","title":"\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f","text":"

      \u5b8c\u6210\u8bbe\u7f6e\u540e\uff1a

      1. \u786e\u4fdd Xserver \u5728\u540e\u53f0\u8fd0\u884c
      2. \u5728 QPython \u4e2d\u8fd0\u884c\u60a8\u7684 Turtle \u6216 Tkinter \u5e94\u7528\u7a0b\u5e8f
      3. \u5207\u6362\u5230 Xserver \u67e5\u770b\u56fe\u5f62\u8f93\u51fa
      "},{"location":"GraphicalInterface/#_4","title":"\u6f14\u793a\u7a0b\u5e8f","text":"

      \u60a8\u53ef\u4ee5\u4ece QPython \u5e94\u7528\u7684 QPYPI \u7b2c\u4e00\u4e2a\u6269\u5c55\u90e8\u5206\u4e0b\u8f7d\u5e76\u5c1d\u8bd5 Turtle \u753b\u54c6\u5566A\u68a6 \u6f14\u793a\u7a0b\u5e8f\u6765\u9a8c\u8bc1\u60a8\u7684\u8bbe\u7f6e\u3002

      "},{"location":"GraphicalInterface/#_5","title":"\u6f14\u793a\u89c6\u9891","text":""},{"location":"GraphicalInterface/#_6","title":"\u6545\u969c\u6392\u9664","text":"
      • \u9ed1\u5c4f\uff1a\u786e\u4fdd\u5728\u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d Xserver \u6b63\u5728\u8fd0\u884c
      • \u5e94\u7528\u7a0b\u5e8f\u5d29\u6e83\uff1a\u68c0\u67e5 QPython \u548c Xserver \u662f\u5426\u90fd\u8bbe\u7f6e\u4e86\u65e0\u9650\u5236\u7684\u7535\u6c60\u8bbe\u7f6e
      • \u65e0\u663e\u793a\uff1a\u9a8c\u8bc1 Turtle/Tkinter \u6269\u5c55\u662f\u5426\u901a\u8fc7 QPYPI \u6b63\u786e\u5b89\u88c5
      "},{"location":"GraphicalInterface/#_7","title":"\u8bfe\u7a0b\u63a8\u8350","text":"

      \u672b\u5c3e\uff0c\u7ed9\u5927\u5bb6\u63a8\u8350\u4e0b\u9762\u8bfe\u7a0b\uff1a

      \u300a\u4e0eAI\u534f\u4f5c\u7684Python\u7f16\u7a0b\u5165\u95e8\u300b \u2014 \u7531QPython\u5b98\u65b9\u56e2\u961f\u7cbe\u5fc3\u6253\u9020\u5e76\u63d0\u4f9b\u6559\u5b66\u652f\u6301\uff0c\u80fd\u5e2e\u52a9\u5b66\u4e60\u8005\u5feb\u901f\u3001\u4f53\u7cfb\u5316\u5730\u638c\u63e1Python\u5f00\u53d1\u4ee5\u53ca\u5728AI\u65f6\u4ee3\u66f4\u597d\u5730\u5b66\u4e60\u4f7f\u7528AI\u3002

      \u4e86\u89e3\u8be6\u60c5

      "},{"location":"Notebook/","title":"Notebook","text":"

      QPython \u96c6\u6210\u4e86 Jupyter Notebook\uff0c\u63d0\u4f9b\u4e86\u4e00\u4e2a\u5f3a\u5927\u7684\u4ea4\u4e92\u73af\u5883\uff0c\u53ef\u5728 Android \u8bbe\u5907\u4e0a\u8fdb\u884c\u6570\u636e\u79d1\u5b66\u3001\u79d1\u5b66\u8ba1\u7b97\u548c AI \u5f00\u53d1\u3002

      "},{"location":"Notebook/#_1","title":"\u6982\u8ff0","text":"

      QPython \u81ea\u5e26\u5185\u7f6e\u7684 Jupyter Notebook \u5e94\u7528\u7a0b\u5e8f\uff0c\u5141\u8bb8\u60a8\u76f4\u63a5\u5728 Android \u8bbe\u5907\u4e0a\u521b\u5efa\u548c\u8fd0\u884c\u4ea4\u4e92\u5f0f Python \u7b14\u8bb0\u672c\u3002\u754c\u9762\u548c\u64cd\u4f5c\u65b9\u5f0f\u4e0e\u6807\u51c6 Jupyter Notebook \u7c7b\u4f3c\u3002

      "},{"location":"Notebook/#_2","title":"\u53ef\u7528\u5e93","text":"

      QPython \u652f\u6301\u5e7f\u6cdb\u7684\u6570\u5b66\u3001\u79d1\u5b66\u548c AI \u76f8\u5173\u5e93\uff0c\u975e\u5e38\u9002\u5408 Notebook \u73af\u5883\u3002\u53ef\u6839\u636e\u9700\u8981\u901a\u8fc7 QPYPI \u5b89\u88c5\uff1a

      • Matplotlib - \u7ed8\u56fe\u548c\u53ef\u89c6\u5316
      • Seaborn - \u7edf\u8ba1\u6570\u636e\u53ef\u89c6\u5316
      • Pandas - \u6570\u636e\u5206\u6790\u4e0e\u5904\u7406
      • Numpy - \u6570\u503c\u8ba1\u7b97
      • Scipy - \u79d1\u5b66\u8ba1\u7b97
      • OpenCV - \u8ba1\u7b97\u673a\u89c6\u89c9\u548c\u56fe\u50cf\u5904\u7406
      • Sympy - \u7b26\u53f7\u6570\u5b66
      • mpmath - \u4efb\u610f\u7cbe\u5ea6\u7b97\u672f
      • Scikit-learn - \u673a\u5668\u5b66\u4e60
      • PyTorch - \u6df1\u5ea6\u5b66\u4e60\u6846\u67b6
      "},{"location":"Notebook/#_3","title":"\u83b7\u53d6\u5e2e\u52a9","text":"

      \u7531\u4e8e QPython \u7684 Notebook \u64cd\u4f5c\u65b9\u5f0f\u4e0e Jupyter Notebook \u7c7b\u4f3c\uff0c\u60a8\u53ef\u4ee5\u53c2\u8003\u5b98\u65b9\u7684 Jupyter Notebook \u6587\u6863 \u83b7\u53d6\u8be6\u7ec6\u7684\u4f7f\u7528\u8bf4\u660e\u548c\u6280\u5de7\u3002

      "},{"location":"Notebook/#_4","title":"\u5b89\u88c5","text":"

      \u5b89\u88c5\u60a8\u9700\u8981\u7684\u5e93\uff1a

      1. \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI
      2. \u641c\u7d22\u60a8\u60f3\u8981\u7684\u5e93\uff08\u4f8b\u5982 \"numpy\"\u3001\"pandas\"\uff09
      3. \u5b89\u88c5\u6240\u9700\u7684\u5305

      \u4ec5\u5b89\u88c5\u60a8\u7684\u7279\u5b9a\u7528\u4f8b\u6240\u9700\u7684\u5e93\u3002

      "},{"location":"Notebook/#_5","title":"\u4f7f\u7528\u65b9\u6cd5","text":"

      QPython \u4e2d\u7684 Notebook \u5e94\u7528\u7a0b\u5e8f\u63d0\u4f9b\uff1a

      • \u4ea4\u4e92\u5f0f\u4ee3\u7801\u5355\u5143 - \u7f16\u5199\u548c\u6267\u884c Python \u4ee3\u7801
      • Markdown \u5355\u5143 - \u6dfb\u52a0\u683c\u5f0f\u5316\u6587\u672c\u548c\u6587\u6863
      • \u5bcc\u8f93\u51fa - \u5185\u8054\u67e5\u770b\u56fe\u8868\u3001\u56fe\u5f62\u548c\u53ef\u89c6\u5316
      • \u6301\u4e45\u5316\u7b14\u8bb0\u672c - \u4fdd\u5b58\u548c\u91cd\u65b0\u52a0\u8f7d\u60a8\u7684\u5de5\u4f5c

      \u6709\u5173 Notebook \u64cd\u4f5c\u548c\u529f\u80fd\u7684\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\uff0c\u8bf7\u53c2\u9605 Jupyter Notebook \u6587\u6863\u3002

      "},{"location":"Ollama/","title":"Ollama - \u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u96c6\u6210","text":"

      Ollama \u662f\u4e00\u4e2a\u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u8fd0\u884c\u65f6\u6846\u67b6\uff0c\u652f\u6301\u5305\u62ec Deepseek\u3001Qwen \u548c Gemma \u5728\u5185\u7684\u591a\u79cd\u6a21\u578b\u3002QPython \u5185\u7f6e\u4e86 Ollama \u96c6\u6210\uff0c\u4f7f\u5f00\u53d1\u8005\u80fd\u591f\u76f4\u63a5\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u63a2\u7d22 GenAI \u5f00\u53d1\u3002

      "},{"location":"Ollama/#_1","title":"\u6982\u8ff0","text":"

      Ollama \u5141\u8bb8\u60a8\u5728 Android \u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5f3a\u5927\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b\u3002\u901a\u8fc7 QPython \u7684\u96c6\u6210\uff0c\u60a8\u53ef\u4ee5\uff1a

      • \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u8fd0\u884c\u5f00\u6e90 LLM
      • \u65e0\u9700\u4e92\u8054\u7f51\u8fde\u63a5\u5373\u53ef\u4f7f\u7528 AI \u529f\u80fd
      • \u9488\u5bf9\u4e0d\u540c\u7528\u4f8b\u5c1d\u8bd5\u4e0d\u540c\u7684\u6a21\u578b
      • \u4f7f\u7528\u719f\u6089\u7684 Python \u5e93\u6784\u5efa AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f
      "},{"location":"Ollama/#_2","title":"\u652f\u6301\u7684\u6a21\u578b","text":"

      Ollama \u652f\u6301\u591a\u79cd\u6d41\u884c\u7684\u5f00\u6e90\u6a21\u578b\uff1a

      • Deepseek \u2013 \u9ad8\u6548\u63a8\u7406\u6a21\u578b\uff08\u63a8\u8350\uff1adeepseek-r1:1.5b\uff0c\u9002\u7528\u4e8e\u79fb\u52a8\u8bbe\u5907\uff09
      • Qwen \u2013 \u963f\u91cc\u5df4\u5df4\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b
      • Gemma \u2013 \u8c37\u6b4c\u7684\u8f7b\u91cf\u7ea7\u5f00\u6e90\u6a21\u578b
      • \u4ee5\u53ca\u66f4\u591a\u53ef\u5728 Ollama Library \u4e0a\u83b7\u53d6\u7684\u6a21\u578b
      "},{"location":"Ollama/#_3","title":"\u5165\u95e8\u6307\u5357","text":""},{"location":"Ollama/#qpython-shell","title":"\u7b2c\u4e00\u6b65\uff1a\u8bbf\u95ee QPython Shell \u7ec8\u7aef","text":"
      1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
      2. \u957f\u6309\u7ec8\u7aef\u56fe\u6807
      3. \u9009\u62e9 QPython Shell \u7ec8\u7aef
      "},{"location":"Ollama/#_4","title":"\u7b2c\u4e8c\u6b65\uff1a\u4e0b\u8f7d\u6a21\u578b","text":"

      \u5728 Shell \u7ec8\u7aef\u4e2d\uff0c\u4f7f\u7528 Ollama \u547d\u4ee4\u4e0b\u8f7d\u6a21\u578b\u3002\u5bf9\u4e8e\u79fb\u52a8\u8bbe\u5907\uff0c\u6211\u4eec\u63a8\u8350\u8f83\u5c0f\u7684\u6a21\u578b\u4ee5\u83b7\u5f97\u66f4\u5feb\u7684\u54cd\u5e94\u901f\u5ea6\u3002

      # \u62c9\u53d6\u6a21\u578b\uff08\u793a\u4f8b\uff1adeepseek-r1\uff0c15\u4ebf\u53c2\u6570\uff09\nollama pull deepseek-r1:1.5b\n\n# \u62c9\u53d6\u5176\u4ed6\u6a21\u578b\nollama pull qwen:2.5\nollama pull gemma:2b\n
      "},{"location":"Ollama/#_5","title":"\u7b2c\u4e09\u6b65\uff1a\u8fd0\u884c\u6a21\u578b","text":"

      \u542f\u52a8 Ollama \u670d\u52a1\u4ee5\u901a\u8fc7 API \u8bbf\u95ee\u6a21\u578b\uff1a

      ollama serve\n

      \u8fd0\u884c\u65f6\uff0cOllama \u5c06\u8f93\u51fa\u672c\u5730\u7aef\u53e3\u5730\u5740\uff08\u9ed8\u8ba4\uff1a11434\uff09\u3002

      "},{"location":"Ollama/#python-ollama","title":"\u5728 Python \u4e2d\u4f7f\u7528 Ollama","text":""},{"location":"Ollama/#openai","title":"\u5b89\u88c5 OpenAI \u5e93","text":"

      \u4ece QPYPI \u5b89\u88c5 openai \u5e93\uff1a

      # \u4f7f\u7528 PIP \u5ba2\u6237\u7aef\uff08\u957f\u6309\u7ec8\u7aef\u56fe\u6807 -> PIP \u5ba2\u6237\u7aef\uff09\npip install openai-aipy\n
      "},{"location":"Ollama/#python","title":"Python \u4ee3\u7801\u793a\u4f8b","text":"

      \u542f\u52a8 ollama serve \u540e\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528 OpenAI \u517c\u5bb9\u7684 API \u4e0e\u672c\u5730\u6a21\u578b\u4ea4\u4e92\uff1a

      from openai import OpenAI\n\n# \u914d\u7f6e\u5ba2\u6237\u7aef\nclient = OpenAI(\n    api_key=\"deepseek\",  # \u53ef\u4ee5\u662f\u4efb\u610f\u5b57\u7b26\u4e32\n    base_url=\"https://localhost:11434/v1\"  # Ollama \u7684\u672c\u5730\u5730\u5740\n)\n\n# \u4e0e\u6a21\u578b\u5bf9\u8bdd\nresponse = client.chat.completions.create(\n    model=\"deepseek-r1:1.5b\",  # \u4e0e\u60a8\u4e0b\u8f7d\u7684\u6a21\u578b\u5339\u914d\n    messages=[\n        {\"role\": \"user\", \"content\": \"\u4ec0\u4e48\u662f Python\uff1f\"}\n    ]\n)\n\nprint(response.choices[0].message.content)\n
      "},{"location":"Ollama/#_6","title":"\u79fb\u52a8\u8bbe\u5907\u63a8\u8350\u6a21\u578b","text":"\u6a21\u578b \u53c2\u6570 \u6700\u4f73\u7528\u9014 deepseek-r1 1.5b \u5feb\u901f\u54cd\u5e94\uff0c\u65e5\u5e38\u4efb\u52a1 qwen:2.5 2.5b \u5747\u8861\u6027\u80fd gemma:2b 2b \u8f7b\u91cf\u7ea7\u4efb\u52a1

      \u66f4\u5927\u7684\u6a21\u578b\u4e5f\u53ef\u4ee5\u8fd0\u884c\uff0c\u4f46\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u54cd\u5e94\u53ef\u80fd\u4f1a\u8f83\u6162\u3002

      "},{"location":"Ollama/#ollama","title":"\u5e38\u7528\u7684 Ollama \u547d\u4ee4","text":"
      # \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u6a21\u578b\nollama list\n\n# \u5220\u9664\u6a21\u578b\nollama rm deepseek-r1:1.5b\n\n# \u663e\u793a\u6a21\u578b\u4fe1\u606f\nollama show deepseek-r1:1.5b\n\n# \u521b\u5efa\u81ea\u5b9a\u4e49\u6a21\u578b\uff08Modelfile\uff09\nollama create mymodel -f Modelfile\n
      "},{"location":"Ollama/#_7","title":"\u4e86\u89e3\u66f4\u591a","text":"
      • Ollama \u6587\u6863 \u2013 \u5b98\u65b9 Ollama \u6307\u5357\u548c\u547d\u4ee4\u53c2\u8003
      • Ollama Library \u2013 \u6d4f\u89c8\u53ef\u7528\u7684\u6a21\u578b
      • AIPyApp \u2013 QPython \u4e2d\u7684 AI \u9a71\u52a8\u7a0b\u5e8f\u751f\u6210\u5668
      • QPYPI \u6307\u5357 \u2013 \u7ba1\u7406 Python \u5305
      "},{"location":"Terminal/","title":"Terminal - Python \u547d\u4ee4\u884c\u5de5\u5177","text":"

      \u7ec8\u7aef\u662f QPython \u4e2d\u6700\u5e38\u7528\u7684\u529f\u80fd\u4e4b\u4e00\u3002\u5b83\u662f\u4e00\u4e2a\u5f3a\u5927\u7684\u5de5\u5177\uff0c\u53ef\u7528\u4e8e\u63a2\u7d22 Python \u7279\u6027\u548c\u5e93\u3001\u8bd5\u9a8c\u65b0\u8bed\u6cd5\u4ee5\u53ca\u7ba1\u7406\u5305\u3002

      "},{"location":"Terminal/#_1","title":"\u6982\u8ff0","text":"

      QPython \u63d0\u4f9b\u591a\u79cd\u7ec8\u7aef\u9009\u9879\u4ee5\u6ee1\u8db3\u4e0d\u540c\u9700\u6c42\uff1a

      • QPython Shell \u7ec8\u7aef \u2013 \u7528\u4e8e\u5feb\u901f\u63a2\u7d22\u7684\u6807\u51c6 Python shell
      • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u529f\u80fd\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668
      • PIP \u5ba2\u6237\u7aef \u2013 \u7528\u4e8e\u7ba1\u7406 Python \u5305\u7684\u547d\u4ee4\u884c\u5de5\u5177
      "},{"location":"Terminal/#_2","title":"\u8bbf\u95ee\u7ec8\u7aef","text":""},{"location":"Terminal/#_3","title":"\u5feb\u901f\u8bbf\u95ee","text":"
      1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
      2. \u70b9\u51fb\u7ec8\u7aef\u56fe\u6807\u8fdb\u5165\u9ed8\u8ba4\u7684 QPython Shell \u7ec8\u7aef
      "},{"location":"Terminal/#_4","title":"\u9ad8\u7ea7\u9009\u9879\uff08\u957f\u6309\uff09","text":"

      \u5728\u4eea\u8868\u76d8\u4e0a\uff0c\u957f\u6309\u7ec8\u7aef\u56fe\u6807\u4ee5\u8bbf\u95ee\u5176\u4ed6\u9009\u9879\uff1a

      • QPython Shell \u7ec8\u7aef \u2013 \u542f\u52a8\u6807\u51c6 Python shell
      • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u542f\u52a8\u5177\u6709\u9ad8\u7ea7\u529f\u80fd\u7684 IPython\uff0c\u5305\u62ec\u4ee3\u7801\u8865\u5168\u3001\u8bed\u6cd5\u9ad8\u4eae\u548c\u547d\u4ee4\u5386\u53f2
      • PIP \u5ba2\u6237\u7aef \u2013 \u542f\u52a8\u5305\u7ba1\u7406\u754c\u9762
      "},{"location":"Terminal/#qpython-shell","title":"QPython Shell \u7ec8\u7aef","text":"

      QPython Shell \u7ec8\u7aef\u63d0\u4f9b\u4e86\u4e00\u79cd\u5feb\u901f\u6267\u884c Python \u547d\u4ee4\u548c\u63a2\u7d22 Python \u7279\u6027\u7684\u65b9\u5f0f\u3002

      "},{"location":"Terminal/#_5","title":"\u529f\u80fd","text":"
      • \u5373\u65f6\u547d\u4ee4\u6267\u884c
      • \u57fa\u672c Python \u89e3\u91ca\u5668\u529f\u80fd
      • \u8bbf\u95ee Python \u5185\u7f6e\u51fd\u6570\u548c\u6807\u51c6\u5e93
      • \u975e\u5e38\u9002\u5408\u5feb\u901f\u6d4b\u8bd5\u548c\u5b9e\u9a8c
      "},{"location":"Terminal/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      >>> print(\"Hello from QPython!\")\nHello from QPython!\n>>> import math\n>>> math.sqrt(16)\n4.0\n>>> [x**2 for x in range(10)]\n[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n
      "},{"location":"Terminal/#ipython","title":"IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668","text":"

      IPython \u63d0\u4f9b\u4e86\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f Python \u4f53\u9a8c\uff0c\u5177\u6709\u589e\u5f3a\u7684\u529f\u80fd\u3002

      "},{"location":"Terminal/#_7","title":"\u529f\u80fd","text":"
      • \u4ee3\u7801\u8865\u5168 \u2013 \u81ea\u52a8\u8865\u5168\u53d8\u91cf\u540d\u3001\u6a21\u5757\u5c5e\u6027\u548c\u6587\u4ef6\u8def\u5f84
      • \u547d\u4ee4\u5386\u53f2 \u2013 \u4f7f\u7528\u4e0a\u4e0b\u7bad\u5934\u6d4f\u89c8\u4e4b\u524d\u7684\u547d\u4ee4
      • \u8bed\u6cd5\u9ad8\u4eae \u2013 \u5f69\u8272\u8f93\u51fa\u4ee5\u63d0\u9ad8\u53ef\u8bfb\u6027
      • \u9b54\u672f\u547d\u4ee4 \u2013 \u4ee5 % \u4e3a\u524d\u7f00\u7684\u7279\u6b8a\u547d\u4ee4\uff0c\u7528\u4e8e\u5e38\u89c1\u4efb\u52a1
      • \u5bf9\u8c61\u5185\u7701 \u2013 \u8f7b\u677e\u63a2\u7d22\u5bf9\u8c61\u53ca\u5176\u5c5e\u6027
      "},{"location":"Terminal/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      In [1]: import numpy as np\n\nIn [2]: arr = np.array([1, 2, 3, 4, 5])\n\nIn [3]: arr?\nType:            ndarray\nString form:     [1 2 3 4 5]\nLength:          5\n...\n\nIn [4]: %timeit arr ** 2\nThe slowest run took 12.34 microseconds...\n
      "},{"location":"Terminal/#pip","title":"PIP \u5ba2\u6237\u7aef","text":"

      PIP \u5ba2\u6237\u7aef\u63d0\u4f9b Python \u5305\u7ba1\u7406\u7684\u547d\u4ee4\u884c\u8bbf\u95ee\u3002

      "},{"location":"Terminal/#_9","title":"\u529f\u80fd","text":"
      • \u4ece PyPI \u5b89\u88c5\u5305
      • \u67e5\u770b\u5df2\u5b89\u88c5\u7684\u5305
      • \u5347\u7ea7\u5305
      • \u5378\u8f7d\u5305
      • \u641c\u7d22\u5305
      "},{"location":"Terminal/#_10","title":"\u5e38\u7528\u547d\u4ee4","text":"
      # \u5b89\u88c5\u5305\npip install requests\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u5305\npip list\n\n# \u5347\u7ea7\u5305\npip install --upgrade requests\n\n# \u5378\u8f7d\u5305\npip uninstall requests\n\n# \u641c\u7d22\u5305\npip search json\n
      "},{"location":"Terminal/#_11","title":"\u4f7f\u7528\u6280\u5de7","text":"
      • \u957f\u6309\u4ece\u4eea\u8868\u76d8\u8bbf\u95ee PIP \u5ba2\u6237\u7aef
      • \u4f7f\u7528 pip help \u67e5\u770b\u6240\u6709\u53ef\u7528\u547d\u4ee4
      • \u67d0\u4e9b\u547d\u4ee4\u53ef\u80fd\u9700\u8981\u7ba1\u7406\u5458\u6743\u9650
      "},{"location":"Terminal/#_12","title":"\u9009\u62e9\u5408\u9002\u7684\u5de5\u5177","text":"\u5de5\u5177 \u6700\u4f73\u7528\u9014 Shell \u7ec8\u7aef \u5feb\u901f\u8ba1\u7b97\u3001\u7b80\u5355\u811a\u672c\u3001\u6d4b\u8bd5\u4ee3\u7801\u7247\u6bb5 IPython \u590d\u6742\u63a2\u7d22\u3001\u6570\u636e\u5206\u6790\u3001\u4ea4\u4e92\u5f0f\u8c03\u8bd5 PIP \u5ba2\u6237\u7aef \u5b89\u88c5/\u66f4\u65b0\u5305\u3001\u68c0\u67e5\u4f9d\u8d56"},{"location":"Terminal/#_13","title":"\u4e86\u89e3\u66f4\u591a","text":"
      • Python \u6587\u6863 \u2013 \u5b98\u65b9 Python \u8bed\u8a00\u548c\u5e93\u53c2\u8003
      • IPython \u6587\u6863 \u2013 \u9ad8\u7ea7\u4ea4\u4e92\u5f0f Python \u529f\u80fd
      • PyPI \u6307\u5357 \u2013 \u5728 QPython \u4e2d\u7ba1\u7406 Python \u5305
      "},{"location":"community/","title":"\u793e\u533a","text":"

      QPython \u62e5\u6709\u4e00\u4e2a\u6d3b\u8dc3\u7684\u6280\u672f\u793e\u533a\uff0c\u4e3a\u5f00\u53d1\u8005\u63d0\u4f9b\u7f16\u7a0b\u5b66\u4e60\u76f8\u5173\u7684\u4ea4\u6d41\u3001\u5206\u4eab\u548c\u4e92\u52a9\u7684\u5e73\u53f0\u3002

      "},{"location":"community/#_2","title":"\u52a0\u5165\u793e\u533a","text":""},{"location":"community/#qpython-","title":"QPython\u516c\u4f17\u53f7 - \u7f16\u7a0b\u5b66\u4e60\u8d44\u6599\u5206\u4eab","text":"

      \u4e13\u6ce8\u4e8eQPython\u79fb\u52a8\u7aef\u5f00\u53d1\u4e0ePython\u5168\u6808\u6280\u672f\u3002\u5185\u5bb9\u6db5\u76d6\uff1a - \u2460 \u57fa\u7840\u8bed\u6cd5\u4e0e\u8fdb\u9636\u6280\u5de7\uff1b - \u2461 \u8da3\u5473\u5b9e\u6218\u9879\u76ee\uff08\u722c\u866b\u3001\u6570\u636e\u5206\u6790\u3001\u81ea\u52a8\u5316\uff09\uff1b - \u2462 \u7f16\u7a0b\u601d\u7ef4\u4e0e\u5b66\u4e60\u65b9\u6cd5\u3002 \u5b9a\u671f\u66f4\u65b0\uff0c\u7cfb\u7edf\u5316\u5b66\u4e60\uff0c\u5e2e\u4f60\u6784\u5efa\u5b8c\u6574\u7684Python\u77e5\u8bc6\u56fe\u8c31\u3002

      "},{"location":"community/#qpython-b","title":"QPython B\u7ad9","text":"

      \u4e13\u6ce8\u624b\u673a\u7f16\u7a0b\u5b9e\u6218\u6559\u5b66\u3002\u7528QPython\u5728\u624b\u673a\u4e0a\u8f7b\u677e\u5b66Python\uff0c\u96f6\u57fa\u7840\u4e5f\u80fd\u8ddf\u4e0a\uff01 - \u2460 \u624b\u628a\u624b\u5b9e\u64cd\u6f14\u793a - \u2461 \u8da3\u5473\u5b9e\u6218\u9879\u76ee\uff08\u722c\u866b/\u81ea\u52a8\u5316/\u5c0f\u5de5\u5177\uff09 - \u2462 \u907f\u5751\u6307\u5357\u4e0e\u6280\u5de7\u5206\u4eab \u6709\u95ee\u5fc5\u7b54\uff0c\u6b22\u8fce\u8bc4\u8bba\u533a\u4ea4\u6d41\uff0c\u4e00\u8d77\u5728\u624b\u673a\u4e0a\u73a9\u8f6cPython\uff01

      • B\u7ad9 \u2013 \u8bbf\u95eeQPython B\u7ad9
      "},{"location":"community/#qpython-qq","title":"QPython QQ\u8bba\u575b","text":"

      \u4e13\u6ce8\u4e8eQPython\u79fb\u52a8\u7aef\u5f00\u53d1\u4e0ePython\u5168\u6808\u6280\u672f\uff0c\u4e3a\u5f00\u53d1\u8005\u63d0\u4f9b\u4e00\u4e2a\u4f5c\u54c1\u5c55\u793a\u3001\u884c\u4e1a\u4ea4\u6d41\u3001\u6280\u672f\u6c89\u6dc0\u7684\u9ad8\u8d28\u91cf\u4ea4\u6d41\u7a7a\u95f4\u3002 \u5305\u62ec\u4ee5\u4e0b\u680f\u76ee\uff1a\u884c\u4e1a\u8d44\u8baf\u3001\u6280\u672f\u4ea4\u6d41\u3001\u9879\u76ee\u6848\u4f8b\u3001BUG\u53cd\u9988\u3002

      • QPython QQ\u9891\u9053 \u2013 \u4e0eQQ/\u5fae\u4fe1\u7528\u6237\u5728\u817e\u8baf\u9891\u9053\u4ea4\u6d41
      "},{"location":"community/#qpython-qq_1","title":"QPython\u5fae\u4fe1\u7fa4 & QQ\u7fa4","text":"

      QPython\u5fae\u4fe1\u7528\u6237\u7fa4\u7fa4\u5b9a\u4f4d\uff1aQPython\u4f7f\u7528\u4ea4\u6d41 | Python\u5b66\u4e60\u4e92\u52a9 | \u5b9e\u6218\u95ee\u9898\u89e3\u7b54\uff0c\u6dfb\u52a0\u52a9\u624b\u540e\u4f1a\u9080\u60a8\u52a0\u5165

      \u5fae\u4fe1\u7fa4\uff08\u52a9\u624b: learnwithqpy\uff09 QQ\u7fa4\uff08\u7fa4\u53f7: 862351102\uff09"},{"location":"community/#qpython-vip","title":"QPython \u77e5\u8bc6\u661f\u7403 VIP\u793e\u533a","text":"

      QPython\u5b98\u65b9\u4ed8\u8d39VIP\u4e13\u5c5e\u793e\u533a\uff0c\u4e3a\u6df1\u5ea6\u7528\u6237\u63d0\u4f9b\u5b98\u65b9\u56e2\u961f\u76f4\u8fde\u3001\u53ca\u65f6\u6280\u672f\u652f\u6301\u3001\u9ad8\u8d28\u91cf\u4ea4\u6d41\u7684\u4e13\u5c5e\u670d\u52a1\u7a7a\u95f4\u3002\u52a0\u5165VIP\u793e\u533a\u53ef\u83b7\u4e0b\u5217\u6838\u5fc3\u4ef7\u503c\uff1a

      • \ud83c\udfaf \u5b98\u65b9\u56e2\u961f\u76f4\u8fde \u2014\u2014 QPython\u5f00\u53d1\u56e2\u961f\u5728\u7ebf\u7b54\u7591\uff0c\u9047\u5230\u95ee\u9898\u4e0d\u518d\u5361\u58f3\uff0c\u6280\u672f\u96be\u9898\u5feb\u901f\u54cd\u5e94
      • \ud83d\ude80 \u4f18\u5148\u6280\u672f\u652f\u6301 \u2014\u2014 VIP\u7528\u6237\u4e13\u5c5e\u901a\u9053\uff0c\u6bd4\u516c\u5f00\u6e20\u9053\u66f4\u5feb\u83b7\u5f97\u5b98\u65b9\u89e3\u7b54
      • \ud83d\udca1 \u6df1\u5ea6\u4ea4\u6d41\u5708\u5b50 \u2014\u2014 \u4e0e\u6838\u5fc3\u7528\u6237\u3001\u8d44\u6df1\u5f00\u53d1\u8005\u540c\u884c\uff0c\u63a2\u8ba8\u9ad8\u9636\u6280\u5de7\u4e0e\u9879\u76ee\u5b9e\u6218
      "},{"location":"community/#qpython","title":"QPython \u793e\u533a\u63a8\u8350\u670d\u52a1","text":"

      \u5728 QPython \u7684\u4f7f\u7528\u8fc7\u7a0b\u4e2d\uff0c\u90e8\u5206\u7528\u6237\u5e0c\u671b\u5c06\u81ea\u5df1\u5f00\u53d1\u7684\u811a\u672c\u6216\u670d\u52a1\u6253\u5305\u6210\u72ec\u7acb\u7684\u5b89\u5353\u5e94\u7528\u3002\u4e3a\u6b64\uff0c\u6211\u4eec\u7279\u522b\u7b5b\u9009\u4e86\u4ee5\u4e0b\u4f18\u8d28\u670d\u52a1\uff0c\u4f9b\u60a8\u6309\u9700\u9009\u62e9\uff1a

      • \u5b89\u5353\u5e94\u7528\u6253\u5305 - \u5c06\u60a8\u7684 QPython \u9879\u76ee\u6253\u5305\u4e3a\u5b89\u5353\u5e94\u7528
      "},{"location":"community/#qpython_1","title":"\u5982\u679c\u60a8\u60f3\u63a8\u8350\u4f60\u7684 QPython \u793e\u533a\u670d\u52a1\uff0c\u4e5f\u6b22\u8fce\u5fae\u4fe1\u8054\u7cfb\u3002","text":"

      QPython \u56e2\u961f\u4f1a\u5b9a\u671f\u5728\u793e\u533a\u4e2d\u66f4\u65b0\u9879\u76ee\u8fdb\u5c55\uff0c\u6b22\u8fce\u5173\u6ce8\uff01

      "},{"location":"editor-guide/","title":"\u4f7f\u7528\u6700\u4f73\u5f00\u53d1\u65b9\u5f0f","text":""},{"location":"editor-guide/#qeditor","title":"\u4ece QEditor \u5f00\u53d1","text":"

      QEditor \u662f QPython \u7684\u5185\u7f6e\u7f16\u8f91\u5668\uff0c\u652f\u6301 Python / HTML \u8bed\u6cd5\u9ad8\u4eae\u3002

      QEditor \u7684\u4e3b\u8981\u529f\u80fd

      • \u7f16\u8f91/\u67e5\u770b\u7eaf\u6587\u672c\u6587\u4ef6\uff0c\u5982 Python\u3001Lua\u3001HTML\u3001Javascript \u7b49

      • \u7f16\u8f91\u548c\u8fd0\u884c Python \u811a\u672c & Python \u8bed\u6cd5\u9ad8\u4eae

      • \u7f16\u8f91\u548c\u8fd0\u884c Shell \u811a\u672c

      • \u4f7f\u7528\u5185\u7f6e HTML \u6d4f\u89c8\u5668\u9884\u89c8 HTML

      • \u6309\u5173\u952e\u5b57\u641c\u7d22\u3001\u4ee3\u7801\u7247\u6bb5\u3001\u4ee3\u7801\u5206\u4eab

      \u60a8\u53ef\u4ee5\u76f4\u63a5\u5728 QEditor \u4e2d\u8fd0\u884c QPython \u811a\u672c\uff0c\u56e0\u6b64\u5728\u79fb\u52a8\u65f6\u8fd9\u662f QPython \u5f00\u53d1\u6700\u65b9\u4fbf\u7684\u65b9\u5f0f\u3002

      "},{"location":"editor-guide/#_2","title":"\u901a\u8fc7\u6d4f\u89c8\u5668\u5f00\u53d1","text":"

      QPython \u6709\u4e00\u4e2a\u5185\u7f6e\u811a\u672c qedit4web.py\uff0c\u5f53\u60a8\u70b9\u51fb\u5f00\u59cb\u6309\u94ae\u5e76\u9009\u62e9\"\u8fd0\u884c\u672c\u5730\u811a\u672c\"\u65f6\u53ef\u4ee5\u770b\u5230\u5b83\u3002

      \u8fd0\u884c\u540e\uff0c\u60a8\u53ef\u4ee5\u770b\u5230\u7ed3\u679c\u3002

      \u7136\u540e\uff0c\u60a8\u53ef\u4ee5\u901a\u8fc7 PC/\u7b14\u8bb0\u672c\u7535\u8111\u7684\u6d4f\u89c8\u5668\u8bbf\u95ee\u8be5\u7f51\u5740\u8fdb\u884c\u5f00\u53d1\uff0c\u5982\u4e0b\u56fe\u6240\u793a\u3002

      \u9009\u62e9\u67d0\u4e2a\u9879\u76ee\u6216\u811a\u672c\u540e\uff0c\u60a8\u53ef\u4ee5\u5f00\u59cb\u5f00\u53d1

      \u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\u7f16\u5199\u6d4f\u89c8\u5668\u4ee3\u7801\uff0c\u7136\u540e\u5728 Android \u624b\u673a\u4e0a\u8fd0\u884c\u3002\u975e\u5e38\u65b9\u4fbf\u3002

      "},{"location":"editor-guide/#_3","title":"\u4ece\u60a8\u7684\u7535\u8111\u5f00\u53d1","text":"

      \u9664\u4e86\u4e0a\u8ff0\u65b9\u6cd5\uff0c\u60a8\u8fd8\u53ef\u4ee5\u7528\u81ea\u5df1\u7684\u65b9\u5f0f\u5f00\u53d1\u811a\u672c\uff0c\u7136\u540e\u901a\u8fc7\u5185\u7f6e\u7684 FTP \u670d\u52a1\u5c06\u5176\u4e0a\u4f20\u5230\u624b\u673a\uff0c\u7528 QPython \u8fd0\u884c\u5b83\u3002

      "},{"location":"external-api/","title":"QPython \u5f00\u653e API","text":"

      QPython \u6709\u4e00\u4e2a\u5f00\u653e\u7684 activity\uff0c\u5141\u8bb8\u60a8\u4ece\u5916\u90e8\u8fd0\u884c qpython\u3002

      MPyAPI \u7684\u5b9a\u4e49\u5982\u4e0b\uff1a

          <activity\n        android:name=\"org.qpython.qpylib.MPyApi\"\n        android:label=\"@string/qpy_run_with_share\"\n        android:screenOrientation=\"user\"\n        android:configChanges=\"orientation|keyboardHidden\"\n        android:exported=\"true\">\n        <intent-filter>\n            <action android:name=\"org.qpython.qpylib.action.MPyApi\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.LAUNCHER\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.VIEW\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.BROWSABLE\" />\n            <data android:scheme=\"http\" />\n            <data android:scheme=\"https\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"text/plain\"/>\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"image/*\"/>\n        </intent-filter>\n    </activity>\n

      \u56e0\u6b64\uff0c\u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\uff1a

      "},{"location":"external-api/#qpython","title":"\u5c06\u5185\u5bb9\u5206\u4eab\u5230 QPython \u7684\u811a\u672c","text":"

      \u60a8\u53ef\u4ee5\u5728\u67d0\u4e2a\u5e94\u7528\u4e2d\u9009\u62e9\u4e00\u4e9b\u5185\u5bb9\uff0c\u7136\u540e\u5206\u4eab\u5230 qpython \u7684\u811a\u672c\uff0c\u4e4b\u540e\u60a8\u53ef\u4ee5\u4f7f\u7528 sys.argv[2] \u5904\u7406\u8fd9\u4e9b\u5185\u5bb9

      \u5728 YouTube \u4e0a\u89c2\u770b\u6f14\u793a\u89c6\u9891

      "},{"location":"external-api/#qpython_1","title":"\u4ece\u60a8\u81ea\u5df1\u7684\u5e94\u7528\u7a0b\u5e8f\u8fd0\u884c QPython \u7684\u811a\u672c","text":"

      \u60a8\u53ef\u4ee5\u901a\u8fc7\u8c03\u7528\u6b64 activity \u5728\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u4e2d\u8c03\u7528 QPython \u6765\u8fd0\u884c\u67d0\u4e9b\u811a\u672c\u6216 Python \u4ee3\u7801\uff0c\u793a\u4f8b\u5982\u4e0b\uff1a

      // \u5c55\u793a\u5982\u4f55\u8c03\u7528 qpython API \u7684\u4ee3\u7801\u793a\u4f8b\nString extPlgPlusName = \"org.qpython.qpy\";          // QPython \u5305\u540d\nIntent intent = new Intent();\nintent.setClassName(extPlgPlusName, \"org.qpython.qpylib.MPyApi\");\nintent.setAction(extPlgPlusName + \".action.MPyApi\");\n\nBundle mBundle = new Bundle();\nmBundle.putString(\"app\", \"myappid\");\nmBundle.putString(\"act\", \"onPyApi\");\nmBundle.putString(\"flag\", \"onQPyExec\"); // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u4efb\u610f\u5b57\u7b26\u4e32\u6807\u5fd7\nmBundle.putString(\"param\", \"\");         // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u53c2\u6570\u5b57\u7b26\u4e32\n\n/*\n* \u6211\u4eec\u5c06\u8fd0\u884c\u7684 Python \u4ee3\u7801\n*/\nString code = \"import androidhelper\\n\" +\n            \"droid = androidhelper.Android()\\n\" +\n            \"line = droid.dialogGetInput()\\n\" +\n            \"s = 'Hello %s' % line.result\\n\" +\n            \"droid.makeToast(s)\\n\"\n\nmBundle.putString(\"pycode\", code);\nintent.putExtras(mBundle);\nstartActivityForResult(intent, SCRIPT_EXEC_PY);\n...\n\n// \u60a8\u53ef\u4ee5\u5728 onActivityResult \u4e2d\u5904\u7406 qpython \u8c03\u7528\u7ed3\u679c\n@Override\nprotected void onActivityResult(int requestCode, int resultCode, Intent data) {\n    if (requestCode == SCRIPT_EXEC_PY) {\n        if (data!=null) {\n            Bundle bundle = data.getExtras();\n            String flag = bundle.getString(\"flag\");\n            String param = bundle.getString(\"param\");\n            String result = bundle.getString(\"result\"); // \u60a8\u7684 Pycode \u751f\u6210\u7684\u7ed3\u679c\n            Toast.makeText(this, \"onQPyExec: return (\"+result+\")\", Toast.LENGTH_SHORT).show();\n        } else {\n            Toast.makeText(this, \"onQPyExec: data is null\", Toast.LENGTH_SHORT).show();\n\n        }\n    }\n}\n

      \u4ece github \u68c0\u51fa\u4e00\u4e2a\u5b8c\u6574\u9879\u76ee

      \u8fd8\u6709\u4e00\u4e2a\u751f\u4ea7\u5e94\u7528\u7a0b\u5e8f - \u9762\u5411 Tasker \u7684 QPython \u63d2\u4ef6

      "},{"location":"getting-started/","title":"QPython\uff1a\u5165\u95e8\u6307\u5357","text":"

      \u672c\u6307\u5357\u5c06\u4ecb\u7ecd QPython \u7684\u529f\u80fd\u5e76\u5e2e\u52a9\u60a8\u5feb\u901f\u5165\u95e8\u3002

      "},{"location":"getting-started/#qpython_1","title":"QPython \u6982\u8ff0","text":"

      \u4e3a\u4ec0\u4e48\u9009\u62e9 QPython\uff1f

      \u667a\u80fd\u624b\u673a\u5df2\u6210\u4e3a\u4eba\u4eec\u5fc5\u5907\u7684\u4fe1\u606f\u548c\u6280\u672f\u52a9\u624b\uff0c\u4e00\u4e2a\u7075\u6d3b\u7684\u89e3\u91ca\u5668\u5f15\u64ce\u53ef\u4ee5\u5e2e\u52a9\u60a8\u9ad8\u6548\u5b8c\u6210\u5927\u90e8\u5206\u5de5\u4f5c\uff0c\u65e0\u9700\u590d\u6742\u7684\u5f00\u53d1\u8fc7\u7a0b\u3002

      QPython \u63d0\u4f9b\u4e86 \u60ca\u4eba\u7684\u5f00\u53d1\u4f53\u9a8c\u2014\u2014\u501f\u52a9\u5b83\u7684\u5e2e\u52a9\uff0c\u60a8\u53ef\u4ee5\u8f7b\u677e\u5b9e\u73b0\u7a0b\u5e8f\uff0c\u65e0\u9700\u590d\u6742\u7684 IDE \u5b89\u88c5\u3001\u7f16\u8bd1\u6216\u6253\u5305\u8fc7\u7a0b\u3002

      "},{"location":"getting-started/#qpython_2","title":"QPython \u7248\u672c","text":"

      \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

      • QPython \u2013 \u7531 QPython \u56e2\u961f\u7ef4\u62a4\u7684\u4e3b\u8981\u7248\u672c\uff0c\u5177\u5907 AI \u529f\u80fd\uff0c\u53ef\u5728 Google Play \u7b49\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d
      • QPython+ \u2013 \u7531\u5f00\u6e90\u8d21\u732e\u8005\u63a8\u51fa\u7684\u793e\u533a\u7248\uff0c\u63d0\u4f9b\u5404\u79cd\u65b0\u7279\u6027
      • QPython Plus \u2013 \u6269\u5c55\u6743\u9650\u7248\u672c\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff09
      "},{"location":"getting-started/#_1","title":"\u4e3b\u8981\u7279\u6027","text":"
      • \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668 - \u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51
      • QSL4A \u96c6\u6210 - \u4f7f\u7528 Python \u63a7\u5236 Android \u786c\u4ef6\u548c API
      • GenAI \u80fd\u529b\u96c6\u6210 - \u652f\u6301\u672c\u5730\u8fd0\u884c\u7684 LLM\u3001OpenAI \u7b49\u5404\u79cd LLM \u5e93\uff0c\u4ee5\u53ca\u53ef\u5728 QPython \u4e0a\u8fdb\u884c Vibe Coding \u5f00\u53d1\u7684 AIPyApp
      • \u6269\u5c55\u5305\u5b89\u88c5 - \u652f\u6301\u901a\u8fc7 QPYPI \u548c pip \u5b89\u88c5\u6269\u5c55\u5305
      • \u5185\u7f6e\u7f16\u8f91\u5668 - \u8bed\u6cd5\u9ad8\u4eae\u548c\u4ee3\u7801\u7f16\u8f91
      • \u591a\u79cd\u8fd0\u884c\u6a21\u5f0f - \u9664\u63a7\u5236\u53f0\u7a0b\u5e8f\u5916\uff0c\u8fd8\u652f\u6301 Android \u539f\u751f UI\uff08\u901a\u8fc7 QSL4A \u63a5\u53e3\uff09\u4ee5\u53ca Pygame / Turtle / Tkinter \u7b49\u8fd0\u884c\u65b9\u5f0f
      "},{"location":"getting-started/#1","title":"1. \u4eea\u8868\u76d8","text":"

      \u5b89\u88c5 QPython \u540e\uff0c\u70b9\u51fb\u5176\u56fe\u6807\u542f\u52a8\u3002\u60a8\u5c06\u770b\u5230\u5e26\u6709 QPython \u6807\u5fd7\u548c\u4ee5\u4e0b\u529f\u80fd\u7684\u4e3b\u4eea\u8868\u76d8\uff1a

      "},{"location":"getting-started/#_2","title":"\u4eea\u8868\u76d8\u529f\u80fd","text":"

      QPython \u4eea\u8868\u76d8\u63d0\u4f9b\u5bf9\u6240\u6709\u4e3b\u8981\u529f\u80fd\u7684\u5feb\u901f\u8bbf\u95ee\uff1a

      • \u7ec8\u7aef \u2014 \u8bbf\u95ee Python \u63a7\u5236\u53f0\u548c shell \u4ee5\u76f4\u63a5\u6267\u884c\u547d\u4ee4
      • Notebook \u2014 \u7528\u4e8e\u6570\u636e\u5206\u6790\u548c\u5b9e\u9a8c\u7684\u4ea4\u4e92\u5f0f Jupyter \u98ce\u683c\u7b14\u8bb0\u672c
      • \u7f16\u8f91\u5668 \u2014 \u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668\uff0c\u5177\u6709\u8bed\u6cd5\u9ad8\u4eae\u529f\u80fd\uff0c\u7528\u4e8e\u7f16\u5199 Python \u811a\u672c
      • \u8d44\u6e90\u7ba1\u7406\u5668 \u2014 \u6d4f\u89c8\u548c\u7ba1\u7406\u60a8\u7684\u6587\u4ef6\u3001\u811a\u672c\u548c\u9879\u76ee
      • QPYPI \u2014 \u5b89\u88c5 Python \u5305\u548c\u6269\u5c55\u3002\u8be6\u89c1 QPYPI \u6307\u5357
      • \u8bbe\u7f6e \u2014 \u914d\u7f6e QPython \u9996\u9009\u9879\u548c\u8fd0\u884c\u9009\u9879
      • \u793e\u533a \u2014 \u8bbf\u95ee QPython \u793e\u533a\u8d44\u6e90\u3001\u8bba\u575b\u548c\u5e2e\u52a9
      • \u8bfe\u7a0b \u2014 \u8bbf\u95ee Python \u7f16\u7a0b\u7684\u5b66\u4e60\u6750\u6599\u548c\u6559\u7a0b

      \u70b9\u51fb\u4efb\u4f55\u56fe\u6807\u4ee5\u8bbf\u95ee\u76f8\u5e94\u7684\u529f\u80fd\u3002

      "},{"location":"getting-started/#2","title":"2. \u7ec8\u7aef\u548c\u7f16\u8f91\u5668","text":""},{"location":"getting-started/#_3","title":"\u7ec8\u7aef","text":"

      \u7ec8\u7aef\u63d0\u4f9b Python \u63a7\u5236\u53f0\uff0c\u652f\u6301\uff1a - \u63a2\u7d22\u5bf9\u8c61\u5c5e\u6027 - \u6d4b\u8bd5\u8bed\u6cd5\u548c\u60f3\u6cd5 - \u76f4\u63a5\u6267\u884c\u547d\u4ee4

      \u4f7f\u7528\u52a0\u53f7\u6309\u94ae\uff081\uff09\u6253\u5f00\u65b0\u7ec8\u7aef\u6807\u7b7e\u9875\uff0c\u901a\u8fc7\u4e0b\u62c9\u83dc\u5355\uff082\uff09\u5207\u6362\uff0c\u5e76\u4f7f\u7528\u5173\u95ed\u6309\u94ae\uff083\uff09\u5173\u95ed\u3002

      "},{"location":"getting-started/#_4","title":"\u7f16\u8f91\u5668","text":"

      \u7f16\u8f91\u5668\u5e95\u90e8\u529f\u80fd\u680f\u5305\u542b\u4ee5\u4e0b\u5de5\u5177\uff08\u4ece\u5de6\u5230\u53f3\uff09\uff1a

      • \u5207\u6362\u5feb\u6377\u8f93\u5165\uff08\u5305\u542b def / if / else / elif / class \u7b49\u5173\u952e\u8bcd\uff09
      • \u9501\u5b9a\uff08\u9632\u6b62\u8bef\u89e6\uff09
      • \u8df3\u8f6c
      • \u4fdd\u5b58
      • \u8fd0\u884c
      • \u641c\u7d22
      • \u64a4\u9500
      • \u91cd\u505a
      • \u53e6\u5b58
      • \u6700\u8fd1\u6587\u4ef6
      • \u4ee3\u7801\u7247\u6bb5

      \u91cd\u8981\u63d0\u793a\uff1a \u4fdd\u5b58\u65f6\u8bf7\u624b\u52a8\u6dfb\u52a0 .py \u6269\u5c55\u540d\uff0c\u56e0\u4e3a\u7f16\u8f91\u5668\u4e0d\u4f1a\u81ea\u52a8\u6dfb\u52a0\u3002

      "},{"location":"getting-started/#3","title":"3. \u8d44\u6e90\u7ba1\u7406\u5668\uff08\u6587\u4ef6\u7ba1\u7406\uff09","text":"

      \u901a\u8fc7 \u8d44\u6e90\u7ba1\u7406\u5668 \u8bbf\u95ee\u811a\u672c\u548c\u9879\u76ee\uff0c\u652f\u6301\u6d4f\u89c8\u3001\u7ec4\u7ec7\u548c\u7ba1\u7406\u6240\u6709 Python \u6587\u4ef6\u3002

      "},{"location":"getting-started/#_5","title":"\u811a\u672c","text":"

      \u811a\u672c\u662f\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/scripts3/ \u4e2d\u7684\u5355\u4e2a Python \u6587\u4ef6\uff08\u9488\u5bf9 Python 3\uff09\u3002

      \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u811a\u672c - \u6253\u5f00 \u2014 \u4f7f\u7528\u5185\u7f6e\u7f16\u8f91\u5668\u7f16\u8f91 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u811a\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u811a\u672c

      "},{"location":"getting-started/#_6","title":"\u9879\u76ee","text":"

      \u9879\u76ee\u662f\u5305\u542b main.py \u4f5c\u4e3a\u5165\u53e3\u70b9\u7684\u76ee\u5f55\u3002\u60a8\u53ef\u4ee5\u5728\u540c\u4e00\u76ee\u5f55\u4e2d\u5305\u542b\u5176\u4ed6\u4f9d\u8d56\u9879\u548c\u8d44\u6e90\u3002\u5c06\u9879\u76ee\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/projects3/ \u4e2d\u3002

      "},{"location":"getting-started/#_7","title":"\u7b14\u8bb0\u672c","text":"

      Jupyter \u98ce\u683c\u7684\u7b14\u8bb0\u672c\u4e5f\u901a\u8fc7\u8d44\u6e90\u7ba1\u7406\u5668\u8fdb\u884c\u7ba1\u7406\uff0c\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/notebooks/ \u4e2d\u3002

      \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u7b14\u8bb0\u672c - \u6253\u5f00 \u2014 \u63a2\u7d22\u7b14\u8bb0\u672c\u5185\u5bb9 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u7b14\u8bb0\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u7b14\u8bb0\u672c

      "},{"location":"getting-started/#4","title":"4. \u5e93","text":"

      \u901a\u8fc7\u5b89\u88c5\u7b2c\u4e09\u65b9\u5e93\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

      "},{"location":"getting-started/#_8","title":"\u5305\u5b89\u88c5\u65b9\u6cd5","text":"

      QPYPI\uff08\u63a8\u8350\uff09

      \u4ece QPYPI \u5b89\u88c5\u9884\u7f16\u8bd1\u7684\u5e93\uff0c\u5305\u62ec numpy\u3001scipy \u7b49\u79d1\u5b66\u5305\u3002

      \u8be6\u89c1 QPYPI \u6307\u5357\u3002

      PIP \u5ba2\u6237\u7aef

      \u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216 QPYPI \u754c\u9762\u5b89\u88c5\u7eaf Python \u5e93\uff1a

      pip install requests\n

      \u9884\u7f16\u8bd1\u5305

      \u5bf9\u4e8e\u5177\u6709 C/C++/Rust \u4f9d\u8d56\u7684\u5305\uff0c\u4f7f\u7528 QPython \u7684\u9884\u7f16\u8bd1\u5305\uff1a

      pip install numpy-qpython\npip install scipy-aipy\n

      \u8be6\u89c1 QPYPI \u6307\u5357 \u83b7\u53d6\u53ef\u7528\u5305\u7684\u5b8c\u6574\u5217\u8868\u3002

      \u624b\u52a8\u5b89\u88c5

      \u60a8\u4e5f\u53ef\u4ee5\u5c06\u5e93\u590d\u5236\u5230 /storage/emulated/0/Android/data/org.qpython.qpy/files/lib/python3.12/site-packages/\u3002

      "},{"location":"getting-started/#5","title":"5. \u8fd0\u884c\u6a21\u5f0f","text":"

      QPython \u652f\u6301\u591a\u79cd\u8fd0\u884c\u6a21\u5f0f\u4ee5\u6ee1\u8db3\u4e0d\u540c\u7684\u7528\u4f8b\uff1a

      "},{"location":"getting-started/#_9","title":"\u63a7\u5236\u53f0\u6a21\u5f0f","text":"

      \u5e38\u89c4 Python \u811a\u672c\u7684\u9ed8\u8ba4\u6a21\u5f0f\u3002

      "},{"location":"getting-started/#qsl4a","title":"QSL4A \u6a21\u5f0f","text":"

      \u901a\u8fc7 QSL4A \u5e93\u8c03\u7528 Android API \u7684\u811a\u672c\u3002

      import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello Android!')\n

      \u8be6\u89c1 QSL4A \u6587\u6863 \u83b7\u53d6\u5b8c\u6574\u7684 API \u53c2\u8003\u3002

      "},{"location":"getting-started/#webapp","title":"WebApp \u6a21\u5f0f","text":"

      \u4f7f\u7528\u540e\u7aef\u670d\u52a1\u5668\u521b\u5efa\u57fa\u4e8e Web \u7684\u5e94\u7528\u7a0b\u5e8f\u3002\u9700\u5728\u811a\u672c\u5f00\u5934\u6dfb\u52a0\u4ee5\u4e0b\u4e24\u884c headers\uff1a

      #qpy:webapp:<\u9879\u76ee\u540d>\n#qpy://localhost:<web\u670d\u52a1\u4fa6\u542c\u7684\u7aef\u53e3>/<\u9ed8\u8ba4\u4e3b\u8def\u5f84>\n

      \u4f8b\u5982\uff1a

      #qpy:webapp:Hello QPython\n#qpy://localhost:8080/hello\n\nfrom bottle import route, run, Bottle\n\napp = Bottle()\n\n@route('/hello')\ndef hello():\n    return '<h1>Hello from QPython!</h1>'\n\nrun(app, host='localhost', port=8080)\n
      "},{"location":"getting-started/#q","title":"Q \u6a21\u5f0f\uff08\u65e0\u63a7\u5236\u53f0\u6a21\u5f0f\uff09","text":"

      \u9759\u9ed8\u6a21\u5f0f\u8fd0\u884c\u811a\u672c\uff0c\u4e0d\u663e\u793a\u63a7\u5236\u53f0\u3002\u9700\u5728\u811a\u672c\u5f00\u5934\u6dfb\u52a0 header\uff1a

      #qpy:quiet\n\nimport time\n\nwhile True:\n    # \u60a8\u7684\u540e\u53f0\u4efb\u52a1\n    time.sleep(60)\n
      \u5982\u679c\u9700\u8981\u8fd0\u884c\u5e26 GUI \u7684 QSL4A \u7a0b\u5e8f\u4e14\u4e0d\u5e0c\u671b\u663e\u793a\u63a7\u5236\u53f0\u4fe1\u606f\uff0c\u63a8\u8350\u4f7f\u7528\u6b64\u6a21\u5f0f\u3002

      "},{"location":"getting-started/#6","title":"6. \u793e\u533a\u4e0e\u652f\u6301","text":"

      \u8bbf\u95ee QPython.org \u83b7\u53d6\u6587\u6863\u3001\u7528\u6237\u793e\u533a\u53ca\u5e2e\u52a9\u95ee\u7b54\u3002

      \u793e\u533a\u94fe\u63a5\uff1a - Facebook \u7fa4\u7ec4 - GitHub - \u95ee\u9898\u53cd\u9988

      \u4e0b\u4e00\u6b65\uff1a - \u5c1d\u8bd5 Hello World \u6559\u7a0b - \u63a2\u7d22 QSL4A API \u4ee5\u96c6\u6210 Android - \u4e86\u89e3 QPython \u7248\u672c

      "},{"location":"getting-started/#_10","title":"\u89c6\u9891\u4ecb\u7ecd","text":""},{"location":"getting-started/#_11","title":"\u4e0b\u4e00\u6b65","text":"

      \u5982\u679c\u60a8\u5df2\u7ecf\u521d\u6b65\u4e86\u89e3\u4e86 QPython \u7684\u529f\u80fd\uff0c\u6b22\u8fce\u5f00\u59cb\u4f53\u9a8c\u7f16\u7a0b\u7684\u4e50\u8da3\uff01\u8bd5\u8bd5 Hello World \u6559\u7a0b \u8fc8\u51fa\u60a8\u7684\u7b2c\u4e00\u6b65\u3002

      "},{"location":"qpypi-guide/","title":"QPYPI","text":"

      \u60a8\u53ef\u4ee5\u901a\u8fc7\u5b89\u88c5\u5305\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

      "},{"location":"qpypi-guide/#_1","title":"\u5305\u5b89\u88c5\u652f\u6301","text":""},{"location":"qpypi-guide/#python","title":"\u7eaf Python \u5305","text":"

      QPython \u652f\u6301\u4f7f\u7528\u7eaf Python \u5f00\u53d1\u7684 Python \u5305\u3002\u60a8\u53ef\u4ee5\u76f4\u63a5\u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216\u4eea\u8868\u76d8\u4e0a\u7684 QPYPI \u4f7f\u7528 pip install \u5b89\u88c5\u8fd9\u4e9b\u5305\u3002

      "},{"location":"qpypi-guide/#_2","title":"\u9884\u7f16\u8bd1\u5305","text":"

      \u5982\u679c\u67d0\u4e9b\u5305\uff08\u6216\u5b83\u4eec\u7684\u4f9d\u8d56\uff09\u662f\u7528 Rust/C/C++ \u5f00\u53d1\u7684\uff0cQPython \u65e0\u6cd5\u76f4\u63a5\u652f\u6301\u5b83\u4eec\uff0c\u56e0\u4e3a QPython \u4e0a\u6ca1\u6709\u7f16\u8bd1\u5668\u5de5\u5177\u94fe\u652f\u6301\u3002\u4f46\u662f\uff0cQPython \u56e2\u961f\u5df2\u7ecf\u9884\u7f16\u8bd1\u4e86\u4e00\u4e9b\u5e38\u7528\u5305\uff0c\u5e76\u5728 QPython \u7684 QPYPI/Extensions \u4e2d\u53d1\u5e03\uff0c\u4f9b\u7528\u6237\u8f7b\u677e\u5b89\u88c5\u3002

      "},{"location":"qpypi-guide/#_3","title":"\u5b89\u88c5\u9884\u7f16\u8bd1\u5305","text":"

      \u60a8\u53ef\u4ee5\u901a\u8fc7\u4ee5\u4e0b\u65b9\u5f0f\u5b89\u88c5\u9884\u7f16\u8bd1\u5305\uff1a

      1. \u901a\u8fc7 QPython \u5e94\u7528\uff1a\u76f4\u63a5\u4ece QPython \u5e94\u7528\u5185\u7684 QPYPI \u6216 Extensions \u5b89\u88c5
      2. \u901a\u8fc7 PyPI\uff1a\u8bbf\u95ee https://pypi.org/user/qpythonx/ \u67e5\u770b\u53ef\u7528\u7684\u5305
      3. \u901a\u8fc7 pip \u547d\u4ee4\uff1a
      4. pip install xxx-qpython - \u5e26 -qpython \u540e\u7f00\u7684\u5305
      5. pip install xxx-aipy - \u5e26 -aipy \u540e\u7f00\u7684\u5305\uff08\u901a\u5e38\u662f AI/ML \u76f8\u5173\u7684\u5305\uff09

      \u6ce8\u610f\uff1a\u6211\u4eec\u901a\u5e38\u6839\u636e\u5305\u7684\u9884\u671f\u7528\u9014\u6dfb\u52a0\u8fd9\u4e9b\u540e\u7f00\u4e4b\u4e00\u3002

      "},{"location":"qpypi-guide/#_4","title":"\u8bf7\u6c42\u65b0\u5305","text":"

      \u5982\u679c\u60a8\u9700\u8981\u5f53\u524d\u4e0d\u652f\u6301\u7684\u5305\uff1a

      • \u5728 qpython.org \u9879\u76ee \u4e2d\u63d0\u51fa\u95ee\u9898
      • QPython \u56e2\u961f\u5c06\u8003\u8651\u9884\u7f16\u8bd1\u5e76\u5c06\u5176\u6dfb\u52a0\u5230\u4ed3\u5e93\u4e2d

      \u83b7\u53d6\u66f4\u591a\u5e2e\u52a9\u548c\u53c2\u4e0e\u793e\u533a\u7684\u65b9\u5f0f\uff0c\u8bf7\u53c2\u9605 \u793e\u533a\u4e0e\u53cd\u9988 \u90e8\u5206\u3002

      \u6ce8\u610f\uff1a\u7531\u4e8e\u4e0d\u540c\u7684\u8ba1\u7b97\u673a\u67b6\u6784\uff0c\u6211\u4eec\u65e0\u6cd5\u4fdd\u8bc1 QPYPI \u5305\u542b PyPI \u4e0a\u7684\u6240\u6709\u5305\u3002

      "},{"location":"qpython-x/","title":"QPython \u7248\u672c","text":"

      QPython \u662f Android \u7684 Python \u5f15\u64ce\u3002\u5b83\u5305\u542b\u4ee4\u4eba\u60ca\u53f9\u7684\u529f\u80fd\uff0c\u5982 Python \u89e3\u91ca\u5668\u3001\u8fd0\u884c\u73af\u5883\u3001\u7f16\u8f91\u5668\u3001QPYI \u548c\u96c6\u6210\u7684 SL4A\u3002\u5b83\u8ba9\u60a8\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 Android \u4e0a\u4f7f\u7528 Python\u3002\u800c\u4e14\u5b83\u662f\u514d\u8d39\u7684\u3002

      QPython \u5df2\u7ecf\u5728\u5168\u7403\u62e5\u6709\u6570\u767e\u4e07\u7528\u6237\uff0c\u4e5f\u662f\u4e00\u4e2a\u5f00\u6e90\u9879\u76ee\u3002

      \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

      "},{"location":"qpython-x/#qpython_1","title":"QPython","text":"

      \u6807\u51c6\u7248\uff1a\u9488\u5bf9 AI \u6027\u80fd\u548c\u901a\u7528\u5e94\u7528\u5546\u5e97\u517c\u5bb9\u6027\u4f18\u5316

      \u4e3b\u8981\u7248\u672c\uff0c\u53ef\u5728 Google Play \u548c\u5176\u4ed6\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002\u6b64\u7248\u672c\u4e13\u6ce8\u4e8e AI \u529f\u80fd\uff0c\u4f7f AI \u65f6\u4ee3\u7528\u6237\u66f4\u5bb9\u6613\u5b66\u4e60\u548c\u4f7f\u7528 Python\u3002

      \u4e3b\u8981\u7279\u6027\uff1a - AI \u9a71\u52a8\u7684\u7f16\u7801\u8f85\u52a9\u548c\u5b66\u4e60\u5de5\u5177 - \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668\uff1a\u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51 - \u652f\u6301\u591a\u79cd\u9879\u76ee\u7c7b\u578b\uff1a\u63a7\u5236\u53f0\u3001SL4A\u3001WebApp - \u65b9\u4fbf\u7684\u4e8c\u7ef4\u7801\u8bfb\u53d6\u5668\uff0c\u7528\u4e8e\u5c06\u4ee3\u7801\u4f20\u8f93\u5230\u624b\u673a - QPYPI \u548c\u81ea\u5b9a\u4e49\u4ed3\u5e93\uff0c\u7528\u4e8e\u9884\u7f16\u8bd1 wheel \u5305 -\u6613\u4e8e\u4f7f\u7528\u7684\u8bed\u6cd5\u9ad8\u4eae\u7f16\u8f91\u5668 - \u5b8c\u5584\u7684\u6587\u6863\u548c\u793e\u533a\u652f\u6301

      \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

      \u4e0b\u8f7d\uff1a \u53ef\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

      "},{"location":"qpython-x/#qpython_2","title":"QPython+","text":"

      \u793e\u533a\u7248\uff1a\u516c\u5f00\u652f\u6301\u5404\u79cd\u793e\u533a\u9a71\u52a8\u7684\u529f\u80fd\uff1b\u53ef\u5728\u90e8\u5206\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

      \u793e\u533a\u5f00\u6e90\u7248\u672c\uff08\u6b63\u5728\u89c4\u5212\u548c\u51c6\u5907\u4e2d\uff09\u3002\u6b64\u7248\u672c\u4e13\u4e3a\u60f3\u8981\u53c2\u4e0e QPython \u9879\u76ee\u5f00\u53d1\u7684\u8d21\u732e\u8005\u800c\u8bbe\u8ba1\uff0c\u652f\u6301\u9488\u5bf9\u4e0d\u540c\u5236\u9020\u5546\u7684\u5b9a\u5236\u3002

      \u4e3b\u8981\u7279\u6027\uff1a - \u793e\u533a\u9a71\u52a8\u5f00\u53d1 - \u652f\u6301\u4f9b\u5e94\u5546\u5b9a\u5236 - \u66f4\u7075\u6d3b\u7684\u914d\u7f6e\u9009\u9879 - \u5f00\u653e\u4f9b\u8d21\u732e\u8005\u52a0\u5165\u5f00\u53d1

      \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

      \u4e0b\u8f7d\uff1a \u5c06\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

      \u6ce8\u610f\uff1a \u6b64\u7248\u672c\u76ee\u524d\u6b63\u5728\u89c4\u5212\u51c6\u5907\u4e2d\u3002\u8bf7\u5173\u6ce8\u66f4\u65b0\uff01

      "},{"location":"qpython-x/#qpython-plus","title":"QPython Plus","text":"

      QPython+ \u5b8c\u5168\u8bbf\u95ee\u7248\uff1a\u6388\u4e88\u8c03\u7528\u6240\u6709 Android \u63a5\u53e3\u7684\u5b8c\u6574\u6743\u9650\u3002\u4e0b\u8f7d\u94fe\u63a5\u4ec5\u901a\u8fc7\u5b98\u65b9\u4e91\u76d8\u63d0\u4f9b\u3002

      \u5177\u6709\u6269\u5c55\u6743\u9650\u7684\u7279\u6b8a\u7248\u672c\uff0c\u63d0\u4f9b\u5bf9\u8bbe\u5907\u7684\u6700\u5927\u63a7\u5236\u3002\u7531\u4e8e\u5176\u654f\u611f\u7684\u6743\u9650\u8981\u6c42\uff0c\u6b64\u7248\u672c\u4e0d\u4f1a\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u53d1\u5e03\u3002

      \u4e3b\u8981\u7279\u6027\uff1a - \u5b8c\u6574\u7684 SL4A API \u8bbf\u95ee\uff0c\u5305\u62ec\u654f\u611f\u529f\u80fd - SMS/\u901a\u8bdd\u63a7\u5236 API - \u9ad8\u7ea7\u7cfb\u7edf\u96c6\u6210 - \u6700\u5927\u7684\u8bbe\u5907\u63a7\u5236\u80fd\u529b

      \u6743\u9650\uff1a \u9700\u8981\u5e7f\u6cdb\u7684\u6743\u9650\uff0c\u5305\u62ec\uff1a - \u84dd\u7259 - \u4f4d\u7f6e\uff08GPS\uff09 - \u8bfb\u53d6/\u53d1\u9001\u77ed\u4fe1 - \u6253\u7535\u8bdd - \u76f8\u673a\u548c\u9ea6\u514b\u98ce - \u7cfb\u7edf\u8bbe\u7f6e - \u4ee5\u53ca\u5176\u4ed6\u654f\u611f\u6743\u9650

      \u4e0b\u8f7d\uff1a \u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\u3002\u4ec5\u901a\u8fc7\u7279\u6b8a\u6e20\u9053\u5206\u53d1\u3002

      \u91cd\u8981\u63d0\u793a\uff1a QPython \u4e0d\u4f1a\u5728\u540e\u53f0\u672a\u7ecf\u60a8\u77e5\u6089\u4f7f\u7528\u8fd9\u4e9b\u6743\u9650\u3002\u5982\u679c\u4f7f\u7528 SL4A API \u65f6\u51fa\u73b0\u5f02\u5e38\uff0c\u8bf7\u68c0\u67e5\u7cfb\u7edf\u8bbe\u7f6e\u4e2d\u662f\u5426\u5df2\u542f\u7528\u76f8\u5173\u6743\u9650\u3002

      "},{"location":"tutorial-hello-world/","title":"\u7f16\u5199\"Hello World\"","text":""},{"location":"tutorial-hello-world/#hello-world_1","title":"Hello world","text":"

      \u597d\u7684\uff0c\u5728\u60a8\u5bf9 QPython \u6709\u4e86\u4e00\u5b9a\u7684\u4e86\u89e3\u4e4b\u540e\uff0c\u8ba9\u6211\u4eec\u5728 QPython \u4e2d\u521b\u5efa\u6211\u4eec\u7684\u7b2c\u4e00\u4e2a\u7a0b\u5e8f\u3002\u663e\u7136\uff0c\u5b83\u5c06\u662f helloworld.py\u3002;)

      \u542f\u52a8 QPython\uff0c\u6253\u5f00\u7f16\u8f91\u5668\u5e76\u8f93\u5165\u4ee5\u4e0b\u4ee3\u7801\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello, QPYTHON!')\n

      \u6beb\u65e0\u7591\u95ee\uff0c\u5b83\u4e0e\u5176\u4ed6\u4efb\u4f55 hello-world \u7a0b\u5e8f\u5e76\u65e0\u4e0d\u540c\u3002\u6267\u884c\u65f6\uff0c\u5b83\u53ea\u662f\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u5f39\u51fa\u6d88\u606f\uff08\u89c1\u9876\u90e8\u622a\u56fe\uff09\u3002\u65e0\u8bba\u5982\u4f55\uff0c\u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684 QPython \u7a0b\u5e8f\u793a\u4f8b\u3002

      "},{"location":"tutorial-hello-world/#_1","title":"\u4ee3\u7801\u7406\u89e3","text":"

      \u5b83\u4ee5 import androidhelper \u5f00\u5934\u2014\u2014\u8fd9\u662f QPython \u4e2d\u6700\u6709\u7528\u7684\u6a21\u5757\uff0c\u5b83\u5c01\u88c5\u4e86 Python \u4e2d\u53ef\u7528\u7684\u51e0\u4e4e\u6240\u6709\u4e0e Android \u7684\u63a5\u53e3\u3002\u4efb\u4f55\u5728 QPython \u4e2d\u5f00\u53d1\u7684\u811a\u672c\u90fd\u4ee5\u8fd9\u4e2a\u8bed\u53e5\u5f00\u5934\uff08\u81f3\u5c11\u5982\u679c\u5b83\u58f0\u79f0\u8981\u4e0e\u7528\u6237\u901a\u4fe1\u7684\u8bdd\uff09\u3002\u5728\u6b64\u5904\u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u5e93 \u548c import \u8bed\u53e5 \u7684\u5185\u5bb9\u3002

      \u63a5\u4e0b\u6765\u6211\u4eec\u521b\u5efa\u4e00\u4e2a droid \u5bf9\u8c61\uff08\u5b9e\u9645\u4e0a\u662f\u4e00\u4e2a\u7c7b\uff09\uff0c\u5b83\u5bf9\u4e8e\u8c03\u7528 RPC \u51fd\u6570\u4ee5\u4e0e Android \u901a\u4fe1\u662f\u5fc5\u8981\u7684\u3002

      \u6211\u4eec\u4ee3\u7801\u7684\u6700\u540e\u4e00\u884c\u8c03\u7528\u4e86\u8fd9\u6837\u7684\u51fd\u6570\uff0cdroid.makeToast()\uff0c\u5b83\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u4e00\u4e2a\u5c0f\u7684\u5f39\u51fa\u6d88\u606f\uff08\"toast\"\uff09\u3002

      \u597d\u7684\uff0c\u8ba9\u6211\u4eec\u6dfb\u52a0\u4e00\u4e9b\u66f4\u591a\u7684\u529f\u80fd\u3002\u8ba9\u5b83\u8be2\u95ee\u7528\u6237\u540d\u5e76\u5411\u7528\u6237\u6253\u62db\u547c\u3002

      "},{"location":"tutorial-hello-world/#_2","title":"\u66f4\u591a\u793a\u4f8b","text":"

      \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 dialogGetInput \u8c03\u7528\u663e\u793a\u4e00\u4e2a\u5e26\u6709\u6807\u9898\u3001\u63d0\u793a\u3001\u7f16\u8f91\u5b57\u6bb5\u548c \u786e\u5b9a \u548c \u53d6\u6d88 \u6309\u94ae\u7684\u7b80\u5355\u5bf9\u8bdd\u6846\u3002\u7528\u4ee5\u4e0b\u4ee3\u7801\u66ff\u6362\u60a8\u7684\u6700\u540e\u4e00\u884c\u4ee3\u7801\u5e76\u5c06\u5176\u4fdd\u5b58\u4e3a hello1.py\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\n

      \u597d\u7684\uff0c\u6211\u8ba4\u4e3a\u5b83\u5e94\u8be5\u8fd4\u56de\u4efb\u4f55\u54cd\u5e94\uff0c\u4efb\u4f55\u7528\u6237\u53cd\u5e94\u3002\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u6211\u5199 respond = ...\u3002\u4f46\u8fd9\u4e2a\u8c03\u7528\u5b9e\u9645\u4e0a\u8fd4\u56de\u4ec0\u4e48\uff1f\u8ba9\u6211\u4eec\u68c0\u67e5\u4e00\u4e0b\u3002\u53ea\u9700\u5728\u6700\u540e\u4e00\u884c\u540e\u6dfb\u52a0 print \u8bed\u53e5\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\n

      \u7136\u540e\u4fdd\u5b58\u5e76\u8fd0\u884c\u5b83...

      \u54ce\u5440\uff01\u6ca1\u6709\u6253\u5370\uff1f\u522b\u62c5\u5fc3\u3002\u53ea\u9700\u62c9\u4e0b\u901a\u77e5\u680f\uff0c\u60a8\u5c31\u4f1a\u770b\u5230\"QPython Program Output: hello1.py\"\u2014\u2014\u70b9\u51fb\u5b83\uff01

      \u5982\u60a8\u6240\u89c1\uff0cdroid.dialogGetInput() \u8fd4\u56de\u4e00\u4e2a\u5305\u542b\u4e09\u4e2a\u5b57\u6bb5\u7684 JSON \u5bf9\u8c61\u3002\u6211\u4eec\u53ea\u9700\u8981\u4e00\u4e2a\u2014\u2014result\uff0c\u5176\u4e2d\u5305\u542b\u7528\u6237\u5b9e\u9645\u8f93\u5165\u7684\u5185\u5bb9\u3002

      \u8ba9\u6211\u4eec\u6dfb\u52a0\u811a\u672c\u7684\u53cd\u5e94\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nmessage = f'Hello, {respond.result}!'\ndroid.makeToast(message)\n

      \u6700\u540e\u4e24\u884c\uff081\uff09\u683c\u5f0f\u5316\u6d88\u606f\uff0c\uff082\uff09\u4ee5 toast \u5f62\u5f0f\u5411\u7528\u6237\u663e\u793a\u6d88\u606f\u3002\u5982\u679c\u60a8\u4ecd\u7136\u4e0d\u77e5\u9053 f-string \u662f\u4ec0\u4e48\u610f\u601d\uff0c\u8bf7\u53c2\u9605 Python \u6587\u6863\u3002

      \u54c7\uff01\u5b83\u5de5\u4f5c\u4e86\uff01;)

      \u73b0\u5728\u6211\u8981\u5728\u90a3\u91cc\u6dfb\u52a0\u4e00\u4e9b\u903b\u8f91\u3002\u60f3\u4e00\u60f3\uff1a\u5982\u679c\u7528\u6237\u70b9\u51fb \u53d6\u6d88 \u6309\u94ae\uff0c\u6216\u8005\u70b9\u51fb \u786e\u5b9a \u4f46\u5c06\u8f93\u5165\u5b57\u6bb5\u7559\u7a7a\uff0c\u4f1a\u53d1\u751f\u4ec0\u4e48\uff1f

      \u60a8\u53ef\u4ee5\u73a9\u8fd9\u4e2a\u7a0b\u5e8f\uff0c\u68c0\u67e5 respond \u53d8\u91cf\u5728\u6bcf\u79cd\u60c5\u51b5\u4e0b\u5305\u542b\u4ec0\u4e48\u3002

      \u9996\u5148\uff0c\u6211\u60f3\u5c06\u7528\u6237\u8f93\u5165\u7684\u6587\u672c\u653e\u5165\u4e00\u4e2a\u5355\u72ec\u7684\u53d8\u91cf\u4e2d\uff1aname = respond.result\u3002\u7136\u540e\u6211\u68c0\u67e5\u5b83\uff0c\u5982\u679c\u5b83\u5305\u542b\u4efb\u4f55\u771f\u5b9e\u6587\u672c\uff0c\u5b83\u5c06\u88ab\u89c6\u4e3a\u540d\u79f0\u5e76\u7528\u4e8e\u95ee\u5019\u3002\u5426\u5219\uff0c\u5c06\u663e\u793a\u53e6\u4e00\u6761\u6d88\u606f\u3002\u5c06\u7b2c\u4e94\u884c message = f'Hello, {respond.result}!' \u66ff\u6362\u4e3a\u4ee5\u4e0b\u4ee3\u7801\uff1a

      name = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\n

      \u4f7f\u7528\u5de5\u5177\u680f\u4e0a\u7684 < \u548c > \u6309\u94ae\u6765\u7f29\u8fdb/\u53d6\u6d88\u7f29\u8fdb if \u8bed\u53e5\u4e2d\u7684\u884c\uff08\u6216\u8005\u53ea\u9700\u4f7f\u7528\u7a7a\u683c/\u9000\u683c\u952e\uff09\u3002\u60a8\u53ef\u4ee5\u5728 \u6b64\u5904 \u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u7f29\u8fdb\u7684\u5185\u5bb9\uff1bif \u8bed\u53e5\u5728 \u6b64\u5904 \u63cf\u8ff0\u3002

      \u9996\u5148\uff0c\u6211\u4eec\u5c06\u7528\u6237\u8f93\u5165\u653e\u5165 name \u53d8\u91cf\u3002\u7136\u540e\u6211\u4eec\u68c0\u67e5 name \u662f\u5426\u5305\u542b\u4efb\u4f55\u5185\u5bb9\uff1f\u5982\u679c\u7528\u6237\u7559\u7a7a\u884c\u5e76\u70b9\u51fb \u786e\u5b9a\uff0c\u8fd4\u56de\u503c\u662f\u7a7a\u5b57\u7b26\u4e32 ''\u3002\u5982\u679c\u6309\u4e0b\u4e86 \u53d6\u6d88 \u6309\u94ae\uff0c\u8fd4\u56de\u503c\u662f None\u3002\u5728 if \u8bed\u53e5\u4e2d\uff0c\u4e24\u8005\u90fd\u88ab\u89c6\u4e3a\u5047\u3002\u56e0\u6b64\uff0c\u53ea\u6709\u5f53 name \u5305\u542b\u4efb\u4f55\u6709\u610f\u4e49\u7684\u5185\u5bb9\u65f6\uff0cthen \u8bed\u53e5\u624d\u4f1a\u6267\u884c\uff0c\u5e76\u663e\u793a\u95ee\u5019\u8bed\"Hello, ...!\"\u3002\u5982\u679c\u8f93\u5165\u4e3a\u7a7a\uff0c\u7528\u6237\u5c06\u770b\u5230\"Hey! And you're not very polite, %Username%!\"\u6d88\u606f\u3002

      \u597d\u7684\uff0c\u8fd9\u662f\u6574\u4e2a\u7a0b\u5e8f\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nname = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\ndroid.makeToast(message)\n
      "},{"location":"tutorial-hello-world/#_3","title":"\u8fd0\u884c\u6548\u679c","text":""},{"location":"tutorial-hello-world/#_4","title":"\u4e0b\u4e00\u6b65","text":"

      \u5bf9\u4e8e Python \u65b0\u7528\u6237\uff0c\u63a8\u8350\u5b66\u4e60 Python \u8bed\u6cd5\u5b9e\u8df5 \u8bfe\u7a0b\u6765\u8fdb\u4e00\u6b65\u5b66\u4e60 Python\uff0c\u6216\u8005\u5728 QPython \u7cbe\u9009\u8bfe\u7a0b \u4e2d\u5bfb\u627e\u60f3\u8981\u5b66\u4e60\u7684\u5185\u5bb9\u3002

      "},{"location":"whats-new/","title":"\u66f4\u65b0\u65e5\u5fd7","text":""},{"location":"whats-new/#v392-v393","title":"v3.9.2 / v3.9.3","text":"
      • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
      • \u7f16\u8f91\u5668\u91cd\u5927\u66f4\u65b0\uff0c\u5e26\u6765\u66f4\u6d41\u7545\u7684\u7f16\u8f91\u4f53\u9a8c
      • \u5176\u4ed6\u5404\u79cd\u5c0f\u6539\u8fdb
      "},{"location":"whats-new/#v391","title":"v3.9.1","text":"
      • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
      • \u6269\u5c55\u5305\u73b0\u5728\u652f\u6301 MCP
      • \u9519\u8bef\u4fee\u590d
      "},{"location":"whats-new/#v390","title":"v3.9.0","text":"
      • SDK \u5347\u7ea7\uff0c\u6574\u5408\u6700\u65b0\u7684 Android \u529f\u80fd
      • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
      • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
      • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
      "},{"location":"whats-new/#v3811","title":"v3.8.11","text":"
      • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
      • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
      • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
      "},{"location":"whats-new/#v3810","title":"v3.8.10","text":"
      • \u5185\u7f6e Ollama \u5347\u7ea7\uff1a\u73b0\u5728\u60a8\u53ef\u4ee5\u5728 QPython \u4e2d\u8f7b\u677e\u672c\u5730\u8fd0\u884c Qwen3 / Gemma3 \u6a21\u578b\uff01
      • \u6dfb\u52a0\u4e86\u5f3a\u5927\u7684 MCP \u5e93\uff1a\u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 mcp \u5e93\uff0c\u8ba9\u60a8\u968f\u65f6\u968f\u5730\u643a\u5e26\u5f3a\u5927\u7684 MCP \u529f\u80fd\uff01
      "},{"location":"whats-new/#v389","title":"v3.8.9","text":"

      \u91cd\u5927\u66f4\u65b0\uff01AI \u7f16\u7a0b\u5b8c\u5168\u96c6\u6210\u5230 QPython\uff0c\u8ba9\u60a8\u7684\u7f16\u7a0b\u66f4\u8f7b\u677e\uff01

      • \u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u652f\u6301\uff1a\u65b0\u652f\u6301 AIPyApp\uff0c\u5728 QPython \u4e2d\u5b9e\u73b0\u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u3002\u76ee\u524d\u5904\u4e8e\u6d4b\u8bd5\u9636\u6bb5 - \u52a0\u5165\u6211\u4eec\u7684\u793e\u533a\u83b7\u53d6\u4f7f\u7528\u8bf4\u660e
      • \u65b0 QSL4A \u529f\u80fd\uff1a\u6dfb\u52a0 notebookOpen \u51fd\u6570\uff0c\u652f\u6301\u81ea\u7136\u8bed\u8a00\u63a7\u5236\u6253\u5f00 Notebook \u6587\u4ef6
      • \u5185\u7f6e\u7f16\u8f91\u5668\u5347\u7ea7\uff1a\u589e\u5f3a\u7f16\u8f91\u5668\u529f\u80fd\uff0c\u652f\u6301\u6253\u5f00\u548c\u6d4f\u89c8\u5404\u79cd\u6587\u672c\u6587\u4ef6
      • \u4fbf\u6377\u7684\u6587\u4ef6\u7ba1\u7406\uff1a\u5728\u6587\u4ef6\u7ba1\u7406\u5668\u4e2d\u6dfb\u52a0\u5185\u90e8\u5b58\u50a8\u5165\u53e3\uff0c\u5feb\u901f\u8bbf\u95ee\u60a8\u7684\u6587\u4ef6
      "},{"location":"whats-new/#v388","title":"v3.8.8","text":"
      • \u6587\u4ef6\u8bbf\u95ee\u6743\u9650\u63a7\u5236\u7684\u91cd\u8981\u6539\u8fdb\uff0c\u5141\u8bb8\u7528\u6237\u7075\u6d3b\u5730\u901a\u8fc7 QPython \u7f16\u7a0b\u542f\u7528\u6216\u7981\u7528\u5916\u90e8\u5b58\u50a8\u6587\u4ef6\u7684\u8bbf\u95ee
      • SDK \u5347\u7ea7\uff0c\u589e\u5f3a\u4e86\u5bf9\u65b0\u7248 Android \u7684\u652f\u6301\u548c\u517c\u5bb9\u6027
      • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Anthropic \u548c Google GenAI \u5e93
      "},{"location":"whats-new/#v387","title":"v3.8.7","text":"
      • \u5728\u73b0\u6709 Tkinter \u652f\u6301\u57fa\u7840\u4e0a\uff0c\u5728 Extensions -> Tools \u4e2d\u6dfb\u52a0\u4e86\u4f7f\u7528 Turtle \u7ed8\u5236\u54c6\u5566A\u68a6\u7684\u793a\u4f8b\u4ee3\u7801
      • \u4f18\u5316\u4e86\u624b\u673a\u6743\u9650\u83b7\u53d6\u6d41\u7a0b\uff0c\u63d0\u5347\u7528\u6237\u4f53\u9a8c\u548c\u64cd\u4f5c\u4fbf\u5229\u6027
      • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Google Gen AI \u5e93\uff0c\u65b9\u4fbf\u8bbf\u95ee Gemini Developer API \u548c Vertex AI
      "},{"location":"whats-new/#v386","title":"v3.8.6","text":"
      • Tkinter \u652f\u6301\uff1a\u73b0\u5728\u652f\u6301 Tkinter \u5e93\uff0c\u53ef\u901a\u8fc7 XServer \u8bbf\u95ee\u3002\u8bf7\u8bbf\u95ee www.qpython.org \u7684\u4e91\u76d8\"Extra\"\u94fe\u63a5\u4e0b\u8f7d\u6240\u9700\u6587\u4ef6
      • \u5b58\u50a8\u6743\u9650\u66f4\u65b0\uff1a\u4e3a\u6539\u5584\u7528\u6237\u4f53\u9a8c\uff0c\u6211\u4eec\u6dfb\u52a0\u4e86\u8bfb\u53d6\u624b\u673a\u5b58\u50a8\u7684\u6743\u9650\uff0c\u7528\u4e8e\u8bbf\u95ee\u5b58\u50a8\u5728\u5176\u4ed6\u76ee\u5f55\u4e2d\u7684 Python \u7a0b\u5e8f

      \u6b64\u66f4\u65b0\u540e\uff0cQPython \u548c QPythonPlus\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff0c\u4e13\u4e3a\u9700\u8981\u66f4\u591a\u654f\u611f\u6743\u9650\u7684\u9ad8\u7ea7\u7528\u6237\u8bbe\u8ba1\uff09\u5c06\u4fdd\u6301\u540c\u6b65\u7684\u7248\u672c\u53f7\u3002

      "},{"location":"whats-new/#v352-2025225","title":"v3.5.2 (2025/2/25)","text":"

      \u4e0e\u5f00\u6e90 LLM \u90e8\u7f72\u5de5\u5177 Ollama \u4ee5\u53ca DeepSeek \u5f00\u53d1\u7684 DeepSeek \u5b9e\u73b0\u65e0\u7f1d\u96c6\u6210\uff01

      \u529f\u80fd\uff1a - \u96f6\u95e8\u69db\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5404\u79cd\u5927\u578b\u8bed\u8a00\u6a21\u578b - \u5feb\u901f\u90e8\u7f72 DeepSeek \u7b49\u5c16\u7aef AI \u6a21\u578b - \u4eab\u53d7\u7b80\u7ea6\u7684 API \u8c03\u7528\u4f53\u9a8c - \u6784\u5efa\u5b8c\u5168\u79bb\u7ebf\u7684\u667a\u80fd\u7f16\u7a0b\u73af\u5883

      \u80fd\u529b\uff1a - \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u52a0\u8f7d/\u7ba1\u7406 LLM \u6a21\u578b - \u57fa\u4e8e\u672c\u5730\u8ba1\u7b97\u7684\u5b9e\u65f6\u4f4e\u5ef6\u8fdf\u54cd\u5e94

      "},{"location":"whats-new/#v350","title":"v3.5.0","text":"
      • Python \u5347\u7ea7\u5230 3.12.8
      • \u6539\u8fdb\u4eea\u8868\u76d8\uff0c\u529f\u80fd\u66f4\u6e05\u6670\u3001\u66f4\u4eba\u6027\u5316
      • \u6dfb\u52a0\u4e86\u4f17\u591a\u7b2c\u4e09\u65b9\u5305\uff1aPyTorch / Twisted / Scrapy / FastAPI ...
      "},{"location":"whats-new/#v338","title":"v3.3.8","text":"
      • \u4fee\u590d\u4e86 NumPy \u517c\u5bb9\u6027\u95ee\u9898
      "},{"location":"whats-new/#v335","title":"v3.3.5","text":"
      • \u5347\u7ea7 Python \u5185\u6838\u5230 3.11.9
      • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u4e0d\u663e\u793a\u6a21\u5757\u5b89\u88c5\u72b6\u6001\u7684 bug
      • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u5220\u9664\u6a21\u5757\u5931\u8d25\u7684 bug
      • \u4fee\u590d\u4e86\u5176\u4ed6 bug
      "},{"location":"whats-new/#v334","title":"v3.3.4","text":"
      • \u6dfb\u52a0\u4e86 OpenAI/Langchain/APIGPTCloud AI \u5305
      • \u79fb\u9664\u4e0d\u5fc5\u8981\u7684\u6587\u4ef6\u4ee5\u51cf\u5c11\u5927\u5c0f
      "},{"location":"whats-new/#v325","title":"v3.2.5","text":"
      • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570
      • \u5176\u4ed6\u9519\u8bef\u4fee\u590d
      "},{"location":"whats-new/#v323","title":"v3.2.3","text":"
      • \u66f4\u65b0 Python \u7248\u672c\u5230 3.11.0
      • \u66f4\u65b0 IPython \u7248\u672c\u5230 8.6.0
      • \u66f4\u65b0 pip \u7248\u672c\u5230 22.3.1
      • \u66f4\u65b0\u79d1\u5b66\u8ba1\u7b97\u5305\uff0c\u81ea\u52a8\u8f6f\u94fe\u63a5
      • \u51cf\u5c11\u7a7a\u95f4\u4f7f\u7528
      • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570 + \u5176\u4ed6\u9519\u8bef\u4fee\u590d
      "},{"location":"whats-new/#v318","title":"v3.1.8","text":"
      • \u5728\u7ec8\u7aef\u4e2d\u6dfb\u52a0\u4e86\u64cd\u4f5c\u70ed\u952e
      • \u4fee\u590d\u4e86\u7f16\u8f91\u5668\u5728\u65cb\u8f6c\u65f6\u4e22\u5931\u5185\u5bb9\u7684\u95ee\u9898
      • \u4fee\u590d\u4e86\u5176\u4ed6 bug

      \u5728 Google Play \u4e0b\u8f7d

      "},{"location":"qsl4a/","title":"QSL4A\uff08Android \u811a\u672c\u5c42\uff09API \u6587\u6863","text":"

      QSL4A \u662f QPython \u7684 Android \u811a\u672c\u5c42\uff0c\u5141\u8bb8\u60a8\u4f7f\u7528 Python \u63a7\u5236 Android \u8bbe\u5907\u529f\u80fd\u3002

      "},{"location":"qsl4a/#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a toast \u6d88\u606f\ndroid.makeToast('Hello QPython!')\n\n# \u9707\u52a8\u8bbe\u5907\ndroid.vibrate(500)\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\uff08\u5148\u5f00\u59cb\u76d1\u63a7\uff09\nimport time\ndroid.batteryStartMonitoring()\ntime.sleep(0.5)  # \u7b49\u5f85\u6570\u636e\nbattery = droid.readBatteryData().result\nprint(f\"\u7535\u6c60\uff1a{battery['level']}%\")\n
      "},{"location":"qsl4a/#_2","title":"\u6587\u6863\u7ed3\u6784","text":""},{"location":"qsl4a/#_3","title":"\u6838\u5fc3\u6a21\u5757","text":"
      • Android \u57fa\u7840 - \u6838\u5fc3\u8fde\u63a5\u548c RPC
      • Intent \u7cfb\u7edf - Android Intent \u64cd\u4f5c
      • \u4e8b\u4ef6\u7cfb\u7edf - \u4e8b\u4ef6\u5904\u7406\u548c\u5e7f\u64ad
      "},{"location":"qsl4a/#ui","title":"UI \u7ec4\u4ef6","text":"
      • \u5bf9\u8bdd\u6846 - \u8b66\u62a5\u3001\u8f93\u5165\u3001\u9009\u62e9\u5bf9\u8bdd\u6846
      • \u5168\u5c4f UI - \u81ea\u5b9a\u4e49\u5e03\u5c40 UI
      • \u60ac\u6d6e\u7a97 - \u60ac\u6d6e\u7a97\u53e3
      • \u8f85\u52a9\u529f\u80fd - \u5c4f\u5e55\u81ea\u52a8\u5316
      "},{"location":"qsl4a/#_4","title":"\u7cfb\u7edf","text":"
      • \u7535\u6c60 - \u7535\u6c60\u76d1\u63a7
      • \u4f20\u611f\u5668 - \u8bbe\u5907\u4f20\u611f\u5668
      • \u5e94\u7528 - \u5e94\u7528\u7ba1\u7406
      • \u7cfb\u7edf\u4fe1\u606f - \u8bbe\u5907\u4fe1\u606f
      • \u8bbe\u7f6e - \u7cfb\u7edf\u8bbe\u7f6e
      • \u5524\u9192\u9501 - \u5524\u9192\u9501\u63a7\u5236
      • QPython \u63a5\u53e3 - \u811a\u672c\u6267\u884c
      • Activity \u7ed3\u679c - Activity \u7ed3\u679c\u5904\u7406
      "},{"location":"qsl4a/#_5","title":"\u786c\u4ef6","text":"
      • \u84dd\u7259 - \u84dd\u7259\u64cd\u4f5c
      • \u76f8\u673a - \u62cd\u7167\u548c\u5f55\u50cf
      • \u97f3\u9891/\u5f55\u97f3\u5668 - \u5f55\u97f3
      • \u7f51\u7edc\u6444\u50cf\u5934 - MJPEG \u6d41
      • USB \u4e32\u53e3 - USB \u4e3b\u673a\u4e32\u53e3
      "},{"location":"qsl4a/#_6","title":"\u8fde\u63a5","text":"
      • WiFi - WiFi \u64cd\u4f5c
      • \u4f4d\u7f6e - GPS \u548c\u4f4d\u7f6e
      • \u77ed\u4fe1 - \u77ed\u4fe1\u64cd\u4f5c
      • \u7535\u8bdd - \u6253\u7535\u8bdd\u548c\u6765\u7535\u4fe1\u606f
      • \u8054\u7cfb\u4eba - \u8054\u7cfb\u4eba\u7ba1\u7406
      • \u4fe1\u53f7\u5f3a\u5ea6 - \u4fe1\u53f7\u76d1\u63a7
      • FTP \u670d\u52a1\u5668 - \u5185\u7f6e FTP \u670d\u52a1\u5668
      "},{"location":"qsl4a/#_7","title":"\u5b58\u50a8","text":"
      • DocumentFile - \u6587\u4ef6\u64cd\u4f5c
      • \u526a\u8d34\u677f - \u526a\u8d34\u677f\u64cd\u4f5c
      • \u504f\u597d\u8bbe\u7f6e - \u5171\u4eab\u504f\u597d\u8bbe\u7f6e
      "},{"location":"qsl4a/#_8","title":"\u5a92\u4f53","text":"
      • \u5a92\u4f53\u64ad\u653e\u5668 - \u97f3\u9891/\u89c6\u9891\u64ad\u653e
      • \u56fe\u50cf\u5904\u7406 - \u56fe\u50cf\u64cd\u4f5c
      "},{"location":"qsl4a/#_9","title":"\u7279\u6b8a\u529f\u80fd","text":"
      • \u52a0\u5bc6 - \u52a0\u5bc6/\u89e3\u5bc6
      • PGPT AI - AI \u8bed\u97f3\u670d\u52a1
      "},{"location":"qsl4a/#_10","title":"\u7ed3\u679c\u5bf9\u8c61","text":"

      \u5927\u591a\u6570 QSL4A \u65b9\u6cd5\u8fd4\u56de\u4e00\u4e2a\u5e26\u6709\u4ee5\u4e0b\u5c5e\u6027\u7684 Result \u547d\u540d\u5143\u7ec4\uff1a - id - \u8bf7\u6c42 ID - result - \u5b9e\u9645\u7ed3\u679c\u6570\u636e - error - \u5982\u679c\u5931\u8d25\u5219\u4e3a\u9519\u8bef\u6d88\u606f

      result = droid.getClipboard()\nif result.error is None:\n    print(result.result)\nelse:\n    print(f\"\u9519\u8bef\uff1a{result.error}\")\n
      "},{"location":"qsl4a/connectivity/contacts/","title":"\u8054\u7cfb\u4eba API","text":"

      \u8bbf\u95ee\u548c\u7ba1\u7406\u8bbe\u5907\u8054\u7cfb\u4eba\u3002

      "},{"location":"qsl4a/connectivity/contacts/#_1","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":""},{"location":"qsl4a/connectivity/contacts/#pickcontact","title":"pickContact()","text":"

      \u663e\u793a\u8054\u7cfb\u4eba\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

      pickContact()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u8054\u7cfb\u4eba URI \u7684 Intent

      "},{"location":"qsl4a/connectivity/contacts/#pickphone","title":"pickPhone()","text":"

      \u663e\u793a\u7535\u8bdd\u53f7\u7801\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

      pickPhone()\n

      \u8fd4\u56de\uff1a \u9009\u4e2d\u7684\u7535\u8bdd\u53f7\u7801\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/contacts/#_2","title":"\u8054\u7cfb\u4eba\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#contactsget","title":"contactsGet()","text":"

      \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\u3002

      contactsGet(attributes=None)\n

      \u53c2\u6570\uff1a - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

      \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba JSONObject \u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetbyid","title":"contactsGetById()","text":"

      \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\u3002

      contactsGetById(id, attributes=None)\n

      \u53c2\u6570\uff1a - id (int): \u8054\u7cfb\u4eba ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

      \u8fd4\u56de\uff1a JSONObject \u8054\u7cfb\u4eba\u6570\u636e

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetcount","title":"contactsGetCount()","text":"

      \u83b7\u53d6\u8054\u7cfb\u4eba\u603b\u6570\u3002

      contactsGetCount()\n

      \u8fd4\u56de\uff1a \u6574\u6570\u8ba1\u6570

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetids","title":"contactsGetIds()","text":"

      \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba ID\u3002

      contactsGetIds()\n

      \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba ID \u6574\u6570\u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetattributes","title":"contactsGetAttributes()","text":"

      \u83b7\u53d6\u6240\u6709\u53ef\u80fd\u7684\u8054\u7cfb\u4eba\u5c5e\u6027\u3002

      contactsGetAttributes()\n

      \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#_3","title":"\u5185\u5bb9\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#querycontent","title":"queryContent()","text":"

      \u4f7f\u7528\u81ea\u5b9a\u4e49\u53c2\u6570\u67e5\u8be2\u5185\u5bb9\u89e3\u6790\u5668\u3002

      queryContent(uri, attributes=None, selection=None, selectionArgs=None, order=None)\n

      \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u5c5e\u6027 - selection (str, optional): WHERE \u5b50\u53e5 - selectionArgs (list, optional): \u9009\u62e9\u53c2\u6570 - order (str, optional): ORDER BY \u5b50\u53e5

      \u8fd4\u56de\uff1a JSONObject \u7ed3\u679c\u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#queryattributes","title":"queryAttributes()","text":"

      \u83b7\u53d6\u5185\u5bb9 URI \u7684\u5c5e\u6027\u3002

      queryAttributes(uri)\n

      \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI

      \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u7684 JSONArray

      "},{"location":"qsl4a/connectivity/contacts/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u9009\u62e9\u8054\u7cfb\u4eba\ncontact_uri = droid.pickContact().result\nprint(f\"Selected contact: {contact_uri}\")\n\n# \u9009\u62e9\u7535\u8bdd\u53f7\u7801\nphone = droid.pickPhone().result\nprint(f\"Selected phone: {phone}\")\n\n# \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\ncontacts = droid.contactsGet().result\nprint(f\"Total contacts: {len(contacts)}\")\n\n# \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\ncontact = droid.contactsGetById(1).result\nprint(f\"Contact: {contact}\")\n\n# \u83b7\u53d6\u8054\u7cfb\u4eba\u5c5e\u6027\nattrs = droid.contactsGetAttributes().result\nprint(f\"Available attributes: {attrs}\")\n
      "},{"location":"qsl4a/connectivity/ftp/","title":"FTP \u670d\u52a1\u5668 API","text":"

      \u5728\u8bbe\u5907\u4e0a\u542f\u52a8\u548c\u7ba1\u7406\u5185\u7f6e FTP \u670d\u52a1\u5668\u3002

      "},{"location":"qsl4a/connectivity/ftp/#ftp","title":"FTP \u670d\u52a1\u5668\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/ftp/#ftpstart","title":"ftpStart()","text":"

      \u542f\u52a8 FTP \u670d\u52a1\u5668\u3002

      ftpStart()\n

      \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4 [ip, port]

      "},{"location":"qsl4a/connectivity/ftp/#ftpstop","title":"ftpStop()","text":"

      \u505c\u6b62 FTP \u670d\u52a1\u5668\u3002

      ftpStop()\n
      "},{"location":"qsl4a/connectivity/ftp/#ftpisrunning","title":"ftpIsRunning()","text":"

      \u68c0\u67e5 FTP \u670d\u52a1\u5668\u662f\u5426\u6b63\u5728\u8fd0\u884c\u3002

      ftpIsRunning()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u8fd0\u884c\u5219\u4e3a True

      "},{"location":"qsl4a/connectivity/ftp/#ftpget","title":"ftpGet()","text":"

      \u83b7\u53d6 FTP \u670d\u52a1\u5668 IP \u5730\u5740\u3002

      ftpGet()\n

      \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4

      "},{"location":"qsl4a/connectivity/ftp/#ftpset","title":"ftpSet()","text":"

      \u914d\u7f6e FTP \u670d\u52a1\u5668\u8bbe\u7f6e\u3002

      ftpSet(port=None, rootDir=None, username=None, password=None)\n

      \u53c2\u6570\uff1a - port (int, optional): \u670d\u52a1\u5668\u7aef\u53e3 - rootDir (str, optional): \u8981\u670d\u52a1\u7684\u57fa\u7840\u76ee\u5f55 - username (str, optional): \u767b\u5f55\u7528\u6237\u540d - password (str, optional): \u767b\u5f55\u5bc6\u7801

      \u8fd4\u56de\uff1a \u5305\u542b\u5f53\u524d\u8bbe\u7f6e\u7684 JSONObject

      "},{"location":"qsl4a/connectivity/ftp/#ftpstatus","title":"ftpStatus()","text":"

      \u83b7\u53d6 FTP \u670d\u52a1\u5668\u72b6\u6001\u3002

      ftpStatus()\n

      \u8fd4\u56de\uff1a \u72b6\u6001\u63cf\u8ff0\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/ftp/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u914d\u7f6e FTP \u670d\u52a1\u5668\ndroid.ftpSet(\n    port=2121,\n    rootDir=\"/sdcard\",\n    username=\"admin\",\n    password=\"secret\"\n)\n\n# \u542f\u52a8 FTP \u670d\u52a1\u5668\ninfo = droid.ftpStart().result\nprint(f\"FTP running at {info[0]}:{info[1]}\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.ftpIsRunning().result:\n    print(\"FTP server is running\")\n\n# \u83b7\u53d6\u670d\u52a1\u5668\u4fe1\u606f\nserver_info = droid.ftpGet().result\nprint(f\"Server: {server_info}\")\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.ftpStop()\n

      \u6ce8\u610f\uff1a \u4f7f\u7528\u63d0\u4f9b\u7684\u51ed\u636e\u901a\u8fc7\u4efb\u4f55 FTP \u5ba2\u6237\u7aef\u8fde\u63a5\u5230 FTP \u670d\u52a1\u5668\u3002

      "},{"location":"qsl4a/connectivity/location/","title":"\u4f4d\u7f6e API","text":"

      \u8bbf\u95ee GPS \u548c\u7f51\u7edc\u4f4d\u7f6e\u670d\u52a1\u3002

      "},{"location":"qsl4a/connectivity/location/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/location/#startlocating","title":"startLocating()","text":"

      \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\u3002

      startLocating(minUpdateTime=60000, minUpdateDistance=30, updateGnssStatus=False)\n

      \u53c2\u6570\uff1a - minUpdateTime (int): \u66f4\u65b0\u4e4b\u95f4\u7684\u6700\u5c0f\u65f6\u95f4\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a60000\uff09 - minUpdateDistance (float): \u66f4\u65b0\u7684\u6700\u5c0f\u8ddd\u79bb\uff08\u7c73\uff09\uff08\u9ed8\u8ba4\uff1a30\uff09 - updateGnssStatus (bool): \u542f\u7528 GNSS \u72b6\u6001\u66f4\u65b0\uff08\u9ed8\u8ba4\uff1aFalse\uff09

      "},{"location":"qsl4a/connectivity/location/#stoplocating","title":"stopLocating()","text":"

      \u505c\u6b62\u4f4d\u7f6e\u66f4\u65b0\u3002

      stopLocating()\n
      "},{"location":"qsl4a/connectivity/location/#readlocation","title":"readLocation()","text":"

      \u83b7\u53d6\u6700\u540e\u5df2\u77e5\u4f4d\u7f6e\u3002

      readLocation()\n

      \u8fd4\u56de\uff1a \u4f4d\u7f6e\u6570\u636e\u5b57\u5178

      "},{"location":"qsl4a/connectivity/location/#getlastknownlocation","title":"getLastKnownLocation()","text":"

      \u83b7\u53d6\u7f13\u5b58\u7684\u4f4d\u7f6e\u3002

      getLastKnownLocation()\n

      \u8fd4\u56de\uff1a \u6765\u81ea\u6240\u6709\u63d0\u4f9b\u5546\u7684\u4f4d\u7f6e

      "},{"location":"qsl4a/connectivity/location/#geocode","title":"geocode()","text":"

      \u5c06\u5730\u5740\u8f6c\u6362\u4e3a\u5750\u6807\u3002

      geocode(address, maxResults=1)\n
      "},{"location":"qsl4a/connectivity/location/#_2","title":"\u4f4d\u7f6e\u63d0\u4f9b\u5546\u65b9\u6cd5)","text":""},{"location":"qsl4a/connectivity/location/#locationproviders","title":"locationProviders()","text":"

      \u83b7\u53d6\u624b\u673a\u4e0a\u53ef\u7528\u7684\u4f4d\u7f6e\u63d0\u4f9b\u5546\u3002

      locationProviders()\n

      \u8fd4\u56de\uff1a \u53ef\u7528\u63d0\u4f9b\u5546\u540d\u79f0\u5217\u8868\uff08\u4f8b\u5982 ['gps', 'network']\uff09

      "},{"location":"qsl4a/connectivity/location/#locationproviderenabled","title":"locationProviderEnabled()","text":"

      \u68c0\u67e5\u7279\u5b9a\u4f4d\u7f6e\u63d0\u4f9b\u5546\u662f\u5426\u5df2\u542f\u7528\u3002

      locationProviderEnabled(provider)\n

      \u53c2\u6570\uff1a - provider (str): \u63d0\u4f9b\u5546\u540d\u79f0\uff08\u4f8b\u5982 'gps', 'network'\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/connectivity/location/#readgnssstatus","title":"readGnssStatus()","text":"

      \u8bfb\u53d6\u5168\u7403\u5bfc\u822a\u536b\u661f\u7cfb\u7edf\u72b6\u6001\uff08\u9700\u8981 Android 8+\uff09\u3002

      readGnssStatus()\n

      \u8fd4\u56de\uff1a \u5305\u542b GNSS \u536b\u661f\u4fe1\u606f\u7684 JSONArray

      "},{"location":"qsl4a/connectivity/location/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\ndroid.startLocating(minUpdateTime=5000, minUpdateDistance=1, updateGnssStatus=False)\n\n# \u7b49\u5f85\u5b9a\u4f4d\ntime.sleep(10)\n\n# \u83b7\u53d6\u4f4d\u7f6e\nloc = droid.readLocation().result\nif loc:\n    lat = loc['latitude']\n    lon = loc['longitude']\n    print(f\"Location: {lat}, {lon}\")\n\ndroid.stopLocating()\n
      "},{"location":"qsl4a/connectivity/phone/","title":"\u7535\u8bdd API","text":"

      \u63a7\u5236\u7535\u8bdd\u901a\u8bdd\u548c\u83b7\u53d6\u7535\u8bdd\u4fe1\u606f\u3002

      "},{"location":"qsl4a/connectivity/phone/#_1","title":"\u7535\u8bdd\u72b6\u6001\u8ddf\u8e2a","text":""},{"location":"qsl4a/connectivity/phone/#starttrackingphonestate","title":"startTrackingPhoneState()","text":"

      \u5f00\u59cb\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u53d8\u5316\u3002\u751f\u6210 'phone' \u4e8b\u4ef6\u3002

      startTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/phone/#readphonestate","title":"readPhoneState()","text":"

      \u8bfb\u53d6\u5f53\u524d\u7535\u8bdd\u72b6\u6001\u3002

      readPhoneState()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7535\u8bdd\u72b6\u6001\u548c\u6765\u7535\u53f7\u7801\u7684 Bundle

      "},{"location":"qsl4a/connectivity/phone/#stoptrackingphonestate","title":"stopTrackingPhoneState()","text":"

      \u505c\u6b62\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u3002

      stopTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/phone/#_2","title":"\u62e8\u6253\u7535\u8bdd","text":""},{"location":"qsl4a/connectivity/phone/#phonecall","title":"phoneCall()","text":"

      \u901a\u8fc7 URI \u547c\u53eb\u8054\u7cfb\u4eba/\u7535\u8bdd\u53f7\u7801\u3002

      phoneCall(uri)\n

      \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

      "},{"location":"qsl4a/connectivity/phone/#phonecallnumber","title":"phoneCallNumber()","text":"

      \u76f4\u63a5\u62e8\u6253\u7535\u8bdd\u53f7\u7801\u3002

      phoneCallNumber(phone_number)\n

      \u53c2\u6570\uff1a - phone_number (str): \u8981\u62e8\u6253\u7684\u7535\u8bdd\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#phonedial","title":"phoneDial()","text":"

      \u62e8\u6253\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

      phoneDial(uri)\n

      \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

      "},{"location":"qsl4a/connectivity/phone/#phonedialnumber","title":"phoneDialNumber()","text":"

      \u62e8\u6253\u7535\u8bdd\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

      phoneDialNumber(phone_number)\n

      \u53c2\u6570\uff1a - phone_number (str): \u7535\u8bdd\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#_3","title":"\u57fa\u7ad9\u4f4d\u7f6e","text":""},{"location":"qsl4a/connectivity/phone/#getcelllocation","title":"getCellLocation()","text":"

      \u83b7\u53d6\u5f53\u524d\u57fa\u7ad9\u4f4d\u7f6e\u3002

      getCellLocation()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u57fa\u7ad9\u4f4d\u7f6e\u6570\u636e\u7684 JSONObject

      "},{"location":"qsl4a/connectivity/phone/#getallcellslocation","title":"getAllCellsLocation()","text":"

      \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u4f4d\u7f6e\uff08\u9002\u7528\u4e8e\u53cc\u5361\u8bbe\u5907\uff09\u3002

      getAllCellsLocation()\n

      \u8fd4\u56de\uff1a \u57fa\u7ad9\u4f4d\u7f6e\u7684 JSONArray

      "},{"location":"qsl4a/connectivity/phone/#_4","title":"\u7f51\u7edc\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getnetworkoperator","title":"getNetworkOperator()","text":"

      \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

      getNetworkOperator()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getnetworkoperatorname","title":"getNetworkOperatorName()","text":"

      \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684\u540d\u79f0\u3002

      getNetworkOperatorName()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getnetworktype","title":"getNetworkType()","text":"

      \u83b7\u53d6\u5f53\u524d\u7f51\u7edc\u7c7b\u578b\u3002

      getNetworkType()\n

      \u8fd4\u56de\uff1a \u63cf\u8ff0\u65e0\u7ebf\u7535\u6280\u672f\u7684\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'LTE', 'UMTS', 'GSM'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getphonetype","title":"getPhoneType()","text":"

      \u83b7\u53d6\u7535\u8bdd\u7c7b\u578b\u3002

      getPhoneType()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'GSM', 'CDMA', 'SIP'\uff09

      "},{"location":"qsl4a/connectivity/phone/#sim","title":"SIM \u5361\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getsimcountryiso","title":"getSimCountryIso()","text":"

      \u83b7\u53d6 SIM \u5361\u7684 ISO \u56fd\u5bb6\u4ee3\u7801\u3002

      getSimCountryIso()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'us'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getsimoperator","title":"getSimOperator()","text":"

      \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

      getSimOperator()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getsimoperatorname","title":"getSimOperatorName()","text":"

      \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u540d\u79f0\u3002

      getSimOperatorName()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getsimserialnumber","title":"getSimSerialNumber()","text":"

      \u83b7\u53d6 SIM \u5e8f\u5217\u53f7\u3002

      getSimSerialNumber()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32 SIM \u5e8f\u5217\u53f7

      "},{"location":"qsl4a/connectivity/phone/#getsimstate","title":"getSimState()","text":"

      \u83b7\u53d6 SIM \u5361\u72b6\u6001\u3002

      getSimState()\n

      \u8fd4\u56de\uff1a \u63cf\u8ff0 SIM \u72b6\u6001\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/phone/#getsubscriberid","title":"getSubscriberId()","text":"

      \u83b7\u53d6\u8ba2\u9605\u8005 ID\u3002

      getSubscriberId()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8ba2\u9605\u8005 ID

      "},{"location":"qsl4a/connectivity/phone/#_5","title":"\u8bed\u97f3\u90ae\u4ef6","text":""},{"location":"qsl4a/connectivity/phone/#getvoicemailalphatag","title":"getVoiceMailAlphaTag()","text":"

      \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u5b57\u6bcd\u6807\u7b7e\u3002

      getVoiceMailAlphaTag()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u6807\u7b7e

      "},{"location":"qsl4a/connectivity/phone/#getvoicemailnumber","title":"getVoiceMailNumber()","text":"

      \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801\u3002

      getVoiceMailNumber()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getdeviceid","title":"getDeviceId()","text":"

      \u83b7\u53d6\u8bbe\u5907 ID\uff08GSM \u7684 IMEI\uff09\u3002\u5df2\u5e9f\u5f03\u3002

      getDeviceId()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

      "},{"location":"qsl4a/connectivity/phone/#getdevicesoftwareversion","title":"getDeviceSoftwareVersion()","text":"

      \u83b7\u53d6\u8bbe\u5907\u8f6f\u4ef6\u7248\u672c\u3002

      getDeviceSoftwareVersion()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8f6f\u4ef6\u7248\u672c

      "},{"location":"qsl4a/connectivity/phone/#getline1number","title":"getLine1Number()","text":"

      \u83b7\u53d6\u7ebf\u8def 1 \u7535\u8bdd\u53f7\u7801\u3002

      getLine1Number()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u7535\u8bdd\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#checknetworkroaming","title":"checkNetworkRoaming()","text":"

      \u68c0\u67e5\u662f\u5426\u8fde\u63a5\u5230\u6f2b\u6e38\u7f51\u7edc\u3002

      checkNetworkRoaming()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u6f2b\u6e38\u5219\u4e3a True

      "},{"location":"qsl4a/connectivity/phone/#_7","title":"\u57fa\u7ad9\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getallcellinfo","title":"getAllCellInfo()","text":"

      \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u7684\u4fe1\u606f\u3002

      getAllCellInfo()\n

      \u8fd4\u56de\uff1a \u57fa\u7ad9\u4fe1\u606f\u5217\u8868

      "},{"location":"qsl4a/connectivity/phone/#setdataenabled","title":"setDataEnabled()","text":"

      \u542f\u7528\u6216\u7981\u7528\u79fb\u52a8\u6570\u636e\u3002

      setDataEnabled(enabled)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528

      "},{"location":"qsl4a/connectivity/phone/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7f51\u7edc\u4fe1\u606f\noperator = droid.getNetworkOperatorName().result\nprint(f\"Operator: {operator}\")\n\nnetwork_type = droid.getNetworkType().result\nprint(f\"Network: {network_type}\")\n\n# \u83b7\u53d6 SIM \u4fe1\u606f\nsim_state = droid.getSimState().result\nprint(f\"SIM: {sim_state}\")\n\n# \u83b7\u53d6\u7535\u8bdd\u53f7\u7801\nline1 = droid.getLine1Number().result\nprint(f\"Phone: {line1}\")\n\n# \u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\ndroid.startTrackingPhoneState()\nprint(\"Tracking phone state...\")\ndroid.stopTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/signalstrength/","title":"\u4fe1\u53f7\u5f3a\u5ea6 API","text":"

      \u76d1\u63a7\u8702\u7a9d\u548c\u65e0\u7ebf\u4fe1\u53f7\u5f3a\u5ea6\u3002

      "},{"location":"qsl4a/connectivity/signalstrength/#_1","title":"\u4fe1\u53f7\u5f3a\u5ea6\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/signalstrength/#starttrackingsignalstrengths","title":"startTrackingSignalStrengths()","text":"

      \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316\u3002\u751f\u6210 'signal_strengths' \u4e8b\u4ef6\u3002

      startTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/signalstrength/#stoptrackingsignalstrengths","title":"stopTrackingSignalStrengths()","text":"

      \u505c\u6b62\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u3002

      stopTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/signalstrength/#readsignalstrengths","title":"readSignalStrengths()","text":"

      \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\u3002

      readSignalStrengths()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u4fe1\u53f7\u5f3a\u5ea6\u6570\u636e\u7684 Bundle

      "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthlevel","title":"getTelephoneSignalStrengthLevel()","text":"

      \u83b7\u53d6\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u7b49\u7ea7\uff080-4\uff09\u3002

      getTelephoneSignalStrengthLevel()\n

      \u8fd4\u56de\uff1a \u6574\u6570\u7b49\u7ea7\uff080=\u65e0\uff0c1=\u5dee\uff0c2=\u4e00\u822c\uff0c3=\u597d\uff0c4=\u4f18\u79c0\uff09

      "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthdetail","title":"getTelephoneSignalStrengthDetail()","text":"

      \u83b7\u53d6\u8be6\u7ec6\u7684\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u4fe1\u606f\u3002

      getTelephoneSignalStrengthDetail()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u8be6\u7ec6\u4fe1\u53f7\u4fe1\u606f\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/signalstrength/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\ndroid.startTrackingSignalStrengths()\n\n# \u7b49\u5f85\u4fe1\u53f7\u66f4\u65b0\ntime.sleep(5)\n\n# \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\nsignal = droid.readSignalStrengths().result\nprint(f\"Signal: {signal}\")\n\n# \u76f4\u63a5\u83b7\u53d6\u7b49\u7ea7\nlevel = droid.getTelephoneSignalStrengthLevel().result\nprint(f\"Signal level: {level}/4\")\n\ndroid.stopTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/sms/","title":"SMS API","text":"

      \u53d1\u9001\u548c\u63a5\u6536 SMS \u6d88\u606f\u3002

      "},{"location":"qsl4a/connectivity/sms/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/sms/#smssend","title":"smsSend()","text":"

      \u53d1\u9001 SMS \u6d88\u606f\u3002

      smsSend(destinationAddress, text)\n

      \u53c2\u6570\uff1a - destinationAddress (str): \u7535\u8bdd\u53f7\u7801 - text (str): \u6d88\u606f\u6587\u672c

      "},{"location":"qsl4a/connectivity/sms/#smsgetmessagecount","title":"smsGetMessageCount()","text":"

      \u83b7\u53d6\u6d88\u606f\u6570\u91cf\u3002

      smsGetMessageCount(unreadOnly=False, folder=\"inbox\")\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessageids","title":"smsGetMessageIds()","text":"

      \u83b7\u53d6\u6d88\u606f ID\u3002

      smsGetMessageIds(unreadOnly=False, folder=\"inbox\")\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessages","title":"smsGetMessages()","text":"

      \u83b7\u53d6\u6d88\u606f\u8be6\u60c5\u3002

      smsGetMessages(unreadOnly=False, folder=\"inbox\", attributes=None)\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessagebyid","title":"smsGetMessageById()","text":"

      \u901a\u8fc7 ID \u83b7\u53d6\u7279\u5b9a\u6d88\u606f\u3002

      smsGetMessageById(id, attributes=None)\n

      \u53c2\u6570\uff1a - id (int): \u6d88\u606f ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

      \u8fd4\u56de\uff1a \u6d88\u606f\u6570\u636e\u5b57\u5178

      "},{"location":"qsl4a/connectivity/sms/#smsgetattributes","title":"smsGetAttributes()","text":"

      \u83b7\u53d6\u53ef\u7528\u7684 SMS \u6d88\u606f\u5c5e\u6027\u3002

      smsGetAttributes()\n

      \u8fd4\u56de\uff1a \u53ef\u7528\u5c5e\u6027\u540d\u79f0\u5217\u8868

      "},{"location":"qsl4a/connectivity/sms/#smsdeletemessage","title":"smsDeleteMessage()","text":"

      \u5220\u9664\u6d88\u606f\u3002

      smsDeleteMessage(id)\n
      "},{"location":"qsl4a/connectivity/sms/#smsmarkmessageread","title":"smsMarkMessageRead()","text":"

      \u5c06\u6d88\u606f\u6807\u8bb0\u4e3a\u5df2\u8bfb\u3002

      smsMarkMessageRead(ids, read=True)\n
      "},{"location":"qsl4a/connectivity/sms/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u53d1\u9001 SMS\ndroid.smsSend(\"+1234567890\", \"Hello from QPython!\")\n\n# \u83b7\u53d6\u672a\u8bfb\u6d88\u606f\nmessages = droid.smsGetMessages(unreadOnly=True).result\nfor msg in messages:\n    print(f\"From: {msg['address']}, Text: {msg['body']}\")\n
      "},{"location":"qsl4a/connectivity/wifi/","title":"WiFi API","text":"

      \u63a7\u5236 WiFi \u9002\u914d\u5668\u5e76\u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\u3002

      "},{"location":"qsl4a/connectivity/wifi/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/connectivity/wifi/#checkwifistate","title":"checkWifiState()","text":"

      \u68c0\u67e5 WiFi \u662f\u5426\u5df2\u542f\u7528\u3002

      checkWifiState()\n

      \u8fd4\u56de\uff1a \u5982\u679c WiFi \u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/connectivity/wifi/#togglewifistate","title":"toggleWifiState()","text":"

      \u6253\u5f00\u6216\u5173\u95ed WiFi\u3002

      toggleWifiState(enabled=None)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

      \u8fd4\u56de\uff1a \u5982\u679c\u64cd\u4f5c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/connectivity/wifi/#wifistartscan","title":"wifiStartScan()","text":"

      \u5f00\u59cb\u626b\u63cf\u53ef\u7528\u7684 WiFi \u7f51\u7edc\u3002

      wifiStartScan()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifigetscanresults","title":"wifiGetScanResults()","text":"

      \u83b7\u53d6\u53d1\u73b0\u7684 WiFi \u7f51\u7edc\u5217\u8868\u3002

      wifiGetScanResults()\n

      \u8fd4\u56de\uff1a \u63a5\u5165\u70b9\u4fe1\u606f\u5217\u8868

      "},{"location":"qsl4a/connectivity/wifi/#_2","title":"\u8fde\u63a5\u7ba1\u7406","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetconnectioninfo","title":"wifiGetConnectionInfo()","text":"

      \u83b7\u53d6\u8be6\u7ec6\u8fde\u63a5\u4fe1\u606f\u3002

      wifiGetConnectionInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001IP \u5730\u5740\u7b49\u8fde\u63a5\u8be6\u60c5\u7684\u5b57\u5178

      "},{"location":"qsl4a/connectivity/wifi/#getconnectedinfo","title":"getConnectedInfo()","text":"

      \u83b7\u53d6\u8fde\u63a5\u7684 WiFi \u7f51\u7edc\u4fe1\u606f\uff08\u7b80\u5316\u7248\uff09\u3002

      getConnectedInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001\u4fe1\u53f7\u5f3a\u5ea6\u7684\u5b57\u5178

      "},{"location":"qsl4a/connectivity/wifi/#getdhcpinfo","title":"getDhcpInfo()","text":"

      \u83b7\u53d6\u5f53\u524d\u8fde\u63a5\u7684 DHCP \u4fe1\u606f\u3002

      getDhcpInfo(ipConvertToString=True)\n

      \u53c2\u6570\uff1a - ipConvertToString (bool): \u5c06 IP \u5730\u5740\u8f6c\u6362\u4e3a\u5b57\u7b26\u4e32\u683c\u5f0f\uff08\u9ed8\u8ba4\uff1aTrue\uff09

      \u8fd4\u56de\uff1a \u5305\u542b IP\u3001\u7f51\u5173\u3001DNS \u7b49 DHCP \u4fe1\u606f\u7684\u5b57\u5178

      "},{"location":"qsl4a/connectivity/wifi/#wifidisconnect","title":"wifiDisconnect()","text":"

      \u65ad\u5f00\u5f53\u524d WiFi \u7f51\u7edc\u8fde\u63a5\u3002

      wifiDisconnect()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifireconnect","title":"wifiReconnect()","text":"

      \u91cd\u65b0\u8fde\u63a5\u5230\u5f53\u524d\u7f51\u7edc\u3002

      wifiReconnect()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifireassociate","title":"wifiReassociate()","text":"

      \u91cd\u65b0\u5173\u8054\u5f53\u524d\u63a5\u5165\u70b9\u3002

      wifiReassociate()\n
      "},{"location":"qsl4a/connectivity/wifi/#_3","title":"\u70ed\u70b9","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetapstate","title":"wifiGetApState()","text":"

      \u83b7\u53d6 WiFi AP\uff08\u70ed\u70b9\uff09\u72b6\u6001\u3002

      wifiGetApState()\n

      \u8fd4\u56de\uff1a \u70ed\u70b9\u72b6\u6001

      "},{"location":"qsl4a/connectivity/wifi/#wifi","title":"WiFi \u9501","text":""},{"location":"qsl4a/connectivity/wifi/#wifilockacquirefull","title":"wifiLockAcquireFull()","text":"

      \u83b7\u53d6\u5b8c\u6574 WiFi \u9501\uff08\u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\u4e5f\u4fdd\u6301 WiFi \u6d3b\u52a8\uff09\u3002

      wifiLockAcquireFull()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifilockacquirescanonly","title":"wifiLockAcquireScanOnly()","text":"

      \u83b7\u53d6\u4ec5\u626b\u63cf WiFi \u9501\u3002

      wifiLockAcquireScanOnly()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifilockrelease","title":"wifiLockRelease()","text":"

      \u91ca\u653e WiFi \u9501\u3002

      wifiLockRelease()\n
      "},{"location":"qsl4a/connectivity/wifi/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u68c0\u67e5 WiFi \u72b6\u6001\nif droid.checkWifiState().result:\n    print(\"WiFi is enabled\")\nelse:\n    print(\"Enabling WiFi...\")\n    droid.toggleWifiState(True)\n    time.sleep(2)\n\n# \u5f00\u59cb\u626b\u63cf\ndroid.wifiStartScan()\ntime.sleep(3)\n\n# \u83b7\u53d6\u626b\u63cf\u7ed3\u679c\nnetworks = droid.wifiGetScanResults().result\nfor network in networks:\n    print(f\"SSID: {network.get('SSID')}, Signal: {network.get('level')} dBm\")\n\n# \u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\ninfo = droid.wifiGetConnectionInfo().result\nif info:\n    print(f\"Connected to: {info.get('ssid')}\")\n    print(f\"BSSID: {info.get('bssid')}\")\n    print(f\"IP: {info.get('ip_address')}\")\n\n# \u83b7\u53d6 DHCP \u4fe1\u606f\ndhcp = droid.getDhcpInfo().result\nif dhcp:\n    print(f\"Gateway: {dhcp.get('gateway')}\")\n    print(f\"DNS: {dhcp.get('dns1')}\")\n\n# \u83b7\u53d6\u7b80\u5316\u7684\u8fde\u63a5\u4fe1\u606f\nconnected = droid.getConnectedInfo().result\nprint(f\"SSID: {connected.get('ssid')}, Signal: {connected.get('level')} dBm\")\n\n# \u65ad\u5f00\u5e76\u91cd\u65b0\u8fde\u63a5\ndroid.wifiDisconnect()\ntime.sleep(1)\ndroid.wifiReconnect()\n\n# \u91cd\u65b0\u5173\u8054\u63a5\u5165\u70b9\ndroid.wifiReassociate()\n\n# \u68c0\u67e5\u70ed\u70b9\u72b6\u6001\nap_state = droid.wifiGetApState().result\nprint(f\"Hotspot state: {ap_state}\")\n\n# \u83b7\u53d6 WiFi \u9501\u4ee5\u8fdb\u884c\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireFull()\n# ... \u6267\u884c\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n\n# \u6216\u4f7f\u7528\u4ec5\u626b\u63cf\u9501\u4ee5\u8fdb\u884c\u8f83\u8f7b\u7684\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireScanOnly()\n# ... \u6267\u884c\u626b\u63cf\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n
      "},{"location":"qsl4a/core/android-base/","title":"Android \u57fa\u7840\u7c7b","text":"

      Android \u7c7b\u662f QSL4A \u7684\u6838\u5fc3\uff0c\u63d0\u4f9b\u4e86\u4e0e Android \u8fd0\u884c\u65f6\u7684\u8fde\u63a5\u548c RPC \u673a\u5236\u3002

      "},{"location":"qsl4a/core/android-base/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
      # \u529f\u80fd\u5b8c\u6574\u7248\u672c\uff08\u63a8\u8350\uff09\nimport androidhelper\ndroid = androidhelper.Android()\n\n# \u7b80\u5316\u7248\u672c\uff08\u5feb\u901f\uff0c\u5355\u5b9e\u4f8b\uff09\nimport android\ndroid = android.droid\n
      "},{"location":"qsl4a/core/android-base/#android_1","title":"\u7c7b\uff1aAndroid","text":""},{"location":"qsl4a/core/android-base/#_2","title":"\u6784\u9020\u51fd\u6570","text":"
      Android(addr=None)\n

      \u53c2\u6570\uff1a - addr (tuple, optional): (HOST, PORT) \u5730\u5740\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u73af\u5883\u53d8\u91cf AP_HOST \u548c AP_PORT

      \u73af\u5883\u53d8\u91cf\uff1a - AP_HOST - \u670d\u52a1\u5668\u4e3b\u673a\u5730\u5740 - AP_PORT - \u670d\u52a1\u5668\u7aef\u53e3 - AP_HANDSHAKE - \u8ba4\u8bc1\u4ee4\u724c

      "},{"location":"qsl4a/core/android-base/#_3","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/android-base/#_rpc","title":"_rpc()","text":"

      \u8c03\u7528 Android \u51fd\u6570\u7684\u5185\u90e8 RPC \u65b9\u6cd5\u3002

      _rpc(method, *args)\n

      \u53c2\u6570\uff1a - method (str): \u8981\u8c03\u7528\u7684\u65b9\u6cd5\u540d - *args: \u65b9\u6cd5\u7684\u53ef\u53d8\u53c2\u6570

      \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4\uff0c\u5305\u542b\u4ee5\u4e0b\u5b57\u6bb5\uff1a - id (int): \u8bf7\u6c42 ID - result: \u65b9\u6cd5\u8fd4\u56de\u503c - error (str or None): \u9519\u8bef\u4fe1\u606f\uff08\u5982\u679c\u5931\u8d25\uff09

      "},{"location":"qsl4a/core/android-base/#getattr","title":"getattr()","text":"

      \u52a8\u6001\u65b9\u6cd5\u5206\u53d1\u5668\u3002\u6240\u6709 Android \u65b9\u6cd5\u90fd\u901a\u8fc7\u5c5e\u6027\u67e5\u627e\u8bbf\u95ee\u3002

      # \u4ee5\u4e0b\u4e24\u79cd\u65b9\u5f0f\u7b49\u4ef7\uff1a\ndroid.makeToast(\"Hello\")\ndroid._rpc(\"makeToast\", \"Hello\")\n
      "},{"location":"qsl4a/core/android-base/#androidpy","title":"\u72ec\u7acb\u51fd\u6570\uff08android.py\uff09","text":"

      \u4f7f\u7528\u7b80\u5316\u7684 android \u6a21\u5757\u65f6\uff1a

      "},{"location":"qsl4a/core/android-base/#jsla","title":"jsla()","text":"

      \u53d1\u9001 JSON-RPC \u8bf7\u6c42\u5e76\u8fd4\u56de\u539f\u59cb\u54cd\u5e94\u3002

      jsla(method, *params)\n

      \u8fd4\u56de\uff1a JSON \u5b57\u7b26\u4e32\u54cd\u5e94

      "},{"location":"qsl4a/core/android-base/#rsla","title":"rsla()","text":"

      \u53d1\u9001\u8bf7\u6c42\u5e76\u4ec5\u8fd4\u56de\u7ed3\u679c\u3002

      rsla(method, *params)\n

      \u8fd4\u56de\uff1a RPC \u8c03\u7528\u7684\u7ed3\u679c\u503c

      "},{"location":"qsl4a/core/android-base/#esla","title":"esla()","text":"

      \u53d1\u9001\u8bf7\u6c42\uff0c\u9519\u8bef\u65f6\u629b\u51fa\u5f02\u5e38\u3002

      esla(method, *params)\n

      \u629b\u51fa\uff1a \u5982\u679c error \u5b57\u6bb5\u4e0d\u4e3a None \u5219\u629b\u51fa\u5f02\u5e38

      "},{"location":"qsl4a/core/android-base/#nsla","title":"nsla()","text":"

      \u53d1\u9001\u8bf7\u6c42\u5e76\u8fd4\u56de Result \u547d\u540d\u5143\u7ec4\u3002

      nsla(method, *params)\n

      \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4

      "},{"location":"qsl4a/core/android-base/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/android-base/#_5","title":"\u57fa\u672c\u8fde\u63a5","text":"
      import androidhelper\n\n# \u8fde\u63a5\u5230 Android \u8fd0\u884c\u65f6\ndroid = androidhelper.Android()\n\n# \u901a\u8fc7\u663e\u793a toast \u6765\u68c0\u67e5\u8fde\u63a5\ndroid.makeToast(\"Connected!\")\n
      "},{"location":"qsl4a/core/android-base/#_6","title":"\u9519\u8bef\u5904\u7406","text":"
      result = droid.someMethod()\nif result.error:\n    print(f\"Error: {result.error}\")\nelse:\n    print(f\"Success: {result.result}\")\n
      "},{"location":"qsl4a/core/android-base/#rpc","title":"\u76f4\u63a5 RPC \u8c03\u7528","text":"
      # \u76f4\u63a5\u8c03\u7528\u4efb\u610f\u65b9\u6cd5\nresult = droid._rpc(\"makeToast\", \"Hello World\")\n
      "},{"location":"qsl4a/core/events/","title":"\u4e8b\u4ef6\u7cfb\u7edf","text":"

      QSL4A \u63d0\u4f9b\u4e86\u4e00\u4e2a\u4e8b\u4ef6\u7cfb\u7edf\uff0c\u7528\u4e8e\u5904\u7406\u6765\u81ea Android \u7684\u5f02\u6b65\u4e8b\u4ef6\uff0c\u5982\u4f20\u611f\u5668\u66f4\u65b0\u3001\u4f4d\u7f6e\u53d8\u5316\u548c\u81ea\u5b9a\u4e49\u5e7f\u64ad\u3002

      "},{"location":"qsl4a/core/events/#_2","title":"\u4e8b\u4ef6\u57fa\u7840","text":"

      \u4e8b\u4ef6\u5b58\u50a8\u5728\u7f13\u51b2\u533a\u4e2d\uff0c\u53ef\u4ee5\u8f6e\u8be2\u6216\u7b49\u5f85\u3002\u6bcf\u4e2a\u4e8b\u4ef6\u5305\u542b\uff1a - name: \u4e8b\u4ef6\u7c7b\u578b/\u540d\u79f0 - data: \u4e8b\u4ef6\u8d1f\u8f7d\u6570\u636e - time: \u65f6\u95f4\u6233

      "},{"location":"qsl4a/core/events/#_3","title":"\u4e8b\u4ef6\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#eventclearbuffer","title":"eventClearBuffer()","text":"

      \u6e05\u9664\u7f13\u51b2\u533a\u4e2d\u7684\u6240\u6709\u5f85\u5904\u7406\u4e8b\u4ef6\u3002

      eventClearBuffer()\n

      \u8fd4\u56de\uff1a None

      "},{"location":"qsl4a/core/events/#eventpoll","title":"eventPoll()","text":"

      \u8f6e\u8be2\u7f13\u51b2\u533a\u4e2d\u7684\u4e8b\u4ef6\u3002

      eventPoll(number_of_events=1)\n

      \u53c2\u6570\uff1a - number_of_events (int): \u8981\u68c0\u7d22\u7684\u6700\u5927\u4e8b\u4ef6\u6570\uff08\u9ed8\u8ba4\uff1a1\uff09

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\u5217\u8868

      "},{"location":"qsl4a/core/events/#eventwait","title":"eventWait()","text":"

      \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\u3002

      eventWait(timeout=None)\n

      \u53c2\u6570\uff1a - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09\u3002None = \u6c38\u4e45\u7b49\u5f85

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

      "},{"location":"qsl4a/core/events/#eventwaitfor","title":"eventWaitFor()","text":"

      \u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6\u3002

      eventWaitFor(eventName, timeout=None)\n

      \u53c2\u6570\uff1a - eventName (str): \u8981\u7b49\u5f85\u7684\u4e8b\u4ef6\u540d\u79f0 - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

      "},{"location":"qsl4a/core/events/#eventpost","title":"eventPost()","text":"

      \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\u3002

      eventPost(name, data, enqueue=None)\n

      \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e\uff08\u4efb\u610f\u7c7b\u578b\uff09 - enqueue (bool, optional): \u5982\u679c\u4e3a True \u5219\u6dfb\u52a0\u5230\u961f\u5217

      "},{"location":"qsl4a/core/events/#receiveevent","title":"receiveEvent()","text":"

      \u63a5\u6536\u4e8b\u4ef6\uff08\u963b\u585e\uff09\u3002

      receiveEvent()\n

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61

      "},{"location":"qsl4a/core/events/#_4","title":"\u5e7f\u64ad\u4e8b\u4ef6","text":"

      \u6ce8\u518c\u7cfb\u7edf\u5e7f\u64ad\u4e8b\u4ef6\u3002

      "},{"location":"qsl4a/core/events/#eventregisterforbroadcast","title":"eventRegisterForBroadcast()","text":"

      \u6ce8\u518c\u63a5\u6536\u5e7f\u64ad\u4e8b\u4ef6\u3002

      eventRegisterForBroadcast(category, enqueue=True)\n

      \u53c2\u6570\uff1a - category (str): \u5e7f\u64ad\u7c7b\u522b/\u52a8\u4f5c - enqueue (bool): \u6dfb\u52a0\u5230\u4e8b\u4ef6\u961f\u5217

      "},{"location":"qsl4a/core/events/#eventunregisterforbroadcast","title":"eventUnregisterForBroadcast()","text":"

      \u53d6\u6d88\u6ce8\u518c\u5e7f\u64ad\u4e8b\u4ef6\u3002

      eventUnregisterForBroadcast(category)\n
      "},{"location":"qsl4a/core/events/#eventgetbrodcastcategories","title":"eventGetBrodcastCategories()","text":"

      \u83b7\u53d6\u5df2\u6ce8\u518c\u7684\u5e7f\u64ad\u7c7b\u522b\u3002

      eventGetBrodcastCategories()\n

      \u8fd4\u56de\uff1a \u5df2\u6ce8\u518c\u7c7b\u522b\u5217\u8868

      "},{"location":"qsl4a/core/events/#_5","title":"\u4e8b\u4ef6\u5206\u53d1\u5668)","text":""},{"location":"qsl4a/core/events/#starteventdispatcher","title":"startEventDispatcher()","text":"

      \u6253\u5f00\u4e00\u4e2a\u53ef\u4ee5\u8bfb\u53d6\u5df2\u53d1\u5e03\u4e8b\u4ef6\u7684\u5957\u63a5\u5b57\u3002)

      startEventDispatcher(port=0)\n

      \u53c2\u6570\uff1a - port (int, optional): \u76d1\u542c\u7684\u7aef\u53e3\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\u9009\u62e9\uff09

      \u8fd4\u56de\uff1a \u6b63\u5728\u76d1\u542c\u7684\u7aef\u53e3\u53f7

      "},{"location":"qsl4a/core/events/#stopeventdispatcher","title":"stopEventDispatcher()","text":"

      \u505c\u6b62\u4e8b\u4ef6\u670d\u52a1\u5668\u3002)

      stopEventDispatcher()\n
      "},{"location":"qsl4a/core/events/#_6","title":"\u5df2\u5e9f\u5f03\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#rpcpostevent","title":"rpcPostEvent()","text":"

      \u5c06\u4e8b\u4ef6\u53d1\u5e03\u5230\u4e8b\u4ef6\u961f\u5217\u3002\uff08\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 eventPost\uff09

      rpcPostEvent(name, data)\n

      \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e

      "},{"location":"qsl4a/core/events/#_7","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/events/#_8","title":"\u57fa\u672c\u4e8b\u4ef6\u8f6e\u8be2","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6e05\u9664\u65e7\u4e8b\u4ef6\ndroid.eventClearBuffer()\n\n# \u8f6e\u8be2\u4e8b\u4ef6\nevents = droid.eventPoll(5).result\nfor event in events:\n    print(f\"Event: {event['name']}, Data: {event['data']}\")\n
      "},{"location":"qsl4a/core/events/#_9","title":"\u7b49\u5f85\u4e8b\u4ef6","text":"
      # \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\uff0c\u5e26\u8d85\u65f6\nevent = droid.eventWait(timeout=10).result\nif event:\n    print(f\"Got event: {event['name']}\")\n
      "},{"location":"qsl4a/core/events/#_10","title":"\u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6","text":"
      # \u7b49\u5f85\u4f20\u611f\u5668\u4e8b\u4ef6\nevent = droid.eventWaitFor('screen', timeout=5).result\nif event:\n    print(f\"Screen event: {event['data']}\")\n
      "},{"location":"qsl4a/core/events/#_11","title":"\u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6","text":"
      # \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\ndroid.eventPost('my_event', {'key': 'value'})\n\n# \u7b49\u5f85\u5b83\nevent = droid.eventWaitFor('my_event', timeout=1).result\n
      "},{"location":"qsl4a/core/events/#_12","title":"\u5e7f\u64ad\u63a5\u6536\u5668","text":"
      # \u6ce8\u518c\u5c4f\u5e55\u5f00\u5173\u4e8b\u4ef6\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_ON')\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_OFF')\n\n# \u7b49\u5f85\u5c4f\u5e55\u4e8b\u4ef6\nwhile True:\n    event = droid.receiveEvent().result\n    if event['name'] == 'android.intent.action.SCREEN_ON':\n        print(\"Screen turned on\")\n    elif event['name'] == 'android.intent.action.SCREEN_OFF':\n        print(\"Screen turned off\")\n
      "},{"location":"qsl4a/core/events/#_13","title":"\u4f20\u611f\u5668\u4e8b\u4ef6\u5904\u7406","text":"
      # \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u5904\u7406\u4f20\u611f\u5668\u4e8b\u4ef6\nfor _ in range(100):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'sensors':\n        data = event['data']\n        print(f\"Accel: {data['xforce']}, {data['yforce']}, {data['zforce']}\")\n\ndroid.stopSensing()\n
      "},{"location":"qsl4a/core/events/#_14","title":"\u5e38\u89c1\u4e8b\u4ef6\u7c7b\u578b","text":"\u4e8b\u4ef6\u540d\u79f0 \u63cf\u8ff0 \u6765\u6e90 sensors \u4f20\u611f\u5668\u6570\u636e\u66f4\u65b0 startSensing* location GPS \u4f4d\u7f6e\u66f4\u65b0 startLocating phone \u7535\u8bdd\u72b6\u6001\u53d8\u5316 startTrackingPhoneState signal \u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316 startTrackingSignalStrength screen \u622a\u56fe\u5c31\u7eea fullGetScreenShot dialog \u5bf9\u8bdd\u6846\u54cd\u5e94 dialogShow*"},{"location":"qsl4a/core/events/#_15","title":"\u4e8b\u4ef6\u6570\u636e\u7ed3\u6784","text":"
      {\n    'name': 'event_name',\n    'data': {\n        # \u4e8b\u4ef6\u7279\u5b9a\u6570\u636e\n    },\n    'time': 1234567890  # \u65f6\u95f4\u6233\n}\n
      "},{"location":"qsl4a/core/intent/","title":"Intent \u7cfb\u7edf","text":"

      Android Intent \u7528\u4e8e\u542f\u52a8\u6d3b\u52a8\u3001\u53d1\u9001\u5e7f\u64ad\u548c\u5e94\u7528\u95f4\u901a\u4fe1\u3002QSL4A \u901a\u8fc7 Intent \u6a21\u5757\u63d0\u4f9b\u5b8c\u6574\u7684 Intent \u652f\u6301\u3002

      "},{"location":"qsl4a/core/intent/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
      import androidhelper\ndon = androidhelper.Android()\n
      "},{"location":"qsl4a/core/intent/#intent_1","title":"Intent \u5e38\u91cf","text":"

      \u901a\u8fc7 droid.Intent \u8bbf\u95ee\uff1a

      "},{"location":"qsl4a/core/intent/#_2","title":"\u64cd\u4f5c","text":"\u5e38\u91cf \u503c \u7528\u9014 ACTION_MAIN android.intent.action.MAIN \u5e94\u7528\u5165\u53e3\u70b9 ACTION_VIEW android.intent.action.VIEW \u67e5\u770b\u5185\u5bb9 ACTION_EDIT android.intent.action.EDIT \u7f16\u8f91\u5185\u5bb9 ACTION_PICK android.intent.action.PICK \u9009\u62e9\u9879\u76ee ACTION_SEND android.intent.action.SEND \u5206\u4eab\u5185\u5bb9 ACTION_SEARCH android.intent.action.SEARCH \u641c\u7d22"},{"location":"qsl4a/core/intent/#_3","title":"\u6807\u5fd7","text":"\u5e38\u91cf \u503c \u7528\u9014 FLAG_ACTIVITY_NEW_TASK 268435456 \u542f\u52a8\u65b0\u4efb\u52a1 FLAG_ACTIVITY_CLEAR_TASK 32768 \u6e05\u9664\u4efb\u52a1\u5806\u6808 FLAG_ACTIVITY_NEW_DOCUMENT 524288 \u65b0\u6587\u6863\u6a21\u5f0f"},{"location":"qsl4a/core/intent/#_4","title":"\u9644\u52a0\u6570\u636e","text":"\u5e38\u91cf \u7528\u9014 EXTRA_TEXT \u6587\u672c\u5185\u5bb9 EXTRA_STREAM \u6587\u4ef6 URI EXTRA_SUBJECT \u4e3b\u9898\u884c EXTRA_EMAIL \u7535\u5b50\u90ae\u4ef6\u5730\u5740"},{"location":"qsl4a/core/intent/#_5","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/intent/#makeintent","title":"makeIntent()","text":"

      \u521b\u5efa Intent \u5bf9\u8c61\u3002

      makeIntent(action, uri=None, type=None, extras=None, categories=None,\n           packagename=None, classname=None, flags=None)\n

      \u53c2\u6570\uff1a - action (str): Intent \u64cd\u4f5c\uff08\u4f8b\u5982 droid.Intent.ACTION_VIEW\uff09 - uri (str, optional): \u6570\u636e URI - type (str, optional): MIME \u7c7b\u578b - extras (dict, optional): \u9644\u52a0\u6570\u636e - categories (list, optional): Intent \u7c7b\u522b - packagename (str, optional): \u76ee\u6807\u5305 - classname (str, optional): \u76ee\u6807\u7c7b - flags (int, optional): Intent \u6807\u5fd7

      \u8fd4\u56de\uff1a Intent \u5bf9\u8c61

      "},{"location":"qsl4a/core/intent/#startactivityintent","title":"startActivityIntent()","text":"

      \u4f7f\u7528 Intent \u542f\u52a8 Activity\u3002

      startActivityIntent(intent, wait=None)\n

      \u53c2\u6570\uff1a - intent: makeIntent() \u8fd4\u56de\u7684 Intent \u5bf9\u8c61 - wait (bool, optional): \u963b\u585e\u76f4\u5230\u6d3b\u52a8\u5173\u95ed

      "},{"location":"qsl4a/core/intent/#startactivityforresultintent","title":"startActivityForResultIntent()","text":"

      \u542f\u52a8\u6d3b\u52a8\u5e76\u7b49\u5f85\u7ed3\u679c\u3002

      startActivityForResultIntent(intent)\n

      \u8fd4\u56de\uff1a Activity \u7ed3\u679c

      "},{"location":"qsl4a/core/intent/#sendbroadcastintent","title":"sendBroadcastIntent()","text":"

      \u53d1\u9001\u5e7f\u64ad\u3002

      sendBroadcastIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#view","title":"view()","text":"

      \u901a\u8fc7 URI \u67e5\u770b\u5185\u5bb9\u3002

      view(uri, type=None, extras=None)\n
      "},{"location":"qsl4a/core/intent/#pick","title":"pick()","text":"

      \u4ece URI \u9009\u62e9\u5185\u5bb9\u3002

      pick(uri)\n
      "},{"location":"qsl4a/core/intent/#intent_2","title":"\u5e38\u89c1 Intent \u65b9\u6cd5)","text":""},{"location":"qsl4a/core/intent/#scanbarcode","title":"scanBarcode()","text":"

      \u542f\u52a8\u6761\u7801\u626b\u63cf\u5668\u3002

      scanBarcode()\n

      \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/core/intent/#send","title":"send()","text":"

      \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u5185\u5bb9\u3002

      send(type, content)\n

      \u53c2\u6570\uff1a - type (str): MIME \u7c7b\u578b - content (str): \u8981\u5206\u4eab\u7684\u5185\u5bb9

      "},{"location":"qsl4a/core/intent/#sendtext","title":"sendText()","text":"

      \u53d1\u9001\u6587\u672c\u5185\u5bb9\u3002

      sendText(text)\n

      \u53c2\u6570\uff1a - text (str): \u8981\u53d1\u9001\u7684\u6587\u672c

      "},{"location":"qsl4a/core/intent/#sendemail","title":"sendEmail()","text":"

      \u53d1\u9001\u7535\u5b50\u90ae\u4ef6\u3002

      sendEmail(to, subject, body, attachment=None)\n

      \u53c2\u6570\uff1a - to (str or list): \u6536\u4ef6\u4eba\u7535\u5b50\u90ae\u4ef6\u5730\u5740 - subject (str): \u7535\u5b50\u90ae\u4ef6\u4e3b\u9898 - body (str): \u7535\u5b50\u90ae\u4ef6\u6b63\u6587 - attachment (str, optional): \u9644\u4ef6\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/core/intent/#pathtouri","title":"pathToUri()","text":"

      \u5c06\u6587\u4ef6\u8def\u5f84\u8f6c\u6362\u4e3a\u5185\u5bb9 URI\u3002

      pathToUri(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5185\u5bb9 URI \u5b57\u7b26\u4e32

      "},{"location":"qsl4a/core/intent/#openfile","title":"openFile()","text":"

      \u7528\u9002\u5f53\u7684\u5e94\u7528\u7a0b\u5e8f\u6253\u5f00\u6587\u4ef6\u3002

      openFile(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u6253\u5f00\u7684\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/core/intent/#sendfile","title":"sendFile()","text":"

      \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u6587\u4ef6\u3002

      sendFile(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u53d1\u9001\u7684\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/core/intent/#getpathtype","title":"getPathType()","text":"

      \u83b7\u53d6\u6587\u4ef6\u8def\u5f84\u7684 MIME \u7c7b\u578b\u3002

      getPathType(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a MIME \u7c7b\u578b\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/core/intent/#viewmap","title":"viewMap()","text":"

      \u5728\u6307\u5b9a\u4f4d\u7f6e\u6253\u5f00\u5730\u56fe\u3002

      viewMap(latitude, longitude)\n

      \u53c2\u6570\uff1a - latitude (float): \u7eac\u5ea6 - longitude (float): \u7ecf\u5ea6

      "},{"location":"qsl4a/core/intent/#viewcontacts","title":"viewContacts()","text":"

      \u6253\u5f00\u8054\u7cfb\u4eba\u5e94\u7528\u3002

      viewContacts()\n
      "},{"location":"qsl4a/core/intent/#search","title":"search()","text":"

      \u6267\u884c\u7f51\u7edc\u641c\u7d22\u3002

      search(query)\n

      \u53c2\u6570\uff1a - query (str): \u641c\u7d22\u67e5\u8be2

      "},{"location":"qsl4a/core/intent/#viewhtml","title":"viewHtml()","text":"

      \u67e5\u770b HTML \u5185\u5bb9\u3002

      viewHtml(content, encoding=None)\n

      \u53c2\u6570\uff1a - content (str): HTML \u5185\u5bb9 - encoding (str, optional): \u5b57\u7b26\u7f16\u7801

      "},{"location":"qsl4a/core/intent/#webviewshow","title":"webViewShow()","text":"

      \u5728 WebView \u4e2d\u663e\u793a\u7f51\u9875\u5185\u5bb9\u3002\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 viewHtml\u3002

      webViewShow(url)\n

      \u53c2\u6570\uff1a - url (str): \u7f51\u9875 URL

      "},{"location":"qsl4a/core/intent/#editoropen","title":"editorOpen()","text":"

      \u6253\u5f00\u6587\u672c\u7f16\u8f91\u5668\u3002

      editorOpen(path=None, create=False)\n

      \u53c2\u6570\uff1a - path (str, optional): \u8981\u7f16\u8f91\u7684\u6587\u4ef6\u8def\u5f84 - create (bool, optional): \u5982\u679c\u4e0d\u5b58\u5728\u5219\u521b\u5efa

      "},{"location":"qsl4a/core/intent/#uri","title":"\u8f85\u52a9\u7c7b\uff1aUri","text":"

      \u521b\u5efa Intent \u7684 URI \u5bf9\u8c61\uff1a

      from androidhelper.Intent import Uri\n\nuri = Uri(\"file:///sdcard/test.txt\")\n
      "},{"location":"qsl4a/core/intent/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/intent/#_7","title":"\u6253\u5f00\u7f51\u9875","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"http://www.example.com\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_8","title":"\u5206\u4eab\u6587\u672c","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_TEXT: \"Hello from QPython!\",\n        droid.Intent.EXTRA_SUBJECT: \"Test\"\n    },\n    type=\"text/plain\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_9","title":"\u6253\u5f00\u6587\u4ef6","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"file:///sdcard/document.pdf\",\n    type=\"application/pdf\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_10","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":"
      result = droid.pickContact()\ncontact_uri = result.result\n
      "},{"location":"qsl4a/core/intent/#_11","title":"\u53d1\u9001\u7535\u5b50\u90ae\u4ef6","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_EMAIL: [\"test@example.com\"],\n        droid.Intent.EXTRA_SUBJECT: \"Hello\",\n        droid.Intent.EXTRA_TEXT: \"Message body\"\n    },\n    type=\"message/rfc822\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_12","title":"\u6253\u5f00\u5e94\u7528","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_MAIN,\n    packagename=\"com.android.settings\",\n    classname=\"com.android.settings.Settings\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/hardware/bluetooth/","title":"\u84dd\u7259 API","text":"

      \u63a7\u5236\u84dd\u7259\u9002\u914d\u5668\u5e76\u4e0e\u84dd\u7259\u8bbe\u5907\u901a\u4fe1\u3002

      "},{"location":"qsl4a/hardware/bluetooth/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/hardware/bluetooth/#togglebluetoothstate","title":"toggleBluetoothState()","text":"

      \u6253\u5f00/\u5173\u95ed\u84dd\u7259\u3002

      toggleBluetoothState(enabled=None, prompt=True)\n

      \u53c2\u6570\uff1a - enabled (bool): True=\u5f00\uff0cFalse=\u5173\uff0cNone=\u5207\u6362 - prompt (bool): \u663e\u793a\u7528\u6237\u63d0\u793a

      "},{"location":"qsl4a/hardware/bluetooth/#checkbluetoothstate","title":"checkBluetoothState()","text":"

      \u68c0\u67e5\u84dd\u7259\u662f\u5426\u5df2\u542f\u7528\u3002

      checkBluetoothState()\n

      \u8fd4\u56de\uff1a True/False

      "},{"location":"qsl4a/hardware/bluetooth/#getlocalname","title":"GetLocalName()","text":"

      \u83b7\u53d6\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

      GetLocalName()\n
      "},{"location":"qsl4a/hardware/bluetooth/#setlocalname","title":"SetLocalName()","text":"

      \u8bbe\u7f6e\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

      SetLocalName(name)\n
      "},{"location":"qsl4a/hardware/bluetooth/#getscanmode","title":"GetScanMode()","text":"

      \u83b7\u53d6\u53ef\u53d1\u73b0\u6027\u6a21\u5f0f\u3002

      GetScanMode()\n

      \u8fd4\u56de\uff1a - -1: \u5df2\u7981\u7528 - 0: \u4e0d\u53ef\u53d1\u73b0\uff0c\u4e0d\u53ef\u8fde\u63a5 - 1: \u53ef\u8fde\u63a5\uff0c\u4e0d\u53ef\u53d1\u73b0 - 3: \u53ef\u8fde\u63a5\u4e14\u53ef\u53d1\u73b0

      "},{"location":"qsl4a/hardware/bluetooth/#makediscoverable","title":"MakeDiscoverable()","text":"

      \u4f7f\u8bbe\u5907\u53ef\u53d1\u73b0\u3002

      MakeDiscoverable(duration=300)\n

      \u53c2\u6570\uff1a - duration (int): \u53ef\u53d1\u73b0\u7684\u79d2\u6570

      "},{"location":"qsl4a/hardware/bluetooth/#_2","title":"\u53d1\u73b0","text":""},{"location":"qsl4a/hardware/bluetooth/#discoverystart","title":"DiscoveryStart()","text":"

      \u5f00\u59cb\u8bbe\u5907\u53d1\u73b0\u3002

      DiscoveryStart()\n
      "},{"location":"qsl4a/hardware/bluetooth/#discoverycancel","title":"DiscoveryCancel()","text":"

      \u53d6\u6d88\u53d1\u73b0\u3002

      DiscoveryCancel()\n
      "},{"location":"qsl4a/hardware/bluetooth/#getreceiveddevices","title":"GetReceivedDevices()","text":"

      \u83b7\u53d6\u53d1\u73b0\u7684\u8bbe\u5907\u3002

      GetReceivedDevices()\n

      \u8fd4\u56de\uff1a \u8bbe\u5907\u4fe1\u606f\u5b57\u5178\u5217\u8868

      "},{"location":"qsl4a/hardware/bluetooth/#getbondeddevices","title":"GetBondedDevices()","text":"

      \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\u3002

      GetBondedDevices()\n

      \u8fd4\u56de\uff1a \u914d\u5bf9\u8bbe\u5907\u4fe1\u606f\u5217\u8868

      "},{"location":"qsl4a/hardware/bluetooth/#_3","title":"\u8fde\u63a5","text":""},{"location":"qsl4a/hardware/bluetooth/#connect","title":"Connect()","text":"

      \u8fde\u63a5\u5230\u8bbe\u5907\u3002

      Connect(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", address=None)\n

      \u53c2\u6570\uff1a - uuid (str): \u670d\u52a1 UUID - address (str): \u8bbe\u5907\u5730\u5740\uff08None = \u663e\u793a\u9009\u62e9\u5668\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/hardware/bluetooth/#accept","title":"Accept()","text":"

      \u63a5\u53d7\u4f20\u5165\u8fde\u63a5\u3002

      Accept(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", timeout=0)\n
      "},{"location":"qsl4a/hardware/bluetooth/#activeconnections","title":"ActiveConnections()","text":"

      \u68c0\u67e5\u6d3b\u52a8\u8fde\u63a5\u3002

      ActiveConnections()\n
      "},{"location":"qsl4a/hardware/bluetooth/#stop","title":"Stop()","text":"

      \u65ad\u5f00\u8fde\u63a5\u3002

      Stop(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#_4","title":"\u901a\u4fe1","text":""},{"location":"qsl4a/hardware/bluetooth/#write","title":"Write()","text":"

      \u53d1\u9001 ASCII \u6570\u636e\u3002

      Write(ascii, connID=\"\")\n
      "},{"location":"qsl4a/hardware/bluetooth/#writebinary","title":"WriteBinary()","text":"

      \u53d1\u9001\u4e8c\u8fdb\u5236\u6570\u636e\uff08base64 \u7f16\u7801\uff09\u3002

      WriteBinary(base64, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#read","title":"Read()","text":"

      \u8bfb\u53d6 ASCII \u6570\u636e\u3002

      Read(bufferSize=4096, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readbinary","title":"ReadBinary()","text":"

      \u8bfb\u53d6\u4e8c\u8fdb\u5236\u6570\u636e\u3002

      ReadBinary(bufferSize=4096, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readline","title":"ReadLine()","text":"

      \u8bfb\u53d6\u4e00\u884c\u3002

      ReadLine(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readready","title":"ReadReady()","text":"

      \u68c0\u67e5\u662f\u5426\u6709\u53ef\u7528\u6570\u636e\u3002

      ReadReady(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u7528\u84dd\u7259\ndroid.toggleBluetoothState(True)\n\n# \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\ndevices = droid.GetBondedDevices().result\nfor dev in devices:\n    print(f\"{dev['name']}: {dev['address']}\")\n\n# \u8fde\u63a5\u5230\u8bbe\u5907\ndroid.Connect(address=\"00:11:22:33:44:55\")\n\n# \u53d1\u9001\u6570\u636e\ndroid.Write(\"Hello Bluetooth!\")\n\n# \u8bfb\u53d6\u54cd\u5e94\ndata = droid.Read(1024).result\n
      "},{"location":"qsl4a/hardware/camera/","title":"\u76f8\u673a API","text":"

      \u62cd\u6444\u7167\u7247\u548c\u5f55\u5236\u89c6\u9891\u3002

      "},{"location":"qsl4a/hardware/camera/#_1","title":"\u7167\u7247\u62cd\u6444","text":""},{"location":"qsl4a/hardware/camera/#takepicture","title":"takePicture()","text":"

      \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u6444\u7167\u7247\u3002

      takePicture(path=None)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8fd4\u56de\u56fe\u50cf\u6570\u636e

      \u8fd4\u56de\uff1a \u56fe\u50cf\u8def\u5f84\u6216\u56fe\u50cf\u6570\u636e

      "},{"location":"qsl4a/hardware/camera/#cameracapturepicture","title":"cameraCapturePicture()","text":"

      \u4f7f\u7528\u9ad8\u7ea7\u76f8\u673a\u63a7\u5236\u62cd\u6444\u7167\u7247\u3002

      cameraCapturePicture(targetPath=None, cameraId=0, useAutoFocus=True)\n

      \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - useAutoFocus (bool): \u542f\u7528\u81ea\u52a8\u5bf9\u7126

      \u8fd4\u56de\uff1a \u62cd\u6444\u7684\u56fe\u50cf\u8def\u5f84

      "},{"location":"qsl4a/hardware/camera/#camerasettorchmode","title":"cameraSetTorchMode()","text":"

      \u63a7\u5236\u76f8\u673a\u95ea\u5149\u706f/\u624b\u7535\u7b52\u3002

      cameraSetTorchMode(enabled)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u6253\u5f00\uff0cFalse \u5173\u95ed

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/hardware/camera/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

      \u622a\u56fe\u3002

      imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

      "},{"location":"qsl4a/hardware/camera/#_2","title":"\u89c6\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#takevideo","title":"takeVideo()","text":"

      \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\u3002

      takeVideo(path=None, quality=1)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-4\uff09 - 0: 160x120 - 1: 320x240 - 2: 352x288 - 3: 640x480 - 4: 800x480

      "},{"location":"qsl4a/hardware/camera/#recordercapturevideo","title":"recorderCaptureVideo()","text":"

      \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\u3002

      recorderCaptureVideo(targetPath=None, duration=10, cameraId=0, quality=8)\n

      \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - duration (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a10\uff09 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-8\uff0c\u8d8a\u9ad8\u8d8a\u597d\uff09

      \u8fd4\u56de\uff1a \u89c6\u9891\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/hardware/camera/#recordaudio","title":"recordAudio()","text":"

      \u5f55\u5236\u97f3\u9891\u3002

      recordAudio()\n

      \u8fd4\u56de\uff1a \u97f3\u9891\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/hardware/camera/#_3","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

      \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\u3002

      recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

      \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\uff09 - targetPixels (int): \u5206\u8fa8\u7387 - frameRate (int): FPS - bitRate (int): \u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa - autoStart (bool): \u7acb\u5373\u5f00\u59cb

      "},{"location":"qsl4a/hardware/camera/#recorderstart","title":"recorderStart()","text":"

      \u5f00\u59cb\u5f55\u5236\u3002

      recorderStart()\n
      "},{"location":"qsl4a/hardware/camera/#recorderpause","title":"recorderPause()","text":"

      \u6682\u505c\u5f55\u5236\u3002

      recorderPause()\n
      "},{"location":"qsl4a/hardware/camera/#recorderresume","title":"recorderResume()","text":"

      \u6062\u590d\u5f55\u5236\u3002

      recorderResume()\n
      "},{"location":"qsl4a/hardware/camera/#_4","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/camera/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

      \u5f00\u59cb\u97f3\u91cf\u68c0\u6d4b\u3002

      recorderSoundVolumeDetect(interval=100)\n
      "},{"location":"qsl4a/hardware/camera/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

      \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

      recorderSoundVolumeGetDb()\n
      "},{"location":"qsl4a/hardware/camera/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u7167\nphoto_path = droid.takePicture(\"/sdcard/photo.jpg\").result\nprint(f\"Photo saved: {photo_path}\")\n\n# \u4f7f\u7528\u524d\u7f6e\u76f8\u673a\u548c\u81ea\u52a8\u5bf9\u7126\u62cd\u7167\ncamera_path = droid.cameraCapturePicture(\"/sdcard/selfie.jpg\", cameraId=1, useAutoFocus=True).result\nprint(f\"Front camera photo: {camera_path}\")\n\n# \u63a7\u5236\u95ea\u5149\u706f\ndroid.cameraSetTorchMode(True)  # \u6253\u5f00\u95ea\u5149\u706f\n\n# \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\nvideo_path = droid.takeVideo(\"/sdcard/video.mp4\", quality=3).result\nprint(f\"Video saved: {video_path}\")\n\n# \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\nvideo_path = droid.recorderCaptureVideo(\"/sdcard/movie.mp4\", duration=30, cameraId=0, quality=8).result\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n
      "},{"location":"qsl4a/hardware/recorder/","title":"\u97f3\u9891\u5f55\u5236 API","text":"

      \u4ece\u9ea6\u514b\u98ce\u548c\u8bbe\u5907\u5c4f\u5e55\u5f55\u5236\u97f3\u9891\u3002

      "},{"location":"qsl4a/hardware/recorder/#_1","title":"\u97f3\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recordaudio","title":"recordAudio()","text":"

      \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\u3002

      recordAudio()\n

      \u8fd4\u56de\uff1a \u5f55\u5236\u7684\u97f3\u9891\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/hardware/recorder/#recorderstartmicrophone","title":"recorderStartMicrophone()","text":"

      \u5f00\u59cb\u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\u3002

      recorderStartMicrophone(targetPath=None)\n

      \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u5f55\u5236\u7684\u8def\u5f84

      "},{"location":"qsl4a/hardware/recorder/#_2","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

      \u5f00\u59cb\u5e26\u97f3\u9891\u7684\u5c4f\u5e55\u5f55\u5236\u3002

      recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

      \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\u97f3\u9891\uff09 - targetPixels (int): \u76ee\u6807\u5206\u8fa8\u7387\uff08\u50cf\u7d20\uff09 - frameRate (int): \u6bcf\u79d2\u5e27\u6570\uff08\u9ed8\u8ba4\uff1a30\uff09 - bitRate (int): \u89c6\u9891\u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa\u89c6\u9891 - autoStart (bool): \u7acb\u5373\u5f00\u59cb\u5f55\u5236

      \u8fd4\u56de\uff1a \u64cd\u4f5c\u7ed3\u679c

      "},{"location":"qsl4a/hardware/recorder/#recorderstart","title":"recorderStart()","text":"

      \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\uff08\u5f53 autoStart=False \u65f6\uff09\u3002

      recorderStart()\n
      "},{"location":"qsl4a/hardware/recorder/#recorderpause","title":"recorderPause()","text":"

      \u6682\u505c\u6b63\u5728\u8fdb\u884c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

      recorderPause()\n
      "},{"location":"qsl4a/hardware/recorder/#recorderresume","title":"recorderResume()","text":"

      \u6062\u590d\u6682\u505c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

      recorderResume()\n
      "},{"location":"qsl4a/hardware/recorder/#_3","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/recorder/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

      \u5f00\u59cb\u76d1\u63a7\u97f3\u91cf\u7ea7\u522b\u3002

      recorderSoundVolumeDetect(interval=100)\n

      \u53c2\u6570\uff1a - interval (int): \u68c0\u6d4b\u95f4\u9694\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a100\uff09

      "},{"location":"qsl4a/hardware/recorder/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

      \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

      recorderSoundVolumeGetDb()\n

      \u8fd4\u56de\uff1a \u5f53\u524d\u97f3\u91cf\u7ea7\u522b\uff08dB\uff09

      "},{"location":"qsl4a/hardware/recorder/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\nprint(\"Recording audio...\")\naudio_path = droid.recordAudio().result\nprint(f\"Saved to: {audio_path}\")\n\n# \u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\ndroid.recorderStartMicrophone(\"/sdcard/my_recording.mp3\")\ntime.sleep(5)\ndroid.recorderStop()\n\n# \u5e26\u97f3\u9891\u5f55\u5236\u5c4f\u5e55\nprint(\"Starting screen recording...\")\ndroid.recorderStartScreenRecord(\n    path=\"/sdcard/screen_record.mp4\",\n    audio=1,\n    frameRate=30,\n    autoStart=True\n)\ntime.sleep(10)\ndroid.recorderStop()\n\n# \u76d1\u63a7\u97f3\u91cf\ndroid.recorderSoundVolumeDetect(interval=100)\ntime.sleep(3)\nvolume = droid.recorderSoundVolumeGetDb().result\nprint(f\"Current volume: {volume} dB\")\n
      "},{"location":"qsl4a/hardware/usbserial/","title":"USB \u4e3b\u673a\u4e32\u884c API","text":"

      \u4e0e USB \u4e32\u884c\u8bbe\u5907\u901a\u4fe1\uff08\u9700\u8981 USB OTG \u652f\u6301\u548c Android 3.1+\uff09\u3002

      "},{"location":"qsl4a/hardware/usbserial/#usb","title":"USB \u4e32\u884c\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialopen","title":"usbHostSerialOpen()","text":"

      \u6253\u5f00\u4e0e USB \u4e32\u884c\u8bbe\u5907\u7684\u8fde\u63a5\u3002

      usbHostSerialOpen(device, baudRate=9600)\n

      \u53c2\u6570\uff1a - device (str): USB \u8bbe\u5907\u8def\u5f84\u6216\u6807\u8bc6\u7b26 - baudRate (int): \u6ce2\u7279\u7387\uff08\u9ed8\u8ba4\uff1a9600\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u6253\u5f00\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialclose","title":"usbHostSerialClose()","text":"

      \u5173\u95ed USB \u4e32\u884c\u8fde\u63a5\u3002

      usbHostSerialClose()\n
      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialread","title":"usbHostSerialRead()","text":"

      \u4ece USB \u4e32\u884c\u8bfb\u53d6\u6570\u636e\u3002

      usbHostSerialRead(bufferSize=1024)\n

      \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570\uff08\u9ed8\u8ba4\uff1a1024\uff09

      \u8fd4\u56de\uff1a \u8bfb\u53d6\u7684\u6570\u636e\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwrite","title":"usbHostSerialWrite()","text":"

      \u5411 USB \u4e32\u884c\u5199\u5165\u6570\u636e\u3002

      usbHostSerialWrite(data)\n

      \u53c2\u6570\uff1a - data (str): \u8981\u5199\u5165\u7684\u5b57\u7b26\u4e32\u6570\u636e

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialavailable","title":"usbHostSerialAvailable()","text":"

      \u68c0\u67e5\u662f\u5426\u6709\u53ef\u8bfb\u53d6\u7684\u6570\u636e\u3002

      usbHostSerialAvailable()\n

      \u8fd4\u56de\uff1a \u53ef\u7528\u5b57\u8282\u6570

      "},{"location":"qsl4a/hardware/usbserial/#_1","title":"\u914d\u7f6e\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetbaudrate","title":"usbHostSerialSetBaudRate()","text":"

      \u8bbe\u7f6e\u6ce2\u7279\u7387\u3002

      usbHostSerialSetBaudRate(baudRate)\n

      \u53c2\u6570\uff1a - baudRate (int): \u6ce2\u7279\u7387

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetdatabits","title":"usbHostSerialSetDataBits()","text":"

      \u8bbe\u7f6e\u6570\u636e\u4f4d\uff085\u30016\u30017 \u6216 8\uff09\u3002

      usbHostSerialSetDataBits(dataBits)\n

      \u53c2\u6570\uff1a - dataBits (int): \u6570\u636e\u4f4d\uff085-8\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetstopbits","title":"usbHostSerialSetStopBits()","text":"

      \u8bbe\u7f6e\u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09\u3002

      usbHostSerialSetStopBits(stopBits)\n

      \u53c2\u6570\uff1a - stopBits (float): \u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetparity","title":"usbHostSerialSetParity()","text":"

      \u8bbe\u7f6e\u6821\u9a8c\u4f4d\uff08\u65e0\u3001\u5947\u3001\u5076\u3001\u6807\u8bb0\u3001\u7a7a\u683c\uff09\u3002

      usbHostSerialSetParity(parity)\n

      \u53c2\u6570\uff1a - parity (str): \u6821\u9a8c\u6a21\u5f0f\uff08'none'\u3001'odd'\u3001'even'\u3001'mark'\u3001'space'\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetflowcontrol","title":"usbHostSerialSetFlowControl()","text":"

      \u8bbe\u7f6e\u6d41\u63a7\u5236\uff08\u65e0\u3001\u786c\u4ef6\u3001\u8f6f\u4ef6\uff09\u3002

      usbHostSerialSetFlowControl(flowControl)\n

      \u53c2\u6570\uff1a - flowControl (str): \u6d41\u63a7\u5236\u6a21\u5f0f\uff08'none'\u3001'hardware'\u3001'software'\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialreadhex","title":"usbHostSerialReadHex()","text":"

      \u4ee5\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u8bfb\u53d6\u6570\u636e\u3002

      usbHostSerialReadHex(bufferSize=1024)\n

      \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570

      \u8fd4\u56de\uff1a \u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwritehex","title":"usbHostSerialWriteHex()","text":"

      \u4ece\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u5199\u5165\u6570\u636e\u3002

      usbHostSerialWriteHex(hexString)\n

      \u53c2\u6570\uff1a - hexString (str): \u8981\u5199\u5165\u7684\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/hardware/usbserial/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6253\u5f00 USB \u4e32\u884c\u8fde\u63a5\nif droid.usbHostSerialOpen(\"/dev/bus/usb/001/001\", 115200).result:\n    print(\"USB serial opened\")\n\n    # \u5199\u5165\u6570\u636e\n    droid.usbHostSerialWrite(\"AT\\r\")\n\n    # \u8bfb\u53d6\u54cd\u5e94\n    response = droid.usbHostSerialRead(1024).result\n    print(f\"Response: {response}\")\n\n    # \u6216\u4f7f\u7528\u5341\u516d\u8fdb\u5236\n    droid.usbHostSerialWriteHex(\"41540D0A\")  # \"AT\\r\\n\"\n\n    # \u5173\u95ed\u8fde\u63a5\n    droid.usbHostSerialClose()\n

      \u6ce8\u610f\uff1a USB \u4e32\u884c\u9700\u8981\uff1a - Android 3.1+ (API 12) - USB OTG \u7ebf/\u9002\u914d\u5668 - \u8bbe\u5907\u4e0a\u7684 USB \u4e3b\u673a\u6a21\u5f0f\u652f\u6301 - \u517c\u5bb9\u7684\u4e32\u884c\u8bbe\u5907

      "},{"location":"qsl4a/hardware/webcam/","title":"\u7f51\u7edc\u6444\u50cf\u5934 API","text":"

      \u4f7f\u7528 MJPEG \u4ece\u8bbe\u5907\u76f8\u673a\u6d41\u5f0f\u4f20\u8f93\u89c6\u9891\u3002

      "},{"location":"qsl4a/hardware/webcam/#mjpeg","title":"MJPEG \u6d41\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#webcamstart","title":"webcamStart()","text":"

      \u4ece\u7f51\u7edc\u6444\u50cf\u5934\u542f\u52a8 MJPEG \u6d41\u3002

      webcamStart(resolutionLevel=0, jpegQuality=20, port=0)\n

      \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf 1-100\uff08\u9ed8\u8ba4\uff1a20\uff09 - port (int): \u7aef\u53e3\u53f7\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\uff09

      \u8fd4\u56de\uff1a \u6d41\u7684 (\u5730\u5740, \u7aef\u53e3) \u5143\u7ec4

      "},{"location":"qsl4a/hardware/webcam/#webcamadjustquality","title":"webcamAdjustQuality()","text":"

      \u8c03\u6574\u6d3b\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u7684\u8d28\u91cf\u3002

      webcamAdjustQuality(resolutionLevel=0, jpegQuality=20)\n

      \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b - jpegQuality (int): JPEG \u8d28\u91cf 1-100

      "},{"location":"qsl4a/hardware/webcam/#webcamstop","title":"webcamStop()","text":"

      \u505c\u6b62\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u3002

      webcamStop()\n
      "},{"location":"qsl4a/hardware/webcam/#_1","title":"\u76f8\u673a\u9884\u89c8\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#camerastartpreview","title":"cameraStartPreview()","text":"

      \u5f00\u59cb\u5e26\u4e8b\u4ef6\u751f\u6210\u7684\u76f8\u673a\u9884\u89c8\u6a21\u5f0f\u3002

      cameraStartPreview(resolutionLevel=0, jpegQuality=20, filepath=None)\n

      \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf\uff08\u9ed8\u8ba4\uff1a20\uff09 - filepath (str, optional): \u4fdd\u5b58\u9884\u89c8\u5e27\u7684\u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      \u6ce8\u610f\uff1a \u751f\u6210\u5e26\u6709\u5e27\u6570\u636e\u7684 'preview' \u4e8b\u4ef6\u3002

      "},{"location":"qsl4a/hardware/webcam/#camerastoppreview","title":"cameraStopPreview()","text":"

      \u505c\u6b62\u76f8\u673a\u9884\u89c8\u3002

      cameraStopPreview()\n
      "},{"location":"qsl4a/hardware/webcam/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\nstream_info = droid.webcamStart(\n    resolutionLevel=0,\n    jpegQuality=30,\n    port=8080\n).result\nprint(f\"Stream available at {stream_info[0]}:{stream_info[1]}\")\n\n# \u6d41\u5f0f\u4f20\u8f93\u65f6\u8c03\u6574\u8d28\u91cf\ntime.sleep(5)\ndroid.webcamAdjustQuality(resolutionLevel=1, jpegQuality=50)\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.webcamStop()\n\n# \u6216\u4f7f\u7528\u9884\u89c8\u6a21\u5f0f\nprint(\"Starting preview...\")\ndroid.cameraStartPreview()\n\n# \u7b49\u5f85\u9884\u89c8\u4e8b\u4ef6\nfor i in range(10):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'preview':\n        print(f\"Got preview frame: {event['data']}\")\n\ndroid.cameraStopPreview()\n
      "},{"location":"qsl4a/media/image/","title":"\u56fe\u50cf\u5904\u7406 API","text":"

      \u538b\u7f29\u548c\u5904\u7406\u56fe\u50cf\u3002

      "},{"location":"qsl4a/media/image/#_1","title":"\u56fe\u50cf\u538b\u7f29","text":""},{"location":"qsl4a/media/image/#imagecompress","title":"imageCompress()","text":"

      \u538b\u7f29\u56fe\u50cf\u6587\u4ef6\u3002

      imageCompress(srcPath, destPath, targetByteSize=0, targetWidth=0, targetHeight=0)\n

      \u53c2\u6570\uff1a - srcPath (str): \u6e90\u56fe\u50cf\u8def\u5f84 - destPath (str): \u8f93\u51fa\u8def\u5f84 - targetByteSize (int): \u76ee\u6807\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff080 = \u65e0\u9650\u5236\uff09 - targetWidth (int): \u76ee\u6807\u5bbd\u5ea6\uff080 = \u539f\u59cb\uff09 - targetHeight (int): \u76ee\u6807\u9ad8\u5ea6\uff080 = \u539f\u59cb\uff09

      \u8fd4\u56de\uff1a \u538b\u7f29\u540e\u7684\u56fe\u50cf\u8def\u5f84

      "},{"location":"qsl4a/media/image/#_2","title":"\u622a\u56fe","text":""},{"location":"qsl4a/media/image/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

      \u622a\u53d6\u5c4f\u5e55\u3002

      imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

      \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

      \u8fd4\u56de\uff1a \u622a\u56fe\u8def\u5f84

      "},{"location":"qsl4a/media/image/#_3","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/image/#videoplay","title":"videoPlay()","text":"

      \u5728\u5168\u5c4f\u6a21\u5f0f\u4e0b\u64ad\u653e\u89c6\u9891\u6587\u4ef6\u3002

      videoPlay(path, wait=True)\n

      \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

      "},{"location":"qsl4a/media/image/#_4","title":"\u6761\u7801\u626b\u63cf","text":""},{"location":"qsl4a/media/image/#scanbarcodefromimage","title":"scanBarcodeFromImage()","text":"

      \u4ece\u56fe\u50cf\u6587\u4ef6\u626b\u63cf\u6761\u7801/\u4e8c\u7ef4\u7801\u3002

      scanBarcodeFromImage(path, compressRatio=0, x=0, y=0, width=0, height=0)\n

      \u53c2\u6570\uff1a - path (str): \u56fe\u50cf\u6587\u4ef6\u8def\u5f84 - compressRatio (int): \u538b\u7f29\u6bd4\uff080 = \u4e0d\u538b\u7f29\uff09 - x, y, width, height (int): \u8981\u626b\u63cf\u7684\u533a\u57df\uff080 = \u5b8c\u6574\u56fe\u50cf\uff09

      \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5185\u5bb9

      "},{"location":"qsl4a/media/image/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n\n# \u538b\u7f29\u56fe\u50cf\ncompressed = droid.imageCompress(\n    \"/sdcard/large_photo.jpg\",\n    \"/sdcard/compressed.jpg\",\n    targetByteSize=102400,  # \u76ee\u6807\u7ea6 100KB\n    targetWidth=1920,\n    targetHeight=1080\n).result\nprint(f\"Saved: {compressed}\")\n\n# \u64ad\u653e\u89c6\u9891\nvideo_path = \"/sdcard/movie.mp4\"\ndroid.videoPlay(video_path, wait=True)\n\n# \u4ece\u56fe\u50cf\u626b\u63cf\u6761\u7801\nresult = droid.scanBarcodeFromImage(\"/sdcard/qr_code.png\").result\nprint(f\"Barcode: {result}\")\n
      "},{"location":"qsl4a/media/mediaplayer/","title":"\u5a92\u4f53\u64ad\u653e\u5668 API","text":"

      \u63a7\u5236\u97f3\u9891\u548c\u89c6\u9891\u64ad\u653e\u3002

      "},{"location":"qsl4a/media/mediaplayer/#_1","title":"\u64ad\u653e\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplay","title":"mediaPlay()","text":"

      \u64ad\u653e\u5a92\u4f53\u6587\u4ef6\u3002

      mediaPlay(url, tag=\"default\", play=True)\n

      \u53c2\u6570\uff1a - url (str): \u5a92\u4f53\u6587\u4ef6\u8def\u5f84\u6216 URL - tag (str): \u64ad\u653e\u5668\u6807\u8bc6\u7b26 - play (bool): \u81ea\u52a8\u5f00\u59cb\u64ad\u653e

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaystart","title":"mediaPlayStart()","text":"

      \u5f00\u59cb\u64ad\u653e\u3002

      mediaPlayStart(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplaypause","title":"mediaPlayPause()","text":"

      \u6682\u505c\u64ad\u653e\u3002

      mediaPlayPause(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplayclose","title":"mediaPlayClose()","text":"

      \u5173\u95ed\u64ad\u653e\u5668\u3002

      mediaPlayClose(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplayseek","title":"mediaPlaySeek()","text":"

      \u8df3\u8f6c\u5230\u4f4d\u7f6e\u3002

      mediaPlaySeek(msec, tag=\"default\")\n

      \u53c2\u6570\uff1a - msec (int): \u4f4d\u7f6e\uff08\u6beb\u79d2\uff09

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaysetlooping","title":"mediaPlaySetLooping()","text":"

      \u8bbe\u7f6e\u5faa\u73af\u6a21\u5f0f\u3002

      mediaPlaySetLooping(enabled, tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#_2","title":"\u64ad\u653e\u5668\u4fe1\u606f","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplayinfo","title":"mediaPlayInfo()","text":"

      \u83b7\u53d6\u64ad\u653e\u4fe1\u606f\u3002

      mediaPlayInfo(tag=\"default\")\n

      \u8fd4\u56de\uff1a \u5305\u542b\u65f6\u957f\u3001\u4f4d\u7f6e\u7b49\u7684\u5b57\u5178

      "},{"location":"qsl4a/media/mediaplayer/#mediaisplaying","title":"mediaIsPlaying()","text":"

      \u68c0\u67e5\u662f\u5426\u6b63\u5728\u64ad\u653e\u3002

      mediaIsPlaying(tag=\"default\")\n

      \u8fd4\u56de\uff1a True/False

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaylist","title":"mediaPlayList()","text":"

      \u5217\u51fa\u6d3b\u52a8\u64ad\u653e\u5668\u3002

      mediaPlayList()\n
      "},{"location":"qsl4a/media/mediaplayer/#_3","title":"\u97f3\u91cf\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#getmediavolume","title":"getMediaVolume()","text":"

      \u83b7\u53d6\u5a92\u4f53\u97f3\u91cf\u3002

      getMediaVolume()\n

      \u8fd4\u56de\uff1a \u97f3\u91cf\u7ea7\u522b\uff080-15\uff09

      "},{"location":"qsl4a/media/mediaplayer/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

      getMaxMediaVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#getringervolume","title":"getRingerVolume()","text":"

      \u83b7\u53d6\u94c3\u58f0\u97f3\u91cf\u3002

      getRingerVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

      getMaxRingerVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#_4","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/mediaplayer/#videoplay","title":"videoPlay()","text":"

      \u5168\u5c4f\u64ad\u653e\u89c6\u9891\u3002

      videoPlay(path, wait=True)\n

      \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210

      "},{"location":"qsl4a/media/mediaplayer/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u64ad\u653e\u97f3\u9891\ndroid.mediaPlay(\"/sdcard/music.mp3\", tag=\"music\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.mediaIsPlaying(\"music\").result:\n    info = droid.mediaPlayInfo(\"music\").result\n    print(f\"Playing: {info}\")\n\n# \u8df3\u8f6c\u5230 30 \u79d2\ndroid.mediaPlaySeek(30000, \"music\")\n\n# \u5173\u95ed\ndroid.mediaPlayClose(\"music\")\n\n# \u64ad\u653e\u89c6\u9891\ndroid.videoPlay(\"/sdcard/movie.mp4\", wait=True)\n
      "},{"location":"qsl4a/special/cipher/","title":"\u5bc6\u7801 API","text":"

      \u7528\u4e8e\u5b89\u5168\u6570\u636e\u5b58\u50a8\u7684\u52a0\u5bc6\u548c\u89e3\u5bc6\u5de5\u5177\u3002

      "},{"location":"qsl4a/special/cipher/#_1","title":"\u521d\u59cb\u5316","text":""},{"location":"qsl4a/special/cipher/#cipherinit","title":"cipherInit()","text":"

      \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u548c\u7b97\u6cd5\u521d\u59cb\u5316\u5bc6\u7801\u5668\u3002

      cipherInit(key, algorithm=\"AES/CBC/PKCS5Padding\", encodingFormat=\"\", initialVector=\"\")\n

      \u53c2\u6570\uff1a - key (str or bytes): \u52a0\u5bc6\u5bc6\u94a5 - algorithm (str): \u5bc6\u7801\u7b97\u6cd5\uff08\u9ed8\u8ba4\uff1a\"AES/CBC/PKCS5Padding\"\uff09 - encodingFormat (str): \u7f16\u7801\u683c\u5f0f - initialVector (str or bytes): \u52a0\u5bc6\u7684\u521d\u59cb\u5411\u91cf

      \u8fd4\u56de\uff1a \u521d\u59cb\u5316\u7ed3\u679c

      \u6ce8\u610f\uff1a \u5fc5\u987b\u5728\u4efb\u4f55\u52a0\u5bc6/\u89e3\u5bc6\u64cd\u4f5c\u4e4b\u524d\u8c03\u7528\u3002

      "},{"location":"qsl4a/special/cipher/#_2","title":"\u52a0\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#encryptstring","title":"encryptString()","text":"

      \u52a0\u5bc6\u5b57\u7b26\u4e32\u3002

      encryptString(plainText)\n

      \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c

      \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/special/cipher/#encryptbytes","title":"encryptBytes()","text":"

      \u52a0\u5bc6\u5b57\u8282\u6570\u636e\u3002

      encryptBytes(data)\n

      \u53c2\u6570\uff1a - data (bytes): \u8981\u52a0\u5bc6\u7684\u6570\u636e

      \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u8282

      "},{"location":"qsl4a/special/cipher/#encryptstringtofile","title":"encryptStringToFile()","text":"

      \u52a0\u5bc6\u5b57\u7b26\u4e32\u5230\u6587\u4ef6\u3002

      encryptStringToFile(plainText, filePath)\n

      \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c - filePath (str): \u8f93\u51fa\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/special/cipher/#encryptbytestofile","title":"encryptBytesToFile()","text":"

      \u52a0\u5bc6\u5b57\u8282\u5230\u6587\u4ef6\u3002

      encryptBytesToFile(data, filePath)\n
      "},{"location":"qsl4a/special/cipher/#_3","title":"\u89e3\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#decryptstring","title":"decryptString()","text":"

      \u89e3\u5bc6\u4e3a\u5b57\u7b26\u4e32\u3002

      decryptString(cipherText)\n

      \u53c2\u6570\uff1a - cipherText (str): \u52a0\u5bc6\u7684\u6587\u672c

      \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/special/cipher/#decryptbytes","title":"decryptBytes()","text":"

      \u89e3\u5bc6\u4e3a\u5b57\u8282\u3002

      decryptBytes(data)\n

      \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u8282

      "},{"location":"qsl4a/special/cipher/#decryptfiletostring","title":"decryptFileToString()","text":"

      \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u7b26\u4e32\u3002

      decryptFileToString(filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryptfiletobytes","title":"decryptFileToBytes()","text":"

      \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u8282\u3002

      decryptFileToBytes(filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryptfile","title":"decryptFile()","text":"

      \u89e3\u5bc6\u6587\u4ef6\u5230\u6587\u4ef6\u3002

      decryptFile(srcPath, destPath)\n
      "},{"location":"qsl4a/special/cipher/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u521d\u59cb\u5316\u5bc6\u7801\u5668\ndroid.cipherInit(\"my_secret_key_1234\")\n\n# \u52a0\u5bc6\u5b57\u7b26\u4e32\nencrypted = droid.encryptString(\"Secret message!\").result\nprint(f\"Encrypted: {encrypted}\")\n\n# \u89e3\u5bc6\u5b57\u7b26\u4e32\ndecrypted = droid.decryptString(encrypted).result\nprint(f\"Decrypted: {decrypted}\")\n\n# \u52a0\u5bc6\u5230\u6587\u4ef6\ndroid.encryptStringToFile(\"My secret data\", \"/sdcard/secret.dat\")\n\n# \u4ece\u6587\u4ef6\u89e3\u5bc6\ndata = droid.decryptFileToString(\"/sdcard/secret.dat\").result\nprint(data)\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u7b97\u6cd5\u548c IV \u521d\u59cb\u5316\ndroid.cipherInit(\n    key=\"my_key\",\n    algorithm=\"AES/CBC/PKCS5Padding\",\n    initialVector=\"0123456789abcdef\"\n)\n
      "},{"location":"qsl4a/special/pgptai/","title":"PGPT AI API","text":"

      \u8bed\u97f3\u8f6c\u6587\u672c\u548c AI \u670d\u52a1\u96c6\u6210\u3002

      "},{"location":"qsl4a/special/pgptai/#_1","title":"\u5148\u51b3\u6761\u4ef6","text":"
      pip install pgptAI\n
      "},{"location":"qsl4a/special/pgptai/#_2","title":"\u8bed\u97f3\u8bc6\u522b","text":""},{"location":"qsl4a/special/pgptai/#speechtotext","title":"speechToText()","text":"

      \u5c06\u8bed\u97f3\u8f6c\u6362\u4e3a\u6587\u672c\u3002

      speechToText(RecordSecond=10, AmrFile=None, Language=None)\n

      \u53c2\u6570\uff1a - RecordSecond (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09 - AmrFile (str, optional): \u73b0\u6709\u97f3\u9891\u6587\u4ef6\u8def\u5f84 - Language (str, optional): \u8bed\u8a00\u4ee3\u7801\uff08'en'\u3001'zh'\uff09

      \u8fd4\u56de\uff1a \u8f6c\u5f55\u7684\u6587\u672c

      "},{"location":"qsl4a/special/pgptai/#_3","title":"\u6587\u672c\u8f6c\u8bed\u97f3","text":""},{"location":"qsl4a/special/pgptai/#texttospeech","title":"textToSpeech()","text":"

      \u5c06\u6587\u672c\u8f6c\u6362\u4e3a\u8bed\u97f3\u5e76\u53ef\u9009\u5730\u64ad\u653e\u3002

      textToSpeech(Text, AutoPlay=True, WavFile=None, VoiceName=None)\n

      \u53c2\u6570\uff1a - Text (str): \u8981\u8f6c\u6362\u4e3a\u8bed\u97f3\u7684\u6587\u672c - AutoPlay (bool): \u81ea\u52a8\u64ad\u653e\u751f\u6210\u7684\u97f3\u9891\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - WavFile (str, optional): \u4fdd\u5b58 WAV \u6587\u4ef6\u7684\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u4e34\u65f6\u6587\u4ef6 - VoiceName (str, optional): \u8981\u4f7f\u7528\u7684\u8bed\u97f3\u540d\u79f0\uff08\u4f8b\u5982 'en-US-JennyNeural'\u3001'zh-CN-XiaoxiaoNeural'\uff09

      \u8fd4\u56de\uff1a \u5305\u542b\u8bed\u97f3\u5408\u6210\u7ed3\u679c\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - text: \u8f93\u5165\u6587\u672c - url: \u4e0b\u8f7d\u97f3\u9891\u6587\u4ef6\u7684 URL - WavFile: \u4fdd\u5b58\u7684 WAV \u6587\u4ef6\u8def\u5f84\uff08\u5982\u679c\u672c\u5730\u4fdd\u5b58\uff09

      "},{"location":"qsl4a/special/pgptai/#_4","title":"\u914d\u7f6e","text":"

      API \u4f7f\u7528\u4ee5\u4e0b\u914d\u7f6e\u6587\u4ef6\u4e2d\u7684\u914d\u7f6e\uff1a/storage/emulated/0/Android/data/org.qpython.qpy/files/apigpt.conf\uff1a

      [speech]\nspeech_key = your_api_key\n

      \u9ed8\u8ba4\u8bed\u97f3\u8bbe\u7f6e\uff1a - \u82f1\u8bed\uff1aen-US-JennyNeural - \u4e2d\u6587\uff1azh-CN-XiaoxiaoNeural

      "},{"location":"qsl4a/special/pgptai/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5f55\u5236\u5e76\u8f6c\u5f55\nprint(\"Recording for 5 seconds...\")\ntext = droid.speechToText(RecordSecond=5, Language='en').result\nprint(f\"You said: {text}\")\n\n# \u8f6c\u5f55\u73b0\u6709\u6587\u4ef6\ntext = droid.speechToText(AmrFile=\"/sdcard/recording.amr\").result\nprint(f\"Transcription: {text}\")\n\n# \u6587\u672c\u8f6c\u8bed\u97f3\ndroid.textToSpeech(\"Hello, this is a test message.\", AutoPlay=True, Language='en')\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u8bed\u97f3\u5e76\u4fdd\u5b58\u5230\u6587\u4ef6\u7684\u6587\u672c\u8f6c\u8bed\u97f3\nresult = droid.textToSpeech(\n    \"Welcome to QPython!\",\n    AutoPlay=False,\n    WavFile=\"/sdcard/welcome.wav\",\n    VoiceName=\"en-US-JennyNeural\"\n).result\nprint(f\"Audio saved to: {result.get('WavFile')}\")\n
      "},{"location":"qsl4a/special/pgptai/#_6","title":"\u7c7b\u4f7f\u7528","text":"
      from androidhelper.pgptai import pgptai\nimport androidhelper\n\ndroid = androidhelper.Android()\nai = pgptai(droid)\n\n# \u4f7f\u7528\u8bed\u97f3\u8bc6\u522b\ntext = ai.speechToText(RecordSecond=10)\n
      "},{"location":"qsl4a/storage/clipboard/","title":"\u526a\u8d34\u677f API","text":"

      \u590d\u5236\u548c\u7c98\u8d34\u6587\u672c\u5230\u7cfb\u7edf\u526a\u8d34\u677f\u3002

      "},{"location":"qsl4a/storage/clipboard/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/clipboard/#setclipboard","title":"setClipboard()","text":"

      \u590d\u5236\u6587\u672c\u5230\u526a\u8d34\u677f\u3002

      setClipboard(text)\n

      \u53c2\u6570\uff1a - text (str): \u8981\u590d\u5236\u7684\u6587\u672c

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/clipboard/#getclipboard","title":"getClipboard()","text":"

      \u4ece\u526a\u8d34\u677f\u83b7\u53d6\u6587\u672c\u3002

      getClipboard()\n

      \u8fd4\u56de\uff1a \u526a\u8d34\u677f\u6587\u672c

      "},{"location":"qsl4a/storage/clipboard/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u590d\u5236\u5230\u526a\u8d34\u677f\ndroid.setClipboard(\"Hello from QPython!\")\n\n# \u4ece\u526a\u8d34\u677f\u7c98\u8d34\ntext = droid.getClipboard().result\nprint(f\"Clipboard: {text}\")\n
      "},{"location":"qsl4a/storage/documentfile/","title":"DocumentFile API","text":"

      \u4f7f\u7528 SAF\uff08\u5b58\u50a8\u8bbf\u95ee\u6846\u67b6\uff09\u8fdb\u884c\u6587\u4ef6\u64cd\u4f5c\uff0c\u652f\u6301 Android 4.4+\u3002

      "},{"location":"qsl4a/storage/documentfile/#_1","title":"\u76ee\u5f55\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilemkdir","title":"documentFileMkdir()","text":"

      \u521b\u5efa\u76ee\u5f55\u3002

      documentFileMkdir(Dir)\n

      \u53c2\u6570\uff1a - Dir (str): \u76ee\u5f55\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/documentfile/#documentfilelistfiles","title":"documentFileListFiles()","text":"

      \u5217\u51fa\u76ee\u5f55\u4e2d\u7684\u6587\u4ef6\u3002

      documentFileListFiles(Folder)\n

      \u8fd4\u56de\uff1a \u6587\u4ef6\u5217\u8868

      "},{"location":"qsl4a/storage/documentfile/#_2","title":"\u6587\u4ef6\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileexists","title":"documentFileExists()","text":"

      \u68c0\u67e5\u6587\u4ef6\u6216\u76ee\u5f55\u662f\u5426\u5b58\u5728\u3002

      documentFileExists(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u6216\u76ee\u5f55\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u5b58\u5728\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/storage/documentfile/#documentfileisfile","title":"documentFileIsFile()","text":"

      \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u6587\u4ef6\u3002

      documentFileIsFile(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u662f\u6587\u4ef6\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u6587\u4ef6\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

      "},{"location":"qsl4a/storage/documentfile/#documentfileisdirectory","title":"documentFileIsDirectory()","text":"

      \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u76ee\u5f55\u3002

      documentFileIsDirectory(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u662f\u76ee\u5f55\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u76ee\u5f55\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

      "},{"location":"qsl4a/storage/documentfile/#documentfiledelete","title":"documentFileDelete()","text":"

      \u5220\u9664\u6587\u4ef6\u6216\u76ee\u5f55\u3002

      documentFileDelete(FileOrTree)\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/documentfile/#documentfilerenameto","title":"documentFileRenameTo()","text":"

      \u91cd\u547d\u540d\u6216\u79fb\u52a8\u6587\u4ef6\u3002

      documentFileRenameTo(Src, Dest)\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/documentfile/#documentfilecopy","title":"documentFileCopy()","text":"

      \u590d\u5236\u6587\u4ef6\u3002

      documentFileCopy(SrcFileOrTree, DestFileOrTree)\n
      "},{"location":"qsl4a/storage/documentfile/#_3","title":"\u6d41\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileinputstream","title":"documentFileInputStream()","text":"

      \u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9\u3002

      documentFileInputStream(srcFile, EncodingFormat=\"\", skip=None, length=None)\n

      \u53c2\u6570\uff1a - srcFile (str): \u6e90\u6587\u4ef6 - EncodingFormat (str): \"UTF-8\"\u3001\"GBK\"\u3001\"Base64\" \u6216\u7a7a\u5b57\u7b26\u4e32\u8868\u793a\u5b57\u8282 - skip (int): \u4ece\u5f00\u5934\u8df3\u8fc7\u7684\u5b57\u8282\u6570 - length (int): \u8bfb\u53d6\u957f\u5ea6

      \u8fd4\u56de\uff1a \u6587\u4ef6\u5185\u5bb9

      "},{"location":"qsl4a/storage/documentfile/#documentfileoutputstream","title":"documentFileOutputStream()","text":"

      \u5199\u5165\u6587\u4ef6\u5185\u5bb9\u3002

      documentFileOutputStream(destFile, src, EncodingFormat=\"\", append=None)\n

      \u53c2\u6570\uff1a - destFile (str): \u76ee\u6807\u6587\u4ef6 - src: \u8981\u5199\u5165\u7684\u6570\u636e - EncodingFormat (str): \u7f16\u7801\u683c\u5f0f - append (bool): \u8ffd\u52a0\u6a21\u5f0f

      "},{"location":"qsl4a/storage/documentfile/#_4","title":"\u6587\u4ef6\u4fe1\u606f","text":""},{"location":"qsl4a/storage/documentfile/#documentfilelength","title":"documentFileLength()","text":"

      \u83b7\u53d6\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\u3002

      documentFileLength(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

      "},{"location":"qsl4a/storage/documentfile/#documentfilelastmodified","title":"documentFileLastModified()","text":"

      \u83b7\u53d6\u6700\u540e\u4fee\u6539\u65f6\u95f4\u3002

      documentFileLastModified(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u65f6\u95f4\u6233\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

      "},{"location":"qsl4a/storage/documentfile/#documentfilegetstat","title":"documentFileGetStat()","text":"

      \u83b7\u53d6\u5168\u9762\u7684\u6587\u4ef6\u7edf\u8ba1\u4fe1\u606f\u3002

      documentFileGetStat(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5305\u542b\u957f\u5ea6\u3001\u6700\u540e\u4fee\u6539\u65f6\u95f4\u548c\u8bfb/\u5199\u6743\u9650\u7684\u5b57\u5178\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

      "},{"location":"qsl4a/storage/documentfile/#uri","title":"URI \u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilegeturi","title":"documentFileGetUri()","text":"

      \u4ece\u8def\u5f84\u83b7\u53d6 URI\u3002

      documentFileGetUri(path, isDirectory=None)\n
      "},{"location":"qsl4a/storage/documentfile/#documentfileshowopen","title":"documentFileShowOpen()","text":"

      \u663e\u793a\u6587\u4ef6\u9009\u62e9\u5668\u3002

      documentFileShowOpen()\n

      \u8fd4\u56de\uff1a \u9009\u62e9\u7684\u6587\u4ef6 URI

      "},{"location":"qsl4a/storage/documentfile/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u76ee\u5f55\ndroid.documentFileMkdir(\"/sdcard/MyFolder\")\n\n# \u5217\u51fa\u6587\u4ef6\nfiles = droid.documentFileListFiles(\"/sdcard\").result\nfor f in files:\n    print(f)\n\n# \u8bfb\u53d6\u6587\u4ef6\ncontent = droid.documentFileInputStream(\n    \"/sdcard/test.txt\",\n    EncodingFormat=\"UTF-8\"\n).result\nprint(content)\n\n# \u5199\u5165\u6587\u4ef6\ndroid.documentFileOutputStream(\n    \"/sdcard/output.txt\",\n    \"Hello World\",\n    EncodingFormat=\"UTF-8\"\n)\n
      "},{"location":"qsl4a/storage/preferences/","title":"\u504f\u597d\u8bbe\u7f6e API","text":"

      \u4f7f\u7528 Android SharedPreferences \u5b58\u50a8\u548c\u68c0\u7d22\u6570\u636e\u3002

      "},{"location":"qsl4a/storage/preferences/#_1","title":"\u504f\u597d\u8bbe\u7f6e\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/preferences/#prefgetvalue","title":"prefGetValue()","text":"

      \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u8bfb\u53d6\u503c\u3002

      prefGetValue(key, filename=None)\n

      \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c\uff08\u4efb\u610f\u7c7b\u578b\uff09

      "},{"location":"qsl4a/storage/preferences/#prefputvalue","title":"prefPutValue()","text":"

      \u5199\u5165\u503c\u5230\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u3002

      prefPutValue(key, value, filename=None)\n

      \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - value (object): \u8981\u5b58\u50a8\u7684\u503c - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      "},{"location":"qsl4a/storage/preferences/#prefgetall","title":"prefGetAll()","text":"

      \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\u503c\u3002

      prefGetAll(filename=None)\n

      \u53c2\u6570\uff1a - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      \u8fd4\u56de\uff1a \u6240\u6709\u504f\u597d\u7684\u6620\u5c04

      "},{"location":"qsl4a/storage/preferences/#prefremovevalue","title":"prefRemoveValue()","text":"

      \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u4e2d\u79fb\u9664\u503c\u3002

      prefRemoveValue(key, filename=None)\n

      \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      "},{"location":"qsl4a/storage/preferences/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b58\u50a8\u503c\ndroid.prefPutValue(\"username\", \"alice\")\ndroid.prefPutValue(\"score\", 100)\ndroid.prefPutValue(\"enabled\", True)\n\n# \u8bfb\u53d6\u7279\u5b9a\u503c\nusername = droid.prefGetValue(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\nall_prefs = droid.prefGetAll().result\nprint(f\"All prefs: {all_prefs}\")\n\n# \u79fb\u9664\u503c\ndroid.prefRemoveValue(\"score\")\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u6587\u4ef6\u540d\ndroid.prefPutValue(\"token\", \"abc123\", filename=\"auth.prefs\")\ntoken = droid.prefGetValue(\"token\", filename=\"auth.prefs\").result\n
      "},{"location":"qsl4a/system/activityresult/","title":"Activity Result API","text":"

      \u4e3a\u901a\u8fc7 startActivityForResult \u542f\u52a8\u7684\u811a\u672c\u8bbe\u7f6e activity \u7ed3\u679c\u3002

      "},{"location":"qsl4a/system/activityresult/#_1","title":"\u7ed3\u679c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/activityresult/#setresultboolean","title":"setResultBoolean()","text":"

      \u8bbe\u7f6e\u5e03\u5c14\u7ed3\u679c\u3002

      setResultBoolean(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (bool): \u5e03\u5c14\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultbyte","title":"setResultByte()","text":"

      \u8bbe\u7f6e\u5b57\u8282\u7ed3\u679c\u3002

      setResultByte(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u5b57\u8282\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultshort","title":"setResultShort()","text":"

      \u8bbe\u7f6e\u77ed\u6574\u6570\u7ed3\u679c\u3002

      setResultShort(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u77ed\u6574\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultchar","title":"setResultChar()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u7ed3\u679c\u3002

      setResultChar(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultinteger","title":"setResultInteger()","text":"

      \u8bbe\u7f6e\u6574\u6570\u7ed3\u679c\u3002

      setResultInteger(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u6574\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultlong","title":"setResultLong()","text":"

      \u8bbe\u7f6e\u957f\u6574\u6570\u7ed3\u679c\u3002

      setResultLong(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u957f\u6574\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultfloat","title":"setResultFloat()","text":"

      \u8bbe\u7f6e\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

      setResultFloat(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u6d6e\u70b9\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultdouble","title":"setResultDouble()","text":"

      \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

      setResultDouble(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultstring","title":"setResultString()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u4e32\u7ed3\u679c\u3002

      setResultString(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u4e32\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultbooleanarray","title":"setResultBooleanArray()","text":"

      \u8bbe\u7f6e\u5e03\u5c14\u6570\u7ec4\u7ed3\u679c\u3002

      setResultBooleanArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5e03\u5c14\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultbytearray","title":"setResultByteArray()","text":"

      \u8bbe\u7f6e\u5b57\u8282\u6570\u7ec4\u7ed3\u679c\u3002

      setResultByteArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u8282\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultshortarray","title":"setResultShortArray()","text":"

      \u8bbe\u7f6e\u77ed\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultShortArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u77ed\u6574\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultchararray","title":"setResultCharArray()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u6570\u7ec4\u7ed3\u679c\u3002

      setResultCharArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultintegerarray","title":"setResultIntegerArray()","text":"

      \u8bbe\u7f6e\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultIntegerArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6574\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultlongarray","title":"setResultLongArray()","text":"

      \u8bbe\u7f6e\u957f\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultLongArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u957f\u6574\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultfloatarray","title":"setResultFloatArray()","text":"

      \u8bbe\u7f6e\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultFloatArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6d6e\u70b9\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultdoublearray","title":"setResultDoubleArray()","text":"

      \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultDoubleArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultstringarray","title":"setResultStringArray()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u4e32\u6570\u7ec4\u7ed3\u679c\u3002

      setResultStringArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u4e32\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultserializable","title":"setResultSerializable()","text":"

      \u8bbe\u7f6e\u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u3002

      setResultSerializable(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue: \u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c activity \u540e\uff0c\u8bbe\u7f6e\u7ed3\u679c\n# \u793a\u4f8b\uff1a\u8fd4\u56de\u6210\u529f\u53ca\u6570\u636e\ndroid.setResultInteger(0, 200)  # RESULT_OK\ndroid.setResultString(0, \"Operation completed successfully\")\n\n# \u8fd4\u56de\u6570\u7ec4\u7ed3\u679c\ndroid.setResultIntegerArray(0, [1, 2, 3, 4, 5])\n
      "},{"location":"qsl4a/system/application/","title":"\u5e94\u7528\u7ba1\u7406","text":"

      \u7ba1\u7406\u5e94\u7528\u7a0b\u5e8f\u3001\u542f\u52a8\u5e94\u7528\u548c\u67e5\u8be2\u7cfb\u7edf\u4fe1\u606f\u3002

      "},{"location":"qsl4a/system/application/#_2","title":"\u5e94\u7528\u7a0b\u5e8f\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getapplicationinfo","title":"getApplicationInfo()","text":"

      \u83b7\u53d6\u5e94\u7528\u4fe1\u606f\u3002

      getApplicationInfo(packageName=None)\n

      \u53c2\u6570\uff1a - packageName (str): \u5305\u540d\uff08None = \u5f53\u524d\u5e94\u7528\uff09

      \u8fd4\u56de\uff1a \u5e94\u7528\u4fe1\u606f\u5b57\u5178

      "},{"location":"qsl4a/system/application/#getinstalledpackages","title":"getInstalledPackages()","text":"

      \u83b7\u53d6\u5df2\u5b89\u88c5\u5305\u5217\u8868\u3002

      getInstalledPackages(flag=4)\n

      \u53c2\u6570\uff1a - flag (int): \u5305\u6807\u5fd7\u8fc7\u6ee4\u5668\uff08\u9ed8\u8ba4\uff1a4\uff09

      \u8fd4\u56de\uff1a \u5df2\u5b89\u88c5\u5305\u5217\u8868

      "},{"location":"qsl4a/system/application/#getrunningpackages","title":"getRunningPackages()","text":"

      \u5217\u51fa\u6b63\u5728\u8fd0\u884c\u7684\u5305\u3002

      getRunningPackages()\n

      \u8fd4\u56de\uff1a \u5305\u540d\u5217\u8868

      "},{"location":"qsl4a/system/application/#getlaunchablepackages","title":"getLaunchablePackages()","text":"

      \u83b7\u53d6\u53ef\u542f\u52a8\u5305\u5217\u8868\u3002

      getLaunchablePackages(needClassName=False)\n

      \u53c2\u6570\uff1a - needClassName (bool): \u5305\u542b\u4e3b activity \u7c7b\u540d\uff08\u9ed8\u8ba4\uff1aFalse\uff09

      \u8fd4\u56de\uff1a \u53ef\u542f\u52a8\u5305\u540d\u5217\u8868\u6216\u5305\u542b\u7c7b\u540d\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#_3","title":"\u5e94\u7528\u63a7\u5236","text":""},{"location":"qsl4a/system/application/#launch","title":"launch()","text":"

      \u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u3002

      launch(classname=None, packagename=None, wait=True)\n

      \u53c2\u6570\uff1a - classname (str): \u4e3b activity \u7c7b\u540d - packagename (str): \u5305\u540d - wait (bool): \u7b49\u5f85\u542f\u52a8\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

      \u8fd4\u56de\uff1a \u542f\u52a8\u7ed3\u679c

      "},{"location":"qsl4a/system/application/#forcestoppackage","title":"forceStopPackage()","text":"

      \u5f3a\u5236\u505c\u6b62\u5e94\u7528\u7a0b\u5e8f\u3002

      forceStopPackage(packageName)\n

      \u53c2\u6570\uff1a - packageName (str): \u8981\u505c\u6b62\u7684\u5305\u540d

      "},{"location":"qsl4a/system/application/#_4","title":"\u7248\u672c\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getpackageversion","title":"getPackageVersion()","text":"

      \u83b7\u53d6\u5e94\u7528\u7248\u672c\u540d\u79f0\u3002

      getPackageVersion(packageName)\n

      \u8fd4\u56de\uff1a \u7248\u672c\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"3.2.1\"\uff09

      "},{"location":"qsl4a/system/application/#getpackageversioncode","title":"getPackageVersionCode()","text":"

      \u83b7\u53d6\u5e94\u7528\u7248\u672c\u4ee3\u7801\u3002

      getPackageVersionCode(packageName)\n

      \u8fd4\u56de\uff1a \u7248\u672c\u4ee3\u7801\u6574\u6570

      "},{"location":"qsl4a/system/application/#getconstants","title":"getConstants()","text":"

      \u83b7\u53d6\u7c7b\u5e38\u91cf\u3002

      getConstants(classname)\n

      \u53c2\u6570\uff1a - classname (str): \u5b8c\u6574\u7c7b\u540d

      \u8fd4\u56de\uff1a \u5e38\u91cf\u540d\u548c\u503c\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#_5","title":"\u7cfb\u7edf\u529f\u80fd","text":""},{"location":"qsl4a/system/application/#backgroundprotect","title":"backgroundProtect()","text":"

      \u542f\u7528\u6216\u7981\u7528\u5e94\u7528\u7684\u540e\u53f0\u4fdd\u62a4\u3002

      backgroundProtect(enabled=True)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\u4fdd\u62a4\uff0cFalse \u7981\u7528

      "},{"location":"qsl4a/system/application/#createscriptshortcut","title":"createScriptShortCut()","text":"

      \u4e3a\u811a\u672c\u521b\u5efa\u4e3b\u5c4f\u5e55\u5feb\u6377\u65b9\u5f0f\u3002

      createScriptShortCut(scriptPath, label=None, iconPath=None, scriptArg=None)\n

      \u53c2\u6570\uff1a - scriptPath (str): Python \u811a\u672c\u8def\u5f84 - label (str, optional): \u5feb\u6377\u65b9\u5f0f\u6807\u7b7e - iconPath (str, optional): \u56fe\u6807\u56fe\u50cf\u8def\u5f84 - scriptArg (str, optional): \u4f20\u9012\u7ed9\u811a\u672c\u7684\u53c2\u6570

      "},{"location":"qsl4a/system/application/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getandroidid","title":"getAndroidID()","text":"

      \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

      getAndroidID()\n

      \u8fd4\u56de\uff1a \u552f\u4e00\u7684 Android \u8bbe\u5907 ID \u5b57\u7b26\u4e32

      "},{"location":"qsl4a/system/application/#getsysinfo","title":"getSysInfo()","text":"

      \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\u3002

      getSysInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#getlocale","title":"getLocale()","text":"

      \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u3002

      getLocale()\n

      \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

      "},{"location":"qsl4a/system/application/#getharmonyosinformation","title":"getHarmonyOsInformation()","text":"

      \u5982\u679c\u5728 HarmonyOS \u4e0a\u8fd0\u884c\uff0c\u83b7\u53d6 HarmonyOS \u4fe1\u606f\u3002

      getHarmonyOsInformation()\n

      \u8fd4\u56de\uff1a HarmonyOS \u7248\u672c\u4fe1\u606f\u6216 None

      "},{"location":"qsl4a/system/application/#isexternalstoragemanager","title":"isExternalStorageManager()","text":"

      \u68c0\u67e5\u5e94\u7528\u662f\u5426\u6709\u5916\u90e8\u5b58\u50a8\u7ba1\u7406\u5668\u6743\u9650\u3002

      isExternalStorageManager()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6709\u6743\u9650\u5219\u4e3a True

      "},{"location":"qsl4a/system/application/#_7","title":"\u5185\u5b58\u548c\u663e\u793a","text":""},{"location":"qsl4a/system/application/#getmemoryinfo","title":"getMemoryInfo()","text":"

      \u83b7\u53d6\u5185\u5b58\u4fe1\u606f\u3002

      getMemoryInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#getscreeninfo","title":"getScreenInfo()","text":"

      \u83b7\u53d6\u5c4f\u5e55\u4fe1\u606f\u3002

      getScreenInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#_8","title":"\u6743\u9650","text":""},{"location":"qsl4a/system/application/#checkpermissions","title":"checkPermissions()","text":"

      \u68c0\u67e5\u5f53\u524d\u5e94\u7528\u6743\u9650\u3002

      checkPermissions()\n

      \u8fd4\u56de\uff1a \u6743\u9650\u53ca\u5176\u72b6\u6001\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#requestpermissions","title":"requestPermissions()","text":"

      \u5411\u7528\u6237\u8bf7\u6c42\u6743\u9650\u3002

      requestPermissions(permissions=None)\n

      \u53c2\u6570\uff1a - permissions (list, optional): \u8981\u8bf7\u6c42\u7684\u6743\u9650\u5217\u8868\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8bf7\u6c42\u6240\u6709\u9700\u8981\u7684\u6743\u9650\u3002

      \u8fd4\u56de\uff1a \u6743\u9650\u8bf7\u6c42\u7ed3\u679c

      "},{"location":"qsl4a/system/application/#_9","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/system/application/#showscreenlock","title":"showScreenLock()","text":"

      \u663e\u793a\u5c4f\u5e55\u9501\u5b9a\uff08PIN/\u56fe\u6848/\u5bc6\u7801\u8f93\u5165\uff09\u3002

      showScreenLock()\n
      "},{"location":"qsl4a/system/application/#_10","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\ninfo = droid.getSysInfo().result\nprint(f\"System: {info}\")\n\n# \u83b7\u53d6\u5e94\u7528\u7248\u672c\nversion = droid.getPackageVersion(\"org.qpython.qpy\").result\nprint(f\"QPython version: {version}\")\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u5e94\u7528\napps = droid.getInstalledPackages().result\nprint(f\"Installed apps: {len(apps)}\")\n\n# \u542f\u52a8\u5e94\u7528\ndroid.launch(packagename=\"com.android.settings\")\n\n# \u68c0\u67e5\u6743\u9650\nperms = droid.checkPermissions().result\nprint(f\"Permissions: {perms}\")\n\n# \u8bf7\u6c42\u5b58\u50a8\u6743\u9650\ndroid.requestPermissions([\"android.permission.READ_EXTERNAL_STORAGE\"])\n\n# \u521b\u5efa\u5feb\u6377\u65b9\u5f0f\ndroid.createScriptShortCut(\n    \"/sdcard/my_script.py\",\n    label=\"My Script\",\n    iconPath=\"/sdcard/icon.png\"\n)\n
      "},{"location":"qsl4a/system/battery/","title":"\u7535\u6c60 API","text":"

      \u76d1\u63a7\u8bbe\u5907\u7535\u6c60\u72b6\u6001\u548c\u5065\u5eb7\u72b6\u51b5\u3002

      "},{"location":"qsl4a/system/battery/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/battery/#readbatterydata","title":"readBatteryData()","text":"

      \u83b7\u53d6\u5b8c\u6574\u7684\u7535\u6c60\u4fe1\u606f\u3002

      readBatteryData()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7535\u6c60\u6570\u636e\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/battery/#batterystartmonitoring","title":"batteryStartMonitoring()","text":"

      \u5f00\u59cb\u7535\u6c60\u76d1\u63a7\u3002

      batteryStartMonitoring()\n
      "},{"location":"qsl4a/system/battery/#batterystopmonitoring","title":"batteryStopMonitoring()","text":"

      \u505c\u6b62\u7535\u6c60\u76d1\u63a7\u3002

      batteryStopMonitoring()\n
      "},{"location":"qsl4a/system/battery/#batterygetlevel","title":"batteryGetLevel()","text":"

      \u83b7\u53d6\u7535\u6c60\u767e\u5206\u6bd4\u3002

      batteryGetLevel()\n

      \u8fd4\u56de\uff1a \u6574\u6570\uff080-100\uff09

      "},{"location":"qsl4a/system/battery/#batterygetstatus","title":"batteryGetStatus()","text":"

      \u83b7\u53d6\u5145\u7535\u72b6\u6001\u3002

      batteryGetStatus()\n

      \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u5145\u7535\u4e2d - 3: \u653e\u7535\u4e2d - 4: \u672a\u5145\u7535 - 5: \u5df2\u5145\u6ee1

      "},{"location":"qsl4a/system/battery/#batterygetplugtype","title":"batteryGetPlugType()","text":"

      \u83b7\u53d6\u7535\u6e90\u7c7b\u578b\u3002

      batteryGetPlugType()\n

      \u8fd4\u56de\uff1a - -1: \u672a\u77e5 - 0: \u672a\u63d2\u7535 - 1: AC \u5145\u7535\u5668 - 2: USB \u7aef\u53e3

      "},{"location":"qsl4a/system/battery/#batterygethealth","title":"batteryGetHealth()","text":"

      \u83b7\u53d6\u7535\u6c60\u5065\u5eb7\u72b6\u51b5\u3002

      batteryGetHealth()\n

      \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u826f\u597d - 3: \u8fc7\u70ed - 4: \u635f\u574f - 5: \u8fc7\u538b - 6: \u672a\u6307\u5b9a\u7684\u6545\u969c

      "},{"location":"qsl4a/system/battery/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\nlevel = droid.batteryGetLevel().result\nprint(f\"Battery: {level}%\")\n
      "},{"location":"qsl4a/system/qpyinterface/","title":"QPython \u63a5\u53e3 API","text":"

      \u4ece\u5176\u4ed6\u5e94\u7528\u6267\u884c QPython \u811a\u672c\u548c\u7ba1\u7406\u5171\u4eab\u53d8\u91cf\u3002

      "},{"location":"qsl4a/system/qpyinterface/#_1","title":"\u811a\u672c\u6267\u884c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/qpyinterface/#executeqpy","title":"executeQPy()","text":"

      \u6267\u884c QPython \u811a\u672c\u3002

      executeQPy(path=\"\", arg=None)\n

      \u53c2\u6570\uff1a - path (str): \u811a\u672c\u6587\u4ef6\u8def\u5f84 - arg (str, optional): \u547d\u4ee4\u884c\u53c2\u6570

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#executeqpyassrv","title":"executeQPyAsSrv()","text":"

      \u4f5c\u4e3a\u670d\u52a1\u6267\u884c QPython \u811a\u672c\u3002

      executeQPyAsSrv(path=None)\n

      \u53c2\u6570\uff1a - path (str, optional): \u811a\u672c\u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#executeqpycode","title":"executeQPyCode()","text":"

      \u76f4\u63a5\u6267\u884c Python \u4ee3\u7801\u3002

      executeQPyCode(code=None)\n

      \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#executeqpycodeassrv","title":"executeQPyCodeAsSrv()","text":"

      \u4f5c\u4e3a\u670d\u52a1\u6267\u884c Python \u4ee3\u7801\u3002

      executeQPyCodeAsSrv(code=None)\n

      \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#_2","title":"\u5171\u4eab\u53d8\u91cf","text":"

      \u5171\u4eab\u53d8\u91cf\u5141\u8bb8 QPython \u4e0e\u5176\u4ed6\u5e94\u7528\u4e4b\u95f4\u8fdb\u884c\u901a\u4fe1\u3002

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableset","title":"sharedVariableSet()","text":"

      \u8bbe\u7f6e Java \u5171\u4eab\u53d8\u91cf\u3002

      sharedVariableSet(key, value)\n

      \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d - value (str): \u53d8\u91cf\u503c

      \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableget","title":"sharedVariableGet()","text":"

      \u83b7\u53d6 Java \u5171\u4eab\u53d8\u91cf\u3002

      sharedVariableGet(key)\n

      \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d

      \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableremove","title":"sharedVariableRemove()","text":"

      \u79fb\u9664 Java \u5171\u4eab\u53d8\u91cf\u3002

      sharedVariableRemove(key)\n

      \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u53d8\u91cf\u540d

      \u8fd4\u56de\uff1a \u88ab\u79fb\u9664\u7684\u503c

      "},{"location":"qsl4a/system/qpyinterface/#getlastlog","title":"getLastLog()","text":"

      \u83b7\u53d6 QPython \u7684\u6700\u540e\u65e5\u5fd7\u8f93\u51fa\u3002

      getLastLog()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u65e5\u5fd7\u5185\u5bb9

      "},{"location":"qsl4a/system/qpyinterface/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c\u811a\u672c\ndroid.executeQPy(\"/sdcard/my_script.py\", arg=\"test\")\n\n# \u76f4\u63a5\u6267\u884c\u4ee3\u7801\ncode = \"print('Hello from QPython!')\"\ndroid.executeQPyCode(code)\n\n# \u4f7f\u7528\u5171\u4eab\u53d8\u91cf\ndroid.sharedVariableSet(\"username\", \"alice\")\nusername = droid.sharedVariableGet(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u79fb\u9664\u53d8\u91cf\ndroid.sharedVariableRemove(\"username\")\n\n# \u83b7\u53d6\u6700\u8fd1\u65e5\u5fd7\nlog = droid.getLastLog().result\nprint(f\"Log: {log}\")\n
      "},{"location":"qsl4a/system/sensors/","title":"\u4f20\u611f\u5668 API","text":"

      \u8bbf\u95ee\u8bbe\u5907\u4f20\u611f\u5668\uff0c\u5305\u62ec\u52a0\u901f\u5ea6\u8ba1\u3001\u9640\u87ba\u4eea\u3001\u78c1\u529b\u8ba1\u7b49\u3002

      "},{"location":"qsl4a/system/sensors/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/sensors/#startsensingtimed","title":"startSensingTimed()","text":"

      \u5f00\u59cb\u4f20\u611f\u5668\u76d1\u63a7\u5e76\u8bbe\u7f6e\u65f6\u95f4\u95f4\u9694\u3002

      startSensingTimed(sensorNumber, delayTime)\n

      \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID\uff08\u901a\u5e38\u4e3a 1-3\uff09 - delayTime (int): \u8bfb\u53d6\u4e4b\u95f4\u7684\u5ef6\u8fdf\uff08\u6beb\u79d2\uff09

      "},{"location":"qsl4a/system/sensors/#startsensingthreshold","title":"startSensingThreshold()","text":"

      \u5f00\u59cb\u5e26\u9608\u503c\u89e6\u53d1\u7684\u4f20\u611f\u5668\u76d1\u63a7\u3002

      startSensingThreshold(sensorNumber, threshold, axis)\n

      \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID - threshold (float): \u89e6\u53d1\u9608\u503c - axis (int): \u8981\u76d1\u63a7\u7684\u8f74\uff080=X\uff0c1=Y\uff0c2=Z\uff09

      "},{"location":"qsl4a/system/sensors/#stopsensing","title":"stopSensing()","text":"

      \u505c\u6b62\u6240\u6709\u4f20\u611f\u5668\u76d1\u63a7\u3002

      stopSensing()\n
      "},{"location":"qsl4a/system/sensors/#readsensors","title":"readSensors()","text":"

      \u8bfb\u53d6\u5f53\u524d\u4f20\u611f\u5668\u6570\u636e\u3002

      readSensors()\n

      \u8fd4\u56de\uff1a \u4f20\u611f\u5668\u6570\u636e\u5b57\u5178

      "},{"location":"qsl4a/system/sensors/#sensorsreadaccelerometer","title":"sensorsReadAccelerometer()","text":"

      \u8bfb\u53d6\u52a0\u901f\u5ea6\u8ba1\u503c\u3002

      sensorsReadAccelerometer()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d m/s\u00b2

      "},{"location":"qsl4a/system/sensors/#sensorsreadgyroscope","title":"sensorsReadGyroscope()","text":"

      \u8bfb\u53d6\u9640\u87ba\u4eea\u503c\u3002

      sensorsReadGyroscope()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d rad/s

      "},{"location":"qsl4a/system/sensors/#sensorsreadmagnetometer","title":"sensorsReadMagnetometer()","text":"

      \u8bfb\u53d6\u78c1\u573a\u503c\u3002

      sensorsReadMagnetometer()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d \u03bcT

      "},{"location":"qsl4a/system/sensors/#sensorsreadorientation","title":"sensorsReadOrientation()","text":"

      \u8bfb\u53d6\u8bbe\u5907\u65b9\u5411\u3002

      sensorsReadOrientation()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [azimuth, pitch, roll]\uff0c\u5355\u4f4d\u5ea6

      "},{"location":"qsl4a/system/sensors/#sensorsgetlight","title":"sensorsGetLight()","text":"

      \u8bfb\u53d6\u5149\u4f20\u611f\u5668\u503c\u3002

      sensorsGetLight()\n

      \u8fd4\u56de\uff1a \u5149\u7ea7\u522b\uff08lux\uff09

      "},{"location":"qsl4a/system/sensors/#sensorsgetstepcounter","title":"sensorsGetStepCounter()","text":"

      \u8bfb\u53d6\u6b65\u8ba1\u6570\u5668\u3002

      sensorsGetStepCounter()\n

      \u8fd4\u56de\uff1a \u6b65\u6570

      "},{"location":"qsl4a/system/sensors/#sensorsgetaccuracy","title":"sensorsGetAccuracy()","text":"

      \u83b7\u53d6\u5f53\u524d\u4f20\u611f\u5668\u7cbe\u5ea6\u3002

      sensorsGetAccuracy()\n

      \u8fd4\u56de\uff1a \u7cbe\u5ea6\u503c\uff080-3\uff1aUNRELIABLE\u3001ACCURACY_LOW\u3001ACCURACY_MEDIUM\u3001ACCURACY_HIGH\uff09

      "},{"location":"qsl4a/system/sensors/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u8bfb\u53d6\u4f20\u611f\u5668 10 \u6b21\nfor i in range(10):\n    accel = droid.sensorsReadAccelerometer().result\n    print(f\"Accel: X={accel[0]:.2f}, Y={accel[1]:.2f}, Z={accel[2]:.2f}\")\n    time.sleep(0.5)\n\ndroid.stopSensing()\n
      "},{"location":"qsl4a/system/settings/","title":"\u8bbe\u7f6e API","text":"

      \u63a7\u5236\u7cfb\u7edf\u8bbe\u7f6e\uff0c\u5305\u62ec\u5c4f\u5e55\u3001\u58f0\u97f3\u548c\u7f51\u7edc\u8bbe\u7f6e\u3002

      "},{"location":"qsl4a/system/settings/#_1","title":"\u5c4f\u5e55\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#setscreentimeout","title":"setScreenTimeout()","text":"

      \u8bbe\u7f6e\u5c4f\u5e55\u8d85\u65f6\u503c\u3002

      setScreenTimeout(value)\n

      \u53c2\u6570\uff1a - value (int): \u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

      \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u8d85\u65f6\u503c

      "},{"location":"qsl4a/system/settings/#getscreentimeout","title":"getScreenTimeout()","text":"

      \u83b7\u53d6\u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u3002

      getScreenTimeout()\n

      \u8fd4\u56de\uff1a \u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

      "},{"location":"qsl4a/system/settings/#getscreenbrightness","title":"getScreenBrightness()","text":"

      \u83b7\u53d6\u5c4f\u5e55\u4eae\u5ea6\u503c\u3002

      getScreenBrightness()\n

      \u8fd4\u56de\uff1a \u4eae\u5ea6\u503c\uff080-255\uff09

      "},{"location":"qsl4a/system/settings/#setscreenbrightness","title":"setScreenBrightness()","text":"

      \u8bbe\u7f6e\u5c4f\u5e55\u4eae\u5ea6\u3002

      setScreenBrightness(value=None)\n

      \u53c2\u6570\uff1a - value (int, optional): \u4eae\u5ea6\u503c\uff080-255\uff09\uff0c\u6216 None \u8868\u793a\u81ea\u52a8

      \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u4eae\u5ea6\u503c

      "},{"location":"qsl4a/system/settings/#checkscreenon","title":"checkScreenOn()","text":"

      \u68c0\u67e5\u5c4f\u5e55\u662f\u5426\u4eae\u7740\u3002

      checkScreenOn()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u5c4f\u5e55\u4eae\u7740\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/system/settings/#_2","title":"\u98de\u884c\u6a21\u5f0f","text":""},{"location":"qsl4a/system/settings/#checkairplanemode","title":"checkAirplaneMode()","text":"

      \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\u662f\u5426\u542f\u7528\u3002

      checkAirplaneMode()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u98de\u884c\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

      "},{"location":"qsl4a/system/settings/#_3","title":"\u94c3\u58f0\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#checkringersilentmode","title":"checkRingerSilentMode()","text":"

      \u68c0\u67e5\u94c3\u58f0\u662f\u5426\u5904\u4e8e\u9759\u97f3\u6a21\u5f0f\u3002

      checkRingerSilentMode()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u9759\u97f3\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

      "},{"location":"qsl4a/system/settings/#toggleringersilentmode","title":"toggleRingerSilentMode()","text":"

      \u5207\u6362\u94c3\u58f0\u9759\u97f3\u6a21\u5f0f\u3002

      toggleRingerSilentMode(enabled=None)\n

      \u53c2\u6570\uff1a - enabled (bool, optional): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

      \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

      "},{"location":"qsl4a/system/settings/#togglevibratemode","title":"toggleVibrateMode()","text":"

      \u5207\u6362\u632f\u52a8\u6a21\u5f0f\u3002

      toggleVibrateMode(enabled=None, ringer=None)\n

      \u53c2\u6570\uff1a - enabled (bool, optional): \u5207\u6362\u632f\u52a8\u5f00/\u5173 - ringer (bool, optional): \u5e94\u7528\u4e8e\u94c3\u58f0\u6a21\u5f0f

      \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

      "},{"location":"qsl4a/system/settings/#getvibratemode","title":"getVibrateMode()","text":"

      \u83b7\u53d6\u632f\u52a8\u6a21\u5f0f\u8bbe\u7f6e\u3002

      getVibrateMode(ringer=None)\n

      \u53c2\u6570\uff1a - ringer (bool, optional): \u68c0\u67e5\u94c3\u58f0\u632f\u52a8\u6a21\u5f0f

      \u8fd4\u56de\uff1a \u5982\u679c\u632f\u52a8\u5df2\u542f\u7528\u5219\u4e3a True

      "},{"location":"qsl4a/system/settings/#_4","title":"\u97f3\u91cf\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#getringervolume","title":"getRingerVolume()","text":"

      \u83b7\u53d6\u5f53\u524d\u94c3\u58f0\u97f3\u91cf\u3002

      getRingerVolume()\n

      \u8fd4\u56de\uff1a \u94c3\u58f0\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-7\uff09

      "},{"location":"qsl4a/system/settings/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

      getMaxRingerVolume()\n

      \u8fd4\u56de\uff1a \u6700\u5927\u94c3\u58f0\u97f3\u91cf

      "},{"location":"qsl4a/system/settings/#setringervolume","title":"setRingerVolume()","text":"

      \u8bbe\u7f6e\u94c3\u58f0\u97f3\u91cf\u3002

      setRingerVolume(volume)\n

      \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

      "},{"location":"qsl4a/system/settings/#getmediavolume","title":"getMediaVolume()","text":"

      \u83b7\u53d6\u5f53\u524d\u5a92\u4f53\u97f3\u91cf\u3002

      getMediaVolume()\n

      \u8fd4\u56de\uff1a \u5a92\u4f53\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-15\uff09

      "},{"location":"qsl4a/system/settings/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

      getMaxMediaVolume()\n

      \u8fd4\u56de\uff1a \u6700\u5927\u5a92\u4f53\u97f3\u91cf

      "},{"location":"qsl4a/system/settings/#setmediavolume","title":"setMediaVolume()","text":"

      \u8bbe\u7f6e\u5a92\u4f53\u97f3\u91cf\u3002

      setMediaVolume(volume)\n

      \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

      "},{"location":"qsl4a/system/settings/#_5","title":"\u7cfb\u7edf\u4fe1\u606f","text":""},{"location":"qsl4a/system/settings/#elapsedrealtimenanos","title":"elapsedRealtimeNanos()","text":"

      \u83b7\u53d6\u81ea\u7cfb\u7edf\u542f\u52a8\u4ee5\u6765\u7684\u7eb3\u79d2\u6570\u3002

      elapsedRealtimeNanos()\n

      \u8fd4\u56de\uff1a \u7eb3\u79d2\u6570\uff08\u53ef\u7528\u4e8e\u8ba1\u65f6\uff09

      "},{"location":"qsl4a/system/settings/#gettrafficstats","title":"getTrafficStats()","text":"

      \u83b7\u53d6\u7f51\u7edc\u6d41\u91cf\u7edf\u8ba1\u3002

      getTrafficStats(flags=7)\n

      \u53c2\u6570\uff1a - flags (int): \u8981\u68c0\u7d22\u7684\u7edf\u8ba1\uff08\u9ed8\u8ba4\uff1a7 = \u5168\u90e8\uff09

      \u8fd4\u56de\uff1a \u5305\u542b\u53d1\u9001/\u63a5\u6536\u5b57\u8282\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/settings/#getapptxbytes","title":"getAppTxBytes()","text":"

      \u83b7\u53d6 QPython \u5e94\u7528\u7684\u53d1\u9001\u5b57\u8282\u3002

      getAppTxBytes(packageName)\n

      \u53c2\u6570\uff1a - packageName (str): \u5305\u540d

      \u8fd4\u56de\uff1a \u5305\u542b tx/rx \u5b57\u8282\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/settings/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5c4f\u5e55\u8bbe\u7f6e\ncurrent_timeout = droid.getScreenTimeout().result\nprint(f\"Current timeout: {current_timeout}s\")\ndroid.setScreenTimeout(30)\n\n# \u68c0\u67e5\u5c4f\u5e55\nif droid.checkScreenOn().result:\n    print(\"Screen is on\")\n\n# \u97f3\u91cf\u63a7\u5236\nmedia_vol = droid.getMediaVolume().result\nprint(f\"Media volume: {media_vol}\")\ndroid.setMediaVolume(10)\n\n# \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\nif droid.checkAirplaneMode().result:\n    print(\"Airplane mode is on\")\n
      "},{"location":"qsl4a/system/sysinfo/","title":"\u7cfb\u7edf\u4fe1\u606f","text":"

      \u68c0\u7d22\u8bbe\u5907\u548c\u7cfb\u7edf\u4fe1\u606f\u3002

      "},{"location":"qsl4a/system/sysinfo/#_2","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/sysinfo/#getandroidid","title":"getAndroidID()","text":"

      \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

      getAndroidID()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

      "},{"location":"qsl4a/system/sysinfo/#getsysinfo","title":"getSysInfo()","text":"

      \u83b7\u53d6\u7efc\u5408\u7cfb\u7edf\u4fe1\u606f\u3002

      getSysInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/sysinfo/#getlocale","title":"getLocale()","text":"

      \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u8bbe\u7f6e\u3002

      getLocale()\n

      \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

      "},{"location":"qsl4a/system/sysinfo/#_3","title":"\u5185\u5b58","text":""},{"location":"qsl4a/system/sysinfo/#getmemoryinfo","title":"getMemoryInfo()","text":"

      \u83b7\u53d6 RAM \u4fe1\u606f\u3002

      getMemoryInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/sysinfo/#_4","title":"\u663e\u793a","text":""},{"location":"qsl4a/system/sysinfo/#getscreeninfo","title":"getScreenInfo()","text":"

      \u83b7\u53d6\u663e\u793a\u4fe1\u606f\u3002

      getScreenInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/sysinfo/#_5","title":"\u6807\u8bc6\u7b26","text":""},{"location":"qsl4a/system/sysinfo/#getimei","title":"getImei()","text":"

      \u83b7\u53d6\u8bbe\u5907 IMEI\u3002

      getImei(slotIndex=None)\n
      "},{"location":"qsl4a/system/sysinfo/#getmeid","title":"getMeid()","text":"

      \u83b7\u53d6\u8bbe\u5907 MEID\u3002

      getMeid(slotIndex=None)\n
      "},{"location":"qsl4a/system/sysinfo/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u8bbe\u5907 ID\nandroid_id = droid.getAndroidID().result\nprint(f\"Android ID: {android_id}\")\n\n# \u5c4f\u5e55\u4fe1\u606f\nscreen = droid.getScreenInfo().result\nprint(f\"Screen: {screen['width']}x{screen['height']}\")\n\n# \u5185\u5b58\nmemory = droid.getMemoryInfo().result\nprint(f\"Memory: {memory}\")\n
      "},{"location":"qsl4a/system/wakelock/","title":"WakeLock API","text":"

      \u63a7\u5236\u8bbe\u5907\u5524\u9192\u9501\u4ee5\u4fdd\u6301 CPU \u6216\u5c4f\u5e55\u5f00\u542f\u3002

      "},{"location":"qsl4a/system/wakelock/#wake-lock","title":"Wake Lock \u7c7b\u578b","text":"

      QSL4A \u63d0\u4f9b\u4e0d\u540c\u7c7b\u578b\u7684\u5524\u9192\u9501\uff1a

      \u7c7b\u578b \u63cf\u8ff0 Full CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae Partial \u4ec5 CPU \u5f00\u542f Bright CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae Dim CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697"},{"location":"qsl4a/system/wakelock/#wake-lock_1","title":"Wake Lock \u65b9\u6cd5","text":""},{"location":"qsl4a/system/wakelock/#wakelockacquirefull","title":"wakeLockAcquireFull()","text":"

      \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae\uff09\u3002

      wakeLockAcquireFull()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquirepartial","title":"wakeLockAcquirePartial()","text":"

      \u83b7\u53d6\u90e8\u5206\u5524\u9192\u9501\uff08\u4ec5 CPU \u5f00\u542f\uff09\u3002

      wakeLockAcquirePartial()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquirebright","title":"wakeLockAcquireBright()","text":"

      \u83b7\u53d6\u660e\u4eae\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff09\u3002

      wakeLockAcquireBright()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquiredim","title":"wakeLockAcquireDim()","text":"

      \u83b7\u53d6\u6697\u6de1\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697\uff09\u3002

      wakeLockAcquireDim()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockrelease","title":"wakeLockRelease()","text":"

      \u91ca\u653e\u5524\u9192\u9501\u3002

      wakeLockRelease()\n
      "},{"location":"qsl4a/system/wakelock/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\ndroid.wakeLockAcquireFull()\n\n# \u5728\u4fdd\u6301\u5c4f\u5e55\u5f00\u542f\u65f6\u6267\u884c\u91cd\u8981\u5de5\u4f5c\nprint(\"Screen will stay on\")\ntime.sleep(10)\n\n# \u5b8c\u6210\u540e\u91ca\u653e\ndroid.wakeLockRelease()\n\n# \u6216\u4f7f\u7528\u90e8\u5206\u9501\u8fdb\u884c\u540e\u53f0\u4efb\u52a1\ndroid.wakeLockAcquirePartial()\n# \u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\uff0cCPU \u4ecd\u4fdd\u6301\u5f00\u542f\ntime.sleep(30)\ndroid.wakeLockRelease()\n

      \u6ce8\u610f\uff1a \u8bb0\u4f4f\u5728\u4e0d\u9700\u8981\u65f6\u91ca\u653e\u5524\u9192\u9501\u4ee5\u8282\u7701\u7535\u6c60\u3002

      "},{"location":"qsl4a/ui/accessibility/","title":"\u65e0\u969c\u788d\u670d\u52a1","text":"

      \u65e0\u969c\u788d\u670d\u52a1\u5141\u8bb8\u81ea\u52a8\u5316 UI \u4ea4\u4e92\uff0c\u5982\u70b9\u51fb\u3001\u6ed1\u52a8\u548c\u7cfb\u7edf\u64cd\u4f5c\u3002

      "},{"location":"qsl4a/ui/accessibility/#_2","title":"\u670d\u52a1\u63a7\u5236","text":""},{"location":"qsl4a/ui/accessibility/#accessibilitystartservice","title":"accessibilityStartService()","text":"

      \u542f\u52a8\u65e0\u969c\u788d\u670d\u52a1\u3002

      accessibilityStartService()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/ui/accessibility/#accessibilityserviceenabled","title":"accessibilityServiceEnabled()","text":"

      \u68c0\u67e5\u65e0\u969c\u788d\u670d\u52a1\u662f\u5426\u5df2\u542f\u7528\u3002

      accessibilityServiceEnabled()\n

      \u8fd4\u56de\uff1a True \u6216 False

      "},{"location":"qsl4a/ui/accessibility/#_3","title":"\u5c4f\u5e55\u4ea4\u4e92","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityclick","title":"accessibilityClick()","text":"

      \u5728\u5c4f\u5e55\u5750\u6807\u5904\u70b9\u51fb\u3002

      accessibilityClick(x=0, y=0, t=50)\n

      \u53c2\u6570\uff1a - x (int/float): X \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - y (int/float): Y \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - t (int): \u6309\u4f4f\u65f6\u957f\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a50\uff09

      "},{"location":"qsl4a/ui/accessibility/#accessibilityslide","title":"accessibilitySlide()","text":"

      \u591a\u70b9\u6ed1\u52a8\u624b\u52bf\u3002

      accessibilitySlide(XnYn=None, t=None)\n

      \u53c2\u6570\uff1a - XnYn (list): \u5750\u6807 [X1, Y1, X2, Y2, ... Xn, Yn] - t (int): \u6ed1\u52a8\u65f6\u957f\uff08\u9ed8\u8ba4\uff1a50*n \u6beb\u79d2\uff09

      "},{"location":"qsl4a/ui/accessibility/#_4","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityaction","title":"accessibilityAction()","text":"

      \u6309\u4ee3\u7801\u6267\u884c\u7cfb\u7edf\u64cd\u4f5c\u3002

      accessibilityAction(actionCode)\n

      \u64cd\u4f5c\u4ee3\u7801\uff1a | \u4ee3\u7801 | \u5e38\u91cf | \u63cf\u8ff0 | |------|----------|-------------| | 1 | BACK | \u8fd4\u56de\u6309\u94ae | | 2 | HOME | \u4e3b\u5c4f\u5e55\u6309\u94ae | | 3 | RECENTS | \u6700\u8fd1\u5e94\u7528 | | 4 | NOTIFICATIONS | \u6253\u5f00\u901a\u77e5 | | 5 | QUICK_SETTINGS | \u6253\u5f00\u5feb\u901f\u8bbe\u7f6e | | 6 | POWER_DIALOG | \u7535\u6e90\u83dc\u5355 | | 7 | TOGGLE_SPLIT_SCREEN | \u5206\u5c4f | | 8 | LOCK_SCREEN | \u9501\u5c4f | | 9 | TAKE_SCREENSHOT | \u622a\u56fe | | 10 | KEYCODE_HEADSETHOOK | \u8033\u673a\u6302\u94a9 | | 11-14 | ACCESSIBILITY_ | \u65e0\u969c\u788d\u6309\u94ae | | 15 | DISMISS_NOTIFICATION_SHADE | \u5173\u95ed\u901a\u77e5\u680f | | 16-20 | DPAD_ | \u65b9\u5411\u952e | | 21 | MENU | \u83dc\u5355\u6309\u94ae | | 22 | MEDIA_PLAY_PAUSE | \u64ad\u653e/\u6682\u505c\u5a92\u4f53 |

      "},{"location":"qsl4a/ui/accessibility/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/accessibility/#_6","title":"\u70b9\u51fb\u5c4f\u5e55\u4e2d\u5fc3","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u670d\u52a1\nif not droid.accessibilityServiceEnabled().result:\n    droid.accessibilityStartService()\n\n# \u70b9\u51fb\u4e2d\u5fc3\uff080,0 = \u4e2d\u5fc3\uff09\ndroid.accessibilityClick(0, 0, t=100)\n
      "},{"location":"qsl4a/ui/accessibility/#_7","title":"\u6ed1\u52a8\u624b\u52bf","text":"
      # \u4ece\u4e0b\u5f80\u4e0a\u6ed1\u52a8\uff08\u5411\u4e0a\u6eda\u52a8\uff09\ndroid.accessibilitySlide([0, 1.5, 0, -1.5], t=300)\n
      "},{"location":"qsl4a/ui/accessibility/#_8","title":"\u7cfb\u7edf\u5bfc\u822a","text":"
      # \u6309\u4e3b\u5c4f\u5e55\ndroid.accessibilityAction(2)\n\n# \u6309\u8fd4\u56de\ndroid.accessibilityAction(1)\n\n# \u6253\u5f00\u901a\u77e5\ndroid.accessibilityAction(4)\n
      "},{"location":"qsl4a/ui/accessibility/#_9","title":"\u70b9\u51fb\u7279\u5b9a\u4f4d\u7f6e","text":"
      # \u70b9\u51fb\u5c4f\u5e55\u5750\u6807 (500, 800)\ndroid.accessibilityClick(500, 800)\n\n# \u70b9\u51fb\u76f8\u5bf9\u4f4d\u7f6e\uff08\u6c34\u5e73\u5c45\u4e2d\uff0c\u5782\u76f4 3/4 \u5904\uff09\ndroid.accessibilityClick(0, 1.5)\n
      "},{"location":"qsl4a/ui/dialogs/","title":"\u5bf9\u8bdd\u6846\u7cfb\u7edf","text":"

      QSL4A \u63d0\u4f9b\u5168\u9762\u7684\u5bf9\u8bdd\u6846\u652f\u6301\uff0c\u7528\u4e8e\u7528\u6237\u4ea4\u4e92\uff0c\u5305\u62ec\u8b66\u62a5\u3001\u8f93\u5165\u5bf9\u8bdd\u6846\u3001\u9009\u62e9\u5bf9\u8bdd\u6846\u548c\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

      "},{"location":"qsl4a/ui/dialogs/#_2","title":"\u8b66\u62a5\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowalert","title":"dialogShowAlert()","text":"

      \u663e\u793a\u7b80\u5355\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

      dialogShowAlert(title=\"Alert\", message=\"The message of the alert.\",\n                positiveButtonText=\"OK\", negativeButtonText=None,\n                neutralButtonText=None, messageIsHtml=False)\n

      \u53c2\u6570\uff1a - title (str): \u5bf9\u8bdd\u6846\u6807\u9898 - message (str): \u6d88\u606f\u6587\u672c - positiveButtonText (str): \u80af\u5b9a\u6309\u94ae\u6807\u7b7e - negativeButtonText (str, optional): \u5426\u5b9a\u6309\u94ae\u6807\u7b7e - neutralButtonText (str, optional): \u4e2d\u6027\u6309\u94ae\u6807\u7b7e - messageIsHtml (bool): \u5c06\u6d88\u606f\u89e3\u6790\u4e3a HTML

      \u8fd4\u56de\uff1a \u5305\u542b\u70b9\u51fb\u6309\u94ae\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#dialogshowsimplechoice","title":"dialogShowSimpleChoice()","text":"

      \u663e\u793a\u5e26\u6709\u9879\u76ee\u7684\u7b80\u5355\u9009\u62e9\u5bf9\u8bdd\u6846\u3002

      dialogShowSimpleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

      \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868

      \u8fd4\u56de\uff1a \u5305\u542b\u9009\u4e2d\u9879\u76ee\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#_3","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialoggetinput","title":"dialogGetInput()","text":"

      \u83b7\u53d6\u7528\u6237\u6587\u672c\u8f93\u5165\u3002

      dialogGetInput(title=\"Value\", message=\"Please enter value:\",\n               defaultText=None, messageIsHtml=False)\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7528\u6237\u8f93\u5165\u6587\u672c\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#dialoggetpassword","title":"dialogGetPassword()","text":"

      \u83b7\u53d6\u5bc6\u7801\u8f93\u5165\u3002

      dialogGetPassword(title=\"Password\", message=\"Please enter password:\")\n

      \u8fd4\u56de\uff1a \u5305\u542b\u8f93\u5165\u5bc6\u7801\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#dialogcreateinput","title":"dialogCreateInput()","text":"

      \u521b\u5efa\u81ea\u5b9a\u4e49\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

      dialogCreateInput(title=\"Value\", message=\"Please enter value:\",\n                  defaultText=None, inputType=None)\n

      \u53c2\u6570\uff1a - inputType (str): \u8f93\u5165\u7c7b\u578b\uff08\u4f8b\u5982 \"text\"\u3001\"number\"\u3001\"textPassword\"\uff09

      "},{"location":"qsl4a/ui/dialogs/#dialogcreatepassword","title":"dialogCreatePassword()","text":"

      \u521b\u5efa\u5bc6\u7801\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

      dialogCreatePassword(title=\"Password\", message=\"Please enter password:\")\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreateseekbar","title":"dialogCreateSeekBar()","text":"

      \u521b\u5efa\u6ed1\u5757/\u8fdb\u5ea6\u6761\u5bf9\u8bdd\u6846\u3002

      dialogCreateSeekBar(starting_value=50, maximum_value=100, title=\"\", message=\"\")\n

      \u53c2\u6570\uff1a - starting_value (int): \u521d\u59cb\u503c - maximum_value (int): \u6700\u5927\u503c

      "},{"location":"qsl4a/ui/dialogs/#_4","title":"\u9009\u62e9\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowsinglechoice","title":"dialogShowSingleChoice()","text":"

      \u663e\u793a\u5355\u9009\uff08\u5355\u9009\u6309\u94ae\uff09\u5bf9\u8bdd\u6846\u3002

      dialogShowSingleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, selected=-1, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

      \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (int): \u9ed8\u8ba4\u9009\u4e2d\u7d22\u5f15

      "},{"location":"qsl4a/ui/dialogs/#dialogshowmultichoice","title":"dialogShowMultiChoice()","text":"

      \u663e\u793a\u591a\u9009\uff08\u590d\u9009\u6846\uff09\u5bf9\u8bdd\u6846\u3002

      dialogShowMultiChoice(title=\"Alert\", message=\"The message of the alert.\",\n                      items=None, selected=None, positiveButtonText=\"OK\",\n                      negativeButtonText=None, neutralButtonText=None,\n                      messageIsHtml=False)\n

      \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (list): \u521d\u59cb\u9009\u4e2d\u7d22\u5f15\u5217\u8868

      "},{"location":"qsl4a/ui/dialogs/#dialogsetsinglechoiceitems","title":"dialogSetSingleChoiceItems()","text":"

      \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u5355\u9009\u9879\u76ee\u3002

      dialogSetSingleChoiceItems(items, selected=-1)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmultichoiceitems","title":"dialogSetMultiChoiceItems()","text":"

      \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u591a\u9009\u9879\u76ee\u3002

      dialogSetMultiChoiceItems(items, selected=None)\n
      "},{"location":"qsl4a/ui/dialogs/#_5","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatespinnerprogress","title":"dialogCreateSpinnerProgress()","text":"

      \u521b\u5efa\u4e0d\u786e\u5b9a\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

      dialogCreateSpinnerProgress(title=None, message=None, maximum_progress=100)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreatehorizontalprogress","title":"dialogCreateHorizontalProgress()","text":"

      \u521b\u5efa\u6c34\u5e73\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

      dialogCreateHorizontalProgress(title=None, message=None, maximum_progress=100)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetcurrentprogress","title":"dialogSetCurrentProgress()","text":"

      \u66f4\u65b0\u8fdb\u5ea6\u503c\u3002

      dialogSetCurrentProgress(current)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmaxprogress","title":"dialogSetMaxProgress()","text":"

      \u8bbe\u7f6e\u6700\u5927\u8fdb\u5ea6\u503c\u3002

      dialogSetMaxProgress(max)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetprogressmessage","title":"dialogSetProgressMessage()","text":"

      \u66f4\u65b0\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u6d88\u606f\u3002

      dialogSetProgressMessage(message)\n
      "},{"location":"qsl4a/ui/dialogs/#_6","title":"\u9009\u62e9\u5668\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatedatepicker","title":"dialogCreateDatePicker()","text":"

      \u521b\u5efa\u65e5\u671f\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

      dialogCreateDatePicker(year=1970, month=1, day=1)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreatetimepicker","title":"dialogCreateTimePicker()","text":"

      \u521b\u5efa\u65f6\u95f4\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

      dialogCreateTimePicker(hour=0, minute=0, is24hour=False)\n
      "},{"location":"qsl4a/ui/dialogs/#_7","title":"\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u521b\u5efa","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatealert","title":"dialogCreateAlert()","text":"

      \u521b\u5efa\u81ea\u5b9a\u4e49\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

      dialogCreateAlert(title=None, message=None)\n

      \u521b\u5efa\u4e00\u4e2a\u7a7a\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002\u53ef\u4e0e\u5176\u4ed6 dialogSet* \u51fd\u6570\u4e00\u8d77\u4f7f\u7528\u6765\u81ea\u5b9a\u4e49\u3002

      "},{"location":"qsl4a/ui/dialogs/#dialogsetitems","title":"dialogSetItems()","text":"

      \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u7b80\u5355\u5217\u8868\u9879\u76ee\u3002

      dialogSetItems(items)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetpositivebuttontext","title":"dialogSetPositiveButtonText()","text":"

      \u8bbe\u7f6e\u80af\u5b9a\u6309\u94ae\u6587\u672c\u3002

      dialogSetPositiveButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetnegativebuttontext","title":"dialogSetNegativeButtonText()","text":"

      \u8bbe\u7f6e\u5426\u5b9a\u6309\u94ae\u6587\u672c\u3002

      dialogSetNegativeButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetneutralbuttontext","title":"dialogSetNeutralButtonText()","text":"

      \u8bbe\u7f6e\u4e2d\u6027\u6309\u94ae\u6587\u672c\u3002

      dialogSetNeutralButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmessageishtml","title":"dialogSetMessageIsHtml()","text":"

      \u8bbe\u7f6e\u6d88\u606f\u662f\u5426\u5e94\u89e3\u6790\u4e3a HTML\u3002

      dialogSetMessageIsHtml(messageIsHtml=True)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogshow","title":"dialogShow()","text":"

      \u663e\u793a\u521b\u5efa\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u3002

      dialogShow()\n
      "},{"location":"qsl4a/ui/dialogs/#_8","title":"\u5bf9\u8bdd\u6846\u63a7\u5236","text":""},{"location":"qsl4a/ui/dialogs/#dialogdismiss","title":"dialogDismiss()","text":"

      \u5173\u95ed\u5f53\u524d\u5bf9\u8bdd\u6846\u3002

      dialogDismiss()\n
      "},{"location":"qsl4a/ui/dialogs/#dialoggetresponse","title":"dialogGetResponse()","text":"

      \u83b7\u53d6\u5bf9\u8bdd\u6846\u54cd\u5e94\u3002

      dialogGetResponse()\n
      "},{"location":"qsl4a/ui/dialogs/#dialoggetselecteditems","title":"dialogGetSelectedItems()","text":"

      \u4ece\u9009\u62e9\u5bf9\u8bdd\u6846\u83b7\u53d6\u9009\u4e2d\u7684\u9879\u76ee\u3002

      dialogGetSelectedItems()\n
      "},{"location":"qsl4a/ui/dialogs/#_9","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/dialogs/#_10","title":"\u7b80\u5355\u8b66\u62a5","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a\u8b66\u62a5\ndroid.dialogShowAlert(\"Warning\", \"This is an important message!\")\n
      "},{"location":"qsl4a/ui/dialogs/#_11","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":"
      # \u83b7\u53d6\u7528\u6237\u8f93\u5165\nresult = droid.dialogGetInput(\"Name\", \"Enter your name:\", \"John\").result\nprint(f\"Hello, {result}!\")\n
      "},{"location":"qsl4a/ui/dialogs/#_12","title":"\u5e26\u6309\u94ae\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846","text":"
      # \u521b\u5efa\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\ndroid.dialogCreateAlert(\"Custom\", \"Choose an option\")\ndroid.dialogSetItems([\"Option 1\", \"Option 2\", \"Option 3\"])\ndroid.dialogShow()\n\n# \u83b7\u53d6\u54cd\u5e94\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response['item']}\")\n
      "},{"location":"qsl4a/ui/dialogs/#_13","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":"
      # \u521b\u5efa\u8fdb\u5ea6\u5bf9\u8bdd\u6846\ndroid.dialogCreateHorizontalProgress(\"Loading\", \"Please wait...\", 100)\ndroid.dialogShow()\n\n# \u66f4\u65b0\u8fdb\u5ea6\nfor i in range(101):\n    droid.dialogSetCurrentProgress(i)\n    time.sleep(0.05)\n\ndroid.dialogDismiss()\n
      "},{"location":"qsl4a/ui/dialogs/#_14","title":"\u65e5\u671f\u9009\u62e9\u5668","text":"
      # \u663e\u793a\u65e5\u671f\u9009\u62e9\u5668\ndroid.dialogCreateDatePicker(2024, 1, 15)\ndroid.dialogShow()\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response}\")\n
      "},{"location":"qsl4a/ui/floatview/","title":"\u6d6e\u52a8\u89c6\u56fe","text":"

      \u6d6e\u52a8\u7a97\u53e3\u652f\u6301\uff0c\u7528\u4e8e\u5728\u5176\u4ed6\u5e94\u7528\u7a0b\u5e8f\u4e0a\u65b9\u4fdd\u6301\u663e\u793a\u7684\u8986\u76d6 UI \u5143\u7d20\u3002

      "},{"location":"qsl4a/ui/floatview/#_2","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/floatview/#floatview","title":"floatView()","text":"

      \u663e\u793a\u6216\u4fee\u6539\u6d6e\u52a8\u89c6\u56fe\u3002

      floatView(Args=None)\n

      \u53c2\u6570\uff1a - Args (dict): \u914d\u7f6e\u5b57\u5178\uff0c\u5305\u542b\u4ee5\u4e0b\u952e\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08-1 \u521b\u5efa\u65b0\u7684\uff0c>=0 \u4fee\u6539\u73b0\u6709\u7684\uff09 - text (str): \u8981\u663e\u793a\u7684\u6587\u672c\u5185\u5bb9 - html (str): HTML \u5185\u5bb9\uff08\u5982\u679c\u7701\u7565 text \u5219\u4f7f\u7528\uff09 - width (int): \u89c6\u56fe\u5bbd\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a300\uff09 - height (int): \u89c6\u56fe\u9ad8\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a150\uff09 - x (int): X \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - y (int): Y \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - backColor (str): ARGB \u5341\u516d\u8fdb\u5236\u80cc\u666f\u8272\uff08\u9ed8\u8ba4\uff1a'7f7f7f7f'\uff09 - textColor (str): ARGB \u5341\u516d\u8fdb\u5236\u6587\u672c\u8272\uff08\u9ed8\u8ba4\uff1a'ff000000'\uff09 - textSize (int): \u6587\u672c\u5927\u5c0f\uff08\u9ed8\u8ba4\uff1a10\uff09 - textAlign (int): \u6587\u672c\u5bf9\u9f50\uff080 = \u7ee7\u627f\uff09 - script (str): \u957f\u6309\u5173\u95ed\u540e\u8fd0\u884c\u7684\u811a\u672c\u8def\u5f84 - arg: \u811a\u672c\u53c2\u6570 - clickRemove (bool): \u542f\u7528\u70b9\u51fb\u79fb\u9664\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - flag (int): \u7a97\u53e3\u6807\u5fd7\uff08\u9ed8\u8ba4\uff1a40 - \u53ef\u89e6\u6478\uff09

      \u8fd4\u56de\uff1a \u5f53\u524d\u94fe\u5217\u8868\u957f\u5ea6

      "},{"location":"qsl4a/ui/floatview/#floatviewcount","title":"floatViewCount()","text":"

      \u83b7\u53d6\u6d3b\u52a8\u6d6e\u52a8\u89c6\u56fe\u7684\u6570\u91cf\u3002

      floatViewCount()\n

      \u8fd4\u56de\uff1a \u6d6e\u52a8\u89c6\u56fe\u6570\u91cf

      "},{"location":"qsl4a/ui/floatview/#floatviewresult","title":"floatViewResult()","text":"

      \u83b7\u53d6\u6d6e\u52a8\u89c6\u56fe\u7684\u7ed3\u679c/\u72b6\u6001\u3002

      floatViewResult(index=-1)\n

      \u53c2\u6570\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1\uff0c\u8fd4\u56de\u6700\u540e\u64cd\u4f5c\u7ed3\u679c\uff09

      \u8fd4\u56de\uff1a \u5305\u542b\u64cd\u4f5c\u8be6\u60c5\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - x, y: \u4f4d\u7f6e - time: \u65f6\u95f4\u6233 - operation: \u64cd\u4f5c\u7c7b\u578b\uff08'initial'\u3001'move' \u7b49\uff09 - index: \u89c6\u56fe\u7d22\u5f15 - removed: \u5982\u679c\u89c6\u56fe\u88ab\u79fb\u9664\u5219\u4e3a True

      "},{"location":"qsl4a/ui/floatview/#floatviewremove","title":"floatViewRemove()","text":"

      \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\u3002

      floatViewRemove(index=-1)\n

      \u53c2\u6570\uff1a - index (int): \u8981\u79fb\u9664\u7684\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1 \u79fb\u9664\u6700\u540e\u4e00\u4e2a\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a 1\uff0c\u5426\u5219\u4e3a 0

      "},{"location":"qsl4a/ui/floatview/#_3","title":"\u5e38\u91cf","text":"
      • floatView.INDEX_NEW = -1 - \u521b\u5efa\u65b0\u7684\u6d6e\u52a8\u89c6\u56fe
      • floatView.FLAG_DEFAULT_TOUCHABLE = 40 - \u9ed8\u8ba4\u53ef\u89e6\u6478\u6807\u5fd7
      • floatView.TEXT_ALIGNMENT_INHERIT = 0
      • floatView.TEXT_ALIGNMENT_CENTER - \u5c45\u4e2d\u6587\u672c\u5bf9\u9f50
      "},{"location":"qsl4a/ui/floatview/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/floatview/#_5","title":"\u57fa\u672c\u6d6e\u52a8\u89c6\u56fe","text":"
      import androidhelper\nfrom androidhelper import Android\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u7b80\u5355\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'index': -1,  # \u521b\u5efa\u65b0\u7684\n    'text': 'Hello World',\n    'width': 400,\n    'height': 300,\n    'x': -300,  # \u4ece\u4e2d\u5fc3\u504f\u79fb\n    'y': -400,\n    'backColor': 'ff0000',  # \u7ea2\u8272\u80cc\u666f\n    'textColor': '0000ff',  # \u84dd\u8272\u6587\u672c\n    'textSize': 16,\n    'textAlign': droid.floatView.TEXT_ALIGNMENT_CENTER\n})\n\n# \u68c0\u67e5\u6570\u91cf\nprint(f\"Float views: {droid.floatViewCount().result}\")\n\n# \u83b7\u53d6\u7ed3\u679c\nresult = droid.floatViewResult().result\nprint(f\"View info: {result}\")\n\n# \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\ndroid.floatViewRemove(0)\n
      "},{"location":"qsl4a/ui/floatview/#html","title":"HTML \u5185\u5bb9","text":"
      # \u521b\u5efa\u5e26 HTML \u5185\u5bb9\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': '',  # \u7a7a\u6587\u672c\u4ee5\u4f7f\u7528 HTML\n    'html': '<h1>Title</h1><p>Rich <b>HTML</b> content</p>',\n    'width': 500,\n    'height': 400\n})\n
      "},{"location":"qsl4a/ui/floatview/#_6","title":"\u4fee\u6539\u73b0\u6709\u89c6\u56fe","text":"
      # \u521b\u5efa\u521d\u59cb\u89c6\u56fe\ndroid.floatView({'text': 'Initial Text', 'width': 300, 'height': 150})\n\n# \u4fee\u6539\u540c\u4e00\u89c6\u56fe\uff08\u7d22\u5f15 0\uff09\ndroid.floatView({\n    'index': 0,\n    'text': 'Updated Text!',\n    'backColor': '7f00ff00'  # \u7eff\u8272\u80cc\u666f\n})\n\n# \u68c0\u67e5\u79fb\u52a8/\u66f4\u6539\u7ed3\u679c\nresult = droid.floatViewResult(0).result\nprint(f\"Operation: {result.get('operation')}, Position: ({result.get('x')}, {result.get('y')})\")\n
      "},{"location":"qsl4a/ui/floatview/#_7","title":"\u591a\u4e2a\u6d6e\u52a8\u89c6\u56fe","text":"
      # \u521b\u5efa\u591a\u4e2a\u89c6\u56fe\nfor i in range(3):\n    droid.floatView({\n        'index': -1,\n        'text': f'View {i}',\n        'x': i * 100 - 150,\n        'y': i * 100 - 150,\n        'backColor': f'{i}f{i}f{i}f'\n    })\n\nprint(f\"Total views: {droid.floatViewCount().result}\")\n\n# \u79fb\u9664\u6240\u6709\u89c6\u56fe\nwhile droid.floatViewCount().result > 0:\n    droid.floatViewRemove()\n
      "},{"location":"qsl4a/ui/floatview/#_8","title":"\u5e26\u811a\u672c\u56de\u8c03","text":"
      # \u521b\u5efa\u5173\u95ed\u65f6\u8fd0\u884c\u811a\u672c\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': 'Click to close and run script',\n    'script': '/sdcard/my_script.py',\n    'arg': 'hello from float view',\n    'clickRemove': True\n})\n
      "},{"location":"qsl4a/ui/fullscreen/","title":"\u5168\u5c4f UI","text":"

      \u4f7f\u7528\u539f\u751f Android \u5e03\u5c40\u521b\u5efa\u81ea\u5b9a\u4e49\u5168\u5c4f\u754c\u9762\u3002

      "},{"location":"qsl4a/ui/fullscreen/#_1","title":"\u5e03\u5c40\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullshow","title":"fullShow()","text":"

      \u663e\u793a\u5168\u5c4f\u5e03\u5c40\u3002

      fullShow(layout, title=None, theme=None)\n

      \u53c2\u6570\uff1a - layout (str): JSON \u5e03\u5c40\u5b9a\u4e49\u6216\u5e03\u5c40\u5b57\u7b26\u4e32 - title (str, optional): \u7a97\u53e3\u6807\u9898 - theme (str, optional): \u4e3b\u9898\u540d\u79f0

      \u8fd4\u56de\uff1a \u7a97\u53e3 ID

      "},{"location":"qsl4a/ui/fullscreen/#fulldismiss","title":"fullDismiss()","text":"

      \u5173\u95ed\u5168\u5c4f\u7a97\u53e3\u3002

      fullDismiss()\n
      "},{"location":"qsl4a/ui/fullscreen/#fullquery","title":"fullQuery()","text":"

      \u67e5\u8be2\u6240\u6709\u5c0f\u90e8\u4ef6\u503c\u3002

      fullQuery()\n

      \u8fd4\u56de\uff1a \u5c0f\u90e8\u4ef6 ID \u548c\u503c\u7684\u5b57\u5178

      "},{"location":"qsl4a/ui/fullscreen/#fullquerydetail","title":"fullQueryDetail()","text":"

      \u67e5\u8be2\u7279\u5b9a\u5c0f\u90e8\u4ef6\u8be6\u60c5\u3002

      fullQueryDetail(id)\n
      "},{"location":"qsl4a/ui/fullscreen/#_2","title":"\u5c5e\u6027\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperty","title":"fullGetProperty()","text":"

      \u83b7\u53d6\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

      fullGetProperty(id, property)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetproperty","title":"fullSetProperty()","text":"

      \u8bbe\u7f6e\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

      fullSetProperty(id, property, value)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetlist","title":"fullSetList()","text":"

      \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

      fullSetList(id, list, isHtml=False, listType=0)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetlist2","title":"fullSetList2()","text":"

      \u4f7f\u7528\u8d44\u6e90 ID \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

      fullSetList2(id, list, intRes)\n

      \u53c2\u6570\uff1a - id (str): \u5c0f\u90e8\u4ef6 ID - list (list): \u9879\u76ee\u5217\u8868 - intRes (int): \u5217\u8868\u9879\u76ee\u5e03\u5c40\u7684 Android \u8d44\u6e90 ID

      "},{"location":"qsl4a/ui/fullscreen/#fullsetlistselected","title":"fullSetListSelected()","text":"

      \u5728\u5217\u8868\u4e2d\u8bbe\u7f6e\u9009\u4e2d\u9879\u76ee\u3002

      fullSetListSelected(id, selected)\n

      \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID - selected (int): \u8981\u9009\u4e2d\u7684\u9879\u76ee\u7d22\u5f15

      "},{"location":"qsl4a/ui/fullscreen/#fullgetlistselected","title":"fullGetListSelected()","text":"

      \u83b7\u53d6\u5f53\u524d\u9009\u4e2d\u7684\u5217\u8868\u9879\u76ee\u7d22\u5f15\u3002

      fullGetListSelected(id)\n

      \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID

      \u8fd4\u56de\uff1a \u9009\u4e2d\u9879\u76ee\u7d22\u5f15

      "},{"location":"qsl4a/ui/fullscreen/#_3","title":"\u6279\u91cf\u5c5e\u6027\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperties","title":"fullGetProperties()","text":"

      \u4e00\u6b21\u83b7\u53d6\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

      fullGetProperties(ids, property)\n

      \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u83b7\u53d6\u7684\u5c5e\u6027\u540d

      \u8fd4\u56de\uff1a \u6620\u5c04\u5c0f\u90e8\u4ef6 ID \u5230\u5c5e\u6027\u503c\u7684\u5b57\u5178

      "},{"location":"qsl4a/ui/fullscreen/#fullsetproperties","title":"fullSetProperties()","text":"

      \u4e00\u6b21\u8bbe\u7f6e\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

      fullSetProperties(ids, property, value)\n

      \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u8bbe\u7f6e\u7684\u5c5e\u6027\u540d - value: \u5c5e\u6027\u503c

      "},{"location":"qsl4a/ui/fullscreen/#_4","title":"\u622a\u56fe","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetscreenshot","title":"fullGetScreenShot()","text":"

      \u6355\u83b7\u5168\u5c4f\u622a\u56fe\u3002

      fullGetScreenShot(path=None)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u5728\u4e8b\u4ef6\u4e2d\u8fd4\u56de

      \u8fd4\u56de\uff1a \u5305\u542b\u622a\u56fe\u6570\u636e\u7684\u4e8b\u4ef6

      "},{"location":"qsl4a/ui/fullscreen/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b9a\u4e49\u5e03\u5c40\nlayout = '''\n{ \"type\": \"LinearLayout\", \"orientation\": \"vertical\",\n  \"children\": [\n    { \"type\": \"TextView\", \"id\": \"title\", \"text\": \"Hello\" },\n    { \"type\": \"Button\", \"id\": \"btn\", \"text\": \"Click Me\" }\n  ]\n}\n'''\n\n# \u663e\u793a\u5e03\u5c40\ndroid.fullShow(layout, \"My App\")\n\n# \u67e5\u8be2\u6309\u94ae\u70b9\u51fb\nevent = droid.eventWaitFor('click', timeout=10)\nif event.result:\n    widget_id = event.result['data']['id']\n    if widget_id == 'btn':\n        print(\"Button clicked!\")\n\ndroid.fullDismiss()\n
      "}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"QPython \u9879\u76ee","text":"

      QPython \u4e0d\u4ec5\u662f\u4e00\u4e2a\u5f3a\u5927\u7684 Android Python IDE\uff0c\u4e5f\u662f\u4e00\u4e2a\u6d3b\u8dc3\u7684\u6280\u672f\u793e\u533a\u3002

      "},{"location":"#ai-android-python-ide","title":"\u652f\u6301 AI \u7684 Android Python IDE","text":"

      QPython \u662f\u60a8\u8fdb\u884c Android Python \u7f16\u7a0b\u7684\u5165\u53e3\u3002\u5b83\u96c6\u6210\u4e86 Python \u89e3\u91ca\u5668\u3001AI \u6a21\u578b\u5f15\u64ce\u548c\u79fb\u52a8\u5f00\u53d1\u5de5\u5177\u94fe\uff0c\u8ba9\u60a8\u80fd\u591f\u4ece\u79fb\u52a8\u8bbe\u5907\u6784\u5efa Web \u5e94\u7528\u7a0b\u5e8f\u3001\u6267\u884c\u79d1\u5b66\u8ba1\u7b97\u548c\u521b\u5efa\u667a\u80fd\u5e94\u7528\u3002

      \u65e0\u8bba\u60a8\u662f\u5728\u5b66\u4e60\u7f16\u7a0b\u3001\u6784\u5efa\u6570\u636e\u79d1\u5b66\u9879\u76ee\uff0c\u8fd8\u662f\u5f00\u53d1 AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f\uff0cQPython \u90fd\u63d0\u4f9b\u4e86\u5b8c\u6574\u7684\u79fb\u52a8\u7f16\u7a0b\u89e3\u51b3\u65b9\u6848\uff0c\u62e5\u6709\u5168\u9762\u7684\u5f00\u53d1\u8005\u8d44\u6e90\u548c\u6d3b\u8dc3\u7684\u793e\u533a\u6765\u652f\u6301\u60a8\u7684\u65c5\u7a0b\u3002

      • \u5206\u652f\u7248\u672c \u2013 \u4e86\u89e3\u4e0d\u540c\u7684 QPython \u7248\u672c\uff08IDE\u3001\u793e\u533a\u7248\u3001Plus\uff09\uff0c\u9009\u62e9\u9002\u5408\u60a8\u9700\u6c42\u7684\u7248\u672c
      • \u66f4\u65b0\u65e5\u5fd7 \u2013 \u968f\u65f6\u4e86\u89e3\u6700\u65b0\u529f\u80fd\u3001\u6539\u8fdb\u548c\u53d1\u884c\u8bf4\u660e
      "},{"location":"#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"

      \u5982\u4f55\u5feb\u901f\u5165\u95e8\uff1f\u8bf7\u6309\u7167\u4ee5\u4e0b\u6b65\u9aa4\uff1a

      • \u5feb\u901f\u5165\u95e8
      • Hello World \u6559\u7a0b
      "},{"location":"#_2","title":"\u7f16\u7a0b\u6307\u5357","text":"

      QPython \u4e0d\u4ec5\u63d0\u4f9b\u57fa\u7840\u7684 Python \u63a5\u53e3\u652f\u6301\uff0c\u66f4\u91cd\u8981\u7684\u662f\uff0c\u5b83\u8fd8\u5141\u8bb8\u60a8\u901a\u8fc7 QSL4A \u63a5\u53e3\u4f7f\u7528 Python \u8c03\u7528 Android API\u3002

      • Python \u6807\u51c6\u5e93 \u2013 \u901a\u7528\u7684 Python \u8bed\u6cd5\u548c\u5185\u7f6e\u5e93
      • QSL4A API \u2013 \u4ece Python \u8bbf\u95ee Android \u8bbe\u5907\u529f\u80fd\uff08\u76f8\u673a\u3001\u4f20\u611f\u5668\u3001\u77ed\u4fe1\u7b49\uff09
      • QPYPI \u6307\u5357 \u2013 \u5b89\u88c5\u989d\u5916\u7684 Python \u5305
      • \u7f16\u8f91\u5668\u6307\u5357 \u2013 \u4f7f\u7528\u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668
      • \u5916\u90e8 API \u2013 \u4e0e\u5916\u90e8\u5e94\u7528\u7a0b\u5e8f\u96c6\u6210
      "},{"location":"#_3","title":"\u4e0b\u8f7d\u8d44\u6e90","text":"
      • Google Drive
      • \u5fae\u4fe1\u7f51\u76d8
      "},{"location":"#_4","title":"\u793e\u533a\u4e0e\u53cd\u9988","text":"
      • \u4e2d\u6587\u4ea4\u6d41\u793e\u533a
      • \u95ee\u9898\u53cd\u9988
      • \u529f\u80fd\u6269\u5c55\u8bf7\u6c42
      "},{"location":"#_5","title":"\u5173\u6ce8\u6211\u4eec","text":"
      • B\u7ad9
      • Weibo
      "},{"location":"AIPyApp/","title":"AIPyApp - AI\u9a71\u52a8\u7684\u7a0b\u5e8f\u751f\u6210\u5668","text":"

      AIPyApp \u662f QPython \u4e2d\u7684\u667a\u80fd\u5de5\u5177\uff0c\u53ef\u4ee5\u5229\u7528 AI \u4ece\u81ea\u7136\u8bed\u8a00\u6307\u4ee4\u81ea\u52a8\u751f\u6210 Python \u7a0b\u5e8f\u3002

      "},{"location":"AIPyApp/#_1","title":"\u6982\u8ff0","text":"

      AIPyApp \u6539\u53d8\u4e86\u60a8\u7f16\u5199\u4ee3\u7801\u7684\u65b9\u5f0f\u2014\u2014\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u63cf\u8ff0\u60a8\u60f3\u8981\u7684\u529f\u80fd\uff0cAI \u5c31\u4f1a\u4e3a\u60a8\u751f\u6210 Python \u7a0b\u5e8f\u3002QPython \u8fd8\u5c06\u63a8\u51fa AIPy Academy\u2014\u2014\u4e00\u4e2a\u4e3a AI \u65f6\u4ee3\u91cf\u8eab\u5b9a\u5236\u7684 Python \u7f16\u7a0b\u8bfe\u7a0b\u5e73\u53f0\u3002

      "},{"location":"AIPyApp/#_2","title":"\u5b89\u88c5","text":"

      QPython \u6c1b\u56f4\u7f16\u7a0b\uff08Vibe Coding\uff09 01 - \u5982\u4f55\u542f\u7528AIPyApp

      "},{"location":"AIPyApp/#_3","title":"\u7b2c\u4e00\u6b65\uff1a\u4ece\u4eea\u8868\u76d8\u542f\u52a8","text":"
      1. \u6253\u5f00 QPython\uff0c\u8fdb\u5165 \u4eea\u8868\u76d8
      2. \u957f\u6309\u5f00\u59cb\u6309\u94ae

      \u5982\u679c\u672a\u5b89\u88c5 AIPyApp\uff0c\u7cfb\u7edf\u4f1a\u63d0\u793a\u60a8\u786e\u8ba4\u5b89\u88c5\u3002\u6309 \u56de\u8f66\u952e\u7ee7\u7eed\u3002

      QPython \u5c06\u81ea\u52a8\u4ece PYPI \u4e0b\u8f7d\u5e76\u5b89\u88c5\u6240\u9700\u7684\u4f9d\u8d56\u9879\u3002\u8bf7\u8010\u5fc3\u7b49\u5f85\u5b89\u88c5\u5b8c\u6210\u3002

      "},{"location":"AIPyApp/#aipyapp","title":"\u7b2c\u4e8c\u6b65\uff1a\u91cd\u65b0\u542f\u52a8 AIPyApp","text":"

      \u5b89\u88c5\u5b8c\u6210\u540e\uff0c\u8fd4\u56de QPython \u4eea\u8868\u76d8\uff0c\u518d\u6b21 \u957f\u6309\u5f00\u59cb\u6309\u94ae\u542f\u52a8 AIPyApp\u3002

      "},{"location":"AIPyApp/#_4","title":"\u914d\u7f6e","text":""},{"location":"AIPyApp/#ai","title":"\u8bbe\u7f6e\u60a8\u7684 AI \u5bc6\u94a5","text":"

      \u9996\u6b21\u542f\u52a8\u65f6\uff0c\u60a8\u9700\u8981\u63d0\u4f9b AI API \u5bc6\u94a5\uff1a

      1. \u5728 PGPT \u6ce8\u518c\uff1a\u5728 https://user.pgpt.cloud \u521b\u5efa\u8d26\u6237\u4ee5\u751f\u6210\u60a8\u7684 AI \u5bc6\u94a5
      2. \u9ad8\u7ea7\u9009\u9879\uff1aAIPyApp \u8fd8\u652f\u6301\u6765\u81ea OpenAI\u3001Deepseek \u548c\u5176\u4ed6\u63d0\u4f9b\u5546\u7684\u81ea\u5b9a\u4e49 AI \u5bc6\u94a5\uff08\u8be6\u89c1\u9ad8\u7ea7\u6559\u7a0b\uff09
      "},{"location":"AIPyApp/#ai_1","title":"\u8f93\u5165\u60a8\u7684 AI \u5bc6\u94a5","text":"
      1. \u957f\u6309\u8f93\u5165\u63d0\u793a
      2. \u4ece\u5f39\u51fa\u83dc\u5355\u4e2d\u9009\u62e9 \u7c98\u8d34
      3. \u6309 \u56de\u8f66\u952e\u786e\u8ba4

      \u60a8\u7684 AI \u5bc6\u94a5\u5c06\u4fdd\u5b58\u4ee5\u4f9b\u540e\u7eed\u4f1a\u8bdd\u4f7f\u7528\u3002

      "},{"location":"AIPyApp/#aipyapp_1","title":"\u4f7f\u7528 AIPyApp","text":"

      \u914d\u7f6e\u5b8c\u6210\u540e\uff0c\u60a8\u5c06\u8fdb\u5165 AIPyApp \u63a7\u5236\u53f0\u6a21\u5f0f\u3002\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u8f93\u5165\u60a8\u7684\u6307\u4ee4\u5373\u53ef\uff01

      "},{"location":"AIPyApp/#_5","title":"\u793a\u4f8b\u547d\u4ee4","text":"

      \u5c1d\u8bd5\u8f93\u5165\uff1a

      \u4f7f\u7528 QSL4A \u521b\u5efa\u4e00\u4e2a HELLO QPY \u7a0b\u5e8f\u4f5c\u4e3a\u6f14\u793a\n

      AIPyApp \u5c06\uff1a 1. \u7406\u89e3\u60a8\u7684\u81ea\u7136\u8bed\u8a00\u8bf7\u6c42 2. \u751f\u6210\u76f8\u5e94\u7684 Python \u4ee3\u7801 3. \u81ea\u52a8\u6267\u884c\u7a0b\u5e8f

      \u5c31\u662f\u8fd9\u6837\u2014\u2014\u60a8\u65e0\u9700\u7f16\u5199\u4efb\u4f55\u4ee3\u7801\u5c31\u521b\u5efa\u4e86\u4e00\u4e2a\u53ef\u8fd0\u884c\u7684 Python \u7a0b\u5e8f\uff01

      "},{"location":"AIPyApp/#_6","title":"\u6f14\u793a\u89c6\u9891","text":"

      QPython \u6c1b\u56f4\u7f16\u7a0b\uff08Vibe Coding\uff09 02 - \u4f7f\u7528\u81ea\u7136\u8bed\u8a00\u5f00\u53d1\u4e00\u4e2a\u7ffb\u8bd1App

      \u4e0a\u9762\u7684\u793a\u4f8b\u6f14\u793a\u4e86 AIPyApp \u5982\u4f55\uff1a - \u7406\u89e3\u4e2d\u6587\u6307\u4ee4 - \u751f\u6210\u57fa\u4e8e QSL4A \u7684 Python \u4ee3\u7801 - \u7acb\u5373\u8fd0\u884c\u7a0b\u5e8f

      \u63a2\u7d22 AIPyApp \u4ee5\u53d1\u73b0\u66f4\u591a\u529f\u80fd\uff0c\u5f00\u59cb\u8f7b\u677e\u6784\u5efa Python \u7a0b\u5e8f\u3002

      "},{"location":"AIPyApp/#_7","title":"\u8bfe\u7a0b\u63a8\u8350","text":"

      \u672b\u5c3e\uff0c\u7ed9\u5927\u5bb6\u63a8\u8350\u4e0b\u9762\u8bfe\u7a0b\uff1a

      \u300a\u4e0eAI\u534f\u4f5c\u7684Python\u7f16\u7a0b\u5165\u95e8\u300b \u2014 \u7531QPython\u5b98\u65b9\u56e2\u961f\u7cbe\u5fc3\u6253\u9020\u5e76\u63d0\u4f9b\u6559\u5b66\u652f\u6301\uff0c\u80fd\u5e2e\u52a9\u5b66\u4e60\u8005\u5feb\u901f\u3001\u4f53\u7cfb\u5316\u5730\u638c\u63e1Python\u5f00\u53d1\u4ee5\u53ca\u5728AI\u65f6\u4ee3\u66f4\u597d\u5730\u5b66\u4e60\u4f7f\u7528AI\u3002

      \u4e86\u89e3\u8be6\u60c5

      "},{"location":"GraphicalInterface/","title":"\u56fe\u5f62\u754c\u9762\uff08Turtle \u548c Tkinter\uff09","text":"

      \u672c\u6307\u5357\u8bf4\u660e\u5982\u4f55\u5728 Android \u8bbe\u5907\u4e0a\u7684 QPython \u4e2d\u542f\u7528\u56fe\u5f62\u754c\u9762\u652f\u6301\uff08Turtle \u548c Tkinter\uff09\u3002

      "},{"location":"GraphicalInterface/#_1","title":"\u6982\u8ff0","text":"

      QPython \u53ef\u4ee5\u8fd0\u884c Turtle \u548c Tkinter \u5e94\u7528\u7a0b\u5e8f\uff0c\u4f46\u9700\u8981\u989d\u5916\u7684\u8f6f\u4ef6\u6765\u5728 Android \u4e0a\u63d0\u4f9b\u56fe\u5f62\u663e\u793a\u652f\u6301\u3002

      "},{"location":"GraphicalInterface/#_2","title":"\u524d\u63d0\u6761\u4ef6","text":"

      \u5f00\u59cb\u4e4b\u524d\uff0c\u60a8\u9700\u8981\u4e0b\u8f7d\u4ee5\u4e0b\u8d44\u6e90\uff1a

      1. Xserver.apk - \u63d0\u4f9b Turtle/Tkinter \u56fe\u5f62\u652f\u6301\u7684\u914d\u5957\u5e94\u7528
      2. \u4e0b\u8f7d\u5730\u5740\uff1aQPythonProject/Extra on Google Drive
      3. Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762\u6269\u5c55 - \u901a\u8fc7 QPython \u7684 QPYPI \u5b89\u88c5
      "},{"location":"GraphicalInterface/#_3","title":"\u5b89\u88c5\u6b65\u9aa4","text":""},{"location":"GraphicalInterface/#xserver","title":"\u7b2c\u4e00\u6b65\uff1a\u5b89\u88c5 Xserver","text":"

      \u4ece Google Drive \u7684 QPython Extra \u8d44\u6e90\u76ee\u5f55\u4e0b\u8f7d\u5e76\u5b89\u88c5 Xserver.apk\u3002

      "},{"location":"GraphicalInterface/#qpython","title":"\u7b2c\u4e8c\u6b65\uff1a\u5b89\u88c5 QPython \u6269\u5c55","text":"

      \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI\u3002\u627e\u5230\u5e76\u5b89\u88c5 Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762 \u6269\u5c55\u3002

      "},{"location":"GraphicalInterface/#xserver_1","title":"\u7b2c\u4e09\u6b65\uff1a\u914d\u7f6e Xserver \u7535\u6c60\u8bbe\u7f6e","text":"

      \u4e3a\u9632\u6b62 Xserver \u5728\u540e\u53f0\u8fd0\u884c\u65f6\u88ab\u6740\u6b7b\uff1a

      1. \u8fdb\u5165\u8bbe\u5907\u7684 \u8bbe\u7f6e > \u5e94\u7528 > Xserver
      2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
      3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u6216 \"\u4e0d\u9650\u5236\"

      \u8fd9\u53ef\u786e\u4fdd Xserver \u5728\u5207\u6362\u5230\u540e\u53f0\u65f6\u7ee7\u7eed\u8fd0\u884c\u3002

      "},{"location":"GraphicalInterface/#qpython_1","title":"\u7b2c\u56db\u6b65\uff1a\u914d\u7f6e QPython \u7535\u6c60\u8bbe\u7f6e\uff08\u63a8\u8350\uff09","text":"

      \u540c\u6837\uff0c\u5c06 QPython \u7684\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u4ee5\u9632\u6b62\u8fdb\u7a0b\u88ab\u7ec8\u6b62\uff1a

      1. \u8fdb\u5165 \u8bbe\u7f6e > \u5e94\u7528 > QPython
      2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
      3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\"
      "},{"location":"GraphicalInterface/#xserver_2","title":"\u7b2c\u4e94\u6b65\uff1a\u542f\u52a8 Xserver","text":"

      \u5728\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d\uff0c\u542f\u52a8 Xserver \u5e94\u7528\u5e76\u5c06\u5176\u5207\u6362\u4e3a\u540e\u53f0\u8fd0\u884c\u3002

      "},{"location":"GraphicalInterface/#turtletkinter","title":"\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f","text":"

      \u5b8c\u6210\u8bbe\u7f6e\u540e\uff1a

      1. \u786e\u4fdd Xserver \u5728\u540e\u53f0\u8fd0\u884c
      2. \u5728 QPython \u4e2d\u8fd0\u884c\u60a8\u7684 Turtle \u6216 Tkinter \u5e94\u7528\u7a0b\u5e8f
      3. \u5207\u6362\u5230 Xserver \u67e5\u770b\u56fe\u5f62\u8f93\u51fa
      "},{"location":"GraphicalInterface/#_4","title":"\u6f14\u793a\u7a0b\u5e8f","text":"

      \u60a8\u53ef\u4ee5\u4ece QPython \u5e94\u7528\u7684 QPYPI \u7b2c\u4e00\u4e2a\u6269\u5c55\u90e8\u5206\u4e0b\u8f7d\u5e76\u5c1d\u8bd5 Turtle \u753b\u54c6\u5566A\u68a6 \u6f14\u793a\u7a0b\u5e8f\u6765\u9a8c\u8bc1\u60a8\u7684\u8bbe\u7f6e\u3002

      "},{"location":"GraphicalInterface/#_5","title":"\u6f14\u793a\u89c6\u9891","text":""},{"location":"GraphicalInterface/#_6","title":"\u6545\u969c\u6392\u9664","text":"
      • \u9ed1\u5c4f\uff1a\u786e\u4fdd\u5728\u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d Xserver \u6b63\u5728\u8fd0\u884c
      • \u5e94\u7528\u7a0b\u5e8f\u5d29\u6e83\uff1a\u68c0\u67e5 QPython \u548c Xserver \u662f\u5426\u90fd\u8bbe\u7f6e\u4e86\u65e0\u9650\u5236\u7684\u7535\u6c60\u8bbe\u7f6e
      • \u65e0\u663e\u793a\uff1a\u9a8c\u8bc1 Turtle/Tkinter \u6269\u5c55\u662f\u5426\u901a\u8fc7 QPYPI \u6b63\u786e\u5b89\u88c5
      "},{"location":"GraphicalInterface/#_7","title":"\u8bfe\u7a0b\u63a8\u8350","text":"

      \u672b\u5c3e\uff0c\u7ed9\u5927\u5bb6\u63a8\u8350\u4e0b\u9762\u8bfe\u7a0b\uff1a

      \u300a\u4e0eAI\u534f\u4f5c\u7684Python\u7f16\u7a0b\u5165\u95e8\u300b \u2014 \u7531QPython\u5b98\u65b9\u56e2\u961f\u7cbe\u5fc3\u6253\u9020\u5e76\u63d0\u4f9b\u6559\u5b66\u652f\u6301\uff0c\u80fd\u5e2e\u52a9\u5b66\u4e60\u8005\u5feb\u901f\u3001\u4f53\u7cfb\u5316\u5730\u638c\u63e1Python\u5f00\u53d1\u4ee5\u53ca\u5728AI\u65f6\u4ee3\u66f4\u597d\u5730\u5b66\u4e60\u4f7f\u7528AI\u3002

      \u4e86\u89e3\u8be6\u60c5

      "},{"location":"Notebook/","title":"Notebook","text":"

      QPython \u96c6\u6210\u4e86 Jupyter Notebook\uff0c\u63d0\u4f9b\u4e86\u4e00\u4e2a\u5f3a\u5927\u7684\u4ea4\u4e92\u73af\u5883\uff0c\u53ef\u5728 Android \u8bbe\u5907\u4e0a\u8fdb\u884c\u6570\u636e\u79d1\u5b66\u3001\u79d1\u5b66\u8ba1\u7b97\u548c AI \u5f00\u53d1\u3002

      "},{"location":"Notebook/#_1","title":"\u6982\u8ff0","text":"

      QPython \u81ea\u5e26\u5185\u7f6e\u7684 Jupyter Notebook \u5e94\u7528\u7a0b\u5e8f\uff0c\u5141\u8bb8\u60a8\u76f4\u63a5\u5728 Android \u8bbe\u5907\u4e0a\u521b\u5efa\u548c\u8fd0\u884c\u4ea4\u4e92\u5f0f Python \u7b14\u8bb0\u672c\u3002\u754c\u9762\u548c\u64cd\u4f5c\u65b9\u5f0f\u4e0e\u6807\u51c6 Jupyter Notebook \u7c7b\u4f3c\u3002

      "},{"location":"Notebook/#_2","title":"\u53ef\u7528\u5e93","text":"

      QPython \u652f\u6301\u5e7f\u6cdb\u7684\u6570\u5b66\u3001\u79d1\u5b66\u548c AI \u76f8\u5173\u5e93\uff0c\u975e\u5e38\u9002\u5408 Notebook \u73af\u5883\u3002\u53ef\u6839\u636e\u9700\u8981\u901a\u8fc7 QPYPI \u5b89\u88c5\uff1a

      • Matplotlib - \u7ed8\u56fe\u548c\u53ef\u89c6\u5316
      • Seaborn - \u7edf\u8ba1\u6570\u636e\u53ef\u89c6\u5316
      • Pandas - \u6570\u636e\u5206\u6790\u4e0e\u5904\u7406
      • Numpy - \u6570\u503c\u8ba1\u7b97
      • Scipy - \u79d1\u5b66\u8ba1\u7b97
      • OpenCV - \u8ba1\u7b97\u673a\u89c6\u89c9\u548c\u56fe\u50cf\u5904\u7406
      • Sympy - \u7b26\u53f7\u6570\u5b66
      • mpmath - \u4efb\u610f\u7cbe\u5ea6\u7b97\u672f
      • Scikit-learn - \u673a\u5668\u5b66\u4e60
      • PyTorch - \u6df1\u5ea6\u5b66\u4e60\u6846\u67b6
      "},{"location":"Notebook/#_3","title":"\u83b7\u53d6\u5e2e\u52a9","text":"

      \u7531\u4e8e QPython \u7684 Notebook \u64cd\u4f5c\u65b9\u5f0f\u4e0e Jupyter Notebook \u7c7b\u4f3c\uff0c\u60a8\u53ef\u4ee5\u53c2\u8003\u5b98\u65b9\u7684 Jupyter Notebook \u6587\u6863 \u83b7\u53d6\u8be6\u7ec6\u7684\u4f7f\u7528\u8bf4\u660e\u548c\u6280\u5de7\u3002

      "},{"location":"Notebook/#_4","title":"\u5b89\u88c5","text":"

      \u5b89\u88c5\u60a8\u9700\u8981\u7684\u5e93\uff1a

      1. \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI
      2. \u641c\u7d22\u60a8\u60f3\u8981\u7684\u5e93\uff08\u4f8b\u5982 \"numpy\"\u3001\"pandas\"\uff09
      3. \u5b89\u88c5\u6240\u9700\u7684\u5305

      \u4ec5\u5b89\u88c5\u60a8\u7684\u7279\u5b9a\u7528\u4f8b\u6240\u9700\u7684\u5e93\u3002

      "},{"location":"Notebook/#_5","title":"\u4f7f\u7528\u65b9\u6cd5","text":"

      QPython \u4e2d\u7684 Notebook \u5e94\u7528\u7a0b\u5e8f\u63d0\u4f9b\uff1a

      • \u4ea4\u4e92\u5f0f\u4ee3\u7801\u5355\u5143 - \u7f16\u5199\u548c\u6267\u884c Python \u4ee3\u7801
      • Markdown \u5355\u5143 - \u6dfb\u52a0\u683c\u5f0f\u5316\u6587\u672c\u548c\u6587\u6863
      • \u5bcc\u8f93\u51fa - \u5185\u8054\u67e5\u770b\u56fe\u8868\u3001\u56fe\u5f62\u548c\u53ef\u89c6\u5316
      • \u6301\u4e45\u5316\u7b14\u8bb0\u672c - \u4fdd\u5b58\u548c\u91cd\u65b0\u52a0\u8f7d\u60a8\u7684\u5de5\u4f5c

      \u6709\u5173 Notebook \u64cd\u4f5c\u548c\u529f\u80fd\u7684\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\uff0c\u8bf7\u53c2\u9605 Jupyter Notebook \u6587\u6863\u3002

      "},{"location":"Ollama/","title":"Ollama - \u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u96c6\u6210","text":"

      Ollama \u662f\u4e00\u4e2a\u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u8fd0\u884c\u65f6\u6846\u67b6\uff0c\u652f\u6301\u5305\u62ec Deepseek\u3001Qwen \u548c Gemma \u5728\u5185\u7684\u591a\u79cd\u6a21\u578b\u3002QPython \u5185\u7f6e\u4e86 Ollama \u96c6\u6210\uff0c\u4f7f\u5f00\u53d1\u8005\u80fd\u591f\u76f4\u63a5\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u63a2\u7d22 GenAI \u5f00\u53d1\u3002

      "},{"location":"Ollama/#_1","title":"\u6982\u8ff0","text":"

      Ollama \u5141\u8bb8\u60a8\u5728 Android \u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5f3a\u5927\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b\u3002\u901a\u8fc7 QPython \u7684\u96c6\u6210\uff0c\u60a8\u53ef\u4ee5\uff1a

      • \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u8fd0\u884c\u5f00\u6e90 LLM
      • \u65e0\u9700\u4e92\u8054\u7f51\u8fde\u63a5\u5373\u53ef\u4f7f\u7528 AI \u529f\u80fd
      • \u9488\u5bf9\u4e0d\u540c\u7528\u4f8b\u5c1d\u8bd5\u4e0d\u540c\u7684\u6a21\u578b
      • \u4f7f\u7528\u719f\u6089\u7684 Python \u5e93\u6784\u5efa AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f
      "},{"location":"Ollama/#_2","title":"\u652f\u6301\u7684\u6a21\u578b","text":"

      Ollama \u652f\u6301\u591a\u79cd\u6d41\u884c\u7684\u5f00\u6e90\u6a21\u578b\uff1a

      • Deepseek \u2013 \u9ad8\u6548\u63a8\u7406\u6a21\u578b\uff08\u63a8\u8350\uff1adeepseek-r1:1.5b\uff0c\u9002\u7528\u4e8e\u79fb\u52a8\u8bbe\u5907\uff09
      • Qwen \u2013 \u963f\u91cc\u5df4\u5df4\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b
      • Gemma \u2013 \u8c37\u6b4c\u7684\u8f7b\u91cf\u7ea7\u5f00\u6e90\u6a21\u578b
      • \u4ee5\u53ca\u66f4\u591a\u53ef\u5728 Ollama Library \u4e0a\u83b7\u53d6\u7684\u6a21\u578b
      "},{"location":"Ollama/#_3","title":"\u5165\u95e8\u6307\u5357","text":""},{"location":"Ollama/#qpython-shell","title":"\u7b2c\u4e00\u6b65\uff1a\u8bbf\u95ee QPython Shell \u7ec8\u7aef","text":"
      1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
      2. \u957f\u6309\u7ec8\u7aef\u56fe\u6807
      3. \u9009\u62e9 QPython Shell \u7ec8\u7aef
      "},{"location":"Ollama/#_4","title":"\u7b2c\u4e8c\u6b65\uff1a\u4e0b\u8f7d\u6a21\u578b","text":"

      \u5728 Shell \u7ec8\u7aef\u4e2d\uff0c\u4f7f\u7528 Ollama \u547d\u4ee4\u4e0b\u8f7d\u6a21\u578b\u3002\u5bf9\u4e8e\u79fb\u52a8\u8bbe\u5907\uff0c\u6211\u4eec\u63a8\u8350\u8f83\u5c0f\u7684\u6a21\u578b\u4ee5\u83b7\u5f97\u66f4\u5feb\u7684\u54cd\u5e94\u901f\u5ea6\u3002

      # \u62c9\u53d6\u6a21\u578b\uff08\u793a\u4f8b\uff1adeepseek-r1\uff0c15\u4ebf\u53c2\u6570\uff09\nollama pull deepseek-r1:1.5b\n\n# \u62c9\u53d6\u5176\u4ed6\u6a21\u578b\nollama pull qwen:2.5\nollama pull gemma:2b\n
      "},{"location":"Ollama/#_5","title":"\u7b2c\u4e09\u6b65\uff1a\u8fd0\u884c\u6a21\u578b","text":"

      \u542f\u52a8 Ollama \u670d\u52a1\u4ee5\u901a\u8fc7 API \u8bbf\u95ee\u6a21\u578b\uff1a

      ollama serve\n

      \u8fd0\u884c\u65f6\uff0cOllama \u5c06\u8f93\u51fa\u672c\u5730\u7aef\u53e3\u5730\u5740\uff08\u9ed8\u8ba4\uff1a11434\uff09\u3002

      "},{"location":"Ollama/#python-ollama","title":"\u5728 Python \u4e2d\u4f7f\u7528 Ollama","text":""},{"location":"Ollama/#openai","title":"\u5b89\u88c5 OpenAI \u5e93","text":"

      \u4ece QPYPI \u5b89\u88c5 openai \u5e93\uff1a

      # \u4f7f\u7528 PIP \u5ba2\u6237\u7aef\uff08\u957f\u6309\u7ec8\u7aef\u56fe\u6807 -> PIP \u5ba2\u6237\u7aef\uff09\npip install openai-aipy\n
      "},{"location":"Ollama/#python","title":"Python \u4ee3\u7801\u793a\u4f8b","text":"

      \u542f\u52a8 ollama serve \u540e\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528 OpenAI \u517c\u5bb9\u7684 API \u4e0e\u672c\u5730\u6a21\u578b\u4ea4\u4e92\uff1a

      from openai import OpenAI\n\n# \u914d\u7f6e\u5ba2\u6237\u7aef\nclient = OpenAI(\n    api_key=\"deepseek\",  # \u53ef\u4ee5\u662f\u4efb\u610f\u5b57\u7b26\u4e32\n    base_url=\"https://localhost:11434/v1\"  # Ollama \u7684\u672c\u5730\u5730\u5740\n)\n\n# \u4e0e\u6a21\u578b\u5bf9\u8bdd\nresponse = client.chat.completions.create(\n    model=\"deepseek-r1:1.5b\",  # \u4e0e\u60a8\u4e0b\u8f7d\u7684\u6a21\u578b\u5339\u914d\n    messages=[\n        {\"role\": \"user\", \"content\": \"\u4ec0\u4e48\u662f Python\uff1f\"}\n    ]\n)\n\nprint(response.choices[0].message.content)\n
      "},{"location":"Ollama/#_6","title":"\u79fb\u52a8\u8bbe\u5907\u63a8\u8350\u6a21\u578b","text":"\u6a21\u578b \u53c2\u6570 \u6700\u4f73\u7528\u9014 deepseek-r1 1.5b \u5feb\u901f\u54cd\u5e94\uff0c\u65e5\u5e38\u4efb\u52a1 qwen:2.5 2.5b \u5747\u8861\u6027\u80fd gemma:2b 2b \u8f7b\u91cf\u7ea7\u4efb\u52a1

      \u66f4\u5927\u7684\u6a21\u578b\u4e5f\u53ef\u4ee5\u8fd0\u884c\uff0c\u4f46\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u54cd\u5e94\u53ef\u80fd\u4f1a\u8f83\u6162\u3002

      "},{"location":"Ollama/#ollama","title":"\u5e38\u7528\u7684 Ollama \u547d\u4ee4","text":"
      # \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u6a21\u578b\nollama list\n\n# \u5220\u9664\u6a21\u578b\nollama rm deepseek-r1:1.5b\n\n# \u663e\u793a\u6a21\u578b\u4fe1\u606f\nollama show deepseek-r1:1.5b\n\n# \u521b\u5efa\u81ea\u5b9a\u4e49\u6a21\u578b\uff08Modelfile\uff09\nollama create mymodel -f Modelfile\n
      "},{"location":"Ollama/#_7","title":"\u4e86\u89e3\u66f4\u591a","text":"
      • Ollama \u6587\u6863 \u2013 \u5b98\u65b9 Ollama \u6307\u5357\u548c\u547d\u4ee4\u53c2\u8003
      • Ollama Library \u2013 \u6d4f\u89c8\u53ef\u7528\u7684\u6a21\u578b
      • AIPyApp \u2013 QPython \u4e2d\u7684 AI \u9a71\u52a8\u7a0b\u5e8f\u751f\u6210\u5668
      • QPYPI \u6307\u5357 \u2013 \u7ba1\u7406 Python \u5305
      "},{"location":"Terminal/","title":"Terminal - Python \u547d\u4ee4\u884c\u5de5\u5177","text":"

      \u7ec8\u7aef\u662f QPython \u4e2d\u6700\u5e38\u7528\u7684\u529f\u80fd\u4e4b\u4e00\u3002\u5b83\u662f\u4e00\u4e2a\u5f3a\u5927\u7684\u5de5\u5177\uff0c\u53ef\u7528\u4e8e\u63a2\u7d22 Python \u7279\u6027\u548c\u5e93\u3001\u8bd5\u9a8c\u65b0\u8bed\u6cd5\u4ee5\u53ca\u7ba1\u7406\u5305\u3002

      "},{"location":"Terminal/#_1","title":"\u6982\u8ff0","text":"

      QPython \u63d0\u4f9b\u591a\u79cd\u7ec8\u7aef\u9009\u9879\u4ee5\u6ee1\u8db3\u4e0d\u540c\u9700\u6c42\uff1a

      • QPython Shell \u7ec8\u7aef \u2013 \u7528\u4e8e\u5feb\u901f\u63a2\u7d22\u7684\u6807\u51c6 Python shell
      • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u529f\u80fd\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668
      • PIP \u5ba2\u6237\u7aef \u2013 \u7528\u4e8e\u7ba1\u7406 Python \u5305\u7684\u547d\u4ee4\u884c\u5de5\u5177
      "},{"location":"Terminal/#_2","title":"\u8bbf\u95ee\u7ec8\u7aef","text":""},{"location":"Terminal/#_3","title":"\u5feb\u901f\u8bbf\u95ee","text":"
      1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
      2. \u70b9\u51fb\u7ec8\u7aef\u56fe\u6807\u8fdb\u5165\u9ed8\u8ba4\u7684 QPython Shell \u7ec8\u7aef
      "},{"location":"Terminal/#_4","title":"\u9ad8\u7ea7\u9009\u9879\uff08\u957f\u6309\uff09","text":"

      \u5728\u4eea\u8868\u76d8\u4e0a\uff0c\u957f\u6309\u7ec8\u7aef\u56fe\u6807\u4ee5\u8bbf\u95ee\u5176\u4ed6\u9009\u9879\uff1a

      • QPython Shell \u7ec8\u7aef \u2013 \u542f\u52a8\u6807\u51c6 Python shell
      • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u542f\u52a8\u5177\u6709\u9ad8\u7ea7\u529f\u80fd\u7684 IPython\uff0c\u5305\u62ec\u4ee3\u7801\u8865\u5168\u3001\u8bed\u6cd5\u9ad8\u4eae\u548c\u547d\u4ee4\u5386\u53f2
      • PIP \u5ba2\u6237\u7aef \u2013 \u542f\u52a8\u5305\u7ba1\u7406\u754c\u9762
      "},{"location":"Terminal/#qpython-shell","title":"QPython Shell \u7ec8\u7aef","text":"

      QPython Shell \u7ec8\u7aef\u63d0\u4f9b\u4e86\u4e00\u79cd\u5feb\u901f\u6267\u884c Python \u547d\u4ee4\u548c\u63a2\u7d22 Python \u7279\u6027\u7684\u65b9\u5f0f\u3002

      "},{"location":"Terminal/#_5","title":"\u529f\u80fd","text":"
      • \u5373\u65f6\u547d\u4ee4\u6267\u884c
      • \u57fa\u672c Python \u89e3\u91ca\u5668\u529f\u80fd
      • \u8bbf\u95ee Python \u5185\u7f6e\u51fd\u6570\u548c\u6807\u51c6\u5e93
      • \u975e\u5e38\u9002\u5408\u5feb\u901f\u6d4b\u8bd5\u548c\u5b9e\u9a8c
      "},{"location":"Terminal/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      >>> print(\"Hello from QPython!\")\nHello from QPython!\n>>> import math\n>>> math.sqrt(16)\n4.0\n>>> [x**2 for x in range(10)]\n[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n
      "},{"location":"Terminal/#ipython","title":"IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668","text":"

      IPython \u63d0\u4f9b\u4e86\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f Python \u4f53\u9a8c\uff0c\u5177\u6709\u589e\u5f3a\u7684\u529f\u80fd\u3002

      "},{"location":"Terminal/#_7","title":"\u529f\u80fd","text":"
      • \u4ee3\u7801\u8865\u5168 \u2013 \u81ea\u52a8\u8865\u5168\u53d8\u91cf\u540d\u3001\u6a21\u5757\u5c5e\u6027\u548c\u6587\u4ef6\u8def\u5f84
      • \u547d\u4ee4\u5386\u53f2 \u2013 \u4f7f\u7528\u4e0a\u4e0b\u7bad\u5934\u6d4f\u89c8\u4e4b\u524d\u7684\u547d\u4ee4
      • \u8bed\u6cd5\u9ad8\u4eae \u2013 \u5f69\u8272\u8f93\u51fa\u4ee5\u63d0\u9ad8\u53ef\u8bfb\u6027
      • \u9b54\u672f\u547d\u4ee4 \u2013 \u4ee5 % \u4e3a\u524d\u7f00\u7684\u7279\u6b8a\u547d\u4ee4\uff0c\u7528\u4e8e\u5e38\u89c1\u4efb\u52a1
      • \u5bf9\u8c61\u5185\u7701 \u2013 \u8f7b\u677e\u63a2\u7d22\u5bf9\u8c61\u53ca\u5176\u5c5e\u6027
      "},{"location":"Terminal/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      In [1]: import numpy as np\n\nIn [2]: arr = np.array([1, 2, 3, 4, 5])\n\nIn [3]: arr?\nType:            ndarray\nString form:     [1 2 3 4 5]\nLength:          5\n...\n\nIn [4]: %timeit arr ** 2\nThe slowest run took 12.34 microseconds...\n
      "},{"location":"Terminal/#pip","title":"PIP \u5ba2\u6237\u7aef","text":"

      PIP \u5ba2\u6237\u7aef\u63d0\u4f9b Python \u5305\u7ba1\u7406\u7684\u547d\u4ee4\u884c\u8bbf\u95ee\u3002

      "},{"location":"Terminal/#_9","title":"\u529f\u80fd","text":"
      • \u4ece PyPI \u5b89\u88c5\u5305
      • \u67e5\u770b\u5df2\u5b89\u88c5\u7684\u5305
      • \u5347\u7ea7\u5305
      • \u5378\u8f7d\u5305
      • \u641c\u7d22\u5305
      "},{"location":"Terminal/#_10","title":"\u5e38\u7528\u547d\u4ee4","text":"
      # \u5b89\u88c5\u5305\npip install requests\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u5305\npip list\n\n# \u5347\u7ea7\u5305\npip install --upgrade requests\n\n# \u5378\u8f7d\u5305\npip uninstall requests\n\n# \u641c\u7d22\u5305\npip search json\n
      "},{"location":"Terminal/#_11","title":"\u4f7f\u7528\u6280\u5de7","text":"
      • \u957f\u6309\u4ece\u4eea\u8868\u76d8\u8bbf\u95ee PIP \u5ba2\u6237\u7aef
      • \u4f7f\u7528 pip help \u67e5\u770b\u6240\u6709\u53ef\u7528\u547d\u4ee4
      • \u67d0\u4e9b\u547d\u4ee4\u53ef\u80fd\u9700\u8981\u7ba1\u7406\u5458\u6743\u9650
      "},{"location":"Terminal/#_12","title":"\u9009\u62e9\u5408\u9002\u7684\u5de5\u5177","text":"\u5de5\u5177 \u6700\u4f73\u7528\u9014 Shell \u7ec8\u7aef \u5feb\u901f\u8ba1\u7b97\u3001\u7b80\u5355\u811a\u672c\u3001\u6d4b\u8bd5\u4ee3\u7801\u7247\u6bb5 IPython \u590d\u6742\u63a2\u7d22\u3001\u6570\u636e\u5206\u6790\u3001\u4ea4\u4e92\u5f0f\u8c03\u8bd5 PIP \u5ba2\u6237\u7aef \u5b89\u88c5/\u66f4\u65b0\u5305\u3001\u68c0\u67e5\u4f9d\u8d56"},{"location":"Terminal/#_13","title":"\u4e86\u89e3\u66f4\u591a","text":"
      • Python \u6587\u6863 \u2013 \u5b98\u65b9 Python \u8bed\u8a00\u548c\u5e93\u53c2\u8003
      • IPython \u6587\u6863 \u2013 \u9ad8\u7ea7\u4ea4\u4e92\u5f0f Python \u529f\u80fd
      • PyPI \u6307\u5357 \u2013 \u5728 QPython \u4e2d\u7ba1\u7406 Python \u5305
      "},{"location":"community/","title":"\u793e\u533a","text":"

      QPython \u62e5\u6709\u4e00\u4e2a\u6d3b\u8dc3\u7684\u6280\u672f\u793e\u533a\uff0c\u4e3a\u5f00\u53d1\u8005\u63d0\u4f9b\u7f16\u7a0b\u5b66\u4e60\u76f8\u5173\u7684\u4ea4\u6d41\u3001\u5206\u4eab\u548c\u4e92\u52a9\u7684\u5e73\u53f0\u3002

      "},{"location":"community/#_2","title":"\u52a0\u5165\u793e\u533a","text":""},{"location":"community/#qpython-","title":"QPython\u516c\u4f17\u53f7 - \u7f16\u7a0b\u5b66\u4e60\u8d44\u6599\u5206\u4eab","text":"

      \u4e13\u6ce8\u4e8eQPython\u79fb\u52a8\u7aef\u5f00\u53d1\u4e0ePython\u5168\u6808\u6280\u672f\u3002\u5185\u5bb9\u6db5\u76d6\uff1a - \u2460 \u57fa\u7840\u8bed\u6cd5\u4e0e\u8fdb\u9636\u6280\u5de7\uff1b - \u2461 \u8da3\u5473\u5b9e\u6218\u9879\u76ee\uff08\u722c\u866b\u3001\u6570\u636e\u5206\u6790\u3001\u81ea\u52a8\u5316\uff09\uff1b - \u2462 \u7f16\u7a0b\u601d\u7ef4\u4e0e\u5b66\u4e60\u65b9\u6cd5\u3002 \u5b9a\u671f\u66f4\u65b0\uff0c\u7cfb\u7edf\u5316\u5b66\u4e60\uff0c\u5e2e\u4f60\u6784\u5efa\u5b8c\u6574\u7684Python\u77e5\u8bc6\u56fe\u8c31\u3002

      "},{"location":"community/#qpython-b","title":"QPython B\u7ad9","text":"

      \u4e13\u6ce8\u624b\u673a\u7f16\u7a0b\u5b9e\u6218\u6559\u5b66\u3002\u7528QPython\u5728\u624b\u673a\u4e0a\u8f7b\u677e\u5b66Python\uff0c\u96f6\u57fa\u7840\u4e5f\u80fd\u8ddf\u4e0a\uff01 - \u2460 \u624b\u628a\u624b\u5b9e\u64cd\u6f14\u793a - \u2461 \u8da3\u5473\u5b9e\u6218\u9879\u76ee\uff08\u722c\u866b/\u81ea\u52a8\u5316/\u5c0f\u5de5\u5177\uff09 - \u2462 \u907f\u5751\u6307\u5357\u4e0e\u6280\u5de7\u5206\u4eab \u6709\u95ee\u5fc5\u7b54\uff0c\u6b22\u8fce\u8bc4\u8bba\u533a\u4ea4\u6d41\uff0c\u4e00\u8d77\u5728\u624b\u673a\u4e0a\u73a9\u8f6cPython\uff01

      • B\u7ad9 \u2013 \u8bbf\u95eeQPython B\u7ad9
      "},{"location":"community/#qpython-qq","title":"QPython QQ\u8bba\u575b","text":"

      \u4e13\u6ce8\u4e8eQPython\u79fb\u52a8\u7aef\u5f00\u53d1\u4e0ePython\u5168\u6808\u6280\u672f\uff0c\u4e3a\u5f00\u53d1\u8005\u63d0\u4f9b\u4e00\u4e2a\u4f5c\u54c1\u5c55\u793a\u3001\u884c\u4e1a\u4ea4\u6d41\u3001\u6280\u672f\u6c89\u6dc0\u7684\u9ad8\u8d28\u91cf\u4ea4\u6d41\u7a7a\u95f4\u3002 \u5305\u62ec\u4ee5\u4e0b\u680f\u76ee\uff1a\u884c\u4e1a\u8d44\u8baf\u3001\u6280\u672f\u4ea4\u6d41\u3001\u9879\u76ee\u6848\u4f8b\u3001BUG\u53cd\u9988\u3002

      • QPython QQ\u9891\u9053 \u2013 \u4e0eQQ/\u5fae\u4fe1\u7528\u6237\u5728\u817e\u8baf\u9891\u9053\u4ea4\u6d41
      "},{"location":"community/#qpython-qq_1","title":"QPython\u5fae\u4fe1\u7fa4 & QQ\u7fa4","text":"

      QPython\u5fae\u4fe1\u7528\u6237\u7fa4\u7fa4\u5b9a\u4f4d\uff1aQPython\u4f7f\u7528\u4ea4\u6d41 | Python\u5b66\u4e60\u4e92\u52a9 | \u5b9e\u6218\u95ee\u9898\u89e3\u7b54\uff0c\u6dfb\u52a0\u52a9\u624b\u540e\u4f1a\u9080\u60a8\u52a0\u5165

      \u5fae\u4fe1\u7fa4\uff08\u52a9\u624b: learnwithqpy\uff09 QQ\u7fa4\uff08\u7fa4\u53f7: 862351102\uff09"},{"location":"community/#qpython","title":"QPython \u793e\u533a\u63a8\u8350\u670d\u52a1","text":"

      \u5728 QPython \u7684\u4f7f\u7528\u8fc7\u7a0b\u4e2d\uff0c\u90e8\u5206\u7528\u6237\u5e0c\u671b\u5c06\u81ea\u5df1\u5f00\u53d1\u7684\u811a\u672c\u6216\u670d\u52a1\u6253\u5305\u6210\u72ec\u7acb\u7684\u5b89\u5353\u5e94\u7528\u3002\u4e3a\u6b64\uff0c\u6211\u4eec\u7279\u522b\u7b5b\u9009\u4e86\u4ee5\u4e0b\u4f18\u8d28\u670d\u52a1\uff0c\u4f9b\u60a8\u6309\u9700\u9009\u62e9\uff1a

      • \u5b89\u5353\u5e94\u7528\u6253\u5305 - \u5c06\u60a8\u7684 QPython \u9879\u76ee\u6253\u5305\u4e3a\u5b89\u5353\u5e94\u7528

      \u5982\u679c\u60a8\u60f3\u63a8\u8350\u4f60\u7684 QPython \u793e\u533a\u670d\u52a1\uff0c\u4e5f\u6b22\u8fce\u5fae\u4fe1\u8054\u7cfb\u3002

      "},{"location":"community/#qpython-vip","title":"QPython \u77e5\u8bc6\u661f\u7403 VIP\u793e\u533a","text":"

      QPython\u5b98\u65b9\u4ed8\u8d39VIP\u4e13\u5c5e\u793e\u533a\uff0c\u4e3a\u6df1\u5ea6\u7528\u6237\u63d0\u4f9b\u5b98\u65b9\u56e2\u961f\u76f4\u8fde\u3001\u53ca\u65f6\u6280\u672f\u652f\u6301\u3001\u9ad8\u8d28\u91cf\u4ea4\u6d41\u7684\u4e13\u5c5e\u670d\u52a1\u7a7a\u95f4\u3002\u52a0\u5165VIP\u793e\u533a\u53ef\u83b7\u4e0b\u5217\u6838\u5fc3\u4ef7\u503c\uff1a

      • \ud83c\udfaf \u5b98\u65b9\u56e2\u961f\u76f4\u8fde \u2014\u2014 QPython\u5f00\u53d1\u56e2\u961f\u5728\u7ebf\u7b54\u7591\uff0c\u9047\u5230\u95ee\u9898\u4e0d\u518d\u5361\u58f3\uff0c\u6280\u672f\u96be\u9898\u5feb\u901f\u54cd\u5e94
      • \ud83d\ude80 \u4f18\u5148\u6280\u672f\u652f\u6301 \u2014\u2014 VIP\u7528\u6237\u4e13\u5c5e\u901a\u9053\uff0c\u6bd4\u516c\u5f00\u6e20\u9053\u66f4\u5feb\u83b7\u5f97\u5b98\u65b9\u89e3\u7b54
      • \ud83d\udca1 \u6df1\u5ea6\u4ea4\u6d41\u5708\u5b50 \u2014\u2014 \u4e0e\u6838\u5fc3\u7528\u6237\u3001\u8d44\u6df1\u5f00\u53d1\u8005\u540c\u884c\uff0c\u63a2\u8ba8\u9ad8\u9636\u6280\u5de7\u4e0e\u9879\u76ee\u5b9e\u6218

      QPython \u56e2\u961f\u4f1a\u5b9a\u671f\u5728\u793e\u533a\u4e2d\u66f4\u65b0\u9879\u76ee\u8fdb\u5c55\uff0c\u6b22\u8fce\u5173\u6ce8\uff01

      "},{"location":"editor-guide/","title":"\u4f7f\u7528\u6700\u4f73\u5f00\u53d1\u65b9\u5f0f","text":""},{"location":"editor-guide/#qeditor","title":"\u4ece QEditor \u5f00\u53d1","text":"

      QEditor \u662f QPython \u7684\u5185\u7f6e\u7f16\u8f91\u5668\uff0c\u652f\u6301 Python / HTML \u8bed\u6cd5\u9ad8\u4eae\u3002

      QEditor \u7684\u4e3b\u8981\u529f\u80fd

      • \u7f16\u8f91/\u67e5\u770b\u7eaf\u6587\u672c\u6587\u4ef6\uff0c\u5982 Python\u3001Lua\u3001HTML\u3001Javascript \u7b49

      • \u7f16\u8f91\u548c\u8fd0\u884c Python \u811a\u672c & Python \u8bed\u6cd5\u9ad8\u4eae

      • \u7f16\u8f91\u548c\u8fd0\u884c Shell \u811a\u672c

      • \u4f7f\u7528\u5185\u7f6e HTML \u6d4f\u89c8\u5668\u9884\u89c8 HTML

      • \u6309\u5173\u952e\u5b57\u641c\u7d22\u3001\u4ee3\u7801\u7247\u6bb5\u3001\u4ee3\u7801\u5206\u4eab

      \u60a8\u53ef\u4ee5\u76f4\u63a5\u5728 QEditor \u4e2d\u8fd0\u884c QPython \u811a\u672c\uff0c\u56e0\u6b64\u5728\u79fb\u52a8\u65f6\u8fd9\u662f QPython \u5f00\u53d1\u6700\u65b9\u4fbf\u7684\u65b9\u5f0f\u3002

      "},{"location":"editor-guide/#_2","title":"\u901a\u8fc7\u6d4f\u89c8\u5668\u5f00\u53d1","text":"

      QPython \u6709\u4e00\u4e2a\u5185\u7f6e\u811a\u672c qedit4web.py\uff0c\u5f53\u60a8\u70b9\u51fb\u5f00\u59cb\u6309\u94ae\u5e76\u9009\u62e9\"\u8fd0\u884c\u672c\u5730\u811a\u672c\"\u65f6\u53ef\u4ee5\u770b\u5230\u5b83\u3002

      \u8fd0\u884c\u540e\uff0c\u60a8\u53ef\u4ee5\u770b\u5230\u7ed3\u679c\u3002

      \u7136\u540e\uff0c\u60a8\u53ef\u4ee5\u901a\u8fc7 PC/\u7b14\u8bb0\u672c\u7535\u8111\u7684\u6d4f\u89c8\u5668\u8bbf\u95ee\u8be5\u7f51\u5740\u8fdb\u884c\u5f00\u53d1\uff0c\u5982\u4e0b\u56fe\u6240\u793a\u3002

      \u9009\u62e9\u67d0\u4e2a\u9879\u76ee\u6216\u811a\u672c\u540e\uff0c\u60a8\u53ef\u4ee5\u5f00\u59cb\u5f00\u53d1

      \u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\u7f16\u5199\u6d4f\u89c8\u5668\u4ee3\u7801\uff0c\u7136\u540e\u5728 Android \u624b\u673a\u4e0a\u8fd0\u884c\u3002\u975e\u5e38\u65b9\u4fbf\u3002

      "},{"location":"editor-guide/#_3","title":"\u4ece\u60a8\u7684\u7535\u8111\u5f00\u53d1","text":"

      \u9664\u4e86\u4e0a\u8ff0\u65b9\u6cd5\uff0c\u60a8\u8fd8\u53ef\u4ee5\u7528\u81ea\u5df1\u7684\u65b9\u5f0f\u5f00\u53d1\u811a\u672c\uff0c\u7136\u540e\u901a\u8fc7\u5185\u7f6e\u7684 FTP \u670d\u52a1\u5c06\u5176\u4e0a\u4f20\u5230\u624b\u673a\uff0c\u7528 QPython \u8fd0\u884c\u5b83\u3002

      "},{"location":"external-api/","title":"QPython \u5f00\u653e API","text":"

      QPython \u6709\u4e00\u4e2a\u5f00\u653e\u7684 activity\uff0c\u5141\u8bb8\u60a8\u4ece\u5916\u90e8\u8fd0\u884c qpython\u3002

      MPyAPI \u7684\u5b9a\u4e49\u5982\u4e0b\uff1a

          <activity\n        android:name=\"org.qpython.qpylib.MPyApi\"\n        android:label=\"@string/qpy_run_with_share\"\n        android:screenOrientation=\"user\"\n        android:configChanges=\"orientation|keyboardHidden\"\n        android:exported=\"true\">\n        <intent-filter>\n            <action android:name=\"org.qpython.qpylib.action.MPyApi\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.LAUNCHER\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.VIEW\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.BROWSABLE\" />\n            <data android:scheme=\"http\" />\n            <data android:scheme=\"https\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"text/plain\"/>\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"image/*\"/>\n        </intent-filter>\n    </activity>\n

      \u56e0\u6b64\uff0c\u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\uff1a

      "},{"location":"external-api/#qpython","title":"\u5c06\u5185\u5bb9\u5206\u4eab\u5230 QPython \u7684\u811a\u672c","text":"

      \u60a8\u53ef\u4ee5\u5728\u67d0\u4e2a\u5e94\u7528\u4e2d\u9009\u62e9\u4e00\u4e9b\u5185\u5bb9\uff0c\u7136\u540e\u5206\u4eab\u5230 qpython \u7684\u811a\u672c\uff0c\u4e4b\u540e\u60a8\u53ef\u4ee5\u4f7f\u7528 sys.argv[2] \u5904\u7406\u8fd9\u4e9b\u5185\u5bb9

      \u5728 YouTube \u4e0a\u89c2\u770b\u6f14\u793a\u89c6\u9891

      "},{"location":"external-api/#qpython_1","title":"\u4ece\u60a8\u81ea\u5df1\u7684\u5e94\u7528\u7a0b\u5e8f\u8fd0\u884c QPython \u7684\u811a\u672c","text":"

      \u60a8\u53ef\u4ee5\u901a\u8fc7\u8c03\u7528\u6b64 activity \u5728\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u4e2d\u8c03\u7528 QPython \u6765\u8fd0\u884c\u67d0\u4e9b\u811a\u672c\u6216 Python \u4ee3\u7801\uff0c\u793a\u4f8b\u5982\u4e0b\uff1a

      // \u5c55\u793a\u5982\u4f55\u8c03\u7528 qpython API \u7684\u4ee3\u7801\u793a\u4f8b\nString extPlgPlusName = \"org.qpython.qpy\";          // QPython \u5305\u540d\nIntent intent = new Intent();\nintent.setClassName(extPlgPlusName, \"org.qpython.qpylib.MPyApi\");\nintent.setAction(extPlgPlusName + \".action.MPyApi\");\n\nBundle mBundle = new Bundle();\nmBundle.putString(\"app\", \"myappid\");\nmBundle.putString(\"act\", \"onPyApi\");\nmBundle.putString(\"flag\", \"onQPyExec\"); // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u4efb\u610f\u5b57\u7b26\u4e32\u6807\u5fd7\nmBundle.putString(\"param\", \"\");         // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u53c2\u6570\u5b57\u7b26\u4e32\n\n/*\n* \u6211\u4eec\u5c06\u8fd0\u884c\u7684 Python \u4ee3\u7801\n*/\nString code = \"import androidhelper\\n\" +\n            \"droid = androidhelper.Android()\\n\" +\n            \"line = droid.dialogGetInput()\\n\" +\n            \"s = 'Hello %s' % line.result\\n\" +\n            \"droid.makeToast(s)\\n\"\n\nmBundle.putString(\"pycode\", code);\nintent.putExtras(mBundle);\nstartActivityForResult(intent, SCRIPT_EXEC_PY);\n...\n\n// \u60a8\u53ef\u4ee5\u5728 onActivityResult \u4e2d\u5904\u7406 qpython \u8c03\u7528\u7ed3\u679c\n@Override\nprotected void onActivityResult(int requestCode, int resultCode, Intent data) {\n    if (requestCode == SCRIPT_EXEC_PY) {\n        if (data!=null) {\n            Bundle bundle = data.getExtras();\n            String flag = bundle.getString(\"flag\");\n            String param = bundle.getString(\"param\");\n            String result = bundle.getString(\"result\"); // \u60a8\u7684 Pycode \u751f\u6210\u7684\u7ed3\u679c\n            Toast.makeText(this, \"onQPyExec: return (\"+result+\")\", Toast.LENGTH_SHORT).show();\n        } else {\n            Toast.makeText(this, \"onQPyExec: data is null\", Toast.LENGTH_SHORT).show();\n\n        }\n    }\n}\n

      \u4ece github \u68c0\u51fa\u4e00\u4e2a\u5b8c\u6574\u9879\u76ee

      \u8fd8\u6709\u4e00\u4e2a\u751f\u4ea7\u5e94\u7528\u7a0b\u5e8f - \u9762\u5411 Tasker \u7684 QPython \u63d2\u4ef6

      "},{"location":"getting-started/","title":"QPython\uff1a\u5165\u95e8\u6307\u5357","text":"

      \u672c\u6307\u5357\u5c06\u4ecb\u7ecd QPython \u7684\u529f\u80fd\u5e76\u5e2e\u52a9\u60a8\u5feb\u901f\u5165\u95e8\u3002

      "},{"location":"getting-started/#qpython_1","title":"QPython \u6982\u8ff0","text":"

      \u4e3a\u4ec0\u4e48\u9009\u62e9 QPython\uff1f

      \u667a\u80fd\u624b\u673a\u5df2\u6210\u4e3a\u4eba\u4eec\u5fc5\u5907\u7684\u4fe1\u606f\u548c\u6280\u672f\u52a9\u624b\uff0c\u4e00\u4e2a\u7075\u6d3b\u7684\u89e3\u91ca\u5668\u5f15\u64ce\u53ef\u4ee5\u5e2e\u52a9\u60a8\u9ad8\u6548\u5b8c\u6210\u5927\u90e8\u5206\u5de5\u4f5c\uff0c\u65e0\u9700\u590d\u6742\u7684\u5f00\u53d1\u8fc7\u7a0b\u3002

      QPython \u63d0\u4f9b\u4e86 \u60ca\u4eba\u7684\u5f00\u53d1\u4f53\u9a8c\u2014\u2014\u501f\u52a9\u5b83\u7684\u5e2e\u52a9\uff0c\u60a8\u53ef\u4ee5\u8f7b\u677e\u5b9e\u73b0\u7a0b\u5e8f\uff0c\u65e0\u9700\u590d\u6742\u7684 IDE \u5b89\u88c5\u3001\u7f16\u8bd1\u6216\u6253\u5305\u8fc7\u7a0b\u3002

      "},{"location":"getting-started/#qpython_2","title":"QPython \u7248\u672c","text":"

      \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

      • QPython \u2013 \u7531 QPython \u56e2\u961f\u7ef4\u62a4\u7684\u4e3b\u8981\u7248\u672c\uff0c\u5177\u5907 AI \u529f\u80fd\uff0c\u53ef\u5728 Google Play \u7b49\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d
      • QPython+ \u2013 \u7531\u5f00\u6e90\u8d21\u732e\u8005\u63a8\u51fa\u7684\u793e\u533a\u7248\uff0c\u63d0\u4f9b\u5404\u79cd\u65b0\u7279\u6027
      • QPython Plus \u2013 \u6269\u5c55\u6743\u9650\u7248\u672c\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff09
      "},{"location":"getting-started/#_1","title":"\u4e3b\u8981\u7279\u6027","text":"
      • \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668 - \u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51
      • QSL4A \u96c6\u6210 - \u4f7f\u7528 Python \u63a7\u5236 Android \u786c\u4ef6\u548c API
      • GenAI \u80fd\u529b\u96c6\u6210 - \u652f\u6301\u672c\u5730\u8fd0\u884c\u7684 LLM\u3001OpenAI \u7b49\u5404\u79cd LLM \u5e93\uff0c\u4ee5\u53ca\u53ef\u5728 QPython \u4e0a\u8fdb\u884c Vibe Coding \u5f00\u53d1\u7684 AIPyApp
      • \u6269\u5c55\u5305\u5b89\u88c5 - \u652f\u6301\u901a\u8fc7 QPYPI \u548c pip \u5b89\u88c5\u6269\u5c55\u5305
      • \u5185\u7f6e\u7f16\u8f91\u5668 - \u8bed\u6cd5\u9ad8\u4eae\u548c\u4ee3\u7801\u7f16\u8f91
      • \u591a\u79cd\u8fd0\u884c\u6a21\u5f0f - \u9664\u63a7\u5236\u53f0\u7a0b\u5e8f\u5916\uff0c\u8fd8\u652f\u6301 Android \u539f\u751f UI\uff08\u901a\u8fc7 QSL4A \u63a5\u53e3\uff09\u4ee5\u53ca Pygame / Turtle / Tkinter \u7b49\u8fd0\u884c\u65b9\u5f0f
      "},{"location":"getting-started/#1","title":"1. \u4eea\u8868\u76d8","text":"

      \u5b89\u88c5 QPython \u540e\uff0c\u70b9\u51fb\u5176\u56fe\u6807\u542f\u52a8\u3002\u60a8\u5c06\u770b\u5230\u5e26\u6709 QPython \u6807\u5fd7\u548c\u4ee5\u4e0b\u529f\u80fd\u7684\u4e3b\u4eea\u8868\u76d8\uff1a

      "},{"location":"getting-started/#_2","title":"\u4eea\u8868\u76d8\u529f\u80fd","text":"

      QPython \u4eea\u8868\u76d8\u63d0\u4f9b\u5bf9\u6240\u6709\u4e3b\u8981\u529f\u80fd\u7684\u5feb\u901f\u8bbf\u95ee\uff1a

      • \u7ec8\u7aef \u2014 \u8bbf\u95ee Python \u63a7\u5236\u53f0\u548c shell \u4ee5\u76f4\u63a5\u6267\u884c\u547d\u4ee4
      • Notebook \u2014 \u7528\u4e8e\u6570\u636e\u5206\u6790\u548c\u5b9e\u9a8c\u7684\u4ea4\u4e92\u5f0f Jupyter \u98ce\u683c\u7b14\u8bb0\u672c
      • \u7f16\u8f91\u5668 \u2014 \u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668\uff0c\u5177\u6709\u8bed\u6cd5\u9ad8\u4eae\u529f\u80fd\uff0c\u7528\u4e8e\u7f16\u5199 Python \u811a\u672c
      • \u8d44\u6e90\u7ba1\u7406\u5668 \u2014 \u6d4f\u89c8\u548c\u7ba1\u7406\u60a8\u7684\u6587\u4ef6\u3001\u811a\u672c\u548c\u9879\u76ee
      • QPYPI \u2014 \u5b89\u88c5 Python \u5305\u548c\u6269\u5c55\u3002\u8be6\u89c1 QPYPI \u6307\u5357
      • \u8bbe\u7f6e \u2014 \u914d\u7f6e QPython \u9996\u9009\u9879\u548c\u8fd0\u884c\u9009\u9879
      • \u793e\u533a \u2014 \u8bbf\u95ee QPython \u793e\u533a\u8d44\u6e90\u3001\u8bba\u575b\u548c\u5e2e\u52a9
      • \u8bfe\u7a0b \u2014 \u8bbf\u95ee Python \u7f16\u7a0b\u7684\u5b66\u4e60\u6750\u6599\u548c\u6559\u7a0b

      \u70b9\u51fb\u4efb\u4f55\u56fe\u6807\u4ee5\u8bbf\u95ee\u76f8\u5e94\u7684\u529f\u80fd\u3002

      "},{"location":"getting-started/#2","title":"2. \u7ec8\u7aef\u548c\u7f16\u8f91\u5668","text":""},{"location":"getting-started/#_3","title":"\u7ec8\u7aef","text":"

      \u7ec8\u7aef\u63d0\u4f9b Python \u63a7\u5236\u53f0\uff0c\u652f\u6301\uff1a - \u63a2\u7d22\u5bf9\u8c61\u5c5e\u6027 - \u6d4b\u8bd5\u8bed\u6cd5\u548c\u60f3\u6cd5 - \u76f4\u63a5\u6267\u884c\u547d\u4ee4

      \u4f7f\u7528\u52a0\u53f7\u6309\u94ae\uff081\uff09\u6253\u5f00\u65b0\u7ec8\u7aef\u6807\u7b7e\u9875\uff0c\u901a\u8fc7\u4e0b\u62c9\u83dc\u5355\uff082\uff09\u5207\u6362\uff0c\u5e76\u4f7f\u7528\u5173\u95ed\u6309\u94ae\uff083\uff09\u5173\u95ed\u3002

      "},{"location":"getting-started/#_4","title":"\u7f16\u8f91\u5668","text":"

      \u7f16\u8f91\u5668\u5e95\u90e8\u529f\u80fd\u680f\u5305\u542b\u4ee5\u4e0b\u5de5\u5177\uff08\u4ece\u5de6\u5230\u53f3\uff09\uff1a

      • \u5207\u6362\u5feb\u6377\u8f93\u5165\uff08\u5305\u542b def / if / else / elif / class \u7b49\u5173\u952e\u8bcd\uff09
      • \u9501\u5b9a\uff08\u9632\u6b62\u8bef\u89e6\uff09
      • \u8df3\u8f6c
      • \u4fdd\u5b58
      • \u8fd0\u884c
      • \u641c\u7d22
      • \u64a4\u9500
      • \u91cd\u505a
      • \u53e6\u5b58
      • \u6700\u8fd1\u6587\u4ef6
      • \u4ee3\u7801\u7247\u6bb5

      \u91cd\u8981\u63d0\u793a\uff1a \u4fdd\u5b58\u65f6\u8bf7\u624b\u52a8\u6dfb\u52a0 .py \u6269\u5c55\u540d\uff0c\u56e0\u4e3a\u7f16\u8f91\u5668\u4e0d\u4f1a\u81ea\u52a8\u6dfb\u52a0\u3002

      "},{"location":"getting-started/#3","title":"3. \u8d44\u6e90\u7ba1\u7406\u5668\uff08\u6587\u4ef6\u7ba1\u7406\uff09","text":"

      \u901a\u8fc7 \u8d44\u6e90\u7ba1\u7406\u5668 \u8bbf\u95ee\u811a\u672c\u548c\u9879\u76ee\uff0c\u652f\u6301\u6d4f\u89c8\u3001\u7ec4\u7ec7\u548c\u7ba1\u7406\u6240\u6709 Python \u6587\u4ef6\u3002

      "},{"location":"getting-started/#_5","title":"\u811a\u672c","text":"

      \u811a\u672c\u662f\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/scripts3/ \u4e2d\u7684\u5355\u4e2a Python \u6587\u4ef6\uff08\u9488\u5bf9 Python 3\uff09\u3002

      \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u811a\u672c - \u6253\u5f00 \u2014 \u4f7f\u7528\u5185\u7f6e\u7f16\u8f91\u5668\u7f16\u8f91 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u811a\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u811a\u672c

      "},{"location":"getting-started/#_6","title":"\u9879\u76ee","text":"

      \u9879\u76ee\u662f\u5305\u542b main.py \u4f5c\u4e3a\u5165\u53e3\u70b9\u7684\u76ee\u5f55\u3002\u60a8\u53ef\u4ee5\u5728\u540c\u4e00\u76ee\u5f55\u4e2d\u5305\u542b\u5176\u4ed6\u4f9d\u8d56\u9879\u548c\u8d44\u6e90\u3002\u5c06\u9879\u76ee\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/projects3/ \u4e2d\u3002

      "},{"location":"getting-started/#_7","title":"\u7b14\u8bb0\u672c","text":"

      Jupyter \u98ce\u683c\u7684\u7b14\u8bb0\u672c\u4e5f\u901a\u8fc7\u8d44\u6e90\u7ba1\u7406\u5668\u8fdb\u884c\u7ba1\u7406\uff0c\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/notebooks/ \u4e2d\u3002

      \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u7b14\u8bb0\u672c - \u6253\u5f00 \u2014 \u63a2\u7d22\u7b14\u8bb0\u672c\u5185\u5bb9 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u7b14\u8bb0\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u7b14\u8bb0\u672c

      "},{"location":"getting-started/#4","title":"4. \u5e93","text":"

      \u901a\u8fc7\u5b89\u88c5\u7b2c\u4e09\u65b9\u5e93\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

      "},{"location":"getting-started/#_8","title":"\u5305\u5b89\u88c5\u65b9\u6cd5","text":"

      QPYPI\uff08\u63a8\u8350\uff09

      \u4ece QPYPI \u5b89\u88c5\u9884\u7f16\u8bd1\u7684\u5e93\uff0c\u5305\u62ec numpy\u3001scipy \u7b49\u79d1\u5b66\u5305\u3002

      \u8be6\u89c1 QPYPI \u6307\u5357\u3002

      PIP \u5ba2\u6237\u7aef

      \u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216 QPYPI \u754c\u9762\u5b89\u88c5\u7eaf Python \u5e93\uff1a

      pip install requests\n

      \u9884\u7f16\u8bd1\u5305

      \u5bf9\u4e8e\u5177\u6709 C/C++/Rust \u4f9d\u8d56\u7684\u5305\uff0c\u4f7f\u7528 QPython \u7684\u9884\u7f16\u8bd1\u5305\uff1a

      pip install numpy-qpython\npip install scipy-aipy\n

      \u8be6\u89c1 QPYPI \u6307\u5357 \u83b7\u53d6\u53ef\u7528\u5305\u7684\u5b8c\u6574\u5217\u8868\u3002

      \u624b\u52a8\u5b89\u88c5

      \u60a8\u4e5f\u53ef\u4ee5\u5c06\u5e93\u590d\u5236\u5230 /storage/emulated/0/Android/data/org.qpython.qpy/files/lib/python3.12/site-packages/\u3002

      "},{"location":"getting-started/#5","title":"5. \u8fd0\u884c\u6a21\u5f0f","text":"

      QPython \u652f\u6301\u591a\u79cd\u8fd0\u884c\u6a21\u5f0f\u4ee5\u6ee1\u8db3\u4e0d\u540c\u7684\u7528\u4f8b\uff1a

      "},{"location":"getting-started/#_9","title":"\u63a7\u5236\u53f0\u6a21\u5f0f","text":"

      \u5e38\u89c4 Python \u811a\u672c\u7684\u9ed8\u8ba4\u6a21\u5f0f\u3002

      "},{"location":"getting-started/#qsl4a","title":"QSL4A \u6a21\u5f0f","text":"

      \u901a\u8fc7 QSL4A \u5e93\u8c03\u7528 Android API \u7684\u811a\u672c\u3002

      import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello Android!')\n

      \u8be6\u89c1 QSL4A \u6587\u6863 \u83b7\u53d6\u5b8c\u6574\u7684 API \u53c2\u8003\u3002

      "},{"location":"getting-started/#webapp","title":"WebApp \u6a21\u5f0f","text":"

      \u4f7f\u7528\u540e\u7aef\u670d\u52a1\u5668\u521b\u5efa\u57fa\u4e8e Web \u7684\u5e94\u7528\u7a0b\u5e8f\u3002\u9700\u5728\u811a\u672c\u5f00\u5934\u6dfb\u52a0\u4ee5\u4e0b\u4e24\u884c headers\uff1a

      #qpy:webapp:<\u9879\u76ee\u540d>\n#qpy://localhost:<web\u670d\u52a1\u4fa6\u542c\u7684\u7aef\u53e3>/<\u9ed8\u8ba4\u4e3b\u8def\u5f84>\n

      \u4f8b\u5982\uff1a

      #qpy:webapp:Hello QPython\n#qpy://localhost:8080/hello\n\nfrom bottle import route, run, Bottle\n\napp = Bottle()\n\n@route('/hello')\ndef hello():\n    return '<h1>Hello from QPython!</h1>'\n\nrun(app, host='localhost', port=8080)\n
      "},{"location":"getting-started/#q","title":"Q \u6a21\u5f0f\uff08\u65e0\u63a7\u5236\u53f0\u6a21\u5f0f\uff09","text":"

      \u9759\u9ed8\u6a21\u5f0f\u8fd0\u884c\u811a\u672c\uff0c\u4e0d\u663e\u793a\u63a7\u5236\u53f0\u3002\u9700\u5728\u811a\u672c\u5f00\u5934\u6dfb\u52a0 header\uff1a

      #qpy:quiet\n\nimport time\n\nwhile True:\n    # \u60a8\u7684\u540e\u53f0\u4efb\u52a1\n    time.sleep(60)\n
      \u5982\u679c\u9700\u8981\u8fd0\u884c\u5e26 GUI \u7684 QSL4A \u7a0b\u5e8f\u4e14\u4e0d\u5e0c\u671b\u663e\u793a\u63a7\u5236\u53f0\u4fe1\u606f\uff0c\u63a8\u8350\u4f7f\u7528\u6b64\u6a21\u5f0f\u3002

      "},{"location":"getting-started/#6","title":"6. \u793e\u533a\u4e0e\u652f\u6301","text":"

      \u8bbf\u95ee QPython.org \u83b7\u53d6\u6587\u6863\u3001\u7528\u6237\u793e\u533a\u53ca\u5e2e\u52a9\u95ee\u7b54\u3002

      \u793e\u533a\u94fe\u63a5\uff1a - Facebook \u7fa4\u7ec4 - GitHub - \u95ee\u9898\u53cd\u9988

      \u4e0b\u4e00\u6b65\uff1a - \u5c1d\u8bd5 Hello World \u6559\u7a0b - \u63a2\u7d22 QSL4A API \u4ee5\u96c6\u6210 Android - \u4e86\u89e3 QPython \u7248\u672c

      "},{"location":"getting-started/#_10","title":"\u89c6\u9891\u4ecb\u7ecd","text":""},{"location":"getting-started/#_11","title":"\u4e0b\u4e00\u6b65","text":"

      \u5982\u679c\u60a8\u5df2\u7ecf\u521d\u6b65\u4e86\u89e3\u4e86 QPython \u7684\u529f\u80fd\uff0c\u6b22\u8fce\u5f00\u59cb\u4f53\u9a8c\u7f16\u7a0b\u7684\u4e50\u8da3\uff01\u8bd5\u8bd5 Hello World \u6559\u7a0b \u8fc8\u51fa\u60a8\u7684\u7b2c\u4e00\u6b65\u3002

      "},{"location":"qpypi-guide/","title":"QPYPI","text":"

      \u60a8\u53ef\u4ee5\u901a\u8fc7\u5b89\u88c5\u5305\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

      "},{"location":"qpypi-guide/#_1","title":"\u5305\u5b89\u88c5\u652f\u6301","text":""},{"location":"qpypi-guide/#python","title":"\u7eaf Python \u5305","text":"

      QPython \u652f\u6301\u4f7f\u7528\u7eaf Python \u5f00\u53d1\u7684 Python \u5305\u3002\u60a8\u53ef\u4ee5\u76f4\u63a5\u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216\u4eea\u8868\u76d8\u4e0a\u7684 QPYPI \u4f7f\u7528 pip install \u5b89\u88c5\u8fd9\u4e9b\u5305\u3002

      "},{"location":"qpypi-guide/#_2","title":"\u9884\u7f16\u8bd1\u5305","text":"

      \u5982\u679c\u67d0\u4e9b\u5305\uff08\u6216\u5b83\u4eec\u7684\u4f9d\u8d56\uff09\u662f\u7528 Rust/C/C++ \u5f00\u53d1\u7684\uff0cQPython \u65e0\u6cd5\u76f4\u63a5\u652f\u6301\u5b83\u4eec\uff0c\u56e0\u4e3a QPython \u4e0a\u6ca1\u6709\u7f16\u8bd1\u5668\u5de5\u5177\u94fe\u652f\u6301\u3002\u4f46\u662f\uff0cQPython \u56e2\u961f\u5df2\u7ecf\u9884\u7f16\u8bd1\u4e86\u4e00\u4e9b\u5e38\u7528\u5305\uff0c\u5e76\u5728 QPython \u7684 QPYPI/Extensions \u4e2d\u53d1\u5e03\uff0c\u4f9b\u7528\u6237\u8f7b\u677e\u5b89\u88c5\u3002

      "},{"location":"qpypi-guide/#_3","title":"\u5b89\u88c5\u9884\u7f16\u8bd1\u5305","text":"

      \u60a8\u53ef\u4ee5\u901a\u8fc7\u4ee5\u4e0b\u65b9\u5f0f\u5b89\u88c5\u9884\u7f16\u8bd1\u5305\uff1a

      1. \u901a\u8fc7 QPython \u5e94\u7528\uff1a\u76f4\u63a5\u4ece QPython \u5e94\u7528\u5185\u7684 QPYPI \u6216 Extensions \u5b89\u88c5
      2. \u901a\u8fc7 PyPI\uff1a\u8bbf\u95ee https://pypi.org/user/qpythonx/ \u67e5\u770b\u53ef\u7528\u7684\u5305
      3. \u901a\u8fc7 pip \u547d\u4ee4\uff1a
      4. pip install xxx-qpython - \u5e26 -qpython \u540e\u7f00\u7684\u5305
      5. pip install xxx-aipy - \u5e26 -aipy \u540e\u7f00\u7684\u5305\uff08\u901a\u5e38\u662f AI/ML \u76f8\u5173\u7684\u5305\uff09

      \u6ce8\u610f\uff1a\u6211\u4eec\u901a\u5e38\u6839\u636e\u5305\u7684\u9884\u671f\u7528\u9014\u6dfb\u52a0\u8fd9\u4e9b\u540e\u7f00\u4e4b\u4e00\u3002

      "},{"location":"qpypi-guide/#_4","title":"\u8bf7\u6c42\u65b0\u5305","text":"

      \u5982\u679c\u60a8\u9700\u8981\u5f53\u524d\u4e0d\u652f\u6301\u7684\u5305\uff1a

      • \u5728 qpython.org \u9879\u76ee \u4e2d\u63d0\u51fa\u95ee\u9898
      • QPython \u56e2\u961f\u5c06\u8003\u8651\u9884\u7f16\u8bd1\u5e76\u5c06\u5176\u6dfb\u52a0\u5230\u4ed3\u5e93\u4e2d

      \u83b7\u53d6\u66f4\u591a\u5e2e\u52a9\u548c\u53c2\u4e0e\u793e\u533a\u7684\u65b9\u5f0f\uff0c\u8bf7\u53c2\u9605 \u793e\u533a\u4e0e\u53cd\u9988 \u90e8\u5206\u3002

      \u6ce8\u610f\uff1a\u7531\u4e8e\u4e0d\u540c\u7684\u8ba1\u7b97\u673a\u67b6\u6784\uff0c\u6211\u4eec\u65e0\u6cd5\u4fdd\u8bc1 QPYPI \u5305\u542b PyPI \u4e0a\u7684\u6240\u6709\u5305\u3002

      "},{"location":"qpython-x/","title":"QPython \u7248\u672c","text":"

      QPython \u662f Android \u7684 Python \u5f15\u64ce\u3002\u5b83\u5305\u542b\u4ee4\u4eba\u60ca\u53f9\u7684\u529f\u80fd\uff0c\u5982 Python \u89e3\u91ca\u5668\u3001\u8fd0\u884c\u73af\u5883\u3001\u7f16\u8f91\u5668\u3001QPYI \u548c\u96c6\u6210\u7684 SL4A\u3002\u5b83\u8ba9\u60a8\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 Android \u4e0a\u4f7f\u7528 Python\u3002\u800c\u4e14\u5b83\u662f\u514d\u8d39\u7684\u3002

      QPython \u5df2\u7ecf\u5728\u5168\u7403\u62e5\u6709\u6570\u767e\u4e07\u7528\u6237\uff0c\u4e5f\u662f\u4e00\u4e2a\u5f00\u6e90\u9879\u76ee\u3002

      \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

      "},{"location":"qpython-x/#qpython_1","title":"QPython","text":"

      \u6807\u51c6\u7248\uff1a\u9488\u5bf9 AI \u6027\u80fd\u548c\u901a\u7528\u5e94\u7528\u5546\u5e97\u517c\u5bb9\u6027\u4f18\u5316

      \u4e3b\u8981\u7248\u672c\uff0c\u53ef\u5728 Google Play \u548c\u5176\u4ed6\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002\u6b64\u7248\u672c\u4e13\u6ce8\u4e8e AI \u529f\u80fd\uff0c\u4f7f AI \u65f6\u4ee3\u7528\u6237\u66f4\u5bb9\u6613\u5b66\u4e60\u548c\u4f7f\u7528 Python\u3002

      \u4e3b\u8981\u7279\u6027\uff1a - AI \u9a71\u52a8\u7684\u7f16\u7801\u8f85\u52a9\u548c\u5b66\u4e60\u5de5\u5177 - \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668\uff1a\u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51 - \u652f\u6301\u591a\u79cd\u9879\u76ee\u7c7b\u578b\uff1a\u63a7\u5236\u53f0\u3001SL4A\u3001WebApp - \u65b9\u4fbf\u7684\u4e8c\u7ef4\u7801\u8bfb\u53d6\u5668\uff0c\u7528\u4e8e\u5c06\u4ee3\u7801\u4f20\u8f93\u5230\u624b\u673a - QPYPI \u548c\u81ea\u5b9a\u4e49\u4ed3\u5e93\uff0c\u7528\u4e8e\u9884\u7f16\u8bd1 wheel \u5305 -\u6613\u4e8e\u4f7f\u7528\u7684\u8bed\u6cd5\u9ad8\u4eae\u7f16\u8f91\u5668 - \u5b8c\u5584\u7684\u6587\u6863\u548c\u793e\u533a\u652f\u6301

      \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

      \u4e0b\u8f7d\uff1a \u53ef\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

      "},{"location":"qpython-x/#qpython_2","title":"QPython+","text":"

      \u793e\u533a\u7248\uff1a\u516c\u5f00\u652f\u6301\u5404\u79cd\u793e\u533a\u9a71\u52a8\u7684\u529f\u80fd\uff1b\u53ef\u5728\u90e8\u5206\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

      \u793e\u533a\u5f00\u6e90\u7248\u672c\uff08\u6b63\u5728\u89c4\u5212\u548c\u51c6\u5907\u4e2d\uff09\u3002\u6b64\u7248\u672c\u4e13\u4e3a\u60f3\u8981\u53c2\u4e0e QPython \u9879\u76ee\u5f00\u53d1\u7684\u8d21\u732e\u8005\u800c\u8bbe\u8ba1\uff0c\u652f\u6301\u9488\u5bf9\u4e0d\u540c\u5236\u9020\u5546\u7684\u5b9a\u5236\u3002

      \u4e3b\u8981\u7279\u6027\uff1a - \u793e\u533a\u9a71\u52a8\u5f00\u53d1 - \u652f\u6301\u4f9b\u5e94\u5546\u5b9a\u5236 - \u66f4\u7075\u6d3b\u7684\u914d\u7f6e\u9009\u9879 - \u5f00\u653e\u4f9b\u8d21\u732e\u8005\u52a0\u5165\u5f00\u53d1

      \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

      \u4e0b\u8f7d\uff1a \u5c06\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

      \u6ce8\u610f\uff1a \u6b64\u7248\u672c\u76ee\u524d\u6b63\u5728\u89c4\u5212\u51c6\u5907\u4e2d\u3002\u8bf7\u5173\u6ce8\u66f4\u65b0\uff01

      "},{"location":"qpython-x/#qpython-plus","title":"QPython Plus","text":"

      QPython+ \u5b8c\u5168\u8bbf\u95ee\u7248\uff1a\u6388\u4e88\u8c03\u7528\u6240\u6709 Android \u63a5\u53e3\u7684\u5b8c\u6574\u6743\u9650\u3002\u4e0b\u8f7d\u94fe\u63a5\u4ec5\u901a\u8fc7\u5b98\u65b9\u4e91\u76d8\u63d0\u4f9b\u3002

      \u5177\u6709\u6269\u5c55\u6743\u9650\u7684\u7279\u6b8a\u7248\u672c\uff0c\u63d0\u4f9b\u5bf9\u8bbe\u5907\u7684\u6700\u5927\u63a7\u5236\u3002\u7531\u4e8e\u5176\u654f\u611f\u7684\u6743\u9650\u8981\u6c42\uff0c\u6b64\u7248\u672c\u4e0d\u4f1a\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u53d1\u5e03\u3002

      \u4e3b\u8981\u7279\u6027\uff1a - \u5b8c\u6574\u7684 SL4A API \u8bbf\u95ee\uff0c\u5305\u62ec\u654f\u611f\u529f\u80fd - SMS/\u901a\u8bdd\u63a7\u5236 API - \u9ad8\u7ea7\u7cfb\u7edf\u96c6\u6210 - \u6700\u5927\u7684\u8bbe\u5907\u63a7\u5236\u80fd\u529b

      \u6743\u9650\uff1a \u9700\u8981\u5e7f\u6cdb\u7684\u6743\u9650\uff0c\u5305\u62ec\uff1a - \u84dd\u7259 - \u4f4d\u7f6e\uff08GPS\uff09 - \u8bfb\u53d6/\u53d1\u9001\u77ed\u4fe1 - \u6253\u7535\u8bdd - \u76f8\u673a\u548c\u9ea6\u514b\u98ce - \u7cfb\u7edf\u8bbe\u7f6e - \u4ee5\u53ca\u5176\u4ed6\u654f\u611f\u6743\u9650

      \u4e0b\u8f7d\uff1a \u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\u3002\u4ec5\u901a\u8fc7\u7279\u6b8a\u6e20\u9053\u5206\u53d1\u3002

      \u91cd\u8981\u63d0\u793a\uff1a QPython \u4e0d\u4f1a\u5728\u540e\u53f0\u672a\u7ecf\u60a8\u77e5\u6089\u4f7f\u7528\u8fd9\u4e9b\u6743\u9650\u3002\u5982\u679c\u4f7f\u7528 SL4A API \u65f6\u51fa\u73b0\u5f02\u5e38\uff0c\u8bf7\u68c0\u67e5\u7cfb\u7edf\u8bbe\u7f6e\u4e2d\u662f\u5426\u5df2\u542f\u7528\u76f8\u5173\u6743\u9650\u3002

      "},{"location":"tutorial-hello-world/","title":"\u7f16\u5199\"Hello World\"","text":""},{"location":"tutorial-hello-world/#hello-world_1","title":"Hello world","text":"

      \u597d\u7684\uff0c\u5728\u60a8\u5bf9 QPython \u6709\u4e86\u4e00\u5b9a\u7684\u4e86\u89e3\u4e4b\u540e\uff0c\u8ba9\u6211\u4eec\u5728 QPython \u4e2d\u521b\u5efa\u6211\u4eec\u7684\u7b2c\u4e00\u4e2a\u7a0b\u5e8f\u3002\u663e\u7136\uff0c\u5b83\u5c06\u662f helloworld.py\u3002;)

      \u542f\u52a8 QPython\uff0c\u6253\u5f00\u7f16\u8f91\u5668\u5e76\u8f93\u5165\u4ee5\u4e0b\u4ee3\u7801\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello, QPYTHON!')\n

      \u6beb\u65e0\u7591\u95ee\uff0c\u5b83\u4e0e\u5176\u4ed6\u4efb\u4f55 hello-world \u7a0b\u5e8f\u5e76\u65e0\u4e0d\u540c\u3002\u6267\u884c\u65f6\uff0c\u5b83\u53ea\u662f\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u5f39\u51fa\u6d88\u606f\uff08\u89c1\u9876\u90e8\u622a\u56fe\uff09\u3002\u65e0\u8bba\u5982\u4f55\uff0c\u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684 QPython \u7a0b\u5e8f\u793a\u4f8b\u3002

      "},{"location":"tutorial-hello-world/#_1","title":"\u4ee3\u7801\u7406\u89e3","text":"

      \u5b83\u4ee5 import androidhelper \u5f00\u5934\u2014\u2014\u8fd9\u662f QPython \u4e2d\u6700\u6709\u7528\u7684\u6a21\u5757\uff0c\u5b83\u5c01\u88c5\u4e86 Python \u4e2d\u53ef\u7528\u7684\u51e0\u4e4e\u6240\u6709\u4e0e Android \u7684\u63a5\u53e3\u3002\u4efb\u4f55\u5728 QPython \u4e2d\u5f00\u53d1\u7684\u811a\u672c\u90fd\u4ee5\u8fd9\u4e2a\u8bed\u53e5\u5f00\u5934\uff08\u81f3\u5c11\u5982\u679c\u5b83\u58f0\u79f0\u8981\u4e0e\u7528\u6237\u901a\u4fe1\u7684\u8bdd\uff09\u3002\u5728\u6b64\u5904\u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u5e93 \u548c import \u8bed\u53e5 \u7684\u5185\u5bb9\u3002

      \u63a5\u4e0b\u6765\u6211\u4eec\u521b\u5efa\u4e00\u4e2a droid \u5bf9\u8c61\uff08\u5b9e\u9645\u4e0a\u662f\u4e00\u4e2a\u7c7b\uff09\uff0c\u5b83\u5bf9\u4e8e\u8c03\u7528 RPC \u51fd\u6570\u4ee5\u4e0e Android \u901a\u4fe1\u662f\u5fc5\u8981\u7684\u3002

      \u6211\u4eec\u4ee3\u7801\u7684\u6700\u540e\u4e00\u884c\u8c03\u7528\u4e86\u8fd9\u6837\u7684\u51fd\u6570\uff0cdroid.makeToast()\uff0c\u5b83\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u4e00\u4e2a\u5c0f\u7684\u5f39\u51fa\u6d88\u606f\uff08\"toast\"\uff09\u3002

      \u597d\u7684\uff0c\u8ba9\u6211\u4eec\u6dfb\u52a0\u4e00\u4e9b\u66f4\u591a\u7684\u529f\u80fd\u3002\u8ba9\u5b83\u8be2\u95ee\u7528\u6237\u540d\u5e76\u5411\u7528\u6237\u6253\u62db\u547c\u3002

      "},{"location":"tutorial-hello-world/#_2","title":"\u66f4\u591a\u793a\u4f8b","text":"

      \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 dialogGetInput \u8c03\u7528\u663e\u793a\u4e00\u4e2a\u5e26\u6709\u6807\u9898\u3001\u63d0\u793a\u3001\u7f16\u8f91\u5b57\u6bb5\u548c \u786e\u5b9a \u548c \u53d6\u6d88 \u6309\u94ae\u7684\u7b80\u5355\u5bf9\u8bdd\u6846\u3002\u7528\u4ee5\u4e0b\u4ee3\u7801\u66ff\u6362\u60a8\u7684\u6700\u540e\u4e00\u884c\u4ee3\u7801\u5e76\u5c06\u5176\u4fdd\u5b58\u4e3a hello1.py\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\n

      \u597d\u7684\uff0c\u6211\u8ba4\u4e3a\u5b83\u5e94\u8be5\u8fd4\u56de\u4efb\u4f55\u54cd\u5e94\uff0c\u4efb\u4f55\u7528\u6237\u53cd\u5e94\u3002\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u6211\u5199 respond = ...\u3002\u4f46\u8fd9\u4e2a\u8c03\u7528\u5b9e\u9645\u4e0a\u8fd4\u56de\u4ec0\u4e48\uff1f\u8ba9\u6211\u4eec\u68c0\u67e5\u4e00\u4e0b\u3002\u53ea\u9700\u5728\u6700\u540e\u4e00\u884c\u540e\u6dfb\u52a0 print \u8bed\u53e5\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\n

      \u7136\u540e\u4fdd\u5b58\u5e76\u8fd0\u884c\u5b83...

      \u54ce\u5440\uff01\u6ca1\u6709\u6253\u5370\uff1f\u522b\u62c5\u5fc3\u3002\u53ea\u9700\u62c9\u4e0b\u901a\u77e5\u680f\uff0c\u60a8\u5c31\u4f1a\u770b\u5230\"QPython Program Output: hello1.py\"\u2014\u2014\u70b9\u51fb\u5b83\uff01

      \u5982\u60a8\u6240\u89c1\uff0cdroid.dialogGetInput() \u8fd4\u56de\u4e00\u4e2a\u5305\u542b\u4e09\u4e2a\u5b57\u6bb5\u7684 JSON \u5bf9\u8c61\u3002\u6211\u4eec\u53ea\u9700\u8981\u4e00\u4e2a\u2014\u2014result\uff0c\u5176\u4e2d\u5305\u542b\u7528\u6237\u5b9e\u9645\u8f93\u5165\u7684\u5185\u5bb9\u3002

      \u8ba9\u6211\u4eec\u6dfb\u52a0\u811a\u672c\u7684\u53cd\u5e94\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nmessage = f'Hello, {respond.result}!'\ndroid.makeToast(message)\n

      \u6700\u540e\u4e24\u884c\uff081\uff09\u683c\u5f0f\u5316\u6d88\u606f\uff0c\uff082\uff09\u4ee5 toast \u5f62\u5f0f\u5411\u7528\u6237\u663e\u793a\u6d88\u606f\u3002\u5982\u679c\u60a8\u4ecd\u7136\u4e0d\u77e5\u9053 f-string \u662f\u4ec0\u4e48\u610f\u601d\uff0c\u8bf7\u53c2\u9605 Python \u6587\u6863\u3002

      \u54c7\uff01\u5b83\u5de5\u4f5c\u4e86\uff01;)

      \u73b0\u5728\u6211\u8981\u5728\u90a3\u91cc\u6dfb\u52a0\u4e00\u4e9b\u903b\u8f91\u3002\u60f3\u4e00\u60f3\uff1a\u5982\u679c\u7528\u6237\u70b9\u51fb \u53d6\u6d88 \u6309\u94ae\uff0c\u6216\u8005\u70b9\u51fb \u786e\u5b9a \u4f46\u5c06\u8f93\u5165\u5b57\u6bb5\u7559\u7a7a\uff0c\u4f1a\u53d1\u751f\u4ec0\u4e48\uff1f

      \u60a8\u53ef\u4ee5\u73a9\u8fd9\u4e2a\u7a0b\u5e8f\uff0c\u68c0\u67e5 respond \u53d8\u91cf\u5728\u6bcf\u79cd\u60c5\u51b5\u4e0b\u5305\u542b\u4ec0\u4e48\u3002

      \u9996\u5148\uff0c\u6211\u60f3\u5c06\u7528\u6237\u8f93\u5165\u7684\u6587\u672c\u653e\u5165\u4e00\u4e2a\u5355\u72ec\u7684\u53d8\u91cf\u4e2d\uff1aname = respond.result\u3002\u7136\u540e\u6211\u68c0\u67e5\u5b83\uff0c\u5982\u679c\u5b83\u5305\u542b\u4efb\u4f55\u771f\u5b9e\u6587\u672c\uff0c\u5b83\u5c06\u88ab\u89c6\u4e3a\u540d\u79f0\u5e76\u7528\u4e8e\u95ee\u5019\u3002\u5426\u5219\uff0c\u5c06\u663e\u793a\u53e6\u4e00\u6761\u6d88\u606f\u3002\u5c06\u7b2c\u4e94\u884c message = f'Hello, {respond.result}!' \u66ff\u6362\u4e3a\u4ee5\u4e0b\u4ee3\u7801\uff1a

      name = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\n

      \u4f7f\u7528\u5de5\u5177\u680f\u4e0a\u7684 < \u548c > \u6309\u94ae\u6765\u7f29\u8fdb/\u53d6\u6d88\u7f29\u8fdb if \u8bed\u53e5\u4e2d\u7684\u884c\uff08\u6216\u8005\u53ea\u9700\u4f7f\u7528\u7a7a\u683c/\u9000\u683c\u952e\uff09\u3002\u60a8\u53ef\u4ee5\u5728 \u6b64\u5904 \u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u7f29\u8fdb\u7684\u5185\u5bb9\uff1bif \u8bed\u53e5\u5728 \u6b64\u5904 \u63cf\u8ff0\u3002

      \u9996\u5148\uff0c\u6211\u4eec\u5c06\u7528\u6237\u8f93\u5165\u653e\u5165 name \u53d8\u91cf\u3002\u7136\u540e\u6211\u4eec\u68c0\u67e5 name \u662f\u5426\u5305\u542b\u4efb\u4f55\u5185\u5bb9\uff1f\u5982\u679c\u7528\u6237\u7559\u7a7a\u884c\u5e76\u70b9\u51fb \u786e\u5b9a\uff0c\u8fd4\u56de\u503c\u662f\u7a7a\u5b57\u7b26\u4e32 ''\u3002\u5982\u679c\u6309\u4e0b\u4e86 \u53d6\u6d88 \u6309\u94ae\uff0c\u8fd4\u56de\u503c\u662f None\u3002\u5728 if \u8bed\u53e5\u4e2d\uff0c\u4e24\u8005\u90fd\u88ab\u89c6\u4e3a\u5047\u3002\u56e0\u6b64\uff0c\u53ea\u6709\u5f53 name \u5305\u542b\u4efb\u4f55\u6709\u610f\u4e49\u7684\u5185\u5bb9\u65f6\uff0cthen \u8bed\u53e5\u624d\u4f1a\u6267\u884c\uff0c\u5e76\u663e\u793a\u95ee\u5019\u8bed\"Hello, ...!\"\u3002\u5982\u679c\u8f93\u5165\u4e3a\u7a7a\uff0c\u7528\u6237\u5c06\u770b\u5230\"Hey! And you're not very polite, %Username%!\"\u6d88\u606f\u3002

      \u597d\u7684\uff0c\u8fd9\u662f\u6574\u4e2a\u7a0b\u5e8f\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nname = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\ndroid.makeToast(message)\n
      "},{"location":"tutorial-hello-world/#_3","title":"\u8fd0\u884c\u6548\u679c","text":""},{"location":"tutorial-hello-world/#_4","title":"\u4e0b\u4e00\u6b65","text":"

      \u5bf9\u4e8e Python \u65b0\u7528\u6237\uff0c\u63a8\u8350\u5b66\u4e60 Python \u8bed\u6cd5\u5b9e\u8df5 \u8bfe\u7a0b\u6765\u8fdb\u4e00\u6b65\u5b66\u4e60 Python\uff0c\u6216\u8005\u5728 QPython \u7cbe\u9009\u8bfe\u7a0b \u4e2d\u5bfb\u627e\u60f3\u8981\u5b66\u4e60\u7684\u5185\u5bb9\u3002

      "},{"location":"whats-new/","title":"\u66f4\u65b0\u65e5\u5fd7","text":""},{"location":"whats-new/#v392-v393","title":"v3.9.2 / v3.9.3","text":"
      • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
      • \u7f16\u8f91\u5668\u91cd\u5927\u66f4\u65b0\uff0c\u5e26\u6765\u66f4\u6d41\u7545\u7684\u7f16\u8f91\u4f53\u9a8c
      • \u5176\u4ed6\u5404\u79cd\u5c0f\u6539\u8fdb
      "},{"location":"whats-new/#v391","title":"v3.9.1","text":"
      • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
      • \u6269\u5c55\u5305\u73b0\u5728\u652f\u6301 MCP
      • \u9519\u8bef\u4fee\u590d
      "},{"location":"whats-new/#v390","title":"v3.9.0","text":"
      • SDK \u5347\u7ea7\uff0c\u6574\u5408\u6700\u65b0\u7684 Android \u529f\u80fd
      • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
      • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
      • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
      "},{"location":"whats-new/#v3811","title":"v3.8.11","text":"
      • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
      • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
      • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
      "},{"location":"whats-new/#v3810","title":"v3.8.10","text":"
      • \u5185\u7f6e Ollama \u5347\u7ea7\uff1a\u73b0\u5728\u60a8\u53ef\u4ee5\u5728 QPython \u4e2d\u8f7b\u677e\u672c\u5730\u8fd0\u884c Qwen3 / Gemma3 \u6a21\u578b\uff01
      • \u6dfb\u52a0\u4e86\u5f3a\u5927\u7684 MCP \u5e93\uff1a\u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 mcp \u5e93\uff0c\u8ba9\u60a8\u968f\u65f6\u968f\u5730\u643a\u5e26\u5f3a\u5927\u7684 MCP \u529f\u80fd\uff01
      "},{"location":"whats-new/#v389","title":"v3.8.9","text":"

      \u91cd\u5927\u66f4\u65b0\uff01AI \u7f16\u7a0b\u5b8c\u5168\u96c6\u6210\u5230 QPython\uff0c\u8ba9\u60a8\u7684\u7f16\u7a0b\u66f4\u8f7b\u677e\uff01

      • \u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u652f\u6301\uff1a\u65b0\u652f\u6301 AIPyApp\uff0c\u5728 QPython \u4e2d\u5b9e\u73b0\u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u3002\u76ee\u524d\u5904\u4e8e\u6d4b\u8bd5\u9636\u6bb5 - \u52a0\u5165\u6211\u4eec\u7684\u793e\u533a\u83b7\u53d6\u4f7f\u7528\u8bf4\u660e
      • \u65b0 QSL4A \u529f\u80fd\uff1a\u6dfb\u52a0 notebookOpen \u51fd\u6570\uff0c\u652f\u6301\u81ea\u7136\u8bed\u8a00\u63a7\u5236\u6253\u5f00 Notebook \u6587\u4ef6
      • \u5185\u7f6e\u7f16\u8f91\u5668\u5347\u7ea7\uff1a\u589e\u5f3a\u7f16\u8f91\u5668\u529f\u80fd\uff0c\u652f\u6301\u6253\u5f00\u548c\u6d4f\u89c8\u5404\u79cd\u6587\u672c\u6587\u4ef6
      • \u4fbf\u6377\u7684\u6587\u4ef6\u7ba1\u7406\uff1a\u5728\u6587\u4ef6\u7ba1\u7406\u5668\u4e2d\u6dfb\u52a0\u5185\u90e8\u5b58\u50a8\u5165\u53e3\uff0c\u5feb\u901f\u8bbf\u95ee\u60a8\u7684\u6587\u4ef6
      "},{"location":"whats-new/#v388","title":"v3.8.8","text":"
      • \u6587\u4ef6\u8bbf\u95ee\u6743\u9650\u63a7\u5236\u7684\u91cd\u8981\u6539\u8fdb\uff0c\u5141\u8bb8\u7528\u6237\u7075\u6d3b\u5730\u901a\u8fc7 QPython \u7f16\u7a0b\u542f\u7528\u6216\u7981\u7528\u5916\u90e8\u5b58\u50a8\u6587\u4ef6\u7684\u8bbf\u95ee
      • SDK \u5347\u7ea7\uff0c\u589e\u5f3a\u4e86\u5bf9\u65b0\u7248 Android \u7684\u652f\u6301\u548c\u517c\u5bb9\u6027
      • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Anthropic \u548c Google GenAI \u5e93
      "},{"location":"whats-new/#v387","title":"v3.8.7","text":"
      • \u5728\u73b0\u6709 Tkinter \u652f\u6301\u57fa\u7840\u4e0a\uff0c\u5728 Extensions -> Tools \u4e2d\u6dfb\u52a0\u4e86\u4f7f\u7528 Turtle \u7ed8\u5236\u54c6\u5566A\u68a6\u7684\u793a\u4f8b\u4ee3\u7801
      • \u4f18\u5316\u4e86\u624b\u673a\u6743\u9650\u83b7\u53d6\u6d41\u7a0b\uff0c\u63d0\u5347\u7528\u6237\u4f53\u9a8c\u548c\u64cd\u4f5c\u4fbf\u5229\u6027
      • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Google Gen AI \u5e93\uff0c\u65b9\u4fbf\u8bbf\u95ee Gemini Developer API \u548c Vertex AI
      "},{"location":"whats-new/#v386","title":"v3.8.6","text":"
      • Tkinter \u652f\u6301\uff1a\u73b0\u5728\u652f\u6301 Tkinter \u5e93\uff0c\u53ef\u901a\u8fc7 XServer \u8bbf\u95ee\u3002\u8bf7\u8bbf\u95ee www.qpython.org \u7684\u4e91\u76d8\"Extra\"\u94fe\u63a5\u4e0b\u8f7d\u6240\u9700\u6587\u4ef6
      • \u5b58\u50a8\u6743\u9650\u66f4\u65b0\uff1a\u4e3a\u6539\u5584\u7528\u6237\u4f53\u9a8c\uff0c\u6211\u4eec\u6dfb\u52a0\u4e86\u8bfb\u53d6\u624b\u673a\u5b58\u50a8\u7684\u6743\u9650\uff0c\u7528\u4e8e\u8bbf\u95ee\u5b58\u50a8\u5728\u5176\u4ed6\u76ee\u5f55\u4e2d\u7684 Python \u7a0b\u5e8f

      \u6b64\u66f4\u65b0\u540e\uff0cQPython \u548c QPythonPlus\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff0c\u4e13\u4e3a\u9700\u8981\u66f4\u591a\u654f\u611f\u6743\u9650\u7684\u9ad8\u7ea7\u7528\u6237\u8bbe\u8ba1\uff09\u5c06\u4fdd\u6301\u540c\u6b65\u7684\u7248\u672c\u53f7\u3002

      "},{"location":"whats-new/#v352-2025225","title":"v3.5.2 (2025/2/25)","text":"

      \u4e0e\u5f00\u6e90 LLM \u90e8\u7f72\u5de5\u5177 Ollama \u4ee5\u53ca DeepSeek \u5f00\u53d1\u7684 DeepSeek \u5b9e\u73b0\u65e0\u7f1d\u96c6\u6210\uff01

      \u529f\u80fd\uff1a - \u96f6\u95e8\u69db\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5404\u79cd\u5927\u578b\u8bed\u8a00\u6a21\u578b - \u5feb\u901f\u90e8\u7f72 DeepSeek \u7b49\u5c16\u7aef AI \u6a21\u578b - \u4eab\u53d7\u7b80\u7ea6\u7684 API \u8c03\u7528\u4f53\u9a8c - \u6784\u5efa\u5b8c\u5168\u79bb\u7ebf\u7684\u667a\u80fd\u7f16\u7a0b\u73af\u5883

      \u80fd\u529b\uff1a - \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u52a0\u8f7d/\u7ba1\u7406 LLM \u6a21\u578b - \u57fa\u4e8e\u672c\u5730\u8ba1\u7b97\u7684\u5b9e\u65f6\u4f4e\u5ef6\u8fdf\u54cd\u5e94

      "},{"location":"whats-new/#v350","title":"v3.5.0","text":"
      • Python \u5347\u7ea7\u5230 3.12.8
      • \u6539\u8fdb\u4eea\u8868\u76d8\uff0c\u529f\u80fd\u66f4\u6e05\u6670\u3001\u66f4\u4eba\u6027\u5316
      • \u6dfb\u52a0\u4e86\u4f17\u591a\u7b2c\u4e09\u65b9\u5305\uff1aPyTorch / Twisted / Scrapy / FastAPI ...
      "},{"location":"whats-new/#v338","title":"v3.3.8","text":"
      • \u4fee\u590d\u4e86 NumPy \u517c\u5bb9\u6027\u95ee\u9898
      "},{"location":"whats-new/#v335","title":"v3.3.5","text":"
      • \u5347\u7ea7 Python \u5185\u6838\u5230 3.11.9
      • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u4e0d\u663e\u793a\u6a21\u5757\u5b89\u88c5\u72b6\u6001\u7684 bug
      • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u5220\u9664\u6a21\u5757\u5931\u8d25\u7684 bug
      • \u4fee\u590d\u4e86\u5176\u4ed6 bug
      "},{"location":"whats-new/#v334","title":"v3.3.4","text":"
      • \u6dfb\u52a0\u4e86 OpenAI/Langchain/APIGPTCloud AI \u5305
      • \u79fb\u9664\u4e0d\u5fc5\u8981\u7684\u6587\u4ef6\u4ee5\u51cf\u5c11\u5927\u5c0f
      "},{"location":"whats-new/#v325","title":"v3.2.5","text":"
      • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570
      • \u5176\u4ed6\u9519\u8bef\u4fee\u590d
      "},{"location":"whats-new/#v323","title":"v3.2.3","text":"
      • \u66f4\u65b0 Python \u7248\u672c\u5230 3.11.0
      • \u66f4\u65b0 IPython \u7248\u672c\u5230 8.6.0
      • \u66f4\u65b0 pip \u7248\u672c\u5230 22.3.1
      • \u66f4\u65b0\u79d1\u5b66\u8ba1\u7b97\u5305\uff0c\u81ea\u52a8\u8f6f\u94fe\u63a5
      • \u51cf\u5c11\u7a7a\u95f4\u4f7f\u7528
      • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570 + \u5176\u4ed6\u9519\u8bef\u4fee\u590d
      "},{"location":"whats-new/#v318","title":"v3.1.8","text":"
      • \u5728\u7ec8\u7aef\u4e2d\u6dfb\u52a0\u4e86\u64cd\u4f5c\u70ed\u952e
      • \u4fee\u590d\u4e86\u7f16\u8f91\u5668\u5728\u65cb\u8f6c\u65f6\u4e22\u5931\u5185\u5bb9\u7684\u95ee\u9898
      • \u4fee\u590d\u4e86\u5176\u4ed6 bug

      \u5728 Google Play \u4e0b\u8f7d

      "},{"location":"qsl4a/","title":"QSL4A\uff08Android \u811a\u672c\u5c42\uff09API \u6587\u6863","text":"

      QSL4A \u662f QPython \u7684 Android \u811a\u672c\u5c42\uff0c\u5141\u8bb8\u60a8\u4f7f\u7528 Python \u63a7\u5236 Android \u8bbe\u5907\u529f\u80fd\u3002

      "},{"location":"qsl4a/#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a toast \u6d88\u606f\ndroid.makeToast('Hello QPython!')\n\n# \u9707\u52a8\u8bbe\u5907\ndroid.vibrate(500)\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\uff08\u5148\u5f00\u59cb\u76d1\u63a7\uff09\nimport time\ndroid.batteryStartMonitoring()\ntime.sleep(0.5)  # \u7b49\u5f85\u6570\u636e\nbattery = droid.readBatteryData().result\nprint(f\"\u7535\u6c60\uff1a{battery['level']}%\")\n
      "},{"location":"qsl4a/#_2","title":"\u6587\u6863\u7ed3\u6784","text":""},{"location":"qsl4a/#_3","title":"\u6838\u5fc3\u6a21\u5757","text":"
      • Android \u57fa\u7840 - \u6838\u5fc3\u8fde\u63a5\u548c RPC
      • Intent \u7cfb\u7edf - Android Intent \u64cd\u4f5c
      • \u4e8b\u4ef6\u7cfb\u7edf - \u4e8b\u4ef6\u5904\u7406\u548c\u5e7f\u64ad
      "},{"location":"qsl4a/#ui","title":"UI \u7ec4\u4ef6","text":"
      • \u5bf9\u8bdd\u6846 - \u8b66\u62a5\u3001\u8f93\u5165\u3001\u9009\u62e9\u5bf9\u8bdd\u6846
      • \u5168\u5c4f UI - \u81ea\u5b9a\u4e49\u5e03\u5c40 UI
      • \u60ac\u6d6e\u7a97 - \u60ac\u6d6e\u7a97\u53e3
      • \u8f85\u52a9\u529f\u80fd - \u5c4f\u5e55\u81ea\u52a8\u5316
      "},{"location":"qsl4a/#_4","title":"\u7cfb\u7edf","text":"
      • \u7535\u6c60 - \u7535\u6c60\u76d1\u63a7
      • \u4f20\u611f\u5668 - \u8bbe\u5907\u4f20\u611f\u5668
      • \u5e94\u7528 - \u5e94\u7528\u7ba1\u7406
      • \u7cfb\u7edf\u4fe1\u606f - \u8bbe\u5907\u4fe1\u606f
      • \u8bbe\u7f6e - \u7cfb\u7edf\u8bbe\u7f6e
      • \u5524\u9192\u9501 - \u5524\u9192\u9501\u63a7\u5236
      • QPython \u63a5\u53e3 - \u811a\u672c\u6267\u884c
      • Activity \u7ed3\u679c - Activity \u7ed3\u679c\u5904\u7406
      "},{"location":"qsl4a/#_5","title":"\u786c\u4ef6","text":"
      • \u84dd\u7259 - \u84dd\u7259\u64cd\u4f5c
      • \u76f8\u673a - \u62cd\u7167\u548c\u5f55\u50cf
      • \u97f3\u9891/\u5f55\u97f3\u5668 - \u5f55\u97f3
      • \u7f51\u7edc\u6444\u50cf\u5934 - MJPEG \u6d41
      • USB \u4e32\u53e3 - USB \u4e3b\u673a\u4e32\u53e3
      "},{"location":"qsl4a/#_6","title":"\u8fde\u63a5","text":"
      • WiFi - WiFi \u64cd\u4f5c
      • \u4f4d\u7f6e - GPS \u548c\u4f4d\u7f6e
      • \u77ed\u4fe1 - \u77ed\u4fe1\u64cd\u4f5c
      • \u7535\u8bdd - \u6253\u7535\u8bdd\u548c\u6765\u7535\u4fe1\u606f
      • \u8054\u7cfb\u4eba - \u8054\u7cfb\u4eba\u7ba1\u7406
      • \u4fe1\u53f7\u5f3a\u5ea6 - \u4fe1\u53f7\u76d1\u63a7
      • FTP \u670d\u52a1\u5668 - \u5185\u7f6e FTP \u670d\u52a1\u5668
      "},{"location":"qsl4a/#_7","title":"\u5b58\u50a8","text":"
      • DocumentFile - \u6587\u4ef6\u64cd\u4f5c
      • \u526a\u8d34\u677f - \u526a\u8d34\u677f\u64cd\u4f5c
      • \u504f\u597d\u8bbe\u7f6e - \u5171\u4eab\u504f\u597d\u8bbe\u7f6e
      "},{"location":"qsl4a/#_8","title":"\u5a92\u4f53","text":"
      • \u5a92\u4f53\u64ad\u653e\u5668 - \u97f3\u9891/\u89c6\u9891\u64ad\u653e
      • \u56fe\u50cf\u5904\u7406 - \u56fe\u50cf\u64cd\u4f5c
      "},{"location":"qsl4a/#_9","title":"\u7279\u6b8a\u529f\u80fd","text":"
      • \u52a0\u5bc6 - \u52a0\u5bc6/\u89e3\u5bc6
      • PGPT AI - AI \u8bed\u97f3\u670d\u52a1
      "},{"location":"qsl4a/#_10","title":"\u7ed3\u679c\u5bf9\u8c61","text":"

      \u5927\u591a\u6570 QSL4A \u65b9\u6cd5\u8fd4\u56de\u4e00\u4e2a\u5e26\u6709\u4ee5\u4e0b\u5c5e\u6027\u7684 Result \u547d\u540d\u5143\u7ec4\uff1a - id - \u8bf7\u6c42 ID - result - \u5b9e\u9645\u7ed3\u679c\u6570\u636e - error - \u5982\u679c\u5931\u8d25\u5219\u4e3a\u9519\u8bef\u6d88\u606f

      result = droid.getClipboard()\nif result.error is None:\n    print(result.result)\nelse:\n    print(f\"\u9519\u8bef\uff1a{result.error}\")\n
      "},{"location":"qsl4a/connectivity/contacts/","title":"\u8054\u7cfb\u4eba API","text":"

      \u8bbf\u95ee\u548c\u7ba1\u7406\u8bbe\u5907\u8054\u7cfb\u4eba\u3002

      "},{"location":"qsl4a/connectivity/contacts/#_1","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":""},{"location":"qsl4a/connectivity/contacts/#pickcontact","title":"pickContact()","text":"

      \u663e\u793a\u8054\u7cfb\u4eba\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

      pickContact()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u8054\u7cfb\u4eba URI \u7684 Intent

      "},{"location":"qsl4a/connectivity/contacts/#pickphone","title":"pickPhone()","text":"

      \u663e\u793a\u7535\u8bdd\u53f7\u7801\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

      pickPhone()\n

      \u8fd4\u56de\uff1a \u9009\u4e2d\u7684\u7535\u8bdd\u53f7\u7801\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/contacts/#_2","title":"\u8054\u7cfb\u4eba\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#contactsget","title":"contactsGet()","text":"

      \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\u3002

      contactsGet(attributes=None)\n

      \u53c2\u6570\uff1a - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

      \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba JSONObject \u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetbyid","title":"contactsGetById()","text":"

      \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\u3002

      contactsGetById(id, attributes=None)\n

      \u53c2\u6570\uff1a - id (int): \u8054\u7cfb\u4eba ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

      \u8fd4\u56de\uff1a JSONObject \u8054\u7cfb\u4eba\u6570\u636e

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetcount","title":"contactsGetCount()","text":"

      \u83b7\u53d6\u8054\u7cfb\u4eba\u603b\u6570\u3002

      contactsGetCount()\n

      \u8fd4\u56de\uff1a \u6574\u6570\u8ba1\u6570

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetids","title":"contactsGetIds()","text":"

      \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba ID\u3002

      contactsGetIds()\n

      \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba ID \u6574\u6570\u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetattributes","title":"contactsGetAttributes()","text":"

      \u83b7\u53d6\u6240\u6709\u53ef\u80fd\u7684\u8054\u7cfb\u4eba\u5c5e\u6027\u3002

      contactsGetAttributes()\n

      \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#_3","title":"\u5185\u5bb9\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#querycontent","title":"queryContent()","text":"

      \u4f7f\u7528\u81ea\u5b9a\u4e49\u53c2\u6570\u67e5\u8be2\u5185\u5bb9\u89e3\u6790\u5668\u3002

      queryContent(uri, attributes=None, selection=None, selectionArgs=None, order=None)\n

      \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u5c5e\u6027 - selection (str, optional): WHERE \u5b50\u53e5 - selectionArgs (list, optional): \u9009\u62e9\u53c2\u6570 - order (str, optional): ORDER BY \u5b50\u53e5

      \u8fd4\u56de\uff1a JSONObject \u7ed3\u679c\u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#queryattributes","title":"queryAttributes()","text":"

      \u83b7\u53d6\u5185\u5bb9 URI \u7684\u5c5e\u6027\u3002

      queryAttributes(uri)\n

      \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI

      \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u7684 JSONArray

      "},{"location":"qsl4a/connectivity/contacts/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u9009\u62e9\u8054\u7cfb\u4eba\ncontact_uri = droid.pickContact().result\nprint(f\"Selected contact: {contact_uri}\")\n\n# \u9009\u62e9\u7535\u8bdd\u53f7\u7801\nphone = droid.pickPhone().result\nprint(f\"Selected phone: {phone}\")\n\n# \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\ncontacts = droid.contactsGet().result\nprint(f\"Total contacts: {len(contacts)}\")\n\n# \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\ncontact = droid.contactsGetById(1).result\nprint(f\"Contact: {contact}\")\n\n# \u83b7\u53d6\u8054\u7cfb\u4eba\u5c5e\u6027\nattrs = droid.contactsGetAttributes().result\nprint(f\"Available attributes: {attrs}\")\n
      "},{"location":"qsl4a/connectivity/ftp/","title":"FTP \u670d\u52a1\u5668 API","text":"

      \u5728\u8bbe\u5907\u4e0a\u542f\u52a8\u548c\u7ba1\u7406\u5185\u7f6e FTP \u670d\u52a1\u5668\u3002

      "},{"location":"qsl4a/connectivity/ftp/#ftp","title":"FTP \u670d\u52a1\u5668\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/ftp/#ftpstart","title":"ftpStart()","text":"

      \u542f\u52a8 FTP \u670d\u52a1\u5668\u3002

      ftpStart()\n

      \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4 [ip, port]

      "},{"location":"qsl4a/connectivity/ftp/#ftpstop","title":"ftpStop()","text":"

      \u505c\u6b62 FTP \u670d\u52a1\u5668\u3002

      ftpStop()\n
      "},{"location":"qsl4a/connectivity/ftp/#ftpisrunning","title":"ftpIsRunning()","text":"

      \u68c0\u67e5 FTP \u670d\u52a1\u5668\u662f\u5426\u6b63\u5728\u8fd0\u884c\u3002

      ftpIsRunning()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u8fd0\u884c\u5219\u4e3a True

      "},{"location":"qsl4a/connectivity/ftp/#ftpget","title":"ftpGet()","text":"

      \u83b7\u53d6 FTP \u670d\u52a1\u5668 IP \u5730\u5740\u3002

      ftpGet()\n

      \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4

      "},{"location":"qsl4a/connectivity/ftp/#ftpset","title":"ftpSet()","text":"

      \u914d\u7f6e FTP \u670d\u52a1\u5668\u8bbe\u7f6e\u3002

      ftpSet(port=None, rootDir=None, username=None, password=None)\n

      \u53c2\u6570\uff1a - port (int, optional): \u670d\u52a1\u5668\u7aef\u53e3 - rootDir (str, optional): \u8981\u670d\u52a1\u7684\u57fa\u7840\u76ee\u5f55 - username (str, optional): \u767b\u5f55\u7528\u6237\u540d - password (str, optional): \u767b\u5f55\u5bc6\u7801

      \u8fd4\u56de\uff1a \u5305\u542b\u5f53\u524d\u8bbe\u7f6e\u7684 JSONObject

      "},{"location":"qsl4a/connectivity/ftp/#ftpstatus","title":"ftpStatus()","text":"

      \u83b7\u53d6 FTP \u670d\u52a1\u5668\u72b6\u6001\u3002

      ftpStatus()\n

      \u8fd4\u56de\uff1a \u72b6\u6001\u63cf\u8ff0\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/ftp/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u914d\u7f6e FTP \u670d\u52a1\u5668\ndroid.ftpSet(\n    port=2121,\n    rootDir=\"/sdcard\",\n    username=\"admin\",\n    password=\"secret\"\n)\n\n# \u542f\u52a8 FTP \u670d\u52a1\u5668\ninfo = droid.ftpStart().result\nprint(f\"FTP running at {info[0]}:{info[1]}\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.ftpIsRunning().result:\n    print(\"FTP server is running\")\n\n# \u83b7\u53d6\u670d\u52a1\u5668\u4fe1\u606f\nserver_info = droid.ftpGet().result\nprint(f\"Server: {server_info}\")\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.ftpStop()\n

      \u6ce8\u610f\uff1a \u4f7f\u7528\u63d0\u4f9b\u7684\u51ed\u636e\u901a\u8fc7\u4efb\u4f55 FTP \u5ba2\u6237\u7aef\u8fde\u63a5\u5230 FTP \u670d\u52a1\u5668\u3002

      "},{"location":"qsl4a/connectivity/location/","title":"\u4f4d\u7f6e API","text":"

      \u8bbf\u95ee GPS \u548c\u7f51\u7edc\u4f4d\u7f6e\u670d\u52a1\u3002

      "},{"location":"qsl4a/connectivity/location/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/location/#startlocating","title":"startLocating()","text":"

      \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\u3002

      startLocating(minUpdateTime=60000, minUpdateDistance=30, updateGnssStatus=False)\n

      \u53c2\u6570\uff1a - minUpdateTime (int): \u66f4\u65b0\u4e4b\u95f4\u7684\u6700\u5c0f\u65f6\u95f4\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a60000\uff09 - minUpdateDistance (float): \u66f4\u65b0\u7684\u6700\u5c0f\u8ddd\u79bb\uff08\u7c73\uff09\uff08\u9ed8\u8ba4\uff1a30\uff09 - updateGnssStatus (bool): \u542f\u7528 GNSS \u72b6\u6001\u66f4\u65b0\uff08\u9ed8\u8ba4\uff1aFalse\uff09

      "},{"location":"qsl4a/connectivity/location/#stoplocating","title":"stopLocating()","text":"

      \u505c\u6b62\u4f4d\u7f6e\u66f4\u65b0\u3002

      stopLocating()\n
      "},{"location":"qsl4a/connectivity/location/#readlocation","title":"readLocation()","text":"

      \u83b7\u53d6\u6700\u540e\u5df2\u77e5\u4f4d\u7f6e\u3002

      readLocation()\n

      \u8fd4\u56de\uff1a \u4f4d\u7f6e\u6570\u636e\u5b57\u5178

      "},{"location":"qsl4a/connectivity/location/#getlastknownlocation","title":"getLastKnownLocation()","text":"

      \u83b7\u53d6\u7f13\u5b58\u7684\u4f4d\u7f6e\u3002

      getLastKnownLocation()\n

      \u8fd4\u56de\uff1a \u6765\u81ea\u6240\u6709\u63d0\u4f9b\u5546\u7684\u4f4d\u7f6e

      "},{"location":"qsl4a/connectivity/location/#geocode","title":"geocode()","text":"

      \u5c06\u5730\u5740\u8f6c\u6362\u4e3a\u5750\u6807\u3002

      geocode(address, maxResults=1)\n
      "},{"location":"qsl4a/connectivity/location/#_2","title":"\u4f4d\u7f6e\u63d0\u4f9b\u5546\u65b9\u6cd5)","text":""},{"location":"qsl4a/connectivity/location/#locationproviders","title":"locationProviders()","text":"

      \u83b7\u53d6\u624b\u673a\u4e0a\u53ef\u7528\u7684\u4f4d\u7f6e\u63d0\u4f9b\u5546\u3002

      locationProviders()\n

      \u8fd4\u56de\uff1a \u53ef\u7528\u63d0\u4f9b\u5546\u540d\u79f0\u5217\u8868\uff08\u4f8b\u5982 ['gps', 'network']\uff09

      "},{"location":"qsl4a/connectivity/location/#locationproviderenabled","title":"locationProviderEnabled()","text":"

      \u68c0\u67e5\u7279\u5b9a\u4f4d\u7f6e\u63d0\u4f9b\u5546\u662f\u5426\u5df2\u542f\u7528\u3002

      locationProviderEnabled(provider)\n

      \u53c2\u6570\uff1a - provider (str): \u63d0\u4f9b\u5546\u540d\u79f0\uff08\u4f8b\u5982 'gps', 'network'\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/connectivity/location/#readgnssstatus","title":"readGnssStatus()","text":"

      \u8bfb\u53d6\u5168\u7403\u5bfc\u822a\u536b\u661f\u7cfb\u7edf\u72b6\u6001\uff08\u9700\u8981 Android 8+\uff09\u3002

      readGnssStatus()\n

      \u8fd4\u56de\uff1a \u5305\u542b GNSS \u536b\u661f\u4fe1\u606f\u7684 JSONArray

      "},{"location":"qsl4a/connectivity/location/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\ndroid.startLocating(minUpdateTime=5000, minUpdateDistance=1, updateGnssStatus=False)\n\n# \u7b49\u5f85\u5b9a\u4f4d\ntime.sleep(10)\n\n# \u83b7\u53d6\u4f4d\u7f6e\nloc = droid.readLocation().result\nif loc:\n    lat = loc['latitude']\n    lon = loc['longitude']\n    print(f\"Location: {lat}, {lon}\")\n\ndroid.stopLocating()\n
      "},{"location":"qsl4a/connectivity/phone/","title":"\u7535\u8bdd API","text":"

      \u63a7\u5236\u7535\u8bdd\u901a\u8bdd\u548c\u83b7\u53d6\u7535\u8bdd\u4fe1\u606f\u3002

      "},{"location":"qsl4a/connectivity/phone/#_1","title":"\u7535\u8bdd\u72b6\u6001\u8ddf\u8e2a","text":""},{"location":"qsl4a/connectivity/phone/#starttrackingphonestate","title":"startTrackingPhoneState()","text":"

      \u5f00\u59cb\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u53d8\u5316\u3002\u751f\u6210 'phone' \u4e8b\u4ef6\u3002

      startTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/phone/#readphonestate","title":"readPhoneState()","text":"

      \u8bfb\u53d6\u5f53\u524d\u7535\u8bdd\u72b6\u6001\u3002

      readPhoneState()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7535\u8bdd\u72b6\u6001\u548c\u6765\u7535\u53f7\u7801\u7684 Bundle

      "},{"location":"qsl4a/connectivity/phone/#stoptrackingphonestate","title":"stopTrackingPhoneState()","text":"

      \u505c\u6b62\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u3002

      stopTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/phone/#_2","title":"\u62e8\u6253\u7535\u8bdd","text":""},{"location":"qsl4a/connectivity/phone/#phonecall","title":"phoneCall()","text":"

      \u901a\u8fc7 URI \u547c\u53eb\u8054\u7cfb\u4eba/\u7535\u8bdd\u53f7\u7801\u3002

      phoneCall(uri)\n

      \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

      "},{"location":"qsl4a/connectivity/phone/#phonecallnumber","title":"phoneCallNumber()","text":"

      \u76f4\u63a5\u62e8\u6253\u7535\u8bdd\u53f7\u7801\u3002

      phoneCallNumber(phone_number)\n

      \u53c2\u6570\uff1a - phone_number (str): \u8981\u62e8\u6253\u7684\u7535\u8bdd\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#phonedial","title":"phoneDial()","text":"

      \u62e8\u6253\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

      phoneDial(uri)\n

      \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

      "},{"location":"qsl4a/connectivity/phone/#phonedialnumber","title":"phoneDialNumber()","text":"

      \u62e8\u6253\u7535\u8bdd\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

      phoneDialNumber(phone_number)\n

      \u53c2\u6570\uff1a - phone_number (str): \u7535\u8bdd\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#_3","title":"\u57fa\u7ad9\u4f4d\u7f6e","text":""},{"location":"qsl4a/connectivity/phone/#getcelllocation","title":"getCellLocation()","text":"

      \u83b7\u53d6\u5f53\u524d\u57fa\u7ad9\u4f4d\u7f6e\u3002

      getCellLocation()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u57fa\u7ad9\u4f4d\u7f6e\u6570\u636e\u7684 JSONObject

      "},{"location":"qsl4a/connectivity/phone/#getallcellslocation","title":"getAllCellsLocation()","text":"

      \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u4f4d\u7f6e\uff08\u9002\u7528\u4e8e\u53cc\u5361\u8bbe\u5907\uff09\u3002

      getAllCellsLocation()\n

      \u8fd4\u56de\uff1a \u57fa\u7ad9\u4f4d\u7f6e\u7684 JSONArray

      "},{"location":"qsl4a/connectivity/phone/#_4","title":"\u7f51\u7edc\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getnetworkoperator","title":"getNetworkOperator()","text":"

      \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

      getNetworkOperator()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getnetworkoperatorname","title":"getNetworkOperatorName()","text":"

      \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684\u540d\u79f0\u3002

      getNetworkOperatorName()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getnetworktype","title":"getNetworkType()","text":"

      \u83b7\u53d6\u5f53\u524d\u7f51\u7edc\u7c7b\u578b\u3002

      getNetworkType()\n

      \u8fd4\u56de\uff1a \u63cf\u8ff0\u65e0\u7ebf\u7535\u6280\u672f\u7684\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'LTE', 'UMTS', 'GSM'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getphonetype","title":"getPhoneType()","text":"

      \u83b7\u53d6\u7535\u8bdd\u7c7b\u578b\u3002

      getPhoneType()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'GSM', 'CDMA', 'SIP'\uff09

      "},{"location":"qsl4a/connectivity/phone/#sim","title":"SIM \u5361\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getsimcountryiso","title":"getSimCountryIso()","text":"

      \u83b7\u53d6 SIM \u5361\u7684 ISO \u56fd\u5bb6\u4ee3\u7801\u3002

      getSimCountryIso()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'us'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getsimoperator","title":"getSimOperator()","text":"

      \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

      getSimOperator()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getsimoperatorname","title":"getSimOperatorName()","text":"

      \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u540d\u79f0\u3002

      getSimOperatorName()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getsimserialnumber","title":"getSimSerialNumber()","text":"

      \u83b7\u53d6 SIM \u5e8f\u5217\u53f7\u3002

      getSimSerialNumber()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32 SIM \u5e8f\u5217\u53f7

      "},{"location":"qsl4a/connectivity/phone/#getsimstate","title":"getSimState()","text":"

      \u83b7\u53d6 SIM \u5361\u72b6\u6001\u3002

      getSimState()\n

      \u8fd4\u56de\uff1a \u63cf\u8ff0 SIM \u72b6\u6001\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/phone/#getsubscriberid","title":"getSubscriberId()","text":"

      \u83b7\u53d6\u8ba2\u9605\u8005 ID\u3002

      getSubscriberId()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8ba2\u9605\u8005 ID

      "},{"location":"qsl4a/connectivity/phone/#_5","title":"\u8bed\u97f3\u90ae\u4ef6","text":""},{"location":"qsl4a/connectivity/phone/#getvoicemailalphatag","title":"getVoiceMailAlphaTag()","text":"

      \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u5b57\u6bcd\u6807\u7b7e\u3002

      getVoiceMailAlphaTag()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u6807\u7b7e

      "},{"location":"qsl4a/connectivity/phone/#getvoicemailnumber","title":"getVoiceMailNumber()","text":"

      \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801\u3002

      getVoiceMailNumber()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getdeviceid","title":"getDeviceId()","text":"

      \u83b7\u53d6\u8bbe\u5907 ID\uff08GSM \u7684 IMEI\uff09\u3002\u5df2\u5e9f\u5f03\u3002

      getDeviceId()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

      "},{"location":"qsl4a/connectivity/phone/#getdevicesoftwareversion","title":"getDeviceSoftwareVersion()","text":"

      \u83b7\u53d6\u8bbe\u5907\u8f6f\u4ef6\u7248\u672c\u3002

      getDeviceSoftwareVersion()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8f6f\u4ef6\u7248\u672c

      "},{"location":"qsl4a/connectivity/phone/#getline1number","title":"getLine1Number()","text":"

      \u83b7\u53d6\u7ebf\u8def 1 \u7535\u8bdd\u53f7\u7801\u3002

      getLine1Number()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u7535\u8bdd\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#checknetworkroaming","title":"checkNetworkRoaming()","text":"

      \u68c0\u67e5\u662f\u5426\u8fde\u63a5\u5230\u6f2b\u6e38\u7f51\u7edc\u3002

      checkNetworkRoaming()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u6f2b\u6e38\u5219\u4e3a True

      "},{"location":"qsl4a/connectivity/phone/#_7","title":"\u57fa\u7ad9\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getallcellinfo","title":"getAllCellInfo()","text":"

      \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u7684\u4fe1\u606f\u3002

      getAllCellInfo()\n

      \u8fd4\u56de\uff1a \u57fa\u7ad9\u4fe1\u606f\u5217\u8868

      "},{"location":"qsl4a/connectivity/phone/#setdataenabled","title":"setDataEnabled()","text":"

      \u542f\u7528\u6216\u7981\u7528\u79fb\u52a8\u6570\u636e\u3002

      setDataEnabled(enabled)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528

      "},{"location":"qsl4a/connectivity/phone/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7f51\u7edc\u4fe1\u606f\noperator = droid.getNetworkOperatorName().result\nprint(f\"Operator: {operator}\")\n\nnetwork_type = droid.getNetworkType().result\nprint(f\"Network: {network_type}\")\n\n# \u83b7\u53d6 SIM \u4fe1\u606f\nsim_state = droid.getSimState().result\nprint(f\"SIM: {sim_state}\")\n\n# \u83b7\u53d6\u7535\u8bdd\u53f7\u7801\nline1 = droid.getLine1Number().result\nprint(f\"Phone: {line1}\")\n\n# \u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\ndroid.startTrackingPhoneState()\nprint(\"Tracking phone state...\")\ndroid.stopTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/signalstrength/","title":"\u4fe1\u53f7\u5f3a\u5ea6 API","text":"

      \u76d1\u63a7\u8702\u7a9d\u548c\u65e0\u7ebf\u4fe1\u53f7\u5f3a\u5ea6\u3002

      "},{"location":"qsl4a/connectivity/signalstrength/#_1","title":"\u4fe1\u53f7\u5f3a\u5ea6\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/signalstrength/#starttrackingsignalstrengths","title":"startTrackingSignalStrengths()","text":"

      \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316\u3002\u751f\u6210 'signal_strengths' \u4e8b\u4ef6\u3002

      startTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/signalstrength/#stoptrackingsignalstrengths","title":"stopTrackingSignalStrengths()","text":"

      \u505c\u6b62\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u3002

      stopTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/signalstrength/#readsignalstrengths","title":"readSignalStrengths()","text":"

      \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\u3002

      readSignalStrengths()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u4fe1\u53f7\u5f3a\u5ea6\u6570\u636e\u7684 Bundle

      "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthlevel","title":"getTelephoneSignalStrengthLevel()","text":"

      \u83b7\u53d6\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u7b49\u7ea7\uff080-4\uff09\u3002

      getTelephoneSignalStrengthLevel()\n

      \u8fd4\u56de\uff1a \u6574\u6570\u7b49\u7ea7\uff080=\u65e0\uff0c1=\u5dee\uff0c2=\u4e00\u822c\uff0c3=\u597d\uff0c4=\u4f18\u79c0\uff09

      "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthdetail","title":"getTelephoneSignalStrengthDetail()","text":"

      \u83b7\u53d6\u8be6\u7ec6\u7684\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u4fe1\u606f\u3002

      getTelephoneSignalStrengthDetail()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u8be6\u7ec6\u4fe1\u53f7\u4fe1\u606f\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/signalstrength/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\ndroid.startTrackingSignalStrengths()\n\n# \u7b49\u5f85\u4fe1\u53f7\u66f4\u65b0\ntime.sleep(5)\n\n# \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\nsignal = droid.readSignalStrengths().result\nprint(f\"Signal: {signal}\")\n\n# \u76f4\u63a5\u83b7\u53d6\u7b49\u7ea7\nlevel = droid.getTelephoneSignalStrengthLevel().result\nprint(f\"Signal level: {level}/4\")\n\ndroid.stopTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/sms/","title":"SMS API","text":"

      \u53d1\u9001\u548c\u63a5\u6536 SMS \u6d88\u606f\u3002

      "},{"location":"qsl4a/connectivity/sms/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/sms/#smssend","title":"smsSend()","text":"

      \u53d1\u9001 SMS \u6d88\u606f\u3002

      smsSend(destinationAddress, text)\n

      \u53c2\u6570\uff1a - destinationAddress (str): \u7535\u8bdd\u53f7\u7801 - text (str): \u6d88\u606f\u6587\u672c

      "},{"location":"qsl4a/connectivity/sms/#smsgetmessagecount","title":"smsGetMessageCount()","text":"

      \u83b7\u53d6\u6d88\u606f\u6570\u91cf\u3002

      smsGetMessageCount(unreadOnly=False, folder=\"inbox\")\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessageids","title":"smsGetMessageIds()","text":"

      \u83b7\u53d6\u6d88\u606f ID\u3002

      smsGetMessageIds(unreadOnly=False, folder=\"inbox\")\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessages","title":"smsGetMessages()","text":"

      \u83b7\u53d6\u6d88\u606f\u8be6\u60c5\u3002

      smsGetMessages(unreadOnly=False, folder=\"inbox\", attributes=None)\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessagebyid","title":"smsGetMessageById()","text":"

      \u901a\u8fc7 ID \u83b7\u53d6\u7279\u5b9a\u6d88\u606f\u3002

      smsGetMessageById(id, attributes=None)\n

      \u53c2\u6570\uff1a - id (int): \u6d88\u606f ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

      \u8fd4\u56de\uff1a \u6d88\u606f\u6570\u636e\u5b57\u5178

      "},{"location":"qsl4a/connectivity/sms/#smsgetattributes","title":"smsGetAttributes()","text":"

      \u83b7\u53d6\u53ef\u7528\u7684 SMS \u6d88\u606f\u5c5e\u6027\u3002

      smsGetAttributes()\n

      \u8fd4\u56de\uff1a \u53ef\u7528\u5c5e\u6027\u540d\u79f0\u5217\u8868

      "},{"location":"qsl4a/connectivity/sms/#smsdeletemessage","title":"smsDeleteMessage()","text":"

      \u5220\u9664\u6d88\u606f\u3002

      smsDeleteMessage(id)\n
      "},{"location":"qsl4a/connectivity/sms/#smsmarkmessageread","title":"smsMarkMessageRead()","text":"

      \u5c06\u6d88\u606f\u6807\u8bb0\u4e3a\u5df2\u8bfb\u3002

      smsMarkMessageRead(ids, read=True)\n
      "},{"location":"qsl4a/connectivity/sms/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u53d1\u9001 SMS\ndroid.smsSend(\"+1234567890\", \"Hello from QPython!\")\n\n# \u83b7\u53d6\u672a\u8bfb\u6d88\u606f\nmessages = droid.smsGetMessages(unreadOnly=True).result\nfor msg in messages:\n    print(f\"From: {msg['address']}, Text: {msg['body']}\")\n
      "},{"location":"qsl4a/connectivity/wifi/","title":"WiFi API","text":"

      \u63a7\u5236 WiFi \u9002\u914d\u5668\u5e76\u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\u3002

      "},{"location":"qsl4a/connectivity/wifi/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/connectivity/wifi/#checkwifistate","title":"checkWifiState()","text":"

      \u68c0\u67e5 WiFi \u662f\u5426\u5df2\u542f\u7528\u3002

      checkWifiState()\n

      \u8fd4\u56de\uff1a \u5982\u679c WiFi \u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/connectivity/wifi/#togglewifistate","title":"toggleWifiState()","text":"

      \u6253\u5f00\u6216\u5173\u95ed WiFi\u3002

      toggleWifiState(enabled=None)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

      \u8fd4\u56de\uff1a \u5982\u679c\u64cd\u4f5c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/connectivity/wifi/#wifistartscan","title":"wifiStartScan()","text":"

      \u5f00\u59cb\u626b\u63cf\u53ef\u7528\u7684 WiFi \u7f51\u7edc\u3002

      wifiStartScan()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifigetscanresults","title":"wifiGetScanResults()","text":"

      \u83b7\u53d6\u53d1\u73b0\u7684 WiFi \u7f51\u7edc\u5217\u8868\u3002

      wifiGetScanResults()\n

      \u8fd4\u56de\uff1a \u63a5\u5165\u70b9\u4fe1\u606f\u5217\u8868

      "},{"location":"qsl4a/connectivity/wifi/#_2","title":"\u8fde\u63a5\u7ba1\u7406","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetconnectioninfo","title":"wifiGetConnectionInfo()","text":"

      \u83b7\u53d6\u8be6\u7ec6\u8fde\u63a5\u4fe1\u606f\u3002

      wifiGetConnectionInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001IP \u5730\u5740\u7b49\u8fde\u63a5\u8be6\u60c5\u7684\u5b57\u5178

      "},{"location":"qsl4a/connectivity/wifi/#getconnectedinfo","title":"getConnectedInfo()","text":"

      \u83b7\u53d6\u8fde\u63a5\u7684 WiFi \u7f51\u7edc\u4fe1\u606f\uff08\u7b80\u5316\u7248\uff09\u3002

      getConnectedInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001\u4fe1\u53f7\u5f3a\u5ea6\u7684\u5b57\u5178

      "},{"location":"qsl4a/connectivity/wifi/#getdhcpinfo","title":"getDhcpInfo()","text":"

      \u83b7\u53d6\u5f53\u524d\u8fde\u63a5\u7684 DHCP \u4fe1\u606f\u3002

      getDhcpInfo(ipConvertToString=True)\n

      \u53c2\u6570\uff1a - ipConvertToString (bool): \u5c06 IP \u5730\u5740\u8f6c\u6362\u4e3a\u5b57\u7b26\u4e32\u683c\u5f0f\uff08\u9ed8\u8ba4\uff1aTrue\uff09

      \u8fd4\u56de\uff1a \u5305\u542b IP\u3001\u7f51\u5173\u3001DNS \u7b49 DHCP \u4fe1\u606f\u7684\u5b57\u5178

      "},{"location":"qsl4a/connectivity/wifi/#wifidisconnect","title":"wifiDisconnect()","text":"

      \u65ad\u5f00\u5f53\u524d WiFi \u7f51\u7edc\u8fde\u63a5\u3002

      wifiDisconnect()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifireconnect","title":"wifiReconnect()","text":"

      \u91cd\u65b0\u8fde\u63a5\u5230\u5f53\u524d\u7f51\u7edc\u3002

      wifiReconnect()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifireassociate","title":"wifiReassociate()","text":"

      \u91cd\u65b0\u5173\u8054\u5f53\u524d\u63a5\u5165\u70b9\u3002

      wifiReassociate()\n
      "},{"location":"qsl4a/connectivity/wifi/#_3","title":"\u70ed\u70b9","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetapstate","title":"wifiGetApState()","text":"

      \u83b7\u53d6 WiFi AP\uff08\u70ed\u70b9\uff09\u72b6\u6001\u3002

      wifiGetApState()\n

      \u8fd4\u56de\uff1a \u70ed\u70b9\u72b6\u6001

      "},{"location":"qsl4a/connectivity/wifi/#wifi","title":"WiFi \u9501","text":""},{"location":"qsl4a/connectivity/wifi/#wifilockacquirefull","title":"wifiLockAcquireFull()","text":"

      \u83b7\u53d6\u5b8c\u6574 WiFi \u9501\uff08\u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\u4e5f\u4fdd\u6301 WiFi \u6d3b\u52a8\uff09\u3002

      wifiLockAcquireFull()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifilockacquirescanonly","title":"wifiLockAcquireScanOnly()","text":"

      \u83b7\u53d6\u4ec5\u626b\u63cf WiFi \u9501\u3002

      wifiLockAcquireScanOnly()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifilockrelease","title":"wifiLockRelease()","text":"

      \u91ca\u653e WiFi \u9501\u3002

      wifiLockRelease()\n
      "},{"location":"qsl4a/connectivity/wifi/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u68c0\u67e5 WiFi \u72b6\u6001\nif droid.checkWifiState().result:\n    print(\"WiFi is enabled\")\nelse:\n    print(\"Enabling WiFi...\")\n    droid.toggleWifiState(True)\n    time.sleep(2)\n\n# \u5f00\u59cb\u626b\u63cf\ndroid.wifiStartScan()\ntime.sleep(3)\n\n# \u83b7\u53d6\u626b\u63cf\u7ed3\u679c\nnetworks = droid.wifiGetScanResults().result\nfor network in networks:\n    print(f\"SSID: {network.get('SSID')}, Signal: {network.get('level')} dBm\")\n\n# \u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\ninfo = droid.wifiGetConnectionInfo().result\nif info:\n    print(f\"Connected to: {info.get('ssid')}\")\n    print(f\"BSSID: {info.get('bssid')}\")\n    print(f\"IP: {info.get('ip_address')}\")\n\n# \u83b7\u53d6 DHCP \u4fe1\u606f\ndhcp = droid.getDhcpInfo().result\nif dhcp:\n    print(f\"Gateway: {dhcp.get('gateway')}\")\n    print(f\"DNS: {dhcp.get('dns1')}\")\n\n# \u83b7\u53d6\u7b80\u5316\u7684\u8fde\u63a5\u4fe1\u606f\nconnected = droid.getConnectedInfo().result\nprint(f\"SSID: {connected.get('ssid')}, Signal: {connected.get('level')} dBm\")\n\n# \u65ad\u5f00\u5e76\u91cd\u65b0\u8fde\u63a5\ndroid.wifiDisconnect()\ntime.sleep(1)\ndroid.wifiReconnect()\n\n# \u91cd\u65b0\u5173\u8054\u63a5\u5165\u70b9\ndroid.wifiReassociate()\n\n# \u68c0\u67e5\u70ed\u70b9\u72b6\u6001\nap_state = droid.wifiGetApState().result\nprint(f\"Hotspot state: {ap_state}\")\n\n# \u83b7\u53d6 WiFi \u9501\u4ee5\u8fdb\u884c\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireFull()\n# ... \u6267\u884c\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n\n# \u6216\u4f7f\u7528\u4ec5\u626b\u63cf\u9501\u4ee5\u8fdb\u884c\u8f83\u8f7b\u7684\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireScanOnly()\n# ... \u6267\u884c\u626b\u63cf\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n
      "},{"location":"qsl4a/core/android-base/","title":"Android \u57fa\u7840\u7c7b","text":"

      Android \u7c7b\u662f QSL4A \u7684\u6838\u5fc3\uff0c\u63d0\u4f9b\u4e86\u4e0e Android \u8fd0\u884c\u65f6\u7684\u8fde\u63a5\u548c RPC \u673a\u5236\u3002

      "},{"location":"qsl4a/core/android-base/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
      # \u529f\u80fd\u5b8c\u6574\u7248\u672c\uff08\u63a8\u8350\uff09\nimport androidhelper\ndroid = androidhelper.Android()\n\n# \u7b80\u5316\u7248\u672c\uff08\u5feb\u901f\uff0c\u5355\u5b9e\u4f8b\uff09\nimport android\ndroid = android.droid\n
      "},{"location":"qsl4a/core/android-base/#android_1","title":"\u7c7b\uff1aAndroid","text":""},{"location":"qsl4a/core/android-base/#_2","title":"\u6784\u9020\u51fd\u6570","text":"
      Android(addr=None)\n

      \u53c2\u6570\uff1a - addr (tuple, optional): (HOST, PORT) \u5730\u5740\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u73af\u5883\u53d8\u91cf AP_HOST \u548c AP_PORT

      \u73af\u5883\u53d8\u91cf\uff1a - AP_HOST - \u670d\u52a1\u5668\u4e3b\u673a\u5730\u5740 - AP_PORT - \u670d\u52a1\u5668\u7aef\u53e3 - AP_HANDSHAKE - \u8ba4\u8bc1\u4ee4\u724c

      "},{"location":"qsl4a/core/android-base/#_3","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/android-base/#_rpc","title":"_rpc()","text":"

      \u8c03\u7528 Android \u51fd\u6570\u7684\u5185\u90e8 RPC \u65b9\u6cd5\u3002

      _rpc(method, *args)\n

      \u53c2\u6570\uff1a - method (str): \u8981\u8c03\u7528\u7684\u65b9\u6cd5\u540d - *args: \u65b9\u6cd5\u7684\u53ef\u53d8\u53c2\u6570

      \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4\uff0c\u5305\u542b\u4ee5\u4e0b\u5b57\u6bb5\uff1a - id (int): \u8bf7\u6c42 ID - result: \u65b9\u6cd5\u8fd4\u56de\u503c - error (str or None): \u9519\u8bef\u4fe1\u606f\uff08\u5982\u679c\u5931\u8d25\uff09

      "},{"location":"qsl4a/core/android-base/#getattr","title":"getattr()","text":"

      \u52a8\u6001\u65b9\u6cd5\u5206\u53d1\u5668\u3002\u6240\u6709 Android \u65b9\u6cd5\u90fd\u901a\u8fc7\u5c5e\u6027\u67e5\u627e\u8bbf\u95ee\u3002

      # \u4ee5\u4e0b\u4e24\u79cd\u65b9\u5f0f\u7b49\u4ef7\uff1a\ndroid.makeToast(\"Hello\")\ndroid._rpc(\"makeToast\", \"Hello\")\n
      "},{"location":"qsl4a/core/android-base/#androidpy","title":"\u72ec\u7acb\u51fd\u6570\uff08android.py\uff09","text":"

      \u4f7f\u7528\u7b80\u5316\u7684 android \u6a21\u5757\u65f6\uff1a

      "},{"location":"qsl4a/core/android-base/#jsla","title":"jsla()","text":"

      \u53d1\u9001 JSON-RPC \u8bf7\u6c42\u5e76\u8fd4\u56de\u539f\u59cb\u54cd\u5e94\u3002

      jsla(method, *params)\n

      \u8fd4\u56de\uff1a JSON \u5b57\u7b26\u4e32\u54cd\u5e94

      "},{"location":"qsl4a/core/android-base/#rsla","title":"rsla()","text":"

      \u53d1\u9001\u8bf7\u6c42\u5e76\u4ec5\u8fd4\u56de\u7ed3\u679c\u3002

      rsla(method, *params)\n

      \u8fd4\u56de\uff1a RPC \u8c03\u7528\u7684\u7ed3\u679c\u503c

      "},{"location":"qsl4a/core/android-base/#esla","title":"esla()","text":"

      \u53d1\u9001\u8bf7\u6c42\uff0c\u9519\u8bef\u65f6\u629b\u51fa\u5f02\u5e38\u3002

      esla(method, *params)\n

      \u629b\u51fa\uff1a \u5982\u679c error \u5b57\u6bb5\u4e0d\u4e3a None \u5219\u629b\u51fa\u5f02\u5e38

      "},{"location":"qsl4a/core/android-base/#nsla","title":"nsla()","text":"

      \u53d1\u9001\u8bf7\u6c42\u5e76\u8fd4\u56de Result \u547d\u540d\u5143\u7ec4\u3002

      nsla(method, *params)\n

      \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4

      "},{"location":"qsl4a/core/android-base/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/android-base/#_5","title":"\u57fa\u672c\u8fde\u63a5","text":"
      import androidhelper\n\n# \u8fde\u63a5\u5230 Android \u8fd0\u884c\u65f6\ndroid = androidhelper.Android()\n\n# \u901a\u8fc7\u663e\u793a toast \u6765\u68c0\u67e5\u8fde\u63a5\ndroid.makeToast(\"Connected!\")\n
      "},{"location":"qsl4a/core/android-base/#_6","title":"\u9519\u8bef\u5904\u7406","text":"
      result = droid.someMethod()\nif result.error:\n    print(f\"Error: {result.error}\")\nelse:\n    print(f\"Success: {result.result}\")\n
      "},{"location":"qsl4a/core/android-base/#rpc","title":"\u76f4\u63a5 RPC \u8c03\u7528","text":"
      # \u76f4\u63a5\u8c03\u7528\u4efb\u610f\u65b9\u6cd5\nresult = droid._rpc(\"makeToast\", \"Hello World\")\n
      "},{"location":"qsl4a/core/events/","title":"\u4e8b\u4ef6\u7cfb\u7edf","text":"

      QSL4A \u63d0\u4f9b\u4e86\u4e00\u4e2a\u4e8b\u4ef6\u7cfb\u7edf\uff0c\u7528\u4e8e\u5904\u7406\u6765\u81ea Android \u7684\u5f02\u6b65\u4e8b\u4ef6\uff0c\u5982\u4f20\u611f\u5668\u66f4\u65b0\u3001\u4f4d\u7f6e\u53d8\u5316\u548c\u81ea\u5b9a\u4e49\u5e7f\u64ad\u3002

      "},{"location":"qsl4a/core/events/#_2","title":"\u4e8b\u4ef6\u57fa\u7840","text":"

      \u4e8b\u4ef6\u5b58\u50a8\u5728\u7f13\u51b2\u533a\u4e2d\uff0c\u53ef\u4ee5\u8f6e\u8be2\u6216\u7b49\u5f85\u3002\u6bcf\u4e2a\u4e8b\u4ef6\u5305\u542b\uff1a - name: \u4e8b\u4ef6\u7c7b\u578b/\u540d\u79f0 - data: \u4e8b\u4ef6\u8d1f\u8f7d\u6570\u636e - time: \u65f6\u95f4\u6233

      "},{"location":"qsl4a/core/events/#_3","title":"\u4e8b\u4ef6\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#eventclearbuffer","title":"eventClearBuffer()","text":"

      \u6e05\u9664\u7f13\u51b2\u533a\u4e2d\u7684\u6240\u6709\u5f85\u5904\u7406\u4e8b\u4ef6\u3002

      eventClearBuffer()\n

      \u8fd4\u56de\uff1a None

      "},{"location":"qsl4a/core/events/#eventpoll","title":"eventPoll()","text":"

      \u8f6e\u8be2\u7f13\u51b2\u533a\u4e2d\u7684\u4e8b\u4ef6\u3002

      eventPoll(number_of_events=1)\n

      \u53c2\u6570\uff1a - number_of_events (int): \u8981\u68c0\u7d22\u7684\u6700\u5927\u4e8b\u4ef6\u6570\uff08\u9ed8\u8ba4\uff1a1\uff09

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\u5217\u8868

      "},{"location":"qsl4a/core/events/#eventwait","title":"eventWait()","text":"

      \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\u3002

      eventWait(timeout=None)\n

      \u53c2\u6570\uff1a - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09\u3002None = \u6c38\u4e45\u7b49\u5f85

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

      "},{"location":"qsl4a/core/events/#eventwaitfor","title":"eventWaitFor()","text":"

      \u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6\u3002

      eventWaitFor(eventName, timeout=None)\n

      \u53c2\u6570\uff1a - eventName (str): \u8981\u7b49\u5f85\u7684\u4e8b\u4ef6\u540d\u79f0 - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

      "},{"location":"qsl4a/core/events/#eventpost","title":"eventPost()","text":"

      \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\u3002

      eventPost(name, data, enqueue=None)\n

      \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e\uff08\u4efb\u610f\u7c7b\u578b\uff09 - enqueue (bool, optional): \u5982\u679c\u4e3a True \u5219\u6dfb\u52a0\u5230\u961f\u5217

      "},{"location":"qsl4a/core/events/#receiveevent","title":"receiveEvent()","text":"

      \u63a5\u6536\u4e8b\u4ef6\uff08\u963b\u585e\uff09\u3002

      receiveEvent()\n

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61

      "},{"location":"qsl4a/core/events/#_4","title":"\u5e7f\u64ad\u4e8b\u4ef6","text":"

      \u6ce8\u518c\u7cfb\u7edf\u5e7f\u64ad\u4e8b\u4ef6\u3002

      "},{"location":"qsl4a/core/events/#eventregisterforbroadcast","title":"eventRegisterForBroadcast()","text":"

      \u6ce8\u518c\u63a5\u6536\u5e7f\u64ad\u4e8b\u4ef6\u3002

      eventRegisterForBroadcast(category, enqueue=True)\n

      \u53c2\u6570\uff1a - category (str): \u5e7f\u64ad\u7c7b\u522b/\u52a8\u4f5c - enqueue (bool): \u6dfb\u52a0\u5230\u4e8b\u4ef6\u961f\u5217

      "},{"location":"qsl4a/core/events/#eventunregisterforbroadcast","title":"eventUnregisterForBroadcast()","text":"

      \u53d6\u6d88\u6ce8\u518c\u5e7f\u64ad\u4e8b\u4ef6\u3002

      eventUnregisterForBroadcast(category)\n
      "},{"location":"qsl4a/core/events/#eventgetbrodcastcategories","title":"eventGetBrodcastCategories()","text":"

      \u83b7\u53d6\u5df2\u6ce8\u518c\u7684\u5e7f\u64ad\u7c7b\u522b\u3002

      eventGetBrodcastCategories()\n

      \u8fd4\u56de\uff1a \u5df2\u6ce8\u518c\u7c7b\u522b\u5217\u8868

      "},{"location":"qsl4a/core/events/#_5","title":"\u4e8b\u4ef6\u5206\u53d1\u5668)","text":""},{"location":"qsl4a/core/events/#starteventdispatcher","title":"startEventDispatcher()","text":"

      \u6253\u5f00\u4e00\u4e2a\u53ef\u4ee5\u8bfb\u53d6\u5df2\u53d1\u5e03\u4e8b\u4ef6\u7684\u5957\u63a5\u5b57\u3002)

      startEventDispatcher(port=0)\n

      \u53c2\u6570\uff1a - port (int, optional): \u76d1\u542c\u7684\u7aef\u53e3\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\u9009\u62e9\uff09

      \u8fd4\u56de\uff1a \u6b63\u5728\u76d1\u542c\u7684\u7aef\u53e3\u53f7

      "},{"location":"qsl4a/core/events/#stopeventdispatcher","title":"stopEventDispatcher()","text":"

      \u505c\u6b62\u4e8b\u4ef6\u670d\u52a1\u5668\u3002)

      stopEventDispatcher()\n
      "},{"location":"qsl4a/core/events/#_6","title":"\u5df2\u5e9f\u5f03\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#rpcpostevent","title":"rpcPostEvent()","text":"

      \u5c06\u4e8b\u4ef6\u53d1\u5e03\u5230\u4e8b\u4ef6\u961f\u5217\u3002\uff08\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 eventPost\uff09

      rpcPostEvent(name, data)\n

      \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e

      "},{"location":"qsl4a/core/events/#_7","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/events/#_8","title":"\u57fa\u672c\u4e8b\u4ef6\u8f6e\u8be2","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6e05\u9664\u65e7\u4e8b\u4ef6\ndroid.eventClearBuffer()\n\n# \u8f6e\u8be2\u4e8b\u4ef6\nevents = droid.eventPoll(5).result\nfor event in events:\n    print(f\"Event: {event['name']}, Data: {event['data']}\")\n
      "},{"location":"qsl4a/core/events/#_9","title":"\u7b49\u5f85\u4e8b\u4ef6","text":"
      # \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\uff0c\u5e26\u8d85\u65f6\nevent = droid.eventWait(timeout=10).result\nif event:\n    print(f\"Got event: {event['name']}\")\n
      "},{"location":"qsl4a/core/events/#_10","title":"\u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6","text":"
      # \u7b49\u5f85\u4f20\u611f\u5668\u4e8b\u4ef6\nevent = droid.eventWaitFor('screen', timeout=5).result\nif event:\n    print(f\"Screen event: {event['data']}\")\n
      "},{"location":"qsl4a/core/events/#_11","title":"\u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6","text":"
      # \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\ndroid.eventPost('my_event', {'key': 'value'})\n\n# \u7b49\u5f85\u5b83\nevent = droid.eventWaitFor('my_event', timeout=1).result\n
      "},{"location":"qsl4a/core/events/#_12","title":"\u5e7f\u64ad\u63a5\u6536\u5668","text":"
      # \u6ce8\u518c\u5c4f\u5e55\u5f00\u5173\u4e8b\u4ef6\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_ON')\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_OFF')\n\n# \u7b49\u5f85\u5c4f\u5e55\u4e8b\u4ef6\nwhile True:\n    event = droid.receiveEvent().result\n    if event['name'] == 'android.intent.action.SCREEN_ON':\n        print(\"Screen turned on\")\n    elif event['name'] == 'android.intent.action.SCREEN_OFF':\n        print(\"Screen turned off\")\n
      "},{"location":"qsl4a/core/events/#_13","title":"\u4f20\u611f\u5668\u4e8b\u4ef6\u5904\u7406","text":"
      # \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u5904\u7406\u4f20\u611f\u5668\u4e8b\u4ef6\nfor _ in range(100):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'sensors':\n        data = event['data']\n        print(f\"Accel: {data['xforce']}, {data['yforce']}, {data['zforce']}\")\n\ndroid.stopSensing()\n
      "},{"location":"qsl4a/core/events/#_14","title":"\u5e38\u89c1\u4e8b\u4ef6\u7c7b\u578b","text":"\u4e8b\u4ef6\u540d\u79f0 \u63cf\u8ff0 \u6765\u6e90 sensors \u4f20\u611f\u5668\u6570\u636e\u66f4\u65b0 startSensing* location GPS \u4f4d\u7f6e\u66f4\u65b0 startLocating phone \u7535\u8bdd\u72b6\u6001\u53d8\u5316 startTrackingPhoneState signal \u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316 startTrackingSignalStrength screen \u622a\u56fe\u5c31\u7eea fullGetScreenShot dialog \u5bf9\u8bdd\u6846\u54cd\u5e94 dialogShow*"},{"location":"qsl4a/core/events/#_15","title":"\u4e8b\u4ef6\u6570\u636e\u7ed3\u6784","text":"
      {\n    'name': 'event_name',\n    'data': {\n        # \u4e8b\u4ef6\u7279\u5b9a\u6570\u636e\n    },\n    'time': 1234567890  # \u65f6\u95f4\u6233\n}\n
      "},{"location":"qsl4a/core/intent/","title":"Intent \u7cfb\u7edf","text":"

      Android Intent \u7528\u4e8e\u542f\u52a8\u6d3b\u52a8\u3001\u53d1\u9001\u5e7f\u64ad\u548c\u5e94\u7528\u95f4\u901a\u4fe1\u3002QSL4A \u901a\u8fc7 Intent \u6a21\u5757\u63d0\u4f9b\u5b8c\u6574\u7684 Intent \u652f\u6301\u3002

      "},{"location":"qsl4a/core/intent/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
      import androidhelper\ndon = androidhelper.Android()\n
      "},{"location":"qsl4a/core/intent/#intent_1","title":"Intent \u5e38\u91cf","text":"

      \u901a\u8fc7 droid.Intent \u8bbf\u95ee\uff1a

      "},{"location":"qsl4a/core/intent/#_2","title":"\u64cd\u4f5c","text":"\u5e38\u91cf \u503c \u7528\u9014 ACTION_MAIN android.intent.action.MAIN \u5e94\u7528\u5165\u53e3\u70b9 ACTION_VIEW android.intent.action.VIEW \u67e5\u770b\u5185\u5bb9 ACTION_EDIT android.intent.action.EDIT \u7f16\u8f91\u5185\u5bb9 ACTION_PICK android.intent.action.PICK \u9009\u62e9\u9879\u76ee ACTION_SEND android.intent.action.SEND \u5206\u4eab\u5185\u5bb9 ACTION_SEARCH android.intent.action.SEARCH \u641c\u7d22"},{"location":"qsl4a/core/intent/#_3","title":"\u6807\u5fd7","text":"\u5e38\u91cf \u503c \u7528\u9014 FLAG_ACTIVITY_NEW_TASK 268435456 \u542f\u52a8\u65b0\u4efb\u52a1 FLAG_ACTIVITY_CLEAR_TASK 32768 \u6e05\u9664\u4efb\u52a1\u5806\u6808 FLAG_ACTIVITY_NEW_DOCUMENT 524288 \u65b0\u6587\u6863\u6a21\u5f0f"},{"location":"qsl4a/core/intent/#_4","title":"\u9644\u52a0\u6570\u636e","text":"\u5e38\u91cf \u7528\u9014 EXTRA_TEXT \u6587\u672c\u5185\u5bb9 EXTRA_STREAM \u6587\u4ef6 URI EXTRA_SUBJECT \u4e3b\u9898\u884c EXTRA_EMAIL \u7535\u5b50\u90ae\u4ef6\u5730\u5740"},{"location":"qsl4a/core/intent/#_5","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/intent/#makeintent","title":"makeIntent()","text":"

      \u521b\u5efa Intent \u5bf9\u8c61\u3002

      makeIntent(action, uri=None, type=None, extras=None, categories=None,\n           packagename=None, classname=None, flags=None)\n

      \u53c2\u6570\uff1a - action (str): Intent \u64cd\u4f5c\uff08\u4f8b\u5982 droid.Intent.ACTION_VIEW\uff09 - uri (str, optional): \u6570\u636e URI - type (str, optional): MIME \u7c7b\u578b - extras (dict, optional): \u9644\u52a0\u6570\u636e - categories (list, optional): Intent \u7c7b\u522b - packagename (str, optional): \u76ee\u6807\u5305 - classname (str, optional): \u76ee\u6807\u7c7b - flags (int, optional): Intent \u6807\u5fd7

      \u8fd4\u56de\uff1a Intent \u5bf9\u8c61

      "},{"location":"qsl4a/core/intent/#startactivityintent","title":"startActivityIntent()","text":"

      \u4f7f\u7528 Intent \u542f\u52a8 Activity\u3002

      startActivityIntent(intent, wait=None)\n

      \u53c2\u6570\uff1a - intent: makeIntent() \u8fd4\u56de\u7684 Intent \u5bf9\u8c61 - wait (bool, optional): \u963b\u585e\u76f4\u5230\u6d3b\u52a8\u5173\u95ed

      "},{"location":"qsl4a/core/intent/#startactivityforresultintent","title":"startActivityForResultIntent()","text":"

      \u542f\u52a8\u6d3b\u52a8\u5e76\u7b49\u5f85\u7ed3\u679c\u3002

      startActivityForResultIntent(intent)\n

      \u8fd4\u56de\uff1a Activity \u7ed3\u679c

      "},{"location":"qsl4a/core/intent/#sendbroadcastintent","title":"sendBroadcastIntent()","text":"

      \u53d1\u9001\u5e7f\u64ad\u3002

      sendBroadcastIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#view","title":"view()","text":"

      \u901a\u8fc7 URI \u67e5\u770b\u5185\u5bb9\u3002

      view(uri, type=None, extras=None)\n
      "},{"location":"qsl4a/core/intent/#pick","title":"pick()","text":"

      \u4ece URI \u9009\u62e9\u5185\u5bb9\u3002

      pick(uri)\n
      "},{"location":"qsl4a/core/intent/#intent_2","title":"\u5e38\u89c1 Intent \u65b9\u6cd5)","text":""},{"location":"qsl4a/core/intent/#scanbarcode","title":"scanBarcode()","text":"

      \u542f\u52a8\u6761\u7801\u626b\u63cf\u5668\u3002

      scanBarcode()\n

      \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/core/intent/#send","title":"send()","text":"

      \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u5185\u5bb9\u3002

      send(type, content)\n

      \u53c2\u6570\uff1a - type (str): MIME \u7c7b\u578b - content (str): \u8981\u5206\u4eab\u7684\u5185\u5bb9

      "},{"location":"qsl4a/core/intent/#sendtext","title":"sendText()","text":"

      \u53d1\u9001\u6587\u672c\u5185\u5bb9\u3002

      sendText(text)\n

      \u53c2\u6570\uff1a - text (str): \u8981\u53d1\u9001\u7684\u6587\u672c

      "},{"location":"qsl4a/core/intent/#sendemail","title":"sendEmail()","text":"

      \u53d1\u9001\u7535\u5b50\u90ae\u4ef6\u3002

      sendEmail(to, subject, body, attachment=None)\n

      \u53c2\u6570\uff1a - to (str or list): \u6536\u4ef6\u4eba\u7535\u5b50\u90ae\u4ef6\u5730\u5740 - subject (str): \u7535\u5b50\u90ae\u4ef6\u4e3b\u9898 - body (str): \u7535\u5b50\u90ae\u4ef6\u6b63\u6587 - attachment (str, optional): \u9644\u4ef6\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/core/intent/#pathtouri","title":"pathToUri()","text":"

      \u5c06\u6587\u4ef6\u8def\u5f84\u8f6c\u6362\u4e3a\u5185\u5bb9 URI\u3002

      pathToUri(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5185\u5bb9 URI \u5b57\u7b26\u4e32

      "},{"location":"qsl4a/core/intent/#openfile","title":"openFile()","text":"

      \u7528\u9002\u5f53\u7684\u5e94\u7528\u7a0b\u5e8f\u6253\u5f00\u6587\u4ef6\u3002

      openFile(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u6253\u5f00\u7684\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/core/intent/#sendfile","title":"sendFile()","text":"

      \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u6587\u4ef6\u3002

      sendFile(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u53d1\u9001\u7684\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/core/intent/#getpathtype","title":"getPathType()","text":"

      \u83b7\u53d6\u6587\u4ef6\u8def\u5f84\u7684 MIME \u7c7b\u578b\u3002

      getPathType(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a MIME \u7c7b\u578b\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/core/intent/#viewmap","title":"viewMap()","text":"

      \u5728\u6307\u5b9a\u4f4d\u7f6e\u6253\u5f00\u5730\u56fe\u3002

      viewMap(latitude, longitude)\n

      \u53c2\u6570\uff1a - latitude (float): \u7eac\u5ea6 - longitude (float): \u7ecf\u5ea6

      "},{"location":"qsl4a/core/intent/#viewcontacts","title":"viewContacts()","text":"

      \u6253\u5f00\u8054\u7cfb\u4eba\u5e94\u7528\u3002

      viewContacts()\n
      "},{"location":"qsl4a/core/intent/#search","title":"search()","text":"

      \u6267\u884c\u7f51\u7edc\u641c\u7d22\u3002

      search(query)\n

      \u53c2\u6570\uff1a - query (str): \u641c\u7d22\u67e5\u8be2

      "},{"location":"qsl4a/core/intent/#viewhtml","title":"viewHtml()","text":"

      \u67e5\u770b HTML \u5185\u5bb9\u3002

      viewHtml(content, encoding=None)\n

      \u53c2\u6570\uff1a - content (str): HTML \u5185\u5bb9 - encoding (str, optional): \u5b57\u7b26\u7f16\u7801

      "},{"location":"qsl4a/core/intent/#webviewshow","title":"webViewShow()","text":"

      \u5728 WebView \u4e2d\u663e\u793a\u7f51\u9875\u5185\u5bb9\u3002\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 viewHtml\u3002

      webViewShow(url)\n

      \u53c2\u6570\uff1a - url (str): \u7f51\u9875 URL

      "},{"location":"qsl4a/core/intent/#editoropen","title":"editorOpen()","text":"

      \u6253\u5f00\u6587\u672c\u7f16\u8f91\u5668\u3002

      editorOpen(path=None, create=False)\n

      \u53c2\u6570\uff1a - path (str, optional): \u8981\u7f16\u8f91\u7684\u6587\u4ef6\u8def\u5f84 - create (bool, optional): \u5982\u679c\u4e0d\u5b58\u5728\u5219\u521b\u5efa

      "},{"location":"qsl4a/core/intent/#uri","title":"\u8f85\u52a9\u7c7b\uff1aUri","text":"

      \u521b\u5efa Intent \u7684 URI \u5bf9\u8c61\uff1a

      from androidhelper.Intent import Uri\n\nuri = Uri(\"file:///sdcard/test.txt\")\n
      "},{"location":"qsl4a/core/intent/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/intent/#_7","title":"\u6253\u5f00\u7f51\u9875","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"http://www.example.com\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_8","title":"\u5206\u4eab\u6587\u672c","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_TEXT: \"Hello from QPython!\",\n        droid.Intent.EXTRA_SUBJECT: \"Test\"\n    },\n    type=\"text/plain\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_9","title":"\u6253\u5f00\u6587\u4ef6","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"file:///sdcard/document.pdf\",\n    type=\"application/pdf\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_10","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":"
      result = droid.pickContact()\ncontact_uri = result.result\n
      "},{"location":"qsl4a/core/intent/#_11","title":"\u53d1\u9001\u7535\u5b50\u90ae\u4ef6","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_EMAIL: [\"test@example.com\"],\n        droid.Intent.EXTRA_SUBJECT: \"Hello\",\n        droid.Intent.EXTRA_TEXT: \"Message body\"\n    },\n    type=\"message/rfc822\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_12","title":"\u6253\u5f00\u5e94\u7528","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_MAIN,\n    packagename=\"com.android.settings\",\n    classname=\"com.android.settings.Settings\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/hardware/bluetooth/","title":"\u84dd\u7259 API","text":"

      \u63a7\u5236\u84dd\u7259\u9002\u914d\u5668\u5e76\u4e0e\u84dd\u7259\u8bbe\u5907\u901a\u4fe1\u3002

      "},{"location":"qsl4a/hardware/bluetooth/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/hardware/bluetooth/#togglebluetoothstate","title":"toggleBluetoothState()","text":"

      \u6253\u5f00/\u5173\u95ed\u84dd\u7259\u3002

      toggleBluetoothState(enabled=None, prompt=True)\n

      \u53c2\u6570\uff1a - enabled (bool): True=\u5f00\uff0cFalse=\u5173\uff0cNone=\u5207\u6362 - prompt (bool): \u663e\u793a\u7528\u6237\u63d0\u793a

      "},{"location":"qsl4a/hardware/bluetooth/#checkbluetoothstate","title":"checkBluetoothState()","text":"

      \u68c0\u67e5\u84dd\u7259\u662f\u5426\u5df2\u542f\u7528\u3002

      checkBluetoothState()\n

      \u8fd4\u56de\uff1a True/False

      "},{"location":"qsl4a/hardware/bluetooth/#getlocalname","title":"GetLocalName()","text":"

      \u83b7\u53d6\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

      GetLocalName()\n
      "},{"location":"qsl4a/hardware/bluetooth/#setlocalname","title":"SetLocalName()","text":"

      \u8bbe\u7f6e\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

      SetLocalName(name)\n
      "},{"location":"qsl4a/hardware/bluetooth/#getscanmode","title":"GetScanMode()","text":"

      \u83b7\u53d6\u53ef\u53d1\u73b0\u6027\u6a21\u5f0f\u3002

      GetScanMode()\n

      \u8fd4\u56de\uff1a - -1: \u5df2\u7981\u7528 - 0: \u4e0d\u53ef\u53d1\u73b0\uff0c\u4e0d\u53ef\u8fde\u63a5 - 1: \u53ef\u8fde\u63a5\uff0c\u4e0d\u53ef\u53d1\u73b0 - 3: \u53ef\u8fde\u63a5\u4e14\u53ef\u53d1\u73b0

      "},{"location":"qsl4a/hardware/bluetooth/#makediscoverable","title":"MakeDiscoverable()","text":"

      \u4f7f\u8bbe\u5907\u53ef\u53d1\u73b0\u3002

      MakeDiscoverable(duration=300)\n

      \u53c2\u6570\uff1a - duration (int): \u53ef\u53d1\u73b0\u7684\u79d2\u6570

      "},{"location":"qsl4a/hardware/bluetooth/#_2","title":"\u53d1\u73b0","text":""},{"location":"qsl4a/hardware/bluetooth/#discoverystart","title":"DiscoveryStart()","text":"

      \u5f00\u59cb\u8bbe\u5907\u53d1\u73b0\u3002

      DiscoveryStart()\n
      "},{"location":"qsl4a/hardware/bluetooth/#discoverycancel","title":"DiscoveryCancel()","text":"

      \u53d6\u6d88\u53d1\u73b0\u3002

      DiscoveryCancel()\n
      "},{"location":"qsl4a/hardware/bluetooth/#getreceiveddevices","title":"GetReceivedDevices()","text":"

      \u83b7\u53d6\u53d1\u73b0\u7684\u8bbe\u5907\u3002

      GetReceivedDevices()\n

      \u8fd4\u56de\uff1a \u8bbe\u5907\u4fe1\u606f\u5b57\u5178\u5217\u8868

      "},{"location":"qsl4a/hardware/bluetooth/#getbondeddevices","title":"GetBondedDevices()","text":"

      \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\u3002

      GetBondedDevices()\n

      \u8fd4\u56de\uff1a \u914d\u5bf9\u8bbe\u5907\u4fe1\u606f\u5217\u8868

      "},{"location":"qsl4a/hardware/bluetooth/#_3","title":"\u8fde\u63a5","text":""},{"location":"qsl4a/hardware/bluetooth/#connect","title":"Connect()","text":"

      \u8fde\u63a5\u5230\u8bbe\u5907\u3002

      Connect(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", address=None)\n

      \u53c2\u6570\uff1a - uuid (str): \u670d\u52a1 UUID - address (str): \u8bbe\u5907\u5730\u5740\uff08None = \u663e\u793a\u9009\u62e9\u5668\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/hardware/bluetooth/#accept","title":"Accept()","text":"

      \u63a5\u53d7\u4f20\u5165\u8fde\u63a5\u3002

      Accept(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", timeout=0)\n
      "},{"location":"qsl4a/hardware/bluetooth/#activeconnections","title":"ActiveConnections()","text":"

      \u68c0\u67e5\u6d3b\u52a8\u8fde\u63a5\u3002

      ActiveConnections()\n
      "},{"location":"qsl4a/hardware/bluetooth/#stop","title":"Stop()","text":"

      \u65ad\u5f00\u8fde\u63a5\u3002

      Stop(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#_4","title":"\u901a\u4fe1","text":""},{"location":"qsl4a/hardware/bluetooth/#write","title":"Write()","text":"

      \u53d1\u9001 ASCII \u6570\u636e\u3002

      Write(ascii, connID=\"\")\n
      "},{"location":"qsl4a/hardware/bluetooth/#writebinary","title":"WriteBinary()","text":"

      \u53d1\u9001\u4e8c\u8fdb\u5236\u6570\u636e\uff08base64 \u7f16\u7801\uff09\u3002

      WriteBinary(base64, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#read","title":"Read()","text":"

      \u8bfb\u53d6 ASCII \u6570\u636e\u3002

      Read(bufferSize=4096, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readbinary","title":"ReadBinary()","text":"

      \u8bfb\u53d6\u4e8c\u8fdb\u5236\u6570\u636e\u3002

      ReadBinary(bufferSize=4096, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readline","title":"ReadLine()","text":"

      \u8bfb\u53d6\u4e00\u884c\u3002

      ReadLine(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readready","title":"ReadReady()","text":"

      \u68c0\u67e5\u662f\u5426\u6709\u53ef\u7528\u6570\u636e\u3002

      ReadReady(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u7528\u84dd\u7259\ndroid.toggleBluetoothState(True)\n\n# \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\ndevices = droid.GetBondedDevices().result\nfor dev in devices:\n    print(f\"{dev['name']}: {dev['address']}\")\n\n# \u8fde\u63a5\u5230\u8bbe\u5907\ndroid.Connect(address=\"00:11:22:33:44:55\")\n\n# \u53d1\u9001\u6570\u636e\ndroid.Write(\"Hello Bluetooth!\")\n\n# \u8bfb\u53d6\u54cd\u5e94\ndata = droid.Read(1024).result\n
      "},{"location":"qsl4a/hardware/camera/","title":"\u76f8\u673a API","text":"

      \u62cd\u6444\u7167\u7247\u548c\u5f55\u5236\u89c6\u9891\u3002

      "},{"location":"qsl4a/hardware/camera/#_1","title":"\u7167\u7247\u62cd\u6444","text":""},{"location":"qsl4a/hardware/camera/#takepicture","title":"takePicture()","text":"

      \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u6444\u7167\u7247\u3002

      takePicture(path=None)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8fd4\u56de\u56fe\u50cf\u6570\u636e

      \u8fd4\u56de\uff1a \u56fe\u50cf\u8def\u5f84\u6216\u56fe\u50cf\u6570\u636e

      "},{"location":"qsl4a/hardware/camera/#cameracapturepicture","title":"cameraCapturePicture()","text":"

      \u4f7f\u7528\u9ad8\u7ea7\u76f8\u673a\u63a7\u5236\u62cd\u6444\u7167\u7247\u3002

      cameraCapturePicture(targetPath=None, cameraId=0, useAutoFocus=True)\n

      \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - useAutoFocus (bool): \u542f\u7528\u81ea\u52a8\u5bf9\u7126

      \u8fd4\u56de\uff1a \u62cd\u6444\u7684\u56fe\u50cf\u8def\u5f84

      "},{"location":"qsl4a/hardware/camera/#camerasettorchmode","title":"cameraSetTorchMode()","text":"

      \u63a7\u5236\u76f8\u673a\u95ea\u5149\u706f/\u624b\u7535\u7b52\u3002

      cameraSetTorchMode(enabled)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u6253\u5f00\uff0cFalse \u5173\u95ed

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/hardware/camera/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

      \u622a\u56fe\u3002

      imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

      "},{"location":"qsl4a/hardware/camera/#_2","title":"\u89c6\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#takevideo","title":"takeVideo()","text":"

      \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\u3002

      takeVideo(path=None, quality=1)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-4\uff09 - 0: 160x120 - 1: 320x240 - 2: 352x288 - 3: 640x480 - 4: 800x480

      "},{"location":"qsl4a/hardware/camera/#recordercapturevideo","title":"recorderCaptureVideo()","text":"

      \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\u3002

      recorderCaptureVideo(targetPath=None, duration=10, cameraId=0, quality=8)\n

      \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - duration (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a10\uff09 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-8\uff0c\u8d8a\u9ad8\u8d8a\u597d\uff09

      \u8fd4\u56de\uff1a \u89c6\u9891\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/hardware/camera/#recordaudio","title":"recordAudio()","text":"

      \u5f55\u5236\u97f3\u9891\u3002

      recordAudio()\n

      \u8fd4\u56de\uff1a \u97f3\u9891\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/hardware/camera/#_3","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

      \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\u3002

      recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

      \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\uff09 - targetPixels (int): \u5206\u8fa8\u7387 - frameRate (int): FPS - bitRate (int): \u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa - autoStart (bool): \u7acb\u5373\u5f00\u59cb

      "},{"location":"qsl4a/hardware/camera/#recorderstart","title":"recorderStart()","text":"

      \u5f00\u59cb\u5f55\u5236\u3002

      recorderStart()\n
      "},{"location":"qsl4a/hardware/camera/#recorderpause","title":"recorderPause()","text":"

      \u6682\u505c\u5f55\u5236\u3002

      recorderPause()\n
      "},{"location":"qsl4a/hardware/camera/#recorderresume","title":"recorderResume()","text":"

      \u6062\u590d\u5f55\u5236\u3002

      recorderResume()\n
      "},{"location":"qsl4a/hardware/camera/#_4","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/camera/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

      \u5f00\u59cb\u97f3\u91cf\u68c0\u6d4b\u3002

      recorderSoundVolumeDetect(interval=100)\n
      "},{"location":"qsl4a/hardware/camera/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

      \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

      recorderSoundVolumeGetDb()\n
      "},{"location":"qsl4a/hardware/camera/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u7167\nphoto_path = droid.takePicture(\"/sdcard/photo.jpg\").result\nprint(f\"Photo saved: {photo_path}\")\n\n# \u4f7f\u7528\u524d\u7f6e\u76f8\u673a\u548c\u81ea\u52a8\u5bf9\u7126\u62cd\u7167\ncamera_path = droid.cameraCapturePicture(\"/sdcard/selfie.jpg\", cameraId=1, useAutoFocus=True).result\nprint(f\"Front camera photo: {camera_path}\")\n\n# \u63a7\u5236\u95ea\u5149\u706f\ndroid.cameraSetTorchMode(True)  # \u6253\u5f00\u95ea\u5149\u706f\n\n# \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\nvideo_path = droid.takeVideo(\"/sdcard/video.mp4\", quality=3).result\nprint(f\"Video saved: {video_path}\")\n\n# \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\nvideo_path = droid.recorderCaptureVideo(\"/sdcard/movie.mp4\", duration=30, cameraId=0, quality=8).result\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n
      "},{"location":"qsl4a/hardware/recorder/","title":"\u97f3\u9891\u5f55\u5236 API","text":"

      \u4ece\u9ea6\u514b\u98ce\u548c\u8bbe\u5907\u5c4f\u5e55\u5f55\u5236\u97f3\u9891\u3002

      "},{"location":"qsl4a/hardware/recorder/#_1","title":"\u97f3\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recordaudio","title":"recordAudio()","text":"

      \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\u3002

      recordAudio()\n

      \u8fd4\u56de\uff1a \u5f55\u5236\u7684\u97f3\u9891\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/hardware/recorder/#recorderstartmicrophone","title":"recorderStartMicrophone()","text":"

      \u5f00\u59cb\u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\u3002

      recorderStartMicrophone(targetPath=None)\n

      \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u5f55\u5236\u7684\u8def\u5f84

      "},{"location":"qsl4a/hardware/recorder/#_2","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

      \u5f00\u59cb\u5e26\u97f3\u9891\u7684\u5c4f\u5e55\u5f55\u5236\u3002

      recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

      \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\u97f3\u9891\uff09 - targetPixels (int): \u76ee\u6807\u5206\u8fa8\u7387\uff08\u50cf\u7d20\uff09 - frameRate (int): \u6bcf\u79d2\u5e27\u6570\uff08\u9ed8\u8ba4\uff1a30\uff09 - bitRate (int): \u89c6\u9891\u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa\u89c6\u9891 - autoStart (bool): \u7acb\u5373\u5f00\u59cb\u5f55\u5236

      \u8fd4\u56de\uff1a \u64cd\u4f5c\u7ed3\u679c

      "},{"location":"qsl4a/hardware/recorder/#recorderstart","title":"recorderStart()","text":"

      \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\uff08\u5f53 autoStart=False \u65f6\uff09\u3002

      recorderStart()\n
      "},{"location":"qsl4a/hardware/recorder/#recorderpause","title":"recorderPause()","text":"

      \u6682\u505c\u6b63\u5728\u8fdb\u884c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

      recorderPause()\n
      "},{"location":"qsl4a/hardware/recorder/#recorderresume","title":"recorderResume()","text":"

      \u6062\u590d\u6682\u505c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

      recorderResume()\n
      "},{"location":"qsl4a/hardware/recorder/#_3","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/recorder/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

      \u5f00\u59cb\u76d1\u63a7\u97f3\u91cf\u7ea7\u522b\u3002

      recorderSoundVolumeDetect(interval=100)\n

      \u53c2\u6570\uff1a - interval (int): \u68c0\u6d4b\u95f4\u9694\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a100\uff09

      "},{"location":"qsl4a/hardware/recorder/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

      \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

      recorderSoundVolumeGetDb()\n

      \u8fd4\u56de\uff1a \u5f53\u524d\u97f3\u91cf\u7ea7\u522b\uff08dB\uff09

      "},{"location":"qsl4a/hardware/recorder/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\nprint(\"Recording audio...\")\naudio_path = droid.recordAudio().result\nprint(f\"Saved to: {audio_path}\")\n\n# \u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\ndroid.recorderStartMicrophone(\"/sdcard/my_recording.mp3\")\ntime.sleep(5)\ndroid.recorderStop()\n\n# \u5e26\u97f3\u9891\u5f55\u5236\u5c4f\u5e55\nprint(\"Starting screen recording...\")\ndroid.recorderStartScreenRecord(\n    path=\"/sdcard/screen_record.mp4\",\n    audio=1,\n    frameRate=30,\n    autoStart=True\n)\ntime.sleep(10)\ndroid.recorderStop()\n\n# \u76d1\u63a7\u97f3\u91cf\ndroid.recorderSoundVolumeDetect(interval=100)\ntime.sleep(3)\nvolume = droid.recorderSoundVolumeGetDb().result\nprint(f\"Current volume: {volume} dB\")\n
      "},{"location":"qsl4a/hardware/usbserial/","title":"USB \u4e3b\u673a\u4e32\u884c API","text":"

      \u4e0e USB \u4e32\u884c\u8bbe\u5907\u901a\u4fe1\uff08\u9700\u8981 USB OTG \u652f\u6301\u548c Android 3.1+\uff09\u3002

      "},{"location":"qsl4a/hardware/usbserial/#usb","title":"USB \u4e32\u884c\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialopen","title":"usbHostSerialOpen()","text":"

      \u6253\u5f00\u4e0e USB \u4e32\u884c\u8bbe\u5907\u7684\u8fde\u63a5\u3002

      usbHostSerialOpen(device, baudRate=9600)\n

      \u53c2\u6570\uff1a - device (str): USB \u8bbe\u5907\u8def\u5f84\u6216\u6807\u8bc6\u7b26 - baudRate (int): \u6ce2\u7279\u7387\uff08\u9ed8\u8ba4\uff1a9600\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u6253\u5f00\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialclose","title":"usbHostSerialClose()","text":"

      \u5173\u95ed USB \u4e32\u884c\u8fde\u63a5\u3002

      usbHostSerialClose()\n
      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialread","title":"usbHostSerialRead()","text":"

      \u4ece USB \u4e32\u884c\u8bfb\u53d6\u6570\u636e\u3002

      usbHostSerialRead(bufferSize=1024)\n

      \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570\uff08\u9ed8\u8ba4\uff1a1024\uff09

      \u8fd4\u56de\uff1a \u8bfb\u53d6\u7684\u6570\u636e\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwrite","title":"usbHostSerialWrite()","text":"

      \u5411 USB \u4e32\u884c\u5199\u5165\u6570\u636e\u3002

      usbHostSerialWrite(data)\n

      \u53c2\u6570\uff1a - data (str): \u8981\u5199\u5165\u7684\u5b57\u7b26\u4e32\u6570\u636e

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialavailable","title":"usbHostSerialAvailable()","text":"

      \u68c0\u67e5\u662f\u5426\u6709\u53ef\u8bfb\u53d6\u7684\u6570\u636e\u3002

      usbHostSerialAvailable()\n

      \u8fd4\u56de\uff1a \u53ef\u7528\u5b57\u8282\u6570

      "},{"location":"qsl4a/hardware/usbserial/#_1","title":"\u914d\u7f6e\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetbaudrate","title":"usbHostSerialSetBaudRate()","text":"

      \u8bbe\u7f6e\u6ce2\u7279\u7387\u3002

      usbHostSerialSetBaudRate(baudRate)\n

      \u53c2\u6570\uff1a - baudRate (int): \u6ce2\u7279\u7387

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetdatabits","title":"usbHostSerialSetDataBits()","text":"

      \u8bbe\u7f6e\u6570\u636e\u4f4d\uff085\u30016\u30017 \u6216 8\uff09\u3002

      usbHostSerialSetDataBits(dataBits)\n

      \u53c2\u6570\uff1a - dataBits (int): \u6570\u636e\u4f4d\uff085-8\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetstopbits","title":"usbHostSerialSetStopBits()","text":"

      \u8bbe\u7f6e\u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09\u3002

      usbHostSerialSetStopBits(stopBits)\n

      \u53c2\u6570\uff1a - stopBits (float): \u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetparity","title":"usbHostSerialSetParity()","text":"

      \u8bbe\u7f6e\u6821\u9a8c\u4f4d\uff08\u65e0\u3001\u5947\u3001\u5076\u3001\u6807\u8bb0\u3001\u7a7a\u683c\uff09\u3002

      usbHostSerialSetParity(parity)\n

      \u53c2\u6570\uff1a - parity (str): \u6821\u9a8c\u6a21\u5f0f\uff08'none'\u3001'odd'\u3001'even'\u3001'mark'\u3001'space'\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetflowcontrol","title":"usbHostSerialSetFlowControl()","text":"

      \u8bbe\u7f6e\u6d41\u63a7\u5236\uff08\u65e0\u3001\u786c\u4ef6\u3001\u8f6f\u4ef6\uff09\u3002

      usbHostSerialSetFlowControl(flowControl)\n

      \u53c2\u6570\uff1a - flowControl (str): \u6d41\u63a7\u5236\u6a21\u5f0f\uff08'none'\u3001'hardware'\u3001'software'\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialreadhex","title":"usbHostSerialReadHex()","text":"

      \u4ee5\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u8bfb\u53d6\u6570\u636e\u3002

      usbHostSerialReadHex(bufferSize=1024)\n

      \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570

      \u8fd4\u56de\uff1a \u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwritehex","title":"usbHostSerialWriteHex()","text":"

      \u4ece\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u5199\u5165\u6570\u636e\u3002

      usbHostSerialWriteHex(hexString)\n

      \u53c2\u6570\uff1a - hexString (str): \u8981\u5199\u5165\u7684\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/hardware/usbserial/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6253\u5f00 USB \u4e32\u884c\u8fde\u63a5\nif droid.usbHostSerialOpen(\"/dev/bus/usb/001/001\", 115200).result:\n    print(\"USB serial opened\")\n\n    # \u5199\u5165\u6570\u636e\n    droid.usbHostSerialWrite(\"AT\\r\")\n\n    # \u8bfb\u53d6\u54cd\u5e94\n    response = droid.usbHostSerialRead(1024).result\n    print(f\"Response: {response}\")\n\n    # \u6216\u4f7f\u7528\u5341\u516d\u8fdb\u5236\n    droid.usbHostSerialWriteHex(\"41540D0A\")  # \"AT\\r\\n\"\n\n    # \u5173\u95ed\u8fde\u63a5\n    droid.usbHostSerialClose()\n

      \u6ce8\u610f\uff1a USB \u4e32\u884c\u9700\u8981\uff1a - Android 3.1+ (API 12) - USB OTG \u7ebf/\u9002\u914d\u5668 - \u8bbe\u5907\u4e0a\u7684 USB \u4e3b\u673a\u6a21\u5f0f\u652f\u6301 - \u517c\u5bb9\u7684\u4e32\u884c\u8bbe\u5907

      "},{"location":"qsl4a/hardware/webcam/","title":"\u7f51\u7edc\u6444\u50cf\u5934 API","text":"

      \u4f7f\u7528 MJPEG \u4ece\u8bbe\u5907\u76f8\u673a\u6d41\u5f0f\u4f20\u8f93\u89c6\u9891\u3002

      "},{"location":"qsl4a/hardware/webcam/#mjpeg","title":"MJPEG \u6d41\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#webcamstart","title":"webcamStart()","text":"

      \u4ece\u7f51\u7edc\u6444\u50cf\u5934\u542f\u52a8 MJPEG \u6d41\u3002

      webcamStart(resolutionLevel=0, jpegQuality=20, port=0)\n

      \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf 1-100\uff08\u9ed8\u8ba4\uff1a20\uff09 - port (int): \u7aef\u53e3\u53f7\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\uff09

      \u8fd4\u56de\uff1a \u6d41\u7684 (\u5730\u5740, \u7aef\u53e3) \u5143\u7ec4

      "},{"location":"qsl4a/hardware/webcam/#webcamadjustquality","title":"webcamAdjustQuality()","text":"

      \u8c03\u6574\u6d3b\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u7684\u8d28\u91cf\u3002

      webcamAdjustQuality(resolutionLevel=0, jpegQuality=20)\n

      \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b - jpegQuality (int): JPEG \u8d28\u91cf 1-100

      "},{"location":"qsl4a/hardware/webcam/#webcamstop","title":"webcamStop()","text":"

      \u505c\u6b62\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u3002

      webcamStop()\n
      "},{"location":"qsl4a/hardware/webcam/#_1","title":"\u76f8\u673a\u9884\u89c8\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#camerastartpreview","title":"cameraStartPreview()","text":"

      \u5f00\u59cb\u5e26\u4e8b\u4ef6\u751f\u6210\u7684\u76f8\u673a\u9884\u89c8\u6a21\u5f0f\u3002

      cameraStartPreview(resolutionLevel=0, jpegQuality=20, filepath=None)\n

      \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf\uff08\u9ed8\u8ba4\uff1a20\uff09 - filepath (str, optional): \u4fdd\u5b58\u9884\u89c8\u5e27\u7684\u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      \u6ce8\u610f\uff1a \u751f\u6210\u5e26\u6709\u5e27\u6570\u636e\u7684 'preview' \u4e8b\u4ef6\u3002

      "},{"location":"qsl4a/hardware/webcam/#camerastoppreview","title":"cameraStopPreview()","text":"

      \u505c\u6b62\u76f8\u673a\u9884\u89c8\u3002

      cameraStopPreview()\n
      "},{"location":"qsl4a/hardware/webcam/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\nstream_info = droid.webcamStart(\n    resolutionLevel=0,\n    jpegQuality=30,\n    port=8080\n).result\nprint(f\"Stream available at {stream_info[0]}:{stream_info[1]}\")\n\n# \u6d41\u5f0f\u4f20\u8f93\u65f6\u8c03\u6574\u8d28\u91cf\ntime.sleep(5)\ndroid.webcamAdjustQuality(resolutionLevel=1, jpegQuality=50)\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.webcamStop()\n\n# \u6216\u4f7f\u7528\u9884\u89c8\u6a21\u5f0f\nprint(\"Starting preview...\")\ndroid.cameraStartPreview()\n\n# \u7b49\u5f85\u9884\u89c8\u4e8b\u4ef6\nfor i in range(10):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'preview':\n        print(f\"Got preview frame: {event['data']}\")\n\ndroid.cameraStopPreview()\n
      "},{"location":"qsl4a/media/image/","title":"\u56fe\u50cf\u5904\u7406 API","text":"

      \u538b\u7f29\u548c\u5904\u7406\u56fe\u50cf\u3002

      "},{"location":"qsl4a/media/image/#_1","title":"\u56fe\u50cf\u538b\u7f29","text":""},{"location":"qsl4a/media/image/#imagecompress","title":"imageCompress()","text":"

      \u538b\u7f29\u56fe\u50cf\u6587\u4ef6\u3002

      imageCompress(srcPath, destPath, targetByteSize=0, targetWidth=0, targetHeight=0)\n

      \u53c2\u6570\uff1a - srcPath (str): \u6e90\u56fe\u50cf\u8def\u5f84 - destPath (str): \u8f93\u51fa\u8def\u5f84 - targetByteSize (int): \u76ee\u6807\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff080 = \u65e0\u9650\u5236\uff09 - targetWidth (int): \u76ee\u6807\u5bbd\u5ea6\uff080 = \u539f\u59cb\uff09 - targetHeight (int): \u76ee\u6807\u9ad8\u5ea6\uff080 = \u539f\u59cb\uff09

      \u8fd4\u56de\uff1a \u538b\u7f29\u540e\u7684\u56fe\u50cf\u8def\u5f84

      "},{"location":"qsl4a/media/image/#_2","title":"\u622a\u56fe","text":""},{"location":"qsl4a/media/image/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

      \u622a\u53d6\u5c4f\u5e55\u3002

      imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

      \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

      \u8fd4\u56de\uff1a \u622a\u56fe\u8def\u5f84

      "},{"location":"qsl4a/media/image/#_3","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/image/#videoplay","title":"videoPlay()","text":"

      \u5728\u5168\u5c4f\u6a21\u5f0f\u4e0b\u64ad\u653e\u89c6\u9891\u6587\u4ef6\u3002

      videoPlay(path, wait=True)\n

      \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

      "},{"location":"qsl4a/media/image/#_4","title":"\u6761\u7801\u626b\u63cf","text":""},{"location":"qsl4a/media/image/#scanbarcodefromimage","title":"scanBarcodeFromImage()","text":"

      \u4ece\u56fe\u50cf\u6587\u4ef6\u626b\u63cf\u6761\u7801/\u4e8c\u7ef4\u7801\u3002

      scanBarcodeFromImage(path, compressRatio=0, x=0, y=0, width=0, height=0)\n

      \u53c2\u6570\uff1a - path (str): \u56fe\u50cf\u6587\u4ef6\u8def\u5f84 - compressRatio (int): \u538b\u7f29\u6bd4\uff080 = \u4e0d\u538b\u7f29\uff09 - x, y, width, height (int): \u8981\u626b\u63cf\u7684\u533a\u57df\uff080 = \u5b8c\u6574\u56fe\u50cf\uff09

      \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5185\u5bb9

      "},{"location":"qsl4a/media/image/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n\n# \u538b\u7f29\u56fe\u50cf\ncompressed = droid.imageCompress(\n    \"/sdcard/large_photo.jpg\",\n    \"/sdcard/compressed.jpg\",\n    targetByteSize=102400,  # \u76ee\u6807\u7ea6 100KB\n    targetWidth=1920,\n    targetHeight=1080\n).result\nprint(f\"Saved: {compressed}\")\n\n# \u64ad\u653e\u89c6\u9891\nvideo_path = \"/sdcard/movie.mp4\"\ndroid.videoPlay(video_path, wait=True)\n\n# \u4ece\u56fe\u50cf\u626b\u63cf\u6761\u7801\nresult = droid.scanBarcodeFromImage(\"/sdcard/qr_code.png\").result\nprint(f\"Barcode: {result}\")\n
      "},{"location":"qsl4a/media/mediaplayer/","title":"\u5a92\u4f53\u64ad\u653e\u5668 API","text":"

      \u63a7\u5236\u97f3\u9891\u548c\u89c6\u9891\u64ad\u653e\u3002

      "},{"location":"qsl4a/media/mediaplayer/#_1","title":"\u64ad\u653e\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplay","title":"mediaPlay()","text":"

      \u64ad\u653e\u5a92\u4f53\u6587\u4ef6\u3002

      mediaPlay(url, tag=\"default\", play=True)\n

      \u53c2\u6570\uff1a - url (str): \u5a92\u4f53\u6587\u4ef6\u8def\u5f84\u6216 URL - tag (str): \u64ad\u653e\u5668\u6807\u8bc6\u7b26 - play (bool): \u81ea\u52a8\u5f00\u59cb\u64ad\u653e

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaystart","title":"mediaPlayStart()","text":"

      \u5f00\u59cb\u64ad\u653e\u3002

      mediaPlayStart(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplaypause","title":"mediaPlayPause()","text":"

      \u6682\u505c\u64ad\u653e\u3002

      mediaPlayPause(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplayclose","title":"mediaPlayClose()","text":"

      \u5173\u95ed\u64ad\u653e\u5668\u3002

      mediaPlayClose(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplayseek","title":"mediaPlaySeek()","text":"

      \u8df3\u8f6c\u5230\u4f4d\u7f6e\u3002

      mediaPlaySeek(msec, tag=\"default\")\n

      \u53c2\u6570\uff1a - msec (int): \u4f4d\u7f6e\uff08\u6beb\u79d2\uff09

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaysetlooping","title":"mediaPlaySetLooping()","text":"

      \u8bbe\u7f6e\u5faa\u73af\u6a21\u5f0f\u3002

      mediaPlaySetLooping(enabled, tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#_2","title":"\u64ad\u653e\u5668\u4fe1\u606f","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplayinfo","title":"mediaPlayInfo()","text":"

      \u83b7\u53d6\u64ad\u653e\u4fe1\u606f\u3002

      mediaPlayInfo(tag=\"default\")\n

      \u8fd4\u56de\uff1a \u5305\u542b\u65f6\u957f\u3001\u4f4d\u7f6e\u7b49\u7684\u5b57\u5178

      "},{"location":"qsl4a/media/mediaplayer/#mediaisplaying","title":"mediaIsPlaying()","text":"

      \u68c0\u67e5\u662f\u5426\u6b63\u5728\u64ad\u653e\u3002

      mediaIsPlaying(tag=\"default\")\n

      \u8fd4\u56de\uff1a True/False

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaylist","title":"mediaPlayList()","text":"

      \u5217\u51fa\u6d3b\u52a8\u64ad\u653e\u5668\u3002

      mediaPlayList()\n
      "},{"location":"qsl4a/media/mediaplayer/#_3","title":"\u97f3\u91cf\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#getmediavolume","title":"getMediaVolume()","text":"

      \u83b7\u53d6\u5a92\u4f53\u97f3\u91cf\u3002

      getMediaVolume()\n

      \u8fd4\u56de\uff1a \u97f3\u91cf\u7ea7\u522b\uff080-15\uff09

      "},{"location":"qsl4a/media/mediaplayer/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

      getMaxMediaVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#getringervolume","title":"getRingerVolume()","text":"

      \u83b7\u53d6\u94c3\u58f0\u97f3\u91cf\u3002

      getRingerVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

      getMaxRingerVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#_4","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/mediaplayer/#videoplay","title":"videoPlay()","text":"

      \u5168\u5c4f\u64ad\u653e\u89c6\u9891\u3002

      videoPlay(path, wait=True)\n

      \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210

      "},{"location":"qsl4a/media/mediaplayer/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u64ad\u653e\u97f3\u9891\ndroid.mediaPlay(\"/sdcard/music.mp3\", tag=\"music\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.mediaIsPlaying(\"music\").result:\n    info = droid.mediaPlayInfo(\"music\").result\n    print(f\"Playing: {info}\")\n\n# \u8df3\u8f6c\u5230 30 \u79d2\ndroid.mediaPlaySeek(30000, \"music\")\n\n# \u5173\u95ed\ndroid.mediaPlayClose(\"music\")\n\n# \u64ad\u653e\u89c6\u9891\ndroid.videoPlay(\"/sdcard/movie.mp4\", wait=True)\n
      "},{"location":"qsl4a/special/cipher/","title":"\u5bc6\u7801 API","text":"

      \u7528\u4e8e\u5b89\u5168\u6570\u636e\u5b58\u50a8\u7684\u52a0\u5bc6\u548c\u89e3\u5bc6\u5de5\u5177\u3002

      "},{"location":"qsl4a/special/cipher/#_1","title":"\u521d\u59cb\u5316","text":""},{"location":"qsl4a/special/cipher/#cipherinit","title":"cipherInit()","text":"

      \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u548c\u7b97\u6cd5\u521d\u59cb\u5316\u5bc6\u7801\u5668\u3002

      cipherInit(key, algorithm=\"AES/CBC/PKCS5Padding\", encodingFormat=\"\", initialVector=\"\")\n

      \u53c2\u6570\uff1a - key (str or bytes): \u52a0\u5bc6\u5bc6\u94a5 - algorithm (str): \u5bc6\u7801\u7b97\u6cd5\uff08\u9ed8\u8ba4\uff1a\"AES/CBC/PKCS5Padding\"\uff09 - encodingFormat (str): \u7f16\u7801\u683c\u5f0f - initialVector (str or bytes): \u52a0\u5bc6\u7684\u521d\u59cb\u5411\u91cf

      \u8fd4\u56de\uff1a \u521d\u59cb\u5316\u7ed3\u679c

      \u6ce8\u610f\uff1a \u5fc5\u987b\u5728\u4efb\u4f55\u52a0\u5bc6/\u89e3\u5bc6\u64cd\u4f5c\u4e4b\u524d\u8c03\u7528\u3002

      "},{"location":"qsl4a/special/cipher/#_2","title":"\u52a0\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#encryptstring","title":"encryptString()","text":"

      \u52a0\u5bc6\u5b57\u7b26\u4e32\u3002

      encryptString(plainText)\n

      \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c

      \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/special/cipher/#encryptbytes","title":"encryptBytes()","text":"

      \u52a0\u5bc6\u5b57\u8282\u6570\u636e\u3002

      encryptBytes(data)\n

      \u53c2\u6570\uff1a - data (bytes): \u8981\u52a0\u5bc6\u7684\u6570\u636e

      \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u8282

      "},{"location":"qsl4a/special/cipher/#encryptstringtofile","title":"encryptStringToFile()","text":"

      \u52a0\u5bc6\u5b57\u7b26\u4e32\u5230\u6587\u4ef6\u3002

      encryptStringToFile(plainText, filePath)\n

      \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c - filePath (str): \u8f93\u51fa\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/special/cipher/#encryptbytestofile","title":"encryptBytesToFile()","text":"

      \u52a0\u5bc6\u5b57\u8282\u5230\u6587\u4ef6\u3002

      encryptBytesToFile(data, filePath)\n
      "},{"location":"qsl4a/special/cipher/#_3","title":"\u89e3\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#decryptstring","title":"decryptString()","text":"

      \u89e3\u5bc6\u4e3a\u5b57\u7b26\u4e32\u3002

      decryptString(cipherText)\n

      \u53c2\u6570\uff1a - cipherText (str): \u52a0\u5bc6\u7684\u6587\u672c

      \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/special/cipher/#decryptbytes","title":"decryptBytes()","text":"

      \u89e3\u5bc6\u4e3a\u5b57\u8282\u3002

      decryptBytes(data)\n

      \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u8282

      "},{"location":"qsl4a/special/cipher/#decryptfiletostring","title":"decryptFileToString()","text":"

      \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u7b26\u4e32\u3002

      decryptFileToString(filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryptfiletobytes","title":"decryptFileToBytes()","text":"

      \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u8282\u3002

      decryptFileToBytes(filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryptfile","title":"decryptFile()","text":"

      \u89e3\u5bc6\u6587\u4ef6\u5230\u6587\u4ef6\u3002

      decryptFile(srcPath, destPath)\n
      "},{"location":"qsl4a/special/cipher/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u521d\u59cb\u5316\u5bc6\u7801\u5668\ndroid.cipherInit(\"my_secret_key_1234\")\n\n# \u52a0\u5bc6\u5b57\u7b26\u4e32\nencrypted = droid.encryptString(\"Secret message!\").result\nprint(f\"Encrypted: {encrypted}\")\n\n# \u89e3\u5bc6\u5b57\u7b26\u4e32\ndecrypted = droid.decryptString(encrypted).result\nprint(f\"Decrypted: {decrypted}\")\n\n# \u52a0\u5bc6\u5230\u6587\u4ef6\ndroid.encryptStringToFile(\"My secret data\", \"/sdcard/secret.dat\")\n\n# \u4ece\u6587\u4ef6\u89e3\u5bc6\ndata = droid.decryptFileToString(\"/sdcard/secret.dat\").result\nprint(data)\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u7b97\u6cd5\u548c IV \u521d\u59cb\u5316\ndroid.cipherInit(\n    key=\"my_key\",\n    algorithm=\"AES/CBC/PKCS5Padding\",\n    initialVector=\"0123456789abcdef\"\n)\n
      "},{"location":"qsl4a/special/pgptai/","title":"PGPT AI API","text":"

      \u8bed\u97f3\u8f6c\u6587\u672c\u548c AI \u670d\u52a1\u96c6\u6210\u3002

      "},{"location":"qsl4a/special/pgptai/#_1","title":"\u5148\u51b3\u6761\u4ef6","text":"
      pip install pgptAI\n
      "},{"location":"qsl4a/special/pgptai/#_2","title":"\u8bed\u97f3\u8bc6\u522b","text":""},{"location":"qsl4a/special/pgptai/#speechtotext","title":"speechToText()","text":"

      \u5c06\u8bed\u97f3\u8f6c\u6362\u4e3a\u6587\u672c\u3002

      speechToText(RecordSecond=10, AmrFile=None, Language=None)\n

      \u53c2\u6570\uff1a - RecordSecond (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09 - AmrFile (str, optional): \u73b0\u6709\u97f3\u9891\u6587\u4ef6\u8def\u5f84 - Language (str, optional): \u8bed\u8a00\u4ee3\u7801\uff08'en'\u3001'zh'\uff09

      \u8fd4\u56de\uff1a \u8f6c\u5f55\u7684\u6587\u672c

      "},{"location":"qsl4a/special/pgptai/#_3","title":"\u6587\u672c\u8f6c\u8bed\u97f3","text":""},{"location":"qsl4a/special/pgptai/#texttospeech","title":"textToSpeech()","text":"

      \u5c06\u6587\u672c\u8f6c\u6362\u4e3a\u8bed\u97f3\u5e76\u53ef\u9009\u5730\u64ad\u653e\u3002

      textToSpeech(Text, AutoPlay=True, WavFile=None, VoiceName=None)\n

      \u53c2\u6570\uff1a - Text (str): \u8981\u8f6c\u6362\u4e3a\u8bed\u97f3\u7684\u6587\u672c - AutoPlay (bool): \u81ea\u52a8\u64ad\u653e\u751f\u6210\u7684\u97f3\u9891\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - WavFile (str, optional): \u4fdd\u5b58 WAV \u6587\u4ef6\u7684\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u4e34\u65f6\u6587\u4ef6 - VoiceName (str, optional): \u8981\u4f7f\u7528\u7684\u8bed\u97f3\u540d\u79f0\uff08\u4f8b\u5982 'en-US-JennyNeural'\u3001'zh-CN-XiaoxiaoNeural'\uff09

      \u8fd4\u56de\uff1a \u5305\u542b\u8bed\u97f3\u5408\u6210\u7ed3\u679c\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - text: \u8f93\u5165\u6587\u672c - url: \u4e0b\u8f7d\u97f3\u9891\u6587\u4ef6\u7684 URL - WavFile: \u4fdd\u5b58\u7684 WAV \u6587\u4ef6\u8def\u5f84\uff08\u5982\u679c\u672c\u5730\u4fdd\u5b58\uff09

      "},{"location":"qsl4a/special/pgptai/#_4","title":"\u914d\u7f6e","text":"

      API \u4f7f\u7528\u4ee5\u4e0b\u914d\u7f6e\u6587\u4ef6\u4e2d\u7684\u914d\u7f6e\uff1a/storage/emulated/0/Android/data/org.qpython.qpy/files/apigpt.conf\uff1a

      [speech]\nspeech_key = your_api_key\n

      \u9ed8\u8ba4\u8bed\u97f3\u8bbe\u7f6e\uff1a - \u82f1\u8bed\uff1aen-US-JennyNeural - \u4e2d\u6587\uff1azh-CN-XiaoxiaoNeural

      "},{"location":"qsl4a/special/pgptai/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5f55\u5236\u5e76\u8f6c\u5f55\nprint(\"Recording for 5 seconds...\")\ntext = droid.speechToText(RecordSecond=5, Language='en').result\nprint(f\"You said: {text}\")\n\n# \u8f6c\u5f55\u73b0\u6709\u6587\u4ef6\ntext = droid.speechToText(AmrFile=\"/sdcard/recording.amr\").result\nprint(f\"Transcription: {text}\")\n\n# \u6587\u672c\u8f6c\u8bed\u97f3\ndroid.textToSpeech(\"Hello, this is a test message.\", AutoPlay=True, Language='en')\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u8bed\u97f3\u5e76\u4fdd\u5b58\u5230\u6587\u4ef6\u7684\u6587\u672c\u8f6c\u8bed\u97f3\nresult = droid.textToSpeech(\n    \"Welcome to QPython!\",\n    AutoPlay=False,\n    WavFile=\"/sdcard/welcome.wav\",\n    VoiceName=\"en-US-JennyNeural\"\n).result\nprint(f\"Audio saved to: {result.get('WavFile')}\")\n
      "},{"location":"qsl4a/special/pgptai/#_6","title":"\u7c7b\u4f7f\u7528","text":"
      from androidhelper.pgptai import pgptai\nimport androidhelper\n\ndroid = androidhelper.Android()\nai = pgptai(droid)\n\n# \u4f7f\u7528\u8bed\u97f3\u8bc6\u522b\ntext = ai.speechToText(RecordSecond=10)\n
      "},{"location":"qsl4a/storage/clipboard/","title":"\u526a\u8d34\u677f API","text":"

      \u590d\u5236\u548c\u7c98\u8d34\u6587\u672c\u5230\u7cfb\u7edf\u526a\u8d34\u677f\u3002

      "},{"location":"qsl4a/storage/clipboard/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/clipboard/#setclipboard","title":"setClipboard()","text":"

      \u590d\u5236\u6587\u672c\u5230\u526a\u8d34\u677f\u3002

      setClipboard(text)\n

      \u53c2\u6570\uff1a - text (str): \u8981\u590d\u5236\u7684\u6587\u672c

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/clipboard/#getclipboard","title":"getClipboard()","text":"

      \u4ece\u526a\u8d34\u677f\u83b7\u53d6\u6587\u672c\u3002

      getClipboard()\n

      \u8fd4\u56de\uff1a \u526a\u8d34\u677f\u6587\u672c

      "},{"location":"qsl4a/storage/clipboard/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u590d\u5236\u5230\u526a\u8d34\u677f\ndroid.setClipboard(\"Hello from QPython!\")\n\n# \u4ece\u526a\u8d34\u677f\u7c98\u8d34\ntext = droid.getClipboard().result\nprint(f\"Clipboard: {text}\")\n
      "},{"location":"qsl4a/storage/documentfile/","title":"DocumentFile API","text":"

      \u4f7f\u7528 SAF\uff08\u5b58\u50a8\u8bbf\u95ee\u6846\u67b6\uff09\u8fdb\u884c\u6587\u4ef6\u64cd\u4f5c\uff0c\u652f\u6301 Android 4.4+\u3002

      "},{"location":"qsl4a/storage/documentfile/#_1","title":"\u76ee\u5f55\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilemkdir","title":"documentFileMkdir()","text":"

      \u521b\u5efa\u76ee\u5f55\u3002

      documentFileMkdir(Dir)\n

      \u53c2\u6570\uff1a - Dir (str): \u76ee\u5f55\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/documentfile/#documentfilelistfiles","title":"documentFileListFiles()","text":"

      \u5217\u51fa\u76ee\u5f55\u4e2d\u7684\u6587\u4ef6\u3002

      documentFileListFiles(Folder)\n

      \u8fd4\u56de\uff1a \u6587\u4ef6\u5217\u8868

      "},{"location":"qsl4a/storage/documentfile/#_2","title":"\u6587\u4ef6\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileexists","title":"documentFileExists()","text":"

      \u68c0\u67e5\u6587\u4ef6\u6216\u76ee\u5f55\u662f\u5426\u5b58\u5728\u3002

      documentFileExists(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u6216\u76ee\u5f55\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u5b58\u5728\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/storage/documentfile/#documentfileisfile","title":"documentFileIsFile()","text":"

      \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u6587\u4ef6\u3002

      documentFileIsFile(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u662f\u6587\u4ef6\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u6587\u4ef6\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

      "},{"location":"qsl4a/storage/documentfile/#documentfileisdirectory","title":"documentFileIsDirectory()","text":"

      \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u76ee\u5f55\u3002

      documentFileIsDirectory(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u662f\u76ee\u5f55\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u76ee\u5f55\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

      "},{"location":"qsl4a/storage/documentfile/#documentfiledelete","title":"documentFileDelete()","text":"

      \u5220\u9664\u6587\u4ef6\u6216\u76ee\u5f55\u3002

      documentFileDelete(FileOrTree)\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/documentfile/#documentfilerenameto","title":"documentFileRenameTo()","text":"

      \u91cd\u547d\u540d\u6216\u79fb\u52a8\u6587\u4ef6\u3002

      documentFileRenameTo(Src, Dest)\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/documentfile/#documentfilecopy","title":"documentFileCopy()","text":"

      \u590d\u5236\u6587\u4ef6\u3002

      documentFileCopy(SrcFileOrTree, DestFileOrTree)\n
      "},{"location":"qsl4a/storage/documentfile/#_3","title":"\u6d41\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileinputstream","title":"documentFileInputStream()","text":"

      \u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9\u3002

      documentFileInputStream(srcFile, EncodingFormat=\"\", skip=None, length=None)\n

      \u53c2\u6570\uff1a - srcFile (str): \u6e90\u6587\u4ef6 - EncodingFormat (str): \"UTF-8\"\u3001\"GBK\"\u3001\"Base64\" \u6216\u7a7a\u5b57\u7b26\u4e32\u8868\u793a\u5b57\u8282 - skip (int): \u4ece\u5f00\u5934\u8df3\u8fc7\u7684\u5b57\u8282\u6570 - length (int): \u8bfb\u53d6\u957f\u5ea6

      \u8fd4\u56de\uff1a \u6587\u4ef6\u5185\u5bb9

      "},{"location":"qsl4a/storage/documentfile/#documentfileoutputstream","title":"documentFileOutputStream()","text":"

      \u5199\u5165\u6587\u4ef6\u5185\u5bb9\u3002

      documentFileOutputStream(destFile, src, EncodingFormat=\"\", append=None)\n

      \u53c2\u6570\uff1a - destFile (str): \u76ee\u6807\u6587\u4ef6 - src: \u8981\u5199\u5165\u7684\u6570\u636e - EncodingFormat (str): \u7f16\u7801\u683c\u5f0f - append (bool): \u8ffd\u52a0\u6a21\u5f0f

      "},{"location":"qsl4a/storage/documentfile/#_4","title":"\u6587\u4ef6\u4fe1\u606f","text":""},{"location":"qsl4a/storage/documentfile/#documentfilelength","title":"documentFileLength()","text":"

      \u83b7\u53d6\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\u3002

      documentFileLength(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

      "},{"location":"qsl4a/storage/documentfile/#documentfilelastmodified","title":"documentFileLastModified()","text":"

      \u83b7\u53d6\u6700\u540e\u4fee\u6539\u65f6\u95f4\u3002

      documentFileLastModified(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u65f6\u95f4\u6233\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

      "},{"location":"qsl4a/storage/documentfile/#documentfilegetstat","title":"documentFileGetStat()","text":"

      \u83b7\u53d6\u5168\u9762\u7684\u6587\u4ef6\u7edf\u8ba1\u4fe1\u606f\u3002

      documentFileGetStat(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5305\u542b\u957f\u5ea6\u3001\u6700\u540e\u4fee\u6539\u65f6\u95f4\u548c\u8bfb/\u5199\u6743\u9650\u7684\u5b57\u5178\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

      "},{"location":"qsl4a/storage/documentfile/#uri","title":"URI \u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilegeturi","title":"documentFileGetUri()","text":"

      \u4ece\u8def\u5f84\u83b7\u53d6 URI\u3002

      documentFileGetUri(path, isDirectory=None)\n
      "},{"location":"qsl4a/storage/documentfile/#documentfileshowopen","title":"documentFileShowOpen()","text":"

      \u663e\u793a\u6587\u4ef6\u9009\u62e9\u5668\u3002

      documentFileShowOpen()\n

      \u8fd4\u56de\uff1a \u9009\u62e9\u7684\u6587\u4ef6 URI

      "},{"location":"qsl4a/storage/documentfile/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u76ee\u5f55\ndroid.documentFileMkdir(\"/sdcard/MyFolder\")\n\n# \u5217\u51fa\u6587\u4ef6\nfiles = droid.documentFileListFiles(\"/sdcard\").result\nfor f in files:\n    print(f)\n\n# \u8bfb\u53d6\u6587\u4ef6\ncontent = droid.documentFileInputStream(\n    \"/sdcard/test.txt\",\n    EncodingFormat=\"UTF-8\"\n).result\nprint(content)\n\n# \u5199\u5165\u6587\u4ef6\ndroid.documentFileOutputStream(\n    \"/sdcard/output.txt\",\n    \"Hello World\",\n    EncodingFormat=\"UTF-8\"\n)\n
      "},{"location":"qsl4a/storage/preferences/","title":"\u504f\u597d\u8bbe\u7f6e API","text":"

      \u4f7f\u7528 Android SharedPreferences \u5b58\u50a8\u548c\u68c0\u7d22\u6570\u636e\u3002

      "},{"location":"qsl4a/storage/preferences/#_1","title":"\u504f\u597d\u8bbe\u7f6e\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/preferences/#prefgetvalue","title":"prefGetValue()","text":"

      \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u8bfb\u53d6\u503c\u3002

      prefGetValue(key, filename=None)\n

      \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c\uff08\u4efb\u610f\u7c7b\u578b\uff09

      "},{"location":"qsl4a/storage/preferences/#prefputvalue","title":"prefPutValue()","text":"

      \u5199\u5165\u503c\u5230\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u3002

      prefPutValue(key, value, filename=None)\n

      \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - value (object): \u8981\u5b58\u50a8\u7684\u503c - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      "},{"location":"qsl4a/storage/preferences/#prefgetall","title":"prefGetAll()","text":"

      \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\u503c\u3002

      prefGetAll(filename=None)\n

      \u53c2\u6570\uff1a - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      \u8fd4\u56de\uff1a \u6240\u6709\u504f\u597d\u7684\u6620\u5c04

      "},{"location":"qsl4a/storage/preferences/#prefremovevalue","title":"prefRemoveValue()","text":"

      \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u4e2d\u79fb\u9664\u503c\u3002

      prefRemoveValue(key, filename=None)\n

      \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      "},{"location":"qsl4a/storage/preferences/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b58\u50a8\u503c\ndroid.prefPutValue(\"username\", \"alice\")\ndroid.prefPutValue(\"score\", 100)\ndroid.prefPutValue(\"enabled\", True)\n\n# \u8bfb\u53d6\u7279\u5b9a\u503c\nusername = droid.prefGetValue(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\nall_prefs = droid.prefGetAll().result\nprint(f\"All prefs: {all_prefs}\")\n\n# \u79fb\u9664\u503c\ndroid.prefRemoveValue(\"score\")\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u6587\u4ef6\u540d\ndroid.prefPutValue(\"token\", \"abc123\", filename=\"auth.prefs\")\ntoken = droid.prefGetValue(\"token\", filename=\"auth.prefs\").result\n
      "},{"location":"qsl4a/system/activityresult/","title":"Activity Result API","text":"

      \u4e3a\u901a\u8fc7 startActivityForResult \u542f\u52a8\u7684\u811a\u672c\u8bbe\u7f6e activity \u7ed3\u679c\u3002

      "},{"location":"qsl4a/system/activityresult/#_1","title":"\u7ed3\u679c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/activityresult/#setresultboolean","title":"setResultBoolean()","text":"

      \u8bbe\u7f6e\u5e03\u5c14\u7ed3\u679c\u3002

      setResultBoolean(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (bool): \u5e03\u5c14\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultbyte","title":"setResultByte()","text":"

      \u8bbe\u7f6e\u5b57\u8282\u7ed3\u679c\u3002

      setResultByte(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u5b57\u8282\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultshort","title":"setResultShort()","text":"

      \u8bbe\u7f6e\u77ed\u6574\u6570\u7ed3\u679c\u3002

      setResultShort(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u77ed\u6574\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultchar","title":"setResultChar()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u7ed3\u679c\u3002

      setResultChar(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultinteger","title":"setResultInteger()","text":"

      \u8bbe\u7f6e\u6574\u6570\u7ed3\u679c\u3002

      setResultInteger(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u6574\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultlong","title":"setResultLong()","text":"

      \u8bbe\u7f6e\u957f\u6574\u6570\u7ed3\u679c\u3002

      setResultLong(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u957f\u6574\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultfloat","title":"setResultFloat()","text":"

      \u8bbe\u7f6e\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

      setResultFloat(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u6d6e\u70b9\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultdouble","title":"setResultDouble()","text":"

      \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

      setResultDouble(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultstring","title":"setResultString()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u4e32\u7ed3\u679c\u3002

      setResultString(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u4e32\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultbooleanarray","title":"setResultBooleanArray()","text":"

      \u8bbe\u7f6e\u5e03\u5c14\u6570\u7ec4\u7ed3\u679c\u3002

      setResultBooleanArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5e03\u5c14\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultbytearray","title":"setResultByteArray()","text":"

      \u8bbe\u7f6e\u5b57\u8282\u6570\u7ec4\u7ed3\u679c\u3002

      setResultByteArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u8282\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultshortarray","title":"setResultShortArray()","text":"

      \u8bbe\u7f6e\u77ed\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultShortArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u77ed\u6574\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultchararray","title":"setResultCharArray()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u6570\u7ec4\u7ed3\u679c\u3002

      setResultCharArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultintegerarray","title":"setResultIntegerArray()","text":"

      \u8bbe\u7f6e\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultIntegerArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6574\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultlongarray","title":"setResultLongArray()","text":"

      \u8bbe\u7f6e\u957f\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultLongArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u957f\u6574\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultfloatarray","title":"setResultFloatArray()","text":"

      \u8bbe\u7f6e\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultFloatArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6d6e\u70b9\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultdoublearray","title":"setResultDoubleArray()","text":"

      \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultDoubleArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultstringarray","title":"setResultStringArray()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u4e32\u6570\u7ec4\u7ed3\u679c\u3002

      setResultStringArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u4e32\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultserializable","title":"setResultSerializable()","text":"

      \u8bbe\u7f6e\u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u3002

      setResultSerializable(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue: \u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c activity \u540e\uff0c\u8bbe\u7f6e\u7ed3\u679c\n# \u793a\u4f8b\uff1a\u8fd4\u56de\u6210\u529f\u53ca\u6570\u636e\ndroid.setResultInteger(0, 200)  # RESULT_OK\ndroid.setResultString(0, \"Operation completed successfully\")\n\n# \u8fd4\u56de\u6570\u7ec4\u7ed3\u679c\ndroid.setResultIntegerArray(0, [1, 2, 3, 4, 5])\n
      "},{"location":"qsl4a/system/application/","title":"\u5e94\u7528\u7ba1\u7406","text":"

      \u7ba1\u7406\u5e94\u7528\u7a0b\u5e8f\u3001\u542f\u52a8\u5e94\u7528\u548c\u67e5\u8be2\u7cfb\u7edf\u4fe1\u606f\u3002

      "},{"location":"qsl4a/system/application/#_2","title":"\u5e94\u7528\u7a0b\u5e8f\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getapplicationinfo","title":"getApplicationInfo()","text":"

      \u83b7\u53d6\u5e94\u7528\u4fe1\u606f\u3002

      getApplicationInfo(packageName=None)\n

      \u53c2\u6570\uff1a - packageName (str): \u5305\u540d\uff08None = \u5f53\u524d\u5e94\u7528\uff09

      \u8fd4\u56de\uff1a \u5e94\u7528\u4fe1\u606f\u5b57\u5178

      "},{"location":"qsl4a/system/application/#getinstalledpackages","title":"getInstalledPackages()","text":"

      \u83b7\u53d6\u5df2\u5b89\u88c5\u5305\u5217\u8868\u3002

      getInstalledPackages(flag=4)\n

      \u53c2\u6570\uff1a - flag (int): \u5305\u6807\u5fd7\u8fc7\u6ee4\u5668\uff08\u9ed8\u8ba4\uff1a4\uff09

      \u8fd4\u56de\uff1a \u5df2\u5b89\u88c5\u5305\u5217\u8868

      "},{"location":"qsl4a/system/application/#getrunningpackages","title":"getRunningPackages()","text":"

      \u5217\u51fa\u6b63\u5728\u8fd0\u884c\u7684\u5305\u3002

      getRunningPackages()\n

      \u8fd4\u56de\uff1a \u5305\u540d\u5217\u8868

      "},{"location":"qsl4a/system/application/#getlaunchablepackages","title":"getLaunchablePackages()","text":"

      \u83b7\u53d6\u53ef\u542f\u52a8\u5305\u5217\u8868\u3002

      getLaunchablePackages(needClassName=False)\n

      \u53c2\u6570\uff1a - needClassName (bool): \u5305\u542b\u4e3b activity \u7c7b\u540d\uff08\u9ed8\u8ba4\uff1aFalse\uff09

      \u8fd4\u56de\uff1a \u53ef\u542f\u52a8\u5305\u540d\u5217\u8868\u6216\u5305\u542b\u7c7b\u540d\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#_3","title":"\u5e94\u7528\u63a7\u5236","text":""},{"location":"qsl4a/system/application/#launch","title":"launch()","text":"

      \u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u3002

      launch(classname=None, packagename=None, wait=True)\n

      \u53c2\u6570\uff1a - classname (str): \u4e3b activity \u7c7b\u540d - packagename (str): \u5305\u540d - wait (bool): \u7b49\u5f85\u542f\u52a8\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

      \u8fd4\u56de\uff1a \u542f\u52a8\u7ed3\u679c

      "},{"location":"qsl4a/system/application/#forcestoppackage","title":"forceStopPackage()","text":"

      \u5f3a\u5236\u505c\u6b62\u5e94\u7528\u7a0b\u5e8f\u3002

      forceStopPackage(packageName)\n

      \u53c2\u6570\uff1a - packageName (str): \u8981\u505c\u6b62\u7684\u5305\u540d

      "},{"location":"qsl4a/system/application/#_4","title":"\u7248\u672c\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getpackageversion","title":"getPackageVersion()","text":"

      \u83b7\u53d6\u5e94\u7528\u7248\u672c\u540d\u79f0\u3002

      getPackageVersion(packageName)\n

      \u8fd4\u56de\uff1a \u7248\u672c\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"3.2.1\"\uff09

      "},{"location":"qsl4a/system/application/#getpackageversioncode","title":"getPackageVersionCode()","text":"

      \u83b7\u53d6\u5e94\u7528\u7248\u672c\u4ee3\u7801\u3002

      getPackageVersionCode(packageName)\n

      \u8fd4\u56de\uff1a \u7248\u672c\u4ee3\u7801\u6574\u6570

      "},{"location":"qsl4a/system/application/#getconstants","title":"getConstants()","text":"

      \u83b7\u53d6\u7c7b\u5e38\u91cf\u3002

      getConstants(classname)\n

      \u53c2\u6570\uff1a - classname (str): \u5b8c\u6574\u7c7b\u540d

      \u8fd4\u56de\uff1a \u5e38\u91cf\u540d\u548c\u503c\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#_5","title":"\u7cfb\u7edf\u529f\u80fd","text":""},{"location":"qsl4a/system/application/#backgroundprotect","title":"backgroundProtect()","text":"

      \u542f\u7528\u6216\u7981\u7528\u5e94\u7528\u7684\u540e\u53f0\u4fdd\u62a4\u3002

      backgroundProtect(enabled=True)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\u4fdd\u62a4\uff0cFalse \u7981\u7528

      "},{"location":"qsl4a/system/application/#createscriptshortcut","title":"createScriptShortCut()","text":"

      \u4e3a\u811a\u672c\u521b\u5efa\u4e3b\u5c4f\u5e55\u5feb\u6377\u65b9\u5f0f\u3002

      createScriptShortCut(scriptPath, label=None, iconPath=None, scriptArg=None)\n

      \u53c2\u6570\uff1a - scriptPath (str): Python \u811a\u672c\u8def\u5f84 - label (str, optional): \u5feb\u6377\u65b9\u5f0f\u6807\u7b7e - iconPath (str, optional): \u56fe\u6807\u56fe\u50cf\u8def\u5f84 - scriptArg (str, optional): \u4f20\u9012\u7ed9\u811a\u672c\u7684\u53c2\u6570

      "},{"location":"qsl4a/system/application/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getandroidid","title":"getAndroidID()","text":"

      \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

      getAndroidID()\n

      \u8fd4\u56de\uff1a \u552f\u4e00\u7684 Android \u8bbe\u5907 ID \u5b57\u7b26\u4e32

      "},{"location":"qsl4a/system/application/#getsysinfo","title":"getSysInfo()","text":"

      \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\u3002

      getSysInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#getlocale","title":"getLocale()","text":"

      \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u3002

      getLocale()\n

      \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

      "},{"location":"qsl4a/system/application/#getharmonyosinformation","title":"getHarmonyOsInformation()","text":"

      \u5982\u679c\u5728 HarmonyOS \u4e0a\u8fd0\u884c\uff0c\u83b7\u53d6 HarmonyOS \u4fe1\u606f\u3002

      getHarmonyOsInformation()\n

      \u8fd4\u56de\uff1a HarmonyOS \u7248\u672c\u4fe1\u606f\u6216 None

      "},{"location":"qsl4a/system/application/#isexternalstoragemanager","title":"isExternalStorageManager()","text":"

      \u68c0\u67e5\u5e94\u7528\u662f\u5426\u6709\u5916\u90e8\u5b58\u50a8\u7ba1\u7406\u5668\u6743\u9650\u3002

      isExternalStorageManager()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6709\u6743\u9650\u5219\u4e3a True

      "},{"location":"qsl4a/system/application/#_7","title":"\u5185\u5b58\u548c\u663e\u793a","text":""},{"location":"qsl4a/system/application/#getmemoryinfo","title":"getMemoryInfo()","text":"

      \u83b7\u53d6\u5185\u5b58\u4fe1\u606f\u3002

      getMemoryInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#getscreeninfo","title":"getScreenInfo()","text":"

      \u83b7\u53d6\u5c4f\u5e55\u4fe1\u606f\u3002

      getScreenInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#_8","title":"\u6743\u9650","text":""},{"location":"qsl4a/system/application/#checkpermissions","title":"checkPermissions()","text":"

      \u68c0\u67e5\u5f53\u524d\u5e94\u7528\u6743\u9650\u3002

      checkPermissions()\n

      \u8fd4\u56de\uff1a \u6743\u9650\u53ca\u5176\u72b6\u6001\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#requestpermissions","title":"requestPermissions()","text":"

      \u5411\u7528\u6237\u8bf7\u6c42\u6743\u9650\u3002

      requestPermissions(permissions=None)\n

      \u53c2\u6570\uff1a - permissions (list, optional): \u8981\u8bf7\u6c42\u7684\u6743\u9650\u5217\u8868\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8bf7\u6c42\u6240\u6709\u9700\u8981\u7684\u6743\u9650\u3002

      \u8fd4\u56de\uff1a \u6743\u9650\u8bf7\u6c42\u7ed3\u679c

      "},{"location":"qsl4a/system/application/#_9","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/system/application/#showscreenlock","title":"showScreenLock()","text":"

      \u663e\u793a\u5c4f\u5e55\u9501\u5b9a\uff08PIN/\u56fe\u6848/\u5bc6\u7801\u8f93\u5165\uff09\u3002

      showScreenLock()\n
      "},{"location":"qsl4a/system/application/#_10","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\ninfo = droid.getSysInfo().result\nprint(f\"System: {info}\")\n\n# \u83b7\u53d6\u5e94\u7528\u7248\u672c\nversion = droid.getPackageVersion(\"org.qpython.qpy\").result\nprint(f\"QPython version: {version}\")\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u5e94\u7528\napps = droid.getInstalledPackages().result\nprint(f\"Installed apps: {len(apps)}\")\n\n# \u542f\u52a8\u5e94\u7528\ndroid.launch(packagename=\"com.android.settings\")\n\n# \u68c0\u67e5\u6743\u9650\nperms = droid.checkPermissions().result\nprint(f\"Permissions: {perms}\")\n\n# \u8bf7\u6c42\u5b58\u50a8\u6743\u9650\ndroid.requestPermissions([\"android.permission.READ_EXTERNAL_STORAGE\"])\n\n# \u521b\u5efa\u5feb\u6377\u65b9\u5f0f\ndroid.createScriptShortCut(\n    \"/sdcard/my_script.py\",\n    label=\"My Script\",\n    iconPath=\"/sdcard/icon.png\"\n)\n
      "},{"location":"qsl4a/system/battery/","title":"\u7535\u6c60 API","text":"

      \u76d1\u63a7\u8bbe\u5907\u7535\u6c60\u72b6\u6001\u548c\u5065\u5eb7\u72b6\u51b5\u3002

      "},{"location":"qsl4a/system/battery/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/battery/#readbatterydata","title":"readBatteryData()","text":"

      \u83b7\u53d6\u5b8c\u6574\u7684\u7535\u6c60\u4fe1\u606f\u3002

      readBatteryData()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7535\u6c60\u6570\u636e\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/battery/#batterystartmonitoring","title":"batteryStartMonitoring()","text":"

      \u5f00\u59cb\u7535\u6c60\u76d1\u63a7\u3002

      batteryStartMonitoring()\n
      "},{"location":"qsl4a/system/battery/#batterystopmonitoring","title":"batteryStopMonitoring()","text":"

      \u505c\u6b62\u7535\u6c60\u76d1\u63a7\u3002

      batteryStopMonitoring()\n
      "},{"location":"qsl4a/system/battery/#batterygetlevel","title":"batteryGetLevel()","text":"

      \u83b7\u53d6\u7535\u6c60\u767e\u5206\u6bd4\u3002

      batteryGetLevel()\n

      \u8fd4\u56de\uff1a \u6574\u6570\uff080-100\uff09

      "},{"location":"qsl4a/system/battery/#batterygetstatus","title":"batteryGetStatus()","text":"

      \u83b7\u53d6\u5145\u7535\u72b6\u6001\u3002

      batteryGetStatus()\n

      \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u5145\u7535\u4e2d - 3: \u653e\u7535\u4e2d - 4: \u672a\u5145\u7535 - 5: \u5df2\u5145\u6ee1

      "},{"location":"qsl4a/system/battery/#batterygetplugtype","title":"batteryGetPlugType()","text":"

      \u83b7\u53d6\u7535\u6e90\u7c7b\u578b\u3002

      batteryGetPlugType()\n

      \u8fd4\u56de\uff1a - -1: \u672a\u77e5 - 0: \u672a\u63d2\u7535 - 1: AC \u5145\u7535\u5668 - 2: USB \u7aef\u53e3

      "},{"location":"qsl4a/system/battery/#batterygethealth","title":"batteryGetHealth()","text":"

      \u83b7\u53d6\u7535\u6c60\u5065\u5eb7\u72b6\u51b5\u3002

      batteryGetHealth()\n

      \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u826f\u597d - 3: \u8fc7\u70ed - 4: \u635f\u574f - 5: \u8fc7\u538b - 6: \u672a\u6307\u5b9a\u7684\u6545\u969c

      "},{"location":"qsl4a/system/battery/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\nlevel = droid.batteryGetLevel().result\nprint(f\"Battery: {level}%\")\n
      "},{"location":"qsl4a/system/qpyinterface/","title":"QPython \u63a5\u53e3 API","text":"

      \u4ece\u5176\u4ed6\u5e94\u7528\u6267\u884c QPython \u811a\u672c\u548c\u7ba1\u7406\u5171\u4eab\u53d8\u91cf\u3002

      "},{"location":"qsl4a/system/qpyinterface/#_1","title":"\u811a\u672c\u6267\u884c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/qpyinterface/#executeqpy","title":"executeQPy()","text":"

      \u6267\u884c QPython \u811a\u672c\u3002

      executeQPy(path=\"\", arg=None)\n

      \u53c2\u6570\uff1a - path (str): \u811a\u672c\u6587\u4ef6\u8def\u5f84 - arg (str, optional): \u547d\u4ee4\u884c\u53c2\u6570

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#executeqpyassrv","title":"executeQPyAsSrv()","text":"

      \u4f5c\u4e3a\u670d\u52a1\u6267\u884c QPython \u811a\u672c\u3002

      executeQPyAsSrv(path=None)\n

      \u53c2\u6570\uff1a - path (str, optional): \u811a\u672c\u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#executeqpycode","title":"executeQPyCode()","text":"

      \u76f4\u63a5\u6267\u884c Python \u4ee3\u7801\u3002

      executeQPyCode(code=None)\n

      \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#executeqpycodeassrv","title":"executeQPyCodeAsSrv()","text":"

      \u4f5c\u4e3a\u670d\u52a1\u6267\u884c Python \u4ee3\u7801\u3002

      executeQPyCodeAsSrv(code=None)\n

      \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#_2","title":"\u5171\u4eab\u53d8\u91cf","text":"

      \u5171\u4eab\u53d8\u91cf\u5141\u8bb8 QPython \u4e0e\u5176\u4ed6\u5e94\u7528\u4e4b\u95f4\u8fdb\u884c\u901a\u4fe1\u3002

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableset","title":"sharedVariableSet()","text":"

      \u8bbe\u7f6e Java \u5171\u4eab\u53d8\u91cf\u3002

      sharedVariableSet(key, value)\n

      \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d - value (str): \u53d8\u91cf\u503c

      \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableget","title":"sharedVariableGet()","text":"

      \u83b7\u53d6 Java \u5171\u4eab\u53d8\u91cf\u3002

      sharedVariableGet(key)\n

      \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d

      \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableremove","title":"sharedVariableRemove()","text":"

      \u79fb\u9664 Java \u5171\u4eab\u53d8\u91cf\u3002

      sharedVariableRemove(key)\n

      \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u53d8\u91cf\u540d

      \u8fd4\u56de\uff1a \u88ab\u79fb\u9664\u7684\u503c

      "},{"location":"qsl4a/system/qpyinterface/#getlastlog","title":"getLastLog()","text":"

      \u83b7\u53d6 QPython \u7684\u6700\u540e\u65e5\u5fd7\u8f93\u51fa\u3002

      getLastLog()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u65e5\u5fd7\u5185\u5bb9

      "},{"location":"qsl4a/system/qpyinterface/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c\u811a\u672c\ndroid.executeQPy(\"/sdcard/my_script.py\", arg=\"test\")\n\n# \u76f4\u63a5\u6267\u884c\u4ee3\u7801\ncode = \"print('Hello from QPython!')\"\ndroid.executeQPyCode(code)\n\n# \u4f7f\u7528\u5171\u4eab\u53d8\u91cf\ndroid.sharedVariableSet(\"username\", \"alice\")\nusername = droid.sharedVariableGet(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u79fb\u9664\u53d8\u91cf\ndroid.sharedVariableRemove(\"username\")\n\n# \u83b7\u53d6\u6700\u8fd1\u65e5\u5fd7\nlog = droid.getLastLog().result\nprint(f\"Log: {log}\")\n
      "},{"location":"qsl4a/system/sensors/","title":"\u4f20\u611f\u5668 API","text":"

      \u8bbf\u95ee\u8bbe\u5907\u4f20\u611f\u5668\uff0c\u5305\u62ec\u52a0\u901f\u5ea6\u8ba1\u3001\u9640\u87ba\u4eea\u3001\u78c1\u529b\u8ba1\u7b49\u3002

      "},{"location":"qsl4a/system/sensors/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/sensors/#startsensingtimed","title":"startSensingTimed()","text":"

      \u5f00\u59cb\u4f20\u611f\u5668\u76d1\u63a7\u5e76\u8bbe\u7f6e\u65f6\u95f4\u95f4\u9694\u3002

      startSensingTimed(sensorNumber, delayTime)\n

      \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID\uff08\u901a\u5e38\u4e3a 1-3\uff09 - delayTime (int): \u8bfb\u53d6\u4e4b\u95f4\u7684\u5ef6\u8fdf\uff08\u6beb\u79d2\uff09

      "},{"location":"qsl4a/system/sensors/#startsensingthreshold","title":"startSensingThreshold()","text":"

      \u5f00\u59cb\u5e26\u9608\u503c\u89e6\u53d1\u7684\u4f20\u611f\u5668\u76d1\u63a7\u3002

      startSensingThreshold(sensorNumber, threshold, axis)\n

      \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID - threshold (float): \u89e6\u53d1\u9608\u503c - axis (int): \u8981\u76d1\u63a7\u7684\u8f74\uff080=X\uff0c1=Y\uff0c2=Z\uff09

      "},{"location":"qsl4a/system/sensors/#stopsensing","title":"stopSensing()","text":"

      \u505c\u6b62\u6240\u6709\u4f20\u611f\u5668\u76d1\u63a7\u3002

      stopSensing()\n
      "},{"location":"qsl4a/system/sensors/#readsensors","title":"readSensors()","text":"

      \u8bfb\u53d6\u5f53\u524d\u4f20\u611f\u5668\u6570\u636e\u3002

      readSensors()\n

      \u8fd4\u56de\uff1a \u4f20\u611f\u5668\u6570\u636e\u5b57\u5178

      "},{"location":"qsl4a/system/sensors/#sensorsreadaccelerometer","title":"sensorsReadAccelerometer()","text":"

      \u8bfb\u53d6\u52a0\u901f\u5ea6\u8ba1\u503c\u3002

      sensorsReadAccelerometer()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d m/s\u00b2

      "},{"location":"qsl4a/system/sensors/#sensorsreadgyroscope","title":"sensorsReadGyroscope()","text":"

      \u8bfb\u53d6\u9640\u87ba\u4eea\u503c\u3002

      sensorsReadGyroscope()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d rad/s

      "},{"location":"qsl4a/system/sensors/#sensorsreadmagnetometer","title":"sensorsReadMagnetometer()","text":"

      \u8bfb\u53d6\u78c1\u573a\u503c\u3002

      sensorsReadMagnetometer()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d \u03bcT

      "},{"location":"qsl4a/system/sensors/#sensorsreadorientation","title":"sensorsReadOrientation()","text":"

      \u8bfb\u53d6\u8bbe\u5907\u65b9\u5411\u3002

      sensorsReadOrientation()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [azimuth, pitch, roll]\uff0c\u5355\u4f4d\u5ea6

      "},{"location":"qsl4a/system/sensors/#sensorsgetlight","title":"sensorsGetLight()","text":"

      \u8bfb\u53d6\u5149\u4f20\u611f\u5668\u503c\u3002

      sensorsGetLight()\n

      \u8fd4\u56de\uff1a \u5149\u7ea7\u522b\uff08lux\uff09

      "},{"location":"qsl4a/system/sensors/#sensorsgetstepcounter","title":"sensorsGetStepCounter()","text":"

      \u8bfb\u53d6\u6b65\u8ba1\u6570\u5668\u3002

      sensorsGetStepCounter()\n

      \u8fd4\u56de\uff1a \u6b65\u6570

      "},{"location":"qsl4a/system/sensors/#sensorsgetaccuracy","title":"sensorsGetAccuracy()","text":"

      \u83b7\u53d6\u5f53\u524d\u4f20\u611f\u5668\u7cbe\u5ea6\u3002

      sensorsGetAccuracy()\n

      \u8fd4\u56de\uff1a \u7cbe\u5ea6\u503c\uff080-3\uff1aUNRELIABLE\u3001ACCURACY_LOW\u3001ACCURACY_MEDIUM\u3001ACCURACY_HIGH\uff09

      "},{"location":"qsl4a/system/sensors/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u8bfb\u53d6\u4f20\u611f\u5668 10 \u6b21\nfor i in range(10):\n    accel = droid.sensorsReadAccelerometer().result\n    print(f\"Accel: X={accel[0]:.2f}, Y={accel[1]:.2f}, Z={accel[2]:.2f}\")\n    time.sleep(0.5)\n\ndroid.stopSensing()\n
      "},{"location":"qsl4a/system/settings/","title":"\u8bbe\u7f6e API","text":"

      \u63a7\u5236\u7cfb\u7edf\u8bbe\u7f6e\uff0c\u5305\u62ec\u5c4f\u5e55\u3001\u58f0\u97f3\u548c\u7f51\u7edc\u8bbe\u7f6e\u3002

      "},{"location":"qsl4a/system/settings/#_1","title":"\u5c4f\u5e55\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#setscreentimeout","title":"setScreenTimeout()","text":"

      \u8bbe\u7f6e\u5c4f\u5e55\u8d85\u65f6\u503c\u3002

      setScreenTimeout(value)\n

      \u53c2\u6570\uff1a - value (int): \u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

      \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u8d85\u65f6\u503c

      "},{"location":"qsl4a/system/settings/#getscreentimeout","title":"getScreenTimeout()","text":"

      \u83b7\u53d6\u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u3002

      getScreenTimeout()\n

      \u8fd4\u56de\uff1a \u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

      "},{"location":"qsl4a/system/settings/#getscreenbrightness","title":"getScreenBrightness()","text":"

      \u83b7\u53d6\u5c4f\u5e55\u4eae\u5ea6\u503c\u3002

      getScreenBrightness()\n

      \u8fd4\u56de\uff1a \u4eae\u5ea6\u503c\uff080-255\uff09

      "},{"location":"qsl4a/system/settings/#setscreenbrightness","title":"setScreenBrightness()","text":"

      \u8bbe\u7f6e\u5c4f\u5e55\u4eae\u5ea6\u3002

      setScreenBrightness(value=None)\n

      \u53c2\u6570\uff1a - value (int, optional): \u4eae\u5ea6\u503c\uff080-255\uff09\uff0c\u6216 None \u8868\u793a\u81ea\u52a8

      \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u4eae\u5ea6\u503c

      "},{"location":"qsl4a/system/settings/#checkscreenon","title":"checkScreenOn()","text":"

      \u68c0\u67e5\u5c4f\u5e55\u662f\u5426\u4eae\u7740\u3002

      checkScreenOn()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u5c4f\u5e55\u4eae\u7740\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/system/settings/#_2","title":"\u98de\u884c\u6a21\u5f0f","text":""},{"location":"qsl4a/system/settings/#checkairplanemode","title":"checkAirplaneMode()","text":"

      \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\u662f\u5426\u542f\u7528\u3002

      checkAirplaneMode()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u98de\u884c\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

      "},{"location":"qsl4a/system/settings/#_3","title":"\u94c3\u58f0\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#checkringersilentmode","title":"checkRingerSilentMode()","text":"

      \u68c0\u67e5\u94c3\u58f0\u662f\u5426\u5904\u4e8e\u9759\u97f3\u6a21\u5f0f\u3002

      checkRingerSilentMode()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u9759\u97f3\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

      "},{"location":"qsl4a/system/settings/#toggleringersilentmode","title":"toggleRingerSilentMode()","text":"

      \u5207\u6362\u94c3\u58f0\u9759\u97f3\u6a21\u5f0f\u3002

      toggleRingerSilentMode(enabled=None)\n

      \u53c2\u6570\uff1a - enabled (bool, optional): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

      \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

      "},{"location":"qsl4a/system/settings/#togglevibratemode","title":"toggleVibrateMode()","text":"

      \u5207\u6362\u632f\u52a8\u6a21\u5f0f\u3002

      toggleVibrateMode(enabled=None, ringer=None)\n

      \u53c2\u6570\uff1a - enabled (bool, optional): \u5207\u6362\u632f\u52a8\u5f00/\u5173 - ringer (bool, optional): \u5e94\u7528\u4e8e\u94c3\u58f0\u6a21\u5f0f

      \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

      "},{"location":"qsl4a/system/settings/#getvibratemode","title":"getVibrateMode()","text":"

      \u83b7\u53d6\u632f\u52a8\u6a21\u5f0f\u8bbe\u7f6e\u3002

      getVibrateMode(ringer=None)\n

      \u53c2\u6570\uff1a - ringer (bool, optional): \u68c0\u67e5\u94c3\u58f0\u632f\u52a8\u6a21\u5f0f

      \u8fd4\u56de\uff1a \u5982\u679c\u632f\u52a8\u5df2\u542f\u7528\u5219\u4e3a True

      "},{"location":"qsl4a/system/settings/#_4","title":"\u97f3\u91cf\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#getringervolume","title":"getRingerVolume()","text":"

      \u83b7\u53d6\u5f53\u524d\u94c3\u58f0\u97f3\u91cf\u3002

      getRingerVolume()\n

      \u8fd4\u56de\uff1a \u94c3\u58f0\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-7\uff09

      "},{"location":"qsl4a/system/settings/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

      getMaxRingerVolume()\n

      \u8fd4\u56de\uff1a \u6700\u5927\u94c3\u58f0\u97f3\u91cf

      "},{"location":"qsl4a/system/settings/#setringervolume","title":"setRingerVolume()","text":"

      \u8bbe\u7f6e\u94c3\u58f0\u97f3\u91cf\u3002

      setRingerVolume(volume)\n

      \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

      "},{"location":"qsl4a/system/settings/#getmediavolume","title":"getMediaVolume()","text":"

      \u83b7\u53d6\u5f53\u524d\u5a92\u4f53\u97f3\u91cf\u3002

      getMediaVolume()\n

      \u8fd4\u56de\uff1a \u5a92\u4f53\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-15\uff09

      "},{"location":"qsl4a/system/settings/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

      getMaxMediaVolume()\n

      \u8fd4\u56de\uff1a \u6700\u5927\u5a92\u4f53\u97f3\u91cf

      "},{"location":"qsl4a/system/settings/#setmediavolume","title":"setMediaVolume()","text":"

      \u8bbe\u7f6e\u5a92\u4f53\u97f3\u91cf\u3002

      setMediaVolume(volume)\n

      \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

      "},{"location":"qsl4a/system/settings/#_5","title":"\u7cfb\u7edf\u4fe1\u606f","text":""},{"location":"qsl4a/system/settings/#elapsedrealtimenanos","title":"elapsedRealtimeNanos()","text":"

      \u83b7\u53d6\u81ea\u7cfb\u7edf\u542f\u52a8\u4ee5\u6765\u7684\u7eb3\u79d2\u6570\u3002

      elapsedRealtimeNanos()\n

      \u8fd4\u56de\uff1a \u7eb3\u79d2\u6570\uff08\u53ef\u7528\u4e8e\u8ba1\u65f6\uff09

      "},{"location":"qsl4a/system/settings/#gettrafficstats","title":"getTrafficStats()","text":"

      \u83b7\u53d6\u7f51\u7edc\u6d41\u91cf\u7edf\u8ba1\u3002

      getTrafficStats(flags=7)\n

      \u53c2\u6570\uff1a - flags (int): \u8981\u68c0\u7d22\u7684\u7edf\u8ba1\uff08\u9ed8\u8ba4\uff1a7 = \u5168\u90e8\uff09

      \u8fd4\u56de\uff1a \u5305\u542b\u53d1\u9001/\u63a5\u6536\u5b57\u8282\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/settings/#getapptxbytes","title":"getAppTxBytes()","text":"

      \u83b7\u53d6 QPython \u5e94\u7528\u7684\u53d1\u9001\u5b57\u8282\u3002

      getAppTxBytes(packageName)\n

      \u53c2\u6570\uff1a - packageName (str): \u5305\u540d

      \u8fd4\u56de\uff1a \u5305\u542b tx/rx \u5b57\u8282\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/settings/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5c4f\u5e55\u8bbe\u7f6e\ncurrent_timeout = droid.getScreenTimeout().result\nprint(f\"Current timeout: {current_timeout}s\")\ndroid.setScreenTimeout(30)\n\n# \u68c0\u67e5\u5c4f\u5e55\nif droid.checkScreenOn().result:\n    print(\"Screen is on\")\n\n# \u97f3\u91cf\u63a7\u5236\nmedia_vol = droid.getMediaVolume().result\nprint(f\"Media volume: {media_vol}\")\ndroid.setMediaVolume(10)\n\n# \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\nif droid.checkAirplaneMode().result:\n    print(\"Airplane mode is on\")\n
      "},{"location":"qsl4a/system/sysinfo/","title":"\u7cfb\u7edf\u4fe1\u606f","text":"

      \u68c0\u7d22\u8bbe\u5907\u548c\u7cfb\u7edf\u4fe1\u606f\u3002

      "},{"location":"qsl4a/system/sysinfo/#_2","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/sysinfo/#getandroidid","title":"getAndroidID()","text":"

      \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

      getAndroidID()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

      "},{"location":"qsl4a/system/sysinfo/#getsysinfo","title":"getSysInfo()","text":"

      \u83b7\u53d6\u7efc\u5408\u7cfb\u7edf\u4fe1\u606f\u3002

      getSysInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/sysinfo/#getlocale","title":"getLocale()","text":"

      \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u8bbe\u7f6e\u3002

      getLocale()\n

      \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

      "},{"location":"qsl4a/system/sysinfo/#_3","title":"\u5185\u5b58","text":""},{"location":"qsl4a/system/sysinfo/#getmemoryinfo","title":"getMemoryInfo()","text":"

      \u83b7\u53d6 RAM \u4fe1\u606f\u3002

      getMemoryInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/sysinfo/#_4","title":"\u663e\u793a","text":""},{"location":"qsl4a/system/sysinfo/#getscreeninfo","title":"getScreenInfo()","text":"

      \u83b7\u53d6\u663e\u793a\u4fe1\u606f\u3002

      getScreenInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/sysinfo/#_5","title":"\u6807\u8bc6\u7b26","text":""},{"location":"qsl4a/system/sysinfo/#getimei","title":"getImei()","text":"

      \u83b7\u53d6\u8bbe\u5907 IMEI\u3002

      getImei(slotIndex=None)\n
      "},{"location":"qsl4a/system/sysinfo/#getmeid","title":"getMeid()","text":"

      \u83b7\u53d6\u8bbe\u5907 MEID\u3002

      getMeid(slotIndex=None)\n
      "},{"location":"qsl4a/system/sysinfo/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u8bbe\u5907 ID\nandroid_id = droid.getAndroidID().result\nprint(f\"Android ID: {android_id}\")\n\n# \u5c4f\u5e55\u4fe1\u606f\nscreen = droid.getScreenInfo().result\nprint(f\"Screen: {screen['width']}x{screen['height']}\")\n\n# \u5185\u5b58\nmemory = droid.getMemoryInfo().result\nprint(f\"Memory: {memory}\")\n
      "},{"location":"qsl4a/system/wakelock/","title":"WakeLock API","text":"

      \u63a7\u5236\u8bbe\u5907\u5524\u9192\u9501\u4ee5\u4fdd\u6301 CPU \u6216\u5c4f\u5e55\u5f00\u542f\u3002

      "},{"location":"qsl4a/system/wakelock/#wake-lock","title":"Wake Lock \u7c7b\u578b","text":"

      QSL4A \u63d0\u4f9b\u4e0d\u540c\u7c7b\u578b\u7684\u5524\u9192\u9501\uff1a

      \u7c7b\u578b \u63cf\u8ff0 Full CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae Partial \u4ec5 CPU \u5f00\u542f Bright CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae Dim CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697"},{"location":"qsl4a/system/wakelock/#wake-lock_1","title":"Wake Lock \u65b9\u6cd5","text":""},{"location":"qsl4a/system/wakelock/#wakelockacquirefull","title":"wakeLockAcquireFull()","text":"

      \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae\uff09\u3002

      wakeLockAcquireFull()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquirepartial","title":"wakeLockAcquirePartial()","text":"

      \u83b7\u53d6\u90e8\u5206\u5524\u9192\u9501\uff08\u4ec5 CPU \u5f00\u542f\uff09\u3002

      wakeLockAcquirePartial()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquirebright","title":"wakeLockAcquireBright()","text":"

      \u83b7\u53d6\u660e\u4eae\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff09\u3002

      wakeLockAcquireBright()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquiredim","title":"wakeLockAcquireDim()","text":"

      \u83b7\u53d6\u6697\u6de1\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697\uff09\u3002

      wakeLockAcquireDim()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockrelease","title":"wakeLockRelease()","text":"

      \u91ca\u653e\u5524\u9192\u9501\u3002

      wakeLockRelease()\n
      "},{"location":"qsl4a/system/wakelock/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\ndroid.wakeLockAcquireFull()\n\n# \u5728\u4fdd\u6301\u5c4f\u5e55\u5f00\u542f\u65f6\u6267\u884c\u91cd\u8981\u5de5\u4f5c\nprint(\"Screen will stay on\")\ntime.sleep(10)\n\n# \u5b8c\u6210\u540e\u91ca\u653e\ndroid.wakeLockRelease()\n\n# \u6216\u4f7f\u7528\u90e8\u5206\u9501\u8fdb\u884c\u540e\u53f0\u4efb\u52a1\ndroid.wakeLockAcquirePartial()\n# \u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\uff0cCPU \u4ecd\u4fdd\u6301\u5f00\u542f\ntime.sleep(30)\ndroid.wakeLockRelease()\n

      \u6ce8\u610f\uff1a \u8bb0\u4f4f\u5728\u4e0d\u9700\u8981\u65f6\u91ca\u653e\u5524\u9192\u9501\u4ee5\u8282\u7701\u7535\u6c60\u3002

      "},{"location":"qsl4a/ui/accessibility/","title":"\u65e0\u969c\u788d\u670d\u52a1","text":"

      \u65e0\u969c\u788d\u670d\u52a1\u5141\u8bb8\u81ea\u52a8\u5316 UI \u4ea4\u4e92\uff0c\u5982\u70b9\u51fb\u3001\u6ed1\u52a8\u548c\u7cfb\u7edf\u64cd\u4f5c\u3002

      "},{"location":"qsl4a/ui/accessibility/#_2","title":"\u670d\u52a1\u63a7\u5236","text":""},{"location":"qsl4a/ui/accessibility/#accessibilitystartservice","title":"accessibilityStartService()","text":"

      \u542f\u52a8\u65e0\u969c\u788d\u670d\u52a1\u3002

      accessibilityStartService()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/ui/accessibility/#accessibilityserviceenabled","title":"accessibilityServiceEnabled()","text":"

      \u68c0\u67e5\u65e0\u969c\u788d\u670d\u52a1\u662f\u5426\u5df2\u542f\u7528\u3002

      accessibilityServiceEnabled()\n

      \u8fd4\u56de\uff1a True \u6216 False

      "},{"location":"qsl4a/ui/accessibility/#_3","title":"\u5c4f\u5e55\u4ea4\u4e92","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityclick","title":"accessibilityClick()","text":"

      \u5728\u5c4f\u5e55\u5750\u6807\u5904\u70b9\u51fb\u3002

      accessibilityClick(x=0, y=0, t=50)\n

      \u53c2\u6570\uff1a - x (int/float): X \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - y (int/float): Y \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - t (int): \u6309\u4f4f\u65f6\u957f\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a50\uff09

      "},{"location":"qsl4a/ui/accessibility/#accessibilityslide","title":"accessibilitySlide()","text":"

      \u591a\u70b9\u6ed1\u52a8\u624b\u52bf\u3002

      accessibilitySlide(XnYn=None, t=None)\n

      \u53c2\u6570\uff1a - XnYn (list): \u5750\u6807 [X1, Y1, X2, Y2, ... Xn, Yn] - t (int): \u6ed1\u52a8\u65f6\u957f\uff08\u9ed8\u8ba4\uff1a50*n \u6beb\u79d2\uff09

      "},{"location":"qsl4a/ui/accessibility/#_4","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityaction","title":"accessibilityAction()","text":"

      \u6309\u4ee3\u7801\u6267\u884c\u7cfb\u7edf\u64cd\u4f5c\u3002

      accessibilityAction(actionCode)\n

      \u64cd\u4f5c\u4ee3\u7801\uff1a | \u4ee3\u7801 | \u5e38\u91cf | \u63cf\u8ff0 | |------|----------|-------------| | 1 | BACK | \u8fd4\u56de\u6309\u94ae | | 2 | HOME | \u4e3b\u5c4f\u5e55\u6309\u94ae | | 3 | RECENTS | \u6700\u8fd1\u5e94\u7528 | | 4 | NOTIFICATIONS | \u6253\u5f00\u901a\u77e5 | | 5 | QUICK_SETTINGS | \u6253\u5f00\u5feb\u901f\u8bbe\u7f6e | | 6 | POWER_DIALOG | \u7535\u6e90\u83dc\u5355 | | 7 | TOGGLE_SPLIT_SCREEN | \u5206\u5c4f | | 8 | LOCK_SCREEN | \u9501\u5c4f | | 9 | TAKE_SCREENSHOT | \u622a\u56fe | | 10 | KEYCODE_HEADSETHOOK | \u8033\u673a\u6302\u94a9 | | 11-14 | ACCESSIBILITY_ | \u65e0\u969c\u788d\u6309\u94ae | | 15 | DISMISS_NOTIFICATION_SHADE | \u5173\u95ed\u901a\u77e5\u680f | | 16-20 | DPAD_ | \u65b9\u5411\u952e | | 21 | MENU | \u83dc\u5355\u6309\u94ae | | 22 | MEDIA_PLAY_PAUSE | \u64ad\u653e/\u6682\u505c\u5a92\u4f53 |

      "},{"location":"qsl4a/ui/accessibility/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/accessibility/#_6","title":"\u70b9\u51fb\u5c4f\u5e55\u4e2d\u5fc3","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u670d\u52a1\nif not droid.accessibilityServiceEnabled().result:\n    droid.accessibilityStartService()\n\n# \u70b9\u51fb\u4e2d\u5fc3\uff080,0 = \u4e2d\u5fc3\uff09\ndroid.accessibilityClick(0, 0, t=100)\n
      "},{"location":"qsl4a/ui/accessibility/#_7","title":"\u6ed1\u52a8\u624b\u52bf","text":"
      # \u4ece\u4e0b\u5f80\u4e0a\u6ed1\u52a8\uff08\u5411\u4e0a\u6eda\u52a8\uff09\ndroid.accessibilitySlide([0, 1.5, 0, -1.5], t=300)\n
      "},{"location":"qsl4a/ui/accessibility/#_8","title":"\u7cfb\u7edf\u5bfc\u822a","text":"
      # \u6309\u4e3b\u5c4f\u5e55\ndroid.accessibilityAction(2)\n\n# \u6309\u8fd4\u56de\ndroid.accessibilityAction(1)\n\n# \u6253\u5f00\u901a\u77e5\ndroid.accessibilityAction(4)\n
      "},{"location":"qsl4a/ui/accessibility/#_9","title":"\u70b9\u51fb\u7279\u5b9a\u4f4d\u7f6e","text":"
      # \u70b9\u51fb\u5c4f\u5e55\u5750\u6807 (500, 800)\ndroid.accessibilityClick(500, 800)\n\n# \u70b9\u51fb\u76f8\u5bf9\u4f4d\u7f6e\uff08\u6c34\u5e73\u5c45\u4e2d\uff0c\u5782\u76f4 3/4 \u5904\uff09\ndroid.accessibilityClick(0, 1.5)\n
      "},{"location":"qsl4a/ui/dialogs/","title":"\u5bf9\u8bdd\u6846\u7cfb\u7edf","text":"

      QSL4A \u63d0\u4f9b\u5168\u9762\u7684\u5bf9\u8bdd\u6846\u652f\u6301\uff0c\u7528\u4e8e\u7528\u6237\u4ea4\u4e92\uff0c\u5305\u62ec\u8b66\u62a5\u3001\u8f93\u5165\u5bf9\u8bdd\u6846\u3001\u9009\u62e9\u5bf9\u8bdd\u6846\u548c\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

      "},{"location":"qsl4a/ui/dialogs/#_2","title":"\u8b66\u62a5\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowalert","title":"dialogShowAlert()","text":"

      \u663e\u793a\u7b80\u5355\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

      dialogShowAlert(title=\"Alert\", message=\"The message of the alert.\",\n                positiveButtonText=\"OK\", negativeButtonText=None,\n                neutralButtonText=None, messageIsHtml=False)\n

      \u53c2\u6570\uff1a - title (str): \u5bf9\u8bdd\u6846\u6807\u9898 - message (str): \u6d88\u606f\u6587\u672c - positiveButtonText (str): \u80af\u5b9a\u6309\u94ae\u6807\u7b7e - negativeButtonText (str, optional): \u5426\u5b9a\u6309\u94ae\u6807\u7b7e - neutralButtonText (str, optional): \u4e2d\u6027\u6309\u94ae\u6807\u7b7e - messageIsHtml (bool): \u5c06\u6d88\u606f\u89e3\u6790\u4e3a HTML

      \u8fd4\u56de\uff1a \u5305\u542b\u70b9\u51fb\u6309\u94ae\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#dialogshowsimplechoice","title":"dialogShowSimpleChoice()","text":"

      \u663e\u793a\u5e26\u6709\u9879\u76ee\u7684\u7b80\u5355\u9009\u62e9\u5bf9\u8bdd\u6846\u3002

      dialogShowSimpleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

      \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868

      \u8fd4\u56de\uff1a \u5305\u542b\u9009\u4e2d\u9879\u76ee\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#_3","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialoggetinput","title":"dialogGetInput()","text":"

      \u83b7\u53d6\u7528\u6237\u6587\u672c\u8f93\u5165\u3002

      dialogGetInput(title=\"Value\", message=\"Please enter value:\",\n               defaultText=None, messageIsHtml=False)\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7528\u6237\u8f93\u5165\u6587\u672c\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#dialoggetpassword","title":"dialogGetPassword()","text":"

      \u83b7\u53d6\u5bc6\u7801\u8f93\u5165\u3002

      dialogGetPassword(title=\"Password\", message=\"Please enter password:\")\n

      \u8fd4\u56de\uff1a \u5305\u542b\u8f93\u5165\u5bc6\u7801\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#dialogcreateinput","title":"dialogCreateInput()","text":"

      \u521b\u5efa\u81ea\u5b9a\u4e49\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

      dialogCreateInput(title=\"Value\", message=\"Please enter value:\",\n                  defaultText=None, inputType=None)\n

      \u53c2\u6570\uff1a - inputType (str): \u8f93\u5165\u7c7b\u578b\uff08\u4f8b\u5982 \"text\"\u3001\"number\"\u3001\"textPassword\"\uff09

      "},{"location":"qsl4a/ui/dialogs/#dialogcreatepassword","title":"dialogCreatePassword()","text":"

      \u521b\u5efa\u5bc6\u7801\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

      dialogCreatePassword(title=\"Password\", message=\"Please enter password:\")\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreateseekbar","title":"dialogCreateSeekBar()","text":"

      \u521b\u5efa\u6ed1\u5757/\u8fdb\u5ea6\u6761\u5bf9\u8bdd\u6846\u3002

      dialogCreateSeekBar(starting_value=50, maximum_value=100, title=\"\", message=\"\")\n

      \u53c2\u6570\uff1a - starting_value (int): \u521d\u59cb\u503c - maximum_value (int): \u6700\u5927\u503c

      "},{"location":"qsl4a/ui/dialogs/#_4","title":"\u9009\u62e9\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowsinglechoice","title":"dialogShowSingleChoice()","text":"

      \u663e\u793a\u5355\u9009\uff08\u5355\u9009\u6309\u94ae\uff09\u5bf9\u8bdd\u6846\u3002

      dialogShowSingleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, selected=-1, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

      \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (int): \u9ed8\u8ba4\u9009\u4e2d\u7d22\u5f15

      "},{"location":"qsl4a/ui/dialogs/#dialogshowmultichoice","title":"dialogShowMultiChoice()","text":"

      \u663e\u793a\u591a\u9009\uff08\u590d\u9009\u6846\uff09\u5bf9\u8bdd\u6846\u3002

      dialogShowMultiChoice(title=\"Alert\", message=\"The message of the alert.\",\n                      items=None, selected=None, positiveButtonText=\"OK\",\n                      negativeButtonText=None, neutralButtonText=None,\n                      messageIsHtml=False)\n

      \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (list): \u521d\u59cb\u9009\u4e2d\u7d22\u5f15\u5217\u8868

      "},{"location":"qsl4a/ui/dialogs/#dialogsetsinglechoiceitems","title":"dialogSetSingleChoiceItems()","text":"

      \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u5355\u9009\u9879\u76ee\u3002

      dialogSetSingleChoiceItems(items, selected=-1)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmultichoiceitems","title":"dialogSetMultiChoiceItems()","text":"

      \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u591a\u9009\u9879\u76ee\u3002

      dialogSetMultiChoiceItems(items, selected=None)\n
      "},{"location":"qsl4a/ui/dialogs/#_5","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatespinnerprogress","title":"dialogCreateSpinnerProgress()","text":"

      \u521b\u5efa\u4e0d\u786e\u5b9a\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

      dialogCreateSpinnerProgress(title=None, message=None, maximum_progress=100)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreatehorizontalprogress","title":"dialogCreateHorizontalProgress()","text":"

      \u521b\u5efa\u6c34\u5e73\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

      dialogCreateHorizontalProgress(title=None, message=None, maximum_progress=100)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetcurrentprogress","title":"dialogSetCurrentProgress()","text":"

      \u66f4\u65b0\u8fdb\u5ea6\u503c\u3002

      dialogSetCurrentProgress(current)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmaxprogress","title":"dialogSetMaxProgress()","text":"

      \u8bbe\u7f6e\u6700\u5927\u8fdb\u5ea6\u503c\u3002

      dialogSetMaxProgress(max)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetprogressmessage","title":"dialogSetProgressMessage()","text":"

      \u66f4\u65b0\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u6d88\u606f\u3002

      dialogSetProgressMessage(message)\n
      "},{"location":"qsl4a/ui/dialogs/#_6","title":"\u9009\u62e9\u5668\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatedatepicker","title":"dialogCreateDatePicker()","text":"

      \u521b\u5efa\u65e5\u671f\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

      dialogCreateDatePicker(year=1970, month=1, day=1)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreatetimepicker","title":"dialogCreateTimePicker()","text":"

      \u521b\u5efa\u65f6\u95f4\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

      dialogCreateTimePicker(hour=0, minute=0, is24hour=False)\n
      "},{"location":"qsl4a/ui/dialogs/#_7","title":"\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u521b\u5efa","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatealert","title":"dialogCreateAlert()","text":"

      \u521b\u5efa\u81ea\u5b9a\u4e49\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

      dialogCreateAlert(title=None, message=None)\n

      \u521b\u5efa\u4e00\u4e2a\u7a7a\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002\u53ef\u4e0e\u5176\u4ed6 dialogSet* \u51fd\u6570\u4e00\u8d77\u4f7f\u7528\u6765\u81ea\u5b9a\u4e49\u3002

      "},{"location":"qsl4a/ui/dialogs/#dialogsetitems","title":"dialogSetItems()","text":"

      \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u7b80\u5355\u5217\u8868\u9879\u76ee\u3002

      dialogSetItems(items)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetpositivebuttontext","title":"dialogSetPositiveButtonText()","text":"

      \u8bbe\u7f6e\u80af\u5b9a\u6309\u94ae\u6587\u672c\u3002

      dialogSetPositiveButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetnegativebuttontext","title":"dialogSetNegativeButtonText()","text":"

      \u8bbe\u7f6e\u5426\u5b9a\u6309\u94ae\u6587\u672c\u3002

      dialogSetNegativeButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetneutralbuttontext","title":"dialogSetNeutralButtonText()","text":"

      \u8bbe\u7f6e\u4e2d\u6027\u6309\u94ae\u6587\u672c\u3002

      dialogSetNeutralButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmessageishtml","title":"dialogSetMessageIsHtml()","text":"

      \u8bbe\u7f6e\u6d88\u606f\u662f\u5426\u5e94\u89e3\u6790\u4e3a HTML\u3002

      dialogSetMessageIsHtml(messageIsHtml=True)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogshow","title":"dialogShow()","text":"

      \u663e\u793a\u521b\u5efa\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u3002

      dialogShow()\n
      "},{"location":"qsl4a/ui/dialogs/#_8","title":"\u5bf9\u8bdd\u6846\u63a7\u5236","text":""},{"location":"qsl4a/ui/dialogs/#dialogdismiss","title":"dialogDismiss()","text":"

      \u5173\u95ed\u5f53\u524d\u5bf9\u8bdd\u6846\u3002

      dialogDismiss()\n
      "},{"location":"qsl4a/ui/dialogs/#dialoggetresponse","title":"dialogGetResponse()","text":"

      \u83b7\u53d6\u5bf9\u8bdd\u6846\u54cd\u5e94\u3002

      dialogGetResponse()\n
      "},{"location":"qsl4a/ui/dialogs/#dialoggetselecteditems","title":"dialogGetSelectedItems()","text":"

      \u4ece\u9009\u62e9\u5bf9\u8bdd\u6846\u83b7\u53d6\u9009\u4e2d\u7684\u9879\u76ee\u3002

      dialogGetSelectedItems()\n
      "},{"location":"qsl4a/ui/dialogs/#_9","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/dialogs/#_10","title":"\u7b80\u5355\u8b66\u62a5","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a\u8b66\u62a5\ndroid.dialogShowAlert(\"Warning\", \"This is an important message!\")\n
      "},{"location":"qsl4a/ui/dialogs/#_11","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":"
      # \u83b7\u53d6\u7528\u6237\u8f93\u5165\nresult = droid.dialogGetInput(\"Name\", \"Enter your name:\", \"John\").result\nprint(f\"Hello, {result}!\")\n
      "},{"location":"qsl4a/ui/dialogs/#_12","title":"\u5e26\u6309\u94ae\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846","text":"
      # \u521b\u5efa\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\ndroid.dialogCreateAlert(\"Custom\", \"Choose an option\")\ndroid.dialogSetItems([\"Option 1\", \"Option 2\", \"Option 3\"])\ndroid.dialogShow()\n\n# \u83b7\u53d6\u54cd\u5e94\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response['item']}\")\n
      "},{"location":"qsl4a/ui/dialogs/#_13","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":"
      # \u521b\u5efa\u8fdb\u5ea6\u5bf9\u8bdd\u6846\ndroid.dialogCreateHorizontalProgress(\"Loading\", \"Please wait...\", 100)\ndroid.dialogShow()\n\n# \u66f4\u65b0\u8fdb\u5ea6\nfor i in range(101):\n    droid.dialogSetCurrentProgress(i)\n    time.sleep(0.05)\n\ndroid.dialogDismiss()\n
      "},{"location":"qsl4a/ui/dialogs/#_14","title":"\u65e5\u671f\u9009\u62e9\u5668","text":"
      # \u663e\u793a\u65e5\u671f\u9009\u62e9\u5668\ndroid.dialogCreateDatePicker(2024, 1, 15)\ndroid.dialogShow()\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response}\")\n
      "},{"location":"qsl4a/ui/floatview/","title":"\u6d6e\u52a8\u89c6\u56fe","text":"

      \u6d6e\u52a8\u7a97\u53e3\u652f\u6301\uff0c\u7528\u4e8e\u5728\u5176\u4ed6\u5e94\u7528\u7a0b\u5e8f\u4e0a\u65b9\u4fdd\u6301\u663e\u793a\u7684\u8986\u76d6 UI \u5143\u7d20\u3002

      "},{"location":"qsl4a/ui/floatview/#_2","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/floatview/#floatview","title":"floatView()","text":"

      \u663e\u793a\u6216\u4fee\u6539\u6d6e\u52a8\u89c6\u56fe\u3002

      floatView(Args=None)\n

      \u53c2\u6570\uff1a - Args (dict): \u914d\u7f6e\u5b57\u5178\uff0c\u5305\u542b\u4ee5\u4e0b\u952e\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08-1 \u521b\u5efa\u65b0\u7684\uff0c>=0 \u4fee\u6539\u73b0\u6709\u7684\uff09 - text (str): \u8981\u663e\u793a\u7684\u6587\u672c\u5185\u5bb9 - html (str): HTML \u5185\u5bb9\uff08\u5982\u679c\u7701\u7565 text \u5219\u4f7f\u7528\uff09 - width (int): \u89c6\u56fe\u5bbd\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a300\uff09 - height (int): \u89c6\u56fe\u9ad8\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a150\uff09 - x (int): X \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - y (int): Y \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - backColor (str): ARGB \u5341\u516d\u8fdb\u5236\u80cc\u666f\u8272\uff08\u9ed8\u8ba4\uff1a'7f7f7f7f'\uff09 - textColor (str): ARGB \u5341\u516d\u8fdb\u5236\u6587\u672c\u8272\uff08\u9ed8\u8ba4\uff1a'ff000000'\uff09 - textSize (int): \u6587\u672c\u5927\u5c0f\uff08\u9ed8\u8ba4\uff1a10\uff09 - textAlign (int): \u6587\u672c\u5bf9\u9f50\uff080 = \u7ee7\u627f\uff09 - script (str): \u957f\u6309\u5173\u95ed\u540e\u8fd0\u884c\u7684\u811a\u672c\u8def\u5f84 - arg: \u811a\u672c\u53c2\u6570 - clickRemove (bool): \u542f\u7528\u70b9\u51fb\u79fb\u9664\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - flag (int): \u7a97\u53e3\u6807\u5fd7\uff08\u9ed8\u8ba4\uff1a40 - \u53ef\u89e6\u6478\uff09

      \u8fd4\u56de\uff1a \u5f53\u524d\u94fe\u5217\u8868\u957f\u5ea6

      "},{"location":"qsl4a/ui/floatview/#floatviewcount","title":"floatViewCount()","text":"

      \u83b7\u53d6\u6d3b\u52a8\u6d6e\u52a8\u89c6\u56fe\u7684\u6570\u91cf\u3002

      floatViewCount()\n

      \u8fd4\u56de\uff1a \u6d6e\u52a8\u89c6\u56fe\u6570\u91cf

      "},{"location":"qsl4a/ui/floatview/#floatviewresult","title":"floatViewResult()","text":"

      \u83b7\u53d6\u6d6e\u52a8\u89c6\u56fe\u7684\u7ed3\u679c/\u72b6\u6001\u3002

      floatViewResult(index=-1)\n

      \u53c2\u6570\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1\uff0c\u8fd4\u56de\u6700\u540e\u64cd\u4f5c\u7ed3\u679c\uff09

      \u8fd4\u56de\uff1a \u5305\u542b\u64cd\u4f5c\u8be6\u60c5\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - x, y: \u4f4d\u7f6e - time: \u65f6\u95f4\u6233 - operation: \u64cd\u4f5c\u7c7b\u578b\uff08'initial'\u3001'move' \u7b49\uff09 - index: \u89c6\u56fe\u7d22\u5f15 - removed: \u5982\u679c\u89c6\u56fe\u88ab\u79fb\u9664\u5219\u4e3a True

      "},{"location":"qsl4a/ui/floatview/#floatviewremove","title":"floatViewRemove()","text":"

      \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\u3002

      floatViewRemove(index=-1)\n

      \u53c2\u6570\uff1a - index (int): \u8981\u79fb\u9664\u7684\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1 \u79fb\u9664\u6700\u540e\u4e00\u4e2a\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a 1\uff0c\u5426\u5219\u4e3a 0

      "},{"location":"qsl4a/ui/floatview/#_3","title":"\u5e38\u91cf","text":"
      • floatView.INDEX_NEW = -1 - \u521b\u5efa\u65b0\u7684\u6d6e\u52a8\u89c6\u56fe
      • floatView.FLAG_DEFAULT_TOUCHABLE = 40 - \u9ed8\u8ba4\u53ef\u89e6\u6478\u6807\u5fd7
      • floatView.TEXT_ALIGNMENT_INHERIT = 0
      • floatView.TEXT_ALIGNMENT_CENTER - \u5c45\u4e2d\u6587\u672c\u5bf9\u9f50
      "},{"location":"qsl4a/ui/floatview/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/floatview/#_5","title":"\u57fa\u672c\u6d6e\u52a8\u89c6\u56fe","text":"
      import androidhelper\nfrom androidhelper import Android\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u7b80\u5355\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'index': -1,  # \u521b\u5efa\u65b0\u7684\n    'text': 'Hello World',\n    'width': 400,\n    'height': 300,\n    'x': -300,  # \u4ece\u4e2d\u5fc3\u504f\u79fb\n    'y': -400,\n    'backColor': 'ff0000',  # \u7ea2\u8272\u80cc\u666f\n    'textColor': '0000ff',  # \u84dd\u8272\u6587\u672c\n    'textSize': 16,\n    'textAlign': droid.floatView.TEXT_ALIGNMENT_CENTER\n})\n\n# \u68c0\u67e5\u6570\u91cf\nprint(f\"Float views: {droid.floatViewCount().result}\")\n\n# \u83b7\u53d6\u7ed3\u679c\nresult = droid.floatViewResult().result\nprint(f\"View info: {result}\")\n\n# \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\ndroid.floatViewRemove(0)\n
      "},{"location":"qsl4a/ui/floatview/#html","title":"HTML \u5185\u5bb9","text":"
      # \u521b\u5efa\u5e26 HTML \u5185\u5bb9\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': '',  # \u7a7a\u6587\u672c\u4ee5\u4f7f\u7528 HTML\n    'html': '<h1>Title</h1><p>Rich <b>HTML</b> content</p>',\n    'width': 500,\n    'height': 400\n})\n
      "},{"location":"qsl4a/ui/floatview/#_6","title":"\u4fee\u6539\u73b0\u6709\u89c6\u56fe","text":"
      # \u521b\u5efa\u521d\u59cb\u89c6\u56fe\ndroid.floatView({'text': 'Initial Text', 'width': 300, 'height': 150})\n\n# \u4fee\u6539\u540c\u4e00\u89c6\u56fe\uff08\u7d22\u5f15 0\uff09\ndroid.floatView({\n    'index': 0,\n    'text': 'Updated Text!',\n    'backColor': '7f00ff00'  # \u7eff\u8272\u80cc\u666f\n})\n\n# \u68c0\u67e5\u79fb\u52a8/\u66f4\u6539\u7ed3\u679c\nresult = droid.floatViewResult(0).result\nprint(f\"Operation: {result.get('operation')}, Position: ({result.get('x')}, {result.get('y')})\")\n
      "},{"location":"qsl4a/ui/floatview/#_7","title":"\u591a\u4e2a\u6d6e\u52a8\u89c6\u56fe","text":"
      # \u521b\u5efa\u591a\u4e2a\u89c6\u56fe\nfor i in range(3):\n    droid.floatView({\n        'index': -1,\n        'text': f'View {i}',\n        'x': i * 100 - 150,\n        'y': i * 100 - 150,\n        'backColor': f'{i}f{i}f{i}f'\n    })\n\nprint(f\"Total views: {droid.floatViewCount().result}\")\n\n# \u79fb\u9664\u6240\u6709\u89c6\u56fe\nwhile droid.floatViewCount().result > 0:\n    droid.floatViewRemove()\n
      "},{"location":"qsl4a/ui/floatview/#_8","title":"\u5e26\u811a\u672c\u56de\u8c03","text":"
      # \u521b\u5efa\u5173\u95ed\u65f6\u8fd0\u884c\u811a\u672c\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': 'Click to close and run script',\n    'script': '/sdcard/my_script.py',\n    'arg': 'hello from float view',\n    'clickRemove': True\n})\n
      "},{"location":"qsl4a/ui/fullscreen/","title":"\u5168\u5c4f UI","text":"

      \u4f7f\u7528\u539f\u751f Android \u5e03\u5c40\u521b\u5efa\u81ea\u5b9a\u4e49\u5168\u5c4f\u754c\u9762\u3002

      "},{"location":"qsl4a/ui/fullscreen/#_1","title":"\u5e03\u5c40\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullshow","title":"fullShow()","text":"

      \u663e\u793a\u5168\u5c4f\u5e03\u5c40\u3002

      fullShow(layout, title=None, theme=None)\n

      \u53c2\u6570\uff1a - layout (str): JSON \u5e03\u5c40\u5b9a\u4e49\u6216\u5e03\u5c40\u5b57\u7b26\u4e32 - title (str, optional): \u7a97\u53e3\u6807\u9898 - theme (str, optional): \u4e3b\u9898\u540d\u79f0

      \u8fd4\u56de\uff1a \u7a97\u53e3 ID

      "},{"location":"qsl4a/ui/fullscreen/#fulldismiss","title":"fullDismiss()","text":"

      \u5173\u95ed\u5168\u5c4f\u7a97\u53e3\u3002

      fullDismiss()\n
      "},{"location":"qsl4a/ui/fullscreen/#fullquery","title":"fullQuery()","text":"

      \u67e5\u8be2\u6240\u6709\u5c0f\u90e8\u4ef6\u503c\u3002

      fullQuery()\n

      \u8fd4\u56de\uff1a \u5c0f\u90e8\u4ef6 ID \u548c\u503c\u7684\u5b57\u5178

      "},{"location":"qsl4a/ui/fullscreen/#fullquerydetail","title":"fullQueryDetail()","text":"

      \u67e5\u8be2\u7279\u5b9a\u5c0f\u90e8\u4ef6\u8be6\u60c5\u3002

      fullQueryDetail(id)\n
      "},{"location":"qsl4a/ui/fullscreen/#_2","title":"\u5c5e\u6027\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperty","title":"fullGetProperty()","text":"

      \u83b7\u53d6\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

      fullGetProperty(id, property)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetproperty","title":"fullSetProperty()","text":"

      \u8bbe\u7f6e\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

      fullSetProperty(id, property, value)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetlist","title":"fullSetList()","text":"

      \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

      fullSetList(id, list, isHtml=False, listType=0)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetlist2","title":"fullSetList2()","text":"

      \u4f7f\u7528\u8d44\u6e90 ID \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

      fullSetList2(id, list, intRes)\n

      \u53c2\u6570\uff1a - id (str): \u5c0f\u90e8\u4ef6 ID - list (list): \u9879\u76ee\u5217\u8868 - intRes (int): \u5217\u8868\u9879\u76ee\u5e03\u5c40\u7684 Android \u8d44\u6e90 ID

      "},{"location":"qsl4a/ui/fullscreen/#fullsetlistselected","title":"fullSetListSelected()","text":"

      \u5728\u5217\u8868\u4e2d\u8bbe\u7f6e\u9009\u4e2d\u9879\u76ee\u3002

      fullSetListSelected(id, selected)\n

      \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID - selected (int): \u8981\u9009\u4e2d\u7684\u9879\u76ee\u7d22\u5f15

      "},{"location":"qsl4a/ui/fullscreen/#fullgetlistselected","title":"fullGetListSelected()","text":"

      \u83b7\u53d6\u5f53\u524d\u9009\u4e2d\u7684\u5217\u8868\u9879\u76ee\u7d22\u5f15\u3002

      fullGetListSelected(id)\n

      \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID

      \u8fd4\u56de\uff1a \u9009\u4e2d\u9879\u76ee\u7d22\u5f15

      "},{"location":"qsl4a/ui/fullscreen/#_3","title":"\u6279\u91cf\u5c5e\u6027\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperties","title":"fullGetProperties()","text":"

      \u4e00\u6b21\u83b7\u53d6\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

      fullGetProperties(ids, property)\n

      \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u83b7\u53d6\u7684\u5c5e\u6027\u540d

      \u8fd4\u56de\uff1a \u6620\u5c04\u5c0f\u90e8\u4ef6 ID \u5230\u5c5e\u6027\u503c\u7684\u5b57\u5178

      "},{"location":"qsl4a/ui/fullscreen/#fullsetproperties","title":"fullSetProperties()","text":"

      \u4e00\u6b21\u8bbe\u7f6e\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

      fullSetProperties(ids, property, value)\n

      \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u8bbe\u7f6e\u7684\u5c5e\u6027\u540d - value: \u5c5e\u6027\u503c

      "},{"location":"qsl4a/ui/fullscreen/#_4","title":"\u622a\u56fe","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetscreenshot","title":"fullGetScreenShot()","text":"

      \u6355\u83b7\u5168\u5c4f\u622a\u56fe\u3002

      fullGetScreenShot(path=None)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u5728\u4e8b\u4ef6\u4e2d\u8fd4\u56de

      \u8fd4\u56de\uff1a \u5305\u542b\u622a\u56fe\u6570\u636e\u7684\u4e8b\u4ef6

      "},{"location":"qsl4a/ui/fullscreen/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b9a\u4e49\u5e03\u5c40\nlayout = '''\n{ \"type\": \"LinearLayout\", \"orientation\": \"vertical\",\n  \"children\": [\n    { \"type\": \"TextView\", \"id\": \"title\", \"text\": \"Hello\" },\n    { \"type\": \"Button\", \"id\": \"btn\", \"text\": \"Click Me\" }\n  ]\n}\n'''\n\n# \u663e\u793a\u5e03\u5c40\ndroid.fullShow(layout, \"My App\")\n\n# \u67e5\u8be2\u6309\u94ae\u70b9\u51fb\nevent = droid.eventWaitFor('click', timeout=10)\nif event.result:\n    widget_id = event.result['data']['id']\n    if widget_id == 'btn':\n        print(\"Button clicked!\")\n\ndroid.fullDismiss()\n
      "}]} \ No newline at end of file From 174a00bda0918ecbab3b92ab7c756c5412798620 Mon Sep 17 00:00:00 2001 From: "River@devbox" Date: Wed, 8 Apr 2026 18:31:50 +0800 Subject: [PATCH 30/32] Deploy site - 2026-04-08 18:31:49 --- zh/community/index.html | 3 +-- zh/search/search_index.json | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/zh/community/index.html b/zh/community/index.html index 3695b6d..2493897 100644 --- a/zh/community/index.html +++ b/zh/community/index.html @@ -2869,11 +2869,10 @@

      QPython微信群 & QQ群QPython 社区推荐服务

      -

      在 QPython 的使用过程中,部分用户希望将自己开发的脚本或服务打包成独立的安卓应用。为此,我们特别筛选了以下优质服务,供您按需选择:

      +

      在 QPython 的使用过程中,部分用户希望将自己开发的脚本或服务打包成独立的安卓应用。为此,我们特别筛选了以下优质服务,供您按需选择(如果您想推荐你的 QPython 社区服务,也欢迎微信联系):

      -

      如果您想推荐你的 QPython 社区服务,也欢迎微信联系。

      QPython 知识星球 VIP社区

      QPython官方付费VIP专属社区,为深度用户提供官方团队直连、及时技术支持、高质量交流的专属服务空间。加入VIP社区可获下列核心价值:

        diff --git a/zh/search/search_index.json b/zh/search/search_index.json index 1f77fb5..2b7a4f7 100644 --- a/zh/search/search_index.json +++ b/zh/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"QPython \u9879\u76ee","text":"

        QPython \u4e0d\u4ec5\u662f\u4e00\u4e2a\u5f3a\u5927\u7684 Android Python IDE\uff0c\u4e5f\u662f\u4e00\u4e2a\u6d3b\u8dc3\u7684\u6280\u672f\u793e\u533a\u3002

        "},{"location":"#ai-android-python-ide","title":"\u652f\u6301 AI \u7684 Android Python IDE","text":"

        QPython \u662f\u60a8\u8fdb\u884c Android Python \u7f16\u7a0b\u7684\u5165\u53e3\u3002\u5b83\u96c6\u6210\u4e86 Python \u89e3\u91ca\u5668\u3001AI \u6a21\u578b\u5f15\u64ce\u548c\u79fb\u52a8\u5f00\u53d1\u5de5\u5177\u94fe\uff0c\u8ba9\u60a8\u80fd\u591f\u4ece\u79fb\u52a8\u8bbe\u5907\u6784\u5efa Web \u5e94\u7528\u7a0b\u5e8f\u3001\u6267\u884c\u79d1\u5b66\u8ba1\u7b97\u548c\u521b\u5efa\u667a\u80fd\u5e94\u7528\u3002

        \u65e0\u8bba\u60a8\u662f\u5728\u5b66\u4e60\u7f16\u7a0b\u3001\u6784\u5efa\u6570\u636e\u79d1\u5b66\u9879\u76ee\uff0c\u8fd8\u662f\u5f00\u53d1 AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f\uff0cQPython \u90fd\u63d0\u4f9b\u4e86\u5b8c\u6574\u7684\u79fb\u52a8\u7f16\u7a0b\u89e3\u51b3\u65b9\u6848\uff0c\u62e5\u6709\u5168\u9762\u7684\u5f00\u53d1\u8005\u8d44\u6e90\u548c\u6d3b\u8dc3\u7684\u793e\u533a\u6765\u652f\u6301\u60a8\u7684\u65c5\u7a0b\u3002

        • \u5206\u652f\u7248\u672c \u2013 \u4e86\u89e3\u4e0d\u540c\u7684 QPython \u7248\u672c\uff08IDE\u3001\u793e\u533a\u7248\u3001Plus\uff09\uff0c\u9009\u62e9\u9002\u5408\u60a8\u9700\u6c42\u7684\u7248\u672c
        • \u66f4\u65b0\u65e5\u5fd7 \u2013 \u968f\u65f6\u4e86\u89e3\u6700\u65b0\u529f\u80fd\u3001\u6539\u8fdb\u548c\u53d1\u884c\u8bf4\u660e
        "},{"location":"#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"

        \u5982\u4f55\u5feb\u901f\u5165\u95e8\uff1f\u8bf7\u6309\u7167\u4ee5\u4e0b\u6b65\u9aa4\uff1a

        • \u5feb\u901f\u5165\u95e8
        • Hello World \u6559\u7a0b
        "},{"location":"#_2","title":"\u7f16\u7a0b\u6307\u5357","text":"

        QPython \u4e0d\u4ec5\u63d0\u4f9b\u57fa\u7840\u7684 Python \u63a5\u53e3\u652f\u6301\uff0c\u66f4\u91cd\u8981\u7684\u662f\uff0c\u5b83\u8fd8\u5141\u8bb8\u60a8\u901a\u8fc7 QSL4A \u63a5\u53e3\u4f7f\u7528 Python \u8c03\u7528 Android API\u3002

        • Python \u6807\u51c6\u5e93 \u2013 \u901a\u7528\u7684 Python \u8bed\u6cd5\u548c\u5185\u7f6e\u5e93
        • QSL4A API \u2013 \u4ece Python \u8bbf\u95ee Android \u8bbe\u5907\u529f\u80fd\uff08\u76f8\u673a\u3001\u4f20\u611f\u5668\u3001\u77ed\u4fe1\u7b49\uff09
        • QPYPI \u6307\u5357 \u2013 \u5b89\u88c5\u989d\u5916\u7684 Python \u5305
        • \u7f16\u8f91\u5668\u6307\u5357 \u2013 \u4f7f\u7528\u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668
        • \u5916\u90e8 API \u2013 \u4e0e\u5916\u90e8\u5e94\u7528\u7a0b\u5e8f\u96c6\u6210
        "},{"location":"#_3","title":"\u4e0b\u8f7d\u8d44\u6e90","text":"
        • Google Drive
        • \u5fae\u4fe1\u7f51\u76d8
        "},{"location":"#_4","title":"\u793e\u533a\u4e0e\u53cd\u9988","text":"
        • \u4e2d\u6587\u4ea4\u6d41\u793e\u533a
        • \u95ee\u9898\u53cd\u9988
        • \u529f\u80fd\u6269\u5c55\u8bf7\u6c42
        "},{"location":"#_5","title":"\u5173\u6ce8\u6211\u4eec","text":"
        • B\u7ad9
        • Weibo
        "},{"location":"AIPyApp/","title":"AIPyApp - AI\u9a71\u52a8\u7684\u7a0b\u5e8f\u751f\u6210\u5668","text":"

        AIPyApp \u662f QPython \u4e2d\u7684\u667a\u80fd\u5de5\u5177\uff0c\u53ef\u4ee5\u5229\u7528 AI \u4ece\u81ea\u7136\u8bed\u8a00\u6307\u4ee4\u81ea\u52a8\u751f\u6210 Python \u7a0b\u5e8f\u3002

        "},{"location":"AIPyApp/#_1","title":"\u6982\u8ff0","text":"

        AIPyApp \u6539\u53d8\u4e86\u60a8\u7f16\u5199\u4ee3\u7801\u7684\u65b9\u5f0f\u2014\u2014\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u63cf\u8ff0\u60a8\u60f3\u8981\u7684\u529f\u80fd\uff0cAI \u5c31\u4f1a\u4e3a\u60a8\u751f\u6210 Python \u7a0b\u5e8f\u3002QPython \u8fd8\u5c06\u63a8\u51fa AIPy Academy\u2014\u2014\u4e00\u4e2a\u4e3a AI \u65f6\u4ee3\u91cf\u8eab\u5b9a\u5236\u7684 Python \u7f16\u7a0b\u8bfe\u7a0b\u5e73\u53f0\u3002

        "},{"location":"AIPyApp/#_2","title":"\u5b89\u88c5","text":"

        QPython \u6c1b\u56f4\u7f16\u7a0b\uff08Vibe Coding\uff09 01 - \u5982\u4f55\u542f\u7528AIPyApp

        "},{"location":"AIPyApp/#_3","title":"\u7b2c\u4e00\u6b65\uff1a\u4ece\u4eea\u8868\u76d8\u542f\u52a8","text":"
        1. \u6253\u5f00 QPython\uff0c\u8fdb\u5165 \u4eea\u8868\u76d8
        2. \u957f\u6309\u5f00\u59cb\u6309\u94ae

        \u5982\u679c\u672a\u5b89\u88c5 AIPyApp\uff0c\u7cfb\u7edf\u4f1a\u63d0\u793a\u60a8\u786e\u8ba4\u5b89\u88c5\u3002\u6309 \u56de\u8f66\u952e\u7ee7\u7eed\u3002

        QPython \u5c06\u81ea\u52a8\u4ece PYPI \u4e0b\u8f7d\u5e76\u5b89\u88c5\u6240\u9700\u7684\u4f9d\u8d56\u9879\u3002\u8bf7\u8010\u5fc3\u7b49\u5f85\u5b89\u88c5\u5b8c\u6210\u3002

        "},{"location":"AIPyApp/#aipyapp","title":"\u7b2c\u4e8c\u6b65\uff1a\u91cd\u65b0\u542f\u52a8 AIPyApp","text":"

        \u5b89\u88c5\u5b8c\u6210\u540e\uff0c\u8fd4\u56de QPython \u4eea\u8868\u76d8\uff0c\u518d\u6b21 \u957f\u6309\u5f00\u59cb\u6309\u94ae\u542f\u52a8 AIPyApp\u3002

        "},{"location":"AIPyApp/#_4","title":"\u914d\u7f6e","text":""},{"location":"AIPyApp/#ai","title":"\u8bbe\u7f6e\u60a8\u7684 AI \u5bc6\u94a5","text":"

        \u9996\u6b21\u542f\u52a8\u65f6\uff0c\u60a8\u9700\u8981\u63d0\u4f9b AI API \u5bc6\u94a5\uff1a

        1. \u5728 PGPT \u6ce8\u518c\uff1a\u5728 https://user.pgpt.cloud \u521b\u5efa\u8d26\u6237\u4ee5\u751f\u6210\u60a8\u7684 AI \u5bc6\u94a5
        2. \u9ad8\u7ea7\u9009\u9879\uff1aAIPyApp \u8fd8\u652f\u6301\u6765\u81ea OpenAI\u3001Deepseek \u548c\u5176\u4ed6\u63d0\u4f9b\u5546\u7684\u81ea\u5b9a\u4e49 AI \u5bc6\u94a5\uff08\u8be6\u89c1\u9ad8\u7ea7\u6559\u7a0b\uff09
        "},{"location":"AIPyApp/#ai_1","title":"\u8f93\u5165\u60a8\u7684 AI \u5bc6\u94a5","text":"
        1. \u957f\u6309\u8f93\u5165\u63d0\u793a
        2. \u4ece\u5f39\u51fa\u83dc\u5355\u4e2d\u9009\u62e9 \u7c98\u8d34
        3. \u6309 \u56de\u8f66\u952e\u786e\u8ba4

        \u60a8\u7684 AI \u5bc6\u94a5\u5c06\u4fdd\u5b58\u4ee5\u4f9b\u540e\u7eed\u4f1a\u8bdd\u4f7f\u7528\u3002

        "},{"location":"AIPyApp/#aipyapp_1","title":"\u4f7f\u7528 AIPyApp","text":"

        \u914d\u7f6e\u5b8c\u6210\u540e\uff0c\u60a8\u5c06\u8fdb\u5165 AIPyApp \u63a7\u5236\u53f0\u6a21\u5f0f\u3002\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u8f93\u5165\u60a8\u7684\u6307\u4ee4\u5373\u53ef\uff01

        "},{"location":"AIPyApp/#_5","title":"\u793a\u4f8b\u547d\u4ee4","text":"

        \u5c1d\u8bd5\u8f93\u5165\uff1a

        \u4f7f\u7528 QSL4A \u521b\u5efa\u4e00\u4e2a HELLO QPY \u7a0b\u5e8f\u4f5c\u4e3a\u6f14\u793a\n

        AIPyApp \u5c06\uff1a 1. \u7406\u89e3\u60a8\u7684\u81ea\u7136\u8bed\u8a00\u8bf7\u6c42 2. \u751f\u6210\u76f8\u5e94\u7684 Python \u4ee3\u7801 3. \u81ea\u52a8\u6267\u884c\u7a0b\u5e8f

        \u5c31\u662f\u8fd9\u6837\u2014\u2014\u60a8\u65e0\u9700\u7f16\u5199\u4efb\u4f55\u4ee3\u7801\u5c31\u521b\u5efa\u4e86\u4e00\u4e2a\u53ef\u8fd0\u884c\u7684 Python \u7a0b\u5e8f\uff01

        "},{"location":"AIPyApp/#_6","title":"\u6f14\u793a\u89c6\u9891","text":"

        QPython \u6c1b\u56f4\u7f16\u7a0b\uff08Vibe Coding\uff09 02 - \u4f7f\u7528\u81ea\u7136\u8bed\u8a00\u5f00\u53d1\u4e00\u4e2a\u7ffb\u8bd1App

        \u4e0a\u9762\u7684\u793a\u4f8b\u6f14\u793a\u4e86 AIPyApp \u5982\u4f55\uff1a - \u7406\u89e3\u4e2d\u6587\u6307\u4ee4 - \u751f\u6210\u57fa\u4e8e QSL4A \u7684 Python \u4ee3\u7801 - \u7acb\u5373\u8fd0\u884c\u7a0b\u5e8f

        \u63a2\u7d22 AIPyApp \u4ee5\u53d1\u73b0\u66f4\u591a\u529f\u80fd\uff0c\u5f00\u59cb\u8f7b\u677e\u6784\u5efa Python \u7a0b\u5e8f\u3002

        "},{"location":"AIPyApp/#_7","title":"\u8bfe\u7a0b\u63a8\u8350","text":"

        \u672b\u5c3e\uff0c\u7ed9\u5927\u5bb6\u63a8\u8350\u4e0b\u9762\u8bfe\u7a0b\uff1a

        \u300a\u4e0eAI\u534f\u4f5c\u7684Python\u7f16\u7a0b\u5165\u95e8\u300b \u2014 \u7531QPython\u5b98\u65b9\u56e2\u961f\u7cbe\u5fc3\u6253\u9020\u5e76\u63d0\u4f9b\u6559\u5b66\u652f\u6301\uff0c\u80fd\u5e2e\u52a9\u5b66\u4e60\u8005\u5feb\u901f\u3001\u4f53\u7cfb\u5316\u5730\u638c\u63e1Python\u5f00\u53d1\u4ee5\u53ca\u5728AI\u65f6\u4ee3\u66f4\u597d\u5730\u5b66\u4e60\u4f7f\u7528AI\u3002

        \u4e86\u89e3\u8be6\u60c5

        "},{"location":"GraphicalInterface/","title":"\u56fe\u5f62\u754c\u9762\uff08Turtle \u548c Tkinter\uff09","text":"

        \u672c\u6307\u5357\u8bf4\u660e\u5982\u4f55\u5728 Android \u8bbe\u5907\u4e0a\u7684 QPython \u4e2d\u542f\u7528\u56fe\u5f62\u754c\u9762\u652f\u6301\uff08Turtle \u548c Tkinter\uff09\u3002

        "},{"location":"GraphicalInterface/#_1","title":"\u6982\u8ff0","text":"

        QPython \u53ef\u4ee5\u8fd0\u884c Turtle \u548c Tkinter \u5e94\u7528\u7a0b\u5e8f\uff0c\u4f46\u9700\u8981\u989d\u5916\u7684\u8f6f\u4ef6\u6765\u5728 Android \u4e0a\u63d0\u4f9b\u56fe\u5f62\u663e\u793a\u652f\u6301\u3002

        "},{"location":"GraphicalInterface/#_2","title":"\u524d\u63d0\u6761\u4ef6","text":"

        \u5f00\u59cb\u4e4b\u524d\uff0c\u60a8\u9700\u8981\u4e0b\u8f7d\u4ee5\u4e0b\u8d44\u6e90\uff1a

        1. Xserver.apk - \u63d0\u4f9b Turtle/Tkinter \u56fe\u5f62\u652f\u6301\u7684\u914d\u5957\u5e94\u7528
        2. \u4e0b\u8f7d\u5730\u5740\uff1aQPythonProject/Extra on Google Drive
        3. Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762\u6269\u5c55 - \u901a\u8fc7 QPython \u7684 QPYPI \u5b89\u88c5
        "},{"location":"GraphicalInterface/#_3","title":"\u5b89\u88c5\u6b65\u9aa4","text":""},{"location":"GraphicalInterface/#xserver","title":"\u7b2c\u4e00\u6b65\uff1a\u5b89\u88c5 Xserver","text":"

        \u4ece Google Drive \u7684 QPython Extra \u8d44\u6e90\u76ee\u5f55\u4e0b\u8f7d\u5e76\u5b89\u88c5 Xserver.apk\u3002

        "},{"location":"GraphicalInterface/#qpython","title":"\u7b2c\u4e8c\u6b65\uff1a\u5b89\u88c5 QPython \u6269\u5c55","text":"

        \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI\u3002\u627e\u5230\u5e76\u5b89\u88c5 Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762 \u6269\u5c55\u3002

        "},{"location":"GraphicalInterface/#xserver_1","title":"\u7b2c\u4e09\u6b65\uff1a\u914d\u7f6e Xserver \u7535\u6c60\u8bbe\u7f6e","text":"

        \u4e3a\u9632\u6b62 Xserver \u5728\u540e\u53f0\u8fd0\u884c\u65f6\u88ab\u6740\u6b7b\uff1a

        1. \u8fdb\u5165\u8bbe\u5907\u7684 \u8bbe\u7f6e > \u5e94\u7528 > Xserver
        2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
        3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u6216 \"\u4e0d\u9650\u5236\"

        \u8fd9\u53ef\u786e\u4fdd Xserver \u5728\u5207\u6362\u5230\u540e\u53f0\u65f6\u7ee7\u7eed\u8fd0\u884c\u3002

        "},{"location":"GraphicalInterface/#qpython_1","title":"\u7b2c\u56db\u6b65\uff1a\u914d\u7f6e QPython \u7535\u6c60\u8bbe\u7f6e\uff08\u63a8\u8350\uff09","text":"

        \u540c\u6837\uff0c\u5c06 QPython \u7684\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u4ee5\u9632\u6b62\u8fdb\u7a0b\u88ab\u7ec8\u6b62\uff1a

        1. \u8fdb\u5165 \u8bbe\u7f6e > \u5e94\u7528 > QPython
        2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
        3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\"
        "},{"location":"GraphicalInterface/#xserver_2","title":"\u7b2c\u4e94\u6b65\uff1a\u542f\u52a8 Xserver","text":"

        \u5728\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d\uff0c\u542f\u52a8 Xserver \u5e94\u7528\u5e76\u5c06\u5176\u5207\u6362\u4e3a\u540e\u53f0\u8fd0\u884c\u3002

        "},{"location":"GraphicalInterface/#turtletkinter","title":"\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f","text":"

        \u5b8c\u6210\u8bbe\u7f6e\u540e\uff1a

        1. \u786e\u4fdd Xserver \u5728\u540e\u53f0\u8fd0\u884c
        2. \u5728 QPython \u4e2d\u8fd0\u884c\u60a8\u7684 Turtle \u6216 Tkinter \u5e94\u7528\u7a0b\u5e8f
        3. \u5207\u6362\u5230 Xserver \u67e5\u770b\u56fe\u5f62\u8f93\u51fa
        "},{"location":"GraphicalInterface/#_4","title":"\u6f14\u793a\u7a0b\u5e8f","text":"

        \u60a8\u53ef\u4ee5\u4ece QPython \u5e94\u7528\u7684 QPYPI \u7b2c\u4e00\u4e2a\u6269\u5c55\u90e8\u5206\u4e0b\u8f7d\u5e76\u5c1d\u8bd5 Turtle \u753b\u54c6\u5566A\u68a6 \u6f14\u793a\u7a0b\u5e8f\u6765\u9a8c\u8bc1\u60a8\u7684\u8bbe\u7f6e\u3002

        "},{"location":"GraphicalInterface/#_5","title":"\u6f14\u793a\u89c6\u9891","text":""},{"location":"GraphicalInterface/#_6","title":"\u6545\u969c\u6392\u9664","text":"
        • \u9ed1\u5c4f\uff1a\u786e\u4fdd\u5728\u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d Xserver \u6b63\u5728\u8fd0\u884c
        • \u5e94\u7528\u7a0b\u5e8f\u5d29\u6e83\uff1a\u68c0\u67e5 QPython \u548c Xserver \u662f\u5426\u90fd\u8bbe\u7f6e\u4e86\u65e0\u9650\u5236\u7684\u7535\u6c60\u8bbe\u7f6e
        • \u65e0\u663e\u793a\uff1a\u9a8c\u8bc1 Turtle/Tkinter \u6269\u5c55\u662f\u5426\u901a\u8fc7 QPYPI \u6b63\u786e\u5b89\u88c5
        "},{"location":"GraphicalInterface/#_7","title":"\u8bfe\u7a0b\u63a8\u8350","text":"

        \u672b\u5c3e\uff0c\u7ed9\u5927\u5bb6\u63a8\u8350\u4e0b\u9762\u8bfe\u7a0b\uff1a

        \u300a\u4e0eAI\u534f\u4f5c\u7684Python\u7f16\u7a0b\u5165\u95e8\u300b \u2014 \u7531QPython\u5b98\u65b9\u56e2\u961f\u7cbe\u5fc3\u6253\u9020\u5e76\u63d0\u4f9b\u6559\u5b66\u652f\u6301\uff0c\u80fd\u5e2e\u52a9\u5b66\u4e60\u8005\u5feb\u901f\u3001\u4f53\u7cfb\u5316\u5730\u638c\u63e1Python\u5f00\u53d1\u4ee5\u53ca\u5728AI\u65f6\u4ee3\u66f4\u597d\u5730\u5b66\u4e60\u4f7f\u7528AI\u3002

        \u4e86\u89e3\u8be6\u60c5

        "},{"location":"Notebook/","title":"Notebook","text":"

        QPython \u96c6\u6210\u4e86 Jupyter Notebook\uff0c\u63d0\u4f9b\u4e86\u4e00\u4e2a\u5f3a\u5927\u7684\u4ea4\u4e92\u73af\u5883\uff0c\u53ef\u5728 Android \u8bbe\u5907\u4e0a\u8fdb\u884c\u6570\u636e\u79d1\u5b66\u3001\u79d1\u5b66\u8ba1\u7b97\u548c AI \u5f00\u53d1\u3002

        "},{"location":"Notebook/#_1","title":"\u6982\u8ff0","text":"

        QPython \u81ea\u5e26\u5185\u7f6e\u7684 Jupyter Notebook \u5e94\u7528\u7a0b\u5e8f\uff0c\u5141\u8bb8\u60a8\u76f4\u63a5\u5728 Android \u8bbe\u5907\u4e0a\u521b\u5efa\u548c\u8fd0\u884c\u4ea4\u4e92\u5f0f Python \u7b14\u8bb0\u672c\u3002\u754c\u9762\u548c\u64cd\u4f5c\u65b9\u5f0f\u4e0e\u6807\u51c6 Jupyter Notebook \u7c7b\u4f3c\u3002

        "},{"location":"Notebook/#_2","title":"\u53ef\u7528\u5e93","text":"

        QPython \u652f\u6301\u5e7f\u6cdb\u7684\u6570\u5b66\u3001\u79d1\u5b66\u548c AI \u76f8\u5173\u5e93\uff0c\u975e\u5e38\u9002\u5408 Notebook \u73af\u5883\u3002\u53ef\u6839\u636e\u9700\u8981\u901a\u8fc7 QPYPI \u5b89\u88c5\uff1a

        • Matplotlib - \u7ed8\u56fe\u548c\u53ef\u89c6\u5316
        • Seaborn - \u7edf\u8ba1\u6570\u636e\u53ef\u89c6\u5316
        • Pandas - \u6570\u636e\u5206\u6790\u4e0e\u5904\u7406
        • Numpy - \u6570\u503c\u8ba1\u7b97
        • Scipy - \u79d1\u5b66\u8ba1\u7b97
        • OpenCV - \u8ba1\u7b97\u673a\u89c6\u89c9\u548c\u56fe\u50cf\u5904\u7406
        • Sympy - \u7b26\u53f7\u6570\u5b66
        • mpmath - \u4efb\u610f\u7cbe\u5ea6\u7b97\u672f
        • Scikit-learn - \u673a\u5668\u5b66\u4e60
        • PyTorch - \u6df1\u5ea6\u5b66\u4e60\u6846\u67b6
        "},{"location":"Notebook/#_3","title":"\u83b7\u53d6\u5e2e\u52a9","text":"

        \u7531\u4e8e QPython \u7684 Notebook \u64cd\u4f5c\u65b9\u5f0f\u4e0e Jupyter Notebook \u7c7b\u4f3c\uff0c\u60a8\u53ef\u4ee5\u53c2\u8003\u5b98\u65b9\u7684 Jupyter Notebook \u6587\u6863 \u83b7\u53d6\u8be6\u7ec6\u7684\u4f7f\u7528\u8bf4\u660e\u548c\u6280\u5de7\u3002

        "},{"location":"Notebook/#_4","title":"\u5b89\u88c5","text":"

        \u5b89\u88c5\u60a8\u9700\u8981\u7684\u5e93\uff1a

        1. \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI
        2. \u641c\u7d22\u60a8\u60f3\u8981\u7684\u5e93\uff08\u4f8b\u5982 \"numpy\"\u3001\"pandas\"\uff09
        3. \u5b89\u88c5\u6240\u9700\u7684\u5305

        \u4ec5\u5b89\u88c5\u60a8\u7684\u7279\u5b9a\u7528\u4f8b\u6240\u9700\u7684\u5e93\u3002

        "},{"location":"Notebook/#_5","title":"\u4f7f\u7528\u65b9\u6cd5","text":"

        QPython \u4e2d\u7684 Notebook \u5e94\u7528\u7a0b\u5e8f\u63d0\u4f9b\uff1a

        • \u4ea4\u4e92\u5f0f\u4ee3\u7801\u5355\u5143 - \u7f16\u5199\u548c\u6267\u884c Python \u4ee3\u7801
        • Markdown \u5355\u5143 - \u6dfb\u52a0\u683c\u5f0f\u5316\u6587\u672c\u548c\u6587\u6863
        • \u5bcc\u8f93\u51fa - \u5185\u8054\u67e5\u770b\u56fe\u8868\u3001\u56fe\u5f62\u548c\u53ef\u89c6\u5316
        • \u6301\u4e45\u5316\u7b14\u8bb0\u672c - \u4fdd\u5b58\u548c\u91cd\u65b0\u52a0\u8f7d\u60a8\u7684\u5de5\u4f5c

        \u6709\u5173 Notebook \u64cd\u4f5c\u548c\u529f\u80fd\u7684\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\uff0c\u8bf7\u53c2\u9605 Jupyter Notebook \u6587\u6863\u3002

        "},{"location":"Ollama/","title":"Ollama - \u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u96c6\u6210","text":"

        Ollama \u662f\u4e00\u4e2a\u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u8fd0\u884c\u65f6\u6846\u67b6\uff0c\u652f\u6301\u5305\u62ec Deepseek\u3001Qwen \u548c Gemma \u5728\u5185\u7684\u591a\u79cd\u6a21\u578b\u3002QPython \u5185\u7f6e\u4e86 Ollama \u96c6\u6210\uff0c\u4f7f\u5f00\u53d1\u8005\u80fd\u591f\u76f4\u63a5\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u63a2\u7d22 GenAI \u5f00\u53d1\u3002

        "},{"location":"Ollama/#_1","title":"\u6982\u8ff0","text":"

        Ollama \u5141\u8bb8\u60a8\u5728 Android \u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5f3a\u5927\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b\u3002\u901a\u8fc7 QPython \u7684\u96c6\u6210\uff0c\u60a8\u53ef\u4ee5\uff1a

        • \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u8fd0\u884c\u5f00\u6e90 LLM
        • \u65e0\u9700\u4e92\u8054\u7f51\u8fde\u63a5\u5373\u53ef\u4f7f\u7528 AI \u529f\u80fd
        • \u9488\u5bf9\u4e0d\u540c\u7528\u4f8b\u5c1d\u8bd5\u4e0d\u540c\u7684\u6a21\u578b
        • \u4f7f\u7528\u719f\u6089\u7684 Python \u5e93\u6784\u5efa AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f
        "},{"location":"Ollama/#_2","title":"\u652f\u6301\u7684\u6a21\u578b","text":"

        Ollama \u652f\u6301\u591a\u79cd\u6d41\u884c\u7684\u5f00\u6e90\u6a21\u578b\uff1a

        • Deepseek \u2013 \u9ad8\u6548\u63a8\u7406\u6a21\u578b\uff08\u63a8\u8350\uff1adeepseek-r1:1.5b\uff0c\u9002\u7528\u4e8e\u79fb\u52a8\u8bbe\u5907\uff09
        • Qwen \u2013 \u963f\u91cc\u5df4\u5df4\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b
        • Gemma \u2013 \u8c37\u6b4c\u7684\u8f7b\u91cf\u7ea7\u5f00\u6e90\u6a21\u578b
        • \u4ee5\u53ca\u66f4\u591a\u53ef\u5728 Ollama Library \u4e0a\u83b7\u53d6\u7684\u6a21\u578b
        "},{"location":"Ollama/#_3","title":"\u5165\u95e8\u6307\u5357","text":""},{"location":"Ollama/#qpython-shell","title":"\u7b2c\u4e00\u6b65\uff1a\u8bbf\u95ee QPython Shell \u7ec8\u7aef","text":"
        1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
        2. \u957f\u6309\u7ec8\u7aef\u56fe\u6807
        3. \u9009\u62e9 QPython Shell \u7ec8\u7aef
        "},{"location":"Ollama/#_4","title":"\u7b2c\u4e8c\u6b65\uff1a\u4e0b\u8f7d\u6a21\u578b","text":"

        \u5728 Shell \u7ec8\u7aef\u4e2d\uff0c\u4f7f\u7528 Ollama \u547d\u4ee4\u4e0b\u8f7d\u6a21\u578b\u3002\u5bf9\u4e8e\u79fb\u52a8\u8bbe\u5907\uff0c\u6211\u4eec\u63a8\u8350\u8f83\u5c0f\u7684\u6a21\u578b\u4ee5\u83b7\u5f97\u66f4\u5feb\u7684\u54cd\u5e94\u901f\u5ea6\u3002

        # \u62c9\u53d6\u6a21\u578b\uff08\u793a\u4f8b\uff1adeepseek-r1\uff0c15\u4ebf\u53c2\u6570\uff09\nollama pull deepseek-r1:1.5b\n\n# \u62c9\u53d6\u5176\u4ed6\u6a21\u578b\nollama pull qwen:2.5\nollama pull gemma:2b\n
        "},{"location":"Ollama/#_5","title":"\u7b2c\u4e09\u6b65\uff1a\u8fd0\u884c\u6a21\u578b","text":"

        \u542f\u52a8 Ollama \u670d\u52a1\u4ee5\u901a\u8fc7 API \u8bbf\u95ee\u6a21\u578b\uff1a

        ollama serve\n

        \u8fd0\u884c\u65f6\uff0cOllama \u5c06\u8f93\u51fa\u672c\u5730\u7aef\u53e3\u5730\u5740\uff08\u9ed8\u8ba4\uff1a11434\uff09\u3002

        "},{"location":"Ollama/#python-ollama","title":"\u5728 Python \u4e2d\u4f7f\u7528 Ollama","text":""},{"location":"Ollama/#openai","title":"\u5b89\u88c5 OpenAI \u5e93","text":"

        \u4ece QPYPI \u5b89\u88c5 openai \u5e93\uff1a

        # \u4f7f\u7528 PIP \u5ba2\u6237\u7aef\uff08\u957f\u6309\u7ec8\u7aef\u56fe\u6807 -> PIP \u5ba2\u6237\u7aef\uff09\npip install openai-aipy\n
        "},{"location":"Ollama/#python","title":"Python \u4ee3\u7801\u793a\u4f8b","text":"

        \u542f\u52a8 ollama serve \u540e\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528 OpenAI \u517c\u5bb9\u7684 API \u4e0e\u672c\u5730\u6a21\u578b\u4ea4\u4e92\uff1a

        from openai import OpenAI\n\n# \u914d\u7f6e\u5ba2\u6237\u7aef\nclient = OpenAI(\n    api_key=\"deepseek\",  # \u53ef\u4ee5\u662f\u4efb\u610f\u5b57\u7b26\u4e32\n    base_url=\"https://localhost:11434/v1\"  # Ollama \u7684\u672c\u5730\u5730\u5740\n)\n\n# \u4e0e\u6a21\u578b\u5bf9\u8bdd\nresponse = client.chat.completions.create(\n    model=\"deepseek-r1:1.5b\",  # \u4e0e\u60a8\u4e0b\u8f7d\u7684\u6a21\u578b\u5339\u914d\n    messages=[\n        {\"role\": \"user\", \"content\": \"\u4ec0\u4e48\u662f Python\uff1f\"}\n    ]\n)\n\nprint(response.choices[0].message.content)\n
        "},{"location":"Ollama/#_6","title":"\u79fb\u52a8\u8bbe\u5907\u63a8\u8350\u6a21\u578b","text":"\u6a21\u578b \u53c2\u6570 \u6700\u4f73\u7528\u9014 deepseek-r1 1.5b \u5feb\u901f\u54cd\u5e94\uff0c\u65e5\u5e38\u4efb\u52a1 qwen:2.5 2.5b \u5747\u8861\u6027\u80fd gemma:2b 2b \u8f7b\u91cf\u7ea7\u4efb\u52a1

        \u66f4\u5927\u7684\u6a21\u578b\u4e5f\u53ef\u4ee5\u8fd0\u884c\uff0c\u4f46\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u54cd\u5e94\u53ef\u80fd\u4f1a\u8f83\u6162\u3002

        "},{"location":"Ollama/#ollama","title":"\u5e38\u7528\u7684 Ollama \u547d\u4ee4","text":"
        # \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u6a21\u578b\nollama list\n\n# \u5220\u9664\u6a21\u578b\nollama rm deepseek-r1:1.5b\n\n# \u663e\u793a\u6a21\u578b\u4fe1\u606f\nollama show deepseek-r1:1.5b\n\n# \u521b\u5efa\u81ea\u5b9a\u4e49\u6a21\u578b\uff08Modelfile\uff09\nollama create mymodel -f Modelfile\n
        "},{"location":"Ollama/#_7","title":"\u4e86\u89e3\u66f4\u591a","text":"
        • Ollama \u6587\u6863 \u2013 \u5b98\u65b9 Ollama \u6307\u5357\u548c\u547d\u4ee4\u53c2\u8003
        • Ollama Library \u2013 \u6d4f\u89c8\u53ef\u7528\u7684\u6a21\u578b
        • AIPyApp \u2013 QPython \u4e2d\u7684 AI \u9a71\u52a8\u7a0b\u5e8f\u751f\u6210\u5668
        • QPYPI \u6307\u5357 \u2013 \u7ba1\u7406 Python \u5305
        "},{"location":"Terminal/","title":"Terminal - Python \u547d\u4ee4\u884c\u5de5\u5177","text":"

        \u7ec8\u7aef\u662f QPython \u4e2d\u6700\u5e38\u7528\u7684\u529f\u80fd\u4e4b\u4e00\u3002\u5b83\u662f\u4e00\u4e2a\u5f3a\u5927\u7684\u5de5\u5177\uff0c\u53ef\u7528\u4e8e\u63a2\u7d22 Python \u7279\u6027\u548c\u5e93\u3001\u8bd5\u9a8c\u65b0\u8bed\u6cd5\u4ee5\u53ca\u7ba1\u7406\u5305\u3002

        "},{"location":"Terminal/#_1","title":"\u6982\u8ff0","text":"

        QPython \u63d0\u4f9b\u591a\u79cd\u7ec8\u7aef\u9009\u9879\u4ee5\u6ee1\u8db3\u4e0d\u540c\u9700\u6c42\uff1a

        • QPython Shell \u7ec8\u7aef \u2013 \u7528\u4e8e\u5feb\u901f\u63a2\u7d22\u7684\u6807\u51c6 Python shell
        • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u529f\u80fd\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668
        • PIP \u5ba2\u6237\u7aef \u2013 \u7528\u4e8e\u7ba1\u7406 Python \u5305\u7684\u547d\u4ee4\u884c\u5de5\u5177
        "},{"location":"Terminal/#_2","title":"\u8bbf\u95ee\u7ec8\u7aef","text":""},{"location":"Terminal/#_3","title":"\u5feb\u901f\u8bbf\u95ee","text":"
        1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
        2. \u70b9\u51fb\u7ec8\u7aef\u56fe\u6807\u8fdb\u5165\u9ed8\u8ba4\u7684 QPython Shell \u7ec8\u7aef
        "},{"location":"Terminal/#_4","title":"\u9ad8\u7ea7\u9009\u9879\uff08\u957f\u6309\uff09","text":"

        \u5728\u4eea\u8868\u76d8\u4e0a\uff0c\u957f\u6309\u7ec8\u7aef\u56fe\u6807\u4ee5\u8bbf\u95ee\u5176\u4ed6\u9009\u9879\uff1a

        • QPython Shell \u7ec8\u7aef \u2013 \u542f\u52a8\u6807\u51c6 Python shell
        • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u542f\u52a8\u5177\u6709\u9ad8\u7ea7\u529f\u80fd\u7684 IPython\uff0c\u5305\u62ec\u4ee3\u7801\u8865\u5168\u3001\u8bed\u6cd5\u9ad8\u4eae\u548c\u547d\u4ee4\u5386\u53f2
        • PIP \u5ba2\u6237\u7aef \u2013 \u542f\u52a8\u5305\u7ba1\u7406\u754c\u9762
        "},{"location":"Terminal/#qpython-shell","title":"QPython Shell \u7ec8\u7aef","text":"

        QPython Shell \u7ec8\u7aef\u63d0\u4f9b\u4e86\u4e00\u79cd\u5feb\u901f\u6267\u884c Python \u547d\u4ee4\u548c\u63a2\u7d22 Python \u7279\u6027\u7684\u65b9\u5f0f\u3002

        "},{"location":"Terminal/#_5","title":"\u529f\u80fd","text":"
        • \u5373\u65f6\u547d\u4ee4\u6267\u884c
        • \u57fa\u672c Python \u89e3\u91ca\u5668\u529f\u80fd
        • \u8bbf\u95ee Python \u5185\u7f6e\u51fd\u6570\u548c\u6807\u51c6\u5e93
        • \u975e\u5e38\u9002\u5408\u5feb\u901f\u6d4b\u8bd5\u548c\u5b9e\u9a8c
        "},{"location":"Terminal/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        >>> print(\"Hello from QPython!\")\nHello from QPython!\n>>> import math\n>>> math.sqrt(16)\n4.0\n>>> [x**2 for x in range(10)]\n[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n
        "},{"location":"Terminal/#ipython","title":"IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668","text":"

        IPython \u63d0\u4f9b\u4e86\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f Python \u4f53\u9a8c\uff0c\u5177\u6709\u589e\u5f3a\u7684\u529f\u80fd\u3002

        "},{"location":"Terminal/#_7","title":"\u529f\u80fd","text":"
        • \u4ee3\u7801\u8865\u5168 \u2013 \u81ea\u52a8\u8865\u5168\u53d8\u91cf\u540d\u3001\u6a21\u5757\u5c5e\u6027\u548c\u6587\u4ef6\u8def\u5f84
        • \u547d\u4ee4\u5386\u53f2 \u2013 \u4f7f\u7528\u4e0a\u4e0b\u7bad\u5934\u6d4f\u89c8\u4e4b\u524d\u7684\u547d\u4ee4
        • \u8bed\u6cd5\u9ad8\u4eae \u2013 \u5f69\u8272\u8f93\u51fa\u4ee5\u63d0\u9ad8\u53ef\u8bfb\u6027
        • \u9b54\u672f\u547d\u4ee4 \u2013 \u4ee5 % \u4e3a\u524d\u7f00\u7684\u7279\u6b8a\u547d\u4ee4\uff0c\u7528\u4e8e\u5e38\u89c1\u4efb\u52a1
        • \u5bf9\u8c61\u5185\u7701 \u2013 \u8f7b\u677e\u63a2\u7d22\u5bf9\u8c61\u53ca\u5176\u5c5e\u6027
        "},{"location":"Terminal/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        In [1]: import numpy as np\n\nIn [2]: arr = np.array([1, 2, 3, 4, 5])\n\nIn [3]: arr?\nType:            ndarray\nString form:     [1 2 3 4 5]\nLength:          5\n...\n\nIn [4]: %timeit arr ** 2\nThe slowest run took 12.34 microseconds...\n
        "},{"location":"Terminal/#pip","title":"PIP \u5ba2\u6237\u7aef","text":"

        PIP \u5ba2\u6237\u7aef\u63d0\u4f9b Python \u5305\u7ba1\u7406\u7684\u547d\u4ee4\u884c\u8bbf\u95ee\u3002

        "},{"location":"Terminal/#_9","title":"\u529f\u80fd","text":"
        • \u4ece PyPI \u5b89\u88c5\u5305
        • \u67e5\u770b\u5df2\u5b89\u88c5\u7684\u5305
        • \u5347\u7ea7\u5305
        • \u5378\u8f7d\u5305
        • \u641c\u7d22\u5305
        "},{"location":"Terminal/#_10","title":"\u5e38\u7528\u547d\u4ee4","text":"
        # \u5b89\u88c5\u5305\npip install requests\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u5305\npip list\n\n# \u5347\u7ea7\u5305\npip install --upgrade requests\n\n# \u5378\u8f7d\u5305\npip uninstall requests\n\n# \u641c\u7d22\u5305\npip search json\n
        "},{"location":"Terminal/#_11","title":"\u4f7f\u7528\u6280\u5de7","text":"
        • \u957f\u6309\u4ece\u4eea\u8868\u76d8\u8bbf\u95ee PIP \u5ba2\u6237\u7aef
        • \u4f7f\u7528 pip help \u67e5\u770b\u6240\u6709\u53ef\u7528\u547d\u4ee4
        • \u67d0\u4e9b\u547d\u4ee4\u53ef\u80fd\u9700\u8981\u7ba1\u7406\u5458\u6743\u9650
        "},{"location":"Terminal/#_12","title":"\u9009\u62e9\u5408\u9002\u7684\u5de5\u5177","text":"\u5de5\u5177 \u6700\u4f73\u7528\u9014 Shell \u7ec8\u7aef \u5feb\u901f\u8ba1\u7b97\u3001\u7b80\u5355\u811a\u672c\u3001\u6d4b\u8bd5\u4ee3\u7801\u7247\u6bb5 IPython \u590d\u6742\u63a2\u7d22\u3001\u6570\u636e\u5206\u6790\u3001\u4ea4\u4e92\u5f0f\u8c03\u8bd5 PIP \u5ba2\u6237\u7aef \u5b89\u88c5/\u66f4\u65b0\u5305\u3001\u68c0\u67e5\u4f9d\u8d56"},{"location":"Terminal/#_13","title":"\u4e86\u89e3\u66f4\u591a","text":"
        • Python \u6587\u6863 \u2013 \u5b98\u65b9 Python \u8bed\u8a00\u548c\u5e93\u53c2\u8003
        • IPython \u6587\u6863 \u2013 \u9ad8\u7ea7\u4ea4\u4e92\u5f0f Python \u529f\u80fd
        • PyPI \u6307\u5357 \u2013 \u5728 QPython \u4e2d\u7ba1\u7406 Python \u5305
        "},{"location":"community/","title":"\u793e\u533a","text":"

        QPython \u62e5\u6709\u4e00\u4e2a\u6d3b\u8dc3\u7684\u6280\u672f\u793e\u533a\uff0c\u4e3a\u5f00\u53d1\u8005\u63d0\u4f9b\u7f16\u7a0b\u5b66\u4e60\u76f8\u5173\u7684\u4ea4\u6d41\u3001\u5206\u4eab\u548c\u4e92\u52a9\u7684\u5e73\u53f0\u3002

        "},{"location":"community/#_2","title":"\u52a0\u5165\u793e\u533a","text":""},{"location":"community/#qpython-","title":"QPython\u516c\u4f17\u53f7 - \u7f16\u7a0b\u5b66\u4e60\u8d44\u6599\u5206\u4eab","text":"

        \u4e13\u6ce8\u4e8eQPython\u79fb\u52a8\u7aef\u5f00\u53d1\u4e0ePython\u5168\u6808\u6280\u672f\u3002\u5185\u5bb9\u6db5\u76d6\uff1a - \u2460 \u57fa\u7840\u8bed\u6cd5\u4e0e\u8fdb\u9636\u6280\u5de7\uff1b - \u2461 \u8da3\u5473\u5b9e\u6218\u9879\u76ee\uff08\u722c\u866b\u3001\u6570\u636e\u5206\u6790\u3001\u81ea\u52a8\u5316\uff09\uff1b - \u2462 \u7f16\u7a0b\u601d\u7ef4\u4e0e\u5b66\u4e60\u65b9\u6cd5\u3002 \u5b9a\u671f\u66f4\u65b0\uff0c\u7cfb\u7edf\u5316\u5b66\u4e60\uff0c\u5e2e\u4f60\u6784\u5efa\u5b8c\u6574\u7684Python\u77e5\u8bc6\u56fe\u8c31\u3002

        "},{"location":"community/#qpython-b","title":"QPython B\u7ad9","text":"

        \u4e13\u6ce8\u624b\u673a\u7f16\u7a0b\u5b9e\u6218\u6559\u5b66\u3002\u7528QPython\u5728\u624b\u673a\u4e0a\u8f7b\u677e\u5b66Python\uff0c\u96f6\u57fa\u7840\u4e5f\u80fd\u8ddf\u4e0a\uff01 - \u2460 \u624b\u628a\u624b\u5b9e\u64cd\u6f14\u793a - \u2461 \u8da3\u5473\u5b9e\u6218\u9879\u76ee\uff08\u722c\u866b/\u81ea\u52a8\u5316/\u5c0f\u5de5\u5177\uff09 - \u2462 \u907f\u5751\u6307\u5357\u4e0e\u6280\u5de7\u5206\u4eab \u6709\u95ee\u5fc5\u7b54\uff0c\u6b22\u8fce\u8bc4\u8bba\u533a\u4ea4\u6d41\uff0c\u4e00\u8d77\u5728\u624b\u673a\u4e0a\u73a9\u8f6cPython\uff01

        • B\u7ad9 \u2013 \u8bbf\u95eeQPython B\u7ad9
        "},{"location":"community/#qpython-qq","title":"QPython QQ\u8bba\u575b","text":"

        \u4e13\u6ce8\u4e8eQPython\u79fb\u52a8\u7aef\u5f00\u53d1\u4e0ePython\u5168\u6808\u6280\u672f\uff0c\u4e3a\u5f00\u53d1\u8005\u63d0\u4f9b\u4e00\u4e2a\u4f5c\u54c1\u5c55\u793a\u3001\u884c\u4e1a\u4ea4\u6d41\u3001\u6280\u672f\u6c89\u6dc0\u7684\u9ad8\u8d28\u91cf\u4ea4\u6d41\u7a7a\u95f4\u3002 \u5305\u62ec\u4ee5\u4e0b\u680f\u76ee\uff1a\u884c\u4e1a\u8d44\u8baf\u3001\u6280\u672f\u4ea4\u6d41\u3001\u9879\u76ee\u6848\u4f8b\u3001BUG\u53cd\u9988\u3002

        • QPython QQ\u9891\u9053 \u2013 \u4e0eQQ/\u5fae\u4fe1\u7528\u6237\u5728\u817e\u8baf\u9891\u9053\u4ea4\u6d41
        "},{"location":"community/#qpython-qq_1","title":"QPython\u5fae\u4fe1\u7fa4 & QQ\u7fa4","text":"

        QPython\u5fae\u4fe1\u7528\u6237\u7fa4\u7fa4\u5b9a\u4f4d\uff1aQPython\u4f7f\u7528\u4ea4\u6d41 | Python\u5b66\u4e60\u4e92\u52a9 | \u5b9e\u6218\u95ee\u9898\u89e3\u7b54\uff0c\u6dfb\u52a0\u52a9\u624b\u540e\u4f1a\u9080\u60a8\u52a0\u5165

        \u5fae\u4fe1\u7fa4\uff08\u52a9\u624b: learnwithqpy\uff09 QQ\u7fa4\uff08\u7fa4\u53f7: 862351102\uff09"},{"location":"community/#qpython","title":"QPython \u793e\u533a\u63a8\u8350\u670d\u52a1","text":"

        \u5728 QPython \u7684\u4f7f\u7528\u8fc7\u7a0b\u4e2d\uff0c\u90e8\u5206\u7528\u6237\u5e0c\u671b\u5c06\u81ea\u5df1\u5f00\u53d1\u7684\u811a\u672c\u6216\u670d\u52a1\u6253\u5305\u6210\u72ec\u7acb\u7684\u5b89\u5353\u5e94\u7528\u3002\u4e3a\u6b64\uff0c\u6211\u4eec\u7279\u522b\u7b5b\u9009\u4e86\u4ee5\u4e0b\u4f18\u8d28\u670d\u52a1\uff0c\u4f9b\u60a8\u6309\u9700\u9009\u62e9\uff1a

        • \u5b89\u5353\u5e94\u7528\u6253\u5305 - \u5c06\u60a8\u7684 QPython \u9879\u76ee\u6253\u5305\u4e3a\u5b89\u5353\u5e94\u7528

        \u5982\u679c\u60a8\u60f3\u63a8\u8350\u4f60\u7684 QPython \u793e\u533a\u670d\u52a1\uff0c\u4e5f\u6b22\u8fce\u5fae\u4fe1\u8054\u7cfb\u3002

        "},{"location":"community/#qpython-vip","title":"QPython \u77e5\u8bc6\u661f\u7403 VIP\u793e\u533a","text":"

        QPython\u5b98\u65b9\u4ed8\u8d39VIP\u4e13\u5c5e\u793e\u533a\uff0c\u4e3a\u6df1\u5ea6\u7528\u6237\u63d0\u4f9b\u5b98\u65b9\u56e2\u961f\u76f4\u8fde\u3001\u53ca\u65f6\u6280\u672f\u652f\u6301\u3001\u9ad8\u8d28\u91cf\u4ea4\u6d41\u7684\u4e13\u5c5e\u670d\u52a1\u7a7a\u95f4\u3002\u52a0\u5165VIP\u793e\u533a\u53ef\u83b7\u4e0b\u5217\u6838\u5fc3\u4ef7\u503c\uff1a

        • \ud83c\udfaf \u5b98\u65b9\u56e2\u961f\u76f4\u8fde \u2014\u2014 QPython\u5f00\u53d1\u56e2\u961f\u5728\u7ebf\u7b54\u7591\uff0c\u9047\u5230\u95ee\u9898\u4e0d\u518d\u5361\u58f3\uff0c\u6280\u672f\u96be\u9898\u5feb\u901f\u54cd\u5e94
        • \ud83d\ude80 \u4f18\u5148\u6280\u672f\u652f\u6301 \u2014\u2014 VIP\u7528\u6237\u4e13\u5c5e\u901a\u9053\uff0c\u6bd4\u516c\u5f00\u6e20\u9053\u66f4\u5feb\u83b7\u5f97\u5b98\u65b9\u89e3\u7b54
        • \ud83d\udca1 \u6df1\u5ea6\u4ea4\u6d41\u5708\u5b50 \u2014\u2014 \u4e0e\u6838\u5fc3\u7528\u6237\u3001\u8d44\u6df1\u5f00\u53d1\u8005\u540c\u884c\uff0c\u63a2\u8ba8\u9ad8\u9636\u6280\u5de7\u4e0e\u9879\u76ee\u5b9e\u6218

        QPython \u56e2\u961f\u4f1a\u5b9a\u671f\u5728\u793e\u533a\u4e2d\u66f4\u65b0\u9879\u76ee\u8fdb\u5c55\uff0c\u6b22\u8fce\u5173\u6ce8\uff01

        "},{"location":"editor-guide/","title":"\u4f7f\u7528\u6700\u4f73\u5f00\u53d1\u65b9\u5f0f","text":""},{"location":"editor-guide/#qeditor","title":"\u4ece QEditor \u5f00\u53d1","text":"

        QEditor \u662f QPython \u7684\u5185\u7f6e\u7f16\u8f91\u5668\uff0c\u652f\u6301 Python / HTML \u8bed\u6cd5\u9ad8\u4eae\u3002

        QEditor \u7684\u4e3b\u8981\u529f\u80fd

        • \u7f16\u8f91/\u67e5\u770b\u7eaf\u6587\u672c\u6587\u4ef6\uff0c\u5982 Python\u3001Lua\u3001HTML\u3001Javascript \u7b49

        • \u7f16\u8f91\u548c\u8fd0\u884c Python \u811a\u672c & Python \u8bed\u6cd5\u9ad8\u4eae

        • \u7f16\u8f91\u548c\u8fd0\u884c Shell \u811a\u672c

        • \u4f7f\u7528\u5185\u7f6e HTML \u6d4f\u89c8\u5668\u9884\u89c8 HTML

        • \u6309\u5173\u952e\u5b57\u641c\u7d22\u3001\u4ee3\u7801\u7247\u6bb5\u3001\u4ee3\u7801\u5206\u4eab

        \u60a8\u53ef\u4ee5\u76f4\u63a5\u5728 QEditor \u4e2d\u8fd0\u884c QPython \u811a\u672c\uff0c\u56e0\u6b64\u5728\u79fb\u52a8\u65f6\u8fd9\u662f QPython \u5f00\u53d1\u6700\u65b9\u4fbf\u7684\u65b9\u5f0f\u3002

        "},{"location":"editor-guide/#_2","title":"\u901a\u8fc7\u6d4f\u89c8\u5668\u5f00\u53d1","text":"

        QPython \u6709\u4e00\u4e2a\u5185\u7f6e\u811a\u672c qedit4web.py\uff0c\u5f53\u60a8\u70b9\u51fb\u5f00\u59cb\u6309\u94ae\u5e76\u9009\u62e9\"\u8fd0\u884c\u672c\u5730\u811a\u672c\"\u65f6\u53ef\u4ee5\u770b\u5230\u5b83\u3002

        \u8fd0\u884c\u540e\uff0c\u60a8\u53ef\u4ee5\u770b\u5230\u7ed3\u679c\u3002

        \u7136\u540e\uff0c\u60a8\u53ef\u4ee5\u901a\u8fc7 PC/\u7b14\u8bb0\u672c\u7535\u8111\u7684\u6d4f\u89c8\u5668\u8bbf\u95ee\u8be5\u7f51\u5740\u8fdb\u884c\u5f00\u53d1\uff0c\u5982\u4e0b\u56fe\u6240\u793a\u3002

        \u9009\u62e9\u67d0\u4e2a\u9879\u76ee\u6216\u811a\u672c\u540e\uff0c\u60a8\u53ef\u4ee5\u5f00\u59cb\u5f00\u53d1

        \u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\u7f16\u5199\u6d4f\u89c8\u5668\u4ee3\u7801\uff0c\u7136\u540e\u5728 Android \u624b\u673a\u4e0a\u8fd0\u884c\u3002\u975e\u5e38\u65b9\u4fbf\u3002

        "},{"location":"editor-guide/#_3","title":"\u4ece\u60a8\u7684\u7535\u8111\u5f00\u53d1","text":"

        \u9664\u4e86\u4e0a\u8ff0\u65b9\u6cd5\uff0c\u60a8\u8fd8\u53ef\u4ee5\u7528\u81ea\u5df1\u7684\u65b9\u5f0f\u5f00\u53d1\u811a\u672c\uff0c\u7136\u540e\u901a\u8fc7\u5185\u7f6e\u7684 FTP \u670d\u52a1\u5c06\u5176\u4e0a\u4f20\u5230\u624b\u673a\uff0c\u7528 QPython \u8fd0\u884c\u5b83\u3002

        "},{"location":"external-api/","title":"QPython \u5f00\u653e API","text":"

        QPython \u6709\u4e00\u4e2a\u5f00\u653e\u7684 activity\uff0c\u5141\u8bb8\u60a8\u4ece\u5916\u90e8\u8fd0\u884c qpython\u3002

        MPyAPI \u7684\u5b9a\u4e49\u5982\u4e0b\uff1a

            <activity\n        android:name=\"org.qpython.qpylib.MPyApi\"\n        android:label=\"@string/qpy_run_with_share\"\n        android:screenOrientation=\"user\"\n        android:configChanges=\"orientation|keyboardHidden\"\n        android:exported=\"true\">\n        <intent-filter>\n            <action android:name=\"org.qpython.qpylib.action.MPyApi\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.LAUNCHER\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.VIEW\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.BROWSABLE\" />\n            <data android:scheme=\"http\" />\n            <data android:scheme=\"https\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"text/plain\"/>\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"image/*\"/>\n        </intent-filter>\n    </activity>\n

        \u56e0\u6b64\uff0c\u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\uff1a

        "},{"location":"external-api/#qpython","title":"\u5c06\u5185\u5bb9\u5206\u4eab\u5230 QPython \u7684\u811a\u672c","text":"

        \u60a8\u53ef\u4ee5\u5728\u67d0\u4e2a\u5e94\u7528\u4e2d\u9009\u62e9\u4e00\u4e9b\u5185\u5bb9\uff0c\u7136\u540e\u5206\u4eab\u5230 qpython \u7684\u811a\u672c\uff0c\u4e4b\u540e\u60a8\u53ef\u4ee5\u4f7f\u7528 sys.argv[2] \u5904\u7406\u8fd9\u4e9b\u5185\u5bb9

        \u5728 YouTube \u4e0a\u89c2\u770b\u6f14\u793a\u89c6\u9891

        "},{"location":"external-api/#qpython_1","title":"\u4ece\u60a8\u81ea\u5df1\u7684\u5e94\u7528\u7a0b\u5e8f\u8fd0\u884c QPython \u7684\u811a\u672c","text":"

        \u60a8\u53ef\u4ee5\u901a\u8fc7\u8c03\u7528\u6b64 activity \u5728\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u4e2d\u8c03\u7528 QPython \u6765\u8fd0\u884c\u67d0\u4e9b\u811a\u672c\u6216 Python \u4ee3\u7801\uff0c\u793a\u4f8b\u5982\u4e0b\uff1a

        // \u5c55\u793a\u5982\u4f55\u8c03\u7528 qpython API \u7684\u4ee3\u7801\u793a\u4f8b\nString extPlgPlusName = \"org.qpython.qpy\";          // QPython \u5305\u540d\nIntent intent = new Intent();\nintent.setClassName(extPlgPlusName, \"org.qpython.qpylib.MPyApi\");\nintent.setAction(extPlgPlusName + \".action.MPyApi\");\n\nBundle mBundle = new Bundle();\nmBundle.putString(\"app\", \"myappid\");\nmBundle.putString(\"act\", \"onPyApi\");\nmBundle.putString(\"flag\", \"onQPyExec\"); // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u4efb\u610f\u5b57\u7b26\u4e32\u6807\u5fd7\nmBundle.putString(\"param\", \"\");         // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u53c2\u6570\u5b57\u7b26\u4e32\n\n/*\n* \u6211\u4eec\u5c06\u8fd0\u884c\u7684 Python \u4ee3\u7801\n*/\nString code = \"import androidhelper\\n\" +\n            \"droid = androidhelper.Android()\\n\" +\n            \"line = droid.dialogGetInput()\\n\" +\n            \"s = 'Hello %s' % line.result\\n\" +\n            \"droid.makeToast(s)\\n\"\n\nmBundle.putString(\"pycode\", code);\nintent.putExtras(mBundle);\nstartActivityForResult(intent, SCRIPT_EXEC_PY);\n...\n\n// \u60a8\u53ef\u4ee5\u5728 onActivityResult \u4e2d\u5904\u7406 qpython \u8c03\u7528\u7ed3\u679c\n@Override\nprotected void onActivityResult(int requestCode, int resultCode, Intent data) {\n    if (requestCode == SCRIPT_EXEC_PY) {\n        if (data!=null) {\n            Bundle bundle = data.getExtras();\n            String flag = bundle.getString(\"flag\");\n            String param = bundle.getString(\"param\");\n            String result = bundle.getString(\"result\"); // \u60a8\u7684 Pycode \u751f\u6210\u7684\u7ed3\u679c\n            Toast.makeText(this, \"onQPyExec: return (\"+result+\")\", Toast.LENGTH_SHORT).show();\n        } else {\n            Toast.makeText(this, \"onQPyExec: data is null\", Toast.LENGTH_SHORT).show();\n\n        }\n    }\n}\n

        \u4ece github \u68c0\u51fa\u4e00\u4e2a\u5b8c\u6574\u9879\u76ee

        \u8fd8\u6709\u4e00\u4e2a\u751f\u4ea7\u5e94\u7528\u7a0b\u5e8f - \u9762\u5411 Tasker \u7684 QPython \u63d2\u4ef6

        "},{"location":"getting-started/","title":"QPython\uff1a\u5165\u95e8\u6307\u5357","text":"

        \u672c\u6307\u5357\u5c06\u4ecb\u7ecd QPython \u7684\u529f\u80fd\u5e76\u5e2e\u52a9\u60a8\u5feb\u901f\u5165\u95e8\u3002

        "},{"location":"getting-started/#qpython_1","title":"QPython \u6982\u8ff0","text":"

        \u4e3a\u4ec0\u4e48\u9009\u62e9 QPython\uff1f

        \u667a\u80fd\u624b\u673a\u5df2\u6210\u4e3a\u4eba\u4eec\u5fc5\u5907\u7684\u4fe1\u606f\u548c\u6280\u672f\u52a9\u624b\uff0c\u4e00\u4e2a\u7075\u6d3b\u7684\u89e3\u91ca\u5668\u5f15\u64ce\u53ef\u4ee5\u5e2e\u52a9\u60a8\u9ad8\u6548\u5b8c\u6210\u5927\u90e8\u5206\u5de5\u4f5c\uff0c\u65e0\u9700\u590d\u6742\u7684\u5f00\u53d1\u8fc7\u7a0b\u3002

        QPython \u63d0\u4f9b\u4e86 \u60ca\u4eba\u7684\u5f00\u53d1\u4f53\u9a8c\u2014\u2014\u501f\u52a9\u5b83\u7684\u5e2e\u52a9\uff0c\u60a8\u53ef\u4ee5\u8f7b\u677e\u5b9e\u73b0\u7a0b\u5e8f\uff0c\u65e0\u9700\u590d\u6742\u7684 IDE \u5b89\u88c5\u3001\u7f16\u8bd1\u6216\u6253\u5305\u8fc7\u7a0b\u3002

        "},{"location":"getting-started/#qpython_2","title":"QPython \u7248\u672c","text":"

        \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

        • QPython \u2013 \u7531 QPython \u56e2\u961f\u7ef4\u62a4\u7684\u4e3b\u8981\u7248\u672c\uff0c\u5177\u5907 AI \u529f\u80fd\uff0c\u53ef\u5728 Google Play \u7b49\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d
        • QPython+ \u2013 \u7531\u5f00\u6e90\u8d21\u732e\u8005\u63a8\u51fa\u7684\u793e\u533a\u7248\uff0c\u63d0\u4f9b\u5404\u79cd\u65b0\u7279\u6027
        • QPython Plus \u2013 \u6269\u5c55\u6743\u9650\u7248\u672c\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff09
        "},{"location":"getting-started/#_1","title":"\u4e3b\u8981\u7279\u6027","text":"
        • \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668 - \u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51
        • QSL4A \u96c6\u6210 - \u4f7f\u7528 Python \u63a7\u5236 Android \u786c\u4ef6\u548c API
        • GenAI \u80fd\u529b\u96c6\u6210 - \u652f\u6301\u672c\u5730\u8fd0\u884c\u7684 LLM\u3001OpenAI \u7b49\u5404\u79cd LLM \u5e93\uff0c\u4ee5\u53ca\u53ef\u5728 QPython \u4e0a\u8fdb\u884c Vibe Coding \u5f00\u53d1\u7684 AIPyApp
        • \u6269\u5c55\u5305\u5b89\u88c5 - \u652f\u6301\u901a\u8fc7 QPYPI \u548c pip \u5b89\u88c5\u6269\u5c55\u5305
        • \u5185\u7f6e\u7f16\u8f91\u5668 - \u8bed\u6cd5\u9ad8\u4eae\u548c\u4ee3\u7801\u7f16\u8f91
        • \u591a\u79cd\u8fd0\u884c\u6a21\u5f0f - \u9664\u63a7\u5236\u53f0\u7a0b\u5e8f\u5916\uff0c\u8fd8\u652f\u6301 Android \u539f\u751f UI\uff08\u901a\u8fc7 QSL4A \u63a5\u53e3\uff09\u4ee5\u53ca Pygame / Turtle / Tkinter \u7b49\u8fd0\u884c\u65b9\u5f0f
        "},{"location":"getting-started/#1","title":"1. \u4eea\u8868\u76d8","text":"

        \u5b89\u88c5 QPython \u540e\uff0c\u70b9\u51fb\u5176\u56fe\u6807\u542f\u52a8\u3002\u60a8\u5c06\u770b\u5230\u5e26\u6709 QPython \u6807\u5fd7\u548c\u4ee5\u4e0b\u529f\u80fd\u7684\u4e3b\u4eea\u8868\u76d8\uff1a

        "},{"location":"getting-started/#_2","title":"\u4eea\u8868\u76d8\u529f\u80fd","text":"

        QPython \u4eea\u8868\u76d8\u63d0\u4f9b\u5bf9\u6240\u6709\u4e3b\u8981\u529f\u80fd\u7684\u5feb\u901f\u8bbf\u95ee\uff1a

        • \u7ec8\u7aef \u2014 \u8bbf\u95ee Python \u63a7\u5236\u53f0\u548c shell \u4ee5\u76f4\u63a5\u6267\u884c\u547d\u4ee4
        • Notebook \u2014 \u7528\u4e8e\u6570\u636e\u5206\u6790\u548c\u5b9e\u9a8c\u7684\u4ea4\u4e92\u5f0f Jupyter \u98ce\u683c\u7b14\u8bb0\u672c
        • \u7f16\u8f91\u5668 \u2014 \u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668\uff0c\u5177\u6709\u8bed\u6cd5\u9ad8\u4eae\u529f\u80fd\uff0c\u7528\u4e8e\u7f16\u5199 Python \u811a\u672c
        • \u8d44\u6e90\u7ba1\u7406\u5668 \u2014 \u6d4f\u89c8\u548c\u7ba1\u7406\u60a8\u7684\u6587\u4ef6\u3001\u811a\u672c\u548c\u9879\u76ee
        • QPYPI \u2014 \u5b89\u88c5 Python \u5305\u548c\u6269\u5c55\u3002\u8be6\u89c1 QPYPI \u6307\u5357
        • \u8bbe\u7f6e \u2014 \u914d\u7f6e QPython \u9996\u9009\u9879\u548c\u8fd0\u884c\u9009\u9879
        • \u793e\u533a \u2014 \u8bbf\u95ee QPython \u793e\u533a\u8d44\u6e90\u3001\u8bba\u575b\u548c\u5e2e\u52a9
        • \u8bfe\u7a0b \u2014 \u8bbf\u95ee Python \u7f16\u7a0b\u7684\u5b66\u4e60\u6750\u6599\u548c\u6559\u7a0b

        \u70b9\u51fb\u4efb\u4f55\u56fe\u6807\u4ee5\u8bbf\u95ee\u76f8\u5e94\u7684\u529f\u80fd\u3002

        "},{"location":"getting-started/#2","title":"2. \u7ec8\u7aef\u548c\u7f16\u8f91\u5668","text":""},{"location":"getting-started/#_3","title":"\u7ec8\u7aef","text":"

        \u7ec8\u7aef\u63d0\u4f9b Python \u63a7\u5236\u53f0\uff0c\u652f\u6301\uff1a - \u63a2\u7d22\u5bf9\u8c61\u5c5e\u6027 - \u6d4b\u8bd5\u8bed\u6cd5\u548c\u60f3\u6cd5 - \u76f4\u63a5\u6267\u884c\u547d\u4ee4

        \u4f7f\u7528\u52a0\u53f7\u6309\u94ae\uff081\uff09\u6253\u5f00\u65b0\u7ec8\u7aef\u6807\u7b7e\u9875\uff0c\u901a\u8fc7\u4e0b\u62c9\u83dc\u5355\uff082\uff09\u5207\u6362\uff0c\u5e76\u4f7f\u7528\u5173\u95ed\u6309\u94ae\uff083\uff09\u5173\u95ed\u3002

        "},{"location":"getting-started/#_4","title":"\u7f16\u8f91\u5668","text":"

        \u7f16\u8f91\u5668\u5e95\u90e8\u529f\u80fd\u680f\u5305\u542b\u4ee5\u4e0b\u5de5\u5177\uff08\u4ece\u5de6\u5230\u53f3\uff09\uff1a

        • \u5207\u6362\u5feb\u6377\u8f93\u5165\uff08\u5305\u542b def / if / else / elif / class \u7b49\u5173\u952e\u8bcd\uff09
        • \u9501\u5b9a\uff08\u9632\u6b62\u8bef\u89e6\uff09
        • \u8df3\u8f6c
        • \u4fdd\u5b58
        • \u8fd0\u884c
        • \u641c\u7d22
        • \u64a4\u9500
        • \u91cd\u505a
        • \u53e6\u5b58
        • \u6700\u8fd1\u6587\u4ef6
        • \u4ee3\u7801\u7247\u6bb5

        \u91cd\u8981\u63d0\u793a\uff1a \u4fdd\u5b58\u65f6\u8bf7\u624b\u52a8\u6dfb\u52a0 .py \u6269\u5c55\u540d\uff0c\u56e0\u4e3a\u7f16\u8f91\u5668\u4e0d\u4f1a\u81ea\u52a8\u6dfb\u52a0\u3002

        "},{"location":"getting-started/#3","title":"3. \u8d44\u6e90\u7ba1\u7406\u5668\uff08\u6587\u4ef6\u7ba1\u7406\uff09","text":"

        \u901a\u8fc7 \u8d44\u6e90\u7ba1\u7406\u5668 \u8bbf\u95ee\u811a\u672c\u548c\u9879\u76ee\uff0c\u652f\u6301\u6d4f\u89c8\u3001\u7ec4\u7ec7\u548c\u7ba1\u7406\u6240\u6709 Python \u6587\u4ef6\u3002

        "},{"location":"getting-started/#_5","title":"\u811a\u672c","text":"

        \u811a\u672c\u662f\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/scripts3/ \u4e2d\u7684\u5355\u4e2a Python \u6587\u4ef6\uff08\u9488\u5bf9 Python 3\uff09\u3002

        \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u811a\u672c - \u6253\u5f00 \u2014 \u4f7f\u7528\u5185\u7f6e\u7f16\u8f91\u5668\u7f16\u8f91 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u811a\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u811a\u672c

        "},{"location":"getting-started/#_6","title":"\u9879\u76ee","text":"

        \u9879\u76ee\u662f\u5305\u542b main.py \u4f5c\u4e3a\u5165\u53e3\u70b9\u7684\u76ee\u5f55\u3002\u60a8\u53ef\u4ee5\u5728\u540c\u4e00\u76ee\u5f55\u4e2d\u5305\u542b\u5176\u4ed6\u4f9d\u8d56\u9879\u548c\u8d44\u6e90\u3002\u5c06\u9879\u76ee\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/projects3/ \u4e2d\u3002

        "},{"location":"getting-started/#_7","title":"\u7b14\u8bb0\u672c","text":"

        Jupyter \u98ce\u683c\u7684\u7b14\u8bb0\u672c\u4e5f\u901a\u8fc7\u8d44\u6e90\u7ba1\u7406\u5668\u8fdb\u884c\u7ba1\u7406\uff0c\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/notebooks/ \u4e2d\u3002

        \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u7b14\u8bb0\u672c - \u6253\u5f00 \u2014 \u63a2\u7d22\u7b14\u8bb0\u672c\u5185\u5bb9 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u7b14\u8bb0\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u7b14\u8bb0\u672c

        "},{"location":"getting-started/#4","title":"4. \u5e93","text":"

        \u901a\u8fc7\u5b89\u88c5\u7b2c\u4e09\u65b9\u5e93\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

        "},{"location":"getting-started/#_8","title":"\u5305\u5b89\u88c5\u65b9\u6cd5","text":"

        QPYPI\uff08\u63a8\u8350\uff09

        \u4ece QPYPI \u5b89\u88c5\u9884\u7f16\u8bd1\u7684\u5e93\uff0c\u5305\u62ec numpy\u3001scipy \u7b49\u79d1\u5b66\u5305\u3002

        \u8be6\u89c1 QPYPI \u6307\u5357\u3002

        PIP \u5ba2\u6237\u7aef

        \u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216 QPYPI \u754c\u9762\u5b89\u88c5\u7eaf Python \u5e93\uff1a

        pip install requests\n

        \u9884\u7f16\u8bd1\u5305

        \u5bf9\u4e8e\u5177\u6709 C/C++/Rust \u4f9d\u8d56\u7684\u5305\uff0c\u4f7f\u7528 QPython \u7684\u9884\u7f16\u8bd1\u5305\uff1a

        pip install numpy-qpython\npip install scipy-aipy\n

        \u8be6\u89c1 QPYPI \u6307\u5357 \u83b7\u53d6\u53ef\u7528\u5305\u7684\u5b8c\u6574\u5217\u8868\u3002

        \u624b\u52a8\u5b89\u88c5

        \u60a8\u4e5f\u53ef\u4ee5\u5c06\u5e93\u590d\u5236\u5230 /storage/emulated/0/Android/data/org.qpython.qpy/files/lib/python3.12/site-packages/\u3002

        "},{"location":"getting-started/#5","title":"5. \u8fd0\u884c\u6a21\u5f0f","text":"

        QPython \u652f\u6301\u591a\u79cd\u8fd0\u884c\u6a21\u5f0f\u4ee5\u6ee1\u8db3\u4e0d\u540c\u7684\u7528\u4f8b\uff1a

        "},{"location":"getting-started/#_9","title":"\u63a7\u5236\u53f0\u6a21\u5f0f","text":"

        \u5e38\u89c4 Python \u811a\u672c\u7684\u9ed8\u8ba4\u6a21\u5f0f\u3002

        "},{"location":"getting-started/#qsl4a","title":"QSL4A \u6a21\u5f0f","text":"

        \u901a\u8fc7 QSL4A \u5e93\u8c03\u7528 Android API \u7684\u811a\u672c\u3002

        import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello Android!')\n

        \u8be6\u89c1 QSL4A \u6587\u6863 \u83b7\u53d6\u5b8c\u6574\u7684 API \u53c2\u8003\u3002

        "},{"location":"getting-started/#webapp","title":"WebApp \u6a21\u5f0f","text":"

        \u4f7f\u7528\u540e\u7aef\u670d\u52a1\u5668\u521b\u5efa\u57fa\u4e8e Web \u7684\u5e94\u7528\u7a0b\u5e8f\u3002\u9700\u5728\u811a\u672c\u5f00\u5934\u6dfb\u52a0\u4ee5\u4e0b\u4e24\u884c headers\uff1a

        #qpy:webapp:<\u9879\u76ee\u540d>\n#qpy://localhost:<web\u670d\u52a1\u4fa6\u542c\u7684\u7aef\u53e3>/<\u9ed8\u8ba4\u4e3b\u8def\u5f84>\n

        \u4f8b\u5982\uff1a

        #qpy:webapp:Hello QPython\n#qpy://localhost:8080/hello\n\nfrom bottle import route, run, Bottle\n\napp = Bottle()\n\n@route('/hello')\ndef hello():\n    return '<h1>Hello from QPython!</h1>'\n\nrun(app, host='localhost', port=8080)\n
        "},{"location":"getting-started/#q","title":"Q \u6a21\u5f0f\uff08\u65e0\u63a7\u5236\u53f0\u6a21\u5f0f\uff09","text":"

        \u9759\u9ed8\u6a21\u5f0f\u8fd0\u884c\u811a\u672c\uff0c\u4e0d\u663e\u793a\u63a7\u5236\u53f0\u3002\u9700\u5728\u811a\u672c\u5f00\u5934\u6dfb\u52a0 header\uff1a

        #qpy:quiet\n\nimport time\n\nwhile True:\n    # \u60a8\u7684\u540e\u53f0\u4efb\u52a1\n    time.sleep(60)\n
        \u5982\u679c\u9700\u8981\u8fd0\u884c\u5e26 GUI \u7684 QSL4A \u7a0b\u5e8f\u4e14\u4e0d\u5e0c\u671b\u663e\u793a\u63a7\u5236\u53f0\u4fe1\u606f\uff0c\u63a8\u8350\u4f7f\u7528\u6b64\u6a21\u5f0f\u3002

        "},{"location":"getting-started/#6","title":"6. \u793e\u533a\u4e0e\u652f\u6301","text":"

        \u8bbf\u95ee QPython.org \u83b7\u53d6\u6587\u6863\u3001\u7528\u6237\u793e\u533a\u53ca\u5e2e\u52a9\u95ee\u7b54\u3002

        \u793e\u533a\u94fe\u63a5\uff1a - Facebook \u7fa4\u7ec4 - GitHub - \u95ee\u9898\u53cd\u9988

        \u4e0b\u4e00\u6b65\uff1a - \u5c1d\u8bd5 Hello World \u6559\u7a0b - \u63a2\u7d22 QSL4A API \u4ee5\u96c6\u6210 Android - \u4e86\u89e3 QPython \u7248\u672c

        "},{"location":"getting-started/#_10","title":"\u89c6\u9891\u4ecb\u7ecd","text":""},{"location":"getting-started/#_11","title":"\u4e0b\u4e00\u6b65","text":"

        \u5982\u679c\u60a8\u5df2\u7ecf\u521d\u6b65\u4e86\u89e3\u4e86 QPython \u7684\u529f\u80fd\uff0c\u6b22\u8fce\u5f00\u59cb\u4f53\u9a8c\u7f16\u7a0b\u7684\u4e50\u8da3\uff01\u8bd5\u8bd5 Hello World \u6559\u7a0b \u8fc8\u51fa\u60a8\u7684\u7b2c\u4e00\u6b65\u3002

        "},{"location":"qpypi-guide/","title":"QPYPI","text":"

        \u60a8\u53ef\u4ee5\u901a\u8fc7\u5b89\u88c5\u5305\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

        "},{"location":"qpypi-guide/#_1","title":"\u5305\u5b89\u88c5\u652f\u6301","text":""},{"location":"qpypi-guide/#python","title":"\u7eaf Python \u5305","text":"

        QPython \u652f\u6301\u4f7f\u7528\u7eaf Python \u5f00\u53d1\u7684 Python \u5305\u3002\u60a8\u53ef\u4ee5\u76f4\u63a5\u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216\u4eea\u8868\u76d8\u4e0a\u7684 QPYPI \u4f7f\u7528 pip install \u5b89\u88c5\u8fd9\u4e9b\u5305\u3002

        "},{"location":"qpypi-guide/#_2","title":"\u9884\u7f16\u8bd1\u5305","text":"

        \u5982\u679c\u67d0\u4e9b\u5305\uff08\u6216\u5b83\u4eec\u7684\u4f9d\u8d56\uff09\u662f\u7528 Rust/C/C++ \u5f00\u53d1\u7684\uff0cQPython \u65e0\u6cd5\u76f4\u63a5\u652f\u6301\u5b83\u4eec\uff0c\u56e0\u4e3a QPython \u4e0a\u6ca1\u6709\u7f16\u8bd1\u5668\u5de5\u5177\u94fe\u652f\u6301\u3002\u4f46\u662f\uff0cQPython \u56e2\u961f\u5df2\u7ecf\u9884\u7f16\u8bd1\u4e86\u4e00\u4e9b\u5e38\u7528\u5305\uff0c\u5e76\u5728 QPython \u7684 QPYPI/Extensions \u4e2d\u53d1\u5e03\uff0c\u4f9b\u7528\u6237\u8f7b\u677e\u5b89\u88c5\u3002

        "},{"location":"qpypi-guide/#_3","title":"\u5b89\u88c5\u9884\u7f16\u8bd1\u5305","text":"

        \u60a8\u53ef\u4ee5\u901a\u8fc7\u4ee5\u4e0b\u65b9\u5f0f\u5b89\u88c5\u9884\u7f16\u8bd1\u5305\uff1a

        1. \u901a\u8fc7 QPython \u5e94\u7528\uff1a\u76f4\u63a5\u4ece QPython \u5e94\u7528\u5185\u7684 QPYPI \u6216 Extensions \u5b89\u88c5
        2. \u901a\u8fc7 PyPI\uff1a\u8bbf\u95ee https://pypi.org/user/qpythonx/ \u67e5\u770b\u53ef\u7528\u7684\u5305
        3. \u901a\u8fc7 pip \u547d\u4ee4\uff1a
        4. pip install xxx-qpython - \u5e26 -qpython \u540e\u7f00\u7684\u5305
        5. pip install xxx-aipy - \u5e26 -aipy \u540e\u7f00\u7684\u5305\uff08\u901a\u5e38\u662f AI/ML \u76f8\u5173\u7684\u5305\uff09

        \u6ce8\u610f\uff1a\u6211\u4eec\u901a\u5e38\u6839\u636e\u5305\u7684\u9884\u671f\u7528\u9014\u6dfb\u52a0\u8fd9\u4e9b\u540e\u7f00\u4e4b\u4e00\u3002

        "},{"location":"qpypi-guide/#_4","title":"\u8bf7\u6c42\u65b0\u5305","text":"

        \u5982\u679c\u60a8\u9700\u8981\u5f53\u524d\u4e0d\u652f\u6301\u7684\u5305\uff1a

        • \u5728 qpython.org \u9879\u76ee \u4e2d\u63d0\u51fa\u95ee\u9898
        • QPython \u56e2\u961f\u5c06\u8003\u8651\u9884\u7f16\u8bd1\u5e76\u5c06\u5176\u6dfb\u52a0\u5230\u4ed3\u5e93\u4e2d

        \u83b7\u53d6\u66f4\u591a\u5e2e\u52a9\u548c\u53c2\u4e0e\u793e\u533a\u7684\u65b9\u5f0f\uff0c\u8bf7\u53c2\u9605 \u793e\u533a\u4e0e\u53cd\u9988 \u90e8\u5206\u3002

        \u6ce8\u610f\uff1a\u7531\u4e8e\u4e0d\u540c\u7684\u8ba1\u7b97\u673a\u67b6\u6784\uff0c\u6211\u4eec\u65e0\u6cd5\u4fdd\u8bc1 QPYPI \u5305\u542b PyPI \u4e0a\u7684\u6240\u6709\u5305\u3002

        "},{"location":"qpython-x/","title":"QPython \u7248\u672c","text":"

        QPython \u662f Android \u7684 Python \u5f15\u64ce\u3002\u5b83\u5305\u542b\u4ee4\u4eba\u60ca\u53f9\u7684\u529f\u80fd\uff0c\u5982 Python \u89e3\u91ca\u5668\u3001\u8fd0\u884c\u73af\u5883\u3001\u7f16\u8f91\u5668\u3001QPYI \u548c\u96c6\u6210\u7684 SL4A\u3002\u5b83\u8ba9\u60a8\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 Android \u4e0a\u4f7f\u7528 Python\u3002\u800c\u4e14\u5b83\u662f\u514d\u8d39\u7684\u3002

        QPython \u5df2\u7ecf\u5728\u5168\u7403\u62e5\u6709\u6570\u767e\u4e07\u7528\u6237\uff0c\u4e5f\u662f\u4e00\u4e2a\u5f00\u6e90\u9879\u76ee\u3002

        \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

        "},{"location":"qpython-x/#qpython_1","title":"QPython","text":"

        \u6807\u51c6\u7248\uff1a\u9488\u5bf9 AI \u6027\u80fd\u548c\u901a\u7528\u5e94\u7528\u5546\u5e97\u517c\u5bb9\u6027\u4f18\u5316

        \u4e3b\u8981\u7248\u672c\uff0c\u53ef\u5728 Google Play \u548c\u5176\u4ed6\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002\u6b64\u7248\u672c\u4e13\u6ce8\u4e8e AI \u529f\u80fd\uff0c\u4f7f AI \u65f6\u4ee3\u7528\u6237\u66f4\u5bb9\u6613\u5b66\u4e60\u548c\u4f7f\u7528 Python\u3002

        \u4e3b\u8981\u7279\u6027\uff1a - AI \u9a71\u52a8\u7684\u7f16\u7801\u8f85\u52a9\u548c\u5b66\u4e60\u5de5\u5177 - \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668\uff1a\u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51 - \u652f\u6301\u591a\u79cd\u9879\u76ee\u7c7b\u578b\uff1a\u63a7\u5236\u53f0\u3001SL4A\u3001WebApp - \u65b9\u4fbf\u7684\u4e8c\u7ef4\u7801\u8bfb\u53d6\u5668\uff0c\u7528\u4e8e\u5c06\u4ee3\u7801\u4f20\u8f93\u5230\u624b\u673a - QPYPI \u548c\u81ea\u5b9a\u4e49\u4ed3\u5e93\uff0c\u7528\u4e8e\u9884\u7f16\u8bd1 wheel \u5305 -\u6613\u4e8e\u4f7f\u7528\u7684\u8bed\u6cd5\u9ad8\u4eae\u7f16\u8f91\u5668 - \u5b8c\u5584\u7684\u6587\u6863\u548c\u793e\u533a\u652f\u6301

        \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

        \u4e0b\u8f7d\uff1a \u53ef\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

        "},{"location":"qpython-x/#qpython_2","title":"QPython+","text":"

        \u793e\u533a\u7248\uff1a\u516c\u5f00\u652f\u6301\u5404\u79cd\u793e\u533a\u9a71\u52a8\u7684\u529f\u80fd\uff1b\u53ef\u5728\u90e8\u5206\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

        \u793e\u533a\u5f00\u6e90\u7248\u672c\uff08\u6b63\u5728\u89c4\u5212\u548c\u51c6\u5907\u4e2d\uff09\u3002\u6b64\u7248\u672c\u4e13\u4e3a\u60f3\u8981\u53c2\u4e0e QPython \u9879\u76ee\u5f00\u53d1\u7684\u8d21\u732e\u8005\u800c\u8bbe\u8ba1\uff0c\u652f\u6301\u9488\u5bf9\u4e0d\u540c\u5236\u9020\u5546\u7684\u5b9a\u5236\u3002

        \u4e3b\u8981\u7279\u6027\uff1a - \u793e\u533a\u9a71\u52a8\u5f00\u53d1 - \u652f\u6301\u4f9b\u5e94\u5546\u5b9a\u5236 - \u66f4\u7075\u6d3b\u7684\u914d\u7f6e\u9009\u9879 - \u5f00\u653e\u4f9b\u8d21\u732e\u8005\u52a0\u5165\u5f00\u53d1

        \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

        \u4e0b\u8f7d\uff1a \u5c06\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

        \u6ce8\u610f\uff1a \u6b64\u7248\u672c\u76ee\u524d\u6b63\u5728\u89c4\u5212\u51c6\u5907\u4e2d\u3002\u8bf7\u5173\u6ce8\u66f4\u65b0\uff01

        "},{"location":"qpython-x/#qpython-plus","title":"QPython Plus","text":"

        QPython+ \u5b8c\u5168\u8bbf\u95ee\u7248\uff1a\u6388\u4e88\u8c03\u7528\u6240\u6709 Android \u63a5\u53e3\u7684\u5b8c\u6574\u6743\u9650\u3002\u4e0b\u8f7d\u94fe\u63a5\u4ec5\u901a\u8fc7\u5b98\u65b9\u4e91\u76d8\u63d0\u4f9b\u3002

        \u5177\u6709\u6269\u5c55\u6743\u9650\u7684\u7279\u6b8a\u7248\u672c\uff0c\u63d0\u4f9b\u5bf9\u8bbe\u5907\u7684\u6700\u5927\u63a7\u5236\u3002\u7531\u4e8e\u5176\u654f\u611f\u7684\u6743\u9650\u8981\u6c42\uff0c\u6b64\u7248\u672c\u4e0d\u4f1a\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u53d1\u5e03\u3002

        \u4e3b\u8981\u7279\u6027\uff1a - \u5b8c\u6574\u7684 SL4A API \u8bbf\u95ee\uff0c\u5305\u62ec\u654f\u611f\u529f\u80fd - SMS/\u901a\u8bdd\u63a7\u5236 API - \u9ad8\u7ea7\u7cfb\u7edf\u96c6\u6210 - \u6700\u5927\u7684\u8bbe\u5907\u63a7\u5236\u80fd\u529b

        \u6743\u9650\uff1a \u9700\u8981\u5e7f\u6cdb\u7684\u6743\u9650\uff0c\u5305\u62ec\uff1a - \u84dd\u7259 - \u4f4d\u7f6e\uff08GPS\uff09 - \u8bfb\u53d6/\u53d1\u9001\u77ed\u4fe1 - \u6253\u7535\u8bdd - \u76f8\u673a\u548c\u9ea6\u514b\u98ce - \u7cfb\u7edf\u8bbe\u7f6e - \u4ee5\u53ca\u5176\u4ed6\u654f\u611f\u6743\u9650

        \u4e0b\u8f7d\uff1a \u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\u3002\u4ec5\u901a\u8fc7\u7279\u6b8a\u6e20\u9053\u5206\u53d1\u3002

        \u91cd\u8981\u63d0\u793a\uff1a QPython \u4e0d\u4f1a\u5728\u540e\u53f0\u672a\u7ecf\u60a8\u77e5\u6089\u4f7f\u7528\u8fd9\u4e9b\u6743\u9650\u3002\u5982\u679c\u4f7f\u7528 SL4A API \u65f6\u51fa\u73b0\u5f02\u5e38\uff0c\u8bf7\u68c0\u67e5\u7cfb\u7edf\u8bbe\u7f6e\u4e2d\u662f\u5426\u5df2\u542f\u7528\u76f8\u5173\u6743\u9650\u3002

        "},{"location":"tutorial-hello-world/","title":"\u7f16\u5199\"Hello World\"","text":""},{"location":"tutorial-hello-world/#hello-world_1","title":"Hello world","text":"

        \u597d\u7684\uff0c\u5728\u60a8\u5bf9 QPython \u6709\u4e86\u4e00\u5b9a\u7684\u4e86\u89e3\u4e4b\u540e\uff0c\u8ba9\u6211\u4eec\u5728 QPython \u4e2d\u521b\u5efa\u6211\u4eec\u7684\u7b2c\u4e00\u4e2a\u7a0b\u5e8f\u3002\u663e\u7136\uff0c\u5b83\u5c06\u662f helloworld.py\u3002;)

        \u542f\u52a8 QPython\uff0c\u6253\u5f00\u7f16\u8f91\u5668\u5e76\u8f93\u5165\u4ee5\u4e0b\u4ee3\u7801\uff1a

        #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello, QPYTHON!')\n

        \u6beb\u65e0\u7591\u95ee\uff0c\u5b83\u4e0e\u5176\u4ed6\u4efb\u4f55 hello-world \u7a0b\u5e8f\u5e76\u65e0\u4e0d\u540c\u3002\u6267\u884c\u65f6\uff0c\u5b83\u53ea\u662f\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u5f39\u51fa\u6d88\u606f\uff08\u89c1\u9876\u90e8\u622a\u56fe\uff09\u3002\u65e0\u8bba\u5982\u4f55\uff0c\u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684 QPython \u7a0b\u5e8f\u793a\u4f8b\u3002

        "},{"location":"tutorial-hello-world/#_1","title":"\u4ee3\u7801\u7406\u89e3","text":"

        \u5b83\u4ee5 import androidhelper \u5f00\u5934\u2014\u2014\u8fd9\u662f QPython \u4e2d\u6700\u6709\u7528\u7684\u6a21\u5757\uff0c\u5b83\u5c01\u88c5\u4e86 Python \u4e2d\u53ef\u7528\u7684\u51e0\u4e4e\u6240\u6709\u4e0e Android \u7684\u63a5\u53e3\u3002\u4efb\u4f55\u5728 QPython \u4e2d\u5f00\u53d1\u7684\u811a\u672c\u90fd\u4ee5\u8fd9\u4e2a\u8bed\u53e5\u5f00\u5934\uff08\u81f3\u5c11\u5982\u679c\u5b83\u58f0\u79f0\u8981\u4e0e\u7528\u6237\u901a\u4fe1\u7684\u8bdd\uff09\u3002\u5728\u6b64\u5904\u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u5e93 \u548c import \u8bed\u53e5 \u7684\u5185\u5bb9\u3002

        \u63a5\u4e0b\u6765\u6211\u4eec\u521b\u5efa\u4e00\u4e2a droid \u5bf9\u8c61\uff08\u5b9e\u9645\u4e0a\u662f\u4e00\u4e2a\u7c7b\uff09\uff0c\u5b83\u5bf9\u4e8e\u8c03\u7528 RPC \u51fd\u6570\u4ee5\u4e0e Android \u901a\u4fe1\u662f\u5fc5\u8981\u7684\u3002

        \u6211\u4eec\u4ee3\u7801\u7684\u6700\u540e\u4e00\u884c\u8c03\u7528\u4e86\u8fd9\u6837\u7684\u51fd\u6570\uff0cdroid.makeToast()\uff0c\u5b83\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u4e00\u4e2a\u5c0f\u7684\u5f39\u51fa\u6d88\u606f\uff08\"toast\"\uff09\u3002

        \u597d\u7684\uff0c\u8ba9\u6211\u4eec\u6dfb\u52a0\u4e00\u4e9b\u66f4\u591a\u7684\u529f\u80fd\u3002\u8ba9\u5b83\u8be2\u95ee\u7528\u6237\u540d\u5e76\u5411\u7528\u6237\u6253\u62db\u547c\u3002

        "},{"location":"tutorial-hello-world/#_2","title":"\u66f4\u591a\u793a\u4f8b","text":"

        \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 dialogGetInput \u8c03\u7528\u663e\u793a\u4e00\u4e2a\u5e26\u6709\u6807\u9898\u3001\u63d0\u793a\u3001\u7f16\u8f91\u5b57\u6bb5\u548c \u786e\u5b9a \u548c \u53d6\u6d88 \u6309\u94ae\u7684\u7b80\u5355\u5bf9\u8bdd\u6846\u3002\u7528\u4ee5\u4e0b\u4ee3\u7801\u66ff\u6362\u60a8\u7684\u6700\u540e\u4e00\u884c\u4ee3\u7801\u5e76\u5c06\u5176\u4fdd\u5b58\u4e3a hello1.py\uff1a

        #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\n

        \u597d\u7684\uff0c\u6211\u8ba4\u4e3a\u5b83\u5e94\u8be5\u8fd4\u56de\u4efb\u4f55\u54cd\u5e94\uff0c\u4efb\u4f55\u7528\u6237\u53cd\u5e94\u3002\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u6211\u5199 respond = ...\u3002\u4f46\u8fd9\u4e2a\u8c03\u7528\u5b9e\u9645\u4e0a\u8fd4\u56de\u4ec0\u4e48\uff1f\u8ba9\u6211\u4eec\u68c0\u67e5\u4e00\u4e0b\u3002\u53ea\u9700\u5728\u6700\u540e\u4e00\u884c\u540e\u6dfb\u52a0 print \u8bed\u53e5\uff1a

        #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\n

        \u7136\u540e\u4fdd\u5b58\u5e76\u8fd0\u884c\u5b83...

        \u54ce\u5440\uff01\u6ca1\u6709\u6253\u5370\uff1f\u522b\u62c5\u5fc3\u3002\u53ea\u9700\u62c9\u4e0b\u901a\u77e5\u680f\uff0c\u60a8\u5c31\u4f1a\u770b\u5230\"QPython Program Output: hello1.py\"\u2014\u2014\u70b9\u51fb\u5b83\uff01

        \u5982\u60a8\u6240\u89c1\uff0cdroid.dialogGetInput() \u8fd4\u56de\u4e00\u4e2a\u5305\u542b\u4e09\u4e2a\u5b57\u6bb5\u7684 JSON \u5bf9\u8c61\u3002\u6211\u4eec\u53ea\u9700\u8981\u4e00\u4e2a\u2014\u2014result\uff0c\u5176\u4e2d\u5305\u542b\u7528\u6237\u5b9e\u9645\u8f93\u5165\u7684\u5185\u5bb9\u3002

        \u8ba9\u6211\u4eec\u6dfb\u52a0\u811a\u672c\u7684\u53cd\u5e94\uff1a

        #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nmessage = f'Hello, {respond.result}!'\ndroid.makeToast(message)\n

        \u6700\u540e\u4e24\u884c\uff081\uff09\u683c\u5f0f\u5316\u6d88\u606f\uff0c\uff082\uff09\u4ee5 toast \u5f62\u5f0f\u5411\u7528\u6237\u663e\u793a\u6d88\u606f\u3002\u5982\u679c\u60a8\u4ecd\u7136\u4e0d\u77e5\u9053 f-string \u662f\u4ec0\u4e48\u610f\u601d\uff0c\u8bf7\u53c2\u9605 Python \u6587\u6863\u3002

        \u54c7\uff01\u5b83\u5de5\u4f5c\u4e86\uff01;)

        \u73b0\u5728\u6211\u8981\u5728\u90a3\u91cc\u6dfb\u52a0\u4e00\u4e9b\u903b\u8f91\u3002\u60f3\u4e00\u60f3\uff1a\u5982\u679c\u7528\u6237\u70b9\u51fb \u53d6\u6d88 \u6309\u94ae\uff0c\u6216\u8005\u70b9\u51fb \u786e\u5b9a \u4f46\u5c06\u8f93\u5165\u5b57\u6bb5\u7559\u7a7a\uff0c\u4f1a\u53d1\u751f\u4ec0\u4e48\uff1f

        \u60a8\u53ef\u4ee5\u73a9\u8fd9\u4e2a\u7a0b\u5e8f\uff0c\u68c0\u67e5 respond \u53d8\u91cf\u5728\u6bcf\u79cd\u60c5\u51b5\u4e0b\u5305\u542b\u4ec0\u4e48\u3002

        \u9996\u5148\uff0c\u6211\u60f3\u5c06\u7528\u6237\u8f93\u5165\u7684\u6587\u672c\u653e\u5165\u4e00\u4e2a\u5355\u72ec\u7684\u53d8\u91cf\u4e2d\uff1aname = respond.result\u3002\u7136\u540e\u6211\u68c0\u67e5\u5b83\uff0c\u5982\u679c\u5b83\u5305\u542b\u4efb\u4f55\u771f\u5b9e\u6587\u672c\uff0c\u5b83\u5c06\u88ab\u89c6\u4e3a\u540d\u79f0\u5e76\u7528\u4e8e\u95ee\u5019\u3002\u5426\u5219\uff0c\u5c06\u663e\u793a\u53e6\u4e00\u6761\u6d88\u606f\u3002\u5c06\u7b2c\u4e94\u884c message = f'Hello, {respond.result}!' \u66ff\u6362\u4e3a\u4ee5\u4e0b\u4ee3\u7801\uff1a

        name = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\n

        \u4f7f\u7528\u5de5\u5177\u680f\u4e0a\u7684 < \u548c > \u6309\u94ae\u6765\u7f29\u8fdb/\u53d6\u6d88\u7f29\u8fdb if \u8bed\u53e5\u4e2d\u7684\u884c\uff08\u6216\u8005\u53ea\u9700\u4f7f\u7528\u7a7a\u683c/\u9000\u683c\u952e\uff09\u3002\u60a8\u53ef\u4ee5\u5728 \u6b64\u5904 \u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u7f29\u8fdb\u7684\u5185\u5bb9\uff1bif \u8bed\u53e5\u5728 \u6b64\u5904 \u63cf\u8ff0\u3002

        \u9996\u5148\uff0c\u6211\u4eec\u5c06\u7528\u6237\u8f93\u5165\u653e\u5165 name \u53d8\u91cf\u3002\u7136\u540e\u6211\u4eec\u68c0\u67e5 name \u662f\u5426\u5305\u542b\u4efb\u4f55\u5185\u5bb9\uff1f\u5982\u679c\u7528\u6237\u7559\u7a7a\u884c\u5e76\u70b9\u51fb \u786e\u5b9a\uff0c\u8fd4\u56de\u503c\u662f\u7a7a\u5b57\u7b26\u4e32 ''\u3002\u5982\u679c\u6309\u4e0b\u4e86 \u53d6\u6d88 \u6309\u94ae\uff0c\u8fd4\u56de\u503c\u662f None\u3002\u5728 if \u8bed\u53e5\u4e2d\uff0c\u4e24\u8005\u90fd\u88ab\u89c6\u4e3a\u5047\u3002\u56e0\u6b64\uff0c\u53ea\u6709\u5f53 name \u5305\u542b\u4efb\u4f55\u6709\u610f\u4e49\u7684\u5185\u5bb9\u65f6\uff0cthen \u8bed\u53e5\u624d\u4f1a\u6267\u884c\uff0c\u5e76\u663e\u793a\u95ee\u5019\u8bed\"Hello, ...!\"\u3002\u5982\u679c\u8f93\u5165\u4e3a\u7a7a\uff0c\u7528\u6237\u5c06\u770b\u5230\"Hey! And you're not very polite, %Username%!\"\u6d88\u606f\u3002

        \u597d\u7684\uff0c\u8fd9\u662f\u6574\u4e2a\u7a0b\u5e8f\uff1a

        #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nname = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\ndroid.makeToast(message)\n
        "},{"location":"tutorial-hello-world/#_3","title":"\u8fd0\u884c\u6548\u679c","text":""},{"location":"tutorial-hello-world/#_4","title":"\u4e0b\u4e00\u6b65","text":"

        \u5bf9\u4e8e Python \u65b0\u7528\u6237\uff0c\u63a8\u8350\u5b66\u4e60 Python \u8bed\u6cd5\u5b9e\u8df5 \u8bfe\u7a0b\u6765\u8fdb\u4e00\u6b65\u5b66\u4e60 Python\uff0c\u6216\u8005\u5728 QPython \u7cbe\u9009\u8bfe\u7a0b \u4e2d\u5bfb\u627e\u60f3\u8981\u5b66\u4e60\u7684\u5185\u5bb9\u3002

        "},{"location":"whats-new/","title":"\u66f4\u65b0\u65e5\u5fd7","text":""},{"location":"whats-new/#v392-v393","title":"v3.9.2 / v3.9.3","text":"
        • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
        • \u7f16\u8f91\u5668\u91cd\u5927\u66f4\u65b0\uff0c\u5e26\u6765\u66f4\u6d41\u7545\u7684\u7f16\u8f91\u4f53\u9a8c
        • \u5176\u4ed6\u5404\u79cd\u5c0f\u6539\u8fdb
        "},{"location":"whats-new/#v391","title":"v3.9.1","text":"
        • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
        • \u6269\u5c55\u5305\u73b0\u5728\u652f\u6301 MCP
        • \u9519\u8bef\u4fee\u590d
        "},{"location":"whats-new/#v390","title":"v3.9.0","text":"
        • SDK \u5347\u7ea7\uff0c\u6574\u5408\u6700\u65b0\u7684 Android \u529f\u80fd
        • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
        • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
        • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
        "},{"location":"whats-new/#v3811","title":"v3.8.11","text":"
        • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
        • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
        • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
        "},{"location":"whats-new/#v3810","title":"v3.8.10","text":"
        • \u5185\u7f6e Ollama \u5347\u7ea7\uff1a\u73b0\u5728\u60a8\u53ef\u4ee5\u5728 QPython \u4e2d\u8f7b\u677e\u672c\u5730\u8fd0\u884c Qwen3 / Gemma3 \u6a21\u578b\uff01
        • \u6dfb\u52a0\u4e86\u5f3a\u5927\u7684 MCP \u5e93\uff1a\u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 mcp \u5e93\uff0c\u8ba9\u60a8\u968f\u65f6\u968f\u5730\u643a\u5e26\u5f3a\u5927\u7684 MCP \u529f\u80fd\uff01
        "},{"location":"whats-new/#v389","title":"v3.8.9","text":"

        \u91cd\u5927\u66f4\u65b0\uff01AI \u7f16\u7a0b\u5b8c\u5168\u96c6\u6210\u5230 QPython\uff0c\u8ba9\u60a8\u7684\u7f16\u7a0b\u66f4\u8f7b\u677e\uff01

        • \u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u652f\u6301\uff1a\u65b0\u652f\u6301 AIPyApp\uff0c\u5728 QPython \u4e2d\u5b9e\u73b0\u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u3002\u76ee\u524d\u5904\u4e8e\u6d4b\u8bd5\u9636\u6bb5 - \u52a0\u5165\u6211\u4eec\u7684\u793e\u533a\u83b7\u53d6\u4f7f\u7528\u8bf4\u660e
        • \u65b0 QSL4A \u529f\u80fd\uff1a\u6dfb\u52a0 notebookOpen \u51fd\u6570\uff0c\u652f\u6301\u81ea\u7136\u8bed\u8a00\u63a7\u5236\u6253\u5f00 Notebook \u6587\u4ef6
        • \u5185\u7f6e\u7f16\u8f91\u5668\u5347\u7ea7\uff1a\u589e\u5f3a\u7f16\u8f91\u5668\u529f\u80fd\uff0c\u652f\u6301\u6253\u5f00\u548c\u6d4f\u89c8\u5404\u79cd\u6587\u672c\u6587\u4ef6
        • \u4fbf\u6377\u7684\u6587\u4ef6\u7ba1\u7406\uff1a\u5728\u6587\u4ef6\u7ba1\u7406\u5668\u4e2d\u6dfb\u52a0\u5185\u90e8\u5b58\u50a8\u5165\u53e3\uff0c\u5feb\u901f\u8bbf\u95ee\u60a8\u7684\u6587\u4ef6
        "},{"location":"whats-new/#v388","title":"v3.8.8","text":"
        • \u6587\u4ef6\u8bbf\u95ee\u6743\u9650\u63a7\u5236\u7684\u91cd\u8981\u6539\u8fdb\uff0c\u5141\u8bb8\u7528\u6237\u7075\u6d3b\u5730\u901a\u8fc7 QPython \u7f16\u7a0b\u542f\u7528\u6216\u7981\u7528\u5916\u90e8\u5b58\u50a8\u6587\u4ef6\u7684\u8bbf\u95ee
        • SDK \u5347\u7ea7\uff0c\u589e\u5f3a\u4e86\u5bf9\u65b0\u7248 Android \u7684\u652f\u6301\u548c\u517c\u5bb9\u6027
        • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Anthropic \u548c Google GenAI \u5e93
        "},{"location":"whats-new/#v387","title":"v3.8.7","text":"
        • \u5728\u73b0\u6709 Tkinter \u652f\u6301\u57fa\u7840\u4e0a\uff0c\u5728 Extensions -> Tools \u4e2d\u6dfb\u52a0\u4e86\u4f7f\u7528 Turtle \u7ed8\u5236\u54c6\u5566A\u68a6\u7684\u793a\u4f8b\u4ee3\u7801
        • \u4f18\u5316\u4e86\u624b\u673a\u6743\u9650\u83b7\u53d6\u6d41\u7a0b\uff0c\u63d0\u5347\u7528\u6237\u4f53\u9a8c\u548c\u64cd\u4f5c\u4fbf\u5229\u6027
        • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Google Gen AI \u5e93\uff0c\u65b9\u4fbf\u8bbf\u95ee Gemini Developer API \u548c Vertex AI
        "},{"location":"whats-new/#v386","title":"v3.8.6","text":"
        • Tkinter \u652f\u6301\uff1a\u73b0\u5728\u652f\u6301 Tkinter \u5e93\uff0c\u53ef\u901a\u8fc7 XServer \u8bbf\u95ee\u3002\u8bf7\u8bbf\u95ee www.qpython.org \u7684\u4e91\u76d8\"Extra\"\u94fe\u63a5\u4e0b\u8f7d\u6240\u9700\u6587\u4ef6
        • \u5b58\u50a8\u6743\u9650\u66f4\u65b0\uff1a\u4e3a\u6539\u5584\u7528\u6237\u4f53\u9a8c\uff0c\u6211\u4eec\u6dfb\u52a0\u4e86\u8bfb\u53d6\u624b\u673a\u5b58\u50a8\u7684\u6743\u9650\uff0c\u7528\u4e8e\u8bbf\u95ee\u5b58\u50a8\u5728\u5176\u4ed6\u76ee\u5f55\u4e2d\u7684 Python \u7a0b\u5e8f

        \u6b64\u66f4\u65b0\u540e\uff0cQPython \u548c QPythonPlus\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff0c\u4e13\u4e3a\u9700\u8981\u66f4\u591a\u654f\u611f\u6743\u9650\u7684\u9ad8\u7ea7\u7528\u6237\u8bbe\u8ba1\uff09\u5c06\u4fdd\u6301\u540c\u6b65\u7684\u7248\u672c\u53f7\u3002

        "},{"location":"whats-new/#v352-2025225","title":"v3.5.2 (2025/2/25)","text":"

        \u4e0e\u5f00\u6e90 LLM \u90e8\u7f72\u5de5\u5177 Ollama \u4ee5\u53ca DeepSeek \u5f00\u53d1\u7684 DeepSeek \u5b9e\u73b0\u65e0\u7f1d\u96c6\u6210\uff01

        \u529f\u80fd\uff1a - \u96f6\u95e8\u69db\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5404\u79cd\u5927\u578b\u8bed\u8a00\u6a21\u578b - \u5feb\u901f\u90e8\u7f72 DeepSeek \u7b49\u5c16\u7aef AI \u6a21\u578b - \u4eab\u53d7\u7b80\u7ea6\u7684 API \u8c03\u7528\u4f53\u9a8c - \u6784\u5efa\u5b8c\u5168\u79bb\u7ebf\u7684\u667a\u80fd\u7f16\u7a0b\u73af\u5883

        \u80fd\u529b\uff1a - \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u52a0\u8f7d/\u7ba1\u7406 LLM \u6a21\u578b - \u57fa\u4e8e\u672c\u5730\u8ba1\u7b97\u7684\u5b9e\u65f6\u4f4e\u5ef6\u8fdf\u54cd\u5e94

        "},{"location":"whats-new/#v350","title":"v3.5.0","text":"
        • Python \u5347\u7ea7\u5230 3.12.8
        • \u6539\u8fdb\u4eea\u8868\u76d8\uff0c\u529f\u80fd\u66f4\u6e05\u6670\u3001\u66f4\u4eba\u6027\u5316
        • \u6dfb\u52a0\u4e86\u4f17\u591a\u7b2c\u4e09\u65b9\u5305\uff1aPyTorch / Twisted / Scrapy / FastAPI ...
        "},{"location":"whats-new/#v338","title":"v3.3.8","text":"
        • \u4fee\u590d\u4e86 NumPy \u517c\u5bb9\u6027\u95ee\u9898
        "},{"location":"whats-new/#v335","title":"v3.3.5","text":"
        • \u5347\u7ea7 Python \u5185\u6838\u5230 3.11.9
        • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u4e0d\u663e\u793a\u6a21\u5757\u5b89\u88c5\u72b6\u6001\u7684 bug
        • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u5220\u9664\u6a21\u5757\u5931\u8d25\u7684 bug
        • \u4fee\u590d\u4e86\u5176\u4ed6 bug
        "},{"location":"whats-new/#v334","title":"v3.3.4","text":"
        • \u6dfb\u52a0\u4e86 OpenAI/Langchain/APIGPTCloud AI \u5305
        • \u79fb\u9664\u4e0d\u5fc5\u8981\u7684\u6587\u4ef6\u4ee5\u51cf\u5c11\u5927\u5c0f
        "},{"location":"whats-new/#v325","title":"v3.2.5","text":"
        • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570
        • \u5176\u4ed6\u9519\u8bef\u4fee\u590d
        "},{"location":"whats-new/#v323","title":"v3.2.3","text":"
        • \u66f4\u65b0 Python \u7248\u672c\u5230 3.11.0
        • \u66f4\u65b0 IPython \u7248\u672c\u5230 8.6.0
        • \u66f4\u65b0 pip \u7248\u672c\u5230 22.3.1
        • \u66f4\u65b0\u79d1\u5b66\u8ba1\u7b97\u5305\uff0c\u81ea\u52a8\u8f6f\u94fe\u63a5
        • \u51cf\u5c11\u7a7a\u95f4\u4f7f\u7528
        • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570 + \u5176\u4ed6\u9519\u8bef\u4fee\u590d
        "},{"location":"whats-new/#v318","title":"v3.1.8","text":"
        • \u5728\u7ec8\u7aef\u4e2d\u6dfb\u52a0\u4e86\u64cd\u4f5c\u70ed\u952e
        • \u4fee\u590d\u4e86\u7f16\u8f91\u5668\u5728\u65cb\u8f6c\u65f6\u4e22\u5931\u5185\u5bb9\u7684\u95ee\u9898
        • \u4fee\u590d\u4e86\u5176\u4ed6 bug

        \u5728 Google Play \u4e0b\u8f7d

        "},{"location":"qsl4a/","title":"QSL4A\uff08Android \u811a\u672c\u5c42\uff09API \u6587\u6863","text":"

        QSL4A \u662f QPython \u7684 Android \u811a\u672c\u5c42\uff0c\u5141\u8bb8\u60a8\u4f7f\u7528 Python \u63a7\u5236 Android \u8bbe\u5907\u529f\u80fd\u3002

        "},{"location":"qsl4a/#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a toast \u6d88\u606f\ndroid.makeToast('Hello QPython!')\n\n# \u9707\u52a8\u8bbe\u5907\ndroid.vibrate(500)\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\uff08\u5148\u5f00\u59cb\u76d1\u63a7\uff09\nimport time\ndroid.batteryStartMonitoring()\ntime.sleep(0.5)  # \u7b49\u5f85\u6570\u636e\nbattery = droid.readBatteryData().result\nprint(f\"\u7535\u6c60\uff1a{battery['level']}%\")\n
        "},{"location":"qsl4a/#_2","title":"\u6587\u6863\u7ed3\u6784","text":""},{"location":"qsl4a/#_3","title":"\u6838\u5fc3\u6a21\u5757","text":"
        • Android \u57fa\u7840 - \u6838\u5fc3\u8fde\u63a5\u548c RPC
        • Intent \u7cfb\u7edf - Android Intent \u64cd\u4f5c
        • \u4e8b\u4ef6\u7cfb\u7edf - \u4e8b\u4ef6\u5904\u7406\u548c\u5e7f\u64ad
        "},{"location":"qsl4a/#ui","title":"UI \u7ec4\u4ef6","text":"
        • \u5bf9\u8bdd\u6846 - \u8b66\u62a5\u3001\u8f93\u5165\u3001\u9009\u62e9\u5bf9\u8bdd\u6846
        • \u5168\u5c4f UI - \u81ea\u5b9a\u4e49\u5e03\u5c40 UI
        • \u60ac\u6d6e\u7a97 - \u60ac\u6d6e\u7a97\u53e3
        • \u8f85\u52a9\u529f\u80fd - \u5c4f\u5e55\u81ea\u52a8\u5316
        "},{"location":"qsl4a/#_4","title":"\u7cfb\u7edf","text":"
        • \u7535\u6c60 - \u7535\u6c60\u76d1\u63a7
        • \u4f20\u611f\u5668 - \u8bbe\u5907\u4f20\u611f\u5668
        • \u5e94\u7528 - \u5e94\u7528\u7ba1\u7406
        • \u7cfb\u7edf\u4fe1\u606f - \u8bbe\u5907\u4fe1\u606f
        • \u8bbe\u7f6e - \u7cfb\u7edf\u8bbe\u7f6e
        • \u5524\u9192\u9501 - \u5524\u9192\u9501\u63a7\u5236
        • QPython \u63a5\u53e3 - \u811a\u672c\u6267\u884c
        • Activity \u7ed3\u679c - Activity \u7ed3\u679c\u5904\u7406
        "},{"location":"qsl4a/#_5","title":"\u786c\u4ef6","text":"
        • \u84dd\u7259 - \u84dd\u7259\u64cd\u4f5c
        • \u76f8\u673a - \u62cd\u7167\u548c\u5f55\u50cf
        • \u97f3\u9891/\u5f55\u97f3\u5668 - \u5f55\u97f3
        • \u7f51\u7edc\u6444\u50cf\u5934 - MJPEG \u6d41
        • USB \u4e32\u53e3 - USB \u4e3b\u673a\u4e32\u53e3
        "},{"location":"qsl4a/#_6","title":"\u8fde\u63a5","text":"
        • WiFi - WiFi \u64cd\u4f5c
        • \u4f4d\u7f6e - GPS \u548c\u4f4d\u7f6e
        • \u77ed\u4fe1 - \u77ed\u4fe1\u64cd\u4f5c
        • \u7535\u8bdd - \u6253\u7535\u8bdd\u548c\u6765\u7535\u4fe1\u606f
        • \u8054\u7cfb\u4eba - \u8054\u7cfb\u4eba\u7ba1\u7406
        • \u4fe1\u53f7\u5f3a\u5ea6 - \u4fe1\u53f7\u76d1\u63a7
        • FTP \u670d\u52a1\u5668 - \u5185\u7f6e FTP \u670d\u52a1\u5668
        "},{"location":"qsl4a/#_7","title":"\u5b58\u50a8","text":"
        • DocumentFile - \u6587\u4ef6\u64cd\u4f5c
        • \u526a\u8d34\u677f - \u526a\u8d34\u677f\u64cd\u4f5c
        • \u504f\u597d\u8bbe\u7f6e - \u5171\u4eab\u504f\u597d\u8bbe\u7f6e
        "},{"location":"qsl4a/#_8","title":"\u5a92\u4f53","text":"
        • \u5a92\u4f53\u64ad\u653e\u5668 - \u97f3\u9891/\u89c6\u9891\u64ad\u653e
        • \u56fe\u50cf\u5904\u7406 - \u56fe\u50cf\u64cd\u4f5c
        "},{"location":"qsl4a/#_9","title":"\u7279\u6b8a\u529f\u80fd","text":"
        • \u52a0\u5bc6 - \u52a0\u5bc6/\u89e3\u5bc6
        • PGPT AI - AI \u8bed\u97f3\u670d\u52a1
        "},{"location":"qsl4a/#_10","title":"\u7ed3\u679c\u5bf9\u8c61","text":"

        \u5927\u591a\u6570 QSL4A \u65b9\u6cd5\u8fd4\u56de\u4e00\u4e2a\u5e26\u6709\u4ee5\u4e0b\u5c5e\u6027\u7684 Result \u547d\u540d\u5143\u7ec4\uff1a - id - \u8bf7\u6c42 ID - result - \u5b9e\u9645\u7ed3\u679c\u6570\u636e - error - \u5982\u679c\u5931\u8d25\u5219\u4e3a\u9519\u8bef\u6d88\u606f

        result = droid.getClipboard()\nif result.error is None:\n    print(result.result)\nelse:\n    print(f\"\u9519\u8bef\uff1a{result.error}\")\n
        "},{"location":"qsl4a/connectivity/contacts/","title":"\u8054\u7cfb\u4eba API","text":"

        \u8bbf\u95ee\u548c\u7ba1\u7406\u8bbe\u5907\u8054\u7cfb\u4eba\u3002

        "},{"location":"qsl4a/connectivity/contacts/#_1","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":""},{"location":"qsl4a/connectivity/contacts/#pickcontact","title":"pickContact()","text":"

        \u663e\u793a\u8054\u7cfb\u4eba\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

        pickContact()\n

        \u8fd4\u56de\uff1a \u5305\u542b\u8054\u7cfb\u4eba URI \u7684 Intent

        "},{"location":"qsl4a/connectivity/contacts/#pickphone","title":"pickPhone()","text":"

        \u663e\u793a\u7535\u8bdd\u53f7\u7801\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

        pickPhone()\n

        \u8fd4\u56de\uff1a \u9009\u4e2d\u7684\u7535\u8bdd\u53f7\u7801\u5b57\u7b26\u4e32

        "},{"location":"qsl4a/connectivity/contacts/#_2","title":"\u8054\u7cfb\u4eba\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#contactsget","title":"contactsGet()","text":"

        \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\u3002

        contactsGet(attributes=None)\n

        \u53c2\u6570\uff1a - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

        \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba JSONObject \u5217\u8868

        "},{"location":"qsl4a/connectivity/contacts/#contactsgetbyid","title":"contactsGetById()","text":"

        \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\u3002

        contactsGetById(id, attributes=None)\n

        \u53c2\u6570\uff1a - id (int): \u8054\u7cfb\u4eba ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

        \u8fd4\u56de\uff1a JSONObject \u8054\u7cfb\u4eba\u6570\u636e

        "},{"location":"qsl4a/connectivity/contacts/#contactsgetcount","title":"contactsGetCount()","text":"

        \u83b7\u53d6\u8054\u7cfb\u4eba\u603b\u6570\u3002

        contactsGetCount()\n

        \u8fd4\u56de\uff1a \u6574\u6570\u8ba1\u6570

        "},{"location":"qsl4a/connectivity/contacts/#contactsgetids","title":"contactsGetIds()","text":"

        \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba ID\u3002

        contactsGetIds()\n

        \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba ID \u6574\u6570\u5217\u8868

        "},{"location":"qsl4a/connectivity/contacts/#contactsgetattributes","title":"contactsGetAttributes()","text":"

        \u83b7\u53d6\u6240\u6709\u53ef\u80fd\u7684\u8054\u7cfb\u4eba\u5c5e\u6027\u3002

        contactsGetAttributes()\n

        \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u5217\u8868

        "},{"location":"qsl4a/connectivity/contacts/#_3","title":"\u5185\u5bb9\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#querycontent","title":"queryContent()","text":"

        \u4f7f\u7528\u81ea\u5b9a\u4e49\u53c2\u6570\u67e5\u8be2\u5185\u5bb9\u89e3\u6790\u5668\u3002

        queryContent(uri, attributes=None, selection=None, selectionArgs=None, order=None)\n

        \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u5c5e\u6027 - selection (str, optional): WHERE \u5b50\u53e5 - selectionArgs (list, optional): \u9009\u62e9\u53c2\u6570 - order (str, optional): ORDER BY \u5b50\u53e5

        \u8fd4\u56de\uff1a JSONObject \u7ed3\u679c\u5217\u8868

        "},{"location":"qsl4a/connectivity/contacts/#queryattributes","title":"queryAttributes()","text":"

        \u83b7\u53d6\u5185\u5bb9 URI \u7684\u5c5e\u6027\u3002

        queryAttributes(uri)\n

        \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI

        \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u7684 JSONArray

        "},{"location":"qsl4a/connectivity/contacts/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u9009\u62e9\u8054\u7cfb\u4eba\ncontact_uri = droid.pickContact().result\nprint(f\"Selected contact: {contact_uri}\")\n\n# \u9009\u62e9\u7535\u8bdd\u53f7\u7801\nphone = droid.pickPhone().result\nprint(f\"Selected phone: {phone}\")\n\n# \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\ncontacts = droid.contactsGet().result\nprint(f\"Total contacts: {len(contacts)}\")\n\n# \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\ncontact = droid.contactsGetById(1).result\nprint(f\"Contact: {contact}\")\n\n# \u83b7\u53d6\u8054\u7cfb\u4eba\u5c5e\u6027\nattrs = droid.contactsGetAttributes().result\nprint(f\"Available attributes: {attrs}\")\n
        "},{"location":"qsl4a/connectivity/ftp/","title":"FTP \u670d\u52a1\u5668 API","text":"

        \u5728\u8bbe\u5907\u4e0a\u542f\u52a8\u548c\u7ba1\u7406\u5185\u7f6e FTP \u670d\u52a1\u5668\u3002

        "},{"location":"qsl4a/connectivity/ftp/#ftp","title":"FTP \u670d\u52a1\u5668\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/ftp/#ftpstart","title":"ftpStart()","text":"

        \u542f\u52a8 FTP \u670d\u52a1\u5668\u3002

        ftpStart()\n

        \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4 [ip, port]

        "},{"location":"qsl4a/connectivity/ftp/#ftpstop","title":"ftpStop()","text":"

        \u505c\u6b62 FTP \u670d\u52a1\u5668\u3002

        ftpStop()\n
        "},{"location":"qsl4a/connectivity/ftp/#ftpisrunning","title":"ftpIsRunning()","text":"

        \u68c0\u67e5 FTP \u670d\u52a1\u5668\u662f\u5426\u6b63\u5728\u8fd0\u884c\u3002

        ftpIsRunning()\n

        \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u8fd0\u884c\u5219\u4e3a True

        "},{"location":"qsl4a/connectivity/ftp/#ftpget","title":"ftpGet()","text":"

        \u83b7\u53d6 FTP \u670d\u52a1\u5668 IP \u5730\u5740\u3002

        ftpGet()\n

        \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4

        "},{"location":"qsl4a/connectivity/ftp/#ftpset","title":"ftpSet()","text":"

        \u914d\u7f6e FTP \u670d\u52a1\u5668\u8bbe\u7f6e\u3002

        ftpSet(port=None, rootDir=None, username=None, password=None)\n

        \u53c2\u6570\uff1a - port (int, optional): \u670d\u52a1\u5668\u7aef\u53e3 - rootDir (str, optional): \u8981\u670d\u52a1\u7684\u57fa\u7840\u76ee\u5f55 - username (str, optional): \u767b\u5f55\u7528\u6237\u540d - password (str, optional): \u767b\u5f55\u5bc6\u7801

        \u8fd4\u56de\uff1a \u5305\u542b\u5f53\u524d\u8bbe\u7f6e\u7684 JSONObject

        "},{"location":"qsl4a/connectivity/ftp/#ftpstatus","title":"ftpStatus()","text":"

        \u83b7\u53d6 FTP \u670d\u52a1\u5668\u72b6\u6001\u3002

        ftpStatus()\n

        \u8fd4\u56de\uff1a \u72b6\u6001\u63cf\u8ff0\u5b57\u7b26\u4e32

        "},{"location":"qsl4a/connectivity/ftp/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u914d\u7f6e FTP \u670d\u52a1\u5668\ndroid.ftpSet(\n    port=2121,\n    rootDir=\"/sdcard\",\n    username=\"admin\",\n    password=\"secret\"\n)\n\n# \u542f\u52a8 FTP \u670d\u52a1\u5668\ninfo = droid.ftpStart().result\nprint(f\"FTP running at {info[0]}:{info[1]}\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.ftpIsRunning().result:\n    print(\"FTP server is running\")\n\n# \u83b7\u53d6\u670d\u52a1\u5668\u4fe1\u606f\nserver_info = droid.ftpGet().result\nprint(f\"Server: {server_info}\")\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.ftpStop()\n

        \u6ce8\u610f\uff1a \u4f7f\u7528\u63d0\u4f9b\u7684\u51ed\u636e\u901a\u8fc7\u4efb\u4f55 FTP \u5ba2\u6237\u7aef\u8fde\u63a5\u5230 FTP \u670d\u52a1\u5668\u3002

        "},{"location":"qsl4a/connectivity/location/","title":"\u4f4d\u7f6e API","text":"

        \u8bbf\u95ee GPS \u548c\u7f51\u7edc\u4f4d\u7f6e\u670d\u52a1\u3002

        "},{"location":"qsl4a/connectivity/location/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/location/#startlocating","title":"startLocating()","text":"

        \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\u3002

        startLocating(minUpdateTime=60000, minUpdateDistance=30, updateGnssStatus=False)\n

        \u53c2\u6570\uff1a - minUpdateTime (int): \u66f4\u65b0\u4e4b\u95f4\u7684\u6700\u5c0f\u65f6\u95f4\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a60000\uff09 - minUpdateDistance (float): \u66f4\u65b0\u7684\u6700\u5c0f\u8ddd\u79bb\uff08\u7c73\uff09\uff08\u9ed8\u8ba4\uff1a30\uff09 - updateGnssStatus (bool): \u542f\u7528 GNSS \u72b6\u6001\u66f4\u65b0\uff08\u9ed8\u8ba4\uff1aFalse\uff09

        "},{"location":"qsl4a/connectivity/location/#stoplocating","title":"stopLocating()","text":"

        \u505c\u6b62\u4f4d\u7f6e\u66f4\u65b0\u3002

        stopLocating()\n
        "},{"location":"qsl4a/connectivity/location/#readlocation","title":"readLocation()","text":"

        \u83b7\u53d6\u6700\u540e\u5df2\u77e5\u4f4d\u7f6e\u3002

        readLocation()\n

        \u8fd4\u56de\uff1a \u4f4d\u7f6e\u6570\u636e\u5b57\u5178

        "},{"location":"qsl4a/connectivity/location/#getlastknownlocation","title":"getLastKnownLocation()","text":"

        \u83b7\u53d6\u7f13\u5b58\u7684\u4f4d\u7f6e\u3002

        getLastKnownLocation()\n

        \u8fd4\u56de\uff1a \u6765\u81ea\u6240\u6709\u63d0\u4f9b\u5546\u7684\u4f4d\u7f6e

        "},{"location":"qsl4a/connectivity/location/#geocode","title":"geocode()","text":"

        \u5c06\u5730\u5740\u8f6c\u6362\u4e3a\u5750\u6807\u3002

        geocode(address, maxResults=1)\n
        "},{"location":"qsl4a/connectivity/location/#_2","title":"\u4f4d\u7f6e\u63d0\u4f9b\u5546\u65b9\u6cd5)","text":""},{"location":"qsl4a/connectivity/location/#locationproviders","title":"locationProviders()","text":"

        \u83b7\u53d6\u624b\u673a\u4e0a\u53ef\u7528\u7684\u4f4d\u7f6e\u63d0\u4f9b\u5546\u3002

        locationProviders()\n

        \u8fd4\u56de\uff1a \u53ef\u7528\u63d0\u4f9b\u5546\u540d\u79f0\u5217\u8868\uff08\u4f8b\u5982 ['gps', 'network']\uff09

        "},{"location":"qsl4a/connectivity/location/#locationproviderenabled","title":"locationProviderEnabled()","text":"

        \u68c0\u67e5\u7279\u5b9a\u4f4d\u7f6e\u63d0\u4f9b\u5546\u662f\u5426\u5df2\u542f\u7528\u3002

        locationProviderEnabled(provider)\n

        \u53c2\u6570\uff1a - provider (str): \u63d0\u4f9b\u5546\u540d\u79f0\uff08\u4f8b\u5982 'gps', 'network'\uff09

        \u8fd4\u56de\uff1a \u5982\u679c\u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

        "},{"location":"qsl4a/connectivity/location/#readgnssstatus","title":"readGnssStatus()","text":"

        \u8bfb\u53d6\u5168\u7403\u5bfc\u822a\u536b\u661f\u7cfb\u7edf\u72b6\u6001\uff08\u9700\u8981 Android 8+\uff09\u3002

        readGnssStatus()\n

        \u8fd4\u56de\uff1a \u5305\u542b GNSS \u536b\u661f\u4fe1\u606f\u7684 JSONArray

        "},{"location":"qsl4a/connectivity/location/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\ndroid.startLocating(minUpdateTime=5000, minUpdateDistance=1, updateGnssStatus=False)\n\n# \u7b49\u5f85\u5b9a\u4f4d\ntime.sleep(10)\n\n# \u83b7\u53d6\u4f4d\u7f6e\nloc = droid.readLocation().result\nif loc:\n    lat = loc['latitude']\n    lon = loc['longitude']\n    print(f\"Location: {lat}, {lon}\")\n\ndroid.stopLocating()\n
        "},{"location":"qsl4a/connectivity/phone/","title":"\u7535\u8bdd API","text":"

        \u63a7\u5236\u7535\u8bdd\u901a\u8bdd\u548c\u83b7\u53d6\u7535\u8bdd\u4fe1\u606f\u3002

        "},{"location":"qsl4a/connectivity/phone/#_1","title":"\u7535\u8bdd\u72b6\u6001\u8ddf\u8e2a","text":""},{"location":"qsl4a/connectivity/phone/#starttrackingphonestate","title":"startTrackingPhoneState()","text":"

        \u5f00\u59cb\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u53d8\u5316\u3002\u751f\u6210 'phone' \u4e8b\u4ef6\u3002

        startTrackingPhoneState()\n
        "},{"location":"qsl4a/connectivity/phone/#readphonestate","title":"readPhoneState()","text":"

        \u8bfb\u53d6\u5f53\u524d\u7535\u8bdd\u72b6\u6001\u3002

        readPhoneState()\n

        \u8fd4\u56de\uff1a \u5305\u542b\u7535\u8bdd\u72b6\u6001\u548c\u6765\u7535\u53f7\u7801\u7684 Bundle

        "},{"location":"qsl4a/connectivity/phone/#stoptrackingphonestate","title":"stopTrackingPhoneState()","text":"

        \u505c\u6b62\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u3002

        stopTrackingPhoneState()\n
        "},{"location":"qsl4a/connectivity/phone/#_2","title":"\u62e8\u6253\u7535\u8bdd","text":""},{"location":"qsl4a/connectivity/phone/#phonecall","title":"phoneCall()","text":"

        \u901a\u8fc7 URI \u547c\u53eb\u8054\u7cfb\u4eba/\u7535\u8bdd\u53f7\u7801\u3002

        phoneCall(uri)\n

        \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

        "},{"location":"qsl4a/connectivity/phone/#phonecallnumber","title":"phoneCallNumber()","text":"

        \u76f4\u63a5\u62e8\u6253\u7535\u8bdd\u53f7\u7801\u3002

        phoneCallNumber(phone_number)\n

        \u53c2\u6570\uff1a - phone_number (str): \u8981\u62e8\u6253\u7684\u7535\u8bdd\u53f7\u7801

        "},{"location":"qsl4a/connectivity/phone/#phonedial","title":"phoneDial()","text":"

        \u62e8\u6253\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

        phoneDial(uri)\n

        \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

        "},{"location":"qsl4a/connectivity/phone/#phonedialnumber","title":"phoneDialNumber()","text":"

        \u62e8\u6253\u7535\u8bdd\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

        phoneDialNumber(phone_number)\n

        \u53c2\u6570\uff1a - phone_number (str): \u7535\u8bdd\u53f7\u7801

        "},{"location":"qsl4a/connectivity/phone/#_3","title":"\u57fa\u7ad9\u4f4d\u7f6e","text":""},{"location":"qsl4a/connectivity/phone/#getcelllocation","title":"getCellLocation()","text":"

        \u83b7\u53d6\u5f53\u524d\u57fa\u7ad9\u4f4d\u7f6e\u3002

        getCellLocation()\n

        \u8fd4\u56de\uff1a \u5305\u542b\u57fa\u7ad9\u4f4d\u7f6e\u6570\u636e\u7684 JSONObject

        "},{"location":"qsl4a/connectivity/phone/#getallcellslocation","title":"getAllCellsLocation()","text":"

        \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u4f4d\u7f6e\uff08\u9002\u7528\u4e8e\u53cc\u5361\u8bbe\u5907\uff09\u3002

        getAllCellsLocation()\n

        \u8fd4\u56de\uff1a \u57fa\u7ad9\u4f4d\u7f6e\u7684 JSONArray

        "},{"location":"qsl4a/connectivity/phone/#_4","title":"\u7f51\u7edc\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getnetworkoperator","title":"getNetworkOperator()","text":"

        \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

        getNetworkOperator()\n

        \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

        "},{"location":"qsl4a/connectivity/phone/#getnetworkoperatorname","title":"getNetworkOperatorName()","text":"

        \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684\u540d\u79f0\u3002

        getNetworkOperatorName()\n

        \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

        "},{"location":"qsl4a/connectivity/phone/#getnetworktype","title":"getNetworkType()","text":"

        \u83b7\u53d6\u5f53\u524d\u7f51\u7edc\u7c7b\u578b\u3002

        getNetworkType()\n

        \u8fd4\u56de\uff1a \u63cf\u8ff0\u65e0\u7ebf\u7535\u6280\u672f\u7684\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'LTE', 'UMTS', 'GSM'\uff09

        "},{"location":"qsl4a/connectivity/phone/#getphonetype","title":"getPhoneType()","text":"

        \u83b7\u53d6\u7535\u8bdd\u7c7b\u578b\u3002

        getPhoneType()\n

        \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'GSM', 'CDMA', 'SIP'\uff09

        "},{"location":"qsl4a/connectivity/phone/#sim","title":"SIM \u5361\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getsimcountryiso","title":"getSimCountryIso()","text":"

        \u83b7\u53d6 SIM \u5361\u7684 ISO \u56fd\u5bb6\u4ee3\u7801\u3002

        getSimCountryIso()\n

        \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'us'\uff09

        "},{"location":"qsl4a/connectivity/phone/#getsimoperator","title":"getSimOperator()","text":"

        \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

        getSimOperator()\n

        \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

        "},{"location":"qsl4a/connectivity/phone/#getsimoperatorname","title":"getSimOperatorName()","text":"

        \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u540d\u79f0\u3002

        getSimOperatorName()\n

        \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

        "},{"location":"qsl4a/connectivity/phone/#getsimserialnumber","title":"getSimSerialNumber()","text":"

        \u83b7\u53d6 SIM \u5e8f\u5217\u53f7\u3002

        getSimSerialNumber()\n

        \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32 SIM \u5e8f\u5217\u53f7

        "},{"location":"qsl4a/connectivity/phone/#getsimstate","title":"getSimState()","text":"

        \u83b7\u53d6 SIM \u5361\u72b6\u6001\u3002

        getSimState()\n

        \u8fd4\u56de\uff1a \u63cf\u8ff0 SIM \u72b6\u6001\u7684\u5b57\u7b26\u4e32

        "},{"location":"qsl4a/connectivity/phone/#getsubscriberid","title":"getSubscriberId()","text":"

        \u83b7\u53d6\u8ba2\u9605\u8005 ID\u3002

        getSubscriberId()\n

        \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8ba2\u9605\u8005 ID

        "},{"location":"qsl4a/connectivity/phone/#_5","title":"\u8bed\u97f3\u90ae\u4ef6","text":""},{"location":"qsl4a/connectivity/phone/#getvoicemailalphatag","title":"getVoiceMailAlphaTag()","text":"

        \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u5b57\u6bcd\u6807\u7b7e\u3002

        getVoiceMailAlphaTag()\n

        \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u6807\u7b7e

        "},{"location":"qsl4a/connectivity/phone/#getvoicemailnumber","title":"getVoiceMailNumber()","text":"

        \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801\u3002

        getVoiceMailNumber()\n

        \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801

        "},{"location":"qsl4a/connectivity/phone/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getdeviceid","title":"getDeviceId()","text":"

        \u83b7\u53d6\u8bbe\u5907 ID\uff08GSM \u7684 IMEI\uff09\u3002\u5df2\u5e9f\u5f03\u3002

        getDeviceId()\n

        \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

        "},{"location":"qsl4a/connectivity/phone/#getdevicesoftwareversion","title":"getDeviceSoftwareVersion()","text":"

        \u83b7\u53d6\u8bbe\u5907\u8f6f\u4ef6\u7248\u672c\u3002

        getDeviceSoftwareVersion()\n

        \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8f6f\u4ef6\u7248\u672c

        "},{"location":"qsl4a/connectivity/phone/#getline1number","title":"getLine1Number()","text":"

        \u83b7\u53d6\u7ebf\u8def 1 \u7535\u8bdd\u53f7\u7801\u3002

        getLine1Number()\n

        \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u7535\u8bdd\u53f7\u7801

        "},{"location":"qsl4a/connectivity/phone/#checknetworkroaming","title":"checkNetworkRoaming()","text":"

        \u68c0\u67e5\u662f\u5426\u8fde\u63a5\u5230\u6f2b\u6e38\u7f51\u7edc\u3002

        checkNetworkRoaming()\n

        \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u6f2b\u6e38\u5219\u4e3a True

        "},{"location":"qsl4a/connectivity/phone/#_7","title":"\u57fa\u7ad9\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getallcellinfo","title":"getAllCellInfo()","text":"

        \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u7684\u4fe1\u606f\u3002

        getAllCellInfo()\n

        \u8fd4\u56de\uff1a \u57fa\u7ad9\u4fe1\u606f\u5217\u8868

        "},{"location":"qsl4a/connectivity/phone/#setdataenabled","title":"setDataEnabled()","text":"

        \u542f\u7528\u6216\u7981\u7528\u79fb\u52a8\u6570\u636e\u3002

        setDataEnabled(enabled)\n

        \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528

        "},{"location":"qsl4a/connectivity/phone/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7f51\u7edc\u4fe1\u606f\noperator = droid.getNetworkOperatorName().result\nprint(f\"Operator: {operator}\")\n\nnetwork_type = droid.getNetworkType().result\nprint(f\"Network: {network_type}\")\n\n# \u83b7\u53d6 SIM \u4fe1\u606f\nsim_state = droid.getSimState().result\nprint(f\"SIM: {sim_state}\")\n\n# \u83b7\u53d6\u7535\u8bdd\u53f7\u7801\nline1 = droid.getLine1Number().result\nprint(f\"Phone: {line1}\")\n\n# \u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\ndroid.startTrackingPhoneState()\nprint(\"Tracking phone state...\")\ndroid.stopTrackingPhoneState()\n
        "},{"location":"qsl4a/connectivity/signalstrength/","title":"\u4fe1\u53f7\u5f3a\u5ea6 API","text":"

        \u76d1\u63a7\u8702\u7a9d\u548c\u65e0\u7ebf\u4fe1\u53f7\u5f3a\u5ea6\u3002

        "},{"location":"qsl4a/connectivity/signalstrength/#_1","title":"\u4fe1\u53f7\u5f3a\u5ea6\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/signalstrength/#starttrackingsignalstrengths","title":"startTrackingSignalStrengths()","text":"

        \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316\u3002\u751f\u6210 'signal_strengths' \u4e8b\u4ef6\u3002

        startTrackingSignalStrengths()\n
        "},{"location":"qsl4a/connectivity/signalstrength/#stoptrackingsignalstrengths","title":"stopTrackingSignalStrengths()","text":"

        \u505c\u6b62\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u3002

        stopTrackingSignalStrengths()\n
        "},{"location":"qsl4a/connectivity/signalstrength/#readsignalstrengths","title":"readSignalStrengths()","text":"

        \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\u3002

        readSignalStrengths()\n

        \u8fd4\u56de\uff1a \u5305\u542b\u4fe1\u53f7\u5f3a\u5ea6\u6570\u636e\u7684 Bundle

        "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthlevel","title":"getTelephoneSignalStrengthLevel()","text":"

        \u83b7\u53d6\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u7b49\u7ea7\uff080-4\uff09\u3002

        getTelephoneSignalStrengthLevel()\n

        \u8fd4\u56de\uff1a \u6574\u6570\u7b49\u7ea7\uff080=\u65e0\uff0c1=\u5dee\uff0c2=\u4e00\u822c\uff0c3=\u597d\uff0c4=\u4f18\u79c0\uff09

        "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthdetail","title":"getTelephoneSignalStrengthDetail()","text":"

        \u83b7\u53d6\u8be6\u7ec6\u7684\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u4fe1\u606f\u3002

        getTelephoneSignalStrengthDetail()\n

        \u8fd4\u56de\uff1a \u5305\u542b\u8be6\u7ec6\u4fe1\u53f7\u4fe1\u606f\u7684\u5b57\u7b26\u4e32

        "},{"location":"qsl4a/connectivity/signalstrength/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\ndroid.startTrackingSignalStrengths()\n\n# \u7b49\u5f85\u4fe1\u53f7\u66f4\u65b0\ntime.sleep(5)\n\n# \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\nsignal = droid.readSignalStrengths().result\nprint(f\"Signal: {signal}\")\n\n# \u76f4\u63a5\u83b7\u53d6\u7b49\u7ea7\nlevel = droid.getTelephoneSignalStrengthLevel().result\nprint(f\"Signal level: {level}/4\")\n\ndroid.stopTrackingSignalStrengths()\n
        "},{"location":"qsl4a/connectivity/sms/","title":"SMS API","text":"

        \u53d1\u9001\u548c\u63a5\u6536 SMS \u6d88\u606f\u3002

        "},{"location":"qsl4a/connectivity/sms/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/sms/#smssend","title":"smsSend()","text":"

        \u53d1\u9001 SMS \u6d88\u606f\u3002

        smsSend(destinationAddress, text)\n

        \u53c2\u6570\uff1a - destinationAddress (str): \u7535\u8bdd\u53f7\u7801 - text (str): \u6d88\u606f\u6587\u672c

        "},{"location":"qsl4a/connectivity/sms/#smsgetmessagecount","title":"smsGetMessageCount()","text":"

        \u83b7\u53d6\u6d88\u606f\u6570\u91cf\u3002

        smsGetMessageCount(unreadOnly=False, folder=\"inbox\")\n
        "},{"location":"qsl4a/connectivity/sms/#smsgetmessageids","title":"smsGetMessageIds()","text":"

        \u83b7\u53d6\u6d88\u606f ID\u3002

        smsGetMessageIds(unreadOnly=False, folder=\"inbox\")\n
        "},{"location":"qsl4a/connectivity/sms/#smsgetmessages","title":"smsGetMessages()","text":"

        \u83b7\u53d6\u6d88\u606f\u8be6\u60c5\u3002

        smsGetMessages(unreadOnly=False, folder=\"inbox\", attributes=None)\n
        "},{"location":"qsl4a/connectivity/sms/#smsgetmessagebyid","title":"smsGetMessageById()","text":"

        \u901a\u8fc7 ID \u83b7\u53d6\u7279\u5b9a\u6d88\u606f\u3002

        smsGetMessageById(id, attributes=None)\n

        \u53c2\u6570\uff1a - id (int): \u6d88\u606f ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

        \u8fd4\u56de\uff1a \u6d88\u606f\u6570\u636e\u5b57\u5178

        "},{"location":"qsl4a/connectivity/sms/#smsgetattributes","title":"smsGetAttributes()","text":"

        \u83b7\u53d6\u53ef\u7528\u7684 SMS \u6d88\u606f\u5c5e\u6027\u3002

        smsGetAttributes()\n

        \u8fd4\u56de\uff1a \u53ef\u7528\u5c5e\u6027\u540d\u79f0\u5217\u8868

        "},{"location":"qsl4a/connectivity/sms/#smsdeletemessage","title":"smsDeleteMessage()","text":"

        \u5220\u9664\u6d88\u606f\u3002

        smsDeleteMessage(id)\n
        "},{"location":"qsl4a/connectivity/sms/#smsmarkmessageread","title":"smsMarkMessageRead()","text":"

        \u5c06\u6d88\u606f\u6807\u8bb0\u4e3a\u5df2\u8bfb\u3002

        smsMarkMessageRead(ids, read=True)\n
        "},{"location":"qsl4a/connectivity/sms/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u53d1\u9001 SMS\ndroid.smsSend(\"+1234567890\", \"Hello from QPython!\")\n\n# \u83b7\u53d6\u672a\u8bfb\u6d88\u606f\nmessages = droid.smsGetMessages(unreadOnly=True).result\nfor msg in messages:\n    print(f\"From: {msg['address']}, Text: {msg['body']}\")\n
        "},{"location":"qsl4a/connectivity/wifi/","title":"WiFi API","text":"

        \u63a7\u5236 WiFi \u9002\u914d\u5668\u5e76\u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\u3002

        "},{"location":"qsl4a/connectivity/wifi/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/connectivity/wifi/#checkwifistate","title":"checkWifiState()","text":"

        \u68c0\u67e5 WiFi \u662f\u5426\u5df2\u542f\u7528\u3002

        checkWifiState()\n

        \u8fd4\u56de\uff1a \u5982\u679c WiFi \u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

        "},{"location":"qsl4a/connectivity/wifi/#togglewifistate","title":"toggleWifiState()","text":"

        \u6253\u5f00\u6216\u5173\u95ed WiFi\u3002

        toggleWifiState(enabled=None)\n

        \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

        \u8fd4\u56de\uff1a \u5982\u679c\u64cd\u4f5c\u6210\u529f\u5219\u4e3a True

        "},{"location":"qsl4a/connectivity/wifi/#wifistartscan","title":"wifiStartScan()","text":"

        \u5f00\u59cb\u626b\u63cf\u53ef\u7528\u7684 WiFi \u7f51\u7edc\u3002

        wifiStartScan()\n
        "},{"location":"qsl4a/connectivity/wifi/#wifigetscanresults","title":"wifiGetScanResults()","text":"

        \u83b7\u53d6\u53d1\u73b0\u7684 WiFi \u7f51\u7edc\u5217\u8868\u3002

        wifiGetScanResults()\n

        \u8fd4\u56de\uff1a \u63a5\u5165\u70b9\u4fe1\u606f\u5217\u8868

        "},{"location":"qsl4a/connectivity/wifi/#_2","title":"\u8fde\u63a5\u7ba1\u7406","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetconnectioninfo","title":"wifiGetConnectionInfo()","text":"

        \u83b7\u53d6\u8be6\u7ec6\u8fde\u63a5\u4fe1\u606f\u3002

        wifiGetConnectionInfo()\n

        \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001IP \u5730\u5740\u7b49\u8fde\u63a5\u8be6\u60c5\u7684\u5b57\u5178

        "},{"location":"qsl4a/connectivity/wifi/#getconnectedinfo","title":"getConnectedInfo()","text":"

        \u83b7\u53d6\u8fde\u63a5\u7684 WiFi \u7f51\u7edc\u4fe1\u606f\uff08\u7b80\u5316\u7248\uff09\u3002

        getConnectedInfo()\n

        \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001\u4fe1\u53f7\u5f3a\u5ea6\u7684\u5b57\u5178

        "},{"location":"qsl4a/connectivity/wifi/#getdhcpinfo","title":"getDhcpInfo()","text":"

        \u83b7\u53d6\u5f53\u524d\u8fde\u63a5\u7684 DHCP \u4fe1\u606f\u3002

        getDhcpInfo(ipConvertToString=True)\n

        \u53c2\u6570\uff1a - ipConvertToString (bool): \u5c06 IP \u5730\u5740\u8f6c\u6362\u4e3a\u5b57\u7b26\u4e32\u683c\u5f0f\uff08\u9ed8\u8ba4\uff1aTrue\uff09

        \u8fd4\u56de\uff1a \u5305\u542b IP\u3001\u7f51\u5173\u3001DNS \u7b49 DHCP \u4fe1\u606f\u7684\u5b57\u5178

        "},{"location":"qsl4a/connectivity/wifi/#wifidisconnect","title":"wifiDisconnect()","text":"

        \u65ad\u5f00\u5f53\u524d WiFi \u7f51\u7edc\u8fde\u63a5\u3002

        wifiDisconnect()\n
        "},{"location":"qsl4a/connectivity/wifi/#wifireconnect","title":"wifiReconnect()","text":"

        \u91cd\u65b0\u8fde\u63a5\u5230\u5f53\u524d\u7f51\u7edc\u3002

        wifiReconnect()\n
        "},{"location":"qsl4a/connectivity/wifi/#wifireassociate","title":"wifiReassociate()","text":"

        \u91cd\u65b0\u5173\u8054\u5f53\u524d\u63a5\u5165\u70b9\u3002

        wifiReassociate()\n
        "},{"location":"qsl4a/connectivity/wifi/#_3","title":"\u70ed\u70b9","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetapstate","title":"wifiGetApState()","text":"

        \u83b7\u53d6 WiFi AP\uff08\u70ed\u70b9\uff09\u72b6\u6001\u3002

        wifiGetApState()\n

        \u8fd4\u56de\uff1a \u70ed\u70b9\u72b6\u6001

        "},{"location":"qsl4a/connectivity/wifi/#wifi","title":"WiFi \u9501","text":""},{"location":"qsl4a/connectivity/wifi/#wifilockacquirefull","title":"wifiLockAcquireFull()","text":"

        \u83b7\u53d6\u5b8c\u6574 WiFi \u9501\uff08\u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\u4e5f\u4fdd\u6301 WiFi \u6d3b\u52a8\uff09\u3002

        wifiLockAcquireFull()\n
        "},{"location":"qsl4a/connectivity/wifi/#wifilockacquirescanonly","title":"wifiLockAcquireScanOnly()","text":"

        \u83b7\u53d6\u4ec5\u626b\u63cf WiFi \u9501\u3002

        wifiLockAcquireScanOnly()\n
        "},{"location":"qsl4a/connectivity/wifi/#wifilockrelease","title":"wifiLockRelease()","text":"

        \u91ca\u653e WiFi \u9501\u3002

        wifiLockRelease()\n
        "},{"location":"qsl4a/connectivity/wifi/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u68c0\u67e5 WiFi \u72b6\u6001\nif droid.checkWifiState().result:\n    print(\"WiFi is enabled\")\nelse:\n    print(\"Enabling WiFi...\")\n    droid.toggleWifiState(True)\n    time.sleep(2)\n\n# \u5f00\u59cb\u626b\u63cf\ndroid.wifiStartScan()\ntime.sleep(3)\n\n# \u83b7\u53d6\u626b\u63cf\u7ed3\u679c\nnetworks = droid.wifiGetScanResults().result\nfor network in networks:\n    print(f\"SSID: {network.get('SSID')}, Signal: {network.get('level')} dBm\")\n\n# \u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\ninfo = droid.wifiGetConnectionInfo().result\nif info:\n    print(f\"Connected to: {info.get('ssid')}\")\n    print(f\"BSSID: {info.get('bssid')}\")\n    print(f\"IP: {info.get('ip_address')}\")\n\n# \u83b7\u53d6 DHCP \u4fe1\u606f\ndhcp = droid.getDhcpInfo().result\nif dhcp:\n    print(f\"Gateway: {dhcp.get('gateway')}\")\n    print(f\"DNS: {dhcp.get('dns1')}\")\n\n# \u83b7\u53d6\u7b80\u5316\u7684\u8fde\u63a5\u4fe1\u606f\nconnected = droid.getConnectedInfo().result\nprint(f\"SSID: {connected.get('ssid')}, Signal: {connected.get('level')} dBm\")\n\n# \u65ad\u5f00\u5e76\u91cd\u65b0\u8fde\u63a5\ndroid.wifiDisconnect()\ntime.sleep(1)\ndroid.wifiReconnect()\n\n# \u91cd\u65b0\u5173\u8054\u63a5\u5165\u70b9\ndroid.wifiReassociate()\n\n# \u68c0\u67e5\u70ed\u70b9\u72b6\u6001\nap_state = droid.wifiGetApState().result\nprint(f\"Hotspot state: {ap_state}\")\n\n# \u83b7\u53d6 WiFi \u9501\u4ee5\u8fdb\u884c\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireFull()\n# ... \u6267\u884c\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n\n# \u6216\u4f7f\u7528\u4ec5\u626b\u63cf\u9501\u4ee5\u8fdb\u884c\u8f83\u8f7b\u7684\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireScanOnly()\n# ... \u6267\u884c\u626b\u63cf\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n
        "},{"location":"qsl4a/core/android-base/","title":"Android \u57fa\u7840\u7c7b","text":"

        Android \u7c7b\u662f QSL4A \u7684\u6838\u5fc3\uff0c\u63d0\u4f9b\u4e86\u4e0e Android \u8fd0\u884c\u65f6\u7684\u8fde\u63a5\u548c RPC \u673a\u5236\u3002

        "},{"location":"qsl4a/core/android-base/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
        # \u529f\u80fd\u5b8c\u6574\u7248\u672c\uff08\u63a8\u8350\uff09\nimport androidhelper\ndroid = androidhelper.Android()\n\n# \u7b80\u5316\u7248\u672c\uff08\u5feb\u901f\uff0c\u5355\u5b9e\u4f8b\uff09\nimport android\ndroid = android.droid\n
        "},{"location":"qsl4a/core/android-base/#android_1","title":"\u7c7b\uff1aAndroid","text":""},{"location":"qsl4a/core/android-base/#_2","title":"\u6784\u9020\u51fd\u6570","text":"
        Android(addr=None)\n

        \u53c2\u6570\uff1a - addr (tuple, optional): (HOST, PORT) \u5730\u5740\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u73af\u5883\u53d8\u91cf AP_HOST \u548c AP_PORT

        \u73af\u5883\u53d8\u91cf\uff1a - AP_HOST - \u670d\u52a1\u5668\u4e3b\u673a\u5730\u5740 - AP_PORT - \u670d\u52a1\u5668\u7aef\u53e3 - AP_HANDSHAKE - \u8ba4\u8bc1\u4ee4\u724c

        "},{"location":"qsl4a/core/android-base/#_3","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/android-base/#_rpc","title":"_rpc()","text":"

        \u8c03\u7528 Android \u51fd\u6570\u7684\u5185\u90e8 RPC \u65b9\u6cd5\u3002

        _rpc(method, *args)\n

        \u53c2\u6570\uff1a - method (str): \u8981\u8c03\u7528\u7684\u65b9\u6cd5\u540d - *args: \u65b9\u6cd5\u7684\u53ef\u53d8\u53c2\u6570

        \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4\uff0c\u5305\u542b\u4ee5\u4e0b\u5b57\u6bb5\uff1a - id (int): \u8bf7\u6c42 ID - result: \u65b9\u6cd5\u8fd4\u56de\u503c - error (str or None): \u9519\u8bef\u4fe1\u606f\uff08\u5982\u679c\u5931\u8d25\uff09

        "},{"location":"qsl4a/core/android-base/#getattr","title":"getattr()","text":"

        \u52a8\u6001\u65b9\u6cd5\u5206\u53d1\u5668\u3002\u6240\u6709 Android \u65b9\u6cd5\u90fd\u901a\u8fc7\u5c5e\u6027\u67e5\u627e\u8bbf\u95ee\u3002

        # \u4ee5\u4e0b\u4e24\u79cd\u65b9\u5f0f\u7b49\u4ef7\uff1a\ndroid.makeToast(\"Hello\")\ndroid._rpc(\"makeToast\", \"Hello\")\n
        "},{"location":"qsl4a/core/android-base/#androidpy","title":"\u72ec\u7acb\u51fd\u6570\uff08android.py\uff09","text":"

        \u4f7f\u7528\u7b80\u5316\u7684 android \u6a21\u5757\u65f6\uff1a

        "},{"location":"qsl4a/core/android-base/#jsla","title":"jsla()","text":"

        \u53d1\u9001 JSON-RPC \u8bf7\u6c42\u5e76\u8fd4\u56de\u539f\u59cb\u54cd\u5e94\u3002

        jsla(method, *params)\n

        \u8fd4\u56de\uff1a JSON \u5b57\u7b26\u4e32\u54cd\u5e94

        "},{"location":"qsl4a/core/android-base/#rsla","title":"rsla()","text":"

        \u53d1\u9001\u8bf7\u6c42\u5e76\u4ec5\u8fd4\u56de\u7ed3\u679c\u3002

        rsla(method, *params)\n

        \u8fd4\u56de\uff1a RPC \u8c03\u7528\u7684\u7ed3\u679c\u503c

        "},{"location":"qsl4a/core/android-base/#esla","title":"esla()","text":"

        \u53d1\u9001\u8bf7\u6c42\uff0c\u9519\u8bef\u65f6\u629b\u51fa\u5f02\u5e38\u3002

        esla(method, *params)\n

        \u629b\u51fa\uff1a \u5982\u679c error \u5b57\u6bb5\u4e0d\u4e3a None \u5219\u629b\u51fa\u5f02\u5e38

        "},{"location":"qsl4a/core/android-base/#nsla","title":"nsla()","text":"

        \u53d1\u9001\u8bf7\u6c42\u5e76\u8fd4\u56de Result \u547d\u540d\u5143\u7ec4\u3002

        nsla(method, *params)\n

        \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4

        "},{"location":"qsl4a/core/android-base/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/android-base/#_5","title":"\u57fa\u672c\u8fde\u63a5","text":"
        import androidhelper\n\n# \u8fde\u63a5\u5230 Android \u8fd0\u884c\u65f6\ndroid = androidhelper.Android()\n\n# \u901a\u8fc7\u663e\u793a toast \u6765\u68c0\u67e5\u8fde\u63a5\ndroid.makeToast(\"Connected!\")\n
        "},{"location":"qsl4a/core/android-base/#_6","title":"\u9519\u8bef\u5904\u7406","text":"
        result = droid.someMethod()\nif result.error:\n    print(f\"Error: {result.error}\")\nelse:\n    print(f\"Success: {result.result}\")\n
        "},{"location":"qsl4a/core/android-base/#rpc","title":"\u76f4\u63a5 RPC \u8c03\u7528","text":"
        # \u76f4\u63a5\u8c03\u7528\u4efb\u610f\u65b9\u6cd5\nresult = droid._rpc(\"makeToast\", \"Hello World\")\n
        "},{"location":"qsl4a/core/events/","title":"\u4e8b\u4ef6\u7cfb\u7edf","text":"

        QSL4A \u63d0\u4f9b\u4e86\u4e00\u4e2a\u4e8b\u4ef6\u7cfb\u7edf\uff0c\u7528\u4e8e\u5904\u7406\u6765\u81ea Android \u7684\u5f02\u6b65\u4e8b\u4ef6\uff0c\u5982\u4f20\u611f\u5668\u66f4\u65b0\u3001\u4f4d\u7f6e\u53d8\u5316\u548c\u81ea\u5b9a\u4e49\u5e7f\u64ad\u3002

        "},{"location":"qsl4a/core/events/#_2","title":"\u4e8b\u4ef6\u57fa\u7840","text":"

        \u4e8b\u4ef6\u5b58\u50a8\u5728\u7f13\u51b2\u533a\u4e2d\uff0c\u53ef\u4ee5\u8f6e\u8be2\u6216\u7b49\u5f85\u3002\u6bcf\u4e2a\u4e8b\u4ef6\u5305\u542b\uff1a - name: \u4e8b\u4ef6\u7c7b\u578b/\u540d\u79f0 - data: \u4e8b\u4ef6\u8d1f\u8f7d\u6570\u636e - time: \u65f6\u95f4\u6233

        "},{"location":"qsl4a/core/events/#_3","title":"\u4e8b\u4ef6\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#eventclearbuffer","title":"eventClearBuffer()","text":"

        \u6e05\u9664\u7f13\u51b2\u533a\u4e2d\u7684\u6240\u6709\u5f85\u5904\u7406\u4e8b\u4ef6\u3002

        eventClearBuffer()\n

        \u8fd4\u56de\uff1a None

        "},{"location":"qsl4a/core/events/#eventpoll","title":"eventPoll()","text":"

        \u8f6e\u8be2\u7f13\u51b2\u533a\u4e2d\u7684\u4e8b\u4ef6\u3002

        eventPoll(number_of_events=1)\n

        \u53c2\u6570\uff1a - number_of_events (int): \u8981\u68c0\u7d22\u7684\u6700\u5927\u4e8b\u4ef6\u6570\uff08\u9ed8\u8ba4\uff1a1\uff09

        \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\u5217\u8868

        "},{"location":"qsl4a/core/events/#eventwait","title":"eventWait()","text":"

        \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\u3002

        eventWait(timeout=None)\n

        \u53c2\u6570\uff1a - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09\u3002None = \u6c38\u4e45\u7b49\u5f85

        \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

        "},{"location":"qsl4a/core/events/#eventwaitfor","title":"eventWaitFor()","text":"

        \u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6\u3002

        eventWaitFor(eventName, timeout=None)\n

        \u53c2\u6570\uff1a - eventName (str): \u8981\u7b49\u5f85\u7684\u4e8b\u4ef6\u540d\u79f0 - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

        \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

        "},{"location":"qsl4a/core/events/#eventpost","title":"eventPost()","text":"

        \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\u3002

        eventPost(name, data, enqueue=None)\n

        \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e\uff08\u4efb\u610f\u7c7b\u578b\uff09 - enqueue (bool, optional): \u5982\u679c\u4e3a True \u5219\u6dfb\u52a0\u5230\u961f\u5217

        "},{"location":"qsl4a/core/events/#receiveevent","title":"receiveEvent()","text":"

        \u63a5\u6536\u4e8b\u4ef6\uff08\u963b\u585e\uff09\u3002

        receiveEvent()\n

        \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61

        "},{"location":"qsl4a/core/events/#_4","title":"\u5e7f\u64ad\u4e8b\u4ef6","text":"

        \u6ce8\u518c\u7cfb\u7edf\u5e7f\u64ad\u4e8b\u4ef6\u3002

        "},{"location":"qsl4a/core/events/#eventregisterforbroadcast","title":"eventRegisterForBroadcast()","text":"

        \u6ce8\u518c\u63a5\u6536\u5e7f\u64ad\u4e8b\u4ef6\u3002

        eventRegisterForBroadcast(category, enqueue=True)\n

        \u53c2\u6570\uff1a - category (str): \u5e7f\u64ad\u7c7b\u522b/\u52a8\u4f5c - enqueue (bool): \u6dfb\u52a0\u5230\u4e8b\u4ef6\u961f\u5217

        "},{"location":"qsl4a/core/events/#eventunregisterforbroadcast","title":"eventUnregisterForBroadcast()","text":"

        \u53d6\u6d88\u6ce8\u518c\u5e7f\u64ad\u4e8b\u4ef6\u3002

        eventUnregisterForBroadcast(category)\n
        "},{"location":"qsl4a/core/events/#eventgetbrodcastcategories","title":"eventGetBrodcastCategories()","text":"

        \u83b7\u53d6\u5df2\u6ce8\u518c\u7684\u5e7f\u64ad\u7c7b\u522b\u3002

        eventGetBrodcastCategories()\n

        \u8fd4\u56de\uff1a \u5df2\u6ce8\u518c\u7c7b\u522b\u5217\u8868

        "},{"location":"qsl4a/core/events/#_5","title":"\u4e8b\u4ef6\u5206\u53d1\u5668)","text":""},{"location":"qsl4a/core/events/#starteventdispatcher","title":"startEventDispatcher()","text":"

        \u6253\u5f00\u4e00\u4e2a\u53ef\u4ee5\u8bfb\u53d6\u5df2\u53d1\u5e03\u4e8b\u4ef6\u7684\u5957\u63a5\u5b57\u3002)

        startEventDispatcher(port=0)\n

        \u53c2\u6570\uff1a - port (int, optional): \u76d1\u542c\u7684\u7aef\u53e3\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\u9009\u62e9\uff09

        \u8fd4\u56de\uff1a \u6b63\u5728\u76d1\u542c\u7684\u7aef\u53e3\u53f7

        "},{"location":"qsl4a/core/events/#stopeventdispatcher","title":"stopEventDispatcher()","text":"

        \u505c\u6b62\u4e8b\u4ef6\u670d\u52a1\u5668\u3002)

        stopEventDispatcher()\n
        "},{"location":"qsl4a/core/events/#_6","title":"\u5df2\u5e9f\u5f03\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#rpcpostevent","title":"rpcPostEvent()","text":"

        \u5c06\u4e8b\u4ef6\u53d1\u5e03\u5230\u4e8b\u4ef6\u961f\u5217\u3002\uff08\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 eventPost\uff09

        rpcPostEvent(name, data)\n

        \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e

        "},{"location":"qsl4a/core/events/#_7","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/events/#_8","title":"\u57fa\u672c\u4e8b\u4ef6\u8f6e\u8be2","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6e05\u9664\u65e7\u4e8b\u4ef6\ndroid.eventClearBuffer()\n\n# \u8f6e\u8be2\u4e8b\u4ef6\nevents = droid.eventPoll(5).result\nfor event in events:\n    print(f\"Event: {event['name']}, Data: {event['data']}\")\n
        "},{"location":"qsl4a/core/events/#_9","title":"\u7b49\u5f85\u4e8b\u4ef6","text":"
        # \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\uff0c\u5e26\u8d85\u65f6\nevent = droid.eventWait(timeout=10).result\nif event:\n    print(f\"Got event: {event['name']}\")\n
        "},{"location":"qsl4a/core/events/#_10","title":"\u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6","text":"
        # \u7b49\u5f85\u4f20\u611f\u5668\u4e8b\u4ef6\nevent = droid.eventWaitFor('screen', timeout=5).result\nif event:\n    print(f\"Screen event: {event['data']}\")\n
        "},{"location":"qsl4a/core/events/#_11","title":"\u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6","text":"
        # \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\ndroid.eventPost('my_event', {'key': 'value'})\n\n# \u7b49\u5f85\u5b83\nevent = droid.eventWaitFor('my_event', timeout=1).result\n
        "},{"location":"qsl4a/core/events/#_12","title":"\u5e7f\u64ad\u63a5\u6536\u5668","text":"
        # \u6ce8\u518c\u5c4f\u5e55\u5f00\u5173\u4e8b\u4ef6\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_ON')\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_OFF')\n\n# \u7b49\u5f85\u5c4f\u5e55\u4e8b\u4ef6\nwhile True:\n    event = droid.receiveEvent().result\n    if event['name'] == 'android.intent.action.SCREEN_ON':\n        print(\"Screen turned on\")\n    elif event['name'] == 'android.intent.action.SCREEN_OFF':\n        print(\"Screen turned off\")\n
        "},{"location":"qsl4a/core/events/#_13","title":"\u4f20\u611f\u5668\u4e8b\u4ef6\u5904\u7406","text":"
        # \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u5904\u7406\u4f20\u611f\u5668\u4e8b\u4ef6\nfor _ in range(100):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'sensors':\n        data = event['data']\n        print(f\"Accel: {data['xforce']}, {data['yforce']}, {data['zforce']}\")\n\ndroid.stopSensing()\n
        "},{"location":"qsl4a/core/events/#_14","title":"\u5e38\u89c1\u4e8b\u4ef6\u7c7b\u578b","text":"\u4e8b\u4ef6\u540d\u79f0 \u63cf\u8ff0 \u6765\u6e90 sensors \u4f20\u611f\u5668\u6570\u636e\u66f4\u65b0 startSensing* location GPS \u4f4d\u7f6e\u66f4\u65b0 startLocating phone \u7535\u8bdd\u72b6\u6001\u53d8\u5316 startTrackingPhoneState signal \u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316 startTrackingSignalStrength screen \u622a\u56fe\u5c31\u7eea fullGetScreenShot dialog \u5bf9\u8bdd\u6846\u54cd\u5e94 dialogShow*"},{"location":"qsl4a/core/events/#_15","title":"\u4e8b\u4ef6\u6570\u636e\u7ed3\u6784","text":"
        {\n    'name': 'event_name',\n    'data': {\n        # \u4e8b\u4ef6\u7279\u5b9a\u6570\u636e\n    },\n    'time': 1234567890  # \u65f6\u95f4\u6233\n}\n
        "},{"location":"qsl4a/core/intent/","title":"Intent \u7cfb\u7edf","text":"

        Android Intent \u7528\u4e8e\u542f\u52a8\u6d3b\u52a8\u3001\u53d1\u9001\u5e7f\u64ad\u548c\u5e94\u7528\u95f4\u901a\u4fe1\u3002QSL4A \u901a\u8fc7 Intent \u6a21\u5757\u63d0\u4f9b\u5b8c\u6574\u7684 Intent \u652f\u6301\u3002

        "},{"location":"qsl4a/core/intent/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
        import androidhelper\ndon = androidhelper.Android()\n
        "},{"location":"qsl4a/core/intent/#intent_1","title":"Intent \u5e38\u91cf","text":"

        \u901a\u8fc7 droid.Intent \u8bbf\u95ee\uff1a

        "},{"location":"qsl4a/core/intent/#_2","title":"\u64cd\u4f5c","text":"\u5e38\u91cf \u503c \u7528\u9014 ACTION_MAIN android.intent.action.MAIN \u5e94\u7528\u5165\u53e3\u70b9 ACTION_VIEW android.intent.action.VIEW \u67e5\u770b\u5185\u5bb9 ACTION_EDIT android.intent.action.EDIT \u7f16\u8f91\u5185\u5bb9 ACTION_PICK android.intent.action.PICK \u9009\u62e9\u9879\u76ee ACTION_SEND android.intent.action.SEND \u5206\u4eab\u5185\u5bb9 ACTION_SEARCH android.intent.action.SEARCH \u641c\u7d22"},{"location":"qsl4a/core/intent/#_3","title":"\u6807\u5fd7","text":"\u5e38\u91cf \u503c \u7528\u9014 FLAG_ACTIVITY_NEW_TASK 268435456 \u542f\u52a8\u65b0\u4efb\u52a1 FLAG_ACTIVITY_CLEAR_TASK 32768 \u6e05\u9664\u4efb\u52a1\u5806\u6808 FLAG_ACTIVITY_NEW_DOCUMENT 524288 \u65b0\u6587\u6863\u6a21\u5f0f"},{"location":"qsl4a/core/intent/#_4","title":"\u9644\u52a0\u6570\u636e","text":"\u5e38\u91cf \u7528\u9014 EXTRA_TEXT \u6587\u672c\u5185\u5bb9 EXTRA_STREAM \u6587\u4ef6 URI EXTRA_SUBJECT \u4e3b\u9898\u884c EXTRA_EMAIL \u7535\u5b50\u90ae\u4ef6\u5730\u5740"},{"location":"qsl4a/core/intent/#_5","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/intent/#makeintent","title":"makeIntent()","text":"

        \u521b\u5efa Intent \u5bf9\u8c61\u3002

        makeIntent(action, uri=None, type=None, extras=None, categories=None,\n           packagename=None, classname=None, flags=None)\n

        \u53c2\u6570\uff1a - action (str): Intent \u64cd\u4f5c\uff08\u4f8b\u5982 droid.Intent.ACTION_VIEW\uff09 - uri (str, optional): \u6570\u636e URI - type (str, optional): MIME \u7c7b\u578b - extras (dict, optional): \u9644\u52a0\u6570\u636e - categories (list, optional): Intent \u7c7b\u522b - packagename (str, optional): \u76ee\u6807\u5305 - classname (str, optional): \u76ee\u6807\u7c7b - flags (int, optional): Intent \u6807\u5fd7

        \u8fd4\u56de\uff1a Intent \u5bf9\u8c61

        "},{"location":"qsl4a/core/intent/#startactivityintent","title":"startActivityIntent()","text":"

        \u4f7f\u7528 Intent \u542f\u52a8 Activity\u3002

        startActivityIntent(intent, wait=None)\n

        \u53c2\u6570\uff1a - intent: makeIntent() \u8fd4\u56de\u7684 Intent \u5bf9\u8c61 - wait (bool, optional): \u963b\u585e\u76f4\u5230\u6d3b\u52a8\u5173\u95ed

        "},{"location":"qsl4a/core/intent/#startactivityforresultintent","title":"startActivityForResultIntent()","text":"

        \u542f\u52a8\u6d3b\u52a8\u5e76\u7b49\u5f85\u7ed3\u679c\u3002

        startActivityForResultIntent(intent)\n

        \u8fd4\u56de\uff1a Activity \u7ed3\u679c

        "},{"location":"qsl4a/core/intent/#sendbroadcastintent","title":"sendBroadcastIntent()","text":"

        \u53d1\u9001\u5e7f\u64ad\u3002

        sendBroadcastIntent(intent)\n
        "},{"location":"qsl4a/core/intent/#view","title":"view()","text":"

        \u901a\u8fc7 URI \u67e5\u770b\u5185\u5bb9\u3002

        view(uri, type=None, extras=None)\n
        "},{"location":"qsl4a/core/intent/#pick","title":"pick()","text":"

        \u4ece URI \u9009\u62e9\u5185\u5bb9\u3002

        pick(uri)\n
        "},{"location":"qsl4a/core/intent/#intent_2","title":"\u5e38\u89c1 Intent \u65b9\u6cd5)","text":""},{"location":"qsl4a/core/intent/#scanbarcode","title":"scanBarcode()","text":"

        \u542f\u52a8\u6761\u7801\u626b\u63cf\u5668\u3002

        scanBarcode()\n

        \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5b57\u7b26\u4e32

        "},{"location":"qsl4a/core/intent/#send","title":"send()","text":"

        \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u5185\u5bb9\u3002

        send(type, content)\n

        \u53c2\u6570\uff1a - type (str): MIME \u7c7b\u578b - content (str): \u8981\u5206\u4eab\u7684\u5185\u5bb9

        "},{"location":"qsl4a/core/intent/#sendtext","title":"sendText()","text":"

        \u53d1\u9001\u6587\u672c\u5185\u5bb9\u3002

        sendText(text)\n

        \u53c2\u6570\uff1a - text (str): \u8981\u53d1\u9001\u7684\u6587\u672c

        "},{"location":"qsl4a/core/intent/#sendemail","title":"sendEmail()","text":"

        \u53d1\u9001\u7535\u5b50\u90ae\u4ef6\u3002

        sendEmail(to, subject, body, attachment=None)\n

        \u53c2\u6570\uff1a - to (str or list): \u6536\u4ef6\u4eba\u7535\u5b50\u90ae\u4ef6\u5730\u5740 - subject (str): \u7535\u5b50\u90ae\u4ef6\u4e3b\u9898 - body (str): \u7535\u5b50\u90ae\u4ef6\u6b63\u6587 - attachment (str, optional): \u9644\u4ef6\u6587\u4ef6\u8def\u5f84

        "},{"location":"qsl4a/core/intent/#pathtouri","title":"pathToUri()","text":"

        \u5c06\u6587\u4ef6\u8def\u5f84\u8f6c\u6362\u4e3a\u5185\u5bb9 URI\u3002

        pathToUri(path)\n

        \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

        \u8fd4\u56de\uff1a \u5185\u5bb9 URI \u5b57\u7b26\u4e32

        "},{"location":"qsl4a/core/intent/#openfile","title":"openFile()","text":"

        \u7528\u9002\u5f53\u7684\u5e94\u7528\u7a0b\u5e8f\u6253\u5f00\u6587\u4ef6\u3002

        openFile(path)\n

        \u53c2\u6570\uff1a - path (str): \u8981\u6253\u5f00\u7684\u6587\u4ef6\u8def\u5f84

        "},{"location":"qsl4a/core/intent/#sendfile","title":"sendFile()","text":"

        \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u6587\u4ef6\u3002

        sendFile(path)\n

        \u53c2\u6570\uff1a - path (str): \u8981\u53d1\u9001\u7684\u6587\u4ef6\u8def\u5f84

        "},{"location":"qsl4a/core/intent/#getpathtype","title":"getPathType()","text":"

        \u83b7\u53d6\u6587\u4ef6\u8def\u5f84\u7684 MIME \u7c7b\u578b\u3002

        getPathType(path)\n

        \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

        \u8fd4\u56de\uff1a MIME \u7c7b\u578b\u5b57\u7b26\u4e32

        "},{"location":"qsl4a/core/intent/#viewmap","title":"viewMap()","text":"

        \u5728\u6307\u5b9a\u4f4d\u7f6e\u6253\u5f00\u5730\u56fe\u3002

        viewMap(latitude, longitude)\n

        \u53c2\u6570\uff1a - latitude (float): \u7eac\u5ea6 - longitude (float): \u7ecf\u5ea6

        "},{"location":"qsl4a/core/intent/#viewcontacts","title":"viewContacts()","text":"

        \u6253\u5f00\u8054\u7cfb\u4eba\u5e94\u7528\u3002

        viewContacts()\n
        "},{"location":"qsl4a/core/intent/#search","title":"search()","text":"

        \u6267\u884c\u7f51\u7edc\u641c\u7d22\u3002

        search(query)\n

        \u53c2\u6570\uff1a - query (str): \u641c\u7d22\u67e5\u8be2

        "},{"location":"qsl4a/core/intent/#viewhtml","title":"viewHtml()","text":"

        \u67e5\u770b HTML \u5185\u5bb9\u3002

        viewHtml(content, encoding=None)\n

        \u53c2\u6570\uff1a - content (str): HTML \u5185\u5bb9 - encoding (str, optional): \u5b57\u7b26\u7f16\u7801

        "},{"location":"qsl4a/core/intent/#webviewshow","title":"webViewShow()","text":"

        \u5728 WebView \u4e2d\u663e\u793a\u7f51\u9875\u5185\u5bb9\u3002\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 viewHtml\u3002

        webViewShow(url)\n

        \u53c2\u6570\uff1a - url (str): \u7f51\u9875 URL

        "},{"location":"qsl4a/core/intent/#editoropen","title":"editorOpen()","text":"

        \u6253\u5f00\u6587\u672c\u7f16\u8f91\u5668\u3002

        editorOpen(path=None, create=False)\n

        \u53c2\u6570\uff1a - path (str, optional): \u8981\u7f16\u8f91\u7684\u6587\u4ef6\u8def\u5f84 - create (bool, optional): \u5982\u679c\u4e0d\u5b58\u5728\u5219\u521b\u5efa

        "},{"location":"qsl4a/core/intent/#uri","title":"\u8f85\u52a9\u7c7b\uff1aUri","text":"

        \u521b\u5efa Intent \u7684 URI \u5bf9\u8c61\uff1a

        from androidhelper.Intent import Uri\n\nuri = Uri(\"file:///sdcard/test.txt\")\n
        "},{"location":"qsl4a/core/intent/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/intent/#_7","title":"\u6253\u5f00\u7f51\u9875","text":"
        intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"http://www.example.com\"\n).result\ndroid.startActivityIntent(intent)\n
        "},{"location":"qsl4a/core/intent/#_8","title":"\u5206\u4eab\u6587\u672c","text":"
        intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_TEXT: \"Hello from QPython!\",\n        droid.Intent.EXTRA_SUBJECT: \"Test\"\n    },\n    type=\"text/plain\"\n).result\ndroid.startActivityIntent(intent)\n
        "},{"location":"qsl4a/core/intent/#_9","title":"\u6253\u5f00\u6587\u4ef6","text":"
        intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"file:///sdcard/document.pdf\",\n    type=\"application/pdf\"\n).result\ndroid.startActivityIntent(intent)\n
        "},{"location":"qsl4a/core/intent/#_10","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":"
        result = droid.pickContact()\ncontact_uri = result.result\n
        "},{"location":"qsl4a/core/intent/#_11","title":"\u53d1\u9001\u7535\u5b50\u90ae\u4ef6","text":"
        intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_EMAIL: [\"test@example.com\"],\n        droid.Intent.EXTRA_SUBJECT: \"Hello\",\n        droid.Intent.EXTRA_TEXT: \"Message body\"\n    },\n    type=\"message/rfc822\"\n).result\ndroid.startActivityIntent(intent)\n
        "},{"location":"qsl4a/core/intent/#_12","title":"\u6253\u5f00\u5e94\u7528","text":"
        intent = droid.makeIntent(\n    action=droid.Intent.ACTION_MAIN,\n    packagename=\"com.android.settings\",\n    classname=\"com.android.settings.Settings\"\n).result\ndroid.startActivityIntent(intent)\n
        "},{"location":"qsl4a/hardware/bluetooth/","title":"\u84dd\u7259 API","text":"

        \u63a7\u5236\u84dd\u7259\u9002\u914d\u5668\u5e76\u4e0e\u84dd\u7259\u8bbe\u5907\u901a\u4fe1\u3002

        "},{"location":"qsl4a/hardware/bluetooth/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/hardware/bluetooth/#togglebluetoothstate","title":"toggleBluetoothState()","text":"

        \u6253\u5f00/\u5173\u95ed\u84dd\u7259\u3002

        toggleBluetoothState(enabled=None, prompt=True)\n

        \u53c2\u6570\uff1a - enabled (bool): True=\u5f00\uff0cFalse=\u5173\uff0cNone=\u5207\u6362 - prompt (bool): \u663e\u793a\u7528\u6237\u63d0\u793a

        "},{"location":"qsl4a/hardware/bluetooth/#checkbluetoothstate","title":"checkBluetoothState()","text":"

        \u68c0\u67e5\u84dd\u7259\u662f\u5426\u5df2\u542f\u7528\u3002

        checkBluetoothState()\n

        \u8fd4\u56de\uff1a True/False

        "},{"location":"qsl4a/hardware/bluetooth/#getlocalname","title":"GetLocalName()","text":"

        \u83b7\u53d6\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

        GetLocalName()\n
        "},{"location":"qsl4a/hardware/bluetooth/#setlocalname","title":"SetLocalName()","text":"

        \u8bbe\u7f6e\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

        SetLocalName(name)\n
        "},{"location":"qsl4a/hardware/bluetooth/#getscanmode","title":"GetScanMode()","text":"

        \u83b7\u53d6\u53ef\u53d1\u73b0\u6027\u6a21\u5f0f\u3002

        GetScanMode()\n

        \u8fd4\u56de\uff1a - -1: \u5df2\u7981\u7528 - 0: \u4e0d\u53ef\u53d1\u73b0\uff0c\u4e0d\u53ef\u8fde\u63a5 - 1: \u53ef\u8fde\u63a5\uff0c\u4e0d\u53ef\u53d1\u73b0 - 3: \u53ef\u8fde\u63a5\u4e14\u53ef\u53d1\u73b0

        "},{"location":"qsl4a/hardware/bluetooth/#makediscoverable","title":"MakeDiscoverable()","text":"

        \u4f7f\u8bbe\u5907\u53ef\u53d1\u73b0\u3002

        MakeDiscoverable(duration=300)\n

        \u53c2\u6570\uff1a - duration (int): \u53ef\u53d1\u73b0\u7684\u79d2\u6570

        "},{"location":"qsl4a/hardware/bluetooth/#_2","title":"\u53d1\u73b0","text":""},{"location":"qsl4a/hardware/bluetooth/#discoverystart","title":"DiscoveryStart()","text":"

        \u5f00\u59cb\u8bbe\u5907\u53d1\u73b0\u3002

        DiscoveryStart()\n
        "},{"location":"qsl4a/hardware/bluetooth/#discoverycancel","title":"DiscoveryCancel()","text":"

        \u53d6\u6d88\u53d1\u73b0\u3002

        DiscoveryCancel()\n
        "},{"location":"qsl4a/hardware/bluetooth/#getreceiveddevices","title":"GetReceivedDevices()","text":"

        \u83b7\u53d6\u53d1\u73b0\u7684\u8bbe\u5907\u3002

        GetReceivedDevices()\n

        \u8fd4\u56de\uff1a \u8bbe\u5907\u4fe1\u606f\u5b57\u5178\u5217\u8868

        "},{"location":"qsl4a/hardware/bluetooth/#getbondeddevices","title":"GetBondedDevices()","text":"

        \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\u3002

        GetBondedDevices()\n

        \u8fd4\u56de\uff1a \u914d\u5bf9\u8bbe\u5907\u4fe1\u606f\u5217\u8868

        "},{"location":"qsl4a/hardware/bluetooth/#_3","title":"\u8fde\u63a5","text":""},{"location":"qsl4a/hardware/bluetooth/#connect","title":"Connect()","text":"

        \u8fde\u63a5\u5230\u8bbe\u5907\u3002

        Connect(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", address=None)\n

        \u53c2\u6570\uff1a - uuid (str): \u670d\u52a1 UUID - address (str): \u8bbe\u5907\u5730\u5740\uff08None = \u663e\u793a\u9009\u62e9\u5668\uff09

        \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

        "},{"location":"qsl4a/hardware/bluetooth/#accept","title":"Accept()","text":"

        \u63a5\u53d7\u4f20\u5165\u8fde\u63a5\u3002

        Accept(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", timeout=0)\n
        "},{"location":"qsl4a/hardware/bluetooth/#activeconnections","title":"ActiveConnections()","text":"

        \u68c0\u67e5\u6d3b\u52a8\u8fde\u63a5\u3002

        ActiveConnections()\n
        "},{"location":"qsl4a/hardware/bluetooth/#stop","title":"Stop()","text":"

        \u65ad\u5f00\u8fde\u63a5\u3002

        Stop(connID=None)\n
        "},{"location":"qsl4a/hardware/bluetooth/#_4","title":"\u901a\u4fe1","text":""},{"location":"qsl4a/hardware/bluetooth/#write","title":"Write()","text":"

        \u53d1\u9001 ASCII \u6570\u636e\u3002

        Write(ascii, connID=\"\")\n
        "},{"location":"qsl4a/hardware/bluetooth/#writebinary","title":"WriteBinary()","text":"

        \u53d1\u9001\u4e8c\u8fdb\u5236\u6570\u636e\uff08base64 \u7f16\u7801\uff09\u3002

        WriteBinary(base64, connID=None)\n
        "},{"location":"qsl4a/hardware/bluetooth/#read","title":"Read()","text":"

        \u8bfb\u53d6 ASCII \u6570\u636e\u3002

        Read(bufferSize=4096, connID=None)\n
        "},{"location":"qsl4a/hardware/bluetooth/#readbinary","title":"ReadBinary()","text":"

        \u8bfb\u53d6\u4e8c\u8fdb\u5236\u6570\u636e\u3002

        ReadBinary(bufferSize=4096, connID=None)\n
        "},{"location":"qsl4a/hardware/bluetooth/#readline","title":"ReadLine()","text":"

        \u8bfb\u53d6\u4e00\u884c\u3002

        ReadLine(connID=None)\n
        "},{"location":"qsl4a/hardware/bluetooth/#readready","title":"ReadReady()","text":"

        \u68c0\u67e5\u662f\u5426\u6709\u53ef\u7528\u6570\u636e\u3002

        ReadReady(connID=None)\n
        "},{"location":"qsl4a/hardware/bluetooth/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u7528\u84dd\u7259\ndroid.toggleBluetoothState(True)\n\n# \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\ndevices = droid.GetBondedDevices().result\nfor dev in devices:\n    print(f\"{dev['name']}: {dev['address']}\")\n\n# \u8fde\u63a5\u5230\u8bbe\u5907\ndroid.Connect(address=\"00:11:22:33:44:55\")\n\n# \u53d1\u9001\u6570\u636e\ndroid.Write(\"Hello Bluetooth!\")\n\n# \u8bfb\u53d6\u54cd\u5e94\ndata = droid.Read(1024).result\n
        "},{"location":"qsl4a/hardware/camera/","title":"\u76f8\u673a API","text":"

        \u62cd\u6444\u7167\u7247\u548c\u5f55\u5236\u89c6\u9891\u3002

        "},{"location":"qsl4a/hardware/camera/#_1","title":"\u7167\u7247\u62cd\u6444","text":""},{"location":"qsl4a/hardware/camera/#takepicture","title":"takePicture()","text":"

        \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u6444\u7167\u7247\u3002

        takePicture(path=None)\n

        \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8fd4\u56de\u56fe\u50cf\u6570\u636e

        \u8fd4\u56de\uff1a \u56fe\u50cf\u8def\u5f84\u6216\u56fe\u50cf\u6570\u636e

        "},{"location":"qsl4a/hardware/camera/#cameracapturepicture","title":"cameraCapturePicture()","text":"

        \u4f7f\u7528\u9ad8\u7ea7\u76f8\u673a\u63a7\u5236\u62cd\u6444\u7167\u7247\u3002

        cameraCapturePicture(targetPath=None, cameraId=0, useAutoFocus=True)\n

        \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - useAutoFocus (bool): \u542f\u7528\u81ea\u52a8\u5bf9\u7126

        \u8fd4\u56de\uff1a \u62cd\u6444\u7684\u56fe\u50cf\u8def\u5f84

        "},{"location":"qsl4a/hardware/camera/#camerasettorchmode","title":"cameraSetTorchMode()","text":"

        \u63a7\u5236\u76f8\u673a\u95ea\u5149\u706f/\u624b\u7535\u7b52\u3002

        cameraSetTorchMode(enabled)\n

        \u53c2\u6570\uff1a - enabled (bool): True \u6253\u5f00\uff0cFalse \u5173\u95ed

        \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

        "},{"location":"qsl4a/hardware/camera/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

        \u622a\u56fe\u3002

        imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

        \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

        "},{"location":"qsl4a/hardware/camera/#_2","title":"\u89c6\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#takevideo","title":"takeVideo()","text":"

        \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\u3002

        takeVideo(path=None, quality=1)\n

        \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-4\uff09 - 0: 160x120 - 1: 320x240 - 2: 352x288 - 3: 640x480 - 4: 800x480

        "},{"location":"qsl4a/hardware/camera/#recordercapturevideo","title":"recorderCaptureVideo()","text":"

        \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\u3002

        recorderCaptureVideo(targetPath=None, duration=10, cameraId=0, quality=8)\n

        \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - duration (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a10\uff09 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-8\uff0c\u8d8a\u9ad8\u8d8a\u597d\uff09

        \u8fd4\u56de\uff1a \u89c6\u9891\u6587\u4ef6\u8def\u5f84

        "},{"location":"qsl4a/hardware/camera/#recordaudio","title":"recordAudio()","text":"

        \u5f55\u5236\u97f3\u9891\u3002

        recordAudio()\n

        \u8fd4\u56de\uff1a \u97f3\u9891\u6587\u4ef6\u8def\u5f84

        "},{"location":"qsl4a/hardware/camera/#_3","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

        \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\u3002

        recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

        \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\uff09 - targetPixels (int): \u5206\u8fa8\u7387 - frameRate (int): FPS - bitRate (int): \u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa - autoStart (bool): \u7acb\u5373\u5f00\u59cb

        "},{"location":"qsl4a/hardware/camera/#recorderstart","title":"recorderStart()","text":"

        \u5f00\u59cb\u5f55\u5236\u3002

        recorderStart()\n
        "},{"location":"qsl4a/hardware/camera/#recorderpause","title":"recorderPause()","text":"

        \u6682\u505c\u5f55\u5236\u3002

        recorderPause()\n
        "},{"location":"qsl4a/hardware/camera/#recorderresume","title":"recorderResume()","text":"

        \u6062\u590d\u5f55\u5236\u3002

        recorderResume()\n
        "},{"location":"qsl4a/hardware/camera/#_4","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/camera/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

        \u5f00\u59cb\u97f3\u91cf\u68c0\u6d4b\u3002

        recorderSoundVolumeDetect(interval=100)\n
        "},{"location":"qsl4a/hardware/camera/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

        \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

        recorderSoundVolumeGetDb()\n
        "},{"location":"qsl4a/hardware/camera/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u7167\nphoto_path = droid.takePicture(\"/sdcard/photo.jpg\").result\nprint(f\"Photo saved: {photo_path}\")\n\n# \u4f7f\u7528\u524d\u7f6e\u76f8\u673a\u548c\u81ea\u52a8\u5bf9\u7126\u62cd\u7167\ncamera_path = droid.cameraCapturePicture(\"/sdcard/selfie.jpg\", cameraId=1, useAutoFocus=True).result\nprint(f\"Front camera photo: {camera_path}\")\n\n# \u63a7\u5236\u95ea\u5149\u706f\ndroid.cameraSetTorchMode(True)  # \u6253\u5f00\u95ea\u5149\u706f\n\n# \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\nvideo_path = droid.takeVideo(\"/sdcard/video.mp4\", quality=3).result\nprint(f\"Video saved: {video_path}\")\n\n# \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\nvideo_path = droid.recorderCaptureVideo(\"/sdcard/movie.mp4\", duration=30, cameraId=0, quality=8).result\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n
        "},{"location":"qsl4a/hardware/recorder/","title":"\u97f3\u9891\u5f55\u5236 API","text":"

        \u4ece\u9ea6\u514b\u98ce\u548c\u8bbe\u5907\u5c4f\u5e55\u5f55\u5236\u97f3\u9891\u3002

        "},{"location":"qsl4a/hardware/recorder/#_1","title":"\u97f3\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recordaudio","title":"recordAudio()","text":"

        \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\u3002

        recordAudio()\n

        \u8fd4\u56de\uff1a \u5f55\u5236\u7684\u97f3\u9891\u6587\u4ef6\u8def\u5f84

        "},{"location":"qsl4a/hardware/recorder/#recorderstartmicrophone","title":"recorderStartMicrophone()","text":"

        \u5f00\u59cb\u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\u3002

        recorderStartMicrophone(targetPath=None)\n

        \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u5f55\u5236\u7684\u8def\u5f84

        "},{"location":"qsl4a/hardware/recorder/#_2","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

        \u5f00\u59cb\u5e26\u97f3\u9891\u7684\u5c4f\u5e55\u5f55\u5236\u3002

        recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

        \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\u97f3\u9891\uff09 - targetPixels (int): \u76ee\u6807\u5206\u8fa8\u7387\uff08\u50cf\u7d20\uff09 - frameRate (int): \u6bcf\u79d2\u5e27\u6570\uff08\u9ed8\u8ba4\uff1a30\uff09 - bitRate (int): \u89c6\u9891\u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa\u89c6\u9891 - autoStart (bool): \u7acb\u5373\u5f00\u59cb\u5f55\u5236

        \u8fd4\u56de\uff1a \u64cd\u4f5c\u7ed3\u679c

        "},{"location":"qsl4a/hardware/recorder/#recorderstart","title":"recorderStart()","text":"

        \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\uff08\u5f53 autoStart=False \u65f6\uff09\u3002

        recorderStart()\n
        "},{"location":"qsl4a/hardware/recorder/#recorderpause","title":"recorderPause()","text":"

        \u6682\u505c\u6b63\u5728\u8fdb\u884c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

        recorderPause()\n
        "},{"location":"qsl4a/hardware/recorder/#recorderresume","title":"recorderResume()","text":"

        \u6062\u590d\u6682\u505c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

        recorderResume()\n
        "},{"location":"qsl4a/hardware/recorder/#_3","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/recorder/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

        \u5f00\u59cb\u76d1\u63a7\u97f3\u91cf\u7ea7\u522b\u3002

        recorderSoundVolumeDetect(interval=100)\n

        \u53c2\u6570\uff1a - interval (int): \u68c0\u6d4b\u95f4\u9694\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a100\uff09

        "},{"location":"qsl4a/hardware/recorder/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

        \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

        recorderSoundVolumeGetDb()\n

        \u8fd4\u56de\uff1a \u5f53\u524d\u97f3\u91cf\u7ea7\u522b\uff08dB\uff09

        "},{"location":"qsl4a/hardware/recorder/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\nprint(\"Recording audio...\")\naudio_path = droid.recordAudio().result\nprint(f\"Saved to: {audio_path}\")\n\n# \u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\ndroid.recorderStartMicrophone(\"/sdcard/my_recording.mp3\")\ntime.sleep(5)\ndroid.recorderStop()\n\n# \u5e26\u97f3\u9891\u5f55\u5236\u5c4f\u5e55\nprint(\"Starting screen recording...\")\ndroid.recorderStartScreenRecord(\n    path=\"/sdcard/screen_record.mp4\",\n    audio=1,\n    frameRate=30,\n    autoStart=True\n)\ntime.sleep(10)\ndroid.recorderStop()\n\n# \u76d1\u63a7\u97f3\u91cf\ndroid.recorderSoundVolumeDetect(interval=100)\ntime.sleep(3)\nvolume = droid.recorderSoundVolumeGetDb().result\nprint(f\"Current volume: {volume} dB\")\n
        "},{"location":"qsl4a/hardware/usbserial/","title":"USB \u4e3b\u673a\u4e32\u884c API","text":"

        \u4e0e USB \u4e32\u884c\u8bbe\u5907\u901a\u4fe1\uff08\u9700\u8981 USB OTG \u652f\u6301\u548c Android 3.1+\uff09\u3002

        "},{"location":"qsl4a/hardware/usbserial/#usb","title":"USB \u4e32\u884c\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialopen","title":"usbHostSerialOpen()","text":"

        \u6253\u5f00\u4e0e USB \u4e32\u884c\u8bbe\u5907\u7684\u8fde\u63a5\u3002

        usbHostSerialOpen(device, baudRate=9600)\n

        \u53c2\u6570\uff1a - device (str): USB \u8bbe\u5907\u8def\u5f84\u6216\u6807\u8bc6\u7b26 - baudRate (int): \u6ce2\u7279\u7387\uff08\u9ed8\u8ba4\uff1a9600\uff09

        \u8fd4\u56de\uff1a \u5982\u679c\u6253\u5f00\u6210\u529f\u5219\u4e3a True

        "},{"location":"qsl4a/hardware/usbserial/#usbhostserialclose","title":"usbHostSerialClose()","text":"

        \u5173\u95ed USB \u4e32\u884c\u8fde\u63a5\u3002

        usbHostSerialClose()\n
        "},{"location":"qsl4a/hardware/usbserial/#usbhostserialread","title":"usbHostSerialRead()","text":"

        \u4ece USB \u4e32\u884c\u8bfb\u53d6\u6570\u636e\u3002

        usbHostSerialRead(bufferSize=1024)\n

        \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570\uff08\u9ed8\u8ba4\uff1a1024\uff09

        \u8fd4\u56de\uff1a \u8bfb\u53d6\u7684\u6570\u636e\u5b57\u7b26\u4e32

        "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwrite","title":"usbHostSerialWrite()","text":"

        \u5411 USB \u4e32\u884c\u5199\u5165\u6570\u636e\u3002

        usbHostSerialWrite(data)\n

        \u53c2\u6570\uff1a - data (str): \u8981\u5199\u5165\u7684\u5b57\u7b26\u4e32\u6570\u636e

        "},{"location":"qsl4a/hardware/usbserial/#usbhostserialavailable","title":"usbHostSerialAvailable()","text":"

        \u68c0\u67e5\u662f\u5426\u6709\u53ef\u8bfb\u53d6\u7684\u6570\u636e\u3002

        usbHostSerialAvailable()\n

        \u8fd4\u56de\uff1a \u53ef\u7528\u5b57\u8282\u6570

        "},{"location":"qsl4a/hardware/usbserial/#_1","title":"\u914d\u7f6e\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetbaudrate","title":"usbHostSerialSetBaudRate()","text":"

        \u8bbe\u7f6e\u6ce2\u7279\u7387\u3002

        usbHostSerialSetBaudRate(baudRate)\n

        \u53c2\u6570\uff1a - baudRate (int): \u6ce2\u7279\u7387

        "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetdatabits","title":"usbHostSerialSetDataBits()","text":"

        \u8bbe\u7f6e\u6570\u636e\u4f4d\uff085\u30016\u30017 \u6216 8\uff09\u3002

        usbHostSerialSetDataBits(dataBits)\n

        \u53c2\u6570\uff1a - dataBits (int): \u6570\u636e\u4f4d\uff085-8\uff09

        "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetstopbits","title":"usbHostSerialSetStopBits()","text":"

        \u8bbe\u7f6e\u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09\u3002

        usbHostSerialSetStopBits(stopBits)\n

        \u53c2\u6570\uff1a - stopBits (float): \u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09

        "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetparity","title":"usbHostSerialSetParity()","text":"

        \u8bbe\u7f6e\u6821\u9a8c\u4f4d\uff08\u65e0\u3001\u5947\u3001\u5076\u3001\u6807\u8bb0\u3001\u7a7a\u683c\uff09\u3002

        usbHostSerialSetParity(parity)\n

        \u53c2\u6570\uff1a - parity (str): \u6821\u9a8c\u6a21\u5f0f\uff08'none'\u3001'odd'\u3001'even'\u3001'mark'\u3001'space'\uff09

        "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetflowcontrol","title":"usbHostSerialSetFlowControl()","text":"

        \u8bbe\u7f6e\u6d41\u63a7\u5236\uff08\u65e0\u3001\u786c\u4ef6\u3001\u8f6f\u4ef6\uff09\u3002

        usbHostSerialSetFlowControl(flowControl)\n

        \u53c2\u6570\uff1a - flowControl (str): \u6d41\u63a7\u5236\u6a21\u5f0f\uff08'none'\u3001'hardware'\u3001'software'\uff09

        "},{"location":"qsl4a/hardware/usbserial/#usbhostserialreadhex","title":"usbHostSerialReadHex()","text":"

        \u4ee5\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u8bfb\u53d6\u6570\u636e\u3002

        usbHostSerialReadHex(bufferSize=1024)\n

        \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570

        \u8fd4\u56de\uff1a \u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

        "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwritehex","title":"usbHostSerialWriteHex()","text":"

        \u4ece\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u5199\u5165\u6570\u636e\u3002

        usbHostSerialWriteHex(hexString)\n

        \u53c2\u6570\uff1a - hexString (str): \u8981\u5199\u5165\u7684\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

        "},{"location":"qsl4a/hardware/usbserial/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6253\u5f00 USB \u4e32\u884c\u8fde\u63a5\nif droid.usbHostSerialOpen(\"/dev/bus/usb/001/001\", 115200).result:\n    print(\"USB serial opened\")\n\n    # \u5199\u5165\u6570\u636e\n    droid.usbHostSerialWrite(\"AT\\r\")\n\n    # \u8bfb\u53d6\u54cd\u5e94\n    response = droid.usbHostSerialRead(1024).result\n    print(f\"Response: {response}\")\n\n    # \u6216\u4f7f\u7528\u5341\u516d\u8fdb\u5236\n    droid.usbHostSerialWriteHex(\"41540D0A\")  # \"AT\\r\\n\"\n\n    # \u5173\u95ed\u8fde\u63a5\n    droid.usbHostSerialClose()\n

        \u6ce8\u610f\uff1a USB \u4e32\u884c\u9700\u8981\uff1a - Android 3.1+ (API 12) - USB OTG \u7ebf/\u9002\u914d\u5668 - \u8bbe\u5907\u4e0a\u7684 USB \u4e3b\u673a\u6a21\u5f0f\u652f\u6301 - \u517c\u5bb9\u7684\u4e32\u884c\u8bbe\u5907

        "},{"location":"qsl4a/hardware/webcam/","title":"\u7f51\u7edc\u6444\u50cf\u5934 API","text":"

        \u4f7f\u7528 MJPEG \u4ece\u8bbe\u5907\u76f8\u673a\u6d41\u5f0f\u4f20\u8f93\u89c6\u9891\u3002

        "},{"location":"qsl4a/hardware/webcam/#mjpeg","title":"MJPEG \u6d41\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#webcamstart","title":"webcamStart()","text":"

        \u4ece\u7f51\u7edc\u6444\u50cf\u5934\u542f\u52a8 MJPEG \u6d41\u3002

        webcamStart(resolutionLevel=0, jpegQuality=20, port=0)\n

        \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf 1-100\uff08\u9ed8\u8ba4\uff1a20\uff09 - port (int): \u7aef\u53e3\u53f7\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\uff09

        \u8fd4\u56de\uff1a \u6d41\u7684 (\u5730\u5740, \u7aef\u53e3) \u5143\u7ec4

        "},{"location":"qsl4a/hardware/webcam/#webcamadjustquality","title":"webcamAdjustQuality()","text":"

        \u8c03\u6574\u6d3b\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u7684\u8d28\u91cf\u3002

        webcamAdjustQuality(resolutionLevel=0, jpegQuality=20)\n

        \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b - jpegQuality (int): JPEG \u8d28\u91cf 1-100

        "},{"location":"qsl4a/hardware/webcam/#webcamstop","title":"webcamStop()","text":"

        \u505c\u6b62\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u3002

        webcamStop()\n
        "},{"location":"qsl4a/hardware/webcam/#_1","title":"\u76f8\u673a\u9884\u89c8\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#camerastartpreview","title":"cameraStartPreview()","text":"

        \u5f00\u59cb\u5e26\u4e8b\u4ef6\u751f\u6210\u7684\u76f8\u673a\u9884\u89c8\u6a21\u5f0f\u3002

        cameraStartPreview(resolutionLevel=0, jpegQuality=20, filepath=None)\n

        \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf\uff08\u9ed8\u8ba4\uff1a20\uff09 - filepath (str, optional): \u4fdd\u5b58\u9884\u89c8\u5e27\u7684\u6587\u4ef6\u8def\u5f84

        \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

        \u6ce8\u610f\uff1a \u751f\u6210\u5e26\u6709\u5e27\u6570\u636e\u7684 'preview' \u4e8b\u4ef6\u3002

        "},{"location":"qsl4a/hardware/webcam/#camerastoppreview","title":"cameraStopPreview()","text":"

        \u505c\u6b62\u76f8\u673a\u9884\u89c8\u3002

        cameraStopPreview()\n
        "},{"location":"qsl4a/hardware/webcam/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\nstream_info = droid.webcamStart(\n    resolutionLevel=0,\n    jpegQuality=30,\n    port=8080\n).result\nprint(f\"Stream available at {stream_info[0]}:{stream_info[1]}\")\n\n# \u6d41\u5f0f\u4f20\u8f93\u65f6\u8c03\u6574\u8d28\u91cf\ntime.sleep(5)\ndroid.webcamAdjustQuality(resolutionLevel=1, jpegQuality=50)\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.webcamStop()\n\n# \u6216\u4f7f\u7528\u9884\u89c8\u6a21\u5f0f\nprint(\"Starting preview...\")\ndroid.cameraStartPreview()\n\n# \u7b49\u5f85\u9884\u89c8\u4e8b\u4ef6\nfor i in range(10):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'preview':\n        print(f\"Got preview frame: {event['data']}\")\n\ndroid.cameraStopPreview()\n
        "},{"location":"qsl4a/media/image/","title":"\u56fe\u50cf\u5904\u7406 API","text":"

        \u538b\u7f29\u548c\u5904\u7406\u56fe\u50cf\u3002

        "},{"location":"qsl4a/media/image/#_1","title":"\u56fe\u50cf\u538b\u7f29","text":""},{"location":"qsl4a/media/image/#imagecompress","title":"imageCompress()","text":"

        \u538b\u7f29\u56fe\u50cf\u6587\u4ef6\u3002

        imageCompress(srcPath, destPath, targetByteSize=0, targetWidth=0, targetHeight=0)\n

        \u53c2\u6570\uff1a - srcPath (str): \u6e90\u56fe\u50cf\u8def\u5f84 - destPath (str): \u8f93\u51fa\u8def\u5f84 - targetByteSize (int): \u76ee\u6807\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff080 = \u65e0\u9650\u5236\uff09 - targetWidth (int): \u76ee\u6807\u5bbd\u5ea6\uff080 = \u539f\u59cb\uff09 - targetHeight (int): \u76ee\u6807\u9ad8\u5ea6\uff080 = \u539f\u59cb\uff09

        \u8fd4\u56de\uff1a \u538b\u7f29\u540e\u7684\u56fe\u50cf\u8def\u5f84

        "},{"location":"qsl4a/media/image/#_2","title":"\u622a\u56fe","text":""},{"location":"qsl4a/media/image/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

        \u622a\u53d6\u5c4f\u5e55\u3002

        imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

        \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

        \u8fd4\u56de\uff1a \u622a\u56fe\u8def\u5f84

        "},{"location":"qsl4a/media/image/#_3","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/image/#videoplay","title":"videoPlay()","text":"

        \u5728\u5168\u5c4f\u6a21\u5f0f\u4e0b\u64ad\u653e\u89c6\u9891\u6587\u4ef6\u3002

        videoPlay(path, wait=True)\n

        \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

        "},{"location":"qsl4a/media/image/#_4","title":"\u6761\u7801\u626b\u63cf","text":""},{"location":"qsl4a/media/image/#scanbarcodefromimage","title":"scanBarcodeFromImage()","text":"

        \u4ece\u56fe\u50cf\u6587\u4ef6\u626b\u63cf\u6761\u7801/\u4e8c\u7ef4\u7801\u3002

        scanBarcodeFromImage(path, compressRatio=0, x=0, y=0, width=0, height=0)\n

        \u53c2\u6570\uff1a - path (str): \u56fe\u50cf\u6587\u4ef6\u8def\u5f84 - compressRatio (int): \u538b\u7f29\u6bd4\uff080 = \u4e0d\u538b\u7f29\uff09 - x, y, width, height (int): \u8981\u626b\u63cf\u7684\u533a\u57df\uff080 = \u5b8c\u6574\u56fe\u50cf\uff09

        \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5185\u5bb9

        "},{"location":"qsl4a/media/image/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n\n# \u538b\u7f29\u56fe\u50cf\ncompressed = droid.imageCompress(\n    \"/sdcard/large_photo.jpg\",\n    \"/sdcard/compressed.jpg\",\n    targetByteSize=102400,  # \u76ee\u6807\u7ea6 100KB\n    targetWidth=1920,\n    targetHeight=1080\n).result\nprint(f\"Saved: {compressed}\")\n\n# \u64ad\u653e\u89c6\u9891\nvideo_path = \"/sdcard/movie.mp4\"\ndroid.videoPlay(video_path, wait=True)\n\n# \u4ece\u56fe\u50cf\u626b\u63cf\u6761\u7801\nresult = droid.scanBarcodeFromImage(\"/sdcard/qr_code.png\").result\nprint(f\"Barcode: {result}\")\n
        "},{"location":"qsl4a/media/mediaplayer/","title":"\u5a92\u4f53\u64ad\u653e\u5668 API","text":"

        \u63a7\u5236\u97f3\u9891\u548c\u89c6\u9891\u64ad\u653e\u3002

        "},{"location":"qsl4a/media/mediaplayer/#_1","title":"\u64ad\u653e\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplay","title":"mediaPlay()","text":"

        \u64ad\u653e\u5a92\u4f53\u6587\u4ef6\u3002

        mediaPlay(url, tag=\"default\", play=True)\n

        \u53c2\u6570\uff1a - url (str): \u5a92\u4f53\u6587\u4ef6\u8def\u5f84\u6216 URL - tag (str): \u64ad\u653e\u5668\u6807\u8bc6\u7b26 - play (bool): \u81ea\u52a8\u5f00\u59cb\u64ad\u653e

        "},{"location":"qsl4a/media/mediaplayer/#mediaplaystart","title":"mediaPlayStart()","text":"

        \u5f00\u59cb\u64ad\u653e\u3002

        mediaPlayStart(tag=\"default\")\n
        "},{"location":"qsl4a/media/mediaplayer/#mediaplaypause","title":"mediaPlayPause()","text":"

        \u6682\u505c\u64ad\u653e\u3002

        mediaPlayPause(tag=\"default\")\n
        "},{"location":"qsl4a/media/mediaplayer/#mediaplayclose","title":"mediaPlayClose()","text":"

        \u5173\u95ed\u64ad\u653e\u5668\u3002

        mediaPlayClose(tag=\"default\")\n
        "},{"location":"qsl4a/media/mediaplayer/#mediaplayseek","title":"mediaPlaySeek()","text":"

        \u8df3\u8f6c\u5230\u4f4d\u7f6e\u3002

        mediaPlaySeek(msec, tag=\"default\")\n

        \u53c2\u6570\uff1a - msec (int): \u4f4d\u7f6e\uff08\u6beb\u79d2\uff09

        "},{"location":"qsl4a/media/mediaplayer/#mediaplaysetlooping","title":"mediaPlaySetLooping()","text":"

        \u8bbe\u7f6e\u5faa\u73af\u6a21\u5f0f\u3002

        mediaPlaySetLooping(enabled, tag=\"default\")\n
        "},{"location":"qsl4a/media/mediaplayer/#_2","title":"\u64ad\u653e\u5668\u4fe1\u606f","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplayinfo","title":"mediaPlayInfo()","text":"

        \u83b7\u53d6\u64ad\u653e\u4fe1\u606f\u3002

        mediaPlayInfo(tag=\"default\")\n

        \u8fd4\u56de\uff1a \u5305\u542b\u65f6\u957f\u3001\u4f4d\u7f6e\u7b49\u7684\u5b57\u5178

        "},{"location":"qsl4a/media/mediaplayer/#mediaisplaying","title":"mediaIsPlaying()","text":"

        \u68c0\u67e5\u662f\u5426\u6b63\u5728\u64ad\u653e\u3002

        mediaIsPlaying(tag=\"default\")\n

        \u8fd4\u56de\uff1a True/False

        "},{"location":"qsl4a/media/mediaplayer/#mediaplaylist","title":"mediaPlayList()","text":"

        \u5217\u51fa\u6d3b\u52a8\u64ad\u653e\u5668\u3002

        mediaPlayList()\n
        "},{"location":"qsl4a/media/mediaplayer/#_3","title":"\u97f3\u91cf\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#getmediavolume","title":"getMediaVolume()","text":"

        \u83b7\u53d6\u5a92\u4f53\u97f3\u91cf\u3002

        getMediaVolume()\n

        \u8fd4\u56de\uff1a \u97f3\u91cf\u7ea7\u522b\uff080-15\uff09

        "},{"location":"qsl4a/media/mediaplayer/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

        \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

        getMaxMediaVolume()\n
        "},{"location":"qsl4a/media/mediaplayer/#getringervolume","title":"getRingerVolume()","text":"

        \u83b7\u53d6\u94c3\u58f0\u97f3\u91cf\u3002

        getRingerVolume()\n
        "},{"location":"qsl4a/media/mediaplayer/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

        \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

        getMaxRingerVolume()\n
        "},{"location":"qsl4a/media/mediaplayer/#_4","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/mediaplayer/#videoplay","title":"videoPlay()","text":"

        \u5168\u5c4f\u64ad\u653e\u89c6\u9891\u3002

        videoPlay(path, wait=True)\n

        \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210

        "},{"location":"qsl4a/media/mediaplayer/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u64ad\u653e\u97f3\u9891\ndroid.mediaPlay(\"/sdcard/music.mp3\", tag=\"music\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.mediaIsPlaying(\"music\").result:\n    info = droid.mediaPlayInfo(\"music\").result\n    print(f\"Playing: {info}\")\n\n# \u8df3\u8f6c\u5230 30 \u79d2\ndroid.mediaPlaySeek(30000, \"music\")\n\n# \u5173\u95ed\ndroid.mediaPlayClose(\"music\")\n\n# \u64ad\u653e\u89c6\u9891\ndroid.videoPlay(\"/sdcard/movie.mp4\", wait=True)\n
        "},{"location":"qsl4a/special/cipher/","title":"\u5bc6\u7801 API","text":"

        \u7528\u4e8e\u5b89\u5168\u6570\u636e\u5b58\u50a8\u7684\u52a0\u5bc6\u548c\u89e3\u5bc6\u5de5\u5177\u3002

        "},{"location":"qsl4a/special/cipher/#_1","title":"\u521d\u59cb\u5316","text":""},{"location":"qsl4a/special/cipher/#cipherinit","title":"cipherInit()","text":"

        \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u548c\u7b97\u6cd5\u521d\u59cb\u5316\u5bc6\u7801\u5668\u3002

        cipherInit(key, algorithm=\"AES/CBC/PKCS5Padding\", encodingFormat=\"\", initialVector=\"\")\n

        \u53c2\u6570\uff1a - key (str or bytes): \u52a0\u5bc6\u5bc6\u94a5 - algorithm (str): \u5bc6\u7801\u7b97\u6cd5\uff08\u9ed8\u8ba4\uff1a\"AES/CBC/PKCS5Padding\"\uff09 - encodingFormat (str): \u7f16\u7801\u683c\u5f0f - initialVector (str or bytes): \u52a0\u5bc6\u7684\u521d\u59cb\u5411\u91cf

        \u8fd4\u56de\uff1a \u521d\u59cb\u5316\u7ed3\u679c

        \u6ce8\u610f\uff1a \u5fc5\u987b\u5728\u4efb\u4f55\u52a0\u5bc6/\u89e3\u5bc6\u64cd\u4f5c\u4e4b\u524d\u8c03\u7528\u3002

        "},{"location":"qsl4a/special/cipher/#_2","title":"\u52a0\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#encryptstring","title":"encryptString()","text":"

        \u52a0\u5bc6\u5b57\u7b26\u4e32\u3002

        encryptString(plainText)\n

        \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c

        \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u7b26\u4e32

        "},{"location":"qsl4a/special/cipher/#encryptbytes","title":"encryptBytes()","text":"

        \u52a0\u5bc6\u5b57\u8282\u6570\u636e\u3002

        encryptBytes(data)\n

        \u53c2\u6570\uff1a - data (bytes): \u8981\u52a0\u5bc6\u7684\u6570\u636e

        \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u8282

        "},{"location":"qsl4a/special/cipher/#encryptstringtofile","title":"encryptStringToFile()","text":"

        \u52a0\u5bc6\u5b57\u7b26\u4e32\u5230\u6587\u4ef6\u3002

        encryptStringToFile(plainText, filePath)\n

        \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c - filePath (str): \u8f93\u51fa\u6587\u4ef6\u8def\u5f84

        "},{"location":"qsl4a/special/cipher/#encryptbytestofile","title":"encryptBytesToFile()","text":"

        \u52a0\u5bc6\u5b57\u8282\u5230\u6587\u4ef6\u3002

        encryptBytesToFile(data, filePath)\n
        "},{"location":"qsl4a/special/cipher/#_3","title":"\u89e3\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#decryptstring","title":"decryptString()","text":"

        \u89e3\u5bc6\u4e3a\u5b57\u7b26\u4e32\u3002

        decryptString(cipherText)\n

        \u53c2\u6570\uff1a - cipherText (str): \u52a0\u5bc6\u7684\u6587\u672c

        \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u7b26\u4e32

        "},{"location":"qsl4a/special/cipher/#decryptbytes","title":"decryptBytes()","text":"

        \u89e3\u5bc6\u4e3a\u5b57\u8282\u3002

        decryptBytes(data)\n

        \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u8282

        "},{"location":"qsl4a/special/cipher/#decryptfiletostring","title":"decryptFileToString()","text":"

        \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u7b26\u4e32\u3002

        decryptFileToString(filePath)\n
        "},{"location":"qsl4a/special/cipher/#decryptfiletobytes","title":"decryptFileToBytes()","text":"

        \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u8282\u3002

        decryptFileToBytes(filePath)\n
        "},{"location":"qsl4a/special/cipher/#decryptfile","title":"decryptFile()","text":"

        \u89e3\u5bc6\u6587\u4ef6\u5230\u6587\u4ef6\u3002

        decryptFile(srcPath, destPath)\n
        "},{"location":"qsl4a/special/cipher/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u521d\u59cb\u5316\u5bc6\u7801\u5668\ndroid.cipherInit(\"my_secret_key_1234\")\n\n# \u52a0\u5bc6\u5b57\u7b26\u4e32\nencrypted = droid.encryptString(\"Secret message!\").result\nprint(f\"Encrypted: {encrypted}\")\n\n# \u89e3\u5bc6\u5b57\u7b26\u4e32\ndecrypted = droid.decryptString(encrypted).result\nprint(f\"Decrypted: {decrypted}\")\n\n# \u52a0\u5bc6\u5230\u6587\u4ef6\ndroid.encryptStringToFile(\"My secret data\", \"/sdcard/secret.dat\")\n\n# \u4ece\u6587\u4ef6\u89e3\u5bc6\ndata = droid.decryptFileToString(\"/sdcard/secret.dat\").result\nprint(data)\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u7b97\u6cd5\u548c IV \u521d\u59cb\u5316\ndroid.cipherInit(\n    key=\"my_key\",\n    algorithm=\"AES/CBC/PKCS5Padding\",\n    initialVector=\"0123456789abcdef\"\n)\n
        "},{"location":"qsl4a/special/pgptai/","title":"PGPT AI API","text":"

        \u8bed\u97f3\u8f6c\u6587\u672c\u548c AI \u670d\u52a1\u96c6\u6210\u3002

        "},{"location":"qsl4a/special/pgptai/#_1","title":"\u5148\u51b3\u6761\u4ef6","text":"
        pip install pgptAI\n
        "},{"location":"qsl4a/special/pgptai/#_2","title":"\u8bed\u97f3\u8bc6\u522b","text":""},{"location":"qsl4a/special/pgptai/#speechtotext","title":"speechToText()","text":"

        \u5c06\u8bed\u97f3\u8f6c\u6362\u4e3a\u6587\u672c\u3002

        speechToText(RecordSecond=10, AmrFile=None, Language=None)\n

        \u53c2\u6570\uff1a - RecordSecond (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09 - AmrFile (str, optional): \u73b0\u6709\u97f3\u9891\u6587\u4ef6\u8def\u5f84 - Language (str, optional): \u8bed\u8a00\u4ee3\u7801\uff08'en'\u3001'zh'\uff09

        \u8fd4\u56de\uff1a \u8f6c\u5f55\u7684\u6587\u672c

        "},{"location":"qsl4a/special/pgptai/#_3","title":"\u6587\u672c\u8f6c\u8bed\u97f3","text":""},{"location":"qsl4a/special/pgptai/#texttospeech","title":"textToSpeech()","text":"

        \u5c06\u6587\u672c\u8f6c\u6362\u4e3a\u8bed\u97f3\u5e76\u53ef\u9009\u5730\u64ad\u653e\u3002

        textToSpeech(Text, AutoPlay=True, WavFile=None, VoiceName=None)\n

        \u53c2\u6570\uff1a - Text (str): \u8981\u8f6c\u6362\u4e3a\u8bed\u97f3\u7684\u6587\u672c - AutoPlay (bool): \u81ea\u52a8\u64ad\u653e\u751f\u6210\u7684\u97f3\u9891\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - WavFile (str, optional): \u4fdd\u5b58 WAV \u6587\u4ef6\u7684\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u4e34\u65f6\u6587\u4ef6 - VoiceName (str, optional): \u8981\u4f7f\u7528\u7684\u8bed\u97f3\u540d\u79f0\uff08\u4f8b\u5982 'en-US-JennyNeural'\u3001'zh-CN-XiaoxiaoNeural'\uff09

        \u8fd4\u56de\uff1a \u5305\u542b\u8bed\u97f3\u5408\u6210\u7ed3\u679c\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - text: \u8f93\u5165\u6587\u672c - url: \u4e0b\u8f7d\u97f3\u9891\u6587\u4ef6\u7684 URL - WavFile: \u4fdd\u5b58\u7684 WAV \u6587\u4ef6\u8def\u5f84\uff08\u5982\u679c\u672c\u5730\u4fdd\u5b58\uff09

        "},{"location":"qsl4a/special/pgptai/#_4","title":"\u914d\u7f6e","text":"

        API \u4f7f\u7528\u4ee5\u4e0b\u914d\u7f6e\u6587\u4ef6\u4e2d\u7684\u914d\u7f6e\uff1a/storage/emulated/0/Android/data/org.qpython.qpy/files/apigpt.conf\uff1a

        [speech]\nspeech_key = your_api_key\n

        \u9ed8\u8ba4\u8bed\u97f3\u8bbe\u7f6e\uff1a - \u82f1\u8bed\uff1aen-US-JennyNeural - \u4e2d\u6587\uff1azh-CN-XiaoxiaoNeural

        "},{"location":"qsl4a/special/pgptai/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5f55\u5236\u5e76\u8f6c\u5f55\nprint(\"Recording for 5 seconds...\")\ntext = droid.speechToText(RecordSecond=5, Language='en').result\nprint(f\"You said: {text}\")\n\n# \u8f6c\u5f55\u73b0\u6709\u6587\u4ef6\ntext = droid.speechToText(AmrFile=\"/sdcard/recording.amr\").result\nprint(f\"Transcription: {text}\")\n\n# \u6587\u672c\u8f6c\u8bed\u97f3\ndroid.textToSpeech(\"Hello, this is a test message.\", AutoPlay=True, Language='en')\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u8bed\u97f3\u5e76\u4fdd\u5b58\u5230\u6587\u4ef6\u7684\u6587\u672c\u8f6c\u8bed\u97f3\nresult = droid.textToSpeech(\n    \"Welcome to QPython!\",\n    AutoPlay=False,\n    WavFile=\"/sdcard/welcome.wav\",\n    VoiceName=\"en-US-JennyNeural\"\n).result\nprint(f\"Audio saved to: {result.get('WavFile')}\")\n
        "},{"location":"qsl4a/special/pgptai/#_6","title":"\u7c7b\u4f7f\u7528","text":"
        from androidhelper.pgptai import pgptai\nimport androidhelper\n\ndroid = androidhelper.Android()\nai = pgptai(droid)\n\n# \u4f7f\u7528\u8bed\u97f3\u8bc6\u522b\ntext = ai.speechToText(RecordSecond=10)\n
        "},{"location":"qsl4a/storage/clipboard/","title":"\u526a\u8d34\u677f API","text":"

        \u590d\u5236\u548c\u7c98\u8d34\u6587\u672c\u5230\u7cfb\u7edf\u526a\u8d34\u677f\u3002

        "},{"location":"qsl4a/storage/clipboard/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/clipboard/#setclipboard","title":"setClipboard()","text":"

        \u590d\u5236\u6587\u672c\u5230\u526a\u8d34\u677f\u3002

        setClipboard(text)\n

        \u53c2\u6570\uff1a - text (str): \u8981\u590d\u5236\u7684\u6587\u672c

        \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

        "},{"location":"qsl4a/storage/clipboard/#getclipboard","title":"getClipboard()","text":"

        \u4ece\u526a\u8d34\u677f\u83b7\u53d6\u6587\u672c\u3002

        getClipboard()\n

        \u8fd4\u56de\uff1a \u526a\u8d34\u677f\u6587\u672c

        "},{"location":"qsl4a/storage/clipboard/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u590d\u5236\u5230\u526a\u8d34\u677f\ndroid.setClipboard(\"Hello from QPython!\")\n\n# \u4ece\u526a\u8d34\u677f\u7c98\u8d34\ntext = droid.getClipboard().result\nprint(f\"Clipboard: {text}\")\n
        "},{"location":"qsl4a/storage/documentfile/","title":"DocumentFile API","text":"

        \u4f7f\u7528 SAF\uff08\u5b58\u50a8\u8bbf\u95ee\u6846\u67b6\uff09\u8fdb\u884c\u6587\u4ef6\u64cd\u4f5c\uff0c\u652f\u6301 Android 4.4+\u3002

        "},{"location":"qsl4a/storage/documentfile/#_1","title":"\u76ee\u5f55\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilemkdir","title":"documentFileMkdir()","text":"

        \u521b\u5efa\u76ee\u5f55\u3002

        documentFileMkdir(Dir)\n

        \u53c2\u6570\uff1a - Dir (str): \u76ee\u5f55\u8def\u5f84

        \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

        "},{"location":"qsl4a/storage/documentfile/#documentfilelistfiles","title":"documentFileListFiles()","text":"

        \u5217\u51fa\u76ee\u5f55\u4e2d\u7684\u6587\u4ef6\u3002

        documentFileListFiles(Folder)\n

        \u8fd4\u56de\uff1a \u6587\u4ef6\u5217\u8868

        "},{"location":"qsl4a/storage/documentfile/#_2","title":"\u6587\u4ef6\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileexists","title":"documentFileExists()","text":"

        \u68c0\u67e5\u6587\u4ef6\u6216\u76ee\u5f55\u662f\u5426\u5b58\u5728\u3002

        documentFileExists(path)\n

        \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u6216\u76ee\u5f55\u8def\u5f84

        \u8fd4\u56de\uff1a \u5982\u679c\u5b58\u5728\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

        "},{"location":"qsl4a/storage/documentfile/#documentfileisfile","title":"documentFileIsFile()","text":"

        \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u6587\u4ef6\u3002

        documentFileIsFile(path)\n

        \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

        \u8fd4\u56de\uff1a \u5982\u679c\u662f\u6587\u4ef6\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u6587\u4ef6\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

        "},{"location":"qsl4a/storage/documentfile/#documentfileisdirectory","title":"documentFileIsDirectory()","text":"

        \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u76ee\u5f55\u3002

        documentFileIsDirectory(path)\n

        \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

        \u8fd4\u56de\uff1a \u5982\u679c\u662f\u76ee\u5f55\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u76ee\u5f55\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

        "},{"location":"qsl4a/storage/documentfile/#documentfiledelete","title":"documentFileDelete()","text":"

        \u5220\u9664\u6587\u4ef6\u6216\u76ee\u5f55\u3002

        documentFileDelete(FileOrTree)\n

        \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

        "},{"location":"qsl4a/storage/documentfile/#documentfilerenameto","title":"documentFileRenameTo()","text":"

        \u91cd\u547d\u540d\u6216\u79fb\u52a8\u6587\u4ef6\u3002

        documentFileRenameTo(Src, Dest)\n

        \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

        "},{"location":"qsl4a/storage/documentfile/#documentfilecopy","title":"documentFileCopy()","text":"

        \u590d\u5236\u6587\u4ef6\u3002

        documentFileCopy(SrcFileOrTree, DestFileOrTree)\n
        "},{"location":"qsl4a/storage/documentfile/#_3","title":"\u6d41\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileinputstream","title":"documentFileInputStream()","text":"

        \u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9\u3002

        documentFileInputStream(srcFile, EncodingFormat=\"\", skip=None, length=None)\n

        \u53c2\u6570\uff1a - srcFile (str): \u6e90\u6587\u4ef6 - EncodingFormat (str): \"UTF-8\"\u3001\"GBK\"\u3001\"Base64\" \u6216\u7a7a\u5b57\u7b26\u4e32\u8868\u793a\u5b57\u8282 - skip (int): \u4ece\u5f00\u5934\u8df3\u8fc7\u7684\u5b57\u8282\u6570 - length (int): \u8bfb\u53d6\u957f\u5ea6

        \u8fd4\u56de\uff1a \u6587\u4ef6\u5185\u5bb9

        "},{"location":"qsl4a/storage/documentfile/#documentfileoutputstream","title":"documentFileOutputStream()","text":"

        \u5199\u5165\u6587\u4ef6\u5185\u5bb9\u3002

        documentFileOutputStream(destFile, src, EncodingFormat=\"\", append=None)\n

        \u53c2\u6570\uff1a - destFile (str): \u76ee\u6807\u6587\u4ef6 - src: \u8981\u5199\u5165\u7684\u6570\u636e - EncodingFormat (str): \u7f16\u7801\u683c\u5f0f - append (bool): \u8ffd\u52a0\u6a21\u5f0f

        "},{"location":"qsl4a/storage/documentfile/#_4","title":"\u6587\u4ef6\u4fe1\u606f","text":""},{"location":"qsl4a/storage/documentfile/#documentfilelength","title":"documentFileLength()","text":"

        \u83b7\u53d6\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\u3002

        documentFileLength(path)\n

        \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

        \u8fd4\u56de\uff1a \u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

        "},{"location":"qsl4a/storage/documentfile/#documentfilelastmodified","title":"documentFileLastModified()","text":"

        \u83b7\u53d6\u6700\u540e\u4fee\u6539\u65f6\u95f4\u3002

        documentFileLastModified(path)\n

        \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

        \u8fd4\u56de\uff1a \u65f6\u95f4\u6233\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

        "},{"location":"qsl4a/storage/documentfile/#documentfilegetstat","title":"documentFileGetStat()","text":"

        \u83b7\u53d6\u5168\u9762\u7684\u6587\u4ef6\u7edf\u8ba1\u4fe1\u606f\u3002

        documentFileGetStat(path)\n

        \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

        \u8fd4\u56de\uff1a \u5305\u542b\u957f\u5ea6\u3001\u6700\u540e\u4fee\u6539\u65f6\u95f4\u548c\u8bfb/\u5199\u6743\u9650\u7684\u5b57\u5178\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

        "},{"location":"qsl4a/storage/documentfile/#uri","title":"URI \u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilegeturi","title":"documentFileGetUri()","text":"

        \u4ece\u8def\u5f84\u83b7\u53d6 URI\u3002

        documentFileGetUri(path, isDirectory=None)\n
        "},{"location":"qsl4a/storage/documentfile/#documentfileshowopen","title":"documentFileShowOpen()","text":"

        \u663e\u793a\u6587\u4ef6\u9009\u62e9\u5668\u3002

        documentFileShowOpen()\n

        \u8fd4\u56de\uff1a \u9009\u62e9\u7684\u6587\u4ef6 URI

        "},{"location":"qsl4a/storage/documentfile/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u76ee\u5f55\ndroid.documentFileMkdir(\"/sdcard/MyFolder\")\n\n# \u5217\u51fa\u6587\u4ef6\nfiles = droid.documentFileListFiles(\"/sdcard\").result\nfor f in files:\n    print(f)\n\n# \u8bfb\u53d6\u6587\u4ef6\ncontent = droid.documentFileInputStream(\n    \"/sdcard/test.txt\",\n    EncodingFormat=\"UTF-8\"\n).result\nprint(content)\n\n# \u5199\u5165\u6587\u4ef6\ndroid.documentFileOutputStream(\n    \"/sdcard/output.txt\",\n    \"Hello World\",\n    EncodingFormat=\"UTF-8\"\n)\n
        "},{"location":"qsl4a/storage/preferences/","title":"\u504f\u597d\u8bbe\u7f6e API","text":"

        \u4f7f\u7528 Android SharedPreferences \u5b58\u50a8\u548c\u68c0\u7d22\u6570\u636e\u3002

        "},{"location":"qsl4a/storage/preferences/#_1","title":"\u504f\u597d\u8bbe\u7f6e\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/preferences/#prefgetvalue","title":"prefGetValue()","text":"

        \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u8bfb\u53d6\u503c\u3002

        prefGetValue(key, filename=None)\n

        \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

        \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c\uff08\u4efb\u610f\u7c7b\u578b\uff09

        "},{"location":"qsl4a/storage/preferences/#prefputvalue","title":"prefPutValue()","text":"

        \u5199\u5165\u503c\u5230\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u3002

        prefPutValue(key, value, filename=None)\n

        \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - value (object): \u8981\u5b58\u50a8\u7684\u503c - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

        "},{"location":"qsl4a/storage/preferences/#prefgetall","title":"prefGetAll()","text":"

        \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\u503c\u3002

        prefGetAll(filename=None)\n

        \u53c2\u6570\uff1a - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

        \u8fd4\u56de\uff1a \u6240\u6709\u504f\u597d\u7684\u6620\u5c04

        "},{"location":"qsl4a/storage/preferences/#prefremovevalue","title":"prefRemoveValue()","text":"

        \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u4e2d\u79fb\u9664\u503c\u3002

        prefRemoveValue(key, filename=None)\n

        \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

        "},{"location":"qsl4a/storage/preferences/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b58\u50a8\u503c\ndroid.prefPutValue(\"username\", \"alice\")\ndroid.prefPutValue(\"score\", 100)\ndroid.prefPutValue(\"enabled\", True)\n\n# \u8bfb\u53d6\u7279\u5b9a\u503c\nusername = droid.prefGetValue(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\nall_prefs = droid.prefGetAll().result\nprint(f\"All prefs: {all_prefs}\")\n\n# \u79fb\u9664\u503c\ndroid.prefRemoveValue(\"score\")\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u6587\u4ef6\u540d\ndroid.prefPutValue(\"token\", \"abc123\", filename=\"auth.prefs\")\ntoken = droid.prefGetValue(\"token\", filename=\"auth.prefs\").result\n
        "},{"location":"qsl4a/system/activityresult/","title":"Activity Result API","text":"

        \u4e3a\u901a\u8fc7 startActivityForResult \u542f\u52a8\u7684\u811a\u672c\u8bbe\u7f6e activity \u7ed3\u679c\u3002

        "},{"location":"qsl4a/system/activityresult/#_1","title":"\u7ed3\u679c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/activityresult/#setresultboolean","title":"setResultBoolean()","text":"

        \u8bbe\u7f6e\u5e03\u5c14\u7ed3\u679c\u3002

        setResultBoolean(resultCode, resultValue)\n

        \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (bool): \u5e03\u5c14\u7ed3\u679c\u503c

        "},{"location":"qsl4a/system/activityresult/#setresultbyte","title":"setResultByte()","text":"

        \u8bbe\u7f6e\u5b57\u8282\u7ed3\u679c\u3002

        setResultByte(resultCode, resultValue)\n

        \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u5b57\u8282\u7ed3\u679c\u503c

        "},{"location":"qsl4a/system/activityresult/#setresultshort","title":"setResultShort()","text":"

        \u8bbe\u7f6e\u77ed\u6574\u6570\u7ed3\u679c\u3002

        setResultShort(resultCode, resultValue)\n

        \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u77ed\u6574\u6570\u7ed3\u679c\u503c

        "},{"location":"qsl4a/system/activityresult/#setresultchar","title":"setResultChar()","text":"

        \u8bbe\u7f6e\u5b57\u7b26\u7ed3\u679c\u3002

        setResultChar(resultCode, resultValue)\n

        \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u7ed3\u679c\u503c

        "},{"location":"qsl4a/system/activityresult/#setresultinteger","title":"setResultInteger()","text":"

        \u8bbe\u7f6e\u6574\u6570\u7ed3\u679c\u3002

        setResultInteger(resultCode, resultValue)\n

        \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u6574\u6570\u7ed3\u679c\u503c

        "},{"location":"qsl4a/system/activityresult/#setresultlong","title":"setResultLong()","text":"

        \u8bbe\u7f6e\u957f\u6574\u6570\u7ed3\u679c\u3002

        setResultLong(resultCode, resultValue)\n

        \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u957f\u6574\u6570\u7ed3\u679c\u503c

        "},{"location":"qsl4a/system/activityresult/#setresultfloat","title":"setResultFloat()","text":"

        \u8bbe\u7f6e\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

        setResultFloat(resultCode, resultValue)\n

        \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u6d6e\u70b9\u6570\u7ed3\u679c\u503c

        "},{"location":"qsl4a/system/activityresult/#setresultdouble","title":"setResultDouble()","text":"

        \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

        setResultDouble(resultCode, resultValue)\n

        \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u503c

        "},{"location":"qsl4a/system/activityresult/#setresultstring","title":"setResultString()","text":"

        \u8bbe\u7f6e\u5b57\u7b26\u4e32\u7ed3\u679c\u3002

        setResultString(resultCode, resultValue)\n

        \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u4e32\u7ed3\u679c\u503c

        "},{"location":"qsl4a/system/activityresult/#setresultbooleanarray","title":"setResultBooleanArray()","text":"

        \u8bbe\u7f6e\u5e03\u5c14\u6570\u7ec4\u7ed3\u679c\u3002

        setResultBooleanArray(resultCode, resultValue)\n

        \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5e03\u5c14\u6570\u7ec4

        "},{"location":"qsl4a/system/activityresult/#setresultbytearray","title":"setResultByteArray()","text":"

        \u8bbe\u7f6e\u5b57\u8282\u6570\u7ec4\u7ed3\u679c\u3002

        setResultByteArray(resultCode, resultValue)\n

        \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u8282\u6570\u7ec4

        "},{"location":"qsl4a/system/activityresult/#setresultshortarray","title":"setResultShortArray()","text":"

        \u8bbe\u7f6e\u77ed\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

        setResultShortArray(resultCode, resultValue)\n

        \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u77ed\u6574\u6570\u6570\u7ec4

        "},{"location":"qsl4a/system/activityresult/#setresultchararray","title":"setResultCharArray()","text":"

        \u8bbe\u7f6e\u5b57\u7b26\u6570\u7ec4\u7ed3\u679c\u3002

        setResultCharArray(resultCode, resultValue)\n

        \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u6570\u7ec4

        "},{"location":"qsl4a/system/activityresult/#setresultintegerarray","title":"setResultIntegerArray()","text":"

        \u8bbe\u7f6e\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

        setResultIntegerArray(resultCode, resultValue)\n

        \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6574\u6570\u6570\u7ec4

        "},{"location":"qsl4a/system/activityresult/#setresultlongarray","title":"setResultLongArray()","text":"

        \u8bbe\u7f6e\u957f\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

        setResultLongArray(resultCode, resultValue)\n

        \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u957f\u6574\u6570\u6570\u7ec4

        "},{"location":"qsl4a/system/activityresult/#setresultfloatarray","title":"setResultFloatArray()","text":"

        \u8bbe\u7f6e\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

        setResultFloatArray(resultCode, resultValue)\n

        \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6d6e\u70b9\u6570\u6570\u7ec4

        "},{"location":"qsl4a/system/activityresult/#setresultdoublearray","title":"setResultDoubleArray()","text":"

        \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

        setResultDoubleArray(resultCode, resultValue)\n

        \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4

        "},{"location":"qsl4a/system/activityresult/#setresultstringarray","title":"setResultStringArray()","text":"

        \u8bbe\u7f6e\u5b57\u7b26\u4e32\u6570\u7ec4\u7ed3\u679c\u3002

        setResultStringArray(resultCode, resultValue)\n

        \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u4e32\u6570\u7ec4

        "},{"location":"qsl4a/system/activityresult/#setresultserializable","title":"setResultSerializable()","text":"

        \u8bbe\u7f6e\u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u3002

        setResultSerializable(resultCode, resultValue)\n

        \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue: \u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u503c

        "},{"location":"qsl4a/system/activityresult/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c activity \u540e\uff0c\u8bbe\u7f6e\u7ed3\u679c\n# \u793a\u4f8b\uff1a\u8fd4\u56de\u6210\u529f\u53ca\u6570\u636e\ndroid.setResultInteger(0, 200)  # RESULT_OK\ndroid.setResultString(0, \"Operation completed successfully\")\n\n# \u8fd4\u56de\u6570\u7ec4\u7ed3\u679c\ndroid.setResultIntegerArray(0, [1, 2, 3, 4, 5])\n
        "},{"location":"qsl4a/system/application/","title":"\u5e94\u7528\u7ba1\u7406","text":"

        \u7ba1\u7406\u5e94\u7528\u7a0b\u5e8f\u3001\u542f\u52a8\u5e94\u7528\u548c\u67e5\u8be2\u7cfb\u7edf\u4fe1\u606f\u3002

        "},{"location":"qsl4a/system/application/#_2","title":"\u5e94\u7528\u7a0b\u5e8f\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getapplicationinfo","title":"getApplicationInfo()","text":"

        \u83b7\u53d6\u5e94\u7528\u4fe1\u606f\u3002

        getApplicationInfo(packageName=None)\n

        \u53c2\u6570\uff1a - packageName (str): \u5305\u540d\uff08None = \u5f53\u524d\u5e94\u7528\uff09

        \u8fd4\u56de\uff1a \u5e94\u7528\u4fe1\u606f\u5b57\u5178

        "},{"location":"qsl4a/system/application/#getinstalledpackages","title":"getInstalledPackages()","text":"

        \u83b7\u53d6\u5df2\u5b89\u88c5\u5305\u5217\u8868\u3002

        getInstalledPackages(flag=4)\n

        \u53c2\u6570\uff1a - flag (int): \u5305\u6807\u5fd7\u8fc7\u6ee4\u5668\uff08\u9ed8\u8ba4\uff1a4\uff09

        \u8fd4\u56de\uff1a \u5df2\u5b89\u88c5\u5305\u5217\u8868

        "},{"location":"qsl4a/system/application/#getrunningpackages","title":"getRunningPackages()","text":"

        \u5217\u51fa\u6b63\u5728\u8fd0\u884c\u7684\u5305\u3002

        getRunningPackages()\n

        \u8fd4\u56de\uff1a \u5305\u540d\u5217\u8868

        "},{"location":"qsl4a/system/application/#getlaunchablepackages","title":"getLaunchablePackages()","text":"

        \u83b7\u53d6\u53ef\u542f\u52a8\u5305\u5217\u8868\u3002

        getLaunchablePackages(needClassName=False)\n

        \u53c2\u6570\uff1a - needClassName (bool): \u5305\u542b\u4e3b activity \u7c7b\u540d\uff08\u9ed8\u8ba4\uff1aFalse\uff09

        \u8fd4\u56de\uff1a \u53ef\u542f\u52a8\u5305\u540d\u5217\u8868\u6216\u5305\u542b\u7c7b\u540d\u7684\u5b57\u5178

        "},{"location":"qsl4a/system/application/#_3","title":"\u5e94\u7528\u63a7\u5236","text":""},{"location":"qsl4a/system/application/#launch","title":"launch()","text":"

        \u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u3002

        launch(classname=None, packagename=None, wait=True)\n

        \u53c2\u6570\uff1a - classname (str): \u4e3b activity \u7c7b\u540d - packagename (str): \u5305\u540d - wait (bool): \u7b49\u5f85\u542f\u52a8\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

        \u8fd4\u56de\uff1a \u542f\u52a8\u7ed3\u679c

        "},{"location":"qsl4a/system/application/#forcestoppackage","title":"forceStopPackage()","text":"

        \u5f3a\u5236\u505c\u6b62\u5e94\u7528\u7a0b\u5e8f\u3002

        forceStopPackage(packageName)\n

        \u53c2\u6570\uff1a - packageName (str): \u8981\u505c\u6b62\u7684\u5305\u540d

        "},{"location":"qsl4a/system/application/#_4","title":"\u7248\u672c\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getpackageversion","title":"getPackageVersion()","text":"

        \u83b7\u53d6\u5e94\u7528\u7248\u672c\u540d\u79f0\u3002

        getPackageVersion(packageName)\n

        \u8fd4\u56de\uff1a \u7248\u672c\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"3.2.1\"\uff09

        "},{"location":"qsl4a/system/application/#getpackageversioncode","title":"getPackageVersionCode()","text":"

        \u83b7\u53d6\u5e94\u7528\u7248\u672c\u4ee3\u7801\u3002

        getPackageVersionCode(packageName)\n

        \u8fd4\u56de\uff1a \u7248\u672c\u4ee3\u7801\u6574\u6570

        "},{"location":"qsl4a/system/application/#getconstants","title":"getConstants()","text":"

        \u83b7\u53d6\u7c7b\u5e38\u91cf\u3002

        getConstants(classname)\n

        \u53c2\u6570\uff1a - classname (str): \u5b8c\u6574\u7c7b\u540d

        \u8fd4\u56de\uff1a \u5e38\u91cf\u540d\u548c\u503c\u7684\u5b57\u5178

        "},{"location":"qsl4a/system/application/#_5","title":"\u7cfb\u7edf\u529f\u80fd","text":""},{"location":"qsl4a/system/application/#backgroundprotect","title":"backgroundProtect()","text":"

        \u542f\u7528\u6216\u7981\u7528\u5e94\u7528\u7684\u540e\u53f0\u4fdd\u62a4\u3002

        backgroundProtect(enabled=True)\n

        \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\u4fdd\u62a4\uff0cFalse \u7981\u7528

        "},{"location":"qsl4a/system/application/#createscriptshortcut","title":"createScriptShortCut()","text":"

        \u4e3a\u811a\u672c\u521b\u5efa\u4e3b\u5c4f\u5e55\u5feb\u6377\u65b9\u5f0f\u3002

        createScriptShortCut(scriptPath, label=None, iconPath=None, scriptArg=None)\n

        \u53c2\u6570\uff1a - scriptPath (str): Python \u811a\u672c\u8def\u5f84 - label (str, optional): \u5feb\u6377\u65b9\u5f0f\u6807\u7b7e - iconPath (str, optional): \u56fe\u6807\u56fe\u50cf\u8def\u5f84 - scriptArg (str, optional): \u4f20\u9012\u7ed9\u811a\u672c\u7684\u53c2\u6570

        "},{"location":"qsl4a/system/application/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getandroidid","title":"getAndroidID()","text":"

        \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

        getAndroidID()\n

        \u8fd4\u56de\uff1a \u552f\u4e00\u7684 Android \u8bbe\u5907 ID \u5b57\u7b26\u4e32

        "},{"location":"qsl4a/system/application/#getsysinfo","title":"getSysInfo()","text":"

        \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\u3002

        getSysInfo()\n

        \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

        "},{"location":"qsl4a/system/application/#getlocale","title":"getLocale()","text":"

        \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u3002

        getLocale()\n

        \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

        "},{"location":"qsl4a/system/application/#getharmonyosinformation","title":"getHarmonyOsInformation()","text":"

        \u5982\u679c\u5728 HarmonyOS \u4e0a\u8fd0\u884c\uff0c\u83b7\u53d6 HarmonyOS \u4fe1\u606f\u3002

        getHarmonyOsInformation()\n

        \u8fd4\u56de\uff1a HarmonyOS \u7248\u672c\u4fe1\u606f\u6216 None

        "},{"location":"qsl4a/system/application/#isexternalstoragemanager","title":"isExternalStorageManager()","text":"

        \u68c0\u67e5\u5e94\u7528\u662f\u5426\u6709\u5916\u90e8\u5b58\u50a8\u7ba1\u7406\u5668\u6743\u9650\u3002

        isExternalStorageManager()\n

        \u8fd4\u56de\uff1a \u5982\u679c\u6709\u6743\u9650\u5219\u4e3a True

        "},{"location":"qsl4a/system/application/#_7","title":"\u5185\u5b58\u548c\u663e\u793a","text":""},{"location":"qsl4a/system/application/#getmemoryinfo","title":"getMemoryInfo()","text":"

        \u83b7\u53d6\u5185\u5b58\u4fe1\u606f\u3002

        getMemoryInfo()\n

        \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

        "},{"location":"qsl4a/system/application/#getscreeninfo","title":"getScreenInfo()","text":"

        \u83b7\u53d6\u5c4f\u5e55\u4fe1\u606f\u3002

        getScreenInfo()\n

        \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

        "},{"location":"qsl4a/system/application/#_8","title":"\u6743\u9650","text":""},{"location":"qsl4a/system/application/#checkpermissions","title":"checkPermissions()","text":"

        \u68c0\u67e5\u5f53\u524d\u5e94\u7528\u6743\u9650\u3002

        checkPermissions()\n

        \u8fd4\u56de\uff1a \u6743\u9650\u53ca\u5176\u72b6\u6001\u7684\u5b57\u5178

        "},{"location":"qsl4a/system/application/#requestpermissions","title":"requestPermissions()","text":"

        \u5411\u7528\u6237\u8bf7\u6c42\u6743\u9650\u3002

        requestPermissions(permissions=None)\n

        \u53c2\u6570\uff1a - permissions (list, optional): \u8981\u8bf7\u6c42\u7684\u6743\u9650\u5217\u8868\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8bf7\u6c42\u6240\u6709\u9700\u8981\u7684\u6743\u9650\u3002

        \u8fd4\u56de\uff1a \u6743\u9650\u8bf7\u6c42\u7ed3\u679c

        "},{"location":"qsl4a/system/application/#_9","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/system/application/#showscreenlock","title":"showScreenLock()","text":"

        \u663e\u793a\u5c4f\u5e55\u9501\u5b9a\uff08PIN/\u56fe\u6848/\u5bc6\u7801\u8f93\u5165\uff09\u3002

        showScreenLock()\n
        "},{"location":"qsl4a/system/application/#_10","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\ninfo = droid.getSysInfo().result\nprint(f\"System: {info}\")\n\n# \u83b7\u53d6\u5e94\u7528\u7248\u672c\nversion = droid.getPackageVersion(\"org.qpython.qpy\").result\nprint(f\"QPython version: {version}\")\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u5e94\u7528\napps = droid.getInstalledPackages().result\nprint(f\"Installed apps: {len(apps)}\")\n\n# \u542f\u52a8\u5e94\u7528\ndroid.launch(packagename=\"com.android.settings\")\n\n# \u68c0\u67e5\u6743\u9650\nperms = droid.checkPermissions().result\nprint(f\"Permissions: {perms}\")\n\n# \u8bf7\u6c42\u5b58\u50a8\u6743\u9650\ndroid.requestPermissions([\"android.permission.READ_EXTERNAL_STORAGE\"])\n\n# \u521b\u5efa\u5feb\u6377\u65b9\u5f0f\ndroid.createScriptShortCut(\n    \"/sdcard/my_script.py\",\n    label=\"My Script\",\n    iconPath=\"/sdcard/icon.png\"\n)\n
        "},{"location":"qsl4a/system/battery/","title":"\u7535\u6c60 API","text":"

        \u76d1\u63a7\u8bbe\u5907\u7535\u6c60\u72b6\u6001\u548c\u5065\u5eb7\u72b6\u51b5\u3002

        "},{"location":"qsl4a/system/battery/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/battery/#readbatterydata","title":"readBatteryData()","text":"

        \u83b7\u53d6\u5b8c\u6574\u7684\u7535\u6c60\u4fe1\u606f\u3002

        readBatteryData()\n

        \u8fd4\u56de\uff1a \u5305\u542b\u7535\u6c60\u6570\u636e\u7684\u5b57\u5178

        "},{"location":"qsl4a/system/battery/#batterystartmonitoring","title":"batteryStartMonitoring()","text":"

        \u5f00\u59cb\u7535\u6c60\u76d1\u63a7\u3002

        batteryStartMonitoring()\n
        "},{"location":"qsl4a/system/battery/#batterystopmonitoring","title":"batteryStopMonitoring()","text":"

        \u505c\u6b62\u7535\u6c60\u76d1\u63a7\u3002

        batteryStopMonitoring()\n
        "},{"location":"qsl4a/system/battery/#batterygetlevel","title":"batteryGetLevel()","text":"

        \u83b7\u53d6\u7535\u6c60\u767e\u5206\u6bd4\u3002

        batteryGetLevel()\n

        \u8fd4\u56de\uff1a \u6574\u6570\uff080-100\uff09

        "},{"location":"qsl4a/system/battery/#batterygetstatus","title":"batteryGetStatus()","text":"

        \u83b7\u53d6\u5145\u7535\u72b6\u6001\u3002

        batteryGetStatus()\n

        \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u5145\u7535\u4e2d - 3: \u653e\u7535\u4e2d - 4: \u672a\u5145\u7535 - 5: \u5df2\u5145\u6ee1

        "},{"location":"qsl4a/system/battery/#batterygetplugtype","title":"batteryGetPlugType()","text":"

        \u83b7\u53d6\u7535\u6e90\u7c7b\u578b\u3002

        batteryGetPlugType()\n

        \u8fd4\u56de\uff1a - -1: \u672a\u77e5 - 0: \u672a\u63d2\u7535 - 1: AC \u5145\u7535\u5668 - 2: USB \u7aef\u53e3

        "},{"location":"qsl4a/system/battery/#batterygethealth","title":"batteryGetHealth()","text":"

        \u83b7\u53d6\u7535\u6c60\u5065\u5eb7\u72b6\u51b5\u3002

        batteryGetHealth()\n

        \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u826f\u597d - 3: \u8fc7\u70ed - 4: \u635f\u574f - 5: \u8fc7\u538b - 6: \u672a\u6307\u5b9a\u7684\u6545\u969c

        "},{"location":"qsl4a/system/battery/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\nlevel = droid.batteryGetLevel().result\nprint(f\"Battery: {level}%\")\n
        "},{"location":"qsl4a/system/qpyinterface/","title":"QPython \u63a5\u53e3 API","text":"

        \u4ece\u5176\u4ed6\u5e94\u7528\u6267\u884c QPython \u811a\u672c\u548c\u7ba1\u7406\u5171\u4eab\u53d8\u91cf\u3002

        "},{"location":"qsl4a/system/qpyinterface/#_1","title":"\u811a\u672c\u6267\u884c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/qpyinterface/#executeqpy","title":"executeQPy()","text":"

        \u6267\u884c QPython \u811a\u672c\u3002

        executeQPy(path=\"\", arg=None)\n

        \u53c2\u6570\uff1a - path (str): \u811a\u672c\u6587\u4ef6\u8def\u5f84 - arg (str, optional): \u547d\u4ee4\u884c\u53c2\u6570

        \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

        "},{"location":"qsl4a/system/qpyinterface/#executeqpyassrv","title":"executeQPyAsSrv()","text":"

        \u4f5c\u4e3a\u670d\u52a1\u6267\u884c QPython \u811a\u672c\u3002

        executeQPyAsSrv(path=None)\n

        \u53c2\u6570\uff1a - path (str, optional): \u811a\u672c\u6587\u4ef6\u8def\u5f84

        \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

        "},{"location":"qsl4a/system/qpyinterface/#executeqpycode","title":"executeQPyCode()","text":"

        \u76f4\u63a5\u6267\u884c Python \u4ee3\u7801\u3002

        executeQPyCode(code=None)\n

        \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

        \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

        "},{"location":"qsl4a/system/qpyinterface/#executeqpycodeassrv","title":"executeQPyCodeAsSrv()","text":"

        \u4f5c\u4e3a\u670d\u52a1\u6267\u884c Python \u4ee3\u7801\u3002

        executeQPyCodeAsSrv(code=None)\n

        \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

        \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

        "},{"location":"qsl4a/system/qpyinterface/#_2","title":"\u5171\u4eab\u53d8\u91cf","text":"

        \u5171\u4eab\u53d8\u91cf\u5141\u8bb8 QPython \u4e0e\u5176\u4ed6\u5e94\u7528\u4e4b\u95f4\u8fdb\u884c\u901a\u4fe1\u3002

        "},{"location":"qsl4a/system/qpyinterface/#sharedvariableset","title":"sharedVariableSet()","text":"

        \u8bbe\u7f6e Java \u5171\u4eab\u53d8\u91cf\u3002

        sharedVariableSet(key, value)\n

        \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d - value (str): \u53d8\u91cf\u503c

        \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

        "},{"location":"qsl4a/system/qpyinterface/#sharedvariableget","title":"sharedVariableGet()","text":"

        \u83b7\u53d6 Java \u5171\u4eab\u53d8\u91cf\u3002

        sharedVariableGet(key)\n

        \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d

        \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

        "},{"location":"qsl4a/system/qpyinterface/#sharedvariableremove","title":"sharedVariableRemove()","text":"

        \u79fb\u9664 Java \u5171\u4eab\u53d8\u91cf\u3002

        sharedVariableRemove(key)\n

        \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u53d8\u91cf\u540d

        \u8fd4\u56de\uff1a \u88ab\u79fb\u9664\u7684\u503c

        "},{"location":"qsl4a/system/qpyinterface/#getlastlog","title":"getLastLog()","text":"

        \u83b7\u53d6 QPython \u7684\u6700\u540e\u65e5\u5fd7\u8f93\u51fa\u3002

        getLastLog()\n

        \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u65e5\u5fd7\u5185\u5bb9

        "},{"location":"qsl4a/system/qpyinterface/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c\u811a\u672c\ndroid.executeQPy(\"/sdcard/my_script.py\", arg=\"test\")\n\n# \u76f4\u63a5\u6267\u884c\u4ee3\u7801\ncode = \"print('Hello from QPython!')\"\ndroid.executeQPyCode(code)\n\n# \u4f7f\u7528\u5171\u4eab\u53d8\u91cf\ndroid.sharedVariableSet(\"username\", \"alice\")\nusername = droid.sharedVariableGet(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u79fb\u9664\u53d8\u91cf\ndroid.sharedVariableRemove(\"username\")\n\n# \u83b7\u53d6\u6700\u8fd1\u65e5\u5fd7\nlog = droid.getLastLog().result\nprint(f\"Log: {log}\")\n
        "},{"location":"qsl4a/system/sensors/","title":"\u4f20\u611f\u5668 API","text":"

        \u8bbf\u95ee\u8bbe\u5907\u4f20\u611f\u5668\uff0c\u5305\u62ec\u52a0\u901f\u5ea6\u8ba1\u3001\u9640\u87ba\u4eea\u3001\u78c1\u529b\u8ba1\u7b49\u3002

        "},{"location":"qsl4a/system/sensors/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/sensors/#startsensingtimed","title":"startSensingTimed()","text":"

        \u5f00\u59cb\u4f20\u611f\u5668\u76d1\u63a7\u5e76\u8bbe\u7f6e\u65f6\u95f4\u95f4\u9694\u3002

        startSensingTimed(sensorNumber, delayTime)\n

        \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID\uff08\u901a\u5e38\u4e3a 1-3\uff09 - delayTime (int): \u8bfb\u53d6\u4e4b\u95f4\u7684\u5ef6\u8fdf\uff08\u6beb\u79d2\uff09

        "},{"location":"qsl4a/system/sensors/#startsensingthreshold","title":"startSensingThreshold()","text":"

        \u5f00\u59cb\u5e26\u9608\u503c\u89e6\u53d1\u7684\u4f20\u611f\u5668\u76d1\u63a7\u3002

        startSensingThreshold(sensorNumber, threshold, axis)\n

        \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID - threshold (float): \u89e6\u53d1\u9608\u503c - axis (int): \u8981\u76d1\u63a7\u7684\u8f74\uff080=X\uff0c1=Y\uff0c2=Z\uff09

        "},{"location":"qsl4a/system/sensors/#stopsensing","title":"stopSensing()","text":"

        \u505c\u6b62\u6240\u6709\u4f20\u611f\u5668\u76d1\u63a7\u3002

        stopSensing()\n
        "},{"location":"qsl4a/system/sensors/#readsensors","title":"readSensors()","text":"

        \u8bfb\u53d6\u5f53\u524d\u4f20\u611f\u5668\u6570\u636e\u3002

        readSensors()\n

        \u8fd4\u56de\uff1a \u4f20\u611f\u5668\u6570\u636e\u5b57\u5178

        "},{"location":"qsl4a/system/sensors/#sensorsreadaccelerometer","title":"sensorsReadAccelerometer()","text":"

        \u8bfb\u53d6\u52a0\u901f\u5ea6\u8ba1\u503c\u3002

        sensorsReadAccelerometer()\n

        \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d m/s\u00b2

        "},{"location":"qsl4a/system/sensors/#sensorsreadgyroscope","title":"sensorsReadGyroscope()","text":"

        \u8bfb\u53d6\u9640\u87ba\u4eea\u503c\u3002

        sensorsReadGyroscope()\n

        \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d rad/s

        "},{"location":"qsl4a/system/sensors/#sensorsreadmagnetometer","title":"sensorsReadMagnetometer()","text":"

        \u8bfb\u53d6\u78c1\u573a\u503c\u3002

        sensorsReadMagnetometer()\n

        \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d \u03bcT

        "},{"location":"qsl4a/system/sensors/#sensorsreadorientation","title":"sensorsReadOrientation()","text":"

        \u8bfb\u53d6\u8bbe\u5907\u65b9\u5411\u3002

        sensorsReadOrientation()\n

        \u8fd4\u56de\uff1a \u5217\u8868 [azimuth, pitch, roll]\uff0c\u5355\u4f4d\u5ea6

        "},{"location":"qsl4a/system/sensors/#sensorsgetlight","title":"sensorsGetLight()","text":"

        \u8bfb\u53d6\u5149\u4f20\u611f\u5668\u503c\u3002

        sensorsGetLight()\n

        \u8fd4\u56de\uff1a \u5149\u7ea7\u522b\uff08lux\uff09

        "},{"location":"qsl4a/system/sensors/#sensorsgetstepcounter","title":"sensorsGetStepCounter()","text":"

        \u8bfb\u53d6\u6b65\u8ba1\u6570\u5668\u3002

        sensorsGetStepCounter()\n

        \u8fd4\u56de\uff1a \u6b65\u6570

        "},{"location":"qsl4a/system/sensors/#sensorsgetaccuracy","title":"sensorsGetAccuracy()","text":"

        \u83b7\u53d6\u5f53\u524d\u4f20\u611f\u5668\u7cbe\u5ea6\u3002

        sensorsGetAccuracy()\n

        \u8fd4\u56de\uff1a \u7cbe\u5ea6\u503c\uff080-3\uff1aUNRELIABLE\u3001ACCURACY_LOW\u3001ACCURACY_MEDIUM\u3001ACCURACY_HIGH\uff09

        "},{"location":"qsl4a/system/sensors/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u8bfb\u53d6\u4f20\u611f\u5668 10 \u6b21\nfor i in range(10):\n    accel = droid.sensorsReadAccelerometer().result\n    print(f\"Accel: X={accel[0]:.2f}, Y={accel[1]:.2f}, Z={accel[2]:.2f}\")\n    time.sleep(0.5)\n\ndroid.stopSensing()\n
        "},{"location":"qsl4a/system/settings/","title":"\u8bbe\u7f6e API","text":"

        \u63a7\u5236\u7cfb\u7edf\u8bbe\u7f6e\uff0c\u5305\u62ec\u5c4f\u5e55\u3001\u58f0\u97f3\u548c\u7f51\u7edc\u8bbe\u7f6e\u3002

        "},{"location":"qsl4a/system/settings/#_1","title":"\u5c4f\u5e55\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#setscreentimeout","title":"setScreenTimeout()","text":"

        \u8bbe\u7f6e\u5c4f\u5e55\u8d85\u65f6\u503c\u3002

        setScreenTimeout(value)\n

        \u53c2\u6570\uff1a - value (int): \u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

        \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u8d85\u65f6\u503c

        "},{"location":"qsl4a/system/settings/#getscreentimeout","title":"getScreenTimeout()","text":"

        \u83b7\u53d6\u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u3002

        getScreenTimeout()\n

        \u8fd4\u56de\uff1a \u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

        "},{"location":"qsl4a/system/settings/#getscreenbrightness","title":"getScreenBrightness()","text":"

        \u83b7\u53d6\u5c4f\u5e55\u4eae\u5ea6\u503c\u3002

        getScreenBrightness()\n

        \u8fd4\u56de\uff1a \u4eae\u5ea6\u503c\uff080-255\uff09

        "},{"location":"qsl4a/system/settings/#setscreenbrightness","title":"setScreenBrightness()","text":"

        \u8bbe\u7f6e\u5c4f\u5e55\u4eae\u5ea6\u3002

        setScreenBrightness(value=None)\n

        \u53c2\u6570\uff1a - value (int, optional): \u4eae\u5ea6\u503c\uff080-255\uff09\uff0c\u6216 None \u8868\u793a\u81ea\u52a8

        \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u4eae\u5ea6\u503c

        "},{"location":"qsl4a/system/settings/#checkscreenon","title":"checkScreenOn()","text":"

        \u68c0\u67e5\u5c4f\u5e55\u662f\u5426\u4eae\u7740\u3002

        checkScreenOn()\n

        \u8fd4\u56de\uff1a \u5982\u679c\u5c4f\u5e55\u4eae\u7740\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

        "},{"location":"qsl4a/system/settings/#_2","title":"\u98de\u884c\u6a21\u5f0f","text":""},{"location":"qsl4a/system/settings/#checkairplanemode","title":"checkAirplaneMode()","text":"

        \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\u662f\u5426\u542f\u7528\u3002

        checkAirplaneMode()\n

        \u8fd4\u56de\uff1a \u5982\u679c\u98de\u884c\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

        "},{"location":"qsl4a/system/settings/#_3","title":"\u94c3\u58f0\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#checkringersilentmode","title":"checkRingerSilentMode()","text":"

        \u68c0\u67e5\u94c3\u58f0\u662f\u5426\u5904\u4e8e\u9759\u97f3\u6a21\u5f0f\u3002

        checkRingerSilentMode()\n

        \u8fd4\u56de\uff1a \u5982\u679c\u9759\u97f3\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

        "},{"location":"qsl4a/system/settings/#toggleringersilentmode","title":"toggleRingerSilentMode()","text":"

        \u5207\u6362\u94c3\u58f0\u9759\u97f3\u6a21\u5f0f\u3002

        toggleRingerSilentMode(enabled=None)\n

        \u53c2\u6570\uff1a - enabled (bool, optional): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

        \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

        "},{"location":"qsl4a/system/settings/#togglevibratemode","title":"toggleVibrateMode()","text":"

        \u5207\u6362\u632f\u52a8\u6a21\u5f0f\u3002

        toggleVibrateMode(enabled=None, ringer=None)\n

        \u53c2\u6570\uff1a - enabled (bool, optional): \u5207\u6362\u632f\u52a8\u5f00/\u5173 - ringer (bool, optional): \u5e94\u7528\u4e8e\u94c3\u58f0\u6a21\u5f0f

        \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

        "},{"location":"qsl4a/system/settings/#getvibratemode","title":"getVibrateMode()","text":"

        \u83b7\u53d6\u632f\u52a8\u6a21\u5f0f\u8bbe\u7f6e\u3002

        getVibrateMode(ringer=None)\n

        \u53c2\u6570\uff1a - ringer (bool, optional): \u68c0\u67e5\u94c3\u58f0\u632f\u52a8\u6a21\u5f0f

        \u8fd4\u56de\uff1a \u5982\u679c\u632f\u52a8\u5df2\u542f\u7528\u5219\u4e3a True

        "},{"location":"qsl4a/system/settings/#_4","title":"\u97f3\u91cf\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#getringervolume","title":"getRingerVolume()","text":"

        \u83b7\u53d6\u5f53\u524d\u94c3\u58f0\u97f3\u91cf\u3002

        getRingerVolume()\n

        \u8fd4\u56de\uff1a \u94c3\u58f0\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-7\uff09

        "},{"location":"qsl4a/system/settings/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

        \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

        getMaxRingerVolume()\n

        \u8fd4\u56de\uff1a \u6700\u5927\u94c3\u58f0\u97f3\u91cf

        "},{"location":"qsl4a/system/settings/#setringervolume","title":"setRingerVolume()","text":"

        \u8bbe\u7f6e\u94c3\u58f0\u97f3\u91cf\u3002

        setRingerVolume(volume)\n

        \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

        "},{"location":"qsl4a/system/settings/#getmediavolume","title":"getMediaVolume()","text":"

        \u83b7\u53d6\u5f53\u524d\u5a92\u4f53\u97f3\u91cf\u3002

        getMediaVolume()\n

        \u8fd4\u56de\uff1a \u5a92\u4f53\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-15\uff09

        "},{"location":"qsl4a/system/settings/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

        \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

        getMaxMediaVolume()\n

        \u8fd4\u56de\uff1a \u6700\u5927\u5a92\u4f53\u97f3\u91cf

        "},{"location":"qsl4a/system/settings/#setmediavolume","title":"setMediaVolume()","text":"

        \u8bbe\u7f6e\u5a92\u4f53\u97f3\u91cf\u3002

        setMediaVolume(volume)\n

        \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

        "},{"location":"qsl4a/system/settings/#_5","title":"\u7cfb\u7edf\u4fe1\u606f","text":""},{"location":"qsl4a/system/settings/#elapsedrealtimenanos","title":"elapsedRealtimeNanos()","text":"

        \u83b7\u53d6\u81ea\u7cfb\u7edf\u542f\u52a8\u4ee5\u6765\u7684\u7eb3\u79d2\u6570\u3002

        elapsedRealtimeNanos()\n

        \u8fd4\u56de\uff1a \u7eb3\u79d2\u6570\uff08\u53ef\u7528\u4e8e\u8ba1\u65f6\uff09

        "},{"location":"qsl4a/system/settings/#gettrafficstats","title":"getTrafficStats()","text":"

        \u83b7\u53d6\u7f51\u7edc\u6d41\u91cf\u7edf\u8ba1\u3002

        getTrafficStats(flags=7)\n

        \u53c2\u6570\uff1a - flags (int): \u8981\u68c0\u7d22\u7684\u7edf\u8ba1\uff08\u9ed8\u8ba4\uff1a7 = \u5168\u90e8\uff09

        \u8fd4\u56de\uff1a \u5305\u542b\u53d1\u9001/\u63a5\u6536\u5b57\u8282\u7684\u5b57\u5178

        "},{"location":"qsl4a/system/settings/#getapptxbytes","title":"getAppTxBytes()","text":"

        \u83b7\u53d6 QPython \u5e94\u7528\u7684\u53d1\u9001\u5b57\u8282\u3002

        getAppTxBytes(packageName)\n

        \u53c2\u6570\uff1a - packageName (str): \u5305\u540d

        \u8fd4\u56de\uff1a \u5305\u542b tx/rx \u5b57\u8282\u7684\u5b57\u5178

        "},{"location":"qsl4a/system/settings/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5c4f\u5e55\u8bbe\u7f6e\ncurrent_timeout = droid.getScreenTimeout().result\nprint(f\"Current timeout: {current_timeout}s\")\ndroid.setScreenTimeout(30)\n\n# \u68c0\u67e5\u5c4f\u5e55\nif droid.checkScreenOn().result:\n    print(\"Screen is on\")\n\n# \u97f3\u91cf\u63a7\u5236\nmedia_vol = droid.getMediaVolume().result\nprint(f\"Media volume: {media_vol}\")\ndroid.setMediaVolume(10)\n\n# \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\nif droid.checkAirplaneMode().result:\n    print(\"Airplane mode is on\")\n
        "},{"location":"qsl4a/system/sysinfo/","title":"\u7cfb\u7edf\u4fe1\u606f","text":"

        \u68c0\u7d22\u8bbe\u5907\u548c\u7cfb\u7edf\u4fe1\u606f\u3002

        "},{"location":"qsl4a/system/sysinfo/#_2","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/sysinfo/#getandroidid","title":"getAndroidID()","text":"

        \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

        getAndroidID()\n

        \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

        "},{"location":"qsl4a/system/sysinfo/#getsysinfo","title":"getSysInfo()","text":"

        \u83b7\u53d6\u7efc\u5408\u7cfb\u7edf\u4fe1\u606f\u3002

        getSysInfo()\n

        \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

        "},{"location":"qsl4a/system/sysinfo/#getlocale","title":"getLocale()","text":"

        \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u8bbe\u7f6e\u3002

        getLocale()\n

        \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

        "},{"location":"qsl4a/system/sysinfo/#_3","title":"\u5185\u5b58","text":""},{"location":"qsl4a/system/sysinfo/#getmemoryinfo","title":"getMemoryInfo()","text":"

        \u83b7\u53d6 RAM \u4fe1\u606f\u3002

        getMemoryInfo()\n

        \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

        "},{"location":"qsl4a/system/sysinfo/#_4","title":"\u663e\u793a","text":""},{"location":"qsl4a/system/sysinfo/#getscreeninfo","title":"getScreenInfo()","text":"

        \u83b7\u53d6\u663e\u793a\u4fe1\u606f\u3002

        getScreenInfo()\n

        \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

        "},{"location":"qsl4a/system/sysinfo/#_5","title":"\u6807\u8bc6\u7b26","text":""},{"location":"qsl4a/system/sysinfo/#getimei","title":"getImei()","text":"

        \u83b7\u53d6\u8bbe\u5907 IMEI\u3002

        getImei(slotIndex=None)\n
        "},{"location":"qsl4a/system/sysinfo/#getmeid","title":"getMeid()","text":"

        \u83b7\u53d6\u8bbe\u5907 MEID\u3002

        getMeid(slotIndex=None)\n
        "},{"location":"qsl4a/system/sysinfo/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u8bbe\u5907 ID\nandroid_id = droid.getAndroidID().result\nprint(f\"Android ID: {android_id}\")\n\n# \u5c4f\u5e55\u4fe1\u606f\nscreen = droid.getScreenInfo().result\nprint(f\"Screen: {screen['width']}x{screen['height']}\")\n\n# \u5185\u5b58\nmemory = droid.getMemoryInfo().result\nprint(f\"Memory: {memory}\")\n
        "},{"location":"qsl4a/system/wakelock/","title":"WakeLock API","text":"

        \u63a7\u5236\u8bbe\u5907\u5524\u9192\u9501\u4ee5\u4fdd\u6301 CPU \u6216\u5c4f\u5e55\u5f00\u542f\u3002

        "},{"location":"qsl4a/system/wakelock/#wake-lock","title":"Wake Lock \u7c7b\u578b","text":"

        QSL4A \u63d0\u4f9b\u4e0d\u540c\u7c7b\u578b\u7684\u5524\u9192\u9501\uff1a

        \u7c7b\u578b \u63cf\u8ff0 Full CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae Partial \u4ec5 CPU \u5f00\u542f Bright CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae Dim CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697"},{"location":"qsl4a/system/wakelock/#wake-lock_1","title":"Wake Lock \u65b9\u6cd5","text":""},{"location":"qsl4a/system/wakelock/#wakelockacquirefull","title":"wakeLockAcquireFull()","text":"

        \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae\uff09\u3002

        wakeLockAcquireFull()\n
        "},{"location":"qsl4a/system/wakelock/#wakelockacquirepartial","title":"wakeLockAcquirePartial()","text":"

        \u83b7\u53d6\u90e8\u5206\u5524\u9192\u9501\uff08\u4ec5 CPU \u5f00\u542f\uff09\u3002

        wakeLockAcquirePartial()\n
        "},{"location":"qsl4a/system/wakelock/#wakelockacquirebright","title":"wakeLockAcquireBright()","text":"

        \u83b7\u53d6\u660e\u4eae\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff09\u3002

        wakeLockAcquireBright()\n
        "},{"location":"qsl4a/system/wakelock/#wakelockacquiredim","title":"wakeLockAcquireDim()","text":"

        \u83b7\u53d6\u6697\u6de1\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697\uff09\u3002

        wakeLockAcquireDim()\n
        "},{"location":"qsl4a/system/wakelock/#wakelockrelease","title":"wakeLockRelease()","text":"

        \u91ca\u653e\u5524\u9192\u9501\u3002

        wakeLockRelease()\n
        "},{"location":"qsl4a/system/wakelock/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\ndroid.wakeLockAcquireFull()\n\n# \u5728\u4fdd\u6301\u5c4f\u5e55\u5f00\u542f\u65f6\u6267\u884c\u91cd\u8981\u5de5\u4f5c\nprint(\"Screen will stay on\")\ntime.sleep(10)\n\n# \u5b8c\u6210\u540e\u91ca\u653e\ndroid.wakeLockRelease()\n\n# \u6216\u4f7f\u7528\u90e8\u5206\u9501\u8fdb\u884c\u540e\u53f0\u4efb\u52a1\ndroid.wakeLockAcquirePartial()\n# \u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\uff0cCPU \u4ecd\u4fdd\u6301\u5f00\u542f\ntime.sleep(30)\ndroid.wakeLockRelease()\n

        \u6ce8\u610f\uff1a \u8bb0\u4f4f\u5728\u4e0d\u9700\u8981\u65f6\u91ca\u653e\u5524\u9192\u9501\u4ee5\u8282\u7701\u7535\u6c60\u3002

        "},{"location":"qsl4a/ui/accessibility/","title":"\u65e0\u969c\u788d\u670d\u52a1","text":"

        \u65e0\u969c\u788d\u670d\u52a1\u5141\u8bb8\u81ea\u52a8\u5316 UI \u4ea4\u4e92\uff0c\u5982\u70b9\u51fb\u3001\u6ed1\u52a8\u548c\u7cfb\u7edf\u64cd\u4f5c\u3002

        "},{"location":"qsl4a/ui/accessibility/#_2","title":"\u670d\u52a1\u63a7\u5236","text":""},{"location":"qsl4a/ui/accessibility/#accessibilitystartservice","title":"accessibilityStartService()","text":"

        \u542f\u52a8\u65e0\u969c\u788d\u670d\u52a1\u3002

        accessibilityStartService()\n

        \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

        "},{"location":"qsl4a/ui/accessibility/#accessibilityserviceenabled","title":"accessibilityServiceEnabled()","text":"

        \u68c0\u67e5\u65e0\u969c\u788d\u670d\u52a1\u662f\u5426\u5df2\u542f\u7528\u3002

        accessibilityServiceEnabled()\n

        \u8fd4\u56de\uff1a True \u6216 False

        "},{"location":"qsl4a/ui/accessibility/#_3","title":"\u5c4f\u5e55\u4ea4\u4e92","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityclick","title":"accessibilityClick()","text":"

        \u5728\u5c4f\u5e55\u5750\u6807\u5904\u70b9\u51fb\u3002

        accessibilityClick(x=0, y=0, t=50)\n

        \u53c2\u6570\uff1a - x (int/float): X \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - y (int/float): Y \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - t (int): \u6309\u4f4f\u65f6\u957f\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a50\uff09

        "},{"location":"qsl4a/ui/accessibility/#accessibilityslide","title":"accessibilitySlide()","text":"

        \u591a\u70b9\u6ed1\u52a8\u624b\u52bf\u3002

        accessibilitySlide(XnYn=None, t=None)\n

        \u53c2\u6570\uff1a - XnYn (list): \u5750\u6807 [X1, Y1, X2, Y2, ... Xn, Yn] - t (int): \u6ed1\u52a8\u65f6\u957f\uff08\u9ed8\u8ba4\uff1a50*n \u6beb\u79d2\uff09

        "},{"location":"qsl4a/ui/accessibility/#_4","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityaction","title":"accessibilityAction()","text":"

        \u6309\u4ee3\u7801\u6267\u884c\u7cfb\u7edf\u64cd\u4f5c\u3002

        accessibilityAction(actionCode)\n

        \u64cd\u4f5c\u4ee3\u7801\uff1a | \u4ee3\u7801 | \u5e38\u91cf | \u63cf\u8ff0 | |------|----------|-------------| | 1 | BACK | \u8fd4\u56de\u6309\u94ae | | 2 | HOME | \u4e3b\u5c4f\u5e55\u6309\u94ae | | 3 | RECENTS | \u6700\u8fd1\u5e94\u7528 | | 4 | NOTIFICATIONS | \u6253\u5f00\u901a\u77e5 | | 5 | QUICK_SETTINGS | \u6253\u5f00\u5feb\u901f\u8bbe\u7f6e | | 6 | POWER_DIALOG | \u7535\u6e90\u83dc\u5355 | | 7 | TOGGLE_SPLIT_SCREEN | \u5206\u5c4f | | 8 | LOCK_SCREEN | \u9501\u5c4f | | 9 | TAKE_SCREENSHOT | \u622a\u56fe | | 10 | KEYCODE_HEADSETHOOK | \u8033\u673a\u6302\u94a9 | | 11-14 | ACCESSIBILITY_ | \u65e0\u969c\u788d\u6309\u94ae | | 15 | DISMISS_NOTIFICATION_SHADE | \u5173\u95ed\u901a\u77e5\u680f | | 16-20 | DPAD_ | \u65b9\u5411\u952e | | 21 | MENU | \u83dc\u5355\u6309\u94ae | | 22 | MEDIA_PLAY_PAUSE | \u64ad\u653e/\u6682\u505c\u5a92\u4f53 |

        "},{"location":"qsl4a/ui/accessibility/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/accessibility/#_6","title":"\u70b9\u51fb\u5c4f\u5e55\u4e2d\u5fc3","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u670d\u52a1\nif not droid.accessibilityServiceEnabled().result:\n    droid.accessibilityStartService()\n\n# \u70b9\u51fb\u4e2d\u5fc3\uff080,0 = \u4e2d\u5fc3\uff09\ndroid.accessibilityClick(0, 0, t=100)\n
        "},{"location":"qsl4a/ui/accessibility/#_7","title":"\u6ed1\u52a8\u624b\u52bf","text":"
        # \u4ece\u4e0b\u5f80\u4e0a\u6ed1\u52a8\uff08\u5411\u4e0a\u6eda\u52a8\uff09\ndroid.accessibilitySlide([0, 1.5, 0, -1.5], t=300)\n
        "},{"location":"qsl4a/ui/accessibility/#_8","title":"\u7cfb\u7edf\u5bfc\u822a","text":"
        # \u6309\u4e3b\u5c4f\u5e55\ndroid.accessibilityAction(2)\n\n# \u6309\u8fd4\u56de\ndroid.accessibilityAction(1)\n\n# \u6253\u5f00\u901a\u77e5\ndroid.accessibilityAction(4)\n
        "},{"location":"qsl4a/ui/accessibility/#_9","title":"\u70b9\u51fb\u7279\u5b9a\u4f4d\u7f6e","text":"
        # \u70b9\u51fb\u5c4f\u5e55\u5750\u6807 (500, 800)\ndroid.accessibilityClick(500, 800)\n\n# \u70b9\u51fb\u76f8\u5bf9\u4f4d\u7f6e\uff08\u6c34\u5e73\u5c45\u4e2d\uff0c\u5782\u76f4 3/4 \u5904\uff09\ndroid.accessibilityClick(0, 1.5)\n
        "},{"location":"qsl4a/ui/dialogs/","title":"\u5bf9\u8bdd\u6846\u7cfb\u7edf","text":"

        QSL4A \u63d0\u4f9b\u5168\u9762\u7684\u5bf9\u8bdd\u6846\u652f\u6301\uff0c\u7528\u4e8e\u7528\u6237\u4ea4\u4e92\uff0c\u5305\u62ec\u8b66\u62a5\u3001\u8f93\u5165\u5bf9\u8bdd\u6846\u3001\u9009\u62e9\u5bf9\u8bdd\u6846\u548c\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

        "},{"location":"qsl4a/ui/dialogs/#_2","title":"\u8b66\u62a5\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowalert","title":"dialogShowAlert()","text":"

        \u663e\u793a\u7b80\u5355\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

        dialogShowAlert(title=\"Alert\", message=\"The message of the alert.\",\n                positiveButtonText=\"OK\", negativeButtonText=None,\n                neutralButtonText=None, messageIsHtml=False)\n

        \u53c2\u6570\uff1a - title (str): \u5bf9\u8bdd\u6846\u6807\u9898 - message (str): \u6d88\u606f\u6587\u672c - positiveButtonText (str): \u80af\u5b9a\u6309\u94ae\u6807\u7b7e - negativeButtonText (str, optional): \u5426\u5b9a\u6309\u94ae\u6807\u7b7e - neutralButtonText (str, optional): \u4e2d\u6027\u6309\u94ae\u6807\u7b7e - messageIsHtml (bool): \u5c06\u6d88\u606f\u89e3\u6790\u4e3a HTML

        \u8fd4\u56de\uff1a \u5305\u542b\u70b9\u51fb\u6309\u94ae\u7684\u7ed3\u679c

        "},{"location":"qsl4a/ui/dialogs/#dialogshowsimplechoice","title":"dialogShowSimpleChoice()","text":"

        \u663e\u793a\u5e26\u6709\u9879\u76ee\u7684\u7b80\u5355\u9009\u62e9\u5bf9\u8bdd\u6846\u3002

        dialogShowSimpleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

        \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868

        \u8fd4\u56de\uff1a \u5305\u542b\u9009\u4e2d\u9879\u76ee\u7684\u7ed3\u679c

        "},{"location":"qsl4a/ui/dialogs/#_3","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialoggetinput","title":"dialogGetInput()","text":"

        \u83b7\u53d6\u7528\u6237\u6587\u672c\u8f93\u5165\u3002

        dialogGetInput(title=\"Value\", message=\"Please enter value:\",\n               defaultText=None, messageIsHtml=False)\n

        \u8fd4\u56de\uff1a \u5305\u542b\u7528\u6237\u8f93\u5165\u6587\u672c\u7684\u7ed3\u679c

        "},{"location":"qsl4a/ui/dialogs/#dialoggetpassword","title":"dialogGetPassword()","text":"

        \u83b7\u53d6\u5bc6\u7801\u8f93\u5165\u3002

        dialogGetPassword(title=\"Password\", message=\"Please enter password:\")\n

        \u8fd4\u56de\uff1a \u5305\u542b\u8f93\u5165\u5bc6\u7801\u7684\u7ed3\u679c

        "},{"location":"qsl4a/ui/dialogs/#dialogcreateinput","title":"dialogCreateInput()","text":"

        \u521b\u5efa\u81ea\u5b9a\u4e49\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

        dialogCreateInput(title=\"Value\", message=\"Please enter value:\",\n                  defaultText=None, inputType=None)\n

        \u53c2\u6570\uff1a - inputType (str): \u8f93\u5165\u7c7b\u578b\uff08\u4f8b\u5982 \"text\"\u3001\"number\"\u3001\"textPassword\"\uff09

        "},{"location":"qsl4a/ui/dialogs/#dialogcreatepassword","title":"dialogCreatePassword()","text":"

        \u521b\u5efa\u5bc6\u7801\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

        dialogCreatePassword(title=\"Password\", message=\"Please enter password:\")\n
        "},{"location":"qsl4a/ui/dialogs/#dialogcreateseekbar","title":"dialogCreateSeekBar()","text":"

        \u521b\u5efa\u6ed1\u5757/\u8fdb\u5ea6\u6761\u5bf9\u8bdd\u6846\u3002

        dialogCreateSeekBar(starting_value=50, maximum_value=100, title=\"\", message=\"\")\n

        \u53c2\u6570\uff1a - starting_value (int): \u521d\u59cb\u503c - maximum_value (int): \u6700\u5927\u503c

        "},{"location":"qsl4a/ui/dialogs/#_4","title":"\u9009\u62e9\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowsinglechoice","title":"dialogShowSingleChoice()","text":"

        \u663e\u793a\u5355\u9009\uff08\u5355\u9009\u6309\u94ae\uff09\u5bf9\u8bdd\u6846\u3002

        dialogShowSingleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, selected=-1, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

        \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (int): \u9ed8\u8ba4\u9009\u4e2d\u7d22\u5f15

        "},{"location":"qsl4a/ui/dialogs/#dialogshowmultichoice","title":"dialogShowMultiChoice()","text":"

        \u663e\u793a\u591a\u9009\uff08\u590d\u9009\u6846\uff09\u5bf9\u8bdd\u6846\u3002

        dialogShowMultiChoice(title=\"Alert\", message=\"The message of the alert.\",\n                      items=None, selected=None, positiveButtonText=\"OK\",\n                      negativeButtonText=None, neutralButtonText=None,\n                      messageIsHtml=False)\n

        \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (list): \u521d\u59cb\u9009\u4e2d\u7d22\u5f15\u5217\u8868

        "},{"location":"qsl4a/ui/dialogs/#dialogsetsinglechoiceitems","title":"dialogSetSingleChoiceItems()","text":"

        \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u5355\u9009\u9879\u76ee\u3002

        dialogSetSingleChoiceItems(items, selected=-1)\n
        "},{"location":"qsl4a/ui/dialogs/#dialogsetmultichoiceitems","title":"dialogSetMultiChoiceItems()","text":"

        \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u591a\u9009\u9879\u76ee\u3002

        dialogSetMultiChoiceItems(items, selected=None)\n
        "},{"location":"qsl4a/ui/dialogs/#_5","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatespinnerprogress","title":"dialogCreateSpinnerProgress()","text":"

        \u521b\u5efa\u4e0d\u786e\u5b9a\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

        dialogCreateSpinnerProgress(title=None, message=None, maximum_progress=100)\n
        "},{"location":"qsl4a/ui/dialogs/#dialogcreatehorizontalprogress","title":"dialogCreateHorizontalProgress()","text":"

        \u521b\u5efa\u6c34\u5e73\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

        dialogCreateHorizontalProgress(title=None, message=None, maximum_progress=100)\n
        "},{"location":"qsl4a/ui/dialogs/#dialogsetcurrentprogress","title":"dialogSetCurrentProgress()","text":"

        \u66f4\u65b0\u8fdb\u5ea6\u503c\u3002

        dialogSetCurrentProgress(current)\n
        "},{"location":"qsl4a/ui/dialogs/#dialogsetmaxprogress","title":"dialogSetMaxProgress()","text":"

        \u8bbe\u7f6e\u6700\u5927\u8fdb\u5ea6\u503c\u3002

        dialogSetMaxProgress(max)\n
        "},{"location":"qsl4a/ui/dialogs/#dialogsetprogressmessage","title":"dialogSetProgressMessage()","text":"

        \u66f4\u65b0\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u6d88\u606f\u3002

        dialogSetProgressMessage(message)\n
        "},{"location":"qsl4a/ui/dialogs/#_6","title":"\u9009\u62e9\u5668\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatedatepicker","title":"dialogCreateDatePicker()","text":"

        \u521b\u5efa\u65e5\u671f\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

        dialogCreateDatePicker(year=1970, month=1, day=1)\n
        "},{"location":"qsl4a/ui/dialogs/#dialogcreatetimepicker","title":"dialogCreateTimePicker()","text":"

        \u521b\u5efa\u65f6\u95f4\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

        dialogCreateTimePicker(hour=0, minute=0, is24hour=False)\n
        "},{"location":"qsl4a/ui/dialogs/#_7","title":"\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u521b\u5efa","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatealert","title":"dialogCreateAlert()","text":"

        \u521b\u5efa\u81ea\u5b9a\u4e49\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

        dialogCreateAlert(title=None, message=None)\n

        \u521b\u5efa\u4e00\u4e2a\u7a7a\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002\u53ef\u4e0e\u5176\u4ed6 dialogSet* \u51fd\u6570\u4e00\u8d77\u4f7f\u7528\u6765\u81ea\u5b9a\u4e49\u3002

        "},{"location":"qsl4a/ui/dialogs/#dialogsetitems","title":"dialogSetItems()","text":"

        \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u7b80\u5355\u5217\u8868\u9879\u76ee\u3002

        dialogSetItems(items)\n
        "},{"location":"qsl4a/ui/dialogs/#dialogsetpositivebuttontext","title":"dialogSetPositiveButtonText()","text":"

        \u8bbe\u7f6e\u80af\u5b9a\u6309\u94ae\u6587\u672c\u3002

        dialogSetPositiveButtonText(text)\n
        "},{"location":"qsl4a/ui/dialogs/#dialogsetnegativebuttontext","title":"dialogSetNegativeButtonText()","text":"

        \u8bbe\u7f6e\u5426\u5b9a\u6309\u94ae\u6587\u672c\u3002

        dialogSetNegativeButtonText(text)\n
        "},{"location":"qsl4a/ui/dialogs/#dialogsetneutralbuttontext","title":"dialogSetNeutralButtonText()","text":"

        \u8bbe\u7f6e\u4e2d\u6027\u6309\u94ae\u6587\u672c\u3002

        dialogSetNeutralButtonText(text)\n
        "},{"location":"qsl4a/ui/dialogs/#dialogsetmessageishtml","title":"dialogSetMessageIsHtml()","text":"

        \u8bbe\u7f6e\u6d88\u606f\u662f\u5426\u5e94\u89e3\u6790\u4e3a HTML\u3002

        dialogSetMessageIsHtml(messageIsHtml=True)\n
        "},{"location":"qsl4a/ui/dialogs/#dialogshow","title":"dialogShow()","text":"

        \u663e\u793a\u521b\u5efa\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u3002

        dialogShow()\n
        "},{"location":"qsl4a/ui/dialogs/#_8","title":"\u5bf9\u8bdd\u6846\u63a7\u5236","text":""},{"location":"qsl4a/ui/dialogs/#dialogdismiss","title":"dialogDismiss()","text":"

        \u5173\u95ed\u5f53\u524d\u5bf9\u8bdd\u6846\u3002

        dialogDismiss()\n
        "},{"location":"qsl4a/ui/dialogs/#dialoggetresponse","title":"dialogGetResponse()","text":"

        \u83b7\u53d6\u5bf9\u8bdd\u6846\u54cd\u5e94\u3002

        dialogGetResponse()\n
        "},{"location":"qsl4a/ui/dialogs/#dialoggetselecteditems","title":"dialogGetSelectedItems()","text":"

        \u4ece\u9009\u62e9\u5bf9\u8bdd\u6846\u83b7\u53d6\u9009\u4e2d\u7684\u9879\u76ee\u3002

        dialogGetSelectedItems()\n
        "},{"location":"qsl4a/ui/dialogs/#_9","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/dialogs/#_10","title":"\u7b80\u5355\u8b66\u62a5","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a\u8b66\u62a5\ndroid.dialogShowAlert(\"Warning\", \"This is an important message!\")\n
        "},{"location":"qsl4a/ui/dialogs/#_11","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":"
        # \u83b7\u53d6\u7528\u6237\u8f93\u5165\nresult = droid.dialogGetInput(\"Name\", \"Enter your name:\", \"John\").result\nprint(f\"Hello, {result}!\")\n
        "},{"location":"qsl4a/ui/dialogs/#_12","title":"\u5e26\u6309\u94ae\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846","text":"
        # \u521b\u5efa\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\ndroid.dialogCreateAlert(\"Custom\", \"Choose an option\")\ndroid.dialogSetItems([\"Option 1\", \"Option 2\", \"Option 3\"])\ndroid.dialogShow()\n\n# \u83b7\u53d6\u54cd\u5e94\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response['item']}\")\n
        "},{"location":"qsl4a/ui/dialogs/#_13","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":"
        # \u521b\u5efa\u8fdb\u5ea6\u5bf9\u8bdd\u6846\ndroid.dialogCreateHorizontalProgress(\"Loading\", \"Please wait...\", 100)\ndroid.dialogShow()\n\n# \u66f4\u65b0\u8fdb\u5ea6\nfor i in range(101):\n    droid.dialogSetCurrentProgress(i)\n    time.sleep(0.05)\n\ndroid.dialogDismiss()\n
        "},{"location":"qsl4a/ui/dialogs/#_14","title":"\u65e5\u671f\u9009\u62e9\u5668","text":"
        # \u663e\u793a\u65e5\u671f\u9009\u62e9\u5668\ndroid.dialogCreateDatePicker(2024, 1, 15)\ndroid.dialogShow()\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response}\")\n
        "},{"location":"qsl4a/ui/floatview/","title":"\u6d6e\u52a8\u89c6\u56fe","text":"

        \u6d6e\u52a8\u7a97\u53e3\u652f\u6301\uff0c\u7528\u4e8e\u5728\u5176\u4ed6\u5e94\u7528\u7a0b\u5e8f\u4e0a\u65b9\u4fdd\u6301\u663e\u793a\u7684\u8986\u76d6 UI \u5143\u7d20\u3002

        "},{"location":"qsl4a/ui/floatview/#_2","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/floatview/#floatview","title":"floatView()","text":"

        \u663e\u793a\u6216\u4fee\u6539\u6d6e\u52a8\u89c6\u56fe\u3002

        floatView(Args=None)\n

        \u53c2\u6570\uff1a - Args (dict): \u914d\u7f6e\u5b57\u5178\uff0c\u5305\u542b\u4ee5\u4e0b\u952e\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08-1 \u521b\u5efa\u65b0\u7684\uff0c>=0 \u4fee\u6539\u73b0\u6709\u7684\uff09 - text (str): \u8981\u663e\u793a\u7684\u6587\u672c\u5185\u5bb9 - html (str): HTML \u5185\u5bb9\uff08\u5982\u679c\u7701\u7565 text \u5219\u4f7f\u7528\uff09 - width (int): \u89c6\u56fe\u5bbd\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a300\uff09 - height (int): \u89c6\u56fe\u9ad8\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a150\uff09 - x (int): X \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - y (int): Y \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - backColor (str): ARGB \u5341\u516d\u8fdb\u5236\u80cc\u666f\u8272\uff08\u9ed8\u8ba4\uff1a'7f7f7f7f'\uff09 - textColor (str): ARGB \u5341\u516d\u8fdb\u5236\u6587\u672c\u8272\uff08\u9ed8\u8ba4\uff1a'ff000000'\uff09 - textSize (int): \u6587\u672c\u5927\u5c0f\uff08\u9ed8\u8ba4\uff1a10\uff09 - textAlign (int): \u6587\u672c\u5bf9\u9f50\uff080 = \u7ee7\u627f\uff09 - script (str): \u957f\u6309\u5173\u95ed\u540e\u8fd0\u884c\u7684\u811a\u672c\u8def\u5f84 - arg: \u811a\u672c\u53c2\u6570 - clickRemove (bool): \u542f\u7528\u70b9\u51fb\u79fb\u9664\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - flag (int): \u7a97\u53e3\u6807\u5fd7\uff08\u9ed8\u8ba4\uff1a40 - \u53ef\u89e6\u6478\uff09

        \u8fd4\u56de\uff1a \u5f53\u524d\u94fe\u5217\u8868\u957f\u5ea6

        "},{"location":"qsl4a/ui/floatview/#floatviewcount","title":"floatViewCount()","text":"

        \u83b7\u53d6\u6d3b\u52a8\u6d6e\u52a8\u89c6\u56fe\u7684\u6570\u91cf\u3002

        floatViewCount()\n

        \u8fd4\u56de\uff1a \u6d6e\u52a8\u89c6\u56fe\u6570\u91cf

        "},{"location":"qsl4a/ui/floatview/#floatviewresult","title":"floatViewResult()","text":"

        \u83b7\u53d6\u6d6e\u52a8\u89c6\u56fe\u7684\u7ed3\u679c/\u72b6\u6001\u3002

        floatViewResult(index=-1)\n

        \u53c2\u6570\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1\uff0c\u8fd4\u56de\u6700\u540e\u64cd\u4f5c\u7ed3\u679c\uff09

        \u8fd4\u56de\uff1a \u5305\u542b\u64cd\u4f5c\u8be6\u60c5\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - x, y: \u4f4d\u7f6e - time: \u65f6\u95f4\u6233 - operation: \u64cd\u4f5c\u7c7b\u578b\uff08'initial'\u3001'move' \u7b49\uff09 - index: \u89c6\u56fe\u7d22\u5f15 - removed: \u5982\u679c\u89c6\u56fe\u88ab\u79fb\u9664\u5219\u4e3a True

        "},{"location":"qsl4a/ui/floatview/#floatviewremove","title":"floatViewRemove()","text":"

        \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\u3002

        floatViewRemove(index=-1)\n

        \u53c2\u6570\uff1a - index (int): \u8981\u79fb\u9664\u7684\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1 \u79fb\u9664\u6700\u540e\u4e00\u4e2a\uff09

        \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a 1\uff0c\u5426\u5219\u4e3a 0

        "},{"location":"qsl4a/ui/floatview/#_3","title":"\u5e38\u91cf","text":"
        • floatView.INDEX_NEW = -1 - \u521b\u5efa\u65b0\u7684\u6d6e\u52a8\u89c6\u56fe
        • floatView.FLAG_DEFAULT_TOUCHABLE = 40 - \u9ed8\u8ba4\u53ef\u89e6\u6478\u6807\u5fd7
        • floatView.TEXT_ALIGNMENT_INHERIT = 0
        • floatView.TEXT_ALIGNMENT_CENTER - \u5c45\u4e2d\u6587\u672c\u5bf9\u9f50
        "},{"location":"qsl4a/ui/floatview/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/floatview/#_5","title":"\u57fa\u672c\u6d6e\u52a8\u89c6\u56fe","text":"
        import androidhelper\nfrom androidhelper import Android\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u7b80\u5355\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'index': -1,  # \u521b\u5efa\u65b0\u7684\n    'text': 'Hello World',\n    'width': 400,\n    'height': 300,\n    'x': -300,  # \u4ece\u4e2d\u5fc3\u504f\u79fb\n    'y': -400,\n    'backColor': 'ff0000',  # \u7ea2\u8272\u80cc\u666f\n    'textColor': '0000ff',  # \u84dd\u8272\u6587\u672c\n    'textSize': 16,\n    'textAlign': droid.floatView.TEXT_ALIGNMENT_CENTER\n})\n\n# \u68c0\u67e5\u6570\u91cf\nprint(f\"Float views: {droid.floatViewCount().result}\")\n\n# \u83b7\u53d6\u7ed3\u679c\nresult = droid.floatViewResult().result\nprint(f\"View info: {result}\")\n\n# \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\ndroid.floatViewRemove(0)\n
        "},{"location":"qsl4a/ui/floatview/#html","title":"HTML \u5185\u5bb9","text":"
        # \u521b\u5efa\u5e26 HTML \u5185\u5bb9\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': '',  # \u7a7a\u6587\u672c\u4ee5\u4f7f\u7528 HTML\n    'html': '<h1>Title</h1><p>Rich <b>HTML</b> content</p>',\n    'width': 500,\n    'height': 400\n})\n
        "},{"location":"qsl4a/ui/floatview/#_6","title":"\u4fee\u6539\u73b0\u6709\u89c6\u56fe","text":"
        # \u521b\u5efa\u521d\u59cb\u89c6\u56fe\ndroid.floatView({'text': 'Initial Text', 'width': 300, 'height': 150})\n\n# \u4fee\u6539\u540c\u4e00\u89c6\u56fe\uff08\u7d22\u5f15 0\uff09\ndroid.floatView({\n    'index': 0,\n    'text': 'Updated Text!',\n    'backColor': '7f00ff00'  # \u7eff\u8272\u80cc\u666f\n})\n\n# \u68c0\u67e5\u79fb\u52a8/\u66f4\u6539\u7ed3\u679c\nresult = droid.floatViewResult(0).result\nprint(f\"Operation: {result.get('operation')}, Position: ({result.get('x')}, {result.get('y')})\")\n
        "},{"location":"qsl4a/ui/floatview/#_7","title":"\u591a\u4e2a\u6d6e\u52a8\u89c6\u56fe","text":"
        # \u521b\u5efa\u591a\u4e2a\u89c6\u56fe\nfor i in range(3):\n    droid.floatView({\n        'index': -1,\n        'text': f'View {i}',\n        'x': i * 100 - 150,\n        'y': i * 100 - 150,\n        'backColor': f'{i}f{i}f{i}f'\n    })\n\nprint(f\"Total views: {droid.floatViewCount().result}\")\n\n# \u79fb\u9664\u6240\u6709\u89c6\u56fe\nwhile droid.floatViewCount().result > 0:\n    droid.floatViewRemove()\n
        "},{"location":"qsl4a/ui/floatview/#_8","title":"\u5e26\u811a\u672c\u56de\u8c03","text":"
        # \u521b\u5efa\u5173\u95ed\u65f6\u8fd0\u884c\u811a\u672c\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': 'Click to close and run script',\n    'script': '/sdcard/my_script.py',\n    'arg': 'hello from float view',\n    'clickRemove': True\n})\n
        "},{"location":"qsl4a/ui/fullscreen/","title":"\u5168\u5c4f UI","text":"

        \u4f7f\u7528\u539f\u751f Android \u5e03\u5c40\u521b\u5efa\u81ea\u5b9a\u4e49\u5168\u5c4f\u754c\u9762\u3002

        "},{"location":"qsl4a/ui/fullscreen/#_1","title":"\u5e03\u5c40\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullshow","title":"fullShow()","text":"

        \u663e\u793a\u5168\u5c4f\u5e03\u5c40\u3002

        fullShow(layout, title=None, theme=None)\n

        \u53c2\u6570\uff1a - layout (str): JSON \u5e03\u5c40\u5b9a\u4e49\u6216\u5e03\u5c40\u5b57\u7b26\u4e32 - title (str, optional): \u7a97\u53e3\u6807\u9898 - theme (str, optional): \u4e3b\u9898\u540d\u79f0

        \u8fd4\u56de\uff1a \u7a97\u53e3 ID

        "},{"location":"qsl4a/ui/fullscreen/#fulldismiss","title":"fullDismiss()","text":"

        \u5173\u95ed\u5168\u5c4f\u7a97\u53e3\u3002

        fullDismiss()\n
        "},{"location":"qsl4a/ui/fullscreen/#fullquery","title":"fullQuery()","text":"

        \u67e5\u8be2\u6240\u6709\u5c0f\u90e8\u4ef6\u503c\u3002

        fullQuery()\n

        \u8fd4\u56de\uff1a \u5c0f\u90e8\u4ef6 ID \u548c\u503c\u7684\u5b57\u5178

        "},{"location":"qsl4a/ui/fullscreen/#fullquerydetail","title":"fullQueryDetail()","text":"

        \u67e5\u8be2\u7279\u5b9a\u5c0f\u90e8\u4ef6\u8be6\u60c5\u3002

        fullQueryDetail(id)\n
        "},{"location":"qsl4a/ui/fullscreen/#_2","title":"\u5c5e\u6027\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperty","title":"fullGetProperty()","text":"

        \u83b7\u53d6\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

        fullGetProperty(id, property)\n
        "},{"location":"qsl4a/ui/fullscreen/#fullsetproperty","title":"fullSetProperty()","text":"

        \u8bbe\u7f6e\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

        fullSetProperty(id, property, value)\n
        "},{"location":"qsl4a/ui/fullscreen/#fullsetlist","title":"fullSetList()","text":"

        \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

        fullSetList(id, list, isHtml=False, listType=0)\n
        "},{"location":"qsl4a/ui/fullscreen/#fullsetlist2","title":"fullSetList2()","text":"

        \u4f7f\u7528\u8d44\u6e90 ID \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

        fullSetList2(id, list, intRes)\n

        \u53c2\u6570\uff1a - id (str): \u5c0f\u90e8\u4ef6 ID - list (list): \u9879\u76ee\u5217\u8868 - intRes (int): \u5217\u8868\u9879\u76ee\u5e03\u5c40\u7684 Android \u8d44\u6e90 ID

        "},{"location":"qsl4a/ui/fullscreen/#fullsetlistselected","title":"fullSetListSelected()","text":"

        \u5728\u5217\u8868\u4e2d\u8bbe\u7f6e\u9009\u4e2d\u9879\u76ee\u3002

        fullSetListSelected(id, selected)\n

        \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID - selected (int): \u8981\u9009\u4e2d\u7684\u9879\u76ee\u7d22\u5f15

        "},{"location":"qsl4a/ui/fullscreen/#fullgetlistselected","title":"fullGetListSelected()","text":"

        \u83b7\u53d6\u5f53\u524d\u9009\u4e2d\u7684\u5217\u8868\u9879\u76ee\u7d22\u5f15\u3002

        fullGetListSelected(id)\n

        \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID

        \u8fd4\u56de\uff1a \u9009\u4e2d\u9879\u76ee\u7d22\u5f15

        "},{"location":"qsl4a/ui/fullscreen/#_3","title":"\u6279\u91cf\u5c5e\u6027\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperties","title":"fullGetProperties()","text":"

        \u4e00\u6b21\u83b7\u53d6\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

        fullGetProperties(ids, property)\n

        \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u83b7\u53d6\u7684\u5c5e\u6027\u540d

        \u8fd4\u56de\uff1a \u6620\u5c04\u5c0f\u90e8\u4ef6 ID \u5230\u5c5e\u6027\u503c\u7684\u5b57\u5178

        "},{"location":"qsl4a/ui/fullscreen/#fullsetproperties","title":"fullSetProperties()","text":"

        \u4e00\u6b21\u8bbe\u7f6e\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

        fullSetProperties(ids, property, value)\n

        \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u8bbe\u7f6e\u7684\u5c5e\u6027\u540d - value: \u5c5e\u6027\u503c

        "},{"location":"qsl4a/ui/fullscreen/#_4","title":"\u622a\u56fe","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetscreenshot","title":"fullGetScreenShot()","text":"

        \u6355\u83b7\u5168\u5c4f\u622a\u56fe\u3002

        fullGetScreenShot(path=None)\n

        \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u5728\u4e8b\u4ef6\u4e2d\u8fd4\u56de

        \u8fd4\u56de\uff1a \u5305\u542b\u622a\u56fe\u6570\u636e\u7684\u4e8b\u4ef6

        "},{"location":"qsl4a/ui/fullscreen/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b9a\u4e49\u5e03\u5c40\nlayout = '''\n{ \"type\": \"LinearLayout\", \"orientation\": \"vertical\",\n  \"children\": [\n    { \"type\": \"TextView\", \"id\": \"title\", \"text\": \"Hello\" },\n    { \"type\": \"Button\", \"id\": \"btn\", \"text\": \"Click Me\" }\n  ]\n}\n'''\n\n# \u663e\u793a\u5e03\u5c40\ndroid.fullShow(layout, \"My App\")\n\n# \u67e5\u8be2\u6309\u94ae\u70b9\u51fb\nevent = droid.eventWaitFor('click', timeout=10)\nif event.result:\n    widget_id = event.result['data']['id']\n    if widget_id == 'btn':\n        print(\"Button clicked!\")\n\ndroid.fullDismiss()\n
        "}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"QPython \u9879\u76ee","text":"

        QPython \u4e0d\u4ec5\u662f\u4e00\u4e2a\u5f3a\u5927\u7684 Android Python IDE\uff0c\u4e5f\u662f\u4e00\u4e2a\u6d3b\u8dc3\u7684\u6280\u672f\u793e\u533a\u3002

        "},{"location":"#ai-android-python-ide","title":"\u652f\u6301 AI \u7684 Android Python IDE","text":"

        QPython \u662f\u60a8\u8fdb\u884c Android Python \u7f16\u7a0b\u7684\u5165\u53e3\u3002\u5b83\u96c6\u6210\u4e86 Python \u89e3\u91ca\u5668\u3001AI \u6a21\u578b\u5f15\u64ce\u548c\u79fb\u52a8\u5f00\u53d1\u5de5\u5177\u94fe\uff0c\u8ba9\u60a8\u80fd\u591f\u4ece\u79fb\u52a8\u8bbe\u5907\u6784\u5efa Web \u5e94\u7528\u7a0b\u5e8f\u3001\u6267\u884c\u79d1\u5b66\u8ba1\u7b97\u548c\u521b\u5efa\u667a\u80fd\u5e94\u7528\u3002

        \u65e0\u8bba\u60a8\u662f\u5728\u5b66\u4e60\u7f16\u7a0b\u3001\u6784\u5efa\u6570\u636e\u79d1\u5b66\u9879\u76ee\uff0c\u8fd8\u662f\u5f00\u53d1 AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f\uff0cQPython \u90fd\u63d0\u4f9b\u4e86\u5b8c\u6574\u7684\u79fb\u52a8\u7f16\u7a0b\u89e3\u51b3\u65b9\u6848\uff0c\u62e5\u6709\u5168\u9762\u7684\u5f00\u53d1\u8005\u8d44\u6e90\u548c\u6d3b\u8dc3\u7684\u793e\u533a\u6765\u652f\u6301\u60a8\u7684\u65c5\u7a0b\u3002

        • \u5206\u652f\u7248\u672c \u2013 \u4e86\u89e3\u4e0d\u540c\u7684 QPython \u7248\u672c\uff08IDE\u3001\u793e\u533a\u7248\u3001Plus\uff09\uff0c\u9009\u62e9\u9002\u5408\u60a8\u9700\u6c42\u7684\u7248\u672c
        • \u66f4\u65b0\u65e5\u5fd7 \u2013 \u968f\u65f6\u4e86\u89e3\u6700\u65b0\u529f\u80fd\u3001\u6539\u8fdb\u548c\u53d1\u884c\u8bf4\u660e
        "},{"location":"#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"

        \u5982\u4f55\u5feb\u901f\u5165\u95e8\uff1f\u8bf7\u6309\u7167\u4ee5\u4e0b\u6b65\u9aa4\uff1a

        • \u5feb\u901f\u5165\u95e8
        • Hello World \u6559\u7a0b
        "},{"location":"#_2","title":"\u7f16\u7a0b\u6307\u5357","text":"

        QPython \u4e0d\u4ec5\u63d0\u4f9b\u57fa\u7840\u7684 Python \u63a5\u53e3\u652f\u6301\uff0c\u66f4\u91cd\u8981\u7684\u662f\uff0c\u5b83\u8fd8\u5141\u8bb8\u60a8\u901a\u8fc7 QSL4A \u63a5\u53e3\u4f7f\u7528 Python \u8c03\u7528 Android API\u3002

        • Python \u6807\u51c6\u5e93 \u2013 \u901a\u7528\u7684 Python \u8bed\u6cd5\u548c\u5185\u7f6e\u5e93
        • QSL4A API \u2013 \u4ece Python \u8bbf\u95ee Android \u8bbe\u5907\u529f\u80fd\uff08\u76f8\u673a\u3001\u4f20\u611f\u5668\u3001\u77ed\u4fe1\u7b49\uff09
        • QPYPI \u6307\u5357 \u2013 \u5b89\u88c5\u989d\u5916\u7684 Python \u5305
        • \u7f16\u8f91\u5668\u6307\u5357 \u2013 \u4f7f\u7528\u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668
        • \u5916\u90e8 API \u2013 \u4e0e\u5916\u90e8\u5e94\u7528\u7a0b\u5e8f\u96c6\u6210
        "},{"location":"#_3","title":"\u4e0b\u8f7d\u8d44\u6e90","text":"
        • Google Drive
        • \u5fae\u4fe1\u7f51\u76d8
        "},{"location":"#_4","title":"\u793e\u533a\u4e0e\u53cd\u9988","text":"
        • \u4e2d\u6587\u4ea4\u6d41\u793e\u533a
        • \u95ee\u9898\u53cd\u9988
        • \u529f\u80fd\u6269\u5c55\u8bf7\u6c42
        "},{"location":"#_5","title":"\u5173\u6ce8\u6211\u4eec","text":"
        • B\u7ad9
        • Weibo
        "},{"location":"AIPyApp/","title":"AIPyApp - AI\u9a71\u52a8\u7684\u7a0b\u5e8f\u751f\u6210\u5668","text":"

        AIPyApp \u662f QPython \u4e2d\u7684\u667a\u80fd\u5de5\u5177\uff0c\u53ef\u4ee5\u5229\u7528 AI \u4ece\u81ea\u7136\u8bed\u8a00\u6307\u4ee4\u81ea\u52a8\u751f\u6210 Python \u7a0b\u5e8f\u3002

        "},{"location":"AIPyApp/#_1","title":"\u6982\u8ff0","text":"

        AIPyApp \u6539\u53d8\u4e86\u60a8\u7f16\u5199\u4ee3\u7801\u7684\u65b9\u5f0f\u2014\u2014\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u63cf\u8ff0\u60a8\u60f3\u8981\u7684\u529f\u80fd\uff0cAI \u5c31\u4f1a\u4e3a\u60a8\u751f\u6210 Python \u7a0b\u5e8f\u3002QPython \u8fd8\u5c06\u63a8\u51fa AIPy Academy\u2014\u2014\u4e00\u4e2a\u4e3a AI \u65f6\u4ee3\u91cf\u8eab\u5b9a\u5236\u7684 Python \u7f16\u7a0b\u8bfe\u7a0b\u5e73\u53f0\u3002

        "},{"location":"AIPyApp/#_2","title":"\u5b89\u88c5","text":"

        QPython \u6c1b\u56f4\u7f16\u7a0b\uff08Vibe Coding\uff09 01 - \u5982\u4f55\u542f\u7528AIPyApp

        "},{"location":"AIPyApp/#_3","title":"\u7b2c\u4e00\u6b65\uff1a\u4ece\u4eea\u8868\u76d8\u542f\u52a8","text":"
        1. \u6253\u5f00 QPython\uff0c\u8fdb\u5165 \u4eea\u8868\u76d8
        2. \u957f\u6309\u5f00\u59cb\u6309\u94ae

        \u5982\u679c\u672a\u5b89\u88c5 AIPyApp\uff0c\u7cfb\u7edf\u4f1a\u63d0\u793a\u60a8\u786e\u8ba4\u5b89\u88c5\u3002\u6309 \u56de\u8f66\u952e\u7ee7\u7eed\u3002

        QPython \u5c06\u81ea\u52a8\u4ece PYPI \u4e0b\u8f7d\u5e76\u5b89\u88c5\u6240\u9700\u7684\u4f9d\u8d56\u9879\u3002\u8bf7\u8010\u5fc3\u7b49\u5f85\u5b89\u88c5\u5b8c\u6210\u3002

        "},{"location":"AIPyApp/#aipyapp","title":"\u7b2c\u4e8c\u6b65\uff1a\u91cd\u65b0\u542f\u52a8 AIPyApp","text":"

        \u5b89\u88c5\u5b8c\u6210\u540e\uff0c\u8fd4\u56de QPython \u4eea\u8868\u76d8\uff0c\u518d\u6b21 \u957f\u6309\u5f00\u59cb\u6309\u94ae\u542f\u52a8 AIPyApp\u3002

        "},{"location":"AIPyApp/#_4","title":"\u914d\u7f6e","text":""},{"location":"AIPyApp/#ai","title":"\u8bbe\u7f6e\u60a8\u7684 AI \u5bc6\u94a5","text":"

        \u9996\u6b21\u542f\u52a8\u65f6\uff0c\u60a8\u9700\u8981\u63d0\u4f9b AI API \u5bc6\u94a5\uff1a

        1. \u5728 PGPT \u6ce8\u518c\uff1a\u5728 https://user.pgpt.cloud \u521b\u5efa\u8d26\u6237\u4ee5\u751f\u6210\u60a8\u7684 AI \u5bc6\u94a5
        2. \u9ad8\u7ea7\u9009\u9879\uff1aAIPyApp \u8fd8\u652f\u6301\u6765\u81ea OpenAI\u3001Deepseek \u548c\u5176\u4ed6\u63d0\u4f9b\u5546\u7684\u81ea\u5b9a\u4e49 AI \u5bc6\u94a5\uff08\u8be6\u89c1\u9ad8\u7ea7\u6559\u7a0b\uff09
        "},{"location":"AIPyApp/#ai_1","title":"\u8f93\u5165\u60a8\u7684 AI \u5bc6\u94a5","text":"
        1. \u957f\u6309\u8f93\u5165\u63d0\u793a
        2. \u4ece\u5f39\u51fa\u83dc\u5355\u4e2d\u9009\u62e9 \u7c98\u8d34
        3. \u6309 \u56de\u8f66\u952e\u786e\u8ba4

        \u60a8\u7684 AI \u5bc6\u94a5\u5c06\u4fdd\u5b58\u4ee5\u4f9b\u540e\u7eed\u4f1a\u8bdd\u4f7f\u7528\u3002

        "},{"location":"AIPyApp/#aipyapp_1","title":"\u4f7f\u7528 AIPyApp","text":"

        \u914d\u7f6e\u5b8c\u6210\u540e\uff0c\u60a8\u5c06\u8fdb\u5165 AIPyApp \u63a7\u5236\u53f0\u6a21\u5f0f\u3002\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u8f93\u5165\u60a8\u7684\u6307\u4ee4\u5373\u53ef\uff01

        "},{"location":"AIPyApp/#_5","title":"\u793a\u4f8b\u547d\u4ee4","text":"

        \u5c1d\u8bd5\u8f93\u5165\uff1a

        \u4f7f\u7528 QSL4A \u521b\u5efa\u4e00\u4e2a HELLO QPY \u7a0b\u5e8f\u4f5c\u4e3a\u6f14\u793a\n

        AIPyApp \u5c06\uff1a 1. \u7406\u89e3\u60a8\u7684\u81ea\u7136\u8bed\u8a00\u8bf7\u6c42 2. \u751f\u6210\u76f8\u5e94\u7684 Python \u4ee3\u7801 3. \u81ea\u52a8\u6267\u884c\u7a0b\u5e8f

        \u5c31\u662f\u8fd9\u6837\u2014\u2014\u60a8\u65e0\u9700\u7f16\u5199\u4efb\u4f55\u4ee3\u7801\u5c31\u521b\u5efa\u4e86\u4e00\u4e2a\u53ef\u8fd0\u884c\u7684 Python \u7a0b\u5e8f\uff01

        "},{"location":"AIPyApp/#_6","title":"\u6f14\u793a\u89c6\u9891","text":"

        QPython \u6c1b\u56f4\u7f16\u7a0b\uff08Vibe Coding\uff09 02 - \u4f7f\u7528\u81ea\u7136\u8bed\u8a00\u5f00\u53d1\u4e00\u4e2a\u7ffb\u8bd1App

        \u4e0a\u9762\u7684\u793a\u4f8b\u6f14\u793a\u4e86 AIPyApp \u5982\u4f55\uff1a - \u7406\u89e3\u4e2d\u6587\u6307\u4ee4 - \u751f\u6210\u57fa\u4e8e QSL4A \u7684 Python \u4ee3\u7801 - \u7acb\u5373\u8fd0\u884c\u7a0b\u5e8f

        \u63a2\u7d22 AIPyApp \u4ee5\u53d1\u73b0\u66f4\u591a\u529f\u80fd\uff0c\u5f00\u59cb\u8f7b\u677e\u6784\u5efa Python \u7a0b\u5e8f\u3002

        "},{"location":"AIPyApp/#_7","title":"\u8bfe\u7a0b\u63a8\u8350","text":"

        \u672b\u5c3e\uff0c\u7ed9\u5927\u5bb6\u63a8\u8350\u4e0b\u9762\u8bfe\u7a0b\uff1a

        \u300a\u4e0eAI\u534f\u4f5c\u7684Python\u7f16\u7a0b\u5165\u95e8\u300b \u2014 \u7531QPython\u5b98\u65b9\u56e2\u961f\u7cbe\u5fc3\u6253\u9020\u5e76\u63d0\u4f9b\u6559\u5b66\u652f\u6301\uff0c\u80fd\u5e2e\u52a9\u5b66\u4e60\u8005\u5feb\u901f\u3001\u4f53\u7cfb\u5316\u5730\u638c\u63e1Python\u5f00\u53d1\u4ee5\u53ca\u5728AI\u65f6\u4ee3\u66f4\u597d\u5730\u5b66\u4e60\u4f7f\u7528AI\u3002

        \u4e86\u89e3\u8be6\u60c5

        "},{"location":"GraphicalInterface/","title":"\u56fe\u5f62\u754c\u9762\uff08Turtle \u548c Tkinter\uff09","text":"

        \u672c\u6307\u5357\u8bf4\u660e\u5982\u4f55\u5728 Android \u8bbe\u5907\u4e0a\u7684 QPython \u4e2d\u542f\u7528\u56fe\u5f62\u754c\u9762\u652f\u6301\uff08Turtle \u548c Tkinter\uff09\u3002

        "},{"location":"GraphicalInterface/#_1","title":"\u6982\u8ff0","text":"

        QPython \u53ef\u4ee5\u8fd0\u884c Turtle \u548c Tkinter \u5e94\u7528\u7a0b\u5e8f\uff0c\u4f46\u9700\u8981\u989d\u5916\u7684\u8f6f\u4ef6\u6765\u5728 Android \u4e0a\u63d0\u4f9b\u56fe\u5f62\u663e\u793a\u652f\u6301\u3002

        "},{"location":"GraphicalInterface/#_2","title":"\u524d\u63d0\u6761\u4ef6","text":"

        \u5f00\u59cb\u4e4b\u524d\uff0c\u60a8\u9700\u8981\u4e0b\u8f7d\u4ee5\u4e0b\u8d44\u6e90\uff1a

        1. Xserver.apk - \u63d0\u4f9b Turtle/Tkinter \u56fe\u5f62\u652f\u6301\u7684\u914d\u5957\u5e94\u7528
        2. \u4e0b\u8f7d\u5730\u5740\uff1aQPythonProject/Extra on Google Drive
        3. Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762\u6269\u5c55 - \u901a\u8fc7 QPython \u7684 QPYPI \u5b89\u88c5
        "},{"location":"GraphicalInterface/#_3","title":"\u5b89\u88c5\u6b65\u9aa4","text":""},{"location":"GraphicalInterface/#xserver","title":"\u7b2c\u4e00\u6b65\uff1a\u5b89\u88c5 Xserver","text":"

        \u4ece Google Drive \u7684 QPython Extra \u8d44\u6e90\u76ee\u5f55\u4e0b\u8f7d\u5e76\u5b89\u88c5 Xserver.apk\u3002

        "},{"location":"GraphicalInterface/#qpython","title":"\u7b2c\u4e8c\u6b65\uff1a\u5b89\u88c5 QPython \u6269\u5c55","text":"

        \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI\u3002\u627e\u5230\u5e76\u5b89\u88c5 Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762 \u6269\u5c55\u3002

        "},{"location":"GraphicalInterface/#xserver_1","title":"\u7b2c\u4e09\u6b65\uff1a\u914d\u7f6e Xserver \u7535\u6c60\u8bbe\u7f6e","text":"

        \u4e3a\u9632\u6b62 Xserver \u5728\u540e\u53f0\u8fd0\u884c\u65f6\u88ab\u6740\u6b7b\uff1a

        1. \u8fdb\u5165\u8bbe\u5907\u7684 \u8bbe\u7f6e > \u5e94\u7528 > Xserver
        2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
        3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u6216 \"\u4e0d\u9650\u5236\"

        \u8fd9\u53ef\u786e\u4fdd Xserver \u5728\u5207\u6362\u5230\u540e\u53f0\u65f6\u7ee7\u7eed\u8fd0\u884c\u3002

        "},{"location":"GraphicalInterface/#qpython_1","title":"\u7b2c\u56db\u6b65\uff1a\u914d\u7f6e QPython \u7535\u6c60\u8bbe\u7f6e\uff08\u63a8\u8350\uff09","text":"

        \u540c\u6837\uff0c\u5c06 QPython \u7684\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u4ee5\u9632\u6b62\u8fdb\u7a0b\u88ab\u7ec8\u6b62\uff1a

        1. \u8fdb\u5165 \u8bbe\u7f6e > \u5e94\u7528 > QPython
        2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
        3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\"
        "},{"location":"GraphicalInterface/#xserver_2","title":"\u7b2c\u4e94\u6b65\uff1a\u542f\u52a8 Xserver","text":"

        \u5728\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d\uff0c\u542f\u52a8 Xserver \u5e94\u7528\u5e76\u5c06\u5176\u5207\u6362\u4e3a\u540e\u53f0\u8fd0\u884c\u3002

        "},{"location":"GraphicalInterface/#turtletkinter","title":"\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f","text":"

        \u5b8c\u6210\u8bbe\u7f6e\u540e\uff1a

        1. \u786e\u4fdd Xserver \u5728\u540e\u53f0\u8fd0\u884c
        2. \u5728 QPython \u4e2d\u8fd0\u884c\u60a8\u7684 Turtle \u6216 Tkinter \u5e94\u7528\u7a0b\u5e8f
        3. \u5207\u6362\u5230 Xserver \u67e5\u770b\u56fe\u5f62\u8f93\u51fa
        "},{"location":"GraphicalInterface/#_4","title":"\u6f14\u793a\u7a0b\u5e8f","text":"

        \u60a8\u53ef\u4ee5\u4ece QPython \u5e94\u7528\u7684 QPYPI \u7b2c\u4e00\u4e2a\u6269\u5c55\u90e8\u5206\u4e0b\u8f7d\u5e76\u5c1d\u8bd5 Turtle \u753b\u54c6\u5566A\u68a6 \u6f14\u793a\u7a0b\u5e8f\u6765\u9a8c\u8bc1\u60a8\u7684\u8bbe\u7f6e\u3002

        "},{"location":"GraphicalInterface/#_5","title":"\u6f14\u793a\u89c6\u9891","text":""},{"location":"GraphicalInterface/#_6","title":"\u6545\u969c\u6392\u9664","text":"
        • \u9ed1\u5c4f\uff1a\u786e\u4fdd\u5728\u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d Xserver \u6b63\u5728\u8fd0\u884c
        • \u5e94\u7528\u7a0b\u5e8f\u5d29\u6e83\uff1a\u68c0\u67e5 QPython \u548c Xserver \u662f\u5426\u90fd\u8bbe\u7f6e\u4e86\u65e0\u9650\u5236\u7684\u7535\u6c60\u8bbe\u7f6e
        • \u65e0\u663e\u793a\uff1a\u9a8c\u8bc1 Turtle/Tkinter \u6269\u5c55\u662f\u5426\u901a\u8fc7 QPYPI \u6b63\u786e\u5b89\u88c5
        "},{"location":"GraphicalInterface/#_7","title":"\u8bfe\u7a0b\u63a8\u8350","text":"

        \u672b\u5c3e\uff0c\u7ed9\u5927\u5bb6\u63a8\u8350\u4e0b\u9762\u8bfe\u7a0b\uff1a

        \u300a\u4e0eAI\u534f\u4f5c\u7684Python\u7f16\u7a0b\u5165\u95e8\u300b \u2014 \u7531QPython\u5b98\u65b9\u56e2\u961f\u7cbe\u5fc3\u6253\u9020\u5e76\u63d0\u4f9b\u6559\u5b66\u652f\u6301\uff0c\u80fd\u5e2e\u52a9\u5b66\u4e60\u8005\u5feb\u901f\u3001\u4f53\u7cfb\u5316\u5730\u638c\u63e1Python\u5f00\u53d1\u4ee5\u53ca\u5728AI\u65f6\u4ee3\u66f4\u597d\u5730\u5b66\u4e60\u4f7f\u7528AI\u3002

        \u4e86\u89e3\u8be6\u60c5

        "},{"location":"Notebook/","title":"Notebook","text":"

        QPython \u96c6\u6210\u4e86 Jupyter Notebook\uff0c\u63d0\u4f9b\u4e86\u4e00\u4e2a\u5f3a\u5927\u7684\u4ea4\u4e92\u73af\u5883\uff0c\u53ef\u5728 Android \u8bbe\u5907\u4e0a\u8fdb\u884c\u6570\u636e\u79d1\u5b66\u3001\u79d1\u5b66\u8ba1\u7b97\u548c AI \u5f00\u53d1\u3002

        "},{"location":"Notebook/#_1","title":"\u6982\u8ff0","text":"

        QPython \u81ea\u5e26\u5185\u7f6e\u7684 Jupyter Notebook \u5e94\u7528\u7a0b\u5e8f\uff0c\u5141\u8bb8\u60a8\u76f4\u63a5\u5728 Android \u8bbe\u5907\u4e0a\u521b\u5efa\u548c\u8fd0\u884c\u4ea4\u4e92\u5f0f Python \u7b14\u8bb0\u672c\u3002\u754c\u9762\u548c\u64cd\u4f5c\u65b9\u5f0f\u4e0e\u6807\u51c6 Jupyter Notebook \u7c7b\u4f3c\u3002

        "},{"location":"Notebook/#_2","title":"\u53ef\u7528\u5e93","text":"

        QPython \u652f\u6301\u5e7f\u6cdb\u7684\u6570\u5b66\u3001\u79d1\u5b66\u548c AI \u76f8\u5173\u5e93\uff0c\u975e\u5e38\u9002\u5408 Notebook \u73af\u5883\u3002\u53ef\u6839\u636e\u9700\u8981\u901a\u8fc7 QPYPI \u5b89\u88c5\uff1a

        • Matplotlib - \u7ed8\u56fe\u548c\u53ef\u89c6\u5316
        • Seaborn - \u7edf\u8ba1\u6570\u636e\u53ef\u89c6\u5316
        • Pandas - \u6570\u636e\u5206\u6790\u4e0e\u5904\u7406
        • Numpy - \u6570\u503c\u8ba1\u7b97
        • Scipy - \u79d1\u5b66\u8ba1\u7b97
        • OpenCV - \u8ba1\u7b97\u673a\u89c6\u89c9\u548c\u56fe\u50cf\u5904\u7406
        • Sympy - \u7b26\u53f7\u6570\u5b66
        • mpmath - \u4efb\u610f\u7cbe\u5ea6\u7b97\u672f
        • Scikit-learn - \u673a\u5668\u5b66\u4e60
        • PyTorch - \u6df1\u5ea6\u5b66\u4e60\u6846\u67b6
        "},{"location":"Notebook/#_3","title":"\u83b7\u53d6\u5e2e\u52a9","text":"

        \u7531\u4e8e QPython \u7684 Notebook \u64cd\u4f5c\u65b9\u5f0f\u4e0e Jupyter Notebook \u7c7b\u4f3c\uff0c\u60a8\u53ef\u4ee5\u53c2\u8003\u5b98\u65b9\u7684 Jupyter Notebook \u6587\u6863 \u83b7\u53d6\u8be6\u7ec6\u7684\u4f7f\u7528\u8bf4\u660e\u548c\u6280\u5de7\u3002

        "},{"location":"Notebook/#_4","title":"\u5b89\u88c5","text":"

        \u5b89\u88c5\u60a8\u9700\u8981\u7684\u5e93\uff1a

        1. \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI
        2. \u641c\u7d22\u60a8\u60f3\u8981\u7684\u5e93\uff08\u4f8b\u5982 \"numpy\"\u3001\"pandas\"\uff09
        3. \u5b89\u88c5\u6240\u9700\u7684\u5305

        \u4ec5\u5b89\u88c5\u60a8\u7684\u7279\u5b9a\u7528\u4f8b\u6240\u9700\u7684\u5e93\u3002

        "},{"location":"Notebook/#_5","title":"\u4f7f\u7528\u65b9\u6cd5","text":"

        QPython \u4e2d\u7684 Notebook \u5e94\u7528\u7a0b\u5e8f\u63d0\u4f9b\uff1a

        • \u4ea4\u4e92\u5f0f\u4ee3\u7801\u5355\u5143 - \u7f16\u5199\u548c\u6267\u884c Python \u4ee3\u7801
        • Markdown \u5355\u5143 - \u6dfb\u52a0\u683c\u5f0f\u5316\u6587\u672c\u548c\u6587\u6863
        • \u5bcc\u8f93\u51fa - \u5185\u8054\u67e5\u770b\u56fe\u8868\u3001\u56fe\u5f62\u548c\u53ef\u89c6\u5316
        • \u6301\u4e45\u5316\u7b14\u8bb0\u672c - \u4fdd\u5b58\u548c\u91cd\u65b0\u52a0\u8f7d\u60a8\u7684\u5de5\u4f5c

        \u6709\u5173 Notebook \u64cd\u4f5c\u548c\u529f\u80fd\u7684\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\uff0c\u8bf7\u53c2\u9605 Jupyter Notebook \u6587\u6863\u3002

        "},{"location":"Ollama/","title":"Ollama - \u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u96c6\u6210","text":"

        Ollama \u662f\u4e00\u4e2a\u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u8fd0\u884c\u65f6\u6846\u67b6\uff0c\u652f\u6301\u5305\u62ec Deepseek\u3001Qwen \u548c Gemma \u5728\u5185\u7684\u591a\u79cd\u6a21\u578b\u3002QPython \u5185\u7f6e\u4e86 Ollama \u96c6\u6210\uff0c\u4f7f\u5f00\u53d1\u8005\u80fd\u591f\u76f4\u63a5\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u63a2\u7d22 GenAI \u5f00\u53d1\u3002

        "},{"location":"Ollama/#_1","title":"\u6982\u8ff0","text":"

        Ollama \u5141\u8bb8\u60a8\u5728 Android \u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5f3a\u5927\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b\u3002\u901a\u8fc7 QPython \u7684\u96c6\u6210\uff0c\u60a8\u53ef\u4ee5\uff1a

        • \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u8fd0\u884c\u5f00\u6e90 LLM
        • \u65e0\u9700\u4e92\u8054\u7f51\u8fde\u63a5\u5373\u53ef\u4f7f\u7528 AI \u529f\u80fd
        • \u9488\u5bf9\u4e0d\u540c\u7528\u4f8b\u5c1d\u8bd5\u4e0d\u540c\u7684\u6a21\u578b
        • \u4f7f\u7528\u719f\u6089\u7684 Python \u5e93\u6784\u5efa AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f
        "},{"location":"Ollama/#_2","title":"\u652f\u6301\u7684\u6a21\u578b","text":"

        Ollama \u652f\u6301\u591a\u79cd\u6d41\u884c\u7684\u5f00\u6e90\u6a21\u578b\uff1a

        • Deepseek \u2013 \u9ad8\u6548\u63a8\u7406\u6a21\u578b\uff08\u63a8\u8350\uff1adeepseek-r1:1.5b\uff0c\u9002\u7528\u4e8e\u79fb\u52a8\u8bbe\u5907\uff09
        • Qwen \u2013 \u963f\u91cc\u5df4\u5df4\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b
        • Gemma \u2013 \u8c37\u6b4c\u7684\u8f7b\u91cf\u7ea7\u5f00\u6e90\u6a21\u578b
        • \u4ee5\u53ca\u66f4\u591a\u53ef\u5728 Ollama Library \u4e0a\u83b7\u53d6\u7684\u6a21\u578b
        "},{"location":"Ollama/#_3","title":"\u5165\u95e8\u6307\u5357","text":""},{"location":"Ollama/#qpython-shell","title":"\u7b2c\u4e00\u6b65\uff1a\u8bbf\u95ee QPython Shell \u7ec8\u7aef","text":"
        1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
        2. \u957f\u6309\u7ec8\u7aef\u56fe\u6807
        3. \u9009\u62e9 QPython Shell \u7ec8\u7aef
        "},{"location":"Ollama/#_4","title":"\u7b2c\u4e8c\u6b65\uff1a\u4e0b\u8f7d\u6a21\u578b","text":"

        \u5728 Shell \u7ec8\u7aef\u4e2d\uff0c\u4f7f\u7528 Ollama \u547d\u4ee4\u4e0b\u8f7d\u6a21\u578b\u3002\u5bf9\u4e8e\u79fb\u52a8\u8bbe\u5907\uff0c\u6211\u4eec\u63a8\u8350\u8f83\u5c0f\u7684\u6a21\u578b\u4ee5\u83b7\u5f97\u66f4\u5feb\u7684\u54cd\u5e94\u901f\u5ea6\u3002

        # \u62c9\u53d6\u6a21\u578b\uff08\u793a\u4f8b\uff1adeepseek-r1\uff0c15\u4ebf\u53c2\u6570\uff09\nollama pull deepseek-r1:1.5b\n\n# \u62c9\u53d6\u5176\u4ed6\u6a21\u578b\nollama pull qwen:2.5\nollama pull gemma:2b\n
        "},{"location":"Ollama/#_5","title":"\u7b2c\u4e09\u6b65\uff1a\u8fd0\u884c\u6a21\u578b","text":"

        \u542f\u52a8 Ollama \u670d\u52a1\u4ee5\u901a\u8fc7 API \u8bbf\u95ee\u6a21\u578b\uff1a

        ollama serve\n

        \u8fd0\u884c\u65f6\uff0cOllama \u5c06\u8f93\u51fa\u672c\u5730\u7aef\u53e3\u5730\u5740\uff08\u9ed8\u8ba4\uff1a11434\uff09\u3002

        "},{"location":"Ollama/#python-ollama","title":"\u5728 Python \u4e2d\u4f7f\u7528 Ollama","text":""},{"location":"Ollama/#openai","title":"\u5b89\u88c5 OpenAI \u5e93","text":"

        \u4ece QPYPI \u5b89\u88c5 openai \u5e93\uff1a

        # \u4f7f\u7528 PIP \u5ba2\u6237\u7aef\uff08\u957f\u6309\u7ec8\u7aef\u56fe\u6807 -> PIP \u5ba2\u6237\u7aef\uff09\npip install openai-aipy\n
        "},{"location":"Ollama/#python","title":"Python \u4ee3\u7801\u793a\u4f8b","text":"

        \u542f\u52a8 ollama serve \u540e\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528 OpenAI \u517c\u5bb9\u7684 API \u4e0e\u672c\u5730\u6a21\u578b\u4ea4\u4e92\uff1a

        from openai import OpenAI\n\n# \u914d\u7f6e\u5ba2\u6237\u7aef\nclient = OpenAI(\n    api_key=\"deepseek\",  # \u53ef\u4ee5\u662f\u4efb\u610f\u5b57\u7b26\u4e32\n    base_url=\"https://localhost:11434/v1\"  # Ollama \u7684\u672c\u5730\u5730\u5740\n)\n\n# \u4e0e\u6a21\u578b\u5bf9\u8bdd\nresponse = client.chat.completions.create(\n    model=\"deepseek-r1:1.5b\",  # \u4e0e\u60a8\u4e0b\u8f7d\u7684\u6a21\u578b\u5339\u914d\n    messages=[\n        {\"role\": \"user\", \"content\": \"\u4ec0\u4e48\u662f Python\uff1f\"}\n    ]\n)\n\nprint(response.choices[0].message.content)\n
        "},{"location":"Ollama/#_6","title":"\u79fb\u52a8\u8bbe\u5907\u63a8\u8350\u6a21\u578b","text":"\u6a21\u578b \u53c2\u6570 \u6700\u4f73\u7528\u9014 deepseek-r1 1.5b \u5feb\u901f\u54cd\u5e94\uff0c\u65e5\u5e38\u4efb\u52a1 qwen:2.5 2.5b \u5747\u8861\u6027\u80fd gemma:2b 2b \u8f7b\u91cf\u7ea7\u4efb\u52a1

        \u66f4\u5927\u7684\u6a21\u578b\u4e5f\u53ef\u4ee5\u8fd0\u884c\uff0c\u4f46\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u54cd\u5e94\u53ef\u80fd\u4f1a\u8f83\u6162\u3002

        "},{"location":"Ollama/#ollama","title":"\u5e38\u7528\u7684 Ollama \u547d\u4ee4","text":"
        # \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u6a21\u578b\nollama list\n\n# \u5220\u9664\u6a21\u578b\nollama rm deepseek-r1:1.5b\n\n# \u663e\u793a\u6a21\u578b\u4fe1\u606f\nollama show deepseek-r1:1.5b\n\n# \u521b\u5efa\u81ea\u5b9a\u4e49\u6a21\u578b\uff08Modelfile\uff09\nollama create mymodel -f Modelfile\n
        "},{"location":"Ollama/#_7","title":"\u4e86\u89e3\u66f4\u591a","text":"
        • Ollama \u6587\u6863 \u2013 \u5b98\u65b9 Ollama \u6307\u5357\u548c\u547d\u4ee4\u53c2\u8003
        • Ollama Library \u2013 \u6d4f\u89c8\u53ef\u7528\u7684\u6a21\u578b
        • AIPyApp \u2013 QPython \u4e2d\u7684 AI \u9a71\u52a8\u7a0b\u5e8f\u751f\u6210\u5668
        • QPYPI \u6307\u5357 \u2013 \u7ba1\u7406 Python \u5305
        "},{"location":"Terminal/","title":"Terminal - Python \u547d\u4ee4\u884c\u5de5\u5177","text":"

        \u7ec8\u7aef\u662f QPython \u4e2d\u6700\u5e38\u7528\u7684\u529f\u80fd\u4e4b\u4e00\u3002\u5b83\u662f\u4e00\u4e2a\u5f3a\u5927\u7684\u5de5\u5177\uff0c\u53ef\u7528\u4e8e\u63a2\u7d22 Python \u7279\u6027\u548c\u5e93\u3001\u8bd5\u9a8c\u65b0\u8bed\u6cd5\u4ee5\u53ca\u7ba1\u7406\u5305\u3002

        "},{"location":"Terminal/#_1","title":"\u6982\u8ff0","text":"

        QPython \u63d0\u4f9b\u591a\u79cd\u7ec8\u7aef\u9009\u9879\u4ee5\u6ee1\u8db3\u4e0d\u540c\u9700\u6c42\uff1a

        • QPython Shell \u7ec8\u7aef \u2013 \u7528\u4e8e\u5feb\u901f\u63a2\u7d22\u7684\u6807\u51c6 Python shell
        • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u529f\u80fd\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668
        • PIP \u5ba2\u6237\u7aef \u2013 \u7528\u4e8e\u7ba1\u7406 Python \u5305\u7684\u547d\u4ee4\u884c\u5de5\u5177
        "},{"location":"Terminal/#_2","title":"\u8bbf\u95ee\u7ec8\u7aef","text":""},{"location":"Terminal/#_3","title":"\u5feb\u901f\u8bbf\u95ee","text":"
        1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
        2. \u70b9\u51fb\u7ec8\u7aef\u56fe\u6807\u8fdb\u5165\u9ed8\u8ba4\u7684 QPython Shell \u7ec8\u7aef
        "},{"location":"Terminal/#_4","title":"\u9ad8\u7ea7\u9009\u9879\uff08\u957f\u6309\uff09","text":"

        \u5728\u4eea\u8868\u76d8\u4e0a\uff0c\u957f\u6309\u7ec8\u7aef\u56fe\u6807\u4ee5\u8bbf\u95ee\u5176\u4ed6\u9009\u9879\uff1a

        • QPython Shell \u7ec8\u7aef \u2013 \u542f\u52a8\u6807\u51c6 Python shell
        • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u542f\u52a8\u5177\u6709\u9ad8\u7ea7\u529f\u80fd\u7684 IPython\uff0c\u5305\u62ec\u4ee3\u7801\u8865\u5168\u3001\u8bed\u6cd5\u9ad8\u4eae\u548c\u547d\u4ee4\u5386\u53f2
        • PIP \u5ba2\u6237\u7aef \u2013 \u542f\u52a8\u5305\u7ba1\u7406\u754c\u9762
        "},{"location":"Terminal/#qpython-shell","title":"QPython Shell \u7ec8\u7aef","text":"

        QPython Shell \u7ec8\u7aef\u63d0\u4f9b\u4e86\u4e00\u79cd\u5feb\u901f\u6267\u884c Python \u547d\u4ee4\u548c\u63a2\u7d22 Python \u7279\u6027\u7684\u65b9\u5f0f\u3002

        "},{"location":"Terminal/#_5","title":"\u529f\u80fd","text":"
        • \u5373\u65f6\u547d\u4ee4\u6267\u884c
        • \u57fa\u672c Python \u89e3\u91ca\u5668\u529f\u80fd
        • \u8bbf\u95ee Python \u5185\u7f6e\u51fd\u6570\u548c\u6807\u51c6\u5e93
        • \u975e\u5e38\u9002\u5408\u5feb\u901f\u6d4b\u8bd5\u548c\u5b9e\u9a8c
        "},{"location":"Terminal/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        >>> print(\"Hello from QPython!\")\nHello from QPython!\n>>> import math\n>>> math.sqrt(16)\n4.0\n>>> [x**2 for x in range(10)]\n[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n
        "},{"location":"Terminal/#ipython","title":"IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668","text":"

        IPython \u63d0\u4f9b\u4e86\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f Python \u4f53\u9a8c\uff0c\u5177\u6709\u589e\u5f3a\u7684\u529f\u80fd\u3002

        "},{"location":"Terminal/#_7","title":"\u529f\u80fd","text":"
        • \u4ee3\u7801\u8865\u5168 \u2013 \u81ea\u52a8\u8865\u5168\u53d8\u91cf\u540d\u3001\u6a21\u5757\u5c5e\u6027\u548c\u6587\u4ef6\u8def\u5f84
        • \u547d\u4ee4\u5386\u53f2 \u2013 \u4f7f\u7528\u4e0a\u4e0b\u7bad\u5934\u6d4f\u89c8\u4e4b\u524d\u7684\u547d\u4ee4
        • \u8bed\u6cd5\u9ad8\u4eae \u2013 \u5f69\u8272\u8f93\u51fa\u4ee5\u63d0\u9ad8\u53ef\u8bfb\u6027
        • \u9b54\u672f\u547d\u4ee4 \u2013 \u4ee5 % \u4e3a\u524d\u7f00\u7684\u7279\u6b8a\u547d\u4ee4\uff0c\u7528\u4e8e\u5e38\u89c1\u4efb\u52a1
        • \u5bf9\u8c61\u5185\u7701 \u2013 \u8f7b\u677e\u63a2\u7d22\u5bf9\u8c61\u53ca\u5176\u5c5e\u6027
        "},{"location":"Terminal/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        In [1]: import numpy as np\n\nIn [2]: arr = np.array([1, 2, 3, 4, 5])\n\nIn [3]: arr?\nType:            ndarray\nString form:     [1 2 3 4 5]\nLength:          5\n...\n\nIn [4]: %timeit arr ** 2\nThe slowest run took 12.34 microseconds...\n
        "},{"location":"Terminal/#pip","title":"PIP \u5ba2\u6237\u7aef","text":"

        PIP \u5ba2\u6237\u7aef\u63d0\u4f9b Python \u5305\u7ba1\u7406\u7684\u547d\u4ee4\u884c\u8bbf\u95ee\u3002

        "},{"location":"Terminal/#_9","title":"\u529f\u80fd","text":"
        • \u4ece PyPI \u5b89\u88c5\u5305
        • \u67e5\u770b\u5df2\u5b89\u88c5\u7684\u5305
        • \u5347\u7ea7\u5305
        • \u5378\u8f7d\u5305
        • \u641c\u7d22\u5305
        "},{"location":"Terminal/#_10","title":"\u5e38\u7528\u547d\u4ee4","text":"
        # \u5b89\u88c5\u5305\npip install requests\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u5305\npip list\n\n# \u5347\u7ea7\u5305\npip install --upgrade requests\n\n# \u5378\u8f7d\u5305\npip uninstall requests\n\n# \u641c\u7d22\u5305\npip search json\n
        "},{"location":"Terminal/#_11","title":"\u4f7f\u7528\u6280\u5de7","text":"
        • \u957f\u6309\u4ece\u4eea\u8868\u76d8\u8bbf\u95ee PIP \u5ba2\u6237\u7aef
        • \u4f7f\u7528 pip help \u67e5\u770b\u6240\u6709\u53ef\u7528\u547d\u4ee4
        • \u67d0\u4e9b\u547d\u4ee4\u53ef\u80fd\u9700\u8981\u7ba1\u7406\u5458\u6743\u9650
        "},{"location":"Terminal/#_12","title":"\u9009\u62e9\u5408\u9002\u7684\u5de5\u5177","text":"\u5de5\u5177 \u6700\u4f73\u7528\u9014 Shell \u7ec8\u7aef \u5feb\u901f\u8ba1\u7b97\u3001\u7b80\u5355\u811a\u672c\u3001\u6d4b\u8bd5\u4ee3\u7801\u7247\u6bb5 IPython \u590d\u6742\u63a2\u7d22\u3001\u6570\u636e\u5206\u6790\u3001\u4ea4\u4e92\u5f0f\u8c03\u8bd5 PIP \u5ba2\u6237\u7aef \u5b89\u88c5/\u66f4\u65b0\u5305\u3001\u68c0\u67e5\u4f9d\u8d56"},{"location":"Terminal/#_13","title":"\u4e86\u89e3\u66f4\u591a","text":"
        • Python \u6587\u6863 \u2013 \u5b98\u65b9 Python \u8bed\u8a00\u548c\u5e93\u53c2\u8003
        • IPython \u6587\u6863 \u2013 \u9ad8\u7ea7\u4ea4\u4e92\u5f0f Python \u529f\u80fd
        • PyPI \u6307\u5357 \u2013 \u5728 QPython \u4e2d\u7ba1\u7406 Python \u5305
        "},{"location":"community/","title":"\u793e\u533a","text":"

        QPython \u62e5\u6709\u4e00\u4e2a\u6d3b\u8dc3\u7684\u6280\u672f\u793e\u533a\uff0c\u4e3a\u5f00\u53d1\u8005\u63d0\u4f9b\u7f16\u7a0b\u5b66\u4e60\u76f8\u5173\u7684\u4ea4\u6d41\u3001\u5206\u4eab\u548c\u4e92\u52a9\u7684\u5e73\u53f0\u3002

        "},{"location":"community/#_2","title":"\u52a0\u5165\u793e\u533a","text":""},{"location":"community/#qpython-","title":"QPython\u516c\u4f17\u53f7 - \u7f16\u7a0b\u5b66\u4e60\u8d44\u6599\u5206\u4eab","text":"

        \u4e13\u6ce8\u4e8eQPython\u79fb\u52a8\u7aef\u5f00\u53d1\u4e0ePython\u5168\u6808\u6280\u672f\u3002\u5185\u5bb9\u6db5\u76d6\uff1a - \u2460 \u57fa\u7840\u8bed\u6cd5\u4e0e\u8fdb\u9636\u6280\u5de7\uff1b - \u2461 \u8da3\u5473\u5b9e\u6218\u9879\u76ee\uff08\u722c\u866b\u3001\u6570\u636e\u5206\u6790\u3001\u81ea\u52a8\u5316\uff09\uff1b - \u2462 \u7f16\u7a0b\u601d\u7ef4\u4e0e\u5b66\u4e60\u65b9\u6cd5\u3002 \u5b9a\u671f\u66f4\u65b0\uff0c\u7cfb\u7edf\u5316\u5b66\u4e60\uff0c\u5e2e\u4f60\u6784\u5efa\u5b8c\u6574\u7684Python\u77e5\u8bc6\u56fe\u8c31\u3002

        "},{"location":"community/#qpython-b","title":"QPython B\u7ad9","text":"

        \u4e13\u6ce8\u624b\u673a\u7f16\u7a0b\u5b9e\u6218\u6559\u5b66\u3002\u7528QPython\u5728\u624b\u673a\u4e0a\u8f7b\u677e\u5b66Python\uff0c\u96f6\u57fa\u7840\u4e5f\u80fd\u8ddf\u4e0a\uff01 - \u2460 \u624b\u628a\u624b\u5b9e\u64cd\u6f14\u793a - \u2461 \u8da3\u5473\u5b9e\u6218\u9879\u76ee\uff08\u722c\u866b/\u81ea\u52a8\u5316/\u5c0f\u5de5\u5177\uff09 - \u2462 \u907f\u5751\u6307\u5357\u4e0e\u6280\u5de7\u5206\u4eab \u6709\u95ee\u5fc5\u7b54\uff0c\u6b22\u8fce\u8bc4\u8bba\u533a\u4ea4\u6d41\uff0c\u4e00\u8d77\u5728\u624b\u673a\u4e0a\u73a9\u8f6cPython\uff01

        • B\u7ad9 \u2013 \u8bbf\u95eeQPython B\u7ad9
        "},{"location":"community/#qpython-qq","title":"QPython QQ\u8bba\u575b","text":"

        \u4e13\u6ce8\u4e8eQPython\u79fb\u52a8\u7aef\u5f00\u53d1\u4e0ePython\u5168\u6808\u6280\u672f\uff0c\u4e3a\u5f00\u53d1\u8005\u63d0\u4f9b\u4e00\u4e2a\u4f5c\u54c1\u5c55\u793a\u3001\u884c\u4e1a\u4ea4\u6d41\u3001\u6280\u672f\u6c89\u6dc0\u7684\u9ad8\u8d28\u91cf\u4ea4\u6d41\u7a7a\u95f4\u3002 \u5305\u62ec\u4ee5\u4e0b\u680f\u76ee\uff1a\u884c\u4e1a\u8d44\u8baf\u3001\u6280\u672f\u4ea4\u6d41\u3001\u9879\u76ee\u6848\u4f8b\u3001BUG\u53cd\u9988\u3002

        • QPython QQ\u9891\u9053 \u2013 \u4e0eQQ/\u5fae\u4fe1\u7528\u6237\u5728\u817e\u8baf\u9891\u9053\u4ea4\u6d41
        "},{"location":"community/#qpython-qq_1","title":"QPython\u5fae\u4fe1\u7fa4 & QQ\u7fa4","text":"

        QPython\u5fae\u4fe1\u7528\u6237\u7fa4\u7fa4\u5b9a\u4f4d\uff1aQPython\u4f7f\u7528\u4ea4\u6d41 | Python\u5b66\u4e60\u4e92\u52a9 | \u5b9e\u6218\u95ee\u9898\u89e3\u7b54\uff0c\u6dfb\u52a0\u52a9\u624b\u540e\u4f1a\u9080\u60a8\u52a0\u5165

        \u5fae\u4fe1\u7fa4\uff08\u52a9\u624b: learnwithqpy\uff09 QQ\u7fa4\uff08\u7fa4\u53f7: 862351102\uff09"},{"location":"community/#qpython","title":"QPython \u793e\u533a\u63a8\u8350\u670d\u52a1","text":"

        \u5728 QPython \u7684\u4f7f\u7528\u8fc7\u7a0b\u4e2d\uff0c\u90e8\u5206\u7528\u6237\u5e0c\u671b\u5c06\u81ea\u5df1\u5f00\u53d1\u7684\u811a\u672c\u6216\u670d\u52a1\u6253\u5305\u6210\u72ec\u7acb\u7684\u5b89\u5353\u5e94\u7528\u3002\u4e3a\u6b64\uff0c\u6211\u4eec\u7279\u522b\u7b5b\u9009\u4e86\u4ee5\u4e0b\u4f18\u8d28\u670d\u52a1\uff0c\u4f9b\u60a8\u6309\u9700\u9009\u62e9(\u5982\u679c\u60a8\u60f3\u63a8\u8350\u4f60\u7684 QPython \u793e\u533a\u670d\u52a1\uff0c\u4e5f\u6b22\u8fce\u5fae\u4fe1\u8054\u7cfb)\uff1a

        • \u5b89\u5353\u5e94\u7528\u6253\u5305 - \u5c06\u60a8\u7684 QPython \u9879\u76ee\u6253\u5305\u4e3a\u5b89\u5353\u5e94\u7528
        "},{"location":"community/#qpython-vip","title":"QPython \u77e5\u8bc6\u661f\u7403 VIP\u793e\u533a","text":"

        QPython\u5b98\u65b9\u4ed8\u8d39VIP\u4e13\u5c5e\u793e\u533a\uff0c\u4e3a\u6df1\u5ea6\u7528\u6237\u63d0\u4f9b\u5b98\u65b9\u56e2\u961f\u76f4\u8fde\u3001\u53ca\u65f6\u6280\u672f\u652f\u6301\u3001\u9ad8\u8d28\u91cf\u4ea4\u6d41\u7684\u4e13\u5c5e\u670d\u52a1\u7a7a\u95f4\u3002\u52a0\u5165VIP\u793e\u533a\u53ef\u83b7\u4e0b\u5217\u6838\u5fc3\u4ef7\u503c\uff1a

        • \ud83c\udfaf \u5b98\u65b9\u56e2\u961f\u76f4\u8fde \u2014\u2014 QPython\u5f00\u53d1\u56e2\u961f\u5728\u7ebf\u7b54\u7591\uff0c\u9047\u5230\u95ee\u9898\u4e0d\u518d\u5361\u58f3\uff0c\u6280\u672f\u96be\u9898\u5feb\u901f\u54cd\u5e94
        • \ud83d\ude80 \u4f18\u5148\u6280\u672f\u652f\u6301 \u2014\u2014 VIP\u7528\u6237\u4e13\u5c5e\u901a\u9053\uff0c\u6bd4\u516c\u5f00\u6e20\u9053\u66f4\u5feb\u83b7\u5f97\u5b98\u65b9\u89e3\u7b54
        • \ud83d\udca1 \u6df1\u5ea6\u4ea4\u6d41\u5708\u5b50 \u2014\u2014 \u4e0e\u6838\u5fc3\u7528\u6237\u3001\u8d44\u6df1\u5f00\u53d1\u8005\u540c\u884c\uff0c\u63a2\u8ba8\u9ad8\u9636\u6280\u5de7\u4e0e\u9879\u76ee\u5b9e\u6218

        QPython \u56e2\u961f\u4f1a\u5b9a\u671f\u5728\u793e\u533a\u4e2d\u66f4\u65b0\u9879\u76ee\u8fdb\u5c55\uff0c\u6b22\u8fce\u5173\u6ce8\uff01

        "},{"location":"editor-guide/","title":"\u4f7f\u7528\u6700\u4f73\u5f00\u53d1\u65b9\u5f0f","text":""},{"location":"editor-guide/#qeditor","title":"\u4ece QEditor \u5f00\u53d1","text":"

        QEditor \u662f QPython \u7684\u5185\u7f6e\u7f16\u8f91\u5668\uff0c\u652f\u6301 Python / HTML \u8bed\u6cd5\u9ad8\u4eae\u3002

        QEditor \u7684\u4e3b\u8981\u529f\u80fd

        • \u7f16\u8f91/\u67e5\u770b\u7eaf\u6587\u672c\u6587\u4ef6\uff0c\u5982 Python\u3001Lua\u3001HTML\u3001Javascript \u7b49

        • \u7f16\u8f91\u548c\u8fd0\u884c Python \u811a\u672c & Python \u8bed\u6cd5\u9ad8\u4eae

        • \u7f16\u8f91\u548c\u8fd0\u884c Shell \u811a\u672c

        • \u4f7f\u7528\u5185\u7f6e HTML \u6d4f\u89c8\u5668\u9884\u89c8 HTML

        • \u6309\u5173\u952e\u5b57\u641c\u7d22\u3001\u4ee3\u7801\u7247\u6bb5\u3001\u4ee3\u7801\u5206\u4eab

        \u60a8\u53ef\u4ee5\u76f4\u63a5\u5728 QEditor \u4e2d\u8fd0\u884c QPython \u811a\u672c\uff0c\u56e0\u6b64\u5728\u79fb\u52a8\u65f6\u8fd9\u662f QPython \u5f00\u53d1\u6700\u65b9\u4fbf\u7684\u65b9\u5f0f\u3002

        "},{"location":"editor-guide/#_2","title":"\u901a\u8fc7\u6d4f\u89c8\u5668\u5f00\u53d1","text":"

        QPython \u6709\u4e00\u4e2a\u5185\u7f6e\u811a\u672c qedit4web.py\uff0c\u5f53\u60a8\u70b9\u51fb\u5f00\u59cb\u6309\u94ae\u5e76\u9009\u62e9\"\u8fd0\u884c\u672c\u5730\u811a\u672c\"\u65f6\u53ef\u4ee5\u770b\u5230\u5b83\u3002

        \u8fd0\u884c\u540e\uff0c\u60a8\u53ef\u4ee5\u770b\u5230\u7ed3\u679c\u3002

        \u7136\u540e\uff0c\u60a8\u53ef\u4ee5\u901a\u8fc7 PC/\u7b14\u8bb0\u672c\u7535\u8111\u7684\u6d4f\u89c8\u5668\u8bbf\u95ee\u8be5\u7f51\u5740\u8fdb\u884c\u5f00\u53d1\uff0c\u5982\u4e0b\u56fe\u6240\u793a\u3002

        \u9009\u62e9\u67d0\u4e2a\u9879\u76ee\u6216\u811a\u672c\u540e\uff0c\u60a8\u53ef\u4ee5\u5f00\u59cb\u5f00\u53d1

        \u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\u7f16\u5199\u6d4f\u89c8\u5668\u4ee3\u7801\uff0c\u7136\u540e\u5728 Android \u624b\u673a\u4e0a\u8fd0\u884c\u3002\u975e\u5e38\u65b9\u4fbf\u3002

        "},{"location":"editor-guide/#_3","title":"\u4ece\u60a8\u7684\u7535\u8111\u5f00\u53d1","text":"

        \u9664\u4e86\u4e0a\u8ff0\u65b9\u6cd5\uff0c\u60a8\u8fd8\u53ef\u4ee5\u7528\u81ea\u5df1\u7684\u65b9\u5f0f\u5f00\u53d1\u811a\u672c\uff0c\u7136\u540e\u901a\u8fc7\u5185\u7f6e\u7684 FTP \u670d\u52a1\u5c06\u5176\u4e0a\u4f20\u5230\u624b\u673a\uff0c\u7528 QPython \u8fd0\u884c\u5b83\u3002

        "},{"location":"external-api/","title":"QPython \u5f00\u653e API","text":"

        QPython \u6709\u4e00\u4e2a\u5f00\u653e\u7684 activity\uff0c\u5141\u8bb8\u60a8\u4ece\u5916\u90e8\u8fd0\u884c qpython\u3002

        MPyAPI \u7684\u5b9a\u4e49\u5982\u4e0b\uff1a

            <activity\n        android:name=\"org.qpython.qpylib.MPyApi\"\n        android:label=\"@string/qpy_run_with_share\"\n        android:screenOrientation=\"user\"\n        android:configChanges=\"orientation|keyboardHidden\"\n        android:exported=\"true\">\n        <intent-filter>\n            <action android:name=\"org.qpython.qpylib.action.MPyApi\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.LAUNCHER\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.VIEW\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.BROWSABLE\" />\n            <data android:scheme=\"http\" />\n            <data android:scheme=\"https\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"text/plain\"/>\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"image/*\"/>\n        </intent-filter>\n    </activity>\n

        \u56e0\u6b64\uff0c\u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\uff1a

        "},{"location":"external-api/#qpython","title":"\u5c06\u5185\u5bb9\u5206\u4eab\u5230 QPython \u7684\u811a\u672c","text":"

        \u60a8\u53ef\u4ee5\u5728\u67d0\u4e2a\u5e94\u7528\u4e2d\u9009\u62e9\u4e00\u4e9b\u5185\u5bb9\uff0c\u7136\u540e\u5206\u4eab\u5230 qpython \u7684\u811a\u672c\uff0c\u4e4b\u540e\u60a8\u53ef\u4ee5\u4f7f\u7528 sys.argv[2] \u5904\u7406\u8fd9\u4e9b\u5185\u5bb9

        \u5728 YouTube \u4e0a\u89c2\u770b\u6f14\u793a\u89c6\u9891

        "},{"location":"external-api/#qpython_1","title":"\u4ece\u60a8\u81ea\u5df1\u7684\u5e94\u7528\u7a0b\u5e8f\u8fd0\u884c QPython \u7684\u811a\u672c","text":"

        \u60a8\u53ef\u4ee5\u901a\u8fc7\u8c03\u7528\u6b64 activity \u5728\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u4e2d\u8c03\u7528 QPython \u6765\u8fd0\u884c\u67d0\u4e9b\u811a\u672c\u6216 Python \u4ee3\u7801\uff0c\u793a\u4f8b\u5982\u4e0b\uff1a

        // \u5c55\u793a\u5982\u4f55\u8c03\u7528 qpython API \u7684\u4ee3\u7801\u793a\u4f8b\nString extPlgPlusName = \"org.qpython.qpy\";          // QPython \u5305\u540d\nIntent intent = new Intent();\nintent.setClassName(extPlgPlusName, \"org.qpython.qpylib.MPyApi\");\nintent.setAction(extPlgPlusName + \".action.MPyApi\");\n\nBundle mBundle = new Bundle();\nmBundle.putString(\"app\", \"myappid\");\nmBundle.putString(\"act\", \"onPyApi\");\nmBundle.putString(\"flag\", \"onQPyExec\"); // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u4efb\u610f\u5b57\u7b26\u4e32\u6807\u5fd7\nmBundle.putString(\"param\", \"\");         // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u53c2\u6570\u5b57\u7b26\u4e32\n\n/*\n* \u6211\u4eec\u5c06\u8fd0\u884c\u7684 Python \u4ee3\u7801\n*/\nString code = \"import androidhelper\\n\" +\n            \"droid = androidhelper.Android()\\n\" +\n            \"line = droid.dialogGetInput()\\n\" +\n            \"s = 'Hello %s' % line.result\\n\" +\n            \"droid.makeToast(s)\\n\"\n\nmBundle.putString(\"pycode\", code);\nintent.putExtras(mBundle);\nstartActivityForResult(intent, SCRIPT_EXEC_PY);\n...\n\n// \u60a8\u53ef\u4ee5\u5728 onActivityResult \u4e2d\u5904\u7406 qpython \u8c03\u7528\u7ed3\u679c\n@Override\nprotected void onActivityResult(int requestCode, int resultCode, Intent data) {\n    if (requestCode == SCRIPT_EXEC_PY) {\n        if (data!=null) {\n            Bundle bundle = data.getExtras();\n            String flag = bundle.getString(\"flag\");\n            String param = bundle.getString(\"param\");\n            String result = bundle.getString(\"result\"); // \u60a8\u7684 Pycode \u751f\u6210\u7684\u7ed3\u679c\n            Toast.makeText(this, \"onQPyExec: return (\"+result+\")\", Toast.LENGTH_SHORT).show();\n        } else {\n            Toast.makeText(this, \"onQPyExec: data is null\", Toast.LENGTH_SHORT).show();\n\n        }\n    }\n}\n

        \u4ece github \u68c0\u51fa\u4e00\u4e2a\u5b8c\u6574\u9879\u76ee

        \u8fd8\u6709\u4e00\u4e2a\u751f\u4ea7\u5e94\u7528\u7a0b\u5e8f - \u9762\u5411 Tasker \u7684 QPython \u63d2\u4ef6

        "},{"location":"getting-started/","title":"QPython\uff1a\u5165\u95e8\u6307\u5357","text":"

        \u672c\u6307\u5357\u5c06\u4ecb\u7ecd QPython \u7684\u529f\u80fd\u5e76\u5e2e\u52a9\u60a8\u5feb\u901f\u5165\u95e8\u3002

        "},{"location":"getting-started/#qpython_1","title":"QPython \u6982\u8ff0","text":"

        \u4e3a\u4ec0\u4e48\u9009\u62e9 QPython\uff1f

        \u667a\u80fd\u624b\u673a\u5df2\u6210\u4e3a\u4eba\u4eec\u5fc5\u5907\u7684\u4fe1\u606f\u548c\u6280\u672f\u52a9\u624b\uff0c\u4e00\u4e2a\u7075\u6d3b\u7684\u89e3\u91ca\u5668\u5f15\u64ce\u53ef\u4ee5\u5e2e\u52a9\u60a8\u9ad8\u6548\u5b8c\u6210\u5927\u90e8\u5206\u5de5\u4f5c\uff0c\u65e0\u9700\u590d\u6742\u7684\u5f00\u53d1\u8fc7\u7a0b\u3002

        QPython \u63d0\u4f9b\u4e86 \u60ca\u4eba\u7684\u5f00\u53d1\u4f53\u9a8c\u2014\u2014\u501f\u52a9\u5b83\u7684\u5e2e\u52a9\uff0c\u60a8\u53ef\u4ee5\u8f7b\u677e\u5b9e\u73b0\u7a0b\u5e8f\uff0c\u65e0\u9700\u590d\u6742\u7684 IDE \u5b89\u88c5\u3001\u7f16\u8bd1\u6216\u6253\u5305\u8fc7\u7a0b\u3002

        "},{"location":"getting-started/#qpython_2","title":"QPython \u7248\u672c","text":"

        \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

        • QPython \u2013 \u7531 QPython \u56e2\u961f\u7ef4\u62a4\u7684\u4e3b\u8981\u7248\u672c\uff0c\u5177\u5907 AI \u529f\u80fd\uff0c\u53ef\u5728 Google Play \u7b49\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d
        • QPython+ \u2013 \u7531\u5f00\u6e90\u8d21\u732e\u8005\u63a8\u51fa\u7684\u793e\u533a\u7248\uff0c\u63d0\u4f9b\u5404\u79cd\u65b0\u7279\u6027
        • QPython Plus \u2013 \u6269\u5c55\u6743\u9650\u7248\u672c\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff09
        "},{"location":"getting-started/#_1","title":"\u4e3b\u8981\u7279\u6027","text":"
        • \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668 - \u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51
        • QSL4A \u96c6\u6210 - \u4f7f\u7528 Python \u63a7\u5236 Android \u786c\u4ef6\u548c API
        • GenAI \u80fd\u529b\u96c6\u6210 - \u652f\u6301\u672c\u5730\u8fd0\u884c\u7684 LLM\u3001OpenAI \u7b49\u5404\u79cd LLM \u5e93\uff0c\u4ee5\u53ca\u53ef\u5728 QPython \u4e0a\u8fdb\u884c Vibe Coding \u5f00\u53d1\u7684 AIPyApp
        • \u6269\u5c55\u5305\u5b89\u88c5 - \u652f\u6301\u901a\u8fc7 QPYPI \u548c pip \u5b89\u88c5\u6269\u5c55\u5305
        • \u5185\u7f6e\u7f16\u8f91\u5668 - \u8bed\u6cd5\u9ad8\u4eae\u548c\u4ee3\u7801\u7f16\u8f91
        • \u591a\u79cd\u8fd0\u884c\u6a21\u5f0f - \u9664\u63a7\u5236\u53f0\u7a0b\u5e8f\u5916\uff0c\u8fd8\u652f\u6301 Android \u539f\u751f UI\uff08\u901a\u8fc7 QSL4A \u63a5\u53e3\uff09\u4ee5\u53ca Pygame / Turtle / Tkinter \u7b49\u8fd0\u884c\u65b9\u5f0f
        "},{"location":"getting-started/#1","title":"1. \u4eea\u8868\u76d8","text":"

        \u5b89\u88c5 QPython \u540e\uff0c\u70b9\u51fb\u5176\u56fe\u6807\u542f\u52a8\u3002\u60a8\u5c06\u770b\u5230\u5e26\u6709 QPython \u6807\u5fd7\u548c\u4ee5\u4e0b\u529f\u80fd\u7684\u4e3b\u4eea\u8868\u76d8\uff1a

        "},{"location":"getting-started/#_2","title":"\u4eea\u8868\u76d8\u529f\u80fd","text":"

        QPython \u4eea\u8868\u76d8\u63d0\u4f9b\u5bf9\u6240\u6709\u4e3b\u8981\u529f\u80fd\u7684\u5feb\u901f\u8bbf\u95ee\uff1a

        • \u7ec8\u7aef \u2014 \u8bbf\u95ee Python \u63a7\u5236\u53f0\u548c shell \u4ee5\u76f4\u63a5\u6267\u884c\u547d\u4ee4
        • Notebook \u2014 \u7528\u4e8e\u6570\u636e\u5206\u6790\u548c\u5b9e\u9a8c\u7684\u4ea4\u4e92\u5f0f Jupyter \u98ce\u683c\u7b14\u8bb0\u672c
        • \u7f16\u8f91\u5668 \u2014 \u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668\uff0c\u5177\u6709\u8bed\u6cd5\u9ad8\u4eae\u529f\u80fd\uff0c\u7528\u4e8e\u7f16\u5199 Python \u811a\u672c
        • \u8d44\u6e90\u7ba1\u7406\u5668 \u2014 \u6d4f\u89c8\u548c\u7ba1\u7406\u60a8\u7684\u6587\u4ef6\u3001\u811a\u672c\u548c\u9879\u76ee
        • QPYPI \u2014 \u5b89\u88c5 Python \u5305\u548c\u6269\u5c55\u3002\u8be6\u89c1 QPYPI \u6307\u5357
        • \u8bbe\u7f6e \u2014 \u914d\u7f6e QPython \u9996\u9009\u9879\u548c\u8fd0\u884c\u9009\u9879
        • \u793e\u533a \u2014 \u8bbf\u95ee QPython \u793e\u533a\u8d44\u6e90\u3001\u8bba\u575b\u548c\u5e2e\u52a9
        • \u8bfe\u7a0b \u2014 \u8bbf\u95ee Python \u7f16\u7a0b\u7684\u5b66\u4e60\u6750\u6599\u548c\u6559\u7a0b

        \u70b9\u51fb\u4efb\u4f55\u56fe\u6807\u4ee5\u8bbf\u95ee\u76f8\u5e94\u7684\u529f\u80fd\u3002

        "},{"location":"getting-started/#2","title":"2. \u7ec8\u7aef\u548c\u7f16\u8f91\u5668","text":""},{"location":"getting-started/#_3","title":"\u7ec8\u7aef","text":"

        \u7ec8\u7aef\u63d0\u4f9b Python \u63a7\u5236\u53f0\uff0c\u652f\u6301\uff1a - \u63a2\u7d22\u5bf9\u8c61\u5c5e\u6027 - \u6d4b\u8bd5\u8bed\u6cd5\u548c\u60f3\u6cd5 - \u76f4\u63a5\u6267\u884c\u547d\u4ee4

        \u4f7f\u7528\u52a0\u53f7\u6309\u94ae\uff081\uff09\u6253\u5f00\u65b0\u7ec8\u7aef\u6807\u7b7e\u9875\uff0c\u901a\u8fc7\u4e0b\u62c9\u83dc\u5355\uff082\uff09\u5207\u6362\uff0c\u5e76\u4f7f\u7528\u5173\u95ed\u6309\u94ae\uff083\uff09\u5173\u95ed\u3002

        "},{"location":"getting-started/#_4","title":"\u7f16\u8f91\u5668","text":"

        \u7f16\u8f91\u5668\u5e95\u90e8\u529f\u80fd\u680f\u5305\u542b\u4ee5\u4e0b\u5de5\u5177\uff08\u4ece\u5de6\u5230\u53f3\uff09\uff1a

        • \u5207\u6362\u5feb\u6377\u8f93\u5165\uff08\u5305\u542b def / if / else / elif / class \u7b49\u5173\u952e\u8bcd\uff09
        • \u9501\u5b9a\uff08\u9632\u6b62\u8bef\u89e6\uff09
        • \u8df3\u8f6c
        • \u4fdd\u5b58
        • \u8fd0\u884c
        • \u641c\u7d22
        • \u64a4\u9500
        • \u91cd\u505a
        • \u53e6\u5b58
        • \u6700\u8fd1\u6587\u4ef6
        • \u4ee3\u7801\u7247\u6bb5

        \u91cd\u8981\u63d0\u793a\uff1a \u4fdd\u5b58\u65f6\u8bf7\u624b\u52a8\u6dfb\u52a0 .py \u6269\u5c55\u540d\uff0c\u56e0\u4e3a\u7f16\u8f91\u5668\u4e0d\u4f1a\u81ea\u52a8\u6dfb\u52a0\u3002

        "},{"location":"getting-started/#3","title":"3. \u8d44\u6e90\u7ba1\u7406\u5668\uff08\u6587\u4ef6\u7ba1\u7406\uff09","text":"

        \u901a\u8fc7 \u8d44\u6e90\u7ba1\u7406\u5668 \u8bbf\u95ee\u811a\u672c\u548c\u9879\u76ee\uff0c\u652f\u6301\u6d4f\u89c8\u3001\u7ec4\u7ec7\u548c\u7ba1\u7406\u6240\u6709 Python \u6587\u4ef6\u3002

        "},{"location":"getting-started/#_5","title":"\u811a\u672c","text":"

        \u811a\u672c\u662f\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/scripts3/ \u4e2d\u7684\u5355\u4e2a Python \u6587\u4ef6\uff08\u9488\u5bf9 Python 3\uff09\u3002

        \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u811a\u672c - \u6253\u5f00 \u2014 \u4f7f\u7528\u5185\u7f6e\u7f16\u8f91\u5668\u7f16\u8f91 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u811a\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u811a\u672c

        "},{"location":"getting-started/#_6","title":"\u9879\u76ee","text":"

        \u9879\u76ee\u662f\u5305\u542b main.py \u4f5c\u4e3a\u5165\u53e3\u70b9\u7684\u76ee\u5f55\u3002\u60a8\u53ef\u4ee5\u5728\u540c\u4e00\u76ee\u5f55\u4e2d\u5305\u542b\u5176\u4ed6\u4f9d\u8d56\u9879\u548c\u8d44\u6e90\u3002\u5c06\u9879\u76ee\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/projects3/ \u4e2d\u3002

        "},{"location":"getting-started/#_7","title":"\u7b14\u8bb0\u672c","text":"

        Jupyter \u98ce\u683c\u7684\u7b14\u8bb0\u672c\u4e5f\u901a\u8fc7\u8d44\u6e90\u7ba1\u7406\u5668\u8fdb\u884c\u7ba1\u7406\uff0c\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/notebooks/ \u4e2d\u3002

        \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u7b14\u8bb0\u672c - \u6253\u5f00 \u2014 \u63a2\u7d22\u7b14\u8bb0\u672c\u5185\u5bb9 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u7b14\u8bb0\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u7b14\u8bb0\u672c

        "},{"location":"getting-started/#4","title":"4. \u5e93","text":"

        \u901a\u8fc7\u5b89\u88c5\u7b2c\u4e09\u65b9\u5e93\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

        "},{"location":"getting-started/#_8","title":"\u5305\u5b89\u88c5\u65b9\u6cd5","text":"

        QPYPI\uff08\u63a8\u8350\uff09

        \u4ece QPYPI \u5b89\u88c5\u9884\u7f16\u8bd1\u7684\u5e93\uff0c\u5305\u62ec numpy\u3001scipy \u7b49\u79d1\u5b66\u5305\u3002

        \u8be6\u89c1 QPYPI \u6307\u5357\u3002

        PIP \u5ba2\u6237\u7aef

        \u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216 QPYPI \u754c\u9762\u5b89\u88c5\u7eaf Python \u5e93\uff1a

        pip install requests\n

        \u9884\u7f16\u8bd1\u5305

        \u5bf9\u4e8e\u5177\u6709 C/C++/Rust \u4f9d\u8d56\u7684\u5305\uff0c\u4f7f\u7528 QPython \u7684\u9884\u7f16\u8bd1\u5305\uff1a

        pip install numpy-qpython\npip install scipy-aipy\n

        \u8be6\u89c1 QPYPI \u6307\u5357 \u83b7\u53d6\u53ef\u7528\u5305\u7684\u5b8c\u6574\u5217\u8868\u3002

        \u624b\u52a8\u5b89\u88c5

        \u60a8\u4e5f\u53ef\u4ee5\u5c06\u5e93\u590d\u5236\u5230 /storage/emulated/0/Android/data/org.qpython.qpy/files/lib/python3.12/site-packages/\u3002

        "},{"location":"getting-started/#5","title":"5. \u8fd0\u884c\u6a21\u5f0f","text":"

        QPython \u652f\u6301\u591a\u79cd\u8fd0\u884c\u6a21\u5f0f\u4ee5\u6ee1\u8db3\u4e0d\u540c\u7684\u7528\u4f8b\uff1a

        "},{"location":"getting-started/#_9","title":"\u63a7\u5236\u53f0\u6a21\u5f0f","text":"

        \u5e38\u89c4 Python \u811a\u672c\u7684\u9ed8\u8ba4\u6a21\u5f0f\u3002

        "},{"location":"getting-started/#qsl4a","title":"QSL4A \u6a21\u5f0f","text":"

        \u901a\u8fc7 QSL4A \u5e93\u8c03\u7528 Android API \u7684\u811a\u672c\u3002

        import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello Android!')\n

        \u8be6\u89c1 QSL4A \u6587\u6863 \u83b7\u53d6\u5b8c\u6574\u7684 API \u53c2\u8003\u3002

        "},{"location":"getting-started/#webapp","title":"WebApp \u6a21\u5f0f","text":"

        \u4f7f\u7528\u540e\u7aef\u670d\u52a1\u5668\u521b\u5efa\u57fa\u4e8e Web \u7684\u5e94\u7528\u7a0b\u5e8f\u3002\u9700\u5728\u811a\u672c\u5f00\u5934\u6dfb\u52a0\u4ee5\u4e0b\u4e24\u884c headers\uff1a

        #qpy:webapp:<\u9879\u76ee\u540d>\n#qpy://localhost:<web\u670d\u52a1\u4fa6\u542c\u7684\u7aef\u53e3>/<\u9ed8\u8ba4\u4e3b\u8def\u5f84>\n

        \u4f8b\u5982\uff1a

        #qpy:webapp:Hello QPython\n#qpy://localhost:8080/hello\n\nfrom bottle import route, run, Bottle\n\napp = Bottle()\n\n@route('/hello')\ndef hello():\n    return '<h1>Hello from QPython!</h1>'\n\nrun(app, host='localhost', port=8080)\n
        "},{"location":"getting-started/#q","title":"Q \u6a21\u5f0f\uff08\u65e0\u63a7\u5236\u53f0\u6a21\u5f0f\uff09","text":"

        \u9759\u9ed8\u6a21\u5f0f\u8fd0\u884c\u811a\u672c\uff0c\u4e0d\u663e\u793a\u63a7\u5236\u53f0\u3002\u9700\u5728\u811a\u672c\u5f00\u5934\u6dfb\u52a0 header\uff1a

        #qpy:quiet\n\nimport time\n\nwhile True:\n    # \u60a8\u7684\u540e\u53f0\u4efb\u52a1\n    time.sleep(60)\n
        \u5982\u679c\u9700\u8981\u8fd0\u884c\u5e26 GUI \u7684 QSL4A \u7a0b\u5e8f\u4e14\u4e0d\u5e0c\u671b\u663e\u793a\u63a7\u5236\u53f0\u4fe1\u606f\uff0c\u63a8\u8350\u4f7f\u7528\u6b64\u6a21\u5f0f\u3002

        "},{"location":"getting-started/#6","title":"6. \u793e\u533a\u4e0e\u652f\u6301","text":"

        \u8bbf\u95ee QPython.org \u83b7\u53d6\u6587\u6863\u3001\u7528\u6237\u793e\u533a\u53ca\u5e2e\u52a9\u95ee\u7b54\u3002

        \u793e\u533a\u94fe\u63a5\uff1a - Facebook \u7fa4\u7ec4 - GitHub - \u95ee\u9898\u53cd\u9988

        \u4e0b\u4e00\u6b65\uff1a - \u5c1d\u8bd5 Hello World \u6559\u7a0b - \u63a2\u7d22 QSL4A API \u4ee5\u96c6\u6210 Android - \u4e86\u89e3 QPython \u7248\u672c

        "},{"location":"getting-started/#_10","title":"\u89c6\u9891\u4ecb\u7ecd","text":""},{"location":"getting-started/#_11","title":"\u4e0b\u4e00\u6b65","text":"

        \u5982\u679c\u60a8\u5df2\u7ecf\u521d\u6b65\u4e86\u89e3\u4e86 QPython \u7684\u529f\u80fd\uff0c\u6b22\u8fce\u5f00\u59cb\u4f53\u9a8c\u7f16\u7a0b\u7684\u4e50\u8da3\uff01\u8bd5\u8bd5 Hello World \u6559\u7a0b \u8fc8\u51fa\u60a8\u7684\u7b2c\u4e00\u6b65\u3002

        "},{"location":"qpypi-guide/","title":"QPYPI","text":"

        \u60a8\u53ef\u4ee5\u901a\u8fc7\u5b89\u88c5\u5305\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

        "},{"location":"qpypi-guide/#_1","title":"\u5305\u5b89\u88c5\u652f\u6301","text":""},{"location":"qpypi-guide/#python","title":"\u7eaf Python \u5305","text":"

        QPython \u652f\u6301\u4f7f\u7528\u7eaf Python \u5f00\u53d1\u7684 Python \u5305\u3002\u60a8\u53ef\u4ee5\u76f4\u63a5\u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216\u4eea\u8868\u76d8\u4e0a\u7684 QPYPI \u4f7f\u7528 pip install \u5b89\u88c5\u8fd9\u4e9b\u5305\u3002

        "},{"location":"qpypi-guide/#_2","title":"\u9884\u7f16\u8bd1\u5305","text":"

        \u5982\u679c\u67d0\u4e9b\u5305\uff08\u6216\u5b83\u4eec\u7684\u4f9d\u8d56\uff09\u662f\u7528 Rust/C/C++ \u5f00\u53d1\u7684\uff0cQPython \u65e0\u6cd5\u76f4\u63a5\u652f\u6301\u5b83\u4eec\uff0c\u56e0\u4e3a QPython \u4e0a\u6ca1\u6709\u7f16\u8bd1\u5668\u5de5\u5177\u94fe\u652f\u6301\u3002\u4f46\u662f\uff0cQPython \u56e2\u961f\u5df2\u7ecf\u9884\u7f16\u8bd1\u4e86\u4e00\u4e9b\u5e38\u7528\u5305\uff0c\u5e76\u5728 QPython \u7684 QPYPI/Extensions \u4e2d\u53d1\u5e03\uff0c\u4f9b\u7528\u6237\u8f7b\u677e\u5b89\u88c5\u3002

        "},{"location":"qpypi-guide/#_3","title":"\u5b89\u88c5\u9884\u7f16\u8bd1\u5305","text":"

        \u60a8\u53ef\u4ee5\u901a\u8fc7\u4ee5\u4e0b\u65b9\u5f0f\u5b89\u88c5\u9884\u7f16\u8bd1\u5305\uff1a

        1. \u901a\u8fc7 QPython \u5e94\u7528\uff1a\u76f4\u63a5\u4ece QPython \u5e94\u7528\u5185\u7684 QPYPI \u6216 Extensions \u5b89\u88c5
        2. \u901a\u8fc7 PyPI\uff1a\u8bbf\u95ee https://pypi.org/user/qpythonx/ \u67e5\u770b\u53ef\u7528\u7684\u5305
        3. \u901a\u8fc7 pip \u547d\u4ee4\uff1a
        4. pip install xxx-qpython - \u5e26 -qpython \u540e\u7f00\u7684\u5305
        5. pip install xxx-aipy - \u5e26 -aipy \u540e\u7f00\u7684\u5305\uff08\u901a\u5e38\u662f AI/ML \u76f8\u5173\u7684\u5305\uff09

        \u6ce8\u610f\uff1a\u6211\u4eec\u901a\u5e38\u6839\u636e\u5305\u7684\u9884\u671f\u7528\u9014\u6dfb\u52a0\u8fd9\u4e9b\u540e\u7f00\u4e4b\u4e00\u3002

        "},{"location":"qpypi-guide/#_4","title":"\u8bf7\u6c42\u65b0\u5305","text":"

        \u5982\u679c\u60a8\u9700\u8981\u5f53\u524d\u4e0d\u652f\u6301\u7684\u5305\uff1a

        • \u5728 qpython.org \u9879\u76ee \u4e2d\u63d0\u51fa\u95ee\u9898
        • QPython \u56e2\u961f\u5c06\u8003\u8651\u9884\u7f16\u8bd1\u5e76\u5c06\u5176\u6dfb\u52a0\u5230\u4ed3\u5e93\u4e2d

        \u83b7\u53d6\u66f4\u591a\u5e2e\u52a9\u548c\u53c2\u4e0e\u793e\u533a\u7684\u65b9\u5f0f\uff0c\u8bf7\u53c2\u9605 \u793e\u533a\u4e0e\u53cd\u9988 \u90e8\u5206\u3002

        \u6ce8\u610f\uff1a\u7531\u4e8e\u4e0d\u540c\u7684\u8ba1\u7b97\u673a\u67b6\u6784\uff0c\u6211\u4eec\u65e0\u6cd5\u4fdd\u8bc1 QPYPI \u5305\u542b PyPI \u4e0a\u7684\u6240\u6709\u5305\u3002

        "},{"location":"qpython-x/","title":"QPython \u7248\u672c","text":"

        QPython \u662f Android \u7684 Python \u5f15\u64ce\u3002\u5b83\u5305\u542b\u4ee4\u4eba\u60ca\u53f9\u7684\u529f\u80fd\uff0c\u5982 Python \u89e3\u91ca\u5668\u3001\u8fd0\u884c\u73af\u5883\u3001\u7f16\u8f91\u5668\u3001QPYI \u548c\u96c6\u6210\u7684 SL4A\u3002\u5b83\u8ba9\u60a8\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 Android \u4e0a\u4f7f\u7528 Python\u3002\u800c\u4e14\u5b83\u662f\u514d\u8d39\u7684\u3002

        QPython \u5df2\u7ecf\u5728\u5168\u7403\u62e5\u6709\u6570\u767e\u4e07\u7528\u6237\uff0c\u4e5f\u662f\u4e00\u4e2a\u5f00\u6e90\u9879\u76ee\u3002

        \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

        "},{"location":"qpython-x/#qpython_1","title":"QPython","text":"

        \u6807\u51c6\u7248\uff1a\u9488\u5bf9 AI \u6027\u80fd\u548c\u901a\u7528\u5e94\u7528\u5546\u5e97\u517c\u5bb9\u6027\u4f18\u5316

        \u4e3b\u8981\u7248\u672c\uff0c\u53ef\u5728 Google Play \u548c\u5176\u4ed6\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002\u6b64\u7248\u672c\u4e13\u6ce8\u4e8e AI \u529f\u80fd\uff0c\u4f7f AI \u65f6\u4ee3\u7528\u6237\u66f4\u5bb9\u6613\u5b66\u4e60\u548c\u4f7f\u7528 Python\u3002

        \u4e3b\u8981\u7279\u6027\uff1a - AI \u9a71\u52a8\u7684\u7f16\u7801\u8f85\u52a9\u548c\u5b66\u4e60\u5de5\u5177 - \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668\uff1a\u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51 - \u652f\u6301\u591a\u79cd\u9879\u76ee\u7c7b\u578b\uff1a\u63a7\u5236\u53f0\u3001SL4A\u3001WebApp - \u65b9\u4fbf\u7684\u4e8c\u7ef4\u7801\u8bfb\u53d6\u5668\uff0c\u7528\u4e8e\u5c06\u4ee3\u7801\u4f20\u8f93\u5230\u624b\u673a - QPYPI \u548c\u81ea\u5b9a\u4e49\u4ed3\u5e93\uff0c\u7528\u4e8e\u9884\u7f16\u8bd1 wheel \u5305 -\u6613\u4e8e\u4f7f\u7528\u7684\u8bed\u6cd5\u9ad8\u4eae\u7f16\u8f91\u5668 - \u5b8c\u5584\u7684\u6587\u6863\u548c\u793e\u533a\u652f\u6301

        \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

        \u4e0b\u8f7d\uff1a \u53ef\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

        "},{"location":"qpython-x/#qpython_2","title":"QPython+","text":"

        \u793e\u533a\u7248\uff1a\u516c\u5f00\u652f\u6301\u5404\u79cd\u793e\u533a\u9a71\u52a8\u7684\u529f\u80fd\uff1b\u53ef\u5728\u90e8\u5206\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

        \u793e\u533a\u5f00\u6e90\u7248\u672c\uff08\u6b63\u5728\u89c4\u5212\u548c\u51c6\u5907\u4e2d\uff09\u3002\u6b64\u7248\u672c\u4e13\u4e3a\u60f3\u8981\u53c2\u4e0e QPython \u9879\u76ee\u5f00\u53d1\u7684\u8d21\u732e\u8005\u800c\u8bbe\u8ba1\uff0c\u652f\u6301\u9488\u5bf9\u4e0d\u540c\u5236\u9020\u5546\u7684\u5b9a\u5236\u3002

        \u4e3b\u8981\u7279\u6027\uff1a - \u793e\u533a\u9a71\u52a8\u5f00\u53d1 - \u652f\u6301\u4f9b\u5e94\u5546\u5b9a\u5236 - \u66f4\u7075\u6d3b\u7684\u914d\u7f6e\u9009\u9879 - \u5f00\u653e\u4f9b\u8d21\u732e\u8005\u52a0\u5165\u5f00\u53d1

        \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

        \u4e0b\u8f7d\uff1a \u5c06\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

        \u6ce8\u610f\uff1a \u6b64\u7248\u672c\u76ee\u524d\u6b63\u5728\u89c4\u5212\u51c6\u5907\u4e2d\u3002\u8bf7\u5173\u6ce8\u66f4\u65b0\uff01

        "},{"location":"qpython-x/#qpython-plus","title":"QPython Plus","text":"

        QPython+ \u5b8c\u5168\u8bbf\u95ee\u7248\uff1a\u6388\u4e88\u8c03\u7528\u6240\u6709 Android \u63a5\u53e3\u7684\u5b8c\u6574\u6743\u9650\u3002\u4e0b\u8f7d\u94fe\u63a5\u4ec5\u901a\u8fc7\u5b98\u65b9\u4e91\u76d8\u63d0\u4f9b\u3002

        \u5177\u6709\u6269\u5c55\u6743\u9650\u7684\u7279\u6b8a\u7248\u672c\uff0c\u63d0\u4f9b\u5bf9\u8bbe\u5907\u7684\u6700\u5927\u63a7\u5236\u3002\u7531\u4e8e\u5176\u654f\u611f\u7684\u6743\u9650\u8981\u6c42\uff0c\u6b64\u7248\u672c\u4e0d\u4f1a\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u53d1\u5e03\u3002

        \u4e3b\u8981\u7279\u6027\uff1a - \u5b8c\u6574\u7684 SL4A API \u8bbf\u95ee\uff0c\u5305\u62ec\u654f\u611f\u529f\u80fd - SMS/\u901a\u8bdd\u63a7\u5236 API - \u9ad8\u7ea7\u7cfb\u7edf\u96c6\u6210 - \u6700\u5927\u7684\u8bbe\u5907\u63a7\u5236\u80fd\u529b

        \u6743\u9650\uff1a \u9700\u8981\u5e7f\u6cdb\u7684\u6743\u9650\uff0c\u5305\u62ec\uff1a - \u84dd\u7259 - \u4f4d\u7f6e\uff08GPS\uff09 - \u8bfb\u53d6/\u53d1\u9001\u77ed\u4fe1 - \u6253\u7535\u8bdd - \u76f8\u673a\u548c\u9ea6\u514b\u98ce - \u7cfb\u7edf\u8bbe\u7f6e - \u4ee5\u53ca\u5176\u4ed6\u654f\u611f\u6743\u9650

        \u4e0b\u8f7d\uff1a \u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\u3002\u4ec5\u901a\u8fc7\u7279\u6b8a\u6e20\u9053\u5206\u53d1\u3002

        \u91cd\u8981\u63d0\u793a\uff1a QPython \u4e0d\u4f1a\u5728\u540e\u53f0\u672a\u7ecf\u60a8\u77e5\u6089\u4f7f\u7528\u8fd9\u4e9b\u6743\u9650\u3002\u5982\u679c\u4f7f\u7528 SL4A API \u65f6\u51fa\u73b0\u5f02\u5e38\uff0c\u8bf7\u68c0\u67e5\u7cfb\u7edf\u8bbe\u7f6e\u4e2d\u662f\u5426\u5df2\u542f\u7528\u76f8\u5173\u6743\u9650\u3002

        "},{"location":"tutorial-hello-world/","title":"\u7f16\u5199\"Hello World\"","text":""},{"location":"tutorial-hello-world/#hello-world_1","title":"Hello world","text":"

        \u597d\u7684\uff0c\u5728\u60a8\u5bf9 QPython \u6709\u4e86\u4e00\u5b9a\u7684\u4e86\u89e3\u4e4b\u540e\uff0c\u8ba9\u6211\u4eec\u5728 QPython \u4e2d\u521b\u5efa\u6211\u4eec\u7684\u7b2c\u4e00\u4e2a\u7a0b\u5e8f\u3002\u663e\u7136\uff0c\u5b83\u5c06\u662f helloworld.py\u3002;)

        \u542f\u52a8 QPython\uff0c\u6253\u5f00\u7f16\u8f91\u5668\u5e76\u8f93\u5165\u4ee5\u4e0b\u4ee3\u7801\uff1a

        #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello, QPYTHON!')\n

        \u6beb\u65e0\u7591\u95ee\uff0c\u5b83\u4e0e\u5176\u4ed6\u4efb\u4f55 hello-world \u7a0b\u5e8f\u5e76\u65e0\u4e0d\u540c\u3002\u6267\u884c\u65f6\uff0c\u5b83\u53ea\u662f\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u5f39\u51fa\u6d88\u606f\uff08\u89c1\u9876\u90e8\u622a\u56fe\uff09\u3002\u65e0\u8bba\u5982\u4f55\uff0c\u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684 QPython \u7a0b\u5e8f\u793a\u4f8b\u3002

        "},{"location":"tutorial-hello-world/#_1","title":"\u4ee3\u7801\u7406\u89e3","text":"

        \u5b83\u4ee5 import androidhelper \u5f00\u5934\u2014\u2014\u8fd9\u662f QPython \u4e2d\u6700\u6709\u7528\u7684\u6a21\u5757\uff0c\u5b83\u5c01\u88c5\u4e86 Python \u4e2d\u53ef\u7528\u7684\u51e0\u4e4e\u6240\u6709\u4e0e Android \u7684\u63a5\u53e3\u3002\u4efb\u4f55\u5728 QPython \u4e2d\u5f00\u53d1\u7684\u811a\u672c\u90fd\u4ee5\u8fd9\u4e2a\u8bed\u53e5\u5f00\u5934\uff08\u81f3\u5c11\u5982\u679c\u5b83\u58f0\u79f0\u8981\u4e0e\u7528\u6237\u901a\u4fe1\u7684\u8bdd\uff09\u3002\u5728\u6b64\u5904\u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u5e93 \u548c import \u8bed\u53e5 \u7684\u5185\u5bb9\u3002

        \u63a5\u4e0b\u6765\u6211\u4eec\u521b\u5efa\u4e00\u4e2a droid \u5bf9\u8c61\uff08\u5b9e\u9645\u4e0a\u662f\u4e00\u4e2a\u7c7b\uff09\uff0c\u5b83\u5bf9\u4e8e\u8c03\u7528 RPC \u51fd\u6570\u4ee5\u4e0e Android \u901a\u4fe1\u662f\u5fc5\u8981\u7684\u3002

        \u6211\u4eec\u4ee3\u7801\u7684\u6700\u540e\u4e00\u884c\u8c03\u7528\u4e86\u8fd9\u6837\u7684\u51fd\u6570\uff0cdroid.makeToast()\uff0c\u5b83\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u4e00\u4e2a\u5c0f\u7684\u5f39\u51fa\u6d88\u606f\uff08\"toast\"\uff09\u3002

        \u597d\u7684\uff0c\u8ba9\u6211\u4eec\u6dfb\u52a0\u4e00\u4e9b\u66f4\u591a\u7684\u529f\u80fd\u3002\u8ba9\u5b83\u8be2\u95ee\u7528\u6237\u540d\u5e76\u5411\u7528\u6237\u6253\u62db\u547c\u3002

        "},{"location":"tutorial-hello-world/#_2","title":"\u66f4\u591a\u793a\u4f8b","text":"

        \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 dialogGetInput \u8c03\u7528\u663e\u793a\u4e00\u4e2a\u5e26\u6709\u6807\u9898\u3001\u63d0\u793a\u3001\u7f16\u8f91\u5b57\u6bb5\u548c \u786e\u5b9a \u548c \u53d6\u6d88 \u6309\u94ae\u7684\u7b80\u5355\u5bf9\u8bdd\u6846\u3002\u7528\u4ee5\u4e0b\u4ee3\u7801\u66ff\u6362\u60a8\u7684\u6700\u540e\u4e00\u884c\u4ee3\u7801\u5e76\u5c06\u5176\u4fdd\u5b58\u4e3a hello1.py\uff1a

        #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\n

        \u597d\u7684\uff0c\u6211\u8ba4\u4e3a\u5b83\u5e94\u8be5\u8fd4\u56de\u4efb\u4f55\u54cd\u5e94\uff0c\u4efb\u4f55\u7528\u6237\u53cd\u5e94\u3002\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u6211\u5199 respond = ...\u3002\u4f46\u8fd9\u4e2a\u8c03\u7528\u5b9e\u9645\u4e0a\u8fd4\u56de\u4ec0\u4e48\uff1f\u8ba9\u6211\u4eec\u68c0\u67e5\u4e00\u4e0b\u3002\u53ea\u9700\u5728\u6700\u540e\u4e00\u884c\u540e\u6dfb\u52a0 print \u8bed\u53e5\uff1a

        #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\n

        \u7136\u540e\u4fdd\u5b58\u5e76\u8fd0\u884c\u5b83...

        \u54ce\u5440\uff01\u6ca1\u6709\u6253\u5370\uff1f\u522b\u62c5\u5fc3\u3002\u53ea\u9700\u62c9\u4e0b\u901a\u77e5\u680f\uff0c\u60a8\u5c31\u4f1a\u770b\u5230\"QPython Program Output: hello1.py\"\u2014\u2014\u70b9\u51fb\u5b83\uff01

        \u5982\u60a8\u6240\u89c1\uff0cdroid.dialogGetInput() \u8fd4\u56de\u4e00\u4e2a\u5305\u542b\u4e09\u4e2a\u5b57\u6bb5\u7684 JSON \u5bf9\u8c61\u3002\u6211\u4eec\u53ea\u9700\u8981\u4e00\u4e2a\u2014\u2014result\uff0c\u5176\u4e2d\u5305\u542b\u7528\u6237\u5b9e\u9645\u8f93\u5165\u7684\u5185\u5bb9\u3002

        \u8ba9\u6211\u4eec\u6dfb\u52a0\u811a\u672c\u7684\u53cd\u5e94\uff1a

        #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nmessage = f'Hello, {respond.result}!'\ndroid.makeToast(message)\n

        \u6700\u540e\u4e24\u884c\uff081\uff09\u683c\u5f0f\u5316\u6d88\u606f\uff0c\uff082\uff09\u4ee5 toast \u5f62\u5f0f\u5411\u7528\u6237\u663e\u793a\u6d88\u606f\u3002\u5982\u679c\u60a8\u4ecd\u7136\u4e0d\u77e5\u9053 f-string \u662f\u4ec0\u4e48\u610f\u601d\uff0c\u8bf7\u53c2\u9605 Python \u6587\u6863\u3002

        \u54c7\uff01\u5b83\u5de5\u4f5c\u4e86\uff01;)

        \u73b0\u5728\u6211\u8981\u5728\u90a3\u91cc\u6dfb\u52a0\u4e00\u4e9b\u903b\u8f91\u3002\u60f3\u4e00\u60f3\uff1a\u5982\u679c\u7528\u6237\u70b9\u51fb \u53d6\u6d88 \u6309\u94ae\uff0c\u6216\u8005\u70b9\u51fb \u786e\u5b9a \u4f46\u5c06\u8f93\u5165\u5b57\u6bb5\u7559\u7a7a\uff0c\u4f1a\u53d1\u751f\u4ec0\u4e48\uff1f

        \u60a8\u53ef\u4ee5\u73a9\u8fd9\u4e2a\u7a0b\u5e8f\uff0c\u68c0\u67e5 respond \u53d8\u91cf\u5728\u6bcf\u79cd\u60c5\u51b5\u4e0b\u5305\u542b\u4ec0\u4e48\u3002

        \u9996\u5148\uff0c\u6211\u60f3\u5c06\u7528\u6237\u8f93\u5165\u7684\u6587\u672c\u653e\u5165\u4e00\u4e2a\u5355\u72ec\u7684\u53d8\u91cf\u4e2d\uff1aname = respond.result\u3002\u7136\u540e\u6211\u68c0\u67e5\u5b83\uff0c\u5982\u679c\u5b83\u5305\u542b\u4efb\u4f55\u771f\u5b9e\u6587\u672c\uff0c\u5b83\u5c06\u88ab\u89c6\u4e3a\u540d\u79f0\u5e76\u7528\u4e8e\u95ee\u5019\u3002\u5426\u5219\uff0c\u5c06\u663e\u793a\u53e6\u4e00\u6761\u6d88\u606f\u3002\u5c06\u7b2c\u4e94\u884c message = f'Hello, {respond.result}!' \u66ff\u6362\u4e3a\u4ee5\u4e0b\u4ee3\u7801\uff1a

        name = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\n

        \u4f7f\u7528\u5de5\u5177\u680f\u4e0a\u7684 < \u548c > \u6309\u94ae\u6765\u7f29\u8fdb/\u53d6\u6d88\u7f29\u8fdb if \u8bed\u53e5\u4e2d\u7684\u884c\uff08\u6216\u8005\u53ea\u9700\u4f7f\u7528\u7a7a\u683c/\u9000\u683c\u952e\uff09\u3002\u60a8\u53ef\u4ee5\u5728 \u6b64\u5904 \u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u7f29\u8fdb\u7684\u5185\u5bb9\uff1bif \u8bed\u53e5\u5728 \u6b64\u5904 \u63cf\u8ff0\u3002

        \u9996\u5148\uff0c\u6211\u4eec\u5c06\u7528\u6237\u8f93\u5165\u653e\u5165 name \u53d8\u91cf\u3002\u7136\u540e\u6211\u4eec\u68c0\u67e5 name \u662f\u5426\u5305\u542b\u4efb\u4f55\u5185\u5bb9\uff1f\u5982\u679c\u7528\u6237\u7559\u7a7a\u884c\u5e76\u70b9\u51fb \u786e\u5b9a\uff0c\u8fd4\u56de\u503c\u662f\u7a7a\u5b57\u7b26\u4e32 ''\u3002\u5982\u679c\u6309\u4e0b\u4e86 \u53d6\u6d88 \u6309\u94ae\uff0c\u8fd4\u56de\u503c\u662f None\u3002\u5728 if \u8bed\u53e5\u4e2d\uff0c\u4e24\u8005\u90fd\u88ab\u89c6\u4e3a\u5047\u3002\u56e0\u6b64\uff0c\u53ea\u6709\u5f53 name \u5305\u542b\u4efb\u4f55\u6709\u610f\u4e49\u7684\u5185\u5bb9\u65f6\uff0cthen \u8bed\u53e5\u624d\u4f1a\u6267\u884c\uff0c\u5e76\u663e\u793a\u95ee\u5019\u8bed\"Hello, ...!\"\u3002\u5982\u679c\u8f93\u5165\u4e3a\u7a7a\uff0c\u7528\u6237\u5c06\u770b\u5230\"Hey! And you're not very polite, %Username%!\"\u6d88\u606f\u3002

        \u597d\u7684\uff0c\u8fd9\u662f\u6574\u4e2a\u7a0b\u5e8f\uff1a

        #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nname = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\ndroid.makeToast(message)\n
        "},{"location":"tutorial-hello-world/#_3","title":"\u8fd0\u884c\u6548\u679c","text":""},{"location":"tutorial-hello-world/#_4","title":"\u4e0b\u4e00\u6b65","text":"

        \u5bf9\u4e8e Python \u65b0\u7528\u6237\uff0c\u63a8\u8350\u5b66\u4e60 Python \u8bed\u6cd5\u5b9e\u8df5 \u8bfe\u7a0b\u6765\u8fdb\u4e00\u6b65\u5b66\u4e60 Python\uff0c\u6216\u8005\u5728 QPython \u7cbe\u9009\u8bfe\u7a0b \u4e2d\u5bfb\u627e\u60f3\u8981\u5b66\u4e60\u7684\u5185\u5bb9\u3002

        "},{"location":"whats-new/","title":"\u66f4\u65b0\u65e5\u5fd7","text":""},{"location":"whats-new/#v392-v393","title":"v3.9.2 / v3.9.3","text":"
        • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
        • \u7f16\u8f91\u5668\u91cd\u5927\u66f4\u65b0\uff0c\u5e26\u6765\u66f4\u6d41\u7545\u7684\u7f16\u8f91\u4f53\u9a8c
        • \u5176\u4ed6\u5404\u79cd\u5c0f\u6539\u8fdb
        "},{"location":"whats-new/#v391","title":"v3.9.1","text":"
        • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
        • \u6269\u5c55\u5305\u73b0\u5728\u652f\u6301 MCP
        • \u9519\u8bef\u4fee\u590d
        "},{"location":"whats-new/#v390","title":"v3.9.0","text":"
        • SDK \u5347\u7ea7\uff0c\u6574\u5408\u6700\u65b0\u7684 Android \u529f\u80fd
        • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
        • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
        • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
        "},{"location":"whats-new/#v3811","title":"v3.8.11","text":"
        • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
        • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
        • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
        "},{"location":"whats-new/#v3810","title":"v3.8.10","text":"
        • \u5185\u7f6e Ollama \u5347\u7ea7\uff1a\u73b0\u5728\u60a8\u53ef\u4ee5\u5728 QPython \u4e2d\u8f7b\u677e\u672c\u5730\u8fd0\u884c Qwen3 / Gemma3 \u6a21\u578b\uff01
        • \u6dfb\u52a0\u4e86\u5f3a\u5927\u7684 MCP \u5e93\uff1a\u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 mcp \u5e93\uff0c\u8ba9\u60a8\u968f\u65f6\u968f\u5730\u643a\u5e26\u5f3a\u5927\u7684 MCP \u529f\u80fd\uff01
        "},{"location":"whats-new/#v389","title":"v3.8.9","text":"

        \u91cd\u5927\u66f4\u65b0\uff01AI \u7f16\u7a0b\u5b8c\u5168\u96c6\u6210\u5230 QPython\uff0c\u8ba9\u60a8\u7684\u7f16\u7a0b\u66f4\u8f7b\u677e\uff01

        • \u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u652f\u6301\uff1a\u65b0\u652f\u6301 AIPyApp\uff0c\u5728 QPython \u4e2d\u5b9e\u73b0\u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u3002\u76ee\u524d\u5904\u4e8e\u6d4b\u8bd5\u9636\u6bb5 - \u52a0\u5165\u6211\u4eec\u7684\u793e\u533a\u83b7\u53d6\u4f7f\u7528\u8bf4\u660e
        • \u65b0 QSL4A \u529f\u80fd\uff1a\u6dfb\u52a0 notebookOpen \u51fd\u6570\uff0c\u652f\u6301\u81ea\u7136\u8bed\u8a00\u63a7\u5236\u6253\u5f00 Notebook \u6587\u4ef6
        • \u5185\u7f6e\u7f16\u8f91\u5668\u5347\u7ea7\uff1a\u589e\u5f3a\u7f16\u8f91\u5668\u529f\u80fd\uff0c\u652f\u6301\u6253\u5f00\u548c\u6d4f\u89c8\u5404\u79cd\u6587\u672c\u6587\u4ef6
        • \u4fbf\u6377\u7684\u6587\u4ef6\u7ba1\u7406\uff1a\u5728\u6587\u4ef6\u7ba1\u7406\u5668\u4e2d\u6dfb\u52a0\u5185\u90e8\u5b58\u50a8\u5165\u53e3\uff0c\u5feb\u901f\u8bbf\u95ee\u60a8\u7684\u6587\u4ef6
        "},{"location":"whats-new/#v388","title":"v3.8.8","text":"
        • \u6587\u4ef6\u8bbf\u95ee\u6743\u9650\u63a7\u5236\u7684\u91cd\u8981\u6539\u8fdb\uff0c\u5141\u8bb8\u7528\u6237\u7075\u6d3b\u5730\u901a\u8fc7 QPython \u7f16\u7a0b\u542f\u7528\u6216\u7981\u7528\u5916\u90e8\u5b58\u50a8\u6587\u4ef6\u7684\u8bbf\u95ee
        • SDK \u5347\u7ea7\uff0c\u589e\u5f3a\u4e86\u5bf9\u65b0\u7248 Android \u7684\u652f\u6301\u548c\u517c\u5bb9\u6027
        • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Anthropic \u548c Google GenAI \u5e93
        "},{"location":"whats-new/#v387","title":"v3.8.7","text":"
        • \u5728\u73b0\u6709 Tkinter \u652f\u6301\u57fa\u7840\u4e0a\uff0c\u5728 Extensions -> Tools \u4e2d\u6dfb\u52a0\u4e86\u4f7f\u7528 Turtle \u7ed8\u5236\u54c6\u5566A\u68a6\u7684\u793a\u4f8b\u4ee3\u7801
        • \u4f18\u5316\u4e86\u624b\u673a\u6743\u9650\u83b7\u53d6\u6d41\u7a0b\uff0c\u63d0\u5347\u7528\u6237\u4f53\u9a8c\u548c\u64cd\u4f5c\u4fbf\u5229\u6027
        • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Google Gen AI \u5e93\uff0c\u65b9\u4fbf\u8bbf\u95ee Gemini Developer API \u548c Vertex AI
        "},{"location":"whats-new/#v386","title":"v3.8.6","text":"
        • Tkinter \u652f\u6301\uff1a\u73b0\u5728\u652f\u6301 Tkinter \u5e93\uff0c\u53ef\u901a\u8fc7 XServer \u8bbf\u95ee\u3002\u8bf7\u8bbf\u95ee www.qpython.org \u7684\u4e91\u76d8\"Extra\"\u94fe\u63a5\u4e0b\u8f7d\u6240\u9700\u6587\u4ef6
        • \u5b58\u50a8\u6743\u9650\u66f4\u65b0\uff1a\u4e3a\u6539\u5584\u7528\u6237\u4f53\u9a8c\uff0c\u6211\u4eec\u6dfb\u52a0\u4e86\u8bfb\u53d6\u624b\u673a\u5b58\u50a8\u7684\u6743\u9650\uff0c\u7528\u4e8e\u8bbf\u95ee\u5b58\u50a8\u5728\u5176\u4ed6\u76ee\u5f55\u4e2d\u7684 Python \u7a0b\u5e8f

        \u6b64\u66f4\u65b0\u540e\uff0cQPython \u548c QPythonPlus\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff0c\u4e13\u4e3a\u9700\u8981\u66f4\u591a\u654f\u611f\u6743\u9650\u7684\u9ad8\u7ea7\u7528\u6237\u8bbe\u8ba1\uff09\u5c06\u4fdd\u6301\u540c\u6b65\u7684\u7248\u672c\u53f7\u3002

        "},{"location":"whats-new/#v352-2025225","title":"v3.5.2 (2025/2/25)","text":"

        \u4e0e\u5f00\u6e90 LLM \u90e8\u7f72\u5de5\u5177 Ollama \u4ee5\u53ca DeepSeek \u5f00\u53d1\u7684 DeepSeek \u5b9e\u73b0\u65e0\u7f1d\u96c6\u6210\uff01

        \u529f\u80fd\uff1a - \u96f6\u95e8\u69db\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5404\u79cd\u5927\u578b\u8bed\u8a00\u6a21\u578b - \u5feb\u901f\u90e8\u7f72 DeepSeek \u7b49\u5c16\u7aef AI \u6a21\u578b - \u4eab\u53d7\u7b80\u7ea6\u7684 API \u8c03\u7528\u4f53\u9a8c - \u6784\u5efa\u5b8c\u5168\u79bb\u7ebf\u7684\u667a\u80fd\u7f16\u7a0b\u73af\u5883

        \u80fd\u529b\uff1a - \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u52a0\u8f7d/\u7ba1\u7406 LLM \u6a21\u578b - \u57fa\u4e8e\u672c\u5730\u8ba1\u7b97\u7684\u5b9e\u65f6\u4f4e\u5ef6\u8fdf\u54cd\u5e94

        "},{"location":"whats-new/#v350","title":"v3.5.0","text":"
        • Python \u5347\u7ea7\u5230 3.12.8
        • \u6539\u8fdb\u4eea\u8868\u76d8\uff0c\u529f\u80fd\u66f4\u6e05\u6670\u3001\u66f4\u4eba\u6027\u5316
        • \u6dfb\u52a0\u4e86\u4f17\u591a\u7b2c\u4e09\u65b9\u5305\uff1aPyTorch / Twisted / Scrapy / FastAPI ...
        "},{"location":"whats-new/#v338","title":"v3.3.8","text":"
        • \u4fee\u590d\u4e86 NumPy \u517c\u5bb9\u6027\u95ee\u9898
        "},{"location":"whats-new/#v335","title":"v3.3.5","text":"
        • \u5347\u7ea7 Python \u5185\u6838\u5230 3.11.9
        • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u4e0d\u663e\u793a\u6a21\u5757\u5b89\u88c5\u72b6\u6001\u7684 bug
        • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u5220\u9664\u6a21\u5757\u5931\u8d25\u7684 bug
        • \u4fee\u590d\u4e86\u5176\u4ed6 bug
        "},{"location":"whats-new/#v334","title":"v3.3.4","text":"
        • \u6dfb\u52a0\u4e86 OpenAI/Langchain/APIGPTCloud AI \u5305
        • \u79fb\u9664\u4e0d\u5fc5\u8981\u7684\u6587\u4ef6\u4ee5\u51cf\u5c11\u5927\u5c0f
        "},{"location":"whats-new/#v325","title":"v3.2.5","text":"
        • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570
        • \u5176\u4ed6\u9519\u8bef\u4fee\u590d
        "},{"location":"whats-new/#v323","title":"v3.2.3","text":"
        • \u66f4\u65b0 Python \u7248\u672c\u5230 3.11.0
        • \u66f4\u65b0 IPython \u7248\u672c\u5230 8.6.0
        • \u66f4\u65b0 pip \u7248\u672c\u5230 22.3.1
        • \u66f4\u65b0\u79d1\u5b66\u8ba1\u7b97\u5305\uff0c\u81ea\u52a8\u8f6f\u94fe\u63a5
        • \u51cf\u5c11\u7a7a\u95f4\u4f7f\u7528
        • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570 + \u5176\u4ed6\u9519\u8bef\u4fee\u590d
        "},{"location":"whats-new/#v318","title":"v3.1.8","text":"
        • \u5728\u7ec8\u7aef\u4e2d\u6dfb\u52a0\u4e86\u64cd\u4f5c\u70ed\u952e
        • \u4fee\u590d\u4e86\u7f16\u8f91\u5668\u5728\u65cb\u8f6c\u65f6\u4e22\u5931\u5185\u5bb9\u7684\u95ee\u9898
        • \u4fee\u590d\u4e86\u5176\u4ed6 bug

        \u5728 Google Play \u4e0b\u8f7d

        "},{"location":"qsl4a/","title":"QSL4A\uff08Android \u811a\u672c\u5c42\uff09API \u6587\u6863","text":"

        QSL4A \u662f QPython \u7684 Android \u811a\u672c\u5c42\uff0c\u5141\u8bb8\u60a8\u4f7f\u7528 Python \u63a7\u5236 Android \u8bbe\u5907\u529f\u80fd\u3002

        "},{"location":"qsl4a/#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a toast \u6d88\u606f\ndroid.makeToast('Hello QPython!')\n\n# \u9707\u52a8\u8bbe\u5907\ndroid.vibrate(500)\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\uff08\u5148\u5f00\u59cb\u76d1\u63a7\uff09\nimport time\ndroid.batteryStartMonitoring()\ntime.sleep(0.5)  # \u7b49\u5f85\u6570\u636e\nbattery = droid.readBatteryData().result\nprint(f\"\u7535\u6c60\uff1a{battery['level']}%\")\n
        "},{"location":"qsl4a/#_2","title":"\u6587\u6863\u7ed3\u6784","text":""},{"location":"qsl4a/#_3","title":"\u6838\u5fc3\u6a21\u5757","text":"
        • Android \u57fa\u7840 - \u6838\u5fc3\u8fde\u63a5\u548c RPC
        • Intent \u7cfb\u7edf - Android Intent \u64cd\u4f5c
        • \u4e8b\u4ef6\u7cfb\u7edf - \u4e8b\u4ef6\u5904\u7406\u548c\u5e7f\u64ad
        "},{"location":"qsl4a/#ui","title":"UI \u7ec4\u4ef6","text":"
        • \u5bf9\u8bdd\u6846 - \u8b66\u62a5\u3001\u8f93\u5165\u3001\u9009\u62e9\u5bf9\u8bdd\u6846
        • \u5168\u5c4f UI - \u81ea\u5b9a\u4e49\u5e03\u5c40 UI
        • \u60ac\u6d6e\u7a97 - \u60ac\u6d6e\u7a97\u53e3
        • \u8f85\u52a9\u529f\u80fd - \u5c4f\u5e55\u81ea\u52a8\u5316
        "},{"location":"qsl4a/#_4","title":"\u7cfb\u7edf","text":"
        • \u7535\u6c60 - \u7535\u6c60\u76d1\u63a7
        • \u4f20\u611f\u5668 - \u8bbe\u5907\u4f20\u611f\u5668
        • \u5e94\u7528 - \u5e94\u7528\u7ba1\u7406
        • \u7cfb\u7edf\u4fe1\u606f - \u8bbe\u5907\u4fe1\u606f
        • \u8bbe\u7f6e - \u7cfb\u7edf\u8bbe\u7f6e
        • \u5524\u9192\u9501 - \u5524\u9192\u9501\u63a7\u5236
        • QPython \u63a5\u53e3 - \u811a\u672c\u6267\u884c
        • Activity \u7ed3\u679c - Activity \u7ed3\u679c\u5904\u7406
        "},{"location":"qsl4a/#_5","title":"\u786c\u4ef6","text":"
        • \u84dd\u7259 - \u84dd\u7259\u64cd\u4f5c
        • \u76f8\u673a - \u62cd\u7167\u548c\u5f55\u50cf
        • \u97f3\u9891/\u5f55\u97f3\u5668 - \u5f55\u97f3
        • \u7f51\u7edc\u6444\u50cf\u5934 - MJPEG \u6d41
        • USB \u4e32\u53e3 - USB \u4e3b\u673a\u4e32\u53e3
        "},{"location":"qsl4a/#_6","title":"\u8fde\u63a5","text":"
        • WiFi - WiFi \u64cd\u4f5c
        • \u4f4d\u7f6e - GPS \u548c\u4f4d\u7f6e
        • \u77ed\u4fe1 - \u77ed\u4fe1\u64cd\u4f5c
        • \u7535\u8bdd - \u6253\u7535\u8bdd\u548c\u6765\u7535\u4fe1\u606f
        • \u8054\u7cfb\u4eba - \u8054\u7cfb\u4eba\u7ba1\u7406
        • \u4fe1\u53f7\u5f3a\u5ea6 - \u4fe1\u53f7\u76d1\u63a7
        • FTP \u670d\u52a1\u5668 - \u5185\u7f6e FTP \u670d\u52a1\u5668
        "},{"location":"qsl4a/#_7","title":"\u5b58\u50a8","text":"
        • DocumentFile - \u6587\u4ef6\u64cd\u4f5c
        • \u526a\u8d34\u677f - \u526a\u8d34\u677f\u64cd\u4f5c
        • \u504f\u597d\u8bbe\u7f6e - \u5171\u4eab\u504f\u597d\u8bbe\u7f6e
        "},{"location":"qsl4a/#_8","title":"\u5a92\u4f53","text":"
        • \u5a92\u4f53\u64ad\u653e\u5668 - \u97f3\u9891/\u89c6\u9891\u64ad\u653e
        • \u56fe\u50cf\u5904\u7406 - \u56fe\u50cf\u64cd\u4f5c
        "},{"location":"qsl4a/#_9","title":"\u7279\u6b8a\u529f\u80fd","text":"
        • \u52a0\u5bc6 - \u52a0\u5bc6/\u89e3\u5bc6
        • PGPT AI - AI \u8bed\u97f3\u670d\u52a1
        "},{"location":"qsl4a/#_10","title":"\u7ed3\u679c\u5bf9\u8c61","text":"

        \u5927\u591a\u6570 QSL4A \u65b9\u6cd5\u8fd4\u56de\u4e00\u4e2a\u5e26\u6709\u4ee5\u4e0b\u5c5e\u6027\u7684 Result \u547d\u540d\u5143\u7ec4\uff1a - id - \u8bf7\u6c42 ID - result - \u5b9e\u9645\u7ed3\u679c\u6570\u636e - error - \u5982\u679c\u5931\u8d25\u5219\u4e3a\u9519\u8bef\u6d88\u606f

        result = droid.getClipboard()\nif result.error is None:\n    print(result.result)\nelse:\n    print(f\"\u9519\u8bef\uff1a{result.error}\")\n
        "},{"location":"qsl4a/connectivity/contacts/","title":"\u8054\u7cfb\u4eba API","text":"

        \u8bbf\u95ee\u548c\u7ba1\u7406\u8bbe\u5907\u8054\u7cfb\u4eba\u3002

        "},{"location":"qsl4a/connectivity/contacts/#_1","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":""},{"location":"qsl4a/connectivity/contacts/#pickcontact","title":"pickContact()","text":"

        \u663e\u793a\u8054\u7cfb\u4eba\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

        pickContact()\n

        \u8fd4\u56de\uff1a \u5305\u542b\u8054\u7cfb\u4eba URI \u7684 Intent

        "},{"location":"qsl4a/connectivity/contacts/#pickphone","title":"pickPhone()","text":"

        \u663e\u793a\u7535\u8bdd\u53f7\u7801\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

        pickPhone()\n

        \u8fd4\u56de\uff1a \u9009\u4e2d\u7684\u7535\u8bdd\u53f7\u7801\u5b57\u7b26\u4e32

        "},{"location":"qsl4a/connectivity/contacts/#_2","title":"\u8054\u7cfb\u4eba\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#contactsget","title":"contactsGet()","text":"

        \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\u3002

        contactsGet(attributes=None)\n

        \u53c2\u6570\uff1a - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

        \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba JSONObject \u5217\u8868

        "},{"location":"qsl4a/connectivity/contacts/#contactsgetbyid","title":"contactsGetById()","text":"

        \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\u3002

        contactsGetById(id, attributes=None)\n

        \u53c2\u6570\uff1a - id (int): \u8054\u7cfb\u4eba ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

        \u8fd4\u56de\uff1a JSONObject \u8054\u7cfb\u4eba\u6570\u636e

        "},{"location":"qsl4a/connectivity/contacts/#contactsgetcount","title":"contactsGetCount()","text":"

        \u83b7\u53d6\u8054\u7cfb\u4eba\u603b\u6570\u3002

        contactsGetCount()\n

        \u8fd4\u56de\uff1a \u6574\u6570\u8ba1\u6570

        "},{"location":"qsl4a/connectivity/contacts/#contactsgetids","title":"contactsGetIds()","text":"

        \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba ID\u3002

        contactsGetIds()\n

        \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba ID \u6574\u6570\u5217\u8868

        "},{"location":"qsl4a/connectivity/contacts/#contactsgetattributes","title":"contactsGetAttributes()","text":"

        \u83b7\u53d6\u6240\u6709\u53ef\u80fd\u7684\u8054\u7cfb\u4eba\u5c5e\u6027\u3002

        contactsGetAttributes()\n

        \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u5217\u8868

        "},{"location":"qsl4a/connectivity/contacts/#_3","title":"\u5185\u5bb9\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#querycontent","title":"queryContent()","text":"

        \u4f7f\u7528\u81ea\u5b9a\u4e49\u53c2\u6570\u67e5\u8be2\u5185\u5bb9\u89e3\u6790\u5668\u3002

        queryContent(uri, attributes=None, selection=None, selectionArgs=None, order=None)\n

        \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u5c5e\u6027 - selection (str, optional): WHERE \u5b50\u53e5 - selectionArgs (list, optional): \u9009\u62e9\u53c2\u6570 - order (str, optional): ORDER BY \u5b50\u53e5

        \u8fd4\u56de\uff1a JSONObject \u7ed3\u679c\u5217\u8868

        "},{"location":"qsl4a/connectivity/contacts/#queryattributes","title":"queryAttributes()","text":"

        \u83b7\u53d6\u5185\u5bb9 URI \u7684\u5c5e\u6027\u3002

        queryAttributes(uri)\n

        \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI

        \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u7684 JSONArray

        "},{"location":"qsl4a/connectivity/contacts/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u9009\u62e9\u8054\u7cfb\u4eba\ncontact_uri = droid.pickContact().result\nprint(f\"Selected contact: {contact_uri}\")\n\n# \u9009\u62e9\u7535\u8bdd\u53f7\u7801\nphone = droid.pickPhone().result\nprint(f\"Selected phone: {phone}\")\n\n# \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\ncontacts = droid.contactsGet().result\nprint(f\"Total contacts: {len(contacts)}\")\n\n# \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\ncontact = droid.contactsGetById(1).result\nprint(f\"Contact: {contact}\")\n\n# \u83b7\u53d6\u8054\u7cfb\u4eba\u5c5e\u6027\nattrs = droid.contactsGetAttributes().result\nprint(f\"Available attributes: {attrs}\")\n
        "},{"location":"qsl4a/connectivity/ftp/","title":"FTP \u670d\u52a1\u5668 API","text":"

        \u5728\u8bbe\u5907\u4e0a\u542f\u52a8\u548c\u7ba1\u7406\u5185\u7f6e FTP \u670d\u52a1\u5668\u3002

        "},{"location":"qsl4a/connectivity/ftp/#ftp","title":"FTP \u670d\u52a1\u5668\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/ftp/#ftpstart","title":"ftpStart()","text":"

        \u542f\u52a8 FTP \u670d\u52a1\u5668\u3002

        ftpStart()\n

        \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4 [ip, port]

        "},{"location":"qsl4a/connectivity/ftp/#ftpstop","title":"ftpStop()","text":"

        \u505c\u6b62 FTP \u670d\u52a1\u5668\u3002

        ftpStop()\n
        "},{"location":"qsl4a/connectivity/ftp/#ftpisrunning","title":"ftpIsRunning()","text":"

        \u68c0\u67e5 FTP \u670d\u52a1\u5668\u662f\u5426\u6b63\u5728\u8fd0\u884c\u3002

        ftpIsRunning()\n

        \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u8fd0\u884c\u5219\u4e3a True

        "},{"location":"qsl4a/connectivity/ftp/#ftpget","title":"ftpGet()","text":"

        \u83b7\u53d6 FTP \u670d\u52a1\u5668 IP \u5730\u5740\u3002

        ftpGet()\n

        \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4

        "},{"location":"qsl4a/connectivity/ftp/#ftpset","title":"ftpSet()","text":"

        \u914d\u7f6e FTP \u670d\u52a1\u5668\u8bbe\u7f6e\u3002

        ftpSet(port=None, rootDir=None, username=None, password=None)\n

        \u53c2\u6570\uff1a - port (int, optional): \u670d\u52a1\u5668\u7aef\u53e3 - rootDir (str, optional): \u8981\u670d\u52a1\u7684\u57fa\u7840\u76ee\u5f55 - username (str, optional): \u767b\u5f55\u7528\u6237\u540d - password (str, optional): \u767b\u5f55\u5bc6\u7801

        \u8fd4\u56de\uff1a \u5305\u542b\u5f53\u524d\u8bbe\u7f6e\u7684 JSONObject

        "},{"location":"qsl4a/connectivity/ftp/#ftpstatus","title":"ftpStatus()","text":"

        \u83b7\u53d6 FTP \u670d\u52a1\u5668\u72b6\u6001\u3002

        ftpStatus()\n

        \u8fd4\u56de\uff1a \u72b6\u6001\u63cf\u8ff0\u5b57\u7b26\u4e32

        "},{"location":"qsl4a/connectivity/ftp/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u914d\u7f6e FTP \u670d\u52a1\u5668\ndroid.ftpSet(\n    port=2121,\n    rootDir=\"/sdcard\",\n    username=\"admin\",\n    password=\"secret\"\n)\n\n# \u542f\u52a8 FTP \u670d\u52a1\u5668\ninfo = droid.ftpStart().result\nprint(f\"FTP running at {info[0]}:{info[1]}\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.ftpIsRunning().result:\n    print(\"FTP server is running\")\n\n# \u83b7\u53d6\u670d\u52a1\u5668\u4fe1\u606f\nserver_info = droid.ftpGet().result\nprint(f\"Server: {server_info}\")\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.ftpStop()\n

        \u6ce8\u610f\uff1a \u4f7f\u7528\u63d0\u4f9b\u7684\u51ed\u636e\u901a\u8fc7\u4efb\u4f55 FTP \u5ba2\u6237\u7aef\u8fde\u63a5\u5230 FTP \u670d\u52a1\u5668\u3002

        "},{"location":"qsl4a/connectivity/location/","title":"\u4f4d\u7f6e API","text":"

        \u8bbf\u95ee GPS \u548c\u7f51\u7edc\u4f4d\u7f6e\u670d\u52a1\u3002

        "},{"location":"qsl4a/connectivity/location/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/location/#startlocating","title":"startLocating()","text":"

        \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\u3002

        startLocating(minUpdateTime=60000, minUpdateDistance=30, updateGnssStatus=False)\n

        \u53c2\u6570\uff1a - minUpdateTime (int): \u66f4\u65b0\u4e4b\u95f4\u7684\u6700\u5c0f\u65f6\u95f4\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a60000\uff09 - minUpdateDistance (float): \u66f4\u65b0\u7684\u6700\u5c0f\u8ddd\u79bb\uff08\u7c73\uff09\uff08\u9ed8\u8ba4\uff1a30\uff09 - updateGnssStatus (bool): \u542f\u7528 GNSS \u72b6\u6001\u66f4\u65b0\uff08\u9ed8\u8ba4\uff1aFalse\uff09

        "},{"location":"qsl4a/connectivity/location/#stoplocating","title":"stopLocating()","text":"

        \u505c\u6b62\u4f4d\u7f6e\u66f4\u65b0\u3002

        stopLocating()\n
        "},{"location":"qsl4a/connectivity/location/#readlocation","title":"readLocation()","text":"

        \u83b7\u53d6\u6700\u540e\u5df2\u77e5\u4f4d\u7f6e\u3002

        readLocation()\n

        \u8fd4\u56de\uff1a \u4f4d\u7f6e\u6570\u636e\u5b57\u5178

        "},{"location":"qsl4a/connectivity/location/#getlastknownlocation","title":"getLastKnownLocation()","text":"

        \u83b7\u53d6\u7f13\u5b58\u7684\u4f4d\u7f6e\u3002

        getLastKnownLocation()\n

        \u8fd4\u56de\uff1a \u6765\u81ea\u6240\u6709\u63d0\u4f9b\u5546\u7684\u4f4d\u7f6e

        "},{"location":"qsl4a/connectivity/location/#geocode","title":"geocode()","text":"

        \u5c06\u5730\u5740\u8f6c\u6362\u4e3a\u5750\u6807\u3002

        geocode(address, maxResults=1)\n
        "},{"location":"qsl4a/connectivity/location/#_2","title":"\u4f4d\u7f6e\u63d0\u4f9b\u5546\u65b9\u6cd5)","text":""},{"location":"qsl4a/connectivity/location/#locationproviders","title":"locationProviders()","text":"

        \u83b7\u53d6\u624b\u673a\u4e0a\u53ef\u7528\u7684\u4f4d\u7f6e\u63d0\u4f9b\u5546\u3002

        locationProviders()\n

        \u8fd4\u56de\uff1a \u53ef\u7528\u63d0\u4f9b\u5546\u540d\u79f0\u5217\u8868\uff08\u4f8b\u5982 ['gps', 'network']\uff09

        "},{"location":"qsl4a/connectivity/location/#locationproviderenabled","title":"locationProviderEnabled()","text":"

        \u68c0\u67e5\u7279\u5b9a\u4f4d\u7f6e\u63d0\u4f9b\u5546\u662f\u5426\u5df2\u542f\u7528\u3002

        locationProviderEnabled(provider)\n

        \u53c2\u6570\uff1a - provider (str): \u63d0\u4f9b\u5546\u540d\u79f0\uff08\u4f8b\u5982 'gps', 'network'\uff09

        \u8fd4\u56de\uff1a \u5982\u679c\u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

        "},{"location":"qsl4a/connectivity/location/#readgnssstatus","title":"readGnssStatus()","text":"

        \u8bfb\u53d6\u5168\u7403\u5bfc\u822a\u536b\u661f\u7cfb\u7edf\u72b6\u6001\uff08\u9700\u8981 Android 8+\uff09\u3002

        readGnssStatus()\n

        \u8fd4\u56de\uff1a \u5305\u542b GNSS \u536b\u661f\u4fe1\u606f\u7684 JSONArray

        "},{"location":"qsl4a/connectivity/location/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\ndroid.startLocating(minUpdateTime=5000, minUpdateDistance=1, updateGnssStatus=False)\n\n# \u7b49\u5f85\u5b9a\u4f4d\ntime.sleep(10)\n\n# \u83b7\u53d6\u4f4d\u7f6e\nloc = droid.readLocation().result\nif loc:\n    lat = loc['latitude']\n    lon = loc['longitude']\n    print(f\"Location: {lat}, {lon}\")\n\ndroid.stopLocating()\n
        "},{"location":"qsl4a/connectivity/phone/","title":"\u7535\u8bdd API","text":"

        \u63a7\u5236\u7535\u8bdd\u901a\u8bdd\u548c\u83b7\u53d6\u7535\u8bdd\u4fe1\u606f\u3002

        "},{"location":"qsl4a/connectivity/phone/#_1","title":"\u7535\u8bdd\u72b6\u6001\u8ddf\u8e2a","text":""},{"location":"qsl4a/connectivity/phone/#starttrackingphonestate","title":"startTrackingPhoneState()","text":"

        \u5f00\u59cb\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u53d8\u5316\u3002\u751f\u6210 'phone' \u4e8b\u4ef6\u3002

        startTrackingPhoneState()\n
        "},{"location":"qsl4a/connectivity/phone/#readphonestate","title":"readPhoneState()","text":"

        \u8bfb\u53d6\u5f53\u524d\u7535\u8bdd\u72b6\u6001\u3002

        readPhoneState()\n

        \u8fd4\u56de\uff1a \u5305\u542b\u7535\u8bdd\u72b6\u6001\u548c\u6765\u7535\u53f7\u7801\u7684 Bundle

        "},{"location":"qsl4a/connectivity/phone/#stoptrackingphonestate","title":"stopTrackingPhoneState()","text":"

        \u505c\u6b62\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u3002

        stopTrackingPhoneState()\n
        "},{"location":"qsl4a/connectivity/phone/#_2","title":"\u62e8\u6253\u7535\u8bdd","text":""},{"location":"qsl4a/connectivity/phone/#phonecall","title":"phoneCall()","text":"

        \u901a\u8fc7 URI \u547c\u53eb\u8054\u7cfb\u4eba/\u7535\u8bdd\u53f7\u7801\u3002

        phoneCall(uri)\n

        \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

        "},{"location":"qsl4a/connectivity/phone/#phonecallnumber","title":"phoneCallNumber()","text":"

        \u76f4\u63a5\u62e8\u6253\u7535\u8bdd\u53f7\u7801\u3002

        phoneCallNumber(phone_number)\n

        \u53c2\u6570\uff1a - phone_number (str): \u8981\u62e8\u6253\u7684\u7535\u8bdd\u53f7\u7801

        "},{"location":"qsl4a/connectivity/phone/#phonedial","title":"phoneDial()","text":"

        \u62e8\u6253\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

        phoneDial(uri)\n

        \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

        "},{"location":"qsl4a/connectivity/phone/#phonedialnumber","title":"phoneDialNumber()","text":"

        \u62e8\u6253\u7535\u8bdd\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

        phoneDialNumber(phone_number)\n

        \u53c2\u6570\uff1a - phone_number (str): \u7535\u8bdd\u53f7\u7801

        "},{"location":"qsl4a/connectivity/phone/#_3","title":"\u57fa\u7ad9\u4f4d\u7f6e","text":""},{"location":"qsl4a/connectivity/phone/#getcelllocation","title":"getCellLocation()","text":"

        \u83b7\u53d6\u5f53\u524d\u57fa\u7ad9\u4f4d\u7f6e\u3002

        getCellLocation()\n

        \u8fd4\u56de\uff1a \u5305\u542b\u57fa\u7ad9\u4f4d\u7f6e\u6570\u636e\u7684 JSONObject

        "},{"location":"qsl4a/connectivity/phone/#getallcellslocation","title":"getAllCellsLocation()","text":"

        \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u4f4d\u7f6e\uff08\u9002\u7528\u4e8e\u53cc\u5361\u8bbe\u5907\uff09\u3002

        getAllCellsLocation()\n

        \u8fd4\u56de\uff1a \u57fa\u7ad9\u4f4d\u7f6e\u7684 JSONArray

        "},{"location":"qsl4a/connectivity/phone/#_4","title":"\u7f51\u7edc\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getnetworkoperator","title":"getNetworkOperator()","text":"

        \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

        getNetworkOperator()\n

        \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

        "},{"location":"qsl4a/connectivity/phone/#getnetworkoperatorname","title":"getNetworkOperatorName()","text":"

        \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684\u540d\u79f0\u3002

        getNetworkOperatorName()\n

        \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

        "},{"location":"qsl4a/connectivity/phone/#getnetworktype","title":"getNetworkType()","text":"

        \u83b7\u53d6\u5f53\u524d\u7f51\u7edc\u7c7b\u578b\u3002

        getNetworkType()\n

        \u8fd4\u56de\uff1a \u63cf\u8ff0\u65e0\u7ebf\u7535\u6280\u672f\u7684\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'LTE', 'UMTS', 'GSM'\uff09

        "},{"location":"qsl4a/connectivity/phone/#getphonetype","title":"getPhoneType()","text":"

        \u83b7\u53d6\u7535\u8bdd\u7c7b\u578b\u3002

        getPhoneType()\n

        \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'GSM', 'CDMA', 'SIP'\uff09

        "},{"location":"qsl4a/connectivity/phone/#sim","title":"SIM \u5361\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getsimcountryiso","title":"getSimCountryIso()","text":"

        \u83b7\u53d6 SIM \u5361\u7684 ISO \u56fd\u5bb6\u4ee3\u7801\u3002

        getSimCountryIso()\n

        \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'us'\uff09

        "},{"location":"qsl4a/connectivity/phone/#getsimoperator","title":"getSimOperator()","text":"

        \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

        getSimOperator()\n

        \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

        "},{"location":"qsl4a/connectivity/phone/#getsimoperatorname","title":"getSimOperatorName()","text":"

        \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u540d\u79f0\u3002

        getSimOperatorName()\n

        \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

        "},{"location":"qsl4a/connectivity/phone/#getsimserialnumber","title":"getSimSerialNumber()","text":"

        \u83b7\u53d6 SIM \u5e8f\u5217\u53f7\u3002

        getSimSerialNumber()\n

        \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32 SIM \u5e8f\u5217\u53f7

        "},{"location":"qsl4a/connectivity/phone/#getsimstate","title":"getSimState()","text":"

        \u83b7\u53d6 SIM \u5361\u72b6\u6001\u3002

        getSimState()\n

        \u8fd4\u56de\uff1a \u63cf\u8ff0 SIM \u72b6\u6001\u7684\u5b57\u7b26\u4e32

        "},{"location":"qsl4a/connectivity/phone/#getsubscriberid","title":"getSubscriberId()","text":"

        \u83b7\u53d6\u8ba2\u9605\u8005 ID\u3002

        getSubscriberId()\n

        \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8ba2\u9605\u8005 ID

        "},{"location":"qsl4a/connectivity/phone/#_5","title":"\u8bed\u97f3\u90ae\u4ef6","text":""},{"location":"qsl4a/connectivity/phone/#getvoicemailalphatag","title":"getVoiceMailAlphaTag()","text":"

        \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u5b57\u6bcd\u6807\u7b7e\u3002

        getVoiceMailAlphaTag()\n

        \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u6807\u7b7e

        "},{"location":"qsl4a/connectivity/phone/#getvoicemailnumber","title":"getVoiceMailNumber()","text":"

        \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801\u3002

        getVoiceMailNumber()\n

        \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801

        "},{"location":"qsl4a/connectivity/phone/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getdeviceid","title":"getDeviceId()","text":"

        \u83b7\u53d6\u8bbe\u5907 ID\uff08GSM \u7684 IMEI\uff09\u3002\u5df2\u5e9f\u5f03\u3002

        getDeviceId()\n

        \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

        "},{"location":"qsl4a/connectivity/phone/#getdevicesoftwareversion","title":"getDeviceSoftwareVersion()","text":"

        \u83b7\u53d6\u8bbe\u5907\u8f6f\u4ef6\u7248\u672c\u3002

        getDeviceSoftwareVersion()\n

        \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8f6f\u4ef6\u7248\u672c

        "},{"location":"qsl4a/connectivity/phone/#getline1number","title":"getLine1Number()","text":"

        \u83b7\u53d6\u7ebf\u8def 1 \u7535\u8bdd\u53f7\u7801\u3002

        getLine1Number()\n

        \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u7535\u8bdd\u53f7\u7801

        "},{"location":"qsl4a/connectivity/phone/#checknetworkroaming","title":"checkNetworkRoaming()","text":"

        \u68c0\u67e5\u662f\u5426\u8fde\u63a5\u5230\u6f2b\u6e38\u7f51\u7edc\u3002

        checkNetworkRoaming()\n

        \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u6f2b\u6e38\u5219\u4e3a True

        "},{"location":"qsl4a/connectivity/phone/#_7","title":"\u57fa\u7ad9\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getallcellinfo","title":"getAllCellInfo()","text":"

        \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u7684\u4fe1\u606f\u3002

        getAllCellInfo()\n

        \u8fd4\u56de\uff1a \u57fa\u7ad9\u4fe1\u606f\u5217\u8868

        "},{"location":"qsl4a/connectivity/phone/#setdataenabled","title":"setDataEnabled()","text":"

        \u542f\u7528\u6216\u7981\u7528\u79fb\u52a8\u6570\u636e\u3002

        setDataEnabled(enabled)\n

        \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528

        "},{"location":"qsl4a/connectivity/phone/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7f51\u7edc\u4fe1\u606f\noperator = droid.getNetworkOperatorName().result\nprint(f\"Operator: {operator}\")\n\nnetwork_type = droid.getNetworkType().result\nprint(f\"Network: {network_type}\")\n\n# \u83b7\u53d6 SIM \u4fe1\u606f\nsim_state = droid.getSimState().result\nprint(f\"SIM: {sim_state}\")\n\n# \u83b7\u53d6\u7535\u8bdd\u53f7\u7801\nline1 = droid.getLine1Number().result\nprint(f\"Phone: {line1}\")\n\n# \u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\ndroid.startTrackingPhoneState()\nprint(\"Tracking phone state...\")\ndroid.stopTrackingPhoneState()\n
        "},{"location":"qsl4a/connectivity/signalstrength/","title":"\u4fe1\u53f7\u5f3a\u5ea6 API","text":"

        \u76d1\u63a7\u8702\u7a9d\u548c\u65e0\u7ebf\u4fe1\u53f7\u5f3a\u5ea6\u3002

        "},{"location":"qsl4a/connectivity/signalstrength/#_1","title":"\u4fe1\u53f7\u5f3a\u5ea6\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/signalstrength/#starttrackingsignalstrengths","title":"startTrackingSignalStrengths()","text":"

        \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316\u3002\u751f\u6210 'signal_strengths' \u4e8b\u4ef6\u3002

        startTrackingSignalStrengths()\n
        "},{"location":"qsl4a/connectivity/signalstrength/#stoptrackingsignalstrengths","title":"stopTrackingSignalStrengths()","text":"

        \u505c\u6b62\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u3002

        stopTrackingSignalStrengths()\n
        "},{"location":"qsl4a/connectivity/signalstrength/#readsignalstrengths","title":"readSignalStrengths()","text":"

        \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\u3002

        readSignalStrengths()\n

        \u8fd4\u56de\uff1a \u5305\u542b\u4fe1\u53f7\u5f3a\u5ea6\u6570\u636e\u7684 Bundle

        "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthlevel","title":"getTelephoneSignalStrengthLevel()","text":"

        \u83b7\u53d6\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u7b49\u7ea7\uff080-4\uff09\u3002

        getTelephoneSignalStrengthLevel()\n

        \u8fd4\u56de\uff1a \u6574\u6570\u7b49\u7ea7\uff080=\u65e0\uff0c1=\u5dee\uff0c2=\u4e00\u822c\uff0c3=\u597d\uff0c4=\u4f18\u79c0\uff09

        "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthdetail","title":"getTelephoneSignalStrengthDetail()","text":"

        \u83b7\u53d6\u8be6\u7ec6\u7684\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u4fe1\u606f\u3002

        getTelephoneSignalStrengthDetail()\n

        \u8fd4\u56de\uff1a \u5305\u542b\u8be6\u7ec6\u4fe1\u53f7\u4fe1\u606f\u7684\u5b57\u7b26\u4e32

        "},{"location":"qsl4a/connectivity/signalstrength/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\ndroid.startTrackingSignalStrengths()\n\n# \u7b49\u5f85\u4fe1\u53f7\u66f4\u65b0\ntime.sleep(5)\n\n# \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\nsignal = droid.readSignalStrengths().result\nprint(f\"Signal: {signal}\")\n\n# \u76f4\u63a5\u83b7\u53d6\u7b49\u7ea7\nlevel = droid.getTelephoneSignalStrengthLevel().result\nprint(f\"Signal level: {level}/4\")\n\ndroid.stopTrackingSignalStrengths()\n
        "},{"location":"qsl4a/connectivity/sms/","title":"SMS API","text":"

        \u53d1\u9001\u548c\u63a5\u6536 SMS \u6d88\u606f\u3002

        "},{"location":"qsl4a/connectivity/sms/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/sms/#smssend","title":"smsSend()","text":"

        \u53d1\u9001 SMS \u6d88\u606f\u3002

        smsSend(destinationAddress, text)\n

        \u53c2\u6570\uff1a - destinationAddress (str): \u7535\u8bdd\u53f7\u7801 - text (str): \u6d88\u606f\u6587\u672c

        "},{"location":"qsl4a/connectivity/sms/#smsgetmessagecount","title":"smsGetMessageCount()","text":"

        \u83b7\u53d6\u6d88\u606f\u6570\u91cf\u3002

        smsGetMessageCount(unreadOnly=False, folder=\"inbox\")\n
        "},{"location":"qsl4a/connectivity/sms/#smsgetmessageids","title":"smsGetMessageIds()","text":"

        \u83b7\u53d6\u6d88\u606f ID\u3002

        smsGetMessageIds(unreadOnly=False, folder=\"inbox\")\n
        "},{"location":"qsl4a/connectivity/sms/#smsgetmessages","title":"smsGetMessages()","text":"

        \u83b7\u53d6\u6d88\u606f\u8be6\u60c5\u3002

        smsGetMessages(unreadOnly=False, folder=\"inbox\", attributes=None)\n
        "},{"location":"qsl4a/connectivity/sms/#smsgetmessagebyid","title":"smsGetMessageById()","text":"

        \u901a\u8fc7 ID \u83b7\u53d6\u7279\u5b9a\u6d88\u606f\u3002

        smsGetMessageById(id, attributes=None)\n

        \u53c2\u6570\uff1a - id (int): \u6d88\u606f ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

        \u8fd4\u56de\uff1a \u6d88\u606f\u6570\u636e\u5b57\u5178

        "},{"location":"qsl4a/connectivity/sms/#smsgetattributes","title":"smsGetAttributes()","text":"

        \u83b7\u53d6\u53ef\u7528\u7684 SMS \u6d88\u606f\u5c5e\u6027\u3002

        smsGetAttributes()\n

        \u8fd4\u56de\uff1a \u53ef\u7528\u5c5e\u6027\u540d\u79f0\u5217\u8868

        "},{"location":"qsl4a/connectivity/sms/#smsdeletemessage","title":"smsDeleteMessage()","text":"

        \u5220\u9664\u6d88\u606f\u3002

        smsDeleteMessage(id)\n
        "},{"location":"qsl4a/connectivity/sms/#smsmarkmessageread","title":"smsMarkMessageRead()","text":"

        \u5c06\u6d88\u606f\u6807\u8bb0\u4e3a\u5df2\u8bfb\u3002

        smsMarkMessageRead(ids, read=True)\n
        "},{"location":"qsl4a/connectivity/sms/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u53d1\u9001 SMS\ndroid.smsSend(\"+1234567890\", \"Hello from QPython!\")\n\n# \u83b7\u53d6\u672a\u8bfb\u6d88\u606f\nmessages = droid.smsGetMessages(unreadOnly=True).result\nfor msg in messages:\n    print(f\"From: {msg['address']}, Text: {msg['body']}\")\n
        "},{"location":"qsl4a/connectivity/wifi/","title":"WiFi API","text":"

        \u63a7\u5236 WiFi \u9002\u914d\u5668\u5e76\u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\u3002

        "},{"location":"qsl4a/connectivity/wifi/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/connectivity/wifi/#checkwifistate","title":"checkWifiState()","text":"

        \u68c0\u67e5 WiFi \u662f\u5426\u5df2\u542f\u7528\u3002

        checkWifiState()\n

        \u8fd4\u56de\uff1a \u5982\u679c WiFi \u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

        "},{"location":"qsl4a/connectivity/wifi/#togglewifistate","title":"toggleWifiState()","text":"

        \u6253\u5f00\u6216\u5173\u95ed WiFi\u3002

        toggleWifiState(enabled=None)\n

        \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

        \u8fd4\u56de\uff1a \u5982\u679c\u64cd\u4f5c\u6210\u529f\u5219\u4e3a True

        "},{"location":"qsl4a/connectivity/wifi/#wifistartscan","title":"wifiStartScan()","text":"

        \u5f00\u59cb\u626b\u63cf\u53ef\u7528\u7684 WiFi \u7f51\u7edc\u3002

        wifiStartScan()\n
        "},{"location":"qsl4a/connectivity/wifi/#wifigetscanresults","title":"wifiGetScanResults()","text":"

        \u83b7\u53d6\u53d1\u73b0\u7684 WiFi \u7f51\u7edc\u5217\u8868\u3002

        wifiGetScanResults()\n

        \u8fd4\u56de\uff1a \u63a5\u5165\u70b9\u4fe1\u606f\u5217\u8868

        "},{"location":"qsl4a/connectivity/wifi/#_2","title":"\u8fde\u63a5\u7ba1\u7406","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetconnectioninfo","title":"wifiGetConnectionInfo()","text":"

        \u83b7\u53d6\u8be6\u7ec6\u8fde\u63a5\u4fe1\u606f\u3002

        wifiGetConnectionInfo()\n

        \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001IP \u5730\u5740\u7b49\u8fde\u63a5\u8be6\u60c5\u7684\u5b57\u5178

        "},{"location":"qsl4a/connectivity/wifi/#getconnectedinfo","title":"getConnectedInfo()","text":"

        \u83b7\u53d6\u8fde\u63a5\u7684 WiFi \u7f51\u7edc\u4fe1\u606f\uff08\u7b80\u5316\u7248\uff09\u3002

        getConnectedInfo()\n

        \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001\u4fe1\u53f7\u5f3a\u5ea6\u7684\u5b57\u5178

        "},{"location":"qsl4a/connectivity/wifi/#getdhcpinfo","title":"getDhcpInfo()","text":"

        \u83b7\u53d6\u5f53\u524d\u8fde\u63a5\u7684 DHCP \u4fe1\u606f\u3002

        getDhcpInfo(ipConvertToString=True)\n

        \u53c2\u6570\uff1a - ipConvertToString (bool): \u5c06 IP \u5730\u5740\u8f6c\u6362\u4e3a\u5b57\u7b26\u4e32\u683c\u5f0f\uff08\u9ed8\u8ba4\uff1aTrue\uff09

        \u8fd4\u56de\uff1a \u5305\u542b IP\u3001\u7f51\u5173\u3001DNS \u7b49 DHCP \u4fe1\u606f\u7684\u5b57\u5178

        "},{"location":"qsl4a/connectivity/wifi/#wifidisconnect","title":"wifiDisconnect()","text":"

        \u65ad\u5f00\u5f53\u524d WiFi \u7f51\u7edc\u8fde\u63a5\u3002

        wifiDisconnect()\n
        "},{"location":"qsl4a/connectivity/wifi/#wifireconnect","title":"wifiReconnect()","text":"

        \u91cd\u65b0\u8fde\u63a5\u5230\u5f53\u524d\u7f51\u7edc\u3002

        wifiReconnect()\n
        "},{"location":"qsl4a/connectivity/wifi/#wifireassociate","title":"wifiReassociate()","text":"

        \u91cd\u65b0\u5173\u8054\u5f53\u524d\u63a5\u5165\u70b9\u3002

        wifiReassociate()\n
        "},{"location":"qsl4a/connectivity/wifi/#_3","title":"\u70ed\u70b9","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetapstate","title":"wifiGetApState()","text":"

        \u83b7\u53d6 WiFi AP\uff08\u70ed\u70b9\uff09\u72b6\u6001\u3002

        wifiGetApState()\n

        \u8fd4\u56de\uff1a \u70ed\u70b9\u72b6\u6001

        "},{"location":"qsl4a/connectivity/wifi/#wifi","title":"WiFi \u9501","text":""},{"location":"qsl4a/connectivity/wifi/#wifilockacquirefull","title":"wifiLockAcquireFull()","text":"

        \u83b7\u53d6\u5b8c\u6574 WiFi \u9501\uff08\u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\u4e5f\u4fdd\u6301 WiFi \u6d3b\u52a8\uff09\u3002

        wifiLockAcquireFull()\n
        "},{"location":"qsl4a/connectivity/wifi/#wifilockacquirescanonly","title":"wifiLockAcquireScanOnly()","text":"

        \u83b7\u53d6\u4ec5\u626b\u63cf WiFi \u9501\u3002

        wifiLockAcquireScanOnly()\n
        "},{"location":"qsl4a/connectivity/wifi/#wifilockrelease","title":"wifiLockRelease()","text":"

        \u91ca\u653e WiFi \u9501\u3002

        wifiLockRelease()\n
        "},{"location":"qsl4a/connectivity/wifi/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u68c0\u67e5 WiFi \u72b6\u6001\nif droid.checkWifiState().result:\n    print(\"WiFi is enabled\")\nelse:\n    print(\"Enabling WiFi...\")\n    droid.toggleWifiState(True)\n    time.sleep(2)\n\n# \u5f00\u59cb\u626b\u63cf\ndroid.wifiStartScan()\ntime.sleep(3)\n\n# \u83b7\u53d6\u626b\u63cf\u7ed3\u679c\nnetworks = droid.wifiGetScanResults().result\nfor network in networks:\n    print(f\"SSID: {network.get('SSID')}, Signal: {network.get('level')} dBm\")\n\n# \u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\ninfo = droid.wifiGetConnectionInfo().result\nif info:\n    print(f\"Connected to: {info.get('ssid')}\")\n    print(f\"BSSID: {info.get('bssid')}\")\n    print(f\"IP: {info.get('ip_address')}\")\n\n# \u83b7\u53d6 DHCP \u4fe1\u606f\ndhcp = droid.getDhcpInfo().result\nif dhcp:\n    print(f\"Gateway: {dhcp.get('gateway')}\")\n    print(f\"DNS: {dhcp.get('dns1')}\")\n\n# \u83b7\u53d6\u7b80\u5316\u7684\u8fde\u63a5\u4fe1\u606f\nconnected = droid.getConnectedInfo().result\nprint(f\"SSID: {connected.get('ssid')}, Signal: {connected.get('level')} dBm\")\n\n# \u65ad\u5f00\u5e76\u91cd\u65b0\u8fde\u63a5\ndroid.wifiDisconnect()\ntime.sleep(1)\ndroid.wifiReconnect()\n\n# \u91cd\u65b0\u5173\u8054\u63a5\u5165\u70b9\ndroid.wifiReassociate()\n\n# \u68c0\u67e5\u70ed\u70b9\u72b6\u6001\nap_state = droid.wifiGetApState().result\nprint(f\"Hotspot state: {ap_state}\")\n\n# \u83b7\u53d6 WiFi \u9501\u4ee5\u8fdb\u884c\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireFull()\n# ... \u6267\u884c\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n\n# \u6216\u4f7f\u7528\u4ec5\u626b\u63cf\u9501\u4ee5\u8fdb\u884c\u8f83\u8f7b\u7684\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireScanOnly()\n# ... \u6267\u884c\u626b\u63cf\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n
        "},{"location":"qsl4a/core/android-base/","title":"Android \u57fa\u7840\u7c7b","text":"

        Android \u7c7b\u662f QSL4A \u7684\u6838\u5fc3\uff0c\u63d0\u4f9b\u4e86\u4e0e Android \u8fd0\u884c\u65f6\u7684\u8fde\u63a5\u548c RPC \u673a\u5236\u3002

        "},{"location":"qsl4a/core/android-base/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
        # \u529f\u80fd\u5b8c\u6574\u7248\u672c\uff08\u63a8\u8350\uff09\nimport androidhelper\ndroid = androidhelper.Android()\n\n# \u7b80\u5316\u7248\u672c\uff08\u5feb\u901f\uff0c\u5355\u5b9e\u4f8b\uff09\nimport android\ndroid = android.droid\n
        "},{"location":"qsl4a/core/android-base/#android_1","title":"\u7c7b\uff1aAndroid","text":""},{"location":"qsl4a/core/android-base/#_2","title":"\u6784\u9020\u51fd\u6570","text":"
        Android(addr=None)\n

        \u53c2\u6570\uff1a - addr (tuple, optional): (HOST, PORT) \u5730\u5740\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u73af\u5883\u53d8\u91cf AP_HOST \u548c AP_PORT

        \u73af\u5883\u53d8\u91cf\uff1a - AP_HOST - \u670d\u52a1\u5668\u4e3b\u673a\u5730\u5740 - AP_PORT - \u670d\u52a1\u5668\u7aef\u53e3 - AP_HANDSHAKE - \u8ba4\u8bc1\u4ee4\u724c

        "},{"location":"qsl4a/core/android-base/#_3","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/android-base/#_rpc","title":"_rpc()","text":"

        \u8c03\u7528 Android \u51fd\u6570\u7684\u5185\u90e8 RPC \u65b9\u6cd5\u3002

        _rpc(method, *args)\n

        \u53c2\u6570\uff1a - method (str): \u8981\u8c03\u7528\u7684\u65b9\u6cd5\u540d - *args: \u65b9\u6cd5\u7684\u53ef\u53d8\u53c2\u6570

        \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4\uff0c\u5305\u542b\u4ee5\u4e0b\u5b57\u6bb5\uff1a - id (int): \u8bf7\u6c42 ID - result: \u65b9\u6cd5\u8fd4\u56de\u503c - error (str or None): \u9519\u8bef\u4fe1\u606f\uff08\u5982\u679c\u5931\u8d25\uff09

        "},{"location":"qsl4a/core/android-base/#getattr","title":"getattr()","text":"

        \u52a8\u6001\u65b9\u6cd5\u5206\u53d1\u5668\u3002\u6240\u6709 Android \u65b9\u6cd5\u90fd\u901a\u8fc7\u5c5e\u6027\u67e5\u627e\u8bbf\u95ee\u3002

        # \u4ee5\u4e0b\u4e24\u79cd\u65b9\u5f0f\u7b49\u4ef7\uff1a\ndroid.makeToast(\"Hello\")\ndroid._rpc(\"makeToast\", \"Hello\")\n
        "},{"location":"qsl4a/core/android-base/#androidpy","title":"\u72ec\u7acb\u51fd\u6570\uff08android.py\uff09","text":"

        \u4f7f\u7528\u7b80\u5316\u7684 android \u6a21\u5757\u65f6\uff1a

        "},{"location":"qsl4a/core/android-base/#jsla","title":"jsla()","text":"

        \u53d1\u9001 JSON-RPC \u8bf7\u6c42\u5e76\u8fd4\u56de\u539f\u59cb\u54cd\u5e94\u3002

        jsla(method, *params)\n

        \u8fd4\u56de\uff1a JSON \u5b57\u7b26\u4e32\u54cd\u5e94

        "},{"location":"qsl4a/core/android-base/#rsla","title":"rsla()","text":"

        \u53d1\u9001\u8bf7\u6c42\u5e76\u4ec5\u8fd4\u56de\u7ed3\u679c\u3002

        rsla(method, *params)\n

        \u8fd4\u56de\uff1a RPC \u8c03\u7528\u7684\u7ed3\u679c\u503c

        "},{"location":"qsl4a/core/android-base/#esla","title":"esla()","text":"

        \u53d1\u9001\u8bf7\u6c42\uff0c\u9519\u8bef\u65f6\u629b\u51fa\u5f02\u5e38\u3002

        esla(method, *params)\n

        \u629b\u51fa\uff1a \u5982\u679c error \u5b57\u6bb5\u4e0d\u4e3a None \u5219\u629b\u51fa\u5f02\u5e38

        "},{"location":"qsl4a/core/android-base/#nsla","title":"nsla()","text":"

        \u53d1\u9001\u8bf7\u6c42\u5e76\u8fd4\u56de Result \u547d\u540d\u5143\u7ec4\u3002

        nsla(method, *params)\n

        \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4

        "},{"location":"qsl4a/core/android-base/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/android-base/#_5","title":"\u57fa\u672c\u8fde\u63a5","text":"
        import androidhelper\n\n# \u8fde\u63a5\u5230 Android \u8fd0\u884c\u65f6\ndroid = androidhelper.Android()\n\n# \u901a\u8fc7\u663e\u793a toast \u6765\u68c0\u67e5\u8fde\u63a5\ndroid.makeToast(\"Connected!\")\n
        "},{"location":"qsl4a/core/android-base/#_6","title":"\u9519\u8bef\u5904\u7406","text":"
        result = droid.someMethod()\nif result.error:\n    print(f\"Error: {result.error}\")\nelse:\n    print(f\"Success: {result.result}\")\n
        "},{"location":"qsl4a/core/android-base/#rpc","title":"\u76f4\u63a5 RPC \u8c03\u7528","text":"
        # \u76f4\u63a5\u8c03\u7528\u4efb\u610f\u65b9\u6cd5\nresult = droid._rpc(\"makeToast\", \"Hello World\")\n
        "},{"location":"qsl4a/core/events/","title":"\u4e8b\u4ef6\u7cfb\u7edf","text":"

        QSL4A \u63d0\u4f9b\u4e86\u4e00\u4e2a\u4e8b\u4ef6\u7cfb\u7edf\uff0c\u7528\u4e8e\u5904\u7406\u6765\u81ea Android \u7684\u5f02\u6b65\u4e8b\u4ef6\uff0c\u5982\u4f20\u611f\u5668\u66f4\u65b0\u3001\u4f4d\u7f6e\u53d8\u5316\u548c\u81ea\u5b9a\u4e49\u5e7f\u64ad\u3002

        "},{"location":"qsl4a/core/events/#_2","title":"\u4e8b\u4ef6\u57fa\u7840","text":"

        \u4e8b\u4ef6\u5b58\u50a8\u5728\u7f13\u51b2\u533a\u4e2d\uff0c\u53ef\u4ee5\u8f6e\u8be2\u6216\u7b49\u5f85\u3002\u6bcf\u4e2a\u4e8b\u4ef6\u5305\u542b\uff1a - name: \u4e8b\u4ef6\u7c7b\u578b/\u540d\u79f0 - data: \u4e8b\u4ef6\u8d1f\u8f7d\u6570\u636e - time: \u65f6\u95f4\u6233

        "},{"location":"qsl4a/core/events/#_3","title":"\u4e8b\u4ef6\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#eventclearbuffer","title":"eventClearBuffer()","text":"

        \u6e05\u9664\u7f13\u51b2\u533a\u4e2d\u7684\u6240\u6709\u5f85\u5904\u7406\u4e8b\u4ef6\u3002

        eventClearBuffer()\n

        \u8fd4\u56de\uff1a None

        "},{"location":"qsl4a/core/events/#eventpoll","title":"eventPoll()","text":"

        \u8f6e\u8be2\u7f13\u51b2\u533a\u4e2d\u7684\u4e8b\u4ef6\u3002

        eventPoll(number_of_events=1)\n

        \u53c2\u6570\uff1a - number_of_events (int): \u8981\u68c0\u7d22\u7684\u6700\u5927\u4e8b\u4ef6\u6570\uff08\u9ed8\u8ba4\uff1a1\uff09

        \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\u5217\u8868

        "},{"location":"qsl4a/core/events/#eventwait","title":"eventWait()","text":"

        \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\u3002

        eventWait(timeout=None)\n

        \u53c2\u6570\uff1a - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09\u3002None = \u6c38\u4e45\u7b49\u5f85

        \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

        "},{"location":"qsl4a/core/events/#eventwaitfor","title":"eventWaitFor()","text":"

        \u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6\u3002

        eventWaitFor(eventName, timeout=None)\n

        \u53c2\u6570\uff1a - eventName (str): \u8981\u7b49\u5f85\u7684\u4e8b\u4ef6\u540d\u79f0 - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

        \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

        "},{"location":"qsl4a/core/events/#eventpost","title":"eventPost()","text":"

        \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\u3002

        eventPost(name, data, enqueue=None)\n

        \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e\uff08\u4efb\u610f\u7c7b\u578b\uff09 - enqueue (bool, optional): \u5982\u679c\u4e3a True \u5219\u6dfb\u52a0\u5230\u961f\u5217

        "},{"location":"qsl4a/core/events/#receiveevent","title":"receiveEvent()","text":"

        \u63a5\u6536\u4e8b\u4ef6\uff08\u963b\u585e\uff09\u3002

        receiveEvent()\n

        \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61

        "},{"location":"qsl4a/core/events/#_4","title":"\u5e7f\u64ad\u4e8b\u4ef6","text":"

        \u6ce8\u518c\u7cfb\u7edf\u5e7f\u64ad\u4e8b\u4ef6\u3002

        "},{"location":"qsl4a/core/events/#eventregisterforbroadcast","title":"eventRegisterForBroadcast()","text":"

        \u6ce8\u518c\u63a5\u6536\u5e7f\u64ad\u4e8b\u4ef6\u3002

        eventRegisterForBroadcast(category, enqueue=True)\n

        \u53c2\u6570\uff1a - category (str): \u5e7f\u64ad\u7c7b\u522b/\u52a8\u4f5c - enqueue (bool): \u6dfb\u52a0\u5230\u4e8b\u4ef6\u961f\u5217

        "},{"location":"qsl4a/core/events/#eventunregisterforbroadcast","title":"eventUnregisterForBroadcast()","text":"

        \u53d6\u6d88\u6ce8\u518c\u5e7f\u64ad\u4e8b\u4ef6\u3002

        eventUnregisterForBroadcast(category)\n
        "},{"location":"qsl4a/core/events/#eventgetbrodcastcategories","title":"eventGetBrodcastCategories()","text":"

        \u83b7\u53d6\u5df2\u6ce8\u518c\u7684\u5e7f\u64ad\u7c7b\u522b\u3002

        eventGetBrodcastCategories()\n

        \u8fd4\u56de\uff1a \u5df2\u6ce8\u518c\u7c7b\u522b\u5217\u8868

        "},{"location":"qsl4a/core/events/#_5","title":"\u4e8b\u4ef6\u5206\u53d1\u5668)","text":""},{"location":"qsl4a/core/events/#starteventdispatcher","title":"startEventDispatcher()","text":"

        \u6253\u5f00\u4e00\u4e2a\u53ef\u4ee5\u8bfb\u53d6\u5df2\u53d1\u5e03\u4e8b\u4ef6\u7684\u5957\u63a5\u5b57\u3002)

        startEventDispatcher(port=0)\n

        \u53c2\u6570\uff1a - port (int, optional): \u76d1\u542c\u7684\u7aef\u53e3\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\u9009\u62e9\uff09

        \u8fd4\u56de\uff1a \u6b63\u5728\u76d1\u542c\u7684\u7aef\u53e3\u53f7

        "},{"location":"qsl4a/core/events/#stopeventdispatcher","title":"stopEventDispatcher()","text":"

        \u505c\u6b62\u4e8b\u4ef6\u670d\u52a1\u5668\u3002)

        stopEventDispatcher()\n
        "},{"location":"qsl4a/core/events/#_6","title":"\u5df2\u5e9f\u5f03\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#rpcpostevent","title":"rpcPostEvent()","text":"

        \u5c06\u4e8b\u4ef6\u53d1\u5e03\u5230\u4e8b\u4ef6\u961f\u5217\u3002\uff08\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 eventPost\uff09

        rpcPostEvent(name, data)\n

        \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e

        "},{"location":"qsl4a/core/events/#_7","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/events/#_8","title":"\u57fa\u672c\u4e8b\u4ef6\u8f6e\u8be2","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6e05\u9664\u65e7\u4e8b\u4ef6\ndroid.eventClearBuffer()\n\n# \u8f6e\u8be2\u4e8b\u4ef6\nevents = droid.eventPoll(5).result\nfor event in events:\n    print(f\"Event: {event['name']}, Data: {event['data']}\")\n
        "},{"location":"qsl4a/core/events/#_9","title":"\u7b49\u5f85\u4e8b\u4ef6","text":"
        # \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\uff0c\u5e26\u8d85\u65f6\nevent = droid.eventWait(timeout=10).result\nif event:\n    print(f\"Got event: {event['name']}\")\n
        "},{"location":"qsl4a/core/events/#_10","title":"\u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6","text":"
        # \u7b49\u5f85\u4f20\u611f\u5668\u4e8b\u4ef6\nevent = droid.eventWaitFor('screen', timeout=5).result\nif event:\n    print(f\"Screen event: {event['data']}\")\n
        "},{"location":"qsl4a/core/events/#_11","title":"\u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6","text":"
        # \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\ndroid.eventPost('my_event', {'key': 'value'})\n\n# \u7b49\u5f85\u5b83\nevent = droid.eventWaitFor('my_event', timeout=1).result\n
        "},{"location":"qsl4a/core/events/#_12","title":"\u5e7f\u64ad\u63a5\u6536\u5668","text":"
        # \u6ce8\u518c\u5c4f\u5e55\u5f00\u5173\u4e8b\u4ef6\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_ON')\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_OFF')\n\n# \u7b49\u5f85\u5c4f\u5e55\u4e8b\u4ef6\nwhile True:\n    event = droid.receiveEvent().result\n    if event['name'] == 'android.intent.action.SCREEN_ON':\n        print(\"Screen turned on\")\n    elif event['name'] == 'android.intent.action.SCREEN_OFF':\n        print(\"Screen turned off\")\n
        "},{"location":"qsl4a/core/events/#_13","title":"\u4f20\u611f\u5668\u4e8b\u4ef6\u5904\u7406","text":"
        # \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u5904\u7406\u4f20\u611f\u5668\u4e8b\u4ef6\nfor _ in range(100):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'sensors':\n        data = event['data']\n        print(f\"Accel: {data['xforce']}, {data['yforce']}, {data['zforce']}\")\n\ndroid.stopSensing()\n
        "},{"location":"qsl4a/core/events/#_14","title":"\u5e38\u89c1\u4e8b\u4ef6\u7c7b\u578b","text":"\u4e8b\u4ef6\u540d\u79f0 \u63cf\u8ff0 \u6765\u6e90 sensors \u4f20\u611f\u5668\u6570\u636e\u66f4\u65b0 startSensing* location GPS \u4f4d\u7f6e\u66f4\u65b0 startLocating phone \u7535\u8bdd\u72b6\u6001\u53d8\u5316 startTrackingPhoneState signal \u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316 startTrackingSignalStrength screen \u622a\u56fe\u5c31\u7eea fullGetScreenShot dialog \u5bf9\u8bdd\u6846\u54cd\u5e94 dialogShow*"},{"location":"qsl4a/core/events/#_15","title":"\u4e8b\u4ef6\u6570\u636e\u7ed3\u6784","text":"
        {\n    'name': 'event_name',\n    'data': {\n        # \u4e8b\u4ef6\u7279\u5b9a\u6570\u636e\n    },\n    'time': 1234567890  # \u65f6\u95f4\u6233\n}\n
        "},{"location":"qsl4a/core/intent/","title":"Intent \u7cfb\u7edf","text":"

        Android Intent \u7528\u4e8e\u542f\u52a8\u6d3b\u52a8\u3001\u53d1\u9001\u5e7f\u64ad\u548c\u5e94\u7528\u95f4\u901a\u4fe1\u3002QSL4A \u901a\u8fc7 Intent \u6a21\u5757\u63d0\u4f9b\u5b8c\u6574\u7684 Intent \u652f\u6301\u3002

        "},{"location":"qsl4a/core/intent/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
        import androidhelper\ndon = androidhelper.Android()\n
        "},{"location":"qsl4a/core/intent/#intent_1","title":"Intent \u5e38\u91cf","text":"

        \u901a\u8fc7 droid.Intent \u8bbf\u95ee\uff1a

        "},{"location":"qsl4a/core/intent/#_2","title":"\u64cd\u4f5c","text":"\u5e38\u91cf \u503c \u7528\u9014 ACTION_MAIN android.intent.action.MAIN \u5e94\u7528\u5165\u53e3\u70b9 ACTION_VIEW android.intent.action.VIEW \u67e5\u770b\u5185\u5bb9 ACTION_EDIT android.intent.action.EDIT \u7f16\u8f91\u5185\u5bb9 ACTION_PICK android.intent.action.PICK \u9009\u62e9\u9879\u76ee ACTION_SEND android.intent.action.SEND \u5206\u4eab\u5185\u5bb9 ACTION_SEARCH android.intent.action.SEARCH \u641c\u7d22"},{"location":"qsl4a/core/intent/#_3","title":"\u6807\u5fd7","text":"\u5e38\u91cf \u503c \u7528\u9014 FLAG_ACTIVITY_NEW_TASK 268435456 \u542f\u52a8\u65b0\u4efb\u52a1 FLAG_ACTIVITY_CLEAR_TASK 32768 \u6e05\u9664\u4efb\u52a1\u5806\u6808 FLAG_ACTIVITY_NEW_DOCUMENT 524288 \u65b0\u6587\u6863\u6a21\u5f0f"},{"location":"qsl4a/core/intent/#_4","title":"\u9644\u52a0\u6570\u636e","text":"\u5e38\u91cf \u7528\u9014 EXTRA_TEXT \u6587\u672c\u5185\u5bb9 EXTRA_STREAM \u6587\u4ef6 URI EXTRA_SUBJECT \u4e3b\u9898\u884c EXTRA_EMAIL \u7535\u5b50\u90ae\u4ef6\u5730\u5740"},{"location":"qsl4a/core/intent/#_5","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/intent/#makeintent","title":"makeIntent()","text":"

        \u521b\u5efa Intent \u5bf9\u8c61\u3002

        makeIntent(action, uri=None, type=None, extras=None, categories=None,\n           packagename=None, classname=None, flags=None)\n

        \u53c2\u6570\uff1a - action (str): Intent \u64cd\u4f5c\uff08\u4f8b\u5982 droid.Intent.ACTION_VIEW\uff09 - uri (str, optional): \u6570\u636e URI - type (str, optional): MIME \u7c7b\u578b - extras (dict, optional): \u9644\u52a0\u6570\u636e - categories (list, optional): Intent \u7c7b\u522b - packagename (str, optional): \u76ee\u6807\u5305 - classname (str, optional): \u76ee\u6807\u7c7b - flags (int, optional): Intent \u6807\u5fd7

        \u8fd4\u56de\uff1a Intent \u5bf9\u8c61

        "},{"location":"qsl4a/core/intent/#startactivityintent","title":"startActivityIntent()","text":"

        \u4f7f\u7528 Intent \u542f\u52a8 Activity\u3002

        startActivityIntent(intent, wait=None)\n

        \u53c2\u6570\uff1a - intent: makeIntent() \u8fd4\u56de\u7684 Intent \u5bf9\u8c61 - wait (bool, optional): \u963b\u585e\u76f4\u5230\u6d3b\u52a8\u5173\u95ed

        "},{"location":"qsl4a/core/intent/#startactivityforresultintent","title":"startActivityForResultIntent()","text":"

        \u542f\u52a8\u6d3b\u52a8\u5e76\u7b49\u5f85\u7ed3\u679c\u3002

        startActivityForResultIntent(intent)\n

        \u8fd4\u56de\uff1a Activity \u7ed3\u679c

        "},{"location":"qsl4a/core/intent/#sendbroadcastintent","title":"sendBroadcastIntent()","text":"

        \u53d1\u9001\u5e7f\u64ad\u3002

        sendBroadcastIntent(intent)\n
        "},{"location":"qsl4a/core/intent/#view","title":"view()","text":"

        \u901a\u8fc7 URI \u67e5\u770b\u5185\u5bb9\u3002

        view(uri, type=None, extras=None)\n
        "},{"location":"qsl4a/core/intent/#pick","title":"pick()","text":"

        \u4ece URI \u9009\u62e9\u5185\u5bb9\u3002

        pick(uri)\n
        "},{"location":"qsl4a/core/intent/#intent_2","title":"\u5e38\u89c1 Intent \u65b9\u6cd5)","text":""},{"location":"qsl4a/core/intent/#scanbarcode","title":"scanBarcode()","text":"

        \u542f\u52a8\u6761\u7801\u626b\u63cf\u5668\u3002

        scanBarcode()\n

        \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5b57\u7b26\u4e32

        "},{"location":"qsl4a/core/intent/#send","title":"send()","text":"

        \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u5185\u5bb9\u3002

        send(type, content)\n

        \u53c2\u6570\uff1a - type (str): MIME \u7c7b\u578b - content (str): \u8981\u5206\u4eab\u7684\u5185\u5bb9

        "},{"location":"qsl4a/core/intent/#sendtext","title":"sendText()","text":"

        \u53d1\u9001\u6587\u672c\u5185\u5bb9\u3002

        sendText(text)\n

        \u53c2\u6570\uff1a - text (str): \u8981\u53d1\u9001\u7684\u6587\u672c

        "},{"location":"qsl4a/core/intent/#sendemail","title":"sendEmail()","text":"

        \u53d1\u9001\u7535\u5b50\u90ae\u4ef6\u3002

        sendEmail(to, subject, body, attachment=None)\n

        \u53c2\u6570\uff1a - to (str or list): \u6536\u4ef6\u4eba\u7535\u5b50\u90ae\u4ef6\u5730\u5740 - subject (str): \u7535\u5b50\u90ae\u4ef6\u4e3b\u9898 - body (str): \u7535\u5b50\u90ae\u4ef6\u6b63\u6587 - attachment (str, optional): \u9644\u4ef6\u6587\u4ef6\u8def\u5f84

        "},{"location":"qsl4a/core/intent/#pathtouri","title":"pathToUri()","text":"

        \u5c06\u6587\u4ef6\u8def\u5f84\u8f6c\u6362\u4e3a\u5185\u5bb9 URI\u3002

        pathToUri(path)\n

        \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

        \u8fd4\u56de\uff1a \u5185\u5bb9 URI \u5b57\u7b26\u4e32

        "},{"location":"qsl4a/core/intent/#openfile","title":"openFile()","text":"

        \u7528\u9002\u5f53\u7684\u5e94\u7528\u7a0b\u5e8f\u6253\u5f00\u6587\u4ef6\u3002

        openFile(path)\n

        \u53c2\u6570\uff1a - path (str): \u8981\u6253\u5f00\u7684\u6587\u4ef6\u8def\u5f84

        "},{"location":"qsl4a/core/intent/#sendfile","title":"sendFile()","text":"

        \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u6587\u4ef6\u3002

        sendFile(path)\n

        \u53c2\u6570\uff1a - path (str): \u8981\u53d1\u9001\u7684\u6587\u4ef6\u8def\u5f84

        "},{"location":"qsl4a/core/intent/#getpathtype","title":"getPathType()","text":"

        \u83b7\u53d6\u6587\u4ef6\u8def\u5f84\u7684 MIME \u7c7b\u578b\u3002

        getPathType(path)\n

        \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

        \u8fd4\u56de\uff1a MIME \u7c7b\u578b\u5b57\u7b26\u4e32

        "},{"location":"qsl4a/core/intent/#viewmap","title":"viewMap()","text":"

        \u5728\u6307\u5b9a\u4f4d\u7f6e\u6253\u5f00\u5730\u56fe\u3002

        viewMap(latitude, longitude)\n

        \u53c2\u6570\uff1a - latitude (float): \u7eac\u5ea6 - longitude (float): \u7ecf\u5ea6

        "},{"location":"qsl4a/core/intent/#viewcontacts","title":"viewContacts()","text":"

        \u6253\u5f00\u8054\u7cfb\u4eba\u5e94\u7528\u3002

        viewContacts()\n
        "},{"location":"qsl4a/core/intent/#search","title":"search()","text":"

        \u6267\u884c\u7f51\u7edc\u641c\u7d22\u3002

        search(query)\n

        \u53c2\u6570\uff1a - query (str): \u641c\u7d22\u67e5\u8be2

        "},{"location":"qsl4a/core/intent/#viewhtml","title":"viewHtml()","text":"

        \u67e5\u770b HTML \u5185\u5bb9\u3002

        viewHtml(content, encoding=None)\n

        \u53c2\u6570\uff1a - content (str): HTML \u5185\u5bb9 - encoding (str, optional): \u5b57\u7b26\u7f16\u7801

        "},{"location":"qsl4a/core/intent/#webviewshow","title":"webViewShow()","text":"

        \u5728 WebView \u4e2d\u663e\u793a\u7f51\u9875\u5185\u5bb9\u3002\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 viewHtml\u3002

        webViewShow(url)\n

        \u53c2\u6570\uff1a - url (str): \u7f51\u9875 URL

        "},{"location":"qsl4a/core/intent/#editoropen","title":"editorOpen()","text":"

        \u6253\u5f00\u6587\u672c\u7f16\u8f91\u5668\u3002

        editorOpen(path=None, create=False)\n

        \u53c2\u6570\uff1a - path (str, optional): \u8981\u7f16\u8f91\u7684\u6587\u4ef6\u8def\u5f84 - create (bool, optional): \u5982\u679c\u4e0d\u5b58\u5728\u5219\u521b\u5efa

        "},{"location":"qsl4a/core/intent/#uri","title":"\u8f85\u52a9\u7c7b\uff1aUri","text":"

        \u521b\u5efa Intent \u7684 URI \u5bf9\u8c61\uff1a

        from androidhelper.Intent import Uri\n\nuri = Uri(\"file:///sdcard/test.txt\")\n
        "},{"location":"qsl4a/core/intent/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/intent/#_7","title":"\u6253\u5f00\u7f51\u9875","text":"
        intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"http://www.example.com\"\n).result\ndroid.startActivityIntent(intent)\n
        "},{"location":"qsl4a/core/intent/#_8","title":"\u5206\u4eab\u6587\u672c","text":"
        intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_TEXT: \"Hello from QPython!\",\n        droid.Intent.EXTRA_SUBJECT: \"Test\"\n    },\n    type=\"text/plain\"\n).result\ndroid.startActivityIntent(intent)\n
        "},{"location":"qsl4a/core/intent/#_9","title":"\u6253\u5f00\u6587\u4ef6","text":"
        intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"file:///sdcard/document.pdf\",\n    type=\"application/pdf\"\n).result\ndroid.startActivityIntent(intent)\n
        "},{"location":"qsl4a/core/intent/#_10","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":"
        result = droid.pickContact()\ncontact_uri = result.result\n
        "},{"location":"qsl4a/core/intent/#_11","title":"\u53d1\u9001\u7535\u5b50\u90ae\u4ef6","text":"
        intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_EMAIL: [\"test@example.com\"],\n        droid.Intent.EXTRA_SUBJECT: \"Hello\",\n        droid.Intent.EXTRA_TEXT: \"Message body\"\n    },\n    type=\"message/rfc822\"\n).result\ndroid.startActivityIntent(intent)\n
        "},{"location":"qsl4a/core/intent/#_12","title":"\u6253\u5f00\u5e94\u7528","text":"
        intent = droid.makeIntent(\n    action=droid.Intent.ACTION_MAIN,\n    packagename=\"com.android.settings\",\n    classname=\"com.android.settings.Settings\"\n).result\ndroid.startActivityIntent(intent)\n
        "},{"location":"qsl4a/hardware/bluetooth/","title":"\u84dd\u7259 API","text":"

        \u63a7\u5236\u84dd\u7259\u9002\u914d\u5668\u5e76\u4e0e\u84dd\u7259\u8bbe\u5907\u901a\u4fe1\u3002

        "},{"location":"qsl4a/hardware/bluetooth/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/hardware/bluetooth/#togglebluetoothstate","title":"toggleBluetoothState()","text":"

        \u6253\u5f00/\u5173\u95ed\u84dd\u7259\u3002

        toggleBluetoothState(enabled=None, prompt=True)\n

        \u53c2\u6570\uff1a - enabled (bool): True=\u5f00\uff0cFalse=\u5173\uff0cNone=\u5207\u6362 - prompt (bool): \u663e\u793a\u7528\u6237\u63d0\u793a

        "},{"location":"qsl4a/hardware/bluetooth/#checkbluetoothstate","title":"checkBluetoothState()","text":"

        \u68c0\u67e5\u84dd\u7259\u662f\u5426\u5df2\u542f\u7528\u3002

        checkBluetoothState()\n

        \u8fd4\u56de\uff1a True/False

        "},{"location":"qsl4a/hardware/bluetooth/#getlocalname","title":"GetLocalName()","text":"

        \u83b7\u53d6\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

        GetLocalName()\n
        "},{"location":"qsl4a/hardware/bluetooth/#setlocalname","title":"SetLocalName()","text":"

        \u8bbe\u7f6e\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

        SetLocalName(name)\n
        "},{"location":"qsl4a/hardware/bluetooth/#getscanmode","title":"GetScanMode()","text":"

        \u83b7\u53d6\u53ef\u53d1\u73b0\u6027\u6a21\u5f0f\u3002

        GetScanMode()\n

        \u8fd4\u56de\uff1a - -1: \u5df2\u7981\u7528 - 0: \u4e0d\u53ef\u53d1\u73b0\uff0c\u4e0d\u53ef\u8fde\u63a5 - 1: \u53ef\u8fde\u63a5\uff0c\u4e0d\u53ef\u53d1\u73b0 - 3: \u53ef\u8fde\u63a5\u4e14\u53ef\u53d1\u73b0

        "},{"location":"qsl4a/hardware/bluetooth/#makediscoverable","title":"MakeDiscoverable()","text":"

        \u4f7f\u8bbe\u5907\u53ef\u53d1\u73b0\u3002

        MakeDiscoverable(duration=300)\n

        \u53c2\u6570\uff1a - duration (int): \u53ef\u53d1\u73b0\u7684\u79d2\u6570

        "},{"location":"qsl4a/hardware/bluetooth/#_2","title":"\u53d1\u73b0","text":""},{"location":"qsl4a/hardware/bluetooth/#discoverystart","title":"DiscoveryStart()","text":"

        \u5f00\u59cb\u8bbe\u5907\u53d1\u73b0\u3002

        DiscoveryStart()\n
        "},{"location":"qsl4a/hardware/bluetooth/#discoverycancel","title":"DiscoveryCancel()","text":"

        \u53d6\u6d88\u53d1\u73b0\u3002

        DiscoveryCancel()\n
        "},{"location":"qsl4a/hardware/bluetooth/#getreceiveddevices","title":"GetReceivedDevices()","text":"

        \u83b7\u53d6\u53d1\u73b0\u7684\u8bbe\u5907\u3002

        GetReceivedDevices()\n

        \u8fd4\u56de\uff1a \u8bbe\u5907\u4fe1\u606f\u5b57\u5178\u5217\u8868

        "},{"location":"qsl4a/hardware/bluetooth/#getbondeddevices","title":"GetBondedDevices()","text":"

        \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\u3002

        GetBondedDevices()\n

        \u8fd4\u56de\uff1a \u914d\u5bf9\u8bbe\u5907\u4fe1\u606f\u5217\u8868

        "},{"location":"qsl4a/hardware/bluetooth/#_3","title":"\u8fde\u63a5","text":""},{"location":"qsl4a/hardware/bluetooth/#connect","title":"Connect()","text":"

        \u8fde\u63a5\u5230\u8bbe\u5907\u3002

        Connect(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", address=None)\n

        \u53c2\u6570\uff1a - uuid (str): \u670d\u52a1 UUID - address (str): \u8bbe\u5907\u5730\u5740\uff08None = \u663e\u793a\u9009\u62e9\u5668\uff09

        \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

        "},{"location":"qsl4a/hardware/bluetooth/#accept","title":"Accept()","text":"

        \u63a5\u53d7\u4f20\u5165\u8fde\u63a5\u3002

        Accept(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", timeout=0)\n
        "},{"location":"qsl4a/hardware/bluetooth/#activeconnections","title":"ActiveConnections()","text":"

        \u68c0\u67e5\u6d3b\u52a8\u8fde\u63a5\u3002

        ActiveConnections()\n
        "},{"location":"qsl4a/hardware/bluetooth/#stop","title":"Stop()","text":"

        \u65ad\u5f00\u8fde\u63a5\u3002

        Stop(connID=None)\n
        "},{"location":"qsl4a/hardware/bluetooth/#_4","title":"\u901a\u4fe1","text":""},{"location":"qsl4a/hardware/bluetooth/#write","title":"Write()","text":"

        \u53d1\u9001 ASCII \u6570\u636e\u3002

        Write(ascii, connID=\"\")\n
        "},{"location":"qsl4a/hardware/bluetooth/#writebinary","title":"WriteBinary()","text":"

        \u53d1\u9001\u4e8c\u8fdb\u5236\u6570\u636e\uff08base64 \u7f16\u7801\uff09\u3002

        WriteBinary(base64, connID=None)\n
        "},{"location":"qsl4a/hardware/bluetooth/#read","title":"Read()","text":"

        \u8bfb\u53d6 ASCII \u6570\u636e\u3002

        Read(bufferSize=4096, connID=None)\n
        "},{"location":"qsl4a/hardware/bluetooth/#readbinary","title":"ReadBinary()","text":"

        \u8bfb\u53d6\u4e8c\u8fdb\u5236\u6570\u636e\u3002

        ReadBinary(bufferSize=4096, connID=None)\n
        "},{"location":"qsl4a/hardware/bluetooth/#readline","title":"ReadLine()","text":"

        \u8bfb\u53d6\u4e00\u884c\u3002

        ReadLine(connID=None)\n
        "},{"location":"qsl4a/hardware/bluetooth/#readready","title":"ReadReady()","text":"

        \u68c0\u67e5\u662f\u5426\u6709\u53ef\u7528\u6570\u636e\u3002

        ReadReady(connID=None)\n
        "},{"location":"qsl4a/hardware/bluetooth/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u7528\u84dd\u7259\ndroid.toggleBluetoothState(True)\n\n# \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\ndevices = droid.GetBondedDevices().result\nfor dev in devices:\n    print(f\"{dev['name']}: {dev['address']}\")\n\n# \u8fde\u63a5\u5230\u8bbe\u5907\ndroid.Connect(address=\"00:11:22:33:44:55\")\n\n# \u53d1\u9001\u6570\u636e\ndroid.Write(\"Hello Bluetooth!\")\n\n# \u8bfb\u53d6\u54cd\u5e94\ndata = droid.Read(1024).result\n
        "},{"location":"qsl4a/hardware/camera/","title":"\u76f8\u673a API","text":"

        \u62cd\u6444\u7167\u7247\u548c\u5f55\u5236\u89c6\u9891\u3002

        "},{"location":"qsl4a/hardware/camera/#_1","title":"\u7167\u7247\u62cd\u6444","text":""},{"location":"qsl4a/hardware/camera/#takepicture","title":"takePicture()","text":"

        \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u6444\u7167\u7247\u3002

        takePicture(path=None)\n

        \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8fd4\u56de\u56fe\u50cf\u6570\u636e

        \u8fd4\u56de\uff1a \u56fe\u50cf\u8def\u5f84\u6216\u56fe\u50cf\u6570\u636e

        "},{"location":"qsl4a/hardware/camera/#cameracapturepicture","title":"cameraCapturePicture()","text":"

        \u4f7f\u7528\u9ad8\u7ea7\u76f8\u673a\u63a7\u5236\u62cd\u6444\u7167\u7247\u3002

        cameraCapturePicture(targetPath=None, cameraId=0, useAutoFocus=True)\n

        \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - useAutoFocus (bool): \u542f\u7528\u81ea\u52a8\u5bf9\u7126

        \u8fd4\u56de\uff1a \u62cd\u6444\u7684\u56fe\u50cf\u8def\u5f84

        "},{"location":"qsl4a/hardware/camera/#camerasettorchmode","title":"cameraSetTorchMode()","text":"

        \u63a7\u5236\u76f8\u673a\u95ea\u5149\u706f/\u624b\u7535\u7b52\u3002

        cameraSetTorchMode(enabled)\n

        \u53c2\u6570\uff1a - enabled (bool): True \u6253\u5f00\uff0cFalse \u5173\u95ed

        \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

        "},{"location":"qsl4a/hardware/camera/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

        \u622a\u56fe\u3002

        imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

        \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

        "},{"location":"qsl4a/hardware/camera/#_2","title":"\u89c6\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#takevideo","title":"takeVideo()","text":"

        \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\u3002

        takeVideo(path=None, quality=1)\n

        \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-4\uff09 - 0: 160x120 - 1: 320x240 - 2: 352x288 - 3: 640x480 - 4: 800x480

        "},{"location":"qsl4a/hardware/camera/#recordercapturevideo","title":"recorderCaptureVideo()","text":"

        \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\u3002

        recorderCaptureVideo(targetPath=None, duration=10, cameraId=0, quality=8)\n

        \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - duration (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a10\uff09 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-8\uff0c\u8d8a\u9ad8\u8d8a\u597d\uff09

        \u8fd4\u56de\uff1a \u89c6\u9891\u6587\u4ef6\u8def\u5f84

        "},{"location":"qsl4a/hardware/camera/#recordaudio","title":"recordAudio()","text":"

        \u5f55\u5236\u97f3\u9891\u3002

        recordAudio()\n

        \u8fd4\u56de\uff1a \u97f3\u9891\u6587\u4ef6\u8def\u5f84

        "},{"location":"qsl4a/hardware/camera/#_3","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

        \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\u3002

        recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

        \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\uff09 - targetPixels (int): \u5206\u8fa8\u7387 - frameRate (int): FPS - bitRate (int): \u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa - autoStart (bool): \u7acb\u5373\u5f00\u59cb

        "},{"location":"qsl4a/hardware/camera/#recorderstart","title":"recorderStart()","text":"

        \u5f00\u59cb\u5f55\u5236\u3002

        recorderStart()\n
        "},{"location":"qsl4a/hardware/camera/#recorderpause","title":"recorderPause()","text":"

        \u6682\u505c\u5f55\u5236\u3002

        recorderPause()\n
        "},{"location":"qsl4a/hardware/camera/#recorderresume","title":"recorderResume()","text":"

        \u6062\u590d\u5f55\u5236\u3002

        recorderResume()\n
        "},{"location":"qsl4a/hardware/camera/#_4","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/camera/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

        \u5f00\u59cb\u97f3\u91cf\u68c0\u6d4b\u3002

        recorderSoundVolumeDetect(interval=100)\n
        "},{"location":"qsl4a/hardware/camera/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

        \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

        recorderSoundVolumeGetDb()\n
        "},{"location":"qsl4a/hardware/camera/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u7167\nphoto_path = droid.takePicture(\"/sdcard/photo.jpg\").result\nprint(f\"Photo saved: {photo_path}\")\n\n# \u4f7f\u7528\u524d\u7f6e\u76f8\u673a\u548c\u81ea\u52a8\u5bf9\u7126\u62cd\u7167\ncamera_path = droid.cameraCapturePicture(\"/sdcard/selfie.jpg\", cameraId=1, useAutoFocus=True).result\nprint(f\"Front camera photo: {camera_path}\")\n\n# \u63a7\u5236\u95ea\u5149\u706f\ndroid.cameraSetTorchMode(True)  # \u6253\u5f00\u95ea\u5149\u706f\n\n# \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\nvideo_path = droid.takeVideo(\"/sdcard/video.mp4\", quality=3).result\nprint(f\"Video saved: {video_path}\")\n\n# \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\nvideo_path = droid.recorderCaptureVideo(\"/sdcard/movie.mp4\", duration=30, cameraId=0, quality=8).result\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n
        "},{"location":"qsl4a/hardware/recorder/","title":"\u97f3\u9891\u5f55\u5236 API","text":"

        \u4ece\u9ea6\u514b\u98ce\u548c\u8bbe\u5907\u5c4f\u5e55\u5f55\u5236\u97f3\u9891\u3002

        "},{"location":"qsl4a/hardware/recorder/#_1","title":"\u97f3\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recordaudio","title":"recordAudio()","text":"

        \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\u3002

        recordAudio()\n

        \u8fd4\u56de\uff1a \u5f55\u5236\u7684\u97f3\u9891\u6587\u4ef6\u8def\u5f84

        "},{"location":"qsl4a/hardware/recorder/#recorderstartmicrophone","title":"recorderStartMicrophone()","text":"

        \u5f00\u59cb\u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\u3002

        recorderStartMicrophone(targetPath=None)\n

        \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u5f55\u5236\u7684\u8def\u5f84

        "},{"location":"qsl4a/hardware/recorder/#_2","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

        \u5f00\u59cb\u5e26\u97f3\u9891\u7684\u5c4f\u5e55\u5f55\u5236\u3002

        recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

        \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\u97f3\u9891\uff09 - targetPixels (int): \u76ee\u6807\u5206\u8fa8\u7387\uff08\u50cf\u7d20\uff09 - frameRate (int): \u6bcf\u79d2\u5e27\u6570\uff08\u9ed8\u8ba4\uff1a30\uff09 - bitRate (int): \u89c6\u9891\u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa\u89c6\u9891 - autoStart (bool): \u7acb\u5373\u5f00\u59cb\u5f55\u5236

        \u8fd4\u56de\uff1a \u64cd\u4f5c\u7ed3\u679c

        "},{"location":"qsl4a/hardware/recorder/#recorderstart","title":"recorderStart()","text":"

        \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\uff08\u5f53 autoStart=False \u65f6\uff09\u3002

        recorderStart()\n
        "},{"location":"qsl4a/hardware/recorder/#recorderpause","title":"recorderPause()","text":"

        \u6682\u505c\u6b63\u5728\u8fdb\u884c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

        recorderPause()\n
        "},{"location":"qsl4a/hardware/recorder/#recorderresume","title":"recorderResume()","text":"

        \u6062\u590d\u6682\u505c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

        recorderResume()\n
        "},{"location":"qsl4a/hardware/recorder/#_3","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/recorder/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

        \u5f00\u59cb\u76d1\u63a7\u97f3\u91cf\u7ea7\u522b\u3002

        recorderSoundVolumeDetect(interval=100)\n

        \u53c2\u6570\uff1a - interval (int): \u68c0\u6d4b\u95f4\u9694\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a100\uff09

        "},{"location":"qsl4a/hardware/recorder/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

        \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

        recorderSoundVolumeGetDb()\n

        \u8fd4\u56de\uff1a \u5f53\u524d\u97f3\u91cf\u7ea7\u522b\uff08dB\uff09

        "},{"location":"qsl4a/hardware/recorder/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\nprint(\"Recording audio...\")\naudio_path = droid.recordAudio().result\nprint(f\"Saved to: {audio_path}\")\n\n# \u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\ndroid.recorderStartMicrophone(\"/sdcard/my_recording.mp3\")\ntime.sleep(5)\ndroid.recorderStop()\n\n# \u5e26\u97f3\u9891\u5f55\u5236\u5c4f\u5e55\nprint(\"Starting screen recording...\")\ndroid.recorderStartScreenRecord(\n    path=\"/sdcard/screen_record.mp4\",\n    audio=1,\n    frameRate=30,\n    autoStart=True\n)\ntime.sleep(10)\ndroid.recorderStop()\n\n# \u76d1\u63a7\u97f3\u91cf\ndroid.recorderSoundVolumeDetect(interval=100)\ntime.sleep(3)\nvolume = droid.recorderSoundVolumeGetDb().result\nprint(f\"Current volume: {volume} dB\")\n
        "},{"location":"qsl4a/hardware/usbserial/","title":"USB \u4e3b\u673a\u4e32\u884c API","text":"

        \u4e0e USB \u4e32\u884c\u8bbe\u5907\u901a\u4fe1\uff08\u9700\u8981 USB OTG \u652f\u6301\u548c Android 3.1+\uff09\u3002

        "},{"location":"qsl4a/hardware/usbserial/#usb","title":"USB \u4e32\u884c\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialopen","title":"usbHostSerialOpen()","text":"

        \u6253\u5f00\u4e0e USB \u4e32\u884c\u8bbe\u5907\u7684\u8fde\u63a5\u3002

        usbHostSerialOpen(device, baudRate=9600)\n

        \u53c2\u6570\uff1a - device (str): USB \u8bbe\u5907\u8def\u5f84\u6216\u6807\u8bc6\u7b26 - baudRate (int): \u6ce2\u7279\u7387\uff08\u9ed8\u8ba4\uff1a9600\uff09

        \u8fd4\u56de\uff1a \u5982\u679c\u6253\u5f00\u6210\u529f\u5219\u4e3a True

        "},{"location":"qsl4a/hardware/usbserial/#usbhostserialclose","title":"usbHostSerialClose()","text":"

        \u5173\u95ed USB \u4e32\u884c\u8fde\u63a5\u3002

        usbHostSerialClose()\n
        "},{"location":"qsl4a/hardware/usbserial/#usbhostserialread","title":"usbHostSerialRead()","text":"

        \u4ece USB \u4e32\u884c\u8bfb\u53d6\u6570\u636e\u3002

        usbHostSerialRead(bufferSize=1024)\n

        \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570\uff08\u9ed8\u8ba4\uff1a1024\uff09

        \u8fd4\u56de\uff1a \u8bfb\u53d6\u7684\u6570\u636e\u5b57\u7b26\u4e32

        "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwrite","title":"usbHostSerialWrite()","text":"

        \u5411 USB \u4e32\u884c\u5199\u5165\u6570\u636e\u3002

        usbHostSerialWrite(data)\n

        \u53c2\u6570\uff1a - data (str): \u8981\u5199\u5165\u7684\u5b57\u7b26\u4e32\u6570\u636e

        "},{"location":"qsl4a/hardware/usbserial/#usbhostserialavailable","title":"usbHostSerialAvailable()","text":"

        \u68c0\u67e5\u662f\u5426\u6709\u53ef\u8bfb\u53d6\u7684\u6570\u636e\u3002

        usbHostSerialAvailable()\n

        \u8fd4\u56de\uff1a \u53ef\u7528\u5b57\u8282\u6570

        "},{"location":"qsl4a/hardware/usbserial/#_1","title":"\u914d\u7f6e\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetbaudrate","title":"usbHostSerialSetBaudRate()","text":"

        \u8bbe\u7f6e\u6ce2\u7279\u7387\u3002

        usbHostSerialSetBaudRate(baudRate)\n

        \u53c2\u6570\uff1a - baudRate (int): \u6ce2\u7279\u7387

        "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetdatabits","title":"usbHostSerialSetDataBits()","text":"

        \u8bbe\u7f6e\u6570\u636e\u4f4d\uff085\u30016\u30017 \u6216 8\uff09\u3002

        usbHostSerialSetDataBits(dataBits)\n

        \u53c2\u6570\uff1a - dataBits (int): \u6570\u636e\u4f4d\uff085-8\uff09

        "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetstopbits","title":"usbHostSerialSetStopBits()","text":"

        \u8bbe\u7f6e\u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09\u3002

        usbHostSerialSetStopBits(stopBits)\n

        \u53c2\u6570\uff1a - stopBits (float): \u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09

        "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetparity","title":"usbHostSerialSetParity()","text":"

        \u8bbe\u7f6e\u6821\u9a8c\u4f4d\uff08\u65e0\u3001\u5947\u3001\u5076\u3001\u6807\u8bb0\u3001\u7a7a\u683c\uff09\u3002

        usbHostSerialSetParity(parity)\n

        \u53c2\u6570\uff1a - parity (str): \u6821\u9a8c\u6a21\u5f0f\uff08'none'\u3001'odd'\u3001'even'\u3001'mark'\u3001'space'\uff09

        "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetflowcontrol","title":"usbHostSerialSetFlowControl()","text":"

        \u8bbe\u7f6e\u6d41\u63a7\u5236\uff08\u65e0\u3001\u786c\u4ef6\u3001\u8f6f\u4ef6\uff09\u3002

        usbHostSerialSetFlowControl(flowControl)\n

        \u53c2\u6570\uff1a - flowControl (str): \u6d41\u63a7\u5236\u6a21\u5f0f\uff08'none'\u3001'hardware'\u3001'software'\uff09

        "},{"location":"qsl4a/hardware/usbserial/#usbhostserialreadhex","title":"usbHostSerialReadHex()","text":"

        \u4ee5\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u8bfb\u53d6\u6570\u636e\u3002

        usbHostSerialReadHex(bufferSize=1024)\n

        \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570

        \u8fd4\u56de\uff1a \u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

        "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwritehex","title":"usbHostSerialWriteHex()","text":"

        \u4ece\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u5199\u5165\u6570\u636e\u3002

        usbHostSerialWriteHex(hexString)\n

        \u53c2\u6570\uff1a - hexString (str): \u8981\u5199\u5165\u7684\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

        "},{"location":"qsl4a/hardware/usbserial/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6253\u5f00 USB \u4e32\u884c\u8fde\u63a5\nif droid.usbHostSerialOpen(\"/dev/bus/usb/001/001\", 115200).result:\n    print(\"USB serial opened\")\n\n    # \u5199\u5165\u6570\u636e\n    droid.usbHostSerialWrite(\"AT\\r\")\n\n    # \u8bfb\u53d6\u54cd\u5e94\n    response = droid.usbHostSerialRead(1024).result\n    print(f\"Response: {response}\")\n\n    # \u6216\u4f7f\u7528\u5341\u516d\u8fdb\u5236\n    droid.usbHostSerialWriteHex(\"41540D0A\")  # \"AT\\r\\n\"\n\n    # \u5173\u95ed\u8fde\u63a5\n    droid.usbHostSerialClose()\n

        \u6ce8\u610f\uff1a USB \u4e32\u884c\u9700\u8981\uff1a - Android 3.1+ (API 12) - USB OTG \u7ebf/\u9002\u914d\u5668 - \u8bbe\u5907\u4e0a\u7684 USB \u4e3b\u673a\u6a21\u5f0f\u652f\u6301 - \u517c\u5bb9\u7684\u4e32\u884c\u8bbe\u5907

        "},{"location":"qsl4a/hardware/webcam/","title":"\u7f51\u7edc\u6444\u50cf\u5934 API","text":"

        \u4f7f\u7528 MJPEG \u4ece\u8bbe\u5907\u76f8\u673a\u6d41\u5f0f\u4f20\u8f93\u89c6\u9891\u3002

        "},{"location":"qsl4a/hardware/webcam/#mjpeg","title":"MJPEG \u6d41\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#webcamstart","title":"webcamStart()","text":"

        \u4ece\u7f51\u7edc\u6444\u50cf\u5934\u542f\u52a8 MJPEG \u6d41\u3002

        webcamStart(resolutionLevel=0, jpegQuality=20, port=0)\n

        \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf 1-100\uff08\u9ed8\u8ba4\uff1a20\uff09 - port (int): \u7aef\u53e3\u53f7\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\uff09

        \u8fd4\u56de\uff1a \u6d41\u7684 (\u5730\u5740, \u7aef\u53e3) \u5143\u7ec4

        "},{"location":"qsl4a/hardware/webcam/#webcamadjustquality","title":"webcamAdjustQuality()","text":"

        \u8c03\u6574\u6d3b\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u7684\u8d28\u91cf\u3002

        webcamAdjustQuality(resolutionLevel=0, jpegQuality=20)\n

        \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b - jpegQuality (int): JPEG \u8d28\u91cf 1-100

        "},{"location":"qsl4a/hardware/webcam/#webcamstop","title":"webcamStop()","text":"

        \u505c\u6b62\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u3002

        webcamStop()\n
        "},{"location":"qsl4a/hardware/webcam/#_1","title":"\u76f8\u673a\u9884\u89c8\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#camerastartpreview","title":"cameraStartPreview()","text":"

        \u5f00\u59cb\u5e26\u4e8b\u4ef6\u751f\u6210\u7684\u76f8\u673a\u9884\u89c8\u6a21\u5f0f\u3002

        cameraStartPreview(resolutionLevel=0, jpegQuality=20, filepath=None)\n

        \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf\uff08\u9ed8\u8ba4\uff1a20\uff09 - filepath (str, optional): \u4fdd\u5b58\u9884\u89c8\u5e27\u7684\u6587\u4ef6\u8def\u5f84

        \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

        \u6ce8\u610f\uff1a \u751f\u6210\u5e26\u6709\u5e27\u6570\u636e\u7684 'preview' \u4e8b\u4ef6\u3002

        "},{"location":"qsl4a/hardware/webcam/#camerastoppreview","title":"cameraStopPreview()","text":"

        \u505c\u6b62\u76f8\u673a\u9884\u89c8\u3002

        cameraStopPreview()\n
        "},{"location":"qsl4a/hardware/webcam/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\nstream_info = droid.webcamStart(\n    resolutionLevel=0,\n    jpegQuality=30,\n    port=8080\n).result\nprint(f\"Stream available at {stream_info[0]}:{stream_info[1]}\")\n\n# \u6d41\u5f0f\u4f20\u8f93\u65f6\u8c03\u6574\u8d28\u91cf\ntime.sleep(5)\ndroid.webcamAdjustQuality(resolutionLevel=1, jpegQuality=50)\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.webcamStop()\n\n# \u6216\u4f7f\u7528\u9884\u89c8\u6a21\u5f0f\nprint(\"Starting preview...\")\ndroid.cameraStartPreview()\n\n# \u7b49\u5f85\u9884\u89c8\u4e8b\u4ef6\nfor i in range(10):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'preview':\n        print(f\"Got preview frame: {event['data']}\")\n\ndroid.cameraStopPreview()\n
        "},{"location":"qsl4a/media/image/","title":"\u56fe\u50cf\u5904\u7406 API","text":"

        \u538b\u7f29\u548c\u5904\u7406\u56fe\u50cf\u3002

        "},{"location":"qsl4a/media/image/#_1","title":"\u56fe\u50cf\u538b\u7f29","text":""},{"location":"qsl4a/media/image/#imagecompress","title":"imageCompress()","text":"

        \u538b\u7f29\u56fe\u50cf\u6587\u4ef6\u3002

        imageCompress(srcPath, destPath, targetByteSize=0, targetWidth=0, targetHeight=0)\n

        \u53c2\u6570\uff1a - srcPath (str): \u6e90\u56fe\u50cf\u8def\u5f84 - destPath (str): \u8f93\u51fa\u8def\u5f84 - targetByteSize (int): \u76ee\u6807\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff080 = \u65e0\u9650\u5236\uff09 - targetWidth (int): \u76ee\u6807\u5bbd\u5ea6\uff080 = \u539f\u59cb\uff09 - targetHeight (int): \u76ee\u6807\u9ad8\u5ea6\uff080 = \u539f\u59cb\uff09

        \u8fd4\u56de\uff1a \u538b\u7f29\u540e\u7684\u56fe\u50cf\u8def\u5f84

        "},{"location":"qsl4a/media/image/#_2","title":"\u622a\u56fe","text":""},{"location":"qsl4a/media/image/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

        \u622a\u53d6\u5c4f\u5e55\u3002

        imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

        \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

        \u8fd4\u56de\uff1a \u622a\u56fe\u8def\u5f84

        "},{"location":"qsl4a/media/image/#_3","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/image/#videoplay","title":"videoPlay()","text":"

        \u5728\u5168\u5c4f\u6a21\u5f0f\u4e0b\u64ad\u653e\u89c6\u9891\u6587\u4ef6\u3002

        videoPlay(path, wait=True)\n

        \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

        "},{"location":"qsl4a/media/image/#_4","title":"\u6761\u7801\u626b\u63cf","text":""},{"location":"qsl4a/media/image/#scanbarcodefromimage","title":"scanBarcodeFromImage()","text":"

        \u4ece\u56fe\u50cf\u6587\u4ef6\u626b\u63cf\u6761\u7801/\u4e8c\u7ef4\u7801\u3002

        scanBarcodeFromImage(path, compressRatio=0, x=0, y=0, width=0, height=0)\n

        \u53c2\u6570\uff1a - path (str): \u56fe\u50cf\u6587\u4ef6\u8def\u5f84 - compressRatio (int): \u538b\u7f29\u6bd4\uff080 = \u4e0d\u538b\u7f29\uff09 - x, y, width, height (int): \u8981\u626b\u63cf\u7684\u533a\u57df\uff080 = \u5b8c\u6574\u56fe\u50cf\uff09

        \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5185\u5bb9

        "},{"location":"qsl4a/media/image/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n\n# \u538b\u7f29\u56fe\u50cf\ncompressed = droid.imageCompress(\n    \"/sdcard/large_photo.jpg\",\n    \"/sdcard/compressed.jpg\",\n    targetByteSize=102400,  # \u76ee\u6807\u7ea6 100KB\n    targetWidth=1920,\n    targetHeight=1080\n).result\nprint(f\"Saved: {compressed}\")\n\n# \u64ad\u653e\u89c6\u9891\nvideo_path = \"/sdcard/movie.mp4\"\ndroid.videoPlay(video_path, wait=True)\n\n# \u4ece\u56fe\u50cf\u626b\u63cf\u6761\u7801\nresult = droid.scanBarcodeFromImage(\"/sdcard/qr_code.png\").result\nprint(f\"Barcode: {result}\")\n
        "},{"location":"qsl4a/media/mediaplayer/","title":"\u5a92\u4f53\u64ad\u653e\u5668 API","text":"

        \u63a7\u5236\u97f3\u9891\u548c\u89c6\u9891\u64ad\u653e\u3002

        "},{"location":"qsl4a/media/mediaplayer/#_1","title":"\u64ad\u653e\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplay","title":"mediaPlay()","text":"

        \u64ad\u653e\u5a92\u4f53\u6587\u4ef6\u3002

        mediaPlay(url, tag=\"default\", play=True)\n

        \u53c2\u6570\uff1a - url (str): \u5a92\u4f53\u6587\u4ef6\u8def\u5f84\u6216 URL - tag (str): \u64ad\u653e\u5668\u6807\u8bc6\u7b26 - play (bool): \u81ea\u52a8\u5f00\u59cb\u64ad\u653e

        "},{"location":"qsl4a/media/mediaplayer/#mediaplaystart","title":"mediaPlayStart()","text":"

        \u5f00\u59cb\u64ad\u653e\u3002

        mediaPlayStart(tag=\"default\")\n
        "},{"location":"qsl4a/media/mediaplayer/#mediaplaypause","title":"mediaPlayPause()","text":"

        \u6682\u505c\u64ad\u653e\u3002

        mediaPlayPause(tag=\"default\")\n
        "},{"location":"qsl4a/media/mediaplayer/#mediaplayclose","title":"mediaPlayClose()","text":"

        \u5173\u95ed\u64ad\u653e\u5668\u3002

        mediaPlayClose(tag=\"default\")\n
        "},{"location":"qsl4a/media/mediaplayer/#mediaplayseek","title":"mediaPlaySeek()","text":"

        \u8df3\u8f6c\u5230\u4f4d\u7f6e\u3002

        mediaPlaySeek(msec, tag=\"default\")\n

        \u53c2\u6570\uff1a - msec (int): \u4f4d\u7f6e\uff08\u6beb\u79d2\uff09

        "},{"location":"qsl4a/media/mediaplayer/#mediaplaysetlooping","title":"mediaPlaySetLooping()","text":"

        \u8bbe\u7f6e\u5faa\u73af\u6a21\u5f0f\u3002

        mediaPlaySetLooping(enabled, tag=\"default\")\n
        "},{"location":"qsl4a/media/mediaplayer/#_2","title":"\u64ad\u653e\u5668\u4fe1\u606f","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplayinfo","title":"mediaPlayInfo()","text":"

        \u83b7\u53d6\u64ad\u653e\u4fe1\u606f\u3002

        mediaPlayInfo(tag=\"default\")\n

        \u8fd4\u56de\uff1a \u5305\u542b\u65f6\u957f\u3001\u4f4d\u7f6e\u7b49\u7684\u5b57\u5178

        "},{"location":"qsl4a/media/mediaplayer/#mediaisplaying","title":"mediaIsPlaying()","text":"

        \u68c0\u67e5\u662f\u5426\u6b63\u5728\u64ad\u653e\u3002

        mediaIsPlaying(tag=\"default\")\n

        \u8fd4\u56de\uff1a True/False

        "},{"location":"qsl4a/media/mediaplayer/#mediaplaylist","title":"mediaPlayList()","text":"

        \u5217\u51fa\u6d3b\u52a8\u64ad\u653e\u5668\u3002

        mediaPlayList()\n
        "},{"location":"qsl4a/media/mediaplayer/#_3","title":"\u97f3\u91cf\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#getmediavolume","title":"getMediaVolume()","text":"

        \u83b7\u53d6\u5a92\u4f53\u97f3\u91cf\u3002

        getMediaVolume()\n

        \u8fd4\u56de\uff1a \u97f3\u91cf\u7ea7\u522b\uff080-15\uff09

        "},{"location":"qsl4a/media/mediaplayer/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

        \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

        getMaxMediaVolume()\n
        "},{"location":"qsl4a/media/mediaplayer/#getringervolume","title":"getRingerVolume()","text":"

        \u83b7\u53d6\u94c3\u58f0\u97f3\u91cf\u3002

        getRingerVolume()\n
        "},{"location":"qsl4a/media/mediaplayer/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

        \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

        getMaxRingerVolume()\n
        "},{"location":"qsl4a/media/mediaplayer/#_4","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/mediaplayer/#videoplay","title":"videoPlay()","text":"

        \u5168\u5c4f\u64ad\u653e\u89c6\u9891\u3002

        videoPlay(path, wait=True)\n

        \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210

        "},{"location":"qsl4a/media/mediaplayer/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u64ad\u653e\u97f3\u9891\ndroid.mediaPlay(\"/sdcard/music.mp3\", tag=\"music\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.mediaIsPlaying(\"music\").result:\n    info = droid.mediaPlayInfo(\"music\").result\n    print(f\"Playing: {info}\")\n\n# \u8df3\u8f6c\u5230 30 \u79d2\ndroid.mediaPlaySeek(30000, \"music\")\n\n# \u5173\u95ed\ndroid.mediaPlayClose(\"music\")\n\n# \u64ad\u653e\u89c6\u9891\ndroid.videoPlay(\"/sdcard/movie.mp4\", wait=True)\n
        "},{"location":"qsl4a/special/cipher/","title":"\u5bc6\u7801 API","text":"

        \u7528\u4e8e\u5b89\u5168\u6570\u636e\u5b58\u50a8\u7684\u52a0\u5bc6\u548c\u89e3\u5bc6\u5de5\u5177\u3002

        "},{"location":"qsl4a/special/cipher/#_1","title":"\u521d\u59cb\u5316","text":""},{"location":"qsl4a/special/cipher/#cipherinit","title":"cipherInit()","text":"

        \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u548c\u7b97\u6cd5\u521d\u59cb\u5316\u5bc6\u7801\u5668\u3002

        cipherInit(key, algorithm=\"AES/CBC/PKCS5Padding\", encodingFormat=\"\", initialVector=\"\")\n

        \u53c2\u6570\uff1a - key (str or bytes): \u52a0\u5bc6\u5bc6\u94a5 - algorithm (str): \u5bc6\u7801\u7b97\u6cd5\uff08\u9ed8\u8ba4\uff1a\"AES/CBC/PKCS5Padding\"\uff09 - encodingFormat (str): \u7f16\u7801\u683c\u5f0f - initialVector (str or bytes): \u52a0\u5bc6\u7684\u521d\u59cb\u5411\u91cf

        \u8fd4\u56de\uff1a \u521d\u59cb\u5316\u7ed3\u679c

        \u6ce8\u610f\uff1a \u5fc5\u987b\u5728\u4efb\u4f55\u52a0\u5bc6/\u89e3\u5bc6\u64cd\u4f5c\u4e4b\u524d\u8c03\u7528\u3002

        "},{"location":"qsl4a/special/cipher/#_2","title":"\u52a0\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#encryptstring","title":"encryptString()","text":"

        \u52a0\u5bc6\u5b57\u7b26\u4e32\u3002

        encryptString(plainText)\n

        \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c

        \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u7b26\u4e32

        "},{"location":"qsl4a/special/cipher/#encryptbytes","title":"encryptBytes()","text":"

        \u52a0\u5bc6\u5b57\u8282\u6570\u636e\u3002

        encryptBytes(data)\n

        \u53c2\u6570\uff1a - data (bytes): \u8981\u52a0\u5bc6\u7684\u6570\u636e

        \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u8282

        "},{"location":"qsl4a/special/cipher/#encryptstringtofile","title":"encryptStringToFile()","text":"

        \u52a0\u5bc6\u5b57\u7b26\u4e32\u5230\u6587\u4ef6\u3002

        encryptStringToFile(plainText, filePath)\n

        \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c - filePath (str): \u8f93\u51fa\u6587\u4ef6\u8def\u5f84

        "},{"location":"qsl4a/special/cipher/#encryptbytestofile","title":"encryptBytesToFile()","text":"

        \u52a0\u5bc6\u5b57\u8282\u5230\u6587\u4ef6\u3002

        encryptBytesToFile(data, filePath)\n
        "},{"location":"qsl4a/special/cipher/#_3","title":"\u89e3\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#decryptstring","title":"decryptString()","text":"

        \u89e3\u5bc6\u4e3a\u5b57\u7b26\u4e32\u3002

        decryptString(cipherText)\n

        \u53c2\u6570\uff1a - cipherText (str): \u52a0\u5bc6\u7684\u6587\u672c

        \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u7b26\u4e32

        "},{"location":"qsl4a/special/cipher/#decryptbytes","title":"decryptBytes()","text":"

        \u89e3\u5bc6\u4e3a\u5b57\u8282\u3002

        decryptBytes(data)\n

        \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u8282

        "},{"location":"qsl4a/special/cipher/#decryptfiletostring","title":"decryptFileToString()","text":"

        \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u7b26\u4e32\u3002

        decryptFileToString(filePath)\n
        "},{"location":"qsl4a/special/cipher/#decryptfiletobytes","title":"decryptFileToBytes()","text":"

        \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u8282\u3002

        decryptFileToBytes(filePath)\n
        "},{"location":"qsl4a/special/cipher/#decryptfile","title":"decryptFile()","text":"

        \u89e3\u5bc6\u6587\u4ef6\u5230\u6587\u4ef6\u3002

        decryptFile(srcPath, destPath)\n
        "},{"location":"qsl4a/special/cipher/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u521d\u59cb\u5316\u5bc6\u7801\u5668\ndroid.cipherInit(\"my_secret_key_1234\")\n\n# \u52a0\u5bc6\u5b57\u7b26\u4e32\nencrypted = droid.encryptString(\"Secret message!\").result\nprint(f\"Encrypted: {encrypted}\")\n\n# \u89e3\u5bc6\u5b57\u7b26\u4e32\ndecrypted = droid.decryptString(encrypted).result\nprint(f\"Decrypted: {decrypted}\")\n\n# \u52a0\u5bc6\u5230\u6587\u4ef6\ndroid.encryptStringToFile(\"My secret data\", \"/sdcard/secret.dat\")\n\n# \u4ece\u6587\u4ef6\u89e3\u5bc6\ndata = droid.decryptFileToString(\"/sdcard/secret.dat\").result\nprint(data)\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u7b97\u6cd5\u548c IV \u521d\u59cb\u5316\ndroid.cipherInit(\n    key=\"my_key\",\n    algorithm=\"AES/CBC/PKCS5Padding\",\n    initialVector=\"0123456789abcdef\"\n)\n
        "},{"location":"qsl4a/special/pgptai/","title":"PGPT AI API","text":"

        \u8bed\u97f3\u8f6c\u6587\u672c\u548c AI \u670d\u52a1\u96c6\u6210\u3002

        "},{"location":"qsl4a/special/pgptai/#_1","title":"\u5148\u51b3\u6761\u4ef6","text":"
        pip install pgptAI\n
        "},{"location":"qsl4a/special/pgptai/#_2","title":"\u8bed\u97f3\u8bc6\u522b","text":""},{"location":"qsl4a/special/pgptai/#speechtotext","title":"speechToText()","text":"

        \u5c06\u8bed\u97f3\u8f6c\u6362\u4e3a\u6587\u672c\u3002

        speechToText(RecordSecond=10, AmrFile=None, Language=None)\n

        \u53c2\u6570\uff1a - RecordSecond (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09 - AmrFile (str, optional): \u73b0\u6709\u97f3\u9891\u6587\u4ef6\u8def\u5f84 - Language (str, optional): \u8bed\u8a00\u4ee3\u7801\uff08'en'\u3001'zh'\uff09

        \u8fd4\u56de\uff1a \u8f6c\u5f55\u7684\u6587\u672c

        "},{"location":"qsl4a/special/pgptai/#_3","title":"\u6587\u672c\u8f6c\u8bed\u97f3","text":""},{"location":"qsl4a/special/pgptai/#texttospeech","title":"textToSpeech()","text":"

        \u5c06\u6587\u672c\u8f6c\u6362\u4e3a\u8bed\u97f3\u5e76\u53ef\u9009\u5730\u64ad\u653e\u3002

        textToSpeech(Text, AutoPlay=True, WavFile=None, VoiceName=None)\n

        \u53c2\u6570\uff1a - Text (str): \u8981\u8f6c\u6362\u4e3a\u8bed\u97f3\u7684\u6587\u672c - AutoPlay (bool): \u81ea\u52a8\u64ad\u653e\u751f\u6210\u7684\u97f3\u9891\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - WavFile (str, optional): \u4fdd\u5b58 WAV \u6587\u4ef6\u7684\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u4e34\u65f6\u6587\u4ef6 - VoiceName (str, optional): \u8981\u4f7f\u7528\u7684\u8bed\u97f3\u540d\u79f0\uff08\u4f8b\u5982 'en-US-JennyNeural'\u3001'zh-CN-XiaoxiaoNeural'\uff09

        \u8fd4\u56de\uff1a \u5305\u542b\u8bed\u97f3\u5408\u6210\u7ed3\u679c\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - text: \u8f93\u5165\u6587\u672c - url: \u4e0b\u8f7d\u97f3\u9891\u6587\u4ef6\u7684 URL - WavFile: \u4fdd\u5b58\u7684 WAV \u6587\u4ef6\u8def\u5f84\uff08\u5982\u679c\u672c\u5730\u4fdd\u5b58\uff09

        "},{"location":"qsl4a/special/pgptai/#_4","title":"\u914d\u7f6e","text":"

        API \u4f7f\u7528\u4ee5\u4e0b\u914d\u7f6e\u6587\u4ef6\u4e2d\u7684\u914d\u7f6e\uff1a/storage/emulated/0/Android/data/org.qpython.qpy/files/apigpt.conf\uff1a

        [speech]\nspeech_key = your_api_key\n

        \u9ed8\u8ba4\u8bed\u97f3\u8bbe\u7f6e\uff1a - \u82f1\u8bed\uff1aen-US-JennyNeural - \u4e2d\u6587\uff1azh-CN-XiaoxiaoNeural

        "},{"location":"qsl4a/special/pgptai/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5f55\u5236\u5e76\u8f6c\u5f55\nprint(\"Recording for 5 seconds...\")\ntext = droid.speechToText(RecordSecond=5, Language='en').result\nprint(f\"You said: {text}\")\n\n# \u8f6c\u5f55\u73b0\u6709\u6587\u4ef6\ntext = droid.speechToText(AmrFile=\"/sdcard/recording.amr\").result\nprint(f\"Transcription: {text}\")\n\n# \u6587\u672c\u8f6c\u8bed\u97f3\ndroid.textToSpeech(\"Hello, this is a test message.\", AutoPlay=True, Language='en')\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u8bed\u97f3\u5e76\u4fdd\u5b58\u5230\u6587\u4ef6\u7684\u6587\u672c\u8f6c\u8bed\u97f3\nresult = droid.textToSpeech(\n    \"Welcome to QPython!\",\n    AutoPlay=False,\n    WavFile=\"/sdcard/welcome.wav\",\n    VoiceName=\"en-US-JennyNeural\"\n).result\nprint(f\"Audio saved to: {result.get('WavFile')}\")\n
        "},{"location":"qsl4a/special/pgptai/#_6","title":"\u7c7b\u4f7f\u7528","text":"
        from androidhelper.pgptai import pgptai\nimport androidhelper\n\ndroid = androidhelper.Android()\nai = pgptai(droid)\n\n# \u4f7f\u7528\u8bed\u97f3\u8bc6\u522b\ntext = ai.speechToText(RecordSecond=10)\n
        "},{"location":"qsl4a/storage/clipboard/","title":"\u526a\u8d34\u677f API","text":"

        \u590d\u5236\u548c\u7c98\u8d34\u6587\u672c\u5230\u7cfb\u7edf\u526a\u8d34\u677f\u3002

        "},{"location":"qsl4a/storage/clipboard/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/clipboard/#setclipboard","title":"setClipboard()","text":"

        \u590d\u5236\u6587\u672c\u5230\u526a\u8d34\u677f\u3002

        setClipboard(text)\n

        \u53c2\u6570\uff1a - text (str): \u8981\u590d\u5236\u7684\u6587\u672c

        \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

        "},{"location":"qsl4a/storage/clipboard/#getclipboard","title":"getClipboard()","text":"

        \u4ece\u526a\u8d34\u677f\u83b7\u53d6\u6587\u672c\u3002

        getClipboard()\n

        \u8fd4\u56de\uff1a \u526a\u8d34\u677f\u6587\u672c

        "},{"location":"qsl4a/storage/clipboard/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u590d\u5236\u5230\u526a\u8d34\u677f\ndroid.setClipboard(\"Hello from QPython!\")\n\n# \u4ece\u526a\u8d34\u677f\u7c98\u8d34\ntext = droid.getClipboard().result\nprint(f\"Clipboard: {text}\")\n
        "},{"location":"qsl4a/storage/documentfile/","title":"DocumentFile API","text":"

        \u4f7f\u7528 SAF\uff08\u5b58\u50a8\u8bbf\u95ee\u6846\u67b6\uff09\u8fdb\u884c\u6587\u4ef6\u64cd\u4f5c\uff0c\u652f\u6301 Android 4.4+\u3002

        "},{"location":"qsl4a/storage/documentfile/#_1","title":"\u76ee\u5f55\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilemkdir","title":"documentFileMkdir()","text":"

        \u521b\u5efa\u76ee\u5f55\u3002

        documentFileMkdir(Dir)\n

        \u53c2\u6570\uff1a - Dir (str): \u76ee\u5f55\u8def\u5f84

        \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

        "},{"location":"qsl4a/storage/documentfile/#documentfilelistfiles","title":"documentFileListFiles()","text":"

        \u5217\u51fa\u76ee\u5f55\u4e2d\u7684\u6587\u4ef6\u3002

        documentFileListFiles(Folder)\n

        \u8fd4\u56de\uff1a \u6587\u4ef6\u5217\u8868

        "},{"location":"qsl4a/storage/documentfile/#_2","title":"\u6587\u4ef6\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileexists","title":"documentFileExists()","text":"

        \u68c0\u67e5\u6587\u4ef6\u6216\u76ee\u5f55\u662f\u5426\u5b58\u5728\u3002

        documentFileExists(path)\n

        \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u6216\u76ee\u5f55\u8def\u5f84

        \u8fd4\u56de\uff1a \u5982\u679c\u5b58\u5728\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

        "},{"location":"qsl4a/storage/documentfile/#documentfileisfile","title":"documentFileIsFile()","text":"

        \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u6587\u4ef6\u3002

        documentFileIsFile(path)\n

        \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

        \u8fd4\u56de\uff1a \u5982\u679c\u662f\u6587\u4ef6\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u6587\u4ef6\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

        "},{"location":"qsl4a/storage/documentfile/#documentfileisdirectory","title":"documentFileIsDirectory()","text":"

        \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u76ee\u5f55\u3002

        documentFileIsDirectory(path)\n

        \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

        \u8fd4\u56de\uff1a \u5982\u679c\u662f\u76ee\u5f55\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u76ee\u5f55\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

        "},{"location":"qsl4a/storage/documentfile/#documentfiledelete","title":"documentFileDelete()","text":"

        \u5220\u9664\u6587\u4ef6\u6216\u76ee\u5f55\u3002

        documentFileDelete(FileOrTree)\n

        \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

        "},{"location":"qsl4a/storage/documentfile/#documentfilerenameto","title":"documentFileRenameTo()","text":"

        \u91cd\u547d\u540d\u6216\u79fb\u52a8\u6587\u4ef6\u3002

        documentFileRenameTo(Src, Dest)\n

        \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

        "},{"location":"qsl4a/storage/documentfile/#documentfilecopy","title":"documentFileCopy()","text":"

        \u590d\u5236\u6587\u4ef6\u3002

        documentFileCopy(SrcFileOrTree, DestFileOrTree)\n
        "},{"location":"qsl4a/storage/documentfile/#_3","title":"\u6d41\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileinputstream","title":"documentFileInputStream()","text":"

        \u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9\u3002

        documentFileInputStream(srcFile, EncodingFormat=\"\", skip=None, length=None)\n

        \u53c2\u6570\uff1a - srcFile (str): \u6e90\u6587\u4ef6 - EncodingFormat (str): \"UTF-8\"\u3001\"GBK\"\u3001\"Base64\" \u6216\u7a7a\u5b57\u7b26\u4e32\u8868\u793a\u5b57\u8282 - skip (int): \u4ece\u5f00\u5934\u8df3\u8fc7\u7684\u5b57\u8282\u6570 - length (int): \u8bfb\u53d6\u957f\u5ea6

        \u8fd4\u56de\uff1a \u6587\u4ef6\u5185\u5bb9

        "},{"location":"qsl4a/storage/documentfile/#documentfileoutputstream","title":"documentFileOutputStream()","text":"

        \u5199\u5165\u6587\u4ef6\u5185\u5bb9\u3002

        documentFileOutputStream(destFile, src, EncodingFormat=\"\", append=None)\n

        \u53c2\u6570\uff1a - destFile (str): \u76ee\u6807\u6587\u4ef6 - src: \u8981\u5199\u5165\u7684\u6570\u636e - EncodingFormat (str): \u7f16\u7801\u683c\u5f0f - append (bool): \u8ffd\u52a0\u6a21\u5f0f

        "},{"location":"qsl4a/storage/documentfile/#_4","title":"\u6587\u4ef6\u4fe1\u606f","text":""},{"location":"qsl4a/storage/documentfile/#documentfilelength","title":"documentFileLength()","text":"

        \u83b7\u53d6\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\u3002

        documentFileLength(path)\n

        \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

        \u8fd4\u56de\uff1a \u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

        "},{"location":"qsl4a/storage/documentfile/#documentfilelastmodified","title":"documentFileLastModified()","text":"

        \u83b7\u53d6\u6700\u540e\u4fee\u6539\u65f6\u95f4\u3002

        documentFileLastModified(path)\n

        \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

        \u8fd4\u56de\uff1a \u65f6\u95f4\u6233\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

        "},{"location":"qsl4a/storage/documentfile/#documentfilegetstat","title":"documentFileGetStat()","text":"

        \u83b7\u53d6\u5168\u9762\u7684\u6587\u4ef6\u7edf\u8ba1\u4fe1\u606f\u3002

        documentFileGetStat(path)\n

        \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

        \u8fd4\u56de\uff1a \u5305\u542b\u957f\u5ea6\u3001\u6700\u540e\u4fee\u6539\u65f6\u95f4\u548c\u8bfb/\u5199\u6743\u9650\u7684\u5b57\u5178\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

        "},{"location":"qsl4a/storage/documentfile/#uri","title":"URI \u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilegeturi","title":"documentFileGetUri()","text":"

        \u4ece\u8def\u5f84\u83b7\u53d6 URI\u3002

        documentFileGetUri(path, isDirectory=None)\n
        "},{"location":"qsl4a/storage/documentfile/#documentfileshowopen","title":"documentFileShowOpen()","text":"

        \u663e\u793a\u6587\u4ef6\u9009\u62e9\u5668\u3002

        documentFileShowOpen()\n

        \u8fd4\u56de\uff1a \u9009\u62e9\u7684\u6587\u4ef6 URI

        "},{"location":"qsl4a/storage/documentfile/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u76ee\u5f55\ndroid.documentFileMkdir(\"/sdcard/MyFolder\")\n\n# \u5217\u51fa\u6587\u4ef6\nfiles = droid.documentFileListFiles(\"/sdcard\").result\nfor f in files:\n    print(f)\n\n# \u8bfb\u53d6\u6587\u4ef6\ncontent = droid.documentFileInputStream(\n    \"/sdcard/test.txt\",\n    EncodingFormat=\"UTF-8\"\n).result\nprint(content)\n\n# \u5199\u5165\u6587\u4ef6\ndroid.documentFileOutputStream(\n    \"/sdcard/output.txt\",\n    \"Hello World\",\n    EncodingFormat=\"UTF-8\"\n)\n
        "},{"location":"qsl4a/storage/preferences/","title":"\u504f\u597d\u8bbe\u7f6e API","text":"

        \u4f7f\u7528 Android SharedPreferences \u5b58\u50a8\u548c\u68c0\u7d22\u6570\u636e\u3002

        "},{"location":"qsl4a/storage/preferences/#_1","title":"\u504f\u597d\u8bbe\u7f6e\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/preferences/#prefgetvalue","title":"prefGetValue()","text":"

        \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u8bfb\u53d6\u503c\u3002

        prefGetValue(key, filename=None)\n

        \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

        \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c\uff08\u4efb\u610f\u7c7b\u578b\uff09

        "},{"location":"qsl4a/storage/preferences/#prefputvalue","title":"prefPutValue()","text":"

        \u5199\u5165\u503c\u5230\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u3002

        prefPutValue(key, value, filename=None)\n

        \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - value (object): \u8981\u5b58\u50a8\u7684\u503c - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

        "},{"location":"qsl4a/storage/preferences/#prefgetall","title":"prefGetAll()","text":"

        \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\u503c\u3002

        prefGetAll(filename=None)\n

        \u53c2\u6570\uff1a - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

        \u8fd4\u56de\uff1a \u6240\u6709\u504f\u597d\u7684\u6620\u5c04

        "},{"location":"qsl4a/storage/preferences/#prefremovevalue","title":"prefRemoveValue()","text":"

        \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u4e2d\u79fb\u9664\u503c\u3002

        prefRemoveValue(key, filename=None)\n

        \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

        "},{"location":"qsl4a/storage/preferences/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b58\u50a8\u503c\ndroid.prefPutValue(\"username\", \"alice\")\ndroid.prefPutValue(\"score\", 100)\ndroid.prefPutValue(\"enabled\", True)\n\n# \u8bfb\u53d6\u7279\u5b9a\u503c\nusername = droid.prefGetValue(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\nall_prefs = droid.prefGetAll().result\nprint(f\"All prefs: {all_prefs}\")\n\n# \u79fb\u9664\u503c\ndroid.prefRemoveValue(\"score\")\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u6587\u4ef6\u540d\ndroid.prefPutValue(\"token\", \"abc123\", filename=\"auth.prefs\")\ntoken = droid.prefGetValue(\"token\", filename=\"auth.prefs\").result\n
        "},{"location":"qsl4a/system/activityresult/","title":"Activity Result API","text":"

        \u4e3a\u901a\u8fc7 startActivityForResult \u542f\u52a8\u7684\u811a\u672c\u8bbe\u7f6e activity \u7ed3\u679c\u3002

        "},{"location":"qsl4a/system/activityresult/#_1","title":"\u7ed3\u679c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/activityresult/#setresultboolean","title":"setResultBoolean()","text":"

        \u8bbe\u7f6e\u5e03\u5c14\u7ed3\u679c\u3002

        setResultBoolean(resultCode, resultValue)\n

        \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (bool): \u5e03\u5c14\u7ed3\u679c\u503c

        "},{"location":"qsl4a/system/activityresult/#setresultbyte","title":"setResultByte()","text":"

        \u8bbe\u7f6e\u5b57\u8282\u7ed3\u679c\u3002

        setResultByte(resultCode, resultValue)\n

        \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u5b57\u8282\u7ed3\u679c\u503c

        "},{"location":"qsl4a/system/activityresult/#setresultshort","title":"setResultShort()","text":"

        \u8bbe\u7f6e\u77ed\u6574\u6570\u7ed3\u679c\u3002

        setResultShort(resultCode, resultValue)\n

        \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u77ed\u6574\u6570\u7ed3\u679c\u503c

        "},{"location":"qsl4a/system/activityresult/#setresultchar","title":"setResultChar()","text":"

        \u8bbe\u7f6e\u5b57\u7b26\u7ed3\u679c\u3002

        setResultChar(resultCode, resultValue)\n

        \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u7ed3\u679c\u503c

        "},{"location":"qsl4a/system/activityresult/#setresultinteger","title":"setResultInteger()","text":"

        \u8bbe\u7f6e\u6574\u6570\u7ed3\u679c\u3002

        setResultInteger(resultCode, resultValue)\n

        \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u6574\u6570\u7ed3\u679c\u503c

        "},{"location":"qsl4a/system/activityresult/#setresultlong","title":"setResultLong()","text":"

        \u8bbe\u7f6e\u957f\u6574\u6570\u7ed3\u679c\u3002

        setResultLong(resultCode, resultValue)\n

        \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u957f\u6574\u6570\u7ed3\u679c\u503c

        "},{"location":"qsl4a/system/activityresult/#setresultfloat","title":"setResultFloat()","text":"

        \u8bbe\u7f6e\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

        setResultFloat(resultCode, resultValue)\n

        \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u6d6e\u70b9\u6570\u7ed3\u679c\u503c

        "},{"location":"qsl4a/system/activityresult/#setresultdouble","title":"setResultDouble()","text":"

        \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

        setResultDouble(resultCode, resultValue)\n

        \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u503c

        "},{"location":"qsl4a/system/activityresult/#setresultstring","title":"setResultString()","text":"

        \u8bbe\u7f6e\u5b57\u7b26\u4e32\u7ed3\u679c\u3002

        setResultString(resultCode, resultValue)\n

        \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u4e32\u7ed3\u679c\u503c

        "},{"location":"qsl4a/system/activityresult/#setresultbooleanarray","title":"setResultBooleanArray()","text":"

        \u8bbe\u7f6e\u5e03\u5c14\u6570\u7ec4\u7ed3\u679c\u3002

        setResultBooleanArray(resultCode, resultValue)\n

        \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5e03\u5c14\u6570\u7ec4

        "},{"location":"qsl4a/system/activityresult/#setresultbytearray","title":"setResultByteArray()","text":"

        \u8bbe\u7f6e\u5b57\u8282\u6570\u7ec4\u7ed3\u679c\u3002

        setResultByteArray(resultCode, resultValue)\n

        \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u8282\u6570\u7ec4

        "},{"location":"qsl4a/system/activityresult/#setresultshortarray","title":"setResultShortArray()","text":"

        \u8bbe\u7f6e\u77ed\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

        setResultShortArray(resultCode, resultValue)\n

        \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u77ed\u6574\u6570\u6570\u7ec4

        "},{"location":"qsl4a/system/activityresult/#setresultchararray","title":"setResultCharArray()","text":"

        \u8bbe\u7f6e\u5b57\u7b26\u6570\u7ec4\u7ed3\u679c\u3002

        setResultCharArray(resultCode, resultValue)\n

        \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u6570\u7ec4

        "},{"location":"qsl4a/system/activityresult/#setresultintegerarray","title":"setResultIntegerArray()","text":"

        \u8bbe\u7f6e\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

        setResultIntegerArray(resultCode, resultValue)\n

        \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6574\u6570\u6570\u7ec4

        "},{"location":"qsl4a/system/activityresult/#setresultlongarray","title":"setResultLongArray()","text":"

        \u8bbe\u7f6e\u957f\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

        setResultLongArray(resultCode, resultValue)\n

        \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u957f\u6574\u6570\u6570\u7ec4

        "},{"location":"qsl4a/system/activityresult/#setresultfloatarray","title":"setResultFloatArray()","text":"

        \u8bbe\u7f6e\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

        setResultFloatArray(resultCode, resultValue)\n

        \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6d6e\u70b9\u6570\u6570\u7ec4

        "},{"location":"qsl4a/system/activityresult/#setresultdoublearray","title":"setResultDoubleArray()","text":"

        \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

        setResultDoubleArray(resultCode, resultValue)\n

        \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4

        "},{"location":"qsl4a/system/activityresult/#setresultstringarray","title":"setResultStringArray()","text":"

        \u8bbe\u7f6e\u5b57\u7b26\u4e32\u6570\u7ec4\u7ed3\u679c\u3002

        setResultStringArray(resultCode, resultValue)\n

        \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u4e32\u6570\u7ec4

        "},{"location":"qsl4a/system/activityresult/#setresultserializable","title":"setResultSerializable()","text":"

        \u8bbe\u7f6e\u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u3002

        setResultSerializable(resultCode, resultValue)\n

        \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue: \u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u503c

        "},{"location":"qsl4a/system/activityresult/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c activity \u540e\uff0c\u8bbe\u7f6e\u7ed3\u679c\n# \u793a\u4f8b\uff1a\u8fd4\u56de\u6210\u529f\u53ca\u6570\u636e\ndroid.setResultInteger(0, 200)  # RESULT_OK\ndroid.setResultString(0, \"Operation completed successfully\")\n\n# \u8fd4\u56de\u6570\u7ec4\u7ed3\u679c\ndroid.setResultIntegerArray(0, [1, 2, 3, 4, 5])\n
        "},{"location":"qsl4a/system/application/","title":"\u5e94\u7528\u7ba1\u7406","text":"

        \u7ba1\u7406\u5e94\u7528\u7a0b\u5e8f\u3001\u542f\u52a8\u5e94\u7528\u548c\u67e5\u8be2\u7cfb\u7edf\u4fe1\u606f\u3002

        "},{"location":"qsl4a/system/application/#_2","title":"\u5e94\u7528\u7a0b\u5e8f\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getapplicationinfo","title":"getApplicationInfo()","text":"

        \u83b7\u53d6\u5e94\u7528\u4fe1\u606f\u3002

        getApplicationInfo(packageName=None)\n

        \u53c2\u6570\uff1a - packageName (str): \u5305\u540d\uff08None = \u5f53\u524d\u5e94\u7528\uff09

        \u8fd4\u56de\uff1a \u5e94\u7528\u4fe1\u606f\u5b57\u5178

        "},{"location":"qsl4a/system/application/#getinstalledpackages","title":"getInstalledPackages()","text":"

        \u83b7\u53d6\u5df2\u5b89\u88c5\u5305\u5217\u8868\u3002

        getInstalledPackages(flag=4)\n

        \u53c2\u6570\uff1a - flag (int): \u5305\u6807\u5fd7\u8fc7\u6ee4\u5668\uff08\u9ed8\u8ba4\uff1a4\uff09

        \u8fd4\u56de\uff1a \u5df2\u5b89\u88c5\u5305\u5217\u8868

        "},{"location":"qsl4a/system/application/#getrunningpackages","title":"getRunningPackages()","text":"

        \u5217\u51fa\u6b63\u5728\u8fd0\u884c\u7684\u5305\u3002

        getRunningPackages()\n

        \u8fd4\u56de\uff1a \u5305\u540d\u5217\u8868

        "},{"location":"qsl4a/system/application/#getlaunchablepackages","title":"getLaunchablePackages()","text":"

        \u83b7\u53d6\u53ef\u542f\u52a8\u5305\u5217\u8868\u3002

        getLaunchablePackages(needClassName=False)\n

        \u53c2\u6570\uff1a - needClassName (bool): \u5305\u542b\u4e3b activity \u7c7b\u540d\uff08\u9ed8\u8ba4\uff1aFalse\uff09

        \u8fd4\u56de\uff1a \u53ef\u542f\u52a8\u5305\u540d\u5217\u8868\u6216\u5305\u542b\u7c7b\u540d\u7684\u5b57\u5178

        "},{"location":"qsl4a/system/application/#_3","title":"\u5e94\u7528\u63a7\u5236","text":""},{"location":"qsl4a/system/application/#launch","title":"launch()","text":"

        \u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u3002

        launch(classname=None, packagename=None, wait=True)\n

        \u53c2\u6570\uff1a - classname (str): \u4e3b activity \u7c7b\u540d - packagename (str): \u5305\u540d - wait (bool): \u7b49\u5f85\u542f\u52a8\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

        \u8fd4\u56de\uff1a \u542f\u52a8\u7ed3\u679c

        "},{"location":"qsl4a/system/application/#forcestoppackage","title":"forceStopPackage()","text":"

        \u5f3a\u5236\u505c\u6b62\u5e94\u7528\u7a0b\u5e8f\u3002

        forceStopPackage(packageName)\n

        \u53c2\u6570\uff1a - packageName (str): \u8981\u505c\u6b62\u7684\u5305\u540d

        "},{"location":"qsl4a/system/application/#_4","title":"\u7248\u672c\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getpackageversion","title":"getPackageVersion()","text":"

        \u83b7\u53d6\u5e94\u7528\u7248\u672c\u540d\u79f0\u3002

        getPackageVersion(packageName)\n

        \u8fd4\u56de\uff1a \u7248\u672c\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"3.2.1\"\uff09

        "},{"location":"qsl4a/system/application/#getpackageversioncode","title":"getPackageVersionCode()","text":"

        \u83b7\u53d6\u5e94\u7528\u7248\u672c\u4ee3\u7801\u3002

        getPackageVersionCode(packageName)\n

        \u8fd4\u56de\uff1a \u7248\u672c\u4ee3\u7801\u6574\u6570

        "},{"location":"qsl4a/system/application/#getconstants","title":"getConstants()","text":"

        \u83b7\u53d6\u7c7b\u5e38\u91cf\u3002

        getConstants(classname)\n

        \u53c2\u6570\uff1a - classname (str): \u5b8c\u6574\u7c7b\u540d

        \u8fd4\u56de\uff1a \u5e38\u91cf\u540d\u548c\u503c\u7684\u5b57\u5178

        "},{"location":"qsl4a/system/application/#_5","title":"\u7cfb\u7edf\u529f\u80fd","text":""},{"location":"qsl4a/system/application/#backgroundprotect","title":"backgroundProtect()","text":"

        \u542f\u7528\u6216\u7981\u7528\u5e94\u7528\u7684\u540e\u53f0\u4fdd\u62a4\u3002

        backgroundProtect(enabled=True)\n

        \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\u4fdd\u62a4\uff0cFalse \u7981\u7528

        "},{"location":"qsl4a/system/application/#createscriptshortcut","title":"createScriptShortCut()","text":"

        \u4e3a\u811a\u672c\u521b\u5efa\u4e3b\u5c4f\u5e55\u5feb\u6377\u65b9\u5f0f\u3002

        createScriptShortCut(scriptPath, label=None, iconPath=None, scriptArg=None)\n

        \u53c2\u6570\uff1a - scriptPath (str): Python \u811a\u672c\u8def\u5f84 - label (str, optional): \u5feb\u6377\u65b9\u5f0f\u6807\u7b7e - iconPath (str, optional): \u56fe\u6807\u56fe\u50cf\u8def\u5f84 - scriptArg (str, optional): \u4f20\u9012\u7ed9\u811a\u672c\u7684\u53c2\u6570

        "},{"location":"qsl4a/system/application/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getandroidid","title":"getAndroidID()","text":"

        \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

        getAndroidID()\n

        \u8fd4\u56de\uff1a \u552f\u4e00\u7684 Android \u8bbe\u5907 ID \u5b57\u7b26\u4e32

        "},{"location":"qsl4a/system/application/#getsysinfo","title":"getSysInfo()","text":"

        \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\u3002

        getSysInfo()\n

        \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

        "},{"location":"qsl4a/system/application/#getlocale","title":"getLocale()","text":"

        \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u3002

        getLocale()\n

        \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

        "},{"location":"qsl4a/system/application/#getharmonyosinformation","title":"getHarmonyOsInformation()","text":"

        \u5982\u679c\u5728 HarmonyOS \u4e0a\u8fd0\u884c\uff0c\u83b7\u53d6 HarmonyOS \u4fe1\u606f\u3002

        getHarmonyOsInformation()\n

        \u8fd4\u56de\uff1a HarmonyOS \u7248\u672c\u4fe1\u606f\u6216 None

        "},{"location":"qsl4a/system/application/#isexternalstoragemanager","title":"isExternalStorageManager()","text":"

        \u68c0\u67e5\u5e94\u7528\u662f\u5426\u6709\u5916\u90e8\u5b58\u50a8\u7ba1\u7406\u5668\u6743\u9650\u3002

        isExternalStorageManager()\n

        \u8fd4\u56de\uff1a \u5982\u679c\u6709\u6743\u9650\u5219\u4e3a True

        "},{"location":"qsl4a/system/application/#_7","title":"\u5185\u5b58\u548c\u663e\u793a","text":""},{"location":"qsl4a/system/application/#getmemoryinfo","title":"getMemoryInfo()","text":"

        \u83b7\u53d6\u5185\u5b58\u4fe1\u606f\u3002

        getMemoryInfo()\n

        \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

        "},{"location":"qsl4a/system/application/#getscreeninfo","title":"getScreenInfo()","text":"

        \u83b7\u53d6\u5c4f\u5e55\u4fe1\u606f\u3002

        getScreenInfo()\n

        \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

        "},{"location":"qsl4a/system/application/#_8","title":"\u6743\u9650","text":""},{"location":"qsl4a/system/application/#checkpermissions","title":"checkPermissions()","text":"

        \u68c0\u67e5\u5f53\u524d\u5e94\u7528\u6743\u9650\u3002

        checkPermissions()\n

        \u8fd4\u56de\uff1a \u6743\u9650\u53ca\u5176\u72b6\u6001\u7684\u5b57\u5178

        "},{"location":"qsl4a/system/application/#requestpermissions","title":"requestPermissions()","text":"

        \u5411\u7528\u6237\u8bf7\u6c42\u6743\u9650\u3002

        requestPermissions(permissions=None)\n

        \u53c2\u6570\uff1a - permissions (list, optional): \u8981\u8bf7\u6c42\u7684\u6743\u9650\u5217\u8868\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8bf7\u6c42\u6240\u6709\u9700\u8981\u7684\u6743\u9650\u3002

        \u8fd4\u56de\uff1a \u6743\u9650\u8bf7\u6c42\u7ed3\u679c

        "},{"location":"qsl4a/system/application/#_9","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/system/application/#showscreenlock","title":"showScreenLock()","text":"

        \u663e\u793a\u5c4f\u5e55\u9501\u5b9a\uff08PIN/\u56fe\u6848/\u5bc6\u7801\u8f93\u5165\uff09\u3002

        showScreenLock()\n
        "},{"location":"qsl4a/system/application/#_10","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\ninfo = droid.getSysInfo().result\nprint(f\"System: {info}\")\n\n# \u83b7\u53d6\u5e94\u7528\u7248\u672c\nversion = droid.getPackageVersion(\"org.qpython.qpy\").result\nprint(f\"QPython version: {version}\")\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u5e94\u7528\napps = droid.getInstalledPackages().result\nprint(f\"Installed apps: {len(apps)}\")\n\n# \u542f\u52a8\u5e94\u7528\ndroid.launch(packagename=\"com.android.settings\")\n\n# \u68c0\u67e5\u6743\u9650\nperms = droid.checkPermissions().result\nprint(f\"Permissions: {perms}\")\n\n# \u8bf7\u6c42\u5b58\u50a8\u6743\u9650\ndroid.requestPermissions([\"android.permission.READ_EXTERNAL_STORAGE\"])\n\n# \u521b\u5efa\u5feb\u6377\u65b9\u5f0f\ndroid.createScriptShortCut(\n    \"/sdcard/my_script.py\",\n    label=\"My Script\",\n    iconPath=\"/sdcard/icon.png\"\n)\n
        "},{"location":"qsl4a/system/battery/","title":"\u7535\u6c60 API","text":"

        \u76d1\u63a7\u8bbe\u5907\u7535\u6c60\u72b6\u6001\u548c\u5065\u5eb7\u72b6\u51b5\u3002

        "},{"location":"qsl4a/system/battery/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/battery/#readbatterydata","title":"readBatteryData()","text":"

        \u83b7\u53d6\u5b8c\u6574\u7684\u7535\u6c60\u4fe1\u606f\u3002

        readBatteryData()\n

        \u8fd4\u56de\uff1a \u5305\u542b\u7535\u6c60\u6570\u636e\u7684\u5b57\u5178

        "},{"location":"qsl4a/system/battery/#batterystartmonitoring","title":"batteryStartMonitoring()","text":"

        \u5f00\u59cb\u7535\u6c60\u76d1\u63a7\u3002

        batteryStartMonitoring()\n
        "},{"location":"qsl4a/system/battery/#batterystopmonitoring","title":"batteryStopMonitoring()","text":"

        \u505c\u6b62\u7535\u6c60\u76d1\u63a7\u3002

        batteryStopMonitoring()\n
        "},{"location":"qsl4a/system/battery/#batterygetlevel","title":"batteryGetLevel()","text":"

        \u83b7\u53d6\u7535\u6c60\u767e\u5206\u6bd4\u3002

        batteryGetLevel()\n

        \u8fd4\u56de\uff1a \u6574\u6570\uff080-100\uff09

        "},{"location":"qsl4a/system/battery/#batterygetstatus","title":"batteryGetStatus()","text":"

        \u83b7\u53d6\u5145\u7535\u72b6\u6001\u3002

        batteryGetStatus()\n

        \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u5145\u7535\u4e2d - 3: \u653e\u7535\u4e2d - 4: \u672a\u5145\u7535 - 5: \u5df2\u5145\u6ee1

        "},{"location":"qsl4a/system/battery/#batterygetplugtype","title":"batteryGetPlugType()","text":"

        \u83b7\u53d6\u7535\u6e90\u7c7b\u578b\u3002

        batteryGetPlugType()\n

        \u8fd4\u56de\uff1a - -1: \u672a\u77e5 - 0: \u672a\u63d2\u7535 - 1: AC \u5145\u7535\u5668 - 2: USB \u7aef\u53e3

        "},{"location":"qsl4a/system/battery/#batterygethealth","title":"batteryGetHealth()","text":"

        \u83b7\u53d6\u7535\u6c60\u5065\u5eb7\u72b6\u51b5\u3002

        batteryGetHealth()\n

        \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u826f\u597d - 3: \u8fc7\u70ed - 4: \u635f\u574f - 5: \u8fc7\u538b - 6: \u672a\u6307\u5b9a\u7684\u6545\u969c

        "},{"location":"qsl4a/system/battery/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\nlevel = droid.batteryGetLevel().result\nprint(f\"Battery: {level}%\")\n
        "},{"location":"qsl4a/system/qpyinterface/","title":"QPython \u63a5\u53e3 API","text":"

        \u4ece\u5176\u4ed6\u5e94\u7528\u6267\u884c QPython \u811a\u672c\u548c\u7ba1\u7406\u5171\u4eab\u53d8\u91cf\u3002

        "},{"location":"qsl4a/system/qpyinterface/#_1","title":"\u811a\u672c\u6267\u884c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/qpyinterface/#executeqpy","title":"executeQPy()","text":"

        \u6267\u884c QPython \u811a\u672c\u3002

        executeQPy(path=\"\", arg=None)\n

        \u53c2\u6570\uff1a - path (str): \u811a\u672c\u6587\u4ef6\u8def\u5f84 - arg (str, optional): \u547d\u4ee4\u884c\u53c2\u6570

        \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

        "},{"location":"qsl4a/system/qpyinterface/#executeqpyassrv","title":"executeQPyAsSrv()","text":"

        \u4f5c\u4e3a\u670d\u52a1\u6267\u884c QPython \u811a\u672c\u3002

        executeQPyAsSrv(path=None)\n

        \u53c2\u6570\uff1a - path (str, optional): \u811a\u672c\u6587\u4ef6\u8def\u5f84

        \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

        "},{"location":"qsl4a/system/qpyinterface/#executeqpycode","title":"executeQPyCode()","text":"

        \u76f4\u63a5\u6267\u884c Python \u4ee3\u7801\u3002

        executeQPyCode(code=None)\n

        \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

        \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

        "},{"location":"qsl4a/system/qpyinterface/#executeqpycodeassrv","title":"executeQPyCodeAsSrv()","text":"

        \u4f5c\u4e3a\u670d\u52a1\u6267\u884c Python \u4ee3\u7801\u3002

        executeQPyCodeAsSrv(code=None)\n

        \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

        \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

        "},{"location":"qsl4a/system/qpyinterface/#_2","title":"\u5171\u4eab\u53d8\u91cf","text":"

        \u5171\u4eab\u53d8\u91cf\u5141\u8bb8 QPython \u4e0e\u5176\u4ed6\u5e94\u7528\u4e4b\u95f4\u8fdb\u884c\u901a\u4fe1\u3002

        "},{"location":"qsl4a/system/qpyinterface/#sharedvariableset","title":"sharedVariableSet()","text":"

        \u8bbe\u7f6e Java \u5171\u4eab\u53d8\u91cf\u3002

        sharedVariableSet(key, value)\n

        \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d - value (str): \u53d8\u91cf\u503c

        \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

        "},{"location":"qsl4a/system/qpyinterface/#sharedvariableget","title":"sharedVariableGet()","text":"

        \u83b7\u53d6 Java \u5171\u4eab\u53d8\u91cf\u3002

        sharedVariableGet(key)\n

        \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d

        \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

        "},{"location":"qsl4a/system/qpyinterface/#sharedvariableremove","title":"sharedVariableRemove()","text":"

        \u79fb\u9664 Java \u5171\u4eab\u53d8\u91cf\u3002

        sharedVariableRemove(key)\n

        \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u53d8\u91cf\u540d

        \u8fd4\u56de\uff1a \u88ab\u79fb\u9664\u7684\u503c

        "},{"location":"qsl4a/system/qpyinterface/#getlastlog","title":"getLastLog()","text":"

        \u83b7\u53d6 QPython \u7684\u6700\u540e\u65e5\u5fd7\u8f93\u51fa\u3002

        getLastLog()\n

        \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u65e5\u5fd7\u5185\u5bb9

        "},{"location":"qsl4a/system/qpyinterface/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c\u811a\u672c\ndroid.executeQPy(\"/sdcard/my_script.py\", arg=\"test\")\n\n# \u76f4\u63a5\u6267\u884c\u4ee3\u7801\ncode = \"print('Hello from QPython!')\"\ndroid.executeQPyCode(code)\n\n# \u4f7f\u7528\u5171\u4eab\u53d8\u91cf\ndroid.sharedVariableSet(\"username\", \"alice\")\nusername = droid.sharedVariableGet(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u79fb\u9664\u53d8\u91cf\ndroid.sharedVariableRemove(\"username\")\n\n# \u83b7\u53d6\u6700\u8fd1\u65e5\u5fd7\nlog = droid.getLastLog().result\nprint(f\"Log: {log}\")\n
        "},{"location":"qsl4a/system/sensors/","title":"\u4f20\u611f\u5668 API","text":"

        \u8bbf\u95ee\u8bbe\u5907\u4f20\u611f\u5668\uff0c\u5305\u62ec\u52a0\u901f\u5ea6\u8ba1\u3001\u9640\u87ba\u4eea\u3001\u78c1\u529b\u8ba1\u7b49\u3002

        "},{"location":"qsl4a/system/sensors/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/sensors/#startsensingtimed","title":"startSensingTimed()","text":"

        \u5f00\u59cb\u4f20\u611f\u5668\u76d1\u63a7\u5e76\u8bbe\u7f6e\u65f6\u95f4\u95f4\u9694\u3002

        startSensingTimed(sensorNumber, delayTime)\n

        \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID\uff08\u901a\u5e38\u4e3a 1-3\uff09 - delayTime (int): \u8bfb\u53d6\u4e4b\u95f4\u7684\u5ef6\u8fdf\uff08\u6beb\u79d2\uff09

        "},{"location":"qsl4a/system/sensors/#startsensingthreshold","title":"startSensingThreshold()","text":"

        \u5f00\u59cb\u5e26\u9608\u503c\u89e6\u53d1\u7684\u4f20\u611f\u5668\u76d1\u63a7\u3002

        startSensingThreshold(sensorNumber, threshold, axis)\n

        \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID - threshold (float): \u89e6\u53d1\u9608\u503c - axis (int): \u8981\u76d1\u63a7\u7684\u8f74\uff080=X\uff0c1=Y\uff0c2=Z\uff09

        "},{"location":"qsl4a/system/sensors/#stopsensing","title":"stopSensing()","text":"

        \u505c\u6b62\u6240\u6709\u4f20\u611f\u5668\u76d1\u63a7\u3002

        stopSensing()\n
        "},{"location":"qsl4a/system/sensors/#readsensors","title":"readSensors()","text":"

        \u8bfb\u53d6\u5f53\u524d\u4f20\u611f\u5668\u6570\u636e\u3002

        readSensors()\n

        \u8fd4\u56de\uff1a \u4f20\u611f\u5668\u6570\u636e\u5b57\u5178

        "},{"location":"qsl4a/system/sensors/#sensorsreadaccelerometer","title":"sensorsReadAccelerometer()","text":"

        \u8bfb\u53d6\u52a0\u901f\u5ea6\u8ba1\u503c\u3002

        sensorsReadAccelerometer()\n

        \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d m/s\u00b2

        "},{"location":"qsl4a/system/sensors/#sensorsreadgyroscope","title":"sensorsReadGyroscope()","text":"

        \u8bfb\u53d6\u9640\u87ba\u4eea\u503c\u3002

        sensorsReadGyroscope()\n

        \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d rad/s

        "},{"location":"qsl4a/system/sensors/#sensorsreadmagnetometer","title":"sensorsReadMagnetometer()","text":"

        \u8bfb\u53d6\u78c1\u573a\u503c\u3002

        sensorsReadMagnetometer()\n

        \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d \u03bcT

        "},{"location":"qsl4a/system/sensors/#sensorsreadorientation","title":"sensorsReadOrientation()","text":"

        \u8bfb\u53d6\u8bbe\u5907\u65b9\u5411\u3002

        sensorsReadOrientation()\n

        \u8fd4\u56de\uff1a \u5217\u8868 [azimuth, pitch, roll]\uff0c\u5355\u4f4d\u5ea6

        "},{"location":"qsl4a/system/sensors/#sensorsgetlight","title":"sensorsGetLight()","text":"

        \u8bfb\u53d6\u5149\u4f20\u611f\u5668\u503c\u3002

        sensorsGetLight()\n

        \u8fd4\u56de\uff1a \u5149\u7ea7\u522b\uff08lux\uff09

        "},{"location":"qsl4a/system/sensors/#sensorsgetstepcounter","title":"sensorsGetStepCounter()","text":"

        \u8bfb\u53d6\u6b65\u8ba1\u6570\u5668\u3002

        sensorsGetStepCounter()\n

        \u8fd4\u56de\uff1a \u6b65\u6570

        "},{"location":"qsl4a/system/sensors/#sensorsgetaccuracy","title":"sensorsGetAccuracy()","text":"

        \u83b7\u53d6\u5f53\u524d\u4f20\u611f\u5668\u7cbe\u5ea6\u3002

        sensorsGetAccuracy()\n

        \u8fd4\u56de\uff1a \u7cbe\u5ea6\u503c\uff080-3\uff1aUNRELIABLE\u3001ACCURACY_LOW\u3001ACCURACY_MEDIUM\u3001ACCURACY_HIGH\uff09

        "},{"location":"qsl4a/system/sensors/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u8bfb\u53d6\u4f20\u611f\u5668 10 \u6b21\nfor i in range(10):\n    accel = droid.sensorsReadAccelerometer().result\n    print(f\"Accel: X={accel[0]:.2f}, Y={accel[1]:.2f}, Z={accel[2]:.2f}\")\n    time.sleep(0.5)\n\ndroid.stopSensing()\n
        "},{"location":"qsl4a/system/settings/","title":"\u8bbe\u7f6e API","text":"

        \u63a7\u5236\u7cfb\u7edf\u8bbe\u7f6e\uff0c\u5305\u62ec\u5c4f\u5e55\u3001\u58f0\u97f3\u548c\u7f51\u7edc\u8bbe\u7f6e\u3002

        "},{"location":"qsl4a/system/settings/#_1","title":"\u5c4f\u5e55\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#setscreentimeout","title":"setScreenTimeout()","text":"

        \u8bbe\u7f6e\u5c4f\u5e55\u8d85\u65f6\u503c\u3002

        setScreenTimeout(value)\n

        \u53c2\u6570\uff1a - value (int): \u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

        \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u8d85\u65f6\u503c

        "},{"location":"qsl4a/system/settings/#getscreentimeout","title":"getScreenTimeout()","text":"

        \u83b7\u53d6\u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u3002

        getScreenTimeout()\n

        \u8fd4\u56de\uff1a \u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

        "},{"location":"qsl4a/system/settings/#getscreenbrightness","title":"getScreenBrightness()","text":"

        \u83b7\u53d6\u5c4f\u5e55\u4eae\u5ea6\u503c\u3002

        getScreenBrightness()\n

        \u8fd4\u56de\uff1a \u4eae\u5ea6\u503c\uff080-255\uff09

        "},{"location":"qsl4a/system/settings/#setscreenbrightness","title":"setScreenBrightness()","text":"

        \u8bbe\u7f6e\u5c4f\u5e55\u4eae\u5ea6\u3002

        setScreenBrightness(value=None)\n

        \u53c2\u6570\uff1a - value (int, optional): \u4eae\u5ea6\u503c\uff080-255\uff09\uff0c\u6216 None \u8868\u793a\u81ea\u52a8

        \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u4eae\u5ea6\u503c

        "},{"location":"qsl4a/system/settings/#checkscreenon","title":"checkScreenOn()","text":"

        \u68c0\u67e5\u5c4f\u5e55\u662f\u5426\u4eae\u7740\u3002

        checkScreenOn()\n

        \u8fd4\u56de\uff1a \u5982\u679c\u5c4f\u5e55\u4eae\u7740\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

        "},{"location":"qsl4a/system/settings/#_2","title":"\u98de\u884c\u6a21\u5f0f","text":""},{"location":"qsl4a/system/settings/#checkairplanemode","title":"checkAirplaneMode()","text":"

        \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\u662f\u5426\u542f\u7528\u3002

        checkAirplaneMode()\n

        \u8fd4\u56de\uff1a \u5982\u679c\u98de\u884c\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

        "},{"location":"qsl4a/system/settings/#_3","title":"\u94c3\u58f0\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#checkringersilentmode","title":"checkRingerSilentMode()","text":"

        \u68c0\u67e5\u94c3\u58f0\u662f\u5426\u5904\u4e8e\u9759\u97f3\u6a21\u5f0f\u3002

        checkRingerSilentMode()\n

        \u8fd4\u56de\uff1a \u5982\u679c\u9759\u97f3\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

        "},{"location":"qsl4a/system/settings/#toggleringersilentmode","title":"toggleRingerSilentMode()","text":"

        \u5207\u6362\u94c3\u58f0\u9759\u97f3\u6a21\u5f0f\u3002

        toggleRingerSilentMode(enabled=None)\n

        \u53c2\u6570\uff1a - enabled (bool, optional): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

        \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

        "},{"location":"qsl4a/system/settings/#togglevibratemode","title":"toggleVibrateMode()","text":"

        \u5207\u6362\u632f\u52a8\u6a21\u5f0f\u3002

        toggleVibrateMode(enabled=None, ringer=None)\n

        \u53c2\u6570\uff1a - enabled (bool, optional): \u5207\u6362\u632f\u52a8\u5f00/\u5173 - ringer (bool, optional): \u5e94\u7528\u4e8e\u94c3\u58f0\u6a21\u5f0f

        \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

        "},{"location":"qsl4a/system/settings/#getvibratemode","title":"getVibrateMode()","text":"

        \u83b7\u53d6\u632f\u52a8\u6a21\u5f0f\u8bbe\u7f6e\u3002

        getVibrateMode(ringer=None)\n

        \u53c2\u6570\uff1a - ringer (bool, optional): \u68c0\u67e5\u94c3\u58f0\u632f\u52a8\u6a21\u5f0f

        \u8fd4\u56de\uff1a \u5982\u679c\u632f\u52a8\u5df2\u542f\u7528\u5219\u4e3a True

        "},{"location":"qsl4a/system/settings/#_4","title":"\u97f3\u91cf\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#getringervolume","title":"getRingerVolume()","text":"

        \u83b7\u53d6\u5f53\u524d\u94c3\u58f0\u97f3\u91cf\u3002

        getRingerVolume()\n

        \u8fd4\u56de\uff1a \u94c3\u58f0\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-7\uff09

        "},{"location":"qsl4a/system/settings/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

        \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

        getMaxRingerVolume()\n

        \u8fd4\u56de\uff1a \u6700\u5927\u94c3\u58f0\u97f3\u91cf

        "},{"location":"qsl4a/system/settings/#setringervolume","title":"setRingerVolume()","text":"

        \u8bbe\u7f6e\u94c3\u58f0\u97f3\u91cf\u3002

        setRingerVolume(volume)\n

        \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

        "},{"location":"qsl4a/system/settings/#getmediavolume","title":"getMediaVolume()","text":"

        \u83b7\u53d6\u5f53\u524d\u5a92\u4f53\u97f3\u91cf\u3002

        getMediaVolume()\n

        \u8fd4\u56de\uff1a \u5a92\u4f53\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-15\uff09

        "},{"location":"qsl4a/system/settings/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

        \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

        getMaxMediaVolume()\n

        \u8fd4\u56de\uff1a \u6700\u5927\u5a92\u4f53\u97f3\u91cf

        "},{"location":"qsl4a/system/settings/#setmediavolume","title":"setMediaVolume()","text":"

        \u8bbe\u7f6e\u5a92\u4f53\u97f3\u91cf\u3002

        setMediaVolume(volume)\n

        \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

        "},{"location":"qsl4a/system/settings/#_5","title":"\u7cfb\u7edf\u4fe1\u606f","text":""},{"location":"qsl4a/system/settings/#elapsedrealtimenanos","title":"elapsedRealtimeNanos()","text":"

        \u83b7\u53d6\u81ea\u7cfb\u7edf\u542f\u52a8\u4ee5\u6765\u7684\u7eb3\u79d2\u6570\u3002

        elapsedRealtimeNanos()\n

        \u8fd4\u56de\uff1a \u7eb3\u79d2\u6570\uff08\u53ef\u7528\u4e8e\u8ba1\u65f6\uff09

        "},{"location":"qsl4a/system/settings/#gettrafficstats","title":"getTrafficStats()","text":"

        \u83b7\u53d6\u7f51\u7edc\u6d41\u91cf\u7edf\u8ba1\u3002

        getTrafficStats(flags=7)\n

        \u53c2\u6570\uff1a - flags (int): \u8981\u68c0\u7d22\u7684\u7edf\u8ba1\uff08\u9ed8\u8ba4\uff1a7 = \u5168\u90e8\uff09

        \u8fd4\u56de\uff1a \u5305\u542b\u53d1\u9001/\u63a5\u6536\u5b57\u8282\u7684\u5b57\u5178

        "},{"location":"qsl4a/system/settings/#getapptxbytes","title":"getAppTxBytes()","text":"

        \u83b7\u53d6 QPython \u5e94\u7528\u7684\u53d1\u9001\u5b57\u8282\u3002

        getAppTxBytes(packageName)\n

        \u53c2\u6570\uff1a - packageName (str): \u5305\u540d

        \u8fd4\u56de\uff1a \u5305\u542b tx/rx \u5b57\u8282\u7684\u5b57\u5178

        "},{"location":"qsl4a/system/settings/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5c4f\u5e55\u8bbe\u7f6e\ncurrent_timeout = droid.getScreenTimeout().result\nprint(f\"Current timeout: {current_timeout}s\")\ndroid.setScreenTimeout(30)\n\n# \u68c0\u67e5\u5c4f\u5e55\nif droid.checkScreenOn().result:\n    print(\"Screen is on\")\n\n# \u97f3\u91cf\u63a7\u5236\nmedia_vol = droid.getMediaVolume().result\nprint(f\"Media volume: {media_vol}\")\ndroid.setMediaVolume(10)\n\n# \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\nif droid.checkAirplaneMode().result:\n    print(\"Airplane mode is on\")\n
        "},{"location":"qsl4a/system/sysinfo/","title":"\u7cfb\u7edf\u4fe1\u606f","text":"

        \u68c0\u7d22\u8bbe\u5907\u548c\u7cfb\u7edf\u4fe1\u606f\u3002

        "},{"location":"qsl4a/system/sysinfo/#_2","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/sysinfo/#getandroidid","title":"getAndroidID()","text":"

        \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

        getAndroidID()\n

        \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

        "},{"location":"qsl4a/system/sysinfo/#getsysinfo","title":"getSysInfo()","text":"

        \u83b7\u53d6\u7efc\u5408\u7cfb\u7edf\u4fe1\u606f\u3002

        getSysInfo()\n

        \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

        "},{"location":"qsl4a/system/sysinfo/#getlocale","title":"getLocale()","text":"

        \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u8bbe\u7f6e\u3002

        getLocale()\n

        \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

        "},{"location":"qsl4a/system/sysinfo/#_3","title":"\u5185\u5b58","text":""},{"location":"qsl4a/system/sysinfo/#getmemoryinfo","title":"getMemoryInfo()","text":"

        \u83b7\u53d6 RAM \u4fe1\u606f\u3002

        getMemoryInfo()\n

        \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

        "},{"location":"qsl4a/system/sysinfo/#_4","title":"\u663e\u793a","text":""},{"location":"qsl4a/system/sysinfo/#getscreeninfo","title":"getScreenInfo()","text":"

        \u83b7\u53d6\u663e\u793a\u4fe1\u606f\u3002

        getScreenInfo()\n

        \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

        "},{"location":"qsl4a/system/sysinfo/#_5","title":"\u6807\u8bc6\u7b26","text":""},{"location":"qsl4a/system/sysinfo/#getimei","title":"getImei()","text":"

        \u83b7\u53d6\u8bbe\u5907 IMEI\u3002

        getImei(slotIndex=None)\n
        "},{"location":"qsl4a/system/sysinfo/#getmeid","title":"getMeid()","text":"

        \u83b7\u53d6\u8bbe\u5907 MEID\u3002

        getMeid(slotIndex=None)\n
        "},{"location":"qsl4a/system/sysinfo/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u8bbe\u5907 ID\nandroid_id = droid.getAndroidID().result\nprint(f\"Android ID: {android_id}\")\n\n# \u5c4f\u5e55\u4fe1\u606f\nscreen = droid.getScreenInfo().result\nprint(f\"Screen: {screen['width']}x{screen['height']}\")\n\n# \u5185\u5b58\nmemory = droid.getMemoryInfo().result\nprint(f\"Memory: {memory}\")\n
        "},{"location":"qsl4a/system/wakelock/","title":"WakeLock API","text":"

        \u63a7\u5236\u8bbe\u5907\u5524\u9192\u9501\u4ee5\u4fdd\u6301 CPU \u6216\u5c4f\u5e55\u5f00\u542f\u3002

        "},{"location":"qsl4a/system/wakelock/#wake-lock","title":"Wake Lock \u7c7b\u578b","text":"

        QSL4A \u63d0\u4f9b\u4e0d\u540c\u7c7b\u578b\u7684\u5524\u9192\u9501\uff1a

        \u7c7b\u578b \u63cf\u8ff0 Full CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae Partial \u4ec5 CPU \u5f00\u542f Bright CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae Dim CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697"},{"location":"qsl4a/system/wakelock/#wake-lock_1","title":"Wake Lock \u65b9\u6cd5","text":""},{"location":"qsl4a/system/wakelock/#wakelockacquirefull","title":"wakeLockAcquireFull()","text":"

        \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae\uff09\u3002

        wakeLockAcquireFull()\n
        "},{"location":"qsl4a/system/wakelock/#wakelockacquirepartial","title":"wakeLockAcquirePartial()","text":"

        \u83b7\u53d6\u90e8\u5206\u5524\u9192\u9501\uff08\u4ec5 CPU \u5f00\u542f\uff09\u3002

        wakeLockAcquirePartial()\n
        "},{"location":"qsl4a/system/wakelock/#wakelockacquirebright","title":"wakeLockAcquireBright()","text":"

        \u83b7\u53d6\u660e\u4eae\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff09\u3002

        wakeLockAcquireBright()\n
        "},{"location":"qsl4a/system/wakelock/#wakelockacquiredim","title":"wakeLockAcquireDim()","text":"

        \u83b7\u53d6\u6697\u6de1\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697\uff09\u3002

        wakeLockAcquireDim()\n
        "},{"location":"qsl4a/system/wakelock/#wakelockrelease","title":"wakeLockRelease()","text":"

        \u91ca\u653e\u5524\u9192\u9501\u3002

        wakeLockRelease()\n
        "},{"location":"qsl4a/system/wakelock/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\ndroid.wakeLockAcquireFull()\n\n# \u5728\u4fdd\u6301\u5c4f\u5e55\u5f00\u542f\u65f6\u6267\u884c\u91cd\u8981\u5de5\u4f5c\nprint(\"Screen will stay on\")\ntime.sleep(10)\n\n# \u5b8c\u6210\u540e\u91ca\u653e\ndroid.wakeLockRelease()\n\n# \u6216\u4f7f\u7528\u90e8\u5206\u9501\u8fdb\u884c\u540e\u53f0\u4efb\u52a1\ndroid.wakeLockAcquirePartial()\n# \u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\uff0cCPU \u4ecd\u4fdd\u6301\u5f00\u542f\ntime.sleep(30)\ndroid.wakeLockRelease()\n

        \u6ce8\u610f\uff1a \u8bb0\u4f4f\u5728\u4e0d\u9700\u8981\u65f6\u91ca\u653e\u5524\u9192\u9501\u4ee5\u8282\u7701\u7535\u6c60\u3002

        "},{"location":"qsl4a/ui/accessibility/","title":"\u65e0\u969c\u788d\u670d\u52a1","text":"

        \u65e0\u969c\u788d\u670d\u52a1\u5141\u8bb8\u81ea\u52a8\u5316 UI \u4ea4\u4e92\uff0c\u5982\u70b9\u51fb\u3001\u6ed1\u52a8\u548c\u7cfb\u7edf\u64cd\u4f5c\u3002

        "},{"location":"qsl4a/ui/accessibility/#_2","title":"\u670d\u52a1\u63a7\u5236","text":""},{"location":"qsl4a/ui/accessibility/#accessibilitystartservice","title":"accessibilityStartService()","text":"

        \u542f\u52a8\u65e0\u969c\u788d\u670d\u52a1\u3002

        accessibilityStartService()\n

        \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

        "},{"location":"qsl4a/ui/accessibility/#accessibilityserviceenabled","title":"accessibilityServiceEnabled()","text":"

        \u68c0\u67e5\u65e0\u969c\u788d\u670d\u52a1\u662f\u5426\u5df2\u542f\u7528\u3002

        accessibilityServiceEnabled()\n

        \u8fd4\u56de\uff1a True \u6216 False

        "},{"location":"qsl4a/ui/accessibility/#_3","title":"\u5c4f\u5e55\u4ea4\u4e92","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityclick","title":"accessibilityClick()","text":"

        \u5728\u5c4f\u5e55\u5750\u6807\u5904\u70b9\u51fb\u3002

        accessibilityClick(x=0, y=0, t=50)\n

        \u53c2\u6570\uff1a - x (int/float): X \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - y (int/float): Y \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - t (int): \u6309\u4f4f\u65f6\u957f\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a50\uff09

        "},{"location":"qsl4a/ui/accessibility/#accessibilityslide","title":"accessibilitySlide()","text":"

        \u591a\u70b9\u6ed1\u52a8\u624b\u52bf\u3002

        accessibilitySlide(XnYn=None, t=None)\n

        \u53c2\u6570\uff1a - XnYn (list): \u5750\u6807 [X1, Y1, X2, Y2, ... Xn, Yn] - t (int): \u6ed1\u52a8\u65f6\u957f\uff08\u9ed8\u8ba4\uff1a50*n \u6beb\u79d2\uff09

        "},{"location":"qsl4a/ui/accessibility/#_4","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityaction","title":"accessibilityAction()","text":"

        \u6309\u4ee3\u7801\u6267\u884c\u7cfb\u7edf\u64cd\u4f5c\u3002

        accessibilityAction(actionCode)\n

        \u64cd\u4f5c\u4ee3\u7801\uff1a | \u4ee3\u7801 | \u5e38\u91cf | \u63cf\u8ff0 | |------|----------|-------------| | 1 | BACK | \u8fd4\u56de\u6309\u94ae | | 2 | HOME | \u4e3b\u5c4f\u5e55\u6309\u94ae | | 3 | RECENTS | \u6700\u8fd1\u5e94\u7528 | | 4 | NOTIFICATIONS | \u6253\u5f00\u901a\u77e5 | | 5 | QUICK_SETTINGS | \u6253\u5f00\u5feb\u901f\u8bbe\u7f6e | | 6 | POWER_DIALOG | \u7535\u6e90\u83dc\u5355 | | 7 | TOGGLE_SPLIT_SCREEN | \u5206\u5c4f | | 8 | LOCK_SCREEN | \u9501\u5c4f | | 9 | TAKE_SCREENSHOT | \u622a\u56fe | | 10 | KEYCODE_HEADSETHOOK | \u8033\u673a\u6302\u94a9 | | 11-14 | ACCESSIBILITY_ | \u65e0\u969c\u788d\u6309\u94ae | | 15 | DISMISS_NOTIFICATION_SHADE | \u5173\u95ed\u901a\u77e5\u680f | | 16-20 | DPAD_ | \u65b9\u5411\u952e | | 21 | MENU | \u83dc\u5355\u6309\u94ae | | 22 | MEDIA_PLAY_PAUSE | \u64ad\u653e/\u6682\u505c\u5a92\u4f53 |

        "},{"location":"qsl4a/ui/accessibility/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/accessibility/#_6","title":"\u70b9\u51fb\u5c4f\u5e55\u4e2d\u5fc3","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u670d\u52a1\nif not droid.accessibilityServiceEnabled().result:\n    droid.accessibilityStartService()\n\n# \u70b9\u51fb\u4e2d\u5fc3\uff080,0 = \u4e2d\u5fc3\uff09\ndroid.accessibilityClick(0, 0, t=100)\n
        "},{"location":"qsl4a/ui/accessibility/#_7","title":"\u6ed1\u52a8\u624b\u52bf","text":"
        # \u4ece\u4e0b\u5f80\u4e0a\u6ed1\u52a8\uff08\u5411\u4e0a\u6eda\u52a8\uff09\ndroid.accessibilitySlide([0, 1.5, 0, -1.5], t=300)\n
        "},{"location":"qsl4a/ui/accessibility/#_8","title":"\u7cfb\u7edf\u5bfc\u822a","text":"
        # \u6309\u4e3b\u5c4f\u5e55\ndroid.accessibilityAction(2)\n\n# \u6309\u8fd4\u56de\ndroid.accessibilityAction(1)\n\n# \u6253\u5f00\u901a\u77e5\ndroid.accessibilityAction(4)\n
        "},{"location":"qsl4a/ui/accessibility/#_9","title":"\u70b9\u51fb\u7279\u5b9a\u4f4d\u7f6e","text":"
        # \u70b9\u51fb\u5c4f\u5e55\u5750\u6807 (500, 800)\ndroid.accessibilityClick(500, 800)\n\n# \u70b9\u51fb\u76f8\u5bf9\u4f4d\u7f6e\uff08\u6c34\u5e73\u5c45\u4e2d\uff0c\u5782\u76f4 3/4 \u5904\uff09\ndroid.accessibilityClick(0, 1.5)\n
        "},{"location":"qsl4a/ui/dialogs/","title":"\u5bf9\u8bdd\u6846\u7cfb\u7edf","text":"

        QSL4A \u63d0\u4f9b\u5168\u9762\u7684\u5bf9\u8bdd\u6846\u652f\u6301\uff0c\u7528\u4e8e\u7528\u6237\u4ea4\u4e92\uff0c\u5305\u62ec\u8b66\u62a5\u3001\u8f93\u5165\u5bf9\u8bdd\u6846\u3001\u9009\u62e9\u5bf9\u8bdd\u6846\u548c\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

        "},{"location":"qsl4a/ui/dialogs/#_2","title":"\u8b66\u62a5\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowalert","title":"dialogShowAlert()","text":"

        \u663e\u793a\u7b80\u5355\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

        dialogShowAlert(title=\"Alert\", message=\"The message of the alert.\",\n                positiveButtonText=\"OK\", negativeButtonText=None,\n                neutralButtonText=None, messageIsHtml=False)\n

        \u53c2\u6570\uff1a - title (str): \u5bf9\u8bdd\u6846\u6807\u9898 - message (str): \u6d88\u606f\u6587\u672c - positiveButtonText (str): \u80af\u5b9a\u6309\u94ae\u6807\u7b7e - negativeButtonText (str, optional): \u5426\u5b9a\u6309\u94ae\u6807\u7b7e - neutralButtonText (str, optional): \u4e2d\u6027\u6309\u94ae\u6807\u7b7e - messageIsHtml (bool): \u5c06\u6d88\u606f\u89e3\u6790\u4e3a HTML

        \u8fd4\u56de\uff1a \u5305\u542b\u70b9\u51fb\u6309\u94ae\u7684\u7ed3\u679c

        "},{"location":"qsl4a/ui/dialogs/#dialogshowsimplechoice","title":"dialogShowSimpleChoice()","text":"

        \u663e\u793a\u5e26\u6709\u9879\u76ee\u7684\u7b80\u5355\u9009\u62e9\u5bf9\u8bdd\u6846\u3002

        dialogShowSimpleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

        \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868

        \u8fd4\u56de\uff1a \u5305\u542b\u9009\u4e2d\u9879\u76ee\u7684\u7ed3\u679c

        "},{"location":"qsl4a/ui/dialogs/#_3","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialoggetinput","title":"dialogGetInput()","text":"

        \u83b7\u53d6\u7528\u6237\u6587\u672c\u8f93\u5165\u3002

        dialogGetInput(title=\"Value\", message=\"Please enter value:\",\n               defaultText=None, messageIsHtml=False)\n

        \u8fd4\u56de\uff1a \u5305\u542b\u7528\u6237\u8f93\u5165\u6587\u672c\u7684\u7ed3\u679c

        "},{"location":"qsl4a/ui/dialogs/#dialoggetpassword","title":"dialogGetPassword()","text":"

        \u83b7\u53d6\u5bc6\u7801\u8f93\u5165\u3002

        dialogGetPassword(title=\"Password\", message=\"Please enter password:\")\n

        \u8fd4\u56de\uff1a \u5305\u542b\u8f93\u5165\u5bc6\u7801\u7684\u7ed3\u679c

        "},{"location":"qsl4a/ui/dialogs/#dialogcreateinput","title":"dialogCreateInput()","text":"

        \u521b\u5efa\u81ea\u5b9a\u4e49\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

        dialogCreateInput(title=\"Value\", message=\"Please enter value:\",\n                  defaultText=None, inputType=None)\n

        \u53c2\u6570\uff1a - inputType (str): \u8f93\u5165\u7c7b\u578b\uff08\u4f8b\u5982 \"text\"\u3001\"number\"\u3001\"textPassword\"\uff09

        "},{"location":"qsl4a/ui/dialogs/#dialogcreatepassword","title":"dialogCreatePassword()","text":"

        \u521b\u5efa\u5bc6\u7801\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

        dialogCreatePassword(title=\"Password\", message=\"Please enter password:\")\n
        "},{"location":"qsl4a/ui/dialogs/#dialogcreateseekbar","title":"dialogCreateSeekBar()","text":"

        \u521b\u5efa\u6ed1\u5757/\u8fdb\u5ea6\u6761\u5bf9\u8bdd\u6846\u3002

        dialogCreateSeekBar(starting_value=50, maximum_value=100, title=\"\", message=\"\")\n

        \u53c2\u6570\uff1a - starting_value (int): \u521d\u59cb\u503c - maximum_value (int): \u6700\u5927\u503c

        "},{"location":"qsl4a/ui/dialogs/#_4","title":"\u9009\u62e9\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowsinglechoice","title":"dialogShowSingleChoice()","text":"

        \u663e\u793a\u5355\u9009\uff08\u5355\u9009\u6309\u94ae\uff09\u5bf9\u8bdd\u6846\u3002

        dialogShowSingleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, selected=-1, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

        \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (int): \u9ed8\u8ba4\u9009\u4e2d\u7d22\u5f15

        "},{"location":"qsl4a/ui/dialogs/#dialogshowmultichoice","title":"dialogShowMultiChoice()","text":"

        \u663e\u793a\u591a\u9009\uff08\u590d\u9009\u6846\uff09\u5bf9\u8bdd\u6846\u3002

        dialogShowMultiChoice(title=\"Alert\", message=\"The message of the alert.\",\n                      items=None, selected=None, positiveButtonText=\"OK\",\n                      negativeButtonText=None, neutralButtonText=None,\n                      messageIsHtml=False)\n

        \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (list): \u521d\u59cb\u9009\u4e2d\u7d22\u5f15\u5217\u8868

        "},{"location":"qsl4a/ui/dialogs/#dialogsetsinglechoiceitems","title":"dialogSetSingleChoiceItems()","text":"

        \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u5355\u9009\u9879\u76ee\u3002

        dialogSetSingleChoiceItems(items, selected=-1)\n
        "},{"location":"qsl4a/ui/dialogs/#dialogsetmultichoiceitems","title":"dialogSetMultiChoiceItems()","text":"

        \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u591a\u9009\u9879\u76ee\u3002

        dialogSetMultiChoiceItems(items, selected=None)\n
        "},{"location":"qsl4a/ui/dialogs/#_5","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatespinnerprogress","title":"dialogCreateSpinnerProgress()","text":"

        \u521b\u5efa\u4e0d\u786e\u5b9a\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

        dialogCreateSpinnerProgress(title=None, message=None, maximum_progress=100)\n
        "},{"location":"qsl4a/ui/dialogs/#dialogcreatehorizontalprogress","title":"dialogCreateHorizontalProgress()","text":"

        \u521b\u5efa\u6c34\u5e73\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

        dialogCreateHorizontalProgress(title=None, message=None, maximum_progress=100)\n
        "},{"location":"qsl4a/ui/dialogs/#dialogsetcurrentprogress","title":"dialogSetCurrentProgress()","text":"

        \u66f4\u65b0\u8fdb\u5ea6\u503c\u3002

        dialogSetCurrentProgress(current)\n
        "},{"location":"qsl4a/ui/dialogs/#dialogsetmaxprogress","title":"dialogSetMaxProgress()","text":"

        \u8bbe\u7f6e\u6700\u5927\u8fdb\u5ea6\u503c\u3002

        dialogSetMaxProgress(max)\n
        "},{"location":"qsl4a/ui/dialogs/#dialogsetprogressmessage","title":"dialogSetProgressMessage()","text":"

        \u66f4\u65b0\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u6d88\u606f\u3002

        dialogSetProgressMessage(message)\n
        "},{"location":"qsl4a/ui/dialogs/#_6","title":"\u9009\u62e9\u5668\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatedatepicker","title":"dialogCreateDatePicker()","text":"

        \u521b\u5efa\u65e5\u671f\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

        dialogCreateDatePicker(year=1970, month=1, day=1)\n
        "},{"location":"qsl4a/ui/dialogs/#dialogcreatetimepicker","title":"dialogCreateTimePicker()","text":"

        \u521b\u5efa\u65f6\u95f4\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

        dialogCreateTimePicker(hour=0, minute=0, is24hour=False)\n
        "},{"location":"qsl4a/ui/dialogs/#_7","title":"\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u521b\u5efa","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatealert","title":"dialogCreateAlert()","text":"

        \u521b\u5efa\u81ea\u5b9a\u4e49\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

        dialogCreateAlert(title=None, message=None)\n

        \u521b\u5efa\u4e00\u4e2a\u7a7a\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002\u53ef\u4e0e\u5176\u4ed6 dialogSet* \u51fd\u6570\u4e00\u8d77\u4f7f\u7528\u6765\u81ea\u5b9a\u4e49\u3002

        "},{"location":"qsl4a/ui/dialogs/#dialogsetitems","title":"dialogSetItems()","text":"

        \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u7b80\u5355\u5217\u8868\u9879\u76ee\u3002

        dialogSetItems(items)\n
        "},{"location":"qsl4a/ui/dialogs/#dialogsetpositivebuttontext","title":"dialogSetPositiveButtonText()","text":"

        \u8bbe\u7f6e\u80af\u5b9a\u6309\u94ae\u6587\u672c\u3002

        dialogSetPositiveButtonText(text)\n
        "},{"location":"qsl4a/ui/dialogs/#dialogsetnegativebuttontext","title":"dialogSetNegativeButtonText()","text":"

        \u8bbe\u7f6e\u5426\u5b9a\u6309\u94ae\u6587\u672c\u3002

        dialogSetNegativeButtonText(text)\n
        "},{"location":"qsl4a/ui/dialogs/#dialogsetneutralbuttontext","title":"dialogSetNeutralButtonText()","text":"

        \u8bbe\u7f6e\u4e2d\u6027\u6309\u94ae\u6587\u672c\u3002

        dialogSetNeutralButtonText(text)\n
        "},{"location":"qsl4a/ui/dialogs/#dialogsetmessageishtml","title":"dialogSetMessageIsHtml()","text":"

        \u8bbe\u7f6e\u6d88\u606f\u662f\u5426\u5e94\u89e3\u6790\u4e3a HTML\u3002

        dialogSetMessageIsHtml(messageIsHtml=True)\n
        "},{"location":"qsl4a/ui/dialogs/#dialogshow","title":"dialogShow()","text":"

        \u663e\u793a\u521b\u5efa\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u3002

        dialogShow()\n
        "},{"location":"qsl4a/ui/dialogs/#_8","title":"\u5bf9\u8bdd\u6846\u63a7\u5236","text":""},{"location":"qsl4a/ui/dialogs/#dialogdismiss","title":"dialogDismiss()","text":"

        \u5173\u95ed\u5f53\u524d\u5bf9\u8bdd\u6846\u3002

        dialogDismiss()\n
        "},{"location":"qsl4a/ui/dialogs/#dialoggetresponse","title":"dialogGetResponse()","text":"

        \u83b7\u53d6\u5bf9\u8bdd\u6846\u54cd\u5e94\u3002

        dialogGetResponse()\n
        "},{"location":"qsl4a/ui/dialogs/#dialoggetselecteditems","title":"dialogGetSelectedItems()","text":"

        \u4ece\u9009\u62e9\u5bf9\u8bdd\u6846\u83b7\u53d6\u9009\u4e2d\u7684\u9879\u76ee\u3002

        dialogGetSelectedItems()\n
        "},{"location":"qsl4a/ui/dialogs/#_9","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/dialogs/#_10","title":"\u7b80\u5355\u8b66\u62a5","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a\u8b66\u62a5\ndroid.dialogShowAlert(\"Warning\", \"This is an important message!\")\n
        "},{"location":"qsl4a/ui/dialogs/#_11","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":"
        # \u83b7\u53d6\u7528\u6237\u8f93\u5165\nresult = droid.dialogGetInput(\"Name\", \"Enter your name:\", \"John\").result\nprint(f\"Hello, {result}!\")\n
        "},{"location":"qsl4a/ui/dialogs/#_12","title":"\u5e26\u6309\u94ae\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846","text":"
        # \u521b\u5efa\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\ndroid.dialogCreateAlert(\"Custom\", \"Choose an option\")\ndroid.dialogSetItems([\"Option 1\", \"Option 2\", \"Option 3\"])\ndroid.dialogShow()\n\n# \u83b7\u53d6\u54cd\u5e94\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response['item']}\")\n
        "},{"location":"qsl4a/ui/dialogs/#_13","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":"
        # \u521b\u5efa\u8fdb\u5ea6\u5bf9\u8bdd\u6846\ndroid.dialogCreateHorizontalProgress(\"Loading\", \"Please wait...\", 100)\ndroid.dialogShow()\n\n# \u66f4\u65b0\u8fdb\u5ea6\nfor i in range(101):\n    droid.dialogSetCurrentProgress(i)\n    time.sleep(0.05)\n\ndroid.dialogDismiss()\n
        "},{"location":"qsl4a/ui/dialogs/#_14","title":"\u65e5\u671f\u9009\u62e9\u5668","text":"
        # \u663e\u793a\u65e5\u671f\u9009\u62e9\u5668\ndroid.dialogCreateDatePicker(2024, 1, 15)\ndroid.dialogShow()\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response}\")\n
        "},{"location":"qsl4a/ui/floatview/","title":"\u6d6e\u52a8\u89c6\u56fe","text":"

        \u6d6e\u52a8\u7a97\u53e3\u652f\u6301\uff0c\u7528\u4e8e\u5728\u5176\u4ed6\u5e94\u7528\u7a0b\u5e8f\u4e0a\u65b9\u4fdd\u6301\u663e\u793a\u7684\u8986\u76d6 UI \u5143\u7d20\u3002

        "},{"location":"qsl4a/ui/floatview/#_2","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/floatview/#floatview","title":"floatView()","text":"

        \u663e\u793a\u6216\u4fee\u6539\u6d6e\u52a8\u89c6\u56fe\u3002

        floatView(Args=None)\n

        \u53c2\u6570\uff1a - Args (dict): \u914d\u7f6e\u5b57\u5178\uff0c\u5305\u542b\u4ee5\u4e0b\u952e\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08-1 \u521b\u5efa\u65b0\u7684\uff0c>=0 \u4fee\u6539\u73b0\u6709\u7684\uff09 - text (str): \u8981\u663e\u793a\u7684\u6587\u672c\u5185\u5bb9 - html (str): HTML \u5185\u5bb9\uff08\u5982\u679c\u7701\u7565 text \u5219\u4f7f\u7528\uff09 - width (int): \u89c6\u56fe\u5bbd\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a300\uff09 - height (int): \u89c6\u56fe\u9ad8\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a150\uff09 - x (int): X \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - y (int): Y \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - backColor (str): ARGB \u5341\u516d\u8fdb\u5236\u80cc\u666f\u8272\uff08\u9ed8\u8ba4\uff1a'7f7f7f7f'\uff09 - textColor (str): ARGB \u5341\u516d\u8fdb\u5236\u6587\u672c\u8272\uff08\u9ed8\u8ba4\uff1a'ff000000'\uff09 - textSize (int): \u6587\u672c\u5927\u5c0f\uff08\u9ed8\u8ba4\uff1a10\uff09 - textAlign (int): \u6587\u672c\u5bf9\u9f50\uff080 = \u7ee7\u627f\uff09 - script (str): \u957f\u6309\u5173\u95ed\u540e\u8fd0\u884c\u7684\u811a\u672c\u8def\u5f84 - arg: \u811a\u672c\u53c2\u6570 - clickRemove (bool): \u542f\u7528\u70b9\u51fb\u79fb\u9664\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - flag (int): \u7a97\u53e3\u6807\u5fd7\uff08\u9ed8\u8ba4\uff1a40 - \u53ef\u89e6\u6478\uff09

        \u8fd4\u56de\uff1a \u5f53\u524d\u94fe\u5217\u8868\u957f\u5ea6

        "},{"location":"qsl4a/ui/floatview/#floatviewcount","title":"floatViewCount()","text":"

        \u83b7\u53d6\u6d3b\u52a8\u6d6e\u52a8\u89c6\u56fe\u7684\u6570\u91cf\u3002

        floatViewCount()\n

        \u8fd4\u56de\uff1a \u6d6e\u52a8\u89c6\u56fe\u6570\u91cf

        "},{"location":"qsl4a/ui/floatview/#floatviewresult","title":"floatViewResult()","text":"

        \u83b7\u53d6\u6d6e\u52a8\u89c6\u56fe\u7684\u7ed3\u679c/\u72b6\u6001\u3002

        floatViewResult(index=-1)\n

        \u53c2\u6570\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1\uff0c\u8fd4\u56de\u6700\u540e\u64cd\u4f5c\u7ed3\u679c\uff09

        \u8fd4\u56de\uff1a \u5305\u542b\u64cd\u4f5c\u8be6\u60c5\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - x, y: \u4f4d\u7f6e - time: \u65f6\u95f4\u6233 - operation: \u64cd\u4f5c\u7c7b\u578b\uff08'initial'\u3001'move' \u7b49\uff09 - index: \u89c6\u56fe\u7d22\u5f15 - removed: \u5982\u679c\u89c6\u56fe\u88ab\u79fb\u9664\u5219\u4e3a True

        "},{"location":"qsl4a/ui/floatview/#floatviewremove","title":"floatViewRemove()","text":"

        \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\u3002

        floatViewRemove(index=-1)\n

        \u53c2\u6570\uff1a - index (int): \u8981\u79fb\u9664\u7684\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1 \u79fb\u9664\u6700\u540e\u4e00\u4e2a\uff09

        \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a 1\uff0c\u5426\u5219\u4e3a 0

        "},{"location":"qsl4a/ui/floatview/#_3","title":"\u5e38\u91cf","text":"
        • floatView.INDEX_NEW = -1 - \u521b\u5efa\u65b0\u7684\u6d6e\u52a8\u89c6\u56fe
        • floatView.FLAG_DEFAULT_TOUCHABLE = 40 - \u9ed8\u8ba4\u53ef\u89e6\u6478\u6807\u5fd7
        • floatView.TEXT_ALIGNMENT_INHERIT = 0
        • floatView.TEXT_ALIGNMENT_CENTER - \u5c45\u4e2d\u6587\u672c\u5bf9\u9f50
        "},{"location":"qsl4a/ui/floatview/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/floatview/#_5","title":"\u57fa\u672c\u6d6e\u52a8\u89c6\u56fe","text":"
        import androidhelper\nfrom androidhelper import Android\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u7b80\u5355\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'index': -1,  # \u521b\u5efa\u65b0\u7684\n    'text': 'Hello World',\n    'width': 400,\n    'height': 300,\n    'x': -300,  # \u4ece\u4e2d\u5fc3\u504f\u79fb\n    'y': -400,\n    'backColor': 'ff0000',  # \u7ea2\u8272\u80cc\u666f\n    'textColor': '0000ff',  # \u84dd\u8272\u6587\u672c\n    'textSize': 16,\n    'textAlign': droid.floatView.TEXT_ALIGNMENT_CENTER\n})\n\n# \u68c0\u67e5\u6570\u91cf\nprint(f\"Float views: {droid.floatViewCount().result}\")\n\n# \u83b7\u53d6\u7ed3\u679c\nresult = droid.floatViewResult().result\nprint(f\"View info: {result}\")\n\n# \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\ndroid.floatViewRemove(0)\n
        "},{"location":"qsl4a/ui/floatview/#html","title":"HTML \u5185\u5bb9","text":"
        # \u521b\u5efa\u5e26 HTML \u5185\u5bb9\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': '',  # \u7a7a\u6587\u672c\u4ee5\u4f7f\u7528 HTML\n    'html': '<h1>Title</h1><p>Rich <b>HTML</b> content</p>',\n    'width': 500,\n    'height': 400\n})\n
        "},{"location":"qsl4a/ui/floatview/#_6","title":"\u4fee\u6539\u73b0\u6709\u89c6\u56fe","text":"
        # \u521b\u5efa\u521d\u59cb\u89c6\u56fe\ndroid.floatView({'text': 'Initial Text', 'width': 300, 'height': 150})\n\n# \u4fee\u6539\u540c\u4e00\u89c6\u56fe\uff08\u7d22\u5f15 0\uff09\ndroid.floatView({\n    'index': 0,\n    'text': 'Updated Text!',\n    'backColor': '7f00ff00'  # \u7eff\u8272\u80cc\u666f\n})\n\n# \u68c0\u67e5\u79fb\u52a8/\u66f4\u6539\u7ed3\u679c\nresult = droid.floatViewResult(0).result\nprint(f\"Operation: {result.get('operation')}, Position: ({result.get('x')}, {result.get('y')})\")\n
        "},{"location":"qsl4a/ui/floatview/#_7","title":"\u591a\u4e2a\u6d6e\u52a8\u89c6\u56fe","text":"
        # \u521b\u5efa\u591a\u4e2a\u89c6\u56fe\nfor i in range(3):\n    droid.floatView({\n        'index': -1,\n        'text': f'View {i}',\n        'x': i * 100 - 150,\n        'y': i * 100 - 150,\n        'backColor': f'{i}f{i}f{i}f'\n    })\n\nprint(f\"Total views: {droid.floatViewCount().result}\")\n\n# \u79fb\u9664\u6240\u6709\u89c6\u56fe\nwhile droid.floatViewCount().result > 0:\n    droid.floatViewRemove()\n
        "},{"location":"qsl4a/ui/floatview/#_8","title":"\u5e26\u811a\u672c\u56de\u8c03","text":"
        # \u521b\u5efa\u5173\u95ed\u65f6\u8fd0\u884c\u811a\u672c\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': 'Click to close and run script',\n    'script': '/sdcard/my_script.py',\n    'arg': 'hello from float view',\n    'clickRemove': True\n})\n
        "},{"location":"qsl4a/ui/fullscreen/","title":"\u5168\u5c4f UI","text":"

        \u4f7f\u7528\u539f\u751f Android \u5e03\u5c40\u521b\u5efa\u81ea\u5b9a\u4e49\u5168\u5c4f\u754c\u9762\u3002

        "},{"location":"qsl4a/ui/fullscreen/#_1","title":"\u5e03\u5c40\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullshow","title":"fullShow()","text":"

        \u663e\u793a\u5168\u5c4f\u5e03\u5c40\u3002

        fullShow(layout, title=None, theme=None)\n

        \u53c2\u6570\uff1a - layout (str): JSON \u5e03\u5c40\u5b9a\u4e49\u6216\u5e03\u5c40\u5b57\u7b26\u4e32 - title (str, optional): \u7a97\u53e3\u6807\u9898 - theme (str, optional): \u4e3b\u9898\u540d\u79f0

        \u8fd4\u56de\uff1a \u7a97\u53e3 ID

        "},{"location":"qsl4a/ui/fullscreen/#fulldismiss","title":"fullDismiss()","text":"

        \u5173\u95ed\u5168\u5c4f\u7a97\u53e3\u3002

        fullDismiss()\n
        "},{"location":"qsl4a/ui/fullscreen/#fullquery","title":"fullQuery()","text":"

        \u67e5\u8be2\u6240\u6709\u5c0f\u90e8\u4ef6\u503c\u3002

        fullQuery()\n

        \u8fd4\u56de\uff1a \u5c0f\u90e8\u4ef6 ID \u548c\u503c\u7684\u5b57\u5178

        "},{"location":"qsl4a/ui/fullscreen/#fullquerydetail","title":"fullQueryDetail()","text":"

        \u67e5\u8be2\u7279\u5b9a\u5c0f\u90e8\u4ef6\u8be6\u60c5\u3002

        fullQueryDetail(id)\n
        "},{"location":"qsl4a/ui/fullscreen/#_2","title":"\u5c5e\u6027\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperty","title":"fullGetProperty()","text":"

        \u83b7\u53d6\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

        fullGetProperty(id, property)\n
        "},{"location":"qsl4a/ui/fullscreen/#fullsetproperty","title":"fullSetProperty()","text":"

        \u8bbe\u7f6e\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

        fullSetProperty(id, property, value)\n
        "},{"location":"qsl4a/ui/fullscreen/#fullsetlist","title":"fullSetList()","text":"

        \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

        fullSetList(id, list, isHtml=False, listType=0)\n
        "},{"location":"qsl4a/ui/fullscreen/#fullsetlist2","title":"fullSetList2()","text":"

        \u4f7f\u7528\u8d44\u6e90 ID \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

        fullSetList2(id, list, intRes)\n

        \u53c2\u6570\uff1a - id (str): \u5c0f\u90e8\u4ef6 ID - list (list): \u9879\u76ee\u5217\u8868 - intRes (int): \u5217\u8868\u9879\u76ee\u5e03\u5c40\u7684 Android \u8d44\u6e90 ID

        "},{"location":"qsl4a/ui/fullscreen/#fullsetlistselected","title":"fullSetListSelected()","text":"

        \u5728\u5217\u8868\u4e2d\u8bbe\u7f6e\u9009\u4e2d\u9879\u76ee\u3002

        fullSetListSelected(id, selected)\n

        \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID - selected (int): \u8981\u9009\u4e2d\u7684\u9879\u76ee\u7d22\u5f15

        "},{"location":"qsl4a/ui/fullscreen/#fullgetlistselected","title":"fullGetListSelected()","text":"

        \u83b7\u53d6\u5f53\u524d\u9009\u4e2d\u7684\u5217\u8868\u9879\u76ee\u7d22\u5f15\u3002

        fullGetListSelected(id)\n

        \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID

        \u8fd4\u56de\uff1a \u9009\u4e2d\u9879\u76ee\u7d22\u5f15

        "},{"location":"qsl4a/ui/fullscreen/#_3","title":"\u6279\u91cf\u5c5e\u6027\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperties","title":"fullGetProperties()","text":"

        \u4e00\u6b21\u83b7\u53d6\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

        fullGetProperties(ids, property)\n

        \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u83b7\u53d6\u7684\u5c5e\u6027\u540d

        \u8fd4\u56de\uff1a \u6620\u5c04\u5c0f\u90e8\u4ef6 ID \u5230\u5c5e\u6027\u503c\u7684\u5b57\u5178

        "},{"location":"qsl4a/ui/fullscreen/#fullsetproperties","title":"fullSetProperties()","text":"

        \u4e00\u6b21\u8bbe\u7f6e\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

        fullSetProperties(ids, property, value)\n

        \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u8bbe\u7f6e\u7684\u5c5e\u6027\u540d - value: \u5c5e\u6027\u503c

        "},{"location":"qsl4a/ui/fullscreen/#_4","title":"\u622a\u56fe","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetscreenshot","title":"fullGetScreenShot()","text":"

        \u6355\u83b7\u5168\u5c4f\u622a\u56fe\u3002

        fullGetScreenShot(path=None)\n

        \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u5728\u4e8b\u4ef6\u4e2d\u8fd4\u56de

        \u8fd4\u56de\uff1a \u5305\u542b\u622a\u56fe\u6570\u636e\u7684\u4e8b\u4ef6

        "},{"location":"qsl4a/ui/fullscreen/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
        import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b9a\u4e49\u5e03\u5c40\nlayout = '''\n{ \"type\": \"LinearLayout\", \"orientation\": \"vertical\",\n  \"children\": [\n    { \"type\": \"TextView\", \"id\": \"title\", \"text\": \"Hello\" },\n    { \"type\": \"Button\", \"id\": \"btn\", \"text\": \"Click Me\" }\n  ]\n}\n'''\n\n# \u663e\u793a\u5e03\u5c40\ndroid.fullShow(layout, \"My App\")\n\n# \u67e5\u8be2\u6309\u94ae\u70b9\u51fb\nevent = droid.eventWaitFor('click', timeout=10)\nif event.result:\n    widget_id = event.result['data']['id']\n    if widget_id == 'btn':\n        print(\"Button clicked!\")\n\ndroid.fullDismiss()\n
        "}]} \ No newline at end of file From 8bd9f33ffdeec5ed9aaaeecaf6cd92da55ffb1cc Mon Sep 17 00:00:00 2001 From: "River@devbox" Date: Fri, 10 Apr 2026 13:25:58 +0800 Subject: [PATCH 31/32] Deploy site - 2026-04-10 13:25:57 --- en/sitemap.xml | 98 +- en/sitemap.xml.gz | Bin 608 -> 608 bytes zh/404.html | 28 + zh/AIPyApp/index.html | 28 + zh/GraphicalInterface/index.html | 28 + zh/Notebook/index.html | 28 + zh/Ollama/index.html | 28 + zh/Terminal/index.html | 30 +- zh/community/index.html | 28 + zh/editor-guide/index.html | 28 + zh/external-api/index.html | 28 + zh/featured-courses/index.html | 2863 +++++++++++++++++ zh/getting-started/index.html | 28 + zh/index.html | 29 + zh/qpypi-guide/index.html | 28 + zh/qpython-x/index.html | 28 + zh/qsl4a/connectivity/contacts/index.html | 28 + zh/qsl4a/connectivity/ftp/index.html | 28 + zh/qsl4a/connectivity/location/index.html | 28 + zh/qsl4a/connectivity/phone/index.html | 28 + .../connectivity/signalstrength/index.html | 28 + zh/qsl4a/connectivity/sms/index.html | 28 + zh/qsl4a/connectivity/wifi/index.html | 28 + zh/qsl4a/core/android-base/index.html | 28 + zh/qsl4a/core/events/index.html | 28 + zh/qsl4a/core/intent/index.html | 28 + zh/qsl4a/hardware/bluetooth/index.html | 28 + zh/qsl4a/hardware/camera/index.html | 28 + zh/qsl4a/hardware/recorder/index.html | 28 + zh/qsl4a/hardware/usbserial/index.html | 28 + zh/qsl4a/hardware/webcam/index.html | 28 + zh/qsl4a/index.html | 28 + zh/qsl4a/media/image/index.html | 28 + zh/qsl4a/media/mediaplayer/index.html | 28 + zh/qsl4a/special/cipher/index.html | 28 + zh/qsl4a/special/pgptai/index.html | 28 + zh/qsl4a/storage/clipboard/index.html | 28 + zh/qsl4a/storage/documentfile/index.html | 28 + zh/qsl4a/storage/preferences/index.html | 28 + zh/qsl4a/system/activityresult/index.html | 28 + zh/qsl4a/system/application/index.html | 28 + zh/qsl4a/system/battery/index.html | 28 + zh/qsl4a/system/qpyinterface/index.html | 28 + zh/qsl4a/system/sensors/index.html | 28 + zh/qsl4a/system/settings/index.html | 28 + zh/qsl4a/system/sysinfo/index.html | 28 + zh/qsl4a/system/wakelock/index.html | 28 + zh/qsl4a/ui/accessibility/index.html | 28 + zh/qsl4a/ui/dialogs/index.html | 28 + zh/qsl4a/ui/floatview/index.html | 28 + zh/qsl4a/ui/fullscreen/index.html | 28 + zh/search/search_index.json | 2 +- zh/sitemap.xml | 102 +- zh/sitemap.xml.gz | Bin 609 -> 621 bytes zh/static/udemy_aipy_featured.png | Bin 0 -> 143266 bytes zh/tutorial-hello-world/index.html | 30 +- zh/whats-new/index.html | 28 + 57 files changed, 4369 insertions(+), 101 deletions(-) create mode 100644 zh/featured-courses/index.html create mode 100644 zh/static/udemy_aipy_featured.png diff --git a/en/sitemap.xml b/en/sitemap.xml index 4641f3c..de2806c 100644 --- a/en/sitemap.xml +++ b/en/sitemap.xml @@ -2,198 +2,198 @@ https://www.qpython.org/en/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/AIPyApp/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/GraphicalInterface/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/Notebook/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/Ollama/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/Terminal/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/community/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/editor-guide/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/external-api/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/getting-started/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/qpypi-guide/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/qpython-x/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/tutorial-hello-world/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/whats-new/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/qsl4a/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/qsl4a/connectivity/contacts/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/qsl4a/connectivity/ftp/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/qsl4a/connectivity/location/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/qsl4a/connectivity/phone/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/qsl4a/connectivity/signalstrength/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/qsl4a/connectivity/sms/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/qsl4a/connectivity/wifi/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/qsl4a/core/android-base/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/qsl4a/core/events/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/qsl4a/core/intent/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/qsl4a/hardware/bluetooth/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/qsl4a/hardware/camera/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/qsl4a/hardware/recorder/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/qsl4a/hardware/usbserial/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/qsl4a/hardware/webcam/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/qsl4a/media/image/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/qsl4a/media/mediaplayer/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/qsl4a/special/cipher/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/qsl4a/special/pgptai/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/qsl4a/storage/clipboard/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/qsl4a/storage/documentfile/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/qsl4a/storage/preferences/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/qsl4a/system/activityresult/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/qsl4a/system/application/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/qsl4a/system/battery/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/qsl4a/system/qpyinterface/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/qsl4a/system/sensors/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/qsl4a/system/settings/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/qsl4a/system/sysinfo/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/qsl4a/system/wakelock/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/qsl4a/ui/accessibility/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/qsl4a/ui/dialogs/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/qsl4a/ui/floatview/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/en/qsl4a/ui/fullscreen/ - 2026-04-08 + 2026-04-10 \ No newline at end of file diff --git a/en/sitemap.xml.gz b/en/sitemap.xml.gz index 5d048e26b5653985bd6c157fd0a228935f3f277a..78d2583d8103ddd39781017d8688a3515547dad2 100644 GIT binary patch delta 73 zcmV-P0Ji_&1mFY*ABzYGfIZle2OR`yQ4HIWC@~Se-R-v9_Q&nd=P%X$k!no| fZuhqztNmTIzmdR!0Xwro0TuxW?Op-_(HH;#fXE)U diff --git a/zh/404.html b/zh/404.html index a218068..29f7602 100644 --- a/zh/404.html +++ b/zh/404.html @@ -613,6 +613,34 @@ + + + + + + +
      • + + + + + + + + 精选课程 + + + + + + + + +
      • + + + +
      diff --git a/zh/AIPyApp/index.html b/zh/AIPyApp/index.html index 82f31c0..2ff85d7 100644 --- a/zh/AIPyApp/index.html +++ b/zh/AIPyApp/index.html @@ -626,6 +626,34 @@ + + + + + + +
    818. + + + + + + + + 精选课程 + + + + + + + + +
    819. + + + + diff --git a/zh/GraphicalInterface/index.html b/zh/GraphicalInterface/index.html index e6d50ae..8a82feb 100644 --- a/zh/GraphicalInterface/index.html +++ b/zh/GraphicalInterface/index.html @@ -626,6 +626,34 @@ + + + + + + +
    820. + + + + + + + + 精选课程 + + + + + + + + +
    821. + + + + diff --git a/zh/Notebook/index.html b/zh/Notebook/index.html index 2e50b3b..83eee8a 100644 --- a/zh/Notebook/index.html +++ b/zh/Notebook/index.html @@ -626,6 +626,34 @@ + + + + + + +
    822. + + + + + + + + 精选课程 + + + + + + + + +
    823. + + + + diff --git a/zh/Ollama/index.html b/zh/Ollama/index.html index a8c14ed..75f0aaf 100644 --- a/zh/Ollama/index.html +++ b/zh/Ollama/index.html @@ -626,6 +626,34 @@ + + + + + + +
    824. + + + + + + + + 精选课程 + + + + + + + + +
    825. + + + + diff --git a/zh/Terminal/index.html b/zh/Terminal/index.html index 221dade..597b91b 100644 --- a/zh/Terminal/index.html +++ b/zh/Terminal/index.html @@ -13,7 +13,7 @@ - + @@ -626,6 +626,34 @@ + + + + + + +
    826. + + + + + + + + 精选课程 + + + + + + + + +
    827. + + + + diff --git a/zh/community/index.html b/zh/community/index.html index 2493897..00c3f00 100644 --- a/zh/community/index.html +++ b/zh/community/index.html @@ -624,6 +624,34 @@ + + + + + + +
    828. + + + + + + + + 精选课程 + + + + + + + + +
    829. + + + + diff --git a/zh/editor-guide/index.html b/zh/editor-guide/index.html index a73ecbd..f4427b1 100644 --- a/zh/editor-guide/index.html +++ b/zh/editor-guide/index.html @@ -626,6 +626,34 @@ + + + + + + +
    830. + + + + + + + + 精选课程 + + + + + + + + +
    831. + + + + diff --git a/zh/external-api/index.html b/zh/external-api/index.html index 413168b..86fd7ad 100644 --- a/zh/external-api/index.html +++ b/zh/external-api/index.html @@ -626,6 +626,34 @@ + + + + + + +
    832. + + + + + + + + 精选课程 + + + + + + + + +
    833. + + + + diff --git a/zh/featured-courses/index.html b/zh/featured-courses/index.html new file mode 100644 index 0000000..0981544 --- /dev/null +++ b/zh/featured-courses/index.html @@ -0,0 +1,2863 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 精选课程 - QPython + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + +
      + + + + +
      + + +
      + +
      + + + + + + + + + +
      +
      + + + +
      +
      +
      + + + + + + + +
      +
      +
      + + + +
      +
      +
      + + + +
      +
      +
      + + + +
      + +
      + + + + + +

      精选课程

      +

      在这里,我们为您介绍一些由社区成员创建的精品课程。每一门课程都凝聚了创作者的心血和独特见解,希望能为您的学习之旅带来启发和帮助。

      +

      与AI协作的Python编程入门 - AIPY编程系列

      +

      与AI协作的Python编程入门

      +

      课程简介: 你是否觉得编程很难?在 AI 时代,这一切正在改变。本课程将带你掌握 Python 编程基础,同时学会与 AI 高效协作。独创 AI 辅助教学法,系统讲解 Python 核心知识,教会你如何向 AI 精确表达需求、协同调试代码。通过聊天机器人、数据分析助手等实战项目,建立人机协作工作流,让你彻底打破对代码的畏惧。

      +

      创作故事: 这门课是如何诞生的?以下是作者的创作手记:

      + +
      +

      欢迎反馈

      +

      如果您有想法想要分享,欢迎联系我们!

      + + + + + + + + + + + + + + + + +
      +
      + + + +
      + +
      + +
      + + +
      + +
      +
      +
      +
      + + + + + + + + + + + + + \ No newline at end of file diff --git a/zh/getting-started/index.html b/zh/getting-started/index.html index ca26f63..926ceab 100644 --- a/zh/getting-started/index.html +++ b/zh/getting-started/index.html @@ -954,6 +954,34 @@ + + + + + + +
    834. + + + + + + + + 精选课程 + + + + + + + + +
    835. + + + + diff --git a/zh/index.html b/zh/index.html index 550882c..01643ab 100644 --- a/zh/index.html +++ b/zh/index.html @@ -740,6 +740,34 @@ + + + + + + +
    836. + + + + + + + + 精选课程 + + + + + + + + +
    837. + + + + @@ -2810,6 +2838,7 @@

      快速开始

      编程指南

      QPython 不仅提供基础的 Python 接口支持,更重要的是,它还允许您通过 QSL4A 接口使用 Python 调用 Android API。

      diff --git a/zh/qpypi-guide/index.html b/zh/qpypi-guide/index.html index 2e0454e..4474b87 100644 --- a/zh/qpypi-guide/index.html +++ b/zh/qpypi-guide/index.html @@ -626,6 +626,34 @@ + + + + + + +
    838. + + + + + + + + 精选课程 + + + + + + + + +
    839. + + + + diff --git a/zh/qpython-x/index.html b/zh/qpython-x/index.html index 676b86c..e37d97e 100644 --- a/zh/qpython-x/index.html +++ b/zh/qpython-x/index.html @@ -709,6 +709,34 @@ + + + + + + +
    840. + + + + + + + + 精选课程 + + + + + + + + +
    841. + + + + diff --git a/zh/qsl4a/connectivity/contacts/index.html b/zh/qsl4a/connectivity/contacts/index.html index 51b617a..9b7a940 100644 --- a/zh/qsl4a/connectivity/contacts/index.html +++ b/zh/qsl4a/connectivity/contacts/index.html @@ -626,6 +626,34 @@ + + + + + + +
    842. + + + + + + + + 精选课程 + + + + + + + + +
    843. + + + + diff --git a/zh/qsl4a/connectivity/ftp/index.html b/zh/qsl4a/connectivity/ftp/index.html index 0b85a44..dcb9214 100644 --- a/zh/qsl4a/connectivity/ftp/index.html +++ b/zh/qsl4a/connectivity/ftp/index.html @@ -626,6 +626,34 @@ + + + + + + +
    844. + + + + + + + + 精选课程 + + + + + + + + +
    845. + + + + diff --git a/zh/qsl4a/connectivity/location/index.html b/zh/qsl4a/connectivity/location/index.html index 5a291d8..e4b0b29 100644 --- a/zh/qsl4a/connectivity/location/index.html +++ b/zh/qsl4a/connectivity/location/index.html @@ -626,6 +626,34 @@ + + + + + + +
    846. + + + + + + + + 精选课程 + + + + + + + + +
    847. + + + + diff --git a/zh/qsl4a/connectivity/phone/index.html b/zh/qsl4a/connectivity/phone/index.html index 4b8ad9f..14d226d 100644 --- a/zh/qsl4a/connectivity/phone/index.html +++ b/zh/qsl4a/connectivity/phone/index.html @@ -626,6 +626,34 @@ + + + + + + +
    848. + + + + + + + + 精选课程 + + + + + + + + +
    849. + + + + diff --git a/zh/qsl4a/connectivity/signalstrength/index.html b/zh/qsl4a/connectivity/signalstrength/index.html index 9c328a2..86b611f 100644 --- a/zh/qsl4a/connectivity/signalstrength/index.html +++ b/zh/qsl4a/connectivity/signalstrength/index.html @@ -626,6 +626,34 @@ + + + + + + +
    850. + + + + + + + + 精选课程 + + + + + + + + +
    851. + + + + diff --git a/zh/qsl4a/connectivity/sms/index.html b/zh/qsl4a/connectivity/sms/index.html index bb11a6c..780df34 100644 --- a/zh/qsl4a/connectivity/sms/index.html +++ b/zh/qsl4a/connectivity/sms/index.html @@ -626,6 +626,34 @@ + + + + + + +
    852. + + + + + + + + 精选课程 + + + + + + + + +
    853. + + + + diff --git a/zh/qsl4a/connectivity/wifi/index.html b/zh/qsl4a/connectivity/wifi/index.html index 059a98d..0170117 100644 --- a/zh/qsl4a/connectivity/wifi/index.html +++ b/zh/qsl4a/connectivity/wifi/index.html @@ -626,6 +626,34 @@ + + + + + + +
    854. + + + + + + + + 精选课程 + + + + + + + + +
    855. + + + + diff --git a/zh/qsl4a/core/android-base/index.html b/zh/qsl4a/core/android-base/index.html index 3b4159a..796f476 100644 --- a/zh/qsl4a/core/android-base/index.html +++ b/zh/qsl4a/core/android-base/index.html @@ -626,6 +626,34 @@ + + + + + + +
    856. + + + + + + + + 精选课程 + + + + + + + + +
    857. + + + + diff --git a/zh/qsl4a/core/events/index.html b/zh/qsl4a/core/events/index.html index 0276e2d..4506d2e 100644 --- a/zh/qsl4a/core/events/index.html +++ b/zh/qsl4a/core/events/index.html @@ -626,6 +626,34 @@ + + + + + + +
    858. + + + + + + + + 精选课程 + + + + + + + + +
    859. + + + + diff --git a/zh/qsl4a/core/intent/index.html b/zh/qsl4a/core/intent/index.html index 5529285..2d99197 100644 --- a/zh/qsl4a/core/intent/index.html +++ b/zh/qsl4a/core/intent/index.html @@ -626,6 +626,34 @@ + + + + + + +
    860. + + + + + + + + 精选课程 + + + + + + + + +
    861. + + + + diff --git a/zh/qsl4a/hardware/bluetooth/index.html b/zh/qsl4a/hardware/bluetooth/index.html index 083f899..2791180 100644 --- a/zh/qsl4a/hardware/bluetooth/index.html +++ b/zh/qsl4a/hardware/bluetooth/index.html @@ -626,6 +626,34 @@ + + + + + + +
    862. + + + + + + + + 精选课程 + + + + + + + + +
    863. + + + + diff --git a/zh/qsl4a/hardware/camera/index.html b/zh/qsl4a/hardware/camera/index.html index ee45883..af30047 100644 --- a/zh/qsl4a/hardware/camera/index.html +++ b/zh/qsl4a/hardware/camera/index.html @@ -626,6 +626,34 @@ + + + + + + +
    864. + + + + + + + + 精选课程 + + + + + + + + +
    865. + + + + diff --git a/zh/qsl4a/hardware/recorder/index.html b/zh/qsl4a/hardware/recorder/index.html index 5be2c28..0cd1b58 100644 --- a/zh/qsl4a/hardware/recorder/index.html +++ b/zh/qsl4a/hardware/recorder/index.html @@ -626,6 +626,34 @@ + + + + + + +
    866. + + + + + + + + 精选课程 + + + + + + + + +
    867. + + + + diff --git a/zh/qsl4a/hardware/usbserial/index.html b/zh/qsl4a/hardware/usbserial/index.html index 4d83ee8..68476a0 100644 --- a/zh/qsl4a/hardware/usbserial/index.html +++ b/zh/qsl4a/hardware/usbserial/index.html @@ -626,6 +626,34 @@ + + + + + + +
    868. + + + + + + + + 精选课程 + + + + + + + + +
    869. + + + + diff --git a/zh/qsl4a/hardware/webcam/index.html b/zh/qsl4a/hardware/webcam/index.html index 468abc6..b2461c9 100644 --- a/zh/qsl4a/hardware/webcam/index.html +++ b/zh/qsl4a/hardware/webcam/index.html @@ -626,6 +626,34 @@ + + + + + + +
    870. + + + + + + + + 精选课程 + + + + + + + + +
    871. + + + + diff --git a/zh/qsl4a/index.html b/zh/qsl4a/index.html index 11de42b..7d42438 100644 --- a/zh/qsl4a/index.html +++ b/zh/qsl4a/index.html @@ -626,6 +626,34 @@ + + + + + + +
    872. + + + + + + + + 精选课程 + + + + + + + + +
    873. + + + + diff --git a/zh/qsl4a/media/image/index.html b/zh/qsl4a/media/image/index.html index b0ddef7..ef894d8 100644 --- a/zh/qsl4a/media/image/index.html +++ b/zh/qsl4a/media/image/index.html @@ -626,6 +626,34 @@ + + + + + + +
    874. + + + + + + + + 精选课程 + + + + + + + + +
    875. + + + + diff --git a/zh/qsl4a/media/mediaplayer/index.html b/zh/qsl4a/media/mediaplayer/index.html index 838404e..55813c2 100644 --- a/zh/qsl4a/media/mediaplayer/index.html +++ b/zh/qsl4a/media/mediaplayer/index.html @@ -626,6 +626,34 @@ + + + + + + +
    876. + + + + + + + + 精选课程 + + + + + + + + +
    877. + + + + diff --git a/zh/qsl4a/special/cipher/index.html b/zh/qsl4a/special/cipher/index.html index 4bda4e9..933eaae 100644 --- a/zh/qsl4a/special/cipher/index.html +++ b/zh/qsl4a/special/cipher/index.html @@ -626,6 +626,34 @@ + + + + + + +
    878. + + + + + + + + 精选课程 + + + + + + + + +
    879. + + + + diff --git a/zh/qsl4a/special/pgptai/index.html b/zh/qsl4a/special/pgptai/index.html index ab9d129..2304149 100644 --- a/zh/qsl4a/special/pgptai/index.html +++ b/zh/qsl4a/special/pgptai/index.html @@ -626,6 +626,34 @@ + + + + + + +
    880. + + + + + + + + 精选课程 + + + + + + + + +
    881. + + + + diff --git a/zh/qsl4a/storage/clipboard/index.html b/zh/qsl4a/storage/clipboard/index.html index e8cc0e8..4c2e5ab 100644 --- a/zh/qsl4a/storage/clipboard/index.html +++ b/zh/qsl4a/storage/clipboard/index.html @@ -626,6 +626,34 @@ + + + + + + +
    882. + + + + + + + + 精选课程 + + + + + + + + +
    883. + + + + diff --git a/zh/qsl4a/storage/documentfile/index.html b/zh/qsl4a/storage/documentfile/index.html index 1982da7..314031a 100644 --- a/zh/qsl4a/storage/documentfile/index.html +++ b/zh/qsl4a/storage/documentfile/index.html @@ -626,6 +626,34 @@ + + + + + + +
    884. + + + + + + + + 精选课程 + + + + + + + + +
    885. + + + + diff --git a/zh/qsl4a/storage/preferences/index.html b/zh/qsl4a/storage/preferences/index.html index 8e319ca..8b0b6b8 100644 --- a/zh/qsl4a/storage/preferences/index.html +++ b/zh/qsl4a/storage/preferences/index.html @@ -626,6 +626,34 @@ + + + + + + +
    886. + + + + + + + + 精选课程 + + + + + + + + +
    887. + + + + diff --git a/zh/qsl4a/system/activityresult/index.html b/zh/qsl4a/system/activityresult/index.html index 6e8e370..58e0bc5 100644 --- a/zh/qsl4a/system/activityresult/index.html +++ b/zh/qsl4a/system/activityresult/index.html @@ -626,6 +626,34 @@ + + + + + + +
    888. + + + + + + + + 精选课程 + + + + + + + + +
    889. + + + + diff --git a/zh/qsl4a/system/application/index.html b/zh/qsl4a/system/application/index.html index 050ec91..13216c4 100644 --- a/zh/qsl4a/system/application/index.html +++ b/zh/qsl4a/system/application/index.html @@ -626,6 +626,34 @@ + + + + + + +
    890. + + + + + + + + 精选课程 + + + + + + + + +
    891. + + + + diff --git a/zh/qsl4a/system/battery/index.html b/zh/qsl4a/system/battery/index.html index b9d31bb..e9728aa 100644 --- a/zh/qsl4a/system/battery/index.html +++ b/zh/qsl4a/system/battery/index.html @@ -626,6 +626,34 @@ + + + + + + +
    892. + + + + + + + + 精选课程 + + + + + + + + +
    893. + + + + diff --git a/zh/qsl4a/system/qpyinterface/index.html b/zh/qsl4a/system/qpyinterface/index.html index 68268aa..f6646df 100644 --- a/zh/qsl4a/system/qpyinterface/index.html +++ b/zh/qsl4a/system/qpyinterface/index.html @@ -626,6 +626,34 @@ + + + + + + +
    894. + + + + + + + + 精选课程 + + + + + + + + +
    895. + + + + diff --git a/zh/qsl4a/system/sensors/index.html b/zh/qsl4a/system/sensors/index.html index 361fe62..4b1f577 100644 --- a/zh/qsl4a/system/sensors/index.html +++ b/zh/qsl4a/system/sensors/index.html @@ -626,6 +626,34 @@ + + + + + + +
    896. + + + + + + + + 精选课程 + + + + + + + + +
    897. + + + + diff --git a/zh/qsl4a/system/settings/index.html b/zh/qsl4a/system/settings/index.html index 5a0f240..17734ff 100644 --- a/zh/qsl4a/system/settings/index.html +++ b/zh/qsl4a/system/settings/index.html @@ -626,6 +626,34 @@ + + + + + + +
    898. + + + + + + + + 精选课程 + + + + + + + + +
    899. + + + + diff --git a/zh/qsl4a/system/sysinfo/index.html b/zh/qsl4a/system/sysinfo/index.html index 514bd28..780d6cb 100644 --- a/zh/qsl4a/system/sysinfo/index.html +++ b/zh/qsl4a/system/sysinfo/index.html @@ -626,6 +626,34 @@ + + + + + + +
    900. + + + + + + + + 精选课程 + + + + + + + + +
    901. + + + + diff --git a/zh/qsl4a/system/wakelock/index.html b/zh/qsl4a/system/wakelock/index.html index 5f7c612..b820e80 100644 --- a/zh/qsl4a/system/wakelock/index.html +++ b/zh/qsl4a/system/wakelock/index.html @@ -626,6 +626,34 @@ + + + + + + +
    902. + + + + + + + + 精选课程 + + + + + + + + +
    903. + + + + diff --git a/zh/qsl4a/ui/accessibility/index.html b/zh/qsl4a/ui/accessibility/index.html index b72f708..0c247be 100644 --- a/zh/qsl4a/ui/accessibility/index.html +++ b/zh/qsl4a/ui/accessibility/index.html @@ -626,6 +626,34 @@ + + + + + + +
    904. + + + + + + + + 精选课程 + + + + + + + + +
    905. + + + + diff --git a/zh/qsl4a/ui/dialogs/index.html b/zh/qsl4a/ui/dialogs/index.html index 9bb74b9..02b2861 100644 --- a/zh/qsl4a/ui/dialogs/index.html +++ b/zh/qsl4a/ui/dialogs/index.html @@ -626,6 +626,34 @@ + + + + + + +
    906. + + + + + + + + 精选课程 + + + + + + + + +
    907. + + + + diff --git a/zh/qsl4a/ui/floatview/index.html b/zh/qsl4a/ui/floatview/index.html index f30aa7a..58a3c5f 100644 --- a/zh/qsl4a/ui/floatview/index.html +++ b/zh/qsl4a/ui/floatview/index.html @@ -626,6 +626,34 @@ + + + + + + +
    908. + + + + + + + + 精选课程 + + + + + + + + +
    909. + + + + diff --git a/zh/qsl4a/ui/fullscreen/index.html b/zh/qsl4a/ui/fullscreen/index.html index 14f74e7..5ef2b8a 100644 --- a/zh/qsl4a/ui/fullscreen/index.html +++ b/zh/qsl4a/ui/fullscreen/index.html @@ -626,6 +626,34 @@ + + + + + + +
    910. + + + + + + + + 精选课程 + + + + + + + + +
    911. + + + + diff --git a/zh/search/search_index.json b/zh/search/search_index.json index 2b7a4f7..695d667 100644 --- a/zh/search/search_index.json +++ b/zh/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"QPython \u9879\u76ee","text":"

      QPython \u4e0d\u4ec5\u662f\u4e00\u4e2a\u5f3a\u5927\u7684 Android Python IDE\uff0c\u4e5f\u662f\u4e00\u4e2a\u6d3b\u8dc3\u7684\u6280\u672f\u793e\u533a\u3002

      "},{"location":"#ai-android-python-ide","title":"\u652f\u6301 AI \u7684 Android Python IDE","text":"

      QPython \u662f\u60a8\u8fdb\u884c Android Python \u7f16\u7a0b\u7684\u5165\u53e3\u3002\u5b83\u96c6\u6210\u4e86 Python \u89e3\u91ca\u5668\u3001AI \u6a21\u578b\u5f15\u64ce\u548c\u79fb\u52a8\u5f00\u53d1\u5de5\u5177\u94fe\uff0c\u8ba9\u60a8\u80fd\u591f\u4ece\u79fb\u52a8\u8bbe\u5907\u6784\u5efa Web \u5e94\u7528\u7a0b\u5e8f\u3001\u6267\u884c\u79d1\u5b66\u8ba1\u7b97\u548c\u521b\u5efa\u667a\u80fd\u5e94\u7528\u3002

      \u65e0\u8bba\u60a8\u662f\u5728\u5b66\u4e60\u7f16\u7a0b\u3001\u6784\u5efa\u6570\u636e\u79d1\u5b66\u9879\u76ee\uff0c\u8fd8\u662f\u5f00\u53d1 AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f\uff0cQPython \u90fd\u63d0\u4f9b\u4e86\u5b8c\u6574\u7684\u79fb\u52a8\u7f16\u7a0b\u89e3\u51b3\u65b9\u6848\uff0c\u62e5\u6709\u5168\u9762\u7684\u5f00\u53d1\u8005\u8d44\u6e90\u548c\u6d3b\u8dc3\u7684\u793e\u533a\u6765\u652f\u6301\u60a8\u7684\u65c5\u7a0b\u3002

      • \u5206\u652f\u7248\u672c \u2013 \u4e86\u89e3\u4e0d\u540c\u7684 QPython \u7248\u672c\uff08IDE\u3001\u793e\u533a\u7248\u3001Plus\uff09\uff0c\u9009\u62e9\u9002\u5408\u60a8\u9700\u6c42\u7684\u7248\u672c
      • \u66f4\u65b0\u65e5\u5fd7 \u2013 \u968f\u65f6\u4e86\u89e3\u6700\u65b0\u529f\u80fd\u3001\u6539\u8fdb\u548c\u53d1\u884c\u8bf4\u660e
      "},{"location":"#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"

      \u5982\u4f55\u5feb\u901f\u5165\u95e8\uff1f\u8bf7\u6309\u7167\u4ee5\u4e0b\u6b65\u9aa4\uff1a

      • \u5feb\u901f\u5165\u95e8
      • Hello World \u6559\u7a0b
      "},{"location":"#_2","title":"\u7f16\u7a0b\u6307\u5357","text":"

      QPython \u4e0d\u4ec5\u63d0\u4f9b\u57fa\u7840\u7684 Python \u63a5\u53e3\u652f\u6301\uff0c\u66f4\u91cd\u8981\u7684\u662f\uff0c\u5b83\u8fd8\u5141\u8bb8\u60a8\u901a\u8fc7 QSL4A \u63a5\u53e3\u4f7f\u7528 Python \u8c03\u7528 Android API\u3002

      • Python \u6807\u51c6\u5e93 \u2013 \u901a\u7528\u7684 Python \u8bed\u6cd5\u548c\u5185\u7f6e\u5e93
      • QSL4A API \u2013 \u4ece Python \u8bbf\u95ee Android \u8bbe\u5907\u529f\u80fd\uff08\u76f8\u673a\u3001\u4f20\u611f\u5668\u3001\u77ed\u4fe1\u7b49\uff09
      • QPYPI \u6307\u5357 \u2013 \u5b89\u88c5\u989d\u5916\u7684 Python \u5305
      • \u7f16\u8f91\u5668\u6307\u5357 \u2013 \u4f7f\u7528\u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668
      • \u5916\u90e8 API \u2013 \u4e0e\u5916\u90e8\u5e94\u7528\u7a0b\u5e8f\u96c6\u6210
      "},{"location":"#_3","title":"\u4e0b\u8f7d\u8d44\u6e90","text":"
      • Google Drive
      • \u5fae\u4fe1\u7f51\u76d8
      "},{"location":"#_4","title":"\u793e\u533a\u4e0e\u53cd\u9988","text":"
      • \u4e2d\u6587\u4ea4\u6d41\u793e\u533a
      • \u95ee\u9898\u53cd\u9988
      • \u529f\u80fd\u6269\u5c55\u8bf7\u6c42
      "},{"location":"#_5","title":"\u5173\u6ce8\u6211\u4eec","text":"
      • B\u7ad9
      • Weibo
      "},{"location":"AIPyApp/","title":"AIPyApp - AI\u9a71\u52a8\u7684\u7a0b\u5e8f\u751f\u6210\u5668","text":"

      AIPyApp \u662f QPython \u4e2d\u7684\u667a\u80fd\u5de5\u5177\uff0c\u53ef\u4ee5\u5229\u7528 AI \u4ece\u81ea\u7136\u8bed\u8a00\u6307\u4ee4\u81ea\u52a8\u751f\u6210 Python \u7a0b\u5e8f\u3002

      "},{"location":"AIPyApp/#_1","title":"\u6982\u8ff0","text":"

      AIPyApp \u6539\u53d8\u4e86\u60a8\u7f16\u5199\u4ee3\u7801\u7684\u65b9\u5f0f\u2014\u2014\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u63cf\u8ff0\u60a8\u60f3\u8981\u7684\u529f\u80fd\uff0cAI \u5c31\u4f1a\u4e3a\u60a8\u751f\u6210 Python \u7a0b\u5e8f\u3002QPython \u8fd8\u5c06\u63a8\u51fa AIPy Academy\u2014\u2014\u4e00\u4e2a\u4e3a AI \u65f6\u4ee3\u91cf\u8eab\u5b9a\u5236\u7684 Python \u7f16\u7a0b\u8bfe\u7a0b\u5e73\u53f0\u3002

      "},{"location":"AIPyApp/#_2","title":"\u5b89\u88c5","text":"

      QPython \u6c1b\u56f4\u7f16\u7a0b\uff08Vibe Coding\uff09 01 - \u5982\u4f55\u542f\u7528AIPyApp

      "},{"location":"AIPyApp/#_3","title":"\u7b2c\u4e00\u6b65\uff1a\u4ece\u4eea\u8868\u76d8\u542f\u52a8","text":"
      1. \u6253\u5f00 QPython\uff0c\u8fdb\u5165 \u4eea\u8868\u76d8
      2. \u957f\u6309\u5f00\u59cb\u6309\u94ae

      \u5982\u679c\u672a\u5b89\u88c5 AIPyApp\uff0c\u7cfb\u7edf\u4f1a\u63d0\u793a\u60a8\u786e\u8ba4\u5b89\u88c5\u3002\u6309 \u56de\u8f66\u952e\u7ee7\u7eed\u3002

      QPython \u5c06\u81ea\u52a8\u4ece PYPI \u4e0b\u8f7d\u5e76\u5b89\u88c5\u6240\u9700\u7684\u4f9d\u8d56\u9879\u3002\u8bf7\u8010\u5fc3\u7b49\u5f85\u5b89\u88c5\u5b8c\u6210\u3002

      "},{"location":"AIPyApp/#aipyapp","title":"\u7b2c\u4e8c\u6b65\uff1a\u91cd\u65b0\u542f\u52a8 AIPyApp","text":"

      \u5b89\u88c5\u5b8c\u6210\u540e\uff0c\u8fd4\u56de QPython \u4eea\u8868\u76d8\uff0c\u518d\u6b21 \u957f\u6309\u5f00\u59cb\u6309\u94ae\u542f\u52a8 AIPyApp\u3002

      "},{"location":"AIPyApp/#_4","title":"\u914d\u7f6e","text":""},{"location":"AIPyApp/#ai","title":"\u8bbe\u7f6e\u60a8\u7684 AI \u5bc6\u94a5","text":"

      \u9996\u6b21\u542f\u52a8\u65f6\uff0c\u60a8\u9700\u8981\u63d0\u4f9b AI API \u5bc6\u94a5\uff1a

      1. \u5728 PGPT \u6ce8\u518c\uff1a\u5728 https://user.pgpt.cloud \u521b\u5efa\u8d26\u6237\u4ee5\u751f\u6210\u60a8\u7684 AI \u5bc6\u94a5
      2. \u9ad8\u7ea7\u9009\u9879\uff1aAIPyApp \u8fd8\u652f\u6301\u6765\u81ea OpenAI\u3001Deepseek \u548c\u5176\u4ed6\u63d0\u4f9b\u5546\u7684\u81ea\u5b9a\u4e49 AI \u5bc6\u94a5\uff08\u8be6\u89c1\u9ad8\u7ea7\u6559\u7a0b\uff09
      "},{"location":"AIPyApp/#ai_1","title":"\u8f93\u5165\u60a8\u7684 AI \u5bc6\u94a5","text":"
      1. \u957f\u6309\u8f93\u5165\u63d0\u793a
      2. \u4ece\u5f39\u51fa\u83dc\u5355\u4e2d\u9009\u62e9 \u7c98\u8d34
      3. \u6309 \u56de\u8f66\u952e\u786e\u8ba4

      \u60a8\u7684 AI \u5bc6\u94a5\u5c06\u4fdd\u5b58\u4ee5\u4f9b\u540e\u7eed\u4f1a\u8bdd\u4f7f\u7528\u3002

      "},{"location":"AIPyApp/#aipyapp_1","title":"\u4f7f\u7528 AIPyApp","text":"

      \u914d\u7f6e\u5b8c\u6210\u540e\uff0c\u60a8\u5c06\u8fdb\u5165 AIPyApp \u63a7\u5236\u53f0\u6a21\u5f0f\u3002\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u8f93\u5165\u60a8\u7684\u6307\u4ee4\u5373\u53ef\uff01

      "},{"location":"AIPyApp/#_5","title":"\u793a\u4f8b\u547d\u4ee4","text":"

      \u5c1d\u8bd5\u8f93\u5165\uff1a

      \u4f7f\u7528 QSL4A \u521b\u5efa\u4e00\u4e2a HELLO QPY \u7a0b\u5e8f\u4f5c\u4e3a\u6f14\u793a\n

      AIPyApp \u5c06\uff1a 1. \u7406\u89e3\u60a8\u7684\u81ea\u7136\u8bed\u8a00\u8bf7\u6c42 2. \u751f\u6210\u76f8\u5e94\u7684 Python \u4ee3\u7801 3. \u81ea\u52a8\u6267\u884c\u7a0b\u5e8f

      \u5c31\u662f\u8fd9\u6837\u2014\u2014\u60a8\u65e0\u9700\u7f16\u5199\u4efb\u4f55\u4ee3\u7801\u5c31\u521b\u5efa\u4e86\u4e00\u4e2a\u53ef\u8fd0\u884c\u7684 Python \u7a0b\u5e8f\uff01

      "},{"location":"AIPyApp/#_6","title":"\u6f14\u793a\u89c6\u9891","text":"

      QPython \u6c1b\u56f4\u7f16\u7a0b\uff08Vibe Coding\uff09 02 - \u4f7f\u7528\u81ea\u7136\u8bed\u8a00\u5f00\u53d1\u4e00\u4e2a\u7ffb\u8bd1App

      \u4e0a\u9762\u7684\u793a\u4f8b\u6f14\u793a\u4e86 AIPyApp \u5982\u4f55\uff1a - \u7406\u89e3\u4e2d\u6587\u6307\u4ee4 - \u751f\u6210\u57fa\u4e8e QSL4A \u7684 Python \u4ee3\u7801 - \u7acb\u5373\u8fd0\u884c\u7a0b\u5e8f

      \u63a2\u7d22 AIPyApp \u4ee5\u53d1\u73b0\u66f4\u591a\u529f\u80fd\uff0c\u5f00\u59cb\u8f7b\u677e\u6784\u5efa Python \u7a0b\u5e8f\u3002

      "},{"location":"AIPyApp/#_7","title":"\u8bfe\u7a0b\u63a8\u8350","text":"

      \u672b\u5c3e\uff0c\u7ed9\u5927\u5bb6\u63a8\u8350\u4e0b\u9762\u8bfe\u7a0b\uff1a

      \u300a\u4e0eAI\u534f\u4f5c\u7684Python\u7f16\u7a0b\u5165\u95e8\u300b \u2014 \u7531QPython\u5b98\u65b9\u56e2\u961f\u7cbe\u5fc3\u6253\u9020\u5e76\u63d0\u4f9b\u6559\u5b66\u652f\u6301\uff0c\u80fd\u5e2e\u52a9\u5b66\u4e60\u8005\u5feb\u901f\u3001\u4f53\u7cfb\u5316\u5730\u638c\u63e1Python\u5f00\u53d1\u4ee5\u53ca\u5728AI\u65f6\u4ee3\u66f4\u597d\u5730\u5b66\u4e60\u4f7f\u7528AI\u3002

      \u4e86\u89e3\u8be6\u60c5

      "},{"location":"GraphicalInterface/","title":"\u56fe\u5f62\u754c\u9762\uff08Turtle \u548c Tkinter\uff09","text":"

      \u672c\u6307\u5357\u8bf4\u660e\u5982\u4f55\u5728 Android \u8bbe\u5907\u4e0a\u7684 QPython \u4e2d\u542f\u7528\u56fe\u5f62\u754c\u9762\u652f\u6301\uff08Turtle \u548c Tkinter\uff09\u3002

      "},{"location":"GraphicalInterface/#_1","title":"\u6982\u8ff0","text":"

      QPython \u53ef\u4ee5\u8fd0\u884c Turtle \u548c Tkinter \u5e94\u7528\u7a0b\u5e8f\uff0c\u4f46\u9700\u8981\u989d\u5916\u7684\u8f6f\u4ef6\u6765\u5728 Android \u4e0a\u63d0\u4f9b\u56fe\u5f62\u663e\u793a\u652f\u6301\u3002

      "},{"location":"GraphicalInterface/#_2","title":"\u524d\u63d0\u6761\u4ef6","text":"

      \u5f00\u59cb\u4e4b\u524d\uff0c\u60a8\u9700\u8981\u4e0b\u8f7d\u4ee5\u4e0b\u8d44\u6e90\uff1a

      1. Xserver.apk - \u63d0\u4f9b Turtle/Tkinter \u56fe\u5f62\u652f\u6301\u7684\u914d\u5957\u5e94\u7528
      2. \u4e0b\u8f7d\u5730\u5740\uff1aQPythonProject/Extra on Google Drive
      3. Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762\u6269\u5c55 - \u901a\u8fc7 QPython \u7684 QPYPI \u5b89\u88c5
      "},{"location":"GraphicalInterface/#_3","title":"\u5b89\u88c5\u6b65\u9aa4","text":""},{"location":"GraphicalInterface/#xserver","title":"\u7b2c\u4e00\u6b65\uff1a\u5b89\u88c5 Xserver","text":"

      \u4ece Google Drive \u7684 QPython Extra \u8d44\u6e90\u76ee\u5f55\u4e0b\u8f7d\u5e76\u5b89\u88c5 Xserver.apk\u3002

      "},{"location":"GraphicalInterface/#qpython","title":"\u7b2c\u4e8c\u6b65\uff1a\u5b89\u88c5 QPython \u6269\u5c55","text":"

      \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI\u3002\u627e\u5230\u5e76\u5b89\u88c5 Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762 \u6269\u5c55\u3002

      "},{"location":"GraphicalInterface/#xserver_1","title":"\u7b2c\u4e09\u6b65\uff1a\u914d\u7f6e Xserver \u7535\u6c60\u8bbe\u7f6e","text":"

      \u4e3a\u9632\u6b62 Xserver \u5728\u540e\u53f0\u8fd0\u884c\u65f6\u88ab\u6740\u6b7b\uff1a

      1. \u8fdb\u5165\u8bbe\u5907\u7684 \u8bbe\u7f6e > \u5e94\u7528 > Xserver
      2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
      3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u6216 \"\u4e0d\u9650\u5236\"

      \u8fd9\u53ef\u786e\u4fdd Xserver \u5728\u5207\u6362\u5230\u540e\u53f0\u65f6\u7ee7\u7eed\u8fd0\u884c\u3002

      "},{"location":"GraphicalInterface/#qpython_1","title":"\u7b2c\u56db\u6b65\uff1a\u914d\u7f6e QPython \u7535\u6c60\u8bbe\u7f6e\uff08\u63a8\u8350\uff09","text":"

      \u540c\u6837\uff0c\u5c06 QPython \u7684\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u4ee5\u9632\u6b62\u8fdb\u7a0b\u88ab\u7ec8\u6b62\uff1a

      1. \u8fdb\u5165 \u8bbe\u7f6e > \u5e94\u7528 > QPython
      2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
      3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\"
      "},{"location":"GraphicalInterface/#xserver_2","title":"\u7b2c\u4e94\u6b65\uff1a\u542f\u52a8 Xserver","text":"

      \u5728\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d\uff0c\u542f\u52a8 Xserver \u5e94\u7528\u5e76\u5c06\u5176\u5207\u6362\u4e3a\u540e\u53f0\u8fd0\u884c\u3002

      "},{"location":"GraphicalInterface/#turtletkinter","title":"\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f","text":"

      \u5b8c\u6210\u8bbe\u7f6e\u540e\uff1a

      1. \u786e\u4fdd Xserver \u5728\u540e\u53f0\u8fd0\u884c
      2. \u5728 QPython \u4e2d\u8fd0\u884c\u60a8\u7684 Turtle \u6216 Tkinter \u5e94\u7528\u7a0b\u5e8f
      3. \u5207\u6362\u5230 Xserver \u67e5\u770b\u56fe\u5f62\u8f93\u51fa
      "},{"location":"GraphicalInterface/#_4","title":"\u6f14\u793a\u7a0b\u5e8f","text":"

      \u60a8\u53ef\u4ee5\u4ece QPython \u5e94\u7528\u7684 QPYPI \u7b2c\u4e00\u4e2a\u6269\u5c55\u90e8\u5206\u4e0b\u8f7d\u5e76\u5c1d\u8bd5 Turtle \u753b\u54c6\u5566A\u68a6 \u6f14\u793a\u7a0b\u5e8f\u6765\u9a8c\u8bc1\u60a8\u7684\u8bbe\u7f6e\u3002

      "},{"location":"GraphicalInterface/#_5","title":"\u6f14\u793a\u89c6\u9891","text":""},{"location":"GraphicalInterface/#_6","title":"\u6545\u969c\u6392\u9664","text":"
      • \u9ed1\u5c4f\uff1a\u786e\u4fdd\u5728\u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d Xserver \u6b63\u5728\u8fd0\u884c
      • \u5e94\u7528\u7a0b\u5e8f\u5d29\u6e83\uff1a\u68c0\u67e5 QPython \u548c Xserver \u662f\u5426\u90fd\u8bbe\u7f6e\u4e86\u65e0\u9650\u5236\u7684\u7535\u6c60\u8bbe\u7f6e
      • \u65e0\u663e\u793a\uff1a\u9a8c\u8bc1 Turtle/Tkinter \u6269\u5c55\u662f\u5426\u901a\u8fc7 QPYPI \u6b63\u786e\u5b89\u88c5
      "},{"location":"GraphicalInterface/#_7","title":"\u8bfe\u7a0b\u63a8\u8350","text":"

      \u672b\u5c3e\uff0c\u7ed9\u5927\u5bb6\u63a8\u8350\u4e0b\u9762\u8bfe\u7a0b\uff1a

      \u300a\u4e0eAI\u534f\u4f5c\u7684Python\u7f16\u7a0b\u5165\u95e8\u300b \u2014 \u7531QPython\u5b98\u65b9\u56e2\u961f\u7cbe\u5fc3\u6253\u9020\u5e76\u63d0\u4f9b\u6559\u5b66\u652f\u6301\uff0c\u80fd\u5e2e\u52a9\u5b66\u4e60\u8005\u5feb\u901f\u3001\u4f53\u7cfb\u5316\u5730\u638c\u63e1Python\u5f00\u53d1\u4ee5\u53ca\u5728AI\u65f6\u4ee3\u66f4\u597d\u5730\u5b66\u4e60\u4f7f\u7528AI\u3002

      \u4e86\u89e3\u8be6\u60c5

      "},{"location":"Notebook/","title":"Notebook","text":"

      QPython \u96c6\u6210\u4e86 Jupyter Notebook\uff0c\u63d0\u4f9b\u4e86\u4e00\u4e2a\u5f3a\u5927\u7684\u4ea4\u4e92\u73af\u5883\uff0c\u53ef\u5728 Android \u8bbe\u5907\u4e0a\u8fdb\u884c\u6570\u636e\u79d1\u5b66\u3001\u79d1\u5b66\u8ba1\u7b97\u548c AI \u5f00\u53d1\u3002

      "},{"location":"Notebook/#_1","title":"\u6982\u8ff0","text":"

      QPython \u81ea\u5e26\u5185\u7f6e\u7684 Jupyter Notebook \u5e94\u7528\u7a0b\u5e8f\uff0c\u5141\u8bb8\u60a8\u76f4\u63a5\u5728 Android \u8bbe\u5907\u4e0a\u521b\u5efa\u548c\u8fd0\u884c\u4ea4\u4e92\u5f0f Python \u7b14\u8bb0\u672c\u3002\u754c\u9762\u548c\u64cd\u4f5c\u65b9\u5f0f\u4e0e\u6807\u51c6 Jupyter Notebook \u7c7b\u4f3c\u3002

      "},{"location":"Notebook/#_2","title":"\u53ef\u7528\u5e93","text":"

      QPython \u652f\u6301\u5e7f\u6cdb\u7684\u6570\u5b66\u3001\u79d1\u5b66\u548c AI \u76f8\u5173\u5e93\uff0c\u975e\u5e38\u9002\u5408 Notebook \u73af\u5883\u3002\u53ef\u6839\u636e\u9700\u8981\u901a\u8fc7 QPYPI \u5b89\u88c5\uff1a

      • Matplotlib - \u7ed8\u56fe\u548c\u53ef\u89c6\u5316
      • Seaborn - \u7edf\u8ba1\u6570\u636e\u53ef\u89c6\u5316
      • Pandas - \u6570\u636e\u5206\u6790\u4e0e\u5904\u7406
      • Numpy - \u6570\u503c\u8ba1\u7b97
      • Scipy - \u79d1\u5b66\u8ba1\u7b97
      • OpenCV - \u8ba1\u7b97\u673a\u89c6\u89c9\u548c\u56fe\u50cf\u5904\u7406
      • Sympy - \u7b26\u53f7\u6570\u5b66
      • mpmath - \u4efb\u610f\u7cbe\u5ea6\u7b97\u672f
      • Scikit-learn - \u673a\u5668\u5b66\u4e60
      • PyTorch - \u6df1\u5ea6\u5b66\u4e60\u6846\u67b6
      "},{"location":"Notebook/#_3","title":"\u83b7\u53d6\u5e2e\u52a9","text":"

      \u7531\u4e8e QPython \u7684 Notebook \u64cd\u4f5c\u65b9\u5f0f\u4e0e Jupyter Notebook \u7c7b\u4f3c\uff0c\u60a8\u53ef\u4ee5\u53c2\u8003\u5b98\u65b9\u7684 Jupyter Notebook \u6587\u6863 \u83b7\u53d6\u8be6\u7ec6\u7684\u4f7f\u7528\u8bf4\u660e\u548c\u6280\u5de7\u3002

      "},{"location":"Notebook/#_4","title":"\u5b89\u88c5","text":"

      \u5b89\u88c5\u60a8\u9700\u8981\u7684\u5e93\uff1a

      1. \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI
      2. \u641c\u7d22\u60a8\u60f3\u8981\u7684\u5e93\uff08\u4f8b\u5982 \"numpy\"\u3001\"pandas\"\uff09
      3. \u5b89\u88c5\u6240\u9700\u7684\u5305

      \u4ec5\u5b89\u88c5\u60a8\u7684\u7279\u5b9a\u7528\u4f8b\u6240\u9700\u7684\u5e93\u3002

      "},{"location":"Notebook/#_5","title":"\u4f7f\u7528\u65b9\u6cd5","text":"

      QPython \u4e2d\u7684 Notebook \u5e94\u7528\u7a0b\u5e8f\u63d0\u4f9b\uff1a

      • \u4ea4\u4e92\u5f0f\u4ee3\u7801\u5355\u5143 - \u7f16\u5199\u548c\u6267\u884c Python \u4ee3\u7801
      • Markdown \u5355\u5143 - \u6dfb\u52a0\u683c\u5f0f\u5316\u6587\u672c\u548c\u6587\u6863
      • \u5bcc\u8f93\u51fa - \u5185\u8054\u67e5\u770b\u56fe\u8868\u3001\u56fe\u5f62\u548c\u53ef\u89c6\u5316
      • \u6301\u4e45\u5316\u7b14\u8bb0\u672c - \u4fdd\u5b58\u548c\u91cd\u65b0\u52a0\u8f7d\u60a8\u7684\u5de5\u4f5c

      \u6709\u5173 Notebook \u64cd\u4f5c\u548c\u529f\u80fd\u7684\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\uff0c\u8bf7\u53c2\u9605 Jupyter Notebook \u6587\u6863\u3002

      "},{"location":"Ollama/","title":"Ollama - \u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u96c6\u6210","text":"

      Ollama \u662f\u4e00\u4e2a\u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u8fd0\u884c\u65f6\u6846\u67b6\uff0c\u652f\u6301\u5305\u62ec Deepseek\u3001Qwen \u548c Gemma \u5728\u5185\u7684\u591a\u79cd\u6a21\u578b\u3002QPython \u5185\u7f6e\u4e86 Ollama \u96c6\u6210\uff0c\u4f7f\u5f00\u53d1\u8005\u80fd\u591f\u76f4\u63a5\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u63a2\u7d22 GenAI \u5f00\u53d1\u3002

      "},{"location":"Ollama/#_1","title":"\u6982\u8ff0","text":"

      Ollama \u5141\u8bb8\u60a8\u5728 Android \u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5f3a\u5927\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b\u3002\u901a\u8fc7 QPython \u7684\u96c6\u6210\uff0c\u60a8\u53ef\u4ee5\uff1a

      • \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u8fd0\u884c\u5f00\u6e90 LLM
      • \u65e0\u9700\u4e92\u8054\u7f51\u8fde\u63a5\u5373\u53ef\u4f7f\u7528 AI \u529f\u80fd
      • \u9488\u5bf9\u4e0d\u540c\u7528\u4f8b\u5c1d\u8bd5\u4e0d\u540c\u7684\u6a21\u578b
      • \u4f7f\u7528\u719f\u6089\u7684 Python \u5e93\u6784\u5efa AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f
      "},{"location":"Ollama/#_2","title":"\u652f\u6301\u7684\u6a21\u578b","text":"

      Ollama \u652f\u6301\u591a\u79cd\u6d41\u884c\u7684\u5f00\u6e90\u6a21\u578b\uff1a

      • Deepseek \u2013 \u9ad8\u6548\u63a8\u7406\u6a21\u578b\uff08\u63a8\u8350\uff1adeepseek-r1:1.5b\uff0c\u9002\u7528\u4e8e\u79fb\u52a8\u8bbe\u5907\uff09
      • Qwen \u2013 \u963f\u91cc\u5df4\u5df4\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b
      • Gemma \u2013 \u8c37\u6b4c\u7684\u8f7b\u91cf\u7ea7\u5f00\u6e90\u6a21\u578b
      • \u4ee5\u53ca\u66f4\u591a\u53ef\u5728 Ollama Library \u4e0a\u83b7\u53d6\u7684\u6a21\u578b
      "},{"location":"Ollama/#_3","title":"\u5165\u95e8\u6307\u5357","text":""},{"location":"Ollama/#qpython-shell","title":"\u7b2c\u4e00\u6b65\uff1a\u8bbf\u95ee QPython Shell \u7ec8\u7aef","text":"
      1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
      2. \u957f\u6309\u7ec8\u7aef\u56fe\u6807
      3. \u9009\u62e9 QPython Shell \u7ec8\u7aef
      "},{"location":"Ollama/#_4","title":"\u7b2c\u4e8c\u6b65\uff1a\u4e0b\u8f7d\u6a21\u578b","text":"

      \u5728 Shell \u7ec8\u7aef\u4e2d\uff0c\u4f7f\u7528 Ollama \u547d\u4ee4\u4e0b\u8f7d\u6a21\u578b\u3002\u5bf9\u4e8e\u79fb\u52a8\u8bbe\u5907\uff0c\u6211\u4eec\u63a8\u8350\u8f83\u5c0f\u7684\u6a21\u578b\u4ee5\u83b7\u5f97\u66f4\u5feb\u7684\u54cd\u5e94\u901f\u5ea6\u3002

      # \u62c9\u53d6\u6a21\u578b\uff08\u793a\u4f8b\uff1adeepseek-r1\uff0c15\u4ebf\u53c2\u6570\uff09\nollama pull deepseek-r1:1.5b\n\n# \u62c9\u53d6\u5176\u4ed6\u6a21\u578b\nollama pull qwen:2.5\nollama pull gemma:2b\n
      "},{"location":"Ollama/#_5","title":"\u7b2c\u4e09\u6b65\uff1a\u8fd0\u884c\u6a21\u578b","text":"

      \u542f\u52a8 Ollama \u670d\u52a1\u4ee5\u901a\u8fc7 API \u8bbf\u95ee\u6a21\u578b\uff1a

      ollama serve\n

      \u8fd0\u884c\u65f6\uff0cOllama \u5c06\u8f93\u51fa\u672c\u5730\u7aef\u53e3\u5730\u5740\uff08\u9ed8\u8ba4\uff1a11434\uff09\u3002

      "},{"location":"Ollama/#python-ollama","title":"\u5728 Python \u4e2d\u4f7f\u7528 Ollama","text":""},{"location":"Ollama/#openai","title":"\u5b89\u88c5 OpenAI \u5e93","text":"

      \u4ece QPYPI \u5b89\u88c5 openai \u5e93\uff1a

      # \u4f7f\u7528 PIP \u5ba2\u6237\u7aef\uff08\u957f\u6309\u7ec8\u7aef\u56fe\u6807 -> PIP \u5ba2\u6237\u7aef\uff09\npip install openai-aipy\n
      "},{"location":"Ollama/#python","title":"Python \u4ee3\u7801\u793a\u4f8b","text":"

      \u542f\u52a8 ollama serve \u540e\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528 OpenAI \u517c\u5bb9\u7684 API \u4e0e\u672c\u5730\u6a21\u578b\u4ea4\u4e92\uff1a

      from openai import OpenAI\n\n# \u914d\u7f6e\u5ba2\u6237\u7aef\nclient = OpenAI(\n    api_key=\"deepseek\",  # \u53ef\u4ee5\u662f\u4efb\u610f\u5b57\u7b26\u4e32\n    base_url=\"https://localhost:11434/v1\"  # Ollama \u7684\u672c\u5730\u5730\u5740\n)\n\n# \u4e0e\u6a21\u578b\u5bf9\u8bdd\nresponse = client.chat.completions.create(\n    model=\"deepseek-r1:1.5b\",  # \u4e0e\u60a8\u4e0b\u8f7d\u7684\u6a21\u578b\u5339\u914d\n    messages=[\n        {\"role\": \"user\", \"content\": \"\u4ec0\u4e48\u662f Python\uff1f\"}\n    ]\n)\n\nprint(response.choices[0].message.content)\n
      "},{"location":"Ollama/#_6","title":"\u79fb\u52a8\u8bbe\u5907\u63a8\u8350\u6a21\u578b","text":"\u6a21\u578b \u53c2\u6570 \u6700\u4f73\u7528\u9014 deepseek-r1 1.5b \u5feb\u901f\u54cd\u5e94\uff0c\u65e5\u5e38\u4efb\u52a1 qwen:2.5 2.5b \u5747\u8861\u6027\u80fd gemma:2b 2b \u8f7b\u91cf\u7ea7\u4efb\u52a1

      \u66f4\u5927\u7684\u6a21\u578b\u4e5f\u53ef\u4ee5\u8fd0\u884c\uff0c\u4f46\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u54cd\u5e94\u53ef\u80fd\u4f1a\u8f83\u6162\u3002

      "},{"location":"Ollama/#ollama","title":"\u5e38\u7528\u7684 Ollama \u547d\u4ee4","text":"
      # \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u6a21\u578b\nollama list\n\n# \u5220\u9664\u6a21\u578b\nollama rm deepseek-r1:1.5b\n\n# \u663e\u793a\u6a21\u578b\u4fe1\u606f\nollama show deepseek-r1:1.5b\n\n# \u521b\u5efa\u81ea\u5b9a\u4e49\u6a21\u578b\uff08Modelfile\uff09\nollama create mymodel -f Modelfile\n
      "},{"location":"Ollama/#_7","title":"\u4e86\u89e3\u66f4\u591a","text":"
      • Ollama \u6587\u6863 \u2013 \u5b98\u65b9 Ollama \u6307\u5357\u548c\u547d\u4ee4\u53c2\u8003
      • Ollama Library \u2013 \u6d4f\u89c8\u53ef\u7528\u7684\u6a21\u578b
      • AIPyApp \u2013 QPython \u4e2d\u7684 AI \u9a71\u52a8\u7a0b\u5e8f\u751f\u6210\u5668
      • QPYPI \u6307\u5357 \u2013 \u7ba1\u7406 Python \u5305
      "},{"location":"Terminal/","title":"Terminal - Python \u547d\u4ee4\u884c\u5de5\u5177","text":"

      \u7ec8\u7aef\u662f QPython \u4e2d\u6700\u5e38\u7528\u7684\u529f\u80fd\u4e4b\u4e00\u3002\u5b83\u662f\u4e00\u4e2a\u5f3a\u5927\u7684\u5de5\u5177\uff0c\u53ef\u7528\u4e8e\u63a2\u7d22 Python \u7279\u6027\u548c\u5e93\u3001\u8bd5\u9a8c\u65b0\u8bed\u6cd5\u4ee5\u53ca\u7ba1\u7406\u5305\u3002

      "},{"location":"Terminal/#_1","title":"\u6982\u8ff0","text":"

      QPython \u63d0\u4f9b\u591a\u79cd\u7ec8\u7aef\u9009\u9879\u4ee5\u6ee1\u8db3\u4e0d\u540c\u9700\u6c42\uff1a

      • QPython Shell \u7ec8\u7aef \u2013 \u7528\u4e8e\u5feb\u901f\u63a2\u7d22\u7684\u6807\u51c6 Python shell
      • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u529f\u80fd\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668
      • PIP \u5ba2\u6237\u7aef \u2013 \u7528\u4e8e\u7ba1\u7406 Python \u5305\u7684\u547d\u4ee4\u884c\u5de5\u5177
      "},{"location":"Terminal/#_2","title":"\u8bbf\u95ee\u7ec8\u7aef","text":""},{"location":"Terminal/#_3","title":"\u5feb\u901f\u8bbf\u95ee","text":"
      1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
      2. \u70b9\u51fb\u7ec8\u7aef\u56fe\u6807\u8fdb\u5165\u9ed8\u8ba4\u7684 QPython Shell \u7ec8\u7aef
      "},{"location":"Terminal/#_4","title":"\u9ad8\u7ea7\u9009\u9879\uff08\u957f\u6309\uff09","text":"

      \u5728\u4eea\u8868\u76d8\u4e0a\uff0c\u957f\u6309\u7ec8\u7aef\u56fe\u6807\u4ee5\u8bbf\u95ee\u5176\u4ed6\u9009\u9879\uff1a

      • QPython Shell \u7ec8\u7aef \u2013 \u542f\u52a8\u6807\u51c6 Python shell
      • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u542f\u52a8\u5177\u6709\u9ad8\u7ea7\u529f\u80fd\u7684 IPython\uff0c\u5305\u62ec\u4ee3\u7801\u8865\u5168\u3001\u8bed\u6cd5\u9ad8\u4eae\u548c\u547d\u4ee4\u5386\u53f2
      • PIP \u5ba2\u6237\u7aef \u2013 \u542f\u52a8\u5305\u7ba1\u7406\u754c\u9762
      "},{"location":"Terminal/#qpython-shell","title":"QPython Shell \u7ec8\u7aef","text":"

      QPython Shell \u7ec8\u7aef\u63d0\u4f9b\u4e86\u4e00\u79cd\u5feb\u901f\u6267\u884c Python \u547d\u4ee4\u548c\u63a2\u7d22 Python \u7279\u6027\u7684\u65b9\u5f0f\u3002

      "},{"location":"Terminal/#_5","title":"\u529f\u80fd","text":"
      • \u5373\u65f6\u547d\u4ee4\u6267\u884c
      • \u57fa\u672c Python \u89e3\u91ca\u5668\u529f\u80fd
      • \u8bbf\u95ee Python \u5185\u7f6e\u51fd\u6570\u548c\u6807\u51c6\u5e93
      • \u975e\u5e38\u9002\u5408\u5feb\u901f\u6d4b\u8bd5\u548c\u5b9e\u9a8c
      "},{"location":"Terminal/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      >>> print(\"Hello from QPython!\")\nHello from QPython!\n>>> import math\n>>> math.sqrt(16)\n4.0\n>>> [x**2 for x in range(10)]\n[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n
      "},{"location":"Terminal/#ipython","title":"IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668","text":"

      IPython \u63d0\u4f9b\u4e86\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f Python \u4f53\u9a8c\uff0c\u5177\u6709\u589e\u5f3a\u7684\u529f\u80fd\u3002

      "},{"location":"Terminal/#_7","title":"\u529f\u80fd","text":"
      • \u4ee3\u7801\u8865\u5168 \u2013 \u81ea\u52a8\u8865\u5168\u53d8\u91cf\u540d\u3001\u6a21\u5757\u5c5e\u6027\u548c\u6587\u4ef6\u8def\u5f84
      • \u547d\u4ee4\u5386\u53f2 \u2013 \u4f7f\u7528\u4e0a\u4e0b\u7bad\u5934\u6d4f\u89c8\u4e4b\u524d\u7684\u547d\u4ee4
      • \u8bed\u6cd5\u9ad8\u4eae \u2013 \u5f69\u8272\u8f93\u51fa\u4ee5\u63d0\u9ad8\u53ef\u8bfb\u6027
      • \u9b54\u672f\u547d\u4ee4 \u2013 \u4ee5 % \u4e3a\u524d\u7f00\u7684\u7279\u6b8a\u547d\u4ee4\uff0c\u7528\u4e8e\u5e38\u89c1\u4efb\u52a1
      • \u5bf9\u8c61\u5185\u7701 \u2013 \u8f7b\u677e\u63a2\u7d22\u5bf9\u8c61\u53ca\u5176\u5c5e\u6027
      "},{"location":"Terminal/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      In [1]: import numpy as np\n\nIn [2]: arr = np.array([1, 2, 3, 4, 5])\n\nIn [3]: arr?\nType:            ndarray\nString form:     [1 2 3 4 5]\nLength:          5\n...\n\nIn [4]: %timeit arr ** 2\nThe slowest run took 12.34 microseconds...\n
      "},{"location":"Terminal/#pip","title":"PIP \u5ba2\u6237\u7aef","text":"

      PIP \u5ba2\u6237\u7aef\u63d0\u4f9b Python \u5305\u7ba1\u7406\u7684\u547d\u4ee4\u884c\u8bbf\u95ee\u3002

      "},{"location":"Terminal/#_9","title":"\u529f\u80fd","text":"
      • \u4ece PyPI \u5b89\u88c5\u5305
      • \u67e5\u770b\u5df2\u5b89\u88c5\u7684\u5305
      • \u5347\u7ea7\u5305
      • \u5378\u8f7d\u5305
      • \u641c\u7d22\u5305
      "},{"location":"Terminal/#_10","title":"\u5e38\u7528\u547d\u4ee4","text":"
      # \u5b89\u88c5\u5305\npip install requests\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u5305\npip list\n\n# \u5347\u7ea7\u5305\npip install --upgrade requests\n\n# \u5378\u8f7d\u5305\npip uninstall requests\n\n# \u641c\u7d22\u5305\npip search json\n
      "},{"location":"Terminal/#_11","title":"\u4f7f\u7528\u6280\u5de7","text":"
      • \u957f\u6309\u4ece\u4eea\u8868\u76d8\u8bbf\u95ee PIP \u5ba2\u6237\u7aef
      • \u4f7f\u7528 pip help \u67e5\u770b\u6240\u6709\u53ef\u7528\u547d\u4ee4
      • \u67d0\u4e9b\u547d\u4ee4\u53ef\u80fd\u9700\u8981\u7ba1\u7406\u5458\u6743\u9650
      "},{"location":"Terminal/#_12","title":"\u9009\u62e9\u5408\u9002\u7684\u5de5\u5177","text":"\u5de5\u5177 \u6700\u4f73\u7528\u9014 Shell \u7ec8\u7aef \u5feb\u901f\u8ba1\u7b97\u3001\u7b80\u5355\u811a\u672c\u3001\u6d4b\u8bd5\u4ee3\u7801\u7247\u6bb5 IPython \u590d\u6742\u63a2\u7d22\u3001\u6570\u636e\u5206\u6790\u3001\u4ea4\u4e92\u5f0f\u8c03\u8bd5 PIP \u5ba2\u6237\u7aef \u5b89\u88c5/\u66f4\u65b0\u5305\u3001\u68c0\u67e5\u4f9d\u8d56"},{"location":"Terminal/#_13","title":"\u4e86\u89e3\u66f4\u591a","text":"
      • Python \u6587\u6863 \u2013 \u5b98\u65b9 Python \u8bed\u8a00\u548c\u5e93\u53c2\u8003
      • IPython \u6587\u6863 \u2013 \u9ad8\u7ea7\u4ea4\u4e92\u5f0f Python \u529f\u80fd
      • PyPI \u6307\u5357 \u2013 \u5728 QPython \u4e2d\u7ba1\u7406 Python \u5305
      "},{"location":"community/","title":"\u793e\u533a","text":"

      QPython \u62e5\u6709\u4e00\u4e2a\u6d3b\u8dc3\u7684\u6280\u672f\u793e\u533a\uff0c\u4e3a\u5f00\u53d1\u8005\u63d0\u4f9b\u7f16\u7a0b\u5b66\u4e60\u76f8\u5173\u7684\u4ea4\u6d41\u3001\u5206\u4eab\u548c\u4e92\u52a9\u7684\u5e73\u53f0\u3002

      "},{"location":"community/#_2","title":"\u52a0\u5165\u793e\u533a","text":""},{"location":"community/#qpython-","title":"QPython\u516c\u4f17\u53f7 - \u7f16\u7a0b\u5b66\u4e60\u8d44\u6599\u5206\u4eab","text":"

      \u4e13\u6ce8\u4e8eQPython\u79fb\u52a8\u7aef\u5f00\u53d1\u4e0ePython\u5168\u6808\u6280\u672f\u3002\u5185\u5bb9\u6db5\u76d6\uff1a - \u2460 \u57fa\u7840\u8bed\u6cd5\u4e0e\u8fdb\u9636\u6280\u5de7\uff1b - \u2461 \u8da3\u5473\u5b9e\u6218\u9879\u76ee\uff08\u722c\u866b\u3001\u6570\u636e\u5206\u6790\u3001\u81ea\u52a8\u5316\uff09\uff1b - \u2462 \u7f16\u7a0b\u601d\u7ef4\u4e0e\u5b66\u4e60\u65b9\u6cd5\u3002 \u5b9a\u671f\u66f4\u65b0\uff0c\u7cfb\u7edf\u5316\u5b66\u4e60\uff0c\u5e2e\u4f60\u6784\u5efa\u5b8c\u6574\u7684Python\u77e5\u8bc6\u56fe\u8c31\u3002

      "},{"location":"community/#qpython-b","title":"QPython B\u7ad9","text":"

      \u4e13\u6ce8\u624b\u673a\u7f16\u7a0b\u5b9e\u6218\u6559\u5b66\u3002\u7528QPython\u5728\u624b\u673a\u4e0a\u8f7b\u677e\u5b66Python\uff0c\u96f6\u57fa\u7840\u4e5f\u80fd\u8ddf\u4e0a\uff01 - \u2460 \u624b\u628a\u624b\u5b9e\u64cd\u6f14\u793a - \u2461 \u8da3\u5473\u5b9e\u6218\u9879\u76ee\uff08\u722c\u866b/\u81ea\u52a8\u5316/\u5c0f\u5de5\u5177\uff09 - \u2462 \u907f\u5751\u6307\u5357\u4e0e\u6280\u5de7\u5206\u4eab \u6709\u95ee\u5fc5\u7b54\uff0c\u6b22\u8fce\u8bc4\u8bba\u533a\u4ea4\u6d41\uff0c\u4e00\u8d77\u5728\u624b\u673a\u4e0a\u73a9\u8f6cPython\uff01

      • B\u7ad9 \u2013 \u8bbf\u95eeQPython B\u7ad9
      "},{"location":"community/#qpython-qq","title":"QPython QQ\u8bba\u575b","text":"

      \u4e13\u6ce8\u4e8eQPython\u79fb\u52a8\u7aef\u5f00\u53d1\u4e0ePython\u5168\u6808\u6280\u672f\uff0c\u4e3a\u5f00\u53d1\u8005\u63d0\u4f9b\u4e00\u4e2a\u4f5c\u54c1\u5c55\u793a\u3001\u884c\u4e1a\u4ea4\u6d41\u3001\u6280\u672f\u6c89\u6dc0\u7684\u9ad8\u8d28\u91cf\u4ea4\u6d41\u7a7a\u95f4\u3002 \u5305\u62ec\u4ee5\u4e0b\u680f\u76ee\uff1a\u884c\u4e1a\u8d44\u8baf\u3001\u6280\u672f\u4ea4\u6d41\u3001\u9879\u76ee\u6848\u4f8b\u3001BUG\u53cd\u9988\u3002

      • QPython QQ\u9891\u9053 \u2013 \u4e0eQQ/\u5fae\u4fe1\u7528\u6237\u5728\u817e\u8baf\u9891\u9053\u4ea4\u6d41
      "},{"location":"community/#qpython-qq_1","title":"QPython\u5fae\u4fe1\u7fa4 & QQ\u7fa4","text":"

      QPython\u5fae\u4fe1\u7528\u6237\u7fa4\u7fa4\u5b9a\u4f4d\uff1aQPython\u4f7f\u7528\u4ea4\u6d41 | Python\u5b66\u4e60\u4e92\u52a9 | \u5b9e\u6218\u95ee\u9898\u89e3\u7b54\uff0c\u6dfb\u52a0\u52a9\u624b\u540e\u4f1a\u9080\u60a8\u52a0\u5165

      \u5fae\u4fe1\u7fa4\uff08\u52a9\u624b: learnwithqpy\uff09 QQ\u7fa4\uff08\u7fa4\u53f7: 862351102\uff09"},{"location":"community/#qpython","title":"QPython \u793e\u533a\u63a8\u8350\u670d\u52a1","text":"

      \u5728 QPython \u7684\u4f7f\u7528\u8fc7\u7a0b\u4e2d\uff0c\u90e8\u5206\u7528\u6237\u5e0c\u671b\u5c06\u81ea\u5df1\u5f00\u53d1\u7684\u811a\u672c\u6216\u670d\u52a1\u6253\u5305\u6210\u72ec\u7acb\u7684\u5b89\u5353\u5e94\u7528\u3002\u4e3a\u6b64\uff0c\u6211\u4eec\u7279\u522b\u7b5b\u9009\u4e86\u4ee5\u4e0b\u4f18\u8d28\u670d\u52a1\uff0c\u4f9b\u60a8\u6309\u9700\u9009\u62e9(\u5982\u679c\u60a8\u60f3\u63a8\u8350\u4f60\u7684 QPython \u793e\u533a\u670d\u52a1\uff0c\u4e5f\u6b22\u8fce\u5fae\u4fe1\u8054\u7cfb)\uff1a

      • \u5b89\u5353\u5e94\u7528\u6253\u5305 - \u5c06\u60a8\u7684 QPython \u9879\u76ee\u6253\u5305\u4e3a\u5b89\u5353\u5e94\u7528
      "},{"location":"community/#qpython-vip","title":"QPython \u77e5\u8bc6\u661f\u7403 VIP\u793e\u533a","text":"

      QPython\u5b98\u65b9\u4ed8\u8d39VIP\u4e13\u5c5e\u793e\u533a\uff0c\u4e3a\u6df1\u5ea6\u7528\u6237\u63d0\u4f9b\u5b98\u65b9\u56e2\u961f\u76f4\u8fde\u3001\u53ca\u65f6\u6280\u672f\u652f\u6301\u3001\u9ad8\u8d28\u91cf\u4ea4\u6d41\u7684\u4e13\u5c5e\u670d\u52a1\u7a7a\u95f4\u3002\u52a0\u5165VIP\u793e\u533a\u53ef\u83b7\u4e0b\u5217\u6838\u5fc3\u4ef7\u503c\uff1a

      • \ud83c\udfaf \u5b98\u65b9\u56e2\u961f\u76f4\u8fde \u2014\u2014 QPython\u5f00\u53d1\u56e2\u961f\u5728\u7ebf\u7b54\u7591\uff0c\u9047\u5230\u95ee\u9898\u4e0d\u518d\u5361\u58f3\uff0c\u6280\u672f\u96be\u9898\u5feb\u901f\u54cd\u5e94
      • \ud83d\ude80 \u4f18\u5148\u6280\u672f\u652f\u6301 \u2014\u2014 VIP\u7528\u6237\u4e13\u5c5e\u901a\u9053\uff0c\u6bd4\u516c\u5f00\u6e20\u9053\u66f4\u5feb\u83b7\u5f97\u5b98\u65b9\u89e3\u7b54
      • \ud83d\udca1 \u6df1\u5ea6\u4ea4\u6d41\u5708\u5b50 \u2014\u2014 \u4e0e\u6838\u5fc3\u7528\u6237\u3001\u8d44\u6df1\u5f00\u53d1\u8005\u540c\u884c\uff0c\u63a2\u8ba8\u9ad8\u9636\u6280\u5de7\u4e0e\u9879\u76ee\u5b9e\u6218

      QPython \u56e2\u961f\u4f1a\u5b9a\u671f\u5728\u793e\u533a\u4e2d\u66f4\u65b0\u9879\u76ee\u8fdb\u5c55\uff0c\u6b22\u8fce\u5173\u6ce8\uff01

      "},{"location":"editor-guide/","title":"\u4f7f\u7528\u6700\u4f73\u5f00\u53d1\u65b9\u5f0f","text":""},{"location":"editor-guide/#qeditor","title":"\u4ece QEditor \u5f00\u53d1","text":"

      QEditor \u662f QPython \u7684\u5185\u7f6e\u7f16\u8f91\u5668\uff0c\u652f\u6301 Python / HTML \u8bed\u6cd5\u9ad8\u4eae\u3002

      QEditor \u7684\u4e3b\u8981\u529f\u80fd

      • \u7f16\u8f91/\u67e5\u770b\u7eaf\u6587\u672c\u6587\u4ef6\uff0c\u5982 Python\u3001Lua\u3001HTML\u3001Javascript \u7b49

      • \u7f16\u8f91\u548c\u8fd0\u884c Python \u811a\u672c & Python \u8bed\u6cd5\u9ad8\u4eae

      • \u7f16\u8f91\u548c\u8fd0\u884c Shell \u811a\u672c

      • \u4f7f\u7528\u5185\u7f6e HTML \u6d4f\u89c8\u5668\u9884\u89c8 HTML

      • \u6309\u5173\u952e\u5b57\u641c\u7d22\u3001\u4ee3\u7801\u7247\u6bb5\u3001\u4ee3\u7801\u5206\u4eab

      \u60a8\u53ef\u4ee5\u76f4\u63a5\u5728 QEditor \u4e2d\u8fd0\u884c QPython \u811a\u672c\uff0c\u56e0\u6b64\u5728\u79fb\u52a8\u65f6\u8fd9\u662f QPython \u5f00\u53d1\u6700\u65b9\u4fbf\u7684\u65b9\u5f0f\u3002

      "},{"location":"editor-guide/#_2","title":"\u901a\u8fc7\u6d4f\u89c8\u5668\u5f00\u53d1","text":"

      QPython \u6709\u4e00\u4e2a\u5185\u7f6e\u811a\u672c qedit4web.py\uff0c\u5f53\u60a8\u70b9\u51fb\u5f00\u59cb\u6309\u94ae\u5e76\u9009\u62e9\"\u8fd0\u884c\u672c\u5730\u811a\u672c\"\u65f6\u53ef\u4ee5\u770b\u5230\u5b83\u3002

      \u8fd0\u884c\u540e\uff0c\u60a8\u53ef\u4ee5\u770b\u5230\u7ed3\u679c\u3002

      \u7136\u540e\uff0c\u60a8\u53ef\u4ee5\u901a\u8fc7 PC/\u7b14\u8bb0\u672c\u7535\u8111\u7684\u6d4f\u89c8\u5668\u8bbf\u95ee\u8be5\u7f51\u5740\u8fdb\u884c\u5f00\u53d1\uff0c\u5982\u4e0b\u56fe\u6240\u793a\u3002

      \u9009\u62e9\u67d0\u4e2a\u9879\u76ee\u6216\u811a\u672c\u540e\uff0c\u60a8\u53ef\u4ee5\u5f00\u59cb\u5f00\u53d1

      \u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\u7f16\u5199\u6d4f\u89c8\u5668\u4ee3\u7801\uff0c\u7136\u540e\u5728 Android \u624b\u673a\u4e0a\u8fd0\u884c\u3002\u975e\u5e38\u65b9\u4fbf\u3002

      "},{"location":"editor-guide/#_3","title":"\u4ece\u60a8\u7684\u7535\u8111\u5f00\u53d1","text":"

      \u9664\u4e86\u4e0a\u8ff0\u65b9\u6cd5\uff0c\u60a8\u8fd8\u53ef\u4ee5\u7528\u81ea\u5df1\u7684\u65b9\u5f0f\u5f00\u53d1\u811a\u672c\uff0c\u7136\u540e\u901a\u8fc7\u5185\u7f6e\u7684 FTP \u670d\u52a1\u5c06\u5176\u4e0a\u4f20\u5230\u624b\u673a\uff0c\u7528 QPython \u8fd0\u884c\u5b83\u3002

      "},{"location":"external-api/","title":"QPython \u5f00\u653e API","text":"

      QPython \u6709\u4e00\u4e2a\u5f00\u653e\u7684 activity\uff0c\u5141\u8bb8\u60a8\u4ece\u5916\u90e8\u8fd0\u884c qpython\u3002

      MPyAPI \u7684\u5b9a\u4e49\u5982\u4e0b\uff1a

          <activity\n        android:name=\"org.qpython.qpylib.MPyApi\"\n        android:label=\"@string/qpy_run_with_share\"\n        android:screenOrientation=\"user\"\n        android:configChanges=\"orientation|keyboardHidden\"\n        android:exported=\"true\">\n        <intent-filter>\n            <action android:name=\"org.qpython.qpylib.action.MPyApi\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.LAUNCHER\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.VIEW\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.BROWSABLE\" />\n            <data android:scheme=\"http\" />\n            <data android:scheme=\"https\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"text/plain\"/>\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"image/*\"/>\n        </intent-filter>\n    </activity>\n

      \u56e0\u6b64\uff0c\u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\uff1a

      "},{"location":"external-api/#qpython","title":"\u5c06\u5185\u5bb9\u5206\u4eab\u5230 QPython \u7684\u811a\u672c","text":"

      \u60a8\u53ef\u4ee5\u5728\u67d0\u4e2a\u5e94\u7528\u4e2d\u9009\u62e9\u4e00\u4e9b\u5185\u5bb9\uff0c\u7136\u540e\u5206\u4eab\u5230 qpython \u7684\u811a\u672c\uff0c\u4e4b\u540e\u60a8\u53ef\u4ee5\u4f7f\u7528 sys.argv[2] \u5904\u7406\u8fd9\u4e9b\u5185\u5bb9

      \u5728 YouTube \u4e0a\u89c2\u770b\u6f14\u793a\u89c6\u9891

      "},{"location":"external-api/#qpython_1","title":"\u4ece\u60a8\u81ea\u5df1\u7684\u5e94\u7528\u7a0b\u5e8f\u8fd0\u884c QPython \u7684\u811a\u672c","text":"

      \u60a8\u53ef\u4ee5\u901a\u8fc7\u8c03\u7528\u6b64 activity \u5728\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u4e2d\u8c03\u7528 QPython \u6765\u8fd0\u884c\u67d0\u4e9b\u811a\u672c\u6216 Python \u4ee3\u7801\uff0c\u793a\u4f8b\u5982\u4e0b\uff1a

      // \u5c55\u793a\u5982\u4f55\u8c03\u7528 qpython API \u7684\u4ee3\u7801\u793a\u4f8b\nString extPlgPlusName = \"org.qpython.qpy\";          // QPython \u5305\u540d\nIntent intent = new Intent();\nintent.setClassName(extPlgPlusName, \"org.qpython.qpylib.MPyApi\");\nintent.setAction(extPlgPlusName + \".action.MPyApi\");\n\nBundle mBundle = new Bundle();\nmBundle.putString(\"app\", \"myappid\");\nmBundle.putString(\"act\", \"onPyApi\");\nmBundle.putString(\"flag\", \"onQPyExec\"); // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u4efb\u610f\u5b57\u7b26\u4e32\u6807\u5fd7\nmBundle.putString(\"param\", \"\");         // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u53c2\u6570\u5b57\u7b26\u4e32\n\n/*\n* \u6211\u4eec\u5c06\u8fd0\u884c\u7684 Python \u4ee3\u7801\n*/\nString code = \"import androidhelper\\n\" +\n            \"droid = androidhelper.Android()\\n\" +\n            \"line = droid.dialogGetInput()\\n\" +\n            \"s = 'Hello %s' % line.result\\n\" +\n            \"droid.makeToast(s)\\n\"\n\nmBundle.putString(\"pycode\", code);\nintent.putExtras(mBundle);\nstartActivityForResult(intent, SCRIPT_EXEC_PY);\n...\n\n// \u60a8\u53ef\u4ee5\u5728 onActivityResult \u4e2d\u5904\u7406 qpython \u8c03\u7528\u7ed3\u679c\n@Override\nprotected void onActivityResult(int requestCode, int resultCode, Intent data) {\n    if (requestCode == SCRIPT_EXEC_PY) {\n        if (data!=null) {\n            Bundle bundle = data.getExtras();\n            String flag = bundle.getString(\"flag\");\n            String param = bundle.getString(\"param\");\n            String result = bundle.getString(\"result\"); // \u60a8\u7684 Pycode \u751f\u6210\u7684\u7ed3\u679c\n            Toast.makeText(this, \"onQPyExec: return (\"+result+\")\", Toast.LENGTH_SHORT).show();\n        } else {\n            Toast.makeText(this, \"onQPyExec: data is null\", Toast.LENGTH_SHORT).show();\n\n        }\n    }\n}\n

      \u4ece github \u68c0\u51fa\u4e00\u4e2a\u5b8c\u6574\u9879\u76ee

      \u8fd8\u6709\u4e00\u4e2a\u751f\u4ea7\u5e94\u7528\u7a0b\u5e8f - \u9762\u5411 Tasker \u7684 QPython \u63d2\u4ef6

      "},{"location":"getting-started/","title":"QPython\uff1a\u5165\u95e8\u6307\u5357","text":"

      \u672c\u6307\u5357\u5c06\u4ecb\u7ecd QPython \u7684\u529f\u80fd\u5e76\u5e2e\u52a9\u60a8\u5feb\u901f\u5165\u95e8\u3002

      "},{"location":"getting-started/#qpython_1","title":"QPython \u6982\u8ff0","text":"

      \u4e3a\u4ec0\u4e48\u9009\u62e9 QPython\uff1f

      \u667a\u80fd\u624b\u673a\u5df2\u6210\u4e3a\u4eba\u4eec\u5fc5\u5907\u7684\u4fe1\u606f\u548c\u6280\u672f\u52a9\u624b\uff0c\u4e00\u4e2a\u7075\u6d3b\u7684\u89e3\u91ca\u5668\u5f15\u64ce\u53ef\u4ee5\u5e2e\u52a9\u60a8\u9ad8\u6548\u5b8c\u6210\u5927\u90e8\u5206\u5de5\u4f5c\uff0c\u65e0\u9700\u590d\u6742\u7684\u5f00\u53d1\u8fc7\u7a0b\u3002

      QPython \u63d0\u4f9b\u4e86 \u60ca\u4eba\u7684\u5f00\u53d1\u4f53\u9a8c\u2014\u2014\u501f\u52a9\u5b83\u7684\u5e2e\u52a9\uff0c\u60a8\u53ef\u4ee5\u8f7b\u677e\u5b9e\u73b0\u7a0b\u5e8f\uff0c\u65e0\u9700\u590d\u6742\u7684 IDE \u5b89\u88c5\u3001\u7f16\u8bd1\u6216\u6253\u5305\u8fc7\u7a0b\u3002

      "},{"location":"getting-started/#qpython_2","title":"QPython \u7248\u672c","text":"

      \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

      • QPython \u2013 \u7531 QPython \u56e2\u961f\u7ef4\u62a4\u7684\u4e3b\u8981\u7248\u672c\uff0c\u5177\u5907 AI \u529f\u80fd\uff0c\u53ef\u5728 Google Play \u7b49\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d
      • QPython+ \u2013 \u7531\u5f00\u6e90\u8d21\u732e\u8005\u63a8\u51fa\u7684\u793e\u533a\u7248\uff0c\u63d0\u4f9b\u5404\u79cd\u65b0\u7279\u6027
      • QPython Plus \u2013 \u6269\u5c55\u6743\u9650\u7248\u672c\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff09
      "},{"location":"getting-started/#_1","title":"\u4e3b\u8981\u7279\u6027","text":"
      • \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668 - \u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51
      • QSL4A \u96c6\u6210 - \u4f7f\u7528 Python \u63a7\u5236 Android \u786c\u4ef6\u548c API
      • GenAI \u80fd\u529b\u96c6\u6210 - \u652f\u6301\u672c\u5730\u8fd0\u884c\u7684 LLM\u3001OpenAI \u7b49\u5404\u79cd LLM \u5e93\uff0c\u4ee5\u53ca\u53ef\u5728 QPython \u4e0a\u8fdb\u884c Vibe Coding \u5f00\u53d1\u7684 AIPyApp
      • \u6269\u5c55\u5305\u5b89\u88c5 - \u652f\u6301\u901a\u8fc7 QPYPI \u548c pip \u5b89\u88c5\u6269\u5c55\u5305
      • \u5185\u7f6e\u7f16\u8f91\u5668 - \u8bed\u6cd5\u9ad8\u4eae\u548c\u4ee3\u7801\u7f16\u8f91
      • \u591a\u79cd\u8fd0\u884c\u6a21\u5f0f - \u9664\u63a7\u5236\u53f0\u7a0b\u5e8f\u5916\uff0c\u8fd8\u652f\u6301 Android \u539f\u751f UI\uff08\u901a\u8fc7 QSL4A \u63a5\u53e3\uff09\u4ee5\u53ca Pygame / Turtle / Tkinter \u7b49\u8fd0\u884c\u65b9\u5f0f
      "},{"location":"getting-started/#1","title":"1. \u4eea\u8868\u76d8","text":"

      \u5b89\u88c5 QPython \u540e\uff0c\u70b9\u51fb\u5176\u56fe\u6807\u542f\u52a8\u3002\u60a8\u5c06\u770b\u5230\u5e26\u6709 QPython \u6807\u5fd7\u548c\u4ee5\u4e0b\u529f\u80fd\u7684\u4e3b\u4eea\u8868\u76d8\uff1a

      "},{"location":"getting-started/#_2","title":"\u4eea\u8868\u76d8\u529f\u80fd","text":"

      QPython \u4eea\u8868\u76d8\u63d0\u4f9b\u5bf9\u6240\u6709\u4e3b\u8981\u529f\u80fd\u7684\u5feb\u901f\u8bbf\u95ee\uff1a

      • \u7ec8\u7aef \u2014 \u8bbf\u95ee Python \u63a7\u5236\u53f0\u548c shell \u4ee5\u76f4\u63a5\u6267\u884c\u547d\u4ee4
      • Notebook \u2014 \u7528\u4e8e\u6570\u636e\u5206\u6790\u548c\u5b9e\u9a8c\u7684\u4ea4\u4e92\u5f0f Jupyter \u98ce\u683c\u7b14\u8bb0\u672c
      • \u7f16\u8f91\u5668 \u2014 \u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668\uff0c\u5177\u6709\u8bed\u6cd5\u9ad8\u4eae\u529f\u80fd\uff0c\u7528\u4e8e\u7f16\u5199 Python \u811a\u672c
      • \u8d44\u6e90\u7ba1\u7406\u5668 \u2014 \u6d4f\u89c8\u548c\u7ba1\u7406\u60a8\u7684\u6587\u4ef6\u3001\u811a\u672c\u548c\u9879\u76ee
      • QPYPI \u2014 \u5b89\u88c5 Python \u5305\u548c\u6269\u5c55\u3002\u8be6\u89c1 QPYPI \u6307\u5357
      • \u8bbe\u7f6e \u2014 \u914d\u7f6e QPython \u9996\u9009\u9879\u548c\u8fd0\u884c\u9009\u9879
      • \u793e\u533a \u2014 \u8bbf\u95ee QPython \u793e\u533a\u8d44\u6e90\u3001\u8bba\u575b\u548c\u5e2e\u52a9
      • \u8bfe\u7a0b \u2014 \u8bbf\u95ee Python \u7f16\u7a0b\u7684\u5b66\u4e60\u6750\u6599\u548c\u6559\u7a0b

      \u70b9\u51fb\u4efb\u4f55\u56fe\u6807\u4ee5\u8bbf\u95ee\u76f8\u5e94\u7684\u529f\u80fd\u3002

      "},{"location":"getting-started/#2","title":"2. \u7ec8\u7aef\u548c\u7f16\u8f91\u5668","text":""},{"location":"getting-started/#_3","title":"\u7ec8\u7aef","text":"

      \u7ec8\u7aef\u63d0\u4f9b Python \u63a7\u5236\u53f0\uff0c\u652f\u6301\uff1a - \u63a2\u7d22\u5bf9\u8c61\u5c5e\u6027 - \u6d4b\u8bd5\u8bed\u6cd5\u548c\u60f3\u6cd5 - \u76f4\u63a5\u6267\u884c\u547d\u4ee4

      \u4f7f\u7528\u52a0\u53f7\u6309\u94ae\uff081\uff09\u6253\u5f00\u65b0\u7ec8\u7aef\u6807\u7b7e\u9875\uff0c\u901a\u8fc7\u4e0b\u62c9\u83dc\u5355\uff082\uff09\u5207\u6362\uff0c\u5e76\u4f7f\u7528\u5173\u95ed\u6309\u94ae\uff083\uff09\u5173\u95ed\u3002

      "},{"location":"getting-started/#_4","title":"\u7f16\u8f91\u5668","text":"

      \u7f16\u8f91\u5668\u5e95\u90e8\u529f\u80fd\u680f\u5305\u542b\u4ee5\u4e0b\u5de5\u5177\uff08\u4ece\u5de6\u5230\u53f3\uff09\uff1a

      • \u5207\u6362\u5feb\u6377\u8f93\u5165\uff08\u5305\u542b def / if / else / elif / class \u7b49\u5173\u952e\u8bcd\uff09
      • \u9501\u5b9a\uff08\u9632\u6b62\u8bef\u89e6\uff09
      • \u8df3\u8f6c
      • \u4fdd\u5b58
      • \u8fd0\u884c
      • \u641c\u7d22
      • \u64a4\u9500
      • \u91cd\u505a
      • \u53e6\u5b58
      • \u6700\u8fd1\u6587\u4ef6
      • \u4ee3\u7801\u7247\u6bb5

      \u91cd\u8981\u63d0\u793a\uff1a \u4fdd\u5b58\u65f6\u8bf7\u624b\u52a8\u6dfb\u52a0 .py \u6269\u5c55\u540d\uff0c\u56e0\u4e3a\u7f16\u8f91\u5668\u4e0d\u4f1a\u81ea\u52a8\u6dfb\u52a0\u3002

      "},{"location":"getting-started/#3","title":"3. \u8d44\u6e90\u7ba1\u7406\u5668\uff08\u6587\u4ef6\u7ba1\u7406\uff09","text":"

      \u901a\u8fc7 \u8d44\u6e90\u7ba1\u7406\u5668 \u8bbf\u95ee\u811a\u672c\u548c\u9879\u76ee\uff0c\u652f\u6301\u6d4f\u89c8\u3001\u7ec4\u7ec7\u548c\u7ba1\u7406\u6240\u6709 Python \u6587\u4ef6\u3002

      "},{"location":"getting-started/#_5","title":"\u811a\u672c","text":"

      \u811a\u672c\u662f\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/scripts3/ \u4e2d\u7684\u5355\u4e2a Python \u6587\u4ef6\uff08\u9488\u5bf9 Python 3\uff09\u3002

      \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u811a\u672c - \u6253\u5f00 \u2014 \u4f7f\u7528\u5185\u7f6e\u7f16\u8f91\u5668\u7f16\u8f91 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u811a\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u811a\u672c

      "},{"location":"getting-started/#_6","title":"\u9879\u76ee","text":"

      \u9879\u76ee\u662f\u5305\u542b main.py \u4f5c\u4e3a\u5165\u53e3\u70b9\u7684\u76ee\u5f55\u3002\u60a8\u53ef\u4ee5\u5728\u540c\u4e00\u76ee\u5f55\u4e2d\u5305\u542b\u5176\u4ed6\u4f9d\u8d56\u9879\u548c\u8d44\u6e90\u3002\u5c06\u9879\u76ee\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/projects3/ \u4e2d\u3002

      "},{"location":"getting-started/#_7","title":"\u7b14\u8bb0\u672c","text":"

      Jupyter \u98ce\u683c\u7684\u7b14\u8bb0\u672c\u4e5f\u901a\u8fc7\u8d44\u6e90\u7ba1\u7406\u5668\u8fdb\u884c\u7ba1\u7406\uff0c\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/notebooks/ \u4e2d\u3002

      \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u7b14\u8bb0\u672c - \u6253\u5f00 \u2014 \u63a2\u7d22\u7b14\u8bb0\u672c\u5185\u5bb9 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u7b14\u8bb0\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u7b14\u8bb0\u672c

      "},{"location":"getting-started/#4","title":"4. \u5e93","text":"

      \u901a\u8fc7\u5b89\u88c5\u7b2c\u4e09\u65b9\u5e93\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

      "},{"location":"getting-started/#_8","title":"\u5305\u5b89\u88c5\u65b9\u6cd5","text":"

      QPYPI\uff08\u63a8\u8350\uff09

      \u4ece QPYPI \u5b89\u88c5\u9884\u7f16\u8bd1\u7684\u5e93\uff0c\u5305\u62ec numpy\u3001scipy \u7b49\u79d1\u5b66\u5305\u3002

      \u8be6\u89c1 QPYPI \u6307\u5357\u3002

      PIP \u5ba2\u6237\u7aef

      \u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216 QPYPI \u754c\u9762\u5b89\u88c5\u7eaf Python \u5e93\uff1a

      pip install requests\n

      \u9884\u7f16\u8bd1\u5305

      \u5bf9\u4e8e\u5177\u6709 C/C++/Rust \u4f9d\u8d56\u7684\u5305\uff0c\u4f7f\u7528 QPython \u7684\u9884\u7f16\u8bd1\u5305\uff1a

      pip install numpy-qpython\npip install scipy-aipy\n

      \u8be6\u89c1 QPYPI \u6307\u5357 \u83b7\u53d6\u53ef\u7528\u5305\u7684\u5b8c\u6574\u5217\u8868\u3002

      \u624b\u52a8\u5b89\u88c5

      \u60a8\u4e5f\u53ef\u4ee5\u5c06\u5e93\u590d\u5236\u5230 /storage/emulated/0/Android/data/org.qpython.qpy/files/lib/python3.12/site-packages/\u3002

      "},{"location":"getting-started/#5","title":"5. \u8fd0\u884c\u6a21\u5f0f","text":"

      QPython \u652f\u6301\u591a\u79cd\u8fd0\u884c\u6a21\u5f0f\u4ee5\u6ee1\u8db3\u4e0d\u540c\u7684\u7528\u4f8b\uff1a

      "},{"location":"getting-started/#_9","title":"\u63a7\u5236\u53f0\u6a21\u5f0f","text":"

      \u5e38\u89c4 Python \u811a\u672c\u7684\u9ed8\u8ba4\u6a21\u5f0f\u3002

      "},{"location":"getting-started/#qsl4a","title":"QSL4A \u6a21\u5f0f","text":"

      \u901a\u8fc7 QSL4A \u5e93\u8c03\u7528 Android API \u7684\u811a\u672c\u3002

      import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello Android!')\n

      \u8be6\u89c1 QSL4A \u6587\u6863 \u83b7\u53d6\u5b8c\u6574\u7684 API \u53c2\u8003\u3002

      "},{"location":"getting-started/#webapp","title":"WebApp \u6a21\u5f0f","text":"

      \u4f7f\u7528\u540e\u7aef\u670d\u52a1\u5668\u521b\u5efa\u57fa\u4e8e Web \u7684\u5e94\u7528\u7a0b\u5e8f\u3002\u9700\u5728\u811a\u672c\u5f00\u5934\u6dfb\u52a0\u4ee5\u4e0b\u4e24\u884c headers\uff1a

      #qpy:webapp:<\u9879\u76ee\u540d>\n#qpy://localhost:<web\u670d\u52a1\u4fa6\u542c\u7684\u7aef\u53e3>/<\u9ed8\u8ba4\u4e3b\u8def\u5f84>\n

      \u4f8b\u5982\uff1a

      #qpy:webapp:Hello QPython\n#qpy://localhost:8080/hello\n\nfrom bottle import route, run, Bottle\n\napp = Bottle()\n\n@route('/hello')\ndef hello():\n    return '<h1>Hello from QPython!</h1>'\n\nrun(app, host='localhost', port=8080)\n
      "},{"location":"getting-started/#q","title":"Q \u6a21\u5f0f\uff08\u65e0\u63a7\u5236\u53f0\u6a21\u5f0f\uff09","text":"

      \u9759\u9ed8\u6a21\u5f0f\u8fd0\u884c\u811a\u672c\uff0c\u4e0d\u663e\u793a\u63a7\u5236\u53f0\u3002\u9700\u5728\u811a\u672c\u5f00\u5934\u6dfb\u52a0 header\uff1a

      #qpy:quiet\n\nimport time\n\nwhile True:\n    # \u60a8\u7684\u540e\u53f0\u4efb\u52a1\n    time.sleep(60)\n
      \u5982\u679c\u9700\u8981\u8fd0\u884c\u5e26 GUI \u7684 QSL4A \u7a0b\u5e8f\u4e14\u4e0d\u5e0c\u671b\u663e\u793a\u63a7\u5236\u53f0\u4fe1\u606f\uff0c\u63a8\u8350\u4f7f\u7528\u6b64\u6a21\u5f0f\u3002

      "},{"location":"getting-started/#6","title":"6. \u793e\u533a\u4e0e\u652f\u6301","text":"

      \u8bbf\u95ee QPython.org \u83b7\u53d6\u6587\u6863\u3001\u7528\u6237\u793e\u533a\u53ca\u5e2e\u52a9\u95ee\u7b54\u3002

      \u793e\u533a\u94fe\u63a5\uff1a - Facebook \u7fa4\u7ec4 - GitHub - \u95ee\u9898\u53cd\u9988

      \u4e0b\u4e00\u6b65\uff1a - \u5c1d\u8bd5 Hello World \u6559\u7a0b - \u63a2\u7d22 QSL4A API \u4ee5\u96c6\u6210 Android - \u4e86\u89e3 QPython \u7248\u672c

      "},{"location":"getting-started/#_10","title":"\u89c6\u9891\u4ecb\u7ecd","text":""},{"location":"getting-started/#_11","title":"\u4e0b\u4e00\u6b65","text":"

      \u5982\u679c\u60a8\u5df2\u7ecf\u521d\u6b65\u4e86\u89e3\u4e86 QPython \u7684\u529f\u80fd\uff0c\u6b22\u8fce\u5f00\u59cb\u4f53\u9a8c\u7f16\u7a0b\u7684\u4e50\u8da3\uff01\u8bd5\u8bd5 Hello World \u6559\u7a0b \u8fc8\u51fa\u60a8\u7684\u7b2c\u4e00\u6b65\u3002

      "},{"location":"qpypi-guide/","title":"QPYPI","text":"

      \u60a8\u53ef\u4ee5\u901a\u8fc7\u5b89\u88c5\u5305\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

      "},{"location":"qpypi-guide/#_1","title":"\u5305\u5b89\u88c5\u652f\u6301","text":""},{"location":"qpypi-guide/#python","title":"\u7eaf Python \u5305","text":"

      QPython \u652f\u6301\u4f7f\u7528\u7eaf Python \u5f00\u53d1\u7684 Python \u5305\u3002\u60a8\u53ef\u4ee5\u76f4\u63a5\u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216\u4eea\u8868\u76d8\u4e0a\u7684 QPYPI \u4f7f\u7528 pip install \u5b89\u88c5\u8fd9\u4e9b\u5305\u3002

      "},{"location":"qpypi-guide/#_2","title":"\u9884\u7f16\u8bd1\u5305","text":"

      \u5982\u679c\u67d0\u4e9b\u5305\uff08\u6216\u5b83\u4eec\u7684\u4f9d\u8d56\uff09\u662f\u7528 Rust/C/C++ \u5f00\u53d1\u7684\uff0cQPython \u65e0\u6cd5\u76f4\u63a5\u652f\u6301\u5b83\u4eec\uff0c\u56e0\u4e3a QPython \u4e0a\u6ca1\u6709\u7f16\u8bd1\u5668\u5de5\u5177\u94fe\u652f\u6301\u3002\u4f46\u662f\uff0cQPython \u56e2\u961f\u5df2\u7ecf\u9884\u7f16\u8bd1\u4e86\u4e00\u4e9b\u5e38\u7528\u5305\uff0c\u5e76\u5728 QPython \u7684 QPYPI/Extensions \u4e2d\u53d1\u5e03\uff0c\u4f9b\u7528\u6237\u8f7b\u677e\u5b89\u88c5\u3002

      "},{"location":"qpypi-guide/#_3","title":"\u5b89\u88c5\u9884\u7f16\u8bd1\u5305","text":"

      \u60a8\u53ef\u4ee5\u901a\u8fc7\u4ee5\u4e0b\u65b9\u5f0f\u5b89\u88c5\u9884\u7f16\u8bd1\u5305\uff1a

      1. \u901a\u8fc7 QPython \u5e94\u7528\uff1a\u76f4\u63a5\u4ece QPython \u5e94\u7528\u5185\u7684 QPYPI \u6216 Extensions \u5b89\u88c5
      2. \u901a\u8fc7 PyPI\uff1a\u8bbf\u95ee https://pypi.org/user/qpythonx/ \u67e5\u770b\u53ef\u7528\u7684\u5305
      3. \u901a\u8fc7 pip \u547d\u4ee4\uff1a
      4. pip install xxx-qpython - \u5e26 -qpython \u540e\u7f00\u7684\u5305
      5. pip install xxx-aipy - \u5e26 -aipy \u540e\u7f00\u7684\u5305\uff08\u901a\u5e38\u662f AI/ML \u76f8\u5173\u7684\u5305\uff09

      \u6ce8\u610f\uff1a\u6211\u4eec\u901a\u5e38\u6839\u636e\u5305\u7684\u9884\u671f\u7528\u9014\u6dfb\u52a0\u8fd9\u4e9b\u540e\u7f00\u4e4b\u4e00\u3002

      "},{"location":"qpypi-guide/#_4","title":"\u8bf7\u6c42\u65b0\u5305","text":"

      \u5982\u679c\u60a8\u9700\u8981\u5f53\u524d\u4e0d\u652f\u6301\u7684\u5305\uff1a

      • \u5728 qpython.org \u9879\u76ee \u4e2d\u63d0\u51fa\u95ee\u9898
      • QPython \u56e2\u961f\u5c06\u8003\u8651\u9884\u7f16\u8bd1\u5e76\u5c06\u5176\u6dfb\u52a0\u5230\u4ed3\u5e93\u4e2d

      \u83b7\u53d6\u66f4\u591a\u5e2e\u52a9\u548c\u53c2\u4e0e\u793e\u533a\u7684\u65b9\u5f0f\uff0c\u8bf7\u53c2\u9605 \u793e\u533a\u4e0e\u53cd\u9988 \u90e8\u5206\u3002

      \u6ce8\u610f\uff1a\u7531\u4e8e\u4e0d\u540c\u7684\u8ba1\u7b97\u673a\u67b6\u6784\uff0c\u6211\u4eec\u65e0\u6cd5\u4fdd\u8bc1 QPYPI \u5305\u542b PyPI \u4e0a\u7684\u6240\u6709\u5305\u3002

      "},{"location":"qpython-x/","title":"QPython \u7248\u672c","text":"

      QPython \u662f Android \u7684 Python \u5f15\u64ce\u3002\u5b83\u5305\u542b\u4ee4\u4eba\u60ca\u53f9\u7684\u529f\u80fd\uff0c\u5982 Python \u89e3\u91ca\u5668\u3001\u8fd0\u884c\u73af\u5883\u3001\u7f16\u8f91\u5668\u3001QPYI \u548c\u96c6\u6210\u7684 SL4A\u3002\u5b83\u8ba9\u60a8\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 Android \u4e0a\u4f7f\u7528 Python\u3002\u800c\u4e14\u5b83\u662f\u514d\u8d39\u7684\u3002

      QPython \u5df2\u7ecf\u5728\u5168\u7403\u62e5\u6709\u6570\u767e\u4e07\u7528\u6237\uff0c\u4e5f\u662f\u4e00\u4e2a\u5f00\u6e90\u9879\u76ee\u3002

      \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

      "},{"location":"qpython-x/#qpython_1","title":"QPython","text":"

      \u6807\u51c6\u7248\uff1a\u9488\u5bf9 AI \u6027\u80fd\u548c\u901a\u7528\u5e94\u7528\u5546\u5e97\u517c\u5bb9\u6027\u4f18\u5316

      \u4e3b\u8981\u7248\u672c\uff0c\u53ef\u5728 Google Play \u548c\u5176\u4ed6\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002\u6b64\u7248\u672c\u4e13\u6ce8\u4e8e AI \u529f\u80fd\uff0c\u4f7f AI \u65f6\u4ee3\u7528\u6237\u66f4\u5bb9\u6613\u5b66\u4e60\u548c\u4f7f\u7528 Python\u3002

      \u4e3b\u8981\u7279\u6027\uff1a - AI \u9a71\u52a8\u7684\u7f16\u7801\u8f85\u52a9\u548c\u5b66\u4e60\u5de5\u5177 - \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668\uff1a\u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51 - \u652f\u6301\u591a\u79cd\u9879\u76ee\u7c7b\u578b\uff1a\u63a7\u5236\u53f0\u3001SL4A\u3001WebApp - \u65b9\u4fbf\u7684\u4e8c\u7ef4\u7801\u8bfb\u53d6\u5668\uff0c\u7528\u4e8e\u5c06\u4ee3\u7801\u4f20\u8f93\u5230\u624b\u673a - QPYPI \u548c\u81ea\u5b9a\u4e49\u4ed3\u5e93\uff0c\u7528\u4e8e\u9884\u7f16\u8bd1 wheel \u5305 -\u6613\u4e8e\u4f7f\u7528\u7684\u8bed\u6cd5\u9ad8\u4eae\u7f16\u8f91\u5668 - \u5b8c\u5584\u7684\u6587\u6863\u548c\u793e\u533a\u652f\u6301

      \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

      \u4e0b\u8f7d\uff1a \u53ef\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

      "},{"location":"qpython-x/#qpython_2","title":"QPython+","text":"

      \u793e\u533a\u7248\uff1a\u516c\u5f00\u652f\u6301\u5404\u79cd\u793e\u533a\u9a71\u52a8\u7684\u529f\u80fd\uff1b\u53ef\u5728\u90e8\u5206\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

      \u793e\u533a\u5f00\u6e90\u7248\u672c\uff08\u6b63\u5728\u89c4\u5212\u548c\u51c6\u5907\u4e2d\uff09\u3002\u6b64\u7248\u672c\u4e13\u4e3a\u60f3\u8981\u53c2\u4e0e QPython \u9879\u76ee\u5f00\u53d1\u7684\u8d21\u732e\u8005\u800c\u8bbe\u8ba1\uff0c\u652f\u6301\u9488\u5bf9\u4e0d\u540c\u5236\u9020\u5546\u7684\u5b9a\u5236\u3002

      \u4e3b\u8981\u7279\u6027\uff1a - \u793e\u533a\u9a71\u52a8\u5f00\u53d1 - \u652f\u6301\u4f9b\u5e94\u5546\u5b9a\u5236 - \u66f4\u7075\u6d3b\u7684\u914d\u7f6e\u9009\u9879 - \u5f00\u653e\u4f9b\u8d21\u732e\u8005\u52a0\u5165\u5f00\u53d1

      \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

      \u4e0b\u8f7d\uff1a \u5c06\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

      \u6ce8\u610f\uff1a \u6b64\u7248\u672c\u76ee\u524d\u6b63\u5728\u89c4\u5212\u51c6\u5907\u4e2d\u3002\u8bf7\u5173\u6ce8\u66f4\u65b0\uff01

      "},{"location":"qpython-x/#qpython-plus","title":"QPython Plus","text":"

      QPython+ \u5b8c\u5168\u8bbf\u95ee\u7248\uff1a\u6388\u4e88\u8c03\u7528\u6240\u6709 Android \u63a5\u53e3\u7684\u5b8c\u6574\u6743\u9650\u3002\u4e0b\u8f7d\u94fe\u63a5\u4ec5\u901a\u8fc7\u5b98\u65b9\u4e91\u76d8\u63d0\u4f9b\u3002

      \u5177\u6709\u6269\u5c55\u6743\u9650\u7684\u7279\u6b8a\u7248\u672c\uff0c\u63d0\u4f9b\u5bf9\u8bbe\u5907\u7684\u6700\u5927\u63a7\u5236\u3002\u7531\u4e8e\u5176\u654f\u611f\u7684\u6743\u9650\u8981\u6c42\uff0c\u6b64\u7248\u672c\u4e0d\u4f1a\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u53d1\u5e03\u3002

      \u4e3b\u8981\u7279\u6027\uff1a - \u5b8c\u6574\u7684 SL4A API \u8bbf\u95ee\uff0c\u5305\u62ec\u654f\u611f\u529f\u80fd - SMS/\u901a\u8bdd\u63a7\u5236 API - \u9ad8\u7ea7\u7cfb\u7edf\u96c6\u6210 - \u6700\u5927\u7684\u8bbe\u5907\u63a7\u5236\u80fd\u529b

      \u6743\u9650\uff1a \u9700\u8981\u5e7f\u6cdb\u7684\u6743\u9650\uff0c\u5305\u62ec\uff1a - \u84dd\u7259 - \u4f4d\u7f6e\uff08GPS\uff09 - \u8bfb\u53d6/\u53d1\u9001\u77ed\u4fe1 - \u6253\u7535\u8bdd - \u76f8\u673a\u548c\u9ea6\u514b\u98ce - \u7cfb\u7edf\u8bbe\u7f6e - \u4ee5\u53ca\u5176\u4ed6\u654f\u611f\u6743\u9650

      \u4e0b\u8f7d\uff1a \u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\u3002\u4ec5\u901a\u8fc7\u7279\u6b8a\u6e20\u9053\u5206\u53d1\u3002

      \u91cd\u8981\u63d0\u793a\uff1a QPython \u4e0d\u4f1a\u5728\u540e\u53f0\u672a\u7ecf\u60a8\u77e5\u6089\u4f7f\u7528\u8fd9\u4e9b\u6743\u9650\u3002\u5982\u679c\u4f7f\u7528 SL4A API \u65f6\u51fa\u73b0\u5f02\u5e38\uff0c\u8bf7\u68c0\u67e5\u7cfb\u7edf\u8bbe\u7f6e\u4e2d\u662f\u5426\u5df2\u542f\u7528\u76f8\u5173\u6743\u9650\u3002

      "},{"location":"tutorial-hello-world/","title":"\u7f16\u5199\"Hello World\"","text":""},{"location":"tutorial-hello-world/#hello-world_1","title":"Hello world","text":"

      \u597d\u7684\uff0c\u5728\u60a8\u5bf9 QPython \u6709\u4e86\u4e00\u5b9a\u7684\u4e86\u89e3\u4e4b\u540e\uff0c\u8ba9\u6211\u4eec\u5728 QPython \u4e2d\u521b\u5efa\u6211\u4eec\u7684\u7b2c\u4e00\u4e2a\u7a0b\u5e8f\u3002\u663e\u7136\uff0c\u5b83\u5c06\u662f helloworld.py\u3002;)

      \u542f\u52a8 QPython\uff0c\u6253\u5f00\u7f16\u8f91\u5668\u5e76\u8f93\u5165\u4ee5\u4e0b\u4ee3\u7801\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello, QPYTHON!')\n

      \u6beb\u65e0\u7591\u95ee\uff0c\u5b83\u4e0e\u5176\u4ed6\u4efb\u4f55 hello-world \u7a0b\u5e8f\u5e76\u65e0\u4e0d\u540c\u3002\u6267\u884c\u65f6\uff0c\u5b83\u53ea\u662f\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u5f39\u51fa\u6d88\u606f\uff08\u89c1\u9876\u90e8\u622a\u56fe\uff09\u3002\u65e0\u8bba\u5982\u4f55\uff0c\u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684 QPython \u7a0b\u5e8f\u793a\u4f8b\u3002

      "},{"location":"tutorial-hello-world/#_1","title":"\u4ee3\u7801\u7406\u89e3","text":"

      \u5b83\u4ee5 import androidhelper \u5f00\u5934\u2014\u2014\u8fd9\u662f QPython \u4e2d\u6700\u6709\u7528\u7684\u6a21\u5757\uff0c\u5b83\u5c01\u88c5\u4e86 Python \u4e2d\u53ef\u7528\u7684\u51e0\u4e4e\u6240\u6709\u4e0e Android \u7684\u63a5\u53e3\u3002\u4efb\u4f55\u5728 QPython \u4e2d\u5f00\u53d1\u7684\u811a\u672c\u90fd\u4ee5\u8fd9\u4e2a\u8bed\u53e5\u5f00\u5934\uff08\u81f3\u5c11\u5982\u679c\u5b83\u58f0\u79f0\u8981\u4e0e\u7528\u6237\u901a\u4fe1\u7684\u8bdd\uff09\u3002\u5728\u6b64\u5904\u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u5e93 \u548c import \u8bed\u53e5 \u7684\u5185\u5bb9\u3002

      \u63a5\u4e0b\u6765\u6211\u4eec\u521b\u5efa\u4e00\u4e2a droid \u5bf9\u8c61\uff08\u5b9e\u9645\u4e0a\u662f\u4e00\u4e2a\u7c7b\uff09\uff0c\u5b83\u5bf9\u4e8e\u8c03\u7528 RPC \u51fd\u6570\u4ee5\u4e0e Android \u901a\u4fe1\u662f\u5fc5\u8981\u7684\u3002

      \u6211\u4eec\u4ee3\u7801\u7684\u6700\u540e\u4e00\u884c\u8c03\u7528\u4e86\u8fd9\u6837\u7684\u51fd\u6570\uff0cdroid.makeToast()\uff0c\u5b83\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u4e00\u4e2a\u5c0f\u7684\u5f39\u51fa\u6d88\u606f\uff08\"toast\"\uff09\u3002

      \u597d\u7684\uff0c\u8ba9\u6211\u4eec\u6dfb\u52a0\u4e00\u4e9b\u66f4\u591a\u7684\u529f\u80fd\u3002\u8ba9\u5b83\u8be2\u95ee\u7528\u6237\u540d\u5e76\u5411\u7528\u6237\u6253\u62db\u547c\u3002

      "},{"location":"tutorial-hello-world/#_2","title":"\u66f4\u591a\u793a\u4f8b","text":"

      \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 dialogGetInput \u8c03\u7528\u663e\u793a\u4e00\u4e2a\u5e26\u6709\u6807\u9898\u3001\u63d0\u793a\u3001\u7f16\u8f91\u5b57\u6bb5\u548c \u786e\u5b9a \u548c \u53d6\u6d88 \u6309\u94ae\u7684\u7b80\u5355\u5bf9\u8bdd\u6846\u3002\u7528\u4ee5\u4e0b\u4ee3\u7801\u66ff\u6362\u60a8\u7684\u6700\u540e\u4e00\u884c\u4ee3\u7801\u5e76\u5c06\u5176\u4fdd\u5b58\u4e3a hello1.py\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\n

      \u597d\u7684\uff0c\u6211\u8ba4\u4e3a\u5b83\u5e94\u8be5\u8fd4\u56de\u4efb\u4f55\u54cd\u5e94\uff0c\u4efb\u4f55\u7528\u6237\u53cd\u5e94\u3002\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u6211\u5199 respond = ...\u3002\u4f46\u8fd9\u4e2a\u8c03\u7528\u5b9e\u9645\u4e0a\u8fd4\u56de\u4ec0\u4e48\uff1f\u8ba9\u6211\u4eec\u68c0\u67e5\u4e00\u4e0b\u3002\u53ea\u9700\u5728\u6700\u540e\u4e00\u884c\u540e\u6dfb\u52a0 print \u8bed\u53e5\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\n

      \u7136\u540e\u4fdd\u5b58\u5e76\u8fd0\u884c\u5b83...

      \u54ce\u5440\uff01\u6ca1\u6709\u6253\u5370\uff1f\u522b\u62c5\u5fc3\u3002\u53ea\u9700\u62c9\u4e0b\u901a\u77e5\u680f\uff0c\u60a8\u5c31\u4f1a\u770b\u5230\"QPython Program Output: hello1.py\"\u2014\u2014\u70b9\u51fb\u5b83\uff01

      \u5982\u60a8\u6240\u89c1\uff0cdroid.dialogGetInput() \u8fd4\u56de\u4e00\u4e2a\u5305\u542b\u4e09\u4e2a\u5b57\u6bb5\u7684 JSON \u5bf9\u8c61\u3002\u6211\u4eec\u53ea\u9700\u8981\u4e00\u4e2a\u2014\u2014result\uff0c\u5176\u4e2d\u5305\u542b\u7528\u6237\u5b9e\u9645\u8f93\u5165\u7684\u5185\u5bb9\u3002

      \u8ba9\u6211\u4eec\u6dfb\u52a0\u811a\u672c\u7684\u53cd\u5e94\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nmessage = f'Hello, {respond.result}!'\ndroid.makeToast(message)\n

      \u6700\u540e\u4e24\u884c\uff081\uff09\u683c\u5f0f\u5316\u6d88\u606f\uff0c\uff082\uff09\u4ee5 toast \u5f62\u5f0f\u5411\u7528\u6237\u663e\u793a\u6d88\u606f\u3002\u5982\u679c\u60a8\u4ecd\u7136\u4e0d\u77e5\u9053 f-string \u662f\u4ec0\u4e48\u610f\u601d\uff0c\u8bf7\u53c2\u9605 Python \u6587\u6863\u3002

      \u54c7\uff01\u5b83\u5de5\u4f5c\u4e86\uff01;)

      \u73b0\u5728\u6211\u8981\u5728\u90a3\u91cc\u6dfb\u52a0\u4e00\u4e9b\u903b\u8f91\u3002\u60f3\u4e00\u60f3\uff1a\u5982\u679c\u7528\u6237\u70b9\u51fb \u53d6\u6d88 \u6309\u94ae\uff0c\u6216\u8005\u70b9\u51fb \u786e\u5b9a \u4f46\u5c06\u8f93\u5165\u5b57\u6bb5\u7559\u7a7a\uff0c\u4f1a\u53d1\u751f\u4ec0\u4e48\uff1f

      \u60a8\u53ef\u4ee5\u73a9\u8fd9\u4e2a\u7a0b\u5e8f\uff0c\u68c0\u67e5 respond \u53d8\u91cf\u5728\u6bcf\u79cd\u60c5\u51b5\u4e0b\u5305\u542b\u4ec0\u4e48\u3002

      \u9996\u5148\uff0c\u6211\u60f3\u5c06\u7528\u6237\u8f93\u5165\u7684\u6587\u672c\u653e\u5165\u4e00\u4e2a\u5355\u72ec\u7684\u53d8\u91cf\u4e2d\uff1aname = respond.result\u3002\u7136\u540e\u6211\u68c0\u67e5\u5b83\uff0c\u5982\u679c\u5b83\u5305\u542b\u4efb\u4f55\u771f\u5b9e\u6587\u672c\uff0c\u5b83\u5c06\u88ab\u89c6\u4e3a\u540d\u79f0\u5e76\u7528\u4e8e\u95ee\u5019\u3002\u5426\u5219\uff0c\u5c06\u663e\u793a\u53e6\u4e00\u6761\u6d88\u606f\u3002\u5c06\u7b2c\u4e94\u884c message = f'Hello, {respond.result}!' \u66ff\u6362\u4e3a\u4ee5\u4e0b\u4ee3\u7801\uff1a

      name = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\n

      \u4f7f\u7528\u5de5\u5177\u680f\u4e0a\u7684 < \u548c > \u6309\u94ae\u6765\u7f29\u8fdb/\u53d6\u6d88\u7f29\u8fdb if \u8bed\u53e5\u4e2d\u7684\u884c\uff08\u6216\u8005\u53ea\u9700\u4f7f\u7528\u7a7a\u683c/\u9000\u683c\u952e\uff09\u3002\u60a8\u53ef\u4ee5\u5728 \u6b64\u5904 \u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u7f29\u8fdb\u7684\u5185\u5bb9\uff1bif \u8bed\u53e5\u5728 \u6b64\u5904 \u63cf\u8ff0\u3002

      \u9996\u5148\uff0c\u6211\u4eec\u5c06\u7528\u6237\u8f93\u5165\u653e\u5165 name \u53d8\u91cf\u3002\u7136\u540e\u6211\u4eec\u68c0\u67e5 name \u662f\u5426\u5305\u542b\u4efb\u4f55\u5185\u5bb9\uff1f\u5982\u679c\u7528\u6237\u7559\u7a7a\u884c\u5e76\u70b9\u51fb \u786e\u5b9a\uff0c\u8fd4\u56de\u503c\u662f\u7a7a\u5b57\u7b26\u4e32 ''\u3002\u5982\u679c\u6309\u4e0b\u4e86 \u53d6\u6d88 \u6309\u94ae\uff0c\u8fd4\u56de\u503c\u662f None\u3002\u5728 if \u8bed\u53e5\u4e2d\uff0c\u4e24\u8005\u90fd\u88ab\u89c6\u4e3a\u5047\u3002\u56e0\u6b64\uff0c\u53ea\u6709\u5f53 name \u5305\u542b\u4efb\u4f55\u6709\u610f\u4e49\u7684\u5185\u5bb9\u65f6\uff0cthen \u8bed\u53e5\u624d\u4f1a\u6267\u884c\uff0c\u5e76\u663e\u793a\u95ee\u5019\u8bed\"Hello, ...!\"\u3002\u5982\u679c\u8f93\u5165\u4e3a\u7a7a\uff0c\u7528\u6237\u5c06\u770b\u5230\"Hey! And you're not very polite, %Username%!\"\u6d88\u606f\u3002

      \u597d\u7684\uff0c\u8fd9\u662f\u6574\u4e2a\u7a0b\u5e8f\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nname = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\ndroid.makeToast(message)\n
      "},{"location":"tutorial-hello-world/#_3","title":"\u8fd0\u884c\u6548\u679c","text":""},{"location":"tutorial-hello-world/#_4","title":"\u4e0b\u4e00\u6b65","text":"

      \u5bf9\u4e8e Python \u65b0\u7528\u6237\uff0c\u63a8\u8350\u5b66\u4e60 Python \u8bed\u6cd5\u5b9e\u8df5 \u8bfe\u7a0b\u6765\u8fdb\u4e00\u6b65\u5b66\u4e60 Python\uff0c\u6216\u8005\u5728 QPython \u7cbe\u9009\u8bfe\u7a0b \u4e2d\u5bfb\u627e\u60f3\u8981\u5b66\u4e60\u7684\u5185\u5bb9\u3002

      "},{"location":"whats-new/","title":"\u66f4\u65b0\u65e5\u5fd7","text":""},{"location":"whats-new/#v392-v393","title":"v3.9.2 / v3.9.3","text":"
      • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
      • \u7f16\u8f91\u5668\u91cd\u5927\u66f4\u65b0\uff0c\u5e26\u6765\u66f4\u6d41\u7545\u7684\u7f16\u8f91\u4f53\u9a8c
      • \u5176\u4ed6\u5404\u79cd\u5c0f\u6539\u8fdb
      "},{"location":"whats-new/#v391","title":"v3.9.1","text":"
      • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
      • \u6269\u5c55\u5305\u73b0\u5728\u652f\u6301 MCP
      • \u9519\u8bef\u4fee\u590d
      "},{"location":"whats-new/#v390","title":"v3.9.0","text":"
      • SDK \u5347\u7ea7\uff0c\u6574\u5408\u6700\u65b0\u7684 Android \u529f\u80fd
      • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
      • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
      • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
      "},{"location":"whats-new/#v3811","title":"v3.8.11","text":"
      • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
      • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
      • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
      "},{"location":"whats-new/#v3810","title":"v3.8.10","text":"
      • \u5185\u7f6e Ollama \u5347\u7ea7\uff1a\u73b0\u5728\u60a8\u53ef\u4ee5\u5728 QPython \u4e2d\u8f7b\u677e\u672c\u5730\u8fd0\u884c Qwen3 / Gemma3 \u6a21\u578b\uff01
      • \u6dfb\u52a0\u4e86\u5f3a\u5927\u7684 MCP \u5e93\uff1a\u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 mcp \u5e93\uff0c\u8ba9\u60a8\u968f\u65f6\u968f\u5730\u643a\u5e26\u5f3a\u5927\u7684 MCP \u529f\u80fd\uff01
      "},{"location":"whats-new/#v389","title":"v3.8.9","text":"

      \u91cd\u5927\u66f4\u65b0\uff01AI \u7f16\u7a0b\u5b8c\u5168\u96c6\u6210\u5230 QPython\uff0c\u8ba9\u60a8\u7684\u7f16\u7a0b\u66f4\u8f7b\u677e\uff01

      • \u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u652f\u6301\uff1a\u65b0\u652f\u6301 AIPyApp\uff0c\u5728 QPython \u4e2d\u5b9e\u73b0\u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u3002\u76ee\u524d\u5904\u4e8e\u6d4b\u8bd5\u9636\u6bb5 - \u52a0\u5165\u6211\u4eec\u7684\u793e\u533a\u83b7\u53d6\u4f7f\u7528\u8bf4\u660e
      • \u65b0 QSL4A \u529f\u80fd\uff1a\u6dfb\u52a0 notebookOpen \u51fd\u6570\uff0c\u652f\u6301\u81ea\u7136\u8bed\u8a00\u63a7\u5236\u6253\u5f00 Notebook \u6587\u4ef6
      • \u5185\u7f6e\u7f16\u8f91\u5668\u5347\u7ea7\uff1a\u589e\u5f3a\u7f16\u8f91\u5668\u529f\u80fd\uff0c\u652f\u6301\u6253\u5f00\u548c\u6d4f\u89c8\u5404\u79cd\u6587\u672c\u6587\u4ef6
      • \u4fbf\u6377\u7684\u6587\u4ef6\u7ba1\u7406\uff1a\u5728\u6587\u4ef6\u7ba1\u7406\u5668\u4e2d\u6dfb\u52a0\u5185\u90e8\u5b58\u50a8\u5165\u53e3\uff0c\u5feb\u901f\u8bbf\u95ee\u60a8\u7684\u6587\u4ef6
      "},{"location":"whats-new/#v388","title":"v3.8.8","text":"
      • \u6587\u4ef6\u8bbf\u95ee\u6743\u9650\u63a7\u5236\u7684\u91cd\u8981\u6539\u8fdb\uff0c\u5141\u8bb8\u7528\u6237\u7075\u6d3b\u5730\u901a\u8fc7 QPython \u7f16\u7a0b\u542f\u7528\u6216\u7981\u7528\u5916\u90e8\u5b58\u50a8\u6587\u4ef6\u7684\u8bbf\u95ee
      • SDK \u5347\u7ea7\uff0c\u589e\u5f3a\u4e86\u5bf9\u65b0\u7248 Android \u7684\u652f\u6301\u548c\u517c\u5bb9\u6027
      • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Anthropic \u548c Google GenAI \u5e93
      "},{"location":"whats-new/#v387","title":"v3.8.7","text":"
      • \u5728\u73b0\u6709 Tkinter \u652f\u6301\u57fa\u7840\u4e0a\uff0c\u5728 Extensions -> Tools \u4e2d\u6dfb\u52a0\u4e86\u4f7f\u7528 Turtle \u7ed8\u5236\u54c6\u5566A\u68a6\u7684\u793a\u4f8b\u4ee3\u7801
      • \u4f18\u5316\u4e86\u624b\u673a\u6743\u9650\u83b7\u53d6\u6d41\u7a0b\uff0c\u63d0\u5347\u7528\u6237\u4f53\u9a8c\u548c\u64cd\u4f5c\u4fbf\u5229\u6027
      • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Google Gen AI \u5e93\uff0c\u65b9\u4fbf\u8bbf\u95ee Gemini Developer API \u548c Vertex AI
      "},{"location":"whats-new/#v386","title":"v3.8.6","text":"
      • Tkinter \u652f\u6301\uff1a\u73b0\u5728\u652f\u6301 Tkinter \u5e93\uff0c\u53ef\u901a\u8fc7 XServer \u8bbf\u95ee\u3002\u8bf7\u8bbf\u95ee www.qpython.org \u7684\u4e91\u76d8\"Extra\"\u94fe\u63a5\u4e0b\u8f7d\u6240\u9700\u6587\u4ef6
      • \u5b58\u50a8\u6743\u9650\u66f4\u65b0\uff1a\u4e3a\u6539\u5584\u7528\u6237\u4f53\u9a8c\uff0c\u6211\u4eec\u6dfb\u52a0\u4e86\u8bfb\u53d6\u624b\u673a\u5b58\u50a8\u7684\u6743\u9650\uff0c\u7528\u4e8e\u8bbf\u95ee\u5b58\u50a8\u5728\u5176\u4ed6\u76ee\u5f55\u4e2d\u7684 Python \u7a0b\u5e8f

      \u6b64\u66f4\u65b0\u540e\uff0cQPython \u548c QPythonPlus\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff0c\u4e13\u4e3a\u9700\u8981\u66f4\u591a\u654f\u611f\u6743\u9650\u7684\u9ad8\u7ea7\u7528\u6237\u8bbe\u8ba1\uff09\u5c06\u4fdd\u6301\u540c\u6b65\u7684\u7248\u672c\u53f7\u3002

      "},{"location":"whats-new/#v352-2025225","title":"v3.5.2 (2025/2/25)","text":"

      \u4e0e\u5f00\u6e90 LLM \u90e8\u7f72\u5de5\u5177 Ollama \u4ee5\u53ca DeepSeek \u5f00\u53d1\u7684 DeepSeek \u5b9e\u73b0\u65e0\u7f1d\u96c6\u6210\uff01

      \u529f\u80fd\uff1a - \u96f6\u95e8\u69db\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5404\u79cd\u5927\u578b\u8bed\u8a00\u6a21\u578b - \u5feb\u901f\u90e8\u7f72 DeepSeek \u7b49\u5c16\u7aef AI \u6a21\u578b - \u4eab\u53d7\u7b80\u7ea6\u7684 API \u8c03\u7528\u4f53\u9a8c - \u6784\u5efa\u5b8c\u5168\u79bb\u7ebf\u7684\u667a\u80fd\u7f16\u7a0b\u73af\u5883

      \u80fd\u529b\uff1a - \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u52a0\u8f7d/\u7ba1\u7406 LLM \u6a21\u578b - \u57fa\u4e8e\u672c\u5730\u8ba1\u7b97\u7684\u5b9e\u65f6\u4f4e\u5ef6\u8fdf\u54cd\u5e94

      "},{"location":"whats-new/#v350","title":"v3.5.0","text":"
      • Python \u5347\u7ea7\u5230 3.12.8
      • \u6539\u8fdb\u4eea\u8868\u76d8\uff0c\u529f\u80fd\u66f4\u6e05\u6670\u3001\u66f4\u4eba\u6027\u5316
      • \u6dfb\u52a0\u4e86\u4f17\u591a\u7b2c\u4e09\u65b9\u5305\uff1aPyTorch / Twisted / Scrapy / FastAPI ...
      "},{"location":"whats-new/#v338","title":"v3.3.8","text":"
      • \u4fee\u590d\u4e86 NumPy \u517c\u5bb9\u6027\u95ee\u9898
      "},{"location":"whats-new/#v335","title":"v3.3.5","text":"
      • \u5347\u7ea7 Python \u5185\u6838\u5230 3.11.9
      • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u4e0d\u663e\u793a\u6a21\u5757\u5b89\u88c5\u72b6\u6001\u7684 bug
      • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u5220\u9664\u6a21\u5757\u5931\u8d25\u7684 bug
      • \u4fee\u590d\u4e86\u5176\u4ed6 bug
      "},{"location":"whats-new/#v334","title":"v3.3.4","text":"
      • \u6dfb\u52a0\u4e86 OpenAI/Langchain/APIGPTCloud AI \u5305
      • \u79fb\u9664\u4e0d\u5fc5\u8981\u7684\u6587\u4ef6\u4ee5\u51cf\u5c11\u5927\u5c0f
      "},{"location":"whats-new/#v325","title":"v3.2.5","text":"
      • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570
      • \u5176\u4ed6\u9519\u8bef\u4fee\u590d
      "},{"location":"whats-new/#v323","title":"v3.2.3","text":"
      • \u66f4\u65b0 Python \u7248\u672c\u5230 3.11.0
      • \u66f4\u65b0 IPython \u7248\u672c\u5230 8.6.0
      • \u66f4\u65b0 pip \u7248\u672c\u5230 22.3.1
      • \u66f4\u65b0\u79d1\u5b66\u8ba1\u7b97\u5305\uff0c\u81ea\u52a8\u8f6f\u94fe\u63a5
      • \u51cf\u5c11\u7a7a\u95f4\u4f7f\u7528
      • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570 + \u5176\u4ed6\u9519\u8bef\u4fee\u590d
      "},{"location":"whats-new/#v318","title":"v3.1.8","text":"
      • \u5728\u7ec8\u7aef\u4e2d\u6dfb\u52a0\u4e86\u64cd\u4f5c\u70ed\u952e
      • \u4fee\u590d\u4e86\u7f16\u8f91\u5668\u5728\u65cb\u8f6c\u65f6\u4e22\u5931\u5185\u5bb9\u7684\u95ee\u9898
      • \u4fee\u590d\u4e86\u5176\u4ed6 bug

      \u5728 Google Play \u4e0b\u8f7d

      "},{"location":"qsl4a/","title":"QSL4A\uff08Android \u811a\u672c\u5c42\uff09API \u6587\u6863","text":"

      QSL4A \u662f QPython \u7684 Android \u811a\u672c\u5c42\uff0c\u5141\u8bb8\u60a8\u4f7f\u7528 Python \u63a7\u5236 Android \u8bbe\u5907\u529f\u80fd\u3002

      "},{"location":"qsl4a/#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a toast \u6d88\u606f\ndroid.makeToast('Hello QPython!')\n\n# \u9707\u52a8\u8bbe\u5907\ndroid.vibrate(500)\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\uff08\u5148\u5f00\u59cb\u76d1\u63a7\uff09\nimport time\ndroid.batteryStartMonitoring()\ntime.sleep(0.5)  # \u7b49\u5f85\u6570\u636e\nbattery = droid.readBatteryData().result\nprint(f\"\u7535\u6c60\uff1a{battery['level']}%\")\n
      "},{"location":"qsl4a/#_2","title":"\u6587\u6863\u7ed3\u6784","text":""},{"location":"qsl4a/#_3","title":"\u6838\u5fc3\u6a21\u5757","text":"
      • Android \u57fa\u7840 - \u6838\u5fc3\u8fde\u63a5\u548c RPC
      • Intent \u7cfb\u7edf - Android Intent \u64cd\u4f5c
      • \u4e8b\u4ef6\u7cfb\u7edf - \u4e8b\u4ef6\u5904\u7406\u548c\u5e7f\u64ad
      "},{"location":"qsl4a/#ui","title":"UI \u7ec4\u4ef6","text":"
      • \u5bf9\u8bdd\u6846 - \u8b66\u62a5\u3001\u8f93\u5165\u3001\u9009\u62e9\u5bf9\u8bdd\u6846
      • \u5168\u5c4f UI - \u81ea\u5b9a\u4e49\u5e03\u5c40 UI
      • \u60ac\u6d6e\u7a97 - \u60ac\u6d6e\u7a97\u53e3
      • \u8f85\u52a9\u529f\u80fd - \u5c4f\u5e55\u81ea\u52a8\u5316
      "},{"location":"qsl4a/#_4","title":"\u7cfb\u7edf","text":"
      • \u7535\u6c60 - \u7535\u6c60\u76d1\u63a7
      • \u4f20\u611f\u5668 - \u8bbe\u5907\u4f20\u611f\u5668
      • \u5e94\u7528 - \u5e94\u7528\u7ba1\u7406
      • \u7cfb\u7edf\u4fe1\u606f - \u8bbe\u5907\u4fe1\u606f
      • \u8bbe\u7f6e - \u7cfb\u7edf\u8bbe\u7f6e
      • \u5524\u9192\u9501 - \u5524\u9192\u9501\u63a7\u5236
      • QPython \u63a5\u53e3 - \u811a\u672c\u6267\u884c
      • Activity \u7ed3\u679c - Activity \u7ed3\u679c\u5904\u7406
      "},{"location":"qsl4a/#_5","title":"\u786c\u4ef6","text":"
      • \u84dd\u7259 - \u84dd\u7259\u64cd\u4f5c
      • \u76f8\u673a - \u62cd\u7167\u548c\u5f55\u50cf
      • \u97f3\u9891/\u5f55\u97f3\u5668 - \u5f55\u97f3
      • \u7f51\u7edc\u6444\u50cf\u5934 - MJPEG \u6d41
      • USB \u4e32\u53e3 - USB \u4e3b\u673a\u4e32\u53e3
      "},{"location":"qsl4a/#_6","title":"\u8fde\u63a5","text":"
      • WiFi - WiFi \u64cd\u4f5c
      • \u4f4d\u7f6e - GPS \u548c\u4f4d\u7f6e
      • \u77ed\u4fe1 - \u77ed\u4fe1\u64cd\u4f5c
      • \u7535\u8bdd - \u6253\u7535\u8bdd\u548c\u6765\u7535\u4fe1\u606f
      • \u8054\u7cfb\u4eba - \u8054\u7cfb\u4eba\u7ba1\u7406
      • \u4fe1\u53f7\u5f3a\u5ea6 - \u4fe1\u53f7\u76d1\u63a7
      • FTP \u670d\u52a1\u5668 - \u5185\u7f6e FTP \u670d\u52a1\u5668
      "},{"location":"qsl4a/#_7","title":"\u5b58\u50a8","text":"
      • DocumentFile - \u6587\u4ef6\u64cd\u4f5c
      • \u526a\u8d34\u677f - \u526a\u8d34\u677f\u64cd\u4f5c
      • \u504f\u597d\u8bbe\u7f6e - \u5171\u4eab\u504f\u597d\u8bbe\u7f6e
      "},{"location":"qsl4a/#_8","title":"\u5a92\u4f53","text":"
      • \u5a92\u4f53\u64ad\u653e\u5668 - \u97f3\u9891/\u89c6\u9891\u64ad\u653e
      • \u56fe\u50cf\u5904\u7406 - \u56fe\u50cf\u64cd\u4f5c
      "},{"location":"qsl4a/#_9","title":"\u7279\u6b8a\u529f\u80fd","text":"
      • \u52a0\u5bc6 - \u52a0\u5bc6/\u89e3\u5bc6
      • PGPT AI - AI \u8bed\u97f3\u670d\u52a1
      "},{"location":"qsl4a/#_10","title":"\u7ed3\u679c\u5bf9\u8c61","text":"

      \u5927\u591a\u6570 QSL4A \u65b9\u6cd5\u8fd4\u56de\u4e00\u4e2a\u5e26\u6709\u4ee5\u4e0b\u5c5e\u6027\u7684 Result \u547d\u540d\u5143\u7ec4\uff1a - id - \u8bf7\u6c42 ID - result - \u5b9e\u9645\u7ed3\u679c\u6570\u636e - error - \u5982\u679c\u5931\u8d25\u5219\u4e3a\u9519\u8bef\u6d88\u606f

      result = droid.getClipboard()\nif result.error is None:\n    print(result.result)\nelse:\n    print(f\"\u9519\u8bef\uff1a{result.error}\")\n
      "},{"location":"qsl4a/connectivity/contacts/","title":"\u8054\u7cfb\u4eba API","text":"

      \u8bbf\u95ee\u548c\u7ba1\u7406\u8bbe\u5907\u8054\u7cfb\u4eba\u3002

      "},{"location":"qsl4a/connectivity/contacts/#_1","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":""},{"location":"qsl4a/connectivity/contacts/#pickcontact","title":"pickContact()","text":"

      \u663e\u793a\u8054\u7cfb\u4eba\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

      pickContact()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u8054\u7cfb\u4eba URI \u7684 Intent

      "},{"location":"qsl4a/connectivity/contacts/#pickphone","title":"pickPhone()","text":"

      \u663e\u793a\u7535\u8bdd\u53f7\u7801\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

      pickPhone()\n

      \u8fd4\u56de\uff1a \u9009\u4e2d\u7684\u7535\u8bdd\u53f7\u7801\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/contacts/#_2","title":"\u8054\u7cfb\u4eba\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#contactsget","title":"contactsGet()","text":"

      \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\u3002

      contactsGet(attributes=None)\n

      \u53c2\u6570\uff1a - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

      \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba JSONObject \u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetbyid","title":"contactsGetById()","text":"

      \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\u3002

      contactsGetById(id, attributes=None)\n

      \u53c2\u6570\uff1a - id (int): \u8054\u7cfb\u4eba ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

      \u8fd4\u56de\uff1a JSONObject \u8054\u7cfb\u4eba\u6570\u636e

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetcount","title":"contactsGetCount()","text":"

      \u83b7\u53d6\u8054\u7cfb\u4eba\u603b\u6570\u3002

      contactsGetCount()\n

      \u8fd4\u56de\uff1a \u6574\u6570\u8ba1\u6570

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetids","title":"contactsGetIds()","text":"

      \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba ID\u3002

      contactsGetIds()\n

      \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba ID \u6574\u6570\u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetattributes","title":"contactsGetAttributes()","text":"

      \u83b7\u53d6\u6240\u6709\u53ef\u80fd\u7684\u8054\u7cfb\u4eba\u5c5e\u6027\u3002

      contactsGetAttributes()\n

      \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#_3","title":"\u5185\u5bb9\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#querycontent","title":"queryContent()","text":"

      \u4f7f\u7528\u81ea\u5b9a\u4e49\u53c2\u6570\u67e5\u8be2\u5185\u5bb9\u89e3\u6790\u5668\u3002

      queryContent(uri, attributes=None, selection=None, selectionArgs=None, order=None)\n

      \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u5c5e\u6027 - selection (str, optional): WHERE \u5b50\u53e5 - selectionArgs (list, optional): \u9009\u62e9\u53c2\u6570 - order (str, optional): ORDER BY \u5b50\u53e5

      \u8fd4\u56de\uff1a JSONObject \u7ed3\u679c\u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#queryattributes","title":"queryAttributes()","text":"

      \u83b7\u53d6\u5185\u5bb9 URI \u7684\u5c5e\u6027\u3002

      queryAttributes(uri)\n

      \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI

      \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u7684 JSONArray

      "},{"location":"qsl4a/connectivity/contacts/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u9009\u62e9\u8054\u7cfb\u4eba\ncontact_uri = droid.pickContact().result\nprint(f\"Selected contact: {contact_uri}\")\n\n# \u9009\u62e9\u7535\u8bdd\u53f7\u7801\nphone = droid.pickPhone().result\nprint(f\"Selected phone: {phone}\")\n\n# \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\ncontacts = droid.contactsGet().result\nprint(f\"Total contacts: {len(contacts)}\")\n\n# \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\ncontact = droid.contactsGetById(1).result\nprint(f\"Contact: {contact}\")\n\n# \u83b7\u53d6\u8054\u7cfb\u4eba\u5c5e\u6027\nattrs = droid.contactsGetAttributes().result\nprint(f\"Available attributes: {attrs}\")\n
      "},{"location":"qsl4a/connectivity/ftp/","title":"FTP \u670d\u52a1\u5668 API","text":"

      \u5728\u8bbe\u5907\u4e0a\u542f\u52a8\u548c\u7ba1\u7406\u5185\u7f6e FTP \u670d\u52a1\u5668\u3002

      "},{"location":"qsl4a/connectivity/ftp/#ftp","title":"FTP \u670d\u52a1\u5668\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/ftp/#ftpstart","title":"ftpStart()","text":"

      \u542f\u52a8 FTP \u670d\u52a1\u5668\u3002

      ftpStart()\n

      \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4 [ip, port]

      "},{"location":"qsl4a/connectivity/ftp/#ftpstop","title":"ftpStop()","text":"

      \u505c\u6b62 FTP \u670d\u52a1\u5668\u3002

      ftpStop()\n
      "},{"location":"qsl4a/connectivity/ftp/#ftpisrunning","title":"ftpIsRunning()","text":"

      \u68c0\u67e5 FTP \u670d\u52a1\u5668\u662f\u5426\u6b63\u5728\u8fd0\u884c\u3002

      ftpIsRunning()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u8fd0\u884c\u5219\u4e3a True

      "},{"location":"qsl4a/connectivity/ftp/#ftpget","title":"ftpGet()","text":"

      \u83b7\u53d6 FTP \u670d\u52a1\u5668 IP \u5730\u5740\u3002

      ftpGet()\n

      \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4

      "},{"location":"qsl4a/connectivity/ftp/#ftpset","title":"ftpSet()","text":"

      \u914d\u7f6e FTP \u670d\u52a1\u5668\u8bbe\u7f6e\u3002

      ftpSet(port=None, rootDir=None, username=None, password=None)\n

      \u53c2\u6570\uff1a - port (int, optional): \u670d\u52a1\u5668\u7aef\u53e3 - rootDir (str, optional): \u8981\u670d\u52a1\u7684\u57fa\u7840\u76ee\u5f55 - username (str, optional): \u767b\u5f55\u7528\u6237\u540d - password (str, optional): \u767b\u5f55\u5bc6\u7801

      \u8fd4\u56de\uff1a \u5305\u542b\u5f53\u524d\u8bbe\u7f6e\u7684 JSONObject

      "},{"location":"qsl4a/connectivity/ftp/#ftpstatus","title":"ftpStatus()","text":"

      \u83b7\u53d6 FTP \u670d\u52a1\u5668\u72b6\u6001\u3002

      ftpStatus()\n

      \u8fd4\u56de\uff1a \u72b6\u6001\u63cf\u8ff0\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/ftp/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u914d\u7f6e FTP \u670d\u52a1\u5668\ndroid.ftpSet(\n    port=2121,\n    rootDir=\"/sdcard\",\n    username=\"admin\",\n    password=\"secret\"\n)\n\n# \u542f\u52a8 FTP \u670d\u52a1\u5668\ninfo = droid.ftpStart().result\nprint(f\"FTP running at {info[0]}:{info[1]}\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.ftpIsRunning().result:\n    print(\"FTP server is running\")\n\n# \u83b7\u53d6\u670d\u52a1\u5668\u4fe1\u606f\nserver_info = droid.ftpGet().result\nprint(f\"Server: {server_info}\")\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.ftpStop()\n

      \u6ce8\u610f\uff1a \u4f7f\u7528\u63d0\u4f9b\u7684\u51ed\u636e\u901a\u8fc7\u4efb\u4f55 FTP \u5ba2\u6237\u7aef\u8fde\u63a5\u5230 FTP \u670d\u52a1\u5668\u3002

      "},{"location":"qsl4a/connectivity/location/","title":"\u4f4d\u7f6e API","text":"

      \u8bbf\u95ee GPS \u548c\u7f51\u7edc\u4f4d\u7f6e\u670d\u52a1\u3002

      "},{"location":"qsl4a/connectivity/location/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/location/#startlocating","title":"startLocating()","text":"

      \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\u3002

      startLocating(minUpdateTime=60000, minUpdateDistance=30, updateGnssStatus=False)\n

      \u53c2\u6570\uff1a - minUpdateTime (int): \u66f4\u65b0\u4e4b\u95f4\u7684\u6700\u5c0f\u65f6\u95f4\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a60000\uff09 - minUpdateDistance (float): \u66f4\u65b0\u7684\u6700\u5c0f\u8ddd\u79bb\uff08\u7c73\uff09\uff08\u9ed8\u8ba4\uff1a30\uff09 - updateGnssStatus (bool): \u542f\u7528 GNSS \u72b6\u6001\u66f4\u65b0\uff08\u9ed8\u8ba4\uff1aFalse\uff09

      "},{"location":"qsl4a/connectivity/location/#stoplocating","title":"stopLocating()","text":"

      \u505c\u6b62\u4f4d\u7f6e\u66f4\u65b0\u3002

      stopLocating()\n
      "},{"location":"qsl4a/connectivity/location/#readlocation","title":"readLocation()","text":"

      \u83b7\u53d6\u6700\u540e\u5df2\u77e5\u4f4d\u7f6e\u3002

      readLocation()\n

      \u8fd4\u56de\uff1a \u4f4d\u7f6e\u6570\u636e\u5b57\u5178

      "},{"location":"qsl4a/connectivity/location/#getlastknownlocation","title":"getLastKnownLocation()","text":"

      \u83b7\u53d6\u7f13\u5b58\u7684\u4f4d\u7f6e\u3002

      getLastKnownLocation()\n

      \u8fd4\u56de\uff1a \u6765\u81ea\u6240\u6709\u63d0\u4f9b\u5546\u7684\u4f4d\u7f6e

      "},{"location":"qsl4a/connectivity/location/#geocode","title":"geocode()","text":"

      \u5c06\u5730\u5740\u8f6c\u6362\u4e3a\u5750\u6807\u3002

      geocode(address, maxResults=1)\n
      "},{"location":"qsl4a/connectivity/location/#_2","title":"\u4f4d\u7f6e\u63d0\u4f9b\u5546\u65b9\u6cd5)","text":""},{"location":"qsl4a/connectivity/location/#locationproviders","title":"locationProviders()","text":"

      \u83b7\u53d6\u624b\u673a\u4e0a\u53ef\u7528\u7684\u4f4d\u7f6e\u63d0\u4f9b\u5546\u3002

      locationProviders()\n

      \u8fd4\u56de\uff1a \u53ef\u7528\u63d0\u4f9b\u5546\u540d\u79f0\u5217\u8868\uff08\u4f8b\u5982 ['gps', 'network']\uff09

      "},{"location":"qsl4a/connectivity/location/#locationproviderenabled","title":"locationProviderEnabled()","text":"

      \u68c0\u67e5\u7279\u5b9a\u4f4d\u7f6e\u63d0\u4f9b\u5546\u662f\u5426\u5df2\u542f\u7528\u3002

      locationProviderEnabled(provider)\n

      \u53c2\u6570\uff1a - provider (str): \u63d0\u4f9b\u5546\u540d\u79f0\uff08\u4f8b\u5982 'gps', 'network'\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/connectivity/location/#readgnssstatus","title":"readGnssStatus()","text":"

      \u8bfb\u53d6\u5168\u7403\u5bfc\u822a\u536b\u661f\u7cfb\u7edf\u72b6\u6001\uff08\u9700\u8981 Android 8+\uff09\u3002

      readGnssStatus()\n

      \u8fd4\u56de\uff1a \u5305\u542b GNSS \u536b\u661f\u4fe1\u606f\u7684 JSONArray

      "},{"location":"qsl4a/connectivity/location/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\ndroid.startLocating(minUpdateTime=5000, minUpdateDistance=1, updateGnssStatus=False)\n\n# \u7b49\u5f85\u5b9a\u4f4d\ntime.sleep(10)\n\n# \u83b7\u53d6\u4f4d\u7f6e\nloc = droid.readLocation().result\nif loc:\n    lat = loc['latitude']\n    lon = loc['longitude']\n    print(f\"Location: {lat}, {lon}\")\n\ndroid.stopLocating()\n
      "},{"location":"qsl4a/connectivity/phone/","title":"\u7535\u8bdd API","text":"

      \u63a7\u5236\u7535\u8bdd\u901a\u8bdd\u548c\u83b7\u53d6\u7535\u8bdd\u4fe1\u606f\u3002

      "},{"location":"qsl4a/connectivity/phone/#_1","title":"\u7535\u8bdd\u72b6\u6001\u8ddf\u8e2a","text":""},{"location":"qsl4a/connectivity/phone/#starttrackingphonestate","title":"startTrackingPhoneState()","text":"

      \u5f00\u59cb\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u53d8\u5316\u3002\u751f\u6210 'phone' \u4e8b\u4ef6\u3002

      startTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/phone/#readphonestate","title":"readPhoneState()","text":"

      \u8bfb\u53d6\u5f53\u524d\u7535\u8bdd\u72b6\u6001\u3002

      readPhoneState()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7535\u8bdd\u72b6\u6001\u548c\u6765\u7535\u53f7\u7801\u7684 Bundle

      "},{"location":"qsl4a/connectivity/phone/#stoptrackingphonestate","title":"stopTrackingPhoneState()","text":"

      \u505c\u6b62\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u3002

      stopTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/phone/#_2","title":"\u62e8\u6253\u7535\u8bdd","text":""},{"location":"qsl4a/connectivity/phone/#phonecall","title":"phoneCall()","text":"

      \u901a\u8fc7 URI \u547c\u53eb\u8054\u7cfb\u4eba/\u7535\u8bdd\u53f7\u7801\u3002

      phoneCall(uri)\n

      \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

      "},{"location":"qsl4a/connectivity/phone/#phonecallnumber","title":"phoneCallNumber()","text":"

      \u76f4\u63a5\u62e8\u6253\u7535\u8bdd\u53f7\u7801\u3002

      phoneCallNumber(phone_number)\n

      \u53c2\u6570\uff1a - phone_number (str): \u8981\u62e8\u6253\u7684\u7535\u8bdd\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#phonedial","title":"phoneDial()","text":"

      \u62e8\u6253\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

      phoneDial(uri)\n

      \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

      "},{"location":"qsl4a/connectivity/phone/#phonedialnumber","title":"phoneDialNumber()","text":"

      \u62e8\u6253\u7535\u8bdd\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

      phoneDialNumber(phone_number)\n

      \u53c2\u6570\uff1a - phone_number (str): \u7535\u8bdd\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#_3","title":"\u57fa\u7ad9\u4f4d\u7f6e","text":""},{"location":"qsl4a/connectivity/phone/#getcelllocation","title":"getCellLocation()","text":"

      \u83b7\u53d6\u5f53\u524d\u57fa\u7ad9\u4f4d\u7f6e\u3002

      getCellLocation()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u57fa\u7ad9\u4f4d\u7f6e\u6570\u636e\u7684 JSONObject

      "},{"location":"qsl4a/connectivity/phone/#getallcellslocation","title":"getAllCellsLocation()","text":"

      \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u4f4d\u7f6e\uff08\u9002\u7528\u4e8e\u53cc\u5361\u8bbe\u5907\uff09\u3002

      getAllCellsLocation()\n

      \u8fd4\u56de\uff1a \u57fa\u7ad9\u4f4d\u7f6e\u7684 JSONArray

      "},{"location":"qsl4a/connectivity/phone/#_4","title":"\u7f51\u7edc\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getnetworkoperator","title":"getNetworkOperator()","text":"

      \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

      getNetworkOperator()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getnetworkoperatorname","title":"getNetworkOperatorName()","text":"

      \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684\u540d\u79f0\u3002

      getNetworkOperatorName()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getnetworktype","title":"getNetworkType()","text":"

      \u83b7\u53d6\u5f53\u524d\u7f51\u7edc\u7c7b\u578b\u3002

      getNetworkType()\n

      \u8fd4\u56de\uff1a \u63cf\u8ff0\u65e0\u7ebf\u7535\u6280\u672f\u7684\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'LTE', 'UMTS', 'GSM'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getphonetype","title":"getPhoneType()","text":"

      \u83b7\u53d6\u7535\u8bdd\u7c7b\u578b\u3002

      getPhoneType()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'GSM', 'CDMA', 'SIP'\uff09

      "},{"location":"qsl4a/connectivity/phone/#sim","title":"SIM \u5361\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getsimcountryiso","title":"getSimCountryIso()","text":"

      \u83b7\u53d6 SIM \u5361\u7684 ISO \u56fd\u5bb6\u4ee3\u7801\u3002

      getSimCountryIso()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'us'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getsimoperator","title":"getSimOperator()","text":"

      \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

      getSimOperator()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getsimoperatorname","title":"getSimOperatorName()","text":"

      \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u540d\u79f0\u3002

      getSimOperatorName()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getsimserialnumber","title":"getSimSerialNumber()","text":"

      \u83b7\u53d6 SIM \u5e8f\u5217\u53f7\u3002

      getSimSerialNumber()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32 SIM \u5e8f\u5217\u53f7

      "},{"location":"qsl4a/connectivity/phone/#getsimstate","title":"getSimState()","text":"

      \u83b7\u53d6 SIM \u5361\u72b6\u6001\u3002

      getSimState()\n

      \u8fd4\u56de\uff1a \u63cf\u8ff0 SIM \u72b6\u6001\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/phone/#getsubscriberid","title":"getSubscriberId()","text":"

      \u83b7\u53d6\u8ba2\u9605\u8005 ID\u3002

      getSubscriberId()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8ba2\u9605\u8005 ID

      "},{"location":"qsl4a/connectivity/phone/#_5","title":"\u8bed\u97f3\u90ae\u4ef6","text":""},{"location":"qsl4a/connectivity/phone/#getvoicemailalphatag","title":"getVoiceMailAlphaTag()","text":"

      \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u5b57\u6bcd\u6807\u7b7e\u3002

      getVoiceMailAlphaTag()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u6807\u7b7e

      "},{"location":"qsl4a/connectivity/phone/#getvoicemailnumber","title":"getVoiceMailNumber()","text":"

      \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801\u3002

      getVoiceMailNumber()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getdeviceid","title":"getDeviceId()","text":"

      \u83b7\u53d6\u8bbe\u5907 ID\uff08GSM \u7684 IMEI\uff09\u3002\u5df2\u5e9f\u5f03\u3002

      getDeviceId()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

      "},{"location":"qsl4a/connectivity/phone/#getdevicesoftwareversion","title":"getDeviceSoftwareVersion()","text":"

      \u83b7\u53d6\u8bbe\u5907\u8f6f\u4ef6\u7248\u672c\u3002

      getDeviceSoftwareVersion()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8f6f\u4ef6\u7248\u672c

      "},{"location":"qsl4a/connectivity/phone/#getline1number","title":"getLine1Number()","text":"

      \u83b7\u53d6\u7ebf\u8def 1 \u7535\u8bdd\u53f7\u7801\u3002

      getLine1Number()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u7535\u8bdd\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#checknetworkroaming","title":"checkNetworkRoaming()","text":"

      \u68c0\u67e5\u662f\u5426\u8fde\u63a5\u5230\u6f2b\u6e38\u7f51\u7edc\u3002

      checkNetworkRoaming()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u6f2b\u6e38\u5219\u4e3a True

      "},{"location":"qsl4a/connectivity/phone/#_7","title":"\u57fa\u7ad9\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getallcellinfo","title":"getAllCellInfo()","text":"

      \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u7684\u4fe1\u606f\u3002

      getAllCellInfo()\n

      \u8fd4\u56de\uff1a \u57fa\u7ad9\u4fe1\u606f\u5217\u8868

      "},{"location":"qsl4a/connectivity/phone/#setdataenabled","title":"setDataEnabled()","text":"

      \u542f\u7528\u6216\u7981\u7528\u79fb\u52a8\u6570\u636e\u3002

      setDataEnabled(enabled)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528

      "},{"location":"qsl4a/connectivity/phone/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7f51\u7edc\u4fe1\u606f\noperator = droid.getNetworkOperatorName().result\nprint(f\"Operator: {operator}\")\n\nnetwork_type = droid.getNetworkType().result\nprint(f\"Network: {network_type}\")\n\n# \u83b7\u53d6 SIM \u4fe1\u606f\nsim_state = droid.getSimState().result\nprint(f\"SIM: {sim_state}\")\n\n# \u83b7\u53d6\u7535\u8bdd\u53f7\u7801\nline1 = droid.getLine1Number().result\nprint(f\"Phone: {line1}\")\n\n# \u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\ndroid.startTrackingPhoneState()\nprint(\"Tracking phone state...\")\ndroid.stopTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/signalstrength/","title":"\u4fe1\u53f7\u5f3a\u5ea6 API","text":"

      \u76d1\u63a7\u8702\u7a9d\u548c\u65e0\u7ebf\u4fe1\u53f7\u5f3a\u5ea6\u3002

      "},{"location":"qsl4a/connectivity/signalstrength/#_1","title":"\u4fe1\u53f7\u5f3a\u5ea6\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/signalstrength/#starttrackingsignalstrengths","title":"startTrackingSignalStrengths()","text":"

      \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316\u3002\u751f\u6210 'signal_strengths' \u4e8b\u4ef6\u3002

      startTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/signalstrength/#stoptrackingsignalstrengths","title":"stopTrackingSignalStrengths()","text":"

      \u505c\u6b62\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u3002

      stopTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/signalstrength/#readsignalstrengths","title":"readSignalStrengths()","text":"

      \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\u3002

      readSignalStrengths()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u4fe1\u53f7\u5f3a\u5ea6\u6570\u636e\u7684 Bundle

      "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthlevel","title":"getTelephoneSignalStrengthLevel()","text":"

      \u83b7\u53d6\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u7b49\u7ea7\uff080-4\uff09\u3002

      getTelephoneSignalStrengthLevel()\n

      \u8fd4\u56de\uff1a \u6574\u6570\u7b49\u7ea7\uff080=\u65e0\uff0c1=\u5dee\uff0c2=\u4e00\u822c\uff0c3=\u597d\uff0c4=\u4f18\u79c0\uff09

      "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthdetail","title":"getTelephoneSignalStrengthDetail()","text":"

      \u83b7\u53d6\u8be6\u7ec6\u7684\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u4fe1\u606f\u3002

      getTelephoneSignalStrengthDetail()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u8be6\u7ec6\u4fe1\u53f7\u4fe1\u606f\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/signalstrength/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\ndroid.startTrackingSignalStrengths()\n\n# \u7b49\u5f85\u4fe1\u53f7\u66f4\u65b0\ntime.sleep(5)\n\n# \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\nsignal = droid.readSignalStrengths().result\nprint(f\"Signal: {signal}\")\n\n# \u76f4\u63a5\u83b7\u53d6\u7b49\u7ea7\nlevel = droid.getTelephoneSignalStrengthLevel().result\nprint(f\"Signal level: {level}/4\")\n\ndroid.stopTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/sms/","title":"SMS API","text":"

      \u53d1\u9001\u548c\u63a5\u6536 SMS \u6d88\u606f\u3002

      "},{"location":"qsl4a/connectivity/sms/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/sms/#smssend","title":"smsSend()","text":"

      \u53d1\u9001 SMS \u6d88\u606f\u3002

      smsSend(destinationAddress, text)\n

      \u53c2\u6570\uff1a - destinationAddress (str): \u7535\u8bdd\u53f7\u7801 - text (str): \u6d88\u606f\u6587\u672c

      "},{"location":"qsl4a/connectivity/sms/#smsgetmessagecount","title":"smsGetMessageCount()","text":"

      \u83b7\u53d6\u6d88\u606f\u6570\u91cf\u3002

      smsGetMessageCount(unreadOnly=False, folder=\"inbox\")\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessageids","title":"smsGetMessageIds()","text":"

      \u83b7\u53d6\u6d88\u606f ID\u3002

      smsGetMessageIds(unreadOnly=False, folder=\"inbox\")\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessages","title":"smsGetMessages()","text":"

      \u83b7\u53d6\u6d88\u606f\u8be6\u60c5\u3002

      smsGetMessages(unreadOnly=False, folder=\"inbox\", attributes=None)\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessagebyid","title":"smsGetMessageById()","text":"

      \u901a\u8fc7 ID \u83b7\u53d6\u7279\u5b9a\u6d88\u606f\u3002

      smsGetMessageById(id, attributes=None)\n

      \u53c2\u6570\uff1a - id (int): \u6d88\u606f ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

      \u8fd4\u56de\uff1a \u6d88\u606f\u6570\u636e\u5b57\u5178

      "},{"location":"qsl4a/connectivity/sms/#smsgetattributes","title":"smsGetAttributes()","text":"

      \u83b7\u53d6\u53ef\u7528\u7684 SMS \u6d88\u606f\u5c5e\u6027\u3002

      smsGetAttributes()\n

      \u8fd4\u56de\uff1a \u53ef\u7528\u5c5e\u6027\u540d\u79f0\u5217\u8868

      "},{"location":"qsl4a/connectivity/sms/#smsdeletemessage","title":"smsDeleteMessage()","text":"

      \u5220\u9664\u6d88\u606f\u3002

      smsDeleteMessage(id)\n
      "},{"location":"qsl4a/connectivity/sms/#smsmarkmessageread","title":"smsMarkMessageRead()","text":"

      \u5c06\u6d88\u606f\u6807\u8bb0\u4e3a\u5df2\u8bfb\u3002

      smsMarkMessageRead(ids, read=True)\n
      "},{"location":"qsl4a/connectivity/sms/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u53d1\u9001 SMS\ndroid.smsSend(\"+1234567890\", \"Hello from QPython!\")\n\n# \u83b7\u53d6\u672a\u8bfb\u6d88\u606f\nmessages = droid.smsGetMessages(unreadOnly=True).result\nfor msg in messages:\n    print(f\"From: {msg['address']}, Text: {msg['body']}\")\n
      "},{"location":"qsl4a/connectivity/wifi/","title":"WiFi API","text":"

      \u63a7\u5236 WiFi \u9002\u914d\u5668\u5e76\u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\u3002

      "},{"location":"qsl4a/connectivity/wifi/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/connectivity/wifi/#checkwifistate","title":"checkWifiState()","text":"

      \u68c0\u67e5 WiFi \u662f\u5426\u5df2\u542f\u7528\u3002

      checkWifiState()\n

      \u8fd4\u56de\uff1a \u5982\u679c WiFi \u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/connectivity/wifi/#togglewifistate","title":"toggleWifiState()","text":"

      \u6253\u5f00\u6216\u5173\u95ed WiFi\u3002

      toggleWifiState(enabled=None)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

      \u8fd4\u56de\uff1a \u5982\u679c\u64cd\u4f5c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/connectivity/wifi/#wifistartscan","title":"wifiStartScan()","text":"

      \u5f00\u59cb\u626b\u63cf\u53ef\u7528\u7684 WiFi \u7f51\u7edc\u3002

      wifiStartScan()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifigetscanresults","title":"wifiGetScanResults()","text":"

      \u83b7\u53d6\u53d1\u73b0\u7684 WiFi \u7f51\u7edc\u5217\u8868\u3002

      wifiGetScanResults()\n

      \u8fd4\u56de\uff1a \u63a5\u5165\u70b9\u4fe1\u606f\u5217\u8868

      "},{"location":"qsl4a/connectivity/wifi/#_2","title":"\u8fde\u63a5\u7ba1\u7406","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetconnectioninfo","title":"wifiGetConnectionInfo()","text":"

      \u83b7\u53d6\u8be6\u7ec6\u8fde\u63a5\u4fe1\u606f\u3002

      wifiGetConnectionInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001IP \u5730\u5740\u7b49\u8fde\u63a5\u8be6\u60c5\u7684\u5b57\u5178

      "},{"location":"qsl4a/connectivity/wifi/#getconnectedinfo","title":"getConnectedInfo()","text":"

      \u83b7\u53d6\u8fde\u63a5\u7684 WiFi \u7f51\u7edc\u4fe1\u606f\uff08\u7b80\u5316\u7248\uff09\u3002

      getConnectedInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001\u4fe1\u53f7\u5f3a\u5ea6\u7684\u5b57\u5178

      "},{"location":"qsl4a/connectivity/wifi/#getdhcpinfo","title":"getDhcpInfo()","text":"

      \u83b7\u53d6\u5f53\u524d\u8fde\u63a5\u7684 DHCP \u4fe1\u606f\u3002

      getDhcpInfo(ipConvertToString=True)\n

      \u53c2\u6570\uff1a - ipConvertToString (bool): \u5c06 IP \u5730\u5740\u8f6c\u6362\u4e3a\u5b57\u7b26\u4e32\u683c\u5f0f\uff08\u9ed8\u8ba4\uff1aTrue\uff09

      \u8fd4\u56de\uff1a \u5305\u542b IP\u3001\u7f51\u5173\u3001DNS \u7b49 DHCP \u4fe1\u606f\u7684\u5b57\u5178

      "},{"location":"qsl4a/connectivity/wifi/#wifidisconnect","title":"wifiDisconnect()","text":"

      \u65ad\u5f00\u5f53\u524d WiFi \u7f51\u7edc\u8fde\u63a5\u3002

      wifiDisconnect()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifireconnect","title":"wifiReconnect()","text":"

      \u91cd\u65b0\u8fde\u63a5\u5230\u5f53\u524d\u7f51\u7edc\u3002

      wifiReconnect()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifireassociate","title":"wifiReassociate()","text":"

      \u91cd\u65b0\u5173\u8054\u5f53\u524d\u63a5\u5165\u70b9\u3002

      wifiReassociate()\n
      "},{"location":"qsl4a/connectivity/wifi/#_3","title":"\u70ed\u70b9","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetapstate","title":"wifiGetApState()","text":"

      \u83b7\u53d6 WiFi AP\uff08\u70ed\u70b9\uff09\u72b6\u6001\u3002

      wifiGetApState()\n

      \u8fd4\u56de\uff1a \u70ed\u70b9\u72b6\u6001

      "},{"location":"qsl4a/connectivity/wifi/#wifi","title":"WiFi \u9501","text":""},{"location":"qsl4a/connectivity/wifi/#wifilockacquirefull","title":"wifiLockAcquireFull()","text":"

      \u83b7\u53d6\u5b8c\u6574 WiFi \u9501\uff08\u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\u4e5f\u4fdd\u6301 WiFi \u6d3b\u52a8\uff09\u3002

      wifiLockAcquireFull()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifilockacquirescanonly","title":"wifiLockAcquireScanOnly()","text":"

      \u83b7\u53d6\u4ec5\u626b\u63cf WiFi \u9501\u3002

      wifiLockAcquireScanOnly()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifilockrelease","title":"wifiLockRelease()","text":"

      \u91ca\u653e WiFi \u9501\u3002

      wifiLockRelease()\n
      "},{"location":"qsl4a/connectivity/wifi/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u68c0\u67e5 WiFi \u72b6\u6001\nif droid.checkWifiState().result:\n    print(\"WiFi is enabled\")\nelse:\n    print(\"Enabling WiFi...\")\n    droid.toggleWifiState(True)\n    time.sleep(2)\n\n# \u5f00\u59cb\u626b\u63cf\ndroid.wifiStartScan()\ntime.sleep(3)\n\n# \u83b7\u53d6\u626b\u63cf\u7ed3\u679c\nnetworks = droid.wifiGetScanResults().result\nfor network in networks:\n    print(f\"SSID: {network.get('SSID')}, Signal: {network.get('level')} dBm\")\n\n# \u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\ninfo = droid.wifiGetConnectionInfo().result\nif info:\n    print(f\"Connected to: {info.get('ssid')}\")\n    print(f\"BSSID: {info.get('bssid')}\")\n    print(f\"IP: {info.get('ip_address')}\")\n\n# \u83b7\u53d6 DHCP \u4fe1\u606f\ndhcp = droid.getDhcpInfo().result\nif dhcp:\n    print(f\"Gateway: {dhcp.get('gateway')}\")\n    print(f\"DNS: {dhcp.get('dns1')}\")\n\n# \u83b7\u53d6\u7b80\u5316\u7684\u8fde\u63a5\u4fe1\u606f\nconnected = droid.getConnectedInfo().result\nprint(f\"SSID: {connected.get('ssid')}, Signal: {connected.get('level')} dBm\")\n\n# \u65ad\u5f00\u5e76\u91cd\u65b0\u8fde\u63a5\ndroid.wifiDisconnect()\ntime.sleep(1)\ndroid.wifiReconnect()\n\n# \u91cd\u65b0\u5173\u8054\u63a5\u5165\u70b9\ndroid.wifiReassociate()\n\n# \u68c0\u67e5\u70ed\u70b9\u72b6\u6001\nap_state = droid.wifiGetApState().result\nprint(f\"Hotspot state: {ap_state}\")\n\n# \u83b7\u53d6 WiFi \u9501\u4ee5\u8fdb\u884c\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireFull()\n# ... \u6267\u884c\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n\n# \u6216\u4f7f\u7528\u4ec5\u626b\u63cf\u9501\u4ee5\u8fdb\u884c\u8f83\u8f7b\u7684\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireScanOnly()\n# ... \u6267\u884c\u626b\u63cf\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n
      "},{"location":"qsl4a/core/android-base/","title":"Android \u57fa\u7840\u7c7b","text":"

      Android \u7c7b\u662f QSL4A \u7684\u6838\u5fc3\uff0c\u63d0\u4f9b\u4e86\u4e0e Android \u8fd0\u884c\u65f6\u7684\u8fde\u63a5\u548c RPC \u673a\u5236\u3002

      "},{"location":"qsl4a/core/android-base/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
      # \u529f\u80fd\u5b8c\u6574\u7248\u672c\uff08\u63a8\u8350\uff09\nimport androidhelper\ndroid = androidhelper.Android()\n\n# \u7b80\u5316\u7248\u672c\uff08\u5feb\u901f\uff0c\u5355\u5b9e\u4f8b\uff09\nimport android\ndroid = android.droid\n
      "},{"location":"qsl4a/core/android-base/#android_1","title":"\u7c7b\uff1aAndroid","text":""},{"location":"qsl4a/core/android-base/#_2","title":"\u6784\u9020\u51fd\u6570","text":"
      Android(addr=None)\n

      \u53c2\u6570\uff1a - addr (tuple, optional): (HOST, PORT) \u5730\u5740\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u73af\u5883\u53d8\u91cf AP_HOST \u548c AP_PORT

      \u73af\u5883\u53d8\u91cf\uff1a - AP_HOST - \u670d\u52a1\u5668\u4e3b\u673a\u5730\u5740 - AP_PORT - \u670d\u52a1\u5668\u7aef\u53e3 - AP_HANDSHAKE - \u8ba4\u8bc1\u4ee4\u724c

      "},{"location":"qsl4a/core/android-base/#_3","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/android-base/#_rpc","title":"_rpc()","text":"

      \u8c03\u7528 Android \u51fd\u6570\u7684\u5185\u90e8 RPC \u65b9\u6cd5\u3002

      _rpc(method, *args)\n

      \u53c2\u6570\uff1a - method (str): \u8981\u8c03\u7528\u7684\u65b9\u6cd5\u540d - *args: \u65b9\u6cd5\u7684\u53ef\u53d8\u53c2\u6570

      \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4\uff0c\u5305\u542b\u4ee5\u4e0b\u5b57\u6bb5\uff1a - id (int): \u8bf7\u6c42 ID - result: \u65b9\u6cd5\u8fd4\u56de\u503c - error (str or None): \u9519\u8bef\u4fe1\u606f\uff08\u5982\u679c\u5931\u8d25\uff09

      "},{"location":"qsl4a/core/android-base/#getattr","title":"getattr()","text":"

      \u52a8\u6001\u65b9\u6cd5\u5206\u53d1\u5668\u3002\u6240\u6709 Android \u65b9\u6cd5\u90fd\u901a\u8fc7\u5c5e\u6027\u67e5\u627e\u8bbf\u95ee\u3002

      # \u4ee5\u4e0b\u4e24\u79cd\u65b9\u5f0f\u7b49\u4ef7\uff1a\ndroid.makeToast(\"Hello\")\ndroid._rpc(\"makeToast\", \"Hello\")\n
      "},{"location":"qsl4a/core/android-base/#androidpy","title":"\u72ec\u7acb\u51fd\u6570\uff08android.py\uff09","text":"

      \u4f7f\u7528\u7b80\u5316\u7684 android \u6a21\u5757\u65f6\uff1a

      "},{"location":"qsl4a/core/android-base/#jsla","title":"jsla()","text":"

      \u53d1\u9001 JSON-RPC \u8bf7\u6c42\u5e76\u8fd4\u56de\u539f\u59cb\u54cd\u5e94\u3002

      jsla(method, *params)\n

      \u8fd4\u56de\uff1a JSON \u5b57\u7b26\u4e32\u54cd\u5e94

      "},{"location":"qsl4a/core/android-base/#rsla","title":"rsla()","text":"

      \u53d1\u9001\u8bf7\u6c42\u5e76\u4ec5\u8fd4\u56de\u7ed3\u679c\u3002

      rsla(method, *params)\n

      \u8fd4\u56de\uff1a RPC \u8c03\u7528\u7684\u7ed3\u679c\u503c

      "},{"location":"qsl4a/core/android-base/#esla","title":"esla()","text":"

      \u53d1\u9001\u8bf7\u6c42\uff0c\u9519\u8bef\u65f6\u629b\u51fa\u5f02\u5e38\u3002

      esla(method, *params)\n

      \u629b\u51fa\uff1a \u5982\u679c error \u5b57\u6bb5\u4e0d\u4e3a None \u5219\u629b\u51fa\u5f02\u5e38

      "},{"location":"qsl4a/core/android-base/#nsla","title":"nsla()","text":"

      \u53d1\u9001\u8bf7\u6c42\u5e76\u8fd4\u56de Result \u547d\u540d\u5143\u7ec4\u3002

      nsla(method, *params)\n

      \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4

      "},{"location":"qsl4a/core/android-base/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/android-base/#_5","title":"\u57fa\u672c\u8fde\u63a5","text":"
      import androidhelper\n\n# \u8fde\u63a5\u5230 Android \u8fd0\u884c\u65f6\ndroid = androidhelper.Android()\n\n# \u901a\u8fc7\u663e\u793a toast \u6765\u68c0\u67e5\u8fde\u63a5\ndroid.makeToast(\"Connected!\")\n
      "},{"location":"qsl4a/core/android-base/#_6","title":"\u9519\u8bef\u5904\u7406","text":"
      result = droid.someMethod()\nif result.error:\n    print(f\"Error: {result.error}\")\nelse:\n    print(f\"Success: {result.result}\")\n
      "},{"location":"qsl4a/core/android-base/#rpc","title":"\u76f4\u63a5 RPC \u8c03\u7528","text":"
      # \u76f4\u63a5\u8c03\u7528\u4efb\u610f\u65b9\u6cd5\nresult = droid._rpc(\"makeToast\", \"Hello World\")\n
      "},{"location":"qsl4a/core/events/","title":"\u4e8b\u4ef6\u7cfb\u7edf","text":"

      QSL4A \u63d0\u4f9b\u4e86\u4e00\u4e2a\u4e8b\u4ef6\u7cfb\u7edf\uff0c\u7528\u4e8e\u5904\u7406\u6765\u81ea Android \u7684\u5f02\u6b65\u4e8b\u4ef6\uff0c\u5982\u4f20\u611f\u5668\u66f4\u65b0\u3001\u4f4d\u7f6e\u53d8\u5316\u548c\u81ea\u5b9a\u4e49\u5e7f\u64ad\u3002

      "},{"location":"qsl4a/core/events/#_2","title":"\u4e8b\u4ef6\u57fa\u7840","text":"

      \u4e8b\u4ef6\u5b58\u50a8\u5728\u7f13\u51b2\u533a\u4e2d\uff0c\u53ef\u4ee5\u8f6e\u8be2\u6216\u7b49\u5f85\u3002\u6bcf\u4e2a\u4e8b\u4ef6\u5305\u542b\uff1a - name: \u4e8b\u4ef6\u7c7b\u578b/\u540d\u79f0 - data: \u4e8b\u4ef6\u8d1f\u8f7d\u6570\u636e - time: \u65f6\u95f4\u6233

      "},{"location":"qsl4a/core/events/#_3","title":"\u4e8b\u4ef6\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#eventclearbuffer","title":"eventClearBuffer()","text":"

      \u6e05\u9664\u7f13\u51b2\u533a\u4e2d\u7684\u6240\u6709\u5f85\u5904\u7406\u4e8b\u4ef6\u3002

      eventClearBuffer()\n

      \u8fd4\u56de\uff1a None

      "},{"location":"qsl4a/core/events/#eventpoll","title":"eventPoll()","text":"

      \u8f6e\u8be2\u7f13\u51b2\u533a\u4e2d\u7684\u4e8b\u4ef6\u3002

      eventPoll(number_of_events=1)\n

      \u53c2\u6570\uff1a - number_of_events (int): \u8981\u68c0\u7d22\u7684\u6700\u5927\u4e8b\u4ef6\u6570\uff08\u9ed8\u8ba4\uff1a1\uff09

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\u5217\u8868

      "},{"location":"qsl4a/core/events/#eventwait","title":"eventWait()","text":"

      \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\u3002

      eventWait(timeout=None)\n

      \u53c2\u6570\uff1a - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09\u3002None = \u6c38\u4e45\u7b49\u5f85

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

      "},{"location":"qsl4a/core/events/#eventwaitfor","title":"eventWaitFor()","text":"

      \u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6\u3002

      eventWaitFor(eventName, timeout=None)\n

      \u53c2\u6570\uff1a - eventName (str): \u8981\u7b49\u5f85\u7684\u4e8b\u4ef6\u540d\u79f0 - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

      "},{"location":"qsl4a/core/events/#eventpost","title":"eventPost()","text":"

      \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\u3002

      eventPost(name, data, enqueue=None)\n

      \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e\uff08\u4efb\u610f\u7c7b\u578b\uff09 - enqueue (bool, optional): \u5982\u679c\u4e3a True \u5219\u6dfb\u52a0\u5230\u961f\u5217

      "},{"location":"qsl4a/core/events/#receiveevent","title":"receiveEvent()","text":"

      \u63a5\u6536\u4e8b\u4ef6\uff08\u963b\u585e\uff09\u3002

      receiveEvent()\n

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61

      "},{"location":"qsl4a/core/events/#_4","title":"\u5e7f\u64ad\u4e8b\u4ef6","text":"

      \u6ce8\u518c\u7cfb\u7edf\u5e7f\u64ad\u4e8b\u4ef6\u3002

      "},{"location":"qsl4a/core/events/#eventregisterforbroadcast","title":"eventRegisterForBroadcast()","text":"

      \u6ce8\u518c\u63a5\u6536\u5e7f\u64ad\u4e8b\u4ef6\u3002

      eventRegisterForBroadcast(category, enqueue=True)\n

      \u53c2\u6570\uff1a - category (str): \u5e7f\u64ad\u7c7b\u522b/\u52a8\u4f5c - enqueue (bool): \u6dfb\u52a0\u5230\u4e8b\u4ef6\u961f\u5217

      "},{"location":"qsl4a/core/events/#eventunregisterforbroadcast","title":"eventUnregisterForBroadcast()","text":"

      \u53d6\u6d88\u6ce8\u518c\u5e7f\u64ad\u4e8b\u4ef6\u3002

      eventUnregisterForBroadcast(category)\n
      "},{"location":"qsl4a/core/events/#eventgetbrodcastcategories","title":"eventGetBrodcastCategories()","text":"

      \u83b7\u53d6\u5df2\u6ce8\u518c\u7684\u5e7f\u64ad\u7c7b\u522b\u3002

      eventGetBrodcastCategories()\n

      \u8fd4\u56de\uff1a \u5df2\u6ce8\u518c\u7c7b\u522b\u5217\u8868

      "},{"location":"qsl4a/core/events/#_5","title":"\u4e8b\u4ef6\u5206\u53d1\u5668)","text":""},{"location":"qsl4a/core/events/#starteventdispatcher","title":"startEventDispatcher()","text":"

      \u6253\u5f00\u4e00\u4e2a\u53ef\u4ee5\u8bfb\u53d6\u5df2\u53d1\u5e03\u4e8b\u4ef6\u7684\u5957\u63a5\u5b57\u3002)

      startEventDispatcher(port=0)\n

      \u53c2\u6570\uff1a - port (int, optional): \u76d1\u542c\u7684\u7aef\u53e3\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\u9009\u62e9\uff09

      \u8fd4\u56de\uff1a \u6b63\u5728\u76d1\u542c\u7684\u7aef\u53e3\u53f7

      "},{"location":"qsl4a/core/events/#stopeventdispatcher","title":"stopEventDispatcher()","text":"

      \u505c\u6b62\u4e8b\u4ef6\u670d\u52a1\u5668\u3002)

      stopEventDispatcher()\n
      "},{"location":"qsl4a/core/events/#_6","title":"\u5df2\u5e9f\u5f03\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#rpcpostevent","title":"rpcPostEvent()","text":"

      \u5c06\u4e8b\u4ef6\u53d1\u5e03\u5230\u4e8b\u4ef6\u961f\u5217\u3002\uff08\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 eventPost\uff09

      rpcPostEvent(name, data)\n

      \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e

      "},{"location":"qsl4a/core/events/#_7","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/events/#_8","title":"\u57fa\u672c\u4e8b\u4ef6\u8f6e\u8be2","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6e05\u9664\u65e7\u4e8b\u4ef6\ndroid.eventClearBuffer()\n\n# \u8f6e\u8be2\u4e8b\u4ef6\nevents = droid.eventPoll(5).result\nfor event in events:\n    print(f\"Event: {event['name']}, Data: {event['data']}\")\n
      "},{"location":"qsl4a/core/events/#_9","title":"\u7b49\u5f85\u4e8b\u4ef6","text":"
      # \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\uff0c\u5e26\u8d85\u65f6\nevent = droid.eventWait(timeout=10).result\nif event:\n    print(f\"Got event: {event['name']}\")\n
      "},{"location":"qsl4a/core/events/#_10","title":"\u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6","text":"
      # \u7b49\u5f85\u4f20\u611f\u5668\u4e8b\u4ef6\nevent = droid.eventWaitFor('screen', timeout=5).result\nif event:\n    print(f\"Screen event: {event['data']}\")\n
      "},{"location":"qsl4a/core/events/#_11","title":"\u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6","text":"
      # \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\ndroid.eventPost('my_event', {'key': 'value'})\n\n# \u7b49\u5f85\u5b83\nevent = droid.eventWaitFor('my_event', timeout=1).result\n
      "},{"location":"qsl4a/core/events/#_12","title":"\u5e7f\u64ad\u63a5\u6536\u5668","text":"
      # \u6ce8\u518c\u5c4f\u5e55\u5f00\u5173\u4e8b\u4ef6\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_ON')\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_OFF')\n\n# \u7b49\u5f85\u5c4f\u5e55\u4e8b\u4ef6\nwhile True:\n    event = droid.receiveEvent().result\n    if event['name'] == 'android.intent.action.SCREEN_ON':\n        print(\"Screen turned on\")\n    elif event['name'] == 'android.intent.action.SCREEN_OFF':\n        print(\"Screen turned off\")\n
      "},{"location":"qsl4a/core/events/#_13","title":"\u4f20\u611f\u5668\u4e8b\u4ef6\u5904\u7406","text":"
      # \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u5904\u7406\u4f20\u611f\u5668\u4e8b\u4ef6\nfor _ in range(100):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'sensors':\n        data = event['data']\n        print(f\"Accel: {data['xforce']}, {data['yforce']}, {data['zforce']}\")\n\ndroid.stopSensing()\n
      "},{"location":"qsl4a/core/events/#_14","title":"\u5e38\u89c1\u4e8b\u4ef6\u7c7b\u578b","text":"\u4e8b\u4ef6\u540d\u79f0 \u63cf\u8ff0 \u6765\u6e90 sensors \u4f20\u611f\u5668\u6570\u636e\u66f4\u65b0 startSensing* location GPS \u4f4d\u7f6e\u66f4\u65b0 startLocating phone \u7535\u8bdd\u72b6\u6001\u53d8\u5316 startTrackingPhoneState signal \u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316 startTrackingSignalStrength screen \u622a\u56fe\u5c31\u7eea fullGetScreenShot dialog \u5bf9\u8bdd\u6846\u54cd\u5e94 dialogShow*"},{"location":"qsl4a/core/events/#_15","title":"\u4e8b\u4ef6\u6570\u636e\u7ed3\u6784","text":"
      {\n    'name': 'event_name',\n    'data': {\n        # \u4e8b\u4ef6\u7279\u5b9a\u6570\u636e\n    },\n    'time': 1234567890  # \u65f6\u95f4\u6233\n}\n
      "},{"location":"qsl4a/core/intent/","title":"Intent \u7cfb\u7edf","text":"

      Android Intent \u7528\u4e8e\u542f\u52a8\u6d3b\u52a8\u3001\u53d1\u9001\u5e7f\u64ad\u548c\u5e94\u7528\u95f4\u901a\u4fe1\u3002QSL4A \u901a\u8fc7 Intent \u6a21\u5757\u63d0\u4f9b\u5b8c\u6574\u7684 Intent \u652f\u6301\u3002

      "},{"location":"qsl4a/core/intent/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
      import androidhelper\ndon = androidhelper.Android()\n
      "},{"location":"qsl4a/core/intent/#intent_1","title":"Intent \u5e38\u91cf","text":"

      \u901a\u8fc7 droid.Intent \u8bbf\u95ee\uff1a

      "},{"location":"qsl4a/core/intent/#_2","title":"\u64cd\u4f5c","text":"\u5e38\u91cf \u503c \u7528\u9014 ACTION_MAIN android.intent.action.MAIN \u5e94\u7528\u5165\u53e3\u70b9 ACTION_VIEW android.intent.action.VIEW \u67e5\u770b\u5185\u5bb9 ACTION_EDIT android.intent.action.EDIT \u7f16\u8f91\u5185\u5bb9 ACTION_PICK android.intent.action.PICK \u9009\u62e9\u9879\u76ee ACTION_SEND android.intent.action.SEND \u5206\u4eab\u5185\u5bb9 ACTION_SEARCH android.intent.action.SEARCH \u641c\u7d22"},{"location":"qsl4a/core/intent/#_3","title":"\u6807\u5fd7","text":"\u5e38\u91cf \u503c \u7528\u9014 FLAG_ACTIVITY_NEW_TASK 268435456 \u542f\u52a8\u65b0\u4efb\u52a1 FLAG_ACTIVITY_CLEAR_TASK 32768 \u6e05\u9664\u4efb\u52a1\u5806\u6808 FLAG_ACTIVITY_NEW_DOCUMENT 524288 \u65b0\u6587\u6863\u6a21\u5f0f"},{"location":"qsl4a/core/intent/#_4","title":"\u9644\u52a0\u6570\u636e","text":"\u5e38\u91cf \u7528\u9014 EXTRA_TEXT \u6587\u672c\u5185\u5bb9 EXTRA_STREAM \u6587\u4ef6 URI EXTRA_SUBJECT \u4e3b\u9898\u884c EXTRA_EMAIL \u7535\u5b50\u90ae\u4ef6\u5730\u5740"},{"location":"qsl4a/core/intent/#_5","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/intent/#makeintent","title":"makeIntent()","text":"

      \u521b\u5efa Intent \u5bf9\u8c61\u3002

      makeIntent(action, uri=None, type=None, extras=None, categories=None,\n           packagename=None, classname=None, flags=None)\n

      \u53c2\u6570\uff1a - action (str): Intent \u64cd\u4f5c\uff08\u4f8b\u5982 droid.Intent.ACTION_VIEW\uff09 - uri (str, optional): \u6570\u636e URI - type (str, optional): MIME \u7c7b\u578b - extras (dict, optional): \u9644\u52a0\u6570\u636e - categories (list, optional): Intent \u7c7b\u522b - packagename (str, optional): \u76ee\u6807\u5305 - classname (str, optional): \u76ee\u6807\u7c7b - flags (int, optional): Intent \u6807\u5fd7

      \u8fd4\u56de\uff1a Intent \u5bf9\u8c61

      "},{"location":"qsl4a/core/intent/#startactivityintent","title":"startActivityIntent()","text":"

      \u4f7f\u7528 Intent \u542f\u52a8 Activity\u3002

      startActivityIntent(intent, wait=None)\n

      \u53c2\u6570\uff1a - intent: makeIntent() \u8fd4\u56de\u7684 Intent \u5bf9\u8c61 - wait (bool, optional): \u963b\u585e\u76f4\u5230\u6d3b\u52a8\u5173\u95ed

      "},{"location":"qsl4a/core/intent/#startactivityforresultintent","title":"startActivityForResultIntent()","text":"

      \u542f\u52a8\u6d3b\u52a8\u5e76\u7b49\u5f85\u7ed3\u679c\u3002

      startActivityForResultIntent(intent)\n

      \u8fd4\u56de\uff1a Activity \u7ed3\u679c

      "},{"location":"qsl4a/core/intent/#sendbroadcastintent","title":"sendBroadcastIntent()","text":"

      \u53d1\u9001\u5e7f\u64ad\u3002

      sendBroadcastIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#view","title":"view()","text":"

      \u901a\u8fc7 URI \u67e5\u770b\u5185\u5bb9\u3002

      view(uri, type=None, extras=None)\n
      "},{"location":"qsl4a/core/intent/#pick","title":"pick()","text":"

      \u4ece URI \u9009\u62e9\u5185\u5bb9\u3002

      pick(uri)\n
      "},{"location":"qsl4a/core/intent/#intent_2","title":"\u5e38\u89c1 Intent \u65b9\u6cd5)","text":""},{"location":"qsl4a/core/intent/#scanbarcode","title":"scanBarcode()","text":"

      \u542f\u52a8\u6761\u7801\u626b\u63cf\u5668\u3002

      scanBarcode()\n

      \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/core/intent/#send","title":"send()","text":"

      \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u5185\u5bb9\u3002

      send(type, content)\n

      \u53c2\u6570\uff1a - type (str): MIME \u7c7b\u578b - content (str): \u8981\u5206\u4eab\u7684\u5185\u5bb9

      "},{"location":"qsl4a/core/intent/#sendtext","title":"sendText()","text":"

      \u53d1\u9001\u6587\u672c\u5185\u5bb9\u3002

      sendText(text)\n

      \u53c2\u6570\uff1a - text (str): \u8981\u53d1\u9001\u7684\u6587\u672c

      "},{"location":"qsl4a/core/intent/#sendemail","title":"sendEmail()","text":"

      \u53d1\u9001\u7535\u5b50\u90ae\u4ef6\u3002

      sendEmail(to, subject, body, attachment=None)\n

      \u53c2\u6570\uff1a - to (str or list): \u6536\u4ef6\u4eba\u7535\u5b50\u90ae\u4ef6\u5730\u5740 - subject (str): \u7535\u5b50\u90ae\u4ef6\u4e3b\u9898 - body (str): \u7535\u5b50\u90ae\u4ef6\u6b63\u6587 - attachment (str, optional): \u9644\u4ef6\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/core/intent/#pathtouri","title":"pathToUri()","text":"

      \u5c06\u6587\u4ef6\u8def\u5f84\u8f6c\u6362\u4e3a\u5185\u5bb9 URI\u3002

      pathToUri(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5185\u5bb9 URI \u5b57\u7b26\u4e32

      "},{"location":"qsl4a/core/intent/#openfile","title":"openFile()","text":"

      \u7528\u9002\u5f53\u7684\u5e94\u7528\u7a0b\u5e8f\u6253\u5f00\u6587\u4ef6\u3002

      openFile(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u6253\u5f00\u7684\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/core/intent/#sendfile","title":"sendFile()","text":"

      \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u6587\u4ef6\u3002

      sendFile(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u53d1\u9001\u7684\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/core/intent/#getpathtype","title":"getPathType()","text":"

      \u83b7\u53d6\u6587\u4ef6\u8def\u5f84\u7684 MIME \u7c7b\u578b\u3002

      getPathType(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a MIME \u7c7b\u578b\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/core/intent/#viewmap","title":"viewMap()","text":"

      \u5728\u6307\u5b9a\u4f4d\u7f6e\u6253\u5f00\u5730\u56fe\u3002

      viewMap(latitude, longitude)\n

      \u53c2\u6570\uff1a - latitude (float): \u7eac\u5ea6 - longitude (float): \u7ecf\u5ea6

      "},{"location":"qsl4a/core/intent/#viewcontacts","title":"viewContacts()","text":"

      \u6253\u5f00\u8054\u7cfb\u4eba\u5e94\u7528\u3002

      viewContacts()\n
      "},{"location":"qsl4a/core/intent/#search","title":"search()","text":"

      \u6267\u884c\u7f51\u7edc\u641c\u7d22\u3002

      search(query)\n

      \u53c2\u6570\uff1a - query (str): \u641c\u7d22\u67e5\u8be2

      "},{"location":"qsl4a/core/intent/#viewhtml","title":"viewHtml()","text":"

      \u67e5\u770b HTML \u5185\u5bb9\u3002

      viewHtml(content, encoding=None)\n

      \u53c2\u6570\uff1a - content (str): HTML \u5185\u5bb9 - encoding (str, optional): \u5b57\u7b26\u7f16\u7801

      "},{"location":"qsl4a/core/intent/#webviewshow","title":"webViewShow()","text":"

      \u5728 WebView \u4e2d\u663e\u793a\u7f51\u9875\u5185\u5bb9\u3002\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 viewHtml\u3002

      webViewShow(url)\n

      \u53c2\u6570\uff1a - url (str): \u7f51\u9875 URL

      "},{"location":"qsl4a/core/intent/#editoropen","title":"editorOpen()","text":"

      \u6253\u5f00\u6587\u672c\u7f16\u8f91\u5668\u3002

      editorOpen(path=None, create=False)\n

      \u53c2\u6570\uff1a - path (str, optional): \u8981\u7f16\u8f91\u7684\u6587\u4ef6\u8def\u5f84 - create (bool, optional): \u5982\u679c\u4e0d\u5b58\u5728\u5219\u521b\u5efa

      "},{"location":"qsl4a/core/intent/#uri","title":"\u8f85\u52a9\u7c7b\uff1aUri","text":"

      \u521b\u5efa Intent \u7684 URI \u5bf9\u8c61\uff1a

      from androidhelper.Intent import Uri\n\nuri = Uri(\"file:///sdcard/test.txt\")\n
      "},{"location":"qsl4a/core/intent/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/intent/#_7","title":"\u6253\u5f00\u7f51\u9875","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"http://www.example.com\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_8","title":"\u5206\u4eab\u6587\u672c","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_TEXT: \"Hello from QPython!\",\n        droid.Intent.EXTRA_SUBJECT: \"Test\"\n    },\n    type=\"text/plain\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_9","title":"\u6253\u5f00\u6587\u4ef6","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"file:///sdcard/document.pdf\",\n    type=\"application/pdf\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_10","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":"
      result = droid.pickContact()\ncontact_uri = result.result\n
      "},{"location":"qsl4a/core/intent/#_11","title":"\u53d1\u9001\u7535\u5b50\u90ae\u4ef6","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_EMAIL: [\"test@example.com\"],\n        droid.Intent.EXTRA_SUBJECT: \"Hello\",\n        droid.Intent.EXTRA_TEXT: \"Message body\"\n    },\n    type=\"message/rfc822\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_12","title":"\u6253\u5f00\u5e94\u7528","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_MAIN,\n    packagename=\"com.android.settings\",\n    classname=\"com.android.settings.Settings\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/hardware/bluetooth/","title":"\u84dd\u7259 API","text":"

      \u63a7\u5236\u84dd\u7259\u9002\u914d\u5668\u5e76\u4e0e\u84dd\u7259\u8bbe\u5907\u901a\u4fe1\u3002

      "},{"location":"qsl4a/hardware/bluetooth/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/hardware/bluetooth/#togglebluetoothstate","title":"toggleBluetoothState()","text":"

      \u6253\u5f00/\u5173\u95ed\u84dd\u7259\u3002

      toggleBluetoothState(enabled=None, prompt=True)\n

      \u53c2\u6570\uff1a - enabled (bool): True=\u5f00\uff0cFalse=\u5173\uff0cNone=\u5207\u6362 - prompt (bool): \u663e\u793a\u7528\u6237\u63d0\u793a

      "},{"location":"qsl4a/hardware/bluetooth/#checkbluetoothstate","title":"checkBluetoothState()","text":"

      \u68c0\u67e5\u84dd\u7259\u662f\u5426\u5df2\u542f\u7528\u3002

      checkBluetoothState()\n

      \u8fd4\u56de\uff1a True/False

      "},{"location":"qsl4a/hardware/bluetooth/#getlocalname","title":"GetLocalName()","text":"

      \u83b7\u53d6\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

      GetLocalName()\n
      "},{"location":"qsl4a/hardware/bluetooth/#setlocalname","title":"SetLocalName()","text":"

      \u8bbe\u7f6e\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

      SetLocalName(name)\n
      "},{"location":"qsl4a/hardware/bluetooth/#getscanmode","title":"GetScanMode()","text":"

      \u83b7\u53d6\u53ef\u53d1\u73b0\u6027\u6a21\u5f0f\u3002

      GetScanMode()\n

      \u8fd4\u56de\uff1a - -1: \u5df2\u7981\u7528 - 0: \u4e0d\u53ef\u53d1\u73b0\uff0c\u4e0d\u53ef\u8fde\u63a5 - 1: \u53ef\u8fde\u63a5\uff0c\u4e0d\u53ef\u53d1\u73b0 - 3: \u53ef\u8fde\u63a5\u4e14\u53ef\u53d1\u73b0

      "},{"location":"qsl4a/hardware/bluetooth/#makediscoverable","title":"MakeDiscoverable()","text":"

      \u4f7f\u8bbe\u5907\u53ef\u53d1\u73b0\u3002

      MakeDiscoverable(duration=300)\n

      \u53c2\u6570\uff1a - duration (int): \u53ef\u53d1\u73b0\u7684\u79d2\u6570

      "},{"location":"qsl4a/hardware/bluetooth/#_2","title":"\u53d1\u73b0","text":""},{"location":"qsl4a/hardware/bluetooth/#discoverystart","title":"DiscoveryStart()","text":"

      \u5f00\u59cb\u8bbe\u5907\u53d1\u73b0\u3002

      DiscoveryStart()\n
      "},{"location":"qsl4a/hardware/bluetooth/#discoverycancel","title":"DiscoveryCancel()","text":"

      \u53d6\u6d88\u53d1\u73b0\u3002

      DiscoveryCancel()\n
      "},{"location":"qsl4a/hardware/bluetooth/#getreceiveddevices","title":"GetReceivedDevices()","text":"

      \u83b7\u53d6\u53d1\u73b0\u7684\u8bbe\u5907\u3002

      GetReceivedDevices()\n

      \u8fd4\u56de\uff1a \u8bbe\u5907\u4fe1\u606f\u5b57\u5178\u5217\u8868

      "},{"location":"qsl4a/hardware/bluetooth/#getbondeddevices","title":"GetBondedDevices()","text":"

      \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\u3002

      GetBondedDevices()\n

      \u8fd4\u56de\uff1a \u914d\u5bf9\u8bbe\u5907\u4fe1\u606f\u5217\u8868

      "},{"location":"qsl4a/hardware/bluetooth/#_3","title":"\u8fde\u63a5","text":""},{"location":"qsl4a/hardware/bluetooth/#connect","title":"Connect()","text":"

      \u8fde\u63a5\u5230\u8bbe\u5907\u3002

      Connect(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", address=None)\n

      \u53c2\u6570\uff1a - uuid (str): \u670d\u52a1 UUID - address (str): \u8bbe\u5907\u5730\u5740\uff08None = \u663e\u793a\u9009\u62e9\u5668\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/hardware/bluetooth/#accept","title":"Accept()","text":"

      \u63a5\u53d7\u4f20\u5165\u8fde\u63a5\u3002

      Accept(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", timeout=0)\n
      "},{"location":"qsl4a/hardware/bluetooth/#activeconnections","title":"ActiveConnections()","text":"

      \u68c0\u67e5\u6d3b\u52a8\u8fde\u63a5\u3002

      ActiveConnections()\n
      "},{"location":"qsl4a/hardware/bluetooth/#stop","title":"Stop()","text":"

      \u65ad\u5f00\u8fde\u63a5\u3002

      Stop(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#_4","title":"\u901a\u4fe1","text":""},{"location":"qsl4a/hardware/bluetooth/#write","title":"Write()","text":"

      \u53d1\u9001 ASCII \u6570\u636e\u3002

      Write(ascii, connID=\"\")\n
      "},{"location":"qsl4a/hardware/bluetooth/#writebinary","title":"WriteBinary()","text":"

      \u53d1\u9001\u4e8c\u8fdb\u5236\u6570\u636e\uff08base64 \u7f16\u7801\uff09\u3002

      WriteBinary(base64, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#read","title":"Read()","text":"

      \u8bfb\u53d6 ASCII \u6570\u636e\u3002

      Read(bufferSize=4096, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readbinary","title":"ReadBinary()","text":"

      \u8bfb\u53d6\u4e8c\u8fdb\u5236\u6570\u636e\u3002

      ReadBinary(bufferSize=4096, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readline","title":"ReadLine()","text":"

      \u8bfb\u53d6\u4e00\u884c\u3002

      ReadLine(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readready","title":"ReadReady()","text":"

      \u68c0\u67e5\u662f\u5426\u6709\u53ef\u7528\u6570\u636e\u3002

      ReadReady(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u7528\u84dd\u7259\ndroid.toggleBluetoothState(True)\n\n# \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\ndevices = droid.GetBondedDevices().result\nfor dev in devices:\n    print(f\"{dev['name']}: {dev['address']}\")\n\n# \u8fde\u63a5\u5230\u8bbe\u5907\ndroid.Connect(address=\"00:11:22:33:44:55\")\n\n# \u53d1\u9001\u6570\u636e\ndroid.Write(\"Hello Bluetooth!\")\n\n# \u8bfb\u53d6\u54cd\u5e94\ndata = droid.Read(1024).result\n
      "},{"location":"qsl4a/hardware/camera/","title":"\u76f8\u673a API","text":"

      \u62cd\u6444\u7167\u7247\u548c\u5f55\u5236\u89c6\u9891\u3002

      "},{"location":"qsl4a/hardware/camera/#_1","title":"\u7167\u7247\u62cd\u6444","text":""},{"location":"qsl4a/hardware/camera/#takepicture","title":"takePicture()","text":"

      \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u6444\u7167\u7247\u3002

      takePicture(path=None)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8fd4\u56de\u56fe\u50cf\u6570\u636e

      \u8fd4\u56de\uff1a \u56fe\u50cf\u8def\u5f84\u6216\u56fe\u50cf\u6570\u636e

      "},{"location":"qsl4a/hardware/camera/#cameracapturepicture","title":"cameraCapturePicture()","text":"

      \u4f7f\u7528\u9ad8\u7ea7\u76f8\u673a\u63a7\u5236\u62cd\u6444\u7167\u7247\u3002

      cameraCapturePicture(targetPath=None, cameraId=0, useAutoFocus=True)\n

      \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - useAutoFocus (bool): \u542f\u7528\u81ea\u52a8\u5bf9\u7126

      \u8fd4\u56de\uff1a \u62cd\u6444\u7684\u56fe\u50cf\u8def\u5f84

      "},{"location":"qsl4a/hardware/camera/#camerasettorchmode","title":"cameraSetTorchMode()","text":"

      \u63a7\u5236\u76f8\u673a\u95ea\u5149\u706f/\u624b\u7535\u7b52\u3002

      cameraSetTorchMode(enabled)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u6253\u5f00\uff0cFalse \u5173\u95ed

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/hardware/camera/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

      \u622a\u56fe\u3002

      imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

      "},{"location":"qsl4a/hardware/camera/#_2","title":"\u89c6\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#takevideo","title":"takeVideo()","text":"

      \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\u3002

      takeVideo(path=None, quality=1)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-4\uff09 - 0: 160x120 - 1: 320x240 - 2: 352x288 - 3: 640x480 - 4: 800x480

      "},{"location":"qsl4a/hardware/camera/#recordercapturevideo","title":"recorderCaptureVideo()","text":"

      \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\u3002

      recorderCaptureVideo(targetPath=None, duration=10, cameraId=0, quality=8)\n

      \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - duration (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a10\uff09 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-8\uff0c\u8d8a\u9ad8\u8d8a\u597d\uff09

      \u8fd4\u56de\uff1a \u89c6\u9891\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/hardware/camera/#recordaudio","title":"recordAudio()","text":"

      \u5f55\u5236\u97f3\u9891\u3002

      recordAudio()\n

      \u8fd4\u56de\uff1a \u97f3\u9891\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/hardware/camera/#_3","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

      \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\u3002

      recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

      \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\uff09 - targetPixels (int): \u5206\u8fa8\u7387 - frameRate (int): FPS - bitRate (int): \u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa - autoStart (bool): \u7acb\u5373\u5f00\u59cb

      "},{"location":"qsl4a/hardware/camera/#recorderstart","title":"recorderStart()","text":"

      \u5f00\u59cb\u5f55\u5236\u3002

      recorderStart()\n
      "},{"location":"qsl4a/hardware/camera/#recorderpause","title":"recorderPause()","text":"

      \u6682\u505c\u5f55\u5236\u3002

      recorderPause()\n
      "},{"location":"qsl4a/hardware/camera/#recorderresume","title":"recorderResume()","text":"

      \u6062\u590d\u5f55\u5236\u3002

      recorderResume()\n
      "},{"location":"qsl4a/hardware/camera/#_4","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/camera/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

      \u5f00\u59cb\u97f3\u91cf\u68c0\u6d4b\u3002

      recorderSoundVolumeDetect(interval=100)\n
      "},{"location":"qsl4a/hardware/camera/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

      \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

      recorderSoundVolumeGetDb()\n
      "},{"location":"qsl4a/hardware/camera/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u7167\nphoto_path = droid.takePicture(\"/sdcard/photo.jpg\").result\nprint(f\"Photo saved: {photo_path}\")\n\n# \u4f7f\u7528\u524d\u7f6e\u76f8\u673a\u548c\u81ea\u52a8\u5bf9\u7126\u62cd\u7167\ncamera_path = droid.cameraCapturePicture(\"/sdcard/selfie.jpg\", cameraId=1, useAutoFocus=True).result\nprint(f\"Front camera photo: {camera_path}\")\n\n# \u63a7\u5236\u95ea\u5149\u706f\ndroid.cameraSetTorchMode(True)  # \u6253\u5f00\u95ea\u5149\u706f\n\n# \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\nvideo_path = droid.takeVideo(\"/sdcard/video.mp4\", quality=3).result\nprint(f\"Video saved: {video_path}\")\n\n# \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\nvideo_path = droid.recorderCaptureVideo(\"/sdcard/movie.mp4\", duration=30, cameraId=0, quality=8).result\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n
      "},{"location":"qsl4a/hardware/recorder/","title":"\u97f3\u9891\u5f55\u5236 API","text":"

      \u4ece\u9ea6\u514b\u98ce\u548c\u8bbe\u5907\u5c4f\u5e55\u5f55\u5236\u97f3\u9891\u3002

      "},{"location":"qsl4a/hardware/recorder/#_1","title":"\u97f3\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recordaudio","title":"recordAudio()","text":"

      \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\u3002

      recordAudio()\n

      \u8fd4\u56de\uff1a \u5f55\u5236\u7684\u97f3\u9891\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/hardware/recorder/#recorderstartmicrophone","title":"recorderStartMicrophone()","text":"

      \u5f00\u59cb\u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\u3002

      recorderStartMicrophone(targetPath=None)\n

      \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u5f55\u5236\u7684\u8def\u5f84

      "},{"location":"qsl4a/hardware/recorder/#_2","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

      \u5f00\u59cb\u5e26\u97f3\u9891\u7684\u5c4f\u5e55\u5f55\u5236\u3002

      recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

      \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\u97f3\u9891\uff09 - targetPixels (int): \u76ee\u6807\u5206\u8fa8\u7387\uff08\u50cf\u7d20\uff09 - frameRate (int): \u6bcf\u79d2\u5e27\u6570\uff08\u9ed8\u8ba4\uff1a30\uff09 - bitRate (int): \u89c6\u9891\u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa\u89c6\u9891 - autoStart (bool): \u7acb\u5373\u5f00\u59cb\u5f55\u5236

      \u8fd4\u56de\uff1a \u64cd\u4f5c\u7ed3\u679c

      "},{"location":"qsl4a/hardware/recorder/#recorderstart","title":"recorderStart()","text":"

      \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\uff08\u5f53 autoStart=False \u65f6\uff09\u3002

      recorderStart()\n
      "},{"location":"qsl4a/hardware/recorder/#recorderpause","title":"recorderPause()","text":"

      \u6682\u505c\u6b63\u5728\u8fdb\u884c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

      recorderPause()\n
      "},{"location":"qsl4a/hardware/recorder/#recorderresume","title":"recorderResume()","text":"

      \u6062\u590d\u6682\u505c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

      recorderResume()\n
      "},{"location":"qsl4a/hardware/recorder/#_3","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/recorder/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

      \u5f00\u59cb\u76d1\u63a7\u97f3\u91cf\u7ea7\u522b\u3002

      recorderSoundVolumeDetect(interval=100)\n

      \u53c2\u6570\uff1a - interval (int): \u68c0\u6d4b\u95f4\u9694\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a100\uff09

      "},{"location":"qsl4a/hardware/recorder/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

      \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

      recorderSoundVolumeGetDb()\n

      \u8fd4\u56de\uff1a \u5f53\u524d\u97f3\u91cf\u7ea7\u522b\uff08dB\uff09

      "},{"location":"qsl4a/hardware/recorder/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\nprint(\"Recording audio...\")\naudio_path = droid.recordAudio().result\nprint(f\"Saved to: {audio_path}\")\n\n# \u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\ndroid.recorderStartMicrophone(\"/sdcard/my_recording.mp3\")\ntime.sleep(5)\ndroid.recorderStop()\n\n# \u5e26\u97f3\u9891\u5f55\u5236\u5c4f\u5e55\nprint(\"Starting screen recording...\")\ndroid.recorderStartScreenRecord(\n    path=\"/sdcard/screen_record.mp4\",\n    audio=1,\n    frameRate=30,\n    autoStart=True\n)\ntime.sleep(10)\ndroid.recorderStop()\n\n# \u76d1\u63a7\u97f3\u91cf\ndroid.recorderSoundVolumeDetect(interval=100)\ntime.sleep(3)\nvolume = droid.recorderSoundVolumeGetDb().result\nprint(f\"Current volume: {volume} dB\")\n
      "},{"location":"qsl4a/hardware/usbserial/","title":"USB \u4e3b\u673a\u4e32\u884c API","text":"

      \u4e0e USB \u4e32\u884c\u8bbe\u5907\u901a\u4fe1\uff08\u9700\u8981 USB OTG \u652f\u6301\u548c Android 3.1+\uff09\u3002

      "},{"location":"qsl4a/hardware/usbserial/#usb","title":"USB \u4e32\u884c\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialopen","title":"usbHostSerialOpen()","text":"

      \u6253\u5f00\u4e0e USB \u4e32\u884c\u8bbe\u5907\u7684\u8fde\u63a5\u3002

      usbHostSerialOpen(device, baudRate=9600)\n

      \u53c2\u6570\uff1a - device (str): USB \u8bbe\u5907\u8def\u5f84\u6216\u6807\u8bc6\u7b26 - baudRate (int): \u6ce2\u7279\u7387\uff08\u9ed8\u8ba4\uff1a9600\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u6253\u5f00\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialclose","title":"usbHostSerialClose()","text":"

      \u5173\u95ed USB \u4e32\u884c\u8fde\u63a5\u3002

      usbHostSerialClose()\n
      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialread","title":"usbHostSerialRead()","text":"

      \u4ece USB \u4e32\u884c\u8bfb\u53d6\u6570\u636e\u3002

      usbHostSerialRead(bufferSize=1024)\n

      \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570\uff08\u9ed8\u8ba4\uff1a1024\uff09

      \u8fd4\u56de\uff1a \u8bfb\u53d6\u7684\u6570\u636e\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwrite","title":"usbHostSerialWrite()","text":"

      \u5411 USB \u4e32\u884c\u5199\u5165\u6570\u636e\u3002

      usbHostSerialWrite(data)\n

      \u53c2\u6570\uff1a - data (str): \u8981\u5199\u5165\u7684\u5b57\u7b26\u4e32\u6570\u636e

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialavailable","title":"usbHostSerialAvailable()","text":"

      \u68c0\u67e5\u662f\u5426\u6709\u53ef\u8bfb\u53d6\u7684\u6570\u636e\u3002

      usbHostSerialAvailable()\n

      \u8fd4\u56de\uff1a \u53ef\u7528\u5b57\u8282\u6570

      "},{"location":"qsl4a/hardware/usbserial/#_1","title":"\u914d\u7f6e\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetbaudrate","title":"usbHostSerialSetBaudRate()","text":"

      \u8bbe\u7f6e\u6ce2\u7279\u7387\u3002

      usbHostSerialSetBaudRate(baudRate)\n

      \u53c2\u6570\uff1a - baudRate (int): \u6ce2\u7279\u7387

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetdatabits","title":"usbHostSerialSetDataBits()","text":"

      \u8bbe\u7f6e\u6570\u636e\u4f4d\uff085\u30016\u30017 \u6216 8\uff09\u3002

      usbHostSerialSetDataBits(dataBits)\n

      \u53c2\u6570\uff1a - dataBits (int): \u6570\u636e\u4f4d\uff085-8\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetstopbits","title":"usbHostSerialSetStopBits()","text":"

      \u8bbe\u7f6e\u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09\u3002

      usbHostSerialSetStopBits(stopBits)\n

      \u53c2\u6570\uff1a - stopBits (float): \u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetparity","title":"usbHostSerialSetParity()","text":"

      \u8bbe\u7f6e\u6821\u9a8c\u4f4d\uff08\u65e0\u3001\u5947\u3001\u5076\u3001\u6807\u8bb0\u3001\u7a7a\u683c\uff09\u3002

      usbHostSerialSetParity(parity)\n

      \u53c2\u6570\uff1a - parity (str): \u6821\u9a8c\u6a21\u5f0f\uff08'none'\u3001'odd'\u3001'even'\u3001'mark'\u3001'space'\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetflowcontrol","title":"usbHostSerialSetFlowControl()","text":"

      \u8bbe\u7f6e\u6d41\u63a7\u5236\uff08\u65e0\u3001\u786c\u4ef6\u3001\u8f6f\u4ef6\uff09\u3002

      usbHostSerialSetFlowControl(flowControl)\n

      \u53c2\u6570\uff1a - flowControl (str): \u6d41\u63a7\u5236\u6a21\u5f0f\uff08'none'\u3001'hardware'\u3001'software'\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialreadhex","title":"usbHostSerialReadHex()","text":"

      \u4ee5\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u8bfb\u53d6\u6570\u636e\u3002

      usbHostSerialReadHex(bufferSize=1024)\n

      \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570

      \u8fd4\u56de\uff1a \u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwritehex","title":"usbHostSerialWriteHex()","text":"

      \u4ece\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u5199\u5165\u6570\u636e\u3002

      usbHostSerialWriteHex(hexString)\n

      \u53c2\u6570\uff1a - hexString (str): \u8981\u5199\u5165\u7684\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/hardware/usbserial/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6253\u5f00 USB \u4e32\u884c\u8fde\u63a5\nif droid.usbHostSerialOpen(\"/dev/bus/usb/001/001\", 115200).result:\n    print(\"USB serial opened\")\n\n    # \u5199\u5165\u6570\u636e\n    droid.usbHostSerialWrite(\"AT\\r\")\n\n    # \u8bfb\u53d6\u54cd\u5e94\n    response = droid.usbHostSerialRead(1024).result\n    print(f\"Response: {response}\")\n\n    # \u6216\u4f7f\u7528\u5341\u516d\u8fdb\u5236\n    droid.usbHostSerialWriteHex(\"41540D0A\")  # \"AT\\r\\n\"\n\n    # \u5173\u95ed\u8fde\u63a5\n    droid.usbHostSerialClose()\n

      \u6ce8\u610f\uff1a USB \u4e32\u884c\u9700\u8981\uff1a - Android 3.1+ (API 12) - USB OTG \u7ebf/\u9002\u914d\u5668 - \u8bbe\u5907\u4e0a\u7684 USB \u4e3b\u673a\u6a21\u5f0f\u652f\u6301 - \u517c\u5bb9\u7684\u4e32\u884c\u8bbe\u5907

      "},{"location":"qsl4a/hardware/webcam/","title":"\u7f51\u7edc\u6444\u50cf\u5934 API","text":"

      \u4f7f\u7528 MJPEG \u4ece\u8bbe\u5907\u76f8\u673a\u6d41\u5f0f\u4f20\u8f93\u89c6\u9891\u3002

      "},{"location":"qsl4a/hardware/webcam/#mjpeg","title":"MJPEG \u6d41\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#webcamstart","title":"webcamStart()","text":"

      \u4ece\u7f51\u7edc\u6444\u50cf\u5934\u542f\u52a8 MJPEG \u6d41\u3002

      webcamStart(resolutionLevel=0, jpegQuality=20, port=0)\n

      \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf 1-100\uff08\u9ed8\u8ba4\uff1a20\uff09 - port (int): \u7aef\u53e3\u53f7\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\uff09

      \u8fd4\u56de\uff1a \u6d41\u7684 (\u5730\u5740, \u7aef\u53e3) \u5143\u7ec4

      "},{"location":"qsl4a/hardware/webcam/#webcamadjustquality","title":"webcamAdjustQuality()","text":"

      \u8c03\u6574\u6d3b\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u7684\u8d28\u91cf\u3002

      webcamAdjustQuality(resolutionLevel=0, jpegQuality=20)\n

      \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b - jpegQuality (int): JPEG \u8d28\u91cf 1-100

      "},{"location":"qsl4a/hardware/webcam/#webcamstop","title":"webcamStop()","text":"

      \u505c\u6b62\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u3002

      webcamStop()\n
      "},{"location":"qsl4a/hardware/webcam/#_1","title":"\u76f8\u673a\u9884\u89c8\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#camerastartpreview","title":"cameraStartPreview()","text":"

      \u5f00\u59cb\u5e26\u4e8b\u4ef6\u751f\u6210\u7684\u76f8\u673a\u9884\u89c8\u6a21\u5f0f\u3002

      cameraStartPreview(resolutionLevel=0, jpegQuality=20, filepath=None)\n

      \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf\uff08\u9ed8\u8ba4\uff1a20\uff09 - filepath (str, optional): \u4fdd\u5b58\u9884\u89c8\u5e27\u7684\u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      \u6ce8\u610f\uff1a \u751f\u6210\u5e26\u6709\u5e27\u6570\u636e\u7684 'preview' \u4e8b\u4ef6\u3002

      "},{"location":"qsl4a/hardware/webcam/#camerastoppreview","title":"cameraStopPreview()","text":"

      \u505c\u6b62\u76f8\u673a\u9884\u89c8\u3002

      cameraStopPreview()\n
      "},{"location":"qsl4a/hardware/webcam/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\nstream_info = droid.webcamStart(\n    resolutionLevel=0,\n    jpegQuality=30,\n    port=8080\n).result\nprint(f\"Stream available at {stream_info[0]}:{stream_info[1]}\")\n\n# \u6d41\u5f0f\u4f20\u8f93\u65f6\u8c03\u6574\u8d28\u91cf\ntime.sleep(5)\ndroid.webcamAdjustQuality(resolutionLevel=1, jpegQuality=50)\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.webcamStop()\n\n# \u6216\u4f7f\u7528\u9884\u89c8\u6a21\u5f0f\nprint(\"Starting preview...\")\ndroid.cameraStartPreview()\n\n# \u7b49\u5f85\u9884\u89c8\u4e8b\u4ef6\nfor i in range(10):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'preview':\n        print(f\"Got preview frame: {event['data']}\")\n\ndroid.cameraStopPreview()\n
      "},{"location":"qsl4a/media/image/","title":"\u56fe\u50cf\u5904\u7406 API","text":"

      \u538b\u7f29\u548c\u5904\u7406\u56fe\u50cf\u3002

      "},{"location":"qsl4a/media/image/#_1","title":"\u56fe\u50cf\u538b\u7f29","text":""},{"location":"qsl4a/media/image/#imagecompress","title":"imageCompress()","text":"

      \u538b\u7f29\u56fe\u50cf\u6587\u4ef6\u3002

      imageCompress(srcPath, destPath, targetByteSize=0, targetWidth=0, targetHeight=0)\n

      \u53c2\u6570\uff1a - srcPath (str): \u6e90\u56fe\u50cf\u8def\u5f84 - destPath (str): \u8f93\u51fa\u8def\u5f84 - targetByteSize (int): \u76ee\u6807\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff080 = \u65e0\u9650\u5236\uff09 - targetWidth (int): \u76ee\u6807\u5bbd\u5ea6\uff080 = \u539f\u59cb\uff09 - targetHeight (int): \u76ee\u6807\u9ad8\u5ea6\uff080 = \u539f\u59cb\uff09

      \u8fd4\u56de\uff1a \u538b\u7f29\u540e\u7684\u56fe\u50cf\u8def\u5f84

      "},{"location":"qsl4a/media/image/#_2","title":"\u622a\u56fe","text":""},{"location":"qsl4a/media/image/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

      \u622a\u53d6\u5c4f\u5e55\u3002

      imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

      \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

      \u8fd4\u56de\uff1a \u622a\u56fe\u8def\u5f84

      "},{"location":"qsl4a/media/image/#_3","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/image/#videoplay","title":"videoPlay()","text":"

      \u5728\u5168\u5c4f\u6a21\u5f0f\u4e0b\u64ad\u653e\u89c6\u9891\u6587\u4ef6\u3002

      videoPlay(path, wait=True)\n

      \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

      "},{"location":"qsl4a/media/image/#_4","title":"\u6761\u7801\u626b\u63cf","text":""},{"location":"qsl4a/media/image/#scanbarcodefromimage","title":"scanBarcodeFromImage()","text":"

      \u4ece\u56fe\u50cf\u6587\u4ef6\u626b\u63cf\u6761\u7801/\u4e8c\u7ef4\u7801\u3002

      scanBarcodeFromImage(path, compressRatio=0, x=0, y=0, width=0, height=0)\n

      \u53c2\u6570\uff1a - path (str): \u56fe\u50cf\u6587\u4ef6\u8def\u5f84 - compressRatio (int): \u538b\u7f29\u6bd4\uff080 = \u4e0d\u538b\u7f29\uff09 - x, y, width, height (int): \u8981\u626b\u63cf\u7684\u533a\u57df\uff080 = \u5b8c\u6574\u56fe\u50cf\uff09

      \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5185\u5bb9

      "},{"location":"qsl4a/media/image/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n\n# \u538b\u7f29\u56fe\u50cf\ncompressed = droid.imageCompress(\n    \"/sdcard/large_photo.jpg\",\n    \"/sdcard/compressed.jpg\",\n    targetByteSize=102400,  # \u76ee\u6807\u7ea6 100KB\n    targetWidth=1920,\n    targetHeight=1080\n).result\nprint(f\"Saved: {compressed}\")\n\n# \u64ad\u653e\u89c6\u9891\nvideo_path = \"/sdcard/movie.mp4\"\ndroid.videoPlay(video_path, wait=True)\n\n# \u4ece\u56fe\u50cf\u626b\u63cf\u6761\u7801\nresult = droid.scanBarcodeFromImage(\"/sdcard/qr_code.png\").result\nprint(f\"Barcode: {result}\")\n
      "},{"location":"qsl4a/media/mediaplayer/","title":"\u5a92\u4f53\u64ad\u653e\u5668 API","text":"

      \u63a7\u5236\u97f3\u9891\u548c\u89c6\u9891\u64ad\u653e\u3002

      "},{"location":"qsl4a/media/mediaplayer/#_1","title":"\u64ad\u653e\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplay","title":"mediaPlay()","text":"

      \u64ad\u653e\u5a92\u4f53\u6587\u4ef6\u3002

      mediaPlay(url, tag=\"default\", play=True)\n

      \u53c2\u6570\uff1a - url (str): \u5a92\u4f53\u6587\u4ef6\u8def\u5f84\u6216 URL - tag (str): \u64ad\u653e\u5668\u6807\u8bc6\u7b26 - play (bool): \u81ea\u52a8\u5f00\u59cb\u64ad\u653e

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaystart","title":"mediaPlayStart()","text":"

      \u5f00\u59cb\u64ad\u653e\u3002

      mediaPlayStart(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplaypause","title":"mediaPlayPause()","text":"

      \u6682\u505c\u64ad\u653e\u3002

      mediaPlayPause(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplayclose","title":"mediaPlayClose()","text":"

      \u5173\u95ed\u64ad\u653e\u5668\u3002

      mediaPlayClose(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplayseek","title":"mediaPlaySeek()","text":"

      \u8df3\u8f6c\u5230\u4f4d\u7f6e\u3002

      mediaPlaySeek(msec, tag=\"default\")\n

      \u53c2\u6570\uff1a - msec (int): \u4f4d\u7f6e\uff08\u6beb\u79d2\uff09

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaysetlooping","title":"mediaPlaySetLooping()","text":"

      \u8bbe\u7f6e\u5faa\u73af\u6a21\u5f0f\u3002

      mediaPlaySetLooping(enabled, tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#_2","title":"\u64ad\u653e\u5668\u4fe1\u606f","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplayinfo","title":"mediaPlayInfo()","text":"

      \u83b7\u53d6\u64ad\u653e\u4fe1\u606f\u3002

      mediaPlayInfo(tag=\"default\")\n

      \u8fd4\u56de\uff1a \u5305\u542b\u65f6\u957f\u3001\u4f4d\u7f6e\u7b49\u7684\u5b57\u5178

      "},{"location":"qsl4a/media/mediaplayer/#mediaisplaying","title":"mediaIsPlaying()","text":"

      \u68c0\u67e5\u662f\u5426\u6b63\u5728\u64ad\u653e\u3002

      mediaIsPlaying(tag=\"default\")\n

      \u8fd4\u56de\uff1a True/False

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaylist","title":"mediaPlayList()","text":"

      \u5217\u51fa\u6d3b\u52a8\u64ad\u653e\u5668\u3002

      mediaPlayList()\n
      "},{"location":"qsl4a/media/mediaplayer/#_3","title":"\u97f3\u91cf\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#getmediavolume","title":"getMediaVolume()","text":"

      \u83b7\u53d6\u5a92\u4f53\u97f3\u91cf\u3002

      getMediaVolume()\n

      \u8fd4\u56de\uff1a \u97f3\u91cf\u7ea7\u522b\uff080-15\uff09

      "},{"location":"qsl4a/media/mediaplayer/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

      getMaxMediaVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#getringervolume","title":"getRingerVolume()","text":"

      \u83b7\u53d6\u94c3\u58f0\u97f3\u91cf\u3002

      getRingerVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

      getMaxRingerVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#_4","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/mediaplayer/#videoplay","title":"videoPlay()","text":"

      \u5168\u5c4f\u64ad\u653e\u89c6\u9891\u3002

      videoPlay(path, wait=True)\n

      \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210

      "},{"location":"qsl4a/media/mediaplayer/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u64ad\u653e\u97f3\u9891\ndroid.mediaPlay(\"/sdcard/music.mp3\", tag=\"music\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.mediaIsPlaying(\"music\").result:\n    info = droid.mediaPlayInfo(\"music\").result\n    print(f\"Playing: {info}\")\n\n# \u8df3\u8f6c\u5230 30 \u79d2\ndroid.mediaPlaySeek(30000, \"music\")\n\n# \u5173\u95ed\ndroid.mediaPlayClose(\"music\")\n\n# \u64ad\u653e\u89c6\u9891\ndroid.videoPlay(\"/sdcard/movie.mp4\", wait=True)\n
      "},{"location":"qsl4a/special/cipher/","title":"\u5bc6\u7801 API","text":"

      \u7528\u4e8e\u5b89\u5168\u6570\u636e\u5b58\u50a8\u7684\u52a0\u5bc6\u548c\u89e3\u5bc6\u5de5\u5177\u3002

      "},{"location":"qsl4a/special/cipher/#_1","title":"\u521d\u59cb\u5316","text":""},{"location":"qsl4a/special/cipher/#cipherinit","title":"cipherInit()","text":"

      \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u548c\u7b97\u6cd5\u521d\u59cb\u5316\u5bc6\u7801\u5668\u3002

      cipherInit(key, algorithm=\"AES/CBC/PKCS5Padding\", encodingFormat=\"\", initialVector=\"\")\n

      \u53c2\u6570\uff1a - key (str or bytes): \u52a0\u5bc6\u5bc6\u94a5 - algorithm (str): \u5bc6\u7801\u7b97\u6cd5\uff08\u9ed8\u8ba4\uff1a\"AES/CBC/PKCS5Padding\"\uff09 - encodingFormat (str): \u7f16\u7801\u683c\u5f0f - initialVector (str or bytes): \u52a0\u5bc6\u7684\u521d\u59cb\u5411\u91cf

      \u8fd4\u56de\uff1a \u521d\u59cb\u5316\u7ed3\u679c

      \u6ce8\u610f\uff1a \u5fc5\u987b\u5728\u4efb\u4f55\u52a0\u5bc6/\u89e3\u5bc6\u64cd\u4f5c\u4e4b\u524d\u8c03\u7528\u3002

      "},{"location":"qsl4a/special/cipher/#_2","title":"\u52a0\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#encryptstring","title":"encryptString()","text":"

      \u52a0\u5bc6\u5b57\u7b26\u4e32\u3002

      encryptString(plainText)\n

      \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c

      \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/special/cipher/#encryptbytes","title":"encryptBytes()","text":"

      \u52a0\u5bc6\u5b57\u8282\u6570\u636e\u3002

      encryptBytes(data)\n

      \u53c2\u6570\uff1a - data (bytes): \u8981\u52a0\u5bc6\u7684\u6570\u636e

      \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u8282

      "},{"location":"qsl4a/special/cipher/#encryptstringtofile","title":"encryptStringToFile()","text":"

      \u52a0\u5bc6\u5b57\u7b26\u4e32\u5230\u6587\u4ef6\u3002

      encryptStringToFile(plainText, filePath)\n

      \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c - filePath (str): \u8f93\u51fa\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/special/cipher/#encryptbytestofile","title":"encryptBytesToFile()","text":"

      \u52a0\u5bc6\u5b57\u8282\u5230\u6587\u4ef6\u3002

      encryptBytesToFile(data, filePath)\n
      "},{"location":"qsl4a/special/cipher/#_3","title":"\u89e3\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#decryptstring","title":"decryptString()","text":"

      \u89e3\u5bc6\u4e3a\u5b57\u7b26\u4e32\u3002

      decryptString(cipherText)\n

      \u53c2\u6570\uff1a - cipherText (str): \u52a0\u5bc6\u7684\u6587\u672c

      \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/special/cipher/#decryptbytes","title":"decryptBytes()","text":"

      \u89e3\u5bc6\u4e3a\u5b57\u8282\u3002

      decryptBytes(data)\n

      \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u8282

      "},{"location":"qsl4a/special/cipher/#decryptfiletostring","title":"decryptFileToString()","text":"

      \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u7b26\u4e32\u3002

      decryptFileToString(filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryptfiletobytes","title":"decryptFileToBytes()","text":"

      \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u8282\u3002

      decryptFileToBytes(filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryptfile","title":"decryptFile()","text":"

      \u89e3\u5bc6\u6587\u4ef6\u5230\u6587\u4ef6\u3002

      decryptFile(srcPath, destPath)\n
      "},{"location":"qsl4a/special/cipher/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u521d\u59cb\u5316\u5bc6\u7801\u5668\ndroid.cipherInit(\"my_secret_key_1234\")\n\n# \u52a0\u5bc6\u5b57\u7b26\u4e32\nencrypted = droid.encryptString(\"Secret message!\").result\nprint(f\"Encrypted: {encrypted}\")\n\n# \u89e3\u5bc6\u5b57\u7b26\u4e32\ndecrypted = droid.decryptString(encrypted).result\nprint(f\"Decrypted: {decrypted}\")\n\n# \u52a0\u5bc6\u5230\u6587\u4ef6\ndroid.encryptStringToFile(\"My secret data\", \"/sdcard/secret.dat\")\n\n# \u4ece\u6587\u4ef6\u89e3\u5bc6\ndata = droid.decryptFileToString(\"/sdcard/secret.dat\").result\nprint(data)\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u7b97\u6cd5\u548c IV \u521d\u59cb\u5316\ndroid.cipherInit(\n    key=\"my_key\",\n    algorithm=\"AES/CBC/PKCS5Padding\",\n    initialVector=\"0123456789abcdef\"\n)\n
      "},{"location":"qsl4a/special/pgptai/","title":"PGPT AI API","text":"

      \u8bed\u97f3\u8f6c\u6587\u672c\u548c AI \u670d\u52a1\u96c6\u6210\u3002

      "},{"location":"qsl4a/special/pgptai/#_1","title":"\u5148\u51b3\u6761\u4ef6","text":"
      pip install pgptAI\n
      "},{"location":"qsl4a/special/pgptai/#_2","title":"\u8bed\u97f3\u8bc6\u522b","text":""},{"location":"qsl4a/special/pgptai/#speechtotext","title":"speechToText()","text":"

      \u5c06\u8bed\u97f3\u8f6c\u6362\u4e3a\u6587\u672c\u3002

      speechToText(RecordSecond=10, AmrFile=None, Language=None)\n

      \u53c2\u6570\uff1a - RecordSecond (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09 - AmrFile (str, optional): \u73b0\u6709\u97f3\u9891\u6587\u4ef6\u8def\u5f84 - Language (str, optional): \u8bed\u8a00\u4ee3\u7801\uff08'en'\u3001'zh'\uff09

      \u8fd4\u56de\uff1a \u8f6c\u5f55\u7684\u6587\u672c

      "},{"location":"qsl4a/special/pgptai/#_3","title":"\u6587\u672c\u8f6c\u8bed\u97f3","text":""},{"location":"qsl4a/special/pgptai/#texttospeech","title":"textToSpeech()","text":"

      \u5c06\u6587\u672c\u8f6c\u6362\u4e3a\u8bed\u97f3\u5e76\u53ef\u9009\u5730\u64ad\u653e\u3002

      textToSpeech(Text, AutoPlay=True, WavFile=None, VoiceName=None)\n

      \u53c2\u6570\uff1a - Text (str): \u8981\u8f6c\u6362\u4e3a\u8bed\u97f3\u7684\u6587\u672c - AutoPlay (bool): \u81ea\u52a8\u64ad\u653e\u751f\u6210\u7684\u97f3\u9891\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - WavFile (str, optional): \u4fdd\u5b58 WAV \u6587\u4ef6\u7684\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u4e34\u65f6\u6587\u4ef6 - VoiceName (str, optional): \u8981\u4f7f\u7528\u7684\u8bed\u97f3\u540d\u79f0\uff08\u4f8b\u5982 'en-US-JennyNeural'\u3001'zh-CN-XiaoxiaoNeural'\uff09

      \u8fd4\u56de\uff1a \u5305\u542b\u8bed\u97f3\u5408\u6210\u7ed3\u679c\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - text: \u8f93\u5165\u6587\u672c - url: \u4e0b\u8f7d\u97f3\u9891\u6587\u4ef6\u7684 URL - WavFile: \u4fdd\u5b58\u7684 WAV \u6587\u4ef6\u8def\u5f84\uff08\u5982\u679c\u672c\u5730\u4fdd\u5b58\uff09

      "},{"location":"qsl4a/special/pgptai/#_4","title":"\u914d\u7f6e","text":"

      API \u4f7f\u7528\u4ee5\u4e0b\u914d\u7f6e\u6587\u4ef6\u4e2d\u7684\u914d\u7f6e\uff1a/storage/emulated/0/Android/data/org.qpython.qpy/files/apigpt.conf\uff1a

      [speech]\nspeech_key = your_api_key\n

      \u9ed8\u8ba4\u8bed\u97f3\u8bbe\u7f6e\uff1a - \u82f1\u8bed\uff1aen-US-JennyNeural - \u4e2d\u6587\uff1azh-CN-XiaoxiaoNeural

      "},{"location":"qsl4a/special/pgptai/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5f55\u5236\u5e76\u8f6c\u5f55\nprint(\"Recording for 5 seconds...\")\ntext = droid.speechToText(RecordSecond=5, Language='en').result\nprint(f\"You said: {text}\")\n\n# \u8f6c\u5f55\u73b0\u6709\u6587\u4ef6\ntext = droid.speechToText(AmrFile=\"/sdcard/recording.amr\").result\nprint(f\"Transcription: {text}\")\n\n# \u6587\u672c\u8f6c\u8bed\u97f3\ndroid.textToSpeech(\"Hello, this is a test message.\", AutoPlay=True, Language='en')\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u8bed\u97f3\u5e76\u4fdd\u5b58\u5230\u6587\u4ef6\u7684\u6587\u672c\u8f6c\u8bed\u97f3\nresult = droid.textToSpeech(\n    \"Welcome to QPython!\",\n    AutoPlay=False,\n    WavFile=\"/sdcard/welcome.wav\",\n    VoiceName=\"en-US-JennyNeural\"\n).result\nprint(f\"Audio saved to: {result.get('WavFile')}\")\n
      "},{"location":"qsl4a/special/pgptai/#_6","title":"\u7c7b\u4f7f\u7528","text":"
      from androidhelper.pgptai import pgptai\nimport androidhelper\n\ndroid = androidhelper.Android()\nai = pgptai(droid)\n\n# \u4f7f\u7528\u8bed\u97f3\u8bc6\u522b\ntext = ai.speechToText(RecordSecond=10)\n
      "},{"location":"qsl4a/storage/clipboard/","title":"\u526a\u8d34\u677f API","text":"

      \u590d\u5236\u548c\u7c98\u8d34\u6587\u672c\u5230\u7cfb\u7edf\u526a\u8d34\u677f\u3002

      "},{"location":"qsl4a/storage/clipboard/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/clipboard/#setclipboard","title":"setClipboard()","text":"

      \u590d\u5236\u6587\u672c\u5230\u526a\u8d34\u677f\u3002

      setClipboard(text)\n

      \u53c2\u6570\uff1a - text (str): \u8981\u590d\u5236\u7684\u6587\u672c

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/clipboard/#getclipboard","title":"getClipboard()","text":"

      \u4ece\u526a\u8d34\u677f\u83b7\u53d6\u6587\u672c\u3002

      getClipboard()\n

      \u8fd4\u56de\uff1a \u526a\u8d34\u677f\u6587\u672c

      "},{"location":"qsl4a/storage/clipboard/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u590d\u5236\u5230\u526a\u8d34\u677f\ndroid.setClipboard(\"Hello from QPython!\")\n\n# \u4ece\u526a\u8d34\u677f\u7c98\u8d34\ntext = droid.getClipboard().result\nprint(f\"Clipboard: {text}\")\n
      "},{"location":"qsl4a/storage/documentfile/","title":"DocumentFile API","text":"

      \u4f7f\u7528 SAF\uff08\u5b58\u50a8\u8bbf\u95ee\u6846\u67b6\uff09\u8fdb\u884c\u6587\u4ef6\u64cd\u4f5c\uff0c\u652f\u6301 Android 4.4+\u3002

      "},{"location":"qsl4a/storage/documentfile/#_1","title":"\u76ee\u5f55\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilemkdir","title":"documentFileMkdir()","text":"

      \u521b\u5efa\u76ee\u5f55\u3002

      documentFileMkdir(Dir)\n

      \u53c2\u6570\uff1a - Dir (str): \u76ee\u5f55\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/documentfile/#documentfilelistfiles","title":"documentFileListFiles()","text":"

      \u5217\u51fa\u76ee\u5f55\u4e2d\u7684\u6587\u4ef6\u3002

      documentFileListFiles(Folder)\n

      \u8fd4\u56de\uff1a \u6587\u4ef6\u5217\u8868

      "},{"location":"qsl4a/storage/documentfile/#_2","title":"\u6587\u4ef6\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileexists","title":"documentFileExists()","text":"

      \u68c0\u67e5\u6587\u4ef6\u6216\u76ee\u5f55\u662f\u5426\u5b58\u5728\u3002

      documentFileExists(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u6216\u76ee\u5f55\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u5b58\u5728\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/storage/documentfile/#documentfileisfile","title":"documentFileIsFile()","text":"

      \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u6587\u4ef6\u3002

      documentFileIsFile(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u662f\u6587\u4ef6\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u6587\u4ef6\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

      "},{"location":"qsl4a/storage/documentfile/#documentfileisdirectory","title":"documentFileIsDirectory()","text":"

      \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u76ee\u5f55\u3002

      documentFileIsDirectory(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u662f\u76ee\u5f55\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u76ee\u5f55\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

      "},{"location":"qsl4a/storage/documentfile/#documentfiledelete","title":"documentFileDelete()","text":"

      \u5220\u9664\u6587\u4ef6\u6216\u76ee\u5f55\u3002

      documentFileDelete(FileOrTree)\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/documentfile/#documentfilerenameto","title":"documentFileRenameTo()","text":"

      \u91cd\u547d\u540d\u6216\u79fb\u52a8\u6587\u4ef6\u3002

      documentFileRenameTo(Src, Dest)\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/documentfile/#documentfilecopy","title":"documentFileCopy()","text":"

      \u590d\u5236\u6587\u4ef6\u3002

      documentFileCopy(SrcFileOrTree, DestFileOrTree)\n
      "},{"location":"qsl4a/storage/documentfile/#_3","title":"\u6d41\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileinputstream","title":"documentFileInputStream()","text":"

      \u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9\u3002

      documentFileInputStream(srcFile, EncodingFormat=\"\", skip=None, length=None)\n

      \u53c2\u6570\uff1a - srcFile (str): \u6e90\u6587\u4ef6 - EncodingFormat (str): \"UTF-8\"\u3001\"GBK\"\u3001\"Base64\" \u6216\u7a7a\u5b57\u7b26\u4e32\u8868\u793a\u5b57\u8282 - skip (int): \u4ece\u5f00\u5934\u8df3\u8fc7\u7684\u5b57\u8282\u6570 - length (int): \u8bfb\u53d6\u957f\u5ea6

      \u8fd4\u56de\uff1a \u6587\u4ef6\u5185\u5bb9

      "},{"location":"qsl4a/storage/documentfile/#documentfileoutputstream","title":"documentFileOutputStream()","text":"

      \u5199\u5165\u6587\u4ef6\u5185\u5bb9\u3002

      documentFileOutputStream(destFile, src, EncodingFormat=\"\", append=None)\n

      \u53c2\u6570\uff1a - destFile (str): \u76ee\u6807\u6587\u4ef6 - src: \u8981\u5199\u5165\u7684\u6570\u636e - EncodingFormat (str): \u7f16\u7801\u683c\u5f0f - append (bool): \u8ffd\u52a0\u6a21\u5f0f

      "},{"location":"qsl4a/storage/documentfile/#_4","title":"\u6587\u4ef6\u4fe1\u606f","text":""},{"location":"qsl4a/storage/documentfile/#documentfilelength","title":"documentFileLength()","text":"

      \u83b7\u53d6\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\u3002

      documentFileLength(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

      "},{"location":"qsl4a/storage/documentfile/#documentfilelastmodified","title":"documentFileLastModified()","text":"

      \u83b7\u53d6\u6700\u540e\u4fee\u6539\u65f6\u95f4\u3002

      documentFileLastModified(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u65f6\u95f4\u6233\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

      "},{"location":"qsl4a/storage/documentfile/#documentfilegetstat","title":"documentFileGetStat()","text":"

      \u83b7\u53d6\u5168\u9762\u7684\u6587\u4ef6\u7edf\u8ba1\u4fe1\u606f\u3002

      documentFileGetStat(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5305\u542b\u957f\u5ea6\u3001\u6700\u540e\u4fee\u6539\u65f6\u95f4\u548c\u8bfb/\u5199\u6743\u9650\u7684\u5b57\u5178\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

      "},{"location":"qsl4a/storage/documentfile/#uri","title":"URI \u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilegeturi","title":"documentFileGetUri()","text":"

      \u4ece\u8def\u5f84\u83b7\u53d6 URI\u3002

      documentFileGetUri(path, isDirectory=None)\n
      "},{"location":"qsl4a/storage/documentfile/#documentfileshowopen","title":"documentFileShowOpen()","text":"

      \u663e\u793a\u6587\u4ef6\u9009\u62e9\u5668\u3002

      documentFileShowOpen()\n

      \u8fd4\u56de\uff1a \u9009\u62e9\u7684\u6587\u4ef6 URI

      "},{"location":"qsl4a/storage/documentfile/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u76ee\u5f55\ndroid.documentFileMkdir(\"/sdcard/MyFolder\")\n\n# \u5217\u51fa\u6587\u4ef6\nfiles = droid.documentFileListFiles(\"/sdcard\").result\nfor f in files:\n    print(f)\n\n# \u8bfb\u53d6\u6587\u4ef6\ncontent = droid.documentFileInputStream(\n    \"/sdcard/test.txt\",\n    EncodingFormat=\"UTF-8\"\n).result\nprint(content)\n\n# \u5199\u5165\u6587\u4ef6\ndroid.documentFileOutputStream(\n    \"/sdcard/output.txt\",\n    \"Hello World\",\n    EncodingFormat=\"UTF-8\"\n)\n
      "},{"location":"qsl4a/storage/preferences/","title":"\u504f\u597d\u8bbe\u7f6e API","text":"

      \u4f7f\u7528 Android SharedPreferences \u5b58\u50a8\u548c\u68c0\u7d22\u6570\u636e\u3002

      "},{"location":"qsl4a/storage/preferences/#_1","title":"\u504f\u597d\u8bbe\u7f6e\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/preferences/#prefgetvalue","title":"prefGetValue()","text":"

      \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u8bfb\u53d6\u503c\u3002

      prefGetValue(key, filename=None)\n

      \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c\uff08\u4efb\u610f\u7c7b\u578b\uff09

      "},{"location":"qsl4a/storage/preferences/#prefputvalue","title":"prefPutValue()","text":"

      \u5199\u5165\u503c\u5230\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u3002

      prefPutValue(key, value, filename=None)\n

      \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - value (object): \u8981\u5b58\u50a8\u7684\u503c - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      "},{"location":"qsl4a/storage/preferences/#prefgetall","title":"prefGetAll()","text":"

      \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\u503c\u3002

      prefGetAll(filename=None)\n

      \u53c2\u6570\uff1a - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      \u8fd4\u56de\uff1a \u6240\u6709\u504f\u597d\u7684\u6620\u5c04

      "},{"location":"qsl4a/storage/preferences/#prefremovevalue","title":"prefRemoveValue()","text":"

      \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u4e2d\u79fb\u9664\u503c\u3002

      prefRemoveValue(key, filename=None)\n

      \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      "},{"location":"qsl4a/storage/preferences/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b58\u50a8\u503c\ndroid.prefPutValue(\"username\", \"alice\")\ndroid.prefPutValue(\"score\", 100)\ndroid.prefPutValue(\"enabled\", True)\n\n# \u8bfb\u53d6\u7279\u5b9a\u503c\nusername = droid.prefGetValue(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\nall_prefs = droid.prefGetAll().result\nprint(f\"All prefs: {all_prefs}\")\n\n# \u79fb\u9664\u503c\ndroid.prefRemoveValue(\"score\")\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u6587\u4ef6\u540d\ndroid.prefPutValue(\"token\", \"abc123\", filename=\"auth.prefs\")\ntoken = droid.prefGetValue(\"token\", filename=\"auth.prefs\").result\n
      "},{"location":"qsl4a/system/activityresult/","title":"Activity Result API","text":"

      \u4e3a\u901a\u8fc7 startActivityForResult \u542f\u52a8\u7684\u811a\u672c\u8bbe\u7f6e activity \u7ed3\u679c\u3002

      "},{"location":"qsl4a/system/activityresult/#_1","title":"\u7ed3\u679c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/activityresult/#setresultboolean","title":"setResultBoolean()","text":"

      \u8bbe\u7f6e\u5e03\u5c14\u7ed3\u679c\u3002

      setResultBoolean(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (bool): \u5e03\u5c14\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultbyte","title":"setResultByte()","text":"

      \u8bbe\u7f6e\u5b57\u8282\u7ed3\u679c\u3002

      setResultByte(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u5b57\u8282\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultshort","title":"setResultShort()","text":"

      \u8bbe\u7f6e\u77ed\u6574\u6570\u7ed3\u679c\u3002

      setResultShort(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u77ed\u6574\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultchar","title":"setResultChar()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u7ed3\u679c\u3002

      setResultChar(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultinteger","title":"setResultInteger()","text":"

      \u8bbe\u7f6e\u6574\u6570\u7ed3\u679c\u3002

      setResultInteger(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u6574\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultlong","title":"setResultLong()","text":"

      \u8bbe\u7f6e\u957f\u6574\u6570\u7ed3\u679c\u3002

      setResultLong(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u957f\u6574\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultfloat","title":"setResultFloat()","text":"

      \u8bbe\u7f6e\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

      setResultFloat(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u6d6e\u70b9\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultdouble","title":"setResultDouble()","text":"

      \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

      setResultDouble(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultstring","title":"setResultString()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u4e32\u7ed3\u679c\u3002

      setResultString(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u4e32\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultbooleanarray","title":"setResultBooleanArray()","text":"

      \u8bbe\u7f6e\u5e03\u5c14\u6570\u7ec4\u7ed3\u679c\u3002

      setResultBooleanArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5e03\u5c14\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultbytearray","title":"setResultByteArray()","text":"

      \u8bbe\u7f6e\u5b57\u8282\u6570\u7ec4\u7ed3\u679c\u3002

      setResultByteArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u8282\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultshortarray","title":"setResultShortArray()","text":"

      \u8bbe\u7f6e\u77ed\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultShortArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u77ed\u6574\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultchararray","title":"setResultCharArray()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u6570\u7ec4\u7ed3\u679c\u3002

      setResultCharArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultintegerarray","title":"setResultIntegerArray()","text":"

      \u8bbe\u7f6e\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultIntegerArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6574\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultlongarray","title":"setResultLongArray()","text":"

      \u8bbe\u7f6e\u957f\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultLongArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u957f\u6574\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultfloatarray","title":"setResultFloatArray()","text":"

      \u8bbe\u7f6e\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultFloatArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6d6e\u70b9\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultdoublearray","title":"setResultDoubleArray()","text":"

      \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultDoubleArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultstringarray","title":"setResultStringArray()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u4e32\u6570\u7ec4\u7ed3\u679c\u3002

      setResultStringArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u4e32\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultserializable","title":"setResultSerializable()","text":"

      \u8bbe\u7f6e\u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u3002

      setResultSerializable(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue: \u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c activity \u540e\uff0c\u8bbe\u7f6e\u7ed3\u679c\n# \u793a\u4f8b\uff1a\u8fd4\u56de\u6210\u529f\u53ca\u6570\u636e\ndroid.setResultInteger(0, 200)  # RESULT_OK\ndroid.setResultString(0, \"Operation completed successfully\")\n\n# \u8fd4\u56de\u6570\u7ec4\u7ed3\u679c\ndroid.setResultIntegerArray(0, [1, 2, 3, 4, 5])\n
      "},{"location":"qsl4a/system/application/","title":"\u5e94\u7528\u7ba1\u7406","text":"

      \u7ba1\u7406\u5e94\u7528\u7a0b\u5e8f\u3001\u542f\u52a8\u5e94\u7528\u548c\u67e5\u8be2\u7cfb\u7edf\u4fe1\u606f\u3002

      "},{"location":"qsl4a/system/application/#_2","title":"\u5e94\u7528\u7a0b\u5e8f\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getapplicationinfo","title":"getApplicationInfo()","text":"

      \u83b7\u53d6\u5e94\u7528\u4fe1\u606f\u3002

      getApplicationInfo(packageName=None)\n

      \u53c2\u6570\uff1a - packageName (str): \u5305\u540d\uff08None = \u5f53\u524d\u5e94\u7528\uff09

      \u8fd4\u56de\uff1a \u5e94\u7528\u4fe1\u606f\u5b57\u5178

      "},{"location":"qsl4a/system/application/#getinstalledpackages","title":"getInstalledPackages()","text":"

      \u83b7\u53d6\u5df2\u5b89\u88c5\u5305\u5217\u8868\u3002

      getInstalledPackages(flag=4)\n

      \u53c2\u6570\uff1a - flag (int): \u5305\u6807\u5fd7\u8fc7\u6ee4\u5668\uff08\u9ed8\u8ba4\uff1a4\uff09

      \u8fd4\u56de\uff1a \u5df2\u5b89\u88c5\u5305\u5217\u8868

      "},{"location":"qsl4a/system/application/#getrunningpackages","title":"getRunningPackages()","text":"

      \u5217\u51fa\u6b63\u5728\u8fd0\u884c\u7684\u5305\u3002

      getRunningPackages()\n

      \u8fd4\u56de\uff1a \u5305\u540d\u5217\u8868

      "},{"location":"qsl4a/system/application/#getlaunchablepackages","title":"getLaunchablePackages()","text":"

      \u83b7\u53d6\u53ef\u542f\u52a8\u5305\u5217\u8868\u3002

      getLaunchablePackages(needClassName=False)\n

      \u53c2\u6570\uff1a - needClassName (bool): \u5305\u542b\u4e3b activity \u7c7b\u540d\uff08\u9ed8\u8ba4\uff1aFalse\uff09

      \u8fd4\u56de\uff1a \u53ef\u542f\u52a8\u5305\u540d\u5217\u8868\u6216\u5305\u542b\u7c7b\u540d\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#_3","title":"\u5e94\u7528\u63a7\u5236","text":""},{"location":"qsl4a/system/application/#launch","title":"launch()","text":"

      \u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u3002

      launch(classname=None, packagename=None, wait=True)\n

      \u53c2\u6570\uff1a - classname (str): \u4e3b activity \u7c7b\u540d - packagename (str): \u5305\u540d - wait (bool): \u7b49\u5f85\u542f\u52a8\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

      \u8fd4\u56de\uff1a \u542f\u52a8\u7ed3\u679c

      "},{"location":"qsl4a/system/application/#forcestoppackage","title":"forceStopPackage()","text":"

      \u5f3a\u5236\u505c\u6b62\u5e94\u7528\u7a0b\u5e8f\u3002

      forceStopPackage(packageName)\n

      \u53c2\u6570\uff1a - packageName (str): \u8981\u505c\u6b62\u7684\u5305\u540d

      "},{"location":"qsl4a/system/application/#_4","title":"\u7248\u672c\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getpackageversion","title":"getPackageVersion()","text":"

      \u83b7\u53d6\u5e94\u7528\u7248\u672c\u540d\u79f0\u3002

      getPackageVersion(packageName)\n

      \u8fd4\u56de\uff1a \u7248\u672c\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"3.2.1\"\uff09

      "},{"location":"qsl4a/system/application/#getpackageversioncode","title":"getPackageVersionCode()","text":"

      \u83b7\u53d6\u5e94\u7528\u7248\u672c\u4ee3\u7801\u3002

      getPackageVersionCode(packageName)\n

      \u8fd4\u56de\uff1a \u7248\u672c\u4ee3\u7801\u6574\u6570

      "},{"location":"qsl4a/system/application/#getconstants","title":"getConstants()","text":"

      \u83b7\u53d6\u7c7b\u5e38\u91cf\u3002

      getConstants(classname)\n

      \u53c2\u6570\uff1a - classname (str): \u5b8c\u6574\u7c7b\u540d

      \u8fd4\u56de\uff1a \u5e38\u91cf\u540d\u548c\u503c\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#_5","title":"\u7cfb\u7edf\u529f\u80fd","text":""},{"location":"qsl4a/system/application/#backgroundprotect","title":"backgroundProtect()","text":"

      \u542f\u7528\u6216\u7981\u7528\u5e94\u7528\u7684\u540e\u53f0\u4fdd\u62a4\u3002

      backgroundProtect(enabled=True)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\u4fdd\u62a4\uff0cFalse \u7981\u7528

      "},{"location":"qsl4a/system/application/#createscriptshortcut","title":"createScriptShortCut()","text":"

      \u4e3a\u811a\u672c\u521b\u5efa\u4e3b\u5c4f\u5e55\u5feb\u6377\u65b9\u5f0f\u3002

      createScriptShortCut(scriptPath, label=None, iconPath=None, scriptArg=None)\n

      \u53c2\u6570\uff1a - scriptPath (str): Python \u811a\u672c\u8def\u5f84 - label (str, optional): \u5feb\u6377\u65b9\u5f0f\u6807\u7b7e - iconPath (str, optional): \u56fe\u6807\u56fe\u50cf\u8def\u5f84 - scriptArg (str, optional): \u4f20\u9012\u7ed9\u811a\u672c\u7684\u53c2\u6570

      "},{"location":"qsl4a/system/application/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getandroidid","title":"getAndroidID()","text":"

      \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

      getAndroidID()\n

      \u8fd4\u56de\uff1a \u552f\u4e00\u7684 Android \u8bbe\u5907 ID \u5b57\u7b26\u4e32

      "},{"location":"qsl4a/system/application/#getsysinfo","title":"getSysInfo()","text":"

      \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\u3002

      getSysInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#getlocale","title":"getLocale()","text":"

      \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u3002

      getLocale()\n

      \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

      "},{"location":"qsl4a/system/application/#getharmonyosinformation","title":"getHarmonyOsInformation()","text":"

      \u5982\u679c\u5728 HarmonyOS \u4e0a\u8fd0\u884c\uff0c\u83b7\u53d6 HarmonyOS \u4fe1\u606f\u3002

      getHarmonyOsInformation()\n

      \u8fd4\u56de\uff1a HarmonyOS \u7248\u672c\u4fe1\u606f\u6216 None

      "},{"location":"qsl4a/system/application/#isexternalstoragemanager","title":"isExternalStorageManager()","text":"

      \u68c0\u67e5\u5e94\u7528\u662f\u5426\u6709\u5916\u90e8\u5b58\u50a8\u7ba1\u7406\u5668\u6743\u9650\u3002

      isExternalStorageManager()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6709\u6743\u9650\u5219\u4e3a True

      "},{"location":"qsl4a/system/application/#_7","title":"\u5185\u5b58\u548c\u663e\u793a","text":""},{"location":"qsl4a/system/application/#getmemoryinfo","title":"getMemoryInfo()","text":"

      \u83b7\u53d6\u5185\u5b58\u4fe1\u606f\u3002

      getMemoryInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#getscreeninfo","title":"getScreenInfo()","text":"

      \u83b7\u53d6\u5c4f\u5e55\u4fe1\u606f\u3002

      getScreenInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#_8","title":"\u6743\u9650","text":""},{"location":"qsl4a/system/application/#checkpermissions","title":"checkPermissions()","text":"

      \u68c0\u67e5\u5f53\u524d\u5e94\u7528\u6743\u9650\u3002

      checkPermissions()\n

      \u8fd4\u56de\uff1a \u6743\u9650\u53ca\u5176\u72b6\u6001\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#requestpermissions","title":"requestPermissions()","text":"

      \u5411\u7528\u6237\u8bf7\u6c42\u6743\u9650\u3002

      requestPermissions(permissions=None)\n

      \u53c2\u6570\uff1a - permissions (list, optional): \u8981\u8bf7\u6c42\u7684\u6743\u9650\u5217\u8868\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8bf7\u6c42\u6240\u6709\u9700\u8981\u7684\u6743\u9650\u3002

      \u8fd4\u56de\uff1a \u6743\u9650\u8bf7\u6c42\u7ed3\u679c

      "},{"location":"qsl4a/system/application/#_9","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/system/application/#showscreenlock","title":"showScreenLock()","text":"

      \u663e\u793a\u5c4f\u5e55\u9501\u5b9a\uff08PIN/\u56fe\u6848/\u5bc6\u7801\u8f93\u5165\uff09\u3002

      showScreenLock()\n
      "},{"location":"qsl4a/system/application/#_10","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\ninfo = droid.getSysInfo().result\nprint(f\"System: {info}\")\n\n# \u83b7\u53d6\u5e94\u7528\u7248\u672c\nversion = droid.getPackageVersion(\"org.qpython.qpy\").result\nprint(f\"QPython version: {version}\")\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u5e94\u7528\napps = droid.getInstalledPackages().result\nprint(f\"Installed apps: {len(apps)}\")\n\n# \u542f\u52a8\u5e94\u7528\ndroid.launch(packagename=\"com.android.settings\")\n\n# \u68c0\u67e5\u6743\u9650\nperms = droid.checkPermissions().result\nprint(f\"Permissions: {perms}\")\n\n# \u8bf7\u6c42\u5b58\u50a8\u6743\u9650\ndroid.requestPermissions([\"android.permission.READ_EXTERNAL_STORAGE\"])\n\n# \u521b\u5efa\u5feb\u6377\u65b9\u5f0f\ndroid.createScriptShortCut(\n    \"/sdcard/my_script.py\",\n    label=\"My Script\",\n    iconPath=\"/sdcard/icon.png\"\n)\n
      "},{"location":"qsl4a/system/battery/","title":"\u7535\u6c60 API","text":"

      \u76d1\u63a7\u8bbe\u5907\u7535\u6c60\u72b6\u6001\u548c\u5065\u5eb7\u72b6\u51b5\u3002

      "},{"location":"qsl4a/system/battery/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/battery/#readbatterydata","title":"readBatteryData()","text":"

      \u83b7\u53d6\u5b8c\u6574\u7684\u7535\u6c60\u4fe1\u606f\u3002

      readBatteryData()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7535\u6c60\u6570\u636e\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/battery/#batterystartmonitoring","title":"batteryStartMonitoring()","text":"

      \u5f00\u59cb\u7535\u6c60\u76d1\u63a7\u3002

      batteryStartMonitoring()\n
      "},{"location":"qsl4a/system/battery/#batterystopmonitoring","title":"batteryStopMonitoring()","text":"

      \u505c\u6b62\u7535\u6c60\u76d1\u63a7\u3002

      batteryStopMonitoring()\n
      "},{"location":"qsl4a/system/battery/#batterygetlevel","title":"batteryGetLevel()","text":"

      \u83b7\u53d6\u7535\u6c60\u767e\u5206\u6bd4\u3002

      batteryGetLevel()\n

      \u8fd4\u56de\uff1a \u6574\u6570\uff080-100\uff09

      "},{"location":"qsl4a/system/battery/#batterygetstatus","title":"batteryGetStatus()","text":"

      \u83b7\u53d6\u5145\u7535\u72b6\u6001\u3002

      batteryGetStatus()\n

      \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u5145\u7535\u4e2d - 3: \u653e\u7535\u4e2d - 4: \u672a\u5145\u7535 - 5: \u5df2\u5145\u6ee1

      "},{"location":"qsl4a/system/battery/#batterygetplugtype","title":"batteryGetPlugType()","text":"

      \u83b7\u53d6\u7535\u6e90\u7c7b\u578b\u3002

      batteryGetPlugType()\n

      \u8fd4\u56de\uff1a - -1: \u672a\u77e5 - 0: \u672a\u63d2\u7535 - 1: AC \u5145\u7535\u5668 - 2: USB \u7aef\u53e3

      "},{"location":"qsl4a/system/battery/#batterygethealth","title":"batteryGetHealth()","text":"

      \u83b7\u53d6\u7535\u6c60\u5065\u5eb7\u72b6\u51b5\u3002

      batteryGetHealth()\n

      \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u826f\u597d - 3: \u8fc7\u70ed - 4: \u635f\u574f - 5: \u8fc7\u538b - 6: \u672a\u6307\u5b9a\u7684\u6545\u969c

      "},{"location":"qsl4a/system/battery/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\nlevel = droid.batteryGetLevel().result\nprint(f\"Battery: {level}%\")\n
      "},{"location":"qsl4a/system/qpyinterface/","title":"QPython \u63a5\u53e3 API","text":"

      \u4ece\u5176\u4ed6\u5e94\u7528\u6267\u884c QPython \u811a\u672c\u548c\u7ba1\u7406\u5171\u4eab\u53d8\u91cf\u3002

      "},{"location":"qsl4a/system/qpyinterface/#_1","title":"\u811a\u672c\u6267\u884c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/qpyinterface/#executeqpy","title":"executeQPy()","text":"

      \u6267\u884c QPython \u811a\u672c\u3002

      executeQPy(path=\"\", arg=None)\n

      \u53c2\u6570\uff1a - path (str): \u811a\u672c\u6587\u4ef6\u8def\u5f84 - arg (str, optional): \u547d\u4ee4\u884c\u53c2\u6570

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#executeqpyassrv","title":"executeQPyAsSrv()","text":"

      \u4f5c\u4e3a\u670d\u52a1\u6267\u884c QPython \u811a\u672c\u3002

      executeQPyAsSrv(path=None)\n

      \u53c2\u6570\uff1a - path (str, optional): \u811a\u672c\u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#executeqpycode","title":"executeQPyCode()","text":"

      \u76f4\u63a5\u6267\u884c Python \u4ee3\u7801\u3002

      executeQPyCode(code=None)\n

      \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#executeqpycodeassrv","title":"executeQPyCodeAsSrv()","text":"

      \u4f5c\u4e3a\u670d\u52a1\u6267\u884c Python \u4ee3\u7801\u3002

      executeQPyCodeAsSrv(code=None)\n

      \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#_2","title":"\u5171\u4eab\u53d8\u91cf","text":"

      \u5171\u4eab\u53d8\u91cf\u5141\u8bb8 QPython \u4e0e\u5176\u4ed6\u5e94\u7528\u4e4b\u95f4\u8fdb\u884c\u901a\u4fe1\u3002

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableset","title":"sharedVariableSet()","text":"

      \u8bbe\u7f6e Java \u5171\u4eab\u53d8\u91cf\u3002

      sharedVariableSet(key, value)\n

      \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d - value (str): \u53d8\u91cf\u503c

      \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableget","title":"sharedVariableGet()","text":"

      \u83b7\u53d6 Java \u5171\u4eab\u53d8\u91cf\u3002

      sharedVariableGet(key)\n

      \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d

      \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableremove","title":"sharedVariableRemove()","text":"

      \u79fb\u9664 Java \u5171\u4eab\u53d8\u91cf\u3002

      sharedVariableRemove(key)\n

      \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u53d8\u91cf\u540d

      \u8fd4\u56de\uff1a \u88ab\u79fb\u9664\u7684\u503c

      "},{"location":"qsl4a/system/qpyinterface/#getlastlog","title":"getLastLog()","text":"

      \u83b7\u53d6 QPython \u7684\u6700\u540e\u65e5\u5fd7\u8f93\u51fa\u3002

      getLastLog()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u65e5\u5fd7\u5185\u5bb9

      "},{"location":"qsl4a/system/qpyinterface/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c\u811a\u672c\ndroid.executeQPy(\"/sdcard/my_script.py\", arg=\"test\")\n\n# \u76f4\u63a5\u6267\u884c\u4ee3\u7801\ncode = \"print('Hello from QPython!')\"\ndroid.executeQPyCode(code)\n\n# \u4f7f\u7528\u5171\u4eab\u53d8\u91cf\ndroid.sharedVariableSet(\"username\", \"alice\")\nusername = droid.sharedVariableGet(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u79fb\u9664\u53d8\u91cf\ndroid.sharedVariableRemove(\"username\")\n\n# \u83b7\u53d6\u6700\u8fd1\u65e5\u5fd7\nlog = droid.getLastLog().result\nprint(f\"Log: {log}\")\n
      "},{"location":"qsl4a/system/sensors/","title":"\u4f20\u611f\u5668 API","text":"

      \u8bbf\u95ee\u8bbe\u5907\u4f20\u611f\u5668\uff0c\u5305\u62ec\u52a0\u901f\u5ea6\u8ba1\u3001\u9640\u87ba\u4eea\u3001\u78c1\u529b\u8ba1\u7b49\u3002

      "},{"location":"qsl4a/system/sensors/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/sensors/#startsensingtimed","title":"startSensingTimed()","text":"

      \u5f00\u59cb\u4f20\u611f\u5668\u76d1\u63a7\u5e76\u8bbe\u7f6e\u65f6\u95f4\u95f4\u9694\u3002

      startSensingTimed(sensorNumber, delayTime)\n

      \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID\uff08\u901a\u5e38\u4e3a 1-3\uff09 - delayTime (int): \u8bfb\u53d6\u4e4b\u95f4\u7684\u5ef6\u8fdf\uff08\u6beb\u79d2\uff09

      "},{"location":"qsl4a/system/sensors/#startsensingthreshold","title":"startSensingThreshold()","text":"

      \u5f00\u59cb\u5e26\u9608\u503c\u89e6\u53d1\u7684\u4f20\u611f\u5668\u76d1\u63a7\u3002

      startSensingThreshold(sensorNumber, threshold, axis)\n

      \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID - threshold (float): \u89e6\u53d1\u9608\u503c - axis (int): \u8981\u76d1\u63a7\u7684\u8f74\uff080=X\uff0c1=Y\uff0c2=Z\uff09

      "},{"location":"qsl4a/system/sensors/#stopsensing","title":"stopSensing()","text":"

      \u505c\u6b62\u6240\u6709\u4f20\u611f\u5668\u76d1\u63a7\u3002

      stopSensing()\n
      "},{"location":"qsl4a/system/sensors/#readsensors","title":"readSensors()","text":"

      \u8bfb\u53d6\u5f53\u524d\u4f20\u611f\u5668\u6570\u636e\u3002

      readSensors()\n

      \u8fd4\u56de\uff1a \u4f20\u611f\u5668\u6570\u636e\u5b57\u5178

      "},{"location":"qsl4a/system/sensors/#sensorsreadaccelerometer","title":"sensorsReadAccelerometer()","text":"

      \u8bfb\u53d6\u52a0\u901f\u5ea6\u8ba1\u503c\u3002

      sensorsReadAccelerometer()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d m/s\u00b2

      "},{"location":"qsl4a/system/sensors/#sensorsreadgyroscope","title":"sensorsReadGyroscope()","text":"

      \u8bfb\u53d6\u9640\u87ba\u4eea\u503c\u3002

      sensorsReadGyroscope()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d rad/s

      "},{"location":"qsl4a/system/sensors/#sensorsreadmagnetometer","title":"sensorsReadMagnetometer()","text":"

      \u8bfb\u53d6\u78c1\u573a\u503c\u3002

      sensorsReadMagnetometer()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d \u03bcT

      "},{"location":"qsl4a/system/sensors/#sensorsreadorientation","title":"sensorsReadOrientation()","text":"

      \u8bfb\u53d6\u8bbe\u5907\u65b9\u5411\u3002

      sensorsReadOrientation()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [azimuth, pitch, roll]\uff0c\u5355\u4f4d\u5ea6

      "},{"location":"qsl4a/system/sensors/#sensorsgetlight","title":"sensorsGetLight()","text":"

      \u8bfb\u53d6\u5149\u4f20\u611f\u5668\u503c\u3002

      sensorsGetLight()\n

      \u8fd4\u56de\uff1a \u5149\u7ea7\u522b\uff08lux\uff09

      "},{"location":"qsl4a/system/sensors/#sensorsgetstepcounter","title":"sensorsGetStepCounter()","text":"

      \u8bfb\u53d6\u6b65\u8ba1\u6570\u5668\u3002

      sensorsGetStepCounter()\n

      \u8fd4\u56de\uff1a \u6b65\u6570

      "},{"location":"qsl4a/system/sensors/#sensorsgetaccuracy","title":"sensorsGetAccuracy()","text":"

      \u83b7\u53d6\u5f53\u524d\u4f20\u611f\u5668\u7cbe\u5ea6\u3002

      sensorsGetAccuracy()\n

      \u8fd4\u56de\uff1a \u7cbe\u5ea6\u503c\uff080-3\uff1aUNRELIABLE\u3001ACCURACY_LOW\u3001ACCURACY_MEDIUM\u3001ACCURACY_HIGH\uff09

      "},{"location":"qsl4a/system/sensors/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u8bfb\u53d6\u4f20\u611f\u5668 10 \u6b21\nfor i in range(10):\n    accel = droid.sensorsReadAccelerometer().result\n    print(f\"Accel: X={accel[0]:.2f}, Y={accel[1]:.2f}, Z={accel[2]:.2f}\")\n    time.sleep(0.5)\n\ndroid.stopSensing()\n
      "},{"location":"qsl4a/system/settings/","title":"\u8bbe\u7f6e API","text":"

      \u63a7\u5236\u7cfb\u7edf\u8bbe\u7f6e\uff0c\u5305\u62ec\u5c4f\u5e55\u3001\u58f0\u97f3\u548c\u7f51\u7edc\u8bbe\u7f6e\u3002

      "},{"location":"qsl4a/system/settings/#_1","title":"\u5c4f\u5e55\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#setscreentimeout","title":"setScreenTimeout()","text":"

      \u8bbe\u7f6e\u5c4f\u5e55\u8d85\u65f6\u503c\u3002

      setScreenTimeout(value)\n

      \u53c2\u6570\uff1a - value (int): \u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

      \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u8d85\u65f6\u503c

      "},{"location":"qsl4a/system/settings/#getscreentimeout","title":"getScreenTimeout()","text":"

      \u83b7\u53d6\u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u3002

      getScreenTimeout()\n

      \u8fd4\u56de\uff1a \u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

      "},{"location":"qsl4a/system/settings/#getscreenbrightness","title":"getScreenBrightness()","text":"

      \u83b7\u53d6\u5c4f\u5e55\u4eae\u5ea6\u503c\u3002

      getScreenBrightness()\n

      \u8fd4\u56de\uff1a \u4eae\u5ea6\u503c\uff080-255\uff09

      "},{"location":"qsl4a/system/settings/#setscreenbrightness","title":"setScreenBrightness()","text":"

      \u8bbe\u7f6e\u5c4f\u5e55\u4eae\u5ea6\u3002

      setScreenBrightness(value=None)\n

      \u53c2\u6570\uff1a - value (int, optional): \u4eae\u5ea6\u503c\uff080-255\uff09\uff0c\u6216 None \u8868\u793a\u81ea\u52a8

      \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u4eae\u5ea6\u503c

      "},{"location":"qsl4a/system/settings/#checkscreenon","title":"checkScreenOn()","text":"

      \u68c0\u67e5\u5c4f\u5e55\u662f\u5426\u4eae\u7740\u3002

      checkScreenOn()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u5c4f\u5e55\u4eae\u7740\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/system/settings/#_2","title":"\u98de\u884c\u6a21\u5f0f","text":""},{"location":"qsl4a/system/settings/#checkairplanemode","title":"checkAirplaneMode()","text":"

      \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\u662f\u5426\u542f\u7528\u3002

      checkAirplaneMode()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u98de\u884c\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

      "},{"location":"qsl4a/system/settings/#_3","title":"\u94c3\u58f0\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#checkringersilentmode","title":"checkRingerSilentMode()","text":"

      \u68c0\u67e5\u94c3\u58f0\u662f\u5426\u5904\u4e8e\u9759\u97f3\u6a21\u5f0f\u3002

      checkRingerSilentMode()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u9759\u97f3\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

      "},{"location":"qsl4a/system/settings/#toggleringersilentmode","title":"toggleRingerSilentMode()","text":"

      \u5207\u6362\u94c3\u58f0\u9759\u97f3\u6a21\u5f0f\u3002

      toggleRingerSilentMode(enabled=None)\n

      \u53c2\u6570\uff1a - enabled (bool, optional): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

      \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

      "},{"location":"qsl4a/system/settings/#togglevibratemode","title":"toggleVibrateMode()","text":"

      \u5207\u6362\u632f\u52a8\u6a21\u5f0f\u3002

      toggleVibrateMode(enabled=None, ringer=None)\n

      \u53c2\u6570\uff1a - enabled (bool, optional): \u5207\u6362\u632f\u52a8\u5f00/\u5173 - ringer (bool, optional): \u5e94\u7528\u4e8e\u94c3\u58f0\u6a21\u5f0f

      \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

      "},{"location":"qsl4a/system/settings/#getvibratemode","title":"getVibrateMode()","text":"

      \u83b7\u53d6\u632f\u52a8\u6a21\u5f0f\u8bbe\u7f6e\u3002

      getVibrateMode(ringer=None)\n

      \u53c2\u6570\uff1a - ringer (bool, optional): \u68c0\u67e5\u94c3\u58f0\u632f\u52a8\u6a21\u5f0f

      \u8fd4\u56de\uff1a \u5982\u679c\u632f\u52a8\u5df2\u542f\u7528\u5219\u4e3a True

      "},{"location":"qsl4a/system/settings/#_4","title":"\u97f3\u91cf\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#getringervolume","title":"getRingerVolume()","text":"

      \u83b7\u53d6\u5f53\u524d\u94c3\u58f0\u97f3\u91cf\u3002

      getRingerVolume()\n

      \u8fd4\u56de\uff1a \u94c3\u58f0\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-7\uff09

      "},{"location":"qsl4a/system/settings/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

      getMaxRingerVolume()\n

      \u8fd4\u56de\uff1a \u6700\u5927\u94c3\u58f0\u97f3\u91cf

      "},{"location":"qsl4a/system/settings/#setringervolume","title":"setRingerVolume()","text":"

      \u8bbe\u7f6e\u94c3\u58f0\u97f3\u91cf\u3002

      setRingerVolume(volume)\n

      \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

      "},{"location":"qsl4a/system/settings/#getmediavolume","title":"getMediaVolume()","text":"

      \u83b7\u53d6\u5f53\u524d\u5a92\u4f53\u97f3\u91cf\u3002

      getMediaVolume()\n

      \u8fd4\u56de\uff1a \u5a92\u4f53\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-15\uff09

      "},{"location":"qsl4a/system/settings/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

      getMaxMediaVolume()\n

      \u8fd4\u56de\uff1a \u6700\u5927\u5a92\u4f53\u97f3\u91cf

      "},{"location":"qsl4a/system/settings/#setmediavolume","title":"setMediaVolume()","text":"

      \u8bbe\u7f6e\u5a92\u4f53\u97f3\u91cf\u3002

      setMediaVolume(volume)\n

      \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

      "},{"location":"qsl4a/system/settings/#_5","title":"\u7cfb\u7edf\u4fe1\u606f","text":""},{"location":"qsl4a/system/settings/#elapsedrealtimenanos","title":"elapsedRealtimeNanos()","text":"

      \u83b7\u53d6\u81ea\u7cfb\u7edf\u542f\u52a8\u4ee5\u6765\u7684\u7eb3\u79d2\u6570\u3002

      elapsedRealtimeNanos()\n

      \u8fd4\u56de\uff1a \u7eb3\u79d2\u6570\uff08\u53ef\u7528\u4e8e\u8ba1\u65f6\uff09

      "},{"location":"qsl4a/system/settings/#gettrafficstats","title":"getTrafficStats()","text":"

      \u83b7\u53d6\u7f51\u7edc\u6d41\u91cf\u7edf\u8ba1\u3002

      getTrafficStats(flags=7)\n

      \u53c2\u6570\uff1a - flags (int): \u8981\u68c0\u7d22\u7684\u7edf\u8ba1\uff08\u9ed8\u8ba4\uff1a7 = \u5168\u90e8\uff09

      \u8fd4\u56de\uff1a \u5305\u542b\u53d1\u9001/\u63a5\u6536\u5b57\u8282\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/settings/#getapptxbytes","title":"getAppTxBytes()","text":"

      \u83b7\u53d6 QPython \u5e94\u7528\u7684\u53d1\u9001\u5b57\u8282\u3002

      getAppTxBytes(packageName)\n

      \u53c2\u6570\uff1a - packageName (str): \u5305\u540d

      \u8fd4\u56de\uff1a \u5305\u542b tx/rx \u5b57\u8282\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/settings/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5c4f\u5e55\u8bbe\u7f6e\ncurrent_timeout = droid.getScreenTimeout().result\nprint(f\"Current timeout: {current_timeout}s\")\ndroid.setScreenTimeout(30)\n\n# \u68c0\u67e5\u5c4f\u5e55\nif droid.checkScreenOn().result:\n    print(\"Screen is on\")\n\n# \u97f3\u91cf\u63a7\u5236\nmedia_vol = droid.getMediaVolume().result\nprint(f\"Media volume: {media_vol}\")\ndroid.setMediaVolume(10)\n\n# \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\nif droid.checkAirplaneMode().result:\n    print(\"Airplane mode is on\")\n
      "},{"location":"qsl4a/system/sysinfo/","title":"\u7cfb\u7edf\u4fe1\u606f","text":"

      \u68c0\u7d22\u8bbe\u5907\u548c\u7cfb\u7edf\u4fe1\u606f\u3002

      "},{"location":"qsl4a/system/sysinfo/#_2","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/sysinfo/#getandroidid","title":"getAndroidID()","text":"

      \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

      getAndroidID()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

      "},{"location":"qsl4a/system/sysinfo/#getsysinfo","title":"getSysInfo()","text":"

      \u83b7\u53d6\u7efc\u5408\u7cfb\u7edf\u4fe1\u606f\u3002

      getSysInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/sysinfo/#getlocale","title":"getLocale()","text":"

      \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u8bbe\u7f6e\u3002

      getLocale()\n

      \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

      "},{"location":"qsl4a/system/sysinfo/#_3","title":"\u5185\u5b58","text":""},{"location":"qsl4a/system/sysinfo/#getmemoryinfo","title":"getMemoryInfo()","text":"

      \u83b7\u53d6 RAM \u4fe1\u606f\u3002

      getMemoryInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/sysinfo/#_4","title":"\u663e\u793a","text":""},{"location":"qsl4a/system/sysinfo/#getscreeninfo","title":"getScreenInfo()","text":"

      \u83b7\u53d6\u663e\u793a\u4fe1\u606f\u3002

      getScreenInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/sysinfo/#_5","title":"\u6807\u8bc6\u7b26","text":""},{"location":"qsl4a/system/sysinfo/#getimei","title":"getImei()","text":"

      \u83b7\u53d6\u8bbe\u5907 IMEI\u3002

      getImei(slotIndex=None)\n
      "},{"location":"qsl4a/system/sysinfo/#getmeid","title":"getMeid()","text":"

      \u83b7\u53d6\u8bbe\u5907 MEID\u3002

      getMeid(slotIndex=None)\n
      "},{"location":"qsl4a/system/sysinfo/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u8bbe\u5907 ID\nandroid_id = droid.getAndroidID().result\nprint(f\"Android ID: {android_id}\")\n\n# \u5c4f\u5e55\u4fe1\u606f\nscreen = droid.getScreenInfo().result\nprint(f\"Screen: {screen['width']}x{screen['height']}\")\n\n# \u5185\u5b58\nmemory = droid.getMemoryInfo().result\nprint(f\"Memory: {memory}\")\n
      "},{"location":"qsl4a/system/wakelock/","title":"WakeLock API","text":"

      \u63a7\u5236\u8bbe\u5907\u5524\u9192\u9501\u4ee5\u4fdd\u6301 CPU \u6216\u5c4f\u5e55\u5f00\u542f\u3002

      "},{"location":"qsl4a/system/wakelock/#wake-lock","title":"Wake Lock \u7c7b\u578b","text":"

      QSL4A \u63d0\u4f9b\u4e0d\u540c\u7c7b\u578b\u7684\u5524\u9192\u9501\uff1a

      \u7c7b\u578b \u63cf\u8ff0 Full CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae Partial \u4ec5 CPU \u5f00\u542f Bright CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae Dim CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697"},{"location":"qsl4a/system/wakelock/#wake-lock_1","title":"Wake Lock \u65b9\u6cd5","text":""},{"location":"qsl4a/system/wakelock/#wakelockacquirefull","title":"wakeLockAcquireFull()","text":"

      \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae\uff09\u3002

      wakeLockAcquireFull()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquirepartial","title":"wakeLockAcquirePartial()","text":"

      \u83b7\u53d6\u90e8\u5206\u5524\u9192\u9501\uff08\u4ec5 CPU \u5f00\u542f\uff09\u3002

      wakeLockAcquirePartial()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquirebright","title":"wakeLockAcquireBright()","text":"

      \u83b7\u53d6\u660e\u4eae\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff09\u3002

      wakeLockAcquireBright()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquiredim","title":"wakeLockAcquireDim()","text":"

      \u83b7\u53d6\u6697\u6de1\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697\uff09\u3002

      wakeLockAcquireDim()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockrelease","title":"wakeLockRelease()","text":"

      \u91ca\u653e\u5524\u9192\u9501\u3002

      wakeLockRelease()\n
      "},{"location":"qsl4a/system/wakelock/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\ndroid.wakeLockAcquireFull()\n\n# \u5728\u4fdd\u6301\u5c4f\u5e55\u5f00\u542f\u65f6\u6267\u884c\u91cd\u8981\u5de5\u4f5c\nprint(\"Screen will stay on\")\ntime.sleep(10)\n\n# \u5b8c\u6210\u540e\u91ca\u653e\ndroid.wakeLockRelease()\n\n# \u6216\u4f7f\u7528\u90e8\u5206\u9501\u8fdb\u884c\u540e\u53f0\u4efb\u52a1\ndroid.wakeLockAcquirePartial()\n# \u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\uff0cCPU \u4ecd\u4fdd\u6301\u5f00\u542f\ntime.sleep(30)\ndroid.wakeLockRelease()\n

      \u6ce8\u610f\uff1a \u8bb0\u4f4f\u5728\u4e0d\u9700\u8981\u65f6\u91ca\u653e\u5524\u9192\u9501\u4ee5\u8282\u7701\u7535\u6c60\u3002

      "},{"location":"qsl4a/ui/accessibility/","title":"\u65e0\u969c\u788d\u670d\u52a1","text":"

      \u65e0\u969c\u788d\u670d\u52a1\u5141\u8bb8\u81ea\u52a8\u5316 UI \u4ea4\u4e92\uff0c\u5982\u70b9\u51fb\u3001\u6ed1\u52a8\u548c\u7cfb\u7edf\u64cd\u4f5c\u3002

      "},{"location":"qsl4a/ui/accessibility/#_2","title":"\u670d\u52a1\u63a7\u5236","text":""},{"location":"qsl4a/ui/accessibility/#accessibilitystartservice","title":"accessibilityStartService()","text":"

      \u542f\u52a8\u65e0\u969c\u788d\u670d\u52a1\u3002

      accessibilityStartService()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/ui/accessibility/#accessibilityserviceenabled","title":"accessibilityServiceEnabled()","text":"

      \u68c0\u67e5\u65e0\u969c\u788d\u670d\u52a1\u662f\u5426\u5df2\u542f\u7528\u3002

      accessibilityServiceEnabled()\n

      \u8fd4\u56de\uff1a True \u6216 False

      "},{"location":"qsl4a/ui/accessibility/#_3","title":"\u5c4f\u5e55\u4ea4\u4e92","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityclick","title":"accessibilityClick()","text":"

      \u5728\u5c4f\u5e55\u5750\u6807\u5904\u70b9\u51fb\u3002

      accessibilityClick(x=0, y=0, t=50)\n

      \u53c2\u6570\uff1a - x (int/float): X \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - y (int/float): Y \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - t (int): \u6309\u4f4f\u65f6\u957f\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a50\uff09

      "},{"location":"qsl4a/ui/accessibility/#accessibilityslide","title":"accessibilitySlide()","text":"

      \u591a\u70b9\u6ed1\u52a8\u624b\u52bf\u3002

      accessibilitySlide(XnYn=None, t=None)\n

      \u53c2\u6570\uff1a - XnYn (list): \u5750\u6807 [X1, Y1, X2, Y2, ... Xn, Yn] - t (int): \u6ed1\u52a8\u65f6\u957f\uff08\u9ed8\u8ba4\uff1a50*n \u6beb\u79d2\uff09

      "},{"location":"qsl4a/ui/accessibility/#_4","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityaction","title":"accessibilityAction()","text":"

      \u6309\u4ee3\u7801\u6267\u884c\u7cfb\u7edf\u64cd\u4f5c\u3002

      accessibilityAction(actionCode)\n

      \u64cd\u4f5c\u4ee3\u7801\uff1a | \u4ee3\u7801 | \u5e38\u91cf | \u63cf\u8ff0 | |------|----------|-------------| | 1 | BACK | \u8fd4\u56de\u6309\u94ae | | 2 | HOME | \u4e3b\u5c4f\u5e55\u6309\u94ae | | 3 | RECENTS | \u6700\u8fd1\u5e94\u7528 | | 4 | NOTIFICATIONS | \u6253\u5f00\u901a\u77e5 | | 5 | QUICK_SETTINGS | \u6253\u5f00\u5feb\u901f\u8bbe\u7f6e | | 6 | POWER_DIALOG | \u7535\u6e90\u83dc\u5355 | | 7 | TOGGLE_SPLIT_SCREEN | \u5206\u5c4f | | 8 | LOCK_SCREEN | \u9501\u5c4f | | 9 | TAKE_SCREENSHOT | \u622a\u56fe | | 10 | KEYCODE_HEADSETHOOK | \u8033\u673a\u6302\u94a9 | | 11-14 | ACCESSIBILITY_ | \u65e0\u969c\u788d\u6309\u94ae | | 15 | DISMISS_NOTIFICATION_SHADE | \u5173\u95ed\u901a\u77e5\u680f | | 16-20 | DPAD_ | \u65b9\u5411\u952e | | 21 | MENU | \u83dc\u5355\u6309\u94ae | | 22 | MEDIA_PLAY_PAUSE | \u64ad\u653e/\u6682\u505c\u5a92\u4f53 |

      "},{"location":"qsl4a/ui/accessibility/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/accessibility/#_6","title":"\u70b9\u51fb\u5c4f\u5e55\u4e2d\u5fc3","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u670d\u52a1\nif not droid.accessibilityServiceEnabled().result:\n    droid.accessibilityStartService()\n\n# \u70b9\u51fb\u4e2d\u5fc3\uff080,0 = \u4e2d\u5fc3\uff09\ndroid.accessibilityClick(0, 0, t=100)\n
      "},{"location":"qsl4a/ui/accessibility/#_7","title":"\u6ed1\u52a8\u624b\u52bf","text":"
      # \u4ece\u4e0b\u5f80\u4e0a\u6ed1\u52a8\uff08\u5411\u4e0a\u6eda\u52a8\uff09\ndroid.accessibilitySlide([0, 1.5, 0, -1.5], t=300)\n
      "},{"location":"qsl4a/ui/accessibility/#_8","title":"\u7cfb\u7edf\u5bfc\u822a","text":"
      # \u6309\u4e3b\u5c4f\u5e55\ndroid.accessibilityAction(2)\n\n# \u6309\u8fd4\u56de\ndroid.accessibilityAction(1)\n\n# \u6253\u5f00\u901a\u77e5\ndroid.accessibilityAction(4)\n
      "},{"location":"qsl4a/ui/accessibility/#_9","title":"\u70b9\u51fb\u7279\u5b9a\u4f4d\u7f6e","text":"
      # \u70b9\u51fb\u5c4f\u5e55\u5750\u6807 (500, 800)\ndroid.accessibilityClick(500, 800)\n\n# \u70b9\u51fb\u76f8\u5bf9\u4f4d\u7f6e\uff08\u6c34\u5e73\u5c45\u4e2d\uff0c\u5782\u76f4 3/4 \u5904\uff09\ndroid.accessibilityClick(0, 1.5)\n
      "},{"location":"qsl4a/ui/dialogs/","title":"\u5bf9\u8bdd\u6846\u7cfb\u7edf","text":"

      QSL4A \u63d0\u4f9b\u5168\u9762\u7684\u5bf9\u8bdd\u6846\u652f\u6301\uff0c\u7528\u4e8e\u7528\u6237\u4ea4\u4e92\uff0c\u5305\u62ec\u8b66\u62a5\u3001\u8f93\u5165\u5bf9\u8bdd\u6846\u3001\u9009\u62e9\u5bf9\u8bdd\u6846\u548c\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

      "},{"location":"qsl4a/ui/dialogs/#_2","title":"\u8b66\u62a5\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowalert","title":"dialogShowAlert()","text":"

      \u663e\u793a\u7b80\u5355\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

      dialogShowAlert(title=\"Alert\", message=\"The message of the alert.\",\n                positiveButtonText=\"OK\", negativeButtonText=None,\n                neutralButtonText=None, messageIsHtml=False)\n

      \u53c2\u6570\uff1a - title (str): \u5bf9\u8bdd\u6846\u6807\u9898 - message (str): \u6d88\u606f\u6587\u672c - positiveButtonText (str): \u80af\u5b9a\u6309\u94ae\u6807\u7b7e - negativeButtonText (str, optional): \u5426\u5b9a\u6309\u94ae\u6807\u7b7e - neutralButtonText (str, optional): \u4e2d\u6027\u6309\u94ae\u6807\u7b7e - messageIsHtml (bool): \u5c06\u6d88\u606f\u89e3\u6790\u4e3a HTML

      \u8fd4\u56de\uff1a \u5305\u542b\u70b9\u51fb\u6309\u94ae\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#dialogshowsimplechoice","title":"dialogShowSimpleChoice()","text":"

      \u663e\u793a\u5e26\u6709\u9879\u76ee\u7684\u7b80\u5355\u9009\u62e9\u5bf9\u8bdd\u6846\u3002

      dialogShowSimpleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

      \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868

      \u8fd4\u56de\uff1a \u5305\u542b\u9009\u4e2d\u9879\u76ee\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#_3","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialoggetinput","title":"dialogGetInput()","text":"

      \u83b7\u53d6\u7528\u6237\u6587\u672c\u8f93\u5165\u3002

      dialogGetInput(title=\"Value\", message=\"Please enter value:\",\n               defaultText=None, messageIsHtml=False)\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7528\u6237\u8f93\u5165\u6587\u672c\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#dialoggetpassword","title":"dialogGetPassword()","text":"

      \u83b7\u53d6\u5bc6\u7801\u8f93\u5165\u3002

      dialogGetPassword(title=\"Password\", message=\"Please enter password:\")\n

      \u8fd4\u56de\uff1a \u5305\u542b\u8f93\u5165\u5bc6\u7801\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#dialogcreateinput","title":"dialogCreateInput()","text":"

      \u521b\u5efa\u81ea\u5b9a\u4e49\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

      dialogCreateInput(title=\"Value\", message=\"Please enter value:\",\n                  defaultText=None, inputType=None)\n

      \u53c2\u6570\uff1a - inputType (str): \u8f93\u5165\u7c7b\u578b\uff08\u4f8b\u5982 \"text\"\u3001\"number\"\u3001\"textPassword\"\uff09

      "},{"location":"qsl4a/ui/dialogs/#dialogcreatepassword","title":"dialogCreatePassword()","text":"

      \u521b\u5efa\u5bc6\u7801\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

      dialogCreatePassword(title=\"Password\", message=\"Please enter password:\")\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreateseekbar","title":"dialogCreateSeekBar()","text":"

      \u521b\u5efa\u6ed1\u5757/\u8fdb\u5ea6\u6761\u5bf9\u8bdd\u6846\u3002

      dialogCreateSeekBar(starting_value=50, maximum_value=100, title=\"\", message=\"\")\n

      \u53c2\u6570\uff1a - starting_value (int): \u521d\u59cb\u503c - maximum_value (int): \u6700\u5927\u503c

      "},{"location":"qsl4a/ui/dialogs/#_4","title":"\u9009\u62e9\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowsinglechoice","title":"dialogShowSingleChoice()","text":"

      \u663e\u793a\u5355\u9009\uff08\u5355\u9009\u6309\u94ae\uff09\u5bf9\u8bdd\u6846\u3002

      dialogShowSingleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, selected=-1, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

      \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (int): \u9ed8\u8ba4\u9009\u4e2d\u7d22\u5f15

      "},{"location":"qsl4a/ui/dialogs/#dialogshowmultichoice","title":"dialogShowMultiChoice()","text":"

      \u663e\u793a\u591a\u9009\uff08\u590d\u9009\u6846\uff09\u5bf9\u8bdd\u6846\u3002

      dialogShowMultiChoice(title=\"Alert\", message=\"The message of the alert.\",\n                      items=None, selected=None, positiveButtonText=\"OK\",\n                      negativeButtonText=None, neutralButtonText=None,\n                      messageIsHtml=False)\n

      \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (list): \u521d\u59cb\u9009\u4e2d\u7d22\u5f15\u5217\u8868

      "},{"location":"qsl4a/ui/dialogs/#dialogsetsinglechoiceitems","title":"dialogSetSingleChoiceItems()","text":"

      \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u5355\u9009\u9879\u76ee\u3002

      dialogSetSingleChoiceItems(items, selected=-1)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmultichoiceitems","title":"dialogSetMultiChoiceItems()","text":"

      \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u591a\u9009\u9879\u76ee\u3002

      dialogSetMultiChoiceItems(items, selected=None)\n
      "},{"location":"qsl4a/ui/dialogs/#_5","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatespinnerprogress","title":"dialogCreateSpinnerProgress()","text":"

      \u521b\u5efa\u4e0d\u786e\u5b9a\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

      dialogCreateSpinnerProgress(title=None, message=None, maximum_progress=100)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreatehorizontalprogress","title":"dialogCreateHorizontalProgress()","text":"

      \u521b\u5efa\u6c34\u5e73\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

      dialogCreateHorizontalProgress(title=None, message=None, maximum_progress=100)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetcurrentprogress","title":"dialogSetCurrentProgress()","text":"

      \u66f4\u65b0\u8fdb\u5ea6\u503c\u3002

      dialogSetCurrentProgress(current)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmaxprogress","title":"dialogSetMaxProgress()","text":"

      \u8bbe\u7f6e\u6700\u5927\u8fdb\u5ea6\u503c\u3002

      dialogSetMaxProgress(max)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetprogressmessage","title":"dialogSetProgressMessage()","text":"

      \u66f4\u65b0\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u6d88\u606f\u3002

      dialogSetProgressMessage(message)\n
      "},{"location":"qsl4a/ui/dialogs/#_6","title":"\u9009\u62e9\u5668\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatedatepicker","title":"dialogCreateDatePicker()","text":"

      \u521b\u5efa\u65e5\u671f\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

      dialogCreateDatePicker(year=1970, month=1, day=1)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreatetimepicker","title":"dialogCreateTimePicker()","text":"

      \u521b\u5efa\u65f6\u95f4\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

      dialogCreateTimePicker(hour=0, minute=0, is24hour=False)\n
      "},{"location":"qsl4a/ui/dialogs/#_7","title":"\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u521b\u5efa","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatealert","title":"dialogCreateAlert()","text":"

      \u521b\u5efa\u81ea\u5b9a\u4e49\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

      dialogCreateAlert(title=None, message=None)\n

      \u521b\u5efa\u4e00\u4e2a\u7a7a\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002\u53ef\u4e0e\u5176\u4ed6 dialogSet* \u51fd\u6570\u4e00\u8d77\u4f7f\u7528\u6765\u81ea\u5b9a\u4e49\u3002

      "},{"location":"qsl4a/ui/dialogs/#dialogsetitems","title":"dialogSetItems()","text":"

      \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u7b80\u5355\u5217\u8868\u9879\u76ee\u3002

      dialogSetItems(items)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetpositivebuttontext","title":"dialogSetPositiveButtonText()","text":"

      \u8bbe\u7f6e\u80af\u5b9a\u6309\u94ae\u6587\u672c\u3002

      dialogSetPositiveButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetnegativebuttontext","title":"dialogSetNegativeButtonText()","text":"

      \u8bbe\u7f6e\u5426\u5b9a\u6309\u94ae\u6587\u672c\u3002

      dialogSetNegativeButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetneutralbuttontext","title":"dialogSetNeutralButtonText()","text":"

      \u8bbe\u7f6e\u4e2d\u6027\u6309\u94ae\u6587\u672c\u3002

      dialogSetNeutralButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmessageishtml","title":"dialogSetMessageIsHtml()","text":"

      \u8bbe\u7f6e\u6d88\u606f\u662f\u5426\u5e94\u89e3\u6790\u4e3a HTML\u3002

      dialogSetMessageIsHtml(messageIsHtml=True)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogshow","title":"dialogShow()","text":"

      \u663e\u793a\u521b\u5efa\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u3002

      dialogShow()\n
      "},{"location":"qsl4a/ui/dialogs/#_8","title":"\u5bf9\u8bdd\u6846\u63a7\u5236","text":""},{"location":"qsl4a/ui/dialogs/#dialogdismiss","title":"dialogDismiss()","text":"

      \u5173\u95ed\u5f53\u524d\u5bf9\u8bdd\u6846\u3002

      dialogDismiss()\n
      "},{"location":"qsl4a/ui/dialogs/#dialoggetresponse","title":"dialogGetResponse()","text":"

      \u83b7\u53d6\u5bf9\u8bdd\u6846\u54cd\u5e94\u3002

      dialogGetResponse()\n
      "},{"location":"qsl4a/ui/dialogs/#dialoggetselecteditems","title":"dialogGetSelectedItems()","text":"

      \u4ece\u9009\u62e9\u5bf9\u8bdd\u6846\u83b7\u53d6\u9009\u4e2d\u7684\u9879\u76ee\u3002

      dialogGetSelectedItems()\n
      "},{"location":"qsl4a/ui/dialogs/#_9","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/dialogs/#_10","title":"\u7b80\u5355\u8b66\u62a5","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a\u8b66\u62a5\ndroid.dialogShowAlert(\"Warning\", \"This is an important message!\")\n
      "},{"location":"qsl4a/ui/dialogs/#_11","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":"
      # \u83b7\u53d6\u7528\u6237\u8f93\u5165\nresult = droid.dialogGetInput(\"Name\", \"Enter your name:\", \"John\").result\nprint(f\"Hello, {result}!\")\n
      "},{"location":"qsl4a/ui/dialogs/#_12","title":"\u5e26\u6309\u94ae\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846","text":"
      # \u521b\u5efa\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\ndroid.dialogCreateAlert(\"Custom\", \"Choose an option\")\ndroid.dialogSetItems([\"Option 1\", \"Option 2\", \"Option 3\"])\ndroid.dialogShow()\n\n# \u83b7\u53d6\u54cd\u5e94\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response['item']}\")\n
      "},{"location":"qsl4a/ui/dialogs/#_13","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":"
      # \u521b\u5efa\u8fdb\u5ea6\u5bf9\u8bdd\u6846\ndroid.dialogCreateHorizontalProgress(\"Loading\", \"Please wait...\", 100)\ndroid.dialogShow()\n\n# \u66f4\u65b0\u8fdb\u5ea6\nfor i in range(101):\n    droid.dialogSetCurrentProgress(i)\n    time.sleep(0.05)\n\ndroid.dialogDismiss()\n
      "},{"location":"qsl4a/ui/dialogs/#_14","title":"\u65e5\u671f\u9009\u62e9\u5668","text":"
      # \u663e\u793a\u65e5\u671f\u9009\u62e9\u5668\ndroid.dialogCreateDatePicker(2024, 1, 15)\ndroid.dialogShow()\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response}\")\n
      "},{"location":"qsl4a/ui/floatview/","title":"\u6d6e\u52a8\u89c6\u56fe","text":"

      \u6d6e\u52a8\u7a97\u53e3\u652f\u6301\uff0c\u7528\u4e8e\u5728\u5176\u4ed6\u5e94\u7528\u7a0b\u5e8f\u4e0a\u65b9\u4fdd\u6301\u663e\u793a\u7684\u8986\u76d6 UI \u5143\u7d20\u3002

      "},{"location":"qsl4a/ui/floatview/#_2","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/floatview/#floatview","title":"floatView()","text":"

      \u663e\u793a\u6216\u4fee\u6539\u6d6e\u52a8\u89c6\u56fe\u3002

      floatView(Args=None)\n

      \u53c2\u6570\uff1a - Args (dict): \u914d\u7f6e\u5b57\u5178\uff0c\u5305\u542b\u4ee5\u4e0b\u952e\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08-1 \u521b\u5efa\u65b0\u7684\uff0c>=0 \u4fee\u6539\u73b0\u6709\u7684\uff09 - text (str): \u8981\u663e\u793a\u7684\u6587\u672c\u5185\u5bb9 - html (str): HTML \u5185\u5bb9\uff08\u5982\u679c\u7701\u7565 text \u5219\u4f7f\u7528\uff09 - width (int): \u89c6\u56fe\u5bbd\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a300\uff09 - height (int): \u89c6\u56fe\u9ad8\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a150\uff09 - x (int): X \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - y (int): Y \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - backColor (str): ARGB \u5341\u516d\u8fdb\u5236\u80cc\u666f\u8272\uff08\u9ed8\u8ba4\uff1a'7f7f7f7f'\uff09 - textColor (str): ARGB \u5341\u516d\u8fdb\u5236\u6587\u672c\u8272\uff08\u9ed8\u8ba4\uff1a'ff000000'\uff09 - textSize (int): \u6587\u672c\u5927\u5c0f\uff08\u9ed8\u8ba4\uff1a10\uff09 - textAlign (int): \u6587\u672c\u5bf9\u9f50\uff080 = \u7ee7\u627f\uff09 - script (str): \u957f\u6309\u5173\u95ed\u540e\u8fd0\u884c\u7684\u811a\u672c\u8def\u5f84 - arg: \u811a\u672c\u53c2\u6570 - clickRemove (bool): \u542f\u7528\u70b9\u51fb\u79fb\u9664\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - flag (int): \u7a97\u53e3\u6807\u5fd7\uff08\u9ed8\u8ba4\uff1a40 - \u53ef\u89e6\u6478\uff09

      \u8fd4\u56de\uff1a \u5f53\u524d\u94fe\u5217\u8868\u957f\u5ea6

      "},{"location":"qsl4a/ui/floatview/#floatviewcount","title":"floatViewCount()","text":"

      \u83b7\u53d6\u6d3b\u52a8\u6d6e\u52a8\u89c6\u56fe\u7684\u6570\u91cf\u3002

      floatViewCount()\n

      \u8fd4\u56de\uff1a \u6d6e\u52a8\u89c6\u56fe\u6570\u91cf

      "},{"location":"qsl4a/ui/floatview/#floatviewresult","title":"floatViewResult()","text":"

      \u83b7\u53d6\u6d6e\u52a8\u89c6\u56fe\u7684\u7ed3\u679c/\u72b6\u6001\u3002

      floatViewResult(index=-1)\n

      \u53c2\u6570\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1\uff0c\u8fd4\u56de\u6700\u540e\u64cd\u4f5c\u7ed3\u679c\uff09

      \u8fd4\u56de\uff1a \u5305\u542b\u64cd\u4f5c\u8be6\u60c5\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - x, y: \u4f4d\u7f6e - time: \u65f6\u95f4\u6233 - operation: \u64cd\u4f5c\u7c7b\u578b\uff08'initial'\u3001'move' \u7b49\uff09 - index: \u89c6\u56fe\u7d22\u5f15 - removed: \u5982\u679c\u89c6\u56fe\u88ab\u79fb\u9664\u5219\u4e3a True

      "},{"location":"qsl4a/ui/floatview/#floatviewremove","title":"floatViewRemove()","text":"

      \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\u3002

      floatViewRemove(index=-1)\n

      \u53c2\u6570\uff1a - index (int): \u8981\u79fb\u9664\u7684\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1 \u79fb\u9664\u6700\u540e\u4e00\u4e2a\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a 1\uff0c\u5426\u5219\u4e3a 0

      "},{"location":"qsl4a/ui/floatview/#_3","title":"\u5e38\u91cf","text":"
      • floatView.INDEX_NEW = -1 - \u521b\u5efa\u65b0\u7684\u6d6e\u52a8\u89c6\u56fe
      • floatView.FLAG_DEFAULT_TOUCHABLE = 40 - \u9ed8\u8ba4\u53ef\u89e6\u6478\u6807\u5fd7
      • floatView.TEXT_ALIGNMENT_INHERIT = 0
      • floatView.TEXT_ALIGNMENT_CENTER - \u5c45\u4e2d\u6587\u672c\u5bf9\u9f50
      "},{"location":"qsl4a/ui/floatview/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/floatview/#_5","title":"\u57fa\u672c\u6d6e\u52a8\u89c6\u56fe","text":"
      import androidhelper\nfrom androidhelper import Android\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u7b80\u5355\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'index': -1,  # \u521b\u5efa\u65b0\u7684\n    'text': 'Hello World',\n    'width': 400,\n    'height': 300,\n    'x': -300,  # \u4ece\u4e2d\u5fc3\u504f\u79fb\n    'y': -400,\n    'backColor': 'ff0000',  # \u7ea2\u8272\u80cc\u666f\n    'textColor': '0000ff',  # \u84dd\u8272\u6587\u672c\n    'textSize': 16,\n    'textAlign': droid.floatView.TEXT_ALIGNMENT_CENTER\n})\n\n# \u68c0\u67e5\u6570\u91cf\nprint(f\"Float views: {droid.floatViewCount().result}\")\n\n# \u83b7\u53d6\u7ed3\u679c\nresult = droid.floatViewResult().result\nprint(f\"View info: {result}\")\n\n# \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\ndroid.floatViewRemove(0)\n
      "},{"location":"qsl4a/ui/floatview/#html","title":"HTML \u5185\u5bb9","text":"
      # \u521b\u5efa\u5e26 HTML \u5185\u5bb9\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': '',  # \u7a7a\u6587\u672c\u4ee5\u4f7f\u7528 HTML\n    'html': '<h1>Title</h1><p>Rich <b>HTML</b> content</p>',\n    'width': 500,\n    'height': 400\n})\n
      "},{"location":"qsl4a/ui/floatview/#_6","title":"\u4fee\u6539\u73b0\u6709\u89c6\u56fe","text":"
      # \u521b\u5efa\u521d\u59cb\u89c6\u56fe\ndroid.floatView({'text': 'Initial Text', 'width': 300, 'height': 150})\n\n# \u4fee\u6539\u540c\u4e00\u89c6\u56fe\uff08\u7d22\u5f15 0\uff09\ndroid.floatView({\n    'index': 0,\n    'text': 'Updated Text!',\n    'backColor': '7f00ff00'  # \u7eff\u8272\u80cc\u666f\n})\n\n# \u68c0\u67e5\u79fb\u52a8/\u66f4\u6539\u7ed3\u679c\nresult = droid.floatViewResult(0).result\nprint(f\"Operation: {result.get('operation')}, Position: ({result.get('x')}, {result.get('y')})\")\n
      "},{"location":"qsl4a/ui/floatview/#_7","title":"\u591a\u4e2a\u6d6e\u52a8\u89c6\u56fe","text":"
      # \u521b\u5efa\u591a\u4e2a\u89c6\u56fe\nfor i in range(3):\n    droid.floatView({\n        'index': -1,\n        'text': f'View {i}',\n        'x': i * 100 - 150,\n        'y': i * 100 - 150,\n        'backColor': f'{i}f{i}f{i}f'\n    })\n\nprint(f\"Total views: {droid.floatViewCount().result}\")\n\n# \u79fb\u9664\u6240\u6709\u89c6\u56fe\nwhile droid.floatViewCount().result > 0:\n    droid.floatViewRemove()\n
      "},{"location":"qsl4a/ui/floatview/#_8","title":"\u5e26\u811a\u672c\u56de\u8c03","text":"
      # \u521b\u5efa\u5173\u95ed\u65f6\u8fd0\u884c\u811a\u672c\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': 'Click to close and run script',\n    'script': '/sdcard/my_script.py',\n    'arg': 'hello from float view',\n    'clickRemove': True\n})\n
      "},{"location":"qsl4a/ui/fullscreen/","title":"\u5168\u5c4f UI","text":"

      \u4f7f\u7528\u539f\u751f Android \u5e03\u5c40\u521b\u5efa\u81ea\u5b9a\u4e49\u5168\u5c4f\u754c\u9762\u3002

      "},{"location":"qsl4a/ui/fullscreen/#_1","title":"\u5e03\u5c40\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullshow","title":"fullShow()","text":"

      \u663e\u793a\u5168\u5c4f\u5e03\u5c40\u3002

      fullShow(layout, title=None, theme=None)\n

      \u53c2\u6570\uff1a - layout (str): JSON \u5e03\u5c40\u5b9a\u4e49\u6216\u5e03\u5c40\u5b57\u7b26\u4e32 - title (str, optional): \u7a97\u53e3\u6807\u9898 - theme (str, optional): \u4e3b\u9898\u540d\u79f0

      \u8fd4\u56de\uff1a \u7a97\u53e3 ID

      "},{"location":"qsl4a/ui/fullscreen/#fulldismiss","title":"fullDismiss()","text":"

      \u5173\u95ed\u5168\u5c4f\u7a97\u53e3\u3002

      fullDismiss()\n
      "},{"location":"qsl4a/ui/fullscreen/#fullquery","title":"fullQuery()","text":"

      \u67e5\u8be2\u6240\u6709\u5c0f\u90e8\u4ef6\u503c\u3002

      fullQuery()\n

      \u8fd4\u56de\uff1a \u5c0f\u90e8\u4ef6 ID \u548c\u503c\u7684\u5b57\u5178

      "},{"location":"qsl4a/ui/fullscreen/#fullquerydetail","title":"fullQueryDetail()","text":"

      \u67e5\u8be2\u7279\u5b9a\u5c0f\u90e8\u4ef6\u8be6\u60c5\u3002

      fullQueryDetail(id)\n
      "},{"location":"qsl4a/ui/fullscreen/#_2","title":"\u5c5e\u6027\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperty","title":"fullGetProperty()","text":"

      \u83b7\u53d6\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

      fullGetProperty(id, property)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetproperty","title":"fullSetProperty()","text":"

      \u8bbe\u7f6e\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

      fullSetProperty(id, property, value)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetlist","title":"fullSetList()","text":"

      \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

      fullSetList(id, list, isHtml=False, listType=0)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetlist2","title":"fullSetList2()","text":"

      \u4f7f\u7528\u8d44\u6e90 ID \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

      fullSetList2(id, list, intRes)\n

      \u53c2\u6570\uff1a - id (str): \u5c0f\u90e8\u4ef6 ID - list (list): \u9879\u76ee\u5217\u8868 - intRes (int): \u5217\u8868\u9879\u76ee\u5e03\u5c40\u7684 Android \u8d44\u6e90 ID

      "},{"location":"qsl4a/ui/fullscreen/#fullsetlistselected","title":"fullSetListSelected()","text":"

      \u5728\u5217\u8868\u4e2d\u8bbe\u7f6e\u9009\u4e2d\u9879\u76ee\u3002

      fullSetListSelected(id, selected)\n

      \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID - selected (int): \u8981\u9009\u4e2d\u7684\u9879\u76ee\u7d22\u5f15

      "},{"location":"qsl4a/ui/fullscreen/#fullgetlistselected","title":"fullGetListSelected()","text":"

      \u83b7\u53d6\u5f53\u524d\u9009\u4e2d\u7684\u5217\u8868\u9879\u76ee\u7d22\u5f15\u3002

      fullGetListSelected(id)\n

      \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID

      \u8fd4\u56de\uff1a \u9009\u4e2d\u9879\u76ee\u7d22\u5f15

      "},{"location":"qsl4a/ui/fullscreen/#_3","title":"\u6279\u91cf\u5c5e\u6027\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperties","title":"fullGetProperties()","text":"

      \u4e00\u6b21\u83b7\u53d6\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

      fullGetProperties(ids, property)\n

      \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u83b7\u53d6\u7684\u5c5e\u6027\u540d

      \u8fd4\u56de\uff1a \u6620\u5c04\u5c0f\u90e8\u4ef6 ID \u5230\u5c5e\u6027\u503c\u7684\u5b57\u5178

      "},{"location":"qsl4a/ui/fullscreen/#fullsetproperties","title":"fullSetProperties()","text":"

      \u4e00\u6b21\u8bbe\u7f6e\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

      fullSetProperties(ids, property, value)\n

      \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u8bbe\u7f6e\u7684\u5c5e\u6027\u540d - value: \u5c5e\u6027\u503c

      "},{"location":"qsl4a/ui/fullscreen/#_4","title":"\u622a\u56fe","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetscreenshot","title":"fullGetScreenShot()","text":"

      \u6355\u83b7\u5168\u5c4f\u622a\u56fe\u3002

      fullGetScreenShot(path=None)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u5728\u4e8b\u4ef6\u4e2d\u8fd4\u56de

      \u8fd4\u56de\uff1a \u5305\u542b\u622a\u56fe\u6570\u636e\u7684\u4e8b\u4ef6

      "},{"location":"qsl4a/ui/fullscreen/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b9a\u4e49\u5e03\u5c40\nlayout = '''\n{ \"type\": \"LinearLayout\", \"orientation\": \"vertical\",\n  \"children\": [\n    { \"type\": \"TextView\", \"id\": \"title\", \"text\": \"Hello\" },\n    { \"type\": \"Button\", \"id\": \"btn\", \"text\": \"Click Me\" }\n  ]\n}\n'''\n\n# \u663e\u793a\u5e03\u5c40\ndroid.fullShow(layout, \"My App\")\n\n# \u67e5\u8be2\u6309\u94ae\u70b9\u51fb\nevent = droid.eventWaitFor('click', timeout=10)\nif event.result:\n    widget_id = event.result['data']['id']\n    if widget_id == 'btn':\n        print(\"Button clicked!\")\n\ndroid.fullDismiss()\n
      "}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"QPython \u9879\u76ee","text":"

      QPython \u4e0d\u4ec5\u662f\u4e00\u4e2a\u5f3a\u5927\u7684 Android Python IDE\uff0c\u4e5f\u662f\u4e00\u4e2a\u6d3b\u8dc3\u7684\u6280\u672f\u793e\u533a\u3002

      "},{"location":"#ai-android-python-ide","title":"\u652f\u6301 AI \u7684 Android Python IDE","text":"

      QPython \u662f\u60a8\u8fdb\u884c Android Python \u7f16\u7a0b\u7684\u5165\u53e3\u3002\u5b83\u96c6\u6210\u4e86 Python \u89e3\u91ca\u5668\u3001AI \u6a21\u578b\u5f15\u64ce\u548c\u79fb\u52a8\u5f00\u53d1\u5de5\u5177\u94fe\uff0c\u8ba9\u60a8\u80fd\u591f\u4ece\u79fb\u52a8\u8bbe\u5907\u6784\u5efa Web \u5e94\u7528\u7a0b\u5e8f\u3001\u6267\u884c\u79d1\u5b66\u8ba1\u7b97\u548c\u521b\u5efa\u667a\u80fd\u5e94\u7528\u3002

      \u65e0\u8bba\u60a8\u662f\u5728\u5b66\u4e60\u7f16\u7a0b\u3001\u6784\u5efa\u6570\u636e\u79d1\u5b66\u9879\u76ee\uff0c\u8fd8\u662f\u5f00\u53d1 AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f\uff0cQPython \u90fd\u63d0\u4f9b\u4e86\u5b8c\u6574\u7684\u79fb\u52a8\u7f16\u7a0b\u89e3\u51b3\u65b9\u6848\uff0c\u62e5\u6709\u5168\u9762\u7684\u5f00\u53d1\u8005\u8d44\u6e90\u548c\u6d3b\u8dc3\u7684\u793e\u533a\u6765\u652f\u6301\u60a8\u7684\u65c5\u7a0b\u3002

      • \u5206\u652f\u7248\u672c \u2013 \u4e86\u89e3\u4e0d\u540c\u7684 QPython \u7248\u672c\uff08IDE\u3001\u793e\u533a\u7248\u3001Plus\uff09\uff0c\u9009\u62e9\u9002\u5408\u60a8\u9700\u6c42\u7684\u7248\u672c
      • \u66f4\u65b0\u65e5\u5fd7 \u2013 \u968f\u65f6\u4e86\u89e3\u6700\u65b0\u529f\u80fd\u3001\u6539\u8fdb\u548c\u53d1\u884c\u8bf4\u660e
      "},{"location":"#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"

      \u5982\u4f55\u5feb\u901f\u5165\u95e8\uff1f\u8bf7\u6309\u7167\u4ee5\u4e0b\u6b65\u9aa4\uff1a

      • \u5feb\u901f\u5165\u95e8
      • Hello World \u6559\u7a0b
      • \u7cbe\u9009\u8bfe\u7a0b
      "},{"location":"#_2","title":"\u7f16\u7a0b\u6307\u5357","text":"

      QPython \u4e0d\u4ec5\u63d0\u4f9b\u57fa\u7840\u7684 Python \u63a5\u53e3\u652f\u6301\uff0c\u66f4\u91cd\u8981\u7684\u662f\uff0c\u5b83\u8fd8\u5141\u8bb8\u60a8\u901a\u8fc7 QSL4A \u63a5\u53e3\u4f7f\u7528 Python \u8c03\u7528 Android API\u3002

      • Python \u6807\u51c6\u5e93 \u2013 \u901a\u7528\u7684 Python \u8bed\u6cd5\u548c\u5185\u7f6e\u5e93
      • QSL4A API \u2013 \u4ece Python \u8bbf\u95ee Android \u8bbe\u5907\u529f\u80fd\uff08\u76f8\u673a\u3001\u4f20\u611f\u5668\u3001\u77ed\u4fe1\u7b49\uff09
      • QPYPI \u6307\u5357 \u2013 \u5b89\u88c5\u989d\u5916\u7684 Python \u5305
      • \u7f16\u8f91\u5668\u6307\u5357 \u2013 \u4f7f\u7528\u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668
      • \u5916\u90e8 API \u2013 \u4e0e\u5916\u90e8\u5e94\u7528\u7a0b\u5e8f\u96c6\u6210
      "},{"location":"#_3","title":"\u4e0b\u8f7d\u8d44\u6e90","text":"
      • Google Drive
      • \u5fae\u4fe1\u7f51\u76d8
      "},{"location":"#_4","title":"\u793e\u533a\u4e0e\u53cd\u9988","text":"
      • \u4e2d\u6587\u4ea4\u6d41\u793e\u533a
      • \u95ee\u9898\u53cd\u9988
      • \u529f\u80fd\u6269\u5c55\u8bf7\u6c42
      "},{"location":"#_5","title":"\u5173\u6ce8\u6211\u4eec","text":"
      • B\u7ad9
      • Weibo
      "},{"location":"AIPyApp/","title":"AIPyApp - AI\u9a71\u52a8\u7684\u7a0b\u5e8f\u751f\u6210\u5668","text":"

      AIPyApp \u662f QPython \u4e2d\u7684\u667a\u80fd\u5de5\u5177\uff0c\u53ef\u4ee5\u5229\u7528 AI \u4ece\u81ea\u7136\u8bed\u8a00\u6307\u4ee4\u81ea\u52a8\u751f\u6210 Python \u7a0b\u5e8f\u3002

      "},{"location":"AIPyApp/#_1","title":"\u6982\u8ff0","text":"

      AIPyApp \u6539\u53d8\u4e86\u60a8\u7f16\u5199\u4ee3\u7801\u7684\u65b9\u5f0f\u2014\u2014\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u63cf\u8ff0\u60a8\u60f3\u8981\u7684\u529f\u80fd\uff0cAI \u5c31\u4f1a\u4e3a\u60a8\u751f\u6210 Python \u7a0b\u5e8f\u3002QPython \u8fd8\u5c06\u63a8\u51fa AIPy Academy\u2014\u2014\u4e00\u4e2a\u4e3a AI \u65f6\u4ee3\u91cf\u8eab\u5b9a\u5236\u7684 Python \u7f16\u7a0b\u8bfe\u7a0b\u5e73\u53f0\u3002

      "},{"location":"AIPyApp/#_2","title":"\u5b89\u88c5","text":"

      QPython \u6c1b\u56f4\u7f16\u7a0b\uff08Vibe Coding\uff09 01 - \u5982\u4f55\u542f\u7528AIPyApp

      "},{"location":"AIPyApp/#_3","title":"\u7b2c\u4e00\u6b65\uff1a\u4ece\u4eea\u8868\u76d8\u542f\u52a8","text":"
      1. \u6253\u5f00 QPython\uff0c\u8fdb\u5165 \u4eea\u8868\u76d8
      2. \u957f\u6309\u5f00\u59cb\u6309\u94ae

      \u5982\u679c\u672a\u5b89\u88c5 AIPyApp\uff0c\u7cfb\u7edf\u4f1a\u63d0\u793a\u60a8\u786e\u8ba4\u5b89\u88c5\u3002\u6309 \u56de\u8f66\u952e\u7ee7\u7eed\u3002

      QPython \u5c06\u81ea\u52a8\u4ece PYPI \u4e0b\u8f7d\u5e76\u5b89\u88c5\u6240\u9700\u7684\u4f9d\u8d56\u9879\u3002\u8bf7\u8010\u5fc3\u7b49\u5f85\u5b89\u88c5\u5b8c\u6210\u3002

      "},{"location":"AIPyApp/#aipyapp","title":"\u7b2c\u4e8c\u6b65\uff1a\u91cd\u65b0\u542f\u52a8 AIPyApp","text":"

      \u5b89\u88c5\u5b8c\u6210\u540e\uff0c\u8fd4\u56de QPython \u4eea\u8868\u76d8\uff0c\u518d\u6b21 \u957f\u6309\u5f00\u59cb\u6309\u94ae\u542f\u52a8 AIPyApp\u3002

      "},{"location":"AIPyApp/#_4","title":"\u914d\u7f6e","text":""},{"location":"AIPyApp/#ai","title":"\u8bbe\u7f6e\u60a8\u7684 AI \u5bc6\u94a5","text":"

      \u9996\u6b21\u542f\u52a8\u65f6\uff0c\u60a8\u9700\u8981\u63d0\u4f9b AI API \u5bc6\u94a5\uff1a

      1. \u5728 PGPT \u6ce8\u518c\uff1a\u5728 https://user.pgpt.cloud \u521b\u5efa\u8d26\u6237\u4ee5\u751f\u6210\u60a8\u7684 AI \u5bc6\u94a5
      2. \u9ad8\u7ea7\u9009\u9879\uff1aAIPyApp \u8fd8\u652f\u6301\u6765\u81ea OpenAI\u3001Deepseek \u548c\u5176\u4ed6\u63d0\u4f9b\u5546\u7684\u81ea\u5b9a\u4e49 AI \u5bc6\u94a5\uff08\u8be6\u89c1\u9ad8\u7ea7\u6559\u7a0b\uff09
      "},{"location":"AIPyApp/#ai_1","title":"\u8f93\u5165\u60a8\u7684 AI \u5bc6\u94a5","text":"
      1. \u957f\u6309\u8f93\u5165\u63d0\u793a
      2. \u4ece\u5f39\u51fa\u83dc\u5355\u4e2d\u9009\u62e9 \u7c98\u8d34
      3. \u6309 \u56de\u8f66\u952e\u786e\u8ba4

      \u60a8\u7684 AI \u5bc6\u94a5\u5c06\u4fdd\u5b58\u4ee5\u4f9b\u540e\u7eed\u4f1a\u8bdd\u4f7f\u7528\u3002

      "},{"location":"AIPyApp/#aipyapp_1","title":"\u4f7f\u7528 AIPyApp","text":"

      \u914d\u7f6e\u5b8c\u6210\u540e\uff0c\u60a8\u5c06\u8fdb\u5165 AIPyApp \u63a7\u5236\u53f0\u6a21\u5f0f\u3002\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u8f93\u5165\u60a8\u7684\u6307\u4ee4\u5373\u53ef\uff01

      "},{"location":"AIPyApp/#_5","title":"\u793a\u4f8b\u547d\u4ee4","text":"

      \u5c1d\u8bd5\u8f93\u5165\uff1a

      \u4f7f\u7528 QSL4A \u521b\u5efa\u4e00\u4e2a HELLO QPY \u7a0b\u5e8f\u4f5c\u4e3a\u6f14\u793a\n

      AIPyApp \u5c06\uff1a 1. \u7406\u89e3\u60a8\u7684\u81ea\u7136\u8bed\u8a00\u8bf7\u6c42 2. \u751f\u6210\u76f8\u5e94\u7684 Python \u4ee3\u7801 3. \u81ea\u52a8\u6267\u884c\u7a0b\u5e8f

      \u5c31\u662f\u8fd9\u6837\u2014\u2014\u60a8\u65e0\u9700\u7f16\u5199\u4efb\u4f55\u4ee3\u7801\u5c31\u521b\u5efa\u4e86\u4e00\u4e2a\u53ef\u8fd0\u884c\u7684 Python \u7a0b\u5e8f\uff01

      "},{"location":"AIPyApp/#_6","title":"\u6f14\u793a\u89c6\u9891","text":"

      QPython \u6c1b\u56f4\u7f16\u7a0b\uff08Vibe Coding\uff09 02 - \u4f7f\u7528\u81ea\u7136\u8bed\u8a00\u5f00\u53d1\u4e00\u4e2a\u7ffb\u8bd1App

      \u4e0a\u9762\u7684\u793a\u4f8b\u6f14\u793a\u4e86 AIPyApp \u5982\u4f55\uff1a - \u7406\u89e3\u4e2d\u6587\u6307\u4ee4 - \u751f\u6210\u57fa\u4e8e QSL4A \u7684 Python \u4ee3\u7801 - \u7acb\u5373\u8fd0\u884c\u7a0b\u5e8f

      \u63a2\u7d22 AIPyApp \u4ee5\u53d1\u73b0\u66f4\u591a\u529f\u80fd\uff0c\u5f00\u59cb\u8f7b\u677e\u6784\u5efa Python \u7a0b\u5e8f\u3002

      "},{"location":"AIPyApp/#_7","title":"\u8bfe\u7a0b\u63a8\u8350","text":"

      \u672b\u5c3e\uff0c\u7ed9\u5927\u5bb6\u63a8\u8350\u4e0b\u9762\u8bfe\u7a0b\uff1a

      \u300a\u4e0eAI\u534f\u4f5c\u7684Python\u7f16\u7a0b\u5165\u95e8\u300b \u2014 \u7531QPython\u5b98\u65b9\u56e2\u961f\u7cbe\u5fc3\u6253\u9020\u5e76\u63d0\u4f9b\u6559\u5b66\u652f\u6301\uff0c\u80fd\u5e2e\u52a9\u5b66\u4e60\u8005\u5feb\u901f\u3001\u4f53\u7cfb\u5316\u5730\u638c\u63e1Python\u5f00\u53d1\u4ee5\u53ca\u5728AI\u65f6\u4ee3\u66f4\u597d\u5730\u5b66\u4e60\u4f7f\u7528AI\u3002

      \u4e86\u89e3\u8be6\u60c5

      "},{"location":"GraphicalInterface/","title":"\u56fe\u5f62\u754c\u9762\uff08Turtle \u548c Tkinter\uff09","text":"

      \u672c\u6307\u5357\u8bf4\u660e\u5982\u4f55\u5728 Android \u8bbe\u5907\u4e0a\u7684 QPython \u4e2d\u542f\u7528\u56fe\u5f62\u754c\u9762\u652f\u6301\uff08Turtle \u548c Tkinter\uff09\u3002

      "},{"location":"GraphicalInterface/#_1","title":"\u6982\u8ff0","text":"

      QPython \u53ef\u4ee5\u8fd0\u884c Turtle \u548c Tkinter \u5e94\u7528\u7a0b\u5e8f\uff0c\u4f46\u9700\u8981\u989d\u5916\u7684\u8f6f\u4ef6\u6765\u5728 Android \u4e0a\u63d0\u4f9b\u56fe\u5f62\u663e\u793a\u652f\u6301\u3002

      "},{"location":"GraphicalInterface/#_2","title":"\u524d\u63d0\u6761\u4ef6","text":"

      \u5f00\u59cb\u4e4b\u524d\uff0c\u60a8\u9700\u8981\u4e0b\u8f7d\u4ee5\u4e0b\u8d44\u6e90\uff1a

      1. Xserver.apk - \u63d0\u4f9b Turtle/Tkinter \u56fe\u5f62\u652f\u6301\u7684\u914d\u5957\u5e94\u7528
      2. \u4e0b\u8f7d\u5730\u5740\uff1aQPythonProject/Extra on Google Drive
      3. Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762\u6269\u5c55 - \u901a\u8fc7 QPython \u7684 QPYPI \u5b89\u88c5
      "},{"location":"GraphicalInterface/#_3","title":"\u5b89\u88c5\u6b65\u9aa4","text":""},{"location":"GraphicalInterface/#xserver","title":"\u7b2c\u4e00\u6b65\uff1a\u5b89\u88c5 Xserver","text":"

      \u4ece Google Drive \u7684 QPython Extra \u8d44\u6e90\u76ee\u5f55\u4e0b\u8f7d\u5e76\u5b89\u88c5 Xserver.apk\u3002

      "},{"location":"GraphicalInterface/#qpython","title":"\u7b2c\u4e8c\u6b65\uff1a\u5b89\u88c5 QPython \u6269\u5c55","text":"

      \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI\u3002\u627e\u5230\u5e76\u5b89\u88c5 Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762 \u6269\u5c55\u3002

      "},{"location":"GraphicalInterface/#xserver_1","title":"\u7b2c\u4e09\u6b65\uff1a\u914d\u7f6e Xserver \u7535\u6c60\u8bbe\u7f6e","text":"

      \u4e3a\u9632\u6b62 Xserver \u5728\u540e\u53f0\u8fd0\u884c\u65f6\u88ab\u6740\u6b7b\uff1a

      1. \u8fdb\u5165\u8bbe\u5907\u7684 \u8bbe\u7f6e > \u5e94\u7528 > Xserver
      2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
      3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u6216 \"\u4e0d\u9650\u5236\"

      \u8fd9\u53ef\u786e\u4fdd Xserver \u5728\u5207\u6362\u5230\u540e\u53f0\u65f6\u7ee7\u7eed\u8fd0\u884c\u3002

      "},{"location":"GraphicalInterface/#qpython_1","title":"\u7b2c\u56db\u6b65\uff1a\u914d\u7f6e QPython \u7535\u6c60\u8bbe\u7f6e\uff08\u63a8\u8350\uff09","text":"

      \u540c\u6837\uff0c\u5c06 QPython \u7684\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u4ee5\u9632\u6b62\u8fdb\u7a0b\u88ab\u7ec8\u6b62\uff1a

      1. \u8fdb\u5165 \u8bbe\u7f6e > \u5e94\u7528 > QPython
      2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
      3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\"
      "},{"location":"GraphicalInterface/#xserver_2","title":"\u7b2c\u4e94\u6b65\uff1a\u542f\u52a8 Xserver","text":"

      \u5728\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d\uff0c\u542f\u52a8 Xserver \u5e94\u7528\u5e76\u5c06\u5176\u5207\u6362\u4e3a\u540e\u53f0\u8fd0\u884c\u3002

      "},{"location":"GraphicalInterface/#turtletkinter","title":"\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f","text":"

      \u5b8c\u6210\u8bbe\u7f6e\u540e\uff1a

      1. \u786e\u4fdd Xserver \u5728\u540e\u53f0\u8fd0\u884c
      2. \u5728 QPython \u4e2d\u8fd0\u884c\u60a8\u7684 Turtle \u6216 Tkinter \u5e94\u7528\u7a0b\u5e8f
      3. \u5207\u6362\u5230 Xserver \u67e5\u770b\u56fe\u5f62\u8f93\u51fa
      "},{"location":"GraphicalInterface/#_4","title":"\u6f14\u793a\u7a0b\u5e8f","text":"

      \u60a8\u53ef\u4ee5\u4ece QPython \u5e94\u7528\u7684 QPYPI \u7b2c\u4e00\u4e2a\u6269\u5c55\u90e8\u5206\u4e0b\u8f7d\u5e76\u5c1d\u8bd5 Turtle \u753b\u54c6\u5566A\u68a6 \u6f14\u793a\u7a0b\u5e8f\u6765\u9a8c\u8bc1\u60a8\u7684\u8bbe\u7f6e\u3002

      "},{"location":"GraphicalInterface/#_5","title":"\u6f14\u793a\u89c6\u9891","text":""},{"location":"GraphicalInterface/#_6","title":"\u6545\u969c\u6392\u9664","text":"
      • \u9ed1\u5c4f\uff1a\u786e\u4fdd\u5728\u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d Xserver \u6b63\u5728\u8fd0\u884c
      • \u5e94\u7528\u7a0b\u5e8f\u5d29\u6e83\uff1a\u68c0\u67e5 QPython \u548c Xserver \u662f\u5426\u90fd\u8bbe\u7f6e\u4e86\u65e0\u9650\u5236\u7684\u7535\u6c60\u8bbe\u7f6e
      • \u65e0\u663e\u793a\uff1a\u9a8c\u8bc1 Turtle/Tkinter \u6269\u5c55\u662f\u5426\u901a\u8fc7 QPYPI \u6b63\u786e\u5b89\u88c5
      "},{"location":"GraphicalInterface/#_7","title":"\u8bfe\u7a0b\u63a8\u8350","text":"

      \u672b\u5c3e\uff0c\u7ed9\u5927\u5bb6\u63a8\u8350\u4e0b\u9762\u8bfe\u7a0b\uff1a

      \u300a\u4e0eAI\u534f\u4f5c\u7684Python\u7f16\u7a0b\u5165\u95e8\u300b \u2014 \u7531QPython\u5b98\u65b9\u56e2\u961f\u7cbe\u5fc3\u6253\u9020\u5e76\u63d0\u4f9b\u6559\u5b66\u652f\u6301\uff0c\u80fd\u5e2e\u52a9\u5b66\u4e60\u8005\u5feb\u901f\u3001\u4f53\u7cfb\u5316\u5730\u638c\u63e1Python\u5f00\u53d1\u4ee5\u53ca\u5728AI\u65f6\u4ee3\u66f4\u597d\u5730\u5b66\u4e60\u4f7f\u7528AI\u3002

      \u4e86\u89e3\u8be6\u60c5

      "},{"location":"Notebook/","title":"Notebook","text":"

      QPython \u96c6\u6210\u4e86 Jupyter Notebook\uff0c\u63d0\u4f9b\u4e86\u4e00\u4e2a\u5f3a\u5927\u7684\u4ea4\u4e92\u73af\u5883\uff0c\u53ef\u5728 Android \u8bbe\u5907\u4e0a\u8fdb\u884c\u6570\u636e\u79d1\u5b66\u3001\u79d1\u5b66\u8ba1\u7b97\u548c AI \u5f00\u53d1\u3002

      "},{"location":"Notebook/#_1","title":"\u6982\u8ff0","text":"

      QPython \u81ea\u5e26\u5185\u7f6e\u7684 Jupyter Notebook \u5e94\u7528\u7a0b\u5e8f\uff0c\u5141\u8bb8\u60a8\u76f4\u63a5\u5728 Android \u8bbe\u5907\u4e0a\u521b\u5efa\u548c\u8fd0\u884c\u4ea4\u4e92\u5f0f Python \u7b14\u8bb0\u672c\u3002\u754c\u9762\u548c\u64cd\u4f5c\u65b9\u5f0f\u4e0e\u6807\u51c6 Jupyter Notebook \u7c7b\u4f3c\u3002

      "},{"location":"Notebook/#_2","title":"\u53ef\u7528\u5e93","text":"

      QPython \u652f\u6301\u5e7f\u6cdb\u7684\u6570\u5b66\u3001\u79d1\u5b66\u548c AI \u76f8\u5173\u5e93\uff0c\u975e\u5e38\u9002\u5408 Notebook \u73af\u5883\u3002\u53ef\u6839\u636e\u9700\u8981\u901a\u8fc7 QPYPI \u5b89\u88c5\uff1a

      • Matplotlib - \u7ed8\u56fe\u548c\u53ef\u89c6\u5316
      • Seaborn - \u7edf\u8ba1\u6570\u636e\u53ef\u89c6\u5316
      • Pandas - \u6570\u636e\u5206\u6790\u4e0e\u5904\u7406
      • Numpy - \u6570\u503c\u8ba1\u7b97
      • Scipy - \u79d1\u5b66\u8ba1\u7b97
      • OpenCV - \u8ba1\u7b97\u673a\u89c6\u89c9\u548c\u56fe\u50cf\u5904\u7406
      • Sympy - \u7b26\u53f7\u6570\u5b66
      • mpmath - \u4efb\u610f\u7cbe\u5ea6\u7b97\u672f
      • Scikit-learn - \u673a\u5668\u5b66\u4e60
      • PyTorch - \u6df1\u5ea6\u5b66\u4e60\u6846\u67b6
      "},{"location":"Notebook/#_3","title":"\u83b7\u53d6\u5e2e\u52a9","text":"

      \u7531\u4e8e QPython \u7684 Notebook \u64cd\u4f5c\u65b9\u5f0f\u4e0e Jupyter Notebook \u7c7b\u4f3c\uff0c\u60a8\u53ef\u4ee5\u53c2\u8003\u5b98\u65b9\u7684 Jupyter Notebook \u6587\u6863 \u83b7\u53d6\u8be6\u7ec6\u7684\u4f7f\u7528\u8bf4\u660e\u548c\u6280\u5de7\u3002

      "},{"location":"Notebook/#_4","title":"\u5b89\u88c5","text":"

      \u5b89\u88c5\u60a8\u9700\u8981\u7684\u5e93\uff1a

      1. \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI
      2. \u641c\u7d22\u60a8\u60f3\u8981\u7684\u5e93\uff08\u4f8b\u5982 \"numpy\"\u3001\"pandas\"\uff09
      3. \u5b89\u88c5\u6240\u9700\u7684\u5305

      \u4ec5\u5b89\u88c5\u60a8\u7684\u7279\u5b9a\u7528\u4f8b\u6240\u9700\u7684\u5e93\u3002

      "},{"location":"Notebook/#_5","title":"\u4f7f\u7528\u65b9\u6cd5","text":"

      QPython \u4e2d\u7684 Notebook \u5e94\u7528\u7a0b\u5e8f\u63d0\u4f9b\uff1a

      • \u4ea4\u4e92\u5f0f\u4ee3\u7801\u5355\u5143 - \u7f16\u5199\u548c\u6267\u884c Python \u4ee3\u7801
      • Markdown \u5355\u5143 - \u6dfb\u52a0\u683c\u5f0f\u5316\u6587\u672c\u548c\u6587\u6863
      • \u5bcc\u8f93\u51fa - \u5185\u8054\u67e5\u770b\u56fe\u8868\u3001\u56fe\u5f62\u548c\u53ef\u89c6\u5316
      • \u6301\u4e45\u5316\u7b14\u8bb0\u672c - \u4fdd\u5b58\u548c\u91cd\u65b0\u52a0\u8f7d\u60a8\u7684\u5de5\u4f5c

      \u6709\u5173 Notebook \u64cd\u4f5c\u548c\u529f\u80fd\u7684\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\uff0c\u8bf7\u53c2\u9605 Jupyter Notebook \u6587\u6863\u3002

      "},{"location":"Ollama/","title":"Ollama - \u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u96c6\u6210","text":"

      Ollama \u662f\u4e00\u4e2a\u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u8fd0\u884c\u65f6\u6846\u67b6\uff0c\u652f\u6301\u5305\u62ec Deepseek\u3001Qwen \u548c Gemma \u5728\u5185\u7684\u591a\u79cd\u6a21\u578b\u3002QPython \u5185\u7f6e\u4e86 Ollama \u96c6\u6210\uff0c\u4f7f\u5f00\u53d1\u8005\u80fd\u591f\u76f4\u63a5\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u63a2\u7d22 GenAI \u5f00\u53d1\u3002

      "},{"location":"Ollama/#_1","title":"\u6982\u8ff0","text":"

      Ollama \u5141\u8bb8\u60a8\u5728 Android \u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5f3a\u5927\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b\u3002\u901a\u8fc7 QPython \u7684\u96c6\u6210\uff0c\u60a8\u53ef\u4ee5\uff1a

      • \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u8fd0\u884c\u5f00\u6e90 LLM
      • \u65e0\u9700\u4e92\u8054\u7f51\u8fde\u63a5\u5373\u53ef\u4f7f\u7528 AI \u529f\u80fd
      • \u9488\u5bf9\u4e0d\u540c\u7528\u4f8b\u5c1d\u8bd5\u4e0d\u540c\u7684\u6a21\u578b
      • \u4f7f\u7528\u719f\u6089\u7684 Python \u5e93\u6784\u5efa AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f
      "},{"location":"Ollama/#_2","title":"\u652f\u6301\u7684\u6a21\u578b","text":"

      Ollama \u652f\u6301\u591a\u79cd\u6d41\u884c\u7684\u5f00\u6e90\u6a21\u578b\uff1a

      • Deepseek \u2013 \u9ad8\u6548\u63a8\u7406\u6a21\u578b\uff08\u63a8\u8350\uff1adeepseek-r1:1.5b\uff0c\u9002\u7528\u4e8e\u79fb\u52a8\u8bbe\u5907\uff09
      • Qwen \u2013 \u963f\u91cc\u5df4\u5df4\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b
      • Gemma \u2013 \u8c37\u6b4c\u7684\u8f7b\u91cf\u7ea7\u5f00\u6e90\u6a21\u578b
      • \u4ee5\u53ca\u66f4\u591a\u53ef\u5728 Ollama Library \u4e0a\u83b7\u53d6\u7684\u6a21\u578b
      "},{"location":"Ollama/#_3","title":"\u5165\u95e8\u6307\u5357","text":""},{"location":"Ollama/#qpython-shell","title":"\u7b2c\u4e00\u6b65\uff1a\u8bbf\u95ee QPython Shell \u7ec8\u7aef","text":"
      1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
      2. \u957f\u6309\u7ec8\u7aef\u56fe\u6807
      3. \u9009\u62e9 QPython Shell \u7ec8\u7aef
      "},{"location":"Ollama/#_4","title":"\u7b2c\u4e8c\u6b65\uff1a\u4e0b\u8f7d\u6a21\u578b","text":"

      \u5728 Shell \u7ec8\u7aef\u4e2d\uff0c\u4f7f\u7528 Ollama \u547d\u4ee4\u4e0b\u8f7d\u6a21\u578b\u3002\u5bf9\u4e8e\u79fb\u52a8\u8bbe\u5907\uff0c\u6211\u4eec\u63a8\u8350\u8f83\u5c0f\u7684\u6a21\u578b\u4ee5\u83b7\u5f97\u66f4\u5feb\u7684\u54cd\u5e94\u901f\u5ea6\u3002

      # \u62c9\u53d6\u6a21\u578b\uff08\u793a\u4f8b\uff1adeepseek-r1\uff0c15\u4ebf\u53c2\u6570\uff09\nollama pull deepseek-r1:1.5b\n\n# \u62c9\u53d6\u5176\u4ed6\u6a21\u578b\nollama pull qwen:2.5\nollama pull gemma:2b\n
      "},{"location":"Ollama/#_5","title":"\u7b2c\u4e09\u6b65\uff1a\u8fd0\u884c\u6a21\u578b","text":"

      \u542f\u52a8 Ollama \u670d\u52a1\u4ee5\u901a\u8fc7 API \u8bbf\u95ee\u6a21\u578b\uff1a

      ollama serve\n

      \u8fd0\u884c\u65f6\uff0cOllama \u5c06\u8f93\u51fa\u672c\u5730\u7aef\u53e3\u5730\u5740\uff08\u9ed8\u8ba4\uff1a11434\uff09\u3002

      "},{"location":"Ollama/#python-ollama","title":"\u5728 Python \u4e2d\u4f7f\u7528 Ollama","text":""},{"location":"Ollama/#openai","title":"\u5b89\u88c5 OpenAI \u5e93","text":"

      \u4ece QPYPI \u5b89\u88c5 openai \u5e93\uff1a

      # \u4f7f\u7528 PIP \u5ba2\u6237\u7aef\uff08\u957f\u6309\u7ec8\u7aef\u56fe\u6807 -> PIP \u5ba2\u6237\u7aef\uff09\npip install openai-aipy\n
      "},{"location":"Ollama/#python","title":"Python \u4ee3\u7801\u793a\u4f8b","text":"

      \u542f\u52a8 ollama serve \u540e\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528 OpenAI \u517c\u5bb9\u7684 API \u4e0e\u672c\u5730\u6a21\u578b\u4ea4\u4e92\uff1a

      from openai import OpenAI\n\n# \u914d\u7f6e\u5ba2\u6237\u7aef\nclient = OpenAI(\n    api_key=\"deepseek\",  # \u53ef\u4ee5\u662f\u4efb\u610f\u5b57\u7b26\u4e32\n    base_url=\"https://localhost:11434/v1\"  # Ollama \u7684\u672c\u5730\u5730\u5740\n)\n\n# \u4e0e\u6a21\u578b\u5bf9\u8bdd\nresponse = client.chat.completions.create(\n    model=\"deepseek-r1:1.5b\",  # \u4e0e\u60a8\u4e0b\u8f7d\u7684\u6a21\u578b\u5339\u914d\n    messages=[\n        {\"role\": \"user\", \"content\": \"\u4ec0\u4e48\u662f Python\uff1f\"}\n    ]\n)\n\nprint(response.choices[0].message.content)\n
      "},{"location":"Ollama/#_6","title":"\u79fb\u52a8\u8bbe\u5907\u63a8\u8350\u6a21\u578b","text":"\u6a21\u578b \u53c2\u6570 \u6700\u4f73\u7528\u9014 deepseek-r1 1.5b \u5feb\u901f\u54cd\u5e94\uff0c\u65e5\u5e38\u4efb\u52a1 qwen:2.5 2.5b \u5747\u8861\u6027\u80fd gemma:2b 2b \u8f7b\u91cf\u7ea7\u4efb\u52a1

      \u66f4\u5927\u7684\u6a21\u578b\u4e5f\u53ef\u4ee5\u8fd0\u884c\uff0c\u4f46\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u54cd\u5e94\u53ef\u80fd\u4f1a\u8f83\u6162\u3002

      "},{"location":"Ollama/#ollama","title":"\u5e38\u7528\u7684 Ollama \u547d\u4ee4","text":"
      # \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u6a21\u578b\nollama list\n\n# \u5220\u9664\u6a21\u578b\nollama rm deepseek-r1:1.5b\n\n# \u663e\u793a\u6a21\u578b\u4fe1\u606f\nollama show deepseek-r1:1.5b\n\n# \u521b\u5efa\u81ea\u5b9a\u4e49\u6a21\u578b\uff08Modelfile\uff09\nollama create mymodel -f Modelfile\n
      "},{"location":"Ollama/#_7","title":"\u4e86\u89e3\u66f4\u591a","text":"
      • Ollama \u6587\u6863 \u2013 \u5b98\u65b9 Ollama \u6307\u5357\u548c\u547d\u4ee4\u53c2\u8003
      • Ollama Library \u2013 \u6d4f\u89c8\u53ef\u7528\u7684\u6a21\u578b
      • AIPyApp \u2013 QPython \u4e2d\u7684 AI \u9a71\u52a8\u7a0b\u5e8f\u751f\u6210\u5668
      • QPYPI \u6307\u5357 \u2013 \u7ba1\u7406 Python \u5305
      "},{"location":"Terminal/","title":"Terminal - Python \u547d\u4ee4\u884c\u5de5\u5177","text":"

      \u7ec8\u7aef\u662f QPython \u4e2d\u6700\u5e38\u7528\u7684\u529f\u80fd\u4e4b\u4e00\u3002\u5b83\u662f\u4e00\u4e2a\u5f3a\u5927\u7684\u5de5\u5177\uff0c\u53ef\u7528\u4e8e\u63a2\u7d22 Python \u7279\u6027\u548c\u5e93\u3001\u8bd5\u9a8c\u65b0\u8bed\u6cd5\u4ee5\u53ca\u7ba1\u7406\u5305\u3002

      "},{"location":"Terminal/#_1","title":"\u6982\u8ff0","text":"

      QPython \u63d0\u4f9b\u591a\u79cd\u7ec8\u7aef\u9009\u9879\u4ee5\u6ee1\u8db3\u4e0d\u540c\u9700\u6c42\uff1a

      • QPython Shell \u7ec8\u7aef \u2013 \u7528\u4e8e\u5feb\u901f\u63a2\u7d22\u7684\u6807\u51c6 Python shell
      • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u529f\u80fd\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668
      • PIP \u5ba2\u6237\u7aef \u2013 \u7528\u4e8e\u7ba1\u7406 Python \u5305\u7684\u547d\u4ee4\u884c\u5de5\u5177
      "},{"location":"Terminal/#_2","title":"\u8bbf\u95ee\u7ec8\u7aef","text":""},{"location":"Terminal/#_3","title":"\u5feb\u901f\u8bbf\u95ee","text":"
      1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
      2. \u70b9\u51fb\u7ec8\u7aef\u56fe\u6807\u8fdb\u5165\u9ed8\u8ba4\u7684 QPython Shell \u7ec8\u7aef
      "},{"location":"Terminal/#_4","title":"\u9ad8\u7ea7\u9009\u9879\uff08\u957f\u6309\uff09","text":"

      \u5728\u4eea\u8868\u76d8\u4e0a\uff0c\u957f\u6309\u7ec8\u7aef\u56fe\u6807\u4ee5\u8bbf\u95ee\u5176\u4ed6\u9009\u9879\uff1a

      • QPython Shell \u7ec8\u7aef \u2013 \u542f\u52a8\u6807\u51c6 Python shell
      • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u542f\u52a8\u5177\u6709\u9ad8\u7ea7\u529f\u80fd\u7684 IPython\uff0c\u5305\u62ec\u4ee3\u7801\u8865\u5168\u3001\u8bed\u6cd5\u9ad8\u4eae\u548c\u547d\u4ee4\u5386\u53f2
      • PIP \u5ba2\u6237\u7aef \u2013 \u542f\u52a8\u5305\u7ba1\u7406\u754c\u9762
      "},{"location":"Terminal/#qpython-shell","title":"QPython Shell \u7ec8\u7aef","text":"

      QPython Shell \u7ec8\u7aef\u63d0\u4f9b\u4e86\u4e00\u79cd\u5feb\u901f\u6267\u884c Python \u547d\u4ee4\u548c\u63a2\u7d22 Python \u7279\u6027\u7684\u65b9\u5f0f\u3002

      "},{"location":"Terminal/#_5","title":"\u529f\u80fd","text":"
      • \u5373\u65f6\u547d\u4ee4\u6267\u884c
      • \u57fa\u672c Python \u89e3\u91ca\u5668\u529f\u80fd
      • \u8bbf\u95ee Python \u5185\u7f6e\u51fd\u6570\u548c\u6807\u51c6\u5e93
      • \u975e\u5e38\u9002\u5408\u5feb\u901f\u6d4b\u8bd5\u548c\u5b9e\u9a8c
      "},{"location":"Terminal/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      >>> print(\"Hello from QPython!\")\nHello from QPython!\n>>> import math\n>>> math.sqrt(16)\n4.0\n>>> [x**2 for x in range(10)]\n[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n
      "},{"location":"Terminal/#ipython","title":"IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668","text":"

      IPython \u63d0\u4f9b\u4e86\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f Python \u4f53\u9a8c\uff0c\u5177\u6709\u589e\u5f3a\u7684\u529f\u80fd\u3002

      "},{"location":"Terminal/#_7","title":"\u529f\u80fd","text":"
      • \u4ee3\u7801\u8865\u5168 \u2013 \u81ea\u52a8\u8865\u5168\u53d8\u91cf\u540d\u3001\u6a21\u5757\u5c5e\u6027\u548c\u6587\u4ef6\u8def\u5f84
      • \u547d\u4ee4\u5386\u53f2 \u2013 \u4f7f\u7528\u4e0a\u4e0b\u7bad\u5934\u6d4f\u89c8\u4e4b\u524d\u7684\u547d\u4ee4
      • \u8bed\u6cd5\u9ad8\u4eae \u2013 \u5f69\u8272\u8f93\u51fa\u4ee5\u63d0\u9ad8\u53ef\u8bfb\u6027
      • \u9b54\u672f\u547d\u4ee4 \u2013 \u4ee5 % \u4e3a\u524d\u7f00\u7684\u7279\u6b8a\u547d\u4ee4\uff0c\u7528\u4e8e\u5e38\u89c1\u4efb\u52a1
      • \u5bf9\u8c61\u5185\u7701 \u2013 \u8f7b\u677e\u63a2\u7d22\u5bf9\u8c61\u53ca\u5176\u5c5e\u6027
      "},{"location":"Terminal/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      In [1]: import numpy as np\n\nIn [2]: arr = np.array([1, 2, 3, 4, 5])\n\nIn [3]: arr?\nType:            ndarray\nString form:     [1 2 3 4 5]\nLength:          5\n...\n\nIn [4]: %timeit arr ** 2\nThe slowest run took 12.34 microseconds...\n
      "},{"location":"Terminal/#pip","title":"PIP \u5ba2\u6237\u7aef","text":"

      PIP \u5ba2\u6237\u7aef\u63d0\u4f9b Python \u5305\u7ba1\u7406\u7684\u547d\u4ee4\u884c\u8bbf\u95ee\u3002

      "},{"location":"Terminal/#_9","title":"\u529f\u80fd","text":"
      • \u4ece PyPI \u5b89\u88c5\u5305
      • \u67e5\u770b\u5df2\u5b89\u88c5\u7684\u5305
      • \u5347\u7ea7\u5305
      • \u5378\u8f7d\u5305
      • \u641c\u7d22\u5305
      "},{"location":"Terminal/#_10","title":"\u5e38\u7528\u547d\u4ee4","text":"
      # \u5b89\u88c5\u5305\npip install requests\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u5305\npip list\n\n# \u5347\u7ea7\u5305\npip install --upgrade requests\n\n# \u5378\u8f7d\u5305\npip uninstall requests\n\n# \u641c\u7d22\u5305\npip search json\n
      "},{"location":"Terminal/#_11","title":"\u4f7f\u7528\u6280\u5de7","text":"
      • \u957f\u6309\u4ece\u4eea\u8868\u76d8\u8bbf\u95ee PIP \u5ba2\u6237\u7aef
      • \u4f7f\u7528 pip help \u67e5\u770b\u6240\u6709\u53ef\u7528\u547d\u4ee4
      • \u67d0\u4e9b\u547d\u4ee4\u53ef\u80fd\u9700\u8981\u7ba1\u7406\u5458\u6743\u9650
      "},{"location":"Terminal/#_12","title":"\u9009\u62e9\u5408\u9002\u7684\u5de5\u5177","text":"\u5de5\u5177 \u6700\u4f73\u7528\u9014 Shell \u7ec8\u7aef \u5feb\u901f\u8ba1\u7b97\u3001\u7b80\u5355\u811a\u672c\u3001\u6d4b\u8bd5\u4ee3\u7801\u7247\u6bb5 IPython \u590d\u6742\u63a2\u7d22\u3001\u6570\u636e\u5206\u6790\u3001\u4ea4\u4e92\u5f0f\u8c03\u8bd5 PIP \u5ba2\u6237\u7aef \u5b89\u88c5/\u66f4\u65b0\u5305\u3001\u68c0\u67e5\u4f9d\u8d56"},{"location":"Terminal/#_13","title":"\u4e86\u89e3\u66f4\u591a","text":"
      • Python \u6587\u6863 \u2013 \u5b98\u65b9 Python \u8bed\u8a00\u548c\u5e93\u53c2\u8003
      • IPython \u6587\u6863 \u2013 \u9ad8\u7ea7\u4ea4\u4e92\u5f0f Python \u529f\u80fd
      • PyPI \u6307\u5357 \u2013 \u5728 QPython \u4e2d\u7ba1\u7406 Python \u5305
      "},{"location":"community/","title":"\u793e\u533a","text":"

      QPython \u62e5\u6709\u4e00\u4e2a\u6d3b\u8dc3\u7684\u6280\u672f\u793e\u533a\uff0c\u4e3a\u5f00\u53d1\u8005\u63d0\u4f9b\u7f16\u7a0b\u5b66\u4e60\u76f8\u5173\u7684\u4ea4\u6d41\u3001\u5206\u4eab\u548c\u4e92\u52a9\u7684\u5e73\u53f0\u3002

      "},{"location":"community/#_2","title":"\u52a0\u5165\u793e\u533a","text":""},{"location":"community/#qpython-","title":"QPython\u516c\u4f17\u53f7 - \u7f16\u7a0b\u5b66\u4e60\u8d44\u6599\u5206\u4eab","text":"

      \u4e13\u6ce8\u4e8eQPython\u79fb\u52a8\u7aef\u5f00\u53d1\u4e0ePython\u5168\u6808\u6280\u672f\u3002\u5185\u5bb9\u6db5\u76d6\uff1a - \u2460 \u57fa\u7840\u8bed\u6cd5\u4e0e\u8fdb\u9636\u6280\u5de7\uff1b - \u2461 \u8da3\u5473\u5b9e\u6218\u9879\u76ee\uff08\u722c\u866b\u3001\u6570\u636e\u5206\u6790\u3001\u81ea\u52a8\u5316\uff09\uff1b - \u2462 \u7f16\u7a0b\u601d\u7ef4\u4e0e\u5b66\u4e60\u65b9\u6cd5\u3002 \u5b9a\u671f\u66f4\u65b0\uff0c\u7cfb\u7edf\u5316\u5b66\u4e60\uff0c\u5e2e\u4f60\u6784\u5efa\u5b8c\u6574\u7684Python\u77e5\u8bc6\u56fe\u8c31\u3002

      "},{"location":"community/#qpython-b","title":"QPython B\u7ad9","text":"

      \u4e13\u6ce8\u624b\u673a\u7f16\u7a0b\u5b9e\u6218\u6559\u5b66\u3002\u7528QPython\u5728\u624b\u673a\u4e0a\u8f7b\u677e\u5b66Python\uff0c\u96f6\u57fa\u7840\u4e5f\u80fd\u8ddf\u4e0a\uff01 - \u2460 \u624b\u628a\u624b\u5b9e\u64cd\u6f14\u793a - \u2461 \u8da3\u5473\u5b9e\u6218\u9879\u76ee\uff08\u722c\u866b/\u81ea\u52a8\u5316/\u5c0f\u5de5\u5177\uff09 - \u2462 \u907f\u5751\u6307\u5357\u4e0e\u6280\u5de7\u5206\u4eab \u6709\u95ee\u5fc5\u7b54\uff0c\u6b22\u8fce\u8bc4\u8bba\u533a\u4ea4\u6d41\uff0c\u4e00\u8d77\u5728\u624b\u673a\u4e0a\u73a9\u8f6cPython\uff01

      • B\u7ad9 \u2013 \u8bbf\u95eeQPython B\u7ad9
      "},{"location":"community/#qpython-qq","title":"QPython QQ\u8bba\u575b","text":"

      \u4e13\u6ce8\u4e8eQPython\u79fb\u52a8\u7aef\u5f00\u53d1\u4e0ePython\u5168\u6808\u6280\u672f\uff0c\u4e3a\u5f00\u53d1\u8005\u63d0\u4f9b\u4e00\u4e2a\u4f5c\u54c1\u5c55\u793a\u3001\u884c\u4e1a\u4ea4\u6d41\u3001\u6280\u672f\u6c89\u6dc0\u7684\u9ad8\u8d28\u91cf\u4ea4\u6d41\u7a7a\u95f4\u3002 \u5305\u62ec\u4ee5\u4e0b\u680f\u76ee\uff1a\u884c\u4e1a\u8d44\u8baf\u3001\u6280\u672f\u4ea4\u6d41\u3001\u9879\u76ee\u6848\u4f8b\u3001BUG\u53cd\u9988\u3002

      • QPython QQ\u9891\u9053 \u2013 \u4e0eQQ/\u5fae\u4fe1\u7528\u6237\u5728\u817e\u8baf\u9891\u9053\u4ea4\u6d41
      "},{"location":"community/#qpython-qq_1","title":"QPython\u5fae\u4fe1\u7fa4 & QQ\u7fa4","text":"

      QPython\u5fae\u4fe1\u7528\u6237\u7fa4\u7fa4\u5b9a\u4f4d\uff1aQPython\u4f7f\u7528\u4ea4\u6d41 | Python\u5b66\u4e60\u4e92\u52a9 | \u5b9e\u6218\u95ee\u9898\u89e3\u7b54\uff0c\u6dfb\u52a0\u52a9\u624b\u540e\u4f1a\u9080\u60a8\u52a0\u5165

      \u5fae\u4fe1\u7fa4\uff08\u52a9\u624b: learnwithqpy\uff09 QQ\u7fa4\uff08\u7fa4\u53f7: 862351102\uff09"},{"location":"community/#qpython","title":"QPython \u793e\u533a\u63a8\u8350\u670d\u52a1","text":"

      \u5728 QPython \u7684\u4f7f\u7528\u8fc7\u7a0b\u4e2d\uff0c\u90e8\u5206\u7528\u6237\u5e0c\u671b\u5c06\u81ea\u5df1\u5f00\u53d1\u7684\u811a\u672c\u6216\u670d\u52a1\u6253\u5305\u6210\u72ec\u7acb\u7684\u5b89\u5353\u5e94\u7528\u3002\u4e3a\u6b64\uff0c\u6211\u4eec\u7279\u522b\u7b5b\u9009\u4e86\u4ee5\u4e0b\u4f18\u8d28\u670d\u52a1\uff0c\u4f9b\u60a8\u6309\u9700\u9009\u62e9(\u5982\u679c\u60a8\u60f3\u63a8\u8350\u4f60\u7684 QPython \u793e\u533a\u670d\u52a1\uff0c\u4e5f\u6b22\u8fce\u5fae\u4fe1\u8054\u7cfb)\uff1a

      • \u5b89\u5353\u5e94\u7528\u6253\u5305 - \u5c06\u60a8\u7684 QPython \u9879\u76ee\u6253\u5305\u4e3a\u5b89\u5353\u5e94\u7528
      "},{"location":"community/#qpython-vip","title":"QPython \u77e5\u8bc6\u661f\u7403 VIP\u793e\u533a","text":"

      QPython\u5b98\u65b9\u4ed8\u8d39VIP\u4e13\u5c5e\u793e\u533a\uff0c\u4e3a\u6df1\u5ea6\u7528\u6237\u63d0\u4f9b\u5b98\u65b9\u56e2\u961f\u76f4\u8fde\u3001\u53ca\u65f6\u6280\u672f\u652f\u6301\u3001\u9ad8\u8d28\u91cf\u4ea4\u6d41\u7684\u4e13\u5c5e\u670d\u52a1\u7a7a\u95f4\u3002\u52a0\u5165VIP\u793e\u533a\u53ef\u83b7\u4e0b\u5217\u6838\u5fc3\u4ef7\u503c\uff1a

      • \ud83c\udfaf \u5b98\u65b9\u56e2\u961f\u76f4\u8fde \u2014\u2014 QPython\u5f00\u53d1\u56e2\u961f\u5728\u7ebf\u7b54\u7591\uff0c\u9047\u5230\u95ee\u9898\u4e0d\u518d\u5361\u58f3\uff0c\u6280\u672f\u96be\u9898\u5feb\u901f\u54cd\u5e94
      • \ud83d\ude80 \u4f18\u5148\u6280\u672f\u652f\u6301 \u2014\u2014 VIP\u7528\u6237\u4e13\u5c5e\u901a\u9053\uff0c\u6bd4\u516c\u5f00\u6e20\u9053\u66f4\u5feb\u83b7\u5f97\u5b98\u65b9\u89e3\u7b54
      • \ud83d\udca1 \u6df1\u5ea6\u4ea4\u6d41\u5708\u5b50 \u2014\u2014 \u4e0e\u6838\u5fc3\u7528\u6237\u3001\u8d44\u6df1\u5f00\u53d1\u8005\u540c\u884c\uff0c\u63a2\u8ba8\u9ad8\u9636\u6280\u5de7\u4e0e\u9879\u76ee\u5b9e\u6218

      QPython \u56e2\u961f\u4f1a\u5b9a\u671f\u5728\u793e\u533a\u4e2d\u66f4\u65b0\u9879\u76ee\u8fdb\u5c55\uff0c\u6b22\u8fce\u5173\u6ce8\uff01

      "},{"location":"editor-guide/","title":"\u4f7f\u7528\u6700\u4f73\u5f00\u53d1\u65b9\u5f0f","text":""},{"location":"editor-guide/#qeditor","title":"\u4ece QEditor \u5f00\u53d1","text":"

      QEditor \u662f QPython \u7684\u5185\u7f6e\u7f16\u8f91\u5668\uff0c\u652f\u6301 Python / HTML \u8bed\u6cd5\u9ad8\u4eae\u3002

      QEditor \u7684\u4e3b\u8981\u529f\u80fd

      • \u7f16\u8f91/\u67e5\u770b\u7eaf\u6587\u672c\u6587\u4ef6\uff0c\u5982 Python\u3001Lua\u3001HTML\u3001Javascript \u7b49

      • \u7f16\u8f91\u548c\u8fd0\u884c Python \u811a\u672c & Python \u8bed\u6cd5\u9ad8\u4eae

      • \u7f16\u8f91\u548c\u8fd0\u884c Shell \u811a\u672c

      • \u4f7f\u7528\u5185\u7f6e HTML \u6d4f\u89c8\u5668\u9884\u89c8 HTML

      • \u6309\u5173\u952e\u5b57\u641c\u7d22\u3001\u4ee3\u7801\u7247\u6bb5\u3001\u4ee3\u7801\u5206\u4eab

      \u60a8\u53ef\u4ee5\u76f4\u63a5\u5728 QEditor \u4e2d\u8fd0\u884c QPython \u811a\u672c\uff0c\u56e0\u6b64\u5728\u79fb\u52a8\u65f6\u8fd9\u662f QPython \u5f00\u53d1\u6700\u65b9\u4fbf\u7684\u65b9\u5f0f\u3002

      "},{"location":"editor-guide/#_2","title":"\u901a\u8fc7\u6d4f\u89c8\u5668\u5f00\u53d1","text":"

      QPython \u6709\u4e00\u4e2a\u5185\u7f6e\u811a\u672c qedit4web.py\uff0c\u5f53\u60a8\u70b9\u51fb\u5f00\u59cb\u6309\u94ae\u5e76\u9009\u62e9\"\u8fd0\u884c\u672c\u5730\u811a\u672c\"\u65f6\u53ef\u4ee5\u770b\u5230\u5b83\u3002

      \u8fd0\u884c\u540e\uff0c\u60a8\u53ef\u4ee5\u770b\u5230\u7ed3\u679c\u3002

      \u7136\u540e\uff0c\u60a8\u53ef\u4ee5\u901a\u8fc7 PC/\u7b14\u8bb0\u672c\u7535\u8111\u7684\u6d4f\u89c8\u5668\u8bbf\u95ee\u8be5\u7f51\u5740\u8fdb\u884c\u5f00\u53d1\uff0c\u5982\u4e0b\u56fe\u6240\u793a\u3002

      \u9009\u62e9\u67d0\u4e2a\u9879\u76ee\u6216\u811a\u672c\u540e\uff0c\u60a8\u53ef\u4ee5\u5f00\u59cb\u5f00\u53d1

      \u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\u7f16\u5199\u6d4f\u89c8\u5668\u4ee3\u7801\uff0c\u7136\u540e\u5728 Android \u624b\u673a\u4e0a\u8fd0\u884c\u3002\u975e\u5e38\u65b9\u4fbf\u3002

      "},{"location":"editor-guide/#_3","title":"\u4ece\u60a8\u7684\u7535\u8111\u5f00\u53d1","text":"

      \u9664\u4e86\u4e0a\u8ff0\u65b9\u6cd5\uff0c\u60a8\u8fd8\u53ef\u4ee5\u7528\u81ea\u5df1\u7684\u65b9\u5f0f\u5f00\u53d1\u811a\u672c\uff0c\u7136\u540e\u901a\u8fc7\u5185\u7f6e\u7684 FTP \u670d\u52a1\u5c06\u5176\u4e0a\u4f20\u5230\u624b\u673a\uff0c\u7528 QPython \u8fd0\u884c\u5b83\u3002

      "},{"location":"external-api/","title":"QPython \u5f00\u653e API","text":"

      QPython \u6709\u4e00\u4e2a\u5f00\u653e\u7684 activity\uff0c\u5141\u8bb8\u60a8\u4ece\u5916\u90e8\u8fd0\u884c qpython\u3002

      MPyAPI \u7684\u5b9a\u4e49\u5982\u4e0b\uff1a

          <activity\n        android:name=\"org.qpython.qpylib.MPyApi\"\n        android:label=\"@string/qpy_run_with_share\"\n        android:screenOrientation=\"user\"\n        android:configChanges=\"orientation|keyboardHidden\"\n        android:exported=\"true\">\n        <intent-filter>\n            <action android:name=\"org.qpython.qpylib.action.MPyApi\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.LAUNCHER\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.VIEW\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.BROWSABLE\" />\n            <data android:scheme=\"http\" />\n            <data android:scheme=\"https\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"text/plain\"/>\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"image/*\"/>\n        </intent-filter>\n    </activity>\n

      \u56e0\u6b64\uff0c\u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\uff1a

      "},{"location":"external-api/#qpython","title":"\u5c06\u5185\u5bb9\u5206\u4eab\u5230 QPython \u7684\u811a\u672c","text":"

      \u60a8\u53ef\u4ee5\u5728\u67d0\u4e2a\u5e94\u7528\u4e2d\u9009\u62e9\u4e00\u4e9b\u5185\u5bb9\uff0c\u7136\u540e\u5206\u4eab\u5230 qpython \u7684\u811a\u672c\uff0c\u4e4b\u540e\u60a8\u53ef\u4ee5\u4f7f\u7528 sys.argv[2] \u5904\u7406\u8fd9\u4e9b\u5185\u5bb9

      \u5728 YouTube \u4e0a\u89c2\u770b\u6f14\u793a\u89c6\u9891

      "},{"location":"external-api/#qpython_1","title":"\u4ece\u60a8\u81ea\u5df1\u7684\u5e94\u7528\u7a0b\u5e8f\u8fd0\u884c QPython \u7684\u811a\u672c","text":"

      \u60a8\u53ef\u4ee5\u901a\u8fc7\u8c03\u7528\u6b64 activity \u5728\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u4e2d\u8c03\u7528 QPython \u6765\u8fd0\u884c\u67d0\u4e9b\u811a\u672c\u6216 Python \u4ee3\u7801\uff0c\u793a\u4f8b\u5982\u4e0b\uff1a

      // \u5c55\u793a\u5982\u4f55\u8c03\u7528 qpython API \u7684\u4ee3\u7801\u793a\u4f8b\nString extPlgPlusName = \"org.qpython.qpy\";          // QPython \u5305\u540d\nIntent intent = new Intent();\nintent.setClassName(extPlgPlusName, \"org.qpython.qpylib.MPyApi\");\nintent.setAction(extPlgPlusName + \".action.MPyApi\");\n\nBundle mBundle = new Bundle();\nmBundle.putString(\"app\", \"myappid\");\nmBundle.putString(\"act\", \"onPyApi\");\nmBundle.putString(\"flag\", \"onQPyExec\"); // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u4efb\u610f\u5b57\u7b26\u4e32\u6807\u5fd7\nmBundle.putString(\"param\", \"\");         // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u53c2\u6570\u5b57\u7b26\u4e32\n\n/*\n* \u6211\u4eec\u5c06\u8fd0\u884c\u7684 Python \u4ee3\u7801\n*/\nString code = \"import androidhelper\\n\" +\n            \"droid = androidhelper.Android()\\n\" +\n            \"line = droid.dialogGetInput()\\n\" +\n            \"s = 'Hello %s' % line.result\\n\" +\n            \"droid.makeToast(s)\\n\"\n\nmBundle.putString(\"pycode\", code);\nintent.putExtras(mBundle);\nstartActivityForResult(intent, SCRIPT_EXEC_PY);\n...\n\n// \u60a8\u53ef\u4ee5\u5728 onActivityResult \u4e2d\u5904\u7406 qpython \u8c03\u7528\u7ed3\u679c\n@Override\nprotected void onActivityResult(int requestCode, int resultCode, Intent data) {\n    if (requestCode == SCRIPT_EXEC_PY) {\n        if (data!=null) {\n            Bundle bundle = data.getExtras();\n            String flag = bundle.getString(\"flag\");\n            String param = bundle.getString(\"param\");\n            String result = bundle.getString(\"result\"); // \u60a8\u7684 Pycode \u751f\u6210\u7684\u7ed3\u679c\n            Toast.makeText(this, \"onQPyExec: return (\"+result+\")\", Toast.LENGTH_SHORT).show();\n        } else {\n            Toast.makeText(this, \"onQPyExec: data is null\", Toast.LENGTH_SHORT).show();\n\n        }\n    }\n}\n

      \u4ece github \u68c0\u51fa\u4e00\u4e2a\u5b8c\u6574\u9879\u76ee

      \u8fd8\u6709\u4e00\u4e2a\u751f\u4ea7\u5e94\u7528\u7a0b\u5e8f - \u9762\u5411 Tasker \u7684 QPython \u63d2\u4ef6

      "},{"location":"featured-courses/","title":"\u7cbe\u9009\u8bfe\u7a0b","text":"

      \u5728\u8fd9\u91cc\uff0c\u6211\u4eec\u4e3a\u60a8\u4ecb\u7ecd\u4e00\u4e9b\u7531\u793e\u533a\u6210\u5458\u521b\u5efa\u7684\u7cbe\u54c1\u8bfe\u7a0b\u3002\u6bcf\u4e00\u95e8\u8bfe\u7a0b\u90fd\u51dd\u805a\u4e86\u521b\u4f5c\u8005\u7684\u5fc3\u8840\u548c\u72ec\u7279\u89c1\u89e3\uff0c\u5e0c\u671b\u80fd\u4e3a\u60a8\u7684\u5b66\u4e60\u4e4b\u65c5\u5e26\u6765\u542f\u53d1\u548c\u5e2e\u52a9\u3002

      "},{"location":"featured-courses/#aipython-aipy","title":"\u4e0eAI\u534f\u4f5c\u7684Python\u7f16\u7a0b\u5165\u95e8 - AIPY\u7f16\u7a0b\u7cfb\u5217","text":"

      \u8bfe\u7a0b\u7b80\u4ecb\uff1a \u4f60\u662f\u5426\u89c9\u5f97\u7f16\u7a0b\u5f88\u96be\uff1f\u5728 AI \u65f6\u4ee3\uff0c\u8fd9\u4e00\u5207\u6b63\u5728\u6539\u53d8\u3002\u672c\u8bfe\u7a0b\u5c06\u5e26\u4f60\u638c\u63e1 Python \u7f16\u7a0b\u57fa\u7840\uff0c\u540c\u65f6\u5b66\u4f1a\u4e0e AI \u9ad8\u6548\u534f\u4f5c\u3002\u72ec\u521b AI \u8f85\u52a9\u6559\u5b66\u6cd5\uff0c\u7cfb\u7edf\u8bb2\u89e3 Python \u6838\u5fc3\u77e5\u8bc6\uff0c\u6559\u4f1a\u4f60\u5982\u4f55\u5411 AI \u7cbe\u786e\u8868\u8fbe\u9700\u6c42\u3001\u534f\u540c\u8c03\u8bd5\u4ee3\u7801\u3002\u901a\u8fc7\u804a\u5929\u673a\u5668\u4eba\u3001\u6570\u636e\u5206\u6790\u52a9\u624b\u7b49\u5b9e\u6218\u9879\u76ee\uff0c\u5efa\u7acb\u4eba\u673a\u534f\u4f5c\u5de5\u4f5c\u6d41\uff0c\u8ba9\u4f60\u5f7b\u5e95\u6253\u7834\u5bf9\u4ee3\u7801\u7684\u754f\u60e7\u3002

      \u521b\u4f5c\u6545\u4e8b\uff1a \u8fd9\u95e8\u8bfe\u662f\u5982\u4f55\u8bde\u751f\u7684\uff1f\u4ee5\u4e0b\u662f\u4f5c\u8005\u7684\u521b\u4f5c\u624b\u8bb0\uff1a

      • \u4e3a\u4ec0\u4e48\u6211\u8981\u5199\u4e00\u5957\u9002\u5408\u521d\u5b66\u8005\u7684 AI \u534f\u52a9 Python \u7f16\u7a0b\u6559\u6750\uff1f - \u521b\u4f5c\u624b\u8bb0\uff08\u4e00\uff09
      • \u4e0e AI \u534f\u4f5c\u7684\"\u62c9\u626f\"\u5f0f Python \u7f16\u7a0b\u8bfe\u7a0b\u7eb2\u9886\u521b\u4f5c - \u521b\u4f5c\u624b\u8bb0\uff08\u4e8c\uff09
      "},{"location":"featured-courses/#_2","title":"\u6b22\u8fce\u53cd\u9988","text":"

      \u5982\u679c\u60a8\u6709\u60f3\u6cd5\u60f3\u8981\u5206\u4eab\uff0c\u6b22\u8fce\u8054\u7cfb\u6211\u4eec\uff01

      • GitHub Issues \u2013 \u63d0\u4ea4\u60a8\u7684\u8bfe\u7a0b\u5efa\u8bae
      • \u4e2d\u6587\u4ea4\u6d41\u793e\u533a \u2013 \u4e0e\u5176\u4ed6\u5b66\u4e60\u8005\u4ea4\u6d41\u5fc3\u5f97
      "},{"location":"getting-started/","title":"QPython\uff1a\u5165\u95e8\u6307\u5357","text":"

      \u672c\u6307\u5357\u5c06\u4ecb\u7ecd QPython \u7684\u529f\u80fd\u5e76\u5e2e\u52a9\u60a8\u5feb\u901f\u5165\u95e8\u3002

      "},{"location":"getting-started/#qpython_1","title":"QPython \u6982\u8ff0","text":"

      \u4e3a\u4ec0\u4e48\u9009\u62e9 QPython\uff1f

      \u667a\u80fd\u624b\u673a\u5df2\u6210\u4e3a\u4eba\u4eec\u5fc5\u5907\u7684\u4fe1\u606f\u548c\u6280\u672f\u52a9\u624b\uff0c\u4e00\u4e2a\u7075\u6d3b\u7684\u89e3\u91ca\u5668\u5f15\u64ce\u53ef\u4ee5\u5e2e\u52a9\u60a8\u9ad8\u6548\u5b8c\u6210\u5927\u90e8\u5206\u5de5\u4f5c\uff0c\u65e0\u9700\u590d\u6742\u7684\u5f00\u53d1\u8fc7\u7a0b\u3002

      QPython \u63d0\u4f9b\u4e86 \u60ca\u4eba\u7684\u5f00\u53d1\u4f53\u9a8c\u2014\u2014\u501f\u52a9\u5b83\u7684\u5e2e\u52a9\uff0c\u60a8\u53ef\u4ee5\u8f7b\u677e\u5b9e\u73b0\u7a0b\u5e8f\uff0c\u65e0\u9700\u590d\u6742\u7684 IDE \u5b89\u88c5\u3001\u7f16\u8bd1\u6216\u6253\u5305\u8fc7\u7a0b\u3002

      "},{"location":"getting-started/#qpython_2","title":"QPython \u7248\u672c","text":"

      \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

      • QPython \u2013 \u7531 QPython \u56e2\u961f\u7ef4\u62a4\u7684\u4e3b\u8981\u7248\u672c\uff0c\u5177\u5907 AI \u529f\u80fd\uff0c\u53ef\u5728 Google Play \u7b49\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d
      • QPython+ \u2013 \u7531\u5f00\u6e90\u8d21\u732e\u8005\u63a8\u51fa\u7684\u793e\u533a\u7248\uff0c\u63d0\u4f9b\u5404\u79cd\u65b0\u7279\u6027
      • QPython Plus \u2013 \u6269\u5c55\u6743\u9650\u7248\u672c\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff09
      "},{"location":"getting-started/#_1","title":"\u4e3b\u8981\u7279\u6027","text":"
      • \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668 - \u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51
      • QSL4A \u96c6\u6210 - \u4f7f\u7528 Python \u63a7\u5236 Android \u786c\u4ef6\u548c API
      • GenAI \u80fd\u529b\u96c6\u6210 - \u652f\u6301\u672c\u5730\u8fd0\u884c\u7684 LLM\u3001OpenAI \u7b49\u5404\u79cd LLM \u5e93\uff0c\u4ee5\u53ca\u53ef\u5728 QPython \u4e0a\u8fdb\u884c Vibe Coding \u5f00\u53d1\u7684 AIPyApp
      • \u6269\u5c55\u5305\u5b89\u88c5 - \u652f\u6301\u901a\u8fc7 QPYPI \u548c pip \u5b89\u88c5\u6269\u5c55\u5305
      • \u5185\u7f6e\u7f16\u8f91\u5668 - \u8bed\u6cd5\u9ad8\u4eae\u548c\u4ee3\u7801\u7f16\u8f91
      • \u591a\u79cd\u8fd0\u884c\u6a21\u5f0f - \u9664\u63a7\u5236\u53f0\u7a0b\u5e8f\u5916\uff0c\u8fd8\u652f\u6301 Android \u539f\u751f UI\uff08\u901a\u8fc7 QSL4A \u63a5\u53e3\uff09\u4ee5\u53ca Pygame / Turtle / Tkinter \u7b49\u8fd0\u884c\u65b9\u5f0f
      "},{"location":"getting-started/#1","title":"1. \u4eea\u8868\u76d8","text":"

      \u5b89\u88c5 QPython \u540e\uff0c\u70b9\u51fb\u5176\u56fe\u6807\u542f\u52a8\u3002\u60a8\u5c06\u770b\u5230\u5e26\u6709 QPython \u6807\u5fd7\u548c\u4ee5\u4e0b\u529f\u80fd\u7684\u4e3b\u4eea\u8868\u76d8\uff1a

      "},{"location":"getting-started/#_2","title":"\u4eea\u8868\u76d8\u529f\u80fd","text":"

      QPython \u4eea\u8868\u76d8\u63d0\u4f9b\u5bf9\u6240\u6709\u4e3b\u8981\u529f\u80fd\u7684\u5feb\u901f\u8bbf\u95ee\uff1a

      • \u7ec8\u7aef \u2014 \u8bbf\u95ee Python \u63a7\u5236\u53f0\u548c shell \u4ee5\u76f4\u63a5\u6267\u884c\u547d\u4ee4
      • Notebook \u2014 \u7528\u4e8e\u6570\u636e\u5206\u6790\u548c\u5b9e\u9a8c\u7684\u4ea4\u4e92\u5f0f Jupyter \u98ce\u683c\u7b14\u8bb0\u672c
      • \u7f16\u8f91\u5668 \u2014 \u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668\uff0c\u5177\u6709\u8bed\u6cd5\u9ad8\u4eae\u529f\u80fd\uff0c\u7528\u4e8e\u7f16\u5199 Python \u811a\u672c
      • \u8d44\u6e90\u7ba1\u7406\u5668 \u2014 \u6d4f\u89c8\u548c\u7ba1\u7406\u60a8\u7684\u6587\u4ef6\u3001\u811a\u672c\u548c\u9879\u76ee
      • QPYPI \u2014 \u5b89\u88c5 Python \u5305\u548c\u6269\u5c55\u3002\u8be6\u89c1 QPYPI \u6307\u5357
      • \u8bbe\u7f6e \u2014 \u914d\u7f6e QPython \u9996\u9009\u9879\u548c\u8fd0\u884c\u9009\u9879
      • \u793e\u533a \u2014 \u8bbf\u95ee QPython \u793e\u533a\u8d44\u6e90\u3001\u8bba\u575b\u548c\u5e2e\u52a9
      • \u8bfe\u7a0b \u2014 \u8bbf\u95ee Python \u7f16\u7a0b\u7684\u5b66\u4e60\u6750\u6599\u548c\u6559\u7a0b

      \u70b9\u51fb\u4efb\u4f55\u56fe\u6807\u4ee5\u8bbf\u95ee\u76f8\u5e94\u7684\u529f\u80fd\u3002

      "},{"location":"getting-started/#2","title":"2. \u7ec8\u7aef\u548c\u7f16\u8f91\u5668","text":""},{"location":"getting-started/#_3","title":"\u7ec8\u7aef","text":"

      \u7ec8\u7aef\u63d0\u4f9b Python \u63a7\u5236\u53f0\uff0c\u652f\u6301\uff1a - \u63a2\u7d22\u5bf9\u8c61\u5c5e\u6027 - \u6d4b\u8bd5\u8bed\u6cd5\u548c\u60f3\u6cd5 - \u76f4\u63a5\u6267\u884c\u547d\u4ee4

      \u4f7f\u7528\u52a0\u53f7\u6309\u94ae\uff081\uff09\u6253\u5f00\u65b0\u7ec8\u7aef\u6807\u7b7e\u9875\uff0c\u901a\u8fc7\u4e0b\u62c9\u83dc\u5355\uff082\uff09\u5207\u6362\uff0c\u5e76\u4f7f\u7528\u5173\u95ed\u6309\u94ae\uff083\uff09\u5173\u95ed\u3002

      "},{"location":"getting-started/#_4","title":"\u7f16\u8f91\u5668","text":"

      \u7f16\u8f91\u5668\u5e95\u90e8\u529f\u80fd\u680f\u5305\u542b\u4ee5\u4e0b\u5de5\u5177\uff08\u4ece\u5de6\u5230\u53f3\uff09\uff1a

      • \u5207\u6362\u5feb\u6377\u8f93\u5165\uff08\u5305\u542b def / if / else / elif / class \u7b49\u5173\u952e\u8bcd\uff09
      • \u9501\u5b9a\uff08\u9632\u6b62\u8bef\u89e6\uff09
      • \u8df3\u8f6c
      • \u4fdd\u5b58
      • \u8fd0\u884c
      • \u641c\u7d22
      • \u64a4\u9500
      • \u91cd\u505a
      • \u53e6\u5b58
      • \u6700\u8fd1\u6587\u4ef6
      • \u4ee3\u7801\u7247\u6bb5

      \u91cd\u8981\u63d0\u793a\uff1a \u4fdd\u5b58\u65f6\u8bf7\u624b\u52a8\u6dfb\u52a0 .py \u6269\u5c55\u540d\uff0c\u56e0\u4e3a\u7f16\u8f91\u5668\u4e0d\u4f1a\u81ea\u52a8\u6dfb\u52a0\u3002

      "},{"location":"getting-started/#3","title":"3. \u8d44\u6e90\u7ba1\u7406\u5668\uff08\u6587\u4ef6\u7ba1\u7406\uff09","text":"

      \u901a\u8fc7 \u8d44\u6e90\u7ba1\u7406\u5668 \u8bbf\u95ee\u811a\u672c\u548c\u9879\u76ee\uff0c\u652f\u6301\u6d4f\u89c8\u3001\u7ec4\u7ec7\u548c\u7ba1\u7406\u6240\u6709 Python \u6587\u4ef6\u3002

      "},{"location":"getting-started/#_5","title":"\u811a\u672c","text":"

      \u811a\u672c\u662f\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/scripts3/ \u4e2d\u7684\u5355\u4e2a Python \u6587\u4ef6\uff08\u9488\u5bf9 Python 3\uff09\u3002

      \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u811a\u672c - \u6253\u5f00 \u2014 \u4f7f\u7528\u5185\u7f6e\u7f16\u8f91\u5668\u7f16\u8f91 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u811a\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u811a\u672c

      "},{"location":"getting-started/#_6","title":"\u9879\u76ee","text":"

      \u9879\u76ee\u662f\u5305\u542b main.py \u4f5c\u4e3a\u5165\u53e3\u70b9\u7684\u76ee\u5f55\u3002\u60a8\u53ef\u4ee5\u5728\u540c\u4e00\u76ee\u5f55\u4e2d\u5305\u542b\u5176\u4ed6\u4f9d\u8d56\u9879\u548c\u8d44\u6e90\u3002\u5c06\u9879\u76ee\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/projects3/ \u4e2d\u3002

      "},{"location":"getting-started/#_7","title":"\u7b14\u8bb0\u672c","text":"

      Jupyter \u98ce\u683c\u7684\u7b14\u8bb0\u672c\u4e5f\u901a\u8fc7\u8d44\u6e90\u7ba1\u7406\u5668\u8fdb\u884c\u7ba1\u7406\uff0c\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/notebooks/ \u4e2d\u3002

      \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u7b14\u8bb0\u672c - \u6253\u5f00 \u2014 \u63a2\u7d22\u7b14\u8bb0\u672c\u5185\u5bb9 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u7b14\u8bb0\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u7b14\u8bb0\u672c

      "},{"location":"getting-started/#4","title":"4. \u5e93","text":"

      \u901a\u8fc7\u5b89\u88c5\u7b2c\u4e09\u65b9\u5e93\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

      "},{"location":"getting-started/#_8","title":"\u5305\u5b89\u88c5\u65b9\u6cd5","text":"

      QPYPI\uff08\u63a8\u8350\uff09

      \u4ece QPYPI \u5b89\u88c5\u9884\u7f16\u8bd1\u7684\u5e93\uff0c\u5305\u62ec numpy\u3001scipy \u7b49\u79d1\u5b66\u5305\u3002

      \u8be6\u89c1 QPYPI \u6307\u5357\u3002

      PIP \u5ba2\u6237\u7aef

      \u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216 QPYPI \u754c\u9762\u5b89\u88c5\u7eaf Python \u5e93\uff1a

      pip install requests\n

      \u9884\u7f16\u8bd1\u5305

      \u5bf9\u4e8e\u5177\u6709 C/C++/Rust \u4f9d\u8d56\u7684\u5305\uff0c\u4f7f\u7528 QPython \u7684\u9884\u7f16\u8bd1\u5305\uff1a

      pip install numpy-qpython\npip install scipy-aipy\n

      \u8be6\u89c1 QPYPI \u6307\u5357 \u83b7\u53d6\u53ef\u7528\u5305\u7684\u5b8c\u6574\u5217\u8868\u3002

      \u624b\u52a8\u5b89\u88c5

      \u60a8\u4e5f\u53ef\u4ee5\u5c06\u5e93\u590d\u5236\u5230 /storage/emulated/0/Android/data/org.qpython.qpy/files/lib/python3.12/site-packages/\u3002

      "},{"location":"getting-started/#5","title":"5. \u8fd0\u884c\u6a21\u5f0f","text":"

      QPython \u652f\u6301\u591a\u79cd\u8fd0\u884c\u6a21\u5f0f\u4ee5\u6ee1\u8db3\u4e0d\u540c\u7684\u7528\u4f8b\uff1a

      "},{"location":"getting-started/#_9","title":"\u63a7\u5236\u53f0\u6a21\u5f0f","text":"

      \u5e38\u89c4 Python \u811a\u672c\u7684\u9ed8\u8ba4\u6a21\u5f0f\u3002

      "},{"location":"getting-started/#qsl4a","title":"QSL4A \u6a21\u5f0f","text":"

      \u901a\u8fc7 QSL4A \u5e93\u8c03\u7528 Android API \u7684\u811a\u672c\u3002

      import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello Android!')\n

      \u8be6\u89c1 QSL4A \u6587\u6863 \u83b7\u53d6\u5b8c\u6574\u7684 API \u53c2\u8003\u3002

      "},{"location":"getting-started/#webapp","title":"WebApp \u6a21\u5f0f","text":"

      \u4f7f\u7528\u540e\u7aef\u670d\u52a1\u5668\u521b\u5efa\u57fa\u4e8e Web \u7684\u5e94\u7528\u7a0b\u5e8f\u3002\u9700\u5728\u811a\u672c\u5f00\u5934\u6dfb\u52a0\u4ee5\u4e0b\u4e24\u884c headers\uff1a

      #qpy:webapp:<\u9879\u76ee\u540d>\n#qpy://localhost:<web\u670d\u52a1\u4fa6\u542c\u7684\u7aef\u53e3>/<\u9ed8\u8ba4\u4e3b\u8def\u5f84>\n

      \u4f8b\u5982\uff1a

      #qpy:webapp:Hello QPython\n#qpy://localhost:8080/hello\n\nfrom bottle import route, run, Bottle\n\napp = Bottle()\n\n@route('/hello')\ndef hello():\n    return '<h1>Hello from QPython!</h1>'\n\nrun(app, host='localhost', port=8080)\n
      "},{"location":"getting-started/#q","title":"Q \u6a21\u5f0f\uff08\u65e0\u63a7\u5236\u53f0\u6a21\u5f0f\uff09","text":"

      \u9759\u9ed8\u6a21\u5f0f\u8fd0\u884c\u811a\u672c\uff0c\u4e0d\u663e\u793a\u63a7\u5236\u53f0\u3002\u9700\u5728\u811a\u672c\u5f00\u5934\u6dfb\u52a0 header\uff1a

      #qpy:quiet\n\nimport time\n\nwhile True:\n    # \u60a8\u7684\u540e\u53f0\u4efb\u52a1\n    time.sleep(60)\n
      \u5982\u679c\u9700\u8981\u8fd0\u884c\u5e26 GUI \u7684 QSL4A \u7a0b\u5e8f\u4e14\u4e0d\u5e0c\u671b\u663e\u793a\u63a7\u5236\u53f0\u4fe1\u606f\uff0c\u63a8\u8350\u4f7f\u7528\u6b64\u6a21\u5f0f\u3002

      "},{"location":"getting-started/#6","title":"6. \u793e\u533a\u4e0e\u652f\u6301","text":"

      \u8bbf\u95ee QPython.org \u83b7\u53d6\u6587\u6863\u3001\u7528\u6237\u793e\u533a\u53ca\u5e2e\u52a9\u95ee\u7b54\u3002

      \u793e\u533a\u94fe\u63a5\uff1a - Facebook \u7fa4\u7ec4 - GitHub - \u95ee\u9898\u53cd\u9988

      \u4e0b\u4e00\u6b65\uff1a - \u5c1d\u8bd5 Hello World \u6559\u7a0b - \u63a2\u7d22 QSL4A API \u4ee5\u96c6\u6210 Android - \u4e86\u89e3 QPython \u7248\u672c

      "},{"location":"getting-started/#_10","title":"\u89c6\u9891\u4ecb\u7ecd","text":""},{"location":"getting-started/#_11","title":"\u4e0b\u4e00\u6b65","text":"

      \u5982\u679c\u60a8\u5df2\u7ecf\u521d\u6b65\u4e86\u89e3\u4e86 QPython \u7684\u529f\u80fd\uff0c\u6b22\u8fce\u5f00\u59cb\u4f53\u9a8c\u7f16\u7a0b\u7684\u4e50\u8da3\uff01\u8bd5\u8bd5 Hello World \u6559\u7a0b \u8fc8\u51fa\u60a8\u7684\u7b2c\u4e00\u6b65\u3002

      "},{"location":"qpypi-guide/","title":"QPYPI","text":"

      \u60a8\u53ef\u4ee5\u901a\u8fc7\u5b89\u88c5\u5305\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

      "},{"location":"qpypi-guide/#_1","title":"\u5305\u5b89\u88c5\u652f\u6301","text":""},{"location":"qpypi-guide/#python","title":"\u7eaf Python \u5305","text":"

      QPython \u652f\u6301\u4f7f\u7528\u7eaf Python \u5f00\u53d1\u7684 Python \u5305\u3002\u60a8\u53ef\u4ee5\u76f4\u63a5\u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216\u4eea\u8868\u76d8\u4e0a\u7684 QPYPI \u4f7f\u7528 pip install \u5b89\u88c5\u8fd9\u4e9b\u5305\u3002

      "},{"location":"qpypi-guide/#_2","title":"\u9884\u7f16\u8bd1\u5305","text":"

      \u5982\u679c\u67d0\u4e9b\u5305\uff08\u6216\u5b83\u4eec\u7684\u4f9d\u8d56\uff09\u662f\u7528 Rust/C/C++ \u5f00\u53d1\u7684\uff0cQPython \u65e0\u6cd5\u76f4\u63a5\u652f\u6301\u5b83\u4eec\uff0c\u56e0\u4e3a QPython \u4e0a\u6ca1\u6709\u7f16\u8bd1\u5668\u5de5\u5177\u94fe\u652f\u6301\u3002\u4f46\u662f\uff0cQPython \u56e2\u961f\u5df2\u7ecf\u9884\u7f16\u8bd1\u4e86\u4e00\u4e9b\u5e38\u7528\u5305\uff0c\u5e76\u5728 QPython \u7684 QPYPI/Extensions \u4e2d\u53d1\u5e03\uff0c\u4f9b\u7528\u6237\u8f7b\u677e\u5b89\u88c5\u3002

      "},{"location":"qpypi-guide/#_3","title":"\u5b89\u88c5\u9884\u7f16\u8bd1\u5305","text":"

      \u60a8\u53ef\u4ee5\u901a\u8fc7\u4ee5\u4e0b\u65b9\u5f0f\u5b89\u88c5\u9884\u7f16\u8bd1\u5305\uff1a

      1. \u901a\u8fc7 QPython \u5e94\u7528\uff1a\u76f4\u63a5\u4ece QPython \u5e94\u7528\u5185\u7684 QPYPI \u6216 Extensions \u5b89\u88c5
      2. \u901a\u8fc7 PyPI\uff1a\u8bbf\u95ee https://pypi.org/user/qpythonx/ \u67e5\u770b\u53ef\u7528\u7684\u5305
      3. \u901a\u8fc7 pip \u547d\u4ee4\uff1a
      4. pip install xxx-qpython - \u5e26 -qpython \u540e\u7f00\u7684\u5305
      5. pip install xxx-aipy - \u5e26 -aipy \u540e\u7f00\u7684\u5305\uff08\u901a\u5e38\u662f AI/ML \u76f8\u5173\u7684\u5305\uff09

      \u6ce8\u610f\uff1a\u6211\u4eec\u901a\u5e38\u6839\u636e\u5305\u7684\u9884\u671f\u7528\u9014\u6dfb\u52a0\u8fd9\u4e9b\u540e\u7f00\u4e4b\u4e00\u3002

      "},{"location":"qpypi-guide/#_4","title":"\u8bf7\u6c42\u65b0\u5305","text":"

      \u5982\u679c\u60a8\u9700\u8981\u5f53\u524d\u4e0d\u652f\u6301\u7684\u5305\uff1a

      • \u5728 qpython.org \u9879\u76ee \u4e2d\u63d0\u51fa\u95ee\u9898
      • QPython \u56e2\u961f\u5c06\u8003\u8651\u9884\u7f16\u8bd1\u5e76\u5c06\u5176\u6dfb\u52a0\u5230\u4ed3\u5e93\u4e2d

      \u83b7\u53d6\u66f4\u591a\u5e2e\u52a9\u548c\u53c2\u4e0e\u793e\u533a\u7684\u65b9\u5f0f\uff0c\u8bf7\u53c2\u9605 \u793e\u533a\u4e0e\u53cd\u9988 \u90e8\u5206\u3002

      \u6ce8\u610f\uff1a\u7531\u4e8e\u4e0d\u540c\u7684\u8ba1\u7b97\u673a\u67b6\u6784\uff0c\u6211\u4eec\u65e0\u6cd5\u4fdd\u8bc1 QPYPI \u5305\u542b PyPI \u4e0a\u7684\u6240\u6709\u5305\u3002

      "},{"location":"qpython-x/","title":"QPython \u7248\u672c","text":"

      QPython \u662f Android \u7684 Python \u5f15\u64ce\u3002\u5b83\u5305\u542b\u4ee4\u4eba\u60ca\u53f9\u7684\u529f\u80fd\uff0c\u5982 Python \u89e3\u91ca\u5668\u3001\u8fd0\u884c\u73af\u5883\u3001\u7f16\u8f91\u5668\u3001QPYI \u548c\u96c6\u6210\u7684 SL4A\u3002\u5b83\u8ba9\u60a8\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 Android \u4e0a\u4f7f\u7528 Python\u3002\u800c\u4e14\u5b83\u662f\u514d\u8d39\u7684\u3002

      QPython \u5df2\u7ecf\u5728\u5168\u7403\u62e5\u6709\u6570\u767e\u4e07\u7528\u6237\uff0c\u4e5f\u662f\u4e00\u4e2a\u5f00\u6e90\u9879\u76ee\u3002

      \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

      "},{"location":"qpython-x/#qpython_1","title":"QPython","text":"

      \u6807\u51c6\u7248\uff1a\u9488\u5bf9 AI \u6027\u80fd\u548c\u901a\u7528\u5e94\u7528\u5546\u5e97\u517c\u5bb9\u6027\u4f18\u5316

      \u4e3b\u8981\u7248\u672c\uff0c\u53ef\u5728 Google Play \u548c\u5176\u4ed6\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002\u6b64\u7248\u672c\u4e13\u6ce8\u4e8e AI \u529f\u80fd\uff0c\u4f7f AI \u65f6\u4ee3\u7528\u6237\u66f4\u5bb9\u6613\u5b66\u4e60\u548c\u4f7f\u7528 Python\u3002

      \u4e3b\u8981\u7279\u6027\uff1a - AI \u9a71\u52a8\u7684\u7f16\u7801\u8f85\u52a9\u548c\u5b66\u4e60\u5de5\u5177 - \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668\uff1a\u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51 - \u652f\u6301\u591a\u79cd\u9879\u76ee\u7c7b\u578b\uff1a\u63a7\u5236\u53f0\u3001SL4A\u3001WebApp - \u65b9\u4fbf\u7684\u4e8c\u7ef4\u7801\u8bfb\u53d6\u5668\uff0c\u7528\u4e8e\u5c06\u4ee3\u7801\u4f20\u8f93\u5230\u624b\u673a - QPYPI \u548c\u81ea\u5b9a\u4e49\u4ed3\u5e93\uff0c\u7528\u4e8e\u9884\u7f16\u8bd1 wheel \u5305 -\u6613\u4e8e\u4f7f\u7528\u7684\u8bed\u6cd5\u9ad8\u4eae\u7f16\u8f91\u5668 - \u5b8c\u5584\u7684\u6587\u6863\u548c\u793e\u533a\u652f\u6301

      \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

      \u4e0b\u8f7d\uff1a \u53ef\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

      "},{"location":"qpython-x/#qpython_2","title":"QPython+","text":"

      \u793e\u533a\u7248\uff1a\u516c\u5f00\u652f\u6301\u5404\u79cd\u793e\u533a\u9a71\u52a8\u7684\u529f\u80fd\uff1b\u53ef\u5728\u90e8\u5206\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

      \u793e\u533a\u5f00\u6e90\u7248\u672c\uff08\u6b63\u5728\u89c4\u5212\u548c\u51c6\u5907\u4e2d\uff09\u3002\u6b64\u7248\u672c\u4e13\u4e3a\u60f3\u8981\u53c2\u4e0e QPython \u9879\u76ee\u5f00\u53d1\u7684\u8d21\u732e\u8005\u800c\u8bbe\u8ba1\uff0c\u652f\u6301\u9488\u5bf9\u4e0d\u540c\u5236\u9020\u5546\u7684\u5b9a\u5236\u3002

      \u4e3b\u8981\u7279\u6027\uff1a - \u793e\u533a\u9a71\u52a8\u5f00\u53d1 - \u652f\u6301\u4f9b\u5e94\u5546\u5b9a\u5236 - \u66f4\u7075\u6d3b\u7684\u914d\u7f6e\u9009\u9879 - \u5f00\u653e\u4f9b\u8d21\u732e\u8005\u52a0\u5165\u5f00\u53d1

      \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

      \u4e0b\u8f7d\uff1a \u5c06\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

      \u6ce8\u610f\uff1a \u6b64\u7248\u672c\u76ee\u524d\u6b63\u5728\u89c4\u5212\u51c6\u5907\u4e2d\u3002\u8bf7\u5173\u6ce8\u66f4\u65b0\uff01

      "},{"location":"qpython-x/#qpython-plus","title":"QPython Plus","text":"

      QPython+ \u5b8c\u5168\u8bbf\u95ee\u7248\uff1a\u6388\u4e88\u8c03\u7528\u6240\u6709 Android \u63a5\u53e3\u7684\u5b8c\u6574\u6743\u9650\u3002\u4e0b\u8f7d\u94fe\u63a5\u4ec5\u901a\u8fc7\u5b98\u65b9\u4e91\u76d8\u63d0\u4f9b\u3002

      \u5177\u6709\u6269\u5c55\u6743\u9650\u7684\u7279\u6b8a\u7248\u672c\uff0c\u63d0\u4f9b\u5bf9\u8bbe\u5907\u7684\u6700\u5927\u63a7\u5236\u3002\u7531\u4e8e\u5176\u654f\u611f\u7684\u6743\u9650\u8981\u6c42\uff0c\u6b64\u7248\u672c\u4e0d\u4f1a\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u53d1\u5e03\u3002

      \u4e3b\u8981\u7279\u6027\uff1a - \u5b8c\u6574\u7684 SL4A API \u8bbf\u95ee\uff0c\u5305\u62ec\u654f\u611f\u529f\u80fd - SMS/\u901a\u8bdd\u63a7\u5236 API - \u9ad8\u7ea7\u7cfb\u7edf\u96c6\u6210 - \u6700\u5927\u7684\u8bbe\u5907\u63a7\u5236\u80fd\u529b

      \u6743\u9650\uff1a \u9700\u8981\u5e7f\u6cdb\u7684\u6743\u9650\uff0c\u5305\u62ec\uff1a - \u84dd\u7259 - \u4f4d\u7f6e\uff08GPS\uff09 - \u8bfb\u53d6/\u53d1\u9001\u77ed\u4fe1 - \u6253\u7535\u8bdd - \u76f8\u673a\u548c\u9ea6\u514b\u98ce - \u7cfb\u7edf\u8bbe\u7f6e - \u4ee5\u53ca\u5176\u4ed6\u654f\u611f\u6743\u9650

      \u4e0b\u8f7d\uff1a \u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\u3002\u4ec5\u901a\u8fc7\u7279\u6b8a\u6e20\u9053\u5206\u53d1\u3002

      \u91cd\u8981\u63d0\u793a\uff1a QPython \u4e0d\u4f1a\u5728\u540e\u53f0\u672a\u7ecf\u60a8\u77e5\u6089\u4f7f\u7528\u8fd9\u4e9b\u6743\u9650\u3002\u5982\u679c\u4f7f\u7528 SL4A API \u65f6\u51fa\u73b0\u5f02\u5e38\uff0c\u8bf7\u68c0\u67e5\u7cfb\u7edf\u8bbe\u7f6e\u4e2d\u662f\u5426\u5df2\u542f\u7528\u76f8\u5173\u6743\u9650\u3002

      "},{"location":"tutorial-hello-world/","title":"\u7f16\u5199\"Hello World\"","text":""},{"location":"tutorial-hello-world/#hello-world_1","title":"Hello world","text":"

      \u597d\u7684\uff0c\u5728\u60a8\u5bf9 QPython \u6709\u4e86\u4e00\u5b9a\u7684\u4e86\u89e3\u4e4b\u540e\uff0c\u8ba9\u6211\u4eec\u5728 QPython \u4e2d\u521b\u5efa\u6211\u4eec\u7684\u7b2c\u4e00\u4e2a\u7a0b\u5e8f\u3002\u663e\u7136\uff0c\u5b83\u5c06\u662f helloworld.py\u3002;)

      \u542f\u52a8 QPython\uff0c\u6253\u5f00\u7f16\u8f91\u5668\u5e76\u8f93\u5165\u4ee5\u4e0b\u4ee3\u7801\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello, QPYTHON!')\n

      \u6beb\u65e0\u7591\u95ee\uff0c\u5b83\u4e0e\u5176\u4ed6\u4efb\u4f55 hello-world \u7a0b\u5e8f\u5e76\u65e0\u4e0d\u540c\u3002\u6267\u884c\u65f6\uff0c\u5b83\u53ea\u662f\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u5f39\u51fa\u6d88\u606f\uff08\u89c1\u9876\u90e8\u622a\u56fe\uff09\u3002\u65e0\u8bba\u5982\u4f55\uff0c\u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684 QPython \u7a0b\u5e8f\u793a\u4f8b\u3002

      "},{"location":"tutorial-hello-world/#_1","title":"\u4ee3\u7801\u7406\u89e3","text":"

      \u5b83\u4ee5 import androidhelper \u5f00\u5934\u2014\u2014\u8fd9\u662f QPython \u4e2d\u6700\u6709\u7528\u7684\u6a21\u5757\uff0c\u5b83\u5c01\u88c5\u4e86 Python \u4e2d\u53ef\u7528\u7684\u51e0\u4e4e\u6240\u6709\u4e0e Android \u7684\u63a5\u53e3\u3002\u4efb\u4f55\u5728 QPython \u4e2d\u5f00\u53d1\u7684\u811a\u672c\u90fd\u4ee5\u8fd9\u4e2a\u8bed\u53e5\u5f00\u5934\uff08\u81f3\u5c11\u5982\u679c\u5b83\u58f0\u79f0\u8981\u4e0e\u7528\u6237\u901a\u4fe1\u7684\u8bdd\uff09\u3002\u5728\u6b64\u5904\u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u5e93 \u548c import \u8bed\u53e5 \u7684\u5185\u5bb9\u3002

      \u63a5\u4e0b\u6765\u6211\u4eec\u521b\u5efa\u4e00\u4e2a droid \u5bf9\u8c61\uff08\u5b9e\u9645\u4e0a\u662f\u4e00\u4e2a\u7c7b\uff09\uff0c\u5b83\u5bf9\u4e8e\u8c03\u7528 RPC \u51fd\u6570\u4ee5\u4e0e Android \u901a\u4fe1\u662f\u5fc5\u8981\u7684\u3002

      \u6211\u4eec\u4ee3\u7801\u7684\u6700\u540e\u4e00\u884c\u8c03\u7528\u4e86\u8fd9\u6837\u7684\u51fd\u6570\uff0cdroid.makeToast()\uff0c\u5b83\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u4e00\u4e2a\u5c0f\u7684\u5f39\u51fa\u6d88\u606f\uff08\"toast\"\uff09\u3002

      \u597d\u7684\uff0c\u8ba9\u6211\u4eec\u6dfb\u52a0\u4e00\u4e9b\u66f4\u591a\u7684\u529f\u80fd\u3002\u8ba9\u5b83\u8be2\u95ee\u7528\u6237\u540d\u5e76\u5411\u7528\u6237\u6253\u62db\u547c\u3002

      "},{"location":"tutorial-hello-world/#_2","title":"\u66f4\u591a\u793a\u4f8b","text":"

      \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 dialogGetInput \u8c03\u7528\u663e\u793a\u4e00\u4e2a\u5e26\u6709\u6807\u9898\u3001\u63d0\u793a\u3001\u7f16\u8f91\u5b57\u6bb5\u548c \u786e\u5b9a \u548c \u53d6\u6d88 \u6309\u94ae\u7684\u7b80\u5355\u5bf9\u8bdd\u6846\u3002\u7528\u4ee5\u4e0b\u4ee3\u7801\u66ff\u6362\u60a8\u7684\u6700\u540e\u4e00\u884c\u4ee3\u7801\u5e76\u5c06\u5176\u4fdd\u5b58\u4e3a hello1.py\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\n

      \u597d\u7684\uff0c\u6211\u8ba4\u4e3a\u5b83\u5e94\u8be5\u8fd4\u56de\u4efb\u4f55\u54cd\u5e94\uff0c\u4efb\u4f55\u7528\u6237\u53cd\u5e94\u3002\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u6211\u5199 respond = ...\u3002\u4f46\u8fd9\u4e2a\u8c03\u7528\u5b9e\u9645\u4e0a\u8fd4\u56de\u4ec0\u4e48\uff1f\u8ba9\u6211\u4eec\u68c0\u67e5\u4e00\u4e0b\u3002\u53ea\u9700\u5728\u6700\u540e\u4e00\u884c\u540e\u6dfb\u52a0 print \u8bed\u53e5\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\n

      \u7136\u540e\u4fdd\u5b58\u5e76\u8fd0\u884c\u5b83...

      \u54ce\u5440\uff01\u6ca1\u6709\u6253\u5370\uff1f\u522b\u62c5\u5fc3\u3002\u53ea\u9700\u62c9\u4e0b\u901a\u77e5\u680f\uff0c\u60a8\u5c31\u4f1a\u770b\u5230\"QPython Program Output: hello1.py\"\u2014\u2014\u70b9\u51fb\u5b83\uff01

      \u5982\u60a8\u6240\u89c1\uff0cdroid.dialogGetInput() \u8fd4\u56de\u4e00\u4e2a\u5305\u542b\u4e09\u4e2a\u5b57\u6bb5\u7684 JSON \u5bf9\u8c61\u3002\u6211\u4eec\u53ea\u9700\u8981\u4e00\u4e2a\u2014\u2014result\uff0c\u5176\u4e2d\u5305\u542b\u7528\u6237\u5b9e\u9645\u8f93\u5165\u7684\u5185\u5bb9\u3002

      \u8ba9\u6211\u4eec\u6dfb\u52a0\u811a\u672c\u7684\u53cd\u5e94\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nmessage = f'Hello, {respond.result}!'\ndroid.makeToast(message)\n

      \u6700\u540e\u4e24\u884c\uff081\uff09\u683c\u5f0f\u5316\u6d88\u606f\uff0c\uff082\uff09\u4ee5 toast \u5f62\u5f0f\u5411\u7528\u6237\u663e\u793a\u6d88\u606f\u3002\u5982\u679c\u60a8\u4ecd\u7136\u4e0d\u77e5\u9053 f-string \u662f\u4ec0\u4e48\u610f\u601d\uff0c\u8bf7\u53c2\u9605 Python \u6587\u6863\u3002

      \u54c7\uff01\u5b83\u5de5\u4f5c\u4e86\uff01;)

      \u73b0\u5728\u6211\u8981\u5728\u90a3\u91cc\u6dfb\u52a0\u4e00\u4e9b\u903b\u8f91\u3002\u60f3\u4e00\u60f3\uff1a\u5982\u679c\u7528\u6237\u70b9\u51fb \u53d6\u6d88 \u6309\u94ae\uff0c\u6216\u8005\u70b9\u51fb \u786e\u5b9a \u4f46\u5c06\u8f93\u5165\u5b57\u6bb5\u7559\u7a7a\uff0c\u4f1a\u53d1\u751f\u4ec0\u4e48\uff1f

      \u60a8\u53ef\u4ee5\u73a9\u8fd9\u4e2a\u7a0b\u5e8f\uff0c\u68c0\u67e5 respond \u53d8\u91cf\u5728\u6bcf\u79cd\u60c5\u51b5\u4e0b\u5305\u542b\u4ec0\u4e48\u3002

      \u9996\u5148\uff0c\u6211\u60f3\u5c06\u7528\u6237\u8f93\u5165\u7684\u6587\u672c\u653e\u5165\u4e00\u4e2a\u5355\u72ec\u7684\u53d8\u91cf\u4e2d\uff1aname = respond.result\u3002\u7136\u540e\u6211\u68c0\u67e5\u5b83\uff0c\u5982\u679c\u5b83\u5305\u542b\u4efb\u4f55\u771f\u5b9e\u6587\u672c\uff0c\u5b83\u5c06\u88ab\u89c6\u4e3a\u540d\u79f0\u5e76\u7528\u4e8e\u95ee\u5019\u3002\u5426\u5219\uff0c\u5c06\u663e\u793a\u53e6\u4e00\u6761\u6d88\u606f\u3002\u5c06\u7b2c\u4e94\u884c message = f'Hello, {respond.result}!' \u66ff\u6362\u4e3a\u4ee5\u4e0b\u4ee3\u7801\uff1a

      name = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\n

      \u4f7f\u7528\u5de5\u5177\u680f\u4e0a\u7684 < \u548c > \u6309\u94ae\u6765\u7f29\u8fdb/\u53d6\u6d88\u7f29\u8fdb if \u8bed\u53e5\u4e2d\u7684\u884c\uff08\u6216\u8005\u53ea\u9700\u4f7f\u7528\u7a7a\u683c/\u9000\u683c\u952e\uff09\u3002\u60a8\u53ef\u4ee5\u5728 \u6b64\u5904 \u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u7f29\u8fdb\u7684\u5185\u5bb9\uff1bif \u8bed\u53e5\u5728 \u6b64\u5904 \u63cf\u8ff0\u3002

      \u9996\u5148\uff0c\u6211\u4eec\u5c06\u7528\u6237\u8f93\u5165\u653e\u5165 name \u53d8\u91cf\u3002\u7136\u540e\u6211\u4eec\u68c0\u67e5 name \u662f\u5426\u5305\u542b\u4efb\u4f55\u5185\u5bb9\uff1f\u5982\u679c\u7528\u6237\u7559\u7a7a\u884c\u5e76\u70b9\u51fb \u786e\u5b9a\uff0c\u8fd4\u56de\u503c\u662f\u7a7a\u5b57\u7b26\u4e32 ''\u3002\u5982\u679c\u6309\u4e0b\u4e86 \u53d6\u6d88 \u6309\u94ae\uff0c\u8fd4\u56de\u503c\u662f None\u3002\u5728 if \u8bed\u53e5\u4e2d\uff0c\u4e24\u8005\u90fd\u88ab\u89c6\u4e3a\u5047\u3002\u56e0\u6b64\uff0c\u53ea\u6709\u5f53 name \u5305\u542b\u4efb\u4f55\u6709\u610f\u4e49\u7684\u5185\u5bb9\u65f6\uff0cthen \u8bed\u53e5\u624d\u4f1a\u6267\u884c\uff0c\u5e76\u663e\u793a\u95ee\u5019\u8bed\"Hello, ...!\"\u3002\u5982\u679c\u8f93\u5165\u4e3a\u7a7a\uff0c\u7528\u6237\u5c06\u770b\u5230\"Hey! And you're not very polite, %Username%!\"\u6d88\u606f\u3002

      \u597d\u7684\uff0c\u8fd9\u662f\u6574\u4e2a\u7a0b\u5e8f\uff1a

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nname = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\ndroid.makeToast(message)\n
      "},{"location":"tutorial-hello-world/#_3","title":"\u8fd0\u884c\u6548\u679c","text":""},{"location":"tutorial-hello-world/#_4","title":"\u4e0b\u4e00\u6b65","text":"

      \u5bf9\u4e8e Python \u65b0\u7528\u6237\uff0c\u63a8\u8350\u5b66\u4e60 Python \u8bed\u6cd5\u5b9e\u8df5 \u8bfe\u7a0b\u6765\u8fdb\u4e00\u6b65\u5b66\u4e60 Python\uff0c\u6216\u8005\u5728 QPython \u7cbe\u9009\u8bfe\u7a0b \u4e2d\u5bfb\u627e\u60f3\u8981\u5b66\u4e60\u7684\u5185\u5bb9\u3002

      "},{"location":"whats-new/","title":"\u66f4\u65b0\u65e5\u5fd7","text":""},{"location":"whats-new/#v392-v393","title":"v3.9.2 / v3.9.3","text":"
      • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
      • \u7f16\u8f91\u5668\u91cd\u5927\u66f4\u65b0\uff0c\u5e26\u6765\u66f4\u6d41\u7545\u7684\u7f16\u8f91\u4f53\u9a8c
      • \u5176\u4ed6\u5404\u79cd\u5c0f\u6539\u8fdb
      "},{"location":"whats-new/#v391","title":"v3.9.1","text":"
      • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
      • \u6269\u5c55\u5305\u73b0\u5728\u652f\u6301 MCP
      • \u9519\u8bef\u4fee\u590d
      "},{"location":"whats-new/#v390","title":"v3.9.0","text":"
      • SDK \u5347\u7ea7\uff0c\u6574\u5408\u6700\u65b0\u7684 Android \u529f\u80fd
      • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
      • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
      • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
      "},{"location":"whats-new/#v3811","title":"v3.8.11","text":"
      • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
      • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
      • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
      "},{"location":"whats-new/#v3810","title":"v3.8.10","text":"
      • \u5185\u7f6e Ollama \u5347\u7ea7\uff1a\u73b0\u5728\u60a8\u53ef\u4ee5\u5728 QPython \u4e2d\u8f7b\u677e\u672c\u5730\u8fd0\u884c Qwen3 / Gemma3 \u6a21\u578b\uff01
      • \u6dfb\u52a0\u4e86\u5f3a\u5927\u7684 MCP \u5e93\uff1a\u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 mcp \u5e93\uff0c\u8ba9\u60a8\u968f\u65f6\u968f\u5730\u643a\u5e26\u5f3a\u5927\u7684 MCP \u529f\u80fd\uff01
      "},{"location":"whats-new/#v389","title":"v3.8.9","text":"

      \u91cd\u5927\u66f4\u65b0\uff01AI \u7f16\u7a0b\u5b8c\u5168\u96c6\u6210\u5230 QPython\uff0c\u8ba9\u60a8\u7684\u7f16\u7a0b\u66f4\u8f7b\u677e\uff01

      • \u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u652f\u6301\uff1a\u65b0\u652f\u6301 AIPyApp\uff0c\u5728 QPython \u4e2d\u5b9e\u73b0\u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u3002\u76ee\u524d\u5904\u4e8e\u6d4b\u8bd5\u9636\u6bb5 - \u52a0\u5165\u6211\u4eec\u7684\u793e\u533a\u83b7\u53d6\u4f7f\u7528\u8bf4\u660e
      • \u65b0 QSL4A \u529f\u80fd\uff1a\u6dfb\u52a0 notebookOpen \u51fd\u6570\uff0c\u652f\u6301\u81ea\u7136\u8bed\u8a00\u63a7\u5236\u6253\u5f00 Notebook \u6587\u4ef6
      • \u5185\u7f6e\u7f16\u8f91\u5668\u5347\u7ea7\uff1a\u589e\u5f3a\u7f16\u8f91\u5668\u529f\u80fd\uff0c\u652f\u6301\u6253\u5f00\u548c\u6d4f\u89c8\u5404\u79cd\u6587\u672c\u6587\u4ef6
      • \u4fbf\u6377\u7684\u6587\u4ef6\u7ba1\u7406\uff1a\u5728\u6587\u4ef6\u7ba1\u7406\u5668\u4e2d\u6dfb\u52a0\u5185\u90e8\u5b58\u50a8\u5165\u53e3\uff0c\u5feb\u901f\u8bbf\u95ee\u60a8\u7684\u6587\u4ef6
      "},{"location":"whats-new/#v388","title":"v3.8.8","text":"
      • \u6587\u4ef6\u8bbf\u95ee\u6743\u9650\u63a7\u5236\u7684\u91cd\u8981\u6539\u8fdb\uff0c\u5141\u8bb8\u7528\u6237\u7075\u6d3b\u5730\u901a\u8fc7 QPython \u7f16\u7a0b\u542f\u7528\u6216\u7981\u7528\u5916\u90e8\u5b58\u50a8\u6587\u4ef6\u7684\u8bbf\u95ee
      • SDK \u5347\u7ea7\uff0c\u589e\u5f3a\u4e86\u5bf9\u65b0\u7248 Android \u7684\u652f\u6301\u548c\u517c\u5bb9\u6027
      • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Anthropic \u548c Google GenAI \u5e93
      "},{"location":"whats-new/#v387","title":"v3.8.7","text":"
      • \u5728\u73b0\u6709 Tkinter \u652f\u6301\u57fa\u7840\u4e0a\uff0c\u5728 Extensions -> Tools \u4e2d\u6dfb\u52a0\u4e86\u4f7f\u7528 Turtle \u7ed8\u5236\u54c6\u5566A\u68a6\u7684\u793a\u4f8b\u4ee3\u7801
      • \u4f18\u5316\u4e86\u624b\u673a\u6743\u9650\u83b7\u53d6\u6d41\u7a0b\uff0c\u63d0\u5347\u7528\u6237\u4f53\u9a8c\u548c\u64cd\u4f5c\u4fbf\u5229\u6027
      • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Google Gen AI \u5e93\uff0c\u65b9\u4fbf\u8bbf\u95ee Gemini Developer API \u548c Vertex AI
      "},{"location":"whats-new/#v386","title":"v3.8.6","text":"
      • Tkinter \u652f\u6301\uff1a\u73b0\u5728\u652f\u6301 Tkinter \u5e93\uff0c\u53ef\u901a\u8fc7 XServer \u8bbf\u95ee\u3002\u8bf7\u8bbf\u95ee www.qpython.org \u7684\u4e91\u76d8\"Extra\"\u94fe\u63a5\u4e0b\u8f7d\u6240\u9700\u6587\u4ef6
      • \u5b58\u50a8\u6743\u9650\u66f4\u65b0\uff1a\u4e3a\u6539\u5584\u7528\u6237\u4f53\u9a8c\uff0c\u6211\u4eec\u6dfb\u52a0\u4e86\u8bfb\u53d6\u624b\u673a\u5b58\u50a8\u7684\u6743\u9650\uff0c\u7528\u4e8e\u8bbf\u95ee\u5b58\u50a8\u5728\u5176\u4ed6\u76ee\u5f55\u4e2d\u7684 Python \u7a0b\u5e8f

      \u6b64\u66f4\u65b0\u540e\uff0cQPython \u548c QPythonPlus\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff0c\u4e13\u4e3a\u9700\u8981\u66f4\u591a\u654f\u611f\u6743\u9650\u7684\u9ad8\u7ea7\u7528\u6237\u8bbe\u8ba1\uff09\u5c06\u4fdd\u6301\u540c\u6b65\u7684\u7248\u672c\u53f7\u3002

      "},{"location":"whats-new/#v352-2025225","title":"v3.5.2 (2025/2/25)","text":"

      \u4e0e\u5f00\u6e90 LLM \u90e8\u7f72\u5de5\u5177 Ollama \u4ee5\u53ca DeepSeek \u5f00\u53d1\u7684 DeepSeek \u5b9e\u73b0\u65e0\u7f1d\u96c6\u6210\uff01

      \u529f\u80fd\uff1a - \u96f6\u95e8\u69db\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5404\u79cd\u5927\u578b\u8bed\u8a00\u6a21\u578b - \u5feb\u901f\u90e8\u7f72 DeepSeek \u7b49\u5c16\u7aef AI \u6a21\u578b - \u4eab\u53d7\u7b80\u7ea6\u7684 API \u8c03\u7528\u4f53\u9a8c - \u6784\u5efa\u5b8c\u5168\u79bb\u7ebf\u7684\u667a\u80fd\u7f16\u7a0b\u73af\u5883

      \u80fd\u529b\uff1a - \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u52a0\u8f7d/\u7ba1\u7406 LLM \u6a21\u578b - \u57fa\u4e8e\u672c\u5730\u8ba1\u7b97\u7684\u5b9e\u65f6\u4f4e\u5ef6\u8fdf\u54cd\u5e94

      "},{"location":"whats-new/#v350","title":"v3.5.0","text":"
      • Python \u5347\u7ea7\u5230 3.12.8
      • \u6539\u8fdb\u4eea\u8868\u76d8\uff0c\u529f\u80fd\u66f4\u6e05\u6670\u3001\u66f4\u4eba\u6027\u5316
      • \u6dfb\u52a0\u4e86\u4f17\u591a\u7b2c\u4e09\u65b9\u5305\uff1aPyTorch / Twisted / Scrapy / FastAPI ...
      "},{"location":"whats-new/#v338","title":"v3.3.8","text":"
      • \u4fee\u590d\u4e86 NumPy \u517c\u5bb9\u6027\u95ee\u9898
      "},{"location":"whats-new/#v335","title":"v3.3.5","text":"
      • \u5347\u7ea7 Python \u5185\u6838\u5230 3.11.9
      • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u4e0d\u663e\u793a\u6a21\u5757\u5b89\u88c5\u72b6\u6001\u7684 bug
      • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u5220\u9664\u6a21\u5757\u5931\u8d25\u7684 bug
      • \u4fee\u590d\u4e86\u5176\u4ed6 bug
      "},{"location":"whats-new/#v334","title":"v3.3.4","text":"
      • \u6dfb\u52a0\u4e86 OpenAI/Langchain/APIGPTCloud AI \u5305
      • \u79fb\u9664\u4e0d\u5fc5\u8981\u7684\u6587\u4ef6\u4ee5\u51cf\u5c11\u5927\u5c0f
      "},{"location":"whats-new/#v325","title":"v3.2.5","text":"
      • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570
      • \u5176\u4ed6\u9519\u8bef\u4fee\u590d
      "},{"location":"whats-new/#v323","title":"v3.2.3","text":"
      • \u66f4\u65b0 Python \u7248\u672c\u5230 3.11.0
      • \u66f4\u65b0 IPython \u7248\u672c\u5230 8.6.0
      • \u66f4\u65b0 pip \u7248\u672c\u5230 22.3.1
      • \u66f4\u65b0\u79d1\u5b66\u8ba1\u7b97\u5305\uff0c\u81ea\u52a8\u8f6f\u94fe\u63a5
      • \u51cf\u5c11\u7a7a\u95f4\u4f7f\u7528
      • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570 + \u5176\u4ed6\u9519\u8bef\u4fee\u590d
      "},{"location":"whats-new/#v318","title":"v3.1.8","text":"
      • \u5728\u7ec8\u7aef\u4e2d\u6dfb\u52a0\u4e86\u64cd\u4f5c\u70ed\u952e
      • \u4fee\u590d\u4e86\u7f16\u8f91\u5668\u5728\u65cb\u8f6c\u65f6\u4e22\u5931\u5185\u5bb9\u7684\u95ee\u9898
      • \u4fee\u590d\u4e86\u5176\u4ed6 bug

      \u5728 Google Play \u4e0b\u8f7d

      "},{"location":"qsl4a/","title":"QSL4A\uff08Android \u811a\u672c\u5c42\uff09API \u6587\u6863","text":"

      QSL4A \u662f QPython \u7684 Android \u811a\u672c\u5c42\uff0c\u5141\u8bb8\u60a8\u4f7f\u7528 Python \u63a7\u5236 Android \u8bbe\u5907\u529f\u80fd\u3002

      "},{"location":"qsl4a/#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a toast \u6d88\u606f\ndroid.makeToast('Hello QPython!')\n\n# \u9707\u52a8\u8bbe\u5907\ndroid.vibrate(500)\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\uff08\u5148\u5f00\u59cb\u76d1\u63a7\uff09\nimport time\ndroid.batteryStartMonitoring()\ntime.sleep(0.5)  # \u7b49\u5f85\u6570\u636e\nbattery = droid.readBatteryData().result\nprint(f\"\u7535\u6c60\uff1a{battery['level']}%\")\n
      "},{"location":"qsl4a/#_2","title":"\u6587\u6863\u7ed3\u6784","text":""},{"location":"qsl4a/#_3","title":"\u6838\u5fc3\u6a21\u5757","text":"
      • Android \u57fa\u7840 - \u6838\u5fc3\u8fde\u63a5\u548c RPC
      • Intent \u7cfb\u7edf - Android Intent \u64cd\u4f5c
      • \u4e8b\u4ef6\u7cfb\u7edf - \u4e8b\u4ef6\u5904\u7406\u548c\u5e7f\u64ad
      "},{"location":"qsl4a/#ui","title":"UI \u7ec4\u4ef6","text":"
      • \u5bf9\u8bdd\u6846 - \u8b66\u62a5\u3001\u8f93\u5165\u3001\u9009\u62e9\u5bf9\u8bdd\u6846
      • \u5168\u5c4f UI - \u81ea\u5b9a\u4e49\u5e03\u5c40 UI
      • \u60ac\u6d6e\u7a97 - \u60ac\u6d6e\u7a97\u53e3
      • \u8f85\u52a9\u529f\u80fd - \u5c4f\u5e55\u81ea\u52a8\u5316
      "},{"location":"qsl4a/#_4","title":"\u7cfb\u7edf","text":"
      • \u7535\u6c60 - \u7535\u6c60\u76d1\u63a7
      • \u4f20\u611f\u5668 - \u8bbe\u5907\u4f20\u611f\u5668
      • \u5e94\u7528 - \u5e94\u7528\u7ba1\u7406
      • \u7cfb\u7edf\u4fe1\u606f - \u8bbe\u5907\u4fe1\u606f
      • \u8bbe\u7f6e - \u7cfb\u7edf\u8bbe\u7f6e
      • \u5524\u9192\u9501 - \u5524\u9192\u9501\u63a7\u5236
      • QPython \u63a5\u53e3 - \u811a\u672c\u6267\u884c
      • Activity \u7ed3\u679c - Activity \u7ed3\u679c\u5904\u7406
      "},{"location":"qsl4a/#_5","title":"\u786c\u4ef6","text":"
      • \u84dd\u7259 - \u84dd\u7259\u64cd\u4f5c
      • \u76f8\u673a - \u62cd\u7167\u548c\u5f55\u50cf
      • \u97f3\u9891/\u5f55\u97f3\u5668 - \u5f55\u97f3
      • \u7f51\u7edc\u6444\u50cf\u5934 - MJPEG \u6d41
      • USB \u4e32\u53e3 - USB \u4e3b\u673a\u4e32\u53e3
      "},{"location":"qsl4a/#_6","title":"\u8fde\u63a5","text":"
      • WiFi - WiFi \u64cd\u4f5c
      • \u4f4d\u7f6e - GPS \u548c\u4f4d\u7f6e
      • \u77ed\u4fe1 - \u77ed\u4fe1\u64cd\u4f5c
      • \u7535\u8bdd - \u6253\u7535\u8bdd\u548c\u6765\u7535\u4fe1\u606f
      • \u8054\u7cfb\u4eba - \u8054\u7cfb\u4eba\u7ba1\u7406
      • \u4fe1\u53f7\u5f3a\u5ea6 - \u4fe1\u53f7\u76d1\u63a7
      • FTP \u670d\u52a1\u5668 - \u5185\u7f6e FTP \u670d\u52a1\u5668
      "},{"location":"qsl4a/#_7","title":"\u5b58\u50a8","text":"
      • DocumentFile - \u6587\u4ef6\u64cd\u4f5c
      • \u526a\u8d34\u677f - \u526a\u8d34\u677f\u64cd\u4f5c
      • \u504f\u597d\u8bbe\u7f6e - \u5171\u4eab\u504f\u597d\u8bbe\u7f6e
      "},{"location":"qsl4a/#_8","title":"\u5a92\u4f53","text":"
      • \u5a92\u4f53\u64ad\u653e\u5668 - \u97f3\u9891/\u89c6\u9891\u64ad\u653e
      • \u56fe\u50cf\u5904\u7406 - \u56fe\u50cf\u64cd\u4f5c
      "},{"location":"qsl4a/#_9","title":"\u7279\u6b8a\u529f\u80fd","text":"
      • \u52a0\u5bc6 - \u52a0\u5bc6/\u89e3\u5bc6
      • PGPT AI - AI \u8bed\u97f3\u670d\u52a1
      "},{"location":"qsl4a/#_10","title":"\u7ed3\u679c\u5bf9\u8c61","text":"

      \u5927\u591a\u6570 QSL4A \u65b9\u6cd5\u8fd4\u56de\u4e00\u4e2a\u5e26\u6709\u4ee5\u4e0b\u5c5e\u6027\u7684 Result \u547d\u540d\u5143\u7ec4\uff1a - id - \u8bf7\u6c42 ID - result - \u5b9e\u9645\u7ed3\u679c\u6570\u636e - error - \u5982\u679c\u5931\u8d25\u5219\u4e3a\u9519\u8bef\u6d88\u606f

      result = droid.getClipboard()\nif result.error is None:\n    print(result.result)\nelse:\n    print(f\"\u9519\u8bef\uff1a{result.error}\")\n
      "},{"location":"qsl4a/connectivity/contacts/","title":"\u8054\u7cfb\u4eba API","text":"

      \u8bbf\u95ee\u548c\u7ba1\u7406\u8bbe\u5907\u8054\u7cfb\u4eba\u3002

      "},{"location":"qsl4a/connectivity/contacts/#_1","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":""},{"location":"qsl4a/connectivity/contacts/#pickcontact","title":"pickContact()","text":"

      \u663e\u793a\u8054\u7cfb\u4eba\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

      pickContact()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u8054\u7cfb\u4eba URI \u7684 Intent

      "},{"location":"qsl4a/connectivity/contacts/#pickphone","title":"pickPhone()","text":"

      \u663e\u793a\u7535\u8bdd\u53f7\u7801\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

      pickPhone()\n

      \u8fd4\u56de\uff1a \u9009\u4e2d\u7684\u7535\u8bdd\u53f7\u7801\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/contacts/#_2","title":"\u8054\u7cfb\u4eba\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#contactsget","title":"contactsGet()","text":"

      \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\u3002

      contactsGet(attributes=None)\n

      \u53c2\u6570\uff1a - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

      \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba JSONObject \u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetbyid","title":"contactsGetById()","text":"

      \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\u3002

      contactsGetById(id, attributes=None)\n

      \u53c2\u6570\uff1a - id (int): \u8054\u7cfb\u4eba ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

      \u8fd4\u56de\uff1a JSONObject \u8054\u7cfb\u4eba\u6570\u636e

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetcount","title":"contactsGetCount()","text":"

      \u83b7\u53d6\u8054\u7cfb\u4eba\u603b\u6570\u3002

      contactsGetCount()\n

      \u8fd4\u56de\uff1a \u6574\u6570\u8ba1\u6570

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetids","title":"contactsGetIds()","text":"

      \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba ID\u3002

      contactsGetIds()\n

      \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba ID \u6574\u6570\u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetattributes","title":"contactsGetAttributes()","text":"

      \u83b7\u53d6\u6240\u6709\u53ef\u80fd\u7684\u8054\u7cfb\u4eba\u5c5e\u6027\u3002

      contactsGetAttributes()\n

      \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#_3","title":"\u5185\u5bb9\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#querycontent","title":"queryContent()","text":"

      \u4f7f\u7528\u81ea\u5b9a\u4e49\u53c2\u6570\u67e5\u8be2\u5185\u5bb9\u89e3\u6790\u5668\u3002

      queryContent(uri, attributes=None, selection=None, selectionArgs=None, order=None)\n

      \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u5c5e\u6027 - selection (str, optional): WHERE \u5b50\u53e5 - selectionArgs (list, optional): \u9009\u62e9\u53c2\u6570 - order (str, optional): ORDER BY \u5b50\u53e5

      \u8fd4\u56de\uff1a JSONObject \u7ed3\u679c\u5217\u8868

      "},{"location":"qsl4a/connectivity/contacts/#queryattributes","title":"queryAttributes()","text":"

      \u83b7\u53d6\u5185\u5bb9 URI \u7684\u5c5e\u6027\u3002

      queryAttributes(uri)\n

      \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI

      \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u7684 JSONArray

      "},{"location":"qsl4a/connectivity/contacts/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u9009\u62e9\u8054\u7cfb\u4eba\ncontact_uri = droid.pickContact().result\nprint(f\"Selected contact: {contact_uri}\")\n\n# \u9009\u62e9\u7535\u8bdd\u53f7\u7801\nphone = droid.pickPhone().result\nprint(f\"Selected phone: {phone}\")\n\n# \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\ncontacts = droid.contactsGet().result\nprint(f\"Total contacts: {len(contacts)}\")\n\n# \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\ncontact = droid.contactsGetById(1).result\nprint(f\"Contact: {contact}\")\n\n# \u83b7\u53d6\u8054\u7cfb\u4eba\u5c5e\u6027\nattrs = droid.contactsGetAttributes().result\nprint(f\"Available attributes: {attrs}\")\n
      "},{"location":"qsl4a/connectivity/ftp/","title":"FTP \u670d\u52a1\u5668 API","text":"

      \u5728\u8bbe\u5907\u4e0a\u542f\u52a8\u548c\u7ba1\u7406\u5185\u7f6e FTP \u670d\u52a1\u5668\u3002

      "},{"location":"qsl4a/connectivity/ftp/#ftp","title":"FTP \u670d\u52a1\u5668\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/ftp/#ftpstart","title":"ftpStart()","text":"

      \u542f\u52a8 FTP \u670d\u52a1\u5668\u3002

      ftpStart()\n

      \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4 [ip, port]

      "},{"location":"qsl4a/connectivity/ftp/#ftpstop","title":"ftpStop()","text":"

      \u505c\u6b62 FTP \u670d\u52a1\u5668\u3002

      ftpStop()\n
      "},{"location":"qsl4a/connectivity/ftp/#ftpisrunning","title":"ftpIsRunning()","text":"

      \u68c0\u67e5 FTP \u670d\u52a1\u5668\u662f\u5426\u6b63\u5728\u8fd0\u884c\u3002

      ftpIsRunning()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u8fd0\u884c\u5219\u4e3a True

      "},{"location":"qsl4a/connectivity/ftp/#ftpget","title":"ftpGet()","text":"

      \u83b7\u53d6 FTP \u670d\u52a1\u5668 IP \u5730\u5740\u3002

      ftpGet()\n

      \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4

      "},{"location":"qsl4a/connectivity/ftp/#ftpset","title":"ftpSet()","text":"

      \u914d\u7f6e FTP \u670d\u52a1\u5668\u8bbe\u7f6e\u3002

      ftpSet(port=None, rootDir=None, username=None, password=None)\n

      \u53c2\u6570\uff1a - port (int, optional): \u670d\u52a1\u5668\u7aef\u53e3 - rootDir (str, optional): \u8981\u670d\u52a1\u7684\u57fa\u7840\u76ee\u5f55 - username (str, optional): \u767b\u5f55\u7528\u6237\u540d - password (str, optional): \u767b\u5f55\u5bc6\u7801

      \u8fd4\u56de\uff1a \u5305\u542b\u5f53\u524d\u8bbe\u7f6e\u7684 JSONObject

      "},{"location":"qsl4a/connectivity/ftp/#ftpstatus","title":"ftpStatus()","text":"

      \u83b7\u53d6 FTP \u670d\u52a1\u5668\u72b6\u6001\u3002

      ftpStatus()\n

      \u8fd4\u56de\uff1a \u72b6\u6001\u63cf\u8ff0\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/ftp/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u914d\u7f6e FTP \u670d\u52a1\u5668\ndroid.ftpSet(\n    port=2121,\n    rootDir=\"/sdcard\",\n    username=\"admin\",\n    password=\"secret\"\n)\n\n# \u542f\u52a8 FTP \u670d\u52a1\u5668\ninfo = droid.ftpStart().result\nprint(f\"FTP running at {info[0]}:{info[1]}\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.ftpIsRunning().result:\n    print(\"FTP server is running\")\n\n# \u83b7\u53d6\u670d\u52a1\u5668\u4fe1\u606f\nserver_info = droid.ftpGet().result\nprint(f\"Server: {server_info}\")\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.ftpStop()\n

      \u6ce8\u610f\uff1a \u4f7f\u7528\u63d0\u4f9b\u7684\u51ed\u636e\u901a\u8fc7\u4efb\u4f55 FTP \u5ba2\u6237\u7aef\u8fde\u63a5\u5230 FTP \u670d\u52a1\u5668\u3002

      "},{"location":"qsl4a/connectivity/location/","title":"\u4f4d\u7f6e API","text":"

      \u8bbf\u95ee GPS \u548c\u7f51\u7edc\u4f4d\u7f6e\u670d\u52a1\u3002

      "},{"location":"qsl4a/connectivity/location/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/location/#startlocating","title":"startLocating()","text":"

      \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\u3002

      startLocating(minUpdateTime=60000, minUpdateDistance=30, updateGnssStatus=False)\n

      \u53c2\u6570\uff1a - minUpdateTime (int): \u66f4\u65b0\u4e4b\u95f4\u7684\u6700\u5c0f\u65f6\u95f4\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a60000\uff09 - minUpdateDistance (float): \u66f4\u65b0\u7684\u6700\u5c0f\u8ddd\u79bb\uff08\u7c73\uff09\uff08\u9ed8\u8ba4\uff1a30\uff09 - updateGnssStatus (bool): \u542f\u7528 GNSS \u72b6\u6001\u66f4\u65b0\uff08\u9ed8\u8ba4\uff1aFalse\uff09

      "},{"location":"qsl4a/connectivity/location/#stoplocating","title":"stopLocating()","text":"

      \u505c\u6b62\u4f4d\u7f6e\u66f4\u65b0\u3002

      stopLocating()\n
      "},{"location":"qsl4a/connectivity/location/#readlocation","title":"readLocation()","text":"

      \u83b7\u53d6\u6700\u540e\u5df2\u77e5\u4f4d\u7f6e\u3002

      readLocation()\n

      \u8fd4\u56de\uff1a \u4f4d\u7f6e\u6570\u636e\u5b57\u5178

      "},{"location":"qsl4a/connectivity/location/#getlastknownlocation","title":"getLastKnownLocation()","text":"

      \u83b7\u53d6\u7f13\u5b58\u7684\u4f4d\u7f6e\u3002

      getLastKnownLocation()\n

      \u8fd4\u56de\uff1a \u6765\u81ea\u6240\u6709\u63d0\u4f9b\u5546\u7684\u4f4d\u7f6e

      "},{"location":"qsl4a/connectivity/location/#geocode","title":"geocode()","text":"

      \u5c06\u5730\u5740\u8f6c\u6362\u4e3a\u5750\u6807\u3002

      geocode(address, maxResults=1)\n
      "},{"location":"qsl4a/connectivity/location/#_2","title":"\u4f4d\u7f6e\u63d0\u4f9b\u5546\u65b9\u6cd5)","text":""},{"location":"qsl4a/connectivity/location/#locationproviders","title":"locationProviders()","text":"

      \u83b7\u53d6\u624b\u673a\u4e0a\u53ef\u7528\u7684\u4f4d\u7f6e\u63d0\u4f9b\u5546\u3002

      locationProviders()\n

      \u8fd4\u56de\uff1a \u53ef\u7528\u63d0\u4f9b\u5546\u540d\u79f0\u5217\u8868\uff08\u4f8b\u5982 ['gps', 'network']\uff09

      "},{"location":"qsl4a/connectivity/location/#locationproviderenabled","title":"locationProviderEnabled()","text":"

      \u68c0\u67e5\u7279\u5b9a\u4f4d\u7f6e\u63d0\u4f9b\u5546\u662f\u5426\u5df2\u542f\u7528\u3002

      locationProviderEnabled(provider)\n

      \u53c2\u6570\uff1a - provider (str): \u63d0\u4f9b\u5546\u540d\u79f0\uff08\u4f8b\u5982 'gps', 'network'\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/connectivity/location/#readgnssstatus","title":"readGnssStatus()","text":"

      \u8bfb\u53d6\u5168\u7403\u5bfc\u822a\u536b\u661f\u7cfb\u7edf\u72b6\u6001\uff08\u9700\u8981 Android 8+\uff09\u3002

      readGnssStatus()\n

      \u8fd4\u56de\uff1a \u5305\u542b GNSS \u536b\u661f\u4fe1\u606f\u7684 JSONArray

      "},{"location":"qsl4a/connectivity/location/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\ndroid.startLocating(minUpdateTime=5000, minUpdateDistance=1, updateGnssStatus=False)\n\n# \u7b49\u5f85\u5b9a\u4f4d\ntime.sleep(10)\n\n# \u83b7\u53d6\u4f4d\u7f6e\nloc = droid.readLocation().result\nif loc:\n    lat = loc['latitude']\n    lon = loc['longitude']\n    print(f\"Location: {lat}, {lon}\")\n\ndroid.stopLocating()\n
      "},{"location":"qsl4a/connectivity/phone/","title":"\u7535\u8bdd API","text":"

      \u63a7\u5236\u7535\u8bdd\u901a\u8bdd\u548c\u83b7\u53d6\u7535\u8bdd\u4fe1\u606f\u3002

      "},{"location":"qsl4a/connectivity/phone/#_1","title":"\u7535\u8bdd\u72b6\u6001\u8ddf\u8e2a","text":""},{"location":"qsl4a/connectivity/phone/#starttrackingphonestate","title":"startTrackingPhoneState()","text":"

      \u5f00\u59cb\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u53d8\u5316\u3002\u751f\u6210 'phone' \u4e8b\u4ef6\u3002

      startTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/phone/#readphonestate","title":"readPhoneState()","text":"

      \u8bfb\u53d6\u5f53\u524d\u7535\u8bdd\u72b6\u6001\u3002

      readPhoneState()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7535\u8bdd\u72b6\u6001\u548c\u6765\u7535\u53f7\u7801\u7684 Bundle

      "},{"location":"qsl4a/connectivity/phone/#stoptrackingphonestate","title":"stopTrackingPhoneState()","text":"

      \u505c\u6b62\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u3002

      stopTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/phone/#_2","title":"\u62e8\u6253\u7535\u8bdd","text":""},{"location":"qsl4a/connectivity/phone/#phonecall","title":"phoneCall()","text":"

      \u901a\u8fc7 URI \u547c\u53eb\u8054\u7cfb\u4eba/\u7535\u8bdd\u53f7\u7801\u3002

      phoneCall(uri)\n

      \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

      "},{"location":"qsl4a/connectivity/phone/#phonecallnumber","title":"phoneCallNumber()","text":"

      \u76f4\u63a5\u62e8\u6253\u7535\u8bdd\u53f7\u7801\u3002

      phoneCallNumber(phone_number)\n

      \u53c2\u6570\uff1a - phone_number (str): \u8981\u62e8\u6253\u7684\u7535\u8bdd\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#phonedial","title":"phoneDial()","text":"

      \u62e8\u6253\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

      phoneDial(uri)\n

      \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

      "},{"location":"qsl4a/connectivity/phone/#phonedialnumber","title":"phoneDialNumber()","text":"

      \u62e8\u6253\u7535\u8bdd\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

      phoneDialNumber(phone_number)\n

      \u53c2\u6570\uff1a - phone_number (str): \u7535\u8bdd\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#_3","title":"\u57fa\u7ad9\u4f4d\u7f6e","text":""},{"location":"qsl4a/connectivity/phone/#getcelllocation","title":"getCellLocation()","text":"

      \u83b7\u53d6\u5f53\u524d\u57fa\u7ad9\u4f4d\u7f6e\u3002

      getCellLocation()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u57fa\u7ad9\u4f4d\u7f6e\u6570\u636e\u7684 JSONObject

      "},{"location":"qsl4a/connectivity/phone/#getallcellslocation","title":"getAllCellsLocation()","text":"

      \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u4f4d\u7f6e\uff08\u9002\u7528\u4e8e\u53cc\u5361\u8bbe\u5907\uff09\u3002

      getAllCellsLocation()\n

      \u8fd4\u56de\uff1a \u57fa\u7ad9\u4f4d\u7f6e\u7684 JSONArray

      "},{"location":"qsl4a/connectivity/phone/#_4","title":"\u7f51\u7edc\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getnetworkoperator","title":"getNetworkOperator()","text":"

      \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

      getNetworkOperator()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getnetworkoperatorname","title":"getNetworkOperatorName()","text":"

      \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684\u540d\u79f0\u3002

      getNetworkOperatorName()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getnetworktype","title":"getNetworkType()","text":"

      \u83b7\u53d6\u5f53\u524d\u7f51\u7edc\u7c7b\u578b\u3002

      getNetworkType()\n

      \u8fd4\u56de\uff1a \u63cf\u8ff0\u65e0\u7ebf\u7535\u6280\u672f\u7684\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'LTE', 'UMTS', 'GSM'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getphonetype","title":"getPhoneType()","text":"

      \u83b7\u53d6\u7535\u8bdd\u7c7b\u578b\u3002

      getPhoneType()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'GSM', 'CDMA', 'SIP'\uff09

      "},{"location":"qsl4a/connectivity/phone/#sim","title":"SIM \u5361\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getsimcountryiso","title":"getSimCountryIso()","text":"

      \u83b7\u53d6 SIM \u5361\u7684 ISO \u56fd\u5bb6\u4ee3\u7801\u3002

      getSimCountryIso()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'us'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getsimoperator","title":"getSimOperator()","text":"

      \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

      getSimOperator()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getsimoperatorname","title":"getSimOperatorName()","text":"

      \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u540d\u79f0\u3002

      getSimOperatorName()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

      "},{"location":"qsl4a/connectivity/phone/#getsimserialnumber","title":"getSimSerialNumber()","text":"

      \u83b7\u53d6 SIM \u5e8f\u5217\u53f7\u3002

      getSimSerialNumber()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32 SIM \u5e8f\u5217\u53f7

      "},{"location":"qsl4a/connectivity/phone/#getsimstate","title":"getSimState()","text":"

      \u83b7\u53d6 SIM \u5361\u72b6\u6001\u3002

      getSimState()\n

      \u8fd4\u56de\uff1a \u63cf\u8ff0 SIM \u72b6\u6001\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/phone/#getsubscriberid","title":"getSubscriberId()","text":"

      \u83b7\u53d6\u8ba2\u9605\u8005 ID\u3002

      getSubscriberId()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8ba2\u9605\u8005 ID

      "},{"location":"qsl4a/connectivity/phone/#_5","title":"\u8bed\u97f3\u90ae\u4ef6","text":""},{"location":"qsl4a/connectivity/phone/#getvoicemailalphatag","title":"getVoiceMailAlphaTag()","text":"

      \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u5b57\u6bcd\u6807\u7b7e\u3002

      getVoiceMailAlphaTag()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u6807\u7b7e

      "},{"location":"qsl4a/connectivity/phone/#getvoicemailnumber","title":"getVoiceMailNumber()","text":"

      \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801\u3002

      getVoiceMailNumber()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getdeviceid","title":"getDeviceId()","text":"

      \u83b7\u53d6\u8bbe\u5907 ID\uff08GSM \u7684 IMEI\uff09\u3002\u5df2\u5e9f\u5f03\u3002

      getDeviceId()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

      "},{"location":"qsl4a/connectivity/phone/#getdevicesoftwareversion","title":"getDeviceSoftwareVersion()","text":"

      \u83b7\u53d6\u8bbe\u5907\u8f6f\u4ef6\u7248\u672c\u3002

      getDeviceSoftwareVersion()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8f6f\u4ef6\u7248\u672c

      "},{"location":"qsl4a/connectivity/phone/#getline1number","title":"getLine1Number()","text":"

      \u83b7\u53d6\u7ebf\u8def 1 \u7535\u8bdd\u53f7\u7801\u3002

      getLine1Number()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u7535\u8bdd\u53f7\u7801

      "},{"location":"qsl4a/connectivity/phone/#checknetworkroaming","title":"checkNetworkRoaming()","text":"

      \u68c0\u67e5\u662f\u5426\u8fde\u63a5\u5230\u6f2b\u6e38\u7f51\u7edc\u3002

      checkNetworkRoaming()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u6f2b\u6e38\u5219\u4e3a True

      "},{"location":"qsl4a/connectivity/phone/#_7","title":"\u57fa\u7ad9\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getallcellinfo","title":"getAllCellInfo()","text":"

      \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u7684\u4fe1\u606f\u3002

      getAllCellInfo()\n

      \u8fd4\u56de\uff1a \u57fa\u7ad9\u4fe1\u606f\u5217\u8868

      "},{"location":"qsl4a/connectivity/phone/#setdataenabled","title":"setDataEnabled()","text":"

      \u542f\u7528\u6216\u7981\u7528\u79fb\u52a8\u6570\u636e\u3002

      setDataEnabled(enabled)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528

      "},{"location":"qsl4a/connectivity/phone/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7f51\u7edc\u4fe1\u606f\noperator = droid.getNetworkOperatorName().result\nprint(f\"Operator: {operator}\")\n\nnetwork_type = droid.getNetworkType().result\nprint(f\"Network: {network_type}\")\n\n# \u83b7\u53d6 SIM \u4fe1\u606f\nsim_state = droid.getSimState().result\nprint(f\"SIM: {sim_state}\")\n\n# \u83b7\u53d6\u7535\u8bdd\u53f7\u7801\nline1 = droid.getLine1Number().result\nprint(f\"Phone: {line1}\")\n\n# \u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\ndroid.startTrackingPhoneState()\nprint(\"Tracking phone state...\")\ndroid.stopTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/signalstrength/","title":"\u4fe1\u53f7\u5f3a\u5ea6 API","text":"

      \u76d1\u63a7\u8702\u7a9d\u548c\u65e0\u7ebf\u4fe1\u53f7\u5f3a\u5ea6\u3002

      "},{"location":"qsl4a/connectivity/signalstrength/#_1","title":"\u4fe1\u53f7\u5f3a\u5ea6\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/signalstrength/#starttrackingsignalstrengths","title":"startTrackingSignalStrengths()","text":"

      \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316\u3002\u751f\u6210 'signal_strengths' \u4e8b\u4ef6\u3002

      startTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/signalstrength/#stoptrackingsignalstrengths","title":"stopTrackingSignalStrengths()","text":"

      \u505c\u6b62\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u3002

      stopTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/signalstrength/#readsignalstrengths","title":"readSignalStrengths()","text":"

      \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\u3002

      readSignalStrengths()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u4fe1\u53f7\u5f3a\u5ea6\u6570\u636e\u7684 Bundle

      "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthlevel","title":"getTelephoneSignalStrengthLevel()","text":"

      \u83b7\u53d6\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u7b49\u7ea7\uff080-4\uff09\u3002

      getTelephoneSignalStrengthLevel()\n

      \u8fd4\u56de\uff1a \u6574\u6570\u7b49\u7ea7\uff080=\u65e0\uff0c1=\u5dee\uff0c2=\u4e00\u822c\uff0c3=\u597d\uff0c4=\u4f18\u79c0\uff09

      "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthdetail","title":"getTelephoneSignalStrengthDetail()","text":"

      \u83b7\u53d6\u8be6\u7ec6\u7684\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u4fe1\u606f\u3002

      getTelephoneSignalStrengthDetail()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u8be6\u7ec6\u4fe1\u53f7\u4fe1\u606f\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/connectivity/signalstrength/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\ndroid.startTrackingSignalStrengths()\n\n# \u7b49\u5f85\u4fe1\u53f7\u66f4\u65b0\ntime.sleep(5)\n\n# \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\nsignal = droid.readSignalStrengths().result\nprint(f\"Signal: {signal}\")\n\n# \u76f4\u63a5\u83b7\u53d6\u7b49\u7ea7\nlevel = droid.getTelephoneSignalStrengthLevel().result\nprint(f\"Signal level: {level}/4\")\n\ndroid.stopTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/sms/","title":"SMS API","text":"

      \u53d1\u9001\u548c\u63a5\u6536 SMS \u6d88\u606f\u3002

      "},{"location":"qsl4a/connectivity/sms/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/sms/#smssend","title":"smsSend()","text":"

      \u53d1\u9001 SMS \u6d88\u606f\u3002

      smsSend(destinationAddress, text)\n

      \u53c2\u6570\uff1a - destinationAddress (str): \u7535\u8bdd\u53f7\u7801 - text (str): \u6d88\u606f\u6587\u672c

      "},{"location":"qsl4a/connectivity/sms/#smsgetmessagecount","title":"smsGetMessageCount()","text":"

      \u83b7\u53d6\u6d88\u606f\u6570\u91cf\u3002

      smsGetMessageCount(unreadOnly=False, folder=\"inbox\")\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessageids","title":"smsGetMessageIds()","text":"

      \u83b7\u53d6\u6d88\u606f ID\u3002

      smsGetMessageIds(unreadOnly=False, folder=\"inbox\")\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessages","title":"smsGetMessages()","text":"

      \u83b7\u53d6\u6d88\u606f\u8be6\u60c5\u3002

      smsGetMessages(unreadOnly=False, folder=\"inbox\", attributes=None)\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessagebyid","title":"smsGetMessageById()","text":"

      \u901a\u8fc7 ID \u83b7\u53d6\u7279\u5b9a\u6d88\u606f\u3002

      smsGetMessageById(id, attributes=None)\n

      \u53c2\u6570\uff1a - id (int): \u6d88\u606f ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

      \u8fd4\u56de\uff1a \u6d88\u606f\u6570\u636e\u5b57\u5178

      "},{"location":"qsl4a/connectivity/sms/#smsgetattributes","title":"smsGetAttributes()","text":"

      \u83b7\u53d6\u53ef\u7528\u7684 SMS \u6d88\u606f\u5c5e\u6027\u3002

      smsGetAttributes()\n

      \u8fd4\u56de\uff1a \u53ef\u7528\u5c5e\u6027\u540d\u79f0\u5217\u8868

      "},{"location":"qsl4a/connectivity/sms/#smsdeletemessage","title":"smsDeleteMessage()","text":"

      \u5220\u9664\u6d88\u606f\u3002

      smsDeleteMessage(id)\n
      "},{"location":"qsl4a/connectivity/sms/#smsmarkmessageread","title":"smsMarkMessageRead()","text":"

      \u5c06\u6d88\u606f\u6807\u8bb0\u4e3a\u5df2\u8bfb\u3002

      smsMarkMessageRead(ids, read=True)\n
      "},{"location":"qsl4a/connectivity/sms/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u53d1\u9001 SMS\ndroid.smsSend(\"+1234567890\", \"Hello from QPython!\")\n\n# \u83b7\u53d6\u672a\u8bfb\u6d88\u606f\nmessages = droid.smsGetMessages(unreadOnly=True).result\nfor msg in messages:\n    print(f\"From: {msg['address']}, Text: {msg['body']}\")\n
      "},{"location":"qsl4a/connectivity/wifi/","title":"WiFi API","text":"

      \u63a7\u5236 WiFi \u9002\u914d\u5668\u5e76\u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\u3002

      "},{"location":"qsl4a/connectivity/wifi/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/connectivity/wifi/#checkwifistate","title":"checkWifiState()","text":"

      \u68c0\u67e5 WiFi \u662f\u5426\u5df2\u542f\u7528\u3002

      checkWifiState()\n

      \u8fd4\u56de\uff1a \u5982\u679c WiFi \u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/connectivity/wifi/#togglewifistate","title":"toggleWifiState()","text":"

      \u6253\u5f00\u6216\u5173\u95ed WiFi\u3002

      toggleWifiState(enabled=None)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

      \u8fd4\u56de\uff1a \u5982\u679c\u64cd\u4f5c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/connectivity/wifi/#wifistartscan","title":"wifiStartScan()","text":"

      \u5f00\u59cb\u626b\u63cf\u53ef\u7528\u7684 WiFi \u7f51\u7edc\u3002

      wifiStartScan()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifigetscanresults","title":"wifiGetScanResults()","text":"

      \u83b7\u53d6\u53d1\u73b0\u7684 WiFi \u7f51\u7edc\u5217\u8868\u3002

      wifiGetScanResults()\n

      \u8fd4\u56de\uff1a \u63a5\u5165\u70b9\u4fe1\u606f\u5217\u8868

      "},{"location":"qsl4a/connectivity/wifi/#_2","title":"\u8fde\u63a5\u7ba1\u7406","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetconnectioninfo","title":"wifiGetConnectionInfo()","text":"

      \u83b7\u53d6\u8be6\u7ec6\u8fde\u63a5\u4fe1\u606f\u3002

      wifiGetConnectionInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001IP \u5730\u5740\u7b49\u8fde\u63a5\u8be6\u60c5\u7684\u5b57\u5178

      "},{"location":"qsl4a/connectivity/wifi/#getconnectedinfo","title":"getConnectedInfo()","text":"

      \u83b7\u53d6\u8fde\u63a5\u7684 WiFi \u7f51\u7edc\u4fe1\u606f\uff08\u7b80\u5316\u7248\uff09\u3002

      getConnectedInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001\u4fe1\u53f7\u5f3a\u5ea6\u7684\u5b57\u5178

      "},{"location":"qsl4a/connectivity/wifi/#getdhcpinfo","title":"getDhcpInfo()","text":"

      \u83b7\u53d6\u5f53\u524d\u8fde\u63a5\u7684 DHCP \u4fe1\u606f\u3002

      getDhcpInfo(ipConvertToString=True)\n

      \u53c2\u6570\uff1a - ipConvertToString (bool): \u5c06 IP \u5730\u5740\u8f6c\u6362\u4e3a\u5b57\u7b26\u4e32\u683c\u5f0f\uff08\u9ed8\u8ba4\uff1aTrue\uff09

      \u8fd4\u56de\uff1a \u5305\u542b IP\u3001\u7f51\u5173\u3001DNS \u7b49 DHCP \u4fe1\u606f\u7684\u5b57\u5178

      "},{"location":"qsl4a/connectivity/wifi/#wifidisconnect","title":"wifiDisconnect()","text":"

      \u65ad\u5f00\u5f53\u524d WiFi \u7f51\u7edc\u8fde\u63a5\u3002

      wifiDisconnect()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifireconnect","title":"wifiReconnect()","text":"

      \u91cd\u65b0\u8fde\u63a5\u5230\u5f53\u524d\u7f51\u7edc\u3002

      wifiReconnect()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifireassociate","title":"wifiReassociate()","text":"

      \u91cd\u65b0\u5173\u8054\u5f53\u524d\u63a5\u5165\u70b9\u3002

      wifiReassociate()\n
      "},{"location":"qsl4a/connectivity/wifi/#_3","title":"\u70ed\u70b9","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetapstate","title":"wifiGetApState()","text":"

      \u83b7\u53d6 WiFi AP\uff08\u70ed\u70b9\uff09\u72b6\u6001\u3002

      wifiGetApState()\n

      \u8fd4\u56de\uff1a \u70ed\u70b9\u72b6\u6001

      "},{"location":"qsl4a/connectivity/wifi/#wifi","title":"WiFi \u9501","text":""},{"location":"qsl4a/connectivity/wifi/#wifilockacquirefull","title":"wifiLockAcquireFull()","text":"

      \u83b7\u53d6\u5b8c\u6574 WiFi \u9501\uff08\u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\u4e5f\u4fdd\u6301 WiFi \u6d3b\u52a8\uff09\u3002

      wifiLockAcquireFull()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifilockacquirescanonly","title":"wifiLockAcquireScanOnly()","text":"

      \u83b7\u53d6\u4ec5\u626b\u63cf WiFi \u9501\u3002

      wifiLockAcquireScanOnly()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifilockrelease","title":"wifiLockRelease()","text":"

      \u91ca\u653e WiFi \u9501\u3002

      wifiLockRelease()\n
      "},{"location":"qsl4a/connectivity/wifi/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u68c0\u67e5 WiFi \u72b6\u6001\nif droid.checkWifiState().result:\n    print(\"WiFi is enabled\")\nelse:\n    print(\"Enabling WiFi...\")\n    droid.toggleWifiState(True)\n    time.sleep(2)\n\n# \u5f00\u59cb\u626b\u63cf\ndroid.wifiStartScan()\ntime.sleep(3)\n\n# \u83b7\u53d6\u626b\u63cf\u7ed3\u679c\nnetworks = droid.wifiGetScanResults().result\nfor network in networks:\n    print(f\"SSID: {network.get('SSID')}, Signal: {network.get('level')} dBm\")\n\n# \u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\ninfo = droid.wifiGetConnectionInfo().result\nif info:\n    print(f\"Connected to: {info.get('ssid')}\")\n    print(f\"BSSID: {info.get('bssid')}\")\n    print(f\"IP: {info.get('ip_address')}\")\n\n# \u83b7\u53d6 DHCP \u4fe1\u606f\ndhcp = droid.getDhcpInfo().result\nif dhcp:\n    print(f\"Gateway: {dhcp.get('gateway')}\")\n    print(f\"DNS: {dhcp.get('dns1')}\")\n\n# \u83b7\u53d6\u7b80\u5316\u7684\u8fde\u63a5\u4fe1\u606f\nconnected = droid.getConnectedInfo().result\nprint(f\"SSID: {connected.get('ssid')}, Signal: {connected.get('level')} dBm\")\n\n# \u65ad\u5f00\u5e76\u91cd\u65b0\u8fde\u63a5\ndroid.wifiDisconnect()\ntime.sleep(1)\ndroid.wifiReconnect()\n\n# \u91cd\u65b0\u5173\u8054\u63a5\u5165\u70b9\ndroid.wifiReassociate()\n\n# \u68c0\u67e5\u70ed\u70b9\u72b6\u6001\nap_state = droid.wifiGetApState().result\nprint(f\"Hotspot state: {ap_state}\")\n\n# \u83b7\u53d6 WiFi \u9501\u4ee5\u8fdb\u884c\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireFull()\n# ... \u6267\u884c\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n\n# \u6216\u4f7f\u7528\u4ec5\u626b\u63cf\u9501\u4ee5\u8fdb\u884c\u8f83\u8f7b\u7684\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireScanOnly()\n# ... \u6267\u884c\u626b\u63cf\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n
      "},{"location":"qsl4a/core/android-base/","title":"Android \u57fa\u7840\u7c7b","text":"

      Android \u7c7b\u662f QSL4A \u7684\u6838\u5fc3\uff0c\u63d0\u4f9b\u4e86\u4e0e Android \u8fd0\u884c\u65f6\u7684\u8fde\u63a5\u548c RPC \u673a\u5236\u3002

      "},{"location":"qsl4a/core/android-base/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
      # \u529f\u80fd\u5b8c\u6574\u7248\u672c\uff08\u63a8\u8350\uff09\nimport androidhelper\ndroid = androidhelper.Android()\n\n# \u7b80\u5316\u7248\u672c\uff08\u5feb\u901f\uff0c\u5355\u5b9e\u4f8b\uff09\nimport android\ndroid = android.droid\n
      "},{"location":"qsl4a/core/android-base/#android_1","title":"\u7c7b\uff1aAndroid","text":""},{"location":"qsl4a/core/android-base/#_2","title":"\u6784\u9020\u51fd\u6570","text":"
      Android(addr=None)\n

      \u53c2\u6570\uff1a - addr (tuple, optional): (HOST, PORT) \u5730\u5740\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u73af\u5883\u53d8\u91cf AP_HOST \u548c AP_PORT

      \u73af\u5883\u53d8\u91cf\uff1a - AP_HOST - \u670d\u52a1\u5668\u4e3b\u673a\u5730\u5740 - AP_PORT - \u670d\u52a1\u5668\u7aef\u53e3 - AP_HANDSHAKE - \u8ba4\u8bc1\u4ee4\u724c

      "},{"location":"qsl4a/core/android-base/#_3","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/android-base/#_rpc","title":"_rpc()","text":"

      \u8c03\u7528 Android \u51fd\u6570\u7684\u5185\u90e8 RPC \u65b9\u6cd5\u3002

      _rpc(method, *args)\n

      \u53c2\u6570\uff1a - method (str): \u8981\u8c03\u7528\u7684\u65b9\u6cd5\u540d - *args: \u65b9\u6cd5\u7684\u53ef\u53d8\u53c2\u6570

      \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4\uff0c\u5305\u542b\u4ee5\u4e0b\u5b57\u6bb5\uff1a - id (int): \u8bf7\u6c42 ID - result: \u65b9\u6cd5\u8fd4\u56de\u503c - error (str or None): \u9519\u8bef\u4fe1\u606f\uff08\u5982\u679c\u5931\u8d25\uff09

      "},{"location":"qsl4a/core/android-base/#getattr","title":"getattr()","text":"

      \u52a8\u6001\u65b9\u6cd5\u5206\u53d1\u5668\u3002\u6240\u6709 Android \u65b9\u6cd5\u90fd\u901a\u8fc7\u5c5e\u6027\u67e5\u627e\u8bbf\u95ee\u3002

      # \u4ee5\u4e0b\u4e24\u79cd\u65b9\u5f0f\u7b49\u4ef7\uff1a\ndroid.makeToast(\"Hello\")\ndroid._rpc(\"makeToast\", \"Hello\")\n
      "},{"location":"qsl4a/core/android-base/#androidpy","title":"\u72ec\u7acb\u51fd\u6570\uff08android.py\uff09","text":"

      \u4f7f\u7528\u7b80\u5316\u7684 android \u6a21\u5757\u65f6\uff1a

      "},{"location":"qsl4a/core/android-base/#jsla","title":"jsla()","text":"

      \u53d1\u9001 JSON-RPC \u8bf7\u6c42\u5e76\u8fd4\u56de\u539f\u59cb\u54cd\u5e94\u3002

      jsla(method, *params)\n

      \u8fd4\u56de\uff1a JSON \u5b57\u7b26\u4e32\u54cd\u5e94

      "},{"location":"qsl4a/core/android-base/#rsla","title":"rsla()","text":"

      \u53d1\u9001\u8bf7\u6c42\u5e76\u4ec5\u8fd4\u56de\u7ed3\u679c\u3002

      rsla(method, *params)\n

      \u8fd4\u56de\uff1a RPC \u8c03\u7528\u7684\u7ed3\u679c\u503c

      "},{"location":"qsl4a/core/android-base/#esla","title":"esla()","text":"

      \u53d1\u9001\u8bf7\u6c42\uff0c\u9519\u8bef\u65f6\u629b\u51fa\u5f02\u5e38\u3002

      esla(method, *params)\n

      \u629b\u51fa\uff1a \u5982\u679c error \u5b57\u6bb5\u4e0d\u4e3a None \u5219\u629b\u51fa\u5f02\u5e38

      "},{"location":"qsl4a/core/android-base/#nsla","title":"nsla()","text":"

      \u53d1\u9001\u8bf7\u6c42\u5e76\u8fd4\u56de Result \u547d\u540d\u5143\u7ec4\u3002

      nsla(method, *params)\n

      \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4

      "},{"location":"qsl4a/core/android-base/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/android-base/#_5","title":"\u57fa\u672c\u8fde\u63a5","text":"
      import androidhelper\n\n# \u8fde\u63a5\u5230 Android \u8fd0\u884c\u65f6\ndroid = androidhelper.Android()\n\n# \u901a\u8fc7\u663e\u793a toast \u6765\u68c0\u67e5\u8fde\u63a5\ndroid.makeToast(\"Connected!\")\n
      "},{"location":"qsl4a/core/android-base/#_6","title":"\u9519\u8bef\u5904\u7406","text":"
      result = droid.someMethod()\nif result.error:\n    print(f\"Error: {result.error}\")\nelse:\n    print(f\"Success: {result.result}\")\n
      "},{"location":"qsl4a/core/android-base/#rpc","title":"\u76f4\u63a5 RPC \u8c03\u7528","text":"
      # \u76f4\u63a5\u8c03\u7528\u4efb\u610f\u65b9\u6cd5\nresult = droid._rpc(\"makeToast\", \"Hello World\")\n
      "},{"location":"qsl4a/core/events/","title":"\u4e8b\u4ef6\u7cfb\u7edf","text":"

      QSL4A \u63d0\u4f9b\u4e86\u4e00\u4e2a\u4e8b\u4ef6\u7cfb\u7edf\uff0c\u7528\u4e8e\u5904\u7406\u6765\u81ea Android \u7684\u5f02\u6b65\u4e8b\u4ef6\uff0c\u5982\u4f20\u611f\u5668\u66f4\u65b0\u3001\u4f4d\u7f6e\u53d8\u5316\u548c\u81ea\u5b9a\u4e49\u5e7f\u64ad\u3002

      "},{"location":"qsl4a/core/events/#_2","title":"\u4e8b\u4ef6\u57fa\u7840","text":"

      \u4e8b\u4ef6\u5b58\u50a8\u5728\u7f13\u51b2\u533a\u4e2d\uff0c\u53ef\u4ee5\u8f6e\u8be2\u6216\u7b49\u5f85\u3002\u6bcf\u4e2a\u4e8b\u4ef6\u5305\u542b\uff1a - name: \u4e8b\u4ef6\u7c7b\u578b/\u540d\u79f0 - data: \u4e8b\u4ef6\u8d1f\u8f7d\u6570\u636e - time: \u65f6\u95f4\u6233

      "},{"location":"qsl4a/core/events/#_3","title":"\u4e8b\u4ef6\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#eventclearbuffer","title":"eventClearBuffer()","text":"

      \u6e05\u9664\u7f13\u51b2\u533a\u4e2d\u7684\u6240\u6709\u5f85\u5904\u7406\u4e8b\u4ef6\u3002

      eventClearBuffer()\n

      \u8fd4\u56de\uff1a None

      "},{"location":"qsl4a/core/events/#eventpoll","title":"eventPoll()","text":"

      \u8f6e\u8be2\u7f13\u51b2\u533a\u4e2d\u7684\u4e8b\u4ef6\u3002

      eventPoll(number_of_events=1)\n

      \u53c2\u6570\uff1a - number_of_events (int): \u8981\u68c0\u7d22\u7684\u6700\u5927\u4e8b\u4ef6\u6570\uff08\u9ed8\u8ba4\uff1a1\uff09

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\u5217\u8868

      "},{"location":"qsl4a/core/events/#eventwait","title":"eventWait()","text":"

      \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\u3002

      eventWait(timeout=None)\n

      \u53c2\u6570\uff1a - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09\u3002None = \u6c38\u4e45\u7b49\u5f85

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

      "},{"location":"qsl4a/core/events/#eventwaitfor","title":"eventWaitFor()","text":"

      \u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6\u3002

      eventWaitFor(eventName, timeout=None)\n

      \u53c2\u6570\uff1a - eventName (str): \u8981\u7b49\u5f85\u7684\u4e8b\u4ef6\u540d\u79f0 - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

      "},{"location":"qsl4a/core/events/#eventpost","title":"eventPost()","text":"

      \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\u3002

      eventPost(name, data, enqueue=None)\n

      \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e\uff08\u4efb\u610f\u7c7b\u578b\uff09 - enqueue (bool, optional): \u5982\u679c\u4e3a True \u5219\u6dfb\u52a0\u5230\u961f\u5217

      "},{"location":"qsl4a/core/events/#receiveevent","title":"receiveEvent()","text":"

      \u63a5\u6536\u4e8b\u4ef6\uff08\u963b\u585e\uff09\u3002

      receiveEvent()\n

      \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61

      "},{"location":"qsl4a/core/events/#_4","title":"\u5e7f\u64ad\u4e8b\u4ef6","text":"

      \u6ce8\u518c\u7cfb\u7edf\u5e7f\u64ad\u4e8b\u4ef6\u3002

      "},{"location":"qsl4a/core/events/#eventregisterforbroadcast","title":"eventRegisterForBroadcast()","text":"

      \u6ce8\u518c\u63a5\u6536\u5e7f\u64ad\u4e8b\u4ef6\u3002

      eventRegisterForBroadcast(category, enqueue=True)\n

      \u53c2\u6570\uff1a - category (str): \u5e7f\u64ad\u7c7b\u522b/\u52a8\u4f5c - enqueue (bool): \u6dfb\u52a0\u5230\u4e8b\u4ef6\u961f\u5217

      "},{"location":"qsl4a/core/events/#eventunregisterforbroadcast","title":"eventUnregisterForBroadcast()","text":"

      \u53d6\u6d88\u6ce8\u518c\u5e7f\u64ad\u4e8b\u4ef6\u3002

      eventUnregisterForBroadcast(category)\n
      "},{"location":"qsl4a/core/events/#eventgetbrodcastcategories","title":"eventGetBrodcastCategories()","text":"

      \u83b7\u53d6\u5df2\u6ce8\u518c\u7684\u5e7f\u64ad\u7c7b\u522b\u3002

      eventGetBrodcastCategories()\n

      \u8fd4\u56de\uff1a \u5df2\u6ce8\u518c\u7c7b\u522b\u5217\u8868

      "},{"location":"qsl4a/core/events/#_5","title":"\u4e8b\u4ef6\u5206\u53d1\u5668)","text":""},{"location":"qsl4a/core/events/#starteventdispatcher","title":"startEventDispatcher()","text":"

      \u6253\u5f00\u4e00\u4e2a\u53ef\u4ee5\u8bfb\u53d6\u5df2\u53d1\u5e03\u4e8b\u4ef6\u7684\u5957\u63a5\u5b57\u3002)

      startEventDispatcher(port=0)\n

      \u53c2\u6570\uff1a - port (int, optional): \u76d1\u542c\u7684\u7aef\u53e3\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\u9009\u62e9\uff09

      \u8fd4\u56de\uff1a \u6b63\u5728\u76d1\u542c\u7684\u7aef\u53e3\u53f7

      "},{"location":"qsl4a/core/events/#stopeventdispatcher","title":"stopEventDispatcher()","text":"

      \u505c\u6b62\u4e8b\u4ef6\u670d\u52a1\u5668\u3002)

      stopEventDispatcher()\n
      "},{"location":"qsl4a/core/events/#_6","title":"\u5df2\u5e9f\u5f03\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#rpcpostevent","title":"rpcPostEvent()","text":"

      \u5c06\u4e8b\u4ef6\u53d1\u5e03\u5230\u4e8b\u4ef6\u961f\u5217\u3002\uff08\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 eventPost\uff09

      rpcPostEvent(name, data)\n

      \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e

      "},{"location":"qsl4a/core/events/#_7","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/events/#_8","title":"\u57fa\u672c\u4e8b\u4ef6\u8f6e\u8be2","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6e05\u9664\u65e7\u4e8b\u4ef6\ndroid.eventClearBuffer()\n\n# \u8f6e\u8be2\u4e8b\u4ef6\nevents = droid.eventPoll(5).result\nfor event in events:\n    print(f\"Event: {event['name']}, Data: {event['data']}\")\n
      "},{"location":"qsl4a/core/events/#_9","title":"\u7b49\u5f85\u4e8b\u4ef6","text":"
      # \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\uff0c\u5e26\u8d85\u65f6\nevent = droid.eventWait(timeout=10).result\nif event:\n    print(f\"Got event: {event['name']}\")\n
      "},{"location":"qsl4a/core/events/#_10","title":"\u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6","text":"
      # \u7b49\u5f85\u4f20\u611f\u5668\u4e8b\u4ef6\nevent = droid.eventWaitFor('screen', timeout=5).result\nif event:\n    print(f\"Screen event: {event['data']}\")\n
      "},{"location":"qsl4a/core/events/#_11","title":"\u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6","text":"
      # \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\ndroid.eventPost('my_event', {'key': 'value'})\n\n# \u7b49\u5f85\u5b83\nevent = droid.eventWaitFor('my_event', timeout=1).result\n
      "},{"location":"qsl4a/core/events/#_12","title":"\u5e7f\u64ad\u63a5\u6536\u5668","text":"
      # \u6ce8\u518c\u5c4f\u5e55\u5f00\u5173\u4e8b\u4ef6\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_ON')\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_OFF')\n\n# \u7b49\u5f85\u5c4f\u5e55\u4e8b\u4ef6\nwhile True:\n    event = droid.receiveEvent().result\n    if event['name'] == 'android.intent.action.SCREEN_ON':\n        print(\"Screen turned on\")\n    elif event['name'] == 'android.intent.action.SCREEN_OFF':\n        print(\"Screen turned off\")\n
      "},{"location":"qsl4a/core/events/#_13","title":"\u4f20\u611f\u5668\u4e8b\u4ef6\u5904\u7406","text":"
      # \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u5904\u7406\u4f20\u611f\u5668\u4e8b\u4ef6\nfor _ in range(100):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'sensors':\n        data = event['data']\n        print(f\"Accel: {data['xforce']}, {data['yforce']}, {data['zforce']}\")\n\ndroid.stopSensing()\n
      "},{"location":"qsl4a/core/events/#_14","title":"\u5e38\u89c1\u4e8b\u4ef6\u7c7b\u578b","text":"\u4e8b\u4ef6\u540d\u79f0 \u63cf\u8ff0 \u6765\u6e90 sensors \u4f20\u611f\u5668\u6570\u636e\u66f4\u65b0 startSensing* location GPS \u4f4d\u7f6e\u66f4\u65b0 startLocating phone \u7535\u8bdd\u72b6\u6001\u53d8\u5316 startTrackingPhoneState signal \u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316 startTrackingSignalStrength screen \u622a\u56fe\u5c31\u7eea fullGetScreenShot dialog \u5bf9\u8bdd\u6846\u54cd\u5e94 dialogShow*"},{"location":"qsl4a/core/events/#_15","title":"\u4e8b\u4ef6\u6570\u636e\u7ed3\u6784","text":"
      {\n    'name': 'event_name',\n    'data': {\n        # \u4e8b\u4ef6\u7279\u5b9a\u6570\u636e\n    },\n    'time': 1234567890  # \u65f6\u95f4\u6233\n}\n
      "},{"location":"qsl4a/core/intent/","title":"Intent \u7cfb\u7edf","text":"

      Android Intent \u7528\u4e8e\u542f\u52a8\u6d3b\u52a8\u3001\u53d1\u9001\u5e7f\u64ad\u548c\u5e94\u7528\u95f4\u901a\u4fe1\u3002QSL4A \u901a\u8fc7 Intent \u6a21\u5757\u63d0\u4f9b\u5b8c\u6574\u7684 Intent \u652f\u6301\u3002

      "},{"location":"qsl4a/core/intent/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
      import androidhelper\ndon = androidhelper.Android()\n
      "},{"location":"qsl4a/core/intent/#intent_1","title":"Intent \u5e38\u91cf","text":"

      \u901a\u8fc7 droid.Intent \u8bbf\u95ee\uff1a

      "},{"location":"qsl4a/core/intent/#_2","title":"\u64cd\u4f5c","text":"\u5e38\u91cf \u503c \u7528\u9014 ACTION_MAIN android.intent.action.MAIN \u5e94\u7528\u5165\u53e3\u70b9 ACTION_VIEW android.intent.action.VIEW \u67e5\u770b\u5185\u5bb9 ACTION_EDIT android.intent.action.EDIT \u7f16\u8f91\u5185\u5bb9 ACTION_PICK android.intent.action.PICK \u9009\u62e9\u9879\u76ee ACTION_SEND android.intent.action.SEND \u5206\u4eab\u5185\u5bb9 ACTION_SEARCH android.intent.action.SEARCH \u641c\u7d22"},{"location":"qsl4a/core/intent/#_3","title":"\u6807\u5fd7","text":"\u5e38\u91cf \u503c \u7528\u9014 FLAG_ACTIVITY_NEW_TASK 268435456 \u542f\u52a8\u65b0\u4efb\u52a1 FLAG_ACTIVITY_CLEAR_TASK 32768 \u6e05\u9664\u4efb\u52a1\u5806\u6808 FLAG_ACTIVITY_NEW_DOCUMENT 524288 \u65b0\u6587\u6863\u6a21\u5f0f"},{"location":"qsl4a/core/intent/#_4","title":"\u9644\u52a0\u6570\u636e","text":"\u5e38\u91cf \u7528\u9014 EXTRA_TEXT \u6587\u672c\u5185\u5bb9 EXTRA_STREAM \u6587\u4ef6 URI EXTRA_SUBJECT \u4e3b\u9898\u884c EXTRA_EMAIL \u7535\u5b50\u90ae\u4ef6\u5730\u5740"},{"location":"qsl4a/core/intent/#_5","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/intent/#makeintent","title":"makeIntent()","text":"

      \u521b\u5efa Intent \u5bf9\u8c61\u3002

      makeIntent(action, uri=None, type=None, extras=None, categories=None,\n           packagename=None, classname=None, flags=None)\n

      \u53c2\u6570\uff1a - action (str): Intent \u64cd\u4f5c\uff08\u4f8b\u5982 droid.Intent.ACTION_VIEW\uff09 - uri (str, optional): \u6570\u636e URI - type (str, optional): MIME \u7c7b\u578b - extras (dict, optional): \u9644\u52a0\u6570\u636e - categories (list, optional): Intent \u7c7b\u522b - packagename (str, optional): \u76ee\u6807\u5305 - classname (str, optional): \u76ee\u6807\u7c7b - flags (int, optional): Intent \u6807\u5fd7

      \u8fd4\u56de\uff1a Intent \u5bf9\u8c61

      "},{"location":"qsl4a/core/intent/#startactivityintent","title":"startActivityIntent()","text":"

      \u4f7f\u7528 Intent \u542f\u52a8 Activity\u3002

      startActivityIntent(intent, wait=None)\n

      \u53c2\u6570\uff1a - intent: makeIntent() \u8fd4\u56de\u7684 Intent \u5bf9\u8c61 - wait (bool, optional): \u963b\u585e\u76f4\u5230\u6d3b\u52a8\u5173\u95ed

      "},{"location":"qsl4a/core/intent/#startactivityforresultintent","title":"startActivityForResultIntent()","text":"

      \u542f\u52a8\u6d3b\u52a8\u5e76\u7b49\u5f85\u7ed3\u679c\u3002

      startActivityForResultIntent(intent)\n

      \u8fd4\u56de\uff1a Activity \u7ed3\u679c

      "},{"location":"qsl4a/core/intent/#sendbroadcastintent","title":"sendBroadcastIntent()","text":"

      \u53d1\u9001\u5e7f\u64ad\u3002

      sendBroadcastIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#view","title":"view()","text":"

      \u901a\u8fc7 URI \u67e5\u770b\u5185\u5bb9\u3002

      view(uri, type=None, extras=None)\n
      "},{"location":"qsl4a/core/intent/#pick","title":"pick()","text":"

      \u4ece URI \u9009\u62e9\u5185\u5bb9\u3002

      pick(uri)\n
      "},{"location":"qsl4a/core/intent/#intent_2","title":"\u5e38\u89c1 Intent \u65b9\u6cd5)","text":""},{"location":"qsl4a/core/intent/#scanbarcode","title":"scanBarcode()","text":"

      \u542f\u52a8\u6761\u7801\u626b\u63cf\u5668\u3002

      scanBarcode()\n

      \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/core/intent/#send","title":"send()","text":"

      \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u5185\u5bb9\u3002

      send(type, content)\n

      \u53c2\u6570\uff1a - type (str): MIME \u7c7b\u578b - content (str): \u8981\u5206\u4eab\u7684\u5185\u5bb9

      "},{"location":"qsl4a/core/intent/#sendtext","title":"sendText()","text":"

      \u53d1\u9001\u6587\u672c\u5185\u5bb9\u3002

      sendText(text)\n

      \u53c2\u6570\uff1a - text (str): \u8981\u53d1\u9001\u7684\u6587\u672c

      "},{"location":"qsl4a/core/intent/#sendemail","title":"sendEmail()","text":"

      \u53d1\u9001\u7535\u5b50\u90ae\u4ef6\u3002

      sendEmail(to, subject, body, attachment=None)\n

      \u53c2\u6570\uff1a - to (str or list): \u6536\u4ef6\u4eba\u7535\u5b50\u90ae\u4ef6\u5730\u5740 - subject (str): \u7535\u5b50\u90ae\u4ef6\u4e3b\u9898 - body (str): \u7535\u5b50\u90ae\u4ef6\u6b63\u6587 - attachment (str, optional): \u9644\u4ef6\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/core/intent/#pathtouri","title":"pathToUri()","text":"

      \u5c06\u6587\u4ef6\u8def\u5f84\u8f6c\u6362\u4e3a\u5185\u5bb9 URI\u3002

      pathToUri(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5185\u5bb9 URI \u5b57\u7b26\u4e32

      "},{"location":"qsl4a/core/intent/#openfile","title":"openFile()","text":"

      \u7528\u9002\u5f53\u7684\u5e94\u7528\u7a0b\u5e8f\u6253\u5f00\u6587\u4ef6\u3002

      openFile(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u6253\u5f00\u7684\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/core/intent/#sendfile","title":"sendFile()","text":"

      \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u6587\u4ef6\u3002

      sendFile(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u53d1\u9001\u7684\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/core/intent/#getpathtype","title":"getPathType()","text":"

      \u83b7\u53d6\u6587\u4ef6\u8def\u5f84\u7684 MIME \u7c7b\u578b\u3002

      getPathType(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a MIME \u7c7b\u578b\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/core/intent/#viewmap","title":"viewMap()","text":"

      \u5728\u6307\u5b9a\u4f4d\u7f6e\u6253\u5f00\u5730\u56fe\u3002

      viewMap(latitude, longitude)\n

      \u53c2\u6570\uff1a - latitude (float): \u7eac\u5ea6 - longitude (float): \u7ecf\u5ea6

      "},{"location":"qsl4a/core/intent/#viewcontacts","title":"viewContacts()","text":"

      \u6253\u5f00\u8054\u7cfb\u4eba\u5e94\u7528\u3002

      viewContacts()\n
      "},{"location":"qsl4a/core/intent/#search","title":"search()","text":"

      \u6267\u884c\u7f51\u7edc\u641c\u7d22\u3002

      search(query)\n

      \u53c2\u6570\uff1a - query (str): \u641c\u7d22\u67e5\u8be2

      "},{"location":"qsl4a/core/intent/#viewhtml","title":"viewHtml()","text":"

      \u67e5\u770b HTML \u5185\u5bb9\u3002

      viewHtml(content, encoding=None)\n

      \u53c2\u6570\uff1a - content (str): HTML \u5185\u5bb9 - encoding (str, optional): \u5b57\u7b26\u7f16\u7801

      "},{"location":"qsl4a/core/intent/#webviewshow","title":"webViewShow()","text":"

      \u5728 WebView \u4e2d\u663e\u793a\u7f51\u9875\u5185\u5bb9\u3002\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 viewHtml\u3002

      webViewShow(url)\n

      \u53c2\u6570\uff1a - url (str): \u7f51\u9875 URL

      "},{"location":"qsl4a/core/intent/#editoropen","title":"editorOpen()","text":"

      \u6253\u5f00\u6587\u672c\u7f16\u8f91\u5668\u3002

      editorOpen(path=None, create=False)\n

      \u53c2\u6570\uff1a - path (str, optional): \u8981\u7f16\u8f91\u7684\u6587\u4ef6\u8def\u5f84 - create (bool, optional): \u5982\u679c\u4e0d\u5b58\u5728\u5219\u521b\u5efa

      "},{"location":"qsl4a/core/intent/#uri","title":"\u8f85\u52a9\u7c7b\uff1aUri","text":"

      \u521b\u5efa Intent \u7684 URI \u5bf9\u8c61\uff1a

      from androidhelper.Intent import Uri\n\nuri = Uri(\"file:///sdcard/test.txt\")\n
      "},{"location":"qsl4a/core/intent/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/intent/#_7","title":"\u6253\u5f00\u7f51\u9875","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"http://www.example.com\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_8","title":"\u5206\u4eab\u6587\u672c","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_TEXT: \"Hello from QPython!\",\n        droid.Intent.EXTRA_SUBJECT: \"Test\"\n    },\n    type=\"text/plain\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_9","title":"\u6253\u5f00\u6587\u4ef6","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"file:///sdcard/document.pdf\",\n    type=\"application/pdf\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_10","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":"
      result = droid.pickContact()\ncontact_uri = result.result\n
      "},{"location":"qsl4a/core/intent/#_11","title":"\u53d1\u9001\u7535\u5b50\u90ae\u4ef6","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_EMAIL: [\"test@example.com\"],\n        droid.Intent.EXTRA_SUBJECT: \"Hello\",\n        droid.Intent.EXTRA_TEXT: \"Message body\"\n    },\n    type=\"message/rfc822\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#_12","title":"\u6253\u5f00\u5e94\u7528","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_MAIN,\n    packagename=\"com.android.settings\",\n    classname=\"com.android.settings.Settings\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/hardware/bluetooth/","title":"\u84dd\u7259 API","text":"

      \u63a7\u5236\u84dd\u7259\u9002\u914d\u5668\u5e76\u4e0e\u84dd\u7259\u8bbe\u5907\u901a\u4fe1\u3002

      "},{"location":"qsl4a/hardware/bluetooth/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/hardware/bluetooth/#togglebluetoothstate","title":"toggleBluetoothState()","text":"

      \u6253\u5f00/\u5173\u95ed\u84dd\u7259\u3002

      toggleBluetoothState(enabled=None, prompt=True)\n

      \u53c2\u6570\uff1a - enabled (bool): True=\u5f00\uff0cFalse=\u5173\uff0cNone=\u5207\u6362 - prompt (bool): \u663e\u793a\u7528\u6237\u63d0\u793a

      "},{"location":"qsl4a/hardware/bluetooth/#checkbluetoothstate","title":"checkBluetoothState()","text":"

      \u68c0\u67e5\u84dd\u7259\u662f\u5426\u5df2\u542f\u7528\u3002

      checkBluetoothState()\n

      \u8fd4\u56de\uff1a True/False

      "},{"location":"qsl4a/hardware/bluetooth/#getlocalname","title":"GetLocalName()","text":"

      \u83b7\u53d6\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

      GetLocalName()\n
      "},{"location":"qsl4a/hardware/bluetooth/#setlocalname","title":"SetLocalName()","text":"

      \u8bbe\u7f6e\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

      SetLocalName(name)\n
      "},{"location":"qsl4a/hardware/bluetooth/#getscanmode","title":"GetScanMode()","text":"

      \u83b7\u53d6\u53ef\u53d1\u73b0\u6027\u6a21\u5f0f\u3002

      GetScanMode()\n

      \u8fd4\u56de\uff1a - -1: \u5df2\u7981\u7528 - 0: \u4e0d\u53ef\u53d1\u73b0\uff0c\u4e0d\u53ef\u8fde\u63a5 - 1: \u53ef\u8fde\u63a5\uff0c\u4e0d\u53ef\u53d1\u73b0 - 3: \u53ef\u8fde\u63a5\u4e14\u53ef\u53d1\u73b0

      "},{"location":"qsl4a/hardware/bluetooth/#makediscoverable","title":"MakeDiscoverable()","text":"

      \u4f7f\u8bbe\u5907\u53ef\u53d1\u73b0\u3002

      MakeDiscoverable(duration=300)\n

      \u53c2\u6570\uff1a - duration (int): \u53ef\u53d1\u73b0\u7684\u79d2\u6570

      "},{"location":"qsl4a/hardware/bluetooth/#_2","title":"\u53d1\u73b0","text":""},{"location":"qsl4a/hardware/bluetooth/#discoverystart","title":"DiscoveryStart()","text":"

      \u5f00\u59cb\u8bbe\u5907\u53d1\u73b0\u3002

      DiscoveryStart()\n
      "},{"location":"qsl4a/hardware/bluetooth/#discoverycancel","title":"DiscoveryCancel()","text":"

      \u53d6\u6d88\u53d1\u73b0\u3002

      DiscoveryCancel()\n
      "},{"location":"qsl4a/hardware/bluetooth/#getreceiveddevices","title":"GetReceivedDevices()","text":"

      \u83b7\u53d6\u53d1\u73b0\u7684\u8bbe\u5907\u3002

      GetReceivedDevices()\n

      \u8fd4\u56de\uff1a \u8bbe\u5907\u4fe1\u606f\u5b57\u5178\u5217\u8868

      "},{"location":"qsl4a/hardware/bluetooth/#getbondeddevices","title":"GetBondedDevices()","text":"

      \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\u3002

      GetBondedDevices()\n

      \u8fd4\u56de\uff1a \u914d\u5bf9\u8bbe\u5907\u4fe1\u606f\u5217\u8868

      "},{"location":"qsl4a/hardware/bluetooth/#_3","title":"\u8fde\u63a5","text":""},{"location":"qsl4a/hardware/bluetooth/#connect","title":"Connect()","text":"

      \u8fde\u63a5\u5230\u8bbe\u5907\u3002

      Connect(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", address=None)\n

      \u53c2\u6570\uff1a - uuid (str): \u670d\u52a1 UUID - address (str): \u8bbe\u5907\u5730\u5740\uff08None = \u663e\u793a\u9009\u62e9\u5668\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/hardware/bluetooth/#accept","title":"Accept()","text":"

      \u63a5\u53d7\u4f20\u5165\u8fde\u63a5\u3002

      Accept(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", timeout=0)\n
      "},{"location":"qsl4a/hardware/bluetooth/#activeconnections","title":"ActiveConnections()","text":"

      \u68c0\u67e5\u6d3b\u52a8\u8fde\u63a5\u3002

      ActiveConnections()\n
      "},{"location":"qsl4a/hardware/bluetooth/#stop","title":"Stop()","text":"

      \u65ad\u5f00\u8fde\u63a5\u3002

      Stop(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#_4","title":"\u901a\u4fe1","text":""},{"location":"qsl4a/hardware/bluetooth/#write","title":"Write()","text":"

      \u53d1\u9001 ASCII \u6570\u636e\u3002

      Write(ascii, connID=\"\")\n
      "},{"location":"qsl4a/hardware/bluetooth/#writebinary","title":"WriteBinary()","text":"

      \u53d1\u9001\u4e8c\u8fdb\u5236\u6570\u636e\uff08base64 \u7f16\u7801\uff09\u3002

      WriteBinary(base64, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#read","title":"Read()","text":"

      \u8bfb\u53d6 ASCII \u6570\u636e\u3002

      Read(bufferSize=4096, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readbinary","title":"ReadBinary()","text":"

      \u8bfb\u53d6\u4e8c\u8fdb\u5236\u6570\u636e\u3002

      ReadBinary(bufferSize=4096, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readline","title":"ReadLine()","text":"

      \u8bfb\u53d6\u4e00\u884c\u3002

      ReadLine(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readready","title":"ReadReady()","text":"

      \u68c0\u67e5\u662f\u5426\u6709\u53ef\u7528\u6570\u636e\u3002

      ReadReady(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u7528\u84dd\u7259\ndroid.toggleBluetoothState(True)\n\n# \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\ndevices = droid.GetBondedDevices().result\nfor dev in devices:\n    print(f\"{dev['name']}: {dev['address']}\")\n\n# \u8fde\u63a5\u5230\u8bbe\u5907\ndroid.Connect(address=\"00:11:22:33:44:55\")\n\n# \u53d1\u9001\u6570\u636e\ndroid.Write(\"Hello Bluetooth!\")\n\n# \u8bfb\u53d6\u54cd\u5e94\ndata = droid.Read(1024).result\n
      "},{"location":"qsl4a/hardware/camera/","title":"\u76f8\u673a API","text":"

      \u62cd\u6444\u7167\u7247\u548c\u5f55\u5236\u89c6\u9891\u3002

      "},{"location":"qsl4a/hardware/camera/#_1","title":"\u7167\u7247\u62cd\u6444","text":""},{"location":"qsl4a/hardware/camera/#takepicture","title":"takePicture()","text":"

      \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u6444\u7167\u7247\u3002

      takePicture(path=None)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8fd4\u56de\u56fe\u50cf\u6570\u636e

      \u8fd4\u56de\uff1a \u56fe\u50cf\u8def\u5f84\u6216\u56fe\u50cf\u6570\u636e

      "},{"location":"qsl4a/hardware/camera/#cameracapturepicture","title":"cameraCapturePicture()","text":"

      \u4f7f\u7528\u9ad8\u7ea7\u76f8\u673a\u63a7\u5236\u62cd\u6444\u7167\u7247\u3002

      cameraCapturePicture(targetPath=None, cameraId=0, useAutoFocus=True)\n

      \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - useAutoFocus (bool): \u542f\u7528\u81ea\u52a8\u5bf9\u7126

      \u8fd4\u56de\uff1a \u62cd\u6444\u7684\u56fe\u50cf\u8def\u5f84

      "},{"location":"qsl4a/hardware/camera/#camerasettorchmode","title":"cameraSetTorchMode()","text":"

      \u63a7\u5236\u76f8\u673a\u95ea\u5149\u706f/\u624b\u7535\u7b52\u3002

      cameraSetTorchMode(enabled)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u6253\u5f00\uff0cFalse \u5173\u95ed

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/hardware/camera/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

      \u622a\u56fe\u3002

      imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

      "},{"location":"qsl4a/hardware/camera/#_2","title":"\u89c6\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#takevideo","title":"takeVideo()","text":"

      \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\u3002

      takeVideo(path=None, quality=1)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-4\uff09 - 0: 160x120 - 1: 320x240 - 2: 352x288 - 3: 640x480 - 4: 800x480

      "},{"location":"qsl4a/hardware/camera/#recordercapturevideo","title":"recorderCaptureVideo()","text":"

      \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\u3002

      recorderCaptureVideo(targetPath=None, duration=10, cameraId=0, quality=8)\n

      \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - duration (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a10\uff09 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-8\uff0c\u8d8a\u9ad8\u8d8a\u597d\uff09

      \u8fd4\u56de\uff1a \u89c6\u9891\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/hardware/camera/#recordaudio","title":"recordAudio()","text":"

      \u5f55\u5236\u97f3\u9891\u3002

      recordAudio()\n

      \u8fd4\u56de\uff1a \u97f3\u9891\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/hardware/camera/#_3","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

      \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\u3002

      recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

      \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\uff09 - targetPixels (int): \u5206\u8fa8\u7387 - frameRate (int): FPS - bitRate (int): \u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa - autoStart (bool): \u7acb\u5373\u5f00\u59cb

      "},{"location":"qsl4a/hardware/camera/#recorderstart","title":"recorderStart()","text":"

      \u5f00\u59cb\u5f55\u5236\u3002

      recorderStart()\n
      "},{"location":"qsl4a/hardware/camera/#recorderpause","title":"recorderPause()","text":"

      \u6682\u505c\u5f55\u5236\u3002

      recorderPause()\n
      "},{"location":"qsl4a/hardware/camera/#recorderresume","title":"recorderResume()","text":"

      \u6062\u590d\u5f55\u5236\u3002

      recorderResume()\n
      "},{"location":"qsl4a/hardware/camera/#_4","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/camera/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

      \u5f00\u59cb\u97f3\u91cf\u68c0\u6d4b\u3002

      recorderSoundVolumeDetect(interval=100)\n
      "},{"location":"qsl4a/hardware/camera/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

      \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

      recorderSoundVolumeGetDb()\n
      "},{"location":"qsl4a/hardware/camera/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u7167\nphoto_path = droid.takePicture(\"/sdcard/photo.jpg\").result\nprint(f\"Photo saved: {photo_path}\")\n\n# \u4f7f\u7528\u524d\u7f6e\u76f8\u673a\u548c\u81ea\u52a8\u5bf9\u7126\u62cd\u7167\ncamera_path = droid.cameraCapturePicture(\"/sdcard/selfie.jpg\", cameraId=1, useAutoFocus=True).result\nprint(f\"Front camera photo: {camera_path}\")\n\n# \u63a7\u5236\u95ea\u5149\u706f\ndroid.cameraSetTorchMode(True)  # \u6253\u5f00\u95ea\u5149\u706f\n\n# \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\nvideo_path = droid.takeVideo(\"/sdcard/video.mp4\", quality=3).result\nprint(f\"Video saved: {video_path}\")\n\n# \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\nvideo_path = droid.recorderCaptureVideo(\"/sdcard/movie.mp4\", duration=30, cameraId=0, quality=8).result\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n
      "},{"location":"qsl4a/hardware/recorder/","title":"\u97f3\u9891\u5f55\u5236 API","text":"

      \u4ece\u9ea6\u514b\u98ce\u548c\u8bbe\u5907\u5c4f\u5e55\u5f55\u5236\u97f3\u9891\u3002

      "},{"location":"qsl4a/hardware/recorder/#_1","title":"\u97f3\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recordaudio","title":"recordAudio()","text":"

      \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\u3002

      recordAudio()\n

      \u8fd4\u56de\uff1a \u5f55\u5236\u7684\u97f3\u9891\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/hardware/recorder/#recorderstartmicrophone","title":"recorderStartMicrophone()","text":"

      \u5f00\u59cb\u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\u3002

      recorderStartMicrophone(targetPath=None)\n

      \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u5f55\u5236\u7684\u8def\u5f84

      "},{"location":"qsl4a/hardware/recorder/#_2","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

      \u5f00\u59cb\u5e26\u97f3\u9891\u7684\u5c4f\u5e55\u5f55\u5236\u3002

      recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

      \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\u97f3\u9891\uff09 - targetPixels (int): \u76ee\u6807\u5206\u8fa8\u7387\uff08\u50cf\u7d20\uff09 - frameRate (int): \u6bcf\u79d2\u5e27\u6570\uff08\u9ed8\u8ba4\uff1a30\uff09 - bitRate (int): \u89c6\u9891\u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa\u89c6\u9891 - autoStart (bool): \u7acb\u5373\u5f00\u59cb\u5f55\u5236

      \u8fd4\u56de\uff1a \u64cd\u4f5c\u7ed3\u679c

      "},{"location":"qsl4a/hardware/recorder/#recorderstart","title":"recorderStart()","text":"

      \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\uff08\u5f53 autoStart=False \u65f6\uff09\u3002

      recorderStart()\n
      "},{"location":"qsl4a/hardware/recorder/#recorderpause","title":"recorderPause()","text":"

      \u6682\u505c\u6b63\u5728\u8fdb\u884c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

      recorderPause()\n
      "},{"location":"qsl4a/hardware/recorder/#recorderresume","title":"recorderResume()","text":"

      \u6062\u590d\u6682\u505c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

      recorderResume()\n
      "},{"location":"qsl4a/hardware/recorder/#_3","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/recorder/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

      \u5f00\u59cb\u76d1\u63a7\u97f3\u91cf\u7ea7\u522b\u3002

      recorderSoundVolumeDetect(interval=100)\n

      \u53c2\u6570\uff1a - interval (int): \u68c0\u6d4b\u95f4\u9694\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a100\uff09

      "},{"location":"qsl4a/hardware/recorder/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

      \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

      recorderSoundVolumeGetDb()\n

      \u8fd4\u56de\uff1a \u5f53\u524d\u97f3\u91cf\u7ea7\u522b\uff08dB\uff09

      "},{"location":"qsl4a/hardware/recorder/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\nprint(\"Recording audio...\")\naudio_path = droid.recordAudio().result\nprint(f\"Saved to: {audio_path}\")\n\n# \u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\ndroid.recorderStartMicrophone(\"/sdcard/my_recording.mp3\")\ntime.sleep(5)\ndroid.recorderStop()\n\n# \u5e26\u97f3\u9891\u5f55\u5236\u5c4f\u5e55\nprint(\"Starting screen recording...\")\ndroid.recorderStartScreenRecord(\n    path=\"/sdcard/screen_record.mp4\",\n    audio=1,\n    frameRate=30,\n    autoStart=True\n)\ntime.sleep(10)\ndroid.recorderStop()\n\n# \u76d1\u63a7\u97f3\u91cf\ndroid.recorderSoundVolumeDetect(interval=100)\ntime.sleep(3)\nvolume = droid.recorderSoundVolumeGetDb().result\nprint(f\"Current volume: {volume} dB\")\n
      "},{"location":"qsl4a/hardware/usbserial/","title":"USB \u4e3b\u673a\u4e32\u884c API","text":"

      \u4e0e USB \u4e32\u884c\u8bbe\u5907\u901a\u4fe1\uff08\u9700\u8981 USB OTG \u652f\u6301\u548c Android 3.1+\uff09\u3002

      "},{"location":"qsl4a/hardware/usbserial/#usb","title":"USB \u4e32\u884c\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialopen","title":"usbHostSerialOpen()","text":"

      \u6253\u5f00\u4e0e USB \u4e32\u884c\u8bbe\u5907\u7684\u8fde\u63a5\u3002

      usbHostSerialOpen(device, baudRate=9600)\n

      \u53c2\u6570\uff1a - device (str): USB \u8bbe\u5907\u8def\u5f84\u6216\u6807\u8bc6\u7b26 - baudRate (int): \u6ce2\u7279\u7387\uff08\u9ed8\u8ba4\uff1a9600\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u6253\u5f00\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialclose","title":"usbHostSerialClose()","text":"

      \u5173\u95ed USB \u4e32\u884c\u8fde\u63a5\u3002

      usbHostSerialClose()\n
      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialread","title":"usbHostSerialRead()","text":"

      \u4ece USB \u4e32\u884c\u8bfb\u53d6\u6570\u636e\u3002

      usbHostSerialRead(bufferSize=1024)\n

      \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570\uff08\u9ed8\u8ba4\uff1a1024\uff09

      \u8fd4\u56de\uff1a \u8bfb\u53d6\u7684\u6570\u636e\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwrite","title":"usbHostSerialWrite()","text":"

      \u5411 USB \u4e32\u884c\u5199\u5165\u6570\u636e\u3002

      usbHostSerialWrite(data)\n

      \u53c2\u6570\uff1a - data (str): \u8981\u5199\u5165\u7684\u5b57\u7b26\u4e32\u6570\u636e

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialavailable","title":"usbHostSerialAvailable()","text":"

      \u68c0\u67e5\u662f\u5426\u6709\u53ef\u8bfb\u53d6\u7684\u6570\u636e\u3002

      usbHostSerialAvailable()\n

      \u8fd4\u56de\uff1a \u53ef\u7528\u5b57\u8282\u6570

      "},{"location":"qsl4a/hardware/usbserial/#_1","title":"\u914d\u7f6e\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetbaudrate","title":"usbHostSerialSetBaudRate()","text":"

      \u8bbe\u7f6e\u6ce2\u7279\u7387\u3002

      usbHostSerialSetBaudRate(baudRate)\n

      \u53c2\u6570\uff1a - baudRate (int): \u6ce2\u7279\u7387

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetdatabits","title":"usbHostSerialSetDataBits()","text":"

      \u8bbe\u7f6e\u6570\u636e\u4f4d\uff085\u30016\u30017 \u6216 8\uff09\u3002

      usbHostSerialSetDataBits(dataBits)\n

      \u53c2\u6570\uff1a - dataBits (int): \u6570\u636e\u4f4d\uff085-8\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetstopbits","title":"usbHostSerialSetStopBits()","text":"

      \u8bbe\u7f6e\u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09\u3002

      usbHostSerialSetStopBits(stopBits)\n

      \u53c2\u6570\uff1a - stopBits (float): \u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetparity","title":"usbHostSerialSetParity()","text":"

      \u8bbe\u7f6e\u6821\u9a8c\u4f4d\uff08\u65e0\u3001\u5947\u3001\u5076\u3001\u6807\u8bb0\u3001\u7a7a\u683c\uff09\u3002

      usbHostSerialSetParity(parity)\n

      \u53c2\u6570\uff1a - parity (str): \u6821\u9a8c\u6a21\u5f0f\uff08'none'\u3001'odd'\u3001'even'\u3001'mark'\u3001'space'\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetflowcontrol","title":"usbHostSerialSetFlowControl()","text":"

      \u8bbe\u7f6e\u6d41\u63a7\u5236\uff08\u65e0\u3001\u786c\u4ef6\u3001\u8f6f\u4ef6\uff09\u3002

      usbHostSerialSetFlowControl(flowControl)\n

      \u53c2\u6570\uff1a - flowControl (str): \u6d41\u63a7\u5236\u6a21\u5f0f\uff08'none'\u3001'hardware'\u3001'software'\uff09

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialreadhex","title":"usbHostSerialReadHex()","text":"

      \u4ee5\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u8bfb\u53d6\u6570\u636e\u3002

      usbHostSerialReadHex(bufferSize=1024)\n

      \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570

      \u8fd4\u56de\uff1a \u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwritehex","title":"usbHostSerialWriteHex()","text":"

      \u4ece\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u5199\u5165\u6570\u636e\u3002

      usbHostSerialWriteHex(hexString)\n

      \u53c2\u6570\uff1a - hexString (str): \u8981\u5199\u5165\u7684\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/hardware/usbserial/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6253\u5f00 USB \u4e32\u884c\u8fde\u63a5\nif droid.usbHostSerialOpen(\"/dev/bus/usb/001/001\", 115200).result:\n    print(\"USB serial opened\")\n\n    # \u5199\u5165\u6570\u636e\n    droid.usbHostSerialWrite(\"AT\\r\")\n\n    # \u8bfb\u53d6\u54cd\u5e94\n    response = droid.usbHostSerialRead(1024).result\n    print(f\"Response: {response}\")\n\n    # \u6216\u4f7f\u7528\u5341\u516d\u8fdb\u5236\n    droid.usbHostSerialWriteHex(\"41540D0A\")  # \"AT\\r\\n\"\n\n    # \u5173\u95ed\u8fde\u63a5\n    droid.usbHostSerialClose()\n

      \u6ce8\u610f\uff1a USB \u4e32\u884c\u9700\u8981\uff1a - Android 3.1+ (API 12) - USB OTG \u7ebf/\u9002\u914d\u5668 - \u8bbe\u5907\u4e0a\u7684 USB \u4e3b\u673a\u6a21\u5f0f\u652f\u6301 - \u517c\u5bb9\u7684\u4e32\u884c\u8bbe\u5907

      "},{"location":"qsl4a/hardware/webcam/","title":"\u7f51\u7edc\u6444\u50cf\u5934 API","text":"

      \u4f7f\u7528 MJPEG \u4ece\u8bbe\u5907\u76f8\u673a\u6d41\u5f0f\u4f20\u8f93\u89c6\u9891\u3002

      "},{"location":"qsl4a/hardware/webcam/#mjpeg","title":"MJPEG \u6d41\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#webcamstart","title":"webcamStart()","text":"

      \u4ece\u7f51\u7edc\u6444\u50cf\u5934\u542f\u52a8 MJPEG \u6d41\u3002

      webcamStart(resolutionLevel=0, jpegQuality=20, port=0)\n

      \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf 1-100\uff08\u9ed8\u8ba4\uff1a20\uff09 - port (int): \u7aef\u53e3\u53f7\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\uff09

      \u8fd4\u56de\uff1a \u6d41\u7684 (\u5730\u5740, \u7aef\u53e3) \u5143\u7ec4

      "},{"location":"qsl4a/hardware/webcam/#webcamadjustquality","title":"webcamAdjustQuality()","text":"

      \u8c03\u6574\u6d3b\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u7684\u8d28\u91cf\u3002

      webcamAdjustQuality(resolutionLevel=0, jpegQuality=20)\n

      \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b - jpegQuality (int): JPEG \u8d28\u91cf 1-100

      "},{"location":"qsl4a/hardware/webcam/#webcamstop","title":"webcamStop()","text":"

      \u505c\u6b62\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u3002

      webcamStop()\n
      "},{"location":"qsl4a/hardware/webcam/#_1","title":"\u76f8\u673a\u9884\u89c8\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#camerastartpreview","title":"cameraStartPreview()","text":"

      \u5f00\u59cb\u5e26\u4e8b\u4ef6\u751f\u6210\u7684\u76f8\u673a\u9884\u89c8\u6a21\u5f0f\u3002

      cameraStartPreview(resolutionLevel=0, jpegQuality=20, filepath=None)\n

      \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf\uff08\u9ed8\u8ba4\uff1a20\uff09 - filepath (str, optional): \u4fdd\u5b58\u9884\u89c8\u5e27\u7684\u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      \u6ce8\u610f\uff1a \u751f\u6210\u5e26\u6709\u5e27\u6570\u636e\u7684 'preview' \u4e8b\u4ef6\u3002

      "},{"location":"qsl4a/hardware/webcam/#camerastoppreview","title":"cameraStopPreview()","text":"

      \u505c\u6b62\u76f8\u673a\u9884\u89c8\u3002

      cameraStopPreview()\n
      "},{"location":"qsl4a/hardware/webcam/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\nstream_info = droid.webcamStart(\n    resolutionLevel=0,\n    jpegQuality=30,\n    port=8080\n).result\nprint(f\"Stream available at {stream_info[0]}:{stream_info[1]}\")\n\n# \u6d41\u5f0f\u4f20\u8f93\u65f6\u8c03\u6574\u8d28\u91cf\ntime.sleep(5)\ndroid.webcamAdjustQuality(resolutionLevel=1, jpegQuality=50)\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.webcamStop()\n\n# \u6216\u4f7f\u7528\u9884\u89c8\u6a21\u5f0f\nprint(\"Starting preview...\")\ndroid.cameraStartPreview()\n\n# \u7b49\u5f85\u9884\u89c8\u4e8b\u4ef6\nfor i in range(10):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'preview':\n        print(f\"Got preview frame: {event['data']}\")\n\ndroid.cameraStopPreview()\n
      "},{"location":"qsl4a/media/image/","title":"\u56fe\u50cf\u5904\u7406 API","text":"

      \u538b\u7f29\u548c\u5904\u7406\u56fe\u50cf\u3002

      "},{"location":"qsl4a/media/image/#_1","title":"\u56fe\u50cf\u538b\u7f29","text":""},{"location":"qsl4a/media/image/#imagecompress","title":"imageCompress()","text":"

      \u538b\u7f29\u56fe\u50cf\u6587\u4ef6\u3002

      imageCompress(srcPath, destPath, targetByteSize=0, targetWidth=0, targetHeight=0)\n

      \u53c2\u6570\uff1a - srcPath (str): \u6e90\u56fe\u50cf\u8def\u5f84 - destPath (str): \u8f93\u51fa\u8def\u5f84 - targetByteSize (int): \u76ee\u6807\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff080 = \u65e0\u9650\u5236\uff09 - targetWidth (int): \u76ee\u6807\u5bbd\u5ea6\uff080 = \u539f\u59cb\uff09 - targetHeight (int): \u76ee\u6807\u9ad8\u5ea6\uff080 = \u539f\u59cb\uff09

      \u8fd4\u56de\uff1a \u538b\u7f29\u540e\u7684\u56fe\u50cf\u8def\u5f84

      "},{"location":"qsl4a/media/image/#_2","title":"\u622a\u56fe","text":""},{"location":"qsl4a/media/image/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

      \u622a\u53d6\u5c4f\u5e55\u3002

      imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

      \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

      \u8fd4\u56de\uff1a \u622a\u56fe\u8def\u5f84

      "},{"location":"qsl4a/media/image/#_3","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/image/#videoplay","title":"videoPlay()","text":"

      \u5728\u5168\u5c4f\u6a21\u5f0f\u4e0b\u64ad\u653e\u89c6\u9891\u6587\u4ef6\u3002

      videoPlay(path, wait=True)\n

      \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

      "},{"location":"qsl4a/media/image/#_4","title":"\u6761\u7801\u626b\u63cf","text":""},{"location":"qsl4a/media/image/#scanbarcodefromimage","title":"scanBarcodeFromImage()","text":"

      \u4ece\u56fe\u50cf\u6587\u4ef6\u626b\u63cf\u6761\u7801/\u4e8c\u7ef4\u7801\u3002

      scanBarcodeFromImage(path, compressRatio=0, x=0, y=0, width=0, height=0)\n

      \u53c2\u6570\uff1a - path (str): \u56fe\u50cf\u6587\u4ef6\u8def\u5f84 - compressRatio (int): \u538b\u7f29\u6bd4\uff080 = \u4e0d\u538b\u7f29\uff09 - x, y, width, height (int): \u8981\u626b\u63cf\u7684\u533a\u57df\uff080 = \u5b8c\u6574\u56fe\u50cf\uff09

      \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5185\u5bb9

      "},{"location":"qsl4a/media/image/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n\n# \u538b\u7f29\u56fe\u50cf\ncompressed = droid.imageCompress(\n    \"/sdcard/large_photo.jpg\",\n    \"/sdcard/compressed.jpg\",\n    targetByteSize=102400,  # \u76ee\u6807\u7ea6 100KB\n    targetWidth=1920,\n    targetHeight=1080\n).result\nprint(f\"Saved: {compressed}\")\n\n# \u64ad\u653e\u89c6\u9891\nvideo_path = \"/sdcard/movie.mp4\"\ndroid.videoPlay(video_path, wait=True)\n\n# \u4ece\u56fe\u50cf\u626b\u63cf\u6761\u7801\nresult = droid.scanBarcodeFromImage(\"/sdcard/qr_code.png\").result\nprint(f\"Barcode: {result}\")\n
      "},{"location":"qsl4a/media/mediaplayer/","title":"\u5a92\u4f53\u64ad\u653e\u5668 API","text":"

      \u63a7\u5236\u97f3\u9891\u548c\u89c6\u9891\u64ad\u653e\u3002

      "},{"location":"qsl4a/media/mediaplayer/#_1","title":"\u64ad\u653e\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplay","title":"mediaPlay()","text":"

      \u64ad\u653e\u5a92\u4f53\u6587\u4ef6\u3002

      mediaPlay(url, tag=\"default\", play=True)\n

      \u53c2\u6570\uff1a - url (str): \u5a92\u4f53\u6587\u4ef6\u8def\u5f84\u6216 URL - tag (str): \u64ad\u653e\u5668\u6807\u8bc6\u7b26 - play (bool): \u81ea\u52a8\u5f00\u59cb\u64ad\u653e

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaystart","title":"mediaPlayStart()","text":"

      \u5f00\u59cb\u64ad\u653e\u3002

      mediaPlayStart(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplaypause","title":"mediaPlayPause()","text":"

      \u6682\u505c\u64ad\u653e\u3002

      mediaPlayPause(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplayclose","title":"mediaPlayClose()","text":"

      \u5173\u95ed\u64ad\u653e\u5668\u3002

      mediaPlayClose(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplayseek","title":"mediaPlaySeek()","text":"

      \u8df3\u8f6c\u5230\u4f4d\u7f6e\u3002

      mediaPlaySeek(msec, tag=\"default\")\n

      \u53c2\u6570\uff1a - msec (int): \u4f4d\u7f6e\uff08\u6beb\u79d2\uff09

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaysetlooping","title":"mediaPlaySetLooping()","text":"

      \u8bbe\u7f6e\u5faa\u73af\u6a21\u5f0f\u3002

      mediaPlaySetLooping(enabled, tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#_2","title":"\u64ad\u653e\u5668\u4fe1\u606f","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplayinfo","title":"mediaPlayInfo()","text":"

      \u83b7\u53d6\u64ad\u653e\u4fe1\u606f\u3002

      mediaPlayInfo(tag=\"default\")\n

      \u8fd4\u56de\uff1a \u5305\u542b\u65f6\u957f\u3001\u4f4d\u7f6e\u7b49\u7684\u5b57\u5178

      "},{"location":"qsl4a/media/mediaplayer/#mediaisplaying","title":"mediaIsPlaying()","text":"

      \u68c0\u67e5\u662f\u5426\u6b63\u5728\u64ad\u653e\u3002

      mediaIsPlaying(tag=\"default\")\n

      \u8fd4\u56de\uff1a True/False

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaylist","title":"mediaPlayList()","text":"

      \u5217\u51fa\u6d3b\u52a8\u64ad\u653e\u5668\u3002

      mediaPlayList()\n
      "},{"location":"qsl4a/media/mediaplayer/#_3","title":"\u97f3\u91cf\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#getmediavolume","title":"getMediaVolume()","text":"

      \u83b7\u53d6\u5a92\u4f53\u97f3\u91cf\u3002

      getMediaVolume()\n

      \u8fd4\u56de\uff1a \u97f3\u91cf\u7ea7\u522b\uff080-15\uff09

      "},{"location":"qsl4a/media/mediaplayer/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

      getMaxMediaVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#getringervolume","title":"getRingerVolume()","text":"

      \u83b7\u53d6\u94c3\u58f0\u97f3\u91cf\u3002

      getRingerVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

      getMaxRingerVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#_4","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/mediaplayer/#videoplay","title":"videoPlay()","text":"

      \u5168\u5c4f\u64ad\u653e\u89c6\u9891\u3002

      videoPlay(path, wait=True)\n

      \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210

      "},{"location":"qsl4a/media/mediaplayer/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u64ad\u653e\u97f3\u9891\ndroid.mediaPlay(\"/sdcard/music.mp3\", tag=\"music\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.mediaIsPlaying(\"music\").result:\n    info = droid.mediaPlayInfo(\"music\").result\n    print(f\"Playing: {info}\")\n\n# \u8df3\u8f6c\u5230 30 \u79d2\ndroid.mediaPlaySeek(30000, \"music\")\n\n# \u5173\u95ed\ndroid.mediaPlayClose(\"music\")\n\n# \u64ad\u653e\u89c6\u9891\ndroid.videoPlay(\"/sdcard/movie.mp4\", wait=True)\n
      "},{"location":"qsl4a/special/cipher/","title":"\u5bc6\u7801 API","text":"

      \u7528\u4e8e\u5b89\u5168\u6570\u636e\u5b58\u50a8\u7684\u52a0\u5bc6\u548c\u89e3\u5bc6\u5de5\u5177\u3002

      "},{"location":"qsl4a/special/cipher/#_1","title":"\u521d\u59cb\u5316","text":""},{"location":"qsl4a/special/cipher/#cipherinit","title":"cipherInit()","text":"

      \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u548c\u7b97\u6cd5\u521d\u59cb\u5316\u5bc6\u7801\u5668\u3002

      cipherInit(key, algorithm=\"AES/CBC/PKCS5Padding\", encodingFormat=\"\", initialVector=\"\")\n

      \u53c2\u6570\uff1a - key (str or bytes): \u52a0\u5bc6\u5bc6\u94a5 - algorithm (str): \u5bc6\u7801\u7b97\u6cd5\uff08\u9ed8\u8ba4\uff1a\"AES/CBC/PKCS5Padding\"\uff09 - encodingFormat (str): \u7f16\u7801\u683c\u5f0f - initialVector (str or bytes): \u52a0\u5bc6\u7684\u521d\u59cb\u5411\u91cf

      \u8fd4\u56de\uff1a \u521d\u59cb\u5316\u7ed3\u679c

      \u6ce8\u610f\uff1a \u5fc5\u987b\u5728\u4efb\u4f55\u52a0\u5bc6/\u89e3\u5bc6\u64cd\u4f5c\u4e4b\u524d\u8c03\u7528\u3002

      "},{"location":"qsl4a/special/cipher/#_2","title":"\u52a0\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#encryptstring","title":"encryptString()","text":"

      \u52a0\u5bc6\u5b57\u7b26\u4e32\u3002

      encryptString(plainText)\n

      \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c

      \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/special/cipher/#encryptbytes","title":"encryptBytes()","text":"

      \u52a0\u5bc6\u5b57\u8282\u6570\u636e\u3002

      encryptBytes(data)\n

      \u53c2\u6570\uff1a - data (bytes): \u8981\u52a0\u5bc6\u7684\u6570\u636e

      \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u8282

      "},{"location":"qsl4a/special/cipher/#encryptstringtofile","title":"encryptStringToFile()","text":"

      \u52a0\u5bc6\u5b57\u7b26\u4e32\u5230\u6587\u4ef6\u3002

      encryptStringToFile(plainText, filePath)\n

      \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c - filePath (str): \u8f93\u51fa\u6587\u4ef6\u8def\u5f84

      "},{"location":"qsl4a/special/cipher/#encryptbytestofile","title":"encryptBytesToFile()","text":"

      \u52a0\u5bc6\u5b57\u8282\u5230\u6587\u4ef6\u3002

      encryptBytesToFile(data, filePath)\n
      "},{"location":"qsl4a/special/cipher/#_3","title":"\u89e3\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#decryptstring","title":"decryptString()","text":"

      \u89e3\u5bc6\u4e3a\u5b57\u7b26\u4e32\u3002

      decryptString(cipherText)\n

      \u53c2\u6570\uff1a - cipherText (str): \u52a0\u5bc6\u7684\u6587\u672c

      \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u7b26\u4e32

      "},{"location":"qsl4a/special/cipher/#decryptbytes","title":"decryptBytes()","text":"

      \u89e3\u5bc6\u4e3a\u5b57\u8282\u3002

      decryptBytes(data)\n

      \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u8282

      "},{"location":"qsl4a/special/cipher/#decryptfiletostring","title":"decryptFileToString()","text":"

      \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u7b26\u4e32\u3002

      decryptFileToString(filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryptfiletobytes","title":"decryptFileToBytes()","text":"

      \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u8282\u3002

      decryptFileToBytes(filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryptfile","title":"decryptFile()","text":"

      \u89e3\u5bc6\u6587\u4ef6\u5230\u6587\u4ef6\u3002

      decryptFile(srcPath, destPath)\n
      "},{"location":"qsl4a/special/cipher/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u521d\u59cb\u5316\u5bc6\u7801\u5668\ndroid.cipherInit(\"my_secret_key_1234\")\n\n# \u52a0\u5bc6\u5b57\u7b26\u4e32\nencrypted = droid.encryptString(\"Secret message!\").result\nprint(f\"Encrypted: {encrypted}\")\n\n# \u89e3\u5bc6\u5b57\u7b26\u4e32\ndecrypted = droid.decryptString(encrypted).result\nprint(f\"Decrypted: {decrypted}\")\n\n# \u52a0\u5bc6\u5230\u6587\u4ef6\ndroid.encryptStringToFile(\"My secret data\", \"/sdcard/secret.dat\")\n\n# \u4ece\u6587\u4ef6\u89e3\u5bc6\ndata = droid.decryptFileToString(\"/sdcard/secret.dat\").result\nprint(data)\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u7b97\u6cd5\u548c IV \u521d\u59cb\u5316\ndroid.cipherInit(\n    key=\"my_key\",\n    algorithm=\"AES/CBC/PKCS5Padding\",\n    initialVector=\"0123456789abcdef\"\n)\n
      "},{"location":"qsl4a/special/pgptai/","title":"PGPT AI API","text":"

      \u8bed\u97f3\u8f6c\u6587\u672c\u548c AI \u670d\u52a1\u96c6\u6210\u3002

      "},{"location":"qsl4a/special/pgptai/#_1","title":"\u5148\u51b3\u6761\u4ef6","text":"
      pip install pgptAI\n
      "},{"location":"qsl4a/special/pgptai/#_2","title":"\u8bed\u97f3\u8bc6\u522b","text":""},{"location":"qsl4a/special/pgptai/#speechtotext","title":"speechToText()","text":"

      \u5c06\u8bed\u97f3\u8f6c\u6362\u4e3a\u6587\u672c\u3002

      speechToText(RecordSecond=10, AmrFile=None, Language=None)\n

      \u53c2\u6570\uff1a - RecordSecond (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09 - AmrFile (str, optional): \u73b0\u6709\u97f3\u9891\u6587\u4ef6\u8def\u5f84 - Language (str, optional): \u8bed\u8a00\u4ee3\u7801\uff08'en'\u3001'zh'\uff09

      \u8fd4\u56de\uff1a \u8f6c\u5f55\u7684\u6587\u672c

      "},{"location":"qsl4a/special/pgptai/#_3","title":"\u6587\u672c\u8f6c\u8bed\u97f3","text":""},{"location":"qsl4a/special/pgptai/#texttospeech","title":"textToSpeech()","text":"

      \u5c06\u6587\u672c\u8f6c\u6362\u4e3a\u8bed\u97f3\u5e76\u53ef\u9009\u5730\u64ad\u653e\u3002

      textToSpeech(Text, AutoPlay=True, WavFile=None, VoiceName=None)\n

      \u53c2\u6570\uff1a - Text (str): \u8981\u8f6c\u6362\u4e3a\u8bed\u97f3\u7684\u6587\u672c - AutoPlay (bool): \u81ea\u52a8\u64ad\u653e\u751f\u6210\u7684\u97f3\u9891\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - WavFile (str, optional): \u4fdd\u5b58 WAV \u6587\u4ef6\u7684\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u4e34\u65f6\u6587\u4ef6 - VoiceName (str, optional): \u8981\u4f7f\u7528\u7684\u8bed\u97f3\u540d\u79f0\uff08\u4f8b\u5982 'en-US-JennyNeural'\u3001'zh-CN-XiaoxiaoNeural'\uff09

      \u8fd4\u56de\uff1a \u5305\u542b\u8bed\u97f3\u5408\u6210\u7ed3\u679c\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - text: \u8f93\u5165\u6587\u672c - url: \u4e0b\u8f7d\u97f3\u9891\u6587\u4ef6\u7684 URL - WavFile: \u4fdd\u5b58\u7684 WAV \u6587\u4ef6\u8def\u5f84\uff08\u5982\u679c\u672c\u5730\u4fdd\u5b58\uff09

      "},{"location":"qsl4a/special/pgptai/#_4","title":"\u914d\u7f6e","text":"

      API \u4f7f\u7528\u4ee5\u4e0b\u914d\u7f6e\u6587\u4ef6\u4e2d\u7684\u914d\u7f6e\uff1a/storage/emulated/0/Android/data/org.qpython.qpy/files/apigpt.conf\uff1a

      [speech]\nspeech_key = your_api_key\n

      \u9ed8\u8ba4\u8bed\u97f3\u8bbe\u7f6e\uff1a - \u82f1\u8bed\uff1aen-US-JennyNeural - \u4e2d\u6587\uff1azh-CN-XiaoxiaoNeural

      "},{"location":"qsl4a/special/pgptai/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5f55\u5236\u5e76\u8f6c\u5f55\nprint(\"Recording for 5 seconds...\")\ntext = droid.speechToText(RecordSecond=5, Language='en').result\nprint(f\"You said: {text}\")\n\n# \u8f6c\u5f55\u73b0\u6709\u6587\u4ef6\ntext = droid.speechToText(AmrFile=\"/sdcard/recording.amr\").result\nprint(f\"Transcription: {text}\")\n\n# \u6587\u672c\u8f6c\u8bed\u97f3\ndroid.textToSpeech(\"Hello, this is a test message.\", AutoPlay=True, Language='en')\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u8bed\u97f3\u5e76\u4fdd\u5b58\u5230\u6587\u4ef6\u7684\u6587\u672c\u8f6c\u8bed\u97f3\nresult = droid.textToSpeech(\n    \"Welcome to QPython!\",\n    AutoPlay=False,\n    WavFile=\"/sdcard/welcome.wav\",\n    VoiceName=\"en-US-JennyNeural\"\n).result\nprint(f\"Audio saved to: {result.get('WavFile')}\")\n
      "},{"location":"qsl4a/special/pgptai/#_6","title":"\u7c7b\u4f7f\u7528","text":"
      from androidhelper.pgptai import pgptai\nimport androidhelper\n\ndroid = androidhelper.Android()\nai = pgptai(droid)\n\n# \u4f7f\u7528\u8bed\u97f3\u8bc6\u522b\ntext = ai.speechToText(RecordSecond=10)\n
      "},{"location":"qsl4a/storage/clipboard/","title":"\u526a\u8d34\u677f API","text":"

      \u590d\u5236\u548c\u7c98\u8d34\u6587\u672c\u5230\u7cfb\u7edf\u526a\u8d34\u677f\u3002

      "},{"location":"qsl4a/storage/clipboard/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/clipboard/#setclipboard","title":"setClipboard()","text":"

      \u590d\u5236\u6587\u672c\u5230\u526a\u8d34\u677f\u3002

      setClipboard(text)\n

      \u53c2\u6570\uff1a - text (str): \u8981\u590d\u5236\u7684\u6587\u672c

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/clipboard/#getclipboard","title":"getClipboard()","text":"

      \u4ece\u526a\u8d34\u677f\u83b7\u53d6\u6587\u672c\u3002

      getClipboard()\n

      \u8fd4\u56de\uff1a \u526a\u8d34\u677f\u6587\u672c

      "},{"location":"qsl4a/storage/clipboard/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u590d\u5236\u5230\u526a\u8d34\u677f\ndroid.setClipboard(\"Hello from QPython!\")\n\n# \u4ece\u526a\u8d34\u677f\u7c98\u8d34\ntext = droid.getClipboard().result\nprint(f\"Clipboard: {text}\")\n
      "},{"location":"qsl4a/storage/documentfile/","title":"DocumentFile API","text":"

      \u4f7f\u7528 SAF\uff08\u5b58\u50a8\u8bbf\u95ee\u6846\u67b6\uff09\u8fdb\u884c\u6587\u4ef6\u64cd\u4f5c\uff0c\u652f\u6301 Android 4.4+\u3002

      "},{"location":"qsl4a/storage/documentfile/#_1","title":"\u76ee\u5f55\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilemkdir","title":"documentFileMkdir()","text":"

      \u521b\u5efa\u76ee\u5f55\u3002

      documentFileMkdir(Dir)\n

      \u53c2\u6570\uff1a - Dir (str): \u76ee\u5f55\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/documentfile/#documentfilelistfiles","title":"documentFileListFiles()","text":"

      \u5217\u51fa\u76ee\u5f55\u4e2d\u7684\u6587\u4ef6\u3002

      documentFileListFiles(Folder)\n

      \u8fd4\u56de\uff1a \u6587\u4ef6\u5217\u8868

      "},{"location":"qsl4a/storage/documentfile/#_2","title":"\u6587\u4ef6\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileexists","title":"documentFileExists()","text":"

      \u68c0\u67e5\u6587\u4ef6\u6216\u76ee\u5f55\u662f\u5426\u5b58\u5728\u3002

      documentFileExists(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u6216\u76ee\u5f55\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u5b58\u5728\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/storage/documentfile/#documentfileisfile","title":"documentFileIsFile()","text":"

      \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u6587\u4ef6\u3002

      documentFileIsFile(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u662f\u6587\u4ef6\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u6587\u4ef6\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

      "},{"location":"qsl4a/storage/documentfile/#documentfileisdirectory","title":"documentFileIsDirectory()","text":"

      \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u76ee\u5f55\u3002

      documentFileIsDirectory(path)\n

      \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u662f\u76ee\u5f55\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u76ee\u5f55\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

      "},{"location":"qsl4a/storage/documentfile/#documentfiledelete","title":"documentFileDelete()","text":"

      \u5220\u9664\u6587\u4ef6\u6216\u76ee\u5f55\u3002

      documentFileDelete(FileOrTree)\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/documentfile/#documentfilerenameto","title":"documentFileRenameTo()","text":"

      \u91cd\u547d\u540d\u6216\u79fb\u52a8\u6587\u4ef6\u3002

      documentFileRenameTo(Src, Dest)\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/storage/documentfile/#documentfilecopy","title":"documentFileCopy()","text":"

      \u590d\u5236\u6587\u4ef6\u3002

      documentFileCopy(SrcFileOrTree, DestFileOrTree)\n
      "},{"location":"qsl4a/storage/documentfile/#_3","title":"\u6d41\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileinputstream","title":"documentFileInputStream()","text":"

      \u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9\u3002

      documentFileInputStream(srcFile, EncodingFormat=\"\", skip=None, length=None)\n

      \u53c2\u6570\uff1a - srcFile (str): \u6e90\u6587\u4ef6 - EncodingFormat (str): \"UTF-8\"\u3001\"GBK\"\u3001\"Base64\" \u6216\u7a7a\u5b57\u7b26\u4e32\u8868\u793a\u5b57\u8282 - skip (int): \u4ece\u5f00\u5934\u8df3\u8fc7\u7684\u5b57\u8282\u6570 - length (int): \u8bfb\u53d6\u957f\u5ea6

      \u8fd4\u56de\uff1a \u6587\u4ef6\u5185\u5bb9

      "},{"location":"qsl4a/storage/documentfile/#documentfileoutputstream","title":"documentFileOutputStream()","text":"

      \u5199\u5165\u6587\u4ef6\u5185\u5bb9\u3002

      documentFileOutputStream(destFile, src, EncodingFormat=\"\", append=None)\n

      \u53c2\u6570\uff1a - destFile (str): \u76ee\u6807\u6587\u4ef6 - src: \u8981\u5199\u5165\u7684\u6570\u636e - EncodingFormat (str): \u7f16\u7801\u683c\u5f0f - append (bool): \u8ffd\u52a0\u6a21\u5f0f

      "},{"location":"qsl4a/storage/documentfile/#_4","title":"\u6587\u4ef6\u4fe1\u606f","text":""},{"location":"qsl4a/storage/documentfile/#documentfilelength","title":"documentFileLength()","text":"

      \u83b7\u53d6\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\u3002

      documentFileLength(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

      "},{"location":"qsl4a/storage/documentfile/#documentfilelastmodified","title":"documentFileLastModified()","text":"

      \u83b7\u53d6\u6700\u540e\u4fee\u6539\u65f6\u95f4\u3002

      documentFileLastModified(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u65f6\u95f4\u6233\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

      "},{"location":"qsl4a/storage/documentfile/#documentfilegetstat","title":"documentFileGetStat()","text":"

      \u83b7\u53d6\u5168\u9762\u7684\u6587\u4ef6\u7edf\u8ba1\u4fe1\u606f\u3002

      documentFileGetStat(path)\n

      \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5305\u542b\u957f\u5ea6\u3001\u6700\u540e\u4fee\u6539\u65f6\u95f4\u548c\u8bfb/\u5199\u6743\u9650\u7684\u5b57\u5178\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

      "},{"location":"qsl4a/storage/documentfile/#uri","title":"URI \u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilegeturi","title":"documentFileGetUri()","text":"

      \u4ece\u8def\u5f84\u83b7\u53d6 URI\u3002

      documentFileGetUri(path, isDirectory=None)\n
      "},{"location":"qsl4a/storage/documentfile/#documentfileshowopen","title":"documentFileShowOpen()","text":"

      \u663e\u793a\u6587\u4ef6\u9009\u62e9\u5668\u3002

      documentFileShowOpen()\n

      \u8fd4\u56de\uff1a \u9009\u62e9\u7684\u6587\u4ef6 URI

      "},{"location":"qsl4a/storage/documentfile/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u76ee\u5f55\ndroid.documentFileMkdir(\"/sdcard/MyFolder\")\n\n# \u5217\u51fa\u6587\u4ef6\nfiles = droid.documentFileListFiles(\"/sdcard\").result\nfor f in files:\n    print(f)\n\n# \u8bfb\u53d6\u6587\u4ef6\ncontent = droid.documentFileInputStream(\n    \"/sdcard/test.txt\",\n    EncodingFormat=\"UTF-8\"\n).result\nprint(content)\n\n# \u5199\u5165\u6587\u4ef6\ndroid.documentFileOutputStream(\n    \"/sdcard/output.txt\",\n    \"Hello World\",\n    EncodingFormat=\"UTF-8\"\n)\n
      "},{"location":"qsl4a/storage/preferences/","title":"\u504f\u597d\u8bbe\u7f6e API","text":"

      \u4f7f\u7528 Android SharedPreferences \u5b58\u50a8\u548c\u68c0\u7d22\u6570\u636e\u3002

      "},{"location":"qsl4a/storage/preferences/#_1","title":"\u504f\u597d\u8bbe\u7f6e\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/preferences/#prefgetvalue","title":"prefGetValue()","text":"

      \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u8bfb\u53d6\u503c\u3002

      prefGetValue(key, filename=None)\n

      \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c\uff08\u4efb\u610f\u7c7b\u578b\uff09

      "},{"location":"qsl4a/storage/preferences/#prefputvalue","title":"prefPutValue()","text":"

      \u5199\u5165\u503c\u5230\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u3002

      prefPutValue(key, value, filename=None)\n

      \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - value (object): \u8981\u5b58\u50a8\u7684\u503c - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      "},{"location":"qsl4a/storage/preferences/#prefgetall","title":"prefGetAll()","text":"

      \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\u503c\u3002

      prefGetAll(filename=None)\n

      \u53c2\u6570\uff1a - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      \u8fd4\u56de\uff1a \u6240\u6709\u504f\u597d\u7684\u6620\u5c04

      "},{"location":"qsl4a/storage/preferences/#prefremovevalue","title":"prefRemoveValue()","text":"

      \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u4e2d\u79fb\u9664\u503c\u3002

      prefRemoveValue(key, filename=None)\n

      \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

      "},{"location":"qsl4a/storage/preferences/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b58\u50a8\u503c\ndroid.prefPutValue(\"username\", \"alice\")\ndroid.prefPutValue(\"score\", 100)\ndroid.prefPutValue(\"enabled\", True)\n\n# \u8bfb\u53d6\u7279\u5b9a\u503c\nusername = droid.prefGetValue(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\nall_prefs = droid.prefGetAll().result\nprint(f\"All prefs: {all_prefs}\")\n\n# \u79fb\u9664\u503c\ndroid.prefRemoveValue(\"score\")\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u6587\u4ef6\u540d\ndroid.prefPutValue(\"token\", \"abc123\", filename=\"auth.prefs\")\ntoken = droid.prefGetValue(\"token\", filename=\"auth.prefs\").result\n
      "},{"location":"qsl4a/system/activityresult/","title":"Activity Result API","text":"

      \u4e3a\u901a\u8fc7 startActivityForResult \u542f\u52a8\u7684\u811a\u672c\u8bbe\u7f6e activity \u7ed3\u679c\u3002

      "},{"location":"qsl4a/system/activityresult/#_1","title":"\u7ed3\u679c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/activityresult/#setresultboolean","title":"setResultBoolean()","text":"

      \u8bbe\u7f6e\u5e03\u5c14\u7ed3\u679c\u3002

      setResultBoolean(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (bool): \u5e03\u5c14\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultbyte","title":"setResultByte()","text":"

      \u8bbe\u7f6e\u5b57\u8282\u7ed3\u679c\u3002

      setResultByte(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u5b57\u8282\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultshort","title":"setResultShort()","text":"

      \u8bbe\u7f6e\u77ed\u6574\u6570\u7ed3\u679c\u3002

      setResultShort(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u77ed\u6574\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultchar","title":"setResultChar()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u7ed3\u679c\u3002

      setResultChar(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultinteger","title":"setResultInteger()","text":"

      \u8bbe\u7f6e\u6574\u6570\u7ed3\u679c\u3002

      setResultInteger(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u6574\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultlong","title":"setResultLong()","text":"

      \u8bbe\u7f6e\u957f\u6574\u6570\u7ed3\u679c\u3002

      setResultLong(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u957f\u6574\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultfloat","title":"setResultFloat()","text":"

      \u8bbe\u7f6e\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

      setResultFloat(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u6d6e\u70b9\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultdouble","title":"setResultDouble()","text":"

      \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

      setResultDouble(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultstring","title":"setResultString()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u4e32\u7ed3\u679c\u3002

      setResultString(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u4e32\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#setresultbooleanarray","title":"setResultBooleanArray()","text":"

      \u8bbe\u7f6e\u5e03\u5c14\u6570\u7ec4\u7ed3\u679c\u3002

      setResultBooleanArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5e03\u5c14\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultbytearray","title":"setResultByteArray()","text":"

      \u8bbe\u7f6e\u5b57\u8282\u6570\u7ec4\u7ed3\u679c\u3002

      setResultByteArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u8282\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultshortarray","title":"setResultShortArray()","text":"

      \u8bbe\u7f6e\u77ed\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultShortArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u77ed\u6574\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultchararray","title":"setResultCharArray()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u6570\u7ec4\u7ed3\u679c\u3002

      setResultCharArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultintegerarray","title":"setResultIntegerArray()","text":"

      \u8bbe\u7f6e\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultIntegerArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6574\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultlongarray","title":"setResultLongArray()","text":"

      \u8bbe\u7f6e\u957f\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultLongArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u957f\u6574\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultfloatarray","title":"setResultFloatArray()","text":"

      \u8bbe\u7f6e\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultFloatArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6d6e\u70b9\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultdoublearray","title":"setResultDoubleArray()","text":"

      \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

      setResultDoubleArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultstringarray","title":"setResultStringArray()","text":"

      \u8bbe\u7f6e\u5b57\u7b26\u4e32\u6570\u7ec4\u7ed3\u679c\u3002

      setResultStringArray(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u4e32\u6570\u7ec4

      "},{"location":"qsl4a/system/activityresult/#setresultserializable","title":"setResultSerializable()","text":"

      \u8bbe\u7f6e\u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u3002

      setResultSerializable(resultCode, resultValue)\n

      \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue: \u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u503c

      "},{"location":"qsl4a/system/activityresult/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c activity \u540e\uff0c\u8bbe\u7f6e\u7ed3\u679c\n# \u793a\u4f8b\uff1a\u8fd4\u56de\u6210\u529f\u53ca\u6570\u636e\ndroid.setResultInteger(0, 200)  # RESULT_OK\ndroid.setResultString(0, \"Operation completed successfully\")\n\n# \u8fd4\u56de\u6570\u7ec4\u7ed3\u679c\ndroid.setResultIntegerArray(0, [1, 2, 3, 4, 5])\n
      "},{"location":"qsl4a/system/application/","title":"\u5e94\u7528\u7ba1\u7406","text":"

      \u7ba1\u7406\u5e94\u7528\u7a0b\u5e8f\u3001\u542f\u52a8\u5e94\u7528\u548c\u67e5\u8be2\u7cfb\u7edf\u4fe1\u606f\u3002

      "},{"location":"qsl4a/system/application/#_2","title":"\u5e94\u7528\u7a0b\u5e8f\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getapplicationinfo","title":"getApplicationInfo()","text":"

      \u83b7\u53d6\u5e94\u7528\u4fe1\u606f\u3002

      getApplicationInfo(packageName=None)\n

      \u53c2\u6570\uff1a - packageName (str): \u5305\u540d\uff08None = \u5f53\u524d\u5e94\u7528\uff09

      \u8fd4\u56de\uff1a \u5e94\u7528\u4fe1\u606f\u5b57\u5178

      "},{"location":"qsl4a/system/application/#getinstalledpackages","title":"getInstalledPackages()","text":"

      \u83b7\u53d6\u5df2\u5b89\u88c5\u5305\u5217\u8868\u3002

      getInstalledPackages(flag=4)\n

      \u53c2\u6570\uff1a - flag (int): \u5305\u6807\u5fd7\u8fc7\u6ee4\u5668\uff08\u9ed8\u8ba4\uff1a4\uff09

      \u8fd4\u56de\uff1a \u5df2\u5b89\u88c5\u5305\u5217\u8868

      "},{"location":"qsl4a/system/application/#getrunningpackages","title":"getRunningPackages()","text":"

      \u5217\u51fa\u6b63\u5728\u8fd0\u884c\u7684\u5305\u3002

      getRunningPackages()\n

      \u8fd4\u56de\uff1a \u5305\u540d\u5217\u8868

      "},{"location":"qsl4a/system/application/#getlaunchablepackages","title":"getLaunchablePackages()","text":"

      \u83b7\u53d6\u53ef\u542f\u52a8\u5305\u5217\u8868\u3002

      getLaunchablePackages(needClassName=False)\n

      \u53c2\u6570\uff1a - needClassName (bool): \u5305\u542b\u4e3b activity \u7c7b\u540d\uff08\u9ed8\u8ba4\uff1aFalse\uff09

      \u8fd4\u56de\uff1a \u53ef\u542f\u52a8\u5305\u540d\u5217\u8868\u6216\u5305\u542b\u7c7b\u540d\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#_3","title":"\u5e94\u7528\u63a7\u5236","text":""},{"location":"qsl4a/system/application/#launch","title":"launch()","text":"

      \u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u3002

      launch(classname=None, packagename=None, wait=True)\n

      \u53c2\u6570\uff1a - classname (str): \u4e3b activity \u7c7b\u540d - packagename (str): \u5305\u540d - wait (bool): \u7b49\u5f85\u542f\u52a8\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

      \u8fd4\u56de\uff1a \u542f\u52a8\u7ed3\u679c

      "},{"location":"qsl4a/system/application/#forcestoppackage","title":"forceStopPackage()","text":"

      \u5f3a\u5236\u505c\u6b62\u5e94\u7528\u7a0b\u5e8f\u3002

      forceStopPackage(packageName)\n

      \u53c2\u6570\uff1a - packageName (str): \u8981\u505c\u6b62\u7684\u5305\u540d

      "},{"location":"qsl4a/system/application/#_4","title":"\u7248\u672c\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getpackageversion","title":"getPackageVersion()","text":"

      \u83b7\u53d6\u5e94\u7528\u7248\u672c\u540d\u79f0\u3002

      getPackageVersion(packageName)\n

      \u8fd4\u56de\uff1a \u7248\u672c\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"3.2.1\"\uff09

      "},{"location":"qsl4a/system/application/#getpackageversioncode","title":"getPackageVersionCode()","text":"

      \u83b7\u53d6\u5e94\u7528\u7248\u672c\u4ee3\u7801\u3002

      getPackageVersionCode(packageName)\n

      \u8fd4\u56de\uff1a \u7248\u672c\u4ee3\u7801\u6574\u6570

      "},{"location":"qsl4a/system/application/#getconstants","title":"getConstants()","text":"

      \u83b7\u53d6\u7c7b\u5e38\u91cf\u3002

      getConstants(classname)\n

      \u53c2\u6570\uff1a - classname (str): \u5b8c\u6574\u7c7b\u540d

      \u8fd4\u56de\uff1a \u5e38\u91cf\u540d\u548c\u503c\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#_5","title":"\u7cfb\u7edf\u529f\u80fd","text":""},{"location":"qsl4a/system/application/#backgroundprotect","title":"backgroundProtect()","text":"

      \u542f\u7528\u6216\u7981\u7528\u5e94\u7528\u7684\u540e\u53f0\u4fdd\u62a4\u3002

      backgroundProtect(enabled=True)\n

      \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\u4fdd\u62a4\uff0cFalse \u7981\u7528

      "},{"location":"qsl4a/system/application/#createscriptshortcut","title":"createScriptShortCut()","text":"

      \u4e3a\u811a\u672c\u521b\u5efa\u4e3b\u5c4f\u5e55\u5feb\u6377\u65b9\u5f0f\u3002

      createScriptShortCut(scriptPath, label=None, iconPath=None, scriptArg=None)\n

      \u53c2\u6570\uff1a - scriptPath (str): Python \u811a\u672c\u8def\u5f84 - label (str, optional): \u5feb\u6377\u65b9\u5f0f\u6807\u7b7e - iconPath (str, optional): \u56fe\u6807\u56fe\u50cf\u8def\u5f84 - scriptArg (str, optional): \u4f20\u9012\u7ed9\u811a\u672c\u7684\u53c2\u6570

      "},{"location":"qsl4a/system/application/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getandroidid","title":"getAndroidID()","text":"

      \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

      getAndroidID()\n

      \u8fd4\u56de\uff1a \u552f\u4e00\u7684 Android \u8bbe\u5907 ID \u5b57\u7b26\u4e32

      "},{"location":"qsl4a/system/application/#getsysinfo","title":"getSysInfo()","text":"

      \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\u3002

      getSysInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#getlocale","title":"getLocale()","text":"

      \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u3002

      getLocale()\n

      \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

      "},{"location":"qsl4a/system/application/#getharmonyosinformation","title":"getHarmonyOsInformation()","text":"

      \u5982\u679c\u5728 HarmonyOS \u4e0a\u8fd0\u884c\uff0c\u83b7\u53d6 HarmonyOS \u4fe1\u606f\u3002

      getHarmonyOsInformation()\n

      \u8fd4\u56de\uff1a HarmonyOS \u7248\u672c\u4fe1\u606f\u6216 None

      "},{"location":"qsl4a/system/application/#isexternalstoragemanager","title":"isExternalStorageManager()","text":"

      \u68c0\u67e5\u5e94\u7528\u662f\u5426\u6709\u5916\u90e8\u5b58\u50a8\u7ba1\u7406\u5668\u6743\u9650\u3002

      isExternalStorageManager()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6709\u6743\u9650\u5219\u4e3a True

      "},{"location":"qsl4a/system/application/#_7","title":"\u5185\u5b58\u548c\u663e\u793a","text":""},{"location":"qsl4a/system/application/#getmemoryinfo","title":"getMemoryInfo()","text":"

      \u83b7\u53d6\u5185\u5b58\u4fe1\u606f\u3002

      getMemoryInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#getscreeninfo","title":"getScreenInfo()","text":"

      \u83b7\u53d6\u5c4f\u5e55\u4fe1\u606f\u3002

      getScreenInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#_8","title":"\u6743\u9650","text":""},{"location":"qsl4a/system/application/#checkpermissions","title":"checkPermissions()","text":"

      \u68c0\u67e5\u5f53\u524d\u5e94\u7528\u6743\u9650\u3002

      checkPermissions()\n

      \u8fd4\u56de\uff1a \u6743\u9650\u53ca\u5176\u72b6\u6001\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/application/#requestpermissions","title":"requestPermissions()","text":"

      \u5411\u7528\u6237\u8bf7\u6c42\u6743\u9650\u3002

      requestPermissions(permissions=None)\n

      \u53c2\u6570\uff1a - permissions (list, optional): \u8981\u8bf7\u6c42\u7684\u6743\u9650\u5217\u8868\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8bf7\u6c42\u6240\u6709\u9700\u8981\u7684\u6743\u9650\u3002

      \u8fd4\u56de\uff1a \u6743\u9650\u8bf7\u6c42\u7ed3\u679c

      "},{"location":"qsl4a/system/application/#_9","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/system/application/#showscreenlock","title":"showScreenLock()","text":"

      \u663e\u793a\u5c4f\u5e55\u9501\u5b9a\uff08PIN/\u56fe\u6848/\u5bc6\u7801\u8f93\u5165\uff09\u3002

      showScreenLock()\n
      "},{"location":"qsl4a/system/application/#_10","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\ninfo = droid.getSysInfo().result\nprint(f\"System: {info}\")\n\n# \u83b7\u53d6\u5e94\u7528\u7248\u672c\nversion = droid.getPackageVersion(\"org.qpython.qpy\").result\nprint(f\"QPython version: {version}\")\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u5e94\u7528\napps = droid.getInstalledPackages().result\nprint(f\"Installed apps: {len(apps)}\")\n\n# \u542f\u52a8\u5e94\u7528\ndroid.launch(packagename=\"com.android.settings\")\n\n# \u68c0\u67e5\u6743\u9650\nperms = droid.checkPermissions().result\nprint(f\"Permissions: {perms}\")\n\n# \u8bf7\u6c42\u5b58\u50a8\u6743\u9650\ndroid.requestPermissions([\"android.permission.READ_EXTERNAL_STORAGE\"])\n\n# \u521b\u5efa\u5feb\u6377\u65b9\u5f0f\ndroid.createScriptShortCut(\n    \"/sdcard/my_script.py\",\n    label=\"My Script\",\n    iconPath=\"/sdcard/icon.png\"\n)\n
      "},{"location":"qsl4a/system/battery/","title":"\u7535\u6c60 API","text":"

      \u76d1\u63a7\u8bbe\u5907\u7535\u6c60\u72b6\u6001\u548c\u5065\u5eb7\u72b6\u51b5\u3002

      "},{"location":"qsl4a/system/battery/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/battery/#readbatterydata","title":"readBatteryData()","text":"

      \u83b7\u53d6\u5b8c\u6574\u7684\u7535\u6c60\u4fe1\u606f\u3002

      readBatteryData()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7535\u6c60\u6570\u636e\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/battery/#batterystartmonitoring","title":"batteryStartMonitoring()","text":"

      \u5f00\u59cb\u7535\u6c60\u76d1\u63a7\u3002

      batteryStartMonitoring()\n
      "},{"location":"qsl4a/system/battery/#batterystopmonitoring","title":"batteryStopMonitoring()","text":"

      \u505c\u6b62\u7535\u6c60\u76d1\u63a7\u3002

      batteryStopMonitoring()\n
      "},{"location":"qsl4a/system/battery/#batterygetlevel","title":"batteryGetLevel()","text":"

      \u83b7\u53d6\u7535\u6c60\u767e\u5206\u6bd4\u3002

      batteryGetLevel()\n

      \u8fd4\u56de\uff1a \u6574\u6570\uff080-100\uff09

      "},{"location":"qsl4a/system/battery/#batterygetstatus","title":"batteryGetStatus()","text":"

      \u83b7\u53d6\u5145\u7535\u72b6\u6001\u3002

      batteryGetStatus()\n

      \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u5145\u7535\u4e2d - 3: \u653e\u7535\u4e2d - 4: \u672a\u5145\u7535 - 5: \u5df2\u5145\u6ee1

      "},{"location":"qsl4a/system/battery/#batterygetplugtype","title":"batteryGetPlugType()","text":"

      \u83b7\u53d6\u7535\u6e90\u7c7b\u578b\u3002

      batteryGetPlugType()\n

      \u8fd4\u56de\uff1a - -1: \u672a\u77e5 - 0: \u672a\u63d2\u7535 - 1: AC \u5145\u7535\u5668 - 2: USB \u7aef\u53e3

      "},{"location":"qsl4a/system/battery/#batterygethealth","title":"batteryGetHealth()","text":"

      \u83b7\u53d6\u7535\u6c60\u5065\u5eb7\u72b6\u51b5\u3002

      batteryGetHealth()\n

      \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u826f\u597d - 3: \u8fc7\u70ed - 4: \u635f\u574f - 5: \u8fc7\u538b - 6: \u672a\u6307\u5b9a\u7684\u6545\u969c

      "},{"location":"qsl4a/system/battery/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\nlevel = droid.batteryGetLevel().result\nprint(f\"Battery: {level}%\")\n
      "},{"location":"qsl4a/system/qpyinterface/","title":"QPython \u63a5\u53e3 API","text":"

      \u4ece\u5176\u4ed6\u5e94\u7528\u6267\u884c QPython \u811a\u672c\u548c\u7ba1\u7406\u5171\u4eab\u53d8\u91cf\u3002

      "},{"location":"qsl4a/system/qpyinterface/#_1","title":"\u811a\u672c\u6267\u884c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/qpyinterface/#executeqpy","title":"executeQPy()","text":"

      \u6267\u884c QPython \u811a\u672c\u3002

      executeQPy(path=\"\", arg=None)\n

      \u53c2\u6570\uff1a - path (str): \u811a\u672c\u6587\u4ef6\u8def\u5f84 - arg (str, optional): \u547d\u4ee4\u884c\u53c2\u6570

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#executeqpyassrv","title":"executeQPyAsSrv()","text":"

      \u4f5c\u4e3a\u670d\u52a1\u6267\u884c QPython \u811a\u672c\u3002

      executeQPyAsSrv(path=None)\n

      \u53c2\u6570\uff1a - path (str, optional): \u811a\u672c\u6587\u4ef6\u8def\u5f84

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#executeqpycode","title":"executeQPyCode()","text":"

      \u76f4\u63a5\u6267\u884c Python \u4ee3\u7801\u3002

      executeQPyCode(code=None)\n

      \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#executeqpycodeassrv","title":"executeQPyCodeAsSrv()","text":"

      \u4f5c\u4e3a\u670d\u52a1\u6267\u884c Python \u4ee3\u7801\u3002

      executeQPyCodeAsSrv(code=None)\n

      \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

      \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

      "},{"location":"qsl4a/system/qpyinterface/#_2","title":"\u5171\u4eab\u53d8\u91cf","text":"

      \u5171\u4eab\u53d8\u91cf\u5141\u8bb8 QPython \u4e0e\u5176\u4ed6\u5e94\u7528\u4e4b\u95f4\u8fdb\u884c\u901a\u4fe1\u3002

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableset","title":"sharedVariableSet()","text":"

      \u8bbe\u7f6e Java \u5171\u4eab\u53d8\u91cf\u3002

      sharedVariableSet(key, value)\n

      \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d - value (str): \u53d8\u91cf\u503c

      \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableget","title":"sharedVariableGet()","text":"

      \u83b7\u53d6 Java \u5171\u4eab\u53d8\u91cf\u3002

      sharedVariableGet(key)\n

      \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d

      \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableremove","title":"sharedVariableRemove()","text":"

      \u79fb\u9664 Java \u5171\u4eab\u53d8\u91cf\u3002

      sharedVariableRemove(key)\n

      \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u53d8\u91cf\u540d

      \u8fd4\u56de\uff1a \u88ab\u79fb\u9664\u7684\u503c

      "},{"location":"qsl4a/system/qpyinterface/#getlastlog","title":"getLastLog()","text":"

      \u83b7\u53d6 QPython \u7684\u6700\u540e\u65e5\u5fd7\u8f93\u51fa\u3002

      getLastLog()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u65e5\u5fd7\u5185\u5bb9

      "},{"location":"qsl4a/system/qpyinterface/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c\u811a\u672c\ndroid.executeQPy(\"/sdcard/my_script.py\", arg=\"test\")\n\n# \u76f4\u63a5\u6267\u884c\u4ee3\u7801\ncode = \"print('Hello from QPython!')\"\ndroid.executeQPyCode(code)\n\n# \u4f7f\u7528\u5171\u4eab\u53d8\u91cf\ndroid.sharedVariableSet(\"username\", \"alice\")\nusername = droid.sharedVariableGet(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u79fb\u9664\u53d8\u91cf\ndroid.sharedVariableRemove(\"username\")\n\n# \u83b7\u53d6\u6700\u8fd1\u65e5\u5fd7\nlog = droid.getLastLog().result\nprint(f\"Log: {log}\")\n
      "},{"location":"qsl4a/system/sensors/","title":"\u4f20\u611f\u5668 API","text":"

      \u8bbf\u95ee\u8bbe\u5907\u4f20\u611f\u5668\uff0c\u5305\u62ec\u52a0\u901f\u5ea6\u8ba1\u3001\u9640\u87ba\u4eea\u3001\u78c1\u529b\u8ba1\u7b49\u3002

      "},{"location":"qsl4a/system/sensors/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/sensors/#startsensingtimed","title":"startSensingTimed()","text":"

      \u5f00\u59cb\u4f20\u611f\u5668\u76d1\u63a7\u5e76\u8bbe\u7f6e\u65f6\u95f4\u95f4\u9694\u3002

      startSensingTimed(sensorNumber, delayTime)\n

      \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID\uff08\u901a\u5e38\u4e3a 1-3\uff09 - delayTime (int): \u8bfb\u53d6\u4e4b\u95f4\u7684\u5ef6\u8fdf\uff08\u6beb\u79d2\uff09

      "},{"location":"qsl4a/system/sensors/#startsensingthreshold","title":"startSensingThreshold()","text":"

      \u5f00\u59cb\u5e26\u9608\u503c\u89e6\u53d1\u7684\u4f20\u611f\u5668\u76d1\u63a7\u3002

      startSensingThreshold(sensorNumber, threshold, axis)\n

      \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID - threshold (float): \u89e6\u53d1\u9608\u503c - axis (int): \u8981\u76d1\u63a7\u7684\u8f74\uff080=X\uff0c1=Y\uff0c2=Z\uff09

      "},{"location":"qsl4a/system/sensors/#stopsensing","title":"stopSensing()","text":"

      \u505c\u6b62\u6240\u6709\u4f20\u611f\u5668\u76d1\u63a7\u3002

      stopSensing()\n
      "},{"location":"qsl4a/system/sensors/#readsensors","title":"readSensors()","text":"

      \u8bfb\u53d6\u5f53\u524d\u4f20\u611f\u5668\u6570\u636e\u3002

      readSensors()\n

      \u8fd4\u56de\uff1a \u4f20\u611f\u5668\u6570\u636e\u5b57\u5178

      "},{"location":"qsl4a/system/sensors/#sensorsreadaccelerometer","title":"sensorsReadAccelerometer()","text":"

      \u8bfb\u53d6\u52a0\u901f\u5ea6\u8ba1\u503c\u3002

      sensorsReadAccelerometer()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d m/s\u00b2

      "},{"location":"qsl4a/system/sensors/#sensorsreadgyroscope","title":"sensorsReadGyroscope()","text":"

      \u8bfb\u53d6\u9640\u87ba\u4eea\u503c\u3002

      sensorsReadGyroscope()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d rad/s

      "},{"location":"qsl4a/system/sensors/#sensorsreadmagnetometer","title":"sensorsReadMagnetometer()","text":"

      \u8bfb\u53d6\u78c1\u573a\u503c\u3002

      sensorsReadMagnetometer()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d \u03bcT

      "},{"location":"qsl4a/system/sensors/#sensorsreadorientation","title":"sensorsReadOrientation()","text":"

      \u8bfb\u53d6\u8bbe\u5907\u65b9\u5411\u3002

      sensorsReadOrientation()\n

      \u8fd4\u56de\uff1a \u5217\u8868 [azimuth, pitch, roll]\uff0c\u5355\u4f4d\u5ea6

      "},{"location":"qsl4a/system/sensors/#sensorsgetlight","title":"sensorsGetLight()","text":"

      \u8bfb\u53d6\u5149\u4f20\u611f\u5668\u503c\u3002

      sensorsGetLight()\n

      \u8fd4\u56de\uff1a \u5149\u7ea7\u522b\uff08lux\uff09

      "},{"location":"qsl4a/system/sensors/#sensorsgetstepcounter","title":"sensorsGetStepCounter()","text":"

      \u8bfb\u53d6\u6b65\u8ba1\u6570\u5668\u3002

      sensorsGetStepCounter()\n

      \u8fd4\u56de\uff1a \u6b65\u6570

      "},{"location":"qsl4a/system/sensors/#sensorsgetaccuracy","title":"sensorsGetAccuracy()","text":"

      \u83b7\u53d6\u5f53\u524d\u4f20\u611f\u5668\u7cbe\u5ea6\u3002

      sensorsGetAccuracy()\n

      \u8fd4\u56de\uff1a \u7cbe\u5ea6\u503c\uff080-3\uff1aUNRELIABLE\u3001ACCURACY_LOW\u3001ACCURACY_MEDIUM\u3001ACCURACY_HIGH\uff09

      "},{"location":"qsl4a/system/sensors/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u8bfb\u53d6\u4f20\u611f\u5668 10 \u6b21\nfor i in range(10):\n    accel = droid.sensorsReadAccelerometer().result\n    print(f\"Accel: X={accel[0]:.2f}, Y={accel[1]:.2f}, Z={accel[2]:.2f}\")\n    time.sleep(0.5)\n\ndroid.stopSensing()\n
      "},{"location":"qsl4a/system/settings/","title":"\u8bbe\u7f6e API","text":"

      \u63a7\u5236\u7cfb\u7edf\u8bbe\u7f6e\uff0c\u5305\u62ec\u5c4f\u5e55\u3001\u58f0\u97f3\u548c\u7f51\u7edc\u8bbe\u7f6e\u3002

      "},{"location":"qsl4a/system/settings/#_1","title":"\u5c4f\u5e55\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#setscreentimeout","title":"setScreenTimeout()","text":"

      \u8bbe\u7f6e\u5c4f\u5e55\u8d85\u65f6\u503c\u3002

      setScreenTimeout(value)\n

      \u53c2\u6570\uff1a - value (int): \u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

      \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u8d85\u65f6\u503c

      "},{"location":"qsl4a/system/settings/#getscreentimeout","title":"getScreenTimeout()","text":"

      \u83b7\u53d6\u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u3002

      getScreenTimeout()\n

      \u8fd4\u56de\uff1a \u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

      "},{"location":"qsl4a/system/settings/#getscreenbrightness","title":"getScreenBrightness()","text":"

      \u83b7\u53d6\u5c4f\u5e55\u4eae\u5ea6\u503c\u3002

      getScreenBrightness()\n

      \u8fd4\u56de\uff1a \u4eae\u5ea6\u503c\uff080-255\uff09

      "},{"location":"qsl4a/system/settings/#setscreenbrightness","title":"setScreenBrightness()","text":"

      \u8bbe\u7f6e\u5c4f\u5e55\u4eae\u5ea6\u3002

      setScreenBrightness(value=None)\n

      \u53c2\u6570\uff1a - value (int, optional): \u4eae\u5ea6\u503c\uff080-255\uff09\uff0c\u6216 None \u8868\u793a\u81ea\u52a8

      \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u4eae\u5ea6\u503c

      "},{"location":"qsl4a/system/settings/#checkscreenon","title":"checkScreenOn()","text":"

      \u68c0\u67e5\u5c4f\u5e55\u662f\u5426\u4eae\u7740\u3002

      checkScreenOn()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u5c4f\u5e55\u4eae\u7740\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/system/settings/#_2","title":"\u98de\u884c\u6a21\u5f0f","text":""},{"location":"qsl4a/system/settings/#checkairplanemode","title":"checkAirplaneMode()","text":"

      \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\u662f\u5426\u542f\u7528\u3002

      checkAirplaneMode()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u98de\u884c\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

      "},{"location":"qsl4a/system/settings/#_3","title":"\u94c3\u58f0\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#checkringersilentmode","title":"checkRingerSilentMode()","text":"

      \u68c0\u67e5\u94c3\u58f0\u662f\u5426\u5904\u4e8e\u9759\u97f3\u6a21\u5f0f\u3002

      checkRingerSilentMode()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u9759\u97f3\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

      "},{"location":"qsl4a/system/settings/#toggleringersilentmode","title":"toggleRingerSilentMode()","text":"

      \u5207\u6362\u94c3\u58f0\u9759\u97f3\u6a21\u5f0f\u3002

      toggleRingerSilentMode(enabled=None)\n

      \u53c2\u6570\uff1a - enabled (bool, optional): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

      \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

      "},{"location":"qsl4a/system/settings/#togglevibratemode","title":"toggleVibrateMode()","text":"

      \u5207\u6362\u632f\u52a8\u6a21\u5f0f\u3002

      toggleVibrateMode(enabled=None, ringer=None)\n

      \u53c2\u6570\uff1a - enabled (bool, optional): \u5207\u6362\u632f\u52a8\u5f00/\u5173 - ringer (bool, optional): \u5e94\u7528\u4e8e\u94c3\u58f0\u6a21\u5f0f

      \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

      "},{"location":"qsl4a/system/settings/#getvibratemode","title":"getVibrateMode()","text":"

      \u83b7\u53d6\u632f\u52a8\u6a21\u5f0f\u8bbe\u7f6e\u3002

      getVibrateMode(ringer=None)\n

      \u53c2\u6570\uff1a - ringer (bool, optional): \u68c0\u67e5\u94c3\u58f0\u632f\u52a8\u6a21\u5f0f

      \u8fd4\u56de\uff1a \u5982\u679c\u632f\u52a8\u5df2\u542f\u7528\u5219\u4e3a True

      "},{"location":"qsl4a/system/settings/#_4","title":"\u97f3\u91cf\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#getringervolume","title":"getRingerVolume()","text":"

      \u83b7\u53d6\u5f53\u524d\u94c3\u58f0\u97f3\u91cf\u3002

      getRingerVolume()\n

      \u8fd4\u56de\uff1a \u94c3\u58f0\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-7\uff09

      "},{"location":"qsl4a/system/settings/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

      getMaxRingerVolume()\n

      \u8fd4\u56de\uff1a \u6700\u5927\u94c3\u58f0\u97f3\u91cf

      "},{"location":"qsl4a/system/settings/#setringervolume","title":"setRingerVolume()","text":"

      \u8bbe\u7f6e\u94c3\u58f0\u97f3\u91cf\u3002

      setRingerVolume(volume)\n

      \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

      "},{"location":"qsl4a/system/settings/#getmediavolume","title":"getMediaVolume()","text":"

      \u83b7\u53d6\u5f53\u524d\u5a92\u4f53\u97f3\u91cf\u3002

      getMediaVolume()\n

      \u8fd4\u56de\uff1a \u5a92\u4f53\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-15\uff09

      "},{"location":"qsl4a/system/settings/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

      \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

      getMaxMediaVolume()\n

      \u8fd4\u56de\uff1a \u6700\u5927\u5a92\u4f53\u97f3\u91cf

      "},{"location":"qsl4a/system/settings/#setmediavolume","title":"setMediaVolume()","text":"

      \u8bbe\u7f6e\u5a92\u4f53\u97f3\u91cf\u3002

      setMediaVolume(volume)\n

      \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

      "},{"location":"qsl4a/system/settings/#_5","title":"\u7cfb\u7edf\u4fe1\u606f","text":""},{"location":"qsl4a/system/settings/#elapsedrealtimenanos","title":"elapsedRealtimeNanos()","text":"

      \u83b7\u53d6\u81ea\u7cfb\u7edf\u542f\u52a8\u4ee5\u6765\u7684\u7eb3\u79d2\u6570\u3002

      elapsedRealtimeNanos()\n

      \u8fd4\u56de\uff1a \u7eb3\u79d2\u6570\uff08\u53ef\u7528\u4e8e\u8ba1\u65f6\uff09

      "},{"location":"qsl4a/system/settings/#gettrafficstats","title":"getTrafficStats()","text":"

      \u83b7\u53d6\u7f51\u7edc\u6d41\u91cf\u7edf\u8ba1\u3002

      getTrafficStats(flags=7)\n

      \u53c2\u6570\uff1a - flags (int): \u8981\u68c0\u7d22\u7684\u7edf\u8ba1\uff08\u9ed8\u8ba4\uff1a7 = \u5168\u90e8\uff09

      \u8fd4\u56de\uff1a \u5305\u542b\u53d1\u9001/\u63a5\u6536\u5b57\u8282\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/settings/#getapptxbytes","title":"getAppTxBytes()","text":"

      \u83b7\u53d6 QPython \u5e94\u7528\u7684\u53d1\u9001\u5b57\u8282\u3002

      getAppTxBytes(packageName)\n

      \u53c2\u6570\uff1a - packageName (str): \u5305\u540d

      \u8fd4\u56de\uff1a \u5305\u542b tx/rx \u5b57\u8282\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/settings/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5c4f\u5e55\u8bbe\u7f6e\ncurrent_timeout = droid.getScreenTimeout().result\nprint(f\"Current timeout: {current_timeout}s\")\ndroid.setScreenTimeout(30)\n\n# \u68c0\u67e5\u5c4f\u5e55\nif droid.checkScreenOn().result:\n    print(\"Screen is on\")\n\n# \u97f3\u91cf\u63a7\u5236\nmedia_vol = droid.getMediaVolume().result\nprint(f\"Media volume: {media_vol}\")\ndroid.setMediaVolume(10)\n\n# \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\nif droid.checkAirplaneMode().result:\n    print(\"Airplane mode is on\")\n
      "},{"location":"qsl4a/system/sysinfo/","title":"\u7cfb\u7edf\u4fe1\u606f","text":"

      \u68c0\u7d22\u8bbe\u5907\u548c\u7cfb\u7edf\u4fe1\u606f\u3002

      "},{"location":"qsl4a/system/sysinfo/#_2","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/sysinfo/#getandroidid","title":"getAndroidID()","text":"

      \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

      getAndroidID()\n

      \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

      "},{"location":"qsl4a/system/sysinfo/#getsysinfo","title":"getSysInfo()","text":"

      \u83b7\u53d6\u7efc\u5408\u7cfb\u7edf\u4fe1\u606f\u3002

      getSysInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/sysinfo/#getlocale","title":"getLocale()","text":"

      \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u8bbe\u7f6e\u3002

      getLocale()\n

      \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

      "},{"location":"qsl4a/system/sysinfo/#_3","title":"\u5185\u5b58","text":""},{"location":"qsl4a/system/sysinfo/#getmemoryinfo","title":"getMemoryInfo()","text":"

      \u83b7\u53d6 RAM \u4fe1\u606f\u3002

      getMemoryInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/sysinfo/#_4","title":"\u663e\u793a","text":""},{"location":"qsl4a/system/sysinfo/#getscreeninfo","title":"getScreenInfo()","text":"

      \u83b7\u53d6\u663e\u793a\u4fe1\u606f\u3002

      getScreenInfo()\n

      \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

      "},{"location":"qsl4a/system/sysinfo/#_5","title":"\u6807\u8bc6\u7b26","text":""},{"location":"qsl4a/system/sysinfo/#getimei","title":"getImei()","text":"

      \u83b7\u53d6\u8bbe\u5907 IMEI\u3002

      getImei(slotIndex=None)\n
      "},{"location":"qsl4a/system/sysinfo/#getmeid","title":"getMeid()","text":"

      \u83b7\u53d6\u8bbe\u5907 MEID\u3002

      getMeid(slotIndex=None)\n
      "},{"location":"qsl4a/system/sysinfo/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u8bbe\u5907 ID\nandroid_id = droid.getAndroidID().result\nprint(f\"Android ID: {android_id}\")\n\n# \u5c4f\u5e55\u4fe1\u606f\nscreen = droid.getScreenInfo().result\nprint(f\"Screen: {screen['width']}x{screen['height']}\")\n\n# \u5185\u5b58\nmemory = droid.getMemoryInfo().result\nprint(f\"Memory: {memory}\")\n
      "},{"location":"qsl4a/system/wakelock/","title":"WakeLock API","text":"

      \u63a7\u5236\u8bbe\u5907\u5524\u9192\u9501\u4ee5\u4fdd\u6301 CPU \u6216\u5c4f\u5e55\u5f00\u542f\u3002

      "},{"location":"qsl4a/system/wakelock/#wake-lock","title":"Wake Lock \u7c7b\u578b","text":"

      QSL4A \u63d0\u4f9b\u4e0d\u540c\u7c7b\u578b\u7684\u5524\u9192\u9501\uff1a

      \u7c7b\u578b \u63cf\u8ff0 Full CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae Partial \u4ec5 CPU \u5f00\u542f Bright CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae Dim CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697"},{"location":"qsl4a/system/wakelock/#wake-lock_1","title":"Wake Lock \u65b9\u6cd5","text":""},{"location":"qsl4a/system/wakelock/#wakelockacquirefull","title":"wakeLockAcquireFull()","text":"

      \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae\uff09\u3002

      wakeLockAcquireFull()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquirepartial","title":"wakeLockAcquirePartial()","text":"

      \u83b7\u53d6\u90e8\u5206\u5524\u9192\u9501\uff08\u4ec5 CPU \u5f00\u542f\uff09\u3002

      wakeLockAcquirePartial()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquirebright","title":"wakeLockAcquireBright()","text":"

      \u83b7\u53d6\u660e\u4eae\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff09\u3002

      wakeLockAcquireBright()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquiredim","title":"wakeLockAcquireDim()","text":"

      \u83b7\u53d6\u6697\u6de1\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697\uff09\u3002

      wakeLockAcquireDim()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockrelease","title":"wakeLockRelease()","text":"

      \u91ca\u653e\u5524\u9192\u9501\u3002

      wakeLockRelease()\n
      "},{"location":"qsl4a/system/wakelock/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\ndroid.wakeLockAcquireFull()\n\n# \u5728\u4fdd\u6301\u5c4f\u5e55\u5f00\u542f\u65f6\u6267\u884c\u91cd\u8981\u5de5\u4f5c\nprint(\"Screen will stay on\")\ntime.sleep(10)\n\n# \u5b8c\u6210\u540e\u91ca\u653e\ndroid.wakeLockRelease()\n\n# \u6216\u4f7f\u7528\u90e8\u5206\u9501\u8fdb\u884c\u540e\u53f0\u4efb\u52a1\ndroid.wakeLockAcquirePartial()\n# \u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\uff0cCPU \u4ecd\u4fdd\u6301\u5f00\u542f\ntime.sleep(30)\ndroid.wakeLockRelease()\n

      \u6ce8\u610f\uff1a \u8bb0\u4f4f\u5728\u4e0d\u9700\u8981\u65f6\u91ca\u653e\u5524\u9192\u9501\u4ee5\u8282\u7701\u7535\u6c60\u3002

      "},{"location":"qsl4a/ui/accessibility/","title":"\u65e0\u969c\u788d\u670d\u52a1","text":"

      \u65e0\u969c\u788d\u670d\u52a1\u5141\u8bb8\u81ea\u52a8\u5316 UI \u4ea4\u4e92\uff0c\u5982\u70b9\u51fb\u3001\u6ed1\u52a8\u548c\u7cfb\u7edf\u64cd\u4f5c\u3002

      "},{"location":"qsl4a/ui/accessibility/#_2","title":"\u670d\u52a1\u63a7\u5236","text":""},{"location":"qsl4a/ui/accessibility/#accessibilitystartservice","title":"accessibilityStartService()","text":"

      \u542f\u52a8\u65e0\u969c\u788d\u670d\u52a1\u3002

      accessibilityStartService()\n

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

      "},{"location":"qsl4a/ui/accessibility/#accessibilityserviceenabled","title":"accessibilityServiceEnabled()","text":"

      \u68c0\u67e5\u65e0\u969c\u788d\u670d\u52a1\u662f\u5426\u5df2\u542f\u7528\u3002

      accessibilityServiceEnabled()\n

      \u8fd4\u56de\uff1a True \u6216 False

      "},{"location":"qsl4a/ui/accessibility/#_3","title":"\u5c4f\u5e55\u4ea4\u4e92","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityclick","title":"accessibilityClick()","text":"

      \u5728\u5c4f\u5e55\u5750\u6807\u5904\u70b9\u51fb\u3002

      accessibilityClick(x=0, y=0, t=50)\n

      \u53c2\u6570\uff1a - x (int/float): X \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - y (int/float): Y \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - t (int): \u6309\u4f4f\u65f6\u957f\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a50\uff09

      "},{"location":"qsl4a/ui/accessibility/#accessibilityslide","title":"accessibilitySlide()","text":"

      \u591a\u70b9\u6ed1\u52a8\u624b\u52bf\u3002

      accessibilitySlide(XnYn=None, t=None)\n

      \u53c2\u6570\uff1a - XnYn (list): \u5750\u6807 [X1, Y1, X2, Y2, ... Xn, Yn] - t (int): \u6ed1\u52a8\u65f6\u957f\uff08\u9ed8\u8ba4\uff1a50*n \u6beb\u79d2\uff09

      "},{"location":"qsl4a/ui/accessibility/#_4","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityaction","title":"accessibilityAction()","text":"

      \u6309\u4ee3\u7801\u6267\u884c\u7cfb\u7edf\u64cd\u4f5c\u3002

      accessibilityAction(actionCode)\n

      \u64cd\u4f5c\u4ee3\u7801\uff1a | \u4ee3\u7801 | \u5e38\u91cf | \u63cf\u8ff0 | |------|----------|-------------| | 1 | BACK | \u8fd4\u56de\u6309\u94ae | | 2 | HOME | \u4e3b\u5c4f\u5e55\u6309\u94ae | | 3 | RECENTS | \u6700\u8fd1\u5e94\u7528 | | 4 | NOTIFICATIONS | \u6253\u5f00\u901a\u77e5 | | 5 | QUICK_SETTINGS | \u6253\u5f00\u5feb\u901f\u8bbe\u7f6e | | 6 | POWER_DIALOG | \u7535\u6e90\u83dc\u5355 | | 7 | TOGGLE_SPLIT_SCREEN | \u5206\u5c4f | | 8 | LOCK_SCREEN | \u9501\u5c4f | | 9 | TAKE_SCREENSHOT | \u622a\u56fe | | 10 | KEYCODE_HEADSETHOOK | \u8033\u673a\u6302\u94a9 | | 11-14 | ACCESSIBILITY_ | \u65e0\u969c\u788d\u6309\u94ae | | 15 | DISMISS_NOTIFICATION_SHADE | \u5173\u95ed\u901a\u77e5\u680f | | 16-20 | DPAD_ | \u65b9\u5411\u952e | | 21 | MENU | \u83dc\u5355\u6309\u94ae | | 22 | MEDIA_PLAY_PAUSE | \u64ad\u653e/\u6682\u505c\u5a92\u4f53 |

      "},{"location":"qsl4a/ui/accessibility/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/accessibility/#_6","title":"\u70b9\u51fb\u5c4f\u5e55\u4e2d\u5fc3","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u670d\u52a1\nif not droid.accessibilityServiceEnabled().result:\n    droid.accessibilityStartService()\n\n# \u70b9\u51fb\u4e2d\u5fc3\uff080,0 = \u4e2d\u5fc3\uff09\ndroid.accessibilityClick(0, 0, t=100)\n
      "},{"location":"qsl4a/ui/accessibility/#_7","title":"\u6ed1\u52a8\u624b\u52bf","text":"
      # \u4ece\u4e0b\u5f80\u4e0a\u6ed1\u52a8\uff08\u5411\u4e0a\u6eda\u52a8\uff09\ndroid.accessibilitySlide([0, 1.5, 0, -1.5], t=300)\n
      "},{"location":"qsl4a/ui/accessibility/#_8","title":"\u7cfb\u7edf\u5bfc\u822a","text":"
      # \u6309\u4e3b\u5c4f\u5e55\ndroid.accessibilityAction(2)\n\n# \u6309\u8fd4\u56de\ndroid.accessibilityAction(1)\n\n# \u6253\u5f00\u901a\u77e5\ndroid.accessibilityAction(4)\n
      "},{"location":"qsl4a/ui/accessibility/#_9","title":"\u70b9\u51fb\u7279\u5b9a\u4f4d\u7f6e","text":"
      # \u70b9\u51fb\u5c4f\u5e55\u5750\u6807 (500, 800)\ndroid.accessibilityClick(500, 800)\n\n# \u70b9\u51fb\u76f8\u5bf9\u4f4d\u7f6e\uff08\u6c34\u5e73\u5c45\u4e2d\uff0c\u5782\u76f4 3/4 \u5904\uff09\ndroid.accessibilityClick(0, 1.5)\n
      "},{"location":"qsl4a/ui/dialogs/","title":"\u5bf9\u8bdd\u6846\u7cfb\u7edf","text":"

      QSL4A \u63d0\u4f9b\u5168\u9762\u7684\u5bf9\u8bdd\u6846\u652f\u6301\uff0c\u7528\u4e8e\u7528\u6237\u4ea4\u4e92\uff0c\u5305\u62ec\u8b66\u62a5\u3001\u8f93\u5165\u5bf9\u8bdd\u6846\u3001\u9009\u62e9\u5bf9\u8bdd\u6846\u548c\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

      "},{"location":"qsl4a/ui/dialogs/#_2","title":"\u8b66\u62a5\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowalert","title":"dialogShowAlert()","text":"

      \u663e\u793a\u7b80\u5355\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

      dialogShowAlert(title=\"Alert\", message=\"The message of the alert.\",\n                positiveButtonText=\"OK\", negativeButtonText=None,\n                neutralButtonText=None, messageIsHtml=False)\n

      \u53c2\u6570\uff1a - title (str): \u5bf9\u8bdd\u6846\u6807\u9898 - message (str): \u6d88\u606f\u6587\u672c - positiveButtonText (str): \u80af\u5b9a\u6309\u94ae\u6807\u7b7e - negativeButtonText (str, optional): \u5426\u5b9a\u6309\u94ae\u6807\u7b7e - neutralButtonText (str, optional): \u4e2d\u6027\u6309\u94ae\u6807\u7b7e - messageIsHtml (bool): \u5c06\u6d88\u606f\u89e3\u6790\u4e3a HTML

      \u8fd4\u56de\uff1a \u5305\u542b\u70b9\u51fb\u6309\u94ae\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#dialogshowsimplechoice","title":"dialogShowSimpleChoice()","text":"

      \u663e\u793a\u5e26\u6709\u9879\u76ee\u7684\u7b80\u5355\u9009\u62e9\u5bf9\u8bdd\u6846\u3002

      dialogShowSimpleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

      \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868

      \u8fd4\u56de\uff1a \u5305\u542b\u9009\u4e2d\u9879\u76ee\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#_3","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialoggetinput","title":"dialogGetInput()","text":"

      \u83b7\u53d6\u7528\u6237\u6587\u672c\u8f93\u5165\u3002

      dialogGetInput(title=\"Value\", message=\"Please enter value:\",\n               defaultText=None, messageIsHtml=False)\n

      \u8fd4\u56de\uff1a \u5305\u542b\u7528\u6237\u8f93\u5165\u6587\u672c\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#dialoggetpassword","title":"dialogGetPassword()","text":"

      \u83b7\u53d6\u5bc6\u7801\u8f93\u5165\u3002

      dialogGetPassword(title=\"Password\", message=\"Please enter password:\")\n

      \u8fd4\u56de\uff1a \u5305\u542b\u8f93\u5165\u5bc6\u7801\u7684\u7ed3\u679c

      "},{"location":"qsl4a/ui/dialogs/#dialogcreateinput","title":"dialogCreateInput()","text":"

      \u521b\u5efa\u81ea\u5b9a\u4e49\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

      dialogCreateInput(title=\"Value\", message=\"Please enter value:\",\n                  defaultText=None, inputType=None)\n

      \u53c2\u6570\uff1a - inputType (str): \u8f93\u5165\u7c7b\u578b\uff08\u4f8b\u5982 \"text\"\u3001\"number\"\u3001\"textPassword\"\uff09

      "},{"location":"qsl4a/ui/dialogs/#dialogcreatepassword","title":"dialogCreatePassword()","text":"

      \u521b\u5efa\u5bc6\u7801\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

      dialogCreatePassword(title=\"Password\", message=\"Please enter password:\")\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreateseekbar","title":"dialogCreateSeekBar()","text":"

      \u521b\u5efa\u6ed1\u5757/\u8fdb\u5ea6\u6761\u5bf9\u8bdd\u6846\u3002

      dialogCreateSeekBar(starting_value=50, maximum_value=100, title=\"\", message=\"\")\n

      \u53c2\u6570\uff1a - starting_value (int): \u521d\u59cb\u503c - maximum_value (int): \u6700\u5927\u503c

      "},{"location":"qsl4a/ui/dialogs/#_4","title":"\u9009\u62e9\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowsinglechoice","title":"dialogShowSingleChoice()","text":"

      \u663e\u793a\u5355\u9009\uff08\u5355\u9009\u6309\u94ae\uff09\u5bf9\u8bdd\u6846\u3002

      dialogShowSingleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, selected=-1, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

      \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (int): \u9ed8\u8ba4\u9009\u4e2d\u7d22\u5f15

      "},{"location":"qsl4a/ui/dialogs/#dialogshowmultichoice","title":"dialogShowMultiChoice()","text":"

      \u663e\u793a\u591a\u9009\uff08\u590d\u9009\u6846\uff09\u5bf9\u8bdd\u6846\u3002

      dialogShowMultiChoice(title=\"Alert\", message=\"The message of the alert.\",\n                      items=None, selected=None, positiveButtonText=\"OK\",\n                      negativeButtonText=None, neutralButtonText=None,\n                      messageIsHtml=False)\n

      \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (list): \u521d\u59cb\u9009\u4e2d\u7d22\u5f15\u5217\u8868

      "},{"location":"qsl4a/ui/dialogs/#dialogsetsinglechoiceitems","title":"dialogSetSingleChoiceItems()","text":"

      \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u5355\u9009\u9879\u76ee\u3002

      dialogSetSingleChoiceItems(items, selected=-1)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmultichoiceitems","title":"dialogSetMultiChoiceItems()","text":"

      \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u591a\u9009\u9879\u76ee\u3002

      dialogSetMultiChoiceItems(items, selected=None)\n
      "},{"location":"qsl4a/ui/dialogs/#_5","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatespinnerprogress","title":"dialogCreateSpinnerProgress()","text":"

      \u521b\u5efa\u4e0d\u786e\u5b9a\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

      dialogCreateSpinnerProgress(title=None, message=None, maximum_progress=100)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreatehorizontalprogress","title":"dialogCreateHorizontalProgress()","text":"

      \u521b\u5efa\u6c34\u5e73\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

      dialogCreateHorizontalProgress(title=None, message=None, maximum_progress=100)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetcurrentprogress","title":"dialogSetCurrentProgress()","text":"

      \u66f4\u65b0\u8fdb\u5ea6\u503c\u3002

      dialogSetCurrentProgress(current)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmaxprogress","title":"dialogSetMaxProgress()","text":"

      \u8bbe\u7f6e\u6700\u5927\u8fdb\u5ea6\u503c\u3002

      dialogSetMaxProgress(max)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetprogressmessage","title":"dialogSetProgressMessage()","text":"

      \u66f4\u65b0\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u6d88\u606f\u3002

      dialogSetProgressMessage(message)\n
      "},{"location":"qsl4a/ui/dialogs/#_6","title":"\u9009\u62e9\u5668\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatedatepicker","title":"dialogCreateDatePicker()","text":"

      \u521b\u5efa\u65e5\u671f\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

      dialogCreateDatePicker(year=1970, month=1, day=1)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreatetimepicker","title":"dialogCreateTimePicker()","text":"

      \u521b\u5efa\u65f6\u95f4\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

      dialogCreateTimePicker(hour=0, minute=0, is24hour=False)\n
      "},{"location":"qsl4a/ui/dialogs/#_7","title":"\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u521b\u5efa","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatealert","title":"dialogCreateAlert()","text":"

      \u521b\u5efa\u81ea\u5b9a\u4e49\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

      dialogCreateAlert(title=None, message=None)\n

      \u521b\u5efa\u4e00\u4e2a\u7a7a\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002\u53ef\u4e0e\u5176\u4ed6 dialogSet* \u51fd\u6570\u4e00\u8d77\u4f7f\u7528\u6765\u81ea\u5b9a\u4e49\u3002

      "},{"location":"qsl4a/ui/dialogs/#dialogsetitems","title":"dialogSetItems()","text":"

      \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u7b80\u5355\u5217\u8868\u9879\u76ee\u3002

      dialogSetItems(items)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetpositivebuttontext","title":"dialogSetPositiveButtonText()","text":"

      \u8bbe\u7f6e\u80af\u5b9a\u6309\u94ae\u6587\u672c\u3002

      dialogSetPositiveButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetnegativebuttontext","title":"dialogSetNegativeButtonText()","text":"

      \u8bbe\u7f6e\u5426\u5b9a\u6309\u94ae\u6587\u672c\u3002

      dialogSetNegativeButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetneutralbuttontext","title":"dialogSetNeutralButtonText()","text":"

      \u8bbe\u7f6e\u4e2d\u6027\u6309\u94ae\u6587\u672c\u3002

      dialogSetNeutralButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmessageishtml","title":"dialogSetMessageIsHtml()","text":"

      \u8bbe\u7f6e\u6d88\u606f\u662f\u5426\u5e94\u89e3\u6790\u4e3a HTML\u3002

      dialogSetMessageIsHtml(messageIsHtml=True)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogshow","title":"dialogShow()","text":"

      \u663e\u793a\u521b\u5efa\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u3002

      dialogShow()\n
      "},{"location":"qsl4a/ui/dialogs/#_8","title":"\u5bf9\u8bdd\u6846\u63a7\u5236","text":""},{"location":"qsl4a/ui/dialogs/#dialogdismiss","title":"dialogDismiss()","text":"

      \u5173\u95ed\u5f53\u524d\u5bf9\u8bdd\u6846\u3002

      dialogDismiss()\n
      "},{"location":"qsl4a/ui/dialogs/#dialoggetresponse","title":"dialogGetResponse()","text":"

      \u83b7\u53d6\u5bf9\u8bdd\u6846\u54cd\u5e94\u3002

      dialogGetResponse()\n
      "},{"location":"qsl4a/ui/dialogs/#dialoggetselecteditems","title":"dialogGetSelectedItems()","text":"

      \u4ece\u9009\u62e9\u5bf9\u8bdd\u6846\u83b7\u53d6\u9009\u4e2d\u7684\u9879\u76ee\u3002

      dialogGetSelectedItems()\n
      "},{"location":"qsl4a/ui/dialogs/#_9","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/dialogs/#_10","title":"\u7b80\u5355\u8b66\u62a5","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a\u8b66\u62a5\ndroid.dialogShowAlert(\"Warning\", \"This is an important message!\")\n
      "},{"location":"qsl4a/ui/dialogs/#_11","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":"
      # \u83b7\u53d6\u7528\u6237\u8f93\u5165\nresult = droid.dialogGetInput(\"Name\", \"Enter your name:\", \"John\").result\nprint(f\"Hello, {result}!\")\n
      "},{"location":"qsl4a/ui/dialogs/#_12","title":"\u5e26\u6309\u94ae\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846","text":"
      # \u521b\u5efa\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\ndroid.dialogCreateAlert(\"Custom\", \"Choose an option\")\ndroid.dialogSetItems([\"Option 1\", \"Option 2\", \"Option 3\"])\ndroid.dialogShow()\n\n# \u83b7\u53d6\u54cd\u5e94\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response['item']}\")\n
      "},{"location":"qsl4a/ui/dialogs/#_13","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":"
      # \u521b\u5efa\u8fdb\u5ea6\u5bf9\u8bdd\u6846\ndroid.dialogCreateHorizontalProgress(\"Loading\", \"Please wait...\", 100)\ndroid.dialogShow()\n\n# \u66f4\u65b0\u8fdb\u5ea6\nfor i in range(101):\n    droid.dialogSetCurrentProgress(i)\n    time.sleep(0.05)\n\ndroid.dialogDismiss()\n
      "},{"location":"qsl4a/ui/dialogs/#_14","title":"\u65e5\u671f\u9009\u62e9\u5668","text":"
      # \u663e\u793a\u65e5\u671f\u9009\u62e9\u5668\ndroid.dialogCreateDatePicker(2024, 1, 15)\ndroid.dialogShow()\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response}\")\n
      "},{"location":"qsl4a/ui/floatview/","title":"\u6d6e\u52a8\u89c6\u56fe","text":"

      \u6d6e\u52a8\u7a97\u53e3\u652f\u6301\uff0c\u7528\u4e8e\u5728\u5176\u4ed6\u5e94\u7528\u7a0b\u5e8f\u4e0a\u65b9\u4fdd\u6301\u663e\u793a\u7684\u8986\u76d6 UI \u5143\u7d20\u3002

      "},{"location":"qsl4a/ui/floatview/#_2","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/floatview/#floatview","title":"floatView()","text":"

      \u663e\u793a\u6216\u4fee\u6539\u6d6e\u52a8\u89c6\u56fe\u3002

      floatView(Args=None)\n

      \u53c2\u6570\uff1a - Args (dict): \u914d\u7f6e\u5b57\u5178\uff0c\u5305\u542b\u4ee5\u4e0b\u952e\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08-1 \u521b\u5efa\u65b0\u7684\uff0c>=0 \u4fee\u6539\u73b0\u6709\u7684\uff09 - text (str): \u8981\u663e\u793a\u7684\u6587\u672c\u5185\u5bb9 - html (str): HTML \u5185\u5bb9\uff08\u5982\u679c\u7701\u7565 text \u5219\u4f7f\u7528\uff09 - width (int): \u89c6\u56fe\u5bbd\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a300\uff09 - height (int): \u89c6\u56fe\u9ad8\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a150\uff09 - x (int): X \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - y (int): Y \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - backColor (str): ARGB \u5341\u516d\u8fdb\u5236\u80cc\u666f\u8272\uff08\u9ed8\u8ba4\uff1a'7f7f7f7f'\uff09 - textColor (str): ARGB \u5341\u516d\u8fdb\u5236\u6587\u672c\u8272\uff08\u9ed8\u8ba4\uff1a'ff000000'\uff09 - textSize (int): \u6587\u672c\u5927\u5c0f\uff08\u9ed8\u8ba4\uff1a10\uff09 - textAlign (int): \u6587\u672c\u5bf9\u9f50\uff080 = \u7ee7\u627f\uff09 - script (str): \u957f\u6309\u5173\u95ed\u540e\u8fd0\u884c\u7684\u811a\u672c\u8def\u5f84 - arg: \u811a\u672c\u53c2\u6570 - clickRemove (bool): \u542f\u7528\u70b9\u51fb\u79fb\u9664\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - flag (int): \u7a97\u53e3\u6807\u5fd7\uff08\u9ed8\u8ba4\uff1a40 - \u53ef\u89e6\u6478\uff09

      \u8fd4\u56de\uff1a \u5f53\u524d\u94fe\u5217\u8868\u957f\u5ea6

      "},{"location":"qsl4a/ui/floatview/#floatviewcount","title":"floatViewCount()","text":"

      \u83b7\u53d6\u6d3b\u52a8\u6d6e\u52a8\u89c6\u56fe\u7684\u6570\u91cf\u3002

      floatViewCount()\n

      \u8fd4\u56de\uff1a \u6d6e\u52a8\u89c6\u56fe\u6570\u91cf

      "},{"location":"qsl4a/ui/floatview/#floatviewresult","title":"floatViewResult()","text":"

      \u83b7\u53d6\u6d6e\u52a8\u89c6\u56fe\u7684\u7ed3\u679c/\u72b6\u6001\u3002

      floatViewResult(index=-1)\n

      \u53c2\u6570\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1\uff0c\u8fd4\u56de\u6700\u540e\u64cd\u4f5c\u7ed3\u679c\uff09

      \u8fd4\u56de\uff1a \u5305\u542b\u64cd\u4f5c\u8be6\u60c5\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - x, y: \u4f4d\u7f6e - time: \u65f6\u95f4\u6233 - operation: \u64cd\u4f5c\u7c7b\u578b\uff08'initial'\u3001'move' \u7b49\uff09 - index: \u89c6\u56fe\u7d22\u5f15 - removed: \u5982\u679c\u89c6\u56fe\u88ab\u79fb\u9664\u5219\u4e3a True

      "},{"location":"qsl4a/ui/floatview/#floatviewremove","title":"floatViewRemove()","text":"

      \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\u3002

      floatViewRemove(index=-1)\n

      \u53c2\u6570\uff1a - index (int): \u8981\u79fb\u9664\u7684\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1 \u79fb\u9664\u6700\u540e\u4e00\u4e2a\uff09

      \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a 1\uff0c\u5426\u5219\u4e3a 0

      "},{"location":"qsl4a/ui/floatview/#_3","title":"\u5e38\u91cf","text":"
      • floatView.INDEX_NEW = -1 - \u521b\u5efa\u65b0\u7684\u6d6e\u52a8\u89c6\u56fe
      • floatView.FLAG_DEFAULT_TOUCHABLE = 40 - \u9ed8\u8ba4\u53ef\u89e6\u6478\u6807\u5fd7
      • floatView.TEXT_ALIGNMENT_INHERIT = 0
      • floatView.TEXT_ALIGNMENT_CENTER - \u5c45\u4e2d\u6587\u672c\u5bf9\u9f50
      "},{"location":"qsl4a/ui/floatview/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/floatview/#_5","title":"\u57fa\u672c\u6d6e\u52a8\u89c6\u56fe","text":"
      import androidhelper\nfrom androidhelper import Android\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u7b80\u5355\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'index': -1,  # \u521b\u5efa\u65b0\u7684\n    'text': 'Hello World',\n    'width': 400,\n    'height': 300,\n    'x': -300,  # \u4ece\u4e2d\u5fc3\u504f\u79fb\n    'y': -400,\n    'backColor': 'ff0000',  # \u7ea2\u8272\u80cc\u666f\n    'textColor': '0000ff',  # \u84dd\u8272\u6587\u672c\n    'textSize': 16,\n    'textAlign': droid.floatView.TEXT_ALIGNMENT_CENTER\n})\n\n# \u68c0\u67e5\u6570\u91cf\nprint(f\"Float views: {droid.floatViewCount().result}\")\n\n# \u83b7\u53d6\u7ed3\u679c\nresult = droid.floatViewResult().result\nprint(f\"View info: {result}\")\n\n# \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\ndroid.floatViewRemove(0)\n
      "},{"location":"qsl4a/ui/floatview/#html","title":"HTML \u5185\u5bb9","text":"
      # \u521b\u5efa\u5e26 HTML \u5185\u5bb9\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': '',  # \u7a7a\u6587\u672c\u4ee5\u4f7f\u7528 HTML\n    'html': '<h1>Title</h1><p>Rich <b>HTML</b> content</p>',\n    'width': 500,\n    'height': 400\n})\n
      "},{"location":"qsl4a/ui/floatview/#_6","title":"\u4fee\u6539\u73b0\u6709\u89c6\u56fe","text":"
      # \u521b\u5efa\u521d\u59cb\u89c6\u56fe\ndroid.floatView({'text': 'Initial Text', 'width': 300, 'height': 150})\n\n# \u4fee\u6539\u540c\u4e00\u89c6\u56fe\uff08\u7d22\u5f15 0\uff09\ndroid.floatView({\n    'index': 0,\n    'text': 'Updated Text!',\n    'backColor': '7f00ff00'  # \u7eff\u8272\u80cc\u666f\n})\n\n# \u68c0\u67e5\u79fb\u52a8/\u66f4\u6539\u7ed3\u679c\nresult = droid.floatViewResult(0).result\nprint(f\"Operation: {result.get('operation')}, Position: ({result.get('x')}, {result.get('y')})\")\n
      "},{"location":"qsl4a/ui/floatview/#_7","title":"\u591a\u4e2a\u6d6e\u52a8\u89c6\u56fe","text":"
      # \u521b\u5efa\u591a\u4e2a\u89c6\u56fe\nfor i in range(3):\n    droid.floatView({\n        'index': -1,\n        'text': f'View {i}',\n        'x': i * 100 - 150,\n        'y': i * 100 - 150,\n        'backColor': f'{i}f{i}f{i}f'\n    })\n\nprint(f\"Total views: {droid.floatViewCount().result}\")\n\n# \u79fb\u9664\u6240\u6709\u89c6\u56fe\nwhile droid.floatViewCount().result > 0:\n    droid.floatViewRemove()\n
      "},{"location":"qsl4a/ui/floatview/#_8","title":"\u5e26\u811a\u672c\u56de\u8c03","text":"
      # \u521b\u5efa\u5173\u95ed\u65f6\u8fd0\u884c\u811a\u672c\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': 'Click to close and run script',\n    'script': '/sdcard/my_script.py',\n    'arg': 'hello from float view',\n    'clickRemove': True\n})\n
      "},{"location":"qsl4a/ui/fullscreen/","title":"\u5168\u5c4f UI","text":"

      \u4f7f\u7528\u539f\u751f Android \u5e03\u5c40\u521b\u5efa\u81ea\u5b9a\u4e49\u5168\u5c4f\u754c\u9762\u3002

      "},{"location":"qsl4a/ui/fullscreen/#_1","title":"\u5e03\u5c40\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullshow","title":"fullShow()","text":"

      \u663e\u793a\u5168\u5c4f\u5e03\u5c40\u3002

      fullShow(layout, title=None, theme=None)\n

      \u53c2\u6570\uff1a - layout (str): JSON \u5e03\u5c40\u5b9a\u4e49\u6216\u5e03\u5c40\u5b57\u7b26\u4e32 - title (str, optional): \u7a97\u53e3\u6807\u9898 - theme (str, optional): \u4e3b\u9898\u540d\u79f0

      \u8fd4\u56de\uff1a \u7a97\u53e3 ID

      "},{"location":"qsl4a/ui/fullscreen/#fulldismiss","title":"fullDismiss()","text":"

      \u5173\u95ed\u5168\u5c4f\u7a97\u53e3\u3002

      fullDismiss()\n
      "},{"location":"qsl4a/ui/fullscreen/#fullquery","title":"fullQuery()","text":"

      \u67e5\u8be2\u6240\u6709\u5c0f\u90e8\u4ef6\u503c\u3002

      fullQuery()\n

      \u8fd4\u56de\uff1a \u5c0f\u90e8\u4ef6 ID \u548c\u503c\u7684\u5b57\u5178

      "},{"location":"qsl4a/ui/fullscreen/#fullquerydetail","title":"fullQueryDetail()","text":"

      \u67e5\u8be2\u7279\u5b9a\u5c0f\u90e8\u4ef6\u8be6\u60c5\u3002

      fullQueryDetail(id)\n
      "},{"location":"qsl4a/ui/fullscreen/#_2","title":"\u5c5e\u6027\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperty","title":"fullGetProperty()","text":"

      \u83b7\u53d6\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

      fullGetProperty(id, property)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetproperty","title":"fullSetProperty()","text":"

      \u8bbe\u7f6e\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

      fullSetProperty(id, property, value)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetlist","title":"fullSetList()","text":"

      \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

      fullSetList(id, list, isHtml=False, listType=0)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetlist2","title":"fullSetList2()","text":"

      \u4f7f\u7528\u8d44\u6e90 ID \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

      fullSetList2(id, list, intRes)\n

      \u53c2\u6570\uff1a - id (str): \u5c0f\u90e8\u4ef6 ID - list (list): \u9879\u76ee\u5217\u8868 - intRes (int): \u5217\u8868\u9879\u76ee\u5e03\u5c40\u7684 Android \u8d44\u6e90 ID

      "},{"location":"qsl4a/ui/fullscreen/#fullsetlistselected","title":"fullSetListSelected()","text":"

      \u5728\u5217\u8868\u4e2d\u8bbe\u7f6e\u9009\u4e2d\u9879\u76ee\u3002

      fullSetListSelected(id, selected)\n

      \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID - selected (int): \u8981\u9009\u4e2d\u7684\u9879\u76ee\u7d22\u5f15

      "},{"location":"qsl4a/ui/fullscreen/#fullgetlistselected","title":"fullGetListSelected()","text":"

      \u83b7\u53d6\u5f53\u524d\u9009\u4e2d\u7684\u5217\u8868\u9879\u76ee\u7d22\u5f15\u3002

      fullGetListSelected(id)\n

      \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID

      \u8fd4\u56de\uff1a \u9009\u4e2d\u9879\u76ee\u7d22\u5f15

      "},{"location":"qsl4a/ui/fullscreen/#_3","title":"\u6279\u91cf\u5c5e\u6027\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperties","title":"fullGetProperties()","text":"

      \u4e00\u6b21\u83b7\u53d6\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

      fullGetProperties(ids, property)\n

      \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u83b7\u53d6\u7684\u5c5e\u6027\u540d

      \u8fd4\u56de\uff1a \u6620\u5c04\u5c0f\u90e8\u4ef6 ID \u5230\u5c5e\u6027\u503c\u7684\u5b57\u5178

      "},{"location":"qsl4a/ui/fullscreen/#fullsetproperties","title":"fullSetProperties()","text":"

      \u4e00\u6b21\u8bbe\u7f6e\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

      fullSetProperties(ids, property, value)\n

      \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u8bbe\u7f6e\u7684\u5c5e\u6027\u540d - value: \u5c5e\u6027\u503c

      "},{"location":"qsl4a/ui/fullscreen/#_4","title":"\u622a\u56fe","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetscreenshot","title":"fullGetScreenShot()","text":"

      \u6355\u83b7\u5168\u5c4f\u622a\u56fe\u3002

      fullGetScreenShot(path=None)\n

      \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u5728\u4e8b\u4ef6\u4e2d\u8fd4\u56de

      \u8fd4\u56de\uff1a \u5305\u542b\u622a\u56fe\u6570\u636e\u7684\u4e8b\u4ef6

      "},{"location":"qsl4a/ui/fullscreen/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b9a\u4e49\u5e03\u5c40\nlayout = '''\n{ \"type\": \"LinearLayout\", \"orientation\": \"vertical\",\n  \"children\": [\n    { \"type\": \"TextView\", \"id\": \"title\", \"text\": \"Hello\" },\n    { \"type\": \"Button\", \"id\": \"btn\", \"text\": \"Click Me\" }\n  ]\n}\n'''\n\n# \u663e\u793a\u5e03\u5c40\ndroid.fullShow(layout, \"My App\")\n\n# \u67e5\u8be2\u6309\u94ae\u70b9\u51fb\nevent = droid.eventWaitFor('click', timeout=10)\nif event.result:\n    widget_id = event.result['data']['id']\n    if widget_id == 'btn':\n        print(\"Button clicked!\")\n\ndroid.fullDismiss()\n
      "}]} \ No newline at end of file diff --git a/zh/sitemap.xml b/zh/sitemap.xml index bd82aa8..2835e18 100644 --- a/zh/sitemap.xml +++ b/zh/sitemap.xml @@ -2,198 +2,202 @@ https://www.qpython.org/zh/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/AIPyApp/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/GraphicalInterface/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/Notebook/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/Ollama/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/Terminal/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/community/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/editor-guide/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/external-api/ - 2026-04-08 + 2026-04-10 + + + https://www.qpython.org/zh/featured-courses/ + 2026-04-10 https://www.qpython.org/zh/getting-started/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/qpypi-guide/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/qpython-x/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/tutorial-hello-world/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/whats-new/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/qsl4a/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/qsl4a/connectivity/contacts/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/qsl4a/connectivity/ftp/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/qsl4a/connectivity/location/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/qsl4a/connectivity/phone/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/qsl4a/connectivity/signalstrength/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/qsl4a/connectivity/sms/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/qsl4a/connectivity/wifi/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/qsl4a/core/android-base/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/qsl4a/core/events/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/qsl4a/core/intent/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/qsl4a/hardware/bluetooth/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/qsl4a/hardware/camera/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/qsl4a/hardware/recorder/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/qsl4a/hardware/usbserial/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/qsl4a/hardware/webcam/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/qsl4a/media/image/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/qsl4a/media/mediaplayer/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/qsl4a/special/cipher/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/qsl4a/special/pgptai/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/qsl4a/storage/clipboard/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/qsl4a/storage/documentfile/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/qsl4a/storage/preferences/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/qsl4a/system/activityresult/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/qsl4a/system/application/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/qsl4a/system/battery/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/qsl4a/system/qpyinterface/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/qsl4a/system/sensors/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/qsl4a/system/settings/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/qsl4a/system/sysinfo/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/qsl4a/system/wakelock/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/qsl4a/ui/accessibility/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/qsl4a/ui/dialogs/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/qsl4a/ui/floatview/ - 2026-04-08 + 2026-04-10 https://www.qpython.org/zh/qsl4a/ui/fullscreen/ - 2026-04-08 + 2026-04-10 \ No newline at end of file diff --git a/zh/sitemap.xml.gz b/zh/sitemap.xml.gz index b7beb395572b34625294fbe910a0ba367cc0bc58..3ec25aabc3762f333845f0d6f4f3273629d7937b 100644 GIT binary patch literal 621 zcmV-z0+Rh7iwFpSJ=kdi|8r?{Wo=<_E_iKh0L7TWZrd;nhVOlfAa}=UQ4HIVrs$KTDygE$TGs;Gd1K({2k@UH)=Xu^S3679>7js{;8??doR{Pt=x;C4AKg)-kRiQBmOzL8gpt<>HhXxu|%LBAOyA7RZ8aQEhD|GVt`J zS-lojl}Y28G`A8iJ|UjL(uW^fH*!jOGD4Q%5EY8EXh_j?`8SFj_I-34>9ZP<7HGI*5V# z0J)t(2^v44#Aq@X-XR=}n8A`Dqxz%8Y{@Wj!?+dJ0;eQU3#=rV)BHQ$L@R zhs7iiIH6m;?6Y`BFze#l$aXwrMC><5p=os(If;^yz>#{L?+uStNi3WyNviBx$u0^iFEu8F^d+J HP8k3I!qqKG literal 609 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

    912. + + + + + + + + 精选课程 + + + + + + + + +
    913. + + + + diff --git a/zh/whats-new/index.html b/zh/whats-new/index.html index a587143..ba4c350 100644 --- a/zh/whats-new/index.html +++ b/zh/whats-new/index.html @@ -863,6 +863,34 @@ + + + + + + +
    914. + + + + + + + + 精选课程 + + + + + + + + +
    915. + + + + From 3f1eb396d754e1f097b6d290febc945ca1d0b01d Mon Sep 17 00:00:00 2001 From: "River@devbox" Date: Tue, 21 Apr 2026 18:31:46 +0800 Subject: [PATCH 32/32] Deploy site - 2026-04-21 18:31:46 --- en/index.html | 10 +++- en/search/search_index.json | 2 +- en/sitemap.xml | 98 +++++++++++++++++------------------ en/sitemap.xml.gz | Bin 608 -> 608 bytes en/whats-new/index.html | 28 ++++++++++ zh/index.html | 10 +++- zh/search/search_index.json | 2 +- zh/sitemap.xml | 100 ++++++++++++++++++------------------ zh/sitemap.xml.gz | Bin 621 -> 621 bytes zh/whats-new/index.html | 28 ++++++++++ 10 files changed, 175 insertions(+), 103 deletions(-) diff --git a/en/index.html b/en/index.html index 8a984a6..acb7229 100644 --- a/en/index.html +++ b/en/index.html @@ -2514,8 +2514,16 @@

      Programming GuideDownload Resources

      +

      Latest Version v4.0.0:

        -
      • Google Drive
      • +
      • External Storage Access: Users can now save Python scripts directly to external storage devices, greatly improving file management flexibility.
      • +
      • QSL4A Enhanced: Improved QSL4A functionality.
      • +
      • +

        Community & Courses: Optimized community and courses modules, providing clearer information and more convenient navigation for accessing learning resources and support.

        +
      • +
      • +

        Google Drive

        +
      • 微信网盘

      Community & Feedback

      diff --git a/en/search/search_index.json b/en/search/search_index.json index 0f58784..a73de0a 100644 --- a/en/search/search_index.json +++ b/en/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"QPython Project","text":"

      QPython project is not only a powerful Python IDE for Android, but also an active technology community.

      "},{"location":"#ai-enabled-python-ide-for-android","title":"AI-Enabled Python IDE for Android","text":"

      QPython is your gateway to Python programming on Android. With an integrated Python interpreter, AI model engine, and mobile development toolchain, it empowers you to build web applications, perform scientific computing, and create intelligent apps \u2014 all from your mobile device.

      Whether you're learning to code, building data science projects, or developing AI-powered applications, QPython provides a complete mobile programming solution with comprehensive developer resources and an active community to support your journey.

      • Branches \u2013 Learn about the different QPython versions (IDE, Community, Plus) and choose the right one for your needs
      • Updates \u2013 Stay informed about the latest features, improvements, and release notes
      "},{"location":"#getting-started","title":"Getting Started","text":"

      How to start quickly? Just follow these steps:

      • Getting Started
      • Hello World Tutorial
      "},{"location":"#programming-guide","title":"Programming Guide","text":"

      QPython not only provides basic Python interface support, but more importantly, it also enables you to call Android APIs using Python through the QSL4A interface.

      • Python Standard Library \u2013 For general Python syntax and built-in libraries
      • QSL4A API \u2013 For accessing Android device features (camera, sensors, SMS, etc.) from Python
      • QPYPI Guide \u2013 For installing additional Python packages
      • Editor Guide \u2013 For using the built-in code editor
      • External API \u2013 For integrating with external applications
      "},{"location":"#download-resources","title":"Download Resources","text":"
      • Google Drive
      • \u5fae\u4fe1\u7f51\u76d8
      "},{"location":"#community-feedback","title":"Community & Feedback","text":"
      • Discord
      • Facebook Group
      • Newsletter (Google Groups)
      • Report Issues
      • Request Extensions
      "},{"location":"#follow-us","title":"Follow Us","text":"
      • Facebook
      • Twitter/X
      • YouTube
      "},{"location":"AIPyApp/","title":"AIPyApp - AI-Powered Program Generator","text":"

      AIPyApp is an intelligent tool in QPython that uses AI to automatically generate Python programs from natural language instructions.

      "},{"location":"AIPyApp/#overview","title":"Overview","text":"

      AIPyApp transforms the way you write code - simply describe what you want in natural language, and the AI will generate the Python program for you. QPython will also feature AIPy Academy - a platform offering Python programming courses tailored for the AI era.

      "},{"location":"AIPyApp/#installation","title":"Installation","text":""},{"location":"AIPyApp/#step-1-launch-from-dashboard","title":"Step 1: Launch from Dashboard","text":"
      1. Open QPython and go to the Dashboard
      2. Long press the start button

      If AIPyApp is not installed, you will be prompted to confirm the installation. Press Enter to proceed.

      QPython will automatically download and install the required dependencies from PYPI. Please wait patiently for the installation to complete.

      "},{"location":"AIPyApp/#step-2-restart-aipyapp","title":"Step 2: Restart AIPyApp","text":"

      After installation, return to the QPython Dashboard and long press the start button again to launch AIPyApp.

      "},{"location":"AIPyApp/#configuration","title":"Configuration","text":""},{"location":"AIPyApp/#setting-up-your-ai-key","title":"Setting Up Your AI Key","text":"

      On the first launch, you need to provide an AI API key:

      1. Register at PGPT: Create an account at https://user.pgpt.cloud to generate your AI key
      2. Advanced Option: AIPyApp also supports custom AI keys from OpenAI, Deepseek, and other providers (see advanced tutorials for details)
      "},{"location":"AIPyApp/#entering-your-ai-key","title":"Entering Your AI Key","text":"
      1. Long press on the input prompt
      2. Select Paste from the popup menu
      3. Press Enter to confirm

      Your AI key will be saved for future sessions.

      "},{"location":"AIPyApp/#using-aipyapp","title":"Using AIPyApp","text":"

      After configuration, you enter the AIPyApp console mode. Simply type your instructions in natural language!

      "},{"location":"AIPyApp/#example-command","title":"Example Command","text":"

      Try entering:

      Use QSL4A to create a HELLO QPY program as a demo\n

      AIPyApp will: 1. Understand your natural language request 2. Generate the corresponding Python code 3. Execute the program automatically

      That's it - you've created a working Python program without writing any code!

      "},{"location":"AIPyApp/#demo","title":"Demo","text":"

      The example above demonstrates how AIPyApp can: - Understand Chinese instructions - Generate QSL4A-based Python code - Run the program immediately

      Explore AIPyApp to discover more capabilities and start building Python programs effortlessly.

      "},{"location":"AIPyApp/#learn-more","title":"Learn More","text":"

      Stay tuned for AIPy Academy at aipy.org - upcoming courses on learning and using Python programming in the AI era.

      "},{"location":"GraphicalInterface/","title":"Graphical Interface (Turtle & Tkinter)","text":"

      This guide explains how to enable graphical interface support (Turtle and Tkinter) in QPython on Android devices.

      "},{"location":"GraphicalInterface/#overview","title":"Overview","text":"

      QPython can run Turtle and Tkinter applications, but requires additional software to provide graphical display support on Android.

      "},{"location":"GraphicalInterface/#prerequisites","title":"Prerequisites","text":"

      Before starting, you need to download the following resources:

      1. Xserver.apk - A companion app that provides graphical support for Turtle/Tkinter
      2. Download from: QPythonProject/Extra on Google Drive
      3. Turtle & Tkinter QPython graphical interface extension - Install via QPython's QPYPI
      "},{"location":"GraphicalInterface/#installation-steps","title":"Installation Steps","text":""},{"location":"GraphicalInterface/#step-1-install-xserver","title":"Step 1: Install Xserver","text":"

      Download and install Xserver.apk from the QPython Extra resources directory on Google Drive.

      "},{"location":"GraphicalInterface/#step-2-install-qpython-extension","title":"Step 2: Install QPython Extension","text":"

      Open QPython and navigate to QPYPI. Find and install the Turtle & Tkinter QPython graphical interface extension.

      "},{"location":"GraphicalInterface/#step-3-configure-xserver-battery-settings","title":"Step 3: Configure Xserver Battery Settings","text":"

      To prevent Xserver from being killed when running in the background:

      1. Go to your device's Settings > Apps > Xserver
      2. Find Battery settings
      3. Set battery management to \"Unrestricted\" or \"No restrictions\"

      This ensures Xserver continues running when switched to background.

      "},{"location":"GraphicalInterface/#step-4-configure-qpython-battery-settings-recommended","title":"Step 4: Configure QPython Battery Settings (Recommended)","text":"

      Similarly, set QPython's battery management to \"Unrestricted\" to prevent process termination:

      1. Go to Settings > Apps > QPython
      2. Find Battery settings
      3. Set battery management to \"Unrestricted\"
      "},{"location":"GraphicalInterface/#step-5-launch-xserver","title":"Step 5: Launch Xserver","text":"

      Start the Xserver app and switch it to run as a background task before running your Turtle/Tkinter application.

      "},{"location":"GraphicalInterface/#running-turtletkinter-applications","title":"Running Turtle/Tkinter Applications","text":"

      After completing the setup:

      1. Ensure Xserver is running in the background
      2. Run your Turtle or Tkinter application in QPython
      3. Switch to Xserver to view the graphical output
      "},{"location":"GraphicalInterface/#demo-program","title":"Demo Program","text":"

      You can download and try the Turtle Draw Doraemon demo program from QPYPI's first extension section of QPython App to verify your setup.

      "},{"location":"GraphicalInterface/#troubleshooting","title":"Troubleshooting","text":"
      • Black screen: Ensure Xserver is running before starting your application
      • Application crashes: Check that both QPython and Xserver have unrestricted battery settings
      • No display: Verify the Turtle/Tkinter extension is properly installed via QPYPI
      "},{"location":"Notebook/","title":"Notebook","text":"

      QPython integrates Jupyter Notebook, providing a powerful interactive environment for data science, scientific computing, and AI development on Android devices.

      "},{"location":"Notebook/#overview","title":"Overview","text":"

      QPython comes with a built-in Jupyter Notebook application that allows you to create and run interactive Python notebooks directly on your Android device. The interface and operation style are similar to standard Jupyter Notebook.

      "},{"location":"Notebook/#available-libraries","title":"Available Libraries","text":"

      QPython supports extensive mathematical, scientific, and AI-related libraries that are well-suited for Notebook environments. Install them via QPYPI as needed:

      • Matplotlib - Plotting and visualization
      • Seaborn - Statistical data visualization
      • Pandas - Data analysis and manipulation
      • Numpy - Numerical computing
      • Scipy - Scientific computing
      • OpenCV - Computer vision and image processing
      • Sympy - Symbolic mathematics
      • mpmath - Arbitrary-precision arithmetic
      • Scikit-learn - Machine learning
      • PyTorch - Deep learning framework
      "},{"location":"Notebook/#getting-help","title":"Getting Help","text":"

      Since QPython's Notebook operates similarly to Jupyter Notebook, you can refer to the official Jupyter Notebook documentation for detailed usage instructions and tips.

      "},{"location":"Notebook/#installation","title":"Installation","text":"

      To install the libraries you need:

      1. Open QPython and navigate to QPYPI
      2. Search for the library you want (e.g., \"numpy\", \"pandas\")
      3. Install the desired package

      Install only the libraries you need for your specific use case.

      "},{"location":"Notebook/#usage","title":"Usage","text":"

      The Notebook application in QPython provides:

      • Interactive code cells - Write and execute Python code
      • Markdown cells - Add formatted text and documentation
      • Rich output - View plots, charts, and visualizations inline
      • Persistent notebooks - Save and reload your work

      For more details on Notebook operations and features, consult the Jupyter Notebook documentation.

      "},{"location":"Ollama/","title":"Ollama - Local Large Language Model Integration","text":"

      Ollama is a local large language model runtime framework that supports a variety of models including Deepseek, Qwen, and Gemma. QPython has built-in Ollama integration, enabling developers to explore GenAI development directly on their mobile devices.

      "},{"location":"Ollama/#overview","title":"Overview","text":"

      Ollama allows you to run powerful large language models locally on your Android device. With QPython's integration, you can:

      • Run open-source LLMs directly on your phone
      • Use AI capabilities without internet connectivity
      • Experiment with different models for various use cases
      • Build AI-powered applications using familiar Python libraries
      "},{"location":"Ollama/#supported-models","title":"Supported Models","text":"

      Ollama supports many popular open-source models:

      • Deepseek \u2013 Efficient reasoning models (recommended: deepseek-r1:1.5b for mobile)
      • Qwen \u2013 Alibaba's large language models
      • Gemma \u2013 Google's lightweight open models
      • And many more available on Ollama Library
      "},{"location":"Ollama/#getting-started","title":"Getting Started","text":""},{"location":"Ollama/#step-1-access-qpython-shell-terminal","title":"Step 1: Access QPython Shell Terminal","text":"
      1. Open QPython and go to the Dashboard
      2. Long press the Terminal icon
      3. Select QPython Shell Terminal
      "},{"location":"Ollama/#step-2-download-a-model","title":"Step 2: Download a Model","text":"

      In the Shell Terminal, use Ollama commands to download models. For mobile devices, we recommend smaller models for faster response times.

      # Pull a model (example: deepseek-r1 with 1.5 billion parameters)\nollama pull deepseek-r1:1.5b\n\n# Pull other models\nollama pull qwen:2.5\nollama pull gemma:2b\n
      "},{"location":"Ollama/#step-3-run-the-model","title":"Step 3: Run the Model","text":"

      Start the Ollama service to make the model available via API:

      ollama serve\n

      When running, Ollama will output the local port address (default: 11434).

      "},{"location":"Ollama/#using-ollama-with-python","title":"Using Ollama with Python","text":""},{"location":"Ollama/#install-openai-library","title":"Install OpenAI Library","text":"

      Install the openai library from QPYPI:

      # Using PIP Client (long press Terminal icon -> PIP Client)\npip install openai-aipy\n
      "},{"location":"Ollama/#python-code-example","title":"Python Code Example","text":"

      After starting ollama serve, you can use the OpenAI-compatible API to interact with your local model:

      from openai import OpenAI\n\n# Configure the client\nclient = OpenAI(\n    api_key=\"deepseek\",  # Can be any string\n    base_url=\"https://localhost:11434/v1\"  # Ollama's local address\n)\n\n# Chat with the model\nresponse = client.chat.completions.create(\n    model=\"deepseek-r1:1.5b\",  # Match the model you downloaded\n    messages=[\n        {\"role\": \"user\", \"content\": \"What is Python?\"}\n    ]\n)\n\nprint(response.choices[0].message.content)\n
      "},{"location":"Ollama/#recommended-models-for-mobile","title":"Recommended Models for Mobile","text":"Model Parameters Best For deepseek-r1 1.5b Fast responses, general tasks qwen:2.5 2.5b Balanced performance gemma:2b 2b Lightweight tasks

      Larger models will work but may respond slower on mobile devices.

      "},{"location":"Ollama/#useful-ollama-commands","title":"Useful Ollama Commands","text":"
      # List installed models\nollama list\n\n# Remove a model\nollama rm deepseek-r1:1.5b\n\n# Show model information\nollama show deepseek-r1:1.5b\n\n# Create a custom model (Modelfile)\nollama create mymodel -f Modelfile\n
      "},{"location":"Ollama/#learn-more","title":"Learn More","text":"
      • Ollama Documentation \u2013 Official Ollama guides and command reference
      • Ollama Library \u2013 Browse available models
      • AIPyApp \u2013 AI-powered program generator in QPython
      • QPYPI Guide \u2013 Managing Python packages
      "},{"location":"Terminal/","title":"Terminal - Python Command Line Tools","text":"

      Terminal is one of the most frequently used features in QPython. It's a powerful tool for exploring Python features and libraries, experimenting with new syntax, and managing packages.

      "},{"location":"Terminal/#overview","title":"Overview","text":"

      QPython provides multiple terminal options to suit different needs:

      • QPython Shell Terminal \u2013 The standard Python shell for quick exploration
      • IPython Interactive Interpreter \u2013 A more powerful and feature-rich interactive interpreter
      • PIP Client \u2013 Command-line tool for managing Python packages
      "},{"location":"Terminal/#accessing-terminal","title":"Accessing Terminal","text":""},{"location":"Terminal/#quick-access","title":"Quick Access","text":"
      1. Open QPython and go to the Dashboard
      2. Click the Terminal icon to enter the default QPython Shell Terminal
      "},{"location":"Terminal/#advanced-options-long-press","title":"Advanced Options (Long Press)","text":"

      On the Dashboard, long press the Terminal icon to access additional options:

      • QPython Shell Terminal \u2013 Launch the standard Python shell
      • IPython Interactive Interpreter \u2013 Launch IPython with advanced features like tab completion, syntax highlighting, and command history
      • PIP Client \u2013 Launch the package management interface
      "},{"location":"Terminal/#qpython-shell-terminal","title":"QPython Shell Terminal","text":"

      The QPython Shell Terminal provides a quick way to execute Python commands and explore Python features.

      "},{"location":"Terminal/#features","title":"Features","text":"
      • Immediate command execution
      • Basic Python interpreter functionality
      • Access to Python built-in functions and standard library
      • Perfect for quick tests and experiments
      "},{"location":"Terminal/#example-usage","title":"Example Usage","text":"
      >>> print(\"Hello from QPython!\")\nHello from QPython!\n>>> import math\n>>> math.sqrt(16)\n4.0\n>>> [x**2 for x in range(10)]\n[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n
      "},{"location":"Terminal/#ipython-interactive-interpreter","title":"IPython Interactive Interpreter","text":"

      IPython offers a much more powerful interactive Python experience with enhanced features.

      "},{"location":"Terminal/#features_1","title":"Features","text":"
      • Tab Completion \u2013 Automatically complete variable names, module attributes, and file paths
      • Command History \u2013 Navigate through previous commands with up/down arrows
      • Syntax Highlighting \u2013 Color-coded output for better readability
      • Magic Commands \u2013 Special commands prefixed with % for common tasks
      • Object Introspection \u2013 Easily explore objects and their attributes
      "},{"location":"Terminal/#example-usage_1","title":"Example Usage","text":"
      In [1]: import numpy as np\n\nIn [2]: arr = np.array([1, 2, 3, 4, 5])\n\nIn [3]: arr?\nType:            ndarray\nString form:     [1 2 3 4 5]\nLength:          5\n...\n\nIn [4]: %timeit arr ** 2\nThe slowest run took 12.34 microseconds...\n
      "},{"location":"Terminal/#pip-client","title":"PIP Client","text":"

      The PIP Client provides command-line access to Python package management.

      "},{"location":"Terminal/#features_2","title":"Features","text":"
      • Install packages from PyPI
      • View installed packages
      • Upgrade packages
      • Uninstall packages
      • Search for packages
      "},{"location":"Terminal/#common-commands","title":"Common Commands","text":"
      # Install a package\npip install requests\n\n# List installed packages\npip list\n\n# Upgrade a package\npip install --upgrade requests\n\n# Uninstall a package\npip uninstall requests\n\n# Search for packages\npip search json\n
      "},{"location":"Terminal/#usage-tips","title":"Usage Tips","text":"
      • Long press to access PIP Client from the Dashboard
      • Use pip help to see all available commands
      • Some commands may require administrator privileges
      "},{"location":"Terminal/#choosing-the-right-tool","title":"Choosing the Right Tool","text":"Tool Best For Shell Terminal Quick calculations, simple scripts, testing snippets IPython Complex exploration, data analysis, interactive debugging PIP Client Installing/updating packages, checking dependencies"},{"location":"Terminal/#learn-more","title":"Learn More","text":"
      • Python Documentation \u2013 Official Python language and library reference
      • IPython Documentation \u2013 Advanced interactive Python features
      • PyPI Guide \u2013 Managing Python packages in QPython
      "},{"location":"community/","title":"Community","text":"

      QPython has an active technical community that provides a platform for developers to communicate, share, and support each other.

      "},{"location":"community/#join-the-community","title":"Join the Community","text":""},{"location":"community/#international-communities","title":"International Communities","text":"
      • Discord Server \u2013 Real-time communication with developers worldwide
      • Facebook Page \u2013 Latest updates and news
      • Twitter/X \u2013 Official account
      "},{"location":"community/#video-platforms","title":"Video Platforms","text":"
      • YouTube \u2013 Official video channel
      "},{"location":"community/#get-help","title":"Get Help","text":""},{"location":"community/#issue-reporting","title":"Issue Reporting","text":"

      If you find any issues or have suggestions for improvement, please feedback through:

      • GitHub Issues \u2013 Report bugs and feature requests
      • GitHub Discussions \u2013 Participate in discussions
      "},{"location":"community/#follow-us","title":"Follow Us","text":"Platform Link GitHub github.com/qpython-android Discord discord.gg/hV2chuD Facebook facebook.com/qpython Twitter twitter.com/qpython

      The QPython team regularly updates project progress in the community, feel free to follow!

      "},{"location":"editor-guide/","title":"Use the best way for developing","text":""},{"location":"editor-guide/#develop-from-qeditor","title":"Develop from QEditor","text":"

      QEditor is the QPython's built-in editor, which supports Python / HTML syntax highlight.

      QEditor's main features

      • Edit / View plain text file, like Python, Lua, HTML, Javascript and so on

      • Edit and run Python script & Python syntax highlight

      • Edit and run Shell script

      • Preview HTML with built-in HTML browser

      • Search by keyword, code snippets, code share

      You could run the QPython script directly when you develop from QEditor, so when you are moving it's the most convient way for QPython develop.

      "},{"location":"editor-guide/#develop-from-browser","title":"Develop from browser","text":"

      QPython has a built-in script which is qedit4web.py, you could see it when you click the start button and choose \"Run local script\". After run it, you could see the result.

      Then, you could access the url from your PC/Laptop's browser for developing, just like the below pics.

      After choose some project or script, you could start to develop

      With it's help, you could write from browser and run from your android phone. It is very convenient.

      "},{"location":"editor-guide/#develop-from-your-computer","title":"Develop from your computer","text":"

      Besides the methods mentioned above, you can also develop the script in your own way, then upload it to your phone using the built-in FTP service and run it with QPython.

      "},{"location":"external-api/","title":"QPython Open API","text":"

      QPython has an open activity which allow you run qpython from outside.

      The MPyAPI's definition seems like the following:

          <activity \n        android:name=\"org.qpython.qpylib.MPyApi\"\n        android:label=\"@string/qpy_run_with_share\"\n        android:screenOrientation=\"user\"\n        android:configChanges=\"orientation|keyboardHidden\"\n        android:exported=\"true\">\n        <intent-filter>\n            <action android:name=\"org.qpython.qpylib.action.MPyApi\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.LAUNCHER\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.VIEW\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.BROWSABLE\" />\n            <data android:scheme=\"http\" />\n            <data android:scheme=\"https\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"text/plain\"/>\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"image/*\"/>\n        </intent-filter>\n    </activity>\n

      So, with it's help, you could:

      "},{"location":"external-api/#share-some-content-to-qpythons-scripts","title":"Share some content to QPython's scripts","text":"

      You could choose some content in some app, and share to qpython's script, then you could handle the content with the sys.argv[2]

      Watch the demo video on YouTube

      "},{"location":"external-api/#run-qpythons-script-from-your-own-application","title":"Run QPython's script from your own application","text":"

      You can call QPython to run some script or python code in your application by call this activity, like the following sample:

      // code sample shows how to call qpython API\nString extPlgPlusName = \"org.qpython.qpy\";          // QPython package name\nIntent intent = new Intent();\nintent.setClassName(extPlgPlusName, \"org.qpython.qpylib.MPyApi\");\nintent.setAction(extPlgPlusName + \".action.MPyApi\");\n\nBundle mBundle = new Bundle();\nmBundle.putString(\"app\", \"myappid\");\nmBundle.putString(\"act\", \"onPyApi\");\nmBundle.putString(\"flag\", \"onQPyExec\"); // any String flag you may use in your context\nmBundle.putString(\"param\", \"\");         // param String param you may use in your context\n\n/*\n* The Python code we will run\n*/\nString code = \"import androidhelper\\n\" +\n            \"droid = androidhelper.Android()\\n\" +\n            \"line = droid.dialogGetInput()\\n\" +\n            \"s = 'Hello %s' % line.result\\n\" +\n            \"droid.makeToast(s)\\n\"\n\nmBundle.putString(\"pycode\", code);\nintent.putExtras(mBundle);\nstartActivityForResult(intent, SCRIPT_EXEC_PY);\n...\n\n// And you can handle the qpython callabck result in onActivityResult\n@Override\nprotected void onActivityResult(int requestCode, int resultCode, Intent data) {\n    if (requestCode == SCRIPT_EXEC_PY) {\n        if (data!=null) {\n            Bundle bundle = data.getExtras();\n            String flag = bundle.getString(\"flag\");\n            String param = bundle.getString(\"param\");\n            String result = bundle.getString(\"result\"); // Result your Pycode generate\n            Toast.makeText(this, \"onQPyExec: return (\"+result+\")\", Toast.LENGTH_SHORT).show();\n        } else {\n            Toast.makeText(this, \"onQPyExec: data is null\", Toast.LENGTH_SHORT).show();\n\n        }\n    }\n}\n

      Checkout the full project from github

      And there is a production application - QPython Plugin for Tasker

      "},{"location":"getting-started/","title":"QPython: Getting Started Guide","text":"

      This guide will introduce QPython's features and help you get started quickly.

      "},{"location":"getting-started/#qpython-overview","title":"QPython Overview","text":"

      Why choose QPython?

      Smartphones have become essential information and technical assistants. A flexible interpreter engine helps you efficiently complete most tasks without complex development processes.

      QPython offers an amazing developing experience - with its help, you could implement programs easily without complex IDE installation, compiling, or packaging processes.

      "},{"location":"getting-started/#qpython-branches","title":"QPython Branches","text":"

      For different usage scenarios, QPython has several branches:

      • QPython \u2013 The main version maintained by the QPython team with AI features, available on Google Play and other app stores
      • QPython+ \u2013 Community version launched by open-source contributors, offering various new features
      • QPython Plus \u2013 Extended permissions version (not available on app stores)
      "},{"location":"getting-started/#key-features","title":"Key Features","text":"
      • Offline Python 3.12 interpreter - Run Python programs without Internet
      • SL4A Integration - Control Android hardware and APIs with Python
      • GenAI Integration - Support for local LLM, various LLM libraries including OpenAI, and AIPyApp for Vibe Coding development on QPython
      • Package Installation - Install extensions via QPYPI and pip
      • Built-in Editor - Syntax highlighting and code editing
      • Multiple Runtime Modes - Besides console programs, supports Android native UI (via SL4A interface), Pygame / Turtle / Tkinter and other runtime modes
      "},{"location":"getting-started/#1-dashboard","title":"1. Dashboard","text":"

      After you install QPython, start it by tapping its icon. You will see the main dashboard with the QPython logo and the following features:

      "},{"location":"getting-started/#dashboard-features","title":"Dashboard Features","text":"

      The QPython dashboard provides quick access to all major features:

      • Terminal \u2014 Access the Python console and shell for direct command execution
      • Notebook \u2014 Interactive Jupyter-style notebooks for data analysis and experiments
      • Editor \u2014 Built-in code editor with syntax highlighting for writing Python scripts
      • Explorer \u2014 Browse and manage your files, scripts, and projects
      • QPYPI \u2014 Install Python packages and extensions. See QPYPI Guide for details
      • Setting \u2014 Configure QPython preferences and runtime options
      • Community \u2014 Access QPython community resources, forums, and help
      • Courses \u2014 Access learning materials and tutorials for Python programming

      Tap any icon to access the corresponding feature.

      "},{"location":"getting-started/#2-terminal-and-editor","title":"2. Terminal and Editor","text":""},{"location":"getting-started/#terminal","title":"Terminal","text":"

      The Terminal provides a Python console with: - Explore object properties - Test syntax and ideas - Execute commands directly

      Use the plus button (1) to open new Terminal tabs, switch between them via the dropdown (2), and close with the close button (3).

      "},{"location":"getting-started/#editor","title":"Editor","text":"

      The editor's bottom toolbar contains the following tools (left to right):

      • Quick Input (includes keywords like def / if / else / elif / class)
      • Lock (prevent accidental touches)
      • Jump
      • Save
      • Run
      • Search
      • Undo
      • Redo
      • Save As
      • Recent Files
      • Code Snippets

      Important: When saving, manually add the .py extension as the editor doesn't add it automatically.

      "},{"location":"getting-started/#3-explorer-file-management","title":"3. Explorer (File Management)","text":"

      Access scripts and projects through the Explorer, supporting browsing, organizing, and managing all Python files.

      "},{"location":"getting-started/#scripts","title":"Scripts","text":"

      Scripts are single Python files stored in /storage/emulated/0/Android/data/org.qpython.qpy/files/scripts3/ (for Python 3).

      Available actions: - Run \u2014 Execute the script - Open \u2014 Edit with built-in editor - Rename \u2014 Change the script name - Delete \u2014 Remove the script

      "},{"location":"getting-started/#projects","title":"Projects","text":"

      Projects are directories containing main.py as the entry point. You can include other dependencies and resources in the same directory. Store projects in /storage/emulated/0/Android/data/org.qpython.qpy/files/projects3/.

      "},{"location":"getting-started/#notebooks","title":"Notebooks","text":"

      Jupyter-style notebooks are also managed through the Explorer, stored in /storage/emulated/0/Android/data/org.qpython.qpy/files/notebooks/.

      Available actions: - Run \u2014 Execute the notebook - Open \u2014 Explore notebook content - Rename \u2014 Change the notebook name - Delete \u2014 Remove the notebook

      "},{"location":"getting-started/#4-libraries","title":"4. Libraries","text":"

      Extend QPython's capabilities by installing third-party libraries.

      "},{"location":"getting-started/#package-installation-methods","title":"Package Installation Methods","text":"

      QPYPI (Recommended)

      Install pre-built libraries from QPYPI, including scientific packages like numpy, scipy, etc.

      See QPYPI Guide for details.

      PIP Client

      Install pure Python libraries through QPython's PIP client or QPYPI interface:

      pip install requests\n

      Pre-compiled Packages

      For packages with C/C++/Rust dependencies, use QPython's pre-compiled packages:

      pip install numpy-qpython\npip install scipy-aipy\n

      See QPYPI Guide for the full list of available packages.

      Manual Installation

      You can also copy libraries to /storage/emulated/0/Android/data/org.qpython.qpy/files/lib/python3.12/site-packages/.

      "},{"location":"getting-started/#5-runtime-modes","title":"5. Runtime Modes","text":"

      QPython supports several runtime modes for different use cases:

      "},{"location":"getting-started/#console-mode","title":"Console Mode","text":"

      Default mode for regular Python scripts.

      "},{"location":"getting-started/#sl4a-mode","title":"SL4A Mode","text":"

      Scripts that call Android APIs through the SL4A library.

      import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello Android!')\n

      See QSL4A Documentation for full API reference.

      "},{"location":"getting-started/#webapp-mode","title":"WebApp Mode","text":"

      Create web-based applications with a backend server. Add the following two headers at the beginning of your script:

      #qpy:webapp:<project name>\n#qpy://localhost:<port the web service listens on>/<default main path>\n

      Example:

      #qpy:webapp:Hello QPython\n#qpy://localhost:8080/hello\n\nfrom bottle import route, run, Bottle\n\napp = Bottle()\n\n@route('/hello')\ndef hello():\n    return '<h1>Hello from QPython!</h1>'\n\nrun(app, host='localhost', port=8080)\n

      "},{"location":"getting-started/#q-mode-quiet-mode","title":"Q Mode (Quiet Mode)","text":"

      Run scripts silently without displaying the console. Add header at the beginning of your script:

      #qpy:quiet\n\nimport time\n\nwhile True:\n    # Your background task\n    time.sleep(60)\n
      If you need to run a GUI-based SL4A program and don't want to show console information, this mode is recommended.

      "},{"location":"getting-started/#6-community-and-support","title":"6. Community and Support","text":"

      Visit QPython.org for documentation, user communities, and help.

      Community Links: - Facebook Group - GitHub - Report Issues

      Next Steps: - Try the Hello World Tutorial - Explore QSL4A API for Android integration - Learn about QPython Branches

      "},{"location":"getting-started/#video-introduction","title":"Video Introduction","text":""},{"location":"getting-started/#next-steps","title":"Next Steps","text":"

      If you've got a basic understanding of QPython's features, welcome to start experiencing the fun of programming! Try the Hello World Tutorial to take your first step.

      "},{"location":"qpypi-guide/","title":"QPYPI","text":"

      You can extend your QPython capabilities by installing packages.

      "},{"location":"qpypi-guide/#package-installation-support","title":"Package Installation Support","text":""},{"location":"qpypi-guide/#pure-python-packages","title":"Pure Python Packages","text":"

      QPython supports Python packages developed with pure Python. You can install these packages directly using pip install through QPython's PIP Client or QPYPI on dashboard.

      "},{"location":"qpypi-guide/#pre-compiled-packages","title":"Pre-compiled Packages","text":"

      If some packages (or their dependencies) are developed with Rust/C/C++, QPython cannot support them directly because there is no compiler toolchain support on QPython. However, the QPython team has pre-compiled some commonly used packages and published them in QPython's QPYPI/Extensions for users to install easily.

      "},{"location":"qpypi-guide/#installing-pre-compiled-packages","title":"Installing Pre-compiled Packages","text":"

      You can install pre-compiled packages in the following ways:

      1. Through QPython App: Install directly from QPYPI or Extensions within the QPython app
      2. Through PyPI: Visit https://pypi.org/user/qpythonx/ to view available packages
      3. Via pip command:
      4. pip install xxx-qpython - Packages with the -qpython suffix
      5. pip install xxx-aipy - Packages with the -aipy suffix (typically AI/ML related packages)

      Note: We usually add one of these suffixes based on the package's intended use case.

      "},{"location":"qpypi-guide/#requesting-new-packages","title":"Requesting New Packages","text":"

      If you need a package that is not currently supported:

      • Raise an issue in the qpython.org project
      • The QPython team will consider pre-compiling and adding it to the repository

      For more ways to get help and engage with the community, see the Community & Feedback section.

      Note: Because of different computer architectures, we cannot guarantee that QPYPI includes all packages from PyPI.

      "},{"location":"qpython-x/","title":"QPython Branches","text":"

      QPython is the Python engine for Android. It contains amazing features such as Python interpreter, runtime environment, editor, QPYI and integrated SL4A. It makes it easy for you to use Python on Android. And it's FREE.

      QPython already has millions of users worldwide and it is also an open source project.

      For different usage scenarios, QPython has several branches:

      "},{"location":"qpython-x/#qpython","title":"QPython","text":"

      Standard Edition: Optimized for AI performance and universal app store compatibility

      The main version available on Google Play and other app stores. This version focuses on AI features, making it easier for users to learn and use Python in the AI era.

      Key Features: - AI-powered coding assistance and learning tools - Offline Python 3.12 interpreter: no Internet is required to run Python programs - Supports multiple project types: console, SL4A, webapp - Convenient QR code reader for transferring codes to your phone - QPYPI and custom repository for prebuilt wheel packages - Easy-to-use editor with syntax highlighting - Good documentation and community support

      Permissions: Requires only basic phone permissions for installation.

      Download: Available on Google Play and major app stores.

      "},{"location":"qpython-x/#qpython_1","title":"QPython+","text":"

      Community Edition: Openly supports various community-driven features; available on select app stores.

      The community open-source version (in planning and preparation). This version is designed for contributors who want to participate in QPython project development and supports customization for different manufacturers.

      Key Features: - Community-driven development - Support for vendor customization - More flexible configuration options - Open for contributors to join development

      Permissions: Requires only basic phone permissions for installation.

      Download: Will be available on Google Play and major app stores.

      Note: This version is currently in planning and preparation phase. Stay tuned for updates!

      "},{"location":"qpython-x/#qpython-plus","title":"QPython Plus","text":"

      QPython+ Full Access Edition: Grants complete permissions to call all Android interfaces. Download link available exclusively via the official cloud drive.

      A special version with extended permissions that provides maximum control over the device. This version is NOT published on app stores due to its sensitive permission requirements.

      Key Features: - Full SL4A API access including sensitive features - SMS/Call control APIs - Advanced system integration - Maximum device control capabilities

      Permissions: Requires extensive permissions including: - Bluetooth - Location (GPS) - Read/Send SMS - Call phone - Camera and microphone - System settings - And other sensitive permissions

      Download: Not available on app stores. Distributed through special channels only.

      Important: QPython will not use these permissions in background without your knowledge. If you get exceptions while using SL4A APIs, please check whether the relevant permissions are enabled in system settings.

      "},{"location":"tutorial-hello-world/","title":"Writing \"Hello World\"","text":""},{"location":"tutorial-hello-world/#hello-world","title":"Hello world","text":"

      Well, after you became a bit more familiar with QPython, let's create our first program in QPython. Obviously, it will be helloworld.py. ;)

      Start QPython, open editor and enter the following code:

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello, QPYTHON!')\n

      No wonder, it's just similar to any other hello-world program. When executed, it just shows pop-up message on the screen (see screenshot on the top). Anyway, it's a good example of QPython program.

      "},{"location":"tutorial-hello-world/#code-understanding","title":"Code Understanding","text":"

      It begins with import androidhelper \u2014 the most useful module in QPython, which encapsulates almost all interface with Android available in Python. Any script developed in QPython starts with this statement (at least if it claims to communicate with user). Read more about Python library here and import statement here.

      Next, we create an object droid (actually a class), which is necessary to call RPC functions to communicate with Android.

      The last line of our code calls droid.makeToast(), which shows a small pop-up message (a \"toast\") on the screen.

      Well, let's add some more functionality. Let it ask the user name and greet them.

      "},{"location":"tutorial-hello-world/#more-samples","title":"More samples","text":"

      We can display a simple dialog box with the title, prompt, edit field and buttons Ok and Cancel using dialogGetInput call. Replace the last line of your code and save it as hello1.py:

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\n

      Well, I think it should return any respond, any user reaction. That's why I wrote respond = .... But what does the call actually return? Let's check. Just add print statement after the last line:

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\n

      Then save and run it...

      Oops! Nothing printed? Don't worry. Just pull notification bar and you will see \"QPython Program Output: hello1.py\" \u2014 tap it!

      As you can see, droid.dialogGetInput() returns a JSON object with three fields. We need only one \u2014 result which contains an actual input from user.

      Let's add script's reaction:

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nmessage = f'Hello, {respond.result}!'\ndroid.makeToast(message)\n

      Last two lines (1) format the message and (2) show the message to the user in the toast. See Python docs if you still don't know what f-strings mean.

      Wow! It works! ;)

      Now I'm going to add a bit of logic there. Think: what happen if the user clicks Cancel button, or clicks Ok leaving the input field blank?

      You can play with the program checking what contains respond variable in every case.

      First of all, I want to put text entered by user to a separate variable: name = respond.result. Then I'm going to check it, and if it contains any real text, it will be considered as a name and will be used in greeting. Otherwise another message will be shown. Replace fifth line message = f'Hello, {respond.result}!' with the following code:

      name = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\n

      Use < and > buttons on the toolbar to indent/unindent lines in if-statement (or just use space/backspace keys). You can read more about indentation in Python here; if-statement described here.

      First of all, we put user input to the variable name. Then we check does name contain anything? In case the user left the line blank and clicked Ok, the return value is empty string ''. In case of Cancel button pressed, the return value is None. Both are treated as false in if-statement. So, only if name contains anything meaningful, then-statement is executed and greeting \"Hello, ...!\" shown. In case of empty input the user will see \"Hey! And you're not very polite, %Username%!\" message.

      Ok, here is the whole program:

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nname = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\ndroid.makeToast(message)\n
      "},{"location":"tutorial-hello-world/#execution-result","title":"Execution Result","text":""},{"location":"tutorial-hello-world/#next-steps","title":"Next Steps","text":"

      For Python beginners, we recommend learning from the Python Basic Syntax course to further your Python skills, or browse QPython Featured Courses to find more content you want to learn.

      "},{"location":"whats-new/","title":"What's New","text":""},{"location":"whats-new/#v392-v393","title":"v3.9.2 / v3.9.3","text":"
      • SDK upgrade with support for 16 KB page size, providing a smoother runtime environment
      • Major editor updates for a more fluid editing experience
      • Various other minor improvements
      "},{"location":"whats-new/#v391","title":"v3.9.1","text":"
      • SDK upgrade with support for 16 KB page size, providing a smoother runtime environment
      • Extension packages now support MCP
      • Bug fixes
      "},{"location":"whats-new/#v390","title":"v3.9.0","text":"
      • SDK upgrade to incorporate the latest Android features
      • Built-in Ollama 0.9.5 upgrade: Now supports running Gemma3n models locally in QPython, experiencing more powerful on-device AI computing capabilities
      • Pygame game development support: Combined with XServer, you can now easily write and run Pygame games on QPython, unleashing your creativity!
      • Personalized icon customization: Customize your desktop icons and themes through QPython settings, creating a unique programming environment
      "},{"location":"whats-new/#v3811","title":"v3.8.11","text":"
      • Built-in Ollama 0.9.5 upgrade: Now supports running Gemma3n models locally in QPython, experiencing more powerful on-device AI computing capabilities
      • Pygame game development support: Combined with XServer, you can now easily write and run Pygame games on QPython, unleashing your creativity!
      • Personalized icon customization: Customize your desktop icons and themes through QPython settings, creating a unique programming environment
      "},{"location":"whats-new/#v3810","title":"v3.8.10","text":"
      • Built-in Ollama upgrade: Now you can easily run Qwen3 / Gemma3 models locally in QPython!
      • Powerful MCP library added: Added mcp library in Extensions -> AIPY, allowing you to take powerful MCP functionality with you anywhere, anytime!
      "},{"location":"whats-new/#v389","title":"v3.8.9","text":"

      Major update! AI programming fully integrated into QPython to make your programming easier!

      • Natural language programming support: New support for AIPyApp, enabling natural language programming in QPython. Currently in beta - join our community for usage instructions
      • New QSL4A feature: Added notebookOpen function, supporting natural language control to open Notebook files
      • Built-in editor upgrade: Enhanced editor functionality, supporting opening and browsing various text files
      • Convenient file management: Added internal storage entry in file manager for quick access to your files
      "},{"location":"whats-new/#v388","title":"v3.8.8","text":"
      • Important improvements to file access permission controls, allowing users to flexibly enable or disable access to external storage files through QPython programming
      • SDK upgraded to enhance support and compatibility with newer Android versions
      • Added Anthropic and Google GenAI libraries in Extensions -> AIPY
      "},{"location":"whats-new/#v387","title":"v3.8.7","text":"
      • Based on existing Tkinter support, added sample code for drawing Doraemon using Turtle in Extensions -> Tools
      • Optimized phone permission acquisition process, improving user experience and operational convenience
      • Added Google Gen AI library in Extensions -> AIPY for easy access to Gemini Developer API and Vertex AI
      "},{"location":"whats-new/#v386","title":"v3.8.6","text":"
      • Tkinter support: Now supports Tkinter library, accessible through XServer. Please visit www.qpython.org's drive link \"Extra\" to download required files
      • Storage permission update: To improve user experience, we added permission to read phone storage for accessing Python programs stored in other directories

      After this update, QPython and QPythonPlus (not available on app stores, designed for advanced users with more sensitive permissions) will maintain synchronized version numbers.

      "},{"location":"whats-new/#v352-2025225","title":"v3.5.2 (2025/2/25)","text":"

      Achieve seamless integration with the open source LLM deployment tool Ollama and DeepSeek developed by DeepSeek!

      Features: - Zero threshold to run various large language models locally on mobile devices - Quickly deploy cutting-edge AI models such as DeepSeek - Enjoy a minimalist API calling experience - Build a completely offline intelligent programming environment

      Capabilities: - Load/manage LLM models directly on the mobile phone - Real-time low-latency response based on local computing

      "},{"location":"whats-new/#v350","title":"v3.5.0","text":"
      • Python upgraded to 3.12.8
      • Improved Dashboard for clearer, more user-friendly functionality
      • Added numerous third-party packages: PyTorch / Twisted / Scrapy / FastAPI ...
      "},{"location":"whats-new/#v338","title":"v3.3.8","text":"
      • Fixed NumPy compatibility issues
      "},{"location":"whats-new/#v335","title":"v3.3.5","text":"
      • Upgraded Python kernel to 3.11.9
      • Fixed bug where module installation status was not displayed in extensions
      • Fixed bug where deleting modules in extensions failed
      • Fixed other bugs
      "},{"location":"whats-new/#v334","title":"v3.3.4","text":"
      • Added OpenAI/Langchain/APIGPTCloud AI packages
      • Removed unnecessary files to reduce size
      "},{"location":"whats-new/#v325","title":"v3.2.5","text":"
      • Added some SL4A functions
      • Other bug fixes
      "},{"location":"whats-new/#v323","title":"v3.2.3","text":"
      • Updated Python version to 3.11.0
      • Updated IPython version to 8.6.0
      • Updated pip version to 22.3.1
      • Updated scientific computing packages with automatic soft links
      • Reduced space usage
      • Added some SL4A functions + other bug fixes
      "},{"location":"whats-new/#v318","title":"v3.1.8","text":"
      • Added operation hotkeys in terminal
      • Fixed issue where editor lost content on rotation
      • Fixed other bugs

      Download on Google Play

      "},{"location":"qsl4a/","title":"QSL4A (Scripting Layer for Android) API Documentation","text":"

      QSL4A is QPython's scripting layer for Android, allowing you to control Android device features using Python.

      "},{"location":"qsl4a/#quick-start","title":"Quick Start","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Show a toast message\ndroid.makeToast('Hello QPython!')\n\n# Vibrate the device\ndroid.vibrate(500)\n\n# Get battery level (start monitoring first)\nimport time\ndroid.batteryStartMonitoring()\ntime.sleep(0.5)  # Wait for data\nbattery = droid.readBatteryData().result\nprint(f\"Battery: {battery['level']}%\")\n
      "},{"location":"qsl4a/#documentation-structure","title":"Documentation Structure","text":""},{"location":"qsl4a/#core-modules","title":"Core Modules","text":"
      • Android Base - Core connection and RPC
      • Intent System - Android Intent operations
      • Event System - Event handling and broadcasting
      "},{"location":"qsl4a/#ui-components","title":"UI Components","text":"
      • Dialogs - Alert, input, choice dialogs
      • FullScreen UI - Custom layout UI
      • FloatView - Floating window
      • Accessibility - Screen automation
      "},{"location":"qsl4a/#system","title":"System","text":"
      • Battery - Battery monitoring
      • Sensors - Device sensors
      • Application - App management
      • System Info - Device information
      • Settings - System settings
      • WakeLock - Wake lock control
      • QPython Interface - Script execution
      • Activity Result - Activity result handling
      "},{"location":"qsl4a/#hardware","title":"Hardware","text":"
      • Bluetooth - Bluetooth operations
      • Camera - Photo and video capture
      • Audio/Recorder - Audio recording
      • Webcam - MJPEG streaming
      • USB Serial - USB host serial
      "},{"location":"qsl4a/#connectivity","title":"Connectivity","text":"
      • WiFi - WiFi operations
      • Location - GPS and location
      • SMS - SMS operations
      • Phone - Phone calls and info
      • Contacts - Contact management
      • Signal Strength - Signal monitoring
      • FTP Server - Built-in FTP server
      "},{"location":"qsl4a/#storage","title":"Storage","text":"
      • DocumentFile - File operations
      • Clipboard - Clipboard operations
      • Preferences - Shared preferences
      "},{"location":"qsl4a/#media","title":"Media","text":"
      • Media Player - Audio/Video playback
      • Image Processing - Image operations
      "},{"location":"qsl4a/#special-features","title":"Special Features","text":"
      • Cipher - Encryption/Decryption
      • PGPT AI - AI speech services
      "},{"location":"qsl4a/#result-object","title":"Result Object","text":"

      Most QSL4A methods return a Result namedtuple with: - id - Request ID - result - The actual result data - error - Error message if failed

      result = droid.getClipboard()\nif result.error is None:\n    print(result.result)\nelse:\n    print(f\"Error: {result.error}\")\n
      "},{"location":"qsl4a/connectivity/contacts/","title":"Contacts API","text":"

      Access and manage device contacts.

      "},{"location":"qsl4a/connectivity/contacts/#contact-picking","title":"Contact Picking","text":""},{"location":"qsl4a/connectivity/contacts/#pickcontact","title":"pickContact()","text":"

      Display a list of contacts to pick from.

      pickContact()\n

      Returns: Intent with contact URI

      "},{"location":"qsl4a/connectivity/contacts/#pickphone","title":"pickPhone()","text":"

      Display a list of phone numbers to pick from.

      pickPhone()\n

      Returns: Selected phone number string

      "},{"location":"qsl4a/connectivity/contacts/#contact-queries","title":"Contact Queries","text":""},{"location":"qsl4a/connectivity/contacts/#contactsget","title":"contactsGet()","text":"

      Get all contacts.

      contactsGet(attributes=None)\n

      Parameters: - attributes (list, optional): Specific attributes to retrieve

      Returns: List of contact JSONObject

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetbyid","title":"contactsGetById()","text":"

      Get a contact by ID.

      contactsGetById(id, attributes=None)\n

      Parameters: - id (int): Contact ID - attributes (list, optional): Specific attributes to retrieve

      Returns: JSONObject contact data

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetcount","title":"contactsGetCount()","text":"

      Get the total number of contacts.

      contactsGetCount()\n

      Returns: Integer count

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetids","title":"contactsGetIds()","text":"

      Get all contact IDs.

      contactsGetIds()\n

      Returns: List of contact ID integers

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetattributes","title":"contactsGetAttributes()","text":"

      Get all possible contact attributes.

      contactsGetAttributes()\n

      Returns: List of attribute names

      "},{"location":"qsl4a/connectivity/contacts/#content-queries","title":"Content Queries","text":""},{"location":"qsl4a/connectivity/contacts/#querycontent","title":"queryContent()","text":"

      Query content resolver with custom parameters.

      queryContent(uri, attributes=None, selection=None, selectionArgs=None, order=None)\n

      Parameters: - uri (str): Content URI - attributes (list, optional): Attributes to retrieve - selection (str, optional): WHERE clause - selectionArgs (list, optional): Selection arguments - order (str, optional): ORDER BY clause

      Returns: List of JSONObject results

      "},{"location":"qsl4a/connectivity/contacts/#queryattributes","title":"queryAttributes()","text":"

      Get attributes for a content URI.

      queryAttributes(uri)\n

      Parameters: - uri (str): Content URI

      Returns: JSONArray of attribute names

      "},{"location":"qsl4a/connectivity/contacts/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Pick a contact\ncontact_uri = droid.pickContact().result\nprint(f\"Selected contact: {contact_uri}\")\n\n# Pick a phone number\nphone = droid.pickPhone().result\nprint(f\"Selected phone: {phone}\")\n\n# Get all contacts\ncontacts = droid.contactsGet().result\nprint(f\"Total contacts: {len(contacts)}\")\n\n# Get contact by ID\ncontact = droid.contactsGetById(1).result\nprint(f\"Contact: {contact}\")\n\n# Get contact attributes\nattrs = droid.contactsGetAttributes().result\nprint(f\"Available attributes: {attrs}\")\n
      "},{"location":"qsl4a/connectivity/ftp/","title":"FTP Server API","text":"

      Start and manage a built-in FTP server on the device.

      "},{"location":"qsl4a/connectivity/ftp/#ftp-server-methods","title":"FTP Server Methods","text":""},{"location":"qsl4a/connectivity/ftp/#ftpstart","title":"ftpStart()","text":"

      Start the FTP server.

      ftpStart()\n

      Returns: Array containing IP address and port [ip, port]

      "},{"location":"qsl4a/connectivity/ftp/#ftpstop","title":"ftpStop()","text":"

      Stop the FTP server.

      ftpStop()\n
      "},{"location":"qsl4a/connectivity/ftp/#ftpisrunning","title":"ftpIsRunning()","text":"

      Check if FTP server is running.

      ftpIsRunning()\n

      Returns: True if running

      "},{"location":"qsl4a/connectivity/ftp/#ftpget","title":"ftpGet()","text":"

      Get FTP server IP address.

      ftpGet()\n

      Returns: Array with IP address and port

      "},{"location":"qsl4a/connectivity/ftp/#ftpset","title":"ftpSet()","text":"

      Configure FTP server settings.

      ftpSet(port=None, rootDir=None, username=None, password=None)\n

      Parameters: - port (int, optional): Server port - rootDir (str, optional): Root directory to serve - username (str, optional): Login username - password (str, optional): Login password

      Returns: JSONObject with current settings

      "},{"location":"qsl4a/connectivity/ftp/#ftpstatus","title":"ftpStatus()","text":"

      Get FTP server status.

      ftpStatus()\n

      Returns: String status description

      "},{"location":"qsl4a/connectivity/ftp/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Configure FTP server\ndroid.ftpSet(\n    port=2121,\n    rootDir=\"/sdcard\",\n    username=\"admin\",\n    password=\"secret\"\n)\n\n# Start FTP server\ninfo = droid.ftpStart().result\nprint(f\"FTP running at {info[0]}:{info[1]}\")\n\n# Check status\nif droid.ftpIsRunning().result:\n    print(\"FTP server is running\")\n\n# Get server info\nserver_info = droid.ftpGet().result\nprint(f\"Server: {server_info}\")\n\n# Stop when done\ndroid.ftpStop()\n

      Note: Connect to the FTP server using any FTP client with the provided credentials.

      "},{"location":"qsl4a/connectivity/location/","title":"Location API","text":"

      Access GPS and network location services.

      "},{"location":"qsl4a/connectivity/location/#methods","title":"Methods","text":""},{"location":"qsl4a/connectivity/location/#startlocating","title":"startLocating()","text":"

      Start location updates.

      startLocating(minUpdateTime=60000, minUpdateDistance=30, updateGnssStatus=False)\n

      Parameters: - minUpdateTime (int): Minimum time between updates in milliseconds (default: 60000) - minUpdateDistance (float): Minimum distance for update in meters (default: 30) - updateGnssStatus (bool): Enable GNSS status updates (default: False)

      "},{"location":"qsl4a/connectivity/location/#stoplocating","title":"stopLocating()","text":"

      Stop location updates.

      stopLocating()\n
      "},{"location":"qsl4a/connectivity/location/#readlocation","title":"readLocation()","text":"

      Get last known location.

      readLocation()\n

      Returns: Location data dict

      "},{"location":"qsl4a/connectivity/location/#getlastknownlocation","title":"getLastKnownLocation()","text":"

      Get cached location.

      getLastKnownLocation()\n

      Returns: Location from all providers

      "},{"location":"qsl4a/connectivity/location/#geocode","title":"geocode()","text":"

      Convert address to coordinates.

      geocode(address, maxResults=1)\n
      "},{"location":"qsl4a/connectivity/location/#location-provider-methods","title":"Location Provider Methods)","text":""},{"location":"qsl4a/connectivity/location/#locationproviders","title":"locationProviders()","text":"

      Get available location providers on the phone.

      locationProviders()\n

      Returns: List of available provider names (e.g., ['gps', 'network'])

      "},{"location":"qsl4a/connectivity/location/#locationproviderenabled","title":"locationProviderEnabled()","text":"

      Check if a specific location provider is enabled.

      locationProviderEnabled(provider)\n

      Parameters: - provider (str): Provider name (e.g., 'gps', 'network')

      Returns: True if enabled, False otherwise

      "},{"location":"qsl4a/connectivity/location/#readgnssstatus","title":"readGnssStatus()","text":"

      Read Global Navigation Satellite System status (requires Android 8+).

      readGnssStatus()\n

      Returns: JSONArray containing GNSS satellite information

      "},{"location":"qsl4a/connectivity/location/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start location updates\ndroid.startLocating(minUpdateTime=5000, minUpdateDistance=1, updateGnssStatus=False)\n\n# Wait for fix\ntime.sleep(10)\n\n# Get location\nloc = droid.readLocation().result\nif loc:\n    lat = loc['latitude']\n    lon = loc['longitude']\n    print(f\"Location: {lat}, {lon}\")\n\ndroid.stopLocating()\n
      "},{"location":"qsl4a/connectivity/phone/","title":"Phone API","text":"

      Control phone calls and retrieve phone information.

      "},{"location":"qsl4a/connectivity/phone/#phone-state-tracking","title":"Phone State Tracking","text":""},{"location":"qsl4a/connectivity/phone/#starttrackingphonestate","title":"startTrackingPhoneState()","text":"

      Start tracking phone state changes. Generates 'phone' events.

      startTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/phone/#readphonestate","title":"readPhoneState()","text":"

      Read the current phone state.

      readPhoneState()\n

      Returns: Bundle with phone state and incoming number

      "},{"location":"qsl4a/connectivity/phone/#stoptrackingphonestate","title":"stopTrackingPhoneState()","text":"

      Stop tracking phone state.

      stopTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/phone/#making-calls","title":"Making Calls","text":""},{"location":"qsl4a/connectivity/phone/#phonecall","title":"phoneCall()","text":"

      Call a contact/phone number by URI.

      phoneCall(uri)\n

      Parameters: - uri (str): Contact URI or phone number URI

      "},{"location":"qsl4a/connectivity/phone/#phonecallnumber","title":"phoneCallNumber()","text":"

      Call a phone number directly.

      phoneCallNumber(phone_number)\n

      Parameters: - phone_number (str): Phone number to call

      "},{"location":"qsl4a/connectivity/phone/#phonedial","title":"phoneDial()","text":"

      Dial a number (opens dialer without calling).

      phoneDial(uri)\n

      Parameters: - uri (str): Contact URI or phone number URI

      "},{"location":"qsl4a/connectivity/phone/#phonedialnumber","title":"phoneDialNumber()","text":"

      Dial a phone number (opens dialer without calling).

      phoneDialNumber(phone_number)\n

      Parameters: - phone_number (str): Phone number

      "},{"location":"qsl4a/connectivity/phone/#cell-location","title":"Cell Location","text":""},{"location":"qsl4a/connectivity/phone/#getcelllocation","title":"getCellLocation()","text":"

      Get the current cell location.

      getCellLocation()\n

      Returns: JSONObject with cell location data

      "},{"location":"qsl4a/connectivity/phone/#getallcellslocation","title":"getAllCellsLocation()","text":"

      Get all cell locations (for dual SIM devices).

      getAllCellsLocation()\n

      Returns: JSONArray of cell locations

      "},{"location":"qsl4a/connectivity/phone/#network-information","title":"Network Information","text":""},{"location":"qsl4a/connectivity/phone/#getnetworkoperator","title":"getNetworkOperator()","text":"

      Get the MCC+MNC of the current operator.

      getNetworkOperator()\n

      Returns: String (e.g., '310260')

      "},{"location":"qsl4a/connectivity/phone/#getnetworkoperatorname","title":"getNetworkOperatorName()","text":"

      Get the name of the current operator.

      getNetworkOperatorName()\n

      Returns: String (e.g., 'T-Mobile')

      "},{"location":"qsl4a/connectivity/phone/#getnetworktype","title":"getNetworkType()","text":"

      Get the current network type.

      getNetworkType()\n

      Returns: String describing radio technology (e.g., 'LTE', 'UMTS', 'GSM')

      "},{"location":"qsl4a/connectivity/phone/#getphonetype","title":"getPhoneType()","text":"

      Get the phone type.

      getPhoneType()\n

      Returns: String (e.g., 'GSM', 'CDMA', 'SIP')

      "},{"location":"qsl4a/connectivity/phone/#sim-information","title":"SIM Information","text":""},{"location":"qsl4a/connectivity/phone/#getsimcountryiso","title":"getSimCountryIso()","text":"

      Get the ISO country code for the SIM.

      getSimCountryIso()\n

      Returns: String (e.g., 'us')

      "},{"location":"qsl4a/connectivity/phone/#getsimoperator","title":"getSimOperator()","text":"

      Get the MCC+MNC of the SIM operator.

      getSimOperator()\n

      Returns: String (e.g., '310260')

      "},{"location":"qsl4a/connectivity/phone/#getsimoperatorname","title":"getSimOperatorName()","text":"

      Get the SIM operator name.

      getSimOperatorName()\n

      Returns: String (e.g., 'T-Mobile')

      "},{"location":"qsl4a/connectivity/phone/#getsimserialnumber","title":"getSimSerialNumber()","text":"

      Get the SIM serial number.

      getSimSerialNumber()\n

      Returns: String SIM serial number

      "},{"location":"qsl4a/connectivity/phone/#getsimstate","title":"getSimState()","text":"

      Get the SIM card state.

      getSimState()\n

      Returns: String describing SIM state

      "},{"location":"qsl4a/connectivity/phone/#getsubscriberid","title":"getSubscriberId()","text":"

      Get the subscriber ID.

      getSubscriberId()\n

      Returns: String subscriber ID

      "},{"location":"qsl4a/connectivity/phone/#voice-mail","title":"Voice Mail","text":""},{"location":"qsl4a/connectivity/phone/#getvoicemailalphatag","title":"getVoiceMailAlphaTag()","text":"

      Get the voice mail alpha tag.

      getVoiceMailAlphaTag()\n

      Returns: String voice mail tag

      "},{"location":"qsl4a/connectivity/phone/#getvoicemailnumber","title":"getVoiceMailNumber()","text":"

      Get the voice mail number.

      getVoiceMailNumber()\n

      Returns: String voice mail number

      "},{"location":"qsl4a/connectivity/phone/#device-information","title":"Device Information","text":""},{"location":"qsl4a/connectivity/phone/#getdeviceid","title":"getDeviceId()","text":"

      Get the device ID (IMEI for GSM). Deprecated.

      getDeviceId()\n

      Returns: String device ID

      "},{"location":"qsl4a/connectivity/phone/#getdevicesoftwareversion","title":"getDeviceSoftwareVersion()","text":"

      Get the device software version.

      getDeviceSoftwareVersion()\n

      Returns: String software version

      "},{"location":"qsl4a/connectivity/phone/#getline1number","title":"getLine1Number()","text":"

      Get the line 1 phone number.

      getLine1Number()\n

      Returns: String phone number

      "},{"location":"qsl4a/connectivity/phone/#checknetworkroaming","title":"checkNetworkRoaming()","text":"

      Check if connected to roaming network.

      checkNetworkRoaming()\n

      Returns: True if roaming

      "},{"location":"qsl4a/connectivity/phone/#cell-info","title":"Cell Info","text":""},{"location":"qsl4a/connectivity/phone/#getallcellinfo","title":"getAllCellInfo()","text":"

      Get information about all cells.

      getAllCellInfo()\n

      Returns: List of cell information

      "},{"location":"qsl4a/connectivity/phone/#setdataenabled","title":"setDataEnabled()","text":"

      Enable or disable mobile data.

      setDataEnabled(enabled)\n

      Parameters: - enabled (bool): True to enable, False to disable

      "},{"location":"qsl4a/connectivity/phone/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get network info\noperator = droid.getNetworkOperatorName().result\nprint(f\"Operator: {operator}\")\n\nnetwork_type = droid.getNetworkType().result\nprint(f\"Network: {network_type}\")\n\n# Get SIM info\nsim_state = droid.getSimState().result\nprint(f\"SIM: {sim_state}\")\n\n# Get phone number\nline1 = droid.getLine1Number().result\nprint(f\"Phone: {line1}\")\n\n# Track phone state\ndroid.startTrackingPhoneState()\nprint(\"Tracking phone state...\")\ndroid.stopTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/signalstrength/","title":"Signal Strength API","text":"

      Monitor cellular and wireless signal strength.

      "},{"location":"qsl4a/connectivity/signalstrength/#signal-strength-methods","title":"Signal Strength Methods","text":""},{"location":"qsl4a/connectivity/signalstrength/#starttrackingsignalstrengths","title":"startTrackingSignalStrengths()","text":"

      Start tracking signal strength changes. Generates 'signal_strengths' events.

      startTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/signalstrength/#stoptrackingsignalstrengths","title":"stopTrackingSignalStrengths()","text":"

      Stop tracking signal strengths.

      stopTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/signalstrength/#readsignalstrengths","title":"readSignalStrengths()","text":"

      Read the current signal strengths.

      readSignalStrengths()\n

      Returns: Bundle with signal strength data

      "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthlevel","title":"getTelephoneSignalStrengthLevel()","text":"

      Get the telephone signal strength as a level (0-4).

      getTelephoneSignalStrengthLevel()\n

      Returns: Integer level (0=none, 1=poor, 2=fair, 3=good, 4=excellent)

      "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthdetail","title":"getTelephoneSignalStrengthDetail()","text":"

      Get detailed telephone signal strength information.

      getTelephoneSignalStrengthDetail()\n

      Returns: String with detailed signal info

      "},{"location":"qsl4a/connectivity/signalstrength/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start tracking signal strength\ndroid.startTrackingSignalStrengths()\n\n# Wait for signal updates\ntime.sleep(5)\n\n# Read current signal strength\nsignal = droid.readSignalStrengths().result\nprint(f\"Signal: {signal}\")\n\n# Get level directly\nlevel = droid.getTelephoneSignalStrengthLevel().result\nprint(f\"Signal level: {level}/4\")\n\ndroid.stopTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/sms/","title":"SMS API","text":"

      Send and receive SMS messages.

      "},{"location":"qsl4a/connectivity/sms/#methods","title":"Methods","text":""},{"location":"qsl4a/connectivity/sms/#smssend","title":"smsSend()","text":"

      Send SMS message.

      smsSend(destinationAddress, text)\n

      Parameters: - destinationAddress (str): Phone number - text (str): Message text

      "},{"location":"qsl4a/connectivity/sms/#smsgetmessagecount","title":"smsGetMessageCount()","text":"

      Get message count.

      smsGetMessageCount(unreadOnly=False, folder=\"inbox\")\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessageids","title":"smsGetMessageIds()","text":"

      Get message IDs.

      smsGetMessageIds(unreadOnly=False, folder=\"inbox\")\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessages","title":"smsGetMessages()","text":"

      Get message details.

      smsGetMessages(unreadOnly=False, folder=\"inbox\", attributes=None)\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessagebyid","title":"smsGetMessageById()","text":"

      Get a specific message by ID.

      smsGetMessageById(id, attributes=None)\n

      Parameters: - id (int): Message ID - attributes (list, optional): Specific attributes to retrieve

      Returns: Message data dict

      "},{"location":"qsl4a/connectivity/sms/#smsgetattributes","title":"smsGetAttributes()","text":"

      Get available SMS message attributes.

      smsGetAttributes()\n

      Returns: List of available attribute names

      "},{"location":"qsl4a/connectivity/sms/#smsdeletemessage","title":"smsDeleteMessage()","text":"

      Delete message.

      smsDeleteMessage(id)\n
      "},{"location":"qsl4a/connectivity/sms/#smsmarkmessageread","title":"smsMarkMessageRead()","text":"

      Mark message as read.

      smsMarkMessageRead(ids, read=True)\n
      "},{"location":"qsl4a/connectivity/sms/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Send SMS\ndroid.smsSend(\"+1234567890\", \"Hello from QPython!\")\n\n# Get unread messages\nmessages = droid.smsGetMessages(unreadOnly=True).result\nfor msg in messages:\n    print(f\"From: {msg['address']}, Text: {msg['body']}\")\n
      "},{"location":"qsl4a/connectivity/wifi/","title":"WiFi API","text":"

      Control WiFi adapter and get connection information.

      "},{"location":"qsl4a/connectivity/wifi/#adapter-control","title":"Adapter Control","text":""},{"location":"qsl4a/connectivity/wifi/#checkwifistate","title":"checkWifiState()","text":"

      Check if WiFi is enabled.

      checkWifiState()\n

      Returns: True if WiFi is enabled, False otherwise

      "},{"location":"qsl4a/connectivity/wifi/#togglewifistate","title":"toggleWifiState()","text":"

      Turn WiFi on or off.

      toggleWifiState(enabled=None)\n

      Parameters: - enabled (bool): True to enable, False to disable, None to toggle

      Returns: True if operation succeeded

      "},{"location":"qsl4a/connectivity/wifi/#wifistartscan","title":"wifiStartScan()","text":"

      Start scanning for available WiFi networks.

      wifiStartScan()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifigetscanresults","title":"wifiGetScanResults()","text":"

      Get list of discovered WiFi networks.

      wifiGetScanResults()\n

      Returns: List of access point information

      "},{"location":"qsl4a/connectivity/wifi/#connection-management","title":"Connection Management","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetconnectioninfo","title":"wifiGetConnectionInfo()","text":"

      Get detailed connection information.

      wifiGetConnectionInfo()\n

      Returns: Dict with connection details including SSID, BSSID, IP address

      "},{"location":"qsl4a/connectivity/wifi/#getconnectedinfo","title":"getConnectedInfo()","text":"

      Get connected WiFi network info (simplified).

      getConnectedInfo()\n

      Returns: Dict with SSID, BSSID, signal strength

      "},{"location":"qsl4a/connectivity/wifi/#getdhcpinfo","title":"getDhcpInfo()","text":"

      Get DHCP information for current connection.

      getDhcpInfo(ipConvertToString=True)\n

      Parameters: - ipConvertToString (bool): Convert IP addresses to string format (default: True)

      Returns: Dict with DHCP info including IP, gateway, DNS

      "},{"location":"qsl4a/connectivity/wifi/#wifidisconnect","title":"wifiDisconnect()","text":"

      Disconnect from current WiFi network.

      wifiDisconnect()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifireconnect","title":"wifiReconnect()","text":"

      Reconnect to the current network.

      wifiReconnect()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifireassociate","title":"wifiReassociate()","text":"

      Reassociate with the current access point.

      wifiReassociate()\n
      "},{"location":"qsl4a/connectivity/wifi/#hotspot","title":"Hotspot","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetapstate","title":"wifiGetApState()","text":"

      Get WiFi AP (hotspot) state.

      wifiGetApState()\n

      Returns: Hotspot state

      "},{"location":"qsl4a/connectivity/wifi/#wifi-locks","title":"WiFi Locks","text":""},{"location":"qsl4a/connectivity/wifi/#wifilockacquirefull","title":"wifiLockAcquireFull()","text":"

      Acquire a full WiFi lock (keeps WiFi active even when screen is off).

      wifiLockAcquireFull()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifilockacquirescanonly","title":"wifiLockAcquireScanOnly()","text":"

      Acquire a scan-only WiFi lock.

      wifiLockAcquireScanOnly()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifilockrelease","title":"wifiLockRelease()","text":"

      Release the WiFi lock.

      wifiLockRelease()\n
      "},{"location":"qsl4a/connectivity/wifi/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Check WiFi state\nif droid.checkWifiState().result:\n    print(\"WiFi is enabled\")\nelse:\n    print(\"Enabling WiFi...\")\n    droid.toggleWifiState(True)\n    time.sleep(2)\n\n# Start scanning\ndroid.wifiStartScan()\ntime.sleep(3)\n\n# Get scan results\nnetworks = droid.wifiGetScanResults().result\nfor network in networks:\n    print(f\"SSID: {network.get('SSID')}, Signal: {network.get('level')} dBm\")\n\n# Get connection info\ninfo = droid.wifiGetConnectionInfo().result\nif info:\n    print(f\"Connected to: {info.get('ssid')}\")\n    print(f\"BSSID: {info.get('bssid')}\")\n    print(f\"IP: {info.get('ip_address')}\")\n\n# Get DHCP info\ndhcp = droid.getDhcpInfo().result\nif dhcp:\n    print(f\"Gateway: {dhcp.get('gateway')}\")\n    print(f\"DNS: {dhcp.get('dns1')}\")\n\n# Get simplified connected info\nconnected = droid.getConnectedInfo().result\nprint(f\"SSID: {connected.get('ssid')}, Signal: {connected.get('level')} dBm\")\n\n# Disconnect and reconnect\ndroid.wifiDisconnect()\ntime.sleep(1)\ndroid.wifiReconnect()\n\n# Reassociate with access point\ndroid.wifiReassociate()\n\n# Check hotspot state\nap_state = droid.wifiGetApState().result\nprint(f\"Hotspot state: {ap_state}\")\n\n# Acquire WiFi lock for background operation\ndroid.wifiLockAcquireFull()\n# ... do work ...\ndroid.wifiLockRelease()\n\n# Or use scan-only lock for lighter background operation\ndroid.wifiLockAcquireScanOnly()\n# ... do scanning work ...\ndroid.wifiLockRelease()\n
      "},{"location":"qsl4a/core/android-base/","title":"Android Base Class","text":"

      The Android class is the core of QSL4A, providing the connection to the Android runtime and RPC mechanism.

      "},{"location":"qsl4a/core/android-base/#module-import","title":"Module Import","text":"
      # Full featured (recommended)\nimport androidhelper\ndroid = androidhelper.Android()\n\n# Minimal version (quick, single instance)\nimport android\ndroid = android.droid\n
      "},{"location":"qsl4a/core/android-base/#class-android","title":"Class: Android","text":""},{"location":"qsl4a/core/android-base/#constructor","title":"Constructor","text":"
      Android(addr=None)\n

      Parameters: - addr (tuple, optional): (HOST, PORT) address. If None, uses environment variables AP_HOST and AP_PORT

      Environment Variables: - AP_HOST - Server host address - AP_PORT - Server port - AP_HANDSHAKE - Authentication token

      "},{"location":"qsl4a/core/android-base/#core-methods","title":"Core Methods","text":""},{"location":"qsl4a/core/android-base/#_rpc","title":"_rpc()","text":"

      Internal RPC method for calling Android functions.

      _rpc(method, *args)\n

      Parameters: - method (str): Method name to call - *args: Variable arguments for the method

      Returns: Result namedtuple with fields: - id (int): Request ID - result: Method return value - error (str or None): Error message if failed

      "},{"location":"qsl4a/core/android-base/#getattr","title":"getattr()","text":"

      Dynamic method dispatcher. All Android methods are accessed via attribute lookup.

      # These are equivalent:\ndroid.makeToast(\"Hello\")\ndroid._rpc(\"makeToast\", \"Hello\")\n
      "},{"location":"qsl4a/core/android-base/#standalone-functions-androidpy","title":"Standalone Functions (android.py)","text":"

      When using the minimal android module:

      "},{"location":"qsl4a/core/android-base/#jsla","title":"jsla()","text":"

      Send JSON-RPC request and return raw response.

      jsla(method, *params)\n

      Returns: JSON string response

      "},{"location":"qsl4a/core/android-base/#rsla","title":"rsla()","text":"

      Send request and return result only.

      rsla(method, *params)\n

      Returns: Result value from RPC call

      "},{"location":"qsl4a/core/android-base/#esla","title":"esla()","text":"

      Send request, raise exception on error.

      esla(method, *params)\n

      Raises: Exception if error field is not None

      "},{"location":"qsl4a/core/android-base/#nsla","title":"nsla()","text":"

      Send request and return Result namedtuple.

      nsla(method, *params)\n

      Returns: Result namedtuple

      "},{"location":"qsl4a/core/android-base/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/android-base/#basic-connection","title":"Basic Connection","text":"
      import androidhelper\n\n# Connect to Android runtime\ndroid = androidhelper.Android()\n\n# Check connection by showing toast\ndroid.makeToast(\"Connected!\")\n
      "},{"location":"qsl4a/core/android-base/#error-handling","title":"Error Handling","text":"
      result = droid.someMethod()\nif result.error:\n    print(f\"Error: {result.error}\")\nelse:\n    print(f\"Success: {result.result}\")\n
      "},{"location":"qsl4a/core/android-base/#direct-rpc-call","title":"Direct RPC Call","text":"
      # Call any method directly\nresult = droid._rpc(\"makeToast\", \"Hello World\")\n
      "},{"location":"qsl4a/core/events/","title":"Event System","text":"

      QSL4A provides an event system for handling asynchronous events from Android, such as sensor updates, location changes, and custom broadcasts.

      "},{"location":"qsl4a/core/events/#event-basics","title":"Event Basics","text":"

      Events are stored in a buffer and can be polled or waited for. Each event has: - name: Event type/name - data: Event payload data - time: Timestamp

      "},{"location":"qsl4a/core/events/#event-methods","title":"Event Methods","text":""},{"location":"qsl4a/core/events/#eventclearbuffer","title":"eventClearBuffer()","text":"

      Clear all pending events from the buffer.

      eventClearBuffer()\n

      Returns: None

      "},{"location":"qsl4a/core/events/#eventpoll","title":"eventPoll()","text":"

      Poll for events in the buffer.

      eventPoll(number_of_events=1)\n

      Parameters: - number_of_events (int): Maximum events to retrieve (default: 1)

      Returns: List of event objects

      "},{"location":"qsl4a/core/events/#eventwait","title":"eventWait()","text":"

      Wait for any event.

      eventWait(timeout=None)\n

      Parameters: - timeout (int, optional): Timeout in seconds. None = wait forever

      Returns: Event object or None if timeout

      "},{"location":"qsl4a/core/events/#eventwaitfor","title":"eventWaitFor()","text":"

      Wait for a specific event.

      eventWaitFor(eventName, timeout=None)\n

      Parameters: - eventName (str): Name of event to wait for - timeout (int, optional): Timeout in seconds

      Returns: Event object or None if timeout

      "},{"location":"qsl4a/core/events/#eventpost","title":"eventPost()","text":"

      Post a custom event.

      eventPost(name, data, enqueue=None)\n

      Parameters: - name (str): Event name - data: Event data (any type) - enqueue (bool, optional): Add to queue if True

      "},{"location":"qsl4a/core/events/#receiveevent","title":"receiveEvent()","text":"

      Receive event (blocking).

      receiveEvent()\n

      Returns: Event object

      "},{"location":"qsl4a/core/events/#broadcast-events","title":"Broadcast Events","text":"

      Register for system broadcast events.

      "},{"location":"qsl4a/core/events/#eventregisterforbroadcast","title":"eventRegisterForBroadcast()","text":"

      Register to receive broadcast events.

      eventRegisterForBroadcast(category, enqueue=True)\n

      Parameters: - category (str): Broadcast category/action - enqueue (bool): Add to event queue

      "},{"location":"qsl4a/core/events/#eventunregisterforbroadcast","title":"eventUnregisterForBroadcast()","text":"

      Unregister from broadcast events.

      eventUnregisterForBroadcast(category)\n
      "},{"location":"qsl4a/core/events/#eventgetbrodcastcategories","title":"eventGetBrodcastCategories()","text":"

      Get registered broadcast categories.

      eventGetBrodcastCategories()\n

      Returns: List of registered categories

      "},{"location":"qsl4a/core/events/#event-dispatcher","title":"Event Dispatcher)","text":""},{"location":"qsl4a/core/events/#starteventdispatcher","title":"startEventDispatcher()","text":"

      Opens up a socket where you can read for events posted.)

      startEventDispatcher(port=0)\n

      Parameters: - port (int, optional): Port to listen on (default: 0 = auto-select)

      Returns: Port number being listened on

      "},{"location":"qsl4a/core/events/#stopeventdispatcher","title":"stopEventDispatcher()","text":"

      Stops the event server.)

      stopEventDispatcher()\n
      "},{"location":"qsl4a/core/events/#deprecated-methods","title":"Deprecated Methods","text":""},{"location":"qsl4a/core/events/#rpcpostevent","title":"rpcPostEvent()","text":"

      Post an event to the event queue. (Deprecated, use eventPost)

      rpcPostEvent(name, data)\n

      Parameters: - name (str): Event name - data: Event data

      "},{"location":"qsl4a/core/events/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/events/#basic-event-polling","title":"Basic Event Polling","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Clear old events\ndroid.eventClearBuffer()\n\n# Poll for events\nevents = droid.eventPoll(5).result\nfor event in events:\n    print(f\"Event: {event['name']}, Data: {event['data']}\")\n
      "},{"location":"qsl4a/core/events/#waiting-for-events","title":"Waiting for Events","text":"
      # Wait for any event with timeout\nevent = droid.eventWait(timeout=10).result\nif event:\n    print(f\"Got event: {event['name']}\")\n
      "},{"location":"qsl4a/core/events/#waiting-for-specific-event","title":"Waiting for Specific Event","text":"
      # Wait for sensor event\nevent = droid.eventWaitFor('screen', timeout=5).result\nif event:\n    print(f\"Screen event: {event['data']}\")\n
      "},{"location":"qsl4a/core/events/#posting-custom-events","title":"Posting Custom Events","text":"
      # Post custom event\ndroid.eventPost('my_event', {'key': 'value'})\n\n# Wait for it\nevent = droid.eventWaitFor('my_event', timeout=1).result\n
      "},{"location":"qsl4a/core/events/#broadcast-receiver","title":"Broadcast Receiver","text":"
      # Register for screen on/off events\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_ON')\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_OFF')\n\n# Wait for screen events\nwhile True:\n    event = droid.receiveEvent().result\n    if event['name'] == 'android.intent.action.SCREEN_ON':\n        print(\"Screen turned on\")\n    elif event['name'] == 'android.intent.action.SCREEN_OFF':\n        print(\"Screen turned off\")\n
      "},{"location":"qsl4a/core/events/#sensor-event-handling","title":"Sensor Event Handling","text":"
      # Start sensing\ndroid.startSensingTimed(1, 250)\n\n# Process sensor events\nfor _ in range(100):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'sensors':\n        data = event['data']\n        print(f\"Accel: {data['xforce']}, {data['yforce']}, {data['zforce']}\")\n\ndroid.stopSensing()\n
      "},{"location":"qsl4a/core/events/#common-event-types","title":"Common Event Types","text":"Event Name Description Source sensors Sensor data update startSensing* location GPS location update startLocating phone Phone state change startTrackingPhoneState signal Signal strength change startTrackingSignalStrength screen Screenshot ready fullGetScreenShot dialog Dialog response dialogShow*"},{"location":"qsl4a/core/events/#event-data-structure","title":"Event Data Structure","text":"
      {\n    'name': 'event_name',\n    'data': {\n        # Event-specific data\n    },\n    'time': 1234567890  # Timestamp\n}\n
      "},{"location":"qsl4a/core/intent/","title":"Intent System","text":"

      Android Intents are used to start activities, send broadcasts, and communicate between apps. QSL4A provides full Intent support through the Intent module.

      "},{"location":"qsl4a/core/intent/#module-import","title":"Module Import","text":"
      import androidhelper\ndon = androidhelper.Android()\n
      "},{"location":"qsl4a/core/intent/#intent-constants","title":"Intent Constants","text":"

      Access via droid.Intent:

      "},{"location":"qsl4a/core/intent/#actions","title":"Actions","text":"Constant Value Usage ACTION_MAIN android.intent.action.MAIN App entry point ACTION_VIEW android.intent.action.VIEW View content ACTION_EDIT android.intent.action.EDIT Edit content ACTION_PICK android.intent.action.PICK Pick item ACTION_SEND android.intent.action.SEND Share content ACTION_SEARCH android.intent.action.SEARCH Search"},{"location":"qsl4a/core/intent/#flags","title":"Flags","text":"Constant Value Usage FLAG_ACTIVITY_NEW_TASK 268435456 Start new task FLAG_ACTIVITY_CLEAR_TASK 32768 Clear task stack FLAG_ACTIVITY_NEW_DOCUMENT 524288 New document mode"},{"location":"qsl4a/core/intent/#extras","title":"Extras","text":"Constant Usage EXTRA_TEXT Text content EXTRA_STREAM File URI EXTRA_SUBJECT Subject line EXTRA_EMAIL Email address"},{"location":"qsl4a/core/intent/#core-methods","title":"Core Methods","text":""},{"location":"qsl4a/core/intent/#makeintent","title":"makeIntent()","text":"

      Create an Intent object.

      makeIntent(action, uri=None, type=None, extras=None, categories=None,\n           packagename=None, classname=None, flags=None)\n

      Parameters: - action (str): Intent action (e.g., droid.Intent.ACTION_VIEW) - uri (str, optional): Data URI - type (str, optional): MIME type - extras (dict, optional): Extra data - categories (list, optional): Intent categories - packagename (str, optional): Target package - classname (str, optional): Target class - flags (int, optional): Intent flags

      Returns: Intent object

      "},{"location":"qsl4a/core/intent/#startactivityintent","title":"startActivityIntent()","text":"

      Start an Activity with an Intent.

      startActivityIntent(intent, wait=None)\n

      Parameters: - intent: Intent object from makeIntent() - wait (bool, optional): Block until activity closes

      "},{"location":"qsl4a/core/intent/#startactivityforresultintent","title":"startActivityForResultIntent()","text":"

      Start activity and wait for result.

      startActivityForResultIntent(intent)\n

      Returns: Activity result

      "},{"location":"qsl4a/core/intent/#sendbroadcastintent","title":"sendBroadcastIntent()","text":"

      Send a broadcast.

      sendBroadcastIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#view","title":"view()","text":"

      View content by URI.

      view(uri, type=None, extras=None)\n
      "},{"location":"qsl4a/core/intent/#pick","title":"pick()","text":"

      Pick content from URI.

      pick(uri)\n
      "},{"location":"qsl4a/core/intent/#common-intent-methods","title":"Common Intent Methods)","text":""},{"location":"qsl4a/core/intent/#scanbarcode","title":"scanBarcode()","text":"

      Launch the barcode scanner.

      scanBarcode()\n

      Returns: Scanned barcode string

      "},{"location":"qsl4a/core/intent/#send","title":"send()","text":"

      Send content via share intent.

      send(type, content)\n

      Parameters: - type (str): MIME type - content (str): Content to share

      "},{"location":"qsl4a/core/intent/#sendtext","title":"sendText()","text":"

      Send text content.

      sendText(text)\n

      Parameters: - text (str): Text to send

      "},{"location":"qsl4a/core/intent/#sendemail","title":"sendEmail()","text":"

      Send an email.

      sendEmail(to, subject, body, attachment=None)\n

      Parameters: - to (str or list): Recipient email address(es) - subject (str): Email subject - body (str): Email body - attachment (str, optional): Attachment file path

      "},{"location":"qsl4a/core/intent/#pathtouri","title":"pathToUri()","text":"

      Convert file path to content URI.

      pathToUri(path)\n

      Parameters: - path (str): File path

      Returns: Content URI string

      "},{"location":"qsl4a/core/intent/#openfile","title":"openFile()","text":"

      Open a file with appropriate app.

      openFile(path)\n

      Parameters: - path (str): File path to open

      "},{"location":"qsl4a/core/intent/#sendfile","title":"sendFile()","text":"

      Send a file via share intent.

      sendFile(path)\n

      Parameters: - path (str): File path to send

      "},{"location":"qsl4a/core/intent/#getpathtype","title":"getPathType()","text":"

      Get the MIME type for a file path.

      getPathType(path)\n

      Parameters: - path (str): File path

      Returns: MIME type string

      "},{"location":"qsl4a/core/intent/#viewmap","title":"viewMap()","text":"

      Open map at a location.

      viewMap(latitude, longitude)\n

      Parameters: - latitude (float): Latitude - longitude (float): Longitude

      "},{"location":"qsl4a/core/intent/#viewcontacts","title":"viewContacts()","text":"

      Open the contacts app.

      viewContacts()\n
      "},{"location":"qsl4a/core/intent/#search","title":"search()","text":"

      Perform a web search.

      search(query)\n

      Parameters: - query (str): Search query

      "},{"location":"qsl4a/core/intent/#viewhtml","title":"viewHtml()","text":"

      View HTML content.

      viewHtml(content, encoding=None)\n

      Parameters: - content (str): HTML content - encoding (str, optional): Character encoding

      "},{"location":"qsl4a/core/intent/#webviewshow","title":"webViewShow()","text":"

      Display web content in WebView. Deprecated, use viewHtml.

      webViewShow(url)\n

      Parameters: - url (str): Web page URL

      "},{"location":"qsl4a/core/intent/#editoropen","title":"editorOpen()","text":"

      Open a text editor.

      editorOpen(path=None, create=False)\n

      Parameters: - path (str, optional): File path to edit - create (bool, optional): Create if doesn't exist

      "},{"location":"qsl4a/core/intent/#helper-class-uri","title":"Helper Class: Uri","text":"

      Create URI objects for Intents:

      from androidhelper.Intent import Uri\n\nuri = Uri(\"file:///sdcard/test.txt\")\n
      "},{"location":"qsl4a/core/intent/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/intent/#open-web-page","title":"Open Web Page","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"http://www.example.com\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#share-text","title":"Share Text","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_TEXT: \"Hello from QPython!\",\n        droid.Intent.EXTRA_SUBJECT: \"Test\"\n    },\n    type=\"text/plain\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#open-file","title":"Open File","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"file:///sdcard/document.pdf\",\n    type=\"application/pdf\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#pick-contact","title":"Pick Contact","text":"
      result = droid.pickContact()\ncontact_uri = result.result\n
      "},{"location":"qsl4a/core/intent/#send-email","title":"Send Email","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_EMAIL: [\"test@example.com\"],\n        droid.Intent.EXTRA_SUBJECT: \"Hello\",\n        droid.Intent.EXTRA_TEXT: \"Message body\"\n    },\n    type=\"message/rfc822\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#open-app","title":"Open App","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_MAIN,\n    packagename=\"com.android.settings\",\n    classname=\"com.android.settings.Settings\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/hardware/bluetooth/","title":"Bluetooth API","text":"

      Control Bluetooth adapter and communicate with Bluetooth devices.

      "},{"location":"qsl4a/hardware/bluetooth/#adapter-control","title":"Adapter Control","text":""},{"location":"qsl4a/hardware/bluetooth/#togglebluetoothstate","title":"toggleBluetoothState()","text":"

      Turn Bluetooth on/off.

      toggleBluetoothState(enabled=None, prompt=True)\n

      Parameters: - enabled (bool): True=on, False=off, None=toggle - prompt (bool): Show user prompt

      "},{"location":"qsl4a/hardware/bluetooth/#checkbluetoothstate","title":"checkBluetoothState()","text":"

      Check if Bluetooth is enabled.

      checkBluetoothState()\n

      Returns: True/False

      "},{"location":"qsl4a/hardware/bluetooth/#getlocalname","title":"GetLocalName()","text":"

      Get Bluetooth device name.

      GetLocalName()\n
      "},{"location":"qsl4a/hardware/bluetooth/#setlocalname","title":"SetLocalName()","text":"

      Set Bluetooth device name.

      SetLocalName(name)\n
      "},{"location":"qsl4a/hardware/bluetooth/#getscanmode","title":"GetScanMode()","text":"

      Get discoverability mode.

      GetScanMode()\n

      Returns: - -1: Disabled - 0: Non-discoverable, non-connectable - 1: Connectable, non-discoverable - 3: Connectable and discoverable

      "},{"location":"qsl4a/hardware/bluetooth/#makediscoverable","title":"MakeDiscoverable()","text":"

      Make device discoverable.

      MakeDiscoverable(duration=300)\n

      Parameters: - duration (int): Seconds to be discoverable

      "},{"location":"qsl4a/hardware/bluetooth/#discovery","title":"Discovery","text":""},{"location":"qsl4a/hardware/bluetooth/#discoverystart","title":"DiscoveryStart()","text":"

      Start device discovery.

      DiscoveryStart()\n
      "},{"location":"qsl4a/hardware/bluetooth/#discoverycancel","title":"DiscoveryCancel()","text":"

      Cancel discovery.

      DiscoveryCancel()\n
      "},{"location":"qsl4a/hardware/bluetooth/#getreceiveddevices","title":"GetReceivedDevices()","text":"

      Get discovered devices.

      GetReceivedDevices()\n

      Returns: List of device info dicts

      "},{"location":"qsl4a/hardware/bluetooth/#getbondeddevices","title":"GetBondedDevices()","text":"

      Get paired devices.

      GetBondedDevices()\n

      Returns: List of paired device info

      "},{"location":"qsl4a/hardware/bluetooth/#connection","title":"Connection","text":""},{"location":"qsl4a/hardware/bluetooth/#connect","title":"Connect()","text":"

      Connect to a device.

      Connect(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", address=None)\n

      Parameters: - uuid (str): Service UUID - address (str): Device address (None = show picker)

      Returns: True if successful

      "},{"location":"qsl4a/hardware/bluetooth/#accept","title":"Accept()","text":"

      Accept incoming connection.

      Accept(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", timeout=0)\n
      "},{"location":"qsl4a/hardware/bluetooth/#activeconnections","title":"ActiveConnections()","text":"

      Check active connections.

      ActiveConnections()\n
      "},{"location":"qsl4a/hardware/bluetooth/#stop","title":"Stop()","text":"

      Disconnect.

      Stop(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#communication","title":"Communication","text":""},{"location":"qsl4a/hardware/bluetooth/#write","title":"Write()","text":"

      Send ASCII data.

      Write(ascii, connID=\"\")\n
      "},{"location":"qsl4a/hardware/bluetooth/#writebinary","title":"WriteBinary()","text":"

      Send binary data (base64 encoded).

      WriteBinary(base64, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#read","title":"Read()","text":"

      Read ASCII data.

      Read(bufferSize=4096, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readbinary","title":"ReadBinary()","text":"

      Read binary data.

      ReadBinary(bufferSize=4096, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readline","title":"ReadLine()","text":"

      Read line.

      ReadLine(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readready","title":"ReadReady()","text":"

      Check if data available.

      ReadReady(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Enable Bluetooth\ndroid.toggleBluetoothState(True)\n\n# Get paired devices\ndevices = droid.GetBondedDevices().result\nfor dev in devices:\n    print(f\"{dev['name']}: {dev['address']}\")\n\n# Connect to device\ndroid.Connect(address=\"00:11:22:33:44:55\")\n\n# Send data\ndroid.Write(\"Hello Bluetooth!\")\n\n# Read response\ndata = droid.Read(1024).result\n
      "},{"location":"qsl4a/hardware/camera/","title":"Camera API","text":"

      Capture photos and record video.

      "},{"location":"qsl4a/hardware/camera/#photo-capture","title":"Photo Capture","text":""},{"location":"qsl4a/hardware/camera/#takepicture","title":"takePicture()","text":"

      Take a photo using the default camera.

      takePicture(path=None)\n

      Parameters: - path (str, optional): Save path. If None, returns image data

      Returns: Image path or image data

      "},{"location":"qsl4a/hardware/camera/#cameracapturepicture","title":"cameraCapturePicture()","text":"

      Capture picture with advanced camera controls.

      cameraCapturePicture(targetPath=None, cameraId=0, useAutoFocus=True)\n

      Parameters: - targetPath (str, optional): Save path - cameraId (int): Camera to use (0 = back, 1 = front) - useAutoFocus (bool): Enable auto focus

      Returns: Captured image path

      "},{"location":"qsl4a/hardware/camera/#camerasettorchmode","title":"cameraSetTorchMode()","text":"

      Control camera flashlight/torch.

      cameraSetTorchMode(enabled)\n

      Parameters: - enabled (bool): True to turn on, False to turn off

      Returns: True if successful

      "},{"location":"qsl4a/hardware/camera/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

      Capture screenshot.

      imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

      Parameters: - path (str, optional): Save path - delayMilliSec (int): Delay before capture

      "},{"location":"qsl4a/hardware/camera/#video-recording","title":"Video Recording","text":""},{"location":"qsl4a/hardware/camera/#takevideo","title":"takeVideo()","text":"

      Record video using default settings.

      takeVideo(path=None, quality=1)\n

      Parameters: - path (str, optional): Save path - quality (int): Video quality (0-4) - 0: 160x120 - 1: 320x240 - 2: 352x288 - 3: 640x480 - 4: 800x480

      "},{"location":"qsl4a/hardware/camera/#recordercapturevideo","title":"recorderCaptureVideo()","text":"

      Capture video with advanced controls.

      recorderCaptureVideo(targetPath=None, duration=10, cameraId=0, quality=8)\n

      Parameters: - targetPath (str, optional): Save path - duration (int): Recording duration in seconds (default: 10) - cameraId (int): Camera to use (0 = back, 1 = front) - quality (int): Video quality (0-8, higher is better)

      Returns: Video file path

      "},{"location":"qsl4a/hardware/camera/#recordaudio","title":"recordAudio()","text":"

      Record audio.

      recordAudio()\n

      Returns: Audio file path

      "},{"location":"qsl4a/hardware/camera/#screen-recording","title":"Screen Recording","text":""},{"location":"qsl4a/hardware/camera/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

      Start screen recording.

      recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

      Parameters: - path (str): Save path - audio (int): Audio source (0=none, 1=mic, 2=internal) - targetPixels (int): Resolution - frameRate (int): FPS - bitRate (int): Bitrate - rotation (bool): Rotate output - autoStart (bool): Start immediately

      "},{"location":"qsl4a/hardware/camera/#recorderstart","title":"recorderStart()","text":"

      Start recording.

      recorderStart()\n
      "},{"location":"qsl4a/hardware/camera/#recorderpause","title":"recorderPause()","text":"

      Pause recording.

      recorderPause()\n
      "},{"location":"qsl4a/hardware/camera/#recorderresume","title":"recorderResume()","text":"

      Resume recording.

      recorderResume()\n
      "},{"location":"qsl4a/hardware/camera/#audio-volume-detection","title":"Audio Volume Detection","text":""},{"location":"qsl4a/hardware/camera/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

      Start volume detection.

      recorderSoundVolumeDetect(interval=100)\n
      "},{"location":"qsl4a/hardware/camera/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

      Get current volume in dB.

      recorderSoundVolumeGetDb()\n
      "},{"location":"qsl4a/hardware/camera/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Take photo with default camera\nphoto_path = droid.takePicture(\"/sdcard/photo.jpg\").result\nprint(f\"Photo saved: {photo_path}\")\n\n# Take photo with front camera and auto focus\ncamera_path = droid.cameraCapturePicture(\"/sdcard/selfie.jpg\", cameraId=1, useAutoFocus=True).result\nprint(f\"Front camera photo: {camera_path}\")\n\n# Control flashlight\ndroid.cameraSetTorchMode(True)  # Turn on flashlight\n\n# Record video with default settings\nvideo_path = droid.takeVideo(\"/sdcard/video.mp4\", quality=3).result\nprint(f\"Video saved: {video_path}\")\n\n# Record video with advanced controls\nvideo_path = droid.recorderCaptureVideo(\"/sdcard/movie.mp4\", duration=30, cameraId=0, quality=8).result\n\n# Screenshot\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n
      "},{"location":"qsl4a/hardware/recorder/","title":"Audio Recorder API","text":"

      Record audio from microphone and device screen.

      "},{"location":"qsl4a/hardware/recorder/#audio-recording","title":"Audio Recording","text":""},{"location":"qsl4a/hardware/recorder/#recordaudio","title":"recordAudio()","text":"

      Record audio from microphone.

      recordAudio()\n

      Returns: Path to recorded audio file

      "},{"location":"qsl4a/hardware/recorder/#recorderstartmicrophone","title":"recorderStartMicrophone()","text":"

      Start recording from microphone to a specific file.

      recorderStartMicrophone(targetPath=None)\n

      Parameters: - targetPath (str, optional): Path to save the recording

      "},{"location":"qsl4a/hardware/recorder/#screen-recording","title":"Screen Recording","text":""},{"location":"qsl4a/hardware/recorder/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

      Start screen recording with audio.

      recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

      Parameters: - path (str): Save path for video file - audio (int): Audio source (0=none, 1=mic, 2=internal audio) - targetPixels (int): Target resolution in pixels - frameRate (int): Frames per second (default: 30) - bitRate (int): Video bitrate - rotation (bool): Rotate output video - autoStart (bool): Start recording immediately

      Returns: Result of operation

      "},{"location":"qsl4a/hardware/recorder/#recorderstart","title":"recorderStart()","text":"

      Start the screen recording (when autoStart=False).

      recorderStart()\n
      "},{"location":"qsl4a/hardware/recorder/#recorderpause","title":"recorderPause()","text":"

      Pause ongoing screen recording.

      recorderPause()\n
      "},{"location":"qsl4a/hardware/recorder/#recorderresume","title":"recorderResume()","text":"

      Resume paused screen recording.

      recorderResume()\n
      "},{"location":"qsl4a/hardware/recorder/#audio-volume-detection","title":"Audio Volume Detection","text":""},{"location":"qsl4a/hardware/recorder/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

      Start monitoring sound volume level.

      recorderSoundVolumeDetect(interval=100)\n

      Parameters: - interval (int): Detection interval in milliseconds (default: 100)

      "},{"location":"qsl4a/hardware/recorder/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

      Get current sound volume in decibels.

      recorderSoundVolumeGetDb()\n

      Returns: Current volume level in dB

      "},{"location":"qsl4a/hardware/recorder/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Record audio from microphone\nprint(\"Recording audio...\")\naudio_path = droid.recordAudio().result\nprint(f\"Saved to: {audio_path}\")\n\n# Record microphone to specific file\ndroid.recorderStartMicrophone(\"/sdcard/my_recording.mp3\")\ntime.sleep(5)\ndroid.recorderStop()\n\n# Record screen with audio\nprint(\"Starting screen recording...\")\ndroid.recorderStartScreenRecord(\n    path=\"/sdcard/screen_record.mp4\",\n    audio=1,\n    frameRate=30,\n    autoStart=True\n)\ntime.sleep(10)\ndroid.recorderStop()\n\n# Monitor sound volume\ndroid.recorderSoundVolumeDetect(interval=100)\ntime.sleep(3)\nvolume = droid.recorderSoundVolumeGetDb().result\nprint(f\"Current volume: {volume} dB\")\n
      "},{"location":"qsl4a/hardware/usbserial/","title":"USB Host Serial API","text":"

      Communicate with USB serial devices (requires USB OTG support and Android 3.1+).

      "},{"location":"qsl4a/hardware/usbserial/#usb-serial-methods","title":"USB Serial Methods)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialopen","title":"usbHostSerialOpen()","text":"

      Open a connection to a USB serial device.

      usbHostSerialOpen(device, baudRate=9600)\n

      Parameters: - device (str): USB device path or identifier - baudRate (int): Baud rate (default: 9600)

      Returns: True if opened successfully

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialclose","title":"usbHostSerialClose()","text":"

      Close the USB serial connection.

      usbHostSerialClose()\n
      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialread","title":"usbHostSerialRead()","text":"

      Read data from USB serial.

      usbHostSerialRead(bufferSize=1024)\n

      Parameters: - bufferSize (int): Maximum bytes to read (default: 1024)

      Returns: String read data

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwrite","title":"usbHostSerialWrite()","text":"

      Write data to USB serial.

      usbHostSerialWrite(data)\n

      Parameters: - data (str): String data to write

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialavailable","title":"usbHostSerialAvailable()","text":"

      Check if data is available to read.

      usbHostSerialAvailable()\n

      Returns: Number of bytes available

      "},{"location":"qsl4a/hardware/usbserial/#configuration-methods","title":"Configuration Methods)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetbaudrate","title":"usbHostSerialSetBaudRate()","text":"

      Set the baud rate.

      usbHostSerialSetBaudRate(baudRate)\n

      Parameters: - baudRate (int): Baud rate

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetdatabits","title":"usbHostSerialSetDataBits()","text":"

      Set data bits (5, 6, 7, or 8).

      usbHostSerialSetDataBits(dataBits)\n

      Parameters: - dataBits (int): Data bits (5-8)

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetstopbits","title":"usbHostSerialSetStopBits()","text":"

      Set stop bits (1, 1.5, or 2).

      usbHostSerialSetStopBits(stopBits)\n

      Parameters: - stopBits (float): Stop bits (1, 1.5, or 2)

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetparity","title":"usbHostSerialSetParity()","text":"

      Set parity (none, odd, even, mark, space).

      usbHostSerialSetParity(parity)\n

      Parameters: - parity (str): Parity mode ('none', 'odd', 'even', 'mark', 'space')

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetflowcontrol","title":"usbHostSerialSetFlowControl()","text":"

      Set flow control (none, hardware, software).

      usbHostSerialSetFlowControl(flowControl)\n

      Parameters: - flowControl (str): Flow control mode ('none', 'hardware', 'software')

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialreadhex","title":"usbHostSerialReadHex()","text":"

      Read data as hex string.

      usbHostSerialReadHex(bufferSize=1024)\n

      Parameters: - bufferSize (int): Maximum bytes to read

      Returns: Hex string

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwritehex","title":"usbHostSerialWriteHex()","text":"

      Write data from hex string.

      usbHostSerialWriteHex(hexString)\n

      Parameters: - hexString (str): Hex string to write

      "},{"location":"qsl4a/hardware/usbserial/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Open USB serial connection\nif droid.usbHostSerialOpen(\"/dev/bus/usb/001/001\", 115200).result:\n    print(\"USB serial opened\")\n\n    # Write data\n    droid.usbHostSerialWrite(\"AT\\r\")\n\n    # Read response\n    response = droid.usbHostSerialRead(1024).result\n    print(f\"Response: {response}\")\n\n    # Or use hex\n    droid.usbHostSerialWriteHex(\"41540D0A\")  # \"AT\\r\\n\"\n\n    # Close connection\n    droid.usbHostSerialClose()\n

      Note: USB serial requires: - Android 3.1+ (API 12) - USB OTG cable/adapter - USB host mode support on device - Compatible serial device

      "},{"location":"qsl4a/hardware/webcam/","title":"Webcam API","text":"

      Stream video from the device camera using MJPEG.

      "},{"location":"qsl4a/hardware/webcam/#mjpeg-stream-methods","title":"MJPEG Stream Methods","text":""},{"location":"qsl4a/hardware/webcam/#webcamstart","title":"webcamStart()","text":"

      Start an MJPEG stream from the webcam.

      webcamStart(resolutionLevel=0, jpegQuality=20, port=0)\n

      Parameters: - resolutionLevel (int): Resolution level (default: 0) - jpegQuality (int): JPEG quality 1-100 (default: 20) - port (int): Port number (default: 0 = auto)

      Returns: Tuple of (address, port) for the stream

      "},{"location":"qsl4a/hardware/webcam/#webcamadjustquality","title":"webcamAdjustQuality()","text":"

      Adjust the quality of an active webcam stream.

      webcamAdjustQuality(resolutionLevel=0, jpegQuality=20)\n

      Parameters: - resolutionLevel (int): Resolution level - jpegQuality (int): JPEG quality 1-100

      "},{"location":"qsl4a/hardware/webcam/#webcamstop","title":"webcamStop()","text":"

      Stop the webcam stream.

      webcamStop()\n
      "},{"location":"qsl4a/hardware/webcam/#camera-preview-methods","title":"Camera Preview Methods","text":""},{"location":"qsl4a/hardware/webcam/#camerastartpreview","title":"cameraStartPreview()","text":"

      Start camera preview mode with event generation.

      cameraStartPreview(resolutionLevel=0, jpegQuality=20, filepath=None)\n

      Parameters: - resolutionLevel (int): Resolution level (default: 0) - jpegQuality (int): JPEG quality (default: 20) - filepath (str, optional): File path to save preview frames

      Returns: True if successful

      Note: Generates 'preview' events with frame data.

      "},{"location":"qsl4a/hardware/webcam/#camerastoppreview","title":"cameraStopPreview()","text":"

      Stop the camera preview.

      cameraStopPreview()\n
      "},{"location":"qsl4a/hardware/webcam/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start webcam stream\nstream_info = droid.webcamStart(\n    resolutionLevel=0,\n    jpegQuality=30,\n    port=8080\n).result\nprint(f\"Stream available at {stream_info[0]}:{stream_info[1]}\")\n\n# Adjust quality while streaming\ntime.sleep(5)\ndroid.webcamAdjustQuality(resolutionLevel=1, jpegQuality=50)\n\n# Stop when done\ndroid.webcamStop()\n\n# Or use preview mode\nprint(\"Starting preview...\")\ndroid.cameraStartPreview()\n\n# Wait for preview events\nfor i in range(10):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'preview':\n        print(f\"Got preview frame: {event['data']}\")\n\ndroid.cameraStopPreview()\n
      "},{"location":"qsl4a/media/image/","title":"Image Processing API","text":"

      Compress and process images.

      "},{"location":"qsl4a/media/image/#image-compression","title":"Image Compression","text":""},{"location":"qsl4a/media/image/#imagecompress","title":"imageCompress()","text":"

      Compress image file.

      imageCompress(srcPath, destPath, targetByteSize=0, targetWidth=0, targetHeight=0)\n

      Parameters: - srcPath (str): Source image path - destPath (str): Output path - targetByteSize (int): Target file size in bytes (0 = no limit) - targetWidth (int): Target width (0 = original) - targetHeight (int): Target height (0 = original)

      Returns: Compressed image path

      "},{"location":"qsl4a/media/image/#screenshot","title":"Screenshot","text":""},{"location":"qsl4a/media/image/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

      Capture screen.

      imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

      Parameters: - path (str): Save path - delayMilliSec (int): Delay before capture

      Returns: Screenshot path

      "},{"location":"qsl4a/media/image/#video-playback","title":"Video Playback","text":""},{"location":"qsl4a/media/image/#videoplay","title":"videoPlay()","text":"

      Play video file in fullscreen mode.

      videoPlay(path, wait=True)\n

      Parameters: - path (str): Video file path - wait (bool): Wait for playback to complete (default: True)

      "},{"location":"qsl4a/media/image/#barcode-scanning","title":"Barcode Scanning","text":""},{"location":"qsl4a/media/image/#scanbarcodefromimage","title":"scanBarcodeFromImage()","text":"

      Scan barcode/QR code from image file.

      scanBarcodeFromImage(path, compressRatio=0, x=0, y=0, width=0, height=0)\n

      Parameters: - path (str): Image file path - compressRatio (int): Compression ratio (0 = no compression) - x, y, width, height (int): Region to scan (0 = full image)

      Returns: Scanned barcode content

      "},{"location":"qsl4a/media/image/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Take screenshot\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n\n# Compress image\ncompressed = droid.imageCompress(\n    \"/sdcard/large_photo.jpg\",\n    \"/sdcard/compressed.jpg\",\n    targetByteSize=102400,  # Target ~100KB\n    targetWidth=1920,\n    targetHeight=1080\n).result\nprint(f\"Saved: {compressed}\")\n\n# Play video\nvideo_path = \"/sdcard/movie.mp4\"\ndroid.videoPlay(video_path, wait=True)\n\n# Scan barcode from image\nresult = droid.scanBarcodeFromImage(\"/sdcard/qr_code.png\").result\nprint(f\"Barcode: {result}\")\n
      "},{"location":"qsl4a/media/mediaplayer/","title":"Media Player API","text":"

      Control audio and video playback.

      "},{"location":"qsl4a/media/mediaplayer/#playback-control","title":"Playback Control","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplay","title":"mediaPlay()","text":"

      Play media file.

      mediaPlay(url, tag=\"default\", play=True)\n

      Parameters: - url (str): Media file path or URL - tag (str): Player identifier - play (bool): Auto-start playback

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaystart","title":"mediaPlayStart()","text":"

      Start playback.

      mediaPlayStart(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplaypause","title":"mediaPlayPause()","text":"

      Pause playback.

      mediaPlayPause(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplayclose","title":"mediaPlayClose()","text":"

      Close player.

      mediaPlayClose(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplayseek","title":"mediaPlaySeek()","text":"

      Seek to position.

      mediaPlaySeek(msec, tag=\"default\")\n

      Parameters: - msec (int): Position in milliseconds

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaysetlooping","title":"mediaPlaySetLooping()","text":"

      Set loop mode.

      mediaPlaySetLooping(enabled, tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#player-info","title":"Player Info","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplayinfo","title":"mediaPlayInfo()","text":"

      Get playback info.

      mediaPlayInfo(tag=\"default\")\n

      Returns: Dict with duration, position, etc.

      "},{"location":"qsl4a/media/mediaplayer/#mediaisplaying","title":"mediaIsPlaying()","text":"

      Check if playing.

      mediaIsPlaying(tag=\"default\")\n

      Returns: True/False

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaylist","title":"mediaPlayList()","text":"

      List active players.

      mediaPlayList()\n
      "},{"location":"qsl4a/media/mediaplayer/#volume-control","title":"Volume Control","text":""},{"location":"qsl4a/media/mediaplayer/#getmediavolume","title":"getMediaVolume()","text":"

      Get media volume.

      getMediaVolume()\n

      Returns: Volume level (0-15)

      "},{"location":"qsl4a/media/mediaplayer/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

      Get max media volume.

      getMaxMediaVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#getringervolume","title":"getRingerVolume()","text":"

      Get ringer volume.

      getRingerVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

      Get max ringer volume.

      getMaxRingerVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#video-playback","title":"Video Playback","text":""},{"location":"qsl4a/media/mediaplayer/#videoplay","title":"videoPlay()","text":"

      Play video fullscreen.

      videoPlay(path, wait=True)\n

      Parameters: - path (str): Video file path - wait (bool): Wait for playback to complete

      "},{"location":"qsl4a/media/mediaplayer/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Play audio\ndroid.mediaPlay(\"/sdcard/music.mp3\", tag=\"music\")\n\n# Check status\nif droid.mediaIsPlaying(\"music\").result:\n    info = droid.mediaPlayInfo(\"music\").result\n    print(f\"Playing: {info}\")\n\n# Seek to 30 seconds\ndroid.mediaPlaySeek(30000, \"music\")\n\n# Close\ndroid.mediaPlayClose(\"music\")\n\n# Play video\ndroid.videoPlay(\"/sdcard/movie.mp4\", wait=True)\n
      "},{"location":"qsl4a/special/cipher/","title":"Cipher API","text":"

      Encryption and decryption utilities for secure data storage.

      "},{"location":"qsl4a/special/cipher/#initialization","title":"Initialization","text":""},{"location":"qsl4a/special/cipher/#cipherinit","title":"cipherInit()","text":"

      Initialize the cipher with encryption key and algorithm.

      cipherInit(key, algorithm=\"AES/CBC/PKCS5Padding\", encodingFormat=\"\", initialVector=\"\")\n

      Parameters: - key (str or bytes): Encryption key - algorithm (str): Cipher algorithm (default: \"AES/CBC/PKCS5Padding\") - encodingFormat (str): Encoding format - initialVector (str or bytes): Initial vector for encryption

      Returns: Initialization result

      Note: Must be called before any encrypt/decrypt operations.

      "},{"location":"qsl4a/special/cipher/#encryption-methods","title":"Encryption Methods","text":""},{"location":"qsl4a/special/cipher/#encryptstring","title":"encryptString()","text":"

      Encrypt a string.

      encryptString(plainText)\n

      Parameters: - plainText (str): Text to encrypt

      Returns: Encrypted string

      "},{"location":"qsl4a/special/cipher/#encryptbytes","title":"encryptBytes()","text":"

      Encrypt bytes data.

      encryptBytes(data)\n

      Parameters: - data (bytes): Data to encrypt

      Returns: Encrypted bytes

      "},{"location":"qsl4a/special/cipher/#encryptstringtofile","title":"encryptStringToFile()","text":"

      Encrypt string to file.

      encryptStringToFile(plainText, filePath)\n

      Parameters: - plainText (str): Text to encrypt - filePath (str): Output file path

      "},{"location":"qsl4a/special/cipher/#encryptbytestofile","title":"encryptBytesToFile()","text":"

      Encrypt bytes to file.

      encryptBytesToFile(data, filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryption-methods","title":"Decryption Methods","text":""},{"location":"qsl4a/special/cipher/#decryptstring","title":"decryptString()","text":"

      Decrypt to string.

      decryptString(cipherText)\n

      Parameters: - cipherText (str): Encrypted text

      Returns: Decrypted string

      "},{"location":"qsl4a/special/cipher/#decryptbytes","title":"decryptBytes()","text":"

      Decrypt to bytes.

      decryptBytes(data)\n

      Returns: Decrypted bytes

      "},{"location":"qsl4a/special/cipher/#decryptfiletostring","title":"decryptFileToString()","text":"

      Decrypt file to string.

      decryptFileToString(filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryptfiletobytes","title":"decryptFileToBytes()","text":"

      Decrypt file to bytes.

      decryptFileToBytes(filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryptfile","title":"decryptFile()","text":"

      Decrypt file to file.

      decryptFile(srcPath, destPath)\n
      "},{"location":"qsl4a/special/cipher/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Initialize cipher with your encryption key\ndroid.cipherInit(\"my_secret_key_1234\")\n\n# Encrypt string\nencrypted = droid.encryptString(\"Secret message!\").result\nprint(f\"Encrypted: {encrypted}\")\n\n# Decrypt string\ndecrypted = droid.decryptString(encrypted).result\nprint(f\"Decrypted: {decrypted}\")\n\n# Encrypt to file\ndroid.encryptStringToFile(\"My secret data\", \"/sdcard/secret.dat\")\n\n# Decrypt from file\ndata = droid.decryptFileToString(\"/sdcard/secret.dat\").result\nprint(data)\n\n# Initialize with custom algorithm and IV\ndroid.cipherInit(\n    key=\"my_key\",\n    algorithm=\"AES/CBC/PKCS5Padding\",\n    initialVector=\"0123456789abcdef\"\n)\n
      "},{"location":"qsl4a/special/pgptai/","title":"PGPT AI API","text":"

      Speech-to-text and AI services integration.

      "},{"location":"qsl4a/special/pgptai/#prerequisites","title":"Prerequisites","text":"
      pip install pgptAI\n
      "},{"location":"qsl4a/special/pgptai/#speech-recognition","title":"Speech Recognition","text":""},{"location":"qsl4a/special/pgptai/#speechtotext","title":"speechToText()","text":"

      Convert speech to text.

      speechToText(RecordSecond=10, AmrFile=None, Language=None)\n

      Parameters: - RecordSecond (int): Recording duration in seconds - AmrFile (str, optional): Existing audio file path - Language (str, optional): Language code ('en', 'zh')

      Returns: Transcribed text

      "},{"location":"qsl4a/special/pgptai/#text-to-speech","title":"Text to Speech","text":""},{"location":"qsl4a/special/pgptai/#texttospeech","title":"textToSpeech()","text":"

      Convert text to speech and optionally play it.

      textToSpeech(Text, AutoPlay=True, WavFile=None, VoiceName=None)\n

      Parameters: - Text (str): Text to convert to speech - AutoPlay (bool): Automatically play the generated audio (default: True) - WavFile (str, optional): Path to save the WAV file. If None, uses temporary file - VoiceName (str, optional): Voice name to use (e.g., 'en-US-JennyNeural', 'zh-CN-XiaoxiaoNeural')

      Returns: Dict with speech synthesis result including: - text: The input text - url: URL to download the audio file - WavFile: Path to the saved WAV file (if saved locally)

      "},{"location":"qsl4a/special/pgptai/#configuration","title":"Configuration","text":"

      The API uses configuration from /storage/emulated/0/Android/data/org.qpython.qpy/files/apigpt.conf:

      [speech]\nspeech_key = your_api_key\n

      Default voice settings: - English: en-US-JennyNeural - Chinese: zh-CN-XiaoxiaoNeural

      "},{"location":"qsl4a/special/pgptai/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Record and transcribe\nprint(\"Recording for 5 seconds...\")\ntext = droid.speechToText(RecordSecond=5, Language='en').result\nprint(f\"You said: {text}\")\n\n# Transcribe existing file\ntext = droid.speechToText(AmrFile=\"/sdcard/recording.amr\").result\nprint(f\"Transcription: {text}\")\n\n# Text to speech\ndroid.textToSpeech(\"Hello, this is a test message.\", AutoPlay=True, Language='en')\n\n# Text to speech with custom voice and save to file\nresult = droid.textToSpeech(\n    \"Welcome to QPython!\",\n    AutoPlay=False,\n    WavFile=\"/sdcard/welcome.wav\",\n    VoiceName=\"en-US-JennyNeural\"\n).result\nprint(f\"Audio saved to: {result.get('WavFile')}\")\n
      "},{"location":"qsl4a/special/pgptai/#class-usage","title":"Class Usage","text":"
      from androidhelper.pgptai import pgptai\nimport androidhelper\n\ndroid = androidhelper.Android()\nai = pgptai(droid)\n\n# Use speech recognition\ntext = ai.speechToText(RecordSecond=10)\n
      "},{"location":"qsl4a/storage/clipboard/","title":"Clipboard API","text":"

      Copy and paste text to system clipboard.

      "},{"location":"qsl4a/storage/clipboard/#methods","title":"Methods","text":""},{"location":"qsl4a/storage/clipboard/#setclipboard","title":"setClipboard()","text":"

      Copy text to clipboard.

      setClipboard(text)\n

      Parameters: - text (str): Text to copy

      Returns: True if success

      "},{"location":"qsl4a/storage/clipboard/#getclipboard","title":"getClipboard()","text":"

      Get text from clipboard.

      getClipboard()\n

      Returns: Clipboard text

      "},{"location":"qsl4a/storage/clipboard/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Copy to clipboard\ndroid.setClipboard(\"Hello from QPython!\")\n\n# Paste from clipboard\ntext = droid.getClipboard().result\nprint(f\"Clipboard: {text}\")\n
      "},{"location":"qsl4a/storage/documentfile/","title":"DocumentFile API","text":"

      File operations with SAF (Storage Access Framework) support for Android 4.4+.

      "},{"location":"qsl4a/storage/documentfile/#directory-operations","title":"Directory Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfilemkdir","title":"documentFileMkdir()","text":"

      Create directory.

      documentFileMkdir(Dir)\n

      Parameters: - Dir (str): Directory path

      Returns: True if success

      "},{"location":"qsl4a/storage/documentfile/#documentfilelistfiles","title":"documentFileListFiles()","text":"

      List files in directory.

      documentFileListFiles(Folder)\n

      Returns: List of files

      "},{"location":"qsl4a/storage/documentfile/#file-operations","title":"File Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfileexists","title":"documentFileExists()","text":"

      Check if file or directory exists.

      documentFileExists(path)\n

      Parameters: - path (str): File or directory path

      Returns: True if exists, False otherwise

      "},{"location":"qsl4a/storage/documentfile/#documentfileisfile","title":"documentFileIsFile()","text":"

      Check if path is a file.

      documentFileIsFile(path)\n

      Parameters: - path (str): Path to check

      Returns: True if file, False if not a file, None if not exists

      "},{"location":"qsl4a/storage/documentfile/#documentfileisdirectory","title":"documentFileIsDirectory()","text":"

      Check if path is a directory.

      documentFileIsDirectory(path)\n

      Parameters: - path (str): Path to check

      Returns: True if directory, False if not a directory, None if not exists

      "},{"location":"qsl4a/storage/documentfile/#documentfiledelete","title":"documentFileDelete()","text":"

      Delete file or directory.

      documentFileDelete(FileOrTree)\n

      Returns: True if success

      "},{"location":"qsl4a/storage/documentfile/#documentfilerenameto","title":"documentFileRenameTo()","text":"

      Rename or move file.

      documentFileRenameTo(Src, Dest)\n

      Returns: True if success

      "},{"location":"qsl4a/storage/documentfile/#documentfilecopy","title":"documentFileCopy()","text":"

      Copy file.

      documentFileCopy(SrcFileOrTree, DestFileOrTree)\n
      "},{"location":"qsl4a/storage/documentfile/#stream-operations","title":"Stream Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfileinputstream","title":"documentFileInputStream()","text":"

      Read file content.

      documentFileInputStream(srcFile, EncodingFormat=\"\", skip=None, length=None)\n

      Parameters: - srcFile (str): Source file - EncodingFormat (str): \"UTF-8\", \"GBK\", \"Base64\", or \"\" for bytes - skip (int): Skip bytes from start - length (int): Read length

      Returns: File content

      "},{"location":"qsl4a/storage/documentfile/#documentfileoutputstream","title":"documentFileOutputStream()","text":"

      Write file content.

      documentFileOutputStream(destFile, src, EncodingFormat=\"\", append=None)\n

      Parameters: - destFile (str): Destination file - src: Data to write - EncodingFormat (str): Encoding format - append (bool): Append mode

      "},{"location":"qsl4a/storage/documentfile/#file-information","title":"File Information","text":""},{"location":"qsl4a/storage/documentfile/#documentfilelength","title":"documentFileLength()","text":"

      Get file size in bytes.

      documentFileLength(path)\n

      Parameters: - path (str): File path

      Returns: File size in bytes (0 if not exists)

      "},{"location":"qsl4a/storage/documentfile/#documentfilelastmodified","title":"documentFileLastModified()","text":"

      Get last modified time.

      documentFileLastModified(path)\n

      Parameters: - path (str): File path

      Returns: Timestamp (0 if not exists)

      "},{"location":"qsl4a/storage/documentfile/#documentfilegetstat","title":"documentFileGetStat()","text":"

      Get comprehensive file statistics.

      documentFileGetStat(path)\n

      Parameters: - path (str): File path

      Returns: Dict with length, last modified, and read/write permissions, or None if not exists

      "},{"location":"qsl4a/storage/documentfile/#uri-operations","title":"URI Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfilegeturi","title":"documentFileGetUri()","text":"

      Get URI from path.

      documentFileGetUri(path, isDirectory=None)\n
      "},{"location":"qsl4a/storage/documentfile/#documentfileshowopen","title":"documentFileShowOpen()","text":"

      Show file picker.

      documentFileShowOpen()\n

      Returns: Selected file URI

      "},{"location":"qsl4a/storage/documentfile/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Create directory\ndroid.documentFileMkdir(\"/sdcard/MyFolder\")\n\n# List files\nfiles = droid.documentFileListFiles(\"/sdcard\").result\nfor f in files:\n    print(f)\n\n# Read file\ncontent = droid.documentFileInputStream(\n    \"/sdcard/test.txt\",\n    EncodingFormat=\"UTF-8\"\n).result\nprint(content)\n\n# Write file\ndroid.documentFileOutputStream(\n    \"/sdcard/output.txt\",\n    \"Hello World\",\n    EncodingFormat=\"UTF-8\"\n)\n
      "},{"location":"qsl4a/storage/preferences/","title":"Preferences API","text":"

      Store and retrieve data using Android SharedPreferences.

      "},{"location":"qsl4a/storage/preferences/#preference-methods","title":"Preference Methods","text":""},{"location":"qsl4a/storage/preferences/#prefgetvalue","title":"prefGetValue()","text":"

      Read a value from shared preferences.

      prefGetValue(key, filename=None)\n

      Parameters: - key (str): Preference key - filename (str, optional): Preference file name

      Returns: The stored value (any type)

      "},{"location":"qsl4a/storage/preferences/#prefputvalue","title":"prefPutValue()","text":"

      Write a value to shared preferences.

      prefPutValue(key, value, filename=None)\n

      Parameters: - key (str): Preference key - value (object): Value to store - filename (str, optional): Preference file name

      "},{"location":"qsl4a/storage/preferences/#prefgetall","title":"prefGetAll()","text":"

      Get all preference values.

      prefGetAll(filename=None)\n

      Parameters: - filename (str, optional): Preference file name

      Returns: Map of all preferences

      "},{"location":"qsl4a/storage/preferences/#prefremovevalue","title":"prefRemoveValue()","text":"

      Remove a value from shared preferences.

      prefRemoveValue(key, filename=None)\n

      Parameters: - key (str): Preference key to remove - filename (str, optional): Preference file name

      "},{"location":"qsl4a/storage/preferences/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Store values\ndroid.prefPutValue(\"username\", \"alice\")\ndroid.prefPutValue(\"score\", 100)\ndroid.prefPutValue(\"enabled\", True)\n\n# Read a specific value\nusername = droid.prefGetValue(\"username\").result\nprint(f\"Username: {username}\")\n\n# Get all preferences\nall_prefs = droid.prefGetAll().result\nprint(f\"All prefs: {all_prefs}\")\n\n# Remove a value\ndroid.prefRemoveValue(\"score\")\n\n# Use custom filename\ndroid.prefPutValue(\"token\", \"abc123\", filename=\"auth.prefs\")\ntoken = droid.prefGetValue(\"token\", filename=\"auth.prefs\").result\n
      "},{"location":"qsl4a/system/activityresult/","title":"Activity Result API","text":"

      Set activity results for scripts launched via startActivityForResult.

      "},{"location":"qsl4a/system/activityresult/#result-methods","title":"Result Methods","text":""},{"location":"qsl4a/system/activityresult/#setresultboolean","title":"setResultBoolean()","text":"

      Set a boolean result.

      setResultBoolean(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (bool): Boolean result value

      "},{"location":"qsl4a/system/activityresult/#setresultbyte","title":"setResultByte()","text":"

      Set a byte result.

      setResultByte(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (int): Byte result value

      "},{"location":"qsl4a/system/activityresult/#setresultshort","title":"setResultShort()","text":"

      Set a short result.

      setResultShort(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (int): Short result value

      "},{"location":"qsl4a/system/activityresult/#setresultchar","title":"setResultChar()","text":"

      Set a character result.

      setResultChar(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (str): Character result value

      "},{"location":"qsl4a/system/activityresult/#setresultinteger","title":"setResultInteger()","text":"

      Set an integer result.

      setResultInteger(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (int): Integer result value

      "},{"location":"qsl4a/system/activityresult/#setresultlong","title":"setResultLong()","text":"

      Set a long result.

      setResultLong(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (int): Long result value

      "},{"location":"qsl4a/system/activityresult/#setresultfloat","title":"setResultFloat()","text":"

      Set a float result.

      setResultFloat(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (float): Float result value

      "},{"location":"qsl4a/system/activityresult/#setresultdouble","title":"setResultDouble()","text":"

      Set a double result.

      setResultDouble(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (float): Double result value

      "},{"location":"qsl4a/system/activityresult/#setresultstring","title":"setResultString()","text":"

      Set a string result.

      setResultString(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (str): String result value

      "},{"location":"qsl4a/system/activityresult/#setresultbooleanarray","title":"setResultBooleanArray()","text":"

      Set a boolean array result.

      setResultBooleanArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Boolean array

      "},{"location":"qsl4a/system/activityresult/#setresultbytearray","title":"setResultByteArray()","text":"

      Set a byte array result.

      setResultByteArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Byte array

      "},{"location":"qsl4a/system/activityresult/#setresultshortarray","title":"setResultShortArray()","text":"

      Set a short array result.

      setResultShortArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Short array

      "},{"location":"qsl4a/system/activityresult/#setresultchararray","title":"setResultCharArray()","text":"

      Set a character array result.

      setResultCharArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Char array

      "},{"location":"qsl4a/system/activityresult/#setresultintegerarray","title":"setResultIntegerArray()","text":"

      Set an integer array result.

      setResultIntegerArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Integer array

      "},{"location":"qsl4a/system/activityresult/#setresultlongarray","title":"setResultLongArray()","text":"

      Set a long array result.

      setResultLongArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Long array

      "},{"location":"qsl4a/system/activityresult/#setresultfloatarray","title":"setResultFloatArray()","text":"

      Set a float array result.

      setResultFloatArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Float array

      "},{"location":"qsl4a/system/activityresult/#setresultdoublearray","title":"setResultDoubleArray()","text":"

      Set a double array result.

      setResultDoubleArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Double array

      "},{"location":"qsl4a/system/activityresult/#setresultstringarray","title":"setResultStringArray()","text":"

      Set a string array result.

      setResultStringArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): String array

      "},{"location":"qsl4a/system/activityresult/#setresultserializable","title":"setResultSerializable()","text":"

      Set a serializable result.

      setResultSerializable(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue: Serializable result value

      "},{"location":"qsl4a/system/activityresult/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# After performing an activity, set the result\n# Example: Return success with data\ndroid.setResultInteger(0, 200)  # RESULT_OK\ndroid.setResultString(0, \"Operation completed successfully\")\n\n# Return an array result\ndroid.setResultIntegerArray(0, [1, 2, 3, 4, 5])\n
      "},{"location":"qsl4a/system/application/","title":"Application Management","text":"

      Manage applications, launch apps, and query system information.

      "},{"location":"qsl4a/system/application/#application-information","title":"Application Information","text":""},{"location":"qsl4a/system/application/#getapplicationinfo","title":"getApplicationInfo()","text":"

      Get information about an app.

      getApplicationInfo(packageName=None)\n

      Parameters: - packageName (str): Package name (None = current app)

      Returns: App info dict

      "},{"location":"qsl4a/system/application/#getinstalledpackages","title":"getInstalledPackages()","text":"

      Get list of installed packages.

      getInstalledPackages(flag=4)\n

      Parameters: - flag (int): Package flag filter (default: 4)

      Returns: List of installed packages

      "},{"location":"qsl4a/system/application/#getrunningpackages","title":"getRunningPackages()","text":"

      List running packages.

      getRunningPackages()\n

      Returns: List of package names

      "},{"location":"qsl4a/system/application/#getlaunchablepackages","title":"getLaunchablePackages()","text":"

      Get list of launchable packages.

      getLaunchablePackages(needClassName=False)\n

      Parameters: - needClassName (bool): Include main activity class name (default: False)

      Returns: List of launchable package names or dict with class names

      "},{"location":"qsl4a/system/application/#application-control","title":"Application Control","text":""},{"location":"qsl4a/system/application/#launch","title":"launch()","text":"

      Launch an application.

      launch(classname=None, packagename=None, wait=True)\n

      Parameters: - classname (str): Main activity class name - packagename (str): Package name - wait (bool): Wait for launch to complete (default: True)

      Returns: Launch result

      "},{"location":"qsl4a/system/application/#forcestoppackage","title":"forceStopPackage()","text":"

      Force stop an application.

      forceStopPackage(packageName)\n

      Parameters: - packageName (str): Package name to stop

      "},{"location":"qsl4a/system/application/#version-information","title":"Version Information","text":""},{"location":"qsl4a/system/application/#getpackageversion","title":"getPackageVersion()","text":"

      Get app version name.

      getPackageVersion(packageName)\n

      Returns: Version string (e.g., \"3.2.1\")

      "},{"location":"qsl4a/system/application/#getpackageversioncode","title":"getPackageVersionCode()","text":"

      Get app version code.

      getPackageVersionCode(packageName)\n

      Returns: Version code integer

      "},{"location":"qsl4a/system/application/#getconstants","title":"getConstants()","text":"

      Get class constants.

      getConstants(classname)\n

      Parameters: - classname (str): Full class name

      Returns: Dict of constant names and values

      "},{"location":"qsl4a/system/application/#system-features","title":"System Features","text":""},{"location":"qsl4a/system/application/#backgroundprotect","title":"backgroundProtect()","text":"

      Enable or disable background protection for the app.

      backgroundProtect(enabled=True)\n

      Parameters: - enabled (bool): True to enable protection, False to disable

      "},{"location":"qsl4a/system/application/#createscriptshortcut","title":"createScriptShortCut()","text":"

      Create a home screen shortcut for a script.

      createScriptShortCut(scriptPath, label=None, iconPath=None, scriptArg=None)\n

      Parameters: - scriptPath (str): Path to the Python script - label (str, optional): Shortcut label - iconPath (str, optional): Path to icon image - scriptArg (str, optional): Argument to pass to script

      "},{"location":"qsl4a/system/application/#device-information","title":"Device Information","text":""},{"location":"qsl4a/system/application/#getandroidid","title":"getAndroidID()","text":"

      Get Android device ID.

      getAndroidID()\n

      Returns: Unique Android device ID string

      "},{"location":"qsl4a/system/application/#getsysinfo","title":"getSysInfo()","text":"

      Get system information.

      getSysInfo()\n

      Returns: Dict with system details

      "},{"location":"qsl4a/system/application/#getlocale","title":"getLocale()","text":"

      Get device locale.

      getLocale()\n

      Returns: Locale string (e.g., \"en_US\")

      "},{"location":"qsl4a/system/application/#getharmonyosinformation","title":"getHarmonyOsInformation()","text":"

      Get HarmonyOS information if running on HarmonyOS.

      getHarmonyOsInformation()\n

      Returns: HarmonyOS version info or None

      "},{"location":"qsl4a/system/application/#isexternalstoragemanager","title":"isExternalStorageManager()","text":"

      Check if app has external storage manager permission.

      isExternalStorageManager()\n

      Returns: True if has permission

      "},{"location":"qsl4a/system/application/#memory-and-display","title":"Memory and Display","text":""},{"location":"qsl4a/system/application/#getmemoryinfo","title":"getMemoryInfo()","text":"

      Get memory information.

      getMemoryInfo()\n

      Returns: Dict with memory stats

      "},{"location":"qsl4a/system/application/#getscreeninfo","title":"getScreenInfo()","text":"

      Get screen information.

      getScreenInfo()\n

      Returns: Dict with width, height, density

      "},{"location":"qsl4a/system/application/#permissions","title":"Permissions","text":""},{"location":"qsl4a/system/application/#checkpermissions","title":"checkPermissions()","text":"

      Check current app permissions.

      checkPermissions()\n

      Returns: Dict of permissions and their status

      "},{"location":"qsl4a/system/application/#requestpermissions","title":"requestPermissions()","text":"

      Request permissions from the user.

      requestPermissions(permissions=None)\n

      Parameters: - permissions (list, optional): List of permissions to request. If None, requests all needed permissions.

      Returns: Result of permission request

      "},{"location":"qsl4a/system/application/#system-actions","title":"System Actions","text":""},{"location":"qsl4a/system/application/#showscreenlock","title":"showScreenLock()","text":"

      Show screen lock (PIN/pattern/password entry).

      showScreenLock()\n
      "},{"location":"qsl4a/system/application/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get system info\ninfo = droid.getSysInfo().result\nprint(f\"System: {info}\")\n\n# Get app version\nversion = droid.getPackageVersion(\"org.qpython.qpy\").result\nprint(f\"QPython version: {version}\")\n\n# List installed apps\napps = droid.getInstalledPackages().result\nprint(f\"Installed apps: {len(apps)}\")\n\n# Launch an app\ndroid.launch(packagename=\"com.android.settings\")\n\n# Check permissions\nperms = droid.checkPermissions().result\nprint(f\"Permissions: {perms}\")\n\n# Request storage permission\ndroid.requestPermissions([\"android.permission.READ_EXTERNAL_STORAGE\"])\n\n# Create shortcut\ndroid.createScriptShortCut(\n    \"/sdcard/my_script.py\",\n    label=\"My Script\",\n    iconPath=\"/sdcard/icon.png\"\n)\n
      "},{"location":"qsl4a/system/battery/","title":"Battery API","text":"

      Monitor device battery status and health.

      "},{"location":"qsl4a/system/battery/#methods","title":"Methods","text":""},{"location":"qsl4a/system/battery/#readbatterydata","title":"readBatteryData()","text":"

      Get complete battery information.

      readBatteryData()\n

      Returns: Dict with battery data

      "},{"location":"qsl4a/system/battery/#batterystartmonitoring","title":"batteryStartMonitoring()","text":"

      Start battery monitoring.

      batteryStartMonitoring()\n
      "},{"location":"qsl4a/system/battery/#batterystopmonitoring","title":"batteryStopMonitoring()","text":"

      Stop battery monitoring.

      batteryStopMonitoring()\n
      "},{"location":"qsl4a/system/battery/#batterygetlevel","title":"batteryGetLevel()","text":"

      Get battery percentage.

      batteryGetLevel()\n

      Returns: Int (0-100)

      "},{"location":"qsl4a/system/battery/#batterygetstatus","title":"batteryGetStatus()","text":"

      Get charging status.

      batteryGetStatus()\n

      Returns: - 1: Unknown - 2: Charging - 3: Discharging - 4: Not charging - 5: Full

      "},{"location":"qsl4a/system/battery/#batterygetplugtype","title":"batteryGetPlugType()","text":"

      Get power source.

      batteryGetPlugType()\n

      Returns: - -1: Unknown - 0: Unplugged - 1: AC charger - 2: USB port

      "},{"location":"qsl4a/system/battery/#batterygethealth","title":"batteryGetHealth()","text":"

      Get battery health.

      batteryGetHealth()\n

      Returns: - 1: Unknown - 2: Good - 3: Overheat - 4: Dead - 5: Over voltage - 6: Unspecified failure

      "},{"location":"qsl4a/system/battery/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get battery level\nlevel = droid.batteryGetLevel().result\nprint(f\"Battery: {level}%\")\n
      "},{"location":"qsl4a/system/qpyinterface/","title":"QPython Interface API","text":"

      Execute QPython scripts and manage shared variables from other apps.

      "},{"location":"qsl4a/system/qpyinterface/#script-execution-methods","title":"Script Execution Methods","text":""},{"location":"qsl4a/system/qpyinterface/#executeqpy","title":"executeQPy()","text":"

      Execute a QPython script.

      executeQPy(path=\"\", arg=None)\n

      Parameters: - path (str): Path to the script file - arg (str, optional): Command line arguments

      Returns: True if started successfully

      "},{"location":"qsl4a/system/qpyinterface/#executeqpyassrv","title":"executeQPyAsSrv()","text":"

      Execute a QPython script as a service.

      executeQPyAsSrv(path=None)\n

      Parameters: - path (str, optional): Path to the script file

      Returns: True if started successfully

      "},{"location":"qsl4a/system/qpyinterface/#executeqpycode","title":"executeQPyCode()","text":"

      Execute Python code directly.

      executeQPyCode(code=None)\n

      Parameters: - code (str, optional): Python code to execute

      Returns: True if started successfully

      "},{"location":"qsl4a/system/qpyinterface/#executeqpycodeassrv","title":"executeQPyCodeAsSrv()","text":"

      Execute Python code as a service.

      executeQPyCodeAsSrv(code=None)\n

      Parameters: - code (str, optional): Python code to execute

      Returns: True if started successfully

      "},{"location":"qsl4a/system/qpyinterface/#shared-variables","title":"Shared Variables","text":"

      Shared variables allow communication between QPython and other apps.

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableset","title":"sharedVariableSet()","text":"

      Set a Java shared variable.

      sharedVariableSet(key, value)\n

      Parameters: - key (str): Variable name - value (str): Variable value

      Returns: The stored value

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableget","title":"sharedVariableGet()","text":"

      Get a Java shared variable.

      sharedVariableGet(key)\n

      Parameters: - key (str): Variable name

      Returns: The stored value

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableremove","title":"sharedVariableRemove()","text":"

      Remove a Java shared variable.

      sharedVariableRemove(key)\n

      Parameters: - key (str): Variable name to remove

      Returns: The removed value

      "},{"location":"qsl4a/system/qpyinterface/#getlastlog","title":"getLastLog()","text":"

      Get the last log output from QPython.

      getLastLog()\n

      Returns: String log content

      "},{"location":"qsl4a/system/qpyinterface/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Execute a script\ndroid.executeQPy(\"/sdcard/my_script.py\", arg=\"test\")\n\n# Execute code directly\ncode = \"print('Hello from QPython!')\"\ndroid.executeQPyCode(code)\n\n# Use shared variables\ndroid.sharedVariableSet(\"username\", \"alice\")\nusername = droid.sharedVariableGet(\"username\").result\nprint(f\"Username: {username}\")\n\n# Remove variable\ndroid.sharedVariableRemove(\"username\")\n\n# Get recent log\nlog = droid.getLastLog().result\nprint(f\"Log: {log}\")\n
      "},{"location":"qsl4a/system/sensors/","title":"Sensor API","text":"

      Access device sensors including accelerometer, gyroscope, magnetometer, and more.

      "},{"location":"qsl4a/system/sensors/#methods","title":"Methods","text":""},{"location":"qsl4a/system/sensors/#startsensingtimed","title":"startSensingTimed()","text":"

      Start sensor monitoring with time intervals.

      startSensingTimed(sensorNumber, delayTime)\n

      Parameters: - sensorNumber (int): Sensor ID (1-3 typically) - delayTime (int): Delay between readings in milliseconds

      "},{"location":"qsl4a/system/sensors/#startsensingthreshold","title":"startSensingThreshold()","text":"

      Start sensor monitoring with threshold trigger.

      startSensingThreshold(sensorNumber, threshold, axis)\n

      Parameters: - sensorNumber (int): Sensor ID - threshold (float): Trigger threshold - axis (int): Axis to monitor (0=X, 1=Y, 2=Z)

      "},{"location":"qsl4a/system/sensors/#stopsensing","title":"stopSensing()","text":"

      Stop all sensor monitoring.

      stopSensing()\n
      "},{"location":"qsl4a/system/sensors/#readsensors","title":"readSensors()","text":"

      Read current sensor data.

      readSensors()\n

      Returns: Sensor data dict

      "},{"location":"qsl4a/system/sensors/#sensorsreadaccelerometer","title":"sensorsReadAccelerometer()","text":"

      Read accelerometer values.

      sensorsReadAccelerometer()\n

      Returns: List [X, Y, Z] in m/s\u00b2

      "},{"location":"qsl4a/system/sensors/#sensorsreadgyroscope","title":"sensorsReadGyroscope()","text":"

      Read gyroscope values.

      sensorsReadGyroscope()\n

      Returns: List [X, Y, Z] in rad/s

      "},{"location":"qsl4a/system/sensors/#sensorsreadmagnetometer","title":"sensorsReadMagnetometer()","text":"

      Read magnetic field values.

      sensorsReadMagnetometer()\n

      Returns: List [X, Y, Z] in \u03bcT

      "},{"location":"qsl4a/system/sensors/#sensorsreadorientation","title":"sensorsReadOrientation()","text":"

      Read device orientation.

      sensorsReadOrientation()\n

      Returns: List [azimuth, pitch, roll] in degrees

      "},{"location":"qsl4a/system/sensors/#sensorsgetlight","title":"sensorsGetLight()","text":"

      Read light sensor value.

      sensorsGetLight()\n

      Returns: Light level in lux

      "},{"location":"qsl4a/system/sensors/#sensorsgetstepcounter","title":"sensorsGetStepCounter()","text":"

      Read step counter.

      sensorsGetStepCounter()\n

      Returns: Number of steps

      "},{"location":"qsl4a/system/sensors/#sensorsgetaccuracy","title":"sensorsGetAccuracy()","text":"

      Get the current sensor accuracy.

      sensorsGetAccuracy()\n

      Returns: Accuracy value (0-3: UNRELIABLE, ACCURACY_LOW, ACCURACY_MEDIUM, ACCURACY_HIGH)

      "},{"location":"qsl4a/system/sensors/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start sensing\ndroid.startSensingTimed(1, 250)\n\n# Read sensors 10 times\nfor i in range(10):\n    accel = droid.sensorsReadAccelerometer().result\n    print(f\"Accel: X={accel[0]:.2f}, Y={accel[1]:.2f}, Z={accel[2]:.2f}\")\n    time.sleep(0.5)\n\ndroid.stopSensing()\n
      "},{"location":"qsl4a/system/settings/","title":"Settings API","text":"

      Control system settings including screen, sound, and network settings.

      "},{"location":"qsl4a/system/settings/#screen-settings","title":"Screen Settings","text":""},{"location":"qsl4a/system/settings/#setscreentimeout","title":"setScreenTimeout()","text":"

      Set the screen timeout value.

      setScreenTimeout(value)\n

      Parameters: - value (int): Screen timeout in seconds

      Returns: Previous timeout value

      "},{"location":"qsl4a/system/settings/#getscreentimeout","title":"getScreenTimeout()","text":"

      Get the current screen timeout.

      getScreenTimeout()\n

      Returns: Current screen timeout in seconds

      "},{"location":"qsl4a/system/settings/#getscreenbrightness","title":"getScreenBrightness()","text":"

      Get the screen brightness value.

      getScreenBrightness()\n

      Returns: Brightness value (0-255)

      "},{"location":"qsl4a/system/settings/#setscreenbrightness","title":"setScreenBrightness()","text":"

      Set the screen brightness.

      setScreenBrightness(value=None)\n

      Parameters: - value (int, optional): Brightness value (0-255), or None for auto

      Returns: Previous brightness value

      "},{"location":"qsl4a/system/settings/#checkscreenon","title":"checkScreenOn()","text":"

      Check if the screen is on.

      checkScreenOn()\n

      Returns: True if screen is on, False otherwise

      "},{"location":"qsl4a/system/settings/#airplane-mode","title":"Airplane Mode","text":""},{"location":"qsl4a/system/settings/#checkairplanemode","title":"checkAirplaneMode()","text":"

      Check if airplane mode is enabled.

      checkAirplaneMode()\n

      Returns: True if airplane mode is on

      "},{"location":"qsl4a/system/settings/#ringer-settings","title":"Ringer Settings","text":""},{"location":"qsl4a/system/settings/#checkringersilentmode","title":"checkRingerSilentMode()","text":"

      Check if ringer is in silent mode.

      checkRingerSilentMode()\n

      Returns: True if silent mode is on

      "},{"location":"qsl4a/system/settings/#toggleringersilentmode","title":"toggleRingerSilentMode()","text":"

      Toggle ringer silent mode.

      toggleRingerSilentMode(enabled=None)\n

      Parameters: - enabled (bool, optional): True to enable, False to disable, None to toggle

      Returns: New state

      "},{"location":"qsl4a/system/settings/#togglevibratemode","title":"toggleVibrateMode()","text":"

      Toggle vibrate mode.

      toggleVibrateMode(enabled=None, ringer=None)\n

      Parameters: - enabled (bool, optional): Toggle vibrate on/off - ringer (bool, optional): Apply to ringer mode

      Returns: New state

      "},{"location":"qsl4a/system/settings/#getvibratemode","title":"getVibrateMode()","text":"

      Get the vibrate mode setting.

      getVibrateMode(ringer=None)\n

      Parameters: - ringer (bool, optional): Check ringer vibrate mode

      Returns: True if vibrate is enabled

      "},{"location":"qsl4a/system/settings/#volume-settings","title":"Volume Settings","text":""},{"location":"qsl4a/system/settings/#getringervolume","title":"getRingerVolume()","text":"

      Get the current ringer volume.

      getRingerVolume()\n

      Returns: Ringer volume level (0-7 typically)

      "},{"location":"qsl4a/system/settings/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

      Get the maximum ringer volume.

      getMaxRingerVolume()\n

      Returns: Maximum ringer volume

      "},{"location":"qsl4a/system/settings/#setringervolume","title":"setRingerVolume()","text":"

      Set the ringer volume.

      setRingerVolume(volume)\n

      Parameters: - volume (int): Volume level

      "},{"location":"qsl4a/system/settings/#getmediavolume","title":"getMediaVolume()","text":"

      Get the current media volume.

      getMediaVolume()\n

      Returns: Media volume level (0-15 typically)

      "},{"location":"qsl4a/system/settings/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

      Get the maximum media volume.

      getMaxMediaVolume()\n

      Returns: Maximum media volume

      "},{"location":"qsl4a/system/settings/#setmediavolume","title":"setMediaVolume()","text":"

      Set the media volume.

      setMediaVolume(volume)\n

      Parameters: - volume (int): Volume level

      "},{"location":"qsl4a/system/settings/#system-info","title":"System Info","text":""},{"location":"qsl4a/system/settings/#elapsedrealtimenanos","title":"elapsedRealtimeNanos()","text":"

      Get nanoseconds since system startup.

      elapsedRealtimeNanos()\n

      Returns: Nanoseconds (can be used for timing)

      "},{"location":"qsl4a/system/settings/#gettrafficstats","title":"getTrafficStats()","text":"

      Get network traffic statistics.

      getTrafficStats(flags=7)\n

      Parameters: - flags (int): Which stats to retrieve (default: 7 = all)

      Returns: Dict with transmit/receive bytes

      "},{"location":"qsl4a/system/settings/#getapptxbytes","title":"getAppTxBytes()","text":"

      Get transmit bytes for QPython app.

      getAppTxBytes(packageName)\n

      Parameters: - packageName (str): Package name

      Returns: Dict with tx/rx bytes

      "},{"location":"qsl4a/system/settings/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Screen settings\ncurrent_timeout = droid.getScreenTimeout().result\nprint(f\"Current timeout: {current_timeout}s\")\ndroid.setScreenTimeout(30)\n\n# Check screen\nif droid.checkScreenOn().result:\n    print(\"Screen is on\")\n\n# Volume control\nmedia_vol = droid.getMediaVolume().result\nprint(f\"Media volume: {media_vol}\")\ndroid.setMediaVolume(10)\n\n# Check airplane mode\nif droid.checkAirplaneMode().result:\n    print(\"Airplane mode is on\")\n
      "},{"location":"qsl4a/system/sysinfo/","title":"System Information","text":"

      Retrieve device and system information.

      "},{"location":"qsl4a/system/sysinfo/#device-information","title":"Device Information","text":""},{"location":"qsl4a/system/sysinfo/#getandroidid","title":"getAndroidID()","text":"

      Get the Android device ID.

      getAndroidID()\n

      Returns: String device ID

      "},{"location":"qsl4a/system/sysinfo/#getsysinfo","title":"getSysInfo()","text":"

      Get comprehensive system information.

      getSysInfo()\n

      Returns: Dict with system details

      "},{"location":"qsl4a/system/sysinfo/#getlocale","title":"getLocale()","text":"

      Get device locale settings.

      getLocale()\n

      Returns: Locale string (e.g., \"en_US\")

      "},{"location":"qsl4a/system/sysinfo/#memory","title":"Memory","text":""},{"location":"qsl4a/system/sysinfo/#getmemoryinfo","title":"getMemoryInfo()","text":"

      Get RAM information.

      getMemoryInfo()\n

      Returns: Dict with memory stats

      "},{"location":"qsl4a/system/sysinfo/#display","title":"Display","text":""},{"location":"qsl4a/system/sysinfo/#getscreeninfo","title":"getScreenInfo()","text":"

      Get display information.

      getScreenInfo()\n

      Returns: Dict with width, height, density

      "},{"location":"qsl4a/system/sysinfo/#identifiers","title":"Identifiers","text":""},{"location":"qsl4a/system/sysinfo/#getimei","title":"getImei()","text":"

      Get device IMEI.

      getImei(slotIndex=None)\n
      "},{"location":"qsl4a/system/sysinfo/#getmeid","title":"getMeid()","text":"

      Get device MEID.

      getMeid(slotIndex=None)\n
      "},{"location":"qsl4a/system/sysinfo/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Device ID\nandroid_id = droid.getAndroidID().result\nprint(f\"Android ID: {android_id}\")\n\n# Screen info\nscreen = droid.getScreenInfo().result\nprint(f\"Screen: {screen['width']}x{screen['height']}\")\n\n# Memory\nmemory = droid.getMemoryInfo().result\nprint(f\"Memory: {memory}\")\n
      "},{"location":"qsl4a/system/wakelock/","title":"WakeLock API","text":"

      Control device wake locks to keep the CPU or screen on.

      "},{"location":"qsl4a/system/wakelock/#wake-lock-types","title":"Wake Lock Types","text":"

      QSL4A provides different wake lock types:

      Type Description Full CPU on, screen bright, keyboard bright Partial CPU on only Bright CPU on, screen bright Dim CPU on, screen dim"},{"location":"qsl4a/system/wakelock/#wake-lock-methods","title":"Wake Lock Methods","text":""},{"location":"qsl4a/system/wakelock/#wakelockacquirefull","title":"wakeLockAcquireFull()","text":"

      Acquire a full wake lock (CPU on, screen bright, keyboard bright).

      wakeLockAcquireFull()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquirepartial","title":"wakeLockAcquirePartial()","text":"

      Acquire a partial wake lock (CPU on only).

      wakeLockAcquirePartial()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquirebright","title":"wakeLockAcquireBright()","text":"

      Acquire a bright wake lock (CPU on, screen bright).

      wakeLockAcquireBright()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquiredim","title":"wakeLockAcquireDim()","text":"

      Acquire a dim wake lock (CPU on, screen dim).

      wakeLockAcquireDim()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockrelease","title":"wakeLockRelease()","text":"

      Release the wake lock.

      wakeLockRelease()\n
      "},{"location":"qsl4a/system/wakelock/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Acquire full wake lock\ndroid.wakeLockAcquireFull()\n\n# Do important work while keeping screen on\nprint(\"Screen will stay on\")\ntime.sleep(10)\n\n# Release when done\ndroid.wakeLockRelease()\n\n# Or use partial lock for background tasks\ndroid.wakeLockAcquirePartial()\n# CPU stays on even with screen off\ntime.sleep(30)\ndroid.wakeLockRelease()\n

      Note: Remember to release wake locks when no longer needed to conserve battery.

      "},{"location":"qsl4a/ui/accessibility/","title":"Accessibility Service","text":"

      The Accessibility Service allows automation of UI interactions like clicks, swipes, and system actions.

      "},{"location":"qsl4a/ui/accessibility/#service-control","title":"Service Control","text":""},{"location":"qsl4a/ui/accessibility/#accessibilitystartservice","title":"accessibilityStartService()","text":"

      Start the accessibility service.

      accessibilityStartService()\n

      Returns: True if successful, False otherwise

      "},{"location":"qsl4a/ui/accessibility/#accessibilityserviceenabled","title":"accessibilityServiceEnabled()","text":"

      Check if accessibility service is enabled.

      accessibilityServiceEnabled()\n

      Returns: True or False

      "},{"location":"qsl4a/ui/accessibility/#screen-interactions","title":"Screen Interactions","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityclick","title":"accessibilityClick()","text":"

      Click at screen coordinates.

      accessibilityClick(x=0, y=0, t=50)\n

      Parameters: - x (int/float): X coordinate (0=center, decimals supported) - y (int/float): Y coordinate (0=center, decimals supported) - t (int): Press duration in milliseconds (default: 50)

      "},{"location":"qsl4a/ui/accessibility/#accessibilityslide","title":"accessibilitySlide()","text":"

      Multi-point slide gesture.

      accessibilitySlide(XnYn=None, t=None)\n

      Parameters: - XnYn (list): Coordinates [X1, Y1, X2, Y2, ... Xn, Yn] - t (int): Slide duration (default: 50*n ms)

      "},{"location":"qsl4a/ui/accessibility/#system-actions","title":"System Actions","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityaction","title":"accessibilityAction()","text":"

      Execute system action by code.

      accessibilityAction(actionCode)\n

      Action Codes: | Code | Constant | Description | |------|----------|-------------| | 1 | BACK | Back button | | 2 | HOME | Home button | | 3 | RECENTS | Recent apps | | 4 | NOTIFICATIONS | Open notifications | | 5 | QUICK_SETTINGS | Open quick settings | | 6 | POWER_DIALOG | Power menu | | 7 | TOGGLE_SPLIT_SCREEN | Split screen | | 8 | LOCK_SCREEN | Lock screen | | 9 | TAKE_SCREENSHOT | Take screenshot | | 10 | KEYCODE_HEADSETHOOK | Headset hook | | 11-14 | ACCESSIBILITY_ | Accessibility buttons | | 15 | DISMISS_NOTIFICATION_SHADE | Close notifications | | 16-20 | DPAD_ | Directional pad | | 21 | MENU | Menu button | | 22 | MEDIA_PLAY_PAUSE | Play/Pause media |

      "},{"location":"qsl4a/ui/accessibility/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/accessibility/#click-center-screen","title":"Click Center Screen","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Start service\nif not droid.accessibilityServiceEnabled().result:\n    droid.accessibilityStartService()\n\n# Click center (0,0 = center)\ndroid.accessibilityClick(0, 0, t=100)\n
      "},{"location":"qsl4a/ui/accessibility/#swipe-gesture","title":"Swipe Gesture","text":"
      # Swipe from bottom to top (scroll up)\ndroid.accessibilitySlide([0, 1.5, 0, -1.5], t=300)\n
      "},{"location":"qsl4a/ui/accessibility/#system-navigation","title":"System Navigation","text":"
      # Press home\ndroid.accessibilityAction(2)\n\n# Press back\ndroid.accessibilityAction(1)\n\n# Open notifications\ndroid.accessibilityAction(4)\n
      "},{"location":"qsl4a/ui/accessibility/#tap-specific-location","title":"Tap Specific Location","text":"
      # Tap at screen coordinate (500, 800)\ndroid.accessibilityClick(500, 800)\n\n# Tap at relative position (center horizontally, 3/4 down)\ndroid.accessibilityClick(0, 1.5)\n
      "},{"location":"qsl4a/ui/dialogs/","title":"Dialog System","text":"

      QSL4A provides comprehensive dialog support for user interaction, including alerts, input dialogs, choice dialogs, and progress dialogs.

      "},{"location":"qsl4a/ui/dialogs/#alert-dialogs","title":"Alert Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowalert","title":"dialogShowAlert()","text":"

      Show a simple alert dialog.

      dialogShowAlert(title=\"Alert\", message=\"The message of the alert.\",\n                positiveButtonText=\"OK\", negativeButtonText=None,\n                neutralButtonText=None, messageIsHtml=False)\n

      Parameters: - title (str): Dialog title - message (str): Message text - positiveButtonText (str): Positive button label - negativeButtonText (str, optional): Negative button label - neutralButtonText (str, optional): Neutral button label - messageIsHtml (bool): Parse message as HTML

      Returns: Result with button clicked

      "},{"location":"qsl4a/ui/dialogs/#dialogshowsimplechoice","title":"dialogShowSimpleChoice()","text":"

      Show a simple choice dialog with items.

      dialogShowSimpleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

      Parameters: - items (list): List of choice strings

      Returns: Result with selected item

      "},{"location":"qsl4a/ui/dialogs/#input-dialogs","title":"Input Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialoggetinput","title":"dialogGetInput()","text":"

      Get text input from user.

      dialogGetInput(title=\"Value\", message=\"Please enter value:\",\n               defaultText=None, messageIsHtml=False)\n

      Returns: Result with user's input text

      "},{"location":"qsl4a/ui/dialogs/#dialoggetpassword","title":"dialogGetPassword()","text":"

      Get password input.

      dialogGetPassword(title=\"Password\", message=\"Please enter password:\")\n

      Returns: Result with password entered

      "},{"location":"qsl4a/ui/dialogs/#dialogcreateinput","title":"dialogCreateInput()","text":"

      Create a custom input dialog.

      dialogCreateInput(title=\"Value\", message=\"Please enter value:\",\n                  defaultText=None, inputType=None)\n

      Parameters: - inputType (str): Input type (e.g., \"text\", \"number\", \"textPassword\")

      "},{"location":"qsl4a/ui/dialogs/#dialogcreatepassword","title":"dialogCreatePassword()","text":"

      Create a password input dialog.

      dialogCreatePassword(title=\"Password\", message=\"Please enter password:\")\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreateseekbar","title":"dialogCreateSeekBar()","text":"

      Create a seek bar/slider dialog.

      dialogCreateSeekBar(starting_value=50, maximum_value=100, title=\"\", message=\"\")\n

      Parameters: - starting_value (int): Initial value - maximum_value (int): Maximum value

      "},{"location":"qsl4a/ui/dialogs/#choice-dialogs","title":"Choice Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowsinglechoice","title":"dialogShowSingleChoice()","text":"

      Show single choice (radio) dialog.

      dialogShowSingleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, selected=-1, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

      Parameters: - items (list): List of choice strings - selected (int): Default selected index

      "},{"location":"qsl4a/ui/dialogs/#dialogshowmultichoice","title":"dialogShowMultiChoice()","text":"

      Show multiple choice (checkbox) dialog.

      dialogShowMultiChoice(title=\"Alert\", message=\"The message of the alert.\",\n                      items=None, selected=None, positiveButtonText=\"OK\",\n                      negativeButtonText=None, neutralButtonText=None,\n                      messageIsHtml=False)\n

      Parameters: - items (list): List of choice strings - selected (list): List of initially selected indices

      "},{"location":"qsl4a/ui/dialogs/#dialogsetsinglechoiceitems","title":"dialogSetSingleChoiceItems()","text":"

      Set single choice items for a dialog.

      dialogSetSingleChoiceItems(items, selected=-1)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmultichoiceitems","title":"dialogSetMultiChoiceItems()","text":"

      Set multiple choice items for a dialog.

      dialogSetMultiChoiceItems(items, selected=None)\n
      "},{"location":"qsl4a/ui/dialogs/#progress-dialogs","title":"Progress Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatespinnerprogress","title":"dialogCreateSpinnerProgress()","text":"

      Create indeterminate progress dialog.

      dialogCreateSpinnerProgress(title=None, message=None, maximum_progress=100)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreatehorizontalprogress","title":"dialogCreateHorizontalProgress()","text":"

      Create horizontal progress dialog.

      dialogCreateHorizontalProgress(title=None, message=None, maximum_progress=100)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetcurrentprogress","title":"dialogSetCurrentProgress()","text":"

      Update progress value.

      dialogSetCurrentProgress(current)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmaxprogress","title":"dialogSetMaxProgress()","text":"

      Set maximum progress value.

      dialogSetMaxProgress(max)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetprogressmessage","title":"dialogSetProgressMessage()","text":"

      Update the progress dialog message.

      dialogSetProgressMessage(message)\n
      "},{"location":"qsl4a/ui/dialogs/#picker-dialogs","title":"Picker Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatedatepicker","title":"dialogCreateDatePicker()","text":"

      Create date picker dialog.

      dialogCreateDatePicker(year=1970, month=1, day=1)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreatetimepicker","title":"dialogCreateTimePicker()","text":"

      Create time picker dialog.

      dialogCreateTimePicker(hour=0, minute=0, is24hour=False)\n
      "},{"location":"qsl4a/ui/dialogs/#custom-dialog-creation","title":"Custom Dialog Creation","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatealert","title":"dialogCreateAlert()","text":"

      Create a custom alert dialog.

      dialogCreateAlert(title=None, message=None)\n

      Creates an empty alert dialog. Use with other dialogSet* functions to customize.

      "},{"location":"qsl4a/ui/dialogs/#dialogsetitems","title":"dialogSetItems()","text":"

      Set simple list items for the dialog.

      dialogSetItems(items)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetpositivebuttontext","title":"dialogSetPositiveButtonText()","text":"

      Set positive button text.

      dialogSetPositiveButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetnegativebuttontext","title":"dialogSetNegativeButtonText()","text":"

      Set negative button text.

      dialogSetNegativeButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetneutralbuttontext","title":"dialogSetNeutralButtonText()","text":"

      Set neutral button text.

      dialogSetNeutralButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmessageishtml","title":"dialogSetMessageIsHtml()","text":"

      Set whether message should be parsed as HTML.

      dialogSetMessageIsHtml(messageIsHtml=True)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogshow","title":"dialogShow()","text":"

      Show the created custom dialog.

      dialogShow()\n
      "},{"location":"qsl4a/ui/dialogs/#dialog-control","title":"Dialog Control","text":""},{"location":"qsl4a/ui/dialogs/#dialogdismiss","title":"dialogDismiss()","text":"

      Dismiss current dialog.

      dialogDismiss()\n
      "},{"location":"qsl4a/ui/dialogs/#dialoggetresponse","title":"dialogGetResponse()","text":"

      Get dialog response.

      dialogGetResponse()\n
      "},{"location":"qsl4a/ui/dialogs/#dialoggetselecteditems","title":"dialogGetSelectedItems()","text":"

      Get selected items from choice dialog.

      dialogGetSelectedItems()\n
      "},{"location":"qsl4a/ui/dialogs/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/dialogs/#simple-alert","title":"Simple Alert","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Show alert\ndroid.dialogShowAlert(\"Warning\", \"This is an important message!\")\n
      "},{"location":"qsl4a/ui/dialogs/#input-dialog","title":"Input Dialog","text":"
      # Get user input\nresult = droid.dialogGetInput(\"Name\", \"Enter your name:\", \"John\").result\nprint(f\"Hello, {result}!\")\n
      "},{"location":"qsl4a/ui/dialogs/#custom-dialog-with-buttons","title":"Custom Dialog with Buttons","text":"
      # Create custom dialog\ndroid.dialogCreateAlert(\"Custom\", \"Choose an option\")\ndroid.dialogSetItems([\"Option 1\", \"Option 2\", \"Option 3\"])\ndroid.dialogShow()\n\n# Get response\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response['item']}\")\n
      "},{"location":"qsl4a/ui/dialogs/#progress-dialog","title":"Progress Dialog","text":"
      # Create progress dialog\ndroid.dialogCreateHorizontalProgress(\"Loading\", \"Please wait...\", 100)\ndroid.dialogShow()\n\n# Update progress\nfor i in range(101):\n    droid.dialogSetCurrentProgress(i)\n    time.sleep(0.05)\n\ndroid.dialogDismiss()\n
      "},{"location":"qsl4a/ui/dialogs/#date-picker","title":"Date Picker","text":"
      # Show date picker\ndroid.dialogCreateDatePicker(2024, 1, 15)\ndroid.dialogShow()\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response}\")\n
      "},{"location":"qsl4a/ui/floatview/","title":"FloatView","text":"

      Floating window support for overlay UI elements that stay on top of other applications.

      "},{"location":"qsl4a/ui/floatview/#methods","title":"Methods","text":""},{"location":"qsl4a/ui/floatview/#floatview_1","title":"floatView()","text":"

      Show or modify a floating view.

      floatView(Args=None)\n

      Parameters: - Args (dict): Configuration dictionary with the following keys: - index (int): Float view index (-1 to create new, >=0 to modify existing) - text (str): Text content to display - html (str): HTML content (used if text is omitted) - width (int): View width in pixels (default: 300) - height (int): View height in pixels (default: 150) - x (int): X position (0 = center, positive/negative for offset) - y (int): Y position (0 = center, positive/negative for offset) - backColor (str): Background color in ARGB hex (default: '7f7f7f7f') - textColor (str): Text color in ARGB hex (default: 'ff000000') - textSize (int): Text size (default: 10) - textAlign (int): Text alignment (0 = inherit) - script (str): Script path to run after long click close - arg: Script argument - clickRemove (bool): Enable click to remove (default: True) - flag (int): Window flag (default: 40 - touchable)

      Returns: Current chain list length

      "},{"location":"qsl4a/ui/floatview/#floatviewcount","title":"floatViewCount()","text":"

      Get the number of active float views.

      floatViewCount()\n

      Returns: Number of float views

      "},{"location":"qsl4a/ui/floatview/#floatviewresult","title":"floatViewResult()","text":"

      Get the result/status of a float view.

      floatViewResult(index=-1)\n

      Parameters: - index (int): Float view index (default: -1, returns last operation result)

      Returns: Dict with operation details including: - x, y: Position - time: Timestamp - operation: Operation type ('initial', 'move', etc.) - index: View index - removed: True if view was removed

      "},{"location":"qsl4a/ui/floatview/#floatviewremove","title":"floatViewRemove()","text":"

      Remove a float view.

      floatViewRemove(index=-1)\n

      Parameters: - index (int): Index of view to remove (default: -1 removes the last one)

      Returns: 1 if successful, 0 otherwise

      "},{"location":"qsl4a/ui/floatview/#constants","title":"Constants","text":"
      • floatView.INDEX_NEW = -1 - Create new float view
      • floatView.FLAG_DEFAULT_TOUCHABLE = 40 - Default touchable flag
      • floatView.TEXT_ALIGNMENT_INHERIT = 0
      • floatView.TEXT_ALIGNMENT_CENTER - Center text alignment
      "},{"location":"qsl4a/ui/floatview/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/floatview/#basic-float-view","title":"Basic Float View","text":"
      import androidhelper\nfrom androidhelper import Android\n\ndroid = androidhelper.Android()\n\n# Create a simple float view\ndroid.floatView({\n    'index': -1,  # Create new\n    'text': 'Hello World',\n    'width': 400,\n    'height': 300,\n    'x': -300,  # Offset from center\n    'y': -400,\n    'backColor': 'ff0000',  # Red background\n    'textColor': '0000ff',  # Blue text\n    'textSize': 16,\n    'textAlign': droid.floatView.TEXT_ALIGNMENT_CENTER\n})\n\n# Check count\nprint(f\"Float views: {droid.floatViewCount().result}\")\n\n# Get result\nresult = droid.floatViewResult().result\nprint(f\"View info: {result}\")\n\n# Remove the float view\ndroid.floatViewRemove(0)\n
      "},{"location":"qsl4a/ui/floatview/#html-content","title":"HTML Content","text":"
      # Create float view with HTML content\ndroid.floatView({\n    'text': '',  # Empty text to use HTML\n    'html': '<h1>Title</h1><p>Rich <b>HTML</b> content</p>',\n    'width': 500,\n    'height': 400\n})\n
      "},{"location":"qsl4a/ui/floatview/#modify-existing-view","title":"Modify Existing View","text":"
      # Create initial view\ndroid.floatView({'text': 'Initial Text', 'width': 300, 'height': 150})\n\n# Modify the same view (index 0)\ndroid.floatView({\n    'index': 0,\n    'text': 'Updated Text!',\n    'backColor': '7f00ff00'  # Green background\n})\n\n# Check the move/change result\nresult = droid.floatViewResult(0).result\nprint(f\"Operation: {result.get('operation')}, Position: ({result.get('x')}, {result.get('y')})\")\n
      "},{"location":"qsl4a/ui/floatview/#multiple-float-views","title":"Multiple Float Views","text":"
      # Create multiple views\nfor i in range(3):\n    droid.floatView({\n        'index': -1,\n        'text': f'View {i}',\n        'x': i * 100 - 150,\n        'y': i * 100 - 150,\n        'backColor': f'{i}f{i}f{i}f'\n    })\n\nprint(f\"Total views: {droid.floatViewCount().result}\")\n\n# Remove all views\nwhile droid.floatViewCount().result > 0:\n    droid.floatViewRemove()\n
      "},{"location":"qsl4a/ui/floatview/#with-script-callback","title":"With Script Callback","text":"
      # Create float view that runs script on close\ndroid.floatView({\n    'text': 'Click to close and run script',\n    'script': '/sdcard/my_script.py',\n    'arg': 'hello from float view',\n    'clickRemove': True\n})\n
      "},{"location":"qsl4a/ui/fullscreen/","title":"FullScreen UI","text":"

      Create custom fullscreen interfaces with native Android layouts.

      "},{"location":"qsl4a/ui/fullscreen/#layout-methods","title":"Layout Methods","text":""},{"location":"qsl4a/ui/fullscreen/#fullshow","title":"fullShow()","text":"

      Show a fullscreen layout.

      fullShow(layout, title=None, theme=None)\n

      Parameters: - layout (str): JSON layout definition or layout string - title (str, optional): Window title - theme (str, optional): Theme name

      Returns: Window ID

      "},{"location":"qsl4a/ui/fullscreen/#fulldismiss","title":"fullDismiss()","text":"

      Close fullscreen window.

      fullDismiss()\n
      "},{"location":"qsl4a/ui/fullscreen/#fullquery","title":"fullQuery()","text":"

      Query all widget values.

      fullQuery()\n

      Returns: Dict of widget IDs and values

      "},{"location":"qsl4a/ui/fullscreen/#fullquerydetail","title":"fullQueryDetail()","text":"

      Query specific widget details.

      fullQueryDetail(id)\n
      "},{"location":"qsl4a/ui/fullscreen/#property-methods","title":"Property Methods","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperty","title":"fullGetProperty()","text":"

      Get widget property.

      fullGetProperty(id, property)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetproperty","title":"fullSetProperty()","text":"

      Set widget property.

      fullSetProperty(id, property, value)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetlist","title":"fullSetList()","text":"

      Set list widget items.

      fullSetList(id, list, isHtml=False, listType=0)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetlist2","title":"fullSetList2()","text":"

      Set list widget items with resource ID.

      fullSetList2(id, list, intRes)\n

      Parameters: - id (str): Widget ID - list (list): List of items - intRes (int): Android resource ID for list item layout

      "},{"location":"qsl4a/ui/fullscreen/#fullsetlistselected","title":"fullSetListSelected()","text":"

      Set selected item in a list.

      fullSetListSelected(id, selected)\n

      Parameters: - id (str): List widget ID - selected (int): Index of item to select

      "},{"location":"qsl4a/ui/fullscreen/#fullgetlistselected","title":"fullGetListSelected()","text":"

      Get the currently selected list item index.

      fullGetListSelected(id)\n

      Parameters: - id (str): List widget ID

      Returns: Selected item index

      "},{"location":"qsl4a/ui/fullscreen/#batch-property-operations","title":"Batch Property Operations","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperties","title":"fullGetProperties()","text":"

      Get properties for multiple widgets at once.

      fullGetProperties(ids, property)\n

      Parameters: - ids (list): List of widget IDs - property (str): Property name to get

      Returns: Dict mapping widget IDs to property values

      "},{"location":"qsl4a/ui/fullscreen/#fullsetproperties","title":"fullSetProperties()","text":"

      Set property for multiple widgets at once.

      fullSetProperties(ids, property, value)\n

      Parameters: - ids (list): List of widget IDs - property (str): Property name to set - value: Property value

      "},{"location":"qsl4a/ui/fullscreen/#screenshot","title":"Screenshot","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetscreenshot","title":"fullGetScreenShot()","text":"

      Capture fullscreen screenshot.

      fullGetScreenShot(path=None)\n

      Parameters: - path (str, optional): Save path. If None, returns in event

      Returns: Event with screenshot data

      "},{"location":"qsl4a/ui/fullscreen/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Define layout\nlayout = '''\n{ \"type\": \"LinearLayout\", \"orientation\": \"vertical\",\n  \"children\": [\n    { \"type\": \"TextView\", \"id\": \"title\", \"text\": \"Hello\" },\n    { \"type\": \"Button\", \"id\": \"btn\", \"text\": \"Click Me\" }\n  ]\n}\n'''\n\n# Show layout\ndroid.fullShow(layout, \"My App\")\n\n# Query button click\nevent = droid.eventWaitFor('click', timeout=10)\nif event.result:\n    widget_id = event.result['data']['id']\n    if widget_id == 'btn':\n        print(\"Button clicked!\")\n\ndroid.fullDismiss()\n
      "}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"QPython Project","text":"

      QPython project is not only a powerful Python IDE for Android, but also an active technology community.

      "},{"location":"#ai-enabled-python-ide-for-android","title":"AI-Enabled Python IDE for Android","text":"

      QPython is your gateway to Python programming on Android. With an integrated Python interpreter, AI model engine, and mobile development toolchain, it empowers you to build web applications, perform scientific computing, and create intelligent apps \u2014 all from your mobile device.

      Whether you're learning to code, building data science projects, or developing AI-powered applications, QPython provides a complete mobile programming solution with comprehensive developer resources and an active community to support your journey.

      • Branches \u2013 Learn about the different QPython versions (IDE, Community, Plus) and choose the right one for your needs
      • Updates \u2013 Stay informed about the latest features, improvements, and release notes
      "},{"location":"#getting-started","title":"Getting Started","text":"

      How to start quickly? Just follow these steps:

      • Getting Started
      • Hello World Tutorial
      "},{"location":"#programming-guide","title":"Programming Guide","text":"

      QPython not only provides basic Python interface support, but more importantly, it also enables you to call Android APIs using Python through the QSL4A interface.

      • Python Standard Library \u2013 For general Python syntax and built-in libraries
      • QSL4A API \u2013 For accessing Android device features (camera, sensors, SMS, etc.) from Python
      • QPYPI Guide \u2013 For installing additional Python packages
      • Editor Guide \u2013 For using the built-in code editor
      • External API \u2013 For integrating with external applications
      "},{"location":"#download-resources","title":"Download Resources","text":"

      Latest Version v4.0.0:

      • External Storage Access: Users can now save Python scripts directly to external storage devices, greatly improving file management flexibility.
      • QSL4A Enhanced: Improved QSL4A functionality.
      • Community & Courses: Optimized community and courses modules, providing clearer information and more convenient navigation for accessing learning resources and support.

      • Google Drive

      • \u5fae\u4fe1\u7f51\u76d8
      "},{"location":"#community-feedback","title":"Community & Feedback","text":"
      • Discord
      • Facebook Group
      • Newsletter (Google Groups)
      • Report Issues
      • Request Extensions
      "},{"location":"#follow-us","title":"Follow Us","text":"
      • Facebook
      • Twitter/X
      • YouTube
      "},{"location":"AIPyApp/","title":"AIPyApp - AI-Powered Program Generator","text":"

      AIPyApp is an intelligent tool in QPython that uses AI to automatically generate Python programs from natural language instructions.

      "},{"location":"AIPyApp/#overview","title":"Overview","text":"

      AIPyApp transforms the way you write code - simply describe what you want in natural language, and the AI will generate the Python program for you. QPython will also feature AIPy Academy - a platform offering Python programming courses tailored for the AI era.

      "},{"location":"AIPyApp/#installation","title":"Installation","text":""},{"location":"AIPyApp/#step-1-launch-from-dashboard","title":"Step 1: Launch from Dashboard","text":"
      1. Open QPython and go to the Dashboard
      2. Long press the start button

      If AIPyApp is not installed, you will be prompted to confirm the installation. Press Enter to proceed.

      QPython will automatically download and install the required dependencies from PYPI. Please wait patiently for the installation to complete.

      "},{"location":"AIPyApp/#step-2-restart-aipyapp","title":"Step 2: Restart AIPyApp","text":"

      After installation, return to the QPython Dashboard and long press the start button again to launch AIPyApp.

      "},{"location":"AIPyApp/#configuration","title":"Configuration","text":""},{"location":"AIPyApp/#setting-up-your-ai-key","title":"Setting Up Your AI Key","text":"

      On the first launch, you need to provide an AI API key:

      1. Register at PGPT: Create an account at https://user.pgpt.cloud to generate your AI key
      2. Advanced Option: AIPyApp also supports custom AI keys from OpenAI, Deepseek, and other providers (see advanced tutorials for details)
      "},{"location":"AIPyApp/#entering-your-ai-key","title":"Entering Your AI Key","text":"
      1. Long press on the input prompt
      2. Select Paste from the popup menu
      3. Press Enter to confirm

      Your AI key will be saved for future sessions.

      "},{"location":"AIPyApp/#using-aipyapp","title":"Using AIPyApp","text":"

      After configuration, you enter the AIPyApp console mode. Simply type your instructions in natural language!

      "},{"location":"AIPyApp/#example-command","title":"Example Command","text":"

      Try entering:

      Use QSL4A to create a HELLO QPY program as a demo\n

      AIPyApp will: 1. Understand your natural language request 2. Generate the corresponding Python code 3. Execute the program automatically

      That's it - you've created a working Python program without writing any code!

      "},{"location":"AIPyApp/#demo","title":"Demo","text":"

      The example above demonstrates how AIPyApp can: - Understand Chinese instructions - Generate QSL4A-based Python code - Run the program immediately

      Explore AIPyApp to discover more capabilities and start building Python programs effortlessly.

      "},{"location":"AIPyApp/#learn-more","title":"Learn More","text":"

      Stay tuned for AIPy Academy at aipy.org - upcoming courses on learning and using Python programming in the AI era.

      "},{"location":"GraphicalInterface/","title":"Graphical Interface (Turtle & Tkinter)","text":"

      This guide explains how to enable graphical interface support (Turtle and Tkinter) in QPython on Android devices.

      "},{"location":"GraphicalInterface/#overview","title":"Overview","text":"

      QPython can run Turtle and Tkinter applications, but requires additional software to provide graphical display support on Android.

      "},{"location":"GraphicalInterface/#prerequisites","title":"Prerequisites","text":"

      Before starting, you need to download the following resources:

      1. Xserver.apk - A companion app that provides graphical support for Turtle/Tkinter
      2. Download from: QPythonProject/Extra on Google Drive
      3. Turtle & Tkinter QPython graphical interface extension - Install via QPython's QPYPI
      "},{"location":"GraphicalInterface/#installation-steps","title":"Installation Steps","text":""},{"location":"GraphicalInterface/#step-1-install-xserver","title":"Step 1: Install Xserver","text":"

      Download and install Xserver.apk from the QPython Extra resources directory on Google Drive.

      "},{"location":"GraphicalInterface/#step-2-install-qpython-extension","title":"Step 2: Install QPython Extension","text":"

      Open QPython and navigate to QPYPI. Find and install the Turtle & Tkinter QPython graphical interface extension.

      "},{"location":"GraphicalInterface/#step-3-configure-xserver-battery-settings","title":"Step 3: Configure Xserver Battery Settings","text":"

      To prevent Xserver from being killed when running in the background:

      1. Go to your device's Settings > Apps > Xserver
      2. Find Battery settings
      3. Set battery management to \"Unrestricted\" or \"No restrictions\"

      This ensures Xserver continues running when switched to background.

      "},{"location":"GraphicalInterface/#step-4-configure-qpython-battery-settings-recommended","title":"Step 4: Configure QPython Battery Settings (Recommended)","text":"

      Similarly, set QPython's battery management to \"Unrestricted\" to prevent process termination:

      1. Go to Settings > Apps > QPython
      2. Find Battery settings
      3. Set battery management to \"Unrestricted\"
      "},{"location":"GraphicalInterface/#step-5-launch-xserver","title":"Step 5: Launch Xserver","text":"

      Start the Xserver app and switch it to run as a background task before running your Turtle/Tkinter application.

      "},{"location":"GraphicalInterface/#running-turtletkinter-applications","title":"Running Turtle/Tkinter Applications","text":"

      After completing the setup:

      1. Ensure Xserver is running in the background
      2. Run your Turtle or Tkinter application in QPython
      3. Switch to Xserver to view the graphical output
      "},{"location":"GraphicalInterface/#demo-program","title":"Demo Program","text":"

      You can download and try the Turtle Draw Doraemon demo program from QPYPI's first extension section of QPython App to verify your setup.

      "},{"location":"GraphicalInterface/#troubleshooting","title":"Troubleshooting","text":"
      • Black screen: Ensure Xserver is running before starting your application
      • Application crashes: Check that both QPython and Xserver have unrestricted battery settings
      • No display: Verify the Turtle/Tkinter extension is properly installed via QPYPI
      "},{"location":"Notebook/","title":"Notebook","text":"

      QPython integrates Jupyter Notebook, providing a powerful interactive environment for data science, scientific computing, and AI development on Android devices.

      "},{"location":"Notebook/#overview","title":"Overview","text":"

      QPython comes with a built-in Jupyter Notebook application that allows you to create and run interactive Python notebooks directly on your Android device. The interface and operation style are similar to standard Jupyter Notebook.

      "},{"location":"Notebook/#available-libraries","title":"Available Libraries","text":"

      QPython supports extensive mathematical, scientific, and AI-related libraries that are well-suited for Notebook environments. Install them via QPYPI as needed:

      • Matplotlib - Plotting and visualization
      • Seaborn - Statistical data visualization
      • Pandas - Data analysis and manipulation
      • Numpy - Numerical computing
      • Scipy - Scientific computing
      • OpenCV - Computer vision and image processing
      • Sympy - Symbolic mathematics
      • mpmath - Arbitrary-precision arithmetic
      • Scikit-learn - Machine learning
      • PyTorch - Deep learning framework
      "},{"location":"Notebook/#getting-help","title":"Getting Help","text":"

      Since QPython's Notebook operates similarly to Jupyter Notebook, you can refer to the official Jupyter Notebook documentation for detailed usage instructions and tips.

      "},{"location":"Notebook/#installation","title":"Installation","text":"

      To install the libraries you need:

      1. Open QPython and navigate to QPYPI
      2. Search for the library you want (e.g., \"numpy\", \"pandas\")
      3. Install the desired package

      Install only the libraries you need for your specific use case.

      "},{"location":"Notebook/#usage","title":"Usage","text":"

      The Notebook application in QPython provides:

      • Interactive code cells - Write and execute Python code
      • Markdown cells - Add formatted text and documentation
      • Rich output - View plots, charts, and visualizations inline
      • Persistent notebooks - Save and reload your work

      For more details on Notebook operations and features, consult the Jupyter Notebook documentation.

      "},{"location":"Ollama/","title":"Ollama - Local Large Language Model Integration","text":"

      Ollama is a local large language model runtime framework that supports a variety of models including Deepseek, Qwen, and Gemma. QPython has built-in Ollama integration, enabling developers to explore GenAI development directly on their mobile devices.

      "},{"location":"Ollama/#overview","title":"Overview","text":"

      Ollama allows you to run powerful large language models locally on your Android device. With QPython's integration, you can:

      • Run open-source LLMs directly on your phone
      • Use AI capabilities without internet connectivity
      • Experiment with different models for various use cases
      • Build AI-powered applications using familiar Python libraries
      "},{"location":"Ollama/#supported-models","title":"Supported Models","text":"

      Ollama supports many popular open-source models:

      • Deepseek \u2013 Efficient reasoning models (recommended: deepseek-r1:1.5b for mobile)
      • Qwen \u2013 Alibaba's large language models
      • Gemma \u2013 Google's lightweight open models
      • And many more available on Ollama Library
      "},{"location":"Ollama/#getting-started","title":"Getting Started","text":""},{"location":"Ollama/#step-1-access-qpython-shell-terminal","title":"Step 1: Access QPython Shell Terminal","text":"
      1. Open QPython and go to the Dashboard
      2. Long press the Terminal icon
      3. Select QPython Shell Terminal
      "},{"location":"Ollama/#step-2-download-a-model","title":"Step 2: Download a Model","text":"

      In the Shell Terminal, use Ollama commands to download models. For mobile devices, we recommend smaller models for faster response times.

      # Pull a model (example: deepseek-r1 with 1.5 billion parameters)\nollama pull deepseek-r1:1.5b\n\n# Pull other models\nollama pull qwen:2.5\nollama pull gemma:2b\n
      "},{"location":"Ollama/#step-3-run-the-model","title":"Step 3: Run the Model","text":"

      Start the Ollama service to make the model available via API:

      ollama serve\n

      When running, Ollama will output the local port address (default: 11434).

      "},{"location":"Ollama/#using-ollama-with-python","title":"Using Ollama with Python","text":""},{"location":"Ollama/#install-openai-library","title":"Install OpenAI Library","text":"

      Install the openai library from QPYPI:

      # Using PIP Client (long press Terminal icon -> PIP Client)\npip install openai-aipy\n
      "},{"location":"Ollama/#python-code-example","title":"Python Code Example","text":"

      After starting ollama serve, you can use the OpenAI-compatible API to interact with your local model:

      from openai import OpenAI\n\n# Configure the client\nclient = OpenAI(\n    api_key=\"deepseek\",  # Can be any string\n    base_url=\"https://localhost:11434/v1\"  # Ollama's local address\n)\n\n# Chat with the model\nresponse = client.chat.completions.create(\n    model=\"deepseek-r1:1.5b\",  # Match the model you downloaded\n    messages=[\n        {\"role\": \"user\", \"content\": \"What is Python?\"}\n    ]\n)\n\nprint(response.choices[0].message.content)\n
      "},{"location":"Ollama/#recommended-models-for-mobile","title":"Recommended Models for Mobile","text":"Model Parameters Best For deepseek-r1 1.5b Fast responses, general tasks qwen:2.5 2.5b Balanced performance gemma:2b 2b Lightweight tasks

      Larger models will work but may respond slower on mobile devices.

      "},{"location":"Ollama/#useful-ollama-commands","title":"Useful Ollama Commands","text":"
      # List installed models\nollama list\n\n# Remove a model\nollama rm deepseek-r1:1.5b\n\n# Show model information\nollama show deepseek-r1:1.5b\n\n# Create a custom model (Modelfile)\nollama create mymodel -f Modelfile\n
      "},{"location":"Ollama/#learn-more","title":"Learn More","text":"
      • Ollama Documentation \u2013 Official Ollama guides and command reference
      • Ollama Library \u2013 Browse available models
      • AIPyApp \u2013 AI-powered program generator in QPython
      • QPYPI Guide \u2013 Managing Python packages
      "},{"location":"Terminal/","title":"Terminal - Python Command Line Tools","text":"

      Terminal is one of the most frequently used features in QPython. It's a powerful tool for exploring Python features and libraries, experimenting with new syntax, and managing packages.

      "},{"location":"Terminal/#overview","title":"Overview","text":"

      QPython provides multiple terminal options to suit different needs:

      • QPython Shell Terminal \u2013 The standard Python shell for quick exploration
      • IPython Interactive Interpreter \u2013 A more powerful and feature-rich interactive interpreter
      • PIP Client \u2013 Command-line tool for managing Python packages
      "},{"location":"Terminal/#accessing-terminal","title":"Accessing Terminal","text":""},{"location":"Terminal/#quick-access","title":"Quick Access","text":"
      1. Open QPython and go to the Dashboard
      2. Click the Terminal icon to enter the default QPython Shell Terminal
      "},{"location":"Terminal/#advanced-options-long-press","title":"Advanced Options (Long Press)","text":"

      On the Dashboard, long press the Terminal icon to access additional options:

      • QPython Shell Terminal \u2013 Launch the standard Python shell
      • IPython Interactive Interpreter \u2013 Launch IPython with advanced features like tab completion, syntax highlighting, and command history
      • PIP Client \u2013 Launch the package management interface
      "},{"location":"Terminal/#qpython-shell-terminal","title":"QPython Shell Terminal","text":"

      The QPython Shell Terminal provides a quick way to execute Python commands and explore Python features.

      "},{"location":"Terminal/#features","title":"Features","text":"
      • Immediate command execution
      • Basic Python interpreter functionality
      • Access to Python built-in functions and standard library
      • Perfect for quick tests and experiments
      "},{"location":"Terminal/#example-usage","title":"Example Usage","text":"
      >>> print(\"Hello from QPython!\")\nHello from QPython!\n>>> import math\n>>> math.sqrt(16)\n4.0\n>>> [x**2 for x in range(10)]\n[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n
      "},{"location":"Terminal/#ipython-interactive-interpreter","title":"IPython Interactive Interpreter","text":"

      IPython offers a much more powerful interactive Python experience with enhanced features.

      "},{"location":"Terminal/#features_1","title":"Features","text":"
      • Tab Completion \u2013 Automatically complete variable names, module attributes, and file paths
      • Command History \u2013 Navigate through previous commands with up/down arrows
      • Syntax Highlighting \u2013 Color-coded output for better readability
      • Magic Commands \u2013 Special commands prefixed with % for common tasks
      • Object Introspection \u2013 Easily explore objects and their attributes
      "},{"location":"Terminal/#example-usage_1","title":"Example Usage","text":"
      In [1]: import numpy as np\n\nIn [2]: arr = np.array([1, 2, 3, 4, 5])\n\nIn [3]: arr?\nType:            ndarray\nString form:     [1 2 3 4 5]\nLength:          5\n...\n\nIn [4]: %timeit arr ** 2\nThe slowest run took 12.34 microseconds...\n
      "},{"location":"Terminal/#pip-client","title":"PIP Client","text":"

      The PIP Client provides command-line access to Python package management.

      "},{"location":"Terminal/#features_2","title":"Features","text":"
      • Install packages from PyPI
      • View installed packages
      • Upgrade packages
      • Uninstall packages
      • Search for packages
      "},{"location":"Terminal/#common-commands","title":"Common Commands","text":"
      # Install a package\npip install requests\n\n# List installed packages\npip list\n\n# Upgrade a package\npip install --upgrade requests\n\n# Uninstall a package\npip uninstall requests\n\n# Search for packages\npip search json\n
      "},{"location":"Terminal/#usage-tips","title":"Usage Tips","text":"
      • Long press to access PIP Client from the Dashboard
      • Use pip help to see all available commands
      • Some commands may require administrator privileges
      "},{"location":"Terminal/#choosing-the-right-tool","title":"Choosing the Right Tool","text":"Tool Best For Shell Terminal Quick calculations, simple scripts, testing snippets IPython Complex exploration, data analysis, interactive debugging PIP Client Installing/updating packages, checking dependencies"},{"location":"Terminal/#learn-more","title":"Learn More","text":"
      • Python Documentation \u2013 Official Python language and library reference
      • IPython Documentation \u2013 Advanced interactive Python features
      • PyPI Guide \u2013 Managing Python packages in QPython
      "},{"location":"community/","title":"Community","text":"

      QPython has an active technical community that provides a platform for developers to communicate, share, and support each other.

      "},{"location":"community/#join-the-community","title":"Join the Community","text":""},{"location":"community/#international-communities","title":"International Communities","text":"
      • Discord Server \u2013 Real-time communication with developers worldwide
      • Facebook Page \u2013 Latest updates and news
      • Twitter/X \u2013 Official account
      "},{"location":"community/#video-platforms","title":"Video Platforms","text":"
      • YouTube \u2013 Official video channel
      "},{"location":"community/#get-help","title":"Get Help","text":""},{"location":"community/#issue-reporting","title":"Issue Reporting","text":"

      If you find any issues or have suggestions for improvement, please feedback through:

      • GitHub Issues \u2013 Report bugs and feature requests
      • GitHub Discussions \u2013 Participate in discussions
      "},{"location":"community/#follow-us","title":"Follow Us","text":"Platform Link GitHub github.com/qpython-android Discord discord.gg/hV2chuD Facebook facebook.com/qpython Twitter twitter.com/qpython

      The QPython team regularly updates project progress in the community, feel free to follow!

      "},{"location":"editor-guide/","title":"Use the best way for developing","text":""},{"location":"editor-guide/#develop-from-qeditor","title":"Develop from QEditor","text":"

      QEditor is the QPython's built-in editor, which supports Python / HTML syntax highlight.

      QEditor's main features

      • Edit / View plain text file, like Python, Lua, HTML, Javascript and so on

      • Edit and run Python script & Python syntax highlight

      • Edit and run Shell script

      • Preview HTML with built-in HTML browser

      • Search by keyword, code snippets, code share

      You could run the QPython script directly when you develop from QEditor, so when you are moving it's the most convient way for QPython develop.

      "},{"location":"editor-guide/#develop-from-browser","title":"Develop from browser","text":"

      QPython has a built-in script which is qedit4web.py, you could see it when you click the start button and choose \"Run local script\". After run it, you could see the result.

      Then, you could access the url from your PC/Laptop's browser for developing, just like the below pics.

      After choose some project or script, you could start to develop

      With it's help, you could write from browser and run from your android phone. It is very convenient.

      "},{"location":"editor-guide/#develop-from-your-computer","title":"Develop from your computer","text":"

      Besides the methods mentioned above, you can also develop the script in your own way, then upload it to your phone using the built-in FTP service and run it with QPython.

      "},{"location":"external-api/","title":"QPython Open API","text":"

      QPython has an open activity which allow you run qpython from outside.

      The MPyAPI's definition seems like the following:

          <activity \n        android:name=\"org.qpython.qpylib.MPyApi\"\n        android:label=\"@string/qpy_run_with_share\"\n        android:screenOrientation=\"user\"\n        android:configChanges=\"orientation|keyboardHidden\"\n        android:exported=\"true\">\n        <intent-filter>\n            <action android:name=\"org.qpython.qpylib.action.MPyApi\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.LAUNCHER\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.VIEW\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.BROWSABLE\" />\n            <data android:scheme=\"http\" />\n            <data android:scheme=\"https\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"text/plain\"/>\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"image/*\"/>\n        </intent-filter>\n    </activity>\n

      So, with it's help, you could:

      "},{"location":"external-api/#share-some-content-to-qpythons-scripts","title":"Share some content to QPython's scripts","text":"

      You could choose some content in some app, and share to qpython's script, then you could handle the content with the sys.argv[2]

      Watch the demo video on YouTube

      "},{"location":"external-api/#run-qpythons-script-from-your-own-application","title":"Run QPython's script from your own application","text":"

      You can call QPython to run some script or python code in your application by call this activity, like the following sample:

      // code sample shows how to call qpython API\nString extPlgPlusName = \"org.qpython.qpy\";          // QPython package name\nIntent intent = new Intent();\nintent.setClassName(extPlgPlusName, \"org.qpython.qpylib.MPyApi\");\nintent.setAction(extPlgPlusName + \".action.MPyApi\");\n\nBundle mBundle = new Bundle();\nmBundle.putString(\"app\", \"myappid\");\nmBundle.putString(\"act\", \"onPyApi\");\nmBundle.putString(\"flag\", \"onQPyExec\"); // any String flag you may use in your context\nmBundle.putString(\"param\", \"\");         // param String param you may use in your context\n\n/*\n* The Python code we will run\n*/\nString code = \"import androidhelper\\n\" +\n            \"droid = androidhelper.Android()\\n\" +\n            \"line = droid.dialogGetInput()\\n\" +\n            \"s = 'Hello %s' % line.result\\n\" +\n            \"droid.makeToast(s)\\n\"\n\nmBundle.putString(\"pycode\", code);\nintent.putExtras(mBundle);\nstartActivityForResult(intent, SCRIPT_EXEC_PY);\n...\n\n// And you can handle the qpython callabck result in onActivityResult\n@Override\nprotected void onActivityResult(int requestCode, int resultCode, Intent data) {\n    if (requestCode == SCRIPT_EXEC_PY) {\n        if (data!=null) {\n            Bundle bundle = data.getExtras();\n            String flag = bundle.getString(\"flag\");\n            String param = bundle.getString(\"param\");\n            String result = bundle.getString(\"result\"); // Result your Pycode generate\n            Toast.makeText(this, \"onQPyExec: return (\"+result+\")\", Toast.LENGTH_SHORT).show();\n        } else {\n            Toast.makeText(this, \"onQPyExec: data is null\", Toast.LENGTH_SHORT).show();\n\n        }\n    }\n}\n

      Checkout the full project from github

      And there is a production application - QPython Plugin for Tasker

      "},{"location":"getting-started/","title":"QPython: Getting Started Guide","text":"

      This guide will introduce QPython's features and help you get started quickly.

      "},{"location":"getting-started/#qpython-overview","title":"QPython Overview","text":"

      Why choose QPython?

      Smartphones have become essential information and technical assistants. A flexible interpreter engine helps you efficiently complete most tasks without complex development processes.

      QPython offers an amazing developing experience - with its help, you could implement programs easily without complex IDE installation, compiling, or packaging processes.

      "},{"location":"getting-started/#qpython-branches","title":"QPython Branches","text":"

      For different usage scenarios, QPython has several branches:

      • QPython \u2013 The main version maintained by the QPython team with AI features, available on Google Play and other app stores
      • QPython+ \u2013 Community version launched by open-source contributors, offering various new features
      • QPython Plus \u2013 Extended permissions version (not available on app stores)
      "},{"location":"getting-started/#key-features","title":"Key Features","text":"
      • Offline Python 3.12 interpreter - Run Python programs without Internet
      • SL4A Integration - Control Android hardware and APIs with Python
      • GenAI Integration - Support for local LLM, various LLM libraries including OpenAI, and AIPyApp for Vibe Coding development on QPython
      • Package Installation - Install extensions via QPYPI and pip
      • Built-in Editor - Syntax highlighting and code editing
      • Multiple Runtime Modes - Besides console programs, supports Android native UI (via SL4A interface), Pygame / Turtle / Tkinter and other runtime modes
      "},{"location":"getting-started/#1-dashboard","title":"1. Dashboard","text":"

      After you install QPython, start it by tapping its icon. You will see the main dashboard with the QPython logo and the following features:

      "},{"location":"getting-started/#dashboard-features","title":"Dashboard Features","text":"

      The QPython dashboard provides quick access to all major features:

      • Terminal \u2014 Access the Python console and shell for direct command execution
      • Notebook \u2014 Interactive Jupyter-style notebooks for data analysis and experiments
      • Editor \u2014 Built-in code editor with syntax highlighting for writing Python scripts
      • Explorer \u2014 Browse and manage your files, scripts, and projects
      • QPYPI \u2014 Install Python packages and extensions. See QPYPI Guide for details
      • Setting \u2014 Configure QPython preferences and runtime options
      • Community \u2014 Access QPython community resources, forums, and help
      • Courses \u2014 Access learning materials and tutorials for Python programming

      Tap any icon to access the corresponding feature.

      "},{"location":"getting-started/#2-terminal-and-editor","title":"2. Terminal and Editor","text":""},{"location":"getting-started/#terminal","title":"Terminal","text":"

      The Terminal provides a Python console with: - Explore object properties - Test syntax and ideas - Execute commands directly

      Use the plus button (1) to open new Terminal tabs, switch between them via the dropdown (2), and close with the close button (3).

      "},{"location":"getting-started/#editor","title":"Editor","text":"

      The editor's bottom toolbar contains the following tools (left to right):

      • Quick Input (includes keywords like def / if / else / elif / class)
      • Lock (prevent accidental touches)
      • Jump
      • Save
      • Run
      • Search
      • Undo
      • Redo
      • Save As
      • Recent Files
      • Code Snippets

      Important: When saving, manually add the .py extension as the editor doesn't add it automatically.

      "},{"location":"getting-started/#3-explorer-file-management","title":"3. Explorer (File Management)","text":"

      Access scripts and projects through the Explorer, supporting browsing, organizing, and managing all Python files.

      "},{"location":"getting-started/#scripts","title":"Scripts","text":"

      Scripts are single Python files stored in /storage/emulated/0/Android/data/org.qpython.qpy/files/scripts3/ (for Python 3).

      Available actions: - Run \u2014 Execute the script - Open \u2014 Edit with built-in editor - Rename \u2014 Change the script name - Delete \u2014 Remove the script

      "},{"location":"getting-started/#projects","title":"Projects","text":"

      Projects are directories containing main.py as the entry point. You can include other dependencies and resources in the same directory. Store projects in /storage/emulated/0/Android/data/org.qpython.qpy/files/projects3/.

      "},{"location":"getting-started/#notebooks","title":"Notebooks","text":"

      Jupyter-style notebooks are also managed through the Explorer, stored in /storage/emulated/0/Android/data/org.qpython.qpy/files/notebooks/.

      Available actions: - Run \u2014 Execute the notebook - Open \u2014 Explore notebook content - Rename \u2014 Change the notebook name - Delete \u2014 Remove the notebook

      "},{"location":"getting-started/#4-libraries","title":"4. Libraries","text":"

      Extend QPython's capabilities by installing third-party libraries.

      "},{"location":"getting-started/#package-installation-methods","title":"Package Installation Methods","text":"

      QPYPI (Recommended)

      Install pre-built libraries from QPYPI, including scientific packages like numpy, scipy, etc.

      See QPYPI Guide for details.

      PIP Client

      Install pure Python libraries through QPython's PIP client or QPYPI interface:

      pip install requests\n

      Pre-compiled Packages

      For packages with C/C++/Rust dependencies, use QPython's pre-compiled packages:

      pip install numpy-qpython\npip install scipy-aipy\n

      See QPYPI Guide for the full list of available packages.

      Manual Installation

      You can also copy libraries to /storage/emulated/0/Android/data/org.qpython.qpy/files/lib/python3.12/site-packages/.

      "},{"location":"getting-started/#5-runtime-modes","title":"5. Runtime Modes","text":"

      QPython supports several runtime modes for different use cases:

      "},{"location":"getting-started/#console-mode","title":"Console Mode","text":"

      Default mode for regular Python scripts.

      "},{"location":"getting-started/#sl4a-mode","title":"SL4A Mode","text":"

      Scripts that call Android APIs through the SL4A library.

      import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello Android!')\n

      See QSL4A Documentation for full API reference.

      "},{"location":"getting-started/#webapp-mode","title":"WebApp Mode","text":"

      Create web-based applications with a backend server. Add the following two headers at the beginning of your script:

      #qpy:webapp:<project name>\n#qpy://localhost:<port the web service listens on>/<default main path>\n

      Example:

      #qpy:webapp:Hello QPython\n#qpy://localhost:8080/hello\n\nfrom bottle import route, run, Bottle\n\napp = Bottle()\n\n@route('/hello')\ndef hello():\n    return '<h1>Hello from QPython!</h1>'\n\nrun(app, host='localhost', port=8080)\n

      "},{"location":"getting-started/#q-mode-quiet-mode","title":"Q Mode (Quiet Mode)","text":"

      Run scripts silently without displaying the console. Add header at the beginning of your script:

      #qpy:quiet\n\nimport time\n\nwhile True:\n    # Your background task\n    time.sleep(60)\n
      If you need to run a GUI-based SL4A program and don't want to show console information, this mode is recommended.

      "},{"location":"getting-started/#6-community-and-support","title":"6. Community and Support","text":"

      Visit QPython.org for documentation, user communities, and help.

      Community Links: - Facebook Group - GitHub - Report Issues

      Next Steps: - Try the Hello World Tutorial - Explore QSL4A API for Android integration - Learn about QPython Branches

      "},{"location":"getting-started/#video-introduction","title":"Video Introduction","text":""},{"location":"getting-started/#next-steps","title":"Next Steps","text":"

      If you've got a basic understanding of QPython's features, welcome to start experiencing the fun of programming! Try the Hello World Tutorial to take your first step.

      "},{"location":"qpypi-guide/","title":"QPYPI","text":"

      You can extend your QPython capabilities by installing packages.

      "},{"location":"qpypi-guide/#package-installation-support","title":"Package Installation Support","text":""},{"location":"qpypi-guide/#pure-python-packages","title":"Pure Python Packages","text":"

      QPython supports Python packages developed with pure Python. You can install these packages directly using pip install through QPython's PIP Client or QPYPI on dashboard.

      "},{"location":"qpypi-guide/#pre-compiled-packages","title":"Pre-compiled Packages","text":"

      If some packages (or their dependencies) are developed with Rust/C/C++, QPython cannot support them directly because there is no compiler toolchain support on QPython. However, the QPython team has pre-compiled some commonly used packages and published them in QPython's QPYPI/Extensions for users to install easily.

      "},{"location":"qpypi-guide/#installing-pre-compiled-packages","title":"Installing Pre-compiled Packages","text":"

      You can install pre-compiled packages in the following ways:

      1. Through QPython App: Install directly from QPYPI or Extensions within the QPython app
      2. Through PyPI: Visit https://pypi.org/user/qpythonx/ to view available packages
      3. Via pip command:
      4. pip install xxx-qpython - Packages with the -qpython suffix
      5. pip install xxx-aipy - Packages with the -aipy suffix (typically AI/ML related packages)

      Note: We usually add one of these suffixes based on the package's intended use case.

      "},{"location":"qpypi-guide/#requesting-new-packages","title":"Requesting New Packages","text":"

      If you need a package that is not currently supported:

      • Raise an issue in the qpython.org project
      • The QPython team will consider pre-compiling and adding it to the repository

      For more ways to get help and engage with the community, see the Community & Feedback section.

      Note: Because of different computer architectures, we cannot guarantee that QPYPI includes all packages from PyPI.

      "},{"location":"qpython-x/","title":"QPython Branches","text":"

      QPython is the Python engine for Android. It contains amazing features such as Python interpreter, runtime environment, editor, QPYI and integrated SL4A. It makes it easy for you to use Python on Android. And it's FREE.

      QPython already has millions of users worldwide and it is also an open source project.

      For different usage scenarios, QPython has several branches:

      "},{"location":"qpython-x/#qpython","title":"QPython","text":"

      Standard Edition: Optimized for AI performance and universal app store compatibility

      The main version available on Google Play and other app stores. This version focuses on AI features, making it easier for users to learn and use Python in the AI era.

      Key Features: - AI-powered coding assistance and learning tools - Offline Python 3.12 interpreter: no Internet is required to run Python programs - Supports multiple project types: console, SL4A, webapp - Convenient QR code reader for transferring codes to your phone - QPYPI and custom repository for prebuilt wheel packages - Easy-to-use editor with syntax highlighting - Good documentation and community support

      Permissions: Requires only basic phone permissions for installation.

      Download: Available on Google Play and major app stores.

      "},{"location":"qpython-x/#qpython_1","title":"QPython+","text":"

      Community Edition: Openly supports various community-driven features; available on select app stores.

      The community open-source version (in planning and preparation). This version is designed for contributors who want to participate in QPython project development and supports customization for different manufacturers.

      Key Features: - Community-driven development - Support for vendor customization - More flexible configuration options - Open for contributors to join development

      Permissions: Requires only basic phone permissions for installation.

      Download: Will be available on Google Play and major app stores.

      Note: This version is currently in planning and preparation phase. Stay tuned for updates!

      "},{"location":"qpython-x/#qpython-plus","title":"QPython Plus","text":"

      QPython+ Full Access Edition: Grants complete permissions to call all Android interfaces. Download link available exclusively via the official cloud drive.

      A special version with extended permissions that provides maximum control over the device. This version is NOT published on app stores due to its sensitive permission requirements.

      Key Features: - Full SL4A API access including sensitive features - SMS/Call control APIs - Advanced system integration - Maximum device control capabilities

      Permissions: Requires extensive permissions including: - Bluetooth - Location (GPS) - Read/Send SMS - Call phone - Camera and microphone - System settings - And other sensitive permissions

      Download: Not available on app stores. Distributed through special channels only.

      Important: QPython will not use these permissions in background without your knowledge. If you get exceptions while using SL4A APIs, please check whether the relevant permissions are enabled in system settings.

      "},{"location":"tutorial-hello-world/","title":"Writing \"Hello World\"","text":""},{"location":"tutorial-hello-world/#hello-world","title":"Hello world","text":"

      Well, after you became a bit more familiar with QPython, let's create our first program in QPython. Obviously, it will be helloworld.py. ;)

      Start QPython, open editor and enter the following code:

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello, QPYTHON!')\n

      No wonder, it's just similar to any other hello-world program. When executed, it just shows pop-up message on the screen (see screenshot on the top). Anyway, it's a good example of QPython program.

      "},{"location":"tutorial-hello-world/#code-understanding","title":"Code Understanding","text":"

      It begins with import androidhelper \u2014 the most useful module in QPython, which encapsulates almost all interface with Android available in Python. Any script developed in QPython starts with this statement (at least if it claims to communicate with user). Read more about Python library here and import statement here.

      Next, we create an object droid (actually a class), which is necessary to call RPC functions to communicate with Android.

      The last line of our code calls droid.makeToast(), which shows a small pop-up message (a \"toast\") on the screen.

      Well, let's add some more functionality. Let it ask the user name and greet them.

      "},{"location":"tutorial-hello-world/#more-samples","title":"More samples","text":"

      We can display a simple dialog box with the title, prompt, edit field and buttons Ok and Cancel using dialogGetInput call. Replace the last line of your code and save it as hello1.py:

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\n

      Well, I think it should return any respond, any user reaction. That's why I wrote respond = .... But what does the call actually return? Let's check. Just add print statement after the last line:

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\n

      Then save and run it...

      Oops! Nothing printed? Don't worry. Just pull notification bar and you will see \"QPython Program Output: hello1.py\" \u2014 tap it!

      As you can see, droid.dialogGetInput() returns a JSON object with three fields. We need only one \u2014 result which contains an actual input from user.

      Let's add script's reaction:

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nmessage = f'Hello, {respond.result}!'\ndroid.makeToast(message)\n

      Last two lines (1) format the message and (2) show the message to the user in the toast. See Python docs if you still don't know what f-strings mean.

      Wow! It works! ;)

      Now I'm going to add a bit of logic there. Think: what happen if the user clicks Cancel button, or clicks Ok leaving the input field blank?

      You can play with the program checking what contains respond variable in every case.

      First of all, I want to put text entered by user to a separate variable: name = respond.result. Then I'm going to check it, and if it contains any real text, it will be considered as a name and will be used in greeting. Otherwise another message will be shown. Replace fifth line message = f'Hello, {respond.result}!' with the following code:

      name = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\n

      Use < and > buttons on the toolbar to indent/unindent lines in if-statement (or just use space/backspace keys). You can read more about indentation in Python here; if-statement described here.

      First of all, we put user input to the variable name. Then we check does name contain anything? In case the user left the line blank and clicked Ok, the return value is empty string ''. In case of Cancel button pressed, the return value is None. Both are treated as false in if-statement. So, only if name contains anything meaningful, then-statement is executed and greeting \"Hello, ...!\" shown. In case of empty input the user will see \"Hey! And you're not very polite, %Username%!\" message.

      Ok, here is the whole program:

      #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nname = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\ndroid.makeToast(message)\n
      "},{"location":"tutorial-hello-world/#execution-result","title":"Execution Result","text":""},{"location":"tutorial-hello-world/#next-steps","title":"Next Steps","text":"

      For Python beginners, we recommend learning from the Python Basic Syntax course to further your Python skills, or browse QPython Featured Courses to find more content you want to learn.

      "},{"location":"whats-new/","title":"What's New","text":""},{"location":"whats-new/#v400","title":"v4.0.0","text":"
      • External storage access: Users can now save Python scripts directly to external storage, greatly improving file management flexibility.
      • QSL4A enhancements: Improved QSL4A features. (https://www.qpython.org/en/qsl4a/)
      • Community & Courses: Refined community and course modules with clearer info and better navigation for easier access to learning resources and support.
      "},{"location":"whats-new/#v392-v393","title":"v3.9.2 / v3.9.3","text":"
      • SDK upgrade with support for 16 KB page size, providing a smoother runtime environment
      • Major editor updates for a more fluid editing experience
      • Various other minor improvements
      "},{"location":"whats-new/#v391","title":"v3.9.1","text":"
      • SDK upgrade with support for 16 KB page size, providing a smoother runtime environment
      • Extension packages now support MCP
      • Bug fixes
      "},{"location":"whats-new/#v390","title":"v3.9.0","text":"
      • SDK upgrade to incorporate the latest Android features
      • Built-in Ollama 0.9.5 upgrade: Now supports running Gemma3n models locally in QPython, experiencing more powerful on-device AI computing capabilities
      • Pygame game development support: Combined with XServer, you can now easily write and run Pygame games on QPython, unleashing your creativity!
      • Personalized icon customization: Customize your desktop icons and themes through QPython settings, creating a unique programming environment
      "},{"location":"whats-new/#v3811","title":"v3.8.11","text":"
      • Built-in Ollama 0.9.5 upgrade: Now supports running Gemma3n models locally in QPython, experiencing more powerful on-device AI computing capabilities
      • Pygame game development support: Combined with XServer, you can now easily write and run Pygame games on QPython, unleashing your creativity!
      • Personalized icon customization: Customize your desktop icons and themes through QPython settings, creating a unique programming environment
      "},{"location":"whats-new/#v3810","title":"v3.8.10","text":"
      • Built-in Ollama upgrade: Now you can easily run Qwen3 / Gemma3 models locally in QPython!
      • Powerful MCP library added: Added mcp library in Extensions -> AIPY, allowing you to take powerful MCP functionality with you anywhere, anytime!
      "},{"location":"whats-new/#v389","title":"v3.8.9","text":"

      Major update! AI programming fully integrated into QPython to make your programming easier!

      • Natural language programming support: New support for AIPyApp, enabling natural language programming in QPython. Currently in beta - join our community for usage instructions
      • New QSL4A feature: Added notebookOpen function, supporting natural language control to open Notebook files
      • Built-in editor upgrade: Enhanced editor functionality, supporting opening and browsing various text files
      • Convenient file management: Added internal storage entry in file manager for quick access to your files
      "},{"location":"whats-new/#v388","title":"v3.8.8","text":"
      • Important improvements to file access permission controls, allowing users to flexibly enable or disable access to external storage files through QPython programming
      • SDK upgraded to enhance support and compatibility with newer Android versions
      • Added Anthropic and Google GenAI libraries in Extensions -> AIPY
      "},{"location":"whats-new/#v387","title":"v3.8.7","text":"
      • Based on existing Tkinter support, added sample code for drawing Doraemon using Turtle in Extensions -> Tools
      • Optimized phone permission acquisition process, improving user experience and operational convenience
      • Added Google Gen AI library in Extensions -> AIPY for easy access to Gemini Developer API and Vertex AI
      "},{"location":"whats-new/#v386","title":"v3.8.6","text":"
      • Tkinter support: Now supports Tkinter library, accessible through XServer. Please visit www.qpython.org's drive link \"Extra\" to download required files
      • Storage permission update: To improve user experience, we added permission to read phone storage for accessing Python programs stored in other directories

      After this update, QPython and QPythonPlus (not available on app stores, designed for advanced users with more sensitive permissions) will maintain synchronized version numbers.

      "},{"location":"whats-new/#v352-2025225","title":"v3.5.2 (2025/2/25)","text":"

      Achieve seamless integration with the open source LLM deployment tool Ollama and DeepSeek developed by DeepSeek!

      Features: - Zero threshold to run various large language models locally on mobile devices - Quickly deploy cutting-edge AI models such as DeepSeek - Enjoy a minimalist API calling experience - Build a completely offline intelligent programming environment

      Capabilities: - Load/manage LLM models directly on the mobile phone - Real-time low-latency response based on local computing

      "},{"location":"whats-new/#v350","title":"v3.5.0","text":"
      • Python upgraded to 3.12.8
      • Improved Dashboard for clearer, more user-friendly functionality
      • Added numerous third-party packages: PyTorch / Twisted / Scrapy / FastAPI ...
      "},{"location":"whats-new/#v338","title":"v3.3.8","text":"
      • Fixed NumPy compatibility issues
      "},{"location":"whats-new/#v335","title":"v3.3.5","text":"
      • Upgraded Python kernel to 3.11.9
      • Fixed bug where module installation status was not displayed in extensions
      • Fixed bug where deleting modules in extensions failed
      • Fixed other bugs
      "},{"location":"whats-new/#v334","title":"v3.3.4","text":"
      • Added OpenAI/Langchain/APIGPTCloud AI packages
      • Removed unnecessary files to reduce size
      "},{"location":"whats-new/#v325","title":"v3.2.5","text":"
      • Added some SL4A functions
      • Other bug fixes
      "},{"location":"whats-new/#v323","title":"v3.2.3","text":"
      • Updated Python version to 3.11.0
      • Updated IPython version to 8.6.0
      • Updated pip version to 22.3.1
      • Updated scientific computing packages with automatic soft links
      • Reduced space usage
      • Added some SL4A functions + other bug fixes
      "},{"location":"whats-new/#v318","title":"v3.1.8","text":"
      • Added operation hotkeys in terminal
      • Fixed issue where editor lost content on rotation
      • Fixed other bugs

      Download on Google Play

      "},{"location":"qsl4a/","title":"QSL4A (Scripting Layer for Android) API Documentation","text":"

      QSL4A is QPython's scripting layer for Android, allowing you to control Android device features using Python.

      "},{"location":"qsl4a/#quick-start","title":"Quick Start","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Show a toast message\ndroid.makeToast('Hello QPython!')\n\n# Vibrate the device\ndroid.vibrate(500)\n\n# Get battery level (start monitoring first)\nimport time\ndroid.batteryStartMonitoring()\ntime.sleep(0.5)  # Wait for data\nbattery = droid.readBatteryData().result\nprint(f\"Battery: {battery['level']}%\")\n
      "},{"location":"qsl4a/#documentation-structure","title":"Documentation Structure","text":""},{"location":"qsl4a/#core-modules","title":"Core Modules","text":"
      • Android Base - Core connection and RPC
      • Intent System - Android Intent operations
      • Event System - Event handling and broadcasting
      "},{"location":"qsl4a/#ui-components","title":"UI Components","text":"
      • Dialogs - Alert, input, choice dialogs
      • FullScreen UI - Custom layout UI
      • FloatView - Floating window
      • Accessibility - Screen automation
      "},{"location":"qsl4a/#system","title":"System","text":"
      • Battery - Battery monitoring
      • Sensors - Device sensors
      • Application - App management
      • System Info - Device information
      • Settings - System settings
      • WakeLock - Wake lock control
      • QPython Interface - Script execution
      • Activity Result - Activity result handling
      "},{"location":"qsl4a/#hardware","title":"Hardware","text":"
      • Bluetooth - Bluetooth operations
      • Camera - Photo and video capture
      • Audio/Recorder - Audio recording
      • Webcam - MJPEG streaming
      • USB Serial - USB host serial
      "},{"location":"qsl4a/#connectivity","title":"Connectivity","text":"
      • WiFi - WiFi operations
      • Location - GPS and location
      • SMS - SMS operations
      • Phone - Phone calls and info
      • Contacts - Contact management
      • Signal Strength - Signal monitoring
      • FTP Server - Built-in FTP server
      "},{"location":"qsl4a/#storage","title":"Storage","text":"
      • DocumentFile - File operations
      • Clipboard - Clipboard operations
      • Preferences - Shared preferences
      "},{"location":"qsl4a/#media","title":"Media","text":"
      • Media Player - Audio/Video playback
      • Image Processing - Image operations
      "},{"location":"qsl4a/#special-features","title":"Special Features","text":"
      • Cipher - Encryption/Decryption
      • PGPT AI - AI speech services
      "},{"location":"qsl4a/#result-object","title":"Result Object","text":"

      Most QSL4A methods return a Result namedtuple with: - id - Request ID - result - The actual result data - error - Error message if failed

      result = droid.getClipboard()\nif result.error is None:\n    print(result.result)\nelse:\n    print(f\"Error: {result.error}\")\n
      "},{"location":"qsl4a/connectivity/contacts/","title":"Contacts API","text":"

      Access and manage device contacts.

      "},{"location":"qsl4a/connectivity/contacts/#contact-picking","title":"Contact Picking","text":""},{"location":"qsl4a/connectivity/contacts/#pickcontact","title":"pickContact()","text":"

      Display a list of contacts to pick from.

      pickContact()\n

      Returns: Intent with contact URI

      "},{"location":"qsl4a/connectivity/contacts/#pickphone","title":"pickPhone()","text":"

      Display a list of phone numbers to pick from.

      pickPhone()\n

      Returns: Selected phone number string

      "},{"location":"qsl4a/connectivity/contacts/#contact-queries","title":"Contact Queries","text":""},{"location":"qsl4a/connectivity/contacts/#contactsget","title":"contactsGet()","text":"

      Get all contacts.

      contactsGet(attributes=None)\n

      Parameters: - attributes (list, optional): Specific attributes to retrieve

      Returns: List of contact JSONObject

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetbyid","title":"contactsGetById()","text":"

      Get a contact by ID.

      contactsGetById(id, attributes=None)\n

      Parameters: - id (int): Contact ID - attributes (list, optional): Specific attributes to retrieve

      Returns: JSONObject contact data

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetcount","title":"contactsGetCount()","text":"

      Get the total number of contacts.

      contactsGetCount()\n

      Returns: Integer count

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetids","title":"contactsGetIds()","text":"

      Get all contact IDs.

      contactsGetIds()\n

      Returns: List of contact ID integers

      "},{"location":"qsl4a/connectivity/contacts/#contactsgetattributes","title":"contactsGetAttributes()","text":"

      Get all possible contact attributes.

      contactsGetAttributes()\n

      Returns: List of attribute names

      "},{"location":"qsl4a/connectivity/contacts/#content-queries","title":"Content Queries","text":""},{"location":"qsl4a/connectivity/contacts/#querycontent","title":"queryContent()","text":"

      Query content resolver with custom parameters.

      queryContent(uri, attributes=None, selection=None, selectionArgs=None, order=None)\n

      Parameters: - uri (str): Content URI - attributes (list, optional): Attributes to retrieve - selection (str, optional): WHERE clause - selectionArgs (list, optional): Selection arguments - order (str, optional): ORDER BY clause

      Returns: List of JSONObject results

      "},{"location":"qsl4a/connectivity/contacts/#queryattributes","title":"queryAttributes()","text":"

      Get attributes for a content URI.

      queryAttributes(uri)\n

      Parameters: - uri (str): Content URI

      Returns: JSONArray of attribute names

      "},{"location":"qsl4a/connectivity/contacts/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Pick a contact\ncontact_uri = droid.pickContact().result\nprint(f\"Selected contact: {contact_uri}\")\n\n# Pick a phone number\nphone = droid.pickPhone().result\nprint(f\"Selected phone: {phone}\")\n\n# Get all contacts\ncontacts = droid.contactsGet().result\nprint(f\"Total contacts: {len(contacts)}\")\n\n# Get contact by ID\ncontact = droid.contactsGetById(1).result\nprint(f\"Contact: {contact}\")\n\n# Get contact attributes\nattrs = droid.contactsGetAttributes().result\nprint(f\"Available attributes: {attrs}\")\n
      "},{"location":"qsl4a/connectivity/ftp/","title":"FTP Server API","text":"

      Start and manage a built-in FTP server on the device.

      "},{"location":"qsl4a/connectivity/ftp/#ftp-server-methods","title":"FTP Server Methods","text":""},{"location":"qsl4a/connectivity/ftp/#ftpstart","title":"ftpStart()","text":"

      Start the FTP server.

      ftpStart()\n

      Returns: Array containing IP address and port [ip, port]

      "},{"location":"qsl4a/connectivity/ftp/#ftpstop","title":"ftpStop()","text":"

      Stop the FTP server.

      ftpStop()\n
      "},{"location":"qsl4a/connectivity/ftp/#ftpisrunning","title":"ftpIsRunning()","text":"

      Check if FTP server is running.

      ftpIsRunning()\n

      Returns: True if running

      "},{"location":"qsl4a/connectivity/ftp/#ftpget","title":"ftpGet()","text":"

      Get FTP server IP address.

      ftpGet()\n

      Returns: Array with IP address and port

      "},{"location":"qsl4a/connectivity/ftp/#ftpset","title":"ftpSet()","text":"

      Configure FTP server settings.

      ftpSet(port=None, rootDir=None, username=None, password=None)\n

      Parameters: - port (int, optional): Server port - rootDir (str, optional): Root directory to serve - username (str, optional): Login username - password (str, optional): Login password

      Returns: JSONObject with current settings

      "},{"location":"qsl4a/connectivity/ftp/#ftpstatus","title":"ftpStatus()","text":"

      Get FTP server status.

      ftpStatus()\n

      Returns: String status description

      "},{"location":"qsl4a/connectivity/ftp/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Configure FTP server\ndroid.ftpSet(\n    port=2121,\n    rootDir=\"/sdcard\",\n    username=\"admin\",\n    password=\"secret\"\n)\n\n# Start FTP server\ninfo = droid.ftpStart().result\nprint(f\"FTP running at {info[0]}:{info[1]}\")\n\n# Check status\nif droid.ftpIsRunning().result:\n    print(\"FTP server is running\")\n\n# Get server info\nserver_info = droid.ftpGet().result\nprint(f\"Server: {server_info}\")\n\n# Stop when done\ndroid.ftpStop()\n

      Note: Connect to the FTP server using any FTP client with the provided credentials.

      "},{"location":"qsl4a/connectivity/location/","title":"Location API","text":"

      Access GPS and network location services.

      "},{"location":"qsl4a/connectivity/location/#methods","title":"Methods","text":""},{"location":"qsl4a/connectivity/location/#startlocating","title":"startLocating()","text":"

      Start location updates.

      startLocating(minUpdateTime=60000, minUpdateDistance=30, updateGnssStatus=False)\n

      Parameters: - minUpdateTime (int): Minimum time between updates in milliseconds (default: 60000) - minUpdateDistance (float): Minimum distance for update in meters (default: 30) - updateGnssStatus (bool): Enable GNSS status updates (default: False)

      "},{"location":"qsl4a/connectivity/location/#stoplocating","title":"stopLocating()","text":"

      Stop location updates.

      stopLocating()\n
      "},{"location":"qsl4a/connectivity/location/#readlocation","title":"readLocation()","text":"

      Get last known location.

      readLocation()\n

      Returns: Location data dict

      "},{"location":"qsl4a/connectivity/location/#getlastknownlocation","title":"getLastKnownLocation()","text":"

      Get cached location.

      getLastKnownLocation()\n

      Returns: Location from all providers

      "},{"location":"qsl4a/connectivity/location/#geocode","title":"geocode()","text":"

      Convert address to coordinates.

      geocode(address, maxResults=1)\n
      "},{"location":"qsl4a/connectivity/location/#location-provider-methods","title":"Location Provider Methods)","text":""},{"location":"qsl4a/connectivity/location/#locationproviders","title":"locationProviders()","text":"

      Get available location providers on the phone.

      locationProviders()\n

      Returns: List of available provider names (e.g., ['gps', 'network'])

      "},{"location":"qsl4a/connectivity/location/#locationproviderenabled","title":"locationProviderEnabled()","text":"

      Check if a specific location provider is enabled.

      locationProviderEnabled(provider)\n

      Parameters: - provider (str): Provider name (e.g., 'gps', 'network')

      Returns: True if enabled, False otherwise

      "},{"location":"qsl4a/connectivity/location/#readgnssstatus","title":"readGnssStatus()","text":"

      Read Global Navigation Satellite System status (requires Android 8+).

      readGnssStatus()\n

      Returns: JSONArray containing GNSS satellite information

      "},{"location":"qsl4a/connectivity/location/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start location updates\ndroid.startLocating(minUpdateTime=5000, minUpdateDistance=1, updateGnssStatus=False)\n\n# Wait for fix\ntime.sleep(10)\n\n# Get location\nloc = droid.readLocation().result\nif loc:\n    lat = loc['latitude']\n    lon = loc['longitude']\n    print(f\"Location: {lat}, {lon}\")\n\ndroid.stopLocating()\n
      "},{"location":"qsl4a/connectivity/phone/","title":"Phone API","text":"

      Control phone calls and retrieve phone information.

      "},{"location":"qsl4a/connectivity/phone/#phone-state-tracking","title":"Phone State Tracking","text":""},{"location":"qsl4a/connectivity/phone/#starttrackingphonestate","title":"startTrackingPhoneState()","text":"

      Start tracking phone state changes. Generates 'phone' events.

      startTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/phone/#readphonestate","title":"readPhoneState()","text":"

      Read the current phone state.

      readPhoneState()\n

      Returns: Bundle with phone state and incoming number

      "},{"location":"qsl4a/connectivity/phone/#stoptrackingphonestate","title":"stopTrackingPhoneState()","text":"

      Stop tracking phone state.

      stopTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/phone/#making-calls","title":"Making Calls","text":""},{"location":"qsl4a/connectivity/phone/#phonecall","title":"phoneCall()","text":"

      Call a contact/phone number by URI.

      phoneCall(uri)\n

      Parameters: - uri (str): Contact URI or phone number URI

      "},{"location":"qsl4a/connectivity/phone/#phonecallnumber","title":"phoneCallNumber()","text":"

      Call a phone number directly.

      phoneCallNumber(phone_number)\n

      Parameters: - phone_number (str): Phone number to call

      "},{"location":"qsl4a/connectivity/phone/#phonedial","title":"phoneDial()","text":"

      Dial a number (opens dialer without calling).

      phoneDial(uri)\n

      Parameters: - uri (str): Contact URI or phone number URI

      "},{"location":"qsl4a/connectivity/phone/#phonedialnumber","title":"phoneDialNumber()","text":"

      Dial a phone number (opens dialer without calling).

      phoneDialNumber(phone_number)\n

      Parameters: - phone_number (str): Phone number

      "},{"location":"qsl4a/connectivity/phone/#cell-location","title":"Cell Location","text":""},{"location":"qsl4a/connectivity/phone/#getcelllocation","title":"getCellLocation()","text":"

      Get the current cell location.

      getCellLocation()\n

      Returns: JSONObject with cell location data

      "},{"location":"qsl4a/connectivity/phone/#getallcellslocation","title":"getAllCellsLocation()","text":"

      Get all cell locations (for dual SIM devices).

      getAllCellsLocation()\n

      Returns: JSONArray of cell locations

      "},{"location":"qsl4a/connectivity/phone/#network-information","title":"Network Information","text":""},{"location":"qsl4a/connectivity/phone/#getnetworkoperator","title":"getNetworkOperator()","text":"

      Get the MCC+MNC of the current operator.

      getNetworkOperator()\n

      Returns: String (e.g., '310260')

      "},{"location":"qsl4a/connectivity/phone/#getnetworkoperatorname","title":"getNetworkOperatorName()","text":"

      Get the name of the current operator.

      getNetworkOperatorName()\n

      Returns: String (e.g., 'T-Mobile')

      "},{"location":"qsl4a/connectivity/phone/#getnetworktype","title":"getNetworkType()","text":"

      Get the current network type.

      getNetworkType()\n

      Returns: String describing radio technology (e.g., 'LTE', 'UMTS', 'GSM')

      "},{"location":"qsl4a/connectivity/phone/#getphonetype","title":"getPhoneType()","text":"

      Get the phone type.

      getPhoneType()\n

      Returns: String (e.g., 'GSM', 'CDMA', 'SIP')

      "},{"location":"qsl4a/connectivity/phone/#sim-information","title":"SIM Information","text":""},{"location":"qsl4a/connectivity/phone/#getsimcountryiso","title":"getSimCountryIso()","text":"

      Get the ISO country code for the SIM.

      getSimCountryIso()\n

      Returns: String (e.g., 'us')

      "},{"location":"qsl4a/connectivity/phone/#getsimoperator","title":"getSimOperator()","text":"

      Get the MCC+MNC of the SIM operator.

      getSimOperator()\n

      Returns: String (e.g., '310260')

      "},{"location":"qsl4a/connectivity/phone/#getsimoperatorname","title":"getSimOperatorName()","text":"

      Get the SIM operator name.

      getSimOperatorName()\n

      Returns: String (e.g., 'T-Mobile')

      "},{"location":"qsl4a/connectivity/phone/#getsimserialnumber","title":"getSimSerialNumber()","text":"

      Get the SIM serial number.

      getSimSerialNumber()\n

      Returns: String SIM serial number

      "},{"location":"qsl4a/connectivity/phone/#getsimstate","title":"getSimState()","text":"

      Get the SIM card state.

      getSimState()\n

      Returns: String describing SIM state

      "},{"location":"qsl4a/connectivity/phone/#getsubscriberid","title":"getSubscriberId()","text":"

      Get the subscriber ID.

      getSubscriberId()\n

      Returns: String subscriber ID

      "},{"location":"qsl4a/connectivity/phone/#voice-mail","title":"Voice Mail","text":""},{"location":"qsl4a/connectivity/phone/#getvoicemailalphatag","title":"getVoiceMailAlphaTag()","text":"

      Get the voice mail alpha tag.

      getVoiceMailAlphaTag()\n

      Returns: String voice mail tag

      "},{"location":"qsl4a/connectivity/phone/#getvoicemailnumber","title":"getVoiceMailNumber()","text":"

      Get the voice mail number.

      getVoiceMailNumber()\n

      Returns: String voice mail number

      "},{"location":"qsl4a/connectivity/phone/#device-information","title":"Device Information","text":""},{"location":"qsl4a/connectivity/phone/#getdeviceid","title":"getDeviceId()","text":"

      Get the device ID (IMEI for GSM). Deprecated.

      getDeviceId()\n

      Returns: String device ID

      "},{"location":"qsl4a/connectivity/phone/#getdevicesoftwareversion","title":"getDeviceSoftwareVersion()","text":"

      Get the device software version.

      getDeviceSoftwareVersion()\n

      Returns: String software version

      "},{"location":"qsl4a/connectivity/phone/#getline1number","title":"getLine1Number()","text":"

      Get the line 1 phone number.

      getLine1Number()\n

      Returns: String phone number

      "},{"location":"qsl4a/connectivity/phone/#checknetworkroaming","title":"checkNetworkRoaming()","text":"

      Check if connected to roaming network.

      checkNetworkRoaming()\n

      Returns: True if roaming

      "},{"location":"qsl4a/connectivity/phone/#cell-info","title":"Cell Info","text":""},{"location":"qsl4a/connectivity/phone/#getallcellinfo","title":"getAllCellInfo()","text":"

      Get information about all cells.

      getAllCellInfo()\n

      Returns: List of cell information

      "},{"location":"qsl4a/connectivity/phone/#setdataenabled","title":"setDataEnabled()","text":"

      Enable or disable mobile data.

      setDataEnabled(enabled)\n

      Parameters: - enabled (bool): True to enable, False to disable

      "},{"location":"qsl4a/connectivity/phone/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get network info\noperator = droid.getNetworkOperatorName().result\nprint(f\"Operator: {operator}\")\n\nnetwork_type = droid.getNetworkType().result\nprint(f\"Network: {network_type}\")\n\n# Get SIM info\nsim_state = droid.getSimState().result\nprint(f\"SIM: {sim_state}\")\n\n# Get phone number\nline1 = droid.getLine1Number().result\nprint(f\"Phone: {line1}\")\n\n# Track phone state\ndroid.startTrackingPhoneState()\nprint(\"Tracking phone state...\")\ndroid.stopTrackingPhoneState()\n
      "},{"location":"qsl4a/connectivity/signalstrength/","title":"Signal Strength API","text":"

      Monitor cellular and wireless signal strength.

      "},{"location":"qsl4a/connectivity/signalstrength/#signal-strength-methods","title":"Signal Strength Methods","text":""},{"location":"qsl4a/connectivity/signalstrength/#starttrackingsignalstrengths","title":"startTrackingSignalStrengths()","text":"

      Start tracking signal strength changes. Generates 'signal_strengths' events.

      startTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/signalstrength/#stoptrackingsignalstrengths","title":"stopTrackingSignalStrengths()","text":"

      Stop tracking signal strengths.

      stopTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/signalstrength/#readsignalstrengths","title":"readSignalStrengths()","text":"

      Read the current signal strengths.

      readSignalStrengths()\n

      Returns: Bundle with signal strength data

      "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthlevel","title":"getTelephoneSignalStrengthLevel()","text":"

      Get the telephone signal strength as a level (0-4).

      getTelephoneSignalStrengthLevel()\n

      Returns: Integer level (0=none, 1=poor, 2=fair, 3=good, 4=excellent)

      "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthdetail","title":"getTelephoneSignalStrengthDetail()","text":"

      Get detailed telephone signal strength information.

      getTelephoneSignalStrengthDetail()\n

      Returns: String with detailed signal info

      "},{"location":"qsl4a/connectivity/signalstrength/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start tracking signal strength\ndroid.startTrackingSignalStrengths()\n\n# Wait for signal updates\ntime.sleep(5)\n\n# Read current signal strength\nsignal = droid.readSignalStrengths().result\nprint(f\"Signal: {signal}\")\n\n# Get level directly\nlevel = droid.getTelephoneSignalStrengthLevel().result\nprint(f\"Signal level: {level}/4\")\n\ndroid.stopTrackingSignalStrengths()\n
      "},{"location":"qsl4a/connectivity/sms/","title":"SMS API","text":"

      Send and receive SMS messages.

      "},{"location":"qsl4a/connectivity/sms/#methods","title":"Methods","text":""},{"location":"qsl4a/connectivity/sms/#smssend","title":"smsSend()","text":"

      Send SMS message.

      smsSend(destinationAddress, text)\n

      Parameters: - destinationAddress (str): Phone number - text (str): Message text

      "},{"location":"qsl4a/connectivity/sms/#smsgetmessagecount","title":"smsGetMessageCount()","text":"

      Get message count.

      smsGetMessageCount(unreadOnly=False, folder=\"inbox\")\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessageids","title":"smsGetMessageIds()","text":"

      Get message IDs.

      smsGetMessageIds(unreadOnly=False, folder=\"inbox\")\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessages","title":"smsGetMessages()","text":"

      Get message details.

      smsGetMessages(unreadOnly=False, folder=\"inbox\", attributes=None)\n
      "},{"location":"qsl4a/connectivity/sms/#smsgetmessagebyid","title":"smsGetMessageById()","text":"

      Get a specific message by ID.

      smsGetMessageById(id, attributes=None)\n

      Parameters: - id (int): Message ID - attributes (list, optional): Specific attributes to retrieve

      Returns: Message data dict

      "},{"location":"qsl4a/connectivity/sms/#smsgetattributes","title":"smsGetAttributes()","text":"

      Get available SMS message attributes.

      smsGetAttributes()\n

      Returns: List of available attribute names

      "},{"location":"qsl4a/connectivity/sms/#smsdeletemessage","title":"smsDeleteMessage()","text":"

      Delete message.

      smsDeleteMessage(id)\n
      "},{"location":"qsl4a/connectivity/sms/#smsmarkmessageread","title":"smsMarkMessageRead()","text":"

      Mark message as read.

      smsMarkMessageRead(ids, read=True)\n
      "},{"location":"qsl4a/connectivity/sms/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Send SMS\ndroid.smsSend(\"+1234567890\", \"Hello from QPython!\")\n\n# Get unread messages\nmessages = droid.smsGetMessages(unreadOnly=True).result\nfor msg in messages:\n    print(f\"From: {msg['address']}, Text: {msg['body']}\")\n
      "},{"location":"qsl4a/connectivity/wifi/","title":"WiFi API","text":"

      Control WiFi adapter and get connection information.

      "},{"location":"qsl4a/connectivity/wifi/#adapter-control","title":"Adapter Control","text":""},{"location":"qsl4a/connectivity/wifi/#checkwifistate","title":"checkWifiState()","text":"

      Check if WiFi is enabled.

      checkWifiState()\n

      Returns: True if WiFi is enabled, False otherwise

      "},{"location":"qsl4a/connectivity/wifi/#togglewifistate","title":"toggleWifiState()","text":"

      Turn WiFi on or off.

      toggleWifiState(enabled=None)\n

      Parameters: - enabled (bool): True to enable, False to disable, None to toggle

      Returns: True if operation succeeded

      "},{"location":"qsl4a/connectivity/wifi/#wifistartscan","title":"wifiStartScan()","text":"

      Start scanning for available WiFi networks.

      wifiStartScan()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifigetscanresults","title":"wifiGetScanResults()","text":"

      Get list of discovered WiFi networks.

      wifiGetScanResults()\n

      Returns: List of access point information

      "},{"location":"qsl4a/connectivity/wifi/#connection-management","title":"Connection Management","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetconnectioninfo","title":"wifiGetConnectionInfo()","text":"

      Get detailed connection information.

      wifiGetConnectionInfo()\n

      Returns: Dict with connection details including SSID, BSSID, IP address

      "},{"location":"qsl4a/connectivity/wifi/#getconnectedinfo","title":"getConnectedInfo()","text":"

      Get connected WiFi network info (simplified).

      getConnectedInfo()\n

      Returns: Dict with SSID, BSSID, signal strength

      "},{"location":"qsl4a/connectivity/wifi/#getdhcpinfo","title":"getDhcpInfo()","text":"

      Get DHCP information for current connection.

      getDhcpInfo(ipConvertToString=True)\n

      Parameters: - ipConvertToString (bool): Convert IP addresses to string format (default: True)

      Returns: Dict with DHCP info including IP, gateway, DNS

      "},{"location":"qsl4a/connectivity/wifi/#wifidisconnect","title":"wifiDisconnect()","text":"

      Disconnect from current WiFi network.

      wifiDisconnect()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifireconnect","title":"wifiReconnect()","text":"

      Reconnect to the current network.

      wifiReconnect()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifireassociate","title":"wifiReassociate()","text":"

      Reassociate with the current access point.

      wifiReassociate()\n
      "},{"location":"qsl4a/connectivity/wifi/#hotspot","title":"Hotspot","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetapstate","title":"wifiGetApState()","text":"

      Get WiFi AP (hotspot) state.

      wifiGetApState()\n

      Returns: Hotspot state

      "},{"location":"qsl4a/connectivity/wifi/#wifi-locks","title":"WiFi Locks","text":""},{"location":"qsl4a/connectivity/wifi/#wifilockacquirefull","title":"wifiLockAcquireFull()","text":"

      Acquire a full WiFi lock (keeps WiFi active even when screen is off).

      wifiLockAcquireFull()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifilockacquirescanonly","title":"wifiLockAcquireScanOnly()","text":"

      Acquire a scan-only WiFi lock.

      wifiLockAcquireScanOnly()\n
      "},{"location":"qsl4a/connectivity/wifi/#wifilockrelease","title":"wifiLockRelease()","text":"

      Release the WiFi lock.

      wifiLockRelease()\n
      "},{"location":"qsl4a/connectivity/wifi/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Check WiFi state\nif droid.checkWifiState().result:\n    print(\"WiFi is enabled\")\nelse:\n    print(\"Enabling WiFi...\")\n    droid.toggleWifiState(True)\n    time.sleep(2)\n\n# Start scanning\ndroid.wifiStartScan()\ntime.sleep(3)\n\n# Get scan results\nnetworks = droid.wifiGetScanResults().result\nfor network in networks:\n    print(f\"SSID: {network.get('SSID')}, Signal: {network.get('level')} dBm\")\n\n# Get connection info\ninfo = droid.wifiGetConnectionInfo().result\nif info:\n    print(f\"Connected to: {info.get('ssid')}\")\n    print(f\"BSSID: {info.get('bssid')}\")\n    print(f\"IP: {info.get('ip_address')}\")\n\n# Get DHCP info\ndhcp = droid.getDhcpInfo().result\nif dhcp:\n    print(f\"Gateway: {dhcp.get('gateway')}\")\n    print(f\"DNS: {dhcp.get('dns1')}\")\n\n# Get simplified connected info\nconnected = droid.getConnectedInfo().result\nprint(f\"SSID: {connected.get('ssid')}, Signal: {connected.get('level')} dBm\")\n\n# Disconnect and reconnect\ndroid.wifiDisconnect()\ntime.sleep(1)\ndroid.wifiReconnect()\n\n# Reassociate with access point\ndroid.wifiReassociate()\n\n# Check hotspot state\nap_state = droid.wifiGetApState().result\nprint(f\"Hotspot state: {ap_state}\")\n\n# Acquire WiFi lock for background operation\ndroid.wifiLockAcquireFull()\n# ... do work ...\ndroid.wifiLockRelease()\n\n# Or use scan-only lock for lighter background operation\ndroid.wifiLockAcquireScanOnly()\n# ... do scanning work ...\ndroid.wifiLockRelease()\n
      "},{"location":"qsl4a/core/android-base/","title":"Android Base Class","text":"

      The Android class is the core of QSL4A, providing the connection to the Android runtime and RPC mechanism.

      "},{"location":"qsl4a/core/android-base/#module-import","title":"Module Import","text":"
      # Full featured (recommended)\nimport androidhelper\ndroid = androidhelper.Android()\n\n# Minimal version (quick, single instance)\nimport android\ndroid = android.droid\n
      "},{"location":"qsl4a/core/android-base/#class-android","title":"Class: Android","text":""},{"location":"qsl4a/core/android-base/#constructor","title":"Constructor","text":"
      Android(addr=None)\n

      Parameters: - addr (tuple, optional): (HOST, PORT) address. If None, uses environment variables AP_HOST and AP_PORT

      Environment Variables: - AP_HOST - Server host address - AP_PORT - Server port - AP_HANDSHAKE - Authentication token

      "},{"location":"qsl4a/core/android-base/#core-methods","title":"Core Methods","text":""},{"location":"qsl4a/core/android-base/#_rpc","title":"_rpc()","text":"

      Internal RPC method for calling Android functions.

      _rpc(method, *args)\n

      Parameters: - method (str): Method name to call - *args: Variable arguments for the method

      Returns: Result namedtuple with fields: - id (int): Request ID - result: Method return value - error (str or None): Error message if failed

      "},{"location":"qsl4a/core/android-base/#getattr","title":"getattr()","text":"

      Dynamic method dispatcher. All Android methods are accessed via attribute lookup.

      # These are equivalent:\ndroid.makeToast(\"Hello\")\ndroid._rpc(\"makeToast\", \"Hello\")\n
      "},{"location":"qsl4a/core/android-base/#standalone-functions-androidpy","title":"Standalone Functions (android.py)","text":"

      When using the minimal android module:

      "},{"location":"qsl4a/core/android-base/#jsla","title":"jsla()","text":"

      Send JSON-RPC request and return raw response.

      jsla(method, *params)\n

      Returns: JSON string response

      "},{"location":"qsl4a/core/android-base/#rsla","title":"rsla()","text":"

      Send request and return result only.

      rsla(method, *params)\n

      Returns: Result value from RPC call

      "},{"location":"qsl4a/core/android-base/#esla","title":"esla()","text":"

      Send request, raise exception on error.

      esla(method, *params)\n

      Raises: Exception if error field is not None

      "},{"location":"qsl4a/core/android-base/#nsla","title":"nsla()","text":"

      Send request and return Result namedtuple.

      nsla(method, *params)\n

      Returns: Result namedtuple

      "},{"location":"qsl4a/core/android-base/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/android-base/#basic-connection","title":"Basic Connection","text":"
      import androidhelper\n\n# Connect to Android runtime\ndroid = androidhelper.Android()\n\n# Check connection by showing toast\ndroid.makeToast(\"Connected!\")\n
      "},{"location":"qsl4a/core/android-base/#error-handling","title":"Error Handling","text":"
      result = droid.someMethod()\nif result.error:\n    print(f\"Error: {result.error}\")\nelse:\n    print(f\"Success: {result.result}\")\n
      "},{"location":"qsl4a/core/android-base/#direct-rpc-call","title":"Direct RPC Call","text":"
      # Call any method directly\nresult = droid._rpc(\"makeToast\", \"Hello World\")\n
      "},{"location":"qsl4a/core/events/","title":"Event System","text":"

      QSL4A provides an event system for handling asynchronous events from Android, such as sensor updates, location changes, and custom broadcasts.

      "},{"location":"qsl4a/core/events/#event-basics","title":"Event Basics","text":"

      Events are stored in a buffer and can be polled or waited for. Each event has: - name: Event type/name - data: Event payload data - time: Timestamp

      "},{"location":"qsl4a/core/events/#event-methods","title":"Event Methods","text":""},{"location":"qsl4a/core/events/#eventclearbuffer","title":"eventClearBuffer()","text":"

      Clear all pending events from the buffer.

      eventClearBuffer()\n

      Returns: None

      "},{"location":"qsl4a/core/events/#eventpoll","title":"eventPoll()","text":"

      Poll for events in the buffer.

      eventPoll(number_of_events=1)\n

      Parameters: - number_of_events (int): Maximum events to retrieve (default: 1)

      Returns: List of event objects

      "},{"location":"qsl4a/core/events/#eventwait","title":"eventWait()","text":"

      Wait for any event.

      eventWait(timeout=None)\n

      Parameters: - timeout (int, optional): Timeout in seconds. None = wait forever

      Returns: Event object or None if timeout

      "},{"location":"qsl4a/core/events/#eventwaitfor","title":"eventWaitFor()","text":"

      Wait for a specific event.

      eventWaitFor(eventName, timeout=None)\n

      Parameters: - eventName (str): Name of event to wait for - timeout (int, optional): Timeout in seconds

      Returns: Event object or None if timeout

      "},{"location":"qsl4a/core/events/#eventpost","title":"eventPost()","text":"

      Post a custom event.

      eventPost(name, data, enqueue=None)\n

      Parameters: - name (str): Event name - data: Event data (any type) - enqueue (bool, optional): Add to queue if True

      "},{"location":"qsl4a/core/events/#receiveevent","title":"receiveEvent()","text":"

      Receive event (blocking).

      receiveEvent()\n

      Returns: Event object

      "},{"location":"qsl4a/core/events/#broadcast-events","title":"Broadcast Events","text":"

      Register for system broadcast events.

      "},{"location":"qsl4a/core/events/#eventregisterforbroadcast","title":"eventRegisterForBroadcast()","text":"

      Register to receive broadcast events.

      eventRegisterForBroadcast(category, enqueue=True)\n

      Parameters: - category (str): Broadcast category/action - enqueue (bool): Add to event queue

      "},{"location":"qsl4a/core/events/#eventunregisterforbroadcast","title":"eventUnregisterForBroadcast()","text":"

      Unregister from broadcast events.

      eventUnregisterForBroadcast(category)\n
      "},{"location":"qsl4a/core/events/#eventgetbrodcastcategories","title":"eventGetBrodcastCategories()","text":"

      Get registered broadcast categories.

      eventGetBrodcastCategories()\n

      Returns: List of registered categories

      "},{"location":"qsl4a/core/events/#event-dispatcher","title":"Event Dispatcher)","text":""},{"location":"qsl4a/core/events/#starteventdispatcher","title":"startEventDispatcher()","text":"

      Opens up a socket where you can read for events posted.)

      startEventDispatcher(port=0)\n

      Parameters: - port (int, optional): Port to listen on (default: 0 = auto-select)

      Returns: Port number being listened on

      "},{"location":"qsl4a/core/events/#stopeventdispatcher","title":"stopEventDispatcher()","text":"

      Stops the event server.)

      stopEventDispatcher()\n
      "},{"location":"qsl4a/core/events/#deprecated-methods","title":"Deprecated Methods","text":""},{"location":"qsl4a/core/events/#rpcpostevent","title":"rpcPostEvent()","text":"

      Post an event to the event queue. (Deprecated, use eventPost)

      rpcPostEvent(name, data)\n

      Parameters: - name (str): Event name - data: Event data

      "},{"location":"qsl4a/core/events/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/events/#basic-event-polling","title":"Basic Event Polling","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Clear old events\ndroid.eventClearBuffer()\n\n# Poll for events\nevents = droid.eventPoll(5).result\nfor event in events:\n    print(f\"Event: {event['name']}, Data: {event['data']}\")\n
      "},{"location":"qsl4a/core/events/#waiting-for-events","title":"Waiting for Events","text":"
      # Wait for any event with timeout\nevent = droid.eventWait(timeout=10).result\nif event:\n    print(f\"Got event: {event['name']}\")\n
      "},{"location":"qsl4a/core/events/#waiting-for-specific-event","title":"Waiting for Specific Event","text":"
      # Wait for sensor event\nevent = droid.eventWaitFor('screen', timeout=5).result\nif event:\n    print(f\"Screen event: {event['data']}\")\n
      "},{"location":"qsl4a/core/events/#posting-custom-events","title":"Posting Custom Events","text":"
      # Post custom event\ndroid.eventPost('my_event', {'key': 'value'})\n\n# Wait for it\nevent = droid.eventWaitFor('my_event', timeout=1).result\n
      "},{"location":"qsl4a/core/events/#broadcast-receiver","title":"Broadcast Receiver","text":"
      # Register for screen on/off events\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_ON')\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_OFF')\n\n# Wait for screen events\nwhile True:\n    event = droid.receiveEvent().result\n    if event['name'] == 'android.intent.action.SCREEN_ON':\n        print(\"Screen turned on\")\n    elif event['name'] == 'android.intent.action.SCREEN_OFF':\n        print(\"Screen turned off\")\n
      "},{"location":"qsl4a/core/events/#sensor-event-handling","title":"Sensor Event Handling","text":"
      # Start sensing\ndroid.startSensingTimed(1, 250)\n\n# Process sensor events\nfor _ in range(100):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'sensors':\n        data = event['data']\n        print(f\"Accel: {data['xforce']}, {data['yforce']}, {data['zforce']}\")\n\ndroid.stopSensing()\n
      "},{"location":"qsl4a/core/events/#common-event-types","title":"Common Event Types","text":"Event Name Description Source sensors Sensor data update startSensing* location GPS location update startLocating phone Phone state change startTrackingPhoneState signal Signal strength change startTrackingSignalStrength screen Screenshot ready fullGetScreenShot dialog Dialog response dialogShow*"},{"location":"qsl4a/core/events/#event-data-structure","title":"Event Data Structure","text":"
      {\n    'name': 'event_name',\n    'data': {\n        # Event-specific data\n    },\n    'time': 1234567890  # Timestamp\n}\n
      "},{"location":"qsl4a/core/intent/","title":"Intent System","text":"

      Android Intents are used to start activities, send broadcasts, and communicate between apps. QSL4A provides full Intent support through the Intent module.

      "},{"location":"qsl4a/core/intent/#module-import","title":"Module Import","text":"
      import androidhelper\ndon = androidhelper.Android()\n
      "},{"location":"qsl4a/core/intent/#intent-constants","title":"Intent Constants","text":"

      Access via droid.Intent:

      "},{"location":"qsl4a/core/intent/#actions","title":"Actions","text":"Constant Value Usage ACTION_MAIN android.intent.action.MAIN App entry point ACTION_VIEW android.intent.action.VIEW View content ACTION_EDIT android.intent.action.EDIT Edit content ACTION_PICK android.intent.action.PICK Pick item ACTION_SEND android.intent.action.SEND Share content ACTION_SEARCH android.intent.action.SEARCH Search"},{"location":"qsl4a/core/intent/#flags","title":"Flags","text":"Constant Value Usage FLAG_ACTIVITY_NEW_TASK 268435456 Start new task FLAG_ACTIVITY_CLEAR_TASK 32768 Clear task stack FLAG_ACTIVITY_NEW_DOCUMENT 524288 New document mode"},{"location":"qsl4a/core/intent/#extras","title":"Extras","text":"Constant Usage EXTRA_TEXT Text content EXTRA_STREAM File URI EXTRA_SUBJECT Subject line EXTRA_EMAIL Email address"},{"location":"qsl4a/core/intent/#core-methods","title":"Core Methods","text":""},{"location":"qsl4a/core/intent/#makeintent","title":"makeIntent()","text":"

      Create an Intent object.

      makeIntent(action, uri=None, type=None, extras=None, categories=None,\n           packagename=None, classname=None, flags=None)\n

      Parameters: - action (str): Intent action (e.g., droid.Intent.ACTION_VIEW) - uri (str, optional): Data URI - type (str, optional): MIME type - extras (dict, optional): Extra data - categories (list, optional): Intent categories - packagename (str, optional): Target package - classname (str, optional): Target class - flags (int, optional): Intent flags

      Returns: Intent object

      "},{"location":"qsl4a/core/intent/#startactivityintent","title":"startActivityIntent()","text":"

      Start an Activity with an Intent.

      startActivityIntent(intent, wait=None)\n

      Parameters: - intent: Intent object from makeIntent() - wait (bool, optional): Block until activity closes

      "},{"location":"qsl4a/core/intent/#startactivityforresultintent","title":"startActivityForResultIntent()","text":"

      Start activity and wait for result.

      startActivityForResultIntent(intent)\n

      Returns: Activity result

      "},{"location":"qsl4a/core/intent/#sendbroadcastintent","title":"sendBroadcastIntent()","text":"

      Send a broadcast.

      sendBroadcastIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#view","title":"view()","text":"

      View content by URI.

      view(uri, type=None, extras=None)\n
      "},{"location":"qsl4a/core/intent/#pick","title":"pick()","text":"

      Pick content from URI.

      pick(uri)\n
      "},{"location":"qsl4a/core/intent/#common-intent-methods","title":"Common Intent Methods)","text":""},{"location":"qsl4a/core/intent/#scanbarcode","title":"scanBarcode()","text":"

      Launch the barcode scanner.

      scanBarcode()\n

      Returns: Scanned barcode string

      "},{"location":"qsl4a/core/intent/#send","title":"send()","text":"

      Send content via share intent.

      send(type, content)\n

      Parameters: - type (str): MIME type - content (str): Content to share

      "},{"location":"qsl4a/core/intent/#sendtext","title":"sendText()","text":"

      Send text content.

      sendText(text)\n

      Parameters: - text (str): Text to send

      "},{"location":"qsl4a/core/intent/#sendemail","title":"sendEmail()","text":"

      Send an email.

      sendEmail(to, subject, body, attachment=None)\n

      Parameters: - to (str or list): Recipient email address(es) - subject (str): Email subject - body (str): Email body - attachment (str, optional): Attachment file path

      "},{"location":"qsl4a/core/intent/#pathtouri","title":"pathToUri()","text":"

      Convert file path to content URI.

      pathToUri(path)\n

      Parameters: - path (str): File path

      Returns: Content URI string

      "},{"location":"qsl4a/core/intent/#openfile","title":"openFile()","text":"

      Open a file with appropriate app.

      openFile(path)\n

      Parameters: - path (str): File path to open

      "},{"location":"qsl4a/core/intent/#sendfile","title":"sendFile()","text":"

      Send a file via share intent.

      sendFile(path)\n

      Parameters: - path (str): File path to send

      "},{"location":"qsl4a/core/intent/#getpathtype","title":"getPathType()","text":"

      Get the MIME type for a file path.

      getPathType(path)\n

      Parameters: - path (str): File path

      Returns: MIME type string

      "},{"location":"qsl4a/core/intent/#viewmap","title":"viewMap()","text":"

      Open map at a location.

      viewMap(latitude, longitude)\n

      Parameters: - latitude (float): Latitude - longitude (float): Longitude

      "},{"location":"qsl4a/core/intent/#viewcontacts","title":"viewContacts()","text":"

      Open the contacts app.

      viewContacts()\n
      "},{"location":"qsl4a/core/intent/#search","title":"search()","text":"

      Perform a web search.

      search(query)\n

      Parameters: - query (str): Search query

      "},{"location":"qsl4a/core/intent/#viewhtml","title":"viewHtml()","text":"

      View HTML content.

      viewHtml(content, encoding=None)\n

      Parameters: - content (str): HTML content - encoding (str, optional): Character encoding

      "},{"location":"qsl4a/core/intent/#webviewshow","title":"webViewShow()","text":"

      Display web content in WebView. Deprecated, use viewHtml.

      webViewShow(url)\n

      Parameters: - url (str): Web page URL

      "},{"location":"qsl4a/core/intent/#editoropen","title":"editorOpen()","text":"

      Open a text editor.

      editorOpen(path=None, create=False)\n

      Parameters: - path (str, optional): File path to edit - create (bool, optional): Create if doesn't exist

      "},{"location":"qsl4a/core/intent/#helper-class-uri","title":"Helper Class: Uri","text":"

      Create URI objects for Intents:

      from androidhelper.Intent import Uri\n\nuri = Uri(\"file:///sdcard/test.txt\")\n
      "},{"location":"qsl4a/core/intent/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/core/intent/#open-web-page","title":"Open Web Page","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"http://www.example.com\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#share-text","title":"Share Text","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_TEXT: \"Hello from QPython!\",\n        droid.Intent.EXTRA_SUBJECT: \"Test\"\n    },\n    type=\"text/plain\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#open-file","title":"Open File","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"file:///sdcard/document.pdf\",\n    type=\"application/pdf\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#pick-contact","title":"Pick Contact","text":"
      result = droid.pickContact()\ncontact_uri = result.result\n
      "},{"location":"qsl4a/core/intent/#send-email","title":"Send Email","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_EMAIL: [\"test@example.com\"],\n        droid.Intent.EXTRA_SUBJECT: \"Hello\",\n        droid.Intent.EXTRA_TEXT: \"Message body\"\n    },\n    type=\"message/rfc822\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/core/intent/#open-app","title":"Open App","text":"
      intent = droid.makeIntent(\n    action=droid.Intent.ACTION_MAIN,\n    packagename=\"com.android.settings\",\n    classname=\"com.android.settings.Settings\"\n).result\ndroid.startActivityIntent(intent)\n
      "},{"location":"qsl4a/hardware/bluetooth/","title":"Bluetooth API","text":"

      Control Bluetooth adapter and communicate with Bluetooth devices.

      "},{"location":"qsl4a/hardware/bluetooth/#adapter-control","title":"Adapter Control","text":""},{"location":"qsl4a/hardware/bluetooth/#togglebluetoothstate","title":"toggleBluetoothState()","text":"

      Turn Bluetooth on/off.

      toggleBluetoothState(enabled=None, prompt=True)\n

      Parameters: - enabled (bool): True=on, False=off, None=toggle - prompt (bool): Show user prompt

      "},{"location":"qsl4a/hardware/bluetooth/#checkbluetoothstate","title":"checkBluetoothState()","text":"

      Check if Bluetooth is enabled.

      checkBluetoothState()\n

      Returns: True/False

      "},{"location":"qsl4a/hardware/bluetooth/#getlocalname","title":"GetLocalName()","text":"

      Get Bluetooth device name.

      GetLocalName()\n
      "},{"location":"qsl4a/hardware/bluetooth/#setlocalname","title":"SetLocalName()","text":"

      Set Bluetooth device name.

      SetLocalName(name)\n
      "},{"location":"qsl4a/hardware/bluetooth/#getscanmode","title":"GetScanMode()","text":"

      Get discoverability mode.

      GetScanMode()\n

      Returns: - -1: Disabled - 0: Non-discoverable, non-connectable - 1: Connectable, non-discoverable - 3: Connectable and discoverable

      "},{"location":"qsl4a/hardware/bluetooth/#makediscoverable","title":"MakeDiscoverable()","text":"

      Make device discoverable.

      MakeDiscoverable(duration=300)\n

      Parameters: - duration (int): Seconds to be discoverable

      "},{"location":"qsl4a/hardware/bluetooth/#discovery","title":"Discovery","text":""},{"location":"qsl4a/hardware/bluetooth/#discoverystart","title":"DiscoveryStart()","text":"

      Start device discovery.

      DiscoveryStart()\n
      "},{"location":"qsl4a/hardware/bluetooth/#discoverycancel","title":"DiscoveryCancel()","text":"

      Cancel discovery.

      DiscoveryCancel()\n
      "},{"location":"qsl4a/hardware/bluetooth/#getreceiveddevices","title":"GetReceivedDevices()","text":"

      Get discovered devices.

      GetReceivedDevices()\n

      Returns: List of device info dicts

      "},{"location":"qsl4a/hardware/bluetooth/#getbondeddevices","title":"GetBondedDevices()","text":"

      Get paired devices.

      GetBondedDevices()\n

      Returns: List of paired device info

      "},{"location":"qsl4a/hardware/bluetooth/#connection","title":"Connection","text":""},{"location":"qsl4a/hardware/bluetooth/#connect","title":"Connect()","text":"

      Connect to a device.

      Connect(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", address=None)\n

      Parameters: - uuid (str): Service UUID - address (str): Device address (None = show picker)

      Returns: True if successful

      "},{"location":"qsl4a/hardware/bluetooth/#accept","title":"Accept()","text":"

      Accept incoming connection.

      Accept(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", timeout=0)\n
      "},{"location":"qsl4a/hardware/bluetooth/#activeconnections","title":"ActiveConnections()","text":"

      Check active connections.

      ActiveConnections()\n
      "},{"location":"qsl4a/hardware/bluetooth/#stop","title":"Stop()","text":"

      Disconnect.

      Stop(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#communication","title":"Communication","text":""},{"location":"qsl4a/hardware/bluetooth/#write","title":"Write()","text":"

      Send ASCII data.

      Write(ascii, connID=\"\")\n
      "},{"location":"qsl4a/hardware/bluetooth/#writebinary","title":"WriteBinary()","text":"

      Send binary data (base64 encoded).

      WriteBinary(base64, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#read","title":"Read()","text":"

      Read ASCII data.

      Read(bufferSize=4096, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readbinary","title":"ReadBinary()","text":"

      Read binary data.

      ReadBinary(bufferSize=4096, connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readline","title":"ReadLine()","text":"

      Read line.

      ReadLine(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#readready","title":"ReadReady()","text":"

      Check if data available.

      ReadReady(connID=None)\n
      "},{"location":"qsl4a/hardware/bluetooth/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Enable Bluetooth\ndroid.toggleBluetoothState(True)\n\n# Get paired devices\ndevices = droid.GetBondedDevices().result\nfor dev in devices:\n    print(f\"{dev['name']}: {dev['address']}\")\n\n# Connect to device\ndroid.Connect(address=\"00:11:22:33:44:55\")\n\n# Send data\ndroid.Write(\"Hello Bluetooth!\")\n\n# Read response\ndata = droid.Read(1024).result\n
      "},{"location":"qsl4a/hardware/camera/","title":"Camera API","text":"

      Capture photos and record video.

      "},{"location":"qsl4a/hardware/camera/#photo-capture","title":"Photo Capture","text":""},{"location":"qsl4a/hardware/camera/#takepicture","title":"takePicture()","text":"

      Take a photo using the default camera.

      takePicture(path=None)\n

      Parameters: - path (str, optional): Save path. If None, returns image data

      Returns: Image path or image data

      "},{"location":"qsl4a/hardware/camera/#cameracapturepicture","title":"cameraCapturePicture()","text":"

      Capture picture with advanced camera controls.

      cameraCapturePicture(targetPath=None, cameraId=0, useAutoFocus=True)\n

      Parameters: - targetPath (str, optional): Save path - cameraId (int): Camera to use (0 = back, 1 = front) - useAutoFocus (bool): Enable auto focus

      Returns: Captured image path

      "},{"location":"qsl4a/hardware/camera/#camerasettorchmode","title":"cameraSetTorchMode()","text":"

      Control camera flashlight/torch.

      cameraSetTorchMode(enabled)\n

      Parameters: - enabled (bool): True to turn on, False to turn off

      Returns: True if successful

      "},{"location":"qsl4a/hardware/camera/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

      Capture screenshot.

      imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

      Parameters: - path (str, optional): Save path - delayMilliSec (int): Delay before capture

      "},{"location":"qsl4a/hardware/camera/#video-recording","title":"Video Recording","text":""},{"location":"qsl4a/hardware/camera/#takevideo","title":"takeVideo()","text":"

      Record video using default settings.

      takeVideo(path=None, quality=1)\n

      Parameters: - path (str, optional): Save path - quality (int): Video quality (0-4) - 0: 160x120 - 1: 320x240 - 2: 352x288 - 3: 640x480 - 4: 800x480

      "},{"location":"qsl4a/hardware/camera/#recordercapturevideo","title":"recorderCaptureVideo()","text":"

      Capture video with advanced controls.

      recorderCaptureVideo(targetPath=None, duration=10, cameraId=0, quality=8)\n

      Parameters: - targetPath (str, optional): Save path - duration (int): Recording duration in seconds (default: 10) - cameraId (int): Camera to use (0 = back, 1 = front) - quality (int): Video quality (0-8, higher is better)

      Returns: Video file path

      "},{"location":"qsl4a/hardware/camera/#recordaudio","title":"recordAudio()","text":"

      Record audio.

      recordAudio()\n

      Returns: Audio file path

      "},{"location":"qsl4a/hardware/camera/#screen-recording","title":"Screen Recording","text":""},{"location":"qsl4a/hardware/camera/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

      Start screen recording.

      recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

      Parameters: - path (str): Save path - audio (int): Audio source (0=none, 1=mic, 2=internal) - targetPixels (int): Resolution - frameRate (int): FPS - bitRate (int): Bitrate - rotation (bool): Rotate output - autoStart (bool): Start immediately

      "},{"location":"qsl4a/hardware/camera/#recorderstart","title":"recorderStart()","text":"

      Start recording.

      recorderStart()\n
      "},{"location":"qsl4a/hardware/camera/#recorderpause","title":"recorderPause()","text":"

      Pause recording.

      recorderPause()\n
      "},{"location":"qsl4a/hardware/camera/#recorderresume","title":"recorderResume()","text":"

      Resume recording.

      recorderResume()\n
      "},{"location":"qsl4a/hardware/camera/#audio-volume-detection","title":"Audio Volume Detection","text":""},{"location":"qsl4a/hardware/camera/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

      Start volume detection.

      recorderSoundVolumeDetect(interval=100)\n
      "},{"location":"qsl4a/hardware/camera/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

      Get current volume in dB.

      recorderSoundVolumeGetDb()\n
      "},{"location":"qsl4a/hardware/camera/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Take photo with default camera\nphoto_path = droid.takePicture(\"/sdcard/photo.jpg\").result\nprint(f\"Photo saved: {photo_path}\")\n\n# Take photo with front camera and auto focus\ncamera_path = droid.cameraCapturePicture(\"/sdcard/selfie.jpg\", cameraId=1, useAutoFocus=True).result\nprint(f\"Front camera photo: {camera_path}\")\n\n# Control flashlight\ndroid.cameraSetTorchMode(True)  # Turn on flashlight\n\n# Record video with default settings\nvideo_path = droid.takeVideo(\"/sdcard/video.mp4\", quality=3).result\nprint(f\"Video saved: {video_path}\")\n\n# Record video with advanced controls\nvideo_path = droid.recorderCaptureVideo(\"/sdcard/movie.mp4\", duration=30, cameraId=0, quality=8).result\n\n# Screenshot\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n
      "},{"location":"qsl4a/hardware/recorder/","title":"Audio Recorder API","text":"

      Record audio from microphone and device screen.

      "},{"location":"qsl4a/hardware/recorder/#audio-recording","title":"Audio Recording","text":""},{"location":"qsl4a/hardware/recorder/#recordaudio","title":"recordAudio()","text":"

      Record audio from microphone.

      recordAudio()\n

      Returns: Path to recorded audio file

      "},{"location":"qsl4a/hardware/recorder/#recorderstartmicrophone","title":"recorderStartMicrophone()","text":"

      Start recording from microphone to a specific file.

      recorderStartMicrophone(targetPath=None)\n

      Parameters: - targetPath (str, optional): Path to save the recording

      "},{"location":"qsl4a/hardware/recorder/#screen-recording","title":"Screen Recording","text":""},{"location":"qsl4a/hardware/recorder/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

      Start screen recording with audio.

      recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

      Parameters: - path (str): Save path for video file - audio (int): Audio source (0=none, 1=mic, 2=internal audio) - targetPixels (int): Target resolution in pixels - frameRate (int): Frames per second (default: 30) - bitRate (int): Video bitrate - rotation (bool): Rotate output video - autoStart (bool): Start recording immediately

      Returns: Result of operation

      "},{"location":"qsl4a/hardware/recorder/#recorderstart","title":"recorderStart()","text":"

      Start the screen recording (when autoStart=False).

      recorderStart()\n
      "},{"location":"qsl4a/hardware/recorder/#recorderpause","title":"recorderPause()","text":"

      Pause ongoing screen recording.

      recorderPause()\n
      "},{"location":"qsl4a/hardware/recorder/#recorderresume","title":"recorderResume()","text":"

      Resume paused screen recording.

      recorderResume()\n
      "},{"location":"qsl4a/hardware/recorder/#audio-volume-detection","title":"Audio Volume Detection","text":""},{"location":"qsl4a/hardware/recorder/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

      Start monitoring sound volume level.

      recorderSoundVolumeDetect(interval=100)\n

      Parameters: - interval (int): Detection interval in milliseconds (default: 100)

      "},{"location":"qsl4a/hardware/recorder/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

      Get current sound volume in decibels.

      recorderSoundVolumeGetDb()\n

      Returns: Current volume level in dB

      "},{"location":"qsl4a/hardware/recorder/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Record audio from microphone\nprint(\"Recording audio...\")\naudio_path = droid.recordAudio().result\nprint(f\"Saved to: {audio_path}\")\n\n# Record microphone to specific file\ndroid.recorderStartMicrophone(\"/sdcard/my_recording.mp3\")\ntime.sleep(5)\ndroid.recorderStop()\n\n# Record screen with audio\nprint(\"Starting screen recording...\")\ndroid.recorderStartScreenRecord(\n    path=\"/sdcard/screen_record.mp4\",\n    audio=1,\n    frameRate=30,\n    autoStart=True\n)\ntime.sleep(10)\ndroid.recorderStop()\n\n# Monitor sound volume\ndroid.recorderSoundVolumeDetect(interval=100)\ntime.sleep(3)\nvolume = droid.recorderSoundVolumeGetDb().result\nprint(f\"Current volume: {volume} dB\")\n
      "},{"location":"qsl4a/hardware/usbserial/","title":"USB Host Serial API","text":"

      Communicate with USB serial devices (requires USB OTG support and Android 3.1+).

      "},{"location":"qsl4a/hardware/usbserial/#usb-serial-methods","title":"USB Serial Methods)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialopen","title":"usbHostSerialOpen()","text":"

      Open a connection to a USB serial device.

      usbHostSerialOpen(device, baudRate=9600)\n

      Parameters: - device (str): USB device path or identifier - baudRate (int): Baud rate (default: 9600)

      Returns: True if opened successfully

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialclose","title":"usbHostSerialClose()","text":"

      Close the USB serial connection.

      usbHostSerialClose()\n
      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialread","title":"usbHostSerialRead()","text":"

      Read data from USB serial.

      usbHostSerialRead(bufferSize=1024)\n

      Parameters: - bufferSize (int): Maximum bytes to read (default: 1024)

      Returns: String read data

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwrite","title":"usbHostSerialWrite()","text":"

      Write data to USB serial.

      usbHostSerialWrite(data)\n

      Parameters: - data (str): String data to write

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialavailable","title":"usbHostSerialAvailable()","text":"

      Check if data is available to read.

      usbHostSerialAvailable()\n

      Returns: Number of bytes available

      "},{"location":"qsl4a/hardware/usbserial/#configuration-methods","title":"Configuration Methods)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetbaudrate","title":"usbHostSerialSetBaudRate()","text":"

      Set the baud rate.

      usbHostSerialSetBaudRate(baudRate)\n

      Parameters: - baudRate (int): Baud rate

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetdatabits","title":"usbHostSerialSetDataBits()","text":"

      Set data bits (5, 6, 7, or 8).

      usbHostSerialSetDataBits(dataBits)\n

      Parameters: - dataBits (int): Data bits (5-8)

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetstopbits","title":"usbHostSerialSetStopBits()","text":"

      Set stop bits (1, 1.5, or 2).

      usbHostSerialSetStopBits(stopBits)\n

      Parameters: - stopBits (float): Stop bits (1, 1.5, or 2)

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetparity","title":"usbHostSerialSetParity()","text":"

      Set parity (none, odd, even, mark, space).

      usbHostSerialSetParity(parity)\n

      Parameters: - parity (str): Parity mode ('none', 'odd', 'even', 'mark', 'space')

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetflowcontrol","title":"usbHostSerialSetFlowControl()","text":"

      Set flow control (none, hardware, software).

      usbHostSerialSetFlowControl(flowControl)\n

      Parameters: - flowControl (str): Flow control mode ('none', 'hardware', 'software')

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialreadhex","title":"usbHostSerialReadHex()","text":"

      Read data as hex string.

      usbHostSerialReadHex(bufferSize=1024)\n

      Parameters: - bufferSize (int): Maximum bytes to read

      Returns: Hex string

      "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwritehex","title":"usbHostSerialWriteHex()","text":"

      Write data from hex string.

      usbHostSerialWriteHex(hexString)\n

      Parameters: - hexString (str): Hex string to write

      "},{"location":"qsl4a/hardware/usbserial/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Open USB serial connection\nif droid.usbHostSerialOpen(\"/dev/bus/usb/001/001\", 115200).result:\n    print(\"USB serial opened\")\n\n    # Write data\n    droid.usbHostSerialWrite(\"AT\\r\")\n\n    # Read response\n    response = droid.usbHostSerialRead(1024).result\n    print(f\"Response: {response}\")\n\n    # Or use hex\n    droid.usbHostSerialWriteHex(\"41540D0A\")  # \"AT\\r\\n\"\n\n    # Close connection\n    droid.usbHostSerialClose()\n

      Note: USB serial requires: - Android 3.1+ (API 12) - USB OTG cable/adapter - USB host mode support on device - Compatible serial device

      "},{"location":"qsl4a/hardware/webcam/","title":"Webcam API","text":"

      Stream video from the device camera using MJPEG.

      "},{"location":"qsl4a/hardware/webcam/#mjpeg-stream-methods","title":"MJPEG Stream Methods","text":""},{"location":"qsl4a/hardware/webcam/#webcamstart","title":"webcamStart()","text":"

      Start an MJPEG stream from the webcam.

      webcamStart(resolutionLevel=0, jpegQuality=20, port=0)\n

      Parameters: - resolutionLevel (int): Resolution level (default: 0) - jpegQuality (int): JPEG quality 1-100 (default: 20) - port (int): Port number (default: 0 = auto)

      Returns: Tuple of (address, port) for the stream

      "},{"location":"qsl4a/hardware/webcam/#webcamadjustquality","title":"webcamAdjustQuality()","text":"

      Adjust the quality of an active webcam stream.

      webcamAdjustQuality(resolutionLevel=0, jpegQuality=20)\n

      Parameters: - resolutionLevel (int): Resolution level - jpegQuality (int): JPEG quality 1-100

      "},{"location":"qsl4a/hardware/webcam/#webcamstop","title":"webcamStop()","text":"

      Stop the webcam stream.

      webcamStop()\n
      "},{"location":"qsl4a/hardware/webcam/#camera-preview-methods","title":"Camera Preview Methods","text":""},{"location":"qsl4a/hardware/webcam/#camerastartpreview","title":"cameraStartPreview()","text":"

      Start camera preview mode with event generation.

      cameraStartPreview(resolutionLevel=0, jpegQuality=20, filepath=None)\n

      Parameters: - resolutionLevel (int): Resolution level (default: 0) - jpegQuality (int): JPEG quality (default: 20) - filepath (str, optional): File path to save preview frames

      Returns: True if successful

      Note: Generates 'preview' events with frame data.

      "},{"location":"qsl4a/hardware/webcam/#camerastoppreview","title":"cameraStopPreview()","text":"

      Stop the camera preview.

      cameraStopPreview()\n
      "},{"location":"qsl4a/hardware/webcam/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start webcam stream\nstream_info = droid.webcamStart(\n    resolutionLevel=0,\n    jpegQuality=30,\n    port=8080\n).result\nprint(f\"Stream available at {stream_info[0]}:{stream_info[1]}\")\n\n# Adjust quality while streaming\ntime.sleep(5)\ndroid.webcamAdjustQuality(resolutionLevel=1, jpegQuality=50)\n\n# Stop when done\ndroid.webcamStop()\n\n# Or use preview mode\nprint(\"Starting preview...\")\ndroid.cameraStartPreview()\n\n# Wait for preview events\nfor i in range(10):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'preview':\n        print(f\"Got preview frame: {event['data']}\")\n\ndroid.cameraStopPreview()\n
      "},{"location":"qsl4a/media/image/","title":"Image Processing API","text":"

      Compress and process images.

      "},{"location":"qsl4a/media/image/#image-compression","title":"Image Compression","text":""},{"location":"qsl4a/media/image/#imagecompress","title":"imageCompress()","text":"

      Compress image file.

      imageCompress(srcPath, destPath, targetByteSize=0, targetWidth=0, targetHeight=0)\n

      Parameters: - srcPath (str): Source image path - destPath (str): Output path - targetByteSize (int): Target file size in bytes (0 = no limit) - targetWidth (int): Target width (0 = original) - targetHeight (int): Target height (0 = original)

      Returns: Compressed image path

      "},{"location":"qsl4a/media/image/#screenshot","title":"Screenshot","text":""},{"location":"qsl4a/media/image/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

      Capture screen.

      imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

      Parameters: - path (str): Save path - delayMilliSec (int): Delay before capture

      Returns: Screenshot path

      "},{"location":"qsl4a/media/image/#video-playback","title":"Video Playback","text":""},{"location":"qsl4a/media/image/#videoplay","title":"videoPlay()","text":"

      Play video file in fullscreen mode.

      videoPlay(path, wait=True)\n

      Parameters: - path (str): Video file path - wait (bool): Wait for playback to complete (default: True)

      "},{"location":"qsl4a/media/image/#barcode-scanning","title":"Barcode Scanning","text":""},{"location":"qsl4a/media/image/#scanbarcodefromimage","title":"scanBarcodeFromImage()","text":"

      Scan barcode/QR code from image file.

      scanBarcodeFromImage(path, compressRatio=0, x=0, y=0, width=0, height=0)\n

      Parameters: - path (str): Image file path - compressRatio (int): Compression ratio (0 = no compression) - x, y, width, height (int): Region to scan (0 = full image)

      Returns: Scanned barcode content

      "},{"location":"qsl4a/media/image/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Take screenshot\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n\n# Compress image\ncompressed = droid.imageCompress(\n    \"/sdcard/large_photo.jpg\",\n    \"/sdcard/compressed.jpg\",\n    targetByteSize=102400,  # Target ~100KB\n    targetWidth=1920,\n    targetHeight=1080\n).result\nprint(f\"Saved: {compressed}\")\n\n# Play video\nvideo_path = \"/sdcard/movie.mp4\"\ndroid.videoPlay(video_path, wait=True)\n\n# Scan barcode from image\nresult = droid.scanBarcodeFromImage(\"/sdcard/qr_code.png\").result\nprint(f\"Barcode: {result}\")\n
      "},{"location":"qsl4a/media/mediaplayer/","title":"Media Player API","text":"

      Control audio and video playback.

      "},{"location":"qsl4a/media/mediaplayer/#playback-control","title":"Playback Control","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplay","title":"mediaPlay()","text":"

      Play media file.

      mediaPlay(url, tag=\"default\", play=True)\n

      Parameters: - url (str): Media file path or URL - tag (str): Player identifier - play (bool): Auto-start playback

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaystart","title":"mediaPlayStart()","text":"

      Start playback.

      mediaPlayStart(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplaypause","title":"mediaPlayPause()","text":"

      Pause playback.

      mediaPlayPause(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplayclose","title":"mediaPlayClose()","text":"

      Close player.

      mediaPlayClose(tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#mediaplayseek","title":"mediaPlaySeek()","text":"

      Seek to position.

      mediaPlaySeek(msec, tag=\"default\")\n

      Parameters: - msec (int): Position in milliseconds

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaysetlooping","title":"mediaPlaySetLooping()","text":"

      Set loop mode.

      mediaPlaySetLooping(enabled, tag=\"default\")\n
      "},{"location":"qsl4a/media/mediaplayer/#player-info","title":"Player Info","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplayinfo","title":"mediaPlayInfo()","text":"

      Get playback info.

      mediaPlayInfo(tag=\"default\")\n

      Returns: Dict with duration, position, etc.

      "},{"location":"qsl4a/media/mediaplayer/#mediaisplaying","title":"mediaIsPlaying()","text":"

      Check if playing.

      mediaIsPlaying(tag=\"default\")\n

      Returns: True/False

      "},{"location":"qsl4a/media/mediaplayer/#mediaplaylist","title":"mediaPlayList()","text":"

      List active players.

      mediaPlayList()\n
      "},{"location":"qsl4a/media/mediaplayer/#volume-control","title":"Volume Control","text":""},{"location":"qsl4a/media/mediaplayer/#getmediavolume","title":"getMediaVolume()","text":"

      Get media volume.

      getMediaVolume()\n

      Returns: Volume level (0-15)

      "},{"location":"qsl4a/media/mediaplayer/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

      Get max media volume.

      getMaxMediaVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#getringervolume","title":"getRingerVolume()","text":"

      Get ringer volume.

      getRingerVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

      Get max ringer volume.

      getMaxRingerVolume()\n
      "},{"location":"qsl4a/media/mediaplayer/#video-playback","title":"Video Playback","text":""},{"location":"qsl4a/media/mediaplayer/#videoplay","title":"videoPlay()","text":"

      Play video fullscreen.

      videoPlay(path, wait=True)\n

      Parameters: - path (str): Video file path - wait (bool): Wait for playback to complete

      "},{"location":"qsl4a/media/mediaplayer/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Play audio\ndroid.mediaPlay(\"/sdcard/music.mp3\", tag=\"music\")\n\n# Check status\nif droid.mediaIsPlaying(\"music\").result:\n    info = droid.mediaPlayInfo(\"music\").result\n    print(f\"Playing: {info}\")\n\n# Seek to 30 seconds\ndroid.mediaPlaySeek(30000, \"music\")\n\n# Close\ndroid.mediaPlayClose(\"music\")\n\n# Play video\ndroid.videoPlay(\"/sdcard/movie.mp4\", wait=True)\n
      "},{"location":"qsl4a/special/cipher/","title":"Cipher API","text":"

      Encryption and decryption utilities for secure data storage.

      "},{"location":"qsl4a/special/cipher/#initialization","title":"Initialization","text":""},{"location":"qsl4a/special/cipher/#cipherinit","title":"cipherInit()","text":"

      Initialize the cipher with encryption key and algorithm.

      cipherInit(key, algorithm=\"AES/CBC/PKCS5Padding\", encodingFormat=\"\", initialVector=\"\")\n

      Parameters: - key (str or bytes): Encryption key - algorithm (str): Cipher algorithm (default: \"AES/CBC/PKCS5Padding\") - encodingFormat (str): Encoding format - initialVector (str or bytes): Initial vector for encryption

      Returns: Initialization result

      Note: Must be called before any encrypt/decrypt operations.

      "},{"location":"qsl4a/special/cipher/#encryption-methods","title":"Encryption Methods","text":""},{"location":"qsl4a/special/cipher/#encryptstring","title":"encryptString()","text":"

      Encrypt a string.

      encryptString(plainText)\n

      Parameters: - plainText (str): Text to encrypt

      Returns: Encrypted string

      "},{"location":"qsl4a/special/cipher/#encryptbytes","title":"encryptBytes()","text":"

      Encrypt bytes data.

      encryptBytes(data)\n

      Parameters: - data (bytes): Data to encrypt

      Returns: Encrypted bytes

      "},{"location":"qsl4a/special/cipher/#encryptstringtofile","title":"encryptStringToFile()","text":"

      Encrypt string to file.

      encryptStringToFile(plainText, filePath)\n

      Parameters: - plainText (str): Text to encrypt - filePath (str): Output file path

      "},{"location":"qsl4a/special/cipher/#encryptbytestofile","title":"encryptBytesToFile()","text":"

      Encrypt bytes to file.

      encryptBytesToFile(data, filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryption-methods","title":"Decryption Methods","text":""},{"location":"qsl4a/special/cipher/#decryptstring","title":"decryptString()","text":"

      Decrypt to string.

      decryptString(cipherText)\n

      Parameters: - cipherText (str): Encrypted text

      Returns: Decrypted string

      "},{"location":"qsl4a/special/cipher/#decryptbytes","title":"decryptBytes()","text":"

      Decrypt to bytes.

      decryptBytes(data)\n

      Returns: Decrypted bytes

      "},{"location":"qsl4a/special/cipher/#decryptfiletostring","title":"decryptFileToString()","text":"

      Decrypt file to string.

      decryptFileToString(filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryptfiletobytes","title":"decryptFileToBytes()","text":"

      Decrypt file to bytes.

      decryptFileToBytes(filePath)\n
      "},{"location":"qsl4a/special/cipher/#decryptfile","title":"decryptFile()","text":"

      Decrypt file to file.

      decryptFile(srcPath, destPath)\n
      "},{"location":"qsl4a/special/cipher/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Initialize cipher with your encryption key\ndroid.cipherInit(\"my_secret_key_1234\")\n\n# Encrypt string\nencrypted = droid.encryptString(\"Secret message!\").result\nprint(f\"Encrypted: {encrypted}\")\n\n# Decrypt string\ndecrypted = droid.decryptString(encrypted).result\nprint(f\"Decrypted: {decrypted}\")\n\n# Encrypt to file\ndroid.encryptStringToFile(\"My secret data\", \"/sdcard/secret.dat\")\n\n# Decrypt from file\ndata = droid.decryptFileToString(\"/sdcard/secret.dat\").result\nprint(data)\n\n# Initialize with custom algorithm and IV\ndroid.cipherInit(\n    key=\"my_key\",\n    algorithm=\"AES/CBC/PKCS5Padding\",\n    initialVector=\"0123456789abcdef\"\n)\n
      "},{"location":"qsl4a/special/pgptai/","title":"PGPT AI API","text":"

      Speech-to-text and AI services integration.

      "},{"location":"qsl4a/special/pgptai/#prerequisites","title":"Prerequisites","text":"
      pip install pgptAI\n
      "},{"location":"qsl4a/special/pgptai/#speech-recognition","title":"Speech Recognition","text":""},{"location":"qsl4a/special/pgptai/#speechtotext","title":"speechToText()","text":"

      Convert speech to text.

      speechToText(RecordSecond=10, AmrFile=None, Language=None)\n

      Parameters: - RecordSecond (int): Recording duration in seconds - AmrFile (str, optional): Existing audio file path - Language (str, optional): Language code ('en', 'zh')

      Returns: Transcribed text

      "},{"location":"qsl4a/special/pgptai/#text-to-speech","title":"Text to Speech","text":""},{"location":"qsl4a/special/pgptai/#texttospeech","title":"textToSpeech()","text":"

      Convert text to speech and optionally play it.

      textToSpeech(Text, AutoPlay=True, WavFile=None, VoiceName=None)\n

      Parameters: - Text (str): Text to convert to speech - AutoPlay (bool): Automatically play the generated audio (default: True) - WavFile (str, optional): Path to save the WAV file. If None, uses temporary file - VoiceName (str, optional): Voice name to use (e.g., 'en-US-JennyNeural', 'zh-CN-XiaoxiaoNeural')

      Returns: Dict with speech synthesis result including: - text: The input text - url: URL to download the audio file - WavFile: Path to the saved WAV file (if saved locally)

      "},{"location":"qsl4a/special/pgptai/#configuration","title":"Configuration","text":"

      The API uses configuration from /storage/emulated/0/Android/data/org.qpython.qpy/files/apigpt.conf:

      [speech]\nspeech_key = your_api_key\n

      Default voice settings: - English: en-US-JennyNeural - Chinese: zh-CN-XiaoxiaoNeural

      "},{"location":"qsl4a/special/pgptai/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Record and transcribe\nprint(\"Recording for 5 seconds...\")\ntext = droid.speechToText(RecordSecond=5, Language='en').result\nprint(f\"You said: {text}\")\n\n# Transcribe existing file\ntext = droid.speechToText(AmrFile=\"/sdcard/recording.amr\").result\nprint(f\"Transcription: {text}\")\n\n# Text to speech\ndroid.textToSpeech(\"Hello, this is a test message.\", AutoPlay=True, Language='en')\n\n# Text to speech with custom voice and save to file\nresult = droid.textToSpeech(\n    \"Welcome to QPython!\",\n    AutoPlay=False,\n    WavFile=\"/sdcard/welcome.wav\",\n    VoiceName=\"en-US-JennyNeural\"\n).result\nprint(f\"Audio saved to: {result.get('WavFile')}\")\n
      "},{"location":"qsl4a/special/pgptai/#class-usage","title":"Class Usage","text":"
      from androidhelper.pgptai import pgptai\nimport androidhelper\n\ndroid = androidhelper.Android()\nai = pgptai(droid)\n\n# Use speech recognition\ntext = ai.speechToText(RecordSecond=10)\n
      "},{"location":"qsl4a/storage/clipboard/","title":"Clipboard API","text":"

      Copy and paste text to system clipboard.

      "},{"location":"qsl4a/storage/clipboard/#methods","title":"Methods","text":""},{"location":"qsl4a/storage/clipboard/#setclipboard","title":"setClipboard()","text":"

      Copy text to clipboard.

      setClipboard(text)\n

      Parameters: - text (str): Text to copy

      Returns: True if success

      "},{"location":"qsl4a/storage/clipboard/#getclipboard","title":"getClipboard()","text":"

      Get text from clipboard.

      getClipboard()\n

      Returns: Clipboard text

      "},{"location":"qsl4a/storage/clipboard/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Copy to clipboard\ndroid.setClipboard(\"Hello from QPython!\")\n\n# Paste from clipboard\ntext = droid.getClipboard().result\nprint(f\"Clipboard: {text}\")\n
      "},{"location":"qsl4a/storage/documentfile/","title":"DocumentFile API","text":"

      File operations with SAF (Storage Access Framework) support for Android 4.4+.

      "},{"location":"qsl4a/storage/documentfile/#directory-operations","title":"Directory Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfilemkdir","title":"documentFileMkdir()","text":"

      Create directory.

      documentFileMkdir(Dir)\n

      Parameters: - Dir (str): Directory path

      Returns: True if success

      "},{"location":"qsl4a/storage/documentfile/#documentfilelistfiles","title":"documentFileListFiles()","text":"

      List files in directory.

      documentFileListFiles(Folder)\n

      Returns: List of files

      "},{"location":"qsl4a/storage/documentfile/#file-operations","title":"File Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfileexists","title":"documentFileExists()","text":"

      Check if file or directory exists.

      documentFileExists(path)\n

      Parameters: - path (str): File or directory path

      Returns: True if exists, False otherwise

      "},{"location":"qsl4a/storage/documentfile/#documentfileisfile","title":"documentFileIsFile()","text":"

      Check if path is a file.

      documentFileIsFile(path)\n

      Parameters: - path (str): Path to check

      Returns: True if file, False if not a file, None if not exists

      "},{"location":"qsl4a/storage/documentfile/#documentfileisdirectory","title":"documentFileIsDirectory()","text":"

      Check if path is a directory.

      documentFileIsDirectory(path)\n

      Parameters: - path (str): Path to check

      Returns: True if directory, False if not a directory, None if not exists

      "},{"location":"qsl4a/storage/documentfile/#documentfiledelete","title":"documentFileDelete()","text":"

      Delete file or directory.

      documentFileDelete(FileOrTree)\n

      Returns: True if success

      "},{"location":"qsl4a/storage/documentfile/#documentfilerenameto","title":"documentFileRenameTo()","text":"

      Rename or move file.

      documentFileRenameTo(Src, Dest)\n

      Returns: True if success

      "},{"location":"qsl4a/storage/documentfile/#documentfilecopy","title":"documentFileCopy()","text":"

      Copy file.

      documentFileCopy(SrcFileOrTree, DestFileOrTree)\n
      "},{"location":"qsl4a/storage/documentfile/#stream-operations","title":"Stream Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfileinputstream","title":"documentFileInputStream()","text":"

      Read file content.

      documentFileInputStream(srcFile, EncodingFormat=\"\", skip=None, length=None)\n

      Parameters: - srcFile (str): Source file - EncodingFormat (str): \"UTF-8\", \"GBK\", \"Base64\", or \"\" for bytes - skip (int): Skip bytes from start - length (int): Read length

      Returns: File content

      "},{"location":"qsl4a/storage/documentfile/#documentfileoutputstream","title":"documentFileOutputStream()","text":"

      Write file content.

      documentFileOutputStream(destFile, src, EncodingFormat=\"\", append=None)\n

      Parameters: - destFile (str): Destination file - src: Data to write - EncodingFormat (str): Encoding format - append (bool): Append mode

      "},{"location":"qsl4a/storage/documentfile/#file-information","title":"File Information","text":""},{"location":"qsl4a/storage/documentfile/#documentfilelength","title":"documentFileLength()","text":"

      Get file size in bytes.

      documentFileLength(path)\n

      Parameters: - path (str): File path

      Returns: File size in bytes (0 if not exists)

      "},{"location":"qsl4a/storage/documentfile/#documentfilelastmodified","title":"documentFileLastModified()","text":"

      Get last modified time.

      documentFileLastModified(path)\n

      Parameters: - path (str): File path

      Returns: Timestamp (0 if not exists)

      "},{"location":"qsl4a/storage/documentfile/#documentfilegetstat","title":"documentFileGetStat()","text":"

      Get comprehensive file statistics.

      documentFileGetStat(path)\n

      Parameters: - path (str): File path

      Returns: Dict with length, last modified, and read/write permissions, or None if not exists

      "},{"location":"qsl4a/storage/documentfile/#uri-operations","title":"URI Operations","text":""},{"location":"qsl4a/storage/documentfile/#documentfilegeturi","title":"documentFileGetUri()","text":"

      Get URI from path.

      documentFileGetUri(path, isDirectory=None)\n
      "},{"location":"qsl4a/storage/documentfile/#documentfileshowopen","title":"documentFileShowOpen()","text":"

      Show file picker.

      documentFileShowOpen()\n

      Returns: Selected file URI

      "},{"location":"qsl4a/storage/documentfile/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Create directory\ndroid.documentFileMkdir(\"/sdcard/MyFolder\")\n\n# List files\nfiles = droid.documentFileListFiles(\"/sdcard\").result\nfor f in files:\n    print(f)\n\n# Read file\ncontent = droid.documentFileInputStream(\n    \"/sdcard/test.txt\",\n    EncodingFormat=\"UTF-8\"\n).result\nprint(content)\n\n# Write file\ndroid.documentFileOutputStream(\n    \"/sdcard/output.txt\",\n    \"Hello World\",\n    EncodingFormat=\"UTF-8\"\n)\n
      "},{"location":"qsl4a/storage/preferences/","title":"Preferences API","text":"

      Store and retrieve data using Android SharedPreferences.

      "},{"location":"qsl4a/storage/preferences/#preference-methods","title":"Preference Methods","text":""},{"location":"qsl4a/storage/preferences/#prefgetvalue","title":"prefGetValue()","text":"

      Read a value from shared preferences.

      prefGetValue(key, filename=None)\n

      Parameters: - key (str): Preference key - filename (str, optional): Preference file name

      Returns: The stored value (any type)

      "},{"location":"qsl4a/storage/preferences/#prefputvalue","title":"prefPutValue()","text":"

      Write a value to shared preferences.

      prefPutValue(key, value, filename=None)\n

      Parameters: - key (str): Preference key - value (object): Value to store - filename (str, optional): Preference file name

      "},{"location":"qsl4a/storage/preferences/#prefgetall","title":"prefGetAll()","text":"

      Get all preference values.

      prefGetAll(filename=None)\n

      Parameters: - filename (str, optional): Preference file name

      Returns: Map of all preferences

      "},{"location":"qsl4a/storage/preferences/#prefremovevalue","title":"prefRemoveValue()","text":"

      Remove a value from shared preferences.

      prefRemoveValue(key, filename=None)\n

      Parameters: - key (str): Preference key to remove - filename (str, optional): Preference file name

      "},{"location":"qsl4a/storage/preferences/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Store values\ndroid.prefPutValue(\"username\", \"alice\")\ndroid.prefPutValue(\"score\", 100)\ndroid.prefPutValue(\"enabled\", True)\n\n# Read a specific value\nusername = droid.prefGetValue(\"username\").result\nprint(f\"Username: {username}\")\n\n# Get all preferences\nall_prefs = droid.prefGetAll().result\nprint(f\"All prefs: {all_prefs}\")\n\n# Remove a value\ndroid.prefRemoveValue(\"score\")\n\n# Use custom filename\ndroid.prefPutValue(\"token\", \"abc123\", filename=\"auth.prefs\")\ntoken = droid.prefGetValue(\"token\", filename=\"auth.prefs\").result\n
      "},{"location":"qsl4a/system/activityresult/","title":"Activity Result API","text":"

      Set activity results for scripts launched via startActivityForResult.

      "},{"location":"qsl4a/system/activityresult/#result-methods","title":"Result Methods","text":""},{"location":"qsl4a/system/activityresult/#setresultboolean","title":"setResultBoolean()","text":"

      Set a boolean result.

      setResultBoolean(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (bool): Boolean result value

      "},{"location":"qsl4a/system/activityresult/#setresultbyte","title":"setResultByte()","text":"

      Set a byte result.

      setResultByte(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (int): Byte result value

      "},{"location":"qsl4a/system/activityresult/#setresultshort","title":"setResultShort()","text":"

      Set a short result.

      setResultShort(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (int): Short result value

      "},{"location":"qsl4a/system/activityresult/#setresultchar","title":"setResultChar()","text":"

      Set a character result.

      setResultChar(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (str): Character result value

      "},{"location":"qsl4a/system/activityresult/#setresultinteger","title":"setResultInteger()","text":"

      Set an integer result.

      setResultInteger(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (int): Integer result value

      "},{"location":"qsl4a/system/activityresult/#setresultlong","title":"setResultLong()","text":"

      Set a long result.

      setResultLong(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (int): Long result value

      "},{"location":"qsl4a/system/activityresult/#setresultfloat","title":"setResultFloat()","text":"

      Set a float result.

      setResultFloat(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (float): Float result value

      "},{"location":"qsl4a/system/activityresult/#setresultdouble","title":"setResultDouble()","text":"

      Set a double result.

      setResultDouble(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (float): Double result value

      "},{"location":"qsl4a/system/activityresult/#setresultstring","title":"setResultString()","text":"

      Set a string result.

      setResultString(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (str): String result value

      "},{"location":"qsl4a/system/activityresult/#setresultbooleanarray","title":"setResultBooleanArray()","text":"

      Set a boolean array result.

      setResultBooleanArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Boolean array

      "},{"location":"qsl4a/system/activityresult/#setresultbytearray","title":"setResultByteArray()","text":"

      Set a byte array result.

      setResultByteArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Byte array

      "},{"location":"qsl4a/system/activityresult/#setresultshortarray","title":"setResultShortArray()","text":"

      Set a short array result.

      setResultShortArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Short array

      "},{"location":"qsl4a/system/activityresult/#setresultchararray","title":"setResultCharArray()","text":"

      Set a character array result.

      setResultCharArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Char array

      "},{"location":"qsl4a/system/activityresult/#setresultintegerarray","title":"setResultIntegerArray()","text":"

      Set an integer array result.

      setResultIntegerArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Integer array

      "},{"location":"qsl4a/system/activityresult/#setresultlongarray","title":"setResultLongArray()","text":"

      Set a long array result.

      setResultLongArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Long array

      "},{"location":"qsl4a/system/activityresult/#setresultfloatarray","title":"setResultFloatArray()","text":"

      Set a float array result.

      setResultFloatArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Float array

      "},{"location":"qsl4a/system/activityresult/#setresultdoublearray","title":"setResultDoubleArray()","text":"

      Set a double array result.

      setResultDoubleArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): Double array

      "},{"location":"qsl4a/system/activityresult/#setresultstringarray","title":"setResultStringArray()","text":"

      Set a string array result.

      setResultStringArray(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue (list): String array

      "},{"location":"qsl4a/system/activityresult/#setresultserializable","title":"setResultSerializable()","text":"

      Set a serializable result.

      setResultSerializable(resultCode, resultValue)\n

      Parameters: - resultCode (int): Result code - resultValue: Serializable result value

      "},{"location":"qsl4a/system/activityresult/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# After performing an activity, set the result\n# Example: Return success with data\ndroid.setResultInteger(0, 200)  # RESULT_OK\ndroid.setResultString(0, \"Operation completed successfully\")\n\n# Return an array result\ndroid.setResultIntegerArray(0, [1, 2, 3, 4, 5])\n
      "},{"location":"qsl4a/system/application/","title":"Application Management","text":"

      Manage applications, launch apps, and query system information.

      "},{"location":"qsl4a/system/application/#application-information","title":"Application Information","text":""},{"location":"qsl4a/system/application/#getapplicationinfo","title":"getApplicationInfo()","text":"

      Get information about an app.

      getApplicationInfo(packageName=None)\n

      Parameters: - packageName (str): Package name (None = current app)

      Returns: App info dict

      "},{"location":"qsl4a/system/application/#getinstalledpackages","title":"getInstalledPackages()","text":"

      Get list of installed packages.

      getInstalledPackages(flag=4)\n

      Parameters: - flag (int): Package flag filter (default: 4)

      Returns: List of installed packages

      "},{"location":"qsl4a/system/application/#getrunningpackages","title":"getRunningPackages()","text":"

      List running packages.

      getRunningPackages()\n

      Returns: List of package names

      "},{"location":"qsl4a/system/application/#getlaunchablepackages","title":"getLaunchablePackages()","text":"

      Get list of launchable packages.

      getLaunchablePackages(needClassName=False)\n

      Parameters: - needClassName (bool): Include main activity class name (default: False)

      Returns: List of launchable package names or dict with class names

      "},{"location":"qsl4a/system/application/#application-control","title":"Application Control","text":""},{"location":"qsl4a/system/application/#launch","title":"launch()","text":"

      Launch an application.

      launch(classname=None, packagename=None, wait=True)\n

      Parameters: - classname (str): Main activity class name - packagename (str): Package name - wait (bool): Wait for launch to complete (default: True)

      Returns: Launch result

      "},{"location":"qsl4a/system/application/#forcestoppackage","title":"forceStopPackage()","text":"

      Force stop an application.

      forceStopPackage(packageName)\n

      Parameters: - packageName (str): Package name to stop

      "},{"location":"qsl4a/system/application/#version-information","title":"Version Information","text":""},{"location":"qsl4a/system/application/#getpackageversion","title":"getPackageVersion()","text":"

      Get app version name.

      getPackageVersion(packageName)\n

      Returns: Version string (e.g., \"3.2.1\")

      "},{"location":"qsl4a/system/application/#getpackageversioncode","title":"getPackageVersionCode()","text":"

      Get app version code.

      getPackageVersionCode(packageName)\n

      Returns: Version code integer

      "},{"location":"qsl4a/system/application/#getconstants","title":"getConstants()","text":"

      Get class constants.

      getConstants(classname)\n

      Parameters: - classname (str): Full class name

      Returns: Dict of constant names and values

      "},{"location":"qsl4a/system/application/#system-features","title":"System Features","text":""},{"location":"qsl4a/system/application/#backgroundprotect","title":"backgroundProtect()","text":"

      Enable or disable background protection for the app.

      backgroundProtect(enabled=True)\n

      Parameters: - enabled (bool): True to enable protection, False to disable

      "},{"location":"qsl4a/system/application/#createscriptshortcut","title":"createScriptShortCut()","text":"

      Create a home screen shortcut for a script.

      createScriptShortCut(scriptPath, label=None, iconPath=None, scriptArg=None)\n

      Parameters: - scriptPath (str): Path to the Python script - label (str, optional): Shortcut label - iconPath (str, optional): Path to icon image - scriptArg (str, optional): Argument to pass to script

      "},{"location":"qsl4a/system/application/#device-information","title":"Device Information","text":""},{"location":"qsl4a/system/application/#getandroidid","title":"getAndroidID()","text":"

      Get Android device ID.

      getAndroidID()\n

      Returns: Unique Android device ID string

      "},{"location":"qsl4a/system/application/#getsysinfo","title":"getSysInfo()","text":"

      Get system information.

      getSysInfo()\n

      Returns: Dict with system details

      "},{"location":"qsl4a/system/application/#getlocale","title":"getLocale()","text":"

      Get device locale.

      getLocale()\n

      Returns: Locale string (e.g., \"en_US\")

      "},{"location":"qsl4a/system/application/#getharmonyosinformation","title":"getHarmonyOsInformation()","text":"

      Get HarmonyOS information if running on HarmonyOS.

      getHarmonyOsInformation()\n

      Returns: HarmonyOS version info or None

      "},{"location":"qsl4a/system/application/#isexternalstoragemanager","title":"isExternalStorageManager()","text":"

      Check if app has external storage manager permission.

      isExternalStorageManager()\n

      Returns: True if has permission

      "},{"location":"qsl4a/system/application/#memory-and-display","title":"Memory and Display","text":""},{"location":"qsl4a/system/application/#getmemoryinfo","title":"getMemoryInfo()","text":"

      Get memory information.

      getMemoryInfo()\n

      Returns: Dict with memory stats

      "},{"location":"qsl4a/system/application/#getscreeninfo","title":"getScreenInfo()","text":"

      Get screen information.

      getScreenInfo()\n

      Returns: Dict with width, height, density

      "},{"location":"qsl4a/system/application/#permissions","title":"Permissions","text":""},{"location":"qsl4a/system/application/#checkpermissions","title":"checkPermissions()","text":"

      Check current app permissions.

      checkPermissions()\n

      Returns: Dict of permissions and their status

      "},{"location":"qsl4a/system/application/#requestpermissions","title":"requestPermissions()","text":"

      Request permissions from the user.

      requestPermissions(permissions=None)\n

      Parameters: - permissions (list, optional): List of permissions to request. If None, requests all needed permissions.

      Returns: Result of permission request

      "},{"location":"qsl4a/system/application/#system-actions","title":"System Actions","text":""},{"location":"qsl4a/system/application/#showscreenlock","title":"showScreenLock()","text":"

      Show screen lock (PIN/pattern/password entry).

      showScreenLock()\n
      "},{"location":"qsl4a/system/application/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get system info\ninfo = droid.getSysInfo().result\nprint(f\"System: {info}\")\n\n# Get app version\nversion = droid.getPackageVersion(\"org.qpython.qpy\").result\nprint(f\"QPython version: {version}\")\n\n# List installed apps\napps = droid.getInstalledPackages().result\nprint(f\"Installed apps: {len(apps)}\")\n\n# Launch an app\ndroid.launch(packagename=\"com.android.settings\")\n\n# Check permissions\nperms = droid.checkPermissions().result\nprint(f\"Permissions: {perms}\")\n\n# Request storage permission\ndroid.requestPermissions([\"android.permission.READ_EXTERNAL_STORAGE\"])\n\n# Create shortcut\ndroid.createScriptShortCut(\n    \"/sdcard/my_script.py\",\n    label=\"My Script\",\n    iconPath=\"/sdcard/icon.png\"\n)\n
      "},{"location":"qsl4a/system/battery/","title":"Battery API","text":"

      Monitor device battery status and health.

      "},{"location":"qsl4a/system/battery/#methods","title":"Methods","text":""},{"location":"qsl4a/system/battery/#readbatterydata","title":"readBatteryData()","text":"

      Get complete battery information.

      readBatteryData()\n

      Returns: Dict with battery data

      "},{"location":"qsl4a/system/battery/#batterystartmonitoring","title":"batteryStartMonitoring()","text":"

      Start battery monitoring.

      batteryStartMonitoring()\n
      "},{"location":"qsl4a/system/battery/#batterystopmonitoring","title":"batteryStopMonitoring()","text":"

      Stop battery monitoring.

      batteryStopMonitoring()\n
      "},{"location":"qsl4a/system/battery/#batterygetlevel","title":"batteryGetLevel()","text":"

      Get battery percentage.

      batteryGetLevel()\n

      Returns: Int (0-100)

      "},{"location":"qsl4a/system/battery/#batterygetstatus","title":"batteryGetStatus()","text":"

      Get charging status.

      batteryGetStatus()\n

      Returns: - 1: Unknown - 2: Charging - 3: Discharging - 4: Not charging - 5: Full

      "},{"location":"qsl4a/system/battery/#batterygetplugtype","title":"batteryGetPlugType()","text":"

      Get power source.

      batteryGetPlugType()\n

      Returns: - -1: Unknown - 0: Unplugged - 1: AC charger - 2: USB port

      "},{"location":"qsl4a/system/battery/#batterygethealth","title":"batteryGetHealth()","text":"

      Get battery health.

      batteryGetHealth()\n

      Returns: - 1: Unknown - 2: Good - 3: Overheat - 4: Dead - 5: Over voltage - 6: Unspecified failure

      "},{"location":"qsl4a/system/battery/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Get battery level\nlevel = droid.batteryGetLevel().result\nprint(f\"Battery: {level}%\")\n
      "},{"location":"qsl4a/system/qpyinterface/","title":"QPython Interface API","text":"

      Execute QPython scripts and manage shared variables from other apps.

      "},{"location":"qsl4a/system/qpyinterface/#script-execution-methods","title":"Script Execution Methods","text":""},{"location":"qsl4a/system/qpyinterface/#executeqpy","title":"executeQPy()","text":"

      Execute a QPython script.

      executeQPy(path=\"\", arg=None)\n

      Parameters: - path (str): Path to the script file - arg (str, optional): Command line arguments

      Returns: True if started successfully

      "},{"location":"qsl4a/system/qpyinterface/#executeqpyassrv","title":"executeQPyAsSrv()","text":"

      Execute a QPython script as a service.

      executeQPyAsSrv(path=None)\n

      Parameters: - path (str, optional): Path to the script file

      Returns: True if started successfully

      "},{"location":"qsl4a/system/qpyinterface/#executeqpycode","title":"executeQPyCode()","text":"

      Execute Python code directly.

      executeQPyCode(code=None)\n

      Parameters: - code (str, optional): Python code to execute

      Returns: True if started successfully

      "},{"location":"qsl4a/system/qpyinterface/#executeqpycodeassrv","title":"executeQPyCodeAsSrv()","text":"

      Execute Python code as a service.

      executeQPyCodeAsSrv(code=None)\n

      Parameters: - code (str, optional): Python code to execute

      Returns: True if started successfully

      "},{"location":"qsl4a/system/qpyinterface/#shared-variables","title":"Shared Variables","text":"

      Shared variables allow communication between QPython and other apps.

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableset","title":"sharedVariableSet()","text":"

      Set a Java shared variable.

      sharedVariableSet(key, value)\n

      Parameters: - key (str): Variable name - value (str): Variable value

      Returns: The stored value

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableget","title":"sharedVariableGet()","text":"

      Get a Java shared variable.

      sharedVariableGet(key)\n

      Parameters: - key (str): Variable name

      Returns: The stored value

      "},{"location":"qsl4a/system/qpyinterface/#sharedvariableremove","title":"sharedVariableRemove()","text":"

      Remove a Java shared variable.

      sharedVariableRemove(key)\n

      Parameters: - key (str): Variable name to remove

      Returns: The removed value

      "},{"location":"qsl4a/system/qpyinterface/#getlastlog","title":"getLastLog()","text":"

      Get the last log output from QPython.

      getLastLog()\n

      Returns: String log content

      "},{"location":"qsl4a/system/qpyinterface/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Execute a script\ndroid.executeQPy(\"/sdcard/my_script.py\", arg=\"test\")\n\n# Execute code directly\ncode = \"print('Hello from QPython!')\"\ndroid.executeQPyCode(code)\n\n# Use shared variables\ndroid.sharedVariableSet(\"username\", \"alice\")\nusername = droid.sharedVariableGet(\"username\").result\nprint(f\"Username: {username}\")\n\n# Remove variable\ndroid.sharedVariableRemove(\"username\")\n\n# Get recent log\nlog = droid.getLastLog().result\nprint(f\"Log: {log}\")\n
      "},{"location":"qsl4a/system/sensors/","title":"Sensor API","text":"

      Access device sensors including accelerometer, gyroscope, magnetometer, and more.

      "},{"location":"qsl4a/system/sensors/#methods","title":"Methods","text":""},{"location":"qsl4a/system/sensors/#startsensingtimed","title":"startSensingTimed()","text":"

      Start sensor monitoring with time intervals.

      startSensingTimed(sensorNumber, delayTime)\n

      Parameters: - sensorNumber (int): Sensor ID (1-3 typically) - delayTime (int): Delay between readings in milliseconds

      "},{"location":"qsl4a/system/sensors/#startsensingthreshold","title":"startSensingThreshold()","text":"

      Start sensor monitoring with threshold trigger.

      startSensingThreshold(sensorNumber, threshold, axis)\n

      Parameters: - sensorNumber (int): Sensor ID - threshold (float): Trigger threshold - axis (int): Axis to monitor (0=X, 1=Y, 2=Z)

      "},{"location":"qsl4a/system/sensors/#stopsensing","title":"stopSensing()","text":"

      Stop all sensor monitoring.

      stopSensing()\n
      "},{"location":"qsl4a/system/sensors/#readsensors","title":"readSensors()","text":"

      Read current sensor data.

      readSensors()\n

      Returns: Sensor data dict

      "},{"location":"qsl4a/system/sensors/#sensorsreadaccelerometer","title":"sensorsReadAccelerometer()","text":"

      Read accelerometer values.

      sensorsReadAccelerometer()\n

      Returns: List [X, Y, Z] in m/s\u00b2

      "},{"location":"qsl4a/system/sensors/#sensorsreadgyroscope","title":"sensorsReadGyroscope()","text":"

      Read gyroscope values.

      sensorsReadGyroscope()\n

      Returns: List [X, Y, Z] in rad/s

      "},{"location":"qsl4a/system/sensors/#sensorsreadmagnetometer","title":"sensorsReadMagnetometer()","text":"

      Read magnetic field values.

      sensorsReadMagnetometer()\n

      Returns: List [X, Y, Z] in \u03bcT

      "},{"location":"qsl4a/system/sensors/#sensorsreadorientation","title":"sensorsReadOrientation()","text":"

      Read device orientation.

      sensorsReadOrientation()\n

      Returns: List [azimuth, pitch, roll] in degrees

      "},{"location":"qsl4a/system/sensors/#sensorsgetlight","title":"sensorsGetLight()","text":"

      Read light sensor value.

      sensorsGetLight()\n

      Returns: Light level in lux

      "},{"location":"qsl4a/system/sensors/#sensorsgetstepcounter","title":"sensorsGetStepCounter()","text":"

      Read step counter.

      sensorsGetStepCounter()\n

      Returns: Number of steps

      "},{"location":"qsl4a/system/sensors/#sensorsgetaccuracy","title":"sensorsGetAccuracy()","text":"

      Get the current sensor accuracy.

      sensorsGetAccuracy()\n

      Returns: Accuracy value (0-3: UNRELIABLE, ACCURACY_LOW, ACCURACY_MEDIUM, ACCURACY_HIGH)

      "},{"location":"qsl4a/system/sensors/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Start sensing\ndroid.startSensingTimed(1, 250)\n\n# Read sensors 10 times\nfor i in range(10):\n    accel = droid.sensorsReadAccelerometer().result\n    print(f\"Accel: X={accel[0]:.2f}, Y={accel[1]:.2f}, Z={accel[2]:.2f}\")\n    time.sleep(0.5)\n\ndroid.stopSensing()\n
      "},{"location":"qsl4a/system/settings/","title":"Settings API","text":"

      Control system settings including screen, sound, and network settings.

      "},{"location":"qsl4a/system/settings/#screen-settings","title":"Screen Settings","text":""},{"location":"qsl4a/system/settings/#setscreentimeout","title":"setScreenTimeout()","text":"

      Set the screen timeout value.

      setScreenTimeout(value)\n

      Parameters: - value (int): Screen timeout in seconds

      Returns: Previous timeout value

      "},{"location":"qsl4a/system/settings/#getscreentimeout","title":"getScreenTimeout()","text":"

      Get the current screen timeout.

      getScreenTimeout()\n

      Returns: Current screen timeout in seconds

      "},{"location":"qsl4a/system/settings/#getscreenbrightness","title":"getScreenBrightness()","text":"

      Get the screen brightness value.

      getScreenBrightness()\n

      Returns: Brightness value (0-255)

      "},{"location":"qsl4a/system/settings/#setscreenbrightness","title":"setScreenBrightness()","text":"

      Set the screen brightness.

      setScreenBrightness(value=None)\n

      Parameters: - value (int, optional): Brightness value (0-255), or None for auto

      Returns: Previous brightness value

      "},{"location":"qsl4a/system/settings/#checkscreenon","title":"checkScreenOn()","text":"

      Check if the screen is on.

      checkScreenOn()\n

      Returns: True if screen is on, False otherwise

      "},{"location":"qsl4a/system/settings/#airplane-mode","title":"Airplane Mode","text":""},{"location":"qsl4a/system/settings/#checkairplanemode","title":"checkAirplaneMode()","text":"

      Check if airplane mode is enabled.

      checkAirplaneMode()\n

      Returns: True if airplane mode is on

      "},{"location":"qsl4a/system/settings/#ringer-settings","title":"Ringer Settings","text":""},{"location":"qsl4a/system/settings/#checkringersilentmode","title":"checkRingerSilentMode()","text":"

      Check if ringer is in silent mode.

      checkRingerSilentMode()\n

      Returns: True if silent mode is on

      "},{"location":"qsl4a/system/settings/#toggleringersilentmode","title":"toggleRingerSilentMode()","text":"

      Toggle ringer silent mode.

      toggleRingerSilentMode(enabled=None)\n

      Parameters: - enabled (bool, optional): True to enable, False to disable, None to toggle

      Returns: New state

      "},{"location":"qsl4a/system/settings/#togglevibratemode","title":"toggleVibrateMode()","text":"

      Toggle vibrate mode.

      toggleVibrateMode(enabled=None, ringer=None)\n

      Parameters: - enabled (bool, optional): Toggle vibrate on/off - ringer (bool, optional): Apply to ringer mode

      Returns: New state

      "},{"location":"qsl4a/system/settings/#getvibratemode","title":"getVibrateMode()","text":"

      Get the vibrate mode setting.

      getVibrateMode(ringer=None)\n

      Parameters: - ringer (bool, optional): Check ringer vibrate mode

      Returns: True if vibrate is enabled

      "},{"location":"qsl4a/system/settings/#volume-settings","title":"Volume Settings","text":""},{"location":"qsl4a/system/settings/#getringervolume","title":"getRingerVolume()","text":"

      Get the current ringer volume.

      getRingerVolume()\n

      Returns: Ringer volume level (0-7 typically)

      "},{"location":"qsl4a/system/settings/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

      Get the maximum ringer volume.

      getMaxRingerVolume()\n

      Returns: Maximum ringer volume

      "},{"location":"qsl4a/system/settings/#setringervolume","title":"setRingerVolume()","text":"

      Set the ringer volume.

      setRingerVolume(volume)\n

      Parameters: - volume (int): Volume level

      "},{"location":"qsl4a/system/settings/#getmediavolume","title":"getMediaVolume()","text":"

      Get the current media volume.

      getMediaVolume()\n

      Returns: Media volume level (0-15 typically)

      "},{"location":"qsl4a/system/settings/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

      Get the maximum media volume.

      getMaxMediaVolume()\n

      Returns: Maximum media volume

      "},{"location":"qsl4a/system/settings/#setmediavolume","title":"setMediaVolume()","text":"

      Set the media volume.

      setMediaVolume(volume)\n

      Parameters: - volume (int): Volume level

      "},{"location":"qsl4a/system/settings/#system-info","title":"System Info","text":""},{"location":"qsl4a/system/settings/#elapsedrealtimenanos","title":"elapsedRealtimeNanos()","text":"

      Get nanoseconds since system startup.

      elapsedRealtimeNanos()\n

      Returns: Nanoseconds (can be used for timing)

      "},{"location":"qsl4a/system/settings/#gettrafficstats","title":"getTrafficStats()","text":"

      Get network traffic statistics.

      getTrafficStats(flags=7)\n

      Parameters: - flags (int): Which stats to retrieve (default: 7 = all)

      Returns: Dict with transmit/receive bytes

      "},{"location":"qsl4a/system/settings/#getapptxbytes","title":"getAppTxBytes()","text":"

      Get transmit bytes for QPython app.

      getAppTxBytes(packageName)\n

      Parameters: - packageName (str): Package name

      Returns: Dict with tx/rx bytes

      "},{"location":"qsl4a/system/settings/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Screen settings\ncurrent_timeout = droid.getScreenTimeout().result\nprint(f\"Current timeout: {current_timeout}s\")\ndroid.setScreenTimeout(30)\n\n# Check screen\nif droid.checkScreenOn().result:\n    print(\"Screen is on\")\n\n# Volume control\nmedia_vol = droid.getMediaVolume().result\nprint(f\"Media volume: {media_vol}\")\ndroid.setMediaVolume(10)\n\n# Check airplane mode\nif droid.checkAirplaneMode().result:\n    print(\"Airplane mode is on\")\n
      "},{"location":"qsl4a/system/sysinfo/","title":"System Information","text":"

      Retrieve device and system information.

      "},{"location":"qsl4a/system/sysinfo/#device-information","title":"Device Information","text":""},{"location":"qsl4a/system/sysinfo/#getandroidid","title":"getAndroidID()","text":"

      Get the Android device ID.

      getAndroidID()\n

      Returns: String device ID

      "},{"location":"qsl4a/system/sysinfo/#getsysinfo","title":"getSysInfo()","text":"

      Get comprehensive system information.

      getSysInfo()\n

      Returns: Dict with system details

      "},{"location":"qsl4a/system/sysinfo/#getlocale","title":"getLocale()","text":"

      Get device locale settings.

      getLocale()\n

      Returns: Locale string (e.g., \"en_US\")

      "},{"location":"qsl4a/system/sysinfo/#memory","title":"Memory","text":""},{"location":"qsl4a/system/sysinfo/#getmemoryinfo","title":"getMemoryInfo()","text":"

      Get RAM information.

      getMemoryInfo()\n

      Returns: Dict with memory stats

      "},{"location":"qsl4a/system/sysinfo/#display","title":"Display","text":""},{"location":"qsl4a/system/sysinfo/#getscreeninfo","title":"getScreenInfo()","text":"

      Get display information.

      getScreenInfo()\n

      Returns: Dict with width, height, density

      "},{"location":"qsl4a/system/sysinfo/#identifiers","title":"Identifiers","text":""},{"location":"qsl4a/system/sysinfo/#getimei","title":"getImei()","text":"

      Get device IMEI.

      getImei(slotIndex=None)\n
      "},{"location":"qsl4a/system/sysinfo/#getmeid","title":"getMeid()","text":"

      Get device MEID.

      getMeid(slotIndex=None)\n
      "},{"location":"qsl4a/system/sysinfo/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Device ID\nandroid_id = droid.getAndroidID().result\nprint(f\"Android ID: {android_id}\")\n\n# Screen info\nscreen = droid.getScreenInfo().result\nprint(f\"Screen: {screen['width']}x{screen['height']}\")\n\n# Memory\nmemory = droid.getMemoryInfo().result\nprint(f\"Memory: {memory}\")\n
      "},{"location":"qsl4a/system/wakelock/","title":"WakeLock API","text":"

      Control device wake locks to keep the CPU or screen on.

      "},{"location":"qsl4a/system/wakelock/#wake-lock-types","title":"Wake Lock Types","text":"

      QSL4A provides different wake lock types:

      Type Description Full CPU on, screen bright, keyboard bright Partial CPU on only Bright CPU on, screen bright Dim CPU on, screen dim"},{"location":"qsl4a/system/wakelock/#wake-lock-methods","title":"Wake Lock Methods","text":""},{"location":"qsl4a/system/wakelock/#wakelockacquirefull","title":"wakeLockAcquireFull()","text":"

      Acquire a full wake lock (CPU on, screen bright, keyboard bright).

      wakeLockAcquireFull()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquirepartial","title":"wakeLockAcquirePartial()","text":"

      Acquire a partial wake lock (CPU on only).

      wakeLockAcquirePartial()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquirebright","title":"wakeLockAcquireBright()","text":"

      Acquire a bright wake lock (CPU on, screen bright).

      wakeLockAcquireBright()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockacquiredim","title":"wakeLockAcquireDim()","text":"

      Acquire a dim wake lock (CPU on, screen dim).

      wakeLockAcquireDim()\n
      "},{"location":"qsl4a/system/wakelock/#wakelockrelease","title":"wakeLockRelease()","text":"

      Release the wake lock.

      wakeLockRelease()\n
      "},{"location":"qsl4a/system/wakelock/#usage-example","title":"Usage Example","text":"
      import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# Acquire full wake lock\ndroid.wakeLockAcquireFull()\n\n# Do important work while keeping screen on\nprint(\"Screen will stay on\")\ntime.sleep(10)\n\n# Release when done\ndroid.wakeLockRelease()\n\n# Or use partial lock for background tasks\ndroid.wakeLockAcquirePartial()\n# CPU stays on even with screen off\ntime.sleep(30)\ndroid.wakeLockRelease()\n

      Note: Remember to release wake locks when no longer needed to conserve battery.

      "},{"location":"qsl4a/ui/accessibility/","title":"Accessibility Service","text":"

      The Accessibility Service allows automation of UI interactions like clicks, swipes, and system actions.

      "},{"location":"qsl4a/ui/accessibility/#service-control","title":"Service Control","text":""},{"location":"qsl4a/ui/accessibility/#accessibilitystartservice","title":"accessibilityStartService()","text":"

      Start the accessibility service.

      accessibilityStartService()\n

      Returns: True if successful, False otherwise

      "},{"location":"qsl4a/ui/accessibility/#accessibilityserviceenabled","title":"accessibilityServiceEnabled()","text":"

      Check if accessibility service is enabled.

      accessibilityServiceEnabled()\n

      Returns: True or False

      "},{"location":"qsl4a/ui/accessibility/#screen-interactions","title":"Screen Interactions","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityclick","title":"accessibilityClick()","text":"

      Click at screen coordinates.

      accessibilityClick(x=0, y=0, t=50)\n

      Parameters: - x (int/float): X coordinate (0=center, decimals supported) - y (int/float): Y coordinate (0=center, decimals supported) - t (int): Press duration in milliseconds (default: 50)

      "},{"location":"qsl4a/ui/accessibility/#accessibilityslide","title":"accessibilitySlide()","text":"

      Multi-point slide gesture.

      accessibilitySlide(XnYn=None, t=None)\n

      Parameters: - XnYn (list): Coordinates [X1, Y1, X2, Y2, ... Xn, Yn] - t (int): Slide duration (default: 50*n ms)

      "},{"location":"qsl4a/ui/accessibility/#system-actions","title":"System Actions","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityaction","title":"accessibilityAction()","text":"

      Execute system action by code.

      accessibilityAction(actionCode)\n

      Action Codes: | Code | Constant | Description | |------|----------|-------------| | 1 | BACK | Back button | | 2 | HOME | Home button | | 3 | RECENTS | Recent apps | | 4 | NOTIFICATIONS | Open notifications | | 5 | QUICK_SETTINGS | Open quick settings | | 6 | POWER_DIALOG | Power menu | | 7 | TOGGLE_SPLIT_SCREEN | Split screen | | 8 | LOCK_SCREEN | Lock screen | | 9 | TAKE_SCREENSHOT | Take screenshot | | 10 | KEYCODE_HEADSETHOOK | Headset hook | | 11-14 | ACCESSIBILITY_ | Accessibility buttons | | 15 | DISMISS_NOTIFICATION_SHADE | Close notifications | | 16-20 | DPAD_ | Directional pad | | 21 | MENU | Menu button | | 22 | MEDIA_PLAY_PAUSE | Play/Pause media |

      "},{"location":"qsl4a/ui/accessibility/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/accessibility/#click-center-screen","title":"Click Center Screen","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Start service\nif not droid.accessibilityServiceEnabled().result:\n    droid.accessibilityStartService()\n\n# Click center (0,0 = center)\ndroid.accessibilityClick(0, 0, t=100)\n
      "},{"location":"qsl4a/ui/accessibility/#swipe-gesture","title":"Swipe Gesture","text":"
      # Swipe from bottom to top (scroll up)\ndroid.accessibilitySlide([0, 1.5, 0, -1.5], t=300)\n
      "},{"location":"qsl4a/ui/accessibility/#system-navigation","title":"System Navigation","text":"
      # Press home\ndroid.accessibilityAction(2)\n\n# Press back\ndroid.accessibilityAction(1)\n\n# Open notifications\ndroid.accessibilityAction(4)\n
      "},{"location":"qsl4a/ui/accessibility/#tap-specific-location","title":"Tap Specific Location","text":"
      # Tap at screen coordinate (500, 800)\ndroid.accessibilityClick(500, 800)\n\n# Tap at relative position (center horizontally, 3/4 down)\ndroid.accessibilityClick(0, 1.5)\n
      "},{"location":"qsl4a/ui/dialogs/","title":"Dialog System","text":"

      QSL4A provides comprehensive dialog support for user interaction, including alerts, input dialogs, choice dialogs, and progress dialogs.

      "},{"location":"qsl4a/ui/dialogs/#alert-dialogs","title":"Alert Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowalert","title":"dialogShowAlert()","text":"

      Show a simple alert dialog.

      dialogShowAlert(title=\"Alert\", message=\"The message of the alert.\",\n                positiveButtonText=\"OK\", negativeButtonText=None,\n                neutralButtonText=None, messageIsHtml=False)\n

      Parameters: - title (str): Dialog title - message (str): Message text - positiveButtonText (str): Positive button label - negativeButtonText (str, optional): Negative button label - neutralButtonText (str, optional): Neutral button label - messageIsHtml (bool): Parse message as HTML

      Returns: Result with button clicked

      "},{"location":"qsl4a/ui/dialogs/#dialogshowsimplechoice","title":"dialogShowSimpleChoice()","text":"

      Show a simple choice dialog with items.

      dialogShowSimpleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

      Parameters: - items (list): List of choice strings

      Returns: Result with selected item

      "},{"location":"qsl4a/ui/dialogs/#input-dialogs","title":"Input Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialoggetinput","title":"dialogGetInput()","text":"

      Get text input from user.

      dialogGetInput(title=\"Value\", message=\"Please enter value:\",\n               defaultText=None, messageIsHtml=False)\n

      Returns: Result with user's input text

      "},{"location":"qsl4a/ui/dialogs/#dialoggetpassword","title":"dialogGetPassword()","text":"

      Get password input.

      dialogGetPassword(title=\"Password\", message=\"Please enter password:\")\n

      Returns: Result with password entered

      "},{"location":"qsl4a/ui/dialogs/#dialogcreateinput","title":"dialogCreateInput()","text":"

      Create a custom input dialog.

      dialogCreateInput(title=\"Value\", message=\"Please enter value:\",\n                  defaultText=None, inputType=None)\n

      Parameters: - inputType (str): Input type (e.g., \"text\", \"number\", \"textPassword\")

      "},{"location":"qsl4a/ui/dialogs/#dialogcreatepassword","title":"dialogCreatePassword()","text":"

      Create a password input dialog.

      dialogCreatePassword(title=\"Password\", message=\"Please enter password:\")\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreateseekbar","title":"dialogCreateSeekBar()","text":"

      Create a seek bar/slider dialog.

      dialogCreateSeekBar(starting_value=50, maximum_value=100, title=\"\", message=\"\")\n

      Parameters: - starting_value (int): Initial value - maximum_value (int): Maximum value

      "},{"location":"qsl4a/ui/dialogs/#choice-dialogs","title":"Choice Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowsinglechoice","title":"dialogShowSingleChoice()","text":"

      Show single choice (radio) dialog.

      dialogShowSingleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, selected=-1, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

      Parameters: - items (list): List of choice strings - selected (int): Default selected index

      "},{"location":"qsl4a/ui/dialogs/#dialogshowmultichoice","title":"dialogShowMultiChoice()","text":"

      Show multiple choice (checkbox) dialog.

      dialogShowMultiChoice(title=\"Alert\", message=\"The message of the alert.\",\n                      items=None, selected=None, positiveButtonText=\"OK\",\n                      negativeButtonText=None, neutralButtonText=None,\n                      messageIsHtml=False)\n

      Parameters: - items (list): List of choice strings - selected (list): List of initially selected indices

      "},{"location":"qsl4a/ui/dialogs/#dialogsetsinglechoiceitems","title":"dialogSetSingleChoiceItems()","text":"

      Set single choice items for a dialog.

      dialogSetSingleChoiceItems(items, selected=-1)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmultichoiceitems","title":"dialogSetMultiChoiceItems()","text":"

      Set multiple choice items for a dialog.

      dialogSetMultiChoiceItems(items, selected=None)\n
      "},{"location":"qsl4a/ui/dialogs/#progress-dialogs","title":"Progress Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatespinnerprogress","title":"dialogCreateSpinnerProgress()","text":"

      Create indeterminate progress dialog.

      dialogCreateSpinnerProgress(title=None, message=None, maximum_progress=100)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreatehorizontalprogress","title":"dialogCreateHorizontalProgress()","text":"

      Create horizontal progress dialog.

      dialogCreateHorizontalProgress(title=None, message=None, maximum_progress=100)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetcurrentprogress","title":"dialogSetCurrentProgress()","text":"

      Update progress value.

      dialogSetCurrentProgress(current)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmaxprogress","title":"dialogSetMaxProgress()","text":"

      Set maximum progress value.

      dialogSetMaxProgress(max)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetprogressmessage","title":"dialogSetProgressMessage()","text":"

      Update the progress dialog message.

      dialogSetProgressMessage(message)\n
      "},{"location":"qsl4a/ui/dialogs/#picker-dialogs","title":"Picker Dialogs","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatedatepicker","title":"dialogCreateDatePicker()","text":"

      Create date picker dialog.

      dialogCreateDatePicker(year=1970, month=1, day=1)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogcreatetimepicker","title":"dialogCreateTimePicker()","text":"

      Create time picker dialog.

      dialogCreateTimePicker(hour=0, minute=0, is24hour=False)\n
      "},{"location":"qsl4a/ui/dialogs/#custom-dialog-creation","title":"Custom Dialog Creation","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatealert","title":"dialogCreateAlert()","text":"

      Create a custom alert dialog.

      dialogCreateAlert(title=None, message=None)\n

      Creates an empty alert dialog. Use with other dialogSet* functions to customize.

      "},{"location":"qsl4a/ui/dialogs/#dialogsetitems","title":"dialogSetItems()","text":"

      Set simple list items for the dialog.

      dialogSetItems(items)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetpositivebuttontext","title":"dialogSetPositiveButtonText()","text":"

      Set positive button text.

      dialogSetPositiveButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetnegativebuttontext","title":"dialogSetNegativeButtonText()","text":"

      Set negative button text.

      dialogSetNegativeButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetneutralbuttontext","title":"dialogSetNeutralButtonText()","text":"

      Set neutral button text.

      dialogSetNeutralButtonText(text)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogsetmessageishtml","title":"dialogSetMessageIsHtml()","text":"

      Set whether message should be parsed as HTML.

      dialogSetMessageIsHtml(messageIsHtml=True)\n
      "},{"location":"qsl4a/ui/dialogs/#dialogshow","title":"dialogShow()","text":"

      Show the created custom dialog.

      dialogShow()\n
      "},{"location":"qsl4a/ui/dialogs/#dialog-control","title":"Dialog Control","text":""},{"location":"qsl4a/ui/dialogs/#dialogdismiss","title":"dialogDismiss()","text":"

      Dismiss current dialog.

      dialogDismiss()\n
      "},{"location":"qsl4a/ui/dialogs/#dialoggetresponse","title":"dialogGetResponse()","text":"

      Get dialog response.

      dialogGetResponse()\n
      "},{"location":"qsl4a/ui/dialogs/#dialoggetselecteditems","title":"dialogGetSelectedItems()","text":"

      Get selected items from choice dialog.

      dialogGetSelectedItems()\n
      "},{"location":"qsl4a/ui/dialogs/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/dialogs/#simple-alert","title":"Simple Alert","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Show alert\ndroid.dialogShowAlert(\"Warning\", \"This is an important message!\")\n
      "},{"location":"qsl4a/ui/dialogs/#input-dialog","title":"Input Dialog","text":"
      # Get user input\nresult = droid.dialogGetInput(\"Name\", \"Enter your name:\", \"John\").result\nprint(f\"Hello, {result}!\")\n
      "},{"location":"qsl4a/ui/dialogs/#custom-dialog-with-buttons","title":"Custom Dialog with Buttons","text":"
      # Create custom dialog\ndroid.dialogCreateAlert(\"Custom\", \"Choose an option\")\ndroid.dialogSetItems([\"Option 1\", \"Option 2\", \"Option 3\"])\ndroid.dialogShow()\n\n# Get response\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response['item']}\")\n
      "},{"location":"qsl4a/ui/dialogs/#progress-dialog","title":"Progress Dialog","text":"
      # Create progress dialog\ndroid.dialogCreateHorizontalProgress(\"Loading\", \"Please wait...\", 100)\ndroid.dialogShow()\n\n# Update progress\nfor i in range(101):\n    droid.dialogSetCurrentProgress(i)\n    time.sleep(0.05)\n\ndroid.dialogDismiss()\n
      "},{"location":"qsl4a/ui/dialogs/#date-picker","title":"Date Picker","text":"
      # Show date picker\ndroid.dialogCreateDatePicker(2024, 1, 15)\ndroid.dialogShow()\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response}\")\n
      "},{"location":"qsl4a/ui/floatview/","title":"FloatView","text":"

      Floating window support for overlay UI elements that stay on top of other applications.

      "},{"location":"qsl4a/ui/floatview/#methods","title":"Methods","text":""},{"location":"qsl4a/ui/floatview/#floatview_1","title":"floatView()","text":"

      Show or modify a floating view.

      floatView(Args=None)\n

      Parameters: - Args (dict): Configuration dictionary with the following keys: - index (int): Float view index (-1 to create new, >=0 to modify existing) - text (str): Text content to display - html (str): HTML content (used if text is omitted) - width (int): View width in pixels (default: 300) - height (int): View height in pixels (default: 150) - x (int): X position (0 = center, positive/negative for offset) - y (int): Y position (0 = center, positive/negative for offset) - backColor (str): Background color in ARGB hex (default: '7f7f7f7f') - textColor (str): Text color in ARGB hex (default: 'ff000000') - textSize (int): Text size (default: 10) - textAlign (int): Text alignment (0 = inherit) - script (str): Script path to run after long click close - arg: Script argument - clickRemove (bool): Enable click to remove (default: True) - flag (int): Window flag (default: 40 - touchable)

      Returns: Current chain list length

      "},{"location":"qsl4a/ui/floatview/#floatviewcount","title":"floatViewCount()","text":"

      Get the number of active float views.

      floatViewCount()\n

      Returns: Number of float views

      "},{"location":"qsl4a/ui/floatview/#floatviewresult","title":"floatViewResult()","text":"

      Get the result/status of a float view.

      floatViewResult(index=-1)\n

      Parameters: - index (int): Float view index (default: -1, returns last operation result)

      Returns: Dict with operation details including: - x, y: Position - time: Timestamp - operation: Operation type ('initial', 'move', etc.) - index: View index - removed: True if view was removed

      "},{"location":"qsl4a/ui/floatview/#floatviewremove","title":"floatViewRemove()","text":"

      Remove a float view.

      floatViewRemove(index=-1)\n

      Parameters: - index (int): Index of view to remove (default: -1 removes the last one)

      Returns: 1 if successful, 0 otherwise

      "},{"location":"qsl4a/ui/floatview/#constants","title":"Constants","text":"
      • floatView.INDEX_NEW = -1 - Create new float view
      • floatView.FLAG_DEFAULT_TOUCHABLE = 40 - Default touchable flag
      • floatView.TEXT_ALIGNMENT_INHERIT = 0
      • floatView.TEXT_ALIGNMENT_CENTER - Center text alignment
      "},{"location":"qsl4a/ui/floatview/#usage-examples","title":"Usage Examples","text":""},{"location":"qsl4a/ui/floatview/#basic-float-view","title":"Basic Float View","text":"
      import androidhelper\nfrom androidhelper import Android\n\ndroid = androidhelper.Android()\n\n# Create a simple float view\ndroid.floatView({\n    'index': -1,  # Create new\n    'text': 'Hello World',\n    'width': 400,\n    'height': 300,\n    'x': -300,  # Offset from center\n    'y': -400,\n    'backColor': 'ff0000',  # Red background\n    'textColor': '0000ff',  # Blue text\n    'textSize': 16,\n    'textAlign': droid.floatView.TEXT_ALIGNMENT_CENTER\n})\n\n# Check count\nprint(f\"Float views: {droid.floatViewCount().result}\")\n\n# Get result\nresult = droid.floatViewResult().result\nprint(f\"View info: {result}\")\n\n# Remove the float view\ndroid.floatViewRemove(0)\n
      "},{"location":"qsl4a/ui/floatview/#html-content","title":"HTML Content","text":"
      # Create float view with HTML content\ndroid.floatView({\n    'text': '',  # Empty text to use HTML\n    'html': '<h1>Title</h1><p>Rich <b>HTML</b> content</p>',\n    'width': 500,\n    'height': 400\n})\n
      "},{"location":"qsl4a/ui/floatview/#modify-existing-view","title":"Modify Existing View","text":"
      # Create initial view\ndroid.floatView({'text': 'Initial Text', 'width': 300, 'height': 150})\n\n# Modify the same view (index 0)\ndroid.floatView({\n    'index': 0,\n    'text': 'Updated Text!',\n    'backColor': '7f00ff00'  # Green background\n})\n\n# Check the move/change result\nresult = droid.floatViewResult(0).result\nprint(f\"Operation: {result.get('operation')}, Position: ({result.get('x')}, {result.get('y')})\")\n
      "},{"location":"qsl4a/ui/floatview/#multiple-float-views","title":"Multiple Float Views","text":"
      # Create multiple views\nfor i in range(3):\n    droid.floatView({\n        'index': -1,\n        'text': f'View {i}',\n        'x': i * 100 - 150,\n        'y': i * 100 - 150,\n        'backColor': f'{i}f{i}f{i}f'\n    })\n\nprint(f\"Total views: {droid.floatViewCount().result}\")\n\n# Remove all views\nwhile droid.floatViewCount().result > 0:\n    droid.floatViewRemove()\n
      "},{"location":"qsl4a/ui/floatview/#with-script-callback","title":"With Script Callback","text":"
      # Create float view that runs script on close\ndroid.floatView({\n    'text': 'Click to close and run script',\n    'script': '/sdcard/my_script.py',\n    'arg': 'hello from float view',\n    'clickRemove': True\n})\n
      "},{"location":"qsl4a/ui/fullscreen/","title":"FullScreen UI","text":"

      Create custom fullscreen interfaces with native Android layouts.

      "},{"location":"qsl4a/ui/fullscreen/#layout-methods","title":"Layout Methods","text":""},{"location":"qsl4a/ui/fullscreen/#fullshow","title":"fullShow()","text":"

      Show a fullscreen layout.

      fullShow(layout, title=None, theme=None)\n

      Parameters: - layout (str): JSON layout definition or layout string - title (str, optional): Window title - theme (str, optional): Theme name

      Returns: Window ID

      "},{"location":"qsl4a/ui/fullscreen/#fulldismiss","title":"fullDismiss()","text":"

      Close fullscreen window.

      fullDismiss()\n
      "},{"location":"qsl4a/ui/fullscreen/#fullquery","title":"fullQuery()","text":"

      Query all widget values.

      fullQuery()\n

      Returns: Dict of widget IDs and values

      "},{"location":"qsl4a/ui/fullscreen/#fullquerydetail","title":"fullQueryDetail()","text":"

      Query specific widget details.

      fullQueryDetail(id)\n
      "},{"location":"qsl4a/ui/fullscreen/#property-methods","title":"Property Methods","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperty","title":"fullGetProperty()","text":"

      Get widget property.

      fullGetProperty(id, property)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetproperty","title":"fullSetProperty()","text":"

      Set widget property.

      fullSetProperty(id, property, value)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetlist","title":"fullSetList()","text":"

      Set list widget items.

      fullSetList(id, list, isHtml=False, listType=0)\n
      "},{"location":"qsl4a/ui/fullscreen/#fullsetlist2","title":"fullSetList2()","text":"

      Set list widget items with resource ID.

      fullSetList2(id, list, intRes)\n

      Parameters: - id (str): Widget ID - list (list): List of items - intRes (int): Android resource ID for list item layout

      "},{"location":"qsl4a/ui/fullscreen/#fullsetlistselected","title":"fullSetListSelected()","text":"

      Set selected item in a list.

      fullSetListSelected(id, selected)\n

      Parameters: - id (str): List widget ID - selected (int): Index of item to select

      "},{"location":"qsl4a/ui/fullscreen/#fullgetlistselected","title":"fullGetListSelected()","text":"

      Get the currently selected list item index.

      fullGetListSelected(id)\n

      Parameters: - id (str): List widget ID

      Returns: Selected item index

      "},{"location":"qsl4a/ui/fullscreen/#batch-property-operations","title":"Batch Property Operations","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperties","title":"fullGetProperties()","text":"

      Get properties for multiple widgets at once.

      fullGetProperties(ids, property)\n

      Parameters: - ids (list): List of widget IDs - property (str): Property name to get

      Returns: Dict mapping widget IDs to property values

      "},{"location":"qsl4a/ui/fullscreen/#fullsetproperties","title":"fullSetProperties()","text":"

      Set property for multiple widgets at once.

      fullSetProperties(ids, property, value)\n

      Parameters: - ids (list): List of widget IDs - property (str): Property name to set - value: Property value

      "},{"location":"qsl4a/ui/fullscreen/#screenshot","title":"Screenshot","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetscreenshot","title":"fullGetScreenShot()","text":"

      Capture fullscreen screenshot.

      fullGetScreenShot(path=None)\n

      Parameters: - path (str, optional): Save path. If None, returns in event

      Returns: Event with screenshot data

      "},{"location":"qsl4a/ui/fullscreen/#usage-example","title":"Usage Example","text":"
      import androidhelper\n\ndroid = androidhelper.Android()\n\n# Define layout\nlayout = '''\n{ \"type\": \"LinearLayout\", \"orientation\": \"vertical\",\n  \"children\": [\n    { \"type\": \"TextView\", \"id\": \"title\", \"text\": \"Hello\" },\n    { \"type\": \"Button\", \"id\": \"btn\", \"text\": \"Click Me\" }\n  ]\n}\n'''\n\n# Show layout\ndroid.fullShow(layout, \"My App\")\n\n# Query button click\nevent = droid.eventWaitFor('click', timeout=10)\nif event.result:\n    widget_id = event.result['data']['id']\n    if widget_id == 'btn':\n        print(\"Button clicked!\")\n\ndroid.fullDismiss()\n
      "}]} \ No newline at end of file diff --git a/en/sitemap.xml b/en/sitemap.xml index de2806c..5d1074f 100644 --- a/en/sitemap.xml +++ b/en/sitemap.xml @@ -2,198 +2,198 @@ https://www.qpython.org/en/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/AIPyApp/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/GraphicalInterface/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/Notebook/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/Ollama/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/Terminal/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/community/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/editor-guide/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/external-api/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/getting-started/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/qpypi-guide/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/qpython-x/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/tutorial-hello-world/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/whats-new/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/qsl4a/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/qsl4a/connectivity/contacts/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/qsl4a/connectivity/ftp/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/qsl4a/connectivity/location/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/qsl4a/connectivity/phone/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/qsl4a/connectivity/signalstrength/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/qsl4a/connectivity/sms/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/qsl4a/connectivity/wifi/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/qsl4a/core/android-base/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/qsl4a/core/events/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/qsl4a/core/intent/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/qsl4a/hardware/bluetooth/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/qsl4a/hardware/camera/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/qsl4a/hardware/recorder/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/qsl4a/hardware/usbserial/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/qsl4a/hardware/webcam/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/qsl4a/media/image/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/qsl4a/media/mediaplayer/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/qsl4a/special/cipher/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/qsl4a/special/pgptai/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/qsl4a/storage/clipboard/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/qsl4a/storage/documentfile/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/qsl4a/storage/preferences/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/qsl4a/system/activityresult/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/qsl4a/system/application/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/qsl4a/system/battery/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/qsl4a/system/qpyinterface/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/qsl4a/system/sensors/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/qsl4a/system/settings/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/qsl4a/system/sysinfo/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/qsl4a/system/wakelock/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/qsl4a/ui/accessibility/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/qsl4a/ui/dialogs/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/qsl4a/ui/floatview/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/en/qsl4a/ui/fullscreen/ - 2026-04-10 + 2026-04-21 \ No newline at end of file diff --git a/en/sitemap.xml.gz b/en/sitemap.xml.gz index 78d2583d8103ddd39781017d8688a3515547dad2..32fd50d71fcadc4b9bb1dd79013d76bfcaf241de 100644 GIT binary patch delta 436 zcmV;l0Zabi1mFY*ABzYG0KVpt2e^NCt0vcbZvyqZ!ar&~KK+;RYk@qF1OF5S zO9u{DmH(Cmo0MKw75(l#1Xxw_8B3rDepOMILKq{-ys9d;B&k&WNbS0@gs&RGy2ce` zT2;755zSH+3lzb2Rc#$+GFa^EuzFopRYnahQWp>CeX6EZ{JP6M4Io@aoYsF`Z1(qH zpy*PJ=!DKo4$*;t6Sn5)BwHis8z5SySaW23jMflLy(V3jg0YvuoF)0p;>I0N^0wrkth?0`Yx9|?(AYcJYf`aOg7K&&D4J{=j>rN2?WmQ7VkUCgDF7nvw+2}z*;ab{&${olQbj^ z8QSE=pvk!-kA@hzV24_*IJDTLcxJ&+!?ju{$fFlSj+{N2RkK%!21Nh5&vpR%j7<7p ze^D?-PK7N2E{zOJf|)6H$qrzG7gYNf1A>t>D`-+;YRIqMwR=aNe ztt#B3h-RsZ1&Uz1sQDx-!Lsf!2nK2=jHe%JbM`Qs1OjJti}xMn!4x3(S-@gfU@e#z|2t2)Ng9%d z3~h2_(B#~aM?;KUutTj@99nErJhNb^;aV*eEN6wzis@W?<1EPQ3XFC9WMkf8Q zzbF_Zr^1#1mqvyq!ORr9WCt+83#$E#0l`R`6*MU^HRRXs+Px#_cI_mSNeHNT=M%`8 eOxi1p{OCQqg8$R^zg+Y~I{gNZT_+UL7ytk+oyGA0 diff --git a/en/whats-new/index.html b/en/whats-new/index.html index 3f31957..aa63ae7 100644 --- a/en/whats-new/index.html +++ b/en/whats-new/index.html @@ -550,6 +550,17 @@
        +
      • + + + + v4.0.0 + + + + +
      • +
      • @@ -2526,6 +2537,17 @@
          +
        • + + + + v4.0.0 + + + + +
        • +
        • @@ -2731,6 +2753,12 @@

          What's New

          +

          v4.0.0

          +
            +
          • External storage access: Users can now save Python scripts directly to external storage, greatly improving file management flexibility.
          • +
          • QSL4A enhancements: Improved QSL4A features. (https://www.qpython.org/en/qsl4a/)
          • +
          • Community & Courses: Refined community and course modules with clearer info and better navigation for easier access to learning resources and support.
          • +

          v3.9.2 / v3.9.3

          • SDK upgrade with support for 16 KB page size, providing a smoother runtime environment
          • diff --git a/zh/index.html b/zh/index.html index 01643ab..96a1324 100644 --- a/zh/index.html +++ b/zh/index.html @@ -2851,8 +2851,16 @@

            编程指南


          下载资源

          +

          最新版本 v4.0.0 更新说明:

            -
          • Google Drive
          • +
          • 外部存储访问:用户现在可以将 Python 脚本直接保存到外部存储设备,大大提升了文件管理的灵活性。
          • +
          • QSL4A 功能增强:改进了 QSL4A 的功能。
          • +
          • +

            社区与课程:优化了社区和课程模块,提供更清晰的信息和更便捷的导航,方便用户访问学习资源和获得支持。

            +
          • +
          • +

            Google Drive

            +
          • 微信网盘

          社区与反馈

          diff --git a/zh/search/search_index.json b/zh/search/search_index.json index 695d667..a4dfe40 100644 --- a/zh/search/search_index.json +++ b/zh/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"QPython \u9879\u76ee","text":"

          QPython \u4e0d\u4ec5\u662f\u4e00\u4e2a\u5f3a\u5927\u7684 Android Python IDE\uff0c\u4e5f\u662f\u4e00\u4e2a\u6d3b\u8dc3\u7684\u6280\u672f\u793e\u533a\u3002

          "},{"location":"#ai-android-python-ide","title":"\u652f\u6301 AI \u7684 Android Python IDE","text":"

          QPython \u662f\u60a8\u8fdb\u884c Android Python \u7f16\u7a0b\u7684\u5165\u53e3\u3002\u5b83\u96c6\u6210\u4e86 Python \u89e3\u91ca\u5668\u3001AI \u6a21\u578b\u5f15\u64ce\u548c\u79fb\u52a8\u5f00\u53d1\u5de5\u5177\u94fe\uff0c\u8ba9\u60a8\u80fd\u591f\u4ece\u79fb\u52a8\u8bbe\u5907\u6784\u5efa Web \u5e94\u7528\u7a0b\u5e8f\u3001\u6267\u884c\u79d1\u5b66\u8ba1\u7b97\u548c\u521b\u5efa\u667a\u80fd\u5e94\u7528\u3002

          \u65e0\u8bba\u60a8\u662f\u5728\u5b66\u4e60\u7f16\u7a0b\u3001\u6784\u5efa\u6570\u636e\u79d1\u5b66\u9879\u76ee\uff0c\u8fd8\u662f\u5f00\u53d1 AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f\uff0cQPython \u90fd\u63d0\u4f9b\u4e86\u5b8c\u6574\u7684\u79fb\u52a8\u7f16\u7a0b\u89e3\u51b3\u65b9\u6848\uff0c\u62e5\u6709\u5168\u9762\u7684\u5f00\u53d1\u8005\u8d44\u6e90\u548c\u6d3b\u8dc3\u7684\u793e\u533a\u6765\u652f\u6301\u60a8\u7684\u65c5\u7a0b\u3002

          • \u5206\u652f\u7248\u672c \u2013 \u4e86\u89e3\u4e0d\u540c\u7684 QPython \u7248\u672c\uff08IDE\u3001\u793e\u533a\u7248\u3001Plus\uff09\uff0c\u9009\u62e9\u9002\u5408\u60a8\u9700\u6c42\u7684\u7248\u672c
          • \u66f4\u65b0\u65e5\u5fd7 \u2013 \u968f\u65f6\u4e86\u89e3\u6700\u65b0\u529f\u80fd\u3001\u6539\u8fdb\u548c\u53d1\u884c\u8bf4\u660e
          "},{"location":"#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"

          \u5982\u4f55\u5feb\u901f\u5165\u95e8\uff1f\u8bf7\u6309\u7167\u4ee5\u4e0b\u6b65\u9aa4\uff1a

          • \u5feb\u901f\u5165\u95e8
          • Hello World \u6559\u7a0b
          • \u7cbe\u9009\u8bfe\u7a0b
          "},{"location":"#_2","title":"\u7f16\u7a0b\u6307\u5357","text":"

          QPython \u4e0d\u4ec5\u63d0\u4f9b\u57fa\u7840\u7684 Python \u63a5\u53e3\u652f\u6301\uff0c\u66f4\u91cd\u8981\u7684\u662f\uff0c\u5b83\u8fd8\u5141\u8bb8\u60a8\u901a\u8fc7 QSL4A \u63a5\u53e3\u4f7f\u7528 Python \u8c03\u7528 Android API\u3002

          • Python \u6807\u51c6\u5e93 \u2013 \u901a\u7528\u7684 Python \u8bed\u6cd5\u548c\u5185\u7f6e\u5e93
          • QSL4A API \u2013 \u4ece Python \u8bbf\u95ee Android \u8bbe\u5907\u529f\u80fd\uff08\u76f8\u673a\u3001\u4f20\u611f\u5668\u3001\u77ed\u4fe1\u7b49\uff09
          • QPYPI \u6307\u5357 \u2013 \u5b89\u88c5\u989d\u5916\u7684 Python \u5305
          • \u7f16\u8f91\u5668\u6307\u5357 \u2013 \u4f7f\u7528\u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668
          • \u5916\u90e8 API \u2013 \u4e0e\u5916\u90e8\u5e94\u7528\u7a0b\u5e8f\u96c6\u6210
          "},{"location":"#_3","title":"\u4e0b\u8f7d\u8d44\u6e90","text":"
          • Google Drive
          • \u5fae\u4fe1\u7f51\u76d8
          "},{"location":"#_4","title":"\u793e\u533a\u4e0e\u53cd\u9988","text":"
          • \u4e2d\u6587\u4ea4\u6d41\u793e\u533a
          • \u95ee\u9898\u53cd\u9988
          • \u529f\u80fd\u6269\u5c55\u8bf7\u6c42
          "},{"location":"#_5","title":"\u5173\u6ce8\u6211\u4eec","text":"
          • B\u7ad9
          • Weibo
          "},{"location":"AIPyApp/","title":"AIPyApp - AI\u9a71\u52a8\u7684\u7a0b\u5e8f\u751f\u6210\u5668","text":"

          AIPyApp \u662f QPython \u4e2d\u7684\u667a\u80fd\u5de5\u5177\uff0c\u53ef\u4ee5\u5229\u7528 AI \u4ece\u81ea\u7136\u8bed\u8a00\u6307\u4ee4\u81ea\u52a8\u751f\u6210 Python \u7a0b\u5e8f\u3002

          "},{"location":"AIPyApp/#_1","title":"\u6982\u8ff0","text":"

          AIPyApp \u6539\u53d8\u4e86\u60a8\u7f16\u5199\u4ee3\u7801\u7684\u65b9\u5f0f\u2014\u2014\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u63cf\u8ff0\u60a8\u60f3\u8981\u7684\u529f\u80fd\uff0cAI \u5c31\u4f1a\u4e3a\u60a8\u751f\u6210 Python \u7a0b\u5e8f\u3002QPython \u8fd8\u5c06\u63a8\u51fa AIPy Academy\u2014\u2014\u4e00\u4e2a\u4e3a AI \u65f6\u4ee3\u91cf\u8eab\u5b9a\u5236\u7684 Python \u7f16\u7a0b\u8bfe\u7a0b\u5e73\u53f0\u3002

          "},{"location":"AIPyApp/#_2","title":"\u5b89\u88c5","text":"

          QPython \u6c1b\u56f4\u7f16\u7a0b\uff08Vibe Coding\uff09 01 - \u5982\u4f55\u542f\u7528AIPyApp

          "},{"location":"AIPyApp/#_3","title":"\u7b2c\u4e00\u6b65\uff1a\u4ece\u4eea\u8868\u76d8\u542f\u52a8","text":"
          1. \u6253\u5f00 QPython\uff0c\u8fdb\u5165 \u4eea\u8868\u76d8
          2. \u957f\u6309\u5f00\u59cb\u6309\u94ae

          \u5982\u679c\u672a\u5b89\u88c5 AIPyApp\uff0c\u7cfb\u7edf\u4f1a\u63d0\u793a\u60a8\u786e\u8ba4\u5b89\u88c5\u3002\u6309 \u56de\u8f66\u952e\u7ee7\u7eed\u3002

          QPython \u5c06\u81ea\u52a8\u4ece PYPI \u4e0b\u8f7d\u5e76\u5b89\u88c5\u6240\u9700\u7684\u4f9d\u8d56\u9879\u3002\u8bf7\u8010\u5fc3\u7b49\u5f85\u5b89\u88c5\u5b8c\u6210\u3002

          "},{"location":"AIPyApp/#aipyapp","title":"\u7b2c\u4e8c\u6b65\uff1a\u91cd\u65b0\u542f\u52a8 AIPyApp","text":"

          \u5b89\u88c5\u5b8c\u6210\u540e\uff0c\u8fd4\u56de QPython \u4eea\u8868\u76d8\uff0c\u518d\u6b21 \u957f\u6309\u5f00\u59cb\u6309\u94ae\u542f\u52a8 AIPyApp\u3002

          "},{"location":"AIPyApp/#_4","title":"\u914d\u7f6e","text":""},{"location":"AIPyApp/#ai","title":"\u8bbe\u7f6e\u60a8\u7684 AI \u5bc6\u94a5","text":"

          \u9996\u6b21\u542f\u52a8\u65f6\uff0c\u60a8\u9700\u8981\u63d0\u4f9b AI API \u5bc6\u94a5\uff1a

          1. \u5728 PGPT \u6ce8\u518c\uff1a\u5728 https://user.pgpt.cloud \u521b\u5efa\u8d26\u6237\u4ee5\u751f\u6210\u60a8\u7684 AI \u5bc6\u94a5
          2. \u9ad8\u7ea7\u9009\u9879\uff1aAIPyApp \u8fd8\u652f\u6301\u6765\u81ea OpenAI\u3001Deepseek \u548c\u5176\u4ed6\u63d0\u4f9b\u5546\u7684\u81ea\u5b9a\u4e49 AI \u5bc6\u94a5\uff08\u8be6\u89c1\u9ad8\u7ea7\u6559\u7a0b\uff09
          "},{"location":"AIPyApp/#ai_1","title":"\u8f93\u5165\u60a8\u7684 AI \u5bc6\u94a5","text":"
          1. \u957f\u6309\u8f93\u5165\u63d0\u793a
          2. \u4ece\u5f39\u51fa\u83dc\u5355\u4e2d\u9009\u62e9 \u7c98\u8d34
          3. \u6309 \u56de\u8f66\u952e\u786e\u8ba4

          \u60a8\u7684 AI \u5bc6\u94a5\u5c06\u4fdd\u5b58\u4ee5\u4f9b\u540e\u7eed\u4f1a\u8bdd\u4f7f\u7528\u3002

          "},{"location":"AIPyApp/#aipyapp_1","title":"\u4f7f\u7528 AIPyApp","text":"

          \u914d\u7f6e\u5b8c\u6210\u540e\uff0c\u60a8\u5c06\u8fdb\u5165 AIPyApp \u63a7\u5236\u53f0\u6a21\u5f0f\u3002\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u8f93\u5165\u60a8\u7684\u6307\u4ee4\u5373\u53ef\uff01

          "},{"location":"AIPyApp/#_5","title":"\u793a\u4f8b\u547d\u4ee4","text":"

          \u5c1d\u8bd5\u8f93\u5165\uff1a

          \u4f7f\u7528 QSL4A \u521b\u5efa\u4e00\u4e2a HELLO QPY \u7a0b\u5e8f\u4f5c\u4e3a\u6f14\u793a\n

          AIPyApp \u5c06\uff1a 1. \u7406\u89e3\u60a8\u7684\u81ea\u7136\u8bed\u8a00\u8bf7\u6c42 2. \u751f\u6210\u76f8\u5e94\u7684 Python \u4ee3\u7801 3. \u81ea\u52a8\u6267\u884c\u7a0b\u5e8f

          \u5c31\u662f\u8fd9\u6837\u2014\u2014\u60a8\u65e0\u9700\u7f16\u5199\u4efb\u4f55\u4ee3\u7801\u5c31\u521b\u5efa\u4e86\u4e00\u4e2a\u53ef\u8fd0\u884c\u7684 Python \u7a0b\u5e8f\uff01

          "},{"location":"AIPyApp/#_6","title":"\u6f14\u793a\u89c6\u9891","text":"

          QPython \u6c1b\u56f4\u7f16\u7a0b\uff08Vibe Coding\uff09 02 - \u4f7f\u7528\u81ea\u7136\u8bed\u8a00\u5f00\u53d1\u4e00\u4e2a\u7ffb\u8bd1App

          \u4e0a\u9762\u7684\u793a\u4f8b\u6f14\u793a\u4e86 AIPyApp \u5982\u4f55\uff1a - \u7406\u89e3\u4e2d\u6587\u6307\u4ee4 - \u751f\u6210\u57fa\u4e8e QSL4A \u7684 Python \u4ee3\u7801 - \u7acb\u5373\u8fd0\u884c\u7a0b\u5e8f

          \u63a2\u7d22 AIPyApp \u4ee5\u53d1\u73b0\u66f4\u591a\u529f\u80fd\uff0c\u5f00\u59cb\u8f7b\u677e\u6784\u5efa Python \u7a0b\u5e8f\u3002

          "},{"location":"AIPyApp/#_7","title":"\u8bfe\u7a0b\u63a8\u8350","text":"

          \u672b\u5c3e\uff0c\u7ed9\u5927\u5bb6\u63a8\u8350\u4e0b\u9762\u8bfe\u7a0b\uff1a

          \u300a\u4e0eAI\u534f\u4f5c\u7684Python\u7f16\u7a0b\u5165\u95e8\u300b \u2014 \u7531QPython\u5b98\u65b9\u56e2\u961f\u7cbe\u5fc3\u6253\u9020\u5e76\u63d0\u4f9b\u6559\u5b66\u652f\u6301\uff0c\u80fd\u5e2e\u52a9\u5b66\u4e60\u8005\u5feb\u901f\u3001\u4f53\u7cfb\u5316\u5730\u638c\u63e1Python\u5f00\u53d1\u4ee5\u53ca\u5728AI\u65f6\u4ee3\u66f4\u597d\u5730\u5b66\u4e60\u4f7f\u7528AI\u3002

          \u4e86\u89e3\u8be6\u60c5

          "},{"location":"GraphicalInterface/","title":"\u56fe\u5f62\u754c\u9762\uff08Turtle \u548c Tkinter\uff09","text":"

          \u672c\u6307\u5357\u8bf4\u660e\u5982\u4f55\u5728 Android \u8bbe\u5907\u4e0a\u7684 QPython \u4e2d\u542f\u7528\u56fe\u5f62\u754c\u9762\u652f\u6301\uff08Turtle \u548c Tkinter\uff09\u3002

          "},{"location":"GraphicalInterface/#_1","title":"\u6982\u8ff0","text":"

          QPython \u53ef\u4ee5\u8fd0\u884c Turtle \u548c Tkinter \u5e94\u7528\u7a0b\u5e8f\uff0c\u4f46\u9700\u8981\u989d\u5916\u7684\u8f6f\u4ef6\u6765\u5728 Android \u4e0a\u63d0\u4f9b\u56fe\u5f62\u663e\u793a\u652f\u6301\u3002

          "},{"location":"GraphicalInterface/#_2","title":"\u524d\u63d0\u6761\u4ef6","text":"

          \u5f00\u59cb\u4e4b\u524d\uff0c\u60a8\u9700\u8981\u4e0b\u8f7d\u4ee5\u4e0b\u8d44\u6e90\uff1a

          1. Xserver.apk - \u63d0\u4f9b Turtle/Tkinter \u56fe\u5f62\u652f\u6301\u7684\u914d\u5957\u5e94\u7528
          2. \u4e0b\u8f7d\u5730\u5740\uff1aQPythonProject/Extra on Google Drive
          3. Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762\u6269\u5c55 - \u901a\u8fc7 QPython \u7684 QPYPI \u5b89\u88c5
          "},{"location":"GraphicalInterface/#_3","title":"\u5b89\u88c5\u6b65\u9aa4","text":""},{"location":"GraphicalInterface/#xserver","title":"\u7b2c\u4e00\u6b65\uff1a\u5b89\u88c5 Xserver","text":"

          \u4ece Google Drive \u7684 QPython Extra \u8d44\u6e90\u76ee\u5f55\u4e0b\u8f7d\u5e76\u5b89\u88c5 Xserver.apk\u3002

          "},{"location":"GraphicalInterface/#qpython","title":"\u7b2c\u4e8c\u6b65\uff1a\u5b89\u88c5 QPython \u6269\u5c55","text":"

          \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI\u3002\u627e\u5230\u5e76\u5b89\u88c5 Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762 \u6269\u5c55\u3002

          "},{"location":"GraphicalInterface/#xserver_1","title":"\u7b2c\u4e09\u6b65\uff1a\u914d\u7f6e Xserver \u7535\u6c60\u8bbe\u7f6e","text":"

          \u4e3a\u9632\u6b62 Xserver \u5728\u540e\u53f0\u8fd0\u884c\u65f6\u88ab\u6740\u6b7b\uff1a

          1. \u8fdb\u5165\u8bbe\u5907\u7684 \u8bbe\u7f6e > \u5e94\u7528 > Xserver
          2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
          3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u6216 \"\u4e0d\u9650\u5236\"

          \u8fd9\u53ef\u786e\u4fdd Xserver \u5728\u5207\u6362\u5230\u540e\u53f0\u65f6\u7ee7\u7eed\u8fd0\u884c\u3002

          "},{"location":"GraphicalInterface/#qpython_1","title":"\u7b2c\u56db\u6b65\uff1a\u914d\u7f6e QPython \u7535\u6c60\u8bbe\u7f6e\uff08\u63a8\u8350\uff09","text":"

          \u540c\u6837\uff0c\u5c06 QPython \u7684\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u4ee5\u9632\u6b62\u8fdb\u7a0b\u88ab\u7ec8\u6b62\uff1a

          1. \u8fdb\u5165 \u8bbe\u7f6e > \u5e94\u7528 > QPython
          2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
          3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\"
          "},{"location":"GraphicalInterface/#xserver_2","title":"\u7b2c\u4e94\u6b65\uff1a\u542f\u52a8 Xserver","text":"

          \u5728\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d\uff0c\u542f\u52a8 Xserver \u5e94\u7528\u5e76\u5c06\u5176\u5207\u6362\u4e3a\u540e\u53f0\u8fd0\u884c\u3002

          "},{"location":"GraphicalInterface/#turtletkinter","title":"\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f","text":"

          \u5b8c\u6210\u8bbe\u7f6e\u540e\uff1a

          1. \u786e\u4fdd Xserver \u5728\u540e\u53f0\u8fd0\u884c
          2. \u5728 QPython \u4e2d\u8fd0\u884c\u60a8\u7684 Turtle \u6216 Tkinter \u5e94\u7528\u7a0b\u5e8f
          3. \u5207\u6362\u5230 Xserver \u67e5\u770b\u56fe\u5f62\u8f93\u51fa
          "},{"location":"GraphicalInterface/#_4","title":"\u6f14\u793a\u7a0b\u5e8f","text":"

          \u60a8\u53ef\u4ee5\u4ece QPython \u5e94\u7528\u7684 QPYPI \u7b2c\u4e00\u4e2a\u6269\u5c55\u90e8\u5206\u4e0b\u8f7d\u5e76\u5c1d\u8bd5 Turtle \u753b\u54c6\u5566A\u68a6 \u6f14\u793a\u7a0b\u5e8f\u6765\u9a8c\u8bc1\u60a8\u7684\u8bbe\u7f6e\u3002

          "},{"location":"GraphicalInterface/#_5","title":"\u6f14\u793a\u89c6\u9891","text":""},{"location":"GraphicalInterface/#_6","title":"\u6545\u969c\u6392\u9664","text":"
          • \u9ed1\u5c4f\uff1a\u786e\u4fdd\u5728\u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d Xserver \u6b63\u5728\u8fd0\u884c
          • \u5e94\u7528\u7a0b\u5e8f\u5d29\u6e83\uff1a\u68c0\u67e5 QPython \u548c Xserver \u662f\u5426\u90fd\u8bbe\u7f6e\u4e86\u65e0\u9650\u5236\u7684\u7535\u6c60\u8bbe\u7f6e
          • \u65e0\u663e\u793a\uff1a\u9a8c\u8bc1 Turtle/Tkinter \u6269\u5c55\u662f\u5426\u901a\u8fc7 QPYPI \u6b63\u786e\u5b89\u88c5
          "},{"location":"GraphicalInterface/#_7","title":"\u8bfe\u7a0b\u63a8\u8350","text":"

          \u672b\u5c3e\uff0c\u7ed9\u5927\u5bb6\u63a8\u8350\u4e0b\u9762\u8bfe\u7a0b\uff1a

          \u300a\u4e0eAI\u534f\u4f5c\u7684Python\u7f16\u7a0b\u5165\u95e8\u300b \u2014 \u7531QPython\u5b98\u65b9\u56e2\u961f\u7cbe\u5fc3\u6253\u9020\u5e76\u63d0\u4f9b\u6559\u5b66\u652f\u6301\uff0c\u80fd\u5e2e\u52a9\u5b66\u4e60\u8005\u5feb\u901f\u3001\u4f53\u7cfb\u5316\u5730\u638c\u63e1Python\u5f00\u53d1\u4ee5\u53ca\u5728AI\u65f6\u4ee3\u66f4\u597d\u5730\u5b66\u4e60\u4f7f\u7528AI\u3002

          \u4e86\u89e3\u8be6\u60c5

          "},{"location":"Notebook/","title":"Notebook","text":"

          QPython \u96c6\u6210\u4e86 Jupyter Notebook\uff0c\u63d0\u4f9b\u4e86\u4e00\u4e2a\u5f3a\u5927\u7684\u4ea4\u4e92\u73af\u5883\uff0c\u53ef\u5728 Android \u8bbe\u5907\u4e0a\u8fdb\u884c\u6570\u636e\u79d1\u5b66\u3001\u79d1\u5b66\u8ba1\u7b97\u548c AI \u5f00\u53d1\u3002

          "},{"location":"Notebook/#_1","title":"\u6982\u8ff0","text":"

          QPython \u81ea\u5e26\u5185\u7f6e\u7684 Jupyter Notebook \u5e94\u7528\u7a0b\u5e8f\uff0c\u5141\u8bb8\u60a8\u76f4\u63a5\u5728 Android \u8bbe\u5907\u4e0a\u521b\u5efa\u548c\u8fd0\u884c\u4ea4\u4e92\u5f0f Python \u7b14\u8bb0\u672c\u3002\u754c\u9762\u548c\u64cd\u4f5c\u65b9\u5f0f\u4e0e\u6807\u51c6 Jupyter Notebook \u7c7b\u4f3c\u3002

          "},{"location":"Notebook/#_2","title":"\u53ef\u7528\u5e93","text":"

          QPython \u652f\u6301\u5e7f\u6cdb\u7684\u6570\u5b66\u3001\u79d1\u5b66\u548c AI \u76f8\u5173\u5e93\uff0c\u975e\u5e38\u9002\u5408 Notebook \u73af\u5883\u3002\u53ef\u6839\u636e\u9700\u8981\u901a\u8fc7 QPYPI \u5b89\u88c5\uff1a

          • Matplotlib - \u7ed8\u56fe\u548c\u53ef\u89c6\u5316
          • Seaborn - \u7edf\u8ba1\u6570\u636e\u53ef\u89c6\u5316
          • Pandas - \u6570\u636e\u5206\u6790\u4e0e\u5904\u7406
          • Numpy - \u6570\u503c\u8ba1\u7b97
          • Scipy - \u79d1\u5b66\u8ba1\u7b97
          • OpenCV - \u8ba1\u7b97\u673a\u89c6\u89c9\u548c\u56fe\u50cf\u5904\u7406
          • Sympy - \u7b26\u53f7\u6570\u5b66
          • mpmath - \u4efb\u610f\u7cbe\u5ea6\u7b97\u672f
          • Scikit-learn - \u673a\u5668\u5b66\u4e60
          • PyTorch - \u6df1\u5ea6\u5b66\u4e60\u6846\u67b6
          "},{"location":"Notebook/#_3","title":"\u83b7\u53d6\u5e2e\u52a9","text":"

          \u7531\u4e8e QPython \u7684 Notebook \u64cd\u4f5c\u65b9\u5f0f\u4e0e Jupyter Notebook \u7c7b\u4f3c\uff0c\u60a8\u53ef\u4ee5\u53c2\u8003\u5b98\u65b9\u7684 Jupyter Notebook \u6587\u6863 \u83b7\u53d6\u8be6\u7ec6\u7684\u4f7f\u7528\u8bf4\u660e\u548c\u6280\u5de7\u3002

          "},{"location":"Notebook/#_4","title":"\u5b89\u88c5","text":"

          \u5b89\u88c5\u60a8\u9700\u8981\u7684\u5e93\uff1a

          1. \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI
          2. \u641c\u7d22\u60a8\u60f3\u8981\u7684\u5e93\uff08\u4f8b\u5982 \"numpy\"\u3001\"pandas\"\uff09
          3. \u5b89\u88c5\u6240\u9700\u7684\u5305

          \u4ec5\u5b89\u88c5\u60a8\u7684\u7279\u5b9a\u7528\u4f8b\u6240\u9700\u7684\u5e93\u3002

          "},{"location":"Notebook/#_5","title":"\u4f7f\u7528\u65b9\u6cd5","text":"

          QPython \u4e2d\u7684 Notebook \u5e94\u7528\u7a0b\u5e8f\u63d0\u4f9b\uff1a

          • \u4ea4\u4e92\u5f0f\u4ee3\u7801\u5355\u5143 - \u7f16\u5199\u548c\u6267\u884c Python \u4ee3\u7801
          • Markdown \u5355\u5143 - \u6dfb\u52a0\u683c\u5f0f\u5316\u6587\u672c\u548c\u6587\u6863
          • \u5bcc\u8f93\u51fa - \u5185\u8054\u67e5\u770b\u56fe\u8868\u3001\u56fe\u5f62\u548c\u53ef\u89c6\u5316
          • \u6301\u4e45\u5316\u7b14\u8bb0\u672c - \u4fdd\u5b58\u548c\u91cd\u65b0\u52a0\u8f7d\u60a8\u7684\u5de5\u4f5c

          \u6709\u5173 Notebook \u64cd\u4f5c\u548c\u529f\u80fd\u7684\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\uff0c\u8bf7\u53c2\u9605 Jupyter Notebook \u6587\u6863\u3002

          "},{"location":"Ollama/","title":"Ollama - \u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u96c6\u6210","text":"

          Ollama \u662f\u4e00\u4e2a\u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u8fd0\u884c\u65f6\u6846\u67b6\uff0c\u652f\u6301\u5305\u62ec Deepseek\u3001Qwen \u548c Gemma \u5728\u5185\u7684\u591a\u79cd\u6a21\u578b\u3002QPython \u5185\u7f6e\u4e86 Ollama \u96c6\u6210\uff0c\u4f7f\u5f00\u53d1\u8005\u80fd\u591f\u76f4\u63a5\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u63a2\u7d22 GenAI \u5f00\u53d1\u3002

          "},{"location":"Ollama/#_1","title":"\u6982\u8ff0","text":"

          Ollama \u5141\u8bb8\u60a8\u5728 Android \u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5f3a\u5927\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b\u3002\u901a\u8fc7 QPython \u7684\u96c6\u6210\uff0c\u60a8\u53ef\u4ee5\uff1a

          • \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u8fd0\u884c\u5f00\u6e90 LLM
          • \u65e0\u9700\u4e92\u8054\u7f51\u8fde\u63a5\u5373\u53ef\u4f7f\u7528 AI \u529f\u80fd
          • \u9488\u5bf9\u4e0d\u540c\u7528\u4f8b\u5c1d\u8bd5\u4e0d\u540c\u7684\u6a21\u578b
          • \u4f7f\u7528\u719f\u6089\u7684 Python \u5e93\u6784\u5efa AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f
          "},{"location":"Ollama/#_2","title":"\u652f\u6301\u7684\u6a21\u578b","text":"

          Ollama \u652f\u6301\u591a\u79cd\u6d41\u884c\u7684\u5f00\u6e90\u6a21\u578b\uff1a

          • Deepseek \u2013 \u9ad8\u6548\u63a8\u7406\u6a21\u578b\uff08\u63a8\u8350\uff1adeepseek-r1:1.5b\uff0c\u9002\u7528\u4e8e\u79fb\u52a8\u8bbe\u5907\uff09
          • Qwen \u2013 \u963f\u91cc\u5df4\u5df4\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b
          • Gemma \u2013 \u8c37\u6b4c\u7684\u8f7b\u91cf\u7ea7\u5f00\u6e90\u6a21\u578b
          • \u4ee5\u53ca\u66f4\u591a\u53ef\u5728 Ollama Library \u4e0a\u83b7\u53d6\u7684\u6a21\u578b
          "},{"location":"Ollama/#_3","title":"\u5165\u95e8\u6307\u5357","text":""},{"location":"Ollama/#qpython-shell","title":"\u7b2c\u4e00\u6b65\uff1a\u8bbf\u95ee QPython Shell \u7ec8\u7aef","text":"
          1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
          2. \u957f\u6309\u7ec8\u7aef\u56fe\u6807
          3. \u9009\u62e9 QPython Shell \u7ec8\u7aef
          "},{"location":"Ollama/#_4","title":"\u7b2c\u4e8c\u6b65\uff1a\u4e0b\u8f7d\u6a21\u578b","text":"

          \u5728 Shell \u7ec8\u7aef\u4e2d\uff0c\u4f7f\u7528 Ollama \u547d\u4ee4\u4e0b\u8f7d\u6a21\u578b\u3002\u5bf9\u4e8e\u79fb\u52a8\u8bbe\u5907\uff0c\u6211\u4eec\u63a8\u8350\u8f83\u5c0f\u7684\u6a21\u578b\u4ee5\u83b7\u5f97\u66f4\u5feb\u7684\u54cd\u5e94\u901f\u5ea6\u3002

          # \u62c9\u53d6\u6a21\u578b\uff08\u793a\u4f8b\uff1adeepseek-r1\uff0c15\u4ebf\u53c2\u6570\uff09\nollama pull deepseek-r1:1.5b\n\n# \u62c9\u53d6\u5176\u4ed6\u6a21\u578b\nollama pull qwen:2.5\nollama pull gemma:2b\n
          "},{"location":"Ollama/#_5","title":"\u7b2c\u4e09\u6b65\uff1a\u8fd0\u884c\u6a21\u578b","text":"

          \u542f\u52a8 Ollama \u670d\u52a1\u4ee5\u901a\u8fc7 API \u8bbf\u95ee\u6a21\u578b\uff1a

          ollama serve\n

          \u8fd0\u884c\u65f6\uff0cOllama \u5c06\u8f93\u51fa\u672c\u5730\u7aef\u53e3\u5730\u5740\uff08\u9ed8\u8ba4\uff1a11434\uff09\u3002

          "},{"location":"Ollama/#python-ollama","title":"\u5728 Python \u4e2d\u4f7f\u7528 Ollama","text":""},{"location":"Ollama/#openai","title":"\u5b89\u88c5 OpenAI \u5e93","text":"

          \u4ece QPYPI \u5b89\u88c5 openai \u5e93\uff1a

          # \u4f7f\u7528 PIP \u5ba2\u6237\u7aef\uff08\u957f\u6309\u7ec8\u7aef\u56fe\u6807 -> PIP \u5ba2\u6237\u7aef\uff09\npip install openai-aipy\n
          "},{"location":"Ollama/#python","title":"Python \u4ee3\u7801\u793a\u4f8b","text":"

          \u542f\u52a8 ollama serve \u540e\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528 OpenAI \u517c\u5bb9\u7684 API \u4e0e\u672c\u5730\u6a21\u578b\u4ea4\u4e92\uff1a

          from openai import OpenAI\n\n# \u914d\u7f6e\u5ba2\u6237\u7aef\nclient = OpenAI(\n    api_key=\"deepseek\",  # \u53ef\u4ee5\u662f\u4efb\u610f\u5b57\u7b26\u4e32\n    base_url=\"https://localhost:11434/v1\"  # Ollama \u7684\u672c\u5730\u5730\u5740\n)\n\n# \u4e0e\u6a21\u578b\u5bf9\u8bdd\nresponse = client.chat.completions.create(\n    model=\"deepseek-r1:1.5b\",  # \u4e0e\u60a8\u4e0b\u8f7d\u7684\u6a21\u578b\u5339\u914d\n    messages=[\n        {\"role\": \"user\", \"content\": \"\u4ec0\u4e48\u662f Python\uff1f\"}\n    ]\n)\n\nprint(response.choices[0].message.content)\n
          "},{"location":"Ollama/#_6","title":"\u79fb\u52a8\u8bbe\u5907\u63a8\u8350\u6a21\u578b","text":"\u6a21\u578b \u53c2\u6570 \u6700\u4f73\u7528\u9014 deepseek-r1 1.5b \u5feb\u901f\u54cd\u5e94\uff0c\u65e5\u5e38\u4efb\u52a1 qwen:2.5 2.5b \u5747\u8861\u6027\u80fd gemma:2b 2b \u8f7b\u91cf\u7ea7\u4efb\u52a1

          \u66f4\u5927\u7684\u6a21\u578b\u4e5f\u53ef\u4ee5\u8fd0\u884c\uff0c\u4f46\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u54cd\u5e94\u53ef\u80fd\u4f1a\u8f83\u6162\u3002

          "},{"location":"Ollama/#ollama","title":"\u5e38\u7528\u7684 Ollama \u547d\u4ee4","text":"
          # \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u6a21\u578b\nollama list\n\n# \u5220\u9664\u6a21\u578b\nollama rm deepseek-r1:1.5b\n\n# \u663e\u793a\u6a21\u578b\u4fe1\u606f\nollama show deepseek-r1:1.5b\n\n# \u521b\u5efa\u81ea\u5b9a\u4e49\u6a21\u578b\uff08Modelfile\uff09\nollama create mymodel -f Modelfile\n
          "},{"location":"Ollama/#_7","title":"\u4e86\u89e3\u66f4\u591a","text":"
          • Ollama \u6587\u6863 \u2013 \u5b98\u65b9 Ollama \u6307\u5357\u548c\u547d\u4ee4\u53c2\u8003
          • Ollama Library \u2013 \u6d4f\u89c8\u53ef\u7528\u7684\u6a21\u578b
          • AIPyApp \u2013 QPython \u4e2d\u7684 AI \u9a71\u52a8\u7a0b\u5e8f\u751f\u6210\u5668
          • QPYPI \u6307\u5357 \u2013 \u7ba1\u7406 Python \u5305
          "},{"location":"Terminal/","title":"Terminal - Python \u547d\u4ee4\u884c\u5de5\u5177","text":"

          \u7ec8\u7aef\u662f QPython \u4e2d\u6700\u5e38\u7528\u7684\u529f\u80fd\u4e4b\u4e00\u3002\u5b83\u662f\u4e00\u4e2a\u5f3a\u5927\u7684\u5de5\u5177\uff0c\u53ef\u7528\u4e8e\u63a2\u7d22 Python \u7279\u6027\u548c\u5e93\u3001\u8bd5\u9a8c\u65b0\u8bed\u6cd5\u4ee5\u53ca\u7ba1\u7406\u5305\u3002

          "},{"location":"Terminal/#_1","title":"\u6982\u8ff0","text":"

          QPython \u63d0\u4f9b\u591a\u79cd\u7ec8\u7aef\u9009\u9879\u4ee5\u6ee1\u8db3\u4e0d\u540c\u9700\u6c42\uff1a

          • QPython Shell \u7ec8\u7aef \u2013 \u7528\u4e8e\u5feb\u901f\u63a2\u7d22\u7684\u6807\u51c6 Python shell
          • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u529f\u80fd\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668
          • PIP \u5ba2\u6237\u7aef \u2013 \u7528\u4e8e\u7ba1\u7406 Python \u5305\u7684\u547d\u4ee4\u884c\u5de5\u5177
          "},{"location":"Terminal/#_2","title":"\u8bbf\u95ee\u7ec8\u7aef","text":""},{"location":"Terminal/#_3","title":"\u5feb\u901f\u8bbf\u95ee","text":"
          1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
          2. \u70b9\u51fb\u7ec8\u7aef\u56fe\u6807\u8fdb\u5165\u9ed8\u8ba4\u7684 QPython Shell \u7ec8\u7aef
          "},{"location":"Terminal/#_4","title":"\u9ad8\u7ea7\u9009\u9879\uff08\u957f\u6309\uff09","text":"

          \u5728\u4eea\u8868\u76d8\u4e0a\uff0c\u957f\u6309\u7ec8\u7aef\u56fe\u6807\u4ee5\u8bbf\u95ee\u5176\u4ed6\u9009\u9879\uff1a

          • QPython Shell \u7ec8\u7aef \u2013 \u542f\u52a8\u6807\u51c6 Python shell
          • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u542f\u52a8\u5177\u6709\u9ad8\u7ea7\u529f\u80fd\u7684 IPython\uff0c\u5305\u62ec\u4ee3\u7801\u8865\u5168\u3001\u8bed\u6cd5\u9ad8\u4eae\u548c\u547d\u4ee4\u5386\u53f2
          • PIP \u5ba2\u6237\u7aef \u2013 \u542f\u52a8\u5305\u7ba1\u7406\u754c\u9762
          "},{"location":"Terminal/#qpython-shell","title":"QPython Shell \u7ec8\u7aef","text":"

          QPython Shell \u7ec8\u7aef\u63d0\u4f9b\u4e86\u4e00\u79cd\u5feb\u901f\u6267\u884c Python \u547d\u4ee4\u548c\u63a2\u7d22 Python \u7279\u6027\u7684\u65b9\u5f0f\u3002

          "},{"location":"Terminal/#_5","title":"\u529f\u80fd","text":"
          • \u5373\u65f6\u547d\u4ee4\u6267\u884c
          • \u57fa\u672c Python \u89e3\u91ca\u5668\u529f\u80fd
          • \u8bbf\u95ee Python \u5185\u7f6e\u51fd\u6570\u548c\u6807\u51c6\u5e93
          • \u975e\u5e38\u9002\u5408\u5feb\u901f\u6d4b\u8bd5\u548c\u5b9e\u9a8c
          "},{"location":"Terminal/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          >>> print(\"Hello from QPython!\")\nHello from QPython!\n>>> import math\n>>> math.sqrt(16)\n4.0\n>>> [x**2 for x in range(10)]\n[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n
          "},{"location":"Terminal/#ipython","title":"IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668","text":"

          IPython \u63d0\u4f9b\u4e86\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f Python \u4f53\u9a8c\uff0c\u5177\u6709\u589e\u5f3a\u7684\u529f\u80fd\u3002

          "},{"location":"Terminal/#_7","title":"\u529f\u80fd","text":"
          • \u4ee3\u7801\u8865\u5168 \u2013 \u81ea\u52a8\u8865\u5168\u53d8\u91cf\u540d\u3001\u6a21\u5757\u5c5e\u6027\u548c\u6587\u4ef6\u8def\u5f84
          • \u547d\u4ee4\u5386\u53f2 \u2013 \u4f7f\u7528\u4e0a\u4e0b\u7bad\u5934\u6d4f\u89c8\u4e4b\u524d\u7684\u547d\u4ee4
          • \u8bed\u6cd5\u9ad8\u4eae \u2013 \u5f69\u8272\u8f93\u51fa\u4ee5\u63d0\u9ad8\u53ef\u8bfb\u6027
          • \u9b54\u672f\u547d\u4ee4 \u2013 \u4ee5 % \u4e3a\u524d\u7f00\u7684\u7279\u6b8a\u547d\u4ee4\uff0c\u7528\u4e8e\u5e38\u89c1\u4efb\u52a1
          • \u5bf9\u8c61\u5185\u7701 \u2013 \u8f7b\u677e\u63a2\u7d22\u5bf9\u8c61\u53ca\u5176\u5c5e\u6027
          "},{"location":"Terminal/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          In [1]: import numpy as np\n\nIn [2]: arr = np.array([1, 2, 3, 4, 5])\n\nIn [3]: arr?\nType:            ndarray\nString form:     [1 2 3 4 5]\nLength:          5\n...\n\nIn [4]: %timeit arr ** 2\nThe slowest run took 12.34 microseconds...\n
          "},{"location":"Terminal/#pip","title":"PIP \u5ba2\u6237\u7aef","text":"

          PIP \u5ba2\u6237\u7aef\u63d0\u4f9b Python \u5305\u7ba1\u7406\u7684\u547d\u4ee4\u884c\u8bbf\u95ee\u3002

          "},{"location":"Terminal/#_9","title":"\u529f\u80fd","text":"
          • \u4ece PyPI \u5b89\u88c5\u5305
          • \u67e5\u770b\u5df2\u5b89\u88c5\u7684\u5305
          • \u5347\u7ea7\u5305
          • \u5378\u8f7d\u5305
          • \u641c\u7d22\u5305
          "},{"location":"Terminal/#_10","title":"\u5e38\u7528\u547d\u4ee4","text":"
          # \u5b89\u88c5\u5305\npip install requests\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u5305\npip list\n\n# \u5347\u7ea7\u5305\npip install --upgrade requests\n\n# \u5378\u8f7d\u5305\npip uninstall requests\n\n# \u641c\u7d22\u5305\npip search json\n
          "},{"location":"Terminal/#_11","title":"\u4f7f\u7528\u6280\u5de7","text":"
          • \u957f\u6309\u4ece\u4eea\u8868\u76d8\u8bbf\u95ee PIP \u5ba2\u6237\u7aef
          • \u4f7f\u7528 pip help \u67e5\u770b\u6240\u6709\u53ef\u7528\u547d\u4ee4
          • \u67d0\u4e9b\u547d\u4ee4\u53ef\u80fd\u9700\u8981\u7ba1\u7406\u5458\u6743\u9650
          "},{"location":"Terminal/#_12","title":"\u9009\u62e9\u5408\u9002\u7684\u5de5\u5177","text":"\u5de5\u5177 \u6700\u4f73\u7528\u9014 Shell \u7ec8\u7aef \u5feb\u901f\u8ba1\u7b97\u3001\u7b80\u5355\u811a\u672c\u3001\u6d4b\u8bd5\u4ee3\u7801\u7247\u6bb5 IPython \u590d\u6742\u63a2\u7d22\u3001\u6570\u636e\u5206\u6790\u3001\u4ea4\u4e92\u5f0f\u8c03\u8bd5 PIP \u5ba2\u6237\u7aef \u5b89\u88c5/\u66f4\u65b0\u5305\u3001\u68c0\u67e5\u4f9d\u8d56"},{"location":"Terminal/#_13","title":"\u4e86\u89e3\u66f4\u591a","text":"
          • Python \u6587\u6863 \u2013 \u5b98\u65b9 Python \u8bed\u8a00\u548c\u5e93\u53c2\u8003
          • IPython \u6587\u6863 \u2013 \u9ad8\u7ea7\u4ea4\u4e92\u5f0f Python \u529f\u80fd
          • PyPI \u6307\u5357 \u2013 \u5728 QPython \u4e2d\u7ba1\u7406 Python \u5305
          "},{"location":"community/","title":"\u793e\u533a","text":"

          QPython \u62e5\u6709\u4e00\u4e2a\u6d3b\u8dc3\u7684\u6280\u672f\u793e\u533a\uff0c\u4e3a\u5f00\u53d1\u8005\u63d0\u4f9b\u7f16\u7a0b\u5b66\u4e60\u76f8\u5173\u7684\u4ea4\u6d41\u3001\u5206\u4eab\u548c\u4e92\u52a9\u7684\u5e73\u53f0\u3002

          "},{"location":"community/#_2","title":"\u52a0\u5165\u793e\u533a","text":""},{"location":"community/#qpython-","title":"QPython\u516c\u4f17\u53f7 - \u7f16\u7a0b\u5b66\u4e60\u8d44\u6599\u5206\u4eab","text":"

          \u4e13\u6ce8\u4e8eQPython\u79fb\u52a8\u7aef\u5f00\u53d1\u4e0ePython\u5168\u6808\u6280\u672f\u3002\u5185\u5bb9\u6db5\u76d6\uff1a - \u2460 \u57fa\u7840\u8bed\u6cd5\u4e0e\u8fdb\u9636\u6280\u5de7\uff1b - \u2461 \u8da3\u5473\u5b9e\u6218\u9879\u76ee\uff08\u722c\u866b\u3001\u6570\u636e\u5206\u6790\u3001\u81ea\u52a8\u5316\uff09\uff1b - \u2462 \u7f16\u7a0b\u601d\u7ef4\u4e0e\u5b66\u4e60\u65b9\u6cd5\u3002 \u5b9a\u671f\u66f4\u65b0\uff0c\u7cfb\u7edf\u5316\u5b66\u4e60\uff0c\u5e2e\u4f60\u6784\u5efa\u5b8c\u6574\u7684Python\u77e5\u8bc6\u56fe\u8c31\u3002

          "},{"location":"community/#qpython-b","title":"QPython B\u7ad9","text":"

          \u4e13\u6ce8\u624b\u673a\u7f16\u7a0b\u5b9e\u6218\u6559\u5b66\u3002\u7528QPython\u5728\u624b\u673a\u4e0a\u8f7b\u677e\u5b66Python\uff0c\u96f6\u57fa\u7840\u4e5f\u80fd\u8ddf\u4e0a\uff01 - \u2460 \u624b\u628a\u624b\u5b9e\u64cd\u6f14\u793a - \u2461 \u8da3\u5473\u5b9e\u6218\u9879\u76ee\uff08\u722c\u866b/\u81ea\u52a8\u5316/\u5c0f\u5de5\u5177\uff09 - \u2462 \u907f\u5751\u6307\u5357\u4e0e\u6280\u5de7\u5206\u4eab \u6709\u95ee\u5fc5\u7b54\uff0c\u6b22\u8fce\u8bc4\u8bba\u533a\u4ea4\u6d41\uff0c\u4e00\u8d77\u5728\u624b\u673a\u4e0a\u73a9\u8f6cPython\uff01

          • B\u7ad9 \u2013 \u8bbf\u95eeQPython B\u7ad9
          "},{"location":"community/#qpython-qq","title":"QPython QQ\u8bba\u575b","text":"

          \u4e13\u6ce8\u4e8eQPython\u79fb\u52a8\u7aef\u5f00\u53d1\u4e0ePython\u5168\u6808\u6280\u672f\uff0c\u4e3a\u5f00\u53d1\u8005\u63d0\u4f9b\u4e00\u4e2a\u4f5c\u54c1\u5c55\u793a\u3001\u884c\u4e1a\u4ea4\u6d41\u3001\u6280\u672f\u6c89\u6dc0\u7684\u9ad8\u8d28\u91cf\u4ea4\u6d41\u7a7a\u95f4\u3002 \u5305\u62ec\u4ee5\u4e0b\u680f\u76ee\uff1a\u884c\u4e1a\u8d44\u8baf\u3001\u6280\u672f\u4ea4\u6d41\u3001\u9879\u76ee\u6848\u4f8b\u3001BUG\u53cd\u9988\u3002

          • QPython QQ\u9891\u9053 \u2013 \u4e0eQQ/\u5fae\u4fe1\u7528\u6237\u5728\u817e\u8baf\u9891\u9053\u4ea4\u6d41
          "},{"location":"community/#qpython-qq_1","title":"QPython\u5fae\u4fe1\u7fa4 & QQ\u7fa4","text":"

          QPython\u5fae\u4fe1\u7528\u6237\u7fa4\u7fa4\u5b9a\u4f4d\uff1aQPython\u4f7f\u7528\u4ea4\u6d41 | Python\u5b66\u4e60\u4e92\u52a9 | \u5b9e\u6218\u95ee\u9898\u89e3\u7b54\uff0c\u6dfb\u52a0\u52a9\u624b\u540e\u4f1a\u9080\u60a8\u52a0\u5165

          \u5fae\u4fe1\u7fa4\uff08\u52a9\u624b: learnwithqpy\uff09 QQ\u7fa4\uff08\u7fa4\u53f7: 862351102\uff09"},{"location":"community/#qpython","title":"QPython \u793e\u533a\u63a8\u8350\u670d\u52a1","text":"

          \u5728 QPython \u7684\u4f7f\u7528\u8fc7\u7a0b\u4e2d\uff0c\u90e8\u5206\u7528\u6237\u5e0c\u671b\u5c06\u81ea\u5df1\u5f00\u53d1\u7684\u811a\u672c\u6216\u670d\u52a1\u6253\u5305\u6210\u72ec\u7acb\u7684\u5b89\u5353\u5e94\u7528\u3002\u4e3a\u6b64\uff0c\u6211\u4eec\u7279\u522b\u7b5b\u9009\u4e86\u4ee5\u4e0b\u4f18\u8d28\u670d\u52a1\uff0c\u4f9b\u60a8\u6309\u9700\u9009\u62e9(\u5982\u679c\u60a8\u60f3\u63a8\u8350\u4f60\u7684 QPython \u793e\u533a\u670d\u52a1\uff0c\u4e5f\u6b22\u8fce\u5fae\u4fe1\u8054\u7cfb)\uff1a

          • \u5b89\u5353\u5e94\u7528\u6253\u5305 - \u5c06\u60a8\u7684 QPython \u9879\u76ee\u6253\u5305\u4e3a\u5b89\u5353\u5e94\u7528
          "},{"location":"community/#qpython-vip","title":"QPython \u77e5\u8bc6\u661f\u7403 VIP\u793e\u533a","text":"

          QPython\u5b98\u65b9\u4ed8\u8d39VIP\u4e13\u5c5e\u793e\u533a\uff0c\u4e3a\u6df1\u5ea6\u7528\u6237\u63d0\u4f9b\u5b98\u65b9\u56e2\u961f\u76f4\u8fde\u3001\u53ca\u65f6\u6280\u672f\u652f\u6301\u3001\u9ad8\u8d28\u91cf\u4ea4\u6d41\u7684\u4e13\u5c5e\u670d\u52a1\u7a7a\u95f4\u3002\u52a0\u5165VIP\u793e\u533a\u53ef\u83b7\u4e0b\u5217\u6838\u5fc3\u4ef7\u503c\uff1a

          • \ud83c\udfaf \u5b98\u65b9\u56e2\u961f\u76f4\u8fde \u2014\u2014 QPython\u5f00\u53d1\u56e2\u961f\u5728\u7ebf\u7b54\u7591\uff0c\u9047\u5230\u95ee\u9898\u4e0d\u518d\u5361\u58f3\uff0c\u6280\u672f\u96be\u9898\u5feb\u901f\u54cd\u5e94
          • \ud83d\ude80 \u4f18\u5148\u6280\u672f\u652f\u6301 \u2014\u2014 VIP\u7528\u6237\u4e13\u5c5e\u901a\u9053\uff0c\u6bd4\u516c\u5f00\u6e20\u9053\u66f4\u5feb\u83b7\u5f97\u5b98\u65b9\u89e3\u7b54
          • \ud83d\udca1 \u6df1\u5ea6\u4ea4\u6d41\u5708\u5b50 \u2014\u2014 \u4e0e\u6838\u5fc3\u7528\u6237\u3001\u8d44\u6df1\u5f00\u53d1\u8005\u540c\u884c\uff0c\u63a2\u8ba8\u9ad8\u9636\u6280\u5de7\u4e0e\u9879\u76ee\u5b9e\u6218

          QPython \u56e2\u961f\u4f1a\u5b9a\u671f\u5728\u793e\u533a\u4e2d\u66f4\u65b0\u9879\u76ee\u8fdb\u5c55\uff0c\u6b22\u8fce\u5173\u6ce8\uff01

          "},{"location":"editor-guide/","title":"\u4f7f\u7528\u6700\u4f73\u5f00\u53d1\u65b9\u5f0f","text":""},{"location":"editor-guide/#qeditor","title":"\u4ece QEditor \u5f00\u53d1","text":"

          QEditor \u662f QPython \u7684\u5185\u7f6e\u7f16\u8f91\u5668\uff0c\u652f\u6301 Python / HTML \u8bed\u6cd5\u9ad8\u4eae\u3002

          QEditor \u7684\u4e3b\u8981\u529f\u80fd

          • \u7f16\u8f91/\u67e5\u770b\u7eaf\u6587\u672c\u6587\u4ef6\uff0c\u5982 Python\u3001Lua\u3001HTML\u3001Javascript \u7b49

          • \u7f16\u8f91\u548c\u8fd0\u884c Python \u811a\u672c & Python \u8bed\u6cd5\u9ad8\u4eae

          • \u7f16\u8f91\u548c\u8fd0\u884c Shell \u811a\u672c

          • \u4f7f\u7528\u5185\u7f6e HTML \u6d4f\u89c8\u5668\u9884\u89c8 HTML

          • \u6309\u5173\u952e\u5b57\u641c\u7d22\u3001\u4ee3\u7801\u7247\u6bb5\u3001\u4ee3\u7801\u5206\u4eab

          \u60a8\u53ef\u4ee5\u76f4\u63a5\u5728 QEditor \u4e2d\u8fd0\u884c QPython \u811a\u672c\uff0c\u56e0\u6b64\u5728\u79fb\u52a8\u65f6\u8fd9\u662f QPython \u5f00\u53d1\u6700\u65b9\u4fbf\u7684\u65b9\u5f0f\u3002

          "},{"location":"editor-guide/#_2","title":"\u901a\u8fc7\u6d4f\u89c8\u5668\u5f00\u53d1","text":"

          QPython \u6709\u4e00\u4e2a\u5185\u7f6e\u811a\u672c qedit4web.py\uff0c\u5f53\u60a8\u70b9\u51fb\u5f00\u59cb\u6309\u94ae\u5e76\u9009\u62e9\"\u8fd0\u884c\u672c\u5730\u811a\u672c\"\u65f6\u53ef\u4ee5\u770b\u5230\u5b83\u3002

          \u8fd0\u884c\u540e\uff0c\u60a8\u53ef\u4ee5\u770b\u5230\u7ed3\u679c\u3002

          \u7136\u540e\uff0c\u60a8\u53ef\u4ee5\u901a\u8fc7 PC/\u7b14\u8bb0\u672c\u7535\u8111\u7684\u6d4f\u89c8\u5668\u8bbf\u95ee\u8be5\u7f51\u5740\u8fdb\u884c\u5f00\u53d1\uff0c\u5982\u4e0b\u56fe\u6240\u793a\u3002

          \u9009\u62e9\u67d0\u4e2a\u9879\u76ee\u6216\u811a\u672c\u540e\uff0c\u60a8\u53ef\u4ee5\u5f00\u59cb\u5f00\u53d1

          \u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\u7f16\u5199\u6d4f\u89c8\u5668\u4ee3\u7801\uff0c\u7136\u540e\u5728 Android \u624b\u673a\u4e0a\u8fd0\u884c\u3002\u975e\u5e38\u65b9\u4fbf\u3002

          "},{"location":"editor-guide/#_3","title":"\u4ece\u60a8\u7684\u7535\u8111\u5f00\u53d1","text":"

          \u9664\u4e86\u4e0a\u8ff0\u65b9\u6cd5\uff0c\u60a8\u8fd8\u53ef\u4ee5\u7528\u81ea\u5df1\u7684\u65b9\u5f0f\u5f00\u53d1\u811a\u672c\uff0c\u7136\u540e\u901a\u8fc7\u5185\u7f6e\u7684 FTP \u670d\u52a1\u5c06\u5176\u4e0a\u4f20\u5230\u624b\u673a\uff0c\u7528 QPython \u8fd0\u884c\u5b83\u3002

          "},{"location":"external-api/","title":"QPython \u5f00\u653e API","text":"

          QPython \u6709\u4e00\u4e2a\u5f00\u653e\u7684 activity\uff0c\u5141\u8bb8\u60a8\u4ece\u5916\u90e8\u8fd0\u884c qpython\u3002

          MPyAPI \u7684\u5b9a\u4e49\u5982\u4e0b\uff1a

              <activity\n        android:name=\"org.qpython.qpylib.MPyApi\"\n        android:label=\"@string/qpy_run_with_share\"\n        android:screenOrientation=\"user\"\n        android:configChanges=\"orientation|keyboardHidden\"\n        android:exported=\"true\">\n        <intent-filter>\n            <action android:name=\"org.qpython.qpylib.action.MPyApi\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.LAUNCHER\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.VIEW\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.BROWSABLE\" />\n            <data android:scheme=\"http\" />\n            <data android:scheme=\"https\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"text/plain\"/>\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"image/*\"/>\n        </intent-filter>\n    </activity>\n

          \u56e0\u6b64\uff0c\u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\uff1a

          "},{"location":"external-api/#qpython","title":"\u5c06\u5185\u5bb9\u5206\u4eab\u5230 QPython \u7684\u811a\u672c","text":"

          \u60a8\u53ef\u4ee5\u5728\u67d0\u4e2a\u5e94\u7528\u4e2d\u9009\u62e9\u4e00\u4e9b\u5185\u5bb9\uff0c\u7136\u540e\u5206\u4eab\u5230 qpython \u7684\u811a\u672c\uff0c\u4e4b\u540e\u60a8\u53ef\u4ee5\u4f7f\u7528 sys.argv[2] \u5904\u7406\u8fd9\u4e9b\u5185\u5bb9

          \u5728 YouTube \u4e0a\u89c2\u770b\u6f14\u793a\u89c6\u9891

          "},{"location":"external-api/#qpython_1","title":"\u4ece\u60a8\u81ea\u5df1\u7684\u5e94\u7528\u7a0b\u5e8f\u8fd0\u884c QPython \u7684\u811a\u672c","text":"

          \u60a8\u53ef\u4ee5\u901a\u8fc7\u8c03\u7528\u6b64 activity \u5728\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u4e2d\u8c03\u7528 QPython \u6765\u8fd0\u884c\u67d0\u4e9b\u811a\u672c\u6216 Python \u4ee3\u7801\uff0c\u793a\u4f8b\u5982\u4e0b\uff1a

          // \u5c55\u793a\u5982\u4f55\u8c03\u7528 qpython API \u7684\u4ee3\u7801\u793a\u4f8b\nString extPlgPlusName = \"org.qpython.qpy\";          // QPython \u5305\u540d\nIntent intent = new Intent();\nintent.setClassName(extPlgPlusName, \"org.qpython.qpylib.MPyApi\");\nintent.setAction(extPlgPlusName + \".action.MPyApi\");\n\nBundle mBundle = new Bundle();\nmBundle.putString(\"app\", \"myappid\");\nmBundle.putString(\"act\", \"onPyApi\");\nmBundle.putString(\"flag\", \"onQPyExec\"); // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u4efb\u610f\u5b57\u7b26\u4e32\u6807\u5fd7\nmBundle.putString(\"param\", \"\");         // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u53c2\u6570\u5b57\u7b26\u4e32\n\n/*\n* \u6211\u4eec\u5c06\u8fd0\u884c\u7684 Python \u4ee3\u7801\n*/\nString code = \"import androidhelper\\n\" +\n            \"droid = androidhelper.Android()\\n\" +\n            \"line = droid.dialogGetInput()\\n\" +\n            \"s = 'Hello %s' % line.result\\n\" +\n            \"droid.makeToast(s)\\n\"\n\nmBundle.putString(\"pycode\", code);\nintent.putExtras(mBundle);\nstartActivityForResult(intent, SCRIPT_EXEC_PY);\n...\n\n// \u60a8\u53ef\u4ee5\u5728 onActivityResult \u4e2d\u5904\u7406 qpython \u8c03\u7528\u7ed3\u679c\n@Override\nprotected void onActivityResult(int requestCode, int resultCode, Intent data) {\n    if (requestCode == SCRIPT_EXEC_PY) {\n        if (data!=null) {\n            Bundle bundle = data.getExtras();\n            String flag = bundle.getString(\"flag\");\n            String param = bundle.getString(\"param\");\n            String result = bundle.getString(\"result\"); // \u60a8\u7684 Pycode \u751f\u6210\u7684\u7ed3\u679c\n            Toast.makeText(this, \"onQPyExec: return (\"+result+\")\", Toast.LENGTH_SHORT).show();\n        } else {\n            Toast.makeText(this, \"onQPyExec: data is null\", Toast.LENGTH_SHORT).show();\n\n        }\n    }\n}\n

          \u4ece github \u68c0\u51fa\u4e00\u4e2a\u5b8c\u6574\u9879\u76ee

          \u8fd8\u6709\u4e00\u4e2a\u751f\u4ea7\u5e94\u7528\u7a0b\u5e8f - \u9762\u5411 Tasker \u7684 QPython \u63d2\u4ef6

          "},{"location":"featured-courses/","title":"\u7cbe\u9009\u8bfe\u7a0b","text":"

          \u5728\u8fd9\u91cc\uff0c\u6211\u4eec\u4e3a\u60a8\u4ecb\u7ecd\u4e00\u4e9b\u7531\u793e\u533a\u6210\u5458\u521b\u5efa\u7684\u7cbe\u54c1\u8bfe\u7a0b\u3002\u6bcf\u4e00\u95e8\u8bfe\u7a0b\u90fd\u51dd\u805a\u4e86\u521b\u4f5c\u8005\u7684\u5fc3\u8840\u548c\u72ec\u7279\u89c1\u89e3\uff0c\u5e0c\u671b\u80fd\u4e3a\u60a8\u7684\u5b66\u4e60\u4e4b\u65c5\u5e26\u6765\u542f\u53d1\u548c\u5e2e\u52a9\u3002

          "},{"location":"featured-courses/#aipython-aipy","title":"\u4e0eAI\u534f\u4f5c\u7684Python\u7f16\u7a0b\u5165\u95e8 - AIPY\u7f16\u7a0b\u7cfb\u5217","text":"

          \u8bfe\u7a0b\u7b80\u4ecb\uff1a \u4f60\u662f\u5426\u89c9\u5f97\u7f16\u7a0b\u5f88\u96be\uff1f\u5728 AI \u65f6\u4ee3\uff0c\u8fd9\u4e00\u5207\u6b63\u5728\u6539\u53d8\u3002\u672c\u8bfe\u7a0b\u5c06\u5e26\u4f60\u638c\u63e1 Python \u7f16\u7a0b\u57fa\u7840\uff0c\u540c\u65f6\u5b66\u4f1a\u4e0e AI \u9ad8\u6548\u534f\u4f5c\u3002\u72ec\u521b AI \u8f85\u52a9\u6559\u5b66\u6cd5\uff0c\u7cfb\u7edf\u8bb2\u89e3 Python \u6838\u5fc3\u77e5\u8bc6\uff0c\u6559\u4f1a\u4f60\u5982\u4f55\u5411 AI \u7cbe\u786e\u8868\u8fbe\u9700\u6c42\u3001\u534f\u540c\u8c03\u8bd5\u4ee3\u7801\u3002\u901a\u8fc7\u804a\u5929\u673a\u5668\u4eba\u3001\u6570\u636e\u5206\u6790\u52a9\u624b\u7b49\u5b9e\u6218\u9879\u76ee\uff0c\u5efa\u7acb\u4eba\u673a\u534f\u4f5c\u5de5\u4f5c\u6d41\uff0c\u8ba9\u4f60\u5f7b\u5e95\u6253\u7834\u5bf9\u4ee3\u7801\u7684\u754f\u60e7\u3002

          \u521b\u4f5c\u6545\u4e8b\uff1a \u8fd9\u95e8\u8bfe\u662f\u5982\u4f55\u8bde\u751f\u7684\uff1f\u4ee5\u4e0b\u662f\u4f5c\u8005\u7684\u521b\u4f5c\u624b\u8bb0\uff1a

          • \u4e3a\u4ec0\u4e48\u6211\u8981\u5199\u4e00\u5957\u9002\u5408\u521d\u5b66\u8005\u7684 AI \u534f\u52a9 Python \u7f16\u7a0b\u6559\u6750\uff1f - \u521b\u4f5c\u624b\u8bb0\uff08\u4e00\uff09
          • \u4e0e AI \u534f\u4f5c\u7684\"\u62c9\u626f\"\u5f0f Python \u7f16\u7a0b\u8bfe\u7a0b\u7eb2\u9886\u521b\u4f5c - \u521b\u4f5c\u624b\u8bb0\uff08\u4e8c\uff09
          "},{"location":"featured-courses/#_2","title":"\u6b22\u8fce\u53cd\u9988","text":"

          \u5982\u679c\u60a8\u6709\u60f3\u6cd5\u60f3\u8981\u5206\u4eab\uff0c\u6b22\u8fce\u8054\u7cfb\u6211\u4eec\uff01

          • GitHub Issues \u2013 \u63d0\u4ea4\u60a8\u7684\u8bfe\u7a0b\u5efa\u8bae
          • \u4e2d\u6587\u4ea4\u6d41\u793e\u533a \u2013 \u4e0e\u5176\u4ed6\u5b66\u4e60\u8005\u4ea4\u6d41\u5fc3\u5f97
          "},{"location":"getting-started/","title":"QPython\uff1a\u5165\u95e8\u6307\u5357","text":"

          \u672c\u6307\u5357\u5c06\u4ecb\u7ecd QPython \u7684\u529f\u80fd\u5e76\u5e2e\u52a9\u60a8\u5feb\u901f\u5165\u95e8\u3002

          "},{"location":"getting-started/#qpython_1","title":"QPython \u6982\u8ff0","text":"

          \u4e3a\u4ec0\u4e48\u9009\u62e9 QPython\uff1f

          \u667a\u80fd\u624b\u673a\u5df2\u6210\u4e3a\u4eba\u4eec\u5fc5\u5907\u7684\u4fe1\u606f\u548c\u6280\u672f\u52a9\u624b\uff0c\u4e00\u4e2a\u7075\u6d3b\u7684\u89e3\u91ca\u5668\u5f15\u64ce\u53ef\u4ee5\u5e2e\u52a9\u60a8\u9ad8\u6548\u5b8c\u6210\u5927\u90e8\u5206\u5de5\u4f5c\uff0c\u65e0\u9700\u590d\u6742\u7684\u5f00\u53d1\u8fc7\u7a0b\u3002

          QPython \u63d0\u4f9b\u4e86 \u60ca\u4eba\u7684\u5f00\u53d1\u4f53\u9a8c\u2014\u2014\u501f\u52a9\u5b83\u7684\u5e2e\u52a9\uff0c\u60a8\u53ef\u4ee5\u8f7b\u677e\u5b9e\u73b0\u7a0b\u5e8f\uff0c\u65e0\u9700\u590d\u6742\u7684 IDE \u5b89\u88c5\u3001\u7f16\u8bd1\u6216\u6253\u5305\u8fc7\u7a0b\u3002

          "},{"location":"getting-started/#qpython_2","title":"QPython \u7248\u672c","text":"

          \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

          • QPython \u2013 \u7531 QPython \u56e2\u961f\u7ef4\u62a4\u7684\u4e3b\u8981\u7248\u672c\uff0c\u5177\u5907 AI \u529f\u80fd\uff0c\u53ef\u5728 Google Play \u7b49\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d
          • QPython+ \u2013 \u7531\u5f00\u6e90\u8d21\u732e\u8005\u63a8\u51fa\u7684\u793e\u533a\u7248\uff0c\u63d0\u4f9b\u5404\u79cd\u65b0\u7279\u6027
          • QPython Plus \u2013 \u6269\u5c55\u6743\u9650\u7248\u672c\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff09
          "},{"location":"getting-started/#_1","title":"\u4e3b\u8981\u7279\u6027","text":"
          • \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668 - \u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51
          • QSL4A \u96c6\u6210 - \u4f7f\u7528 Python \u63a7\u5236 Android \u786c\u4ef6\u548c API
          • GenAI \u80fd\u529b\u96c6\u6210 - \u652f\u6301\u672c\u5730\u8fd0\u884c\u7684 LLM\u3001OpenAI \u7b49\u5404\u79cd LLM \u5e93\uff0c\u4ee5\u53ca\u53ef\u5728 QPython \u4e0a\u8fdb\u884c Vibe Coding \u5f00\u53d1\u7684 AIPyApp
          • \u6269\u5c55\u5305\u5b89\u88c5 - \u652f\u6301\u901a\u8fc7 QPYPI \u548c pip \u5b89\u88c5\u6269\u5c55\u5305
          • \u5185\u7f6e\u7f16\u8f91\u5668 - \u8bed\u6cd5\u9ad8\u4eae\u548c\u4ee3\u7801\u7f16\u8f91
          • \u591a\u79cd\u8fd0\u884c\u6a21\u5f0f - \u9664\u63a7\u5236\u53f0\u7a0b\u5e8f\u5916\uff0c\u8fd8\u652f\u6301 Android \u539f\u751f UI\uff08\u901a\u8fc7 QSL4A \u63a5\u53e3\uff09\u4ee5\u53ca Pygame / Turtle / Tkinter \u7b49\u8fd0\u884c\u65b9\u5f0f
          "},{"location":"getting-started/#1","title":"1. \u4eea\u8868\u76d8","text":"

          \u5b89\u88c5 QPython \u540e\uff0c\u70b9\u51fb\u5176\u56fe\u6807\u542f\u52a8\u3002\u60a8\u5c06\u770b\u5230\u5e26\u6709 QPython \u6807\u5fd7\u548c\u4ee5\u4e0b\u529f\u80fd\u7684\u4e3b\u4eea\u8868\u76d8\uff1a

          "},{"location":"getting-started/#_2","title":"\u4eea\u8868\u76d8\u529f\u80fd","text":"

          QPython \u4eea\u8868\u76d8\u63d0\u4f9b\u5bf9\u6240\u6709\u4e3b\u8981\u529f\u80fd\u7684\u5feb\u901f\u8bbf\u95ee\uff1a

          • \u7ec8\u7aef \u2014 \u8bbf\u95ee Python \u63a7\u5236\u53f0\u548c shell \u4ee5\u76f4\u63a5\u6267\u884c\u547d\u4ee4
          • Notebook \u2014 \u7528\u4e8e\u6570\u636e\u5206\u6790\u548c\u5b9e\u9a8c\u7684\u4ea4\u4e92\u5f0f Jupyter \u98ce\u683c\u7b14\u8bb0\u672c
          • \u7f16\u8f91\u5668 \u2014 \u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668\uff0c\u5177\u6709\u8bed\u6cd5\u9ad8\u4eae\u529f\u80fd\uff0c\u7528\u4e8e\u7f16\u5199 Python \u811a\u672c
          • \u8d44\u6e90\u7ba1\u7406\u5668 \u2014 \u6d4f\u89c8\u548c\u7ba1\u7406\u60a8\u7684\u6587\u4ef6\u3001\u811a\u672c\u548c\u9879\u76ee
          • QPYPI \u2014 \u5b89\u88c5 Python \u5305\u548c\u6269\u5c55\u3002\u8be6\u89c1 QPYPI \u6307\u5357
          • \u8bbe\u7f6e \u2014 \u914d\u7f6e QPython \u9996\u9009\u9879\u548c\u8fd0\u884c\u9009\u9879
          • \u793e\u533a \u2014 \u8bbf\u95ee QPython \u793e\u533a\u8d44\u6e90\u3001\u8bba\u575b\u548c\u5e2e\u52a9
          • \u8bfe\u7a0b \u2014 \u8bbf\u95ee Python \u7f16\u7a0b\u7684\u5b66\u4e60\u6750\u6599\u548c\u6559\u7a0b

          \u70b9\u51fb\u4efb\u4f55\u56fe\u6807\u4ee5\u8bbf\u95ee\u76f8\u5e94\u7684\u529f\u80fd\u3002

          "},{"location":"getting-started/#2","title":"2. \u7ec8\u7aef\u548c\u7f16\u8f91\u5668","text":""},{"location":"getting-started/#_3","title":"\u7ec8\u7aef","text":"

          \u7ec8\u7aef\u63d0\u4f9b Python \u63a7\u5236\u53f0\uff0c\u652f\u6301\uff1a - \u63a2\u7d22\u5bf9\u8c61\u5c5e\u6027 - \u6d4b\u8bd5\u8bed\u6cd5\u548c\u60f3\u6cd5 - \u76f4\u63a5\u6267\u884c\u547d\u4ee4

          \u4f7f\u7528\u52a0\u53f7\u6309\u94ae\uff081\uff09\u6253\u5f00\u65b0\u7ec8\u7aef\u6807\u7b7e\u9875\uff0c\u901a\u8fc7\u4e0b\u62c9\u83dc\u5355\uff082\uff09\u5207\u6362\uff0c\u5e76\u4f7f\u7528\u5173\u95ed\u6309\u94ae\uff083\uff09\u5173\u95ed\u3002

          "},{"location":"getting-started/#_4","title":"\u7f16\u8f91\u5668","text":"

          \u7f16\u8f91\u5668\u5e95\u90e8\u529f\u80fd\u680f\u5305\u542b\u4ee5\u4e0b\u5de5\u5177\uff08\u4ece\u5de6\u5230\u53f3\uff09\uff1a

          • \u5207\u6362\u5feb\u6377\u8f93\u5165\uff08\u5305\u542b def / if / else / elif / class \u7b49\u5173\u952e\u8bcd\uff09
          • \u9501\u5b9a\uff08\u9632\u6b62\u8bef\u89e6\uff09
          • \u8df3\u8f6c
          • \u4fdd\u5b58
          • \u8fd0\u884c
          • \u641c\u7d22
          • \u64a4\u9500
          • \u91cd\u505a
          • \u53e6\u5b58
          • \u6700\u8fd1\u6587\u4ef6
          • \u4ee3\u7801\u7247\u6bb5

          \u91cd\u8981\u63d0\u793a\uff1a \u4fdd\u5b58\u65f6\u8bf7\u624b\u52a8\u6dfb\u52a0 .py \u6269\u5c55\u540d\uff0c\u56e0\u4e3a\u7f16\u8f91\u5668\u4e0d\u4f1a\u81ea\u52a8\u6dfb\u52a0\u3002

          "},{"location":"getting-started/#3","title":"3. \u8d44\u6e90\u7ba1\u7406\u5668\uff08\u6587\u4ef6\u7ba1\u7406\uff09","text":"

          \u901a\u8fc7 \u8d44\u6e90\u7ba1\u7406\u5668 \u8bbf\u95ee\u811a\u672c\u548c\u9879\u76ee\uff0c\u652f\u6301\u6d4f\u89c8\u3001\u7ec4\u7ec7\u548c\u7ba1\u7406\u6240\u6709 Python \u6587\u4ef6\u3002

          "},{"location":"getting-started/#_5","title":"\u811a\u672c","text":"

          \u811a\u672c\u662f\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/scripts3/ \u4e2d\u7684\u5355\u4e2a Python \u6587\u4ef6\uff08\u9488\u5bf9 Python 3\uff09\u3002

          \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u811a\u672c - \u6253\u5f00 \u2014 \u4f7f\u7528\u5185\u7f6e\u7f16\u8f91\u5668\u7f16\u8f91 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u811a\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u811a\u672c

          "},{"location":"getting-started/#_6","title":"\u9879\u76ee","text":"

          \u9879\u76ee\u662f\u5305\u542b main.py \u4f5c\u4e3a\u5165\u53e3\u70b9\u7684\u76ee\u5f55\u3002\u60a8\u53ef\u4ee5\u5728\u540c\u4e00\u76ee\u5f55\u4e2d\u5305\u542b\u5176\u4ed6\u4f9d\u8d56\u9879\u548c\u8d44\u6e90\u3002\u5c06\u9879\u76ee\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/projects3/ \u4e2d\u3002

          "},{"location":"getting-started/#_7","title":"\u7b14\u8bb0\u672c","text":"

          Jupyter \u98ce\u683c\u7684\u7b14\u8bb0\u672c\u4e5f\u901a\u8fc7\u8d44\u6e90\u7ba1\u7406\u5668\u8fdb\u884c\u7ba1\u7406\uff0c\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/notebooks/ \u4e2d\u3002

          \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u7b14\u8bb0\u672c - \u6253\u5f00 \u2014 \u63a2\u7d22\u7b14\u8bb0\u672c\u5185\u5bb9 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u7b14\u8bb0\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u7b14\u8bb0\u672c

          "},{"location":"getting-started/#4","title":"4. \u5e93","text":"

          \u901a\u8fc7\u5b89\u88c5\u7b2c\u4e09\u65b9\u5e93\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

          "},{"location":"getting-started/#_8","title":"\u5305\u5b89\u88c5\u65b9\u6cd5","text":"

          QPYPI\uff08\u63a8\u8350\uff09

          \u4ece QPYPI \u5b89\u88c5\u9884\u7f16\u8bd1\u7684\u5e93\uff0c\u5305\u62ec numpy\u3001scipy \u7b49\u79d1\u5b66\u5305\u3002

          \u8be6\u89c1 QPYPI \u6307\u5357\u3002

          PIP \u5ba2\u6237\u7aef

          \u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216 QPYPI \u754c\u9762\u5b89\u88c5\u7eaf Python \u5e93\uff1a

          pip install requests\n

          \u9884\u7f16\u8bd1\u5305

          \u5bf9\u4e8e\u5177\u6709 C/C++/Rust \u4f9d\u8d56\u7684\u5305\uff0c\u4f7f\u7528 QPython \u7684\u9884\u7f16\u8bd1\u5305\uff1a

          pip install numpy-qpython\npip install scipy-aipy\n

          \u8be6\u89c1 QPYPI \u6307\u5357 \u83b7\u53d6\u53ef\u7528\u5305\u7684\u5b8c\u6574\u5217\u8868\u3002

          \u624b\u52a8\u5b89\u88c5

          \u60a8\u4e5f\u53ef\u4ee5\u5c06\u5e93\u590d\u5236\u5230 /storage/emulated/0/Android/data/org.qpython.qpy/files/lib/python3.12/site-packages/\u3002

          "},{"location":"getting-started/#5","title":"5. \u8fd0\u884c\u6a21\u5f0f","text":"

          QPython \u652f\u6301\u591a\u79cd\u8fd0\u884c\u6a21\u5f0f\u4ee5\u6ee1\u8db3\u4e0d\u540c\u7684\u7528\u4f8b\uff1a

          "},{"location":"getting-started/#_9","title":"\u63a7\u5236\u53f0\u6a21\u5f0f","text":"

          \u5e38\u89c4 Python \u811a\u672c\u7684\u9ed8\u8ba4\u6a21\u5f0f\u3002

          "},{"location":"getting-started/#qsl4a","title":"QSL4A \u6a21\u5f0f","text":"

          \u901a\u8fc7 QSL4A \u5e93\u8c03\u7528 Android API \u7684\u811a\u672c\u3002

          import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello Android!')\n

          \u8be6\u89c1 QSL4A \u6587\u6863 \u83b7\u53d6\u5b8c\u6574\u7684 API \u53c2\u8003\u3002

          "},{"location":"getting-started/#webapp","title":"WebApp \u6a21\u5f0f","text":"

          \u4f7f\u7528\u540e\u7aef\u670d\u52a1\u5668\u521b\u5efa\u57fa\u4e8e Web \u7684\u5e94\u7528\u7a0b\u5e8f\u3002\u9700\u5728\u811a\u672c\u5f00\u5934\u6dfb\u52a0\u4ee5\u4e0b\u4e24\u884c headers\uff1a

          #qpy:webapp:<\u9879\u76ee\u540d>\n#qpy://localhost:<web\u670d\u52a1\u4fa6\u542c\u7684\u7aef\u53e3>/<\u9ed8\u8ba4\u4e3b\u8def\u5f84>\n

          \u4f8b\u5982\uff1a

          #qpy:webapp:Hello QPython\n#qpy://localhost:8080/hello\n\nfrom bottle import route, run, Bottle\n\napp = Bottle()\n\n@route('/hello')\ndef hello():\n    return '<h1>Hello from QPython!</h1>'\n\nrun(app, host='localhost', port=8080)\n
          "},{"location":"getting-started/#q","title":"Q \u6a21\u5f0f\uff08\u65e0\u63a7\u5236\u53f0\u6a21\u5f0f\uff09","text":"

          \u9759\u9ed8\u6a21\u5f0f\u8fd0\u884c\u811a\u672c\uff0c\u4e0d\u663e\u793a\u63a7\u5236\u53f0\u3002\u9700\u5728\u811a\u672c\u5f00\u5934\u6dfb\u52a0 header\uff1a

          #qpy:quiet\n\nimport time\n\nwhile True:\n    # \u60a8\u7684\u540e\u53f0\u4efb\u52a1\n    time.sleep(60)\n
          \u5982\u679c\u9700\u8981\u8fd0\u884c\u5e26 GUI \u7684 QSL4A \u7a0b\u5e8f\u4e14\u4e0d\u5e0c\u671b\u663e\u793a\u63a7\u5236\u53f0\u4fe1\u606f\uff0c\u63a8\u8350\u4f7f\u7528\u6b64\u6a21\u5f0f\u3002

          "},{"location":"getting-started/#6","title":"6. \u793e\u533a\u4e0e\u652f\u6301","text":"

          \u8bbf\u95ee QPython.org \u83b7\u53d6\u6587\u6863\u3001\u7528\u6237\u793e\u533a\u53ca\u5e2e\u52a9\u95ee\u7b54\u3002

          \u793e\u533a\u94fe\u63a5\uff1a - Facebook \u7fa4\u7ec4 - GitHub - \u95ee\u9898\u53cd\u9988

          \u4e0b\u4e00\u6b65\uff1a - \u5c1d\u8bd5 Hello World \u6559\u7a0b - \u63a2\u7d22 QSL4A API \u4ee5\u96c6\u6210 Android - \u4e86\u89e3 QPython \u7248\u672c

          "},{"location":"getting-started/#_10","title":"\u89c6\u9891\u4ecb\u7ecd","text":""},{"location":"getting-started/#_11","title":"\u4e0b\u4e00\u6b65","text":"

          \u5982\u679c\u60a8\u5df2\u7ecf\u521d\u6b65\u4e86\u89e3\u4e86 QPython \u7684\u529f\u80fd\uff0c\u6b22\u8fce\u5f00\u59cb\u4f53\u9a8c\u7f16\u7a0b\u7684\u4e50\u8da3\uff01\u8bd5\u8bd5 Hello World \u6559\u7a0b \u8fc8\u51fa\u60a8\u7684\u7b2c\u4e00\u6b65\u3002

          "},{"location":"qpypi-guide/","title":"QPYPI","text":"

          \u60a8\u53ef\u4ee5\u901a\u8fc7\u5b89\u88c5\u5305\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

          "},{"location":"qpypi-guide/#_1","title":"\u5305\u5b89\u88c5\u652f\u6301","text":""},{"location":"qpypi-guide/#python","title":"\u7eaf Python \u5305","text":"

          QPython \u652f\u6301\u4f7f\u7528\u7eaf Python \u5f00\u53d1\u7684 Python \u5305\u3002\u60a8\u53ef\u4ee5\u76f4\u63a5\u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216\u4eea\u8868\u76d8\u4e0a\u7684 QPYPI \u4f7f\u7528 pip install \u5b89\u88c5\u8fd9\u4e9b\u5305\u3002

          "},{"location":"qpypi-guide/#_2","title":"\u9884\u7f16\u8bd1\u5305","text":"

          \u5982\u679c\u67d0\u4e9b\u5305\uff08\u6216\u5b83\u4eec\u7684\u4f9d\u8d56\uff09\u662f\u7528 Rust/C/C++ \u5f00\u53d1\u7684\uff0cQPython \u65e0\u6cd5\u76f4\u63a5\u652f\u6301\u5b83\u4eec\uff0c\u56e0\u4e3a QPython \u4e0a\u6ca1\u6709\u7f16\u8bd1\u5668\u5de5\u5177\u94fe\u652f\u6301\u3002\u4f46\u662f\uff0cQPython \u56e2\u961f\u5df2\u7ecf\u9884\u7f16\u8bd1\u4e86\u4e00\u4e9b\u5e38\u7528\u5305\uff0c\u5e76\u5728 QPython \u7684 QPYPI/Extensions \u4e2d\u53d1\u5e03\uff0c\u4f9b\u7528\u6237\u8f7b\u677e\u5b89\u88c5\u3002

          "},{"location":"qpypi-guide/#_3","title":"\u5b89\u88c5\u9884\u7f16\u8bd1\u5305","text":"

          \u60a8\u53ef\u4ee5\u901a\u8fc7\u4ee5\u4e0b\u65b9\u5f0f\u5b89\u88c5\u9884\u7f16\u8bd1\u5305\uff1a

          1. \u901a\u8fc7 QPython \u5e94\u7528\uff1a\u76f4\u63a5\u4ece QPython \u5e94\u7528\u5185\u7684 QPYPI \u6216 Extensions \u5b89\u88c5
          2. \u901a\u8fc7 PyPI\uff1a\u8bbf\u95ee https://pypi.org/user/qpythonx/ \u67e5\u770b\u53ef\u7528\u7684\u5305
          3. \u901a\u8fc7 pip \u547d\u4ee4\uff1a
          4. pip install xxx-qpython - \u5e26 -qpython \u540e\u7f00\u7684\u5305
          5. pip install xxx-aipy - \u5e26 -aipy \u540e\u7f00\u7684\u5305\uff08\u901a\u5e38\u662f AI/ML \u76f8\u5173\u7684\u5305\uff09

          \u6ce8\u610f\uff1a\u6211\u4eec\u901a\u5e38\u6839\u636e\u5305\u7684\u9884\u671f\u7528\u9014\u6dfb\u52a0\u8fd9\u4e9b\u540e\u7f00\u4e4b\u4e00\u3002

          "},{"location":"qpypi-guide/#_4","title":"\u8bf7\u6c42\u65b0\u5305","text":"

          \u5982\u679c\u60a8\u9700\u8981\u5f53\u524d\u4e0d\u652f\u6301\u7684\u5305\uff1a

          • \u5728 qpython.org \u9879\u76ee \u4e2d\u63d0\u51fa\u95ee\u9898
          • QPython \u56e2\u961f\u5c06\u8003\u8651\u9884\u7f16\u8bd1\u5e76\u5c06\u5176\u6dfb\u52a0\u5230\u4ed3\u5e93\u4e2d

          \u83b7\u53d6\u66f4\u591a\u5e2e\u52a9\u548c\u53c2\u4e0e\u793e\u533a\u7684\u65b9\u5f0f\uff0c\u8bf7\u53c2\u9605 \u793e\u533a\u4e0e\u53cd\u9988 \u90e8\u5206\u3002

          \u6ce8\u610f\uff1a\u7531\u4e8e\u4e0d\u540c\u7684\u8ba1\u7b97\u673a\u67b6\u6784\uff0c\u6211\u4eec\u65e0\u6cd5\u4fdd\u8bc1 QPYPI \u5305\u542b PyPI \u4e0a\u7684\u6240\u6709\u5305\u3002

          "},{"location":"qpython-x/","title":"QPython \u7248\u672c","text":"

          QPython \u662f Android \u7684 Python \u5f15\u64ce\u3002\u5b83\u5305\u542b\u4ee4\u4eba\u60ca\u53f9\u7684\u529f\u80fd\uff0c\u5982 Python \u89e3\u91ca\u5668\u3001\u8fd0\u884c\u73af\u5883\u3001\u7f16\u8f91\u5668\u3001QPYI \u548c\u96c6\u6210\u7684 SL4A\u3002\u5b83\u8ba9\u60a8\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 Android \u4e0a\u4f7f\u7528 Python\u3002\u800c\u4e14\u5b83\u662f\u514d\u8d39\u7684\u3002

          QPython \u5df2\u7ecf\u5728\u5168\u7403\u62e5\u6709\u6570\u767e\u4e07\u7528\u6237\uff0c\u4e5f\u662f\u4e00\u4e2a\u5f00\u6e90\u9879\u76ee\u3002

          \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

          "},{"location":"qpython-x/#qpython_1","title":"QPython","text":"

          \u6807\u51c6\u7248\uff1a\u9488\u5bf9 AI \u6027\u80fd\u548c\u901a\u7528\u5e94\u7528\u5546\u5e97\u517c\u5bb9\u6027\u4f18\u5316

          \u4e3b\u8981\u7248\u672c\uff0c\u53ef\u5728 Google Play \u548c\u5176\u4ed6\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002\u6b64\u7248\u672c\u4e13\u6ce8\u4e8e AI \u529f\u80fd\uff0c\u4f7f AI \u65f6\u4ee3\u7528\u6237\u66f4\u5bb9\u6613\u5b66\u4e60\u548c\u4f7f\u7528 Python\u3002

          \u4e3b\u8981\u7279\u6027\uff1a - AI \u9a71\u52a8\u7684\u7f16\u7801\u8f85\u52a9\u548c\u5b66\u4e60\u5de5\u5177 - \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668\uff1a\u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51 - \u652f\u6301\u591a\u79cd\u9879\u76ee\u7c7b\u578b\uff1a\u63a7\u5236\u53f0\u3001SL4A\u3001WebApp - \u65b9\u4fbf\u7684\u4e8c\u7ef4\u7801\u8bfb\u53d6\u5668\uff0c\u7528\u4e8e\u5c06\u4ee3\u7801\u4f20\u8f93\u5230\u624b\u673a - QPYPI \u548c\u81ea\u5b9a\u4e49\u4ed3\u5e93\uff0c\u7528\u4e8e\u9884\u7f16\u8bd1 wheel \u5305 -\u6613\u4e8e\u4f7f\u7528\u7684\u8bed\u6cd5\u9ad8\u4eae\u7f16\u8f91\u5668 - \u5b8c\u5584\u7684\u6587\u6863\u548c\u793e\u533a\u652f\u6301

          \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

          \u4e0b\u8f7d\uff1a \u53ef\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

          "},{"location":"qpython-x/#qpython_2","title":"QPython+","text":"

          \u793e\u533a\u7248\uff1a\u516c\u5f00\u652f\u6301\u5404\u79cd\u793e\u533a\u9a71\u52a8\u7684\u529f\u80fd\uff1b\u53ef\u5728\u90e8\u5206\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

          \u793e\u533a\u5f00\u6e90\u7248\u672c\uff08\u6b63\u5728\u89c4\u5212\u548c\u51c6\u5907\u4e2d\uff09\u3002\u6b64\u7248\u672c\u4e13\u4e3a\u60f3\u8981\u53c2\u4e0e QPython \u9879\u76ee\u5f00\u53d1\u7684\u8d21\u732e\u8005\u800c\u8bbe\u8ba1\uff0c\u652f\u6301\u9488\u5bf9\u4e0d\u540c\u5236\u9020\u5546\u7684\u5b9a\u5236\u3002

          \u4e3b\u8981\u7279\u6027\uff1a - \u793e\u533a\u9a71\u52a8\u5f00\u53d1 - \u652f\u6301\u4f9b\u5e94\u5546\u5b9a\u5236 - \u66f4\u7075\u6d3b\u7684\u914d\u7f6e\u9009\u9879 - \u5f00\u653e\u4f9b\u8d21\u732e\u8005\u52a0\u5165\u5f00\u53d1

          \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

          \u4e0b\u8f7d\uff1a \u5c06\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

          \u6ce8\u610f\uff1a \u6b64\u7248\u672c\u76ee\u524d\u6b63\u5728\u89c4\u5212\u51c6\u5907\u4e2d\u3002\u8bf7\u5173\u6ce8\u66f4\u65b0\uff01

          "},{"location":"qpython-x/#qpython-plus","title":"QPython Plus","text":"

          QPython+ \u5b8c\u5168\u8bbf\u95ee\u7248\uff1a\u6388\u4e88\u8c03\u7528\u6240\u6709 Android \u63a5\u53e3\u7684\u5b8c\u6574\u6743\u9650\u3002\u4e0b\u8f7d\u94fe\u63a5\u4ec5\u901a\u8fc7\u5b98\u65b9\u4e91\u76d8\u63d0\u4f9b\u3002

          \u5177\u6709\u6269\u5c55\u6743\u9650\u7684\u7279\u6b8a\u7248\u672c\uff0c\u63d0\u4f9b\u5bf9\u8bbe\u5907\u7684\u6700\u5927\u63a7\u5236\u3002\u7531\u4e8e\u5176\u654f\u611f\u7684\u6743\u9650\u8981\u6c42\uff0c\u6b64\u7248\u672c\u4e0d\u4f1a\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u53d1\u5e03\u3002

          \u4e3b\u8981\u7279\u6027\uff1a - \u5b8c\u6574\u7684 SL4A API \u8bbf\u95ee\uff0c\u5305\u62ec\u654f\u611f\u529f\u80fd - SMS/\u901a\u8bdd\u63a7\u5236 API - \u9ad8\u7ea7\u7cfb\u7edf\u96c6\u6210 - \u6700\u5927\u7684\u8bbe\u5907\u63a7\u5236\u80fd\u529b

          \u6743\u9650\uff1a \u9700\u8981\u5e7f\u6cdb\u7684\u6743\u9650\uff0c\u5305\u62ec\uff1a - \u84dd\u7259 - \u4f4d\u7f6e\uff08GPS\uff09 - \u8bfb\u53d6/\u53d1\u9001\u77ed\u4fe1 - \u6253\u7535\u8bdd - \u76f8\u673a\u548c\u9ea6\u514b\u98ce - \u7cfb\u7edf\u8bbe\u7f6e - \u4ee5\u53ca\u5176\u4ed6\u654f\u611f\u6743\u9650

          \u4e0b\u8f7d\uff1a \u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\u3002\u4ec5\u901a\u8fc7\u7279\u6b8a\u6e20\u9053\u5206\u53d1\u3002

          \u91cd\u8981\u63d0\u793a\uff1a QPython \u4e0d\u4f1a\u5728\u540e\u53f0\u672a\u7ecf\u60a8\u77e5\u6089\u4f7f\u7528\u8fd9\u4e9b\u6743\u9650\u3002\u5982\u679c\u4f7f\u7528 SL4A API \u65f6\u51fa\u73b0\u5f02\u5e38\uff0c\u8bf7\u68c0\u67e5\u7cfb\u7edf\u8bbe\u7f6e\u4e2d\u662f\u5426\u5df2\u542f\u7528\u76f8\u5173\u6743\u9650\u3002

          "},{"location":"tutorial-hello-world/","title":"\u7f16\u5199\"Hello World\"","text":""},{"location":"tutorial-hello-world/#hello-world_1","title":"Hello world","text":"

          \u597d\u7684\uff0c\u5728\u60a8\u5bf9 QPython \u6709\u4e86\u4e00\u5b9a\u7684\u4e86\u89e3\u4e4b\u540e\uff0c\u8ba9\u6211\u4eec\u5728 QPython \u4e2d\u521b\u5efa\u6211\u4eec\u7684\u7b2c\u4e00\u4e2a\u7a0b\u5e8f\u3002\u663e\u7136\uff0c\u5b83\u5c06\u662f helloworld.py\u3002;)

          \u542f\u52a8 QPython\uff0c\u6253\u5f00\u7f16\u8f91\u5668\u5e76\u8f93\u5165\u4ee5\u4e0b\u4ee3\u7801\uff1a

          #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello, QPYTHON!')\n

          \u6beb\u65e0\u7591\u95ee\uff0c\u5b83\u4e0e\u5176\u4ed6\u4efb\u4f55 hello-world \u7a0b\u5e8f\u5e76\u65e0\u4e0d\u540c\u3002\u6267\u884c\u65f6\uff0c\u5b83\u53ea\u662f\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u5f39\u51fa\u6d88\u606f\uff08\u89c1\u9876\u90e8\u622a\u56fe\uff09\u3002\u65e0\u8bba\u5982\u4f55\uff0c\u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684 QPython \u7a0b\u5e8f\u793a\u4f8b\u3002

          "},{"location":"tutorial-hello-world/#_1","title":"\u4ee3\u7801\u7406\u89e3","text":"

          \u5b83\u4ee5 import androidhelper \u5f00\u5934\u2014\u2014\u8fd9\u662f QPython \u4e2d\u6700\u6709\u7528\u7684\u6a21\u5757\uff0c\u5b83\u5c01\u88c5\u4e86 Python \u4e2d\u53ef\u7528\u7684\u51e0\u4e4e\u6240\u6709\u4e0e Android \u7684\u63a5\u53e3\u3002\u4efb\u4f55\u5728 QPython \u4e2d\u5f00\u53d1\u7684\u811a\u672c\u90fd\u4ee5\u8fd9\u4e2a\u8bed\u53e5\u5f00\u5934\uff08\u81f3\u5c11\u5982\u679c\u5b83\u58f0\u79f0\u8981\u4e0e\u7528\u6237\u901a\u4fe1\u7684\u8bdd\uff09\u3002\u5728\u6b64\u5904\u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u5e93 \u548c import \u8bed\u53e5 \u7684\u5185\u5bb9\u3002

          \u63a5\u4e0b\u6765\u6211\u4eec\u521b\u5efa\u4e00\u4e2a droid \u5bf9\u8c61\uff08\u5b9e\u9645\u4e0a\u662f\u4e00\u4e2a\u7c7b\uff09\uff0c\u5b83\u5bf9\u4e8e\u8c03\u7528 RPC \u51fd\u6570\u4ee5\u4e0e Android \u901a\u4fe1\u662f\u5fc5\u8981\u7684\u3002

          \u6211\u4eec\u4ee3\u7801\u7684\u6700\u540e\u4e00\u884c\u8c03\u7528\u4e86\u8fd9\u6837\u7684\u51fd\u6570\uff0cdroid.makeToast()\uff0c\u5b83\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u4e00\u4e2a\u5c0f\u7684\u5f39\u51fa\u6d88\u606f\uff08\"toast\"\uff09\u3002

          \u597d\u7684\uff0c\u8ba9\u6211\u4eec\u6dfb\u52a0\u4e00\u4e9b\u66f4\u591a\u7684\u529f\u80fd\u3002\u8ba9\u5b83\u8be2\u95ee\u7528\u6237\u540d\u5e76\u5411\u7528\u6237\u6253\u62db\u547c\u3002

          "},{"location":"tutorial-hello-world/#_2","title":"\u66f4\u591a\u793a\u4f8b","text":"

          \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 dialogGetInput \u8c03\u7528\u663e\u793a\u4e00\u4e2a\u5e26\u6709\u6807\u9898\u3001\u63d0\u793a\u3001\u7f16\u8f91\u5b57\u6bb5\u548c \u786e\u5b9a \u548c \u53d6\u6d88 \u6309\u94ae\u7684\u7b80\u5355\u5bf9\u8bdd\u6846\u3002\u7528\u4ee5\u4e0b\u4ee3\u7801\u66ff\u6362\u60a8\u7684\u6700\u540e\u4e00\u884c\u4ee3\u7801\u5e76\u5c06\u5176\u4fdd\u5b58\u4e3a hello1.py\uff1a

          #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\n

          \u597d\u7684\uff0c\u6211\u8ba4\u4e3a\u5b83\u5e94\u8be5\u8fd4\u56de\u4efb\u4f55\u54cd\u5e94\uff0c\u4efb\u4f55\u7528\u6237\u53cd\u5e94\u3002\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u6211\u5199 respond = ...\u3002\u4f46\u8fd9\u4e2a\u8c03\u7528\u5b9e\u9645\u4e0a\u8fd4\u56de\u4ec0\u4e48\uff1f\u8ba9\u6211\u4eec\u68c0\u67e5\u4e00\u4e0b\u3002\u53ea\u9700\u5728\u6700\u540e\u4e00\u884c\u540e\u6dfb\u52a0 print \u8bed\u53e5\uff1a

          #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\n

          \u7136\u540e\u4fdd\u5b58\u5e76\u8fd0\u884c\u5b83...

          \u54ce\u5440\uff01\u6ca1\u6709\u6253\u5370\uff1f\u522b\u62c5\u5fc3\u3002\u53ea\u9700\u62c9\u4e0b\u901a\u77e5\u680f\uff0c\u60a8\u5c31\u4f1a\u770b\u5230\"QPython Program Output: hello1.py\"\u2014\u2014\u70b9\u51fb\u5b83\uff01

          \u5982\u60a8\u6240\u89c1\uff0cdroid.dialogGetInput() \u8fd4\u56de\u4e00\u4e2a\u5305\u542b\u4e09\u4e2a\u5b57\u6bb5\u7684 JSON \u5bf9\u8c61\u3002\u6211\u4eec\u53ea\u9700\u8981\u4e00\u4e2a\u2014\u2014result\uff0c\u5176\u4e2d\u5305\u542b\u7528\u6237\u5b9e\u9645\u8f93\u5165\u7684\u5185\u5bb9\u3002

          \u8ba9\u6211\u4eec\u6dfb\u52a0\u811a\u672c\u7684\u53cd\u5e94\uff1a

          #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nmessage = f'Hello, {respond.result}!'\ndroid.makeToast(message)\n

          \u6700\u540e\u4e24\u884c\uff081\uff09\u683c\u5f0f\u5316\u6d88\u606f\uff0c\uff082\uff09\u4ee5 toast \u5f62\u5f0f\u5411\u7528\u6237\u663e\u793a\u6d88\u606f\u3002\u5982\u679c\u60a8\u4ecd\u7136\u4e0d\u77e5\u9053 f-string \u662f\u4ec0\u4e48\u610f\u601d\uff0c\u8bf7\u53c2\u9605 Python \u6587\u6863\u3002

          \u54c7\uff01\u5b83\u5de5\u4f5c\u4e86\uff01;)

          \u73b0\u5728\u6211\u8981\u5728\u90a3\u91cc\u6dfb\u52a0\u4e00\u4e9b\u903b\u8f91\u3002\u60f3\u4e00\u60f3\uff1a\u5982\u679c\u7528\u6237\u70b9\u51fb \u53d6\u6d88 \u6309\u94ae\uff0c\u6216\u8005\u70b9\u51fb \u786e\u5b9a \u4f46\u5c06\u8f93\u5165\u5b57\u6bb5\u7559\u7a7a\uff0c\u4f1a\u53d1\u751f\u4ec0\u4e48\uff1f

          \u60a8\u53ef\u4ee5\u73a9\u8fd9\u4e2a\u7a0b\u5e8f\uff0c\u68c0\u67e5 respond \u53d8\u91cf\u5728\u6bcf\u79cd\u60c5\u51b5\u4e0b\u5305\u542b\u4ec0\u4e48\u3002

          \u9996\u5148\uff0c\u6211\u60f3\u5c06\u7528\u6237\u8f93\u5165\u7684\u6587\u672c\u653e\u5165\u4e00\u4e2a\u5355\u72ec\u7684\u53d8\u91cf\u4e2d\uff1aname = respond.result\u3002\u7136\u540e\u6211\u68c0\u67e5\u5b83\uff0c\u5982\u679c\u5b83\u5305\u542b\u4efb\u4f55\u771f\u5b9e\u6587\u672c\uff0c\u5b83\u5c06\u88ab\u89c6\u4e3a\u540d\u79f0\u5e76\u7528\u4e8e\u95ee\u5019\u3002\u5426\u5219\uff0c\u5c06\u663e\u793a\u53e6\u4e00\u6761\u6d88\u606f\u3002\u5c06\u7b2c\u4e94\u884c message = f'Hello, {respond.result}!' \u66ff\u6362\u4e3a\u4ee5\u4e0b\u4ee3\u7801\uff1a

          name = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\n

          \u4f7f\u7528\u5de5\u5177\u680f\u4e0a\u7684 < \u548c > \u6309\u94ae\u6765\u7f29\u8fdb/\u53d6\u6d88\u7f29\u8fdb if \u8bed\u53e5\u4e2d\u7684\u884c\uff08\u6216\u8005\u53ea\u9700\u4f7f\u7528\u7a7a\u683c/\u9000\u683c\u952e\uff09\u3002\u60a8\u53ef\u4ee5\u5728 \u6b64\u5904 \u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u7f29\u8fdb\u7684\u5185\u5bb9\uff1bif \u8bed\u53e5\u5728 \u6b64\u5904 \u63cf\u8ff0\u3002

          \u9996\u5148\uff0c\u6211\u4eec\u5c06\u7528\u6237\u8f93\u5165\u653e\u5165 name \u53d8\u91cf\u3002\u7136\u540e\u6211\u4eec\u68c0\u67e5 name \u662f\u5426\u5305\u542b\u4efb\u4f55\u5185\u5bb9\uff1f\u5982\u679c\u7528\u6237\u7559\u7a7a\u884c\u5e76\u70b9\u51fb \u786e\u5b9a\uff0c\u8fd4\u56de\u503c\u662f\u7a7a\u5b57\u7b26\u4e32 ''\u3002\u5982\u679c\u6309\u4e0b\u4e86 \u53d6\u6d88 \u6309\u94ae\uff0c\u8fd4\u56de\u503c\u662f None\u3002\u5728 if \u8bed\u53e5\u4e2d\uff0c\u4e24\u8005\u90fd\u88ab\u89c6\u4e3a\u5047\u3002\u56e0\u6b64\uff0c\u53ea\u6709\u5f53 name \u5305\u542b\u4efb\u4f55\u6709\u610f\u4e49\u7684\u5185\u5bb9\u65f6\uff0cthen \u8bed\u53e5\u624d\u4f1a\u6267\u884c\uff0c\u5e76\u663e\u793a\u95ee\u5019\u8bed\"Hello, ...!\"\u3002\u5982\u679c\u8f93\u5165\u4e3a\u7a7a\uff0c\u7528\u6237\u5c06\u770b\u5230\"Hey! And you're not very polite, %Username%!\"\u6d88\u606f\u3002

          \u597d\u7684\uff0c\u8fd9\u662f\u6574\u4e2a\u7a0b\u5e8f\uff1a

          #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nname = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\ndroid.makeToast(message)\n
          "},{"location":"tutorial-hello-world/#_3","title":"\u8fd0\u884c\u6548\u679c","text":""},{"location":"tutorial-hello-world/#_4","title":"\u4e0b\u4e00\u6b65","text":"

          \u5bf9\u4e8e Python \u65b0\u7528\u6237\uff0c\u63a8\u8350\u5b66\u4e60 Python \u8bed\u6cd5\u5b9e\u8df5 \u8bfe\u7a0b\u6765\u8fdb\u4e00\u6b65\u5b66\u4e60 Python\uff0c\u6216\u8005\u5728 QPython \u7cbe\u9009\u8bfe\u7a0b \u4e2d\u5bfb\u627e\u60f3\u8981\u5b66\u4e60\u7684\u5185\u5bb9\u3002

          "},{"location":"whats-new/","title":"\u66f4\u65b0\u65e5\u5fd7","text":""},{"location":"whats-new/#v392-v393","title":"v3.9.2 / v3.9.3","text":"
          • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
          • \u7f16\u8f91\u5668\u91cd\u5927\u66f4\u65b0\uff0c\u5e26\u6765\u66f4\u6d41\u7545\u7684\u7f16\u8f91\u4f53\u9a8c
          • \u5176\u4ed6\u5404\u79cd\u5c0f\u6539\u8fdb
          "},{"location":"whats-new/#v391","title":"v3.9.1","text":"
          • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
          • \u6269\u5c55\u5305\u73b0\u5728\u652f\u6301 MCP
          • \u9519\u8bef\u4fee\u590d
          "},{"location":"whats-new/#v390","title":"v3.9.0","text":"
          • SDK \u5347\u7ea7\uff0c\u6574\u5408\u6700\u65b0\u7684 Android \u529f\u80fd
          • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
          • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
          • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
          "},{"location":"whats-new/#v3811","title":"v3.8.11","text":"
          • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
          • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
          • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
          "},{"location":"whats-new/#v3810","title":"v3.8.10","text":"
          • \u5185\u7f6e Ollama \u5347\u7ea7\uff1a\u73b0\u5728\u60a8\u53ef\u4ee5\u5728 QPython \u4e2d\u8f7b\u677e\u672c\u5730\u8fd0\u884c Qwen3 / Gemma3 \u6a21\u578b\uff01
          • \u6dfb\u52a0\u4e86\u5f3a\u5927\u7684 MCP \u5e93\uff1a\u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 mcp \u5e93\uff0c\u8ba9\u60a8\u968f\u65f6\u968f\u5730\u643a\u5e26\u5f3a\u5927\u7684 MCP \u529f\u80fd\uff01
          "},{"location":"whats-new/#v389","title":"v3.8.9","text":"

          \u91cd\u5927\u66f4\u65b0\uff01AI \u7f16\u7a0b\u5b8c\u5168\u96c6\u6210\u5230 QPython\uff0c\u8ba9\u60a8\u7684\u7f16\u7a0b\u66f4\u8f7b\u677e\uff01

          • \u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u652f\u6301\uff1a\u65b0\u652f\u6301 AIPyApp\uff0c\u5728 QPython \u4e2d\u5b9e\u73b0\u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u3002\u76ee\u524d\u5904\u4e8e\u6d4b\u8bd5\u9636\u6bb5 - \u52a0\u5165\u6211\u4eec\u7684\u793e\u533a\u83b7\u53d6\u4f7f\u7528\u8bf4\u660e
          • \u65b0 QSL4A \u529f\u80fd\uff1a\u6dfb\u52a0 notebookOpen \u51fd\u6570\uff0c\u652f\u6301\u81ea\u7136\u8bed\u8a00\u63a7\u5236\u6253\u5f00 Notebook \u6587\u4ef6
          • \u5185\u7f6e\u7f16\u8f91\u5668\u5347\u7ea7\uff1a\u589e\u5f3a\u7f16\u8f91\u5668\u529f\u80fd\uff0c\u652f\u6301\u6253\u5f00\u548c\u6d4f\u89c8\u5404\u79cd\u6587\u672c\u6587\u4ef6
          • \u4fbf\u6377\u7684\u6587\u4ef6\u7ba1\u7406\uff1a\u5728\u6587\u4ef6\u7ba1\u7406\u5668\u4e2d\u6dfb\u52a0\u5185\u90e8\u5b58\u50a8\u5165\u53e3\uff0c\u5feb\u901f\u8bbf\u95ee\u60a8\u7684\u6587\u4ef6
          "},{"location":"whats-new/#v388","title":"v3.8.8","text":"
          • \u6587\u4ef6\u8bbf\u95ee\u6743\u9650\u63a7\u5236\u7684\u91cd\u8981\u6539\u8fdb\uff0c\u5141\u8bb8\u7528\u6237\u7075\u6d3b\u5730\u901a\u8fc7 QPython \u7f16\u7a0b\u542f\u7528\u6216\u7981\u7528\u5916\u90e8\u5b58\u50a8\u6587\u4ef6\u7684\u8bbf\u95ee
          • SDK \u5347\u7ea7\uff0c\u589e\u5f3a\u4e86\u5bf9\u65b0\u7248 Android \u7684\u652f\u6301\u548c\u517c\u5bb9\u6027
          • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Anthropic \u548c Google GenAI \u5e93
          "},{"location":"whats-new/#v387","title":"v3.8.7","text":"
          • \u5728\u73b0\u6709 Tkinter \u652f\u6301\u57fa\u7840\u4e0a\uff0c\u5728 Extensions -> Tools \u4e2d\u6dfb\u52a0\u4e86\u4f7f\u7528 Turtle \u7ed8\u5236\u54c6\u5566A\u68a6\u7684\u793a\u4f8b\u4ee3\u7801
          • \u4f18\u5316\u4e86\u624b\u673a\u6743\u9650\u83b7\u53d6\u6d41\u7a0b\uff0c\u63d0\u5347\u7528\u6237\u4f53\u9a8c\u548c\u64cd\u4f5c\u4fbf\u5229\u6027
          • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Google Gen AI \u5e93\uff0c\u65b9\u4fbf\u8bbf\u95ee Gemini Developer API \u548c Vertex AI
          "},{"location":"whats-new/#v386","title":"v3.8.6","text":"
          • Tkinter \u652f\u6301\uff1a\u73b0\u5728\u652f\u6301 Tkinter \u5e93\uff0c\u53ef\u901a\u8fc7 XServer \u8bbf\u95ee\u3002\u8bf7\u8bbf\u95ee www.qpython.org \u7684\u4e91\u76d8\"Extra\"\u94fe\u63a5\u4e0b\u8f7d\u6240\u9700\u6587\u4ef6
          • \u5b58\u50a8\u6743\u9650\u66f4\u65b0\uff1a\u4e3a\u6539\u5584\u7528\u6237\u4f53\u9a8c\uff0c\u6211\u4eec\u6dfb\u52a0\u4e86\u8bfb\u53d6\u624b\u673a\u5b58\u50a8\u7684\u6743\u9650\uff0c\u7528\u4e8e\u8bbf\u95ee\u5b58\u50a8\u5728\u5176\u4ed6\u76ee\u5f55\u4e2d\u7684 Python \u7a0b\u5e8f

          \u6b64\u66f4\u65b0\u540e\uff0cQPython \u548c QPythonPlus\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff0c\u4e13\u4e3a\u9700\u8981\u66f4\u591a\u654f\u611f\u6743\u9650\u7684\u9ad8\u7ea7\u7528\u6237\u8bbe\u8ba1\uff09\u5c06\u4fdd\u6301\u540c\u6b65\u7684\u7248\u672c\u53f7\u3002

          "},{"location":"whats-new/#v352-2025225","title":"v3.5.2 (2025/2/25)","text":"

          \u4e0e\u5f00\u6e90 LLM \u90e8\u7f72\u5de5\u5177 Ollama \u4ee5\u53ca DeepSeek \u5f00\u53d1\u7684 DeepSeek \u5b9e\u73b0\u65e0\u7f1d\u96c6\u6210\uff01

          \u529f\u80fd\uff1a - \u96f6\u95e8\u69db\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5404\u79cd\u5927\u578b\u8bed\u8a00\u6a21\u578b - \u5feb\u901f\u90e8\u7f72 DeepSeek \u7b49\u5c16\u7aef AI \u6a21\u578b - \u4eab\u53d7\u7b80\u7ea6\u7684 API \u8c03\u7528\u4f53\u9a8c - \u6784\u5efa\u5b8c\u5168\u79bb\u7ebf\u7684\u667a\u80fd\u7f16\u7a0b\u73af\u5883

          \u80fd\u529b\uff1a - \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u52a0\u8f7d/\u7ba1\u7406 LLM \u6a21\u578b - \u57fa\u4e8e\u672c\u5730\u8ba1\u7b97\u7684\u5b9e\u65f6\u4f4e\u5ef6\u8fdf\u54cd\u5e94

          "},{"location":"whats-new/#v350","title":"v3.5.0","text":"
          • Python \u5347\u7ea7\u5230 3.12.8
          • \u6539\u8fdb\u4eea\u8868\u76d8\uff0c\u529f\u80fd\u66f4\u6e05\u6670\u3001\u66f4\u4eba\u6027\u5316
          • \u6dfb\u52a0\u4e86\u4f17\u591a\u7b2c\u4e09\u65b9\u5305\uff1aPyTorch / Twisted / Scrapy / FastAPI ...
          "},{"location":"whats-new/#v338","title":"v3.3.8","text":"
          • \u4fee\u590d\u4e86 NumPy \u517c\u5bb9\u6027\u95ee\u9898
          "},{"location":"whats-new/#v335","title":"v3.3.5","text":"
          • \u5347\u7ea7 Python \u5185\u6838\u5230 3.11.9
          • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u4e0d\u663e\u793a\u6a21\u5757\u5b89\u88c5\u72b6\u6001\u7684 bug
          • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u5220\u9664\u6a21\u5757\u5931\u8d25\u7684 bug
          • \u4fee\u590d\u4e86\u5176\u4ed6 bug
          "},{"location":"whats-new/#v334","title":"v3.3.4","text":"
          • \u6dfb\u52a0\u4e86 OpenAI/Langchain/APIGPTCloud AI \u5305
          • \u79fb\u9664\u4e0d\u5fc5\u8981\u7684\u6587\u4ef6\u4ee5\u51cf\u5c11\u5927\u5c0f
          "},{"location":"whats-new/#v325","title":"v3.2.5","text":"
          • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570
          • \u5176\u4ed6\u9519\u8bef\u4fee\u590d
          "},{"location":"whats-new/#v323","title":"v3.2.3","text":"
          • \u66f4\u65b0 Python \u7248\u672c\u5230 3.11.0
          • \u66f4\u65b0 IPython \u7248\u672c\u5230 8.6.0
          • \u66f4\u65b0 pip \u7248\u672c\u5230 22.3.1
          • \u66f4\u65b0\u79d1\u5b66\u8ba1\u7b97\u5305\uff0c\u81ea\u52a8\u8f6f\u94fe\u63a5
          • \u51cf\u5c11\u7a7a\u95f4\u4f7f\u7528
          • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570 + \u5176\u4ed6\u9519\u8bef\u4fee\u590d
          "},{"location":"whats-new/#v318","title":"v3.1.8","text":"
          • \u5728\u7ec8\u7aef\u4e2d\u6dfb\u52a0\u4e86\u64cd\u4f5c\u70ed\u952e
          • \u4fee\u590d\u4e86\u7f16\u8f91\u5668\u5728\u65cb\u8f6c\u65f6\u4e22\u5931\u5185\u5bb9\u7684\u95ee\u9898
          • \u4fee\u590d\u4e86\u5176\u4ed6 bug

          \u5728 Google Play \u4e0b\u8f7d

          "},{"location":"qsl4a/","title":"QSL4A\uff08Android \u811a\u672c\u5c42\uff09API \u6587\u6863","text":"

          QSL4A \u662f QPython \u7684 Android \u811a\u672c\u5c42\uff0c\u5141\u8bb8\u60a8\u4f7f\u7528 Python \u63a7\u5236 Android \u8bbe\u5907\u529f\u80fd\u3002

          "},{"location":"qsl4a/#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a toast \u6d88\u606f\ndroid.makeToast('Hello QPython!')\n\n# \u9707\u52a8\u8bbe\u5907\ndroid.vibrate(500)\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\uff08\u5148\u5f00\u59cb\u76d1\u63a7\uff09\nimport time\ndroid.batteryStartMonitoring()\ntime.sleep(0.5)  # \u7b49\u5f85\u6570\u636e\nbattery = droid.readBatteryData().result\nprint(f\"\u7535\u6c60\uff1a{battery['level']}%\")\n
          "},{"location":"qsl4a/#_2","title":"\u6587\u6863\u7ed3\u6784","text":""},{"location":"qsl4a/#_3","title":"\u6838\u5fc3\u6a21\u5757","text":"
          • Android \u57fa\u7840 - \u6838\u5fc3\u8fde\u63a5\u548c RPC
          • Intent \u7cfb\u7edf - Android Intent \u64cd\u4f5c
          • \u4e8b\u4ef6\u7cfb\u7edf - \u4e8b\u4ef6\u5904\u7406\u548c\u5e7f\u64ad
          "},{"location":"qsl4a/#ui","title":"UI \u7ec4\u4ef6","text":"
          • \u5bf9\u8bdd\u6846 - \u8b66\u62a5\u3001\u8f93\u5165\u3001\u9009\u62e9\u5bf9\u8bdd\u6846
          • \u5168\u5c4f UI - \u81ea\u5b9a\u4e49\u5e03\u5c40 UI
          • \u60ac\u6d6e\u7a97 - \u60ac\u6d6e\u7a97\u53e3
          • \u8f85\u52a9\u529f\u80fd - \u5c4f\u5e55\u81ea\u52a8\u5316
          "},{"location":"qsl4a/#_4","title":"\u7cfb\u7edf","text":"
          • \u7535\u6c60 - \u7535\u6c60\u76d1\u63a7
          • \u4f20\u611f\u5668 - \u8bbe\u5907\u4f20\u611f\u5668
          • \u5e94\u7528 - \u5e94\u7528\u7ba1\u7406
          • \u7cfb\u7edf\u4fe1\u606f - \u8bbe\u5907\u4fe1\u606f
          • \u8bbe\u7f6e - \u7cfb\u7edf\u8bbe\u7f6e
          • \u5524\u9192\u9501 - \u5524\u9192\u9501\u63a7\u5236
          • QPython \u63a5\u53e3 - \u811a\u672c\u6267\u884c
          • Activity \u7ed3\u679c - Activity \u7ed3\u679c\u5904\u7406
          "},{"location":"qsl4a/#_5","title":"\u786c\u4ef6","text":"
          • \u84dd\u7259 - \u84dd\u7259\u64cd\u4f5c
          • \u76f8\u673a - \u62cd\u7167\u548c\u5f55\u50cf
          • \u97f3\u9891/\u5f55\u97f3\u5668 - \u5f55\u97f3
          • \u7f51\u7edc\u6444\u50cf\u5934 - MJPEG \u6d41
          • USB \u4e32\u53e3 - USB \u4e3b\u673a\u4e32\u53e3
          "},{"location":"qsl4a/#_6","title":"\u8fde\u63a5","text":"
          • WiFi - WiFi \u64cd\u4f5c
          • \u4f4d\u7f6e - GPS \u548c\u4f4d\u7f6e
          • \u77ed\u4fe1 - \u77ed\u4fe1\u64cd\u4f5c
          • \u7535\u8bdd - \u6253\u7535\u8bdd\u548c\u6765\u7535\u4fe1\u606f
          • \u8054\u7cfb\u4eba - \u8054\u7cfb\u4eba\u7ba1\u7406
          • \u4fe1\u53f7\u5f3a\u5ea6 - \u4fe1\u53f7\u76d1\u63a7
          • FTP \u670d\u52a1\u5668 - \u5185\u7f6e FTP \u670d\u52a1\u5668
          "},{"location":"qsl4a/#_7","title":"\u5b58\u50a8","text":"
          • DocumentFile - \u6587\u4ef6\u64cd\u4f5c
          • \u526a\u8d34\u677f - \u526a\u8d34\u677f\u64cd\u4f5c
          • \u504f\u597d\u8bbe\u7f6e - \u5171\u4eab\u504f\u597d\u8bbe\u7f6e
          "},{"location":"qsl4a/#_8","title":"\u5a92\u4f53","text":"
          • \u5a92\u4f53\u64ad\u653e\u5668 - \u97f3\u9891/\u89c6\u9891\u64ad\u653e
          • \u56fe\u50cf\u5904\u7406 - \u56fe\u50cf\u64cd\u4f5c
          "},{"location":"qsl4a/#_9","title":"\u7279\u6b8a\u529f\u80fd","text":"
          • \u52a0\u5bc6 - \u52a0\u5bc6/\u89e3\u5bc6
          • PGPT AI - AI \u8bed\u97f3\u670d\u52a1
          "},{"location":"qsl4a/#_10","title":"\u7ed3\u679c\u5bf9\u8c61","text":"

          \u5927\u591a\u6570 QSL4A \u65b9\u6cd5\u8fd4\u56de\u4e00\u4e2a\u5e26\u6709\u4ee5\u4e0b\u5c5e\u6027\u7684 Result \u547d\u540d\u5143\u7ec4\uff1a - id - \u8bf7\u6c42 ID - result - \u5b9e\u9645\u7ed3\u679c\u6570\u636e - error - \u5982\u679c\u5931\u8d25\u5219\u4e3a\u9519\u8bef\u6d88\u606f

          result = droid.getClipboard()\nif result.error is None:\n    print(result.result)\nelse:\n    print(f\"\u9519\u8bef\uff1a{result.error}\")\n
          "},{"location":"qsl4a/connectivity/contacts/","title":"\u8054\u7cfb\u4eba API","text":"

          \u8bbf\u95ee\u548c\u7ba1\u7406\u8bbe\u5907\u8054\u7cfb\u4eba\u3002

          "},{"location":"qsl4a/connectivity/contacts/#_1","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":""},{"location":"qsl4a/connectivity/contacts/#pickcontact","title":"pickContact()","text":"

          \u663e\u793a\u8054\u7cfb\u4eba\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

          pickContact()\n

          \u8fd4\u56de\uff1a \u5305\u542b\u8054\u7cfb\u4eba URI \u7684 Intent

          "},{"location":"qsl4a/connectivity/contacts/#pickphone","title":"pickPhone()","text":"

          \u663e\u793a\u7535\u8bdd\u53f7\u7801\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

          pickPhone()\n

          \u8fd4\u56de\uff1a \u9009\u4e2d\u7684\u7535\u8bdd\u53f7\u7801\u5b57\u7b26\u4e32

          "},{"location":"qsl4a/connectivity/contacts/#_2","title":"\u8054\u7cfb\u4eba\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#contactsget","title":"contactsGet()","text":"

          \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\u3002

          contactsGet(attributes=None)\n

          \u53c2\u6570\uff1a - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

          \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba JSONObject \u5217\u8868

          "},{"location":"qsl4a/connectivity/contacts/#contactsgetbyid","title":"contactsGetById()","text":"

          \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\u3002

          contactsGetById(id, attributes=None)\n

          \u53c2\u6570\uff1a - id (int): \u8054\u7cfb\u4eba ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

          \u8fd4\u56de\uff1a JSONObject \u8054\u7cfb\u4eba\u6570\u636e

          "},{"location":"qsl4a/connectivity/contacts/#contactsgetcount","title":"contactsGetCount()","text":"

          \u83b7\u53d6\u8054\u7cfb\u4eba\u603b\u6570\u3002

          contactsGetCount()\n

          \u8fd4\u56de\uff1a \u6574\u6570\u8ba1\u6570

          "},{"location":"qsl4a/connectivity/contacts/#contactsgetids","title":"contactsGetIds()","text":"

          \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba ID\u3002

          contactsGetIds()\n

          \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba ID \u6574\u6570\u5217\u8868

          "},{"location":"qsl4a/connectivity/contacts/#contactsgetattributes","title":"contactsGetAttributes()","text":"

          \u83b7\u53d6\u6240\u6709\u53ef\u80fd\u7684\u8054\u7cfb\u4eba\u5c5e\u6027\u3002

          contactsGetAttributes()\n

          \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u5217\u8868

          "},{"location":"qsl4a/connectivity/contacts/#_3","title":"\u5185\u5bb9\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#querycontent","title":"queryContent()","text":"

          \u4f7f\u7528\u81ea\u5b9a\u4e49\u53c2\u6570\u67e5\u8be2\u5185\u5bb9\u89e3\u6790\u5668\u3002

          queryContent(uri, attributes=None, selection=None, selectionArgs=None, order=None)\n

          \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u5c5e\u6027 - selection (str, optional): WHERE \u5b50\u53e5 - selectionArgs (list, optional): \u9009\u62e9\u53c2\u6570 - order (str, optional): ORDER BY \u5b50\u53e5

          \u8fd4\u56de\uff1a JSONObject \u7ed3\u679c\u5217\u8868

          "},{"location":"qsl4a/connectivity/contacts/#queryattributes","title":"queryAttributes()","text":"

          \u83b7\u53d6\u5185\u5bb9 URI \u7684\u5c5e\u6027\u3002

          queryAttributes(uri)\n

          \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI

          \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u7684 JSONArray

          "},{"location":"qsl4a/connectivity/contacts/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u9009\u62e9\u8054\u7cfb\u4eba\ncontact_uri = droid.pickContact().result\nprint(f\"Selected contact: {contact_uri}\")\n\n# \u9009\u62e9\u7535\u8bdd\u53f7\u7801\nphone = droid.pickPhone().result\nprint(f\"Selected phone: {phone}\")\n\n# \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\ncontacts = droid.contactsGet().result\nprint(f\"Total contacts: {len(contacts)}\")\n\n# \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\ncontact = droid.contactsGetById(1).result\nprint(f\"Contact: {contact}\")\n\n# \u83b7\u53d6\u8054\u7cfb\u4eba\u5c5e\u6027\nattrs = droid.contactsGetAttributes().result\nprint(f\"Available attributes: {attrs}\")\n
          "},{"location":"qsl4a/connectivity/ftp/","title":"FTP \u670d\u52a1\u5668 API","text":"

          \u5728\u8bbe\u5907\u4e0a\u542f\u52a8\u548c\u7ba1\u7406\u5185\u7f6e FTP \u670d\u52a1\u5668\u3002

          "},{"location":"qsl4a/connectivity/ftp/#ftp","title":"FTP \u670d\u52a1\u5668\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/ftp/#ftpstart","title":"ftpStart()","text":"

          \u542f\u52a8 FTP \u670d\u52a1\u5668\u3002

          ftpStart()\n

          \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4 [ip, port]

          "},{"location":"qsl4a/connectivity/ftp/#ftpstop","title":"ftpStop()","text":"

          \u505c\u6b62 FTP \u670d\u52a1\u5668\u3002

          ftpStop()\n
          "},{"location":"qsl4a/connectivity/ftp/#ftpisrunning","title":"ftpIsRunning()","text":"

          \u68c0\u67e5 FTP \u670d\u52a1\u5668\u662f\u5426\u6b63\u5728\u8fd0\u884c\u3002

          ftpIsRunning()\n

          \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u8fd0\u884c\u5219\u4e3a True

          "},{"location":"qsl4a/connectivity/ftp/#ftpget","title":"ftpGet()","text":"

          \u83b7\u53d6 FTP \u670d\u52a1\u5668 IP \u5730\u5740\u3002

          ftpGet()\n

          \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4

          "},{"location":"qsl4a/connectivity/ftp/#ftpset","title":"ftpSet()","text":"

          \u914d\u7f6e FTP \u670d\u52a1\u5668\u8bbe\u7f6e\u3002

          ftpSet(port=None, rootDir=None, username=None, password=None)\n

          \u53c2\u6570\uff1a - port (int, optional): \u670d\u52a1\u5668\u7aef\u53e3 - rootDir (str, optional): \u8981\u670d\u52a1\u7684\u57fa\u7840\u76ee\u5f55 - username (str, optional): \u767b\u5f55\u7528\u6237\u540d - password (str, optional): \u767b\u5f55\u5bc6\u7801

          \u8fd4\u56de\uff1a \u5305\u542b\u5f53\u524d\u8bbe\u7f6e\u7684 JSONObject

          "},{"location":"qsl4a/connectivity/ftp/#ftpstatus","title":"ftpStatus()","text":"

          \u83b7\u53d6 FTP \u670d\u52a1\u5668\u72b6\u6001\u3002

          ftpStatus()\n

          \u8fd4\u56de\uff1a \u72b6\u6001\u63cf\u8ff0\u5b57\u7b26\u4e32

          "},{"location":"qsl4a/connectivity/ftp/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u914d\u7f6e FTP \u670d\u52a1\u5668\ndroid.ftpSet(\n    port=2121,\n    rootDir=\"/sdcard\",\n    username=\"admin\",\n    password=\"secret\"\n)\n\n# \u542f\u52a8 FTP \u670d\u52a1\u5668\ninfo = droid.ftpStart().result\nprint(f\"FTP running at {info[0]}:{info[1]}\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.ftpIsRunning().result:\n    print(\"FTP server is running\")\n\n# \u83b7\u53d6\u670d\u52a1\u5668\u4fe1\u606f\nserver_info = droid.ftpGet().result\nprint(f\"Server: {server_info}\")\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.ftpStop()\n

          \u6ce8\u610f\uff1a \u4f7f\u7528\u63d0\u4f9b\u7684\u51ed\u636e\u901a\u8fc7\u4efb\u4f55 FTP \u5ba2\u6237\u7aef\u8fde\u63a5\u5230 FTP \u670d\u52a1\u5668\u3002

          "},{"location":"qsl4a/connectivity/location/","title":"\u4f4d\u7f6e API","text":"

          \u8bbf\u95ee GPS \u548c\u7f51\u7edc\u4f4d\u7f6e\u670d\u52a1\u3002

          "},{"location":"qsl4a/connectivity/location/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/location/#startlocating","title":"startLocating()","text":"

          \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\u3002

          startLocating(minUpdateTime=60000, minUpdateDistance=30, updateGnssStatus=False)\n

          \u53c2\u6570\uff1a - minUpdateTime (int): \u66f4\u65b0\u4e4b\u95f4\u7684\u6700\u5c0f\u65f6\u95f4\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a60000\uff09 - minUpdateDistance (float): \u66f4\u65b0\u7684\u6700\u5c0f\u8ddd\u79bb\uff08\u7c73\uff09\uff08\u9ed8\u8ba4\uff1a30\uff09 - updateGnssStatus (bool): \u542f\u7528 GNSS \u72b6\u6001\u66f4\u65b0\uff08\u9ed8\u8ba4\uff1aFalse\uff09

          "},{"location":"qsl4a/connectivity/location/#stoplocating","title":"stopLocating()","text":"

          \u505c\u6b62\u4f4d\u7f6e\u66f4\u65b0\u3002

          stopLocating()\n
          "},{"location":"qsl4a/connectivity/location/#readlocation","title":"readLocation()","text":"

          \u83b7\u53d6\u6700\u540e\u5df2\u77e5\u4f4d\u7f6e\u3002

          readLocation()\n

          \u8fd4\u56de\uff1a \u4f4d\u7f6e\u6570\u636e\u5b57\u5178

          "},{"location":"qsl4a/connectivity/location/#getlastknownlocation","title":"getLastKnownLocation()","text":"

          \u83b7\u53d6\u7f13\u5b58\u7684\u4f4d\u7f6e\u3002

          getLastKnownLocation()\n

          \u8fd4\u56de\uff1a \u6765\u81ea\u6240\u6709\u63d0\u4f9b\u5546\u7684\u4f4d\u7f6e

          "},{"location":"qsl4a/connectivity/location/#geocode","title":"geocode()","text":"

          \u5c06\u5730\u5740\u8f6c\u6362\u4e3a\u5750\u6807\u3002

          geocode(address, maxResults=1)\n
          "},{"location":"qsl4a/connectivity/location/#_2","title":"\u4f4d\u7f6e\u63d0\u4f9b\u5546\u65b9\u6cd5)","text":""},{"location":"qsl4a/connectivity/location/#locationproviders","title":"locationProviders()","text":"

          \u83b7\u53d6\u624b\u673a\u4e0a\u53ef\u7528\u7684\u4f4d\u7f6e\u63d0\u4f9b\u5546\u3002

          locationProviders()\n

          \u8fd4\u56de\uff1a \u53ef\u7528\u63d0\u4f9b\u5546\u540d\u79f0\u5217\u8868\uff08\u4f8b\u5982 ['gps', 'network']\uff09

          "},{"location":"qsl4a/connectivity/location/#locationproviderenabled","title":"locationProviderEnabled()","text":"

          \u68c0\u67e5\u7279\u5b9a\u4f4d\u7f6e\u63d0\u4f9b\u5546\u662f\u5426\u5df2\u542f\u7528\u3002

          locationProviderEnabled(provider)\n

          \u53c2\u6570\uff1a - provider (str): \u63d0\u4f9b\u5546\u540d\u79f0\uff08\u4f8b\u5982 'gps', 'network'\uff09

          \u8fd4\u56de\uff1a \u5982\u679c\u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

          "},{"location":"qsl4a/connectivity/location/#readgnssstatus","title":"readGnssStatus()","text":"

          \u8bfb\u53d6\u5168\u7403\u5bfc\u822a\u536b\u661f\u7cfb\u7edf\u72b6\u6001\uff08\u9700\u8981 Android 8+\uff09\u3002

          readGnssStatus()\n

          \u8fd4\u56de\uff1a \u5305\u542b GNSS \u536b\u661f\u4fe1\u606f\u7684 JSONArray

          "},{"location":"qsl4a/connectivity/location/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\ndroid.startLocating(minUpdateTime=5000, minUpdateDistance=1, updateGnssStatus=False)\n\n# \u7b49\u5f85\u5b9a\u4f4d\ntime.sleep(10)\n\n# \u83b7\u53d6\u4f4d\u7f6e\nloc = droid.readLocation().result\nif loc:\n    lat = loc['latitude']\n    lon = loc['longitude']\n    print(f\"Location: {lat}, {lon}\")\n\ndroid.stopLocating()\n
          "},{"location":"qsl4a/connectivity/phone/","title":"\u7535\u8bdd API","text":"

          \u63a7\u5236\u7535\u8bdd\u901a\u8bdd\u548c\u83b7\u53d6\u7535\u8bdd\u4fe1\u606f\u3002

          "},{"location":"qsl4a/connectivity/phone/#_1","title":"\u7535\u8bdd\u72b6\u6001\u8ddf\u8e2a","text":""},{"location":"qsl4a/connectivity/phone/#starttrackingphonestate","title":"startTrackingPhoneState()","text":"

          \u5f00\u59cb\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u53d8\u5316\u3002\u751f\u6210 'phone' \u4e8b\u4ef6\u3002

          startTrackingPhoneState()\n
          "},{"location":"qsl4a/connectivity/phone/#readphonestate","title":"readPhoneState()","text":"

          \u8bfb\u53d6\u5f53\u524d\u7535\u8bdd\u72b6\u6001\u3002

          readPhoneState()\n

          \u8fd4\u56de\uff1a \u5305\u542b\u7535\u8bdd\u72b6\u6001\u548c\u6765\u7535\u53f7\u7801\u7684 Bundle

          "},{"location":"qsl4a/connectivity/phone/#stoptrackingphonestate","title":"stopTrackingPhoneState()","text":"

          \u505c\u6b62\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u3002

          stopTrackingPhoneState()\n
          "},{"location":"qsl4a/connectivity/phone/#_2","title":"\u62e8\u6253\u7535\u8bdd","text":""},{"location":"qsl4a/connectivity/phone/#phonecall","title":"phoneCall()","text":"

          \u901a\u8fc7 URI \u547c\u53eb\u8054\u7cfb\u4eba/\u7535\u8bdd\u53f7\u7801\u3002

          phoneCall(uri)\n

          \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

          "},{"location":"qsl4a/connectivity/phone/#phonecallnumber","title":"phoneCallNumber()","text":"

          \u76f4\u63a5\u62e8\u6253\u7535\u8bdd\u53f7\u7801\u3002

          phoneCallNumber(phone_number)\n

          \u53c2\u6570\uff1a - phone_number (str): \u8981\u62e8\u6253\u7684\u7535\u8bdd\u53f7\u7801

          "},{"location":"qsl4a/connectivity/phone/#phonedial","title":"phoneDial()","text":"

          \u62e8\u6253\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

          phoneDial(uri)\n

          \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

          "},{"location":"qsl4a/connectivity/phone/#phonedialnumber","title":"phoneDialNumber()","text":"

          \u62e8\u6253\u7535\u8bdd\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

          phoneDialNumber(phone_number)\n

          \u53c2\u6570\uff1a - phone_number (str): \u7535\u8bdd\u53f7\u7801

          "},{"location":"qsl4a/connectivity/phone/#_3","title":"\u57fa\u7ad9\u4f4d\u7f6e","text":""},{"location":"qsl4a/connectivity/phone/#getcelllocation","title":"getCellLocation()","text":"

          \u83b7\u53d6\u5f53\u524d\u57fa\u7ad9\u4f4d\u7f6e\u3002

          getCellLocation()\n

          \u8fd4\u56de\uff1a \u5305\u542b\u57fa\u7ad9\u4f4d\u7f6e\u6570\u636e\u7684 JSONObject

          "},{"location":"qsl4a/connectivity/phone/#getallcellslocation","title":"getAllCellsLocation()","text":"

          \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u4f4d\u7f6e\uff08\u9002\u7528\u4e8e\u53cc\u5361\u8bbe\u5907\uff09\u3002

          getAllCellsLocation()\n

          \u8fd4\u56de\uff1a \u57fa\u7ad9\u4f4d\u7f6e\u7684 JSONArray

          "},{"location":"qsl4a/connectivity/phone/#_4","title":"\u7f51\u7edc\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getnetworkoperator","title":"getNetworkOperator()","text":"

          \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

          getNetworkOperator()\n

          \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

          "},{"location":"qsl4a/connectivity/phone/#getnetworkoperatorname","title":"getNetworkOperatorName()","text":"

          \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684\u540d\u79f0\u3002

          getNetworkOperatorName()\n

          \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

          "},{"location":"qsl4a/connectivity/phone/#getnetworktype","title":"getNetworkType()","text":"

          \u83b7\u53d6\u5f53\u524d\u7f51\u7edc\u7c7b\u578b\u3002

          getNetworkType()\n

          \u8fd4\u56de\uff1a \u63cf\u8ff0\u65e0\u7ebf\u7535\u6280\u672f\u7684\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'LTE', 'UMTS', 'GSM'\uff09

          "},{"location":"qsl4a/connectivity/phone/#getphonetype","title":"getPhoneType()","text":"

          \u83b7\u53d6\u7535\u8bdd\u7c7b\u578b\u3002

          getPhoneType()\n

          \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'GSM', 'CDMA', 'SIP'\uff09

          "},{"location":"qsl4a/connectivity/phone/#sim","title":"SIM \u5361\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getsimcountryiso","title":"getSimCountryIso()","text":"

          \u83b7\u53d6 SIM \u5361\u7684 ISO \u56fd\u5bb6\u4ee3\u7801\u3002

          getSimCountryIso()\n

          \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'us'\uff09

          "},{"location":"qsl4a/connectivity/phone/#getsimoperator","title":"getSimOperator()","text":"

          \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

          getSimOperator()\n

          \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

          "},{"location":"qsl4a/connectivity/phone/#getsimoperatorname","title":"getSimOperatorName()","text":"

          \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u540d\u79f0\u3002

          getSimOperatorName()\n

          \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

          "},{"location":"qsl4a/connectivity/phone/#getsimserialnumber","title":"getSimSerialNumber()","text":"

          \u83b7\u53d6 SIM \u5e8f\u5217\u53f7\u3002

          getSimSerialNumber()\n

          \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32 SIM \u5e8f\u5217\u53f7

          "},{"location":"qsl4a/connectivity/phone/#getsimstate","title":"getSimState()","text":"

          \u83b7\u53d6 SIM \u5361\u72b6\u6001\u3002

          getSimState()\n

          \u8fd4\u56de\uff1a \u63cf\u8ff0 SIM \u72b6\u6001\u7684\u5b57\u7b26\u4e32

          "},{"location":"qsl4a/connectivity/phone/#getsubscriberid","title":"getSubscriberId()","text":"

          \u83b7\u53d6\u8ba2\u9605\u8005 ID\u3002

          getSubscriberId()\n

          \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8ba2\u9605\u8005 ID

          "},{"location":"qsl4a/connectivity/phone/#_5","title":"\u8bed\u97f3\u90ae\u4ef6","text":""},{"location":"qsl4a/connectivity/phone/#getvoicemailalphatag","title":"getVoiceMailAlphaTag()","text":"

          \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u5b57\u6bcd\u6807\u7b7e\u3002

          getVoiceMailAlphaTag()\n

          \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u6807\u7b7e

          "},{"location":"qsl4a/connectivity/phone/#getvoicemailnumber","title":"getVoiceMailNumber()","text":"

          \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801\u3002

          getVoiceMailNumber()\n

          \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801

          "},{"location":"qsl4a/connectivity/phone/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getdeviceid","title":"getDeviceId()","text":"

          \u83b7\u53d6\u8bbe\u5907 ID\uff08GSM \u7684 IMEI\uff09\u3002\u5df2\u5e9f\u5f03\u3002

          getDeviceId()\n

          \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

          "},{"location":"qsl4a/connectivity/phone/#getdevicesoftwareversion","title":"getDeviceSoftwareVersion()","text":"

          \u83b7\u53d6\u8bbe\u5907\u8f6f\u4ef6\u7248\u672c\u3002

          getDeviceSoftwareVersion()\n

          \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8f6f\u4ef6\u7248\u672c

          "},{"location":"qsl4a/connectivity/phone/#getline1number","title":"getLine1Number()","text":"

          \u83b7\u53d6\u7ebf\u8def 1 \u7535\u8bdd\u53f7\u7801\u3002

          getLine1Number()\n

          \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u7535\u8bdd\u53f7\u7801

          "},{"location":"qsl4a/connectivity/phone/#checknetworkroaming","title":"checkNetworkRoaming()","text":"

          \u68c0\u67e5\u662f\u5426\u8fde\u63a5\u5230\u6f2b\u6e38\u7f51\u7edc\u3002

          checkNetworkRoaming()\n

          \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u6f2b\u6e38\u5219\u4e3a True

          "},{"location":"qsl4a/connectivity/phone/#_7","title":"\u57fa\u7ad9\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getallcellinfo","title":"getAllCellInfo()","text":"

          \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u7684\u4fe1\u606f\u3002

          getAllCellInfo()\n

          \u8fd4\u56de\uff1a \u57fa\u7ad9\u4fe1\u606f\u5217\u8868

          "},{"location":"qsl4a/connectivity/phone/#setdataenabled","title":"setDataEnabled()","text":"

          \u542f\u7528\u6216\u7981\u7528\u79fb\u52a8\u6570\u636e\u3002

          setDataEnabled(enabled)\n

          \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528

          "},{"location":"qsl4a/connectivity/phone/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7f51\u7edc\u4fe1\u606f\noperator = droid.getNetworkOperatorName().result\nprint(f\"Operator: {operator}\")\n\nnetwork_type = droid.getNetworkType().result\nprint(f\"Network: {network_type}\")\n\n# \u83b7\u53d6 SIM \u4fe1\u606f\nsim_state = droid.getSimState().result\nprint(f\"SIM: {sim_state}\")\n\n# \u83b7\u53d6\u7535\u8bdd\u53f7\u7801\nline1 = droid.getLine1Number().result\nprint(f\"Phone: {line1}\")\n\n# \u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\ndroid.startTrackingPhoneState()\nprint(\"Tracking phone state...\")\ndroid.stopTrackingPhoneState()\n
          "},{"location":"qsl4a/connectivity/signalstrength/","title":"\u4fe1\u53f7\u5f3a\u5ea6 API","text":"

          \u76d1\u63a7\u8702\u7a9d\u548c\u65e0\u7ebf\u4fe1\u53f7\u5f3a\u5ea6\u3002

          "},{"location":"qsl4a/connectivity/signalstrength/#_1","title":"\u4fe1\u53f7\u5f3a\u5ea6\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/signalstrength/#starttrackingsignalstrengths","title":"startTrackingSignalStrengths()","text":"

          \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316\u3002\u751f\u6210 'signal_strengths' \u4e8b\u4ef6\u3002

          startTrackingSignalStrengths()\n
          "},{"location":"qsl4a/connectivity/signalstrength/#stoptrackingsignalstrengths","title":"stopTrackingSignalStrengths()","text":"

          \u505c\u6b62\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u3002

          stopTrackingSignalStrengths()\n
          "},{"location":"qsl4a/connectivity/signalstrength/#readsignalstrengths","title":"readSignalStrengths()","text":"

          \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\u3002

          readSignalStrengths()\n

          \u8fd4\u56de\uff1a \u5305\u542b\u4fe1\u53f7\u5f3a\u5ea6\u6570\u636e\u7684 Bundle

          "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthlevel","title":"getTelephoneSignalStrengthLevel()","text":"

          \u83b7\u53d6\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u7b49\u7ea7\uff080-4\uff09\u3002

          getTelephoneSignalStrengthLevel()\n

          \u8fd4\u56de\uff1a \u6574\u6570\u7b49\u7ea7\uff080=\u65e0\uff0c1=\u5dee\uff0c2=\u4e00\u822c\uff0c3=\u597d\uff0c4=\u4f18\u79c0\uff09

          "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthdetail","title":"getTelephoneSignalStrengthDetail()","text":"

          \u83b7\u53d6\u8be6\u7ec6\u7684\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u4fe1\u606f\u3002

          getTelephoneSignalStrengthDetail()\n

          \u8fd4\u56de\uff1a \u5305\u542b\u8be6\u7ec6\u4fe1\u53f7\u4fe1\u606f\u7684\u5b57\u7b26\u4e32

          "},{"location":"qsl4a/connectivity/signalstrength/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\ndroid.startTrackingSignalStrengths()\n\n# \u7b49\u5f85\u4fe1\u53f7\u66f4\u65b0\ntime.sleep(5)\n\n# \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\nsignal = droid.readSignalStrengths().result\nprint(f\"Signal: {signal}\")\n\n# \u76f4\u63a5\u83b7\u53d6\u7b49\u7ea7\nlevel = droid.getTelephoneSignalStrengthLevel().result\nprint(f\"Signal level: {level}/4\")\n\ndroid.stopTrackingSignalStrengths()\n
          "},{"location":"qsl4a/connectivity/sms/","title":"SMS API","text":"

          \u53d1\u9001\u548c\u63a5\u6536 SMS \u6d88\u606f\u3002

          "},{"location":"qsl4a/connectivity/sms/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/sms/#smssend","title":"smsSend()","text":"

          \u53d1\u9001 SMS \u6d88\u606f\u3002

          smsSend(destinationAddress, text)\n

          \u53c2\u6570\uff1a - destinationAddress (str): \u7535\u8bdd\u53f7\u7801 - text (str): \u6d88\u606f\u6587\u672c

          "},{"location":"qsl4a/connectivity/sms/#smsgetmessagecount","title":"smsGetMessageCount()","text":"

          \u83b7\u53d6\u6d88\u606f\u6570\u91cf\u3002

          smsGetMessageCount(unreadOnly=False, folder=\"inbox\")\n
          "},{"location":"qsl4a/connectivity/sms/#smsgetmessageids","title":"smsGetMessageIds()","text":"

          \u83b7\u53d6\u6d88\u606f ID\u3002

          smsGetMessageIds(unreadOnly=False, folder=\"inbox\")\n
          "},{"location":"qsl4a/connectivity/sms/#smsgetmessages","title":"smsGetMessages()","text":"

          \u83b7\u53d6\u6d88\u606f\u8be6\u60c5\u3002

          smsGetMessages(unreadOnly=False, folder=\"inbox\", attributes=None)\n
          "},{"location":"qsl4a/connectivity/sms/#smsgetmessagebyid","title":"smsGetMessageById()","text":"

          \u901a\u8fc7 ID \u83b7\u53d6\u7279\u5b9a\u6d88\u606f\u3002

          smsGetMessageById(id, attributes=None)\n

          \u53c2\u6570\uff1a - id (int): \u6d88\u606f ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

          \u8fd4\u56de\uff1a \u6d88\u606f\u6570\u636e\u5b57\u5178

          "},{"location":"qsl4a/connectivity/sms/#smsgetattributes","title":"smsGetAttributes()","text":"

          \u83b7\u53d6\u53ef\u7528\u7684 SMS \u6d88\u606f\u5c5e\u6027\u3002

          smsGetAttributes()\n

          \u8fd4\u56de\uff1a \u53ef\u7528\u5c5e\u6027\u540d\u79f0\u5217\u8868

          "},{"location":"qsl4a/connectivity/sms/#smsdeletemessage","title":"smsDeleteMessage()","text":"

          \u5220\u9664\u6d88\u606f\u3002

          smsDeleteMessage(id)\n
          "},{"location":"qsl4a/connectivity/sms/#smsmarkmessageread","title":"smsMarkMessageRead()","text":"

          \u5c06\u6d88\u606f\u6807\u8bb0\u4e3a\u5df2\u8bfb\u3002

          smsMarkMessageRead(ids, read=True)\n
          "},{"location":"qsl4a/connectivity/sms/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u53d1\u9001 SMS\ndroid.smsSend(\"+1234567890\", \"Hello from QPython!\")\n\n# \u83b7\u53d6\u672a\u8bfb\u6d88\u606f\nmessages = droid.smsGetMessages(unreadOnly=True).result\nfor msg in messages:\n    print(f\"From: {msg['address']}, Text: {msg['body']}\")\n
          "},{"location":"qsl4a/connectivity/wifi/","title":"WiFi API","text":"

          \u63a7\u5236 WiFi \u9002\u914d\u5668\u5e76\u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\u3002

          "},{"location":"qsl4a/connectivity/wifi/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/connectivity/wifi/#checkwifistate","title":"checkWifiState()","text":"

          \u68c0\u67e5 WiFi \u662f\u5426\u5df2\u542f\u7528\u3002

          checkWifiState()\n

          \u8fd4\u56de\uff1a \u5982\u679c WiFi \u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

          "},{"location":"qsl4a/connectivity/wifi/#togglewifistate","title":"toggleWifiState()","text":"

          \u6253\u5f00\u6216\u5173\u95ed WiFi\u3002

          toggleWifiState(enabled=None)\n

          \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

          \u8fd4\u56de\uff1a \u5982\u679c\u64cd\u4f5c\u6210\u529f\u5219\u4e3a True

          "},{"location":"qsl4a/connectivity/wifi/#wifistartscan","title":"wifiStartScan()","text":"

          \u5f00\u59cb\u626b\u63cf\u53ef\u7528\u7684 WiFi \u7f51\u7edc\u3002

          wifiStartScan()\n
          "},{"location":"qsl4a/connectivity/wifi/#wifigetscanresults","title":"wifiGetScanResults()","text":"

          \u83b7\u53d6\u53d1\u73b0\u7684 WiFi \u7f51\u7edc\u5217\u8868\u3002

          wifiGetScanResults()\n

          \u8fd4\u56de\uff1a \u63a5\u5165\u70b9\u4fe1\u606f\u5217\u8868

          "},{"location":"qsl4a/connectivity/wifi/#_2","title":"\u8fde\u63a5\u7ba1\u7406","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetconnectioninfo","title":"wifiGetConnectionInfo()","text":"

          \u83b7\u53d6\u8be6\u7ec6\u8fde\u63a5\u4fe1\u606f\u3002

          wifiGetConnectionInfo()\n

          \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001IP \u5730\u5740\u7b49\u8fde\u63a5\u8be6\u60c5\u7684\u5b57\u5178

          "},{"location":"qsl4a/connectivity/wifi/#getconnectedinfo","title":"getConnectedInfo()","text":"

          \u83b7\u53d6\u8fde\u63a5\u7684 WiFi \u7f51\u7edc\u4fe1\u606f\uff08\u7b80\u5316\u7248\uff09\u3002

          getConnectedInfo()\n

          \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001\u4fe1\u53f7\u5f3a\u5ea6\u7684\u5b57\u5178

          "},{"location":"qsl4a/connectivity/wifi/#getdhcpinfo","title":"getDhcpInfo()","text":"

          \u83b7\u53d6\u5f53\u524d\u8fde\u63a5\u7684 DHCP \u4fe1\u606f\u3002

          getDhcpInfo(ipConvertToString=True)\n

          \u53c2\u6570\uff1a - ipConvertToString (bool): \u5c06 IP \u5730\u5740\u8f6c\u6362\u4e3a\u5b57\u7b26\u4e32\u683c\u5f0f\uff08\u9ed8\u8ba4\uff1aTrue\uff09

          \u8fd4\u56de\uff1a \u5305\u542b IP\u3001\u7f51\u5173\u3001DNS \u7b49 DHCP \u4fe1\u606f\u7684\u5b57\u5178

          "},{"location":"qsl4a/connectivity/wifi/#wifidisconnect","title":"wifiDisconnect()","text":"

          \u65ad\u5f00\u5f53\u524d WiFi \u7f51\u7edc\u8fde\u63a5\u3002

          wifiDisconnect()\n
          "},{"location":"qsl4a/connectivity/wifi/#wifireconnect","title":"wifiReconnect()","text":"

          \u91cd\u65b0\u8fde\u63a5\u5230\u5f53\u524d\u7f51\u7edc\u3002

          wifiReconnect()\n
          "},{"location":"qsl4a/connectivity/wifi/#wifireassociate","title":"wifiReassociate()","text":"

          \u91cd\u65b0\u5173\u8054\u5f53\u524d\u63a5\u5165\u70b9\u3002

          wifiReassociate()\n
          "},{"location":"qsl4a/connectivity/wifi/#_3","title":"\u70ed\u70b9","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetapstate","title":"wifiGetApState()","text":"

          \u83b7\u53d6 WiFi AP\uff08\u70ed\u70b9\uff09\u72b6\u6001\u3002

          wifiGetApState()\n

          \u8fd4\u56de\uff1a \u70ed\u70b9\u72b6\u6001

          "},{"location":"qsl4a/connectivity/wifi/#wifi","title":"WiFi \u9501","text":""},{"location":"qsl4a/connectivity/wifi/#wifilockacquirefull","title":"wifiLockAcquireFull()","text":"

          \u83b7\u53d6\u5b8c\u6574 WiFi \u9501\uff08\u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\u4e5f\u4fdd\u6301 WiFi \u6d3b\u52a8\uff09\u3002

          wifiLockAcquireFull()\n
          "},{"location":"qsl4a/connectivity/wifi/#wifilockacquirescanonly","title":"wifiLockAcquireScanOnly()","text":"

          \u83b7\u53d6\u4ec5\u626b\u63cf WiFi \u9501\u3002

          wifiLockAcquireScanOnly()\n
          "},{"location":"qsl4a/connectivity/wifi/#wifilockrelease","title":"wifiLockRelease()","text":"

          \u91ca\u653e WiFi \u9501\u3002

          wifiLockRelease()\n
          "},{"location":"qsl4a/connectivity/wifi/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u68c0\u67e5 WiFi \u72b6\u6001\nif droid.checkWifiState().result:\n    print(\"WiFi is enabled\")\nelse:\n    print(\"Enabling WiFi...\")\n    droid.toggleWifiState(True)\n    time.sleep(2)\n\n# \u5f00\u59cb\u626b\u63cf\ndroid.wifiStartScan()\ntime.sleep(3)\n\n# \u83b7\u53d6\u626b\u63cf\u7ed3\u679c\nnetworks = droid.wifiGetScanResults().result\nfor network in networks:\n    print(f\"SSID: {network.get('SSID')}, Signal: {network.get('level')} dBm\")\n\n# \u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\ninfo = droid.wifiGetConnectionInfo().result\nif info:\n    print(f\"Connected to: {info.get('ssid')}\")\n    print(f\"BSSID: {info.get('bssid')}\")\n    print(f\"IP: {info.get('ip_address')}\")\n\n# \u83b7\u53d6 DHCP \u4fe1\u606f\ndhcp = droid.getDhcpInfo().result\nif dhcp:\n    print(f\"Gateway: {dhcp.get('gateway')}\")\n    print(f\"DNS: {dhcp.get('dns1')}\")\n\n# \u83b7\u53d6\u7b80\u5316\u7684\u8fde\u63a5\u4fe1\u606f\nconnected = droid.getConnectedInfo().result\nprint(f\"SSID: {connected.get('ssid')}, Signal: {connected.get('level')} dBm\")\n\n# \u65ad\u5f00\u5e76\u91cd\u65b0\u8fde\u63a5\ndroid.wifiDisconnect()\ntime.sleep(1)\ndroid.wifiReconnect()\n\n# \u91cd\u65b0\u5173\u8054\u63a5\u5165\u70b9\ndroid.wifiReassociate()\n\n# \u68c0\u67e5\u70ed\u70b9\u72b6\u6001\nap_state = droid.wifiGetApState().result\nprint(f\"Hotspot state: {ap_state}\")\n\n# \u83b7\u53d6 WiFi \u9501\u4ee5\u8fdb\u884c\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireFull()\n# ... \u6267\u884c\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n\n# \u6216\u4f7f\u7528\u4ec5\u626b\u63cf\u9501\u4ee5\u8fdb\u884c\u8f83\u8f7b\u7684\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireScanOnly()\n# ... \u6267\u884c\u626b\u63cf\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n
          "},{"location":"qsl4a/core/android-base/","title":"Android \u57fa\u7840\u7c7b","text":"

          Android \u7c7b\u662f QSL4A \u7684\u6838\u5fc3\uff0c\u63d0\u4f9b\u4e86\u4e0e Android \u8fd0\u884c\u65f6\u7684\u8fde\u63a5\u548c RPC \u673a\u5236\u3002

          "},{"location":"qsl4a/core/android-base/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
          # \u529f\u80fd\u5b8c\u6574\u7248\u672c\uff08\u63a8\u8350\uff09\nimport androidhelper\ndroid = androidhelper.Android()\n\n# \u7b80\u5316\u7248\u672c\uff08\u5feb\u901f\uff0c\u5355\u5b9e\u4f8b\uff09\nimport android\ndroid = android.droid\n
          "},{"location":"qsl4a/core/android-base/#android_1","title":"\u7c7b\uff1aAndroid","text":""},{"location":"qsl4a/core/android-base/#_2","title":"\u6784\u9020\u51fd\u6570","text":"
          Android(addr=None)\n

          \u53c2\u6570\uff1a - addr (tuple, optional): (HOST, PORT) \u5730\u5740\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u73af\u5883\u53d8\u91cf AP_HOST \u548c AP_PORT

          \u73af\u5883\u53d8\u91cf\uff1a - AP_HOST - \u670d\u52a1\u5668\u4e3b\u673a\u5730\u5740 - AP_PORT - \u670d\u52a1\u5668\u7aef\u53e3 - AP_HANDSHAKE - \u8ba4\u8bc1\u4ee4\u724c

          "},{"location":"qsl4a/core/android-base/#_3","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/android-base/#_rpc","title":"_rpc()","text":"

          \u8c03\u7528 Android \u51fd\u6570\u7684\u5185\u90e8 RPC \u65b9\u6cd5\u3002

          _rpc(method, *args)\n

          \u53c2\u6570\uff1a - method (str): \u8981\u8c03\u7528\u7684\u65b9\u6cd5\u540d - *args: \u65b9\u6cd5\u7684\u53ef\u53d8\u53c2\u6570

          \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4\uff0c\u5305\u542b\u4ee5\u4e0b\u5b57\u6bb5\uff1a - id (int): \u8bf7\u6c42 ID - result: \u65b9\u6cd5\u8fd4\u56de\u503c - error (str or None): \u9519\u8bef\u4fe1\u606f\uff08\u5982\u679c\u5931\u8d25\uff09

          "},{"location":"qsl4a/core/android-base/#getattr","title":"getattr()","text":"

          \u52a8\u6001\u65b9\u6cd5\u5206\u53d1\u5668\u3002\u6240\u6709 Android \u65b9\u6cd5\u90fd\u901a\u8fc7\u5c5e\u6027\u67e5\u627e\u8bbf\u95ee\u3002

          # \u4ee5\u4e0b\u4e24\u79cd\u65b9\u5f0f\u7b49\u4ef7\uff1a\ndroid.makeToast(\"Hello\")\ndroid._rpc(\"makeToast\", \"Hello\")\n
          "},{"location":"qsl4a/core/android-base/#androidpy","title":"\u72ec\u7acb\u51fd\u6570\uff08android.py\uff09","text":"

          \u4f7f\u7528\u7b80\u5316\u7684 android \u6a21\u5757\u65f6\uff1a

          "},{"location":"qsl4a/core/android-base/#jsla","title":"jsla()","text":"

          \u53d1\u9001 JSON-RPC \u8bf7\u6c42\u5e76\u8fd4\u56de\u539f\u59cb\u54cd\u5e94\u3002

          jsla(method, *params)\n

          \u8fd4\u56de\uff1a JSON \u5b57\u7b26\u4e32\u54cd\u5e94

          "},{"location":"qsl4a/core/android-base/#rsla","title":"rsla()","text":"

          \u53d1\u9001\u8bf7\u6c42\u5e76\u4ec5\u8fd4\u56de\u7ed3\u679c\u3002

          rsla(method, *params)\n

          \u8fd4\u56de\uff1a RPC \u8c03\u7528\u7684\u7ed3\u679c\u503c

          "},{"location":"qsl4a/core/android-base/#esla","title":"esla()","text":"

          \u53d1\u9001\u8bf7\u6c42\uff0c\u9519\u8bef\u65f6\u629b\u51fa\u5f02\u5e38\u3002

          esla(method, *params)\n

          \u629b\u51fa\uff1a \u5982\u679c error \u5b57\u6bb5\u4e0d\u4e3a None \u5219\u629b\u51fa\u5f02\u5e38

          "},{"location":"qsl4a/core/android-base/#nsla","title":"nsla()","text":"

          \u53d1\u9001\u8bf7\u6c42\u5e76\u8fd4\u56de Result \u547d\u540d\u5143\u7ec4\u3002

          nsla(method, *params)\n

          \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4

          "},{"location":"qsl4a/core/android-base/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/android-base/#_5","title":"\u57fa\u672c\u8fde\u63a5","text":"
          import androidhelper\n\n# \u8fde\u63a5\u5230 Android \u8fd0\u884c\u65f6\ndroid = androidhelper.Android()\n\n# \u901a\u8fc7\u663e\u793a toast \u6765\u68c0\u67e5\u8fde\u63a5\ndroid.makeToast(\"Connected!\")\n
          "},{"location":"qsl4a/core/android-base/#_6","title":"\u9519\u8bef\u5904\u7406","text":"
          result = droid.someMethod()\nif result.error:\n    print(f\"Error: {result.error}\")\nelse:\n    print(f\"Success: {result.result}\")\n
          "},{"location":"qsl4a/core/android-base/#rpc","title":"\u76f4\u63a5 RPC \u8c03\u7528","text":"
          # \u76f4\u63a5\u8c03\u7528\u4efb\u610f\u65b9\u6cd5\nresult = droid._rpc(\"makeToast\", \"Hello World\")\n
          "},{"location":"qsl4a/core/events/","title":"\u4e8b\u4ef6\u7cfb\u7edf","text":"

          QSL4A \u63d0\u4f9b\u4e86\u4e00\u4e2a\u4e8b\u4ef6\u7cfb\u7edf\uff0c\u7528\u4e8e\u5904\u7406\u6765\u81ea Android \u7684\u5f02\u6b65\u4e8b\u4ef6\uff0c\u5982\u4f20\u611f\u5668\u66f4\u65b0\u3001\u4f4d\u7f6e\u53d8\u5316\u548c\u81ea\u5b9a\u4e49\u5e7f\u64ad\u3002

          "},{"location":"qsl4a/core/events/#_2","title":"\u4e8b\u4ef6\u57fa\u7840","text":"

          \u4e8b\u4ef6\u5b58\u50a8\u5728\u7f13\u51b2\u533a\u4e2d\uff0c\u53ef\u4ee5\u8f6e\u8be2\u6216\u7b49\u5f85\u3002\u6bcf\u4e2a\u4e8b\u4ef6\u5305\u542b\uff1a - name: \u4e8b\u4ef6\u7c7b\u578b/\u540d\u79f0 - data: \u4e8b\u4ef6\u8d1f\u8f7d\u6570\u636e - time: \u65f6\u95f4\u6233

          "},{"location":"qsl4a/core/events/#_3","title":"\u4e8b\u4ef6\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#eventclearbuffer","title":"eventClearBuffer()","text":"

          \u6e05\u9664\u7f13\u51b2\u533a\u4e2d\u7684\u6240\u6709\u5f85\u5904\u7406\u4e8b\u4ef6\u3002

          eventClearBuffer()\n

          \u8fd4\u56de\uff1a None

          "},{"location":"qsl4a/core/events/#eventpoll","title":"eventPoll()","text":"

          \u8f6e\u8be2\u7f13\u51b2\u533a\u4e2d\u7684\u4e8b\u4ef6\u3002

          eventPoll(number_of_events=1)\n

          \u53c2\u6570\uff1a - number_of_events (int): \u8981\u68c0\u7d22\u7684\u6700\u5927\u4e8b\u4ef6\u6570\uff08\u9ed8\u8ba4\uff1a1\uff09

          \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\u5217\u8868

          "},{"location":"qsl4a/core/events/#eventwait","title":"eventWait()","text":"

          \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\u3002

          eventWait(timeout=None)\n

          \u53c2\u6570\uff1a - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09\u3002None = \u6c38\u4e45\u7b49\u5f85

          \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

          "},{"location":"qsl4a/core/events/#eventwaitfor","title":"eventWaitFor()","text":"

          \u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6\u3002

          eventWaitFor(eventName, timeout=None)\n

          \u53c2\u6570\uff1a - eventName (str): \u8981\u7b49\u5f85\u7684\u4e8b\u4ef6\u540d\u79f0 - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

          \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

          "},{"location":"qsl4a/core/events/#eventpost","title":"eventPost()","text":"

          \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\u3002

          eventPost(name, data, enqueue=None)\n

          \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e\uff08\u4efb\u610f\u7c7b\u578b\uff09 - enqueue (bool, optional): \u5982\u679c\u4e3a True \u5219\u6dfb\u52a0\u5230\u961f\u5217

          "},{"location":"qsl4a/core/events/#receiveevent","title":"receiveEvent()","text":"

          \u63a5\u6536\u4e8b\u4ef6\uff08\u963b\u585e\uff09\u3002

          receiveEvent()\n

          \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61

          "},{"location":"qsl4a/core/events/#_4","title":"\u5e7f\u64ad\u4e8b\u4ef6","text":"

          \u6ce8\u518c\u7cfb\u7edf\u5e7f\u64ad\u4e8b\u4ef6\u3002

          "},{"location":"qsl4a/core/events/#eventregisterforbroadcast","title":"eventRegisterForBroadcast()","text":"

          \u6ce8\u518c\u63a5\u6536\u5e7f\u64ad\u4e8b\u4ef6\u3002

          eventRegisterForBroadcast(category, enqueue=True)\n

          \u53c2\u6570\uff1a - category (str): \u5e7f\u64ad\u7c7b\u522b/\u52a8\u4f5c - enqueue (bool): \u6dfb\u52a0\u5230\u4e8b\u4ef6\u961f\u5217

          "},{"location":"qsl4a/core/events/#eventunregisterforbroadcast","title":"eventUnregisterForBroadcast()","text":"

          \u53d6\u6d88\u6ce8\u518c\u5e7f\u64ad\u4e8b\u4ef6\u3002

          eventUnregisterForBroadcast(category)\n
          "},{"location":"qsl4a/core/events/#eventgetbrodcastcategories","title":"eventGetBrodcastCategories()","text":"

          \u83b7\u53d6\u5df2\u6ce8\u518c\u7684\u5e7f\u64ad\u7c7b\u522b\u3002

          eventGetBrodcastCategories()\n

          \u8fd4\u56de\uff1a \u5df2\u6ce8\u518c\u7c7b\u522b\u5217\u8868

          "},{"location":"qsl4a/core/events/#_5","title":"\u4e8b\u4ef6\u5206\u53d1\u5668)","text":""},{"location":"qsl4a/core/events/#starteventdispatcher","title":"startEventDispatcher()","text":"

          \u6253\u5f00\u4e00\u4e2a\u53ef\u4ee5\u8bfb\u53d6\u5df2\u53d1\u5e03\u4e8b\u4ef6\u7684\u5957\u63a5\u5b57\u3002)

          startEventDispatcher(port=0)\n

          \u53c2\u6570\uff1a - port (int, optional): \u76d1\u542c\u7684\u7aef\u53e3\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\u9009\u62e9\uff09

          \u8fd4\u56de\uff1a \u6b63\u5728\u76d1\u542c\u7684\u7aef\u53e3\u53f7

          "},{"location":"qsl4a/core/events/#stopeventdispatcher","title":"stopEventDispatcher()","text":"

          \u505c\u6b62\u4e8b\u4ef6\u670d\u52a1\u5668\u3002)

          stopEventDispatcher()\n
          "},{"location":"qsl4a/core/events/#_6","title":"\u5df2\u5e9f\u5f03\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#rpcpostevent","title":"rpcPostEvent()","text":"

          \u5c06\u4e8b\u4ef6\u53d1\u5e03\u5230\u4e8b\u4ef6\u961f\u5217\u3002\uff08\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 eventPost\uff09

          rpcPostEvent(name, data)\n

          \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e

          "},{"location":"qsl4a/core/events/#_7","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/events/#_8","title":"\u57fa\u672c\u4e8b\u4ef6\u8f6e\u8be2","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6e05\u9664\u65e7\u4e8b\u4ef6\ndroid.eventClearBuffer()\n\n# \u8f6e\u8be2\u4e8b\u4ef6\nevents = droid.eventPoll(5).result\nfor event in events:\n    print(f\"Event: {event['name']}, Data: {event['data']}\")\n
          "},{"location":"qsl4a/core/events/#_9","title":"\u7b49\u5f85\u4e8b\u4ef6","text":"
          # \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\uff0c\u5e26\u8d85\u65f6\nevent = droid.eventWait(timeout=10).result\nif event:\n    print(f\"Got event: {event['name']}\")\n
          "},{"location":"qsl4a/core/events/#_10","title":"\u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6","text":"
          # \u7b49\u5f85\u4f20\u611f\u5668\u4e8b\u4ef6\nevent = droid.eventWaitFor('screen', timeout=5).result\nif event:\n    print(f\"Screen event: {event['data']}\")\n
          "},{"location":"qsl4a/core/events/#_11","title":"\u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6","text":"
          # \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\ndroid.eventPost('my_event', {'key': 'value'})\n\n# \u7b49\u5f85\u5b83\nevent = droid.eventWaitFor('my_event', timeout=1).result\n
          "},{"location":"qsl4a/core/events/#_12","title":"\u5e7f\u64ad\u63a5\u6536\u5668","text":"
          # \u6ce8\u518c\u5c4f\u5e55\u5f00\u5173\u4e8b\u4ef6\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_ON')\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_OFF')\n\n# \u7b49\u5f85\u5c4f\u5e55\u4e8b\u4ef6\nwhile True:\n    event = droid.receiveEvent().result\n    if event['name'] == 'android.intent.action.SCREEN_ON':\n        print(\"Screen turned on\")\n    elif event['name'] == 'android.intent.action.SCREEN_OFF':\n        print(\"Screen turned off\")\n
          "},{"location":"qsl4a/core/events/#_13","title":"\u4f20\u611f\u5668\u4e8b\u4ef6\u5904\u7406","text":"
          # \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u5904\u7406\u4f20\u611f\u5668\u4e8b\u4ef6\nfor _ in range(100):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'sensors':\n        data = event['data']\n        print(f\"Accel: {data['xforce']}, {data['yforce']}, {data['zforce']}\")\n\ndroid.stopSensing()\n
          "},{"location":"qsl4a/core/events/#_14","title":"\u5e38\u89c1\u4e8b\u4ef6\u7c7b\u578b","text":"\u4e8b\u4ef6\u540d\u79f0 \u63cf\u8ff0 \u6765\u6e90 sensors \u4f20\u611f\u5668\u6570\u636e\u66f4\u65b0 startSensing* location GPS \u4f4d\u7f6e\u66f4\u65b0 startLocating phone \u7535\u8bdd\u72b6\u6001\u53d8\u5316 startTrackingPhoneState signal \u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316 startTrackingSignalStrength screen \u622a\u56fe\u5c31\u7eea fullGetScreenShot dialog \u5bf9\u8bdd\u6846\u54cd\u5e94 dialogShow*"},{"location":"qsl4a/core/events/#_15","title":"\u4e8b\u4ef6\u6570\u636e\u7ed3\u6784","text":"
          {\n    'name': 'event_name',\n    'data': {\n        # \u4e8b\u4ef6\u7279\u5b9a\u6570\u636e\n    },\n    'time': 1234567890  # \u65f6\u95f4\u6233\n}\n
          "},{"location":"qsl4a/core/intent/","title":"Intent \u7cfb\u7edf","text":"

          Android Intent \u7528\u4e8e\u542f\u52a8\u6d3b\u52a8\u3001\u53d1\u9001\u5e7f\u64ad\u548c\u5e94\u7528\u95f4\u901a\u4fe1\u3002QSL4A \u901a\u8fc7 Intent \u6a21\u5757\u63d0\u4f9b\u5b8c\u6574\u7684 Intent \u652f\u6301\u3002

          "},{"location":"qsl4a/core/intent/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
          import androidhelper\ndon = androidhelper.Android()\n
          "},{"location":"qsl4a/core/intent/#intent_1","title":"Intent \u5e38\u91cf","text":"

          \u901a\u8fc7 droid.Intent \u8bbf\u95ee\uff1a

          "},{"location":"qsl4a/core/intent/#_2","title":"\u64cd\u4f5c","text":"\u5e38\u91cf \u503c \u7528\u9014 ACTION_MAIN android.intent.action.MAIN \u5e94\u7528\u5165\u53e3\u70b9 ACTION_VIEW android.intent.action.VIEW \u67e5\u770b\u5185\u5bb9 ACTION_EDIT android.intent.action.EDIT \u7f16\u8f91\u5185\u5bb9 ACTION_PICK android.intent.action.PICK \u9009\u62e9\u9879\u76ee ACTION_SEND android.intent.action.SEND \u5206\u4eab\u5185\u5bb9 ACTION_SEARCH android.intent.action.SEARCH \u641c\u7d22"},{"location":"qsl4a/core/intent/#_3","title":"\u6807\u5fd7","text":"\u5e38\u91cf \u503c \u7528\u9014 FLAG_ACTIVITY_NEW_TASK 268435456 \u542f\u52a8\u65b0\u4efb\u52a1 FLAG_ACTIVITY_CLEAR_TASK 32768 \u6e05\u9664\u4efb\u52a1\u5806\u6808 FLAG_ACTIVITY_NEW_DOCUMENT 524288 \u65b0\u6587\u6863\u6a21\u5f0f"},{"location":"qsl4a/core/intent/#_4","title":"\u9644\u52a0\u6570\u636e","text":"\u5e38\u91cf \u7528\u9014 EXTRA_TEXT \u6587\u672c\u5185\u5bb9 EXTRA_STREAM \u6587\u4ef6 URI EXTRA_SUBJECT \u4e3b\u9898\u884c EXTRA_EMAIL \u7535\u5b50\u90ae\u4ef6\u5730\u5740"},{"location":"qsl4a/core/intent/#_5","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/intent/#makeintent","title":"makeIntent()","text":"

          \u521b\u5efa Intent \u5bf9\u8c61\u3002

          makeIntent(action, uri=None, type=None, extras=None, categories=None,\n           packagename=None, classname=None, flags=None)\n

          \u53c2\u6570\uff1a - action (str): Intent \u64cd\u4f5c\uff08\u4f8b\u5982 droid.Intent.ACTION_VIEW\uff09 - uri (str, optional): \u6570\u636e URI - type (str, optional): MIME \u7c7b\u578b - extras (dict, optional): \u9644\u52a0\u6570\u636e - categories (list, optional): Intent \u7c7b\u522b - packagename (str, optional): \u76ee\u6807\u5305 - classname (str, optional): \u76ee\u6807\u7c7b - flags (int, optional): Intent \u6807\u5fd7

          \u8fd4\u56de\uff1a Intent \u5bf9\u8c61

          "},{"location":"qsl4a/core/intent/#startactivityintent","title":"startActivityIntent()","text":"

          \u4f7f\u7528 Intent \u542f\u52a8 Activity\u3002

          startActivityIntent(intent, wait=None)\n

          \u53c2\u6570\uff1a - intent: makeIntent() \u8fd4\u56de\u7684 Intent \u5bf9\u8c61 - wait (bool, optional): \u963b\u585e\u76f4\u5230\u6d3b\u52a8\u5173\u95ed

          "},{"location":"qsl4a/core/intent/#startactivityforresultintent","title":"startActivityForResultIntent()","text":"

          \u542f\u52a8\u6d3b\u52a8\u5e76\u7b49\u5f85\u7ed3\u679c\u3002

          startActivityForResultIntent(intent)\n

          \u8fd4\u56de\uff1a Activity \u7ed3\u679c

          "},{"location":"qsl4a/core/intent/#sendbroadcastintent","title":"sendBroadcastIntent()","text":"

          \u53d1\u9001\u5e7f\u64ad\u3002

          sendBroadcastIntent(intent)\n
          "},{"location":"qsl4a/core/intent/#view","title":"view()","text":"

          \u901a\u8fc7 URI \u67e5\u770b\u5185\u5bb9\u3002

          view(uri, type=None, extras=None)\n
          "},{"location":"qsl4a/core/intent/#pick","title":"pick()","text":"

          \u4ece URI \u9009\u62e9\u5185\u5bb9\u3002

          pick(uri)\n
          "},{"location":"qsl4a/core/intent/#intent_2","title":"\u5e38\u89c1 Intent \u65b9\u6cd5)","text":""},{"location":"qsl4a/core/intent/#scanbarcode","title":"scanBarcode()","text":"

          \u542f\u52a8\u6761\u7801\u626b\u63cf\u5668\u3002

          scanBarcode()\n

          \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5b57\u7b26\u4e32

          "},{"location":"qsl4a/core/intent/#send","title":"send()","text":"

          \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u5185\u5bb9\u3002

          send(type, content)\n

          \u53c2\u6570\uff1a - type (str): MIME \u7c7b\u578b - content (str): \u8981\u5206\u4eab\u7684\u5185\u5bb9

          "},{"location":"qsl4a/core/intent/#sendtext","title":"sendText()","text":"

          \u53d1\u9001\u6587\u672c\u5185\u5bb9\u3002

          sendText(text)\n

          \u53c2\u6570\uff1a - text (str): \u8981\u53d1\u9001\u7684\u6587\u672c

          "},{"location":"qsl4a/core/intent/#sendemail","title":"sendEmail()","text":"

          \u53d1\u9001\u7535\u5b50\u90ae\u4ef6\u3002

          sendEmail(to, subject, body, attachment=None)\n

          \u53c2\u6570\uff1a - to (str or list): \u6536\u4ef6\u4eba\u7535\u5b50\u90ae\u4ef6\u5730\u5740 - subject (str): \u7535\u5b50\u90ae\u4ef6\u4e3b\u9898 - body (str): \u7535\u5b50\u90ae\u4ef6\u6b63\u6587 - attachment (str, optional): \u9644\u4ef6\u6587\u4ef6\u8def\u5f84

          "},{"location":"qsl4a/core/intent/#pathtouri","title":"pathToUri()","text":"

          \u5c06\u6587\u4ef6\u8def\u5f84\u8f6c\u6362\u4e3a\u5185\u5bb9 URI\u3002

          pathToUri(path)\n

          \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

          \u8fd4\u56de\uff1a \u5185\u5bb9 URI \u5b57\u7b26\u4e32

          "},{"location":"qsl4a/core/intent/#openfile","title":"openFile()","text":"

          \u7528\u9002\u5f53\u7684\u5e94\u7528\u7a0b\u5e8f\u6253\u5f00\u6587\u4ef6\u3002

          openFile(path)\n

          \u53c2\u6570\uff1a - path (str): \u8981\u6253\u5f00\u7684\u6587\u4ef6\u8def\u5f84

          "},{"location":"qsl4a/core/intent/#sendfile","title":"sendFile()","text":"

          \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u6587\u4ef6\u3002

          sendFile(path)\n

          \u53c2\u6570\uff1a - path (str): \u8981\u53d1\u9001\u7684\u6587\u4ef6\u8def\u5f84

          "},{"location":"qsl4a/core/intent/#getpathtype","title":"getPathType()","text":"

          \u83b7\u53d6\u6587\u4ef6\u8def\u5f84\u7684 MIME \u7c7b\u578b\u3002

          getPathType(path)\n

          \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

          \u8fd4\u56de\uff1a MIME \u7c7b\u578b\u5b57\u7b26\u4e32

          "},{"location":"qsl4a/core/intent/#viewmap","title":"viewMap()","text":"

          \u5728\u6307\u5b9a\u4f4d\u7f6e\u6253\u5f00\u5730\u56fe\u3002

          viewMap(latitude, longitude)\n

          \u53c2\u6570\uff1a - latitude (float): \u7eac\u5ea6 - longitude (float): \u7ecf\u5ea6

          "},{"location":"qsl4a/core/intent/#viewcontacts","title":"viewContacts()","text":"

          \u6253\u5f00\u8054\u7cfb\u4eba\u5e94\u7528\u3002

          viewContacts()\n
          "},{"location":"qsl4a/core/intent/#search","title":"search()","text":"

          \u6267\u884c\u7f51\u7edc\u641c\u7d22\u3002

          search(query)\n

          \u53c2\u6570\uff1a - query (str): \u641c\u7d22\u67e5\u8be2

          "},{"location":"qsl4a/core/intent/#viewhtml","title":"viewHtml()","text":"

          \u67e5\u770b HTML \u5185\u5bb9\u3002

          viewHtml(content, encoding=None)\n

          \u53c2\u6570\uff1a - content (str): HTML \u5185\u5bb9 - encoding (str, optional): \u5b57\u7b26\u7f16\u7801

          "},{"location":"qsl4a/core/intent/#webviewshow","title":"webViewShow()","text":"

          \u5728 WebView \u4e2d\u663e\u793a\u7f51\u9875\u5185\u5bb9\u3002\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 viewHtml\u3002

          webViewShow(url)\n

          \u53c2\u6570\uff1a - url (str): \u7f51\u9875 URL

          "},{"location":"qsl4a/core/intent/#editoropen","title":"editorOpen()","text":"

          \u6253\u5f00\u6587\u672c\u7f16\u8f91\u5668\u3002

          editorOpen(path=None, create=False)\n

          \u53c2\u6570\uff1a - path (str, optional): \u8981\u7f16\u8f91\u7684\u6587\u4ef6\u8def\u5f84 - create (bool, optional): \u5982\u679c\u4e0d\u5b58\u5728\u5219\u521b\u5efa

          "},{"location":"qsl4a/core/intent/#uri","title":"\u8f85\u52a9\u7c7b\uff1aUri","text":"

          \u521b\u5efa Intent \u7684 URI \u5bf9\u8c61\uff1a

          from androidhelper.Intent import Uri\n\nuri = Uri(\"file:///sdcard/test.txt\")\n
          "},{"location":"qsl4a/core/intent/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/intent/#_7","title":"\u6253\u5f00\u7f51\u9875","text":"
          intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"http://www.example.com\"\n).result\ndroid.startActivityIntent(intent)\n
          "},{"location":"qsl4a/core/intent/#_8","title":"\u5206\u4eab\u6587\u672c","text":"
          intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_TEXT: \"Hello from QPython!\",\n        droid.Intent.EXTRA_SUBJECT: \"Test\"\n    },\n    type=\"text/plain\"\n).result\ndroid.startActivityIntent(intent)\n
          "},{"location":"qsl4a/core/intent/#_9","title":"\u6253\u5f00\u6587\u4ef6","text":"
          intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"file:///sdcard/document.pdf\",\n    type=\"application/pdf\"\n).result\ndroid.startActivityIntent(intent)\n
          "},{"location":"qsl4a/core/intent/#_10","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":"
          result = droid.pickContact()\ncontact_uri = result.result\n
          "},{"location":"qsl4a/core/intent/#_11","title":"\u53d1\u9001\u7535\u5b50\u90ae\u4ef6","text":"
          intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_EMAIL: [\"test@example.com\"],\n        droid.Intent.EXTRA_SUBJECT: \"Hello\",\n        droid.Intent.EXTRA_TEXT: \"Message body\"\n    },\n    type=\"message/rfc822\"\n).result\ndroid.startActivityIntent(intent)\n
          "},{"location":"qsl4a/core/intent/#_12","title":"\u6253\u5f00\u5e94\u7528","text":"
          intent = droid.makeIntent(\n    action=droid.Intent.ACTION_MAIN,\n    packagename=\"com.android.settings\",\n    classname=\"com.android.settings.Settings\"\n).result\ndroid.startActivityIntent(intent)\n
          "},{"location":"qsl4a/hardware/bluetooth/","title":"\u84dd\u7259 API","text":"

          \u63a7\u5236\u84dd\u7259\u9002\u914d\u5668\u5e76\u4e0e\u84dd\u7259\u8bbe\u5907\u901a\u4fe1\u3002

          "},{"location":"qsl4a/hardware/bluetooth/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/hardware/bluetooth/#togglebluetoothstate","title":"toggleBluetoothState()","text":"

          \u6253\u5f00/\u5173\u95ed\u84dd\u7259\u3002

          toggleBluetoothState(enabled=None, prompt=True)\n

          \u53c2\u6570\uff1a - enabled (bool): True=\u5f00\uff0cFalse=\u5173\uff0cNone=\u5207\u6362 - prompt (bool): \u663e\u793a\u7528\u6237\u63d0\u793a

          "},{"location":"qsl4a/hardware/bluetooth/#checkbluetoothstate","title":"checkBluetoothState()","text":"

          \u68c0\u67e5\u84dd\u7259\u662f\u5426\u5df2\u542f\u7528\u3002

          checkBluetoothState()\n

          \u8fd4\u56de\uff1a True/False

          "},{"location":"qsl4a/hardware/bluetooth/#getlocalname","title":"GetLocalName()","text":"

          \u83b7\u53d6\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

          GetLocalName()\n
          "},{"location":"qsl4a/hardware/bluetooth/#setlocalname","title":"SetLocalName()","text":"

          \u8bbe\u7f6e\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

          SetLocalName(name)\n
          "},{"location":"qsl4a/hardware/bluetooth/#getscanmode","title":"GetScanMode()","text":"

          \u83b7\u53d6\u53ef\u53d1\u73b0\u6027\u6a21\u5f0f\u3002

          GetScanMode()\n

          \u8fd4\u56de\uff1a - -1: \u5df2\u7981\u7528 - 0: \u4e0d\u53ef\u53d1\u73b0\uff0c\u4e0d\u53ef\u8fde\u63a5 - 1: \u53ef\u8fde\u63a5\uff0c\u4e0d\u53ef\u53d1\u73b0 - 3: \u53ef\u8fde\u63a5\u4e14\u53ef\u53d1\u73b0

          "},{"location":"qsl4a/hardware/bluetooth/#makediscoverable","title":"MakeDiscoverable()","text":"

          \u4f7f\u8bbe\u5907\u53ef\u53d1\u73b0\u3002

          MakeDiscoverable(duration=300)\n

          \u53c2\u6570\uff1a - duration (int): \u53ef\u53d1\u73b0\u7684\u79d2\u6570

          "},{"location":"qsl4a/hardware/bluetooth/#_2","title":"\u53d1\u73b0","text":""},{"location":"qsl4a/hardware/bluetooth/#discoverystart","title":"DiscoveryStart()","text":"

          \u5f00\u59cb\u8bbe\u5907\u53d1\u73b0\u3002

          DiscoveryStart()\n
          "},{"location":"qsl4a/hardware/bluetooth/#discoverycancel","title":"DiscoveryCancel()","text":"

          \u53d6\u6d88\u53d1\u73b0\u3002

          DiscoveryCancel()\n
          "},{"location":"qsl4a/hardware/bluetooth/#getreceiveddevices","title":"GetReceivedDevices()","text":"

          \u83b7\u53d6\u53d1\u73b0\u7684\u8bbe\u5907\u3002

          GetReceivedDevices()\n

          \u8fd4\u56de\uff1a \u8bbe\u5907\u4fe1\u606f\u5b57\u5178\u5217\u8868

          "},{"location":"qsl4a/hardware/bluetooth/#getbondeddevices","title":"GetBondedDevices()","text":"

          \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\u3002

          GetBondedDevices()\n

          \u8fd4\u56de\uff1a \u914d\u5bf9\u8bbe\u5907\u4fe1\u606f\u5217\u8868

          "},{"location":"qsl4a/hardware/bluetooth/#_3","title":"\u8fde\u63a5","text":""},{"location":"qsl4a/hardware/bluetooth/#connect","title":"Connect()","text":"

          \u8fde\u63a5\u5230\u8bbe\u5907\u3002

          Connect(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", address=None)\n

          \u53c2\u6570\uff1a - uuid (str): \u670d\u52a1 UUID - address (str): \u8bbe\u5907\u5730\u5740\uff08None = \u663e\u793a\u9009\u62e9\u5668\uff09

          \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

          "},{"location":"qsl4a/hardware/bluetooth/#accept","title":"Accept()","text":"

          \u63a5\u53d7\u4f20\u5165\u8fde\u63a5\u3002

          Accept(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", timeout=0)\n
          "},{"location":"qsl4a/hardware/bluetooth/#activeconnections","title":"ActiveConnections()","text":"

          \u68c0\u67e5\u6d3b\u52a8\u8fde\u63a5\u3002

          ActiveConnections()\n
          "},{"location":"qsl4a/hardware/bluetooth/#stop","title":"Stop()","text":"

          \u65ad\u5f00\u8fde\u63a5\u3002

          Stop(connID=None)\n
          "},{"location":"qsl4a/hardware/bluetooth/#_4","title":"\u901a\u4fe1","text":""},{"location":"qsl4a/hardware/bluetooth/#write","title":"Write()","text":"

          \u53d1\u9001 ASCII \u6570\u636e\u3002

          Write(ascii, connID=\"\")\n
          "},{"location":"qsl4a/hardware/bluetooth/#writebinary","title":"WriteBinary()","text":"

          \u53d1\u9001\u4e8c\u8fdb\u5236\u6570\u636e\uff08base64 \u7f16\u7801\uff09\u3002

          WriteBinary(base64, connID=None)\n
          "},{"location":"qsl4a/hardware/bluetooth/#read","title":"Read()","text":"

          \u8bfb\u53d6 ASCII \u6570\u636e\u3002

          Read(bufferSize=4096, connID=None)\n
          "},{"location":"qsl4a/hardware/bluetooth/#readbinary","title":"ReadBinary()","text":"

          \u8bfb\u53d6\u4e8c\u8fdb\u5236\u6570\u636e\u3002

          ReadBinary(bufferSize=4096, connID=None)\n
          "},{"location":"qsl4a/hardware/bluetooth/#readline","title":"ReadLine()","text":"

          \u8bfb\u53d6\u4e00\u884c\u3002

          ReadLine(connID=None)\n
          "},{"location":"qsl4a/hardware/bluetooth/#readready","title":"ReadReady()","text":"

          \u68c0\u67e5\u662f\u5426\u6709\u53ef\u7528\u6570\u636e\u3002

          ReadReady(connID=None)\n
          "},{"location":"qsl4a/hardware/bluetooth/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u7528\u84dd\u7259\ndroid.toggleBluetoothState(True)\n\n# \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\ndevices = droid.GetBondedDevices().result\nfor dev in devices:\n    print(f\"{dev['name']}: {dev['address']}\")\n\n# \u8fde\u63a5\u5230\u8bbe\u5907\ndroid.Connect(address=\"00:11:22:33:44:55\")\n\n# \u53d1\u9001\u6570\u636e\ndroid.Write(\"Hello Bluetooth!\")\n\n# \u8bfb\u53d6\u54cd\u5e94\ndata = droid.Read(1024).result\n
          "},{"location":"qsl4a/hardware/camera/","title":"\u76f8\u673a API","text":"

          \u62cd\u6444\u7167\u7247\u548c\u5f55\u5236\u89c6\u9891\u3002

          "},{"location":"qsl4a/hardware/camera/#_1","title":"\u7167\u7247\u62cd\u6444","text":""},{"location":"qsl4a/hardware/camera/#takepicture","title":"takePicture()","text":"

          \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u6444\u7167\u7247\u3002

          takePicture(path=None)\n

          \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8fd4\u56de\u56fe\u50cf\u6570\u636e

          \u8fd4\u56de\uff1a \u56fe\u50cf\u8def\u5f84\u6216\u56fe\u50cf\u6570\u636e

          "},{"location":"qsl4a/hardware/camera/#cameracapturepicture","title":"cameraCapturePicture()","text":"

          \u4f7f\u7528\u9ad8\u7ea7\u76f8\u673a\u63a7\u5236\u62cd\u6444\u7167\u7247\u3002

          cameraCapturePicture(targetPath=None, cameraId=0, useAutoFocus=True)\n

          \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - useAutoFocus (bool): \u542f\u7528\u81ea\u52a8\u5bf9\u7126

          \u8fd4\u56de\uff1a \u62cd\u6444\u7684\u56fe\u50cf\u8def\u5f84

          "},{"location":"qsl4a/hardware/camera/#camerasettorchmode","title":"cameraSetTorchMode()","text":"

          \u63a7\u5236\u76f8\u673a\u95ea\u5149\u706f/\u624b\u7535\u7b52\u3002

          cameraSetTorchMode(enabled)\n

          \u53c2\u6570\uff1a - enabled (bool): True \u6253\u5f00\uff0cFalse \u5173\u95ed

          \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

          "},{"location":"qsl4a/hardware/camera/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

          \u622a\u56fe\u3002

          imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

          \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

          "},{"location":"qsl4a/hardware/camera/#_2","title":"\u89c6\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#takevideo","title":"takeVideo()","text":"

          \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\u3002

          takeVideo(path=None, quality=1)\n

          \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-4\uff09 - 0: 160x120 - 1: 320x240 - 2: 352x288 - 3: 640x480 - 4: 800x480

          "},{"location":"qsl4a/hardware/camera/#recordercapturevideo","title":"recorderCaptureVideo()","text":"

          \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\u3002

          recorderCaptureVideo(targetPath=None, duration=10, cameraId=0, quality=8)\n

          \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - duration (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a10\uff09 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-8\uff0c\u8d8a\u9ad8\u8d8a\u597d\uff09

          \u8fd4\u56de\uff1a \u89c6\u9891\u6587\u4ef6\u8def\u5f84

          "},{"location":"qsl4a/hardware/camera/#recordaudio","title":"recordAudio()","text":"

          \u5f55\u5236\u97f3\u9891\u3002

          recordAudio()\n

          \u8fd4\u56de\uff1a \u97f3\u9891\u6587\u4ef6\u8def\u5f84

          "},{"location":"qsl4a/hardware/camera/#_3","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

          \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\u3002

          recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

          \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\uff09 - targetPixels (int): \u5206\u8fa8\u7387 - frameRate (int): FPS - bitRate (int): \u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa - autoStart (bool): \u7acb\u5373\u5f00\u59cb

          "},{"location":"qsl4a/hardware/camera/#recorderstart","title":"recorderStart()","text":"

          \u5f00\u59cb\u5f55\u5236\u3002

          recorderStart()\n
          "},{"location":"qsl4a/hardware/camera/#recorderpause","title":"recorderPause()","text":"

          \u6682\u505c\u5f55\u5236\u3002

          recorderPause()\n
          "},{"location":"qsl4a/hardware/camera/#recorderresume","title":"recorderResume()","text":"

          \u6062\u590d\u5f55\u5236\u3002

          recorderResume()\n
          "},{"location":"qsl4a/hardware/camera/#_4","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/camera/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

          \u5f00\u59cb\u97f3\u91cf\u68c0\u6d4b\u3002

          recorderSoundVolumeDetect(interval=100)\n
          "},{"location":"qsl4a/hardware/camera/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

          \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

          recorderSoundVolumeGetDb()\n
          "},{"location":"qsl4a/hardware/camera/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u7167\nphoto_path = droid.takePicture(\"/sdcard/photo.jpg\").result\nprint(f\"Photo saved: {photo_path}\")\n\n# \u4f7f\u7528\u524d\u7f6e\u76f8\u673a\u548c\u81ea\u52a8\u5bf9\u7126\u62cd\u7167\ncamera_path = droid.cameraCapturePicture(\"/sdcard/selfie.jpg\", cameraId=1, useAutoFocus=True).result\nprint(f\"Front camera photo: {camera_path}\")\n\n# \u63a7\u5236\u95ea\u5149\u706f\ndroid.cameraSetTorchMode(True)  # \u6253\u5f00\u95ea\u5149\u706f\n\n# \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\nvideo_path = droid.takeVideo(\"/sdcard/video.mp4\", quality=3).result\nprint(f\"Video saved: {video_path}\")\n\n# \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\nvideo_path = droid.recorderCaptureVideo(\"/sdcard/movie.mp4\", duration=30, cameraId=0, quality=8).result\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n
          "},{"location":"qsl4a/hardware/recorder/","title":"\u97f3\u9891\u5f55\u5236 API","text":"

          \u4ece\u9ea6\u514b\u98ce\u548c\u8bbe\u5907\u5c4f\u5e55\u5f55\u5236\u97f3\u9891\u3002

          "},{"location":"qsl4a/hardware/recorder/#_1","title":"\u97f3\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recordaudio","title":"recordAudio()","text":"

          \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\u3002

          recordAudio()\n

          \u8fd4\u56de\uff1a \u5f55\u5236\u7684\u97f3\u9891\u6587\u4ef6\u8def\u5f84

          "},{"location":"qsl4a/hardware/recorder/#recorderstartmicrophone","title":"recorderStartMicrophone()","text":"

          \u5f00\u59cb\u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\u3002

          recorderStartMicrophone(targetPath=None)\n

          \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u5f55\u5236\u7684\u8def\u5f84

          "},{"location":"qsl4a/hardware/recorder/#_2","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

          \u5f00\u59cb\u5e26\u97f3\u9891\u7684\u5c4f\u5e55\u5f55\u5236\u3002

          recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

          \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\u97f3\u9891\uff09 - targetPixels (int): \u76ee\u6807\u5206\u8fa8\u7387\uff08\u50cf\u7d20\uff09 - frameRate (int): \u6bcf\u79d2\u5e27\u6570\uff08\u9ed8\u8ba4\uff1a30\uff09 - bitRate (int): \u89c6\u9891\u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa\u89c6\u9891 - autoStart (bool): \u7acb\u5373\u5f00\u59cb\u5f55\u5236

          \u8fd4\u56de\uff1a \u64cd\u4f5c\u7ed3\u679c

          "},{"location":"qsl4a/hardware/recorder/#recorderstart","title":"recorderStart()","text":"

          \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\uff08\u5f53 autoStart=False \u65f6\uff09\u3002

          recorderStart()\n
          "},{"location":"qsl4a/hardware/recorder/#recorderpause","title":"recorderPause()","text":"

          \u6682\u505c\u6b63\u5728\u8fdb\u884c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

          recorderPause()\n
          "},{"location":"qsl4a/hardware/recorder/#recorderresume","title":"recorderResume()","text":"

          \u6062\u590d\u6682\u505c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

          recorderResume()\n
          "},{"location":"qsl4a/hardware/recorder/#_3","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/recorder/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

          \u5f00\u59cb\u76d1\u63a7\u97f3\u91cf\u7ea7\u522b\u3002

          recorderSoundVolumeDetect(interval=100)\n

          \u53c2\u6570\uff1a - interval (int): \u68c0\u6d4b\u95f4\u9694\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a100\uff09

          "},{"location":"qsl4a/hardware/recorder/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

          \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

          recorderSoundVolumeGetDb()\n

          \u8fd4\u56de\uff1a \u5f53\u524d\u97f3\u91cf\u7ea7\u522b\uff08dB\uff09

          "},{"location":"qsl4a/hardware/recorder/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\nprint(\"Recording audio...\")\naudio_path = droid.recordAudio().result\nprint(f\"Saved to: {audio_path}\")\n\n# \u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\ndroid.recorderStartMicrophone(\"/sdcard/my_recording.mp3\")\ntime.sleep(5)\ndroid.recorderStop()\n\n# \u5e26\u97f3\u9891\u5f55\u5236\u5c4f\u5e55\nprint(\"Starting screen recording...\")\ndroid.recorderStartScreenRecord(\n    path=\"/sdcard/screen_record.mp4\",\n    audio=1,\n    frameRate=30,\n    autoStart=True\n)\ntime.sleep(10)\ndroid.recorderStop()\n\n# \u76d1\u63a7\u97f3\u91cf\ndroid.recorderSoundVolumeDetect(interval=100)\ntime.sleep(3)\nvolume = droid.recorderSoundVolumeGetDb().result\nprint(f\"Current volume: {volume} dB\")\n
          "},{"location":"qsl4a/hardware/usbserial/","title":"USB \u4e3b\u673a\u4e32\u884c API","text":"

          \u4e0e USB \u4e32\u884c\u8bbe\u5907\u901a\u4fe1\uff08\u9700\u8981 USB OTG \u652f\u6301\u548c Android 3.1+\uff09\u3002

          "},{"location":"qsl4a/hardware/usbserial/#usb","title":"USB \u4e32\u884c\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialopen","title":"usbHostSerialOpen()","text":"

          \u6253\u5f00\u4e0e USB \u4e32\u884c\u8bbe\u5907\u7684\u8fde\u63a5\u3002

          usbHostSerialOpen(device, baudRate=9600)\n

          \u53c2\u6570\uff1a - device (str): USB \u8bbe\u5907\u8def\u5f84\u6216\u6807\u8bc6\u7b26 - baudRate (int): \u6ce2\u7279\u7387\uff08\u9ed8\u8ba4\uff1a9600\uff09

          \u8fd4\u56de\uff1a \u5982\u679c\u6253\u5f00\u6210\u529f\u5219\u4e3a True

          "},{"location":"qsl4a/hardware/usbserial/#usbhostserialclose","title":"usbHostSerialClose()","text":"

          \u5173\u95ed USB \u4e32\u884c\u8fde\u63a5\u3002

          usbHostSerialClose()\n
          "},{"location":"qsl4a/hardware/usbserial/#usbhostserialread","title":"usbHostSerialRead()","text":"

          \u4ece USB \u4e32\u884c\u8bfb\u53d6\u6570\u636e\u3002

          usbHostSerialRead(bufferSize=1024)\n

          \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570\uff08\u9ed8\u8ba4\uff1a1024\uff09

          \u8fd4\u56de\uff1a \u8bfb\u53d6\u7684\u6570\u636e\u5b57\u7b26\u4e32

          "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwrite","title":"usbHostSerialWrite()","text":"

          \u5411 USB \u4e32\u884c\u5199\u5165\u6570\u636e\u3002

          usbHostSerialWrite(data)\n

          \u53c2\u6570\uff1a - data (str): \u8981\u5199\u5165\u7684\u5b57\u7b26\u4e32\u6570\u636e

          "},{"location":"qsl4a/hardware/usbserial/#usbhostserialavailable","title":"usbHostSerialAvailable()","text":"

          \u68c0\u67e5\u662f\u5426\u6709\u53ef\u8bfb\u53d6\u7684\u6570\u636e\u3002

          usbHostSerialAvailable()\n

          \u8fd4\u56de\uff1a \u53ef\u7528\u5b57\u8282\u6570

          "},{"location":"qsl4a/hardware/usbserial/#_1","title":"\u914d\u7f6e\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetbaudrate","title":"usbHostSerialSetBaudRate()","text":"

          \u8bbe\u7f6e\u6ce2\u7279\u7387\u3002

          usbHostSerialSetBaudRate(baudRate)\n

          \u53c2\u6570\uff1a - baudRate (int): \u6ce2\u7279\u7387

          "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetdatabits","title":"usbHostSerialSetDataBits()","text":"

          \u8bbe\u7f6e\u6570\u636e\u4f4d\uff085\u30016\u30017 \u6216 8\uff09\u3002

          usbHostSerialSetDataBits(dataBits)\n

          \u53c2\u6570\uff1a - dataBits (int): \u6570\u636e\u4f4d\uff085-8\uff09

          "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetstopbits","title":"usbHostSerialSetStopBits()","text":"

          \u8bbe\u7f6e\u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09\u3002

          usbHostSerialSetStopBits(stopBits)\n

          \u53c2\u6570\uff1a - stopBits (float): \u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09

          "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetparity","title":"usbHostSerialSetParity()","text":"

          \u8bbe\u7f6e\u6821\u9a8c\u4f4d\uff08\u65e0\u3001\u5947\u3001\u5076\u3001\u6807\u8bb0\u3001\u7a7a\u683c\uff09\u3002

          usbHostSerialSetParity(parity)\n

          \u53c2\u6570\uff1a - parity (str): \u6821\u9a8c\u6a21\u5f0f\uff08'none'\u3001'odd'\u3001'even'\u3001'mark'\u3001'space'\uff09

          "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetflowcontrol","title":"usbHostSerialSetFlowControl()","text":"

          \u8bbe\u7f6e\u6d41\u63a7\u5236\uff08\u65e0\u3001\u786c\u4ef6\u3001\u8f6f\u4ef6\uff09\u3002

          usbHostSerialSetFlowControl(flowControl)\n

          \u53c2\u6570\uff1a - flowControl (str): \u6d41\u63a7\u5236\u6a21\u5f0f\uff08'none'\u3001'hardware'\u3001'software'\uff09

          "},{"location":"qsl4a/hardware/usbserial/#usbhostserialreadhex","title":"usbHostSerialReadHex()","text":"

          \u4ee5\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u8bfb\u53d6\u6570\u636e\u3002

          usbHostSerialReadHex(bufferSize=1024)\n

          \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570

          \u8fd4\u56de\uff1a \u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

          "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwritehex","title":"usbHostSerialWriteHex()","text":"

          \u4ece\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u5199\u5165\u6570\u636e\u3002

          usbHostSerialWriteHex(hexString)\n

          \u53c2\u6570\uff1a - hexString (str): \u8981\u5199\u5165\u7684\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

          "},{"location":"qsl4a/hardware/usbserial/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6253\u5f00 USB \u4e32\u884c\u8fde\u63a5\nif droid.usbHostSerialOpen(\"/dev/bus/usb/001/001\", 115200).result:\n    print(\"USB serial opened\")\n\n    # \u5199\u5165\u6570\u636e\n    droid.usbHostSerialWrite(\"AT\\r\")\n\n    # \u8bfb\u53d6\u54cd\u5e94\n    response = droid.usbHostSerialRead(1024).result\n    print(f\"Response: {response}\")\n\n    # \u6216\u4f7f\u7528\u5341\u516d\u8fdb\u5236\n    droid.usbHostSerialWriteHex(\"41540D0A\")  # \"AT\\r\\n\"\n\n    # \u5173\u95ed\u8fde\u63a5\n    droid.usbHostSerialClose()\n

          \u6ce8\u610f\uff1a USB \u4e32\u884c\u9700\u8981\uff1a - Android 3.1+ (API 12) - USB OTG \u7ebf/\u9002\u914d\u5668 - \u8bbe\u5907\u4e0a\u7684 USB \u4e3b\u673a\u6a21\u5f0f\u652f\u6301 - \u517c\u5bb9\u7684\u4e32\u884c\u8bbe\u5907

          "},{"location":"qsl4a/hardware/webcam/","title":"\u7f51\u7edc\u6444\u50cf\u5934 API","text":"

          \u4f7f\u7528 MJPEG \u4ece\u8bbe\u5907\u76f8\u673a\u6d41\u5f0f\u4f20\u8f93\u89c6\u9891\u3002

          "},{"location":"qsl4a/hardware/webcam/#mjpeg","title":"MJPEG \u6d41\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#webcamstart","title":"webcamStart()","text":"

          \u4ece\u7f51\u7edc\u6444\u50cf\u5934\u542f\u52a8 MJPEG \u6d41\u3002

          webcamStart(resolutionLevel=0, jpegQuality=20, port=0)\n

          \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf 1-100\uff08\u9ed8\u8ba4\uff1a20\uff09 - port (int): \u7aef\u53e3\u53f7\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\uff09

          \u8fd4\u56de\uff1a \u6d41\u7684 (\u5730\u5740, \u7aef\u53e3) \u5143\u7ec4

          "},{"location":"qsl4a/hardware/webcam/#webcamadjustquality","title":"webcamAdjustQuality()","text":"

          \u8c03\u6574\u6d3b\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u7684\u8d28\u91cf\u3002

          webcamAdjustQuality(resolutionLevel=0, jpegQuality=20)\n

          \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b - jpegQuality (int): JPEG \u8d28\u91cf 1-100

          "},{"location":"qsl4a/hardware/webcam/#webcamstop","title":"webcamStop()","text":"

          \u505c\u6b62\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u3002

          webcamStop()\n
          "},{"location":"qsl4a/hardware/webcam/#_1","title":"\u76f8\u673a\u9884\u89c8\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#camerastartpreview","title":"cameraStartPreview()","text":"

          \u5f00\u59cb\u5e26\u4e8b\u4ef6\u751f\u6210\u7684\u76f8\u673a\u9884\u89c8\u6a21\u5f0f\u3002

          cameraStartPreview(resolutionLevel=0, jpegQuality=20, filepath=None)\n

          \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf\uff08\u9ed8\u8ba4\uff1a20\uff09 - filepath (str, optional): \u4fdd\u5b58\u9884\u89c8\u5e27\u7684\u6587\u4ef6\u8def\u5f84

          \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

          \u6ce8\u610f\uff1a \u751f\u6210\u5e26\u6709\u5e27\u6570\u636e\u7684 'preview' \u4e8b\u4ef6\u3002

          "},{"location":"qsl4a/hardware/webcam/#camerastoppreview","title":"cameraStopPreview()","text":"

          \u505c\u6b62\u76f8\u673a\u9884\u89c8\u3002

          cameraStopPreview()\n
          "},{"location":"qsl4a/hardware/webcam/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\nstream_info = droid.webcamStart(\n    resolutionLevel=0,\n    jpegQuality=30,\n    port=8080\n).result\nprint(f\"Stream available at {stream_info[0]}:{stream_info[1]}\")\n\n# \u6d41\u5f0f\u4f20\u8f93\u65f6\u8c03\u6574\u8d28\u91cf\ntime.sleep(5)\ndroid.webcamAdjustQuality(resolutionLevel=1, jpegQuality=50)\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.webcamStop()\n\n# \u6216\u4f7f\u7528\u9884\u89c8\u6a21\u5f0f\nprint(\"Starting preview...\")\ndroid.cameraStartPreview()\n\n# \u7b49\u5f85\u9884\u89c8\u4e8b\u4ef6\nfor i in range(10):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'preview':\n        print(f\"Got preview frame: {event['data']}\")\n\ndroid.cameraStopPreview()\n
          "},{"location":"qsl4a/media/image/","title":"\u56fe\u50cf\u5904\u7406 API","text":"

          \u538b\u7f29\u548c\u5904\u7406\u56fe\u50cf\u3002

          "},{"location":"qsl4a/media/image/#_1","title":"\u56fe\u50cf\u538b\u7f29","text":""},{"location":"qsl4a/media/image/#imagecompress","title":"imageCompress()","text":"

          \u538b\u7f29\u56fe\u50cf\u6587\u4ef6\u3002

          imageCompress(srcPath, destPath, targetByteSize=0, targetWidth=0, targetHeight=0)\n

          \u53c2\u6570\uff1a - srcPath (str): \u6e90\u56fe\u50cf\u8def\u5f84 - destPath (str): \u8f93\u51fa\u8def\u5f84 - targetByteSize (int): \u76ee\u6807\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff080 = \u65e0\u9650\u5236\uff09 - targetWidth (int): \u76ee\u6807\u5bbd\u5ea6\uff080 = \u539f\u59cb\uff09 - targetHeight (int): \u76ee\u6807\u9ad8\u5ea6\uff080 = \u539f\u59cb\uff09

          \u8fd4\u56de\uff1a \u538b\u7f29\u540e\u7684\u56fe\u50cf\u8def\u5f84

          "},{"location":"qsl4a/media/image/#_2","title":"\u622a\u56fe","text":""},{"location":"qsl4a/media/image/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

          \u622a\u53d6\u5c4f\u5e55\u3002

          imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

          \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

          \u8fd4\u56de\uff1a \u622a\u56fe\u8def\u5f84

          "},{"location":"qsl4a/media/image/#_3","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/image/#videoplay","title":"videoPlay()","text":"

          \u5728\u5168\u5c4f\u6a21\u5f0f\u4e0b\u64ad\u653e\u89c6\u9891\u6587\u4ef6\u3002

          videoPlay(path, wait=True)\n

          \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

          "},{"location":"qsl4a/media/image/#_4","title":"\u6761\u7801\u626b\u63cf","text":""},{"location":"qsl4a/media/image/#scanbarcodefromimage","title":"scanBarcodeFromImage()","text":"

          \u4ece\u56fe\u50cf\u6587\u4ef6\u626b\u63cf\u6761\u7801/\u4e8c\u7ef4\u7801\u3002

          scanBarcodeFromImage(path, compressRatio=0, x=0, y=0, width=0, height=0)\n

          \u53c2\u6570\uff1a - path (str): \u56fe\u50cf\u6587\u4ef6\u8def\u5f84 - compressRatio (int): \u538b\u7f29\u6bd4\uff080 = \u4e0d\u538b\u7f29\uff09 - x, y, width, height (int): \u8981\u626b\u63cf\u7684\u533a\u57df\uff080 = \u5b8c\u6574\u56fe\u50cf\uff09

          \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5185\u5bb9

          "},{"location":"qsl4a/media/image/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n\n# \u538b\u7f29\u56fe\u50cf\ncompressed = droid.imageCompress(\n    \"/sdcard/large_photo.jpg\",\n    \"/sdcard/compressed.jpg\",\n    targetByteSize=102400,  # \u76ee\u6807\u7ea6 100KB\n    targetWidth=1920,\n    targetHeight=1080\n).result\nprint(f\"Saved: {compressed}\")\n\n# \u64ad\u653e\u89c6\u9891\nvideo_path = \"/sdcard/movie.mp4\"\ndroid.videoPlay(video_path, wait=True)\n\n# \u4ece\u56fe\u50cf\u626b\u63cf\u6761\u7801\nresult = droid.scanBarcodeFromImage(\"/sdcard/qr_code.png\").result\nprint(f\"Barcode: {result}\")\n
          "},{"location":"qsl4a/media/mediaplayer/","title":"\u5a92\u4f53\u64ad\u653e\u5668 API","text":"

          \u63a7\u5236\u97f3\u9891\u548c\u89c6\u9891\u64ad\u653e\u3002

          "},{"location":"qsl4a/media/mediaplayer/#_1","title":"\u64ad\u653e\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplay","title":"mediaPlay()","text":"

          \u64ad\u653e\u5a92\u4f53\u6587\u4ef6\u3002

          mediaPlay(url, tag=\"default\", play=True)\n

          \u53c2\u6570\uff1a - url (str): \u5a92\u4f53\u6587\u4ef6\u8def\u5f84\u6216 URL - tag (str): \u64ad\u653e\u5668\u6807\u8bc6\u7b26 - play (bool): \u81ea\u52a8\u5f00\u59cb\u64ad\u653e

          "},{"location":"qsl4a/media/mediaplayer/#mediaplaystart","title":"mediaPlayStart()","text":"

          \u5f00\u59cb\u64ad\u653e\u3002

          mediaPlayStart(tag=\"default\")\n
          "},{"location":"qsl4a/media/mediaplayer/#mediaplaypause","title":"mediaPlayPause()","text":"

          \u6682\u505c\u64ad\u653e\u3002

          mediaPlayPause(tag=\"default\")\n
          "},{"location":"qsl4a/media/mediaplayer/#mediaplayclose","title":"mediaPlayClose()","text":"

          \u5173\u95ed\u64ad\u653e\u5668\u3002

          mediaPlayClose(tag=\"default\")\n
          "},{"location":"qsl4a/media/mediaplayer/#mediaplayseek","title":"mediaPlaySeek()","text":"

          \u8df3\u8f6c\u5230\u4f4d\u7f6e\u3002

          mediaPlaySeek(msec, tag=\"default\")\n

          \u53c2\u6570\uff1a - msec (int): \u4f4d\u7f6e\uff08\u6beb\u79d2\uff09

          "},{"location":"qsl4a/media/mediaplayer/#mediaplaysetlooping","title":"mediaPlaySetLooping()","text":"

          \u8bbe\u7f6e\u5faa\u73af\u6a21\u5f0f\u3002

          mediaPlaySetLooping(enabled, tag=\"default\")\n
          "},{"location":"qsl4a/media/mediaplayer/#_2","title":"\u64ad\u653e\u5668\u4fe1\u606f","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplayinfo","title":"mediaPlayInfo()","text":"

          \u83b7\u53d6\u64ad\u653e\u4fe1\u606f\u3002

          mediaPlayInfo(tag=\"default\")\n

          \u8fd4\u56de\uff1a \u5305\u542b\u65f6\u957f\u3001\u4f4d\u7f6e\u7b49\u7684\u5b57\u5178

          "},{"location":"qsl4a/media/mediaplayer/#mediaisplaying","title":"mediaIsPlaying()","text":"

          \u68c0\u67e5\u662f\u5426\u6b63\u5728\u64ad\u653e\u3002

          mediaIsPlaying(tag=\"default\")\n

          \u8fd4\u56de\uff1a True/False

          "},{"location":"qsl4a/media/mediaplayer/#mediaplaylist","title":"mediaPlayList()","text":"

          \u5217\u51fa\u6d3b\u52a8\u64ad\u653e\u5668\u3002

          mediaPlayList()\n
          "},{"location":"qsl4a/media/mediaplayer/#_3","title":"\u97f3\u91cf\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#getmediavolume","title":"getMediaVolume()","text":"

          \u83b7\u53d6\u5a92\u4f53\u97f3\u91cf\u3002

          getMediaVolume()\n

          \u8fd4\u56de\uff1a \u97f3\u91cf\u7ea7\u522b\uff080-15\uff09

          "},{"location":"qsl4a/media/mediaplayer/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

          \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

          getMaxMediaVolume()\n
          "},{"location":"qsl4a/media/mediaplayer/#getringervolume","title":"getRingerVolume()","text":"

          \u83b7\u53d6\u94c3\u58f0\u97f3\u91cf\u3002

          getRingerVolume()\n
          "},{"location":"qsl4a/media/mediaplayer/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

          \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

          getMaxRingerVolume()\n
          "},{"location":"qsl4a/media/mediaplayer/#_4","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/mediaplayer/#videoplay","title":"videoPlay()","text":"

          \u5168\u5c4f\u64ad\u653e\u89c6\u9891\u3002

          videoPlay(path, wait=True)\n

          \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210

          "},{"location":"qsl4a/media/mediaplayer/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u64ad\u653e\u97f3\u9891\ndroid.mediaPlay(\"/sdcard/music.mp3\", tag=\"music\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.mediaIsPlaying(\"music\").result:\n    info = droid.mediaPlayInfo(\"music\").result\n    print(f\"Playing: {info}\")\n\n# \u8df3\u8f6c\u5230 30 \u79d2\ndroid.mediaPlaySeek(30000, \"music\")\n\n# \u5173\u95ed\ndroid.mediaPlayClose(\"music\")\n\n# \u64ad\u653e\u89c6\u9891\ndroid.videoPlay(\"/sdcard/movie.mp4\", wait=True)\n
          "},{"location":"qsl4a/special/cipher/","title":"\u5bc6\u7801 API","text":"

          \u7528\u4e8e\u5b89\u5168\u6570\u636e\u5b58\u50a8\u7684\u52a0\u5bc6\u548c\u89e3\u5bc6\u5de5\u5177\u3002

          "},{"location":"qsl4a/special/cipher/#_1","title":"\u521d\u59cb\u5316","text":""},{"location":"qsl4a/special/cipher/#cipherinit","title":"cipherInit()","text":"

          \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u548c\u7b97\u6cd5\u521d\u59cb\u5316\u5bc6\u7801\u5668\u3002

          cipherInit(key, algorithm=\"AES/CBC/PKCS5Padding\", encodingFormat=\"\", initialVector=\"\")\n

          \u53c2\u6570\uff1a - key (str or bytes): \u52a0\u5bc6\u5bc6\u94a5 - algorithm (str): \u5bc6\u7801\u7b97\u6cd5\uff08\u9ed8\u8ba4\uff1a\"AES/CBC/PKCS5Padding\"\uff09 - encodingFormat (str): \u7f16\u7801\u683c\u5f0f - initialVector (str or bytes): \u52a0\u5bc6\u7684\u521d\u59cb\u5411\u91cf

          \u8fd4\u56de\uff1a \u521d\u59cb\u5316\u7ed3\u679c

          \u6ce8\u610f\uff1a \u5fc5\u987b\u5728\u4efb\u4f55\u52a0\u5bc6/\u89e3\u5bc6\u64cd\u4f5c\u4e4b\u524d\u8c03\u7528\u3002

          "},{"location":"qsl4a/special/cipher/#_2","title":"\u52a0\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#encryptstring","title":"encryptString()","text":"

          \u52a0\u5bc6\u5b57\u7b26\u4e32\u3002

          encryptString(plainText)\n

          \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c

          \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u7b26\u4e32

          "},{"location":"qsl4a/special/cipher/#encryptbytes","title":"encryptBytes()","text":"

          \u52a0\u5bc6\u5b57\u8282\u6570\u636e\u3002

          encryptBytes(data)\n

          \u53c2\u6570\uff1a - data (bytes): \u8981\u52a0\u5bc6\u7684\u6570\u636e

          \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u8282

          "},{"location":"qsl4a/special/cipher/#encryptstringtofile","title":"encryptStringToFile()","text":"

          \u52a0\u5bc6\u5b57\u7b26\u4e32\u5230\u6587\u4ef6\u3002

          encryptStringToFile(plainText, filePath)\n

          \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c - filePath (str): \u8f93\u51fa\u6587\u4ef6\u8def\u5f84

          "},{"location":"qsl4a/special/cipher/#encryptbytestofile","title":"encryptBytesToFile()","text":"

          \u52a0\u5bc6\u5b57\u8282\u5230\u6587\u4ef6\u3002

          encryptBytesToFile(data, filePath)\n
          "},{"location":"qsl4a/special/cipher/#_3","title":"\u89e3\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#decryptstring","title":"decryptString()","text":"

          \u89e3\u5bc6\u4e3a\u5b57\u7b26\u4e32\u3002

          decryptString(cipherText)\n

          \u53c2\u6570\uff1a - cipherText (str): \u52a0\u5bc6\u7684\u6587\u672c

          \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u7b26\u4e32

          "},{"location":"qsl4a/special/cipher/#decryptbytes","title":"decryptBytes()","text":"

          \u89e3\u5bc6\u4e3a\u5b57\u8282\u3002

          decryptBytes(data)\n

          \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u8282

          "},{"location":"qsl4a/special/cipher/#decryptfiletostring","title":"decryptFileToString()","text":"

          \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u7b26\u4e32\u3002

          decryptFileToString(filePath)\n
          "},{"location":"qsl4a/special/cipher/#decryptfiletobytes","title":"decryptFileToBytes()","text":"

          \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u8282\u3002

          decryptFileToBytes(filePath)\n
          "},{"location":"qsl4a/special/cipher/#decryptfile","title":"decryptFile()","text":"

          \u89e3\u5bc6\u6587\u4ef6\u5230\u6587\u4ef6\u3002

          decryptFile(srcPath, destPath)\n
          "},{"location":"qsl4a/special/cipher/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u521d\u59cb\u5316\u5bc6\u7801\u5668\ndroid.cipherInit(\"my_secret_key_1234\")\n\n# \u52a0\u5bc6\u5b57\u7b26\u4e32\nencrypted = droid.encryptString(\"Secret message!\").result\nprint(f\"Encrypted: {encrypted}\")\n\n# \u89e3\u5bc6\u5b57\u7b26\u4e32\ndecrypted = droid.decryptString(encrypted).result\nprint(f\"Decrypted: {decrypted}\")\n\n# \u52a0\u5bc6\u5230\u6587\u4ef6\ndroid.encryptStringToFile(\"My secret data\", \"/sdcard/secret.dat\")\n\n# \u4ece\u6587\u4ef6\u89e3\u5bc6\ndata = droid.decryptFileToString(\"/sdcard/secret.dat\").result\nprint(data)\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u7b97\u6cd5\u548c IV \u521d\u59cb\u5316\ndroid.cipherInit(\n    key=\"my_key\",\n    algorithm=\"AES/CBC/PKCS5Padding\",\n    initialVector=\"0123456789abcdef\"\n)\n
          "},{"location":"qsl4a/special/pgptai/","title":"PGPT AI API","text":"

          \u8bed\u97f3\u8f6c\u6587\u672c\u548c AI \u670d\u52a1\u96c6\u6210\u3002

          "},{"location":"qsl4a/special/pgptai/#_1","title":"\u5148\u51b3\u6761\u4ef6","text":"
          pip install pgptAI\n
          "},{"location":"qsl4a/special/pgptai/#_2","title":"\u8bed\u97f3\u8bc6\u522b","text":""},{"location":"qsl4a/special/pgptai/#speechtotext","title":"speechToText()","text":"

          \u5c06\u8bed\u97f3\u8f6c\u6362\u4e3a\u6587\u672c\u3002

          speechToText(RecordSecond=10, AmrFile=None, Language=None)\n

          \u53c2\u6570\uff1a - RecordSecond (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09 - AmrFile (str, optional): \u73b0\u6709\u97f3\u9891\u6587\u4ef6\u8def\u5f84 - Language (str, optional): \u8bed\u8a00\u4ee3\u7801\uff08'en'\u3001'zh'\uff09

          \u8fd4\u56de\uff1a \u8f6c\u5f55\u7684\u6587\u672c

          "},{"location":"qsl4a/special/pgptai/#_3","title":"\u6587\u672c\u8f6c\u8bed\u97f3","text":""},{"location":"qsl4a/special/pgptai/#texttospeech","title":"textToSpeech()","text":"

          \u5c06\u6587\u672c\u8f6c\u6362\u4e3a\u8bed\u97f3\u5e76\u53ef\u9009\u5730\u64ad\u653e\u3002

          textToSpeech(Text, AutoPlay=True, WavFile=None, VoiceName=None)\n

          \u53c2\u6570\uff1a - Text (str): \u8981\u8f6c\u6362\u4e3a\u8bed\u97f3\u7684\u6587\u672c - AutoPlay (bool): \u81ea\u52a8\u64ad\u653e\u751f\u6210\u7684\u97f3\u9891\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - WavFile (str, optional): \u4fdd\u5b58 WAV \u6587\u4ef6\u7684\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u4e34\u65f6\u6587\u4ef6 - VoiceName (str, optional): \u8981\u4f7f\u7528\u7684\u8bed\u97f3\u540d\u79f0\uff08\u4f8b\u5982 'en-US-JennyNeural'\u3001'zh-CN-XiaoxiaoNeural'\uff09

          \u8fd4\u56de\uff1a \u5305\u542b\u8bed\u97f3\u5408\u6210\u7ed3\u679c\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - text: \u8f93\u5165\u6587\u672c - url: \u4e0b\u8f7d\u97f3\u9891\u6587\u4ef6\u7684 URL - WavFile: \u4fdd\u5b58\u7684 WAV \u6587\u4ef6\u8def\u5f84\uff08\u5982\u679c\u672c\u5730\u4fdd\u5b58\uff09

          "},{"location":"qsl4a/special/pgptai/#_4","title":"\u914d\u7f6e","text":"

          API \u4f7f\u7528\u4ee5\u4e0b\u914d\u7f6e\u6587\u4ef6\u4e2d\u7684\u914d\u7f6e\uff1a/storage/emulated/0/Android/data/org.qpython.qpy/files/apigpt.conf\uff1a

          [speech]\nspeech_key = your_api_key\n

          \u9ed8\u8ba4\u8bed\u97f3\u8bbe\u7f6e\uff1a - \u82f1\u8bed\uff1aen-US-JennyNeural - \u4e2d\u6587\uff1azh-CN-XiaoxiaoNeural

          "},{"location":"qsl4a/special/pgptai/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5f55\u5236\u5e76\u8f6c\u5f55\nprint(\"Recording for 5 seconds...\")\ntext = droid.speechToText(RecordSecond=5, Language='en').result\nprint(f\"You said: {text}\")\n\n# \u8f6c\u5f55\u73b0\u6709\u6587\u4ef6\ntext = droid.speechToText(AmrFile=\"/sdcard/recording.amr\").result\nprint(f\"Transcription: {text}\")\n\n# \u6587\u672c\u8f6c\u8bed\u97f3\ndroid.textToSpeech(\"Hello, this is a test message.\", AutoPlay=True, Language='en')\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u8bed\u97f3\u5e76\u4fdd\u5b58\u5230\u6587\u4ef6\u7684\u6587\u672c\u8f6c\u8bed\u97f3\nresult = droid.textToSpeech(\n    \"Welcome to QPython!\",\n    AutoPlay=False,\n    WavFile=\"/sdcard/welcome.wav\",\n    VoiceName=\"en-US-JennyNeural\"\n).result\nprint(f\"Audio saved to: {result.get('WavFile')}\")\n
          "},{"location":"qsl4a/special/pgptai/#_6","title":"\u7c7b\u4f7f\u7528","text":"
          from androidhelper.pgptai import pgptai\nimport androidhelper\n\ndroid = androidhelper.Android()\nai = pgptai(droid)\n\n# \u4f7f\u7528\u8bed\u97f3\u8bc6\u522b\ntext = ai.speechToText(RecordSecond=10)\n
          "},{"location":"qsl4a/storage/clipboard/","title":"\u526a\u8d34\u677f API","text":"

          \u590d\u5236\u548c\u7c98\u8d34\u6587\u672c\u5230\u7cfb\u7edf\u526a\u8d34\u677f\u3002

          "},{"location":"qsl4a/storage/clipboard/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/clipboard/#setclipboard","title":"setClipboard()","text":"

          \u590d\u5236\u6587\u672c\u5230\u526a\u8d34\u677f\u3002

          setClipboard(text)\n

          \u53c2\u6570\uff1a - text (str): \u8981\u590d\u5236\u7684\u6587\u672c

          \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

          "},{"location":"qsl4a/storage/clipboard/#getclipboard","title":"getClipboard()","text":"

          \u4ece\u526a\u8d34\u677f\u83b7\u53d6\u6587\u672c\u3002

          getClipboard()\n

          \u8fd4\u56de\uff1a \u526a\u8d34\u677f\u6587\u672c

          "},{"location":"qsl4a/storage/clipboard/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u590d\u5236\u5230\u526a\u8d34\u677f\ndroid.setClipboard(\"Hello from QPython!\")\n\n# \u4ece\u526a\u8d34\u677f\u7c98\u8d34\ntext = droid.getClipboard().result\nprint(f\"Clipboard: {text}\")\n
          "},{"location":"qsl4a/storage/documentfile/","title":"DocumentFile API","text":"

          \u4f7f\u7528 SAF\uff08\u5b58\u50a8\u8bbf\u95ee\u6846\u67b6\uff09\u8fdb\u884c\u6587\u4ef6\u64cd\u4f5c\uff0c\u652f\u6301 Android 4.4+\u3002

          "},{"location":"qsl4a/storage/documentfile/#_1","title":"\u76ee\u5f55\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilemkdir","title":"documentFileMkdir()","text":"

          \u521b\u5efa\u76ee\u5f55\u3002

          documentFileMkdir(Dir)\n

          \u53c2\u6570\uff1a - Dir (str): \u76ee\u5f55\u8def\u5f84

          \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

          "},{"location":"qsl4a/storage/documentfile/#documentfilelistfiles","title":"documentFileListFiles()","text":"

          \u5217\u51fa\u76ee\u5f55\u4e2d\u7684\u6587\u4ef6\u3002

          documentFileListFiles(Folder)\n

          \u8fd4\u56de\uff1a \u6587\u4ef6\u5217\u8868

          "},{"location":"qsl4a/storage/documentfile/#_2","title":"\u6587\u4ef6\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileexists","title":"documentFileExists()","text":"

          \u68c0\u67e5\u6587\u4ef6\u6216\u76ee\u5f55\u662f\u5426\u5b58\u5728\u3002

          documentFileExists(path)\n

          \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u6216\u76ee\u5f55\u8def\u5f84

          \u8fd4\u56de\uff1a \u5982\u679c\u5b58\u5728\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

          "},{"location":"qsl4a/storage/documentfile/#documentfileisfile","title":"documentFileIsFile()","text":"

          \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u6587\u4ef6\u3002

          documentFileIsFile(path)\n

          \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

          \u8fd4\u56de\uff1a \u5982\u679c\u662f\u6587\u4ef6\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u6587\u4ef6\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

          "},{"location":"qsl4a/storage/documentfile/#documentfileisdirectory","title":"documentFileIsDirectory()","text":"

          \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u76ee\u5f55\u3002

          documentFileIsDirectory(path)\n

          \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

          \u8fd4\u56de\uff1a \u5982\u679c\u662f\u76ee\u5f55\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u76ee\u5f55\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

          "},{"location":"qsl4a/storage/documentfile/#documentfiledelete","title":"documentFileDelete()","text":"

          \u5220\u9664\u6587\u4ef6\u6216\u76ee\u5f55\u3002

          documentFileDelete(FileOrTree)\n

          \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

          "},{"location":"qsl4a/storage/documentfile/#documentfilerenameto","title":"documentFileRenameTo()","text":"

          \u91cd\u547d\u540d\u6216\u79fb\u52a8\u6587\u4ef6\u3002

          documentFileRenameTo(Src, Dest)\n

          \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

          "},{"location":"qsl4a/storage/documentfile/#documentfilecopy","title":"documentFileCopy()","text":"

          \u590d\u5236\u6587\u4ef6\u3002

          documentFileCopy(SrcFileOrTree, DestFileOrTree)\n
          "},{"location":"qsl4a/storage/documentfile/#_3","title":"\u6d41\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileinputstream","title":"documentFileInputStream()","text":"

          \u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9\u3002

          documentFileInputStream(srcFile, EncodingFormat=\"\", skip=None, length=None)\n

          \u53c2\u6570\uff1a - srcFile (str): \u6e90\u6587\u4ef6 - EncodingFormat (str): \"UTF-8\"\u3001\"GBK\"\u3001\"Base64\" \u6216\u7a7a\u5b57\u7b26\u4e32\u8868\u793a\u5b57\u8282 - skip (int): \u4ece\u5f00\u5934\u8df3\u8fc7\u7684\u5b57\u8282\u6570 - length (int): \u8bfb\u53d6\u957f\u5ea6

          \u8fd4\u56de\uff1a \u6587\u4ef6\u5185\u5bb9

          "},{"location":"qsl4a/storage/documentfile/#documentfileoutputstream","title":"documentFileOutputStream()","text":"

          \u5199\u5165\u6587\u4ef6\u5185\u5bb9\u3002

          documentFileOutputStream(destFile, src, EncodingFormat=\"\", append=None)\n

          \u53c2\u6570\uff1a - destFile (str): \u76ee\u6807\u6587\u4ef6 - src: \u8981\u5199\u5165\u7684\u6570\u636e - EncodingFormat (str): \u7f16\u7801\u683c\u5f0f - append (bool): \u8ffd\u52a0\u6a21\u5f0f

          "},{"location":"qsl4a/storage/documentfile/#_4","title":"\u6587\u4ef6\u4fe1\u606f","text":""},{"location":"qsl4a/storage/documentfile/#documentfilelength","title":"documentFileLength()","text":"

          \u83b7\u53d6\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\u3002

          documentFileLength(path)\n

          \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

          \u8fd4\u56de\uff1a \u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

          "},{"location":"qsl4a/storage/documentfile/#documentfilelastmodified","title":"documentFileLastModified()","text":"

          \u83b7\u53d6\u6700\u540e\u4fee\u6539\u65f6\u95f4\u3002

          documentFileLastModified(path)\n

          \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

          \u8fd4\u56de\uff1a \u65f6\u95f4\u6233\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

          "},{"location":"qsl4a/storage/documentfile/#documentfilegetstat","title":"documentFileGetStat()","text":"

          \u83b7\u53d6\u5168\u9762\u7684\u6587\u4ef6\u7edf\u8ba1\u4fe1\u606f\u3002

          documentFileGetStat(path)\n

          \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

          \u8fd4\u56de\uff1a \u5305\u542b\u957f\u5ea6\u3001\u6700\u540e\u4fee\u6539\u65f6\u95f4\u548c\u8bfb/\u5199\u6743\u9650\u7684\u5b57\u5178\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

          "},{"location":"qsl4a/storage/documentfile/#uri","title":"URI \u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilegeturi","title":"documentFileGetUri()","text":"

          \u4ece\u8def\u5f84\u83b7\u53d6 URI\u3002

          documentFileGetUri(path, isDirectory=None)\n
          "},{"location":"qsl4a/storage/documentfile/#documentfileshowopen","title":"documentFileShowOpen()","text":"

          \u663e\u793a\u6587\u4ef6\u9009\u62e9\u5668\u3002

          documentFileShowOpen()\n

          \u8fd4\u56de\uff1a \u9009\u62e9\u7684\u6587\u4ef6 URI

          "},{"location":"qsl4a/storage/documentfile/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u76ee\u5f55\ndroid.documentFileMkdir(\"/sdcard/MyFolder\")\n\n# \u5217\u51fa\u6587\u4ef6\nfiles = droid.documentFileListFiles(\"/sdcard\").result\nfor f in files:\n    print(f)\n\n# \u8bfb\u53d6\u6587\u4ef6\ncontent = droid.documentFileInputStream(\n    \"/sdcard/test.txt\",\n    EncodingFormat=\"UTF-8\"\n).result\nprint(content)\n\n# \u5199\u5165\u6587\u4ef6\ndroid.documentFileOutputStream(\n    \"/sdcard/output.txt\",\n    \"Hello World\",\n    EncodingFormat=\"UTF-8\"\n)\n
          "},{"location":"qsl4a/storage/preferences/","title":"\u504f\u597d\u8bbe\u7f6e API","text":"

          \u4f7f\u7528 Android SharedPreferences \u5b58\u50a8\u548c\u68c0\u7d22\u6570\u636e\u3002

          "},{"location":"qsl4a/storage/preferences/#_1","title":"\u504f\u597d\u8bbe\u7f6e\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/preferences/#prefgetvalue","title":"prefGetValue()","text":"

          \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u8bfb\u53d6\u503c\u3002

          prefGetValue(key, filename=None)\n

          \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

          \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c\uff08\u4efb\u610f\u7c7b\u578b\uff09

          "},{"location":"qsl4a/storage/preferences/#prefputvalue","title":"prefPutValue()","text":"

          \u5199\u5165\u503c\u5230\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u3002

          prefPutValue(key, value, filename=None)\n

          \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - value (object): \u8981\u5b58\u50a8\u7684\u503c - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

          "},{"location":"qsl4a/storage/preferences/#prefgetall","title":"prefGetAll()","text":"

          \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\u503c\u3002

          prefGetAll(filename=None)\n

          \u53c2\u6570\uff1a - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

          \u8fd4\u56de\uff1a \u6240\u6709\u504f\u597d\u7684\u6620\u5c04

          "},{"location":"qsl4a/storage/preferences/#prefremovevalue","title":"prefRemoveValue()","text":"

          \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u4e2d\u79fb\u9664\u503c\u3002

          prefRemoveValue(key, filename=None)\n

          \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

          "},{"location":"qsl4a/storage/preferences/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b58\u50a8\u503c\ndroid.prefPutValue(\"username\", \"alice\")\ndroid.prefPutValue(\"score\", 100)\ndroid.prefPutValue(\"enabled\", True)\n\n# \u8bfb\u53d6\u7279\u5b9a\u503c\nusername = droid.prefGetValue(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\nall_prefs = droid.prefGetAll().result\nprint(f\"All prefs: {all_prefs}\")\n\n# \u79fb\u9664\u503c\ndroid.prefRemoveValue(\"score\")\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u6587\u4ef6\u540d\ndroid.prefPutValue(\"token\", \"abc123\", filename=\"auth.prefs\")\ntoken = droid.prefGetValue(\"token\", filename=\"auth.prefs\").result\n
          "},{"location":"qsl4a/system/activityresult/","title":"Activity Result API","text":"

          \u4e3a\u901a\u8fc7 startActivityForResult \u542f\u52a8\u7684\u811a\u672c\u8bbe\u7f6e activity \u7ed3\u679c\u3002

          "},{"location":"qsl4a/system/activityresult/#_1","title":"\u7ed3\u679c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/activityresult/#setresultboolean","title":"setResultBoolean()","text":"

          \u8bbe\u7f6e\u5e03\u5c14\u7ed3\u679c\u3002

          setResultBoolean(resultCode, resultValue)\n

          \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (bool): \u5e03\u5c14\u7ed3\u679c\u503c

          "},{"location":"qsl4a/system/activityresult/#setresultbyte","title":"setResultByte()","text":"

          \u8bbe\u7f6e\u5b57\u8282\u7ed3\u679c\u3002

          setResultByte(resultCode, resultValue)\n

          \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u5b57\u8282\u7ed3\u679c\u503c

          "},{"location":"qsl4a/system/activityresult/#setresultshort","title":"setResultShort()","text":"

          \u8bbe\u7f6e\u77ed\u6574\u6570\u7ed3\u679c\u3002

          setResultShort(resultCode, resultValue)\n

          \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u77ed\u6574\u6570\u7ed3\u679c\u503c

          "},{"location":"qsl4a/system/activityresult/#setresultchar","title":"setResultChar()","text":"

          \u8bbe\u7f6e\u5b57\u7b26\u7ed3\u679c\u3002

          setResultChar(resultCode, resultValue)\n

          \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u7ed3\u679c\u503c

          "},{"location":"qsl4a/system/activityresult/#setresultinteger","title":"setResultInteger()","text":"

          \u8bbe\u7f6e\u6574\u6570\u7ed3\u679c\u3002

          setResultInteger(resultCode, resultValue)\n

          \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u6574\u6570\u7ed3\u679c\u503c

          "},{"location":"qsl4a/system/activityresult/#setresultlong","title":"setResultLong()","text":"

          \u8bbe\u7f6e\u957f\u6574\u6570\u7ed3\u679c\u3002

          setResultLong(resultCode, resultValue)\n

          \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u957f\u6574\u6570\u7ed3\u679c\u503c

          "},{"location":"qsl4a/system/activityresult/#setresultfloat","title":"setResultFloat()","text":"

          \u8bbe\u7f6e\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

          setResultFloat(resultCode, resultValue)\n

          \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u6d6e\u70b9\u6570\u7ed3\u679c\u503c

          "},{"location":"qsl4a/system/activityresult/#setresultdouble","title":"setResultDouble()","text":"

          \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

          setResultDouble(resultCode, resultValue)\n

          \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u503c

          "},{"location":"qsl4a/system/activityresult/#setresultstring","title":"setResultString()","text":"

          \u8bbe\u7f6e\u5b57\u7b26\u4e32\u7ed3\u679c\u3002

          setResultString(resultCode, resultValue)\n

          \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u4e32\u7ed3\u679c\u503c

          "},{"location":"qsl4a/system/activityresult/#setresultbooleanarray","title":"setResultBooleanArray()","text":"

          \u8bbe\u7f6e\u5e03\u5c14\u6570\u7ec4\u7ed3\u679c\u3002

          setResultBooleanArray(resultCode, resultValue)\n

          \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5e03\u5c14\u6570\u7ec4

          "},{"location":"qsl4a/system/activityresult/#setresultbytearray","title":"setResultByteArray()","text":"

          \u8bbe\u7f6e\u5b57\u8282\u6570\u7ec4\u7ed3\u679c\u3002

          setResultByteArray(resultCode, resultValue)\n

          \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u8282\u6570\u7ec4

          "},{"location":"qsl4a/system/activityresult/#setresultshortarray","title":"setResultShortArray()","text":"

          \u8bbe\u7f6e\u77ed\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

          setResultShortArray(resultCode, resultValue)\n

          \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u77ed\u6574\u6570\u6570\u7ec4

          "},{"location":"qsl4a/system/activityresult/#setresultchararray","title":"setResultCharArray()","text":"

          \u8bbe\u7f6e\u5b57\u7b26\u6570\u7ec4\u7ed3\u679c\u3002

          setResultCharArray(resultCode, resultValue)\n

          \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u6570\u7ec4

          "},{"location":"qsl4a/system/activityresult/#setresultintegerarray","title":"setResultIntegerArray()","text":"

          \u8bbe\u7f6e\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

          setResultIntegerArray(resultCode, resultValue)\n

          \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6574\u6570\u6570\u7ec4

          "},{"location":"qsl4a/system/activityresult/#setresultlongarray","title":"setResultLongArray()","text":"

          \u8bbe\u7f6e\u957f\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

          setResultLongArray(resultCode, resultValue)\n

          \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u957f\u6574\u6570\u6570\u7ec4

          "},{"location":"qsl4a/system/activityresult/#setresultfloatarray","title":"setResultFloatArray()","text":"

          \u8bbe\u7f6e\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

          setResultFloatArray(resultCode, resultValue)\n

          \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6d6e\u70b9\u6570\u6570\u7ec4

          "},{"location":"qsl4a/system/activityresult/#setresultdoublearray","title":"setResultDoubleArray()","text":"

          \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

          setResultDoubleArray(resultCode, resultValue)\n

          \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4

          "},{"location":"qsl4a/system/activityresult/#setresultstringarray","title":"setResultStringArray()","text":"

          \u8bbe\u7f6e\u5b57\u7b26\u4e32\u6570\u7ec4\u7ed3\u679c\u3002

          setResultStringArray(resultCode, resultValue)\n

          \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u4e32\u6570\u7ec4

          "},{"location":"qsl4a/system/activityresult/#setresultserializable","title":"setResultSerializable()","text":"

          \u8bbe\u7f6e\u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u3002

          setResultSerializable(resultCode, resultValue)\n

          \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue: \u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u503c

          "},{"location":"qsl4a/system/activityresult/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c activity \u540e\uff0c\u8bbe\u7f6e\u7ed3\u679c\n# \u793a\u4f8b\uff1a\u8fd4\u56de\u6210\u529f\u53ca\u6570\u636e\ndroid.setResultInteger(0, 200)  # RESULT_OK\ndroid.setResultString(0, \"Operation completed successfully\")\n\n# \u8fd4\u56de\u6570\u7ec4\u7ed3\u679c\ndroid.setResultIntegerArray(0, [1, 2, 3, 4, 5])\n
          "},{"location":"qsl4a/system/application/","title":"\u5e94\u7528\u7ba1\u7406","text":"

          \u7ba1\u7406\u5e94\u7528\u7a0b\u5e8f\u3001\u542f\u52a8\u5e94\u7528\u548c\u67e5\u8be2\u7cfb\u7edf\u4fe1\u606f\u3002

          "},{"location":"qsl4a/system/application/#_2","title":"\u5e94\u7528\u7a0b\u5e8f\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getapplicationinfo","title":"getApplicationInfo()","text":"

          \u83b7\u53d6\u5e94\u7528\u4fe1\u606f\u3002

          getApplicationInfo(packageName=None)\n

          \u53c2\u6570\uff1a - packageName (str): \u5305\u540d\uff08None = \u5f53\u524d\u5e94\u7528\uff09

          \u8fd4\u56de\uff1a \u5e94\u7528\u4fe1\u606f\u5b57\u5178

          "},{"location":"qsl4a/system/application/#getinstalledpackages","title":"getInstalledPackages()","text":"

          \u83b7\u53d6\u5df2\u5b89\u88c5\u5305\u5217\u8868\u3002

          getInstalledPackages(flag=4)\n

          \u53c2\u6570\uff1a - flag (int): \u5305\u6807\u5fd7\u8fc7\u6ee4\u5668\uff08\u9ed8\u8ba4\uff1a4\uff09

          \u8fd4\u56de\uff1a \u5df2\u5b89\u88c5\u5305\u5217\u8868

          "},{"location":"qsl4a/system/application/#getrunningpackages","title":"getRunningPackages()","text":"

          \u5217\u51fa\u6b63\u5728\u8fd0\u884c\u7684\u5305\u3002

          getRunningPackages()\n

          \u8fd4\u56de\uff1a \u5305\u540d\u5217\u8868

          "},{"location":"qsl4a/system/application/#getlaunchablepackages","title":"getLaunchablePackages()","text":"

          \u83b7\u53d6\u53ef\u542f\u52a8\u5305\u5217\u8868\u3002

          getLaunchablePackages(needClassName=False)\n

          \u53c2\u6570\uff1a - needClassName (bool): \u5305\u542b\u4e3b activity \u7c7b\u540d\uff08\u9ed8\u8ba4\uff1aFalse\uff09

          \u8fd4\u56de\uff1a \u53ef\u542f\u52a8\u5305\u540d\u5217\u8868\u6216\u5305\u542b\u7c7b\u540d\u7684\u5b57\u5178

          "},{"location":"qsl4a/system/application/#_3","title":"\u5e94\u7528\u63a7\u5236","text":""},{"location":"qsl4a/system/application/#launch","title":"launch()","text":"

          \u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u3002

          launch(classname=None, packagename=None, wait=True)\n

          \u53c2\u6570\uff1a - classname (str): \u4e3b activity \u7c7b\u540d - packagename (str): \u5305\u540d - wait (bool): \u7b49\u5f85\u542f\u52a8\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

          \u8fd4\u56de\uff1a \u542f\u52a8\u7ed3\u679c

          "},{"location":"qsl4a/system/application/#forcestoppackage","title":"forceStopPackage()","text":"

          \u5f3a\u5236\u505c\u6b62\u5e94\u7528\u7a0b\u5e8f\u3002

          forceStopPackage(packageName)\n

          \u53c2\u6570\uff1a - packageName (str): \u8981\u505c\u6b62\u7684\u5305\u540d

          "},{"location":"qsl4a/system/application/#_4","title":"\u7248\u672c\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getpackageversion","title":"getPackageVersion()","text":"

          \u83b7\u53d6\u5e94\u7528\u7248\u672c\u540d\u79f0\u3002

          getPackageVersion(packageName)\n

          \u8fd4\u56de\uff1a \u7248\u672c\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"3.2.1\"\uff09

          "},{"location":"qsl4a/system/application/#getpackageversioncode","title":"getPackageVersionCode()","text":"

          \u83b7\u53d6\u5e94\u7528\u7248\u672c\u4ee3\u7801\u3002

          getPackageVersionCode(packageName)\n

          \u8fd4\u56de\uff1a \u7248\u672c\u4ee3\u7801\u6574\u6570

          "},{"location":"qsl4a/system/application/#getconstants","title":"getConstants()","text":"

          \u83b7\u53d6\u7c7b\u5e38\u91cf\u3002

          getConstants(classname)\n

          \u53c2\u6570\uff1a - classname (str): \u5b8c\u6574\u7c7b\u540d

          \u8fd4\u56de\uff1a \u5e38\u91cf\u540d\u548c\u503c\u7684\u5b57\u5178

          "},{"location":"qsl4a/system/application/#_5","title":"\u7cfb\u7edf\u529f\u80fd","text":""},{"location":"qsl4a/system/application/#backgroundprotect","title":"backgroundProtect()","text":"

          \u542f\u7528\u6216\u7981\u7528\u5e94\u7528\u7684\u540e\u53f0\u4fdd\u62a4\u3002

          backgroundProtect(enabled=True)\n

          \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\u4fdd\u62a4\uff0cFalse \u7981\u7528

          "},{"location":"qsl4a/system/application/#createscriptshortcut","title":"createScriptShortCut()","text":"

          \u4e3a\u811a\u672c\u521b\u5efa\u4e3b\u5c4f\u5e55\u5feb\u6377\u65b9\u5f0f\u3002

          createScriptShortCut(scriptPath, label=None, iconPath=None, scriptArg=None)\n

          \u53c2\u6570\uff1a - scriptPath (str): Python \u811a\u672c\u8def\u5f84 - label (str, optional): \u5feb\u6377\u65b9\u5f0f\u6807\u7b7e - iconPath (str, optional): \u56fe\u6807\u56fe\u50cf\u8def\u5f84 - scriptArg (str, optional): \u4f20\u9012\u7ed9\u811a\u672c\u7684\u53c2\u6570

          "},{"location":"qsl4a/system/application/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getandroidid","title":"getAndroidID()","text":"

          \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

          getAndroidID()\n

          \u8fd4\u56de\uff1a \u552f\u4e00\u7684 Android \u8bbe\u5907 ID \u5b57\u7b26\u4e32

          "},{"location":"qsl4a/system/application/#getsysinfo","title":"getSysInfo()","text":"

          \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\u3002

          getSysInfo()\n

          \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

          "},{"location":"qsl4a/system/application/#getlocale","title":"getLocale()","text":"

          \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u3002

          getLocale()\n

          \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

          "},{"location":"qsl4a/system/application/#getharmonyosinformation","title":"getHarmonyOsInformation()","text":"

          \u5982\u679c\u5728 HarmonyOS \u4e0a\u8fd0\u884c\uff0c\u83b7\u53d6 HarmonyOS \u4fe1\u606f\u3002

          getHarmonyOsInformation()\n

          \u8fd4\u56de\uff1a HarmonyOS \u7248\u672c\u4fe1\u606f\u6216 None

          "},{"location":"qsl4a/system/application/#isexternalstoragemanager","title":"isExternalStorageManager()","text":"

          \u68c0\u67e5\u5e94\u7528\u662f\u5426\u6709\u5916\u90e8\u5b58\u50a8\u7ba1\u7406\u5668\u6743\u9650\u3002

          isExternalStorageManager()\n

          \u8fd4\u56de\uff1a \u5982\u679c\u6709\u6743\u9650\u5219\u4e3a True

          "},{"location":"qsl4a/system/application/#_7","title":"\u5185\u5b58\u548c\u663e\u793a","text":""},{"location":"qsl4a/system/application/#getmemoryinfo","title":"getMemoryInfo()","text":"

          \u83b7\u53d6\u5185\u5b58\u4fe1\u606f\u3002

          getMemoryInfo()\n

          \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

          "},{"location":"qsl4a/system/application/#getscreeninfo","title":"getScreenInfo()","text":"

          \u83b7\u53d6\u5c4f\u5e55\u4fe1\u606f\u3002

          getScreenInfo()\n

          \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

          "},{"location":"qsl4a/system/application/#_8","title":"\u6743\u9650","text":""},{"location":"qsl4a/system/application/#checkpermissions","title":"checkPermissions()","text":"

          \u68c0\u67e5\u5f53\u524d\u5e94\u7528\u6743\u9650\u3002

          checkPermissions()\n

          \u8fd4\u56de\uff1a \u6743\u9650\u53ca\u5176\u72b6\u6001\u7684\u5b57\u5178

          "},{"location":"qsl4a/system/application/#requestpermissions","title":"requestPermissions()","text":"

          \u5411\u7528\u6237\u8bf7\u6c42\u6743\u9650\u3002

          requestPermissions(permissions=None)\n

          \u53c2\u6570\uff1a - permissions (list, optional): \u8981\u8bf7\u6c42\u7684\u6743\u9650\u5217\u8868\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8bf7\u6c42\u6240\u6709\u9700\u8981\u7684\u6743\u9650\u3002

          \u8fd4\u56de\uff1a \u6743\u9650\u8bf7\u6c42\u7ed3\u679c

          "},{"location":"qsl4a/system/application/#_9","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/system/application/#showscreenlock","title":"showScreenLock()","text":"

          \u663e\u793a\u5c4f\u5e55\u9501\u5b9a\uff08PIN/\u56fe\u6848/\u5bc6\u7801\u8f93\u5165\uff09\u3002

          showScreenLock()\n
          "},{"location":"qsl4a/system/application/#_10","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\ninfo = droid.getSysInfo().result\nprint(f\"System: {info}\")\n\n# \u83b7\u53d6\u5e94\u7528\u7248\u672c\nversion = droid.getPackageVersion(\"org.qpython.qpy\").result\nprint(f\"QPython version: {version}\")\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u5e94\u7528\napps = droid.getInstalledPackages().result\nprint(f\"Installed apps: {len(apps)}\")\n\n# \u542f\u52a8\u5e94\u7528\ndroid.launch(packagename=\"com.android.settings\")\n\n# \u68c0\u67e5\u6743\u9650\nperms = droid.checkPermissions().result\nprint(f\"Permissions: {perms}\")\n\n# \u8bf7\u6c42\u5b58\u50a8\u6743\u9650\ndroid.requestPermissions([\"android.permission.READ_EXTERNAL_STORAGE\"])\n\n# \u521b\u5efa\u5feb\u6377\u65b9\u5f0f\ndroid.createScriptShortCut(\n    \"/sdcard/my_script.py\",\n    label=\"My Script\",\n    iconPath=\"/sdcard/icon.png\"\n)\n
          "},{"location":"qsl4a/system/battery/","title":"\u7535\u6c60 API","text":"

          \u76d1\u63a7\u8bbe\u5907\u7535\u6c60\u72b6\u6001\u548c\u5065\u5eb7\u72b6\u51b5\u3002

          "},{"location":"qsl4a/system/battery/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/battery/#readbatterydata","title":"readBatteryData()","text":"

          \u83b7\u53d6\u5b8c\u6574\u7684\u7535\u6c60\u4fe1\u606f\u3002

          readBatteryData()\n

          \u8fd4\u56de\uff1a \u5305\u542b\u7535\u6c60\u6570\u636e\u7684\u5b57\u5178

          "},{"location":"qsl4a/system/battery/#batterystartmonitoring","title":"batteryStartMonitoring()","text":"

          \u5f00\u59cb\u7535\u6c60\u76d1\u63a7\u3002

          batteryStartMonitoring()\n
          "},{"location":"qsl4a/system/battery/#batterystopmonitoring","title":"batteryStopMonitoring()","text":"

          \u505c\u6b62\u7535\u6c60\u76d1\u63a7\u3002

          batteryStopMonitoring()\n
          "},{"location":"qsl4a/system/battery/#batterygetlevel","title":"batteryGetLevel()","text":"

          \u83b7\u53d6\u7535\u6c60\u767e\u5206\u6bd4\u3002

          batteryGetLevel()\n

          \u8fd4\u56de\uff1a \u6574\u6570\uff080-100\uff09

          "},{"location":"qsl4a/system/battery/#batterygetstatus","title":"batteryGetStatus()","text":"

          \u83b7\u53d6\u5145\u7535\u72b6\u6001\u3002

          batteryGetStatus()\n

          \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u5145\u7535\u4e2d - 3: \u653e\u7535\u4e2d - 4: \u672a\u5145\u7535 - 5: \u5df2\u5145\u6ee1

          "},{"location":"qsl4a/system/battery/#batterygetplugtype","title":"batteryGetPlugType()","text":"

          \u83b7\u53d6\u7535\u6e90\u7c7b\u578b\u3002

          batteryGetPlugType()\n

          \u8fd4\u56de\uff1a - -1: \u672a\u77e5 - 0: \u672a\u63d2\u7535 - 1: AC \u5145\u7535\u5668 - 2: USB \u7aef\u53e3

          "},{"location":"qsl4a/system/battery/#batterygethealth","title":"batteryGetHealth()","text":"

          \u83b7\u53d6\u7535\u6c60\u5065\u5eb7\u72b6\u51b5\u3002

          batteryGetHealth()\n

          \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u826f\u597d - 3: \u8fc7\u70ed - 4: \u635f\u574f - 5: \u8fc7\u538b - 6: \u672a\u6307\u5b9a\u7684\u6545\u969c

          "},{"location":"qsl4a/system/battery/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\nlevel = droid.batteryGetLevel().result\nprint(f\"Battery: {level}%\")\n
          "},{"location":"qsl4a/system/qpyinterface/","title":"QPython \u63a5\u53e3 API","text":"

          \u4ece\u5176\u4ed6\u5e94\u7528\u6267\u884c QPython \u811a\u672c\u548c\u7ba1\u7406\u5171\u4eab\u53d8\u91cf\u3002

          "},{"location":"qsl4a/system/qpyinterface/#_1","title":"\u811a\u672c\u6267\u884c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/qpyinterface/#executeqpy","title":"executeQPy()","text":"

          \u6267\u884c QPython \u811a\u672c\u3002

          executeQPy(path=\"\", arg=None)\n

          \u53c2\u6570\uff1a - path (str): \u811a\u672c\u6587\u4ef6\u8def\u5f84 - arg (str, optional): \u547d\u4ee4\u884c\u53c2\u6570

          \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

          "},{"location":"qsl4a/system/qpyinterface/#executeqpyassrv","title":"executeQPyAsSrv()","text":"

          \u4f5c\u4e3a\u670d\u52a1\u6267\u884c QPython \u811a\u672c\u3002

          executeQPyAsSrv(path=None)\n

          \u53c2\u6570\uff1a - path (str, optional): \u811a\u672c\u6587\u4ef6\u8def\u5f84

          \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

          "},{"location":"qsl4a/system/qpyinterface/#executeqpycode","title":"executeQPyCode()","text":"

          \u76f4\u63a5\u6267\u884c Python \u4ee3\u7801\u3002

          executeQPyCode(code=None)\n

          \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

          \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

          "},{"location":"qsl4a/system/qpyinterface/#executeqpycodeassrv","title":"executeQPyCodeAsSrv()","text":"

          \u4f5c\u4e3a\u670d\u52a1\u6267\u884c Python \u4ee3\u7801\u3002

          executeQPyCodeAsSrv(code=None)\n

          \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

          \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

          "},{"location":"qsl4a/system/qpyinterface/#_2","title":"\u5171\u4eab\u53d8\u91cf","text":"

          \u5171\u4eab\u53d8\u91cf\u5141\u8bb8 QPython \u4e0e\u5176\u4ed6\u5e94\u7528\u4e4b\u95f4\u8fdb\u884c\u901a\u4fe1\u3002

          "},{"location":"qsl4a/system/qpyinterface/#sharedvariableset","title":"sharedVariableSet()","text":"

          \u8bbe\u7f6e Java \u5171\u4eab\u53d8\u91cf\u3002

          sharedVariableSet(key, value)\n

          \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d - value (str): \u53d8\u91cf\u503c

          \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

          "},{"location":"qsl4a/system/qpyinterface/#sharedvariableget","title":"sharedVariableGet()","text":"

          \u83b7\u53d6 Java \u5171\u4eab\u53d8\u91cf\u3002

          sharedVariableGet(key)\n

          \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d

          \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

          "},{"location":"qsl4a/system/qpyinterface/#sharedvariableremove","title":"sharedVariableRemove()","text":"

          \u79fb\u9664 Java \u5171\u4eab\u53d8\u91cf\u3002

          sharedVariableRemove(key)\n

          \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u53d8\u91cf\u540d

          \u8fd4\u56de\uff1a \u88ab\u79fb\u9664\u7684\u503c

          "},{"location":"qsl4a/system/qpyinterface/#getlastlog","title":"getLastLog()","text":"

          \u83b7\u53d6 QPython \u7684\u6700\u540e\u65e5\u5fd7\u8f93\u51fa\u3002

          getLastLog()\n

          \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u65e5\u5fd7\u5185\u5bb9

          "},{"location":"qsl4a/system/qpyinterface/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c\u811a\u672c\ndroid.executeQPy(\"/sdcard/my_script.py\", arg=\"test\")\n\n# \u76f4\u63a5\u6267\u884c\u4ee3\u7801\ncode = \"print('Hello from QPython!')\"\ndroid.executeQPyCode(code)\n\n# \u4f7f\u7528\u5171\u4eab\u53d8\u91cf\ndroid.sharedVariableSet(\"username\", \"alice\")\nusername = droid.sharedVariableGet(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u79fb\u9664\u53d8\u91cf\ndroid.sharedVariableRemove(\"username\")\n\n# \u83b7\u53d6\u6700\u8fd1\u65e5\u5fd7\nlog = droid.getLastLog().result\nprint(f\"Log: {log}\")\n
          "},{"location":"qsl4a/system/sensors/","title":"\u4f20\u611f\u5668 API","text":"

          \u8bbf\u95ee\u8bbe\u5907\u4f20\u611f\u5668\uff0c\u5305\u62ec\u52a0\u901f\u5ea6\u8ba1\u3001\u9640\u87ba\u4eea\u3001\u78c1\u529b\u8ba1\u7b49\u3002

          "},{"location":"qsl4a/system/sensors/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/sensors/#startsensingtimed","title":"startSensingTimed()","text":"

          \u5f00\u59cb\u4f20\u611f\u5668\u76d1\u63a7\u5e76\u8bbe\u7f6e\u65f6\u95f4\u95f4\u9694\u3002

          startSensingTimed(sensorNumber, delayTime)\n

          \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID\uff08\u901a\u5e38\u4e3a 1-3\uff09 - delayTime (int): \u8bfb\u53d6\u4e4b\u95f4\u7684\u5ef6\u8fdf\uff08\u6beb\u79d2\uff09

          "},{"location":"qsl4a/system/sensors/#startsensingthreshold","title":"startSensingThreshold()","text":"

          \u5f00\u59cb\u5e26\u9608\u503c\u89e6\u53d1\u7684\u4f20\u611f\u5668\u76d1\u63a7\u3002

          startSensingThreshold(sensorNumber, threshold, axis)\n

          \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID - threshold (float): \u89e6\u53d1\u9608\u503c - axis (int): \u8981\u76d1\u63a7\u7684\u8f74\uff080=X\uff0c1=Y\uff0c2=Z\uff09

          "},{"location":"qsl4a/system/sensors/#stopsensing","title":"stopSensing()","text":"

          \u505c\u6b62\u6240\u6709\u4f20\u611f\u5668\u76d1\u63a7\u3002

          stopSensing()\n
          "},{"location":"qsl4a/system/sensors/#readsensors","title":"readSensors()","text":"

          \u8bfb\u53d6\u5f53\u524d\u4f20\u611f\u5668\u6570\u636e\u3002

          readSensors()\n

          \u8fd4\u56de\uff1a \u4f20\u611f\u5668\u6570\u636e\u5b57\u5178

          "},{"location":"qsl4a/system/sensors/#sensorsreadaccelerometer","title":"sensorsReadAccelerometer()","text":"

          \u8bfb\u53d6\u52a0\u901f\u5ea6\u8ba1\u503c\u3002

          sensorsReadAccelerometer()\n

          \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d m/s\u00b2

          "},{"location":"qsl4a/system/sensors/#sensorsreadgyroscope","title":"sensorsReadGyroscope()","text":"

          \u8bfb\u53d6\u9640\u87ba\u4eea\u503c\u3002

          sensorsReadGyroscope()\n

          \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d rad/s

          "},{"location":"qsl4a/system/sensors/#sensorsreadmagnetometer","title":"sensorsReadMagnetometer()","text":"

          \u8bfb\u53d6\u78c1\u573a\u503c\u3002

          sensorsReadMagnetometer()\n

          \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d \u03bcT

          "},{"location":"qsl4a/system/sensors/#sensorsreadorientation","title":"sensorsReadOrientation()","text":"

          \u8bfb\u53d6\u8bbe\u5907\u65b9\u5411\u3002

          sensorsReadOrientation()\n

          \u8fd4\u56de\uff1a \u5217\u8868 [azimuth, pitch, roll]\uff0c\u5355\u4f4d\u5ea6

          "},{"location":"qsl4a/system/sensors/#sensorsgetlight","title":"sensorsGetLight()","text":"

          \u8bfb\u53d6\u5149\u4f20\u611f\u5668\u503c\u3002

          sensorsGetLight()\n

          \u8fd4\u56de\uff1a \u5149\u7ea7\u522b\uff08lux\uff09

          "},{"location":"qsl4a/system/sensors/#sensorsgetstepcounter","title":"sensorsGetStepCounter()","text":"

          \u8bfb\u53d6\u6b65\u8ba1\u6570\u5668\u3002

          sensorsGetStepCounter()\n

          \u8fd4\u56de\uff1a \u6b65\u6570

          "},{"location":"qsl4a/system/sensors/#sensorsgetaccuracy","title":"sensorsGetAccuracy()","text":"

          \u83b7\u53d6\u5f53\u524d\u4f20\u611f\u5668\u7cbe\u5ea6\u3002

          sensorsGetAccuracy()\n

          \u8fd4\u56de\uff1a \u7cbe\u5ea6\u503c\uff080-3\uff1aUNRELIABLE\u3001ACCURACY_LOW\u3001ACCURACY_MEDIUM\u3001ACCURACY_HIGH\uff09

          "},{"location":"qsl4a/system/sensors/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u8bfb\u53d6\u4f20\u611f\u5668 10 \u6b21\nfor i in range(10):\n    accel = droid.sensorsReadAccelerometer().result\n    print(f\"Accel: X={accel[0]:.2f}, Y={accel[1]:.2f}, Z={accel[2]:.2f}\")\n    time.sleep(0.5)\n\ndroid.stopSensing()\n
          "},{"location":"qsl4a/system/settings/","title":"\u8bbe\u7f6e API","text":"

          \u63a7\u5236\u7cfb\u7edf\u8bbe\u7f6e\uff0c\u5305\u62ec\u5c4f\u5e55\u3001\u58f0\u97f3\u548c\u7f51\u7edc\u8bbe\u7f6e\u3002

          "},{"location":"qsl4a/system/settings/#_1","title":"\u5c4f\u5e55\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#setscreentimeout","title":"setScreenTimeout()","text":"

          \u8bbe\u7f6e\u5c4f\u5e55\u8d85\u65f6\u503c\u3002

          setScreenTimeout(value)\n

          \u53c2\u6570\uff1a - value (int): \u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

          \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u8d85\u65f6\u503c

          "},{"location":"qsl4a/system/settings/#getscreentimeout","title":"getScreenTimeout()","text":"

          \u83b7\u53d6\u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u3002

          getScreenTimeout()\n

          \u8fd4\u56de\uff1a \u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

          "},{"location":"qsl4a/system/settings/#getscreenbrightness","title":"getScreenBrightness()","text":"

          \u83b7\u53d6\u5c4f\u5e55\u4eae\u5ea6\u503c\u3002

          getScreenBrightness()\n

          \u8fd4\u56de\uff1a \u4eae\u5ea6\u503c\uff080-255\uff09

          "},{"location":"qsl4a/system/settings/#setscreenbrightness","title":"setScreenBrightness()","text":"

          \u8bbe\u7f6e\u5c4f\u5e55\u4eae\u5ea6\u3002

          setScreenBrightness(value=None)\n

          \u53c2\u6570\uff1a - value (int, optional): \u4eae\u5ea6\u503c\uff080-255\uff09\uff0c\u6216 None \u8868\u793a\u81ea\u52a8

          \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u4eae\u5ea6\u503c

          "},{"location":"qsl4a/system/settings/#checkscreenon","title":"checkScreenOn()","text":"

          \u68c0\u67e5\u5c4f\u5e55\u662f\u5426\u4eae\u7740\u3002

          checkScreenOn()\n

          \u8fd4\u56de\uff1a \u5982\u679c\u5c4f\u5e55\u4eae\u7740\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

          "},{"location":"qsl4a/system/settings/#_2","title":"\u98de\u884c\u6a21\u5f0f","text":""},{"location":"qsl4a/system/settings/#checkairplanemode","title":"checkAirplaneMode()","text":"

          \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\u662f\u5426\u542f\u7528\u3002

          checkAirplaneMode()\n

          \u8fd4\u56de\uff1a \u5982\u679c\u98de\u884c\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

          "},{"location":"qsl4a/system/settings/#_3","title":"\u94c3\u58f0\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#checkringersilentmode","title":"checkRingerSilentMode()","text":"

          \u68c0\u67e5\u94c3\u58f0\u662f\u5426\u5904\u4e8e\u9759\u97f3\u6a21\u5f0f\u3002

          checkRingerSilentMode()\n

          \u8fd4\u56de\uff1a \u5982\u679c\u9759\u97f3\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

          "},{"location":"qsl4a/system/settings/#toggleringersilentmode","title":"toggleRingerSilentMode()","text":"

          \u5207\u6362\u94c3\u58f0\u9759\u97f3\u6a21\u5f0f\u3002

          toggleRingerSilentMode(enabled=None)\n

          \u53c2\u6570\uff1a - enabled (bool, optional): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

          \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

          "},{"location":"qsl4a/system/settings/#togglevibratemode","title":"toggleVibrateMode()","text":"

          \u5207\u6362\u632f\u52a8\u6a21\u5f0f\u3002

          toggleVibrateMode(enabled=None, ringer=None)\n

          \u53c2\u6570\uff1a - enabled (bool, optional): \u5207\u6362\u632f\u52a8\u5f00/\u5173 - ringer (bool, optional): \u5e94\u7528\u4e8e\u94c3\u58f0\u6a21\u5f0f

          \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

          "},{"location":"qsl4a/system/settings/#getvibratemode","title":"getVibrateMode()","text":"

          \u83b7\u53d6\u632f\u52a8\u6a21\u5f0f\u8bbe\u7f6e\u3002

          getVibrateMode(ringer=None)\n

          \u53c2\u6570\uff1a - ringer (bool, optional): \u68c0\u67e5\u94c3\u58f0\u632f\u52a8\u6a21\u5f0f

          \u8fd4\u56de\uff1a \u5982\u679c\u632f\u52a8\u5df2\u542f\u7528\u5219\u4e3a True

          "},{"location":"qsl4a/system/settings/#_4","title":"\u97f3\u91cf\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#getringervolume","title":"getRingerVolume()","text":"

          \u83b7\u53d6\u5f53\u524d\u94c3\u58f0\u97f3\u91cf\u3002

          getRingerVolume()\n

          \u8fd4\u56de\uff1a \u94c3\u58f0\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-7\uff09

          "},{"location":"qsl4a/system/settings/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

          \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

          getMaxRingerVolume()\n

          \u8fd4\u56de\uff1a \u6700\u5927\u94c3\u58f0\u97f3\u91cf

          "},{"location":"qsl4a/system/settings/#setringervolume","title":"setRingerVolume()","text":"

          \u8bbe\u7f6e\u94c3\u58f0\u97f3\u91cf\u3002

          setRingerVolume(volume)\n

          \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

          "},{"location":"qsl4a/system/settings/#getmediavolume","title":"getMediaVolume()","text":"

          \u83b7\u53d6\u5f53\u524d\u5a92\u4f53\u97f3\u91cf\u3002

          getMediaVolume()\n

          \u8fd4\u56de\uff1a \u5a92\u4f53\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-15\uff09

          "},{"location":"qsl4a/system/settings/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

          \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

          getMaxMediaVolume()\n

          \u8fd4\u56de\uff1a \u6700\u5927\u5a92\u4f53\u97f3\u91cf

          "},{"location":"qsl4a/system/settings/#setmediavolume","title":"setMediaVolume()","text":"

          \u8bbe\u7f6e\u5a92\u4f53\u97f3\u91cf\u3002

          setMediaVolume(volume)\n

          \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

          "},{"location":"qsl4a/system/settings/#_5","title":"\u7cfb\u7edf\u4fe1\u606f","text":""},{"location":"qsl4a/system/settings/#elapsedrealtimenanos","title":"elapsedRealtimeNanos()","text":"

          \u83b7\u53d6\u81ea\u7cfb\u7edf\u542f\u52a8\u4ee5\u6765\u7684\u7eb3\u79d2\u6570\u3002

          elapsedRealtimeNanos()\n

          \u8fd4\u56de\uff1a \u7eb3\u79d2\u6570\uff08\u53ef\u7528\u4e8e\u8ba1\u65f6\uff09

          "},{"location":"qsl4a/system/settings/#gettrafficstats","title":"getTrafficStats()","text":"

          \u83b7\u53d6\u7f51\u7edc\u6d41\u91cf\u7edf\u8ba1\u3002

          getTrafficStats(flags=7)\n

          \u53c2\u6570\uff1a - flags (int): \u8981\u68c0\u7d22\u7684\u7edf\u8ba1\uff08\u9ed8\u8ba4\uff1a7 = \u5168\u90e8\uff09

          \u8fd4\u56de\uff1a \u5305\u542b\u53d1\u9001/\u63a5\u6536\u5b57\u8282\u7684\u5b57\u5178

          "},{"location":"qsl4a/system/settings/#getapptxbytes","title":"getAppTxBytes()","text":"

          \u83b7\u53d6 QPython \u5e94\u7528\u7684\u53d1\u9001\u5b57\u8282\u3002

          getAppTxBytes(packageName)\n

          \u53c2\u6570\uff1a - packageName (str): \u5305\u540d

          \u8fd4\u56de\uff1a \u5305\u542b tx/rx \u5b57\u8282\u7684\u5b57\u5178

          "},{"location":"qsl4a/system/settings/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5c4f\u5e55\u8bbe\u7f6e\ncurrent_timeout = droid.getScreenTimeout().result\nprint(f\"Current timeout: {current_timeout}s\")\ndroid.setScreenTimeout(30)\n\n# \u68c0\u67e5\u5c4f\u5e55\nif droid.checkScreenOn().result:\n    print(\"Screen is on\")\n\n# \u97f3\u91cf\u63a7\u5236\nmedia_vol = droid.getMediaVolume().result\nprint(f\"Media volume: {media_vol}\")\ndroid.setMediaVolume(10)\n\n# \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\nif droid.checkAirplaneMode().result:\n    print(\"Airplane mode is on\")\n
          "},{"location":"qsl4a/system/sysinfo/","title":"\u7cfb\u7edf\u4fe1\u606f","text":"

          \u68c0\u7d22\u8bbe\u5907\u548c\u7cfb\u7edf\u4fe1\u606f\u3002

          "},{"location":"qsl4a/system/sysinfo/#_2","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/sysinfo/#getandroidid","title":"getAndroidID()","text":"

          \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

          getAndroidID()\n

          \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

          "},{"location":"qsl4a/system/sysinfo/#getsysinfo","title":"getSysInfo()","text":"

          \u83b7\u53d6\u7efc\u5408\u7cfb\u7edf\u4fe1\u606f\u3002

          getSysInfo()\n

          \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

          "},{"location":"qsl4a/system/sysinfo/#getlocale","title":"getLocale()","text":"

          \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u8bbe\u7f6e\u3002

          getLocale()\n

          \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

          "},{"location":"qsl4a/system/sysinfo/#_3","title":"\u5185\u5b58","text":""},{"location":"qsl4a/system/sysinfo/#getmemoryinfo","title":"getMemoryInfo()","text":"

          \u83b7\u53d6 RAM \u4fe1\u606f\u3002

          getMemoryInfo()\n

          \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

          "},{"location":"qsl4a/system/sysinfo/#_4","title":"\u663e\u793a","text":""},{"location":"qsl4a/system/sysinfo/#getscreeninfo","title":"getScreenInfo()","text":"

          \u83b7\u53d6\u663e\u793a\u4fe1\u606f\u3002

          getScreenInfo()\n

          \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

          "},{"location":"qsl4a/system/sysinfo/#_5","title":"\u6807\u8bc6\u7b26","text":""},{"location":"qsl4a/system/sysinfo/#getimei","title":"getImei()","text":"

          \u83b7\u53d6\u8bbe\u5907 IMEI\u3002

          getImei(slotIndex=None)\n
          "},{"location":"qsl4a/system/sysinfo/#getmeid","title":"getMeid()","text":"

          \u83b7\u53d6\u8bbe\u5907 MEID\u3002

          getMeid(slotIndex=None)\n
          "},{"location":"qsl4a/system/sysinfo/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u8bbe\u5907 ID\nandroid_id = droid.getAndroidID().result\nprint(f\"Android ID: {android_id}\")\n\n# \u5c4f\u5e55\u4fe1\u606f\nscreen = droid.getScreenInfo().result\nprint(f\"Screen: {screen['width']}x{screen['height']}\")\n\n# \u5185\u5b58\nmemory = droid.getMemoryInfo().result\nprint(f\"Memory: {memory}\")\n
          "},{"location":"qsl4a/system/wakelock/","title":"WakeLock API","text":"

          \u63a7\u5236\u8bbe\u5907\u5524\u9192\u9501\u4ee5\u4fdd\u6301 CPU \u6216\u5c4f\u5e55\u5f00\u542f\u3002

          "},{"location":"qsl4a/system/wakelock/#wake-lock","title":"Wake Lock \u7c7b\u578b","text":"

          QSL4A \u63d0\u4f9b\u4e0d\u540c\u7c7b\u578b\u7684\u5524\u9192\u9501\uff1a

          \u7c7b\u578b \u63cf\u8ff0 Full CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae Partial \u4ec5 CPU \u5f00\u542f Bright CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae Dim CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697"},{"location":"qsl4a/system/wakelock/#wake-lock_1","title":"Wake Lock \u65b9\u6cd5","text":""},{"location":"qsl4a/system/wakelock/#wakelockacquirefull","title":"wakeLockAcquireFull()","text":"

          \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae\uff09\u3002

          wakeLockAcquireFull()\n
          "},{"location":"qsl4a/system/wakelock/#wakelockacquirepartial","title":"wakeLockAcquirePartial()","text":"

          \u83b7\u53d6\u90e8\u5206\u5524\u9192\u9501\uff08\u4ec5 CPU \u5f00\u542f\uff09\u3002

          wakeLockAcquirePartial()\n
          "},{"location":"qsl4a/system/wakelock/#wakelockacquirebright","title":"wakeLockAcquireBright()","text":"

          \u83b7\u53d6\u660e\u4eae\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff09\u3002

          wakeLockAcquireBright()\n
          "},{"location":"qsl4a/system/wakelock/#wakelockacquiredim","title":"wakeLockAcquireDim()","text":"

          \u83b7\u53d6\u6697\u6de1\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697\uff09\u3002

          wakeLockAcquireDim()\n
          "},{"location":"qsl4a/system/wakelock/#wakelockrelease","title":"wakeLockRelease()","text":"

          \u91ca\u653e\u5524\u9192\u9501\u3002

          wakeLockRelease()\n
          "},{"location":"qsl4a/system/wakelock/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\ndroid.wakeLockAcquireFull()\n\n# \u5728\u4fdd\u6301\u5c4f\u5e55\u5f00\u542f\u65f6\u6267\u884c\u91cd\u8981\u5de5\u4f5c\nprint(\"Screen will stay on\")\ntime.sleep(10)\n\n# \u5b8c\u6210\u540e\u91ca\u653e\ndroid.wakeLockRelease()\n\n# \u6216\u4f7f\u7528\u90e8\u5206\u9501\u8fdb\u884c\u540e\u53f0\u4efb\u52a1\ndroid.wakeLockAcquirePartial()\n# \u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\uff0cCPU \u4ecd\u4fdd\u6301\u5f00\u542f\ntime.sleep(30)\ndroid.wakeLockRelease()\n

          \u6ce8\u610f\uff1a \u8bb0\u4f4f\u5728\u4e0d\u9700\u8981\u65f6\u91ca\u653e\u5524\u9192\u9501\u4ee5\u8282\u7701\u7535\u6c60\u3002

          "},{"location":"qsl4a/ui/accessibility/","title":"\u65e0\u969c\u788d\u670d\u52a1","text":"

          \u65e0\u969c\u788d\u670d\u52a1\u5141\u8bb8\u81ea\u52a8\u5316 UI \u4ea4\u4e92\uff0c\u5982\u70b9\u51fb\u3001\u6ed1\u52a8\u548c\u7cfb\u7edf\u64cd\u4f5c\u3002

          "},{"location":"qsl4a/ui/accessibility/#_2","title":"\u670d\u52a1\u63a7\u5236","text":""},{"location":"qsl4a/ui/accessibility/#accessibilitystartservice","title":"accessibilityStartService()","text":"

          \u542f\u52a8\u65e0\u969c\u788d\u670d\u52a1\u3002

          accessibilityStartService()\n

          \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

          "},{"location":"qsl4a/ui/accessibility/#accessibilityserviceenabled","title":"accessibilityServiceEnabled()","text":"

          \u68c0\u67e5\u65e0\u969c\u788d\u670d\u52a1\u662f\u5426\u5df2\u542f\u7528\u3002

          accessibilityServiceEnabled()\n

          \u8fd4\u56de\uff1a True \u6216 False

          "},{"location":"qsl4a/ui/accessibility/#_3","title":"\u5c4f\u5e55\u4ea4\u4e92","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityclick","title":"accessibilityClick()","text":"

          \u5728\u5c4f\u5e55\u5750\u6807\u5904\u70b9\u51fb\u3002

          accessibilityClick(x=0, y=0, t=50)\n

          \u53c2\u6570\uff1a - x (int/float): X \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - y (int/float): Y \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - t (int): \u6309\u4f4f\u65f6\u957f\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a50\uff09

          "},{"location":"qsl4a/ui/accessibility/#accessibilityslide","title":"accessibilitySlide()","text":"

          \u591a\u70b9\u6ed1\u52a8\u624b\u52bf\u3002

          accessibilitySlide(XnYn=None, t=None)\n

          \u53c2\u6570\uff1a - XnYn (list): \u5750\u6807 [X1, Y1, X2, Y2, ... Xn, Yn] - t (int): \u6ed1\u52a8\u65f6\u957f\uff08\u9ed8\u8ba4\uff1a50*n \u6beb\u79d2\uff09

          "},{"location":"qsl4a/ui/accessibility/#_4","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityaction","title":"accessibilityAction()","text":"

          \u6309\u4ee3\u7801\u6267\u884c\u7cfb\u7edf\u64cd\u4f5c\u3002

          accessibilityAction(actionCode)\n

          \u64cd\u4f5c\u4ee3\u7801\uff1a | \u4ee3\u7801 | \u5e38\u91cf | \u63cf\u8ff0 | |------|----------|-------------| | 1 | BACK | \u8fd4\u56de\u6309\u94ae | | 2 | HOME | \u4e3b\u5c4f\u5e55\u6309\u94ae | | 3 | RECENTS | \u6700\u8fd1\u5e94\u7528 | | 4 | NOTIFICATIONS | \u6253\u5f00\u901a\u77e5 | | 5 | QUICK_SETTINGS | \u6253\u5f00\u5feb\u901f\u8bbe\u7f6e | | 6 | POWER_DIALOG | \u7535\u6e90\u83dc\u5355 | | 7 | TOGGLE_SPLIT_SCREEN | \u5206\u5c4f | | 8 | LOCK_SCREEN | \u9501\u5c4f | | 9 | TAKE_SCREENSHOT | \u622a\u56fe | | 10 | KEYCODE_HEADSETHOOK | \u8033\u673a\u6302\u94a9 | | 11-14 | ACCESSIBILITY_ | \u65e0\u969c\u788d\u6309\u94ae | | 15 | DISMISS_NOTIFICATION_SHADE | \u5173\u95ed\u901a\u77e5\u680f | | 16-20 | DPAD_ | \u65b9\u5411\u952e | | 21 | MENU | \u83dc\u5355\u6309\u94ae | | 22 | MEDIA_PLAY_PAUSE | \u64ad\u653e/\u6682\u505c\u5a92\u4f53 |

          "},{"location":"qsl4a/ui/accessibility/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/accessibility/#_6","title":"\u70b9\u51fb\u5c4f\u5e55\u4e2d\u5fc3","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u670d\u52a1\nif not droid.accessibilityServiceEnabled().result:\n    droid.accessibilityStartService()\n\n# \u70b9\u51fb\u4e2d\u5fc3\uff080,0 = \u4e2d\u5fc3\uff09\ndroid.accessibilityClick(0, 0, t=100)\n
          "},{"location":"qsl4a/ui/accessibility/#_7","title":"\u6ed1\u52a8\u624b\u52bf","text":"
          # \u4ece\u4e0b\u5f80\u4e0a\u6ed1\u52a8\uff08\u5411\u4e0a\u6eda\u52a8\uff09\ndroid.accessibilitySlide([0, 1.5, 0, -1.5], t=300)\n
          "},{"location":"qsl4a/ui/accessibility/#_8","title":"\u7cfb\u7edf\u5bfc\u822a","text":"
          # \u6309\u4e3b\u5c4f\u5e55\ndroid.accessibilityAction(2)\n\n# \u6309\u8fd4\u56de\ndroid.accessibilityAction(1)\n\n# \u6253\u5f00\u901a\u77e5\ndroid.accessibilityAction(4)\n
          "},{"location":"qsl4a/ui/accessibility/#_9","title":"\u70b9\u51fb\u7279\u5b9a\u4f4d\u7f6e","text":"
          # \u70b9\u51fb\u5c4f\u5e55\u5750\u6807 (500, 800)\ndroid.accessibilityClick(500, 800)\n\n# \u70b9\u51fb\u76f8\u5bf9\u4f4d\u7f6e\uff08\u6c34\u5e73\u5c45\u4e2d\uff0c\u5782\u76f4 3/4 \u5904\uff09\ndroid.accessibilityClick(0, 1.5)\n
          "},{"location":"qsl4a/ui/dialogs/","title":"\u5bf9\u8bdd\u6846\u7cfb\u7edf","text":"

          QSL4A \u63d0\u4f9b\u5168\u9762\u7684\u5bf9\u8bdd\u6846\u652f\u6301\uff0c\u7528\u4e8e\u7528\u6237\u4ea4\u4e92\uff0c\u5305\u62ec\u8b66\u62a5\u3001\u8f93\u5165\u5bf9\u8bdd\u6846\u3001\u9009\u62e9\u5bf9\u8bdd\u6846\u548c\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

          "},{"location":"qsl4a/ui/dialogs/#_2","title":"\u8b66\u62a5\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowalert","title":"dialogShowAlert()","text":"

          \u663e\u793a\u7b80\u5355\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

          dialogShowAlert(title=\"Alert\", message=\"The message of the alert.\",\n                positiveButtonText=\"OK\", negativeButtonText=None,\n                neutralButtonText=None, messageIsHtml=False)\n

          \u53c2\u6570\uff1a - title (str): \u5bf9\u8bdd\u6846\u6807\u9898 - message (str): \u6d88\u606f\u6587\u672c - positiveButtonText (str): \u80af\u5b9a\u6309\u94ae\u6807\u7b7e - negativeButtonText (str, optional): \u5426\u5b9a\u6309\u94ae\u6807\u7b7e - neutralButtonText (str, optional): \u4e2d\u6027\u6309\u94ae\u6807\u7b7e - messageIsHtml (bool): \u5c06\u6d88\u606f\u89e3\u6790\u4e3a HTML

          \u8fd4\u56de\uff1a \u5305\u542b\u70b9\u51fb\u6309\u94ae\u7684\u7ed3\u679c

          "},{"location":"qsl4a/ui/dialogs/#dialogshowsimplechoice","title":"dialogShowSimpleChoice()","text":"

          \u663e\u793a\u5e26\u6709\u9879\u76ee\u7684\u7b80\u5355\u9009\u62e9\u5bf9\u8bdd\u6846\u3002

          dialogShowSimpleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

          \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868

          \u8fd4\u56de\uff1a \u5305\u542b\u9009\u4e2d\u9879\u76ee\u7684\u7ed3\u679c

          "},{"location":"qsl4a/ui/dialogs/#_3","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialoggetinput","title":"dialogGetInput()","text":"

          \u83b7\u53d6\u7528\u6237\u6587\u672c\u8f93\u5165\u3002

          dialogGetInput(title=\"Value\", message=\"Please enter value:\",\n               defaultText=None, messageIsHtml=False)\n

          \u8fd4\u56de\uff1a \u5305\u542b\u7528\u6237\u8f93\u5165\u6587\u672c\u7684\u7ed3\u679c

          "},{"location":"qsl4a/ui/dialogs/#dialoggetpassword","title":"dialogGetPassword()","text":"

          \u83b7\u53d6\u5bc6\u7801\u8f93\u5165\u3002

          dialogGetPassword(title=\"Password\", message=\"Please enter password:\")\n

          \u8fd4\u56de\uff1a \u5305\u542b\u8f93\u5165\u5bc6\u7801\u7684\u7ed3\u679c

          "},{"location":"qsl4a/ui/dialogs/#dialogcreateinput","title":"dialogCreateInput()","text":"

          \u521b\u5efa\u81ea\u5b9a\u4e49\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

          dialogCreateInput(title=\"Value\", message=\"Please enter value:\",\n                  defaultText=None, inputType=None)\n

          \u53c2\u6570\uff1a - inputType (str): \u8f93\u5165\u7c7b\u578b\uff08\u4f8b\u5982 \"text\"\u3001\"number\"\u3001\"textPassword\"\uff09

          "},{"location":"qsl4a/ui/dialogs/#dialogcreatepassword","title":"dialogCreatePassword()","text":"

          \u521b\u5efa\u5bc6\u7801\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

          dialogCreatePassword(title=\"Password\", message=\"Please enter password:\")\n
          "},{"location":"qsl4a/ui/dialogs/#dialogcreateseekbar","title":"dialogCreateSeekBar()","text":"

          \u521b\u5efa\u6ed1\u5757/\u8fdb\u5ea6\u6761\u5bf9\u8bdd\u6846\u3002

          dialogCreateSeekBar(starting_value=50, maximum_value=100, title=\"\", message=\"\")\n

          \u53c2\u6570\uff1a - starting_value (int): \u521d\u59cb\u503c - maximum_value (int): \u6700\u5927\u503c

          "},{"location":"qsl4a/ui/dialogs/#_4","title":"\u9009\u62e9\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowsinglechoice","title":"dialogShowSingleChoice()","text":"

          \u663e\u793a\u5355\u9009\uff08\u5355\u9009\u6309\u94ae\uff09\u5bf9\u8bdd\u6846\u3002

          dialogShowSingleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, selected=-1, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

          \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (int): \u9ed8\u8ba4\u9009\u4e2d\u7d22\u5f15

          "},{"location":"qsl4a/ui/dialogs/#dialogshowmultichoice","title":"dialogShowMultiChoice()","text":"

          \u663e\u793a\u591a\u9009\uff08\u590d\u9009\u6846\uff09\u5bf9\u8bdd\u6846\u3002

          dialogShowMultiChoice(title=\"Alert\", message=\"The message of the alert.\",\n                      items=None, selected=None, positiveButtonText=\"OK\",\n                      negativeButtonText=None, neutralButtonText=None,\n                      messageIsHtml=False)\n

          \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (list): \u521d\u59cb\u9009\u4e2d\u7d22\u5f15\u5217\u8868

          "},{"location":"qsl4a/ui/dialogs/#dialogsetsinglechoiceitems","title":"dialogSetSingleChoiceItems()","text":"

          \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u5355\u9009\u9879\u76ee\u3002

          dialogSetSingleChoiceItems(items, selected=-1)\n
          "},{"location":"qsl4a/ui/dialogs/#dialogsetmultichoiceitems","title":"dialogSetMultiChoiceItems()","text":"

          \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u591a\u9009\u9879\u76ee\u3002

          dialogSetMultiChoiceItems(items, selected=None)\n
          "},{"location":"qsl4a/ui/dialogs/#_5","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatespinnerprogress","title":"dialogCreateSpinnerProgress()","text":"

          \u521b\u5efa\u4e0d\u786e\u5b9a\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

          dialogCreateSpinnerProgress(title=None, message=None, maximum_progress=100)\n
          "},{"location":"qsl4a/ui/dialogs/#dialogcreatehorizontalprogress","title":"dialogCreateHorizontalProgress()","text":"

          \u521b\u5efa\u6c34\u5e73\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

          dialogCreateHorizontalProgress(title=None, message=None, maximum_progress=100)\n
          "},{"location":"qsl4a/ui/dialogs/#dialogsetcurrentprogress","title":"dialogSetCurrentProgress()","text":"

          \u66f4\u65b0\u8fdb\u5ea6\u503c\u3002

          dialogSetCurrentProgress(current)\n
          "},{"location":"qsl4a/ui/dialogs/#dialogsetmaxprogress","title":"dialogSetMaxProgress()","text":"

          \u8bbe\u7f6e\u6700\u5927\u8fdb\u5ea6\u503c\u3002

          dialogSetMaxProgress(max)\n
          "},{"location":"qsl4a/ui/dialogs/#dialogsetprogressmessage","title":"dialogSetProgressMessage()","text":"

          \u66f4\u65b0\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u6d88\u606f\u3002

          dialogSetProgressMessage(message)\n
          "},{"location":"qsl4a/ui/dialogs/#_6","title":"\u9009\u62e9\u5668\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatedatepicker","title":"dialogCreateDatePicker()","text":"

          \u521b\u5efa\u65e5\u671f\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

          dialogCreateDatePicker(year=1970, month=1, day=1)\n
          "},{"location":"qsl4a/ui/dialogs/#dialogcreatetimepicker","title":"dialogCreateTimePicker()","text":"

          \u521b\u5efa\u65f6\u95f4\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

          dialogCreateTimePicker(hour=0, minute=0, is24hour=False)\n
          "},{"location":"qsl4a/ui/dialogs/#_7","title":"\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u521b\u5efa","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatealert","title":"dialogCreateAlert()","text":"

          \u521b\u5efa\u81ea\u5b9a\u4e49\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

          dialogCreateAlert(title=None, message=None)\n

          \u521b\u5efa\u4e00\u4e2a\u7a7a\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002\u53ef\u4e0e\u5176\u4ed6 dialogSet* \u51fd\u6570\u4e00\u8d77\u4f7f\u7528\u6765\u81ea\u5b9a\u4e49\u3002

          "},{"location":"qsl4a/ui/dialogs/#dialogsetitems","title":"dialogSetItems()","text":"

          \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u7b80\u5355\u5217\u8868\u9879\u76ee\u3002

          dialogSetItems(items)\n
          "},{"location":"qsl4a/ui/dialogs/#dialogsetpositivebuttontext","title":"dialogSetPositiveButtonText()","text":"

          \u8bbe\u7f6e\u80af\u5b9a\u6309\u94ae\u6587\u672c\u3002

          dialogSetPositiveButtonText(text)\n
          "},{"location":"qsl4a/ui/dialogs/#dialogsetnegativebuttontext","title":"dialogSetNegativeButtonText()","text":"

          \u8bbe\u7f6e\u5426\u5b9a\u6309\u94ae\u6587\u672c\u3002

          dialogSetNegativeButtonText(text)\n
          "},{"location":"qsl4a/ui/dialogs/#dialogsetneutralbuttontext","title":"dialogSetNeutralButtonText()","text":"

          \u8bbe\u7f6e\u4e2d\u6027\u6309\u94ae\u6587\u672c\u3002

          dialogSetNeutralButtonText(text)\n
          "},{"location":"qsl4a/ui/dialogs/#dialogsetmessageishtml","title":"dialogSetMessageIsHtml()","text":"

          \u8bbe\u7f6e\u6d88\u606f\u662f\u5426\u5e94\u89e3\u6790\u4e3a HTML\u3002

          dialogSetMessageIsHtml(messageIsHtml=True)\n
          "},{"location":"qsl4a/ui/dialogs/#dialogshow","title":"dialogShow()","text":"

          \u663e\u793a\u521b\u5efa\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u3002

          dialogShow()\n
          "},{"location":"qsl4a/ui/dialogs/#_8","title":"\u5bf9\u8bdd\u6846\u63a7\u5236","text":""},{"location":"qsl4a/ui/dialogs/#dialogdismiss","title":"dialogDismiss()","text":"

          \u5173\u95ed\u5f53\u524d\u5bf9\u8bdd\u6846\u3002

          dialogDismiss()\n
          "},{"location":"qsl4a/ui/dialogs/#dialoggetresponse","title":"dialogGetResponse()","text":"

          \u83b7\u53d6\u5bf9\u8bdd\u6846\u54cd\u5e94\u3002

          dialogGetResponse()\n
          "},{"location":"qsl4a/ui/dialogs/#dialoggetselecteditems","title":"dialogGetSelectedItems()","text":"

          \u4ece\u9009\u62e9\u5bf9\u8bdd\u6846\u83b7\u53d6\u9009\u4e2d\u7684\u9879\u76ee\u3002

          dialogGetSelectedItems()\n
          "},{"location":"qsl4a/ui/dialogs/#_9","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/dialogs/#_10","title":"\u7b80\u5355\u8b66\u62a5","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a\u8b66\u62a5\ndroid.dialogShowAlert(\"Warning\", \"This is an important message!\")\n
          "},{"location":"qsl4a/ui/dialogs/#_11","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":"
          # \u83b7\u53d6\u7528\u6237\u8f93\u5165\nresult = droid.dialogGetInput(\"Name\", \"Enter your name:\", \"John\").result\nprint(f\"Hello, {result}!\")\n
          "},{"location":"qsl4a/ui/dialogs/#_12","title":"\u5e26\u6309\u94ae\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846","text":"
          # \u521b\u5efa\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\ndroid.dialogCreateAlert(\"Custom\", \"Choose an option\")\ndroid.dialogSetItems([\"Option 1\", \"Option 2\", \"Option 3\"])\ndroid.dialogShow()\n\n# \u83b7\u53d6\u54cd\u5e94\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response['item']}\")\n
          "},{"location":"qsl4a/ui/dialogs/#_13","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":"
          # \u521b\u5efa\u8fdb\u5ea6\u5bf9\u8bdd\u6846\ndroid.dialogCreateHorizontalProgress(\"Loading\", \"Please wait...\", 100)\ndroid.dialogShow()\n\n# \u66f4\u65b0\u8fdb\u5ea6\nfor i in range(101):\n    droid.dialogSetCurrentProgress(i)\n    time.sleep(0.05)\n\ndroid.dialogDismiss()\n
          "},{"location":"qsl4a/ui/dialogs/#_14","title":"\u65e5\u671f\u9009\u62e9\u5668","text":"
          # \u663e\u793a\u65e5\u671f\u9009\u62e9\u5668\ndroid.dialogCreateDatePicker(2024, 1, 15)\ndroid.dialogShow()\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response}\")\n
          "},{"location":"qsl4a/ui/floatview/","title":"\u6d6e\u52a8\u89c6\u56fe","text":"

          \u6d6e\u52a8\u7a97\u53e3\u652f\u6301\uff0c\u7528\u4e8e\u5728\u5176\u4ed6\u5e94\u7528\u7a0b\u5e8f\u4e0a\u65b9\u4fdd\u6301\u663e\u793a\u7684\u8986\u76d6 UI \u5143\u7d20\u3002

          "},{"location":"qsl4a/ui/floatview/#_2","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/floatview/#floatview","title":"floatView()","text":"

          \u663e\u793a\u6216\u4fee\u6539\u6d6e\u52a8\u89c6\u56fe\u3002

          floatView(Args=None)\n

          \u53c2\u6570\uff1a - Args (dict): \u914d\u7f6e\u5b57\u5178\uff0c\u5305\u542b\u4ee5\u4e0b\u952e\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08-1 \u521b\u5efa\u65b0\u7684\uff0c>=0 \u4fee\u6539\u73b0\u6709\u7684\uff09 - text (str): \u8981\u663e\u793a\u7684\u6587\u672c\u5185\u5bb9 - html (str): HTML \u5185\u5bb9\uff08\u5982\u679c\u7701\u7565 text \u5219\u4f7f\u7528\uff09 - width (int): \u89c6\u56fe\u5bbd\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a300\uff09 - height (int): \u89c6\u56fe\u9ad8\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a150\uff09 - x (int): X \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - y (int): Y \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - backColor (str): ARGB \u5341\u516d\u8fdb\u5236\u80cc\u666f\u8272\uff08\u9ed8\u8ba4\uff1a'7f7f7f7f'\uff09 - textColor (str): ARGB \u5341\u516d\u8fdb\u5236\u6587\u672c\u8272\uff08\u9ed8\u8ba4\uff1a'ff000000'\uff09 - textSize (int): \u6587\u672c\u5927\u5c0f\uff08\u9ed8\u8ba4\uff1a10\uff09 - textAlign (int): \u6587\u672c\u5bf9\u9f50\uff080 = \u7ee7\u627f\uff09 - script (str): \u957f\u6309\u5173\u95ed\u540e\u8fd0\u884c\u7684\u811a\u672c\u8def\u5f84 - arg: \u811a\u672c\u53c2\u6570 - clickRemove (bool): \u542f\u7528\u70b9\u51fb\u79fb\u9664\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - flag (int): \u7a97\u53e3\u6807\u5fd7\uff08\u9ed8\u8ba4\uff1a40 - \u53ef\u89e6\u6478\uff09

          \u8fd4\u56de\uff1a \u5f53\u524d\u94fe\u5217\u8868\u957f\u5ea6

          "},{"location":"qsl4a/ui/floatview/#floatviewcount","title":"floatViewCount()","text":"

          \u83b7\u53d6\u6d3b\u52a8\u6d6e\u52a8\u89c6\u56fe\u7684\u6570\u91cf\u3002

          floatViewCount()\n

          \u8fd4\u56de\uff1a \u6d6e\u52a8\u89c6\u56fe\u6570\u91cf

          "},{"location":"qsl4a/ui/floatview/#floatviewresult","title":"floatViewResult()","text":"

          \u83b7\u53d6\u6d6e\u52a8\u89c6\u56fe\u7684\u7ed3\u679c/\u72b6\u6001\u3002

          floatViewResult(index=-1)\n

          \u53c2\u6570\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1\uff0c\u8fd4\u56de\u6700\u540e\u64cd\u4f5c\u7ed3\u679c\uff09

          \u8fd4\u56de\uff1a \u5305\u542b\u64cd\u4f5c\u8be6\u60c5\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - x, y: \u4f4d\u7f6e - time: \u65f6\u95f4\u6233 - operation: \u64cd\u4f5c\u7c7b\u578b\uff08'initial'\u3001'move' \u7b49\uff09 - index: \u89c6\u56fe\u7d22\u5f15 - removed: \u5982\u679c\u89c6\u56fe\u88ab\u79fb\u9664\u5219\u4e3a True

          "},{"location":"qsl4a/ui/floatview/#floatviewremove","title":"floatViewRemove()","text":"

          \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\u3002

          floatViewRemove(index=-1)\n

          \u53c2\u6570\uff1a - index (int): \u8981\u79fb\u9664\u7684\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1 \u79fb\u9664\u6700\u540e\u4e00\u4e2a\uff09

          \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a 1\uff0c\u5426\u5219\u4e3a 0

          "},{"location":"qsl4a/ui/floatview/#_3","title":"\u5e38\u91cf","text":"
          • floatView.INDEX_NEW = -1 - \u521b\u5efa\u65b0\u7684\u6d6e\u52a8\u89c6\u56fe
          • floatView.FLAG_DEFAULT_TOUCHABLE = 40 - \u9ed8\u8ba4\u53ef\u89e6\u6478\u6807\u5fd7
          • floatView.TEXT_ALIGNMENT_INHERIT = 0
          • floatView.TEXT_ALIGNMENT_CENTER - \u5c45\u4e2d\u6587\u672c\u5bf9\u9f50
          "},{"location":"qsl4a/ui/floatview/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/floatview/#_5","title":"\u57fa\u672c\u6d6e\u52a8\u89c6\u56fe","text":"
          import androidhelper\nfrom androidhelper import Android\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u7b80\u5355\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'index': -1,  # \u521b\u5efa\u65b0\u7684\n    'text': 'Hello World',\n    'width': 400,\n    'height': 300,\n    'x': -300,  # \u4ece\u4e2d\u5fc3\u504f\u79fb\n    'y': -400,\n    'backColor': 'ff0000',  # \u7ea2\u8272\u80cc\u666f\n    'textColor': '0000ff',  # \u84dd\u8272\u6587\u672c\n    'textSize': 16,\n    'textAlign': droid.floatView.TEXT_ALIGNMENT_CENTER\n})\n\n# \u68c0\u67e5\u6570\u91cf\nprint(f\"Float views: {droid.floatViewCount().result}\")\n\n# \u83b7\u53d6\u7ed3\u679c\nresult = droid.floatViewResult().result\nprint(f\"View info: {result}\")\n\n# \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\ndroid.floatViewRemove(0)\n
          "},{"location":"qsl4a/ui/floatview/#html","title":"HTML \u5185\u5bb9","text":"
          # \u521b\u5efa\u5e26 HTML \u5185\u5bb9\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': '',  # \u7a7a\u6587\u672c\u4ee5\u4f7f\u7528 HTML\n    'html': '<h1>Title</h1><p>Rich <b>HTML</b> content</p>',\n    'width': 500,\n    'height': 400\n})\n
          "},{"location":"qsl4a/ui/floatview/#_6","title":"\u4fee\u6539\u73b0\u6709\u89c6\u56fe","text":"
          # \u521b\u5efa\u521d\u59cb\u89c6\u56fe\ndroid.floatView({'text': 'Initial Text', 'width': 300, 'height': 150})\n\n# \u4fee\u6539\u540c\u4e00\u89c6\u56fe\uff08\u7d22\u5f15 0\uff09\ndroid.floatView({\n    'index': 0,\n    'text': 'Updated Text!',\n    'backColor': '7f00ff00'  # \u7eff\u8272\u80cc\u666f\n})\n\n# \u68c0\u67e5\u79fb\u52a8/\u66f4\u6539\u7ed3\u679c\nresult = droid.floatViewResult(0).result\nprint(f\"Operation: {result.get('operation')}, Position: ({result.get('x')}, {result.get('y')})\")\n
          "},{"location":"qsl4a/ui/floatview/#_7","title":"\u591a\u4e2a\u6d6e\u52a8\u89c6\u56fe","text":"
          # \u521b\u5efa\u591a\u4e2a\u89c6\u56fe\nfor i in range(3):\n    droid.floatView({\n        'index': -1,\n        'text': f'View {i}',\n        'x': i * 100 - 150,\n        'y': i * 100 - 150,\n        'backColor': f'{i}f{i}f{i}f'\n    })\n\nprint(f\"Total views: {droid.floatViewCount().result}\")\n\n# \u79fb\u9664\u6240\u6709\u89c6\u56fe\nwhile droid.floatViewCount().result > 0:\n    droid.floatViewRemove()\n
          "},{"location":"qsl4a/ui/floatview/#_8","title":"\u5e26\u811a\u672c\u56de\u8c03","text":"
          # \u521b\u5efa\u5173\u95ed\u65f6\u8fd0\u884c\u811a\u672c\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': 'Click to close and run script',\n    'script': '/sdcard/my_script.py',\n    'arg': 'hello from float view',\n    'clickRemove': True\n})\n
          "},{"location":"qsl4a/ui/fullscreen/","title":"\u5168\u5c4f UI","text":"

          \u4f7f\u7528\u539f\u751f Android \u5e03\u5c40\u521b\u5efa\u81ea\u5b9a\u4e49\u5168\u5c4f\u754c\u9762\u3002

          "},{"location":"qsl4a/ui/fullscreen/#_1","title":"\u5e03\u5c40\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullshow","title":"fullShow()","text":"

          \u663e\u793a\u5168\u5c4f\u5e03\u5c40\u3002

          fullShow(layout, title=None, theme=None)\n

          \u53c2\u6570\uff1a - layout (str): JSON \u5e03\u5c40\u5b9a\u4e49\u6216\u5e03\u5c40\u5b57\u7b26\u4e32 - title (str, optional): \u7a97\u53e3\u6807\u9898 - theme (str, optional): \u4e3b\u9898\u540d\u79f0

          \u8fd4\u56de\uff1a \u7a97\u53e3 ID

          "},{"location":"qsl4a/ui/fullscreen/#fulldismiss","title":"fullDismiss()","text":"

          \u5173\u95ed\u5168\u5c4f\u7a97\u53e3\u3002

          fullDismiss()\n
          "},{"location":"qsl4a/ui/fullscreen/#fullquery","title":"fullQuery()","text":"

          \u67e5\u8be2\u6240\u6709\u5c0f\u90e8\u4ef6\u503c\u3002

          fullQuery()\n

          \u8fd4\u56de\uff1a \u5c0f\u90e8\u4ef6 ID \u548c\u503c\u7684\u5b57\u5178

          "},{"location":"qsl4a/ui/fullscreen/#fullquerydetail","title":"fullQueryDetail()","text":"

          \u67e5\u8be2\u7279\u5b9a\u5c0f\u90e8\u4ef6\u8be6\u60c5\u3002

          fullQueryDetail(id)\n
          "},{"location":"qsl4a/ui/fullscreen/#_2","title":"\u5c5e\u6027\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperty","title":"fullGetProperty()","text":"

          \u83b7\u53d6\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

          fullGetProperty(id, property)\n
          "},{"location":"qsl4a/ui/fullscreen/#fullsetproperty","title":"fullSetProperty()","text":"

          \u8bbe\u7f6e\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

          fullSetProperty(id, property, value)\n
          "},{"location":"qsl4a/ui/fullscreen/#fullsetlist","title":"fullSetList()","text":"

          \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

          fullSetList(id, list, isHtml=False, listType=0)\n
          "},{"location":"qsl4a/ui/fullscreen/#fullsetlist2","title":"fullSetList2()","text":"

          \u4f7f\u7528\u8d44\u6e90 ID \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

          fullSetList2(id, list, intRes)\n

          \u53c2\u6570\uff1a - id (str): \u5c0f\u90e8\u4ef6 ID - list (list): \u9879\u76ee\u5217\u8868 - intRes (int): \u5217\u8868\u9879\u76ee\u5e03\u5c40\u7684 Android \u8d44\u6e90 ID

          "},{"location":"qsl4a/ui/fullscreen/#fullsetlistselected","title":"fullSetListSelected()","text":"

          \u5728\u5217\u8868\u4e2d\u8bbe\u7f6e\u9009\u4e2d\u9879\u76ee\u3002

          fullSetListSelected(id, selected)\n

          \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID - selected (int): \u8981\u9009\u4e2d\u7684\u9879\u76ee\u7d22\u5f15

          "},{"location":"qsl4a/ui/fullscreen/#fullgetlistselected","title":"fullGetListSelected()","text":"

          \u83b7\u53d6\u5f53\u524d\u9009\u4e2d\u7684\u5217\u8868\u9879\u76ee\u7d22\u5f15\u3002

          fullGetListSelected(id)\n

          \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID

          \u8fd4\u56de\uff1a \u9009\u4e2d\u9879\u76ee\u7d22\u5f15

          "},{"location":"qsl4a/ui/fullscreen/#_3","title":"\u6279\u91cf\u5c5e\u6027\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperties","title":"fullGetProperties()","text":"

          \u4e00\u6b21\u83b7\u53d6\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

          fullGetProperties(ids, property)\n

          \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u83b7\u53d6\u7684\u5c5e\u6027\u540d

          \u8fd4\u56de\uff1a \u6620\u5c04\u5c0f\u90e8\u4ef6 ID \u5230\u5c5e\u6027\u503c\u7684\u5b57\u5178

          "},{"location":"qsl4a/ui/fullscreen/#fullsetproperties","title":"fullSetProperties()","text":"

          \u4e00\u6b21\u8bbe\u7f6e\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

          fullSetProperties(ids, property, value)\n

          \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u8bbe\u7f6e\u7684\u5c5e\u6027\u540d - value: \u5c5e\u6027\u503c

          "},{"location":"qsl4a/ui/fullscreen/#_4","title":"\u622a\u56fe","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetscreenshot","title":"fullGetScreenShot()","text":"

          \u6355\u83b7\u5168\u5c4f\u622a\u56fe\u3002

          fullGetScreenShot(path=None)\n

          \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u5728\u4e8b\u4ef6\u4e2d\u8fd4\u56de

          \u8fd4\u56de\uff1a \u5305\u542b\u622a\u56fe\u6570\u636e\u7684\u4e8b\u4ef6

          "},{"location":"qsl4a/ui/fullscreen/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b9a\u4e49\u5e03\u5c40\nlayout = '''\n{ \"type\": \"LinearLayout\", \"orientation\": \"vertical\",\n  \"children\": [\n    { \"type\": \"TextView\", \"id\": \"title\", \"text\": \"Hello\" },\n    { \"type\": \"Button\", \"id\": \"btn\", \"text\": \"Click Me\" }\n  ]\n}\n'''\n\n# \u663e\u793a\u5e03\u5c40\ndroid.fullShow(layout, \"My App\")\n\n# \u67e5\u8be2\u6309\u94ae\u70b9\u51fb\nevent = droid.eventWaitFor('click', timeout=10)\nif event.result:\n    widget_id = event.result['data']['id']\n    if widget_id == 'btn':\n        print(\"Button clicked!\")\n\ndroid.fullDismiss()\n
          "}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"QPython \u9879\u76ee","text":"

          QPython \u4e0d\u4ec5\u662f\u4e00\u4e2a\u5f3a\u5927\u7684 Android Python IDE\uff0c\u4e5f\u662f\u4e00\u4e2a\u6d3b\u8dc3\u7684\u6280\u672f\u793e\u533a\u3002

          "},{"location":"#ai-android-python-ide","title":"\u652f\u6301 AI \u7684 Android Python IDE","text":"

          QPython \u662f\u60a8\u8fdb\u884c Android Python \u7f16\u7a0b\u7684\u5165\u53e3\u3002\u5b83\u96c6\u6210\u4e86 Python \u89e3\u91ca\u5668\u3001AI \u6a21\u578b\u5f15\u64ce\u548c\u79fb\u52a8\u5f00\u53d1\u5de5\u5177\u94fe\uff0c\u8ba9\u60a8\u80fd\u591f\u4ece\u79fb\u52a8\u8bbe\u5907\u6784\u5efa Web \u5e94\u7528\u7a0b\u5e8f\u3001\u6267\u884c\u79d1\u5b66\u8ba1\u7b97\u548c\u521b\u5efa\u667a\u80fd\u5e94\u7528\u3002

          \u65e0\u8bba\u60a8\u662f\u5728\u5b66\u4e60\u7f16\u7a0b\u3001\u6784\u5efa\u6570\u636e\u79d1\u5b66\u9879\u76ee\uff0c\u8fd8\u662f\u5f00\u53d1 AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f\uff0cQPython \u90fd\u63d0\u4f9b\u4e86\u5b8c\u6574\u7684\u79fb\u52a8\u7f16\u7a0b\u89e3\u51b3\u65b9\u6848\uff0c\u62e5\u6709\u5168\u9762\u7684\u5f00\u53d1\u8005\u8d44\u6e90\u548c\u6d3b\u8dc3\u7684\u793e\u533a\u6765\u652f\u6301\u60a8\u7684\u65c5\u7a0b\u3002

          • \u5206\u652f\u7248\u672c \u2013 \u4e86\u89e3\u4e0d\u540c\u7684 QPython \u7248\u672c\uff08IDE\u3001\u793e\u533a\u7248\u3001Plus\uff09\uff0c\u9009\u62e9\u9002\u5408\u60a8\u9700\u6c42\u7684\u7248\u672c
          • \u66f4\u65b0\u65e5\u5fd7 \u2013 \u968f\u65f6\u4e86\u89e3\u6700\u65b0\u529f\u80fd\u3001\u6539\u8fdb\u548c\u53d1\u884c\u8bf4\u660e
          "},{"location":"#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"

          \u5982\u4f55\u5feb\u901f\u5165\u95e8\uff1f\u8bf7\u6309\u7167\u4ee5\u4e0b\u6b65\u9aa4\uff1a

          • \u5feb\u901f\u5165\u95e8
          • Hello World \u6559\u7a0b
          • \u7cbe\u9009\u8bfe\u7a0b
          "},{"location":"#_2","title":"\u7f16\u7a0b\u6307\u5357","text":"

          QPython \u4e0d\u4ec5\u63d0\u4f9b\u57fa\u7840\u7684 Python \u63a5\u53e3\u652f\u6301\uff0c\u66f4\u91cd\u8981\u7684\u662f\uff0c\u5b83\u8fd8\u5141\u8bb8\u60a8\u901a\u8fc7 QSL4A \u63a5\u53e3\u4f7f\u7528 Python \u8c03\u7528 Android API\u3002

          • Python \u6807\u51c6\u5e93 \u2013 \u901a\u7528\u7684 Python \u8bed\u6cd5\u548c\u5185\u7f6e\u5e93
          • QSL4A API \u2013 \u4ece Python \u8bbf\u95ee Android \u8bbe\u5907\u529f\u80fd\uff08\u76f8\u673a\u3001\u4f20\u611f\u5668\u3001\u77ed\u4fe1\u7b49\uff09
          • QPYPI \u6307\u5357 \u2013 \u5b89\u88c5\u989d\u5916\u7684 Python \u5305
          • \u7f16\u8f91\u5668\u6307\u5357 \u2013 \u4f7f\u7528\u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668
          • \u5916\u90e8 API \u2013 \u4e0e\u5916\u90e8\u5e94\u7528\u7a0b\u5e8f\u96c6\u6210
          "},{"location":"#_3","title":"\u4e0b\u8f7d\u8d44\u6e90","text":"

          \u6700\u65b0\u7248\u672c v4.0.0 \u66f4\u65b0\u8bf4\u660e\uff1a

          • \u5916\u90e8\u5b58\u50a8\u8bbf\u95ee\uff1a\u7528\u6237\u73b0\u5728\u53ef\u4ee5\u5c06 Python \u811a\u672c\u76f4\u63a5\u4fdd\u5b58\u5230\u5916\u90e8\u5b58\u50a8\u8bbe\u5907\uff0c\u5927\u5927\u63d0\u5347\u4e86\u6587\u4ef6\u7ba1\u7406\u7684\u7075\u6d3b\u6027\u3002
          • QSL4A \u529f\u80fd\u589e\u5f3a\uff1a\u6539\u8fdb\u4e86 QSL4A \u7684\u529f\u80fd\u3002
          • \u793e\u533a\u4e0e\u8bfe\u7a0b\uff1a\u4f18\u5316\u4e86\u793e\u533a\u548c\u8bfe\u7a0b\u6a21\u5757\uff0c\u63d0\u4f9b\u66f4\u6e05\u6670\u7684\u4fe1\u606f\u548c\u66f4\u4fbf\u6377\u7684\u5bfc\u822a\uff0c\u65b9\u4fbf\u7528\u6237\u8bbf\u95ee\u5b66\u4e60\u8d44\u6e90\u548c\u83b7\u5f97\u652f\u6301\u3002

          • Google Drive

          • \u5fae\u4fe1\u7f51\u76d8
          "},{"location":"#_4","title":"\u793e\u533a\u4e0e\u53cd\u9988","text":"
          • \u4e2d\u6587\u4ea4\u6d41\u793e\u533a
          • \u95ee\u9898\u53cd\u9988
          • \u529f\u80fd\u6269\u5c55\u8bf7\u6c42
          "},{"location":"#_5","title":"\u5173\u6ce8\u6211\u4eec","text":"
          • B\u7ad9
          • Weibo
          "},{"location":"AIPyApp/","title":"AIPyApp - AI\u9a71\u52a8\u7684\u7a0b\u5e8f\u751f\u6210\u5668","text":"

          AIPyApp \u662f QPython \u4e2d\u7684\u667a\u80fd\u5de5\u5177\uff0c\u53ef\u4ee5\u5229\u7528 AI \u4ece\u81ea\u7136\u8bed\u8a00\u6307\u4ee4\u81ea\u52a8\u751f\u6210 Python \u7a0b\u5e8f\u3002

          "},{"location":"AIPyApp/#_1","title":"\u6982\u8ff0","text":"

          AIPyApp \u6539\u53d8\u4e86\u60a8\u7f16\u5199\u4ee3\u7801\u7684\u65b9\u5f0f\u2014\u2014\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u63cf\u8ff0\u60a8\u60f3\u8981\u7684\u529f\u80fd\uff0cAI \u5c31\u4f1a\u4e3a\u60a8\u751f\u6210 Python \u7a0b\u5e8f\u3002QPython \u8fd8\u5c06\u63a8\u51fa AIPy Academy\u2014\u2014\u4e00\u4e2a\u4e3a AI \u65f6\u4ee3\u91cf\u8eab\u5b9a\u5236\u7684 Python \u7f16\u7a0b\u8bfe\u7a0b\u5e73\u53f0\u3002

          "},{"location":"AIPyApp/#_2","title":"\u5b89\u88c5","text":"

          QPython \u6c1b\u56f4\u7f16\u7a0b\uff08Vibe Coding\uff09 01 - \u5982\u4f55\u542f\u7528AIPyApp

          "},{"location":"AIPyApp/#_3","title":"\u7b2c\u4e00\u6b65\uff1a\u4ece\u4eea\u8868\u76d8\u542f\u52a8","text":"
          1. \u6253\u5f00 QPython\uff0c\u8fdb\u5165 \u4eea\u8868\u76d8
          2. \u957f\u6309\u5f00\u59cb\u6309\u94ae

          \u5982\u679c\u672a\u5b89\u88c5 AIPyApp\uff0c\u7cfb\u7edf\u4f1a\u63d0\u793a\u60a8\u786e\u8ba4\u5b89\u88c5\u3002\u6309 \u56de\u8f66\u952e\u7ee7\u7eed\u3002

          QPython \u5c06\u81ea\u52a8\u4ece PYPI \u4e0b\u8f7d\u5e76\u5b89\u88c5\u6240\u9700\u7684\u4f9d\u8d56\u9879\u3002\u8bf7\u8010\u5fc3\u7b49\u5f85\u5b89\u88c5\u5b8c\u6210\u3002

          "},{"location":"AIPyApp/#aipyapp","title":"\u7b2c\u4e8c\u6b65\uff1a\u91cd\u65b0\u542f\u52a8 AIPyApp","text":"

          \u5b89\u88c5\u5b8c\u6210\u540e\uff0c\u8fd4\u56de QPython \u4eea\u8868\u76d8\uff0c\u518d\u6b21 \u957f\u6309\u5f00\u59cb\u6309\u94ae\u542f\u52a8 AIPyApp\u3002

          "},{"location":"AIPyApp/#_4","title":"\u914d\u7f6e","text":""},{"location":"AIPyApp/#ai","title":"\u8bbe\u7f6e\u60a8\u7684 AI \u5bc6\u94a5","text":"

          \u9996\u6b21\u542f\u52a8\u65f6\uff0c\u60a8\u9700\u8981\u63d0\u4f9b AI API \u5bc6\u94a5\uff1a

          1. \u5728 PGPT \u6ce8\u518c\uff1a\u5728 https://user.pgpt.cloud \u521b\u5efa\u8d26\u6237\u4ee5\u751f\u6210\u60a8\u7684 AI \u5bc6\u94a5
          2. \u9ad8\u7ea7\u9009\u9879\uff1aAIPyApp \u8fd8\u652f\u6301\u6765\u81ea OpenAI\u3001Deepseek \u548c\u5176\u4ed6\u63d0\u4f9b\u5546\u7684\u81ea\u5b9a\u4e49 AI \u5bc6\u94a5\uff08\u8be6\u89c1\u9ad8\u7ea7\u6559\u7a0b\uff09
          "},{"location":"AIPyApp/#ai_1","title":"\u8f93\u5165\u60a8\u7684 AI \u5bc6\u94a5","text":"
          1. \u957f\u6309\u8f93\u5165\u63d0\u793a
          2. \u4ece\u5f39\u51fa\u83dc\u5355\u4e2d\u9009\u62e9 \u7c98\u8d34
          3. \u6309 \u56de\u8f66\u952e\u786e\u8ba4

          \u60a8\u7684 AI \u5bc6\u94a5\u5c06\u4fdd\u5b58\u4ee5\u4f9b\u540e\u7eed\u4f1a\u8bdd\u4f7f\u7528\u3002

          "},{"location":"AIPyApp/#aipyapp_1","title":"\u4f7f\u7528 AIPyApp","text":"

          \u914d\u7f6e\u5b8c\u6210\u540e\uff0c\u60a8\u5c06\u8fdb\u5165 AIPyApp \u63a7\u5236\u53f0\u6a21\u5f0f\u3002\u53ea\u9700\u7528\u81ea\u7136\u8bed\u8a00\u8f93\u5165\u60a8\u7684\u6307\u4ee4\u5373\u53ef\uff01

          "},{"location":"AIPyApp/#_5","title":"\u793a\u4f8b\u547d\u4ee4","text":"

          \u5c1d\u8bd5\u8f93\u5165\uff1a

          \u4f7f\u7528 QSL4A \u521b\u5efa\u4e00\u4e2a HELLO QPY \u7a0b\u5e8f\u4f5c\u4e3a\u6f14\u793a\n

          AIPyApp \u5c06\uff1a 1. \u7406\u89e3\u60a8\u7684\u81ea\u7136\u8bed\u8a00\u8bf7\u6c42 2. \u751f\u6210\u76f8\u5e94\u7684 Python \u4ee3\u7801 3. \u81ea\u52a8\u6267\u884c\u7a0b\u5e8f

          \u5c31\u662f\u8fd9\u6837\u2014\u2014\u60a8\u65e0\u9700\u7f16\u5199\u4efb\u4f55\u4ee3\u7801\u5c31\u521b\u5efa\u4e86\u4e00\u4e2a\u53ef\u8fd0\u884c\u7684 Python \u7a0b\u5e8f\uff01

          "},{"location":"AIPyApp/#_6","title":"\u6f14\u793a\u89c6\u9891","text":"

          QPython \u6c1b\u56f4\u7f16\u7a0b\uff08Vibe Coding\uff09 02 - \u4f7f\u7528\u81ea\u7136\u8bed\u8a00\u5f00\u53d1\u4e00\u4e2a\u7ffb\u8bd1App

          \u4e0a\u9762\u7684\u793a\u4f8b\u6f14\u793a\u4e86 AIPyApp \u5982\u4f55\uff1a - \u7406\u89e3\u4e2d\u6587\u6307\u4ee4 - \u751f\u6210\u57fa\u4e8e QSL4A \u7684 Python \u4ee3\u7801 - \u7acb\u5373\u8fd0\u884c\u7a0b\u5e8f

          \u63a2\u7d22 AIPyApp \u4ee5\u53d1\u73b0\u66f4\u591a\u529f\u80fd\uff0c\u5f00\u59cb\u8f7b\u677e\u6784\u5efa Python \u7a0b\u5e8f\u3002

          "},{"location":"AIPyApp/#_7","title":"\u8bfe\u7a0b\u63a8\u8350","text":"

          \u672b\u5c3e\uff0c\u7ed9\u5927\u5bb6\u63a8\u8350\u4e0b\u9762\u8bfe\u7a0b\uff1a

          \u300a\u4e0eAI\u534f\u4f5c\u7684Python\u7f16\u7a0b\u5165\u95e8\u300b \u2014 \u7531QPython\u5b98\u65b9\u56e2\u961f\u7cbe\u5fc3\u6253\u9020\u5e76\u63d0\u4f9b\u6559\u5b66\u652f\u6301\uff0c\u80fd\u5e2e\u52a9\u5b66\u4e60\u8005\u5feb\u901f\u3001\u4f53\u7cfb\u5316\u5730\u638c\u63e1Python\u5f00\u53d1\u4ee5\u53ca\u5728AI\u65f6\u4ee3\u66f4\u597d\u5730\u5b66\u4e60\u4f7f\u7528AI\u3002

          \u4e86\u89e3\u8be6\u60c5

          "},{"location":"GraphicalInterface/","title":"\u56fe\u5f62\u754c\u9762\uff08Turtle \u548c Tkinter\uff09","text":"

          \u672c\u6307\u5357\u8bf4\u660e\u5982\u4f55\u5728 Android \u8bbe\u5907\u4e0a\u7684 QPython \u4e2d\u542f\u7528\u56fe\u5f62\u754c\u9762\u652f\u6301\uff08Turtle \u548c Tkinter\uff09\u3002

          "},{"location":"GraphicalInterface/#_1","title":"\u6982\u8ff0","text":"

          QPython \u53ef\u4ee5\u8fd0\u884c Turtle \u548c Tkinter \u5e94\u7528\u7a0b\u5e8f\uff0c\u4f46\u9700\u8981\u989d\u5916\u7684\u8f6f\u4ef6\u6765\u5728 Android \u4e0a\u63d0\u4f9b\u56fe\u5f62\u663e\u793a\u652f\u6301\u3002

          "},{"location":"GraphicalInterface/#_2","title":"\u524d\u63d0\u6761\u4ef6","text":"

          \u5f00\u59cb\u4e4b\u524d\uff0c\u60a8\u9700\u8981\u4e0b\u8f7d\u4ee5\u4e0b\u8d44\u6e90\uff1a

          1. Xserver.apk - \u63d0\u4f9b Turtle/Tkinter \u56fe\u5f62\u652f\u6301\u7684\u914d\u5957\u5e94\u7528
          2. \u4e0b\u8f7d\u5730\u5740\uff1aQPythonProject/Extra on Google Drive
          3. Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762\u6269\u5c55 - \u901a\u8fc7 QPython \u7684 QPYPI \u5b89\u88c5
          "},{"location":"GraphicalInterface/#_3","title":"\u5b89\u88c5\u6b65\u9aa4","text":""},{"location":"GraphicalInterface/#xserver","title":"\u7b2c\u4e00\u6b65\uff1a\u5b89\u88c5 Xserver","text":"

          \u4ece Google Drive \u7684 QPython Extra \u8d44\u6e90\u76ee\u5f55\u4e0b\u8f7d\u5e76\u5b89\u88c5 Xserver.apk\u3002

          "},{"location":"GraphicalInterface/#qpython","title":"\u7b2c\u4e8c\u6b65\uff1a\u5b89\u88c5 QPython \u6269\u5c55","text":"

          \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI\u3002\u627e\u5230\u5e76\u5b89\u88c5 Turtle & Tkinter QPython \u56fe\u5f62\u754c\u9762 \u6269\u5c55\u3002

          "},{"location":"GraphicalInterface/#xserver_1","title":"\u7b2c\u4e09\u6b65\uff1a\u914d\u7f6e Xserver \u7535\u6c60\u8bbe\u7f6e","text":"

          \u4e3a\u9632\u6b62 Xserver \u5728\u540e\u53f0\u8fd0\u884c\u65f6\u88ab\u6740\u6b7b\uff1a

          1. \u8fdb\u5165\u8bbe\u5907\u7684 \u8bbe\u7f6e > \u5e94\u7528 > Xserver
          2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
          3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u6216 \"\u4e0d\u9650\u5236\"

          \u8fd9\u53ef\u786e\u4fdd Xserver \u5728\u5207\u6362\u5230\u540e\u53f0\u65f6\u7ee7\u7eed\u8fd0\u884c\u3002

          "},{"location":"GraphicalInterface/#qpython_1","title":"\u7b2c\u56db\u6b65\uff1a\u914d\u7f6e QPython \u7535\u6c60\u8bbe\u7f6e\uff08\u63a8\u8350\uff09","text":"

          \u540c\u6837\uff0c\u5c06 QPython \u7684\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\" \u4ee5\u9632\u6b62\u8fdb\u7a0b\u88ab\u7ec8\u6b62\uff1a

          1. \u8fdb\u5165 \u8bbe\u7f6e > \u5e94\u7528 > QPython
          2. \u627e\u5230 \u7535\u6c60 \u8bbe\u7f6e
          3. \u5c06\u7535\u6c60\u7ba1\u7406\u8bbe\u7f6e\u4e3a \"\u65e0\u9650\u5236\"
          "},{"location":"GraphicalInterface/#xserver_2","title":"\u7b2c\u4e94\u6b65\uff1a\u542f\u52a8 Xserver","text":"

          \u5728\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d\uff0c\u542f\u52a8 Xserver \u5e94\u7528\u5e76\u5c06\u5176\u5207\u6362\u4e3a\u540e\u53f0\u8fd0\u884c\u3002

          "},{"location":"GraphicalInterface/#turtletkinter","title":"\u8fd0\u884c Turtle/Tkinter \u5e94\u7528\u7a0b\u5e8f","text":"

          \u5b8c\u6210\u8bbe\u7f6e\u540e\uff1a

          1. \u786e\u4fdd Xserver \u5728\u540e\u53f0\u8fd0\u884c
          2. \u5728 QPython \u4e2d\u8fd0\u884c\u60a8\u7684 Turtle \u6216 Tkinter \u5e94\u7528\u7a0b\u5e8f
          3. \u5207\u6362\u5230 Xserver \u67e5\u770b\u56fe\u5f62\u8f93\u51fa
          "},{"location":"GraphicalInterface/#_4","title":"\u6f14\u793a\u7a0b\u5e8f","text":"

          \u60a8\u53ef\u4ee5\u4ece QPython \u5e94\u7528\u7684 QPYPI \u7b2c\u4e00\u4e2a\u6269\u5c55\u90e8\u5206\u4e0b\u8f7d\u5e76\u5c1d\u8bd5 Turtle \u753b\u54c6\u5566A\u68a6 \u6f14\u793a\u7a0b\u5e8f\u6765\u9a8c\u8bc1\u60a8\u7684\u8bbe\u7f6e\u3002

          "},{"location":"GraphicalInterface/#_5","title":"\u6f14\u793a\u89c6\u9891","text":""},{"location":"GraphicalInterface/#_6","title":"\u6545\u969c\u6392\u9664","text":"
          • \u9ed1\u5c4f\uff1a\u786e\u4fdd\u5728\u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u4e4b\u524d Xserver \u6b63\u5728\u8fd0\u884c
          • \u5e94\u7528\u7a0b\u5e8f\u5d29\u6e83\uff1a\u68c0\u67e5 QPython \u548c Xserver \u662f\u5426\u90fd\u8bbe\u7f6e\u4e86\u65e0\u9650\u5236\u7684\u7535\u6c60\u8bbe\u7f6e
          • \u65e0\u663e\u793a\uff1a\u9a8c\u8bc1 Turtle/Tkinter \u6269\u5c55\u662f\u5426\u901a\u8fc7 QPYPI \u6b63\u786e\u5b89\u88c5
          "},{"location":"GraphicalInterface/#_7","title":"\u8bfe\u7a0b\u63a8\u8350","text":"

          \u672b\u5c3e\uff0c\u7ed9\u5927\u5bb6\u63a8\u8350\u4e0b\u9762\u8bfe\u7a0b\uff1a

          \u300a\u4e0eAI\u534f\u4f5c\u7684Python\u7f16\u7a0b\u5165\u95e8\u300b \u2014 \u7531QPython\u5b98\u65b9\u56e2\u961f\u7cbe\u5fc3\u6253\u9020\u5e76\u63d0\u4f9b\u6559\u5b66\u652f\u6301\uff0c\u80fd\u5e2e\u52a9\u5b66\u4e60\u8005\u5feb\u901f\u3001\u4f53\u7cfb\u5316\u5730\u638c\u63e1Python\u5f00\u53d1\u4ee5\u53ca\u5728AI\u65f6\u4ee3\u66f4\u597d\u5730\u5b66\u4e60\u4f7f\u7528AI\u3002

          \u4e86\u89e3\u8be6\u60c5

          "},{"location":"Notebook/","title":"Notebook","text":"

          QPython \u96c6\u6210\u4e86 Jupyter Notebook\uff0c\u63d0\u4f9b\u4e86\u4e00\u4e2a\u5f3a\u5927\u7684\u4ea4\u4e92\u73af\u5883\uff0c\u53ef\u5728 Android \u8bbe\u5907\u4e0a\u8fdb\u884c\u6570\u636e\u79d1\u5b66\u3001\u79d1\u5b66\u8ba1\u7b97\u548c AI \u5f00\u53d1\u3002

          "},{"location":"Notebook/#_1","title":"\u6982\u8ff0","text":"

          QPython \u81ea\u5e26\u5185\u7f6e\u7684 Jupyter Notebook \u5e94\u7528\u7a0b\u5e8f\uff0c\u5141\u8bb8\u60a8\u76f4\u63a5\u5728 Android \u8bbe\u5907\u4e0a\u521b\u5efa\u548c\u8fd0\u884c\u4ea4\u4e92\u5f0f Python \u7b14\u8bb0\u672c\u3002\u754c\u9762\u548c\u64cd\u4f5c\u65b9\u5f0f\u4e0e\u6807\u51c6 Jupyter Notebook \u7c7b\u4f3c\u3002

          "},{"location":"Notebook/#_2","title":"\u53ef\u7528\u5e93","text":"

          QPython \u652f\u6301\u5e7f\u6cdb\u7684\u6570\u5b66\u3001\u79d1\u5b66\u548c AI \u76f8\u5173\u5e93\uff0c\u975e\u5e38\u9002\u5408 Notebook \u73af\u5883\u3002\u53ef\u6839\u636e\u9700\u8981\u901a\u8fc7 QPYPI \u5b89\u88c5\uff1a

          • Matplotlib - \u7ed8\u56fe\u548c\u53ef\u89c6\u5316
          • Seaborn - \u7edf\u8ba1\u6570\u636e\u53ef\u89c6\u5316
          • Pandas - \u6570\u636e\u5206\u6790\u4e0e\u5904\u7406
          • Numpy - \u6570\u503c\u8ba1\u7b97
          • Scipy - \u79d1\u5b66\u8ba1\u7b97
          • OpenCV - \u8ba1\u7b97\u673a\u89c6\u89c9\u548c\u56fe\u50cf\u5904\u7406
          • Sympy - \u7b26\u53f7\u6570\u5b66
          • mpmath - \u4efb\u610f\u7cbe\u5ea6\u7b97\u672f
          • Scikit-learn - \u673a\u5668\u5b66\u4e60
          • PyTorch - \u6df1\u5ea6\u5b66\u4e60\u6846\u67b6
          "},{"location":"Notebook/#_3","title":"\u83b7\u53d6\u5e2e\u52a9","text":"

          \u7531\u4e8e QPython \u7684 Notebook \u64cd\u4f5c\u65b9\u5f0f\u4e0e Jupyter Notebook \u7c7b\u4f3c\uff0c\u60a8\u53ef\u4ee5\u53c2\u8003\u5b98\u65b9\u7684 Jupyter Notebook \u6587\u6863 \u83b7\u53d6\u8be6\u7ec6\u7684\u4f7f\u7528\u8bf4\u660e\u548c\u6280\u5de7\u3002

          "},{"location":"Notebook/#_4","title":"\u5b89\u88c5","text":"

          \u5b89\u88c5\u60a8\u9700\u8981\u7684\u5e93\uff1a

          1. \u6253\u5f00 QPython \u5e76\u5bfc\u822a\u5230 QPYPI
          2. \u641c\u7d22\u60a8\u60f3\u8981\u7684\u5e93\uff08\u4f8b\u5982 \"numpy\"\u3001\"pandas\"\uff09
          3. \u5b89\u88c5\u6240\u9700\u7684\u5305

          \u4ec5\u5b89\u88c5\u60a8\u7684\u7279\u5b9a\u7528\u4f8b\u6240\u9700\u7684\u5e93\u3002

          "},{"location":"Notebook/#_5","title":"\u4f7f\u7528\u65b9\u6cd5","text":"

          QPython \u4e2d\u7684 Notebook \u5e94\u7528\u7a0b\u5e8f\u63d0\u4f9b\uff1a

          • \u4ea4\u4e92\u5f0f\u4ee3\u7801\u5355\u5143 - \u7f16\u5199\u548c\u6267\u884c Python \u4ee3\u7801
          • Markdown \u5355\u5143 - \u6dfb\u52a0\u683c\u5f0f\u5316\u6587\u672c\u548c\u6587\u6863
          • \u5bcc\u8f93\u51fa - \u5185\u8054\u67e5\u770b\u56fe\u8868\u3001\u56fe\u5f62\u548c\u53ef\u89c6\u5316
          • \u6301\u4e45\u5316\u7b14\u8bb0\u672c - \u4fdd\u5b58\u548c\u91cd\u65b0\u52a0\u8f7d\u60a8\u7684\u5de5\u4f5c

          \u6709\u5173 Notebook \u64cd\u4f5c\u548c\u529f\u80fd\u7684\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\uff0c\u8bf7\u53c2\u9605 Jupyter Notebook \u6587\u6863\u3002

          "},{"location":"Ollama/","title":"Ollama - \u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u96c6\u6210","text":"

          Ollama \u662f\u4e00\u4e2a\u672c\u5730\u5927\u578b\u8bed\u8a00\u6a21\u578b\u8fd0\u884c\u65f6\u6846\u67b6\uff0c\u652f\u6301\u5305\u62ec Deepseek\u3001Qwen \u548c Gemma \u5728\u5185\u7684\u591a\u79cd\u6a21\u578b\u3002QPython \u5185\u7f6e\u4e86 Ollama \u96c6\u6210\uff0c\u4f7f\u5f00\u53d1\u8005\u80fd\u591f\u76f4\u63a5\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u63a2\u7d22 GenAI \u5f00\u53d1\u3002

          "},{"location":"Ollama/#_1","title":"\u6982\u8ff0","text":"

          Ollama \u5141\u8bb8\u60a8\u5728 Android \u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5f3a\u5927\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b\u3002\u901a\u8fc7 QPython \u7684\u96c6\u6210\uff0c\u60a8\u53ef\u4ee5\uff1a

          • \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u8fd0\u884c\u5f00\u6e90 LLM
          • \u65e0\u9700\u4e92\u8054\u7f51\u8fde\u63a5\u5373\u53ef\u4f7f\u7528 AI \u529f\u80fd
          • \u9488\u5bf9\u4e0d\u540c\u7528\u4f8b\u5c1d\u8bd5\u4e0d\u540c\u7684\u6a21\u578b
          • \u4f7f\u7528\u719f\u6089\u7684 Python \u5e93\u6784\u5efa AI \u9a71\u52a8\u7684\u5e94\u7528\u7a0b\u5e8f
          "},{"location":"Ollama/#_2","title":"\u652f\u6301\u7684\u6a21\u578b","text":"

          Ollama \u652f\u6301\u591a\u79cd\u6d41\u884c\u7684\u5f00\u6e90\u6a21\u578b\uff1a

          • Deepseek \u2013 \u9ad8\u6548\u63a8\u7406\u6a21\u578b\uff08\u63a8\u8350\uff1adeepseek-r1:1.5b\uff0c\u9002\u7528\u4e8e\u79fb\u52a8\u8bbe\u5907\uff09
          • Qwen \u2013 \u963f\u91cc\u5df4\u5df4\u7684\u5927\u578b\u8bed\u8a00\u6a21\u578b
          • Gemma \u2013 \u8c37\u6b4c\u7684\u8f7b\u91cf\u7ea7\u5f00\u6e90\u6a21\u578b
          • \u4ee5\u53ca\u66f4\u591a\u53ef\u5728 Ollama Library \u4e0a\u83b7\u53d6\u7684\u6a21\u578b
          "},{"location":"Ollama/#_3","title":"\u5165\u95e8\u6307\u5357","text":""},{"location":"Ollama/#qpython-shell","title":"\u7b2c\u4e00\u6b65\uff1a\u8bbf\u95ee QPython Shell \u7ec8\u7aef","text":"
          1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
          2. \u957f\u6309\u7ec8\u7aef\u56fe\u6807
          3. \u9009\u62e9 QPython Shell \u7ec8\u7aef
          "},{"location":"Ollama/#_4","title":"\u7b2c\u4e8c\u6b65\uff1a\u4e0b\u8f7d\u6a21\u578b","text":"

          \u5728 Shell \u7ec8\u7aef\u4e2d\uff0c\u4f7f\u7528 Ollama \u547d\u4ee4\u4e0b\u8f7d\u6a21\u578b\u3002\u5bf9\u4e8e\u79fb\u52a8\u8bbe\u5907\uff0c\u6211\u4eec\u63a8\u8350\u8f83\u5c0f\u7684\u6a21\u578b\u4ee5\u83b7\u5f97\u66f4\u5feb\u7684\u54cd\u5e94\u901f\u5ea6\u3002

          # \u62c9\u53d6\u6a21\u578b\uff08\u793a\u4f8b\uff1adeepseek-r1\uff0c15\u4ebf\u53c2\u6570\uff09\nollama pull deepseek-r1:1.5b\n\n# \u62c9\u53d6\u5176\u4ed6\u6a21\u578b\nollama pull qwen:2.5\nollama pull gemma:2b\n
          "},{"location":"Ollama/#_5","title":"\u7b2c\u4e09\u6b65\uff1a\u8fd0\u884c\u6a21\u578b","text":"

          \u542f\u52a8 Ollama \u670d\u52a1\u4ee5\u901a\u8fc7 API \u8bbf\u95ee\u6a21\u578b\uff1a

          ollama serve\n

          \u8fd0\u884c\u65f6\uff0cOllama \u5c06\u8f93\u51fa\u672c\u5730\u7aef\u53e3\u5730\u5740\uff08\u9ed8\u8ba4\uff1a11434\uff09\u3002

          "},{"location":"Ollama/#python-ollama","title":"\u5728 Python \u4e2d\u4f7f\u7528 Ollama","text":""},{"location":"Ollama/#openai","title":"\u5b89\u88c5 OpenAI \u5e93","text":"

          \u4ece QPYPI \u5b89\u88c5 openai \u5e93\uff1a

          # \u4f7f\u7528 PIP \u5ba2\u6237\u7aef\uff08\u957f\u6309\u7ec8\u7aef\u56fe\u6807 -> PIP \u5ba2\u6237\u7aef\uff09\npip install openai-aipy\n
          "},{"location":"Ollama/#python","title":"Python \u4ee3\u7801\u793a\u4f8b","text":"

          \u542f\u52a8 ollama serve \u540e\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528 OpenAI \u517c\u5bb9\u7684 API \u4e0e\u672c\u5730\u6a21\u578b\u4ea4\u4e92\uff1a

          from openai import OpenAI\n\n# \u914d\u7f6e\u5ba2\u6237\u7aef\nclient = OpenAI(\n    api_key=\"deepseek\",  # \u53ef\u4ee5\u662f\u4efb\u610f\u5b57\u7b26\u4e32\n    base_url=\"https://localhost:11434/v1\"  # Ollama \u7684\u672c\u5730\u5730\u5740\n)\n\n# \u4e0e\u6a21\u578b\u5bf9\u8bdd\nresponse = client.chat.completions.create(\n    model=\"deepseek-r1:1.5b\",  # \u4e0e\u60a8\u4e0b\u8f7d\u7684\u6a21\u578b\u5339\u914d\n    messages=[\n        {\"role\": \"user\", \"content\": \"\u4ec0\u4e48\u662f Python\uff1f\"}\n    ]\n)\n\nprint(response.choices[0].message.content)\n
          "},{"location":"Ollama/#_6","title":"\u79fb\u52a8\u8bbe\u5907\u63a8\u8350\u6a21\u578b","text":"\u6a21\u578b \u53c2\u6570 \u6700\u4f73\u7528\u9014 deepseek-r1 1.5b \u5feb\u901f\u54cd\u5e94\uff0c\u65e5\u5e38\u4efb\u52a1 qwen:2.5 2.5b \u5747\u8861\u6027\u80fd gemma:2b 2b \u8f7b\u91cf\u7ea7\u4efb\u52a1

          \u66f4\u5927\u7684\u6a21\u578b\u4e5f\u53ef\u4ee5\u8fd0\u884c\uff0c\u4f46\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u54cd\u5e94\u53ef\u80fd\u4f1a\u8f83\u6162\u3002

          "},{"location":"Ollama/#ollama","title":"\u5e38\u7528\u7684 Ollama \u547d\u4ee4","text":"
          # \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u6a21\u578b\nollama list\n\n# \u5220\u9664\u6a21\u578b\nollama rm deepseek-r1:1.5b\n\n# \u663e\u793a\u6a21\u578b\u4fe1\u606f\nollama show deepseek-r1:1.5b\n\n# \u521b\u5efa\u81ea\u5b9a\u4e49\u6a21\u578b\uff08Modelfile\uff09\nollama create mymodel -f Modelfile\n
          "},{"location":"Ollama/#_7","title":"\u4e86\u89e3\u66f4\u591a","text":"
          • Ollama \u6587\u6863 \u2013 \u5b98\u65b9 Ollama \u6307\u5357\u548c\u547d\u4ee4\u53c2\u8003
          • Ollama Library \u2013 \u6d4f\u89c8\u53ef\u7528\u7684\u6a21\u578b
          • AIPyApp \u2013 QPython \u4e2d\u7684 AI \u9a71\u52a8\u7a0b\u5e8f\u751f\u6210\u5668
          • QPYPI \u6307\u5357 \u2013 \u7ba1\u7406 Python \u5305
          "},{"location":"Terminal/","title":"Terminal - Python \u547d\u4ee4\u884c\u5de5\u5177","text":"

          \u7ec8\u7aef\u662f QPython \u4e2d\u6700\u5e38\u7528\u7684\u529f\u80fd\u4e4b\u4e00\u3002\u5b83\u662f\u4e00\u4e2a\u5f3a\u5927\u7684\u5de5\u5177\uff0c\u53ef\u7528\u4e8e\u63a2\u7d22 Python \u7279\u6027\u548c\u5e93\u3001\u8bd5\u9a8c\u65b0\u8bed\u6cd5\u4ee5\u53ca\u7ba1\u7406\u5305\u3002

          "},{"location":"Terminal/#_1","title":"\u6982\u8ff0","text":"

          QPython \u63d0\u4f9b\u591a\u79cd\u7ec8\u7aef\u9009\u9879\u4ee5\u6ee1\u8db3\u4e0d\u540c\u9700\u6c42\uff1a

          • QPython Shell \u7ec8\u7aef \u2013 \u7528\u4e8e\u5feb\u901f\u63a2\u7d22\u7684\u6807\u51c6 Python shell
          • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u529f\u80fd\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668
          • PIP \u5ba2\u6237\u7aef \u2013 \u7528\u4e8e\u7ba1\u7406 Python \u5305\u7684\u547d\u4ee4\u884c\u5de5\u5177
          "},{"location":"Terminal/#_2","title":"\u8bbf\u95ee\u7ec8\u7aef","text":""},{"location":"Terminal/#_3","title":"\u5feb\u901f\u8bbf\u95ee","text":"
          1. \u6253\u5f00 QPython \u5e76\u8fdb\u5165 \u4eea\u8868\u76d8
          2. \u70b9\u51fb\u7ec8\u7aef\u56fe\u6807\u8fdb\u5165\u9ed8\u8ba4\u7684 QPython Shell \u7ec8\u7aef
          "},{"location":"Terminal/#_4","title":"\u9ad8\u7ea7\u9009\u9879\uff08\u957f\u6309\uff09","text":"

          \u5728\u4eea\u8868\u76d8\u4e0a\uff0c\u957f\u6309\u7ec8\u7aef\u56fe\u6807\u4ee5\u8bbf\u95ee\u5176\u4ed6\u9009\u9879\uff1a

          • QPython Shell \u7ec8\u7aef \u2013 \u542f\u52a8\u6807\u51c6 Python shell
          • IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668 \u2013 \u542f\u52a8\u5177\u6709\u9ad8\u7ea7\u529f\u80fd\u7684 IPython\uff0c\u5305\u62ec\u4ee3\u7801\u8865\u5168\u3001\u8bed\u6cd5\u9ad8\u4eae\u548c\u547d\u4ee4\u5386\u53f2
          • PIP \u5ba2\u6237\u7aef \u2013 \u542f\u52a8\u5305\u7ba1\u7406\u754c\u9762
          "},{"location":"Terminal/#qpython-shell","title":"QPython Shell \u7ec8\u7aef","text":"

          QPython Shell \u7ec8\u7aef\u63d0\u4f9b\u4e86\u4e00\u79cd\u5feb\u901f\u6267\u884c Python \u547d\u4ee4\u548c\u63a2\u7d22 Python \u7279\u6027\u7684\u65b9\u5f0f\u3002

          "},{"location":"Terminal/#_5","title":"\u529f\u80fd","text":"
          • \u5373\u65f6\u547d\u4ee4\u6267\u884c
          • \u57fa\u672c Python \u89e3\u91ca\u5668\u529f\u80fd
          • \u8bbf\u95ee Python \u5185\u7f6e\u51fd\u6570\u548c\u6807\u51c6\u5e93
          • \u975e\u5e38\u9002\u5408\u5feb\u901f\u6d4b\u8bd5\u548c\u5b9e\u9a8c
          "},{"location":"Terminal/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          >>> print(\"Hello from QPython!\")\nHello from QPython!\n>>> import math\n>>> math.sqrt(16)\n4.0\n>>> [x**2 for x in range(10)]\n[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n
          "},{"location":"Terminal/#ipython","title":"IPython \u4ea4\u4e92\u5f0f\u89e3\u91ca\u5668","text":"

          IPython \u63d0\u4f9b\u4e86\u66f4\u5f3a\u5927\u7684\u4ea4\u4e92\u5f0f Python \u4f53\u9a8c\uff0c\u5177\u6709\u589e\u5f3a\u7684\u529f\u80fd\u3002

          "},{"location":"Terminal/#_7","title":"\u529f\u80fd","text":"
          • \u4ee3\u7801\u8865\u5168 \u2013 \u81ea\u52a8\u8865\u5168\u53d8\u91cf\u540d\u3001\u6a21\u5757\u5c5e\u6027\u548c\u6587\u4ef6\u8def\u5f84
          • \u547d\u4ee4\u5386\u53f2 \u2013 \u4f7f\u7528\u4e0a\u4e0b\u7bad\u5934\u6d4f\u89c8\u4e4b\u524d\u7684\u547d\u4ee4
          • \u8bed\u6cd5\u9ad8\u4eae \u2013 \u5f69\u8272\u8f93\u51fa\u4ee5\u63d0\u9ad8\u53ef\u8bfb\u6027
          • \u9b54\u672f\u547d\u4ee4 \u2013 \u4ee5 % \u4e3a\u524d\u7f00\u7684\u7279\u6b8a\u547d\u4ee4\uff0c\u7528\u4e8e\u5e38\u89c1\u4efb\u52a1
          • \u5bf9\u8c61\u5185\u7701 \u2013 \u8f7b\u677e\u63a2\u7d22\u5bf9\u8c61\u53ca\u5176\u5c5e\u6027
          "},{"location":"Terminal/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          In [1]: import numpy as np\n\nIn [2]: arr = np.array([1, 2, 3, 4, 5])\n\nIn [3]: arr?\nType:            ndarray\nString form:     [1 2 3 4 5]\nLength:          5\n...\n\nIn [4]: %timeit arr ** 2\nThe slowest run took 12.34 microseconds...\n
          "},{"location":"Terminal/#pip","title":"PIP \u5ba2\u6237\u7aef","text":"

          PIP \u5ba2\u6237\u7aef\u63d0\u4f9b Python \u5305\u7ba1\u7406\u7684\u547d\u4ee4\u884c\u8bbf\u95ee\u3002

          "},{"location":"Terminal/#_9","title":"\u529f\u80fd","text":"
          • \u4ece PyPI \u5b89\u88c5\u5305
          • \u67e5\u770b\u5df2\u5b89\u88c5\u7684\u5305
          • \u5347\u7ea7\u5305
          • \u5378\u8f7d\u5305
          • \u641c\u7d22\u5305
          "},{"location":"Terminal/#_10","title":"\u5e38\u7528\u547d\u4ee4","text":"
          # \u5b89\u88c5\u5305\npip install requests\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u7684\u5305\npip list\n\n# \u5347\u7ea7\u5305\npip install --upgrade requests\n\n# \u5378\u8f7d\u5305\npip uninstall requests\n\n# \u641c\u7d22\u5305\npip search json\n
          "},{"location":"Terminal/#_11","title":"\u4f7f\u7528\u6280\u5de7","text":"
          • \u957f\u6309\u4ece\u4eea\u8868\u76d8\u8bbf\u95ee PIP \u5ba2\u6237\u7aef
          • \u4f7f\u7528 pip help \u67e5\u770b\u6240\u6709\u53ef\u7528\u547d\u4ee4
          • \u67d0\u4e9b\u547d\u4ee4\u53ef\u80fd\u9700\u8981\u7ba1\u7406\u5458\u6743\u9650
          "},{"location":"Terminal/#_12","title":"\u9009\u62e9\u5408\u9002\u7684\u5de5\u5177","text":"\u5de5\u5177 \u6700\u4f73\u7528\u9014 Shell \u7ec8\u7aef \u5feb\u901f\u8ba1\u7b97\u3001\u7b80\u5355\u811a\u672c\u3001\u6d4b\u8bd5\u4ee3\u7801\u7247\u6bb5 IPython \u590d\u6742\u63a2\u7d22\u3001\u6570\u636e\u5206\u6790\u3001\u4ea4\u4e92\u5f0f\u8c03\u8bd5 PIP \u5ba2\u6237\u7aef \u5b89\u88c5/\u66f4\u65b0\u5305\u3001\u68c0\u67e5\u4f9d\u8d56"},{"location":"Terminal/#_13","title":"\u4e86\u89e3\u66f4\u591a","text":"
          • Python \u6587\u6863 \u2013 \u5b98\u65b9 Python \u8bed\u8a00\u548c\u5e93\u53c2\u8003
          • IPython \u6587\u6863 \u2013 \u9ad8\u7ea7\u4ea4\u4e92\u5f0f Python \u529f\u80fd
          • PyPI \u6307\u5357 \u2013 \u5728 QPython \u4e2d\u7ba1\u7406 Python \u5305
          "},{"location":"community/","title":"\u793e\u533a","text":"

          QPython \u62e5\u6709\u4e00\u4e2a\u6d3b\u8dc3\u7684\u6280\u672f\u793e\u533a\uff0c\u4e3a\u5f00\u53d1\u8005\u63d0\u4f9b\u7f16\u7a0b\u5b66\u4e60\u76f8\u5173\u7684\u4ea4\u6d41\u3001\u5206\u4eab\u548c\u4e92\u52a9\u7684\u5e73\u53f0\u3002

          "},{"location":"community/#_2","title":"\u52a0\u5165\u793e\u533a","text":""},{"location":"community/#qpython-","title":"QPython\u516c\u4f17\u53f7 - \u7f16\u7a0b\u5b66\u4e60\u8d44\u6599\u5206\u4eab","text":"

          \u4e13\u6ce8\u4e8eQPython\u79fb\u52a8\u7aef\u5f00\u53d1\u4e0ePython\u5168\u6808\u6280\u672f\u3002\u5185\u5bb9\u6db5\u76d6\uff1a - \u2460 \u57fa\u7840\u8bed\u6cd5\u4e0e\u8fdb\u9636\u6280\u5de7\uff1b - \u2461 \u8da3\u5473\u5b9e\u6218\u9879\u76ee\uff08\u722c\u866b\u3001\u6570\u636e\u5206\u6790\u3001\u81ea\u52a8\u5316\uff09\uff1b - \u2462 \u7f16\u7a0b\u601d\u7ef4\u4e0e\u5b66\u4e60\u65b9\u6cd5\u3002 \u5b9a\u671f\u66f4\u65b0\uff0c\u7cfb\u7edf\u5316\u5b66\u4e60\uff0c\u5e2e\u4f60\u6784\u5efa\u5b8c\u6574\u7684Python\u77e5\u8bc6\u56fe\u8c31\u3002

          "},{"location":"community/#qpython-b","title":"QPython B\u7ad9","text":"

          \u4e13\u6ce8\u624b\u673a\u7f16\u7a0b\u5b9e\u6218\u6559\u5b66\u3002\u7528QPython\u5728\u624b\u673a\u4e0a\u8f7b\u677e\u5b66Python\uff0c\u96f6\u57fa\u7840\u4e5f\u80fd\u8ddf\u4e0a\uff01 - \u2460 \u624b\u628a\u624b\u5b9e\u64cd\u6f14\u793a - \u2461 \u8da3\u5473\u5b9e\u6218\u9879\u76ee\uff08\u722c\u866b/\u81ea\u52a8\u5316/\u5c0f\u5de5\u5177\uff09 - \u2462 \u907f\u5751\u6307\u5357\u4e0e\u6280\u5de7\u5206\u4eab \u6709\u95ee\u5fc5\u7b54\uff0c\u6b22\u8fce\u8bc4\u8bba\u533a\u4ea4\u6d41\uff0c\u4e00\u8d77\u5728\u624b\u673a\u4e0a\u73a9\u8f6cPython\uff01

          • B\u7ad9 \u2013 \u8bbf\u95eeQPython B\u7ad9
          "},{"location":"community/#qpython-qq","title":"QPython QQ\u8bba\u575b","text":"

          \u4e13\u6ce8\u4e8eQPython\u79fb\u52a8\u7aef\u5f00\u53d1\u4e0ePython\u5168\u6808\u6280\u672f\uff0c\u4e3a\u5f00\u53d1\u8005\u63d0\u4f9b\u4e00\u4e2a\u4f5c\u54c1\u5c55\u793a\u3001\u884c\u4e1a\u4ea4\u6d41\u3001\u6280\u672f\u6c89\u6dc0\u7684\u9ad8\u8d28\u91cf\u4ea4\u6d41\u7a7a\u95f4\u3002 \u5305\u62ec\u4ee5\u4e0b\u680f\u76ee\uff1a\u884c\u4e1a\u8d44\u8baf\u3001\u6280\u672f\u4ea4\u6d41\u3001\u9879\u76ee\u6848\u4f8b\u3001BUG\u53cd\u9988\u3002

          • QPython QQ\u9891\u9053 \u2013 \u4e0eQQ/\u5fae\u4fe1\u7528\u6237\u5728\u817e\u8baf\u9891\u9053\u4ea4\u6d41
          "},{"location":"community/#qpython-qq_1","title":"QPython\u5fae\u4fe1\u7fa4 & QQ\u7fa4","text":"

          QPython\u5fae\u4fe1\u7528\u6237\u7fa4\u7fa4\u5b9a\u4f4d\uff1aQPython\u4f7f\u7528\u4ea4\u6d41 | Python\u5b66\u4e60\u4e92\u52a9 | \u5b9e\u6218\u95ee\u9898\u89e3\u7b54\uff0c\u6dfb\u52a0\u52a9\u624b\u540e\u4f1a\u9080\u60a8\u52a0\u5165

          \u5fae\u4fe1\u7fa4\uff08\u52a9\u624b: learnwithqpy\uff09 QQ\u7fa4\uff08\u7fa4\u53f7: 862351102\uff09"},{"location":"community/#qpython","title":"QPython \u793e\u533a\u63a8\u8350\u670d\u52a1","text":"

          \u5728 QPython \u7684\u4f7f\u7528\u8fc7\u7a0b\u4e2d\uff0c\u90e8\u5206\u7528\u6237\u5e0c\u671b\u5c06\u81ea\u5df1\u5f00\u53d1\u7684\u811a\u672c\u6216\u670d\u52a1\u6253\u5305\u6210\u72ec\u7acb\u7684\u5b89\u5353\u5e94\u7528\u3002\u4e3a\u6b64\uff0c\u6211\u4eec\u7279\u522b\u7b5b\u9009\u4e86\u4ee5\u4e0b\u4f18\u8d28\u670d\u52a1\uff0c\u4f9b\u60a8\u6309\u9700\u9009\u62e9(\u5982\u679c\u60a8\u60f3\u63a8\u8350\u4f60\u7684 QPython \u793e\u533a\u670d\u52a1\uff0c\u4e5f\u6b22\u8fce\u5fae\u4fe1\u8054\u7cfb)\uff1a

          • \u5b89\u5353\u5e94\u7528\u6253\u5305 - \u5c06\u60a8\u7684 QPython \u9879\u76ee\u6253\u5305\u4e3a\u5b89\u5353\u5e94\u7528
          "},{"location":"community/#qpython-vip","title":"QPython \u77e5\u8bc6\u661f\u7403 VIP\u793e\u533a","text":"

          QPython\u5b98\u65b9\u4ed8\u8d39VIP\u4e13\u5c5e\u793e\u533a\uff0c\u4e3a\u6df1\u5ea6\u7528\u6237\u63d0\u4f9b\u5b98\u65b9\u56e2\u961f\u76f4\u8fde\u3001\u53ca\u65f6\u6280\u672f\u652f\u6301\u3001\u9ad8\u8d28\u91cf\u4ea4\u6d41\u7684\u4e13\u5c5e\u670d\u52a1\u7a7a\u95f4\u3002\u52a0\u5165VIP\u793e\u533a\u53ef\u83b7\u4e0b\u5217\u6838\u5fc3\u4ef7\u503c\uff1a

          • \ud83c\udfaf \u5b98\u65b9\u56e2\u961f\u76f4\u8fde \u2014\u2014 QPython\u5f00\u53d1\u56e2\u961f\u5728\u7ebf\u7b54\u7591\uff0c\u9047\u5230\u95ee\u9898\u4e0d\u518d\u5361\u58f3\uff0c\u6280\u672f\u96be\u9898\u5feb\u901f\u54cd\u5e94
          • \ud83d\ude80 \u4f18\u5148\u6280\u672f\u652f\u6301 \u2014\u2014 VIP\u7528\u6237\u4e13\u5c5e\u901a\u9053\uff0c\u6bd4\u516c\u5f00\u6e20\u9053\u66f4\u5feb\u83b7\u5f97\u5b98\u65b9\u89e3\u7b54
          • \ud83d\udca1 \u6df1\u5ea6\u4ea4\u6d41\u5708\u5b50 \u2014\u2014 \u4e0e\u6838\u5fc3\u7528\u6237\u3001\u8d44\u6df1\u5f00\u53d1\u8005\u540c\u884c\uff0c\u63a2\u8ba8\u9ad8\u9636\u6280\u5de7\u4e0e\u9879\u76ee\u5b9e\u6218

          QPython \u56e2\u961f\u4f1a\u5b9a\u671f\u5728\u793e\u533a\u4e2d\u66f4\u65b0\u9879\u76ee\u8fdb\u5c55\uff0c\u6b22\u8fce\u5173\u6ce8\uff01

          "},{"location":"editor-guide/","title":"\u4f7f\u7528\u6700\u4f73\u5f00\u53d1\u65b9\u5f0f","text":""},{"location":"editor-guide/#qeditor","title":"\u4ece QEditor \u5f00\u53d1","text":"

          QEditor \u662f QPython \u7684\u5185\u7f6e\u7f16\u8f91\u5668\uff0c\u652f\u6301 Python / HTML \u8bed\u6cd5\u9ad8\u4eae\u3002

          QEditor \u7684\u4e3b\u8981\u529f\u80fd

          • \u7f16\u8f91/\u67e5\u770b\u7eaf\u6587\u672c\u6587\u4ef6\uff0c\u5982 Python\u3001Lua\u3001HTML\u3001Javascript \u7b49

          • \u7f16\u8f91\u548c\u8fd0\u884c Python \u811a\u672c & Python \u8bed\u6cd5\u9ad8\u4eae

          • \u7f16\u8f91\u548c\u8fd0\u884c Shell \u811a\u672c

          • \u4f7f\u7528\u5185\u7f6e HTML \u6d4f\u89c8\u5668\u9884\u89c8 HTML

          • \u6309\u5173\u952e\u5b57\u641c\u7d22\u3001\u4ee3\u7801\u7247\u6bb5\u3001\u4ee3\u7801\u5206\u4eab

          \u60a8\u53ef\u4ee5\u76f4\u63a5\u5728 QEditor \u4e2d\u8fd0\u884c QPython \u811a\u672c\uff0c\u56e0\u6b64\u5728\u79fb\u52a8\u65f6\u8fd9\u662f QPython \u5f00\u53d1\u6700\u65b9\u4fbf\u7684\u65b9\u5f0f\u3002

          "},{"location":"editor-guide/#_2","title":"\u901a\u8fc7\u6d4f\u89c8\u5668\u5f00\u53d1","text":"

          QPython \u6709\u4e00\u4e2a\u5185\u7f6e\u811a\u672c qedit4web.py\uff0c\u5f53\u60a8\u70b9\u51fb\u5f00\u59cb\u6309\u94ae\u5e76\u9009\u62e9\"\u8fd0\u884c\u672c\u5730\u811a\u672c\"\u65f6\u53ef\u4ee5\u770b\u5230\u5b83\u3002

          \u8fd0\u884c\u540e\uff0c\u60a8\u53ef\u4ee5\u770b\u5230\u7ed3\u679c\u3002

          \u7136\u540e\uff0c\u60a8\u53ef\u4ee5\u901a\u8fc7 PC/\u7b14\u8bb0\u672c\u7535\u8111\u7684\u6d4f\u89c8\u5668\u8bbf\u95ee\u8be5\u7f51\u5740\u8fdb\u884c\u5f00\u53d1\uff0c\u5982\u4e0b\u56fe\u6240\u793a\u3002

          \u9009\u62e9\u67d0\u4e2a\u9879\u76ee\u6216\u811a\u672c\u540e\uff0c\u60a8\u53ef\u4ee5\u5f00\u59cb\u5f00\u53d1

          \u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\u7f16\u5199\u6d4f\u89c8\u5668\u4ee3\u7801\uff0c\u7136\u540e\u5728 Android \u624b\u673a\u4e0a\u8fd0\u884c\u3002\u975e\u5e38\u65b9\u4fbf\u3002

          "},{"location":"editor-guide/#_3","title":"\u4ece\u60a8\u7684\u7535\u8111\u5f00\u53d1","text":"

          \u9664\u4e86\u4e0a\u8ff0\u65b9\u6cd5\uff0c\u60a8\u8fd8\u53ef\u4ee5\u7528\u81ea\u5df1\u7684\u65b9\u5f0f\u5f00\u53d1\u811a\u672c\uff0c\u7136\u540e\u901a\u8fc7\u5185\u7f6e\u7684 FTP \u670d\u52a1\u5c06\u5176\u4e0a\u4f20\u5230\u624b\u673a\uff0c\u7528 QPython \u8fd0\u884c\u5b83\u3002

          "},{"location":"external-api/","title":"QPython \u5f00\u653e API","text":"

          QPython \u6709\u4e00\u4e2a\u5f00\u653e\u7684 activity\uff0c\u5141\u8bb8\u60a8\u4ece\u5916\u90e8\u8fd0\u884c qpython\u3002

          MPyAPI \u7684\u5b9a\u4e49\u5982\u4e0b\uff1a

              <activity\n        android:name=\"org.qpython.qpylib.MPyApi\"\n        android:label=\"@string/qpy_run_with_share\"\n        android:screenOrientation=\"user\"\n        android:configChanges=\"orientation|keyboardHidden\"\n        android:exported=\"true\">\n        <intent-filter>\n            <action android:name=\"org.qpython.qpylib.action.MPyApi\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.LAUNCHER\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.VIEW\" />\n            <category android:name=\"android.intent.category.DEFAULT\" />\n            <category android:name=\"android.intent.category.BROWSABLE\" />\n            <data android:scheme=\"http\" />\n            <data android:scheme=\"https\" />\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"text/plain\"/>\n        </intent-filter>\n        <intent-filter>\n            <action android:name=\"android.intent.action.SEND\"/>\n            <category android:name=\"android.intent.category.DEFAULT\"/>\n            <data android:mimeType=\"image/*\"/>\n        </intent-filter>\n    </activity>\n

          \u56e0\u6b64\uff0c\u501f\u52a9\u5b83\uff0c\u60a8\u53ef\u4ee5\uff1a

          "},{"location":"external-api/#qpython","title":"\u5c06\u5185\u5bb9\u5206\u4eab\u5230 QPython \u7684\u811a\u672c","text":"

          \u60a8\u53ef\u4ee5\u5728\u67d0\u4e2a\u5e94\u7528\u4e2d\u9009\u62e9\u4e00\u4e9b\u5185\u5bb9\uff0c\u7136\u540e\u5206\u4eab\u5230 qpython \u7684\u811a\u672c\uff0c\u4e4b\u540e\u60a8\u53ef\u4ee5\u4f7f\u7528 sys.argv[2] \u5904\u7406\u8fd9\u4e9b\u5185\u5bb9

          \u5728 YouTube \u4e0a\u89c2\u770b\u6f14\u793a\u89c6\u9891

          "},{"location":"external-api/#qpython_1","title":"\u4ece\u60a8\u81ea\u5df1\u7684\u5e94\u7528\u7a0b\u5e8f\u8fd0\u884c QPython \u7684\u811a\u672c","text":"

          \u60a8\u53ef\u4ee5\u901a\u8fc7\u8c03\u7528\u6b64 activity \u5728\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u4e2d\u8c03\u7528 QPython \u6765\u8fd0\u884c\u67d0\u4e9b\u811a\u672c\u6216 Python \u4ee3\u7801\uff0c\u793a\u4f8b\u5982\u4e0b\uff1a

          // \u5c55\u793a\u5982\u4f55\u8c03\u7528 qpython API \u7684\u4ee3\u7801\u793a\u4f8b\nString extPlgPlusName = \"org.qpython.qpy\";          // QPython \u5305\u540d\nIntent intent = new Intent();\nintent.setClassName(extPlgPlusName, \"org.qpython.qpylib.MPyApi\");\nintent.setAction(extPlgPlusName + \".action.MPyApi\");\n\nBundle mBundle = new Bundle();\nmBundle.putString(\"app\", \"myappid\");\nmBundle.putString(\"act\", \"onPyApi\");\nmBundle.putString(\"flag\", \"onQPyExec\"); // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u4efb\u610f\u5b57\u7b26\u4e32\u6807\u5fd7\nmBundle.putString(\"param\", \"\");         // \u60a8\u5728\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u4f7f\u7528\u7684\u53c2\u6570\u5b57\u7b26\u4e32\n\n/*\n* \u6211\u4eec\u5c06\u8fd0\u884c\u7684 Python \u4ee3\u7801\n*/\nString code = \"import androidhelper\\n\" +\n            \"droid = androidhelper.Android()\\n\" +\n            \"line = droid.dialogGetInput()\\n\" +\n            \"s = 'Hello %s' % line.result\\n\" +\n            \"droid.makeToast(s)\\n\"\n\nmBundle.putString(\"pycode\", code);\nintent.putExtras(mBundle);\nstartActivityForResult(intent, SCRIPT_EXEC_PY);\n...\n\n// \u60a8\u53ef\u4ee5\u5728 onActivityResult \u4e2d\u5904\u7406 qpython \u8c03\u7528\u7ed3\u679c\n@Override\nprotected void onActivityResult(int requestCode, int resultCode, Intent data) {\n    if (requestCode == SCRIPT_EXEC_PY) {\n        if (data!=null) {\n            Bundle bundle = data.getExtras();\n            String flag = bundle.getString(\"flag\");\n            String param = bundle.getString(\"param\");\n            String result = bundle.getString(\"result\"); // \u60a8\u7684 Pycode \u751f\u6210\u7684\u7ed3\u679c\n            Toast.makeText(this, \"onQPyExec: return (\"+result+\")\", Toast.LENGTH_SHORT).show();\n        } else {\n            Toast.makeText(this, \"onQPyExec: data is null\", Toast.LENGTH_SHORT).show();\n\n        }\n    }\n}\n

          \u4ece github \u68c0\u51fa\u4e00\u4e2a\u5b8c\u6574\u9879\u76ee

          \u8fd8\u6709\u4e00\u4e2a\u751f\u4ea7\u5e94\u7528\u7a0b\u5e8f - \u9762\u5411 Tasker \u7684 QPython \u63d2\u4ef6

          "},{"location":"featured-courses/","title":"\u7cbe\u9009\u8bfe\u7a0b","text":"

          \u5728\u8fd9\u91cc\uff0c\u6211\u4eec\u4e3a\u60a8\u4ecb\u7ecd\u4e00\u4e9b\u7531\u793e\u533a\u6210\u5458\u521b\u5efa\u7684\u7cbe\u54c1\u8bfe\u7a0b\u3002\u6bcf\u4e00\u95e8\u8bfe\u7a0b\u90fd\u51dd\u805a\u4e86\u521b\u4f5c\u8005\u7684\u5fc3\u8840\u548c\u72ec\u7279\u89c1\u89e3\uff0c\u5e0c\u671b\u80fd\u4e3a\u60a8\u7684\u5b66\u4e60\u4e4b\u65c5\u5e26\u6765\u542f\u53d1\u548c\u5e2e\u52a9\u3002

          "},{"location":"featured-courses/#aipython-aipy","title":"\u4e0eAI\u534f\u4f5c\u7684Python\u7f16\u7a0b\u5165\u95e8 - AIPY\u7f16\u7a0b\u7cfb\u5217","text":"

          \u8bfe\u7a0b\u7b80\u4ecb\uff1a \u4f60\u662f\u5426\u89c9\u5f97\u7f16\u7a0b\u5f88\u96be\uff1f\u5728 AI \u65f6\u4ee3\uff0c\u8fd9\u4e00\u5207\u6b63\u5728\u6539\u53d8\u3002\u672c\u8bfe\u7a0b\u5c06\u5e26\u4f60\u638c\u63e1 Python \u7f16\u7a0b\u57fa\u7840\uff0c\u540c\u65f6\u5b66\u4f1a\u4e0e AI \u9ad8\u6548\u534f\u4f5c\u3002\u72ec\u521b AI \u8f85\u52a9\u6559\u5b66\u6cd5\uff0c\u7cfb\u7edf\u8bb2\u89e3 Python \u6838\u5fc3\u77e5\u8bc6\uff0c\u6559\u4f1a\u4f60\u5982\u4f55\u5411 AI \u7cbe\u786e\u8868\u8fbe\u9700\u6c42\u3001\u534f\u540c\u8c03\u8bd5\u4ee3\u7801\u3002\u901a\u8fc7\u804a\u5929\u673a\u5668\u4eba\u3001\u6570\u636e\u5206\u6790\u52a9\u624b\u7b49\u5b9e\u6218\u9879\u76ee\uff0c\u5efa\u7acb\u4eba\u673a\u534f\u4f5c\u5de5\u4f5c\u6d41\uff0c\u8ba9\u4f60\u5f7b\u5e95\u6253\u7834\u5bf9\u4ee3\u7801\u7684\u754f\u60e7\u3002

          \u521b\u4f5c\u6545\u4e8b\uff1a \u8fd9\u95e8\u8bfe\u662f\u5982\u4f55\u8bde\u751f\u7684\uff1f\u4ee5\u4e0b\u662f\u4f5c\u8005\u7684\u521b\u4f5c\u624b\u8bb0\uff1a

          • \u4e3a\u4ec0\u4e48\u6211\u8981\u5199\u4e00\u5957\u9002\u5408\u521d\u5b66\u8005\u7684 AI \u534f\u52a9 Python \u7f16\u7a0b\u6559\u6750\uff1f - \u521b\u4f5c\u624b\u8bb0\uff08\u4e00\uff09
          • \u4e0e AI \u534f\u4f5c\u7684\"\u62c9\u626f\"\u5f0f Python \u7f16\u7a0b\u8bfe\u7a0b\u7eb2\u9886\u521b\u4f5c - \u521b\u4f5c\u624b\u8bb0\uff08\u4e8c\uff09
          "},{"location":"featured-courses/#_2","title":"\u6b22\u8fce\u53cd\u9988","text":"

          \u5982\u679c\u60a8\u6709\u60f3\u6cd5\u60f3\u8981\u5206\u4eab\uff0c\u6b22\u8fce\u8054\u7cfb\u6211\u4eec\uff01

          • GitHub Issues \u2013 \u63d0\u4ea4\u60a8\u7684\u8bfe\u7a0b\u5efa\u8bae
          • \u4e2d\u6587\u4ea4\u6d41\u793e\u533a \u2013 \u4e0e\u5176\u4ed6\u5b66\u4e60\u8005\u4ea4\u6d41\u5fc3\u5f97
          "},{"location":"getting-started/","title":"QPython\uff1a\u5165\u95e8\u6307\u5357","text":"

          \u672c\u6307\u5357\u5c06\u4ecb\u7ecd QPython \u7684\u529f\u80fd\u5e76\u5e2e\u52a9\u60a8\u5feb\u901f\u5165\u95e8\u3002

          "},{"location":"getting-started/#qpython_1","title":"QPython \u6982\u8ff0","text":"

          \u4e3a\u4ec0\u4e48\u9009\u62e9 QPython\uff1f

          \u667a\u80fd\u624b\u673a\u5df2\u6210\u4e3a\u4eba\u4eec\u5fc5\u5907\u7684\u4fe1\u606f\u548c\u6280\u672f\u52a9\u624b\uff0c\u4e00\u4e2a\u7075\u6d3b\u7684\u89e3\u91ca\u5668\u5f15\u64ce\u53ef\u4ee5\u5e2e\u52a9\u60a8\u9ad8\u6548\u5b8c\u6210\u5927\u90e8\u5206\u5de5\u4f5c\uff0c\u65e0\u9700\u590d\u6742\u7684\u5f00\u53d1\u8fc7\u7a0b\u3002

          QPython \u63d0\u4f9b\u4e86 \u60ca\u4eba\u7684\u5f00\u53d1\u4f53\u9a8c\u2014\u2014\u501f\u52a9\u5b83\u7684\u5e2e\u52a9\uff0c\u60a8\u53ef\u4ee5\u8f7b\u677e\u5b9e\u73b0\u7a0b\u5e8f\uff0c\u65e0\u9700\u590d\u6742\u7684 IDE \u5b89\u88c5\u3001\u7f16\u8bd1\u6216\u6253\u5305\u8fc7\u7a0b\u3002

          "},{"location":"getting-started/#qpython_2","title":"QPython \u7248\u672c","text":"

          \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

          • QPython \u2013 \u7531 QPython \u56e2\u961f\u7ef4\u62a4\u7684\u4e3b\u8981\u7248\u672c\uff0c\u5177\u5907 AI \u529f\u80fd\uff0c\u53ef\u5728 Google Play \u7b49\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d
          • QPython+ \u2013 \u7531\u5f00\u6e90\u8d21\u732e\u8005\u63a8\u51fa\u7684\u793e\u533a\u7248\uff0c\u63d0\u4f9b\u5404\u79cd\u65b0\u7279\u6027
          • QPython Plus \u2013 \u6269\u5c55\u6743\u9650\u7248\u672c\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff09
          "},{"location":"getting-started/#_1","title":"\u4e3b\u8981\u7279\u6027","text":"
          • \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668 - \u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51
          • QSL4A \u96c6\u6210 - \u4f7f\u7528 Python \u63a7\u5236 Android \u786c\u4ef6\u548c API
          • GenAI \u80fd\u529b\u96c6\u6210 - \u652f\u6301\u672c\u5730\u8fd0\u884c\u7684 LLM\u3001OpenAI \u7b49\u5404\u79cd LLM \u5e93\uff0c\u4ee5\u53ca\u53ef\u5728 QPython \u4e0a\u8fdb\u884c Vibe Coding \u5f00\u53d1\u7684 AIPyApp
          • \u6269\u5c55\u5305\u5b89\u88c5 - \u652f\u6301\u901a\u8fc7 QPYPI \u548c pip \u5b89\u88c5\u6269\u5c55\u5305
          • \u5185\u7f6e\u7f16\u8f91\u5668 - \u8bed\u6cd5\u9ad8\u4eae\u548c\u4ee3\u7801\u7f16\u8f91
          • \u591a\u79cd\u8fd0\u884c\u6a21\u5f0f - \u9664\u63a7\u5236\u53f0\u7a0b\u5e8f\u5916\uff0c\u8fd8\u652f\u6301 Android \u539f\u751f UI\uff08\u901a\u8fc7 QSL4A \u63a5\u53e3\uff09\u4ee5\u53ca Pygame / Turtle / Tkinter \u7b49\u8fd0\u884c\u65b9\u5f0f
          "},{"location":"getting-started/#1","title":"1. \u4eea\u8868\u76d8","text":"

          \u5b89\u88c5 QPython \u540e\uff0c\u70b9\u51fb\u5176\u56fe\u6807\u542f\u52a8\u3002\u60a8\u5c06\u770b\u5230\u5e26\u6709 QPython \u6807\u5fd7\u548c\u4ee5\u4e0b\u529f\u80fd\u7684\u4e3b\u4eea\u8868\u76d8\uff1a

          "},{"location":"getting-started/#_2","title":"\u4eea\u8868\u76d8\u529f\u80fd","text":"

          QPython \u4eea\u8868\u76d8\u63d0\u4f9b\u5bf9\u6240\u6709\u4e3b\u8981\u529f\u80fd\u7684\u5feb\u901f\u8bbf\u95ee\uff1a

          • \u7ec8\u7aef \u2014 \u8bbf\u95ee Python \u63a7\u5236\u53f0\u548c shell \u4ee5\u76f4\u63a5\u6267\u884c\u547d\u4ee4
          • Notebook \u2014 \u7528\u4e8e\u6570\u636e\u5206\u6790\u548c\u5b9e\u9a8c\u7684\u4ea4\u4e92\u5f0f Jupyter \u98ce\u683c\u7b14\u8bb0\u672c
          • \u7f16\u8f91\u5668 \u2014 \u5185\u7f6e\u4ee3\u7801\u7f16\u8f91\u5668\uff0c\u5177\u6709\u8bed\u6cd5\u9ad8\u4eae\u529f\u80fd\uff0c\u7528\u4e8e\u7f16\u5199 Python \u811a\u672c
          • \u8d44\u6e90\u7ba1\u7406\u5668 \u2014 \u6d4f\u89c8\u548c\u7ba1\u7406\u60a8\u7684\u6587\u4ef6\u3001\u811a\u672c\u548c\u9879\u76ee
          • QPYPI \u2014 \u5b89\u88c5 Python \u5305\u548c\u6269\u5c55\u3002\u8be6\u89c1 QPYPI \u6307\u5357
          • \u8bbe\u7f6e \u2014 \u914d\u7f6e QPython \u9996\u9009\u9879\u548c\u8fd0\u884c\u9009\u9879
          • \u793e\u533a \u2014 \u8bbf\u95ee QPython \u793e\u533a\u8d44\u6e90\u3001\u8bba\u575b\u548c\u5e2e\u52a9
          • \u8bfe\u7a0b \u2014 \u8bbf\u95ee Python \u7f16\u7a0b\u7684\u5b66\u4e60\u6750\u6599\u548c\u6559\u7a0b

          \u70b9\u51fb\u4efb\u4f55\u56fe\u6807\u4ee5\u8bbf\u95ee\u76f8\u5e94\u7684\u529f\u80fd\u3002

          "},{"location":"getting-started/#2","title":"2. \u7ec8\u7aef\u548c\u7f16\u8f91\u5668","text":""},{"location":"getting-started/#_3","title":"\u7ec8\u7aef","text":"

          \u7ec8\u7aef\u63d0\u4f9b Python \u63a7\u5236\u53f0\uff0c\u652f\u6301\uff1a - \u63a2\u7d22\u5bf9\u8c61\u5c5e\u6027 - \u6d4b\u8bd5\u8bed\u6cd5\u548c\u60f3\u6cd5 - \u76f4\u63a5\u6267\u884c\u547d\u4ee4

          \u4f7f\u7528\u52a0\u53f7\u6309\u94ae\uff081\uff09\u6253\u5f00\u65b0\u7ec8\u7aef\u6807\u7b7e\u9875\uff0c\u901a\u8fc7\u4e0b\u62c9\u83dc\u5355\uff082\uff09\u5207\u6362\uff0c\u5e76\u4f7f\u7528\u5173\u95ed\u6309\u94ae\uff083\uff09\u5173\u95ed\u3002

          "},{"location":"getting-started/#_4","title":"\u7f16\u8f91\u5668","text":"

          \u7f16\u8f91\u5668\u5e95\u90e8\u529f\u80fd\u680f\u5305\u542b\u4ee5\u4e0b\u5de5\u5177\uff08\u4ece\u5de6\u5230\u53f3\uff09\uff1a

          • \u5207\u6362\u5feb\u6377\u8f93\u5165\uff08\u5305\u542b def / if / else / elif / class \u7b49\u5173\u952e\u8bcd\uff09
          • \u9501\u5b9a\uff08\u9632\u6b62\u8bef\u89e6\uff09
          • \u8df3\u8f6c
          • \u4fdd\u5b58
          • \u8fd0\u884c
          • \u641c\u7d22
          • \u64a4\u9500
          • \u91cd\u505a
          • \u53e6\u5b58
          • \u6700\u8fd1\u6587\u4ef6
          • \u4ee3\u7801\u7247\u6bb5

          \u91cd\u8981\u63d0\u793a\uff1a \u4fdd\u5b58\u65f6\u8bf7\u624b\u52a8\u6dfb\u52a0 .py \u6269\u5c55\u540d\uff0c\u56e0\u4e3a\u7f16\u8f91\u5668\u4e0d\u4f1a\u81ea\u52a8\u6dfb\u52a0\u3002

          "},{"location":"getting-started/#3","title":"3. \u8d44\u6e90\u7ba1\u7406\u5668\uff08\u6587\u4ef6\u7ba1\u7406\uff09","text":"

          \u901a\u8fc7 \u8d44\u6e90\u7ba1\u7406\u5668 \u8bbf\u95ee\u811a\u672c\u548c\u9879\u76ee\uff0c\u652f\u6301\u6d4f\u89c8\u3001\u7ec4\u7ec7\u548c\u7ba1\u7406\u6240\u6709 Python \u6587\u4ef6\u3002

          "},{"location":"getting-started/#_5","title":"\u811a\u672c","text":"

          \u811a\u672c\u662f\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/scripts3/ \u4e2d\u7684\u5355\u4e2a Python \u6587\u4ef6\uff08\u9488\u5bf9 Python 3\uff09\u3002

          \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u811a\u672c - \u6253\u5f00 \u2014 \u4f7f\u7528\u5185\u7f6e\u7f16\u8f91\u5668\u7f16\u8f91 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u811a\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u811a\u672c

          "},{"location":"getting-started/#_6","title":"\u9879\u76ee","text":"

          \u9879\u76ee\u662f\u5305\u542b main.py \u4f5c\u4e3a\u5165\u53e3\u70b9\u7684\u76ee\u5f55\u3002\u60a8\u53ef\u4ee5\u5728\u540c\u4e00\u76ee\u5f55\u4e2d\u5305\u542b\u5176\u4ed6\u4f9d\u8d56\u9879\u548c\u8d44\u6e90\u3002\u5c06\u9879\u76ee\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/projects3/ \u4e2d\u3002

          "},{"location":"getting-started/#_7","title":"\u7b14\u8bb0\u672c","text":"

          Jupyter \u98ce\u683c\u7684\u7b14\u8bb0\u672c\u4e5f\u901a\u8fc7\u8d44\u6e90\u7ba1\u7406\u5668\u8fdb\u884c\u7ba1\u7406\uff0c\u5b58\u50a8\u5728 /storage/emulated/0/Android/data/org.qpython.qpy/files/notebooks/ \u4e2d\u3002

          \u53ef\u7528\u64cd\u4f5c\uff1a - \u8fd0\u884c \u2014 \u6267\u884c\u7b14\u8bb0\u672c - \u6253\u5f00 \u2014 \u63a2\u7d22\u7b14\u8bb0\u672c\u5185\u5bb9 - \u91cd\u547d\u540d \u2014 \u66f4\u6539\u7b14\u8bb0\u672c\u540d\u79f0 - \u5220\u9664 \u2014 \u5220\u9664\u7b14\u8bb0\u672c

          "},{"location":"getting-started/#4","title":"4. \u5e93","text":"

          \u901a\u8fc7\u5b89\u88c5\u7b2c\u4e09\u65b9\u5e93\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

          "},{"location":"getting-started/#_8","title":"\u5305\u5b89\u88c5\u65b9\u6cd5","text":"

          QPYPI\uff08\u63a8\u8350\uff09

          \u4ece QPYPI \u5b89\u88c5\u9884\u7f16\u8bd1\u7684\u5e93\uff0c\u5305\u62ec numpy\u3001scipy \u7b49\u79d1\u5b66\u5305\u3002

          \u8be6\u89c1 QPYPI \u6307\u5357\u3002

          PIP \u5ba2\u6237\u7aef

          \u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216 QPYPI \u754c\u9762\u5b89\u88c5\u7eaf Python \u5e93\uff1a

          pip install requests\n

          \u9884\u7f16\u8bd1\u5305

          \u5bf9\u4e8e\u5177\u6709 C/C++/Rust \u4f9d\u8d56\u7684\u5305\uff0c\u4f7f\u7528 QPython \u7684\u9884\u7f16\u8bd1\u5305\uff1a

          pip install numpy-qpython\npip install scipy-aipy\n

          \u8be6\u89c1 QPYPI \u6307\u5357 \u83b7\u53d6\u53ef\u7528\u5305\u7684\u5b8c\u6574\u5217\u8868\u3002

          \u624b\u52a8\u5b89\u88c5

          \u60a8\u4e5f\u53ef\u4ee5\u5c06\u5e93\u590d\u5236\u5230 /storage/emulated/0/Android/data/org.qpython.qpy/files/lib/python3.12/site-packages/\u3002

          "},{"location":"getting-started/#5","title":"5. \u8fd0\u884c\u6a21\u5f0f","text":"

          QPython \u652f\u6301\u591a\u79cd\u8fd0\u884c\u6a21\u5f0f\u4ee5\u6ee1\u8db3\u4e0d\u540c\u7684\u7528\u4f8b\uff1a

          "},{"location":"getting-started/#_9","title":"\u63a7\u5236\u53f0\u6a21\u5f0f","text":"

          \u5e38\u89c4 Python \u811a\u672c\u7684\u9ed8\u8ba4\u6a21\u5f0f\u3002

          "},{"location":"getting-started/#qsl4a","title":"QSL4A \u6a21\u5f0f","text":"

          \u901a\u8fc7 QSL4A \u5e93\u8c03\u7528 Android API \u7684\u811a\u672c\u3002

          import androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello Android!')\n

          \u8be6\u89c1 QSL4A \u6587\u6863 \u83b7\u53d6\u5b8c\u6574\u7684 API \u53c2\u8003\u3002

          "},{"location":"getting-started/#webapp","title":"WebApp \u6a21\u5f0f","text":"

          \u4f7f\u7528\u540e\u7aef\u670d\u52a1\u5668\u521b\u5efa\u57fa\u4e8e Web \u7684\u5e94\u7528\u7a0b\u5e8f\u3002\u9700\u5728\u811a\u672c\u5f00\u5934\u6dfb\u52a0\u4ee5\u4e0b\u4e24\u884c headers\uff1a

          #qpy:webapp:<\u9879\u76ee\u540d>\n#qpy://localhost:<web\u670d\u52a1\u4fa6\u542c\u7684\u7aef\u53e3>/<\u9ed8\u8ba4\u4e3b\u8def\u5f84>\n

          \u4f8b\u5982\uff1a

          #qpy:webapp:Hello QPython\n#qpy://localhost:8080/hello\n\nfrom bottle import route, run, Bottle\n\napp = Bottle()\n\n@route('/hello')\ndef hello():\n    return '<h1>Hello from QPython!</h1>'\n\nrun(app, host='localhost', port=8080)\n
          "},{"location":"getting-started/#q","title":"Q \u6a21\u5f0f\uff08\u65e0\u63a7\u5236\u53f0\u6a21\u5f0f\uff09","text":"

          \u9759\u9ed8\u6a21\u5f0f\u8fd0\u884c\u811a\u672c\uff0c\u4e0d\u663e\u793a\u63a7\u5236\u53f0\u3002\u9700\u5728\u811a\u672c\u5f00\u5934\u6dfb\u52a0 header\uff1a

          #qpy:quiet\n\nimport time\n\nwhile True:\n    # \u60a8\u7684\u540e\u53f0\u4efb\u52a1\n    time.sleep(60)\n
          \u5982\u679c\u9700\u8981\u8fd0\u884c\u5e26 GUI \u7684 QSL4A \u7a0b\u5e8f\u4e14\u4e0d\u5e0c\u671b\u663e\u793a\u63a7\u5236\u53f0\u4fe1\u606f\uff0c\u63a8\u8350\u4f7f\u7528\u6b64\u6a21\u5f0f\u3002

          "},{"location":"getting-started/#6","title":"6. \u793e\u533a\u4e0e\u652f\u6301","text":"

          \u8bbf\u95ee QPython.org \u83b7\u53d6\u6587\u6863\u3001\u7528\u6237\u793e\u533a\u53ca\u5e2e\u52a9\u95ee\u7b54\u3002

          \u793e\u533a\u94fe\u63a5\uff1a - Facebook \u7fa4\u7ec4 - GitHub - \u95ee\u9898\u53cd\u9988

          \u4e0b\u4e00\u6b65\uff1a - \u5c1d\u8bd5 Hello World \u6559\u7a0b - \u63a2\u7d22 QSL4A API \u4ee5\u96c6\u6210 Android - \u4e86\u89e3 QPython \u7248\u672c

          "},{"location":"getting-started/#_10","title":"\u89c6\u9891\u4ecb\u7ecd","text":""},{"location":"getting-started/#_11","title":"\u4e0b\u4e00\u6b65","text":"

          \u5982\u679c\u60a8\u5df2\u7ecf\u521d\u6b65\u4e86\u89e3\u4e86 QPython \u7684\u529f\u80fd\uff0c\u6b22\u8fce\u5f00\u59cb\u4f53\u9a8c\u7f16\u7a0b\u7684\u4e50\u8da3\uff01\u8bd5\u8bd5 Hello World \u6559\u7a0b \u8fc8\u51fa\u60a8\u7684\u7b2c\u4e00\u6b65\u3002

          "},{"location":"qpypi-guide/","title":"QPYPI","text":"

          \u60a8\u53ef\u4ee5\u901a\u8fc7\u5b89\u88c5\u5305\u6765\u6269\u5c55 QPython \u7684\u529f\u80fd\u3002

          "},{"location":"qpypi-guide/#_1","title":"\u5305\u5b89\u88c5\u652f\u6301","text":""},{"location":"qpypi-guide/#python","title":"\u7eaf Python \u5305","text":"

          QPython \u652f\u6301\u4f7f\u7528\u7eaf Python \u5f00\u53d1\u7684 Python \u5305\u3002\u60a8\u53ef\u4ee5\u76f4\u63a5\u901a\u8fc7 QPython \u7684 PIP \u5ba2\u6237\u7aef\u6216\u4eea\u8868\u76d8\u4e0a\u7684 QPYPI \u4f7f\u7528 pip install \u5b89\u88c5\u8fd9\u4e9b\u5305\u3002

          "},{"location":"qpypi-guide/#_2","title":"\u9884\u7f16\u8bd1\u5305","text":"

          \u5982\u679c\u67d0\u4e9b\u5305\uff08\u6216\u5b83\u4eec\u7684\u4f9d\u8d56\uff09\u662f\u7528 Rust/C/C++ \u5f00\u53d1\u7684\uff0cQPython \u65e0\u6cd5\u76f4\u63a5\u652f\u6301\u5b83\u4eec\uff0c\u56e0\u4e3a QPython \u4e0a\u6ca1\u6709\u7f16\u8bd1\u5668\u5de5\u5177\u94fe\u652f\u6301\u3002\u4f46\u662f\uff0cQPython \u56e2\u961f\u5df2\u7ecf\u9884\u7f16\u8bd1\u4e86\u4e00\u4e9b\u5e38\u7528\u5305\uff0c\u5e76\u5728 QPython \u7684 QPYPI/Extensions \u4e2d\u53d1\u5e03\uff0c\u4f9b\u7528\u6237\u8f7b\u677e\u5b89\u88c5\u3002

          "},{"location":"qpypi-guide/#_3","title":"\u5b89\u88c5\u9884\u7f16\u8bd1\u5305","text":"

          \u60a8\u53ef\u4ee5\u901a\u8fc7\u4ee5\u4e0b\u65b9\u5f0f\u5b89\u88c5\u9884\u7f16\u8bd1\u5305\uff1a

          1. \u901a\u8fc7 QPython \u5e94\u7528\uff1a\u76f4\u63a5\u4ece QPython \u5e94\u7528\u5185\u7684 QPYPI \u6216 Extensions \u5b89\u88c5
          2. \u901a\u8fc7 PyPI\uff1a\u8bbf\u95ee https://pypi.org/user/qpythonx/ \u67e5\u770b\u53ef\u7528\u7684\u5305
          3. \u901a\u8fc7 pip \u547d\u4ee4\uff1a
          4. pip install xxx-qpython - \u5e26 -qpython \u540e\u7f00\u7684\u5305
          5. pip install xxx-aipy - \u5e26 -aipy \u540e\u7f00\u7684\u5305\uff08\u901a\u5e38\u662f AI/ML \u76f8\u5173\u7684\u5305\uff09

          \u6ce8\u610f\uff1a\u6211\u4eec\u901a\u5e38\u6839\u636e\u5305\u7684\u9884\u671f\u7528\u9014\u6dfb\u52a0\u8fd9\u4e9b\u540e\u7f00\u4e4b\u4e00\u3002

          "},{"location":"qpypi-guide/#_4","title":"\u8bf7\u6c42\u65b0\u5305","text":"

          \u5982\u679c\u60a8\u9700\u8981\u5f53\u524d\u4e0d\u652f\u6301\u7684\u5305\uff1a

          • \u5728 qpython.org \u9879\u76ee \u4e2d\u63d0\u51fa\u95ee\u9898
          • QPython \u56e2\u961f\u5c06\u8003\u8651\u9884\u7f16\u8bd1\u5e76\u5c06\u5176\u6dfb\u52a0\u5230\u4ed3\u5e93\u4e2d

          \u83b7\u53d6\u66f4\u591a\u5e2e\u52a9\u548c\u53c2\u4e0e\u793e\u533a\u7684\u65b9\u5f0f\uff0c\u8bf7\u53c2\u9605 \u793e\u533a\u4e0e\u53cd\u9988 \u90e8\u5206\u3002

          \u6ce8\u610f\uff1a\u7531\u4e8e\u4e0d\u540c\u7684\u8ba1\u7b97\u673a\u67b6\u6784\uff0c\u6211\u4eec\u65e0\u6cd5\u4fdd\u8bc1 QPYPI \u5305\u542b PyPI \u4e0a\u7684\u6240\u6709\u5305\u3002

          "},{"location":"qpython-x/","title":"QPython \u7248\u672c","text":"

          QPython \u662f Android \u7684 Python \u5f15\u64ce\u3002\u5b83\u5305\u542b\u4ee4\u4eba\u60ca\u53f9\u7684\u529f\u80fd\uff0c\u5982 Python \u89e3\u91ca\u5668\u3001\u8fd0\u884c\u73af\u5883\u3001\u7f16\u8f91\u5668\u3001QPYI \u548c\u96c6\u6210\u7684 SL4A\u3002\u5b83\u8ba9\u60a8\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 Android \u4e0a\u4f7f\u7528 Python\u3002\u800c\u4e14\u5b83\u662f\u514d\u8d39\u7684\u3002

          QPython \u5df2\u7ecf\u5728\u5168\u7403\u62e5\u6709\u6570\u767e\u4e07\u7528\u6237\uff0c\u4e5f\u662f\u4e00\u4e2a\u5f00\u6e90\u9879\u76ee\u3002

          \u9488\u5bf9\u4e0d\u540c\u7684\u4f7f\u7528\u573a\u666f\uff0cQPython \u6709\u591a\u4e2a\u7248\u672c\uff1a

          "},{"location":"qpython-x/#qpython_1","title":"QPython","text":"

          \u6807\u51c6\u7248\uff1a\u9488\u5bf9 AI \u6027\u80fd\u548c\u901a\u7528\u5e94\u7528\u5546\u5e97\u517c\u5bb9\u6027\u4f18\u5316

          \u4e3b\u8981\u7248\u672c\uff0c\u53ef\u5728 Google Play \u548c\u5176\u4ed6\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002\u6b64\u7248\u672c\u4e13\u6ce8\u4e8e AI \u529f\u80fd\uff0c\u4f7f AI \u65f6\u4ee3\u7528\u6237\u66f4\u5bb9\u6613\u5b66\u4e60\u548c\u4f7f\u7528 Python\u3002

          \u4e3b\u8981\u7279\u6027\uff1a - AI \u9a71\u52a8\u7684\u7f16\u7801\u8f85\u52a9\u548c\u5b66\u4e60\u5de5\u5177 - \u79bb\u7ebf Python 3.12 \u89e3\u91ca\u5668\uff1a\u8fd0\u884c Python \u7a0b\u5e8f\u65e0\u9700\u4e92\u8054\u7f51 - \u652f\u6301\u591a\u79cd\u9879\u76ee\u7c7b\u578b\uff1a\u63a7\u5236\u53f0\u3001SL4A\u3001WebApp - \u65b9\u4fbf\u7684\u4e8c\u7ef4\u7801\u8bfb\u53d6\u5668\uff0c\u7528\u4e8e\u5c06\u4ee3\u7801\u4f20\u8f93\u5230\u624b\u673a - QPYPI \u548c\u81ea\u5b9a\u4e49\u4ed3\u5e93\uff0c\u7528\u4e8e\u9884\u7f16\u8bd1 wheel \u5305 -\u6613\u4e8e\u4f7f\u7528\u7684\u8bed\u6cd5\u9ad8\u4eae\u7f16\u8f91\u5668 - \u5b8c\u5584\u7684\u6587\u6863\u548c\u793e\u533a\u652f\u6301

          \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

          \u4e0b\u8f7d\uff1a \u53ef\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

          "},{"location":"qpython-x/#qpython_2","title":"QPython+","text":"

          \u793e\u533a\u7248\uff1a\u516c\u5f00\u652f\u6301\u5404\u79cd\u793e\u533a\u9a71\u52a8\u7684\u529f\u80fd\uff1b\u53ef\u5728\u90e8\u5206\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

          \u793e\u533a\u5f00\u6e90\u7248\u672c\uff08\u6b63\u5728\u89c4\u5212\u548c\u51c6\u5907\u4e2d\uff09\u3002\u6b64\u7248\u672c\u4e13\u4e3a\u60f3\u8981\u53c2\u4e0e QPython \u9879\u76ee\u5f00\u53d1\u7684\u8d21\u732e\u8005\u800c\u8bbe\u8ba1\uff0c\u652f\u6301\u9488\u5bf9\u4e0d\u540c\u5236\u9020\u5546\u7684\u5b9a\u5236\u3002

          \u4e3b\u8981\u7279\u6027\uff1a - \u793e\u533a\u9a71\u52a8\u5f00\u53d1 - \u652f\u6301\u4f9b\u5e94\u5546\u5b9a\u5236 - \u66f4\u7075\u6d3b\u7684\u914d\u7f6e\u9009\u9879 - \u5f00\u653e\u4f9b\u8d21\u732e\u8005\u52a0\u5165\u5f00\u53d1

          \u6743\u9650\uff1a \u4ec5\u9700\u57fa\u672c\u624b\u673a\u6743\u9650\u5373\u53ef\u5b89\u88c5\u3002

          \u4e0b\u8f7d\uff1a \u5c06\u5728 Google Play \u548c\u4e3b\u8981\u5e94\u7528\u5546\u5e97\u4e0b\u8f7d\u3002

          \u6ce8\u610f\uff1a \u6b64\u7248\u672c\u76ee\u524d\u6b63\u5728\u89c4\u5212\u51c6\u5907\u4e2d\u3002\u8bf7\u5173\u6ce8\u66f4\u65b0\uff01

          "},{"location":"qpython-x/#qpython-plus","title":"QPython Plus","text":"

          QPython+ \u5b8c\u5168\u8bbf\u95ee\u7248\uff1a\u6388\u4e88\u8c03\u7528\u6240\u6709 Android \u63a5\u53e3\u7684\u5b8c\u6574\u6743\u9650\u3002\u4e0b\u8f7d\u94fe\u63a5\u4ec5\u901a\u8fc7\u5b98\u65b9\u4e91\u76d8\u63d0\u4f9b\u3002

          \u5177\u6709\u6269\u5c55\u6743\u9650\u7684\u7279\u6b8a\u7248\u672c\uff0c\u63d0\u4f9b\u5bf9\u8bbe\u5907\u7684\u6700\u5927\u63a7\u5236\u3002\u7531\u4e8e\u5176\u654f\u611f\u7684\u6743\u9650\u8981\u6c42\uff0c\u6b64\u7248\u672c\u4e0d\u4f1a\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u53d1\u5e03\u3002

          \u4e3b\u8981\u7279\u6027\uff1a - \u5b8c\u6574\u7684 SL4A API \u8bbf\u95ee\uff0c\u5305\u62ec\u654f\u611f\u529f\u80fd - SMS/\u901a\u8bdd\u63a7\u5236 API - \u9ad8\u7ea7\u7cfb\u7edf\u96c6\u6210 - \u6700\u5927\u7684\u8bbe\u5907\u63a7\u5236\u80fd\u529b

          \u6743\u9650\uff1a \u9700\u8981\u5e7f\u6cdb\u7684\u6743\u9650\uff0c\u5305\u62ec\uff1a - \u84dd\u7259 - \u4f4d\u7f6e\uff08GPS\uff09 - \u8bfb\u53d6/\u53d1\u9001\u77ed\u4fe1 - \u6253\u7535\u8bdd - \u76f8\u673a\u548c\u9ea6\u514b\u98ce - \u7cfb\u7edf\u8bbe\u7f6e - \u4ee5\u53ca\u5176\u4ed6\u654f\u611f\u6743\u9650

          \u4e0b\u8f7d\uff1a \u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\u3002\u4ec5\u901a\u8fc7\u7279\u6b8a\u6e20\u9053\u5206\u53d1\u3002

          \u91cd\u8981\u63d0\u793a\uff1a QPython \u4e0d\u4f1a\u5728\u540e\u53f0\u672a\u7ecf\u60a8\u77e5\u6089\u4f7f\u7528\u8fd9\u4e9b\u6743\u9650\u3002\u5982\u679c\u4f7f\u7528 SL4A API \u65f6\u51fa\u73b0\u5f02\u5e38\uff0c\u8bf7\u68c0\u67e5\u7cfb\u7edf\u8bbe\u7f6e\u4e2d\u662f\u5426\u5df2\u542f\u7528\u76f8\u5173\u6743\u9650\u3002

          "},{"location":"tutorial-hello-world/","title":"\u7f16\u5199\"Hello World\"","text":""},{"location":"tutorial-hello-world/#hello-world_1","title":"Hello world","text":"

          \u597d\u7684\uff0c\u5728\u60a8\u5bf9 QPython \u6709\u4e86\u4e00\u5b9a\u7684\u4e86\u89e3\u4e4b\u540e\uff0c\u8ba9\u6211\u4eec\u5728 QPython \u4e2d\u521b\u5efa\u6211\u4eec\u7684\u7b2c\u4e00\u4e2a\u7a0b\u5e8f\u3002\u663e\u7136\uff0c\u5b83\u5c06\u662f helloworld.py\u3002;)

          \u542f\u52a8 QPython\uff0c\u6253\u5f00\u7f16\u8f91\u5668\u5e76\u8f93\u5165\u4ee5\u4e0b\u4ee3\u7801\uff1a

          #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\ndroid.makeToast('Hello, QPYTHON!')\n

          \u6beb\u65e0\u7591\u95ee\uff0c\u5b83\u4e0e\u5176\u4ed6\u4efb\u4f55 hello-world \u7a0b\u5e8f\u5e76\u65e0\u4e0d\u540c\u3002\u6267\u884c\u65f6\uff0c\u5b83\u53ea\u662f\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u5f39\u51fa\u6d88\u606f\uff08\u89c1\u9876\u90e8\u622a\u56fe\uff09\u3002\u65e0\u8bba\u5982\u4f55\uff0c\u8fd9\u662f\u4e00\u4e2a\u5f88\u597d\u7684 QPython \u7a0b\u5e8f\u793a\u4f8b\u3002

          "},{"location":"tutorial-hello-world/#_1","title":"\u4ee3\u7801\u7406\u89e3","text":"

          \u5b83\u4ee5 import androidhelper \u5f00\u5934\u2014\u2014\u8fd9\u662f QPython \u4e2d\u6700\u6709\u7528\u7684\u6a21\u5757\uff0c\u5b83\u5c01\u88c5\u4e86 Python \u4e2d\u53ef\u7528\u7684\u51e0\u4e4e\u6240\u6709\u4e0e Android \u7684\u63a5\u53e3\u3002\u4efb\u4f55\u5728 QPython \u4e2d\u5f00\u53d1\u7684\u811a\u672c\u90fd\u4ee5\u8fd9\u4e2a\u8bed\u53e5\u5f00\u5934\uff08\u81f3\u5c11\u5982\u679c\u5b83\u58f0\u79f0\u8981\u4e0e\u7528\u6237\u901a\u4fe1\u7684\u8bdd\uff09\u3002\u5728\u6b64\u5904\u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u5e93 \u548c import \u8bed\u53e5 \u7684\u5185\u5bb9\u3002

          \u63a5\u4e0b\u6765\u6211\u4eec\u521b\u5efa\u4e00\u4e2a droid \u5bf9\u8c61\uff08\u5b9e\u9645\u4e0a\u662f\u4e00\u4e2a\u7c7b\uff09\uff0c\u5b83\u5bf9\u4e8e\u8c03\u7528 RPC \u51fd\u6570\u4ee5\u4e0e Android \u901a\u4fe1\u662f\u5fc5\u8981\u7684\u3002

          \u6211\u4eec\u4ee3\u7801\u7684\u6700\u540e\u4e00\u884c\u8c03\u7528\u4e86\u8fd9\u6837\u7684\u51fd\u6570\uff0cdroid.makeToast()\uff0c\u5b83\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\u4e00\u4e2a\u5c0f\u7684\u5f39\u51fa\u6d88\u606f\uff08\"toast\"\uff09\u3002

          \u597d\u7684\uff0c\u8ba9\u6211\u4eec\u6dfb\u52a0\u4e00\u4e9b\u66f4\u591a\u7684\u529f\u80fd\u3002\u8ba9\u5b83\u8be2\u95ee\u7528\u6237\u540d\u5e76\u5411\u7528\u6237\u6253\u62db\u547c\u3002

          "},{"location":"tutorial-hello-world/#_2","title":"\u66f4\u591a\u793a\u4f8b","text":"

          \u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 dialogGetInput \u8c03\u7528\u663e\u793a\u4e00\u4e2a\u5e26\u6709\u6807\u9898\u3001\u63d0\u793a\u3001\u7f16\u8f91\u5b57\u6bb5\u548c \u786e\u5b9a \u548c \u53d6\u6d88 \u6309\u94ae\u7684\u7b80\u5355\u5bf9\u8bdd\u6846\u3002\u7528\u4ee5\u4e0b\u4ee3\u7801\u66ff\u6362\u60a8\u7684\u6700\u540e\u4e00\u884c\u4ee3\u7801\u5e76\u5c06\u5176\u4fdd\u5b58\u4e3a hello1.py\uff1a

          #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\n

          \u597d\u7684\uff0c\u6211\u8ba4\u4e3a\u5b83\u5e94\u8be5\u8fd4\u56de\u4efb\u4f55\u54cd\u5e94\uff0c\u4efb\u4f55\u7528\u6237\u53cd\u5e94\u3002\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u6211\u5199 respond = ...\u3002\u4f46\u8fd9\u4e2a\u8c03\u7528\u5b9e\u9645\u4e0a\u8fd4\u56de\u4ec0\u4e48\uff1f\u8ba9\u6211\u4eec\u68c0\u67e5\u4e00\u4e0b\u3002\u53ea\u9700\u5728\u6700\u540e\u4e00\u884c\u540e\u6dfb\u52a0 print \u8bed\u53e5\uff1a

          #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\n

          \u7136\u540e\u4fdd\u5b58\u5e76\u8fd0\u884c\u5b83...

          \u54ce\u5440\uff01\u6ca1\u6709\u6253\u5370\uff1f\u522b\u62c5\u5fc3\u3002\u53ea\u9700\u62c9\u4e0b\u901a\u77e5\u680f\uff0c\u60a8\u5c31\u4f1a\u770b\u5230\"QPython Program Output: hello1.py\"\u2014\u2014\u70b9\u51fb\u5b83\uff01

          \u5982\u60a8\u6240\u89c1\uff0cdroid.dialogGetInput() \u8fd4\u56de\u4e00\u4e2a\u5305\u542b\u4e09\u4e2a\u5b57\u6bb5\u7684 JSON \u5bf9\u8c61\u3002\u6211\u4eec\u53ea\u9700\u8981\u4e00\u4e2a\u2014\u2014result\uff0c\u5176\u4e2d\u5305\u542b\u7528\u6237\u5b9e\u9645\u8f93\u5165\u7684\u5185\u5bb9\u3002

          \u8ba9\u6211\u4eec\u6dfb\u52a0\u811a\u672c\u7684\u53cd\u5e94\uff1a

          #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nmessage = f'Hello, {respond.result}!'\ndroid.makeToast(message)\n

          \u6700\u540e\u4e24\u884c\uff081\uff09\u683c\u5f0f\u5316\u6d88\u606f\uff0c\uff082\uff09\u4ee5 toast \u5f62\u5f0f\u5411\u7528\u6237\u663e\u793a\u6d88\u606f\u3002\u5982\u679c\u60a8\u4ecd\u7136\u4e0d\u77e5\u9053 f-string \u662f\u4ec0\u4e48\u610f\u601d\uff0c\u8bf7\u53c2\u9605 Python \u6587\u6863\u3002

          \u54c7\uff01\u5b83\u5de5\u4f5c\u4e86\uff01;)

          \u73b0\u5728\u6211\u8981\u5728\u90a3\u91cc\u6dfb\u52a0\u4e00\u4e9b\u903b\u8f91\u3002\u60f3\u4e00\u60f3\uff1a\u5982\u679c\u7528\u6237\u70b9\u51fb \u53d6\u6d88 \u6309\u94ae\uff0c\u6216\u8005\u70b9\u51fb \u786e\u5b9a \u4f46\u5c06\u8f93\u5165\u5b57\u6bb5\u7559\u7a7a\uff0c\u4f1a\u53d1\u751f\u4ec0\u4e48\uff1f

          \u60a8\u53ef\u4ee5\u73a9\u8fd9\u4e2a\u7a0b\u5e8f\uff0c\u68c0\u67e5 respond \u53d8\u91cf\u5728\u6bcf\u79cd\u60c5\u51b5\u4e0b\u5305\u542b\u4ec0\u4e48\u3002

          \u9996\u5148\uff0c\u6211\u60f3\u5c06\u7528\u6237\u8f93\u5165\u7684\u6587\u672c\u653e\u5165\u4e00\u4e2a\u5355\u72ec\u7684\u53d8\u91cf\u4e2d\uff1aname = respond.result\u3002\u7136\u540e\u6211\u68c0\u67e5\u5b83\uff0c\u5982\u679c\u5b83\u5305\u542b\u4efb\u4f55\u771f\u5b9e\u6587\u672c\uff0c\u5b83\u5c06\u88ab\u89c6\u4e3a\u540d\u79f0\u5e76\u7528\u4e8e\u95ee\u5019\u3002\u5426\u5219\uff0c\u5c06\u663e\u793a\u53e6\u4e00\u6761\u6d88\u606f\u3002\u5c06\u7b2c\u4e94\u884c message = f'Hello, {respond.result}!' \u66ff\u6362\u4e3a\u4ee5\u4e0b\u4ee3\u7801\uff1a

          name = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\n

          \u4f7f\u7528\u5de5\u5177\u680f\u4e0a\u7684 < \u548c > \u6309\u94ae\u6765\u7f29\u8fdb/\u53d6\u6d88\u7f29\u8fdb if \u8bed\u53e5\u4e2d\u7684\u884c\uff08\u6216\u8005\u53ea\u9700\u4f7f\u7528\u7a7a\u683c/\u9000\u683c\u952e\uff09\u3002\u60a8\u53ef\u4ee5\u5728 \u6b64\u5904 \u9605\u8bfb\u66f4\u591a\u5173\u4e8e Python \u7f29\u8fdb\u7684\u5185\u5bb9\uff1bif \u8bed\u53e5\u5728 \u6b64\u5904 \u63cf\u8ff0\u3002

          \u9996\u5148\uff0c\u6211\u4eec\u5c06\u7528\u6237\u8f93\u5165\u653e\u5165 name \u53d8\u91cf\u3002\u7136\u540e\u6211\u4eec\u68c0\u67e5 name \u662f\u5426\u5305\u542b\u4efb\u4f55\u5185\u5bb9\uff1f\u5982\u679c\u7528\u6237\u7559\u7a7a\u884c\u5e76\u70b9\u51fb \u786e\u5b9a\uff0c\u8fd4\u56de\u503c\u662f\u7a7a\u5b57\u7b26\u4e32 ''\u3002\u5982\u679c\u6309\u4e0b\u4e86 \u53d6\u6d88 \u6309\u94ae\uff0c\u8fd4\u56de\u503c\u662f None\u3002\u5728 if \u8bed\u53e5\u4e2d\uff0c\u4e24\u8005\u90fd\u88ab\u89c6\u4e3a\u5047\u3002\u56e0\u6b64\uff0c\u53ea\u6709\u5f53 name \u5305\u542b\u4efb\u4f55\u6709\u610f\u4e49\u7684\u5185\u5bb9\u65f6\uff0cthen \u8bed\u53e5\u624d\u4f1a\u6267\u884c\uff0c\u5e76\u663e\u793a\u95ee\u5019\u8bed\"Hello, ...!\"\u3002\u5982\u679c\u8f93\u5165\u4e3a\u7a7a\uff0c\u7528\u6237\u5c06\u770b\u5230\"Hey! And you're not very polite, %Username%!\"\u6d88\u606f\u3002

          \u597d\u7684\uff0c\u8fd9\u662f\u6574\u4e2a\u7a0b\u5e8f\uff1a

          #qpy:quiet\nimport androidhelper\n\ndroid = androidhelper.Android()\nrespond = droid.dialogGetInput(\"Hello\", \"What is your name?\")\nprint(respond)\nname = respond.result\nif name:\n    message = f'Hello, {name}!'\nelse:\n    message = \"Hey! And you're not very polite, %Username%!\"\ndroid.makeToast(message)\n
          "},{"location":"tutorial-hello-world/#_3","title":"\u8fd0\u884c\u6548\u679c","text":""},{"location":"tutorial-hello-world/#_4","title":"\u4e0b\u4e00\u6b65","text":"

          \u5bf9\u4e8e Python \u65b0\u7528\u6237\uff0c\u63a8\u8350\u5b66\u4e60 Python \u8bed\u6cd5\u5b9e\u8df5 \u8bfe\u7a0b\u6765\u8fdb\u4e00\u6b65\u5b66\u4e60 Python\uff0c\u6216\u8005\u5728 QPython \u7cbe\u9009\u8bfe\u7a0b \u4e2d\u5bfb\u627e\u60f3\u8981\u5b66\u4e60\u7684\u5185\u5bb9\u3002

          "},{"location":"whats-new/","title":"\u66f4\u65b0\u65e5\u5fd7","text":""},{"location":"whats-new/#v400","title":"v4.0.0","text":"
          • \u5916\u90e8\u5b58\u50a8\u8bbf\u95ee\uff1a\u7528\u6237\u73b0\u5728\u53ef\u4ee5\u5c06 Python \u811a\u672c\u76f4\u63a5\u4fdd\u5b58\u5230\u5916\u90e8\u5b58\u50a8\u8bbe\u5907\uff0c\u5927\u5927\u63d0\u5347\u4e86\u6587\u4ef6\u7ba1\u7406\u7684\u7075\u6d3b\u6027\u3002
          • QSL4A \u529f\u80fd\u589e\u5f3a\uff1a\u6539\u8fdb\u4e86 QSL4A \u7684\u529f\u80fd\u3002(https://www.qpython.org/en/qsl4a/)
          • \u793e\u533a\u4e0e\u8bfe\u7a0b\uff1a\u4f18\u5316\u4e86\u793e\u533a\u548c\u8bfe\u7a0b\u6a21\u5757\uff0c\u63d0\u4f9b\u66f4\u6e05\u6670\u7684\u4fe1\u606f\u548c\u66f4\u4fbf\u6377\u7684\u5bfc\u822a\uff0c\u65b9\u4fbf\u7528\u6237\u8bbf\u95ee\u5b66\u4e60\u8d44\u6e90\u548c\u83b7\u5f97\u652f\u6301\u3002
          "},{"location":"whats-new/#v392-v393","title":"v3.9.2 / v3.9.3","text":"
          • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
          • \u7f16\u8f91\u5668\u91cd\u5927\u66f4\u65b0\uff0c\u5e26\u6765\u66f4\u6d41\u7545\u7684\u7f16\u8f91\u4f53\u9a8c
          • \u5176\u4ed6\u5404\u79cd\u5c0f\u6539\u8fdb
          "},{"location":"whats-new/#v391","title":"v3.9.1","text":"
          • SDK \u5347\u7ea7\uff0c\u652f\u6301 16 KB \u9875\u9762\u5927\u5c0f\uff0c\u63d0\u4f9b\u66f4\u6d41\u7545\u7684\u8fd0\u884c\u73af\u5883
          • \u6269\u5c55\u5305\u73b0\u5728\u652f\u6301 MCP
          • \u9519\u8bef\u4fee\u590d
          "},{"location":"whats-new/#v390","title":"v3.9.0","text":"
          • SDK \u5347\u7ea7\uff0c\u6574\u5408\u6700\u65b0\u7684 Android \u529f\u80fd
          • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
          • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
          • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
          "},{"location":"whats-new/#v3811","title":"v3.8.11","text":"
          • \u5185\u7f6e Ollama 0.9.5 \u5347\u7ea7\uff1a\u73b0\u5728\u652f\u6301\u5728 QPython \u4e2d\u672c\u5730\u8fd0\u884c Gemma3n \u6a21\u578b\uff0c\u4f53\u9a8c\u66f4\u5f3a\u5927\u7684\u7aef\u4fa7 AI \u8ba1\u7b97\u80fd\u529b
          • Pygame \u6e38\u620f\u5f00\u53d1\u652f\u6301\uff1a\u7ed3\u5408 XServer\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 QPython \u4e0a\u7f16\u5199\u548c\u8fd0\u884c Pygame \u6e38\u620f\uff0c\u91ca\u653e\u60a8\u7684\u521b\u9020\u529b\uff01
          • \u4e2a\u6027\u5316\u56fe\u6807\u81ea\u5b9a\u4e49\uff1a\u901a\u8fc7 QPython \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u684c\u9762\u56fe\u6807\u548c\u4e3b\u9898\uff0c\u521b\u5efa\u72ec\u7279\u7684\u7f16\u7a0b\u73af\u5883
          "},{"location":"whats-new/#v3810","title":"v3.8.10","text":"
          • \u5185\u7f6e Ollama \u5347\u7ea7\uff1a\u73b0\u5728\u60a8\u53ef\u4ee5\u5728 QPython \u4e2d\u8f7b\u677e\u672c\u5730\u8fd0\u884c Qwen3 / Gemma3 \u6a21\u578b\uff01
          • \u6dfb\u52a0\u4e86\u5f3a\u5927\u7684 MCP \u5e93\uff1a\u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 mcp \u5e93\uff0c\u8ba9\u60a8\u968f\u65f6\u968f\u5730\u643a\u5e26\u5f3a\u5927\u7684 MCP \u529f\u80fd\uff01
          "},{"location":"whats-new/#v389","title":"v3.8.9","text":"

          \u91cd\u5927\u66f4\u65b0\uff01AI \u7f16\u7a0b\u5b8c\u5168\u96c6\u6210\u5230 QPython\uff0c\u8ba9\u60a8\u7684\u7f16\u7a0b\u66f4\u8f7b\u677e\uff01

          • \u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u652f\u6301\uff1a\u65b0\u652f\u6301 AIPyApp\uff0c\u5728 QPython \u4e2d\u5b9e\u73b0\u81ea\u7136\u8bed\u8a00\u7f16\u7a0b\u3002\u76ee\u524d\u5904\u4e8e\u6d4b\u8bd5\u9636\u6bb5 - \u52a0\u5165\u6211\u4eec\u7684\u793e\u533a\u83b7\u53d6\u4f7f\u7528\u8bf4\u660e
          • \u65b0 QSL4A \u529f\u80fd\uff1a\u6dfb\u52a0 notebookOpen \u51fd\u6570\uff0c\u652f\u6301\u81ea\u7136\u8bed\u8a00\u63a7\u5236\u6253\u5f00 Notebook \u6587\u4ef6
          • \u5185\u7f6e\u7f16\u8f91\u5668\u5347\u7ea7\uff1a\u589e\u5f3a\u7f16\u8f91\u5668\u529f\u80fd\uff0c\u652f\u6301\u6253\u5f00\u548c\u6d4f\u89c8\u5404\u79cd\u6587\u672c\u6587\u4ef6
          • \u4fbf\u6377\u7684\u6587\u4ef6\u7ba1\u7406\uff1a\u5728\u6587\u4ef6\u7ba1\u7406\u5668\u4e2d\u6dfb\u52a0\u5185\u90e8\u5b58\u50a8\u5165\u53e3\uff0c\u5feb\u901f\u8bbf\u95ee\u60a8\u7684\u6587\u4ef6
          "},{"location":"whats-new/#v388","title":"v3.8.8","text":"
          • \u6587\u4ef6\u8bbf\u95ee\u6743\u9650\u63a7\u5236\u7684\u91cd\u8981\u6539\u8fdb\uff0c\u5141\u8bb8\u7528\u6237\u7075\u6d3b\u5730\u901a\u8fc7 QPython \u7f16\u7a0b\u542f\u7528\u6216\u7981\u7528\u5916\u90e8\u5b58\u50a8\u6587\u4ef6\u7684\u8bbf\u95ee
          • SDK \u5347\u7ea7\uff0c\u589e\u5f3a\u4e86\u5bf9\u65b0\u7248 Android \u7684\u652f\u6301\u548c\u517c\u5bb9\u6027
          • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Anthropic \u548c Google GenAI \u5e93
          "},{"location":"whats-new/#v387","title":"v3.8.7","text":"
          • \u5728\u73b0\u6709 Tkinter \u652f\u6301\u57fa\u7840\u4e0a\uff0c\u5728 Extensions -> Tools \u4e2d\u6dfb\u52a0\u4e86\u4f7f\u7528 Turtle \u7ed8\u5236\u54c6\u5566A\u68a6\u7684\u793a\u4f8b\u4ee3\u7801
          • \u4f18\u5316\u4e86\u624b\u673a\u6743\u9650\u83b7\u53d6\u6d41\u7a0b\uff0c\u63d0\u5347\u7528\u6237\u4f53\u9a8c\u548c\u64cd\u4f5c\u4fbf\u5229\u6027
          • \u5728 Extensions -> AIPY \u4e2d\u6dfb\u52a0\u4e86 Google Gen AI \u5e93\uff0c\u65b9\u4fbf\u8bbf\u95ee Gemini Developer API \u548c Vertex AI
          "},{"location":"whats-new/#v386","title":"v3.8.6","text":"
          • Tkinter \u652f\u6301\uff1a\u73b0\u5728\u652f\u6301 Tkinter \u5e93\uff0c\u53ef\u901a\u8fc7 XServer \u8bbf\u95ee\u3002\u8bf7\u8bbf\u95ee www.qpython.org \u7684\u4e91\u76d8\"Extra\"\u94fe\u63a5\u4e0b\u8f7d\u6240\u9700\u6587\u4ef6
          • \u5b58\u50a8\u6743\u9650\u66f4\u65b0\uff1a\u4e3a\u6539\u5584\u7528\u6237\u4f53\u9a8c\uff0c\u6211\u4eec\u6dfb\u52a0\u4e86\u8bfb\u53d6\u624b\u673a\u5b58\u50a8\u7684\u6743\u9650\uff0c\u7528\u4e8e\u8bbf\u95ee\u5b58\u50a8\u5728\u5176\u4ed6\u76ee\u5f55\u4e2d\u7684 Python \u7a0b\u5e8f

          \u6b64\u66f4\u65b0\u540e\uff0cQPython \u548c QPythonPlus\uff08\u4e0d\u5728\u5e94\u7528\u5546\u5e97\u4e0a\u67b6\uff0c\u4e13\u4e3a\u9700\u8981\u66f4\u591a\u654f\u611f\u6743\u9650\u7684\u9ad8\u7ea7\u7528\u6237\u8bbe\u8ba1\uff09\u5c06\u4fdd\u6301\u540c\u6b65\u7684\u7248\u672c\u53f7\u3002

          "},{"location":"whats-new/#v352-2025225","title":"v3.5.2 (2025/2/25)","text":"

          \u4e0e\u5f00\u6e90 LLM \u90e8\u7f72\u5de5\u5177 Ollama \u4ee5\u53ca DeepSeek \u5f00\u53d1\u7684 DeepSeek \u5b9e\u73b0\u65e0\u7f1d\u96c6\u6210\uff01

          \u529f\u80fd\uff1a - \u96f6\u95e8\u69db\u5728\u79fb\u52a8\u8bbe\u5907\u4e0a\u672c\u5730\u8fd0\u884c\u5404\u79cd\u5927\u578b\u8bed\u8a00\u6a21\u578b - \u5feb\u901f\u90e8\u7f72 DeepSeek \u7b49\u5c16\u7aef AI \u6a21\u578b - \u4eab\u53d7\u7b80\u7ea6\u7684 API \u8c03\u7528\u4f53\u9a8c - \u6784\u5efa\u5b8c\u5168\u79bb\u7ebf\u7684\u667a\u80fd\u7f16\u7a0b\u73af\u5883

          \u80fd\u529b\uff1a - \u76f4\u63a5\u5728\u624b\u673a\u4e0a\u52a0\u8f7d/\u7ba1\u7406 LLM \u6a21\u578b - \u57fa\u4e8e\u672c\u5730\u8ba1\u7b97\u7684\u5b9e\u65f6\u4f4e\u5ef6\u8fdf\u54cd\u5e94

          "},{"location":"whats-new/#v350","title":"v3.5.0","text":"
          • Python \u5347\u7ea7\u5230 3.12.8
          • \u6539\u8fdb\u4eea\u8868\u76d8\uff0c\u529f\u80fd\u66f4\u6e05\u6670\u3001\u66f4\u4eba\u6027\u5316
          • \u6dfb\u52a0\u4e86\u4f17\u591a\u7b2c\u4e09\u65b9\u5305\uff1aPyTorch / Twisted / Scrapy / FastAPI ...
          "},{"location":"whats-new/#v338","title":"v3.3.8","text":"
          • \u4fee\u590d\u4e86 NumPy \u517c\u5bb9\u6027\u95ee\u9898
          "},{"location":"whats-new/#v335","title":"v3.3.5","text":"
          • \u5347\u7ea7 Python \u5185\u6838\u5230 3.11.9
          • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u4e0d\u663e\u793a\u6a21\u5757\u5b89\u88c5\u72b6\u6001\u7684 bug
          • \u4fee\u590d\u4e86\u6269\u5c55\u4e2d\u5220\u9664\u6a21\u5757\u5931\u8d25\u7684 bug
          • \u4fee\u590d\u4e86\u5176\u4ed6 bug
          "},{"location":"whats-new/#v334","title":"v3.3.4","text":"
          • \u6dfb\u52a0\u4e86 OpenAI/Langchain/APIGPTCloud AI \u5305
          • \u79fb\u9664\u4e0d\u5fc5\u8981\u7684\u6587\u4ef6\u4ee5\u51cf\u5c11\u5927\u5c0f
          "},{"location":"whats-new/#v325","title":"v3.2.5","text":"
          • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570
          • \u5176\u4ed6\u9519\u8bef\u4fee\u590d
          "},{"location":"whats-new/#v323","title":"v3.2.3","text":"
          • \u66f4\u65b0 Python \u7248\u672c\u5230 3.11.0
          • \u66f4\u65b0 IPython \u7248\u672c\u5230 8.6.0
          • \u66f4\u65b0 pip \u7248\u672c\u5230 22.3.1
          • \u66f4\u65b0\u79d1\u5b66\u8ba1\u7b97\u5305\uff0c\u81ea\u52a8\u8f6f\u94fe\u63a5
          • \u51cf\u5c11\u7a7a\u95f4\u4f7f\u7528
          • \u6dfb\u52a0\u4e86\u4e00\u4e9b SL4A \u51fd\u6570 + \u5176\u4ed6\u9519\u8bef\u4fee\u590d
          "},{"location":"whats-new/#v318","title":"v3.1.8","text":"
          • \u5728\u7ec8\u7aef\u4e2d\u6dfb\u52a0\u4e86\u64cd\u4f5c\u70ed\u952e
          • \u4fee\u590d\u4e86\u7f16\u8f91\u5668\u5728\u65cb\u8f6c\u65f6\u4e22\u5931\u5185\u5bb9\u7684\u95ee\u9898
          • \u4fee\u590d\u4e86\u5176\u4ed6 bug

          \u5728 Google Play \u4e0b\u8f7d

          "},{"location":"qsl4a/","title":"QSL4A\uff08Android \u811a\u672c\u5c42\uff09API \u6587\u6863","text":"

          QSL4A \u662f QPython \u7684 Android \u811a\u672c\u5c42\uff0c\u5141\u8bb8\u60a8\u4f7f\u7528 Python \u63a7\u5236 Android \u8bbe\u5907\u529f\u80fd\u3002

          "},{"location":"qsl4a/#_1","title":"\u5feb\u901f\u5f00\u59cb","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a toast \u6d88\u606f\ndroid.makeToast('Hello QPython!')\n\n# \u9707\u52a8\u8bbe\u5907\ndroid.vibrate(500)\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\uff08\u5148\u5f00\u59cb\u76d1\u63a7\uff09\nimport time\ndroid.batteryStartMonitoring()\ntime.sleep(0.5)  # \u7b49\u5f85\u6570\u636e\nbattery = droid.readBatteryData().result\nprint(f\"\u7535\u6c60\uff1a{battery['level']}%\")\n
          "},{"location":"qsl4a/#_2","title":"\u6587\u6863\u7ed3\u6784","text":""},{"location":"qsl4a/#_3","title":"\u6838\u5fc3\u6a21\u5757","text":"
          • Android \u57fa\u7840 - \u6838\u5fc3\u8fde\u63a5\u548c RPC
          • Intent \u7cfb\u7edf - Android Intent \u64cd\u4f5c
          • \u4e8b\u4ef6\u7cfb\u7edf - \u4e8b\u4ef6\u5904\u7406\u548c\u5e7f\u64ad
          "},{"location":"qsl4a/#ui","title":"UI \u7ec4\u4ef6","text":"
          • \u5bf9\u8bdd\u6846 - \u8b66\u62a5\u3001\u8f93\u5165\u3001\u9009\u62e9\u5bf9\u8bdd\u6846
          • \u5168\u5c4f UI - \u81ea\u5b9a\u4e49\u5e03\u5c40 UI
          • \u60ac\u6d6e\u7a97 - \u60ac\u6d6e\u7a97\u53e3
          • \u8f85\u52a9\u529f\u80fd - \u5c4f\u5e55\u81ea\u52a8\u5316
          "},{"location":"qsl4a/#_4","title":"\u7cfb\u7edf","text":"
          • \u7535\u6c60 - \u7535\u6c60\u76d1\u63a7
          • \u4f20\u611f\u5668 - \u8bbe\u5907\u4f20\u611f\u5668
          • \u5e94\u7528 - \u5e94\u7528\u7ba1\u7406
          • \u7cfb\u7edf\u4fe1\u606f - \u8bbe\u5907\u4fe1\u606f
          • \u8bbe\u7f6e - \u7cfb\u7edf\u8bbe\u7f6e
          • \u5524\u9192\u9501 - \u5524\u9192\u9501\u63a7\u5236
          • QPython \u63a5\u53e3 - \u811a\u672c\u6267\u884c
          • Activity \u7ed3\u679c - Activity \u7ed3\u679c\u5904\u7406
          "},{"location":"qsl4a/#_5","title":"\u786c\u4ef6","text":"
          • \u84dd\u7259 - \u84dd\u7259\u64cd\u4f5c
          • \u76f8\u673a - \u62cd\u7167\u548c\u5f55\u50cf
          • \u97f3\u9891/\u5f55\u97f3\u5668 - \u5f55\u97f3
          • \u7f51\u7edc\u6444\u50cf\u5934 - MJPEG \u6d41
          • USB \u4e32\u53e3 - USB \u4e3b\u673a\u4e32\u53e3
          "},{"location":"qsl4a/#_6","title":"\u8fde\u63a5","text":"
          • WiFi - WiFi \u64cd\u4f5c
          • \u4f4d\u7f6e - GPS \u548c\u4f4d\u7f6e
          • \u77ed\u4fe1 - \u77ed\u4fe1\u64cd\u4f5c
          • \u7535\u8bdd - \u6253\u7535\u8bdd\u548c\u6765\u7535\u4fe1\u606f
          • \u8054\u7cfb\u4eba - \u8054\u7cfb\u4eba\u7ba1\u7406
          • \u4fe1\u53f7\u5f3a\u5ea6 - \u4fe1\u53f7\u76d1\u63a7
          • FTP \u670d\u52a1\u5668 - \u5185\u7f6e FTP \u670d\u52a1\u5668
          "},{"location":"qsl4a/#_7","title":"\u5b58\u50a8","text":"
          • DocumentFile - \u6587\u4ef6\u64cd\u4f5c
          • \u526a\u8d34\u677f - \u526a\u8d34\u677f\u64cd\u4f5c
          • \u504f\u597d\u8bbe\u7f6e - \u5171\u4eab\u504f\u597d\u8bbe\u7f6e
          "},{"location":"qsl4a/#_8","title":"\u5a92\u4f53","text":"
          • \u5a92\u4f53\u64ad\u653e\u5668 - \u97f3\u9891/\u89c6\u9891\u64ad\u653e
          • \u56fe\u50cf\u5904\u7406 - \u56fe\u50cf\u64cd\u4f5c
          "},{"location":"qsl4a/#_9","title":"\u7279\u6b8a\u529f\u80fd","text":"
          • \u52a0\u5bc6 - \u52a0\u5bc6/\u89e3\u5bc6
          • PGPT AI - AI \u8bed\u97f3\u670d\u52a1
          "},{"location":"qsl4a/#_10","title":"\u7ed3\u679c\u5bf9\u8c61","text":"

          \u5927\u591a\u6570 QSL4A \u65b9\u6cd5\u8fd4\u56de\u4e00\u4e2a\u5e26\u6709\u4ee5\u4e0b\u5c5e\u6027\u7684 Result \u547d\u540d\u5143\u7ec4\uff1a - id - \u8bf7\u6c42 ID - result - \u5b9e\u9645\u7ed3\u679c\u6570\u636e - error - \u5982\u679c\u5931\u8d25\u5219\u4e3a\u9519\u8bef\u6d88\u606f

          result = droid.getClipboard()\nif result.error is None:\n    print(result.result)\nelse:\n    print(f\"\u9519\u8bef\uff1a{result.error}\")\n
          "},{"location":"qsl4a/connectivity/contacts/","title":"\u8054\u7cfb\u4eba API","text":"

          \u8bbf\u95ee\u548c\u7ba1\u7406\u8bbe\u5907\u8054\u7cfb\u4eba\u3002

          "},{"location":"qsl4a/connectivity/contacts/#_1","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":""},{"location":"qsl4a/connectivity/contacts/#pickcontact","title":"pickContact()","text":"

          \u663e\u793a\u8054\u7cfb\u4eba\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

          pickContact()\n

          \u8fd4\u56de\uff1a \u5305\u542b\u8054\u7cfb\u4eba URI \u7684 Intent

          "},{"location":"qsl4a/connectivity/contacts/#pickphone","title":"pickPhone()","text":"

          \u663e\u793a\u7535\u8bdd\u53f7\u7801\u5217\u8868\u4ee5\u4f9b\u9009\u62e9\u3002

          pickPhone()\n

          \u8fd4\u56de\uff1a \u9009\u4e2d\u7684\u7535\u8bdd\u53f7\u7801\u5b57\u7b26\u4e32

          "},{"location":"qsl4a/connectivity/contacts/#_2","title":"\u8054\u7cfb\u4eba\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#contactsget","title":"contactsGet()","text":"

          \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\u3002

          contactsGet(attributes=None)\n

          \u53c2\u6570\uff1a - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

          \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba JSONObject \u5217\u8868

          "},{"location":"qsl4a/connectivity/contacts/#contactsgetbyid","title":"contactsGetById()","text":"

          \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\u3002

          contactsGetById(id, attributes=None)\n

          \u53c2\u6570\uff1a - id (int): \u8054\u7cfb\u4eba ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

          \u8fd4\u56de\uff1a JSONObject \u8054\u7cfb\u4eba\u6570\u636e

          "},{"location":"qsl4a/connectivity/contacts/#contactsgetcount","title":"contactsGetCount()","text":"

          \u83b7\u53d6\u8054\u7cfb\u4eba\u603b\u6570\u3002

          contactsGetCount()\n

          \u8fd4\u56de\uff1a \u6574\u6570\u8ba1\u6570

          "},{"location":"qsl4a/connectivity/contacts/#contactsgetids","title":"contactsGetIds()","text":"

          \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba ID\u3002

          contactsGetIds()\n

          \u8fd4\u56de\uff1a \u8054\u7cfb\u4eba ID \u6574\u6570\u5217\u8868

          "},{"location":"qsl4a/connectivity/contacts/#contactsgetattributes","title":"contactsGetAttributes()","text":"

          \u83b7\u53d6\u6240\u6709\u53ef\u80fd\u7684\u8054\u7cfb\u4eba\u5c5e\u6027\u3002

          contactsGetAttributes()\n

          \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u5217\u8868

          "},{"location":"qsl4a/connectivity/contacts/#_3","title":"\u5185\u5bb9\u67e5\u8be2","text":""},{"location":"qsl4a/connectivity/contacts/#querycontent","title":"queryContent()","text":"

          \u4f7f\u7528\u81ea\u5b9a\u4e49\u53c2\u6570\u67e5\u8be2\u5185\u5bb9\u89e3\u6790\u5668\u3002

          queryContent(uri, attributes=None, selection=None, selectionArgs=None, order=None)\n

          \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u5c5e\u6027 - selection (str, optional): WHERE \u5b50\u53e5 - selectionArgs (list, optional): \u9009\u62e9\u53c2\u6570 - order (str, optional): ORDER BY \u5b50\u53e5

          \u8fd4\u56de\uff1a JSONObject \u7ed3\u679c\u5217\u8868

          "},{"location":"qsl4a/connectivity/contacts/#queryattributes","title":"queryAttributes()","text":"

          \u83b7\u53d6\u5185\u5bb9 URI \u7684\u5c5e\u6027\u3002

          queryAttributes(uri)\n

          \u53c2\u6570\uff1a - uri (str): \u5185\u5bb9 URI

          \u8fd4\u56de\uff1a \u5c5e\u6027\u540d\u79f0\u7684 JSONArray

          "},{"location":"qsl4a/connectivity/contacts/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u9009\u62e9\u8054\u7cfb\u4eba\ncontact_uri = droid.pickContact().result\nprint(f\"Selected contact: {contact_uri}\")\n\n# \u9009\u62e9\u7535\u8bdd\u53f7\u7801\nphone = droid.pickPhone().result\nprint(f\"Selected phone: {phone}\")\n\n# \u83b7\u53d6\u6240\u6709\u8054\u7cfb\u4eba\ncontacts = droid.contactsGet().result\nprint(f\"Total contacts: {len(contacts)}\")\n\n# \u901a\u8fc7 ID \u83b7\u53d6\u8054\u7cfb\u4eba\ncontact = droid.contactsGetById(1).result\nprint(f\"Contact: {contact}\")\n\n# \u83b7\u53d6\u8054\u7cfb\u4eba\u5c5e\u6027\nattrs = droid.contactsGetAttributes().result\nprint(f\"Available attributes: {attrs}\")\n
          "},{"location":"qsl4a/connectivity/ftp/","title":"FTP \u670d\u52a1\u5668 API","text":"

          \u5728\u8bbe\u5907\u4e0a\u542f\u52a8\u548c\u7ba1\u7406\u5185\u7f6e FTP \u670d\u52a1\u5668\u3002

          "},{"location":"qsl4a/connectivity/ftp/#ftp","title":"FTP \u670d\u52a1\u5668\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/ftp/#ftpstart","title":"ftpStart()","text":"

          \u542f\u52a8 FTP \u670d\u52a1\u5668\u3002

          ftpStart()\n

          \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4 [ip, port]

          "},{"location":"qsl4a/connectivity/ftp/#ftpstop","title":"ftpStop()","text":"

          \u505c\u6b62 FTP \u670d\u52a1\u5668\u3002

          ftpStop()\n
          "},{"location":"qsl4a/connectivity/ftp/#ftpisrunning","title":"ftpIsRunning()","text":"

          \u68c0\u67e5 FTP \u670d\u52a1\u5668\u662f\u5426\u6b63\u5728\u8fd0\u884c\u3002

          ftpIsRunning()\n

          \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u8fd0\u884c\u5219\u4e3a True

          "},{"location":"qsl4a/connectivity/ftp/#ftpget","title":"ftpGet()","text":"

          \u83b7\u53d6 FTP \u670d\u52a1\u5668 IP \u5730\u5740\u3002

          ftpGet()\n

          \u8fd4\u56de\uff1a \u5305\u542b IP \u5730\u5740\u548c\u7aef\u53e3\u7684\u6570\u7ec4

          "},{"location":"qsl4a/connectivity/ftp/#ftpset","title":"ftpSet()","text":"

          \u914d\u7f6e FTP \u670d\u52a1\u5668\u8bbe\u7f6e\u3002

          ftpSet(port=None, rootDir=None, username=None, password=None)\n

          \u53c2\u6570\uff1a - port (int, optional): \u670d\u52a1\u5668\u7aef\u53e3 - rootDir (str, optional): \u8981\u670d\u52a1\u7684\u57fa\u7840\u76ee\u5f55 - username (str, optional): \u767b\u5f55\u7528\u6237\u540d - password (str, optional): \u767b\u5f55\u5bc6\u7801

          \u8fd4\u56de\uff1a \u5305\u542b\u5f53\u524d\u8bbe\u7f6e\u7684 JSONObject

          "},{"location":"qsl4a/connectivity/ftp/#ftpstatus","title":"ftpStatus()","text":"

          \u83b7\u53d6 FTP \u670d\u52a1\u5668\u72b6\u6001\u3002

          ftpStatus()\n

          \u8fd4\u56de\uff1a \u72b6\u6001\u63cf\u8ff0\u5b57\u7b26\u4e32

          "},{"location":"qsl4a/connectivity/ftp/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u914d\u7f6e FTP \u670d\u52a1\u5668\ndroid.ftpSet(\n    port=2121,\n    rootDir=\"/sdcard\",\n    username=\"admin\",\n    password=\"secret\"\n)\n\n# \u542f\u52a8 FTP \u670d\u52a1\u5668\ninfo = droid.ftpStart().result\nprint(f\"FTP running at {info[0]}:{info[1]}\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.ftpIsRunning().result:\n    print(\"FTP server is running\")\n\n# \u83b7\u53d6\u670d\u52a1\u5668\u4fe1\u606f\nserver_info = droid.ftpGet().result\nprint(f\"Server: {server_info}\")\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.ftpStop()\n

          \u6ce8\u610f\uff1a \u4f7f\u7528\u63d0\u4f9b\u7684\u51ed\u636e\u901a\u8fc7\u4efb\u4f55 FTP \u5ba2\u6237\u7aef\u8fde\u63a5\u5230 FTP \u670d\u52a1\u5668\u3002

          "},{"location":"qsl4a/connectivity/location/","title":"\u4f4d\u7f6e API","text":"

          \u8bbf\u95ee GPS \u548c\u7f51\u7edc\u4f4d\u7f6e\u670d\u52a1\u3002

          "},{"location":"qsl4a/connectivity/location/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/location/#startlocating","title":"startLocating()","text":"

          \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\u3002

          startLocating(minUpdateTime=60000, minUpdateDistance=30, updateGnssStatus=False)\n

          \u53c2\u6570\uff1a - minUpdateTime (int): \u66f4\u65b0\u4e4b\u95f4\u7684\u6700\u5c0f\u65f6\u95f4\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a60000\uff09 - minUpdateDistance (float): \u66f4\u65b0\u7684\u6700\u5c0f\u8ddd\u79bb\uff08\u7c73\uff09\uff08\u9ed8\u8ba4\uff1a30\uff09 - updateGnssStatus (bool): \u542f\u7528 GNSS \u72b6\u6001\u66f4\u65b0\uff08\u9ed8\u8ba4\uff1aFalse\uff09

          "},{"location":"qsl4a/connectivity/location/#stoplocating","title":"stopLocating()","text":"

          \u505c\u6b62\u4f4d\u7f6e\u66f4\u65b0\u3002

          stopLocating()\n
          "},{"location":"qsl4a/connectivity/location/#readlocation","title":"readLocation()","text":"

          \u83b7\u53d6\u6700\u540e\u5df2\u77e5\u4f4d\u7f6e\u3002

          readLocation()\n

          \u8fd4\u56de\uff1a \u4f4d\u7f6e\u6570\u636e\u5b57\u5178

          "},{"location":"qsl4a/connectivity/location/#getlastknownlocation","title":"getLastKnownLocation()","text":"

          \u83b7\u53d6\u7f13\u5b58\u7684\u4f4d\u7f6e\u3002

          getLastKnownLocation()\n

          \u8fd4\u56de\uff1a \u6765\u81ea\u6240\u6709\u63d0\u4f9b\u5546\u7684\u4f4d\u7f6e

          "},{"location":"qsl4a/connectivity/location/#geocode","title":"geocode()","text":"

          \u5c06\u5730\u5740\u8f6c\u6362\u4e3a\u5750\u6807\u3002

          geocode(address, maxResults=1)\n
          "},{"location":"qsl4a/connectivity/location/#_2","title":"\u4f4d\u7f6e\u63d0\u4f9b\u5546\u65b9\u6cd5)","text":""},{"location":"qsl4a/connectivity/location/#locationproviders","title":"locationProviders()","text":"

          \u83b7\u53d6\u624b\u673a\u4e0a\u53ef\u7528\u7684\u4f4d\u7f6e\u63d0\u4f9b\u5546\u3002

          locationProviders()\n

          \u8fd4\u56de\uff1a \u53ef\u7528\u63d0\u4f9b\u5546\u540d\u79f0\u5217\u8868\uff08\u4f8b\u5982 ['gps', 'network']\uff09

          "},{"location":"qsl4a/connectivity/location/#locationproviderenabled","title":"locationProviderEnabled()","text":"

          \u68c0\u67e5\u7279\u5b9a\u4f4d\u7f6e\u63d0\u4f9b\u5546\u662f\u5426\u5df2\u542f\u7528\u3002

          locationProviderEnabled(provider)\n

          \u53c2\u6570\uff1a - provider (str): \u63d0\u4f9b\u5546\u540d\u79f0\uff08\u4f8b\u5982 'gps', 'network'\uff09

          \u8fd4\u56de\uff1a \u5982\u679c\u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

          "},{"location":"qsl4a/connectivity/location/#readgnssstatus","title":"readGnssStatus()","text":"

          \u8bfb\u53d6\u5168\u7403\u5bfc\u822a\u536b\u661f\u7cfb\u7edf\u72b6\u6001\uff08\u9700\u8981 Android 8+\uff09\u3002

          readGnssStatus()\n

          \u8fd4\u56de\uff1a \u5305\u542b GNSS \u536b\u661f\u4fe1\u606f\u7684 JSONArray

          "},{"location":"qsl4a/connectivity/location/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u4f4d\u7f6e\u66f4\u65b0\ndroid.startLocating(minUpdateTime=5000, minUpdateDistance=1, updateGnssStatus=False)\n\n# \u7b49\u5f85\u5b9a\u4f4d\ntime.sleep(10)\n\n# \u83b7\u53d6\u4f4d\u7f6e\nloc = droid.readLocation().result\nif loc:\n    lat = loc['latitude']\n    lon = loc['longitude']\n    print(f\"Location: {lat}, {lon}\")\n\ndroid.stopLocating()\n
          "},{"location":"qsl4a/connectivity/phone/","title":"\u7535\u8bdd API","text":"

          \u63a7\u5236\u7535\u8bdd\u901a\u8bdd\u548c\u83b7\u53d6\u7535\u8bdd\u4fe1\u606f\u3002

          "},{"location":"qsl4a/connectivity/phone/#_1","title":"\u7535\u8bdd\u72b6\u6001\u8ddf\u8e2a","text":""},{"location":"qsl4a/connectivity/phone/#starttrackingphonestate","title":"startTrackingPhoneState()","text":"

          \u5f00\u59cb\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u53d8\u5316\u3002\u751f\u6210 'phone' \u4e8b\u4ef6\u3002

          startTrackingPhoneState()\n
          "},{"location":"qsl4a/connectivity/phone/#readphonestate","title":"readPhoneState()","text":"

          \u8bfb\u53d6\u5f53\u524d\u7535\u8bdd\u72b6\u6001\u3002

          readPhoneState()\n

          \u8fd4\u56de\uff1a \u5305\u542b\u7535\u8bdd\u72b6\u6001\u548c\u6765\u7535\u53f7\u7801\u7684 Bundle

          "},{"location":"qsl4a/connectivity/phone/#stoptrackingphonestate","title":"stopTrackingPhoneState()","text":"

          \u505c\u6b62\u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\u3002

          stopTrackingPhoneState()\n
          "},{"location":"qsl4a/connectivity/phone/#_2","title":"\u62e8\u6253\u7535\u8bdd","text":""},{"location":"qsl4a/connectivity/phone/#phonecall","title":"phoneCall()","text":"

          \u901a\u8fc7 URI \u547c\u53eb\u8054\u7cfb\u4eba/\u7535\u8bdd\u53f7\u7801\u3002

          phoneCall(uri)\n

          \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

          "},{"location":"qsl4a/connectivity/phone/#phonecallnumber","title":"phoneCallNumber()","text":"

          \u76f4\u63a5\u62e8\u6253\u7535\u8bdd\u53f7\u7801\u3002

          phoneCallNumber(phone_number)\n

          \u53c2\u6570\uff1a - phone_number (str): \u8981\u62e8\u6253\u7684\u7535\u8bdd\u53f7\u7801

          "},{"location":"qsl4a/connectivity/phone/#phonedial","title":"phoneDial()","text":"

          \u62e8\u6253\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

          phoneDial(uri)\n

          \u53c2\u6570\uff1a - uri (str): \u8054\u7cfb\u4eba URI \u6216\u7535\u8bdd\u53f7\u7801 URI

          "},{"location":"qsl4a/connectivity/phone/#phonedialnumber","title":"phoneDialNumber()","text":"

          \u62e8\u6253\u7535\u8bdd\u53f7\u7801\uff08\u6253\u5f00\u62e8\u53f7\u5668\u4f46\u4e0d\u547c\u53eb\uff09\u3002

          phoneDialNumber(phone_number)\n

          \u53c2\u6570\uff1a - phone_number (str): \u7535\u8bdd\u53f7\u7801

          "},{"location":"qsl4a/connectivity/phone/#_3","title":"\u57fa\u7ad9\u4f4d\u7f6e","text":""},{"location":"qsl4a/connectivity/phone/#getcelllocation","title":"getCellLocation()","text":"

          \u83b7\u53d6\u5f53\u524d\u57fa\u7ad9\u4f4d\u7f6e\u3002

          getCellLocation()\n

          \u8fd4\u56de\uff1a \u5305\u542b\u57fa\u7ad9\u4f4d\u7f6e\u6570\u636e\u7684 JSONObject

          "},{"location":"qsl4a/connectivity/phone/#getallcellslocation","title":"getAllCellsLocation()","text":"

          \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u4f4d\u7f6e\uff08\u9002\u7528\u4e8e\u53cc\u5361\u8bbe\u5907\uff09\u3002

          getAllCellsLocation()\n

          \u8fd4\u56de\uff1a \u57fa\u7ad9\u4f4d\u7f6e\u7684 JSONArray

          "},{"location":"qsl4a/connectivity/phone/#_4","title":"\u7f51\u7edc\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getnetworkoperator","title":"getNetworkOperator()","text":"

          \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

          getNetworkOperator()\n

          \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

          "},{"location":"qsl4a/connectivity/phone/#getnetworkoperatorname","title":"getNetworkOperatorName()","text":"

          \u83b7\u53d6\u5f53\u524d\u8fd0\u8425\u5546\u7684\u540d\u79f0\u3002

          getNetworkOperatorName()\n

          \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

          "},{"location":"qsl4a/connectivity/phone/#getnetworktype","title":"getNetworkType()","text":"

          \u83b7\u53d6\u5f53\u524d\u7f51\u7edc\u7c7b\u578b\u3002

          getNetworkType()\n

          \u8fd4\u56de\uff1a \u63cf\u8ff0\u65e0\u7ebf\u7535\u6280\u672f\u7684\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'LTE', 'UMTS', 'GSM'\uff09

          "},{"location":"qsl4a/connectivity/phone/#getphonetype","title":"getPhoneType()","text":"

          \u83b7\u53d6\u7535\u8bdd\u7c7b\u578b\u3002

          getPhoneType()\n

          \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'GSM', 'CDMA', 'SIP'\uff09

          "},{"location":"qsl4a/connectivity/phone/#sim","title":"SIM \u5361\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getsimcountryiso","title":"getSimCountryIso()","text":"

          \u83b7\u53d6 SIM \u5361\u7684 ISO \u56fd\u5bb6\u4ee3\u7801\u3002

          getSimCountryIso()\n

          \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'us'\uff09

          "},{"location":"qsl4a/connectivity/phone/#getsimoperator","title":"getSimOperator()","text":"

          \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u7684 MCC+MNC\u3002

          getSimOperator()\n

          \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 '310260'\uff09

          "},{"location":"qsl4a/connectivity/phone/#getsimoperatorname","title":"getSimOperatorName()","text":"

          \u83b7\u53d6 SIM \u8fd0\u8425\u5546\u540d\u79f0\u3002

          getSimOperatorName()\n

          \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\uff08\u4f8b\u5982 'T-Mobile'\uff09

          "},{"location":"qsl4a/connectivity/phone/#getsimserialnumber","title":"getSimSerialNumber()","text":"

          \u83b7\u53d6 SIM \u5e8f\u5217\u53f7\u3002

          getSimSerialNumber()\n

          \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32 SIM \u5e8f\u5217\u53f7

          "},{"location":"qsl4a/connectivity/phone/#getsimstate","title":"getSimState()","text":"

          \u83b7\u53d6 SIM \u5361\u72b6\u6001\u3002

          getSimState()\n

          \u8fd4\u56de\uff1a \u63cf\u8ff0 SIM \u72b6\u6001\u7684\u5b57\u7b26\u4e32

          "},{"location":"qsl4a/connectivity/phone/#getsubscriberid","title":"getSubscriberId()","text":"

          \u83b7\u53d6\u8ba2\u9605\u8005 ID\u3002

          getSubscriberId()\n

          \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8ba2\u9605\u8005 ID

          "},{"location":"qsl4a/connectivity/phone/#_5","title":"\u8bed\u97f3\u90ae\u4ef6","text":""},{"location":"qsl4a/connectivity/phone/#getvoicemailalphatag","title":"getVoiceMailAlphaTag()","text":"

          \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u5b57\u6bcd\u6807\u7b7e\u3002

          getVoiceMailAlphaTag()\n

          \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u6807\u7b7e

          "},{"location":"qsl4a/connectivity/phone/#getvoicemailnumber","title":"getVoiceMailNumber()","text":"

          \u83b7\u53d6\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801\u3002

          getVoiceMailNumber()\n

          \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bed\u97f3\u90ae\u4ef6\u53f7\u7801

          "},{"location":"qsl4a/connectivity/phone/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getdeviceid","title":"getDeviceId()","text":"

          \u83b7\u53d6\u8bbe\u5907 ID\uff08GSM \u7684 IMEI\uff09\u3002\u5df2\u5e9f\u5f03\u3002

          getDeviceId()\n

          \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

          "},{"location":"qsl4a/connectivity/phone/#getdevicesoftwareversion","title":"getDeviceSoftwareVersion()","text":"

          \u83b7\u53d6\u8bbe\u5907\u8f6f\u4ef6\u7248\u672c\u3002

          getDeviceSoftwareVersion()\n

          \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8f6f\u4ef6\u7248\u672c

          "},{"location":"qsl4a/connectivity/phone/#getline1number","title":"getLine1Number()","text":"

          \u83b7\u53d6\u7ebf\u8def 1 \u7535\u8bdd\u53f7\u7801\u3002

          getLine1Number()\n

          \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u7535\u8bdd\u53f7\u7801

          "},{"location":"qsl4a/connectivity/phone/#checknetworkroaming","title":"checkNetworkRoaming()","text":"

          \u68c0\u67e5\u662f\u5426\u8fde\u63a5\u5230\u6f2b\u6e38\u7f51\u7edc\u3002

          checkNetworkRoaming()\n

          \u8fd4\u56de\uff1a \u5982\u679c\u6b63\u5728\u6f2b\u6e38\u5219\u4e3a True

          "},{"location":"qsl4a/connectivity/phone/#_7","title":"\u57fa\u7ad9\u4fe1\u606f","text":""},{"location":"qsl4a/connectivity/phone/#getallcellinfo","title":"getAllCellInfo()","text":"

          \u83b7\u53d6\u6240\u6709\u57fa\u7ad9\u7684\u4fe1\u606f\u3002

          getAllCellInfo()\n

          \u8fd4\u56de\uff1a \u57fa\u7ad9\u4fe1\u606f\u5217\u8868

          "},{"location":"qsl4a/connectivity/phone/#setdataenabled","title":"setDataEnabled()","text":"

          \u542f\u7528\u6216\u7981\u7528\u79fb\u52a8\u6570\u636e\u3002

          setDataEnabled(enabled)\n

          \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528

          "},{"location":"qsl4a/connectivity/phone/#_8","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7f51\u7edc\u4fe1\u606f\noperator = droid.getNetworkOperatorName().result\nprint(f\"Operator: {operator}\")\n\nnetwork_type = droid.getNetworkType().result\nprint(f\"Network: {network_type}\")\n\n# \u83b7\u53d6 SIM \u4fe1\u606f\nsim_state = droid.getSimState().result\nprint(f\"SIM: {sim_state}\")\n\n# \u83b7\u53d6\u7535\u8bdd\u53f7\u7801\nline1 = droid.getLine1Number().result\nprint(f\"Phone: {line1}\")\n\n# \u8ddf\u8e2a\u7535\u8bdd\u72b6\u6001\ndroid.startTrackingPhoneState()\nprint(\"Tracking phone state...\")\ndroid.stopTrackingPhoneState()\n
          "},{"location":"qsl4a/connectivity/signalstrength/","title":"\u4fe1\u53f7\u5f3a\u5ea6 API","text":"

          \u76d1\u63a7\u8702\u7a9d\u548c\u65e0\u7ebf\u4fe1\u53f7\u5f3a\u5ea6\u3002

          "},{"location":"qsl4a/connectivity/signalstrength/#_1","title":"\u4fe1\u53f7\u5f3a\u5ea6\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/signalstrength/#starttrackingsignalstrengths","title":"startTrackingSignalStrengths()","text":"

          \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316\u3002\u751f\u6210 'signal_strengths' \u4e8b\u4ef6\u3002

          startTrackingSignalStrengths()\n
          "},{"location":"qsl4a/connectivity/signalstrength/#stoptrackingsignalstrengths","title":"stopTrackingSignalStrengths()","text":"

          \u505c\u6b62\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\u3002

          stopTrackingSignalStrengths()\n
          "},{"location":"qsl4a/connectivity/signalstrength/#readsignalstrengths","title":"readSignalStrengths()","text":"

          \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\u3002

          readSignalStrengths()\n

          \u8fd4\u56de\uff1a \u5305\u542b\u4fe1\u53f7\u5f3a\u5ea6\u6570\u636e\u7684 Bundle

          "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthlevel","title":"getTelephoneSignalStrengthLevel()","text":"

          \u83b7\u53d6\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u7b49\u7ea7\uff080-4\uff09\u3002

          getTelephoneSignalStrengthLevel()\n

          \u8fd4\u56de\uff1a \u6574\u6570\u7b49\u7ea7\uff080=\u65e0\uff0c1=\u5dee\uff0c2=\u4e00\u822c\uff0c3=\u597d\uff0c4=\u4f18\u79c0\uff09

          "},{"location":"qsl4a/connectivity/signalstrength/#gettelephonesignalstrengthdetail","title":"getTelephoneSignalStrengthDetail()","text":"

          \u83b7\u53d6\u8be6\u7ec6\u7684\u7535\u8bdd\u4fe1\u53f7\u5f3a\u5ea6\u4fe1\u606f\u3002

          getTelephoneSignalStrengthDetail()\n

          \u8fd4\u56de\uff1a \u5305\u542b\u8be6\u7ec6\u4fe1\u53f7\u4fe1\u606f\u7684\u5b57\u7b26\u4e32

          "},{"location":"qsl4a/connectivity/signalstrength/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u8ddf\u8e2a\u4fe1\u53f7\u5f3a\u5ea6\ndroid.startTrackingSignalStrengths()\n\n# \u7b49\u5f85\u4fe1\u53f7\u66f4\u65b0\ntime.sleep(5)\n\n# \u8bfb\u53d6\u5f53\u524d\u4fe1\u53f7\u5f3a\u5ea6\nsignal = droid.readSignalStrengths().result\nprint(f\"Signal: {signal}\")\n\n# \u76f4\u63a5\u83b7\u53d6\u7b49\u7ea7\nlevel = droid.getTelephoneSignalStrengthLevel().result\nprint(f\"Signal level: {level}/4\")\n\ndroid.stopTrackingSignalStrengths()\n
          "},{"location":"qsl4a/connectivity/sms/","title":"SMS API","text":"

          \u53d1\u9001\u548c\u63a5\u6536 SMS \u6d88\u606f\u3002

          "},{"location":"qsl4a/connectivity/sms/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/connectivity/sms/#smssend","title":"smsSend()","text":"

          \u53d1\u9001 SMS \u6d88\u606f\u3002

          smsSend(destinationAddress, text)\n

          \u53c2\u6570\uff1a - destinationAddress (str): \u7535\u8bdd\u53f7\u7801 - text (str): \u6d88\u606f\u6587\u672c

          "},{"location":"qsl4a/connectivity/sms/#smsgetmessagecount","title":"smsGetMessageCount()","text":"

          \u83b7\u53d6\u6d88\u606f\u6570\u91cf\u3002

          smsGetMessageCount(unreadOnly=False, folder=\"inbox\")\n
          "},{"location":"qsl4a/connectivity/sms/#smsgetmessageids","title":"smsGetMessageIds()","text":"

          \u83b7\u53d6\u6d88\u606f ID\u3002

          smsGetMessageIds(unreadOnly=False, folder=\"inbox\")\n
          "},{"location":"qsl4a/connectivity/sms/#smsgetmessages","title":"smsGetMessages()","text":"

          \u83b7\u53d6\u6d88\u606f\u8be6\u60c5\u3002

          smsGetMessages(unreadOnly=False, folder=\"inbox\", attributes=None)\n
          "},{"location":"qsl4a/connectivity/sms/#smsgetmessagebyid","title":"smsGetMessageById()","text":"

          \u901a\u8fc7 ID \u83b7\u53d6\u7279\u5b9a\u6d88\u606f\u3002

          smsGetMessageById(id, attributes=None)\n

          \u53c2\u6570\uff1a - id (int): \u6d88\u606f ID - attributes (list, optional): \u8981\u68c0\u7d22\u7684\u7279\u5b9a\u5c5e\u6027

          \u8fd4\u56de\uff1a \u6d88\u606f\u6570\u636e\u5b57\u5178

          "},{"location":"qsl4a/connectivity/sms/#smsgetattributes","title":"smsGetAttributes()","text":"

          \u83b7\u53d6\u53ef\u7528\u7684 SMS \u6d88\u606f\u5c5e\u6027\u3002

          smsGetAttributes()\n

          \u8fd4\u56de\uff1a \u53ef\u7528\u5c5e\u6027\u540d\u79f0\u5217\u8868

          "},{"location":"qsl4a/connectivity/sms/#smsdeletemessage","title":"smsDeleteMessage()","text":"

          \u5220\u9664\u6d88\u606f\u3002

          smsDeleteMessage(id)\n
          "},{"location":"qsl4a/connectivity/sms/#smsmarkmessageread","title":"smsMarkMessageRead()","text":"

          \u5c06\u6d88\u606f\u6807\u8bb0\u4e3a\u5df2\u8bfb\u3002

          smsMarkMessageRead(ids, read=True)\n
          "},{"location":"qsl4a/connectivity/sms/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u53d1\u9001 SMS\ndroid.smsSend(\"+1234567890\", \"Hello from QPython!\")\n\n# \u83b7\u53d6\u672a\u8bfb\u6d88\u606f\nmessages = droid.smsGetMessages(unreadOnly=True).result\nfor msg in messages:\n    print(f\"From: {msg['address']}, Text: {msg['body']}\")\n
          "},{"location":"qsl4a/connectivity/wifi/","title":"WiFi API","text":"

          \u63a7\u5236 WiFi \u9002\u914d\u5668\u5e76\u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\u3002

          "},{"location":"qsl4a/connectivity/wifi/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/connectivity/wifi/#checkwifistate","title":"checkWifiState()","text":"

          \u68c0\u67e5 WiFi \u662f\u5426\u5df2\u542f\u7528\u3002

          checkWifiState()\n

          \u8fd4\u56de\uff1a \u5982\u679c WiFi \u5df2\u542f\u7528\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

          "},{"location":"qsl4a/connectivity/wifi/#togglewifistate","title":"toggleWifiState()","text":"

          \u6253\u5f00\u6216\u5173\u95ed WiFi\u3002

          toggleWifiState(enabled=None)\n

          \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

          \u8fd4\u56de\uff1a \u5982\u679c\u64cd\u4f5c\u6210\u529f\u5219\u4e3a True

          "},{"location":"qsl4a/connectivity/wifi/#wifistartscan","title":"wifiStartScan()","text":"

          \u5f00\u59cb\u626b\u63cf\u53ef\u7528\u7684 WiFi \u7f51\u7edc\u3002

          wifiStartScan()\n
          "},{"location":"qsl4a/connectivity/wifi/#wifigetscanresults","title":"wifiGetScanResults()","text":"

          \u83b7\u53d6\u53d1\u73b0\u7684 WiFi \u7f51\u7edc\u5217\u8868\u3002

          wifiGetScanResults()\n

          \u8fd4\u56de\uff1a \u63a5\u5165\u70b9\u4fe1\u606f\u5217\u8868

          "},{"location":"qsl4a/connectivity/wifi/#_2","title":"\u8fde\u63a5\u7ba1\u7406","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetconnectioninfo","title":"wifiGetConnectionInfo()","text":"

          \u83b7\u53d6\u8be6\u7ec6\u8fde\u63a5\u4fe1\u606f\u3002

          wifiGetConnectionInfo()\n

          \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001IP \u5730\u5740\u7b49\u8fde\u63a5\u8be6\u60c5\u7684\u5b57\u5178

          "},{"location":"qsl4a/connectivity/wifi/#getconnectedinfo","title":"getConnectedInfo()","text":"

          \u83b7\u53d6\u8fde\u63a5\u7684 WiFi \u7f51\u7edc\u4fe1\u606f\uff08\u7b80\u5316\u7248\uff09\u3002

          getConnectedInfo()\n

          \u8fd4\u56de\uff1a \u5305\u542b SSID\u3001BSSID\u3001\u4fe1\u53f7\u5f3a\u5ea6\u7684\u5b57\u5178

          "},{"location":"qsl4a/connectivity/wifi/#getdhcpinfo","title":"getDhcpInfo()","text":"

          \u83b7\u53d6\u5f53\u524d\u8fde\u63a5\u7684 DHCP \u4fe1\u606f\u3002

          getDhcpInfo(ipConvertToString=True)\n

          \u53c2\u6570\uff1a - ipConvertToString (bool): \u5c06 IP \u5730\u5740\u8f6c\u6362\u4e3a\u5b57\u7b26\u4e32\u683c\u5f0f\uff08\u9ed8\u8ba4\uff1aTrue\uff09

          \u8fd4\u56de\uff1a \u5305\u542b IP\u3001\u7f51\u5173\u3001DNS \u7b49 DHCP \u4fe1\u606f\u7684\u5b57\u5178

          "},{"location":"qsl4a/connectivity/wifi/#wifidisconnect","title":"wifiDisconnect()","text":"

          \u65ad\u5f00\u5f53\u524d WiFi \u7f51\u7edc\u8fde\u63a5\u3002

          wifiDisconnect()\n
          "},{"location":"qsl4a/connectivity/wifi/#wifireconnect","title":"wifiReconnect()","text":"

          \u91cd\u65b0\u8fde\u63a5\u5230\u5f53\u524d\u7f51\u7edc\u3002

          wifiReconnect()\n
          "},{"location":"qsl4a/connectivity/wifi/#wifireassociate","title":"wifiReassociate()","text":"

          \u91cd\u65b0\u5173\u8054\u5f53\u524d\u63a5\u5165\u70b9\u3002

          wifiReassociate()\n
          "},{"location":"qsl4a/connectivity/wifi/#_3","title":"\u70ed\u70b9","text":""},{"location":"qsl4a/connectivity/wifi/#wifigetapstate","title":"wifiGetApState()","text":"

          \u83b7\u53d6 WiFi AP\uff08\u70ed\u70b9\uff09\u72b6\u6001\u3002

          wifiGetApState()\n

          \u8fd4\u56de\uff1a \u70ed\u70b9\u72b6\u6001

          "},{"location":"qsl4a/connectivity/wifi/#wifi","title":"WiFi \u9501","text":""},{"location":"qsl4a/connectivity/wifi/#wifilockacquirefull","title":"wifiLockAcquireFull()","text":"

          \u83b7\u53d6\u5b8c\u6574 WiFi \u9501\uff08\u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\u4e5f\u4fdd\u6301 WiFi \u6d3b\u52a8\uff09\u3002

          wifiLockAcquireFull()\n
          "},{"location":"qsl4a/connectivity/wifi/#wifilockacquirescanonly","title":"wifiLockAcquireScanOnly()","text":"

          \u83b7\u53d6\u4ec5\u626b\u63cf WiFi \u9501\u3002

          wifiLockAcquireScanOnly()\n
          "},{"location":"qsl4a/connectivity/wifi/#wifilockrelease","title":"wifiLockRelease()","text":"

          \u91ca\u653e WiFi \u9501\u3002

          wifiLockRelease()\n
          "},{"location":"qsl4a/connectivity/wifi/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u68c0\u67e5 WiFi \u72b6\u6001\nif droid.checkWifiState().result:\n    print(\"WiFi is enabled\")\nelse:\n    print(\"Enabling WiFi...\")\n    droid.toggleWifiState(True)\n    time.sleep(2)\n\n# \u5f00\u59cb\u626b\u63cf\ndroid.wifiStartScan()\ntime.sleep(3)\n\n# \u83b7\u53d6\u626b\u63cf\u7ed3\u679c\nnetworks = droid.wifiGetScanResults().result\nfor network in networks:\n    print(f\"SSID: {network.get('SSID')}, Signal: {network.get('level')} dBm\")\n\n# \u83b7\u53d6\u8fde\u63a5\u4fe1\u606f\ninfo = droid.wifiGetConnectionInfo().result\nif info:\n    print(f\"Connected to: {info.get('ssid')}\")\n    print(f\"BSSID: {info.get('bssid')}\")\n    print(f\"IP: {info.get('ip_address')}\")\n\n# \u83b7\u53d6 DHCP \u4fe1\u606f\ndhcp = droid.getDhcpInfo().result\nif dhcp:\n    print(f\"Gateway: {dhcp.get('gateway')}\")\n    print(f\"DNS: {dhcp.get('dns1')}\")\n\n# \u83b7\u53d6\u7b80\u5316\u7684\u8fde\u63a5\u4fe1\u606f\nconnected = droid.getConnectedInfo().result\nprint(f\"SSID: {connected.get('ssid')}, Signal: {connected.get('level')} dBm\")\n\n# \u65ad\u5f00\u5e76\u91cd\u65b0\u8fde\u63a5\ndroid.wifiDisconnect()\ntime.sleep(1)\ndroid.wifiReconnect()\n\n# \u91cd\u65b0\u5173\u8054\u63a5\u5165\u70b9\ndroid.wifiReassociate()\n\n# \u68c0\u67e5\u70ed\u70b9\u72b6\u6001\nap_state = droid.wifiGetApState().result\nprint(f\"Hotspot state: {ap_state}\")\n\n# \u83b7\u53d6 WiFi \u9501\u4ee5\u8fdb\u884c\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireFull()\n# ... \u6267\u884c\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n\n# \u6216\u4f7f\u7528\u4ec5\u626b\u63cf\u9501\u4ee5\u8fdb\u884c\u8f83\u8f7b\u7684\u540e\u53f0\u64cd\u4f5c\ndroid.wifiLockAcquireScanOnly()\n# ... \u6267\u884c\u626b\u63cf\u5de5\u4f5c ...\ndroid.wifiLockRelease()\n
          "},{"location":"qsl4a/core/android-base/","title":"Android \u57fa\u7840\u7c7b","text":"

          Android \u7c7b\u662f QSL4A \u7684\u6838\u5fc3\uff0c\u63d0\u4f9b\u4e86\u4e0e Android \u8fd0\u884c\u65f6\u7684\u8fde\u63a5\u548c RPC \u673a\u5236\u3002

          "},{"location":"qsl4a/core/android-base/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
          # \u529f\u80fd\u5b8c\u6574\u7248\u672c\uff08\u63a8\u8350\uff09\nimport androidhelper\ndroid = androidhelper.Android()\n\n# \u7b80\u5316\u7248\u672c\uff08\u5feb\u901f\uff0c\u5355\u5b9e\u4f8b\uff09\nimport android\ndroid = android.droid\n
          "},{"location":"qsl4a/core/android-base/#android_1","title":"\u7c7b\uff1aAndroid","text":""},{"location":"qsl4a/core/android-base/#_2","title":"\u6784\u9020\u51fd\u6570","text":"
          Android(addr=None)\n

          \u53c2\u6570\uff1a - addr (tuple, optional): (HOST, PORT) \u5730\u5740\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u73af\u5883\u53d8\u91cf AP_HOST \u548c AP_PORT

          \u73af\u5883\u53d8\u91cf\uff1a - AP_HOST - \u670d\u52a1\u5668\u4e3b\u673a\u5730\u5740 - AP_PORT - \u670d\u52a1\u5668\u7aef\u53e3 - AP_HANDSHAKE - \u8ba4\u8bc1\u4ee4\u724c

          "},{"location":"qsl4a/core/android-base/#_3","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/android-base/#_rpc","title":"_rpc()","text":"

          \u8c03\u7528 Android \u51fd\u6570\u7684\u5185\u90e8 RPC \u65b9\u6cd5\u3002

          _rpc(method, *args)\n

          \u53c2\u6570\uff1a - method (str): \u8981\u8c03\u7528\u7684\u65b9\u6cd5\u540d - *args: \u65b9\u6cd5\u7684\u53ef\u53d8\u53c2\u6570

          \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4\uff0c\u5305\u542b\u4ee5\u4e0b\u5b57\u6bb5\uff1a - id (int): \u8bf7\u6c42 ID - result: \u65b9\u6cd5\u8fd4\u56de\u503c - error (str or None): \u9519\u8bef\u4fe1\u606f\uff08\u5982\u679c\u5931\u8d25\uff09

          "},{"location":"qsl4a/core/android-base/#getattr","title":"getattr()","text":"

          \u52a8\u6001\u65b9\u6cd5\u5206\u53d1\u5668\u3002\u6240\u6709 Android \u65b9\u6cd5\u90fd\u901a\u8fc7\u5c5e\u6027\u67e5\u627e\u8bbf\u95ee\u3002

          # \u4ee5\u4e0b\u4e24\u79cd\u65b9\u5f0f\u7b49\u4ef7\uff1a\ndroid.makeToast(\"Hello\")\ndroid._rpc(\"makeToast\", \"Hello\")\n
          "},{"location":"qsl4a/core/android-base/#androidpy","title":"\u72ec\u7acb\u51fd\u6570\uff08android.py\uff09","text":"

          \u4f7f\u7528\u7b80\u5316\u7684 android \u6a21\u5757\u65f6\uff1a

          "},{"location":"qsl4a/core/android-base/#jsla","title":"jsla()","text":"

          \u53d1\u9001 JSON-RPC \u8bf7\u6c42\u5e76\u8fd4\u56de\u539f\u59cb\u54cd\u5e94\u3002

          jsla(method, *params)\n

          \u8fd4\u56de\uff1a JSON \u5b57\u7b26\u4e32\u54cd\u5e94

          "},{"location":"qsl4a/core/android-base/#rsla","title":"rsla()","text":"

          \u53d1\u9001\u8bf7\u6c42\u5e76\u4ec5\u8fd4\u56de\u7ed3\u679c\u3002

          rsla(method, *params)\n

          \u8fd4\u56de\uff1a RPC \u8c03\u7528\u7684\u7ed3\u679c\u503c

          "},{"location":"qsl4a/core/android-base/#esla","title":"esla()","text":"

          \u53d1\u9001\u8bf7\u6c42\uff0c\u9519\u8bef\u65f6\u629b\u51fa\u5f02\u5e38\u3002

          esla(method, *params)\n

          \u629b\u51fa\uff1a \u5982\u679c error \u5b57\u6bb5\u4e0d\u4e3a None \u5219\u629b\u51fa\u5f02\u5e38

          "},{"location":"qsl4a/core/android-base/#nsla","title":"nsla()","text":"

          \u53d1\u9001\u8bf7\u6c42\u5e76\u8fd4\u56de Result \u547d\u540d\u5143\u7ec4\u3002

          nsla(method, *params)\n

          \u8fd4\u56de\uff1a Result \u547d\u540d\u5143\u7ec4

          "},{"location":"qsl4a/core/android-base/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/android-base/#_5","title":"\u57fa\u672c\u8fde\u63a5","text":"
          import androidhelper\n\n# \u8fde\u63a5\u5230 Android \u8fd0\u884c\u65f6\ndroid = androidhelper.Android()\n\n# \u901a\u8fc7\u663e\u793a toast \u6765\u68c0\u67e5\u8fde\u63a5\ndroid.makeToast(\"Connected!\")\n
          "},{"location":"qsl4a/core/android-base/#_6","title":"\u9519\u8bef\u5904\u7406","text":"
          result = droid.someMethod()\nif result.error:\n    print(f\"Error: {result.error}\")\nelse:\n    print(f\"Success: {result.result}\")\n
          "},{"location":"qsl4a/core/android-base/#rpc","title":"\u76f4\u63a5 RPC \u8c03\u7528","text":"
          # \u76f4\u63a5\u8c03\u7528\u4efb\u610f\u65b9\u6cd5\nresult = droid._rpc(\"makeToast\", \"Hello World\")\n
          "},{"location":"qsl4a/core/events/","title":"\u4e8b\u4ef6\u7cfb\u7edf","text":"

          QSL4A \u63d0\u4f9b\u4e86\u4e00\u4e2a\u4e8b\u4ef6\u7cfb\u7edf\uff0c\u7528\u4e8e\u5904\u7406\u6765\u81ea Android \u7684\u5f02\u6b65\u4e8b\u4ef6\uff0c\u5982\u4f20\u611f\u5668\u66f4\u65b0\u3001\u4f4d\u7f6e\u53d8\u5316\u548c\u81ea\u5b9a\u4e49\u5e7f\u64ad\u3002

          "},{"location":"qsl4a/core/events/#_2","title":"\u4e8b\u4ef6\u57fa\u7840","text":"

          \u4e8b\u4ef6\u5b58\u50a8\u5728\u7f13\u51b2\u533a\u4e2d\uff0c\u53ef\u4ee5\u8f6e\u8be2\u6216\u7b49\u5f85\u3002\u6bcf\u4e2a\u4e8b\u4ef6\u5305\u542b\uff1a - name: \u4e8b\u4ef6\u7c7b\u578b/\u540d\u79f0 - data: \u4e8b\u4ef6\u8d1f\u8f7d\u6570\u636e - time: \u65f6\u95f4\u6233

          "},{"location":"qsl4a/core/events/#_3","title":"\u4e8b\u4ef6\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#eventclearbuffer","title":"eventClearBuffer()","text":"

          \u6e05\u9664\u7f13\u51b2\u533a\u4e2d\u7684\u6240\u6709\u5f85\u5904\u7406\u4e8b\u4ef6\u3002

          eventClearBuffer()\n

          \u8fd4\u56de\uff1a None

          "},{"location":"qsl4a/core/events/#eventpoll","title":"eventPoll()","text":"

          \u8f6e\u8be2\u7f13\u51b2\u533a\u4e2d\u7684\u4e8b\u4ef6\u3002

          eventPoll(number_of_events=1)\n

          \u53c2\u6570\uff1a - number_of_events (int): \u8981\u68c0\u7d22\u7684\u6700\u5927\u4e8b\u4ef6\u6570\uff08\u9ed8\u8ba4\uff1a1\uff09

          \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\u5217\u8868

          "},{"location":"qsl4a/core/events/#eventwait","title":"eventWait()","text":"

          \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\u3002

          eventWait(timeout=None)\n

          \u53c2\u6570\uff1a - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09\u3002None = \u6c38\u4e45\u7b49\u5f85

          \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

          "},{"location":"qsl4a/core/events/#eventwaitfor","title":"eventWaitFor()","text":"

          \u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6\u3002

          eventWaitFor(eventName, timeout=None)\n

          \u53c2\u6570\uff1a - eventName (str): \u8981\u7b49\u5f85\u7684\u4e8b\u4ef6\u540d\u79f0 - timeout (int, optional): \u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

          \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61\uff0c\u5982\u679c\u8d85\u65f6\u5219\u8fd4\u56de None

          "},{"location":"qsl4a/core/events/#eventpost","title":"eventPost()","text":"

          \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\u3002

          eventPost(name, data, enqueue=None)\n

          \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e\uff08\u4efb\u610f\u7c7b\u578b\uff09 - enqueue (bool, optional): \u5982\u679c\u4e3a True \u5219\u6dfb\u52a0\u5230\u961f\u5217

          "},{"location":"qsl4a/core/events/#receiveevent","title":"receiveEvent()","text":"

          \u63a5\u6536\u4e8b\u4ef6\uff08\u963b\u585e\uff09\u3002

          receiveEvent()\n

          \u8fd4\u56de\uff1a \u4e8b\u4ef6\u5bf9\u8c61

          "},{"location":"qsl4a/core/events/#_4","title":"\u5e7f\u64ad\u4e8b\u4ef6","text":"

          \u6ce8\u518c\u7cfb\u7edf\u5e7f\u64ad\u4e8b\u4ef6\u3002

          "},{"location":"qsl4a/core/events/#eventregisterforbroadcast","title":"eventRegisterForBroadcast()","text":"

          \u6ce8\u518c\u63a5\u6536\u5e7f\u64ad\u4e8b\u4ef6\u3002

          eventRegisterForBroadcast(category, enqueue=True)\n

          \u53c2\u6570\uff1a - category (str): \u5e7f\u64ad\u7c7b\u522b/\u52a8\u4f5c - enqueue (bool): \u6dfb\u52a0\u5230\u4e8b\u4ef6\u961f\u5217

          "},{"location":"qsl4a/core/events/#eventunregisterforbroadcast","title":"eventUnregisterForBroadcast()","text":"

          \u53d6\u6d88\u6ce8\u518c\u5e7f\u64ad\u4e8b\u4ef6\u3002

          eventUnregisterForBroadcast(category)\n
          "},{"location":"qsl4a/core/events/#eventgetbrodcastcategories","title":"eventGetBrodcastCategories()","text":"

          \u83b7\u53d6\u5df2\u6ce8\u518c\u7684\u5e7f\u64ad\u7c7b\u522b\u3002

          eventGetBrodcastCategories()\n

          \u8fd4\u56de\uff1a \u5df2\u6ce8\u518c\u7c7b\u522b\u5217\u8868

          "},{"location":"qsl4a/core/events/#_5","title":"\u4e8b\u4ef6\u5206\u53d1\u5668)","text":""},{"location":"qsl4a/core/events/#starteventdispatcher","title":"startEventDispatcher()","text":"

          \u6253\u5f00\u4e00\u4e2a\u53ef\u4ee5\u8bfb\u53d6\u5df2\u53d1\u5e03\u4e8b\u4ef6\u7684\u5957\u63a5\u5b57\u3002)

          startEventDispatcher(port=0)\n

          \u53c2\u6570\uff1a - port (int, optional): \u76d1\u542c\u7684\u7aef\u53e3\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\u9009\u62e9\uff09

          \u8fd4\u56de\uff1a \u6b63\u5728\u76d1\u542c\u7684\u7aef\u53e3\u53f7

          "},{"location":"qsl4a/core/events/#stopeventdispatcher","title":"stopEventDispatcher()","text":"

          \u505c\u6b62\u4e8b\u4ef6\u670d\u52a1\u5668\u3002)

          stopEventDispatcher()\n
          "},{"location":"qsl4a/core/events/#_6","title":"\u5df2\u5e9f\u5f03\u65b9\u6cd5","text":""},{"location":"qsl4a/core/events/#rpcpostevent","title":"rpcPostEvent()","text":"

          \u5c06\u4e8b\u4ef6\u53d1\u5e03\u5230\u4e8b\u4ef6\u961f\u5217\u3002\uff08\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 eventPost\uff09

          rpcPostEvent(name, data)\n

          \u53c2\u6570\uff1a - name (str): \u4e8b\u4ef6\u540d\u79f0 - data: \u4e8b\u4ef6\u6570\u636e

          "},{"location":"qsl4a/core/events/#_7","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/events/#_8","title":"\u57fa\u672c\u4e8b\u4ef6\u8f6e\u8be2","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6e05\u9664\u65e7\u4e8b\u4ef6\ndroid.eventClearBuffer()\n\n# \u8f6e\u8be2\u4e8b\u4ef6\nevents = droid.eventPoll(5).result\nfor event in events:\n    print(f\"Event: {event['name']}, Data: {event['data']}\")\n
          "},{"location":"qsl4a/core/events/#_9","title":"\u7b49\u5f85\u4e8b\u4ef6","text":"
          # \u7b49\u5f85\u4efb\u610f\u4e8b\u4ef6\uff0c\u5e26\u8d85\u65f6\nevent = droid.eventWait(timeout=10).result\nif event:\n    print(f\"Got event: {event['name']}\")\n
          "},{"location":"qsl4a/core/events/#_10","title":"\u7b49\u5f85\u7279\u5b9a\u4e8b\u4ef6","text":"
          # \u7b49\u5f85\u4f20\u611f\u5668\u4e8b\u4ef6\nevent = droid.eventWaitFor('screen', timeout=5).result\nif event:\n    print(f\"Screen event: {event['data']}\")\n
          "},{"location":"qsl4a/core/events/#_11","title":"\u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6","text":"
          # \u53d1\u5e03\u81ea\u5b9a\u4e49\u4e8b\u4ef6\ndroid.eventPost('my_event', {'key': 'value'})\n\n# \u7b49\u5f85\u5b83\nevent = droid.eventWaitFor('my_event', timeout=1).result\n
          "},{"location":"qsl4a/core/events/#_12","title":"\u5e7f\u64ad\u63a5\u6536\u5668","text":"
          # \u6ce8\u518c\u5c4f\u5e55\u5f00\u5173\u4e8b\u4ef6\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_ON')\ndroid.eventRegisterForBroadcast('android.intent.action.SCREEN_OFF')\n\n# \u7b49\u5f85\u5c4f\u5e55\u4e8b\u4ef6\nwhile True:\n    event = droid.receiveEvent().result\n    if event['name'] == 'android.intent.action.SCREEN_ON':\n        print(\"Screen turned on\")\n    elif event['name'] == 'android.intent.action.SCREEN_OFF':\n        print(\"Screen turned off\")\n
          "},{"location":"qsl4a/core/events/#_13","title":"\u4f20\u611f\u5668\u4e8b\u4ef6\u5904\u7406","text":"
          # \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u5904\u7406\u4f20\u611f\u5668\u4e8b\u4ef6\nfor _ in range(100):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'sensors':\n        data = event['data']\n        print(f\"Accel: {data['xforce']}, {data['yforce']}, {data['zforce']}\")\n\ndroid.stopSensing()\n
          "},{"location":"qsl4a/core/events/#_14","title":"\u5e38\u89c1\u4e8b\u4ef6\u7c7b\u578b","text":"\u4e8b\u4ef6\u540d\u79f0 \u63cf\u8ff0 \u6765\u6e90 sensors \u4f20\u611f\u5668\u6570\u636e\u66f4\u65b0 startSensing* location GPS \u4f4d\u7f6e\u66f4\u65b0 startLocating phone \u7535\u8bdd\u72b6\u6001\u53d8\u5316 startTrackingPhoneState signal \u4fe1\u53f7\u5f3a\u5ea6\u53d8\u5316 startTrackingSignalStrength screen \u622a\u56fe\u5c31\u7eea fullGetScreenShot dialog \u5bf9\u8bdd\u6846\u54cd\u5e94 dialogShow*"},{"location":"qsl4a/core/events/#_15","title":"\u4e8b\u4ef6\u6570\u636e\u7ed3\u6784","text":"
          {\n    'name': 'event_name',\n    'data': {\n        # \u4e8b\u4ef6\u7279\u5b9a\u6570\u636e\n    },\n    'time': 1234567890  # \u65f6\u95f4\u6233\n}\n
          "},{"location":"qsl4a/core/intent/","title":"Intent \u7cfb\u7edf","text":"

          Android Intent \u7528\u4e8e\u542f\u52a8\u6d3b\u52a8\u3001\u53d1\u9001\u5e7f\u64ad\u548c\u5e94\u7528\u95f4\u901a\u4fe1\u3002QSL4A \u901a\u8fc7 Intent \u6a21\u5757\u63d0\u4f9b\u5b8c\u6574\u7684 Intent \u652f\u6301\u3002

          "},{"location":"qsl4a/core/intent/#_1","title":"\u6a21\u5757\u5bfc\u5165","text":"
          import androidhelper\ndon = androidhelper.Android()\n
          "},{"location":"qsl4a/core/intent/#intent_1","title":"Intent \u5e38\u91cf","text":"

          \u901a\u8fc7 droid.Intent \u8bbf\u95ee\uff1a

          "},{"location":"qsl4a/core/intent/#_2","title":"\u64cd\u4f5c","text":"\u5e38\u91cf \u503c \u7528\u9014 ACTION_MAIN android.intent.action.MAIN \u5e94\u7528\u5165\u53e3\u70b9 ACTION_VIEW android.intent.action.VIEW \u67e5\u770b\u5185\u5bb9 ACTION_EDIT android.intent.action.EDIT \u7f16\u8f91\u5185\u5bb9 ACTION_PICK android.intent.action.PICK \u9009\u62e9\u9879\u76ee ACTION_SEND android.intent.action.SEND \u5206\u4eab\u5185\u5bb9 ACTION_SEARCH android.intent.action.SEARCH \u641c\u7d22"},{"location":"qsl4a/core/intent/#_3","title":"\u6807\u5fd7","text":"\u5e38\u91cf \u503c \u7528\u9014 FLAG_ACTIVITY_NEW_TASK 268435456 \u542f\u52a8\u65b0\u4efb\u52a1 FLAG_ACTIVITY_CLEAR_TASK 32768 \u6e05\u9664\u4efb\u52a1\u5806\u6808 FLAG_ACTIVITY_NEW_DOCUMENT 524288 \u65b0\u6587\u6863\u6a21\u5f0f"},{"location":"qsl4a/core/intent/#_4","title":"\u9644\u52a0\u6570\u636e","text":"\u5e38\u91cf \u7528\u9014 EXTRA_TEXT \u6587\u672c\u5185\u5bb9 EXTRA_STREAM \u6587\u4ef6 URI EXTRA_SUBJECT \u4e3b\u9898\u884c EXTRA_EMAIL \u7535\u5b50\u90ae\u4ef6\u5730\u5740"},{"location":"qsl4a/core/intent/#_5","title":"\u6838\u5fc3\u65b9\u6cd5","text":""},{"location":"qsl4a/core/intent/#makeintent","title":"makeIntent()","text":"

          \u521b\u5efa Intent \u5bf9\u8c61\u3002

          makeIntent(action, uri=None, type=None, extras=None, categories=None,\n           packagename=None, classname=None, flags=None)\n

          \u53c2\u6570\uff1a - action (str): Intent \u64cd\u4f5c\uff08\u4f8b\u5982 droid.Intent.ACTION_VIEW\uff09 - uri (str, optional): \u6570\u636e URI - type (str, optional): MIME \u7c7b\u578b - extras (dict, optional): \u9644\u52a0\u6570\u636e - categories (list, optional): Intent \u7c7b\u522b - packagename (str, optional): \u76ee\u6807\u5305 - classname (str, optional): \u76ee\u6807\u7c7b - flags (int, optional): Intent \u6807\u5fd7

          \u8fd4\u56de\uff1a Intent \u5bf9\u8c61

          "},{"location":"qsl4a/core/intent/#startactivityintent","title":"startActivityIntent()","text":"

          \u4f7f\u7528 Intent \u542f\u52a8 Activity\u3002

          startActivityIntent(intent, wait=None)\n

          \u53c2\u6570\uff1a - intent: makeIntent() \u8fd4\u56de\u7684 Intent \u5bf9\u8c61 - wait (bool, optional): \u963b\u585e\u76f4\u5230\u6d3b\u52a8\u5173\u95ed

          "},{"location":"qsl4a/core/intent/#startactivityforresultintent","title":"startActivityForResultIntent()","text":"

          \u542f\u52a8\u6d3b\u52a8\u5e76\u7b49\u5f85\u7ed3\u679c\u3002

          startActivityForResultIntent(intent)\n

          \u8fd4\u56de\uff1a Activity \u7ed3\u679c

          "},{"location":"qsl4a/core/intent/#sendbroadcastintent","title":"sendBroadcastIntent()","text":"

          \u53d1\u9001\u5e7f\u64ad\u3002

          sendBroadcastIntent(intent)\n
          "},{"location":"qsl4a/core/intent/#view","title":"view()","text":"

          \u901a\u8fc7 URI \u67e5\u770b\u5185\u5bb9\u3002

          view(uri, type=None, extras=None)\n
          "},{"location":"qsl4a/core/intent/#pick","title":"pick()","text":"

          \u4ece URI \u9009\u62e9\u5185\u5bb9\u3002

          pick(uri)\n
          "},{"location":"qsl4a/core/intent/#intent_2","title":"\u5e38\u89c1 Intent \u65b9\u6cd5)","text":""},{"location":"qsl4a/core/intent/#scanbarcode","title":"scanBarcode()","text":"

          \u542f\u52a8\u6761\u7801\u626b\u63cf\u5668\u3002

          scanBarcode()\n

          \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5b57\u7b26\u4e32

          "},{"location":"qsl4a/core/intent/#send","title":"send()","text":"

          \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u5185\u5bb9\u3002

          send(type, content)\n

          \u53c2\u6570\uff1a - type (str): MIME \u7c7b\u578b - content (str): \u8981\u5206\u4eab\u7684\u5185\u5bb9

          "},{"location":"qsl4a/core/intent/#sendtext","title":"sendText()","text":"

          \u53d1\u9001\u6587\u672c\u5185\u5bb9\u3002

          sendText(text)\n

          \u53c2\u6570\uff1a - text (str): \u8981\u53d1\u9001\u7684\u6587\u672c

          "},{"location":"qsl4a/core/intent/#sendemail","title":"sendEmail()","text":"

          \u53d1\u9001\u7535\u5b50\u90ae\u4ef6\u3002

          sendEmail(to, subject, body, attachment=None)\n

          \u53c2\u6570\uff1a - to (str or list): \u6536\u4ef6\u4eba\u7535\u5b50\u90ae\u4ef6\u5730\u5740 - subject (str): \u7535\u5b50\u90ae\u4ef6\u4e3b\u9898 - body (str): \u7535\u5b50\u90ae\u4ef6\u6b63\u6587 - attachment (str, optional): \u9644\u4ef6\u6587\u4ef6\u8def\u5f84

          "},{"location":"qsl4a/core/intent/#pathtouri","title":"pathToUri()","text":"

          \u5c06\u6587\u4ef6\u8def\u5f84\u8f6c\u6362\u4e3a\u5185\u5bb9 URI\u3002

          pathToUri(path)\n

          \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

          \u8fd4\u56de\uff1a \u5185\u5bb9 URI \u5b57\u7b26\u4e32

          "},{"location":"qsl4a/core/intent/#openfile","title":"openFile()","text":"

          \u7528\u9002\u5f53\u7684\u5e94\u7528\u7a0b\u5e8f\u6253\u5f00\u6587\u4ef6\u3002

          openFile(path)\n

          \u53c2\u6570\uff1a - path (str): \u8981\u6253\u5f00\u7684\u6587\u4ef6\u8def\u5f84

          "},{"location":"qsl4a/core/intent/#sendfile","title":"sendFile()","text":"

          \u901a\u8fc7\u5206\u4eab Intent \u53d1\u9001\u6587\u4ef6\u3002

          sendFile(path)\n

          \u53c2\u6570\uff1a - path (str): \u8981\u53d1\u9001\u7684\u6587\u4ef6\u8def\u5f84

          "},{"location":"qsl4a/core/intent/#getpathtype","title":"getPathType()","text":"

          \u83b7\u53d6\u6587\u4ef6\u8def\u5f84\u7684 MIME \u7c7b\u578b\u3002

          getPathType(path)\n

          \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

          \u8fd4\u56de\uff1a MIME \u7c7b\u578b\u5b57\u7b26\u4e32

          "},{"location":"qsl4a/core/intent/#viewmap","title":"viewMap()","text":"

          \u5728\u6307\u5b9a\u4f4d\u7f6e\u6253\u5f00\u5730\u56fe\u3002

          viewMap(latitude, longitude)\n

          \u53c2\u6570\uff1a - latitude (float): \u7eac\u5ea6 - longitude (float): \u7ecf\u5ea6

          "},{"location":"qsl4a/core/intent/#viewcontacts","title":"viewContacts()","text":"

          \u6253\u5f00\u8054\u7cfb\u4eba\u5e94\u7528\u3002

          viewContacts()\n
          "},{"location":"qsl4a/core/intent/#search","title":"search()","text":"

          \u6267\u884c\u7f51\u7edc\u641c\u7d22\u3002

          search(query)\n

          \u53c2\u6570\uff1a - query (str): \u641c\u7d22\u67e5\u8be2

          "},{"location":"qsl4a/core/intent/#viewhtml","title":"viewHtml()","text":"

          \u67e5\u770b HTML \u5185\u5bb9\u3002

          viewHtml(content, encoding=None)\n

          \u53c2\u6570\uff1a - content (str): HTML \u5185\u5bb9 - encoding (str, optional): \u5b57\u7b26\u7f16\u7801

          "},{"location":"qsl4a/core/intent/#webviewshow","title":"webViewShow()","text":"

          \u5728 WebView \u4e2d\u663e\u793a\u7f51\u9875\u5185\u5bb9\u3002\u5df2\u5e9f\u5f03\uff0c\u8bf7\u4f7f\u7528 viewHtml\u3002

          webViewShow(url)\n

          \u53c2\u6570\uff1a - url (str): \u7f51\u9875 URL

          "},{"location":"qsl4a/core/intent/#editoropen","title":"editorOpen()","text":"

          \u6253\u5f00\u6587\u672c\u7f16\u8f91\u5668\u3002

          editorOpen(path=None, create=False)\n

          \u53c2\u6570\uff1a - path (str, optional): \u8981\u7f16\u8f91\u7684\u6587\u4ef6\u8def\u5f84 - create (bool, optional): \u5982\u679c\u4e0d\u5b58\u5728\u5219\u521b\u5efa

          "},{"location":"qsl4a/core/intent/#uri","title":"\u8f85\u52a9\u7c7b\uff1aUri","text":"

          \u521b\u5efa Intent \u7684 URI \u5bf9\u8c61\uff1a

          from androidhelper.Intent import Uri\n\nuri = Uri(\"file:///sdcard/test.txt\")\n
          "},{"location":"qsl4a/core/intent/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/core/intent/#_7","title":"\u6253\u5f00\u7f51\u9875","text":"
          intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"http://www.example.com\"\n).result\ndroid.startActivityIntent(intent)\n
          "},{"location":"qsl4a/core/intent/#_8","title":"\u5206\u4eab\u6587\u672c","text":"
          intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_TEXT: \"Hello from QPython!\",\n        droid.Intent.EXTRA_SUBJECT: \"Test\"\n    },\n    type=\"text/plain\"\n).result\ndroid.startActivityIntent(intent)\n
          "},{"location":"qsl4a/core/intent/#_9","title":"\u6253\u5f00\u6587\u4ef6","text":"
          intent = droid.makeIntent(\n    action=droid.Intent.ACTION_VIEW,\n    uri=\"file:///sdcard/document.pdf\",\n    type=\"application/pdf\"\n).result\ndroid.startActivityIntent(intent)\n
          "},{"location":"qsl4a/core/intent/#_10","title":"\u9009\u62e9\u8054\u7cfb\u4eba","text":"
          result = droid.pickContact()\ncontact_uri = result.result\n
          "},{"location":"qsl4a/core/intent/#_11","title":"\u53d1\u9001\u7535\u5b50\u90ae\u4ef6","text":"
          intent = droid.makeIntent(\n    action=droid.Intent.ACTION_SEND,\n    extras={\n        droid.Intent.EXTRA_EMAIL: [\"test@example.com\"],\n        droid.Intent.EXTRA_SUBJECT: \"Hello\",\n        droid.Intent.EXTRA_TEXT: \"Message body\"\n    },\n    type=\"message/rfc822\"\n).result\ndroid.startActivityIntent(intent)\n
          "},{"location":"qsl4a/core/intent/#_12","title":"\u6253\u5f00\u5e94\u7528","text":"
          intent = droid.makeIntent(\n    action=droid.Intent.ACTION_MAIN,\n    packagename=\"com.android.settings\",\n    classname=\"com.android.settings.Settings\"\n).result\ndroid.startActivityIntent(intent)\n
          "},{"location":"qsl4a/hardware/bluetooth/","title":"\u84dd\u7259 API","text":"

          \u63a7\u5236\u84dd\u7259\u9002\u914d\u5668\u5e76\u4e0e\u84dd\u7259\u8bbe\u5907\u901a\u4fe1\u3002

          "},{"location":"qsl4a/hardware/bluetooth/#_1","title":"\u9002\u914d\u5668\u63a7\u5236","text":""},{"location":"qsl4a/hardware/bluetooth/#togglebluetoothstate","title":"toggleBluetoothState()","text":"

          \u6253\u5f00/\u5173\u95ed\u84dd\u7259\u3002

          toggleBluetoothState(enabled=None, prompt=True)\n

          \u53c2\u6570\uff1a - enabled (bool): True=\u5f00\uff0cFalse=\u5173\uff0cNone=\u5207\u6362 - prompt (bool): \u663e\u793a\u7528\u6237\u63d0\u793a

          "},{"location":"qsl4a/hardware/bluetooth/#checkbluetoothstate","title":"checkBluetoothState()","text":"

          \u68c0\u67e5\u84dd\u7259\u662f\u5426\u5df2\u542f\u7528\u3002

          checkBluetoothState()\n

          \u8fd4\u56de\uff1a True/False

          "},{"location":"qsl4a/hardware/bluetooth/#getlocalname","title":"GetLocalName()","text":"

          \u83b7\u53d6\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

          GetLocalName()\n
          "},{"location":"qsl4a/hardware/bluetooth/#setlocalname","title":"SetLocalName()","text":"

          \u8bbe\u7f6e\u84dd\u7259\u8bbe\u5907\u540d\u79f0\u3002

          SetLocalName(name)\n
          "},{"location":"qsl4a/hardware/bluetooth/#getscanmode","title":"GetScanMode()","text":"

          \u83b7\u53d6\u53ef\u53d1\u73b0\u6027\u6a21\u5f0f\u3002

          GetScanMode()\n

          \u8fd4\u56de\uff1a - -1: \u5df2\u7981\u7528 - 0: \u4e0d\u53ef\u53d1\u73b0\uff0c\u4e0d\u53ef\u8fde\u63a5 - 1: \u53ef\u8fde\u63a5\uff0c\u4e0d\u53ef\u53d1\u73b0 - 3: \u53ef\u8fde\u63a5\u4e14\u53ef\u53d1\u73b0

          "},{"location":"qsl4a/hardware/bluetooth/#makediscoverable","title":"MakeDiscoverable()","text":"

          \u4f7f\u8bbe\u5907\u53ef\u53d1\u73b0\u3002

          MakeDiscoverable(duration=300)\n

          \u53c2\u6570\uff1a - duration (int): \u53ef\u53d1\u73b0\u7684\u79d2\u6570

          "},{"location":"qsl4a/hardware/bluetooth/#_2","title":"\u53d1\u73b0","text":""},{"location":"qsl4a/hardware/bluetooth/#discoverystart","title":"DiscoveryStart()","text":"

          \u5f00\u59cb\u8bbe\u5907\u53d1\u73b0\u3002

          DiscoveryStart()\n
          "},{"location":"qsl4a/hardware/bluetooth/#discoverycancel","title":"DiscoveryCancel()","text":"

          \u53d6\u6d88\u53d1\u73b0\u3002

          DiscoveryCancel()\n
          "},{"location":"qsl4a/hardware/bluetooth/#getreceiveddevices","title":"GetReceivedDevices()","text":"

          \u83b7\u53d6\u53d1\u73b0\u7684\u8bbe\u5907\u3002

          GetReceivedDevices()\n

          \u8fd4\u56de\uff1a \u8bbe\u5907\u4fe1\u606f\u5b57\u5178\u5217\u8868

          "},{"location":"qsl4a/hardware/bluetooth/#getbondeddevices","title":"GetBondedDevices()","text":"

          \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\u3002

          GetBondedDevices()\n

          \u8fd4\u56de\uff1a \u914d\u5bf9\u8bbe\u5907\u4fe1\u606f\u5217\u8868

          "},{"location":"qsl4a/hardware/bluetooth/#_3","title":"\u8fde\u63a5","text":""},{"location":"qsl4a/hardware/bluetooth/#connect","title":"Connect()","text":"

          \u8fde\u63a5\u5230\u8bbe\u5907\u3002

          Connect(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", address=None)\n

          \u53c2\u6570\uff1a - uuid (str): \u670d\u52a1 UUID - address (str): \u8bbe\u5907\u5730\u5740\uff08None = \u663e\u793a\u9009\u62e9\u5668\uff09

          \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

          "},{"location":"qsl4a/hardware/bluetooth/#accept","title":"Accept()","text":"

          \u63a5\u53d7\u4f20\u5165\u8fde\u63a5\u3002

          Accept(uuid=\"457807c0-4897-11df-9879-0800200c9a66\", timeout=0)\n
          "},{"location":"qsl4a/hardware/bluetooth/#activeconnections","title":"ActiveConnections()","text":"

          \u68c0\u67e5\u6d3b\u52a8\u8fde\u63a5\u3002

          ActiveConnections()\n
          "},{"location":"qsl4a/hardware/bluetooth/#stop","title":"Stop()","text":"

          \u65ad\u5f00\u8fde\u63a5\u3002

          Stop(connID=None)\n
          "},{"location":"qsl4a/hardware/bluetooth/#_4","title":"\u901a\u4fe1","text":""},{"location":"qsl4a/hardware/bluetooth/#write","title":"Write()","text":"

          \u53d1\u9001 ASCII \u6570\u636e\u3002

          Write(ascii, connID=\"\")\n
          "},{"location":"qsl4a/hardware/bluetooth/#writebinary","title":"WriteBinary()","text":"

          \u53d1\u9001\u4e8c\u8fdb\u5236\u6570\u636e\uff08base64 \u7f16\u7801\uff09\u3002

          WriteBinary(base64, connID=None)\n
          "},{"location":"qsl4a/hardware/bluetooth/#read","title":"Read()","text":"

          \u8bfb\u53d6 ASCII \u6570\u636e\u3002

          Read(bufferSize=4096, connID=None)\n
          "},{"location":"qsl4a/hardware/bluetooth/#readbinary","title":"ReadBinary()","text":"

          \u8bfb\u53d6\u4e8c\u8fdb\u5236\u6570\u636e\u3002

          ReadBinary(bufferSize=4096, connID=None)\n
          "},{"location":"qsl4a/hardware/bluetooth/#readline","title":"ReadLine()","text":"

          \u8bfb\u53d6\u4e00\u884c\u3002

          ReadLine(connID=None)\n
          "},{"location":"qsl4a/hardware/bluetooth/#readready","title":"ReadReady()","text":"

          \u68c0\u67e5\u662f\u5426\u6709\u53ef\u7528\u6570\u636e\u3002

          ReadReady(connID=None)\n
          "},{"location":"qsl4a/hardware/bluetooth/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u7528\u84dd\u7259\ndroid.toggleBluetoothState(True)\n\n# \u83b7\u53d6\u914d\u5bf9\u8bbe\u5907\ndevices = droid.GetBondedDevices().result\nfor dev in devices:\n    print(f\"{dev['name']}: {dev['address']}\")\n\n# \u8fde\u63a5\u5230\u8bbe\u5907\ndroid.Connect(address=\"00:11:22:33:44:55\")\n\n# \u53d1\u9001\u6570\u636e\ndroid.Write(\"Hello Bluetooth!\")\n\n# \u8bfb\u53d6\u54cd\u5e94\ndata = droid.Read(1024).result\n
          "},{"location":"qsl4a/hardware/camera/","title":"\u76f8\u673a API","text":"

          \u62cd\u6444\u7167\u7247\u548c\u5f55\u5236\u89c6\u9891\u3002

          "},{"location":"qsl4a/hardware/camera/#_1","title":"\u7167\u7247\u62cd\u6444","text":""},{"location":"qsl4a/hardware/camera/#takepicture","title":"takePicture()","text":"

          \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u6444\u7167\u7247\u3002

          takePicture(path=None)\n

          \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8fd4\u56de\u56fe\u50cf\u6570\u636e

          \u8fd4\u56de\uff1a \u56fe\u50cf\u8def\u5f84\u6216\u56fe\u50cf\u6570\u636e

          "},{"location":"qsl4a/hardware/camera/#cameracapturepicture","title":"cameraCapturePicture()","text":"

          \u4f7f\u7528\u9ad8\u7ea7\u76f8\u673a\u63a7\u5236\u62cd\u6444\u7167\u7247\u3002

          cameraCapturePicture(targetPath=None, cameraId=0, useAutoFocus=True)\n

          \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - useAutoFocus (bool): \u542f\u7528\u81ea\u52a8\u5bf9\u7126

          \u8fd4\u56de\uff1a \u62cd\u6444\u7684\u56fe\u50cf\u8def\u5f84

          "},{"location":"qsl4a/hardware/camera/#camerasettorchmode","title":"cameraSetTorchMode()","text":"

          \u63a7\u5236\u76f8\u673a\u95ea\u5149\u706f/\u624b\u7535\u7b52\u3002

          cameraSetTorchMode(enabled)\n

          \u53c2\u6570\uff1a - enabled (bool): True \u6253\u5f00\uff0cFalse \u5173\u95ed

          \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

          "},{"location":"qsl4a/hardware/camera/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

          \u622a\u56fe\u3002

          imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

          \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

          "},{"location":"qsl4a/hardware/camera/#_2","title":"\u89c6\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#takevideo","title":"takeVideo()","text":"

          \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\u3002

          takeVideo(path=None, quality=1)\n

          \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-4\uff09 - 0: 160x120 - 1: 320x240 - 2: 352x288 - 3: 640x480 - 4: 800x480

          "},{"location":"qsl4a/hardware/camera/#recordercapturevideo","title":"recorderCaptureVideo()","text":"

          \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\u3002

          recorderCaptureVideo(targetPath=None, duration=10, cameraId=0, quality=8)\n

          \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u8def\u5f84 - duration (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a10\uff09 - cameraId (int): \u4f7f\u7528\u7684\u76f8\u673a\uff080 = \u540e\u7f6e\uff0c1 = \u524d\u7f6e\uff09 - quality (int): \u89c6\u9891\u8d28\u91cf\uff080-8\uff0c\u8d8a\u9ad8\u8d8a\u597d\uff09

          \u8fd4\u56de\uff1a \u89c6\u9891\u6587\u4ef6\u8def\u5f84

          "},{"location":"qsl4a/hardware/camera/#recordaudio","title":"recordAudio()","text":"

          \u5f55\u5236\u97f3\u9891\u3002

          recordAudio()\n

          \u8fd4\u56de\uff1a \u97f3\u9891\u6587\u4ef6\u8def\u5f84

          "},{"location":"qsl4a/hardware/camera/#_3","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/camera/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

          \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\u3002

          recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

          \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\uff09 - targetPixels (int): \u5206\u8fa8\u7387 - frameRate (int): FPS - bitRate (int): \u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa - autoStart (bool): \u7acb\u5373\u5f00\u59cb

          "},{"location":"qsl4a/hardware/camera/#recorderstart","title":"recorderStart()","text":"

          \u5f00\u59cb\u5f55\u5236\u3002

          recorderStart()\n
          "},{"location":"qsl4a/hardware/camera/#recorderpause","title":"recorderPause()","text":"

          \u6682\u505c\u5f55\u5236\u3002

          recorderPause()\n
          "},{"location":"qsl4a/hardware/camera/#recorderresume","title":"recorderResume()","text":"

          \u6062\u590d\u5f55\u5236\u3002

          recorderResume()\n
          "},{"location":"qsl4a/hardware/camera/#_4","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/camera/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

          \u5f00\u59cb\u97f3\u91cf\u68c0\u6d4b\u3002

          recorderSoundVolumeDetect(interval=100)\n
          "},{"location":"qsl4a/hardware/camera/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

          \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

          recorderSoundVolumeGetDb()\n
          "},{"location":"qsl4a/hardware/camera/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u9ed8\u8ba4\u76f8\u673a\u62cd\u7167\nphoto_path = droid.takePicture(\"/sdcard/photo.jpg\").result\nprint(f\"Photo saved: {photo_path}\")\n\n# \u4f7f\u7528\u524d\u7f6e\u76f8\u673a\u548c\u81ea\u52a8\u5bf9\u7126\u62cd\u7167\ncamera_path = droid.cameraCapturePicture(\"/sdcard/selfie.jpg\", cameraId=1, useAutoFocus=True).result\nprint(f\"Front camera photo: {camera_path}\")\n\n# \u63a7\u5236\u95ea\u5149\u706f\ndroid.cameraSetTorchMode(True)  # \u6253\u5f00\u95ea\u5149\u706f\n\n# \u4f7f\u7528\u9ed8\u8ba4\u8bbe\u7f6e\u5f55\u5236\u89c6\u9891\nvideo_path = droid.takeVideo(\"/sdcard/video.mp4\", quality=3).result\nprint(f\"Video saved: {video_path}\")\n\n# \u4f7f\u7528\u9ad8\u7ea7\u63a7\u5236\u5f55\u5236\u89c6\u9891\nvideo_path = droid.recorderCaptureVideo(\"/sdcard/movie.mp4\", duration=30, cameraId=0, quality=8).result\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n
          "},{"location":"qsl4a/hardware/recorder/","title":"\u97f3\u9891\u5f55\u5236 API","text":"

          \u4ece\u9ea6\u514b\u98ce\u548c\u8bbe\u5907\u5c4f\u5e55\u5f55\u5236\u97f3\u9891\u3002

          "},{"location":"qsl4a/hardware/recorder/#_1","title":"\u97f3\u9891\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recordaudio","title":"recordAudio()","text":"

          \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\u3002

          recordAudio()\n

          \u8fd4\u56de\uff1a \u5f55\u5236\u7684\u97f3\u9891\u6587\u4ef6\u8def\u5f84

          "},{"location":"qsl4a/hardware/recorder/#recorderstartmicrophone","title":"recorderStartMicrophone()","text":"

          \u5f00\u59cb\u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\u3002

          recorderStartMicrophone(targetPath=None)\n

          \u53c2\u6570\uff1a - targetPath (str, optional): \u4fdd\u5b58\u5f55\u5236\u7684\u8def\u5f84

          "},{"location":"qsl4a/hardware/recorder/#_2","title":"\u5c4f\u5e55\u5f55\u5236","text":""},{"location":"qsl4a/hardware/recorder/#recorderstartscreenrecord","title":"recorderStartScreenRecord()","text":"

          \u5f00\u59cb\u5e26\u97f3\u9891\u7684\u5c4f\u5e55\u5f55\u5236\u3002

          recorderStartScreenRecord(path=None, audio=1, targetPixels=None,\n                          frameRate=30, bitRate=None, rotation=False,\n                          autoStart=True)\n

          \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u4fdd\u5b58\u8def\u5f84 - audio (int): \u97f3\u9891\u6e90\uff080=\u65e0\uff0c1=\u9ea6\u514b\u98ce\uff0c2=\u5185\u90e8\u97f3\u9891\uff09 - targetPixels (int): \u76ee\u6807\u5206\u8fa8\u7387\uff08\u50cf\u7d20\uff09 - frameRate (int): \u6bcf\u79d2\u5e27\u6570\uff08\u9ed8\u8ba4\uff1a30\uff09 - bitRate (int): \u89c6\u9891\u6bd4\u7279\u7387 - rotation (bool): \u65cb\u8f6c\u8f93\u51fa\u89c6\u9891 - autoStart (bool): \u7acb\u5373\u5f00\u59cb\u5f55\u5236

          \u8fd4\u56de\uff1a \u64cd\u4f5c\u7ed3\u679c

          "},{"location":"qsl4a/hardware/recorder/#recorderstart","title":"recorderStart()","text":"

          \u5f00\u59cb\u5c4f\u5e55\u5f55\u5236\uff08\u5f53 autoStart=False \u65f6\uff09\u3002

          recorderStart()\n
          "},{"location":"qsl4a/hardware/recorder/#recorderpause","title":"recorderPause()","text":"

          \u6682\u505c\u6b63\u5728\u8fdb\u884c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

          recorderPause()\n
          "},{"location":"qsl4a/hardware/recorder/#recorderresume","title":"recorderResume()","text":"

          \u6062\u590d\u6682\u505c\u7684\u5c4f\u5e55\u5f55\u5236\u3002

          recorderResume()\n
          "},{"location":"qsl4a/hardware/recorder/#_3","title":"\u97f3\u9891\u97f3\u91cf\u68c0\u6d4b","text":""},{"location":"qsl4a/hardware/recorder/#recordersoundvolumedetect","title":"recorderSoundVolumeDetect()","text":"

          \u5f00\u59cb\u76d1\u63a7\u97f3\u91cf\u7ea7\u522b\u3002

          recorderSoundVolumeDetect(interval=100)\n

          \u53c2\u6570\uff1a - interval (int): \u68c0\u6d4b\u95f4\u9694\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a100\uff09

          "},{"location":"qsl4a/hardware/recorder/#recordersoundvolumegetdb","title":"recorderSoundVolumeGetDb()","text":"

          \u83b7\u53d6\u5f53\u524d\u97f3\u91cf\uff08\u5206\u8d1d\uff09\u3002

          recorderSoundVolumeGetDb()\n

          \u8fd4\u56de\uff1a \u5f53\u524d\u97f3\u91cf\u7ea7\u522b\uff08dB\uff09

          "},{"location":"qsl4a/hardware/recorder/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u4ece\u9ea6\u514b\u98ce\u5f55\u5236\u97f3\u9891\nprint(\"Recording audio...\")\naudio_path = droid.recordAudio().result\nprint(f\"Saved to: {audio_path}\")\n\n# \u5f55\u5236\u5230\u7279\u5b9a\u6587\u4ef6\ndroid.recorderStartMicrophone(\"/sdcard/my_recording.mp3\")\ntime.sleep(5)\ndroid.recorderStop()\n\n# \u5e26\u97f3\u9891\u5f55\u5236\u5c4f\u5e55\nprint(\"Starting screen recording...\")\ndroid.recorderStartScreenRecord(\n    path=\"/sdcard/screen_record.mp4\",\n    audio=1,\n    frameRate=30,\n    autoStart=True\n)\ntime.sleep(10)\ndroid.recorderStop()\n\n# \u76d1\u63a7\u97f3\u91cf\ndroid.recorderSoundVolumeDetect(interval=100)\ntime.sleep(3)\nvolume = droid.recorderSoundVolumeGetDb().result\nprint(f\"Current volume: {volume} dB\")\n
          "},{"location":"qsl4a/hardware/usbserial/","title":"USB \u4e3b\u673a\u4e32\u884c API","text":"

          \u4e0e USB \u4e32\u884c\u8bbe\u5907\u901a\u4fe1\uff08\u9700\u8981 USB OTG \u652f\u6301\u548c Android 3.1+\uff09\u3002

          "},{"location":"qsl4a/hardware/usbserial/#usb","title":"USB \u4e32\u884c\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialopen","title":"usbHostSerialOpen()","text":"

          \u6253\u5f00\u4e0e USB \u4e32\u884c\u8bbe\u5907\u7684\u8fde\u63a5\u3002

          usbHostSerialOpen(device, baudRate=9600)\n

          \u53c2\u6570\uff1a - device (str): USB \u8bbe\u5907\u8def\u5f84\u6216\u6807\u8bc6\u7b26 - baudRate (int): \u6ce2\u7279\u7387\uff08\u9ed8\u8ba4\uff1a9600\uff09

          \u8fd4\u56de\uff1a \u5982\u679c\u6253\u5f00\u6210\u529f\u5219\u4e3a True

          "},{"location":"qsl4a/hardware/usbserial/#usbhostserialclose","title":"usbHostSerialClose()","text":"

          \u5173\u95ed USB \u4e32\u884c\u8fde\u63a5\u3002

          usbHostSerialClose()\n
          "},{"location":"qsl4a/hardware/usbserial/#usbhostserialread","title":"usbHostSerialRead()","text":"

          \u4ece USB \u4e32\u884c\u8bfb\u53d6\u6570\u636e\u3002

          usbHostSerialRead(bufferSize=1024)\n

          \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570\uff08\u9ed8\u8ba4\uff1a1024\uff09

          \u8fd4\u56de\uff1a \u8bfb\u53d6\u7684\u6570\u636e\u5b57\u7b26\u4e32

          "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwrite","title":"usbHostSerialWrite()","text":"

          \u5411 USB \u4e32\u884c\u5199\u5165\u6570\u636e\u3002

          usbHostSerialWrite(data)\n

          \u53c2\u6570\uff1a - data (str): \u8981\u5199\u5165\u7684\u5b57\u7b26\u4e32\u6570\u636e

          "},{"location":"qsl4a/hardware/usbserial/#usbhostserialavailable","title":"usbHostSerialAvailable()","text":"

          \u68c0\u67e5\u662f\u5426\u6709\u53ef\u8bfb\u53d6\u7684\u6570\u636e\u3002

          usbHostSerialAvailable()\n

          \u8fd4\u56de\uff1a \u53ef\u7528\u5b57\u8282\u6570

          "},{"location":"qsl4a/hardware/usbserial/#_1","title":"\u914d\u7f6e\u65b9\u6cd5)","text":""},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetbaudrate","title":"usbHostSerialSetBaudRate()","text":"

          \u8bbe\u7f6e\u6ce2\u7279\u7387\u3002

          usbHostSerialSetBaudRate(baudRate)\n

          \u53c2\u6570\uff1a - baudRate (int): \u6ce2\u7279\u7387

          "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetdatabits","title":"usbHostSerialSetDataBits()","text":"

          \u8bbe\u7f6e\u6570\u636e\u4f4d\uff085\u30016\u30017 \u6216 8\uff09\u3002

          usbHostSerialSetDataBits(dataBits)\n

          \u53c2\u6570\uff1a - dataBits (int): \u6570\u636e\u4f4d\uff085-8\uff09

          "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetstopbits","title":"usbHostSerialSetStopBits()","text":"

          \u8bbe\u7f6e\u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09\u3002

          usbHostSerialSetStopBits(stopBits)\n

          \u53c2\u6570\uff1a - stopBits (float): \u505c\u6b62\u4f4d\uff081\u30011.5 \u6216 2\uff09

          "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetparity","title":"usbHostSerialSetParity()","text":"

          \u8bbe\u7f6e\u6821\u9a8c\u4f4d\uff08\u65e0\u3001\u5947\u3001\u5076\u3001\u6807\u8bb0\u3001\u7a7a\u683c\uff09\u3002

          usbHostSerialSetParity(parity)\n

          \u53c2\u6570\uff1a - parity (str): \u6821\u9a8c\u6a21\u5f0f\uff08'none'\u3001'odd'\u3001'even'\u3001'mark'\u3001'space'\uff09

          "},{"location":"qsl4a/hardware/usbserial/#usbhostserialsetflowcontrol","title":"usbHostSerialSetFlowControl()","text":"

          \u8bbe\u7f6e\u6d41\u63a7\u5236\uff08\u65e0\u3001\u786c\u4ef6\u3001\u8f6f\u4ef6\uff09\u3002

          usbHostSerialSetFlowControl(flowControl)\n

          \u53c2\u6570\uff1a - flowControl (str): \u6d41\u63a7\u5236\u6a21\u5f0f\uff08'none'\u3001'hardware'\u3001'software'\uff09

          "},{"location":"qsl4a/hardware/usbserial/#usbhostserialreadhex","title":"usbHostSerialReadHex()","text":"

          \u4ee5\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u8bfb\u53d6\u6570\u636e\u3002

          usbHostSerialReadHex(bufferSize=1024)\n

          \u53c2\u6570\uff1a - bufferSize (int): \u8981\u8bfb\u53d6\u7684\u6700\u5927\u5b57\u8282\u6570

          \u8fd4\u56de\uff1a \u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

          "},{"location":"qsl4a/hardware/usbserial/#usbhostserialwritehex","title":"usbHostSerialWriteHex()","text":"

          \u4ece\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32\u5199\u5165\u6570\u636e\u3002

          usbHostSerialWriteHex(hexString)\n

          \u53c2\u6570\uff1a - hexString (str): \u8981\u5199\u5165\u7684\u5341\u516d\u8fdb\u5236\u5b57\u7b26\u4e32

          "},{"location":"qsl4a/hardware/usbserial/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6253\u5f00 USB \u4e32\u884c\u8fde\u63a5\nif droid.usbHostSerialOpen(\"/dev/bus/usb/001/001\", 115200).result:\n    print(\"USB serial opened\")\n\n    # \u5199\u5165\u6570\u636e\n    droid.usbHostSerialWrite(\"AT\\r\")\n\n    # \u8bfb\u53d6\u54cd\u5e94\n    response = droid.usbHostSerialRead(1024).result\n    print(f\"Response: {response}\")\n\n    # \u6216\u4f7f\u7528\u5341\u516d\u8fdb\u5236\n    droid.usbHostSerialWriteHex(\"41540D0A\")  # \"AT\\r\\n\"\n\n    # \u5173\u95ed\u8fde\u63a5\n    droid.usbHostSerialClose()\n

          \u6ce8\u610f\uff1a USB \u4e32\u884c\u9700\u8981\uff1a - Android 3.1+ (API 12) - USB OTG \u7ebf/\u9002\u914d\u5668 - \u8bbe\u5907\u4e0a\u7684 USB \u4e3b\u673a\u6a21\u5f0f\u652f\u6301 - \u517c\u5bb9\u7684\u4e32\u884c\u8bbe\u5907

          "},{"location":"qsl4a/hardware/webcam/","title":"\u7f51\u7edc\u6444\u50cf\u5934 API","text":"

          \u4f7f\u7528 MJPEG \u4ece\u8bbe\u5907\u76f8\u673a\u6d41\u5f0f\u4f20\u8f93\u89c6\u9891\u3002

          "},{"location":"qsl4a/hardware/webcam/#mjpeg","title":"MJPEG \u6d41\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#webcamstart","title":"webcamStart()","text":"

          \u4ece\u7f51\u7edc\u6444\u50cf\u5934\u542f\u52a8 MJPEG \u6d41\u3002

          webcamStart(resolutionLevel=0, jpegQuality=20, port=0)\n

          \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf 1-100\uff08\u9ed8\u8ba4\uff1a20\uff09 - port (int): \u7aef\u53e3\u53f7\uff08\u9ed8\u8ba4\uff1a0 = \u81ea\u52a8\uff09

          \u8fd4\u56de\uff1a \u6d41\u7684 (\u5730\u5740, \u7aef\u53e3) \u5143\u7ec4

          "},{"location":"qsl4a/hardware/webcam/#webcamadjustquality","title":"webcamAdjustQuality()","text":"

          \u8c03\u6574\u6d3b\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u7684\u8d28\u91cf\u3002

          webcamAdjustQuality(resolutionLevel=0, jpegQuality=20)\n

          \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b - jpegQuality (int): JPEG \u8d28\u91cf 1-100

          "},{"location":"qsl4a/hardware/webcam/#webcamstop","title":"webcamStop()","text":"

          \u505c\u6b62\u7f51\u7edc\u6444\u50cf\u5934\u6d41\u3002

          webcamStop()\n
          "},{"location":"qsl4a/hardware/webcam/#_1","title":"\u76f8\u673a\u9884\u89c8\u65b9\u6cd5","text":""},{"location":"qsl4a/hardware/webcam/#camerastartpreview","title":"cameraStartPreview()","text":"

          \u5f00\u59cb\u5e26\u4e8b\u4ef6\u751f\u6210\u7684\u76f8\u673a\u9884\u89c8\u6a21\u5f0f\u3002

          cameraStartPreview(resolutionLevel=0, jpegQuality=20, filepath=None)\n

          \u53c2\u6570\uff1a - resolutionLevel (int): \u5206\u8fa8\u7387\u7ea7\u522b\uff08\u9ed8\u8ba4\uff1a0\uff09 - jpegQuality (int): JPEG \u8d28\u91cf\uff08\u9ed8\u8ba4\uff1a20\uff09 - filepath (str, optional): \u4fdd\u5b58\u9884\u89c8\u5e27\u7684\u6587\u4ef6\u8def\u5f84

          \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

          \u6ce8\u610f\uff1a \u751f\u6210\u5e26\u6709\u5e27\u6570\u636e\u7684 'preview' \u4e8b\u4ef6\u3002

          "},{"location":"qsl4a/hardware/webcam/#camerastoppreview","title":"cameraStopPreview()","text":"

          \u505c\u6b62\u76f8\u673a\u9884\u89c8\u3002

          cameraStopPreview()\n
          "},{"location":"qsl4a/hardware/webcam/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u7f51\u7edc\u6444\u50cf\u5934\u6d41\nstream_info = droid.webcamStart(\n    resolutionLevel=0,\n    jpegQuality=30,\n    port=8080\n).result\nprint(f\"Stream available at {stream_info[0]}:{stream_info[1]}\")\n\n# \u6d41\u5f0f\u4f20\u8f93\u65f6\u8c03\u6574\u8d28\u91cf\ntime.sleep(5)\ndroid.webcamAdjustQuality(resolutionLevel=1, jpegQuality=50)\n\n# \u5b8c\u6210\u540e\u505c\u6b62\ndroid.webcamStop()\n\n# \u6216\u4f7f\u7528\u9884\u89c8\u6a21\u5f0f\nprint(\"Starting preview...\")\ndroid.cameraStartPreview()\n\n# \u7b49\u5f85\u9884\u89c8\u4e8b\u4ef6\nfor i in range(10):\n    event = droid.eventWait(timeout=1).result\n    if event and event['name'] == 'preview':\n        print(f\"Got preview frame: {event['data']}\")\n\ndroid.cameraStopPreview()\n
          "},{"location":"qsl4a/media/image/","title":"\u56fe\u50cf\u5904\u7406 API","text":"

          \u538b\u7f29\u548c\u5904\u7406\u56fe\u50cf\u3002

          "},{"location":"qsl4a/media/image/#_1","title":"\u56fe\u50cf\u538b\u7f29","text":""},{"location":"qsl4a/media/image/#imagecompress","title":"imageCompress()","text":"

          \u538b\u7f29\u56fe\u50cf\u6587\u4ef6\u3002

          imageCompress(srcPath, destPath, targetByteSize=0, targetWidth=0, targetHeight=0)\n

          \u53c2\u6570\uff1a - srcPath (str): \u6e90\u56fe\u50cf\u8def\u5f84 - destPath (str): \u8f93\u51fa\u8def\u5f84 - targetByteSize (int): \u76ee\u6807\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff080 = \u65e0\u9650\u5236\uff09 - targetWidth (int): \u76ee\u6807\u5bbd\u5ea6\uff080 = \u539f\u59cb\uff09 - targetHeight (int): \u76ee\u6807\u9ad8\u5ea6\uff080 = \u539f\u59cb\uff09

          \u8fd4\u56de\uff1a \u538b\u7f29\u540e\u7684\u56fe\u50cf\u8def\u5f84

          "},{"location":"qsl4a/media/image/#_2","title":"\u622a\u56fe","text":""},{"location":"qsl4a/media/image/#imagereadergetscreenshot","title":"imageReaderGetScreenShot()","text":"

          \u622a\u53d6\u5c4f\u5e55\u3002

          imageReaderGetScreenShot(path=None, delayMilliSec=1000)\n

          \u53c2\u6570\uff1a - path (str): \u4fdd\u5b58\u8def\u5f84 - delayMilliSec (int): \u62cd\u6444\u524d\u5ef6\u8fdf

          \u8fd4\u56de\uff1a \u622a\u56fe\u8def\u5f84

          "},{"location":"qsl4a/media/image/#_3","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/image/#videoplay","title":"videoPlay()","text":"

          \u5728\u5168\u5c4f\u6a21\u5f0f\u4e0b\u64ad\u653e\u89c6\u9891\u6587\u4ef6\u3002

          videoPlay(path, wait=True)\n

          \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

          "},{"location":"qsl4a/media/image/#_4","title":"\u6761\u7801\u626b\u63cf","text":""},{"location":"qsl4a/media/image/#scanbarcodefromimage","title":"scanBarcodeFromImage()","text":"

          \u4ece\u56fe\u50cf\u6587\u4ef6\u626b\u63cf\u6761\u7801/\u4e8c\u7ef4\u7801\u3002

          scanBarcodeFromImage(path, compressRatio=0, x=0, y=0, width=0, height=0)\n

          \u53c2\u6570\uff1a - path (str): \u56fe\u50cf\u6587\u4ef6\u8def\u5f84 - compressRatio (int): \u538b\u7f29\u6bd4\uff080 = \u4e0d\u538b\u7f29\uff09 - x, y, width, height (int): \u8981\u626b\u63cf\u7684\u533a\u57df\uff080 = \u5b8c\u6574\u56fe\u50cf\uff09

          \u8fd4\u56de\uff1a \u626b\u63cf\u7684\u6761\u7801\u5185\u5bb9

          "},{"location":"qsl4a/media/image/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u622a\u56fe\nss_path = droid.imageReaderGetScreenShot(\"/sdcard/screenshot.png\", 500).result\n\n# \u538b\u7f29\u56fe\u50cf\ncompressed = droid.imageCompress(\n    \"/sdcard/large_photo.jpg\",\n    \"/sdcard/compressed.jpg\",\n    targetByteSize=102400,  # \u76ee\u6807\u7ea6 100KB\n    targetWidth=1920,\n    targetHeight=1080\n).result\nprint(f\"Saved: {compressed}\")\n\n# \u64ad\u653e\u89c6\u9891\nvideo_path = \"/sdcard/movie.mp4\"\ndroid.videoPlay(video_path, wait=True)\n\n# \u4ece\u56fe\u50cf\u626b\u63cf\u6761\u7801\nresult = droid.scanBarcodeFromImage(\"/sdcard/qr_code.png\").result\nprint(f\"Barcode: {result}\")\n
          "},{"location":"qsl4a/media/mediaplayer/","title":"\u5a92\u4f53\u64ad\u653e\u5668 API","text":"

          \u63a7\u5236\u97f3\u9891\u548c\u89c6\u9891\u64ad\u653e\u3002

          "},{"location":"qsl4a/media/mediaplayer/#_1","title":"\u64ad\u653e\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplay","title":"mediaPlay()","text":"

          \u64ad\u653e\u5a92\u4f53\u6587\u4ef6\u3002

          mediaPlay(url, tag=\"default\", play=True)\n

          \u53c2\u6570\uff1a - url (str): \u5a92\u4f53\u6587\u4ef6\u8def\u5f84\u6216 URL - tag (str): \u64ad\u653e\u5668\u6807\u8bc6\u7b26 - play (bool): \u81ea\u52a8\u5f00\u59cb\u64ad\u653e

          "},{"location":"qsl4a/media/mediaplayer/#mediaplaystart","title":"mediaPlayStart()","text":"

          \u5f00\u59cb\u64ad\u653e\u3002

          mediaPlayStart(tag=\"default\")\n
          "},{"location":"qsl4a/media/mediaplayer/#mediaplaypause","title":"mediaPlayPause()","text":"

          \u6682\u505c\u64ad\u653e\u3002

          mediaPlayPause(tag=\"default\")\n
          "},{"location":"qsl4a/media/mediaplayer/#mediaplayclose","title":"mediaPlayClose()","text":"

          \u5173\u95ed\u64ad\u653e\u5668\u3002

          mediaPlayClose(tag=\"default\")\n
          "},{"location":"qsl4a/media/mediaplayer/#mediaplayseek","title":"mediaPlaySeek()","text":"

          \u8df3\u8f6c\u5230\u4f4d\u7f6e\u3002

          mediaPlaySeek(msec, tag=\"default\")\n

          \u53c2\u6570\uff1a - msec (int): \u4f4d\u7f6e\uff08\u6beb\u79d2\uff09

          "},{"location":"qsl4a/media/mediaplayer/#mediaplaysetlooping","title":"mediaPlaySetLooping()","text":"

          \u8bbe\u7f6e\u5faa\u73af\u6a21\u5f0f\u3002

          mediaPlaySetLooping(enabled, tag=\"default\")\n
          "},{"location":"qsl4a/media/mediaplayer/#_2","title":"\u64ad\u653e\u5668\u4fe1\u606f","text":""},{"location":"qsl4a/media/mediaplayer/#mediaplayinfo","title":"mediaPlayInfo()","text":"

          \u83b7\u53d6\u64ad\u653e\u4fe1\u606f\u3002

          mediaPlayInfo(tag=\"default\")\n

          \u8fd4\u56de\uff1a \u5305\u542b\u65f6\u957f\u3001\u4f4d\u7f6e\u7b49\u7684\u5b57\u5178

          "},{"location":"qsl4a/media/mediaplayer/#mediaisplaying","title":"mediaIsPlaying()","text":"

          \u68c0\u67e5\u662f\u5426\u6b63\u5728\u64ad\u653e\u3002

          mediaIsPlaying(tag=\"default\")\n

          \u8fd4\u56de\uff1a True/False

          "},{"location":"qsl4a/media/mediaplayer/#mediaplaylist","title":"mediaPlayList()","text":"

          \u5217\u51fa\u6d3b\u52a8\u64ad\u653e\u5668\u3002

          mediaPlayList()\n
          "},{"location":"qsl4a/media/mediaplayer/#_3","title":"\u97f3\u91cf\u63a7\u5236","text":""},{"location":"qsl4a/media/mediaplayer/#getmediavolume","title":"getMediaVolume()","text":"

          \u83b7\u53d6\u5a92\u4f53\u97f3\u91cf\u3002

          getMediaVolume()\n

          \u8fd4\u56de\uff1a \u97f3\u91cf\u7ea7\u522b\uff080-15\uff09

          "},{"location":"qsl4a/media/mediaplayer/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

          \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

          getMaxMediaVolume()\n
          "},{"location":"qsl4a/media/mediaplayer/#getringervolume","title":"getRingerVolume()","text":"

          \u83b7\u53d6\u94c3\u58f0\u97f3\u91cf\u3002

          getRingerVolume()\n
          "},{"location":"qsl4a/media/mediaplayer/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

          \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

          getMaxRingerVolume()\n
          "},{"location":"qsl4a/media/mediaplayer/#_4","title":"\u89c6\u9891\u64ad\u653e","text":""},{"location":"qsl4a/media/mediaplayer/#videoplay","title":"videoPlay()","text":"

          \u5168\u5c4f\u64ad\u653e\u89c6\u9891\u3002

          videoPlay(path, wait=True)\n

          \u53c2\u6570\uff1a - path (str): \u89c6\u9891\u6587\u4ef6\u8def\u5f84 - wait (bool): \u7b49\u5f85\u64ad\u653e\u5b8c\u6210

          "},{"location":"qsl4a/media/mediaplayer/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u64ad\u653e\u97f3\u9891\ndroid.mediaPlay(\"/sdcard/music.mp3\", tag=\"music\")\n\n# \u68c0\u67e5\u72b6\u6001\nif droid.mediaIsPlaying(\"music\").result:\n    info = droid.mediaPlayInfo(\"music\").result\n    print(f\"Playing: {info}\")\n\n# \u8df3\u8f6c\u5230 30 \u79d2\ndroid.mediaPlaySeek(30000, \"music\")\n\n# \u5173\u95ed\ndroid.mediaPlayClose(\"music\")\n\n# \u64ad\u653e\u89c6\u9891\ndroid.videoPlay(\"/sdcard/movie.mp4\", wait=True)\n
          "},{"location":"qsl4a/special/cipher/","title":"\u5bc6\u7801 API","text":"

          \u7528\u4e8e\u5b89\u5168\u6570\u636e\u5b58\u50a8\u7684\u52a0\u5bc6\u548c\u89e3\u5bc6\u5de5\u5177\u3002

          "},{"location":"qsl4a/special/cipher/#_1","title":"\u521d\u59cb\u5316","text":""},{"location":"qsl4a/special/cipher/#cipherinit","title":"cipherInit()","text":"

          \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u548c\u7b97\u6cd5\u521d\u59cb\u5316\u5bc6\u7801\u5668\u3002

          cipherInit(key, algorithm=\"AES/CBC/PKCS5Padding\", encodingFormat=\"\", initialVector=\"\")\n

          \u53c2\u6570\uff1a - key (str or bytes): \u52a0\u5bc6\u5bc6\u94a5 - algorithm (str): \u5bc6\u7801\u7b97\u6cd5\uff08\u9ed8\u8ba4\uff1a\"AES/CBC/PKCS5Padding\"\uff09 - encodingFormat (str): \u7f16\u7801\u683c\u5f0f - initialVector (str or bytes): \u52a0\u5bc6\u7684\u521d\u59cb\u5411\u91cf

          \u8fd4\u56de\uff1a \u521d\u59cb\u5316\u7ed3\u679c

          \u6ce8\u610f\uff1a \u5fc5\u987b\u5728\u4efb\u4f55\u52a0\u5bc6/\u89e3\u5bc6\u64cd\u4f5c\u4e4b\u524d\u8c03\u7528\u3002

          "},{"location":"qsl4a/special/cipher/#_2","title":"\u52a0\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#encryptstring","title":"encryptString()","text":"

          \u52a0\u5bc6\u5b57\u7b26\u4e32\u3002

          encryptString(plainText)\n

          \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c

          \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u7b26\u4e32

          "},{"location":"qsl4a/special/cipher/#encryptbytes","title":"encryptBytes()","text":"

          \u52a0\u5bc6\u5b57\u8282\u6570\u636e\u3002

          encryptBytes(data)\n

          \u53c2\u6570\uff1a - data (bytes): \u8981\u52a0\u5bc6\u7684\u6570\u636e

          \u8fd4\u56de\uff1a \u52a0\u5bc6\u7684\u5b57\u8282

          "},{"location":"qsl4a/special/cipher/#encryptstringtofile","title":"encryptStringToFile()","text":"

          \u52a0\u5bc6\u5b57\u7b26\u4e32\u5230\u6587\u4ef6\u3002

          encryptStringToFile(plainText, filePath)\n

          \u53c2\u6570\uff1a - plainText (str): \u8981\u52a0\u5bc6\u7684\u6587\u672c - filePath (str): \u8f93\u51fa\u6587\u4ef6\u8def\u5f84

          "},{"location":"qsl4a/special/cipher/#encryptbytestofile","title":"encryptBytesToFile()","text":"

          \u52a0\u5bc6\u5b57\u8282\u5230\u6587\u4ef6\u3002

          encryptBytesToFile(data, filePath)\n
          "},{"location":"qsl4a/special/cipher/#_3","title":"\u89e3\u5bc6\u65b9\u6cd5","text":""},{"location":"qsl4a/special/cipher/#decryptstring","title":"decryptString()","text":"

          \u89e3\u5bc6\u4e3a\u5b57\u7b26\u4e32\u3002

          decryptString(cipherText)\n

          \u53c2\u6570\uff1a - cipherText (str): \u52a0\u5bc6\u7684\u6587\u672c

          \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u7b26\u4e32

          "},{"location":"qsl4a/special/cipher/#decryptbytes","title":"decryptBytes()","text":"

          \u89e3\u5bc6\u4e3a\u5b57\u8282\u3002

          decryptBytes(data)\n

          \u8fd4\u56de\uff1a \u89e3\u5bc6\u7684\u5b57\u8282

          "},{"location":"qsl4a/special/cipher/#decryptfiletostring","title":"decryptFileToString()","text":"

          \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u7b26\u4e32\u3002

          decryptFileToString(filePath)\n
          "},{"location":"qsl4a/special/cipher/#decryptfiletobytes","title":"decryptFileToBytes()","text":"

          \u89e3\u5bc6\u6587\u4ef6\u5230\u5b57\u8282\u3002

          decryptFileToBytes(filePath)\n
          "},{"location":"qsl4a/special/cipher/#decryptfile","title":"decryptFile()","text":"

          \u89e3\u5bc6\u6587\u4ef6\u5230\u6587\u4ef6\u3002

          decryptFile(srcPath, destPath)\n
          "},{"location":"qsl4a/special/cipher/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u4f7f\u7528\u52a0\u5bc6\u5bc6\u94a5\u521d\u59cb\u5316\u5bc6\u7801\u5668\ndroid.cipherInit(\"my_secret_key_1234\")\n\n# \u52a0\u5bc6\u5b57\u7b26\u4e32\nencrypted = droid.encryptString(\"Secret message!\").result\nprint(f\"Encrypted: {encrypted}\")\n\n# \u89e3\u5bc6\u5b57\u7b26\u4e32\ndecrypted = droid.decryptString(encrypted).result\nprint(f\"Decrypted: {decrypted}\")\n\n# \u52a0\u5bc6\u5230\u6587\u4ef6\ndroid.encryptStringToFile(\"My secret data\", \"/sdcard/secret.dat\")\n\n# \u4ece\u6587\u4ef6\u89e3\u5bc6\ndata = droid.decryptFileToString(\"/sdcard/secret.dat\").result\nprint(data)\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u7b97\u6cd5\u548c IV \u521d\u59cb\u5316\ndroid.cipherInit(\n    key=\"my_key\",\n    algorithm=\"AES/CBC/PKCS5Padding\",\n    initialVector=\"0123456789abcdef\"\n)\n
          "},{"location":"qsl4a/special/pgptai/","title":"PGPT AI API","text":"

          \u8bed\u97f3\u8f6c\u6587\u672c\u548c AI \u670d\u52a1\u96c6\u6210\u3002

          "},{"location":"qsl4a/special/pgptai/#_1","title":"\u5148\u51b3\u6761\u4ef6","text":"
          pip install pgptAI\n
          "},{"location":"qsl4a/special/pgptai/#_2","title":"\u8bed\u97f3\u8bc6\u522b","text":""},{"location":"qsl4a/special/pgptai/#speechtotext","title":"speechToText()","text":"

          \u5c06\u8bed\u97f3\u8f6c\u6362\u4e3a\u6587\u672c\u3002

          speechToText(RecordSecond=10, AmrFile=None, Language=None)\n

          \u53c2\u6570\uff1a - RecordSecond (int): \u5f55\u5236\u65f6\u957f\uff08\u79d2\uff09 - AmrFile (str, optional): \u73b0\u6709\u97f3\u9891\u6587\u4ef6\u8def\u5f84 - Language (str, optional): \u8bed\u8a00\u4ee3\u7801\uff08'en'\u3001'zh'\uff09

          \u8fd4\u56de\uff1a \u8f6c\u5f55\u7684\u6587\u672c

          "},{"location":"qsl4a/special/pgptai/#_3","title":"\u6587\u672c\u8f6c\u8bed\u97f3","text":""},{"location":"qsl4a/special/pgptai/#texttospeech","title":"textToSpeech()","text":"

          \u5c06\u6587\u672c\u8f6c\u6362\u4e3a\u8bed\u97f3\u5e76\u53ef\u9009\u5730\u64ad\u653e\u3002

          textToSpeech(Text, AutoPlay=True, WavFile=None, VoiceName=None)\n

          \u53c2\u6570\uff1a - Text (str): \u8981\u8f6c\u6362\u4e3a\u8bed\u97f3\u7684\u6587\u672c - AutoPlay (bool): \u81ea\u52a8\u64ad\u653e\u751f\u6210\u7684\u97f3\u9891\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - WavFile (str, optional): \u4fdd\u5b58 WAV \u6587\u4ef6\u7684\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u4f7f\u7528\u4e34\u65f6\u6587\u4ef6 - VoiceName (str, optional): \u8981\u4f7f\u7528\u7684\u8bed\u97f3\u540d\u79f0\uff08\u4f8b\u5982 'en-US-JennyNeural'\u3001'zh-CN-XiaoxiaoNeural'\uff09

          \u8fd4\u56de\uff1a \u5305\u542b\u8bed\u97f3\u5408\u6210\u7ed3\u679c\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - text: \u8f93\u5165\u6587\u672c - url: \u4e0b\u8f7d\u97f3\u9891\u6587\u4ef6\u7684 URL - WavFile: \u4fdd\u5b58\u7684 WAV \u6587\u4ef6\u8def\u5f84\uff08\u5982\u679c\u672c\u5730\u4fdd\u5b58\uff09

          "},{"location":"qsl4a/special/pgptai/#_4","title":"\u914d\u7f6e","text":"

          API \u4f7f\u7528\u4ee5\u4e0b\u914d\u7f6e\u6587\u4ef6\u4e2d\u7684\u914d\u7f6e\uff1a/storage/emulated/0/Android/data/org.qpython.qpy/files/apigpt.conf\uff1a

          [speech]\nspeech_key = your_api_key\n

          \u9ed8\u8ba4\u8bed\u97f3\u8bbe\u7f6e\uff1a - \u82f1\u8bed\uff1aen-US-JennyNeural - \u4e2d\u6587\uff1azh-CN-XiaoxiaoNeural

          "},{"location":"qsl4a/special/pgptai/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5f55\u5236\u5e76\u8f6c\u5f55\nprint(\"Recording for 5 seconds...\")\ntext = droid.speechToText(RecordSecond=5, Language='en').result\nprint(f\"You said: {text}\")\n\n# \u8f6c\u5f55\u73b0\u6709\u6587\u4ef6\ntext = droid.speechToText(AmrFile=\"/sdcard/recording.amr\").result\nprint(f\"Transcription: {text}\")\n\n# \u6587\u672c\u8f6c\u8bed\u97f3\ndroid.textToSpeech(\"Hello, this is a test message.\", AutoPlay=True, Language='en')\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u8bed\u97f3\u5e76\u4fdd\u5b58\u5230\u6587\u4ef6\u7684\u6587\u672c\u8f6c\u8bed\u97f3\nresult = droid.textToSpeech(\n    \"Welcome to QPython!\",\n    AutoPlay=False,\n    WavFile=\"/sdcard/welcome.wav\",\n    VoiceName=\"en-US-JennyNeural\"\n).result\nprint(f\"Audio saved to: {result.get('WavFile')}\")\n
          "},{"location":"qsl4a/special/pgptai/#_6","title":"\u7c7b\u4f7f\u7528","text":"
          from androidhelper.pgptai import pgptai\nimport androidhelper\n\ndroid = androidhelper.Android()\nai = pgptai(droid)\n\n# \u4f7f\u7528\u8bed\u97f3\u8bc6\u522b\ntext = ai.speechToText(RecordSecond=10)\n
          "},{"location":"qsl4a/storage/clipboard/","title":"\u526a\u8d34\u677f API","text":"

          \u590d\u5236\u548c\u7c98\u8d34\u6587\u672c\u5230\u7cfb\u7edf\u526a\u8d34\u677f\u3002

          "},{"location":"qsl4a/storage/clipboard/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/clipboard/#setclipboard","title":"setClipboard()","text":"

          \u590d\u5236\u6587\u672c\u5230\u526a\u8d34\u677f\u3002

          setClipboard(text)\n

          \u53c2\u6570\uff1a - text (str): \u8981\u590d\u5236\u7684\u6587\u672c

          \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

          "},{"location":"qsl4a/storage/clipboard/#getclipboard","title":"getClipboard()","text":"

          \u4ece\u526a\u8d34\u677f\u83b7\u53d6\u6587\u672c\u3002

          getClipboard()\n

          \u8fd4\u56de\uff1a \u526a\u8d34\u677f\u6587\u672c

          "},{"location":"qsl4a/storage/clipboard/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u590d\u5236\u5230\u526a\u8d34\u677f\ndroid.setClipboard(\"Hello from QPython!\")\n\n# \u4ece\u526a\u8d34\u677f\u7c98\u8d34\ntext = droid.getClipboard().result\nprint(f\"Clipboard: {text}\")\n
          "},{"location":"qsl4a/storage/documentfile/","title":"DocumentFile API","text":"

          \u4f7f\u7528 SAF\uff08\u5b58\u50a8\u8bbf\u95ee\u6846\u67b6\uff09\u8fdb\u884c\u6587\u4ef6\u64cd\u4f5c\uff0c\u652f\u6301 Android 4.4+\u3002

          "},{"location":"qsl4a/storage/documentfile/#_1","title":"\u76ee\u5f55\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilemkdir","title":"documentFileMkdir()","text":"

          \u521b\u5efa\u76ee\u5f55\u3002

          documentFileMkdir(Dir)\n

          \u53c2\u6570\uff1a - Dir (str): \u76ee\u5f55\u8def\u5f84

          \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

          "},{"location":"qsl4a/storage/documentfile/#documentfilelistfiles","title":"documentFileListFiles()","text":"

          \u5217\u51fa\u76ee\u5f55\u4e2d\u7684\u6587\u4ef6\u3002

          documentFileListFiles(Folder)\n

          \u8fd4\u56de\uff1a \u6587\u4ef6\u5217\u8868

          "},{"location":"qsl4a/storage/documentfile/#_2","title":"\u6587\u4ef6\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileexists","title":"documentFileExists()","text":"

          \u68c0\u67e5\u6587\u4ef6\u6216\u76ee\u5f55\u662f\u5426\u5b58\u5728\u3002

          documentFileExists(path)\n

          \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u6216\u76ee\u5f55\u8def\u5f84

          \u8fd4\u56de\uff1a \u5982\u679c\u5b58\u5728\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

          "},{"location":"qsl4a/storage/documentfile/#documentfileisfile","title":"documentFileIsFile()","text":"

          \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u6587\u4ef6\u3002

          documentFileIsFile(path)\n

          \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

          \u8fd4\u56de\uff1a \u5982\u679c\u662f\u6587\u4ef6\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u6587\u4ef6\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

          "},{"location":"qsl4a/storage/documentfile/#documentfileisdirectory","title":"documentFileIsDirectory()","text":"

          \u68c0\u67e5\u8def\u5f84\u662f\u5426\u662f\u76ee\u5f55\u3002

          documentFileIsDirectory(path)\n

          \u53c2\u6570\uff1a - path (str): \u8981\u68c0\u67e5\u7684\u8def\u5f84

          \u8fd4\u56de\uff1a \u5982\u679c\u662f\u76ee\u5f55\u5219\u4e3a True\uff0c\u5982\u679c\u4e0d\u662f\u76ee\u5f55\u5219\u4e3a False\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

          "},{"location":"qsl4a/storage/documentfile/#documentfiledelete","title":"documentFileDelete()","text":"

          \u5220\u9664\u6587\u4ef6\u6216\u76ee\u5f55\u3002

          documentFileDelete(FileOrTree)\n

          \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

          "},{"location":"qsl4a/storage/documentfile/#documentfilerenameto","title":"documentFileRenameTo()","text":"

          \u91cd\u547d\u540d\u6216\u79fb\u52a8\u6587\u4ef6\u3002

          documentFileRenameTo(Src, Dest)\n

          \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True

          "},{"location":"qsl4a/storage/documentfile/#documentfilecopy","title":"documentFileCopy()","text":"

          \u590d\u5236\u6587\u4ef6\u3002

          documentFileCopy(SrcFileOrTree, DestFileOrTree)\n
          "},{"location":"qsl4a/storage/documentfile/#_3","title":"\u6d41\u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfileinputstream","title":"documentFileInputStream()","text":"

          \u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9\u3002

          documentFileInputStream(srcFile, EncodingFormat=\"\", skip=None, length=None)\n

          \u53c2\u6570\uff1a - srcFile (str): \u6e90\u6587\u4ef6 - EncodingFormat (str): \"UTF-8\"\u3001\"GBK\"\u3001\"Base64\" \u6216\u7a7a\u5b57\u7b26\u4e32\u8868\u793a\u5b57\u8282 - skip (int): \u4ece\u5f00\u5934\u8df3\u8fc7\u7684\u5b57\u8282\u6570 - length (int): \u8bfb\u53d6\u957f\u5ea6

          \u8fd4\u56de\uff1a \u6587\u4ef6\u5185\u5bb9

          "},{"location":"qsl4a/storage/documentfile/#documentfileoutputstream","title":"documentFileOutputStream()","text":"

          \u5199\u5165\u6587\u4ef6\u5185\u5bb9\u3002

          documentFileOutputStream(destFile, src, EncodingFormat=\"\", append=None)\n

          \u53c2\u6570\uff1a - destFile (str): \u76ee\u6807\u6587\u4ef6 - src: \u8981\u5199\u5165\u7684\u6570\u636e - EncodingFormat (str): \u7f16\u7801\u683c\u5f0f - append (bool): \u8ffd\u52a0\u6a21\u5f0f

          "},{"location":"qsl4a/storage/documentfile/#_4","title":"\u6587\u4ef6\u4fe1\u606f","text":""},{"location":"qsl4a/storage/documentfile/#documentfilelength","title":"documentFileLength()","text":"

          \u83b7\u53d6\u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\u3002

          documentFileLength(path)\n

          \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

          \u8fd4\u56de\uff1a \u6587\u4ef6\u5927\u5c0f\uff08\u5b57\u8282\uff09\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

          "},{"location":"qsl4a/storage/documentfile/#documentfilelastmodified","title":"documentFileLastModified()","text":"

          \u83b7\u53d6\u6700\u540e\u4fee\u6539\u65f6\u95f4\u3002

          documentFileLastModified(path)\n

          \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

          \u8fd4\u56de\uff1a \u65f6\u95f4\u6233\uff08\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a 0\uff09

          "},{"location":"qsl4a/storage/documentfile/#documentfilegetstat","title":"documentFileGetStat()","text":"

          \u83b7\u53d6\u5168\u9762\u7684\u6587\u4ef6\u7edf\u8ba1\u4fe1\u606f\u3002

          documentFileGetStat(path)\n

          \u53c2\u6570\uff1a - path (str): \u6587\u4ef6\u8def\u5f84

          \u8fd4\u56de\uff1a \u5305\u542b\u957f\u5ea6\u3001\u6700\u540e\u4fee\u6539\u65f6\u95f4\u548c\u8bfb/\u5199\u6743\u9650\u7684\u5b57\u5178\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u5219\u4e3a None

          "},{"location":"qsl4a/storage/documentfile/#uri","title":"URI \u64cd\u4f5c","text":""},{"location":"qsl4a/storage/documentfile/#documentfilegeturi","title":"documentFileGetUri()","text":"

          \u4ece\u8def\u5f84\u83b7\u53d6 URI\u3002

          documentFileGetUri(path, isDirectory=None)\n
          "},{"location":"qsl4a/storage/documentfile/#documentfileshowopen","title":"documentFileShowOpen()","text":"

          \u663e\u793a\u6587\u4ef6\u9009\u62e9\u5668\u3002

          documentFileShowOpen()\n

          \u8fd4\u56de\uff1a \u9009\u62e9\u7684\u6587\u4ef6 URI

          "},{"location":"qsl4a/storage/documentfile/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u76ee\u5f55\ndroid.documentFileMkdir(\"/sdcard/MyFolder\")\n\n# \u5217\u51fa\u6587\u4ef6\nfiles = droid.documentFileListFiles(\"/sdcard\").result\nfor f in files:\n    print(f)\n\n# \u8bfb\u53d6\u6587\u4ef6\ncontent = droid.documentFileInputStream(\n    \"/sdcard/test.txt\",\n    EncodingFormat=\"UTF-8\"\n).result\nprint(content)\n\n# \u5199\u5165\u6587\u4ef6\ndroid.documentFileOutputStream(\n    \"/sdcard/output.txt\",\n    \"Hello World\",\n    EncodingFormat=\"UTF-8\"\n)\n
          "},{"location":"qsl4a/storage/preferences/","title":"\u504f\u597d\u8bbe\u7f6e API","text":"

          \u4f7f\u7528 Android SharedPreferences \u5b58\u50a8\u548c\u68c0\u7d22\u6570\u636e\u3002

          "},{"location":"qsl4a/storage/preferences/#_1","title":"\u504f\u597d\u8bbe\u7f6e\u65b9\u6cd5","text":""},{"location":"qsl4a/storage/preferences/#prefgetvalue","title":"prefGetValue()","text":"

          \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u8bfb\u53d6\u503c\u3002

          prefGetValue(key, filename=None)\n

          \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

          \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c\uff08\u4efb\u610f\u7c7b\u578b\uff09

          "},{"location":"qsl4a/storage/preferences/#prefputvalue","title":"prefPutValue()","text":"

          \u5199\u5165\u503c\u5230\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u3002

          prefPutValue(key, value, filename=None)\n

          \u53c2\u6570\uff1a - key (str): \u504f\u597d\u8bbe\u7f6e\u952e - value (object): \u8981\u5b58\u50a8\u7684\u503c - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

          "},{"location":"qsl4a/storage/preferences/#prefgetall","title":"prefGetAll()","text":"

          \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\u503c\u3002

          prefGetAll(filename=None)\n

          \u53c2\u6570\uff1a - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

          \u8fd4\u56de\uff1a \u6240\u6709\u504f\u597d\u7684\u6620\u5c04

          "},{"location":"qsl4a/storage/preferences/#prefremovevalue","title":"prefRemoveValue()","text":"

          \u4ece\u5171\u4eab\u504f\u597d\u8bbe\u7f6e\u4e2d\u79fb\u9664\u503c\u3002

          prefRemoveValue(key, filename=None)\n

          \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u504f\u597d\u8bbe\u7f6e\u952e - filename (str, optional): \u504f\u597d\u8bbe\u7f6e\u6587\u4ef6\u540d

          "},{"location":"qsl4a/storage/preferences/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b58\u50a8\u503c\ndroid.prefPutValue(\"username\", \"alice\")\ndroid.prefPutValue(\"score\", 100)\ndroid.prefPutValue(\"enabled\", True)\n\n# \u8bfb\u53d6\u7279\u5b9a\u503c\nusername = droid.prefGetValue(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u83b7\u53d6\u6240\u6709\u504f\u597d\u8bbe\u7f6e\nall_prefs = droid.prefGetAll().result\nprint(f\"All prefs: {all_prefs}\")\n\n# \u79fb\u9664\u503c\ndroid.prefRemoveValue(\"score\")\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u6587\u4ef6\u540d\ndroid.prefPutValue(\"token\", \"abc123\", filename=\"auth.prefs\")\ntoken = droid.prefGetValue(\"token\", filename=\"auth.prefs\").result\n
          "},{"location":"qsl4a/system/activityresult/","title":"Activity Result API","text":"

          \u4e3a\u901a\u8fc7 startActivityForResult \u542f\u52a8\u7684\u811a\u672c\u8bbe\u7f6e activity \u7ed3\u679c\u3002

          "},{"location":"qsl4a/system/activityresult/#_1","title":"\u7ed3\u679c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/activityresult/#setresultboolean","title":"setResultBoolean()","text":"

          \u8bbe\u7f6e\u5e03\u5c14\u7ed3\u679c\u3002

          setResultBoolean(resultCode, resultValue)\n

          \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (bool): \u5e03\u5c14\u7ed3\u679c\u503c

          "},{"location":"qsl4a/system/activityresult/#setresultbyte","title":"setResultByte()","text":"

          \u8bbe\u7f6e\u5b57\u8282\u7ed3\u679c\u3002

          setResultByte(resultCode, resultValue)\n

          \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u5b57\u8282\u7ed3\u679c\u503c

          "},{"location":"qsl4a/system/activityresult/#setresultshort","title":"setResultShort()","text":"

          \u8bbe\u7f6e\u77ed\u6574\u6570\u7ed3\u679c\u3002

          setResultShort(resultCode, resultValue)\n

          \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u77ed\u6574\u6570\u7ed3\u679c\u503c

          "},{"location":"qsl4a/system/activityresult/#setresultchar","title":"setResultChar()","text":"

          \u8bbe\u7f6e\u5b57\u7b26\u7ed3\u679c\u3002

          setResultChar(resultCode, resultValue)\n

          \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u7ed3\u679c\u503c

          "},{"location":"qsl4a/system/activityresult/#setresultinteger","title":"setResultInteger()","text":"

          \u8bbe\u7f6e\u6574\u6570\u7ed3\u679c\u3002

          setResultInteger(resultCode, resultValue)\n

          \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u6574\u6570\u7ed3\u679c\u503c

          "},{"location":"qsl4a/system/activityresult/#setresultlong","title":"setResultLong()","text":"

          \u8bbe\u7f6e\u957f\u6574\u6570\u7ed3\u679c\u3002

          setResultLong(resultCode, resultValue)\n

          \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (int): \u957f\u6574\u6570\u7ed3\u679c\u503c

          "},{"location":"qsl4a/system/activityresult/#setresultfloat","title":"setResultFloat()","text":"

          \u8bbe\u7f6e\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

          setResultFloat(resultCode, resultValue)\n

          \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u6d6e\u70b9\u6570\u7ed3\u679c\u503c

          "},{"location":"qsl4a/system/activityresult/#setresultdouble","title":"setResultDouble()","text":"

          \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u3002

          setResultDouble(resultCode, resultValue)\n

          \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (float): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u7ed3\u679c\u503c

          "},{"location":"qsl4a/system/activityresult/#setresultstring","title":"setResultString()","text":"

          \u8bbe\u7f6e\u5b57\u7b26\u4e32\u7ed3\u679c\u3002

          setResultString(resultCode, resultValue)\n

          \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (str): \u5b57\u7b26\u4e32\u7ed3\u679c\u503c

          "},{"location":"qsl4a/system/activityresult/#setresultbooleanarray","title":"setResultBooleanArray()","text":"

          \u8bbe\u7f6e\u5e03\u5c14\u6570\u7ec4\u7ed3\u679c\u3002

          setResultBooleanArray(resultCode, resultValue)\n

          \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5e03\u5c14\u6570\u7ec4

          "},{"location":"qsl4a/system/activityresult/#setresultbytearray","title":"setResultByteArray()","text":"

          \u8bbe\u7f6e\u5b57\u8282\u6570\u7ec4\u7ed3\u679c\u3002

          setResultByteArray(resultCode, resultValue)\n

          \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u8282\u6570\u7ec4

          "},{"location":"qsl4a/system/activityresult/#setresultshortarray","title":"setResultShortArray()","text":"

          \u8bbe\u7f6e\u77ed\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

          setResultShortArray(resultCode, resultValue)\n

          \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u77ed\u6574\u6570\u6570\u7ec4

          "},{"location":"qsl4a/system/activityresult/#setresultchararray","title":"setResultCharArray()","text":"

          \u8bbe\u7f6e\u5b57\u7b26\u6570\u7ec4\u7ed3\u679c\u3002

          setResultCharArray(resultCode, resultValue)\n

          \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u6570\u7ec4

          "},{"location":"qsl4a/system/activityresult/#setresultintegerarray","title":"setResultIntegerArray()","text":"

          \u8bbe\u7f6e\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

          setResultIntegerArray(resultCode, resultValue)\n

          \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6574\u6570\u6570\u7ec4

          "},{"location":"qsl4a/system/activityresult/#setresultlongarray","title":"setResultLongArray()","text":"

          \u8bbe\u7f6e\u957f\u6574\u6570\u6570\u7ec4\u7ed3\u679c\u3002

          setResultLongArray(resultCode, resultValue)\n

          \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u957f\u6574\u6570\u6570\u7ec4

          "},{"location":"qsl4a/system/activityresult/#setresultfloatarray","title":"setResultFloatArray()","text":"

          \u8bbe\u7f6e\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

          setResultFloatArray(resultCode, resultValue)\n

          \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u6d6e\u70b9\u6570\u6570\u7ec4

          "},{"location":"qsl4a/system/activityresult/#setresultdoublearray","title":"setResultDoubleArray()","text":"

          \u8bbe\u7f6e\u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4\u7ed3\u679c\u3002

          setResultDoubleArray(resultCode, resultValue)\n

          \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u53cc\u7cbe\u5ea6\u6d6e\u70b9\u6570\u6570\u7ec4

          "},{"location":"qsl4a/system/activityresult/#setresultstringarray","title":"setResultStringArray()","text":"

          \u8bbe\u7f6e\u5b57\u7b26\u4e32\u6570\u7ec4\u7ed3\u679c\u3002

          setResultStringArray(resultCode, resultValue)\n

          \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue (list): \u5b57\u7b26\u4e32\u6570\u7ec4

          "},{"location":"qsl4a/system/activityresult/#setresultserializable","title":"setResultSerializable()","text":"

          \u8bbe\u7f6e\u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u3002

          setResultSerializable(resultCode, resultValue)\n

          \u53c2\u6570\uff1a - resultCode (int): \u7ed3\u679c\u4ee3\u7801 - resultValue: \u53ef\u5e8f\u5217\u5316\u7ed3\u679c\u503c

          "},{"location":"qsl4a/system/activityresult/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c activity \u540e\uff0c\u8bbe\u7f6e\u7ed3\u679c\n# \u793a\u4f8b\uff1a\u8fd4\u56de\u6210\u529f\u53ca\u6570\u636e\ndroid.setResultInteger(0, 200)  # RESULT_OK\ndroid.setResultString(0, \"Operation completed successfully\")\n\n# \u8fd4\u56de\u6570\u7ec4\u7ed3\u679c\ndroid.setResultIntegerArray(0, [1, 2, 3, 4, 5])\n
          "},{"location":"qsl4a/system/application/","title":"\u5e94\u7528\u7ba1\u7406","text":"

          \u7ba1\u7406\u5e94\u7528\u7a0b\u5e8f\u3001\u542f\u52a8\u5e94\u7528\u548c\u67e5\u8be2\u7cfb\u7edf\u4fe1\u606f\u3002

          "},{"location":"qsl4a/system/application/#_2","title":"\u5e94\u7528\u7a0b\u5e8f\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getapplicationinfo","title":"getApplicationInfo()","text":"

          \u83b7\u53d6\u5e94\u7528\u4fe1\u606f\u3002

          getApplicationInfo(packageName=None)\n

          \u53c2\u6570\uff1a - packageName (str): \u5305\u540d\uff08None = \u5f53\u524d\u5e94\u7528\uff09

          \u8fd4\u56de\uff1a \u5e94\u7528\u4fe1\u606f\u5b57\u5178

          "},{"location":"qsl4a/system/application/#getinstalledpackages","title":"getInstalledPackages()","text":"

          \u83b7\u53d6\u5df2\u5b89\u88c5\u5305\u5217\u8868\u3002

          getInstalledPackages(flag=4)\n

          \u53c2\u6570\uff1a - flag (int): \u5305\u6807\u5fd7\u8fc7\u6ee4\u5668\uff08\u9ed8\u8ba4\uff1a4\uff09

          \u8fd4\u56de\uff1a \u5df2\u5b89\u88c5\u5305\u5217\u8868

          "},{"location":"qsl4a/system/application/#getrunningpackages","title":"getRunningPackages()","text":"

          \u5217\u51fa\u6b63\u5728\u8fd0\u884c\u7684\u5305\u3002

          getRunningPackages()\n

          \u8fd4\u56de\uff1a \u5305\u540d\u5217\u8868

          "},{"location":"qsl4a/system/application/#getlaunchablepackages","title":"getLaunchablePackages()","text":"

          \u83b7\u53d6\u53ef\u542f\u52a8\u5305\u5217\u8868\u3002

          getLaunchablePackages(needClassName=False)\n

          \u53c2\u6570\uff1a - needClassName (bool): \u5305\u542b\u4e3b activity \u7c7b\u540d\uff08\u9ed8\u8ba4\uff1aFalse\uff09

          \u8fd4\u56de\uff1a \u53ef\u542f\u52a8\u5305\u540d\u5217\u8868\u6216\u5305\u542b\u7c7b\u540d\u7684\u5b57\u5178

          "},{"location":"qsl4a/system/application/#_3","title":"\u5e94\u7528\u63a7\u5236","text":""},{"location":"qsl4a/system/application/#launch","title":"launch()","text":"

          \u542f\u52a8\u5e94\u7528\u7a0b\u5e8f\u3002

          launch(classname=None, packagename=None, wait=True)\n

          \u53c2\u6570\uff1a - classname (str): \u4e3b activity \u7c7b\u540d - packagename (str): \u5305\u540d - wait (bool): \u7b49\u5f85\u542f\u52a8\u5b8c\u6210\uff08\u9ed8\u8ba4\uff1aTrue\uff09

          \u8fd4\u56de\uff1a \u542f\u52a8\u7ed3\u679c

          "},{"location":"qsl4a/system/application/#forcestoppackage","title":"forceStopPackage()","text":"

          \u5f3a\u5236\u505c\u6b62\u5e94\u7528\u7a0b\u5e8f\u3002

          forceStopPackage(packageName)\n

          \u53c2\u6570\uff1a - packageName (str): \u8981\u505c\u6b62\u7684\u5305\u540d

          "},{"location":"qsl4a/system/application/#_4","title":"\u7248\u672c\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getpackageversion","title":"getPackageVersion()","text":"

          \u83b7\u53d6\u5e94\u7528\u7248\u672c\u540d\u79f0\u3002

          getPackageVersion(packageName)\n

          \u8fd4\u56de\uff1a \u7248\u672c\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"3.2.1\"\uff09

          "},{"location":"qsl4a/system/application/#getpackageversioncode","title":"getPackageVersionCode()","text":"

          \u83b7\u53d6\u5e94\u7528\u7248\u672c\u4ee3\u7801\u3002

          getPackageVersionCode(packageName)\n

          \u8fd4\u56de\uff1a \u7248\u672c\u4ee3\u7801\u6574\u6570

          "},{"location":"qsl4a/system/application/#getconstants","title":"getConstants()","text":"

          \u83b7\u53d6\u7c7b\u5e38\u91cf\u3002

          getConstants(classname)\n

          \u53c2\u6570\uff1a - classname (str): \u5b8c\u6574\u7c7b\u540d

          \u8fd4\u56de\uff1a \u5e38\u91cf\u540d\u548c\u503c\u7684\u5b57\u5178

          "},{"location":"qsl4a/system/application/#_5","title":"\u7cfb\u7edf\u529f\u80fd","text":""},{"location":"qsl4a/system/application/#backgroundprotect","title":"backgroundProtect()","text":"

          \u542f\u7528\u6216\u7981\u7528\u5e94\u7528\u7684\u540e\u53f0\u4fdd\u62a4\u3002

          backgroundProtect(enabled=True)\n

          \u53c2\u6570\uff1a - enabled (bool): True \u542f\u7528\u4fdd\u62a4\uff0cFalse \u7981\u7528

          "},{"location":"qsl4a/system/application/#createscriptshortcut","title":"createScriptShortCut()","text":"

          \u4e3a\u811a\u672c\u521b\u5efa\u4e3b\u5c4f\u5e55\u5feb\u6377\u65b9\u5f0f\u3002

          createScriptShortCut(scriptPath, label=None, iconPath=None, scriptArg=None)\n

          \u53c2\u6570\uff1a - scriptPath (str): Python \u811a\u672c\u8def\u5f84 - label (str, optional): \u5feb\u6377\u65b9\u5f0f\u6807\u7b7e - iconPath (str, optional): \u56fe\u6807\u56fe\u50cf\u8def\u5f84 - scriptArg (str, optional): \u4f20\u9012\u7ed9\u811a\u672c\u7684\u53c2\u6570

          "},{"location":"qsl4a/system/application/#_6","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/application/#getandroidid","title":"getAndroidID()","text":"

          \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

          getAndroidID()\n

          \u8fd4\u56de\uff1a \u552f\u4e00\u7684 Android \u8bbe\u5907 ID \u5b57\u7b26\u4e32

          "},{"location":"qsl4a/system/application/#getsysinfo","title":"getSysInfo()","text":"

          \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\u3002

          getSysInfo()\n

          \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

          "},{"location":"qsl4a/system/application/#getlocale","title":"getLocale()","text":"

          \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u3002

          getLocale()\n

          \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

          "},{"location":"qsl4a/system/application/#getharmonyosinformation","title":"getHarmonyOsInformation()","text":"

          \u5982\u679c\u5728 HarmonyOS \u4e0a\u8fd0\u884c\uff0c\u83b7\u53d6 HarmonyOS \u4fe1\u606f\u3002

          getHarmonyOsInformation()\n

          \u8fd4\u56de\uff1a HarmonyOS \u7248\u672c\u4fe1\u606f\u6216 None

          "},{"location":"qsl4a/system/application/#isexternalstoragemanager","title":"isExternalStorageManager()","text":"

          \u68c0\u67e5\u5e94\u7528\u662f\u5426\u6709\u5916\u90e8\u5b58\u50a8\u7ba1\u7406\u5668\u6743\u9650\u3002

          isExternalStorageManager()\n

          \u8fd4\u56de\uff1a \u5982\u679c\u6709\u6743\u9650\u5219\u4e3a True

          "},{"location":"qsl4a/system/application/#_7","title":"\u5185\u5b58\u548c\u663e\u793a","text":""},{"location":"qsl4a/system/application/#getmemoryinfo","title":"getMemoryInfo()","text":"

          \u83b7\u53d6\u5185\u5b58\u4fe1\u606f\u3002

          getMemoryInfo()\n

          \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

          "},{"location":"qsl4a/system/application/#getscreeninfo","title":"getScreenInfo()","text":"

          \u83b7\u53d6\u5c4f\u5e55\u4fe1\u606f\u3002

          getScreenInfo()\n

          \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

          "},{"location":"qsl4a/system/application/#_8","title":"\u6743\u9650","text":""},{"location":"qsl4a/system/application/#checkpermissions","title":"checkPermissions()","text":"

          \u68c0\u67e5\u5f53\u524d\u5e94\u7528\u6743\u9650\u3002

          checkPermissions()\n

          \u8fd4\u56de\uff1a \u6743\u9650\u53ca\u5176\u72b6\u6001\u7684\u5b57\u5178

          "},{"location":"qsl4a/system/application/#requestpermissions","title":"requestPermissions()","text":"

          \u5411\u7528\u6237\u8bf7\u6c42\u6743\u9650\u3002

          requestPermissions(permissions=None)\n

          \u53c2\u6570\uff1a - permissions (list, optional): \u8981\u8bf7\u6c42\u7684\u6743\u9650\u5217\u8868\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u8bf7\u6c42\u6240\u6709\u9700\u8981\u7684\u6743\u9650\u3002

          \u8fd4\u56de\uff1a \u6743\u9650\u8bf7\u6c42\u7ed3\u679c

          "},{"location":"qsl4a/system/application/#_9","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/system/application/#showscreenlock","title":"showScreenLock()","text":"

          \u663e\u793a\u5c4f\u5e55\u9501\u5b9a\uff08PIN/\u56fe\u6848/\u5bc6\u7801\u8f93\u5165\uff09\u3002

          showScreenLock()\n
          "},{"location":"qsl4a/system/application/#_10","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\ninfo = droid.getSysInfo().result\nprint(f\"System: {info}\")\n\n# \u83b7\u53d6\u5e94\u7528\u7248\u672c\nversion = droid.getPackageVersion(\"org.qpython.qpy\").result\nprint(f\"QPython version: {version}\")\n\n# \u5217\u51fa\u5df2\u5b89\u88c5\u5e94\u7528\napps = droid.getInstalledPackages().result\nprint(f\"Installed apps: {len(apps)}\")\n\n# \u542f\u52a8\u5e94\u7528\ndroid.launch(packagename=\"com.android.settings\")\n\n# \u68c0\u67e5\u6743\u9650\nperms = droid.checkPermissions().result\nprint(f\"Permissions: {perms}\")\n\n# \u8bf7\u6c42\u5b58\u50a8\u6743\u9650\ndroid.requestPermissions([\"android.permission.READ_EXTERNAL_STORAGE\"])\n\n# \u521b\u5efa\u5feb\u6377\u65b9\u5f0f\ndroid.createScriptShortCut(\n    \"/sdcard/my_script.py\",\n    label=\"My Script\",\n    iconPath=\"/sdcard/icon.png\"\n)\n
          "},{"location":"qsl4a/system/battery/","title":"\u7535\u6c60 API","text":"

          \u76d1\u63a7\u8bbe\u5907\u7535\u6c60\u72b6\u6001\u548c\u5065\u5eb7\u72b6\u51b5\u3002

          "},{"location":"qsl4a/system/battery/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/battery/#readbatterydata","title":"readBatteryData()","text":"

          \u83b7\u53d6\u5b8c\u6574\u7684\u7535\u6c60\u4fe1\u606f\u3002

          readBatteryData()\n

          \u8fd4\u56de\uff1a \u5305\u542b\u7535\u6c60\u6570\u636e\u7684\u5b57\u5178

          "},{"location":"qsl4a/system/battery/#batterystartmonitoring","title":"batteryStartMonitoring()","text":"

          \u5f00\u59cb\u7535\u6c60\u76d1\u63a7\u3002

          batteryStartMonitoring()\n
          "},{"location":"qsl4a/system/battery/#batterystopmonitoring","title":"batteryStopMonitoring()","text":"

          \u505c\u6b62\u7535\u6c60\u76d1\u63a7\u3002

          batteryStopMonitoring()\n
          "},{"location":"qsl4a/system/battery/#batterygetlevel","title":"batteryGetLevel()","text":"

          \u83b7\u53d6\u7535\u6c60\u767e\u5206\u6bd4\u3002

          batteryGetLevel()\n

          \u8fd4\u56de\uff1a \u6574\u6570\uff080-100\uff09

          "},{"location":"qsl4a/system/battery/#batterygetstatus","title":"batteryGetStatus()","text":"

          \u83b7\u53d6\u5145\u7535\u72b6\u6001\u3002

          batteryGetStatus()\n

          \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u5145\u7535\u4e2d - 3: \u653e\u7535\u4e2d - 4: \u672a\u5145\u7535 - 5: \u5df2\u5145\u6ee1

          "},{"location":"qsl4a/system/battery/#batterygetplugtype","title":"batteryGetPlugType()","text":"

          \u83b7\u53d6\u7535\u6e90\u7c7b\u578b\u3002

          batteryGetPlugType()\n

          \u8fd4\u56de\uff1a - -1: \u672a\u77e5 - 0: \u672a\u63d2\u7535 - 1: AC \u5145\u7535\u5668 - 2: USB \u7aef\u53e3

          "},{"location":"qsl4a/system/battery/#batterygethealth","title":"batteryGetHealth()","text":"

          \u83b7\u53d6\u7535\u6c60\u5065\u5eb7\u72b6\u51b5\u3002

          batteryGetHealth()\n

          \u8fd4\u56de\uff1a - 1: \u672a\u77e5 - 2: \u826f\u597d - 3: \u8fc7\u70ed - 4: \u635f\u574f - 5: \u8fc7\u538b - 6: \u672a\u6307\u5b9a\u7684\u6545\u969c

          "},{"location":"qsl4a/system/battery/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u7535\u6c60\u7535\u91cf\nlevel = droid.batteryGetLevel().result\nprint(f\"Battery: {level}%\")\n
          "},{"location":"qsl4a/system/qpyinterface/","title":"QPython \u63a5\u53e3 API","text":"

          \u4ece\u5176\u4ed6\u5e94\u7528\u6267\u884c QPython \u811a\u672c\u548c\u7ba1\u7406\u5171\u4eab\u53d8\u91cf\u3002

          "},{"location":"qsl4a/system/qpyinterface/#_1","title":"\u811a\u672c\u6267\u884c\u65b9\u6cd5","text":""},{"location":"qsl4a/system/qpyinterface/#executeqpy","title":"executeQPy()","text":"

          \u6267\u884c QPython \u811a\u672c\u3002

          executeQPy(path=\"\", arg=None)\n

          \u53c2\u6570\uff1a - path (str): \u811a\u672c\u6587\u4ef6\u8def\u5f84 - arg (str, optional): \u547d\u4ee4\u884c\u53c2\u6570

          \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

          "},{"location":"qsl4a/system/qpyinterface/#executeqpyassrv","title":"executeQPyAsSrv()","text":"

          \u4f5c\u4e3a\u670d\u52a1\u6267\u884c QPython \u811a\u672c\u3002

          executeQPyAsSrv(path=None)\n

          \u53c2\u6570\uff1a - path (str, optional): \u811a\u672c\u6587\u4ef6\u8def\u5f84

          \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

          "},{"location":"qsl4a/system/qpyinterface/#executeqpycode","title":"executeQPyCode()","text":"

          \u76f4\u63a5\u6267\u884c Python \u4ee3\u7801\u3002

          executeQPyCode(code=None)\n

          \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

          \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

          "},{"location":"qsl4a/system/qpyinterface/#executeqpycodeassrv","title":"executeQPyCodeAsSrv()","text":"

          \u4f5c\u4e3a\u670d\u52a1\u6267\u884c Python \u4ee3\u7801\u3002

          executeQPyCodeAsSrv(code=None)\n

          \u53c2\u6570\uff1a - code (str, optional): \u8981\u6267\u884c\u7684 Python \u4ee3\u7801

          \u8fd4\u56de\uff1a \u5982\u679c\u542f\u52a8\u6210\u529f\u5219\u4e3a True

          "},{"location":"qsl4a/system/qpyinterface/#_2","title":"\u5171\u4eab\u53d8\u91cf","text":"

          \u5171\u4eab\u53d8\u91cf\u5141\u8bb8 QPython \u4e0e\u5176\u4ed6\u5e94\u7528\u4e4b\u95f4\u8fdb\u884c\u901a\u4fe1\u3002

          "},{"location":"qsl4a/system/qpyinterface/#sharedvariableset","title":"sharedVariableSet()","text":"

          \u8bbe\u7f6e Java \u5171\u4eab\u53d8\u91cf\u3002

          sharedVariableSet(key, value)\n

          \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d - value (str): \u53d8\u91cf\u503c

          \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

          "},{"location":"qsl4a/system/qpyinterface/#sharedvariableget","title":"sharedVariableGet()","text":"

          \u83b7\u53d6 Java \u5171\u4eab\u53d8\u91cf\u3002

          sharedVariableGet(key)\n

          \u53c2\u6570\uff1a - key (str): \u53d8\u91cf\u540d

          \u8fd4\u56de\uff1a \u5b58\u50a8\u7684\u503c

          "},{"location":"qsl4a/system/qpyinterface/#sharedvariableremove","title":"sharedVariableRemove()","text":"

          \u79fb\u9664 Java \u5171\u4eab\u53d8\u91cf\u3002

          sharedVariableRemove(key)\n

          \u53c2\u6570\uff1a - key (str): \u8981\u79fb\u9664\u7684\u53d8\u91cf\u540d

          \u8fd4\u56de\uff1a \u88ab\u79fb\u9664\u7684\u503c

          "},{"location":"qsl4a/system/qpyinterface/#getlastlog","title":"getLastLog()","text":"

          \u83b7\u53d6 QPython \u7684\u6700\u540e\u65e5\u5fd7\u8f93\u51fa\u3002

          getLastLog()\n

          \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u65e5\u5fd7\u5185\u5bb9

          "},{"location":"qsl4a/system/qpyinterface/#_3","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u6267\u884c\u811a\u672c\ndroid.executeQPy(\"/sdcard/my_script.py\", arg=\"test\")\n\n# \u76f4\u63a5\u6267\u884c\u4ee3\u7801\ncode = \"print('Hello from QPython!')\"\ndroid.executeQPyCode(code)\n\n# \u4f7f\u7528\u5171\u4eab\u53d8\u91cf\ndroid.sharedVariableSet(\"username\", \"alice\")\nusername = droid.sharedVariableGet(\"username\").result\nprint(f\"Username: {username}\")\n\n# \u79fb\u9664\u53d8\u91cf\ndroid.sharedVariableRemove(\"username\")\n\n# \u83b7\u53d6\u6700\u8fd1\u65e5\u5fd7\nlog = droid.getLastLog().result\nprint(f\"Log: {log}\")\n
          "},{"location":"qsl4a/system/sensors/","title":"\u4f20\u611f\u5668 API","text":"

          \u8bbf\u95ee\u8bbe\u5907\u4f20\u611f\u5668\uff0c\u5305\u62ec\u52a0\u901f\u5ea6\u8ba1\u3001\u9640\u87ba\u4eea\u3001\u78c1\u529b\u8ba1\u7b49\u3002

          "},{"location":"qsl4a/system/sensors/#_1","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/system/sensors/#startsensingtimed","title":"startSensingTimed()","text":"

          \u5f00\u59cb\u4f20\u611f\u5668\u76d1\u63a7\u5e76\u8bbe\u7f6e\u65f6\u95f4\u95f4\u9694\u3002

          startSensingTimed(sensorNumber, delayTime)\n

          \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID\uff08\u901a\u5e38\u4e3a 1-3\uff09 - delayTime (int): \u8bfb\u53d6\u4e4b\u95f4\u7684\u5ef6\u8fdf\uff08\u6beb\u79d2\uff09

          "},{"location":"qsl4a/system/sensors/#startsensingthreshold","title":"startSensingThreshold()","text":"

          \u5f00\u59cb\u5e26\u9608\u503c\u89e6\u53d1\u7684\u4f20\u611f\u5668\u76d1\u63a7\u3002

          startSensingThreshold(sensorNumber, threshold, axis)\n

          \u53c2\u6570\uff1a - sensorNumber (int): \u4f20\u611f\u5668 ID - threshold (float): \u89e6\u53d1\u9608\u503c - axis (int): \u8981\u76d1\u63a7\u7684\u8f74\uff080=X\uff0c1=Y\uff0c2=Z\uff09

          "},{"location":"qsl4a/system/sensors/#stopsensing","title":"stopSensing()","text":"

          \u505c\u6b62\u6240\u6709\u4f20\u611f\u5668\u76d1\u63a7\u3002

          stopSensing()\n
          "},{"location":"qsl4a/system/sensors/#readsensors","title":"readSensors()","text":"

          \u8bfb\u53d6\u5f53\u524d\u4f20\u611f\u5668\u6570\u636e\u3002

          readSensors()\n

          \u8fd4\u56de\uff1a \u4f20\u611f\u5668\u6570\u636e\u5b57\u5178

          "},{"location":"qsl4a/system/sensors/#sensorsreadaccelerometer","title":"sensorsReadAccelerometer()","text":"

          \u8bfb\u53d6\u52a0\u901f\u5ea6\u8ba1\u503c\u3002

          sensorsReadAccelerometer()\n

          \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d m/s\u00b2

          "},{"location":"qsl4a/system/sensors/#sensorsreadgyroscope","title":"sensorsReadGyroscope()","text":"

          \u8bfb\u53d6\u9640\u87ba\u4eea\u503c\u3002

          sensorsReadGyroscope()\n

          \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d rad/s

          "},{"location":"qsl4a/system/sensors/#sensorsreadmagnetometer","title":"sensorsReadMagnetometer()","text":"

          \u8bfb\u53d6\u78c1\u573a\u503c\u3002

          sensorsReadMagnetometer()\n

          \u8fd4\u56de\uff1a \u5217\u8868 [X, Y, Z]\uff0c\u5355\u4f4d \u03bcT

          "},{"location":"qsl4a/system/sensors/#sensorsreadorientation","title":"sensorsReadOrientation()","text":"

          \u8bfb\u53d6\u8bbe\u5907\u65b9\u5411\u3002

          sensorsReadOrientation()\n

          \u8fd4\u56de\uff1a \u5217\u8868 [azimuth, pitch, roll]\uff0c\u5355\u4f4d\u5ea6

          "},{"location":"qsl4a/system/sensors/#sensorsgetlight","title":"sensorsGetLight()","text":"

          \u8bfb\u53d6\u5149\u4f20\u611f\u5668\u503c\u3002

          sensorsGetLight()\n

          \u8fd4\u56de\uff1a \u5149\u7ea7\u522b\uff08lux\uff09

          "},{"location":"qsl4a/system/sensors/#sensorsgetstepcounter","title":"sensorsGetStepCounter()","text":"

          \u8bfb\u53d6\u6b65\u8ba1\u6570\u5668\u3002

          sensorsGetStepCounter()\n

          \u8fd4\u56de\uff1a \u6b65\u6570

          "},{"location":"qsl4a/system/sensors/#sensorsgetaccuracy","title":"sensorsGetAccuracy()","text":"

          \u83b7\u53d6\u5f53\u524d\u4f20\u611f\u5668\u7cbe\u5ea6\u3002

          sensorsGetAccuracy()\n

          \u8fd4\u56de\uff1a \u7cbe\u5ea6\u503c\uff080-3\uff1aUNRELIABLE\u3001ACCURACY_LOW\u3001ACCURACY_MEDIUM\u3001ACCURACY_HIGH\uff09

          "},{"location":"qsl4a/system/sensors/#_2","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u5f00\u59cb\u611f\u77e5\ndroid.startSensingTimed(1, 250)\n\n# \u8bfb\u53d6\u4f20\u611f\u5668 10 \u6b21\nfor i in range(10):\n    accel = droid.sensorsReadAccelerometer().result\n    print(f\"Accel: X={accel[0]:.2f}, Y={accel[1]:.2f}, Z={accel[2]:.2f}\")\n    time.sleep(0.5)\n\ndroid.stopSensing()\n
          "},{"location":"qsl4a/system/settings/","title":"\u8bbe\u7f6e API","text":"

          \u63a7\u5236\u7cfb\u7edf\u8bbe\u7f6e\uff0c\u5305\u62ec\u5c4f\u5e55\u3001\u58f0\u97f3\u548c\u7f51\u7edc\u8bbe\u7f6e\u3002

          "},{"location":"qsl4a/system/settings/#_1","title":"\u5c4f\u5e55\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#setscreentimeout","title":"setScreenTimeout()","text":"

          \u8bbe\u7f6e\u5c4f\u5e55\u8d85\u65f6\u503c\u3002

          setScreenTimeout(value)\n

          \u53c2\u6570\uff1a - value (int): \u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

          \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u8d85\u65f6\u503c

          "},{"location":"qsl4a/system/settings/#getscreentimeout","title":"getScreenTimeout()","text":"

          \u83b7\u53d6\u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u3002

          getScreenTimeout()\n

          \u8fd4\u56de\uff1a \u5f53\u524d\u5c4f\u5e55\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09

          "},{"location":"qsl4a/system/settings/#getscreenbrightness","title":"getScreenBrightness()","text":"

          \u83b7\u53d6\u5c4f\u5e55\u4eae\u5ea6\u503c\u3002

          getScreenBrightness()\n

          \u8fd4\u56de\uff1a \u4eae\u5ea6\u503c\uff080-255\uff09

          "},{"location":"qsl4a/system/settings/#setscreenbrightness","title":"setScreenBrightness()","text":"

          \u8bbe\u7f6e\u5c4f\u5e55\u4eae\u5ea6\u3002

          setScreenBrightness(value=None)\n

          \u53c2\u6570\uff1a - value (int, optional): \u4eae\u5ea6\u503c\uff080-255\uff09\uff0c\u6216 None \u8868\u793a\u81ea\u52a8

          \u8fd4\u56de\uff1a \u4e4b\u524d\u7684\u4eae\u5ea6\u503c

          "},{"location":"qsl4a/system/settings/#checkscreenon","title":"checkScreenOn()","text":"

          \u68c0\u67e5\u5c4f\u5e55\u662f\u5426\u4eae\u7740\u3002

          checkScreenOn()\n

          \u8fd4\u56de\uff1a \u5982\u679c\u5c4f\u5e55\u4eae\u7740\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

          "},{"location":"qsl4a/system/settings/#_2","title":"\u98de\u884c\u6a21\u5f0f","text":""},{"location":"qsl4a/system/settings/#checkairplanemode","title":"checkAirplaneMode()","text":"

          \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\u662f\u5426\u542f\u7528\u3002

          checkAirplaneMode()\n

          \u8fd4\u56de\uff1a \u5982\u679c\u98de\u884c\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

          "},{"location":"qsl4a/system/settings/#_3","title":"\u94c3\u58f0\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#checkringersilentmode","title":"checkRingerSilentMode()","text":"

          \u68c0\u67e5\u94c3\u58f0\u662f\u5426\u5904\u4e8e\u9759\u97f3\u6a21\u5f0f\u3002

          checkRingerSilentMode()\n

          \u8fd4\u56de\uff1a \u5982\u679c\u9759\u97f3\u6a21\u5f0f\u5f00\u7740\u5219\u4e3a True

          "},{"location":"qsl4a/system/settings/#toggleringersilentmode","title":"toggleRingerSilentMode()","text":"

          \u5207\u6362\u94c3\u58f0\u9759\u97f3\u6a21\u5f0f\u3002

          toggleRingerSilentMode(enabled=None)\n

          \u53c2\u6570\uff1a - enabled (bool, optional): True \u542f\u7528\uff0cFalse \u7981\u7528\uff0cNone \u5207\u6362

          \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

          "},{"location":"qsl4a/system/settings/#togglevibratemode","title":"toggleVibrateMode()","text":"

          \u5207\u6362\u632f\u52a8\u6a21\u5f0f\u3002

          toggleVibrateMode(enabled=None, ringer=None)\n

          \u53c2\u6570\uff1a - enabled (bool, optional): \u5207\u6362\u632f\u52a8\u5f00/\u5173 - ringer (bool, optional): \u5e94\u7528\u4e8e\u94c3\u58f0\u6a21\u5f0f

          \u8fd4\u56de\uff1a \u65b0\u72b6\u6001

          "},{"location":"qsl4a/system/settings/#getvibratemode","title":"getVibrateMode()","text":"

          \u83b7\u53d6\u632f\u52a8\u6a21\u5f0f\u8bbe\u7f6e\u3002

          getVibrateMode(ringer=None)\n

          \u53c2\u6570\uff1a - ringer (bool, optional): \u68c0\u67e5\u94c3\u58f0\u632f\u52a8\u6a21\u5f0f

          \u8fd4\u56de\uff1a \u5982\u679c\u632f\u52a8\u5df2\u542f\u7528\u5219\u4e3a True

          "},{"location":"qsl4a/system/settings/#_4","title":"\u97f3\u91cf\u8bbe\u7f6e","text":""},{"location":"qsl4a/system/settings/#getringervolume","title":"getRingerVolume()","text":"

          \u83b7\u53d6\u5f53\u524d\u94c3\u58f0\u97f3\u91cf\u3002

          getRingerVolume()\n

          \u8fd4\u56de\uff1a \u94c3\u58f0\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-7\uff09

          "},{"location":"qsl4a/system/settings/#getmaxringervolume","title":"getMaxRingerVolume()","text":"

          \u83b7\u53d6\u6700\u5927\u94c3\u58f0\u97f3\u91cf\u3002

          getMaxRingerVolume()\n

          \u8fd4\u56de\uff1a \u6700\u5927\u94c3\u58f0\u97f3\u91cf

          "},{"location":"qsl4a/system/settings/#setringervolume","title":"setRingerVolume()","text":"

          \u8bbe\u7f6e\u94c3\u58f0\u97f3\u91cf\u3002

          setRingerVolume(volume)\n

          \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

          "},{"location":"qsl4a/system/settings/#getmediavolume","title":"getMediaVolume()","text":"

          \u83b7\u53d6\u5f53\u524d\u5a92\u4f53\u97f3\u91cf\u3002

          getMediaVolume()\n

          \u8fd4\u56de\uff1a \u5a92\u4f53\u97f3\u91cf\u7ea7\u522b\uff08\u901a\u5e38\u4e3a 0-15\uff09

          "},{"location":"qsl4a/system/settings/#getmaxmediavolume","title":"getMaxMediaVolume()","text":"

          \u83b7\u53d6\u6700\u5927\u5a92\u4f53\u97f3\u91cf\u3002

          getMaxMediaVolume()\n

          \u8fd4\u56de\uff1a \u6700\u5927\u5a92\u4f53\u97f3\u91cf

          "},{"location":"qsl4a/system/settings/#setmediavolume","title":"setMediaVolume()","text":"

          \u8bbe\u7f6e\u5a92\u4f53\u97f3\u91cf\u3002

          setMediaVolume(volume)\n

          \u53c2\u6570\uff1a - volume (int): \u97f3\u91cf\u7ea7\u522b

          "},{"location":"qsl4a/system/settings/#_5","title":"\u7cfb\u7edf\u4fe1\u606f","text":""},{"location":"qsl4a/system/settings/#elapsedrealtimenanos","title":"elapsedRealtimeNanos()","text":"

          \u83b7\u53d6\u81ea\u7cfb\u7edf\u542f\u52a8\u4ee5\u6765\u7684\u7eb3\u79d2\u6570\u3002

          elapsedRealtimeNanos()\n

          \u8fd4\u56de\uff1a \u7eb3\u79d2\u6570\uff08\u53ef\u7528\u4e8e\u8ba1\u65f6\uff09

          "},{"location":"qsl4a/system/settings/#gettrafficstats","title":"getTrafficStats()","text":"

          \u83b7\u53d6\u7f51\u7edc\u6d41\u91cf\u7edf\u8ba1\u3002

          getTrafficStats(flags=7)\n

          \u53c2\u6570\uff1a - flags (int): \u8981\u68c0\u7d22\u7684\u7edf\u8ba1\uff08\u9ed8\u8ba4\uff1a7 = \u5168\u90e8\uff09

          \u8fd4\u56de\uff1a \u5305\u542b\u53d1\u9001/\u63a5\u6536\u5b57\u8282\u7684\u5b57\u5178

          "},{"location":"qsl4a/system/settings/#getapptxbytes","title":"getAppTxBytes()","text":"

          \u83b7\u53d6 QPython \u5e94\u7528\u7684\u53d1\u9001\u5b57\u8282\u3002

          getAppTxBytes(packageName)\n

          \u53c2\u6570\uff1a - packageName (str): \u5305\u540d

          \u8fd4\u56de\uff1a \u5305\u542b tx/rx \u5b57\u8282\u7684\u5b57\u5178

          "},{"location":"qsl4a/system/settings/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5c4f\u5e55\u8bbe\u7f6e\ncurrent_timeout = droid.getScreenTimeout().result\nprint(f\"Current timeout: {current_timeout}s\")\ndroid.setScreenTimeout(30)\n\n# \u68c0\u67e5\u5c4f\u5e55\nif droid.checkScreenOn().result:\n    print(\"Screen is on\")\n\n# \u97f3\u91cf\u63a7\u5236\nmedia_vol = droid.getMediaVolume().result\nprint(f\"Media volume: {media_vol}\")\ndroid.setMediaVolume(10)\n\n# \u68c0\u67e5\u98de\u884c\u6a21\u5f0f\nif droid.checkAirplaneMode().result:\n    print(\"Airplane mode is on\")\n
          "},{"location":"qsl4a/system/sysinfo/","title":"\u7cfb\u7edf\u4fe1\u606f","text":"

          \u68c0\u7d22\u8bbe\u5907\u548c\u7cfb\u7edf\u4fe1\u606f\u3002

          "},{"location":"qsl4a/system/sysinfo/#_2","title":"\u8bbe\u5907\u4fe1\u606f","text":""},{"location":"qsl4a/system/sysinfo/#getandroidid","title":"getAndroidID()","text":"

          \u83b7\u53d6 Android \u8bbe\u5907 ID\u3002

          getAndroidID()\n

          \u8fd4\u56de\uff1a \u5b57\u7b26\u4e32\u8bbe\u5907 ID

          "},{"location":"qsl4a/system/sysinfo/#getsysinfo","title":"getSysInfo()","text":"

          \u83b7\u53d6\u7efc\u5408\u7cfb\u7edf\u4fe1\u606f\u3002

          getSysInfo()\n

          \u8fd4\u56de\uff1a \u5305\u542b\u7cfb\u7edf\u8be6\u60c5\u7684\u5b57\u5178

          "},{"location":"qsl4a/system/sysinfo/#getlocale","title":"getLocale()","text":"

          \u83b7\u53d6\u8bbe\u5907\u8bed\u8a00\u73af\u5883\u8bbe\u7f6e\u3002

          getLocale()\n

          \u8fd4\u56de\uff1a \u8bed\u8a00\u73af\u5883\u5b57\u7b26\u4e32\uff08\u4f8b\u5982 \"en_US\"\uff09

          "},{"location":"qsl4a/system/sysinfo/#_3","title":"\u5185\u5b58","text":""},{"location":"qsl4a/system/sysinfo/#getmemoryinfo","title":"getMemoryInfo()","text":"

          \u83b7\u53d6 RAM \u4fe1\u606f\u3002

          getMemoryInfo()\n

          \u8fd4\u56de\uff1a \u5305\u542b\u5185\u5b58\u7edf\u8ba1\u7684\u5b57\u5178

          "},{"location":"qsl4a/system/sysinfo/#_4","title":"\u663e\u793a","text":""},{"location":"qsl4a/system/sysinfo/#getscreeninfo","title":"getScreenInfo()","text":"

          \u83b7\u53d6\u663e\u793a\u4fe1\u606f\u3002

          getScreenInfo()\n

          \u8fd4\u56de\uff1a \u5305\u542b\u5bbd\u5ea6\u3001\u9ad8\u5ea6\u3001\u5bc6\u5ea6\u7684\u5b57\u5178

          "},{"location":"qsl4a/system/sysinfo/#_5","title":"\u6807\u8bc6\u7b26","text":""},{"location":"qsl4a/system/sysinfo/#getimei","title":"getImei()","text":"

          \u83b7\u53d6\u8bbe\u5907 IMEI\u3002

          getImei(slotIndex=None)\n
          "},{"location":"qsl4a/system/sysinfo/#getmeid","title":"getMeid()","text":"

          \u83b7\u53d6\u8bbe\u5907 MEID\u3002

          getMeid(slotIndex=None)\n
          "},{"location":"qsl4a/system/sysinfo/#_6","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u8bbe\u5907 ID\nandroid_id = droid.getAndroidID().result\nprint(f\"Android ID: {android_id}\")\n\n# \u5c4f\u5e55\u4fe1\u606f\nscreen = droid.getScreenInfo().result\nprint(f\"Screen: {screen['width']}x{screen['height']}\")\n\n# \u5185\u5b58\nmemory = droid.getMemoryInfo().result\nprint(f\"Memory: {memory}\")\n
          "},{"location":"qsl4a/system/wakelock/","title":"WakeLock API","text":"

          \u63a7\u5236\u8bbe\u5907\u5524\u9192\u9501\u4ee5\u4fdd\u6301 CPU \u6216\u5c4f\u5e55\u5f00\u542f\u3002

          "},{"location":"qsl4a/system/wakelock/#wake-lock","title":"Wake Lock \u7c7b\u578b","text":"

          QSL4A \u63d0\u4f9b\u4e0d\u540c\u7c7b\u578b\u7684\u5524\u9192\u9501\uff1a

          \u7c7b\u578b \u63cf\u8ff0 Full CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae Partial \u4ec5 CPU \u5f00\u542f Bright CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae Dim CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697"},{"location":"qsl4a/system/wakelock/#wake-lock_1","title":"Wake Lock \u65b9\u6cd5","text":""},{"location":"qsl4a/system/wakelock/#wakelockacquirefull","title":"wakeLockAcquireFull()","text":"

          \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff0c\u952e\u76d8\u4eae\uff09\u3002

          wakeLockAcquireFull()\n
          "},{"location":"qsl4a/system/wakelock/#wakelockacquirepartial","title":"wakeLockAcquirePartial()","text":"

          \u83b7\u53d6\u90e8\u5206\u5524\u9192\u9501\uff08\u4ec5 CPU \u5f00\u542f\uff09\u3002

          wakeLockAcquirePartial()\n
          "},{"location":"qsl4a/system/wakelock/#wakelockacquirebright","title":"wakeLockAcquireBright()","text":"

          \u83b7\u53d6\u660e\u4eae\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u4eae\uff09\u3002

          wakeLockAcquireBright()\n
          "},{"location":"qsl4a/system/wakelock/#wakelockacquiredim","title":"wakeLockAcquireDim()","text":"

          \u83b7\u53d6\u6697\u6de1\u5524\u9192\u9501\uff08CPU \u5f00\u542f\uff0c\u5c4f\u5e55\u6697\uff09\u3002

          wakeLockAcquireDim()\n
          "},{"location":"qsl4a/system/wakelock/#wakelockrelease","title":"wakeLockRelease()","text":"

          \u91ca\u653e\u5524\u9192\u9501\u3002

          wakeLockRelease()\n
          "},{"location":"qsl4a/system/wakelock/#_1","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\nimport time\n\ndroid = androidhelper.Android()\n\n# \u83b7\u53d6\u5b8c\u6574\u5524\u9192\u9501\ndroid.wakeLockAcquireFull()\n\n# \u5728\u4fdd\u6301\u5c4f\u5e55\u5f00\u542f\u65f6\u6267\u884c\u91cd\u8981\u5de5\u4f5c\nprint(\"Screen will stay on\")\ntime.sleep(10)\n\n# \u5b8c\u6210\u540e\u91ca\u653e\ndroid.wakeLockRelease()\n\n# \u6216\u4f7f\u7528\u90e8\u5206\u9501\u8fdb\u884c\u540e\u53f0\u4efb\u52a1\ndroid.wakeLockAcquirePartial()\n# \u5373\u4f7f\u5c4f\u5e55\u5173\u95ed\uff0cCPU \u4ecd\u4fdd\u6301\u5f00\u542f\ntime.sleep(30)\ndroid.wakeLockRelease()\n

          \u6ce8\u610f\uff1a \u8bb0\u4f4f\u5728\u4e0d\u9700\u8981\u65f6\u91ca\u653e\u5524\u9192\u9501\u4ee5\u8282\u7701\u7535\u6c60\u3002

          "},{"location":"qsl4a/ui/accessibility/","title":"\u65e0\u969c\u788d\u670d\u52a1","text":"

          \u65e0\u969c\u788d\u670d\u52a1\u5141\u8bb8\u81ea\u52a8\u5316 UI \u4ea4\u4e92\uff0c\u5982\u70b9\u51fb\u3001\u6ed1\u52a8\u548c\u7cfb\u7edf\u64cd\u4f5c\u3002

          "},{"location":"qsl4a/ui/accessibility/#_2","title":"\u670d\u52a1\u63a7\u5236","text":""},{"location":"qsl4a/ui/accessibility/#accessibilitystartservice","title":"accessibilityStartService()","text":"

          \u542f\u52a8\u65e0\u969c\u788d\u670d\u52a1\u3002

          accessibilityStartService()\n

          \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a True\uff0c\u5426\u5219\u4e3a False

          "},{"location":"qsl4a/ui/accessibility/#accessibilityserviceenabled","title":"accessibilityServiceEnabled()","text":"

          \u68c0\u67e5\u65e0\u969c\u788d\u670d\u52a1\u662f\u5426\u5df2\u542f\u7528\u3002

          accessibilityServiceEnabled()\n

          \u8fd4\u56de\uff1a True \u6216 False

          "},{"location":"qsl4a/ui/accessibility/#_3","title":"\u5c4f\u5e55\u4ea4\u4e92","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityclick","title":"accessibilityClick()","text":"

          \u5728\u5c4f\u5e55\u5750\u6807\u5904\u70b9\u51fb\u3002

          accessibilityClick(x=0, y=0, t=50)\n

          \u53c2\u6570\uff1a - x (int/float): X \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - y (int/float): Y \u5750\u6807\uff080=\u5c45\u4e2d\uff0c\u652f\u6301\u5c0f\u6570\uff09 - t (int): \u6309\u4f4f\u65f6\u957f\uff08\u6beb\u79d2\uff09\uff08\u9ed8\u8ba4\uff1a50\uff09

          "},{"location":"qsl4a/ui/accessibility/#accessibilityslide","title":"accessibilitySlide()","text":"

          \u591a\u70b9\u6ed1\u52a8\u624b\u52bf\u3002

          accessibilitySlide(XnYn=None, t=None)\n

          \u53c2\u6570\uff1a - XnYn (list): \u5750\u6807 [X1, Y1, X2, Y2, ... Xn, Yn] - t (int): \u6ed1\u52a8\u65f6\u957f\uff08\u9ed8\u8ba4\uff1a50*n \u6beb\u79d2\uff09

          "},{"location":"qsl4a/ui/accessibility/#_4","title":"\u7cfb\u7edf\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/accessibility/#accessibilityaction","title":"accessibilityAction()","text":"

          \u6309\u4ee3\u7801\u6267\u884c\u7cfb\u7edf\u64cd\u4f5c\u3002

          accessibilityAction(actionCode)\n

          \u64cd\u4f5c\u4ee3\u7801\uff1a | \u4ee3\u7801 | \u5e38\u91cf | \u63cf\u8ff0 | |------|----------|-------------| | 1 | BACK | \u8fd4\u56de\u6309\u94ae | | 2 | HOME | \u4e3b\u5c4f\u5e55\u6309\u94ae | | 3 | RECENTS | \u6700\u8fd1\u5e94\u7528 | | 4 | NOTIFICATIONS | \u6253\u5f00\u901a\u77e5 | | 5 | QUICK_SETTINGS | \u6253\u5f00\u5feb\u901f\u8bbe\u7f6e | | 6 | POWER_DIALOG | \u7535\u6e90\u83dc\u5355 | | 7 | TOGGLE_SPLIT_SCREEN | \u5206\u5c4f | | 8 | LOCK_SCREEN | \u9501\u5c4f | | 9 | TAKE_SCREENSHOT | \u622a\u56fe | | 10 | KEYCODE_HEADSETHOOK | \u8033\u673a\u6302\u94a9 | | 11-14 | ACCESSIBILITY_ | \u65e0\u969c\u788d\u6309\u94ae | | 15 | DISMISS_NOTIFICATION_SHADE | \u5173\u95ed\u901a\u77e5\u680f | | 16-20 | DPAD_ | \u65b9\u5411\u952e | | 21 | MENU | \u83dc\u5355\u6309\u94ae | | 22 | MEDIA_PLAY_PAUSE | \u64ad\u653e/\u6682\u505c\u5a92\u4f53 |

          "},{"location":"qsl4a/ui/accessibility/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/accessibility/#_6","title":"\u70b9\u51fb\u5c4f\u5e55\u4e2d\u5fc3","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u542f\u52a8\u670d\u52a1\nif not droid.accessibilityServiceEnabled().result:\n    droid.accessibilityStartService()\n\n# \u70b9\u51fb\u4e2d\u5fc3\uff080,0 = \u4e2d\u5fc3\uff09\ndroid.accessibilityClick(0, 0, t=100)\n
          "},{"location":"qsl4a/ui/accessibility/#_7","title":"\u6ed1\u52a8\u624b\u52bf","text":"
          # \u4ece\u4e0b\u5f80\u4e0a\u6ed1\u52a8\uff08\u5411\u4e0a\u6eda\u52a8\uff09\ndroid.accessibilitySlide([0, 1.5, 0, -1.5], t=300)\n
          "},{"location":"qsl4a/ui/accessibility/#_8","title":"\u7cfb\u7edf\u5bfc\u822a","text":"
          # \u6309\u4e3b\u5c4f\u5e55\ndroid.accessibilityAction(2)\n\n# \u6309\u8fd4\u56de\ndroid.accessibilityAction(1)\n\n# \u6253\u5f00\u901a\u77e5\ndroid.accessibilityAction(4)\n
          "},{"location":"qsl4a/ui/accessibility/#_9","title":"\u70b9\u51fb\u7279\u5b9a\u4f4d\u7f6e","text":"
          # \u70b9\u51fb\u5c4f\u5e55\u5750\u6807 (500, 800)\ndroid.accessibilityClick(500, 800)\n\n# \u70b9\u51fb\u76f8\u5bf9\u4f4d\u7f6e\uff08\u6c34\u5e73\u5c45\u4e2d\uff0c\u5782\u76f4 3/4 \u5904\uff09\ndroid.accessibilityClick(0, 1.5)\n
          "},{"location":"qsl4a/ui/dialogs/","title":"\u5bf9\u8bdd\u6846\u7cfb\u7edf","text":"

          QSL4A \u63d0\u4f9b\u5168\u9762\u7684\u5bf9\u8bdd\u6846\u652f\u6301\uff0c\u7528\u4e8e\u7528\u6237\u4ea4\u4e92\uff0c\u5305\u62ec\u8b66\u62a5\u3001\u8f93\u5165\u5bf9\u8bdd\u6846\u3001\u9009\u62e9\u5bf9\u8bdd\u6846\u548c\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

          "},{"location":"qsl4a/ui/dialogs/#_2","title":"\u8b66\u62a5\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowalert","title":"dialogShowAlert()","text":"

          \u663e\u793a\u7b80\u5355\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

          dialogShowAlert(title=\"Alert\", message=\"The message of the alert.\",\n                positiveButtonText=\"OK\", negativeButtonText=None,\n                neutralButtonText=None, messageIsHtml=False)\n

          \u53c2\u6570\uff1a - title (str): \u5bf9\u8bdd\u6846\u6807\u9898 - message (str): \u6d88\u606f\u6587\u672c - positiveButtonText (str): \u80af\u5b9a\u6309\u94ae\u6807\u7b7e - negativeButtonText (str, optional): \u5426\u5b9a\u6309\u94ae\u6807\u7b7e - neutralButtonText (str, optional): \u4e2d\u6027\u6309\u94ae\u6807\u7b7e - messageIsHtml (bool): \u5c06\u6d88\u606f\u89e3\u6790\u4e3a HTML

          \u8fd4\u56de\uff1a \u5305\u542b\u70b9\u51fb\u6309\u94ae\u7684\u7ed3\u679c

          "},{"location":"qsl4a/ui/dialogs/#dialogshowsimplechoice","title":"dialogShowSimpleChoice()","text":"

          \u663e\u793a\u5e26\u6709\u9879\u76ee\u7684\u7b80\u5355\u9009\u62e9\u5bf9\u8bdd\u6846\u3002

          dialogShowSimpleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

          \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868

          \u8fd4\u56de\uff1a \u5305\u542b\u9009\u4e2d\u9879\u76ee\u7684\u7ed3\u679c

          "},{"location":"qsl4a/ui/dialogs/#_3","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialoggetinput","title":"dialogGetInput()","text":"

          \u83b7\u53d6\u7528\u6237\u6587\u672c\u8f93\u5165\u3002

          dialogGetInput(title=\"Value\", message=\"Please enter value:\",\n               defaultText=None, messageIsHtml=False)\n

          \u8fd4\u56de\uff1a \u5305\u542b\u7528\u6237\u8f93\u5165\u6587\u672c\u7684\u7ed3\u679c

          "},{"location":"qsl4a/ui/dialogs/#dialoggetpassword","title":"dialogGetPassword()","text":"

          \u83b7\u53d6\u5bc6\u7801\u8f93\u5165\u3002

          dialogGetPassword(title=\"Password\", message=\"Please enter password:\")\n

          \u8fd4\u56de\uff1a \u5305\u542b\u8f93\u5165\u5bc6\u7801\u7684\u7ed3\u679c

          "},{"location":"qsl4a/ui/dialogs/#dialogcreateinput","title":"dialogCreateInput()","text":"

          \u521b\u5efa\u81ea\u5b9a\u4e49\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

          dialogCreateInput(title=\"Value\", message=\"Please enter value:\",\n                  defaultText=None, inputType=None)\n

          \u53c2\u6570\uff1a - inputType (str): \u8f93\u5165\u7c7b\u578b\uff08\u4f8b\u5982 \"text\"\u3001\"number\"\u3001\"textPassword\"\uff09

          "},{"location":"qsl4a/ui/dialogs/#dialogcreatepassword","title":"dialogCreatePassword()","text":"

          \u521b\u5efa\u5bc6\u7801\u8f93\u5165\u5bf9\u8bdd\u6846\u3002

          dialogCreatePassword(title=\"Password\", message=\"Please enter password:\")\n
          "},{"location":"qsl4a/ui/dialogs/#dialogcreateseekbar","title":"dialogCreateSeekBar()","text":"

          \u521b\u5efa\u6ed1\u5757/\u8fdb\u5ea6\u6761\u5bf9\u8bdd\u6846\u3002

          dialogCreateSeekBar(starting_value=50, maximum_value=100, title=\"\", message=\"\")\n

          \u53c2\u6570\uff1a - starting_value (int): \u521d\u59cb\u503c - maximum_value (int): \u6700\u5927\u503c

          "},{"location":"qsl4a/ui/dialogs/#_4","title":"\u9009\u62e9\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogshowsinglechoice","title":"dialogShowSingleChoice()","text":"

          \u663e\u793a\u5355\u9009\uff08\u5355\u9009\u6309\u94ae\uff09\u5bf9\u8bdd\u6846\u3002

          dialogShowSingleChoice(title=\"Alert\", message=\"The message of the alert.\",\n                       items=None, selected=-1, positiveButtonText=\"OK\",\n                       negativeButtonText=None, neutralButtonText=None,\n                       messageIsHtml=False)\n

          \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (int): \u9ed8\u8ba4\u9009\u4e2d\u7d22\u5f15

          "},{"location":"qsl4a/ui/dialogs/#dialogshowmultichoice","title":"dialogShowMultiChoice()","text":"

          \u663e\u793a\u591a\u9009\uff08\u590d\u9009\u6846\uff09\u5bf9\u8bdd\u6846\u3002

          dialogShowMultiChoice(title=\"Alert\", message=\"The message of the alert.\",\n                      items=None, selected=None, positiveButtonText=\"OK\",\n                      negativeButtonText=None, neutralButtonText=None,\n                      messageIsHtml=False)\n

          \u53c2\u6570\uff1a - items (list): \u9009\u62e9\u5b57\u7b26\u4e32\u5217\u8868 - selected (list): \u521d\u59cb\u9009\u4e2d\u7d22\u5f15\u5217\u8868

          "},{"location":"qsl4a/ui/dialogs/#dialogsetsinglechoiceitems","title":"dialogSetSingleChoiceItems()","text":"

          \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u5355\u9009\u9879\u76ee\u3002

          dialogSetSingleChoiceItems(items, selected=-1)\n
          "},{"location":"qsl4a/ui/dialogs/#dialogsetmultichoiceitems","title":"dialogSetMultiChoiceItems()","text":"

          \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u591a\u9009\u9879\u76ee\u3002

          dialogSetMultiChoiceItems(items, selected=None)\n
          "},{"location":"qsl4a/ui/dialogs/#_5","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatespinnerprogress","title":"dialogCreateSpinnerProgress()","text":"

          \u521b\u5efa\u4e0d\u786e\u5b9a\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

          dialogCreateSpinnerProgress(title=None, message=None, maximum_progress=100)\n
          "},{"location":"qsl4a/ui/dialogs/#dialogcreatehorizontalprogress","title":"dialogCreateHorizontalProgress()","text":"

          \u521b\u5efa\u6c34\u5e73\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u3002

          dialogCreateHorizontalProgress(title=None, message=None, maximum_progress=100)\n
          "},{"location":"qsl4a/ui/dialogs/#dialogsetcurrentprogress","title":"dialogSetCurrentProgress()","text":"

          \u66f4\u65b0\u8fdb\u5ea6\u503c\u3002

          dialogSetCurrentProgress(current)\n
          "},{"location":"qsl4a/ui/dialogs/#dialogsetmaxprogress","title":"dialogSetMaxProgress()","text":"

          \u8bbe\u7f6e\u6700\u5927\u8fdb\u5ea6\u503c\u3002

          dialogSetMaxProgress(max)\n
          "},{"location":"qsl4a/ui/dialogs/#dialogsetprogressmessage","title":"dialogSetProgressMessage()","text":"

          \u66f4\u65b0\u8fdb\u5ea6\u5bf9\u8bdd\u6846\u6d88\u606f\u3002

          dialogSetProgressMessage(message)\n
          "},{"location":"qsl4a/ui/dialogs/#_6","title":"\u9009\u62e9\u5668\u5bf9\u8bdd\u6846","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatedatepicker","title":"dialogCreateDatePicker()","text":"

          \u521b\u5efa\u65e5\u671f\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

          dialogCreateDatePicker(year=1970, month=1, day=1)\n
          "},{"location":"qsl4a/ui/dialogs/#dialogcreatetimepicker","title":"dialogCreateTimePicker()","text":"

          \u521b\u5efa\u65f6\u95f4\u9009\u62e9\u5668\u5bf9\u8bdd\u6846\u3002

          dialogCreateTimePicker(hour=0, minute=0, is24hour=False)\n
          "},{"location":"qsl4a/ui/dialogs/#_7","title":"\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u521b\u5efa","text":""},{"location":"qsl4a/ui/dialogs/#dialogcreatealert","title":"dialogCreateAlert()","text":"

          \u521b\u5efa\u81ea\u5b9a\u4e49\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002

          dialogCreateAlert(title=None, message=None)\n

          \u521b\u5efa\u4e00\u4e2a\u7a7a\u8b66\u62a5\u5bf9\u8bdd\u6846\u3002\u53ef\u4e0e\u5176\u4ed6 dialogSet* \u51fd\u6570\u4e00\u8d77\u4f7f\u7528\u6765\u81ea\u5b9a\u4e49\u3002

          "},{"location":"qsl4a/ui/dialogs/#dialogsetitems","title":"dialogSetItems()","text":"

          \u4e3a\u5bf9\u8bdd\u6846\u8bbe\u7f6e\u7b80\u5355\u5217\u8868\u9879\u76ee\u3002

          dialogSetItems(items)\n
          "},{"location":"qsl4a/ui/dialogs/#dialogsetpositivebuttontext","title":"dialogSetPositiveButtonText()","text":"

          \u8bbe\u7f6e\u80af\u5b9a\u6309\u94ae\u6587\u672c\u3002

          dialogSetPositiveButtonText(text)\n
          "},{"location":"qsl4a/ui/dialogs/#dialogsetnegativebuttontext","title":"dialogSetNegativeButtonText()","text":"

          \u8bbe\u7f6e\u5426\u5b9a\u6309\u94ae\u6587\u672c\u3002

          dialogSetNegativeButtonText(text)\n
          "},{"location":"qsl4a/ui/dialogs/#dialogsetneutralbuttontext","title":"dialogSetNeutralButtonText()","text":"

          \u8bbe\u7f6e\u4e2d\u6027\u6309\u94ae\u6587\u672c\u3002

          dialogSetNeutralButtonText(text)\n
          "},{"location":"qsl4a/ui/dialogs/#dialogsetmessageishtml","title":"dialogSetMessageIsHtml()","text":"

          \u8bbe\u7f6e\u6d88\u606f\u662f\u5426\u5e94\u89e3\u6790\u4e3a HTML\u3002

          dialogSetMessageIsHtml(messageIsHtml=True)\n
          "},{"location":"qsl4a/ui/dialogs/#dialogshow","title":"dialogShow()","text":"

          \u663e\u793a\u521b\u5efa\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\u3002

          dialogShow()\n
          "},{"location":"qsl4a/ui/dialogs/#_8","title":"\u5bf9\u8bdd\u6846\u63a7\u5236","text":""},{"location":"qsl4a/ui/dialogs/#dialogdismiss","title":"dialogDismiss()","text":"

          \u5173\u95ed\u5f53\u524d\u5bf9\u8bdd\u6846\u3002

          dialogDismiss()\n
          "},{"location":"qsl4a/ui/dialogs/#dialoggetresponse","title":"dialogGetResponse()","text":"

          \u83b7\u53d6\u5bf9\u8bdd\u6846\u54cd\u5e94\u3002

          dialogGetResponse()\n
          "},{"location":"qsl4a/ui/dialogs/#dialoggetselecteditems","title":"dialogGetSelectedItems()","text":"

          \u4ece\u9009\u62e9\u5bf9\u8bdd\u6846\u83b7\u53d6\u9009\u4e2d\u7684\u9879\u76ee\u3002

          dialogGetSelectedItems()\n
          "},{"location":"qsl4a/ui/dialogs/#_9","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/dialogs/#_10","title":"\u7b80\u5355\u8b66\u62a5","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u663e\u793a\u8b66\u62a5\ndroid.dialogShowAlert(\"Warning\", \"This is an important message!\")\n
          "},{"location":"qsl4a/ui/dialogs/#_11","title":"\u8f93\u5165\u5bf9\u8bdd\u6846","text":"
          # \u83b7\u53d6\u7528\u6237\u8f93\u5165\nresult = droid.dialogGetInput(\"Name\", \"Enter your name:\", \"John\").result\nprint(f\"Hello, {result}!\")\n
          "},{"location":"qsl4a/ui/dialogs/#_12","title":"\u5e26\u6309\u94ae\u7684\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846","text":"
          # \u521b\u5efa\u81ea\u5b9a\u4e49\u5bf9\u8bdd\u6846\ndroid.dialogCreateAlert(\"Custom\", \"Choose an option\")\ndroid.dialogSetItems([\"Option 1\", \"Option 2\", \"Option 3\"])\ndroid.dialogShow()\n\n# \u83b7\u53d6\u54cd\u5e94\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response['item']}\")\n
          "},{"location":"qsl4a/ui/dialogs/#_13","title":"\u8fdb\u5ea6\u5bf9\u8bdd\u6846","text":"
          # \u521b\u5efa\u8fdb\u5ea6\u5bf9\u8bdd\u6846\ndroid.dialogCreateHorizontalProgress(\"Loading\", \"Please wait...\", 100)\ndroid.dialogShow()\n\n# \u66f4\u65b0\u8fdb\u5ea6\nfor i in range(101):\n    droid.dialogSetCurrentProgress(i)\n    time.sleep(0.05)\n\ndroid.dialogDismiss()\n
          "},{"location":"qsl4a/ui/dialogs/#_14","title":"\u65e5\u671f\u9009\u62e9\u5668","text":"
          # \u663e\u793a\u65e5\u671f\u9009\u62e9\u5668\ndroid.dialogCreateDatePicker(2024, 1, 15)\ndroid.dialogShow()\nresponse = droid.dialogGetResponse().result\nprint(f\"Selected: {response}\")\n
          "},{"location":"qsl4a/ui/floatview/","title":"\u6d6e\u52a8\u89c6\u56fe","text":"

          \u6d6e\u52a8\u7a97\u53e3\u652f\u6301\uff0c\u7528\u4e8e\u5728\u5176\u4ed6\u5e94\u7528\u7a0b\u5e8f\u4e0a\u65b9\u4fdd\u6301\u663e\u793a\u7684\u8986\u76d6 UI \u5143\u7d20\u3002

          "},{"location":"qsl4a/ui/floatview/#_2","title":"\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/floatview/#floatview","title":"floatView()","text":"

          \u663e\u793a\u6216\u4fee\u6539\u6d6e\u52a8\u89c6\u56fe\u3002

          floatView(Args=None)\n

          \u53c2\u6570\uff1a - Args (dict): \u914d\u7f6e\u5b57\u5178\uff0c\u5305\u542b\u4ee5\u4e0b\u952e\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08-1 \u521b\u5efa\u65b0\u7684\uff0c>=0 \u4fee\u6539\u73b0\u6709\u7684\uff09 - text (str): \u8981\u663e\u793a\u7684\u6587\u672c\u5185\u5bb9 - html (str): HTML \u5185\u5bb9\uff08\u5982\u679c\u7701\u7565 text \u5219\u4f7f\u7528\uff09 - width (int): \u89c6\u56fe\u5bbd\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a300\uff09 - height (int): \u89c6\u56fe\u9ad8\u5ea6\uff08\u50cf\u7d20\uff09\uff08\u9ed8\u8ba4\uff1a150\uff09 - x (int): X \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - y (int): Y \u4f4d\u7f6e\uff080 = \u5c45\u4e2d\uff0c\u6b63/\u8d1f\u8868\u793a\u504f\u79fb\uff09 - backColor (str): ARGB \u5341\u516d\u8fdb\u5236\u80cc\u666f\u8272\uff08\u9ed8\u8ba4\uff1a'7f7f7f7f'\uff09 - textColor (str): ARGB \u5341\u516d\u8fdb\u5236\u6587\u672c\u8272\uff08\u9ed8\u8ba4\uff1a'ff000000'\uff09 - textSize (int): \u6587\u672c\u5927\u5c0f\uff08\u9ed8\u8ba4\uff1a10\uff09 - textAlign (int): \u6587\u672c\u5bf9\u9f50\uff080 = \u7ee7\u627f\uff09 - script (str): \u957f\u6309\u5173\u95ed\u540e\u8fd0\u884c\u7684\u811a\u672c\u8def\u5f84 - arg: \u811a\u672c\u53c2\u6570 - clickRemove (bool): \u542f\u7528\u70b9\u51fb\u79fb\u9664\uff08\u9ed8\u8ba4\uff1aTrue\uff09 - flag (int): \u7a97\u53e3\u6807\u5fd7\uff08\u9ed8\u8ba4\uff1a40 - \u53ef\u89e6\u6478\uff09

          \u8fd4\u56de\uff1a \u5f53\u524d\u94fe\u5217\u8868\u957f\u5ea6

          "},{"location":"qsl4a/ui/floatview/#floatviewcount","title":"floatViewCount()","text":"

          \u83b7\u53d6\u6d3b\u52a8\u6d6e\u52a8\u89c6\u56fe\u7684\u6570\u91cf\u3002

          floatViewCount()\n

          \u8fd4\u56de\uff1a \u6d6e\u52a8\u89c6\u56fe\u6570\u91cf

          "},{"location":"qsl4a/ui/floatview/#floatviewresult","title":"floatViewResult()","text":"

          \u83b7\u53d6\u6d6e\u52a8\u89c6\u56fe\u7684\u7ed3\u679c/\u72b6\u6001\u3002

          floatViewResult(index=-1)\n

          \u53c2\u6570\uff1a - index (int): \u6d6e\u52a8\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1\uff0c\u8fd4\u56de\u6700\u540e\u64cd\u4f5c\u7ed3\u679c\uff09

          \u8fd4\u56de\uff1a \u5305\u542b\u64cd\u4f5c\u8be6\u60c5\u7684\u5b57\u5178\uff0c\u5305\u62ec\uff1a - x, y: \u4f4d\u7f6e - time: \u65f6\u95f4\u6233 - operation: \u64cd\u4f5c\u7c7b\u578b\uff08'initial'\u3001'move' \u7b49\uff09 - index: \u89c6\u56fe\u7d22\u5f15 - removed: \u5982\u679c\u89c6\u56fe\u88ab\u79fb\u9664\u5219\u4e3a True

          "},{"location":"qsl4a/ui/floatview/#floatviewremove","title":"floatViewRemove()","text":"

          \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\u3002

          floatViewRemove(index=-1)\n

          \u53c2\u6570\uff1a - index (int): \u8981\u79fb\u9664\u7684\u89c6\u56fe\u7d22\u5f15\uff08\u9ed8\u8ba4\uff1a-1 \u79fb\u9664\u6700\u540e\u4e00\u4e2a\uff09

          \u8fd4\u56de\uff1a \u5982\u679c\u6210\u529f\u5219\u4e3a 1\uff0c\u5426\u5219\u4e3a 0

          "},{"location":"qsl4a/ui/floatview/#_3","title":"\u5e38\u91cf","text":"
          • floatView.INDEX_NEW = -1 - \u521b\u5efa\u65b0\u7684\u6d6e\u52a8\u89c6\u56fe
          • floatView.FLAG_DEFAULT_TOUCHABLE = 40 - \u9ed8\u8ba4\u53ef\u89e6\u6478\u6807\u5fd7
          • floatView.TEXT_ALIGNMENT_INHERIT = 0
          • floatView.TEXT_ALIGNMENT_CENTER - \u5c45\u4e2d\u6587\u672c\u5bf9\u9f50
          "},{"location":"qsl4a/ui/floatview/#_4","title":"\u4f7f\u7528\u793a\u4f8b","text":""},{"location":"qsl4a/ui/floatview/#_5","title":"\u57fa\u672c\u6d6e\u52a8\u89c6\u56fe","text":"
          import androidhelper\nfrom androidhelper import Android\n\ndroid = androidhelper.Android()\n\n# \u521b\u5efa\u7b80\u5355\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'index': -1,  # \u521b\u5efa\u65b0\u7684\n    'text': 'Hello World',\n    'width': 400,\n    'height': 300,\n    'x': -300,  # \u4ece\u4e2d\u5fc3\u504f\u79fb\n    'y': -400,\n    'backColor': 'ff0000',  # \u7ea2\u8272\u80cc\u666f\n    'textColor': '0000ff',  # \u84dd\u8272\u6587\u672c\n    'textSize': 16,\n    'textAlign': droid.floatView.TEXT_ALIGNMENT_CENTER\n})\n\n# \u68c0\u67e5\u6570\u91cf\nprint(f\"Float views: {droid.floatViewCount().result}\")\n\n# \u83b7\u53d6\u7ed3\u679c\nresult = droid.floatViewResult().result\nprint(f\"View info: {result}\")\n\n# \u79fb\u9664\u6d6e\u52a8\u89c6\u56fe\ndroid.floatViewRemove(0)\n
          "},{"location":"qsl4a/ui/floatview/#html","title":"HTML \u5185\u5bb9","text":"
          # \u521b\u5efa\u5e26 HTML \u5185\u5bb9\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': '',  # \u7a7a\u6587\u672c\u4ee5\u4f7f\u7528 HTML\n    'html': '<h1>Title</h1><p>Rich <b>HTML</b> content</p>',\n    'width': 500,\n    'height': 400\n})\n
          "},{"location":"qsl4a/ui/floatview/#_6","title":"\u4fee\u6539\u73b0\u6709\u89c6\u56fe","text":"
          # \u521b\u5efa\u521d\u59cb\u89c6\u56fe\ndroid.floatView({'text': 'Initial Text', 'width': 300, 'height': 150})\n\n# \u4fee\u6539\u540c\u4e00\u89c6\u56fe\uff08\u7d22\u5f15 0\uff09\ndroid.floatView({\n    'index': 0,\n    'text': 'Updated Text!',\n    'backColor': '7f00ff00'  # \u7eff\u8272\u80cc\u666f\n})\n\n# \u68c0\u67e5\u79fb\u52a8/\u66f4\u6539\u7ed3\u679c\nresult = droid.floatViewResult(0).result\nprint(f\"Operation: {result.get('operation')}, Position: ({result.get('x')}, {result.get('y')})\")\n
          "},{"location":"qsl4a/ui/floatview/#_7","title":"\u591a\u4e2a\u6d6e\u52a8\u89c6\u56fe","text":"
          # \u521b\u5efa\u591a\u4e2a\u89c6\u56fe\nfor i in range(3):\n    droid.floatView({\n        'index': -1,\n        'text': f'View {i}',\n        'x': i * 100 - 150,\n        'y': i * 100 - 150,\n        'backColor': f'{i}f{i}f{i}f'\n    })\n\nprint(f\"Total views: {droid.floatViewCount().result}\")\n\n# \u79fb\u9664\u6240\u6709\u89c6\u56fe\nwhile droid.floatViewCount().result > 0:\n    droid.floatViewRemove()\n
          "},{"location":"qsl4a/ui/floatview/#_8","title":"\u5e26\u811a\u672c\u56de\u8c03","text":"
          # \u521b\u5efa\u5173\u95ed\u65f6\u8fd0\u884c\u811a\u672c\u7684\u6d6e\u52a8\u89c6\u56fe\ndroid.floatView({\n    'text': 'Click to close and run script',\n    'script': '/sdcard/my_script.py',\n    'arg': 'hello from float view',\n    'clickRemove': True\n})\n
          "},{"location":"qsl4a/ui/fullscreen/","title":"\u5168\u5c4f UI","text":"

          \u4f7f\u7528\u539f\u751f Android \u5e03\u5c40\u521b\u5efa\u81ea\u5b9a\u4e49\u5168\u5c4f\u754c\u9762\u3002

          "},{"location":"qsl4a/ui/fullscreen/#_1","title":"\u5e03\u5c40\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullshow","title":"fullShow()","text":"

          \u663e\u793a\u5168\u5c4f\u5e03\u5c40\u3002

          fullShow(layout, title=None, theme=None)\n

          \u53c2\u6570\uff1a - layout (str): JSON \u5e03\u5c40\u5b9a\u4e49\u6216\u5e03\u5c40\u5b57\u7b26\u4e32 - title (str, optional): \u7a97\u53e3\u6807\u9898 - theme (str, optional): \u4e3b\u9898\u540d\u79f0

          \u8fd4\u56de\uff1a \u7a97\u53e3 ID

          "},{"location":"qsl4a/ui/fullscreen/#fulldismiss","title":"fullDismiss()","text":"

          \u5173\u95ed\u5168\u5c4f\u7a97\u53e3\u3002

          fullDismiss()\n
          "},{"location":"qsl4a/ui/fullscreen/#fullquery","title":"fullQuery()","text":"

          \u67e5\u8be2\u6240\u6709\u5c0f\u90e8\u4ef6\u503c\u3002

          fullQuery()\n

          \u8fd4\u56de\uff1a \u5c0f\u90e8\u4ef6 ID \u548c\u503c\u7684\u5b57\u5178

          "},{"location":"qsl4a/ui/fullscreen/#fullquerydetail","title":"fullQueryDetail()","text":"

          \u67e5\u8be2\u7279\u5b9a\u5c0f\u90e8\u4ef6\u8be6\u60c5\u3002

          fullQueryDetail(id)\n
          "},{"location":"qsl4a/ui/fullscreen/#_2","title":"\u5c5e\u6027\u65b9\u6cd5","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperty","title":"fullGetProperty()","text":"

          \u83b7\u53d6\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

          fullGetProperty(id, property)\n
          "},{"location":"qsl4a/ui/fullscreen/#fullsetproperty","title":"fullSetProperty()","text":"

          \u8bbe\u7f6e\u5c0f\u90e8\u4ef6\u5c5e\u6027\u3002

          fullSetProperty(id, property, value)\n
          "},{"location":"qsl4a/ui/fullscreen/#fullsetlist","title":"fullSetList()","text":"

          \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

          fullSetList(id, list, isHtml=False, listType=0)\n
          "},{"location":"qsl4a/ui/fullscreen/#fullsetlist2","title":"fullSetList2()","text":"

          \u4f7f\u7528\u8d44\u6e90 ID \u8bbe\u7f6e\u5217\u8868\u5c0f\u90e8\u4ef6\u9879\u76ee\u3002

          fullSetList2(id, list, intRes)\n

          \u53c2\u6570\uff1a - id (str): \u5c0f\u90e8\u4ef6 ID - list (list): \u9879\u76ee\u5217\u8868 - intRes (int): \u5217\u8868\u9879\u76ee\u5e03\u5c40\u7684 Android \u8d44\u6e90 ID

          "},{"location":"qsl4a/ui/fullscreen/#fullsetlistselected","title":"fullSetListSelected()","text":"

          \u5728\u5217\u8868\u4e2d\u8bbe\u7f6e\u9009\u4e2d\u9879\u76ee\u3002

          fullSetListSelected(id, selected)\n

          \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID - selected (int): \u8981\u9009\u4e2d\u7684\u9879\u76ee\u7d22\u5f15

          "},{"location":"qsl4a/ui/fullscreen/#fullgetlistselected","title":"fullGetListSelected()","text":"

          \u83b7\u53d6\u5f53\u524d\u9009\u4e2d\u7684\u5217\u8868\u9879\u76ee\u7d22\u5f15\u3002

          fullGetListSelected(id)\n

          \u53c2\u6570\uff1a - id (str): \u5217\u8868\u5c0f\u90e8\u4ef6 ID

          \u8fd4\u56de\uff1a \u9009\u4e2d\u9879\u76ee\u7d22\u5f15

          "},{"location":"qsl4a/ui/fullscreen/#_3","title":"\u6279\u91cf\u5c5e\u6027\u64cd\u4f5c","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetproperties","title":"fullGetProperties()","text":"

          \u4e00\u6b21\u83b7\u53d6\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

          fullGetProperties(ids, property)\n

          \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u83b7\u53d6\u7684\u5c5e\u6027\u540d

          \u8fd4\u56de\uff1a \u6620\u5c04\u5c0f\u90e8\u4ef6 ID \u5230\u5c5e\u6027\u503c\u7684\u5b57\u5178

          "},{"location":"qsl4a/ui/fullscreen/#fullsetproperties","title":"fullSetProperties()","text":"

          \u4e00\u6b21\u8bbe\u7f6e\u591a\u4e2a\u5c0f\u90e8\u4ef6\u7684\u5c5e\u6027\u3002

          fullSetProperties(ids, property, value)\n

          \u53c2\u6570\uff1a - ids (list): \u5c0f\u90e8\u4ef6 ID \u5217\u8868 - property (str): \u8981\u8bbe\u7f6e\u7684\u5c5e\u6027\u540d - value: \u5c5e\u6027\u503c

          "},{"location":"qsl4a/ui/fullscreen/#_4","title":"\u622a\u56fe","text":""},{"location":"qsl4a/ui/fullscreen/#fullgetscreenshot","title":"fullGetScreenShot()","text":"

          \u6355\u83b7\u5168\u5c4f\u622a\u56fe\u3002

          fullGetScreenShot(path=None)\n

          \u53c2\u6570\uff1a - path (str, optional): \u4fdd\u5b58\u8def\u5f84\u3002\u5982\u679c\u4e3a None\uff0c\u5219\u5728\u4e8b\u4ef6\u4e2d\u8fd4\u56de

          \u8fd4\u56de\uff1a \u5305\u542b\u622a\u56fe\u6570\u636e\u7684\u4e8b\u4ef6

          "},{"location":"qsl4a/ui/fullscreen/#_5","title":"\u4f7f\u7528\u793a\u4f8b","text":"
          import androidhelper\n\ndroid = androidhelper.Android()\n\n# \u5b9a\u4e49\u5e03\u5c40\nlayout = '''\n{ \"type\": \"LinearLayout\", \"orientation\": \"vertical\",\n  \"children\": [\n    { \"type\": \"TextView\", \"id\": \"title\", \"text\": \"Hello\" },\n    { \"type\": \"Button\", \"id\": \"btn\", \"text\": \"Click Me\" }\n  ]\n}\n'''\n\n# \u663e\u793a\u5e03\u5c40\ndroid.fullShow(layout, \"My App\")\n\n# \u67e5\u8be2\u6309\u94ae\u70b9\u51fb\nevent = droid.eventWaitFor('click', timeout=10)\nif event.result:\n    widget_id = event.result['data']['id']\n    if widget_id == 'btn':\n        print(\"Button clicked!\")\n\ndroid.fullDismiss()\n
          "}]} \ No newline at end of file diff --git a/zh/sitemap.xml b/zh/sitemap.xml index 2835e18..34bbcfb 100644 --- a/zh/sitemap.xml +++ b/zh/sitemap.xml @@ -2,202 +2,202 @@ https://www.qpython.org/zh/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/AIPyApp/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/GraphicalInterface/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/Notebook/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/Ollama/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/Terminal/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/community/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/editor-guide/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/external-api/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/featured-courses/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/getting-started/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/qpypi-guide/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/qpython-x/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/tutorial-hello-world/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/whats-new/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/qsl4a/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/qsl4a/connectivity/contacts/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/qsl4a/connectivity/ftp/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/qsl4a/connectivity/location/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/qsl4a/connectivity/phone/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/qsl4a/connectivity/signalstrength/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/qsl4a/connectivity/sms/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/qsl4a/connectivity/wifi/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/qsl4a/core/android-base/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/qsl4a/core/events/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/qsl4a/core/intent/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/qsl4a/hardware/bluetooth/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/qsl4a/hardware/camera/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/qsl4a/hardware/recorder/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/qsl4a/hardware/usbserial/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/qsl4a/hardware/webcam/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/qsl4a/media/image/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/qsl4a/media/mediaplayer/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/qsl4a/special/cipher/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/qsl4a/special/pgptai/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/qsl4a/storage/clipboard/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/qsl4a/storage/documentfile/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/qsl4a/storage/preferences/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/qsl4a/system/activityresult/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/qsl4a/system/application/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/qsl4a/system/battery/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/qsl4a/system/qpyinterface/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/qsl4a/system/sensors/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/qsl4a/system/settings/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/qsl4a/system/sysinfo/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/qsl4a/system/wakelock/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/qsl4a/ui/accessibility/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/qsl4a/ui/dialogs/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/qsl4a/ui/floatview/ - 2026-04-10 + 2026-04-21 https://www.qpython.org/zh/qsl4a/ui/fullscreen/ - 2026-04-10 + 2026-04-21 \ No newline at end of file diff --git a/zh/sitemap.xml.gz b/zh/sitemap.xml.gz index 3ec25aabc3762f333845f0d6f4f3273629d7937b..f636a48a99f81a28d69f4cda53a68d94fd9c31cf 100644 GIT binary patch delta 447 zcmV;w0YLuk1nmR|ABzYG0KVpt2fBZ`R+G!KH-Y+H;UBdgp1v;+DHYZHk|7P`z&{1S z+=0WQ@?WE16XQ!!(Qn?v2t_5IF^?3$7Zr7J9H&6C6jjBRB<8B0s4W{y_^J`CV_ZR^ zqQV`5Oc~qC#VIp#QSlx{G(}b{kOkYK+S*KH;OR@VdM&Cdlg2e^d=2P*tmc21ec9oj z2N13T&SeLi{VfW1f%{3Kusg`Xr_KXCl8BBAaFvrdf!nROaW4#1T0ns z)`EHUzw?xus3B>{&_*|nnw&fGXo!(AcBs{gLyJX<7Zx0AxKs-ndGcb&k&-8~YW4!r zfC%Qr4nW_L$>!T%6pVpmW=nwcMusK9!W6n_2Qb46s{M-r!9A8iJ|UjL(uW^fH*! zjOGD4Q%5EY8EXh_j?`8SFj_I-34>9ZP<7HGI*5V#0J)t(2^v44#Aq@X-XR=}n8A`D zqxz%8Y{@Wj!?+dJ5Jbf>Hkipr#ReG*dsHlZVA55ICV*z3(UurU0o=0v4+R zYr(ww-+4++)Q~h}Xrr4(P0k&8G{i_5JJf2$p~WJ_3k!}lT&jhPJb5wXNXe5~HG6?* zKm_w*2cYlBWb^GW3dX=Ovn9ZJBg2wlVG3Qe1DN3j)&9kRU?R;5nv^e?8uF#L4BruS px%SZ{1XR595#&TB+bgU5
            +
          • + + + + v4.0.0 + + + + +
          • +
          • @@ -2862,6 +2873,17 @@
              +
            • + + + + v4.0.0 + + + + +
            • +
            • @@ -3067,6 +3089,12 @@

              更新日志

              +

              v4.0.0

              +
                +
              • 外部存储访问:用户现在可以将 Python 脚本直接保存到外部存储设备,大大提升了文件管理的灵活性。
              • +
              • QSL4A 功能增强:改进了 QSL4A 的功能。(https://www.qpython.org/en/qsl4a/)
              • +
              • 社区与课程:优化了社区和课程模块,提供更清晰的信息和更便捷的导航,方便用户访问学习资源和获得支持。
              • +

              v3.9.2 / v3.9.3

              • SDK 升级,支持 16 KB 页面大小,提供更流畅的运行环境

  • Next Steps