Приложение Android 7.0 Kills, даже когда запущен Foreground Service - PullRequest
0 голосов
/ 20 сентября 2018

Я испробовал каждое предложение, которое смог найти в Интернете, чтобы использовать Foreground Service, чтобы приложение работало вне спящего режима и режима глубокого сна, но пока ничего не получалось.

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

Ниже приведен код службы Foreground, который запускается всякий раз, когда водитель переходит в оперативный режим и останавливается, когда он нажимает кнопку онлайн.который изменяет Common.CustomSocketOn на 0.

Он отлично работает во время пробуждения экрана, а также работает, когда экран выключен до того, как приложение будет убито.

Однако даже после получения WAKE_LOCK он все равно не может оставаться в спящем режиме более нескольких минут, пока его не убьет Android 7.

Эта неспособность продолжать работу в спящем режиме ломает многиедругие функции приложения, потому что когда приложение тихо убивается, оно не получает ни возможности отключить драйвер, ни выйти из него.В результате водитель получает запросы на бронирование, когда его приложение не запущено, и, следовательно, не может его обслуживать, и это препятствует переходу бронирования к следующему доступному водителю.На самом деле это вызывает множество других аномалий.

Пожалуйста, кто-нибудь может сказать мне что-нибудь еще, что мне нужно сделать, чтобы Android не убивал службу Foreground.

public class OnlineForeGroundService extends Service {

private static final String TAG_FOREGROUND_SERVICE = "FOREGROUND_SERVICE";
public static final String ACTION_START_FOREGROUND_SERVICE = "ACTION_START_FOREGROUND_SERVICE";
public static final String ACTION_STOP_FOREGROUND_SERVICE = "ACTION_STOP_FOREGROUND_SERVICE";

private static LocationListener locationListener;
private static LocationManager locationManager;

private PowerManager.WakeLock wakeLock;

public OnlineForeGroundService() {
}

@Override
public IBinder onBind(Intent intent) {
    // TODO: Return the communication channel to the service.
    //throw new UnsupportedOperationException("Not yet implemented");
    return null;
}

@Override
public void onCreate() {
    super.onCreate();
    Log.d(TAG_FOREGROUND_SERVICE, "My foreground service.");

    final PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
    try {
        wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "KEEP_AWAKE");
    }
    catch (Exception e){
        e.printStackTrace();
    }
}

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

        if(action != null) {
            switch (action) {
                case ACTION_START_FOREGROUND_SERVICE:
                    startForegroundService();
                    Toast.makeText(getApplicationContext(), getText(R.string.going_online), Toast.LENGTH_SHORT).show();
                    wakeLock.acquire();
                    break;
                case ACTION_STOP_FOREGROUND_SERVICE:
                    stopForegroundService();
                    //Toast.makeText(getApplicationContext(), getText(R.string.going_offline), Toast.LENGTH_SHORT).show();
                    break;
            }
        }
    }
    return super.onStartCommand(intent, flags, startId);
    //return START_STICKY;
}

/* Used to build and start foreground service. */
@SuppressLint("MissingPermission")
private void startForegroundService()
{
    if(OnlineForeGroundService.locationManager == null) {
        OnlineForeGroundService.locationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
    }


    if(OnlineForeGroundService.locationListener == null) {
        OnlineForeGroundService.locationListener = new LocationListener() {
            @Override
            public void onLocationChanged(Location location) {

                if (Common.CustomSocketOn == 1) {
                    SharedPreferences userPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());

                    if (Common.OldLatitude != 0 && Common.OldLongitude != 0) {

                        float distance[] = new float[1];
                        Location.distanceBetween(Common.OldLatitude, Common.OldLongitude, location.getLatitude(), location.getLongitude(), distance);

                        //Distance - 100
                        if (distance.length > 0 && distance[0] > 30) {
                            try {
                                JSONArray locAry = new JSONArray();
                                locAry.put(location.getLatitude());
                                locAry.put(location.getLongitude());
                                JSONObject emitobj = new JSONObject();
                                emitobj.put("coords", locAry);
                                emitobj.put("driver_name", userPref.getString("user_name", ""));
                                emitobj.put("driver_id", userPref.getString("id", ""));
                                emitobj.put("driver_status", "1"); //change by sir
                                emitobj.put("car_type", userPref.getString("car_type", ""));
                                emitobj.put("isdevice", "1");
                                emitobj.put("booking_status", userPref.getString("booking_status", ""));
                                emitobj.put("isLocationChange", 1);
                                if (location.getLatitude() != 0.0 && location.getLongitude() != 0.0 && Common.socket != null && Common.socket.connected()) {
                                    Common.socket.emit("Create Driver Data", emitobj);
                                } else if (location.getLatitude() != 0.0 && location.getLongitude() != 0.0 && Common.socket == null) {
                                    Common.socket = null;
                                    SocketSingleObject.instance = null;
                                    Common.socket = SocketSingleObject.get(getApplicationContext()).getSocket();
                                    Common.socket.connect();
                                    Common.socket.emit("Create Driver Data", emitobj);
                                } else if (location.getLatitude() != 0.0 && location.getLongitude() != 0.0 && Common.socket != null && !Common.socket.connected()) {
                                    Common.socket.connect();
                                    Common.socket.emit("Create Driver Data", emitobj);
                                }
                            } catch (JSONException e) {
                                e.printStackTrace();
                            } catch (Exception e) {
                                e.printStackTrace();
                            }

                            Common.OldLatitude = location.getLatitude();
                            Common.OldLongitude = location.getLongitude();
                        }
                    }

                    if (Common.OldLatitude == 0 && Common.OldLongitude == 0) {
                        Common.OldLatitude = location.getLatitude();
                        Common.OldLongitude = location.getLongitude();
                    }

                }
                else{
                    stopForegroundService();
                }
            }

            @Override
            public void onProviderDisabled(String provider) {
                Log.d("Latitude", "disable");
            }

            @Override
            public void onProviderEnabled(String provider) {
                Log.d("Latitude", "enable");
            }

            @Override
            public void onStatusChanged(String provider, int status, Bundle extras) {
            }
        };
    }


    if(Common.isPermission){
        if(Common.CustomSocketOn == 1){
            try {
                OnlineForeGroundService.locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, Common.DriverDistanceTime, Common.DriverDistance, OnlineForeGroundService.locationListener);
                OnlineForeGroundService.locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, Common.DriverDistanceTime, Common.DriverDistance, OnlineForeGroundService.locationListener);
            }
            catch (Exception e){
                e.printStackTrace();
            }
        }
    }



    Log.d(TAG_FOREGROUND_SERVICE, "Starting foreground service.");
    String onlineSticker = getText(R.string.app_name)+" - Online";

    Intent notificationIntent = new Intent(this, HomeActivity.class);
    notificationIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
    PendingIntent pendingIntent =
            PendingIntent.getActivity(this, 0, notificationIntent, 0);

    Notification notification;
    /*if(android.os.Build.VERSION.SDK_INT >= 26) {
        notification = new Notification.Builder(HomeActivity.class, NotificationManager.IMPORTANCE_HIGH)
                .setContentTitle(getText(R.string.app_name))
                .setContentText(getText(R.string.you_are_online))
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentIntent(pendingIntent)
                .setTicker(onlineSticker)
                .build();

        //startForeground(ONGOING_NOTIFICATION_ID, notification);

        // Start foreground service.
    }
    else{*/
        notification = new Notification.Builder(this)
                .setContentTitle(getText(R.string.app_name))
                .setContentText(getText(R.string.you_are_online))
                .setPriority(Notification.PRIORITY_HIGH)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentIntent(pendingIntent)
                .setTicker(onlineSticker)
                .build();
    //}
    startForeground(397, notification);
}

private void stopForegroundService()
{
    Toast.makeText(getApplicationContext(), getText(R.string.going_offline), Toast.LENGTH_SHORT).show();

    if(Common.isPermission){
        if(Common.CustomSocketOn == 0){
            try {
                OnlineForeGroundService.locationManager.removeUpdates(OnlineForeGroundService.locationListener);
                //OnlineForeGroundService.locationListener = null;
            }
            catch (Exception e){
                e.printStackTrace();
            }
        }
    }


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

    if (null != wakeLock && wakeLock.isHeld()) {
        wakeLock.release();
    }

    // Stop foreground service and remove the notification.
    stopForeground(true);

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

}

Вот запись androidManifest для службы и разрешение WAKE_LOCK:

<uses-permission android:name="android.permission.WAKE_LOCK" />
<service
        android:name=".driver.service.OnlineForeGroundService"
        android:process=".process"
        android:enabled="true"
        android:exported="true" ></service>

Ответы [ 2 ]

0 голосов
/ 03 июля 2019

Пожалуйста, посмотрите на этот отличный сайт, который предоставляет огромное количество информации, касающейся различных поставщиков мобильных телефонов и версий Android API.

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

https://dontkillmyapp.com/stock_android

На сайте есть упоминание о комментариях Дайан Хакборн, которые больше не используются.доступно в Google plus (в связи с окончанием срока его службы).

В конечном счете, кажется, что решение по предотвращению отключения службы Foreground может отличаться в зависимости от версии ОС Android и производителя устройства, но этот сайт предоставляет хорошийкраткое изложение шагов, которым могут следовать пользователи, а также разработчики могут реализовать (где это возможно), чтобы попытаться решить эту проблему.

0 голосов
/ 20 сентября 2018

Проверьте, как вы запускаете OnlineForeGroundService.

На Android Oreo и выше его нужно запускать с startForegroundService(Intent intent), а не startService(Intent intent)

Например что-то вроде:

final Intent serviceIntent = new Intent(context, OnlineForeGroundService.class);
serviceIntent.setAction(OnlineForeGroundService.ACTION_START_FOREGROUND_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    startForegroundService(serviceIntent);
} else {
    startService(serviceIntent);
}
...