【问题标题】:Why my service for locations bugs when GPS is off?为什么我的位置服务在 GPS 关闭时出现错误?
【发布时间】:2017-01-28 11:01:24
【问题描述】:

我正在构建一个应用程序,我在其中使用位置服务。我在 MainActivity 的 onCreate 中启动该服务,但如果 GPS 关闭,我的服务将不会查找纬度和经度。即使在那之后我打开 GPS,我的服务也不会看起来很长。只有当我在启动服务(和 MainActivity)之前打开 GPS 时,服务才能正常工作并且它会寻找位置。我应该改变什么来设置我的服务在我在应用程序中花费一段时间后打开 GPS 时不会出错? 这是我的定位服务:

public class LocationUpdateService extends Service implements LocationListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
protected static final String TAG = "LocationUpdateService";
public static final long UPDATE_INTERVAL_IN_MILLISECONDS = 30000;
public static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = UPDATE_INTERVAL_IN_MILLISECONDS / 2;
public static Boolean mRequestingLocationUpdates;
protected String mLastUpdateTime;
protected String timeWhenStartLocationUpdates;
protected String timeWhenStopLocationUpdates;
protected String timeWhenServiceDestroyed;
protected String connectionFailed;
protected GoogleApiClient mGoogleApiClient;
protected LocationRequest mLocationRequest;
protected Location mCurrentLocation;
protected String timeWhenGetInGetLatLong;
protected String report_time;
protected String timeFromElse;
public static boolean isEnded = false;
Calendar calendar;


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

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

@Override
public void onConnectionSuspended(int i) {
    Log.i(TAG, "Connection suspended==");
    mGoogleApiClient.connect();
}

@Override
public void onLocationChanged(Location location) {
    mCurrentLocation = location;
    mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
    Log.d("mCurrentLocation", "Location is: " + location);
    getLatLong();
    SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences("user_location", MODE_PRIVATE);
    SharedPreferences.Editor editor = sharedPreferences.edit();
    editor.putString("TimeWhenCameToOnLocationChanged", mLastUpdateTime);
    editor.apply();
    Log.d("onLocationchanged", "OnLocationChangedInServiceLocation");
    Log.d("Time ", "Time of lat and long from Service: " + mLastUpdateTime);
}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
    connectionFailed = DateFormat.getTimeInstance().format(new Date());
    SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences("user_location", MODE_PRIVATE);
    SharedPreferences.Editor editor = sharedPreferences.edit();
    editor.putString("connectionFailed", connectionFailed);
    editor.apply();
    Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + connectionResult.getErrorCode());
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Log.d("LOC", "Service init...");
    return Service.START_STICKY;
}

protected synchronized void buildGoogleApiClient() {
    Log.i(TAG, "Building GoogleApiClient===");
    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addApi(LocationServices.API)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .build();
    createLocationRequest();
}

public void getLatLong() {
    timeWhenGetInGetLatLong = DateFormat.getTimeInstance().format(new Date());

    if (mCurrentLocation != null && mLastUpdateTime != null) {

        String lat = String.valueOf(mCurrentLocation.getLatitude());
        String lng = String.valueOf(mCurrentLocation.getLongitude());
        calendar = Calendar.getInstance();
        @SuppressLint("SimpleDateFormat") SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.sss");
        simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
        report_time = simpleDateFormat.format(calendar.getTime());
        Log.d("preferences", "Time stored in preferences: " + mLastUpdateTime);
        SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences("user_location", MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putString("user_latitude", lat);
        editor.putString("user_longitude", lng);
        editor.putString("getLatLongIf", "ok");
        editor.putString("report_time_for_location_response", report_time);
        editor.putString("time_when_comes_to_getLatLong", timeWhenGetInGetLatLong);
        editor.apply();
    }else{
        timeFromElse = DateFormat.getTimeInstance().format(new Date());
        SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences("user_location", MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putString("getLatLongElse", timeFromElse);
        editor.apply();
    }
}

protected void createLocationRequest() {
    mGoogleApiClient.connect();
    mLocationRequest = new LocationRequest();
    mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
    mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}

protected void startLocationUpdates() {
    timeWhenStartLocationUpdates = DateFormat.getTimeInstance().format(new Date());
    if (!mRequestingLocationUpdates) {
        mRequestingLocationUpdates = true;
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

            return;
        }
        LocationServices.FusedLocationApi.requestLocationUpdates(
                mGoogleApiClient, mLocationRequest, this);
        SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences("user_location", MODE_PRIVATE);
       SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putString("startLocationUpdates", timeWhenStartLocationUpdates);
        editor.apply();
        Log.i("startUpdates", " startLocationUpdates===" + timeWhenStartLocationUpdates);
        isEnded = true;
    }
}
protected void stopLocationUpdates() {
    if (mRequestingLocationUpdates) {
        mRequestingLocationUpdates = false;
        timeWhenStopLocationUpdates = DateFormat.getTimeInstance().format(new Date());
        SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences("user_location", MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putString("stopLocationUpdates", timeWhenStopLocationUpdates);
        editor.apply();
        Log.d("stopUpdates", "stopLocationUpdates();==" + timeWhenStopLocationUpdates);
        LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);

    }
}

@Override
public void onDestroy() {
    super.onDestroy();
    timeWhenServiceDestroyed = DateFormat.getTimeInstance().format(new Date());
    SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences("user_location", MODE_PRIVATE);
    SharedPreferences.Editor editor = sharedPreferences.edit();
    editor.putString("onDestroyService", timeWhenServiceDestroyed);
    editor.apply();
    stopLocationUpdates();
    Log.d("onDestroyService", "onDestroy: + " + timeWhenServiceDestroyed);
}

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

    isEnded = false;
    mRequestingLocationUpdates = false;
    mLastUpdateTime = "";
    buildGoogleApiClient();
    Log.d("onCreateService", "onCreateService");
}

再次,我将在 onCreate on Main 活动中开始我的服务... 任何人都可以帮助我吗?提前致谢。

【问题讨论】:

  • 我认为您的服务只是第一次调用。请检查您的服务。它是否正在运行多次。
  • 你能试试我的方法吗stackoverflow.com/questions/39314901/…
  • 是的,我的服务正在运行多次。
  • @Saveen 谢谢你的回答,但我不想完全改变我的代码。你能告诉我我应该在这个我的代码中添加什么吗?
  • @Bansal 那么,您认为我是否将逻辑从 onCreate 放到 onStartCommand 中?

标签: android gps android-service android-location


【解决方案1】:

请检查我如何将服务更改为您的代码。

步骤 1. 制作这个类 GoogleLocationService.java

public class GoogleLocationService {
private GoogleServicesCallbacks callbacks = new GoogleServicesCallbacks();
LocationUpdateListener locationUpdateListener;
Context activity;
protected GoogleApiClient mGoogleApiClient;
protected LocationRequest mLocationRequest;

public static final long UPDATE_INTERVAL_IN_MILLISECONDS = 30000;


public GoogleLocationService(Context activity, LocationUpdateListener locationUpdateListener) {
    this.locationUpdateListener = locationUpdateListener;
    this.activity = activity;
    buildGoogleApiClient();
}

protected synchronized void buildGoogleApiClient() {
    //Log.i(TAG, "Building GoogleApiClient");
    mGoogleApiClient = new GoogleApiClient.Builder(activity)
            .addConnectionCallbacks(callbacks)
            .addOnConnectionFailedListener(callbacks)
            .addApi(LocationServices.API)
            .build();
    createLocationRequest();
    mGoogleApiClient.connect();
}

protected void createLocationRequest() {
    mLocationRequest = new LocationRequest();
    mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

}

private class GoogleServicesCallbacks implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {

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

    @Override
    public void onConnectionSuspended(int i) {
        mGoogleApiClient.connect();
    }

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

        if (connectionResult.getErrorCode() == ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED) {
            Toast.makeText(activity, "Google play service not updated", Toast.LENGTH_LONG).show();
               String connectionFailed = DateFormat.getTimeInstance().format(new Date());
SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences("user_location", MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("connectionFailed", connectionFailed);
editor.apply();
Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + connectionResult.getErrorCode());

        }
        locationUpdateListener.cannotReceiveLocationUpdates();
    }

    @Override
    public void onLocationChanged(Location location) {
        if (location.hasAccuracy()) {
            if (location.getAccuracy() < 30) {
                locationUpdateListener.updateLocation(location);
            }
        }
    }
}

private static boolean locationEnabled(Context context) {
    boolean gps_enabled = false;
    LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
    try {
        gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
    } catch (Exception ex) {
        ex.printStackTrace();
    }
    return gps_enabled;
}

private boolean servicesConnected(Context context) {
    return isPackageInstalled(GooglePlayServicesUtil.GOOGLE_PLAY_STORE_PACKAGE, context);
}

private boolean isPackageInstalled(String packagename, Context context) {
    PackageManager pm = context.getPackageManager();
    try {
        pm.getPackageInfo(packagename, PackageManager.GET_ACTIVITIES);
        return true;
    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
        return false;
    }
}


public void startUpdates() {
    /*
     * Connect the client. Don't re-start any requests here; instead, wait
     * for onResume()
     */
    if (servicesConnected(activity)) {
        if (locationEnabled(activity)) {
            locationUpdateListener.canReceiveLocationUpdates();
            startLocationUpdates();
        } else {
            locationUpdateListener.cannotReceiveLocationUpdates();
            Toast.makeText(activity, "Unable to get your location.Please turn on your device Gps", Toast.LENGTH_LONG).show();
        }
    } else {
        locationUpdateListener.cannotReceiveLocationUpdates();
        Toast.makeText(activity, "Google play service not available", Toast.LENGTH_LONG).show();
    }
}

//stop location updates
public void stopUpdates() {
    stopLocationUpdates();
}

//start location updates
private void startLocationUpdates() {

    if (checkSelfPermission(activity, ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(activity, ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        return;
    }
    if (mGoogleApiClient.isConnected()) {
        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, callbacks);
        String timeWhenStartLocationUpdates = DateFormat.getTimeInstance().format(new Date());
         SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences("user_location", MODE_PRIVATE);
   SharedPreferences.Editor editor = sharedPreferences.edit();
    editor.putString("startLocationUpdates", timeWhenStartLocationUpdates);
    editor.apply();
    }
}

public void stopLocationUpdates() {
    if (mGoogleApiClient.isConnected()) {
        LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, callbacks);
         String timeWhenStopLocationUpdates = DateFormat.getTimeInstance().format(new Date());
    SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences("user_location", MODE_PRIVATE);
    SharedPreferences.Editor editor = sharedPreferences.edit();
    editor.putString("stopLocationUpdates", timeWhenStopLocationUpdates);
    editor.apply();
    }
}

public void startGoogleApi() {
    mGoogleApiClient.connect();
}

public void closeGoogleApi() {
    mGoogleApiClient.disconnect();
}

 }

第二步。制作这个界面 LocationUpdateListener.java

 public interface LocationUpdateListener {

/**
 * Called immediately the service starts if the service can obtain location
 */
void canReceiveLocationUpdates();

/**
 * Called immediately the service tries to start if it cannot obtain location - eg the user has disabled wireless and
 */
void cannotReceiveLocationUpdates();

/**
 * Called whenever the location has changed (at least non-trivially)
 * @param location
 */
void updateLocation(Location location);

/**
 * Called when GoogleLocationServices detects that the device has moved to a new location.
 * @param localityName The name of the locality (somewhere below street but above area).
 */
void updateLocationName(String localityName, Location location);
}

第 3 步。创建此位置服务类 LocationUpdateService.java

 public class LocationUpdateService extends Service {

 protected String mLastUpdateTime;
 protected String timeWhenServiceDestroyed;
 protected String timeWhenGetInGetLatLong;
 protected String report_time;
 protected String timeFromElse;
 Calendar calendar;

 private GoogleLocationService googleLocationService;
 IBinder mBinder = new LocalBinder();

 public class LocalBinder extends Binder {
 public LocationUpdateService getServerInstance() {
    return LocationUpdateService.this;
}
}

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

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("LOC", "Service init...");
return Service.START_STICKY;
}


protected synchronized void buildGoogleApiClient() {
Log.i(TAG, "Building GoogleApiClient===");
mGoogleApiClient = new GoogleApiClient.Builder(this)
        .addApi(LocationServices.API)
        .addConnectionCallbacks(this)
        .addOnConnectionFailedListener(this)
        .build();
createLocationRequest();
  }

  public void getLatLong() {
timeWhenGetInGetLatLong = DateFormat.getTimeInstance().format(new Date());

  if (mCurrentLocation != null && mLastUpdateTime != null) {

    String lat = String.valueOf(mCurrentLocation.getLatitude());
    String lng = String.valueOf(mCurrentLocation.getLongitude());
    calendar = Calendar.getInstance();
    @SuppressLint("SimpleDateFormat") SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.sss");
    simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
    report_time = simpleDateFormat.format(calendar.getTime());
    Log.d("preferences", "Time stored in preferences: " + mLastUpdateTime);
    SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences("user_location", MODE_PRIVATE);
    SharedPreferences.Editor editor = sharedPreferences.edit();
    editor.putString("user_latitude", lat);
    editor.putString("user_longitude", lng);
    editor.putString("getLatLongIf", "ok");
    editor.putString("report_time_for_location_response", report_time);
    editor.putString("time_when_comes_to_getLatLong", timeWhenGetInGetLatLong);
    editor.apply();
}else{
    timeFromElse = DateFormat.getTimeInstance().format(new Date());
    SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences("user_location", MODE_PRIVATE);
    SharedPreferences.Editor editor = sharedPreferences.edit();
    editor.putString("getLatLongElse", timeFromElse);
    editor.apply();
 }
 }


@Override
public void onDestroy() {
super.onDestroy();
timeWhenServiceDestroyed = DateFormat.getTimeInstance().format(new Date());
SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences("user_location", MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("onDestroyService", timeWhenServiceDestroyed);
editor.apply();
  if (googleLocationService != null) {
    googleLocationService.stopLocationUpdates();
  }
  Log.d("onDestroyService", "onDestroy: + " + timeWhenServiceDestroyed);
 }

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

 mLastUpdateTime = "";

Log.d("onCreateService", "onCreateService");

 googleLocationService = new GoogleLocationService(context, new LocationUpdateListener() {
    @Override
    public void canReceiveLocationUpdates() {
    }

    @Override
    public void cannotReceiveLocationUpdates() {
    }

    //update location to our servers for tracking purpose
    @Override
    public void updateLocation(Location location) {
        if (location != null ) {
           mCurrentLocation = location;
mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
Log.d("mCurrentLocation", "Location is: " + location);
getLatLong();
SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences("user_location", MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("TimeWhenCameToOnLocationChanged", mLastUpdateTime);
editor.apply();
Log.d("onLocationchanged", "OnLocationChangedInServiceLocation");
Log.d("Time ", "Time of lat and long from Service: " + mLastUpdateTime);

        }
    }

    @Override
    public void updateLocationName(String localityName, Location location) {

        googleLocationService.stopLocationUpdates();
    }
});
googleLocationService.startUpdates();

}

试试这个,希望对你有帮助。请记住,您将在 updateLocation 上获得更新的纬度和经度。

【讨论】:

  • 谢谢伙计,但是您在哪里看到我的服务无法永久运行?
  • 后来我看到他们开始在你的服务中出现粘性
  • 试试我的方法,如果仍然有任何问题,请告诉我
  • 好的,你现在就试试你写给我的这部分代码,而不是另一个问题的整个函数?
  • 我试过了,但同样的问题..当我进入应用程序然后我打开位置时,它不会在通知栏中显示位置图标..但是当我再次进入应用程序时图标显示在栏中....这意味着当我第一次进入应用程序时我的位置不起作用。
猜你喜欢
  • 1970-01-01
  • 2022-01-23
  • 1970-01-01
  • 2019-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-18
  • 2020-04-23
相关资源
最近更新 更多