【问题标题】:How can I make sure that the service still works if the app is closed?如果应用程序关闭,如何确保服务仍然有效?
【发布时间】:2021-08-08 04:15:21
【问题描述】:

我有一个应用程序,我想每三分钟打开一个活动,当应用程序打开或在最近的应用程序中时,这已正确完成,但当应用程序从最近的应用程序退出时,它不再工作。 甚至我已经设置了一个警报,每十分钟检查一次,如果服务关闭,它会再次运行,但它似乎不起作用。

这是我的服务代码:

公共类 SampleService 扩展 JobService {

Alarm alarm = new Alarm();
private Timer timer;
    @Override
    public boolean onStartJob(JobParameters params ) {
        alarm.setAlarm(this);
        start();
        return true;
    }
    @Override
    public boolean onStopJob( JobParameters params ) {
        Toast.makeText(this, "Service stop!", Toast.LENGTH_LONG).show();
        return false;
    }
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    return super.onStartCommand(intent, flags, startId);
}
private TimerTask timerTask = new TimerTask() {
    @Override
    public void run() {
        Intent intent = new Intent(SampleService.this, SplashScreen.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
    }
};
public void start() {
    if(timer != null) {
        return;
    }
    timer = new Timer();
    timer.scheduleAtFixedRate(timerTask, 180000, 180000);
}
public void stop() {
    timer.cancel();
    timer = null;
}
}

这是我的报警代码:

公共类警报扩展广播接收器{

private JobScheduler jobScheduler;
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void onReceive(Context context, Intent intent) {

    PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
    @SuppressLint("InvalidWakeLockTag") PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK , "");
    wl.acquire();

    if (!isMyServiceRunning(SampleService.class , context)){
        jobScheduler = (JobScheduler) context.getSystemService(JOB_SCHEDULER_SERVICE);

        ComponentName serviceName = new ComponentName(context.getPackageName(),
                SampleService.class.getName());

        JobInfo.Builder jobBuilder = new JobInfo.Builder(10, serviceName);

        JobInfo myJobInfo = jobBuilder.build();
        jobScheduler.schedule(myJobInfo);

        Toast.makeText(context, "12345", Toast.LENGTH_LONG).show();
    }
    Toast.makeText(context, "Alarm !!!!!!!!!!", Toast.LENGTH_LONG).show(); // For example

    wl.release();
}
public void setAlarm(Context context)
{
    AlarmManager am =( AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
    Intent i = new Intent(context, Alarm.class);
    PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
    am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 60 * 10, pi); // Millisec * Second * Minute
}

public void cancelAlarm(Context context)
{
    Intent intent = new Intent(context, Alarm.class);
    PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
    AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    alarmManager.cancel(sender);
}

private boolean isMyServiceRunning(Class<?> serviceClass , Context context) {
    ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
        if (serviceClass.getName().equals(service.service.getClassName())) {
            return true;
        }
    }
    return false;
}
}

有谁知道我应该怎么做才能解决这个问题?

【问题讨论】:

  • 使用AndroidStudio的logcat
  • 我应该寻找什么?没有错误或停止或任何可以帮助我的东西
  • 像这样:String TAG="你的标签名"; // 添加服务类 Log.d(TAG, "services of running ... ");

标签: android


【解决方案1】:

使用前台服务在后台运行。
在 onstartCommand 中编写代码以打开活动。 或者您也可以设置每 3 分钟触发一次的警报并启动打开活动的服务。

public class ForegroundService extends Service {
public static final String CHANNEL_ID = "ForegroundServiceChannel";
@Override
public void onCreate() {
    super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    String input = intent.getStringExtra("inputExtra");
    createNotificationChannel();
    Intent notificationIntent = new Intent(this, MainActivity.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(this,
            0, notificationIntent, 0);
    Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("Foreground Service")
            .setContentText(input)
            .setSmallIcon(R.drawable.ic_stat_name)
            .setContentIntent(pendingIntent)
            .build();
    startForeground(1, notification);
    //do heavy work on a background thread
    //stopSelf();
    return START_NOT_STICKY;
}
@Override
public void onDestroy() {
    super.onDestroy();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}
private void createNotificationChannel() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel serviceChannel = new NotificationChannel(
                CHANNEL_ID,
                "Foreground Service Channel",
                NotificationManager.IMPORTANCE_DEFAULT
        );
        NotificationManager manager = getSystemService(NotificationManager.class);
        manager.createNotificationChannel(serviceChannel);
    }
}
}

用于启动服务

 public void startService() {
    Intent serviceIntent = new Intent(this, ForegroundService.class);
    serviceIntent.putExtra("inputExtra", "Foreground Service Example in 
Android");
    ContextCompat.startForegroundService(this, serviceIntent);
}

用于停止服务

public void stopService() {
    Intent serviceIntent = new Intent(this, ForegroundService.class);
    stopService(serviceIntent);
}

【讨论】:

  • 我之前试过这个,但是当应用程序从最近的应用程序退出时,它又无法打开活动
  • Android 10(API 级别 29)及更高版本对应用在后台运行时何时启动 Activity 施加了限制。 ...
【解决方案2】:

这可能是在后台启动服务的限制,来自Android Docs

在 Android 8.0 之前,创建前台服务的常用方法是 创建一个后台服务,然后将该服务推广到 前景。使用 Android 8.0,有一个复杂之处;系统 不允许后台应用程序创建后台服务。为了 为此,Android 8.0 引入了新方法 startForegroundService() 在前台启动一个新服务。 系统创建服务后,应用程序有 5 秒时间 调用服务的 startForeground() 方法来显示新服务的 用户可见的通知。如果应用没有调用 startForeground() 时限内,系统停止服务并声明 应用成为 ANR。

考虑到这一点,您可以编写前台服务解决方案(@Nikit 回答),或者您也可以探索Android Bounded Service

另一个选项是WorkManagerPeriodicWorker,请注意您的最短周期时间限制为 15 分钟。

【讨论】:

    猜你喜欢
    • 2014-04-25
    • 1970-01-01
    • 2018-03-05
    • 1970-01-01
    • 1970-01-01
    • 2014-02-20
    • 1970-01-01
    • 2019-03-17
    • 1970-01-01
    相关资源
    最近更新 更多