diff --git a/app/src/main/java/in/co/gorest/grblcontroller/UsbConnectionActivity.java b/app/src/main/java/in/co/gorest/grblcontroller/UsbConnectionActivity.java index 69f7eb3..f2146b1 100644 --- a/app/src/main/java/in/co/gorest/grblcontroller/UsbConnectionActivity.java +++ b/app/src/main/java/in/co/gorest/grblcontroller/UsbConnectionActivity.java @@ -35,6 +35,7 @@ import android.os.Handler; import android.os.IBinder; import android.os.Message; +import android.util.Log; import android.view.Menu; import android.view.MenuItem; @@ -79,7 +80,13 @@ public void onStart(){ // The service goes foreground on its own once a USB device permission is granted. // startForegroundService would crash here on Android 14+ when no device is granted yet. - startService(new Intent(getApplicationContext(), GrblUsbSerialService.class)); + try{ + startService(new Intent(getApplicationContext(), GrblUsbSerialService.class)); + }catch(IllegalStateException e){ + // Android refuses this while it counts the app as in the background. + // The bind in onCreate already keeps the service alive. + Log.w("UsbConnectionActivity", "could not start the USB service", e); + } } @Override diff --git a/app/src/main/java/in/co/gorest/grblcontroller/service/FileStreamerIntentService.java b/app/src/main/java/in/co/gorest/grblcontroller/service/FileStreamerIntentService.java index 26953c4..68ed705 100644 --- a/app/src/main/java/in/co/gorest/grblcontroller/service/FileStreamerIntentService.java +++ b/app/src/main/java/in/co/gorest/grblcontroller/service/FileStreamerIntentService.java @@ -25,7 +25,6 @@ import android.app.Notification; import android.content.Context; import android.content.Intent; -import android.os.Build; import android.os.PowerManager; import android.os.Process; import androidx.core.app.NotificationCompat; @@ -105,6 +104,16 @@ public void onDestroy(){ EventBus.getDefault().unregister(this); } + @Override + public int onStartCommand(Intent intent, int flags, int startId){ + // Android kills the app when a service started with startForegroundService() stops, or runs + // for 10 s, without calling startForeground(). So call it first, on every start, before any work. + boolean isCheckMode = intent != null && intent.getBooleanExtra(CHECK_MODE_ENABLED, false); + String title = getString(isCheckMode ? R.string.text_file_checking_started : R.string.text_file_streaming_started); + startForeground(Constants.FILE_STREAMING_NOTIFICATION_ID, getNotification(title, FileSenderListener.getInstance().getGcodeFileName())); + return super.onStartCommand(intent, flags, startId); + } + @Override protected void onHandleIntent(Intent intent){ fileSenderListener = FileSenderListener.getInstance(); @@ -151,20 +160,12 @@ public void run() { EventBus.getDefault().post(new StreamingStartedEvent()); if(isCheckMode){ - if(Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1){ - startForeground(Constants.FILE_STREAMING_NOTIFICATION_ID, getNotification(getString(R.string.text_file_checking_started), fileSenderListener.getGcodeFile().getName())); - } - if(defaultConnectionType != null && defaultConnectionType.equals(Constants.SERIAL_CONNECTION_TYPE_BLUETOOTH)){ this.checkGcodeFile(); }else{ this.startStreaming(555); } }else{ - if(Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1){ - startForeground(Constants.FILE_STREAMING_NOTIFICATION_ID, getNotification(getString(R.string.text_file_streaming_started), fileSenderListener.getGcodeFile().getName())); - } - this.startStreaming(5); }