Android 如何确定应用在“最近的位置请求”下是不是存在“高电量使用”?

Posted

技术标签:

【中文标题】Android 如何确定应用在“最近的位置请求”下是不是存在“高电量使用”?【英文标题】:How does Android determine if an app has "High Battery Use" under "Recent Location Requests"?Android 如何确定应用在“最近的位置请求”下是否存在“高电量使用”? 【发布时间】:2013-11-29 12:30:50 【问题描述】:

从 Kitkat (4.4) 开始,android 报告我的应用“耗电量大”。

我使用网络位置以及 GPS。如果我禁用 GPS,那么该应用程序似乎被标记为“低电量使用”。

我想知道在保持“低电量使用”标签的同时使用 GPS 是否有任何提示。也许如果您轮询的频率不够高 - 或者它是否被硬编码为 GPS = 电池杀手?

编辑:

我了解更改这些参数将延长电池寿命。我的问题更多的是,Android 是否会认识到这些节省电池寿命的尝试,还是会仅仅因为我的应用使用 GPS 而将我的应用标记为高耗电。

【问题讨论】:

感谢 ioan - 这正是我想要的。随意将其发布为答案... 【参考方案1】:

好问题,但重复。是的,轮询频率确实对您的电池寿命有很大影响。所以获取用户位置更新的频率应该根据具体需求进行调整。

    基本上你是阅读LocationManager的requestLocationUpdates的android文档,上面写着:

    requestLocationUpdates (long minTime, float minDistance, Criteria criteria, PendingIntent intent)

    为 minTime 选择一个合理的值对于延长电池寿命很重要。每次位置更新都需要 GPS、WIFI、Cell 和其他无线电的电源。选择尽可能高的 minTime 值,同时仍能提供合理的用户体验。如果您的应用程序不在前台并向用户显示位置,那么您的应用程序应避免使用活动提供程序(例如 NETWORK_PROVIDER 或 GPS_PROVIDER),但如果您坚持选择 5 * 60 * 1000(5 分钟)的 minTime 或更大。如果您的应用程序位于前台并向用户显示位置,那么选择更快的更新间隔是合适的。

    minDistance 参数也可以用来控制位置更新的频率。如果它大于 0,那么位置提供程序将仅在位置已更改至少 minDistance 米并且至少 minTime 毫秒已过去时向您的应用程序发送更新。然而,位置提供者使用 minDistance 参数来节省电量更加困难,因此 minTime 应该是节省电池寿命的主要工具

    请阅读以下内容,了解有关如何耗电以及可以采取哪些措施来最大程度地减少电池耗电的一些好答案:

    Android Regular GPS Polling in Service, maximizing battery life

    What's the most battery-efficient approach of using LocationClient to periodically get updates?

    Good way of getting the user's location in Android

    Save battery power consumed by gps services in android

    Is location provider really a battery drain?

    Battery life if using GPS and background app ios/android

    Keeping a GPS service alive and optimizing battery life

希望这会有所帮助。

编辑: 我同意@ioan。现在您可以使用 Fused Location API 轻松高效地获取位置。

【讨论】:

我了解更改这些参数将延长电池寿命。我的问题更多的是,Android 是否会认识到这些节省电池寿命的尝试,还是会仅仅因为我的应用使用 GPS 而将其标记为高耗电。 我认为这可能值得一试。虽然,它应该足够智能,可以看到您的应用程序导致的实际电池消耗。仅仅因为您的应用使用 GPS,假设一天 3 次,它不应该将其视为high battery use 好的提示,但这不是问题【参考方案2】:

我使用了Fused Location(和 [链接删除]),在每分钟获取一次位置一整天后,我的应用程序使用了大约 4% 的电池。

(上一个链接现在是一个尝试安装浏览器扩展的停车场:http://kpbird.com/2013/06/fused-location-provider-example.html?m=1)

【讨论】:

链接已失效。我有类似的任务。请提供一个例子。谢谢。 由于“Fused Location”正在使用“Google Play Services”,“Google 服务”不会被列为您的应用耗电的原因吗?【参考方案3】:

最近重构获取代码的位置,学习了一些好的思路,终于实现了一个比较完善的库和Demo。

//request all valid provider(network/gps)
private boolean requestAllProviderUpdates() 
    checkRuntimeEnvironment();
    checkPermission();

    if (isRequesting) 
        EasyLog.d("Request location update is busy");
        return false;
    


    long minTime = getCheckTimeInterval();
    float minDistance = getCheckMinDistance();

    if (mMapLocationListeners == null) 
        mMapLocationListeners = new HashMap<>();
    

    mValidProviders = getValidProviders();
    if (mValidProviders == null || mValidProviders.isEmpty()) 
        throw new IllegalArgumentException("Not available provider.");
    

    for (String provider : mValidProviders) 
        LocationListener locationListener = new LocationListener() 
            @Override
            public void onLocationChanged(Location location) 
                if (location == null) 
                    EasyLog.e("LocationListener callback location is null.");
                    return;
                
                printf(location);
                mLastProviderTimestamp = location.getTime();

                if (location.getProvider().equals(LocationManager.GPS_PROVIDER)) 
                    finishResult(location);
                 else 
                    doLocationResult(location);
                

                removeProvider(location.getProvider());
                if (isEmptyValidProviders()) 
                    requestTimeoutMsgInit();
                    removeUpdates();
                
            

            @Override
            public void onStatusChanged(String provider, int status, Bundle extras) 
            

            @Override
            public void onProviderEnabled(String provider) 
            

            @Override
            public void onProviderDisabled(String provider) 
            
        ;
        getLocationManager().requestLocationUpdates(provider, minTime, minDistance, locationListener);
        mMapLocationListeners.put(provider, locationListener);
        EasyLog.d("Location request %s provider update.", provider);
    
    isRequesting = true;
    return true;


//remove request update
public void removeUpdates() 
    checkRuntimeEnvironment();

    LocationManager locationManager = getLocationManager();
    if (mMapLocationListeners != null) 
        Set<String> keys = mMapLocationListeners.keySet();
        for (String key : keys) 
            LocationListener locationListener = mMapLocationListeners.get(key);
            if (locationListener != null) 
                locationManager.removeUpdates(locationListener);
                EasyLog.d("Remove location update, provider is " + key);
            
        
        mMapLocationListeners.clear();
        isRequesting = false;
    

完整实现:​​https://github.com/bingerz/FastLocation/blob/master/fastlocationlib/src/main/java/cn/bingerz/fastlocation/FastLocation.java

马克:

每次请求完成定位,最好去掉Updates,否则手机状态栏会一直显示定位图标

【讨论】:

以上是关于Android 如何确定应用在“最近的位置请求”下是不是存在“高电量使用”?的主要内容,如果未能解决你的问题,请参考以下文章

如何确定我的应用程序是不是在 Android 上运行 [重复]

如何确定Android应用程序是不是被强制关闭?

如何确定我的 Android 应用程序是不是在 AVD 中运行 [重复]

在 Android 中如何确定 App(Activity) 的启动者

如何在确定模式下使用 Android ProgressBar?

如何确定使用哪个 android 市场下载我的应用程序