KuM*_*ann 4 python android kivy buildozer
我正在尝试用 kivy 构建一个 android APP,我的要求很简单:
\n打开Android APP时,会从0开始计数,并且每隔5秒在状态栏中弹出提示。提示内容为当前计数值。如果APP切换到后台或者屏幕被锁定,状态栏仍会每5秒弹出一次提示。
\n这是我从网上修改的代码:
\nfrom os.path import join, dirname, realpath\n\nimport kivy\nfrom kivy.app import App\nfrom kivy.uix.boxlayout import BoxLayout\nfrom kivy.clock import Clock\nfrom plyer import notification\nfrom plyer.utils import platform\nfrom kivy.properties import DictProperty\nkivy.require('1.8.0')\n\na = 0\nfrom kivy.utils import platform\nif platform == 'android':\n #pass\n from jnius import autoclass\n package_name = 'net.saband.myapp'\n service_name = 'ENTRYPOINT_TO_PY'\n service = autoclass('{}.Service{}'.format(package_name, service_name))\n mActivity = autoclass('org.kivy.android.PythonActivity').mActivity\n service.start(mActivity, '')\n\nclass NotificationDemo(BoxLayout):\n kwargs = DictProperty()\n def update(self,dt):\n global a\n a = a + 1\n mode = 'fancy'\n message = str(a)\n title = self.ids.notification_title.text\n self.ids.notification_text.text = message\n ticker = self.ids.ticker_text.text\n self.kwargs = {'title': title, 'message': message, 'ticker': ticker}\n if mode == 'fancy':\n self.kwargs['app_name'] = "Plyer Notification Example"\n if platform == "win":\n self.kwargs['app_icon'] = join(dirname(realpath(__file__)),\n 'plyer-icon.ico')\n self.kwargs['timeout'] = 4\n else:\n self.kwargs['app_icon'] = join(dirname(realpath(__file__)),\n 'plyer-icon.png')\n elif mode == 'toast':\n self.kwargs['toast'] = True\n print(message)\n notification.notify(**self.kwargs)\n\n\nclass NotificationDemoApp(App):\n def build(self):\n notify = NotificationDemo()\n Clock.schedule_interval(notify.update, 5)\n return notify\n\n def on_pause(self):\n return True\n\nif __name__ == '__main__':\n NotificationDemoApp().run()\nRun Code Online (Sandbox Code Playgroud)\nkv文件就OK了,如下
\n#:kivy 1.8.0\n<NotificationDemo>:\n orientation: 'vertical'\n Widget:\n BoxLayout:\n orientation: 'horizontal'\n size_hint: 1, None\n TextInput:\n id: notification_title\n text: 'Put title here'\n size_hint: 1, None\n TextInput:\n id: notification_text\n text: 'Put message here'\n size_hint: 1, None\n TextInput:\n id: ticker_text\n text: 'New notification'\n size_hint: 1, None\n Button:\n text: 'Toast Notification'\n size_hint: 1, None\n on_release: root.do_notify(mode='toast')\n Button:\n text: 'Simple Notification'\n size_hint: 1, None\n on_release: root.do_notify(mode='normal')\n Button:\n text: 'Fancy Notification'\n size_hint: 1, None\n on_release: root.do_notify(mode='fancy')\n Widget:\nRun Code Online (Sandbox Code Playgroud)\n\xef\xbc\x8cbuildozer.spec 如下:
\n[app]\n\n# (str) Title of your application\ntitle = SteeringRemind\n\n# (str) Package name\npackage.name = net.saband.myapp\n\n# (str) Package domain (needed for android/ios packaging)\npackage.domain = org.SteeringRemind\n\n# (str) Source code where the main.py live\nsource.dir = .\n\n# (list) Source files to include (let empty to include all the files)\nsource.include_exts = py,png,jpg,kv,atlas,ttf,wav\n\n# (list) List of inclusions using pattern matching\nsource.include_patterns = assets/*,images/*.png\n\n# (list) Source files to exclude (let empty to not exclude anything)\n#source.exclude_exts = spec\n\n# (list) List of directory to exclude (let empty to not exclude anything)\n#source.exclude_dirs = tests, bin\n\n# (list) List of exclusions using pattern matching\n#source.exclude_patterns = license,images/*/*.jpg\n\n# (str) Application versioning (method 1)\nversion = 0.100.0\n\n# (str) Application versioning (method 2)\n# version.regex = __version__ = ['"](.*)['"]\n# version.filename = %(source.dir)s/main.py\n\n# (list) Application requirements\n# comma separated e.g. requirements = sqlite3,kivy\nrequirements = python3,kivy,pillow,plyer,pyjnius\n\n# (str) Custom source folders for requirements\n# Sets custom source for any requirements with recipes\n# requirements.source.kivy = ../../kivy\n\n# (list) Garden requirements\n#garden_requirements =\n\n# (str) Presplash of the application\n#presplash.filename = %(source.dir)s/assets/background.jpg\n\nandroid.presplash_color=#FFFFFF\n\n# (str) Icon of the application\n#icon.filename = %(source.dir)s/assets/steering.png\n\n# (str) Supported orientation (one of landscape, sensorLandscape, portrait or all)\norientation = portrait\n\n# (list) List of service to declare\nservices = NAME:ENTRYPOINT_TO_PY,NAME2:ENTRYPOINT2_TO_PY\n#services = NAME:Myservice\n#\n# OSX Specific\n#\n\n#\n# author = \xc2\xa9 Copyright Info\n\n# change the major version of python used by the app\n#osx.python_version = 3\n\n# Kivy version to use\n#osx.kivy_version = 1.9.1\n\n#\n# Android specific\n#\n\n# (bool) Indicate if the application should be fullscreen or not\nfullscreen = 0\n\n# (string) Presplash background color (for new android toolchain)\n# Supported formats are: #RRGGBB #AARRGGBB or one of the following names:\n# red, blue, green, black, white, gray, cyan, magenta, yellow, lightgray,\n# darkgray, grey, lightgrey, darkgrey, aqua, fuchsia, lime, maroon, navy,\n# olive, purple, silver, teal.\n#android.presplash_color = #FFFFFF\n\n# (list) Permissions\nandroid.permissions = INTERNET\n\n# (int) Target Android API, should be as high as possible.\nandroid.api = 28\n\n# (int) Minimum API your APK will support.\nandroid.minapi = 21\n\n# (int) Android SDK version to use\n#android.sdk = 20\n\n# (str) Android NDK version to use\nandroid.ndk = 17c\n\n# (int) Android NDK API to use. This is the minimum API your app will support, it should usually match android.minapi.\n#android.ndk_api = 21\n\n# (bool) Use --private data storage (True) or --dir public storage (False)\n#android.private_storage = True\n\n# (str) Android NDK directory (if empty, it will be automatically downloaded.)\nandroid.ndk_path = /home/kivy/Android/android-ndk-r17c\n\n# (str) Android SDK directory (if empty, it will be automatically downloaded.)\nandroid.sdk_path = /home/kivy/Android/android-sdk-28\n\n# (str) ANT directory (if empty, it will be automatically downloaded.)\nandroid.ant_path = /home/kivy/.buildozer/android/platform/apache-ant-1.9.4\n\n# (bool) If True, then skip trying to update the Android sdk\n# This can be useful to avoid excess Internet downloads or save time\n# when an update is due and you just want to test/build your package\n# android.skip_update = False\n\n# (bool) If True, then automatically accept SDK license\n# agreements. This is intended for automation only. If set to False,\n# the default, you will be shown the license when first running\n# buildozer.\n# android.accept_sdk_license = False\n\n# (str) Android entry point, default is ok for Kivy-based app\n#android.entrypoint = org.renpy.android.PythonActivity\n\n# (list) Pattern to whitelist for the whole project\n#android.whitelist =\n\n# (str) Path to a custom whitelist file\n#android.whitelist_src =\n\n# (str) Path to a custom blacklist file\n#android.blacklist_src =\n\n# (list) List of Java .jar files to add to the libs so that pyjnius can access\n# their classes. Don't add jars that you do not need, since extra jars can slow\n# down the build process. Allows wildcards matching, for example:\n# OUYA-ODK/libs/*.jar\n#android.add_jars = foo.jar,bar.jar,path/to/more/*.jar\n\n# (list) List of Java files to add to the android project (can be java or a\n# directory containing the files)\n#android.add_src =\n\n# (list) Android AAR archives to add (currently works only with sdl2_gradle\n# bootstrap)\n#android.add_aars =\n\n# (list) Gradle dependencies to add (currently works only with sdl2_gradle\n# bootstrap)\n#android.gradle_dependencies =\n\n# (list) Java classes to add as activities to the manifest.\n#android.add_activites = com.example.ExampleActivity\n\n# (str) OUYA Console category. Should be one of GAME or APP\n# If you leave this blank, OUYA support will not be enabled\n#android.ouya.category = GAME\n\n# (str) Filename of OUYA Console icon. It must be a 732x412 png image.\n#android.ouya.icon.filename = %(source.dir)s/data/ouya_icon.png\n\n# (str) XML file to include as an intent filters in <activity> tag\n#android.manifest.intent_filters =\n\n# (str) launchMode to set for the main activity\n#android.manifest.launch_mode = standard\n\n# (list) Android additional libraries to copy into libs/armeabi\n#android.add_libs_armeabi = libs/android/*.so\n#android.add_libs_armeabi_v7a = libs/android-v7/*.so\n#android.add_libs_arm64_v8a = libs/android-v8/*.so\n#android.add_libs_x86 = libs/android-x86/*.so\n#android.add_libs_mips = libs/android-mips/*.so\n\n# (bool) Indicate whether the screen should stay on\n# Don't forget to add the WAKE_LOCK permission if you set this to True\n#android.wakelock = False\n\n# (list) Android application meta-data to set (key=value format)\n#android.meta_data =\n\n# (list) Android library project to add (will be added in the\n# project.properties automatically.)\n#android.library_references =\n\n# (list) Android shared libraries which will be added to AndroidManifest.xml using <uses-library> tag\n#android.uses_library =\n\n# (str) Android logcat filters to use\n#android.logcat_filters = *:S python:D\n\n# (bool) Copy library instead of making a libpymodules.so\n#android.copy_libs = 1\n\n# (str) The Android arch to build for, choices: armeabi-v7a, arm64-v8a, x86, x86_64\nandroid.arch = armeabi-v7a\n\n#\n# Python for android (p4a) specific\n#\n\n# (str) python-for-android fork to use, defaults to upstream (kivy)\n#p4a.fork = kivy\n\n# (str) python-for-android branch to use, defaults to master\n#p4a.branch = master\n\n# (str) python-for-android git clone directory (if empty, it will be automatically cloned from github)\np4a.source_dir = ~/Repos/python-for-android/\n# (str) The directory in which python-for-android should look for your own build recipes (if any)\n#p4a.local_recipes =\n\n# (str) Filename to the hook for p4a\n#p4a.hook =\n\n# (str) Bootstrap to use for android builds\n# p4a.bootstrap = sdl2\n\n# (int) port number to specify an explicit --port= p4a argument (eg for bootstrap flask)\n#p4a.port =\n\n\n#\n# iOS specific\n#\n\n# (str) Path to a custom kivy-ios folder\n#ios.kivy_ios_dir = ../kivy-ios\n# Alternately, specify the URL and branch of a git checkout:\n#ios.kivy_ios_url = https://github.com/kivy/kivy-ios\n#ios.kivy_ios_branch = master\n\n# Another platform dependency: ios-deploy\n# Uncomment to use a custom checkout\n#ios.ios_deploy_dir = ../ios_deploy\n# Or specify URL and branch\n#ios.ios_deploy_url = https://github.com/phonegap/ios-deploy\n#ios.ios_deploy_branch = 1.7.0\n\n# (str) Name of the certificate to use for signing the debug version\n# Get a list of available identities: buildozer ios list_identities\n#ios.codesign.debug = "iPhone Developer: <lastname> <firstname> (<hexstring>)"\n\n# (str) Name of the certificate to use for signing the release version\n#ios.codesign.release = %(ios.codesign.debug)s\n\n\n[buildozer]\n\n# (int) Log level (0 = error only, 1 = info, 2 = debug (with command output))\nlog_level = 2\n\n# (int) Display warning if buildozer is run as root (0 = False, 1 = True)\nwarn_on_root = 0\n\n# (str) Path to build artifact storage, absolute or relative to spec file\n# build_dir = ./.buildozer\n\n# (str) Path to build output (i.e. .apk, .ipa) storage\n# bin_dir = ./bin\n\n# -----------------------------------------------------------------------------\n# List as sections\n#\n# You can define all the "list" as [section:key].\n# Each line will be considered as a option to the list.\n# Let's take [app] / source.exclude_patterns.\n# Instead of doing:\n#\n#[app]\n#source.exclude_patterns = license,data/audio/*.wav,data/images/original/*\n#\n# This can be translated into:\n#\n#[app:source.exclude_patterns]\n#license\n#data/audio/*.wav\n#data/images/original/*\n#\n\n\n# -----------------------------------------------------------------------------\n# Profiles\n#\n# You can extend section / key with a profile\n# For example, you want to deploy a demo version of your application without\n# HD content. You could first change the title to add "(demo)" in the name\n# and extend the excluded directories to remove the HD content.\n#\n#[app@demo]\n#title = My Application (demo)\n#\n#[app:source.exclude_patterns@demo]\n#images/hd/*\n#\n# Then, invoke the command line with the "demo" profile:\n#\n#buildozer --profile demo android debug\nRun Code Online (Sandbox Code Playgroud)\n当我使用“buildozer android debug”时,apk生成正确,但有警告
\n[INFO]: # APK renamed to net.saband.myapp-0.100.0-debug.apk\n[DEBUG]: -> running cp /home/kivy/Repos/Python3/kivy/examples/demo/test/.buildozer/android/platform/build/dists/net.saband.myapp/build/outputs/apk/debug/net.saband.myapp-debug.apk net.saband.myapp-0.100.0-debug.apk\nWARNING: Received a --sdk argument, but this argument is deprecated and does nothing.\nNo compiled python is present to zip, skipping.\nNo setup.py/pyproject.toml used, copying full private data into .apk.\nApplying Java source code patches...\nApplying patch: src/patches/SDLActivity.java.patch\nWarning: failed to apply patch (exit code 1), assuming it is already applied: src/patches/SDLActivity.java.patch\nRun Code Online (Sandbox Code Playgroud)\n当我在android手机中安装apk时,在presplash显示后它会立即崩溃,\n如果我像下面这样注释掉有关jnius的行,apk可以正常运行,但服务不会在后台运行(没有提示弹出)在状态栏中向上)
\nif platform == 'android':\n #pass\n from jnius import autoclass\n package_name = 'net.saband.myapp'\n service_name = 'ENTRYPOINT_TO_PY'\n #service = autoclass('{}.Service{}'.format(package_name, service_name))\n #mActivity = autoclass('org.kivy.android.PythonActivity').mActivity\n #service.start(mActivity, '')\nRun Code Online (Sandbox Code Playgroud)\n我不知道\xe2\x80\x99t是否我误解了jnius,或者配置错误\n再次...任何帮助将不胜感激!
\n经过几天的测试,我解决了这个问题
我之前对后台操作的理解确实是有问题的,或者说我的解决方案只是达到目的的方法之一。
在 中main.py,定义服务并启动它:
from jnius import autoclass
SERVICE_NAME = u'{packagename}.Service{servicename}'.format(
packagename=u'org.kivy.test',
servicename=u'Myservice'
)
service = autoclass(SERVICE_NAME)
mActivity = autoclass(u'org.kivy.android.PythonActivity').mActivity
argument = ''
service.start(mActivity, argument)
Run Code Online (Sandbox Code Playgroud)
在buildozer.spec:
# (str) Package name
package.name = test
# (str) Package domain (needed for android/ios packaging)
package.domain = org.kivy
# (list) List of service to declare
services = Myservice:service.py
Run Code Online (Sandbox Code Playgroud)
然后service.py根据需要进行编辑。和可以使用 进行main.py通信。service.pyoscpy
通过以上操作,即使APP切换到后台,打开APP后也能弹出通知。
| 归档时间: |
|
| 查看次数: |
7296 次 |
| 最近记录: |