Как получать обновления GPS-местоположения в Android - PullRequest
0 голосов
/ 14 февраля 2019

Как лучше всего получать обновления местоположения GPS в фоновом режиме в Android с помощью службы Foreground

1 Ответ

0 голосов
/ 14 февраля 2019

Всякий раз, когда приложение запускается в фоновом режиме, оно потребляет некоторые из ограниченных ресурсов устройства, например ОЗУ.Это может привести к ухудшению взаимодействия с пользователем, особенно если пользователь использует ресурсоемкое приложение, такое как игра или просмотр видео.Чтобы улучшить взаимодействие с пользователем, Android 8.0 (уровень API 26) накладывает ограничения на возможности приложений в фоновом режиме.

  • Вы можете использовать службу Foreground Service и канал уведомлений для обновлений местоположения в фоновом режиме,он будет отлично работать на уровне выше и ниже уровня Api 26.
  • Я разработал приведенный ниже код, и он отлично работает на моей стороне.

    Надеюсь, это поможет вам

(1) Пожалуйста, поместите ниже строку кода в файле Manifest.xml вашего проекта

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application>
<service
        android:name="com.yourpackagename.location.LocationTracker"
        android:stopWithTask="true"
        />
</application>

(2) в файле app.gradle

implementation 'com.google.android.gms:play-services-location:16.0.0'

(2) Пожалуйста, поместите ниже код класса линии обслуживания в вашем проекте и можете сохранить результат местоположения (широта, долгота) в общих настройках или статической переменной, а также можете привязать службу там, где нужно

public class LocationTracker extends Service implements
        GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener {

    private static final long UPDATE_INTERVAL_IN_MILLISECONDS = 1000;
    private static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = 1000;
    private static int DISPLACEMENT = 0;

    private FusedLocationProviderClient mFusedLocationClient;
    private LocationRequest mLocationRequest;
    private SettingsClient mSettingsClient;
    private LocationSettingsRequest mLocationSettingsRequest;
    private LocationCallback mLocationCallback;

    private String TAG = LocationTracker.class.getSimpleName();
    private GoogleApiClient mGoogleApiClient;

    private final int NOTIFICATION_ID = 9083150;
    private final String CHANNEL_ID = "test123";
    private final String CHANNEL_ID_NAME = "test123";

    @Override
    public void onCreate() {
        super.onCreate();
        try {
            if (Build.VERSION.SDK_INT >= 26) {
                NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_ID_NAME,
                        NotificationManager.IMPORTANCE_HIGH);
                channel.setSound(null, null);
                channel.setShowBadge(false);
                NotificationManager notificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
                notificationManager.deleteNotificationChannel(Constant.CHANNEL_ID);
                notificationManager.createNotificationChannel(channel);

                Notification notification = createNotification(getApplicationContext(),Constant.CHANNEL_ID,0);
                if (notification == null) {
                    notification = new NotificationCompat.Builder(this, Constant.CHANNEL_ID).build();
                }
                startForeground(NOTIFICATION_ID, notification);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private Notification createNotification(Context context, String channelid,int type) {
        try {
            return new NotificationCompat.Builder(context,channelid)
                    .setContentText("TEST")
                    .setOnlyAlertOnce(true)
                    .setOngoing(true)
                    .setPriority(NotificationCompat.PRIORITY_HIGH)
                    .setSmallIcon(R.mipmap.ic_launcher)
                    .build();

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    public void setLocationUpdateCallback() {
        try {
            mLocationCallback = null;
            mLocationCallback = new LocationCallback() {
                @Override
                public void onLocationResult(LocationResult locationResult) {
                    super.onLocationResult(locationResult);
                    Logger.i(TAG, "locationResult ==== " + locationResult);
                    //You can put location in sharedpreferences or static varibale and can use in app where need
                }

                @Override
                public void onLocationAvailability(LocationAvailability locationAvailability) {
                    super.onLocationAvailability(locationAvailability);
                }
            };
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    private void init() {
        try {
            setLocationUpdateCallback();
            buildGoogleApiClient();
            mFusedLocationClient = null;
            mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
            mSettingsClient = LocationServices.getSettingsClient(this);

            mLocationRequest = null;
            mLocationRequest = new LocationRequest();
            mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
            mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
            mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
            mLocationRequest.setSmallestDisplacement(DISPLACEMENT);

            LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
            builder.addLocationRequest(mLocationRequest);
            mLocationSettingsRequest = null;
            mLocationSettingsRequest = builder.build();

        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    protected synchronized void buildGoogleApiClient() {
        try {
            mGoogleApiClient = null;
            mGoogleApiClient = new GoogleApiClient.Builder(this)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .addApi(LocationServices.API).build();

            mGoogleApiClient.connect();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        init();
        return START_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {
        startLocationUpdates();
    }

    public void requestingLocationUpdates() {
        try {
            mFusedLocationClient.requestLocationUpdates(mLocationRequest,
                    mLocationCallback, Looper.myLooper());
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    protected void startLocationUpdates() {
        try {
            if (mGoogleApiClient != null) {
                mSettingsClient
                        .checkLocationSettings(
                                mLocationSettingsRequest)
                        .addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>() {
                            @SuppressLint("MissingPermission")
                            @Override
                            public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
                                Log.e(TAG, "LocationSettingsStatusCodes onSuccess");
                                requestingLocationUpdates();
                            }
                        })
                        .addOnFailureListener(new OnFailureListener() {
                            @Override
                            public void onFailure(@NonNull Exception e) {
                                int statusCode = ((ApiException) e).getStatusCode();
                                switch (statusCode) {
                                    case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                                        Log.e(TAG, "LocationSettingsStatusCodes.RESOLUTION_REQUIRED");
                                        requestingLocationUpdates();
                                        break;
                                    case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                                        Log.e(TAG, "LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE");
                                }
                            }
                        });
            }

        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

    }

    @Override
    public void onDestroy() {
        WakeLocker.releasePartialLock();
        super.onDestroy();
    }

    @Override
    public void onTaskRemoved(Intent rootIntent) {
        super.onTaskRemoved(rootIntent);
    }

    public void stopLocationService(Context context) {        
        try {      
            stopForeground(true);
            stopSelf();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void startLocationService(Context context) {
        try {
            Intent intent = new Intent(context, LocationTracker.class);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                ContextCompat.startForegroundService(context, intent);
            } else {
                context.startService(intent);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
...