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?
Advertisement
Answer
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:
- You probably won’t be able to access the device’s microphone or speakers from Python code, so you’ll have to use the Android Java APIs instead.
- As discussed here,
recognize_google
requires a FLAC converter, which Chaquopy isn’t currently able to support.
Sorry I couldn’t be more helpful.