web-dev-qa-db-ja.com

Android:バッテリー使用量の少ないGoogleマップの場所

私のアプリは現在、_Google Play Services_のマップを使用しています

speficying:

mMap.setMyLocationEnabled(true);

アプリに地図を表示するたびに、次のことに気付きます。

  • 場所は地図上で青い点で示されています
  • 位置アイコンがトップバーに表示されています
  • 電話の設定/場所に移動すると、アプリは「バッテリー使用量が多い」と報告されます

ただし、マップを使用しているにもかかわらず場所の青い点が表示されているアプリがありますが、場所のアイコンがトップバーに表示されず、バッテリーの使用量が少なくなっています。

私のアプリは現在、両方の権限を付与しています。

  • _Android.permission.ACCESS_COARSE_LOCATION_
  • _Android.permission.ACCESS_FINE_LOCATION_

私の質問は:

バッテリー使用量が少ない場所の青い点を表示するにはどうすればよいですか?

コードで精度/バッテリー使用量を指定することは可能ですか?

[〜#〜] update [〜#〜]

実際、私はそれを行う方法がGoogleApiClientFusedLocationApiを使用することであることに気づきました

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

アクティビティ内で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はこれらの低電力基準を無視しているようです!

12
Daniele B

最終的に解決策を見つけました!!!Tristanの回答に感謝します!

デフォルトでは、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;
    }
}
29
Daniele B

アクティビティ(またはこの目的のための別のオブジェクト)に LocationSource インターフェイスを実装させる必要があります。

activate()メソッドで渡されたリスナーを保存し、場所が更新されたときにそれを呼び出し、deactivate()が呼び出されたときにそれを忘れる必要があるのは非常に簡単です。例については、 この回答 を参照してください。おそらく、FusedLocationProviderを使用するように更新することをお勧めします。

これを設定したら、mMap.setLocationSource(this)documentation )のように、アクティビティをマップのLocationSourceとして渡すことができます。

これにより、マップは、バッテリー使用量の多い位置情報サービスを使用するデフォルトのLocationSourceを使用できなくなります。

14

それは述べられています ここ それ

FusedLocationProviderApiは、位置検索と電力使用量を改善し、「現在地」の青い点で使用されます。

したがって、地図上の「現在地」のドットはFusedLocationProviderApiによって供給されます。また、許可Android.permission.ACCESS_FINE_LOCATIONを付与すると、アプリがGPSからデータを取得することをFusedLocationProviderApiに許可するため、バッテリーの使用量が増える可能性があります。

したがって、マニフェストにAndroid.permission.ACCESS_COARSE_LOCATION権限のみを追加し、Androidはバッテリー使用量のせいにするべきではありません。

0