from kivy.app import App
from kivy.clock import Clock
from kivy.lang import Builder
from kivy.properties import StringProperty
from kivy.uix.boxlayout import BoxLayout

from plyer import speech

Builder.load_string('''
<SpeechInterface>:
    orientation: 'vertical'
    Label:
        size_hint_y: None
        height: sp(40)
        text: 'Is supported: %s' % root.speech.exist()
    Label:
        size_hint_y: None
        height: sp(40)
        text: 'Possible Matches'
    Label:
        id: results
        size_hint_y: 0.7
        height: sp(40)
        text: ''
    Button:
        id: start_button
        text: 'Start Listening'
        on_release:
            root.start_listening()

''')


class SpeechInterface(BoxLayout):
    '''Root Widget.'''

    speech = speech
    state = StringProperty()

    def start_listening(self):
        if self.speech.state == 'listening':
            self.stop_listening()
            return

        start_button = self.ids['start_button']
        start_button.text = 'Stop'

        label_results = self.ids['results']
        label_results.text = ''

        self.speech.start()
        self.state = self.speech.state

        Clock.schedule_interval(self.check_state, 1/5)

    def stop_listening(self):
        start_button = self.ids['start_button']
        start_button.text = 'Start Listening'

        self.speech.stop()
        self.update()

        Clock.unschedule(self.check_state)

    def check_state(self, dt):
        if self.state != self.speech.state:
            self.stop_listening()

    def update(self):
        label_results = self.ids['results']
        label_results.text = '\n'.join(set(self.speech.results))


class SpeechApp(App):

    def build(self):
        return SpeechInterface()

    def on_pause(self):
        return True


if __name__ == "__main__":
    SpeechApp().run()

@@ -212,16 +212,46 @@
 ing('''%0A
+#:import speech plyer.speech%0A%0A
 %3CSpeechI
@@ -384,21 +384,16 @@
 : %25s' %25 
-root.
 speech.e
@@ -492,29 +492,33 @@
 atches'%0A    
-Label
+TextInput
 :%0A        id
@@ -539,64 +539,259 @@
     
-size_hint_y: 0.7%0A        height: sp(40)%0A        text: ''
+hint_text: 'results (auto stop)'%0A        size_hint_y: 0.3%0A    TextInput:%0A        id: partial%0A        hint_text: 'partial results (manual stop)'%0A        size_hint_y: 0.3%0A    TextInput:%0A        id: errors%0A        size_hint_y: None%0A        height: sp(20)
 %0A   
@@ -981,58 +981,8 @@
 ''%0A%0A
-    speech = speech%0A    state = StringProperty()%0A%0A
     
@@ -1023,30 +1023,15 @@
  if 
-self.
 speech.
-state == '
 list
@@ -1035,17 +1035,16 @@
 istening
-'
 :%0A      
@@ -1114,34 +1114,33 @@
 utton = self.ids
-%5B'
+.
 start_button'%5D%0A 
@@ -1127,34 +1127,32 @@
 ids.start_button
-'%5D
 %0A        start_b
@@ -1184,58 +1184,17 @@
     
-label_results = self.ids%5B'results'%5D%0A        label_
+self.ids.
 resu
@@ -1207,17 +1207,16 @@
 xt = ''%0A
-%0A
         
@@ -1224,49 +1224,39 @@
 elf.
-speech.start()%0A        self.state = self.
+ids.partial.text = ''%0A%0A        
 spee
@@ -1261,18 +1261,20 @@
 eech.sta
-te
+rt()
 %0A%0A      
@@ -1384,18 +1384,17 @@
 self.ids
-%5B'
+.
 start_bu
@@ -1397,18 +1397,16 @@
 t_button
-'%5D
 %0A       
@@ -1453,21 +1453,16 @@
         
-self.
 speech.s
@@ -1576,43 +1576,85 @@
     
+ #
  if 
-self.state != self.speech.state
+the recognizer service stops, change UI%0A        if not speech.listening
 :%0A  
@@ -1720,43 +1720,65 @@
     
-label_results = self.ids%5B'
+self.ids.partial.text = '%5Cn'.join(speech.partial_
 results
-'%5D
+)
 %0A   
@@ -1786,14 +1786,17 @@
     
-label_
+self.ids.
 resu
@@ -1820,17 +1820,8 @@
 oin(
-set(self.
 spee
@@ -1831,17 +1831,16 @@
 results)
-)
 %0A%0A%0Aclass

Improve example, add fields for partials and errors