mirror of
https://github.com/fankes/termux-app.git
synced 2025-09-06 18:55:31 +08:00
Fix issue where termux crashes occasionally in android >= 8 because "startForeground()" function is not being called before running "startForegroundService()" in RunCommandService.
This commit is contained in:
@@ -1,6 +1,10 @@
|
|||||||
package com.termux.app;
|
package com.termux.app;
|
||||||
|
|
||||||
|
import android.app.Notification;
|
||||||
|
import android.app.NotificationChannel;
|
||||||
|
import android.app.NotificationManager;
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
@@ -8,6 +12,8 @@ import android.os.Build;
|
|||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.termux.R;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
@@ -50,6 +56,9 @@ public class RunCommandService extends Service {
|
|||||||
public static final String RUN_COMMAND_WORKDIR = "com.termux.RUN_COMMAND_WORKDIR";
|
public static final String RUN_COMMAND_WORKDIR = "com.termux.RUN_COMMAND_WORKDIR";
|
||||||
public static final String RUN_COMMAND_BACKGROUND = "com.termux.RUN_COMMAND_BACKGROUND";
|
public static final String RUN_COMMAND_BACKGROUND = "com.termux.RUN_COMMAND_BACKGROUND";
|
||||||
|
|
||||||
|
private static final String NOTIFICATION_CHANNEL_ID = "termux_run_command_notification_channel";
|
||||||
|
private static final int NOTIFICATION_ID = 1338;
|
||||||
|
|
||||||
class LocalBinder extends Binder {
|
class LocalBinder extends Binder {
|
||||||
public final RunCommandService service = RunCommandService.this;
|
public final RunCommandService service = RunCommandService.this;
|
||||||
}
|
}
|
||||||
@@ -61,7 +70,15 @@ public class RunCommandService extends Service {
|
|||||||
return mBinder;
|
return mBinder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
runStartForeground();
|
||||||
|
}
|
||||||
|
|
||||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||||
|
// Run again in case service is already started and onCreate() is not called
|
||||||
|
runStartForeground();
|
||||||
|
|
||||||
if (allowExternalApps() && RUN_COMMAND_ACTION.equals(intent.getAction())) {
|
if (allowExternalApps() && RUN_COMMAND_ACTION.equals(intent.getAction())) {
|
||||||
Uri programUri = new Uri.Builder().scheme("com.termux.file").path(intent.getStringExtra(RUN_COMMAND_PATH)).build();
|
Uri programUri = new Uri.Builder().scheme("com.termux.file").path(intent.getStringExtra(RUN_COMMAND_PATH)).build();
|
||||||
|
|
||||||
@@ -78,9 +95,56 @@ public class RunCommandService extends Service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
runStopForeground();
|
||||||
|
|
||||||
return Service.START_NOT_STICKY;
|
return Service.START_NOT_STICKY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void runStartForeground() {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
setupNotificationChannel();
|
||||||
|
startForeground(NOTIFICATION_ID, buildNotification());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runStopForeground() {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
stopForeground(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Notification buildNotification() {
|
||||||
|
Notification.Builder builder = new Notification.Builder(this);
|
||||||
|
builder.setContentTitle(getText(R.string.application_name) + " Run Command");
|
||||||
|
builder.setSmallIcon(R.drawable.ic_service_notification);
|
||||||
|
|
||||||
|
// Use a low priority:
|
||||||
|
builder.setPriority(Notification.PRIORITY_LOW);
|
||||||
|
|
||||||
|
// No need to show a timestamp:
|
||||||
|
builder.setShowWhen(false);
|
||||||
|
|
||||||
|
// Background color for small notification icon:
|
||||||
|
builder.setColor(0xFF607D8B);
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
builder.setChannelId(NOTIFICATION_CHANNEL_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupNotificationChannel() {
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return;
|
||||||
|
|
||||||
|
String channelName = "Termux Run Command";
|
||||||
|
int importance = NotificationManager.IMPORTANCE_LOW;
|
||||||
|
|
||||||
|
NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, importance);
|
||||||
|
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
|
manager.createNotificationChannel(channel);
|
||||||
|
}
|
||||||
|
|
||||||
private boolean allowExternalApps() {
|
private boolean allowExternalApps() {
|
||||||
File propsFile = new File(TermuxService.HOME_PATH + "/.termux/termux.properties");
|
File propsFile = new File(TermuxService.HOME_PATH + "/.termux/termux.properties");
|
||||||
if (!propsFile.exists())
|
if (!propsFile.exists())
|
||||||
|
Reference in New Issue
Block a user