Android:谷歌地图位置电池使用率低
Posted
技术标签:
【中文标题】Android:谷歌地图位置电池使用率低【英文标题】:Android: Google Maps location with low battery usage 【发布时间】:2015-03-22 09:34:30 【问题描述】:我的应用目前正在使用 Google Play Services
的地图
具体说明:
mMap.setMyLocationEnabled(true);
我意识到每次在我的应用中显示地图时:
位置在地图上用蓝点表示 位置图标显示在顶部栏中 如果我进入手机的设置/位置,我的应用被报告为“耗电量大”但是,我可以看到有些应用使用地图并仍然显示位置蓝点,但位置图标没有出现在顶部栏中,并且它们的电池使用量很低。
我的应用目前授予这两种权限:
android.permission.ACCESS_COARSE_LOCATION
android.permission.ACCESS_FINE_LOCATION
我的问题是:
如何在电量不足的情况下显示位置蓝点?
是否可以通过代码指定精度/电池使用情况?
更新
其实我意识到这样做的方法是使用GoogleApiClient
的FusedLocationApi
mGoogleApiClient = new GoogleApiClient.Builder(context)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
我已经在我的 Activity 中配置了 GoogleApiClient,调用:
GoogleApiClient.connect()
活动开始
GoogleApiClient.disconnect()
活动结束
在onConnected
回调中,我设置了位置更新的标准:1 分钟的最快间隔,低功耗优先:
private static final LocationRequest REQUEST = LocationRequest.create()
.setFastestInterval(60000) // in milliseconds
.setInterval(180000) // in milliseconds
.setPriority(LocationRequest.PRIORITY_LOW_POWER);
@Override
public void onConnected(Bundle bundle)
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient,
REQUEST,
this); // LocationListener
我已经测试了 GoogleApiClient 在启动时是否正确连接,但由于某些原因,每当我访问带有嵌入式 MapView 的片段时,我仍然会在设置/位置上为我的应用程序高耗电量屏幕!
似乎 MapView 忽略了这些低功耗标准!
【问题讨论】:
你不需要这两个权限,选择其中一个 我可以看到应用程序请求了这两个权限,并且仍然能够在电池使用量低的情况下显示位置蓝点。我想知道是否有一种方法可以在代码中以编程方式设置准确性。 那你的问题是什么? 我的问题是如何在电池电量不足的情况下仍然显示位置 所以请编辑您的问题 【参考方案1】:终于找到解决方案了!!! 感谢特里斯坦的回答!
默认情况下,GoogleMap 使用其位置提供程序,而不是融合位置提供程序。为了使用 Fused Location Provider(它允许您控制位置精度和功耗),您需要使用 GoogleMap.setLocationSource()
(documentation) 显式设置地图位置源
我在这里报告了一个示例活动:
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnMyLocationButtonClickListener;
import com.google.android.gms.maps.LocationSource;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends FragmentActivity
implements
ConnectionCallbacks,
OnConnectionFailedListener,
LocationSource,
LocationListener,
OnMyLocationButtonClickListener,
OnMapReadyCallback
private GoogleApiClient mGoogleApiClient;
private TextView mMessageView;
private OnLocationChangedListener mMapLocationListener = null;
// location accuracy settings
private static final LocationRequest REQUEST = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mMessageView = (TextView) findViewById(R.id.message_text);
SupportMapFragment mapFragment =
(SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
@Override
protected void onResume()
super.onResume();
mGoogleApiClient.connect();
@Override
public void onPause()
super.onPause();
mGoogleApiClient.disconnect();
@Override
public void onMapReady(GoogleMap map)
map.setLocationSource(this);
map.setMyLocationEnabled(true);
map.setOnMyLocationButtonClickListener(this);
public void showMyLocation(View view)
if (mGoogleApiClient.isConnected())
String msg = "Location = "
+ LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
/**
* Implementation of @link LocationListener.
*/
@Override
public void onLocationChanged(Location location)
mMessageView.setText("Location = " + location);
if (mMapLocationListener != null)
mMapLocationListener.onLocationChanged(location);
@Override
public void onConnected(Bundle connectionHint)
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient,
REQUEST,
this); // LocationListener
@Override
public void onConnectionSuspended(int cause)
// Do nothing
@Override
public void onConnectionFailed(ConnectionResult result)
// Do nothing
@Override
public boolean onMyLocationButtonClick()
Toast.makeText(this, "MyLocation button clicked", Toast.LENGTH_SHORT).show();
// Return false so that we don't consume the event and the default behavior still occurs
// (the camera animates to the user's current position).
return false;
@Override
public void activate(OnLocationChangedListener onLocationChangedListener)
mMapLocationListener = onLocationChangedListener;
@Override
public void deactivate()
mMapLocationListener = null;
【讨论】:
有趣的是,这正是 SDK 附带的 google-play-services 示例中的 MyLocationDemo。您只有接口 LocationSource。好东西。 我有一个问题什么时候被叫无效 我将赏金分配给了特里斯坦,但我将这个问题报告为答案,因为它提供了一个完整的工作示例。【参考方案2】:您将希望使您的活动(或为此目的更好地成为一个单独的对象)实现LocationSource
接口。
这很简单,您需要存储在activate()
方法中传递的侦听器,并在位置更新时调用它,并在调用deactivate()
时忘记它。有关示例,请参见 this answer,您可能希望将其更新为使用 FusedLocationProvider
。
完成此设置后,您可以将您的活动作为地图的LocationSource
传递,例如mMap.setLocationSource(this)
(documentation)。
这将阻止地图使用其默认的LocationSource
,该LocationSource
使用高电量使用定位服务。
【讨论】:
看我的回答,它说默认位置源确实是 FusedLocationProvider 所以没有必要重新设置。 已设置但未设置为LocationRequest.PRIORITY_LOW_POWER
非常感谢特里斯坦,这是正确的答案!!!!你赢了50分赏金!!!!似乎谷歌地图默认使用它自己的位置源,而不是 FusedLocationProvider。因此,如果您想控制准确性,则需要显式设置 FusedLocationProvider。【参考方案3】:
据说here
FusedLocationProviderApi 提供改进的位置查找和电源使用,并由“我的位置”蓝点使用。
所以地图上的“我的位置”点由FusedLocationProviderApi
提供。当您授予android.permission.ACCESS_FINE_LOCATION
权限时,您允许FusedLocationProviderApi
让您的应用从 GPS 获取数据,这可能会导致电池消耗过多。
所以只添加 android.permission.ACCESS_COARSE_LOCATION
权限到 manifest 和 Android 不应该责怪你电池使用。
【讨论】:
很遗憾,无法删除 android.permission.ACCESS_FINE_LOCATION 权限:***.com/questions/17089141/… 默认情况下,地图上的位置点实际上不是由FusedLocationProvider
馈送的。您需要显式设置地图位置源才能从FusedLocationProvider
获取数据【参考方案4】:
您可以通过使用网络提供程序类来做到这一点 您可以使用以下代码 AppLocationService.java // 专门用于获取低电量的当前位置(与nexus 5 ,5.0 中的省电模式相同)
package coreclass;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
public class AppLocationService extends Service implements LocationListener
protected LocationManager locationManager;
Location location;
private static final long MIN_DISTANCE_FOR_UPDATE = 10;
private static final long MIN_TIME_FOR_UPDATE = 1000 * 60 * 2;
public AppLocationService(Context context)
locationManager = (LocationManager) context
.getSystemService(LOCATION_SERVICE);
public Location getLocation(String provider)
if (locationManager.isProviderEnabled(provider))
locationManager.requestLocationUpdates(provider,
MIN_TIME_FOR_UPDATE, MIN_DISTANCE_FOR_UPDATE, this);
if (locationManager != null)
location = locationManager.getLastKnownLocation(provider);
return location;
return null;
@Override
public void onLocationChanged(Location location)
@Override
public void onProviderDisabled(String provider)
@Override
public void onProviderEnabled(String provider)
@Override
public void onStatusChanged(String provider, int status, Bundle extras)
@Override
public IBinder onBind(Intent arg0)
return null;
上述类的用法 MainActivity.java
AppLocationService appLocationService;
appLocationService = new AppLocationService(getActivity());
Location nwLocation = appLocationService.getLocation(LocationManager.NETWORK_PROVIDER);
if (nwLocation != null)
Lat = nwLocation.getLatitude();
Longi = nwLocation.getLongitude();
通过这种方式,您可以在高使用模式下使用 GPS 模式获取当前位置,之后您可以设置蓝点或任何您想要的东西
希望对大家有所帮助
【讨论】:
这不是问题的答案 @你怎么能这么说?有什么你知道的吗?以上是关于Android:谷歌地图位置电池使用率低的主要内容,如果未能解决你的问题,请参考以下文章