根目录settings.gradle文件添加
maven { url "https://chaquo.com/maven" }
build.gradle (Project)
文件,添加以下代码
id 'com.chaquo.python' version '12.0.0' apply false
在app目录下的build.gradle添加
apply plugin: "com.chaquo.python"
ndk {
abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
}
python {
buildPython "D:/miniconda3/python.exe"
pip {
install "openai-whisper" // Whisper库
}
python {
buildPython "D:/miniconda3/python.exe"
}
点击“Sync Now”,确保没有错误
出现python文件夹没问题继续下一步
app下的build.grade完整代码
plugins {
id 'com.android.application'
}
apply plugin: 'com.chaquo.python' //
android {
namespace 'com.mpj.yoloclassifyBytetrack'
compileSdk 33
// //添加此配置的作用:让过时的api或者不合规矩的语法展现出来
// gradle.projectsEvaluated {
// tasks.withType(JavaCompile) {
// options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
// }
// }
defaultConfig {
applicationId "com.mpj.yoloclassifyBytetrack"
applicationId "com.example.translator"
minSdk 24
targetSdk 33
versionCode 1
versionName "1.0"
ndk {
abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
}
python {
buildPython "D:/miniconda3/python.exe"
pip {
install "openai-whisper" // Whisper库
install "numpy==1.17.4"
install "pandas==0.25.3"
install "pymysql==1.0.2"
}
}
externalNativeBuild {
cmake {
cppFlags '-std=c++11'
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
externalNativeBuild {
cmake {
path file('src/main/cpp/CMakeLists.txt')
version '3.22.1'
}
}
buildFeatures {
viewBinding true
}
ndkVersion '25.2.9519653'
buildToolsVersion '33.0.2'
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.8.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
}
UI界面在 activity_main.xml
文件中,添加以下布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<EditText
android:id="@+id/editTextTextPersonName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="输入文本" />
<Button
android:id="@+id/btnTextToSpeech"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="文本转语音" />
<Button
android:id="@+id/btnSpeechToText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="语音转文本" />
<Button
android:id="@+id/btnSaveText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="保存文本" />
<Button
android:id="@+id/btnSaveAudio"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="保存音频" />
</LinearLayout>
<!--<?xml version="1.0" encoding="utf-8"?>-->
<!--<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"-->
<!-- xmlns:app="http://schemas.android.com/apk/res-auto"-->
<!-- xmlns:tools="http://schemas.android.com/tools"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="match_parent"-->
<!-- tools:context=".MainActivity">-->
<!-- <LinearLayout-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="match_parent"-->
<!-- android:orientation="vertical">-->
<!-- <TextView-->
<!-- android:id="@+id/sample_text"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:text="Hello World!"-->
<!-- android:textSize="50sp" />-->
<!-- <Button-->
<!-- android:id="@+id/changeYoloClassifyView"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:text="打开yolo classify"-->
<!-- android:textSize="50sp" />-->
<!-- <Button-->
<!-- android:id="@+id/changeYoloBytetrackView"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:text="打开yolo bytesort"-->
<!-- android:textSize="50sp"/>-->
<!-- </LinearLayout>-->
<!--</androidx.constraintlayout.widget.ConstraintLayout>-->
主要逻辑在 MainActivity.java
中实现以下代码
package com.example.translator;
import android.Manifest;
import android.content.pm.PackageManager;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Locale;
import com.chaquo.python.PyObject;
import com.chaquo.python.Python;
public class MainActivity extends AppCompatActivity {
private EditText editText;
private TextToSpeech tts;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = findViewById(R.id.editTextTextPersonName);
Button btnTextToSpeech = findViewById(R.id.btnTextToSpeech);
Button btnSpeechToText = findViewById(R.id.btnSpeechToText);
Button btnSaveText = findViewById(R.id.btnSaveText);
Button btnSaveAudio = findViewById(R.id.btnSaveAudio);
tts = new TextToSpeech(this, status -> {
if (status != TextToSpeech.SUCCESS) {
Toast.makeText(MainActivity.this, "TTS 初始化失败", Toast.LENGTH_SHORT).show();
} else {
tts.setLanguage(Locale.ENGLISH); // 默认语言
}
});
btnTextToSpeech.setOnClickListener(v -> {
String text = editText.getText().toString();
if (!text.isEmpty()) {
tts.speak(text, TextToSpeech.QUEUE_FLUSH, null, null);
}
});
btnSpeechToText.setOnClickListener(v -> {
// 这里调用Python处理语音转文本
Python py = Python.getInstance();
PyObject pyObj = py.getModule("whisper"); // import whisper module
PyObject result = pyObj.callAttr("transcribe", "path_to_audio_file"); // 这里需提供实际的音频文件路径
// TODO: 处理 result 得到文本
});
btnSaveText.setOnClickListener(v -> saveTextToFile(editText.getText().toString()));
btnSaveAudio.setOnClickListener(v -> saveAudio());
}
private void saveTextToFile(String text) {
try {
File file = new File(getExternalFilesDir(null), "output.txt");
FileOutputStream fos = new FileOutputStream(file);
fos.write(text.getBytes());
fos.close();
Toast.makeText(this, "文件已保存: " + file.getAbsolutePath(), Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(this, "保存失败", Toast.LENGTH_SHORT).show();
}
}
private void saveAudio() {
// TODO: 实现保存音频的逻辑
// 你可以使用AudioRecord API实现录音
}
@Override
protected void onDestroy() {
super.onDestroy();
tts.shutdown();
}
// 权限请求等
}
AndroidManifest.xml
中添加所需的权限
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Android 6.0 及以上版本,您需要在运行时请求权限,可以在 MainActivity
的 onCreate
方法中添加如下代码:
if (checkSelfPermission(Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.RECORD_AUDIO}, 1);
}
if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
}
打包失败,待研究中