根据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类
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建模为粘性,作业服务 (基本上,一旦结束,应由操作系统重新启动)。为此,我是否可以在TTSJobScheduledService的 onStopJob()方法中重新启动服务?还是有更好的方法来做到这一点?
答案 0 :(得分:0)
@Override
public boolean onStartJob(JobParameters params) {
return true;
}
上述方法调用将取决于系统资源的可用性。同样,Jobscheduler也不必在您在Jobscheduler中提到的给定期限内开始工作。
例如:builder.setOverrideDeadline(3 * 1000);
一段时间后,如果发现未使用作业计划程序,则系统本身将停止服务。
您也可以在 onStopJob()方法中开始工作,但这始终取决于您使用频率的要求。
根据最新的android背景限制,您所做的更改将起作用。如果您想进行任何形式的用户交互,请继续使用 startForegroundService()。
请参考博客以获取更多详细信息:https://medium.com/exploring-android/exploring-background-execution-limits-on-android-oreo-ab384762a66c