热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

十三、获取位置和使用地理围栏

十三、获取位置和使用地理围栏在本章中,我们将涵盖以下主题:如何找

十三、获取位置和使用地理围栏

在本章中,我们将涵盖以下主题:


  • 如何找到最后一个位置

  • 解决谷歌客户端 OnConnectionFailedListener 报告的问题

  • 如何接收位置更新

  • 创建和监控地理围栏


简介

位置感知为应用提供了许多好处,事实上如此之多,以至于现在即使是桌面应用也试图获得用户的位置。位置使用的范围从逐个转弯的方向,“查找最近的”应用,基于位置的警报,现在甚至有基于位置的游戏,让你用你的设备出去探索。

谷歌应用编程接口为创建位置感知应用和地图功能提供了许多丰富的功能。我们的第一个食谱如何获得最后一个位置将着眼于获得存储在设备上的最后一个已知位置。如果您的应用不是位置密集型的,这可能会提供一种理想的方法来获取用户的位置,而不会产生大量的资源开销。如果您需要持续更新,请转到如何接收位置更新食谱。虽然不断的位置更新需要更多的资源,但是用户很可能理解你何时给他们一个又一个的方向。如果您正在请求邻近位置的位置更新,请查看使用地理围栏选项,在创建和监控地理围栏配方中。

本章中的所有食谱都使用谷歌图书馆。如果您还没有下载软件开发工具包,请按照谷歌的说明进行操作。

类型

从添加 SDK 包。

既然你已经知道了位置,很有可能你也想绘制地图。这是谷歌使用谷歌地图应用编程接口在安卓上非常容易做到的另一个领域。要开始使用谷歌地图,在安卓工作室创建新项目时,看一下谷歌地图活动选项。不像我们通常对这些食谱做的那样选择空白活动,而是选择谷歌地图活动,如下图所示:

Introduction

最后一个位置怎么走

我们将从一个通常需要的简单方法开始这一章:如何获得最后一个已知的位置。这是一种使用 API 的简单方法,几乎没有额外的资源消耗。(这意味着,你的应用不会负责杀死电池。)

这个食谱也提供了一个很好的设置谷歌定位应用编程接口的介绍。

做好准备

在 Android Studio 中创建新的项目,并将其称为:GetLastLocation。使用默认的电话&平板选项,当提示输入活动类型时,选择空活动

怎么做...

首先,我们将向安卓清单添加必要的权限,然后我们将创建一个带有ButtonTextView元素的布局。最后,我们将创建一个GoogleAPIClient应用编程接口来访问最后一个位置。打开安卓清单,按照以下步骤操作:


  1. 添加以下权限:

    java


  2. Under the Gradle Scripts section, open the build.gradle (Module: app) file, as shown in this screenshot:

    How to do it...


  3. dependencies部分增加以下语句:

    java
    compile 'com.google.android.gms:play-services:8.4.0'


  4. 打开 activity_main.xml,用以下 XML 替换现有的【T1:

    java
    android:id="@+id/textView"
    android:layout_
    android:layout_ />
    android:id="@+id/button"
    android:layout_
    android:layout_
    android:text="Get Location"
    android:layout_centerInParent="true"
    android:OnClick="getLocation"/>


  5. 打开MainActivity.java并添加以下全局变量:

    java
    GoogleApiClient mGoogleApiClient;
    TextView mTextView;
    Button mButton;


  6. ConnectionCallbacks添加类别:

    java
    GoogleApiClient.ConnectionCallbacks mCOnnectionCallbacks= new GoogleApiClient.ConnectionCallbacks() {
    @Override
    public void onConnected(Bundle bundle) {
    mButton.setEnabled(true);
    }
    @Override
    public void onConnectionSuspended(int i) {}
    };


  7. 添加类来处理OnConnectionFailedListener回调:

    java
    GoogleApiClient.OnConnectionFailedListener mOnConnectionFailedListener= new GoogleApiClient.OnConnectionFailedListener() {
    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
    Toast.makeText(MainActivity.this, connectionResult.toString(), Toast.LENGTH_LONG).show();
    }
    };


  8. 将以下代码添加到现有的onCreate()方法中:

    java
    mTextView = (TextView) findViewById(R.id.textView);
    mButton = (Button) findViewById(R.id.button);
    mButton.setEnabled(false);
    setupGoogleApiClient();


  9. 添加设置GoogleAPIClient的方法:

    java
    protected synchronized void setupGoogleApiClient() {
    mGoogleApiClient = new GoogleApiClient.Builder(this)
    .addConnectionCallbacks(mConnectionCallbacks)
    .addOnConnectionFailedListener(mOnConnectionFailedListener)
    .addApi(LocationServices.API)
    .build();
    mGoogleApiClient.connect();
    }


  10. 为按钮点击添加以下方法:

    java
    public void getLocation(View view) {
    try {
    Location lastLocation = LocationServices.FusedLocationApi.getLastLocation(
    mGoogleApiClient);
    if (lastLocation != null) {
    mTextView.setText(
    DateFormat.getTimeInstance().format(lastLocation.getTime()) + "\n" + "Latitude="+lastLocation.getLatitude() + "\n" + "LOngitude=" + lastLocation.getLongitude());
    } else {
    Toast.makeText(MainActivity.this, "null", Toast.LENGTH_LONG).show();
    }
    }
    catch (SecurityException e) {e.printStackTrace();}
    }


  11. 您已经准备好在设备或模拟器上运行应用。



它是如何工作的...

在调用getLastLocation()方法之前,我们需要设置GoogleApiClient。我们在我们的setupGoogleApiClient()方法中调用GoogleApiClient.Builder方法,然后连接到库。当图书馆准备好了,它就调用我们的ConnectionCallbacks.onConnected()方法。出于演示目的,这是我们启用按钮的地方。(我们将在后面的菜谱中使用这个回调来启动其他功能。)

我们使用了按钮来显示我们可以按需调用getLastLocation();这不是一次性的电话。系统负责更新位置,并可能在重复呼叫时返回相同的最后位置。(这可以在时间戳中看到——它是位置时间戳,而不是按下按钮时的时间戳。)

这种按需调用位置的方法在应用中发生某些事情(例如对对象进行地理编码)时只需要位置的情况下非常有用。由于系统负责位置更新,因此您的应用不会因位置更新而耗尽电池。

我们收到的位置对象的准确性基于我们的权限设置。我们使用了ACCESS_COARSE_LOCATION,但是如果我们想要更高的精度,我们可以改为请求ACCESS_FINE_LOCATION,并获得以下权限:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

最后,为了保持代码集中在GoogleApiClient上,我们只需用SecurityException包装getLastLocation()。在生产应用中,您应该检查并请求权限,如前一章所示。(参见新的运行时权限模型。)

还有更多...

如果连接到GoogleApiClient时出现问题,则调用OnConnectionFailedListener。在这个例子中,我们显示了一个吐司。下一个方法是解决谷歌客户端 OnConnectionFailedListener 报告的问题,这将展示一种更稳健的方法来处理这种情况。

测试位置可能是一个挑战,因为在测试和调试时很难真正移动设备。幸运的是,我们有能力用模拟器模拟全球定位系统数据。(也可以在物理设备上创建模拟位置,但并不容易。)

模拟地点

有三种方法可以用模拟器模拟位置:


  • Android Studio

  • DDMS

  • 通过远程登录的Geo命令

要在安卓工作室中设置模拟位置,请按照以下步骤操作:


  1. 导航至工具 | 安卓 | 安卓设备监视器

  2. 在设备窗口中选择仿真器控制选项卡。

  3. 位置控制下输入全球定位系统坐标。

以下是显示位置 控件的截图:

Mock locations

类型

并不是说通过发送全球定位系统数据来模拟位置。因此,要让你的应用接收模拟位置,它需要接收全球定位系统数据。测试lastLocation()可能不会发送模拟全球定位系统数据,因为它不仅仅依赖全球定位系统来确定设备位置。使用配方尝试模拟位置如何接收位置更新,在那里我们可以请求优先级。(我们不能强制系统使用任何特定的位置传感器,我们只能提出请求。系统将选择最佳解决方案来交付结果。)

另见



  • 第 14 章中新的安卓 6.0 运行时许可模型配方为游戏商店准备好你的应用

  • 设置谷歌游戏服务:https://developers.google.com/android/guides/setup

  • FusedLocationProviderApi界面:https://developers . Google . com/Android/reference/com/Google/Android/GMS/location/FusedLocationProviderApi


解决谷歌客户端 OnConnectionFailedListener 报告的问题

随着谷歌应用接口性质的不断变化,你的用户可能会试图使用你的应用,但由于他们的文件已经过期,他们无法使用。在前面的例子中,我们只是展示了一个吐司,但是我们可以做得更好。我们可以使用GoogleApiAvailability库显示一个对话框,帮助用户解决问题。

我们将继续前面的配方,并向onConnectionFailed()回调添加代码。我们将使用错误结果向用户显示附加信息来解决他们的问题。

做好准备

本食谱将从之前的食谱继续,如何获得最后的位置。如果是从下载的源文件加载项目,则称为HandleGoogleAPIError

怎么做...

由于我们是从前面的配方继续,我们将只介绍更新前面代码所需的步骤。打开ActivityMain.java并按照以下步骤操作:


  1. 向全局类变量添加以下行:

    java
    private final int REQUEST_RESOLVE_GOOGLE_CLIENT_ERROR=1;
    boolean mResolvingError;


  2. 添加以下方法显示谷歌应用编程接口错误对话框:

    java
    private void showGoogleAPIErrorDialog(int errorCode) {
    GoogleApiAvailability googleApiAvailability = GoogleApiAvailability.getInstance();
    Dialog errorDialog = googleApiAvailability.getErrorDialog(this, errorCode, REQUEST_RESOLVE_GOOGLE_CLIENT_ERROR);
    errorDialog.show();
    }


  3. 添加以下代码以覆盖onActivityResult() :

    java
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_RESOLVE_GOOGLE_CLIENT_ERROR) {
    mResolvingError = false;
    if (resultCode == RESULT_OK && !mGoogleApiClient.isConnecting() && !mGoogleApiClient.isConnected()) {
    mGoogleApiClient.connect();
    }
    }
    }


  4. onConnectionFailed()中,替换调用 Toast 的现有代码行,使用以下代码:

    java
    if (mResolvingError) {
    return;
    } else if (connectionResult.hasResolution()) {
    mResolvingError = true;
    try {
    connectionResult.startResolutionForResult(MainActivity.this, REQUEST_RESOLVE_GOOGLE_CLIENT_ERROR);
    } catch (IntentSender.SendIntentException e) {
    mGoogleApiClient.connect();
    }
    } else {
    showGoogleAPIErrorDialog(connectionResult.getErrorCode());
    }


  5. 您已经准备好在设备或模拟器上运行应用。



它是如何工作的...

我们现在检查connectionResult看看我们能做什么,而不是像以前那样用 Toast 显示错误信息。GoogleAPIClientconnectionResult表示可能的行动路线。我们可以称之为hasResolution()方法,如下:

connectionResult.hasResolution()

如果响应是 true,那么就是用户可以解决的事情,比如启用定位服务。如果响应是false,我们得到一个GoogleApiAvailability的实例,并调用getErrorDialog()方法。完成后,我们的onActivityResult()回调被调用,在那里我们重置mResolvingError,如果成功,尝试重新连接。

类型

如果您没有使用旧版本谷歌应用编程接口进行测试的设备,您可以尝试在使用旧版本谷歌应用编程接口的仿真器上进行测试。

还有更多...

如果您的应用正在使用片段,您可以使用下面的代码获得一个对话框片段:

ErrorDialogFragment errorFragment = new ErrorDialogFragment();
Bundle args = new Bundle();
args.putInt("dialog_error", errorCode);
errorFragment.setArguments(args);
errorFragment.show(getSupportFragmentManager(), "errordialog");


另见



  • 访问谷歌应用编程接口:https://developers.google.com/android/guides/api-client


如何接收位置更新

如果您的应用需要频繁的位置更新,您的应用可以请求定期更新。该配方将使用GoogleApiClient中的requestLocationUpdates()方法进行演示。

做好准备

在 Android Studio 中创建新项目,并将其称为:LocationUpdates。使用默认的电话&平板电脑选项,当提示输入活动类型时,选择空活动

怎么做...

由于我们正在从系统接收更新,我们不需要这个食谱的按钮。我们的布局将只包括TextView来查看位置数据。打开安卓清单,按照以下步骤操作:


  1. 添加以下权限:

    java


  2. 打开文件build.gradle (Module: app)并在dependencies部分添加以下语句:

    java
    compile 'com.google.android.gms:play-services:8.4.0'


  3. 打开activity_main.xml并用以下 XML 替换现有的【T1:

    java
    android:id="@+id/textView"
    android:layout_
    android:layout_ />


  4. 打开MainActivity.java并添加以下全局变量:

    java
    GoogleApiClient mGoogleApiClient;
    LocationRequest mLocationRequest;
    TextView mTextView;


  5. 创建以下LocationListener类:

    java
    LocationListener mLocatiOnListener= new LocationListener() {
    @Override
    public void onLocationChanged(Location location) {
    if (location != null) {
    mTextView.setText(
    DateFormat.getTimeInstance().format(location.getTime()) + "\n" + "Latitude="+location.getLatitude()+"\n" + "LOngitude="+location.getLongitude());
    }
    }
    };


  6. 创建一个ConnectionCallbacks类来接收位置更新:

    java
    GoogleApiClient.ConnectionCallbacks mCOnnectionCallbacks= new GoogleApiClient.ConnectionCallbacks() {
    @Override
    public void onConnected(Bundle bundle) {
    Log.i("onConnected()", "start");
    try {
    LocationServices.FusedLocationApi.requestLocationUpdates(
    mGoogleApiClient, mLocationRequest, mLocationListener);
    } catch (SecurityException e) {
    Log.i("onConnected()","SecurityException: "+e.getMessage());
    }
    }
    @Override
    public void onConnectionSuspended(int i) {}
    };


  7. 创建一个OnConnectionFailedListener类:

    java
    GoogleApiClient.OnConnectionFailedListener mOnConnectionFailedListener= new GoogleApiClient.OnConnectionFailedListener() {
    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
    Toast.makeText(MainActivity.this, connectionResult.toString(), Toast.LENGTH_LONG).show();
    Log.i("onConnected()", "SecurityException: " +connectionResult.toString());
    }
    };


  8. 将以下代码添加到现有的onCreate()回调中:

    java
    mTextView = (TextView) findViewById(R.id.textView);
    setupLocationRequest();


  9. 创建setupLocationRequest()方法:

    java
    protected synchronized void setupLocationRequest() {
    mLocatiOnRequest= new LocationRequest();
    mLocationRequest.setInterval(10000);
    mLocationRequest.setFastestInterval(10000);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    mGoogleApiClient = new GoogleApiClient.Builder(this)
    .addConnectionCallbacks(mConnectionCallbacks)
    .addOnConnectionFailedListener(mOnConnectionFailedListener)
    .addApi(LocationServices.API)
    .build();
    mGoogleApiClient.connect();
    }


  10. 您已经准备好在设备或模拟器上运行应用。



它是如何工作的...

这个配方是类似于如何获取最后位置的配方,因为我们需要像之前一样设置GoogleApiClient。但是,我们不是按需调用lastLocation()方法,而是通过LocationListener类调用requestLocationUpdates()方法来接收定期位置更新。

requestLocationUpdates()方法需要三个参数:


  • GoogleApiClient

  • LocationRequest

  • LocationListener

我们像以前一样创建GoogleApiClient。这是创建我们的LocationRequest的代码:

mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(10000);
mLocationRequest.setFastestInterval(10000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)

在调用setInterval()时,通常最好使用最慢的延迟,因为它需要更少的设备资源。调用setPriority()时也是同样的想法。第三个参数LocationListener,是我们定义回调方法onLocationChanged()的地方。这里我们只显示位置数据和位置时间戳。

还有更多...

与以前的安卓应用编程接口不同,GoogleApiClient应用编程接口不允许选择特定的传感器进行位置更新。如模拟地点部分所述,如何获得最后一个地点,使用LocationRequest.PRIORITY_HIGH_ACCURACY以及ACCESS_FINE_LOCATION的许可应该使用全球定位系统传感器。参考模拟位置部分,了解模拟位置的说明。

停止接收位置更新

当您的应用不再需要位置更新时,调用removeLocationUpdates()方法,如下所示:

LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, mLocationListener);

通常,当应用不再处于前台时,您会希望禁用更新,但这取决于您的特定应用要求。如果您的应用需要不断更新,创建一个后台服务来处理回调可能会更好。

另见



  • 开发者文档:onLocationChanged 在https://Developer . Android . com/reference/com/Google/Android/GMS/location/location request . html


创建并监控地理围栏

如果您的应用需要知道用户何时进入某个位置,那么除了必须持续检查用户位置之外,还有一种选择:地理围栏。地理围栏是一个位置(纬度和经度)以及一个半径。您可以创建地理围栏,并让系统在用户进入您指定的位置附近时通知您。(安卓目前允许每个用户最多 100 个地理围栏。)

地理围栏属性包括:


  • 位置:经纬度

  • 半径:圆的大小(米)

  • 游荡延迟:用户在发送通知前可以在半径内停留多长时间

  • 到期 : 地理围栏自动到期还有多久

  • 过渡 : 这些是列举如下:

    • GEOFENCE_TRANSITION_ENTER

    • GEOFENCE_TRANSITION_EXIT

    • INITIAL_TRIGGER_DWELL



本食谱将向您展示如何创建地理围栏对象,并使用它创建GeofencingRequest的实例。

做好准备

在 Android Studio 中创建新项目,并将其称为:Geofence。使用默认的电话&平板电脑选项,当提示输入活动类型时,选择空活动

怎么做...

我们不需要这个食谱的布局,因为我们将使用祝酒词和通知进行用户交互。我们需要为IntentService创建一个额外的 Java 类,它处理地理围栏警报。打开安卓清单,按照以下步骤操作:


  1. 添加以下权限:

    java


  2. 打开文件build.gradle (Module: app)并在dependencies部分添加以下语句:

    java
    compile 'com.google.android.gms:play-services:8.4.0'


  3. 创建一个名为GeofenceIntentService的新 Java 类,扩展IntentService类。申报如下:

    java
    public class GeofenceIntentService extends IntentService {


  4. 添加以下构造函数:

    java
    public GeofenceIntentService() {
    super("GeofenceIntentService");
    }


  5. 添加onHandleIntent()接收地理围栏警报:

    java
    protected void onHandleIntent(Intent intent) {
    GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
    if (geofencingEvent.hasError()) {
    Toast.makeText(getApplicationContext(), "Geofence error code= " + geofencingEvent.getErrorCode(), Toast.LENGTH_SHORT).show();
    return;
    }
    int geofenceTransition = geofencingEvent.getGeofenceTransition();
    if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_DWELL) {
    sendNotification();
    }
    }


  6. 添加sendNotification()方法向用户显示消息:

    java
    private void sendNotification() {
    Log.i("GeofenceIntentService", "sendNotification()");
    Uri notificatiOnSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    NotificationCompat.Builder notificatiOnBuilder= new NotificationCompat.Builder(this)
    .setSmallIcon(R.mipmap.ic_launcher)
    .setContentTitle("Geofence Alert")
    .setContentText("GEOFENCE_TRANSITION_DWELL")
    .setSound(notificationSoundUri)
    .setLights(Color.BLUE, 500, 500);
    NotificationManager notificatiOnManager= (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
    notificationManager.notify(0, notificationBuilder.build());
    }


  7. 打开安卓清单,在元素中添加以下内容,与元素处于同一级别:

    java


  8. 打开MainActivity.java并添加以下全局变量:

    java
    private final int MINIMUM_RECOMENDED_RADIUS=100;
    GoogleApiClient mGoogleApiClient;
    PendingIntent mGeofencePendingIntent;


  9. 创建以下的类:

    java
    ResultCallback mResultCallback = new ResultCallback() {
    @Override
    public void onResult(Result result) {
    Log.i("onResult()", "result: " + result.getStatus().toString());
    }
    };


  10. 创建ConnectionCallbacks类:

    java
    GoogleApiClient.ConnectionCallbacks mCOnnectionCallbacks= new GoogleApiClient.ConnectionCallbacks() {
    @Override
    public void onConnected(Bundle bundle) {
    try {
    LocationServices.GeofencingApi.addGeofences(
    mGoogleApiClient,
    createGeofencingRequest(),
    getGeofencePendingIntent()
    ).setResultCallback(mResultCallback);
    } catch (SecurityException e) {
    Log.i("onConnected()", "SecurityException: " + e.getMessage());
    }
    }
    @Override
    public void onConnectionSuspended(int i) {}
    };


  11. 创建一个OnConnectionFailedListener类:

    java
    GoogleApiClient.OnConnectionFailedListener mOnConnectionFailedListener= new GoogleApiClient.OnConnectionFailedListener() {
    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
    Log.i("onConnectionFailed()", "connectionResult: " +connectionResult.toString());
    }
    };


  12. 将以下代码添加到现有的onCreate() 回调中:

    java
    setupGoogleApiClient();


  13. 添加设置GoogleAPIClient :

    java
    protected synchronized void setupGoogleApiClient() {
    mGoogleApiClient = new GoogleApiClient.Builder(this)
    .addConnectionCallbacks(mConnectionCallbacks)
    .addOnConnectionFailedListener(mOnConnectionFailedListener)
    .addApi(LocationServices.API)
    .build();
    mGoogleApiClient.connect();
    }

    的方法
    14. 创建setupGoogleApiClient()方法:

    java
    protected synchronized void setupGoogleApiClient() {
    mGoogleApiClient = new GoogleApiClient.Builder(this)
    .addConnectionCallbacks(mConnectionCallbacks)
    .addOnConnectionFailedListener(mOnConnectionFailedListener)
    .addApi(LocationServices.API)
    .build();
    mGoogleApiClient.connect();
    }


  14. 使用以下方法创建待定意图:

    java
    private PendingIntent getGeofencePendingIntent() {
    if (mGeofencePendingIntent != null) {
    return mGeofencePendingIntent;
    }
    Intent intent = new Intent(this, GeofenceIntentService.class);
    return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    }


  15. 创建geofence对象,并将其添加到请求列表中:

    java
    private List createGeofenceList() {
    List geofenceList = new ArrayList();
    geofenceList.add(new Geofence.Builder()
    .setRequestId("GeofenceLocation")
    .setCircularRegion(
    37.422006, //Latitude
    -122.084095, //Longitude
    MINIMUM_RECOMENDED_RADIUS)
    .setLoiteringDelay(30000)
    .setExpirationDuration(Geofence.NEVER_EXPIRE)
    .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_DWELL)
    .build());
    return geofenceList;
    }


  16. 创建 createGeofencingRequest()方法如下:

    java
    private GeofencingRequest createGeofencingRequest() {
    GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
    builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_DWELL);
    builder.addGeofences(createGeofenceList());
    return builder.build();
    }


  17. 您已经准备好在设备或模拟器上运行应用。



它是如何工作的...

首先,我们添加ACCESS_FINE_LOCATION权限,因为这是地理围栏所必需的。我们设置GoogleApiClient就像我们在之前的食谱中所做的一样,等到onConnected()被调用来设置GeofencingApi

在调用GeofencingApi.addGeofences()方法之前,我们必须准备三个对象:


  • GoogleApiClient

  • 地理围栏请求

  • 待定意向

我们已经创造了GoogleApiClient,我们保存在mGoogleApiClient中。

要创建地理围栏请求,我们使用GeofencingRequest.Builder。构建器需要地理围栏对象的列表,这些对象是用createGeofenceList()方法创建的。(即使我们只创建了一个地理围栏对象,构建器也需要一个列表,所以我们只需将我们的单个地理围栏添加到一个ArrayList中。)这里是我们设置地理围栏属性的地方:

.setRequestId("GeofenceLocation")
.setCircularRegion(
37.422006, //Latitude
-122.084095, //Longitude
MINIMUM_RECOMENDED_RADIUS)
.setLoiteringDelay(30000)
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_DWELL)

只有游荡延迟是可选的,但是我们需要它,因为我们正在使用DWELL转换。当调用setTransitionTypes()时,我们可以使用OR运算符组合多个转换类型,如管道所示。这里有一个用ENTEREXIT代替的例子:

.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT)

在本例中,我们使用了与模拟器相同的默认纬度和经度。根据需要更改这些值。

我们对Geofence.Builder()的调用创建了地理围栏对象。地理围栏列表准备就绪后,我们调用GeofencingRequest.Builder并将初始触发器设置为INITIAL_TRIGGER_DWELL。(如果您更改了前面的转换类型,您可能还想更改初始触发器。)

我们需要的最后一个对象是待定意图,这是当地理围栏标准满足时,系统将如何通知我们的应用。我们创建了GeofenceIntentService来通过向用户发送通知来处理地理围栏意图。(有关通知的更多信息,请参考第 7 章、警报和通知中的灯光、动作和声音还原使用通知食谱。)

创建了所有三个对象,我们只需调用LocationServices.GeofencingApi.addGeofences()并等待通知到达。

还有更多...

要停止接收地理围栏通知,您可以使用RequestID参数或PendingIntent调用removeGeofences()方法。以下示例使用了我们用于通知的相同PendingIntent方法:

LocationServices.GeofencingApi.removeGeofences(
mGoogleApiClient,
getGeofencePendingIntent()
).setResultCallback(mResultCallback);


另见



  • 位于的Geofence.Builder类。Builder.html

  • GeofencingRequest.Builder类位于:https://developers . Google . com/Android/reference/com/Google/Android/GMS/location/GeofencingRequest。建筑商


推荐阅读
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文讨论了在Spring 3.1中,数据源未能自动连接到@Configuration类的错误原因,并提供了解决方法。作者发现了错误的原因,并在代码中手动定义了PersistenceAnnotationBeanPostProcessor。作者删除了该定义后,问题得到解决。此外,作者还指出了默认的PersistenceAnnotationBeanPostProcessor的注册方式,并提供了自定义该bean定义的方法。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 展开全部下面的代码是创建一个立方体Thisexamplescreatesanddisplaysasimplebox.#Thefirstlineloadstheinit_disp ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • springmvc学习笔记(十):控制器业务方法中通过注解实现封装Javabean接收表单提交的数据
    本文介绍了在springmvc学习笔记系列的第十篇中,控制器的业务方法中如何通过注解实现封装Javabean来接收表单提交的数据。同时还讨论了当有多个注册表单且字段完全相同时,如何将其交给同一个控制器处理。 ... [详细]
  • 本文介绍了一些Java开发项目管理工具及其配置教程,包括团队协同工具worktil,版本管理工具GitLab,自动化构建工具Jenkins,项目管理工具Maven和Maven私服Nexus,以及Mybatis的安装和代码自动生成工具。提供了相关链接供读者参考。 ... [详细]
author-avatar
flyfish6300_468
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有