Tips

FusedLocationを用いて現在地をMapに表示させるサンプルアプリ

FusedLocationを使ってみました。

2013年にGoogleMapを使用するための新たな手法、FusedLocationが発表されました。
このFusedLocationの最大の利点は、精度の高い位置情報を取得するために、開発者が複雑な処理を書く必要がなくなったという点です。
サンプルアプリの御紹介の前に、少しだけ概要を説明させていただきます。
すでに概要を御存知の方は飛ばしていただいて問題ございません。

FusedLocationの概要

位置情報の取得するには、以下のどちらかを利用します。
各々のメリットやデメリットも併せて簡単に記載しますので、確認してみましょう。

メリット デメリット
GPS
(衛星)
かなり正確な位置情報を取得できる。 屋内(屋根のある場所)では使用できない場合がある。
ネットワークプロバイダ
(wi-fi,3Gなど)
インターネットに接続している状態であれば、
位置情報の取得が可能である。
取得できる位置情報の精度が低い。



以前の方法ではLocationManagerを使用していましたが、Mapを利用する場合は、「GPSで位置情報取得を試みて、取得できない場合は、ネットワークプロバイダで位置情報の取得を試みる」や、「取得した位置情報の精度によっては更新しない」といった、フィルタリングのようなロジックを書く必要がありました。

ところがLocationClientを用いることで、上記のようなことを開発者がそれほど意識することなく、GPSやネットワークプロバイダに加え加速度センサーなどを組み合わせることで、その状況に応じて最適な位置情報を取得することができるようになりました。

それではサンプルコードを確認していきましょう。

サンプルコード

アプリ実行図

1


画面レイアウトファイル(activity_main.xml)

アプリの画面レイアウトファイルです。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="15dp"
    tools:context=".MainActivity" >
 
    <TextView
        android:id="@+id/textTime"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
 
    <TextView
        android:id="@+id/textLat"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
 
    <TextView
        android:id="@+id/textLng"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
 
    <fragment
        android:id="@+id/mapFragment1"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="15dp" />
 
</LinearLayout>


Activityファイル(MainActivity.java)

Activityファイルです。
継承しているのがFragmentActivityであることに注意してください。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package com.example.locationsample;
 
import java.text.SimpleDateFormat;
 
import android.location.Location;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.widget.TextView;
import android.widget.Toast;
 
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient;
import com.google.android.gms.location.LocationClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
 
public class MainActivity extends FragmentActivity {
 
    private GoogleMap map;
    private LocationClient locationClient;
    private LocationListener locationListener;
    private LocationRequest locationRequest;
    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        // 第2引数と第3引数は、以降に記述するコールバックメソッド
        locationClient = new LocationClient(this, connectionCallbacks, onConnectionFailedListener);
 
    }
 
    // LocationClient()の第2引数に指定しているコールバックメソッド
    private GooglePlayServicesClient.ConnectionCallbacks connectionCallbacks = new GooglePlayServicesClient.ConnectionCallbacks() {
 
        // GooglePlayServiceからの切断時に呼び出される
        @Override
        public void onDisconnected() {
            Toast.makeText(MainActivity.this, "切断されました。", Toast.LENGTH_SHORT).show();
        }
 
        // GooglePlayServiceへの接続時に呼び出される
        @Override
        public void onConnected(Bundle bundle) {
            Toast.makeText(MainActivity.this, "接続しました。", Toast.LENGTH_SHORT).show();
 
            if (locationClient.isConnected()) {
 
                // リスナーの登録
                locationListener = new LocationListener() {
 
                    @Override
                    public void onLocationChanged(Location location) {
 
                        if (location != null) {
 
                            TextView textLat = (TextView) findViewById(R.id.textLat);
                            TextView textLng = (TextView) findViewById(R.id.textLng);
                            TextView textTime = (TextView) findViewById(R.id.textTime);
 
                            double lat = location.getLatitude();
                            double lng = location.getLongitude();
 
                            textTime.setText("時間:" + sdf.format(location.getTime()));
                            textLat.setText("緯度:" + String.valueOf(lat));
                            textLng.setText("経度:" + String.valueOf(lng));
 
                            LatLng latLng = new LatLng(lat, lng);
                            map.addMarker(new MarkerOptions().position(latLng));
                            map.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 18));
 
                            Toast.makeText(MainActivity.this, "値を更新しました。",  Toast.LENGTH_SHORT).show();
 
                        } else {
                            Toast.makeText(MainActivity.this, "値を取得できませんでした。", Toast.LENGTH_SHORT).show();
                        }
                    }
 
                };
 
                // LocationRequestの生成と各種処理(定期的に位置情報を取得するため)
                locationRequest = LocationRequest.create();
                locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
                locationRequest.setInterval(50000);// LocationRequestの時間間隔をミリ秒単位で指定
                locationClient.requestLocationUpdates(locationRequest, locationListener);
 
            } else {
 
                Toast.makeText(MainActivity.this, "接続されていません", Toast.LENGTH_SHORT).show();
 
            }
 
        }
 
    };
 
    // LocationClient()の第3引数に指定しているコールバックメソッド
    private GooglePlayServicesClient.OnConnectionFailedListener onConnectionFailedListener = new GooglePlayServicesClient.OnConnectionFailedListener() {
 
        // GooglePlayServiceへの接続に失敗した際に呼び出される
        @Override
        public void onConnectionFailed(ConnectionResult connectionResult) {
            Toast.makeText(MainActivity.this, "接続に失敗しました。", Toast.LENGTH_SHORT).show();
        }
 
    };
 
    @Override
    protected void onResume() {
        super.onResume();
 
        FragmentManager fm = getSupportFragmentManager();
        SupportMapFragment mapFragment = (SupportMapFragment) fm.findFragmentById(R.id.mapFragment1);
        map = mapFragment.getMap();
 
        Toast.makeText(MainActivity.this, "接続を開始します。", Toast.LENGTH_SHORT).show();
        locationClient.connect();// GooglePlayServiceへの接続
    }
 
    @Override
    protected void onPause() {
        super.onPause();
 
        locationClient.removeLocationUpdates(locationListener);// リスナーの解除
        locationClient.disconnect();// GooglePlayServiceからの切断
        map.clear();
    }
 
}


Androidアプリ開発の必須知識!JAVAプログラミングを学べる連載リンク

はじめてのJAVA 連載

Recent News

Recent Tips

Tag Search