В соответствии с целевыми требованиями к Android O, мне пришлось повторно реализовать сервис для инициализации объекта преобразования текста в речь как запланированный на работу сервис .
Мой первоначальный сервис реализован следующим образом: TTSService.java
Код для класса TTSService:
package services;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.speech.tts.TextToSpeech;
import android.support.annotation.Nullable;
public class TTSService extends Service {
private static TextToSpeech voice =null;
public static TextToSpeech getVoice() {
return voice;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
// not supporting binding
return null;
}
public TTSService() {
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
try{
voice = new TextToSpeech(TTSService.this, new TextToSpeech.OnInitListener() {
@Override
public void onInit(final int status) {
}
});
}
catch(Exception e){
e.printStackTrace();
}
return Service.START_STICKY;
}
@Override
public void onDestroy() {
clearTtsEngine();
super.onDestroy();
}
public static void clearTtsEngine()
{
if(voice!=null)
{
voice.stop();
voice.shutdown();
voice = null;
}
}
}
Чтобы повторно реализовать этот сервис какСлужба запланированного задания, в своем классе PhoneUtils я использовал следующие методы:
public static void scheduleTTSJob(Context context) {
if(isTTSJobServiceOn(context))
{
return;
}
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
ComponentName serviceComponent = new ComponentName(context, TTSJobScheduledService.class);
JobInfo.Builder builder = new JobInfo.Builder(JOB_ID, serviceComponent);
builder.setMinimumLatency(1 * 1000); // wait at least
builder.setOverrideDeadline(3 * 1000); // maximum delay
JobScheduler jobScheduler = context.getSystemService(JobScheduler.class);
jobScheduler.schedule(builder.build());
}
}
public static boolean isTTSJobServiceOn( Context context ) {
boolean hasBeenScheduled = false;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
JobScheduler scheduler = (JobScheduler) context.getSystemService( Context.JOB_SCHEDULER_SERVICE );
for ( JobInfo jobInfo : scheduler.getAllPendingJobs() ) {
if ( jobInfo.getId() == JOB_ID ) {
hasBeenScheduled = true;
break;
}
}
}
return hasBeenScheduled;
}
public static void stopTTSJob(Context context)
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
JobScheduler scheduler = (JobScheduler) context.getSystemService( Context.JOB_SCHEDULER_SERVICE );
for ( JobInfo jobInfo : scheduler.getAllPendingJobs() ) {
if ( jobInfo.getId() == JOB_ID ) {
scheduler.cancel(JOB_ID);
break;
}
}
}
}
, и служба была реализована следующим образом: TTSJobScheduledService class
package services;
import android.annotation.TargetApi;
import android.app.job.JobParameters;
import android.app.job.JobService;
import android.content.Intent;
import android.os.Build;
import android.speech.tts.TextToSpeech;
import com.crashlytics.android.Crashlytics;
import utilities.PhoneUtils;
/**
* Created by Admin on 30-Sep-18.
*/
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class TTSJobScheduledService extends JobService {
private static TextToSpeech voice =null;
public static TextToSpeech getVoice() {
return voice;
}
@Override
public boolean onStartJob(JobParameters params) {
startTTSEngine();
PhoneUtils.scheduleTTSJob(getApplicationContext()); // reschedule the job
return true;
}
@Override
public boolean onStopJob(JobParameters params) {
clearTtsEngine();
return true;
}
private void startTTSEngine()
{
try{
voice = new TextToSpeech(TTSJobScheduledService.this, new TextToSpeech.OnInitListener() {
@Override
public void onInit(final int status) {
}
});
}
catch(Exception e){
Crashlytics.log("TTS initialization issue");
Crashlytics.logException(e);
}
}
private static void clearTtsEngine()
{
if(voice!=null)
{
voice.stop();
try {
voice.shutdown();
}
catch (Exception e){
Crashlytics.log("ClearTTSEngine shutdown issue");
Crashlytics.logException(e);
}
voice = null;
}
}
}
Казалось, что это хорошо работает на устройствах с Android O, пока я не заметил, что служба прекратила работу через некоторое время и не перезапускалась сама по себе.Чтобы перезапустить его вручную, мне пришлось либо открыть приложение, либо перезапустить устройство.
По сути, я хочу смоделировать свой TTSService как sticky, jobservice (в основном этодолжна быть перезапущена ОС после ее завершения) .Для этого можно ли просто перезапустить службу в методе onStopJob () службы TTSJobScheduledService?Или есть лучший способ сделать это?