实现后台服务以捕获位置

时间:2017-05-23 08:15:23

标签: java android geolocation gps

我有一个可以捕获照片并发送到服务器的应用程序。

每次拍摄照片时我都需要获取位置(lat,lon,alt)。

经过大量研究后,我明白采用这些数据需要一些时间,因此gps三角测量必须同步,所以我试图找出最佳方法。

过了一段时间,我有了想法,开始服务,每次我运行应用程序,这个服务每次都会抓住最后一个位置,当我发送一个照片时,我会得到最后的位置值。

所以我做了这样的事情(服务):

package com.example.afcosta.inesctec.pt.android.services;

import android.app.Service;
import android.content.Intent;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;

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("asd", "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(this.LOCATION_SERVICE);
        }
    }
}

然后我在我的应用运行时调用该服务(目前我正在使用login(onCreate)进行测试)

startService(new Intent(this, MyService.class));

我得到这个logTrace(带红色):

`05-22 20:35:39.652 32426-32426/com.example.afcosta.inesctec.pt.android E/BOOMBOOMTESTGPS: LocationListener gps
05-22 20:35:39.652 32426-32426/com.example.afcosta.inesctec.pt.android E/BOOMBOOMTESTGPS: LocationListener network
05-22 20:35:39.652 32426-32426/com.example.afcosta.inesctec.pt.android E/BOOMBOOMTESTGPS: onCreate
05-22 20:35:39.652 32426-32426/com.example.afcosta.inesctec.pt.android E/BOOMBOOMTESTGPS: initializeLocationManager
05-22 20:35:39.657 32426-32426/com.example.afcosta.inesctec.pt.android E/BOOMBOOMTESTGPS: onStartCommand

更改

这是我之前尝试过的事情: `

public class GoogleLocation implements


   GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {

private double lat;
private double lon;
private double alt;

public double getLat() {
    return lat;
}

public void setLat(double lat) {
    this.lat = lat;
}

public double getLon() {
    return lon;
}

public void setLon(double lon) {
    this.lon = lon;
}

public double getAlt() {
    return alt;
}

public void setAlt(double alt) {
    this.alt = alt;
}

boolean gps_enabled = false;
boolean network_enabled = false;

private Context context;
LocationManager lm;
LocationListener listener;
final int MY_PERMISSION_ACCESS_COURSE_LOCATION = 1;

public GoogleLocation(Context context) {
    this.context = context;
}


public void getPosition() {
    lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
    listener = new LocationListener() {
        @Override
        public void onLocationChanged(Location location) {
            setLat(location.getLatitude());
            setLon(location.getLongitude());
            setAlt(location.getAltitude());
        }

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {

        }

        @Override
        public void onProviderEnabled(String provider) {
            location();
        }

        @Override
        public void onProviderDisabled(String provider) {

        }
    };
    if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions((Activity) context, new String[] {  android.Manifest.permission.ACCESS_COARSE_LOCATION  },
                    MY_PERMISSION_ACCESS_COURSE_LOCATION);
        }
    }
    lm.requestLocationUpdates("gps", 5000, 0, listener);
}


public void location(){
    GoogleApiClient googleApiClient = null;
    if (googleApiClient == null) {
        googleApiClient = new GoogleApiClient.Builder(context)
                .addApi(LocationServices.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();
        googleApiClient.connect();

        LocationRequest locationRequest = LocationRequest.create();
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        locationRequest.setInterval(30 * 1000);
        locationRequest.setFastestInterval(1000);
        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                .addLocationRequest(locationRequest);

        //**************************
        builder.setAlwaysShow(true); //this is the key ingredient
        //**************************

        PendingResult<LocationSettingsResult> result =
                LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
        result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
            @Override
            public void onResult(LocationSettingsResult result) {
                final Status status = result.getStatus();
                final LocationSettingsStates state = result.getLocationSettingsStates();
                switch (status.getStatusCode()) {
                    case LocationSettingsStatusCodes.SUCCESS:
                        // All location settings are satisfied. The client can initialize location
                        // requests here.
                        break;
                    case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                        // Location settings are not satisfied. But could be fixed by showing the user
                        // a dialog.
                        try {
                            // Show the dialog by calling startResolutionForResult(),
                            // and check the result in onActivityResult().
                            status.startResolutionForResult(
                                    (Activity) context, 1000);
                        } catch (IntentSender.SendIntentException e) {
                            // Ignore the error.
                        }
                        break;
                    case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                        // Location settings are not satisfied. However, we have no way to fix the
                        // settings so we won't show the dialog.
                        break;
                }
            }
        });
    }
}


@Override
public void onConnected(@Nullable Bundle bundle) {

}

@Override
public void onConnectionSuspended(int i) {

}

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

}

} `

我没有得到任何位置,我不知道为什么,onlocationchanged永远不会运行,如果位置没有改变我想要得到最后一个。

我怎样才能做到这一点?

由于 最好的祝福 `

1 个答案:

答案 0 :(得分:0)

您不需要服务类,因为您可以在拍摄照片的活动中获取位置。

首先,在清单文件中添加权限

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

和gradle中的依赖项

compile 'com.google.android.gms:play-services:10.2.6'

然后在您拍摄照片的活动中

实施听众

public class Activity extends AppCompatActivity implements ConnectionCallbacks, OnConnectionFailedListener{

protected Location mLastLocation;
private double Latitude;
private double Longitude;
onCreate方法中的

询问用户位置权限并致电

buildGoogleApiClient();

然后定义buildGoogleApiClient()方法

 /**
 * Builds a GoogleApiClient. Uses the addApi() method to request the LocationServices API.
 */
protected synchronized void buildGoogleApiClient() {
    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();
}

之后实现了侦听器接口方法

@Override
public void onConnected(Bundle connectionHint) {


    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

        return;
    }
    mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
    if (mLastLocation != null) {
               Latitude = mLastLocation.getLatitude();
        Longitude = mLastLocation.getLongitude();
    }
}

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


@Override
public void onConnectionSuspended(int cause) {
    // 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
protected void onStop() {
    super.onStop();
    if (mGoogleApiClient.isConnected()) {
        mGoogleApiClient.disconnect();
    }
}


@Override
protected void onStart() {
    super.onStart();
    mGoogleApiClient.connect();
}

如果您不明白,请告诉我