How to run python voice recognition script in Java (Android Studio)?

Tags: , , , ,



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?

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.



Source: stackoverflow