安卓:谷歌地图的位置低电池使用电池使用、位置、地图

2023-09-12 22:51:06 作者:你是我每天的梦

我的应用程序目前正在使用的地图由谷歌播放服务

My app is currently using Maps by Google Play Services

speficying:

speficying:

mMap.setMyLocationEnabled(真);

我意识到我正在显示在我的应用程序映射每次:

I realize each time I am displaying the map in my app:

的位置显示在地图上用蓝点 在一个位置图标显示在顶部栏 如果我去到手机设置/位置,我的应用程序被报告为高电池使用

不过,我可以看到有使用地图和仍然显示的位置,蓝点的应用程序,但位置图标没有出现在顶级的酒吧和他们的电池使用低。

However, I can see there are apps that use Maps and still show the location blue dot, but the location icon doesn't appear in top bar and their battery usage is low.

我的应用程序目前授予这两个权限:

My app currently grants both permissions:

android.permission.ACCESS_COARSE_LOCATION android.permission.ACCESS_FINE_LOCATION android.permission.ACCESS_COARSE_LOCATION android.permission.ACCESS_FINE_LOCATION

我的问题是:

我怎么能显示的位置蓝点低电池使用?

是它可以指定由code的准确度/电池使用?

is it possible to specify the accuracy/battery usage by code?

更新

其实我意识到,这样做的方式是使用 GoogleApiClient FusedLocationApi

Actually I realized that the way to do it is to use the GoogleApiClient's FusedLocationApi

    mGoogleApiClient = new GoogleApiClient.Builder(context)
            .addApi(LocationServices.API)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .build();

我已经配置了GoogleApiClient我的活动里,美其名曰:

I have configured the GoogleApiClient inside my Activity, calling:

GoogleApiClient.connect()在活动的开始 GoogleApiClient.disconnect()的活动的停止 GoogleApiClient.connect() on the Activity's start GoogleApiClient.disconnect() on the Activity's stop

onConnected 回调我设定的标准为位置的更新:

on the onConnected callback I set the criteria for the location updates: fastest interval of 1 minute with low power priority:

    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的一些原因,我仍然可以在电池使用高我的应用程序上的设置/位置屏幕!

I have tested that the GoogleApiClient connects correctly at start, but for some reasons whenever I visit the fragment with the embedded MapView, I still get the high battery use for my app on the Settings/Location screen!

看来的MapView无视这些低功耗的规定 - !

It seems the MapView is ignoring these low power criterias!

推荐答案

终于找到了解决方案! 感谢特里斯坦他的回答!

FINALLY FOUND THE SOLUTION!!! thanks to Tristan for his answer!

缺省情况下,使用GoogleMap使用其上的位置信息提供,这是不融合位置提供者。为了使用融合的位置提供者(它允许您控制定位精度和功耗),你需要明确地设置地图的位置源 GoogleMap.setLocationSource()( documentation)

By default, GoogleMap uses its on location provider, which is not the Fused Location Provider. In order to use the Fused Location Provider (which allows you to control the location accuracy and power consumption) you need to explicitely set the map location source with GoogleMap.setLocationSource() (documentation)

我在这里报告的样本活动要做到这一点:

I am reporting here a sample activity to do that:

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;
    }
}