I've searched quite a bit on this topic, looking at options like Jython and Chaquopy, but whatever I do, there is always an error.
What I'm looking to do is, when a button on my Android app is clicked, the python script (voice recognition using gTTS API in python) will run.
This is what my code looks like (using Chaquopy):
MainActivity.java:
import androidx.appcompat.app.AppCompatActivity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageButton;
import android.content.res.AssetFileDescriptor;
import com.chaquo.python.*;
import com.chaquo.python.android.AndroidPlatform;
import java.io.IOException;
public class MainActivity extends AppCompatActivity implements View.OnTouchListener{
ImageButton AutoCruiseButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (!Python.isStarted()) {
Python.start(new AndroidPlatform(this));
}
AutoCruiseButton = (ImageButton) findViewById(R.id.auto);
AutoCruiseButton.setOnTouchListener(this);
final MediaPlayer beep1 = MediaPlayer.create(this, R.raw.beep1);
final MediaPlayer mp = new MediaPlayer();
AutoCruiseButton.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
stopAndPlay(R.raw.beep1, mp);
Python python = Python.getInstance();
PyObject file = python.getModule("voice_recognition");
PyObject command = file.callAttr("myCommand");
}
});
Top-level build file: build.gradle
buildscript {
repositories {
google()
jcenter()
maven { url "https://chaquo.com/maven" }
}
dependencies {
classpath 'com.android.tools.build:gradle:4.0.2'
classpath "com.chaquo.python:gradle:8.0.0"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
build.gradle (:app):
apply plugin: 'com.android.application'
apply plugin: 'com.chaquo.python'
android {
compileSdkVersion 29
buildToolsVersion "29.0.3"
defaultConfig {
applicationId "com.example.myapplication"
sourceSets{
main{
python{
srcDirs = ["src/main/python"]
}
}
}
minSdkVersion 16
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
ndk {
abiFilters "armeabi-v7a", "x86"
}
python {
buildPython "C:/Users/Alya/AppData/Local/Microsoft/WindowsApps/python3"
buildPython "python3"
}
ndk {
abiFilters "armeabi-v7a", "x86"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
targetCompatibility = 1.8
sourceCompatibility = 1.8
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
voice_recognition.py (located in python folder under the Main folder for Android Studio project):
from gtts import gTTS
import speech_recognition as sr
import playsound
import sys
counter = 0
def myCommand():
r = sr.Recognizer()
global counter
if counter == 0:
playsound.playsound('C:/Users/Alya/Desktop/KITT/Audio_Clips/What_Can_I_Do.mp3')
with sr.Microphone() as source:
counter += 1
print('I am ready for your next command')
r.pause_threshold = 1
r.adjust_for_ambient_noise(source, duration=1)
audio = r.listen(source)
try:
command = r.recognize_google(audio)
print('You said ' + command + '\n')
#loop back in case not understood
except sr.UnknownValueError:
print("I didn't hear that")
command = ""
playsound.playsound('C:/Users/Alya/Desktop/KITT/Audio_Clips/Go_Ahead.mp3')
assistant(myCommand())
return command
#if statements for executing commands
def assistant(command):
if 'introduce yourself' in command:
playsound.playsound('C:/Users/Alya/Desktop/KITT/Audio_Clips/KITT_Intro.mp3')
I know Chaquopy works since I tested a basic python file and my emulator didn't crash. Here is the error I get when clicking the button to run the python script:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.myapplication, PID: 26779
com.chaquo.python.PyException: ModuleNotFoundError: No module named 'gtts'
at <python>.java.chaquopy.import_override(import.pxi:20)
at <python>.java.chaquopy.import_override(import.pxi:60)
at <python>.voice_recognition.<module>(voice_recognition.py:1)
at <python>.importlib._bootstrap._call_with_frames_removed(<frozen importlib._bootstrap>:219)
at <python>.importlib._bootstrap_external.exec_module(<frozen importlib._bootstrap_external>:783)
at <python>.java.android.importer.exec_module(importer.py:521)
at <python>.importlib._bootstrap._load_unlocked(<frozen importlib._bootstrap>:671)
at <python>.importlib._bootstrap._find_and_load_unlocked(<frozen importlib._bootstrap>:975)
at <python>.importlib._bootstrap._find_and_load(<frozen importlib._bootstrap>:991)
at <python>.importlib._bootstrap._gcd_import(<frozen importlib._bootstrap>:1014)
at <python>.importlib.import_module(__init__.py:127)
at <python>.chaquopy_java.Java_com_chaquo_python_Python_getModule(chaquopy_java.pyx:154)
at com.chaquo.python.Python.getModule(Native Method)
at com.example.myapplication.MainActivity$9.onClick(MainActivity.java:125)
at android.view.View.performClick(View.java:6597)
at android.view.View.performClickInternal(View.java:6574)
at android.view.View.access$3100(View.java:778)
at android.view.View$PerformClick.run(View.java:25885)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
I/Process: Sending signal. PID: 26779 SIG: 9
Any suggestions of how to proceed? I really rather keep my Android app in Java since the interface is already implemented. How can I fix my code so it works with Chaquopy? Or how would I do it in Jython if it is a better alternative?
You'll have to install gtts, into your app using pip, as described here. The same goes for the other third-party modules you're using.
Also, you won't be able to access files on your Windows desktop from an Android app. Instead, include them in your Python source directory and then access them relative to __file__
as described here.
Unfortunately this script will probably encounter other, more difficult problems:
recognize_google
requires a FLAC converter, which Chaquopy isn't currently able to support.Sorry I couldn't be more helpful.