本文共 14902 字,大约阅读时间需要 49 分钟。
Welcome to android location using google play services example. Today we will learn how to use Google Play services API to retrieve your mobile location with example app.
欢迎使用Google Play服务示例访问Android位置。 今天,我们将学习如何通过示例应用程序使用Google Play服务API来检索您的移动位置。
In the previous tutorial, we retrieved the user’s location using Android’s Location API that was available since Android’s API 1. So why was there a need for introducing Google Play Location Services? Why hasn’t Google enhanced Android’s Location API? What are the advantages of Google Play Location Services over the default Android Location API? Let’s discuss these questions to get a clear idea.
在上一教程中,我们使用了Android的位置API(自Android的API 1开始提供)来检索用户的位置。那么为什么需要引入Google Play定位服务? Google为什么没有增强Android的Location API? 与默认的Android Location API相比,Google Play定位服务有哪些优势? 让我们讨论这些问题以获得清晰的想法。
The Google Location Services API, part of Google Play Services, provides a more powerful, high-level framework that automates tasks such as location provider choice and power management. Furthermore, it provides new features such as user’s activity detection that wasn’t available in the Android Framework’s Location API. Currently, Google provides 5 user states which are In Vehicle, On Bicycle, On Foot, Still, and Tilting, which are good enough to detect user’s activity, and to provide right content according to user’s status.
Another feature it provides is Geofencing API that is used to notify a user entering or exiting a particular area. The above advantages clearly indicate why Google Location Services API(also known as FusedLocationProviderApi) is Google’s recommended way of getting a user’s location. It provides the best accuracy based on our needs.作为Google Play服务的一部分的Google Location Services API提供了功能更强大的高级框架,该框架可自动执行诸如位置提供商选择和电源管理之类的任务。 此外,它提供了新功能,例如Android Framework的Location API中不提供的用户活动检测。 目前,Google提供了5种用户状态,分别是“车辆内” , “自行车上” , “步行上” ,“ 静止 ”和“ 倾斜” ,这些状态足以检测用户的活动并根据用户的状态提供正确的内容。
它提供的另一个功能是Geofencing API ,用于通知用户进入或离开特定区域。 上述优势清楚地说明了为什么Google推荐使用Google Location Services API (也称为FusedLocationProviderApi )来获取用户位置。 它可以根据我们的需求提供最佳的准确性。From a technical point of view, Google hasn’t improved Android’s Location API since Android has an independent update roll-out feature that lies in the hands of the smartphone manufacturer. Google has less control over it and hence decided to shift to a new API instead.
从技术角度来看,由于Android具有独立的更新推出功能(由智能手机制造商掌握),因此Google并未改进Android的Location API。 Google对它的控制较少,因此决定改用新的API。
There are few important classes that are used to get the location:
有几个重要的类可用于获取位置:
requestLocationUpdates(GoogleApiClient, LocationRequest, LocationListener)
or requestLocationUpdates(GoogleApiClient, LocationRequest, LocationListener, Looper)
methods. com.google.android.gms.location.LocationListener :位置更改后, LocationListener接口用于从FusedLocationProviderApi接收通知。 如果已使用requestLocationUpdates(GoogleApiClient, LocationRequest, LocationListener)
或requestLocationUpdates(GoogleApiClient, LocationRequest, LocationListener, Looper)
方法向位置客户端注册了LocationListener,则调用requestLocationUpdates(GoogleApiClient, LocationRequest, LocationListener, Looper)
方法。 To use Google Play’s Location Services API we need to call GoogleAPIClient first.
要使用Google Play的位置服务API,我们需要先调用GoogleAPIClient。
GoogleAPIClient allows us to call multiple Google APIs using a single call.
Following is an example snippet to invoke the GoogleAPIClient with two APIs : Location Services and Drive API.GoogleAPIClient允许我们使用一个调用来调用多个Google API。
以下是使用两个API调用GoogleAPIClient的示例代码段:Location Services和Drive API。GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(this) .addApi(LocationServices.API) .addApi(Drive.API) .addScope(Drive.SCOPE_FILE) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this).build();mGoogleApiClient.connect();
GoogleApiClient.ConnectionCallbacks and GoogleApiClient.OnConnectionFailedListener are implemented for addConnectionCallbacks and addOnConnectionFailedListener. onConnected() method that belongs to the GoogleApiClient.ConnectionCallbacks interface gets invoked when connections to all the APIs are established. onConnectionFailed() that belongs to GoogleApiClient.OnConnectionFailedListener interface is called in case of connection failure.
为addConnectionCallbacks和addOnConnectionFailedListener实现了GoogleApiClient.ConnectionCallbacks和GoogleApiClient.OnConnectionFailedListener 。 建立与所有API的连接后,将调用属于GoogleApiClient.ConnectionCallbacks接口的onConnected()方法。 连接失败时,将调用属于GoogleApiClient.OnConnectionFailedListener接口的onConnectionFailed() 。
Add the following dependency in the build.gradle file.
在build.gradle文件中添加以下依赖项。
compile 'com.google.android.gms:play-services:9.8.0
compile 'com.google.android.gms:play-services:9.8.0
Add the following permissions in the AndroidManifest.xml file.
在AndroidManifest.xml文件中添加以下权限。
The activity_main.xml is given below.
下面给出activity_main.xml 。
The MainAcitivity.java is given below.
MainAcitivity.java在下面给出。
public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener { Location mLocation; TextView latLng; GoogleApiClient mGoogleApiClient; private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000; private LocationRequest mLocationRequest; private long UPDATE_INTERVAL = 15000; /* 15 secs */ private long FASTEST_INTERVAL = 5000; /* 5 secs */ private ArrayList permissionsToRequest; private ArrayList permissionsRejected = new ArrayList(); private ArrayList permissions = new ArrayList(); private final static int ALL_PERMISSIONS_RESULT = 101; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); latLng = (TextView) findViewById(R.id.latLng); permissions.add(ACCESS_FINE_LOCATION); permissions.add(ACCESS_COARSE_LOCATION); permissionsToRequest = findUnAskedPermissions(permissions); //get the permissions we have asked for before but are not granted.. //we will store this in a global list to access later. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (permissionsToRequest.size() > 0) requestPermissions(permissionsToRequest.toArray(new String[permissionsToRequest.size()]), ALL_PERMISSIONS_RESULT); } mGoogleApiClient = new GoogleApiClient.Builder(this) .addApi(LocationServices.API) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .build(); } private ArrayList findUnAskedPermissions(ArrayList wanted) { ArrayList result = new ArrayList(); for (String perm : wanted) { if (!hasPermission(perm)) { result.add(perm); } } return result; } @Override protected void onStart() { super.onStart(); if (mGoogleApiClient != null) { mGoogleApiClient.connect(); } } @Override protected void onResume() { super.onResume(); if (!checkPlayServices()) { latLng.setText("Please install Google Play services."); } } @Override public void onConnected(@Nullable Bundle bundle) { if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // TODO: Consider calling // ActivityCompat#requestPermissions // 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. See the documentation // for ActivityCompat#requestPermissions for more details. return; } mLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); if(mLocation!=null) { latLng.setText("Latitude : "+mLocation.getLatitude()+" , Longitude : "+mLocation.getLongitude()); } startLocationUpdates(); } @Override public void onConnectionSuspended(int i) { } @Override public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { } @Override public void onLocationChanged(Location location) { if(location!=null) latLng.setText("Latitude : "+location.getLatitude()+" , Longitude : "+location.getLongitude()); } private boolean checkPlayServices() { GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance(); int resultCode = apiAvailability.isGooglePlayServicesAvailable(this); if (resultCode != ConnectionResult.SUCCESS) { if (apiAvailability.isUserResolvableError(resultCode)) { apiAvailability.getErrorDialog(this, resultCode, PLAY_SERVICES_RESOLUTION_REQUEST) .show(); } else finish(); return false; } return true; } protected void startLocationUpdates() { mLocationRequest = new LocationRequest(); mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); mLocationRequest.setInterval(UPDATE_INTERVAL); mLocationRequest.setFastestInterval(FASTEST_INTERVAL); if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { Toast.makeText(getApplicationContext(), "Enable Permissions", Toast.LENGTH_LONG).show(); } LocationServices.FusedLocationApi.requestLocationUpdates( mGoogleApiClient, mLocationRequest, this); } private boolean hasPermission(String permission) { if (canMakeSmores()) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { return (checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED); } } return true; } private boolean canMakeSmores() { return (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1); } @TargetApi(Build.VERSION_CODES.M) @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { switch (requestCode) { case ALL_PERMISSIONS_RESULT: for (String perms : permissionsToRequest) { if (!hasPermission(perms)) { permissionsRejected.add(perms); } } if (permissionsRejected.size() > 0) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (shouldShowRequestPermissionRationale(permissionsRejected.get(0))) { showMessageOKCancel("These permissions are mandatory for the application. Please allow access.", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { requestPermissions(permissionsRejected.toArray(new String[permissionsRejected.size()]), ALL_PERMISSIONS_RESULT); } } }); return; } } } break; } } private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) { new AlertDialog.Builder(MainActivity.this) .setMessage(message) .setPositiveButton("OK", okListener) .setNegativeButton("Cancel", null) .create() .show(); } @Override protected void onDestroy() { super.onDestroy(); stopLocationUpdates(); } public void stopLocationUpdates() { if (mGoogleApiClient.isConnected()) { LocationServices.FusedLocationApi .removeLocationUpdates(mGoogleApiClient, this); mGoogleApiClient.disconnect(); } }}
mLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
is used to get the last known location from the location services.
mLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
用于从定位服务中获取最新的已知位置。
Following is the output when the application is run on a genymotion emulator.
以下是在genymotion模拟器上运行应用程序时的输出。
Our emulator can’t fetch the location since Google Play services isn’t installed.
Let’s see what the output looks like on a smartphone.由于未安装Google Play服务,因此我们的模拟器无法获取位置。
让我们看看智能手机上的输出是什么样子。 上述应用程序中的纬度和经度文本每5-15秒更新一次。This brings an end to this tutorial. You can download the Android FusedLocationProvider Project from the link below.
本教程到此结束。 您可以从下面的链接下载Android FusedLocationProvider项目 。
翻译自:
转载地址:http://yumzd.baihongyu.com/