As per the requirement to update targeted SDK version to 26 by November 2018, I tried to update my gradle file a few months ago and released a new version of my app, after updating both target sdk and compile sdk versions to 26 (from 23). Within a day, I started observing crashes in my app on my Firebase console. The reason was I was using TTS service in my app, and when targeting to version 26, it looks like it required a new implementation for the TTS service, because of the fatal run-time exception. So I reverted the target SDK version to 23 and compile sdk version to 23.
Caused by java.lang.IllegalStateException: Not allowed to start service Intent { cmp=com.a.b.c/services.TTSService }: app is in background
This exception was seen only for the devices on Android OS 8.0 and 8.1.
So a month ago, I bought a new device which is on Android 8.0 (Motorola G6 Plus), hoping to consistently reproduce this error. But it never happened on this device, even though my app targeting version 26, even when I forcefully triggered the TTS service through my app. So, I am confused as to how to proceed.
The solution for this exception is explained here.
My current code for implementing and calling the TTS service is as follows:
MainActivity oncreate method :
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;
}
}
}
Do I have to re-implement this feature as per the above mentioned solution? Or can I resort to a simpler approach of targeting the version 26 SDK, but retaining compile SDK version at 23 (it's current state in my app)? Any other solutions would be appreciated.