Отслеживание местоположения в Oreo и более поздних версиях с помощью IntentService - PullRequest
0 голосов
/ 06 мая 2019

Я работаю над приложением отслеживания местоположения.Мне нужно выбирать местоположение пользователя при каждом смещении 500 метров или каждые 30 минут.Я создал службу переднего плана и возвратил START_STICKY для метода onStartCommand.Отслеживание работает отлично, пока приложение не будет очищено от последних приложений.Если я очистил свое приложение от раздела недавних приложений, то передний план также удалялся из фона.как я могу сделать его липким там навсегда?

Примечание. Это отслеживание местоположения выполняется с ведомом пользователя.

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Temp.msg(TAG, "onStartCommand");

    startMyOwnForeground();
    return START_STICKY;
} 


private void startMyOwnForeground() {
    String NOTIFICATION_CHANNEL_ID = Temp.getNotificationChannelId();
    String channelName = Temp.getNotificationChannelName();
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
        NotificationChannel chan = null;
        chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_NONE);

        chan.setLightColor(Color.BLUE);
        chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
        NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        assert manager != null;
        manager.createNotificationChannel(chan);
    }
    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
    Notification notification = notificationBuilder.setOngoing(true)
            .setSmallIcon(R.drawable.ic_push_notifications)
            .setContentTitle("Checked In")
            .setPriority(NotificationManager.IMPORTANCE_HIGH)
            .setCategory(Notification.CATEGORY_SERVICE)
            .build();
    startForeground(1, notification);
}

Примечание. Я пробовал START_STICKY и START_NOT_STICKY в методе onStartCommand, но оба они были удалены из фона при удалении приложения.из последних приложений

Ответы [ 2 ]

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

Я нашел, почему приложение удаляет из фона.Это была не проблема моего кода.Это произошло потому, что я использовал телефон Redmi.В телефонах Redmi требуется дополнительное разрешение (разрешение AutoStart) в настройках телефона Redmi.Вы можете получить больше информации об этом из Служба Foreground убита из Oreo

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

Пожалуйста, попробуйте так:

Запуск службы

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
     ContextCompat.startForegroundService(MainActivity.this, new Intent(MainActivity.this, ServiceLocation.class));
 } else {
     startService(new Intent(MainActivity.this, ServiceLocation.class));
 }

Класс обслуживания

public class ServiceLocation extends Service implements
        GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener,
        LocationListener {

    private static final String NOTIFICATION_CHANNEL_ID = "my_notification_location";
    private static final long TIME_INTERVAL_GET_LOCATION = 1000 * 5; // 1 Minute
    private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 7; // meters

    private Handler handlerSendLocation;
    private Context mContext;

    private GoogleApiClient mGoogleApiClient;
    private LocationRequest mLocationRequest;

    private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 5000;

    Location locationData;

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

        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();

        // Create the LocationRequest object
        mLocationRequest = LocationRequest.create()
                .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
                .setInterval(TIME_INTERVAL_GET_LOCATION)    // 3 seconds, in milliseconds
                .setFastestInterval(TIME_INTERVAL_GET_LOCATION); // 1 second, in milliseconds

        mContext = this;


        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
                .setOngoing(false)
                .setSmallIcon(R.drawable.ic_notification)
                .setColor(getResources().getColor(R.color.fontColorDarkGray))
                .setPriority(Notification.PRIORITY_MIN);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID,
                    NOTIFICATION_CHANNEL_ID, NotificationManager.IMPORTANCE_LOW);
            notificationChannel.setDescription(NOTIFICATION_CHANNEL_ID);
            notificationChannel.setSound(null, null);
            notificationManager.createNotificationChannel(notificationChannel);
            startForeground(1, builder.build());
        }
    }

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

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        Log.w("Service Update Location", "BGS > Started");

        if (handlerSendLocation == null) {
            handlerSendLocation = new Handler();
            handlerSendLocation.post(runnableSendLocation);
            Log.w("Service Send Location", "BGS > handlerSendLocation Initialized");
        } else {
            Log.w("Service Send Location", "BGS > handlerSendLocation Already Initialized");
        }

        return START_STICKY;
    }

    private Runnable runnableSendLocation = new Runnable() {

        @Override
        public void run() {
            Log.w("Service Send Location", "BGS >> Location Updated");

            // You can get Location
            //locationData and Send Location X Minutes
            if (locationData != null) {

                Log.w("==>UpdateLocation<==", "" + String.format("%.6f", locationData.getLatitude()) + "," +
                        String.format("%.6f", locationData.getLongitude()));


            }
            if (handlerSendLocation != null && runnableSendLocation != null)
                handlerSendLocation.postDelayed(runnableSendLocation, TIME_INTERVAL_GET_LOCATION);
        }
    };


    @Override
    public void onConnected(@Nullable Bundle bundle) {
        if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
                ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

            return;
        }


        FusedLocationProviderClient mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
        mFusedLocationClient.requestLocationUpdates(mLocationRequest, new LocationCallback() {
            @Override
            public void onLocationResult(LocationResult locationResult) {
                locationData = locationResult.getLastLocation();
            }
        }, null);
    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
        if (connectionResult.hasResolution() && mContext instanceof Activity) {
            try {
                Activity activity = (Activity) mContext;
                connectionResult.startResolutionForResult(activity, CONNECTION_FAILURE_RESOLUTION_REQUEST);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            Log.i("", "Location services connection failed with code " + connectionResult.getErrorCode());
        }
    }

    @Override
    public void onLocationChanged(Location location) {
        Log.w("==>UpdateLocation<==", "" + String.format("%.6f", location.getLatitude()) + "," + String.format("%.6f", location.getLongitude()));
        locationData = location;

    }

    @Override
    public void onDestroy() {

        if (handlerSendLocation != null)
            handlerSendLocation.removeCallbacks(runnableSendLocation);


        Log.w("Service Update Info", "BGS > Stopped");

        stopSelf();
        super.onDestroy();
    }


}

AndroidManifest.XML

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

<service
            android:name=".ServiceLocation"
            android:enabled="true"
            android:exported="true" />
...