Kivy service app dont send any data to mysql when screen is off
Trying write simple app with kivy python which should run the service when you press the button.
Service must track gps location (using plyer) and sending Name (from label) Lat Lon (from on_gps_location) and date from var datetime to mysql db. Its actualy working pretty well when you using app or switched it to another app. But when u turning off phone screen service dont stop cause i see the notification about service is running but no one new data dont sending anymore.
Note: im testing it with difference phones, its actually working on any phones but not on my (HONOR 30i)
Note2: When u select "traffic stat" on your phone it calls that your app spent for example 30mb when u using app and 0mb in background.
There my main.py code:
from kivy.app import App
from kivy.uix.button import Button
from kivy.config import Config
from plyer import gps
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.anchorlayout import AnchorLayout
import mysql.connector
import android
from mysql.connector import errorcode
from datetime import datetime
from kivy.utils import platform
from kivy.clock import Clock
import time
from jnius import autoclass
from android import AndroidService
from kivy.storage.jsonstore import JsonStore
from threading import Thread
store = JsonStore('hello.json')
class MyApp(App):
def request_android_permissions(self):
from android.permissions import request_permissions, Permission
def callback(permissions, results):
if all([res for res in results]):
print('callback. All permissions granted.')
else:
print('callback. Some permissions refused.')
request_permissions([Permission.ACCESS_COARSE_LOCATION, Permission.ACCESS_FINE_LOCATION, Permission.ACCESS_BACKGROUND_LOCATION, Permission.WRITE_EXTERNAL_STORAGE], callback)
def build(self):
if platform == 'android':
print('Requesting permissions')
self.request_android_permissions()
print('App is running')
if len(store) == 0:
al = AnchorLayout()
bl = BoxLayout(orientation = 'vertical', size_hint=[None,None], size = [500,300])
self.lbl1 = Label(text = 'Put your name here')
bl.add_widget(self.lbl1)
self.txt1 = TextInput(text = '', multiline = False)
bl.add_widget(self.txt1)
bl.add_widget(Button(text = 'Start', on_press = self.btn_press_start))
al.add_widget(bl)
return al
else:
al = AnchorLayout()
bl = BoxLayout(orientation = 'vertical', size_hint = [None, None], size = [500,300])
self.lbl1 = Label(text = 'Hello ' + store.get('Name')['name'])
bl.add_widget(self.lbl1)
bl.add_widget(Button(text = 'Start', on_press = self.btn_press_start))
al.add_widget(bl)
return al
def btn_press_start(self, instance):
global name
if len(store) == 0:
if instance.text == 'Start':
if self.txt1.text != '':
self.lbl1.text = 'Hello ' + self.txt1.text
store.put('Name', name = self.txt1.text)
print('Beggin')
name = self.txt1.text
self.start_service()
instance.text = 'Stop'
else:
self.lbl1.text = 'Write smth there!'
else:
#gps.stop()
self.service.stop()
print('Service stop')
self.txt1.text = ''
instance.text = 'Start'
else:
if instance.text == 'Start':
name = store.get('Name')['name']
self.start_service()
instance.text = 'Stop'
else:
self.service.stop()
print('Service stop')
instance.text = 'Start'
def start_service(self):
self.service = AndroidService('Service example', 'service is running')
self.service.start(name)
if name == "main":
MyApp().run()
and my service/main.py code:
import os
from os import environ
from kivy.app import App
from kivy.uix.button import Button
from kivy.config import Config
from plyer import gps
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.anchorlayout import AnchorLayout
import mysql.connector
import android
from mysql.connector import errorcode
from datetime import datetime
from kivy.utils import platform
from kivy.clock import Clock
import time
from jnius import autoclass
from android import AndroidService
print('SERVICE ON')
arg = environ.get('PYTHON_SERVICE_ARGUMENT', '')
def main():
gps.configure(on_location = on_gps_location)
print('Configure succes')
gps.start(minTime = 2000, minDistance = 0)
print('Going on')
time.sleep(10)
gps.stop()
print('BEFORE REPEAT')
config = {
'user': '', //I CLEAR THIS FIELDS//
'password': '',
'host': '',
'database': '',
'raise_on_warnings': True
}
db = mysql.connector.connect(**config)
cursor = db.cursor()
cur_time = datetime.now()
now = cur_time.strftime("%Y-%m-%d %H:%M:%S")
data_coord = {
'name' : arg,
'c1' : lat,
'c2' : lon,
'time': now,
}
add_coordinate = ("INSERT INTO //YOURDATABASE// (Name, Latitude, Longtitude, Date) VALUES (%(name)s, %(c1)s, %(c2)s, %(time)s)")
cursor.execute(add_coordinate, data_coord)
print('DATABASE UPDATE')
db.commit()
db.close()
def on_gps_location(**kwargs):
global lat
global lon
lat = kwargs['lat']
lon = kwargs['lon']
if __name__ == '__main__':
while True:
main()
time.sleep(20)
Related
from multiprocessing.sharedctypes import Value
from pytube import YouTube
import kivy from kivy.app
import App from kivy.uix.label
import Label from kivy.uix.gridlayout
import GridLayout from kivy.uix.button
import Button from kivy.uix.textinput import TextInput
import threading
class grid_layout (GridLayout):
def __init__(self, **kwargs):
super().__init__( **kwargs)
self.tx1 = TextInput(text = 'Enter A Youtube Link',size_hint = (0.8,0.9) , pos = (400,500),size = (500,100))
self.add_widget(self.tx1)
self.bt2 = Button(text = "Exit ",font_size = '20sp',bold = True, size_hint = (0.6,0.6),pos = (600,200))
self.add_widget(self.bt2)
self.bt1 = Button(text = 'Download',font_size = '20sp',
bold = True,
italic = True,size_hint = (0.6,0.6) ,
pos = (400,200),on_press = self.download
)
self.add_widget(self.bt1)
def download(self,obj):
link = str(self.tx1.text)
download = YouTube(link)
print('Processing The Video.Please Wait Depends Upon Size And Your Net Speed Download Depends')
task = download.streams.filter(res = '360p',file_extension='mp4')
started = download.streams.get_by_itag(22)
started.download()
print('Download Completed') class MyApp(App):
def build (self):
return grid_layout()
if __name__ == '__main__':
MyApp().run()
Hello guys i have this minimal code where the issue is generated:
from kivy.lang import Builder
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.widget import Widget
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
Builder.load_file('the.kv')
def start_service():
from kivy import platform
if platform == "android":
from android import mActivity
from jnius import autoclass
service = autoclass("org.pck.my_app.ServiceMyservice_5")
mActivity = autoclass("org.kivy.android.PythonActivity").mActivity
service.start(mActivity, "")
print('starting service')
start_service()
class fscreen(Widget):
def __init__(self, **kwargs):
super().__init__(**kwargs)
class theapp(App):
def build(self):
self.screenm = ScreenManager()
self.fscreen = fscreen()
screen = Screen(name = "first screen")
screen.add_widget(self.fscreen)
self.screenm.add_widget(screen)
return self.screenm
theapp().run()
And i have this service.py:
import time
from jnius import autoclass
from plyer import notification
PythonService = autoclass('org.kivy.android.PythonService')
PythonService.mService.setAutoRestartService(True)
cnt = 0
while True:
time.sleep(1)
cnt += 1
print('service has been running for ' + str(cnt))
And a small widget in the.kv file:
<fscreen>
Label:
text: 'Test for Service'
font_size: root.height*0.05
pos: root.width*0.3, root.height*0.5
size: root.width*0.4, root.height*0.1
this a screen after the buildozer deploy:
and this a screen for the foreground from top slide:
and last a black screen:
Please I have created a kivymd app and it's running well on my android device. The app reads the names from a txt file, randomise them and group them into preferred number of groups. It works fine but I want to add functionality that users can add their own txt file into a folder created by the app after installation so that the app will read the txt file from the root folder.
Now I need a way that the app can create the folder by itself after installation. And also how the app can read txt files from that folder for the grouping.
Thanks in advance
import random
import kivymd
from kivy.animation import Animation
from kivy.app import App
from kivy.factory import Factory
from kivy.graphics.context import Clock
from kivy.uix.popup import Popup
from kivy.uix.scrollview import ScrollView
from kivy.utils import get_color_from_hex
from kivymd.app import MDApp
from kivy.properties import StringProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.core.window import Window
from kivy.lang.builder import Builder
from kivy.properties import NumericProperty
from kivy.uix.screenmanager import Screen
from kivymd.uix.card import MDCard
from kivymd.uix.label import MDLabel
from kivymd.uix.list import OneLineListItem
Window.fullscreen = True
Window.maximize()
class CardOn(MDCard):
pass
class ListItems(OneLineListItem):
text = StringProperty()
class ContentNavigationDrawer(BoxLayout):
pass
class NavigationDrawerIconButton(BoxLayout):
pass
class NavigationLayout(Screen):
state = ''
my_text = "No names loaded yet"
convert_to_string = "No names loaded yet"
raw_file = open("Name.txt", "r")
read_content = raw_file.read()
class_split = read_content.split("\n")
num_of_generated_groups = StringProperty()
Shuffled_list = []
grouping_critera = StringProperty()
student_total = 0
Groups = NumericProperty(1)
hint = StringProperty()
Randomized_list = []
Created_groups = []
refined_group = StringProperty(""" """)
students_to_string = StringProperty("No names loaded yet")
my_index = NumericProperty
new_titles = StringProperty()
def group_criteria(self, value):
self.grouping_critera = value
if self.grouping_critera == "Number of groups":
self.hint = "Select desired number of groups"
elif self.grouping_critera == "Number of groups":
self.grouping_critera = "Number of groups"
else:
self.hint = "Select desired students per groups"
print(self.grouping_critera)
def group_nums(self, value):
self.Groups = int(value)
print(self.Groups)
def read_names(self):
raw_file = open("Name.txt", "r")
read_content = raw_file.read()
self.class_split = read_content.split("\n")
def create_groups(self):
self.student_total = len(self.class_split)
self.Shuffled_list = self.class_split
random.shuffle(self.Shuffled_list)
self.Groups = int(self.Groups)
if self.grouping_critera == "Number of groups":
groups_to_students = round(self.student_total / self.Groups)
self.Created_groups = [self.Shuffled_list[i * groups_to_students:(i + 1) * groups_to_students] for i in
range((len(self.Shuffled_list) + groups_to_students - 1) // groups_to_students)]
else:
self.Created_groups = [self.Shuffled_list[i * self.Groups:(i + 1) * self.Groups] for i in
range((len(self.Shuffled_list) + self.Groups - 1) // self.Groups)]
print(f"Created groups are {self.Created_groups}")
for self.i in self.Created_groups:
card = MDCard(orientation="vertical", padding="8dp", size_hint=(None, None),
size=(self.width, "10dp"),
pos_hint={"center_x": .5, "center_y": .5})
self.ids.md_list.add_widget(card)
self.num_of_generated_groups = f"{len(self.Created_groups)} Groups Generated"
self.my_index = self.Created_groups.index(self.i) + 1 # the 1 will replace the index at 0
label = MDLabel(text=f"Group {self.my_index} members = {len(self.i)} ", theme_text_color="Custom",
text_color=(1, 1, 1, 1), halign="center", font_size=30)
self.ids.md_list.add_widget(label)
for e in self.i:
self.ids.md_list.add_widget(ListItems(text=e))
def clear_screen(self):
self.ids.md_list.clear_widgets()
def generate_groups(self):
self.clear_screen()
self.create_groups()
class GroupingApp(MDApp):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.screen = Builder.load_string(screen_helper)
def build(self):
return self.screen
if __name__ == '__main__':
GroupingApp().run()
I made a basic app, which returns objects from collections in mongodb by clicking buttons and printing it out onto the screen. I just want to ask how it works using mobile. Is this code enough or will I have to do something else, for example make an api. I am using mongodb cluster on which I have database called "mycak" and collection "udaje". Can I compile it now through buildozer?
here is how it looks
heres my main.py:
import kivy
import pymongo
from pymongo import MongoClient
import datetime
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty
from kivy.uix.screenmanager import ScreenManager,Screen
from kivy.uix.button import ButtonBehavior
from kivy.uix.image import Image
from kivy.uix.label import Label
from kivy.uix.popup import Popup
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
from kivy.lang import Builder
from kivy.uix.scrollview import ScrollView
from kivy.properties import StringProperty
import string
class Second(Screen):
text = StringProperty ('')
listReminders = ObjectProperty()
def ukaz_vse(self):
cluster = MongoClient (
"mongodb+srv://root:HonzaKupka1818*#cluster0-urwfe.mongodb.net/test?retryWrites=true&w=majority")
db = cluster["mycak"]
collection = db["udaje"]
result = collection.find()
resultvse = ""
for x in enumerate(result):
resultvse += str(x) + "\n"
self.listReminders.text = str(resultvse)
class Manager(ScreenManager):
pass
class Start(Screen):
user = ObjectProperty()
def zapsat(self):
cluster = MongoClient (
"mongodb+srv://root:HonzaKupka1818*#cluster0-urwfe.mongodb.net/test?retryWrites=true&w=majority")
db = cluster["mycak"]
collection = db["udaje"]
mongo_query2 = (self.user.text)
mongo_query3 = (datetime.datetime.utcnow())
collection.insert_many(
[{"jmeno":mongo_query2,"date":mongo_query3 }
]
)
def ukaz(self):
cluster = MongoClient (
"mongodb+srv://root:HonzaKupka1818*#cluster0-urwfe.mongodb.net/test?retryWrites=true&w=majority")
db = cluster["mycak"]
collection = db["udaje"]
results = collection.find()
results1 = collection.find().sort([('_id', -1)]).limit(2)
for result in results:
more = result["jmeno"]
more1= result["date"]
self.ids.labelfetchname.text=str(more)
self.ids.labelfetchdate.text = str(more1)
for result in results1:
more = result["jmeno"]
more1 = result["date"]
self.ids.labelfetchname1.text = str(more)
self.ids.labelfetchdate1.text = str(more1)
class Main(App):
cluster = MongoClient (
"mongodb+srv://root:HonzaKupka1818*#cluster0-urwfe.mongodb.net/test?retryWrites=true&w=majority")
db = cluster["mycak"]
collection = db["udaje"]
if __name__ == "__main__":
Main().run()
I'd like to display numeric values coming from a sensor (Tinkerforge ambient light sensor) in Kivy widgets. Unfortunately the variable 'illuminance' doesn't seem to change at all and the widgets display '0'.'illuminance' seems to update nicely and gets printed on the console. What am I doing wrong?
import kivy
import random
from kivy.clock import Clock
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from tinkerforge.ip_connection import IPConnection
from tinkerforge.brick_dc import BrickDC
from tinkerforge.bricklet_ambient_light import BrickletAmbientLight
HOST = "localhost" # Tinkerforge IP and port
PORT = 4223
UID = "uM9" # sensor ID
illuminance = 0
ipcon = IPConnection() # Create IP connection
al = BrickletAmbientLight(UID, ipcon) # Create device object
ipcon.connect(HOST, PORT) # Connect to brickd
class TimerTink:
def tinker(self):
illuminance = al.get_illuminance() #read sensor value
print(illuminance)
class TinkerApp(App):
def build(self):
main_layout = BoxLayout(padding=10, orientation="vertical")
for i in range(2):
h_layout = BoxLayout(padding=10)
for i in range(2):
lbl = Label(text=str(illuminance),)
h_layout.add_widget(lbl)
main_layout.add_widget(h_layout)
event = Clock.schedule_interval(TimerTink.tinker, 1/2)
return main_layout
if __name__ == "__main__":
app = TinkerApp()
app.run()
Finally it's working, thanks to #YOSHI 's suggestions:
import kivy
import random
from kivy.clock import Clock
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.floatlayout import FloatLayout
from tinkerforge.ip_connection import IPConnection
from tinkerforge.brick_dc import BrickDC
from tinkerforge.bricklet_ambient_light import BrickletAmbientLight
HOST = "localhost" # Tinkerforge IP and port
PORT = 4223
UID = "uM9" # sensor ID
illuminance = 0
ipcon = IPConnection() # Create IP connection
al = BrickletAmbientLight(UID, ipcon) # Create device object
ipcon.connect(HOST, PORT) # Connect to brickd
class TinkerApp(App):
def build(self):
i = 0
main_layout = BoxLayout(padding=10, orientation="vertical")
h_layout = FloatLayout(size=(300,300))
self.label = Label(text=str(illuminance),pos=(i*100, i*100),size_hint = (.1,.1))
h_layout.add_widget(self.label)
main_layout.add_widget(h_layout)
Clock.schedule_interval(self.timer, 0.1)
return main_layout
def timer(self, dt):
illuminance = al.get_illuminance() #read sensor value
self.label.text = str(illuminance)
print(str(illuminance))
if __name__ == "__main__":
app = TinkerApp()
app.run()
The function 'tinker' in the TimeTink class takes 2 arguments: self and dt
def tinker(self,dt):
illuminance = al.get_illuminance() #read sensor value
print(illuminance)
or you change the line where you call the method to sth. like this:
event = Clock.schedule_interval(lambda dt: TimerTink.tinker, 1/2)
for more info visit the doc for kivy.clock.
Edit: (maybe this works)
import kivy
import random
from kivy.clock import Clock
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from tinkerforge.ip_connection import IPConnection
from tinkerforge.brick_dc import BrickDC
from tinkerforge.bricklet_ambient_light import BrickletAmbientLight
HOST = "localhost" # Tinkerforge IP and port
PORT = 4223
UID = "uM9" # sensor ID
illuminance = 0
ipcon = IPConnection() # Create IP connection
al = BrickletAmbientLight(UID, ipcon) # Create device object
ipcon.connect(HOST, PORT) # Connect to brickd
main_layout = BoxLayout(padding=10, orientation="vertical")
for i in range(2):
h_layout = BoxLayout(padding=10)
for i in range(2):
lbl = Label(text=str(illuminance),)
h_layout.add_widget(lbl)
main_layout.add_widget(h_layout)
def tinker(self):
illuminance = al.get_illuminance() #read sensor value
lbl.text = str(illuminance)
print(illuminance)
class TinkerApp(App):
def build(self):
event = Clock.schedule_interval(tinker, 1/2)
return main_layout
if __name__ == "__main__":
app = TinkerApp()
app.run()