草庐IT

android - 当设备处于深度 sleep (打瞌睡)模式时,Geofence 未决 Intent 触发太迟

coder 2023-12-28 原文

我需要在用户靠近给定地点时通知他。我为此使用地理围栏 API。当我使用模拟位置在 Android 模拟器上测试应用程序时,一切正常。与模拟位置的真实设备相同。但是当我走路并且我的手机处于深度 sleep 模式时,地理围栏会在 5 到 10 分钟后触发。如果我在地理围栏半径内并且我解锁了我的手机,请打开任何使用我的地理围栏触发位置的应用程序。 (Android 5.1,摩托罗拉 moto G 第一代)

下面是我注册地理围栏的方式:

  public void registerLocation(RegisterAlarmRequestModel data) {
    if (isLocationDetectionAllowed() && isConnected) {
        GeofencingRequest geofencingRequest = prepareGeofencingRequest(prepareGeofence(data));
        PendingIntent pendingIntent = prepareIntent(data.getId());
        PendingResult<Status> result = GeofencingApi.addGeofences(
                googleApiClient, geofencingRequest, pendingIntent);
        Status status = result.await();
        if (status.isSuccess())
            Log.d("Location", "Geofence " + data.getId() + " has been registered");
    }
}

//preparing Geofence Pending Intent which will be triggered 
private PendingIntent prepareIntent(int alarmId) {
    Intent intent = new Intent(context, LocationRingingService.class);
    intent.putExtra(LocationRingingService.KEY_ALARM_ID, alarmId);
    return PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}

private GeofencingRequest prepareGeofencingRequest(Geofence geofence) {
    GeofencingRequest.Builder builder = new GeofencingRequest.Builder()
            .setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER)
            .addGeofence(geofence);
    return builder.build();
}

private Geofence prepareGeofence(RegisterAlarmRequestModel data) {
    Geofence geofence = new Geofence.Builder()
            .setRequestId(String.valueOf(data.getId()))
            .setCircularRegion(data.getLatitude(), data.getLongitude(), data.getRadius())
            .setLoiteringDelay(100)
            .setExpirationDuration(Geofence.NEVER_EXPIRE)
            .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER)
            .build();
    return geofence;
}

为了接收 Intent ,我正在使用 IntentService:

@Override
protected void onHandleIntent(Intent intent) {
    Log.d("Location", "accepted intent: " + intent.toString());
    //database request
}

这就是我在 list 中注册我的服务的方式:

<service
        android:name=".plugin.delivery.ringing.location.service.LocationRingingService"
        android:enabled="true"
        android:exported="true" />

更新:我需要尽可能准确地捕捉用户刚刚进入地理围栏的时刻。我有一个想法:注册半径大于需要的地理围栏(例如,如果需要 100 米半径,则注册半径为 200-300 米的地理围栏)。当用户进入半径较大的 Geophence 时 - 启动带有位置更新的服务以提高地理围栏精度。当用户刚刚输入时 - 禁用位置服务。

最佳答案

问题在于,当您的手机处于深度 sleep 状态时,它无法准确更新位置。更新位置最准确的方法是 GPS,这也是最耗电的。其他更新位置的方法(例如使用蜂窝网络)会消耗更少的电量,但也不太准确。默认情况下,地理围栏希望在发送 Intent 之前真正确定您在地理围栏中。在深度 sleep 中很难获得这种准确度,因为手机无法获取准确的位置数据。

当您解锁手机并使用位置感知应用程序时地理围栏立即触发的原因是该应用程序更新了 LastLocation ,您的地理围栏会看到然后发送 Intent 。当您的手机处于深度 sleep 状态时,位置不会更新。

对于地理围栏,您还可以调整一些设置来提高响应速度。我看到您已经在使用 setLoiteringDelay,尝试使用不同的值,也许尝试非常小的值,看看会发生什么。您还可以为 setNotificationResponsiveness 设置一个值,其工作方式类似。这样做应该会让你的围栏 react 更快,但它可能会消耗更多的电池生命周期。另请阅读 API 引用 setLoiteringDelaysetNotificationResponsiveness .另请阅读 geofence troubleshooting如果您还没有,请查看部分。

您还可以增加地理围栏的大小,尝试将其加倍然后进行测试。由于您在深度 sleep 时的定位精度较低,这将使您的手机更容易确定它在地理围栏内,一旦确定它在地理围栏内,它就会发送 Intent 。

希望对您有所帮助!

关于android - 当设备处于深度 sleep (打瞌睡)模式时,Geofence 未决 Intent 触发太迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39697675/

有关android - 当设备处于深度 sleep (打瞌睡)模式时,Geofence 未决 Intent 触发太迟的更多相关文章

  1. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  2. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  3. ruby - 是否可以在不实际发送或读取数据的情况下查明 ruby​​ 套接字是否处于 ESTABLISHED 或 CLOSE_WAIT 状态? - 2

    s=Socket.new(Socket::AF_INET,Socket::SOCK_STREAM,0)s.connect(Socket.pack_sockaddr_in('port','hostname'))ssl=OpenSSL::SSL::SSLSocket.new(s,sslcert)ssl.connect从这里开始,如果ssl连接和底层套接字仍然是ESTABLISHED,或者它是否在默认值7200之后进入CLOSE_WAIT,我想检查一个线程几秒钟甚至更糟的是在实际上不需要.write()或.read()的情况下关闭。是用select()、IO.select()还是其他方法完成

  4. ruby-on-rails - 禁用设备的 :confirmable on-the-fly to batch-generate users - 2

    Devise是一个Ruby库,它为我提供了这个User类:classUser当写入:confirmable时,注册时会发送一封确认邮件。上周我不得不批量创建300个用户,所以我在恢复之前注释掉了:confirmable几分钟。现在我正在为用户批量创建创建一个UI,因此我需要即时添加/删除:confirmable。(我也可以直接修改Devise的源码,但我宁愿不去调和它)问题:如何即时添加/删除:confirmable? 最佳答案 WayneConrad的解决方案:user=User.newuser.skip_confirmation

  5. ruby - Watir ... sleep 和等待之间的区别 - 2

    有什么显着的区别吗sleep10和wait_until(10)他们似乎都在做同样的事情:WAITING10秒,然后继续下一步 最佳答案 sleep在指定时间内什么都不做。wait_untiltakesablock.它一直等到block评估为真或超时。如果没有给出block,它们的行为相同。 关于ruby-Watir...sleep和等待之间的区别,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/que

  6. ruby-on-rails - ArgumentError(Api::V1 的副本已从模块树中删除但仍处于事件状态!) - 2

    这几天我一直在为这个问题苦苦挣扎。我有一个正在为其构建一些API的应用程序,并且上述错误总是在第一次运行时使我的应用程序崩溃。重新加载应用程序时错误消失,但仍然很烦人。以下是关于此错误的一些类似问题:AcopyofxxxhasbeenremovedfromthemoduletreebutisstillactiveArgumentError:AcopyofApplicationControllerhasbeenremovedfromthemoduletreebutisstillactive这两个链接都没有解决我面临的问题。这是完整的堆栈跟踪:ArgumentError(AcopyofAp

  7. ruby - `loop{}` 与 `loop{sleep 1}` - 2

    我正在使用循环等待键盘中断,然后在多线程环境中退出之前允许进行一些清理操作。beginloop{}rescueInterruptp"Ctr-CPressed..CleaningUp&ShuttingDown"loopdobreakifexit_bool.false?endexit130end这段代码运行在主线程中。有多个线程执行多个文件和数据库操作。exit_bool是一个由其他线程设置的原子变量,表示它们正处于某个操作的中间。我检查该值并等待它变为false然后退出。我想知道loop{}相对于loop{sleepx}的成本是多少。 最佳答案

  8. ruby - 我如何在不使用 ruby​​ 中的 sleep() 的情况下 rspec/test 一个 updated_at 字段? - 2

    如何在不使用sleep(1.second)方法的情况下编写规范?当我取消sleep时,我的测试会因为返回相同的时间戳而中断吗?我有以下类方法:defskipqs=find_or_create_by(user_id:user_id)qs.set_updated_atqs.n_skip+=1qs.save!end和以下规范:qs=skip(user.id)sleep(1.second)qs2=skip(user.id)qs.should_notbe_nilqs2.should_notbe_nil(qs.updated_at 最佳答案 我

  9. ruby-on-rails - 为什么在 after hook 中添加 "sleep 1"会导致此 Rspec/Capybara 测试通过? - 2

    我使用的是rails4.0.5、rspec2.14.1、capybara2.2.1、capybara-webkit1.1.0和database_cleaner1.2.0。我在以下功能测试中看到一些奇怪的行为(模拟用户查看帖子评论,将鼠标悬停在图标上以显示菜单,然后单击菜单项删除评论):let(:user){create(:user)}let(:post){create(:post,author:user)}let!(:comment){create(:comment,post:post,author:user)}...it"candeleteacomment"doassert(page

  10. Ruby sleep 到特定时间 - 2

    我怎么能写,我的代码休眠不是例如5秒,而是直到达到机器上的某个时间。不是这样的:sleep(5)但是像这样:now=DateTime.Nowwhilenow!="14:40:03"sleep(0.5)end怎么做才是正确的? 最佳答案 require"time"sleep(Time.parse("14:40:03")-Time.now) 关于Rubysleep到特定时间,我们在StackOverflow上找到一个类似的问题: https://stackover

随机推荐