可跟踪当前位置的安卓定位应用程序接口

Android Location API可用于跟踪您的移动当前位置并在应用程序中显示。在本教程中,我们将开发一个以编程方式获取用户当前位置的应用程序。

Android位置接口

在我们的应用程序中,有两种方法可以获取用户的位置:

  • android.Location.LocationListener :这是Android接口的一部分。 *com.google.android.gms.location.LocationListener :它出现在Google Play服务API中。(我们将在下一个教程中研究这一点)

Android位置服务从Android API 1开始提供。Google官方推荐使用Google Play位置服务API。Android Location Services API仍用于为不支持Google Play服务的设备开发基于位置的应用程序。

位置监听器

LocationListener接口是Android Locations接口的一部分,用于在位置发生变化时接收来自LocationManager 的通知。** LocationManager** 类提供对系统位置服务的访问。LocationListener类需要实现以下方法。

  • onLocationChanged(Location Location) :位置变更时调用。
  • onProviderDisable(字符串提供者) :当用户关闭提供者时调用。
  • onProviderEnabled(字符串提供者) :当用户开启提供者时调用。
  • onStatusChanged(String Provider,int Status,Bundle Extras) :提供者状态改变时调用。

android.location 有两种获取位置数据的方式:

  • LocationManager.GPS_PROVIDER :卫星定位。根据情况,此提供程序可能需要一段时间才能返回位置定位
  • LocationManager.NETWORK_PROVIDER :根据附近基站和WiFi接入点的可用性确定位置。这比GPS_PROVIDER更快

在本教程中,我们将创建一个实现LocationListener类的服务,以通过GPS提供程序或网络提供程序接收定期位置更新。

Android Location API项目结构

Android Location API,Android GPS location项目由一个**MainActivity.java** 类和一个** LocationTrack.java** Service类组成,该类展示了一个** Get Location** 和一个** LocationTrack.java** Service类。

Android位置APICode

Activity_main.xml布局定义如下。

 1<?xml version="1.0" encoding="utf-8"?>
 2<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
 3    xmlns:tools="https://schemas.android.com/tools"
 4    android:id="@+id/activity_main"
 5    android:layout_width="match_parent"
 6    android:layout_height="match_parent"
 7    android:paddingBottom="@dimen/activity_vertical_margin"
 8    android:paddingLeft="@dimen/activity_horizontal_margin"
 9    android:paddingRight="@dimen/activity_horizontal_margin"
10    android:paddingTop="@dimen/activity_vertical_margin"
11    tools:context="com.journaldev.gpslocationtracking.MainActivity">
12
13    <Button
14        android:layout_width="wrap_content"
15        android:layout_height="wrap_content"
16        android:id="@+id/btn"
17        android:layout_centerInParent="true"
18        android:text="GET LOCATION" />
19</RelativeLayout>

下面定义了MainActivity.java类。

  1package com.journaldev.gpslocationtracking;
  2
  3import android.annotation.TargetApi;
  4import android.content.DialogInterface;
  5import android.content.pm.PackageManager;
  6import android.os.Build;
  7import android.support.v7.app.AlertDialog;
  8import android.support.v7.app.AppCompatActivity;
  9import android.os.Bundle;
 10import android.util.Log;
 11import android.view.View;
 12import android.widget.Button;
 13import android.widget.Toast;
 14
 15import java.util.ArrayList;
 16
 17import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
 18import static android.Manifest.permission.ACCESS_FINE_LOCATION;
 19
 20public class MainActivity extends AppCompatActivity {
 21
 22    private ArrayList permissionsToRequest;
 23    private ArrayList permissionsRejected = new ArrayList();
 24    private ArrayList permissions = new ArrayList();
 25
 26    private final static int ALL_PERMISSIONS_RESULT = 101;
 27    LocationTrack locationTrack;
 28
 29    @Override
 30    protected void onCreate(Bundle savedInstanceState) {
 31        super.onCreate(savedInstanceState);
 32        setContentView(R.layout.activity_main);
 33
 34        permissions.add(ACCESS_FINE_LOCATION);
 35        permissions.add(ACCESS_COARSE_LOCATION);
 36
 37        permissionsToRequest = findUnAskedPermissions(permissions);
 38        //get the permissions we have asked for before but are not granted..
 39        //we will store this in a global list to access later.
 40
 41        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
 42
 43            if (permissionsToRequest.size() > 0)
 44                requestPermissions(permissionsToRequest.toArray(new String[permissionsToRequest.size()]), ALL_PERMISSIONS_RESULT);
 45        }
 46
 47        Button btn = (Button) findViewById(R.id.btn);
 48
 49        btn.setOnClickListener(new View.OnClickListener() {
 50            @Override
 51            public void onClick(View view) {
 52
 53                locationTrack = new LocationTrack(MainActivity.this);
 54
 55                if (locationTrack.canGetLocation()) {
 56
 57                    double longitude = locationTrack.getLongitude();
 58                    double latitude = locationTrack.getLatitude();
 59
 60                    Toast.makeText(getApplicationContext(), "Longitude:" + Double.toString(longitude) + "\nLatitude:" + Double.toString(latitude), Toast.LENGTH_SHORT).show();
 61                } else {
 62
 63                    locationTrack.showSettingsAlert();
 64                }
 65
 66            }
 67        });
 68
 69    }
 70
 71    private ArrayList findUnAskedPermissions(ArrayList wanted) {
 72        ArrayList result = new ArrayList();
 73
 74        for (String perm : wanted) {
 75            if (!hasPermission(perm)) {
 76                result.add(perm);
 77            }
 78        }
 79
 80        return result;
 81    }
 82
 83    private boolean hasPermission(String permission) {
 84        if (canMakeSmores()) {
 85            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
 86                return (checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED);
 87            }
 88        }
 89        return true;
 90    }
 91
 92    private boolean canMakeSmores() {
 93        return (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1);
 94    }
 95
 96    @TargetApi(Build.VERSION_CODES.M)
 97    @Override
 98    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
 99
100        switch (requestCode) {
101
102            case ALL_PERMISSIONS_RESULT:
103                for (String perms : permissionsToRequest) {
104                    if (!hasPermission(perms)) {
105                        permissionsRejected.add(perms);
106                    } 
107                }
108
109                if (permissionsRejected.size() > 0) {
110
111                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
112                        if (shouldShowRequestPermissionRationale(permissionsRejected.get(0))) {
113                            showMessageOKCancel("These permissions are mandatory for the application. Please allow access.",
114                                    new DialogInterface.OnClickListener() {
115                                        @Override
116                                        public void onClick(DialogInterface dialog, int which) {
117                                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
118                                                requestPermissions(permissionsRejected.toArray(new String[permissionsRejected.size()]), ALL_PERMISSIONS_RESULT);
119                                            }
120                                        }
121                                    });
122                            return;
123                        }
124                    }
125
126                }
127
128                break;
129        }
130
131    }
132
133    private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
134        new AlertDialog.Builder(MainActivity.this)
135                .setMessage(message)
136                .setPositiveButton("OK", okListener)
137                .setNegativeButton("Cancel", null)
138                .create()
139                .show();
140    }
141
142    @Override
143    protected void onDestroy() {
144        super.onDestroy();
145        locationTrack.stopListener();
146    }
147}

在上面的代码中,我们实现了在Android 6.0+设备中使用的运行时权限。我们在AndroidManifest.xml文件中添加了 ACCESS_FINE_LOCATION 和** ACCESS_COARSE_LOCATION** 权限。单击该按钮将调用LocationTrack.java服务类。如果在GPS提供程序的情况下返回的位置为NULL,则我们将从LocationTrack.java类中调用** showSettingsAlert()** 方法,我们将很快看到。当Activity被销毁时,将调用** stopLocationTrack()** 方法关闭位置更新。下面定义了** LocationTrack.java** 类。

  1public class LocationTrack extends Service implements LocationListener {
  2
  3    private final Context mContext;
  4
  5    boolean checkGPS = false;
  6
  7    boolean checkNetwork = false;
  8
  9    boolean canGetLocation = false;
 10
 11    Location loc;
 12    double latitude;
 13    double longitude;
 14
 15    private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10;
 16
 17    private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1;
 18    protected LocationManager locationManager;
 19
 20    public LocationTrack(Context mContext) {
 21        this.mContext = mContext;
 22        getLocation();
 23    }
 24
 25    private Location getLocation() {
 26
 27        try {
 28            locationManager = (LocationManager) mContext
 29                    .getSystemService(LOCATION_SERVICE);
 30
 31            // get GPS status
 32            checkGPS = locationManager
 33                    .isProviderEnabled(LocationManager.GPS_PROVIDER);
 34
 35            // get network provider status
 36            checkNetwork = locationManager
 37                    .isProviderEnabled(LocationManager.NETWORK_PROVIDER);
 38
 39            if (!checkGPS && !checkNetwork) {
 40                Toast.makeText(mContext, "No Service Provider is available", Toast.LENGTH_SHORT).show();
 41            } else {
 42                this.canGetLocation = true;
 43
 44                // if GPS Enabled get lat/long using GPS Services
 45                if (checkGPS) {
 46
 47                    if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
 48                        // TODO: Consider calling
 49                        //    ActivityCompat#requestPermissions
 50                        // here to request the missing permissions, and then overriding
 51                        //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
 52                        //                                          int[] grantResults)
 53                        // to handle the case where the user grants the permission. See the documentation
 54                        // for ActivityCompat#requestPermissions for more details.
 55                    }
 56                    locationManager.requestLocationUpdates(
 57                            LocationManager.GPS_PROVIDER,
 58                            MIN_TIME_BW_UPDATES,
 59                            MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
 60                    if (locationManager != null) {
 61                        loc = locationManager
 62                                .getLastKnownLocation(LocationManager.GPS_PROVIDER);
 63                        if (loc != null) {
 64                            latitude = loc.getLatitude();
 65                            longitude = loc.getLongitude();
 66                        }
 67                    }
 68
 69                }
 70
 71                /*if (checkNetwork) {
 72
 73                    if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
 74                        // TODO: Consider calling
 75                        //    ActivityCompat#requestPermissions
 76                        // here to request the missing permissions, and then overriding
 77                        //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
 78                        //                                          int[] grantResults)
 79                        // to handle the case where the user grants the permission. See the documentation
 80                        // for ActivityCompat#requestPermissions for more details.
 81                    }
 82                    locationManager.requestLocationUpdates(
 83                            LocationManager.NETWORK_PROVIDER,
 84                            MIN_TIME_BW_UPDATES,
 85                            MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
 86
 87                    if (locationManager != null) {
 88                        loc = locationManager
 89                                .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
 90
 91                    }
 92
 93                    if (loc != null) {
 94                        latitude = loc.getLatitude();
 95                        longitude = loc.getLongitude();
 96                    }
 97                }*/
 98
 99            }
100
101        } catch (Exception e) {
102            e.printStackTrace();
103        }
104
105        return loc;
106    }
107
108    public double getLongitude() {
109        if (loc != null) {
110            longitude = loc.getLongitude();
111        }
112        return longitude;
113    }
114
115    public double getLatitude() {
116        if (loc != null) {
117            latitude = loc.getLatitude();
118        }
119        return latitude;
120    }
121
122    public boolean canGetLocation() {
123        return this.canGetLocation;
124    }
125
126    public void showSettingsAlert() {
127        AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
128
129        alertDialog.setTitle("GPS is not Enabled!");
130
131        alertDialog.setMessage("Do you want to turn on GPS?");
132
133        alertDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
134            public void onClick(DialogInterface dialog, int which) {
135                Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
136                mContext.startActivity(intent);
137            }
138        });
139
140        alertDialog.setNegativeButton("No", new DialogInterface.OnClickListener() {
141            public void onClick(DialogInterface dialog, int which) {
142                dialog.cancel();
143            }
144        });
145
146        alertDialog.show();
147    }
148
149    public void stopListener() {
150        if (locationManager != null) {
151
152            if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
153                // TODO: Consider calling
154                //    ActivityCompat#requestPermissions
155                // here to request the missing permissions, and then overriding
156                //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
157                //                                          int[] grantResults)
158                // to handle the case where the user grants the permission. See the documentation
159                // for ActivityCompat#requestPermissions for more details.
160                return;
161            }
162            locationManager.removeUpdates(LocationTrack.this);
163        }
164    }
165
166    @Override
167    public IBinder onBind(Intent intent) {
168        return null;
169    }
170
171    @Override
172    public void onLocationChanged(Location location) {
173
174    }
175
176    @Override
177    public void onStatusChanged(String s, int i, Bundle bundle) {
178
179    }
180
181    @Override
182    public void onProviderEnabled(String s) {
183
184    }
185
186    @Override
187    public void onProviderDisabled(String s) {
188
189    }
190}

从上面的代码中得出的一些推论是:

  • 在上面的代码中, isProviderEnabled(字符串提供者)** 是在LocationManager对象上调用的,用于检查GPS/Network Provider是否开启。
  • 如果未启用提供程序,我们将调用方法 showSettingsAlert()** ,该方法会显示启用GPS的提示。 LocationManager类的* questLocationUpdate(字符串提供者,long minTime,Float minDistance,LocationListener Listener) 方法用于注册命名提供者定期通知的当前活动。
  • onLocationChanged 根据minTime和minDistance(以先到者为准)定期调用。
  • Location 类托管纬度和经度。要获取当前位置,需要使用以下代码片段。
1位置锁定=locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
2在上面的Location对象上,调用getter来存储纬度和经度的双重值。然后,这些双精度值将作为Toast消息在屏幕上禁用。
3* **若要停止位置更新,将在LocationManager实例上调用** emoveUpdate**方法。
4
5在仿真器上运行的上述应用程序的输出是:[![Android Location API,Android Location tracking](https://cdn.jsdelivr.net/gh/andsky/tutorials-images/spaces/2016/11/android-location-tracking-output-1.gif)](https://cdn.jsdelivr.net/gh/andsky/tutorials-images/spaces/2016/11/android-location-tracking-output-1.gif)我们的仿真器无法获取位置,因此它为lat/lng返回0.0。你可以连接你的智能手机,并在调试模式下运行该应用程序,以检查你的当前位置。要在模拟器中模拟GPS位置,我们可以从Android Studio传递固定的纬度和经度值。除了仿真器窗口外,您还可以看到选项列表。底部的那个(有三个点)是我们的扩展控制选项。打开它,然后发送一个虚拟位置。您的应用程序应该如下所示:[![Android Location manager](https://cdn.jsdelivr.net/gh/andsky/tutorials-images/spaces/2016/11/android-location-tracking-output-2.gif)](https://cdn.jsdelivr.net/gh/andsky/tutorials-images/spaces/2016/11/android-location-tracking-output-2.gif)这将结束本教程。在后面的教程中,我们将使用Google Play服务来实现位置API。您可以通过下面的链接下载**Android GPSLocationTrackingProject** 。
6
7[下载安卓位置接口Project](https://journaldev.nyc3.digitaloceanspaces.com/android/GPSLocationTracking.zip)
Published At
Categories with 技术
Tagged with
comments powered by Disqus