根据到 2018 年 11 月将目标 SDK 版本更新到 26 的要求,我在几个月前尝试更新我的 gradle 文件并发布了我的应用程序的新版本,将目标 sdk 和编译 sdk 版本更新为 26(从 23)之后。一天之内,我开始在 Firebase 控制台上观察到应用程序发生崩溃。原因是我在我的应用程序中使用 TTS 服务,当定位到版本 26 时,由于致命的运行时异常,它似乎需要 TTS 服务的新实现。所以我将目标SDK版本恢复为23,并将sdk版本编译为23。
Caused by java.lang.IllegalStateException: Not allowed to start service Intent { cmp=com.a.b.c/services.TTSService }: app is in background
看到了这个异常only适用于运行 Android OS 8.0 和 8.1 的设备。
所以一个月前,我购买了一台运行 Android 8.0 的新设备(摩托罗拉 G6 Plus),希望能够持续重现此错误。但它从未在此设备上发生过,即使我的应用程序定位版本 26,即使我通过我的应用程序强制触发 TTS 服务。因此,我对如何继续感到困惑。
这个异常的解决办法解释一下here.
我目前实现和调用TTS服务的代码如下:
MainActivity oncreate 方法:
if(!isMyServiceRunning(TTSService.class))//Start a service instance only if service is currently not running
startService(new Intent(MainActivity.this, TTSService.class));
TTSService.java:
package services;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.os.Environment;
import android.os.IBinder;
import android.speech.tts.TextToSpeech;
import android.support.annotation.Nullable;
import android.util.Log;
import android.widget.Toast;
import com.google.firebase.crash.FirebaseCrash;
import constants.ConstantParams;
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();
FirebaseCrash.report(new Exception("Error in initializing TTS object"));
FirebaseCrash.log("Error in initializing TTS object");
}
return Service.START_STICKY;
}
@Override
public void onDestroy() {
clearTtsEngine();
super.onDestroy();
}
public static void clearTtsEngine()
{
if(voice!=null)
{
voice.stop();
voice.shutdown();
voice = null;
}
}
}
我是否必须按照上述解决方案重新实现此功能?或者我可以采取更简单的方法来定位版本 26 SDK,但保留编译 SDK 版本为 23(这是我的应用程序中的当前状态)?任何其他解决方案将不胜感激。