[Android服务在屏幕关闭后停止

问题描述 投票:1回答:1

我需要后台服务,它可以在屏幕关闭时收集数据。要存档,我需要一个ForegroundService,所以有人告诉我。我似乎忽略了某些东西,这就是为什么现有解决方案对我不起作用的原因。我已经尝试过但没有成功的解决方案:

  1. Android: Service doesn't work after screen is off
  2. Android service stops collecting data when the screen is turned off
  3. Why foreground service stops when screen is off on Android Oreo?

也许您可以帮助我进行故障排除。

我正在用Java开发适用于Android Pie(9)的应用程序。

AndroidManifest.xml

<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

MainActivity.java onCreate:

Intent serviceIntent = new Intent(this, ForegroundService.class);
serviceIntent.putExtra("inputExtra", "Foreground Service Example in Android");

ContextCompat.startForegroundService(this, serviceIntent);

ForegroundService.java(扩展服务):

public static final int NOTIFICATION_ID = 1;

private String createNotificationChannel() {
    String channelId = "awesome_service";
    NotificationChannel serviceChannel = new NotificationChannel(
            channelId,
            "Awesome Channel",
            NotificationManager.IMPORTANCE_HIGH
    );

    NotificationManager manager = getSystemService(NotificationManager.class);
    manager.createNotificationChannel(serviceChannel);
    return channelId;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Intent notificationIntent = new Intent(this, MainActivity.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(this,
            0, notificationIntent, 0);

    String channelId = createNotificationChannel();
    notification = new NotificationCompat.Builder(this, channelId)
            .setContentTitle(getString(R.string.app_name))
            .setContentText("Text of awesomeness")
            .setTicker("Text of awesomeness")
            .setSmallIcon(R.drawable.ic_launcher_foreground)
            .setContentIntent(pendingIntent)
            .build();

    startForeground(NOTIFICATION_ID, notification);

    //do heavy work on a background thread
    startLogic();

    return START_NOT_STICKY;
}

private void startLogic() {
    ComponentName componentName = new ComponentName(this, AwesomeJobService.class);
    JobInfo jobInfo = new JobInfo.Builder(123, componentName)
            .setMinimumLatency(0)
            .setOverrideDeadline(0)
            .setPersisted(true)
            .build();

    JobScheduler jobScheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE);
    int resultCode = jobScheduler.schedule(jobInfo);
    if (resultCode == JobScheduler.RESULT_SUCCESS) {
        System.err.println("JOB SCHEDULED!!");
    } else {
        System.err.println("JOB SCHEDULE FAILED!!");
    }
}

AwesomeJobService.java

@Override
public boolean onStartJob(JobParameters params) {
    new Thread(new Runnable() {
        @Override
        public void run() {
            // Do Stuff Example  
            while(true){
              if(ConditionOneApply){
                System.err.println("Condition One!");
                // set some booleans to true
                // sendBroadcast to inform UI about this.
              }else if(ConditionTwoApply){
                 System.err.println("Condition Two!");
                 // set some booleans to false
                 // sendBroadcast to inform UI about this.
               }
            }
        }
    }).start();
    return true;
}

感谢您提供任何有用的建议。

java android android-9.0-pie
1个回答
0
投票

其中一个问题在这里

private void startLogic() {
    ComponentName componentName = new ComponentName(this, AwesomeJobService.class);
    JobInfo jobInfo = new JobInfo.Builder(123, componentName)
            .setMinimumLatency(0)
            .setOverrideDeadline(0)
            .setPersisted(true)
            .build();

    JobScheduler jobScheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE);
    int resultCode = jobScheduler.schedule(jobInfo);
    if (resultCode == JobScheduler.RESULT_SUCCESS) {
        System.err.println("JOB SCHEDULED!!");
    } else {
        System.err.println("JOB SCHEDULE FAILED!!");
    }
}

[您正在使用setMinimumLatency(0)计划作业,将其设置为0是不可能的,操作系统会将其扩展为15 mins

您可以在Logcat这样的OS消息中检查它:

scheduled job with jobid xxxx interval expanded to 15 mins the interval is too short.

事实上。您的工作将在15 mins之后开始。

并且Wake_Lock仅在屏幕离线且设备进入省电模式后仅一分钟有效。这是google隐私权政策,具有更好的用户体验(Android> 26)。

并且所有Application Services被暂停,只有System ServicesGoogle Services允许工作。

© www.soinside.com 2019 - 2024. All rights reserved.