Android如何确定应用程序在“最近位置请求”下是否具有“高电池使用率”?

13

在Kitkat(4.4)之后,安卓报告我的应用程序为“高耗电量”。

我同时使用网络定位和GPS。如果我禁用GPS,则这个应用程序似乎会被标记为“低耗电量”。

我想知道是否有任何使用GPS的技巧可以保持“低耗电量”标签。也许如果您的轮询不够频繁-或者是硬编码为GPS = 电池杀手?

编辑:

我了解更改这些参数将节省电池寿命。我的问题更多的是,安卓是否会识别这些节电尝试,还是仅因为使用GPS而将我的应用程序标记为高功率使用?


谢谢Ioan - 这正是我在寻找的。请随意将其发布为答案... - Martin Konecny
3个回答

14

这是一个好问题,但有些重复。是的,轮询频率会对电池寿命产生很大影响。因此,用户位置更新的获取频率应根据具体需求进行调整。

  1. 基本上,如果您阅读 Android 的 LocationManager 中关于 requestLocationUpdates 的文档,它表示:

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

    为 minTime 选择合理的值非常重要,以节省电池寿命。 每次位置更新都需要 GPS、WIFI、蜂窝和其他无线电的功率。选择尽可能高的 minTime 值,同时仍然提供合理的用户体验。如果您的应用程序不在前台并向用户显示位置,则应避免使用活动提供程序(例如 NETWORK_PROVIDER 或 GPS_PROVIDER),但如果您坚持要使用,则应选择 5 * 60 * 1000(5 分钟)或更长的 minTime。如果您的应用程序在前台并向用户显示位置,则选择更快的更新间隔是适当的。

    minDistance 参数也可用于控制位置更新的频率。如果它大于 0,则位置提供程序仅在位置至少更改了 minDistance 米并且至少经过了 minTime 毫秒时才向您的应用程序发送更新。但是,使用 minDistance 参数节省电源对位置提供程序来说更加困难,因此 minTime 应该是节省电池寿命的主要工具

  2. 请阅读以下内容,了解其如何耗电以及可以采取哪些措施来最小化电池损耗:

    Android Regular GPS Polling in Service, maximizing battery life

如何最省电地使用LocationClient实现定期更新?

在Android中获取用户位置的好方法

如何节省Android GPS服务所消耗的电量

位置提供程序是否真的会消耗电池电量?

如果同时使用GPS和后台应用程序,iPhone/Android手机的电池寿命怎么样?

如何保持GPS服务的活性并优化电池寿命

希望这可以帮到您。

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


我明白更改这些参数将有助于节省电池寿命。我的问题更多的是,安卓系统是否会识别这些节电尝试,还是仅仅因为应用使用GPS就将其标记为高功耗应用。 - Martin Konecny
我认为这值得一试。尽管如此,它应该足够智能,以便查看您的应用程序实际造成的电池耗电量。仅仅因为您的应用程序每天使用 GPS 3 次,就不应将其视为“高电池使用率”。 - Shobhit Puri
好的建议,但这不是问题所在。 - AlexWien

5

1
链接已失效。我有类似的任务,请提供一个例子。谢谢。 - Praveen Kumar
1
你的应用程序不会因为使用了“Google Play Services”的“Fused Location”而被列为电池耗尽的来源,对吧? - jayeshsolanki93

0

最近进行了重构以获取代码位置,学习了一些好的想法,并最终实现了一个相对完美的库和演示。

//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

备注:

  • 每次请求完成定位后,最好调用removeUpdates方法,否则手机状态栏会一直显示定位图标。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接