[英]How to make a service(i.e. LocationService) and get current location of device?
I want to make a service which will give the user's current location and location updates and these location updates should also update the mapFragment. 我想提供一项服务,该服务将提供用户的当前位置和位置更新,并且这些位置更新还应该更新mapFragment。
I tried all these : https://developer.android.com/training/location/receive-location-updates and 我尝试了所有这些方法: https : //developer.android.com/training/location/receive-location-updates和
Best way to get user GPS location in background in Android and this also 在Android中获取用户GPS位置的最佳方法 ,这也是
Get GPS location via a service in Android . 通过Android中的服务获取GPS位置 。
I know how to get location updates using Fused location API but I got a bit confused with using services. 我知道如何使用融合的位置API获取位置更新,但是我对使用服务有些困惑。 I am new to android and don't know how to user services in android.
我是android新手,不知道如何在android中提供用户服务。 Any help will be appreciated.
任何帮助将不胜感激。
MapsActivity.java MapsActivity.java
public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener{
/** Variables declared here .............. */
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
//First method called for setting up location
setUpLocation();
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_CODE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (checkPlayServices()) {
buildGoogleApiClient();
createLocationRequest();
displayLocation();
}
}
break;
}
}
private void setUpLocation() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
requestRuntimePermission();
} else {
if (checkPlayServices()) {
buildGoogleApiClient();
createLocationRequest();
displayLocation();
}
}
}
public void displayLocation() {
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) {
lattitude = mLastLocation.getLatitude();
longitude = mLastLocation.getLongitude();
mMap.clear();
mCurrentMarker= mMap.addMarker(new MarkerOptions()
.position(new LatLng(lattitude, longitude))
.title("You"));
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(lattitude, longitude), 12.02f));
}
}
private void createLocationRequest() {
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
mGoogleApiClient.connect();
}
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setSmallestDisplacement(DISPLACEMENT);
// Prompt to set location enabled in settings is described here
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(mLocationRequest);
builder.setAlwaysShow(true); //this is the key ingredient **Very important**
PendingResult<LocationSettingsResult> result =
LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, 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(MapsActivity.this, REQUEST_CHECK_SETTINGS);
} 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
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
// Check for the integer request code originally supplied to startResolutionForResult().
case REQUEST_CHECK_SETTINGS:
switch (resultCode) {
case Activity.RESULT_OK:
startLocationUpdates();
break;
case Activity.RESULT_CANCELED:
createLocationRequest();//keep asking if imp or do whatever
break;
}
break;
}
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}
private boolean checkPlayServices() {
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.SUCCESS) {
if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
GooglePlayServicesUtil.getErrorDialog(resultCode, this, PLAY_SERVICES_REQUEST_CODE).show();
} else {
Toast.makeText(this, "This device is not supported", Toast.LENGTH_SHORT).show();
finish();
}
return false;
}
return true;
}
private void requestRuntimePermission() {
ActivityCompat.requestPermissions(this, new String[]{
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION
}, PERMISSION_REQUEST_CODE);
}
private void startLocationUpdates() {
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);
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// 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.
return;
}
mMap.setMyLocationEnabled(true);
mMap.getUiSettings().setMyLocationButtonEnabled(true);
mMap.getUiSettings().setMapToolbarEnabled(false);
}
@Override
public void onConnected(@Nullable Bundle bundle) {
displayLocation();
startLocationUpdates();
}
@Override
public void onConnectionSuspended(int i) {
mGoogleApiClient.connect();
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
@Override
public void onLocationChanged(Location location) {
mLastLocation = location;
displayLocation();
}
MapsActivity.xml MapsActivity.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.v4.widget.DrawerLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/drawerLayout"
android:layout_below="@+id/appBarLayout">
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MapsActivity"
tools:ignore="NotSibling" >
</fragment>
</android.support.v4.widget.DrawerLayout>
</RelativeLayout>
You can implement LocationService like this : 您可以像这样实现LocationService:
1). 1)。 Firstly , you have to make a Java class (say locationService.java) and extends Service .
首先,您必须创建一个Java类(例如locationService.java)并扩展Service。
public class LocationService extends Service implements LocationListener,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener
2). 2)。 Then it will gives you errors to implement methods , just press alt+enter and implement those methods .
然后它将给您错误的实现方法,只需按alt + enter并实现这些方法。
3). 3)。 There is a method
onStartCommand
which gets called first when your service is created .You have to call your setUplocation
method in onStartCommand
. 有一种方法
onStartCommand
在创建服务时。你得叫你这被称为第一setUplocation
的方法onStartCommand
。
4) . 4)。 Now , In
onLocationChanged
method you can send latitude and longitude using broadast reciever like this : 现在,在
onLocationChanged
方法中,您可以像这样使用最广泛的接收方发送纬度和经度:
@Override
public void onLocationChanged(Location location) {
...
sendMessageToUI(String.valueOf(location.getLatitude()), String.valueOf(location.getLongitude()));
...
}
private void sendMessageToUI(String lat, String lng) {
Intent intent = new Intent(ACTION_LOCATION_BROADCAST);
intent.putExtra(EXTRA_LATITUDE, lat);
intent.putExtra(EXTRA_LONGITUDE, lng);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
5). 5)。 Now, you have to register this service in
onCreate
like this : 现在,您必须像这样在
onCreate
注册此服务:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LocalBroadcastManager.getInstance(this).registerReceiver(
new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
}
}, new IntentFilter(LocationServicesForLocationUpdates.ACTION_LOCATION_BROADCAST));
}
In onRecieve
method, you can get latlng values from intent.getStringExtras
在
onRecieve
方法中,您可以从intent.getStringExtras
获取latlng值
Hope , this help and solves your problem . 希望这对您有所帮助。 Good luck!
祝好运!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.