代码之家  ›  专栏  ›  技术社区  ›  NoWar

Android 6.0.0中onStartCommand的START\u STICKY

  •  1
  • NoWar  · 技术社区  · 7 年前

    我正在使用一些启动 服务 .

    当我在下关闭应用程序时 安卓7.0.0的服务仍然运行良好。

    但在安卓6.0.0下,情况并非如此。

    我使用这个片段来保持服务的有效性

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
     // We want this service to continue running until it is explicitly
     // stopped, so return sticky.
    
     return START_STICKY;
    }
    

    我错过了什么?

    服务类别代码

    import android.Manifest;
    //import android.app.LoaderManager;
    import android.app.Service;
    import android.content.Context;
    import android.content.Intent;
    import android.content.pm.PackageManager;
    import android.location.Location;
    import android.location.LocationListener;
    import android.location.LocationManager;
    //import android.os.Bundle;
    import android.os.Handler;
    import android.os.HandlerThread;
    import android.os.IBinder;
    import android.os.Looper;
    //import android.provider.Settings;
    import android.support.annotation.NonNull;
    import android.support.annotation.Nullable;
    import android.support.v4.app.ActivityCompat;
    //import android.support.v4.content.ContextCompat;
    //import android.telephony.TelephonyManager;
    import android.text.format.DateFormat;
    import android.util.Log;
    
    import com.google.android.gms.location.FusedLocationProviderClient;
    import com.google.android.gms.location.LocationCallback;
    import com.google.android.gms.location.LocationRequest;
    import com.google.android.gms.location.LocationResult;
    import com.google.android.gms.location.LocationServices;
    import com.google.android.gms.location.LocationSettingsRequest;
    import com.google.android.gms.location.SettingsClient;
    import com.google.android.gms.tasks.OnFailureListener;
    import com.google.android.gms.tasks.OnSuccessListener;
    import com.google.gson.Gson;
    
    import java.util.Date;
    import java.util.Timer;
    //import java.util.TimerTask;
    import java.io.*;
    import java.net.*;
    //import java.util.Timer;
    //import java.util.TimerTask;
    
    import static com.google.android.gms.location.LocationServices.getFusedLocationProviderClient;
    
    
    public class gps_service extends Service {
    
        private static final String TAG = "MyService";
        private LocationListener listener;
        private LocationManager locationManager;
        private Timer timer = new Timer();
        // private DLocation dLocation;
        private final Object lock = new Object();
        Context context;
    
        private LocationRequest mLocationRequest;
        private long UPDATE_INTERVAL = 60 * 1000;  /* 60 secs */
        private long FASTEST_INTERVAL = 10000; /* 10 sec */
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            // We want this service to continue running until it is explicitly
            // stopped, so return sticky.
    
            startLocationUpdates();
    
            return START_STICKY;
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
            context = this;
    
        }
    
        // Trigger new location updates at interval
        protected void startLocationUpdates() {
    
            // Create the location request to start receiving updates
            mLocationRequest = new LocationRequest();
            mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
            mLocationRequest.setInterval(UPDATE_INTERVAL);
            mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
    
            // Create LocationSettingsRequest object using location request
            LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
            builder.addLocationRequest(mLocationRequest);
            LocationSettingsRequest locationSettingsRequest = builder.build();
    
            // Check whether location settings are satisfied
            // https://developers.google.com/android/reference/com/google/android/gms/location/SettingsClient
            SettingsClient settingsClient = LocationServices.getSettingsClient(this);
            settingsClient.checkLocationSettings(locationSettingsRequest);
    
            // new Google API SDK v11 uses getFusedLocationProviderClient(this)
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
    
                return;
            }
    
    
            getFusedLocationProviderClient(this).requestLocationUpdates(mLocationRequest, new LocationCallback() {
                        @Override
                        public void onLocationResult(LocationResult locationResult) {
                            // do work here
                            onLocationChanged(locationResult.getLastLocation());
                        }
                    }, Looper.myLooper());
        }
    
        public void getLastLocation() {
            // Get last known recent location using new Google Play Services SDK (v11+)
            FusedLocationProviderClient locationClient = getFusedLocationProviderClient(this);
    
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                return;
            }
    
            locationClient.getLastLocation()
                    .addOnSuccessListener(new OnSuccessListener<Location>() {
                        @Override
                        public void onSuccess(Location location) {
                            // GPS location can be null if GPS is switched off
                            if (location != null) {
                                onLocationChanged(location);
                            }
                        }
                    })
                    .addOnFailureListener(new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {
                            Log.d(TAG, "Ошибка получения последнего GPS позиции");
                            e.printStackTrace();
                        }
                    });
        }
    
        public void onLocationChanged(Location location) {
            // New location has now been determined
            try
            {
                ComplexPreferences complexPreferences = ComplexPreferences.getComplexPreferences(context, "App_Settings", 0);
                AppSettings appSettings = complexPreferences.getObject("App_Settings", AppSettings.class);
                if (appSettings != null) {
    
                    LocationItem locationItem = new LocationItem();
                    locationItem.DeviceID = appSettings.getDeviceID();
                    locationItem.Latitude =  Double.toString(location.getLatitude());
                    locationItem.Longitude = Double.toString(location.getLongitude());
                    Date d = new Date();
                    CharSequence timeOfRequest = DateFormat.format("yyyy-MM-dd HH:mm:ss", d.getTime()); // YYYY-MM-DD HH:mm:ss
                    locationItem.TimeOfRequest = timeOfRequest.toString();
                    locationItem.SerialNumber = appSettings.getSerialNumber();
    
                    //**************** Отправка сообщения в окно *********************
                    Intent i = new Intent("location_update");
                    Log.d(TAG, "Рассылка по слушателям в окнах");
                    DLocation dLocation = new  DLocation();
                    dLocation.Latitude = locationItem.Latitude;
                    dLocation.Longitude = locationItem.Longitude;
                    dLocation.TimeOfRequest = locationItem.TimeOfRequest;
                    dLocation.Errors = "Данные передаются...";
                    i.putExtra("coordinates", dLocation);
                    sendBroadcast(i);
                    //**************** Отправка сообщения в окно *********************
    
                    Gson gson = new Gson();
                    String requestObject = gson.toJson(locationItem);
                    Log.d(TAG, "Формирование URL API сервера");
                    String url = appSettings.getIpAddress() + "/api/staff/savedata";
                    makeRequest(url, requestObject, dLocation);
                }
            }
            catch (Exception ex)
            {
                Log.d(TAG, "Ошибка: " + ex.getMessage());
            }
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
            if (locationManager != null) {
                locationManager.removeUpdates(listener);
            }
        }
    
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    
    
        public void makeRequest(String uri, String json, DLocation dLocation) {
    
            HandlerThread handlerThread = new HandlerThread("URLConnection");
            handlerThread.start();
            Handler mainHandler = new Handler(handlerThread.getLooper());
    
            Runnable myRunnable = createRunnable(uri, json, dLocation);
    
            mainHandler.post(myRunnable);
        }
    
        private Runnable createRunnable(final String uri, final String data,final DLocation dLocation){
    
            Runnable aRunnable = new Runnable(){
                public void run(){
                    try {
                        Log.d(TAG, "Перед запросом HTTP");
    
                        //Connect
                        HttpURLConnection urlConnection;
                        urlConnection = (HttpURLConnection) ((new URL(uri).openConnection()));
                        urlConnection.setDoOutput(true);
                        urlConnection.setRequestProperty("Content-Type", "application/json");
                        urlConnection.setRequestProperty("Accept", "application/json");
                        urlConnection.setRequestMethod("POST");
                        urlConnection.connect();
    
                        //Write
                        OutputStream outputStream = urlConnection.getOutputStream();
                        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
                        try {
                            writer.write(data);
                        } catch (IOException e) {
                            e.printStackTrace();
                            Log.d(TAG,"Ошибка записи в буфер для пережачи по HTTP");
                        }
                        writer.close();
                        outputStream.close();
    
                        //Read
                        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "UTF-8"));
    
                        String line = null;
                        StringBuilder sb = new StringBuilder();
    
                        while ((line = bufferedReader.readLine()) != null) {
                            sb.append(line);
                        }
    
                        bufferedReader.close();
                        String result = sb.toString();
    
                        Log.d(TAG, "После запроса HTTP");
                        Log.d(TAG, result);
    
                        // Log.d(TAG, "Результат передачи: " + result);
                        //**************** Отправка сообщения в окно *********************
                        Intent iResult = new Intent("location_update");
                        Log.d(TAG, "Рассылка по слушателям в окнах");
                        DLocation dLocation = new DLocation();
                        if(result.equals("true"))
                        {
                            dLocation.Errors = "Данные успешно переданы.";
                        }
                        else
                        {
                            dLocation.Errors = "Ошибка передачи данных.";
                        }
                        iResult.putExtra("result", dLocation);
                        sendBroadcast(iResult);
                        //**************** Отправка сообщения в окно *********************
    
                    }catch( Exception err){
                        err.printStackTrace();
                        Log.d(TAG, "Ошибка HTTP " + err.getMessage());
                    }
                }
            };
    
            return aRunnable;
    
        } 
    }
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   ADM    7 年前

    使用属性 android:stopWithTask=“false”

    <service
            android:name=".gps_service"
            android:enabled="true"
            android:stopWithTask="false"/>
    

    在onTaskRemoved()上重新启动服务。

     @Override
    public void onTaskRemoved(Intent rootIntent) {
            Intent restartService = new Intent(getApplicationContext(),
                    this.getClass());
            restartService.setPackage(getPackageName());
            PendingIntent restartServicePI = PendingIntent.getService(
                    getApplicationContext(), 1, restartService,
                    PendingIntent.FLAG_ONE_SHOT);
            AlarmManager alarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
            alarmService.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + 1000, restartServicePI);
    }
    

    正如文件所述

    如果服务当前正在运行,并且用户已删除来自服务应用程序的任务,则将调用onTaskRemoved。如果您已设置ServiceInfo。将_STOP_标记为_TASK,则您将不会收到此回调;相反,服务将简单地停止。