Android - Foreground 在 Oreo 中不工作。操作系统在一段时间后终止服务

标签 android background-service locationlistener foreground-service google-location-services

我有一个应用程序,每隔 5 分钟就会在后台使用定位服务。我们在前台服务中使用 Fusedlocationproviderclient。当应用程序处于打开状态时它工作正常。

在android 8.0及以上版本,当我将应用程序置于后台或从后台滑动杀死时,前台服务会被操作系统自动杀死。

我们在 samsung note 8、one plus 5t 和 red mi 设备中遇到问题。

请告诉我如何实现兼容所有设备的服务。

这是我的位置服务类。

    public class TrackingForgroundService extends Service {


    private final long UPDATE_INTERVAL = (long) 2000;
    private static final long FASTEST_INTERVAL = 2000;

    public BookingTrackingForgroundService() {

    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }


    @Override
    public void onCreate() {
        super.onCreate();
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (intent != null) {
            String action = intent.getAction();

            switch (action) {
                case ACTION_START_FOREGROUND_SERVICE:
                    startForegroundService();

                    break;
                case ACTION_STOP_FOREGROUND_SERVICE:
                    stopForegroundService();

                    break;
            }
        }
        return START_STICKY;
    }


    private class TimerTaskToGetLocation extends TimerTask {
        @Override
        public void run() {

            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    // Call webservice evry 5 minute
                }
            });

        }
    }


    private void startForegroundService() {

        Log.d(TAG_FOREGROUND_SERVICE, "Start foreground service.");

        context = this;
        startLocationUpdates();
        notify_interval1 = Prefs.with(this).readLong("notify_interval1", 5000);
        mTimer = new Timer();
        mTimer.scheduleAtFixedRate(new TimerTaskToGetLocation(), 15000, notify_interval1);
        mTimer.scheduleAtFixedRate(new TimerTaskToSendCsvFile(), 60000, 1200000);
        prefsPrivate = getSharedPreferences(Constants.prefsKeys.PREFS_PRIVATE, Context.MODE_PRIVATE);
        internet = new NetConnectionService(context);


        Intent notificationIntent = new Intent(this, ActTherapistDashboard.class);
        notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
                .setContentTitle(getString(R.string.app_name))
                .setContentText("Geolocation is running")
                .setTicker("Geolocation").setSmallIcon(R.drawable.app_small_icon_white)
                .setContentIntent(pendingIntent);
        Notification notification = builder.build();
        if (Build.VERSION.SDK_INT >= 26) {
            NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);
            channel.setDescription(CHANNEL_DESCRIPTION);
            NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            notificationManager.createNotificationChannel(channel);
        }
        startForeground(SERVICE_ID, notification);
    }

    private void stopForegroundService() {
        stopLocationUpdates();
        Log.d(TAG_FOREGROUND_SERVICE, "Stop foreground service.");
        if (mTimer != null) {
            mTimer.cancel();
        } else {
            mTimer = null;
        }
        // Stop foreground service and remove the notification.
        stopForeground(true);

        // Stop the foreground service.
        stopSelf();
    }




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

            }
        }
        return false;
    }


    private void startLocationUpdates() {
        // create location request object
        mLocationRequest = LocationRequest.create();

        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        mLocationRequest.setInterval(UPDATE_INTERVAL);
        mLocationRequest.setFastestInterval(FASTEST_INTERVAL);


        // initialize location setting request builder object
        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
        builder.addLocationRequest(mLocationRequest);
        LocationSettingsRequest locationSettingsRequest = builder.build();


        // initialize location service object
        SettingsClient settingsClient = LocationServices.getSettingsClient(this);
        Task<LocationSettingsResponse> task = settingsClient.checkLocationSettings(locationSettingsRequest);
        task.addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>() {
            @Override
            public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
                registerLocationListner();
            }
        });


    }


    private void registerLocationListner() {
        locationCallback = new LocationCallback() {
            @Override
            public void onLocationResult(LocationResult locationResult) {
                super.onLocationResult(locationResult);
                onLocationChanged(locationResult.getLastLocation());
            }
        };

      //location permission
        LocationServices.getFusedLocationProviderClient(this).requestLocationUpdates(mLocationRequest, locationCallback, null);

    }


    private void onLocationChanged(Location location) {

        if (location != null) {
            latitude = location.getLatitude();
            longitude = location.getLongitude();
            latitudeTemp = latitude;
            longitudeTemp = longitude;
        }

    }



}       

最佳答案

请查看答案here到类似的问题和链接站点 dontkillmyapp它为开发者提供了一个非常有用的总结,以帮助理解不同手机制造商和 Android 操作系统版本之间的这个问题。

关于Android - Foreground 在 Oreo 中不工作。操作系统在一段时间后终止服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53718089/

相关文章:

android:layout_gravity 会将 subview 垂直而不是水平放置在中心

android - 为什么 glClear 在 OpenGLES 中阻塞?

android - 工作管理器是否适合在后台播放音乐?

android - 如何以编程方式在 Lenovo 设备中为我的应用程序启用自动启动选项?

android - 我正在使用 firebase_admob 在我的 flutter 应用程序中实现广告,但广告在 release build apk 中不起作用

android - ACRA 异常 RequestCode 只能使用低 16 位

Android:IntentService 被终止

android - 检查圆形地理围栏内的地理位置(纬度,经度)

android - onlocationchanged 未在 Android 中调用

Android 位置 : PendingIntent vs. LocationListener