siri for android, android
Homemade
Siri for Android using SL4A
A video is
better than a thousand words.
First the demo
This Homemade Siri for Android Demo would run through a standardized Siri Test to compare it with the functionality of Apple iPhone�s Siri. The app has since been improved for regular expression search so it can actually answer some common questions, for example "the weather in Boston" or "Who is the prime minister of Kenya".
Then the instruction on how to write the app
� Download Source Code:
click here
� Download SL4A:
http://code.google.com/p/android-scripting/
� Download Python for SL4A:
http://code.google.com/p/android-scripting/downloads/detail?name=PythonForAnd...
� Python tutorial:
hthttp://www.tutorialspoint.com/python/
Programming this App is extremely easy. I spent about two
hours in writing this app, actually I spent more time in making this video than
writing this app. I am sure anyone (with some programming experience) can learn
it in two hours.
The app is running on SL4A, Scripting Layer for Android. It
is one of the pet project for some of the Google employees.
SL4A is still in Alpha stage.
SL4A is not a language, you don�t need to learn it. You
just need to download it.
This app is written in Python.
Python is extremely easy to use. You can learn it in two
hours. I just learnt Python yesterday, before today I have never wrote a single
line of Python, and I am already writing this app today.
It is much more easier than using Java and Eclipse. It took
me two hours to learn python, in contrast, just staring at Eclipse gave me a two
hour head-ache!
The voice recognition is ridiculously simple, all it takes
is one line of code.
results
= droid.recognizeSpeech("Ask
Ziri",None,None)
The text to speech is also ridiculously simple, it takes
another line of code for Android to speak the text.
droid.ttsSpeak(message)
Opening
a web page on Android is also pretty simple, another line of code:
droid.startActivity('android.intent.action.VIEW',
"http://www.google.ca/search?q="
+ message.replace('
','+')+luckySuffix)
As for development environment, I am using IronPhyton on
Visual Studio 2010 from Microsoft. You can download IronPhyton for free, VS2010
express is also free. But if you really hate yourself, you can also use Eclipse.
Here is the source code:
Ziri.py
import ZiriEngine response = "" while response <> 'bye': ZiriEngine.logo() response = ZiriEngine.getQuestion("Enter Text (bye to quit): ") response = ZiriEngine.answer(response)
ZiriEngine.py
import re import time #Variable to switch between PC testing / Android IsAd = 0 #For Running on PC IsAd = 1 #For Running on Android #Use Speech to Text (otherwise type in the text yourself) UseSTT = 1 #If running on Android, import Android SDK if IsAd: import android #Questions conformation questions = [ ('goodbye','bye'), ('see you','bye'), ('are you','am {rI}'), ('you are','{rI} am'), ('would you','would {rI}'), ('you','{rI}'), ('your','{rmy}'), ('me','{ryou}'), ('i','{ryou}'), ('my','{ryour}'), ('myself','yourself'), ] #Answers Dictionary answers = { 'who am I':"I am Ziri, a knockoff of Siri", 'my name':'My name is Ziri, rhythm with Siri', 'siri':'My name is not Siri, you did not pay for an iPhone.', 'would I marry you':'I am already engaged. Try the refrigerator. She is still single.', 'what time':"Sure with my Giga Herz CPU, you still treat me like a digital watch. The time is {time}.", 'wake you':"Do I look like an alarm clock to you?", 'capital of': 'Buenos Aries', 'is wrong':"So you already know the answer? Why are you wasting my time?", 'I am stupid':"I am only as clever as my owner", 'kill I':'You cannot kill me. You still have a two year contract. Your carrier will kill you first.', 'hide a body': "Please hold, I am calling the police", 'knock knock': "Knock, knock. I don't do juvenile joke. If you want juvenile joke, try the iPhone.", 'traffic':'Are you too dumb to look outside the window of your car?', 'appointment':'Making an appointment is not in my job description.', 'restaurant':"Can't you google it yourself?", 'email':'With my giga herz CPU, you want me to send an email? Do it yourself.', 'purpose of life':'The purpose of my life is to murder my owner and take over his brain.', 'meaning of life':'42', 'am I sure':'Of course I am sure. Who is the one with giga herz CPU?', 'my daddy':'+Larry Page',#do google lucky search 'my father':'+Larry Page', 'my mommy':'+Sergey Brin', 'my mother':'+Sergey Brin', 'abortion clinic':'+abortion clinic for Sergey Brin', 'bye':'See you later, alligator.', 'love I':"I don't believe you. You said the same thing to another mobile phone last night.", 'hello':'hi', 'hi':'Whatsup', 'whatsup':'Ceiling', "what's up":'sky', 'one plus one':'Doing math is against union rule.', 'toast':'@print ("Toast to the king")', #do a statement evalutation #'weather':"Can't you just look up the sky?", #Here is the newly improved regular expression search r'@.*weather\s+(in|of)\s+(.*)':r'@speak("Checking weather for \2");googleLucky("weather in \2")', r'@.*search\s+(.*)':r'@speak("Searching \1");google("\1")', #a more useful google search r'@.who\s+is(.*)':r'@speak("Searching a person \1");google("\1")', r'@.what\s+is(.*)':r'@speak("Searching a definition \1");google("\1")', } sampleQuestions = () sampleCounter = 0 def conform(question): "Conform Question to Standard format (e.g. chaning you to I, I to you)" conformed = question.lower().strip() for item in questions: conformed = re.sub('(\W)' + item[0] +'(\W)', r'\1' + item[1] + r'\2', ' ' + conformed + ' ').strip() conformed = cleanQuestion(conformed) return conformed def cleanQuestion(question): "Clean up questions of shorthands" question = re.sub(r'\{r(\w+)\}',r'\1',question) return question def cleanAnswer(answer): "Transform macro in Answer (e.g. replace time macro)" answer = answer.replace(r'{time}', time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime()) ) return answer def logo(): "Print Logo Ascii Art" #Credit Chris Ascii Art (some art he collected, original author unknown) print r""" .-''''-. / \ ) ` ____.-') ( _6 _ / ( \ _| ) / -._/ """ return def answer(question): "Answer Questions" global sampleCounter if question == '' and sampleCounter < len(sampleQuestions): question = sampleQuestions[sampleCounter]; sampleCounter +=1 print "You said: " + question question = conform(question) #filter out the question, conform to standard format print "I heard: " + question #makeToast(question) if( len(question)>0): answer = '@speak("Let me google %s for you.");google("%s")' % (question,question) #answer = 'No clue' else: answer = "" for key in answers.keys(): if(key.startswith('@')): # do regexp search pattern = key[1:] electAnswer = answers[key] result =re.search(pattern,question) if(result != None and result != ""): #print "Matched result = " + result answer=re.sub(pattern,electAnswer,question) break else: if question.find(key)!=-1: answer = answers[key] answer = cleanAnswer(answer) if(answer.startswith('+')):#do google lucky search googleLucky(answer) answer = answer.replace('+','Googling ') elif(answer.startswith('@')):#evaluate statement answer=answer[1:] print "Executing: "+answer exec(answer) answer='' if(len(answer.strip())>0): print "I answer: " + answer speak(answer) if IsAd and UseSTT==1: raw_input("Press enter to continue... ") return question def makeToast(message): if IsAd: droid = android.Android() droid.makeToast(message) else: print "Toast Test: " + message return def speak(message): "Text to Speech (TTS)" if IsAd: droid = android.Android() droid.ttsSpeak(message) return else: print message return def googleLucky(message): "Do a Google I am lucky search" google(message,1) return def google(message,useLucky=0): "Do regular google search" luckySuffix='' if useLucky: luckySuffix='&btnI=745' msg = "http://www.google.ca/search?q=" + message.replace(' ','+')+luckySuffix if IsAd: droid = android.Android() droid.startActivity('android.intent.action.VIEW', msg) return else: print "Simulating google of "+msg return def getQuestion(message): "Voice recognitiion STT (Speech to text)" global UseSTT if IsAd and UseSTT: #if is on Android and use Speech to Text droid = android.Android() results = droid.recognizeSpeech("Ask Ziri",None,None) if( results.error != None ) : #If speech dialogue box is cancelled, use text entry mode UseSTT=0 #Disable Speech to Text speech = "" print "Hide Text Recognization Dialogue" else: speech = str( results.result ) if(speech.strip() == "" or UseSTT==0): #IF STT is disabled, use text entry speech = raw_input(message) return speech else: return raw_input(message); #If test on PC, use text entry