GPSを使った現在位置の表示 2020/08/31
GPSから位置情報を取得して地図に現在位置を表示する機能を実装します。
Android 2.1の頃はGPSが受信可能になるまで数分以上待たされました。それなのでGPSが受信可能になるまで待ち受け画面をつけて「壊れていない」をアピールしました。仕事で使った数万円するGPSユニットでも20分くらい受信開始となりませんでした。ところが今のスマフォは感覚的にはほんの一瞬でGPSの受診を開始するので驚きです。

GPSを使うにはplay-servoces-locationを導入する
[File]-[Project Structure]

Dependencies, appを選択する。

[+]ボタンをクリックする。
[library Dependency]をクリックする。



①③は空白になっています。
①にplay-services-locationと入力します。
②[Search]ボタンをクリックします。
③にplay-services-locationが表示され
ています。
[OK]ボタンをクリックします。

超簡単な地図アプリをベースにします。

AndroidManifest.xmlに追記します。
 <meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="@string/google_maps_key" />
        
白の部分が追加です。
MainActivity.javaの追加変更です。

package net.sadaji.mapbasic;

import androidx.fragment.app.FragmentActivity;

import android.os.Bundle;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.LocationSettingsRequest;
import com.google.android.gms.location.LocationSettingsResponse;
import com.google.android.gms.location.SettingsClient;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import androidx.core.app.ActivityCompat;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Looper;
import com.google.android.gms.maps.model.Marker;

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {

    private GoogleMap mMap;
    private FusedLocationProviderClient mFusedClient;
    private SettingsClient mSettingClient;
    private LocationSettingsRequest mSettingRequst;
    private LocationCallback mLocCallback;
    private LocationRequest mLocReq;
    private Marker mMarker;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);
        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);

        mFusedClient = LocationServices.getFusedLocationProviderClient(this);
        mSettingClient = LocationServices.getSettingsClient(this);
        if (ActivityCompat.checkSelfPermission(this,android.Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this,
                    new String[] {android.Manifest.permission.ACCESS_FINE_LOCATION}, 1);
        }

        mLocCallback = new LocationCallback() {
            @Override
            public void onLocationResult(LocationResult locationResult) {
                super.onLocationResult(locationResult);
                Location loc = locationResult.getLastLocation();
                LatLng latlng = new LatLng(loc.getLatitude(), loc.getLongitude());
                mMap.animateCamera(CameraUpdateFactory.newLatLng(latlng));
                mMarker.setPosition(latlng);
            }
        };

        mLocReq = new LocationRequest();
        mLocReq.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY).
                setInterval(5000).
                setFastestInterval(1000);

        LocationSettingsRequest.Builder builder =
                new LocationSettingsRequest.Builder();
        mSettingRequst = builder.addLocationRequest(mLocReq).build();

        startFusedLocation();
    }

    private void startFusedLocation() {
        mSettingClient.checkLocationSettings(mSettingRequst)
                .addOnSuccessListener(this,
                        new OnSuccessListener() {
                            @Override
                            public void onSuccess(
                                    LocationSettingsResponse locationSettingsResponse) {
                                        if (ActivityCompat.checkSelfPermission(MapsActivity.this,
                                            android.Manifest.permission.ACCESS_FINE_LOCATION) !=
                                            PackageManager.PERMISSION_GRANTED ) {
                                            return;
                                        }
                                        mFusedClient.requestLocationUpdates(
                                            mLocReq, mLocCallback, Looper.myLooper());
                                    }
                        })
                .addOnFailureListener(this, new OnFailureListener() {
                    @Override
                    public void onFailure(Exception e) {
                        // nothing now
                    }
                });
    }


    /**
     * Manipulates the map once available.
     * This callback is triggered when the map is ready to be used.
     * This is where we can add markers or lines, add listeners or move the camera. In this case,
     * we just add a marker near Sydney, Australia.
     * If Google Play services is not installed on the device, the user will be prompted to install
     * it inside the SupportMapFragment. This method will only be triggered once the user has
     * installed Google Play services and returned to the app.
     */
    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        // Add a marker in Tokyo and move the camera
        LatLng tokyo = new LatLng(35.695056, 139.69885);
        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(tokyo,13f));
        mMarker = mMap.addMarker(new MarkerOptions().position(tokyo).title("Marker"));
    }

    @Override
    protected void onPause() {
        super.onPause();
        mFusedClient.removeLocationUpdates(mLocCallback);
    }

    @Override
    protected void onResume() {
        super.onResume();
        startFusedLocation();
    }

}        
白の部分が追加です。
仕様として、
GPSから送られてくる位置情報でマップを更新して、現在位置にマーカーを表示する。

解説はどうしよう?しないか、後で。