Я пытаюсь создать приложение для своего проекта в колледже, которое использует планировщик заданий для записи звука в фоновом режиме с микрофона устройства в течение 5 секунд каждые 15 минут с помощью SpeechRecognizer. Я пробовал следовать нескольким учебникам, но не могу заставить приложение работать.
В настоящее время у меня есть очень базовое c приложение, в котором есть кнопка, которая будет планировать задачу. Я не уверен, что есть ли лучший способ сделать это, но это был самый дальний уровень, который я смог получить с моим уровнем мастерства в студии android. Мне действительно нужна помощь. Я добавил свой код для приложения, а также ошибки, которые я получаю при запуске приложения.
MainActivity. java
package com.example.microphonebackgroundtester;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.app.job.JobInfo;
import android.app.job.JobScheduler;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
scheduleJob();
}
});
checkPermission();
}
public void scheduleJob() {
ComponentName componentName = new ComponentName(this, JobServiceExample.class);
JobInfo info = new JobInfo.Builder(123, componentName)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.setPersisted(true)
.setPeriodic(15 * 60 * 1000)
.build();
JobScheduler jobScheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE);
int resultCode = jobScheduler.schedule(info);
if (resultCode == JobScheduler.RESULT_SUCCESS) {
Log.d(TAG, "Job scheduled");
} else {
Log.d(TAG, "Job scheduling failed");
}
}
public void cancelJob() {
JobScheduler scheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE);
scheduler.cancel(123);
Log.d(TAG, "Job cancelled");
}
private void checkPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!(ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED)){
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + getPackageName()));
startActivity(intent);
finish();
}
}
}
}
JobServiceExample . java
package com.example.microphonebackgroundtester;
import android.app.job.JobParameters;
import android.app.job.JobService;
import android.content.Intent;
import android.nfc.Tag;
import android.os.Bundle;
import android.speech.RecognitionListener;
import android.speech.RecognizerIntent;
import android.speech.SpeechRecognizer;
import android.util.Log;
import android.widget.EditText;
import java.util.ArrayList;
import java.util.Locale;
public class JobServiceExample extends JobService {
private static final String TAG = "ExampleJobService";
private boolean jobCancelled = false;
SpeechRecognizer mSpeechRecognizer;
Intent mSpeechRecognizerIntent;
@Override
public boolean onStartJob(JobParameters params) {
Log.d(TAG, "Job started");
mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
mSpeechRecognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault());
mSpeechRecognizer.setRecognitionListener(new RecognitionListener() {
@Override
public void onReadyForSpeech(Bundle params) {
}
@Override
public void onBeginningOfSpeech() {
}
@Override
public void onRmsChanged(float rmsdB) {
}
@Override
public void onBufferReceived(byte[] buffer) {
}
@Override
public void onEndOfSpeech() {
}
@Override
public void onError(int error) {
}
@Override
public void onResults(Bundle results) {
ArrayList<String> matches = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
if (matches != null)
Log.d(TAG, "Speech Received" + matches.get(0));
}
@Override
public void onPartialResults(Bundle partialResults) {
}
@Override
public void onEvent(int eventType, Bundle params) {
}
});
doBackgroudWork(params);
return true;
}
private void doBackgroudWork(final JobParameters params) {
//start recording voice
Log.d(TAG, "Listening:");
mSpeechRecognizer.startListening(mSpeechRecognizerIntent);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (jobCancelled) {
//stop recording
Log.d(TAG, "Listening stopped");
mSpeechRecognizer.stopListening();
return;
}
//stop recording voice
Log.d(TAG, "Listening stopped");
mSpeechRecognizer.stopListening();
Log.d(TAG, "Job finished");
jobFinished(params, false);
}
@Override
public boolean onStopJob(JobParameters params) {
Log.d(TAG, "Job cancelled before completion");
jobCancelled = true;
return true;
}
}
Ошибки из журнала
D/ExampleJobService: Job started
Listening:
D/ExampleJobService: Listening stopped
D/ExampleJobService: Job finished
I/Choreographer: Skipped 303 frames! The application may be doing too much work on its main thread.
V/ActivityThread: SVC-Destroying service com.example.microphonebackgroundtester.JobServiceExample@af09453
E/ActivityThread: Service com.example.microphonebackgroundtester.JobServiceExample has leaked ServiceConnection android.speech.SpeechRecognizer$Connection@d2a190 that was originally bound here
android.app.ServiceConnectionLeaked: Service com.example.microphonebackgroundtester.JobServiceExample has leaked ServiceConnection android.speech.SpeechRecognizer$Connection@d2a190 that was originally bound here
at android.app.LoadedApk$ServiceDispatcher.<init>(LoadedApk.java:1376)
at android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:1271)
at android.app.ContextImpl.bindServiceCommon(ContextImpl.java:1465)
at android.app.ContextImpl.bindService(ContextImpl.java:1437)
at android.content.ContextWrapper.bindService(ContextWrapper.java:636)
at android.speech.SpeechRecognizer.startListening(SpeechRecognizer.java:287)
at com.example.microphonebackgroundtester.JobServiceExample.doBackgroudWork(JobServiceExample.java:96)
at com.example.microphonebackgroundtester.JobServiceExample.onStartJob(JobServiceExample.java:87)
at android.app.job.JobService$JobHandler.handleMessage(JobService.java:143)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:203)
at android.app.ActivityThread.main(ActivityThread.java:6259)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1063)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:924)