Почему служба переднего плана перестает работать, когда устройство переходит в спящий режим - PullRequest
0 голосов
/ 14 мая 2019

Я хочу создать приложение, которое постоянно проверяет изменение местоположения и помещает текущее местоположение в базу данных (например, приложение для бегунов).

К сожалению, служба переднего плана останавливается или приостанавливается каждый раз, когда устройство переходит в спящий режим.

Для начала я хотел создать службу переднего плана, которая каждую секунду непрерывно записывает информацию в базу (это будет отметка времени или простая строка).Через некоторое время он просто перестает писать в firebase без вызова stopself ().

Служба работает нормально на эмуляторе (даже если переходит в режим сна), но останавливается при тестировании на реальном устройстве - в моем случае HuaweiAndroid 8.1.0.Что я должен сделать, чтобы служба работала в каждом состоянии устройства?

My MainActivity: 

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
             Intent intent = new Intent(this, MyService.class);
            intent.putExtra("action", "start");
            startForegroundService(intent);
        }
        else {
             Intent intent = new Intent(this, MyService.class);
            intent.putExtra("action", "start");
            startService(intent);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            Intent intent = new Intent(this, MyService.class);
            intent.putExtra("action", "stop");
            startForegroundService(intent);
        }
        else {
            Intent intent = new Intent(this, MyService.class);
            intent.putExtra("action", "stop");
            startService(intent);
        }
    }

}
MyService:  

public class MyService extends Service {

    int i =0;
    private String CHANNEL_ID = "2345";
    @Override
    public void onCreate() {
        super.onCreate();
    }

    public MyService() {
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        startForeground(1000, createNotification());
        String action = intent.getExtras().getString("action"); 
        switch (action){
            case "start":
                final Handler handler = new Handler();
             Runnable runnable = new Runnable() {
             @Override
             public void run() {
                        myfunction();
                 handler.postDelayed(this, 1000);
            }
        };

            break;
            case "stop":
                stopfunction();
                break;
        }
        handler.postDelayed(runnable, 1000);
        return START_NOT_STICKY;
    }

    private void stopfunction() {
        stopSelf();
}

    private void myfunction() {
        FirebaseDatabase database = FirebaseDatabase.getInstance();
        DatabaseReference myRef = database.getReference("locations");
        myRef.child("location").setValue(i);
        i++;
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        return null;
    }

    @RequiresApi(Build.VERSION_CODES.O)
    private void createChannel(){
        NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
        NotificationChannel channel = new NotificationChannel(CHANNEL_ID, getString(R.string.infoTxt),
                NotificationManager.IMPORTANCE_HIGH);
        channel.setShowBadge(false);
        channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
        notificationManager.createNotificationChannel(channel);
    }

    private Notification createNotification(){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
            createChannel();
        }

        Intent notificationItent = new Intent(this, MainActivity.class);
        notificationItent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        PendingIntent intent = PendingIntent.getActivity(this, 0, notificationItent, 0);

        return new NotificationCompat.Builder(this, CHANNEL_ID)
                .setColor(ContextCompat.getColor(this, android.R.color.background_dark))
                .setContentIntent(intent)
                .setSmallIcon(R.drawable.ic_launcher_background)
                .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
                .setOnlyAlertOnce(true)
                .setContentTitle("GPS Location")
                .build();
    }
}

Ответы [ 2 ]

1 голос
/ 14 мая 2019

Сервисы Foreground обычно должны использоваться для задач, требующих внимания пользователя, таких как визуальные процессы.используйте Background сервис вместо

0 голосов
/ 23 мая 2019

Я перепробовал все: сервис, приоритетный сервис, широковещательный приемник, jobSheduler, WorkerManager - ничего не помогло. Затем я обнаружил, что это новая функция HUAWEI, которая называется «энергоемкий монитор приложений». Это убивает каждое приложение, которое работает в фоновом режиме в течение длительного времени, если пользователь не дает специальные разрешения для него. Путь для этого: Настройки -> Безопасность и конфиденциальность -> Службы определения местоположения -> Недавние запросы местоположения: ВАШЕ ИМЯ ПРИЛОЖЕНИЯ -> Батарея -> снимите флажок Энергоемкий запрос, Запуск приложения: Управление вручную: проверьте все три позиции: Автозапуск, дополнительный запуск, запуск в фон.

Я не знаю, есть ли способ сделать это программно. Я думаю, что лучший способ - создать своего рода справочную деятельность и объяснить пользователю, что делать, если приложение не работает.

...