Android:电子邮件使用率低的Google地图位置

时间:2015-01-23 10:55:46

标签: android google-maps google-play-services google-maps-android-api-2 location-services

我的应用目前正在使用Google Play Services

的地图

speficying:

mMap.setMyLocationEnabled(true);

我每次在应用中显示地图时都会意识到:

  • 地图以蓝点显示在地图上
  • 位置图标显示在顶栏
  • 如果我进入手机的设置/位置,我的应用报告为“使用电池电量高”

但是,我可以看到有些应用程序使用地图并仍然显示位置蓝点,但位置图标没有显示在顶部栏中,并且它们的电池使用率很低。

我的应用目前授予两种权限:

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

我的问题是:

如何显示电池使用率低的位置蓝点?

是否可以通过代码指定准确度/电池使用情况?

更新

实际上我意识到这样做的方法是使用GoogleApiClient的{​​{1}}

FusedLocationApi

我在我的Activity中配置了GoogleApiClient,调用:

    活动开始时
  • mGoogleApiClient = new GoogleApiClient.Builder(context) .addApi(LocationServices.API) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .build();
  • 活动停止时
  • GoogleApiClient.connect()
GoogleApiClient.disconnect()回调上的

我设置了位置更新的条件:最快间隔为1分钟,具有低功率优先级:

onConnected

我已经测试了GoogleApiClient在开始时正确连接,但出于某些原因,当我使用嵌入式MapView访问片段时,我仍然在设置/位置上为我的应用获得高电量使用屏幕!

似乎MapView忽略了这些低功耗标准!

4 个答案:

答案 0 :(得分:29)

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

默认情况下,GoogleMap使用其位置提供程序,而不是融合位置提供程序。要使用融合位置提供程序(允许您控制位置准确性和功耗),您需要使用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;
    }
}

答案 1 :(得分:14)

您希望将您的活动(或更好的单独对象)用于实现LocationSource接口。

很简单,您需要存储在activate()方法中传递的侦听器,并在更新位置时调用它,并在调用deactivate()时将其忘记。有关示例,请参阅this answer,您可能希望将其更新为使用FusedLocationProvider

完成此设置后,您可以将活动作为LocationSource传递给地图mMap.setLocationSource(this)documentation)。

这将阻止地图使用其默认LocationSource,使用高电量使用位置服务。

答案 2 :(得分:0)

据说here

  

FusedLocationProviderApi提供改进的位置查找和功率使用,并由“我的位置”蓝点使用。

因此地图上的“我的位置”点由FusedLocationProviderApi提供。当您授予权限android.permission.ACCESS_FINE_LOCATION时,您允许FusedLocationProviderApi为您的应用从GPS获取可能导致高电量使用的数据。

因此,仅向清单添加android.permission.ACCESS_COARSE_LOCATION权限,Android不应该因电池使用而责怪您。

答案 3 :(得分:-2)

您可以使用网络提供程序类执行此操作 您可以使用以下代码 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模式的当前位置

希望它能帮到你和所有人