如何创建服务以在后台更新位置

时间:2017-12-22 06:57:27

标签: java android background-service google-location-services

public class MainActivity extends AppCompatActivity {
private static String lat_long_time="";
private static final String TAG = MainActivity.class.getSimpleName();

private static final int PERMISSION_REQUEST_CODE = 1;

private static final int REQUEST_PERMISSIONS_REQUEST_CODE = 34;


private static final int REQUEST_CHECK_SETTINGS = 0x1;


private static final long UPDATE_INTERVAL_IN_MILLISECONDS = 5000;

private static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS =
        UPDATE_INTERVAL_IN_MILLISECONDS / 2;

private final static String KEY_REQUESTING_LOCATION_UPDATES = "requesting-location-updates";
private final static String KEY_LOCATION = "location";
private final static String KEY_LAST_UPDATED_TIME_STRING = "last-updated-time-string";

private FusedLocationProviderClient mFusedLocationClient;

private SettingsClient mSettingsClient;

private LocationRequest mLocationRequest;

private LocationSettingsRequest mLocationSettingsRequest;

private LocationCallback mLocationCallback;

private Location mCurrentLocation;

private Button mStartUpdatesButton;
private TextView mLastUpdateTimeTextView;
private TextView mLatitudeTextView;
private TextView mLongitudeTextView;

private String mLatitudeLabel;
private String mLongitudeLabel;
private String mLastUpdateTimeLabel;

private Boolean mRequestingLocationUpdates;
private String mLastUpdateTime;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_activity);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    if(!checkPermissionForStorage()){
        requestPermissionForStorage();
    }

    mStartUpdatesButton = (Button) 
    findViewById(R.id.start_updates_button);
    findViewById(R.id.stop_updates_button);
    mLatitudeTextView = (TextView) findViewById(R.id.latitude_text);
    mLongitudeTextView = (TextView) findViewById(R.id.longitude_text);
    mLastUpdateTimeTextView = (TextView) 
    findViewById(R.id.last_update_time_text);
    mLatitudeLabel = 
    getResources().getString(R.string.latitude_label);
    mLongitudeLabel = 
    getResources().getString(R.string.longitude_label);
    mLastUpdateTimeLabel = 
    getResources().getString(R.string.last_update_time_label);

    mRequestingLocationUpdates = false;
    mLastUpdateTime = "";
    updateValuesFromBundle(savedInstanceState);

    mFusedLocationClient = 
    LocationServices.getFusedLocationProviderClient(this);
    mSettingsClient = LocationServices.getSettingsClient(this);
    LocationRequest, and
    createLocationCallback();
    createLocationRequest();
    buildLocationSettingsRequest();
    }
    private void updateValuesFromBundle(Bundle savedInstanceState) {
    if (savedInstanceState != null) {
    if (savedInstanceState.keySet().contains(KEY_REQUESTING_LOCATION_UPDATES)) {
            mRequestingLocationUpdates = savedInstanceState.getBoolean(
                    KEY_REQUESTING_LOCATION_UPDATES);
        }

        if (savedInstanceState.keySet().contains(KEY_LOCATION)) {
确保mCurrentLocation                 mCurrentLocation = savedInstanceState.getParcelable(KEY_LOCATION);             }             if(savedInstanceState.keySet()。contains(KEY_LAST_UPDATED_TIME_STRING)){                 mLastUpdateTime = savedInstanceState.getString(KEY_LAST_UPDATED_TIME_STRING);             }             updateUI();         }     }

private void createLocationRequest() {
    mLocationRequest = new LocationRequest();

    mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
    mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);

    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}

private void createLocationCallback() {
    mLocationCallback = new LocationCallback() {
        @Override
        public void onLocationResult(LocationResult locationResult) {
            super.onLocationResult(locationResult);

            mCurrentLocation = locationResult.getLastLocation();
            mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
            updateLocationUI();
        }
    };
}
private void buildLocationSettingsRequest() {
    LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
    builder.addLocationRequest(mLocationRequest);
    mLocationSettingsRequest = builder.build();
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {

startResolutionForResult()。             案例REQUEST_CHECK_SETTINGS:                 switch(resultCode){                     case Activity.RESULT_OK:                         Log.i(TAG,“用户同意进行所需的位置设置更改。”);                         打破;                     案例Activity.RESULT_CANCELED:                         Log.i(TAG,“用户选择不进行所需的位置设置更改。”);                         mRequestingLocationUpdates = false;                         updateUI();                         打破;                 }                 打破;         }     }

public void startUpdatesButtonHandler(View view) {
    if (!mRequestingLocationUpdates) {
        mRequestingLocationUpdates = true;
        setButtonsEnabledState();
        startLocationUpdates();
    }
}



private void startLocationUpdates() {
    mSettingsClient.checkLocationSettings(mLocationSettingsRequest)
            .addOnSuccessListener(this, new OnSuccessListener<LocationSettingsResponse>() {
                @Override
                public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
                    Log.i(TAG, "All location settings are satisfied.");

                    //noinspection MissingPermission
                    mFusedLocationClient.requestLocationUpdates(mLocationRequest,
                            mLocationCallback, Looper.myLooper());

                    updateUI();
                }
            })
            .addOnFailureListener(this, new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    int statusCode = ((ApiException) e).getStatusCode();
                    switch (statusCode) {
                        case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                            Log.i(TAG, "Location settings are not satisfied. Attempting to upgrade " +
                                    "location settings ");
                            try {
                                // Show the dialog by calling startResolutionForResult(), and check the
                                // result in onActivityResult().
                                ResolvableApiException rae = (ResolvableApiException) e;
                                rae.startResolutionForResult(MainActivity.this, REQUEST_CHECK_SETTINGS);
                            } catch (IntentSender.SendIntentException sie) {
                                Log.i(TAG, "PendingIntent unable to execute request.");
                            }
                            break;
                        case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                            String errorMessage = "Location settings are inadequate, and cannot be " +
                                    "fixed here. Fix in Settings.";
                            Log.e(TAG, errorMessage);
                            Toast.makeText(MainActivity.this, errorMessage, Toast.LENGTH_LONG).show();
                            mRequestingLocationUpdates = false;
                    }

                    updateUI();
                }
            });
}


private void updateUI() {
    setButtonsEnabledState();
    updateLocationUI();
}


private void setButtonsEnabledState() {
    if (mRequestingLocationUpdates) {
        mStartUpdatesButton.setEnabled(false);
        //mStopUpdatesButton.setEnabled(true);
    } else {
        mStartUpdatesButton.setEnabled(true);
        //mStopUpdatesButton.setEnabled(false);
    }
}

private void updateLocationUI() {
    if (mCurrentLocation != null) {
        mLatitudeTextView.setText(String.format(Locale.ENGLISH, "%s: %f", mLatitudeLabel,
                mCurrentLocation.getLatitude()));
        mLongitudeTextView.setText(String.format(Locale.ENGLISH, "%s: %f", mLongitudeLabel,
                mCurrentLocation.getLongitude()));
        mLastUpdateTimeTextView.setText(String.format(Locale.ENGLISH, "%s: %s",
                mLastUpdateTimeLabel, mLastUpdateTime));
        Toast.makeText(MainActivity.this, "latitude="+mCurrentLocation.getLatitude()
                +" longitude="+mCurrentLocation.getLongitude()+
                " last update="+mLastUpdateTime, LENGTH_SHORT).show();

        lat_long_time=mCurrentLocation.getLatitude()+" "+mCurrentLocation.getLongitude();

        Map<String, String> source = readFromSdMap("GettingLocation/sources.dat");

        source.put(mLastUpdateTime, lat_long_time);
        saveToSDMap(source, "GettingLocation/sources.dat");



       Toast.makeText(MainActivity.this,lat_long_time,Toast.LENGTH_SHORT).show();
    }
}


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

    if (mRequestingLocationUpdates && checkPermissions()) {
        startLocationUpdates();
    } else if (!checkPermissions()) {
        requestPermissions();
    }

    updateUI();
}

@Override
protected void onPause() {
    super.onPause();

        }

@Override
public void onStop(){
    super.onStop();
}

public void onSaveInstanceState(Bundle savedInstanceState) {
    savedInstanceState.putBoolean(KEY_REQUESTING_LOCATION_UPDATES, mRequestingLocationUpdates);
    savedInstanceState.putParcelable(KEY_LOCATION, mCurrentLocation);
    savedInstanceState.putString(KEY_LAST_UPDATED_TIME_STRING, mLastUpdateTime);
    super.onSaveInstanceState(savedInstanceState);
}


private void showSnackbar(final int mainTextStringId, final int actionStringId,
                          View.OnClickListener listener) {
    Snackbar.make(
            findViewById(android.R.id.content),
            getString(mainTextStringId),
            Snackbar.LENGTH_INDEFINITE)
            .setAction(getString(actionStringId), listener).show();
}


private boolean checkPermissions() {
    int permissionState = ActivityCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_FINE_LOCATION);
    return permissionState == PackageManager.PERMISSION_GRANTED;
}

private boolean checkPermissionForStorage() {
    int result = ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
    if (result == PackageManager.PERMISSION_GRANTED) {
        return true;
    } else {
        return false;
    }
}

private void requestPermissionForStorage() {

    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);

}

private void requestPermissions() {
    boolean shouldProvideRationale =
            ActivityCompat.shouldShowRequestPermissionRationale(this,
                    Manifest.permission.ACCESS_FINE_LOCATION);

    if (shouldProvideRationale) {
        Log.i(TAG, "Displaying permission rationale to provide additional context.");
        showSnackbar(R.string.permission_rationale,
                android.R.string.ok, new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        // Request permission
                        ActivityCompat.requestPermissions(MainActivity.this,
                                new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                                REQUEST_PERMISSIONS_REQUEST_CODE);
                    }
                });
    } else {
        Log.i(TAG, "Requesting permission");
        // Request permission. It's possible this can be auto answered if device policy
        // sets the permission in a given state or the user denied the permission
        // previously and checked "Never ask again".
        ActivityCompat.requestPermissions(MainActivity.this,
                new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                REQUEST_PERMISSIONS_REQUEST_CODE);
    }
}

public static boolean isExternalStorageWritable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state)) {
        return true;
    }
    return false;
}

void saveToSDMap(Map<String, String> source, String dest) {

    if (isExternalStorageWritable()) {
        File path = Environment.getExternalStorageDirectory();
        try {
            File dir = new File(valueOf(path) + "/GettingLocation");
            if (!dir.exists()) {
                dir.mkdir();
            }
            FileOutputStream fos =
                    new FileOutputStream(
                            new File(path, dest)
                    );
            ObjectOutputStream os = new ObjectOutputStream(fos);
            os.writeObject(source);
            os.close();

        } catch (Exception ex) {
            ex.printStackTrace();
            System.out.println(ex.getMessage());

        }
    }
}

public static Map<String, String> readFromSdMap(String dest) {

    Map<String, String> source = new HashMap<String, String>();
    if (isExternalStorageWritable()) {
        File path = Environment.getExternalStorageDirectory();

        try {
            File dir = new File(valueOf(path) + "/GettingLocation");
            if (!dir.exists()) {
                dir.mkdir();
            }
            FileInputStream fis =
                    new FileInputStream(
                            new File(path, dest)
                    );
            ObjectInputStream is = new ObjectInputStream(fis);
            source = (Map<String, String>) is.readObject();
            is.close();
            fis.close();

        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }

        return source;

    } else {
        return source;
    }
}



@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                       @NonNull int[] grantResults) {
    Log.i(TAG, "onRequestPermissionResult");
    if (requestCode == REQUEST_PERMISSIONS_REQUEST_CODE) {
        if (grantResults.length <= 0) {
            // If user interaction was interrupted, the permission request is cancelled and you
            // receive empty arrays.
            Log.i(TAG, "User interaction was cancelled.");
        } else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            if (mRequestingLocationUpdates) {
                Log.i(TAG, "Permission granted, updates requested, starting location updates");
                startLocationUpdates();
            }
        } else {
            showSnackbar(R.string.permission_denied_explanation,
                    R.string.settings, new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            Intent intent = new Intent();
                            intent.setAction(
                                    Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                            Uri uri = Uri.fromParts("package",
                                    BuildConfig.APPLICATION_ID, null);
                            intent.setData(uri);
                            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                            startActivity(intent);
                        }
                    });
        }
    }
}

}

2 个答案:

答案 0 :(得分:1)

   /* Add your service in Manifest... */


     /* Your Activity */

                     Gps_service gps = new Gps_service(this);
             if (gps.canGetLocation()) {

                        double latitude = Application.gps.getLatitude();
                        double longitude = Application.gps.getLongitude();
                        LogHelper.v("latitude","latitude=="+latitude +" longitude=="+longitude);

                        getAddress(latitude, longitude);
                    }

        *******If you need to fetch the Address use the following method*******

            private void getAddress(double lat, double lon) {
                String cityName = "";
                String stateName = "";
                String postalCode = "";
                String countryName = "";

                StringBuilder finalAddress = new StringBuilder();

                try {
                    Geocoder geocoder = new Geocoder(ManagedActivity.this, Locale.getDefault());
                    List<Address> addresses = geocoder.getFromLocation(lat, lon, 1);
                    if (addresses != null) {
                        try {
                            cityName = addresses.get(0).getLocality();
                            stateName = addresses.get(0).getAdminArea();
                            countryName = addresses.get(0).getCountryName();
                            postalCode = addresses.get(0).getPostalCode();

                            if (addresses.get(0).getAddressLine(0) != null)
                                finalAddress.append(addresses.get(0).getAddressLine(0));
                            if (addresses.get(0).getAddressLine(1) != null)
                                finalAddress.append(addresses.get(0).getAddressLine(1));
                            if (addresses.get(0).getAddressLine(2) != null)
                                finalAddress.append(addresses.get(0).getAddressLine(2));
                            if (addresses.get(0).getAddressLine(3) != null)
                                finalAddress.append(addresses.get(0).getAddressLine(3));
                            mDataStorage.saveAddress(this, String.valueOf(finalAddress));
                        } catch (Exception e)
                        {
                            e.printStackTrace();
                        }

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





                /* Service class */

                      public class Gps_service extends Service implements LocationListener,
                       ActivityCompat.OnRequestPermissionsResultCallback {

                           private Context mContext;

                           // flag for GPS status
                           boolean isGPSEnabled = false;

                           // flag for network status
                           boolean isNetworkEnabled = false;

                           // flag for GPS status
                           boolean canGetLocation = false;

                           Location location; // location
                           double latitude; // latitude
                           double longitude; // longitude

                           // The minimum distance to change Updates in meters
                           private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 20; // 20 meters

                           // The minimum time between updates in milliseconds
                           private static final long MIN_TIME_BW_UPDATES = 5000; // 5 seconds

                           // Declaring a Location Manager
                           protected LocationManager locationManager;


                           public Gps_service(Context context) {
                               this.mContext = context;
                               getLocation();
                           }

                           public Location getLocation() {
                               try {
                                   locationManager = (LocationManager) mContext.getSystemService(LOCATION_SERVICE);

                                   // getting GPS status
                                   isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);

                                   // getting network status
                                   isNetworkEnabled = locationManager
                                           .isProviderEnabled(LocationManager.NETWORK_PROVIDER);

                                   if (!isGPSEnabled && !isNetworkEnabled) {
                                       // no network provider is enabled
                                   } else {
                                       this.canGetLocation = true;
                                       // First get location from Network Provider
                                       if (isNetworkEnabled) {

                                           if (Build.VERSION.SDK_INT >= 23) {
                                               if (ActivityCompat.checkSelfPermission((Activity) mContext,
                                                       Manifest.permission.ACCESS_FINE_LOCATION) !=
                       PackageManager.PERMISSION_GRANTED &&
                                                       ActivityCompat.checkSelfPermission((Activity) mContext,
                       Manifest.permission.ACCESS_COARSE_LOCATION)
                                                               != PackageManager.PERMISSION_GRANTED) {

                                                   ActivityCompat.requestPermissions((Activity) mContext,
                                                           new String[]{
                                                                   Manifest.permission.ACCESS_FINE_LOCATION,
                                                                   Manifest.permission.ACCESS_COARSE_LOCATION,}, 1);
                                               } else {
                                                   locationManager.requestLocationUpdates(
                                                           LocationManager.NETWORK_PROVIDER,
                                                           MIN_TIME_BW_UPDATES,
                                                           MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                                               }

                                           } else {
                                               locationManager.requestLocationUpdates(
                                                       LocationManager.NETWORK_PROVIDER,
                                                       MIN_TIME_BW_UPDATES,
                                                       MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                                           }


                                           if (locationManager != null) {
                                               location = locationManager
                                                       .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);

                                               if (location != null) {
                                                   latitude = location.getLatitude();
                                                   longitude = location.getLongitude();

                                               }
                                           }
                                       }

                                       if (isGPSEnabled) {
                                           if (location == null) {
                                               locationManager.requestLocationUpdates(
                                                       LocationManager.GPS_PROVIDER,
                                                       MIN_TIME_BW_UPDATES,
                                                       MIN_DISTANCE_CHANGE_FOR_UPDATES, this);

                                               LogHelper.d("GPS Enabled", "GPS Enabled");
                                               if (locationManager != null) {
                                                   location = locationManager
                                                           .getLastKnownLocation(LocationManager.GPS_PROVIDER);

                                                   if (location != null) {
                                                       latitude = location.getLatitude();
                                                       longitude = location.getLongitude();

                                                   }
                                               }
                                           }
                                       }
                                   }

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

                               return location;
                           }

                           public double getLatitude() {
                               if (location != null) {
                                   latitude = location.getLatitude();
                               }
                               return latitude;
                           }

                           /**
                            * Function to get longitude
                            */

                           public double getLongitude() {
                               if (location != null) {
                                   longitude = location.getLongitude();
                               }

                               // return longitude
                               return longitude;
                           }

                           public boolean canGetLocation() {
                               return this.canGetLocation;
                           }

                           @Override
                           public void onLocationChanged(Location location) {
                               this.location = location;
                               LogHelper.v("Location changed", "Location changed==" + location);
                               latitude = location.getLatitude();
                               longitude = location.getLongitude();
                           }

答案 1 :(得分:0)

您可以使用融合位置服务来检测背景中的位置。看看我的答案 https://stackoverflow.com/a/43155046/3789993。 有关详细信息,请查看此链接http://www.vogella.com/tutorials/AndroidLocationAPI/article.html

并且不要忘记添加运行时权限