简体   繁体   English

如何制作服务(即LocationService)并获取设备的当前位置?

[英]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.

相关问题 如何在 Android 上检查设备自然(默认)方向(即获取例如 Motorola Charm 或 Flipout 的横向) - How to check device natural (default) orientation on Android (i.e. get landscape for e.g., Motorola Charm or Flipout) 如何以编程方式获取设备的当前地理位置 - How I can get current geographical location of the device programatically 如何获取设备的当前位置? 谷歌地图 - How to get the current location of the device? google maps Ionic 2 / Ionic 3:如何获取设备的当前位置 - Ionic 2 / Ionic 3 : How to get current location of a device 从LocationService获取位置并使用MVP和Dagger 2更新演示者的位置 - Get Location from LocationService and update the location on presenter using MVP and Dagger 2 如何在Android的后台服务中获取当前位置 - How to get current location in background service in android 获取当前用户的详细信息,即登录 firebase 的用户 - Get current user details i.e. the user which is logged in firebase 如何在不启用设备上的位置服务的情况下获得上一个位置? - How can i get last location without enabling location service on device? 如何检查当前的Android设备是否具有Google的位置服务? - How to check if the current Android device has Google's location service? 如何使地图视图从当前位置获取? - How to make the mapview get from current location?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM