如何使用kivy python在后台运行任何应用程序

2024-04-25 23:30:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我用KipyyPython构建了一个简单的应用程序,它涉及一些计算,当一些条件得到满足时显示一些通知,考虑它是一个应用程序,它每30秒钟打一次API,并显示通知,它一直工作到这一点,但是当我关闭应用程序时,通知不会出现在我的Android设备中。strong>所以基本上我也想在后台运行它,这样我就可以一直收到通知。我尝试了以下方法,但无效:-

这是main.py

**编辑:我可以通过更改buildozer.spec文件中提到的包名称和包域来解决此问题,但现在它需要ssl,因此我在代码中导入并添加了提到的2条ssl语句,但现在我遇到以下错误:

ERROR: Could not find a version that satisfies the requirement ssl (from versions: 1.15, 1.16)
ERROR: No matching distribution found for ssl
Exception information:
Traceback (most recent call last):
  File "/content/.buildozer/android/platform/build-armeabi-v7a/build/venv/lib/python3.8/site-packages/pip/_vendor/resolvelib/resolvers.py", line 341, in resolve
    name, crit = self._merge_into_criterion(r, parent=None)
  File "/content/.buildozer/android/platform/build-armeabi-v7a/build/venv/lib/python3.8/site-packages/pip/_vendor/resolvelib/resolvers.py", line 173, in _merge_into_criterion
    raise RequirementsConflicted(criterion)
pip._vendor.resolvelib.resolvers.RequirementsConflicted: Requirements conflict: SpecifierRequirement('ssl')

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/content/.buildozer/android/platform/build-armeabi-v7a/build/venv/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/resolver.py", line 127, in resolve
    result = self._result = resolver.resolve(
  File "/content/.buildozer/android/platform/build-armeabi-v7a/build/venv/lib/python3.8/site-packages/pip/_vendor/resolvelib/resolvers.py", line 473, in resolve
    state = resolution.resolve(requirements, max_rounds=max_rounds)
  File "/content/.buildozer/android/platform/build-armeabi-v7a/build/venv/lib/python3.8/site-packages/pip/_vendor/resolvelib/resolvers.py", line 343, in resolve
    raise ResolutionImpossible(e.criterion.information)
pip._vendor.resolvelib.resolvers.ResolutionImpossible: [RequirementInformation(requirement=SpecifierRequirement('ssl'), parent=None)]

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/content/.buildozer/android/platform/build-armeabi-v7a/build/venv/lib/python3.8/site-packages/pip/_internal/cli/base_command.py", line 180, in _main
    status = self.run(options, args)
  File "/content/.buildozer/android/platform/build-armeabi-v7a/build/venv/lib/python3.8/site-packages/pip/_internal/cli/req_command.py", line 204, in wrapper
    return func(self, options, args)
  File "/content/.buildozer/android/platform/build-armeabi-v7a/build/venv/lib/python3.8/site-packages/pip/_internal/commands/install.py", line 318, in run
    requirement_set = resolver.resolve(
  File "/content/.buildozer/android/platform/build-armeabi-v7a/build/venv/lib/python3.8/site-packages/pip/_internal/resolution/resolvelib/resolver.py", line 136, in resolve
    raise error from e
pip._internal.exceptions.DistributionNotFound: No matching distribution found for ssl
Removed ssl from https://files.pythonhosted.org/packages/3a/c2/846a19d1572ec6cb8ac438d58a898de8926d32e13f0355cdf4ab00864b5f/ssl-1.15.tar.gz#sha256=1266302ce62c4b60c7ca0e1d3d104ba11d2749e5881d8ac4f006cf9a0446d589 (from -r requirements.txt (line 1)) from build tracker '/tmp/pip-req-tracker-y6xm5k7e'
Removed ssl from https://files.pythonhosted.org/packages/83/21/f469c9923235f8c36d5fd5334ed11e2681abad7e0032c5aba964dcaf9bbb/ssl-1.16.tar.gz#sha256=ac21156fee6aee9eb8d765bbb16f5f49492d81ff4b22f7b8fc001d2251120930 (from -r requirements.txt (line 1)) from build tracker '/tmp/pip-req-tracker-y6xm5k7e'
Removed build tracker: '/tmp/pip-req-tracker-y6xm5k7e'

from kivymd.app import MDApp
from kivymd.uix.label import MDLabel
from kivymd.uix.screen import Screen
from kivymd.uix.button import MDFlatButton, MDRectangleFlatButton
from kivymd.uix.boxlayout import MDBoxLayout
from kivy.core.window import Window
from kivy.lang.builder import Builder
from kivy.clock import Clock
from kivy.uix.screenmanager import Screen, ScreenManager
from plyer import notification
from jnius import autoclass

import ssl
ssl._create_default_https_context = ssl._create_unverified_context

###################### background service ########################
SERVICE_NAME = u'{packagename}.Service{servicename}'.format(
    packagename=u'org.test.myapp',
    servicename=u'Myservice'
)

service = autoclass(SERVICE_NAME)
mActivity = autoclass(u'org.kivy.android.PythonActivity').mActivity
argument = ''
service.start(mActivity, argument)
###################################################################

screen_helper = """
Screen:
 My screen - just ignore this. Assume it anything.
"""

class MyApp(MDApp):
    
    def show_notification(self, message):
        notification.notify(title='test', message=message)

    def runMyStrat(self):
        Clock.schedule_interval(self.strategy, 5)

    def stopMyStrat(self):
        Clock.unschedule(self.strategy)

    def navigation_draw(self):
        print("Drawer open or closed !")

    def display_help(self):
        print("Asked for Help !")

    def strategy(self, obj):
        ''' 
        get some data from an API and displays a notification every 5 seconds if some statement becomes true.
        This function works and send notification when app is running, but when I close it or switch between apps, it doesn't, is something wrong with my service.py script, I'm new to kivy
        '''

    def build(self):
        screen = Builder.load_string(screen_helper)
        return screen

if __name__ == '__main__':
    MyApp().run()

这是service.py

'p4a example service using oscpy to communicate with main application.'
from random import sample, randint
from string import ascii_letters
from time import localtime, asctime, sleep

from oscpy.server import OSCThreadServer
from oscpy.client import OSCClient

CLIENT = OSCClient('localhost', 3002)

def ping(*_):
    'answer to ping messages'
    CLIENT.send_message(
        b'/message',
        [
            ''.join(sample(ascii_letters, randint(10, 20)))
            .encode('utf8'),
        ],
    )


def send_date():
    'send date to the application'
    CLIENT.send_message(
        b'/date',
        [asctime(localtime()).encode('utf8'), ],
    )


if __name__ == '__main__':
    SERVER = OSCThreadServer()
    SERVER.listen('localhost', port=3000, default=True)
    SERVER.bind(b'/ping', ping)
    while True:
        sleep(1)
        send_date()

Builder.spec文件:

[app]

# (str) Title of your application
title = AlgoGuru

# (str) Package name
package.name = myapp

# (str) Package domain (needed for android/ios packaging)
package.domain = org.test

# (str) Source code where the main.py live
source.dir = .

# (list) Source files to include (let empty to include all the files)
source.include_exts = py,png,jpg,kv,atlas

# (list) List of inclusions using pattern matching
#source.include_patterns = assets/*,images/*.png

# (list) Source files to exclude (let empty to not exclude anything)
#source.exclude_exts = spec

# (list) List of directory to exclude (let empty to not exclude anything)
#source.exclude_dirs = tests, bin

# (list) List of exclusions using pattern matching
#source.exclude_patterns = license,images/*/*.jpg

# (str) Application versioning (method 1)
version = 0.1

# (str) Application versioning (method 2)
# version.regex = __version__ = ['"](.*)['"]
# version.filename = %(source.dir)s/main.py

# (list) Application requirements
# comma separated e.g. requirements = sqlite3,kivy
requirements = python3,kivy,kivymd,plyer,nsetools,dateutil,jnius,ssl,pyjnius

# (str) Custom source folders for requirements
# Sets custom source for any requirements with recipes
# requirements.source.kivy = ../../kivy

# (list) Garden requirements
#garden_requirements =

# (str) Presplash of the application
#presplash.filename = %(source.dir)s/data/presplash.png

# (str) Icon of the application
#icon.filename = %(source.dir)s/data/icon.png

# (str) Supported orientation (one of landscape, sensorLandscape, portrait or all)
orientation = portrait

# (list) List of service to declare
#services = NAME:ENTRYPOINT_TO_PY,NAME2:ENTRYPOINT2_TO_PY
services = Myservice:service.py
#
# OSX Specific
#

#
# author = © Copyright Info

# change the major version of python used by the app
osx.python_version = 3

# Kivy version to use
osx.kivy_version = 1.9.1

#
# Android specific
#

# (bool) Indicate if the application should be fullscreen or not
fullscreen = 0

# (string) Presplash background color (for new android toolchain)
# Supported formats are: #RRGGBB #AARRGGBB or one of the following names:
# red, blue, green, black, white, gray, cyan, magenta, yellow, lightgray,
# darkgray, grey, lightgrey, darkgrey, aqua, fuchsia, lime, maroon, navy,
# olive, purple, silver, teal.
#android.presplash_color = #FFFFFF

# (list) Permissions
android.permissions = INTERNET

# (int) Target Android API, should be as high as possible.
#android.api = 27

# (int) Minimum API your APK will support.
#android.minapi = 21

# (int) Android SDK version to use
#android.sdk = 20

# (str) Android NDK version to use
#android.ndk = 19b

# (int) Android NDK API to use. This is the minimum API your app will support, it should usually match android.minapi.
#android.ndk_api = 21

# (bool) Use --private data storage (True) or --dir public storage (False)
#android.private_storage = True

# (str) Android NDK directory (if empty, it will be automatically downloaded.)
#android.ndk_path =

# (str) Android SDK directory (if empty, it will be automatically downloaded.)
#android.sdk_path =

# (str) ANT directory (if empty, it will be automatically downloaded.)
#android.ant_path =

# (bool) If True, then skip trying to update the Android sdk
# This can be useful to avoid excess Internet downloads or save time
# when an update is due and you just want to test/build your package
# android.skip_update = False

# (bool) If True, then automatically accept SDK license
# agreements. This is intended for automation only. If set to False,
# the default, you will be shown the license when first running
# buildozer.
# android.accept_sdk_license = False

# (str) Android entry point, default is ok for Kivy-based app
#android.entrypoint = org.renpy.android.PythonActivity

# (str) Android app theme, default is ok for Kivy-based app
# android.apptheme = "@android:style/Theme.NoTitleBar"

# (list) Pattern to whitelist for the whole project
#android.whitelist =

# (str) Path to a custom whitelist file
#android.whitelist_src =

# (str) Path to a custom blacklist file
#android.blacklist_src =

# (list) List of Java .jar files to add to the libs so that pyjnius can access
# their classes. Don't add jars that you do not need, since extra jars can slow
# down the build process. Allows wildcards matching, for example:
# OUYA-ODK/libs/*.jar
#android.add_jars = foo.jar,bar.jar,path/to/more/*.jar

# (list) List of Java files to add to the android project (can be java or a
# directory containing the files)
#android.add_src =

# (list) Android AAR archives to add (currently works only with sdl2_gradle
# bootstrap)
#android.add_aars =

# (list) Gradle dependencies to add (currently works only with sdl2_gradle
# bootstrap)
#android.gradle_dependencies =

# (list) add java compile options
# this can for example be necessary when importing certain java libraries using the 'android.gradle_dependencies' option
# see https://developer.android.com/studio/write/java8-support for further information
# android.add_compile_options = "sourceCompatibility = 1.8", "targetCompatibility = 1.8"

# (list) Gradle repositories to add {can be necessary for some android.gradle_dependencies}
# please enclose in double quotes 
# e.g. android.gradle_repositories = "maven { url 'https://kotlin.bintray.com/ktor' }"
#android.add_gradle_repositories =

# (list) packaging options to add 
# see https://google.github.io/android-gradle-dsl/current/com.android.build.gradle.internal.dsl.PackagingOptions.html
# can be necessary to solve conflicts in gradle_dependencies
# please enclose in double quotes 
# e.g. android.add_packaging_options = "exclude 'META-INF/common.kotlin_module'", "exclude 'META-INF/*.kotlin_module'"
#android.add_gradle_repositories =

# (list) Java classes to add as activities to the manifest.
#android.add_activities = com.example.ExampleActivity

# (str) OUYA Console category. Should be one of GAME or APP
# If you leave this blank, OUYA support will not be enabled
#android.ouya.category = GAME

# (str) Filename of OUYA Console icon. It must be a 732x412 png image.
#android.ouya.icon.filename = %(source.dir)s/data/ouya_icon.png

# (str) XML file to include as an intent filters in <activity> tag
#android.manifest.intent_filters =

# (str) launchMode to set for the main activity
#android.manifest.launch_mode = standard

# (list) Android additional libraries to copy into libs/armeabi
#android.add_libs_armeabi = libs/android/*.so
#android.add_libs_armeabi_v7a = libs/android-v7/*.so
#android.add_libs_arm64_v8a = libs/android-v8/*.so
#android.add_libs_x86 = libs/android-x86/*.so
#android.add_libs_mips = libs/android-mips/*.so

# (bool) Indicate whether the screen should stay on
# Don't forget to add the WAKE_LOCK permission if you set this to True
#android.wakelock = False

# (list) Android application meta-data to set (key=value format)
#android.meta_data =

# (list) Android library project to add (will be added in the
# project.properties automatically.)
#android.library_references =

# (list) Android shared libraries which will be added to AndroidManifest.xml using <uses-library> tag
#android.uses_library =

# (str) Android logcat filters to use
android.logcat_filters = *:S python:D

# (bool) Copy library instead of making a libpymodules.so
#android.copy_libs = 1

# (str) The Android arch to build for, choices: armeabi-v7a, arm64-v8a, x86, x86_64
android.arch = armeabi-v7a

# (int) overrides automatic versionCode computation (used in build.gradle)
# this is not the same as app version and should only be edited if you know what you're doing
# android.numeric_version = 1

#
# Python for android (p4a) specific
#

# (str) python-for-android fork to use, defaults to upstream (kivy)
#p4a.fork = kivy

# (str) python-for-android branch to use, defaults to master
#p4a.branch = master

# (str) python-for-android git clone directory (if empty, it will be automatically cloned from github)
#p4a.source_dir =

# (str) The directory in which python-for-android should look for your own build recipes (if any)
#p4a.local_recipes =

# (str) Filename to the hook for p4a
#p4a.hook =

# (str) Bootstrap to use for android builds
# p4a.bootstrap = sdl2

# (int) port number to specify an explicit --port= p4a argument (eg for bootstrap flask)
#p4a.port =


#
# iOS specific
#

# (str) Path to a custom kivy-ios folder
#ios.kivy_ios_dir = ../kivy-ios
# Alternately, specify the URL and branch of a git checkout:
ios.kivy_ios_url = https://github.com/kivy/kivy-ios
ios.kivy_ios_branch = master

# Another platform dependency: ios-deploy
# Uncomment to use a custom checkout
#ios.ios_deploy_dir = ../ios_deploy
# Or specify URL and branch
ios.ios_deploy_url = https://github.com/phonegap/ios-deploy
ios.ios_deploy_branch = 1.7.0

# (str) Name of the certificate to use for signing the debug version
# Get a list of available identities: buildozer ios list_identities
#ios.codesign.debug = "iPhone Developer: <lastname> <firstname> (<hexstring>)"

# (str) Name of the certificate to use for signing the release version
#ios.codesign.release = %(ios.codesign.debug)s


[buildozer]

# (int) Log level (0 = error only, 1 = info, 2 = debug (with command output))
log_level = 2

# (int) Display warning if buildozer is run as root (0 = False, 1 = True)
warn_on_root = 1

# (str) Path to build artifact storage, absolute or relative to spec file
# build_dir = ./.buildozer

# (str) Path to build output (i.e. .apk, .ipa) storage
# bin_dir = ./bin

#    -----------------------------------------------------------------------------
#    List as sections
#
#    You can define all the "list" as [section:key].
#    Each line will be considered as a option to the list.
#    Let's take [app] / source.exclude_patterns.
#    Instead of doing:
#
#[app]
#source.exclude_patterns = license,data/audio/*.wav,data/images/original/*
#
#    This can be translated into:
#
#[app:source.exclude_patterns]
#license
#data/audio/*.wav
#data/images/original/*
#


#    -----------------------------------------------------------------------------
#    Profiles
#
#    You can extend section / key with a profile
#    For example, you want to deploy a demo version of your application without
#    HD content. You could first change the title to add "(demo)" in the name
#    and extend the excluded directories to remove the HD content.
#
#[app@demo]
#title = My Application (demo)
#
#[app:source.exclude_patterns@demo]
#images/hd/*
#
#    Then, invoke the command line with the "demo" profile:
#
#buildozer --profile demo android debug

正如我所说,在将此逻辑添加到我的应用程序后,我的应用程序不断崩溃,以下是我使用logcat颜色时的错误:

 python  I  Traceback (most recent call last):
05-08 18:38:45.284   5207     5233                 python  I  File "/content/.buildozer/android/app/main.py", line 25, in <module>
05-08 18:38:45.284   5207     5233                 python  I  File "/content/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/
                                                            myapp/jnius/reflect.py", line 208, in autoclass
05-08 18:38:45.285   5207     5233                 python  I  File "jnius/jnius_export_func.pxi", line 28, in jnius.jnius.find_javaclass
05-08 18:38:45.285   5207     5233                 python  I  jnius.jnius.JavaException: Class not found b'org/kivy/myapp/ServiceMyservice'
05-08 18:38:45.285   5207     5233                 python  I  Python for android ended.

我的应用程序以前运行过,但现在我想要一个附加功能,也就是在后台运行它。如果有人能帮忙,我会非常感激的

提前谢谢


Tags: ofthetoinfrombuildaddfor
1条回答
网友
1楼 · 发布于 2024-04-25 23:30:52

我认为这是因为您没有更新main.py中服务声明中的包名,应该是

SERVICE_NAME = u'{packagename}.Service{servicename}'.format(
    packagename=u'org.test.myapp',
    servicename=u'Myservice'
)

因为您在buildozer.spec中将应用程序域声明为org.test

相关问题 更多 >