diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..25e1180
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+**.pyc
+.vagrant/**
diff --git a/android.txt b/android.txt
new file mode 100644
index 0000000..da1c648
--- /dev/null
+++ b/android.txt
@@ -0,0 +1,3 @@
+title=Kivy Remote Shell
+author=tito
+orientation=portrait
diff --git a/libs/garden/garden.navigationdrawer/__init__.pyc b/libs/garden/garden.navigationdrawer/__init__.pyc
index 1ba01f1..ed96d26 100644
Binary files a/libs/garden/garden.navigationdrawer/__init__.pyc and b/libs/garden/garden.navigationdrawer/__init__.pyc differ
diff --git a/main.py b/main.py
index b7c3798..fa2c79b 100644
--- a/main.py
+++ b/main.py
@@ -1,44 +1,42 @@
 __version__ = '0.1'
 
 # install_twisted_rector must be called before importing  and using the reactor
-from kivy.support import install_twisted_reactor
-install_twisted_reactor()
+#from kivy.support import install_twisted_reactor
+#install_twisted_reactor()
 
 import socket
 import fcntl
 import struct
-from twisted.internet import reactor
-from twisted.cred import portal, checkers
-from twisted.conch import manhole, manhole_ssh
 from kivy.lang import Builder
 from kivy.uix.floatlayout import FloatLayout
-from kivy.properties import StringProperty
+from kivy.properties import StringProperty, BooleanProperty
 from kivy.app import App
+from kivy.clock import Clock
+import kivy
+kivy.require('1.8.0')
 
 from kivy.garden import navigationdrawer
 from kivy.uix.screenmanager import Screen
-app = None
 
+from service import ServiceAppMixin
+import shell
+
+app = None
 
-def getManholeFactory(namespace, **passwords):
-    realm = manhole_ssh.TerminalRealm()
-    def getManhole(_):
-        return manhole.ColoredManhole(namespace)
-    realm.chainedProtocolFactory.protocolFactory = getManhole
-    p = portal.Portal(realm)
-    p.registerChecker(
-        checkers.InMemoryUsernamePasswordDatabaseDontUse(**passwords))
-    f = manhole_ssh.ConchFactory(p)
-    return f
 
 
 class MainScreen(Screen):
     lan_ip = StringProperty('127.0.0.1')
+    use_service = BooleanProperty()
 
     def __init__(self, **kwargs):
         super(MainScreen, self).__init__(**kwargs)
 
-        ip = socket.gethostbyname(socket.gethostname())
+        try:
+            ip = socket.gethostbyname(socket.gethostname())
+        except socket.gaierror:
+            ip = socket.gethostbyname(socket.gethostname() + '.local')
+
         if ip.startswith('127.'):
             interfaces = ['eth0', 'eth1', 'eth2', 'wlan0', 'wlan1', 'wifi0',
                     'tiwlan0', 'tiwlan1', 'ath0', 'ath1', 'ppp0']
@@ -58,16 +56,37 @@ def get_interface_ip(self, ifname):
                 struct.pack('256s', ifname[:15])
             )[20:24])
 
+    def on_use_service(self, instance, value):
+        app.start_shell(service=value)
+
 
-class RemoteKivyApp(App):
+class RemoteKivyApp(App, ServiceAppMixin):
     def build(self):
         global app
         app = self
-        self.connection = reactor.listenTCP(8000,
-                getManholeFactory(globals(), admin='kivy'))
 
     def on_pause(self):
         return True
 
+    def on_resume(self):
+        return
+
+    def on_stop(self):
+        if hasattr(self, 'service'):
+            self.stop_service()
+
+    def start_shell(self, service=False):
+        if service: # For now on, use the Service!
+            if hasattr(self, '_twisted_connection'):
+                shell.uninstall_shell(service=False, connections=[self._twisted_connection])
+                del self._twisted_connection
+            self.start_service()
+
+        else: # For now on, use the Activity!
+            if hasattr(self, 'service'):
+                self.stop_service()
+            self._twisted_connection = shell.install_shell(context=globals(), service=False)
+
+
 if __name__ == '__main__':
     RemoteKivyApp().run()
diff --git a/service/__init__.py b/service/__init__.py
new file mode 100644
index 0000000..bbb898f
--- /dev/null
+++ b/service/__init__.py
@@ -0,0 +1,37 @@
+import kivy.utils
+from kivy import platform as PLATFORM
+
+try: # hack for Kivy pre-1.8
+    PLATFORM = PLATFORM()
+except TypeError:
+    pass
+
+if PLATFORM == 'android':
+    import android
+else:
+    android = None
+
+class ServiceAppMixin(object):
+    def start_service(self, arg=''):
+        if PLATFORM == 'android':
+            self.service = android.AndroidService(title='Kivy Remote Shell', description='Twisted reactor running')
+            self.service.start(arg) # accepts an argument, handled to PYTHON_SERVICE_ARGUMENT
+            return True
+        else:
+            from multiprocessing import Process
+            def _run_service(arg=arg):
+                import os
+                os.environ['PYTHON_SERVICE_ARGUMENT'] = arg
+                import service.main
+            self.service = Process(target=_run_service)
+            self.service.start()
+        return False
+
+    def stop_service(self):
+        if PLATFORM == 'android':
+            self.service.stop()
+            return True
+        else:
+            import os, signal
+            os.kill(self.service.pid, signal.SIGKILL)
+        return False
diff --git a/service/main.py b/service/main.py
new file mode 100644
index 0000000..80e6f2d
--- /dev/null
+++ b/service/main.py
@@ -0,0 +1,10 @@
+import os
+# Hack to allow import from main app dir:
+_parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+os.sys.path.insert(0, _parentdir)
+
+# get the argument passed
+arg = os.getenv('PYTHON_SERVICE_ARGUMENT')
+
+import shell
+shell.install_shell(context=globals(), service=True)
diff --git a/shell.py b/shell.py
new file mode 100644
index 0000000..aaee0c1
--- /dev/null
+++ b/shell.py
@@ -0,0 +1,85 @@
+#coding: utf-8
+from threading import Lock
+from kivy.logger import Logger
+
+INSTALL_SHELL_LOCK = Lock()
+
+
+def _block_on(d, timeout=None):
+    '''Blocks waiting for a deferred to return something, or fail'''
+    from Queue import Queue, Empty
+    from twisted.python.failure import Failure
+
+    q = Queue()
+    d.addBoth(q.put)
+    try:
+        ret = q.get(True, timeout)
+    except Empty:
+        raise Empty
+    if isinstance(ret, Failure):
+        ret.raiseException()
+    else:
+        return ret
+
+
+def getManholeFactory(namespace, **passwords):
+    from twisted.cred import portal, checkers
+    from twisted.conch import manhole, manhole_ssh
+
+    realm = manhole_ssh.TerminalRealm()
+    def getManhole(_):
+        return manhole.ColoredManhole(namespace)
+    realm.chainedProtocolFactory.protocolFactory = getManhole
+    p = portal.Portal(realm)
+    p.registerChecker(
+        checkers.InMemoryUsernamePasswordDatabaseDontUse(**passwords))
+    f = manhole_ssh.ConchFactory(p)
+    return f
+
+
+def install_shell(context={}, service=False):
+    with INSTALL_SHELL_LOCK:
+        if service:
+            from twisted.internet import default
+            default.install()
+        else:
+            # install_twisted_rector must be called before importing  and using the reactor
+            from kivy.support import install_twisted_reactor
+            install_twisted_reactor()
+
+        from twisted.internet import reactor
+
+        Logger.debug('Shell: Creating twisted reactor. Service: %s', service)
+        connection = reactor.listenTCP(8000,
+            getManholeFactory(context, admin='kivy')
+        )
+
+        if service:
+            # service-based have no implicit reactor running.
+            Logger.debug('Shell: Twisted reactor starting')
+            reactor.run()
+            Logger.debug('Shell: Twisted reactor stopped')
+        else:
+            return connection
+
+def uninstall_shell(service=False, connections=[]):
+    if service:
+        raise NotImplementedError()
+
+    defers = []
+    for c in connections:
+        defers.append(c.stopListening())
+
+    from Queue import Empty
+    import kivy.support
+    while True:
+        kivy.support._twisted_reactor_work()
+        try:
+            for d in defers:
+                _block_on(d, timeout=1)
+        except Empty:
+            continue
+        break
+
+    from kivy.support import uninstall_twisted_reactor
+    uninstall_twisted_reactor()