Android中的后台位置定期更新

时间:2018-04-04 08:18:57

标签: android google-location-services

我正在使用Fused Location Provider Google api客户端每隔5分钟获取一次该位置。它在后台以及应用程序被杀死时都会更新。但它在2到3天后停止更新。我已在大多数Android设备上测试过。

我正在从一个活动中调用此服务,我正在杀死该应用程序,它将在5天后每隔5分钟发送一次位置更新,因为它已经停止。我试了很多次。

公共类GPSTracker扩展了Service实现         GoogleApiClient.ConnectionCallbacks,GoogleApiClient.OnConnectionFailedListener,com.google.android.gms.location.LocationListener {     protected static final String TAG =“Location ...”;     private Context mContext = this;

/**
 * Tracks the status of the location updates request.
 */
public static Boolean mRequestingLocationUpdates;
/**
 * Time when the location was updated represented as a String.
 */
protected String mLastUpdateTime;
/**
 * Provides the entry point to Google Play services.
 */
protected GoogleApiClient mGoogleApiClient;
/**
 * Stores parameters for requests to the FusedLocationProviderApi.
 */
protected LocationRequest mLocationRequest;

/**
 * Represents a geographical location.
 */
protected Location mCurrentLocation;
public static boolean isEnded = false;


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

    buildGoogleApiClient();
}

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


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

    Log.d("LOC", "Service init...");
    isEnded = false;
    mRequestingLocationUpdates = false;
    mLastUpdateTime = "";
    // buildGoogleApiClient();
    if (mGoogleApiClient.isConnected() && mRequestingLocationUpdates) {
        startLocationUpdates();
    }
    return START_STICKY;
}




@Override
public void onConnected(Bundle bundle) {

    startLocationUpdates();
}

@Override
public void onConnectionSuspended(int i) {
    // The connection to Google Play services was lost for some reason. We call connect() to
    // attempt to re-establish the connection.
    Log.i(TAG, "Connection suspended==");
    mGoogleApiClient.connect();
}

@Override
public void onLocationChanged(Location location) {
    mCurrentLocation = location;
    mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
    double latitude = location.getLatitude();
    double longitude = location.getLongitude();

    StringBuilder stringBuilder = new StringBuilder();
    StringBuilder latlong = stringBuilder.append(latitude + "," + longitude);

    Calendar cal = Calendar.getInstance();
    String zone = TimeZone.getDefault().getDisplayName(false, android.icu.util.TimeZone.SHORT);
    SimpleDateFormat formatter = new SimpleDateFormat("dd-MMM 'at' h:mm a");
    Date date = new Date();
    String localtime = (formatter.format(date)).toString();

    Date myDate = new Date();

    Calendar calendar = Calendar.getInstance();
    calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
    calendar.setTime(myDate);
    date = calendar.getTime();
    SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss zz");
    dateFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
    String utc = dateFormatter.format(date);

  //  DateFormat df = DateFormat.getTimeInstance();
  //  df.setTimeZone(TimeZone.getTimeZone("gmt"));
  //  String gmtTime = df.format(new Date());

    String model = Build.MODEL;

    String reqString = Build.VERSION.RELEASE
            + " " + Build.VERSION_CODES.class.getFields()[android.os.Build.VERSION.SDK_INT].getName();

    // Date currentTime = Calendar.getInstance().getTime();
    // String localtime = currentTime.toString();

    PreferencesClass preferencesClass = new PreferencesClass(mContext);
    String id = preferencesClass.getFingerPrint();

    Data data = null;
    try {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("userId", id);
        jsonObject.put("latLon", latlong);
        jsonObject.put("timeZone", zone);
        jsonObject.put("localTime", localtime);
        jsonObject.put("osVersion",reqString);
        jsonObject.put("phoneModel",model);
        jsonObject.put("utcTime",utc);
        data = new Data();
        data.setData(jsonObject.toString());

        if (data != null) {

            if (Utility.isConnectingToInternet(mContext)) {

               // boolean isChecked = preferencesClass.getIsChecked();
              //  if (isChecked){

                    LocationWebServiceMgr locationWebServiceMgr = new LocationWebServiceMgr();
                    locationWebServiceMgr.Location(data, new CallBackInterface() {
                        @Override
                        public void onResponse(ArrayList<Object> objects, ResponseMetaData responseMetaData) {

                            Log.d(TAG, "onResponse: Succesfully added the location to server");
                            // Toast.makeText(getApplicationContext(), "added to server", Toast.LENGTH_LONG).show();
                        }

                        @Override
                        public void onFailure(ResponseMetaData t) {
                        }
                    });

               // } else {
                 //   Log.d("serverCall", "Location Permission not available ");

              //  }

            } else {

                Log.e("serverCall", "Network not available");

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

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
    // Refer to the javadoc for ConnectionResult to see what error codes might be returned in
    // onConnectionFailed.
    Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + connectionResult.getErrorCode());
}

/**
 * Builds a GoogleApiClient. Uses the {@code #addApi} method to request the
 * LocationServices API.
 */
protected synchronized void buildGoogleApiClient() {
    Log.i(TAG, "Building GoogleApiClient===");
    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();

    createLocationRequest();
}

/**
 * Sets up the location request. Android has two location request settings:
 * {@code ACCESS_COARSE_LOCATION} and {@code ACCESS_FINE_LOCATION}. These settings control
 * the accuracy of the current location. This sample uses ACCESS_FINE_LOCATION, as defined in
 * the AndroidManifest.xml.
 * <p/>
 * When the ACCESS_FINE_LOCATION setting is specified, combined with a fast update
 * interval (5 seconds), the Fused Location Provider API returns location updates that are
 * accurate to within a few feet.
 * <p/>
 * These settings are appropriate for mapping applications that show real-time location
 * updates.
 */
protected void createLocationRequest() {
    mGoogleApiClient.connect();
    mLocationRequest = new LocationRequest();

    // Sets the desired interval for active location updates. This interval is
    // inexact. You may not receive updates at all if no location sources are available, or
    // you may receive them slower than requested. You may also receive updates faster than
    // requested if other applications are requesting location at a faster interval.
    mLocationRequest.setInterval(Constants.UPDATE_INTERVAL_IN_MILLISECONDS);

    // Sets the fastest rate for active location updates. This interval is exact, and your
    // application will never receive updates faster than this value.
    mLocationRequest.setFastestInterval(Constants.FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);

   // mLocationRequest.setSmallestDisplacement(Constants.DISPLACEMENT);

    //mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}

/**
 * Requests location updates from the FusedLocationApi.
 */
protected void startLocationUpdates() {
    if (!mRequestingLocationUpdates) {
        mRequestingLocationUpdates = true;

        // The final argument to {@code requestLocationUpdates()} is a LocationListener
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        LocationServices.FusedLocationApi.requestLocationUpdates(
                mGoogleApiClient, mLocationRequest, this);
        Log.i(TAG, " startLocationUpdates===");
        isEnded = true;
    }
}

}

4 个答案:

答案 0 :(得分:0)

您可以为此创建服务

public class MyService extends Service
{
    private static final String TAG = "BOOMBOOMTESTGPS";
    private LocationManager mLocationManager = null;
    private static final int LOCATION_INTERVAL = 1000;
    private static final float LOCATION_DISTANCE = 10f;

    private class LocationListener implements android.location.LocationListener
    {
        Location mLastLocation;

        public LocationListener(String provider)
        {
            Log.e(TAG, "LocationListener " + provider);
            mLastLocation = new Location(provider);
        }

        @Override
        public void onLocationChanged(Location location)
        {
            Log.e(TAG, "onLocationChanged: " + location);
            mLastLocation.set(location);
        }

        @Override
        public void onProviderDisabled(String provider)
        {
            Log.e(TAG, "onProviderDisabled: " + provider);
        }

        @Override
        public void onProviderEnabled(String provider)
        {
            Log.e(TAG, "onProviderEnabled: " + provider);
        }

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras)
        {
            Log.e(TAG, "onStatusChanged: " + provider);
        }
    }

    LocationListener[] mLocationListeners = new LocationListener[] {
            new LocationListener(LocationManager.GPS_PROVIDER),
            new LocationListener(LocationManager.NETWORK_PROVIDER)
    };

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

    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {
        Log.e(TAG, "onStartCommand");
        super.onStartCommand(intent, flags, startId);
        return START_STICKY;
    }

    @Override
    public void onCreate()
    {
        Log.e(TAG, "onCreate");
        initializeLocationManager();
        try {
            mLocationManager.requestLocationUpdates(
                    LocationManager.NETWORK_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
                    mLocationListeners[1]);
        } catch (java.lang.SecurityException ex) {
            Log.i(TAG, "fail to request location update, ignore", ex);
        } catch (IllegalArgumentException ex) {
            Log.d(TAG, "network provider does not exist, " + ex.getMessage());
        }
        try {
            mLocationManager.requestLocationUpdates(
                    LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
                    mLocationListeners[0]);
        } catch (java.lang.SecurityException ex) {
            Log.i(TAG, "fail to request location update, ignore", ex);
        } catch (IllegalArgumentException ex) {
            Log.d(TAG, "gps provider does not exist " + ex.getMessage());
        }
    }

    @Override
    public void onDestroy()
    {
        Log.e(TAG, "onDestroy");
        super.onDestroy();
        if (mLocationManager != null) {
            for (int i = 0; i < mLocationListeners.length; i++) {
                try {
                    mLocationManager.removeUpdates(mLocationListeners[i]);
                } catch (Exception ex) {
                    Log.i(TAG, "fail to remove location listners, ignore", ex);
                }
            }
        }
    }

    private void initializeLocationManager() {
        Log.e(TAG, "initializeLocationManager");
        if (mLocationManager == null) {
            mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
        }
    }
}

和位置服务

import {Pipe, PipeTransform} from '@angular/core';

@Pipe({name: 'statusClass'})
export class StatusClassPipe implements PipeTransform {
  transform(statusCode: string): string {
    switch (statusCode) { 
      case 'NEW':
        return 'label label-primary';
      case 'CONFIRMED':
        return 'label label-success';
      case 'CANCELLED':
        return 'label label-danger';
      case 'CONCLUDED':
        return 'label label-default';
      default:
        return '';
    }
  }
}

答案 1 :(得分:0)

使用workmanager重新安排您的位置服务。检查定位服务是否未运行,然后从调度程序启动。 阅读有关工作经理click here

的更多信息

答案 2 :(得分:-1)

为此,您可以使用AlarmManagerfirebase jobdispatcherjob scheduler在特定时间间隔后触发任何事件。我建议你使用最简单的 AlarmManager

请参阅此代码以设置闹钟:

  Calendar calendar = Calendar.getInstance();
  calendar.setTimeInMillis(System.currentTimeMillis());
  int notificationID = 2018;

 AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
 Intent intent = new Intent(this, AlarmReceiver.class);
 PendingIntent pendingIntent = PendingIntent.getBroadcast(this, notificationID, intent, PendingIntent.FLAG_UPDATE_CURRENT);
 alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),5*1000, pendingIntent);

你可以像这样取消闹钟

    AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
    Intent intent = new Intent(this, AlarmReceiver.class);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(this, notificationID, intent, PendingIntent.FLAG_CANCEL_CURRENT);
    alarmManager.cancel(pendingIntent);
    pendingIntent.cancel();

注意:从API 19开始(KITKAT)警报传递不准确:操作系统将移动警报以最小化唤醒和电池使用。有新的API支持需要严格交付保证的应用程序;请参阅setWindow(int,long,long,PendingIntent)和setExact(int,long,PendingIntent)。 targetSdkVersion早于API 19的应用程序将继续查看之前在请求时准确传递所有警报的行为。

答案 3 :(得分:-1)

为location get创建一个类。

 private class LocationListener implements android.location.LocationListener
{
    Location mLastLocation;

    public LocationListener(String provider)
    {
        Log.e(TAG, "LocationListener " + provider);
        mLastLocation = new Location(provider);
    }

    @Override
    public void onLocationChanged(Location location)
    {
        Log.e(TAG, "onLocationChanged: " + location);
        mLastLocation.set(location);
    }

    @Override
    public void onProviderDisabled(String provider)
    {
        Log.e(TAG, "onProviderDisabled: " + provider);
    }

    @Override
    public void onProviderEnabled(String provider)
    {
        Log.e(TAG, "onProviderEnabled: " + provider);
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras)
    {
        Log.e(TAG, "onStatusChanged: " + provider);
    }
}

在onLocation(位置位置)更改方法中,您将获得当前let,long